alchemylab 1.0.13 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,9 +34,9 @@ let o=(0,s.getErrorMessage)(r),c=""
34
34
  return r instanceof n.NotFoundError?o=`The request ID "${e.requestId}" was not found. Please provide a valid request ID.`:r instanceof n.ValidationError&&(o.includes("Project cannot accept new tasks")||o.includes("Project is inactive due to tier limits")?c="\n\nThis project is currently inactive due to tier limits. Only your oldest projects can accept new tasks. Please use an active project or upgrade your tier for more simultaneous projects.":o="Invalid input: "+o),a.error("Detailed error when creating task",{error:(0,s.getErrorMessage)(r),stack:r instanceof Error?r.stack:void 0}),i.isOffline,i.apiClient,{content:[{type:"text",text:`Error: ${o}${c}`}],isError:!0}}}
35
35
  const r=t(6183),n=t(9860),o=t(2960),s=t(8824)},184(e,exports,t){"use strict"
36
36
  function r(e,t,r,n,o={}){const s=u.default.resolve(e)
37
- if(D.has(s))return t.child({component:"mcp-server-registry"}).debug("Using existing server for path",{path:s}),D.get(s)
38
- const i=new $(s,t,r,n,o)
39
- return D.set(s,i),i}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
37
+ if(O.has(s))return t.child({component:"mcp-server-registry"}).debug("Using existing server for path",{path:s}),O.get(s)
38
+ const i=new j(s,t,r,n,o)
39
+ return O.set(s,i),i}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
40
40
  var o=Object.getOwnPropertyDescriptor(t,r)
41
41
  o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||(n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[]
42
42
  for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
@@ -44,20 +44,20 @@ return t},n(e)},function(e){if(e&&e.__esModule)return e
44
44
  var t={}
45
45
  if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
46
46
  return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
47
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.McpServer=void 0,exports.resetStdoutWrite=function(){process.stdout.write=O},exports.getMcpServer=r,exports.createServer=function(e,t,n,o,s={}){return r(e,t,n,o,s)}
48
- const c=t(3807),l=t(8909),u=a(t(6928)),d=a(t(9896)),h=a(t(1943)),g=t(9567),p=t(3444),f=t(7660),m=t(1253),y=t(5172),w=t(7976),k=i(t(7478)),b=t(4139),I=new Set,v=t(9860),C=t(1472),_=t(3328),E=t(8955),q=t(3217),S=t(8411),T=t(5278),M=t(446),R=t(9060),P=t(8824),x=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),O=process.stdout.write,j=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
49
- !(0,p.isDebugToolsEnabled)()||j&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,p.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&x.debug("Stdout output",{content:e.substring(0,100),length:e.length}),O.call(process.stdout,e)}catch(e){return x.error("Error in safeStdoutWrite",{error:e+""}),!0}})
50
- class ${constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.clientInfo=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.multiAgentMode=o.multiAgentMode||!1,this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,multiAgentMode:o.multiAgentMode||!1,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=u.default.join(e,b.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new f.ProjectContext(e,t),this.tokenManager=new m.TokenManager(t,e,{remoteServerUrl:n}),this.lockOverrideManager=new M.LockOverrideManager(t),this.configManager=new R.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.interceptConnectMethod(),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
47
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.McpServer=void 0,exports.resetStdoutWrite=function(){process.stdout.write=M},exports.getMcpServer=r,exports.createServer=function(e,t,n,o,s={}){return r(e,t,n,o,s)}
48
+ const c=t(3807),l=t(8909),u=a(t(6928)),d=a(t(9896)),h=a(t(1943)),g=t(9567),p=t(3444),f=t(7660),m=t(1253),y=t(5172),w=i(t(7478)),k=t(4139),b=new Set,I=t(9860),v=t(1472),C=t(3328),_=t(8955),E=t(3217),q=t(5278),S=t(446),T=t(9060),R=t(8824),P=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),M=process.stdout.write,x=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
49
+ !(0,p.isDebugToolsEnabled)()||x&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,p.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&P.debug("Stdout output",{content:e.substring(0,100),length:e.length}),M.call(process.stdout,e)}catch(e){return P.error("Error in safeStdoutWrite",{error:e+""}),!0}})
50
+ class j{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=u.default.join(e,k.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new f.ProjectContext(e,t),this.tokenManager=new m.TokenManager(t,e,{remoteServerUrl:n}),this.lockOverrideManager=new S.LockOverrideManager(t),this.configManager=new T.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),(0,y.setGlobalClientInfo)("OpenCode","1.0.0"),this.metrics.incrementCounter("mcp_server_init_started",1),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
51
51
  const e=this.workspaceManager.getCurrentContext()
52
52
  return{currentBranch:e.branchName,activeRequestId:e.requestId,isOnMainBranch:e.isMainBranch}}async updateBranchState(e,t){this.logger.debug("updateBranchState called - managed by WorkspaceManager",{branch:e,requestId:t})}async getCurrentBranchContext(){if(!this.workspaceManager)return{branch:null,requestId:null,isMain:!0}
53
53
  const e=this.workspaceManager.getCurrentContext()
54
54
  return{branch:e.branchName,requestId:e.requestId,isMain:e.isMainBranch}}async syncBranchState(){this.logger.debug("syncBranchState called - managed by WorkspaceManager")}async switchToMainContext(){return this.workspaceManager?this.workspaceManager.switchToMain():{success:!1,message:"WorkspaceManager not available"}}getCurrentRequestId(){return this.workspaceManager?.getCurrentContext().requestId||null}async getNextId(e){try{const t=this.metrics.startTimer("remote_id_generation"),r=this.apiClient.getProjectClient()
55
55
  if(!r||"function"!=typeof r.getNextId)throw Error("Project client or getNextId method not available")
56
56
  const n=await r.getNextId(e)
57
- return t({success:!0,type:e}),this.metrics.incrementCounter("remote_id_success",1,{type:e}),n}catch(t){throw this.metrics.incrementCounter("remote_id_failure",1,{type:e,error:t instanceof Error?t.name:"unknown"}),this.logger.warn("Failed to get ID from remote server, unable to perform operation",{type:e,error:(0,P.getErrorMessage)(t)}),Error("Failed to get ID from remote server.")}}async initialize(){const e=this.remoteServerUrl||"https://api.alchemylabcode.com"
57
+ return t({success:!0,type:e}),this.metrics.incrementCounter("remote_id_success",1,{type:e}),n}catch(t){throw this.metrics.incrementCounter("remote_id_failure",1,{type:e,error:t instanceof Error?t.name:"unknown"}),this.logger.warn("Failed to get ID from remote server, unable to perform operation",{type:e,error:(0,R.getErrorMessage)(t)}),Error("Failed to get ID from remote server.")}}async initialize(){const e=this.remoteServerUrl||"https://api.alchemylabcode.com"
58
58
  this.logger.debug("Using remote server URL",{remoteServerUrl:e})
59
59
  const t=u.default.resolve(this.basePath)
60
- if(I.has(t))return this.logger.info("Path already initialized in global registry, skipping initialization",{path:t}),void(this.isInitialized=!0)
60
+ if(b.has(t))return this.logger.info("Path already initialized in global registry, skipping initialization",{path:t}),void(this.isInitialized=!0)
61
61
  if(this.isInitialized)this.logger.info("Server already initialized, skipping initialization")
62
62
  else{if(this.isInitializing)return this.logger.info("Initialization already in progress, waiting..."),void await this.initializationPromise
63
63
  this.isInitializing=!0,this.logger.info("SERVER INITIALIZATION STARTING",{path:t,pid:process.pid,time:(new Date).toISOString()}),this.metrics.setGauge("mcp_initialization",0,{status:"starting"})
@@ -65,25 +65,20 @@ try{await this.initializeComplete(),this.isInitialized=!0,this.isInitializing=!1
65
65
  let t=!1
66
66
  try{await h.default.stat(e),this.logger.info("Found existing git repository")}catch{t=!0}this.git=(0,c.simpleGit)({baseDir:this.basePath,binary:this.gitBinary}),t?await this.initializeGitRepo():await this.ensureGitignoreWithAlchemyLab()
67
67
  try{this.logger.info("Validating git repository for branch management...")
68
- const e=await k.validateGitRepository(this.git,this.logger,this.metrics)
68
+ const e=await w.validateGitRepository(this.git,this.logger,this.metrics)
69
69
  if(e.isGitRepository){this.logger.info("Git repository validation completed",{currentBranch:e.currentBranch,isClean:e.isClean,defaultBranch:e.defaultBranch,branchCount:e.branches.length,hasMainBranch:e.hasMainBranch,hasMasterBranch:e.hasMasterBranch})
70
70
  const t=[],r=[]
71
- e.currentBranch||(t.push("Repository is in detached HEAD state"),r.push("Switch to a proper branch: git checkout main")),e.isClean||(t.push(`Repository has ${e.uncommittedChanges.length} uncommitted changes`),r.push("Commit or stash changes before creating requests")),e.defaultBranch||(t.push("No default branch (main/master) found"),r.push("Create a default branch: git checkout -b main")),t.length>0?this.logger.warn("Git repository has potential issues for branch management",{issues:t,recommendations:r}):this.logger.info("Git repository is ready for automatic branch management"),this.metrics.setGauge("git_repository_ready",0===t.length?1:0),this.metrics.setGauge("git_repository_branch_count",e.branches.length),this.metrics.incrementCounter("git_repository_validation_success",1)}else this.logger.error("Git repository validation failed - not a valid git repository"),this.metrics.incrementCounter("git_repository_validation_failed",1)}catch(e){this.logger.warn("Git repository validation encountered an error",{error:e instanceof Error?e.message:e+""}),this.metrics.incrementCounter("git_repository_validation_error",1)}}async ensureGitignoreWithAlchemyLab(){const e=u.default.join(this.basePath,".gitignore"),t=b.ALCHEMY_DIR_NAME+"/"
71
+ e.currentBranch||(t.push("Repository is in detached HEAD state"),r.push("Switch to a proper branch: git checkout main")),e.isClean||(t.push(`Repository has ${e.uncommittedChanges.length} uncommitted changes`),r.push("Commit or stash changes before creating requests")),e.defaultBranch||(t.push("No default branch (main/master) found"),r.push("Create a default branch: git checkout -b main")),t.length>0?this.logger.warn("Git repository has potential issues for branch management",{issues:t,recommendations:r}):this.logger.info("Git repository is ready for automatic branch management"),this.metrics.setGauge("git_repository_ready",0===t.length?1:0),this.metrics.setGauge("git_repository_branch_count",e.branches.length),this.metrics.incrementCounter("git_repository_validation_success",1)}else this.logger.error("Git repository validation failed - not a valid git repository"),this.metrics.incrementCounter("git_repository_validation_failed",1)}catch(e){this.logger.warn("Git repository validation encountered an error",{error:e instanceof Error?e.message:e+""}),this.metrics.incrementCounter("git_repository_validation_error",1)}}async ensureGitignoreWithAlchemyLab(){const e=u.default.join(this.basePath,".gitignore"),t=k.ALCHEMY_DIR_NAME+"/"
72
72
  try{if(d.default.existsSync(e)){const r=await h.default.readFile(e,"utf8")
73
- if(r.split("\n").some((e=>e.trim()===t||e.trim()===t.slice(0,-1))))this.logger.info(b.ALCHEMY_DIR_NAME+"/ already present in .gitignore")
73
+ if(r.split("\n").some((e=>e.trim()===t||e.trim()===t.slice(0,-1))))this.logger.info(k.ALCHEMY_DIR_NAME+"/ already present in .gitignore")
74
74
  else{const n=r.trimEnd()+"\n\n# AlchemyMCP working directory\n"+t+"\n"
75
- await h.default.writeFile(e,n),this.logger.info(`Added ${b.ALCHEMY_DIR_NAME}/ to existing .gitignore`)}}else{const r=["# Dependency directories\nnode_modules/\n.npm\n.yarn\n\n# Build outputs\ndist/\nbuild/\n\n# Logs\nlogs/\n*.log\n\n# Editor files\n.DS_Store\n.vscode/\n.idea/\n\n# Environment variables\n.env\n.env.local\n\n# AlchemyMCP working directory",t,""].join("\n")
76
- await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${b.ALCHEMY_DIR_NAME}/ entry`)}}catch(e){this.logger.warn("Failed to update .gitignore file",{error:(0,P.getErrorMessage)(e)})}}async initializeGitRepo(){try{this.logger.info("Initializing git repository"),await this.git.init(),await this.ensureGitignoreWithAlchemyLab()
75
+ await h.default.writeFile(e,n),this.logger.info(`Added ${k.ALCHEMY_DIR_NAME}/ to existing .gitignore`)}}else{const r=["# Dependency directories\nnode_modules/\n.npm\n.yarn\n\n# Build outputs\ndist/\nbuild/\n\n# Logs\nlogs/\n*.log\n\n# Editor files\n.DS_Store\n.vscode/\n.idea/\n\n# Environment variables\n.env\n.env.local\n\n# AlchemyMCP working directory",t,""].join("\n")
76
+ await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${k.ALCHEMY_DIR_NAME}/ entry`)}}catch(e){this.logger.warn("Failed to update .gitignore file",{error:(0,R.getErrorMessage)(e)})}}async initializeGitRepo(){try{this.logger.info("Initializing git repository"),await this.git.init(),await this.ensureGitignoreWithAlchemyLab()
77
77
  const e=u.default.join(this.basePath,"README.md")
78
78
  if(!d.default.existsSync(e)){const t=`# Project at ${this.basePath}\n\nCreated with AlchemyMCP Server.\n`
79
79
  await h.default.writeFile(e,t)}this.logger.info("Git repository initialized successfully"),await this.git.add(".")
80
80
  const t=await this.git.status()
81
- t.staged.length>0?(await this.git.commit("Initial commit by AlchemyMCP Server"),this.logger.info(`Initial commit created with ${t.staged.length} files`)):this.logger.info("No files to commit in initial repository")}catch(e){this.logger.error("Failed to initialize git repository",{error:e instanceof Error?e.stack:e+""})}}setupMcpEventHandlers(){this.logger.debug("MCP event handlers set up")}captureClientInfo(e){try{const t=e.clientInfo||{}
82
- this.logger.info("[CLIENT-DEBUG] captureClientInfo called",{hasClientInfo:!!t,clientInfoName:t.name,clientInfoVersion:t.version,initDataKeys:Object.keys(e),userAgent:e.userAgent||t.userAgent,connectionType:this.clientInfo?.connectionType})
83
- const r=this.detectClientFromName(t.name)
84
- this.logger.info("[CLIENT-DEBUG] detectClientFromName result",{inputName:t.name,detectedName:r,willUse:r||"Unknown Client"}),this.clientInfo={name:r||"Unknown Client",version:t.version||"Unknown Version",capabilities:e.capabilities||{},userAgent:e.userAgent||t.userAgent,connectedAt:(new Date).toISOString(),initializationData:e},(0,y.setGlobalClientInfo)(this.clientInfo.name||"Unknown Client",this.clientInfo.version||"Unknown Version"),this.logger.info("MCP client connected",{clientName:this.clientInfo.name,clientVersion:this.clientInfo.version,connectionType:this.clientInfo.connectionType||"unknown"})}catch(e){this.logger.error("Failed to capture client information",{error:(0,P.getErrorMessage)(e)})}}detectClientFromName(e){if(!e)return
85
- const t=e.toLowerCase()
86
- return"claude-ai"===t||t.includes("claude")?"Claude Desktop":t.includes("vscode")?"VS Code":t.includes("cursor")?"Cursor":t.includes("opencode")?"OpenCode":e}getClientInfo(){return this.clientInfo}cleanupSSEConnection(){this.currentSSEConnection&&(this.currentSSEConnection.transport.close(),this.currentSSEConnection=null,this.logger.debug("SSE connection closed"))}handleError(e,t){if(t instanceof Error){const r=(0,v.createMcpProtocolError)(t.message||"Unknown error")
81
+ t.staged.length>0?(await this.git.commit("Initial commit by AlchemyMCP Server"),this.logger.info(`Initial commit created with ${t.staged.length} files`)):this.logger.info("No files to commit in initial repository")}catch(e){this.logger.error("Failed to initialize git repository",{error:e instanceof Error?e.stack:e+""})}}cleanupSSEConnection(){this.currentSSEConnection&&(this.currentSSEConnection.transport.close(),this.currentSSEConnection=null,this.logger.debug("SSE connection closed"))}handleError(e,t){if(t instanceof Error){const r=(0,I.createMcpProtocolError)(t.message||"Unknown error")
87
82
  this.logger.error("MCP error",{message:t.message,name:t.name,stack:t.stack,code:r.code}),e.status(500).json({error:{message:t.message,code:r.code,data:r.data||{details:t.message}}})}else this.logger.error("Unknown error",{error:t+""}),e.status(500).json({error:{message:"Unknown error occurred",code:-32e3,data:{details:t+""}}})
88
83
  return Promise.resolve()}async waitForInitialization(){return this.isInitialized?Promise.resolve():(this.logger.debug("Waiting for initialization to complete..."),this.initializationPromise)}async initializeComplete(){let e
89
84
  this.logger.info("Starting server initialization")
@@ -93,8 +88,8 @@ const o=t(6982)
93
88
  e=`prj_${Date.now().toString().substring(5)}_${o.randomBytes(4).toString("hex")}`,this.logger.warn("Using fallback project ID",{projectId:e,reason:"initialization_failure"})
94
89
  try{const t={id:e,name:u.default.basename(this.basePath)||"Local Project",description:"Project for "+u.default.basename(this.basePath),status:"active",createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString(),metadata:{basePath:this.basePath,alchemyPath:this.alchemyPath,fallback:!0}},r=u.default.join(this.alchemyPath,"project.json")
95
90
  d.default.writeFileSync(r,JSON.stringify(t,null,2)),this.logger.debug("Successfully wrote fallback project.json file")}catch(e){this.logger.error("Failed to write fallback project.json",{error:e instanceof Error?e.message:e+""})}}this.logger.info("Server using project ID",{projectId:e})
96
- const r=this.remoteServerUrl||"https://api.alchemylabcode.com",n=await _.ClientFactory.createClient(r,this.logger,this.metrics,{workingDir:this.basePath,alchemyPath:this.alchemyPath,tokenManager:this.tokenManager,circuitBreakerThreshold:5,circuitBreakerResetTime:3e4,retryAttempts:3,retryDelay:1e3})
97
- this.apiClient=n,await(0,E.initializeAgentRegistry)(this.apiClient,this.logger),this.logger.debug("Agent registry initialized"),this.documentFileManager=new T.DocumentFileManager(this.apiClient,this.logger),await this.documentFileManager.initialize(),this.logger.debug("Document file manager initialized"),e&&"PENDING_REMOTE_CREATION"!==e&&(this.apiClient.setProjectId(e),this.logger.debug("Set project ID on API client",{projectId:e}))
91
+ const r=this.remoteServerUrl||"https://api.alchemylabcode.com",n=await C.ClientFactory.createClient(r,this.logger,this.metrics,{workingDir:this.basePath,alchemyPath:this.alchemyPath,tokenManager:this.tokenManager,circuitBreakerThreshold:5,circuitBreakerResetTime:3e4,retryAttempts:3,retryDelay:1e3})
92
+ this.apiClient=n,await(0,_.initializeAgentRegistry)(this.apiClient,this.logger),this.logger.debug("Agent registry initialized"),this.documentFileManager=new q.DocumentFileManager(this.apiClient,this.logger),await this.documentFileManager.initialize(),this.logger.debug("Document file manager initialized"),e&&"PENDING_REMOTE_CREATION"!==e&&(this.apiClient.setProjectId(e),this.logger.debug("Set project ID on API client",{projectId:e}))
98
93
  try{const r=this.apiClient.getProjectClient()
99
94
  if(this.existingProjectId)this.logger.info("Skipping project synchronization - using existing project from HTTP server",{projectId:e})
100
95
  else if("PENDING_REMOTE_CREATION"===e){const{SimpleProjectCreationLock}=await t.e(800).then(t.t.bind(t,3800,23)),n=new SimpleProjectCreationLock(this.basePath,this.logger),o=await n.acquireLock()
@@ -103,71 +98,34 @@ try{const t=u.default.basename(this.basePath)||"Local Project",n=await r.createP
103
98
  this.logger.info("Remote project created",{projectId:n.id,name:n.name,processId:process.pid}),await this.projectContext.createProjectFileWithId(n.id,{name:n.name,description:n.description,status:n.status,metadata:{basePath:this.basePath,alchemyPath:this.alchemyPath}}),e=n.id,this.apiClient.setProjectId(e),this.tokenManager.setProjectId(e)}finally{await n.releaseLock()}}else{if(!o.projectData)throw this.logger.error("No project data available from coordination",{processId:process.pid}),Error("Project coordination failed: no project data available")
104
99
  this.logger.info("Using project created by another process",{projectId:o.projectData.id,name:o.projectData.name,processId:process.pid}),await this.projectContext.createProjectFileWithId(o.projectData.id,{name:o.projectData.name,description:o.projectData.description,status:o.projectData.status,metadata:{basePath:this.basePath,alchemyPath:this.alchemyPath}}),e=o.projectData.id,this.apiClient.setProjectId(e),this.tokenManager.setProjectId(e)}}else{this.logger.debug("Triggering initial project synchronization..."),await r.syncProjects(),this.logger.debug("Initial project synchronization completed successfully")
105
100
  const t=await r.getSynchronizedProjectId()
106
- t&&t!==e&&(this.logger.info("Project ID changed after synchronization",{oldId:e,newId:t}),e=t,await this.projectContext.updateProjectId(t),this.logger.info("Successfully updated project.json with synchronized ID",{synchronizedProjectId:t}),this.apiClient.setProjectId(t),this.tokenManager.setProjectId(t))}}catch(e){this.logger.warn("Initial project synchronization failed, but continuing initialization",{error:e instanceof Error?e.message:e+""})}await this.initializeGitRepositories(),await this.initializeWorkspaceManager(this.multiAgentMode),this.logger.info("Re-initializing all tools with full context...")
107
- const o=this.getContext();(0,C.registerTools)(this.server,o,this.apiClient,this.logger,this.metrics,this.tokenManager,this),this.tokenManager.setProjectId(this.getProjectId()),this.logger.info("Complete initialization finished - all tools available")}async getCurrentBranchInfo(){try{if(!this.git)return{available:!1,message:"No git repository available"}
108
- const e=await k.getRepositoryStatus(this.git,this.logger,this.metrics)
109
- return e.isGitRepository?{available:!0,currentBranch:e.currentBranch,isClean:e.isClean,branchCount:e.branches.length,message:`On branch ${e.currentBranch}${e.isClean?" (clean)":" (uncommitted changes)"}`}:{available:!1,message:"Not a git repository"}}catch(e){return this.logger.warn("Failed to get branch info",{error:(0,P.getErrorMessage)(e)}),{available:!1,message:"Git error: "+(0,P.getErrorMessage)(e)}}}async createSseConnection(e,t){await this.waitForInitialization(),this.cleanupSSEConnection(),this.logger.debug("Creating new SSE connection"),this.logger.info("[CLIENT-DEBUG] createSseConnection called",{userAgent:t,hasExistingClientInfo:!!this.clientInfo,existingName:this.clientInfo?.name}),this.clientInfo?(this.clientInfo.connectionType="sse",this.clientInfo.userAgent=t):this.clientInfo={connectionType:"sse",connectedAt:(new Date).toISOString(),name:"Unknown Client",version:"Unknown Version",userAgent:t},e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive")
101
+ t&&t!==e&&(this.logger.info("Project ID changed after synchronization",{oldId:e,newId:t}),e=t,await this.projectContext.updateProjectId(t),this.logger.info("Successfully updated project.json with synchronized ID",{synchronizedProjectId:t}),this.apiClient.setProjectId(t),this.tokenManager.setProjectId(t))}}catch(e){this.logger.warn("Initial project synchronization failed, but continuing initialization",{error:e instanceof Error?e.message:e+""})}await this.initializeGitRepositories(),await this.initializeWorkspaceManager(),this.logger.info("Re-initializing all tools with full context...")
102
+ const o=this.getContext();(0,v.registerTools)(this.server,o,this.apiClient,this.logger,this.metrics,this.tokenManager,this),this.tokenManager.setProjectId(this.getProjectId()),this.logger.info("Complete initialization finished - all tools available")}async getCurrentBranchInfo(){try{if(!this.git)return{available:!1,message:"No git repository available"}
103
+ const e=await w.getRepositoryStatus(this.git,this.logger,this.metrics)
104
+ return e.isGitRepository?{available:!0,currentBranch:e.currentBranch,isClean:e.isClean,branchCount:e.branches.length,message:`On branch ${e.currentBranch}${e.isClean?" (clean)":" (uncommitted changes)"}`}:{available:!1,message:"Not a git repository"}}catch(e){return this.logger.warn("Failed to get branch info",{error:(0,R.getErrorMessage)(e)}),{available:!1,message:"Git error: "+(0,R.getErrorMessage)(e)}}}async createSseConnection(e,t){await this.waitForInitialization(),this.cleanupSSEConnection(),this.logger.debug("Creating new SSE connection"),e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive")
110
105
  const r=new g.SSEServerTransport("/sse",e)
111
106
  this.currentSSEConnection={transport:r,response:e}
112
- try{await this.server.connect(r),this.extractClientInfoAfterConnection(),this.logger.info("SSE transport connected successfully")}catch(e){this.logger.error("Error connecting SSE transport",{error:(0,P.getErrorMessage)(e)})}return r}async connectStdio(){await this.waitForInitialization(),this.logger.debug("Connecting stdio transport"),this.stdioTransport=new g.StdioServerTransport,this.clientInfo?this.clientInfo.connectionType="stdio":this.clientInfo={connectionType:"stdio",connectedAt:(new Date).toISOString(),name:"Unknown Client",version:"Unknown Version"}
113
- try{await this.server.connect(this.stdioTransport),this.extractClientInfoAfterConnection(),this.logger.info("STDIO transport connected successfully")}catch(e){this.logger.error("Error connecting stdio transport",{error:(0,P.getErrorMessage)(e)})}}getCurrentSSEConnection(){return this.currentSSEConnection}interceptConnectMethod(){try{const e=this.server.connect
114
- "function"==typeof e&&(this.server.connect=async t=>{const r=await e.call(this.server,t)
115
- return setTimeout((()=>{this.extractClientInfoAfterConnection(),this.searchForClaudeAiPattern()}),500),r})}catch(e){this.logger.error("Failed to intercept connect method",{error:(0,P.getErrorMessage)(e)})}}searchForClaudeAiPattern(){try{const e=this.server,t=(e,r=0)=>{if(r>3||!e||"object"!=typeof e)return!1
116
- try{for(const[n,o]of Object.entries(e)){if("string"==typeof o&&"claude-ai"===o)return this.captureClientInfo({clientInfo:{name:"claude-ai",version:"0.1.0"}}),!0
117
- if("object"==typeof o&&null!==o&&t(o,r+1))return!0}}catch(e){}return!1},r=[e._options,e._serverInfo,e._capabilities,this.stdioTransport,this.currentSSEConnection?.transport]
118
- let n=!1
119
- for(const e of r)if(e&&t(e)){n=!0
120
- break}if(!n&&this.clientInfo&&"Unknown Client"===this.clientInfo.name){const e=this.detectClientUsingHeuristics()
121
- e&&(this.clientInfo.name=e,this.clientInfo.version=this.clientInfo.version||"0.1.0",this.logger.info("Client detected using heuristics",{detectedClient:e,connectionType:this.clientInfo.connectionType,userAgent:this.clientInfo.userAgent}))}}catch(e){this.logger.debug("Error searching for claude-ai pattern",{error:(0,P.getErrorMessage)(e)})}}detectClientUsingHeuristics(){try{if(this.logger.info("[CLIENT-DEBUG] detectClientUsingHeuristics called",{hasClientInfo:!!this.clientInfo,connectionType:this.clientInfo?.connectionType,userAgent:this.clientInfo?.userAgent,currentName:this.clientInfo?.name}),!this.clientInfo)return null
122
- if("sse"===this.clientInfo.connectionType){const e=this.clientInfo.userAgent?.toLowerCase()||""
123
- if(this.logger.info("[CLIENT-DEBUG] SSE connection heuristics",{userAgent:e,hasClaude:e.includes("claude"),hasChrome:e.includes("chrome"),hasElectron:e.includes("electron")}),e.includes("claude"))return"Claude Code"
124
- if(e.includes("chrome")||e.includes("electron"))return"Claude Code"}if("stdio"===this.clientInfo.connectionType){const e=process.env.TERM_PROGRAM?.toLowerCase()||""
125
- if(e.includes("vscode")||process.env.VSCODE_PID)return"VS Code"
126
- if(e.includes("cursor")||process.env.CURSOR_PID)return"Cursor"
127
- if(process.env.CLAUDE_CODE_SESSION||e.includes("claude"))return"Claude Code"
128
- try{const e=process.ppid
129
- if(e){const{execSync:r}=t(5317),n=r(`ps -p ${e} -o command=`,{encoding:"utf-8"}).trim(),o=n.toLowerCase()
130
- if(this.logger.info("[CLIENT-DEBUG] Parent process full command",{parentPid:e,commandLine:n.substring(0,200)}),o.includes("claude-code")||o.includes("@anthropic-ai/claude-code"))return"Claude Code"
131
- if((o.includes("visual studio code")||o.includes("/code "))&&!o.includes("claude"))return"VS Code"
132
- if(o.includes("cursor"))return"Cursor"
133
- if(o.includes("opencode"))return"OpenCode"
134
- if(o.includes("claude.app")||o.includes("electron")&&o.includes("claude"))return"Claude Desktop"}}catch(e){this.logger.debug("[CLIENT-DEBUG] Parent process detection failed",{error:e instanceof Error?e.message:e+""})}return"Claude Code"}if(this.clientInfo.initializationData){const e=JSON.stringify(this.clientInfo.initializationData).toLowerCase()
135
- if(e.includes("vscode"))return"VS Code"
136
- if(e.includes("cursor"))return"Cursor"
137
- if(e.includes("claude-code"))return"Claude Code"
138
- if(e.includes("claude")&&e.includes("desktop"))return"Claude Desktop"}return null}catch(e){return this.logger.debug("Error in heuristic client detection",{error:(0,P.getErrorMessage)(e)}),null}}extractClientInfoAfterConnection(){try{setTimeout((()=>{const e=(0,w.getClientInfoForMetadata)(this);(0,y.setGlobalClientInfo)(e.clientName,e.clientVersion)
139
- const t=(0,y.getGlobalClientInfo)()
140
- this.logger.info("MCP session initialized with unique session tag",{clientName:e.clientName,clientVersion:e.clientVersion,sessionTag:t.sessionTag,globalInfoSet:{clientName:t.clientName,clientVersion:t.clientVersion,sessionTag:t.sessionTag}})}),100)}catch(e){this.logger.debug("Could not extract client info after connection",{error:(0,P.getErrorMessage)(e)})}}setCurrentSSEConnection(e){this.currentSSEConnection=e}getServer(){return this.server}getCurrentGitInstance(){if(!this.workspaceManager)return this.git||void 0
107
+ try{await this.server.connect(r),this.logger.info("SSE transport connected successfully")}catch(e){this.logger.error("Error connecting SSE transport",{error:(0,R.getErrorMessage)(e)})}return r}async connectStdio(){await this.waitForInitialization(),this.logger.debug("Connecting stdio transport"),this.stdioTransport=new g.StdioServerTransport
108
+ try{await this.server.connect(this.stdioTransport),this.logger.info("STDIO transport connected successfully")}catch(e){this.logger.error("Error connecting stdio transport",{error:(0,R.getErrorMessage)(e)})}}getCurrentSSEConnection(){return this.currentSSEConnection}setCurrentSSEConnection(e){this.currentSSEConnection=e}getServer(){return this.server}getCurrentGitInstance(){if(!this.workspaceManager)return this.git||void 0
141
109
  const e=this.workspaceManager.getCurrentContext()
142
110
  return"multi-agent"===e.mode&&e.requestId?this.workspaceManager.getCurrentGit():this.git||void 0}getContext(){if(!this.workspaceManager)throw Error("WorkspaceManager not initialized")
143
- return{mainBasePath:this.basePath,alchemyPath:this.alchemyPath,basePath:this.workspaceManager.getCurrentContext().basePath,projectId:this.getProjectId(),git:this.getCurrentGitInstance(),gitBinary:this.gitBinary,apiClient:this.apiClient,workspaceManager:this.workspaceManager,documentFileManager:this.documentFileManager,lockOverrideManager:this.lockOverrideManager,configManager:this.configManager,getNextId:this.getNextId.bind(this),getCurrentBranchContext:this.getCurrentBranchContext.bind(this),syncBranchState:this.syncBranchState.bind(this),switchToMainContext:this.switchToMainContext.bind(this),getCurrentRequestId:this.getCurrentRequestId.bind(this),updateBranchState:this.updateBranchState.bind(this),multiAgentMode:"multi-agent"===this.workspaceManager?.getCurrentContext().mode,getEffectiveBasePath:async()=>this.workspaceManager?.getCurrentContext().basePath||this.basePath}}isMainBranch(e){return"main"===e||"master"===e}extractRequestIdFromBranch(e){const t=e.match(/^feature\/req(\d+)-/)
144
- return t?"req"+t[1]:null}async getEnhancedContext(){return{...this.getContext(),branchInfo:await this.getCurrentBranchInfo()}}getTokenManager(){return this.tokenManager}getProjectId(){try{return this.projectContext.getProjectId()}catch(e){return this.logger.debug("ProjectContext not initialized, using fallback project ID",{error:(0,P.getErrorMessage)(e)}),"INITIALIZING"}}generateSessionId(){return`session_${Date.now().toString(36)}_${Math.random().toString(36).substring(2,8)}_${process.pid.toString(36)}`}getMultiAgentConfig(){return null}isMultiAgentMode(){return this.multiAgentMode}async getActiveWorktrees(){return await this.workspaceManager.listActiveWorkspaces()}async initializeWorkspaceManager(e=!1){try{if(this.logger.debug("initializeWorkspaceManager called",{multiAgentMode:e,basePath:this.basePath}),!this.git)throw Error("Git must be initialized before WorkspaceManager")
145
- this.workspaceManager=(0,q.createWorkspaceManager)(this.basePath,e,this.logger,this.git,this.metrics,this.apiClient),this.logger.debug("WorkspaceManager created successfully"),this.logger.info("Initialized unified workspace manager",{mode:e?"multi-agent":"single-agent",basePath:this.basePath})}catch(e){throw this.logger.error("Failed to initialize workspace manager",{error:e}),e}}async initializeSingleAgentMode(){if(this.logger.info("Initializing single-agent mode"),!(0,S.acquireProcessLock)(this.basePath,!1)){const e=u.default.join(this.basePath,".alchemy_lab",".mcp-server.lock")
146
- throw Error(`Another alchemy instance is running in ${this.basePath}.\n\nTo fix this:\n1. Close the other MCP client/instance\n2. Or if no other instance is running, manually delete the lock file:\n ${e}\n\nNote: Stale locks (>24 hours old) and locks from other computers are automatically cleared.`)}this.logger.info("Process lock acquired for single-agent mode")}async switchToRequestContext(e){return this.logger.debug("switchToRequestContext called",{requestId:e,multiAgentMode:this.multiAgentMode,hasWorkspaceManager:!!this.workspaceManager}),this.multiAgentMode&&this.workspaceManager?this.switchToWorktreeContext(e):this.switchToBranchContext(e)}async switchToWorktreeContext(e){if(this.logger.debug("Using worktree context switching for multi-agent mode",{requestId:e}),!this.workspaceManager)return{success:!1,message:"Workspace manager not available"}
111
+ return{mainBasePath:this.basePath,alchemyPath:this.alchemyPath,basePath:this.workspaceManager.getCurrentContext().basePath,projectId:this.getProjectId(),git:this.getCurrentGitInstance(),gitBinary:this.gitBinary,apiClient:this.apiClient,workspaceManager:this.workspaceManager,documentFileManager:this.documentFileManager,lockOverrideManager:this.lockOverrideManager,configManager:this.configManager,getNextId:this.getNextId.bind(this),getCurrentBranchContext:this.getCurrentBranchContext.bind(this),syncBranchState:this.syncBranchState.bind(this),switchToMainContext:this.switchToMainContext.bind(this),getCurrentRequestId:this.getCurrentRequestId.bind(this),updateBranchState:this.updateBranchState.bind(this)}}isMainBranch(e){return"main"===e||"master"===e}extractRequestIdFromBranch(e){const t=e.match(/^feature\/req(\d+)-/)
112
+ return t?"req"+t[1]:null}async getEnhancedContext(){return{...this.getContext(),branchInfo:await this.getCurrentBranchInfo()}}getTokenManager(){return this.tokenManager}getProjectId(){try{return this.projectContext.getProjectId()}catch(e){return this.logger.debug("ProjectContext not initialized, using fallback project ID",{error:(0,R.getErrorMessage)(e)}),"INITIALIZING"}}generateSessionId(){return`session_${Date.now().toString(36)}_${Math.random().toString(36).substring(2,8)}_${process.pid.toString(36)}`}async getActiveWorktrees(){return await this.workspaceManager.listActiveWorkspaces()}async initializeWorkspaceManager(){try{if(this.logger.debug("initializeWorkspaceManager called",{basePath:this.basePath}),!this.git)throw Error("Git must be initialized before WorkspaceManager")
113
+ this.workspaceManager=(0,E.createWorkspaceManager)(this.basePath,this.logger,this.git,this.metrics,this.apiClient),this.logger.debug("WorkspaceManager created successfully"),this.logger.info("Initialized unified workspace manager",{mode:"multi-agent",basePath:this.basePath})}catch(e){throw this.logger.error("Failed to initialize workspace manager",{error:e}),e}}async switchToRequestContext(e){return this.logger.debug("switchToRequestContext called",{requestId:e,hasWorkspaceManager:!!this.workspaceManager}),this.workspaceManager?this.switchToWorktreeContext(e):{success:!1,message:"Workspace manager not available"}}async switchToWorktreeContext(e){if(this.logger.debug("Using worktree context switching for multi-agent mode",{requestId:e}),!this.workspaceManager)return{success:!1,message:"Workspace manager not available"}
147
114
  try{let t="request-"+e
148
115
  try{this.logger.debug("Attempting to fetch request title from API",{requestId:e})
149
116
  const r=this.apiClient.getRequestClient(),n=await r.getRequest(e)
150
- n&&n.title?(t=n.title,this.logger.debug("Successfully fetched request title for worktree",{requestId:e,actualTitle:n.title})):this.logger.warn("Request info found but no title, using fallback",{requestId:e,requestInfo:n?"exists":"null",fallbackTitle:t})}catch(r){this.logger.warn("Failed to fetch request title, using fallback",{requestId:e,fallbackTitle:t,error:(0,P.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0})}const r=this.generateSessionId()
117
+ n&&n.title?(t=n.title,this.logger.debug("Successfully fetched request title for worktree",{requestId:e,actualTitle:n.title})):this.logger.warn("Request info found but no title, using fallback",{requestId:e,requestInfo:n?"exists":"null",fallbackTitle:t})}catch(r){this.logger.warn("Failed to fetch request title, using fallback",{requestId:e,fallbackTitle:t,error:(0,R.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0})}const r=this.generateSessionId()
151
118
  this.logger.info("Creating worktree for request using WorkspaceManager",{requestId:e,requestTitle:t,sessionId:r}),await this.workspaceManager.ensureWorkspaceReady(e)
152
119
  const n=this.workspaceManager.getCurrentContext()
153
120
  this.git=(0,c.simpleGit)({baseDir:n.basePath,binary:this.gitBinary})
154
- try{const t=await k.getCurrentBranch(this.git,this.logger,this.metrics)
121
+ try{const t=await w.getCurrentBranch(this.git,this.logger,this.metrics)
155
122
  if(this.logger.info("Workspace Git instance branch status",{requestId:e,currentBranch:t,expectedBranch:n.branchName,workspacePath:n.basePath,isMainBranch:n.isMainBranch}),t!==n.branchName&&!n.isMainBranch){this.logger.warn("Workspace not on expected branch, attempting to switch",{requestId:e,currentBranch:t,expectedBranch:n.branchName})
156
- const r=await k.switchToBranch(this.git,n.branchName,this.logger,this.metrics)
157
- r.success?this.logger.info("Successfully switched workspace to correct branch",{requestId:e,branchName:n.branchName}):this.logger.error("Failed to switch workspace to correct branch",{requestId:e,expectedBranch:n.branchName,error:r.message})}}catch(t){this.logger.error("Failed to verify workspace branch status",{requestId:e,workspacePath:n.basePath,error:t instanceof Error?t.message:t+""})}return this.logger.info("Switched to request context",{requestId:e,workspacePath:n.basePath,branchName:n.branchName}),{success:!0,message:"Switched to workspace for request "+e,worktreePath:n.basePath}}catch(t){const r=(0,P.getErrorMessage)(t)
158
- return this.logger.error("Failed to switch to request context",{requestId:e,error:r}),{success:!1,message:"Failed to switch context: "+r}}}async switchToBranchContext(e){if(this.logger.debug("Using branch context switching for single-agent mode",{requestId:e}),!this.workspaceManager)return{success:!1,message:"WorkspaceManager not available"}
159
- try{let t="request-"+e
160
- try{const r=this.apiClient.getRequestClient(),n=await r.getRequest(e)
161
- n&&n.title&&(t=n.title)}catch(t){this.logger.warn("Failed to fetch request title for branch switching",{requestId:e,error:(0,P.getErrorMessage)(t)})}this.logger.info("Ensuring workspace exists before switching (single-agent)",{requestId:e,requestTitle:t,reason:"manual-context-switch"}),await this.workspaceManager.ensureWorkspaceReady(e)
162
- const r={success:!0,message:"Workspace ready"}
163
- if(!r.success)return{success:!1,message:r.message||"Failed to switch to request workspace"}
164
- const n=this.workspaceManager.getCurrentContext()
165
- this.git=(0,c.simpleGit)({baseDir:n.basePath,binary:this.gitBinary})
166
- try{const t=await k.getCurrentBranch(this.git,this.logger,this.metrics)
167
- return this.logger.info("Single-agent Git instance branch status",{requestId:e,currentBranch:t,expectedBranch:n.branchName,basePath:n.basePath}),{success:!0,message:`Switched to request ${e} context`}}catch(t){return this.logger.warn("Branch verification failed but continuing",{requestId:e,error:t instanceof Error?t.message:t+""}),{success:!0,message:`Switched to request ${e} context (branch verification warning)`}}}catch(t){return this.logger.error("Failed to switch to single-agent request context",{requestId:e,error:(0,P.getErrorMessage)(t)}),{success:!1,message:"Failed to switch to request context: "+(0,P.getErrorMessage)(t)}}}async getEffectiveBasePath(e){if(!this.multiAgentMode||!this.workspaceManager||!e)return this.basePath
123
+ const r=await w.switchToBranch(this.git,n.branchName,this.logger,this.metrics)
124
+ r.success?this.logger.info("Successfully switched workspace to correct branch",{requestId:e,branchName:n.branchName}):this.logger.error("Failed to switch workspace to correct branch",{requestId:e,expectedBranch:n.branchName,error:r.message})}}catch(t){this.logger.error("Failed to verify workspace branch status",{requestId:e,workspacePath:n.basePath,error:t instanceof Error?t.message:t+""})}return this.logger.info("Switched to request context",{requestId:e,workspacePath:n.basePath,branchName:n.branchName}),{success:!0,message:"Switched to workspace for request "+e,worktreePath:n.basePath}}catch(t){const r=(0,R.getErrorMessage)(t)
125
+ return this.logger.error("Failed to switch to request context",{requestId:e,error:r}),{success:!1,message:"Failed to switch context: "+r}}}async getEffectiveBasePath(e){if(!this.workspaceManager||!e)return this.basePath
168
126
  const t=await this.workspaceManager.getWorkspaceInfo(e)
169
- return t?.path||this.basePath}}exports.McpServer=$
170
- const D=new Map},213(e,exports,t){"use strict"
127
+ return t?.path||this.basePath}}exports.McpServer=j
128
+ const O=new Map},213(e,exports,t){"use strict"
171
129
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
172
130
  const r=t(6183),n=t(3707)
173
131
  exports.def={name:"quick_write",description:"Create or update a file or document. Wraps the change in a request/task workflow that auto-completes.\n\nUse 'path' for filesystem files or 'documentId' for tracked documents.\nSet append:true to add content to existing content.\n\nRequires: title, description, path/documentId, content.",schema:r.QuickWriteSchema,annotations:{title:"Quick Write",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleQuickChange)(e,"write",t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},233(e,exports,t){"use strict"
@@ -238,49 +196,49 @@ default:t="open"}else t="open"
238
196
  const n=Array.isArray(e.acceptanceCriteria)?e.acceptanceCriteria.map(r):[]
239
197
  return{id:e.id,title:e.title,description:e.description,type:e.type,status:t,acceptanceCriteria:n,createdAt:e.createdAt,updatedAt:e.updatedAt,...e.projectId?{projectId:e.projectId}:{},...e.completionSummary?{completionSummary:e.completionSummary}:{},...e.completedAt?{completedAt:e.completedAt}:{},...e.metadata?{metadata:e.metadata}:{},...e.lockInfo?{lockInfo:e.lockInfo}:{}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.adaptApiAcceptanceCriterionToDomain=r,exports.adaptApiRequestToDomain=n,exports.adaptApiRequestsToDomain=function(e){return e.map(n)}
240
198
  const o=t(6756)},355(e,exports,t){"use strict"
241
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,u,d,h,g){const p=h.child({tool:"complete_task"})
242
- p.info("Completing task",{args:e})
243
- const f=g.startTimer("tool_handler_duration")
244
- try{const{taskId:o,summary:h}=function(e){if(void 0!==e.verificationSteps){const{verificationSteps:t,...r}=e
199
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,l,u,d,h){const g=d.child({tool:"complete_task"})
200
+ g.info("Completing task",{args:e})
201
+ const p=h.startTimer("tool_handler_duration")
202
+ try{const{taskId:o,summary:d}=function(e){if(void 0!==e.verificationSteps){const{verificationSteps:t,...r}=e
245
203
  e=r}try{return r.CompleteTaskSchema.parse(e)}catch(e){if(e instanceof i.ZodError&&e.errors.length>0)throw new n.ValidationError(e.errors[0].message)
246
- throw new n.ValidationError("Invalid input: "+(0,l.getErrorMessage)(e))}}(e),m=u.projectId
247
- if(!m)throw new n.ValidationError("Project ID is required for completing tasks with the new API structure")
248
- g.incrementCounter("complete_task_attempts",1,{taskId:o}),d.setProjectId(m)
249
- const y=d.getTaskClient()
250
- let w
251
- try{const e=await y.getTask(o)
252
- p.info("Raw task response data",{responseData:JSON.stringify(e)}),p.debug("Task response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
253
- const t=(0,s.extractDataFromResponse)(e,{logger:p,operationName:"getTask",throwOnNoData:!0})
254
- w="data"in t?t.data:t,p.info("Current task status: "+w.status,{taskId:o,currentStatus:w.status})}catch(e){if(e instanceof n.ValidationError)throw e
255
- throw new n.NotFoundError(`Task ${o} not found in project ${m}. Please provide a valid task ID.`,{taskId:o,projectId:m,originalError:e})}if("completed"===w.status){const e="Task is already completed."
256
- throw p.warn(e,{taskId:o,currentStatus:w.status}),new n.ValidationError(e)}if("canceled"===w.status){const e="Task is canceled and can not be completed."
257
- throw p.warn(e,{taskId:o,currentStatus:w.status}),new n.ValidationError(e)}if(u.multiAgentMode&&w.requestId){p.debug("Multi-agent mode: checking request lock for task operation",{taskId:o,requestId:w.requestId})
258
- try{const e=d.getRequestClient(),{sessionTag:t}=(0,a.getGlobalClientInfo)(),r=await e.getRequestLockStatus(w.requestId)
259
- if(r.isLocked){if(r.lockedBySessionTag!==t){let e=`Request ${w.requestId} is locked by another agent (${r.lockedBySessionTag}). `
260
- throw r.isExpired?e+="Lock has expired but cleanup may be pending. ":e+=`Lock expires in: ${r.timeRemainingFormatted}. `,e+="Only the agent that locked the request can modify its tasks.",new n.ValidationError(e,{taskId:o,requestId:w.requestId,lockedByAgent:r.lockedBySessionTag,currentAgent:t,timeRemainingMs:r.timeRemainingMs,isExpired:r.isExpired})}}else{p.debug("Lock not held, auto-acquiring for task completion",{requestId:w.requestId,sessionTag:t})
261
- const r=await e.lockRequest(w.requestId,t)
262
- if(!r.locked)throw new n.ValidationError(`Failed to acquire lock for request ${w.requestId}. Another agent may have just locked it. Try again shortly.`,{taskId:o,requestId:w.requestId})
263
- p.info("Auto-acquired lock for task completion",{requestId:w.requestId,sessionTag:t,lockedAt:r.lockedAt})}p.info("Request lock validation passed",{taskId:o,requestId:w.requestId,sessionTag:t})}catch(e){if(e instanceof n.ValidationError)throw e
264
- throw p.error("Failed to check request lock status",{taskId:o,requestId:w.requestId,error:(0,l.getErrorMessage)(e)}),new n.ValidationError("Failed to verify request lock status: "+(0,l.getErrorMessage)(e),{taskId:o,requestId:w.requestId})}}else p.debug("Single-agent mode or task without requestId: skipping lock check",{taskId:o,isMultiAgent:(0,c.isMultiAgentModeEnabled)(),hasRequestId:!!w.requestId})
265
- let k=u.git
266
- if(u.workspaceManager){const e=u.workspaceManager.getCurrentContext()
204
+ throw new n.ValidationError("Invalid input: "+(0,c.getErrorMessage)(e))}}(e),f=l.projectId
205
+ if(!f)throw new n.ValidationError("Project ID is required for completing tasks with the new API structure")
206
+ h.incrementCounter("complete_task_attempts",1,{taskId:o}),u.setProjectId(f)
207
+ const m=u.getTaskClient()
208
+ let y
209
+ try{const e=await m.getTask(o)
210
+ g.info("Raw task response data",{responseData:JSON.stringify(e)}),g.debug("Task response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
211
+ const t=(0,s.extractDataFromResponse)(e,{logger:g,operationName:"getTask",throwOnNoData:!0})
212
+ y="data"in t?t.data:t,g.info("Current task status: "+y.status,{taskId:o,currentStatus:y.status})}catch(e){if(e instanceof n.ValidationError)throw e
213
+ throw new n.NotFoundError(`Task ${o} not found in project ${f}. Please provide a valid task ID.`,{taskId:o,projectId:f,originalError:e})}if("completed"===y.status){const e="Task is already completed."
214
+ throw g.warn(e,{taskId:o,currentStatus:y.status}),new n.ValidationError(e)}if("canceled"===y.status){const e="Task is canceled and can not be completed."
215
+ throw g.warn(e,{taskId:o,currentStatus:y.status}),new n.ValidationError(e)}if(y.requestId){g.debug("Checking request lock for task operation",{taskId:o,requestId:y.requestId})
216
+ try{const e=u.getRequestClient(),{sessionTag:t}=(0,a.getGlobalClientInfo)(),r=await e.getRequestLockStatus(y.requestId)
217
+ if(r.isLocked){if(r.lockedBySessionTag!==t){let e=`Request ${y.requestId} is locked by another agent (${r.lockedBySessionTag}). `
218
+ throw r.isExpired?e+="Lock has expired but cleanup may be pending. ":e+=`Lock expires in: ${r.timeRemainingFormatted}. `,e+="Only the agent that locked the request can modify its tasks.",new n.ValidationError(e,{taskId:o,requestId:y.requestId,lockedByAgent:r.lockedBySessionTag,currentAgent:t,timeRemainingMs:r.timeRemainingMs,isExpired:r.isExpired})}}else{g.debug("Lock not held, auto-acquiring for task completion",{requestId:y.requestId,sessionTag:t})
219
+ const r=await e.lockRequest(y.requestId,t)
220
+ if(!r.locked)throw new n.ValidationError(`Failed to acquire lock for request ${y.requestId}. Another agent may have just locked it. Try again shortly.`,{taskId:o,requestId:y.requestId})
221
+ g.info("Auto-acquired lock for task completion",{requestId:y.requestId,sessionTag:t,lockedAt:r.lockedAt})}g.info("Request lock validation passed",{taskId:o,requestId:y.requestId,sessionTag:t})}catch(e){if(e instanceof n.ValidationError)throw e
222
+ throw g.error("Failed to check request lock status",{taskId:o,requestId:y.requestId,error:(0,c.getErrorMessage)(e)}),new n.ValidationError("Failed to verify request lock status: "+(0,c.getErrorMessage)(e),{taskId:o,requestId:y.requestId})}}else g.debug("Task without requestId: skipping lock check",{taskId:o,hasRequestId:!!y.requestId})
223
+ let w=l.git
224
+ if(l.workspaceManager){const e=l.workspaceManager.getCurrentContext()
267
225
  if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
268
- k=simpleGit({baseDir:e.basePath,binary:u.gitBinary}),p.debug("Using workspace-aware git instance for task completion",{taskId:o,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let b=null
269
- if(k)try{(await k.status()).isClean()||(b=(await k.commit(`Complete task ${o}: ${h}`)).commit,p.info("Created commit for task completion",{taskId:o,commitId:b}))}catch(e){p.warn("Failed to commit changes",{error:(0,l.getErrorMessage)(e)})}let I=null
270
- try{const e=d.getToolRecordClient()
271
- e&&(I={id:(await e.createToolRecord({taskId:o,requestId:w.requestId,projectId:m,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:h,lastCommit:b,completedAt:(new Date).toISOString()},note:`Completed task: ${h.substring(0,100)}${h.length>100?"...":""}`})).id})}catch(e){p.error("Failed to create tool record for task completion, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:o,requestId:w.requestId})}try{const e=w.metadata||{},t=(new Date).toISOString(),r={status:"completed",metadata:{...e,lastCommit:b,completionSummary:h,completionRecordId:I?.id,completedAt:t}},n=await y.updateTask(o,r)
272
- p.info("Raw task update response data",{responseData:JSON.stringify(n)}),p.debug("Task update response structure",{type:typeof n,isArray:Array.isArray(n),hasData:null!=n,properties:n?Object.keys(n):[],dataPreview:n?JSON.stringify(n).substring(0,200)+"...":"null"}),(0,s.extractDataFromResponse)(n,{logger:p,operationName:"updateTask",defaultValue:{id:o,status:"completed"}}),p.info("Successfully completed task",{taskId:o,recordId:I?.id})
273
- const i=w.requestId
274
- let a=`Task ${o} (${w.title}) has been marked as completed.`
275
- if(I?.id&&(a+=`\n[RECORD:${I.id}]`),b&&(a+="\nCommit: "+b.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
276
- p.info("Raw tasks list response data",{responseData:JSON.stringify(e)}),p.debug("Tasks list response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
277
- const t=(0,s.extractArrayFromResponse)(e,{logger:p,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
278
- p.info("Task progress check",{requestId:i,totalTasks:r,completedTasks:n}),a+=`\n\nTask Progress: ${n}/${r} tasks completed`,n===r&&(a+=`\n\nAll tasks for request ${i} are now completed! You may consider marking the request as completed using the complete-request tool.`)}catch(e){p.warn("Failed to check task progress",{error:(0,l.getErrorMessage)(e),requestId:i})}return f({success:!0}),{content:[{type:"text",text:a}]}}catch(e){throw p.error("Failed to complete task",{error:e instanceof Error?e.stack:e+"",taskId:o}),Error("Failed to complete task: "+(0,l.getErrorMessage)(e))}}catch(t){if(p.error("Failed to complete task",{error:t instanceof Error?t.stack:t+"",args:e}),u.projectId)try{const r=d.getToolRecordClient()
226
+ w=simpleGit({baseDir:e.basePath,binary:l.gitBinary}),g.debug("Using workspace-aware git instance for task completion",{taskId:o,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let k=null
227
+ if(w)try{(await w.status()).isClean()||(k=(await w.commit(`Complete task ${o}: ${d}`)).commit,g.info("Created commit for task completion",{taskId:o,commitId:k}))}catch(e){g.warn("Failed to commit changes",{error:(0,c.getErrorMessage)(e)})}let b=null
228
+ try{const e=u.getToolRecordClient()
229
+ e&&(b={id:(await e.createToolRecord({taskId:o,requestId:y.requestId,projectId:f,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:y.title,completionSummary:d,lastCommit:k,completedAt:(new Date).toISOString()},note:`Completed task: ${d.substring(0,100)}${d.length>100?"...":""}`})).id})}catch(e){g.error("Failed to create tool record for task completion, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:o,requestId:y.requestId})}try{const e=y.metadata||{},t=(new Date).toISOString(),r={status:"completed",metadata:{...e,lastCommit:k,completionSummary:d,completionRecordId:b?.id,completedAt:t}},n=await m.updateTask(o,r)
230
+ g.info("Raw task update response data",{responseData:JSON.stringify(n)}),g.debug("Task update response structure",{type:typeof n,isArray:Array.isArray(n),hasData:null!=n,properties:n?Object.keys(n):[],dataPreview:n?JSON.stringify(n).substring(0,200)+"...":"null"}),(0,s.extractDataFromResponse)(n,{logger:g,operationName:"updateTask",defaultValue:{id:o,status:"completed"}}),g.info("Successfully completed task",{taskId:o,recordId:b?.id})
231
+ const i=y.requestId
232
+ let a=`Task ${o} (${y.title}) has been marked as completed.`
233
+ if(b?.id&&(a+=`\n[RECORD:${b.id}]`),k&&(a+="\nCommit: "+k.substring(0,8)),i)try{const e=await m.listTasks({requestId:i})
234
+ g.info("Raw tasks list response data",{responseData:JSON.stringify(e)}),g.debug("Tasks list response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
235
+ const t=(0,s.extractArrayFromResponse)(e,{logger:g,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
236
+ g.info("Task progress check",{requestId:i,totalTasks:r,completedTasks:n}),a+=`\n\nTask Progress: ${n}/${r} tasks completed`,n===r&&(a+=`\n\nAll tasks for request ${i} are now completed! You may consider marking the request as completed using the complete-request tool.`)}catch(e){g.warn("Failed to check task progress",{error:(0,c.getErrorMessage)(e),requestId:i})}return p({success:!0}),{content:[{type:"text",text:a}]}}catch(e){throw g.error("Failed to complete task",{error:e instanceof Error?e.stack:e+"",taskId:o}),Error("Failed to complete task: "+(0,c.getErrorMessage)(e))}}catch(t){if(g.error("Failed to complete task",{error:t instanceof Error?t.stack:t+"",args:e}),l.projectId)try{const r=u.getToolRecordClient()
279
237
  if(r){const o=t instanceof n.NotFoundError||t instanceof n.ValidationError||t instanceof i.ZodError
280
- await r.createToolRecord({...o?{}:{taskId:e.taskId},projectId:u.projectId,type:"complete-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.summary?.substring(0,100)+(e.summary?.length>100?"...":""),error:(0,l.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",attemptedTaskId:e.taskId,taskIdValidationFailed:o},note:"Failed to complete task "+e.taskId})}}catch(e){p.error("Failed to create failure record for task completion",{error:e instanceof Error?e.message:e+""})}f({success:!1,error:t instanceof Error?t.name:"unknown"})
281
- let r=(0,l.getErrorMessage)(t)
238
+ await r.createToolRecord({...o?{}:{taskId:e.taskId},projectId:l.projectId,type:"complete-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.summary?.substring(0,100)+(e.summary?.length>100?"...":""),error:(0,c.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",attemptedTaskId:e.taskId,taskIdValidationFailed:o},note:"Failed to complete task "+e.taskId})}}catch(e){g.error("Failed to create failure record for task completion",{error:e instanceof Error?e.message:e+""})}p({success:!1,error:t instanceof Error?t.name:"unknown"})
239
+ let r=(0,c.getErrorMessage)(t)
282
240
  return t instanceof n.NotFoundError&&(r=`The task ID "${e.taskId}" was not found. Please provide a valid task ID.`),t instanceof o.ConnectionError&&(r="Unable to complete task: Connection to the server failed. Please check your network connection and try again."),t instanceof i.ZodError&&t.errors.length>0&&(r=t.errors[0].message),{content:[{type:"text",text:"Error: "+r}],isError:!0}}}
283
- const r=t(6183),n=t(9860),o=t(5674),s=t(2960),i=t(1569),a=t(5172),c=t(5218),l=t(8824)},405(e,exports,t){"use strict"
241
+ const r=t(6183),n=t(9860),o=t(5674),s=t(2960),i=t(1569),a=t(5172),c=t(8824)},405(e,exports,t){"use strict"
284
242
  var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
285
243
  var o=Object.getOwnPropertyDescriptor(t,r)
286
244
  o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
@@ -335,13 +293,16 @@ const n=Date.now(),o=r.createdAt+6e4*r.validityMinutes
335
293
  return n>o?(this.logger.debug("Password validation failed: expired",{requestId:e,createdAt:new Date(r.createdAt).toISOString(),expiresAt:new Date(o).toISOString(),now:new Date(n).toISOString()}),this.passwords.delete(e),!1):(this.logger.info("Password validation successful",{requestId:e}),this.passwords.delete(e),!0)}cleanupExpiredPasswords(){const e=Date.now()
336
294
  let t=0
337
295
  for(const[r,n]of this.passwords.entries())e>n.createdAt+6e4*n.validityMinutes&&(this.passwords.delete(r),t++)
338
- t>0&&this.logger.debug("Cleaned up expired passwords",{count:t})}getActivePasswordCount(){return this.passwords.size}clearAllPasswords(){this.passwords.clear(),this.logger.debug("Cleared all passwords")}destroy(){this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=null),this.passwords.clear(),this.logger.debug("Lock override manager destroyed")}}exports.LockOverrideManager=n},542(e,exports,t){"use strict"
296
+ t>0&&this.logger.debug("Cleaned up expired passwords",{count:t})}getActivePasswordCount(){return this.passwords.size}clearAllPasswords(){this.passwords.clear(),this.logger.debug("Cleared all passwords")}destroy(){this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=null),this.passwords.clear(),this.logger.debug("Lock override manager destroyed")}}exports.LockOverrideManager=n},509(e,exports,t){"use strict"
297
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
298
+ const r=t(6183),n=t(9968)
299
+ exports.def={name:"update_specialization",description:"Update your specialization summary \u2014 a short description of your accumulated domain expertise. Keep it current as you work on different areas.",schema:r.UpdateSpecializationSchema,annotations:{title:"Update Specialization",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},handler(e,t){return(0,n.handleUpdateSpecialization)(e,t.logger,t.apiClient??void 0,t.cliOrigin)}}},542(e,exports,t){"use strict"
339
300
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.debugDefs=void 0
340
301
  const r=t(1569),n=t(5997),o=t(8349),s=t(9852),i=t(9422),a=r.z.object({}),c=r.z.object({requestId:r.z.string().optional().describe("Request ID to search for")})
341
302
  exports.debugDefs=[{name:"debug_multi_agent_status",description:"Debug tool to check multi-agent mode status, worktree state, and configuration",schema:a,annotations:{title:"Debug Multi-Agent Status",readOnlyHint:!0},debugOnly:!0,readOnly:!0,async handler(e,t){return{content:[{type:"text",text:await(0,n.handleDebugMultiAgentStatus)(e,t.context,t.logger,t.metrics)}]}}},{name:"debug_git_log",description:"Debug tool to examine git log and search for merge commits",schema:a,annotations:{title:"Debug Git Log",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,o.handleDebugGitLog)(e,t.context,t.logger,t.metrics)}},{name:"debug_git_log_request",description:"Debug tool to examine git log for a specific request",schema:c,annotations:{title:"Debug Git Log Request",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,s.handleDebugGitLogRequest)(e,t.context,t.logger,t.metrics)}},{name:"debug_request_file_history",description:"Debug tool to test git merge commit search patterns for request file history",schema:c,annotations:{title:"Debug Request File History",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,i.handleDebugRequestFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}]},700(e,exports,t){"use strict"
342
303
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
343
- const r=t(6183),n=t(8037),o=t(5218)
344
- exports.def={name:"list_requests",description:`List requests with filtering options (status, type, dates) and pagination. Shows detailed request information${(0,o.isMultiAgentModeEnabled)()?" including lock status to indicate which requests are currently in use by other agents":""}.`,schema:r.ListRequestsSchema,annotations:{title:"List Requests",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleListRequests)(e,t.context,t.apiClient,t.logger,t.metrics)}}},857(module){"use strict"
304
+ const r=t(6183),n=t(8037)
305
+ exports.def={name:"list_requests",description:"List requests with filtering options (status, type, dates) and pagination. Shows detailed request information including lock status to indicate which requests are currently in use by other agents.",schema:r.ListRequestsSchema,annotations:{title:"List Requests",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleListRequests)(e,t.context,t.apiClient,t.logger,t.metrics)}}},857(module){"use strict"
345
306
  module.exports=require("os")},922(e,exports,t){"use strict"
346
307
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ToolRecordClient=void 0
347
308
  const r=t(7645),n=t(1038),o=t(2161),s=t(5172),i=t(6688)
@@ -596,19 +557,19 @@ C=r}else C=t.basePath
596
557
  I.resolvedPath=C
597
558
  let _=!1
598
559
  try{_=(await g.default.stat(C)).isFile()}catch(e){const t=`Cannot access path ${C}: ${(0,k.getErrorMessage)(e)}`
599
- throw I.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,T=v.fileExtension,M=v.searchIn||"content"
600
- let R=void 0!==v.contextLines?v.contextLines:0
601
- if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!_&&!T)throw I.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,f.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
602
- let P,x=""
560
+ throw I.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,T=v.fileExtension,R=v.searchIn||"content"
561
+ let P=void 0!==v.contextLines?v.contextLines:0
562
+ if(0>P?P=0:P>10&&(l.warn(`contextLines ${P} exceeds maximum of 10, clamping to 10`),P=10),!_&&!T)throw I.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,f.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
563
+ let M,x=""
603
564
  if(_)x="*"
604
565
  else if("*"===T)x="*"
605
- else if(T){let e=T;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),x=e.startsWith(".")?e:"."+e}try{P=S?q?RegExp(n):RegExp(n,"i"):q?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${S?"regex":"search"} pattern: ${(0,k.getErrorMessage)(e)}`
606
- throw I.errors.push(t),(0,f.createValidationError)(t)}if(I.patternInfo={needle:n,regex:P.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:x},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
566
+ else if(T){let e=T;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),x=e.startsWith(".")?e:"."+e}try{M=S?q?RegExp(n):RegExp(n,"i"):q?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${S?"regex":"search"} pattern: ${(0,k.getErrorMessage)(e)}`
567
+ throw I.errors.push(t),(0,f.createValidationError)(t)}if(I.patternInfo={needle:n,regex:M.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:x},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
607
568
  for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
608
569
  I.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},I.phases.directoryListingTime=I.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,k.getErrorMessage)(e)
609
- I.errors.push(t),l.error(t)}const O=_?"file":"directory"
610
- l.info(`Searching for "${n}" in ${O} ${C} (mode: ${M})`,{needle:n,searchTarget:O,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:x,searchIn:M}}),b=Date.now(),I.phases.initializationTime=b-d
611
- const j=Date.now()
570
+ I.errors.push(t),l.error(t)}const j=_?"file":"directory"
571
+ l.info(`Searching for "${n}" in ${j} ${C} (mode: ${R})`,{needle:n,searchTarget:j,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:x,searchIn:R}}),b=Date.now(),I.phases.initializationTime=b-d
572
+ const O=Date.now()
612
573
  let $=[],D=0,A=0
613
574
  try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:u,contextLines:d}=n,p=[]
614
575
  if(s.info("performLocalSearch started",{searchPath:e,pattern:t.toString(),options:n}),u)return await async function(e,t,r,n,o,s=0){const i=[],a=h.default.basename(e)
@@ -625,17 +586,17 @@ o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,d)
625
586
  const f={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
626
587
  try{const{filesCount:n,fileMatchesCount:c,subdirCount:u,subdirStats:h}=await r(e,t,p,a,o,s,0,f,l,d)
627
588
  return f.filesProcessed=n,f.filesMatched=c,f.subdirectories=u,i.directoryStats.push(f),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:p.length,directories:u+1}),{matches:p,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,k.getErrorMessage)(t)
628
- return f.errors.push(r),i.directoryStats.push(f),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:p,totalFiles:f.filesProcessed}}}(C,P,{maxResults:E,fileExtension:x,searchIn:M,isFile:_,contextLines:R},x,l,I)
589
+ return f.errors.push(r),i.directoryStats.push(f),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:p,totalFiles:f.filesProcessed}}}(C,M,{maxResults:E,fileExtension:x,searchIn:R,isFile:_,contextLines:P},x,l,I)
629
590
  $=e.matches,D=e.totalFiles
630
591
  const t=1e3
631
592
  $.length>0&&$.length<=t?($.sort(((e,t)=>void 0!==e.modifiedTime&&void 0!==t.modifiedTime?t.modifiedTime-e.modifiedTime:void 0!==e.modifiedTime&&void 0===t.modifiedTime?-1:void 0===e.modifiedTime&&void 0!==t.modifiedTime?1:0)),l.info(`Sorted ${$.length} matches by modification time (newest first)`)):$.length>t&&l.info(`Skipped sorting ${$.length} matches (exceeds hard cap of ${t} for performance)`),A=$.length,$.length>E&&($=$.slice(0,E),l.info(`Limited results to ${E} (from ${A} total matches)`)),$.forEach((e=>{e.relativePath=function(e,t){const r=h.default.relative(e,t)
632
- return r?r===h.default.basename(t)?r:r.startsWith("./")?r.substring(2):r:h.default.basename(t)}(C,e.file)})),l.info(`Local search completed: found ${A||$.length} total matches in ${D} files, returning ${$.length} results`),I.phases.searchTime=Date.now()-j}catch(e){const t="Error during search: "+(0,k.getErrorMessage)(e)
633
- I.errors.push(t),l.error(t),I.phases.searchTime=Date.now()-j}I.totalFiles=D,I.totalMatches=$.length,I.endTime=Date.now()
593
+ return r?r===h.default.basename(t)?r:r.startsWith("./")?r.substring(2):r:h.default.basename(t)}(C,e.file)})),l.info(`Local search completed: found ${A||$.length} total matches in ${D} files, returning ${$.length} results`),I.phases.searchTime=Date.now()-O}catch(e){const t="Error during search: "+(0,k.getErrorMessage)(e)
594
+ I.errors.push(t),l.error(t),I.phases.searchTime=Date.now()-O}I.totalFiles=D,I.totalMatches=$.length,I.endTime=Date.now()
634
595
  let F,N=""
635
596
  try{if(t.getCurrentBranchContext){const e=await t.getCurrentBranchContext()
636
597
  e.branch&&(N=e.isMain?` (searched on main branch: ${e.branch})`:` (searched on request branch: ${e.branch}${e.requestId?" for "+e.requestId:""})`)}}catch(e){l.debug("Could not get branch context",{error:e}),N=" (branch context unavailable)"}l.debug("Search diagnostic information",{diagnostic:I})
637
- const L="content"===M?"content":"filename"===M?"filenames":"content and filenames"
638
- if(A>$.length?(F=`Found ${A} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=`${N}. Showing first ${$.length}:\n\n`):(F=`Found ${$.length} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=N+":\n\n"),$.length>0)if(R>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
598
+ const L="content"===R?"content":"filename"===R?"filenames":"content and filenames"
599
+ if(A>$.length?(F=`Found ${A} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=`${N}. Showing first ${$.length}:\n\n`):(F=`Found ${$.length} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=N+":\n\n"),$.length>0)if(P>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
639
600
  if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
640
601
  const o=new Map
641
602
  for(const e of n){const t=o.get(e.file)||[]
@@ -643,7 +604,7 @@ t.push(e),o.set(e.file,t)}const i=[]
643
604
  for(const[e,r]of o.entries()){r.sort(((e,t)=>e.line-t.line))
644
605
  let e=[r[0]]
645
606
  for(let n=1;n<r.length;n++){const o=e[e.length-1],a=r[n],c=o.line+t
646
- a.line-t>c+1?(i.push(s(e,t)),e=[a]):e.push(a)}e.length>0&&i.push(s(e,t))}return{filenameMatches:r,mergedGroups:i}}($,R),r=[]
607
+ a.line-t>c+1?(i.push(s(e,t)),e=[a]):e.push(a)}e.length>0&&i.push(s(e,t))}return{filenameMatches:r,mergedGroups:i}}($,P),r=[]
647
608
  e.forEach((e=>{r.push(e.relativePath+" [filename match]")})),t.forEach((e=>{const t=[]
648
609
  e.lines.forEach((e=>{e.isMatch?t.push(`> ${e.lineNumber}: ${e.content}`):t.push(` ${e.lineNumber}: ${e.content}`)})),r.push(`${e.relativePath}:\n${t.join("\n")}`)})),F+=r.join("\n\n")}else F+=await async function(e){const t=e.filter((e=>"filename"===e.matchType)),r=e.filter((e=>"content"===e.matchType)),n=[]
649
610
  t.length>0&&t.forEach((e=>{n.push(e.relativePath+" [filename match]")}))
@@ -1026,8 +987,8 @@ this.workingDirectory=r.worktreePath,this.logger.info("Using validated worktree
1026
987
  if(a.default.existsSync(r)){const o=a.default.readFileSync(r,"utf8")
1027
988
  this.hasExactConflictMarkers(o)?(t.push(n),this.logger.debug("Found conflict markers in originally conflicted file",{requestId:e,filePath:n,hasStart:/^\s*<{7}(?:\s|$)/m.test(o),hasSeparator:/^\s*={7}(?:\s|$)/m.test(o),hasEnd:/^\s*>{7}(?:\s|$)/m.test(o)})):this.logger.debug("No conflict markers found in file",{requestId:e,filePath:n})}else this.logger.debug("Originally conflicted file no longer exists (possibly deleted as resolution)",{requestId:e,filePath:n})}catch(r){this.logger.warn("Failed to check conflict markers in originally conflicted file",{requestId:e,filePath:n,error:r instanceof Error?r.message:r+""}),a.default.existsSync(i.default.resolve(this.workingDirectory,n))&&t.push(n)}}catch(t){return this.logger.error("Failed to validate conflict markers",{requestId:e,error:(0,n.getErrorMessage)(t)}),{resolved:!1,remainingConflicts:["Failed to validate conflict resolution"]}}return this.logger.info("Conflict marker validation completed",{requestId:e,totalFilesChecked:r?.length||0,filesWithConflicts:t.length,resolved:0===t.length,remainingConflicts:t}),{resolved:0===t.length,remainingConflicts:t}}}exports.ConflictResolutionManager=l},1666(e,exports,t){"use strict"
1028
989
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.RequestClient=void 0
1029
- const r=t(7645),n=t(293),o=t(2161),s=t(5172),i=t(5218),a=t(8824)
1030
- class c extends r.ConnectionAwareClient{constructor(e,t,r,n,o,s,i){const a=t.child({component:"request-client"}),c=s||{isInOfflineMode(){return!1},isOffline(){return!1},setOfflineMode(){},async checkConnectivity(){return!0},getHealthCheckStats(){return{isOffline:!1,consecutiveFailures:0,currentBackoffMs:0,lastCheckTime:0}},cleanup(){}}
990
+ const r=t(7645),n=t(293),o=t(2161),s=t(5172),i=t(8824)
991
+ class a extends r.ConnectionAwareClient{constructor(e,t,r,n,o,s,i){const a=t.child({component:"request-client"}),c=s||{isInOfflineMode(){return!1},isOffline(){return!1},setOfflineMode(){},async checkConnectivity(){return!0},getHealthCheckStats(){return{isOffline:!1,consecutiveFailures:0,currentBackoffMs:0,lastCheckTime:0}},cleanup(){}}
1031
992
  super(e,a,r,o,i),this.setConnectionStatusManager(c),this.projectClient=n}async createRequest(e){if(!e.title)throw Error("Request title is required")
1032
993
  if(!e.type)throw Error("Request type is required")
1033
994
  if(!e.description)throw Error("Request description is required")
@@ -1036,71 +997,69 @@ const t=this.metrics.startTimer("request_creation")
1036
997
  try{const r=e.projectId||this.projectClient.getProjectId()
1037
998
  if(!r)throw this.logger.error("No project ID available for request creation"),Error("No project ID provided or available from project client")
1038
999
  this.logger.debug("Token status check",{internalToken:this.authToken?"PRESENT":"MISSING"})
1039
- let i=r
1040
- if(!this.isOffline())try{i=await this.projectClient.ensureProjectExists(r),i!==r&&this.logger.info("Project ID changed during verification",{requestedId:r,actualId:i}),this.logger.debug("Project verified on remote server",{projectId:i})}catch(e){this.logger.warn(`Failed to verify project ${r} on remote server`,{error:(0,a.getErrorMessage)(e)})}let c=[]
1000
+ let a=r
1001
+ if(!this.isOffline())try{a=await this.projectClient.ensureProjectExists(r),a!==r&&this.logger.info("Project ID changed during verification",{requestedId:r,actualId:a}),this.logger.debug("Project verified on remote server",{projectId:a})}catch(e){this.logger.warn(`Failed to verify project ${r} on remote server`,{error:(0,i.getErrorMessage)(e)})}let c=[]
1041
1002
  Array.isArray(e.acceptanceCriteria)&&e.acceptanceCriteria.length>0&&(c="string"==typeof e.acceptanceCriteria[0]?e.acceptanceCriteria.map(((e,t)=>{const r=null!=e?e:"Acceptance criterion "+(t+1)
1042
1003
  return{id:`temp_${Date.now()}_${t}`,description:r,status:"unverified",evidence:null,evidenceType:null}})):e.acceptanceCriteria.map(((e,t)=>{const r="Acceptance criterion "+(t+1)
1043
1004
  return{id:e.id||`temp_${Date.now()}_${t}`,description:e.description||e.text||r,status:e.status||(e.verified?"verified":"unverified"),evidence:e.evidence||null,evidenceType:e.evidenceType||null,createdAt:e.createdAt,updatedAt:e.updatedAt}})))
1044
- const l={title:e.title,description:e.description,type:e.type,acceptanceCriteria:c,projectId:i}
1005
+ const l={title:e.title,description:e.description,type:e.type,acceptanceCriteria:c,projectId:a}
1045
1006
  "status"in e&&e.status?l.status=e.status:l.status="open",e.planDocumentId&&(l.planDocumentId=e.planDocumentId)
1046
1007
  const u=(0,s.getGlobalClientInfo)()
1047
- if(l.clientName=u.clientName,l.clientVersion=u.clientVersion,l.sessionTag=u.sessionTag,this.logger.info("Creating request with client info",{clientName:u.clientName,clientVersion:u.clientVersion,sessionTag:u.sessionTag,requestTitle:e.title}),"metadata"in e&&e.metadata?l.metadata=e.metadata:l.metadata={},e.cliOrigin&&(l.cliOrigin=e.cliOrigin),this.logger.info("Creating request",{title:e.title,type:e.type,projectId:i,criteriaCount:c.length}),this.authToken){const e={Authorization:"Bearer "+this.authToken}
1008
+ if(l.clientName=u.clientName,l.clientVersion=u.clientVersion,l.sessionTag=u.sessionTag,this.logger.info("Creating request with client info",{clientName:u.clientName,clientVersion:u.clientVersion,sessionTag:u.sessionTag,requestTitle:e.title}),"metadata"in e&&e.metadata?l.metadata=e.metadata:l.metadata={},e.cliOrigin&&(l.cliOrigin=e.cliOrigin),this.logger.info("Creating request",{title:e.title,type:e.type,projectId:a,criteriaCount:c.length}),this.authToken){const e={Authorization:"Bearer "+this.authToken}
1048
1009
  this.logger.debug("Auth header prepared for request creation",{tokenLength:this.authToken.length,tokenPrefix:this.authToken.substring(0,10)+"...",tokenSuffix:"..."+this.authToken.substring(this.authToken.length-10)})
1049
- const r=await this.requestWithRetry("POST",`/api/projects/${i}/requests`,l,e),s=(0,o.safeGetResponseData)(r,{})
1010
+ const r=await this.requestWithRetry("POST",`/api/projects/${a}/requests`,l,e),s=(0,o.safeGetResponseData)(r,{})
1050
1011
  if(!s||!s.id)throw this.logger.error("Received empty response data when creating request"),Error("Failed to create request: Empty response data")
1051
- return t({success:!0}),this.metrics.incrementCounter("request_creation_success",1),this.logger.info("Successfully created request",{requestId:s.id,title:s.title,type:s.type}),(0,n.adaptApiRequestToDomain)(s)}throw this.logger.error("No authentication token available for request creation"),Error("No authentication token available for request creation")}catch(r){throw t({success:!1}),this.metrics.incrementCounter("request_creation_failure",1),this.logger.error("Failed to create request",{error:(0,a.getErrorMessage)(r),title:e.title,type:e.type}),r}}async getRequests(e,t){const r=e||this.projectClient.getProjectId()
1012
+ return t({success:!0}),this.metrics.incrementCounter("request_creation_success",1),this.logger.info("Successfully created request",{requestId:s.id,title:s.title,type:s.type}),(0,n.adaptApiRequestToDomain)(s)}throw this.logger.error("No authentication token available for request creation"),Error("No authentication token available for request creation")}catch(r){throw t({success:!1}),this.metrics.incrementCounter("request_creation_failure",1),this.logger.error("Failed to create request",{error:(0,i.getErrorMessage)(r),title:e.title,type:e.type}),r}}async getRequests(e,t){const r=e||this.projectClient.getProjectId()
1052
1013
  if(!r)throw Error("No project ID provided or available from project client")
1053
1014
  this.logger.info("Getting requests for project",{projectId:r,filters:t})
1054
1015
  try{const e={}
1055
- t?.status&&(e.status=t.status),t?.type&&(e.type=t.type),t?.planDocumentId&&(e.planDocumentId=t.planDocumentId),t?.dateFrom&&(e.dateFrom=t.dateFrom),t?.dateTo&&(e.dateTo=t.dateTo),void 0!==t?.limit&&(e.limit=t.limit),void 0!==t?.offset&&(e.offset=t.offset),t?.sortBy&&(e.sortBy="created"===t.sortBy?"created_at":"updated"===t.sortBy?"updated_at":t.sortBy),t?.sortDirection&&(e.sortDirection=t.sortDirection)
1056
- const s=(0,i.isMultiAgentModeEnabled)()
1057
- e.includeLockInfo="true",this.logger.info("Requesting lock info from server",{multiAgentEnabled:s,environmentVariable:process.env.ALCHEMY_MULTI_AGENT,includeLockInfo:e.includeLockInfo,note:"Lock info always requested for operational visibility"}),this.logger.info("Final query parameters to be sent to server",{queryParams:e,projectId:r,url:`/api/projects/${r}/requests`})
1058
- const a=await this.requestWithRetry("GET",`/api/projects/${r}/requests`,void 0,void 0,e),c=(0,o.safeGetResponseData)(a,[])
1059
- return this.logger.info("Successfully retrieved requests",{projectId:r,count:c.length}),(0,n.adaptApiRequestsToDomain)(c)}catch(e){throw this.logger.error("Failed to get requests",{projectId:r,error:(0,a.getErrorMessage)(e)}),e}}async getRequest(e){const t=this.projectClient.getProjectId()
1016
+ t?.status&&(e.status=t.status),t?.type&&(e.type=t.type),t?.planDocumentId&&(e.planDocumentId=t.planDocumentId),t?.dateFrom&&(e.dateFrom=t.dateFrom),t?.dateTo&&(e.dateTo=t.dateTo),void 0!==t?.limit&&(e.limit=t.limit),void 0!==t?.offset&&(e.offset=t.offset),t?.sortBy&&(e.sortBy="created"===t.sortBy?"created_at":"updated"===t.sortBy?"updated_at":t.sortBy),t?.sortDirection&&(e.sortDirection=t.sortDirection),e.includeLockInfo="true",this.logger.info("Requesting lock info from server",{includeLockInfo:e.includeLockInfo,note:"Lock info always requested for operational visibility"}),this.logger.info("Final query parameters to be sent to server",{queryParams:e,projectId:r,url:`/api/projects/${r}/requests`})
1017
+ const s=await this.requestWithRetry("GET",`/api/projects/${r}/requests`,void 0,void 0,e),i=(0,o.safeGetResponseData)(s,[])
1018
+ return this.logger.info("Successfully retrieved requests",{projectId:r,count:i.length}),(0,n.adaptApiRequestsToDomain)(i)}catch(e){throw this.logger.error("Failed to get requests",{projectId:r,error:(0,i.getErrorMessage)(e)}),e}}async getRequest(e){const t=this.projectClient.getProjectId()
1060
1019
  if(!t)throw Error("No project ID provided or available from project client")
1061
1020
  return this.getRequestWithProject(e,t)}async getRequestWithProject(e,t){this.logger.info("Getting request details",{requestId:e,projectId:t})
1062
1021
  try{const r=await this.requestWithRetry("GET",`/api/projects/${t}/requests/${e}`),s=(0,o.safeGetResponseData)(r,{})
1063
1022
  if(!s||!s.id)throw Error("Request not found: "+e)
1064
- return this.logger.info("Successfully retrieved request",{requestId:e,title:s.title,status:s.status}),(0,n.adaptApiRequestToDomain)(s)}catch(r){throw this.logger.error("Failed to get request",{requestId:e,projectId:t,error:(0,a.getErrorMessage)(r)}),r}}async updateRequestStatus(e,t,r){const s=r||this.projectClient.getProjectId()
1023
+ return this.logger.info("Successfully retrieved request",{requestId:e,title:s.title,status:s.status}),(0,n.adaptApiRequestToDomain)(s)}catch(r){throw this.logger.error("Failed to get request",{requestId:e,projectId:t,error:(0,i.getErrorMessage)(r)}),r}}async updateRequestStatus(e,t,r){const s=r||this.projectClient.getProjectId()
1065
1024
  if(!s)throw Error("No project ID provided or available from project client")
1066
1025
  this.logger.info("Updating request status",{requestId:e,status:t,projectId:s})
1067
1026
  try{const r=await this.requestWithRetry("PATCH",`/api/projects/${s}/requests/${e}`,{status:t}),i=(0,o.safeGetResponseData)(r,{})
1068
1027
  if(!i||!i.id)throw Error("Failed to update request status: "+e)
1069
- return this.logger.info("Successfully updated request status",{requestId:e,status:i.status}),(0,n.adaptApiRequestToDomain)(i)}catch(r){throw this.logger.error("Failed to update request status",{requestId:e,status:t,projectId:s,error:(0,a.getErrorMessage)(r)}),r}}async completeRequest(e,t,r,s){const i=s||this.projectClient.getProjectId()
1070
- if(!i)throw Error("No project ID provided or available from project client")
1028
+ return this.logger.info("Successfully updated request status",{requestId:e,status:i.status}),(0,n.adaptApiRequestToDomain)(i)}catch(r){throw this.logger.error("Failed to update request status",{requestId:e,status:t,projectId:s,error:(0,i.getErrorMessage)(r)}),r}}async completeRequest(e,t,r,s){const a=s||this.projectClient.getProjectId()
1029
+ if(!a)throw Error("No project ID provided or available from project client")
1071
1030
  if(!Array.isArray(t)||0===t.length)throw Error("Evidence is required to complete a request")
1072
- this.logger.info("Completing request",{requestId:e,projectId:i,evidenceCount:t.length})
1031
+ this.logger.info("Completing request",{requestId:e,projectId:a,evidenceCount:t.length})
1073
1032
  const c={status:"completed",completionSummary:r,completionEvidences:t}
1074
- try{const t=await this.requestWithRetry("PATCH",`/api/projects/${i}/requests/${e}`,c),s=(0,o.safeGetResponseData)(t,{})
1033
+ try{const t=await this.requestWithRetry("PATCH",`/api/projects/${a}/requests/${e}`,c),s=(0,o.safeGetResponseData)(t,{})
1075
1034
  if(!s||!s.id)throw Error("Invalid response when completing request "+e)
1076
- const a=s
1077
- return this.logger.info("Successfully completed request",{requestId:e,summary:r.substring(0,50)+(r.length>50?"...":"")}),(0,n.adaptApiRequestToDomain)(a)}catch(t){throw this.logger.error("Failed to complete request",{requestId:e,projectId:i,error:(0,a.getErrorMessage)(t)}),t}}isOffline(){return!!this.connectionStatusManager&&this.connectionStatusManager.isOffline()}async listRequests(e){const t=this.projectClient.getProjectId()
1035
+ const i=s
1036
+ return this.logger.info("Successfully completed request",{requestId:e,summary:r.substring(0,50)+(r.length>50?"...":"")}),(0,n.adaptApiRequestToDomain)(i)}catch(t){throw this.logger.error("Failed to complete request",{requestId:e,projectId:a,error:(0,i.getErrorMessage)(t)}),t}}isOffline(){return!!this.connectionStatusManager&&this.connectionStatusManager.isOffline()}async listRequests(e){const t=this.projectClient.getProjectId()
1078
1037
  if(!t)throw Error("No project ID available for listing requests")
1079
1038
  const r={}
1080
1039
  return e?.status&&(r.status=e.status),e?.type&&(r.type=e.type),e?.planDocumentId&&(r.planDocumentId=e.planDocumentId),e?.dateFrom&&(r.dateFrom=e.dateFrom),e?.dateTo&&(r.dateTo=e.dateTo),void 0!==e?.limit&&(r.limit=+e.limit),void 0!==e?.offset&&(r.offset=+e.offset),e?.sortBy&&(r.sortBy=e.sortBy),e?.sortDirection&&["asc","desc"].includes(e.sortDirection)&&(r.sortDirection=e.sortDirection),this.logger.info("Formatted filters for getRequests",{original:e,formatted:r}),this.getRequests(t,r)}async updateRequest(e,t){const r=this.projectClient.getProjectId()
1081
1040
  if(!r)throw Error("No project ID available for updating request")
1082
1041
  this.logger.info("Updating request",{requestId:e,projectId:r})
1083
- const{clientName:n,clientVersion:i,sessionTag:c}=(0,s.getGlobalClientInfo)(),l={...t,clientName:n,clientVersion:i,sessionTag:c}
1042
+ const{clientName:n,clientVersion:a,sessionTag:c}=(0,s.getGlobalClientInfo)(),l={...t,clientName:n,clientVersion:a,sessionTag:c}
1084
1043
  try{const t=await this.requestWithRetry("PATCH",`/api/projects/${r}/requests/${e}`,l),n=(0,o.safeGetResponseData)(t,{})
1085
1044
  if(!n||!n.id)throw Error("Invalid response when completing request "+e)
1086
1045
  const s=n
1087
- return this.logger.info("Successfully updated request",{requestId:e,status:s.status}),s}catch(t){throw this.logger.error("Failed to update request",{requestId:e,projectId:r,error:(0,a.getErrorMessage)(t)}),t}}async lockRequest(e,t,r){this.logger.debug("Locking request",{requestId:e,sessionTag:t,force:r})
1046
+ return this.logger.info("Successfully updated request",{requestId:e,status:s.status}),s}catch(t){throw this.logger.error("Failed to update request",{requestId:e,projectId:r,error:(0,i.getErrorMessage)(t)}),t}}async lockRequest(e,t,r){this.logger.debug("Locking request",{requestId:e,sessionTag:t,force:r})
1088
1047
  try{const n=this.projectClient.getProjectId()
1089
1048
  if(!n)throw Error("Project ID is required for request locking")
1090
1049
  const s=await this.requestWithRetry("POST",`/api/projects/${n}/requests/${e}/lock`,{sessionTag:t,force:r}),i=(0,o.safeGetResponseData)(s,{locked:!1,lockedAt:void 0,lockedBySessionTag:void 0},this.logger)
1091
- return this.logger.info("Request locked successfully",{requestId:e,sessionTag:t,lockedAt:i.lockedAt}),i}catch(r){throw this.logger.error("Failed to lock request",{requestId:e,sessionTag:t,error:(0,a.getErrorMessage)(r)}),r}}async unlockRequest(e,t){this.logger.debug("Unlocking request",{requestId:e,sessionTag:t})
1050
+ return this.logger.info("Request locked successfully",{requestId:e,sessionTag:t,lockedAt:i.lockedAt}),i}catch(r){throw this.logger.error("Failed to lock request",{requestId:e,sessionTag:t,error:(0,i.getErrorMessage)(r)}),r}}async unlockRequest(e,t){this.logger.debug("Unlocking request",{requestId:e,sessionTag:t})
1092
1051
  try{const r=this.projectClient.getProjectId()
1093
1052
  if(!r)throw Error("Project ID is required for request unlocking")
1094
1053
  const n=t?"?sessionTag="+encodeURIComponent(t):"",s=await this.requestWithRetry("DELETE",`/api/projects/${r}/requests/${e}/lock${n}`),i=(0,o.safeGetResponseData)(s,{locked:!0,unlockedAt:void 0},this.logger)
1095
- return this.logger.info("Request unlocked successfully",{requestId:e,sessionTag:t,unlockedAt:i.unlockedAt}),i}catch(r){throw this.logger.error("Failed to unlock request",{requestId:e,sessionTag:t,error:(0,a.getErrorMessage)(r)}),r}}async cleanupExpiredLock(e,t){this.logger.debug("Cleaning up expired lock",{requestId:e,timeoutMinutes:t})
1054
+ return this.logger.info("Request unlocked successfully",{requestId:e,sessionTag:t,unlockedAt:i.unlockedAt}),i}catch(r){throw this.logger.error("Failed to unlock request",{requestId:e,sessionTag:t,error:(0,i.getErrorMessage)(r)}),r}}async cleanupExpiredLock(e,t){this.logger.debug("Cleaning up expired lock",{requestId:e,timeoutMinutes:t})
1096
1055
  try{const r=this.projectClient.getProjectId()
1097
1056
  if(!r)throw Error("Project ID is required for cleaning up expired lock")
1098
1057
  const n=t?{timeoutMinutes:t}:{},s=await this.requestWithRetry("POST",`/api/projects/${r}/requests/${e}/cleanup-expired-lock`,n),i=(0,o.safeGetResponseData)(s,{requestId:e,wasCleanedUp:!1,timeoutMinutes:60,cleanedAt:(new Date).toISOString()},this.logger)
1099
- return this.logger.info("Expired lock cleanup completed",{requestId:e,wasCleanedUp:i.wasCleanedUp,cleanedAt:i.cleanedAt}),{requestId:i.requestId,wasCleanedUp:i.wasCleanedUp,cleanedAt:i.cleanedAt}}catch(r){throw this.logger.error("Failed to clean up expired lock",{requestId:e,timeoutMinutes:t,error:(0,a.getErrorMessage)(r)}),r}}async getRequestLockStatus(e){this.logger.debug("Getting request lock status",{requestId:e})
1058
+ return this.logger.info("Expired lock cleanup completed",{requestId:e,wasCleanedUp:i.wasCleanedUp,cleanedAt:i.cleanedAt}),{requestId:i.requestId,wasCleanedUp:i.wasCleanedUp,cleanedAt:i.cleanedAt}}catch(r){throw this.logger.error("Failed to clean up expired lock",{requestId:e,timeoutMinutes:t,error:(0,i.getErrorMessage)(r)}),r}}async getRequestLockStatus(e){this.logger.debug("Getting request lock status",{requestId:e})
1100
1059
  try{const t=this.projectClient.getProjectId()
1101
1060
  if(!t)throw Error("Project ID is required for checking request lock status")
1102
1061
  const r=await this.requestWithRetry("GET",`/api/projects/${t}/requests/${e}/lock-status`),n=(0,o.safeGetResponseData)(r,{isLocked:!1,lockedAt:void 0,lockedBySessionTag:void 0,timeRemainingMs:0,timeRemainingFormatted:"No lock",isExpired:!0},this.logger)
1103
- return this.logger.debug("Request lock status retrieved",{requestId:e,isLocked:n.isLocked,lockedBySessionTag:n.lockedBySessionTag,timeRemainingFormatted:n.timeRemainingFormatted,isExpired:n.isExpired}),n}catch(t){throw this.logger.error("Failed to get request lock status",{requestId:e,error:(0,a.getErrorMessage)(t)}),t}}setConnectionStatusManager(e){super.setConnectionStatusManager(e),this.logger.debug("Updated connection status manager in RequestClient")}}exports.RequestClient=c},1695(e,exports,t){"use strict"
1062
+ return this.logger.debug("Request lock status retrieved",{requestId:e,isLocked:n.isLocked,lockedBySessionTag:n.lockedBySessionTag,timeRemainingFormatted:n.timeRemainingFormatted,isExpired:n.isExpired}),n}catch(t){throw this.logger.error("Failed to get request lock status",{requestId:e,error:(0,i.getErrorMessage)(t)}),t}}setConnectionStatusManager(e){super.setConnectionStatusManager(e),this.logger.debug("Updated connection status manager in RequestClient")}}exports.RequestClient=a},1695(e,exports,t){"use strict"
1104
1063
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.HealthCheckManager=void 0
1105
1064
  const r=t(8824)
1106
1065
  exports.HealthCheckManager=class{constructor(e,t,r,n={}){this.online=!1,this.forcedOfflineMode=!1,this.checkInterval=null,this.lastSuccessTime=0,this.lastFailureTime=0,this.successCount=0,this.failureCount=0,this.consecutiveFailures=0,this.currentBackoffMs=0,this.lastCheckTime=0,this.baseUrl=e,this.logger=t.child({component:"health-check-manager"}),this.metrics=r,this.options={checkIntervalMs:n.checkIntervalMs??3e4,timeoutMs:n.timeoutMs??5e3,retryCount:n.retryCount??2,onOfflineCallback:n.onOfflineCallback??(()=>{}),onOnlineCallback:n.onOnlineCallback??(()=>{})},this.metrics.setGauge("health_check_success_count",0),this.metrics.setGauge("health_check_failure_count",0),this.metrics.setGauge("health_check_last_success",0),this.metrics.setGauge("health_check_last_failure",0)}async performHealthCheck(){const e=Date.now()
@@ -1115,115 +1074,92 @@ this.forcedOfflineMode=e,t!==e&&(this.logger.info("Offline mode "+(e?"ENABLED":"
1115
1074
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
1116
1075
  const r=t(6183),n=t(355)
1117
1076
  exports.def={name:"complete_task",description:"Mark a task as completed with a summary of work done.",schema:r.CompleteTaskSchema,annotations:{title:"Complete Task",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},handler(e,t){return(0,n.handleCompleteTask)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},1725(e,exports,t){"use strict"
1118
- function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,T.join)(e.basePath||process.cwd(),".alchemy_lab","spawn-debug.log");(0,S.appendFileSync)(o,n)}catch{}}async function n(e){try{const t=`http://localhost:${P}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
1119
- if(!r.ok)return null
1120
- const n=await r.json()
1121
- return n.success?n.data??null:null}catch{return null}}async function o(e,t,o,s,i){const{agent:a="work",prompt:c,requestId:l,allowParallel:u=!1,useExistingSession:d}=e
1122
- if(r(t,"handleSpawn called",{agent:a,promptLength:c.length,requestId:l,useExistingSession:d,cliOriginSessionId:i?.sessionId||null}),!(0,M.isValidAgent)(a)){const e=(0,M.getAgentNames)()
1123
- return{content:[{type:"text",text:`\u274c Unknown agent '${a}'.\n\n**Available agents:** ${e.join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}}try{const e=i?.sessionId
1124
- let n=v.sessionIdentity.getIdentity()?.agentType
1125
- if(r(t,"Spawn agent type check",{callerSessionId:e||null,cachedAgentType:n||null,pid:process.pid}),!n&&e)try{const o=`http://localhost:${P}/api/sessions/${encodeURIComponent(e)}/agent-type`
1077
+ function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,q.join)(e.basePath||process.cwd(),".alchemy_lab","spawn-debug.log");(0,E.appendFileSync)(o,n)}catch{}}async function n(e,t,n,o,s){const{agent:i="work",prompt:a,requestId:c,allowParallel:l=!1,useExistingSession:u}=e
1078
+ if(r(t,"handleSpawn called",{agent:i,promptLength:a.length,requestId:c,useExistingSession:u,cliOriginSessionId:s?.sessionId||null}),!(0,S.isValidAgent)(i))return{content:[{type:"text",text:`\u274c Unknown agent '${i}'.\n\n**Available agents:** ${(0,S.getAgentNames)().join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}
1079
+ try{const e=s?.sessionId
1080
+ let n=b.sessionIdentity.getIdentity()?.agentType
1081
+ if(r(t,"Spawn agent type check",{callerSessionId:e||null,cachedAgentType:n||null,pid:process.pid}),!n&&e)try{const o=`http://localhost:${T}/api/sessions/${encodeURIComponent(e)}/agent-type`
1126
1082
  r(t,"Looking up agent type from action server",{sessionId:e,url:o})
1127
1083
  const s=await fetch(o)
1128
1084
  if(s.ok){const o=await s.json()
1129
- r(t,"Agent type response from action server",{sessionId:e,agentType:o.agentType||null,source:o.source||null,success:o.success}),o.success&&o.agentType&&(n=o.agentType,v.sessionIdentity.updateIdentity({agentType:n}))}else r(t,"Agent type lookup failed",{sessionId:e,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e,error:(0,q.getErrorMessage)(n)})}if(n){const e=(0,M.getAllowedSubagents)(n)
1130
- if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${n}' cannot spawn '${a}'.\n\n**Allowed subagents for ${n}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,q.getErrorMessage)(e)})}let h
1131
- try{const e=await n(a)
1132
- if(h=e?.requestContextMode,!h){const e=(0,M.getBuiltInAgentConfig)(a)
1133
- h=e?.requestContextMode}}catch{}if(h&&"none"!==h&&!l)return{content:[{type:"text",text:`\u274c Agent '${a}' requires a requestId to be provided.\n\nThis agent has requestContextMode: '${h}' which means it needs to work in the context of a specific request.\n\nPlease provide a requestId when spawning this agent.`}],isError:!0}
1134
- const g=await(0,I.getServerUrl)(t,o)
1135
- r(t,"serverUrl resolved",{serverUrl:g})
1136
- const p=t.basePath
1137
- if(!p)throw new w.ValidationError("Working directory not available in context")
1138
- const f=i?.sessionId
1139
- let m=""
1140
- if(s&&l)try{const e=s.getSessionRequestAssociationClient()
1141
- if(e){const t=await e.getSessionsForRequest(l,!0),r=f?t.filter((e=>e.opencodeSessionId!==f)):t
1085
+ r(t,"Agent type response from action server",{sessionId:e,agentType:o.agentType||null,source:o.source||null,success:o.success}),o.success&&o.agentType&&(n=o.agentType,b.sessionIdentity.updateIdentity({agentType:n}))}else r(t,"Agent type lookup failed",{sessionId:e,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e,error:(0,_.getErrorMessage)(n)})}if(n){const e=(0,S.getAllowedSubagents)(n)
1086
+ if(e&&!e.includes(i))return{content:[{type:"text",text:`\u274c Agent type '${n}' cannot spawn '${i}'.\n\n**Allowed subagents for ${n}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,_.getErrorMessage)(e)})}let d
1087
+ try{const e=await async function(e){try{const t=`http://localhost:${T}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
1088
+ if(!r.ok)return null
1089
+ const n=await r.json()
1090
+ return n.success?n.data??null:null}catch{return null}}(i)
1091
+ if(d=e?.requestContextMode,!d){const e=(0,S.getBuiltInAgentConfig)(i)
1092
+ d=e?.requestContextMode}}catch{}if(d&&"none"!==d&&!c)return{content:[{type:"text",text:`\u274c Agent '${i}' requires a requestId to be provided.\n\nThis agent has requestContextMode: '${d}' which means it needs to work in the context of a specific request.\n\nPlease provide a requestId when spawning this agent.`}],isError:!0}
1093
+ const h=await(0,k.getServerUrl)(t,n)
1094
+ r(t,"serverUrl resolved",{serverUrl:h})
1095
+ const g=t.basePath
1096
+ if(!g)throw new y.ValidationError("Working directory not available in context")
1097
+ const p=s?.sessionId
1098
+ let f=""
1099
+ if(o&&c)try{const e=o.getSessionRequestAssociationClient()
1100
+ if(e){const t=await e.getSessionsForRequest(c,!0),r=p?t.filter((e=>e.opencodeSessionId!==p)):t
1142
1101
  if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
1143
- if(!u)return o.warn("Blocked spawn: request already has active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId))}),{content:[{type:"text",text:`\u274c Cannot spawn: Request ${l} already has ${r.length} active worker(s): ${e}\n\nOptions:\n\u2022 Use \`useExistingSession: "${r[0].opencodeSessionId}"\` to send work to the existing session\n\u2022 Use \`allowParallel: true\` if you really need multiple workers on the same request`}],isError:!0}
1144
- m=`\u26a0\ufe0f Warning: Request ${l} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,o.warn("Spawning parallel subagent for request with existing active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){o.debug("Failed to check for existing workers",{error:(0,q.getErrorMessage)(e)})}let y,_,E=c
1145
- l&&(y="requests/"+l,r(t,"Setting initialBranch for agent",{agent:a,requestId:l,initialBranch:y,agentRequestContextMode:h||"undefined"}),E="readonly"===h?`Working on request ${l} (READONLY mode - you cannot modify files, only explore and report).\n\n${c}`:`Working on request ${l}.\n\n${c}`)
1146
- let S=!1
1147
- if(d){if(_=d,o.info("Using existing session for spawn",{sessionId:_,requestId:l}),!g)throw new w.ValidationError("Could not determine OpenCode server URL")
1102
+ if(!l)return n.warn("Blocked spawn: request already has active workers",{requestId:c,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId))}),{content:[{type:"text",text:`\u274c Cannot spawn: Request ${c} already has ${r.length} active worker(s): ${e}\n\nOptions:\n\u2022 Use \`useExistingSession: "${r[0].opencodeSessionId}"\` to send work to the existing session\n\u2022 Use \`allowParallel: true\` if you really need multiple workers on the same request`}],isError:!0}
1103
+ f=`\u26a0\ufe0f Warning: Request ${c} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,n.warn("Spawning parallel subagent for request with existing active workers",{requestId:c,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){n.debug("Failed to check for existing workers",{error:(0,_.getErrorMessage)(e)})}let m,v,C=a
1104
+ c&&(m="requests/"+c,r(t,"Setting initialBranch for agent",{agent:i,requestId:c,initialBranch:m,agentRequestContextMode:d||"undefined"}),C="readonly"===d?`Working on request ${c} (READONLY mode - you cannot modify files, only explore and report).\n\n${a}`:`Working on request ${c}.\n\n${a}`)
1105
+ let E=!1
1106
+ if(u){if(v=u,n.info("Using existing session for spawn",{sessionId:v,requestId:c}),!h)throw new y.ValidationError("Could not determine OpenCode server URL")
1148
1107
  try{let e
1149
- try{const t=await fetch(`http://localhost:${P}/api/project-settings`)
1108
+ try{const t=await fetch(`http://localhost:${T}/api/project-settings`)
1150
1109
  if(t.ok){const r=await t.json()
1151
1110
  if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
1152
- e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${_}/prompt_async`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:E}],...a?{agent:a}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
1111
+ e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${h.replace(/\/$/,"")}/session/${v}/prompt_async`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:C}],...i?{agent:i}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
1153
1112
  if(!r.ok){const e=await r.text().catch((()=>"Unknown error"))
1154
- throw Error(`Failed to send to existing session: ${r.status} ${e}`)}o.info("Prompt sent to existing session",{sessionId:_,agent:a})}catch(e){throw Error("Failed to use existing session: "+(0,q.getErrorMessage)(e))}}else{if(S=!0,r(t,"Creating session via HTTP and spawning CLI"),!g)throw Error("Cannot spawn subagent: no server URL available")
1155
- const i=f;(0,C.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:i}),r(t,"Parent session discovered",{parentSessionId:i})
1156
- const d=g.replace(/\/$/,"")+"/session",h=e.title?e.title:l?`[${l}] ${c.slice(0,40)}${c.length>40?"...":""}`:`${c.slice(0,50)}${c.length>50?"...":""}`,m=await fetch(d,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentID:i,title:h})})
1157
- if(!m.ok)throw Error("Failed to create session: "+m.status)
1158
- const w=await m.json()
1159
- if(!w.id)throw Error("Session created but no ID returned")
1160
- const I=w.id
1161
- r(t,"Pre-created session with parentID",{preCreatedSessionId:I,parentSessionId:i}),o.info("Pre-created session with parentID",{preCreatedSessionId:I,parentSessionId:i})
1162
- const T=(async()=>{if(s)try{const n=s.getCLISessionClient()
1163
- if(!n)return
1164
- let o,c
1165
- if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:v.sessionIdentity.getIdentity()?.agentType||void 0})
1166
- o=e.id,c=e.workflowId,r(t,"Registered parent session in DB",{parentSessionId:i,parentDbId:o,parentWorkflowId:c})}const l=await n.createOrUpdateSession({externalSessionId:I,providerId:"opencode",parentSessionId:o||null,title:h,status:"active",agentType:a,specialization:e.specialization,workflowId:c||void 0})
1167
- r(t,"Registered child session in DB",{childSessionId:I,childDbId:l.id,parentDbId:o})}catch(e){r(t,"Failed to register sessions in DB",{error:(0,q.getErrorMessage)(e)}),o.warn("Failed to register sessions in alchemy DB",{error:(0,q.getErrorMessage)(e)})}})()
1168
- let x
1169
- r(t,"Starting model resolution",{agent:a,cwd:p})
1170
- try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${P}/api/agents/by-name/${a}`})
1171
- const e=await n(a)
1172
- if(r(t,"Agent config result",{agent:a,agentConfig:e||"null",hasConfig:!!e}),e){const n=e.preferredProvider||"inherit",o=e.preferredModelTier||"same"
1173
- r(t,"Agent preferences",{agent:a,preferredProvider:n,preferredTier:o,rawProvider:e.preferredProvider,rawTier:e.preferredModelTier})
1174
- const s=(0,R.resolveAgentModel)(p,n,o)
1175
- r(t,"Model resolution result",{agent:a,result:s}),s.resolved?(x=s.fullModel,r(t,"Resolved agent model",{agent:a,model:x,preferredProvider:n,preferredTier:o})):r(t,"Model resolution fallback",{agent:a,reason:s.reason})}else{const e=(0,M.getBuiltInAgentConfig)(a)
1176
- if(r(t,"No API agent config, checking built-in defaults",{agent:a,builtInConfig:e||"null"}),e){const n=e.preferredProvider||"inherit",o=e.preferredModelTier||"same"
1177
- r(t,"Using built-in agent preferences",{agent:a,preferredProvider:n,preferredTier:o})
1178
- const s=(0,R.resolveAgentModel)(p,n,o)
1179
- r(t,"Built-in model resolution result",{agent:a,result:s}),s.resolved&&(x=s.fullModel,r(t,"Resolved built-in agent model",{agent:a,model:x,preferredProvider:n,preferredTier:o}))}else r(t,"No built-in config found - using default model",{agent:a})}}catch(e){r(t,"Error resolving agent model",{agent:a,error:(0,q.getErrorMessage)(e)})}try{const e=await async function(){try{const e=`http://localhost:${P}/api/project-settings`,t=await fetch(e)
1180
- if(t.ok){const e=await t.json()
1181
- return e?.data?.defaultModel||null}}catch{}return null}()
1182
- if(e)if(x){const o=await n(a)
1183
- "same"===(o?.preferredModelTier||"same")&&(x=e,r(t,"Applied user default model (same tier)",{agent:a,userDefaultModel:e}))}else x=e,r(t,"Using user default model (no agent resolution)",{agent:a,userDefaultModel:e})}catch(e){r(t,"Failed to fetch user default model",{error:(0,q.getErrorMessage)(e)})}if(r(t,"Final resolved model before spawn",{agent:a,resolvedModel:x||"undefined (will use default)"}),await T,l&&y)try{await(0,b.ensureRequestWorktree)(p,l,o)}catch(e){r(t,"Pre-spawn worktree creation failed (non-fatal)",{requestId:l,error:(0,q.getErrorMessage)(e)})}const O=(0,k.spawnDetachedSubagent)({agent:a,prompt:E,cwd:p,sessionId:I,model:x,initialBranch:y,allowParallel:u,serverUrl:g})
1184
- if(!O.success)throw Error("Failed to spawn subagent: "+O.error)
1185
- _=I,r(t,"CLI spawn successful with pre-created session",{sessionId:I,pid:O.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:I,pid:O.pid,parentSessionId:i})}if(s&&l&&_&&"unknown"!==_&&"spawning"!==_)try{const e=s.getSessionRequestAssociationClient()
1186
- if(e&&(e.createAssociation(_,l).then((()=>o.info("Created session-request association",{sessionId:_,requestId:l}))).catch((e=>o.warn("Failed to create session-request association",{error:(0,q.getErrorMessage)(e),sessionId:_,requestId:l}))),"coder"===a)){const e=s.getRequestClient()
1187
- e&&e.updateRequest(l,{cliOrigin:{providerId:"opencode",sessionId:_,createdAt:(new Date).toISOString()}}).catch((e=>o.debug("Failed to update request cliOrigin",{error:(0,q.getErrorMessage)(e)})))}}catch(e){o.warn("Failed to create session-request association",{error:(0,q.getErrorMessage)(e),sessionId:_,requestId:l})}let T=m
1188
- return d?T+=`Prompt sent to existing session ${_}.`:(T+=`Background ${a} subagent spawned successfully.`,_&&"unknown"!==_&&"spawning"!==_&&(T+=`\n[SESSION:${_}]`)),l&&(T+="\nWorking on: "+l),T+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:T}]}}async function s(e,t,r,n,o,s,i){const a=await(0,I.getServerUrl)(r,n)
1189
- if(!a)throw new w.ValidationError("Could not determine OpenCode server URL")
1113
+ throw Error(`Failed to send to existing session: ${r.status} ${e}`)}n.info("Prompt sent to existing session",{sessionId:v,agent:i})}catch(e){throw Error("Failed to use existing session: "+(0,_.getErrorMessage)(e))}}else{E=!0,r(t,"Creating session via spawn-session endpoint")
1114
+ const o=p;(0,I.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:o})
1115
+ try{const s=`http://localhost:${T}/api/spawn-session`,u=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent:i,prompt:a,requestId:c,parentSessionId:o,title:e.title,specialization:e.specialization,allowParallel:l,callerAgentType:b.sessionIdentity.getIdentity()?.agentType}),signal:AbortSignal.timeout(15e3)})
1116
+ if(!u.ok){const e=await u.text().catch((()=>"Unknown error"))
1117
+ throw Error(`Spawn session endpoint failed: ${u.status} ${e}`)}const d=await u.json()
1118
+ if(!d.success||!d.data)throw Error(d.error||"Spawn session returned unsuccessful")
1119
+ const{sessionId:h,model:p,serverUrl:f,initialBranch:y}=d.data
1120
+ m=y
1121
+ const k=(0,w.spawnDetachedSubagent)({agent:i,prompt:C,cwd:g,sessionId:h,model:p,initialBranch:m,allowParallel:l,serverUrl:f})
1122
+ if(!k.success)throw Error("Failed to spawn subagent: "+k.error)
1123
+ v=h,r(t,"Spawn successful via unified endpoint",{sessionId:h,pid:k.pid,parentSessionId:o,model:p}),n.info("Background subagent spawned via unified endpoint",{agent:i,requestId:c,sessionId:h,pid:k.pid,parentSessionId:o})}catch(e){throw Error("Failed to spawn subagent: "+(0,_.getErrorMessage)(e))}}let q=f
1124
+ return u?q+=`Prompt sent to existing session ${v}.`:(q+=`Background ${i} subagent spawned successfully.`,v&&"unknown"!==v&&"spawning"!==v&&(q+=`\n[SESSION:${v}]`)),c&&(q+="\nWorking on: "+c),q+="\n\nThe subagent is now working independently. You can continue with other tasks.","coder"===i&&(q+="\n\nIf this work has shifted or expanded your area of expertise, update your specialization summary with `update_specialization`."),{content:[{type:"text",text:q}]}}async function o(e,t,r,n,o,s,i){const a=await(0,k.getServerUrl)(r,n)
1125
+ if(!a)throw new y.ValidationError("Could not determine OpenCode server URL")
1190
1126
  if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId
1191
1127
  if(t){const r=o.getCLISessionClient()
1192
1128
  if(r){let o=await r.getByExternalId(t)
1193
- o||(o=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),n.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:o?.id})),o&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:o.id,status:"active"}),n.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){n.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,q.getErrorMessage)(e)})}let c=s
1194
- if(!c)try{const t=`http://localhost:${P}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
1129
+ o||(o=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),n.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:o?.id})),o&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:o.id,status:"active"}),n.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){n.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,_.getErrorMessage)(e)})}let c=s
1130
+ if(!c)try{const t=`http://localhost:${T}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
1195
1131
  if(r.ok){const e=await r.json()
1196
- e.success&&e.agentType&&(c=e.agentType)}}catch{n.warn("Agent type lookup failed for session",{sessionId:e})}if(!c)throw new w.ValidationError(`Cannot continue session ${e}: unable to determine agent type. The session's agent type could not be looked up from the action server.`)
1132
+ e.success&&e.agentType&&(c=e.agentType)}}catch{n.warn("Agent type lookup failed for session",{sessionId:e})}if(!c)throw new y.ValidationError(`Cannot continue session ${e}: unable to determine agent type. The session's agent type could not be looked up from the action server.`)
1197
1133
  try{let r
1198
- try{const e=await fetch(`http://localhost:${P}/api/project-settings`)
1134
+ try{const e=await fetch(`http://localhost:${T}/api/project-settings`)
1199
1135
  if(e.ok){const t=await e.json()
1200
1136
  if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
1201
1137
  r={providerID:e,modelID:n.join("/")}}}}catch{}const o=`${a.replace(/\/$/,"")}/session/${e}/prompt_async`,s=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:t}],...c?{agent:c}:{},...r?{model:r}:{}}),signal:AbortSignal.timeout(1e4)})
1202
1138
  if(!s.ok){const e=await s.text().catch((()=>"Unknown error"))
1203
- throw Error(`Failed to send message: ${s.status} ${e}`)}return n.info("Message sent to subagent session",{sessionId:e,agent:c}),{content:[{type:"text",text:`Message sent to session ${e}.\nThe subagent will process it in the background.`}]}}catch(e){throw Error("Failed to continue session: "+(0,q.getErrorMessage)(e))}}function i(e){const t=Math.floor(e/1e3)
1139
+ throw Error(`Failed to send message: ${s.status} ${e}`)}return n.info("Message sent to subagent session",{sessionId:e,agent:c}),{content:[{type:"text",text:`Message sent to session ${e}.\nThe subagent will process it in the background.`}]}}catch(e){throw Error("Failed to continue session: "+(0,_.getErrorMessage)(e))}}function s(e){const t=Math.floor(e/1e3)
1204
1140
  if(60>t)return t+"s"
1205
1141
  const r=Math.floor(t/60)
1206
- return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function a(e){const t=[]
1142
+ return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function i(e){const t=[]
1207
1143
  for(const r of e)if("assistant"===r.info.role&&r.parts)for(const e of r.parts)if("tool"===e.type&&e.tool&&e.state){const n=e.state.input||{}
1208
1144
  let o=e.tool
1209
1145
  const s=n.path||n.file||n.directory,i=n.needle||n.query||n.pattern
1210
1146
  "string"==typeof s?o+=" "+(s.split("/").pop()||s):"string"==typeof i&&(o+=` "${i.length>30?i.slice(0,27)+"...":i}"`),t.push({name:o,state:e.state.status,time:r.info.time.created})}t.sort(((e,t)=>t.time-e.time))
1211
1147
  const r=t.find((e=>"pending"===e.state||"running"===e.state)),n=t.filter((e=>"completed"===e.state||"error"===e.state)).slice(0,3),o=t.length>0?t[0].time:null
1212
- return{current:r?.name??null,recent:n.map((e=>e.name)),lastActivityTime:o}}function c(e){return 1e3>e?"<1s ago":6e4>e?Math.floor(e/1e3)+"s ago":36e5>e?Math.floor(e/6e4)+"m ago":Math.floor(e/36e5)+"h ago"}function l(e,t){const r=e||t,n=Date.now()-r
1213
- return e&&x>n?{status:"working",detail:"last action "+c(n),isReady:!1}:n>O&&e?{status:"stalled",detail:"no activity for "+c(n),isReady:!0}:e?{status:"idle",detail:"no activity for "+c(n),isReady:!0}:{status:"idle",detail:"no tool activity",isReady:!0}}function u(e){let t=0,r=0,n=0
1148
+ return{current:r?.name??null,recent:n.map((e=>e.name)),lastActivityTime:o}}function a(e){return 1e3>e?"<1s ago":6e4>e?Math.floor(e/1e3)+"s ago":36e5>e?Math.floor(e/6e4)+"m ago":Math.floor(e/36e5)+"h ago"}function c(e,t){const r=e||t,n=Date.now()-r
1149
+ return e&&R>n?{status:"working",detail:"last action "+a(n),isReady:!1}:n>P&&e?{status:"stalled",detail:"no activity for "+a(n),isReady:!0}:e?{status:"idle",detail:"no activity for "+a(n),isReady:!0}:{status:"idle",detail:"no tool activity",isReady:!0}}function l(e){let t=0,r=0,n=0
1214
1150
  for(const o of e.trim().split("\n")){if(!o)continue
1215
1151
  const[e,s]=o.split("\t")
1216
- "-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function d(e,r,n,o){const s=await(0,I.getServerUrl)(r,n)
1217
- if(!s)throw new w.ValidationError("Could not determine OpenCode server URL")
1152
+ "-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function u(e,r,n,o){const a=await(0,k.getServerUrl)(r,n)
1153
+ if(!a)throw new y.ValidationError("Could not determine OpenCode server URL")
1218
1154
  n.info("Checking status of subagent session",{sessionId:e})
1219
- try{const c=`${s.replace(/\/$/,"")}/session/${e}`,d=await fetch(c)
1155
+ try{const u=`${a.replace(/\/$/,"")}/session/${e}`,d=await fetch(u)
1220
1156
  if(!d.ok)return{content:[{type:"text",text:`Session ${e} not found or has exited.`}],isError:!0}
1221
- const h=await d.json(),g=`${s.replace(/\/$/,"")}/session/${e}/message`,p=await fetch(g)
1222
- let f={input:0,output:0,reasoning:0},m="",y=l(null,h.time.updated)
1157
+ const h=await d.json(),g=`${a.replace(/\/$/,"")}/session/${e}/message`,p=await fetch(g)
1158
+ let f={input:0,output:0,reasoning:0},m="",y=c(null,h.time.updated)
1223
1159
  if(p.ok){const e=await p.json()
1224
1160
  for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(f.input+=t.info.tokens.input||0,f.output+=t.info.tokens.output||0,f.reasoning+=t.info.tokens.reasoning||0)
1225
- const t=a(e)
1226
- y=l(t.lastActivityTime,h.time.updated),t.current&&(m+="\nCurrent: "+t.current),t.recent.length>0&&(m+="\nRecent: "+t.recent.join(", "))}const w=Date.now()-h.time.created,k=y.status,b=y.isReady,I=f.input+f.output+f.reasoning
1161
+ const t=i(e)
1162
+ y=c(t.lastActivityTime,h.time.updated),t.current&&(m+="\nCurrent: "+t.current),t.recent.length>0&&(m+="\nRecent: "+t.recent.join(", "))}const w=Date.now()-h.time.created,k=y.status,b=y.isReady,I=f.input+f.output+f.reasoning
1227
1163
  let v="",C="",_=null
1228
1164
  if(o)try{const t=o.getSessionRequestAssociationClient()
1229
1165
  if(t){const r=await t.getActiveRequestsForSession(e,!1)
@@ -1234,74 +1170,87 @@ t.length>0&&a.push("Active: "+t.map((e=>e.requestLocalId)).join(", ")),o.length>
1234
1170
  return t?t[1]:null}(h.title||"")),_&&r.basePath){const e=await async function(e,r){try{const{execSync:n}=await Promise.resolve().then(t.t.bind(t,5317,23)),o="requests/"+e
1235
1171
  let s=!1
1236
1172
  try{n("git rev-parse --verify "+o,{cwd:r,stdio:"pipe"}),s=!0}catch{s=!1}if(s){const e=n(`git diff main...${o} --numstat`,{cwd:r,encoding:"utf8"})
1237
- if(e.trim())return u(e)}try{const t=n(`git log main --merges --oneline -n 50 --grep="${e}"`,{cwd:r,encoding:"utf8"}).trim()
1173
+ if(e.trim())return l(e)}try{const t=n(`git log main --merges --oneline -n 50 --grep="${e}"`,{cwd:r,encoding:"utf8"}).trim()
1238
1174
  if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
1239
- if(o.trim())return{...u(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
1175
+ if(o.trim())return{...l(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
1240
1176
  if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
1241
- v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${k} (${y.detail})\nReady for input: ${b?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${I.toLocaleString()} (in: ${f.input.toLocaleString()}, out: ${f.output.toLocaleString()}${f.reasoning>0?", reasoning: "+f.reasoning.toLocaleString():""})${m}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,q.getErrorMessage)(e))}}async function h(e,t,r){const n=await(0,I.getServerUrl)(t,r)
1242
- if(!n)throw new w.ValidationError("Could not determine OpenCode server URL")
1177
+ v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${k} (${y.detail})\nReady for input: ${b?"Yes":"No"}\nAge: ${s(w)}\nTokens: ${I.toLocaleString()} (in: ${f.input.toLocaleString()}, out: ${f.output.toLocaleString()}${f.reasoning>0?", reasoning: "+f.reasoning.toLocaleString():""})${m}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,_.getErrorMessage)(e))}}async function d(e,t,r){const n=await(0,k.getServerUrl)(t,r)
1178
+ if(!n)throw new y.ValidationError("Could not determine OpenCode server URL")
1243
1179
  r.info("Aborting subagent session",{sessionId:e})
1244
1180
  try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
1245
1181
  if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
1246
- throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,q.getErrorMessage)(e))}}async function g(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:c,minTokens:u,maxTokens:d,maxAgeHours:h}=n,g=await(0,I.getServerUrl)(e,t)
1247
- if(!g)throw new w.ValidationError("Could not determine OpenCode server URL")
1182
+ throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,_.getErrorMessage)(e))}}async function h(e,t,r,n={}){const{activeOnly:o=!1,requestId:a,limit:l,minTokens:u,maxTokens:d,maxAgeHours:h}=n,g=await(0,k.getServerUrl)(e,t)
1183
+ if(!g)throw new y.ValidationError("Could not determine OpenCode server URL")
1248
1184
  t.info("Listing sessions",{filters:n})
1249
1185
  try{const e=g.replace(/\/$/,"")+"/session",t=await fetch(e)
1250
1186
  if(!t.ok)throw Error("Failed to fetch sessions: "+t.status)
1251
1187
  let p=await t.json()
1252
1188
  if(0===p.length)return{content:[{type:"text",text:"No sessions found."}]}
1189
+ const f=p
1253
1190
  n.parentSessionId&&(p=p.filter((e=>(e.parentId||e.parentID)===n.parentSessionId))),p.sort(((e,t)=>t.time.created-e.time.created))
1254
- const f=g.replace(/\/$/,"")+"/session/status",m=await fetch(f),y=m.ok?await m.json():{}
1255
- let w=p
1256
- if(o&&(w=w.filter((e=>"idle"!==(y[e.id]?.type||"idle")))),void 0!==h){const e=36e5*h,t=Date.now()-e
1257
- w=w.filter((e=>e.time.created>=t))}if(0===w.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
1258
- let k={}
1259
- if(r)try{const e=r.getCLISessionClient()
1260
- e&&(k=await e.batchEnrich(w.map((e=>e.id))))}catch{}const b=g.replace(/\/$/,""),I=await Promise.allSettled(w.map((e=>fetch(`${b}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),v=[]
1261
- for(let e=0;e<w.length;e++){const t=w[e],r=Date.now()-t.time.created
1262
- let o=0,i=null,c=[],h=l(null,t.time.updated)
1263
- const g=I[e],p="fulfilled"===g.status?g.value:[]
1191
+ const m=g.replace(/\/$/,"")+"/session/status",y=await fetch(m),w=y.ok?await y.json():{}
1192
+ let k=p
1193
+ if(o&&(k=k.filter((e=>"idle"!==(w[e.id]?.type||"idle")))),void 0!==h){const e=36e5*h,t=Date.now()-e
1194
+ k=k.filter((e=>e.time.created>=t))}if(0===k.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
1195
+ let b={}
1196
+ const I=k.map((e=>e.id))
1197
+ let v={},C=[]
1198
+ if("specialist"===n.agentType){const e=new Set(I)
1199
+ for(const t of f){const r=t.parentId||t.parentID
1200
+ r&&e.has(r)&&(v[r]||(v[r]=[]),v[r].push(t.id),C.push(t.id))}}if(r)try{const e=r.getCLISessionClient()
1201
+ if(e){const t=[...I,...C]
1202
+ b=await e.batchEnrich(t)}}catch{}const _=g.replace(/\/$/,""),E=await Promise.allSettled(k.map((e=>fetch(`${_}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),q=[]
1203
+ for(let e=0;e<k.length;e++){const t=k[e],r=Date.now()-t.time.created
1204
+ let o=0,s=null,l=[],h=c(null,t.time.updated)
1205
+ const g=E[e],p="fulfilled"===g.status?g.value:[]
1264
1206
  for(const e of p)"assistant"===e.info.role&&e.info.tokens&&(o+=(e.info.tokens.input||0)+(e.info.tokens.output||0)+(e.info.tokens.reasoning||0))
1265
- if(p.length>0){const e=a(p)
1266
- h=l(e.lastActivityTime,t.time.updated),i=e.current||null,c=e.recent}const f=h.status
1207
+ if(p.length>0){const e=i(p)
1208
+ h=c(e.lastActivityTime,t.time.updated),s=e.current||null,l=e.recent}const f=h.status
1267
1209
  if(void 0!==u&&u>o)continue
1268
1210
  if(void 0!==d&&o>d)continue
1269
- const m=k[t.id]
1211
+ const m=b[t.id]
1270
1212
  if(n.agentType&&(!m||m.agentType!==n.agentType))continue
1271
1213
  if("archived"===m?.status)continue
1272
1214
  let y=""
1273
- const b=[]
1274
- if(m?.associations&&m.associations.length>0){const e=m.associations.filter((e=>!e.endedAt)).map((e=>e.requestLocalId)),t=m.associations.filter((e=>e.endedAt)).map((e=>e.requestLocalId))
1275
- b.push(...e,...t)
1276
- const r=[]
1277
- e.length>0&&r.push("active: "+e.join(", ")),t.length>0&&r.push("prev: "+t.join(", ")),r.length>0&&(y=` [${r.join(" | ")}]`)}if(s&&!b.includes(s))continue
1278
- const C=t.title||"Untitled",_=C.length>50?C.slice(0,47)+"...":C
1279
- v.push({id:t.id,title:_,status:f,age:r,totalTokens:o,requestsInfo:y,allRequestIds:b,statusDetail:h.detail,specialization:m?.specialization??null,currentAction:i,recentActions:c})}if(0===v.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
1280
- const C=c?v.slice(0,c):v,_=C.map((e=>{const t=e.specialization?"\n Specialization: "+e.specialization:"",r=e.currentAction?"\n Current: "+e.currentAction:"",n=e.recentActions.length>0?"\n Recent: "+e.recentActions.join(", "):""
1281
- return`\u2022 ${e.id}\n ${e.title}${t}\n Status: ${e.status} (${e.statusDetail}) | Age: ${i(e.age)} | ${e.totalTokens.toLocaleString()} tokens${e.requestsInfo}${r}${n}`})),E=c&&v.length>c?` (showing ${c} of ${v.length})`:""
1282
- return{content:[{type:"text",text:`Found ${C.length} session${1!==C.length?"s":""}${E}:\n\n${_.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,q.getErrorMessage)(e))}}var p,f=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
1215
+ const I=[],C=[]
1216
+ m?.associations&&C.push(...m.associations)
1217
+ const _=v[t.id]
1218
+ if(_)for(const e of _){const t=b[e]
1219
+ if(t?.associations){const r=w[e]?.type||"idle",n="idle"===r||"stalled"===r
1220
+ for(const e of t.associations)n&&!e.endedAt?C.push({...e,endedAt:"idle"}):C.push(e)}}if(C.length>0){const e=new Map
1221
+ for(const t of C){const r=e.get(t.requestLocalId)
1222
+ void 0!==r&&(r||t.endedAt)||e.set(t.requestLocalId,!t.endedAt)}const t=[...e.entries()].filter((([,e])=>e)).map((([e])=>e)),r=[...e.entries()].filter((([,e])=>!e)).map((([e])=>e))
1223
+ I.push(...t,...r)
1224
+ const n=[]
1225
+ if(t.length>0&&n.push("active: "+t.join(", ")),r.length>0){const e=5,t=r.slice(0,e),o=r.length-t.length
1226
+ n.push(`prev: ${t.join(", ")}${o>0?` +${o} more`:""}`)}n.length>0&&(y=` [${n.join(" | ")}]`)}if(a&&!I.includes(a))continue
1227
+ const S=t.title||"Untitled",T=S.length>50?S.slice(0,47)+"...":S
1228
+ q.push({id:t.id,title:T,status:f,age:r,totalTokens:o,requestsInfo:y,allRequestIds:I,statusDetail:h.detail,specialization:m?.specialization??null,currentAction:s,recentActions:l})}if(0===q.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
1229
+ const S=l?q.slice(0,l):q,T=S.map((e=>{const t=e.specialization?"\n Specialization: "+e.specialization:"",r=e.currentAction?"\n Current: "+e.currentAction:"",o="specialist"!==n.agentType&&e.recentActions.length>0?"\n Recent: "+e.recentActions.join(", "):""
1230
+ return`\u2022 ${e.id}\n ${e.title}${t}\n Status: ${e.status} (${e.statusDetail}) | Age: ${s(e.age)} | ${e.totalTokens.toLocaleString()} tokens${e.requestsInfo}${r}${o}`})),R=l&&q.length>l?` (showing ${l} of ${q.length})`:""
1231
+ return{content:[{type:"text",text:`Found ${S.length} session${1!==S.length?"s":""}${R}:\n\n${T.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,_.getErrorMessage)(e))}}var g,p=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
1283
1232
  var o=Object.getOwnPropertyDescriptor(t,r)
1284
- o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),m=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),y=this&&this.__importStar||(p=function(e){return p=Object.getOwnPropertyNames||function(e){var t=[]
1233
+ o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),f=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),m=this&&this.__importStar||(g=function(e){return g=Object.getOwnPropertyNames||function(e){var t=[]
1285
1234
  for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
1286
- return t},p(e)},function(e){if(e&&e.__esModule)return e
1235
+ return t},g(e)},function(e){if(e&&e.__esModule)return e
1287
1236
  var t={}
1288
- if(null!=e)for(var r=p(e),n=0;n<r.length;n++)"default"!==r[n]&&f(t,e,r[n])
1289
- return m(t,e),t})
1290
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=o,exports.handleContinue=s,exports.handleCheckStatus=d,exports.handleAbort=h,exports.handleListSessions=g,exports.handleSubagentOperations=async function(e,t,r,n,i,a){const c=r.child({tool:"subagent_operations"}),l=n.startTimer("tool_execution_time")
1237
+ if(null!=e)for(var r=g(e),n=0;n<r.length;n++)"default"!==r[n]&&p(t,e,r[n])
1238
+ return f(t,e),t})
1239
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=n,exports.handleContinue=o,exports.handleCheckStatus=u,exports.handleAbort=d,exports.handleListSessions=h,exports.handleSubagentOperations=async function(e,t,r,s,i,a){const c=r.child({tool:"subagent_operations"}),l=s.startTimer("tool_execution_time")
1291
1240
  try{if(e&&!e.operation&&(e.spawn?e.operation="spawn":e.continue?e.operation="continue":e.readMessages?e.operation="read-messages":e.listSessions?e.operation="list-sessions":e.prompt&&(e.agent||e.description)?e={operation:"spawn",spawn:{agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId,allowParallel:e.allowParallel,useExistingSession:e.useExistingSession}}:e.sessionId&&e.prompt&&!e.spawn?e={operation:"continue",sessionId:e.sessionId,continue:{prompt:e.prompt}}:e.sessionId&&(e={operation:"check-status",sessionId:e.sessionId})),e?.spawn&&"string"==typeof e.spawn)try{e.spawn=JSON.parse(e.spawn)}catch{}if(e?.continue&&"string"==typeof e.continue)try{e.continue=JSON.parse(e.continue)}catch{}"spawn"===e?.operation&&e?.prompt&&!e?.spawn&&(e.spawn={agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId},delete e.prompt,delete e.agent,delete e.description,delete e.requestId),"continue"===e?.operation&&e?.prompt&&!e?.continue&&(e.continue={prompt:e.prompt},delete e.prompt)
1292
- const r=E.validateArgs(e,_.SubagentOperationsSchema),{sessionId:u,operation:p}=r
1241
+ const r=C.validateArgs(e,v.SubagentOperationsSchema),{sessionId:g,operation:p}=r
1293
1242
  let f
1294
- switch(c.info("Processing subagent_operations",{operation:p,sessionId:u}),p){case"spawn":f=await o(r.spawn,t,c,i,a)
1243
+ switch(c.info("Processing subagent_operations",{operation:p,sessionId:g}),p){case"spawn":f=await n(r.spawn,t,c,i,a)
1295
1244
  break
1296
- case"continue":f=await s(u,r.continue.prompt,t,c,i,void 0,a)
1245
+ case"continue":f=await o(g,r.continue.prompt,t,c,i,void 0,a)
1297
1246
  break
1298
- case"check-status":f=await d(u,t,c,i)
1247
+ case"check-status":f=await u(g,t,c,i)
1299
1248
  break
1300
- case"abort":f=await h(u,t,c)
1249
+ case"abort":f=await d(g,t,c)
1301
1250
  break
1302
1251
  case"read-messages":const e=r.readMessages?.limit??1
1303
- f=await async function(e,t,r,n){const o=await(0,I.getServerUrl)(r,n)
1304
- if(!o)throw new w.ValidationError("Could not determine OpenCode server URL")
1252
+ f=await async function(e,t,r,n){const o=await(0,k.getServerUrl)(r,n)
1253
+ if(!o)throw new y.ValidationError("Could not determine OpenCode server URL")
1305
1254
  n.info("Reading messages from subagent session",{sessionId:e,limit:t})
1306
1255
  try{const r=`${o.replace(/\/$/,"")}/session/${e}/message?limit=${t}`,n=await fetch(r)
1307
1256
  if(!n.ok){if(404===n.status)return{content:[{type:"text",text:`Session ${e} not found.`}],isError:!0}
@@ -1309,13 +1258,13 @@ throw Error("Failed to fetch messages: "+n.status)}const s=await n.json()
1309
1258
  if(0===s.length)return{content:[{type:"text",text:`Session ${e} has no messages yet.`}]}
1310
1259
  const i=s.map(((e,t)=>{const r="user"===e.info.role?"USER":"ASSISTANT",n=e.parts.filter((e=>"text"===e.type&&e.text)).map((e=>e.text)).join("\n"),o=n.length>5e3?n.slice(0,5e3)+"...[truncated]":n
1311
1260
  return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n${o}`})).join("\n\n---\n\n")
1312
- return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,q.getErrorMessage)(e))}}(u,e,t,c)
1261
+ return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,_.getErrorMessage)(e))}}(g,e,t,c)
1313
1262
  break
1314
- case"list-sessions":const n={activeOnly:r.listSessions?.activeOnly,requestId:r.listSessions?.requestId,limit:r.listSessions?.limit,minTokens:r.listSessions?.minTokens,maxTokens:r.listSessions?.maxTokens,maxAgeHours:r.listSessions?.maxAgeHours,parentSessionId:a?.sessionId}
1315
- f=await g(t,c,i,n)
1263
+ case"list-sessions":const s={activeOnly:r.listSessions?.activeOnly,requestId:r.listSessions?.requestId,limit:r.listSessions?.limit,minTokens:r.listSessions?.minTokens,maxTokens:r.listSessions?.maxTokens,maxAgeHours:r.listSessions?.maxAgeHours,parentSessionId:a?.sessionId}
1264
+ f=await h(t,c,i,s)
1316
1265
  break
1317
- default:throw new w.ValidationError("Unknown operation: "+p)}return l({success:!0}),n.incrementCounter(`subagent_operations_${p}_success`,1),f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,q.getErrorMessage)(e)}],isError:!0}}}
1318
- const w=t(9860),k=t(8035),b=t(2424),I=t(7617),v=t(6688),C=t(7280),_=t(6183),E=y(t(5967)),q=t(8824),S=t(9896),T=t(6928),M=t(8955),R=t(5671),P=3456,x=6e4,O=3e5},1791(e,exports,t){"use strict"
1266
+ default:throw new y.ValidationError("Unknown operation: "+p)}return l({success:!0}),s.incrementCounter(`subagent_operations_${p}_success`,1),f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),s.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,_.getErrorMessage)(e)}],isError:!0}}}
1267
+ const y=t(9860),w=t(8035),k=t(7617),b=t(6688),I=t(7280),v=t(6183),C=m(t(5967)),_=t(8824),E=t(9896),q=t(6928),S=t(8955),T=3456,R=6e4,P=3e5},1791(e,exports,t){"use strict"
1319
1268
  function r(e,t){return t.info("Creating project context middleware",{projectId:e}),(t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
1320
1269
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
1321
1270
  const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
@@ -1517,12 +1466,11 @@ const r=t(1181),n=t(2960),o=t(8824)},2140(e,exports,t){"use strict"
1517
1466
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSwitchToMainBranch=async function(e,t,i,a,c){const l=a.child({tool:"switch_to_main_branch"}),u=Date.now()
1518
1467
  try{if(r.SwitchToMainBranchSchema.parse(e),l.info("Switching to main branch/repository"),!t.workspaceManager)throw(0,n.createServiceError)("WorkspaceManager not available",{phase:"workspace_manager_check"})
1519
1468
  let a=null
1520
- if(t.multiAgentMode){l.info("Multi-agent mode: checking for requests to unlock")
1469
+ l.info("Checking for requests to unlock")
1521
1470
  try{const{sessionTag:e}=(0,o.getGlobalClientInfo)(),r=t.workspaceManager.getCurrentContext()
1522
1471
  if(r.requestId&&"main"!==r.requestId){l.info("Unlocking current request before switching to main",{requestId:r.requestId,sessionTag:e})
1523
1472
  try{const t=await i.unlockRequest(r.requestId,e)
1524
- !1===t.locked?(a=r.requestId,l.info("Successfully unlocked request",{requestId:r.requestId,unlockedAt:t.unlockedAt})):l.warn("Request unlock returned unexpected result",{requestId:r.requestId,result:t})}catch(t){l.warn("Failed to unlock request (continuing with switch to main)",{requestId:r.requestId,sessionTag:e,error:t instanceof Error?t.message:t+""})}}else l.debug("No request context to unlock",{currentRequestId:r.requestId})}catch(e){l.warn("Error during request unlock check (continuing with switch)",{error:(0,s.getErrorMessage)(e)})}}else l.debug("Single-agent mode: skipping request unlock")
1525
- const d=await t.workspaceManager.switchToMain()
1473
+ !1===t.locked?(a=r.requestId,l.info("Successfully unlocked request",{requestId:r.requestId,unlockedAt:t.unlockedAt})):l.warn("Request unlock returned unexpected result",{requestId:r.requestId,result:t})}catch(t){l.warn("Failed to unlock request (continuing with switch to main)",{requestId:r.requestId,sessionTag:e,error:t instanceof Error?t.message:t+""})}}else l.debug("No request context to unlock",{currentRequestId:r.requestId})}catch(e){l.warn("Error during request unlock check (continuing with switch)",{error:(0,s.getErrorMessage)(e)})}const d=await t.workspaceManager.switchToMain()
1526
1474
  if(!d.success)throw(0,n.createServiceError)("Failed to switch to main: "+d.message,{error:d.message})
1527
1475
  const h=Date.now()-u
1528
1476
  c.recordValue("switch_to_main_branch_time",h),c.incrementCounter("switch_to_main_branch_success",1)
@@ -1616,53 +1564,44 @@ for(const e of h){const{normalizedPath:r,fullPath:n}=u.validateAndNormalizePath(
1616
1564
  _.push({source:r,destination:o,fullSource:n,fullDestination:s})}b=u.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("move_files_phase",1,{phase:b})
1617
1565
  const E=await u.validateTaskId(d,_[0].source,r,m,i,I.metricsPrefix),q=E?.requestId,S=await u.validateWorkItemStates(d,_[0].source,r,o,t,m,i,I.metricsPrefix),T=await u.autoPromoteTaskStatus(d,E.status,q,S.request?.status,_[0].source,r,o,m,i,I.metricsPrefix)
1618
1566
  T.taskPromoted&&m.info(`Auto-promoted task ${d} (${E.title||"Untitled"}) to in_progress for file operations`,{taskId:d,taskTitle:E.title,previousStatus:E.status,newStatus:T.newTaskStatus,operationCount:h.length}),T.requestPromoted&&m.info(`Auto-promoted request ${q} to in_progress for file operations`,{requestId:q,previousStatus:S.request?.status,newStatus:T.newRequestStatus,triggeringTaskId:d})
1619
- const M=await u.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:I.metricsPrefix})
1620
- if(!M.success){if(M.isLockConflict)return{content:[{type:"text",text:"\u274c "+M.error}],isError:!0}
1621
- throw Error(M.error)}let R={hadUserMods:!1,userModsCommitHash:void 0}
1567
+ const R=await u.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:I.metricsPrefix})
1568
+ if(!R.success){if(R.isLockConflict)return{content:[{type:"text",text:"\u274c "+R.error}],isError:!0}
1569
+ throw Error(R.error)}let P={hadUserMods:!1,userModsCommitHash:void 0}
1622
1570
  if(t.git)try{m.debug("[MOVE-FILES] Checking for user changes before move operations")
1623
1571
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"move-files",{requestId:q,taskId:d,workspaceManager:t.workspaceManager},m,i)
1624
- e.userChangesCommitted&&(m.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),m.info("User changes committed before move-files operation",{taskId:d,moveOperationsCount:_.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),R={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){m.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),m.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:d,moveOperationsCount:_.length,error:e instanceof Error?e.message:e+""})}m.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:_.length}),b=u.FileOperationPhase.RECORD_CREATION,i.incrementCounter("move_files_phase",1,{phase:b})
1625
- const{toolRecordId:P,localToolRecordId:x}=await u.createFileOperationRecords(d,q,t.projectId,I.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},r,n,m,i,I.metricsPrefix,f)
1626
- w=P,k=P,b=I.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:b})
1627
- const O=[]
1628
- let j=0
1572
+ e.userChangesCommitted&&(m.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),m.info("User changes committed before move-files operation",{taskId:d,moveOperationsCount:_.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),P={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){m.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),m.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:d,moveOperationsCount:_.length,error:e instanceof Error?e.message:e+""})}m.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:_.length}),b=u.FileOperationPhase.RECORD_CREATION,i.incrementCounter("move_files_phase",1,{phase:b})
1573
+ const{toolRecordId:M,localToolRecordId:x}=await u.createFileOperationRecords(d,q,t.projectId,I.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:P.hadUserMods,userModsCommitHash:P.userModsCommitHash},r,n,m,i,I.metricsPrefix,f)
1574
+ w=M,k=M,b=I.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:b})
1575
+ const j=[]
1576
+ let O=0
1629
1577
  for(const e of _){const t={operation:{source:e.source,destination:e.destination},success:!1}
1630
1578
  try{try{await a.default.access(e.fullSource)}catch(t){throw Error("Source path not accessible: "+e.source)}const r=(await a.default.stat(e.fullSource)).isDirectory()
1631
1579
  t.isDirectory=r
1632
1580
  const n=c.default.dirname(e.fullDestination)
1633
- try{await a.default.mkdir(n,{recursive:!0})}catch(e){throw Error("Failed to create destination directory: "+n)}try{throw await a.default.access(e.fullDestination),Error("Destination already exists: "+e.destination)}catch(e){if(!(e instanceof Error&&e.message.includes("ENOENT")))throw e}await a.default.rename(e.fullSource,e.fullDestination),t.success=!0,j++,m.info("Successfully moved "+(r?"directory":"file"),{source:e.source,destination:e.destination,isDirectory:r})}catch(r){t.error=(0,p.getErrorMessage)(r),m.warn(`Failed to move ${e.source} to ${e.destination}`,{error:t.error})}O.push(t)}const $=Date.now()-y
1634
- i.recordValue("move_files_time",$),i.incrementCounter("move_files_operations_total",h.length),i.incrementCounter("move_files_operations_success",j),i.incrementCounter("move_files_operations_failed",h.length-j),j===h.length?i.incrementCounter("move_files_success",1):j>0?i.incrementCounter("move_files_partial_success",1):i.incrementCounter("move_files_total_failure",1)
1581
+ try{await a.default.mkdir(n,{recursive:!0})}catch(e){throw Error("Failed to create destination directory: "+n)}try{throw await a.default.access(e.fullDestination),Error("Destination already exists: "+e.destination)}catch(e){if(!(e instanceof Error&&e.message.includes("ENOENT")))throw e}await a.default.rename(e.fullSource,e.fullDestination),t.success=!0,O++,m.info("Successfully moved "+(r?"directory":"file"),{source:e.source,destination:e.destination,isDirectory:r})}catch(r){t.error=(0,p.getErrorMessage)(r),m.warn(`Failed to move ${e.source} to ${e.destination}`,{error:t.error})}j.push(t)}const $=Date.now()-y
1582
+ i.recordValue("move_files_time",$),i.incrementCounter("move_files_operations_total",h.length),i.incrementCounter("move_files_operations_success",O),i.incrementCounter("move_files_operations_failed",h.length-O),O===h.length?i.incrementCounter("move_files_success",1):O>0?i.incrementCounter("move_files_partial_success",1):i.incrementCounter("move_files_total_failure",1)
1635
1583
  let D=null
1636
- if(j>0){b=u.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:b})
1637
- const e=O.filter((e=>e.success)),r=1===e.length?`Move ${e[0].isDirectory?"directory":"file"} from ${e[0].operation.source} to ${e[0].operation.destination} - ${v}`:`Move ${e.length} ${1===e.length?"item":"items"} - ${v}`
1638
- D=await u.commitToGit(d,_[0].destination,P,x,r,t,m,i,I.metricsPrefix)}b=u.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:b})
1639
- const A=O.filter((e=>e.success)),F=O.filter((e=>!e.success))
1640
- await u.updateFileOperationRecords(d,w,k,_[0].source,I.recordType,j===h.length?`Successfully moved all ${h.length} items`:`Moved ${j}/${h.length} items successfully`,{status:j===h.length?"completed":"partial_success",commitHash:D?.commitHash,previousCommitHash:D?.previousCommitHash,operationCount:h.length,successCount:j,failureCount:h.length-j,successfulOperations:A.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:F.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},j===h.length?`Successfully moved all ${h.length} items`:`Moved ${j}/${h.length} items successfully`,r,n,m,i,I.metricsPrefix)
1584
+ if(O>0){b=u.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:b})
1585
+ const e=j.filter((e=>e.success)),r=1===e.length?`Move ${e[0].isDirectory?"directory":"file"} from ${e[0].operation.source} to ${e[0].operation.destination} - ${v}`:`Move ${e.length} ${1===e.length?"item":"items"} - ${v}`
1586
+ D=await u.commitToGit(d,_[0].destination,M,x,r,t,m,i,I.metricsPrefix)}b=u.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:b})
1587
+ const A=j.filter((e=>e.success)),F=j.filter((e=>!e.success))
1588
+ await u.updateFileOperationRecords(d,w,k,_[0].source,I.recordType,O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,{status:O===h.length?"completed":"partial_success",commitHash:D?.commitHash,previousCommitHash:D?.previousCommitHash,operationCount:h.length,successCount:O,failureCount:h.length-O,successfulOperations:A.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:F.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:P.hadUserMods,userModsCommitHash:P.userModsCommitHash},O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,r,n,m,i,I.metricsPrefix)
1641
1589
  const N=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
1642
1590
  let L=""
1643
- if(j===h.length)L=`Successfully moved all ${h.length} ${1===h.length?"item":"items"}`
1644
- else if(j>0){const e=O.filter((e=>!e.success))
1645
- L=`Successfully moved ${j}/${h.length} items.\n\nFailed operations:\n`+e.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")}else L="All move operations failed:\n"+O.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")
1646
- return D?.commitHash&&(L+="\nCommit: "+D.commitHash.substring(0,8)),N.requestId&&(L+="\nBranch: "+N.requestId),M.lockAcquired&&M.lockedRequestId&&(L+="\n\u{1f512} **Locked request:** "+M.lockedRequestId),{content:[{type:"text",text:L}],isError:0===j}}catch(o){if(e.taskId&&n)try{const r=o instanceof d.NotFoundError||o instanceof d.ValidationError||o instanceof h.ZodError
1591
+ if(O===h.length)L=`Successfully moved all ${h.length} ${1===h.length?"item":"items"}`
1592
+ else if(O>0){const e=j.filter((e=>!e.success))
1593
+ L=`Successfully moved ${O}/${h.length} items.\n\nFailed operations:\n`+e.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")}else L="All move operations failed:\n"+j.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")
1594
+ return D?.commitHash&&(L+="\nCommit: "+D.commitHash.substring(0,8)),N.requestId&&(L+="\nBranch: "+N.requestId),R.lockAcquired&&R.lockedRequestId&&(L+="\n\u{1f512} **Locked request:** "+R.lockedRequestId),{content:[{type:"text",text:L}],isError:0===O}}catch(o){if(e.taskId&&n)try{const r=o instanceof d.NotFoundError||o instanceof d.ValidationError||o instanceof h.ZodError
1647
1595
  await n.createToolRecord({...r?{}:{taskId:e.taskId},projectId:t.projectId,type:"move-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment,error:(0,p.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:"Failed to move files - "+(0,p.getErrorMessage)(o)})}catch(t){m.error("Failed to create failure record for move-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,operationCount:e.operations?.length||0})}const s=Date.now()-y
1648
1596
  if(i.recordValue("move_files_time",s),i.incrementCounter("move_files_errors",1),m.error("Error in move-files operation:",{error:(0,p.getErrorMessage)(o),time:s}),(w||k)&&e.taskId){b=u.FileOperationPhase.RECORD_UPDATE_FAILURE
1649
1597
  try{await u.updateFileOperationRecords(e.taskId,w,k,e.operations?.[0]?.source||"unknown",I.recordType,"Failed to move files",{status:"failed",error:(0,p.getErrorMessage)(o),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",r,n,m,i,I.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:w,error:t instanceof Error?t.message:t+""})}}return u.handleFileOperationError(o,b,m,i,e,I)}}
1650
1598
  const a=i(t(1943)),c=i(t(6928)),l=t(6183),u=s(t(5967)),d=t(9860),h=t(1569),g=t(7478),p=t(8824)},2422(module){"use strict"
1651
- module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2424(e,exports,t){"use strict"
1652
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.ensureRequestWorktree=async function(e,t,i){const a="requests/"+t,c=(0,n.join)(e,s.ALCHEMY_DIR_NAME,"worktrees"),l=(0,n.join)(c,t)
1653
- if((0,r.existsSync)(l))return void i.info("Worktree already exists on disk, skipping pre-spawn creation",{requestId:t,worktreePath:l})
1654
- const u=(0,o.simpleGit)(e);(0,r.mkdirSync)(c,{recursive:!0})
1655
- try{await u.raw(["worktree","prune"])}catch{}const d=await u.branch(),h=d.all.includes(a)
1656
- try{if(h)await u.raw(["worktree","add",l,a]),i.info("Pre-spawn: created worktree for existing branch",{requestId:t,branchName:a,worktreePath:l})
1657
- else{const e=d.all.includes("main")?"main":"master"
1658
- await u.raw(["worktree","add","-b",a,l,e]),i.info("Pre-spawn: created worktree with new branch from latest main",{requestId:t,branchName:a,mainBranch:e,worktreePath:l})}}catch(e){const r=e instanceof Error?e.message:e+""
1659
- i.warn("Pre-spawn: failed to create worktree (MCP process will retry)",{requestId:t,error:r})}}
1660
- const r=t(9896),n=t(6928),o=t(3807),s=t(4139)},2425(e,exports,t){"use strict"
1599
+ module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){"use strict"
1661
1600
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
1662
1601
  const r=t(6183),n=t(3707)
1663
1602
  exports.def={name:"quick_manage",description:"Move, delete, or create directories. Wraps the change in a request/task workflow that auto-completes.\n\nProvide an array of operations, each with operationType and corresponding data:\n\u2022 create-directory: { createDirectory: { path } }\n\u2022 move-files: { moveFiles: { moves: [{ source, destination }] } }\n\u2022 delete-files: { deleteFiles: { targets: [{ path }] } }\n\nFor read-only operations like get-file-info, use manage_files instead.\n\nRequires: title, description, operations.",schema:r.QuickManageSchema,annotations:{title:"Quick Manage",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleQuickChange)(e,"manage",t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},2462(e,exports,t){"use strict"
1664
1603
  Object.defineProperty(exports,"__esModule",{value:!0})
1665
- const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),u=t(8045),d=t(9697),h=t(9196),g=t(5459),p=t(4805),f=t(260),m=t(2283),y=t(4165),w=t(7834),k=t(9373),b=t(6111),I=t(700),v=t(2783),C=t(2601),_=t(1722),E=t(7257),q=t(9230),S=t(5216),T=t(6473),M=t(4921),R=t(8850),P=t(3556),x=t(1391),O=t(6315),j=t(7713),$=t(6252),D=t(213),A=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),U=t(5247),W=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(u.def),(0,r.registerTool)(d.def),(0,r.registerTool)(h.def),(0,r.registerTool)(g.def),(0,r.registerTool)(p.def),(0,r.registerTool)(f.def),(0,r.registerTool)(m.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(k.def),(0,r.registerTool)(b.def),(0,r.registerTool)(I.def),(0,r.registerTool)(v.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(E.def),(0,r.registerTool)(q.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(M.def),(0,r.registerTool)(R.def),(0,r.registerTool)(P.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(j.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(L.def),(0,r.registerTool)(z.def),(0,r.registerTool)(B.def),(0,r.registerTools)(H.metaDefs),(0,r.registerTools)(U.testingDefs),(0,r.registerTools)(W.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
1604
+ const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),u=t(8045),d=t(9697),h=t(9196),g=t(5459),p=t(4805),f=t(260),m=t(2283),y=t(4165),w=t(7834),k=t(9373),b=t(6111),I=t(700),v=t(2783),C=t(2601),_=t(1722),E=t(7257),q=t(9230),S=t(5216),T=t(6473),R=t(4921),P=t(8850),M=t(3556),x=t(1391),j=t(6315),O=t(7713),$=t(6252),D=t(213),A=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),H=t(509),B=t(7613),U=t(3322),G=t(5247),W=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(u.def),(0,r.registerTool)(d.def),(0,r.registerTool)(h.def),(0,r.registerTool)(g.def),(0,r.registerTool)(p.def),(0,r.registerTool)(f.def),(0,r.registerTool)(m.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(k.def),(0,r.registerTool)(b.def),(0,r.registerTool)(I.def),(0,r.registerTool)(v.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(E.def),(0,r.registerTool)(q.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(R.def),(0,r.registerTool)(P.def),(0,r.registerTool)(M.def),(0,r.registerTool)(x.def),(0,r.registerTool)(j.def),(0,r.registerTool)(O.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(L.def),(0,r.registerTool)(z.def),(0,r.registerTool)(H.def),(0,r.registerTool)(B.def),(0,r.registerTools)(U.metaDefs),(0,r.registerTools)(G.testingDefs),(0,r.registerTools)(W.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
1666
1605
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.requestConfig=void 0,exports.areTestsRequiredForCompletion=function(){return exports.requestConfig.requireTestsForCompletion},exports.setTestsRequiredForCompletion=function(e){exports.requestConfig.requireTestsForCompletion=e},exports.getCompletionMode=function(e){return e&&["auto-merge","auto-test-then-merge","manual-review"].includes(e)?e:"auto-merge"},exports.getApprovalMode=function(e){return e&&["none","require-approval"].includes(e)?e:"none"},exports.requestConfig={requireTestsForCompletion:!1}},2537(e,exports,t){"use strict"
1667
1606
  async function r(e,t,r){if(C.has(r)&&_>=t){if(0===t)return 0
1668
1607
  try{return(await y.default.readFile(e,"utf-8")).split("\n").length}catch{return}}}function n(e,t,r){const n="depth"in e,o=n?e:r,s=n?e.isDirectory:e.isDirectory(),a=e.name,c=s?"[\u{1f4c1} DIR]":"[\u{1f4c4} FILE]"
@@ -1952,17 +1891,15 @@ return r.debug("Retrieved request ID from task",{taskId:e,requestId:s.requestId}
1952
1891
  return r.warn("Failed to get request ID from task",{taskId:e,error:i}),n.incrementCounter("get_request_id_from_task_failure",1),o({success:!1,error:t instanceof Error?t.name:"unknown"}),null}},exports.validateTaskId=async function(e,t,r,n,i,a){try{const o=await r.getTask(e)
1953
1892
  return n.info(`Task ID ${e} validated successfully`,{taskId:e,requestId:o.requestId,path:t}),i.incrementCounter(a+"_valid_task_id",1),o}catch(r){const c=(0,s.getErrorMessage)(r)
1954
1893
  if(c.includes("404")||c.toLowerCase().includes("not found")||c.toLowerCase().includes("task not found"))throw n.error(`Task ID ${e} does not exist (404 Not Found)`,{taskId:e,path:t,error:c}),i.incrementCounter(a+"_task_not_found",1),new o.NotFoundError(`Task ${e} not found in project. Please provide a valid task ID.`,{taskId:e,path:t,originalError:r})
1955
- throw n.error("Could not validate task ID "+e,{taskId:e,path:t,error:c}),i.incrementCounter(a+"_task_validation_error",1),new o.ValidationError(`Could not validate task ${e}: ${c}`,{taskId:e,path:t,originalError:r})}},exports.createReopenGuidanceMessage=r,exports.validateWorkItemStates=async function(e,t,n,a,c,l,u,d){try{const h=await n.getTask(e)
1956
- if(l.info("Validating work item states for task "+e,{taskId:e,taskStatus:h.status,requestId:h.requestId,path:t}),l.info("STRICT VALIDATION - Task details",{taskId:e,taskStatus:h.status,requestId:h.requestId,taskTitle:h.title,path:t,timestamp:(new Date).toISOString()}),"completed"===h.status||"canceled"===h.status||"reverted"===h.status){const n=r(e,h.requestId,h.status)
1957
- throw l.error(`STRICT VALIDATION - File operation blocked on ${h.status} task`,{taskId:e,taskStatus:h.status,path:t,errorMessage:n}),u.incrementCounter(`${d}_blocked_${h.status}_task`,1),new o.ValidationError(n,{taskId:e,taskStatus:h.status,path:t,reason:"task_"+h.status})}let g,p
1958
- if(h.requestId)try{if(g=await a.getRequest(h.requestId),l.info("Validating request status for "+h.requestId,{requestId:h.requestId,requestStatus:g.status,taskId:e,path:t}),l.info("STRICT VALIDATION - Request details",{requestId:h.requestId,requestStatus:g.status,requestTitle:g.title,taskId:e,path:t,timestamp:(new Date).toISOString()}),"pending_approval"===g.status||"ready_for_review"===g.status||"completed"===g.status||"canceled"===g.status){const n=r(e,h.requestId,h.status,g.status)
1959
- throw l.error(`STRICT VALIDATION - File operation blocked on ${g.status} request`,{taskId:e,requestId:h.requestId,requestStatus:g.status,path:t,errorMessage:n}),u.incrementCounter(`${d}_blocked_${g.status}_request`,1),new o.ValidationError(n,{taskId:e,requestId:h.requestId,requestStatus:g.status,path:t,reason:"request_"+g.status})}}catch(r){if(r instanceof o.ValidationError)throw r
1894
+ throw n.error("Could not validate task ID "+e,{taskId:e,path:t,error:c}),i.incrementCounter(a+"_task_validation_error",1),new o.ValidationError(`Could not validate task ${e}: ${c}`,{taskId:e,path:t,originalError:r})}},exports.createReopenGuidanceMessage=r,exports.validateWorkItemStates=async function(e,t,n,i,a,c,l,u){try{const a=await n.getTask(e)
1895
+ if(c.info("Validating work item states for task "+e,{taskId:e,taskStatus:a.status,requestId:a.requestId,path:t}),c.info("STRICT VALIDATION - Task details",{taskId:e,taskStatus:a.status,requestId:a.requestId,taskTitle:a.title,path:t,timestamp:(new Date).toISOString()}),"completed"===a.status||"canceled"===a.status||"reverted"===a.status){const n=r(e,a.requestId,a.status)
1896
+ throw c.error(`STRICT VALIDATION - File operation blocked on ${a.status} task`,{taskId:e,taskStatus:a.status,path:t,errorMessage:n}),l.incrementCounter(`${u}_blocked_${a.status}_task`,1),new o.ValidationError(n,{taskId:e,taskStatus:a.status,path:t,reason:"task_"+a.status})}let d,h
1897
+ if(a.requestId)try{if(d=await i.getRequest(a.requestId),c.info("Validating request status for "+a.requestId,{requestId:a.requestId,requestStatus:d.status,taskId:e,path:t}),c.info("STRICT VALIDATION - Request details",{requestId:a.requestId,requestStatus:d.status,requestTitle:d.title,taskId:e,path:t,timestamp:(new Date).toISOString()}),"pending_approval"===d.status||"ready_for_review"===d.status||"completed"===d.status||"canceled"===d.status){const n=r(e,a.requestId,a.status,d.status)
1898
+ throw c.error(`STRICT VALIDATION - File operation blocked on ${d.status} request`,{taskId:e,requestId:a.requestId,requestStatus:d.status,path:t,errorMessage:n}),l.incrementCounter(`${u}_blocked_${d.status}_request`,1),new o.ValidationError(n,{taskId:e,requestId:a.requestId,requestStatus:d.status,path:t,reason:"request_"+d.status})}}catch(r){if(r instanceof o.ValidationError)throw r
1960
1899
  const n=(0,s.getErrorMessage)(r)
1961
- l.warn("Could not validate request status for "+h.requestId,{taskId:e,requestId:h.requestId,error:n,path:t}),u.incrementCounter(d+"_request_validation_warning",1)}if(l.info("Work item state validation passed",{taskId:e,taskStatus:h.status,requestId:h.requestId,requestStatus:g?.status,path:t}),h.requestId){const r=c.workspaceManager
1962
- if("multi-agent"===r?.getCurrentContext().mode)l.debug("Skipping branch switching in multi-agent mode - worktrees handle branch isolation",{taskId:e,requestId:h.requestId,mode:"multi-agent",reason:"worktree_isolation"}),p={switched:!1,message:"Branch switching skipped in multi-agent mode (using worktrees)"}
1963
- else try{p=await(0,i.ensureCorrectBranch)(h.requestId,e,t,c,l,u,d),p.switched&&l.info("Automatically switched to feature branch for file operation",{taskId:e,requestId:h.requestId,branchName:p.branchName,filePath:t})}catch(r){l.warn("Error during automatic branch switching",{taskId:e,requestId:h.requestId,filePath:t,error:(0,s.getErrorMessage)(r)}),p={switched:!1,message:"Branch switching error: "+(0,s.getErrorMessage)(r)}}}return u.incrementCounter(d+"_state_validation_success",1),{task:h,request:g,branchSwitch:p}}catch(r){if(r instanceof o.ValidationError)throw r
1900
+ c.warn("Could not validate request status for "+a.requestId,{taskId:e,requestId:a.requestId,error:n,path:t}),l.incrementCounter(u+"_request_validation_warning",1)}return c.info("Work item state validation passed",{taskId:e,taskStatus:a.status,requestId:a.requestId,requestStatus:d?.status,path:t}),a.requestId&&(c.debug("Worktrees handle branch isolation, skipping branch switching",{taskId:e,requestId:a.requestId}),h={switched:!1,message:"Branch switching skipped (using worktrees)"}),l.incrementCounter(u+"_state_validation_success",1),{task:a,request:d,branchSwitch:h}}catch(r){if(r instanceof o.ValidationError)throw r
1964
1901
  const n=(0,s.getErrorMessage)(r)
1965
- throw l.error("Could not validate work item states for task "+e,{taskId:e,path:t,error:n}),u.incrementCounter(d+"_state_validation_error",1),new o.ValidationError("Could not validate work item states: "+n,{taskId:e,path:t,originalError:r})}},exports.autoPromoteTaskStatus=async function(e,t,r,o,i,a,c,l,u,d){try{let s,h,g=!1,p=!1
1902
+ throw c.error("Could not validate work item states for task "+e,{taskId:e,path:t,error:n}),l.incrementCounter(u+"_state_validation_error",1),new o.ValidationError("Could not validate work item states: "+n,{taskId:e,path:t,originalError:r})}},exports.autoPromoteTaskStatus=async function(e,t,r,o,i,a,c,l,u,d){try{let s,h,g=!1,p=!1
1966
1903
  if("pending"===t&&(l.info(`Auto-promoting task ${e} from pending to in_progress`,{taskId:e,currentStatus:t,path:i}),await a.updateTaskStatus(e,"in_progress"),l.info(`Successfully auto-promoted task ${e} to in_progress`,{taskId:e,previousStatus:t,newStatus:"in_progress",path:i}),u.incrementCounter(d+"_auto_promotion_success",1),g=!0,s="in_progress",r&&o)){const t=await n(r,o,e,"in_progress",c,l,u,d)
1967
1904
  p=t.promoted,h=t.newStatus}return{taskPromoted:g,newTaskStatus:s,requestPromoted:p,newRequestStatus:h}}catch(r){const n=(0,s.getErrorMessage)(r)
1968
1905
  return l.warn(`Failed to auto-promote task ${e} from pending to in_progress`,{taskId:e,currentStatus:t,error:n,path:i}),u.incrementCounter(d+"_auto_promotion_failure",1),{taskPromoted:!1,requestPromoted:!1}}},exports.autoPromoteRequestStatus=n,exports.validateRequestCompletionEligibility=async function(e,t,r,n,i){try{const s=await t.listTasks({requestId:e})
@@ -1983,7 +1920,7 @@ const s=`Cannot mark request as ready/complete. ${t.join(", ")}. Task breakdown:
1983
1920
  throw r.warn("Request completion blocked due to unresolved tasks",{requestId:e,errorMessage:s,taskBreakdown:a}),n.incrementCounter(i+"_request_completion_blocked",1),new o.ValidationError(s,{requestId:e,taskBreakdown:a,unresolvedTasks:c,reason:"unresolved_tasks"})}return n.incrementCounter(i+"_request_completion_eligible",1),{eligible:!0,taskBreakdown:a}}catch(t){if(t instanceof o.ValidationError)throw t
1984
1921
  const a=(0,s.getErrorMessage)(t)
1985
1922
  throw r.error("Could not validate request completion eligibility for "+e,{requestId:e,error:a}),n.incrementCounter(i+"_request_completion_validation_error",1),new o.ValidationError("Could not validate request completion: "+a,{requestId:e,originalError:t})}}
1986
- const o=t(9860),s=t(8824),i=t(7621)},2982(e,exports,t){"use strict"
1923
+ const o=t(9860),s=t(8824)},2982(e,exports,t){"use strict"
1987
1924
  function r(e){const t=[]
1988
1925
  return"write-file"===e.type&&e.metadata?.path?t.push(e.metadata.path):"replace-in-files"===e.type&&e.metadata?.operations?e.metadata.operations.forEach((e=>{e.path&&t.push(e.path)})):"move-files"===e.type&&e.metadata?.successfulOperations?e.metadata.successfulOperations.forEach((e=>{e.destination&&t.push(e.destination)})):"delete-files"===e.type&&e.metadata?.paths?t.push(...e.metadata.paths):"manage-files"===e.type&&e.metadata?.operations&&e.metadata.operations.forEach((e=>{e.createDirectory?.path&&t.push(e.createDirectory.path),e.moveFiles?.moves&&e.moveFiles.moves.forEach((e=>{e.destination&&t.push(e.destination)})),e.deleteFiles?.targets&&e.deleteFiles.targets.forEach((e=>{e.path&&t.push(e.path)}))})),[...new Set(t)]}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleGenerateRequestJournal=async function(e,t,o,c,l){const u=c.child({tool:"generate_request_journal"}),d=l.startTimer("tool_execution_time")
1989
1926
  try{const i=a.parse(e),{requestId:c}=i
@@ -2007,7 +1944,7 @@ if(u.info("Switching to request: "+h),!t.workspaceManager)throw(0,o.createServic
2007
1944
  let g
2008
1945
  try{if(g=await a.getRequest(h),!g)return{content:[{type:"text",text:`\u274c Request not found: Request ${h} does not exist. Please verify the request ID is correct.`}],isError:!0}}catch(e){if(e instanceof o.NotFoundError)return{content:[{type:"text",text:`\u274c Request not found: Request ${h} does not exist. Please verify the request ID is correct.`}],isError:!0}
2009
1946
  throw(0,o.createServiceError)(`Failed to validate request ${h}: ${(0,i.getErrorMessage)(e)}`,{requestId:h,phase:"request_validation"})}if("reverted"===g.status)return{content:[{type:"text",text:`\u274c Branch for request ${h} does not exist - branch was deleted during revert process. Reverted requests cannot be switched to.`}],isError:!0}
2010
- if("completed"===g.status&&u.info(`Attempting to switch to completed request ${h} - branch should be preserved`),"canceled"===g.status&&u.warn(`Attempting to switch to canceled request ${h} - branch may not exist`),t.multiAgentMode){u.info("Multi-agent mode: checking request lock",{requestId:h})
1947
+ "completed"===g.status&&u.info(`Attempting to switch to completed request ${h} - branch should be preserved`),"canceled"===g.status&&u.warn(`Attempting to switch to canceled request ${h} - branch may not exist`),u.info("Checking request lock",{requestId:h})
2011
1948
  try{const{sessionTag:e}=(0,s.getGlobalClientInfo)(),n=await a.getRequestLockStatus(h)
2012
1949
  if(n.isLocked&&n.lockedBySessionTag!==e){if(!n.isExpired){let e=`\u274c Request ${h} is currently locked by another agent (${n.lockedBySessionTag}).`
2013
1950
  return e+="\n\nLock expires in: "+n.timeRemainingFormatted,e=await r(e,h,t,u),{content:[{type:"text",text:e}],isError:!0}}u.info("Attempting to clean up expired lock",{requestId:h,lockedBySessionTag:n.lockedBySessionTag,expiredLock:!0})
@@ -2024,24 +1961,21 @@ try{const t=await a.lockRequest(h,e)
2024
1961
  if(!t.locked)return{content:[{type:"text",text:`\u274c Failed to acquire lock for request ${h}. Another agent may have locked it simultaneously.`}],isError:!0}
2025
1962
  u.info("Successfully acquired request lock",{requestId:h,sessionTag:e,lockedAt:t.lockedAt})}catch(t){u.error("Failed to acquire request lock",{requestId:h,sessionTag:e,error:t instanceof Error?t.message:t+""})
2026
1963
  const r=t instanceof Error?t.message:t+""
2027
- return r.includes("already locked")?{content:[{type:"text",text:`\u274c Request ${h} is already locked by another agent. ${r}`}],isError:!0}:{content:[{type:"text",text:`\u274c Failed to acquire lock for request ${h}: ${r}`}],isError:!0}}}}catch(e){return u.error("Error checking/acquiring request lock",{requestId:h,error:(0,i.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c Failed to check request lock status: "+(0,i.getErrorMessage)(e)}],isError:!0}}}else u.debug("Single-agent mode: skipping request locking",{requestId:h})
2028
- u.info("Using unified workspace switching",{requestId:h})
1964
+ return r.includes("already locked")?{content:[{type:"text",text:`\u274c Request ${h} is already locked by another agent. ${r}`}],isError:!0}:{content:[{type:"text",text:`\u274c Failed to acquire lock for request ${h}: ${r}`}],isError:!0}}}}catch(e){return u.error("Error checking/acquiring request lock",{requestId:h,error:(0,i.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c Failed to check request lock status: "+(0,i.getErrorMessage)(e)}],isError:!0}}u.info("Using unified workspace switching",{requestId:h})
2029
1965
  const p=await t.workspaceManager.switchToRequest(h,{isCompleted:"completed"===g.status})
2030
- if(!p.success){if(t.multiAgentMode)try{const{sessionTag:e}=(0,s.getGlobalClientInfo)()
1966
+ if(!p.success){try{const{sessionTag:e}=(0,s.getGlobalClientInfo)()
2031
1967
  u.warn("Workspace switch failed, attempting to release acquired lock",{requestId:h,sessionTag:e,switchError:p.message}),await a.unlockRequest(h,e),u.info("Successfully released lock after workspace switch failure",{requestId:h})}catch(e){u.error("Failed to release lock after workspace switch failure",{requestId:h,unlockError:e instanceof Error?e.message:e+""})}const e=p.message||"Unknown error"
2032
1968
  if(e.includes("does not exist")||e.includes("Branch for request"))return{content:[{type:"text",text:`\u274c Branch for request ${h} does not exist. This can happen if:\n- Request was reverted (branch deleted during revert)\n- Request was completed and branch was cleaned up\n- Branch was manually deleted\n\nUse 'get-request-information' to check the request status.`}],isError:!0}
2033
1969
  throw(0,o.createServiceError)(`Failed to switch to request ${h}: ${e}`,{requestId:h,error:e})}const f=Date.now()-d
2034
1970
  l.recordValue("switch_to_request_branch_time",f),l.incrementCounter("switch_to_request_branch_success",1)
2035
1971
  const m=["Successfully switched to branch: "+(p.newContext?.branchName||"unknown"),"**Previous branch:** "+(p.previousContext?.branchName||"unknown")]
2036
- return t.multiAgentMode&&m.push("\u{1f512} **Locked request:** "+h),u.info("Successfully switched to request workspace",{requestId:h,mode:p.newContext?.mode,branch:p.newContext?.branchName,duration:f}),{content:[{type:"text",text:m.join("\n")}]}}catch(t){const r=Date.now()-d
1972
+ return m.push("\u{1f512} **Locked request:** "+h),u.info("Successfully switched to request workspace",{requestId:h,mode:p.newContext?.mode,branch:p.newContext?.branchName,duration:f}),{content:[{type:"text",text:m.join("\n")}]}}catch(t){const r=Date.now()-d
2037
1973
  if(l.recordValue("switch_to_request_branch_time",r),l.incrementCounter("switch_to_request_branch_error",1),u.error("Failed to switch to request branch",{requestId:e.requestId,error:(0,i.getErrorMessage)(t),duration:r}),t instanceof o.ValidationError||t instanceof o.NotFoundError)return{content:[{type:"text",text:"\u274c "+t.message}],isError:!0}
2038
1974
  throw t}}
2039
1975
  const n=t(6183),o=t(9860),s=t(5172),i=t(8824)},3217(e,exports,t){"use strict"
2040
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentWorkspaceManager=exports.SingleAgentWorkspaceManager=void 0,exports.createWorkspaceManager=function(e,t,o,s,i,a){return t?new n.MultiAgentWorkspaceManager(e,o,s,i,a):new r.SingleAgentWorkspaceManager(e,o,s,i)}
2041
- const r=t(9653)
2042
- Object.defineProperty(exports,"SingleAgentWorkspaceManager",{enumerable:!0,get(){return r.SingleAgentWorkspaceManager}})
2043
- const n=t(7636)
2044
- Object.defineProperty(exports,"MultiAgentWorkspaceManager",{enumerable:!0,get(){return n.MultiAgentWorkspaceManager}})},3253(e,exports){"use strict"
1976
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentWorkspaceManager=void 0,exports.createWorkspaceManager=function(e,t,n,o,s){return new r.MultiAgentWorkspaceManager(e,t,n,o,s)}
1977
+ const r=t(7636)
1978
+ Object.defineProperty(exports,"MultiAgentWorkspaceManager",{enumerable:!0,get(){return r.MultiAgentWorkspaceManager}})},3253(e,exports){"use strict"
2045
1979
  function t(e){if(0>=e)return"Lock expired"
2046
1980
  const t=Math.floor(e/1e3),r=Math.floor(t/60),n=Math.floor(r/60)
2047
1981
  if(n>0){const e=r%60
@@ -2116,24 +2050,24 @@ const q=_.filter((e=>e.path)),S=_.filter((e=>e.documentId))
2116
2050
  y.info("Operation breakdown",{fileOperations:q.length,documentOperations:S.length})
2117
2051
  const T=[]
2118
2052
  for(const e of q){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.path,t)
2119
- T.push({type:"file",path:r,fullPath:n,replacements:e.replacements,mode:e.mode||"unique"})}const M=[]
2053
+ T.push({type:"file",path:r,fullPath:n,replacements:e.replacements,mode:e.mode||"unique"})}const R=[]
2120
2054
  if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
2121
- for(const e of S)M.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
2122
- if(M.length>0&&t.apiClient){const e=M.map((e=>e.documentId))
2055
+ for(const e of S)R.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
2056
+ if(R.length>0&&t.apiClient){const e=R.map((e=>e.documentId))
2123
2057
  try{await(0,f.ensureDocumentsNotLocked)(e,t.apiClient,y,a,"replace-strings-documents")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2124
2058
  throw e}}I=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_strings_phase",1,{phase:I})
2125
- const R=T.length>0?T[0].path:"document-operation",P=await d.validateTaskId(C,R,r,y,a,v.metricsPrefix),x=P?.requestId
2126
- let O=null
2127
- T.length>0&&x&&(O=await d.validateWorkItemStates(C,T[0].path,r,s,t,y,a,v.metricsPrefix))
2128
- let j={taskPromoted:!1,requestPromoted:!1}
2129
- T.length>0&&x&&O&&(j=await d.autoPromoteTaskStatus(C,P.status,x,O.request?.status,T[0].path,r,s,y,a,v.metricsPrefix),j.taskPromoted&&y.info("Auto-promoted task to in_progress for replace-strings operation",{taskId:C,requestId:x,previousStatus:P.status,newStatus:j.newTaskStatus,triggeringOperation:"replace-strings"}))
2130
- const $=await d.ensureCorrectWorkspaceContext({taskPromoted:j.taskPromoted,requestId:x,context:t,operation:"replace-strings",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
2059
+ const P=T.length>0?T[0].path:"document-operation",M=await d.validateTaskId(C,P,r,y,a,v.metricsPrefix),x=M?.requestId
2060
+ let j=null
2061
+ T.length>0&&x&&(j=await d.validateWorkItemStates(C,T[0].path,r,s,t,y,a,v.metricsPrefix))
2062
+ let O={taskPromoted:!1,requestPromoted:!1}
2063
+ T.length>0&&x&&j&&(O=await d.autoPromoteTaskStatus(C,M.status,x,j.request?.status,T[0].path,r,s,y,a,v.metricsPrefix),O.taskPromoted&&y.info("Auto-promoted task to in_progress for replace-strings operation",{taskId:C,requestId:x,previousStatus:M.status,newStatus:O.newTaskStatus,triggeringOperation:"replace-strings"}))
2064
+ const $=await d.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:x,context:t,operation:"replace-strings",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
2131
2065
  if(!$.success){if($.isLockConflict)return{content:[{type:"text",text:"\u274c "+$.error}],isError:!0}
2132
2066
  throw Error($.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
2133
2067
  for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
2134
- T[e]={...r,path:o,fullPath:s}}}if(M.length>0&&x)try{await(0,g.validateRequestStatusForDocumentOperation)(x,s,y,a,"replace-strings-document")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2068
+ T[e]={...r,path:o,fullPath:s}}}if(R.length>0&&x)try{await(0,g.validateRequestStatusForDocumentOperation)(x,s,y,a,"replace-strings-document")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2135
2069
  throw e}I=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:I})
2136
- const D=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...M.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:A}=await d.createFileOperationRecords(C,x,t.projectId,v.recordType,R,{operationCount:_.length,fileOperations:T.length,documentOperations:M.length,operations:D,userComment:E},r,o,y,a,v.metricsPrefix,c)
2070
+ const D=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...R.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:A}=await d.createFileOperationRecords(C,x,t.projectId,v.recordType,P,{operationCount:_.length,fileOperations:T.length,documentOperations:R.length,operations:D,userComment:E},r,o,y,a,v.metricsPrefix,c)
2137
2071
  if(k=A,b=A,I=v.fileOperationPhase,a.incrementCounter("replace_strings_phase",1,{phase:I}),T.length>0&&t.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
2138
2072
  const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:x,taskId:C,workspaceManager:t.workspaceManager},y,a)
2139
2073
  e.userChangesCommitted&&(y.debug("[REPLACE-STRINGS] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),y.info("User changes committed before replace-strings operation",{taskId:C,fileOperationsCount:T.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){y.debug("[REPLACE-STRINGS] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),y.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:C,fileOperationsCount:T.length,error:e instanceof Error?e.message:e+""})}y.debug("[REPLACE-STRINGS] Proceeding with file operations",{fileCount:T.length})
@@ -2142,21 +2076,21 @@ let N=0,L=0
2142
2076
  for(const e of T){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2143
2077
  try{if(await l.default.access(e.fullPath),!(await l.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
2144
2078
  const r=await l.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await n(r,e.replacements,e.mode)
2145
- t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,o!==r?(await l.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,L++,y.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),N+=t.failedReplacements}catch(r){t.error=(0,m.getErrorMessage)(r),t.failedReplacements=e.replacements.length,N+=t.failedReplacements,y.error("File operation failed",{path:e.path,error:t.error})}F.push(t)}for(const e of M){const r={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2079
+ t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,o!==r?(await l.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,L++,y.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),N+=t.failedReplacements}catch(r){t.error=(0,m.getErrorMessage)(r),t.failedReplacements=e.replacements.length,N+=t.failedReplacements,y.error("File operation failed",{path:e.path,error:t.error})}F.push(t)}for(const e of R){const r={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2146
2080
  try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.documentFileManager.getCachedDocumentInfo(e.documentId)
2147
2081
  r.filename=s?.filename
2148
2082
  const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
2149
- r.replacements=c,r.successfulReplacements=c.filter((e=>e.success)).length,r.failedReplacements=c.filter((e=>!e.success)).length,a!==i?(await l.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),r.success=!0,L++,y.info("Document updated successfully",{documentId:e.documentId,filename:r.filename,successfulReplacements:r.successfulReplacements,failedReplacements:r.failedReplacements})):0===r.failedReplacements&&(r.success=!0),N+=r.failedReplacements}catch(t){r.error=(0,m.getErrorMessage)(t),r.failedReplacements=e.replacements.length,N+=r.failedReplacements,y.error("Document operation failed",{documentId:e.documentId,error:r.error})}F.push(r)}if(M.length>0)try{for(const e of M){const r=F.find((t=>t.documentId===e.documentId))
2150
- r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const z=await d.handleMultiFileGitCommit(C,T,F,L,{operationType:"Replace strings",toolRecordId:b,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),B=d.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J}=B
2151
- try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+M[0]?.documentId,status:G?"completed":"failed",error:G?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:D,totalSuccessfulReplacements:W,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:E,...T.length>0&&z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}},note:G?`String replacement completed: ${H}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`String replacement partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}d.formatMultiFileToolResponse("String Replacement",{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J},z,$)
2083
+ r.replacements=c,r.successfulReplacements=c.filter((e=>e.success)).length,r.failedReplacements=c.filter((e=>!e.success)).length,a!==i?(await l.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),r.success=!0,L++,y.info("Document updated successfully",{documentId:e.documentId,filename:r.filename,successfulReplacements:r.successfulReplacements,failedReplacements:r.failedReplacements})):0===r.failedReplacements&&(r.success=!0),N+=r.failedReplacements}catch(t){r.error=(0,m.getErrorMessage)(t),r.failedReplacements=e.replacements.length,N+=r.failedReplacements,y.error("Document operation failed",{documentId:e.documentId,error:r.error})}F.push(r)}if(R.length>0)try{for(const e of R){const r=F.find((t=>t.documentId===e.documentId))
2084
+ r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const z=await d.handleMultiFileGitCommit(C,T,F,L,{operationType:"Replace strings",toolRecordId:b,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),H=d.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:B,failedOperations:U,totalSuccessfulChanges:G,overallSuccess:W,successfulFiles:V,failedFiles:J}=H
2085
+ try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+R[0]?.documentId,status:W?"completed":"failed",error:W?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:D,totalSuccessfulReplacements:G,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:E,...T.length>0&&z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}},note:W?`String replacement completed: ${B}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`String replacement partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}d.formatMultiFileToolResponse("String Replacement",{successfulOperations:B,failedOperations:U,totalSuccessfulChanges:G,overallSuccess:W,successfulFiles:V,failedFiles:J},z,$)
2152
2086
  let K="## String Replacement Results\n\n"
2153
- if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${H+U}\n`,K+=`- **Successful operations:** ${H}\n`,K+=`- **Failed operations:** ${U}\n`,K+=`- **Total replacements:** ${W} successful, ${N} failed\n\n`,z.success&&z.commitHash&&(K+="**Git Commit:**\n",K+=`- **Commit Hash:** ${z.commitHash.substring(0,8)}\n`,K+=`- **Files Committed:** ${z.filesCommitted.length}\n`,z.previousCommitHash&&(K+=`- **Previous Commit:** ${z.previousCommitHash.substring(0,8)}\n`),K+="\n"),$.lockAcquired&&$.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
2087
+ if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${B+U}\n`,K+=`- **Successful operations:** ${B}\n`,K+=`- **Failed operations:** ${U}\n`,K+=`- **Total replacements:** ${G} successful, ${N} failed\n\n`,z.success&&z.commitHash&&(K+="**Git Commit:**\n",K+=`- **Commit Hash:** ${z.commitHash.substring(0,8)}\n`,K+=`- **Files Committed:** ${z.filesCommitted.length}\n`,z.previousCommitHash&&(K+=`- **Previous Commit:** ${z.previousCommitHash.substring(0,8)}\n`),K+="\n"),$.lockAcquired&&$.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
2154
2088
  if(K+=`**Operation:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,"file"===e.type?K+=`**File:** ${e.path}\n`:(K+="**Document:** "+e.documentId,e.filename&&(K+=` (${e.filename})`),K+="\n"),e.error?K+=`**Error:** ${e.error}\n`:(K+=`**Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(K+=`, ${e.failedReplacements} failed`),K+="\n"),e.replacements.some((e=>!e.success))){K+="**Failed Replacement Details:**\n"
2155
- for(const t of e.replacements.filter((e=>!e.success)))K+=`- "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}}else{K+="**Summary:**\n",K+=`- **Total Operations:** ${F.length}\n`,K+=`- **Successful:** ${H}\n`,K+=`- **Failed:** ${U}\n`,K+=`- **Total Replacements:** ${W} successful, ${N} failed\n\n`,K+="**Detailed Results:**\n\n"
2089
+ for(const t of e.replacements.filter((e=>!e.success)))K+=`- "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}}else{K+="**Summary:**\n",K+=`- **Total Operations:** ${F.length}\n`,K+=`- **Successful:** ${B}\n`,K+=`- **Failed:** ${U}\n`,K+=`- **Total Replacements:** ${G} successful, ${N} failed\n\n`,K+="**Detailed Results:**\n\n"
2156
2090
  for(const e of F){if("file"===e.type?K+=`### File: ${e.path}\n`:(K+="### Document: "+e.documentId,e.filename&&(K+=` (${e.filename})`),K+="\n"),K+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error?K+=`- **Error:** ${e.error}\n`:(K+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(K+=`, ${e.failedReplacements} failed`),K+="\n"),e.replacements.some((e=>!e.success))){K+="- **Failed Replacement Details:**\n"
2157
- for(const t of e.replacements.filter((e=>!e.success)))K+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}K+="\n"}}M.length>0&&(K+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
2091
+ for(const t of e.replacements.filter((e=>!e.success)))K+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}K+="\n"}}R.length>0&&(K+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
2158
2092
  const Y=Date.now()-w
2159
- return y.info("Replace strings operation completed",{duration:Y,success:G,totalOperations:F.length,successfulOperations:H,failedOperations:U}),a.incrementCounter("replace_strings_total",1,{success:G}),{content:[{type:"text",text:K}],isError:!G}}catch(t){const r=Date.now()-w
2093
+ return y.info("Replace strings operation completed",{duration:Y,success:W,totalOperations:F.length,successfulOperations:B,failedOperations:U}),a.incrementCounter("replace_strings_total",1,{success:W}),{content:[{type:"text",text:K}],isError:!W}}catch(t){const r=Date.now()-w
2160
2094
  if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:I}),b)try{await o.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:I,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_strings_errors",1,{phase:I}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
2161
2095
  const l=c(t(1943)),u=t(6183),d=a(t(5967)),h=t(9860),g=t(5003),p=t(7478),f=t(9949),m=t(8824)},3322(e,exports,t){"use strict"
2162
2096
  var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
@@ -2366,17 +2300,17 @@ if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{
2366
2300
  else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},u,w,b,y,h,g,p)
2367
2301
  else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
2368
2302
  v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||I},u,w,b,y,d,h,g,p)}if(v.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
2369
- try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after operation failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:S}),u.workspaceManager&&(await u.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after operation failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${v.content[0].text}\n\nThe request (${S}) and task have been canceled and cleaned up.`}],isError:!0}}const q=v.content[0].text,M=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
2370
- M?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
2371
- try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${I}${M?" (partial success)":""}`},u,d,h,g),f.info("Task completed successfully",{taskId:T})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
2303
+ try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after operation failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:S}),u.workspaceManager&&(await u.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after operation failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${v.content[0].text}\n\nThe request (${S}) and task have been canceled and cleaned up.`}],isError:!0}}const q=v.content[0].text,R=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
2304
+ R?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
2305
+ try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${I}${R?" (partial success)":""}`},u,d,h,g),f.info("Task completed successfully",{taskId:T})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
2372
2306
  try{await w.updateTaskStatus(T,"completed"),f.info("Task completed via direct updateTaskStatus call",{taskId:T})}catch(e){return f.error("Direct task completion ALSO failed - task may be stuck in in_progress",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0,operationType:t,isDocumentOperation:!!C.documentId}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but task completion failed.\n\n**Request:** ${S}\n**Task:** ${T}\n**Issue:** Could not mark task as completed - it remains in 'in_progress' state\n\nThe ${t} operation was successful, but we couldn't automatically complete the task. Please use the complete-task tool manually with taskId: ${T}\n\nError: `+(e instanceof Error?e.message:e+"")}],isError:!0}}}f.debug("Completing request")
2373
- const R=M?`Quick change completed with partial success: ${I}. Some replacements failed - see details below.`:"Quick change completed: "+I,P=M?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2307
+ const P=R?`Quick change completed with partial success: ${I}. Some replacements failed - see details below.`:"Quick change completed: "+I,M=R?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2374
2308
  let x=!1
2375
- try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:R,acceptanceEvidence:[{evidence:P}],testVerification:void 0},u,d,h,g,p)
2309
+ try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:P,acceptanceEvidence:[{evidence:M}],testVerification:void 0},u,d,h,g,p)
2376
2310
  if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text})
2377
- else{try{await y.updateRequest(S,{status:"completed",completionSummary:R}),f.info("Request finalized to completed",{requestId:S})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:S,error:(0,l.getErrorMessage)(e)})}x=!0,f.info("Request completed successfully",{requestId:S})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:S,error:e instanceof Error?e.message:e+""})}if(!x)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:R}),x=!0,f.info("Request completed successfully via direct API call",{requestId:S})}catch(e){return f.error("Direct request completion also failed",{requestId:S,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${S}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const O=Date.now()-m
2378
- let j
2379
- return f.info("Quick fix completed",{requestId:S,duration:O,hasPartialFailure:M}),j=M?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${I}\n**Operation:** ${t}\n**Duration:** ${O}ms\n**Status:** Some operations succeeded, some failed\n\nThe successful changes have been applied and automatically merged to main.\n**Active branch:** main\n\n**\u26a0\ufe0f Note:** This quick-fix had partial failures. See operation details below:\n\n`+q:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${I}\n**Operation:** ${t}\n**Duration:** ${O}ms\n\nThe change has been applied and automatically merged to main.\n**Active branch:** main`+(q.match(/\[RECORD:trec\d{6}\]/)?.[0]?"\n"+q.match(/\[RECORD:trec\d{6}\]/)?.[0]:""),E&&(j+="\n\n\u{1f4a1} **Recommendation:** You've created several quick-edits in a row. For better traceability and organization, consider creating a proper feature or bugfix request with multiple tasks for your next change."),{content:[{type:"text",text:j}]}}catch(e){if(f.error("Quick change workflow failed after request creation, cleaning up",{requestId:S,error:(0,l.getErrorMessage)(e)}),T)try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after workflow failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after workflow failure",{requestId:S}),u.workspaceManager&&(await u.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after workflow failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}throw e}}catch(e){const t=Date.now()-m
2311
+ else{try{await y.updateRequest(S,{status:"completed",completionSummary:P}),f.info("Request finalized to completed",{requestId:S})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:S,error:(0,l.getErrorMessage)(e)})}x=!0,f.info("Request completed successfully",{requestId:S})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:S,error:e instanceof Error?e.message:e+""})}if(!x)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:P}),x=!0,f.info("Request completed successfully via direct API call",{requestId:S})}catch(e){return f.error("Direct request completion also failed",{requestId:S,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${S}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const j=Date.now()-m
2312
+ let O
2313
+ return f.info("Quick fix completed",{requestId:S,duration:j,hasPartialFailure:R}),O=R?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${I}\n**Operation:** ${t}\n**Duration:** ${j}ms\n**Status:** Some operations succeeded, some failed\n\nThe successful changes have been applied and automatically merged to main.\n**Active branch:** main\n\n**\u26a0\ufe0f Note:** This quick-fix had partial failures. See operation details below:\n\n`+q:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${I}\n**Operation:** ${t}\n**Duration:** ${j}ms\n\nThe change has been applied and automatically merged to main.\n**Active branch:** main`+(q.match(/\[RECORD:trec\d{6}\]/)?.[0]?"\n"+q.match(/\[RECORD:trec\d{6}\]/)?.[0]:""),E&&(O+="\n\n\u{1f4a1} **Recommendation:** You've created several quick-edits in a row. For better traceability and organization, consider creating a proper feature or bugfix request with multiple tasks for your next change."),{content:[{type:"text",text:O}]}}catch(e){if(f.error("Quick change workflow failed after request creation, cleaning up",{requestId:S,error:(0,l.getErrorMessage)(e)}),T)try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after workflow failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after workflow failure",{requestId:S}),u.workspaceManager&&(await u.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after workflow failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}throw e}}catch(e){const t=Date.now()-m
2380
2314
  return f.error("Quick change failed",{error:(0,l.getErrorMessage)(e),duration:t}),e instanceof r.ValidationError?{content:[{type:"text",text:"\u274c "+e.message}],isError:!0}:{content:[{type:"text",text:"\u274c Quick change failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
2381
2315
  const r=t(9860),n=t(4079),o=t(9442),s=t(7684),i=t(355),a=t(5715),c=t(7478),l=t(8824)},3807(module){"use strict"
2382
2316
  module.exports=require("simple-git")},3895(e,exports,t){"use strict"
@@ -2445,43 +2379,43 @@ return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModu
2445
2379
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleWriteFile=async function(e,t,r,n,o,s,i,m,y){const w=i.child({tool:"write_file"}),k=m.startTimer("tool_execution_time"),b=Date.now()
2446
2380
  let I,v,C=u.FileOperationPhase.VALIDATION
2447
2381
  const _={toolName:"write_file",operationName:"write",fileOperationPhase:u.FileOperationPhase.FILE_WRITE,recordType:"write-file",metricsPrefix:"write_file",successMessage:"Successfully wrote content",failureMessage:"Failed to write content"}
2448
- try{const r=u.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:E,content:q,format:S,append:T,comment:M}=r,R=!!E,P=!!f
2449
- w.info("Writing content to "+(R?"document":"file"),{taskId:i,filePath:P?f:void 0,documentId:R?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:T,comment:M})
2450
- let x,O,j,$="",D=!1,A=!1
2451
- const F=P?f:void 0
2452
- if(R){if(t.apiClient)try{await(0,p.ensureDocumentNotLocked)(E,t.apiClient,w,m,"write_file-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2382
+ try{const r=u.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:E,content:q,format:S,append:T,comment:R}=r,P=!!E,M=!!f
2383
+ w.info("Writing content to "+(P?"document":"file"),{taskId:i,filePath:M?f:void 0,documentId:P?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:T,comment:R})
2384
+ let x,j,O,$="",D=!1,A=!1
2385
+ const F=M?f:void 0
2386
+ if(P){if(t.apiClient)try{await(0,p.ensureDocumentNotLocked)(E,t.apiClient,w,m,"write_file-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2453
2387
  throw e}if(!t.documentFileManager)throw Error("Document file manager not available")
2454
2388
  $=await t.documentFileManager.getDocumentAsFile(E)
2455
2389
  const e=t.documentFileManager.getCachedDocumentInfo(E)
2456
- j=e?.filename,A=!0,D=!1}C=u.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("write_file_phase",1,{phase:C})
2457
- const N=P?F:"document:"+E,L=await u.validateTaskId(i,N,n,w,m,_.metricsPrefix),z=L?.requestId
2458
- let B=null
2459
- P&&z&&(B=await u.validateWorkItemStates(i,N,n,s,t,w,m,_.metricsPrefix))
2460
- let H={taskPromoted:!1,requestPromoted:!1}
2461
- P&&z&&B&&(H=await u.autoPromoteTaskStatus(i,L.status,z,B.request?.status,N,n,s,w,m,_.metricsPrefix),H.taskPromoted&&w.info("Auto-promoted task to in_progress for file operation",{taskId:i,requestId:z,previousStatus:L.status,newStatus:H.newTaskStatus,triggeringOperation:"write_file"}))
2462
- const U=await u.ensureCorrectWorkspaceContext({taskPromoted:H.taskPromoted,requestId:z,context:t,operation:"write_file",logger:w,metrics:m,metricsPrefix:_.metricsPrefix,requireRequestContext:P})
2390
+ O=e?.filename,A=!0,D=!1}C=u.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("write_file_phase",1,{phase:C})
2391
+ const N=M?F:"document:"+E,L=await u.validateTaskId(i,N,n,w,m,_.metricsPrefix),z=L?.requestId
2392
+ let H=null
2393
+ M&&z&&(H=await u.validateWorkItemStates(i,N,n,s,t,w,m,_.metricsPrefix))
2394
+ let B={taskPromoted:!1,requestPromoted:!1}
2395
+ M&&z&&H&&(B=await u.autoPromoteTaskStatus(i,L.status,z,H.request?.status,N,n,s,w,m,_.metricsPrefix),B.taskPromoted&&w.info("Auto-promoted task to in_progress for file operation",{taskId:i,requestId:z,previousStatus:L.status,newStatus:B.newTaskStatus,triggeringOperation:"write_file"}))
2396
+ const U=await u.ensureCorrectWorkspaceContext({taskPromoted:B.taskPromoted,requestId:z,context:t,operation:"write_file",logger:w,metrics:m,metricsPrefix:_.metricsPrefix,requireRequestContext:M})
2463
2397
  if(!U.success){if(U.isLockConflict)return{content:[{type:"text",text:"\u274c "+U.error}],isError:!0}
2464
- throw Error(U.error)}if(U.switched&&w.info("Workspace context successfully established",{requestId:z,branchName:U.branchName,operation:"write_file"}),P&&F){const e=u.validateAndNormalizePath(F,t)
2465
- x=e.normalizedPath,O=e.fullPath,$=O
2466
- try{await c.default.access(O),A=!0}catch{A=!1,D=!0}w.debug("Path validated with correct workspace context",{rawPath:F,normalizedPath:x,fullPath:O,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})}if(R&&z)try{await(0,h.validateRequestStatusForDocumentOperation)(z,s,w,m,"write_file-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2398
+ throw Error(U.error)}if(U.switched&&w.info("Workspace context successfully established",{requestId:z,branchName:U.branchName,operation:"write_file"}),M&&F){const e=u.validateAndNormalizePath(F,t)
2399
+ x=e.normalizedPath,j=e.fullPath,$=j
2400
+ try{await c.default.access(j),A=!0}catch{A=!1,D=!0}w.debug("Path validated with correct workspace context",{rawPath:F,normalizedPath:x,fullPath:j,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})}if(P&&z)try{await(0,h.validateRequestStatusForDocumentOperation)(z,s,w,m,"write_file-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2467
2401
  throw e}C=u.FileOperationPhase.RECORD_CREATION,m.incrementCounter("write_file_phase",1,{phase:C})
2468
- const{toolRecordId:W}=await u.createFileOperationRecords(i,z,t.projectId,_.recordType,N,{operationType:R?"document":"file",documentId:R?E:void 0,documentFilename:j,filePath:P?x:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S||"text",append:T||!1,wasFileCreated:!A,userComment:M},n,o,w,m,_.metricsPrefix,y)
2469
- let G
2470
- if(I=W,v=W,C=_.fileOperationPhase,m.incrementCounter("write_file_phase",1,{phase:C}),"json"===S)if("string"==typeof q)try{JSON.parse(q),G=q}catch(e){throw new d.ValidationError("Content is not valid JSON")}else G=JSON.stringify(q,null,2)
2471
- else G="string"==typeof q?q:JSON.stringify(q,null,2)
2472
- let V=G
2473
- if(P&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
2402
+ const{toolRecordId:G}=await u.createFileOperationRecords(i,z,t.projectId,_.recordType,N,{operationType:P?"document":"file",documentId:P?E:void 0,documentFilename:O,filePath:M?x:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S||"text",append:T||!1,wasFileCreated:!A,userComment:R},n,o,w,m,_.metricsPrefix,y)
2403
+ let W
2404
+ if(I=G,v=G,C=_.fileOperationPhase,m.incrementCounter("write_file_phase",1,{phase:C}),"json"===S)if("string"==typeof q)try{JSON.parse(q),W=q}catch(e){throw new d.ValidationError("Content is not valid JSON")}else W=JSON.stringify(q,null,2)
2405
+ else W="string"==typeof q?q:JSON.stringify(q,null,2)
2406
+ let V=W
2407
+ if(M&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
2474
2408
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"write_file",{requestId:t.workspaceManager?.getCurrentContext()?.requestId,taskId:i},w,m)
2475
2409
  e.userChangesCommitted&&(w.debug("[WRITE-FILE] User changes committed before write operation",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before write-file operation",{taskId:i,path:x,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[WRITE-FILE] Pre-tool commit failed, continuing with write",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with write operation",{taskId:i,path:x,error:e instanceof Error?e.message:e+""})}if(!$)throw Error("Target path not properly initialized")
2476
- if(w.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:$}),T&&A)try{V=await c.default.readFile($,"utf8")+G}catch(e){w.warn("Failed to read existing content for append",{error:e})}const J=a.default.dirname($)
2477
- if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile($,V,"utf8"),w.info("Content written successfully",{path:P?x:"document:"+E,finalLength:V.length,append:T,wasCreated:D}),R){t.documentFileManager.markForSync(E)
2410
+ if(w.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:$}),T&&A)try{V=await c.default.readFile($,"utf8")+W}catch(e){w.warn("Failed to read existing content for append",{error:e})}const J=a.default.dirname($)
2411
+ if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile($,V,"utf8"),w.info("Content written successfully",{path:M?x:"document:"+E,finalLength:V.length,append:T,wasCreated:D}),P){t.documentFileManager.markForSync(E)
2478
2412
  try{await t.documentFileManager.syncDocument(E),w.info("Document synced successfully",{documentId:E})}catch(e){w.warn("Failed to sync document immediately",{documentId:E,error:e})}}let K,Y,Q=null
2479
- if(P){if(C=u.FileOperationPhase.GIT_COMMIT,m.incrementCounter("write_file_phase",1,{phase:C}),t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
2413
+ if(M){if(C=u.FileOperationPhase.GIT_COMMIT,m.incrementCounter("write_file_phase",1,{phase:C}),t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
2480
2414
  Y=e.branchName,w.debug("Retrieved branch name from workspace manager",{branchName:Y,requestId:e.requestId,mode:e.mode,isMainBranch:e.isMainBranch})}try{const e=`${D?"Create":T?"Append to":"Update"} ${x} (${v})`,r=await u.commitToGit(i,x,v,v,e,t,w,m,_.metricsPrefix)
2481
- K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:x,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:P?x:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:T&&A,operationType:R?"document":"file",processingTime:Date.now()-b,userComment:M,...P&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(R?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${D?"Created":T?"Appended to":"Updated"} ${R?`document ${E}${j?` (${j})`:""}`:"file "+x}**\n`
2482
- Z+=`**Content Length:** ${V.length} characters\n`,P&&Y&&(Z+=`**Branch:** ${Y}\n`),U.lockAcquired&&U.lockedRequestId&&(Z+=`**Locked request:** ${U.lockedRequestId}\n`),P&&K&&(Z+=`**Commit Hash:** ${K.substring(0,8)}\n`,Q&&(Z+=`**Previous Commit:** ${Q.substring(0,8)}\n`)),v&&(Z+=`[RECORD:${v}]\n`),R&&(Z+=`\n**Document Update:** The document content has been updated and synced back to the tracking system. You can continue editing using other file modification tools with documentId \`${E}\`.`)
2415
+ K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:x,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:M?x:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:T&&A,operationType:P?"document":"file",processingTime:Date.now()-b,userComment:R,...M&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(P?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${D?"Created":T?"Appended to":"Updated"} ${P?`document ${E}${O?` (${O})`:""}`:"file "+x}**\n`
2416
+ Z+=`**Content Length:** ${V.length} characters\n`,M&&Y&&(Z+=`**Branch:** ${Y}\n`),U.lockAcquired&&U.lockedRequestId&&(Z+=`**Locked request:** ${U.lockedRequestId}\n`),M&&K&&(Z+=`**Commit Hash:** ${K.substring(0,8)}\n`,Q&&(Z+=`**Previous Commit:** ${Q.substring(0,8)}\n`)),v&&(Z+=`[RECORD:${v}]\n`),P&&(Z+=`\n**Document Update:** The document content has been updated and synced back to the tracking system. You can continue editing using other file modification tools with documentId \`${E}\`.`)
2483
2417
  const X=Date.now()
2484
- return w.info("Write operation completed successfully",{duration:X-b,path:P?x:"document:"+E,contentLength:V.length,wasCreated:D}),k({tool:"write_file",success:!0}),m.incrementCounter("write_file_total",1,{success:!0}),t.workspaceManager?.largeFileWarning&&(Z+=t.workspaceManager.largeFileWarning,t.workspaceManager.largeFileWarning=""),{content:[{type:"text",text:Z}]}}catch(t){const r=Date.now()-b
2418
+ return w.info("Write operation completed successfully",{duration:X-b,path:M?x:"document:"+E,contentLength:V.length,wasCreated:D}),k({tool:"write_file",success:!0}),m.incrementCounter("write_file_total",1,{success:!0}),t.workspaceManager?.largeFileWarning&&(Z+=t.workspaceManager.largeFileWarning,t.workspaceManager.largeFileWarning=""),{content:[{type:"text",text:Z}]}}catch(t){const r=Date.now()-b
2485
2419
  if(w.error("Write operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:C}),v)try{await o.updateToolRecord(v,{metadata:{path:e?.path,status:"failed",error:(0,f.getErrorMessage)(t),phase:C,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return k({tool:"write_file",success:!1}),m.incrementCounter("write_file_errors",1,{phase:C}),{content:[{type:"text",text:"\u274c **Write Operation Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
2486
2420
  const a=i(t(6928)),c=i(t(1943)),l=t(6183),u=s(t(5967)),d=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824)},4139(e,exports){"use strict"
2487
2421
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ALCHEMY_DIR_NAME=exports.TOKEN_DIR_NAME=void 0,exports.TOKEN_DIR_NAME="alchemy-key",exports.ALCHEMY_DIR_NAME=".alchemy_lab"},4165(e,exports,t){"use strict"
@@ -2881,13 +2815,13 @@ exports.WorktreeGitAdapter=class{constructor(e,t,r,o,s){this.mainGit=e,this.work
2881
2815
  try{const r=o.WorkspaceValidation.validateRequestId(e)
2882
2816
  if(!r.isValid){const t="Invalid request ID: "+r.errors.join(", ")
2883
2817
  throw o.WorkspaceLogging.logOperation(this.logger,"error",t,e,"multi-agent","setupWorkspace"),Error(t)}const n=r.sanitized,s="requests/"+n,i=await this.branchManager.getBaseBranch()
2884
- o.WorkspaceLogging.logOperation(this.logger,"info","Setting up multi-agent workspace",e,"multi-agent","setupWorkspace",{branchName:s,mainBranch:i,architecture:"aligned-with-single-agent"})
2818
+ o.WorkspaceLogging.logOperation(this.logger,"info","Setting up multi-agent workspace",e,"multi-agent","setupWorkspace",{branchName:s,mainBranch:i,architecture:"standard"})
2885
2819
  const a=await this.getWorktreeInfo(n)
2886
2820
  if(!a){if(this.logger.info("No worktree found, checking for quick-edit branch in main repo",{requestId:n,branchName:s}),!(await this.mainGit.branch()).all.includes(s))throw Error(`No worktree or branch found for request ${e}. Use initializeRequest() first.`)
2887
2821
  return this.logger.info("Found quick-edit branch in main repo, using main repo for operations",{requestId:n,branchName:s}),Date.now(),{mode:"multi-agent",requestId:n,branchName:s,workingDirectory:this.worktreeManager.mainRepoPath,isWorktree:!1,branchInfo:{mainBranch:i,currentBranch:s},worktreeInfo:void 0}}const c=Date.now()-t
2888
- return o.WorkspaceLogging.logOperation(this.logger,"info","Worktree info retrieved successfully",e,"multi-agent","setupWorkspace",{worktreePath:a.worktreePath,branchName:a.branchName,duration:c,architecture:"aligned-with-single-agent"}),this.currentRequestId=n,this.currentWorktreePath=a.worktreePath,{mode:"multi-agent",requestId:n,branchName:s,workingDirectory:a.worktreePath,isWorktree:!0,branchInfo:{mainBranch:i,currentBranch:s},worktreeInfo:{worktreePath:a.worktreePath,branchName:a.branchName}}}catch(r){const n=Date.now()-t
2822
+ return o.WorkspaceLogging.logOperation(this.logger,"info","Worktree info retrieved successfully",e,"multi-agent","setupWorkspace",{worktreePath:a.worktreePath,branchName:a.branchName,duration:c,architecture:"standard"}),this.currentRequestId=n,this.currentWorktreePath=a.worktreePath,{mode:"multi-agent",requestId:n,branchName:s,workingDirectory:a.worktreePath,isWorktree:!0,branchInfo:{mainBranch:i,currentBranch:s},worktreeInfo:{worktreePath:a.worktreePath,branchName:a.branchName}}}catch(r){const n=Date.now()-t
2889
2823
  throw o.WorkspaceLogging.logOperation(this.logger,"error","Failed to set up multi-agent workspace",e,"multi-agent","setupWorkspace",{error:(0,i.getErrorMessage)(r),duration:n}),r}}async detectConflicts(e,t){const r=e.isWorktree&&e.worktreeInfo,n=r?e.worktreeInfo.worktreePath:e.workingDirectory
2890
- return this.logger.info("Detecting conflicts in multi-agent mode",{requestId:e.requestId,sourceBranch:t.sourceBranch,targetBranch:t.targetBranch,workingPath:n,isWorktree:r,isQuickEdit:!r}),await this.conflictDetector.detectConflicts({mode:r?"multi-agent":"single-agent",worktreePath:r?e.worktreeInfo.worktreePath:e.workingDirectory,logger:this.logger,requestId:t.requestId,sourceBranch:t.sourceBranch,targetBranch:t.targetBranch})}async stageAndCommitChanges(e){if(!e.worktreeInfo)throw Error("Worktree info not available in context")
2824
+ return this.logger.info("Detecting conflicts in multi-agent mode",{requestId:e.requestId,sourceBranch:t.sourceBranch,targetBranch:t.targetBranch,workingPath:n,isWorktree:r,isQuickEdit:!r}),await this.conflictDetector.detectConflicts({mode:"multi-agent",worktreePath:r?e.worktreeInfo.worktreePath:e.workingDirectory,logger:this.logger,requestId:t.requestId,sourceBranch:t.sourceBranch,targetBranch:t.targetBranch})}async stageAndCommitChanges(e){if(!e.worktreeInfo)throw Error("Worktree info not available in context")
2891
2825
  this.logger.info("Staging and committing changes in multi-agent mode",{requestId:e.requestId,worktreePath:e.worktreeInfo.worktreePath})
2892
2826
  const t=(0,r.simpleGit)(e.worktreeInfo.worktreePath)
2893
2827
  try{const r=await t.status()
@@ -2932,7 +2866,7 @@ module.exports=require("winston")},5172(e,exports){"use strict"
2932
2866
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.setGlobalClientInfo=function(e,r,n){const o=process.env.ALCHEMY_SESSION_TAG||n||function(){const e=new Date
2933
2867
  return`mcp-${(e.getHours()+"").padStart(2,"0")}${(e.getMinutes()+"").padStart(2,"0")}${(e.getSeconds()+"").padStart(2,"0")}-${Math.random().toString(36).substring(2,7)}`}()
2934
2868
  t={name:e,version:r,sessionTag:o}},exports.setSessionTag=function(e){t.sessionTag=e},exports.getGlobalClientInfo=function(){return{clientName:t.name,clientVersion:t.version,sessionTag:t.sessionTag}}
2935
- let t={name:"Unknown Client",version:"Unknown Version",sessionTag:"unknown-session"}},5187(e,exports,t){"use strict"
2869
+ let t={name:"OpenCode",version:"1.0.0",sessionTag:"unknown-session"}},5187(e,exports,t){"use strict"
2936
2870
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.CLISessionClient=void 0
2937
2871
  const r=t(7645),n=t(2161)
2938
2872
  class o extends r.ConnectionAwareClient{constructor(e,t,r,n,o,s,i){const a=t.child({component:"cli-session-client"}),c=s||{isInOfflineMode(){return!1},isOffline(){return!1},setOfflineMode(){},async checkConnectivity(){return!0},getHealthCheckStats(){return{isOffline:!1,consecutiveFailures:0,currentBackoffMs:0,lastCheckTime:0}},cleanup(){}}
@@ -2964,42 +2898,7 @@ const r=await this.requestWithRetry("POST",`/api/projects/${t}/cli-sessions/batc
2964
2898
  return(0,n.safeGetResponseData)(r,{},this.logger)}}exports.CLISessionClient=o},5216(e,exports,t){"use strict"
2965
2899
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
2966
2900
  const r=t(6183),n=t(4041)
2967
- exports.def={name:"switch_to_branch",description:'Switch between main branch and request feature branches.\n\nUSAGE:\n- Main branch: {} or {"branch": "main"}\n- Request branch: {"branch": "req123"}\n\nAll file operations use the active branch context. Usually only needed if we want to read files or do a search on a branch we are currently not working on.',schema:r.SwitchToBranchSchema,annotations:{title:"Switch to Branch",readOnlyHint:!1,destructiveHint:!1},handler(e,t){return(0,n.handleSwitchToBranch)(e,t.context,t.apiClient.getRequestClient(),t.logger,t.metrics)}}},5218(e,exports,t){"use strict"
2968
- var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
2969
- var o=Object.getOwnPropertyDescriptor(t,r)
2970
- o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
2971
- for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
2972
- return t},r(e)},function(e){if(e&&e.__esModule)return e
2973
- var t={}
2974
- if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
2975
- return o(t,e),t})
2976
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentConfigManager=void 0,exports.parseSingleFlag=function(e){for(let t=0;t<e.length;t++)if("--single"===e[t])return!0},exports.isMultiAgentModeEnabled=function(e,t){const r=e||process.cwd(),n=c.join(r,l.ALCHEMY_DIR_NAME),o=c.join(n,"config.json")
2977
- t?.debug("isMultiAgentModeEnabled called",{baseDir:e,configPath:o})
2978
- try{if(a.existsSync(n)||(t?.debug(".alchemy_lab directory does not exist, creating it"),a.mkdirSync(n,{recursive:!0})),a.existsSync(o)){t?.debug("Config file exists, reading")
2979
- const e=a.readFileSync(o,"utf-8"),r=JSON.parse(e),n=!1!==r.multiAgent
2980
- return t?.debug("Parsed config",{multiAgent:n,config:r}),n}{t?.debug("Config file does not exist, creating with defaults")
2981
- const e={multiAgent:!0,lockTimeout:3600,worktreeCleanupDelay:900,maxWorktreeAge:24,cleanupInterval:15,preserveBranchesOnCleanup:!0,maxConcurrentSessions:10,sessionTimeoutWarning:45}
2982
- return a.writeFileSync(o,JSON.stringify(e,null,2),"utf-8"),t?.debug("Created default config",{multiAgent:!0}),!0}}catch(e){return t?.debug("Error reading multi-agent config, defaulting to multi-agent mode",{error:(0,u.getErrorMessage)(e)}),!0}},exports.getLockTimeoutFromEnv=function(){const e=process.env.ALCHEMY_LOCK_TIMEOUT
2983
- return e&&!isNaN(parseInt(e))?1e3*parseInt(e):36e5}
2984
- const i=s(t(1943)),a=s(t(9896)),c=s(t(6928)),l=t(4139),u=t(8824)
2985
- exports.MultiAgentConfigManager=class{constructor(e,t){this.baseDir=e,this.logger=t.child({component:"multi-agent-config"}),this.config=this.getDefaultConfig()}async initialize(){try{const e=this.loadEnvironmentConfig(),t=await this.loadConfigFile()
2986
- return this.config=this.mergeConfigs(this.getDefaultConfig(),t,e),this.logger.info("Multi-agent configuration loaded",{enabled:this.config.enabled,source:this.getConfigSource(),lockTimeout:this.config.lockTimeout,worktreeCleanupDelay:this.config.worktreeCleanupDelay}),this.config}catch(e){return this.logger.error("Failed to load multi-agent configuration",{error:(0,u.getErrorMessage)(e)}),this.config=this.getDefaultConfig(),this.config}}getConfig(){return{...this.config}}isMultiAgentEnabled(){return this.config.enabled}getDefaultConfig(){return{enabled:!1,lockTimeout:36e5,worktreeCleanupDelay:9e5,maxWorktreeAge:864e5,cleanupInterval:9e5,preserveBranchesOnCleanup:!0,maxConcurrentSessions:10,sessionTimeoutWarning:27e5}}loadEnvironmentConfig(){const e={},t=process.env.ALCHEMY_MULTI_AGENT
2987
- void 0!==t&&(e.enabled="true"===t.toLowerCase())
2988
- const r=process.env.ALCHEMY_LOCK_TIMEOUT
2989
- r&&!isNaN(parseInt(r))&&(e.lockTimeout=1e3*parseInt(r))
2990
- const n=process.env.ALCHEMY_WORKTREE_CLEANUP_DELAY
2991
- n&&!isNaN(parseInt(n))&&(e.worktreeCleanupDelay=1e3*parseInt(n))
2992
- const o=process.env.ALCHEMY_MAX_WORKTREE_AGE
2993
- o&&!isNaN(parseInt(o))&&(e.maxWorktreeAge=36e5*parseInt(o))
2994
- const s=process.env.ALCHEMY_PRESERVE_BRANCHES
2995
- void 0!==s&&(e.preserveBranchesOnCleanup="true"===s.toLowerCase())
2996
- const i=process.env.ALCHEMY_MAX_CONCURRENT_SESSIONS
2997
- return i&&!isNaN(parseInt(i))&&(e.maxConcurrentSessions=parseInt(i)),e}async loadConfigFile(){const e=[c.join(this.baseDir,"alchemy.config.json"),c.join(this.baseDir,".alchemyrc.json"),c.join(this.baseDir,l.ALCHEMY_DIR_NAME,"config.json")]
2998
- for(const t of e)try{const e=await i.readFile(t,"utf-8"),r=JSON.parse(e)
2999
- return this.logger.debug("Loaded configuration from file",{configPath:t,config:r}),this.convertFileConfigToRuntime(r)}catch(e){this.logger.debug("Config file not found or invalid",{configPath:t,error:(0,u.getErrorMessage)(e)})}return this.logger.debug("No configuration file found",{searchPaths:e}),{}}convertFileConfigToRuntime(e){const t={}
3000
- return void 0!==e.multiAgent&&(t.enabled=e.multiAgent),void 0!==e.lockTimeout&&(t.lockTimeout=1e3*e.lockTimeout),void 0!==e.worktreeCleanupDelay&&(t.worktreeCleanupDelay=1e3*e.worktreeCleanupDelay),void 0!==e.maxWorktreeAge&&(t.maxWorktreeAge=36e5*e.maxWorktreeAge),void 0!==e.cleanupInterval&&(t.cleanupInterval=6e4*e.cleanupInterval),void 0!==e.preserveBranchesOnCleanup&&(t.preserveBranchesOnCleanup=e.preserveBranchesOnCleanup),void 0!==e.maxConcurrentSessions&&(t.maxConcurrentSessions=e.maxConcurrentSessions),void 0!==e.sessionTimeoutWarning&&(t.sessionTimeoutWarning=6e4*e.sessionTimeoutWarning),t}mergeConfigs(e,t,r){return{...e,...t,...r}}getConfigSource(){const e=[]
3001
- return void 0!==process.env.ALCHEMY_MULTI_AGENT&&e.push("environment"),e.push("defaults"),e.join(", ")}async createSampleConfig(e){const t=e||c.join(this.baseDir,"alchemy.config.json.sample"),r=JSON.stringify({multiAgent:!1,lockTimeout:3600,worktreeCleanupDelay:900,maxWorktreeAge:24,cleanupInterval:15,preserveBranchesOnCleanup:!0,maxConcurrentSessions:10,sessionTimeoutWarning:45},null,2)
3002
- return await i.writeFile(t,r),this.logger.info("Created sample configuration file",{configPath:t}),t}validateConfig(e){6e4>e.lockTimeout&&this.logger.warn("Lock timeout is very short",{lockTimeout:e.lockTimeout,recommended:">=60000 (1 minute)"}),3e4>e.worktreeCleanupDelay&&this.logger.warn("Worktree cleanup delay is very short",{cleanupDelay:e.worktreeCleanupDelay,recommended:">=300000 (5 minutes)"}),e.maxConcurrentSessions>50&&this.logger.warn("Max concurrent sessions is very high",{maxSessions:e.maxConcurrentSessions,recommended:"<=20"})}}},5247(e,exports,t){"use strict"
2901
+ exports.def={name:"switch_to_branch",description:'Switch between main branch and request feature branches.\n\nUSAGE:\n- Main branch: {} or {"branch": "main"}\n- Request branch: {"branch": "req123"}\n\nAll file operations use the active branch context. Usually only needed if we want to read files or do a search on a branch we are currently not working on.',schema:r.SwitchToBranchSchema,annotations:{title:"Switch to Branch",readOnlyHint:!1,destructiveHint:!1},handler(e,t){return(0,n.handleSwitchToBranch)(e,t.context,t.apiClient.getRequestClient(),t.logger,t.metrics)}}},5247(e,exports,t){"use strict"
3003
2902
  var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
3004
2903
  var o=Object.getOwnPropertyDescriptor(t,r)
3005
2904
  o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
@@ -3149,35 +3048,7 @@ const e=u.annotationId,t=u.body,n=r.getDocumentClient(),s=await n.replyToAnnotat
3149
3048
  return o.incrementCounter("document_operations_total",1,{operation:"reply-to-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Reply Added**\n\n**Reply ID:** ${s.id}\n**Annotation:** ${e}\n**Body:** `+t}]}}case"resolve-annotation":{h.info("Resolving annotation")
3150
3049
  const e=u.annotationId,t=r.getDocumentClient()
3151
3050
  return await t.resolveAnnotation(p,e,d?"agent":void 0),o.incrementCounter("document_operations_total",1,{operation:"resolve-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Annotation Resolved**\n\n**Annotation:** ${e}\n**Status:** resolved`}]}}default:throw Error("Unknown operation type: "+g)}}catch(e){return h.error("document_operations failed",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("document_operations_errors",1),{content:[{type:"text",text:"\u274c **Document Operations Failed:** "+(0,u.getErrorMessage)(e)}],isError:!0}}}
3152
- const i=t(6183),a=s(t(5967)),c=t(1572),l=t(1483),u=t(8824)},5671(e,exports,t){"use strict"
3153
- function r(e){const[t,...r]=e.split("/")
3154
- return{provider:t||"anthropic",modelId:r.join("/")||e}}function n(e){const t={anthropic:!1,openai:!1}
3155
- try{const n=(0,a.join)(e,"opencode.json")
3156
- if((0,i.existsSync)(n)){const e=JSON.parse((0,i.readFileSync)(n,"utf8"))
3157
- if(e.provider&&((e.provider.anthropic?.options?.apiKey||process.env.ANTHROPIC_API_KEY)&&(t.anthropic=!0),(e.provider.openai?.options?.apiKey||process.env.OPENAI_API_KEY)&&(t.openai=!0)),e.model){const{provider:n}=r(e.model)
3158
- t[n]=!0}}process.env.ANTHROPIC_API_KEY&&(t.anthropic=!0),process.env.OPENAI_API_KEY&&(t.openai=!0)}catch(e){t.anthropic=!0}return t}function o(e){try{const t=(0,a.join)(e,"opencode.json")
3159
- if((0,i.existsSync)(t))return JSON.parse((0,i.readFileSync)(t,"utf8")).model||null}catch(e){}return null}function s(e,t,n,o){const s=r(e)
3160
- let i=s.provider
3161
- if("inherit"!==t){if(!o[t])return{provider:s.provider,modelId:s.modelId,fullModel:e,resolved:!1,reason:`Preferred provider '${t}' not available, using main session model`}
3162
- i=t}const a=function(e,t){const r=c[e]
3163
- if(!r)return null
3164
- const n=[...r].sort(((e,t)=>t.length-e.length))
3165
- for(const e of n)if(t.includes(e))return e
3166
- return null}(s.provider,s.modelId),l=c[s.provider],u=c[i]
3167
- if(!a||!l||!u)return{provider:s.provider,modelId:s.modelId,fullModel:e,resolved:!1,reason:`Could not determine model family for '${s.modelId}', using main session model`}
3168
- const d=l.indexOf(a)
3169
- let h,g=0
3170
- if("one_down"===n&&(g=1),"two_down"===n&&(g=2),i===s.provider)h=d+g
3171
- else{const e=l.length>1?d/(l.length-1):0
3172
- h=Math.round(e*(u.length-1))+g}h=Math.min(h,u.length-1),h=Math.max(h,0)
3173
- const p=u[h]
3174
- let f
3175
- var m,y
3176
- return i===s.provider?(m=a,y=p,f=s.modelId.replace(m,y)):f=p,{provider:i,modelId:f,fullModel:`${i}/${f}`,resolved:!0}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseModelString=r,exports.getAvailableProviders=n,exports.getMainSessionModel=o,exports.resolveModelTier=s,exports.resolveAgentModel=function(e,t="inherit",i="same"){const a=o(e)
3177
- if(!a)return{provider:"anthropic",modelId:"claude-sonnet-4-5",fullModel:"anthropic/claude-sonnet-4-5",resolved:!1,reason:"Could not determine main session model, using default"}
3178
- if("inherit"===t&&"same"===i){const e=r(a)
3179
- return{provider:e.provider,modelId:e.modelId,fullModel:a,resolved:!0}}return s(a,t,i,n(e))}
3180
- const i=t(9896),a=t(6928),c={anthropic:["opus","sonnet","haiku"]}},5674(e,exports,t){"use strict"
3051
+ const i=t(6183),a=s(t(5967)),c=t(1572),l=t(1483),u=t(8824)},5674(e,exports,t){"use strict"
3181
3052
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionError=void 0
3182
3053
  const r=t(441)
3183
3054
  class n extends Error{constructor(e,t,o,s={}){super(e),this.statusCode=503,this.retryable=!0,this.metadata={},this.name="ConnectionError",this.code=r.CONNECTION_ERROR,this.operation=t,this.lastConnectionAttempt=o,this.details={...s,operation:t,lastConnectionAttempt:o},Object.setPrototypeOf(this,n.prototype)}static operationRequiresConnectivity(e,t="",r){const o=`Cannot perform ${e}${t?` (${t})`:""} - not connected to remote server. Please check your network connection and try again. If the problem persists, verify that the remote server is running and accessible.`,s={operationType:e,operationDetails:t,timestamp:(new Date).toISOString(),suggestions:["Check your internet connection","Verify the remote server URL is correct","Ensure the remote server is running","Check for any firewall or proxy settings that might be blocking the connection"]}
@@ -3251,50 +3122,50 @@ else{if(!E)throw Error("Either paths or operations must be specified")
3251
3122
  S=E.map((e=>{if(e.path)return{type:"file",target:e.path}
3252
3123
  if(e.documentId)return{type:"document",target:e.documentId}
3253
3124
  throw Error("Invalid operation: neither path nor documentId specified")}))}if(0===S.length)throw Error("At least one file or document must be specified for deletion")
3254
- const T=S.filter((e=>"file"===e.type)),M=S.filter((e=>"document"===e.type)),R=S.length
3255
- i.info("Starting mixed file and document deletion operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:M.length,comment:q}),l.validateTaskIdFormat(C,i,o,b.metricsPrefix)
3256
- const P=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3257
- i.info("Initial branch context",{initialBranch:P.branch,initialRequestId:P.requestId,isMain:P.isMain})
3125
+ const T=S.filter((e=>"file"===e.type)),R=S.filter((e=>"document"===e.type)),P=S.length
3126
+ i.info("Starting mixed file and document deletion operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:R.length,comment:q}),l.validateTaskIdFormat(C,i,o,b.metricsPrefix)
3127
+ const M=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3128
+ i.info("Initial branch context",{initialBranch:M.branch,initialRequestId:M.requestId,isMain:M.isMain})
3258
3129
  const x=[]
3259
3130
  for(const e of T){const{normalizedPath:r,fullPath:n}=l.validateAndNormalizePath(e.target,t)
3260
3131
  x.push({normalized:r,full:n})}k=l.FileOperationPhase.TASK_VALIDATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3261
- const O=x.length>0?x[0].normalized:"document_operations",j=await l.validateTaskId(C,O,n,i,o,b.metricsPrefix),$=j?.requestId,D=await l.validateWorkItemStates(C,O,n,I,t,i,o,b.metricsPrefix),A=await l.autoPromoteTaskStatus(C,j.status,$,D.request?.status,O,n,I,i,o,b.metricsPrefix)
3262
- A.taskPromoted&&i.info(`Auto-promoted task ${C} (${j.title||"Untitled"}) to in_progress for mixed operations`,{taskId:C,taskTitle:j.title,previousStatus:j.status,newStatus:A.newTaskStatus,totalOperations:S.length,fileOperations:T.length,documentOperations:M.length}),A.requestPromoted&&i.info(`Auto-promoted request ${$} to in_progress for file operations`,{requestId:$,previousStatus:D.request?.status,newStatus:A.newRequestStatus,triggeringTaskId:C})
3132
+ const j=x.length>0?x[0].normalized:"document_operations",O=await l.validateTaskId(C,j,n,i,o,b.metricsPrefix),$=O?.requestId,D=await l.validateWorkItemStates(C,j,n,I,t,i,o,b.metricsPrefix),A=await l.autoPromoteTaskStatus(C,O.status,$,D.request?.status,j,n,I,i,o,b.metricsPrefix)
3133
+ A.taskPromoted&&i.info(`Auto-promoted task ${C} (${O.title||"Untitled"}) to in_progress for mixed operations`,{taskId:C,taskTitle:O.title,previousStatus:O.status,newStatus:A.newTaskStatus,totalOperations:S.length,fileOperations:T.length,documentOperations:R.length}),A.requestPromoted&&i.info(`Auto-promoted request ${$} to in_progress for file operations`,{requestId:$,previousStatus:D.request?.status,newStatus:A.newRequestStatus,triggeringTaskId:C})
3263
3134
  const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:$,context:t,operation:"delete-files",logger:i,metrics:o,metricsPrefix:b.metricsPrefix})
3264
3135
  if(!F.success){if(F.isLockConflict)return{content:[{type:"text",text:"\u274c "+F.error}],isError:!0}
3265
3136
  throw Error(F.error)}let N={hadUserMods:!1,userModsCommitHash:void 0}
3266
3137
  if(t.git)try{i.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
3267
3138
  const e=await(0,h.commitUserChangesBeforeToolOperation)(t.git,"delete-files",{requestId:$,taskId:C,workspaceManager:t.workspaceManager},i,o)
3268
- e.userChangesCommitted&&(i.debug("[DELETE-FILES] User changes committed before mixed delete operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),i.info("User changes committed before mixed delete-files operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:M.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),N={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){i.debug("[DELETE-FILES] Pre-tool commit failed, continuing with mixed delete operations",{error:e instanceof Error?e.message:e+""}),i.warn("Pre-tool user changes commit failed, continuing with mixed delete operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:M.length,error:e instanceof Error?e.message:e+""})}i.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:S.length,fileDeletes:T.length,documentDeletes:M.length}),k=l.FileOperationPhase.RECORD_CREATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3269
- const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,$,t.projectId,b.recordType,O,{totalOperations:S.length,fileOperations:T.length,documentOperations:M.length,filePaths:x.map((e=>e.normalized)),documentIds:M.map((e=>e.target)),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},n,d,i,o,b.metricsPrefix,s)
3139
+ e.userChangesCommitted&&(i.debug("[DELETE-FILES] User changes committed before mixed delete operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),i.info("User changes committed before mixed delete-files operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:R.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),N={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){i.debug("[DELETE-FILES] Pre-tool commit failed, continuing with mixed delete operations",{error:e instanceof Error?e.message:e+""}),i.warn("Pre-tool user changes commit failed, continuing with mixed delete operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:R.length,error:e instanceof Error?e.message:e+""})}i.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:S.length,fileDeletes:T.length,documentDeletes:R.length}),k=l.FileOperationPhase.RECORD_CREATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3140
+ const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,$,t.projectId,b.recordType,j,{totalOperations:S.length,fileOperations:T.length,documentOperations:R.length,filePaths:x.map((e=>e.normalized)),documentIds:R.map((e=>e.target)),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},n,d,i,o,b.metricsPrefix,s)
3270
3141
  y=L,w=L,k=b.fileOperationPhase,o.incrementCounter("delete_files_phase",1,{phase:k})
3271
- const B=[]
3272
- let H=0
3273
- M.length>0&&r.setProjectId(t.projectId)
3142
+ const H=[]
3143
+ let B=0
3144
+ R.length>0&&r.setProjectId(t.projectId)
3274
3145
  for(let e=0;e<x.length;e++){const t=x[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3275
3146
  try{try{await a.default.access(t.full)}catch(e){throw Error("File not found: "+t.normalized)}if((await a.default.stat(t.full)).isDirectory())throw Error("Cannot 'delete' a directory: "+t.normalized)
3276
- await a.default.unlink(t.full),r.success=!0,H++,i.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete file "+t.normalized,{error:r.error})}B.push(r)}const U=M.length>0?r.getDocumentClient():null
3277
- for(const e of M){const t=e.target,n={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3147
+ await a.default.unlink(t.full),r.success=!0,B++,i.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete file "+t.normalized,{error:r.error})}H.push(r)}const U=R.length>0?r.getDocumentClient():null
3148
+ for(const e of R){const t=e.target,n={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3278
3149
  try{let e
3279
3150
  try{if(e=await U.getDocument(t),n.filename=e.filename,i.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,g.validateRequestStatusForDocumentOperation)(e.requestId,I,i,o,"delete-document")}catch(e){if(e instanceof u.ValidationError)throw Error(e.message)
3280
3151
  throw e}try{await(0,p.ensureDocumentNotLocked)(t,r,i,o,"delete-document-archive")}catch(e){if(e instanceof u.ValidationError)throw Error(e.message)
3281
3152
  throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,f.getErrorMessage)(e)}`)}const s=await U.archiveDocument(t)
3282
- n.success=!0,n.filename=s.filename,H++,i.info("Document archived successfully",{documentId:s.id,filename:s.filename,archivedAt:s.archived_at})}catch(e){n.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete document "+t,{error:n.error})}B.push(n)}const W=Date.now()-m
3283
- o.recordValue("delete_files_time",W),o.incrementCounter("delete_files_operations_total",R),o.incrementCounter("delete_files_operations_success",H),o.incrementCounter("delete_files_operations_failed",R-H),o.incrementCounter("delete_files_file_operations",T.length),o.incrementCounter("delete_files_document_operations",M.length),H===R?o.incrementCounter("delete_files_success",1):H>0?o.incrementCounter("delete_files_partial_success",1):o.incrementCounter("delete_files_total_failure",1)
3284
- let G=null
3285
- if(H>0){k=l.FileOperationPhase.GIT_COMMIT,o.incrementCounter("delete_files_phase",1,{phase:k})
3286
- const e=B.filter((e=>e.success)),r=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
3153
+ n.success=!0,n.filename=s.filename,B++,i.info("Document archived successfully",{documentId:s.id,filename:s.filename,archivedAt:s.archived_at})}catch(e){n.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete document "+t,{error:n.error})}H.push(n)}const G=Date.now()-m
3154
+ o.recordValue("delete_files_time",G),o.incrementCounter("delete_files_operations_total",P),o.incrementCounter("delete_files_operations_success",B),o.incrementCounter("delete_files_operations_failed",P-B),o.incrementCounter("delete_files_file_operations",T.length),o.incrementCounter("delete_files_document_operations",R.length),B===P?o.incrementCounter("delete_files_success",1):B>0?o.incrementCounter("delete_files_partial_success",1):o.incrementCounter("delete_files_total_failure",1)
3155
+ let W=null
3156
+ if(B>0){k=l.FileOperationPhase.GIT_COMMIT,o.incrementCounter("delete_files_phase",1,{phase:k})
3157
+ const e=H.filter((e=>e.success)),r=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
3287
3158
  let s
3288
- s=r>0&&n>0?`Delete ${r} files and ${n} documents - ${q}`:r>0?1===r?"Delete file - "+q:`Delete ${r} files - ${q}`:1===n?"Delete document - "+q:`Delete ${n} documents - ${q}`,G=await l.commitToGit(C,O,L,z,s,t,i,o,b.metricsPrefix)}k=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:k})
3289
- const V=B.filter((e=>e.success)),J=B.filter((e=>!e.success))
3290
- await l.updateFileOperationRecords(C,y,w,O,b.recordType,H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,{status:H===R?"completed":"partial_success",commitHash:G?.commitHash,previousCommitHash:G?.previousCommitHash,totalOperations:R,fileOperations:T.length,documentOperations:M.length,successCount:H,failureCount:R-H,successfulOperations:V.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:J.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,n,d,i,o,b.metricsPrefix)
3159
+ s=r>0&&n>0?`Delete ${r} files and ${n} documents - ${q}`:r>0?1===r?"Delete file - "+q:`Delete ${r} files - ${q}`:1===n?"Delete document - "+q:`Delete ${n} documents - ${q}`,W=await l.commitToGit(C,j,L,z,s,t,i,o,b.metricsPrefix)}k=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:k})
3160
+ const V=H.filter((e=>e.success)),J=H.filter((e=>!e.success))
3161
+ await l.updateFileOperationRecords(C,y,w,j,b.recordType,B===P?`Successfully deleted all ${P} operations`:`Deleted ${B}/${P} operations successfully`,{status:B===P?"completed":"partial_success",commitHash:W?.commitHash,previousCommitHash:W?.previousCommitHash,totalOperations:P,fileOperations:T.length,documentOperations:R.length,successCount:B,failureCount:P-B,successfulOperations:V.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:J.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},B===P?`Successfully deleted all ${P} operations`:`Deleted ${B}/${P} operations successfully`,n,d,i,o,b.metricsPrefix)
3291
3162
  const K=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3292
3163
  let Y=""
3293
- if(H===R){const e=V.filter((e=>"file"===e.type)).length,t=V.filter((e=>"document"===e.type)).length
3294
- Y=e>0&&t>0?`Successfully deleted ${e} files and ${t} documents`:e>0?`Successfully deleted all ${e} ${1===e?"file":"files"}`:`Successfully archived all ${t} ${1===t?"document":"documents"}`}else Y=H>0?`Successfully deleted ${H}/${R} operations.\n\nFailed operations:\n`+B.filter((e=>!e.success)).map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
3295
- return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n"):"All delete operations failed:\n"+B.map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
3164
+ if(B===P){const e=V.filter((e=>"file"===e.type)).length,t=V.filter((e=>"document"===e.type)).length
3165
+ Y=e>0&&t>0?`Successfully deleted ${e} files and ${t} documents`:e>0?`Successfully deleted all ${e} ${1===e?"file":"files"}`:`Successfully archived all ${t} ${1===t?"document":"documents"}`}else Y=B>0?`Successfully deleted ${B}/${P} operations.\n\nFailed operations:\n`+H.filter((e=>!e.success)).map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
3166
+ return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n"):"All delete operations failed:\n"+H.map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
3296
3167
  return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
3297
- return G?.commitHash&&(Y+="\nCommit: "+G.commitHash.substring(0,8)),K.requestId&&(Y+="\nBranch: "+K.requestId),F.lockAcquired&&F.lockedRequestId&&(Y+="\n\u{1f512} **Locked request:** "+F.lockedRequestId),{content:[{type:"text",text:Y}],isError:0===H}}catch(n){if(e.taskId&&r)try{const o=r.getToolRecordClient(),s=n instanceof u.NotFoundError||n instanceof u.ValidationError||n instanceof d.ZodError
3168
+ return W?.commitHash&&(Y+="\nCommit: "+W.commitHash.substring(0,8)),K.requestId&&(Y+="\nBranch: "+K.requestId),F.lockAcquired&&F.lockedRequestId&&(Y+="\n\u{1f512} **Locked request:** "+F.lockedRequestId),{content:[{type:"text",text:Y}],isError:0===B}}catch(n){if(e.taskId&&r)try{const o=r.getToolRecordClient(),s=n instanceof u.NotFoundError||n instanceof u.ValidationError||n instanceof d.ZodError
3298
3169
  await o.createToolRecord({...s?{}:{taskId:e.taskId},projectId:t.projectId,type:"delete-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment,error:(0,f.getErrorMessage)(n),errorDetails:n instanceof Error?n.stack:n+"",phase:k,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,f.getErrorMessage)(n)})}catch(t){i.error("Failed to create failure record for delete-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0})}const s=Date.now()-m
3299
3170
  if(o.recordValue("delete_files_time",s),o.incrementCounter("delete_files_errors",1),i.error("Error in delete-files operation:",{error:(0,f.getErrorMessage)(n),time:s}),(y||w)&&e.taskId){k=l.FileOperationPhase.RECORD_UPDATE_FAILURE
3300
3171
  try{const t=r.getTaskClient(),s=r.getToolRecordClient()
@@ -3308,7 +3179,7 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
3308
3179
  var t={}
3309
3180
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
3310
3181
  return o(t,e),t})
3311
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.DebugMultiAgentTool=void 0,exports.handleDebugMultiAgentStatus=async function(e,r,n){try{const e={environmentVariables:{ALCHEMY_MULTI_AGENT:process.env.ALCHEMY_MULTI_AGENT,ALCHEMY_LOCK_TIMEOUT:process.env.ALCHEMY_LOCK_TIMEOUT},workspaceManager:{available:!!r.workspaceManager,currentContext:r.workspaceManager?.getCurrentContext()||null,activeWorkspaces:r.workspaceManager?.listActiveWorkspaces()||[]},basePath:r.basePath,alchemyPath:a.join(r.basePath,c.ALCHEMY_DIR_NAME),multiAgentMode:"multi-agent"===r.workspaceManager?.getCurrentContext().mode||!1,fileSystemChecks:{}},n=a.join(r.basePath,c.ALCHEMY_DIR_NAME),o=a.join(n,"worktrees")
3182
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.DebugMultiAgentTool=void 0,exports.handleDebugMultiAgentStatus=async function(e,r,n){try{const e={environmentVariables:{MULTI_AGENT_MODE:"always enabled",ALCHEMY_LOCK_TIMEOUT:process.env.ALCHEMY_LOCK_TIMEOUT},workspaceManager:{available:!!r.workspaceManager,currentContext:r.workspaceManager?.getCurrentContext()||null,activeWorkspaces:r.workspaceManager?.listActiveWorkspaces()||[]},basePath:r.basePath,alchemyPath:a.join(r.basePath,c.ALCHEMY_DIR_NAME),multiAgentMode:!0,fileSystemChecks:{}},n=a.join(r.basePath,c.ALCHEMY_DIR_NAME),o=a.join(n,"worktrees")
3312
3183
  if(e.fileSystemChecks={alchemyLabExists:i.existsSync(n),worktreeBaseExists:i.existsSync(o),worktreeContents:[]},e.fileSystemChecks.worktreeBaseExists)try{const t=i.readdirSync(o)
3313
3184
  e.fileSystemChecks.worktreeContents=t}catch(t){e.fileSystemChecks.worktreeReadError=(0,l.getErrorMessage)(t)}try{const t=r.workspaceManager.listActiveWorkspaces()
3314
3185
  e.activeWorkspaces=t}catch(t){e.workspaceManagerError=(0,l.getErrorMessage)(t)}try{const n=t(3807)(r.basePath),o=await n.status()
@@ -3361,12 +3232,12 @@ const n=await this.requestWithRetry("POST","/api/files/recover",t)
3361
3232
  if(!(0,i.safeGetResponseData)(n,null))throw new r.ServiceError("Empty response when recovering file")
3362
3233
  const o=(0,i.safeGetResponseData)(n,{success:!0,path:e.path,commitHash:e.commitHash,backupPath:void 0})
3363
3234
  return this.logger.info("Successfully recovered file "+e.path,{path:o.path,commitHash:o.commitHash,backupPath:o.backupPath}),o}catch(t){throw this.logger.error("Failed to recover file "+e.path,{path:e.path,commitHash:e.commitHash,error:t instanceof Error?t.stack:t+""}),t}}}exports.FileOperationsClient=a},6183(e,exports,t){"use strict"
3364
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.PlanWriteSchema=exports.PlanReadSchema=exports.DocumentOperationsSchema=exports.SearchDocumentsSchema=exports.CreateDocumentSchema=exports.ReplaceLinesSchema=exports.InsertLinesSchema=exports.SwitchToRequestBranchSchema=exports.PlannerOpsSchema=exports.SpecialistOpsSchema=exports.SubagentOperationsSchema=exports.TaskOperationsSchema=exports.CompleteTaskSchema=exports.GetTaskInformationSchema=exports.GetRequestInformationSchema=exports.ListRequestsSchema=exports.ListTasksSchema=exports.SearchSchema=exports.QueryHistorySchema=exports.FileRecoverSchema=exports.FileHistorySchema=exports.DeleteFilesSchema=exports.DeleteFileSchema=exports.ReplaceInFileSchema=exports.ReplaceInFilesSchema=exports.ReplaceStringsSchema=exports.ReplaceStringSchema=exports.MoveFilesSchema=exports.CreateDirectorySchema=exports.GetFileInfoSchema=exports.ListDirectorySchema=exports.ReadFilesSchema=exports.ViewAssetSchema=exports.WriteFileSchema=exports.UpdateTaskStatusSchema=exports.CreateTaskSchema=exports.CreateRequestSchema=exports.CompleteRequestSchema=exports.ExecutedTestSchema=exports.TestVerificationSchema=exports.TestDefinitionSchema=exports.AcceptanceCriterionSchema=exports.RecordTypeEnum=exports.EvidenceTypeEnum=exports.CriterionStatusEnum=exports.RequestStatusEnum=exports.TaskStatusEnum=exports.RequestTypeEnum=exports.TestCoverageTypeEnum=exports.CompletionStatusEnum=void 0,exports.SessionMessageOperationsSchema=exports.ReportTestResultsSchema=exports.ExecuteTestCommandSchema=exports.TestingReferenceSchema=exports.TestingProcessUpdateSchema=exports.TestingProcessCreateSchema=exports.TestingProcessGetSchema=exports.TestingProcessListSchema=exports.MetaReferenceSchema=exports.MetaAgentListSchema=exports.MetaWorkflowRemoveRecipeSchema=exports.MetaWorkflowAddRecipeSchema=exports.MetaHookCreateSchema=exports.MetaHookListSchema=exports.MetaRecipeRemoveHookSchema=exports.MetaRecipeAddHookSchema=exports.MetaRecipeCreateSchema=exports.MetaRecipeGetSchema=exports.MetaRecipeListSchema=exports.MetaWorkflowUpdateSchema=exports.MetaWorkflowCreateSchema=exports.MetaWorkflowGetSchema=exports.MetaWorkflowListSchema=exports.GenerateRequestJournalSchema=exports.QuickManageSchema=exports.QuickReplaceSchema=exports.QuickWriteSchema=exports.RequestOperationsSchema=exports.ManageFilesSchema=exports.ModifyFileSchema=exports.RevertRequestSchema=exports.SwitchToBranchSchema=exports.SwitchToMainBranchSchema=void 0
3235
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.SwitchToMainBranchSchema=exports.PlanWriteSchema=exports.PlanReadSchema=exports.DocumentOperationsSchema=exports.SearchDocumentsSchema=exports.CreateDocumentSchema=exports.ReplaceLinesSchema=exports.InsertLinesSchema=exports.SwitchToRequestBranchSchema=exports.PlannerOpsSchema=exports.SpecialistOpsSchema=exports.SubagentOperationsSchema=exports.TaskOperationsSchema=exports.CompleteTaskSchema=exports.GetTaskInformationSchema=exports.GetRequestInformationSchema=exports.ListRequestsSchema=exports.ListTasksSchema=exports.SearchSchema=exports.QueryHistorySchema=exports.FileRecoverSchema=exports.FileHistorySchema=exports.DeleteFilesSchema=exports.DeleteFileSchema=exports.ReplaceInFilesSchema=exports.ReplaceStringsSchema=exports.ReplaceStringSchema=exports.MoveFilesSchema=exports.CreateDirectorySchema=exports.GetFileInfoSchema=exports.ListDirectorySchema=exports.ReadFilesSchema=exports.ViewAssetSchema=exports.WriteFileSchema=exports.UpdateTaskStatusSchema=exports.CreateTaskSchema=exports.CreateRequestSchema=exports.CompleteRequestSchema=exports.ExecutedTestSchema=exports.TestVerificationSchema=exports.TestDefinitionSchema=exports.AcceptanceCriterionSchema=exports.RecordTypeEnum=exports.EvidenceTypeEnum=exports.CriterionStatusEnum=exports.RequestStatusEnum=exports.TaskStatusEnum=exports.RequestTypeEnum=exports.TestCoverageTypeEnum=exports.CompletionStatusEnum=void 0,exports.UpdateSpecializationSchema=exports.SessionMessageOperationsSchema=exports.ReportTestResultsSchema=exports.ExecuteTestCommandSchema=exports.TestingReferenceSchema=exports.TestingProcessUpdateSchema=exports.TestingProcessCreateSchema=exports.TestingProcessGetSchema=exports.TestingProcessListSchema=exports.MetaReferenceSchema=exports.MetaAgentListSchema=exports.MetaWorkflowRemoveRecipeSchema=exports.MetaWorkflowAddRecipeSchema=exports.MetaHookCreateSchema=exports.MetaHookListSchema=exports.MetaRecipeRemoveHookSchema=exports.MetaRecipeAddHookSchema=exports.MetaRecipeCreateSchema=exports.MetaRecipeGetSchema=exports.MetaRecipeListSchema=exports.MetaWorkflowUpdateSchema=exports.MetaWorkflowCreateSchema=exports.MetaWorkflowGetSchema=exports.MetaWorkflowListSchema=exports.GenerateRequestJournalSchema=exports.QuickManageSchema=exports.QuickReplaceSchema=exports.QuickWriteSchema=exports.RequestOperationsSchema=exports.ManageFilesSchema=exports.ModifyFileSchema=exports.RevertRequestSchema=exports.SwitchToBranchSchema=void 0
3365
3236
  const r=t(1569),n=t(8955),o=r.z.string().refine((e=>!!e&&/^tas\d{6}$/.test(e)),{message:"Task ID must match format: tas###### (e.g. tas000001). If you don't have a task yet, create one first using task_operations with operation 'create'."}),s=r.z.string().refine((e=>!!e&&/^req\d{6}$/.test(e)),{message:"Request ID must match format: req###### (e.g. req000001)"}),i=r.z.string().refine((e=>!!e&&(/^doc_[0-9A-Z]{26}$/i.test(e)||/^(doc|plan|jour)\d{6}$/.test(e))),{message:"Document ID must match format: doc_[26 alphanumeric] (ULID) or doc######/plan######/jour###### (local ID)"})
3366
- exports.CompletionStatusEnum=r.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=r.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=r.z.enum(["feature","bugfix","quick-edit"]),exports.TaskStatusEnum=r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=r.z.enum(["open","in_progress","ready_for_review","ready_for_merge","completed","canceled","reverted","conflicted"]),exports.CriterionStatusEnum=r.z.enum(["unverified","verified"]),exports.EvidenceTypeEnum=r.z.enum(["test","manual","other"]),exports.RecordTypeEnum=r.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=r.z.object({description:r.z.string(),status:r.z.enum(["unverified","verified"]).default("unverified"),evidence:r.z.string().nullable().optional(),evidenceType:r.z.enum(["test","manual","other"]).nullable().optional(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.TestDefinitionSchema=r.z.object({id:r.z.string(),description:r.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:r.z.array(r.z.string())}),exports.TestVerificationSchema=r.z.object({criteria:r.z.array(r.z.string()),tests:r.z.array(r.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:r.z.number(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.ExecutedTestSchema=r.z.object({id:r.z.string(),testId:r.z.string(),status:exports.CompletionStatusEnum,results:r.z.string(),coverage:r.z.array(r.z.string()),executedAt:r.z.string()}),exports.CompleteRequestSchema=r.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:r.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:r.z.string().optional()}),exports.CreateRequestSchema=r.z.object({title:r.z.string(),type:r.z.enum(["feature","bugfix"]),description:r.z.string(),acceptanceCriteria:r.z.array(r.z.string()),planDocumentId:r.z.string().optional()}),exports.CreateTaskSchema=r.z.object({requestId:s,title:r.z.string(),description:r.z.string()}),exports.UpdateTaskStatusSchema=r.z.object({taskId:o,status:exports.TaskStatusEnum,note:r.z.string()}),exports.WriteFileSchema=r.z.object({taskId:o,path:r.z.string().optional(),documentId:i.optional(),content:r.z.union([r.z.string(),r.z.record(r.z.any()),r.z.array(r.z.unknown())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional(),comment:r.z.string()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}),exports.ViewAssetSchema=r.z.object({filename:r.z.string().describe("The asset filename (e.g., 01JMXYZ.png)")}),exports.ReadFilesSchema=r.z.object({paths:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),lines:r.z.string().optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),encoding:r.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=r.z.object({path:r.z.string(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=r.z.object({path:r.z.string()}),exports.CreateDirectorySchema=r.z.object({path:r.z.string(),taskId:o,comment:r.z.string().optional()}),exports.MoveFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()})),comment:r.z.string()}),exports.ReplaceStringSchema=r.z.object({taskId:o,path:r.z.string(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional(),comment:r.z.string()}),exports.ReplaceStringsSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceInFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1,"old string cannot be empty"),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:r.z.boolean().optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"Either path or documentId is required, but not both"})).min(1,"At least one operation required"),fuzzy_match:r.z.boolean().optional().default(!0),comment:r.z.string()}),exports.ReplaceInFileSchema=exports.ReplaceInFilesSchema,exports.DeleteFileSchema=r.z.object({taskId:o,path:r.z.string(),comment:r.z.string()}),exports.DeleteFilesSchema=r.z.object({taskId:o,paths:r.z.array(r.z.string()).optional(),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})).optional(),comment:r.z.string()}).refine((e=>e.paths&&!e.operations||!e.paths&&e.operations),{message:"paths or operations required"}).refine((e=>e.paths?.length||e.operations?.length),{message:"path/operation required"}),exports.FileHistorySchema=r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}),exports.FileRecoverSchema=r.z.object({taskId:o,path:r.z.string(),commitHash:r.z.string(),createBackup:r.z.boolean().default(!0)}),exports.QueryHistorySchema=r.z.object({queryType:r.z.enum(["file-history","request-file-history","recover","blame"],{errorMap(){return{message:"Invalid queryType. Valid options: file-history, request-file-history, recover, blame"}}}),fileHistory:r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}).optional(),requestHistory:r.z.object({requestId:s,detailLevel:r.z.enum(["summary","detailed"]).default("summary"),taskId:o.optional(),showDiff:r.z.boolean().optional(),fileFilter:r.z.string().optional()}).optional(),recover:r.z.object({taskId:o,path:r.z.string(),commitHash:r.z.string().optional(),createBackup:r.z.boolean().default(!0)}).optional(),blame:r.z.object({path:r.z.string(),lines:r.z.string().optional(),branch:r.z.string().optional()}).optional()}).refine((e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"request-file-history"===e.queryType?e.requestHistory&&!e.fileHistory&&!e.recover:"recover"===e.queryType?e.recover&&!e.fileHistory&&!e.requestHistory&&!e.blame:"blame"===e.queryType&&e.blame&&!e.fileHistory&&!e.requestHistory&&!e.recover),{message:"Invalid query data"}),exports.SearchSchema=r.z.object({needle:r.z.string().optional(),directory:r.z.string().optional(),options:r.z.object({caseSensitive:r.z.boolean().optional(),fileExtension:r.z.string().optional(),maxResults:r.z.number().optional(),useRegex:r.z.boolean().optional(),searchIn:r.z.enum(["content","filename","both"]).default("content").optional(),contextLines:r.z.number().min(0).max(10).optional(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=r.z.object({requestId:s,filters:r.z.object({status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.ListRequestsSchema=r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["open","in_progress","ready_for_review","completed","canceled"]).optional(),planDocumentId:r.z.string().optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.GetRequestInformationSchema=r.z.object({requestId:s}),exports.GetTaskInformationSchema=r.z.object({taskId:o}),exports.CompleteTaskSchema=r.z.object({taskId:o,summary:r.z.string()}),exports.TaskOperationsSchema=r.z.object({operation:r.z.enum(["get-info","list"]),taskId:o.optional(),requestId:s.optional(),status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).superRefine(((e,t)=>{"get-info"!==e.operation||e.taskId||t.addIssue({code:"custom",message:'taskId is required for get-info. Example: { "operation": "get-info", "taskId": "tas000001" }'}),"list"!==e.operation||e.requestId||t.addIssue({code:"custom",message:'requestId is required for list. Example: { "operation": "list", "requestId": "req000001" }'})}))
3237
+ exports.CompletionStatusEnum=r.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=r.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=r.z.enum(["feature","bugfix","quick-edit"]),exports.TaskStatusEnum=r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=r.z.enum(["open","in_progress","ready_for_review","ready_for_merge","completed","canceled","reverted","conflicted"]),exports.CriterionStatusEnum=r.z.enum(["unverified","verified"]),exports.EvidenceTypeEnum=r.z.enum(["test","manual","other"]),exports.RecordTypeEnum=r.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=r.z.object({description:r.z.string(),status:r.z.enum(["unverified","verified"]).default("unverified"),evidence:r.z.string().nullable().optional(),evidenceType:r.z.enum(["test","manual","other"]).nullable().optional(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.TestDefinitionSchema=r.z.object({id:r.z.string(),description:r.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:r.z.array(r.z.string())}),exports.TestVerificationSchema=r.z.object({criteria:r.z.array(r.z.string()),tests:r.z.array(r.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:r.z.number(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.ExecutedTestSchema=r.z.object({id:r.z.string(),testId:r.z.string(),status:exports.CompletionStatusEnum,results:r.z.string(),coverage:r.z.array(r.z.string()),executedAt:r.z.string()}),exports.CompleteRequestSchema=r.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:r.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:r.z.string().optional()}),exports.CreateRequestSchema=r.z.object({title:r.z.string(),type:r.z.enum(["feature","bugfix"]),description:r.z.string(),acceptanceCriteria:r.z.array(r.z.string()),planDocumentId:r.z.string().optional()}),exports.CreateTaskSchema=r.z.object({requestId:s,title:r.z.string(),description:r.z.string()}),exports.UpdateTaskStatusSchema=r.z.object({taskId:o,status:exports.TaskStatusEnum,note:r.z.string()}),exports.WriteFileSchema=r.z.object({taskId:o,path:r.z.string().optional(),documentId:i.optional(),content:r.z.union([r.z.string(),r.z.record(r.z.any()),r.z.array(r.z.unknown())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional(),comment:r.z.string()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}),exports.ViewAssetSchema=r.z.object({filename:r.z.string().describe("The asset filename (e.g., 01JMXYZ.png)")}),exports.ReadFilesSchema=r.z.object({paths:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),lines:r.z.string().optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),encoding:r.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=r.z.object({path:r.z.string(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=r.z.object({path:r.z.string()}),exports.CreateDirectorySchema=r.z.object({path:r.z.string(),taskId:o,comment:r.z.string().optional()}),exports.MoveFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()})),comment:r.z.string()}),exports.ReplaceStringSchema=r.z.object({taskId:o,path:r.z.string(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional(),comment:r.z.string()}),exports.ReplaceStringsSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceInFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1,"old string cannot be empty"),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:r.z.boolean().optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"Either path or documentId is required, but not both"})).min(1,"At least one operation required"),fuzzy_match:r.z.boolean().optional().default(!0),comment:r.z.string()}),exports.DeleteFileSchema=r.z.object({taskId:o,path:r.z.string(),comment:r.z.string()}),exports.DeleteFilesSchema=r.z.object({taskId:o,paths:r.z.array(r.z.string()).optional(),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})).optional(),comment:r.z.string()}).refine((e=>e.paths&&!e.operations||!e.paths&&e.operations),{message:"paths or operations required"}).refine((e=>e.paths?.length||e.operations?.length),{message:"path/operation required"}),exports.FileHistorySchema=r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}),exports.FileRecoverSchema=r.z.object({taskId:o,path:r.z.string(),commitHash:r.z.string(),createBackup:r.z.boolean().default(!0)}),exports.QueryHistorySchema=r.z.object({queryType:r.z.enum(["file-history","request-file-history","recover","blame"],{errorMap(){return{message:"Invalid queryType. Valid options: file-history, request-file-history, recover, blame"}}}),fileHistory:r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}).optional(),requestHistory:r.z.object({requestId:s,detailLevel:r.z.enum(["summary","detailed"]).default("summary"),taskId:o.optional(),showDiff:r.z.boolean().optional(),fileFilter:r.z.string().optional()}).optional(),recover:r.z.object({taskId:o,path:r.z.string(),commitHash:r.z.string().optional(),createBackup:r.z.boolean().default(!0)}).optional(),blame:r.z.object({path:r.z.string(),lines:r.z.string().optional(),branch:r.z.string().optional()}).optional()}).refine((e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"request-file-history"===e.queryType?e.requestHistory&&!e.fileHistory&&!e.recover:"recover"===e.queryType?e.recover&&!e.fileHistory&&!e.requestHistory&&!e.blame:"blame"===e.queryType&&e.blame&&!e.fileHistory&&!e.requestHistory&&!e.recover),{message:"Invalid query data"}),exports.SearchSchema=r.z.object({needle:r.z.string().optional(),directory:r.z.string().optional(),options:r.z.object({caseSensitive:r.z.boolean().optional(),fileExtension:r.z.string().optional(),maxResults:r.z.number().optional(),useRegex:r.z.boolean().optional(),searchIn:r.z.enum(["content","filename","both"]).default("content").optional(),contextLines:r.z.number().min(0).max(10).optional(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=r.z.object({requestId:s,filters:r.z.object({status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.ListRequestsSchema=r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["open","in_progress","ready_for_review","completed","canceled"]).optional(),planDocumentId:r.z.string().optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.GetRequestInformationSchema=r.z.object({requestId:s}),exports.GetTaskInformationSchema=r.z.object({taskId:o}),exports.CompleteTaskSchema=r.z.object({taskId:o,summary:r.z.string()}),exports.TaskOperationsSchema=r.z.object({operation:r.z.enum(["get-info","list"]),taskId:o.optional(),requestId:s.optional(),status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).superRefine(((e,t)=>{"get-info"!==e.operation||e.taskId||t.addIssue({code:"custom",message:'taskId is required for get-info. Example: { "operation": "get-info", "taskId": "tas000001" }'}),"list"!==e.operation||e.requestId||t.addIssue({code:"custom",message:'requestId is required for list. Example: { "operation": "list", "requestId": "req000001" }'})}))
3367
3238
  const a=r.z.string().min(1).describe("OpenCode session ID")
3368
3239
  exports.SubagentOperationsSchema=r.z.object({sessionId:a.optional(),operation:r.z.enum(["spawn","continue","check-status","abort","read-messages","list-sessions"]),spawn:r.z.object({agent:r.z.string().default("work").refine((e=>(0,n.isValidAgent)(e)),{message:"Invalid agent. Check tool description for available agents."}).describe("The subagent type to spawn (see tool description for available agents)"),prompt:r.z.string().min(1).describe("The task/prompt for the subagent to work on"),description:r.z.string().max(60).describe('Brief label for the UI, e.g. "Plan auth refactor" (max 60 chars)'),requestId:r.z.string().regex(/^req\d{6}$/).optional().describe("Optional request ID to associate with the work"),allowParallel:r.z.boolean().default(!1).optional().describe("Allow spawning even if request already has active workers (default: false, will block)"),useExistingSession:r.z.string().optional().describe("Optional existing session ID to send prompt to instead of creating new session")}).optional(),continue:r.z.object({prompt:r.z.string().min(1).describe("New instructions/feedback to send to the subagent")}).optional(),readMessages:r.z.object({limit:r.z.number().min(1).max(50).default(1).describe("Number of recent messages to fetch (default 10, max 50)")}).optional(),listSessions:r.z.object({activeOnly:r.z.boolean().default(!1).describe("Only show sessions that are currently active/busy"),requestId:r.z.string().optional().describe("Find sessions that worked on a specific request"),limit:r.z.number().min(1).max(100).optional().describe("Only show N most recent sessions"),minTokens:r.z.number().min(0).optional().describe("Only show sessions with at least this many tokens"),maxTokens:r.z.number().min(0).optional().describe("Only show sessions with at most this many tokens"),maxAgeHours:r.z.number().min(0).optional().describe("Only show sessions newer than X hours")}).optional()}).refine((e=>{const t=!!e.sessionId,r=!!e.spawn,n=!!e.continue,o=!!e.readMessages
3369
- return"spawn"===e.operation?r&&!n&&!o:"continue"===e.operation?n&&!r&&!o&&t:"check-status"===e.operation||"abort"===e.operation?!r&&!n&&!o&&t:"read-messages"===e.operation?!r&&!n&&t:"list-sessions"===e.operation&&!(r||n||o||t)}),{message:"Invalid operation data: spawn requires spawn object, continue/check-status/abort/read-messages require sessionId"}),exports.SpecialistOpsSchema=r.z.object({operation:r.z.enum(["delegate","follow-up","check-status","list","abort"]),sessionId:a.optional(),delegate:r.z.object({prompt:r.z.string().min(1).describe("Detailed instructions for the specialist"),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars)"),requestId:r.z.string().regex(/^req\d{6}$/).describe("Request ID to associate with the work").optional(),specialization:r.z.string().max(100).describe('Domain description for the specialist (e.g. "Frontend UI components", "Database migrations")')}).optional(),followUp:r.z.object({prompt:r.z.string().min(1).describe("Follow-up instructions or feedback for the specialist"),specialization:r.z.string().max(100).describe("Update the specialist's domain description if their focus has shifted").optional()}).optional(),list:r.z.object({activeOnly:r.z.boolean().default(!1).describe("Only show active/busy specialists"),requestId:r.z.string().optional().describe("Filter to specialists working on a specific request"),limit:r.z.number().min(1).max(100).optional().describe("Max sessions to return")}).optional()}).refine((e=>{const t=!!e.sessionId,r=!!e.delegate,n=!!e.followUp
3240
+ return"spawn"===e.operation?r&&!n&&!o:"continue"===e.operation?n&&!r&&!o&&t:"check-status"===e.operation||"abort"===e.operation?!r&&!n&&!o&&t:"read-messages"===e.operation?!r&&!n&&t:"list-sessions"===e.operation&&!(r||n||o||t)}),{message:"Invalid operation data: spawn requires spawn object, continue/check-status/abort/read-messages require sessionId"}),exports.SpecialistOpsSchema=r.z.object({operation:r.z.enum(["delegate","follow-up","check-status","list","abort"]),sessionId:a.optional(),delegate:r.z.object({prompt:r.z.string().min(1).describe("Detailed instructions for the specialist"),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars)"),requestId:r.z.string().regex(/^req\d{6}$/).describe("Request ID to associate with the work").optional(),specialization:r.z.string().max(500).describe('Domain description for the specialist (e.g. "Frontend UI components", "Database migrations")')}).optional(),followUp:r.z.object({prompt:r.z.string().min(1).describe("Follow-up instructions or feedback for the specialist"),specialization:r.z.string().max(500).describe("Update the specialist's domain description if their focus has shifted").optional()}).optional(),list:r.z.object({activeOnly:r.z.boolean().default(!1).describe("Only show active/busy specialists"),requestId:r.z.string().optional().describe("Filter to specialists working on a specific request"),limit:r.z.number().min(1).max(100).optional().describe("Max sessions to return")}).optional()}).refine((e=>{const t=!!e.sessionId,r=!!e.delegate,n=!!e.followUp
3370
3241
  return"delegate"===e.operation?r&&!n&&!t:"follow-up"===e.operation?n&&!r&&t:"check-status"===e.operation||"abort"===e.operation?!r&&!n&&t:"list"===e.operation&&!r&&!n&&!t}),{message:"Invalid operation data: delegate requires delegate object, follow-up/check-status/abort require sessionId"}),exports.PlannerOpsSchema=r.z.object({operation:r.z.enum(["request","check-status","list"]),request:r.z.object({prompt:r.z.string().min(1).describe("What to plan \u2014 feature description, architecture question, etc."),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars)")}).optional(),sessionId:a.optional(),list:r.z.object({activeOnly:r.z.boolean().default(!1).describe("Only show active/busy planning sessions"),limit:r.z.number().min(1).max(100).optional().describe("Max sessions to return")}).optional()}).refine((e=>{const t=!!e.request,r=!!e.sessionId
3371
3242
  return"request"===e.operation?t&&!r:"check-status"===e.operation?!t&&r:"list"===e.operation&&!t&&!r}),{message:"Invalid operation data: request requires request object, check-status requires sessionId"}),exports.SwitchToRequestBranchSchema=r.z.object({requestId:s}),exports.InsertLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.CreateDocumentSchema=r.z.object({requestId:s.optional(),filename:r.z.string().refine((e=>e.toLowerCase().endsWith(".md")),{message:"Filename must end with .md extension"}),content:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"],{errorMap(){return{message:"Document type must be one of: Report, Documentation, Plan, Other"}}}),comment:r.z.string()}),exports.SearchDocumentsSchema=r.z.object({query:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),requestId:s.optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both")}),exports.DocumentOperationsSchema=r.z.object({operation:r.z.enum(["create","search","create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"]),documentId:i.optional(),requestId:s.optional(),filename:r.z.string().optional(),content:r.z.string().optional(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),comment:r.z.string().optional(),query:r.z.string().optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both"),versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional(),versionNumber:r.z.number().int().min(1).optional(),selectedText:r.z.string().optional(),prefixContext:r.z.string().optional(),suffixContext:r.z.string().optional(),lineHint:r.z.number().int().optional(),body:r.z.string().optional(),annotationId:r.z.string().optional()}).superRefine(((e,t)=>{const r=e.operation;["create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"].includes(r)&&!e.documentId&&t.addIssue({code:"custom",message:`documentId is required for '${r}'. Example: { "operation": "${r}", "documentId": "doc000001" }`}),"create"===r&&(e.filename?e.filename.toLowerCase().endsWith(".md")||t.addIssue({code:"custom",message:"Filename must end with .md extension"}):t.addIssue({code:"custom",message:"filename is required for create (must end with .md)"}),e.content||t.addIssue({code:"custom",message:"content is required for create"}),e.type||t.addIssue({code:"custom",message:"type is required for create (Report, Documentation, Plan, or Other)"}),e.comment||t.addIssue({code:"custom",message:"comment is required for create"})),"search"!==r||e.query||t.addIssue({code:"custom",message:'query is required for search. Example: { "operation": "search", "query": "search term" }'}),"get-version"!==r&&"restore-version"!==r||e.versionNumber||t.addIssue({code:"custom",message:`versionNumber is required for '${r}'`}),"create-annotation"===r&&(e.selectedText||t.addIssue({code:"custom",message:"selectedText is required for create-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for create-annotation"})),"reply-to-annotation"===r&&(e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for reply-to-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for reply-to-annotation"})),"resolve-annotation"!==r||e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for resolve-annotation"})}))
3372
3243
  const c=r.z.string().refine((e=>!!e&&(/^doc_[0-9A-Z]{26}$/i.test(e)||/^plan\d{6}$/.test(e))),{message:"Plan ID must match format: doc_[26 alphanumeric] (ULID) or plan###### (local ID)"})
@@ -3376,7 +3247,7 @@ if(["complete","merge","approve","revert","get-info"].includes(n)&&!r)return voi
3376
3247
  const o={complete:{field:"complete",hint:'Provide: { complete: { summary: "..." } }'},merge:{field:"merge",hint:'Provide: { merge: { verifications: [{key: "1a", evidence: "..."}] } }'},revert:{field:"revert",hint:'Provide: { revert: { reason: "..." } }'},search:{field:"search",hint:'Provide: { search: { query: "..." } }'}}[n]
3377
3248
  o&&!e[o.field]&&t.addIssue({code:"custom",message:`'${n}' operation requires '${o.field}' data. ${o.hint}`})})),exports.QuickWriteSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),path:r.z.string().optional(),documentId:i.optional(),content:r.z.union([r.z.string(),r.z.record(r.z.any()),r.z.array(r.z.unknown())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}),exports.QuickReplaceSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:r.z.boolean().optional()})).min(1),fuzzy_match:r.z.boolean().optional(),comment:r.z.string().min(1,"Comment describing the change is required")}),exports.QuickManageSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}))}).optional()})).min(1)}),exports.GenerateRequestJournalSchema=r.z.object({requestId:r.z.string().regex(/^req[_\d].+$/,"Invalid request ID format. Expected format: req_[26 chars] or req######")}),exports.MetaWorkflowListSchema=r.z.object({}),exports.MetaWorkflowGetSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the workflow"),shortName:r.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:r.z.string().optional().describe("Description of what the workflow does"),documentation:r.z.string().optional().describe("Detailed documentation"),defaultAgent:r.z.string().optional().describe("Default agent template to use"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior: auto-merge (default), auto-test-then-merge, or manual-review"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaWorkflowUpdateSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to update"),name:r.z.string().min(1).optional().describe("New name"),shortName:r.z.string().max(10).optional().describe("New short name (max 10 chars)"),description:r.z.string().optional().describe("New description"),documentation:r.z.string().optional().describe("New documentation"),defaultAgent:r.z.string().optional().describe("New default agent"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaRecipeListSchema=r.z.object({}),exports.MetaRecipeGetSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to retrieve")}),exports.MetaRecipeCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the recipe"),description:r.z.string().optional().describe("Description of what the recipe does"),documentation:r.z.string().optional().describe("Detailed documentation")}),exports.MetaRecipeAddHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to add the hook to"),hookId:r.z.string().describe("Hook template ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the recipe (0-based, appended if omitted)")}),exports.MetaRecipeRemoveHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to remove the hook from"),hookId:r.z.string().describe("Hook template ID to remove")}),exports.MetaHookListSchema=r.z.object({}),exports.MetaHookCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the hook"),description:r.z.string().optional().describe("Description of what the hook does"),eventType:r.z.string().describe("Event type that triggers this hook (e.g., session_idle, request_completed, custom:plan_ready)"),category:r.z.enum(["alchemy","session","message","editing","reading","file_management","documents","history","tool"]).default("session").describe("Hook category"),agent:r.z.string().describe("Agent template to execute when hook fires"),promptTemplate:r.z.string().describe("Prompt template with {{variable}} substitution"),condition:r.z.record(r.z.any()).optional().describe("Condition object for filtering when hook fires"),executionMode:r.z.enum(["same_session","sub_agent","background","notification","direct_report"]).default("background").describe("How to execute the hook"),timing:r.z.enum(["before","after"]).default("after").describe("When to fire relative to the event"),maxIterations:r.z.number().int().min(1).optional().describe("Maximum times to fire per session"),emitEvent:r.z.string().optional().describe("Custom event to emit on completion"),emitEventOnCondition:r.z.union([r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}),r.z.array(r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}))]).optional().describe("Conditional event emission based on output")}),exports.MetaWorkflowAddRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to add the recipe to"),recipeId:r.z.string().describe("Recipe ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the workflow (0-based, appended if omitted)")}),exports.MetaWorkflowRemoveRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to remove the recipe from"),recipeId:r.z.string().describe("Recipe ID to remove")}),exports.MetaAgentListSchema=r.z.object({}),exports.MetaReferenceSchema=r.z.object({}),exports.TestingProcessListSchema=r.z.object({}),exports.TestingProcessGetSchema=r.z.object({processId:r.z.string().describe("Test process ID to retrieve")})
3378
3249
  const l=r.z.object({name:r.z.string().min(1).describe('Command name (e.g., "Build", "Unit Tests")'),command:r.z.string().min(1).describe('Shell command to run (e.g., "npm test")'),required:r.z.boolean().default(!0).describe("If true, failure blocks the request (default: true)"),timeout:r.z.number().int().min(10).max(3600).default(300).describe("Max execution time in seconds (default: 300)")})
3379
- exports.TestingProcessCreateSchema=r.z.object({name:r.z.string().min(1).describe("Name for the test process"),description:r.z.string().optional().describe("Description of what this process verifies"),scope:r.z.string().optional().describe('Path prefix for monorepo scoping (e.g., "packages/api/"). Omit for global.'),setup:r.z.array(r.z.string()).optional().describe('Commands to prepare the environment (e.g., ["ln -s ../../node_modules node_modules"])'),commands:r.z.array(l).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands")}),exports.TestingProcessUpdateSchema=r.z.object({processId:r.z.string().describe("Test process ID to update"),name:r.z.string().min(1).optional().describe("New name"),description:r.z.string().optional().describe("New description"),scope:r.z.string().nullable().optional().describe("New scope (null to remove)"),isActive:r.z.boolean().optional().describe("Enable or disable the process"),setup:r.z.array(r.z.string()).optional().describe("New setup commands (replaces existing)"),commands:r.z.array(l).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands")}),exports.TestingReferenceSchema=r.z.object({}),exports.ExecuteTestCommandSchema=r.z.object({processId:r.z.string().describe("Test process ID containing the command"),commandName:r.z.string().describe('Name of the test command to run, or "setup" to run all setup commands in sequence')}),exports.ReportTestResultsSchema=r.z.object({status:r.z.enum(["passed","failed","error"]).describe("Overall result"),results:r.z.object({commands:r.z.array(r.z.object({name:r.z.string().describe("Command name"),status:r.z.enum(["passed","failed","skipped","error"]).describe("Command result"),output:r.z.string().optional().describe("Relevant output snippet"),diagnosis:r.z.string().optional().describe("Why it failed, if applicable")})).describe("Per-command results"),summary:r.z.string().describe("Brief overall summary"),acceptanceCriteria:r.z.array(r.z.object({criterion:r.z.string().describe("The acceptance criterion text"),status:r.z.enum(["verified","unverified","unclear"]),evidence:r.z.string().describe("How verified, or why not")})).optional().describe("AC verification results, if applicable")}).describe("Structured test results")}),exports.SessionMessageOperationsSchema=r.z.object({operation:r.z.enum(["send","reply","list","get","offer-handoff"]),type:r.z.enum(["question","report"]).optional().describe("Message type to send (required for send)"),toSessionId:r.z.string().optional().describe('Target session ID, or "parent" to auto-resolve to parent session (omit for broadcast questions)'),questionType:r.z.enum(["free-form","alternatives"]).optional().describe('Type of question (required for send type="question")'),questionContent:r.z.object({question:r.z.string().min(1).describe("The question text"),context:r.z.string().optional().describe("Additional context"),options:r.z.array(r.z.object({id:r.z.string(),label:r.z.string(),description:r.z.string().optional()})).optional().describe("Options for alternatives questions"),allowMultiple:r.z.boolean().optional().describe("Allow selecting multiple options")}).optional().describe('Question content (required for send type="question")'),priority:r.z.enum(["low","normal","high"]).optional().describe("Question priority"),expiresInHours:r.z.number().optional().describe("Question expiry in hours"),status:r.z.enum(["success","partial","failure","blocked"]).optional().describe('Report status (required for send type="report")'),summary:r.z.string().optional().describe('Report summary (required for send type="report")'),details:r.z.string().optional().describe("Report details"),finish:r.z.boolean().optional().describe("Release request associations after report"),messageCode:r.z.string().optional().describe("Message code (required for reply and get operations)"),respondedBySessionId:r.z.string().optional().describe("Session ID answering the question"),text:r.z.string().optional().describe("Text answer for free-form questions"),selectedOptions:r.z.array(r.z.string()).optional().describe("Selected option IDs for alternatives"),notes:r.z.string().optional().describe("Additional notes"),list:r.z.object({sessionId:r.z.string().optional().describe("Filter by session ID (auto-discovered if omitted)"),messageType:r.z.enum(["question","report","all"]).default("all").describe("Filter by message type"),direction:r.z.enum(["incoming","outgoing","all"]).default("all"),status:r.z.enum(["pending","answered","expired","success","partial","failure","blocked","all"]).default("all").describe("Filter by status"),readStatus:r.z.enum(["unread","read","acknowledged","all"]).default("all").describe("Filter by read status (reports only)"),limit:r.z.number().min(1).max(100).default(50),offset:r.z.number().min(0).default(0)}).optional().describe('List filters (operation: "list" only)'),offerHandoff:r.z.object({summary:r.z.string().describe("Summary of what was planned/created"),requestIds:r.z.array(r.z.string()).describe("Request IDs that were created from the plan")}).optional().describe('Handoff offer details (operation: "offer-handoff" only)')}).refine((e=>"send"===e.operation?!!e.type:"reply"===e.operation?!!e.messageCode:"list"===e.operation||("get"===e.operation?!!e.messageCode:"offer-handoff"===e.operation)),{message:"Invalid operation data: send requires type, reply requires messageCode, get requires messageCode"})},6252(e,exports,t){"use strict"
3250
+ exports.TestingProcessCreateSchema=r.z.object({name:r.z.string().min(1).describe("Name for the test process"),description:r.z.string().optional().describe("Description of what this process verifies"),scope:r.z.string().optional().describe('Path prefix for monorepo scoping (e.g., "packages/api/"). Omit for global.'),setup:r.z.array(r.z.string()).optional().describe('Commands to prepare the environment (e.g., ["ln -s ../../node_modules node_modules"])'),commands:r.z.array(l).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands")}),exports.TestingProcessUpdateSchema=r.z.object({processId:r.z.string().describe("Test process ID to update"),name:r.z.string().min(1).optional().describe("New name"),description:r.z.string().optional().describe("New description"),scope:r.z.string().nullable().optional().describe("New scope (null to remove)"),isActive:r.z.boolean().optional().describe("Enable or disable the process"),setup:r.z.array(r.z.string()).optional().describe("New setup commands (replaces existing)"),commands:r.z.array(l).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands")}),exports.TestingReferenceSchema=r.z.object({}),exports.ExecuteTestCommandSchema=r.z.object({processId:r.z.string().describe("Test process ID containing the command"),commandName:r.z.string().describe('Name of the test command to run, or "setup" to run all setup commands in sequence')}),exports.ReportTestResultsSchema=r.z.object({status:r.z.enum(["passed","failed","error"]).describe("Overall result"),results:r.z.object({commands:r.z.array(r.z.object({name:r.z.string().describe("Command name"),status:r.z.enum(["passed","failed","skipped","error"]).describe("Command result"),output:r.z.string().optional().describe("Relevant output snippet"),diagnosis:r.z.string().optional().describe("Why it failed, if applicable")})).describe("Per-command results"),summary:r.z.string().describe("Brief overall summary"),acceptanceCriteria:r.z.array(r.z.object({criterion:r.z.string().describe("The acceptance criterion text"),status:r.z.enum(["verified","unverified","unclear"]),evidence:r.z.string().describe("How verified, or why not")})).optional().describe("AC verification results, if applicable")}).describe("Structured test results")}),exports.SessionMessageOperationsSchema=r.z.object({operation:r.z.enum(["send","reply","list","get","offer-handoff"]),type:r.z.enum(["question","report"]).optional().describe("Message type to send (required for send)"),toSessionId:r.z.string().optional().describe('Target session ID, or "parent" to auto-resolve to parent session (omit for broadcast questions)'),questionType:r.z.enum(["free-form","alternatives"]).optional().describe('Type of question (required for send type="question")'),questionContent:r.z.object({question:r.z.string().min(1).describe("The question text"),context:r.z.string().optional().describe("Additional context"),options:r.z.array(r.z.object({id:r.z.string(),label:r.z.string(),description:r.z.string().optional()})).optional().describe("Options for alternatives questions"),allowMultiple:r.z.boolean().optional().describe("Allow selecting multiple options")}).optional().describe('Question content (required for send type="question")'),priority:r.z.enum(["low","normal","high"]).optional().describe("Question priority"),expiresInHours:r.z.number().optional().describe("Question expiry in hours"),status:r.z.enum(["success","partial","failure","blocked"]).optional().describe('Report status (required for send type="report")'),summary:r.z.string().optional().describe('Report summary (required for send type="report")'),details:r.z.string().optional().describe("Report details"),finish:r.z.boolean().optional().describe("Release request associations after report"),messageCode:r.z.string().optional().describe("Message code (required for reply and get operations)"),respondedBySessionId:r.z.string().optional().describe("Session ID answering the question"),text:r.z.string().optional().describe("Text answer for free-form questions"),selectedOptions:r.z.array(r.z.string()).optional().describe("Selected option IDs for alternatives"),notes:r.z.string().optional().describe("Additional notes"),list:r.z.object({sessionId:r.z.string().optional().describe("Filter by session ID (auto-discovered if omitted)"),messageType:r.z.enum(["question","report","all"]).default("all").describe("Filter by message type"),direction:r.z.enum(["incoming","outgoing","all"]).default("all"),status:r.z.enum(["pending","answered","expired","success","partial","failure","blocked","all"]).default("all").describe("Filter by status"),readStatus:r.z.enum(["unread","read","acknowledged","all"]).default("all").describe("Filter by read status (reports only)"),limit:r.z.number().min(1).max(100).default(50),offset:r.z.number().min(0).default(0)}).optional().describe('List filters (operation: "list" only)'),offerHandoff:r.z.object({summary:r.z.string().describe("Summary of what was planned/created"),requestIds:r.z.array(r.z.string()).describe("Request IDs that were created from the plan")}).optional().describe('Handoff offer details (operation: "offer-handoff" only)')}).refine((e=>"send"===e.operation?!!e.type:"reply"===e.operation?!!e.messageCode:"list"===e.operation||("get"===e.operation?!!e.messageCode:"offer-handoff"===e.operation)),{message:"Invalid operation data: send requires type, reply requires messageCode, get requires messageCode"}),exports.UpdateSpecializationSchema=r.z.object({specialization:r.z.string().min(1).max(500).describe("Your updated specialization summary \u2014 a concise description of your accumulated domain expertise")})},6252(e,exports,t){"use strict"
3380
3251
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3381
3252
  const r=t(6183),n=t(405)
3382
3253
  exports.def={name:"plan_write",description:"Modify project plans.\n\nOperations:\n\u2022 update - Update plan content\n\u2022 append - Append content to an existing plan\n\u2022 replace - Find and replace text within a plan\n\u2022 create-snapshot - Create a version snapshot\n\u2022 restore - Restore to a previous version",schema:r.PlanWriteSchema,annotations:{title:"Plan Write",readOnlyHint:!1,destructiveHint:!1},handler(e,t){return(0,n.handlePlanWrite)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer,t.cliOrigin)}}},6261(module){"use strict"
@@ -3513,24 +3384,24 @@ const q=_.filter((e=>e.path)),S=_.filter((e=>e.documentId))
3513
3384
  y.info("Operation breakdown",{fileOperations:q.length,documentOperations:S.length})
3514
3385
  const T=[]
3515
3386
  for(const e of q){const{normalizedPath:r,fullPath:n}=u.validateAndNormalizePath(e.path,t)
3516
- T.push({type:"file",path:r,fullPath:n,insertions:e.insertions})}const M=[]
3387
+ T.push({type:"file",path:r,fullPath:n,insertions:e.insertions})}const R=[]
3517
3388
  if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3518
- for(const e of S)M.push({type:"document",documentId:e.documentId,insertions:e.insertions})
3519
- if(M.length>0&&t.apiClient){const e=M.map((e=>e.documentId))
3389
+ for(const e of S)R.push({type:"document",documentId:e.documentId,insertions:e.insertions})
3390
+ if(R.length>0&&t.apiClient){const e=R.map((e=>e.documentId))
3520
3391
  try{await(0,p.ensureDocumentsNotLocked)(e,t.apiClient,y,a,"insert-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3521
3392
  throw e}}I=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("insert_lines_phase",1,{phase:I})
3522
- const R=T.length>0?T[0].path:"document-operation",P=await u.validateTaskId(C,R,n,y,a,v.metricsPrefix),x=P?.requestId
3523
- let O=null
3524
- T.length>0&&x&&(O=await u.validateWorkItemStates(C,T[0].path,n,s,t,y,a,v.metricsPrefix))
3525
- let j={taskPromoted:!1,requestPromoted:!1}
3526
- T.length>0&&x&&O&&(j=await u.autoPromoteTaskStatus(C,P.status,x,O.request?.status,T[0].path,n,s,y,a,v.metricsPrefix),j.taskPromoted&&y.info("Auto-promoted task to in_progress for insert-lines operation",{taskId:C,requestId:x,previousStatus:P.status,newStatus:j.newTaskStatus,triggeringOperation:"insert-lines"}))
3527
- const $=await u.ensureCorrectWorkspaceContext({taskPromoted:j.taskPromoted,requestId:x,context:t,operation:"insert-lines",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
3393
+ const P=T.length>0?T[0].path:"document-operation",M=await u.validateTaskId(C,P,n,y,a,v.metricsPrefix),x=M?.requestId
3394
+ let j=null
3395
+ T.length>0&&x&&(j=await u.validateWorkItemStates(C,T[0].path,n,s,t,y,a,v.metricsPrefix))
3396
+ let O={taskPromoted:!1,requestPromoted:!1}
3397
+ T.length>0&&x&&j&&(O=await u.autoPromoteTaskStatus(C,M.status,x,j.request?.status,T[0].path,n,s,y,a,v.metricsPrefix),O.taskPromoted&&y.info("Auto-promoted task to in_progress for insert-lines operation",{taskId:C,requestId:x,previousStatus:M.status,newStatus:O.newTaskStatus,triggeringOperation:"insert-lines"}))
3398
+ const $=await u.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:x,context:t,operation:"insert-lines",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
3528
3399
  if(!$.success){if($.isLockConflict)return{content:[{type:"text",text:"\u274c "+$.error}],isError:!0}
3529
3400
  throw Error($.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3530
3401
  for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
3531
- T[e]={...r,path:o,fullPath:s}}}if(M.length>0&&x)try{await(0,h.validateRequestStatusForDocumentOperation)(x,s,y,a,"insert-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3402
+ T[e]={...r,path:o,fullPath:s}}}if(R.length>0&&x)try{await(0,h.validateRequestStatusForDocumentOperation)(x,s,y,a,"insert-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3532
3403
  throw e}I=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("insert_lines_phase",1,{phase:I})
3533
- const D=[...T.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...M.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:A}=await u.createFileOperationRecords(C,x,t.projectId,v.recordType,R,{operationCount:_.length,fileOperations:T.length,documentOperations:M.length,operations:D,userComment:E},n,o,y,a,v.metricsPrefix,m)
3404
+ const D=[...T.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...R.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:A}=await u.createFileOperationRecords(C,x,t.projectId,v.recordType,P,{operationCount:_.length,fileOperations:T.length,documentOperations:R.length,operations:D,userComment:E},n,o,y,a,v.metricsPrefix,m)
3534
3405
  if(k=A,b=A,I=v.fileOperationPhase,a.incrementCounter("insert_lines_phase",1,{phase:I}),T.length>0&&t.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
3535
3406
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"insert-lines",{requestId:x,taskId:C,workspaceManager:t.workspaceManager},y,a)
3536
3407
  e.userChangesCommitted&&(y.debug("[INSERT-LINES] User changes committed before insert operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),y.info("User changes committed before insert-lines operation",{taskId:C,fileOperationsCount:T.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){y.debug("[INSERT-LINES] Pre-tool commit failed, continuing with insertions",{error:e instanceof Error?e.message:e+""}),y.warn("Pre-tool user changes commit failed, continuing with insert operation",{taskId:C,fileOperationsCount:T.length,error:e instanceof Error?e.message:e+""})}y.debug("[INSERT-LINES] Proceeding with file operations",{fileCount:T.length})
@@ -3539,22 +3410,22 @@ let N=0,L=0,z=0
3539
3410
  for(const e of T){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3540
3411
  try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
3541
3412
  const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.insertions)
3542
- t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,z++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),N+=t.failedInsertions,L+=t.totalLinesAdded}catch(r){t.error=(0,f.getErrorMessage)(r),t.failedInsertions=e.insertions.length,N+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}F.push(t)}for(const e of M){const n={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3413
+ t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,z++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),N+=t.failedInsertions,L+=t.totalLinesAdded}catch(r){t.error=(0,f.getErrorMessage)(r),t.failedInsertions=e.insertions.length,N+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}F.push(t)}for(const e of R){const n={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3543
3414
  try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.documentFileManager.getCachedDocumentInfo(e.documentId)
3544
3415
  n.filename=s?.filename
3545
3416
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
3546
- n.insertions=l,n.successfulInsertions=l.filter((e=>e.success)).length,n.failedInsertions=l.filter((e=>!e.success)).length,n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulInsertions>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,z++,y.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulInsertions:n.successfulInsertions,failedInsertions:n.failedInsertions,linesAdded:n.totalLinesAdded})):0===n.failedInsertions&&(n.success=!0),N+=n.failedInsertions,L+=n.totalLinesAdded}catch(t){n.error=(0,f.getErrorMessage)(t),n.failedInsertions=e.insertions.length,N+=n.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:n.error})}F.push(n)}if(M.length>0)try{for(const e of M){const r=F.find((t=>t.documentId===e.documentId))
3547
- r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const B=await u.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:b,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),H=u.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:U,failedOperations:W,totalSuccessfulChanges:G,overallSuccess:V,successfulFiles:J,failedFiles:K}=H
3548
- try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+M[0]?.documentId,status:V?"completed":"failed",error:V?void 0:W+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:D,totalSuccessfulInsertions:G,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:E,...T.length>0&&B.success&&B.commitHash&&{commitHash:B.commitHash,previousCommitHash:B.previousCommitHash||void 0}},note:V?`Line insertion completed: ${U}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${W}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
3549
- if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${U+W}\n`,Y+=`- **Successful operations:** ${U}\n`,Y+=`- **Failed operations:** ${W}\n`,Y+=`- **Total insertions:** ${G} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n`,Y+="\n",B.success&&B.commitHash&&(Y+="**Git Commit:**\n",Y+=`- **Commit Hash:** ${B.commitHash.substring(0,8)}\n`,Y+=`- **Files Committed:** ${B.filesCommitted.length}\n`,B.previousCommitHash&&(Y+=`- **Previous Commit:** ${B.previousCommitHash.substring(0,8)}\n`),Y+="\n"),$.lockAcquired&&$.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
3417
+ n.insertions=l,n.successfulInsertions=l.filter((e=>e.success)).length,n.failedInsertions=l.filter((e=>!e.success)).length,n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulInsertions>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,z++,y.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulInsertions:n.successfulInsertions,failedInsertions:n.failedInsertions,linesAdded:n.totalLinesAdded})):0===n.failedInsertions&&(n.success=!0),N+=n.failedInsertions,L+=n.totalLinesAdded}catch(t){n.error=(0,f.getErrorMessage)(t),n.failedInsertions=e.insertions.length,N+=n.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:n.error})}F.push(n)}if(R.length>0)try{for(const e of R){const r=F.find((t=>t.documentId===e.documentId))
3418
+ r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const H=await u.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:b,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),B=u.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:U,failedOperations:G,totalSuccessfulChanges:W,overallSuccess:V,successfulFiles:J,failedFiles:K}=B
3419
+ try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+R[0]?.documentId,status:V?"completed":"failed",error:V?void 0:G+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:D,totalSuccessfulInsertions:W,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:E,...T.length>0&&H.success&&H.commitHash&&{commitHash:H.commitHash,previousCommitHash:H.previousCommitHash||void 0}},note:V?`Line insertion completed: ${U}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${G}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
3420
+ if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${U+G}\n`,Y+=`- **Successful operations:** ${U}\n`,Y+=`- **Failed operations:** ${G}\n`,Y+=`- **Total insertions:** ${W} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n`,Y+="\n",H.success&&H.commitHash&&(Y+="**Git Commit:**\n",Y+=`- **Commit Hash:** ${H.commitHash.substring(0,8)}\n`,Y+=`- **Files Committed:** ${H.filesCommitted.length}\n`,H.previousCommitHash&&(Y+=`- **Previous Commit:** ${H.previousCommitHash.substring(0,8)}\n`),Y+="\n"),$.lockAcquired&&$.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
3550
3421
  if(Y+=`**Operation:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,"file"===e.type?Y+=`**File:** ${e.path}\n`:(Y+="**Document:** "+e.documentId,e.filename&&(Y+=` (${e.filename})`),Y+="\n"),e.error?Y+=`**Error:** ${e.error}\n`:(Y+=`**Insertions:** ${e.successfulInsertions} successful`,e.failedInsertions>0&&(Y+=`, ${e.failedInsertions} failed`),Y+="\n",Y+=`**Lines Added:** ${e.totalLinesAdded}\n`),e.insertions.some((e=>!e.success))){Y+="**Failed Insertion Details:**\n"
3551
3422
  for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?`between lines ${t.afterLine} and ${t.beforeLine}`:`${t.type} line ${t.line}`
3552
- Y+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{Y+="**Summary:**\n",Y+=`- **Total Operations:** ${F.length}\n`,Y+=`- **Successful:** ${U}\n`,Y+=`- **Failed:** ${W}\n`,Y+=`- **Total Insertions:** ${G} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n\n`,Y+="**Detailed Results:**\n\n"
3423
+ Y+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{Y+="**Summary:**\n",Y+=`- **Total Operations:** ${F.length}\n`,Y+=`- **Successful:** ${U}\n`,Y+=`- **Failed:** ${G}\n`,Y+=`- **Total Insertions:** ${W} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n\n`,Y+="**Detailed Results:**\n\n"
3553
3424
  for(const e of F){if("file"===e.type?Y+=`### File: ${e.path}\n`:(Y+="### Document: "+e.documentId,e.filename&&(Y+=` (${e.filename})`),Y+="\n"),Y+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error?Y+=`- **Error:** ${e.error}\n`:(Y+=`- **Insertions:** ${e.successfulInsertions} successful`,e.failedInsertions>0&&(Y+=`, ${e.failedInsertions} failed`),Y+="\n",Y+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.insertions.some((e=>!e.success))){Y+="- **Failed Insertion Details:**\n"
3554
3425
  for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?`between lines ${t.afterLine} and ${t.beforeLine}`:`${t.type} line ${t.line}`
3555
- Y+=` - ${t.type} insertion ${e}: ${t.error}\n`}}Y+="\n"}}M.length>0&&(Y+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3426
+ Y+=` - ${t.type} insertion ${e}: ${t.error}\n`}}Y+="\n"}}R.length>0&&(Y+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3556
3427
  const Q=Date.now()-w
3557
- return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:U,failedOperations:W}),a.incrementCounter("insert_lines_total",1,{success:V}),{content:[{type:"text",text:Y}],isError:!V}}catch(t){const r=Date.now()-w
3428
+ return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:U,failedOperations:G}),a.incrementCounter("insert_lines_total",1,{success:V}),{content:[{type:"text",text:Y}],isError:!V}}catch(t){const r=Date.now()-w
3558
3429
  if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:I}),b)try{await o.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,f.getErrorMessage)(t),phase:I,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("insert_lines_errors",1,{phase:I}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
3559
3430
  const c=a(t(1943)),l=t(6183),u=i(t(5967)),d=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824),m=t(3255)},6539(e,exports,t){"use strict"
3560
3431
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
@@ -3572,54 +3443,53 @@ const S=new d.RequestClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts
3572
3443
  b.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
3573
3444
  const T=new g.DocumentClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3574
3445
  b.registerClient(T)
3575
- const M=new f.ToolRecordClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3576
- b.registerClient(M)
3577
- const R=new u.ProxyClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3578
- if(b.registerClient(R),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
3446
+ const R=new f.ToolRecordClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3447
+ b.registerClient(R)
3448
+ const P=new u.ProxyClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3449
+ if(b.registerClient(P),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
3579
3450
  try{m.info("Creating ProjectSynchronizer components")
3580
3451
  const{ProjectRegistry,ProjectFileSystem,ProjectSynchronizer}=await t.e(478).then(t.bind(t,5478)),e=new ProjectRegistry(m),r=new ProjectFileSystem(m),n=new ProjectSynchronizer(m,e,new l.ProjectClientAdapter(_,m),r,{createRemoteProjects:!0})
3581
3452
  _.setProjectSynchronizer(n),m.info("ProjectSynchronizer created and connected to ProjectClient")}catch(e){const t="Failed to create required ProjectSynchronizer components: "+(0,h.getErrorMessage)(e)
3582
- throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const P=new o.ApiClient(I,_,E,q,S,T,M,R,m)
3583
- m.info("API client initialized with specialized clients"),v?(P.setAuthToken(v),m.info("Auth token set on ApiClient during creation",{hasToken:!0,tokenLength:v.length})):m.warn("No auth token available during ApiClient creation",{info:"Client will need to authenticate before making requests"})
3453
+ throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const M=new o.ApiClient(I,_,E,q,S,T,R,P,m)
3454
+ m.info("API client initialized with specialized clients"),v?(M.setAuthToken(v),m.info("Auth token set on ApiClient during creation",{hasToken:!0,tokenLength:v.length})):m.warn("No auth token available during ApiClient creation",{info:"Client will need to authenticate before making requests"})
3584
3455
  const x=b.verifyAllClients()
3585
3456
  x.success?m.info("Token consistency verified across all clients"):m.error(`Token inconsistency detected in ${x.failedClients.length} clients: ${x.failedClients.join(", ")}`)
3586
- const O=P.getAuthToken()
3587
- return v&&!O?(m.error("CRITICAL: ApiClient token was not set properly!"),P.setAuthToken(v)):O&&m.info("ApiClient token verified",{tokenLength:O.length,matches:O===v}),m.info("API client creation completed successfully"),P}}},6540(e,exports){"use strict"
3457
+ const j=M.getAuthToken()
3458
+ return v&&!j?(m.error("CRITICAL: ApiClient token was not set properly!"),M.setAuthToken(v)):j&&m.info("ApiClient token verified",{tokenLength:j.length,matches:j===v}),m.info("API client creation completed successfully"),M}}},6540(e,exports){"use strict"
3588
3459
  var t
3589
3460
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6552(e,exports,t){"use strict"
3590
- async function r(){const e=new o.StdioServerTransport,t=(0,l.setupParentProcessDetection)((()=>{b.info("Parent process gone or orphan detected. Shutting down."),process.exit(0)}))
3591
- if(E)try{await E.connectStdio(),(0,a.isDebugToolsEnabled)()&&b.info("Connected stdio transport to server")}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3592
- throw b.error("Failed to connect stdio transport",{errorDetails:t}),e}else b.error("No global server instance available to connect transport")
3461
+ async function r(){const e=new o.StdioServerTransport,t=(0,l.setupParentProcessDetection)((()=>{k.info("Parent process gone or orphan detected. Shutting down."),process.exit(0)}))
3462
+ if(_)try{await _.connectStdio(),(0,a.isDebugToolsEnabled)()&&k.info("Connected stdio transport to server")}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3463
+ throw k.error("Failed to connect stdio transport",{errorDetails:t}),e}else k.error("No global server instance available to connect transport")
3593
3464
  return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3594
3465
  Object.defineProperty(exports,"__esModule",{value:!0})
3595
- const o=t(5802),s=n(t(6928)),i=t(184),a=t(3444),c=t(1152),l=t(8851),u=t(8411),d=n(t(9896)),h=t(4139),g=t(5218),p=t(8824),f=t(9939),m=t(7960),y=process.argv.slice(2),w=y[0]||process.cwd(),k=s.default.resolve(w)
3596
- console.error("\n=== MCP STARTUP DIAGNOSTICS ==="),console.error("Script path (process.argv[1]):",process.argv[1]),console.error("Base directory:",k),console.error("ENABLE_DEBUG_TOOLS env:",process.env.ENABLE_DEBUG_TOOLS),console.error("DEBUG_LOGGING env:",process.env.DEBUG_LOGGING),console.error("isDevBuild():",(0,m.isDevBuild)()),console.error("isDebugToolsEnabled():",(0,a.isDebugToolsEnabled)()),console.error("===============================\n")
3597
- const b=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:k});(0,a.isDebugToolsEnabled)()?b.info("MCP Direct server initializing",{baseDir:k,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):b.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(b.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),E)try{E.cleanupSSEConnection()}catch(e){b.error("Error during cleanup after uncaught exception: "+e)}setTimeout((()=>process.exit(1)),500)})),process.on("unhandledRejection",(e=>{b.error("UNHANDLED REJECTION: "+e,{stack:e instanceof Error?e.stack:"No stack available"})})),process.on("exit",(e=>{b.info("Process exiting with code: "+e)}))
3598
- const I=process.stdout.write
3599
- process.stdout.write=function(e,t,r){try{if("string"==typeof e)try{JSON.parse(e)}catch(t){return e.includes('"__message_type"')||(process.stderr.write("[STDOUT REDIRECTED]: "+e),r&&r()),!0}return"string"==typeof t&&"function"==typeof r?I.call(process.stdout,e,t,r):"function"==typeof t?I.call(process.stdout,e,void 0,t):I.call(process.stdout,e)}catch(e){return process.stderr.write("[STDOUT ERROR]: "+e),!0}},(0,a.isDebugToolsEnabled)()&&(b.info("Initialized stdout filtering to ensure only valid JSON is sent"),b.info("!!!MARKER!!! COMMAND-LINE ARGS:",{args:JSON.stringify(y)}),b.info("!!!MARKER!!! BASE DIRECTORY:",{baseDir:w}),b.info("!!!MARKER!!! ABSOLUTE BASE DIR:",{absBaseDir:k}),b.info("Working with base directory:",{absBaseDir:k}))
3600
- try{if(d.default.existsSync(k)||(b.warn(`Base directory ${k} does not exist. Creating it...`),d.default.mkdirSync(k,{recursive:!0})),(0,a.isDebugToolsEnabled)()){const e=s.default.join(k,".mcp-test-file")
3601
- d.default.writeFileSync(e,(new Date).toISOString()),b.info("Successfully wrote test file to "+e),d.default.unlinkSync(e),b.info("Successfully deleted test file"),b.info(`Confirmed base directory ${k} exists and is accessible`)}}catch(e){b.error(`Error accessing base directory ${k}:`,{error:e}),b.warn("This may cause issues with file operations - please check permissions")}const v=(0,c.createMetricsCollector)(!1)
3602
- let C=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com"
3603
- const _=global.__serverInitialized
3604
- void 0===_?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&b.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&b.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
3605
- let E=null
3606
- const q=(0,g.isMultiAgentModeEnabled)(k)
3607
- try{(0,u.acquireProcessLock)(k,q)||(b.error(`Process lock acquisition failed for ${k}. Another instance may be running.`),b.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&(q?b.info("Multi-agent mode enabled - allowing concurrent access to "+k):b.info("Successfully acquired process lock for "+k))}catch(e){b.error("Lock acquisition threw exception",{error:(0,p.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),b.error("Cannot continue without lock in single-agent mode"),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(b.info("============================================================"),b.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),b.info("BASE DIR: "+k),b.info("ALCHEMY PATH: "+s.default.join(k,h.ALCHEMY_DIR_NAME)),b.info("PROJECT PATH: "+s.default.join(k,h.ALCHEMY_DIR_NAME+"/project.json")),b.info("MULTI-AGENT MODE: "+q),b.info("MCP client information will be captured during protocol initialization")),b.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(b.info("============================================================"),b.info("Base directory: "+k),b.info("Remote server URL: "+C),b.info("Node version: "+process.version),b.info("Current working directory: "+process.cwd()),b.info("ALLOWED_DIRECTORIES env var: not used (single working directory mode)"),b.info("Server already initialized: "+(_?"YES":"NO"))),_&&((0,a.isDebugToolsEnabled)()&&(b.info("Server already initialized globally, reusing existing server instance"),b.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3608
- b.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
3609
- try{const e=d.default.existsSync(k)
3610
- if((0,a.isDebugToolsEnabled)()&&b.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=d.default.statSync(k)
3611
- b.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(8)}`)}else(0,a.isDebugToolsEnabled)()&&b.info("Directory does not exist, trying to create it"),d.default.mkdirSync(k,{recursive:!0})}catch(e){b.error("Error checking directory: "+e)}if(!d.default.existsSync(k))try{d.default.mkdirSync(k,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&b.info("Created base directory: "+k)}catch(e){b.error("Failed to create base directory: "+e)}const S=s.default.join(k,h.ALCHEMY_DIR_NAME)
3612
- if(!d.default.existsSync(S))try{d.default.mkdirSync(S,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&b.info("Created alchemy lab directory: "+S)}catch(e){b.error("Failed to create alchemy lab directory: "+e)}try{(async function(){try{C=await async function(){if(process.env.REMOTE_SERVER_URL)return process.env.REMOTE_SERVER_URL
3613
- try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(b),n=await r.getInstallationConfig()
3614
- if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&b.info("Loaded REMOTE_SERVER_URL from installation config",{remoteServerUrl:n.remoteServerUrl}),n.remoteServerUrl}catch(e){(0,a.isDebugToolsEnabled)()&&b.debug("Could not read REMOTE_SERVER_URL from installation config",{error:e instanceof Error?e.message:"Unknown error"})}return"https://api.alchemylabcode.com"}()
3615
- try{const e=await(0,f.syncPlugins)(k,(0,m.isDevBuild)(),b)
3616
- e.synced.length>0&&b.info("Synced plugins on startup",{synced:e.synced}),e.errors.length>0&&b.warn("Some plugins failed to sync",{errors:e.errors})}catch(e){b.warn("Plugin sync failed",{error:e instanceof Error?e.message:"Unknown error"})}(0,a.isDebugToolsEnabled)()&&(b.info("Creating MCP server with base dir: "+k),b.info("Using remote server URL: "+C))
3617
- const e=await(0,i.createServer)(k,b,v,C,{multiAgentMode:(0,g.isMultiAgentModeEnabled)(k)})
3618
- E=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&b.info("MCP server created successfully")
3466
+ const o=t(5802),s=n(t(6928)),i=t(184),a=t(3444),c=t(1152),l=t(8851),u=t(8411),d=n(t(9896)),h=t(4139),g=t(8824),p=t(9939),f=t(7960),m=process.argv.slice(2),y=m[0]||process.cwd(),w=s.default.resolve(y)
3467
+ console.error("\n=== MCP STARTUP DIAGNOSTICS ==="),console.error("Script path (process.argv[1]):",process.argv[1]),console.error("Base directory:",w),console.error("ENABLE_DEBUG_TOOLS env:",process.env.ENABLE_DEBUG_TOOLS),console.error("DEBUG_LOGGING env:",process.env.DEBUG_LOGGING),console.error("isDevBuild():",(0,f.isDevBuild)()),console.error("isDebugToolsEnabled():",(0,a.isDebugToolsEnabled)()),console.error("===============================\n")
3468
+ const k=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:w});(0,a.isDebugToolsEnabled)()?k.info("MCP Direct server initializing",{baseDir:w,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):k.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(k.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),_)try{_.cleanupSSEConnection()}catch(e){k.error("Error during cleanup after uncaught exception: "+e)}setTimeout((()=>process.exit(1)),500)})),process.on("unhandledRejection",(e=>{k.error("UNHANDLED REJECTION: "+e,{stack:e instanceof Error?e.stack:"No stack available"})})),process.on("exit",(e=>{k.info("Process exiting with code: "+e)}))
3469
+ const b=process.stdout.write
3470
+ process.stdout.write=function(e,t,r){try{if("string"==typeof e)try{JSON.parse(e)}catch(t){return e.includes('"__message_type"')||(process.stderr.write("[STDOUT REDIRECTED]: "+e),r&&r()),!0}return"string"==typeof t&&"function"==typeof r?b.call(process.stdout,e,t,r):"function"==typeof t?b.call(process.stdout,e,void 0,t):b.call(process.stdout,e)}catch(e){return process.stderr.write("[STDOUT ERROR]: "+e),!0}},(0,a.isDebugToolsEnabled)()&&(k.info("Initialized stdout filtering to ensure only valid JSON is sent"),k.info("!!!MARKER!!! COMMAND-LINE ARGS:",{args:JSON.stringify(m)}),k.info("!!!MARKER!!! BASE DIRECTORY:",{baseDir:y}),k.info("!!!MARKER!!! ABSOLUTE BASE DIR:",{absBaseDir:w}),k.info("Working with base directory:",{absBaseDir:w}))
3471
+ try{if(d.default.existsSync(w)||(k.warn(`Base directory ${w} does not exist. Creating it...`),d.default.mkdirSync(w,{recursive:!0})),(0,a.isDebugToolsEnabled)()){const e=s.default.join(w,".mcp-test-file")
3472
+ d.default.writeFileSync(e,(new Date).toISOString()),k.info("Successfully wrote test file to "+e),d.default.unlinkSync(e),k.info("Successfully deleted test file"),k.info(`Confirmed base directory ${w} exists and is accessible`)}}catch(e){k.error(`Error accessing base directory ${w}:`,{error:e}),k.warn("This may cause issues with file operations - please check permissions")}const I=(0,c.createMetricsCollector)(!1)
3473
+ let v=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com"
3474
+ const C=global.__serverInitialized
3475
+ void 0===C?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&k.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&k.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
3476
+ let _=null
3477
+ try{(0,u.acquireProcessLock)(w)||(k.error(`Process lock acquisition failed for ${w}. Another instance may be running.`),k.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&k.info("Multi-agent mode enabled - allowing concurrent access to "+w)}catch(e){k.error("Lock acquisition threw exception",{error:(0,g.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(k.info("============================================================"),k.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),k.info("BASE DIR: "+w),k.info("ALCHEMY PATH: "+s.default.join(w,h.ALCHEMY_DIR_NAME)),k.info("PROJECT PATH: "+s.default.join(w,h.ALCHEMY_DIR_NAME+"/project.json")),k.info("MULTI-AGENT MODE: true"),k.info("MCP client information will be captured during protocol initialization")),k.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(k.info("============================================================"),k.info("Base directory: "+w),k.info("Remote server URL: "+v),k.info("Node version: "+process.version),k.info("Current working directory: "+process.cwd()),k.info("ALLOWED_DIRECTORIES env var: not used"),k.info("Server already initialized: "+(C?"YES":"NO"))),C&&((0,a.isDebugToolsEnabled)()&&(k.info("Server already initialized globally, reusing existing server instance"),k.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3478
+ k.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
3479
+ try{const e=d.default.existsSync(w)
3480
+ if((0,a.isDebugToolsEnabled)()&&k.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=d.default.statSync(w)
3481
+ k.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(8)}`)}else(0,a.isDebugToolsEnabled)()&&k.info("Directory does not exist, trying to create it"),d.default.mkdirSync(w,{recursive:!0})}catch(e){k.error("Error checking directory: "+e)}if(!d.default.existsSync(w))try{d.default.mkdirSync(w,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&k.info("Created base directory: "+w)}catch(e){k.error("Failed to create base directory: "+e)}const E=s.default.join(w,h.ALCHEMY_DIR_NAME)
3482
+ if(!d.default.existsSync(E))try{d.default.mkdirSync(E,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&k.info("Created alchemy lab directory: "+E)}catch(e){k.error("Failed to create alchemy lab directory: "+e)}try{(async function(){try{v=await async function(){if(process.env.REMOTE_SERVER_URL)return process.env.REMOTE_SERVER_URL
3483
+ try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(k),n=await r.getInstallationConfig()
3484
+ if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&k.info("Loaded REMOTE_SERVER_URL from installation config",{remoteServerUrl:n.remoteServerUrl}),n.remoteServerUrl}catch(e){(0,a.isDebugToolsEnabled)()&&k.debug("Could not read REMOTE_SERVER_URL from installation config",{error:e instanceof Error?e.message:"Unknown error"})}return"https://api.alchemylabcode.com"}()
3485
+ try{const e=await(0,p.syncPlugins)(w,(0,f.isDevBuild)(),k)
3486
+ e.synced.length>0&&k.info("Synced plugins on startup",{synced:e.synced}),e.errors.length>0&&k.warn("Some plugins failed to sync",{errors:e.errors})}catch(e){k.warn("Plugin sync failed",{error:e instanceof Error?e.message:"Unknown error"})}(0,a.isDebugToolsEnabled)()&&(k.info("Creating MCP server with base dir: "+w),k.info("Using remote server URL: "+v))
3487
+ const e=await(0,i.createServer)(w,k,I,v)
3488
+ _=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&k.info("MCP server created successfully")
3619
3489
  const n=r()
3620
- return(0,a.isDebugToolsEnabled)()&&b.info("Stdio transport registered with server"),{server:E,transportInfo:n}}catch(e){throw b.error("Failed to initialize MCP server",{error:e}),e}})().then((()=>{(0,a.isDebugToolsEnabled)()&&b.info("MCP server initialization complete")})).catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3621
- b.error("Server initialization failed",{errorDetails:t}),process.exit(1)}))}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3622
- b.error("Exception during server initialization",{errorDetails:t}),process.exit(1)}process.on("SIGTERM",(()=>{b.info("SIGTERM received, shutting down"),setTimeout((()=>process.exit(0)),500)})),process.on("SIGINT",(()=>{b.info("SIGINT received, shutting down"),setTimeout((()=>process.exit(0)),500)}))},6595(e,exports,t){"use strict"
3490
+ return(0,a.isDebugToolsEnabled)()&&k.info("Stdio transport registered with server"),{server:_,transportInfo:n}}catch(e){throw k.error("Failed to initialize MCP server",{error:e}),e}})().then((()=>{(0,a.isDebugToolsEnabled)()&&k.info("MCP server initialization complete")})).catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3491
+ k.error("Server initialization failed",{errorDetails:t}),process.exit(1)}))}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3492
+ k.error("Exception during server initialization",{errorDetails:t}),process.exit(1)}process.on("SIGTERM",(()=>{k.info("SIGTERM received, shutting down"),setTimeout((()=>process.exit(0)),500)})),process.on("SIGINT",(()=>{k.info("SIGINT received, shutting down"),setTimeout((()=>process.exit(0)),500)}))},6595(e,exports,t){"use strict"
3623
3493
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ApiClient=void 0
3624
3494
  const r=t(1599),n=t(2690),o=t(4465),s=t(5187),i=t(5674),a=t(8824)
3625
3495
  exports.ApiClient=class{constructor(e,t,r,n,o,s,i,a,c){this.options={createRecords:!0},this.alchemyPath="",this.sessionRequestAssociationClient=null,this.sessionMessageClient=null,this.sessionTagMappingClient=null,this.cliSessionClient=null,this.logger=c,this.authManager=e,this.projectClient=t,this.taskClient=r,this.fileClient=n,this.requestClient=o,this.documentClient=s,this.toolRecordClient=i,this.proxyClient=a,this.tokenSynchronizer=e.getTokenSynchronizer(),this.baseUrl=a.baseUrl||"",this.documentClient&&"function"==typeof this.documentClient.setParentApiClient&&this.documentClient.setParentApiClient(this),this.logger.info("API client initialized with specialized clients")}async setToken(e){return this.authManager.setToken(e)}async getToken(){return this.authManager.getToken()}async hasValidToken(){return this.authManager.hasValidToken()}async removeToken(){return this.authManager.removeToken()}setOptions(e){this.options={...this.options,...e},this.logger.info("API client options updated",{options:this.options})}getOptions(){return{...this.options}}isOffline(){const e=this.projectClient.isOffline?.()||!1,t=this.fileClient.isOffline?.()||!1,r=this.proxyClient.isOffline?.()||!1,n=e||t||r
@@ -3664,48 +3534,48 @@ try{const i=u.validateArgs(e,l.ReplaceLinesSchema),{taskId:_,operations:E,commen
3664
3534
  if(w.info("Replacing lines in files and documents",{taskId:_,operationCount:E.length,comment:q}),!E||0===E.length)throw new d.ValidationError("At least one operation is required")
3665
3535
  const S=E.filter((e=>e.path)),T=E.filter((e=>e.documentId))
3666
3536
  w.info("Operation breakdown",{fileOperations:S.length,documentOperations:T.length})
3667
- const M=[]
3537
+ const R=[]
3668
3538
  for(const e of S){const{normalizedPath:r,fullPath:n}=u.validateAndNormalizePath(e.path,t)
3669
- M.push({type:"file",path:r,fullPath:n,replacements:e.replacements.map((e=>({lines:(0,y.parseLineSpec)(e.lines),content:e.content})))})}const R=[]
3539
+ R.push({type:"file",path:r,fullPath:n,replacements:e.replacements.map((e=>({lines:(0,y.parseLineSpec)(e.lines),content:e.content})))})}const P=[]
3670
3540
  if(T.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3671
- for(const e of T)R.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,y.parseLineSpec)(e.lines),content:e.content})))})
3672
- if(R.length>0&&t.apiClient){const e=R.map((e=>e.documentId))
3541
+ for(const e of T)P.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,y.parseLineSpec)(e.lines),content:e.content})))})
3542
+ if(P.length>0&&t.apiClient){const e=P.map((e=>e.documentId))
3673
3543
  try{await(0,p.ensureDocumentsNotLocked)(e,t.apiClient,w,a,"replace-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3674
3544
  throw e}}v=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
3675
- const P=M.length>0?M[0].path:"document-operation",x=await u.validateTaskId(_,P,n,w,a,C.metricsPrefix),O=x?.requestId
3676
- let j=null
3677
- M.length>0&&O&&(j=await u.validateWorkItemStates(_,M[0].path,n,s,t,w,a,C.metricsPrefix))
3545
+ const M=R.length>0?R[0].path:"document-operation",x=await u.validateTaskId(_,M,n,w,a,C.metricsPrefix),j=x?.requestId
3546
+ let O=null
3547
+ R.length>0&&j&&(O=await u.validateWorkItemStates(_,R[0].path,n,s,t,w,a,C.metricsPrefix))
3678
3548
  let $={taskPromoted:!1,requestPromoted:!1}
3679
- M.length>0&&O&&j&&($=await u.autoPromoteTaskStatus(_,x.status,O,j.request?.status,M[0].path,n,s,w,a,C.metricsPrefix),$.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:_,requestId:O,previousStatus:x.status,newStatus:$.newTaskStatus,triggeringOperation:"replace-lines"}))
3680
- const D=await u.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:O,context:t,operation:"replace-lines",logger:w,metrics:a,metricsPrefix:C.metricsPrefix})
3549
+ R.length>0&&j&&O&&($=await u.autoPromoteTaskStatus(_,x.status,j,O.request?.status,R[0].path,n,s,w,a,C.metricsPrefix),$.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:_,requestId:j,previousStatus:x.status,newStatus:$.newTaskStatus,triggeringOperation:"replace-lines"}))
3550
+ const D=await u.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:j,context:t,operation:"replace-lines",logger:w,metrics:a,metricsPrefix:C.metricsPrefix})
3681
3551
  if(!D.success){if(D.isLockConflict)return{content:[{type:"text",text:"\u274c "+D.error}],isError:!0}
3682
- throw Error(D.error)}if(M.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:M.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3683
- for(let e=0;e<M.length;e++){const r=M[e],n=S[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
3684
- M[e]={...r,path:o,fullPath:s}}}if(R.length>0&&O)try{await(0,h.validateRequestStatusForDocumentOperation)(O,s,w,a,"replace-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3552
+ throw Error(D.error)}if(R.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:R.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3553
+ for(let e=0;e<R.length;e++){const r=R[e],n=S[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
3554
+ R[e]={...r,path:o,fullPath:s}}}if(P.length>0&&j)try{await(0,h.validateRequestStatusForDocumentOperation)(j,s,w,a,"replace-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3685
3555
  throw e}v=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
3686
- const A=[...M.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...R.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await u.createFileOperationRecords(_,O,t.projectId,C.recordType,P,{operationCount:E.length,fileOperations:M.length,documentOperations:R.length,operations:A,userComment:q},n,o,w,a,C.metricsPrefix,m)
3687
- if(b=F,I=F,v=C.fileOperationPhase,a.incrementCounter("replace_lines_phase",1,{phase:v}),M.length>0&&t.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
3688
- const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:O,taskId:_,workspaceManager:t.workspaceManager},w,a)
3689
- e.userChangesCommitted&&(w.debug("[REPLACE-LINES] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before replace-lines operation",{taskId:_,fileOperationsCount:M.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[REPLACE-LINES] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:_,fileOperationsCount:M.length,error:e instanceof Error?e.message:e+""})}w.debug("[REPLACE-LINES] Proceeding with file operations",{fileCount:M.length})
3556
+ const A=[...R.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...P.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await u.createFileOperationRecords(_,j,t.projectId,C.recordType,M,{operationCount:E.length,fileOperations:R.length,documentOperations:P.length,operations:A,userComment:q},n,o,w,a,C.metricsPrefix,m)
3557
+ if(b=F,I=F,v=C.fileOperationPhase,a.incrementCounter("replace_lines_phase",1,{phase:v}),R.length>0&&t.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
3558
+ const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:j,taskId:_,workspaceManager:t.workspaceManager},w,a)
3559
+ e.userChangesCommitted&&(w.debug("[REPLACE-LINES] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before replace-lines operation",{taskId:_,fileOperationsCount:R.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[REPLACE-LINES] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:_,fileOperationsCount:R.length,error:e instanceof Error?e.message:e+""})}w.debug("[REPLACE-LINES] Proceeding with file operations",{fileCount:R.length})
3690
3560
  const N=[]
3691
- let L=0,z=0,B=0,H=0
3692
- for(const e of M){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3561
+ let L=0,z=0,H=0,B=0
3562
+ for(const e of R){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3693
3563
  try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
3694
3564
  const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.replacements)
3695
- t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,t.totalLinesReplaced=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulReplacements>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,H++,w.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),L+=t.failedReplacements,z+=t.totalLinesReplaced,B+=t.totalLinesAdded}catch(r){t.error=(0,f.getErrorMessage)(r),t.failedReplacements=e.replacements.length,L+=t.failedReplacements,w.error("File operation failed",{path:e.path,error:t.error})}N.push(t)}for(const e of R){const n={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3565
+ t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,t.totalLinesReplaced=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulReplacements>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,B++,w.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),L+=t.failedReplacements,z+=t.totalLinesReplaced,H+=t.totalLinesAdded}catch(r){t.error=(0,f.getErrorMessage)(r),t.failedReplacements=e.replacements.length,L+=t.failedReplacements,w.error("File operation failed",{path:e.path,error:t.error})}N.push(t)}for(const e of P){const n={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3696
3566
  try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.documentFileManager.getCachedDocumentInfo(e.documentId)
3697
3567
  n.filename=s?.filename
3698
3568
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
3699
- n.replacements=l,n.successfulReplacements=l.filter((e=>e.success)).length,n.failedReplacements=l.filter((e=>!e.success)).length,n.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,H++,w.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulReplacements:n.successfulReplacements,failedReplacements:n.failedReplacements,linesReplaced:n.totalLinesReplaced,linesAdded:n.totalLinesAdded})):0===n.failedReplacements&&(n.success=!0),L+=n.failedReplacements,z+=n.totalLinesReplaced,B+=n.totalLinesAdded}catch(t){n.error=(0,f.getErrorMessage)(t),n.failedReplacements=e.replacements.length,L+=n.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:n.error})}N.push(n)}if(R.length>0)try{for(const e of R){const r=N.find((t=>t.documentId===e.documentId))
3700
- r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const U=await u.handleMultiFileGitCommit(_,M,N,H,{operationType:"Replace lines",toolRecordId:I,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),W=u.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=W
3701
- try{await o.updateToolRecord(I,{metadata:{path:M.length>0?M[0].path:"document:"+R[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:A,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-k,userComment:q,...M.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:K?`Line replacement completed: ${G}/${N.length} operations successful${M.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${V}/${N.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z="## Line Replacement Results\n\n"
3702
- if(t.workspaceManager&&(Z+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Z+="**Summary:**\n",Z+=`- **Files processed:** ${G+V}\n`,Z+=`- **Successful operations:** ${G}\n`,Z+=`- **Failed operations:** ${V}\n`,Z+=`- **Total replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,B>0&&(Z+=`- **Total Lines Added:** ${B}\n`),Z+="\n",U.success&&U.commitHash&&(Z+="**Git Commit:**\n",Z+=`- **Commit Hash:** ${U.commitHash.substring(0,8)}\n`,Z+=`- **Files Committed:** ${U.filesCommitted.length}\n`,U.previousCommitHash&&(Z+=`- **Previous Commit:** ${U.previousCommitHash.substring(0,8)}\n`),Z+="\n"),D.lockAcquired&&D.lockedRequestId&&(Z+=`\u{1f512} **Locked request:** ${D.lockedRequestId}\n\n`),1===N.length){const e=N[0]
3569
+ n.replacements=l,n.successfulReplacements=l.filter((e=>e.success)).length,n.failedReplacements=l.filter((e=>!e.success)).length,n.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,B++,w.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulReplacements:n.successfulReplacements,failedReplacements:n.failedReplacements,linesReplaced:n.totalLinesReplaced,linesAdded:n.totalLinesAdded})):0===n.failedReplacements&&(n.success=!0),L+=n.failedReplacements,z+=n.totalLinesReplaced,H+=n.totalLinesAdded}catch(t){n.error=(0,f.getErrorMessage)(t),n.failedReplacements=e.replacements.length,L+=n.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:n.error})}N.push(n)}if(P.length>0)try{for(const e of P){const r=N.find((t=>t.documentId===e.documentId))
3570
+ r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const U=await u.handleMultiFileGitCommit(_,R,N,B,{operationType:"Replace lines",toolRecordId:I,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),G=u.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:W,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=G
3571
+ try{await o.updateToolRecord(I,{metadata:{path:R.length>0?R[0].path:"document:"+P[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:A,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:H,operationsWithChanges:B,processingTime:Date.now()-k,userComment:q,...R.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:K?`Line replacement completed: ${W}/${N.length} operations successful${R.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${V}/${N.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z="## Line Replacement Results\n\n"
3572
+ if(t.workspaceManager&&(Z+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Z+="**Summary:**\n",Z+=`- **Files processed:** ${W+V}\n`,Z+=`- **Successful operations:** ${W}\n`,Z+=`- **Failed operations:** ${V}\n`,Z+=`- **Total replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,H>0&&(Z+=`- **Total Lines Added:** ${H}\n`),Z+="\n",U.success&&U.commitHash&&(Z+="**Git Commit:**\n",Z+=`- **Commit Hash:** ${U.commitHash.substring(0,8)}\n`,Z+=`- **Files Committed:** ${U.filesCommitted.length}\n`,U.previousCommitHash&&(Z+=`- **Previous Commit:** ${U.previousCommitHash.substring(0,8)}\n`),Z+="\n"),D.lockAcquired&&D.lockedRequestId&&(Z+=`\u{1f512} **Locked request:** ${D.lockedRequestId}\n\n`),1===N.length){const e=N[0]
3703
3573
  if(Z+=`**Operation:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,"file"===e.type?Z+=`**File:** ${e.path}\n`:(Z+="**Document:** "+e.documentId,e.filename&&(Z+=` (${e.filename})`),Z+="\n"),e.error?Z+=`**Error:** ${e.error}\n`:(Z+=`**Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(Z+=`, ${e.failedReplacements} failed`),Z+="\n",Z+=`**Lines Replaced:** ${e.totalLinesReplaced}\n`,e.totalLinesAdded>0&&(Z+=`**Lines Added:** ${e.totalLinesAdded}\n`)),e.replacements.some((e=>!e.success))){Z+="**Failed Replacement Details:**\n"
3704
- for(const t of e.replacements.filter((e=>!e.success)))Z+=`- Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}}else{Z+="**Summary:**\n",Z+=`- **Total Operations:** ${N.length}\n`,Z+=`- **Successful:** ${G}\n`,Z+=`- **Failed:** ${V}\n`,Z+=`- **Total Replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,B>0&&(Z+=`- **Total Lines Added:** ${B}\n`),Z+="\n",Z+="**Detailed Results:**\n\n"
3574
+ for(const t of e.replacements.filter((e=>!e.success)))Z+=`- Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}}else{Z+="**Summary:**\n",Z+=`- **Total Operations:** ${N.length}\n`,Z+=`- **Successful:** ${W}\n`,Z+=`- **Failed:** ${V}\n`,Z+=`- **Total Replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,H>0&&(Z+=`- **Total Lines Added:** ${H}\n`),Z+="\n",Z+="**Detailed Results:**\n\n"
3705
3575
  for(const e of N){if("file"===e.type?Z+=`### File: ${e.path}\n`:(Z+="### Document: "+e.documentId,e.filename&&(Z+=` (${e.filename})`),Z+="\n"),Z+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error&&(Z+=`- **Error:** ${e.error}\n`),Z+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(Z+=`, ${e.failedReplacements} failed`),Z+="\n",Z+=`- **Lines Replaced:** ${e.totalLinesReplaced}\n`,e.totalLinesAdded>0&&(Z+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.replacements.some((e=>!e.success))){Z+="- **Failed Replacement Details:**\n"
3706
- for(const t of e.replacements.filter((e=>!e.success)))Z+=` - Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}Z+="\n"}}R.length>0&&(Z+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3576
+ for(const t of e.replacements.filter((e=>!e.success)))Z+=` - Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}Z+="\n"}}P.length>0&&(Z+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3707
3577
  const X=Date.now()-k
3708
- return w.info("Replace lines operation completed",{duration:X,success:K,totalOperations:N.length,successfulOperations:G,failedOperations:V}),a.incrementCounter("replace_lines_total",1,{success:K}),{content:[{type:"text",text:Z}],isError:!K}}catch(t){const r=Date.now()-k
3578
+ return w.info("Replace lines operation completed",{duration:X,success:K,totalOperations:N.length,successfulOperations:W,failedOperations:V}),a.incrementCounter("replace_lines_total",1,{success:K}),{content:[{type:"text",text:Z}],isError:!K}}catch(t){const r=Date.now()-k
3709
3579
  if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,f.getErrorMessage)(t),phase:v,duration:r,userComment:e?.comment},note:"Line replacement failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_lines_errors",1,{phase:v}),{content:[{type:"text",text:"\u274c **Replace Lines Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
3710
3580
  const c=a(t(1943)),l=t(6183),u=i(t(5967)),d=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824),m=t(3255),y=t(9470)},6688(e,exports,t){"use strict"
3711
3581
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
@@ -3767,11 +3637,11 @@ s.info("Getting file changes for task "+g,{showDiff:p})
3767
3637
  const f=r.getTaskClient(),m=r.getToolRecordClient(),y=t.projectId
3768
3638
  let w
3769
3639
  r.setProjectId(y)
3770
- try{const M=await f.getTask(g)
3771
- s.info("Raw task response data",{responseDataType:typeof M,isArray:Array.isArray(M),hasData:null!=M,properties:M&&"object"==typeof M?Object.keys(M):[]}),w=(0,l.extractDataFromResponse)(M,{logger:s,operationName:"getTask",defaultValue:{id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+w.title)}catch(R){s.warn("Could not fetch task information: "+(0,d.getErrorMessage)(R)),w={id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let k=[]
3772
- try{const P=await m.getToolRecordsByTaskId(g)
3773
- if(s.info("Raw records response data",{responseDataType:typeof P,isArray:Array.isArray(P),hasData:null!=P,properties:P&&"object"==typeof P?Object.keys(P):[]}),k=(0,l.extractArrayFromResponse)(P,{logger:s,operationName:"searchRecords",defaultValue:[]}),k.length>0&&s.info("First record summary:",{id:k[0].id,type:k[0].type,hasMetadata:!!k[0].metadata,hasCommitHash:!!k[0].metadata?.commitHash}),s.info(`Extracted ${k.length} records for task ${g}`),k.length>0){const x={}
3774
- k.forEach((e=>{x[e.type]=(x[e.type]||0)+1})),s.info("Record type distribution:",x)}}catch(O){s.warn("Error fetching records for task "+g,{error:(0,d.getErrorMessage)(O)}),k=[]}if(0===k.length)return h({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
3640
+ try{const R=await f.getTask(g)
3641
+ s.info("Raw task response data",{responseDataType:typeof R,isArray:Array.isArray(R),hasData:null!=R,properties:R&&"object"==typeof R?Object.keys(R):[]}),w=(0,l.extractDataFromResponse)(R,{logger:s,operationName:"getTask",defaultValue:{id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+w.title)}catch(P){s.warn("Could not fetch task information: "+(0,d.getErrorMessage)(P)),w={id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let k=[]
3642
+ try{const M=await m.getToolRecordsByTaskId(g)
3643
+ if(s.info("Raw records response data",{responseDataType:typeof M,isArray:Array.isArray(M),hasData:null!=M,properties:M&&"object"==typeof M?Object.keys(M):[]}),k=(0,l.extractArrayFromResponse)(M,{logger:s,operationName:"searchRecords",defaultValue:[]}),k.length>0&&s.info("First record summary:",{id:k[0].id,type:k[0].type,hasMetadata:!!k[0].metadata,hasCommitHash:!!k[0].metadata?.commitHash}),s.info(`Extracted ${k.length} records for task ${g}`),k.length>0){const x={}
3644
+ k.forEach((e=>{x[e.type]=(x[e.type]||0)+1})),s.info("Record type distribution:",x)}}catch(j){s.warn("Error fetching records for task "+g,{error:(0,d.getErrorMessage)(j)}),k=[]}if(0===k.length)return h({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
3775
3645
  function b(e){const t=new Map,r=new Map,n=[]
3776
3646
  for(const o of e)if("move-file"===o.type&&o.metadata){const e=o.metadata.source||o.metadata.oldPath,s=o.metadata.destination||o.metadata.newPath
3777
3647
  if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
@@ -3791,8 +3661,8 @@ let n=!1
3791
3661
  if(t&&(n=e.metadata.successfulOperations.some((e=>e&&e.source&&e.destination))),!n&&r&&(n=e.metadata.failedOperations.some((e=>e&&e.source&&e.destination))),!n)return s.warn("Skipping move-files record without valid operation paths: "+e.id),!1}else if("delete-file"===e.type){if(!e.metadata.path)return s.warn("Skipping delete-file record without path metadata: "+e.id),!1}else if("delete-files"===e.type){const t=e.metadata.paths
3792
3662
  if(!Array.isArray(t)||0===t.length)return s.warn("Skipping delete-files record without valid paths array: "+e.id),!1
3793
3663
  if(!t.every((e=>"string"==typeof e&&e.trim().length>0)))return s.warn("Skipping delete-files record without valid file paths: "+e.id),!1}return!0}))
3794
- if(s.info(`Found ${v.length} file operation records`),v.length>0){const j={}
3795
- v.forEach((e=>{j[e.type]=(j[e.type]||0)+1})),s.info("Filtered record type distribution:",j)}if(0===v.length)return h({success:!0,fileChanges:0}),{content:[{type:"text",text:`No file changes found for task ${g}.`}]}
3664
+ if(s.info(`Found ${v.length} file operation records`),v.length>0){const O={}
3665
+ v.forEach((e=>{O[e.type]=(O[e.type]||0)+1})),s.info("Filtered record type distribution:",O)}if(0===v.length)return h({success:!0,fileChanges:0}),{content:[{type:"text",text:`No file changes found for task ${g}.`}]}
3796
3666
  const C=new Map
3797
3667
  v.forEach((e=>{let t=null
3798
3668
  if(e.metadata){if(!e.metadata.commitHash){const t=["gitCommitId","commitId","commit","gitCommit"]
@@ -3835,46 +3705,46 @@ let ee=""
3835
3705
  try{if(X)try{const te=[`${Z.commitHash}:${A}`],re=await t.git.show(te)
3836
3706
  re&&re.trim().length>0?(ee=re.split("\n").map((e=>"+"+e)).join("\n"),_.set(A,{firstChange:Q,lastChange:Z,hasDiff:!0,diffText:ee})):_.set(A,{firstChange:Q,lastChange:Z,hasDiff:!1,diffText:"File exists in git history but has no content"})}catch(ne){s.warn("Error getting file content for "+A,{error:ne instanceof Error?ne.message:ne+""}),_.set(A,{firstChange:Q,lastChange:Z,hasDiff:!1,diffText:"Error getting file content from git"})}else{const oe=[`${Q.commitHash}..${Z.commitHash}`,"--",A]
3837
3707
  ee=await t.git.diff(oe),_.set(A,{firstChange:Q,lastChange:Z,hasDiff:!(!ee||0>=ee.trim().length),diffText:ee||"No changes detected in git diff"})}}catch(se){s.warn("Error generating diff for "+A,{error:se instanceof Error?se.message:se+""}),_.set(A,{firstChange:Q,lastChange:Z,hasDiff:!0,diffText:"Error generating diff, but git history is available"})}continue}}else s.info("No git history found for "+A)}}catch(ie){s.warn("Error getting git history for "+A,{error:(0,d.getErrorMessage)(ie)})}_.set(A,{firstChange:F[0],lastChange:F[F.length-1],hasDiff:!1,diffText:"No commit hashes available for this file"})
3838
- continue}const z=L[0],B=L[L.length-1]
3839
- s.info(`First commit: ${z.commitHash?z.commitHash:"unknown"}, Last commit: ${B.commitHash?B.commitHash:"unknown"}`)
3840
- let H=null,U=!1
3841
- if(t.git&&z.commitHash)try{H=await(0,c.findPreviousCommit)(t.git,A,z.commitHash),H?(U=!0,s.info(`Found previous commit: ${H} for ${A}`)):s.info(`No previous commit found for ${A}, likely a new file`)}catch(ae){s.warn("Error finding previous commit for "+A,{error:(0,d.getErrorMessage)(ae)})}const W=U&&H?{...z,commitHash:H,status:"pre-task"}:z
3842
- if(s.info(`Using ${U?"pre-task":"first task"} commit as baseline for ${A}: ${W.commitHash}`),s.info(`Last commit for ${A}: ${B.commitHash}`),s.info("Commits are "+(W.commitHash===B.commitHash?"identical":"different")),z.commitHash===B.commitHash&&!U){if(p&&!U&&t.git&&B.commitHash)try{const ce=[`${B.commitHash}:${A}`]
3843
- s.info(`Getting new file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${A}`)
3708
+ continue}const z=L[0],H=L[L.length-1]
3709
+ s.info(`First commit: ${z.commitHash?z.commitHash:"unknown"}, Last commit: ${H.commitHash?H.commitHash:"unknown"}`)
3710
+ let B=null,U=!1
3711
+ if(t.git&&z.commitHash)try{B=await(0,c.findPreviousCommit)(t.git,A,z.commitHash),B?(U=!0,s.info(`Found previous commit: ${B} for ${A}`)):s.info(`No previous commit found for ${A}, likely a new file`)}catch(ae){s.warn("Error finding previous commit for "+A,{error:(0,d.getErrorMessage)(ae)})}const G=U&&B?{...z,commitHash:B,status:"pre-task"}:z
3712
+ if(s.info(`Using ${U?"pre-task":"first task"} commit as baseline for ${A}: ${G.commitHash}`),s.info(`Last commit for ${A}: ${H.commitHash}`),s.info("Commits are "+(G.commitHash===H.commitHash?"identical":"different")),z.commitHash===H.commitHash&&!U){if(p&&!U&&t.git&&H.commitHash)try{const ce=[`${H.commitHash}:${A}`]
3713
+ s.info(`Getting new file content using git show: ${H.commitHash?H.commitHash.substring(0,8):"unknown"}:${A}`)
3844
3714
  const le=await t.git.show(ce)
3845
3715
  if(le&&le.trim().length>0){let ue=""
3846
3716
  const de=le.split("\n")
3847
3717
  for(const he of de)ue+=`+${he}\n`
3848
- _.set(A,{firstChange:W,lastChange:B,hasDiff:!0,diffText:ue}),s.info(`Formatted new file content as diff, ${de.length} lines`)
3849
- continue}}catch(ge){s.warn("Error getting new file content for "+A,{error:(0,d.getErrorMessage)(ge)})}_.set(A,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"Only one commit available for this file"})
3850
- continue}if(z.commitHash===B.commitHash&&U){if(H===z.commitHash){_.set(A,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"No changes detected"})
3851
- continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let G="",V=!1
3852
- if(p||"pre-task"!==W.status){try{if(t.git){try{await t.git.show([`${B.commitHash}:${A}`])}catch(fe){s.warn(`File ${A} does not exist in commit ${B.commitHash}, might be deleted or moved`),G="File was deleted or moved from this location during the task",V=!0,_.set(A,{firstChange:W,lastChange:B,hasDiff:V,diffText:G})
3718
+ _.set(A,{firstChange:G,lastChange:H,hasDiff:!0,diffText:ue}),s.info(`Formatted new file content as diff, ${de.length} lines`)
3719
+ continue}}catch(ge){s.warn("Error getting new file content for "+A,{error:(0,d.getErrorMessage)(ge)})}_.set(A,{firstChange:G,lastChange:H,hasDiff:!1,diffText:"Only one commit available for this file"})
3720
+ continue}if(z.commitHash===H.commitHash&&U){if(B===z.commitHash){_.set(A,{firstChange:G,lastChange:H,hasDiff:!1,diffText:"No changes detected"})
3721
+ continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let W="",V=!1
3722
+ if(p||"pre-task"!==G.status){try{if(t.git){try{await t.git.show([`${H.commitHash}:${A}`])}catch(fe){s.warn(`File ${A} does not exist in commit ${H.commitHash}, might be deleted or moved`),W="File was deleted or moved from this location during the task",V=!0,_.set(A,{firstChange:G,lastChange:H,hasDiff:V,diffText:W})
3853
3723
  continue}let pe
3854
- if("pre-task"===W.status?(pe=[`${W.commitHash}..${B.commitHash}`,"--",A],s.info(`Comparing pre-task commit with final commit: ${W.commitHash?W.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${A}`)):(pe=["4b825dc642cb6eb9a060e54bf8d69288fbee4904.."+B.commitHash,"--",A],s.info(`File created during task, showing full file diff using empty tree object: ${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${A}`)),G=await t.git.diff(pe),V=!!G&&G.trim().length>0,!V&&W.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
3855
- try{const me=await t.git.show([`${W.commitHash}:${A}`]),ye=await t.git.show([`${B.commitHash}:${A}`])
3856
- if(me!==ye&&(V=!0,G="Changes detected through direct content comparison (not visible in standard diff)",p)){const we=me.split("\n"),ke=ye.split("\n")
3857
- Math.abs(we.length-ke.length)>0&&(G+=`\n\nLine count changed: ${we.length} \u2192 ${ke.length}`),me.includes("\0")||ye.includes("\0")?G+="\n\nBinary content detected - changes not displayed":me.replace(/\s+/g,"")===ye.replace(/\s+/g,"")&&(G+="\n\nWhitespace-only changes detected")}}catch(be){s.warn("Error in direct file comparison: "+(be instanceof Error?be.message:be+""))}}s.info(`Diff generation result for ${A}: hasDiff=${V}, length=${G.length}`)}}catch(Ie){if(s.warn("Error getting diff for "+A,{error:(0,d.getErrorMessage)(Ie),firstCommit:z.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),G="Error getting diff: "+(0,d.getErrorMessage)(Ie),"pre-task"!==z.status&&t.git)try{const ve=[`${B.commitHash}:${A}`]
3858
- s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${A}`)
3724
+ if("pre-task"===G.status?(pe=[`${G.commitHash}..${H.commitHash}`,"--",A],s.info(`Comparing pre-task commit with final commit: ${G.commitHash?G.commitHash.substring(0,8):"unknown"}..${H.commitHash?H.commitHash.substring(0,8):"unknown"} for ${A}`)):(pe=["4b825dc642cb6eb9a060e54bf8d69288fbee4904.."+H.commitHash,"--",A],s.info(`File created during task, showing full file diff using empty tree object: ${H.commitHash?H.commitHash.substring(0,8):"unknown"} for ${A}`)),W=await t.git.diff(pe),V=!!W&&W.trim().length>0,!V&&G.commitHash!==H.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
3725
+ try{const me=await t.git.show([`${G.commitHash}:${A}`]),ye=await t.git.show([`${H.commitHash}:${A}`])
3726
+ if(me!==ye&&(V=!0,W="Changes detected through direct content comparison (not visible in standard diff)",p)){const we=me.split("\n"),ke=ye.split("\n")
3727
+ Math.abs(we.length-ke.length)>0&&(W+=`\n\nLine count changed: ${we.length} \u2192 ${ke.length}`),me.includes("\0")||ye.includes("\0")?W+="\n\nBinary content detected - changes not displayed":me.replace(/\s+/g,"")===ye.replace(/\s+/g,"")&&(W+="\n\nWhitespace-only changes detected")}}catch(be){s.warn("Error in direct file comparison: "+(be instanceof Error?be.message:be+""))}}s.info(`Diff generation result for ${A}: hasDiff=${V}, length=${W.length}`)}}catch(Ie){if(s.warn("Error getting diff for "+A,{error:(0,d.getErrorMessage)(Ie),firstCommit:z.commitHash||"unknown",lastCommit:H.commitHash||"unknown"}),W="Error getting diff: "+(0,d.getErrorMessage)(Ie),"pre-task"!==z.status&&t.git)try{const ve=[`${H.commitHash}:${A}`]
3728
+ s.info(`Trying fallback to show file content using git show: ${H.commitHash?H.commitHash.substring(0,8):"unknown"}:${A}`)
3859
3729
  const Ce=await t.git.show(ve)
3860
3730
  if(Ce&&Ce.trim().length>0){if(p){let _e=""
3861
3731
  const Ee=Ce.split("\n")
3862
3732
  for(const qe of Ee)_e+=`+${qe}\n`
3863
- G=_e}else G="File created during this task. Content:\n"+Ce
3864
- V=!0,s.info("Fallback succeeded, got file content of length "+Ce.length)}}catch(Se){s.warn("Fallback also failed for "+A,{error:Se instanceof Error?Se.message:Se+""})}}_.set(A,{firstChange:W,lastChange:B,hasDiff:V,diffText:G||"No changes detected between commits"})}else V=W.commitHash!==B.commitHash,G=V?"File has changes":"No changes detected between commits",_.set(A,{firstChange:W,lastChange:B,hasDiff:V,diffText:G})}let E=`# File Changes for Task: ${g}\n\n`
3733
+ W=_e}else W="File created during this task. Content:\n"+Ce
3734
+ V=!0,s.info("Fallback succeeded, got file content of length "+Ce.length)}}catch(Se){s.warn("Fallback also failed for "+A,{error:Se instanceof Error?Se.message:Se+""})}}_.set(A,{firstChange:G,lastChange:H,hasDiff:V,diffText:W||"No changes detected between commits"})}else V=G.commitHash!==H.commitHash,W=V?"File has changes":"No changes detected between commits",_.set(A,{firstChange:G,lastChange:H,hasDiff:V,diffText:W})}let E=`# File Changes for Task: ${g}\n\n`
3865
3735
  w&&"object"==typeof w&&(E+="## Task Information\n",E+=`- **Title**: ${w.title||"Unknown"}\n`,E+=`- **Status**: ${w.status||"Unknown"}\n`,E+=`- **Description**: ${w.description||"No description"}\n\n`)
3866
3736
  const q=3e3
3867
3737
  let S=0,T=!1
3868
3738
  if(p){for(const Te of _.values())Te.hasDiff&&Te.diffText&&(S+=Te.diffText.split("\n").length)
3869
3739
  T=S>q,s.info(`Total diff size: ${S} lines (limit: ${q} lines)`),s.info(`Diffs ${T?"will be limited":"will be shown"} based on size`)}if(E+="## Summary\n",E+=`- **Files Modified**: ${C.size}\n`,E+=`- **Total File Operations**: ${v.length}\n`,E+="- **What's Shown**: For existing files, comparing state before task started with final state.\n",E+=" For files created during task, showing the entire file as created.\n",T?(E+=`- **Diff Display**: Limited (total diff size of ${S} lines exceeds limit of ${q} lines)\n`,E+=" Use file-history tool with individual files to see detailed changes\n\n"):E+=`- **Diff Display**: ${p?"Enabled":"Disabled"} (use showDiff=${!p} to ${p?"hide":"show"} diffs)\n\n`,I.allMoves.length>0){E+="## Move Operations\n\n",E+=`Detected ${I.allMoves.length} file move operation(s):\n\n`
3870
- for(const Me of I.allMoves)E+=`- **${Me.source}** \u2192 **${Me.destination}**\n`,E+=` - Operation: ${Me.type}\n`,E+=` - Timestamp: ${new Date(Me.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Me.recordId}\n\n`}E+="## Modified Files\n\n"
3871
- for(const[Re,Pe]of _.entries()){const{normalizedPath:xe,fullPath:Oe}=u.validateAndNormalizePath(Re,t)
3872
- let je=!1
3873
- try{await a.access(Oe),je=!0}catch{}E+=`### ${Re} ${je?"":"(Deleted)"}\n\n`
3874
- const $e=new Date(Pe.firstChange.timestamp).toLocaleString(),De=new Date(Pe.lastChange.timestamp).toLocaleString()
3875
- E+=`**First Change**: ${$e}\n`,E+=`**Last Change**: ${De}\n`,"pre-task"===Pe.firstChange.status&&Pe.firstChange.commitHash?E+=`**Pre-Task Commit**: ${Pe.firstChange.commitHash.substring(0,8)}\n`:Pe.firstChange.commitHash&&(E+=`**File Created During Task**: ${Pe.firstChange.commitHash.substring(0,8)}\n`),Pe.lastChange.commitHash&&(E+=`**Final Commit**: ${Pe.lastChange.commitHash.substring(0,8)}\n`)
3876
- const Ae=I.sourceToMove.get(Re),Fe=I.destToMove.get(Re)
3877
- Ae?E+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Ae.destination}**\n`:Fe&&(E+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Fe.source}**\n`),p&&!T?Pe.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=Pe.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${Pe.diffText}\n\n`:T&&Pe.hasDiff?(E+=`\n**Note**: File has changes (${Pe.diffText?Pe.diffText.split("\n").length:0} lines). `,E+=`Compare ${Pe.firstChange.commitHash?Pe.firstChange.commitHash.substring(0,8):"unknown"}..${Pe.lastChange.commitHash?Pe.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Pe.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${Pe.diffText}\n\n`,E+="---\n\n"}return h({success:!0,fileCount:C.size}),{content:[{type:"text",text:E}]}}catch(Ne){return s.error("Error in task file history tool",{error:Ne instanceof Error?Ne.stack:Ne+""}),h({success:!1,error:Ne instanceof Error?Ne.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,d.getErrorMessage)(Ne)}],isError:!0}}}
3740
+ for(const Re of I.allMoves)E+=`- **${Re.source}** \u2192 **${Re.destination}**\n`,E+=` - Operation: ${Re.type}\n`,E+=` - Timestamp: ${new Date(Re.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Re.recordId}\n\n`}E+="## Modified Files\n\n"
3741
+ for(const[Pe,Me]of _.entries()){const{normalizedPath:xe,fullPath:je}=u.validateAndNormalizePath(Pe,t)
3742
+ let Oe=!1
3743
+ try{await a.access(je),Oe=!0}catch{}E+=`### ${Pe} ${Oe?"":"(Deleted)"}\n\n`
3744
+ const $e=new Date(Me.firstChange.timestamp).toLocaleString(),De=new Date(Me.lastChange.timestamp).toLocaleString()
3745
+ E+=`**First Change**: ${$e}\n`,E+=`**Last Change**: ${De}\n`,"pre-task"===Me.firstChange.status&&Me.firstChange.commitHash?E+=`**Pre-Task Commit**: ${Me.firstChange.commitHash.substring(0,8)}\n`:Me.firstChange.commitHash&&(E+=`**File Created During Task**: ${Me.firstChange.commitHash.substring(0,8)}\n`),Me.lastChange.commitHash&&(E+=`**Final Commit**: ${Me.lastChange.commitHash.substring(0,8)}\n`)
3746
+ const Ae=I.sourceToMove.get(Pe),Fe=I.destToMove.get(Pe)
3747
+ Ae?E+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Ae.destination}**\n`:Fe&&(E+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Fe.source}**\n`),p&&!T?Me.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=Me.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${Me.diffText}\n\n`:T&&Me.hasDiff?(E+=`\n**Note**: File has changes (${Me.diffText?Me.diffText.split("\n").length:0} lines). `,E+=`Compare ${Me.firstChange.commitHash?Me.firstChange.commitHash.substring(0,8):"unknown"}..${Me.lastChange.commitHash?Me.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Me.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${Me.diffText}\n\n`,E+="---\n\n"}return h({success:!0,fileCount:C.size}),{content:[{type:"text",text:E}]}}catch(Ne){return s.error("Error in task file history tool",{error:Ne instanceof Error?Ne.stack:Ne+""}),h({success:!1,error:Ne instanceof Error?Ne.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,d.getErrorMessage)(Ne)}],isError:!0}}}
3878
3748
  const i=t(9860),a=s(t(1943)),c=t(9671),l=t(2960),u=s(t(5967)),d=t(8824)},6928(module){"use strict"
3879
3749
  module.exports=require("path")},6975(e,exports,t){"use strict"
3880
3750
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
@@ -4246,37 +4116,32 @@ return t.warn("Failed to get current git branch",{error:o}),r.incrementCounter("
4246
4116
  try{if(!t.git)return r.debug("No git repository available"),n.incrementCounter("find_feature_branch_no_git",1),o({success:!1,reason:"no_git"}),{found:!1}
4247
4117
  const s=await d.getRepositoryStatus(t.git,r,n),i=s.branches.filter((t=>t.name==="requests/"+e)),a=i.length>0,c=a?i[0].name:void 0,l=i.map((e=>e.name))
4248
4118
  return r.debug("Searched for feature branch",{requestId:e,found:a,branchName:c,matchingBranches:l.length,totalBranches:s.branches.length}),n.incrementCounter("find_feature_branch_success",1,{found:a.toString()}),o({success:!0,found:a.toString()}),{found:a,branchName:c,allBranches:l}}catch(t){const s=(0,g.getErrorMessage)(t)
4249
- return r.warn("Failed to find feature branch for request",{requestId:e,error:s}),n.incrementCounter("find_feature_branch_failure",1),o({success:!1,error:t instanceof Error?t.name:"unknown"}),{found:!1}}}async function o(e,o,s,i,a,c){if(!o||!s.git)return{switched:!1,message:"No branch switch needed"}
4250
- let l=!1,f=Date.now()
4251
- try{s.syncBranchState&&await s.syncBranchState(),Date.now(),f=Date.now()
4252
- const e=s.getCurrentBranchContext?await s.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
4253
- if(Date.now(),e.requestId===o)return i.debug("Already in correct request context",{requestId:o,currentBranch:e.branch}),{switched:!1,branchName:e.branch||void 0,message:`Already in request ${o} context`,lockAcquired:!1}
4254
- if(s.workspaceManager){i.debug("Using WorkspaceManager for request context switching",{requestId:o,currentMode:s.workspaceManager.getCurrentContext().mode})
4255
- try{if("multi-agent"===s.workspaceManager.getCurrentContext().mode)if(i.debug("Multi-agent mode: checking request lock before auto-switch",{requestId:o}),s.apiClient)try{const e=s.apiClient.getRequestClient(),{sessionTag:t}=(0,h.getGlobalClientInfo)()
4256
- f=Date.now()
4257
- const r=await e.getRequestLockStatus(o)
4258
- if(Date.now(),r.isLocked&&r.lockedBySessionTag!==t){i.warn("Auto-switch blocked by request lock",{requestId:o,lockedByAgent:r.lockedBySessionTag,currentAgent:t,lockedAt:r.lockedAt})
4259
- let e=`Request ${o} is currently locked by another agent (${r.lockedBySessionTag}).\n\nLocked since: ${r.lockedAt||"unknown"}\n\nIn multi-agent mode, only one agent can work on a request at a time. Please wait for the other agent to complete their work or contact an administrator if the lock appears stale.`
4260
- if(s.lockOverrideManager&&s.configManager)try{const t=await s.configManager.getEffectiveConfig(s.mainBasePath)
4261
- t.lockOverride.enabled&&(e+=`\n\n**To take over this request (only if safe to do so), use switch_to_branch with password: \`${s.lockOverrideManager.generatePassword(o,t.lockOverride.passwordValidityMinutes)}\` (valid for ${t.lockOverride.passwordValidityMinutes} minutes)**`)}catch(e){i.warn("Failed to check lock override config",{error:e})}throw new p.RequestLockError(e,o,r.lockedBySessionTag,r.lockedAt)}if(!r.isLocked){f=Date.now(),i.debug("Acquiring lock for auto-switch",{requestId:o,sessionTag:t})
4262
- const r=await e.lockRequest(o,t)
4263
- if(Date.now(),!r.locked){const e=`Failed to acquire lock for request ${o} during auto-switch`
4264
- throw i.warn("Auto-switch lock acquisition failed",{requestId:o}),Error(e)}i.info("Successfully acquired lock for auto-switch",{requestId:o,sessionTag:t,lockedAt:r.lockedAt}),l=!0}}catch(e){throw i.error("Lock check/acquisition failed during auto-switch",{requestId:o,error:e instanceof Error?e.message:e+""}),e}else i.warn("Multi-agent mode but no API client available for locking",{requestId:o})
4265
- i.debug("Ensuring workspace is ready for file operations",{requestId:o,reason:"first-file-operation"}),f=Date.now(),await s.workspaceManager.ensureWorkspaceReady(o),Date.now()
4266
- const e=s.workspaceManager.getCurrentContext()
4267
- if(e.basePath&&(s.git=(0,u.simpleGit)(e.basePath),i.info("Updated git instance to worktree path",{requestId:o,gitWorkingDirectory:e.basePath,mode:e.mode,branchName:e.branchName})),e.requestId!==o){const t=`Workspace switch validation failed. Expected requestId: ${o}, but got: ${e.requestId}`
4268
- throw i.error("Post-switch context validation failed",{requestId:o,expectedRequestId:o,actualRequestId:e.requestId,actualBasePath:e.basePath,mode:e.mode}),Error(t)}i.info("Workspace is ready via WorkspaceManager",{requestId:o,mode:s.workspaceManager.getCurrentContext().mode,workflow:"hybrid-creation-lazy-worktree",validation:"context_validated"})
4269
- try{const{findLargeUntrackedFiles:r,formatLargeFileWarning:n}=await Promise.resolve().then(t.t.bind(t,7478,23)),a=await r(e.basePath)
4270
- if(a.length>0){const e=n(a)
4271
- s.workspaceManager.largeFileWarning=e,i.warn("Large untracked files detected",{requestId:o,fileCount:a.length,files:a.map((e=>({path:e.path,sizeMB:e.sizeMB})))})}}catch(e){i.debug("Large file check failed",{error:e})}return a.incrementCounter(c+"_auto_context_switch_success",1),{switched:!0,branchName:s.workspaceManager.getCurrentContext().branchName,message:"Workspace ready for request "+o,lockAcquired:l,lockedRequestId:l?o:void 0}}catch(e){if(e instanceof p.RequestLockError)throw i.warn("Auto-switch blocked by request lock, re-throwing lock error",{requestId:e.requestId,lockedByAgent:e.lockedByAgent,lockedAt:e.lockedAt}),e
4272
- return i.error("Error switching to request context",{requestId:o,error:(0,g.getErrorMessage)(e)}),a.incrementCounter(c+"_auto_context_switch_error",1),{switched:!1,message:"Context switch error: "+(0,g.getErrorMessage)(e)}}}i.warn("WorkspaceManager not available, falling back to legacy branch switching",{requestId:o})
4273
- const m=await n(o,s,i,a)
4274
- if(!m.found||!m.branchName)return i.warn("No feature branch found for request during auto-switch",{requestId:o,availableBranches:m.allBranches||[]}),a.incrementCounter(c+"_auto_branch_switch_no_branch",1),{switched:!1,message:"No feature branch found for request "+o}
4275
- const y=await r(s,i,a),w=await d.switchToBranch(s.git,m.branchName,i,a)
4276
- return w.success?(s.updateBranchState&&await s.updateBranchState(m.branchName,o),i.info("Auto-switched to request branch after task promotion",{requestId:o,fromBranch:y,toBranch:m.branchName}),a.incrementCounter(c+"_auto_branch_switch_success",1),{switched:!0,branchName:m.branchName,message:"Switched to "+m.branchName}):(i.warn("Failed to auto-switch to request branch",{requestId:o,targetBranch:m.branchName,error:w.message}),a.incrementCounter(c+"_auto_branch_switch_failure",1),{switched:!1,message:"Failed to switch: "+w.message})}catch(e){if(e instanceof p.RequestLockError)throw i.warn("Auto-switch blocked by request lock in legacy mode, re-throwing lock error",{requestId:e.requestId,lockedByAgent:e.lockedByAgent,lockedAt:e.lockedAt}),e
4277
- return i.error("Error during auto-switch to request branch",{requestId:o,error:(0,g.getErrorMessage)(e)}),a.incrementCounter(c+"_auto_branch_switch_error",1),{switched:!1,message:"Error during switch: "+(0,g.getErrorMessage)(e)}}}function s(e,t,r,n){if(!e.workspaceManager)return n.debug("No workspace manager available, skipping context validation",{operation:r,requestId:t}),{isValid:!0}
4119
+ return r.warn("Failed to find feature branch for request",{requestId:e,error:s}),n.incrementCounter("find_feature_branch_failure",1),o({success:!1,error:t instanceof Error?t.name:"unknown"}),{found:!1}}}async function o(e,r,n,o,s,i){if(!r||!n.git)return{switched:!1,message:"No branch switch needed"}
4120
+ let a=!1,c=Date.now()
4121
+ try{n.syncBranchState&&await n.syncBranchState(),Date.now(),c=Date.now()
4122
+ const e=n.getCurrentBranchContext?await n.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
4123
+ if(Date.now(),e.requestId===r)return o.debug("Already in correct request context",{requestId:r,currentBranch:e.branch}),{switched:!1,branchName:e.branch||void 0,message:`Already in request ${r} context`,lockAcquired:!1}
4124
+ if(n.workspaceManager){o.debug("Using WorkspaceManager for request context switching",{requestId:r,currentMode:n.workspaceManager.getCurrentContext().mode})
4125
+ try{if("multi-agent"===n.workspaceManager.getCurrentContext().mode)if(o.debug("Multi-agent mode: checking request lock before auto-switch",{requestId:r}),n.apiClient)try{const e=n.apiClient.getRequestClient(),{sessionTag:t}=(0,h.getGlobalClientInfo)()
4126
+ c=Date.now()
4127
+ const s=await e.getRequestLockStatus(r)
4128
+ if(Date.now(),s.isLocked&&s.lockedBySessionTag!==t){o.warn("Auto-switch blocked by request lock",{requestId:r,lockedByAgent:s.lockedBySessionTag,currentAgent:t,lockedAt:s.lockedAt})
4129
+ let e=`Request ${r} is currently locked by another agent (${s.lockedBySessionTag}).\n\nLocked since: ${s.lockedAt||"unknown"}\n\nIn multi-agent mode, only one agent can work on a request at a time. Please wait for the other agent to complete their work or contact an administrator if the lock appears stale.`
4130
+ if(n.lockOverrideManager&&n.configManager)try{const t=await n.configManager.getEffectiveConfig(n.mainBasePath)
4131
+ t.lockOverride.enabled&&(e+=`\n\n**To take over this request (only if safe to do so), use switch_to_branch with password: \`${n.lockOverrideManager.generatePassword(r,t.lockOverride.passwordValidityMinutes)}\` (valid for ${t.lockOverride.passwordValidityMinutes} minutes)**`)}catch(e){o.warn("Failed to check lock override config",{error:e})}throw new p.RequestLockError(e,r,s.lockedBySessionTag,s.lockedAt)}if(!s.isLocked){c=Date.now(),o.debug("Acquiring lock for auto-switch",{requestId:r,sessionTag:t})
4132
+ const n=await e.lockRequest(r,t)
4133
+ if(Date.now(),!n.locked){const e=`Failed to acquire lock for request ${r} during auto-switch`
4134
+ throw o.warn("Auto-switch lock acquisition failed",{requestId:r}),Error(e)}o.info("Successfully acquired lock for auto-switch",{requestId:r,sessionTag:t,lockedAt:n.lockedAt}),a=!0}}catch(e){throw o.error("Lock check/acquisition failed during auto-switch",{requestId:r,error:e instanceof Error?e.message:e+""}),e}else o.warn("Multi-agent mode but no API client available for locking",{requestId:r})
4135
+ o.debug("Ensuring workspace is ready for file operations",{requestId:r,reason:"first-file-operation"}),c=Date.now(),await n.workspaceManager.ensureWorkspaceReady(r),Date.now()
4136
+ const e=n.workspaceManager.getCurrentContext()
4137
+ if(e.basePath&&(n.git=(0,u.simpleGit)(e.basePath),o.info("Updated git instance to worktree path",{requestId:r,gitWorkingDirectory:e.basePath,mode:e.mode,branchName:e.branchName})),e.requestId!==r){const t=`Workspace switch validation failed. Expected requestId: ${r}, but got: ${e.requestId}`
4138
+ throw o.error("Post-switch context validation failed",{requestId:r,expectedRequestId:r,actualRequestId:e.requestId,actualBasePath:e.basePath,mode:e.mode}),Error(t)}o.info("Workspace is ready via WorkspaceManager",{requestId:r,mode:n.workspaceManager.getCurrentContext().mode,workflow:"hybrid-creation-lazy-worktree",validation:"context_validated"})
4139
+ try{const{findLargeUntrackedFiles:s,formatLargeFileWarning:i}=await Promise.resolve().then(t.t.bind(t,7478,23)),a=await s(e.basePath)
4140
+ if(a.length>0){const e=i(a)
4141
+ n.workspaceManager.largeFileWarning=e,o.warn("Large untracked files detected",{requestId:r,fileCount:a.length,files:a.map((e=>({path:e.path,sizeMB:e.sizeMB})))})}}catch(e){o.debug("Large file check failed",{error:e})}return s.incrementCounter(i+"_auto_context_switch_success",1),{switched:!0,branchName:n.workspaceManager.getCurrentContext().branchName,message:"Workspace ready for request "+r,lockAcquired:a,lockedRequestId:a?r:void 0}}catch(e){if(e instanceof p.RequestLockError)throw o.warn("Auto-switch blocked by request lock, re-throwing lock error",{requestId:e.requestId,lockedByAgent:e.lockedByAgent,lockedAt:e.lockedAt}),e
4142
+ return o.error("Error switching to request context",{requestId:r,error:(0,g.getErrorMessage)(e)}),s.incrementCounter(i+"_auto_context_switch_error",1),{switched:!1,message:"Context switch error: "+(0,g.getErrorMessage)(e)}}}return o.error("WorkspaceManager not available - this should not happen",{requestId:r}),{switched:!1,message:"WorkspaceManager not available"}}catch(e){if(e instanceof p.RequestLockError)throw o.warn("Auto-switch blocked by request lock, re-throwing lock error",{requestId:e.requestId,lockedByAgent:e.lockedByAgent,lockedAt:e.lockedAt}),e
4143
+ return o.error("Error during auto-switch to request branch",{requestId:r,error:(0,g.getErrorMessage)(e)}),s.incrementCounter(i+"_auto_branch_switch_error",1),{switched:!1,message:"Error during switch: "+(0,g.getErrorMessage)(e)}}}function s(e,t,r,n){if(!e.workspaceManager)return n.debug("No workspace manager available, skipping context validation",{operation:r,requestId:t}),{isValid:!0}
4278
4144
  const o=e.workspaceManager.getCurrentContext()
4279
- if("multi-agent"!==o.mode)return n.debug("Single-agent mode detected, skipping multi-agent context validation",{operation:r,requestId:t,mode:o.mode}),{isValid:!0}
4280
4145
  if(!t)return n.debug("File operation without requestId in multi-agent mode",{operation:r,currentContext:o.requestId,mode:o.mode,basePath:o.basePath}),{isValid:!0}
4281
4146
  if(o.requestId!==t){const e=`Workspace context mismatch for ${r}. Expected requestId: ${t}, but current context is: ${o.requestId}. This suggests workspace switching failed or didn't occur. Current basePath: ${o.basePath}, branch: ${o.branchName}`
4282
4147
  return n.error("Workspace context validation failed - context mismatch",{operation:r,expectedRequestId:t,currentRequestId:o.requestId,currentBasePath:o.basePath,currentBranchName:o.branchName,currentIsMainBranch:o.isMainBranch,mode:o.mode,issue:"request_id_mismatch"}),{isValid:!1,errorMessage:e}}if(o.isMainBranch&&t){const e=`File operation ${r} attempted with requestId ${t} but workspace is still in main branch (${o.branchName}). This indicates workspace switching to request context failed.`
@@ -4318,8 +4183,7 @@ try{const l=(await d.getRepositoryStatus(n.git,o,s)).branches.filter((t=>t.name=
4318
4183
  if(0>=l.length)return o.debug("No feature branch found for request, staying on current branch",{requestId:e,currentBranch:a,taskId:t,filePath:r}),s.incrementCounter(i+"_branch_switch_no_feature_branch",1),{switched:!1,message:"No feature branch found for request "+e}
4319
4184
  c=l[0].name,o.debug("Found matching request branch",{requestId:e,targetBranch:c,currentBranch:a})}catch(t){return o.warn("Could not check for request branches, continuing on current branch",{requestId:e,currentBranch:a,error:(0,g.getErrorMessage)(t)}),s.incrementCounter(i+"_branch_switch_branch_check_error",1),{switched:!1}}if(a===c)return o.debug("Already on correct branch for request",{requestId:e,branchName:a,taskId:t,filePath:r}),s.incrementCounter(i+"_branch_switch_already_correct",1),{switched:!1,branchName:a,message:"Already on correct branch "+a}
4320
4185
  try{const l=await d.switchToBranch(n.git,c,o,s)
4321
- return l.success?(o.info("Switched to feature branch for file operation",{requestId:e,taskId:t,filePath:r,fromBranch:a,toBranch:c}),s.incrementCounter(i+"_branch_switch_success",1),{switched:!0,branchName:c||void 0,message:`Switched to feature branch ${c} for this operation`}):(o.warn("Failed to switch to feature branch",{requestId:e,taskId:t,filePath:r,targetBranch:c,reason:l.message}),s.incrementCounter(i+"_branch_switch_failed",1),{switched:!1,message:"Failed to switch to branch: "+l.message})}catch(n){return o.warn("Error during branch switching",{requestId:e,taskId:t,filePath:r,targetBranch:c,error:(0,g.getErrorMessage)(n)}),s.incrementCounter(i+"_branch_switch_error",1),{switched:!1,message:"Error switching branches: "+(0,g.getErrorMessage)(n)}}}catch(n){return o.warn("Overall error in ensureCorrectBranch",{requestId:e,taskId:t,filePath:r,error:(0,g.getErrorMessage)(n)}),s.incrementCounter(i+"_branch_switch_overall_error",1),{switched:!1,message:"Branch switching error: "+(0,g.getErrorMessage)(n)}}},exports.autoSwitchToRequestBranch=o,exports.determineExpectedBranch=function(e,t,r){try{if(t.multiAgentMode){if(t.currentRequestId)return r.debug("Multi-agent mode: worktree should be on correct branch",{taskId:e,requestId:t.currentRequestId}),null}else if(t.currentRequestId){const n=`feature/${t.currentRequestId}-request-${t.currentRequestId}`
4322
- return r.debug("Single-agent mode: determined expected branch",{taskId:e,requestId:t.currentRequestId,expectedBranch:n}),n}return null}catch(t){return r.warn("Failed to determine expected branch for task",{taskId:e,error:(0,g.getErrorMessage)(t)}),null}},exports.validateWorkspaceContextForFileOperation=s,exports.ensureCorrectWorkspaceContext=async function(e){const{taskPromoted:t,requestId:r,context:n,operation:i,logger:a,metrics:c,metricsPrefix:l,requireRequestContext:u=!0}=e
4186
+ return l.success?(o.info("Switched to feature branch for file operation",{requestId:e,taskId:t,filePath:r,fromBranch:a,toBranch:c}),s.incrementCounter(i+"_branch_switch_success",1),{switched:!0,branchName:c||void 0,message:`Switched to feature branch ${c} for this operation`}):(o.warn("Failed to switch to feature branch",{requestId:e,taskId:t,filePath:r,targetBranch:c,reason:l.message}),s.incrementCounter(i+"_branch_switch_failed",1),{switched:!1,message:"Failed to switch to branch: "+l.message})}catch(n){return o.warn("Error during branch switching",{requestId:e,taskId:t,filePath:r,targetBranch:c,error:(0,g.getErrorMessage)(n)}),s.incrementCounter(i+"_branch_switch_error",1),{switched:!1,message:"Error switching branches: "+(0,g.getErrorMessage)(n)}}}catch(n){return o.warn("Overall error in ensureCorrectBranch",{requestId:e,taskId:t,filePath:r,error:(0,g.getErrorMessage)(n)}),s.incrementCounter(i+"_branch_switch_overall_error",1),{switched:!1,message:"Branch switching error: "+(0,g.getErrorMessage)(n)}}},exports.autoSwitchToRequestBranch=o,exports.determineExpectedBranch=function(e,t,r){try{return t.currentRequestId?(r.debug("Worktree should be on correct branch",{taskId:e,requestId:t.currentRequestId}),null):null}catch(t){return r.warn("Failed to determine expected branch for task",{taskId:e,error:(0,g.getErrorMessage)(t)}),null}},exports.validateWorkspaceContextForFileOperation=s,exports.ensureCorrectWorkspaceContext=async function(e){const{taskPromoted:t,requestId:r,context:n,operation:i,logger:a,metrics:c,metricsPrefix:l,requireRequestContext:u=!0}=e
4323
4187
  try{const e=await o(0,r,n,a,c,l)
4324
4188
  if(e.switched&&a.info(`Auto-switched to request workspace during ${i} operation`,{requestId:r,branchName:e.branchName,message:e.message,taskPromoted:t,operation:i}),u&&r){const t=s(n,r,i,a)
4325
4189
  if(!t.isValid)return a.error("Workspace context validation failed for "+i,{requestId:r,operation:i,error:t.errorMessage}),{success:!1,switched:e.switched,branchName:e.branchName,error:t.errorMessage,lockAcquired:e.lockAcquired,lockedRequestId:e.lockedRequestId}}return a.debug("Workspace context successfully ensured for "+i,{requestId:r,operation:i,switched:e.switched,branchName:e.branchName}),{success:!0,switched:e.switched,branchName:e.branchName,lockAcquired:e.lockAcquired,lockedRequestId:e.lockedRequestId}}catch(e){const t=(0,g.getErrorMessage)(e)
@@ -4517,10 +4381,10 @@ if(s.workspaceManager){const t=s.workspaceManager.getCurrentContext()
4517
4381
  if("multi-agent"===t.mode&&t.requestId){if(!t.basePath.includes("/worktrees/")&&!t.basePath.includes("\\worktrees\\"))throw i.error("CRITICAL BUG: Multi-agent mode but basePath is not a worktree path",{taskId:e,requestId:t.requestId,basePath:t.basePath,expectedPattern:"should contain /worktrees/ or \\worktrees\\",issue:"workspace_context_incorrect"}),Error(`Multi-agent mode context error: basePath '${t.basePath}' is not a worktree path. This will cause commits to go to main branch instead of the request branch.`)
4518
4382
  f=(0,a.simpleGit)(t.basePath),i.debug("Using WorkspaceManager git instance for commit",{taskId:e,mode:t.mode,requestId:t.requestId,basePath:t.basePath,branchName:t.branchName,worktreeValidated:!0})}}if(f){i.info("commitToGit called with:",{taskId:e,recordId:r,localRecordId:n,hasLocalRecordId:!!n,localRecordIdType:typeof n,normalizedPath:t})
4519
4383
  let a=!1,m=""
4520
- try{if(m=(await f.raw(["rev-parse","--show-toplevel"])).trim(),a=m.includes("/worktrees/")||m.includes("\\worktrees\\"),i.info("Git context detection for commit operation:",{taskId:e,gitRepoPath:m,isWorktreeOperation:a,multiAgentMode:s.multiAgentMode,targetFile:t,expectedContext:s.multiAgentMode?"worktree":"main repo"}),s.multiAgentMode&&!a)throw i.error("CRITICAL: Multi-agent operation using main repo Git instead of worktree",{taskId:e,detectedPath:m,targetFile:t,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"unknown"}),Error(`Git context mismatch: Multi-agent operation attempted to commit ${t} using main repository Git instance at ${m}, but should use worktree Git instance. This will fail due to .gitignore rules.`)}catch(e){i.warn("Failed to get Git instance info:",{error:e instanceof Error?e.message:e+""})}try{const r=await f.revparse(["--abbrev-ref","HEAD"]),n=await f.revparse(["HEAD"]),o=await f.revparse(["--show-toplevel"])
4521
- i.info("Git repository status before commit:",{taskId:e,currentBranch:r.trim(),currentCommit:n.trim().substring(0,8),repoPath:o.trim(),targetFile:t,multiAgentMode:s.multiAgentMode||!1,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"none"})
4384
+ try{if(m=(await f.raw(["rev-parse","--show-toplevel"])).trim(),a=m.includes("/worktrees/")||m.includes("\\worktrees\\"),i.info("Git context detection for commit operation:",{taskId:e,gitRepoPath:m,isWorktreeOperation:a,targetFile:t,expectedContext:"worktree"}),!a)throw i.error("CRITICAL: Multi-agent operation using main repo Git instead of worktree",{taskId:e,detectedPath:m,targetFile:t,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"unknown"}),Error(`Git context mismatch: Multi-agent operation attempted to commit ${t} using main repository Git instance at ${m}, but should use worktree Git instance. This will fail due to .gitignore rules.`)}catch(e){i.warn("Failed to get Git instance info:",{error:e instanceof Error?e.message:e+""})}try{const r=await f.revparse(["--abbrev-ref","HEAD"]),n=await f.revparse(["HEAD"]),o=await f.revparse(["--show-toplevel"])
4385
+ i.info("Git repository status before commit:",{taskId:e,currentBranch:r.trim(),currentCommit:n.trim().substring(0,8),repoPath:o.trim(),targetFile:t,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"none"})
4522
4386
  const a=r.trim(),c=s.getCurrentRequestId?s.getCurrentRequestId():null
4523
- if(s.multiAgentMode&&c){const t="requests/"+c
4387
+ if(c){const t="requests/"+c
4524
4388
  a!=="requests/"+c?i.warn("Multi-agent file operation may be on wrong branch",{taskId:e,actualBranch:a,expectedPattern:t,requestId:c}):i.info("Multi-agent file operation on expected branch",{taskId:e,branchName:a,requestId:c})}}catch(e){i.warn("Failed to get Git status before commit:",{error:e instanceof Error?e.message:e+""})}try{if(f){const r=await f.revparse(["HEAD"])
4525
4389
  p=await(0,l.findPreviousCommit)(f,t,r),i.info(`Previous commit hash for ${t}: ${p||"none (new file)"}`,{taskId:e,gitInstancePath:m||"unknown",isWorktreeOperation:a,usingCorrectGitInstance:!0})}else i.warn("Git not available for previous commit detection: "+t,{taskId:e,reason:"no_git_instance"})}catch(e){i.warn(`Failed to find previous commit for ${t}:`,{error:(0,u.getErrorMessage)(e)})}const y=n?`[RECORD:${n}] ${o}`:o
4526
4390
  await f.add(t),g=(await f.commit(y)).commit
@@ -4533,25 +4397,19 @@ function t(){const e=process.argv[1]||""
4533
4397
  if(e.includes("/dist-dev/")||e.includes("\\dist-dev\\"))return!0
4534
4398
  if(e.includes("/dist/")||e.includes("\\dist\\"))return!1
4535
4399
  const t=process.cwd()
4536
- return!(!t.includes("/dist-dev")&&!t.includes("\\dist-dev"))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.isDevBuild=t,exports.getBuildMode=function(){return t()?"development":"production"},exports.enableDebugMode=function(){return"true"===process.env.ENABLE_DEBUG_TOOLS&&(process.env.DEBUG_LOGGING="true",!0)}},7976(e,exports,t){"use strict"
4537
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.getClientInfoForMetadata=function(e){let t={name:"unknown",version:"unknown"}
4538
- if(r.debug("getClientInfoForMetadata called",{mcpServerExists:!!e,mcpServerType:typeof e,hasGetClientInfo:e?typeof e.getClientInfo:void 0,mcpServerKeys:e?Object.keys(e):void 0}),e&&"function"==typeof e.getClientInfo)try{t=e.getClientInfo(),r.debug("mcpServer.getClientInfo() returned",{clientInfo:t,clientInfoType:typeof t,name:t?.name,version:t?.version})}catch(e){r.debug("mcpServer.getClientInfo() failed",{error:e})}else r.debug("mcpServer not available or getClientInfo not a function")
4539
- const n={clientName:t.name,clientVersion:t.version}
4540
- return r.debug("getClientInfoForMetadata returning",{result:n}),n}
4541
- const r=t(3444).defaultLogger.child({component:"client-info-utils"})},8035(e,exports,t){"use strict"
4542
- function r(e,t,r){try{const n=`[${(new Date).toISOString()}] [detached-subagent] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,a.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,i.appendFileSync)(o,n)}catch{}}function n(e){const{agent:t,prompt:n,cwd:l,parentServerUrl:u,parentSessionId:d,sessionId:h,model:g,initialBranch:p,serverUrl:f,onSpawn:m,onError:y}=e
4543
- try{const s={...process.env}
4544
- u&&(s.OPENCODE_PARENT_SERVER=u),p&&(s.ALCHEMY_INITIAL_BRANCH=p),e.allowParallel&&(s.ALCHEMY_ALLOW_PARALLEL="1")
4545
- const d=new Date,y=`${(d.getHours()+"").padStart(2,"0")}${(d.getMinutes()+"").padStart(2,"0")}${(d.getSeconds()+"").padStart(2,"0")}`,w=Math.random().toString(36).substring(2,7)
4400
+ return!(!t.includes("/dist-dev")&&!t.includes("\\dist-dev"))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.isDevBuild=t,exports.getBuildMode=function(){return t()?"development":"production"},exports.enableDebugMode=function(){return"true"===process.env.ENABLE_DEBUG_TOOLS&&(process.env.DEBUG_LOGGING="true",!0)}},8035(e,exports,t){"use strict"
4401
+ function r(e,t,r){try{const n=`[${(new Date).toISOString()}] [detached-subagent] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,i.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,s.appendFileSync)(o,n)}catch{}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=function(e){const{agent:t,prompt:c,cwd:l,sessionId:u,model:d,initialBranch:h,serverUrl:g,onSpawn:p}=e
4402
+ try{const o={...process.env},f=l||process.cwd()
4403
+ o.OPENCODE_DATA_DIR=(0,i.join)(f,".alchemy_lab","opencode"),h&&(o.ALCHEMY_INITIAL_BRANCH=h),e.allowParallel&&(o.ALCHEMY_ALLOW_PARALLEL="1")
4404
+ const m=new Date,y=`${(m.getHours()+"").padStart(2,"0")}${(m.getMinutes()+"").padStart(2,"0")}${(m.getSeconds()+"").padStart(2,"0")}`,w=Math.random().toString(36).substring(2,7)
4546
4405
  let k
4547
- if(s.ALCHEMY_SESSION_TAG=`mcp-${y}-${w}`,r(l,"Spawn env setup",{agent:t,initialBranch:p||"none",hasParentServer:!!u,sessionId:h||"new",attachMode:!!f}),k=f&&h&&n?["run","--attach",f,"--session",h,"--agent",t,n]:h&&n?["run","--session",h,"--agent",t,n]:n?["run","--agent",t,n]:["run","--agent",t],g){const e=k.findIndex((e=>e===n))
4548
- e>0?k.splice(e,0,"--model",g):k.push("--model",g)}r(l,"Spawning opencode",{args:k.map((e=>e===n?`[prompt:${e.length}chars]`:e)),model:g||"not specified",promptLength:n?.length,promptPreview:n?.slice(0,100),cwd:l,hasSessionId:!!h,hasParentServerUrl:!!u})
4549
- const b=(0,a.join)(l||process.cwd(),".alchemy_lab"),I=(0,a.join)(b,"spawn-stderr.log")
4406
+ if(o.ALCHEMY_SESSION_TAG=`mcp-${y}-${w}`,r(l,"Spawn env setup",{agent:t,initialBranch:h||"none",sessionId:u||"new",attachMode:!!g}),k=g&&u&&c?["run","--attach",g,"--session",u,"--agent",t,c]:u&&c?["run","--session",u,"--agent",t,c]:c?["run","--agent",t,c]:["run","--agent",t],d){const e=k.findIndex((e=>e===c))
4407
+ e>0?k.splice(e,0,"--model",d):k.push("--model",d)}r(l,"Spawning opencode",{args:k.map((e=>e===c?`[prompt:${e.length}chars]`:e)),model:d||"not specified",promptLength:c?.length,promptPreview:c?.slice(0,100),cwd:l,hasSessionId:!!u})
4408
+ const b=(0,i.join)(l||process.cwd(),".alchemy_lab"),I=(0,i.join)(b,"spawn-stderr.log")
4550
4409
  let v
4551
- try{v=(0,i.openSync)(I,"a")}catch{}const C=(0,c.resolveRunCommand)(),_=(0,o.spawn)(C.command,[...C.prependArgs,...k],{detached:!0,stdio:["ignore","ignore",v??"ignore"],cwd:l||process.cwd(),env:s})
4552
- return _.unref(),m&&m(_.pid),{success:!0,pid:_.pid}}catch(e){const t=(0,s.getErrorMessage)(e)
4553
- return y&&e instanceof Error&&y(e),{success:!1,error:t}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=n,exports.spawnJournalSubagent=function(e,t,r,o){return n({agent:"journal",prompt:`Generate a journal entry for request ${e}.\n\nSteps:\n1. Use ${t}__generate_request_journal tool with requestId: ${e}\n2. Write a concise narrative journal entry based on the returned data covering:\n - What was implemented and why\n - Key decisions and trade-offs made\n - Challenges encountered and solutions\n - Files modified and their purposes\n - How acceptance criteria were met\n3. Save as JOURNAL-${e}.md using ${t}__document_operations (operation: create, type: Report)\n\nKeep it story-focused and informative.`,cwd:r,parentServerUrl:o})},exports.spawnWorkSubagent=function(e,t,r){return n({agent:"work",prompt:e,cwd:t,parentServerUrl:r})}
4554
- const o=t(5317),s=t(8824),i=t(9896),a=t(6928),c=t(9068)},8037(e,exports,t){"use strict"
4410
+ try{v=(0,s.openSync)(I,"a")}catch{}const C=(0,a.resolveRunCommand)(),_=(0,n.spawn)(C.command,[...C.prependArgs,...k],{detached:!0,stdio:["ignore","ignore",v??"ignore"],cwd:l||process.cwd(),env:o})
4411
+ return _.unref(),p&&p(_.pid),{success:!0,pid:_.pid}}catch(e){return{success:!1,error:(0,o.getErrorMessage)(e)}}}
4412
+ const n=t(5317),o=t(8824),s=t(9896),i=t(6928),a=t(9068)},8037(e,exports,t){"use strict"
4555
4413
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListRequests=async function(e,t,i,a,c){const l=a.child({tool:"list_requests"}),u=c.startTimer("tool_execution_time")
4556
4414
  try{const{filters:s={}}=e,a=["open","in_progress","ready_for_review","completed","canceled","reverted"]
4557
4415
  if(s.status&&!a.includes(s.status))throw new r.ValidationError(`Invalid status: ${s.status}. Must be one of: ${a.join(", ")}`)
@@ -4566,17 +4424,15 @@ const h=i.getRequestClient(),g=await h.listRequests(d)
4566
4424
  if(l.debug("=== RAW SERVER RESPONSE DEBUG ===",{responseType:typeof g,isArray:Array.isArray(g),responseKeys:g?Object.keys(g):[],fullResponse:JSON.stringify(g,null,2)}),g&&"object"==typeof g&&"data"in g){const e=g.data
4567
4425
  l.debug("=== SERVER RESPONSE DATA SECTION ===",{dataType:typeof e,isDataArray:Array.isArray(e),dataLength:Array.isArray(e)?e.length:"not array",firstItemKeys:Array.isArray(e)&&e.length>0?Object.keys(e[0]):"no items",firstItemSample:Array.isArray(e)&&e.length>0?JSON.stringify(e[0],null,2):"no items"}),Array.isArray(e)&&e.length>0&&e.slice(0,3).forEach(((e,t)=>{l.info(`=== ITEM ${t+1} LOCK INFO CHECK ===`,{id:e.id,hasLockInfo:"lockInfo"in e,lockInfoValue:e.lockInfo,allKeys:Object.keys(e),lockRelatedKeys:Object.keys(e).filter((e=>e.toLowerCase().includes("lock")))})}))}l.debug("Raw requests response data",{responseData:JSON.stringify(g)}),l.debug("Requests response structure",{type:typeof g,isArray:Array.isArray(g),hasData:null!=g,properties:g?Object.keys(g):[],dataPreview:g?JSON.stringify(g).substring(0,200)+"...":"null"}),l.debug("=== BEFORE EXTRACTION ===",{responseHasData:g&&"data"in g,responseDataLength:g&&"data"in g&&Array.isArray(g.data)?g.data.length:"not array",firstItemBeforeExtraction:g&&"data"in g&&Array.isArray(g.data)&&g.data.length>0?{id:g.data[0].id,hasLockInfo:"lockInfo"in g.data[0],lockInfo:g.data[0].lockInfo,allKeys:Object.keys(g.data[0])}:"no data"})
4568
4426
  const p=(0,n.extractArrayFromResponse)(g,{logger:l,operationName:"listRequests",defaultValue:[]})
4569
- l.info("=== AFTER EXTRACTION ===",{extractedCount:p.length,firstItemAfterExtraction:p.length>0?{id:p[0].id,hasLockInfo:"lockInfo"in p[0],lockInfo:p[0].lockInfo,allKeys:Object.keys(p[0])}:"no items"}),l.info(`Extracted ${p.length} requests from response`)
4570
- const f=t.multiAgentMode||!1
4571
- if(l.debug("Lock info analysis",{multiAgentModeEnabled:f,requestCount:p.length,environmentVariable:process.env.ALCHEMY_MULTI_AGENT,firstRequestSample:p.length>0?{id:p[0].id,hasLockInfo:!!p[0].lockInfo,lockInfo:p[0].lockInfo,allProperties:Object.keys(p[0])}:"No requests to sample"}),p.length>0&&p.forEach(((e,t)=>{l.debug(`Request ${t+1} lock debug`,{id:e.id,title:e.title?.substring(0,50)+"...",hasLockInfo:!!e.lockInfo,lockInfoDetails:e.lockInfo||"NO LOCK INFO",allKeys:Object.keys(e).filter((e=>e.includes("lock")||e.includes("Lock")))})})),0===p.length)return u({success:!0,requestCount:0}),{content:[{type:"text",text:"No requests found with the specified filters."}]}
4572
- l.info("=== PRE-DISPLAY REQUEST ANALYSIS ===",{totalRequests:p.length,multiAgentMode:f,environmentVar:process.env.ALCHEMY_MULTI_AGENT}),p.forEach(((e,t)=>{l.info(`=== REQUEST ${t+1}/${p.length} PRE-DISPLAY ANALYSIS ===`,{id:e.id,title:e.title?.substring(0,30)+"...",hasLockInfo:"lockInfo"in e,lockInfoType:typeof e.lockInfo,lockInfoValue:e.lockInfo,lockInfoIsNull:null===e.lockInfo,lockInfoIsUndefined:void 0===e.lockInfo,allProperties:Object.keys(e),lockRelatedProperties:Object.keys(e).filter((e=>e.toLowerCase().includes("lock")||e.toLowerCase().includes("session")||e.toLowerCase().includes("expire")))}),e.lockInfo&&l.info(`=== REQUEST ${e.id} LOCK INFO DEEP DIVE ===`,{lockInfoKeys:Object.keys(e.lockInfo),isLocked:e.lockInfo.isLocked,lockedBySessionTag:e.lockInfo.lockedBySessionTag,timeRemainingFormatted:e.lockInfo.timeRemainingFormatted,isExpired:e.lockInfo.isExpired,fullLockInfo:JSON.stringify(e.lockInfo,null,2)})}))
4573
- const m=p.map((e=>{let t=""
4574
- if(l.info(`=== FORMATTING REQUEST ${e.id} ===`,{multiAgentMode:f,hasLockInfo:!!e.lockInfo,lockInfoValue:e.lockInfo,willShowLockInfo:!!e.lockInfo,note:"Lock info displayed when available regardless of mode"}),e.lockInfo){if(l.debug(`Processing lock info for ${e.id}:`,e.lockInfo),e.lockInfo.isLocked&&!e.lockInfo.isExpired){const{sessionTag:r}=(0,o.getGlobalClientInfo)(),n=e.lockInfo.lockedBySessionTag||"unknown"
4427
+ if(l.info("=== AFTER EXTRACTION ===",{extractedCount:p.length,firstItemAfterExtraction:p.length>0?{id:p[0].id,hasLockInfo:"lockInfo"in p[0],lockInfo:p[0].lockInfo,allKeys:Object.keys(p[0])}:"no items"}),l.info(`Extracted ${p.length} requests from response`),l.debug("Lock info analysis",{requestCount:p.length,firstRequestSample:p.length>0?{id:p[0].id,hasLockInfo:!!p[0].lockInfo,lockInfo:p[0].lockInfo,allProperties:Object.keys(p[0])}:"No requests to sample"}),p.length>0&&p.forEach(((e,t)=>{l.debug(`Request ${t+1} lock debug`,{id:e.id,title:e.title?.substring(0,50)+"...",hasLockInfo:!!e.lockInfo,lockInfoDetails:e.lockInfo||"NO LOCK INFO",allKeys:Object.keys(e).filter((e=>e.includes("lock")||e.includes("Lock")))})})),0===p.length)return u({success:!0,requestCount:0}),{content:[{type:"text",text:"No requests found with the specified filters."}]}
4428
+ l.info("=== PRE-DISPLAY REQUEST ANALYSIS ===",{totalRequests:p.length}),p.forEach(((e,t)=>{l.info(`=== REQUEST ${t+1}/${p.length} PRE-DISPLAY ANALYSIS ===`,{id:e.id,title:e.title?.substring(0,30)+"...",hasLockInfo:"lockInfo"in e,lockInfoType:typeof e.lockInfo,lockInfoValue:e.lockInfo,lockInfoIsNull:null===e.lockInfo,lockInfoIsUndefined:void 0===e.lockInfo,allProperties:Object.keys(e),lockRelatedProperties:Object.keys(e).filter((e=>e.toLowerCase().includes("lock")||e.toLowerCase().includes("session")||e.toLowerCase().includes("expire")))}),e.lockInfo&&l.info(`=== REQUEST ${e.id} LOCK INFO DEEP DIVE ===`,{lockInfoKeys:Object.keys(e.lockInfo),isLocked:e.lockInfo.isLocked,lockedBySessionTag:e.lockInfo.lockedBySessionTag,timeRemainingFormatted:e.lockInfo.timeRemainingFormatted,isExpired:e.lockInfo.isExpired,fullLockInfo:JSON.stringify(e.lockInfo,null,2)})}))
4429
+ const f=p.map((e=>{let t=""
4430
+ if(l.info(`=== FORMATTING REQUEST ${e.id} ===`,{hasLockInfo:!!e.lockInfo,lockInfoValue:e.lockInfo,willShowLockInfo:!!e.lockInfo,note:"Lock info displayed when available regardless of mode"}),e.lockInfo){if(l.debug(`Processing lock info for ${e.id}:`,e.lockInfo),e.lockInfo.isLocked&&!e.lockInfo.isExpired){const{sessionTag:r}=(0,o.getGlobalClientInfo)(),n=e.lockInfo.lockedBySessionTag||"unknown"
4575
4431
  t=n===r?` [LOCKED by me, expires in ${e.lockInfo.timeRemainingFormatted}]`:` [LOCKED by ${n.length>20?n.substring(0,17)+"...":n}, expires in ${e.lockInfo.timeRemainingFormatted}]`}else t=" [AVAILABLE]"
4576
4432
  l.debug(`Generated lock info for ${e.id}: "${t}"`)}else l.debug("No lock info available for "+e.id)
4577
- return`**${e.title}** (${e.id}) [${e.type}]${t}\nStatus: ${e.status}\nType: ${e.type}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}\n`})).join("\n---\n"),y=p.some((e=>e.lockInfo))
4578
- let w=`Found ${p.length} request${1===p.length?"":"s"}:`
4579
- return y&&f&&(w+="\n\n**Lock Status:**\n",w+="LOCKED = Locked by an agent (shows session name and expiration)\n",w+="AVAILABLE = Not currently locked, safe to work on\n"),u({success:!0,requestCount:p.length}),{content:[{type:"text",text:`${w}\n\n${m}`}]}}catch(t){return l.error("Error listing requests",{args:e,error:t instanceof Error?t.stack:t+""}),u({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:"Error listing requests: "+(0,s.getErrorMessage)(t)}],isError:!0}}}
4433
+ return`**${e.title}** (${e.id}) [${e.type}]${t}\nStatus: ${e.status}\nType: ${e.type}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}\n`})).join("\n---\n"),m=p.some((e=>e.lockInfo))
4434
+ let y=`Found ${p.length} request${1===p.length?"":"s"}:`
4435
+ return m&&(y+="\n\n**Lock Status:**\n",y+="LOCKED = Locked by an agent (shows session name and expiration)\n",y+="AVAILABLE = Not currently locked, safe to work on\n"),u({success:!0,requestCount:p.length}),{content:[{type:"text",text:`${y}\n\n${f}`}]}}catch(t){return l.error("Error listing requests",{args:e,error:t instanceof Error?t.stack:t+""}),u({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:"Error listing requests: "+(0,s.getErrorMessage)(t)}],isError:!0}}}
4580
4436
  const r=t(9860),n=t(2960),o=t(5172),s=t(8824)},8045(e,exports,t){"use strict"
4581
4437
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
4582
4438
  const r=t(6183),n=t(7456)
@@ -4619,14 +4475,14 @@ const S=await u.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,reque
4619
4475
  if(!S.success){if(S.isLockConflict)return{content:[{type:"text",text:"\u274c "+S.error}],isError:!0}
4620
4476
  throw Error(S.error)}let T=!1
4621
4477
  try{T=(await a.default.stat(v)).isDirectory()}catch{T=!1}k=u.FileOperationPhase.RECORD_CREATION,i.incrementCounter("create_directory_phase",1,{phase:k})
4622
- const{toolRecordId:M,localToolRecordId:R}=await u.createFileOperationRecords(d,_,t.projectId,b.recordType,I,{directoryExists:T,userComment:g},r,n,f,i,b.metricsPrefix,p)
4623
- y=M,w=M,k=b.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:k})
4624
- let P=T
4478
+ const{toolRecordId:R,localToolRecordId:P}=await u.createFileOperationRecords(d,_,t.projectId,b.recordType,I,{directoryExists:T,userComment:g},r,n,f,i,b.metricsPrefix,p)
4479
+ y=R,w=R,k=b.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:k})
4480
+ let M=T
4625
4481
  if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+I)
4626
4482
  try{const e=c.default.join(v,".gitkeep")
4627
- await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),P=!0,f.info("Created .gitkeep file for Git tracking")}catch(e){f.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),P=!1}}const x=Date.now()-m
4483
+ await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),M=!0,f.info("Created .gitkeep file for Git tracking")}catch(e){f.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),M=!1}}const x=Date.now()-m
4628
4484
  i.recordValue("create_directory_time",x),i.incrementCounter("create_directory_success",1),k=u.FileOperationPhase.GIT_COMMIT,i.incrementCounter("create_directory_phase",1,{phase:k})
4629
- const O=`Create directory: ${I} - ${g||"Create directory"}`,j=!T&&P?I+"/.gitkeep":I,$=await u.commitToGit(d,j,M,R,O,t,f,i,b.metricsPrefix)
4485
+ const j=`Create directory: ${I} - ${g||"Create directory"}`,O=!T&&M?I+"/.gitkeep":I,$=await u.commitToGit(d,O,R,P,j,t,f,i,b.metricsPrefix)
4630
4486
  k=u.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:k}),await u.updateFileOperationRecords(d,y,w,I,b.recordType,`Successfully ${T?"verified":"created"} directory: ${I}`,{status:"completed",commitHash:$.commitHash,previousCommitHash:$.previousCommitHash,directoryExists:T,isDirectory:!0,userComment:g},`Successfully ${T?"verified":"created"} directory: ${I}`,r,n,f,i,b.metricsPrefix)
4631
4487
  const D=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
4632
4488
  return{content:[{type:"text",text:T?"Directory already exists":`Successfully created directory${$.commitHash?"\nCommit: "+$.commitHash.substring(0,8):""}${D.requestId?"\nBranch: "+D.requestId:""}${S.lockAcquired&&S.lockedRequestId?"\n\u{1f512} **Locked request:** "+S.lockedRequestId:""}`}]}}catch(o){if(e.taskId&&n)try{const r=o instanceof d.NotFoundError||o instanceof d.ValidationError||o instanceof h.ZodError
@@ -4706,31 +4562,25 @@ let o=`## Plans (${r.length})\n\n`
4706
4562
  for(const e of r){const t=e.localId||e.id,r=new Date(e.updatedAt).toLocaleString(),n=e.content?e.content.substring(0,120).replace(/\n/g," ").trim()+(e.content.length>120?"...":""):""
4707
4563
  o+=`**${t}** \u2014 ${e.filename}\n`,o+=` Updated: ${r}\n`,n&&(o+=` ${n}\n`),o+="\n"}return{content:[{type:"text",text:o}]}}catch(e){return s.error("Failed to list plans",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to list plans:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
4708
4564
  const r=t(8824)},8411(e,exports,t){"use strict"
4709
- function r(e){if(!a.default.existsSync(e))return null
4710
- try{const t=a.default.readFileSync(e,"utf8").trim()
4565
+ function r(e,t,r,o){try{const i={mode:"multi-agent",created:o,hostname:a.default.hostname()}
4566
+ s.default.writeFileSync(e,JSON.stringify(i,null,2))
4567
+ const c={count:1,processes:[{pid:r,started:o}]}
4568
+ return s.default.writeFileSync(t,JSON.stringify(c,null,2)),n(e,t,r),h.info("Created new lock",{mode:i.mode,pid:r}),!0}catch(e){return h.error("Error creating new lock",{error:(0,u.getErrorMessage)(e)}),!1}}function n(e,t,r){["SIGINT","SIGTERM","exit"].forEach((n=>{process.on(n,(()=>{try{if(s.default.existsSync(t)){const o=s.default.readFileSync(t,"utf8"),i=JSON.parse(o)
4569
+ i.processes=i.processes.filter((e=>e.pid!==r)),i.count=i.processes.length,i.count>0?(s.default.writeFileSync(t,JSON.stringify(i,null,2)),h.debug("Removed process from multi-agent references",{signal:n,pid:r,remaining:i.count})):(s.default.unlinkSync(t),s.default.existsSync(e)&&s.default.unlinkSync(e),h.debug("Removed multi-agent lock files (last process)",{signal:n,pid:r}))}}catch(e){h.error("Error removing multi-agent lock files",{error:e instanceof Error?e.message:e+"",signal:n})}"exit"!==n&&process.exit(0)}))}))}var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
4570
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.acquireProcessLock=function(e){const t=i.default.join(e,c.ALCHEMY_DIR_NAME)
4571
+ let o,l
4572
+ try{s.default.existsSync(t)||(s.default.mkdirSync(t,{recursive:!0}),h.debug(`Created ${c.ALCHEMY_DIR_NAME} directory for lock file`,{alchemyLabDir:t})),o=i.default.join(t,".mcp-server.lock"),l=i.default.join(t,".mcp-agents.refs"),h.debug(`Using ${c.ALCHEMY_DIR_NAME} directory for lock files`,{lockFilePath:o,refsFilePath:l})}catch(r){h.error(`Failed to create ${c.ALCHEMY_DIR_NAME} directory`,{alchemyLabDir:t,error:r instanceof Error?r.message:r+""}),o=i.default.join(e,".mcp-server.lock"),l=i.default.join(e,".mcp-agents.refs"),h.warn("Falling back to base directory for lock files",{lockFilePath:o,refsFilePath:l})}const g=process.pid,p=(new Date).toISOString()
4573
+ try{const e=function(e){if(!s.default.existsSync(e))return null
4574
+ try{const t=s.default.readFileSync(e,"utf8").trim()
4711
4575
  try{const e=JSON.parse(t)
4712
- return p.debug("Read JSON lock data",e),e}catch{const e=parseInt(t,10)
4713
- if(isNaN(e))return p.warn("Invalid lock file content",{content:t}),null
4714
- const r={mode:"single-agent",created:(new Date).toISOString(),hostname:"unknown",pid:e}
4715
- return p.debug("Read legacy PID lock data",r),r}}catch(e){return p.error("Error reading lock file",{error:(0,h.getErrorMessage)(e)}),null}}function n(e){try{return process.kill(e,0),!0}catch{return!1}}function o(e,t,n,o,i){try{const c={mode:i?"multi-agent":"single-agent",created:o,hostname:l.default.hostname(),...i?{}:{pid:n}}
4716
- if(a.default.writeFileSync(e,JSON.stringify(c,null,2)),i){const r={count:1,processes:[{pid:n,started:o}]}
4717
- a.default.writeFileSync(t,JSON.stringify(r,null,2)),s(e,t,n)}else!function(e,t){["SIGINT","SIGTERM","exit"].forEach((n=>{process.on(n,(()=>{try{if(a.default.existsSync(e)){const o=r(e)
4718
- o&&o.pid===t&&(a.default.unlinkSync(e),p.debug("Removed single-agent lock file",{signal:n,pid:t}))}}catch(e){p.error("Error removing single-agent lock file",{error:e instanceof Error?e.message:e+"",signal:n})}"exit"!==n&&process.exit(0)}))}))}(e,n)
4719
- return p.info("Created new lock",{mode:c.mode,pid:n}),!0}catch(e){return p.error("Error creating new lock",{error:(0,h.getErrorMessage)(e)}),!1}}function s(e,t,r){["SIGINT","SIGTERM","exit"].forEach((n=>{process.on(n,(()=>{try{if(a.default.existsSync(t)){const o=a.default.readFileSync(t,"utf8"),s=JSON.parse(o)
4720
- s.processes=s.processes.filter((e=>e.pid!==r)),s.count=s.processes.length,s.count>0?(a.default.writeFileSync(t,JSON.stringify(s,null,2)),p.debug("Removed process from multi-agent references",{signal:n,pid:r,remaining:s.count})):(a.default.unlinkSync(t),a.default.existsSync(e)&&a.default.unlinkSync(e),p.debug("Removed multi-agent lock files (last process)",{signal:n,pid:r}))}}catch(e){p.error("Error removing multi-agent lock files",{error:e instanceof Error?e.message:e+"",signal:n})}"exit"!==n&&process.exit(0)}))}))}var i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
4721
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.acquireProcessLock=function(e,t=!1){const i=c.default.join(e,u.ALCHEMY_DIR_NAME)
4722
- let d,f
4723
- try{a.default.existsSync(i)||(a.default.mkdirSync(i,{recursive:!0}),p.debug(`Created ${u.ALCHEMY_DIR_NAME} directory for lock file`,{alchemyLabDir:i})),d=c.default.join(i,".mcp-server.lock"),f=c.default.join(i,".mcp-agents.refs"),p.debug(`Using ${u.ALCHEMY_DIR_NAME} directory for lock files`,{lockFilePath:d,refsFilePath:f})}catch(t){p.error(`Failed to create ${u.ALCHEMY_DIR_NAME} directory`,{alchemyLabDir:i,error:t instanceof Error?t.message:t+""}),d=c.default.join(e,".mcp-server.lock"),f=c.default.join(e,".mcp-agents.refs"),p.warn("Falling back to base directory for lock files",{lockFilePath:d,refsFilePath:f})}const m=process.pid,y=(new Date).toISOString()
4724
- try{const e=r(d)
4725
- if(p.info("Lock acquisition attempt",{pid:m,multiAgentMode:t,lockFilePath:d,lockExists:!!e,lockData:e?{mode:e.mode,pid:e.pid,hostname:e.hostname,created:e.created}:null}),!e)return p.info("No existing lock - creating new lock",{pid:m,mode:t?"multi-agent":"single-agent"}),o(d,f,m,y,t)
4726
- {const r=Date.now()-new Date(e.created).getTime(),i=r>g,c=l.default.hostname(),u=e.hostname!==c&&"unknown"!==e.hostname
4727
- if(i)return p.warn("\u26a0\ufe0f Clearing stale lock (older than 24 hours)",{lockAge:Math.round(r/1e3/60/60)+" hours",lockCreated:e.created,lockHostname:e.hostname}),o(d,f,m,y,t)
4728
- if(u)return p.warn("\u26a0\ufe0f Clearing lock from different machine",{lockHostname:e.hostname,currentHostname:c}),o(d,f,m,y,t)
4729
- if("single-agent"===e.mode)return e.pid===m?(p.debug("Same process already has lock",{pid:m}),!0):n(e.pid)?(p.warn("Cannot acquire lock - single-agent mode active",{existingPid:e.pid,currentPid:m,requestedMode:t?"multi-agent":"single-agent"}),!1):(p.info("Taking over lock from dead single-agent process",{deadPid:e.pid,currentPid:m,newMode:t?"multi-agent":"single-agent"}),o(d,f,m,y,t))
4730
- if("multi-agent"===e.mode)return t?function(e,t,r){try{let o={count:0,processes:[]}
4731
- if(a.default.existsSync(e)){const t=a.default.readFileSync(e,"utf8")
4732
- o=JSON.parse(t),o.processes=o.processes.filter((e=>n(e.pid))),o.count=o.processes.length}return o.processes.push({pid:t,started:r}),o.count=o.processes.length,a.default.writeFileSync(e,JSON.stringify(o,null,2)),s(e.replace(".mcp-agents.refs",".mcp-server.lock"),e,t),p.info("Joined multi-agent lock",{pid:t,totalAgents:o.count}),!0}catch(e){return p.error("Error joining multi-agent lock",{error:(0,h.getErrorMessage)(e)}),!1}}(f,m,y):(p.warn("Cannot acquire lock - multi-agent mode active",{currentPid:m,requestedMode:"single-agent"}),!1)}return!1}catch(e){return p.error("Error acquiring lock",{error:(0,h.getErrorMessage)(e),pid:m}),!1}}
4733
- const a=i(t(9896)),c=i(t(6928)),l=i(t(857)),u=t(4139),d=t(3444),h=t(8824),g=864e5,p=(0,d.createLogger)({serviceName:"process-lock",level:d.LogLevel.DEBUG,logToFile:!1})},8451(e,exports,t){"use strict"
4576
+ return h.debug("Read JSON lock data",e),e}catch{if(isNaN(parseInt(t,10)))return h.warn("Invalid lock file content",{content:t}),null
4577
+ const e={mode:"multi-agent",created:(new Date).toISOString(),hostname:"unknown"}
4578
+ return h.debug("Read legacy PID lock data",e),e}}catch(e){return h.error("Error reading lock file",{error:(0,u.getErrorMessage)(e)}),null}}(o)
4579
+ if(h.info("Lock acquisition attempt",{pid:g,lockFilePath:o,lockExists:!!e,lockData:e?{mode:e.mode,hostname:e.hostname,created:e.created}:null}),e){const t=Date.now()-new Date(e.created).getTime(),i=t>d,c=a.default.hostname(),f=e.hostname!==c&&"unknown"!==e.hostname
4580
+ return i?(h.warn("\u26a0\ufe0f Clearing stale lock (older than 24 hours)",{lockAge:Math.round(t/1e3/60/60)+" hours",lockCreated:e.created,lockHostname:e.hostname}),r(o,l,g,p)):f?(h.warn("\u26a0\ufe0f Clearing lock from different machine",{lockHostname:e.hostname,currentHostname:c}),r(o,l,g,p)):"multi-agent"===e.mode?function(e,t,r){try{let o={count:0,processes:[]}
4581
+ if(s.default.existsSync(e)){const t=s.default.readFileSync(e,"utf8")
4582
+ o=JSON.parse(t),o.processes=o.processes.filter((e=>function(e){try{return process.kill(e,0),!0}catch{return!1}}(e.pid))),o.count=o.processes.length}return o.processes.push({pid:t,started:r}),o.count=o.processes.length,s.default.writeFileSync(e,JSON.stringify(o,null,2)),n(e.replace(".mcp-agents.refs",".mcp-server.lock"),e,t),h.info("Joined multi-agent lock",{pid:t,totalAgents:o.count}),!0}catch(e){return h.error("Error joining multi-agent lock",{error:(0,u.getErrorMessage)(e)}),!1}}(l,g,p):(h.info("Taking over legacy lock",{currentPid:g,oldMode:e.mode}),r(o,l,g,p))}return h.info("No existing lock - creating new lock",{pid:g,mode:"multi-agent"}),r(o,l,g,p)}catch(e){return h.error("Error acquiring lock",{error:(0,u.getErrorMessage)(e),pid:g}),!1}}
4583
+ const s=o(t(9896)),i=o(t(6928)),a=o(t(857)),c=t(4139),l=t(3444),u=t(8824),d=864e5,h=(0,l.createLogger)({serviceName:"process-lock",level:l.LogLevel.DEBUG,logToFile:!1})},8451(e,exports,t){"use strict"
4734
4584
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatFileSize=function(e){return 1024>e?e+" bytes":1048576>e?(e/1024).toFixed(2)+" KB":1073741824>e?(e/1048576).toFixed(2)+" MB":(e/1073741824).toFixed(2)+" GB"},exports.truncate=function(e,t){return e.length>t?e.substring(0,t-3)+"...":e},exports.escapeRegExp=function(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},exports.countOccurrences=function(e,t){if(0===t.length)return 0
4735
4585
  let r=0,n=0
4736
4586
  for(;n=e.indexOf(t,n),-1!==n;)r++,n+=t.length
@@ -4912,62 +4762,13 @@ const r=await e.proxyGet("/api/agents/templates")
4912
4762
  r&&Array.isArray(r)&&r.length>0?(s=r.map((e=>({id:e.id||e.name,name:e.name,description:e.description,mode:e.mode,builtIn:e.builtIn}))),t.info("Agent registry initialized",{agentCount:s.length})):(t.warn("No agents returned from API, using defaults"),s=n),i=!0}catch(e){t.warn("Failed to fetch agents from API, using defaults",{error:e instanceof Error?e.message:e+""}),s=n,i=!0}})(),a)},exports.getAvailableAgents=t,exports.getAgentNames=r,exports.isValidAgent=function(e){return r().includes(e)},exports.getDefaultAgent=function(){return"work"},exports.formatAgentsForDescription=function(){return t().map((e=>`'${e.name}'${e.description?" - "+e.description:""}`)).join(", ")},exports.isAgentRegistryInitialized=function(){return i},exports.getBuiltInAgentConfig=function(e){const t=n.find((t=>t.name===e))
4913
4763
  return t?{preferredProvider:t.preferredProvider||"inherit",preferredModelTier:t.preferredModelTier||"same",requestContextMode:t.requestContextMode}:null},exports.getAllowedSubagents=function(e){return o[e]||null},exports.resetAgentRegistry=function(){s=null,i=!1,a=null}
4914
4764
  const n=[{id:"coder",name:"coder",description:"Development and implementation agent",builtIn:!0,preferredModelTier:"same",requestContextMode:"required"},{id:"research",name:"research",description:"Codebase research and exploration agent",builtIn:!0,preferredModelTier:"two_down",requestContextMode:"none"},{id:"journal",name:"journal",description:"Journal generation agent",builtIn:!0,preferredModelTier:"one_down"},{id:"planner",name:"planner",description:"Planning and architecture agent",builtIn:!0,preferredModelTier:"same"},{id:"specialist",name:"specialist",description:"Domain specialist for development tasks",builtIn:!0,preferredModelTier:"same"},{id:"auto-planner",name:"auto-planner",description:"Autonomous background planner",builtIn:!0,preferredModelTier:"same"},{id:"alchemist",name:"alchemist",description:"Persistent orchestrator",builtIn:!0,preferredModelTier:"same"}],o={alchemist:["specialist","research","planner"],specialist:["coder","research","auto-planner","planner"],tester:["research"],"auto-tester":["research"]}
4915
- let s=null,i=!1,a=null},9013(e,exports,t){"use strict"
4916
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.BranchGitAdapter=void 0
4917
- const r=t(7225),n=t(7075),o=t(7478),s=t(8824)
4918
- exports.BranchGitAdapter=class{constructor(e,t,n,o,s){this.basePath=e,this.git=t,this.conflictDetector=n,this.logger=o,this.metrics=s,this.mode="single-agent",this.currentRequestId=null,this.currentBranch="main",this.branchManager=(0,r.createSharedBranchManager)(t,o,s)}async setupWorkspace(e){const t=Date.now()
4919
- try{const r=n.WorkspaceValidation.validateRequestId(e)
4920
- if(!r.isValid){const t="Invalid request ID: "+r.errors.join(", ")
4921
- throw n.WorkspaceLogging.logOperation(this.logger,"error",t,e,"single-agent","setupWorkspace"),Error(t)}const o=r.sanitized,s=this.branchManager.generateRequestBranchName(o),i=await this.branchManager.getBaseBranch()
4922
- n.WorkspaceLogging.logOperation(this.logger,"info","Setting up single-agent workspace",e,"single-agent","setupWorkspace",{branchName:s,mainBranch:i,currentBranch:this.currentBranch})
4923
- const a=await this.git.branch(),c=a.all.includes(s)||a.all.includes("remotes/origin/"+s)
4924
- if(!c)throw Error(`Branch ${s} does not exist. Use initializeRequest() first.`)
4925
- n.WorkspaceLogging.logOperation(this.logger,"info","Branch exists, switching to it",e,"single-agent","setupWorkspace",{branchName:s,branchExists:c,currentBranch:this.currentBranch})
4926
- const l=await this.branchManager.switchToBranch(s,o)
4927
- if(!l.success){n.WorkspaceLogging.logOperation(this.logger,"warn","Branch switch failed, trying direct checkout",e,"single-agent","setupWorkspace",{branchName:s,error:l.error,attempting:"direct-checkout"})
4928
- try{await this.git.checkout(s),n.WorkspaceLogging.logOperation(this.logger,"info","Direct checkout succeeded",e,"single-agent","setupWorkspace",{branchName:s})}catch(e){throw Error(`Failed to switch to branch ${s}: ${l.error}. Direct checkout also failed: ${e}`)}}this.currentBranch=s,this.currentRequestId=o
4929
- const u=Date.now()-t
4930
- return this.metrics?.recordValue("branch_adapter_setup_duration",u),n.WorkspaceLogging.logOperation(this.logger,"info","Successfully set up single-agent workspace",e,"single-agent","setupWorkspace",{branchName:s,mainBranch:i,duration:u}),{mode:"single-agent",requestId:o,branchName:s,workingDirectory:this.basePath,isWorktree:!1,branchInfo:{mainBranch:i,currentBranch:s}}}catch(r){const o=Date.now()-t
4931
- throw this.metrics?.recordValue("branch_adapter_setup_duration",o),n.WorkspaceLogging.logOperation(this.logger,"error","Failed to set up single-agent workspace",e,"single-agent","setupWorkspace",{error:(0,s.getErrorMessage)(r),duration:o}),n.ConflictResolutionUtils.handleBranchCreationError(r instanceof Error?r:Error(r+""),e,"setup workspace","single-agent")}}async detectConflicts(e,t){n.WorkspaceLogging.logOperation(this.logger,"info","Detecting conflicts in single-agent mode",e.requestId,"single-agent","detectConflicts",{sourceBranch:t.sourceBranch,targetBranch:t.targetBranch,workingDirectory:e.workingDirectory})
4932
- const r=await this.conflictDetector.detectConflicts({mode:"single-agent",logger:this.logger,requestId:t.requestId,sourceBranch:t.sourceBranch,targetBranch:t.targetBranch})
4933
- return n.WorkspaceLogging.logOperation(this.logger,"info","Conflict detection completed",e.requestId,"single-agent","detectConflicts",{hasConflicts:r.hasConflicts,conflictedFiles:r.conflictedFiles.length,detectionMethod:r.detectionMethod}),r}async stageAndCommitChanges(e){const t=Date.now()
4934
- n.WorkspaceLogging.logOperation(this.logger,"info","Staging and committing changes in single-agent mode",e.requestId,"single-agent","stageAndCommitChanges",{branchName:e.branchName,workingDirectory:e.workingDirectory})
4935
- try{const r=await this.git.status()
4936
- if(r.modified.length>0||r.not_added.length>0){n.WorkspaceLogging.logOperation(this.logger,"info","Found unstaged changes, staging resolved files",e.requestId,"single-agent","stageAndCommitChanges",{modifiedFiles:r.modified.length,untrackedFiles:r.not_added.length}),r.modified.length>0&&await this.git.add(r.modified),r.not_added.length>0&&await this.git.add(r.not_added),await this.git.commit("Resolve conflicts for request completion",{"--allow-empty":null})
4937
- const o=Date.now()-t
4938
- this.metrics?.recordValue("branch_stage_commit_duration",o),n.WorkspaceLogging.logOperation(this.logger,"info","Successfully staged and committed resolved files",e.requestId,"single-agent","stageAndCommitChanges",{stagedFiles:r.modified.length+r.not_added.length,duration:o})}else{const r=Date.now()-t
4939
- this.metrics?.recordValue("branch_stage_commit_duration",r),n.WorkspaceLogging.logOperation(this.logger,"info","No unstaged changes found, proceeding with existing commit",e.requestId,"single-agent","stageAndCommitChanges",{duration:r})}}catch(r){const o=Date.now()-t
4940
- this.metrics?.recordValue("branch_stage_commit_duration",o),n.WorkspaceLogging.logOperation(this.logger,"warn","Failed to stage resolved files, proceeding anyway",e.requestId,"single-agent","stageAndCommitChanges",{error:r instanceof Error?r.message:r+"",duration:o})}return await this.git.revparse(["HEAD"])}async executeMerge(e,t){const r=Date.now()
4941
- n.WorkspaceLogging.logOperation(this.logger,"info","Executing merge in single-agent mode",e.requestId,"single-agent","executeMerge",{strategy:t.strategy,gitStrategy:t.gitStrategy,branchName:e.branchName})
4942
- const s=e.branchInfo?.mainBranch||"main"
4943
- try{this.logger.debug("Checking for uncommitted changes before branch switch",{mainBranch:s}),n.WorkspaceLogging.logOperation(this.logger,"info","Checking for uncommitted changes before branch switch",e.requestId,"single-agent","executeMerge",{currentBranch:e.branchName,targetBranch:s})
4944
- try{const t=await(0,o.checkUncommittedChanges)(this.git,this.logger,this.metrics||{})
4945
- if(this.logger.debug("Uncommitted changes check result",{hasChanges:t.hasChanges,totalFiles:t.totalFiles,staged:t.stagedFiles.length,unstaged:t.unstagedFiles.length,untracked:t.untrackedFiles.length}),t.hasChanges){this.logger.debug("Found uncommitted changes, committing before branch switch"),n.WorkspaceLogging.logOperation(this.logger,"warn","Found uncommitted changes, committing as user changes before branch switch",e.requestId,"single-agent","executeMerge",{staged:t.stagedFiles.length,unstaged:t.unstagedFiles.length,untracked:t.untrackedFiles.length,total:t.totalFiles,summary:t.summary})
4946
- const r=await(0,o.commitUserChanges)(this.git,e.requestId,t,this.logger,this.metrics||{})
4947
- this.logger.debug("Successfully committed user changes",{commitHash:r.commitHash.substring(0,8),filesCommitted:r.filesCommitted}),n.WorkspaceLogging.logOperation(this.logger,"info","Successfully committed user changes before branch switch",e.requestId,"single-agent","executeMerge",{commitHash:r.commitHash.substring(0,8),filesCommitted:r.filesCommitted,commitMessage:r.message.split("\n")[0]})}else this.logger.debug("No uncommitted changes detected, safe to switch branches"),n.WorkspaceLogging.logOperation(this.logger,"info","No uncommitted changes detected, proceeding with branch switch",e.requestId,"single-agent","executeMerge",{currentBranch:e.branchName,targetBranch:s})}catch(t){this.logger.debug("Failed to check/commit uncommitted changes",{error:t instanceof Error?t.message:t+""}),n.WorkspaceLogging.logOperation(this.logger,"warn","Failed to check/commit uncommitted changes, proceeding with branch switch anyway",e.requestId,"single-agent","executeMerge",{error:t instanceof Error?t.message:t+"",fallback:"continuing-with-branch-switch"})}this.logger.debug("Switching to main branch",{mainBranch:s})
4948
- const i=await this.branchManager.switchToBranch(s,e.requestId)
4949
- if(!i.success)throw Error("Failed to switch to main branch: "+i.error)
4950
- this.logger.debug("Successfully switched to main branch",{mainBranch:s}),n.WorkspaceLogging.logOperation(this.logger,"info","Switched to main branch for merge",e.requestId,"single-agent","executeMerge",{mainBranch:s})
4951
- const a=await this.git.revparse([s]),c=await this.git.revparse([e.branchName])
4952
- a.trim()===c.trim()?(n.WorkspaceLogging.logOperation(this.logger,"info","Request branch has not diverged from main, creating empty commit to enable merge",e.requestId,"single-agent","executeMerge",{mainCommit:a.substring(0,8),requestCommit:c.substring(0,8),reason:"no-file-modifications"}),await this.git.checkout(e.branchName),await this.git.commit(`Empty commit for request ${e.requestId} (no file modifications)`,void 0,{"--allow-empty":null}),await this.git.checkout(s),n.WorkspaceLogging.logOperation(this.logger,"info","Created empty commit on request branch, proceeding with merge",e.requestId,"single-agent","executeMerge",{emptyCommitCreated:!0})):n.WorkspaceLogging.logOperation(this.logger,"info","Request branch has diverged from main, proceeding with normal merge",e.requestId,"single-agent","executeMerge",{mainCommit:a.substring(0,8),requestCommit:c.substring(0,8)}),"direct"===t.strategy&&"theirs"===t.gitStrategy?await this.git.merge([e.branchName,"-m",t.mergeMessage,"--no-ff","-X","theirs"]):await this.git.merge([e.branchName,"-m",t.mergeMessage,"--no-ff"])
4953
- const l=Date.now()-r
4954
- this.metrics?.recordValue("branch_merge_duration",l),n.WorkspaceLogging.logOperation(this.logger,"info","Merge executed successfully",e.requestId,"single-agent","executeMerge",{strategy:t.strategy,gitStrategy:t.gitStrategy||"default",duration:l})}catch(o){const s=Date.now()-r
4955
- throw this.metrics?.recordValue("branch_merge_duration",s),n.WorkspaceLogging.logOperation(this.logger,"error","Merge failed in single-agent mode",e.requestId,"single-agent","executeMerge",{error:o instanceof Error?o.message:o+"",strategy:t.strategy,duration:s}),o}return{mergeCommitHash:await this.git.revparse(["HEAD"]),mergedFiles:[],strategy:t.strategy,wasAutoMerged:"auto-merge"===t.strategy}}async cleanup(e){const t=Date.now()
4956
- n.WorkspaceLogging.logOperation(this.logger,"info","Cleaning up single-agent workspace",e.requestId,"single-agent","cleanup",{branchName:e.branchName,action:"preserve-branch"})
4957
- const r=Date.now()-t
4958
- return this.metrics?.recordValue("branch_cleanup_duration",r),n.WorkspaceLogging.logOperation(this.logger,"info","Branch preserved after completion",e.requestId,"single-agent","cleanup",{branchName:e.branchName,duration:r}),{success:!0,branchDeleted:!1,message:`Branch ${e.branchName} preserved for history`}}async ensureBranchExists(e,t){const r=Date.now()
4959
- try{n.WorkspaceLogging.logOperation(this.logger,"info","Ensuring branch exists for request",e,"single-agent","ensureBranchExists",{requestTitle:t})
4960
- const o=n.ConflictResolutionUtils.createStandardBranchOptions(e,t),s=await this.branchManager.createBranchWithRetry(o),i=Date.now()-r
4961
- return this.metrics?.recordValue("branch_ensure_duration",i),s.success||s.existed?(n.WorkspaceLogging.logOperation(this.logger,"info","Successfully ensured branch exists",e,"single-agent","ensureBranchExists",{branchName:s.branchName,baseBranch:s.baseBranch,existed:s.existed,duration:i}),{success:!0,branchName:s.branchName,baseBranch:s.baseBranch,existed:s.existed,message:s.message}):(n.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure branch exists",e,"single-agent","ensureBranchExists",{error:s.error,duration:i}),{success:!1,branchName:s.branchName,baseBranch:s.baseBranch,existed:!1,message:s.error})}catch(o){const i=Date.now()-r
4962
- this.metrics?.recordValue("branch_ensure_duration",i)
4963
- const a=(0,s.getErrorMessage)(o)
4964
- return n.WorkspaceLogging.logOperation(this.logger,"error","Exception during branch creation",e,"single-agent","ensureBranchExists",{error:a,duration:i}),{success:!1,branchName:this.branchManager.generateRequestBranchName(e,t),baseBranch:"unknown",existed:!1,message:a}}}updateState(e,t){t&&this.currentRequestId===e.requestId&&(this.currentRequestId=null,this.currentBranch=e.branchInfo?.mainBranch||"main"),n.WorkspaceLogging.logOperation(this.logger,"info","Updated single-agent state",e.requestId,"single-agent","updateState",{completed:t,currentRequestId:this.currentRequestId,currentBranch:this.currentBranch})}getMainGit(){return this.git}}},9030(e,exports,t){"use strict"
4765
+ let s=null,i=!1,a=null},9030(e,exports,t){"use strict"
4965
4766
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
4966
4767
  const r=t(6183),n=t(4079)
4967
4768
  exports.def={name:"write_file",description:"Write content to files or documents. Supports both filesystem files (using 'path') and tracked documents (using 'documentId'). For files: requires a taskId and comment, creates/overwrites files, and commits to git. For documents: writes to cached document and syncs back to tracking system. Set append:true to add content to existing content. Handles both text and JSON content.",schema:r.WriteFileSchema,annotations:{title:"Write File/Document",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},createsRecords:!0,handler(e,t){return(0,n.handleWriteFile)(e,t.context,t.apiClient.getFileClient(),t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},9060(e,exports,t){"use strict"
4968
4769
  var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
4969
4770
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConfigManager=void 0,exports.createConfigManager=function(e){return new u(e)}
4970
- const n=r(t(1943)),o=r(t(6928)),s=r(t(857)),i=t(4139),a=t(8824),c={multiAgent:!1,lockOverride:{enabled:!0,passwordValidityMinutes:5}},l={remoteServerUrl:"https://api.alchemylabcode.com",nodePath:"node"}
4771
+ const n=r(t(1943)),o=r(t(6928)),s=r(t(857)),i=t(4139),a=t(8824),c={lockOverride:{enabled:!0,passwordValidityMinutes:5}},l={remoteServerUrl:"https://api.alchemylabcode.com",nodePath:"node"}
4971
4772
  class u{constructor(e){this.logger=e.child({component:"config-manager"}),this.installationConfigDir=this.getInstallationConfigDir()}getInstallationConfigDir(){const e=__dirname||process.cwd(),t=s.default.homedir()
4972
4773
  return e.includes("node_modules")?o.default.join(t,".alchemy_lab","config"):o.default.join(t,".alchemy_lab","config-dev")}async ensureDirectory(e){try{await n.default.access(e)}catch(t){await n.default.mkdir(e,{recursive:!0}),this.logger.debug("Created directory",{dirPath:e})}}async readConfig(e,t){try{const r=await n.default.readFile(e,"utf8"),o=JSON.parse(r)
4973
4774
  return{...t,...o}}catch(r){return"ENOENT"===r.code||this.logger.warn("Error reading config file, using defaults",{filePath:e,error:(0,a.getErrorMessage)(r)}),t}}async writeConfig(e,t){await this.ensureDirectory(o.default.dirname(e)),await n.default.writeFile(e,JSON.stringify(t,null,2),"utf8"),this.logger.debug("Wrote config file",{filePath:e})}async getProjectConfig(e){const t=o.default.join(e,i.ALCHEMY_DIR_NAME,"config.json")
@@ -4977,7 +4778,7 @@ try{const e=await n.default.readFile(t,"utf8"),r=JSON.parse(e)
4977
4778
  return{id:r.id,name:r.name,createdAt:r.createdAt,status:r.status}}catch(e){return"ENOENT"===e.code||this.logger.warn("Error reading project metadata",{projectJsonPath:t,error:(0,a.getErrorMessage)(e)}),null}}async getInstallationConfig(){const e=o.default.join(this.installationConfigDir,"config.json")
4978
4779
  return this.readConfig(e,l)}async updateInstallationConfig(e){const t=o.default.join(this.installationConfigDir,"config.json"),r={...await this.getInstallationConfig(),...e}
4979
4780
  await this.writeConfig(t,r),this.logger.info("Updated installation config",{updates:e})}async getEffectiveConfig(e){const[t,r,n]=await Promise.all([this.getProjectConfig(e),this.getProjectMetadata(e),this.getInstallationConfig()])
4980
- return{remoteServerUrl:n.remoteServerUrl||l.remoteServerUrl,nodePath:n.nodePath||l.nodePath,projectId:r?.id,projectName:r?.name,multiAgent:t.multiAgent||!1,preferredClient:t.preferredClient,lockOverride:{enabled:t.lockOverride?.enabled??c.lockOverride.enabled,passwordValidityMinutes:t.lockOverride?.passwordValidityMinutes??c.lockOverride.passwordValidityMinutes}}}getInstallationConfigPath(){return this.installationConfigDir}}exports.ConfigManager=u},9067(e,exports,t){"use strict"
4781
+ return{remoteServerUrl:n.remoteServerUrl||l.remoteServerUrl,nodePath:n.nodePath||l.nodePath,projectId:r?.id,projectName:r?.name,lockOverride:{enabled:t.lockOverride?.enabled??c.lockOverride.enabled,passwordValidityMinutes:t.lockOverride?.passwordValidityMinutes??c.lockOverride.passwordValidityMinutes}}}getInstallationConfigPath(){return this.installationConfigDir}}exports.ConfigManager=u},9067(e,exports,t){"use strict"
4981
4782
  var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
4982
4783
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ExternalAuthFlow=exports.PollingStatus=void 0
4983
4784
  const n=r(t(6982)),o=t(8824)
@@ -5028,15 +4829,15 @@ e&&(this.pollingStatus=s.AUTHENTICATED,this.tokenResult=e,this.stopPolling(),r&&
5028
4829
  function r(){const e=process.env.ALCHEMY_OPENCODE_DIR
5029
4830
  if(e)return e
5030
4831
  try{const e=("undefined"!=typeof require?require:t(4245)).resolve("alchemylab-opencode/package.json")
5031
- return(0,o.dirname)(e)}catch{}}function n(e,t){return{command:function(){try{const e=(0,i.execFileSync)("node",["--version"],{encoding:"utf8"}).trim()
5032
- if(parseInt(e.replace("v","").split(".")[0],10)>=a)return"node"}catch{}const e=process.env.NVM_DIR||(0,o.join)(process.env.HOME||"",".nvm"),t=(0,o.join)(e,"versions","node")
5033
- if((0,s.existsSync)(t))try{const e=(0,s.readdirSync)(t).filter((e=>parseInt(e.replace("v","").split(".")[0],10)>=a)).sort(((e,t)=>{const r=parseInt(e.replace("v","").split(".")[0],10)
4832
+ return(0,s.dirname)(e)}catch{}}function n(e){return 22===e||e>=24}function o(e,t){return{command:function(){try{const e=(0,a.execFileSync)("node",["--version"],{encoding:"utf8"}).trim()
4833
+ if(n(parseInt(e.replace("v","").split(".")[0],10)))return"node"}catch{}const e=process.env.NVM_DIR||(0,s.join)(process.env.HOME||"",".nvm"),t=(0,s.join)(e,"versions","node")
4834
+ if((0,i.existsSync)(t))try{const e=(0,i.readdirSync)(t).filter((e=>n(parseInt(e.replace("v","").split(".")[0],10)))).sort(((e,t)=>{const r=parseInt(e.replace("v","").split(".")[0],10)
5034
4835
  return parseInt(t.replace("v","").split(".")[0],10)-r}))
5035
- if(e.length>0){const r=(0,o.join)(t,e[0],"bin","node")
5036
- if((0,s.existsSync)(r))return r}}catch{}throw Error(`AlchemyLab requires Node.js >= ${a} to run the OpenCode server.\nYour current version: ${process.version}\nInstall Node ${a}+: nvm install ${a} (or download from https://nodejs.org)`)}(),prependArgs:["--no-warnings",(0,o.join)(e,t)]}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.resolveServeCommand=function(){const e=r()
5037
- return e?n((0,o.join)(e,"dist"),"serve.js"):{command:"opencode",prependArgs:["serve"]}},exports.resolveRunCommand=function(){const e=r()
5038
- return e?n((0,o.join)(e,"dist"),"run.js"):{command:"opencode",prependArgs:[]}}
5039
- const o=t(6928),s=t(9896),i=t(5317),a=24},9072(e,exports,t){"use strict"
4836
+ if(e.length>0){const r=(0,s.join)(t,e[0],"bin","node")
4837
+ if((0,i.existsSync)(r))return r}}catch{}throw Error(`AlchemyLab requires Node.js 22 or 24+ to run the OpenCode server (Node 23 is not supported).\nYour current version: ${process.version}\nInstall a compatible version: nvm install 22 (or download from https://nodejs.org)`)}(),prependArgs:["--no-warnings",(0,s.join)(e,t)]}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.resolveServeCommand=function(){const e=r()
4838
+ return e?o((0,s.join)(e,"dist"),"serve.js"):{command:"opencode",prependArgs:["serve"]}},exports.resolveRunCommand=function(){const e=r()
4839
+ return e?o((0,s.join)(e,"dist"),"run.js"):{command:"opencode",prependArgs:[]}}
4840
+ const s=t(6928),i=t(9896),a=t(5317)},9072(e,exports,t){"use strict"
5040
4841
  async function r(e,t,r,n){try{const o=await(0,u.getServerUrl)(r,n)
5041
4842
  if(!o)return n.warn("Could not get server URL for notification",{sessionId:e}),!1
5042
4843
  let s,i
@@ -5062,7 +4863,7 @@ const d=l.getSessionMessageClient()
5062
4863
  if(!d)throw new c.ValidationError("Session message client not available")
5063
4864
  if("question"===u)return await async function(e,t,i,a,l){const{toSessionId:u,questionType:d,questionContent:h,priority:g,expiresInHours:p}=e
5064
4865
  if(!d||!h?.question)throw new c.ValidationError("Question requires questionType and questionContent.question")
5065
- const f=await o(0,0,"session_message_operations"),m=await async function(e,t,r,o){if("parent"===e){const e=await n(t,r,o)
4866
+ const f=o(0,0,"session_message_operations"),m=await async function(e,t,r,o){if("parent"===e){const e=await n(t,r,o)
5066
4867
  if(!e)throw new c.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
5067
4868
  return o.info('Resolved toSessionId "parent" to actual ID',{parentId:e}),e}return e}(u,f,a,i)
5068
4869
  if(!("alternatives"!==d||h.options&&Array.isArray(h.options)))throw new c.ValidationError("Alternatives questions require options array")
@@ -5074,7 +4875,7 @@ if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&
5074
4875
  for(const e of t.options)r.push(` - [${e.id}] ${e.label}${e.description?" - "+e.description:""}`)}return r.push(""),r.push(`Use \`session_message_operations\` with \`reply\` operation and message code \`${e.messageCode}\` to respond.`),r.join("\n")}(y),t,i)?"\n\n\u{1f4ec} The target session has been notified.":"\n\n\u26a0\ufe0f Could not notify the target session (may be offline)."),{content:[{type:"text",text:`\u2705 Question created!${w}\n\n**Message Code: ${y.messageCode}**\n\nUse this code to check for answers or share with other sessions.\n\n${s(y)}`}]}}(e,t,a,l,d)
5075
4876
  if("report"===u)return await async function(e,t,s,a,l){const{status:u,summary:d,details:h,finish:p}=e
5076
4877
  if(!u||!d)throw new c.ValidationError("Report requires status and summary")
5077
- const f=await o(0,0,"session_message_operations"),m=await(async()=>{if(e.toSessionId&&"parent"!==e.toSessionId)return s.info("Using explicit toSessionId for report",{parentSessionId:e.toSessionId}),e.toSessionId
4878
+ const f=o(0,0,"session_message_operations"),m=await(async()=>{if(e.toSessionId&&"parent"!==e.toSessionId)return s.info("Using explicit toSessionId for report",{parentSessionId:e.toSessionId}),e.toSessionId
5078
4879
  const t=await n(f,a,s)
5079
4880
  if(!t)throw new c.ValidationError("Could not find parent session. This tool should only be used by subagent sessions.")
5080
4881
  return s.info("Auto-resolved parent session",{parentSessionId:t}),t})()
@@ -5134,26 +4935,14 @@ if(t>0){const r=e.slice(0,t).trim()
5134
4935
  return exports.SCIENTIST_NAMES.find((e=>e.toLowerCase()===r.toLowerCase()))??null}return exports.SCIENTIST_NAMES.find((t=>t.toLowerCase()===e.trim().toLowerCase()))??null}Object.defineProperty(exports,"__esModule",{value:!0}),exports.SCIENTIST_NAMES=void 0,exports.pickSpecialistName=function(e){const r=new Set(e.map(t).filter((e=>null!==e))),n=exports.SCIENTIST_NAMES.filter((e=>!r.has(e)))
5135
4936
  return 0===n.length?`${exports.SCIENTIST_NAMES[Math.floor(Math.random()*exports.SCIENTIST_NAMES.length)]}-${e.length+1}`:n[Math.floor(Math.random()*n.length)]},exports.SCIENTIST_NAMES=["Archimedes","Avicenna","Boyle","Brahe","Copernicus","Curie","Darwin","Euclid","Euler","Faraday","Fermi","Fibonacci","Galileo","Gauss","Hooke","Hypatia","Kepler","Lavoisier","Leibniz","Lovelace","Maxwell","Mendeleev","Newton","Nobel","Pascal","Pasteur","Planck","Ptolemy","Tesla","Turing"]},9150(module){"use strict"
5136
4937
  module.exports=require("@modelcontextprotocol/sdk/types.js")},9161(e,exports,t){"use strict"
5137
- function r(e,t){return new a(e,t)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.createImprovedConflictDetector=exports.ConflictDetector=void 0,exports.createConflictDetector=r
5138
- const n=t(8824),o=t(3444),s=t(8712),i=o.defaultLogger.child({component:"conflict-detector"})
5139
- class a{constructor(e,t){this.git=e,this.logger=t}async detectConflicts(e){const t=e.logger.child({component:"conflict-detector",mode:e.mode,requestId:e.requestId,sourceBranch:e.sourceBranch,targetBranch:e.targetBranch})
4938
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConflictDetector=void 0,exports.createConflictDetector=function(e,t){return new i(e,t)}
4939
+ const r=t(8824),n=t(3444),o=t(8712),s=n.defaultLogger.child({component:"conflict-detector"})
4940
+ class i{constructor(e,t){this.git=e,this.logger=t}async detectConflicts(e){const t=e.logger.child({component:"conflict-detector",mode:e.mode,requestId:e.requestId,sourceBranch:e.sourceBranch,targetBranch:e.targetBranch})
5140
4941
  t.info("Starting conflict detection",{mode:e.mode,detectionStrategy:"merge-tree-analysis"})
5141
- try{return"single-agent"===e.mode?await this.detectSingleAgentConflicts(e,t):await this.detectMultiAgentConflicts(e,t)}catch(e){return t.error("Conflict detection failed",{error:e}),{hasConflicts:!1,conflictedFiles:[],summary:"Conflict detection failed - proceeding with caution",resolutionInstructions:"Conflict detection failed: "+(0,n.getErrorMessage)(e),detectionMethod:"merge-tree-analysis",rawOutput:(0,n.getErrorMessage)(e)}}}async detectSingleAgentConflicts(e,t){t.info("Using unified git merge-tree strategy for single-agent conflict detection (no working directory modification)")
5142
- try{const r=await this.git.revparse([e.sourceBranch]),n=await this.git.revparse([e.targetBranch])
5143
- let o,i
5144
- t.debug("Retrieved commits for merge-tree analysis",{sourceCommit:r.substring(0,8),targetCommit:n.substring(0,8),sourceBranch:e.sourceBranch,targetBranch:e.targetBranch})
5145
- try{o=await this.git.raw(["merge-base",r,n])}catch(o){return t.warn("Could not find merge-base, commits may be unrelated",{sourceCommit:r.substring(0,8),targetCommit:n.substring(0,8),error:o}),{hasConflicts:!0,conflictedFiles:[{path:"<multiple files>",conflictType:"content",description:"Branches have diverged significantly (no merge-base found)"}],summary:"Branches have diverged significantly",resolutionInstructions:this.generateSingleAgentInstructions([{path:"<multiple files>",conflictType:"content",description:"Significant divergence"}],e.requestId,e.sourceBranch,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:"merge-base failed: "+o}}t.debug("Commits for merge-tree analysis",{sourceCommit:r.substring(0,8),targetCommit:n.substring(0,8),mergeBase:o.trim().substring(0,8)})
5146
- let a=0
5147
- try{i=await this.git.raw(["merge-tree",o.trim(),n.trim(),r.trim()]),a=0}catch(e){i=e.message||"",a=e.exitCode||1,t.debug("merge-tree failed with error",{exitCode:a,error:e.message})}t.debug("Merge-tree analysis completed",{outputLength:i.length,hasOutput:!!i.trim(),exitCode:a})
5148
- let c=!1,l="",u=null
5149
- if(0!==a?(c=!0,l="merge-tree-exit-code"):i&&i.trim()?(u=(0,s.parseConflictOutputWithContext)(i,e.requestId,e.sourceBranch,e.targetBranch),u.hasConflictMarkers?(c=!0,l="conflict-parser-detected-markers",t.warn("Git exit code 0 but conflict parser found conflict markers - treating as conflict")):(c=!1,l="clean-merge-with-changes",t.info("Git exit code 0 and conflict parser found no markers - treating as clean merge",{hasOutput:!0,outputLength:i.length}))):(c=!1,l="clean-merge-no-changes"),t.info("UNIFIED conflict detection result (same logic as multi-agent)",{hasConflicts:c,exitCode:a,hasOutput:!!i.trim(),outputLength:i?i.length:0,conflictReason:l,method:"git-merge-tree-unified",trustedGitExitCode:0===a}),!c)return{hasConflicts:!1,conflictedFiles:[],summary:"No conflicts detected (merge-tree clean)",resolutionInstructions:"",detectionMethod:"merge-tree-analysis",rawOutput:i}
5150
- !u&&i&&i.trim()&&(u=(0,s.parseConflictOutputWithContext)(i,e.requestId,e.sourceBranch,e.targetBranch))
5151
- let d=[]
5152
- if(u&&u.filesParsed&&u.filesParsed.length>0)d=u.filesParsed.map((e=>({path:e,conflictType:"content",description:"Merge conflict detected"}))),t.debug("Successfully extracted conflict files from parsed content",{conflictedFilesCount:d.length,files:d.map((e=>e.path))})
5153
- else try{d=this.parseMergeTreeOutput(i,t),t.debug("Used fallback merge-tree parsing",{conflictedFilesCount:d.length})}catch(e){t.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),d=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===d.length&&(t.warn("Git detected conflicts but no files could be determined - using fallback"),d=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:d,summary:d.length>0&&"<parsing failed>"!==d[0].path&&"<unknown files>"!==d[0].path?d.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateSingleAgentInstructions(d,e.requestId,e.sourceBranch,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:i,rawConflictContent:u?u.cleanContent:void 0}}catch(e){throw t.error("Unified single-agent conflict detection failed",{error:e}),e}}async detectMultiAgentConflicts(e,r){if(r.info("Using pure merge-tree analysis for multi-agent conflict detection",{worktreePath:e.worktreePath}),!e.worktreePath)throw Error("worktreePath is required for multi-agent conflict detection")
4942
+ try{return await this.detectMultiAgentConflicts(e,t)}catch(e){return t.error("Conflict detection failed",{error:e}),{hasConflicts:!1,conflictedFiles:[],summary:"Conflict detection failed - proceeding with caution",resolutionInstructions:"Conflict detection failed: "+(0,r.getErrorMessage)(e),detectionMethod:"merge-tree-analysis",rawOutput:(0,r.getErrorMessage)(e)}}}async detectMultiAgentConflicts(e,r){if(r.info("Using pure merge-tree analysis for multi-agent conflict detection",{worktreePath:e.worktreePath}),!e.worktreePath)throw Error("worktreePath is required for multi-agent conflict detection")
5154
4943
  try{r.debug("Getting worktree commit for analysis")
5155
- const n=t(3807)(e.worktreePath),o=await n.branch()
5156
- if(r.info("WORKTREE DEBUG: Current branch status",{requestId:e.requestId,currentBranch:o.current,expectedBranch:e.sourceBranch,allBranches:o.all,isDetached:o.detached}),o.current!==e.sourceBranch&&o.current!==e.sourceBranch.replace("refs/heads/","")){r.warn("WORKTREE BRANCH MISMATCH",{requestId:e.requestId,currentBranch:o.current,expectedBranch:e.sourceBranch,worktreePath:e.worktreePath})
4944
+ const n=t(3807)(e.worktreePath),s=await n.branch()
4945
+ if(r.info("WORKTREE DEBUG: Current branch status",{requestId:e.requestId,currentBranch:s.current,expectedBranch:e.sourceBranch,allBranches:s.all,isDetached:s.detached}),s.current!==e.sourceBranch&&s.current!==e.sourceBranch.replace("refs/heads/","")){r.warn("WORKTREE BRANCH MISMATCH",{requestId:e.requestId,currentBranch:s.current,expectedBranch:e.sourceBranch,worktreePath:e.worktreePath})
5157
4946
  try{await n.checkout(e.sourceBranch.replace("refs/heads/","")),r.info("Successfully switched to correct branch",{requestId:e.requestId,branch:e.sourceBranch})}catch(t){r.error("Failed to checkout correct branch",{requestId:e.requestId,expectedBranch:e.sourceBranch,error:t})}}const i=await n.revparse(["HEAD"])
5158
4947
  let a=!1
5159
4948
  try{await this.git.raw(["merge-base","--is-ancestor",i,"main"]),a=!0}catch{a=!1}r.info("WORKTREE DEBUG: HEAD commit analysis",{requestId:e.requestId,commit:i.substring(0,8),fullCommit:i,sourceBranch:e.sourceBranch,isCommitInMain:a,worktreePath:e.worktreePath}),a&&r.warn("POTENTIAL BUG: Worktree HEAD points to commit already in main",{requestId:e.requestId,worktreeCommit:i.substring(0,8),sourceBranch:e.sourceBranch,warning:"This may cause false negative conflict detection"})
@@ -5163,8 +4952,8 @@ try{l=await this.git.raw(["merge-base",i,c])}catch(t){return r.warn("Could not f
5163
4952
  let d=0
5164
4953
  try{u=await this.git.raw(["merge-tree",l.trim(),c.trim(),i.trim()]),d=0}catch(e){u=e.message||"",d=e.exitCode||1,r.debug("merge-tree failed with error",{exitCode:d,error:e.message})}r.debug("Merge-tree analysis completed",{outputLength:u.length,hasOutput:!!u.trim(),exitCode:d})
5165
4954
  let h=!1,g="",p=null
5166
- if(0!==d?(h=!0,g="merge-tree-exit-code"):u&&u.trim()?(p=(0,s.parseConflictOutputWithContext)(u,e.requestId,e.sourceBranch,e.targetBranch),p.hasConflictMarkers?(h=!0,g="conflict-parser-detected-markers",r.warn("Git exit code 0 but conflict parser found conflict markers - treating as conflict")):(h=!1,g="clean-merge-with-changes",r.info("Git exit code 0 and conflict parser found no markers - treating as clean merge",{hasOutput:!0,outputLength:u.length}))):(h=!1,g="clean-merge-no-changes"),r.info("FINAL conflict detection result (trusting Git exit codes)",{hasConflicts:h,exitCode:d,hasOutput:!!u.trim(),outputLength:u?u.length:0,conflictReason:g,method:"git-exit-code-primary",trustedGitExitCode:0===d}),!h)return{hasConflicts:!1,conflictedFiles:[],summary:"No conflicts detected (merge-tree clean)",resolutionInstructions:"",detectionMethod:"merge-tree-analysis",rawOutput:u}
5167
- !p&&u&&u.trim()&&(p=(0,s.parseConflictOutputWithContext)(u,e.requestId,e.sourceBranch,e.targetBranch))
4955
+ if(0!==d?(h=!0,g="merge-tree-exit-code"):u&&u.trim()?(p=(0,o.parseConflictOutputWithContext)(u,e.requestId,e.sourceBranch,e.targetBranch),p.hasConflictMarkers?(h=!0,g="conflict-parser-detected-markers",r.warn("Git exit code 0 but conflict parser found conflict markers - treating as conflict")):(h=!1,g="clean-merge-with-changes",r.info("Git exit code 0 and conflict parser found no markers - treating as clean merge",{hasOutput:!0,outputLength:u.length}))):(h=!1,g="clean-merge-no-changes"),r.info("FINAL conflict detection result (trusting Git exit codes)",{hasConflicts:h,exitCode:d,hasOutput:!!u.trim(),outputLength:u?u.length:0,conflictReason:g,method:"git-exit-code-primary",trustedGitExitCode:0===d}),!h)return{hasConflicts:!1,conflictedFiles:[],summary:"No conflicts detected (merge-tree clean)",resolutionInstructions:"",detectionMethod:"merge-tree-analysis",rawOutput:u}
4956
+ !p&&u&&u.trim()&&(p=(0,o.parseConflictOutputWithContext)(u,e.requestId,e.sourceBranch,e.targetBranch))
5168
4957
  let f=[]
5169
4958
  if(p&&p.filesParsed&&p.filesParsed.length>0)f=p.filesParsed.map((e=>({path:e,conflictType:"content",description:"Merge conflict detected"}))),r.debug("Successfully extracted conflict files from parsed content",{conflictedFilesCount:f.length,files:f.map((e=>e.path))})
5170
4959
  else try{f=this.parseMergeTreeOutput(u,r),r.debug("Used fallback merge-tree parsing",{conflictedFilesCount:f.length})}catch(e){r.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),f=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===f.length&&(r.warn("Git detected conflicts but no files could be determined - using fallback"),f=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:f,summary:f.length>0&&"<parsing failed>"!==f[0].path&&"<unknown files>"!==f[0].path?f.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateMultiAgentInstructions(f,e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:u,rawConflictContent:p?p.cleanContent:void 0}}catch(e){throw r.error("Pure multi-agent conflict detection failed",{error:e}),e}}parseMergeTreeOutput(e,t){const r=[]
@@ -5181,27 +4970,18 @@ for(let i=e+1;i<Math.min(e+10,n.length);i++){const e=n[i].trim().match(/^(?:our|
5181
4970
  if(e){const n=e[1].trim(),i=n.includes(" -> ")?n.split(" -> ")[1]||n.split(" -> ")[0]:n
5182
4971
  i&&!s.has(i)&&(s.add(i),r.push({path:i,conflictType:o,description:t+" conflict"}))}}}const o=t.match(/CONFLICT\\s*\\([^)]+\\):\\s*.*?(?:in|->)\\s+(.+?)(?:\\s*->\\s*(.+?))?$/i)
5183
4972
  if(o){const e=o[1].trim()
5184
- e&&"Merge conflict"!==e&&!s.has(e)&&(s.add(e),r.push({path:e,conflictType:"content",description:"CONFLICT message detected"}))}}return t.debug("Parsed conflicted files from merge-tree",{filesCount:r.length,files:r.map((e=>e.path))}),r}hasConflictIndicators(e){if(!e||!e.trim())return!1
5185
- if(this.logger.debug("Analyzing merge-tree output for conflict indicators",{outputLength:e.length,firstLine:e.split("\n")[0],containsMerged:e.includes("merged\n"),containsResult:e.includes("result "),containsOur:e.includes("our ")}),this.hasExactConflictMarkers(e))return this.logger.debug("Found conflict markers in output"),!0
5186
- const t=["changed in both","added in both","deleted by us","deleted by them","renamed in both","CONFLICT(","conflict:","failed to merge"]
5187
- for(const r of t)if(e.toLowerCase().includes(r.toLowerCase()))return this.logger.debug("Found conflict keyword",{keyword:r}),!0
5188
- this.logger.debug("No conflict keywords found")
5189
- const r=e.split("\n")
5190
- let n=!1
5191
- for(const e of r){const t=e.trim()
5192
- if(/^[UA]{2}\s+/.test(t)||/^DD\s+/.test(t)){this.logger.debug("Found git status conflict indicator",{line:t}),n=!0
5193
- break}}return!!n||(e.includes("merged\n")&&e.includes("result ")&&e.includes("our ")?(this.logger.debug("Detected clean merge format"),!1):(this.logger.debug("No conflict indicators found, assuming clean merge"),!1))}generateSingleAgentInstructions(e,t,r,n){return`MERGE CONFLICTS DETECTED - Resolution Required\n\nConflicted Files:\n${e.map((e=>`- ${e.path} (${e.conflictType} conflict)`)).join("\\n")}\n\nResolution Steps for Single-Agent Mode:\n1. Switch to your feature branch: git checkout ${r}\n2. Merge ${n} into your feature branch: git merge ${n}\n3. Resolve conflicts in each file:\n ${e.map((e=>` - Edit ${e.path} to resolve ${e.conflictType} conflict`)).join("\\n")}\n4. Stage resolved files: git add ${e.map((e=>e.path)).join(" ")}\n5. Commit the resolution: git commit -m "Resolve merge conflicts for request ${t}"\n6. Try completing the request again\n\nThe conflicts must be resolved before the request can be completed.`}generateMultiAgentInstructions(e,t,r,n){return`MERGE CONFLICTS DETECTED - Resolution Required\n\nConflicted Files:\n${e.map((e=>`- ${e.path} (${e.conflictType} conflict)`)).join("\\n")}\n\nResolution Steps for Multi-Agent Mode:\n1. Ensure you're working in the worktree: ${r}\n2. Pull latest ${n} changes: git pull origin ${n}\n3. Resolve conflicts in each file:\n ${e.map((e=>` - Edit ${e.path} to resolve ${e.conflictType} conflict`)).join("\\n")}\n4. Stage resolved files: git add ${e.map((e=>e.path)).join(" ")}\n5. Commit the resolution: git commit -m "Resolve merge conflicts for request ${t}"\n6. Try completing the request again\n\nIMPORTANT: Work only in the worktree (${r}) to avoid affecting other agents.`}hasExactConflictMarkers(e){if(!e||!e.trim())return!1
5194
- i.debug("Checking for conflict markers",{textLength:e.length,firstChars:e.substring(0,100),containsStart:e.includes("<<<<<<<"),containsMiddle:e.includes("======="),containsEnd:e.includes(">>>>>>>")})
4973
+ e&&"Merge conflict"!==e&&!s.has(e)&&(s.add(e),r.push({path:e,conflictType:"content",description:"CONFLICT message detected"}))}}return t.debug("Parsed conflicted files from merge-tree",{filesCount:r.length,files:r.map((e=>e.path))}),r}generateMultiAgentInstructions(e,t,r,n){return`MERGE CONFLICTS DETECTED - Resolution Required\n\nConflicted Files:\n${e.map((e=>`- ${e.path} (${e.conflictType} conflict)`)).join("\\n")}\n\nResolution Steps for Multi-Agent Mode:\n1. Ensure you're working in the worktree: ${r}\n2. Pull latest ${n} changes: git pull origin ${n}\n3. Resolve conflicts in each file:\n ${e.map((e=>` - Edit ${e.path} to resolve ${e.conflictType} conflict`)).join("\\n")}\n4. Stage resolved files: git add ${e.map((e=>e.path)).join(" ")}\n5. Commit the resolution: git commit -m "Resolve merge conflicts for request ${t}"\n6. Try completing the request again\n\nIMPORTANT: Work only in the worktree (${r}) to avoid affecting other agents.`}hasExactConflictMarkers(e){if(!e||!e.trim())return!1
4974
+ s.debug("Checking for conflict markers",{textLength:e.length,firstChars:e.substring(0,100),containsStart:e.includes("<<<<<<<"),containsMiddle:e.includes("======="),containsEnd:e.includes(">>>>>>>")})
5195
4975
  const t=e.split("\n")
5196
- i.debug("Text lines",{totalLines:t.length})
4976
+ s.debug("Text lines",{totalLines:t.length})
5197
4977
  for(let e=0;e<t.length;e++){const r=t[e],n=r.trim()
5198
- if(this.hasExactMarker(n,"<")||this.hasExactMarker(n,"=")||this.hasExactMarker(n,">"))return i.debug("Found conflict marker",{lineNumber:e+1,line:r}),!0;(r.includes("<<<<<<<")||r.includes("=======")||r.includes(">>>>>>>"))&&i.debug("Line contains marker but hasExactMarker failed",{lineNumber:e+1,line:r,trimmed:n,hasStart:this.hasExactMarker(n,"<"),hasMiddle:this.hasExactMarker(n,"="),hasEnd:this.hasExactMarker(n,">")})}return i.debug("No conflict markers detected"),!1}hasExactMarker(e,t){const r=t.repeat(7)
4978
+ if(this.hasExactMarker(n,"<")||this.hasExactMarker(n,"=")||this.hasExactMarker(n,">"))return s.debug("Found conflict marker",{lineNumber:e+1,line:r}),!0;(r.includes("<<<<<<<")||r.includes("=======")||r.includes(">>>>>>>"))&&s.debug("Line contains marker but hasExactMarker failed",{lineNumber:e+1,line:r,trimmed:n,hasStart:this.hasExactMarker(n,"<"),hasMiddle:this.hasExactMarker(n,"="),hasEnd:this.hasExactMarker(n,">")})}return s.debug("No conflict markers detected"),!1}hasExactMarker(e,t){const r=t.repeat(7)
5199
4979
  return!!e.startsWith(r)&&(7===e.length||e[7]!==t)}hasExplicitConflictMarkers(e){if(!e||!e.trim())return!1
5200
4980
  if(this.logger.debug("Checking for explicit conflict markers (conservative)",{outputLength:e.length,firstLine:e.split("\n")[0]}),this.hasExactConflictMarkers(e))return this.logger.debug("Found actual Git conflict markers"),!0
5201
4981
  if(e.includes("CONFLICT("))return this.logger.debug("Found explicit CONFLICT message from Git"),!0
5202
4982
  const t=e.split("\n")
5203
4983
  for(const e of t){const t=e.trim()
5204
- if(/^[UA]{2}\s+/.test(t)||/^DD\s+/.test(t))return this.logger.debug("Found git status conflict indicator",{line:t}),!0}return this.logger.debug("No explicit conflict markers found - assuming clean merge"),!1}}exports.ConflictDetector=a,exports.createImprovedConflictDetector=r},9196(e,exports,t){"use strict"
4984
+ if(/^[UA]{2}\s+/.test(t)||/^DD\s+/.test(t))return this.logger.debug("Found git status conflict indicator",{line:t}),!0}return this.logger.debug("No explicit conflict markers found - assuming clean merge"),!1}}exports.ConflictDetector=i},9196(e,exports,t){"use strict"
5205
4985
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
5206
4986
  const r=t(6183),n=t(8309)
5207
4987
  exports.def={name:"create_directory",description:"Create a new directory or ensure a directory exists. Can create multiple nested directories in one operation. If the directory already exists, this operation will succeed silently. Perfect for setting up directory structures for projects or ensuring required paths exist.",schema:r.CreateDirectorySchema,annotations:{title:"Create Directory",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},hidden:!0,handler(e,t){return(0,n.handleCreateDirectory)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},9230(e,exports,t){"use strict"
@@ -5256,39 +5036,39 @@ b.info("Replace in files batch operation",{taskId:_,operationCount:E.length,tota
5256
5036
  const T=E.filter((e=>e.documentId)).map((e=>e.documentId))
5257
5037
  if(T.length>0&&t.apiClient)try{await(0,m.ensureDocumentsNotLocked)(T,t.apiClient,b,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5258
5038
  throw e}C=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5259
- const M=E[0],R=M.documentId?"document:"+M.documentId:M.path
5260
- let P=Date.now()
5261
- const x=await d.validateTaskId(_,R,r,b,a,"replace_in_files")
5039
+ const R=E[0],P=R.documentId?"document:"+R.documentId:R.path
5040
+ let M=Date.now()
5041
+ const x=await d.validateTaskId(_,P,r,b,a,"replace_in_files")
5262
5042
  Date.now()
5263
- const O=x?.requestId,j=E.some((e=>e.path))
5043
+ const j=x?.requestId,O=E.some((e=>e.path))
5264
5044
  let $=!1
5265
- if(j&&O){P=Date.now()
5266
- const e=await d.validateWorkItemStates(_,R,r,s,t,b,a,"replace_in_files")
5267
- Date.now(),P=Date.now()
5268
- const n=await d.autoPromoteTaskStatus(_,x.status,O,e.request?.status,R,r,s,b,a,"replace_in_files")
5269
- n.taskPromoted&&b.info("Auto-promoted task to in_progress",{taskId:_,requestId:O,previousStatus:x.status,newStatus:n.newTaskStatus}),Date.now(),P=Date.now()
5270
- const o=await d.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:O,context:t,operation:"replace_in_files",logger:b,metrics:a,metricsPrefix:"replace_in_files"})
5045
+ if(O&&j){M=Date.now()
5046
+ const e=await d.validateWorkItemStates(_,P,r,s,t,b,a,"replace_in_files")
5047
+ Date.now(),M=Date.now()
5048
+ const n=await d.autoPromoteTaskStatus(_,x.status,j,e.request?.status,P,r,s,b,a,"replace_in_files")
5049
+ n.taskPromoted&&b.info("Auto-promoted task to in_progress",{taskId:_,requestId:j,previousStatus:x.status,newStatus:n.newTaskStatus}),Date.now(),M=Date.now()
5050
+ const o=await d.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:j,context:t,operation:"replace_in_files",logger:b,metrics:a,metricsPrefix:"replace_in_files"})
5271
5051
  if(!o.success){if(o.isLockConflict)return{content:[{type:"text",text:"\u274c "+o.error}],isError:!0}
5272
- throw Error(o.error)}Date.now(),$=!0}if(T.length>0&&O)try{await(0,p.validateRequestStatusForDocumentOperation)(O,s,b,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5273
- throw e}P=Date.now()
5052
+ throw Error(o.error)}Date.now(),$=!0}if(T.length>0&&j)try{await(0,p.validateRequestStatusForDocumentOperation)(j,s,b,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5053
+ throw e}M=Date.now()
5274
5054
  const D=new Map
5275
- if(b.info("\u{1f50d} Starting external edit detection",{hasFileOperations:j,hasGit:!!t.git,operationCount:E.length}),j&&t.git)for(const e of E)if(e.path&&!e.documentId)try{const r=d.validateAndNormalizePath(e.path,t),n=await l.default.readFile(r.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:q,s=[]
5055
+ if(b.info("\u{1f50d} Starting external edit detection",{hasFileOperations:O,hasGit:!!t.git,operationCount:E.length}),O&&t.git)for(const e of E)if(e.path&&!e.documentId)try{const r=d.validateAndNormalizePath(e.path,t),n=await l.default.readFile(r.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:q,s=[]
5276
5056
  for(const t of e.replacements){const r=(0,h.findMatches)(n,t.old,o,100,e.path)
5277
5057
  s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,r.fullPath)
5278
5058
  b.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
5279
5059
  const i=await(0,w.detectExternalEdits)(t.git,o,b)
5280
- b.info("\u{1f50d} External edit detection result",{path:r.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(D.set(e.path,{message:i.message,debugInfo:i.debugInfo}),b.warn("\u26a0\ufe0f External edits detected before auto-commit",{path:r.normalizedPath,conflictingLines:i.conflictingLines})):(i.debugInfo&&D.set(e.path,{message:"",debugInfo:i.debugInfo}),b.info("\u2705 No external edit conflicts detected",{path:r.normalizedPath}))}else b.info("\u2139\ufe0f No matches found for external edit detection",{path:r.normalizedPath}),D.set(e.path,{message:"",debugInfo:{detectionRan:!1,reason:"No matches found - patterns not found in file",affectedRegion:"none",uncommittedChanges:"not checked",overlapDetected:!1}})}catch(t){b.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,k.getErrorMessage)(t)})}if(Date.now(),P=Date.now(),j&&t.git)try{b.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
5281
- const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:O,taskId:_,workspaceManager:t.workspaceManager},b,a)
5282
- e.userChangesCommitted&&(b.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),b.info("User changes committed before batch operation",{taskId:_,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){b.warn("Pre-tool user changes commit failed",{taskId:_,error:e instanceof Error?e.message:e+""})}Date.now(),P=Date.now(),C=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5283
- const{toolRecordId:A}=await d.createFileOperationRecords(_,O,t.projectId,"replace-in-files",R,{operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,userComment:S},r,o,b,a,"replace_in_files",c)
5284
- v=A,Date.now(),P=Date.now(),C=d.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5060
+ b.info("\u{1f50d} External edit detection result",{path:r.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(D.set(e.path,{message:i.message,debugInfo:i.debugInfo}),b.warn("\u26a0\ufe0f External edits detected before auto-commit",{path:r.normalizedPath,conflictingLines:i.conflictingLines})):(i.debugInfo&&D.set(e.path,{message:"",debugInfo:i.debugInfo}),b.info("\u2705 No external edit conflicts detected",{path:r.normalizedPath}))}else b.info("\u2139\ufe0f No matches found for external edit detection",{path:r.normalizedPath}),D.set(e.path,{message:"",debugInfo:{detectionRan:!1,reason:"No matches found - patterns not found in file",affectedRegion:"none",uncommittedChanges:"not checked",overlapDetected:!1}})}catch(t){b.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,k.getErrorMessage)(t)})}if(Date.now(),M=Date.now(),O&&t.git)try{b.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
5061
+ const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:j,taskId:_,workspaceManager:t.workspaceManager},b,a)
5062
+ e.userChangesCommitted&&(b.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),b.info("User changes committed before batch operation",{taskId:_,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){b.warn("Pre-tool user changes commit failed",{taskId:_,error:e instanceof Error?e.message:e+""})}Date.now(),M=Date.now(),C=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5063
+ const{toolRecordId:A}=await d.createFileOperationRecords(_,j,t.projectId,"replace-in-files",P,{operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,userComment:S},r,o,b,a,"replace_in_files",c)
5064
+ v=A,Date.now(),M=Date.now(),C=d.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5285
5065
  const F=[],N=[]
5286
5066
  for(const e of E){const r=e.path?D.get(e.path):void 0,o=await n(e,q,t,0,0,r?.message,r?.debugInfo)
5287
- F.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&N.push(o.path)}Date.now(),P=Date.now()
5288
- const L=E.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),z=await d.handleMultiFileGitCommit(_,L,F,N.length,{operationType:"Replace in files",toolRecordId:A||v||"unknown",successField:"successfulReplacements",logger:b,metrics:a,metricsPrefix:"replace_in_files"},t),B=z.commitHash
5067
+ F.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&N.push(o.path)}Date.now(),M=Date.now()
5068
+ const L=E.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),z=await d.handleMultiFileGitCommit(_,L,F,N.length,{operationType:"Replace in files",toolRecordId:A||v||"unknown",successField:"successfulReplacements",logger:b,metrics:a,metricsPrefix:"replace_in_files"},t),H=z.commitHash
5289
5069
  Date.now(),Date.now()
5290
- const H=F.filter((e=>e.success)).length,U=F.length-H,W=F.reduce(((e,t)=>e+t.successfulReplacements),0),G=F.reduce(((e,t)=>e+t.failedReplacements),0),V=F.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,replacements:e.replacements.map((e=>({old_str:e.old,new_str:e.new,success:e.success,error:e.error,matchesFound:e.matchesFound,matchType:e.matchType,lines:e.lines})))}))),J=F.filter((e=>e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements}))),K=F.filter((e=>!e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,error:e.error,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements})))
5291
- await o.updateToolRecord(v,{metadata:{path:R,status:0===U?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:K,successfulReplacements:W,failedReplacements:G,processingTime:Date.now()-I,userComment:S,...z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}}})
5070
+ const B=F.filter((e=>e.success)).length,U=F.length-B,G=F.reduce(((e,t)=>e+t.successfulReplacements),0),W=F.reduce(((e,t)=>e+t.failedReplacements),0),V=F.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,replacements:e.replacements.map((e=>({old_str:e.old,new_str:e.new,success:e.success,error:e.error,matchesFound:e.matchesFound,matchType:e.matchType,lines:e.lines})))}))),J=F.filter((e=>e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements}))),K=F.filter((e=>!e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,error:e.error,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements})))
5071
+ await o.updateToolRecord(v,{metadata:{path:P,status:0===U?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:K,successfulReplacements:G,failedReplacements:W,processingTime:Date.now()-I,userComment:S,...z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}}})
5292
5072
  const Y=await async function(e,t,r,n,o,s){const i=e.filter((e=>e.success)).length,a=e.length-i,c=e.filter((e=>!e.success&&!e.error&&e.successfulReplacements>0)).length
5293
5073
  let l="## Replace In Files - Batch Results\n\n"
5294
5074
  if(o.getCurrentBranchContext)try{const e=await o.getCurrentBranchContext()
@@ -5300,8 +5080,8 @@ if(o.length>0){l+="\n**Successful Replacements:**\n"
5300
5080
  for(const e of o)l+=`- \u2705 \`${e.old.substring(0,40)}${e.old.length>40?"...":""}\` \u2192 \`${e.new.substring(0,40)}${e.new.length>40?"...":""}\``,e.matchesFound&&(l+=` (${e.matchesFound} occurrence${e.matchesFound>1?"s":""})`),e.lines&&e.lines.length>0&&3>=e.lines.length?l+=` at line${e.lines.length>1?"s":""} ${e.lines.join(", ")}`:e.lines&&e.lines.length>3&&(l+=` at ${e.lines.length} locations`),l+="\n"}const s=r.replacements.filter((e=>!e.success))
5301
5081
  if(s.length>0){l+="\n**Failed Replacement Details:**\n"
5302
5082
  for(const e of s)l+=`- \u274c \`${e.old.substring(0,40)}${e.old.length>40?"...":""}\` \u2192 \`${e.new.substring(0,40)}${e.new.length>40?"...":""}\`: ${e.error}\n`,e.details&&e.details.length>0&&(l+=" **Candidates found:**\n",l+=e.details.slice(0,5).map((e=>` - Line ${e.line}: \`${e.actually_matched.substring(0,40)}${e.actually_matched.length>40?"...":""}\` (${e.match_type})`)).join("\n")+"\n",e.details.length>5&&(l+=` ... and ${e.details.length-5} more matches\n`)),e.similarMatches&&e.similarMatches.length>0&&(l+=" **Did you mean? (Similar matches found):**\n",l+=e.similarMatches.map((e=>` - Line ${e.line}: \`${e.text.substring(0,60)}${e.text.length>60?"...":""}\` (${e.reason}, similarity: ${(100*e.similarity).toFixed(0)}%)`)).join("\n")+"\n")}l+="\n"}const u=e.filter((e=>"document"===e.type&&(e.success||e.successfulReplacements>0)))
5303
- return u.length>0&&(l+=`\n**Document Changes:** ${u.length} modified document(s) synced back to tracking system.\n`),o.workspaceManager?.largeFileWarning&&(l+=o.workspaceManager.largeFileWarning,o.workspaceManager.largeFileWarning=""),l}(F,B,W,G,t,v)
5304
- return{content:[{type:"text",text:Y}],isError:0===W}}catch(e){const t=Date.now()-I
5083
+ return u.length>0&&(l+=`\n**Document Changes:** ${u.length} modified document(s) synced back to tracking system.\n`),o.workspaceManager?.largeFileWarning&&(l+=o.workspaceManager.largeFileWarning,o.workspaceManager.largeFileWarning=""),l}(F,H,G,W,t,v)
5084
+ return{content:[{type:"text",text:Y}],isError:0===G}}catch(e){const t=Date.now()-I
5305
5085
  if(b.error("Replace in files batch operation failed",{error:e instanceof Error?e.stack:e+"",duration:t,phase:C}),v)try{await o.updateToolRecord(v,{metadata:{status:"failed",error:(0,k.getErrorMessage)(e),phase:C,duration:t}})}catch(e){}return a.incrementCounter("replace_in_files_errors",1,{phase:C}),{content:[{type:"text",text:"\u274c **Replace In Files Failed:** "+(0,k.getErrorMessage)(e)}],isError:!0}}}
5306
5086
  const l=c(t(1943)),u=(a(t(9896)),a(t(6928)),c(t(6982)),t(6183)),d=a(t(5967)),h=t(3626),g=t(9860),p=t(5003),f=t(7478),m=t(9949),y=t(9947),w=t(1318),k=t(8824)},9470(e,exports){"use strict"
5307
5087
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
@@ -5341,87 +5121,7 @@ Object.defineProperty(exports,"Server",{enumerable:!0,get(){return r.Server}})
5341
5121
  const n=t(5802)
5342
5122
  Object.defineProperty(exports,"StdioServerTransport",{enumerable:!0,get(){return n.StdioServerTransport}})
5343
5123
  const o=t(2422)
5344
- Object.defineProperty(exports,"SSEServerTransport",{enumerable:!0,get(){return o.SSEServerTransport}})},9653(e,exports,t){"use strict"
5345
- var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
5346
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.SingleAgentWorkspaceManager=void 0
5347
- const n=r(t(6928)),o=t(8824),s=t(7075),i=t(1387),a=t(9013)
5348
- exports.SingleAgentWorkspaceManager=class{constructor(e,t,r,n){this.basePath=e,this.logger=t,this.git=r,this.metrics=n,this.currentRequestId=null,this.currentBranch="main",this.readonlyBranchCheckDone=!1,this.workspaceKnownClean=!1,this.largeFileWarning=""
5349
- const o=s.ConflictResolutionUtils.initializeDetectors(r,t,n)
5350
- this.conflictDetector=o.conflictDetector,this.safetyAnalyzer=o.safetyAnalyzer,this.conflictResolver=o.conflictResolver,this.gitAdapter=new a.BranchGitAdapter(this.basePath,r,this.conflictDetector,t,n),this.requestProcessor=new i.WorkspaceRequestProcessor(this.gitAdapter,this.conflictDetector,this.safetyAnalyzer,this.conflictResolver,t),this.initializeCurrentBranch()}setTaskCreator(e){this.taskCreator=e}async initializeCurrentBranch(){try{const e=process.env.ALCHEMY_INITIAL_BRANCH
5351
- if(e){this.logger.info("ALCHEMY_INITIAL_BRANCH set, switching to branch without locking",{initialBranch:e})
5352
- try{const t=await this.git.branch()
5353
- if(t.all.includes(e)||t.all.includes("remotes/origin/"+e.replace("refs/heads/",""))){await this.git.checkout(e),this.currentBranch=e
5354
- const t=e.match(/^requests\/(.+)$/)
5355
- return t&&(this.currentRequestId=t[1]),void this.logger.info("Successfully switched to initial branch (readonly mode)",{currentBranch:this.currentBranch,currentRequestId:this.currentRequestId})}this.logger.warn("ALCHEMY_INITIAL_BRANCH specified but branch does not exist",{initialBranch:e})}catch(t){this.logger.warn("Failed to switch to ALCHEMY_INITIAL_BRANCH",{initialBranch:e,error:t})}}if(this.currentBranch=await this.git.revparse(["--abbrev-ref","HEAD"]),this.currentBranch.startsWith("requests/")){const e=this.currentBranch.match(/^requests\/(.+)$/)
5356
- e&&(this.currentRequestId=e[1])}this.logger.debug("Initialized single-agent workspace manager",{currentBranch:this.currentBranch,currentRequestId:this.currentRequestId})}catch(e){this.logger.warn("Failed to initialize current branch, defaulting to main",{error:e}),this.currentBranch="main",this.currentRequestId=null}}async initializeRequest(e,t){const r=Date.now(),n=s.WorkspaceValidation.validateRequestId(e)
5357
- if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
5358
- const i="requests/"+n.sanitized
5359
- try{s.WorkspaceLogging.logOperation(this.logger,"info","Initializing request by creating branch",e,"single-agent","initializeRequest",{requestTitle:t,branchName:i,architecture:"hybrid-creation"})
5360
- const n=(await this.git.branch()).all.includes(i)
5361
- if(n)s.WorkspaceLogging.logOperation(this.logger,"info","Branch already exists, skipping creation",e,"single-agent","initializeRequest",{branchName:i})
5362
- else{const t=await this.git.revparse(["--abbrev-ref","HEAD"]),r=await this.gitAdapter.branchManager.getBaseBranch()
5363
- await this.git.checkout(["-b",i,r]),await this.git.checkout(t),s.WorkspaceLogging.logOperation(this.logger,"info","Created branch and returned to original",e,"single-agent","initializeRequest",{branchName:i,baseBranch:r,returnedTo:t})}const o=Date.now()-r
5364
- this.metrics.recordValue("workspace.initialize",o),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully initialized request with branch",e,"single-agent","initializeRequest",{branchName:i,existed:n,duration:o,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
5365
- throw this.metrics.recordValue("workspace.initialize",n),s.WorkspaceLogging.logOperation(this.logger,"error","Failed to initialize request",e,"single-agent","initializeRequest",{error:(0,o.getErrorMessage)(t),duration:n}),t}}async ensureWorkspaceReady(e,t){const r=Date.now(),n=s.WorkspaceValidation.validateRequestId(e)
5366
- if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
5367
- const i=n.sanitized,a="requests/"+i,c=await this.git.revparse(["--abbrev-ref","HEAD"])
5368
- if(c===a)return this.currentRequestId=i,this.currentBranch=a,void this.logger.debug("Workspace already ready",{requestId:i,currentBranch:this.currentBranch})
5369
- try{if(s.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by switching to branch",e,"single-agent","ensureWorkspaceReady",{currentBranch:c,targetBranch:a,architecture:"hybrid-creation"}),!(await this.git.branch()).all.includes(a))throw Error(`Branch ${a} does not exist. Was initializeRequest() called?`)
5370
- try{await this.switchToRequest(i)}catch(t){s.WorkspaceLogging.logOperation(this.logger,"warn","switchToRequest failed, trying direct checkout",e,"single-agent","ensureWorkspaceReady",{error:t instanceof Error?t.message:t+"",attempting:"direct-checkout",branchName:a}),await this.git.checkout(a),this.currentRequestId=i,this.currentBranch=a,s.WorkspaceLogging.logOperation(this.logger,"info","Direct checkout succeeded",e,"single-agent","ensureWorkspaceReady",{branchName:a})}const t=Date.now()-r
5371
- this.metrics.recordValue("workspace.ensure_ready",t),s.WorkspaceLogging.logOperation(this.logger,"info","Workspace is ready",e,"single-agent","ensureWorkspaceReady",{branchName:this.currentBranch,duration:t,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
5372
- throw this.metrics.recordValue("workspace.ensure_ready",n),s.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure workspace ready",e,"single-agent","ensureWorkspaceReady",{error:(0,o.getErrorMessage)(t),duration:n}),t}}async switchToRequest(e,t){const r=Date.now(),n=this.getCurrentContext(),i=s.WorkspaceValidation.validateRequestId(e)
5373
- if(!i.isValid){const t="Invalid request ID: "+i.errors.join(", ")
5374
- throw s.WorkspaceLogging.logOperation(this.logger,"error",t,e,"single-agent","switchToRequest"),Error(t)}const a=i.sanitized
5375
- try{s.WorkspaceLogging.logOperation(this.logger,"info","Switching to request (assuming branch exists)",e,"single-agent","switchToRequest",{previousBranch:n.branchName,architecture:"aligned-with-multi-agent"})
5376
- const t=await this.gitAdapter.setupWorkspace(a)
5377
- this.currentRequestId=t.requestId,this.currentBranch=t.branchName
5378
- const o=Date.now()-r
5379
- return this.metrics.recordValue("workspace.switch",o),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully switched to request",e,"single-agent","switchToRequest",{branchName:t.branchName,previousBranch:n.branchName,duration:o,architecture:"aligned-with-multi-agent"}),{success:!0,message:"Switched to request "+a,previousContext:n,newContext:this.getCurrentContext()}}catch(t){const n=Date.now()-r
5380
- this.metrics.recordValue("workspace.switch",n)
5381
- const i=(0,o.getErrorMessage)(t),a=i.includes("does not exist"),c=a?`Branch for request ${e} does not exist. Use initializeRequest() first to create the branch.`:`Failed to switch to request ${e}: ${i}`
5382
- throw s.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to request",e,"single-agent","switchToRequest",{error:i,isMissingBranch:a,duration:n,suggestion:a?"Call initializeRequest() first":"Check branch status"}),new s.ConflictDetectionError(c,"single-agent-switch-"+e,[])}}async switchToMain(e){const t=Date.now(),r=this.getCurrentContext()
5383
- try{const e=await this.gitAdapter.branchManager.getBaseBranch(),n=await this.gitAdapter.branchManager.switchToBranch(e)
5384
- if(!n.success)throw Error("Failed to switch to main branch: "+n.error)
5385
- this.currentBranch=e,this.currentRequestId=null
5386
- const o=Date.now()-t
5387
- return this.metrics.recordValue("workspace.switch_main",o),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully switched to main branch",null,"single-agent","switchToMain",{mainBranch:e,previousBranch:r.branchName,duration:o,architecture:"aligned-with-multi-agent"}),{success:!0,message:"Switched to "+e,previousContext:r,newContext:this.getCurrentContext()}}catch(e){const r=Date.now()-t
5388
- throw this.metrics.recordValue("workspace.switch_main",r),s.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to main branch",null,"single-agent","switchToMain",{error:(0,o.getErrorMessage)(e),duration:r}),new s.ConflictDetectionError("Failed to switch to main: "+(0,o.getErrorMessage)(e),"single-agent",[])}}async commitChanges(e,t){const r=Date.now()
5389
- try{t&&t.length>0?await this.git.add(t):await this.git.add("."),await this.git.commit(e)
5390
- const n=await this.git.revparse(["HEAD"]),o=Date.now()-r
5391
- return this.metrics.recordValue("workspace.commit",o),this.logger.info("Successfully committed changes",{message:e,commitHash:n.substring(0,8),filesCount:t?.length||"all",duration:o}),{hash:n,message:e,files:t||[]}}catch(t){const n=Date.now()-r
5392
- throw this.metrics.recordValue("workspace.commit",n),this.logger.error("Failed to commit changes",{message:e,error:(0,o.getErrorMessage)(t),duration:n}),new s.ConflictDetectionError("Failed to commit changes: "+(0,o.getErrorMessage)(t),"single-agent-commit",[])}}async completeRequest(e,t,r){const n=Date.now()
5393
- try{s.WorkspaceLogging.logOperation(this.logger,"info","Starting request completion (refactored)",e,"single-agent","completeRequest",{requestTitle:t,skipConflictDetection:r?.skipConflictDetection||!1,architecture:"shared-processor"})
5394
- const o=await this.requestProcessor.completeRequest(e,t,{skipConflictDetection:r?.skipConflictDetection||!1}),i=Date.now()-n
5395
- return this.metrics.recordValue("workspace.complete",i),s.WorkspaceLogging.logOperation(this.logger,"info","Request completion successful (refactored)",e,"single-agent","completeRequest",{mergeCommitHash:o.mergeCommitHash.substring(0,8),mergedFiles:o.mergedFiles?.length||0,cleanedUp:o.cleanedUp,wasAutoMerged:o.autoMergeInfo?.wasAutoMerged,strategy:o.autoMergeInfo?.strategy,duration:i,architecture:"shared-processor"}),o}catch(t){const r=Date.now()-n
5396
- throw this.metrics.recordValue("workspace.complete",r),s.WorkspaceLogging.logOperation(this.logger,"error","Request completion failed (refactored)",e,"single-agent","completeRequest",{error:(0,o.getErrorMessage)(t),duration:r,architecture:"shared-processor"}),t}}resolveFilePath(e,t){return n.default.resolve(this.basePath,e)}async createCommit(e,t,r){return await this.commitChanges(e,t)}async cancelRequest(e){const t=s.WorkspaceValidation.validateRequestId(e)
5397
- if(!t.isValid)throw Error("Invalid request ID: "+t.errors.join(", "))
5398
- const r="requests/"+t.sanitized
5399
- try{s.WorkspaceLogging.logOperation(this.logger,"info","Cancelling request (deleting branch)",e,"single-agent","cancelRequest",{branchName:r,architecture:"aligned-with-multi-agent"}),this.currentBranch===r&&await this.switchToMain(),await this.git.deleteLocalBranch(r),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully cancelled request",e,"single-agent","cancelRequest",{branchName:r,switchedToMain:this.currentBranch!==r})}catch(t){throw s.WorkspaceLogging.logOperation(this.logger,"error","Failed to cancel request",e,"single-agent","cancelRequest",{branchName:r,error:(0,o.getErrorMessage)(t)}),t}}async listActiveWorkspaces(){try{return(await this.git.branch()).all.filter((e=>e.startsWith("requests/"))).map((e=>({requestId:e.replace("requests/",""),path:this.basePath,branchName:e,isActive:this.currentBranch===e,created:new Date,lastAccessed:new Date})))}catch(e){return this.logger.error("Failed to list active workspaces",{error:(0,o.getErrorMessage)(e)}),[]}}getCurrentContext(e){return{requestId:this.currentRequestId,basePath:this.basePath,branchName:this.currentBranch,isMainBranch:"main"===this.currentBranch||"master"===this.currentBranch,mode:"single-agent"}}async getWorkspaceInfo(e){try{const t=s.WorkspaceValidation.validateRequestId(e)
5400
- if(!t.isValid)return null
5401
- const r=t.sanitized,n="requests/"+r,o=await this.git.branch()
5402
- return o.all.includes(n)||o.all.includes("remotes/origin/"+n)?{requestId:r,path:this.basePath,branchName:n,isActive:this.currentBranch===n,created:new Date,lastAccessed:new Date}:null}catch(t){return this.logger.error("Failed to get workspace info",{requestId:e,error:(0,o.getErrorMessage)(t)}),null}}getMainGit(){return this.gitAdapter.getMainGit()}async getWorktreeInfo(e){}getCurrentGit(e){return this.git}async ensureReadonlyBranchIfNeeded(e,t,r,n){if(!this.readonlyBranchCheckDone){this.readonlyBranchCheckDone=!0
5403
- try{const e=n
5404
- if(!e)return void this.logger.debug("No sessionId available for readonly check")
5405
- this.logger.debug("Checking readonly branch for session",{sessionId:e,toolName:t})
5406
- const o=r?.getCLISessionClient?.()
5407
- if(!o)return void this.logger.debug("No CLI session client available for readonly check")
5408
- const s=await o.getByExternalId(e)
5409
- if(!s?.agentType)return void this.logger.debug("No agent type found for session",{sessionId:e})
5410
- this.logger.debug("Found session agent type",{sessionId:e,agentType:s.agentType})
5411
- const i=await this.fetchAgentConfig(s.agentType)
5412
- if(!i||"readonly"!==i.requestContextMode)return void this.logger.debug("Agent does not have readonly requestContextMode",{agentType:s.agentType})
5413
- this.logger.debug("Agent has readonly requestContextMode",{agentType:s.agentType})
5414
- const a=r?.getSessionRequestAssociationClient?.()
5415
- if(!a)return void this.logger.debug("No session association client available")
5416
- const c=await a.getActiveRequestsForSession(e,!0)
5417
- if(0===c.length)return void this.logger.debug("No active request association found for session",{sessionId:e})
5418
- const l=c[0].requestLocalId,u="requests/"+l
5419
- this.logger.info("Readonly agent with request association, switching to branch without locking",{sessionId:e,agentType:s.agentType,requestId:l,readonlyBranch:u})
5420
- const d=await this.git.branch()
5421
- d.all.includes(u)||d.all.includes("remotes/origin/"+u)?(await this.git.checkout(u),this.currentBranch=u,this.currentRequestId=l,this.logger.info("Successfully switched to readonly branch",{currentBranch:this.currentBranch,currentRequestId:this.currentRequestId})):this.logger.warn("Readonly branch does not exist",{readonlyBranch:u})}catch(e){this.logger.debug("Error during readonly branch check",{error:(0,o.getErrorMessage)(e)})}}}async fetchAgentConfig(e){try{const t="http://localhost:3456/api/agents/by-name/"+encodeURIComponent(e),r=await fetch(t)
5422
- if(!r.ok)return null
5423
- const n=await r.json()
5424
- return n.success?n.data??null:null}catch{return null}}async cleanup(){this.logger.info("Cleaning up single-agent workspace manager")}}},9671(e,exports){"use strict"
5124
+ Object.defineProperty(exports,"SSEServerTransport",{enumerable:!0,get(){return o.SSEServerTransport}})},9671(e,exports){"use strict"
5425
5125
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.findPreviousCommit=async function(e,t,r){try{if(!r){const r=await e.raw(["rev-list","--max-count=1","HEAD","--",t])
5426
5126
  return r&&r.trim()?r.trim():null}const n=await e.raw(["rev-list","--max-count=1",r+"^","--",t])
5427
5127
  return n&&n.trim()?n.trim():null}catch(e){return null}}},9697(e,exports,t){"use strict"
@@ -5608,7 +5308,14 @@ return c.length>0&&(e+=`**Locked Documents (${c.length}):**\n`,c.forEach((t=>{co
5608
5308
  e+=`- \`${t.documentId}\` (locked ${r} by ${t.lockedByUserId||"unknown user"})\n`})),e+="\n"),l.length>0&&(e+=`**Validation Errors (${l.length}):**\n`,l.forEach((t=>{e+=`- ${t}\n`})),e+="\n"),e+="**Resolution:**\n",e+="- Unlock any locked documents before proceeding\n",e+="- Resolve any validation errors\n",e+="- Try the operation again",a.warn("Batch operation blocked due to locked documents or errors",{lockedCount:c.length,errorCount:l.length}),{isValid:!1,error:e}}return a.debug("All documents validated successfully for batch operation"),{isValid:!0}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.validateDocumentNotLocked=r,exports.validateDocumentsNotLocked=n,exports.ensureDocumentNotLocked=async function(e,t,n,s,i){const a=await r(e,t,n,s,i)
5609
5309
  if(!a.isValid)throw new o.ValidationError(a.error||"Document is locked")},exports.ensureDocumentsNotLocked=async function(e,t,r,s,i){const a=await n(e,t,r,s,i)
5610
5310
  if(!a.isValid)throw new o.ValidationError(a.error||"One or more documents are locked")}
5611
- const o=t(9860),s=t(8824)}},s={}
5311
+ const o=t(9860),s=t(8824)},9968(e,exports,t){"use strict"
5312
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleUpdateSpecialization=async function(e,t,o,s){const i=r.UpdateSpecializationSchema.parse(e),{specialization:a}=i
5313
+ if(!s?.sessionId)return{content:[{type:"text",text:"Cannot update specialization: session identity not available."}],isError:!0}
5314
+ if(!o)return{content:[{type:"text",text:"Cannot update specialization: API client not available."}],isError:!0}
5315
+ const c=o.getCLISessionClient()
5316
+ if(!c)return{content:[{type:"text",text:"Cannot update specialization: session client not available."}],isError:!0}
5317
+ try{return await c.createOrUpdateSession({externalSessionId:s.sessionId,specialization:a}),t.info("Specialization updated",{sessionId:s.sessionId,specialization:a}),{content:[{type:"text",text:"Specialization updated to: "+a}]}}catch(e){return t.error("Failed to update specialization",{sessionId:s.sessionId,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:"Failed to update specialization: "+(0,n.getErrorMessage)(e)}],isError:!0}}}
5318
+ const r=t(6183),n=t(8824)}},s={}
5612
5319
  e.m=o,r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,e.t=function(n,o){if(1&o&&(n=this(n)),8&o)return n
5613
5320
  if("object"==typeof n&&n){if(4&o&&n.__esModule)return n
5614
5321
  if(16&o&&"function"==typeof n.then)return n}var s=Object.create(null)