alchemylab 1.0.6 → 1.0.8

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.
@@ -20,13 +20,13 @@ const f={requestId:a.requestId,projectId:l,title:a.title,description:a.descripti
20
20
  u.info("Task input prepared",{taskInput:JSON.stringify(f)}),u.info("Creating task via task client",{projectId:l,requestId:a.requestId,title:a.title})
21
21
  const m=await p.createTask(f)
22
22
  u.debug("Task creation response structure",{type:typeof m,isArray:Array.isArray(m),hasData:null!=m,properties:m?Object.keys(m):[],dataPreview:m?JSON.stringify(m).substring(0,200)+"...":"null"})
23
- const y=(0,o.extractDataFromResponse)(m,{logger:u,operationName:"createTask",defaultValue:{id:"tas"+Date.now().toString().substring(5,11),title:f.title,description:f.description,status:"pending",requestId:f.requestId,projectId:l,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}),w="data"in y?y.data:y,k=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),I=w.title||f.title,b=w.description||f.description,v=w.status||"pending",C=w.requestId||f.requestId
23
+ const y=(0,o.extractDataFromResponse)(m,{logger:u,operationName:"createTask",defaultValue:{id:"tas"+Date.now().toString().substring(5,11),title:f.title,description:f.description,status:"pending",requestId:f.requestId,projectId:l,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}),w="data"in y?y.data:y,k=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),b=w.title||f.title,I=w.description||f.description,v=w.status||"pending",C=w.requestId||f.requestId
24
24
  let _,E="unknown"
25
- w&&"object"==typeof w&&"_workingEndpoint"in w&&(E=w._workingEndpoint),u.info("Successfully extracted task data from response",{taskId:k,requestId:C,title:I})
25
+ w&&"object"==typeof w&&"_workingEndpoint"in w&&(E=w._workingEndpoint),u.info("Successfully extracted task data from response",{taskId:k,requestId:C,title:b})
26
26
  try{const e=i.getToolRecordClient()
27
- if(e){const t=await e.createToolRecord({taskId:k,requestId:C,projectId:l,type:"create-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:I,taskDescription:b,taskStatus:v},note:"Created task "+I})
28
- _=t?.id}}catch(e){u.error("Failed to create tool record for task creation, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:k,requestId:C})}h({success:!0,requestId:a.requestId,projectId:l}),u.info("Task created successfully",{taskId:k,requestId:C,title:I,projectId:l})
29
- let q=`Created Task ${k}: ${I}`
27
+ if(e){const t=await e.createToolRecord({taskId:k,requestId:C,projectId:l,type:"create-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:b,taskDescription:I,taskStatus:v},note:"Created task "+b})
28
+ _=t?.id}}catch(e){u.error("Failed to create tool record for task creation, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:k,requestId:C})}h({success:!0,requestId:a.requestId,projectId:l}),u.info("Task created successfully",{taskId:k,requestId:C,title:b,projectId:l})
29
+ let q=`Created Task ${k}: ${b}`
30
30
  return _&&(q+=`\n[RECORD:${_}]`),{content:[{type:"text",text:q}]}}catch(r){if(u.error("Failed to create task",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new tasks")||r.message.includes("disabled due to tier limits")||r.message.includes("Project is inactive due to tier limits")))u.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
31
31
  else{const n=i.getToolRecordClient()
32
32
  n&&await n.createToolRecord({requestId:e.requestId,projectId:t.projectId,type:"create-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.title,taskDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),error:(0,s.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create task: "+e.title})}}catch(e){u.error("Failed to create failure record for task creation",{error:e instanceof Error?e.message:e+""})}h({success:!1,error:r instanceof Error?r.name:"unknown"})
@@ -44,19 +44,19 @@ var t={}
44
44
  if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
45
45
  return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
46
46
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.McpServer=void 0,exports.resetStdoutWrite=function(){process.stdout.write=x},exports.getMcpServer=r,exports.createServer=function(e,t,n,o,s={}){return r(e,t,n,o,s)}
47
- const c=t(3807),l=t(8909),d=a(t(6928)),u=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)),I=t(4139),b=new Set,v=t(9860),C=t(1472),_=t(3328),E=t(8955),q=t(3217),S=t(8411),T=t(5278),P=t(446),M=t(9060),R=t(8824),j=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),x=process.stdout.write,O=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
48
- !(0,p.isDebugToolsEnabled)()||O&&"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&&j.debug("Stdout output",{content:e.substring(0,100),length:e.length}),x.call(process.stdout,e)}catch(e){return j.error("Error in safeStdoutWrite",{error:e+""}),!0}})
49
- class A{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=d.default.join(e,I.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 P.LockOverrideManager(t),this.configManager=new M.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
+ const c=t(3807),l=t(8909),d=a(t(6928)),u=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),P=t(446),M=t(9060),j=t(8824),R=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),x=process.stdout.write,O=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
48
+ !(0,p.isDebugToolsEnabled)()||O&&"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&&R.debug("Stdout output",{content:e.substring(0,100),length:e.length}),x.call(process.stdout,e)}catch(e){return R.error("Error in safeStdoutWrite",{error:e+""}),!0}})
49
+ class A{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=d.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 P.LockOverrideManager(t),this.configManager=new M.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}
50
50
  const e=this.workspaceManager.getCurrentContext()
51
51
  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}
52
52
  const e=this.workspaceManager.getCurrentContext()
53
53
  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()
54
54
  if(!r||"function"!=typeof r.getNextId)throw Error("Project client or getNextId method not available")
55
55
  const n=await r.getNextId(e)
56
- 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"
56
+ 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,j.getErrorMessage)(t)}),Error("Failed to get ID from remote server.")}}async initialize(){const e=this.remoteServerUrl||"https://api.alchemylabcode.com"
57
57
  this.logger.debug("Using remote server URL",{remoteServerUrl:e})
58
58
  const t=d.default.resolve(this.basePath)
59
- if(b.has(t))return this.logger.info("Path already initialized in global registry, skipping initialization",{path:t}),void(this.isInitialized=!0)
59
+ if(I.has(t))return this.logger.info("Path already initialized in global registry, skipping initialization",{path:t}),void(this.isInitialized=!0)
60
60
  if(this.isInitialized)this.logger.info("Server already initialized, skipping initialization")
61
61
  else{if(this.isInitializing)return this.logger.info("Initialization already in progress, waiting..."),void await this.initializationPromise
62
62
  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"})
@@ -67,12 +67,12 @@ try{this.logger.info("Validating git repository for branch management...")
67
67
  const e=await k.validateGitRepository(this.git,this.logger,this.metrics)
68
68
  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})
69
69
  const t=[],r=[]
70
- 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=d.default.join(this.basePath,".gitignore"),t=I.ALCHEMY_DIR_NAME+"/"
70
+ 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=d.default.join(this.basePath,".gitignore"),t=b.ALCHEMY_DIR_NAME+"/"
71
71
  try{if(u.default.existsSync(e)){const r=await h.default.readFile(e,"utf8")
72
- if(r.split("\n").some((e=>e.trim()===t||e.trim()===t.slice(0,-1))))this.logger.info(I.ALCHEMY_DIR_NAME+"/ already present in .gitignore")
72
+ 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
73
  else{const n=r.trimEnd()+"\n\n# AlchemyMCP working directory\n"+t+"\n"
74
- await h.default.writeFile(e,n),this.logger.info(`Added ${I.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")
75
- await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${I.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()
74
+ 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")
75
+ 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,j.getErrorMessage)(e)})}}async initializeGitRepo(){try{this.logger.info("Initializing git repository"),await this.git.init(),await this.ensureGitignoreWithAlchemyLab()
76
76
  const e=d.default.join(this.basePath,"README.md")
77
77
  if(!u.default.existsSync(e)){const t=`# Project at ${this.basePath}\n\nCreated with AlchemyMCP Server.\n`
78
78
  await h.default.writeFile(e,t)}this.logger.info("Git repository initialized successfully"),await this.git.add(".")
@@ -80,7 +80,7 @@ const t=await this.git.status()
80
80
  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||{}
81
81
  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})
82
82
  const r=this.detectClientFromName(t.name)
83
- 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,R.getErrorMessage)(e)})}}detectClientFromName(e){if(!e)return
83
+ 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,j.getErrorMessage)(e)})}}detectClientFromName(e){if(!e)return
84
84
  const t=e.toLowerCase()
85
85
  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")
86
86
  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+""}}})
@@ -105,19 +105,19 @@ const t=await r.getSynchronizedProjectId()
105
105
  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...")
106
106
  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"}
107
107
  const e=await k.getRepositoryStatus(this.git,this.logger,this.metrics)
108
- 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"),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")
108
+ 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,j.getErrorMessage)(e)}),{available:!1,message:"Git error: "+(0,j.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")
109
109
  const r=new g.SSEServerTransport("/sse",e)
110
110
  this.currentSSEConnection={transport:r,response:e}
111
- 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,R.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"}
112
- 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,R.getErrorMessage)(e)})}}getCurrentSSEConnection(){return this.currentSSEConnection}interceptConnectMethod(){try{const e=this.server.connect
111
+ 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,j.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"}
112
+ 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,j.getErrorMessage)(e)})}}getCurrentSSEConnection(){return this.currentSSEConnection}interceptConnectMethod(){try{const e=this.server.connect
113
113
  "function"==typeof e&&(this.server.connect=async t=>{const r=await e.call(this.server,t)
114
- return setTimeout((()=>{this.extractClientInfoAfterConnection(),this.searchForClaudeAiPattern()}),500),r})}catch(e){this.logger.error("Failed to intercept connect method",{error:(0,R.getErrorMessage)(e)})}}searchForClaudeAiPattern(){try{const e=this.server,t=(e,r=0)=>{if(r>3||!e||"object"!=typeof e)return!1
114
+ return setTimeout((()=>{this.extractClientInfoAfterConnection(),this.searchForClaudeAiPattern()}),500),r})}catch(e){this.logger.error("Failed to intercept connect method",{error:(0,j.getErrorMessage)(e)})}}searchForClaudeAiPattern(){try{const e=this.server,t=(e,r=0)=>{if(r>3||!e||"object"!=typeof e)return!1
115
115
  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
116
116
  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]
117
117
  let n=!1
118
118
  for(const e of r)if(e&&t(e)){n=!0
119
119
  break}if(!n&&this.clientInfo&&"Unknown Client"===this.clientInfo.name){const e=this.detectClientUsingHeuristics()
120
- 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,R.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
120
+ 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,j.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
121
121
  if("sse"===this.clientInfo.connectionType){const e=this.clientInfo.userAgent?.toLowerCase()||""
122
122
  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"
123
123
  if(e.includes("chrome")||e.includes("electron"))return"Claude Code"}if("stdio"===this.clientInfo.connectionType){const e=process.env.TERM_PROGRAM?.toLowerCase()||""
@@ -134,36 +134,36 @@ if(o.includes("claude.app")||o.includes("electron")&&o.includes("claude"))return
134
134
  if(e.includes("vscode"))return"VS Code"
135
135
  if(e.includes("cursor"))return"Cursor"
136
136
  if(e.includes("claude-code"))return"Claude Code"
137
- 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,R.getErrorMessage)(e)}),null}}extractClientInfoAfterConnection(){try{setTimeout((()=>{const e=(0,w.getClientInfoForMetadata)(this);(0,y.setGlobalClientInfo)(e.clientName,e.clientVersion)
137
+ 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,j.getErrorMessage)(e)}),null}}extractClientInfoAfterConnection(){try{setTimeout((()=>{const e=(0,w.getClientInfoForMetadata)(this);(0,y.setGlobalClientInfo)(e.clientName,e.clientVersion)
138
138
  const t=(0,y.getGlobalClientInfo)()
139
- 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,R.getErrorMessage)(e)})}}setCurrentSSEConnection(e){this.currentSSEConnection=e}getServer(){return this.server}getCurrentGitInstance(){if(!this.workspaceManager)return this.git||void 0
139
+ 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,j.getErrorMessage)(e)})}}setCurrentSSEConnection(e){this.currentSSEConnection=e}getServer(){return this.server}getCurrentGitInstance(){if(!this.workspaceManager)return this.git||void 0
140
140
  const e=this.workspaceManager.getCurrentContext()
141
141
  return"multi-agent"===e.mode&&e.requestId?this.workspaceManager.getCurrentGit():this.git||void 0}getContext(){if(!this.workspaceManager)throw Error("WorkspaceManager not initialized")
142
142
  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+)-/)
143
- 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)}`}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")
143
+ 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,j.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")
144
144
  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=d.default.join(this.basePath,".alchemy_lab",".mcp-server.lock")
145
145
  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"}
146
146
  try{let t="request-"+e
147
147
  try{this.logger.debug("Attempting to fetch request title from API",{requestId:e})
148
148
  const r=this.apiClient.getRequestClient(),n=await r.getRequest(e)
149
- 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()
149
+ 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,j.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0})}const r=this.generateSessionId()
150
150
  this.logger.info("Creating worktree for request using WorkspaceManager",{requestId:e,requestTitle:t,sessionId:r}),await this.workspaceManager.ensureWorkspaceReady(e)
151
151
  const n=this.workspaceManager.getCurrentContext()
152
152
  this.git=(0,c.simpleGit)({baseDir:n.basePath,binary:this.gitBinary})
153
153
  try{const t=await k.getCurrentBranch(this.git,this.logger,this.metrics)
154
154
  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})
155
155
  const r=await k.switchToBranch(this.git,n.branchName,this.logger,this.metrics)
156
- 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)
156
+ 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,j.getErrorMessage)(t)
157
157
  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"}
158
158
  try{let t="request-"+e
159
159
  try{const r=this.apiClient.getRequestClient(),n=await r.getRequest(e)
160
- n&&n.title&&(t=n.title)}catch(t){this.logger.warn("Failed to fetch request title for branch switching",{requestId:e,error:(0,R.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)
160
+ n&&n.title&&(t=n.title)}catch(t){this.logger.warn("Failed to fetch request title for branch switching",{requestId:e,error:(0,j.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)
161
161
  const r={success:!0,message:"Workspace ready"}
162
162
  if(!r.success)return{success:!1,message:r.message||"Failed to switch to request workspace"}
163
163
  const n=this.workspaceManager.getCurrentContext()
164
164
  this.git=(0,c.simpleGit)({baseDir:n.basePath,binary:this.gitBinary})
165
165
  try{const t=await k.getCurrentBranch(this.git,this.logger,this.metrics)
166
- 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,R.getErrorMessage)(t)}),{success:!1,message:"Failed to switch to request context: "+(0,R.getErrorMessage)(t)}}}async getEffectiveBasePath(e){if(!this.multiAgentMode||!this.workspaceManager||!e)return this.basePath
166
+ 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,j.getErrorMessage)(t)}),{success:!1,message:"Failed to switch to request context: "+(0,j.getErrorMessage)(t)}}}async getEffectiveBasePath(e){if(!this.multiAgentMode||!this.workspaceManager||!e)return this.basePath
167
167
  const t=await this.workspaceManager.getWorkspaceInfo(e)
168
168
  return t?.path||this.basePath}}exports.McpServer=A
169
169
  const D=new Map},213(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
@@ -195,13 +195,13 @@ const w=[],k=a.toLowerCase()
195
195
  for(const e of y){const t=[]
196
196
  if("all"!==l&&"title"!==l||!e.title||e.title.toLowerCase().includes(k)&&t.push({request:e,matchType:"title",matchSnippet:r(e.title,a)}),"all"!==l&&"description"!==l||!e.description||e.description.toLowerCase().includes(k)&&t.push({request:e,matchType:"description",matchSnippet:n(e.description,k,150)}),("all"===l||"criteria"===l)&&e.acceptanceCriteria)for(const r of e.acceptanceCriteria){const o="string"==typeof r?r:r.description
197
197
  if(o&&o.toLowerCase().includes(k)){t.push({request:e,matchType:"criteria",matchSnippet:n(o,k,150)})
198
- break}}t.length>0&&w.push(t[0])}const I=g.limit||20,b=w.slice(0,I)
199
- if(0===b.length)return h({success:!0,resultCount:0}),{content:[{type:"text",text:`No requests found matching "${a}".\n\nSearched in: ${l}\nTotal requests checked: ${y.length}`}]}
200
- let v=`Found ${b.length} request${1===b.length?"":"s"} matching "${a}":\n\n`
201
- for(const e of b){const t=e.request,r=o(t.status)
198
+ break}}t.length>0&&w.push(t[0])}const b=g.limit||20,I=w.slice(0,b)
199
+ if(0===I.length)return h({success:!0,resultCount:0}),{content:[{type:"text",text:`No requests found matching "${a}".\n\nSearched in: ${l}\nTotal requests checked: ${y.length}`}]}
200
+ let v=`Found ${I.length} request${1===I.length?"":"s"} matching "${a}":\n\n`
201
+ for(const e of I){const t=e.request,r=o(t.status)
202
202
  v+=`${s(t.type)} **${t.title}** (${t.id}) ${r}\n`,v+=" \u{1f4cd} Match in "+e.matchType,e.matchSnippet&&(v+=": "+e.matchSnippet),v+="\n\n"}v+=`---\nSearched ${y.length} requests (filtered by: `
203
203
  const C=[]
204
- return g.status&&C.push("status="+g.status),g.type&&C.push("type="+g.type),g.dateFrom&&C.push("from="+g.dateFrom),g.dateTo&&C.push("to="+g.dateTo),v+=C.length>0?C.join(", "):"none",v+=")",h({success:!0,resultCount:b.length}),d.incrementCounter("search_requests_success",1),{content:[{type:"text",text:v}]}}catch(e){return u.error("Search requests failed",{error:e instanceof Error?e.stack:e+""}),h({success:!1,error:(0,a.getErrorMessage)(e)}),d.incrementCounter("search_requests_errors",1),{content:[{type:"text",text:"\u274c **Search Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
204
+ return g.status&&C.push("status="+g.status),g.type&&C.push("type="+g.type),g.dateFrom&&C.push("from="+g.dateFrom),g.dateTo&&C.push("to="+g.dateTo),v+=C.length>0?C.join(", "):"none",v+=")",h({success:!0,resultCount:I.length}),d.incrementCounter("search_requests_success",1),{content:[{type:"text",text:v}]}}catch(e){return u.error("Search requests failed",{error:e instanceof Error?e.stack:e+""}),h({success:!1,error:(0,a.getErrorMessage)(e)}),d.incrementCounter("search_requests_errors",1),{content:[{type:"text",text:"\u274c **Search Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
205
205
  const i=t(9860),a=t(8824)},260(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
206
206
  const r=t(6183),n=t(4221)
207
207
  exports.def={name:"view_asset",description:"View an image from the project's .alchemy_lab/assets/ folder. Returns the image so you can see it. Use this when you encounter asset:filename.png references in plans or documents and need to understand the image content.",schema:r.ViewAssetSchema,annotations:{title:"View Asset Image",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleViewAsset)(e,t.context,t.logger,t.metrics)}}},270(e,exports){Object.defineProperty(exports,"__esModule",{value:!0})},293(e,exports,t){function r(e){let t
@@ -258,14 +258,14 @@ throw p.error("Failed to check request lock status",{taskId:o,requestId:w.reques
258
258
  let k=d.git
259
259
  if(d.workspaceManager){const e=d.workspaceManager.getCurrentContext()
260
260
  if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
261
- k=simpleGit({baseDir:e.basePath,binary:d.gitBinary}),p.debug("Using workspace-aware git instance for task completion",{taskId:o,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let I=null
262
- if(k)try{(await k.status()).isClean()||(I=(await k.commit(`Complete task ${o}: ${h}`)).commit,p.info("Created commit for task completion",{taskId:o,commitId:I}))}catch(e){p.warn("Failed to commit changes",{error:(0,l.getErrorMessage)(e)})}let b=null
261
+ k=simpleGit({baseDir:e.basePath,binary:d.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
262
+ 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
263
263
  try{const e=u.getToolRecordClient()
264
- e&&(b={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:I,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:I,completionSummary:h,completionRecordId:b?.id,completedAt:t}},n=await y.updateTask(o,r)
265
- 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:b?.id})
264
+ 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)
265
+ 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})
266
266
  const i=w.requestId
267
267
  let a=`Task ${o} (${w.title}) has been marked as completed.`
268
- if(b?.id&&(a+=`\n[RECORD:${b.id}]`),I&&(a+="\nCommit: "+I.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
268
+ if(I?.id&&(a+=`\n[RECORD:${I.id}]`),b&&(a+="\nCommit: "+b.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
269
269
  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"})
270
270
  const t=(0,s.extractArrayFromResponse)(e,{logger:p,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
271
271
  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}),d.projectId)try{const r=u.getToolRecordClient()
@@ -328,9 +328,8 @@ t>0&&this.logger.debug("Cleaned up expired passwords",{count:t})}getActivePasswo
328
328
  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")})
329
329
  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){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
330
330
  const r=t(6183),n=t(8037),o=t(5218)
331
- 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)}}},715(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.setCachedSession=function(e){r.sessionIdentity.setIdentity(e)},exports.updateCachedSession=function(e){r.sessionIdentity.updateIdentity(e)},exports.getCachedSession=function(){return r.sessionIdentity.getIdentity()},exports.hasDiscoveryBeenAttempted=function(){return r.sessionIdentity.hasDiscoveryBeenAttempted()},exports.setDiscoveryAttempted=function(){r.sessionIdentity.markDiscoveryAttempted()},exports.resetDiscovery=function(){r.sessionIdentity.reset()},exports.buildCliOrigin=function(e){return r.sessionIdentity.buildCliOrigin(e)},exports.setCurrentCallCliOrigin=function(e){r.sessionIdentity.setCurrentCallOrigin(e)},exports.getGlobalCliOrigin=function(){return r.sessionIdentity.getCurrentCallOrigin()}
332
- const r=t(6688)},857(module){module.exports=require("os")},922(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ToolRecordClient=void 0
333
- const r=t(7645),n=t(1038),o=t(2161),s=t(5172),i=t(715)
331
+ 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){module.exports=require("os")},922(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ToolRecordClient=void 0
332
+ const r=t(7645),n=t(1038),o=t(2161),s=t(5172),i=t(6688)
334
333
  class a extends r.ConnectionAwareClient{constructor(e,t,r,n,o,s,i){const a=t.child({component:"tool-record-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(){}}
335
334
  super(e,a,r,o,i),this.setConnectionStatusManager(c),this.projectClient=n,this.logger.info("ToolRecordClient initialized",{baseUrl:e,hasAuthToken:!!o,options:JSON.stringify(i)})}async createToolRecord(e){if(this.logger.debug("Creating tool record",{record:e}),!e.projectId)throw this.logger.error("No project ID provided for creating tool record"),Error("Project ID is required for tool record creation")
336
335
  if(!e.type)throw this.logger.error("No record type provided for creating tool record"),Error("Record type is required for tool record creation")
@@ -339,7 +338,7 @@ try{const r=e.projectId||this.projectClient.getProjectId()
339
338
  if(!r)throw this.logger.error("No project ID available for creating tool record"),Error("Project ID is required for tool record operations")
340
339
  try{const a=`/api/projects/${r}/tool-records`
341
340
  this.logger.debug("Using tool record endpoint",{endpoint:a,projectId:r}),this.getAuthToken(),this.logger.info("Sending tool record to server",{endpoint:a,recordType:e.type,taskId:e.taskId,requestId:e.requestId})
342
- const c=(0,s.getGlobalClientInfo)(),l=(0,i.getGlobalCliOrigin)(),d={...e,...l&&{cliOrigin:l},metadata:{...e.metadata,clientName:c.clientName,clientVersion:c.clientVersion,sessionTag:c.sessionTag}},u=await this.requestWithRetry("POST",a,d)
341
+ const c=(0,s.getGlobalClientInfo)(),l=i.sessionIdentity.getCurrentCallOrigin(),d={...e,...l&&{cliOrigin:l},metadata:{...e.metadata,clientName:c.clientName,clientVersion:c.clientVersion,sessionTag:c.sessionTag}},u=await this.requestWithRetry("POST",a,d)
343
342
  this.logger.debug("Raw tool record creation response",{responseStatus:(0,o.isSuccessResponse)(u)?200:(0,o.isErrorResponse)(u)?u.error.statusCode:"unknown",responseData:(0,o.isSuccessResponse)(u)?JSON.stringify(u.data).substring(0,500):(0,o.isErrorResponse)(u)?JSON.stringify(u.error).substring(0,500):"unknown response format"})
344
343
  const h=(0,o.safeGetResponseData)(u,{})
345
344
  return t({success:!0}),this.metrics.incrementCounter("tool_record_creation_success",1),this.logger.info("Successfully created tool record",{recordId:h.id,type:h.type,taskId:h.task_id,requestId:h.request_id}),(0,n.adaptApiToolRecordToDomain)(h)}catch(s){if(404===this.extractErrorStatus(s)){this.logger.error("Tool record creation failed: Endpoint not found (404)",{endpoint:`/api/projects/${r}/tool-records`,error:this.getErrorMessage(s)})
@@ -458,21 +457,21 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
458
457
  var t={}
459
458
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
460
459
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
461
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerApiRoutes=async function(e,r,n,o){const s=n.child({component:"api"}),i=r.getTokenManager(),T=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com",P=new m.AuthenticationManager(i,n.child({component:"auth-manager"})),M=P.getTokenSynchronizer(),R=await P.getTokenString()||void 0
460
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerApiRoutes=async function(e,r,n,o){const s=n.child({component:"api"}),i=r.getTokenManager(),T=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com",P=new m.AuthenticationManager(i,n.child({component:"auth-manager"})),M=P.getTokenSynchronizer(),j=await P.getTokenString()||void 0
462
461
  n.debug("Token retrieved from authentication manager")
463
- const j=new k.ConnectionStatusManager(T,n.child({component:"connection-status-manager"}),o,{checkIntervalMs:3e4,timeoutMs:5e3}),x=new w.ProjectClient(T,n.child({component:"project-client"}),o,j,R)
462
+ const R=new k.ConnectionStatusManager(T,n.child({component:"connection-status-manager"}),o,{checkIntervalMs:3e4,timeoutMs:5e3}),x=new w.ProjectClient(T,n.child({component:"project-client"}),o,R,j)
464
463
  M.registerClient(x)
465
- const O=new b.TaskClient(T,n.child({component:"task-client"}),o,x,j,R)
464
+ const O=new I.TaskClient(T,n.child({component:"task-client"}),o,x,R,j)
466
465
  M.registerClient(O)
467
- const A=new v.FileOperationsClient(T,n.child({component:"file-client"}),o,x,R,j)
466
+ const A=new v.FileOperationsClient(T,n.child({component:"file-client"}),o,x,j,R)
468
467
  M.registerClient(A)
469
- const D=new C.ProxyClient(T,n.child({component:"proxy-client"}),o,x,R,j)
468
+ const D=new C.ProxyClient(T,n.child({component:"proxy-client"}),o,x,j,R)
470
469
  M.registerClient(D)
471
- const $=new _.RequestClient(T,n.child({component:"request-client"}),o,x,R,j)
472
- $.setAuthToken(R),(0,d.isDebugToolsEnabled)()&&n.debug("Explicitly set token on RequestClient",{tokenPresent:!!R}),M.registerClient($)
473
- const F=new E.DocumentClient(T,n.child({component:"document-client"}),o,x,R,j)
470
+ const $=new _.RequestClient(T,n.child({component:"request-client"}),o,x,j,R)
471
+ $.setAuthToken(j),(0,d.isDebugToolsEnabled)()&&n.debug("Explicitly set token on RequestClient",{tokenPresent:!!j}),M.registerClient($)
472
+ const F=new E.DocumentClient(T,n.child({component:"document-client"}),o,x,j,R)
474
473
  M.registerClient(F)
475
- const N=new q.ToolRecordClient(T,n.child({component:"tool-record-client"}),o,x,R,j)
474
+ const N=new q.ToolRecordClient(T,n.child({component:"tool-record-client"}),o,x,j,R)
476
475
  M.registerClient(N)
477
476
  const L=new S.ApiClient(P,x,O,A,$,F,N,D,n.child({component:"api-client"})),z=a.default.Router();(0,h.registerAuthRoutes)(z,{projectClient:x,taskClient:O,fileClient:A,authManager:P,apiClient:L},i,n)
478
477
  const B=r.getContext();(0,g.registerConfigRoutes)(z,n,B.basePath),e.use("/api",z)
@@ -488,9 +487,9 @@ if((0,d.isDebugToolsEnabled)()&&s.debug("Task validation response received",{tas
488
487
  let o=!1
489
488
  if("object"==typeof e&&null!==e){404===e.statusCode&&(o=!0),404===e.response?.statusCode&&(o=!0)
490
489
  const t=(e.message||e.error||e)+"";(t.includes("404")||t.toLowerCase().includes("not found"))&&(o=!0)}if(o)return s.info("Task ID not found - blocking operation",{taskId:n,statusCode:404,action:"blocking"}),t.status(400).json({success:!1,error:{code:"TASK_NOT_FOUND",message:"Task ID does not exist: "+n,retryable:!1,statusCode:400}})
491
- s.warn("Error validating task ID",{taskId:n,error:(0,I.getErrorMessage)(e)}),s.warn("Error validating task ID, but continuing as fallback",{taskId:n,action:"continuing"}),r()}}
490
+ s.warn("Error validating task ID",{taskId:n,error:(0,b.getErrorMessage)(e)}),s.warn("Error validating task ID, but continuing as fallback",{taskId:n,action:"continuing"}),r()}}
492
491
  e.get("/health",((e,t)=>{o.incrementCounter("api_requests_total",1,{endpoint:"health",method:"GET"}),t.json({success:!0,data:{status:"ok",version:"0.1.0",serverType:"mcp-local-server",timestamp:(new Date).toISOString()}})})),e.get("/mcp/sse",(async(e,t)=>{s.info("New SSE connection requested",{ip:e.ip,userAgent:e.headers["user-agent"]}),o.incrementCounter("mcp_connections_total",1,{type:"sse"})
493
- try{await r.createSseConnection(t,e.headers["user-agent"]),t.on("close",(()=>{s.info("SSE connection closed"),o.setGauge("mcp_active_connections",0,{type:"sse"}),r.cleanupSSEConnection()}))}catch(e){s.error("Failed to establish MCP SSE connection",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("mcp_connection_errors",1,{type:"sse",error:e instanceof Error?e.name:"unknown"}),t.headersSent?t.end():t.status(500).json({success:!1,error:"Failed to establish SSE connection",message:(0,I.getErrorMessage)(e)})}})),e.get("/api/files/exists",W,(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/exists",method:"GET"})
492
+ try{await r.createSseConnection(t,e.headers["user-agent"]),t.on("close",(()=>{s.info("SSE connection closed"),o.setGauge("mcp_active_connections",0,{type:"sse"}),r.cleanupSSEConnection()}))}catch(e){s.error("Failed to establish MCP SSE connection",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("mcp_connection_errors",1,{type:"sse",error:e instanceof Error?e.name:"unknown"}),t.headersSent?t.end():t.status(500).json({success:!1,error:"Failed to establish SSE connection",message:(0,b.getErrorMessage)(e)})}})),e.get("/api/files/exists",W,(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/exists",method:"GET"})
494
493
  const r=H("api_request_duration")
495
494
  try{const n=await l.default.stat(e.fullPath)
496
495
  r({endpoint:"files/exists",method:"GET",success:!0}),t.json({success:!0,data:{exists:!0,isDirectory:n.isDirectory(),isFile:n.isFile(),size:n.size,modified:n.mtime}})}catch(e){if("ENOENT"!==e.code)throw e
@@ -540,7 +539,7 @@ r.getContext(),s.info("Manual project synchronization requested"),s.info("Starti
540
539
  try{await x.syncProjects(),e({endpoint:"sync/projects",method:"POST",success:!0}),t.json({success:!0,data:{message:"Project synchronization completed successfully",timestamp:(new Date).toISOString()}})}catch(r){s.error("Project synchronization failed",{error:r instanceof Error?r.stack:r+""}),e({endpoint:"sync/projects",method:"POST",success:!1}),t.status(500).json({success:!1,error:"Project synchronization failed",message:r instanceof Error?r.message:r+"",timestamp:(new Date).toISOString()})}}catch(e){n(e)}})),e.get("/api/remote/status",(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"remote/status",method:"GET"})
541
540
  const e=H("api_request_duration")
542
541
  try{const r=await x.pingDetailed(),n="online"===r.status,o=r.latency
543
- e({endpoint:"remote/status",method:"GET",success:!0,connected:n}),s.info("Remote server status check",{status:n?"ONLINE":"OFFLINE",latencyMs:o}),t.json({success:!0,data:{connected:n,url:T,latency:o,queueStats:{total:0,pending:0,inProgress:0,completed:0,failed:0},isOffline:x.isOffline(),serverTime:(new Date).toISOString()}})}catch(r){e({endpoint:"remote/status",method:"GET",success:!0,connected:!1}),t.json({success:!0,data:{connected:!1,url:T,error:(0,I.getErrorMessage)(r),serverTime:(new Date).toISOString()}})}}catch(e){r(e)}})),e.get("/api/proxy/*",(async(e,t,r)=>{try{const r=e.path.substring(11)
542
+ e({endpoint:"remote/status",method:"GET",success:!0,connected:n}),s.info("Remote server status check",{status:n?"ONLINE":"OFFLINE",latencyMs:o}),t.json({success:!0,data:{connected:n,url:T,latency:o,queueStats:{total:0,pending:0,inProgress:0,completed:0,failed:0},isOffline:x.isOffline(),serverTime:(new Date).toISOString()}})}catch(r){e({endpoint:"remote/status",method:"GET",success:!0,connected:!1}),t.json({success:!0,data:{connected:!1,url:T,error:(0,b.getErrorMessage)(r),serverTime:(new Date).toISOString()}})}}catch(e){r(e)}})),e.get("/api/proxy/*",(async(e,t,r)=>{try{const r=e.path.substring(11)
544
543
  try{const n=await L.proxyGet(r,e.query)
545
544
  t.json(n)}catch(e){if(e instanceof Error&&e.message.includes("ECONNREFUSED"))return t.status(503).json({success:!1,error:"Remote server is unreachable",remotePath:r})
546
545
  throw e}}catch(e){r(e)}})),e.post("/api/proxy/*",U,(async(e,t,r)=>{try{const r=e.path.substring(11)
@@ -550,7 +549,7 @@ throw e}}catch(e){r(e)}})),e.patch("/api/proxy/*",U,(async(e,t,r)=>{try{const r=
550
549
  try{const n=await L.proxyPatch(r,e.body)
551
550
  t.json(n)}catch(e){if(e instanceof Error&&e.message.includes("ECONNREFUSED"))return t.status(503).json({success:!1,error:"Remote server is unreachable",remotePath:r})
552
551
  throw e}}catch(e){r(e)}}))}
553
- const a=i(t(7252)),c=i(t(6928)),l=i(t(1943)),d=t(3444),u=t(9860),h=t(6776),g=t(6476),p=t(3306),f=t(4079),m=t(3895),y=s(t(5967)),w=t(4710),k=t(5681),I=t(8824),b=t(2968),v=t(6153),C=t(1887),_=t(1666),E=t(9884),q=t(922),S=t(3328)},1253(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
552
+ const a=i(t(7252)),c=i(t(6928)),l=i(t(1943)),d=t(3444),u=t(9860),h=t(6776),g=t(6476),p=t(3306),f=t(4079),m=t(3895),y=s(t(5967)),w=t(4710),k=t(5681),b=t(8824),I=t(2968),v=t(6153),C=t(1887),_=t(1666),E=t(9884),q=t(922),S=t(3328)},1253(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
554
553
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.TokenManager=void 0
555
554
  const n=r(t(6928)),o=r(t(1943)),s=r(t(6982)),i=r(t(857)),a=t(9067),c=t(8824),l="alchemy-lab"
556
555
  exports.TokenManager=class{constructor(e,t,r={}){this.projectId=null,this.encryptionKey=null,this.pendingAuthCheck=!1,this.tempAuthCode=null,this.CACHE_TTL_MS=6e4,this.TOKEN_CACHE={manualToken:null,encryptedToken:null,hasValidToken:null},this.initPromise=null,this.initialized=!1,this.logger=e.child({component:"token-manager"}),this.remoteServerUrl=r.remoteServerUrl||"https://api.alchemylabcode.com",this.allowInteractiveAuth=!1!==r.allowInteractiveAuth,void 0!==r.cacheTtlMs&&r.cacheTtlMs>0&&(this.CACHE_TTL_MS=r.cacheTtlMs),this.serverInstallDir=this.getModuleDir(),this.tokenDirPath=this.serverInstallDir,this.authFlow=new a.ExternalAuthFlow(e,this.remoteServerUrl),this.logger.info("TokenManager initialized",{workingDir:t,serverInstallDir:this.serverInstallDir,tokenDirPath:this.tokenDirPath,allowInteractiveAuth:this.allowInteractiveAuth,cacheTtlMs:this.CACHE_TTL_MS}),this.generateEncryptionKey()}getModuleDir(){const e=__dirname||process.cwd(),t=i.default.homedir()
@@ -614,18 +613,18 @@ const r=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Co
614
613
  if(r.ok){const e=await r.json()
615
614
  return this.logger.info("Token validation successful",{status:e.status||"unknown",username:e.username||"unknown"}),!0}return this.logger.info("Token validation failed - token may be invalid or expired",{status:r.status,statusText:r.statusText}),this.invalidateCache(),!1}catch(e){return e instanceof Error&&"AbortError"===e.name?(this.logger.info("Token validation request timed out - assuming offline or server unavailable"),!0):(this.logger.info("Token validation request failed",{error:(0,c.getErrorMessage)(e)}),!0)}}async hasValidAndWorkingToken(){return!!await this.hasValidToken()&&await this.validateTokenWithRemoteServer()}async isGoogleOAuthAvailable(){return await this.authFlow.isGoogleOAuthAvailable()}async startGoogleOAuthFlow(){return await this.authFlow.startGoogleOAuthFlow()}async startGoogleOAuthPolling(e,t,r,n,o){return await this.authFlow.startGoogleOAuthPolling(e,t,r,n,o)}}},1281(e,exports,t){async function r(e,t,o,s,i,a,c,l,d,u=0){let p=0,f=0,m=0
616
615
  const y=[]
617
- if(o.length>=b||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:b,depth:c}),{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}
616
+ if(o.length>=I||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:I,depth:c}),{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}
618
617
  try{const w=await g.default.readdir(e,{withFileTypes:!0}),v=[],C=[]
619
618
  for(const t of w){const r=h.default.join(e,t.name)
620
- if(t.isDirectory()){if(I.includes(t.name)||t.name.startsWith(".")){a.debug("Skipping excluded directory: "+t.name)
619
+ if(t.isDirectory()){if(b.includes(t.name)||t.name.startsWith(".")){a.debug("Skipping excluded directory: "+t.name)
621
620
  continue}C.push({entry:t,fullPath:r})}else if(t.isFile()){if("*"!==i&&!t.name.endsWith(i)){a.debug("Skipping file due to extension mismatch",{filename:t.name,requiredExtension:i})
622
621
  continue}v.push({entry:t,fullPath:r})}}if(v.length>0){const e=[]
623
622
  for(let t=0;t<v.length;t+=16)e.push(v.slice(t,t+16))
624
- for(const r of e){if(o.length>=b)break
623
+ for(const r of e){if(o.length>=I)break
625
624
  const e=await Promise.all(r.map((({entry:e,fullPath:r})=>n(r,t,0,o,l,d,e.name,u))))
626
625
  for(const t of e){p++,t.hasMatches&&f++
627
- for(const e of t.matches){if(o.length>=b)return{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}
628
- o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=b)break
626
+ for(const e of t.matches){if(o.length>=I)return{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}
627
+ o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=I)break
629
628
  m++
630
629
  const e={path:n,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
631
630
  try{const l=await r(n,t,o,s,i,a,c+1,e,d,u)
@@ -636,7 +635,7 @@ let l,d=!1
636
635
  const u=async()=>{if(void 0===l)try{const t=await g.default.stat(e)
637
636
  l=t.mtime.getTime()}catch(e){l=void 0}return l}
638
637
  if("filename"!==s&&"both"!==s||t.test(i)&&(d=!0,await u(),c.push({file:e,line:0,text:i,modifiedTime:l,matchType:"filename"})),"content"===s||"both"===s)try{const r=(await g.default.readFile(e,"utf8")).split("\n")
639
- for(let o=0;o<r.length&&n.length<b;o++)if(t.test(r[o])){d=!0,await u()
638
+ for(let o=0;o<r.length&&n.length<I;o++)if(t.test(r[o])){d=!0,await u()
640
639
  const t={file:e,line:o+1,text:(0,y.truncate)(r[o].trim(),120),modifiedTime:l,matchType:"content"}
641
640
  if(a>0){const e=Math.max(0,o-a)
642
641
  t.contextBefore=r.slice(e,o).map((e=>(0,y.truncate)(e.trim(),120)))
@@ -663,29 +662,29 @@ var t={}
663
662
  if(null!=e)for(var r=a(e),n=0;n<r.length;n++)"default"!==r[n]&&c(t,e,r[n])
664
663
  return l(t,e),t}),u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
665
664
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearch=async function(e,t,n,a,c){const l=a.child({tool:"search"}),d=c.startTimer("tool_execution_time"),u=Date.now()
666
- let I=0
667
- const b={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:p.default.hostname(),username:p.default.userInfo().username,workingDirectory:process.cwd(),contextBasePath:t?.basePath||"unknown"},startTime:u,endTime:0,phases:{initializationTime:0,searchTime:0,directoryListingTime:0},totalFiles:0,totalMatches:0,directoryStats:[],errors:[]}
665
+ let b=0
666
+ const I={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:p.default.hostname(),username:p.default.userInfo().username,workingDirectory:process.cwd(),contextBasePath:t?.basePath||"unknown"},startTime:u,endTime:0,phases:{initializationTime:0,searchTime:0,directoryListingTime:0},totalFiles:0,totalMatches:0,directoryStats:[],errors:[]}
668
667
  try{const{needle:n,directory:p,options:v={}}=e
669
668
  if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,w.handleListDirectory)({path:p||".",levels:v.levels||1,sortBy:v.sortBy||"name"},t,a,c)
670
- if("string"!=typeof n)throw b.errors.push("Search term (needle) must be a string"),(0,f.createValidationError)("Search term (needle) must be a string")
669
+ if("string"!=typeof n)throw I.errors.push("Search term (needle) must be a string"),(0,f.createValidationError)("Search term (needle) must be a string")
671
670
  let C
672
- if(b.searchDirectory=p||".",p){const{normalizedPath:e,fullPath:r}=m.validateAndNormalizePath(p,t)
671
+ if(I.searchDirectory=p||".",p){const{normalizedPath:e,fullPath:r}=m.validateAndNormalizePath(p,t)
673
672
  C=r}else C=t.basePath
674
- b.resolvedPath=C
673
+ I.resolvedPath=C
675
674
  let _=!1
676
675
  try{_=(await g.default.stat(C)).isFile()}catch(e){const t=`Cannot access path ${C}: ${(0,k.getErrorMessage)(e)}`
677
- throw b.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,T=v.fileExtension,P=v.searchIn||"content"
676
+ throw I.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,T=v.fileExtension,P=v.searchIn||"content"
678
677
  let M=void 0!==v.contextLines?v.contextLines:0
679
- if(0>M?M=0:M>10&&(l.warn(`contextLines ${M} exceeds maximum of 10, clamping to 10`),M=10),!_&&!T)throw b.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")')
680
- let R,j=""
681
- if(_)j="*"
682
- else if("*"===T)j="*"
683
- else if(T){let e=T;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),j=e.startsWith(".")?e:"."+e}try{R=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)}`
684
- throw b.errors.push(t),(0,f.createValidationError)(t)}if(b.patternInfo={needle:n,regex:R.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:j},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
678
+ if(0>M?M=0:M>10&&(l.warn(`contextLines ${M} exceeds maximum of 10, clamping to 10`),M=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")')
679
+ let j,R=""
680
+ if(_)R="*"
681
+ else if("*"===T)R="*"
682
+ else if(T){let e=T;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),R=e.startsWith(".")?e:"."+e}try{j=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)}`
683
+ throw I.errors.push(t),(0,f.createValidationError)(t)}if(I.patternInfo={needle:n,regex:j.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:R},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
685
684
  for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
686
- b.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},b.phases.directoryListingTime=b.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,k.getErrorMessage)(e)
687
- b.errors.push(t),l.error(t)}const x=_?"file":"directory"
688
- l.info(`Searching for "${n}" in ${x} ${C} (mode: ${P})`,{needle:n,searchTarget:x,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:j,searchIn:P}}),I=Date.now(),b.phases.initializationTime=I-u
685
+ 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)
686
+ I.errors.push(t),l.error(t)}const x=_?"file":"directory"
687
+ l.info(`Searching for "${n}" in ${x} ${C} (mode: ${P})`,{needle:n,searchTarget:x,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:R,searchIn:P}}),b=Date.now(),I.phases.initializationTime=b-u
689
688
  const O=Date.now()
690
689
  let A=[],D=0,$=0
691
690
  try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,p=[]
@@ -703,15 +702,15 @@ o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
703
702
  const f={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
704
703
  try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,p,a,o,s,0,f,l,u)
705
704
  return f.filesProcessed=n,f.filesMatched=c,f.subdirectories=d,i.directoryStats.push(f),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:p.length,directories:d+1}),{matches:p,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,k.getErrorMessage)(t)
706
- 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,R,{maxResults:E,fileExtension:j,searchIn:P,isFile:_,contextLines:M},j,l,b)
705
+ 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,j,{maxResults:E,fileExtension:R,searchIn:P,isFile:_,contextLines:M},R,l,I)
707
706
  A=e.matches,D=e.totalFiles
708
707
  const t=1e3
709
708
  A.length>0&&A.length<=t?(A.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 ${A.length} matches by modification time (newest first)`)):A.length>t&&l.info(`Skipped sorting ${A.length} matches (exceeds hard cap of ${t} for performance)`),$=A.length,A.length>E&&(A=A.slice(0,E),l.info(`Limited results to ${E} (from ${$} total matches)`)),A.forEach((e=>{e.relativePath=function(e,t){const r=h.default.relative(e,t)
710
- 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 ${A.length} results`),b.phases.searchTime=Date.now()-O}catch(e){const t="Error during search: "+(0,k.getErrorMessage)(e)
711
- b.errors.push(t),l.error(t),b.phases.searchTime=Date.now()-O}b.totalFiles=D,b.totalMatches=A.length,b.endTime=Date.now()
709
+ 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 ${A.length} results`),I.phases.searchTime=Date.now()-O}catch(e){const t="Error during search: "+(0,k.getErrorMessage)(e)
710
+ I.errors.push(t),l.error(t),I.phases.searchTime=Date.now()-O}I.totalFiles=D,I.totalMatches=A.length,I.endTime=Date.now()
712
711
  let F,N=""
713
712
  try{if(t.getCurrentBranchContext){const e=await t.getCurrentBranchContext()
714
- 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:b})
713
+ 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})
715
714
  const L="content"===P?"content":"filename"===P?"filenames":"content and filenames"
716
715
  if($>A.length?(F=`Found ${$} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=`${N}. Showing first ${A.length}:\n\n`):(F=`Found ${A.length} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=N+":\n\n"),A.length>0)if(M>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
717
716
  if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
@@ -734,10 +733,10 @@ void 0!==s&&(a+=` (${s} lines)`),a+=` - ${o} ${1===o?"match":"matches"}:`
734
733
  const c=t.map((e=>` :${e.line} - ${e.text}`))
735
734
  n.push(a+"\n"+c.join("\n"))}return n.join("\n\n")}(A)
736
735
  else F+="No matches found."
737
- return d({success:!0}),{content:[{type:"text",text:F}]}}catch(t){l.error("Search failed",{args:e,error:t instanceof Error?t.stack:t+""}),b.errors.push((0,k.getErrorMessage)(t)),b.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:b})
736
+ return d({success:!0}),{content:[{type:"text",text:F}]}}catch(t){l.error("Search failed",{args:e,error:t instanceof Error?t.stack:t+""}),I.errors.push((0,k.getErrorMessage)(t)),I.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:I})
738
737
  let r="Search failed: "+(0,k.getErrorMessage)(t)
739
738
  return d({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:r}],isError:!0}}}
740
- const h=u(t(6928)),g=u(t(1943)),p=u(t(857)),f=t(9860),m=d(t(5967)),y=t(5967),w=t(2537),k=t(8824),I=["node_modules"],b=1e4,v=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore"]),C=1048576},1318(e,exports,t){async function r(e,t,r){try{const r=(await e.revparse(["--show-toplevel"])).trim(),n=c.default.isAbsolute(t)?t:c.default.resolve(t)
739
+ const h=u(t(6928)),g=u(t(1943)),p=u(t(857)),f=t(9860),m=d(t(5967)),y=t(5967),w=t(2537),k=t(8824),b=["node_modules"],I=1e4,v=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore"]),C=1048576},1318(e,exports,t){async function r(e,t,r){try{const r=(await e.revparse(["--show-toplevel"])).trim(),n=c.default.isAbsolute(t)?t:c.default.resolve(t)
741
740
  return c.default.relative(r,n)}catch(e){return r.warn("Failed to get repo-relative path, using original",{filePath:t,error:(0,l.getErrorMessage)(e)}),t}}function n(e){return/\(trec\d{6}\)/.test(e)}async function o(e,t,n,o,s){try{const i=await r(e,t,s),a=await e.raw(["log","-1","--pretty=format:%H|%s",`-L${n},${o}:${i}`])
742
741
  if(!a||""===a.trim())return null
743
742
  const c=a.trim().split("\n")[0],[l,...d]=c.split("|"),u=d.join("|")
@@ -813,37 +812,34 @@ try{return await i.hasValidToken()}catch(e){return m.error("Error checking authe
813
812
  m.info(`Generating tools list with testsRequired=${e}, authenticated=${t}`)
814
813
  const r={testsRequired:e,authenticated:t}
815
814
  return(0,f.generateVisibleToolsList)(r)}
816
- let I=k(),b=[]
817
- I.then((e=>{b=e})).catch((e=>{m.error("Error generating initial tools list",{error:(0,l.getErrorMessage)(e)}),b=[]})),e.setRequestHandler(a.ListToolsRequestSchema,(async()=>{try{return b=await k(),{tools:b}}catch(e){return m.error("Error generating tools list",{error:(0,l.getErrorMessage)(e)}),{tools:[]}}}))
815
+ let b=k(),I=[]
816
+ b.then((e=>{I=e})).catch((e=>{m.error("Error generating initial tools list",{error:(0,l.getErrorMessage)(e)}),I=[]})),e.setRequestHandler(a.ListToolsRequestSchema,(async()=>{try{return I=await k(),{tools:I}}catch(e){return m.error("Error generating tools list",{error:(0,l.getErrorMessage)(e)}),{tools:[]}}}))
818
817
  let v=!1
819
818
  e.setRequestHandler(a.CallToolRequestSchema,(async e=>{try{const{name:i,arguments:a={},_meta:c}=e.params;(0,p.logSessionIdentity)(i,"_meta-debug",{has_meta:!!c,sessionId:c?.sessionId||null,messageId:c?.messageId||null,paramKeys:Object.keys(e.params)}),m.info("Tool call received: "+i,{tool:i}),s.incrementCounter("tool_calls_total",1,{tool:i})
820
819
  const k=s.startTimer("tool_execution_time")
821
820
  Date.now()
822
- let I=Date.now()
823
- const b=r(a)
824
- if(Date.now(),I=Date.now(),y){const e=await w()
821
+ let b=Date.now()
822
+ const I=r(a)
823
+ if(Date.now(),b=Date.now(),y){const e=await w()
825
824
  if(Date.now(),!e)return m.warn("Unauthenticated tool call attempt",{tool:i}),{content:[{type:"text",text:"Authentication required. Please run 'alchemylab setup' to authenticate and configure your project."}],isError:!0}}const C=(0,f.getToolByName)(i)
826
- if(I=Date.now(),n?(n.setOptions({createRecords:C?.createsRecords??!1}),m.info(`Setting record creation for tool ${i}: ${C?.createsRecords??!1}`)):m.debug(`No API client available for tool ${i} (minimal mode)`),Date.now(),I=Date.now(),t?.workspaceManager&&!t.workspaceManager.readonlyBranchCheckDone)try{const e=await(0,d.getServerUrl)(t,m)
827
- e&&n&&await t.workspaceManager.ensureReadonlyBranchIfNeeded(e,i,n,c?.sessionId)}catch(e){m.debug("Error during readonly branch check",{error:(0,l.getErrorMessage)(e)})}let _,E
828
- if(Date.now(),Date.now(),I=Date.now(),C&&!C.readOnly)if(c?.sessionId){const e=c.sessionId,r=c.messageId,n=u.sessionIdentity.getIdentity()
829
- if(n)n.sessionId!==e&&((0,p.logSessionIdentity)(i,"_meta-session-switch",{prevSessionId:n.sessionId,prevAgentType:n.agentType,newSessionId:e}),u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:n.serverUrl}))
825
+ let _
826
+ if(b=Date.now(),n?(n.setOptions({createRecords:C?.createsRecords??!1}),m.info(`Setting record creation for tool ${i}: ${C?.createsRecords??!1}`)):m.debug(`No API client available for tool ${i} (minimal mode)`),Date.now(),Date.now(),b=Date.now(),c?.sessionId){const e=c.sessionId,r=c.messageId,n=u.sessionIdentity.getIdentity()
827
+ if(n)n.sessionId!==e&&((0,p.logSessionIdentity)(i,"_meta-session-switch",{prevSessionId:n.sessionId,prevAgentType:n.agentType,newSessionId:e}),u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:n.serverUrl}),t?.workspaceManager?.resetCurrentContext?.(e))
830
828
  else{const r=await(0,d.getServerUrl)(t,m)
831
- u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r||""}),u.sessionIdentity.markDiscoveryAttempted()}_={providerId:"opencode",sessionId:e,messageId:r,createdAt:(new Date).toISOString()},(0,p.logSessionIdentity)(i,"_meta",{sessionId:e,messageId:r})}else{const e=u.sessionIdentity.getIdentity()
832
- if(e){let r,n=!1
833
- try{r=await(0,d.findMessageIdForTool)(e.serverUrl,e.sessionId,i)}catch{n=!0}if(r)_=u.sessionIdentity.buildCliOrigin(r)
834
- else if(n)_=u.sessionIdentity.buildCliOrigin()
835
- else{m.info("Session identity mismatch: tool call not found in cached session, re-discovering",{prevSessionId:e.sessionId,prevAgentType:e.agentType,tool:i}),u.sessionIdentity.reset(),t?.workspaceManager?.resetCurrentContext?.()
836
- try{const t=await(0,d.getAndStoreSessionId)(e.serverUrl,m,i)
837
- t?(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e.serverUrl}),(0,p.logSessionIdentity)(i,"re-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId)):(u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),m.info("Re-discovery found no other session, keeping current identity",{sessionId:e.sessionId})),u.sessionIdentity.markDiscoveryAttempted()}catch(t){u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),u.sessionIdentity.markDiscoveryAttempted(),m.warn("Re-discovery failed, keeping current identity (may be stale)",{error:(0,l.getErrorMessage)(t),tool:i,sessionId:e.sessionId})}}}else if(!u.sessionIdentity.hasDiscoveryBeenAttempted())try{const e=await(0,d.getServerUrl)(t,m)
838
- if(e){const t=await(0,d.getAndStoreSessionId)(e,m,i)
839
- t&&(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e}),(0,p.logSessionIdentity)(i,"http-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId))}u.sessionIdentity.markDiscoveryAttempted()}catch(e){u.sessionIdentity.markDiscoveryAttempted(),(0,p.logSessionIdentity)(i,"discovery-failed",{error:(0,l.getErrorMessage)(e)}),m.debug("cliOrigin discovery failed",{error:(0,l.getErrorMessage)(e),tool:i})}}if(u.sessionIdentity.setCurrentCallOrigin(_),!v&&n){const e=u.sessionIdentity.getIdentity(),t=process.env.ALCHEMY_INITIAL_BRANCH
829
+ u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r||""})}_={providerId:"opencode",sessionId:e,messageId:r,createdAt:(new Date).toISOString()},(0,p.logSessionIdentity)(i,"_meta",{sessionId:e,messageId:r})}else m.warn("No _meta.sessionId on tool call \u2014 session identity unavailable",{tool:i})
830
+ u.sessionIdentity.setCurrentCallOrigin(_)
831
+ const E=_?.sessionId||c?.sessionId
832
+ if(t?.workspaceManager){b=Date.now()
833
+ try{const e=await(0,d.getServerUrl)(t,m)
834
+ e&&n&&await t.workspaceManager.ensureReadonlyBranchIfNeeded(e,i,n,E)}catch(e){m.debug("Error during workspace check",{error:(0,l.getErrorMessage)(e)})}Date.now()}if(!v&&n){const e=u.sessionIdentity.getIdentity(),t=process.env.ALCHEMY_INITIAL_BRANCH
840
835
  if(e?.sessionId&&t){const r=t.match(/^requests\/(.+)$/),o="1"===process.env.ALCHEMY_ALLOW_PARALLEL
841
836
  if(r&&!o){const t=r[1]
842
837
  v=!0
843
838
  try{const{sessionTag:r}=(0,h.getGlobalClientInfo)(),o=n.getSessionTagMappingClient(),s=n.getRequestClient(),i=o?o.getMappingByOpencodeSessionId(e.sessionId).then((t=>{t?((0,h.setSessionTag)(t.sessionTag),m.info("Recovered session tag from mapping",{opencodeSessionId:e.sessionId,sessionTag:t.sessionTag})):(o.createOrUpdateMapping(r,e.sessionId).catch((()=>{})),m.info("Registered session tag mapping",{opencodeSessionId:e.sessionId,sessionTag:r}))}),(e=>m.debug("Mapping lookup failed",{error:(0,l.getErrorMessage)(e)}))):Promise.resolve(),a=s.lockRequest?s.lockRequest(t,r).then((e=>{e.locked?m.info("Acquired request lock",{requestId:t,sessionTag:r}):m.warn("Failed to acquire request lock",{requestId:t,sessionTag:r})}),(e=>m.warn("Lock acquisition failed",{error:(0,l.getErrorMessage)(e)}))):Promise.resolve()
844
- await Promise.all([i,a])}catch(e){m.warn("Error in session tag mapping / lock acquisition",{error:(0,l.getErrorMessage)(e)})}}}}if(C){const e={context:t,apiClient:n,logger:o,metrics:s,mcpServer:g,cliOrigin:_}
845
- E=await C.handler(b,e)}else m.info(`Tool ${i} not found, returning negative response`),E={content:[{type:"text",text:`The tool '${i}' does not exist.`}]}
846
- return Date.now(),Date.now(),k({tool:i,success:!0}),E}catch(t){m.error("Error executing tool:",{error:t instanceof Error?t.stack:t+"",tool:e.params.name}),s.incrementCounter("tool_errors_total",1,{tool:e.params.name,error:t instanceof Error?t.name:"unknown"})
839
+ await Promise.all([i,a])}catch(e){m.warn("Error in session tag mapping / lock acquisition",{error:(0,l.getErrorMessage)(e)})}}}}let q
840
+ if(C){const e={context:t,apiClient:n,logger:o,metrics:s,mcpServer:g,cliOrigin:_}
841
+ q=await C.handler(I,e)}else m.info(`Tool ${i} not found, returning negative response`),q={content:[{type:"text",text:`The tool '${i}' does not exist.`}]}
842
+ return Date.now(),Date.now(),k({tool:i,success:!0}),q}catch(t){m.error("Error executing tool:",{error:t instanceof Error?t.stack:t+"",tool:e.params.name}),s.incrementCounter("tool_errors_total",1,{tool:e.params.name,error:t instanceof Error?t.name:"unknown"})
847
843
  let r="Unknown error"
848
844
  if(t instanceof Error)r=t.message
849
845
  else if("string"==typeof t)r=t
@@ -1180,94 +1176,92 @@ const e=this.online,t=await this.performHealthCheck()
1180
1176
  return e!==t&&(t?(this.logger.info("Health check status changed to ONLINE"),this.options.onOnlineCallback()):(this.logger.info("Health check status changed to OFFLINE"),this.options.onOfflineCallback())),t}isOffline(){return this.forcedOfflineMode||!1}scheduleNextCheck(e=this.options.checkIntervalMs){this.checkInterval&&(clearInterval(this.checkInterval),this.checkInterval=null),0!==e?setTimeout((()=>{this.performHealthCheck().catch((()=>{}))}),e||this.options.checkIntervalMs||3e4):this.performHealthCheck().catch((()=>{}))}setOfflineMode(e){const t=this.forcedOfflineMode
1181
1177
  this.forcedOfflineMode=e,t!==e&&(this.logger.info("Offline mode "+(e?"ENABLED":"DISABLED")),this.metrics.setGauge("health_check_forced_offline",e?1:0),e||this.scheduleNextCheck(0))}getStats(){return{consecutiveFailures:this.consecutiveFailures,currentBackoffMs:this.currentBackoffMs,lastCheckTime:this.lastCheckTime}}}},1722(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
1182
1178
  const r=t(6183),n=t(355)
1183
- 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){function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,S.join)(e.basePath||process.cwd(),".alchemy_lab","spawn-debug.log");(0,q.appendFileSync)(o,n)}catch{}}async function n(e){try{const t=`http://localhost:${M}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
1179
+ 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){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:${j}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
1184
1180
  if(!r.ok)return null
1185
1181
  const n=await r.json()
1186
1182
  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:d=!1,useExistingSession:u}=e
1187
- if(r(t,"handleSpawn called",{agent:a,promptLength:c.length,requestId:l,useExistingSession:u,cliOriginSessionId:i?.sessionId||null}),!(0,T.isValidAgent)(a)){const e=(0,T.getAgentNames)()
1188
- 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=(0,b.getCachedSession)(),n=i?.sessionId||e?.sessionId
1189
- let o=e?.agentType
1190
- if(r(t,"Spawn agent type check",{cliOriginSessionId:i?.sessionId||null,cachedSessionId:e?.sessionId||null,cachedAgentType:e?.agentType||null,pid:process.pid,envSessionTag:process.env.ALCHEMY_SESSION_TAG||null,envInitialBranch:process.env.ALCHEMY_INITIAL_BRANCH||null}),!o&&n)try{const e=`http://localhost:${M}/api/sessions/${encodeURIComponent(n)}/agent-type`
1191
- r(t,"Looking up agent type from action server",{sessionId:n,url:e})
1192
- const s=await fetch(e)
1193
- if(s.ok){const e=await s.json()
1194
- r(t,"Agent type response from action server",{sessionId:n,agentType:e.agentType||null,source:e.source||null,success:e.success}),e.success&&e.agentType&&(o=e.agentType,(0,b.updateCachedSession)({agentType:o}))}else r(t,"Agent type lookup failed",{sessionId:n,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e?.sessionId,error:(0,E.getErrorMessage)(n)})}if(o){const e=(0,T.getAllowedSubagents)(o)
1195
- if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${o}' cannot spawn '${a}'.\n\n**Allowed subagents for ${o}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,E.getErrorMessage)(e)})}let h
1183
+ if(r(t,"handleSpawn called",{agent:a,promptLength:c.length,requestId:l,useExistingSession:u,cliOriginSessionId:i?.sessionId||null}),!(0,P.isValidAgent)(a)){const e=(0,P.getAgentNames)()
1184
+ 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
1185
+ let n=v.sessionIdentity.getIdentity()?.agentType
1186
+ if(r(t,"Spawn agent type check",{callerSessionId:e||null,cachedAgentType:n||null,pid:process.pid}),!n&&e)try{const o=`http://localhost:${j}/api/sessions/${encodeURIComponent(e)}/agent-type`
1187
+ r(t,"Looking up agent type from action server",{sessionId:e,url:o})
1188
+ const s=await fetch(o)
1189
+ if(s.ok){const o=await s.json()
1190
+ 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,P.getAllowedSubagents)(n)
1191
+ 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
1196
1192
  try{const e=await n(a)
1197
- if(h=e?.requestContextMode,!h){const e=(0,T.getBuiltInAgentConfig)(a)
1193
+ if(h=e?.requestContextMode,!h){const e=(0,P.getBuiltInAgentConfig)(a)
1198
1194
  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}
1199
1195
  const g=await(0,I.getServerUrl)(t,o)
1200
1196
  r(t,"serverUrl resolved",{serverUrl:g})
1201
1197
  const p=t.basePath
1202
1198
  if(!p)throw new w.ValidationError("Working directory not available in context")
1203
- const f=(0,b.getCachedSession)()
1204
- let m
1205
- if(g)try{m=i?.sessionId||f?.sessionId||await(0,I.discoverParentSessionId)(g,o)}catch{}let y=""
1199
+ const f=i?.sessionId
1200
+ let m=""
1206
1201
  if(s&&l)try{const e=s.getSessionRequestAssociationClient()
1207
- if(e){const t=await e.getSessionsForRequest(l,!0),r=m?t.filter((e=>e.opencodeSessionId!==m)):t
1202
+ if(e){const t=await e.getSessionsForRequest(l,!0),r=f?t.filter((e=>e.opencodeSessionId!==f)):t
1208
1203
  if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
1209
1204
  if(!d)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}
1210
- y=`\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,E.getErrorMessage)(e)})}let C,_,q=c
1211
- l&&(C="requests/"+l,r(t,"Setting initialBranch for agent",{agent:a,requestId:l,initialBranch:C,agentRequestContextMode:h||"undefined"}),q="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}`)
1205
+ 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
1206
+ 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}`)
1212
1207
  let S=!1
1213
1208
  if(u){if(_=u,o.info("Using existing session for spawn",{sessionId:_,requestId:l}),!g)throw new w.ValidationError("Could not determine OpenCode server URL")
1214
1209
  try{let e
1215
- try{const t=await fetch(`http://localhost:${M}/api/project-settings`)
1210
+ try{const t=await fetch(`http://localhost:${j}/api/project-settings`)
1216
1211
  if(t.ok){const r=await t.json()
1217
1212
  if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
1218
- 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:q}],...a?{agent:a}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
1213
+ 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)})
1219
1214
  if(!r.ok){const e=await r.text().catch((()=>"Unknown error"))
1220
- 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,E.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")
1221
- const i=m||f?.sessionId||await(0,I.discoverParentSessionId)(g,o);(0,v.logSessionIdentity)("subagent_operations.spawn",m?"early-discovery":f?"_meta":"http-discovery",{parentSessionId:i}),r(t,"Parent session discovered",{parentSessionId:i})
1222
- const u=g.replace(/\/$/,"")+"/session",h=e.title?e.title:l?`[${l}] ${c.slice(0,40)}${c.length>40?"...":""}`:`${c.slice(0,50)}${c.length>50?"...":""}`,y=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentID:i,title:h})})
1223
- if(!y.ok)throw Error("Failed to create session: "+y.status)
1224
- const w=await y.json()
1215
+ 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")
1216
+ const i=f;(0,C.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:i}),r(t,"Parent session discovered",{parentSessionId:i})
1217
+ const u=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(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentID:i,title:h})})
1218
+ if(!m.ok)throw Error("Failed to create session: "+m.status)
1219
+ const w=await m.json()
1225
1220
  if(!w.id)throw Error("Session created but no ID returned")
1226
- const R=w.id
1227
- r(t,"Pre-created session with parentID",{preCreatedSessionId:R,parentSessionId:i}),o.info("Pre-created session with parentID",{preCreatedSessionId:R,parentSessionId:i})
1228
- const j=(async()=>{if(s)try{const n=s.getCLISessionClient()
1221
+ const I=w.id
1222
+ r(t,"Pre-created session with parentID",{preCreatedSessionId:I,parentSessionId:i}),o.info("Pre-created session with parentID",{preCreatedSessionId:I,parentSessionId:i})
1223
+ const T=(async()=>{if(s)try{const n=s.getCLISessionClient()
1229
1224
  if(!n)return
1230
1225
  let o,c
1231
- if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:(0,b.getCachedSession)()?.agentType||void 0})
1232
- 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:R,providerId:"opencode",parentSessionId:o||null,title:h,status:"active",agentType:a,specialization:e.specialization,workflowId:c||void 0})
1233
- r(t,"Registered child session in DB",{childSessionId:R,childDbId:l.id,parentDbId:o})}catch(e){r(t,"Failed to register sessions in DB",{error:(0,E.getErrorMessage)(e)}),o.warn("Failed to register sessions in alchemy DB",{error:(0,E.getErrorMessage)(e)})}})()
1234
- let x
1226
+ if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:v.sessionIdentity.getIdentity()?.agentType||void 0})
1227
+ 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})
1228
+ 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)})}})()
1229
+ let R
1235
1230
  r(t,"Starting model resolution",{agent:a,cwd:p})
1236
- try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${M}/api/agents/by-name/${a}`})
1231
+ try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${j}/api/agents/by-name/${a}`})
1237
1232
  const e=await n(a)
1238
1233
  if(r(t,"Agent config result",{agent:a,agentConfig:e||"null",hasConfig:!!e}),e){const n=e.preferredProvider||"inherit",o=e.preferredModelTier||"same"
1239
1234
  r(t,"Agent preferences",{agent:a,preferredProvider:n,preferredTier:o,rawProvider:e.preferredProvider,rawTier:e.preferredModelTier})
1240
- const s=(0,P.resolveAgentModel)(p,n,o)
1241
- 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,T.getBuiltInAgentConfig)(a)
1235
+ const s=(0,M.resolveAgentModel)(p,n,o)
1236
+ r(t,"Model resolution result",{agent:a,result:s}),s.resolved?(R=s.fullModel,r(t,"Resolved agent model",{agent:a,model:R,preferredProvider:n,preferredTier:o})):r(t,"Model resolution fallback",{agent:a,reason:s.reason})}else{const e=(0,P.getBuiltInAgentConfig)(a)
1242
1237
  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"
1243
1238
  r(t,"Using built-in agent preferences",{agent:a,preferredProvider:n,preferredTier:o})
1244
- const s=(0,P.resolveAgentModel)(p,n,o)
1245
- 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,E.getErrorMessage)(e)})}try{const e=await async function(){try{const e=`http://localhost:${M}/api/project-settings`,t=await fetch(e)
1239
+ const s=(0,M.resolveAgentModel)(p,n,o)
1240
+ r(t,"Built-in model resolution result",{agent:a,result:s}),s.resolved&&(R=s.fullModel,r(t,"Resolved built-in agent model",{agent:a,model:R,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:${j}/api/project-settings`,t=await fetch(e)
1246
1241
  if(t.ok){const e=await t.json()
1247
1242
  return e?.data?.defaultModel||null}}catch{}return null}()
1248
- if(e)if(x){const o=await n(a)
1249
- "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,E.getErrorMessage)(e)})}r(t,"Final resolved model before spawn",{agent:a,resolvedModel:x||"undefined (will use default)"}),await j
1250
- const O=(0,k.spawnDetachedSubagent)({agent:a,prompt:q,cwd:p,sessionId:R,model:x,initialBranch:C,allowParallel:d,serverUrl:g})
1251
- if(!O.success)throw Error("Failed to spawn subagent: "+O.error)
1252
- _=R,r(t,"CLI spawn successful with pre-created session",{sessionId:R,pid:O.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:R,pid:O.pid,parentSessionId:i})}if(s&&l&&_&&"unknown"!==_&&"spawning"!==_)try{const e=s.getSessionRequestAssociationClient()
1253
- 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,E.getErrorMessage)(e),sessionId:_,requestId:l}))),"coder"===a)){const e=s.getRequestClient()
1254
- e&&e.updateRequest(l,{cliOrigin:{providerId:"opencode",sessionId:_,createdAt:(new Date).toISOString()}}).catch((e=>o.debug("Failed to update request cliOrigin",{error:(0,E.getErrorMessage)(e)})))}}catch(e){o.warn("Failed to create session-request association",{error:(0,E.getErrorMessage)(e),sessionId:_,requestId:l})}let R=y
1255
- return u?R+=`Prompt sent to existing session ${_}.`:(R+=`Background ${a} subagent spawned successfully.`,_&&"unknown"!==_&&"spawning"!==_&&(R+=`\n[SESSION:${_}]`)),l&&(R+="\nWorking on: "+l),R+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:R}]}}async function s(e,t,r,n,o,s,i){const a=await(0,I.getServerUrl)(r,n)
1243
+ if(e)if(R){const o=await n(a)
1244
+ "same"===(o?.preferredModelTier||"same")&&(R=e,r(t,"Applied user default model (same tier)",{agent:a,userDefaultModel:e}))}else R=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:R||"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 x=(0,k.spawnDetachedSubagent)({agent:a,prompt:E,cwd:p,sessionId:I,model:R,initialBranch:y,allowParallel:d,serverUrl:g})
1245
+ if(!x.success)throw Error("Failed to spawn subagent: "+x.error)
1246
+ _=I,r(t,"CLI spawn successful with pre-created session",{sessionId:I,pid:x.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:I,pid:x.pid,parentSessionId:i})}if(s&&l&&_&&"unknown"!==_&&"spawning"!==_)try{const e=s.getSessionRequestAssociationClient()
1247
+ 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()
1248
+ 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
1249
+ return u?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)
1256
1250
  if(!a)throw new w.ValidationError("Could not determine OpenCode server URL")
1257
- if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId||(0,b.getCachedSession)()?.sessionId||await(0,I.discoverParentSessionId)(a,n)
1251
+ if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId
1258
1252
  if(t){const r=o.getCLISessionClient()
1259
1253
  if(r){let o=await r.getByExternalId(t)
1260
- 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,E.getErrorMessage)(e)})}let c=s
1261
- if(!c)try{const t=`http://localhost:${M}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
1254
+ 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
1255
+ if(!c)try{const t=`http://localhost:${j}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
1262
1256
  if(r.ok){const e=await r.json()
1263
1257
  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.`)
1264
1258
  try{let r
1265
- try{const e=await fetch(`http://localhost:${M}/api/project-settings`)
1259
+ try{const e=await fetch(`http://localhost:${j}/api/project-settings`)
1266
1260
  if(e.ok){const t=await e.json()
1267
1261
  if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
1268
1262
  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)})
1269
1263
  if(!s.ok){const e=await s.text().catch((()=>"Unknown error"))
1270
- 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,E.getErrorMessage)(e))}}function i(e){const t=Math.floor(e/1e3)
1264
+ 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)
1271
1265
  if(60>t)return t+"s"
1272
1266
  const r=Math.floor(t/60)
1273
1267
  return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function a(e){const t=[]
@@ -1277,7 +1271,7 @@ const s=n.path||n.file||n.directory,i=n.needle||n.query||n.pattern
1277
1271
  "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))
1278
1272
  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
1279
1273
  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
1280
- return e&&R>n?{status:"working",detail:"last action "+c(n),isReady:!1}:n>j&&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 d(e){let t=0,r=0,n=0
1274
+ return e&&R>n?{status:"working",detail:"last action "+c(n),isReady:!1}:n>x&&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 d(e){let t=0,r=0,n=0
1281
1275
  for(const o of e.trim().split("\n")){if(!o)continue
1282
1276
  const[e,s]=o.split("\t")
1283
1277
  "-"!==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 s=await(0,I.getServerUrl)(r,n)
@@ -1290,7 +1284,7 @@ let f={input:0,output:0,reasoning:0},m="",y=l(null,h.time.updated)
1290
1284
  if(p.ok){const e=await p.json()
1291
1285
  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)
1292
1286
  const t=a(e)
1293
- 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,I=y.isReady,b=f.input+f.output+f.reasoning
1287
+ 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
1294
1288
  let v="",C="",_=null
1295
1289
  if(o)try{const t=o.getSessionRequestAssociationClient()
1296
1290
  if(t){const r=await t.getActiveRequestsForSession(e,!1)
@@ -1305,12 +1299,12 @@ if(e.trim())return d(e)}try{const t=n(`git log main --merges --oneline -n 50 --g
1305
1299
  if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
1306
1300
  if(o.trim())return{...d(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
1307
1301
  if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
1308
- 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: ${I?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${b.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,E.getErrorMessage)(e))}}async function h(e,t,r){const n=await(0,I.getServerUrl)(t,r)
1302
+ 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)
1309
1303
  if(!n)throw new w.ValidationError("Could not determine OpenCode server URL")
1310
1304
  r.info("Aborting subagent session",{sessionId:e})
1311
1305
  try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
1312
1306
  if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
1313
- 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,E.getErrorMessage)(e))}}async function g(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:c,minTokens:d,maxTokens:u,maxAgeHours:h}=n,g=await(0,I.getServerUrl)(e,t)
1307
+ 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:d,maxTokens:u,maxAgeHours:h}=n,g=await(0,I.getServerUrl)(e,t)
1314
1308
  if(!g)throw new w.ValidationError("Could not determine OpenCode server URL")
1315
1309
  t.info("Listing sessions",{filters:n})
1316
1310
  try{const e=g.replace(/\/$/,"")+"/session",t=await fetch(e)
@@ -1324,10 +1318,10 @@ if(o&&(w=w.filter((e=>"idle"!==(y[e.id]?.type||"idle")))),void 0!==h){const e=36
1324
1318
  w=w.filter((e=>e.time.created>=t))}if(0===w.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
1325
1319
  let k={}
1326
1320
  if(r)try{const e=r.getCLISessionClient()
1327
- e&&(k=await e.batchEnrich(w.map((e=>e.id))))}catch{}const I=g.replace(/\/$/,""),b=await Promise.allSettled(w.map((e=>fetch(`${I}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),v=[]
1321
+ 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=[]
1328
1322
  for(let e=0;e<w.length;e++){const t=w[e],r=Date.now()-t.time.created
1329
1323
  let o=0,i=null,c=[],h=l(null,t.time.updated)
1330
- const g=b[e],p="fulfilled"===g.status?g.value:[]
1324
+ const g=I[e],p="fulfilled"===g.status?g.value:[]
1331
1325
  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))
1332
1326
  if(p.length>0){const e=a(p)
1333
1327
  h=l(e.lastActivityTime,t.time.updated),i=e.current||null,c=e.recent}const f=h.status
@@ -1337,16 +1331,16 @@ const m=k[t.id]
1337
1331
  if(n.agentType&&(!m||m.agentType!==n.agentType))continue
1338
1332
  if("archived"===m?.status)continue
1339
1333
  let y=""
1340
- const I=[]
1334
+ const b=[]
1341
1335
  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))
1342
- I.push(...e,...t)
1336
+ b.push(...e,...t)
1343
1337
  const r=[]
1344
- e.length>0&&r.push("active: "+e.join(", ")),t.length>0&&r.push("prev: "+t.join(", ")),r.length>0&&(y=` [${r.join(" | ")}]`)}if(s&&!I.includes(s))continue
1338
+ 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
1345
1339
  const C=t.title||"Untitled",_=C.length>50?C.slice(0,47)+"...":C
1346
- v.push({id:t.id,title:_,status:f,age:r,totalTokens:o,requestsInfo:y,allRequestIds:I,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."}]}
1340
+ 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."}]}
1347
1341
  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(", "):""
1348
1342
  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})`:""
1349
- 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,E.getErrorMessage)(e))}}var p,f=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
1343
+ 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)
1350
1344
  var o=Object.getOwnPropertyDescriptor(t,r)
1351
1345
  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=[]
1352
1346
  for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
@@ -1356,7 +1350,7 @@ if(null!=e)for(var r=p(e),n=0;n<r.length;n++)"default"!==r[n]&&f(t,e,r[n])
1356
1350
  return m(t,e),t})
1357
1351
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=o,exports.handleContinue=s,exports.handleCheckStatus=u,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")
1358
1352
  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)
1359
- const r=_.validateArgs(e,C.SubagentOperationsSchema),{sessionId:d,operation:p}=r
1353
+ const r=E.validateArgs(e,_.SubagentOperationsSchema),{sessionId:d,operation:p}=r
1360
1354
  let f
1361
1355
  switch(c.info("Processing subagent_operations",{operation:p,sessionId:d}),p){case"spawn":f=await o(r.spawn,t,c,i,a)
1362
1356
  break
@@ -1376,13 +1370,13 @@ throw Error("Failed to fetch messages: "+n.status)}const s=await n.json()
1376
1370
  if(0===s.length)return{content:[{type:"text",text:`Session ${e} has no messages yet.`}]}
1377
1371
  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
1378
1372
  return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n${o}`})).join("\n\n---\n\n")
1379
- return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,E.getErrorMessage)(e))}}(d,e,t,c)
1373
+ 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))}}(d,e,t,c)
1380
1374
  break
1381
- 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||(0,b.getCachedSession)()?.sessionId}
1375
+ 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}
1382
1376
  f=await g(t,c,i,n)
1383
1377
  break
1384
- 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,E.getErrorMessage)(e)}],isError:!0}}}
1385
- const w=t(9860),k=t(8035),I=t(7617),b=t(715),v=t(7280),C=t(6183),_=y(t(5967)),E=t(8824),q=t(9896),S=t(6928),T=t(8955),P=t(5671),M=3456,R=6e4,j=3e5},1791(e,exports,t){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}}
1378
+ 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}}}
1379
+ 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),P=t(8955),M=t(5671),j=3456,R=6e4,x=3e5},1791(e,exports,t){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}}
1386
1380
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
1387
1381
  const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
1388
1382
  exports.ProjectContext=class{constructor(e,t){this.projectId=null,this.initialized=!1,this.initializationInProgress=!1,this.initializationPromise=null,this.basePath=e,this.alchemyPath=s.default.join(e,i.ALCHEMY_DIR_NAME),this.projectFilePath=s.default.join(this.alchemyPath,"project.json"),this.logger=t.child({component:"project-context"}),this.logger.debug("Project context constructed",{basePath:this.basePath,alchemyPath:this.alchemyPath,projectFilePath:this.projectFilePath})}initialize(){return this.initialized&&this.projectId?(this.logger.info("Project context already initialized",{projectId:this.projectId}),Promise.resolve(this.projectId)):this.initializationInProgress&&this.initializationPromise?(this.logger.info("Project context initialization already in progress, reusing promise"),this.initializationPromise):(this.initializationInProgress=!0,this.logger.debug("Starting initialization",{basePath:this.basePath}),this.initializationPromise=this.doInitialize(),this.initializationPromise)}async doInitialize(){try{if(o.default.existsSync(this.alchemyPath))this.logger.debug("alchemy_lab directory already exists")
@@ -1673,26 +1667,26 @@ var t={}
1673
1667
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
1674
1668
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
1675
1669
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,t,r,n,o,s,i,f){const m=s.child({tool:"move_files"}),y=Date.now()
1676
- let w,k,I=d.FileOperationPhase.VALIDATION
1677
- const b={toolName:"move-files",operationName:"write",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"move-files",metricsPrefix:"move_files",successMessage:"Successfully moved files",failureMessage:"Failed to move files"}
1670
+ let w,k,b=d.FileOperationPhase.VALIDATION
1671
+ const I={toolName:"move-files",operationName:"write",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"move-files",metricsPrefix:"move_files",successMessage:"Successfully moved files",failureMessage:"Failed to move files"}
1678
1672
  try{const s=d.validateArgs(e,l.MoveFilesSchema),{taskId:u,operations:h,comment:v}=s
1679
1673
  if(m.info("Moving multiple files and directories",{taskId:u,operationCount:h.length,comment:v}),!h||0===h.length)throw Error("At least one move operation must be specified")
1680
- d.validateTaskIdFormat(u,m,i,b.metricsPrefix)
1674
+ d.validateTaskIdFormat(u,m,i,I.metricsPrefix)
1681
1675
  const C=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
1682
1676
  m.info("Initial branch context",{initialBranch:C.branch,initialRequestId:C.requestId,isMain:C.isMain})
1683
1677
  const _=[]
1684
1678
  for(const e of h){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.source,t),{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(e.destination,t)
1685
- _.push({source:r,destination:o,fullSource:n,fullDestination:s})}I=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("move_files_phase",1,{phase:I})
1686
- const E=await d.validateTaskId(u,_[0].source,r,m,i,b.metricsPrefix),q=E?.requestId,S=await d.validateWorkItemStates(u,_[0].source,r,o,t,m,i,b.metricsPrefix),T=await d.autoPromoteTaskStatus(u,E.status,q,S.request?.status,_[0].source,r,o,m,i,b.metricsPrefix)
1679
+ _.push({source:r,destination:o,fullSource:n,fullDestination:s})}b=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("move_files_phase",1,{phase:b})
1680
+ const E=await d.validateTaskId(u,_[0].source,r,m,i,I.metricsPrefix),q=E?.requestId,S=await d.validateWorkItemStates(u,_[0].source,r,o,t,m,i,I.metricsPrefix),T=await d.autoPromoteTaskStatus(u,E.status,q,S.request?.status,_[0].source,r,o,m,i,I.metricsPrefix)
1687
1681
  T.taskPromoted&&m.info(`Auto-promoted task ${u} (${E.title||"Untitled"}) to in_progress for file operations`,{taskId:u,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:u})
1688
- const P=await d.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:b.metricsPrefix})
1682
+ const P=await d.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:I.metricsPrefix})
1689
1683
  if(!P.success){if(P.isLockConflict)return{content:[{type:"text",text:"\u274c "+P.error}],isError:!0}
1690
1684
  throw Error(P.error)}let M={hadUserMods:!1,userModsCommitHash:void 0}
1691
1685
  if(t.git)try{m.debug("[MOVE-FILES] Checking for user changes before move operations")
1692
1686
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"move-files",{requestId:q,taskId:u,workspaceManager:t.workspaceManager},m,i)
1693
- 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:u,moveOperationsCount:_.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),M={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:u,moveOperationsCount:_.length,error:e instanceof Error?e.message:e+""})}m.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:_.length}),I=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("move_files_phase",1,{phase:I})
1694
- const{toolRecordId:R,localToolRecordId:j}=await d.createFileOperationRecords(u,q,t.projectId,b.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},r,n,m,i,b.metricsPrefix,f)
1695
- w=R,k=R,I=b.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:I})
1687
+ 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:u,moveOperationsCount:_.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),M={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:u,moveOperationsCount:_.length,error:e instanceof Error?e.message:e+""})}m.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:_.length}),b=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("move_files_phase",1,{phase:b})
1688
+ const{toolRecordId:j,localToolRecordId:R}=await d.createFileOperationRecords(u,q,t.projectId,I.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},r,n,m,i,I.metricsPrefix,f)
1689
+ w=j,k=j,b=I.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:b})
1696
1690
  const x=[]
1697
1691
  let O=0
1698
1692
  for(const e of _){const t={operation:{source:e.source,destination:e.destination},success:!1}
@@ -1702,24 +1696,32 @@ const n=c.default.dirname(e.fullDestination)
1702
1696
  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})}x.push(t)}const A=Date.now()-y
1703
1697
  i.recordValue("move_files_time",A),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)
1704
1698
  let D=null
1705
- if(O>0){I=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:I})
1699
+ if(O>0){b=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:b})
1706
1700
  const e=x.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}`
1707
- D=await d.commitToGit(u,_[0].destination,R,j,r,t,m,i,b.metricsPrefix)}I=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:I})
1701
+ D=await d.commitToGit(u,_[0].destination,j,R,r,t,m,i,I.metricsPrefix)}b=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:b})
1708
1702
  const $=x.filter((e=>e.success)),F=x.filter((e=>!e.success))
1709
- await d.updateFileOperationRecords(u,w,k,_[0].source,b.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:$.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:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,r,n,m,i,b.metricsPrefix)
1703
+ await d.updateFileOperationRecords(u,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:$.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:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,r,n,m,i,I.metricsPrefix)
1710
1704
  const N=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
1711
1705
  let L=""
1712
1706
  if(O===h.length)L=`Successfully moved all ${h.length} ${1===h.length?"item":"items"}`
1713
1707
  else if(O>0){const e=x.filter((e=>!e.success))
1714
1708
  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"+x.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")
1715
1709
  return D?.commitHash&&(L+="\nCommit: "+D.commitHash.substring(0,8)),N.requestId&&(L+="\nBranch: "+N.requestId),P.lockAcquired&&P.lockedRequestId&&(L+="\n\u{1f512} **Locked request:** "+P.lockedRequestId),{content:[{type:"text",text:L}],isError:0===O}}catch(o){if(e.taskId&&n)try{const r=o instanceof u.NotFoundError||o instanceof u.ValidationError||o instanceof h.ZodError
1716
- 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:I,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
1717
- 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){I=d.FileOperationPhase.RECORD_UPDATE_FAILURE
1718
- try{await d.updateFileOperationRecords(e.taskId,w,k,e.operations?.[0]?.source||"unknown",b.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,b.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 d.handleFileOperationError(o,I,m,i,e,b)}}
1719
- const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(7478),p=t(8824)},2422(module){module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
1710
+ 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
1711
+ 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=d.FileOperationPhase.RECORD_UPDATE_FAILURE
1712
+ try{await d.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 d.handleFileOperationError(o,b,m,i,e,I)}}
1713
+ const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(7478),p=t(8824)},2422(module){module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2424(e,exports,t){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)
1714
+ if((0,r.existsSync)(l))return void i.info("Worktree already exists on disk, skipping pre-spawn creation",{requestId:t,worktreePath:l})
1715
+ const d=(0,o.simpleGit)(e);(0,r.mkdirSync)(c,{recursive:!0})
1716
+ try{await d.raw(["worktree","prune"])}catch{}const u=await d.branch(),h=u.all.includes(a)
1717
+ try{if(h)await d.raw(["worktree","add",l,a]),i.info("Pre-spawn: created worktree for existing branch",{requestId:t,branchName:a,worktreePath:l})
1718
+ else{const e=u.all.includes("main")?"main":"master"
1719
+ await d.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+""
1720
+ i.warn("Pre-spawn: failed to create worktree (MCP process will retry)",{requestId:t,error:r})}}
1721
+ const r=t(9896),n=t(6928),o=t(3807),s=t(4139)},2425(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
1720
1722
  const r=t(6183),n=t(3707)
1721
1723
  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){Object.defineProperty(exports,"__esModule",{value:!0})
1722
- 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),d=t(8045),u=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),I=t(6111),b=t(700),v=t(2783),C=t(2601),_=t(1722),E=t(7257),q=t(9230),S=t(5216),T=t(6473),P=t(4921),M=t(8850),R=t(3556),j=t(1391),x=t(6315),O=t(7713),A=t(6252),D=t(213),$=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),W=t(5247),U=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)(d.def),(0,r.registerTool)(u.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)(I.def),(0,r.registerTool)(b.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)(P.def),(0,r.registerTool)(M.def),(0,r.registerTool)(R.def),(0,r.registerTool)(j.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(A.def),(0,r.registerTool)(D.def),(0,r.registerTool)($.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)(W.testingDefs),(0,r.registerTools)(U.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){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){async function r(e,t,r){if(C.has(r)&&_>=t){if(0===t)return 0
1724
+ 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),d=t(8045),u=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),P=t(4921),M=t(8850),j=t(3556),R=t(1391),x=t(6315),O=t(7713),A=t(6252),D=t(213),$=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),W=t(5247),U=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)(d.def),(0,r.registerTool)(u.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)(P.def),(0,r.registerTool)(M.def),(0,r.registerTool)(j.def),(0,r.registerTool)(R.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(A.def),(0,r.registerTool)(D.def),(0,r.registerTool)($.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)(W.testingDefs),(0,r.registerTools)(U.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){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){async function r(e,t,r){if(C.has(r)&&_>=t){if(0===t)return 0
1723
1725
  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]"
1724
1726
  let l=""
1725
1727
  if(s||void 0===o?.lineCount||(l=` (${i(o.lineCount)} lines)`),s&&o?.subtreeTotals){const{files:e,lines:t}=o.subtreeTotals
@@ -1735,14 +1737,14 @@ if(30>s)return`${s} day${1===s?"":"s"} ago`
1735
1737
  const i=Math.floor(s/30)
1736
1738
  if(12>i)return`${i} month${1===i?"":"s"} ago`
1737
1739
  const a=Math.floor(i/12)
1738
- return`${a} year${1===a?"":"s"} ago`}(o.modified)} | ${(0,b.formatTimestamp)(o.modified)})`)
1740
+ return`${a} year${1===a?"":"s"} ago`}(o.modified)} | ${(0,I.formatTimestamp)(o.modified)})`)
1739
1741
  break
1740
1742
  case"size":s||"number"!=typeof o.size||(l+=` (${function(e){if(0===e)return"0 bytes"
1741
1743
  let t=e,r=0
1742
1744
  for(;t>=1024&&4>r;)t/=1024,r++
1743
1745
  return`${0===r?t.toString():t.toFixed(10>t?1:0)}${["bytes","KB","MB","GB","TB"][r]}`}(o.size)})`)}return`${c} ${a}${l}`}async function o(e,t,n=0,s,i,l){if(n>=s)return[]
1744
- try{const{fullPath:d}=I.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),g=[]
1745
- for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=I.validateAndNormalizePath(u,t),p=await y.default.stat(h),f=d.isFile()?w.default.extname(d.name).toLowerCase():""
1746
+ try{const{fullPath:d}=b.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),g=[]
1747
+ for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=b.validateAndNormalizePath(u,t),p=await y.default.stat(h),f=d.isFile()?w.default.extname(d.name).toLowerCase():""
1746
1748
  let m
1747
1749
  d.isFile()&&(m=await r(h,p.size,f))
1748
1750
  const k={name:d.name,isDirectory:d.isDirectory(),depth:n,size:p.size,modified:p.mtime,extension:f,lineCount:m}
@@ -1751,8 +1753,8 @@ const o=[]
1751
1753
  return e.forEach(((i,a)=>{const c=a===e.length-1,l=c?"\u2514\u2500\u2500 ":"\u251c\u2500\u2500 ",d=n(i,t),u=i.isDirectory?"/":""
1752
1754
  if(o.push(`${r}${l}${d}${u}`),i.children&&i.children.length>0){const e=r+(c?" ":"\u2502 "),n=s(i.children,t,e)
1753
1755
  n&&o.push(n)}})),o.join("\n")}function i(e){return e.toLocaleString()}async function a(e,t,n){const o={files:0,directories:0,lines:0}
1754
- try{const{fullPath:n}=I.validateAndNormalizePath(e,t),s=await y.default.readdir(n,{withFileTypes:!0})
1755
- for(const n of s)try{const s=w.default.join(e,n.name).replace(/\\/g,"/"),{fullPath:i}=I.validateAndNormalizePath(s,t)
1756
+ try{const{fullPath:n}=b.validateAndNormalizePath(e,t),s=await y.default.readdir(n,{withFileTypes:!0})
1757
+ for(const n of s)try{const s=w.default.join(e,n.name).replace(/\\/g,"/"),{fullPath:i}=b.validateAndNormalizePath(s,t)
1756
1758
  if(n.isDirectory())o.directories+=1
1757
1759
  else{o.files+=1
1758
1760
  const e=await y.default.stat(i),t=w.default.extname(n.name).toLowerCase(),s=await r(i,e.size,t)
@@ -1778,27 +1780,27 @@ var t={}
1778
1780
  if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&g(t,e,r[n])
1779
1781
  return p(t,e),t}),m=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
1780
1782
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
1781
- let g=I.FileOperationPhase.VALIDATION
1782
- I.FileOperationPhase.FILE_WRITE
1783
- try{const p=I.validateArgs(e,k.ListDirectorySchema),{path:f,levels:m=1,sortBy:b="name"}=p
1783
+ let g=b.FileOperationPhase.VALIDATION
1784
+ b.FileOperationPhase.FILE_WRITE
1785
+ try{const p=b.validateArgs(e,k.ListDirectorySchema),{path:f,levels:m=1,sortBy:I="name"}=p
1784
1786
  i.info("Listing directory: "+f)
1785
- const{normalizedPath:C,fullPath:_}=I.validateAndNormalizePath(f,t)
1786
- g=I.FileOperationPhase.FILE_WRITE
1787
+ const{normalizedPath:C,fullPath:_}=b.validateAndNormalizePath(f,t)
1788
+ g=b.FileOperationPhase.FILE_WRITE
1787
1789
  try{if(!(await y.default.stat(_)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+f}],isError:!0}
1788
1790
  await y.default.access(_,y.default.constants.R_OK)}catch(e){return e instanceof Error&&"ENOENT"===e.code?{content:[{type:"text",text:"Directory does not exist: "+f}],isError:!0}:e instanceof Error&&"EACCES"===e.code?{content:[{type:"text",text:"Directory not accessible: "+f}],isError:!0}:{content:[{type:"text",text:"Cannot access directory: "+f}],isError:!0}}let E,q
1789
- if(m>1){i.info(`Building tree structure for: ${C} (levels: ${m}, sortBy: ${b})`)
1790
- const e=await o(C,t,0,m,b,i)
1791
- if(e.length>0){const t=s(e,b)
1791
+ if(m>1){i.info(`Building tree structure for: ${C} (levels: ${m}, sortBy: ${I})`)
1792
+ const e=await o(C,t,0,m,I,i)
1793
+ if(e.length>0){const t=s(e,I)
1792
1794
  E=`Directory tree for ${C} (${m} levels):\n${l(c(e))}\n\n${t}`,q=d(e)}else E=`Directory ${C} is empty or inaccessible.`,q=0}else{const e=await y.default.readdir(_,{withFileTypes:!0}),o=[]
1793
- for(const n of e)try{const e=w.default.join(C,n.name).replace(/\\/g,"/"),{fullPath:s}=I.validateAndNormalizePath(e,t),i=await y.default.stat(s),a=n.isFile()?w.default.extname(n.name).toLowerCase():""
1795
+ for(const n of e)try{const e=w.default.join(C,n.name).replace(/\\/g,"/"),{fullPath:s}=b.validateAndNormalizePath(e,t),i=await y.default.stat(s),a=n.isFile()?w.default.extname(n.name).toLowerCase():""
1794
1796
  let c
1795
- n.isFile()&&(c=await r(s,i.size,a)),o.push({name:n.name,isDirectory:n.isDirectory(),depth:0,size:i.size,modified:i.mtime,extension:a,lineCount:c})}catch(e){i.debug("Excluding directory entry from listing: "+n.name,{reason:(0,v.getErrorMessage)(e)})}const s=u(o,b),a=s.map((e=>n({name:e.name,isDirectory(){return e.isDirectory},isFile(){return!e.isDirectory}},b,e)))
1797
+ n.isFile()&&(c=await r(s,i.size,a)),o.push({name:n.name,isDirectory:n.isDirectory(),depth:0,size:i.size,modified:i.mtime,extension:a,lineCount:c})}catch(e){i.debug("Excluding directory entry from listing: "+n.name,{reason:(0,v.getErrorMessage)(e)})}const s=u(o,I),a=s.map((e=>n({name:e.name,isDirectory(){return e.isDirectory},isFile(){return!e.isDirectory}},I,e)))
1796
1798
  E=a.length>0?`Directory listing for ${C}:\n${l(c(s))}\n\n${a.join("\n")}`:`Directory ${C} is empty.`,q=s.length}const S=t.workspaceManager?.getCurrentContext()
1797
1799
  E+="\n\nBranch: "+(S?.branchName||"unknown")
1798
1800
  const T=Date.now()-h
1799
1801
  return a.recordValue("list_directory_time",T),a.recordValue("list_directory_entries",q),a.incrementCounter("list_directory_success",1),i.info("Successfully listed directory: "+C,{entryCount:q,levels:m,time:T}),{content:[{type:"text",text:E}]}}catch(e){const t=Date.now()-h
1800
1802
  return a.recordValue("list_directory_time",t),a.incrementCounter("list_directory_errors",1),i.error("Error listing directory:",{error:(0,v.getErrorMessage)(e),time:t}),{content:[{type:"text",text:(0,v.getErrorMessage)(e)}],isError:!0}}}
1801
- const y=m(t(1943)),w=m(t(6928)),k=t(6183),I=f(t(5967)),b=t(3253),v=t(8824),C=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore",".config",".conf",".ini",".cfg"]),_=1048576},2568(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
1803
+ const y=m(t(1943)),w=m(t(6928)),k=t(6183),b=f(t(5967)),I=t(3253),v=t(8824),C=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore",".config",".conf",".ini",".cfg"]),_=1048576},2568(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
1802
1804
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectSynchronizer=void 0
1803
1805
  const n=r(t(6928)),o=t(8029),s=t(8824),i=t(2096)
1804
1806
  exports.ProjectSynchronizer=class{constructor(e,t,r,n,o={}){this.logger=e.child({component:"project-synchronizer"}),this.registry=t,this.remoteApi=r,this.fileSystem=n,this.options={createRemoteProjects:o.createRemoteProjects??!0,maxRetryAttempts:o.maxRetryAttempts??3,retryDelayMs:o.retryDelayMs??1e3},this.logger.info("ProjectSynchronizer initialized",{options:this.options})}async ensureProjectExists(e){const t=Math.random().toString(36).substring(2,8)
@@ -1977,11 +1979,11 @@ const f=await Promise.all(p)
1977
1979
  let m=""
1978
1980
  if(t.getCurrentBranchContext)try{const e=await t.getCurrentBranchContext()
1979
1981
  e.branch&&(m=`**Current Branch:** ${e.branch}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const y=f.filter((e=>e.success)).length,w=f.filter((e=>!e.success)).length,k=f.length
1980
- let I="## Read Files/Documents\n\n"
1981
- m&&(I+=m),I+=`**Total Requests:** ${k} - **Successful:** ${y} - **Failed:** ${w}\n\n`
1982
+ let b="## Read Files/Documents\n\n"
1983
+ m&&(b+=m),b+=`**Total Requests:** ${k} - **Successful:** ${y} - **Failed:** ${w}\n\n`
1982
1984
  for(let e=0;e<f.length;e++){const t=f[e]
1983
- "file"===t.type?I+=`File ${e+1}: ${t.path}\n`:(I+=`Document ${e+1}: ${t.documentId}`,t.filename&&(I+=` (${t.filename})`),I+="\n"),t.success?(I+="**Status:** Success\n",t.lineCount&&t.totalLines&&(I+=`Lines Read / Total Lines ${t.lineCount} / ${t.totalLines}\n`),t.originalRequest?.lines&&t.totalLines&&(I+=`**Lines:** ${t.originalRequest.lines}\n`),I+=`\n**Content:**\n\`\`\`\n${t.content}\n\`\`\`\n`):(I+="**Status:** Failed\n",I+=`**Error:** ${t.error}\n`),I+="\n"}const b=0===w
1984
- return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:k,successfulReads:y,failedReads:w,success:b}),s.incrementCounter("read_files_total",1,{success:b}),{content:[{type:"text",text:I}],isError:!b}}catch(e){const t=Date.now()-a
1985
+ "file"===t.type?b+=`File ${e+1}: ${t.path}\n`:(b+=`Document ${e+1}: ${t.documentId}`,t.filename&&(b+=` (${t.filename})`),b+="\n"),t.success?(b+="**Status:** Success\n",t.lineCount&&t.totalLines&&(b+=`Lines Read / Total Lines ${t.lineCount} / ${t.totalLines}\n`),t.originalRequest?.lines&&t.totalLines&&(b+=`**Lines:** ${t.originalRequest.lines}\n`),b+=`\n**Content:**\n\`\`\`\n${t.content}\n\`\`\`\n`):(b+="**Status:** Failed\n",b+=`**Error:** ${t.error}\n`),b+="\n"}const I=0===w
1986
+ return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:k,successfulReads:y,failedReads:w,success:I}),s.incrementCounter("read_files_total",1,{success:I}),{content:[{type:"text",text:b}],isError:!I}}catch(e){const t=Date.now()-a
1985
1987
  return i.error("Read multiple files operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),s.incrementCounter("read_files_errors",1),{content:[{type:"text",text:"\u274c **Read Operation Failed:** "+(0,p.getErrorMessage)(e)}],isError:!0}}}
1986
1988
  const l=c(t(1943)),d=t(6183),u=t(1569),h=a(t(5967)),g=t(9470),p=t(8824)},2968(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.TaskClient=void 0
1987
1989
  const r=t(8824),n=t(7645),o=t(2161),s=t(5172)
@@ -2094,12 +2096,12 @@ d.info("Generating journal for request",{requestId:c})
2094
2096
  const h=t.projectId
2095
2097
  if(!h)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
2096
2098
  o.setProjectId(h),d.info("Fetching request data, tasks, and file history in parallel")
2097
- const g=o.getRequestClient(),p=o.getTaskClient(),f=o.getToolRecordClient(),[m,y,w]=await Promise.all([g.getRequest(c),p.listTasks({requestId:c}),f.getToolRecordsByRequestId(c).catch((e=>(d.warn("Failed to fetch tool records",{error:e+""}),[])))]),k=(0,s.extractDataFromResponse)(m,{logger:d,operationName:"getRequest",throwOnNoData:!0}),I="data"in k?k.data:k,b={id:I.id||c,title:I.title||"Unknown Request",description:I.description||"No description available",status:I.status||"unknown",type:I.type||"unknown",acceptanceCriteria:I.acceptanceCriteria||[],createdAt:I.createdAt||(new Date).toISOString(),updatedAt:I.updatedAt||(new Date).toISOString(),completedAt:I.completedAt},v=(0,s.extractDataFromResponse)(y,{logger:d,operationName:"listTasks",throwOnNoData:!1}),C=(Array.isArray(v)?v:"data"in v?v.data:[]).map((e=>({id:e.id,title:e.title||"Untitled Task",description:e.description||"No description",status:e.status||"unknown",createdAt:e.createdAt||(new Date).toISOString(),completedAt:e.metadata?.completedAt})))
2099
+ const g=o.getRequestClient(),p=o.getTaskClient(),f=o.getToolRecordClient(),[m,y,w]=await Promise.all([g.getRequest(c),p.listTasks({requestId:c}),f.getToolRecordsByRequestId(c).catch((e=>(d.warn("Failed to fetch tool records",{error:e+""}),[])))]),k=(0,s.extractDataFromResponse)(m,{logger:d,operationName:"getRequest",throwOnNoData:!0}),b="data"in k?k.data:k,I={id:b.id||c,title:b.title||"Unknown Request",description:b.description||"No description available",status:b.status||"unknown",type:b.type||"unknown",acceptanceCriteria:b.acceptanceCriteria||[],createdAt:b.createdAt||(new Date).toISOString(),updatedAt:b.updatedAt||(new Date).toISOString(),completedAt:b.completedAt},v=(0,s.extractDataFromResponse)(y,{logger:d,operationName:"listTasks",throwOnNoData:!1}),C=(Array.isArray(v)?v:"data"in v?v.data:[]).map((e=>({id:e.id,title:e.title||"Untitled Task",description:e.description||"No description",status:e.status||"unknown",createdAt:e.createdAt||(new Date).toISOString(),completedAt:e.metadata?.completedAt})))
2098
2100
  d.info(`Fetched request, ${C.length} tasks, ${w.length} tool records`)
2099
2101
  const _=await async function(e){const t=new Map,n=[],o=e.filter((e=>["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(e.type))).sort(((e,t)=>new Date(e.createdAt).getTime()-new Date(t.createdAt).getTime()))
2100
2102
  for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
2101
2103
  n.push({type:e.type,timestamp:e.createdAt,comment:s,files:o,recordId:e.localId||e.id})
2102
- for(const e of o)t.set(e,(t.get(e)||0)+1)}return{files:Array.from(t.entries()).map((([e,t])=>({path:e,operations:t}))).sort(((e,t)=>t.operations-e.operations)),operations:n}}(w),E={request:b,tasks:C,fileChanges:{summary:{totalFiles:_.files.length,totalOperations:_.operations.length,files:_.files},operations:_.operations},suggestedFilename:`JOURNAL-${c}.md`,metadata:{projectId:h,requestId:c,generatedAt:(new Date).toISOString()}},q=`\u2705 **Request Data Fetched Successfully!**\n\n**Request:** ${b.title} (${c})\n**Status:** ${b.status}\n**Type:** ${b.type}\n**Tasks:** ${C.length}\n**Files Changed:** ${_.files.length}\n**File Operations:** ${_.operations.length}\n\n**Data Summary:**\n\`\`\`json\n${JSON.stringify(E,null,2)}\n\`\`\`\n\n**Next Steps:**\nWrite a **compact technical narrative** and save as \`JOURNAL-${c}.md\` using document_operations (create).\n\n**Style Guide:**\n- Be concise and direct - no fluff, repetition, or unnecessary elaboration\n- Write in narrative flow connecting the changes chronologically\n- Reference files with paths: "Modified \\\`src/tools/example.ts\\\` to add X..."\n- Include operation comments inline: ("comment: 'Fix bug in parser'")\n- **Link to tool records**: Use \\\`[RECORD:trec######]\\\` format to reference operations (e.g., "Modified parser.ts [RECORD:trec004123]")\n- Show key code changes with brief snippets where they add clarity\n- Explain what changed and why, skip obvious details\n- Focus on technical substance over structure\n\n**Example:** "Modified \\\`parser.ts\\\` [RECORD:trec004123] to handle edge cases (comment: 'Fix null handling'). Added \\\`if (!input) return null;\\\` check at line 45. Then updated \\\`validator.ts\\\` [RECORD:trec004124] to use the new parser behavior..."`
2104
+ for(const e of o)t.set(e,(t.get(e)||0)+1)}return{files:Array.from(t.entries()).map((([e,t])=>({path:e,operations:t}))).sort(((e,t)=>t.operations-e.operations)),operations:n}}(w),E={request:I,tasks:C,fileChanges:{summary:{totalFiles:_.files.length,totalOperations:_.operations.length,files:_.files},operations:_.operations},suggestedFilename:`JOURNAL-${c}.md`,metadata:{projectId:h,requestId:c,generatedAt:(new Date).toISOString()}},q=`\u2705 **Request Data Fetched Successfully!**\n\n**Request:** ${I.title} (${c})\n**Status:** ${I.status}\n**Type:** ${I.type}\n**Tasks:** ${C.length}\n**Files Changed:** ${_.files.length}\n**File Operations:** ${_.operations.length}\n\n**Data Summary:**\n\`\`\`json\n${JSON.stringify(E,null,2)}\n\`\`\`\n\n**Next Steps:**\nWrite a **compact technical narrative** and save as \`JOURNAL-${c}.md\` using document_operations (create).\n\n**Style Guide:**\n- Be concise and direct - no fluff, repetition, or unnecessary elaboration\n- Write in narrative flow connecting the changes chronologically\n- Reference files with paths: "Modified \\\`src/tools/example.ts\\\` to add X..."\n- Include operation comments inline: ("comment: 'Fix bug in parser'")\n- **Link to tool records**: Use \\\`[RECORD:trec######]\\\` format to reference operations (e.g., "Modified parser.ts [RECORD:trec004123]")\n- Show key code changes with brief snippets where they add clarity\n- Explain what changed and why, skip obvious details\n- Focus on technical substance over structure\n\n**Example:** "Modified \\\`parser.ts\\\` [RECORD:trec004123] to handle edge cases (comment: 'Fix null handling'). Added \\\`if (!input) return null;\\\` check at line 45. Then updated \\\`validator.ts\\\` [RECORD:trec004124] to use the new parser behavior..."`
2103
2105
  return u({tool:"generate_request_journal",success:!0}),l.incrementCounter("generate_request_journal_total",1,{success:!0}),{content:[{type:"text",text:q}]}}catch(e){return d.error("Error generating request journal",{error:e instanceof Error?e.stack:e+""}),u({tool:"generate_request_journal",success:!1}),l.incrementCounter("generate_request_journal_errors",1),{content:[{type:"text",text:"\u274c **Failed to generate journal:** "+(0,i.getErrorMessage)(e)}],isError:!0}}}
2104
2106
  const n=t(9860),o=t(1569),s=t(2960),i=t(8824),a=o.z.object({requestId:o.z.string().regex(/^req[_\d].+$/,"Invalid request ID format")})},3064(e,exports,t){async function r(e,t,r,n){if(!r.lockOverrideManager||!r.configManager)return e
2105
2107
  try{const n=await r.configManager.getEffectiveConfig(r.mainBasePath)
@@ -2216,7 +2218,7 @@ var t={}
2216
2218
  if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
2217
2219
  return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
2218
2220
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceStrings=async function(e,t,r,o,s,i,a,c){const y=i.child({tool:"replace_strings"}),w=Date.now()
2219
- let k,I,b=u.FileOperationPhase.VALIDATION
2221
+ let k,b,I=u.FileOperationPhase.VALIDATION
2220
2222
  const v={toolName:"replace-strings",operationName:"replace-string",fileOperationPhase:u.FileOperationPhase.STRING_REPLACEMENT,recordType:"replace-strings",metricsPrefix:"replace_strings",successMessage:"Successfully replaced strings across files and documents",failureMessage:"Failed to replace strings across files and documents"}
2221
2223
  try{const i=u.validateArgs(e,d.ReplaceStringsSchema),{taskId:C,operations:_,comment:E}=i
2222
2224
  if(y.info("Replacing strings across files and documents",{taskId:C,operationCount:_.length,comment:E}),!_||0===_.length)throw new h.ValidationError("At least one operation is required")
@@ -2229,21 +2231,21 @@ if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not ava
2229
2231
  for(const e of S)P.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
2230
2232
  if(P.length>0&&t.apiClient){const e=P.map((e=>e.documentId))
2231
2233
  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}
2232
- throw e}}b=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_strings_phase",1,{phase:b})
2233
- const M=T.length>0?T[0].path:"document-operation",R=await u.validateTaskId(C,M,r,y,a,v.metricsPrefix),j=R?.requestId
2234
+ throw e}}I=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_strings_phase",1,{phase:I})
2235
+ const M=T.length>0?T[0].path:"document-operation",j=await u.validateTaskId(C,M,r,y,a,v.metricsPrefix),R=j?.requestId
2234
2236
  let x=null
2235
- T.length>0&&j&&(x=await u.validateWorkItemStates(C,T[0].path,r,s,t,y,a,v.metricsPrefix))
2237
+ T.length>0&&R&&(x=await u.validateWorkItemStates(C,T[0].path,r,s,t,y,a,v.metricsPrefix))
2236
2238
  let O={taskPromoted:!1,requestPromoted:!1}
2237
- T.length>0&&j&&x&&(O=await u.autoPromoteTaskStatus(C,R.status,j,x.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:j,previousStatus:R.status,newStatus:O.newTaskStatus,triggeringOperation:"replace-strings"}))
2238
- const A=await u.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:j,context:t,operation:"replace-strings",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
2239
+ T.length>0&&R&&x&&(O=await u.autoPromoteTaskStatus(C,j.status,R,x.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:R,previousStatus:j.status,newStatus:O.newTaskStatus,triggeringOperation:"replace-strings"}))
2240
+ const A=await u.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:R,context:t,operation:"replace-strings",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
2239
2241
  if(!A.success){if(A.isLockConflict)return{content:[{type:"text",text:"\u274c "+A.error}],isError:!0}
2240
2242
  throw Error(A.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
2241
2243
  for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
2242
- T[e]={...r,path:o,fullPath:s}}}if(P.length>0&&j)try{await(0,g.validateRequestStatusForDocumentOperation)(j,s,y,a,"replace-strings-document")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2243
- throw e}b=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:b})
2244
- const D=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...P.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:$}=await u.createFileOperationRecords(C,j,t.projectId,v.recordType,M,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:D,userComment:E},r,o,y,a,v.metricsPrefix,c)
2245
- if(k=$,I=$,b=v.fileOperationPhase,a.incrementCounter("replace_strings_phase",1,{phase:b}),T.length>0&&t.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
2246
- const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:j,taskId:C,workspaceManager:t.workspaceManager},y,a)
2244
+ T[e]={...r,path:o,fullPath:s}}}if(P.length>0&&R)try{await(0,g.validateRequestStatusForDocumentOperation)(R,s,y,a,"replace-strings-document")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2245
+ throw e}I=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:I})
2246
+ const D=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...P.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:$}=await u.createFileOperationRecords(C,R,t.projectId,v.recordType,M,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:D,userComment:E},r,o,y,a,v.metricsPrefix,c)
2247
+ if(k=$,b=$,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")
2248
+ const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:R,taskId:C,workspaceManager:t.workspaceManager},y,a)
2247
2249
  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})
2248
2250
  const F=[]
2249
2251
  let N=0,L=0
@@ -2255,17 +2257,17 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
2255
2257
  r.filename=s?.filename
2256
2258
  const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
2257
2259
  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(P.length>0)try{for(const e of P){const r=F.find((t=>t.documentId===e.documentId))
2258
- r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const z=await u.handleMultiFileGitCommit(C,T,F,L,{operationType:"Replace strings",toolRecordId:I,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),B=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:H,failedOperations:W,totalSuccessfulChanges:U,overallSuccess:G,successfulFiles:V,failedFiles:J}=B
2259
- try{await o.updateToolRecord(I,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:G?"completed":"failed",error:G?void 0:W+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:D,totalSuccessfulReplacements:U,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: ${W}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}u.formatMultiFileToolResponse("String Replacement",{successfulOperations:H,failedOperations:W,totalSuccessfulChanges:U,overallSuccess:G,successfulFiles:V,failedFiles:J},z,A)
2260
- let Y="## String Replacement Results\n\n"
2261
- if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${H+W}\n`,Y+=`- **Successful operations:** ${H}\n`,Y+=`- **Failed operations:** ${W}\n`,Y+=`- **Total replacements:** ${U} successful, ${N} failed\n\n`,z.success&&z.commitHash&&(Y+="**Git Commit:**\n",Y+=`- **Commit Hash:** ${z.commitHash.substring(0,8)}\n`,Y+=`- **Files Committed:** ${z.filesCommitted.length}\n`,z.previousCommitHash&&(Y+=`- **Previous Commit:** ${z.previousCommitHash.substring(0,8)}\n`),Y+="\n"),A.lockAcquired&&A.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${A.lockedRequestId}\n\n`),1===F.length){const e=F[0]
2262
- 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+=`**Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(Y+=`, ${e.failedReplacements} failed`),Y+="\n"),e.replacements.some((e=>!e.success))){Y+="**Failed Replacement Details:**\n"
2263
- for(const t of e.replacements.filter((e=>!e.success)))Y+=`- "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}}else{Y+="**Summary:**\n",Y+=`- **Total Operations:** ${F.length}\n`,Y+=`- **Successful:** ${H}\n`,Y+=`- **Failed:** ${W}\n`,Y+=`- **Total Replacements:** ${U} successful, ${N} failed\n\n`,Y+="**Detailed Results:**\n\n"
2264
- 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+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(Y+=`, ${e.failedReplacements} failed`),Y+="\n"),e.replacements.some((e=>!e.success))){Y+="- **Failed Replacement Details:**\n"
2265
- for(const t of e.replacements.filter((e=>!e.success)))Y+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}Y+="\n"}}P.length>0&&(Y+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
2266
- const K=Date.now()-w
2267
- return y.info("Replace strings operation completed",{duration:K,success:G,totalOperations:F.length,successfulOperations:H,failedOperations:W}),a.incrementCounter("replace_strings_total",1,{success:G}),{content:[{type:"text",text:Y}],isError:!G}}catch(t){const r=Date.now()-w
2268
- if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:b}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:b,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_strings_errors",1,{phase:b}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
2260
+ r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const z=await u.handleMultiFileGitCommit(C,T,F,L,{operationType:"Replace strings",toolRecordId:b,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),B=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:H,failedOperations:W,totalSuccessfulChanges:U,overallSuccess:G,successfulFiles:V,failedFiles:J}=B
2261
+ try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:G?"completed":"failed",error:G?void 0:W+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:D,totalSuccessfulReplacements:U,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: ${W}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}u.formatMultiFileToolResponse("String Replacement",{successfulOperations:H,failedOperations:W,totalSuccessfulChanges:U,overallSuccess:G,successfulFiles:V,failedFiles:J},z,A)
2262
+ let K="## String Replacement Results\n\n"
2263
+ if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${H+W}\n`,K+=`- **Successful operations:** ${H}\n`,K+=`- **Failed operations:** ${W}\n`,K+=`- **Total replacements:** ${U} 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"),A.lockAcquired&&A.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${A.lockedRequestId}\n\n`),1===F.length){const e=F[0]
2264
+ 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"
2265
+ 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:** ${W}\n`,K+=`- **Total Replacements:** ${U} successful, ${N} failed\n\n`,K+="**Detailed Results:**\n\n"
2266
+ 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"
2267
+ for(const t of e.replacements.filter((e=>!e.success)))K+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}K+="\n"}}P.length>0&&(K+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
2268
+ const Y=Date.now()-w
2269
+ return y.info("Replace strings operation completed",{duration:Y,success:G,totalOperations:F.length,successfulOperations:H,failedOperations:W}),a.incrementCounter("replace_strings_total",1,{success:G}),{content:[{type:"text",text:K}],isError:!G}}catch(t){const r=Date.now()-w
2270
+ 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}}}
2269
2271
  const l=c(t(1943)),d=t(6183),u=a(t(5967)),h=t(9860),g=t(5003),p=t(7478),f=t(9949),m=t(8824)},3322(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
2270
2272
  var o=Object.getOwnPropertyDescriptor(t,r)
2271
2273
  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=[]
@@ -2351,26 +2353,26 @@ Object.defineProperty(exports,"LogLevel",{enumerable:!0,get(){return s.LogLevel}
2351
2353
  const r=t(6183),n=t(8317)
2352
2354
  exports.def={name:"request_file_history",description:"Get file change history for an entire request. Supports summary mode (net diffs) or detailed mode (chronological operations). Can be filtered to specific task. Use query_history tool instead.",schema:r.QueryHistorySchema,annotations:{title:"Request File History",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleRequestFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}},3611(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
2353
2355
  Object.defineProperty(exports,"__esModule",{value:!0})
2354
- const n=r(t(6928)),o=r(t(7252)),s=r(t(8577)),i=t(184),a=t(1213),c=t(3444),l=t(9955),d=t(5218),u=t(2568),h=t(3102),g=t(1152),p=t(3884),f=t(7888),m=t(4139),y=t(6800),w=t(6539),k=t(8824),I=t(6975),b=t(1253),v=process.argv.slice(2),C=v[0]||process.cwd(),_=n.default.resolve(C),E=parseInt(process.env.LOCAL_SERVER_PORT||v[1]||"3002",10),q=(0,c.createEnvLogger)({serviceName:"mcp-http-server"});(0,c.isDebugToolsEnabled)()?q.info("HTTP server initializing",{baseDir:_,preferredPort:E,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL}):q.info("HTTP server starting",{port:E})
2356
+ const n=r(t(6928)),o=r(t(7252)),s=r(t(8577)),i=t(184),a=t(1213),c=t(3444),l=t(9955),d=t(5218),u=t(2568),h=t(3102),g=t(1152),p=t(3884),f=t(7888),m=t(4139),y=t(6800),w=t(6539),k=t(8824),b=t(6975),I=t(1253),v=process.argv.slice(2),C=v[0]||process.cwd(),_=n.default.resolve(C),E=parseInt(process.env.LOCAL_SERVER_PORT||v[1]||"3002",10),q=(0,c.createEnvLogger)({serviceName:"mcp-http-server"});(0,c.isDebugToolsEnabled)()?q.info("HTTP server initializing",{baseDir:_,preferredPort:E,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL}):q.info("HTTP server starting",{port:E})
2355
2357
  const S=(0,g.createMetricsCollector)(!0),T=(process.env.REMOTE_SERVER_PORT,process.env.REMOTE_SERVER_HOST,process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com")
2356
2358
  q.info("Using remote server URL",{remoteServerUrl:T}),async function(){try{q.info("Finding available port...",{preferredPort:E,baseDir:_,remoteServerUrl:T})
2357
2359
  const e=await(0,y.findAvailablePort)(E)
2358
2360
  e!==E&&q.info(`Preferred port ${E} is in use, using port ${e} instead`),q.info("Starting HTTP API server...",{port:e,baseDir:_,remoteServerUrl:T})
2359
2361
  const t=new l.ProjectRegistry(q),r=new h.DefaultProjectFileSystem(q),c=n.default.join(_,m.ALCHEMY_DIR_NAME)
2360
2362
  q.info(`Checking ${m.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensureDirectoryExists(c)
2361
- const g=new b.TokenManager(q,n.default.join(c,"auth-token.json")),v=(await w.ClientFactory.createClient(T,q,S,{tokenManager:g,workingDir:_,alchemyPath:c})).projectClient,C=new I.ProjectClientAdapter(v,q),P=new u.ProjectSynchronizer(q,t,C,r),M=await P.getOrCreateProject(_,{name:n.default.basename(_)||"Local Project",description:"Project for "+n.default.basename(_),status:"active",metadata:{basePath:_,alchemyPath:c,bootstrapped:!0}})
2363
+ const g=new I.TokenManager(q,n.default.join(c,"auth-token.json")),v=(await w.ClientFactory.createClient(T,q,S,{tokenManager:g,workingDir:_,alchemyPath:c})).projectClient,C=new b.ProjectClientAdapter(v,q),P=new u.ProjectSynchronizer(q,t,C,r),M=await P.getOrCreateProject(_,{name:n.default.basename(_)||"Local Project",description:"Project for "+n.default.basename(_),status:"active",metadata:{basePath:_,alchemyPath:c,bootstrapped:!0}})
2362
2364
  q.info("Using project",{projectId:M.id,projectName:M.name})
2363
- const R=(0,o.default)()
2364
- R.use((0,s.default)()),R.use(o.default.json({limit:"50mb"})),R.use(o.default.urlencoded({extended:!0})),R.use((0,p.requestLogger)(q))
2365
+ const j=(0,o.default)()
2366
+ j.use((0,s.default)()),j.use(o.default.json({limit:"50mb"})),j.use(o.default.urlencoded({extended:!0})),j.use((0,p.requestLogger)(q))
2365
2367
  try{q.info("Creating MCP server instance")
2366
2368
  const t=await(0,i.createServer)(_,q,S,T,{existingProjectId:M.id,multiAgentMode:(0,d.isMultiAgentModeEnabled)(_)})
2367
2369
  q.info("MCP server instance created successfully")
2368
2370
  const r=t.getContext()
2369
- q.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(q.info("Adding connection status middleware"),R.use((0,f.addConnectionStatusInfo)(t.connectionManager))):q.warn("Unable to add connection status middleware - connection manager not available")
2371
+ q.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(q.info("Adding connection status middleware"),j.use((0,f.addConnectionStatusInfo)(t.connectionManager))):q.warn("Unable to add connection status middleware - connection manager not available")
2370
2372
  try{const e=M.id
2371
- q.info("Setting up project context middleware",{projectId:e}),R.use("/api",((t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}))}catch(e){q.warn("Failed to set up project context middleware",{error:(0,k.getErrorMessage)(e)})}(0,a.registerApiRoutes)(R,t,q,S),R.use((0,p.errorHandler)(q,S)),R.listen(e,(()=>{q.info("HTTP API server listening on port "+e,{baseDir:_,port:e,nodeVersion:process.version})}))}catch(e){q.error("Failed to create or initialize MCP server",{error:e instanceof Error?e.stack:e+""})
2373
+ q.info("Setting up project context middleware",{projectId:e}),j.use("/api",((t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}))}catch(e){q.warn("Failed to set up project context middleware",{error:(0,k.getErrorMessage)(e)})}(0,a.registerApiRoutes)(j,t,q,S),j.use((0,p.errorHandler)(q,S)),j.listen(e,(()=>{q.info("HTTP API server listening on port "+e,{baseDir:_,port:e,nodeVersion:process.version})}))}catch(e){q.error("Failed to create or initialize MCP server",{error:e instanceof Error?e.stack:e+""})
2372
2374
  let t=!1
2373
- e instanceof Error&&(t=e.message.includes("connection")||e.message.includes("timeout")||e.message.includes("network")||"ConnectionError"===e.name),S.incrementCounter("server_initialization_failure",1,{isConnectionError:t?"true":"false"}),R.use(((e,t,r)=>{t.set("X-Connection-Status","offline"),t.set("X-Server-Initialization-Failed","true"),r()})),R.use("/api",((t,r)=>{r.status(503).json({success:!1,error:{code:"CONNECTION_ERROR",message:"Server failed to initialize due to connection issues. Please check connectivity and try again.",details:{serverError:e instanceof Error?e.message:e+"",suggestions:["Check your network connection","Verify that the remote server is running","Try restarting the local server"],isConnectionIssue:!0},retryable:!0,statusCode:503}})})),q.warn("Continuing with limited functionality due to initialization error")}process.on("SIGINT",(()=>{q.info("Received SIGINT signal, shutting down..."),process.exit(0)})),process.on("SIGTERM",(()=>{q.info("Received SIGTERM signal, shutting down..."),process.exit(0)})),process.on("uncaughtException",(e=>{q.error("Uncaught exception",{error:e.stack}),process.exit(1)})),process.on("unhandledRejection",(e=>{q.error("Unhandled promise rejection",{reason:e}),process.exit(1)}))}catch(e){q.error("Failed to start HTTP API server",{error:e instanceof Error?e.stack:e+""}),process.exit(1)}}()},3626(e,exports,t){function r(e){if(!e)return!1
2375
+ e instanceof Error&&(t=e.message.includes("connection")||e.message.includes("timeout")||e.message.includes("network")||"ConnectionError"===e.name),S.incrementCounter("server_initialization_failure",1,{isConnectionError:t?"true":"false"}),j.use(((e,t,r)=>{t.set("X-Connection-Status","offline"),t.set("X-Server-Initialization-Failed","true"),r()})),j.use("/api",((t,r)=>{r.status(503).json({success:!1,error:{code:"CONNECTION_ERROR",message:"Server failed to initialize due to connection issues. Please check connectivity and try again.",details:{serverError:e instanceof Error?e.message:e+"",suggestions:["Check your network connection","Verify that the remote server is running","Try restarting the local server"],isConnectionIssue:!0},retryable:!0,statusCode:503}})})),q.warn("Continuing with limited functionality due to initialization error")}process.on("SIGINT",(()=>{q.info("Received SIGINT signal, shutting down..."),process.exit(0)})),process.on("SIGTERM",(()=>{q.info("Received SIGTERM signal, shutting down..."),process.exit(0)})),process.on("uncaughtException",(e=>{q.error("Uncaught exception",{error:e.stack}),process.exit(1)})),process.on("unhandledRejection",(e=>{q.error("Unhandled promise rejection",{reason:e}),process.exit(1)}))}catch(e){q.error("Failed to start HTTP API server",{error:e instanceof Error?e.stack:e+""}),process.exit(1)}}()},3626(e,exports,t){function r(e){if(!e)return!1
2374
2376
  const t=e.toLowerCase().replace(/^\./,"")
2375
2377
  return u.has(t)}function n(e,t){if(r(t)){const t=e.match(/^([ \t]*)(.*?)\s*$/)
2376
2378
  if(!t)return e
@@ -2461,18 +2463,18 @@ try{const a=u.validateArgs(e,d.GetFileInfoSchema),{path:h}=a
2461
2463
  n.info("Getting file info: "+h)
2462
2464
  const{normalizedPath:f,fullPath:m}=u.validateAndNormalizePath(h,t)
2463
2465
  i=u.FileOperationPhase.FILE_WRITE
2464
- try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+h)}const y=await c.default.stat(m),w=y.isFile()?l.default.extname(m).slice(1):"",k={path:f,type:y.isDirectory()?"directory":"file",size:y.size,sizeFormatted:(p=y.size,u.formatFileSize(p)),created:r(y.birthtime),modified:r(y.mtime),accessed:r(y.atime),permissions:(g=y.mode,(511&g).toString(8)),isDirectory:y.isDirectory(),isFile:y.isFile(),isSymbolicLink:y.isSymbolicLink(),extension:w},I=["File Information for: "+f,"Type: "+k.type,`Size: ${k.sizeFormatted} (${k.size} bytes)`,"Created: "+k.created,"Modified: "+k.modified,"Accessed: "+k.accessed,"Permissions: "+k.permissions,"Is Directory: "+k.isDirectory,"Is File: "+k.isFile,"Is Symbolic Link: "+k.isSymbolicLink]
2465
- k.isFile&&w&&I.push("Extension: "+w)
2466
- const b=Date.now()-s
2467
- return o.recordValue("get_file_info_time",b),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+f,{type:k.type,size:k.size,time:b}),{content:[{type:"text",text:I.join("\n")}]}}catch(t){const r=Date.now()-s
2466
+ try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+h)}const y=await c.default.stat(m),w=y.isFile()?l.default.extname(m).slice(1):"",k={path:f,type:y.isDirectory()?"directory":"file",size:y.size,sizeFormatted:(p=y.size,u.formatFileSize(p)),created:r(y.birthtime),modified:r(y.mtime),accessed:r(y.atime),permissions:(g=y.mode,(511&g).toString(8)),isDirectory:y.isDirectory(),isFile:y.isFile(),isSymbolicLink:y.isSymbolicLink(),extension:w},b=["File Information for: "+f,"Type: "+k.type,`Size: ${k.sizeFormatted} (${k.size} bytes)`,"Created: "+k.created,"Modified: "+k.modified,"Accessed: "+k.accessed,"Permissions: "+k.permissions,"Is Directory: "+k.isDirectory,"Is File: "+k.isFile,"Is Symbolic Link: "+k.isSymbolicLink]
2467
+ k.isFile&&w&&b.push("Extension: "+w)
2468
+ const I=Date.now()-s
2469
+ return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+f,{type:k.type,size:k.size,time:I}),{content:[{type:"text",text:b.join("\n")}]}}catch(t){const r=Date.now()-s
2468
2470
  return o.recordValue("get_file_info_time",r),o.incrementCounter("get_file_info_errors",1),n.error("Error getting file info:",{error:(0,h.getErrorMessage)(t),time:r}),u.handleFileOperationError(t,i,n,o,e,a)}var g,p}
2469
2471
  const c=a(t(1943)),l=a(t(6928)),d=t(6183),u=i(t(5967)),h=t(8824)},3707(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,d,u,h,g,p){const f=h.child({tool:"quick_edit"}),m=Date.now()
2470
- try{const y=u.getRequestClient(),w=u.getTaskClient(),k=u.getFileClient(),I=u.getToolRecordClient(),{title:b,description:v,...C}=e,_=e.comment||b
2471
- f.info("Starting quick_edit workflow",{title:b,operationType:t})
2472
+ try{const y=u.getRequestClient(),w=u.getTaskClient(),k=u.getFileClient(),b=u.getToolRecordClient(),{title:I,description:v,...C}=e,_=e.comment||I
2473
+ f.info("Starting quick_edit workflow",{title:I,operationType:t})
2472
2474
  let E=!1
2473
2475
  try{const e=await y.listRequests({limit:2,sortBy:"created_at",sortDirection:"desc"})
2474
2476
  e&&2===e.length&&e.every((e=>"quick-edit"===e.type))&&(E=!0,f.info("Detected two consecutive quick-edits, will recommend normal request"))}catch(e){f.warn("Could not check recent requests for recommendation",{error:e})}f.debug("Creating quick_edit request")
2475
- const q=await y.createRequest({title:b,description:v,type:"quick-edit",acceptanceCriteria:["Quick change completed successfully"]})
2477
+ const q=await y.createRequest({title:I,description:v,type:"quick-edit",acceptanceCriteria:["Quick change completed successfully"]})
2476
2478
  if(!q||!q.id)throw Error("Failed to create request")
2477
2479
  const S=q.id
2478
2480
  let T
@@ -2480,24 +2482,24 @@ f.info("Created request",{requestId:S})
2480
2482
  try{if(f.debug("Checking for uncommitted user changes before quick-edit branch creation"),d.git)try{const e=await(0,c.commitUserChangesBeforeToolOperation)(d.git,"quick-fix",{requestId:S,taskId:void 0,workspaceManager:d.workspaceManager},h,g)
2481
2483
  e.userChangesCommitted?f.info("Committed user changes to main before quick-edit branch creation",{requestId:S,commitHash:e.commitHash?.substring(0,8)}):f.debug("No uncommitted changes found, proceeding with quick-edit")}catch(e){f.warn("Failed to commit user changes before quick-edit, proceeding anyway",{requestId:S,error:e instanceof Error?e.message:e+""})}else f.debug("No git instance available, skipping uncommitted changes check")
2482
2484
  f.debug("Creating task")
2483
- const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+b})
2485
+ const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+I})
2484
2486
  if(!e||!e.id)throw Error("Failed to create task")
2485
2487
  let v
2486
- if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{operationType:t}),"write"===t)v=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,k,w,I,y,h,g,p)
2487
- else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,I,y,h,g,p)
2488
+ if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{operationType:t}),"write"===t)v=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,k,w,b,y,h,g,p)
2489
+ else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,b,y,h,g,p)
2488
2490
  else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
2489
- v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||b},d,w,I,y,u,h,g,p)}if(v.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
2491
+ v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||I},d,w,b,y,u,h,g,p)}if(v.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
2490
2492
  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}),d.workspaceManager&&(await d.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,P=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
2491
2493
  P?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
2492
- try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${b}${P?" (partial success)":""}`},d,u,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})
2494
+ try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${I}${P?" (partial success)":""}`},d,u,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})
2493
2495
  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")
2494
- const M=P?`Quick change completed with partial success: ${b}. Some replacements failed - see details below.`:"Quick change completed: "+b,R=P?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2495
- let j=!1
2496
- try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:M,acceptanceEvidence:[{evidence:R}],testVerification:void 0},d,u,h,g,p)
2496
+ const M=P?`Quick change completed with partial success: ${I}. Some replacements failed - see details below.`:"Quick change completed: "+I,j=P?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2497
+ let R=!1
2498
+ try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:M,acceptanceEvidence:[{evidence:j}],testVerification:void 0},d,u,h,g,p)
2497
2499
  if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text})
2498
- else{try{await y.updateRequest(S,{status:"completed",completionSummary:M}),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)})}j=!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(!j)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:M}),j=!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 x=Date.now()-m
2500
+ else{try{await y.updateRequest(S,{status:"completed",completionSummary:M}),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)})}R=!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(!R)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:M}),R=!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 x=Date.now()-m
2499
2501
  let O
2500
- return f.info("Quick fix completed",{requestId:S,duration:x,hasPartialFailure:P}),O=P?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${x}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:** ${b}\n**Operation:** ${t}\n**Duration:** ${x}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}),d.workspaceManager&&(await d.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
2502
+ return f.info("Quick fix completed",{requestId:S,duration:x,hasPartialFailure:P}),O=P?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${I}\n**Operation:** ${t}\n**Duration:** ${x}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:** ${x}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}),d.workspaceManager&&(await d.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
2501
2503
  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}}}
2502
2504
  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){module.exports=require("simple-git")},3884(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.middleware=exports.validateRequest=exports.authenticate=exports.corsOptions=exports.errorHandler=exports.requestLogger=void 0
2503
2505
  const r=t(9860),n=t(5674)
@@ -2570,46 +2572,46 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
2570
2572
  var t={}
2571
2573
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
2572
2574
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
2573
- 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"),I=Date.now()
2574
- let b,v,C=d.FileOperationPhase.VALIDATION
2575
+ 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()
2576
+ let I,v,C=d.FileOperationPhase.VALIDATION
2575
2577
  const _={toolName:"write_file",operationName:"write",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"write-file",metricsPrefix:"write_file",successMessage:"Successfully wrote content",failureMessage:"Failed to write content"}
2576
- try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:E,content:q,format:S,append:T,comment:P}=r,M=!!E,R=!!f
2577
- w.info("Writing content to "+(M?"document":"file"),{taskId:i,filePath:R?f:void 0,documentId:M?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:T,comment:P})
2578
- let j,x,O,A="",D=!1,$=!1
2579
- const F=R?f:void 0
2578
+ try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:E,content:q,format:S,append:T,comment:P}=r,M=!!E,j=!!f
2579
+ w.info("Writing content to "+(M?"document":"file"),{taskId:i,filePath:j?f:void 0,documentId:M?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:T,comment:P})
2580
+ let R,x,O,A="",D=!1,$=!1
2581
+ const F=j?f:void 0
2580
2582
  if(M){if(t.apiClient)try{await(0,p.ensureDocumentNotLocked)(E,t.apiClient,w,m,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2581
2583
  throw e}if(!t.documentFileManager)throw Error("Document file manager not available")
2582
2584
  A=await t.documentFileManager.getDocumentAsFile(E)
2583
2585
  const e=t.documentFileManager.getCachedDocumentInfo(E)
2584
2586
  O=e?.filename,$=!0,D=!1}C=d.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("write_file_phase",1,{phase:C})
2585
- const N=R?F:"document:"+E,L=await d.validateTaskId(i,N,n,w,m,_.metricsPrefix),z=L?.requestId
2587
+ const N=j?F:"document:"+E,L=await d.validateTaskId(i,N,n,w,m,_.metricsPrefix),z=L?.requestId
2586
2588
  let B=null
2587
- R&&z&&(B=await d.validateWorkItemStates(i,N,n,s,t,w,m,_.metricsPrefix))
2589
+ j&&z&&(B=await d.validateWorkItemStates(i,N,n,s,t,w,m,_.metricsPrefix))
2588
2590
  let H={taskPromoted:!1,requestPromoted:!1}
2589
- R&&z&&B&&(H=await d.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"}))
2590
- const W=await d.ensureCorrectWorkspaceContext({taskPromoted:H.taskPromoted,requestId:z,context:t,operation:"write_file",logger:w,metrics:m,metricsPrefix:_.metricsPrefix,requireRequestContext:R})
2591
+ j&&z&&B&&(H=await d.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"}))
2592
+ const W=await d.ensureCorrectWorkspaceContext({taskPromoted:H.taskPromoted,requestId:z,context:t,operation:"write_file",logger:w,metrics:m,metricsPrefix:_.metricsPrefix,requireRequestContext:j})
2591
2593
  if(!W.success){if(W.isLockConflict)return{content:[{type:"text",text:"\u274c "+W.error}],isError:!0}
2592
- throw Error(W.error)}if(W.switched&&w.info("Workspace context successfully established",{requestId:z,branchName:W.branchName,operation:"write_file"}),R&&F){const e=d.validateAndNormalizePath(F,t)
2593
- j=e.normalizedPath,x=e.fullPath,A=x
2594
- try{await c.default.access(x),$=!0}catch{$=!1,D=!0}w.debug("Path validated with correct workspace context",{rawPath:F,normalizedPath:j,fullPath:x,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})}if(M&&z)try{await(0,h.validateRequestStatusForDocumentOperation)(z,s,w,m,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2594
+ throw Error(W.error)}if(W.switched&&w.info("Workspace context successfully established",{requestId:z,branchName:W.branchName,operation:"write_file"}),j&&F){const e=d.validateAndNormalizePath(F,t)
2595
+ R=e.normalizedPath,x=e.fullPath,A=x
2596
+ try{await c.default.access(x),$=!0}catch{$=!1,D=!0}w.debug("Path validated with correct workspace context",{rawPath:F,normalizedPath:R,fullPath:x,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})}if(M&&z)try{await(0,h.validateRequestStatusForDocumentOperation)(z,s,w,m,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2595
2597
  throw e}C=d.FileOperationPhase.RECORD_CREATION,m.incrementCounter("write_file_phase",1,{phase:C})
2596
- const{toolRecordId:U}=await d.createFileOperationRecords(i,z,t.projectId,_.recordType,N,{operationType:M?"document":"file",documentId:M?E:void 0,documentFilename:O,filePath:R?j:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S||"text",append:T||!1,wasFileCreated:!$,userComment:P},n,o,w,m,_.metricsPrefix,y)
2598
+ const{toolRecordId:U}=await d.createFileOperationRecords(i,z,t.projectId,_.recordType,N,{operationType:M?"document":"file",documentId:M?E:void 0,documentFilename:O,filePath:j?R:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S||"text",append:T||!1,wasFileCreated:!$,userComment:P},n,o,w,m,_.metricsPrefix,y)
2597
2599
  let G
2598
- if(b=U,v=U,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 u.ValidationError("Content is not valid JSON")}else G=JSON.stringify(q,null,2)
2600
+ if(I=U,v=U,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 u.ValidationError("Content is not valid JSON")}else G=JSON.stringify(q,null,2)
2599
2601
  else G="string"==typeof q?q:JSON.stringify(q,null,2)
2600
2602
  let V=G
2601
- if(R&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
2603
+ if(j&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
2602
2604
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"write_file",{requestId:t.workspaceManager?.getCurrentContext()?.requestId,taskId:i},w,m)
2603
- 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:j,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:j,error:e instanceof Error?e.message:e+""})}if(!A)throw Error("Target path not properly initialized")
2605
+ 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:R,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:R,error:e instanceof Error?e.message:e+""})}if(!A)throw Error("Target path not properly initialized")
2604
2606
  if(w.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:A}),T&&$)try{V=await c.default.readFile(A,"utf8")+G}catch(e){w.warn("Failed to read existing content for append",{error:e})}const J=a.default.dirname(A)
2605
- if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile(A,V,"utf8"),w.info("Content written successfully",{path:R?j:"document:"+E,finalLength:V.length,append:T,wasCreated:D}),M){t.documentFileManager.markForSync(E)
2606
- 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 Y,K,Q=null
2607
- if(R){if(C=d.FileOperationPhase.GIT_COMMIT,m.incrementCounter("write_file_phase",1,{phase:C}),t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
2608
- K=e.branchName,w.debug("Retrieved branch name from workspace manager",{branchName:K,requestId:e.requestId,mode:e.mode,isMainBranch:e.isMainBranch})}try{const e=`${D?"Create":T?"Append to":"Update"} ${j} (${v})`,r=await d.commitToGit(i,j,v,v,e,t,w,m,_.metricsPrefix)
2609
- Y=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:j,commitMessage:e,commitHash:Y?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:K,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:R?j:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:T&&$,operationType:M?"document":"file",processingTime:Date.now()-I,userComment:P,...R&&Y&&{commitHash:Y,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(M?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${D?"Created":T?"Appended to":"Updated"} ${M?`document ${E}${O?` (${O})`:""}`:"file "+j}**\n`
2610
- Z+=`**Content Length:** ${V.length} characters\n`,R&&K&&(Z+=`**Branch:** ${K}\n`),W.lockAcquired&&W.lockedRequestId&&(Z+=`**Locked request:** ${W.lockedRequestId}\n`),R&&Y&&(Z+=`**Commit Hash:** ${Y.substring(0,8)}\n`,Q&&(Z+=`**Previous Commit:** ${Q.substring(0,8)}\n`)),v&&(Z+=`[RECORD:${v}]\n`),M&&(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}\`.`)
2607
+ if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile(A,V,"utf8"),w.info("Content written successfully",{path:j?R:"document:"+E,finalLength:V.length,append:T,wasCreated:D}),M){t.documentFileManager.markForSync(E)
2608
+ 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
2609
+ if(j){if(C=d.FileOperationPhase.GIT_COMMIT,m.incrementCounter("write_file_phase",1,{phase:C}),t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
2610
+ 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"} ${R} (${v})`,r=await d.commitToGit(i,R,v,v,e,t,w,m,_.metricsPrefix)
2611
+ K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:R,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:j?R:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:T&&$,operationType:M?"document":"file",processingTime:Date.now()-b,userComment:P,...j&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(M?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${D?"Created":T?"Appended to":"Updated"} ${M?`document ${E}${O?` (${O})`:""}`:"file "+R}**\n`
2612
+ Z+=`**Content Length:** ${V.length} characters\n`,j&&Y&&(Z+=`**Branch:** ${Y}\n`),W.lockAcquired&&W.lockedRequestId&&(Z+=`**Locked request:** ${W.lockedRequestId}\n`),j&&K&&(Z+=`**Commit Hash:** ${K.substring(0,8)}\n`,Q&&(Z+=`**Previous Commit:** ${Q.substring(0,8)}\n`)),v&&(Z+=`[RECORD:${v}]\n`),M&&(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}\`.`)
2611
2613
  const X=Date.now()
2612
- return w.info("Write operation completed successfully",{duration:X-I,path:R?j:"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()-I
2614
+ return w.info("Write operation completed successfully",{duration:X-b,path:j?R:"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
2613
2615
  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}}}
2614
2616
  const a=i(t(6928)),c=i(t(1943)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824)},4139(e,exports){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){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
2615
2617
  const r=t(6183),n=t(4648)
@@ -2780,10 +2782,10 @@ try{let o
2780
2782
  try{o=i.FileRecoverSchema.parse(e)}catch(t){if(t instanceof a.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
2781
2783
  return p.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{taskId:f,path:y,commitHash:w,createBackup:k}=o
2782
2784
  return p.info("Recovering file to previous version",{taskId:f,filePath:y,commitHash:w,createBackup:k}),await async function(e,t,r,n,o,s,i,a,g,p,f){let m
2783
- try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),k=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:I}=await d.createFileOperationRecords(e,k?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),i,a,g,"file-recover",f)
2784
- m=I
2785
- let b,v=!1
2786
- try{await l.access(w),v=!0,n&&(b=`${w}.backup-${(new Date).toISOString().replace(/[:.]/g,"-")}`,await l.copyFile(w,b),a.info("Created backup",{originalPath:w,backupPath:b}))}catch{v=!1}const C=o.git
2785
+ try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),k=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:b}=await d.createFileOperationRecords(e,k?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),i,a,g,"file-recover",f)
2786
+ m=b
2787
+ let I,v=!1
2788
+ try{await l.access(w),v=!0,n&&(I=`${w}.backup-${(new Date).toISOString().replace(/[:.]/g,"-")}`,await l.copyFile(w,I),a.info("Created backup",{originalPath:w,backupPath:I}))}catch{v=!1}const C=o.git
2787
2789
  if(!C)throw Error("Git is not available")
2788
2790
  if(!(await(0,u.validateCommitHash)(C,r,a,"file-recover")).valid)throw Error(`Commit hash '${r}' is invalid or not found`)
2789
2791
  let _
@@ -2792,9 +2794,9 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
2792
2794
  throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await l.writeFile(w,_,"utf8")
2793
2795
  let E={}
2794
2796
  try{const t=`Recover ${y} from ${r.substring(0,8)}`
2795
- E=await d.commitToGit(e,y,m,m,t,o,a,g,"file-recover"),a.info("Recovery committed via shared utility",{path:y,sourceCommitHash:r,newCommitHash:E.commitHash?.substring(0,8),commitMessage:t})}catch(e){a.warn("Failed to commit recovery via shared utility",{error:e})}if(m)try{await i.updateToolRecord(m,{metadata:{path:y,status:"completed",recoveredLength:_.length,hadBackup:n&&v,backupPath:b,wasFileCreated:!v,processingTime:Date.now()-p,...E.commitHash&&{commitHash:E.commitHash,previousCommitHash:E.previousCommitHash||void 0}},note:"File recovered successfully from "+r.substring(0,8)})}catch(e){a.warn("Failed to update tool record",{recordError:e})}const q=v?"recovered":"created from recovery"
2797
+ E=await d.commitToGit(e,y,m,m,t,o,a,g,"file-recover"),a.info("Recovery committed via shared utility",{path:y,sourceCommitHash:r,newCommitHash:E.commitHash?.substring(0,8),commitMessage:t})}catch(e){a.warn("Failed to commit recovery via shared utility",{error:e})}if(m)try{await i.updateToolRecord(m,{metadata:{path:y,status:"completed",recoveredLength:_.length,hadBackup:n&&v,backupPath:I,wasFileCreated:!v,processingTime:Date.now()-p,...E.commitHash&&{commitHash:E.commitHash,previousCommitHash:E.previousCommitHash||void 0}},note:"File recovered successfully from "+r.substring(0,8)})}catch(e){a.warn("Failed to update tool record",{recordError:e})}const q=v?"recovered":"created from recovery"
2796
2798
  let S=`\u2705 **File ${q.charAt(0).toUpperCase()+q.slice(1)} Successfully**\n\n`
2797
- return S+=`**File:** ${y}\n`,S+=`**Recovered from:** ${r.substring(0,8)}\n`,S+=`**Content length:** ${_.length} characters\n`,n&&v&&b&&(S+=`**Backup created:** ${c.basename(b)}\n`),S+="**Git status:** Recovery committed\n",S+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",a.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-p}),g.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:S}]}}catch(e){throw e}}(f,y,w,k,t,r,n,p,s,m,g)}catch(e){const t=Date.now()-m
2799
+ return S+=`**File:** ${y}\n`,S+=`**Recovered from:** ${r.substring(0,8)}\n`,S+=`**Content length:** ${_.length} characters\n`,n&&v&&I&&(S+=`**Backup created:** ${c.basename(I)}\n`),S+="**Git status:** Recovery committed\n",S+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",a.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-p}),g.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:S}]}}catch(e){throw e}}(f,y,w,k,t,r,n,p,s,m,g)}catch(e){const t=Date.now()-m
2798
2800
  return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),f({tool:"file_recover",success:!1}),s.incrementCounter("file_recover_errors",1),{content:[{type:"text",text:"\u274c **Recovery Failed:** "+(0,h.getErrorMessage)(e)}],isError:!0}}}
2799
2801
  const i=t(6183),a=t(1569),c=s(t(6928)),l=s(t(1943)),d=s(t(5967)),u=t(3922),h=t(8824)},4648(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,t,u,h,g,p){const f=h.child({tool:"request_operations"})
2800
2802
  try{for(const t of["complete","verifyCriteria","merge","revert","search","list"])if(e&&"string"==typeof e[t])try{e[t]=JSON.parse(e[t])}catch{}"complete"===e?.operation&&e?.summary&&!e?.complete&&(e.complete={summary:e.summary},delete e.summary),"complete"!==e?.operation||e?.complete||e?.summary||(e.complete={summary:""}),"merge"===e?.operation&&e?.verifications&&!e?.merge&&(e.merge={verifications:e.verifications},delete e.verifications),e?.merge&&Array.isArray(e.merge)&&(e.merge={verifications:e.merge}),"verify-criteria"===e?.operation&&(e.operation="merge",e.verifyCriteria&&!e.merge&&(e.merge=e.verifyCriteria,delete e.verifyCriteria)),"finalize"===e?.operation&&(e.operation="merge",e.merge||(e.merge={verifications:[]})),"revert"===e?.operation&&e?.reason&&!e?.revert&&(e.revert={reason:e.reason,confirmDestructive:e.confirmDestructive},delete e.reason,delete e.confirmDestructive),"search"===e?.operation&&e?.query&&!e?.search&&(e.search={query:e.query,searchIn:e.searchIn||"all",filters:e.filters},delete e.query,delete e.searchIn,delete e.filters)
@@ -2942,15 +2944,15 @@ if(/^\d+$/.test(e)){const t=parseInt(e,10)
2942
2944
  return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
2943
2945
  if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
2944
2946
  if(e.match(/^(\d+(?:,\d+)+)$/)){const t=e.split(",").map((e=>parseInt(e,10)))
2945
- return{start:Math.min(...t),end:Math.max(...t)}}return null}(p),I=["blame","--porcelain"]
2946
- let b
2947
- k&&I.push(`-L${k.start},${k.end}`),f&&I.push(f),I.push("--",w),c.debug("Executing git blame",{args:I})
2947
+ return{start:Math.min(...t),end:Math.max(...t)}}return null}(p),b=["blame","--porcelain"]
2948
+ let I
2949
+ k&&b.push(`-L${k.start},${k.end}`),f&&b.push(f),b.push("--",w),c.debug("Executing git blame",{args:b})
2948
2950
  try{if(!t.git)throw Error("Git context not available")
2949
- b=await t.git.raw(I)}catch(e){const t=(0,h.getErrorMessage)(e)
2951
+ I=await t.git.raw(b)}catch(e){const t=(0,h.getErrorMessage)(e)
2950
2952
  return c.error("Git blame failed",{error:t}),{content:[{type:"text",text:"\u274c Git blame failed: "+t}],isError:!0}}const v=function(e){const t=[],r=e.split("\n")
2951
2953
  let n="",o="",s="",i=0,a=0,c=new Map
2952
2954
  for(let e=0;e<r.length;e++){const l=r[e],d=l.match(/^([0-9a-f]{40})\s+\d+\s+(\d+)/)
2953
- d?(n=d[1],a=parseInt(d[2],10)):l.startsWith("author ")?o=l.substring(7):l.startsWith("author-mail ")?s=l.substring(12).replace(/[<>]/g,""):l.startsWith("author-time ")?i=parseInt(l.substring(12),10):l.startsWith("summary ")?c.set(n,l.substring(8)):l.startsWith("\t")&&t.push({lineNumber:a,commitHash:n,author:o,authorEmail:s,timestamp:i,content:l.substring(1),commitMessage:c.get(n)})}return t}(b)
2955
+ d?(n=d[1],a=parseInt(d[2],10)):l.startsWith("author ")?o=l.substring(7):l.startsWith("author-mail ")?s=l.substring(12).replace(/[<>]/g,""):l.startsWith("author-time ")?i=parseInt(l.substring(12),10):l.startsWith("summary ")?c.set(n,l.substring(8)):l.startsWith("\t")&&t.push({lineNumber:a,commitHash:n,author:o,authorEmail:s,timestamp:i,content:l.substring(1),commitMessage:c.get(n)})}return t}(I)
2954
2956
  if(0===v.length)return{content:[{type:"text",text:"\u274c No blame information found for "+w}],isError:!0}
2955
2957
  const C=function(e){if(0===e.length)return[]
2956
2958
  const t=[]
@@ -3186,10 +3188,10 @@ const m=g.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_
3186
3188
  m.forEach((e=>{const t=e.status||"unverified"
3187
3189
  t in y&&y[t]++}))
3188
3190
  let w=g.testVerification||null
3189
- const k=g.title,I=g.type
3190
- let b=`# ${"feature"===I?"Feature":"quick-edit"===I?"Quick Edit":"Bug Fix"} Request: ${k} (${t})\nStatus: ${g.status}\nCreated: ${new Date(g.createdAt).toLocaleString()}\nUpdated: ${new Date(g.updatedAt).toLocaleString()}\n\n## Description\n${g.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${f.completed}/${f.total} completed (${Math.round(f.completed/f.total*100)||0}%)\n- Acceptance Criteria: ${y.verified}/${y.total} verified (${Math.round(y.verified/y.total*100)||0}%)\n`
3191
- return b+=`\n## Task Status\n- Pending: ${f.pending}\n- In Progress: ${f.in_progress}\n- Blocked: ${f.blocked}\n- Ready for Review: ${f.ready_for_review}\n- Completed: ${f.completed}\n- Reverted: ${f.reverted}\n`,b+="\n## Tasks\n",0===p.length?b+="No tasks found for this request.\n":p.forEach((e=>{b+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${p.length} tasks`),b+="\n## Acceptance Criteria\n",b+=(0,i.formatCriteriaWithHashes)(m)+"\n","ready_for_review"===g.status&&m.some((e=>"verified"!==e.status))&&(b+="\n> **Status: ready_for_review** \u2014 Use the merge operation to verify criteria and merge to main.\n"),w&&(b+=`\n## Test Coverage\n- Test Cases: ${w.totalTestCases||0}\n- Criteria Tested: ${w.criteriaTestedCount||0}/${y.total}\n`,w.criterionCoverage&&Array.isArray(w.criterionCoverage)&&(b+="\n### Detailed Test Coverage:\n",w.criterionCoverage.forEach((e=>{b+=`- Criterion ${e.criterionId}: ${e.coverage} coverage\n`})))),g.recentActivity&&Array.isArray(g.recentActivity)&&(b+="\n## Recent Activity\n",g.recentActivity.slice(0,5).forEach((e=>{const t=new Date(e.timestamp).toLocaleString()
3192
- b+=`- ${t}: ${e.description}\n`}))),u({success:!0}),{content:[{type:"text",text:b}]}}catch(t){return d.error("Error getting request information",{args:e,error:t instanceof Error?t.stack:t+""}),u({success:!1,error:t instanceof Error?t.name:"unknown"}),t instanceof n.ConnectionError?{content:[{type:"text",text:"Unable to get request information: Connection to the server failed. Please check your network connection and try again."}],isError:!0}:{content:[{type:"text",text:"Error getting request information: "+(0,s.getErrorMessage)(t)}],isError:!0}}}
3191
+ const k=g.title,b=g.type
3192
+ let I=`# ${"feature"===b?"Feature":"quick-edit"===b?"Quick Edit":"Bug Fix"} Request: ${k} (${t})\nStatus: ${g.status}\nCreated: ${new Date(g.createdAt).toLocaleString()}\nUpdated: ${new Date(g.updatedAt).toLocaleString()}\n\n## Description\n${g.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${f.completed}/${f.total} completed (${Math.round(f.completed/f.total*100)||0}%)\n- Acceptance Criteria: ${y.verified}/${y.total} verified (${Math.round(y.verified/y.total*100)||0}%)\n`
3193
+ return I+=`\n## Task Status\n- Pending: ${f.pending}\n- In Progress: ${f.in_progress}\n- Blocked: ${f.blocked}\n- Ready for Review: ${f.ready_for_review}\n- Completed: ${f.completed}\n- Reverted: ${f.reverted}\n`,I+="\n## Tasks\n",0===p.length?I+="No tasks found for this request.\n":p.forEach((e=>{I+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${p.length} tasks`),I+="\n## Acceptance Criteria\n",I+=(0,i.formatCriteriaWithHashes)(m)+"\n","ready_for_review"===g.status&&m.some((e=>"verified"!==e.status))&&(I+="\n> **Status: ready_for_review** \u2014 Use the merge operation to verify criteria and merge to main.\n"),w&&(I+=`\n## Test Coverage\n- Test Cases: ${w.totalTestCases||0}\n- Criteria Tested: ${w.criteriaTestedCount||0}/${y.total}\n`,w.criterionCoverage&&Array.isArray(w.criterionCoverage)&&(I+="\n### Detailed Test Coverage:\n",w.criterionCoverage.forEach((e=>{I+=`- Criterion ${e.criterionId}: ${e.coverage} coverage\n`})))),g.recentActivity&&Array.isArray(g.recentActivity)&&(I+="\n## Recent Activity\n",g.recentActivity.slice(0,5).forEach((e=>{const t=new Date(e.timestamp).toLocaleString()
3194
+ I+=`- ${t}: ${e.description}\n`}))),u({success:!0}),{content:[{type:"text",text:I}]}}catch(t){return d.error("Error getting request information",{args:e,error:t instanceof Error?t.stack:t+""}),u({success:!1,error:t instanceof Error?t.name:"unknown"}),t instanceof n.ConnectionError?{content:[{type:"text",text:"Unable to get request information: Connection to the server failed. Please check your network connection and try again."}],isError:!0}:{content:[{type:"text",text:"Error getting request information: "+(0,s.getErrorMessage)(t)}],isError:!0}}}
3193
3195
  const r=t(9860),n=t(5674),o=t(2960),s=t(8824),i=t(5454)},5454(e,exports){function t(e,t){let r=0
3194
3196
  for(let t=0;t<e.length;t++)r=(r<<5)-r+e.charCodeAt(t)|0
3195
3197
  return`${t+1}${String.fromCharCode(97+Math.abs(r)%26)}`}function r(e){const r=new Map
@@ -3287,25 +3289,25 @@ if(t){const e=Date.now()-t
3287
3289
  try{this.metrics.observeHistogram("offline_duration_ms",e,{reconnection_type:"manual"}),this.logger.info(`System was offline for ${Math.round(e/1e3)} seconds before manual reconnection`)}catch(e){this.logger.warn("Error observing histogram for offline duration on manual reconnection",{error:e instanceof Error?e.message:e+""})}}}}catch(e){this.logger.warn("Error calculating offline duration during manual mode change",{error:(0,s.getErrorMessage)(e)})}this.notifyOnlineStatus()}else!t&&e&&(this.logger.info("Manually setting connection mode to OFFLINE"),this.safeSetGauge("connection_status",0),this.safeSetGauge("last_connection_failure_timestamp",Date.now()),this.safeIncrementCounter("manual_disconnections",1),process.nextTick((()=>{exports.eventBus.emit(exports.EVENTS.OFFLINE,{timestamp:(new Date).toISOString()})})))}isOffline(){return this.isInOfflineMode()}async checkConnectivity(){return this.logger.debug("Explicit connectivity check requested"),this.healthCheckManager.requestHealthCheck()}getHealthCheckStats(){const e=this.healthCheckManager.getStats()
3288
3290
  return{isOffline:this.isInOfflineMode(),consecutiveFailures:e.consecutiveFailures,currentBackoffMs:e.currentBackoffMs,lastCheckTime:e.lastCheckTime}}cleanup(){this.logger.debug("Cleaning up connection status manager resources"),this.healthCheckManager.stopHealthChecks(),exports.eventBus.removeAllListeners(exports.EVENTS.ONLINE),exports.eventBus.removeAllListeners(exports.EVENTS.OFFLINE)}}},5692(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3289
3291
  const r=t(6183),n=t(2965)
3290
- exports.def={name:"read_files",description:'Read the contents of multiple files and documents with flexible line selection.\n\nLINE SELECTION (string format):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "5-15"\n- Entire file: omit "lines" parameter\n\nEXAMPLES:\n- Read first 10 lines: {"path": "file.txt", "lines": "1-10"}\n- Read specific lines: {"path": "file.txt", "lines": "1,5,25"}\n- Read line 42 only: {"path": "file.txt", "lines": "42"}\n- Read entire file: {"path": "file.txt"}\n\nSupports both filesystem files (using \'path\') and tracked documents (using \'documentId\'). More efficient than reading files one by one. Failed reads won\'t stop the entire operation.',schema:r.ReadFilesSchema,annotations:{title:"Read Files/Documents",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleReadFiles)(e,t.context,t.logger,t.metrics)}}},5715(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const g=l.child({tool:"complete_request"}),p=d.startTimer("tool_execution_time")
3291
- try{const{requestId:o,summary:s}=e
3292
- if(!o)throw(0,r.createValidationError)("Request ID is required")
3293
- if(!s)throw(0,r.createValidationError)("Summary is required")
3294
- g.info("Starting request completion",{requestId:o})
3295
- const l=h?.sessionId||(0,n.getCachedSession)()?.sessionId
3296
- let d
3297
- try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${o}/validate-completion`,{sessionId:l})
3298
- d=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
3299
- return g.error("Server validation failed",{requestId:o,error:t}),p({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate completion: "+t}],isError:!0}}if(!d.canComplete){let e=`Cannot complete request ${o}: ${d.reason}\n`
3300
- return d.blockedByTasks&&d.blockedByTasks.length>0&&(e+="\n**Tasks that must be completed or canceled first:**\n",d.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (Status: ${t.status})\n`}))),d.lifoViolation&&(e+="\n**Requests that must be re-completed first (LIFO order):**\n",d.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (Status: ${t.status})\n`}))),p({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}const u=c.getRequestClient(),f="auto-test-then-merge"===d.completionMode,m=f?"ready_for_review":"ready_for_merge"
3301
- try{await u.updateRequest(o,{status:m,completionSummary:s})}catch(e){const t=(0,i.getErrorMessage)(e)
3302
- return p({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let y
3303
- try{y=await u.getRequest(o)}catch(e){const t=(0,i.getErrorMessage)(e)
3304
- return p({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const w=y?.acceptanceCriteria||[]
3305
- return p({success:!0}),f?{content:[{type:"text",text:`Request ${o} moved to ready_for_review. Testing is active \u2014 a notification has been created for the user to choose testing mode. Do NOT call merge or any other tool. Your work is done. Stop here and wait.`}]}:0===w.length?{content:[{type:"text",text:`Request ${o} is ready. No acceptance criteria defined \u2014 call merge directly.`}]}:{content:[{type:"text",text:`Request ${o} completion started (${m}).\n\n## Next Step: Verify & Merge\n\n${(0,a.formatVerifyInstructions)(w)}\n\nUse the merge operation with your verification evidence to merge to main.`}]}}catch(r){let n="An unexpected error occurred",i=""
3306
- r instanceof o.ZodError?(n="Validation error",i=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")):r instanceof Error?(n=r.message,i=r.stack||""):i=r+"",g.error("Complete request failed",{error:n,details:i})
3307
- try{await(0,s.createFailureToolRecord)("complete-request",r,{error:n,details:i,requestId:e?.requestId},c.getToolRecordClient(),g,d,{requestId:e?.requestId,projectId:t.projectId,note:"Failed to complete request"})}catch{}return d.startTimer("tool_execution_time")({success:!1,error:r instanceof Error?r.name:"unknown"}),{content:[{type:"text",text:"Error: "+n}],isError:!0}}}
3308
- const r=t(9860),n=t(715),o=t(1569),s=t(8616),i=t(8824),a=t(5454)},5767(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3292
+ exports.def={name:"read_files",description:'Read the contents of multiple files and documents with flexible line selection.\n\nLINE SELECTION (string format):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "5-15"\n- Entire file: omit "lines" parameter\n\nEXAMPLES:\n- Read first 10 lines: {"path": "file.txt", "lines": "1-10"}\n- Read specific lines: {"path": "file.txt", "lines": "1,5,25"}\n- Read line 42 only: {"path": "file.txt", "lines": "42"}\n- Read entire file: {"path": "file.txt"}\n\nSupports both filesystem files (using \'path\') and tracked documents (using \'documentId\'). More efficient than reading files one by one. Failed reads won\'t stop the entire operation.',schema:r.ReadFilesSchema,annotations:{title:"Read Files/Documents",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleReadFiles)(e,t.context,t.logger,t.metrics)}}},5715(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,a,c,l,d,u){const h=c.child({tool:"complete_request"}),g=l.startTimer("tool_execution_time")
3293
+ try{const{requestId:n,summary:o}=e
3294
+ if(!n)throw(0,r.createValidationError)("Request ID is required")
3295
+ if(!o)throw(0,r.createValidationError)("Summary is required")
3296
+ h.info("Starting request completion",{requestId:n})
3297
+ const c=u?.sessionId
3298
+ let l
3299
+ try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:c})
3300
+ l=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
3301
+ return h.error("Server validation failed",{requestId:n,error:t}),g({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate completion: "+t}],isError:!0}}if(!l.canComplete){let e=`Cannot complete request ${n}: ${l.reason}\n`
3302
+ return l.blockedByTasks&&l.blockedByTasks.length>0&&(e+="\n**Tasks that must be completed or canceled first:**\n",l.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (Status: ${t.status})\n`}))),l.lifoViolation&&(e+="\n**Requests that must be re-completed first (LIFO order):**\n",l.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (Status: ${t.status})\n`}))),g({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}const d=a.getRequestClient(),p="auto-test-then-merge"===l.completionMode,f=p?"ready_for_review":"ready_for_merge"
3303
+ try{await d.updateRequest(n,{status:f,completionSummary:o})}catch(e){const t=(0,s.getErrorMessage)(e)
3304
+ return g({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let m
3305
+ try{m=await d.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
3306
+ return g({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const y=m?.acceptanceCriteria||[]
3307
+ return g({success:!0}),p?{content:[{type:"text",text:`Request ${n} moved to ready_for_review. Testing is active \u2014 a notification has been created for the user to choose testing mode. Do NOT call merge or any other tool. Your work is done. Stop here and wait.`}]}:0===y.length?{content:[{type:"text",text:`Request ${n} is ready. No acceptance criteria defined \u2014 call merge directly.`}]}:{content:[{type:"text",text:`Request ${n} completion started (${f}).\n\n## Next Step: Verify & Merge\n\n${(0,i.formatVerifyInstructions)(y)}\n\nUse the merge operation with your verification evidence to merge to main.`}]}}catch(r){let s="An unexpected error occurred",i=""
3308
+ r instanceof n.ZodError?(s="Validation error",i=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")):r instanceof Error?(s=r.message,i=r.stack||""):i=r+"",h.error("Complete request failed",{error:s,details:i})
3309
+ try{await(0,o.createFailureToolRecord)("complete-request",r,{error:s,details:i,requestId:e?.requestId},a.getToolRecordClient(),h,l,{requestId:e?.requestId,projectId:t.projectId,note:"Failed to complete request"})}catch{}return l.startTimer("tool_execution_time")({success:!1,error:r instanceof Error?r.name:"unknown"}),{content:[{type:"text",text:"Error: "+s}],isError:!0}}}
3310
+ const r=t(9860),n=t(1569),o=t(8616),s=t(8824),i=t(5454)},5767(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3309
3311
  const r=t(6183),n=t(6285)
3310
3312
  exports.def={name:"specialist_ops",description:"Manage your pool of up to 10 specialists. Each has a specialization describing their domain. Reuse specialists via follow-up before spawning new ones.\n\nOperations:\n\u2022 delegate - Spawn a new specialist (include specialization). Abort an idle specialist first if pool is full.\n\u2022 follow-up - Send follow-up instructions to an existing specialist (can update specialization)\n\u2022 check-status - Check if a specialist is busy or idle\n\u2022 list - List specialist sessions with specializations\n\u2022 abort - Cancel a stuck specialist",schema:r.SpecialistOpsSchema,annotations:{title:"Specialist Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleSpecialistOps)(e,t.context,t.logger,t.metrics,t.apiClient??void 0,t.cliOrigin)}}},5802(module){module.exports=require("@modelcontextprotocol/sdk/server/stdio.js")},5806(e,exports,t){function r(){const e=n.z.object({requestId:n.z.string(),summary:n.z.string(),acceptanceEvidence:n.z.array(n.z.object({evidence:n.z.string()}))}),t=n.z.object({testRecords:n.z.array(n.z.string()),coverage:n.z.object({criteriaTestedCount:n.z.number(),totalTestCases:n.z.number()}),criterionCoverage:n.z.array(n.z.object({coverage:n.z.enum(["none","partial","full"]),testRecords:n.z.array(n.z.string())}))})
3311
3313
  return(0,o.areTestsRequiredForCompletion)()?e.extend({testVerification:t}):e}Object.defineProperty(exports,"__esModule",{value:!0}),exports.DynamicCompleteRequestSchema=void 0,exports.getDynamicCompleteRequestSchema=r
@@ -3324,8 +3326,8 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
3324
3326
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3325
3327
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDeleteFiles=async function(e,t,r,n,o,s){const i=n.child({tool:"delete_files"}),m=Date.now()
3326
3328
  let y,w,k=l.FileOperationPhase.VALIDATION
3327
- const I={toolName:"delete-files",operationName:"delete",fileOperationPhase:l.FileOperationPhase.FILE_WRITE,recordType:"delete-files",metricsPrefix:"delete_files",successMessage:"Successfully deleted files",failureMessage:"Failed to delete files"}
3328
- try{const n=r.getTaskClient(),u=r.getToolRecordClient(),b=r.getRequestClient(),v=l.validateArgs(e,c.DeleteFilesSchema),{taskId:C,paths:_,operations:E,comment:q}=v
3329
+ const b={toolName:"delete-files",operationName:"delete",fileOperationPhase:l.FileOperationPhase.FILE_WRITE,recordType:"delete-files",metricsPrefix:"delete_files",successMessage:"Successfully deleted files",failureMessage:"Failed to delete files"}
3330
+ try{const n=r.getTaskClient(),u=r.getToolRecordClient(),I=r.getRequestClient(),v=l.validateArgs(e,c.DeleteFilesSchema),{taskId:C,paths:_,operations:E,comment:q}=v
3329
3331
  let S=[]
3330
3332
  if(_)S=_.map((e=>({type:"file",target:e})))
3331
3333
  else{if(!E)throw Error("Either paths or operations must be specified")
@@ -3333,31 +3335,31 @@ S=E.map((e=>{if(e.path)return{type:"file",target:e.path}
3333
3335
  if(e.documentId)return{type:"document",target:e.documentId}
3334
3336
  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")
3335
3337
  const T=S.filter((e=>"file"===e.type)),P=S.filter((e=>"document"===e.type)),M=S.length
3336
- i.info("Starting mixed file and document deletion operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,comment:q}),l.validateTaskIdFormat(C,i,o,I.metricsPrefix)
3337
- const R=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3338
- i.info("Initial branch context",{initialBranch:R.branch,initialRequestId:R.requestId,isMain:R.isMain})
3339
- const j=[]
3338
+ i.info("Starting mixed file and document deletion operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,comment:q}),l.validateTaskIdFormat(C,i,o,b.metricsPrefix)
3339
+ const j=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3340
+ i.info("Initial branch context",{initialBranch:j.branch,initialRequestId:j.requestId,isMain:j.isMain})
3341
+ const R=[]
3340
3342
  for(const e of T){const{normalizedPath:r,fullPath:n}=l.validateAndNormalizePath(e.target,t)
3341
- j.push({normalized:r,full:n})}k=l.FileOperationPhase.TASK_VALIDATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3342
- const x=j.length>0?j[0].normalized:"document_operations",O=await l.validateTaskId(C,x,n,i,o,I.metricsPrefix),A=O?.requestId,D=await l.validateWorkItemStates(C,x,n,b,t,i,o,I.metricsPrefix),$=await l.autoPromoteTaskStatus(C,O.status,A,D.request?.status,x,n,b,i,o,I.metricsPrefix)
3343
+ R.push({normalized:r,full:n})}k=l.FileOperationPhase.TASK_VALIDATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3344
+ const x=R.length>0?R[0].normalized:"document_operations",O=await l.validateTaskId(C,x,n,i,o,b.metricsPrefix),A=O?.requestId,D=await l.validateWorkItemStates(C,x,n,I,t,i,o,b.metricsPrefix),$=await l.autoPromoteTaskStatus(C,O.status,A,D.request?.status,x,n,I,i,o,b.metricsPrefix)
3343
3345
  $.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:$.newTaskStatus,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length}),$.requestPromoted&&i.info(`Auto-promoted request ${A} to in_progress for file operations`,{requestId:A,previousStatus:D.request?.status,newStatus:$.newRequestStatus,triggeringTaskId:C})
3344
- const F=await l.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:A,context:t,operation:"delete-files",logger:i,metrics:o,metricsPrefix:I.metricsPrefix})
3346
+ const F=await l.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:A,context:t,operation:"delete-files",logger:i,metrics:o,metricsPrefix:b.metricsPrefix})
3345
3347
  if(!F.success){if(F.isLockConflict)return{content:[{type:"text",text:"\u274c "+F.error}],isError:!0}
3346
3348
  throw Error(F.error)}let N={hadUserMods:!1,userModsCommitHash:void 0}
3347
3349
  if(t.git)try{i.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
3348
3350
  const e=await(0,h.commitUserChangesBeforeToolOperation)(t.git,"delete-files",{requestId:A,taskId:C,workspaceManager:t.workspaceManager},i,o)
3349
3351
  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:P.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:P.length,error:e instanceof Error?e.message:e+""})}i.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:S.length,fileDeletes:T.length,documentDeletes:P.length}),k=l.FileOperationPhase.RECORD_CREATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3350
- const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,A,t.projectId,I.recordType,x,{totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,filePaths:j.map((e=>e.normalized)),documentIds:P.map((e=>e.target)),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},n,u,i,o,I.metricsPrefix,s)
3351
- y=L,w=L,k=I.fileOperationPhase,o.incrementCounter("delete_files_phase",1,{phase:k})
3352
+ const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,A,t.projectId,b.recordType,x,{totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,filePaths:R.map((e=>e.normalized)),documentIds:P.map((e=>e.target)),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},n,u,i,o,b.metricsPrefix,s)
3353
+ y=L,w=L,k=b.fileOperationPhase,o.incrementCounter("delete_files_phase",1,{phase:k})
3352
3354
  const B=[]
3353
3355
  let H=0
3354
3356
  P.length>0&&r.setProjectId(t.projectId)
3355
- for(let e=0;e<j.length;e++){const t=j[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3357
+ for(let e=0;e<R.length;e++){const t=R[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3356
3358
  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)
3357
3359
  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 W=P.length>0?r.getDocumentClient():null
3358
3360
  for(const e of P){const t=e.target,n={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3359
3361
  try{let e
3360
- try{if(e=await W.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,b,i,o,"delete-document")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
3362
+ try{if(e=await W.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 d.ValidationError)throw Error(e.message)
3361
3363
  throw e}try{await(0,p.ensureDocumentNotLocked)(t,r,i,o,"delete-document-archive")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
3362
3364
  throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,f.getErrorMessage)(e)}`)}const s=await W.archiveDocument(t)
3363
3365
  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 U=Date.now()-m
@@ -3366,20 +3368,20 @@ let G=null
3366
3368
  if(H>0){k=l.FileOperationPhase.GIT_COMMIT,o.incrementCounter("delete_files_phase",1,{phase:k})
3367
3369
  const e=B.filter((e=>e.success)),r=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
3368
3370
  let s
3369
- 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,x,L,z,s,t,i,o,I.metricsPrefix)}k=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:k})
3371
+ 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,x,L,z,s,t,i,o,b.metricsPrefix)}k=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:k})
3370
3372
  const V=B.filter((e=>e.success)),J=B.filter((e=>!e.success))
3371
- await l.updateFileOperationRecords(C,y,w,x,I.recordType,H===M?`Successfully deleted all ${M} operations`:`Deleted ${H}/${M} operations successfully`,{status:H===M?"completed":"partial_success",commitHash:G?.commitHash,previousCommitHash:G?.previousCommitHash,totalOperations:M,fileOperations:T.length,documentOperations:P.length,successCount:H,failureCount:M-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===M?`Successfully deleted all ${M} operations`:`Deleted ${H}/${M} operations successfully`,n,u,i,o,I.metricsPrefix)
3372
- const Y=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3373
- let K=""
3373
+ await l.updateFileOperationRecords(C,y,w,x,b.recordType,H===M?`Successfully deleted all ${M} operations`:`Deleted ${H}/${M} operations successfully`,{status:H===M?"completed":"partial_success",commitHash:G?.commitHash,previousCommitHash:G?.previousCommitHash,totalOperations:M,fileOperations:T.length,documentOperations:P.length,successCount:H,failureCount:M-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===M?`Successfully deleted all ${M} operations`:`Deleted ${H}/${M} operations successfully`,n,u,i,o,b.metricsPrefix)
3374
+ const K=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3375
+ let Y=""
3374
3376
  if(H===M){const e=V.filter((e=>"file"===e.type)).length,t=V.filter((e=>"document"===e.type)).length
3375
- K=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 K=H>0?`Successfully deleted ${H}/${M} 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})`
3377
+ 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}/${M} 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})`
3376
3378
  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})`
3377
3379
  return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
3378
- return G?.commitHash&&(K+="\nCommit: "+G.commitHash.substring(0,8)),Y.requestId&&(K+="\nBranch: "+Y.requestId),F.lockAcquired&&F.lockedRequestId&&(K+="\n\u{1f512} **Locked request:** "+F.lockedRequestId),{content:[{type:"text",text:K}],isError:0===H}}catch(n){if(e.taskId&&r)try{const o=r.getToolRecordClient(),s=n instanceof d.NotFoundError||n instanceof d.ValidationError||n instanceof u.ZodError
3380
+ 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 d.NotFoundError||n instanceof d.ValidationError||n instanceof u.ZodError
3379
3381
  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
3380
3382
  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
3381
3383
  try{const t=r.getTaskClient(),s=r.getToolRecordClient()
3382
- await l.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",I.recordType,"Failed to delete operations",{status:"failed",error:(0,f.getErrorMessage)(n),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},"Failed to delete operations",t,s,i,o,I.metricsPrefix)}catch(t){i.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(n,k,i,o,e,I)}}
3384
+ await l.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",b.recordType,"Failed to delete operations",{status:"failed",error:(0,f.getErrorMessage)(n),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},"Failed to delete operations",t,s,i,o,b.metricsPrefix)}catch(t){i.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(n,k,i,o,e,b)}}
3383
3385
  const a=i(t(1943)),c=t(6183),l=s(t(5967)),d=t(9860),u=t(1569),h=t(7478),g=t(5003),p=t(9949),f=t(8824)},5997(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
3384
3386
  var o=Object.getOwnPropertyDescriptor(t,r)
3385
3387
  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=[]
@@ -3463,15 +3465,13 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
3463
3465
  var t={}
3464
3466
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
3465
3467
  return o(t,e),t})
3466
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,r,n,o,s,f){const m=n.child({tool:"specialist_ops"}),y=o.startTimer("tool_execution_time")
3468
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,r,n,o,s,p){const f=n.child({tool:"specialist_ops"}),m=o.startTimer("tool_execution_time")
3467
3469
  try{if(!e?.operation&&e&&(e.prompt&&!e.sessionId?e.operation="delegate":e.prompt&&e.sessionId?e.operation="follow-up":e.sessionId&&(e.operation="check-status")),e?.followUp&&"string"==typeof e.followUp)try{e.followUp=JSON.parse(e.followUp)}catch{}if(e?.delegate&&"string"==typeof e.delegate)try{e.delegate=JSON.parse(e.delegate)}catch{}if("string"==typeof e?.delegate){const t=e.delegate
3468
3470
  e.delegate={prompt:e.prompt||t,description:e.description||t.slice(0,60),specialization:e.specialization||"general",requestId:e.requestId},e.operation=e.operation||"delegate",delete e.prompt,delete e.description,delete e.specialization,delete e.requestId}"follow-up"===e?.operation&&e?.prompt&&!e?.followUp&&(e.followUp={prompt:e.prompt,specialization:e.specialization},delete e.prompt,e.specialization&&delete e.specialization),"delegate"===e?.operation&&e?.prompt&&!e?.delegate&&(e.delegate={prompt:e.prompt,description:e.description||e.prompt.slice(0,60),specialization:e.specialization||"general",requestId:e.requestId},delete e.prompt,delete e.description,delete e.specialization,delete e.requestId)
3469
- const n=c.validateArgs(e,a.SpecialistOpsSchema),{operation:w,sessionId:k}=n
3470
- let I
3471
- switch(m.info("Processing specialist_ops",{operation:w,sessionId:k}),w){case"delegate":{const e=n.delegate,o=10
3472
- let i=f?.sessionId||p.sessionIdentity.getIdentity()?.sessionId
3473
- if(!i){const e=await(0,h.getServerUrl)(r,m)
3474
- if(e)try{i=(0,g.getCachedSession)()?.sessionId||await(0,h.discoverParentSessionId)(e,m)}catch{}}if(i&&s){const e=await async function(e,t,r,n,o){n.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
3471
+ const n=c.validateArgs(e,a.SpecialistOpsSchema),{operation:y,sessionId:w}=n
3472
+ let k
3473
+ switch(f.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=n.delegate,o=10,i=p?.sessionId||g.sessionIdentity.getIdentity()?.sessionId
3474
+ if(i&&s){const e=await async function(e,t,r,n,o){n.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
3475
3475
  const s=await(0,h.getServerUrl)(r,n)
3476
3476
  if(s)try{const r=await fetch(s.replace(/\/$/,"")+"/session")
3477
3477
  if(!r.ok)return
@@ -3484,34 +3484,33 @@ return"specialist"===t?.agentType&&"archived"!==t?.status}))
3484
3484
  if(n.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
3485
3485
  const g=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
3486
3486
  return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
3487
- return{content:[{type:"text",text:`\u274c Specialist pool is full (${h.length}/${t}).\nAbort an idle specialist first with \`specialist_ops abort\`, then delegate again.\n\nCurrent pool:\n`+g}],isError:!0}}catch(e){return void n.warn("Pool limit check failed, allowing spawn",{error:(0,l.getErrorMessage)(e)})}}(i,o,r,m,s)
3488
- if(e){I=e
3487
+ return{content:[{type:"text",text:`\u274c Specialist pool is full (${h.length}/${t}).\nAbort an idle specialist first with \`specialist_ops abort\`, then delegate again.\n\nCurrent pool:\n`+g}],isError:!0}}catch(e){return void n.warn("Pool limit check failed, allowing spawn",{error:(0,l.getErrorMessage)(e)})}}(i,o,r,f,s)
3488
+ if(e){k=e
3489
3489
  break}}let a=e.description
3490
- const c=await Promise.resolve().then(t.t.bind(t,9896,23)),y=e=>c.appendFileSync("/tmp/specialist-name-debug.log",`${(new Date).toISOString()} ${e}\n`)
3491
- if(i)try{const e=await(0,h.getServerUrl)(r,m)
3492
- if(y(`serverUrl=${e}, parentId=${i}`),e){const t=await fetch(e.replace(/\/$/,"")+"/session")
3493
- if(y("session fetch status="+t.status),t.ok){const e=(await t.json()).filter((e=>(e.parentId||e.parentID)===i)).map((e=>e.title||""))
3494
- y(`siblings=${e.length}: ${e.join(", ")}`)
3490
+ const c=await Promise.resolve().then(t.t.bind(t,9896,23)),m=e=>c.appendFileSync("/tmp/specialist-name-debug.log",`${(new Date).toISOString()} ${e}\n`)
3491
+ if(i)try{const e=await(0,h.getServerUrl)(r,f)
3492
+ if(m(`serverUrl=${e}, parentId=${i}`),e){const t=await fetch(e.replace(/\/$/,"")+"/session")
3493
+ if(m("session fetch status="+t.status),t.ok){const e=(await t.json()).filter((e=>(e.parentId||e.parentID)===i)).map((e=>e.title||""))
3494
+ m(`siblings=${e.length}: ${e.join(", ")}`)
3495
3495
  const r=(0,d.pickSpecialistName)(e)
3496
- a=r,y("picked name: "+r)}}else y("no serverUrl")}catch(e){y("error: "+(e instanceof Error?e.message:e+""))}else y("no parentId")
3497
- const w=e.requestId,k=w?`Working on request ${w}.\n\n${e.prompt}`:e.prompt
3498
- I=await(0,u.handleSpawn)({agent:"specialist",prompt:k,title:a,specialization:e.specialization},r,m,s,f)
3499
- break}case"follow-up":{const e=await(0,h.getServerUrl)(r,m)
3496
+ a=r,m("picked name: "+r)}}else m("no serverUrl")}catch(e){m("error: "+(e instanceof Error?e.message:e+""))}else m("no parentId")
3497
+ const y=e.requestId,w=y?`Working on request ${y}.\n\n${e.prompt}`:e.prompt
3498
+ k=await(0,u.handleSpawn)({agent:"specialist",prompt:w,title:a,specialization:e.specialization},r,f,s,p)
3499
+ break}case"follow-up":{const e=await(0,h.getServerUrl)(r,f)
3500
3500
  if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
3501
- if(t.ok){const e=await t.json(),r=e[k]?.type
3502
- if(r&&"idle"!==r&&"prompting"!==r){I={content:[{type:"text",text:`\u274c Specialist ${k} is currently busy (status: ${r}).\nUse \`delegate\` to spawn a new specialist instead.`}],isError:!0}
3503
- break}}}catch{}I=await(0,u.handleContinue)(k,n.followUp.prompt,r,m,s,"specialist",f)
3501
+ if(t.ok){const e=await t.json(),r=e[w]?.type
3502
+ if(r&&"idle"!==r&&"prompting"!==r){k={content:[{type:"text",text:`\u274c Specialist ${w} is currently busy (status: ${r}).\nUse \`delegate\` to spawn a new specialist instead.`}],isError:!0}
3503
+ break}}}catch{}k=await(0,u.handleContinue)(w,n.followUp.prompt,r,f,s,"specialist",p)
3504
3504
  const t=n.followUp.specialization
3505
3505
  if(t&&s)try{const e=s.getCLISessionClient()
3506
- e&&(await e.createOrUpdateSession({externalSessionId:k,specialization:t}),I.content[0].text+="\nSpecialization updated to: "+t)}catch{}break}case"check-status":I=await(0,u.handleCheckStatus)(k,r,m,s)
3506
+ e&&(await e.createOrUpdateSession({externalSessionId:w,specialization:t}),k.content[0].text+="\nSpecialization updated to: "+t)}catch{}break}case"check-status":k=await(0,u.handleCheckStatus)(w,r,f,s)
3507
3507
  break
3508
- case"abort":if(I=await(0,u.handleAbort)(k,r,m),!I.isError&&s)try{const e=s.getCLISessionClient()
3509
- e&&await e.createOrUpdateSession({externalSessionId:k,status:"archived"})}catch{}break
3510
- case"list":{let e=f?.sessionId||p.sessionIdentity.getIdentity()?.sessionId
3511
- if(!e){const t=await(0,h.getServerUrl)(r,m)
3512
- if(t)try{e=(0,g.getCachedSession)()?.sessionId||await(0,h.discoverParentSessionId)(t,m)}catch{}}I=await(0,u.handleListSessions)(r,m,s,{activeOnly:n.list?.activeOnly,requestId:n.list?.requestId,limit:n.list?.limit,agentType:"specialist",parentSessionId:e})
3513
- break}default:throw new i.ValidationError("Unknown operation: "+w)}return y({success:!0}),o.incrementCounter(`specialist_ops_${w}_success`,1),I}catch(e){return m.error("Specialist ops failed",{error:e instanceof Error?e.stack:e+""}),y({success:!1}),o.incrementCounter("specialist_ops_errors",1),{content:[{type:"text",text:"Specialist operation failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
3514
- const i=t(9860),a=t(6183),c=s(t(5967)),l=t(8824),d=t(9089),u=t(1725),h=t(7617),g=t(715),p=t(6688)},6315(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3508
+ case"abort":if(k=await(0,u.handleAbort)(w,r,f),!k.isError&&s)try{const e=s.getCLISessionClient()
3509
+ e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
3510
+ case"list":{const e=p?.sessionId||g.sessionIdentity.getIdentity()?.sessionId
3511
+ k=await(0,u.handleListSessions)(r,f,s,{activeOnly:n.list?.activeOnly,requestId:n.list?.requestId,limit:n.list?.limit,agentType:"specialist",parentSessionId:e})
3512
+ break}default:throw new i.ValidationError("Unknown operation: "+y)}return m({success:!0}),o.incrementCounter(`specialist_ops_${y}_success`,1),k}catch(e){return f.error("Specialist ops failed",{error:e instanceof Error?e.stack:e+""}),m({success:!1}),o.incrementCounter("specialist_ops_errors",1),{content:[{type:"text",text:"Specialist operation failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
3513
+ const i=t(9860),a=t(6183),c=s(t(5967)),l=t(8824),d=t(9089),u=t(1725),h=t(7617),g=t(6688)},6315(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3515
3514
  const r=t(6183),n=t(2982)
3516
3515
  exports.def={name:"generate_request_journal",description:"Fetch comprehensive data about a request for writing a journal entry.\n\nReturns structured data including:\n\u2022 Request details (title, description, type, status, acceptance criteria)\n\u2022 All tasks with descriptions and status\n\u2022 File changes summary (files modified, operations performed)\n\u2022 Chronological operation history\n\nUse this data to write a narrative journal entry and save it as:\nJOURNAL-{requestId}.md using document-operations (create).",schema:r.GenerateRequestJournalSchema,annotations:{title:"Generate Request Journal",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0},readOnly:!0,hidden(){return"journal"!==process.env.ALCHEMY_MODE},handler(e,t){return(0,n.handleGenerateRequestJournal)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},6416(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
3517
3516
  var o=Object.getOwnPropertyDescriptor(t,r)
@@ -3588,7 +3587,7 @@ var t={}
3588
3587
  if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
3589
3588
  return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3590
3589
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleInsertLines=async function(e,t,n,o,s,i,a,m){const y=i.child({tool:"insert_lines"}),w=Date.now()
3591
- let k,I,b=d.FileOperationPhase.VALIDATION
3590
+ let k,b,I=d.FileOperationPhase.VALIDATION
3592
3591
  const v={toolName:"insert-lines",operationName:"insert-lines",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"insert-lines",metricsPrefix:"insert_lines",successMessage:"Successfully inserted lines into files and documents",failureMessage:"Failed to insert lines into files and documents"}
3593
3592
  try{const i=d.validateArgs(e,l.InsertLinesSchema),{taskId:C,operations:_,comment:E}=i
3594
3593
  if(y.info("Inserting lines into files and documents",{taskId:C,operationCount:_.length,comment:E}),!_||0===_.length)throw new u.ValidationError("At least one operation is required")
@@ -3601,21 +3600,21 @@ if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not ava
3601
3600
  for(const e of S)P.push({type:"document",documentId:e.documentId,insertions:e.insertions})
3602
3601
  if(P.length>0&&t.apiClient){const e=P.map((e=>e.documentId))
3603
3602
  try{await(0,p.ensureDocumentsNotLocked)(e,t.apiClient,y,a,"insert-lines-documents")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3604
- throw e}}b=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("insert_lines_phase",1,{phase:b})
3605
- const M=T.length>0?T[0].path:"document-operation",R=await d.validateTaskId(C,M,n,y,a,v.metricsPrefix),j=R?.requestId
3603
+ throw e}}I=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("insert_lines_phase",1,{phase:I})
3604
+ const M=T.length>0?T[0].path:"document-operation",j=await d.validateTaskId(C,M,n,y,a,v.metricsPrefix),R=j?.requestId
3606
3605
  let x=null
3607
- T.length>0&&j&&(x=await d.validateWorkItemStates(C,T[0].path,n,s,t,y,a,v.metricsPrefix))
3606
+ T.length>0&&R&&(x=await d.validateWorkItemStates(C,T[0].path,n,s,t,y,a,v.metricsPrefix))
3608
3607
  let O={taskPromoted:!1,requestPromoted:!1}
3609
- T.length>0&&j&&x&&(O=await d.autoPromoteTaskStatus(C,R.status,j,x.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:j,previousStatus:R.status,newStatus:O.newTaskStatus,triggeringOperation:"insert-lines"}))
3610
- const A=await d.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:j,context:t,operation:"insert-lines",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
3608
+ T.length>0&&R&&x&&(O=await d.autoPromoteTaskStatus(C,j.status,R,x.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:R,previousStatus:j.status,newStatus:O.newTaskStatus,triggeringOperation:"insert-lines"}))
3609
+ const A=await d.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:R,context:t,operation:"insert-lines",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
3611
3610
  if(!A.success){if(A.isLockConflict)return{content:[{type:"text",text:"\u274c "+A.error}],isError:!0}
3612
3611
  throw Error(A.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3613
3612
  for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
3614
- T[e]={...r,path:o,fullPath:s}}}if(P.length>0&&j)try{await(0,h.validateRequestStatusForDocumentOperation)(j,s,y,a,"insert-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3615
- throw e}b=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("insert_lines_phase",1,{phase:b})
3616
- const D=[...T.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...P.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:$}=await d.createFileOperationRecords(C,j,t.projectId,v.recordType,M,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:D,userComment:E},n,o,y,a,v.metricsPrefix,m)
3617
- if(k=$,I=$,b=v.fileOperationPhase,a.incrementCounter("insert_lines_phase",1,{phase:b}),T.length>0&&t.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
3618
- const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"insert-lines",{requestId:j,taskId:C,workspaceManager:t.workspaceManager},y,a)
3613
+ T[e]={...r,path:o,fullPath:s}}}if(P.length>0&&R)try{await(0,h.validateRequestStatusForDocumentOperation)(R,s,y,a,"insert-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3614
+ throw e}I=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("insert_lines_phase",1,{phase:I})
3615
+ const D=[...T.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...P.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:$}=await d.createFileOperationRecords(C,R,t.projectId,v.recordType,M,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:D,userComment:E},n,o,y,a,v.metricsPrefix,m)
3616
+ if(k=$,b=$,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")
3617
+ const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"insert-lines",{requestId:R,taskId:C,workspaceManager:t.workspaceManager},y,a)
3619
3618
  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})
3620
3619
  const F=[]
3621
3620
  let N=0,L=0,z=0
@@ -3627,46 +3626,46 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
3627
3626
  n.filename=s?.filename
3628
3627
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
3629
3628
  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(P.length>0)try{for(const e of P){const r=F.find((t=>t.documentId===e.documentId))
3630
- r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const B=await d.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),H=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:W,failedOperations:U,totalSuccessfulChanges:G,overallSuccess:V,successfulFiles:J,failedFiles:Y}=H
3631
- try{await o.updateToolRecord(I,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:V?"completed":"failed",error:V?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:Y,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: ${W}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let K="## Line Insertion Results\n\n"
3632
- if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${W+U}\n`,K+=`- **Successful operations:** ${W}\n`,K+=`- **Failed operations:** ${U}\n`,K+=`- **Total insertions:** ${G} successful, ${N} failed\n`,K+=`- **Total Lines Added:** ${L}\n`,K+="\n",B.success&&B.commitHash&&(K+="**Git Commit:**\n",K+=`- **Commit Hash:** ${B.commitHash.substring(0,8)}\n`,K+=`- **Files Committed:** ${B.filesCommitted.length}\n`,B.previousCommitHash&&(K+=`- **Previous Commit:** ${B.previousCommitHash.substring(0,8)}\n`),K+="\n"),A.lockAcquired&&A.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${A.lockedRequestId}\n\n`),1===F.length){const e=F[0]
3633
- 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+=`**Insertions:** ${e.successfulInsertions} successful`,e.failedInsertions>0&&(K+=`, ${e.failedInsertions} failed`),K+="\n",K+=`**Lines Added:** ${e.totalLinesAdded}\n`),e.insertions.some((e=>!e.success))){K+="**Failed Insertion Details:**\n"
3629
+ r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const B=await d.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:b,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),H=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:W,failedOperations:U,totalSuccessfulChanges:G,overallSuccess:V,successfulFiles:J,failedFiles:K}=H
3630
+ try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:V?"completed":"failed",error:V?void 0:U+" 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: ${W}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
3631
+ if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${W+U}\n`,Y+=`- **Successful operations:** ${W}\n`,Y+=`- **Failed operations:** ${U}\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"),A.lockAcquired&&A.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${A.lockedRequestId}\n\n`),1===F.length){const e=F[0]
3632
+ 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"
3634
3633
  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}`
3635
- K+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{K+="**Summary:**\n",K+=`- **Total Operations:** ${F.length}\n`,K+=`- **Successful:** ${W}\n`,K+=`- **Failed:** ${U}\n`,K+=`- **Total Insertions:** ${G} successful, ${N} failed\n`,K+=`- **Total Lines Added:** ${L}\n\n`,K+="**Detailed Results:**\n\n"
3636
- 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+=`- **Insertions:** ${e.successfulInsertions} successful`,e.failedInsertions>0&&(K+=`, ${e.failedInsertions} failed`),K+="\n",K+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.insertions.some((e=>!e.success))){K+="- **Failed Insertion Details:**\n"
3634
+ Y+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{Y+="**Summary:**\n",Y+=`- **Total Operations:** ${F.length}\n`,Y+=`- **Successful:** ${W}\n`,Y+=`- **Failed:** ${U}\n`,Y+=`- **Total Insertions:** ${G} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n\n`,Y+="**Detailed Results:**\n\n"
3635
+ 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"
3637
3636
  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}`
3638
- K+=` - ${t.type} insertion ${e}: ${t.error}\n`}}K+="\n"}}P.length>0&&(K+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3637
+ Y+=` - ${t.type} insertion ${e}: ${t.error}\n`}}Y+="\n"}}P.length>0&&(Y+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3639
3638
  const Q=Date.now()-w
3640
- return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:W,failedOperations:U}),a.incrementCounter("insert_lines_total",1,{success:V}),{content:[{type:"text",text:K}],isError:!V}}catch(t){const r=Date.now()-w
3641
- if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:b}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,f.getErrorMessage)(t),phase:b,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("insert_lines_errors",1,{phase:b}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
3639
+ return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:W,failedOperations:U}),a.incrementCounter("insert_lines_total",1,{success:V}),{content:[{type:"text",text:Y}],isError:!V}}catch(t){const r=Date.now()-w
3640
+ 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}}}
3642
3641
  const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824),m=t(3255)},6539(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
3643
3642
  const r=t(1253),n=t(5681),o=t(6595),s=t(3895),i=t(6848),a=t(6153),c=t(4710),l=t(6975),d=t(1887),u=t(1666),h=t(8824),g=t(9884),p=t(2968),f=t(922)
3644
3643
  exports.ClientFactory=class{static async createClient(e,m,y,w={}){(m=m.child({component:"client-factory"})).info("Creating API client with components")
3645
3644
  const k=w.tokenManager||new r.TokenManager(m,w.workingDir||process.cwd())
3646
3645
  await k.initialize()
3647
- const I=w.tokenSynchronizer||new i.ClientTokenSynchronizer(m),b=new s.AuthenticationManager(k,m,I),v=await b.getTokenString(),C=w.connectionStatusManager||new n.ConnectionStatusManager(e,m,y,{alchemyPath:w.alchemyPath,checkIntervalMs:w.offlineCheckIntervalMs,timeoutMs:w.timeout,retryCount:w.retryAttempts}),_=new c.ProjectClient(e,m,y,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3648
- I.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
3646
+ const b=w.tokenSynchronizer||new i.ClientTokenSynchronizer(m),I=new s.AuthenticationManager(k,m,b),v=await I.getTokenString(),C=w.connectionStatusManager||new n.ConnectionStatusManager(e,m,y,{alchemyPath:w.alchemyPath,checkIntervalMs:w.offlineCheckIntervalMs,timeoutMs:w.timeout,retryCount:w.retryAttempts}),_=new c.ProjectClient(e,m,y,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3647
+ b.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
3649
3648
  const E=new p.TaskClient(e,m,y,_,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3650
- I.registerClient(E)
3649
+ b.registerClient(E)
3651
3650
  const q=new a.FileOperationsClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3652
- I.registerClient(q),m.info("RequestClient constructor received token: "+(v?"present":"missing"))
3651
+ b.registerClient(q),m.info("RequestClient constructor received token: "+(v?"present":"missing"))
3653
3652
  const S=new u.RequestClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3654
- I.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
3653
+ b.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
3655
3654
  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})
3656
- I.registerClient(T)
3655
+ b.registerClient(T)
3657
3656
  const P=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})
3658
- I.registerClient(P)
3657
+ b.registerClient(P)
3659
3658
  const M=new d.ProxyClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3660
- if(I.registerClient(M),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
3659
+ if(b.registerClient(M),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
3661
3660
  try{m.info("Creating ProjectSynchronizer components")
3662
3661
  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})
3663
3662
  _.setProjectSynchronizer(n),m.info("ProjectSynchronizer created and connected to ProjectClient")}catch(e){const t="Failed to create required ProjectSynchronizer components: "+(0,h.getErrorMessage)(e)
3664
- throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const R=new o.ApiClient(b,_,E,q,S,T,P,M,m)
3665
- m.info("API client initialized with specialized clients"),v?(R.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"})
3666
- const j=I.verifyAllClients()
3667
- j.success?m.info("Token consistency verified across all clients"):m.error(`Token inconsistency detected in ${j.failedClients.length} clients: ${j.failedClients.join(", ")}`)
3668
- const x=R.getAuthToken()
3669
- return v&&!x?(m.error("CRITICAL: ApiClient token was not set properly!"),R.setAuthToken(v)):x&&m.info("ApiClient token verified",{tokenLength:x.length,matches:x===v}),m.info("API client creation completed successfully"),R}}},6540(e,exports){var t
3663
+ throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const j=new o.ApiClient(I,_,E,q,S,T,P,M,m)
3664
+ m.info("API client initialized with specialized clients"),v?(j.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"})
3665
+ const R=b.verifyAllClients()
3666
+ R.success?m.info("Token consistency verified across all clients"):m.error(`Token inconsistency detected in ${R.failedClients.length} clients: ${R.failedClients.join(", ")}`)
3667
+ const x=j.getAuthToken()
3668
+ return v&&!x?(m.error("CRITICAL: ApiClient token was not set properly!"),j.setAuthToken(v)):x&&m.info("ApiClient token verified",{tokenLength:x.length,matches:x===v}),m.info("API client creation completed successfully"),j}}},6540(e,exports){var t
3670
3669
  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={}))},6595(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ApiClient=void 0
3671
3670
  const r=t(1599),n=t(2690),o=t(4465),s=t(5187),i=t(5674),a=t(8824)
3672
3671
  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
@@ -3704,7 +3703,7 @@ var t={}
3704
3703
  if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
3705
3704
  return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3706
3705
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceLines=async function(e,t,n,o,s,i,a,m){const w=i.child({tool:"replace_lines"}),k=Date.now()
3707
- let I,b,v=d.FileOperationPhase.VALIDATION
3706
+ let b,I,v=d.FileOperationPhase.VALIDATION
3708
3707
  const C={toolName:"replace-lines",operationName:"replace-lines",fileOperationPhase:d.FileOperationPhase.STRING_REPLACEMENT,recordType:"replace-lines",metricsPrefix:"replace_lines",successMessage:"Successfully replaced lines in files and documents",failureMessage:"Failed to replace lines in files and documents"}
3709
3708
  try{const i=d.validateArgs(e,l.ReplaceLinesSchema),{taskId:_,operations:E,comment:q}=i
3710
3709
  if(w.info("Replacing lines in files and documents",{taskId:_,operationCount:E.length,comment:q}),!E||0===E.length)throw new u.ValidationError("At least one operation is required")
@@ -3718,19 +3717,19 @@ for(const e of T)M.push({type:"document",documentId:e.documentId,replacements:e.
3718
3717
  if(M.length>0&&t.apiClient){const e=M.map((e=>e.documentId))
3719
3718
  try{await(0,p.ensureDocumentsNotLocked)(e,t.apiClient,w,a,"replace-lines-documents")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3720
3719
  throw e}}v=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
3721
- const R=P.length>0?P[0].path:"document-operation",j=await d.validateTaskId(_,R,n,w,a,C.metricsPrefix),x=j?.requestId
3720
+ const j=P.length>0?P[0].path:"document-operation",R=await d.validateTaskId(_,j,n,w,a,C.metricsPrefix),x=R?.requestId
3722
3721
  let O=null
3723
3722
  P.length>0&&x&&(O=await d.validateWorkItemStates(_,P[0].path,n,s,t,w,a,C.metricsPrefix))
3724
3723
  let A={taskPromoted:!1,requestPromoted:!1}
3725
- P.length>0&&x&&O&&(A=await d.autoPromoteTaskStatus(_,j.status,x,O.request?.status,P[0].path,n,s,w,a,C.metricsPrefix),A.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:_,requestId:x,previousStatus:j.status,newStatus:A.newTaskStatus,triggeringOperation:"replace-lines"}))
3724
+ P.length>0&&x&&O&&(A=await d.autoPromoteTaskStatus(_,R.status,x,O.request?.status,P[0].path,n,s,w,a,C.metricsPrefix),A.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:_,requestId:x,previousStatus:R.status,newStatus:A.newTaskStatus,triggeringOperation:"replace-lines"}))
3726
3725
  const D=await d.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:x,context:t,operation:"replace-lines",logger:w,metrics:a,metricsPrefix:C.metricsPrefix})
3727
3726
  if(!D.success){if(D.isLockConflict)return{content:[{type:"text",text:"\u274c "+D.error}],isError:!0}
3728
3727
  throw Error(D.error)}if(P.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:P.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3729
3728
  for(let e=0;e<P.length;e++){const r=P[e],n=S[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
3730
3729
  P[e]={...r,path:o,fullPath:s}}}if(M.length>0&&x)try{await(0,h.validateRequestStatusForDocumentOperation)(x,s,w,a,"replace-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3731
3730
  throw e}v=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
3732
- const $=[...P.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...M.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await d.createFileOperationRecords(_,x,t.projectId,C.recordType,R,{operationCount:E.length,fileOperations:P.length,documentOperations:M.length,operations:$,userComment:q},n,o,w,a,C.metricsPrefix,m)
3733
- if(I=F,b=F,v=C.fileOperationPhase,a.incrementCounter("replace_lines_phase",1,{phase:v}),P.length>0&&t.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
3731
+ const $=[...P.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...M.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await d.createFileOperationRecords(_,x,t.projectId,C.recordType,j,{operationCount:E.length,fileOperations:P.length,documentOperations:M.length,operations:$,userComment:q},n,o,w,a,C.metricsPrefix,m)
3732
+ if(b=F,I=F,v=C.fileOperationPhase,a.incrementCounter("replace_lines_phase",1,{phase:v}),P.length>0&&t.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
3734
3733
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},w,a)
3735
3734
  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:P.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:P.length,error:e instanceof Error?e.message:e+""})}w.debug("[REPLACE-LINES] Proceeding with file operations",{fileCount:P.length})
3736
3735
  const N=[]
@@ -3743,33 +3742,33 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
3743
3742
  n.filename=s?.filename
3744
3743
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
3745
3744
  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(M.length>0)try{for(const e of M){const r=N.find((t=>t.documentId===e.documentId))
3746
- r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const W=await d.handleMultiFileGitCommit(_,P,N,H,{operationType:"Replace lines",toolRecordId:b,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),U=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:Y,successfulFiles:K,failedFiles:Q}=U
3747
- try{await o.updateToolRecord(b,{metadata:{path:P.length>0?P[0].path:"document:"+M[0]?.documentId,status:Y?"completed":"failed",error:Y?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:K,failedFiles:Q,operations:$,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-k,userComment:q,...P.length>0&&W.success&&W.commitHash&&{commitHash:W.commitHash,previousCommitHash:W.previousCommitHash||void 0}},note:Y?`Line replacement completed: ${G}/${N.length} operations successful${P.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"
3745
+ r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const W=await d.handleMultiFileGitCommit(_,P,N,H,{operationType:"Replace lines",toolRecordId:I,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),U=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=U
3746
+ try{await o.updateToolRecord(I,{metadata:{path:P.length>0?P[0].path:"document:"+M[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:$,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-k,userComment:q,...P.length>0&&W.success&&W.commitHash&&{commitHash:W.commitHash,previousCommitHash:W.previousCommitHash||void 0}},note:K?`Line replacement completed: ${G}/${N.length} operations successful${P.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"
3748
3747
  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",W.success&&W.commitHash&&(Z+="**Git Commit:**\n",Z+=`- **Commit Hash:** ${W.commitHash.substring(0,8)}\n`,Z+=`- **Files Committed:** ${W.filesCommitted.length}\n`,W.previousCommitHash&&(Z+=`- **Previous Commit:** ${W.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]
3749
3748
  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"
3750
3749
  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"
3751
3750
  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"
3752
3751
  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"}}M.length>0&&(Z+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3753
3752
  const X=Date.now()-k
3754
- return w.info("Replace lines operation completed",{duration:X,success:Y,totalOperations:N.length,successfulOperations:G,failedOperations:V}),a.incrementCounter("replace_lines_total",1,{success:Y}),{content:[{type:"text",text:Z}],isError:!Y}}catch(t){const r=Date.now()-k
3755
- if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),b)try{await o.updateToolRecord(b,{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}}}
3753
+ 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
3754
+ 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}}}
3756
3755
  const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824),m=t(3255),y=t(9470)},6688(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
3757
3756
  const r=t(9896),n=t(6928)
3758
- exports.sessionIdentity=new class{constructor(){this.discoveryAttempted=!1,this.parentCache=new Map}setIdentity(e){const t=this.identity
3757
+ exports.sessionIdentity=new class{constructor(){this.parentCache=new Map}setIdentity(e){const t=this.identity
3759
3758
  this.identity=e,this.log("setIdentity",{sessionId:e.sessionId,serverUrl:e.serverUrl,agentType:e.agentType||null,prevSessionId:t?.sessionId||null,changed:t?.sessionId!==e.sessionId})}getIdentity(){return this.identity}updateIdentity(e){if(this.identity){const t={...this.identity}
3760
- this.identity={...this.identity,...e},this.log("updateIdentity",{sessionId:this.identity.sessionId,updates:Object.keys(e),agentTypeBefore:t.agentType||null,agentTypeAfter:this.identity.agentType||null})}}reset(){const e=this.identity
3761
- this.identity=void 0,this.discoveryAttempted=!1,this.log("reset",{prevSessionId:e?.sessionId||null,prevAgentType:e?.agentType||null})}hasDiscoveryBeenAttempted(){return this.discoveryAttempted}markDiscoveryAttempted(){this.discoveryAttempted=!0}async getParentSessionId(e,t,r){if(this.parentCache.has(e)){const t=this.parentCache.get(e)
3759
+ this.identity={...this.identity,...e},this.log("updateIdentity",{sessionId:this.identity.sessionId,updates:Object.keys(e),agentTypeBefore:t.agentType||null,agentTypeAfter:this.identity.agentType||null})}}async getParentSessionId(e,t,r){if(this.parentCache.has(e)){const t=this.parentCache.get(e)
3762
3760
  return this.log("getParentSessionId.cache-hit",{childExternalId:e,parentExternalId:t}),t}try{const n=t.getCLISessionClient()
3763
3761
  if(!n)return r.warn("CLI session client not available"),null
3764
3762
  const o=await n.getParent(e),s=o?.externalSessionId||null
3765
3763
  return this.parentCache.set(e,s),this.log("getParentSessionId.resolved",{childExternalId:e,parentExternalId:s}),s||r.warn("Parent session not found",{sessionId:e}),s}catch(t){const n=t instanceof Error?t.message:t+""
3766
- return r.warn("Error getting parent session",{sessionId:e,error:n}),null}}setParentSessionId(e,t){this.parentCache.set(e,t)}async getSessionRequestId(e,t){if(!this.identity?.sessionId)return t.warn("Cannot get session request: no session identity"),null
3764
+ return r.warn("Error getting parent session",{sessionId:e,error:n}),null}}setParentSessionId(e,t){this.parentCache.set(e,t)}async getSessionRequestId(e,t,r){const n=r||this.identity?.sessionId
3765
+ if(!n)return t.warn("Cannot get session request: no session identity"),null
3767
3766
  try{const r=e.getSessionRequestAssociationClient?.()
3768
3767
  if(!r)return t.warn("Session request association client not available"),null
3769
- const n=await r.getActiveRequestsForSession(this.identity.sessionId)
3770
- if(n?.length>0){const e=n[0].requestLocalId||n[0].request_local_id
3771
- return this.log("getSessionRequestId.resolved",{sessionId:this.identity.sessionId,requestId:e}),e||null}return this.log("getSessionRequestId.none",{sessionId:this.identity.sessionId}),null}catch(e){const r=e instanceof Error?e.message:e+""
3772
- return t.warn("Error getting session request",{sessionId:this.identity.sessionId,error:r}),null}}buildCliOrigin(e){if(this.identity)return{providerId:this.identity.providerId,sessionId:this.identity.sessionId,messageId:e,createdAt:(new Date).toISOString()}}setCurrentCallOrigin(e){this.currentCallOrigin=e}getCurrentCallOrigin(){return this.currentCallOrigin||this.buildCliOrigin()}log(e,t){try{const o=process.env.ALCHEMY_PROJECT_PATH||process.cwd(),s=(0,n.join)(o,".alchemy_lab");(0,r.existsSync)(s)||(0,r.mkdirSync)(s,{recursive:!0})
3768
+ const o=await r.getActiveRequestsForSession(n)
3769
+ if(o?.length>0){const e=o[0].requestLocalId||o[0].request_local_id
3770
+ return this.log("getSessionRequestId.resolved",{sessionId:n,requestId:e}),e||null}return this.log("getSessionRequestId.none",{sessionId:n}),null}catch(e){const r=e instanceof Error?e.message:e+""
3771
+ return t.warn("Error getting session request",{sessionId:n,error:r}),null}}buildCliOrigin(e){if(this.identity)return{providerId:this.identity.providerId,sessionId:this.identity.sessionId,messageId:e,createdAt:(new Date).toISOString()}}setCurrentCallOrigin(e){this.currentCallOrigin=e}getCurrentCallOrigin(){return this.currentCallOrigin||this.buildCliOrigin()}log(e,t){try{const o=process.env.ALCHEMY_PROJECT_PATH||process.cwd(),s=(0,n.join)(o,".alchemy_lab");(0,r.existsSync)(s)||(0,r.mkdirSync)(s,{recursive:!0})
3773
3772
  const i=(0,n.join)(s,"mcp-identity-debug.log"),a=(new Date).toISOString(),c=process.pid,l=t?" "+JSON.stringify(t):"";(0,r.appendFileSync)(i,`[${a}] [PID:${c}] identity.${e}${l}\n`)}catch{}}},exports.sessionIdentity.log("module-load",{ALCHEMY_SESSION_TAG:process.env.ALCHEMY_SESSION_TAG||null,ALCHEMY_INITIAL_BRANCH:process.env.ALCHEMY_INITIAL_BRANCH||null,ALCHEMY_ALLOW_PARALLEL:process.env.ALCHEMY_ALLOW_PARALLEL||null})},6756(e,exports){var t,r
3774
3773
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.TaskStatus=exports.RequestStatus=void 0,function(e){e.OPEN="open",e.IN_PROGRESS="in_progress",e.COMPLETED="completed",e.CONFLICTED="conflicted",e.READY_FOR_REVIEW="ready_for_review",e.PENDING_APPROVAL="pending_approval"}(t||(exports.RequestStatus=t={})),function(e){e.PENDING="pending",e.IN_PROGRESS="in_progress",e.READY_FOR_REVIEW="ready_for_review",e.COMPLETED="completed"}(r||(exports.TaskStatus=r={}))},6770(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3775
3774
  const r=t(6183),n=t(6651)
@@ -3829,16 +3828,16 @@ let w
3829
3828
  r.setProjectId(y)
3830
3829
  try{const P=await f.getTask(g)
3831
3830
  s.info("Raw task response data",{responseDataType:typeof P,isArray:Array.isArray(P),hasData:null!=P,properties:P&&"object"==typeof P?Object.keys(P):[]}),w=(0,l.extractDataFromResponse)(P,{logger:s,operationName:"getTask",defaultValue:{id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+w.title)}catch(M){s.warn("Could not fetch task information: "+(0,u.getErrorMessage)(M)),w={id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let k=[]
3832
- try{const R=await m.getToolRecordsByTaskId(g)
3833
- if(s.info("Raw records response data",{responseDataType:typeof R,isArray:Array.isArray(R),hasData:null!=R,properties:R&&"object"==typeof R?Object.keys(R):[]}),k=(0,l.extractArrayFromResponse)(R,{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 j={}
3834
- k.forEach((e=>{j[e.type]=(j[e.type]||0)+1})),s.info("Record type distribution:",j)}}catch(x){s.warn("Error fetching records for task "+g,{error:(0,u.getErrorMessage)(x)}),k=[]}if(0===k.length)return h({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
3835
- function I(e){const t=new Map,r=new Map,n=[]
3831
+ try{const j=await m.getToolRecordsByTaskId(g)
3832
+ if(s.info("Raw records response data",{responseDataType:typeof j,isArray:Array.isArray(j),hasData:null!=j,properties:j&&"object"==typeof j?Object.keys(j):[]}),k=(0,l.extractArrayFromResponse)(j,{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 R={}
3833
+ k.forEach((e=>{R[e.type]=(R[e.type]||0)+1})),s.info("Record type distribution:",R)}}catch(x){s.warn("Error fetching records for task "+g,{error:(0,u.getErrorMessage)(x)}),k=[]}if(0===k.length)return h({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
3834
+ function b(e){const t=new Map,r=new Map,n=[]
3836
3835
  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
3837
3836
  if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
3838
3837
  t.set(e,i),r.set(s,i),n.push(i)}}else if("move-files"===o.type&&o.metadata){const e=[...o.metadata.successfulOperations||[],...o.metadata.failedOperations||[]]
3839
3838
  for(const s of e)if(s.source&&s.destination){const e={source:s.source,destination:s.destination,recordId:o.id,timestamp:o.createdAt,type:"move-files"}
3840
- t.set(s.source,e),r.set(s.destination,e),n.push(e)}}return{sourceToMove:t,destToMove:r,allMoves:n}}const b=I(k)
3841
- s.info(`Detected ${b.allMoves.length} move operations`)
3839
+ t.set(s.source,e),r.set(s.destination,e),n.push(e)}}return{sourceToMove:t,destToMove:r,allMoves:n}}const I=b(k)
3840
+ s.info(`Detected ${I.allMoves.length} move operations`)
3842
3841
  const v=k.filter((e=>{if(!e||"object"!=typeof e)return s.warn("Skipping invalid record (not an object)"),!1
3843
3842
  if(!["write-file","replace-in-files","move-file","move-files","delete-file","delete-files","manage-files"].includes(e.type))return s.debug("Skipping record with non-file operation type: "+e.type),!1
3844
3843
  if(!e.metadata)return s.warn("Skipping record without metadata: "+e.id),!1
@@ -3886,10 +3885,10 @@ const N=new Map
3886
3885
  F.forEach((e=>{e.recordId&&e.record?.metadata?.status&&(N.has(e.recordId)||N.set(e.recordId,[]),N.get(e.recordId)?.push(e.record.metadata.status))})),N.forEach(((e,t)=>{s.info(`Record ${t} status updates: ${e.join(" -> ")}`)}))
3887
3886
  const L=F.filter((e=>e.commitHash))
3888
3887
  if(s.info(`Found ${L.length} records with commit hash for ${$}`),0===L.length){s.info(`No commit hashes found in record metadata for ${$}, trying git log`)
3889
- try{if(t.git){const J={file:$,n:10},Y=await t.git.log(J)
3890
- if(Y&&Y.all&&Y.all.length>0){s.info(`Found ${Y.all.length} commits for ${$} using git log`)
3891
- const K=Y.all.map((e=>({filePath:$,recordId:"git-"+e.hash.substring(0,8),type:"git-commit",timestamp:new Date(e.date).toISOString(),commitHash:e.hash,status:"completed",record:{id:"git-"+e.hash.substring(0,8),type:"git-commit",content:e.message,createdAt:new Date(e.date).toISOString(),metadata:{commitHash:e.hash}}})))
3892
- if(K.length>0){const Q=K.length>1?K[K.length-1]:K[0],Z=K[0],X=1===K.length
3888
+ try{if(t.git){const J={file:$,n:10},K=await t.git.log(J)
3889
+ if(K&&K.all&&K.all.length>0){s.info(`Found ${K.all.length} commits for ${$} using git log`)
3890
+ const Y=K.all.map((e=>({filePath:$,recordId:"git-"+e.hash.substring(0,8),type:"git-commit",timestamp:new Date(e.date).toISOString(),commitHash:e.hash,status:"completed",record:{id:"git-"+e.hash.substring(0,8),type:"git-commit",content:e.message,createdAt:new Date(e.date).toISOString(),metadata:{commitHash:e.hash}}})))
3891
+ if(Y.length>0){const Q=Y.length>1?Y[Y.length-1]:Y[0],Z=Y[0],X=1===Y.length
3893
3892
  s.info(X?`Using single git commit for ${$}: ${Z.commitHash?Z.commitHash.substring(0,8):"unknown"}`:`Using git commits for ${$}: ${Q.commitHash?Q.commitHash.substring(0,8):"unknown"} to ${Z.commitHash?Z.commitHash.substring(0,8):"unknown"}`)
3894
3893
  let ee=""
3895
3894
  try{if(X)try{const te=[`${Z.commitHash}:${$}`],re=await t.git.show(te)
@@ -3914,7 +3913,7 @@ continue}let pe
3914
3913
  if("pre-task"===U.status?(pe=[`${U.commitHash}..${B.commitHash}`,"--",$],s.info(`Comparing pre-task commit with final commit: ${U.commitHash?U.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${$}`)):(pe=["4b825dc642cb6eb9a060e54bf8d69288fbee4904.."+B.commitHash,"--",$],s.info(`File created during task, showing full file diff using empty tree object: ${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${$}`)),G=await t.git.diff(pe),V=!!G&&G.trim().length>0,!V&&U.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
3915
3914
  try{const me=await t.git.show([`${U.commitHash}:${$}`]),ye=await t.git.show([`${B.commitHash}:${$}`])
3916
3915
  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")
3917
- 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(Ie){s.warn("Error in direct file comparison: "+(Ie instanceof Error?Ie.message:Ie+""))}}s.info(`Diff generation result for ${$}: hasDiff=${V}, length=${G.length}`)}}catch(be){if(s.warn("Error getting diff for "+$,{error:(0,u.getErrorMessage)(be),firstCommit:z.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),G="Error getting diff: "+(0,u.getErrorMessage)(be),"pre-task"!==z.status&&t.git)try{const ve=[`${B.commitHash}:${$}`]
3916
+ 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 ${$}: hasDiff=${V}, length=${G.length}`)}}catch(Ie){if(s.warn("Error getting diff for "+$,{error:(0,u.getErrorMessage)(Ie),firstCommit:z.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),G="Error getting diff: "+(0,u.getErrorMessage)(Ie),"pre-task"!==z.status&&t.git)try{const ve=[`${B.commitHash}:${$}`]
3918
3917
  s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${$}`)
3919
3918
  const Ce=await t.git.show(ve)
3920
3919
  if(Ce&&Ce.trim().length>0){if(p){let _e=""
@@ -3926,15 +3925,15 @@ w&&"object"==typeof w&&(E+="## Task Information\n",E+=`- **Title**: ${w.title||"
3926
3925
  const q=3e3
3927
3926
  let S=0,T=!1
3928
3927
  if(p){for(const Te of _.values())Te.hasDiff&&Te.diffText&&(S+=Te.diffText.split("\n").length)
3929
- 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`,b.allMoves.length>0){E+="## Move Operations\n\n",E+=`Detected ${b.allMoves.length} file move operation(s):\n\n`
3930
- for(const Pe of b.allMoves)E+=`- **${Pe.source}** \u2192 **${Pe.destination}**\n`,E+=` - Operation: ${Pe.type}\n`,E+=` - Timestamp: ${new Date(Pe.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Pe.recordId}\n\n`}E+="## Modified Files\n\n"
3931
- for(const[Me,Re]of _.entries()){const{normalizedPath:je,fullPath:xe}=d.validateAndNormalizePath(Me,t)
3928
+ 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`
3929
+ for(const Pe of I.allMoves)E+=`- **${Pe.source}** \u2192 **${Pe.destination}**\n`,E+=` - Operation: ${Pe.type}\n`,E+=` - Timestamp: ${new Date(Pe.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Pe.recordId}\n\n`}E+="## Modified Files\n\n"
3930
+ for(const[Me,je]of _.entries()){const{normalizedPath:Re,fullPath:xe}=d.validateAndNormalizePath(Me,t)
3932
3931
  let Oe=!1
3933
3932
  try{await a.access(xe),Oe=!0}catch{}E+=`### ${Me} ${Oe?"":"(Deleted)"}\n\n`
3934
- const Ae=new Date(Re.firstChange.timestamp).toLocaleString(),De=new Date(Re.lastChange.timestamp).toLocaleString()
3935
- E+=`**First Change**: ${Ae}\n`,E+=`**Last Change**: ${De}\n`,"pre-task"===Re.firstChange.status&&Re.firstChange.commitHash?E+=`**Pre-Task Commit**: ${Re.firstChange.commitHash.substring(0,8)}\n`:Re.firstChange.commitHash&&(E+=`**File Created During Task**: ${Re.firstChange.commitHash.substring(0,8)}\n`),Re.lastChange.commitHash&&(E+=`**Final Commit**: ${Re.lastChange.commitHash.substring(0,8)}\n`)
3936
- const $e=b.sourceToMove.get(Me),Fe=b.destToMove.get(Me)
3937
- $e?E+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${$e.destination}**\n`:Fe&&(E+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Fe.source}**\n`),p&&!T?Re.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=Re.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${Re.diffText}\n\n`:T&&Re.hasDiff?(E+=`\n**Note**: File has changes (${Re.diffText?Re.diffText.split("\n").length:0} lines). `,E+=`Compare ${Re.firstChange.commitHash?Re.firstChange.commitHash.substring(0,8):"unknown"}..${Re.lastChange.commitHash?Re.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Re.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${Re.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,u.getErrorMessage)(Ne)}],isError:!0}}}
3933
+ const Ae=new Date(je.firstChange.timestamp).toLocaleString(),De=new Date(je.lastChange.timestamp).toLocaleString()
3934
+ E+=`**First Change**: ${Ae}\n`,E+=`**Last Change**: ${De}\n`,"pre-task"===je.firstChange.status&&je.firstChange.commitHash?E+=`**Pre-Task Commit**: ${je.firstChange.commitHash.substring(0,8)}\n`:je.firstChange.commitHash&&(E+=`**File Created During Task**: ${je.firstChange.commitHash.substring(0,8)}\n`),je.lastChange.commitHash&&(E+=`**Final Commit**: ${je.lastChange.commitHash.substring(0,8)}\n`)
3935
+ const $e=I.sourceToMove.get(Me),Fe=I.destToMove.get(Me)
3936
+ $e?E+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${$e.destination}**\n`:Fe&&(E+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Fe.source}**\n`),p&&!T?je.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=je.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${je.diffText}\n\n`:T&&je.hasDiff?(E+=`\n**Note**: File has changes (${je.diffText?je.diffText.split("\n").length:0} lines). `,E+=`Compare ${je.firstChange.commitHash?je.firstChange.commitHash.substring(0,8):"unknown"}..${je.lastChange.commitHash?je.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):je.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${je.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,u.getErrorMessage)(Ne)}],isError:!0}}}
3938
3937
  const i=t(9860),a=s(t(1943)),c=t(9671),l=t(2960),d=s(t(5967)),u=t(8824)},6928(module){module.exports=require("path")},6975(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
3939
3938
  const r=t(1058)
3940
3939
  exports.ProjectClientAdapter=class{constructor(e,t){this.client=e,this.logger=t.child({component:"project-client-adapter"}),this.logger.info("ProjectClientAdapter initialized")}isOnline(){return!this.client.isOffline()}async fetchProject(e){try{return this.logger.debug("ProjectClientAdapter.fetchProject called",{projectId:e}),await this.client.getProject(e)}catch(t){return this.logger.error("Error in ProjectClientAdapter.fetchProject",{projectId:e,error:t instanceof Error?t.stack:t+""}),null}}async createProject(e){try{this.logger.debug("ProjectClientAdapter.createProject called",{projectName:e.name,projectId:e.id}),this.logger.info("Creating project via adapter",{name:e.name,id:e.id,description:e.description?.substring(0,50)})
@@ -4056,42 +4055,42 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentit
4056
4055
  i.existsSync(n)||i.mkdirSync(n,{recursive:!0})
4057
4056
  const s=(new Date).toISOString(),c=Object.keys(r).length?" "+JSON.stringify(r):""
4058
4057
  i.appendFileSync(o,`[${s}] ${e} | ${t}${c}\n`)}catch(e){}}
4059
- const i=s(t(9896)),a=s(t(6928))},7334(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,l,d,u,h,g){const p=d.child({tool:"create_request"})
4060
- p.info("Creating new request",{args:e})
4061
- const f=u.startTimer("tool_handler_duration")
4062
- try{if(e&&"string"==typeof e.acceptanceCriteria)try{e.acceptanceCriteria=JSON.parse(e.acceptanceCriteria)}catch{}const d=function(e){try{return r.CreateRequestSchema.parse(e)}catch(e){if(e instanceof s.ZodError&&e.errors.length>0)throw new n.ValidationError(e.errors[0].message)
4058
+ const i=s(t(9896)),a=s(t(6928))},7334(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,c,l,d,u,h){const g=l.child({tool:"create_request"})
4059
+ g.info("Creating new request",{args:e})
4060
+ const p=d.startTimer("tool_handler_duration")
4061
+ try{if(e&&"string"==typeof e.acceptanceCriteria)try{e.acceptanceCriteria=JSON.parse(e.acceptanceCriteria)}catch{}const l=function(e){try{return r.CreateRequestSchema.parse(e)}catch(e){if(e instanceof s.ZodError&&e.errors.length>0)throw new n.ValidationError(e.errors[0].message)
4063
4062
  throw new n.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
4064
- u.incrementCounter("create_request_attempts",1,{type:d.type,criteriaCounts:d.acceptanceCriteria.length})
4065
- const m=t.projectId
4066
- if(!m)throw new n.ValidationError("Project ID is required for creating requests.")
4067
- l.setProjectId(m)
4068
- const y=l.getRequestClient()
4069
- let w=(0,a.getApprovalMode)()
4070
- try{const e=g?.sessionId||(0,c.getCachedSession)()?.sessionId
4071
- if(e){const t=l.getCLISessionClient()
4063
+ d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
4064
+ const f=t.projectId
4065
+ if(!f)throw new n.ValidationError("Project ID is required for creating requests.")
4066
+ c.setProjectId(f)
4067
+ const m=c.getRequestClient()
4068
+ let y=(0,a.getApprovalMode)()
4069
+ try{const e=h?.sessionId
4070
+ if(e){const t=c.getCLISessionClient()
4072
4071
  if(t){const r=await t.getByExternalId(e)
4073
- if(r?.workflowId){const e=await l.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
4074
- t?.approvalMode&&(w=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===w)try{const e=await l.proxyGet("/api/projects/"+m),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
4075
- r&&(w=(0,a.getApprovalMode)(r))}catch(e){p.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){p.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const k="require-approval"===w&&"quick-edit"!==d.type?"pending_approval":"open",I={title:d.title,description:d.description,type:d.type,acceptanceCriteria:d.acceptanceCriteria,status:k,...d.planDocumentId&&{planDocumentId:d.planDocumentId},...g&&{cliOrigin:g}}
4076
- p.info("Creating request via request client",{projectId:m,title:d.title,type:d.type,criteriaCount:d.acceptanceCriteria.length})
4077
- const b=await y.createRequest(I)
4078
- p.debug("Create request response structure",{type:typeof b,isArray:Array.isArray(b),hasData:null!=b,properties:b?Object.keys(b):[],dataPreview:b?JSON.stringify(b).substring(0,200)+"...":"null"})
4079
- const v=(0,o.extractDataFromResponse)(b,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
4080
- let _,E={created:!1}
4081
- if(h?.workspaceManager)try{await h.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},p.info("Request branch initialized successfully",{requestId:C.id,branchName:E.branchName,title:C.title})}catch(e){p.warn("Failed to initialize request branch, will retry on first operation",{requestId:C.id,error:(0,i.getErrorMessage)(e)})}else"quick-edit"===d.type?p.info("Quick-edit request - skipping branch creation, will work directly on main",{requestId:C.id}):p.debug("No workspace manager available, branch creation deferred",{requestId:C.id})
4082
- p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
4083
- try{const e=l.getToolRecordClient()
4084
- if(e){const t=await e.createToolRecord({requestId:C.id,projectId:m,type:"create-request",metadata:{status:"completed",timestamp:(new Date).toISOString(),requestType:C.type,requestTitle:C.title,requestDescription:C.description,criteriaCount:C.acceptanceCriteria.length,branchCreated:E.created,branchName:E.created?E.branchName:null},note:`Created request "${C.title}" of type ${C.type}${E.created?" with branch "+E.branchName:" - branch will be created on first file operation"}`})
4085
- _=t?.id}}catch(e){p.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:C.id})}f({success:!0,type:d.type,hasProjectId:!0}),p.info("Request created successfully",{requestId:C.id,title:C.title,type:C.type,projectId:m})
4086
- const q=C.localId||C.id
4087
- let S="pending_approval"===k?`Created Request ${q} (pending approval)`:"Created Request "+q
4088
- return _&&(S+=`\n[RECORD:${_}]`),{content:[{type:"text",text:S}]}}catch(r){if(p.error("Failed to create request",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new requests")||r.message.includes("disabled due to tier limits")))p.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
4089
- else{const n=l.getToolRecordClient()
4090
- n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){p.error("Failed to create failure record for request creation",{error:e instanceof Error?e.message:e+""})}if(f({success:!1,error:r instanceof Error?r.name:"unknown"}),r instanceof s.ZodError&&r.errors.length>0){const e=r.errors[0]
4072
+ if(r?.workflowId){const e=await c.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
4073
+ t?.approvalMode&&(y=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===y)try{const e=await c.proxyGet("/api/projects/"+f),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
4074
+ r&&(y=(0,a.getApprovalMode)(r))}catch(e){g.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){g.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const w="require-approval"===y&&"quick-edit"!==l.type?"pending_approval":"open",k={title:l.title,description:l.description,type:l.type,acceptanceCriteria:l.acceptanceCriteria,status:w,...l.planDocumentId&&{planDocumentId:l.planDocumentId},...h&&{cliOrigin:h}}
4075
+ g.info("Creating request via request client",{projectId:f,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
4076
+ const b=await m.createRequest(k)
4077
+ g.debug("Create request response structure",{type:typeof b,isArray:Array.isArray(b),hasData:null!=b,properties:b?Object.keys(b):[],dataPreview:b?JSON.stringify(b).substring(0,200)+"...":"null"})
4078
+ const I=(0,o.extractDataFromResponse)(b,{logger:g,operationName:"createRequest",throwOnNoData:!0}),v="data"in I?I.data:I
4079
+ let C,_={created:!1}
4080
+ if(u?.workspaceManager)try{await u.workspaceManager.initializeRequest(v.id,v.title),_={created:!0,branchName:"requests/"+v.id,message:"Branch created successfully"},g.info("Request branch initialized successfully",{requestId:v.id,branchName:_.branchName,title:v.title})}catch(e){g.warn("Failed to initialize request branch, will retry on first operation",{requestId:v.id,error:(0,i.getErrorMessage)(e)})}else"quick-edit"===l.type?g.info("Quick-edit request - skipping branch creation, will work directly on main",{requestId:v.id}):g.debug("No workspace manager available, branch creation deferred",{requestId:v.id})
4081
+ g.info("Request created successfully",{requestId:v.id,title:v.title,branchCreated:_.created,branchName:_.branchName})
4082
+ try{const e=c.getToolRecordClient()
4083
+ if(e){const t=await e.createToolRecord({requestId:v.id,projectId:f,type:"create-request",metadata:{status:"completed",timestamp:(new Date).toISOString(),requestType:v.type,requestTitle:v.title,requestDescription:v.description,criteriaCount:v.acceptanceCriteria.length,branchCreated:_.created,branchName:_.created?_.branchName:null},note:`Created request "${v.title}" of type ${v.type}${_.created?" with branch "+_.branchName:" - branch will be created on first file operation"}`})
4084
+ C=t?.id}}catch(e){g.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:v.id})}p({success:!0,type:l.type,hasProjectId:!0}),g.info("Request created successfully",{requestId:v.id,title:v.title,type:v.type,projectId:f})
4085
+ const E=v.localId||v.id
4086
+ let q="pending_approval"===w?`Created Request ${E} (pending approval)`:"Created Request "+E
4087
+ return C&&(q+=`\n[RECORD:${C}]`),{content:[{type:"text",text:q}]}}catch(r){if(g.error("Failed to create request",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new requests")||r.message.includes("disabled due to tier limits")))g.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
4088
+ else{const n=c.getToolRecordClient()
4089
+ n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){g.error("Failed to create failure record for request creation",{error:e instanceof Error?e.message:e+""})}if(p({success:!1,error:r instanceof Error?r.name:"unknown"}),r instanceof s.ZodError&&r.errors.length>0){const e=r.errors[0]
4091
4090
  let t=e.message
4092
4091
  return e.path.includes("acceptanceCriteria")&&(t=`Acceptance criteria: ${t}. Please provide a list of criteria descriptions.`),{content:[{type:"text",text:"Error: "+t}],isError:!0}}let n=(0,i.getErrorMessage)(r),o="Unable to create request. Please check your input and try again."
4093
4092
  return(n.includes("Project cannot accept new requests")||n.includes("Project is inactive due to tier limits"))&&(o="This project is currently inactive due to tier limits. Only your oldest projects can accept new requests. Please use an active project or upgrade your tier for more simultaneous projects."),{content:[{type:"text",text:`Error: ${n}\n\n${o}`}],isError:!0}}}
4094
- const r=t(6183),n=t(9860),o=t(2960),s=t(1569),i=t(8824),a=t(2478),c=t(715)},7388(e,exports,t){var r=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
4093
+ const r=t(6183),n=t(9860),o=t(2960),s=t(1569),i=t(8824),a=t(2478)},7388(e,exports,t){var r=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
4095
4094
  var o=Object.getOwnPropertyDescriptor(t,r)
4096
4095
  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]}),n=this&&this.__exportStar||function(e,exports){for(var t in e)"default"===t||{}.hasOwnProperty.call(exports,t)||r(exports,e,t)}
4097
4096
  Object.defineProperty(exports,"__esModule",{value:!0}),n(t(441),exports),n(t(270),exports)},7456(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
@@ -4105,7 +4104,7 @@ return o(t,e),t})
4105
4104
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,t,r,n,o,s,h,g){const p=s.child({tool:"modify_file"})
4106
4105
  try{const s=a.validateArgs(e,i.ModifyFileSchema),{taskId:u,operations:f,comment:m}=s
4107
4106
  p.info("Processing modify-file operations",{taskId:u,operationCount:f.length,comment:m})
4108
- const y=[],w=[],k=[],I=[],b=[]
4107
+ const y=[],w=[],k=[],b=[],I=[]
4109
4108
  for(const e of f){const t={path:e.path,documentId:e.documentId}
4110
4109
  switch(e.operationType){case"replace-string":y.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
4111
4110
  break
@@ -4113,19 +4112,19 @@ case"insert-lines":w.push({...t,insertions:e.insertLines.insertions})
4113
4112
  break
4114
4113
  case"replace-lines":k.push({...t,replacements:e.replaceLines.replacements})
4115
4114
  break
4116
- case"delete-string":I.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
4115
+ case"delete-string":b.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
4117
4116
  break
4118
- case"delete-lines":b.push({...t,lines:e.deleteLines.lines})}}const v=[]
4117
+ case"delete-lines":I.push({...t,lines:e.deleteLines.lines})}}const v=[]
4119
4118
  if(y.length>0){p.info("Routing to replace-strings handler",{operationCount:y.length})
4120
4119
  const e=await(0,c.handleReplaceStrings)({taskId:u,operations:y,comment:m+" [via modify-file: replace-string]"},t,r,n,o,p,h,g)
4121
4120
  v.push({type:"replace-string",result:e})}if(w.length>0){p.info("Routing to insert-lines handler",{operationCount:w.length})
4122
4121
  const e=await(0,l.handleInsertLines)({taskId:u,operations:w,comment:m+" [via modify-file: insert-lines]"},t,r,n,o,p,h,g)
4123
4122
  v.push({type:"insert-lines",result:e})}if(k.length>0){p.info("Routing to replace-lines handler",{operationCount:k.length})
4124
4123
  const e=await(0,d.handleReplaceLines)({taskId:u,operations:k,comment:m+" [via modify-file: replace-lines]"},t,r,n,o,p,h,g)
4125
- v.push({type:"replace-lines",result:e})}if(I.length>0){p.info("Routing delete-string to replace-strings handler",{operationCount:I.length})
4126
- const e=await(0,c.handleReplaceStrings)({taskId:u,operations:I,comment:m+" [via modify-file: delete-string]"},t,r,n,o,p,h,g)
4127
- v.push({type:"delete-string",result:e})}if(b.length>0){p.info("Processing delete-lines operations",{operationCount:b.length})
4128
- const e=b.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),s=await(0,d.handleReplaceLines)({taskId:u,operations:e,comment:m+" [via modify-file: delete-lines]"},t,r,n,o,p,h,g)
4124
+ v.push({type:"replace-lines",result:e})}if(b.length>0){p.info("Routing delete-string to replace-strings handler",{operationCount:b.length})
4125
+ const e=await(0,c.handleReplaceStrings)({taskId:u,operations:b,comment:m+" [via modify-file: delete-string]"},t,r,n,o,p,h,g)
4126
+ v.push({type:"delete-string",result:e})}if(I.length>0){p.info("Processing delete-lines operations",{operationCount:I.length})
4127
+ const e=I.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),s=await(0,d.handleReplaceLines)({taskId:u,operations:e,comment:m+" [via modify-file: delete-lines]"},t,r,n,o,p,h,g)
4129
4128
  v.push({type:"delete-lines",result:s})}const C=v.some((e=>e.result.isError)),_=v.filter((e=>!e.result.isError)).length,E=v.filter((e=>e.result.isError)).length
4130
4129
  let q="## Modify File Results\n\n"
4131
4130
  q+="**Summary:**\n",q+=`- **Total operation types:** ${v.length}\n`,q+=`- **Successful:** ${_}\n`,q+=`- **Failed:** ${E}\n\n`
@@ -4277,55 +4276,9 @@ const i=await t.updateDocument(e.planId,o),a=i.localId||i.id
4277
4276
  return s.info("Plan updated",{planId:a}),{content:[{type:"text",text:`\u2705 **Plan Updated**\n\n**Plan ID:** ${a}\n**Filename:** ${i.filename}\n**Updated:** `+new Date(i.updatedAt).toLocaleString()}]}}catch(e){return s.error("Failed to update plan",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to update plan:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
4278
4277
  const r=t(8824)},7613(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
4279
4278
  const r=t(6183),n=t(9072)
4280
- exports.def={name:"session_message_operations",description:'Inter-session messaging (questions and reports).\n\nOperations:\n\u2022 send - Send a message (type: "question" or "report")\n\u2022 reply - Reply to a message (answer a question or acknowledge a report). Type inferred from code prefix (Q-/R-).\n\u2022 list - List messages (filter by messageType, direction, status)\n\u2022 get - Get a message by its code\n\u2022 offer-handoff - Present the user with a choice to start building or keep planning\n\nMessage codes: Q-{id}-{seq} for questions, R-{id}-{seq} for reports.',schema:r.SessionMessageOperationsSchema,annotations:{title:"Session Message Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleSessionMessageOperations)(e,t.context,t.logger,t.metrics,t.apiClient??void 0)}}},7617(e,exports,t){function r(e,t){if(!e.operation||!t.operation)return!1
4281
- if(e.operation!==t.operation)return!1
4282
- if("ask"===e.operation){let r=e.ask||e,n=t.ask||t
4283
- if("string"==typeof n)try{n=JSON.parse(n)}catch{}if("string"==typeof r)try{r=JSON.parse(r)}catch{}const o=r?.questionContent?.question||r?.question,s=n?.questionContent?.question||n?.question
4284
- return!(!o||!s)&&o===s}return!0}async function n(e,t,n,s){const i=n.child({component:"session-discovery"})
4285
- try{const n=e.replace(/\/$/,"")+"/session",o=await fetch(n)
4286
- if(!o.ok)return void i.warn("Failed to get session list",{status:o.status})
4287
- const a=await o.json(),c=a.sort(((e,t)=>t.time.updated-e.time.updated)),l=e.replace(/\/$/,"")+"/session/status",d=await fetch(l)
4288
- if(!d.ok)return void i.warn("Failed to get session status",{status:d.status})
4289
- const u=await d.json(),h=c.filter((e=>"busy"===u[e.id]?.type)),g=5,p=c.slice(0,g),f=new Set(h.map((e=>e.id))),m=[...h,...p.filter((e=>!f.has(e.id)))]
4290
- let y=null
4291
- const w=[]
4292
- for(const n of m)try{const o=`${e.replace(/\/$/,"")}/session/${n.id}/message?limit=50`,a=await fetch(o)
4293
- if(!a.ok){i.debug("Failed to get messages for session",{sessionId:n.id,status:a.status})
4294
- continue}const c=await a.json()
4295
- let l=0
4296
- for(const e of c){const o=(e.info||e).role||e.role,i=e.parts
4297
- if("assistant"===o&&i)for(const o of i)if("tool"===o.type){const i=o.tool,a=o.state?.status,c=o.sessionID
4298
- if(l++,i&&i.includes(t)){if("running"!==a&&"pending"!==a){w.push({sessionId:n.id,tool:i,reason:"wrong state: "+a})
4299
- continue}const t=o.state?.input,l=o.state?.time?.start||0,d=c||n.id,u=Date.now(),h=l>0?u-l:0
4300
- if(l>0&&h>6e4){w.push({sessionId:n.id,tool:i,reason:`stale: running for ${Math.round(h/1e3)}s`})
4301
- continue}if(s&&t&&!r(s,t)){w.push({sessionId:n.id,tool:i,reason:"params mismatch"})
4302
- continue}const g=e.info?.id
4303
- y&&l<=y.startTime||(y={sessionId:d,messageId:g,startTime:l,toolName:i})}else i&&(i.includes("session-qa")||i.includes("subagent"))&&w.push({sessionId:n.id,tool:i,reason:"name mismatch: looking for "+t})}}}catch(e){i.debug("Error checking session",{sessionId:n.id,error:e+""})
4304
- continue}return y?{sessionId:y.sessionId,messageId:y.messageId}:void i.warn("Session discovery failed - no matching tool call found",{toolName:t,totalSessions:a.length,busySessions:h.length,rejectionCount:w.length,rejections:w.slice(0,10)})}catch(e){return void i.warn("Failed to discover calling session",{error:(0,o.getErrorMessage)(e)})}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.getServerUrl=async function(e,r){let n=process.env.OPENCODE_TUI_URL
4279
+ exports.def={name:"session_message_operations",description:'Inter-session messaging (questions and reports).\n\nOperations:\n\u2022 send - Send a message (type: "question" or "report")\n\u2022 reply - Reply to a message (answer a question or acknowledge a report). Type inferred from code prefix (Q-/R-).\n\u2022 list - List messages (filter by messageType, direction, status)\n\u2022 get - Get a message by its code\n\u2022 offer-handoff - Present the user with a choice to start building or keep planning\n\nMessage codes: Q-{id}-{seq} for questions, R-{id}-{seq} for reports.',schema:r.SessionMessageOperationsSchema,annotations:{title:"Session Message Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleSessionMessageOperations)(e,t.context,t.logger,t.metrics,t.apiClient??void 0)}}},7617(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.getServerUrl=async function(e,r){let n=process.env.OPENCODE_TUI_URL
4305
4280
  if(!n)try{const{readFileSync:o}=await Promise.resolve().then(t.t.bind(t,9896,23)),{join:s}=await Promise.resolve().then(t.t.bind(t,6928,23)),i=o(s(e.basePath,".alchemy_lab","opencode.json"),"utf8"),a=JSON.parse(i)
4306
- a.port&&(n="http://127.0.0.1:"+a.port,r.debug("Discovered OpenCode server URL from .alchemy_lab/opencode.json",{serverUrl:n}))}catch(e){r.debug("Could not read .alchemy_lab/opencode.json",{error:e instanceof Error?e.message:e+""})}return n},exports.getAndStoreSessionId=async function(e,t,r,o){if(r){const s=await n(e,r,t,o)
4307
- if(s)return t.info("Found calling session by tool",{sessionId:s.sessionId,messageId:s.messageId,toolName:r}),s}},exports.findMessageIdForTool=async function(e,t,r){try{const n=`${e.replace(/\/$/,"")}/session/${t}/message?limit=50`,o=await fetch(n)
4308
- if(!o.ok)return
4309
- const s=await o.json()
4310
- let i,a=0
4311
- for(const e of s){const t=(e.info||e).role||e.role,n=e.parts
4312
- if("assistant"===t&&n)for(const t of n){if("tool"!==t.type)continue
4313
- const n=t.tool,o=t.state?.status
4314
- if(!n?.includes(r))continue
4315
- if("running"!==o&&"pending"!==o)continue
4316
- const s=t.state?.time?.start||0
4317
- s>a&&(a=s,i=e.info?.id)}}return i}catch{return}},exports.discoverCallingSession=n,exports.discoverParentSessionId=async function(e,t){try{const r=e.replace(/\/$/,"")+"/session",n=await fetch(r)
4318
- if(!n.ok)return void t.warn("Failed to get session list",{status:n.status})
4319
- const o=[...await n.json()].sort(((e,t)=>t.time.updated-e.time.updated))
4320
- if(0===o.length)return void t.warn("No sessions found")
4321
- const s=e.replace(/\/$/,"")+"/session/status",i=await fetch(s)
4322
- if(!i.ok)return void t.warn("Failed to get session status",{status:i.status})
4323
- const a=await i.json(),c=o.filter((e=>"busy"===a[e.id]?.type))
4324
- for(const r of c)try{const n=`${e.replace(/\/$/,"")}/session/${r.id}/message?limit=20`,o=await fetch(n)
4325
- if(!o.ok)continue
4326
- const s=await o.json()
4327
- for(const e of s)if("assistant"===e.role&&e.parts)for(const n of e.parts)if("tool-invocation"===n.type&&"subagent_operations"===n.toolInvocation?.toolName&&"spawn"===n.toolInvocation?.args?.operation&&"pending"===n.toolInvocation?.state)return t.info("Found parent session via spawn tool call",{parentSessionId:r.id}),r.id}catch{continue}return c.length>0?(t.info("Fallback: using first busy session",{parentSessionId:c[0].id}),c[0].id):(t.info("Last resort: using most recent session",{parentSessionId:o[0].id}),o[0].id)}catch(e){t.warn("Failed to query OpenCode API for parent session",{error:e instanceof Error?e.message:e+""})}}
4328
- const o=t(8824)},7621(e,exports,t){async function r(e,t,r){const n=r.startTimer("get_current_git_branch_duration")
4281
+ a.port&&(n="http://127.0.0.1:"+a.port,r.debug("Discovered OpenCode server URL from .alchemy_lab/opencode.json",{serverUrl:n}))}catch(e){r.debug("Could not read .alchemy_lab/opencode.json",{error:e instanceof Error?e.message:e+""})}return n}},7621(e,exports,t){async function r(e,t,r){const n=r.startTimer("get_current_git_branch_duration")
4329
4282
  try{if(!e.git)return t.debug("No git repository available"),r.incrementCounter("get_current_git_branch_no_git",1),n({success:!1,reason:"no_git"}),null
4330
4283
  const o=await u.getCurrentBranch(e.git,t,r)
4331
4284
  return t.debug("Retrieved current git branch",{currentBranch:o}),r.incrementCounter("get_current_git_branch_success",1),n({success:!0}),o}catch(e){const o=(0,g.getErrorMessage)(e)
@@ -4419,7 +4372,9 @@ var n=t(2037)
4419
4372
  Object.defineProperty(exports,"RequestLockManager",{enumerable:!0,get(){return n.RequestLockManager}})},7636(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
4420
4373
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentWorkspaceManager=void 0
4421
4374
  const n=r(t(6928)),o=t(3807),s=t(7634),i=t(8824),a=t(7075),c=t(1387),l=t(4968)
4422
- exports.MultiAgentWorkspaceManager=class{constructor(e,t,r,n,o){this.basePath=e,this.logger=t,this.mainGit=r,this.metrics=n,this.currentRequestId=null,this.currentWorktreePath=null,this.workspaceStates=new Map,this.readonlyBranchCheckDone=!1,this.workspaceKnownClean=!1,this.largeFileWarning="",this.apiClient=o,this.currentGit=r
4375
+ class d{getSession(e){const t=e||d.DEFAULT_SESSION
4376
+ let r=this.sessions.get(t)
4377
+ return r||(r={requestId:null,worktreePath:null,git:this.mainGit,readonlyBranchCheckDone:!1,workspaceKnownClean:!1,largeFileWarning:""},this.sessions.set(t,r)),r}constructor(e,t,r,n,o){this.basePath=e,this.logger=t,this.mainGit=r,this.metrics=n,this.workspaceStates=new Map,this.sessions=new Map,this.apiClient=o
4423
4378
  const i=a.ConflictResolutionUtils.initializeDetectors(r,t)
4424
4379
  this.conflictDetector=i.conflictDetector,this.safetyAnalyzer=i.safetyAnalyzer,this.conflictResolver=i.conflictResolver,this.worktreeManager=new s.WorktreeManager(e,t,n),this.gitAdapter=new l.WorktreeGitAdapter(r,this.worktreeManager,this.conflictDetector,t,n),this.requestProcessor=new c.WorkspaceRequestProcessor(this.gitAdapter,this.conflictDetector,this.safetyAnalyzer,this.conflictResolver,t),this.initializeWorktreeManager(),this.initializeFromEnv()}async initializeFromEnv(){const e=process.env.ALCHEMY_INITIAL_BRANCH
4425
4380
  if(!e)return
@@ -4427,73 +4382,81 @@ const t=e.match(/^requests\/(.+)$/)
4427
4382
  if(!t)return void this.logger.warn("ALCHEMY_INITIAL_BRANCH set but not a request branch",{initialBranch:e})
4428
4383
  const r=t[1]
4429
4384
  this.logger.info("ALCHEMY_INITIAL_BRANCH set, switching to worktree",{initialBranch:e,requestId:r})
4430
- try{await this.ensureWorkspaceReady(r),this.readonlyBranchCheckDone=!0,this.logger.info("Successfully switched to worktree from ALCHEMY_INITIAL_BRANCH",{requestId:r,worktreePath:this.currentWorktreePath})}catch(t){this.logger.warn("Failed to switch to worktree from ALCHEMY_INITIAL_BRANCH",{initialBranch:e,requestId:r,error:(0,i.getErrorMessage)(t)})}}hasExactConflictMarkers(e){return!(!e||!e.trim())&&[/^\s*<{7}(?:\s|$)/m,/^\s*={7}(?:\s|$)/m,/^\s*>{7}(?:\s|$)/m].some((t=>t.test(e)))}async initializeWorktreeManager(){try{await this.worktreeManager.initialize(),this.logger.debug("Initialized multi-agent workspace manager with worktrees")}catch(e){throw this.logger.error("Failed to initialize worktree manager",{error:e}),e}}setTaskCreator(e){this.taskCreator=e}async initializeRequest(e,t){const r=Date.now(),n=a.WorkspaceValidation.validateRequestId(e)
4385
+ try{await this.ensureWorkspaceReady(r)
4386
+ const e=this.getSession()
4387
+ e.readonlyBranchCheckDone=!0,this.logger.info("Successfully switched to worktree from ALCHEMY_INITIAL_BRANCH",{requestId:r,worktreePath:e.worktreePath})}catch(t){this.logger.warn("Failed to switch to worktree from ALCHEMY_INITIAL_BRANCH",{initialBranch:e,requestId:r,error:(0,i.getErrorMessage)(t)})}}hasExactConflictMarkers(e){return!(!e||!e.trim())&&[/^\s*<{7}(?:\s|$)/m,/^\s*={7}(?:\s|$)/m,/^\s*>{7}(?:\s|$)/m].some((t=>t.test(e)))}async initializeWorktreeManager(){try{await this.worktreeManager.initialize(),this.logger.debug("Initialized multi-agent workspace manager with worktrees")}catch(e){throw this.logger.error("Failed to initialize worktree manager",{error:e}),e}}setTaskCreator(e){this.taskCreator=e}async initializeRequest(e,t){const r=Date.now(),n=a.WorkspaceValidation.validateRequestId(e)
4431
4388
  if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
4432
4389
  const o=n.sanitized
4433
- try{a.WorkspaceLogging.logOperation(this.logger,"info","Initializing request by creating branch (no worktree yet)",e,"multi-agent","initializeRequest",{requestTitle:t,architecture:"hybrid-creation"})
4434
- const n="requests/"+o,s=await this.mainGit.branch().then((e=>e.all.includes(n)||e.all.includes("remotes/origin/"+n)))
4435
- if(!s){const e=await this.mainGit.revparse(["--abbrev-ref","HEAD"]),t=(await this.mainGit.branch()).all.includes("main")?"main":"master"
4436
- await this.mainGit.checkout(["-b",n,t]),this.logger.info("Created branch for request",{requestId:o,branchName:n,fromBranch:t}),await this.mainGit.checkout(e),this.logger.info("Returned to original branch after creation",{returnedTo:e,createdBranch:n})}this.workspaceStates.set(o,"initialized")
4437
- const i=Date.now()-r
4438
- this.metrics.recordValue("workspace.initialize",i),a.WorkspaceLogging.logOperation(this.logger,"info","Successfully initialized request with branch (no worktree)",e,"multi-agent","initializeRequest",{branchName:n,branchExisted:s,duration:i,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
4439
- throw this.metrics.recordValue("workspace.initialize",n),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to initialize request",e,"multi-agent","initializeRequest",{error:(0,i.getErrorMessage)(t),duration:n}),t}}async ensureWorkspaceReady(e){const t=Date.now(),r=a.WorkspaceValidation.validateRequestId(e)
4440
- if(!r.isValid)throw Error("Invalid request ID: "+r.errors.join(", "))
4441
- const n=r.sanitized
4442
- let s=!1
4443
- if(this.apiClient)try{const e=this.apiClient.getRequestClient(),t=await e.getRequest(n)
4444
- if(t&&"quick-edit"===t.type){s=!0,this.logger.info("Quick-edit request detected - checking out branch in main repo (no worktree)",{requestId:n,requestType:t.type})
4445
- const e="requests/"+n
4446
- return(await this.mainGit.branch()).all.includes(e)?(await this.mainGit.checkout(e),this.logger.info("Checked out existing quick-edit branch in main repo",{requestId:n,branchName:e})):(await this.mainGit.checkoutLocalBranch(e),this.logger.info("Created and checked out quick-edit branch in main repo",{requestId:n,branchName:e})),this.currentRequestId=n,this.currentWorktreePath=null,this.currentGit=this.mainGit,void this.workspaceStates.set(n,"ready")}}catch(e){this.logger.warn("Failed to check request type, proceeding with normal workflow",{requestId:n,error:(0,i.getErrorMessage)(e)})}if("ready"!==this.workspaceStates.get(n)||this.currentRequestId!==n){if("ready"===this.workspaceStates.get(n)&&this.currentRequestId!==n){this.logger.info("Workspace ready but not in correct context, switching to it",{requestId:n,currentRequestId:this.currentRequestId,reason:"context_mismatch"})
4447
- const e=this.worktreeManager.getWorktreeInfo(n)
4448
- if(e&&e.worktreePath)return this.currentRequestId=n,this.currentWorktreePath=e.worktreePath,this.currentGit=(0,o.simpleGit)(e.worktreePath),void this.logger.info("Switched to existing ready workspace",{requestId:n,worktreePath:e.worktreePath})}try{a.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by creating/switching to worktree",e,"multi-agent","ensureWorkspaceReady",{currentState:this.workspaceStates.get(n)||"not-initialized",currentRequestId:this.currentRequestId,architecture:"hybrid-creation"})
4449
- const r=await this.worktreeManager.ensureWorktreeExists(n,void 0,void 0)
4450
- if(!r.success)throw Error("Failed to create worktree: "+r.message)
4451
- if(this.currentRequestId=n,this.currentWorktreePath=r.worktreePath,this.currentGit=(0,o.simpleGit)(r.worktreePath),this.workspaceStates.set(n,"ready"),r.created){this.workspaceKnownClean=!0
4452
- try{const e=(0,o.simpleGit)(r.worktreePath),t=(await this.mainGit.branch()).all.includes("main")?"main":"master",s=await this.mainGit.revparse([t]),i=await e.revparse(["HEAD"])
4453
- s!==i&&0===(await e.log({from:t,to:"HEAD"})).total&&(await e.rebase([t]),this.logger.info("Rebased fresh request branch onto latest main",{requestId:n,mainHead:s.substring(0,8),previousHead:i.substring(0,8)}))}catch(e){this.logger.warn("Failed to rebase onto main, proceeding with existing branch",{requestId:n,error:(0,i.getErrorMessage)(e)})}}const s=Date.now()-t
4454
- this.metrics.recordValue("workspace.ensure_ready",s),a.WorkspaceLogging.logOperation(this.logger,"info","Workspace is ready with worktree",e,"multi-agent","ensureWorkspaceReady",{worktreePath:r.worktreePath,branchName:r.branchName,duration:s,architecture:"hybrid-creation"})}catch(r){const n=Date.now()-t
4455
- throw this.metrics.recordValue("workspace.ensure_ready",n),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure workspace ready",e,"multi-agent","ensureWorkspaceReady",{error:(0,i.getErrorMessage)(r),duration:n}),r}}else this.logger.debug("Workspace already ready and in correct context",{requestId:n,worktreePath:this.currentWorktreePath})}async switchToRequest(e,t){this.logger.debug("switchToRequest called",{requestId:e,options:t})
4456
- const r=Date.now(),n=this.getCurrentContext()
4457
- if(this.logger.debug("previousContext",{previousContext:n}),t?.isCompleted&&this.currentRequestId!==e)return this.logger.debug("Completed request detected - using simple checkout instead of worktree"),await this.switchToCompletedRequest(e,r,n)
4458
- const o=a.WorkspaceValidation.validateRequestId(e)
4459
- if(!o.isValid){const t="Invalid request ID: "+o.errors.join(", ")
4460
- return a.WorkspaceLogging.logOperation(this.logger,"error",t,e,"multi-agent","switchToRequest"),{success:!1,message:t,previousContext:n,newContext:n}}try{this.logger.debug("About to call ensureWorkspaceReady",{requestId:o.sanitized}),await this.ensureWorkspaceReady(o.sanitized),this.logger.debug("ensureWorkspaceReady completed",{currentRequestId:this.currentRequestId,currentWorktreePath:this.currentWorktreePath})
4390
+ try{this.workspaceStates.set(o,"initialized")
4461
4391
  const t=Date.now()-r
4462
- return this.metrics?.recordValue("workspace_switch_duration",t),a.WorkspaceLogging.logOperation(this.logger,"info","Switched to worktree for request",e,"multi-agent","switchToRequest",{worktreePath:this.currentWorktreePath,duration:t}),{success:!0,message:"Switched to worktree for request: "+e,previousContext:n,newContext:this.getCurrentContext(),worktreePath:this.currentWorktreePath}}catch(t){const o=Date.now()-r
4463
- return this.metrics?.recordValue("workspace_switch_duration",o),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to request",e,"multi-agent","switchToRequest",{error:(0,i.getErrorMessage)(t),duration:o}),{success:!1,message:"Failed to switch to request: "+(0,i.getErrorMessage)(t),previousContext:n,newContext:n}}}async switchToCompletedRequest(e,t,r){try{const n="requests/"+e
4464
- a.WorkspaceLogging.logOperation(this.logger,"info","Switching to completed request (no worktree)",e,"multi-agent","switchToCompletedRequest",{branchName:n}),await this.mainGit.checkout(n),this.currentRequestId=e,this.currentWorktreePath=null,this.currentGit=this.mainGit
4465
- const o=Date.now()-t
4466
- return this.metrics?.recordValue("workspace_switch_duration",o),a.WorkspaceLogging.logOperation(this.logger,"info","Successfully switched to completed request branch",e,"multi-agent","switchToCompletedRequest",{branchName:n,duration:o,worktree:!1}),{success:!0,message:`Switched to completed request branch: ${n} (no worktree)`,previousContext:r,newContext:this.getCurrentContext()}}catch(n){const o=Date.now()-t
4467
- return this.metrics?.recordValue("workspace_switch_duration",o),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to completed request",e,"multi-agent","switchToCompletedRequest",{error:(0,i.getErrorMessage)(n),duration:o}),{success:!1,message:"Failed to switch to completed request: "+(0,i.getErrorMessage)(n),previousContext:r,newContext:r}}}async switchToMain(){const e=this.getCurrentContext()
4468
- return this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit,this.logger.info("Switched to main repository context"),{success:!0,message:"Switched to main repository",previousContext:e,newContext:this.getCurrentContext()}}async commitChanges(e,t){const r=Date.now()
4469
- if(!this.currentRequestId||!this.currentWorktreePath)throw new a.ConflictDetectionError("No active request context for commit","multi-agent-commit",[])
4470
- try{t&&t.length>0?await this.currentGit.add(t):await this.currentGit.add("."),await this.currentGit.commit(e)
4471
- const n=await this.currentGit.revparse(["HEAD"]),o=Date.now()-r
4472
- return this.metrics?.recordValue("workspace_commit_duration",o),this.logger.info("Successfully committed changes in worktree",{requestId:this.currentRequestId,worktreePath:this.currentWorktreePath,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
4473
- throw this.metrics?.recordValue("workspace_commit_duration",n),this.logger.error("Failed to commit changes in worktree",{requestId:this.currentRequestId,worktreePath:this.currentWorktreePath,message:e,error:(0,i.getErrorMessage)(t),duration:n}),new a.ConflictDetectionError("Failed to commit changes: "+(0,i.getErrorMessage)(t),"multi-agent-commit",[])}}async completeRequest(e,t,r){const n=Date.now()
4392
+ this.metrics.recordValue("workspace.initialize",t),a.WorkspaceLogging.logOperation(this.logger,"info","Successfully initialized request (branch deferred)",e,"multi-agent","initializeRequest",{duration:t,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
4393
+ throw this.metrics.recordValue("workspace.initialize",n),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to initialize request",e,"multi-agent","initializeRequest",{error:(0,i.getErrorMessage)(t),duration:n}),t}}async ensureWorkspaceReady(e,t){const r=this.getSession(t),n=Date.now(),s=a.WorkspaceValidation.validateRequestId(e)
4394
+ if(!s.isValid)throw Error("Invalid request ID: "+s.errors.join(", "))
4395
+ const c=s.sanitized
4396
+ let l=!1
4397
+ if(this.apiClient)try{const e=this.apiClient.getRequestClient(),t=await e.getRequest(c)
4398
+ if(t&&"quick-edit"===t.type){l=!0,this.logger.info("Quick-edit request detected - checking out branch in main repo (no worktree)",{requestId:c,requestType:t.type})
4399
+ const e="requests/"+c
4400
+ return(await this.mainGit.branch()).all.includes(e)?(await this.mainGit.checkout(e),this.logger.info("Checked out existing quick-edit branch in main repo",{requestId:c,branchName:e})):(await this.mainGit.checkoutLocalBranch(e),this.logger.info("Created and checked out quick-edit branch in main repo",{requestId:c,branchName:e})),r.requestId=c,r.worktreePath=null,r.git=this.mainGit,void this.workspaceStates.set(c,"ready")}}catch(e){this.logger.warn("Failed to check request type, proceeding with normal workflow",{requestId:c,error:(0,i.getErrorMessage)(e)})}if("ready"!==this.workspaceStates.get(c)||r.requestId!==c){if("ready"===this.workspaceStates.get(c)&&r.requestId!==c){this.logger.info("Workspace ready but not in correct context, switching to it",{requestId:c,currentRequestId:r.requestId,reason:"context_mismatch"})
4401
+ const e=this.worktreeManager.getWorktreeInfo(c)
4402
+ if(e&&e.worktreePath)return r.requestId=c,r.worktreePath=e.worktreePath,r.git=(0,o.simpleGit)(e.worktreePath),void this.logger.info("Switched to existing ready workspace",{requestId:c,worktreePath:e.worktreePath})}try{a.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by creating/switching to worktree",e,"multi-agent","ensureWorkspaceReady",{currentState:this.workspaceStates.get(c)||"not-initialized",currentRequestId:r.requestId,architecture:"hybrid-creation"})
4403
+ const t=await this.worktreeManager.ensureWorktreeExists(c,void 0,void 0)
4404
+ if(!t.success)throw Error("Failed to create worktree: "+t.message)
4405
+ if(r.requestId=c,r.worktreePath=t.worktreePath,r.git=(0,o.simpleGit)(t.worktreePath),this.workspaceStates.set(c,"ready"),t.created){r.workspaceKnownClean=!0
4406
+ try{const e=(0,o.simpleGit)(t.worktreePath),r=(await this.mainGit.branch()).all.includes("main")?"main":"master",n=await this.mainGit.revparse([r]),s=await e.revparse(["HEAD"])
4407
+ n!==s&&0===(await e.log({from:r,to:"HEAD"})).total&&(await e.rebase([r]),this.logger.info("Rebased fresh request branch onto latest main",{requestId:c,mainHead:n.substring(0,8),previousHead:s.substring(0,8)}))}catch(e){this.logger.warn("Failed to rebase onto main, proceeding with existing branch",{requestId:c,error:(0,i.getErrorMessage)(e)})}}const s=Date.now()-n
4408
+ this.metrics.recordValue("workspace.ensure_ready",s),a.WorkspaceLogging.logOperation(this.logger,"info","Workspace is ready with worktree",e,"multi-agent","ensureWorkspaceReady",{worktreePath:t.worktreePath,branchName:t.branchName,duration:s,architecture:"hybrid-creation"})}catch(t){const r=Date.now()-n
4409
+ throw this.metrics.recordValue("workspace.ensure_ready",r),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure workspace ready",e,"multi-agent","ensureWorkspaceReady",{error:(0,i.getErrorMessage)(t),duration:r}),t}}else this.logger.debug("Workspace already ready and in correct context",{requestId:c,worktreePath:r.worktreePath})}async switchToRequest(e,t){const r=t?.sessionId,n=this.getSession(r)
4410
+ this.logger.debug("switchToRequest called",{requestId:e,options:t,sessionId:r})
4411
+ const o=Date.now(),s=this.getCurrentContext(r)
4412
+ if(this.logger.debug("previousContext",{previousContext:s}),t?.isCompleted&&n.requestId!==e)return this.logger.debug("Completed request detected - using simple checkout instead of worktree"),await this.switchToCompletedRequest(e,o,s)
4413
+ const c=a.WorkspaceValidation.validateRequestId(e)
4414
+ if(!c.isValid){const t="Invalid request ID: "+c.errors.join(", ")
4415
+ return a.WorkspaceLogging.logOperation(this.logger,"error",t,e,"multi-agent","switchToRequest"),{success:!1,message:t,previousContext:s,newContext:s}}try{this.logger.debug("About to call ensureWorkspaceReady",{requestId:c.sanitized}),await this.ensureWorkspaceReady(c.sanitized,r),this.logger.debug("ensureWorkspaceReady completed",{currentRequestId:n.requestId,currentWorktreePath:n.worktreePath})
4416
+ const t=Date.now()-o
4417
+ return this.metrics?.recordValue("workspace_switch_duration",t),a.WorkspaceLogging.logOperation(this.logger,"info","Switched to worktree for request",e,"multi-agent","switchToRequest",{worktreePath:n.worktreePath,duration:t}),{success:!0,message:"Switched to worktree for request: "+e,previousContext:s,newContext:this.getCurrentContext(r),worktreePath:n.worktreePath}}catch(t){const r=Date.now()-o
4418
+ return this.metrics?.recordValue("workspace_switch_duration",r),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to request",e,"multi-agent","switchToRequest",{error:(0,i.getErrorMessage)(t),duration:r}),{success:!1,message:"Failed to switch to request: "+(0,i.getErrorMessage)(t),previousContext:s,newContext:s}}}async switchToCompletedRequest(e,t,r){try{const n="requests/"+e
4419
+ a.WorkspaceLogging.logOperation(this.logger,"info","Switching to completed request (no worktree)",e,"multi-agent","switchToCompletedRequest",{branchName:n}),await this.mainGit.checkout(n)
4420
+ const o=this.getSession()
4421
+ o.requestId=e,o.worktreePath=null,o.git=this.mainGit
4422
+ const s=Date.now()-t
4423
+ return this.metrics?.recordValue("workspace_switch_duration",s),a.WorkspaceLogging.logOperation(this.logger,"info","Successfully switched to completed request branch",e,"multi-agent","switchToCompletedRequest",{branchName:n,duration:s,worktree:!1}),{success:!0,message:`Switched to completed request branch: ${n} (no worktree)`,previousContext:r,newContext:this.getCurrentContext()}}catch(n){const o=Date.now()-t
4424
+ return this.metrics?.recordValue("workspace_switch_duration",o),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to completed request",e,"multi-agent","switchToCompletedRequest",{error:(0,i.getErrorMessage)(n),duration:o}),{success:!1,message:"Failed to switch to completed request: "+(0,i.getErrorMessage)(n),previousContext:r,newContext:r}}}async switchToMain(e){const t=this.getSession(e),r=this.getCurrentContext(e)
4425
+ return t.requestId=null,t.worktreePath=null,t.git=this.mainGit,this.logger.info("Switched to main repository context"),{success:!0,message:"Switched to main repository",previousContext:r,newContext:this.getCurrentContext(e)}}async commitChanges(e,t,r){const n=this.getSession(r),o=Date.now()
4426
+ if(!n.requestId||!n.worktreePath)throw new a.ConflictDetectionError("No active request context for commit","multi-agent-commit",[])
4427
+ try{t&&t.length>0?await n.git.add(t):await n.git.add("."),await n.git.commit(e)
4428
+ const r=await n.git.revparse(["HEAD"]),s=Date.now()-o
4429
+ return this.metrics?.recordValue("workspace_commit_duration",s),this.logger.info("Successfully committed changes in worktree",{requestId:n.requestId,worktreePath:n.worktreePath,message:e,commitHash:r.substring(0,8),filesCount:t?.length||"all",duration:s}),{hash:r,message:e,files:t||[]}}catch(t){const r=Date.now()-o
4430
+ throw this.metrics?.recordValue("workspace_commit_duration",r),this.logger.error("Failed to commit changes in worktree",{requestId:n.requestId,worktreePath:n.worktreePath,message:e,error:(0,i.getErrorMessage)(t),duration:r}),new a.ConflictDetectionError("Failed to commit changes: "+(0,i.getErrorMessage)(t),"multi-agent-commit",[])}}async completeRequest(e,t,r){const n=Date.now()
4474
4431
  try{a.WorkspaceLogging.logOperation(this.logger,"info","Starting request completion (refactored)",e,"multi-agent","completeRequest",{requestTitle:t,skipConflictDetection:r?.skipConflictDetection||!1,architecture:"shared-processor"})
4475
4432
  const o=await this.requestProcessor.completeRequest(e,t,{skipConflictDetection:r?.skipConflictDetection||!1}),s=Date.now()-n
4476
- return this.metrics?.recordValue("workspace_complete_duration",s),this.metrics?.incrementCounter("workspace_complete_success",1),this.currentRequestId===e&&(this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit),a.WorkspaceLogging.logOperation(this.logger,"info","Request completion successful (refactored)",e,"multi-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:s,architecture:"shared-processor"}),o}catch(t){const r=Date.now()-n
4477
- throw this.metrics?.recordValue("workspace_complete_duration",r),this.metrics?.incrementCounter("workspace_complete_error",1),a.WorkspaceLogging.logOperation(this.logger,"error","Request completion failed (refactored)",e,"multi-agent","completeRequest",{error:(0,i.getErrorMessage)(t),duration:r,architecture:"shared-processor"}),t}}resolveFilePath(e){if(this.currentWorktreePath)return this.logger.debug("Resolving file path in worktree context",{relativePath:e,worktreePath:this.currentWorktreePath,requestId:this.currentRequestId}),n.default.resolve(this.currentWorktreePath,e)
4478
- const t=`Cannot resolve file path in multi-agent mode without request context. Current state: requestId=${this.currentRequestId}, worktreePath=${this.currentWorktreePath}. Ensure you switch to a request workspace before performing file operations.`
4479
- throw this.logger.error("Unsafe file path resolution attempt in multi-agent mode",{relativePath:e,currentRequestId:this.currentRequestId,currentWorktreePath:this.currentWorktreePath,basePath:this.basePath,action:"preventing_fallback_to_main"}),Error(t)}resolveMainBranchFilePath(e){return this.logger.debug("Resolving file path in main branch context",{relativePath:e,basePath:this.basePath,context:"explicit_main_branch_operation"}),n.default.resolve(this.basePath,e)}async createCommit(e,t){return await this.commitChanges(e,t)}async cancelRequest(e){const t=a.WorkspaceValidation.validateRequestId(e)
4433
+ this.metrics?.recordValue("workspace_complete_duration",s),this.metrics?.incrementCounter("workspace_complete_success",1)
4434
+ for(const[t,r]of this.sessions)r.requestId===e&&(r.requestId=null,r.worktreePath=null,r.git=this.mainGit)
4435
+ return a.WorkspaceLogging.logOperation(this.logger,"info","Request completion successful (refactored)",e,"multi-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:s,architecture:"shared-processor"}),o}catch(t){const r=Date.now()-n
4436
+ throw this.metrics?.recordValue("workspace_complete_duration",r),this.metrics?.incrementCounter("workspace_complete_error",1),a.WorkspaceLogging.logOperation(this.logger,"error","Request completion failed (refactored)",e,"multi-agent","completeRequest",{error:(0,i.getErrorMessage)(t),duration:r,architecture:"shared-processor"}),t}}resolveFilePath(e,t){const r=this.getSession(t)
4437
+ if(r.worktreePath)return this.logger.debug("Resolving file path in worktree context",{relativePath:e,worktreePath:r.worktreePath,requestId:r.requestId}),n.default.resolve(r.worktreePath,e)
4438
+ const o=`Cannot resolve file path in multi-agent mode without request context. Current state: requestId=${r.requestId}, worktreePath=${r.worktreePath}. Ensure you switch to a request workspace before performing file operations.`
4439
+ throw this.logger.error("Unsafe file path resolution attempt in multi-agent mode",{relativePath:e,currentRequestId:r.requestId,currentWorktreePath:r.worktreePath,basePath:this.basePath,action:"preventing_fallback_to_main"}),Error(o)}resolveMainBranchFilePath(e){return this.logger.debug("Resolving file path in main branch context",{relativePath:e,basePath:this.basePath,context:"explicit_main_branch_operation"}),n.default.resolve(this.basePath,e)}async createCommit(e,t,r){return await this.commitChanges(e,t,r)}async cancelRequest(e){const t=a.WorkspaceValidation.validateRequestId(e)
4480
4440
  if(!t.isValid)throw Error("Invalid request ID: "+t.errors.join(", "))
4481
4441
  const r=t.sanitized
4482
- try{this.currentRequestId===r&&await this.switchToMain()
4442
+ try{for(const[e,t]of this.sessions)t.requestId===r&&(t.requestId=null,t.worktreePath=null,t.git=this.mainGit)
4483
4443
  const e=await this.worktreeManager.removeWorktree(r,!1)
4484
4444
  if(!e.success)throw Error(e.message||"Failed to remove worktree")
4485
- this.logger.info("Successfully cancelled request",{requestId:r})}catch(e){throw this.logger.error("Failed to cancel request",{requestId:r,error:(0,i.getErrorMessage)(e)}),e}}getCurrentContext(){const e={requestId:this.currentRequestId,basePath:this.currentWorktreePath||this.basePath,branchName:this.currentRequestId?"requests/"+this.currentRequestId:"main",isMainBranch:!this.currentRequestId,mode:"multi-agent"}
4486
- return this.logger.debug("getCurrentContext returning",{context:e}),e}resetCurrentContext(){this.currentRequestId&&this.logger.info("Resetting workspace context (session switch)",{prevRequestId:this.currentRequestId,prevWorktreePath:this.currentWorktreePath}),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit}async getWorkspaceInfo(e){try{const t=a.WorkspaceValidation.validateRequestId(e)
4445
+ this.logger.info("Successfully cancelled request",{requestId:r})}catch(e){throw this.logger.error("Failed to cancel request",{requestId:r,error:(0,i.getErrorMessage)(e)}),e}}getCurrentContext(e){const t=this.getSession(e),r={requestId:t.requestId,basePath:t.worktreePath||this.basePath,branchName:t.requestId?"requests/"+t.requestId:"main",isMainBranch:!t.requestId,mode:"multi-agent"}
4446
+ return this.logger.debug("getCurrentContext returning",{context:r,sessionId:e}),r}resetCurrentContext(e){const t=this.getSession(e)
4447
+ t.requestId&&this.logger.info("Resetting workspace context (session switch)",{prevRequestId:t.requestId,prevWorktreePath:t.worktreePath,sessionId:e}),t.requestId=null,t.worktreePath=null,t.git=this.mainGit,t.readonlyBranchCheckDone=!1}async getWorkspaceInfo(e){try{const t=a.WorkspaceValidation.validateRequestId(e)
4487
4448
  if(!t.isValid)return null
4488
4449
  const r=t.sanitized,n=await this.getWorktreeInfo(r)
4489
- return n?{requestId:r,path:n.worktreePath,branchName:n.branchName,isActive:this.currentRequestId===r,created:new Date,lastAccessed:new Date}:null}catch(t){return this.logger.error("Failed to get workspace info",{requestId:e,error:(0,i.getErrorMessage)(t)}),null}}async listActiveWorkspaces(){try{return(await this.worktreeManager.listActiveWorktrees()).map((e=>this.convertWorktreeInfoToWorkspaceInfo(e)))}catch(e){return this.logger.error("Failed to list active workspaces",{error:(0,i.getErrorMessage)(e)}),[]}}extractRequestIdFromBranch(e){const t=e.match(/^requests\/(.+)$/)
4490
- return t?t[1]:null}convertWorktreeInfoToWorkspaceInfo(e){return{requestId:e.requestId,path:e.worktreePath,branchName:e.branchName,isActive:this.currentRequestId===e.requestId,created:e.created,lastAccessed:e.lastAccessed}}async getWorktreeInfo(e){try{const t=e.replace(/[^a-zA-Z0-9_-]/g,"_")
4491
- return this.worktreeManager.getWorktreeInfo(t)}catch(t){return void this.logger.warn("Failed to get worktree info",{requestId:e,error:(0,i.getErrorMessage)(t)})}}getMainGit(){return this.gitAdapter.getMainGit()}getCurrentGit(){return this.currentGit}async ensureReadonlyBranchIfNeeded(e,t,r,n){if(this.readonlyBranchCheckDone)return
4492
- this.readonlyBranchCheckDone=!0
4493
- const o=process.env.ALCHEMY_INITIAL_BRANCH
4494
- if(o){const e=o.match(/^requests\/(.+)$/)
4450
+ return n?{requestId:r,path:n.worktreePath,branchName:n.branchName,isActive:this.isActiveForAnySession(r),created:new Date,lastAccessed:new Date}:null}catch(t){return this.logger.error("Failed to get workspace info",{requestId:e,error:(0,i.getErrorMessage)(t)}),null}}async listActiveWorkspaces(){try{return(await this.worktreeManager.listActiveWorktrees()).map((e=>this.convertWorktreeInfoToWorkspaceInfo(e)))}catch(e){return this.logger.error("Failed to list active workspaces",{error:(0,i.getErrorMessage)(e)}),[]}}extractRequestIdFromBranch(e){const t=e.match(/^requests\/(.+)$/)
4451
+ return t?t[1]:null}convertWorktreeInfoToWorkspaceInfo(e){return{requestId:e.requestId,path:e.worktreePath,branchName:e.branchName,isActive:this.isActiveForAnySession(e.requestId),created:e.created,lastAccessed:e.lastAccessed}}async getWorktreeInfo(e){try{const t=e.replace(/[^a-zA-Z0-9_-]/g,"_")
4452
+ return this.worktreeManager.getWorktreeInfo(t)}catch(t){return void this.logger.warn("Failed to get worktree info",{requestId:e,error:(0,i.getErrorMessage)(t)})}}getMainGit(){return this.gitAdapter.getMainGit()}getCurrentGit(e){return this.getSession(e).git}get readonlyBranchCheckDone(){return this.getSession().readonlyBranchCheckDone}set readonlyBranchCheckDone(e){this.getSession().readonlyBranchCheckDone=e}get workspaceKnownClean(){return this.getSession().workspaceKnownClean}set workspaceKnownClean(e){this.getSession().workspaceKnownClean=e}get largeFileWarning(){return this.getSession().largeFileWarning}set largeFileWarning(e){this.getSession().largeFileWarning=e}async ensureReadonlyBranchIfNeeded(e,r,n,o){const s=this.getSession(o)
4453
+ if(s.readonlyBranchCheckDone)return
4454
+ if(s.readonlyBranchCheckDone=!0,o&&n)try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=await e.getSessionRequestId(n,this.logger,o)
4455
+ if(r)return await this.ensureWorkspaceReady(r,o),void this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready from session DB lookup",{requestId:r,sessionId:o})}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: session DB lookup failed, falling back to env var",{error:(0,i.getErrorMessage)(e)})}const a=process.env.ALCHEMY_INITIAL_BRANCH
4456
+ if(a){const e=a.match(/^requests\/(.+)$/)
4495
4457
  if(e){const t=e[1]
4496
- try{await this.ensureWorkspaceReady(t),this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready",{requestId:t})}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: failed to ensure workspace",{requestId:t,error:(0,i.getErrorMessage)(e)})}}}}async cleanup(){this.logger.info("Cleaning up multi-agent workspace manager"),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit}}},7645(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionAwareClient=void 0
4458
+ try{await this.ensureWorkspaceReady(t,o),this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready from env var",{requestId:t})}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: failed to ensure workspace",{requestId:t,error:(0,i.getErrorMessage)(e)})}}}}isActiveForAnySession(e){for(const[,t]of this.sessions)if(t.requestId===e)return!0
4459
+ return!1}async cleanup(){this.logger.info("Cleaning up multi-agent workspace manager"),this.sessions.clear()}}exports.MultiAgentWorkspaceManager=d,d.DEFAULT_SESSION="__default__"},7645(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionAwareClient=void 0
4497
4460
  const r=t(4192),n=t(7163)
4498
4461
  class o extends r.BaseApiClient{constructor(e,t,r,o,s,i){t.debug("ConnectionAwareClient constructor parameters:",{hasAuthToken:!!o,hasOptions:!!s,optionsType:s?typeof s:"undefined",options:s?JSON.stringify(s):"undefined",hasConnectionManager:!!i}),super(e,t,r,o,s),this.isGettingAuthToken=!1,this.connectionStatusManager=i||{isInOfflineMode(){return!1},isOffline(){return!1},setOfflineMode(){},async checkConnectivity(){return!0},getHealthCheckStats(){return{isOffline:!1,consecutiveFailures:0,currentBackoffMs:0,lastCheckTime:0}},cleanup(){}},o&&this.logger.debug("Client initialized with auth token",{clientType:this.constructor.name,tokenPrefix:o.substring(0,10)+"..."})
4499
4462
  try{(0,n.debugTokenAccess)(this,"ConnectionAwareClient constructor")}catch(e){this.logger.debug("Error accessing token details during init",{error:e instanceof Error?e.message:e+""})}}setConnectionStatusManager(e){this.logger.debug("Setting connection status manager in ConnectionAwareClient"),this.connectionStatusManager=e}}exports.ConnectionAwareClient=o},7660(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.projectContextMiddleware=exports.ProjectContext=exports.ProjectIDFactory=exports.ProjectID=void 0
@@ -4511,20 +4474,20 @@ return o(t,e),t})
4511
4474
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,t,r,n,o,s,g,p,f){const m=g.child({tool:"manage_files"})
4512
4475
  try{const h=a.validateArgs(e,i.ManageFilesSchema),{taskId:g,operations:y,comment:w}=h
4513
4476
  m.info("Processing manage-files operations",{taskId:g,operationCount:y.length,comment:w})
4514
- const k=[],I=[],b=[],v=[]
4477
+ const k=[],b=[],I=[],v=[]
4515
4478
  for(const e of y)switch(e.operationType){case"create-directory":k.push({path:e.createDirectory.path})
4516
4479
  break
4517
- case"move-files":for(const t of e.moveFiles.moves)I.push(t)
4480
+ case"move-files":for(const t of e.moveFiles.moves)b.push(t)
4518
4481
  break
4519
- case"delete-files":b.push(...e.deleteFiles.targets)
4482
+ case"delete-files":I.push(...e.deleteFiles.targets)
4520
4483
  break
4521
4484
  case"get-file-info":v.push({path:e.getFileInfo.path})}const C=[]
4522
4485
  for(const e of k){m.info("Routing to create-directory handler",{path:e.path})
4523
4486
  const s=await(0,c.handleCreateDirectory)({taskId:g,path:e.path,comment:w+" [via manage-files: create-directory]"},t,r,n,o,m,p,f)
4524
- C.push({type:"create-directory",result:s})}if(I.length>0){m.info("Routing to move-files handler",{operationCount:I.length})
4525
- const e=await(0,l.handleMoveFiles)({taskId:g,operations:I,comment:w+" [via manage-files: move-files]"},t,r,n,o,m,p,f)
4526
- C.push({type:"move-files",result:e})}if(b.length>0){m.info("Routing to delete-files handler",{operationCount:b.length})
4527
- const e=await(0,u.handleDeleteFiles)({taskId:g,operations:b,comment:w+" [via manage-files: delete-files]"},t,s,m,p,f)
4487
+ C.push({type:"create-directory",result:s})}if(b.length>0){m.info("Routing to move-files handler",{operationCount:b.length})
4488
+ const e=await(0,l.handleMoveFiles)({taskId:g,operations:b,comment:w+" [via manage-files: move-files]"},t,r,n,o,m,p,f)
4489
+ C.push({type:"move-files",result:e})}if(I.length>0){m.info("Routing to delete-files handler",{operationCount:I.length})
4490
+ const e=await(0,u.handleDeleteFiles)({taskId:g,operations:I,comment:w+" [via manage-files: delete-files]"},t,s,m,p,f)
4528
4491
  C.push({type:"delete-files",result:e})}for(const e of v){m.info("Routing to get-file-info handler",{path:e.path})
4529
4492
  const r=await(0,d.handleGetFileInfo)({path:e.path},t,m,p)
4530
4493
  C.push({type:"get-file-info",result:r})}const _=C.some((e=>e.result.isError)),E=C.filter((e=>!e.result.isError)).length,q=C.filter((e=>e.result.isError)).length
@@ -4614,19 +4577,19 @@ const n=r(t(6982))
4614
4577
  class o{static create(){return exports.ProjectIDFactory.create()}static fromString(e){return exports.ProjectIDFactory.fromString(e)}static isValid(e){return exports.ProjectIDFactory.isValid(e)}constructor(e){this.id=e}toString(){return this.id}equals(e){return this.id===e.toString()}isStandardFormat(){return this.id.includes("_")&&this.id.startsWith("prj_")}}exports.ProjectID=o,exports.ProjectIDFactory={create(){const e=Date.now().toString().substring(5),t=n.default.randomBytes(4).toString("hex")
4615
4578
  return o.fromString(`prj_${e}_${t}`)},fromString(e){return this.isValid(e)?new o(e):null},isValid(e){if(!e||"string"!=typeof e||5>e.length||!e.startsWith("prj"))return!1
4616
4579
  if(e.includes("_")){const t=e.split("_")
4617
- return t.length>=3&&"prj"===t[0]}return!1}},exports.ProjectIDBackwardCompat={create:exports.ProjectIDFactory.create,fromString:exports.ProjectIDFactory.fromString,isValid:exports.ProjectIDFactory.isValid},Object.assign(o,exports.ProjectIDBackwardCompat)},8035(e,exports,t){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:c,parentServerUrl:l,parentSessionId:d,sessionId:u,model:h,initialBranch:g,serverUrl:p,onSpawn:f,onError:m}=e
4580
+ return t.length>=3&&"prj"===t[0]}return!1}},exports.ProjectIDBackwardCompat={create:exports.ProjectIDFactory.create,fromString:exports.ProjectIDFactory.fromString,isValid:exports.ProjectIDFactory.isValid},Object.assign(o,exports.ProjectIDBackwardCompat)},8035(e,exports,t){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:d,parentSessionId:u,sessionId:h,model:g,initialBranch:p,serverUrl:f,onSpawn:m,onError:y}=e
4618
4581
  try{const s={...process.env}
4619
- l&&(s.OPENCODE_PARENT_SERVER=l),g&&(s.ALCHEMY_INITIAL_BRANCH=g),e.allowParallel&&(s.ALCHEMY_ALLOW_PARALLEL="1")
4620
- const d=new Date,m=`${(d.getHours()+"").padStart(2,"0")}${(d.getMinutes()+"").padStart(2,"0")}${(d.getSeconds()+"").padStart(2,"0")}`,y=Math.random().toString(36).substring(2,7)
4621
- let w
4622
- if(s.ALCHEMY_SESSION_TAG=`mcp-${m}-${y}`,r(c,"Spawn env setup",{agent:t,initialBranch:g||"none",hasParentServer:!!l,sessionId:u||"new",attachMode:!!p}),w=p&&u&&n?["run","--attach",p,"--session",u,"--agent",t,n]:u&&n?["run","--session",u,"--agent",t,n]:n?["run","--agent",t,n]:["run","--agent",t],h){const e=w.findIndex((e=>e===n))
4623
- e>0?w.splice(e,0,"--model",h):w.push("--model",h)}r(c,"Spawning opencode",{args:w.map((e=>e===n?`[prompt:${e.length}chars]`:e)),model:h||"not specified",promptLength:n?.length,promptPreview:n?.slice(0,100),cwd:c,hasSessionId:!!u,hasParentServerUrl:!!l})
4624
- const k=(0,a.join)(c||process.cwd(),".alchemy_lab"),I=(0,a.join)(k,"spawn-stderr.log")
4625
- let b
4626
- try{b=(0,i.openSync)(I,"a")}catch{}const v=(0,o.spawn)("opencode",w,{detached:!0,stdio:["ignore","ignore",b??"ignore"],cwd:c||process.cwd(),env:s})
4627
- return v.unref(),f&&f(v.pid),{success:!0,pid:v.pid}}catch(e){const t=(0,s.getErrorMessage)(e)
4628
- return m&&e instanceof Error&&m(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})}
4629
- const o=t(5317),s=t(8824),i=t(9896),a=t(6928)},8037(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListRequests=async function(e,t,i,a,c){const l=a.child({tool:"list_requests"}),d=c.startTimer("tool_execution_time")
4582
+ d&&(s.OPENCODE_PARENT_SERVER=d),p&&(s.ALCHEMY_INITIAL_BRANCH=p),e.allowParallel&&(s.ALCHEMY_ALLOW_PARALLEL="1")
4583
+ const u=new Date,y=`${(u.getHours()+"").padStart(2,"0")}${(u.getMinutes()+"").padStart(2,"0")}${(u.getSeconds()+"").padStart(2,"0")}`,w=Math.random().toString(36).substring(2,7)
4584
+ let k
4585
+ if(s.ALCHEMY_SESSION_TAG=`mcp-${y}-${w}`,r(l,"Spawn env setup",{agent:t,initialBranch:p||"none",hasParentServer:!!d,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))
4586
+ 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:!!d})
4587
+ const b=(0,a.join)(l||process.cwd(),".alchemy_lab"),I=(0,a.join)(b,"spawn-stderr.log")
4588
+ let v
4589
+ 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})
4590
+ return _.unref(),m&&m(_.pid),{success:!0,pid:_.pid}}catch(e){const t=(0,s.getErrorMessage)(e)
4591
+ 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})}
4592
+ const o=t(5317),s=t(8824),i=t(9896),a=t(6928),c=t(9068)},8037(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListRequests=async function(e,t,i,a,c){const l=a.child({tool:"list_requests"}),d=c.startTimer("tool_execution_time")
4630
4593
  try{const{filters:s={}}=e,a=["open","in_progress","ready_for_review","completed","canceled","reverted"]
4631
4594
  if(s.status&&!a.includes(s.status))throw new r.ValidationError(`Invalid status: ${s.status}. Must be one of: ${a.join(", ")}`)
4632
4595
  if(void 0!==s.limit&&1>s.limit)throw new r.ValidationError("Limit must be at least 1")
@@ -4679,31 +4642,31 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
4679
4642
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
4680
4643
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,t,r,n,o,s,i,p){const f=s.child({tool:"create_directory"}),m=Date.now()
4681
4644
  let y,w,k=d.FileOperationPhase.VALIDATION
4682
- const I={toolName:"create-directory",operationName:"create",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"create-directory",metricsPrefix:"create_directory",successMessage:"Successfully created directory {path}",failureMessage:"Failed to create directory {path}"}
4645
+ const b={toolName:"create-directory",operationName:"create",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"create-directory",metricsPrefix:"create_directory",successMessage:"Successfully created directory {path}",failureMessage:"Failed to create directory {path}"}
4683
4646
  try{const s=d.validateArgs(e,l.CreateDirectorySchema),{taskId:u,path:h,comment:g}=s
4684
- f.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,f,i,I.metricsPrefix),t.getCurrentBranchContext&&await t.getCurrentBranchContext()
4685
- const{normalizedPath:b,fullPath:v}=d.validateAndNormalizePath(h,t)
4647
+ f.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,f,i,b.metricsPrefix),t.getCurrentBranchContext&&await t.getCurrentBranchContext()
4648
+ const{normalizedPath:I,fullPath:v}=d.validateAndNormalizePath(h,t)
4686
4649
  k=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("create_directory_phase",1,{phase:k})
4687
- const C=await d.validateTaskId(u,b,r,f,i,I.metricsPrefix),_=C?.requestId,E=await d.validateWorkItemStates(u,b,r,o,t,f,i,I.metricsPrefix),q=await d.autoPromoteTaskStatus(u,C.status,_,E.request?.status,b,r,o,f,i,I.metricsPrefix)
4688
- q.taskPromoted&&f.info(`Auto-promoted task ${u} (${C.title||"Untitled"}) to in_progress for file operation`,{taskId:u,taskTitle:C.title,previousStatus:C.status,newStatus:q.newTaskStatus,path:b}),q.requestPromoted&&f.info(`Auto-promoted request ${_} to in_progress for file operation`,{requestId:_,previousStatus:E.request?.status,newStatus:q.newRequestStatus,triggeringTaskId:u})
4689
- const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:f,metrics:i,metricsPrefix:I.metricsPrefix})
4650
+ const C=await d.validateTaskId(u,I,r,f,i,b.metricsPrefix),_=C?.requestId,E=await d.validateWorkItemStates(u,I,r,o,t,f,i,b.metricsPrefix),q=await d.autoPromoteTaskStatus(u,C.status,_,E.request?.status,I,r,o,f,i,b.metricsPrefix)
4651
+ q.taskPromoted&&f.info(`Auto-promoted task ${u} (${C.title||"Untitled"}) to in_progress for file operation`,{taskId:u,taskTitle:C.title,previousStatus:C.status,newStatus:q.newTaskStatus,path:I}),q.requestPromoted&&f.info(`Auto-promoted request ${_} to in_progress for file operation`,{requestId:_,previousStatus:E.request?.status,newStatus:q.newRequestStatus,triggeringTaskId:u})
4652
+ const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:f,metrics:i,metricsPrefix:b.metricsPrefix})
4690
4653
  if(!S.success){if(S.isLockConflict)return{content:[{type:"text",text:"\u274c "+S.error}],isError:!0}
4691
4654
  throw Error(S.error)}let T=!1
4692
4655
  try{T=(await a.default.stat(v)).isDirectory()}catch{T=!1}k=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("create_directory_phase",1,{phase:k})
4693
- const{toolRecordId:P,localToolRecordId:M}=await d.createFileOperationRecords(u,_,t.projectId,I.recordType,b,{directoryExists:T,userComment:g},r,n,f,i,I.metricsPrefix,p)
4694
- y=P,w=P,k=I.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:k})
4695
- let R=T
4696
- if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+b)
4656
+ const{toolRecordId:P,localToolRecordId:M}=await d.createFileOperationRecords(u,_,t.projectId,b.recordType,I,{directoryExists:T,userComment:g},r,n,f,i,b.metricsPrefix,p)
4657
+ y=P,w=P,k=b.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:k})
4658
+ let j=T
4659
+ if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+I)
4697
4660
  try{const e=c.default.join(v,".gitkeep")
4698
- await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),R=!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+""}),R=!1}}const j=Date.now()-m
4699
- i.recordValue("create_directory_time",j),i.incrementCounter("create_directory_success",1),k=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("create_directory_phase",1,{phase:k})
4700
- const x=`Create directory: ${b} - ${g||"Create directory"}`,O=!T&&R?b+"/.gitkeep":b,A=await d.commitToGit(u,O,P,M,x,t,f,i,I.metricsPrefix)
4701
- k=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:k}),await d.updateFileOperationRecords(u,y,w,b,I.recordType,`Successfully ${T?"verified":"created"} directory: ${b}`,{status:"completed",commitHash:A.commitHash,previousCommitHash:A.previousCommitHash,directoryExists:T,isDirectory:!0,userComment:g},`Successfully ${T?"verified":"created"} directory: ${b}`,r,n,f,i,I.metricsPrefix)
4661
+ await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),j=!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+""}),j=!1}}const R=Date.now()-m
4662
+ i.recordValue("create_directory_time",R),i.incrementCounter("create_directory_success",1),k=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("create_directory_phase",1,{phase:k})
4663
+ const x=`Create directory: ${I} - ${g||"Create directory"}`,O=!T&&j?I+"/.gitkeep":I,A=await d.commitToGit(u,O,P,M,x,t,f,i,b.metricsPrefix)
4664
+ k=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:k}),await d.updateFileOperationRecords(u,y,w,I,b.recordType,`Successfully ${T?"verified":"created"} directory: ${I}`,{status:"completed",commitHash:A.commitHash,previousCommitHash:A.previousCommitHash,directoryExists:T,isDirectory:!0,userComment:g},`Successfully ${T?"verified":"created"} directory: ${I}`,r,n,f,i,b.metricsPrefix)
4702
4665
  const D=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
4703
4666
  return{content:[{type:"text",text:T?"Directory already exists":`Successfully created directory${A.commitHash?"\nCommit: "+A.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 u.NotFoundError||o instanceof u.ValidationError||o instanceof h.ZodError
4704
4667
  await n.createToolRecord({...r?{}:{taskId:e.taskId},projectId:t.projectId,type:"create-directory",metadata:{status:"failed",timestamp:(new Date).toISOString(),path:e.path,userComment:e.comment,error:(0,g.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:k,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:`Failed to create directory ${e.path} - ${(0,g.getErrorMessage)(o)}`})}catch(t){f.error("Failed to create failure record for create directory operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,path:e.path})}const s=Date.now()-m
4705
4668
  if(i.recordValue("create_directory_time",s),i.incrementCounter("create_directory_errors",1),f.error("Error creating directory:",{error:(0,g.getErrorMessage)(o),time:s}),(y||w)&&e.taskId){k=d.FileOperationPhase.RECORD_UPDATE_FAILURE
4706
- try{await d.updateFileOperationRecords(e.taskId,y,w,e.path,I.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,g.getErrorMessage)(o),userComment:e.comment},"Failed to create directory "+e.path,r,n,f,i,I.metricsPrefix)}catch(t){f.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,k,f,i,e,I)}}
4669
+ try{await d.updateFileOperationRecords(e.taskId,y,w,e.path,b.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,g.getErrorMessage)(o),userComment:e.comment},"Failed to create directory "+e.path,r,n,f,i,b.metricsPrefix)}catch(t){f.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,k,f,i,e,b)}}
4707
4670
  const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(8824)},8317(e,exports,t){function r(e){const t=[]
4708
4671
  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)]}function n(e){switch(e){case"write-file":return"\u{1f4dd} Write File"
4709
4672
  case"replace-in-files":return"\u{1f504} Replace in Files"
@@ -4912,34 +4875,34 @@ return i(t,e),t})
4912
4875
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileHistory=async function(e,t,n,o,s){const i=o.child({tool:"file_history"}),a=s.startTimer("tool_execution_time"),m=Date.now()
4913
4876
  try{let o
4914
4877
  try{o=d.FileHistorySchema.parse(e)}catch(t){if(t instanceof u.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
4915
- return i.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{path:a,limit:y,showDiff:w,showTraceability:k,branch:I,commit:b,since:v}=o
4916
- return b?(i.info("Getting diff for specific commit",{filePath:a,commit:b}),await async function(e,t,r,n){const o=r.git,s=c.normalize(e).replace(/\\/g,"/")
4878
+ return i.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{path:a,limit:y,showDiff:w,showTraceability:k,branch:b,commit:I,since:v}=o
4879
+ return I?(i.info("Getting diff for specific commit",{filePath:a,commit:I}),await async function(e,t,r,n){const o=r.git,s=c.normalize(e).replace(/\\/g,"/")
4917
4880
  if(n.info("Getting full diff for commit",{filePath:e,commit:t}),!o)return{content:[{type:"text",text:"\u274c Git not initialized"}],isError:!0}
4918
4881
  try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
4919
4882
  if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
4920
4883
  const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
4921
4884
  let a="# File History - Commit Diff\n\n"
4922
- return a+=`**File:** ${e}\n`,a+=`**Commit:** ${t.substring(0,8)}\n`,a+=`**Author:** ${n.author_name}\n`,a+=`**Date:** ${n.date}\n`,a+=`**Message:** ${n.message}\n\n`,i&&i.trim()?a+=`## Full Diff\n\n\`\`\`diff\n${i}\n\`\`\`\n`:a+="*No diff available for this commit*\n",{content:[{type:"text",text:a}]}}catch(r){return n.error("Failed to get commit diff",{error:r,commit:t,filePath:e}),{content:[{type:"text",text:`\u274c Failed to get diff for commit ${t}: ${(0,p.getErrorMessage)(r)}`}],isError:!0}}}(a,b,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:y,showDiff:w,showTraceability:k,branch:I}),await async function(e,t,n,o,s,i,a,c,d,u,p){try{const{normalizedPath:m,fullPath:y}=f.validateAndNormalizePath(e,a)
4885
+ return a+=`**File:** ${e}\n`,a+=`**Commit:** ${t.substring(0,8)}\n`,a+=`**Author:** ${n.author_name}\n`,a+=`**Date:** ${n.date}\n`,a+=`**Message:** ${n.message}\n\n`,i&&i.trim()?a+=`## Full Diff\n\n\`\`\`diff\n${i}\n\`\`\`\n`:a+="*No diff available for this commit*\n",{content:[{type:"text",text:a}]}}catch(r){return n.error("Failed to get commit diff",{error:r,commit:t,filePath:e}),{content:[{type:"text",text:`\u274c Failed to get diff for commit ${t}: ${(0,p.getErrorMessage)(r)}`}],isError:!0}}}(a,I,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:y,showDiff:w,showTraceability:k,branch:b}),await async function(e,t,n,o,s,i,a,c,d,u,p){try{const{normalizedPath:m,fullPath:y}=f.validateAndNormalizePath(e,a)
4923
4886
  try{await l.access(y)}catch(e){throw Error("File not found: "+m)}const w=a.git
4924
4887
  if(!w)throw Error("Git is not available in this context")
4925
4888
  let k={branch:null,requestId:null,isMain:!0}
4926
- if(a.getCurrentBranchContext)try{k=await a.getCurrentBranchContext(),d.info("Current branch context detected",{branch:k.branch,requestId:k.requestId,isMain:k.isMain})}catch(e){d.warn("Could not get current branch context",{error:e})}let I=[],b=""
4927
- if(s)I=await r(w,m,t,n,o,s,i,c,d,u),b=`## File History: ${m} (Branch: ${s})\n\n`
4889
+ if(a.getCurrentBranchContext)try{k=await a.getCurrentBranchContext(),d.info("Current branch context detected",{branch:k.branch,requestId:k.requestId,isMain:k.isMain})}catch(e){d.warn("Could not get current branch context",{error:e})}let b=[],I=""
4890
+ if(s)b=await r(w,m,t,n,o,s,i,c,d,u),I=`## File History: ${m} (Branch: ${s})\n\n`
4928
4891
  else{if(k.isMain&&!o)return d.info("Showing request-level timeline on main branch"),{content:[{type:"text",text:await(0,g.getRequestTimelineForFile)(w,m,c,d,u)}]}
4929
4892
  if(k.requestId)return d.info("Showing operation-level detail on request branch",{requestId:k.requestId}),{content:[{type:"text",text:await(0,g.getOperationDetailForFile)(m,k.requestId,c,d,u)}]}
4930
4893
  {const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
4931
4894
  if(!i.isMain&&i.branch){const g=await r(e,t,n,o,s,i.branch,a,c,l,d)
4932
4895
  u.push(...g),g.length>0&&h.push(i.branch+" (current)")}const g=await r(e,t,n,o,s,"main",a,c,l,d),p=new Set(u.map((e=>e.hash))),f=g.filter((e=>!p.has(e.hash)))
4933
4896
  return u.push(...f),g.length>0&&h.push("main"),u.sort(((e,t)=>new Date(t.date).getTime()-new Date(e.date).getTime())),{versions:u.slice(0,n),sources:h}}(w,m,t,n,o,k,i,c,d,u)
4934
- I=e.versions,b=`## File History: ${m} (Combined View)\n\n`,b+=`**Current Context:** ${k.isMain?"main":`${k.branch} (${k.requestId})`}\n`,b+=`**History Sources:** ${e.sources.join(", ")}\n\n`}}if(0===I.length)return b+="\u274c **No history found**\n\nThis file has no git history. It may be:\n- A new file that hasn't been committed\n- Located outside the git repository\n- The path may be incorrect\n- No history exists in the specified branch context",{content:[{type:"text",text:b}]}
4935
- const v=I.length,C=Math.min(I.length,t)
4936
- v>t?b+=`\u{1f4ca} **Summary:** ${v} versions found, showing ${C} most recent\n\n`:v>0&&(b+=`\u{1f4ca} **Summary:** ${v} version${v>1?"s":""} found\n\n`),b+=`**Total Versions:** ${I.length}\n`,b+="**Current File Size:** "
4937
- try{b+=(await l.stat(y)).size+" bytes\n"}catch{b+="Unknown\n"}b+="\n"
4938
- for(let e=0;e<I.length;e++){const t=I[e]
4939
- if(b+=`### Version ${e+1} (${t.hash.substring(0,8)})\n`,t.branch&&(b+=`- **Branch:** ${t.branch}\n`),b+=`- **Author:** ${t.author}\n`,b+=`- **Date:** ${t.date}\n`,b+=`- **Message:** ${t.message}\n`,o&&t.traceability&&(b+=`\n${(0,h.formatTraceabilityInfo)(t.traceability)}\n`),n&&t.diff){const e=t.diff.split("\n")
4897
+ b=e.versions,I=`## File History: ${m} (Combined View)\n\n`,I+=`**Current Context:** ${k.isMain?"main":`${k.branch} (${k.requestId})`}\n`,I+=`**History Sources:** ${e.sources.join(", ")}\n\n`}}if(0===b.length)return I+="\u274c **No history found**\n\nThis file has no git history. It may be:\n- A new file that hasn't been committed\n- Located outside the git repository\n- The path may be incorrect\n- No history exists in the specified branch context",{content:[{type:"text",text:I}]}
4898
+ const v=b.length,C=Math.min(b.length,t)
4899
+ v>t?I+=`\u{1f4ca} **Summary:** ${v} versions found, showing ${C} most recent\n\n`:v>0&&(I+=`\u{1f4ca} **Summary:** ${v} version${v>1?"s":""} found\n\n`),I+=`**Total Versions:** ${b.length}\n`,I+="**Current File Size:** "
4900
+ try{I+=(await l.stat(y)).size+" bytes\n"}catch{I+="Unknown\n"}I+="\n"
4901
+ for(let e=0;e<b.length;e++){const t=b[e]
4902
+ if(I+=`### Version ${e+1} (${t.hash.substring(0,8)})\n`,t.branch&&(I+=`- **Branch:** ${t.branch}\n`),I+=`- **Author:** ${t.author}\n`,I+=`- **Date:** ${t.date}\n`,I+=`- **Message:** ${t.message}\n`,o&&t.traceability&&(I+=`\n${(0,h.formatTraceabilityInfo)(t.traceability)}\n`),n&&t.diff){const e=t.diff.split("\n")
4940
4903
  let r=0,n=0
4941
4904
  for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
4942
- b+=`\n**Changes:**${r>0||n>0?` (Added ${r} lines, removed ${n} lines)`:""}\n\`\`\`diff\n${t.diff}\n\`\`\`\n`}b+="\n"}return b+="\u{1f4a1} **Tips:**\n",b+="- Use `file-recover` with a commit hash to restore the file to a previous version\n",b+='- Use `{"branch": "main"}` to see only main branch history\n',b+='- Use `{"branch": "req123456"}` to see only request branch history\n\n',d.info("Branch-aware file history retrieved successfully",{path:m,versions:I.length,targetBranch:s,currentBranch:k.branch,duration:Date.now()-p}),u.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:b}]}}catch(e){throw e}}(a,y,w,k,I,v,t,n,i,s,m))}catch(e){const t=Date.now()-m
4905
+ I+=`\n**Changes:**${r>0||n>0?` (Added ${r} lines, removed ${n} lines)`:""}\n\`\`\`diff\n${t.diff}\n\`\`\`\n`}I+="\n"}return I+="\u{1f4a1} **Tips:**\n",I+="- Use `file-recover` with a commit hash to restore the file to a previous version\n",I+='- Use `{"branch": "main"}` to see only main branch history\n',I+='- Use `{"branch": "req123456"}` to see only request branch history\n\n',d.info("Branch-aware file history retrieved successfully",{path:m,versions:b.length,targetBranch:s,currentBranch:k.branch,duration:Date.now()-p}),u.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:I}]}}catch(e){throw e}}(a,y,w,k,b,v,t,n,i,s,m))}catch(e){const t=Date.now()-m
4943
4906
  return i.error("File/Document history operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),a({tool:"file_history",success:!1}),s.incrementCounter("file_history_errors",1),{content:[{type:"text",text:"\u274c **History Operation Failed:** "+(0,p.getErrorMessage)(e)}],isError:!0}}}
4944
4907
  const c=a(t(6928)),l=a(t(1943)),d=t(6183),u=t(1569),h=t(1181),g=t(2085),p=t(8824),f=a(t(5967)),m=a(t(7478)),{getCurrentBranch:y}=m},8850(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
4945
4908
  const r=t(6183),n=t(6891)
@@ -5072,7 +5035,14 @@ if(!o.ok)return void this.logger.debug("Polling response not ok",{status:o.statu
5072
5035
  const i=await o.json()
5073
5036
  if(this.logger.debug("Google OAuth polling response",{data:i}),i.success&&i.data&&i.data.authenticated&&i.data.token){this.logger.info("Google OAuth authentication completed")
5074
5037
  const e=this.parseTokenResponse(i.data)
5075
- e&&(this.pollingStatus=s.AUTHENTICATED,this.tokenResult=e,this.stopPolling(),r&&r(e))}else this.logger.debug("Not authenticated yet, continuing to poll",{hasSuccess:!!i.success,hasData:!!i.data,authenticated:i.data?.authenticated})}catch(e){this.logger.error("Error during Google OAuth polling",{error:(0,o.getErrorMessage)(e)}),this.pollingStatus=s.ERROR,this.pollingError=(0,o.getErrorMessage)(e),this.stopPolling(),i&&i(this.pollingError)}}),this.pollingIntervalMs),{authUrl:e,state:t}}}},9072(e,exports,t){async function r(e,t,r,n){try{const o=await(0,d.getServerUrl)(r,n)
5038
+ e&&(this.pollingStatus=s.AUTHENTICATED,this.tokenResult=e,this.stopPolling(),r&&r(e))}else this.logger.debug("Not authenticated yet, continuing to poll",{hasSuccess:!!i.success,hasData:!!i.data,authenticated:i.data?.authenticated})}catch(e){this.logger.error("Error during Google OAuth polling",{error:(0,o.getErrorMessage)(e)}),this.pollingStatus=s.ERROR,this.pollingError=(0,o.getErrorMessage)(e),this.stopPolling(),i&&i(this.pollingError)}}),this.pollingIntervalMs),{authUrl:e,state:t}}}},9068(e,exports,t){function r(){const e=process.env.ALCHEMY_OPENCODE_DIR
5039
+ if(e)return e
5040
+ try{const e=Object(function(){var e=Error("Cannot find module 'alchemylab-opencode/package.json'")
5041
+ throw e.code="MODULE_NOT_FOUND",e}())
5042
+ return(0,o.dirname)(e)}catch{}}function n(e,t){return{command:"node",prependArgs:["--experimental-strip-types","--experimental-transform-types","--no-warnings","--import",(0,o.join)(e,"node-preload.mjs"),(0,o.join)(e,t)]}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.resolveServeCommand=function(){const e=r()
5043
+ return e?n((0,o.join)(e,"packages","opencode","src"),"serve.ts"):{command:"opencode",prependArgs:["serve"]}},exports.resolveRunCommand=function(){const e=r()
5044
+ return e?n((0,o.join)(e,"packages","opencode","src"),"run.ts"):{command:"opencode",prependArgs:[]}}
5045
+ const o=t(6928)},9072(e,exports,t){async function r(e,t,r,n){try{const o=await(0,d.getServerUrl)(r,n)
5076
5046
  if(!o)return n.warn("Could not get server URL for notification",{sessionId:e}),!1
5077
5047
  let s,i
5078
5048
  try{const t=`http://localhost:${g}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
@@ -5081,27 +5051,23 @@ e.success&&e.agentType&&(s=e.agentType)}}catch(t){n.warn("Agent type lookup fail
5081
5051
  if(e.ok){const t=await e.json()
5082
5052
  if(t.data?.defaultModel){const[e,...r]=t.data.defaultModel.split("/")
5083
5053
  i={providerID:e,modelID:r.join("/")}}}}catch{}const a=`${o.replace(/\/$/,"")}/session/${e}/prompt_async`,c=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:"\x3c!-- inserted-prompt --\x3e"+t}],...s?{agent:s}:{},...i?{model:i}:{}})})
5084
- return c.ok?(n.info("Notified session",{sessionId:e}),!0):(n.warn("Failed to notify session",{sessionId:e,status:c.status}),!1)}catch(t){return n.warn("Error notifying session",{sessionId:e,error:(0,l.getErrorMessage)(t)}),!1}}function n(e,t,r){return u.sessionIdentity.getParentSessionId(e,t,r)}async function o(e,t,r,n){const o=u.sessionIdentity.getIdentity()
5085
- if(o?.sessionId)return(0,h.logSessionIdentity)(""+r,"identity-cache",{sessionId:o.sessionId}),o.sessionId
5086
- const s=await(0,d.getServerUrl)(e,t)
5087
- if(!s)throw new c.ValidationError("Could not determine OpenCode server URL")
5088
- const i=await(0,d.getAndStoreSessionId)(s,t,r,n),a=i?.sessionId
5089
- if(!a)throw new c.ValidationError("Could not discover current session ID. Make sure you are running within an OpenCode session.")
5090
- return(0,h.logSessionIdentity)(""+r,"per-call-discovery",{sessionId:a}),a}function s(e){const t=[],r=e.content||{}
5054
+ return c.ok?(n.info("Notified session",{sessionId:e}),!0):(n.warn("Failed to notify session",{sessionId:e,status:c.status}),!1)}catch(t){return n.warn("Error notifying session",{sessionId:e,error:(0,l.getErrorMessage)(t)}),!1}}function n(e,t,r){return u.sessionIdentity.getParentSessionId(e,t,r)}function o(e,t,r){const n=u.sessionIdentity.getIdentity()
5055
+ if(!n?.sessionId)throw new c.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
5056
+ return(0,h.logSessionIdentity)(""+r,"identity",{sessionId:n.sessionId}),n.sessionId}function s(e){const t=[],r=e.content||{}
5091
5057
  if(t.push("**Message Code:** "+e.messageCode),t.push(`**Type:** question (${r.questionType})`),t.push("**Status:** "+e.status),t.push("**Priority:** "+e.priority),t.push("**From:** "+e.fromSessionId),t.push(e.toSessionId?"**To:** "+e.toSessionId:"**To:** (broadcast)"),t.push("**Created:** "+e.createdAt),t.push("**Expires:** "+e.expiresAt),t.push(""),t.push("**Question:** "+r.question),r.context&&t.push("**Context:** "+r.context),"alternatives"===r.questionType&&r.options){t.push(""),t.push("**Options:**")
5092
5058
  for(const e of r.options)t.push(` - [${e.id}] ${e.label}${e.description?" - "+e.description:""}`)}return"responded"===e.status&&e.response&&(t.push(""),t.push("---"),t.push("**Answered by:** "+e.respondedBySessionId),t.push("**Answered at:** "+e.respondedAt),e.response.text&&t.push("**Answer:** "+e.response.text),e.response.selectedOptions&&t.push("**Selected:** "+e.response.selectedOptions.join(", ")),e.response.notes&&t.push("**Notes:** "+e.response.notes)),t.join("\n")}function i(e){const t=[],r=e.content||{}
5093
- return t.push("**Status:** "+(r.reportStatus||"unknown")),t.push("**Summary:** "+(r.summary||"")),r.details&&(t.push(""),t.push("**Details:**"),t.push(r.details)),t.join("\n")}function a(e){return"question"===e.messageType?s(e):i(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSessionMessageOperations=async function(e,t,p,f,m){const y=p.child({component:"session_message_operations"})
5094
- if(!m)throw new c.ValidationError("API client not available")
5095
- const{operation:w}=e
5096
- y.info("Session message operation",{operation:w}),f.incrementCounter("session_message_operations",1,{operation:w})
5097
- try{switch(w){case"send":if(!e.type)throw new c.ValidationError('send operation requires type ("question" or "report")')
5059
+ return t.push("**Status:** "+(r.reportStatus||"unknown")),t.push("**Summary:** "+(r.summary||"")),r.details&&(t.push(""),t.push("**Details:**"),t.push(r.details)),t.join("\n")}function a(e){return"question"===e.messageType?s(e):i(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSessionMessageOperations=async function(e,t,d,p,f){const m=d.child({component:"session_message_operations"})
5060
+ if(!f)throw new c.ValidationError("API client not available")
5061
+ const{operation:y}=e
5062
+ m.info("Session message operation",{operation:y}),p.incrementCounter("session_message_operations",1,{operation:y})
5063
+ try{switch(y){case"send":if(!e.type)throw new c.ValidationError('send operation requires type ("question" or "report")')
5098
5064
  return await async function(e,t,a,l){const{type:d}=e
5099
5065
  if(!d)throw new c.ValidationError('send operation requires type ("question" or "report")')
5100
5066
  const u=l.getSessionMessageClient()
5101
5067
  if(!u)throw new c.ValidationError("Session message client not available")
5102
5068
  if("question"===d)return await async function(e,t,i,a,l){const{toSessionId:d,questionType:u,questionContent:h,priority:g,expiresInHours:p}=e
5103
5069
  if(!u||!h?.question)throw new c.ValidationError("Question requires questionType and questionContent.question")
5104
- const f=await o(t,i,"session_message_operations",{operation:"send",send:{type:"question",questionType:u,questionContent:h}}),m=await async function(e,t,r,o){if("parent"===e){const e=await n(t,r,o)
5070
+ 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)
5105
5071
  if(!e)throw new c.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
5106
5072
  return o.info('Resolved toSessionId "parent" to actual ID',{parentId:e}),e}return e}(d,f,a,i)
5107
5073
  if(!("alternatives"!==u||h.options&&Array.isArray(h.options)))throw new c.ValidationError("Alternatives questions require options array")
@@ -5113,7 +5079,7 @@ if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&
5113
5079
  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,u)
5114
5080
  if("report"===d)return await async function(e,t,s,a,l){const{status:d,summary:u,details:h,finish:p}=e
5115
5081
  if(!d||!u)throw new c.ValidationError("Report requires status and summary")
5116
- const f=await o(t,s,"session_message_operations",{operation:"send",send:{type:"report",status:d,summary:u}}),m=await(async()=>{if(e.toSessionId&&"parent"!==e.toSessionId)return s.info("Using explicit toSessionId for report",{parentSessionId:e.toSessionId}),e.toSessionId
5082
+ 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
5117
5083
  const t=await n(f,a,s)
5118
5084
  if(!t)throw new c.ValidationError("Could not find parent session. This tool should only be used by subagent sessions.")
5119
5085
  return s.info("Auto-resolved parent session",{parentSessionId:t}),t})()
@@ -5125,7 +5091,7 @@ if(e.ok){const t=await e.json()
5125
5091
  t.success&&t.agentType&&(w=t.agentType)}}catch{}const k=await r(m,function(e,t="agent"){const r=e.content||{},n=[`${{success:"\u2705",partial:"\u26a0\ufe0f",failure:"\u274c",blocked:"\u{1f6ab}"}[r.reportStatus]||"\u{1f4cb}"} **Report \u2014 ${r.reportStatus}**`,`from: ${t} (${e.fromSessionId})`,"",r.summary]
5126
5092
  return r.details&&(n.push(""),n.push(r.details)),n.join("\n")}(y,w),t,s)
5127
5093
  return{content:[{type:"text",text:`\u2705 Report submitted.${k?"\n\n\u{1f4ec} The parent session has been notified.":"\n\n\u26a0\ufe0f Could not notify the parent session (may be offline)."}\n\n${i(y)}`}]}}(e,t,a,l,u)
5128
- throw new c.ValidationError(`Unknown message type: ${d}. Use "question" or "report".`)}(e,t,y,m)
5094
+ throw new c.ValidationError(`Unknown message type: ${d}. Use "question" or "report".`)}(e,t,m,f)
5129
5095
  case"reply":if(!e.messageCode)throw new c.ValidationError("reply operation requires messageCode")
5130
5096
  return await async function(e,t,n,o){const{messageCode:a}=e
5131
5097
  if(!a)throw new c.ValidationError("reply operation requires messageCode")
@@ -5136,26 +5102,24 @@ n.info("Answering question",{messageCode:a,respondedBySessionId:o})
5136
5102
  const u=await l.answerQuestion(a,{respondedBySessionId:o,text:i,selectedOptions:c,notes:d})
5137
5103
  return{content:[{type:"text",text:`\u2705 Question answered!${await r(u.fromSessionId,function(e){const t=e.content||{},r=e.response||{},n=["\u{1f4ec} **Your question has been answered!**","","**Question Code:** "+e.messageCode,"**Question:** "+t.question,"","---","**Answered by:** "+e.respondedBySessionId]
5138
5104
  return r.text&&n.push("**Answer:** "+r.text),r.selectedOptions&&n.push("**Selected:** "+r.selectedOptions.join(", ")),r.notes&&n.push("**Notes:** "+r.notes),n.join("\n")}(u),t,n)?"\n\n\u{1f4ec} The asking session has been notified.":"\n\n\u26a0\ufe0f Could not notify the asking session (may be offline)."}\n\n${s(u)}`}]}}if(a.startsWith("R-"))return n.info("Acknowledging report",{messageCode:a}),{content:[{type:"text",text:"\u2705 Report acknowledged!\n\n"+i(await l.acknowledgeReport(a))}]}
5139
- throw new c.ValidationError(`Cannot determine message type from code "${a}". Expected Q-xxx (question) or R-xxx (report).`)}(e,t,y,m)
5140
- case"offer-handoff":{const r=e.offerHandoff||{summary:e.summary||"",requestIds:e.requestIds||[]}
5141
- let s=null,i=null
5142
- try{s=await o(t,y,"session_message_operations",{operation:"offer-handoff"}),i=await n(s,m,y)}catch(e){y.warn("offer-handoff: could not discover parent session via HTTP",{error:(0,l.getErrorMessage)(e)})}if(!s){const e=u.sessionIdentity.getIdentity()
5143
- if(e?.sessionId){if(s=e.sessionId,y.info("offer-handoff: using cached session as fallback",{sessionId:s}),!i)try{i=await n(s,m,y)}catch(e){y.warn("offer-handoff: could not resolve parent from cached session",{error:(0,l.getErrorMessage)(e)})}}else y.warn("offer-handoff: no session ID available (discovery failed, no cache)")}try{const e=m.getSessionMessageClient()
5144
- if(e&&s){const t=r.requestIds?.length||0
5145
- await e.createQuestion({fromSessionId:s,toSessionId:i||void 0,questionType:"alternatives",question:"Plan ready: "+(r.summary||"Plan complete"),options:[{id:"build",label:"Start Building",description:`Begin building ${t} request${1!==t?"s":""}`},{id:"plan",label:"Keep Planning",description:"Continue refining the plan"}],context:t>0?"Created requests: "+r.requestIds.join(", "):void 0,category:"action-required",priority:"high"}),y.info("offer-handoff: notification question created",{fromSessionId:s})}else y.warn("offer-handoff: skipping notification question",{hasClient:!!e,fromSessionId:s})}catch(e){y.warn("offer-handoff: failed to create notification question",{error:(0,l.getErrorMessage)(e)})}return{content:[{type:"text",text:'Handoff offered to user. STOP here and wait \u2014 the user will choose "Start Building" or "Keep Planning". You will receive their choice as a new message. Do NOT generate any further output until then.\nPLAN_HANDOFF_PENDING|'+JSON.stringify({summary:r.summary,requestIds:r.requestIds,parentSessionId:i})}],isError:!1}}case"list":return await async function(e,t,r,n){let{sessionId:o,messageType:s,direction:i,status:l,readStatus:u,reportStatus:g,limit:p,offset:f}=e
5105
+ throw new c.ValidationError(`Cannot determine message type from code "${a}". Expected Q-xxx (question) or R-xxx (report).`)}(e,t,m,f)
5106
+ case"offer-handoff":{const t=e.offerHandoff||{summary:e.summary||"",requestIds:e.requestIds||[]}
5107
+ let r=null,s=null
5108
+ try{r=o(0,0,"session_message_operations"),s=await n(r,f,m)}catch(e){m.warn("offer-handoff: could not resolve session/parent",{error:(0,l.getErrorMessage)(e)})}try{const e=f.getSessionMessageClient()
5109
+ if(e&&r){const n=t.requestIds?.length||0
5110
+ await e.createQuestion({fromSessionId:r,toSessionId:s||void 0,questionType:"alternatives",question:"Plan ready: "+(t.summary||"Plan complete"),options:[{id:"build",label:"Start Building",description:`Begin building ${n} request${1!==n?"s":""}`},{id:"plan",label:"Keep Planning",description:"Continue refining the plan"}],context:n>0?"Created requests: "+t.requestIds.join(", "):void 0,category:"action-required",priority:"high"}),m.info("offer-handoff: notification question created",{fromSessionId:r})}else m.warn("offer-handoff: skipping notification question",{hasClient:!!e,fromSessionId:r})}catch(e){m.warn("offer-handoff: failed to create notification question",{error:(0,l.getErrorMessage)(e)})}return{content:[{type:"text",text:'Handoff offered to user. STOP here and wait \u2014 the user will choose "Start Building" or "Keep Planning". You will receive their choice as a new message. Do NOT generate any further output until then.\nPLAN_HANDOFF_PENDING|'+JSON.stringify({summary:t.summary,requestIds:t.requestIds,parentSessionId:s})}],isError:!1}}case"list":return await async function(e,t,r,n){let{sessionId:o,messageType:s,direction:i,status:l,readStatus:d,reportStatus:g,limit:p,offset:f}=e
5146
5111
  const m=n.getSessionMessageClient()
5147
5112
  if(!m)throw new c.ValidationError("Session message client not available")
5148
- if(!o){const e=await(0,d.getServerUrl)(t,r)
5149
- if(!e)return{content:[{type:"text",text:"\u26a0\ufe0f Could not connect to OpenCode server. Unable to list messages without a session context."}]}
5150
- {const t={operation:"list",list:{messageType:s,direction:i,status:l}},n=await(0,d.getAndStoreSessionId)(e,r,"session_message_operations",t)
5151
- if(o=n?.sessionId,(0,h.logSessionIdentity)("session_message_operations.list",o?"per-call-discovery":"discovery-failed",{sessionId:o}),!o)return r.warn("Session discovery FAILED for list - returning empty to prevent data leak"),{content:[{type:"text",text:"\u26a0\ufe0f Could not determine current session ID. Unable to list messages without a session context."}]}}}r.debug("Listing messages",{sessionId:o,messageType:s,direction:i,status:l,readStatus:u})
5113
+ if(!o){const e=u.sessionIdentity.getIdentity()
5114
+ if(!e?.sessionId)return r.warn("No session identity for list operation"),{content:[{type:"text",text:"\u26a0\ufe0f Could not determine current session ID. Unable to list messages without a session context."}]}
5115
+ o=e.sessionId,(0,h.logSessionIdentity)("session_message_operations.list","identity",{sessionId:o})}r.debug("Listing messages",{sessionId:o,messageType:s,direction:i,status:l,readStatus:d})
5152
5116
  const y={sessionId:o,direction:i,limit:p,offset:f}
5153
- s&&"all"!==s&&(y.messageType=s),l&&"all"!==l&&("report"===s?y.reportStatus=l:y.status=l),u&&"all"!==u&&(y.readStatus=u),g&&"all"!==g&&(y.reportStatus=g)
5117
+ s&&"all"!==s&&(y.messageType=s),l&&"all"!==l&&("report"===s?y.reportStatus=l:y.status=l),d&&"all"!==d&&(y.readStatus=d),g&&"all"!==g&&(y.reportStatus=g)
5154
5118
  const w=await m.listMessages(y)
5155
5119
  if(0===w.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
5156
5120
  const k=[`Found ${w.length} message(s):\n`]
5157
5121
  for(const e of w)k.push("---\n"),k.push(a(e)),k.push("")
5158
- return{content:[{type:"text",text:k.join("\n")}]}}(e.list||{},t,y,m)
5122
+ return{content:[{type:"text",text:k.join("\n")}]}}(e.list||{},0,m,f)
5159
5123
  case"get":if(!e.messageCode)throw new c.ValidationError("get operation requires messageCode")
5160
5124
  return await async function(e,t,r){const{messageCode:n}=e
5161
5125
  if(!n)throw new c.ValidationError("get operation requires messageCode")
@@ -5163,8 +5127,8 @@ const o=r.getSessionMessageClient()
5163
5127
  if(!o)throw new c.ValidationError("Session message client not available")
5164
5128
  t.debug("Getting message",{messageCode:n})
5165
5129
  const s=await o.getMessage(n)
5166
- return s?{content:[{type:"text",text:a(s)}]}:{content:[{type:"text",text:`\u274c Message with code ${n} not found.`}],isError:!0}}(e,y,m)
5167
- default:throw new c.ValidationError(`Unknown operation: ${w}. Valid operations: send, reply, list, get`)}}catch(e){return y.error("Session message operation failed",{operation:w,error:(0,l.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c Error: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
5130
+ return s?{content:[{type:"text",text:a(s)}]}:{content:[{type:"text",text:`\u274c Message with code ${n} not found.`}],isError:!0}}(e,m,f)
5131
+ default:throw new c.ValidationError(`Unknown operation: ${y}. Valid operations: send, reply, list, get`)}}catch(e){return m.error("Session message operation failed",{operation:y,error:(0,l.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c Error: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
5168
5132
  const c=t(9860),l=t(8824),d=t(7617),u=t(6688),h=t(7280),g=3456},9080(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
5169
5133
  const r=t(6183),n=t(1281)
5170
5134
  exports.def={name:"search",description:"Search for text patterns in files on the currently active branch. Supports regex patterns and sorts results by file modification time (newest first).\n\nFile extensions: 'ts', '.ts', '*.ts' (all valid). Use '*' for any file type.\n\nCONTEXT LINES: Use contextLines option (0-10) to show surrounding lines before and after matches, reducing need for follow-up reads.\n\nLIST-ALL MODE: Omit 'needle' to list all files in a directory with tree structure (like ls/tree). Options: levels (1-4 depth), sortBy (name/modified/size/type).",schema:r.SearchSchema,annotations:{title:"Search Files",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleSearch)(e,t.context,t.apiClient,t.logger,t.metrics)}}},9089(e,exports){function t(e){if(e.toLowerCase().startsWith("specialist:")){const t=e.slice(11).trim()
@@ -5268,10 +5232,10 @@ continue}const t=(0,h.findMatches)(s,n,m,100,e.path)
5268
5232
  if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(m?" (tried fuzzy matching)":""),a.success=!1
5269
5233
  const e=(0,h.findSimilarMatches)(s,n,5,.3)
5270
5234
  e.length>0&&(a.similarMatches=e),y.failedReplacements++}else"unique"===i&&t.length>1?(a.error=`Multiple matches found (${t.length}) - expected unique match`,a.success=!1,a.details=t.map(r),y.failedReplacements++):p.push({matches:t,newText:o,matchMode:i,repResult:a})}catch(e){a.error=(0,k.getErrorMessage)(e),a.success=!1,y.failedReplacements++}y.replacements.push(a)}let w=s
5271
- const I=[]
5272
- for(const e of p)for(const t of e.matches)I.push({match:t,newText:e.newText,repResult:e.repResult})
5273
- I.sort(((e,t)=>t.match.startPos-e.match.startPos))
5274
- for(const{match:e,newText:t,repResult:n}of I)w=(0,h.replaceMatch)(w,e,t),n.success?(n.lines.push(e.line),n.details.push(r(e))):(n.success=!0,n.matchType=e.matchType,n.lines=[e.line],n.details=[r(e)],y.successfulReplacements++)
5235
+ const b=[]
5236
+ for(const e of p)for(const t of e.matches)b.push({match:t,newText:e.newText,repResult:e.repResult})
5237
+ b.sort(((e,t)=>t.match.startPos-e.match.startPos))
5238
+ for(const{match:e,newText:t,repResult:n}of b)w=(0,h.replaceMatch)(w,e,t),n.success?(n.lines.push(e.line),n.details.push(r(e))):(n.success=!0,n.matchType=e.matchType,n.lines=[e.line],n.details=[r(e)],y.successfulReplacements++)
5275
5239
  y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),f&&(n.documentFileManager.markForSync(d),await n.documentFileManager.syncDocument(d))),i&&(y.externalEditWarning=i),a&&(y.externalEditDebugInfo={detectionRan:!0,...a}),y.success=0===y.failedReplacements}catch(e){y.error=(0,k.getErrorMessage)(e),y.success=!1,y.failedReplacements=g.length,y.replacements=g.map((e=>({old:e.old,new:e.new,success:!1,error:y.error})))}return y}var o,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
5276
5240
  var o=Object.getOwnPropertyDescriptor(t,r)
5277
5241
  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]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||(o=function(e){return o=Object.getOwnPropertyNames||function(e){var t=[]
@@ -5280,48 +5244,48 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
5280
5244
  var t={}
5281
5245
  if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
5282
5246
  return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
5283
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFiles=async function(e,t,r,o,s,i,a,c){const I=i.child({tool:"replace_in_files"}),b=Date.now()
5247
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFiles=async function(e,t,r,o,s,i,a,c){const b=i.child({tool:"replace_in_files"}),I=Date.now()
5284
5248
  let v,C=u.FileOperationPhase.VALIDATION
5285
5249
  try{if(e&&"string"==typeof e.operations)try{e.operations=JSON.parse(e.operations)}catch{}if(e&&Array.isArray(e.operations))for(const t of e.operations)t.old&&t.new&&!t.replacements&&(t.replacements=[{old:t.old,new:t.new,match_mode:t.match_mode}],delete t.old,delete t.new,delete t.match_mode)
5286
5250
  const i=u.validateArgs(e,d.ReplaceInFilesSchema),{taskId:_,operations:E,fuzzy_match:q=!0,comment:S}=i
5287
- I.info("Replace in files batch operation",{taskId:_,operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,comment:S})
5251
+ b.info("Replace in files batch operation",{taskId:_,operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,comment:S})
5288
5252
  const T=E.filter((e=>e.documentId)).map((e=>e.documentId))
5289
- if(T.length>0&&t.apiClient)try{await(0,m.ensureDocumentsNotLocked)(T,t.apiClient,I,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5253
+ 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}
5290
5254
  throw e}C=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5291
5255
  const P=E[0],M=P.documentId?"document:"+P.documentId:P.path
5292
- let R=Date.now()
5293
- const j=await u.validateTaskId(_,M,r,I,a,"replace_in_files")
5256
+ let j=Date.now()
5257
+ const R=await u.validateTaskId(_,M,r,b,a,"replace_in_files")
5294
5258
  Date.now()
5295
- const x=j?.requestId,O=E.some((e=>e.path))
5259
+ const x=R?.requestId,O=E.some((e=>e.path))
5296
5260
  let A=!1
5297
- if(O&&x){R=Date.now()
5298
- const e=await u.validateWorkItemStates(_,M,r,s,t,I,a,"replace_in_files")
5299
- Date.now(),R=Date.now()
5300
- const n=await u.autoPromoteTaskStatus(_,j.status,x,e.request?.status,M,r,s,I,a,"replace_in_files")
5301
- n.taskPromoted&&I.info("Auto-promoted task to in_progress",{taskId:_,requestId:x,previousStatus:j.status,newStatus:n.newTaskStatus}),Date.now(),R=Date.now()
5302
- const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:x,context:t,operation:"replace_in_files",logger:I,metrics:a,metricsPrefix:"replace_in_files"})
5261
+ if(O&&x){j=Date.now()
5262
+ const e=await u.validateWorkItemStates(_,M,r,s,t,b,a,"replace_in_files")
5263
+ Date.now(),j=Date.now()
5264
+ const n=await u.autoPromoteTaskStatus(_,R.status,x,e.request?.status,M,r,s,b,a,"replace_in_files")
5265
+ n.taskPromoted&&b.info("Auto-promoted task to in_progress",{taskId:_,requestId:x,previousStatus:R.status,newStatus:n.newTaskStatus}),Date.now(),j=Date.now()
5266
+ const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:x,context:t,operation:"replace_in_files",logger:b,metrics:a,metricsPrefix:"replace_in_files"})
5303
5267
  if(!o.success){if(o.isLockConflict)return{content:[{type:"text",text:"\u274c "+o.error}],isError:!0}
5304
- throw Error(o.error)}Date.now(),A=!0}if(T.length>0&&x)try{await(0,p.validateRequestStatusForDocumentOperation)(x,s,I,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5305
- throw e}R=Date.now()
5268
+ throw Error(o.error)}Date.now(),A=!0}if(T.length>0&&x)try{await(0,p.validateRequestStatusForDocumentOperation)(x,s,b,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5269
+ throw e}j=Date.now()
5306
5270
  const D=new Map
5307
- if(I.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=u.validateAndNormalizePath(e.path,t),n=await l.default.readFile(r.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:q,s=[]
5271
+ 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=u.validateAndNormalizePath(e.path,t),n=await l.default.readFile(r.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:q,s=[]
5308
5272
  for(const t of e.replacements){const r=(0,h.findMatches)(n,t.old,o,100,e.path)
5309
5273
  s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,r.fullPath)
5310
- I.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
5311
- const i=await(0,w.detectExternalEdits)(t.git,o,I)
5312
- I.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}),I.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}),I.info("\u2705 No external edit conflicts detected",{path:r.normalizedPath}))}else I.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){I.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,k.getErrorMessage)(t)})}if(Date.now(),R=Date.now(),O&&t.git)try{I.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
5313
- const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},I,a)
5314
- e.userChangesCommitted&&(I.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),I.info("User changes committed before batch operation",{taskId:_,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){I.warn("Pre-tool user changes commit failed",{taskId:_,error:e instanceof Error?e.message:e+""})}Date.now(),R=Date.now(),C=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5315
- const{toolRecordId:$}=await u.createFileOperationRecords(_,x,t.projectId,"replace-in-files",M,{operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,userComment:S},r,o,I,a,"replace_in_files",c)
5316
- v=$,Date.now(),R=Date.now(),C=u.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5274
+ b.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
5275
+ const i=await(0,w.detectExternalEdits)(t.git,o,b)
5276
+ 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(),j=Date.now(),O&&t.git)try{b.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
5277
+ const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},b,a)
5278
+ 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(),j=Date.now(),C=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5279
+ const{toolRecordId:$}=await u.createFileOperationRecords(_,x,t.projectId,"replace-in-files",M,{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)
5280
+ v=$,Date.now(),j=Date.now(),C=u.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5317
5281
  const F=[],N=[]
5318
5282
  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)
5319
- F.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&N.push(o.path)}Date.now(),R=Date.now()
5320
- const L=E.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),z=await u.handleMultiFileGitCommit(_,L,F,N.length,{operationType:"Replace in files",toolRecordId:$||v||"unknown",successField:"successfulReplacements",logger:I,metrics:a,metricsPrefix:"replace_in_files"},t),B=z.commitHash
5283
+ F.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&N.push(o.path)}Date.now(),j=Date.now()
5284
+ const L=E.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),z=await u.handleMultiFileGitCommit(_,L,F,N.length,{operationType:"Replace in files",toolRecordId:$||v||"unknown",successField:"successfulReplacements",logger:b,metrics:a,metricsPrefix:"replace_in_files"},t),B=z.commitHash
5321
5285
  Date.now(),Date.now()
5322
- const H=F.filter((e=>e.success)).length,W=F.length-H,U=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}))),Y=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})))
5323
- await o.updateToolRecord(v,{metadata:{path:M,status:0===W?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:Y,successfulReplacements:U,failedReplacements:G,processingTime:Date.now()-b,userComment:S,...z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}}})
5324
- const K=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
5286
+ const H=F.filter((e=>e.success)).length,W=F.length-H,U=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})))
5287
+ await o.updateToolRecord(v,{metadata:{path:M,status:0===W?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:K,successfulReplacements:U,failedReplacements:G,processingTime:Date.now()-I,userComment:S,...z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}}})
5288
+ 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
5325
5289
  let l="## Replace In Files - Batch Results\n\n"
5326
5290
  if(o.getCurrentBranchContext)try{const e=await o.getCurrentBranchContext()
5327
5291
  e.branch&&(l+=`**Current Branch:** ${e.branch}\n\n`)}catch(e){}l+="**Summary:**\n",l+=`- **Files/Documents:** ${e.length} total`,l+=c>0?` (\u2705 ${i} fully succeeded, \u26a0\ufe0f ${c} partial, \u274c ${a-c} failed)\n`:` (\u2705 ${i} successful, \u274c ${a} failed)\n`,l+=`- **Replacements:** ${r+n} total (\u2705 ${r} successful, \u274c ${n} failed)\n`,t&&(l+=`- **Git Commit:** ${t.substring(0,8)}\n`),s&&(l+=`[RECORD:${s}]\n`),l+="\n---\n\n"
@@ -5333,8 +5297,8 @@ for(const e of o)l+=`- \u2705 \`${e.old.substring(0,40)}${e.old.length>40?"...":
5333
5297
  if(s.length>0){l+="\n**Failed Replacement Details:**\n"
5334
5298
  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 d=e.filter((e=>"document"===e.type&&(e.success||e.successfulReplacements>0)))
5335
5299
  return d.length>0&&(l+=`\n**Document Changes:** ${d.length} modified document(s) synced back to tracking system.\n`),o.workspaceManager?.largeFileWarning&&(l+=o.workspaceManager.largeFileWarning,o.workspaceManager.largeFileWarning=""),l}(F,B,U,G,t,v)
5336
- return{content:[{type:"text",text:K}],isError:0===U}}catch(e){const t=Date.now()-b
5337
- if(I.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}}}
5300
+ return{content:[{type:"text",text:Y}],isError:0===U}}catch(e){const t=Date.now()-I
5301
+ 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}}}
5338
5302
  const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(6183)),u=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){Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
5339
5303
  const t=e.trim()
5340
5304
  if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
@@ -5390,14 +5354,14 @@ if(n)s.WorkspaceLogging.logOperation(this.logger,"info","Branch already exists,
5390
5354
  else{const t=await this.git.revparse(["--abbrev-ref","HEAD"]),r=await this.gitAdapter.branchManager.getBaseBranch()
5391
5355
  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
5392
5356
  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
5393
- 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){const t=Date.now(),r=s.WorkspaceValidation.validateRequestId(e)
5394
- if(!r.isValid)throw Error("Invalid request ID: "+r.errors.join(", "))
5395
- const n=r.sanitized,i="requests/"+n,a=await this.git.revparse(["--abbrev-ref","HEAD"])
5396
- if(a===i)return this.currentRequestId=n,this.currentBranch=i,void this.logger.debug("Workspace already ready",{requestId:n,currentBranch:this.currentBranch})
5397
- try{if(s.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by switching to branch",e,"single-agent","ensureWorkspaceReady",{currentBranch:a,targetBranch:i,architecture:"hybrid-creation"}),!(await this.git.branch()).all.includes(i))throw Error(`Branch ${i} does not exist. Was initializeRequest() called?`)
5398
- try{await this.switchToRequest(n)}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:i}),await this.git.checkout(i),this.currentRequestId=n,this.currentBranch=i,s.WorkspaceLogging.logOperation(this.logger,"info","Direct checkout succeeded",e,"single-agent","ensureWorkspaceReady",{branchName:i})}const r=Date.now()-t
5399
- this.metrics.recordValue("workspace.ensure_ready",r),s.WorkspaceLogging.logOperation(this.logger,"info","Workspace is ready",e,"single-agent","ensureWorkspaceReady",{branchName:this.currentBranch,duration:r,architecture:"hybrid-creation"})}catch(r){const n=Date.now()-t
5400
- 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)(r),duration:n}),r}}async switchToRequest(e,t){const r=Date.now(),n=this.getCurrentContext(),i=s.WorkspaceValidation.validateRequestId(e)
5357
+ 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)
5358
+ if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
5359
+ const i=n.sanitized,a="requests/"+i,c=await this.git.revparse(["--abbrev-ref","HEAD"])
5360
+ if(c===a)return this.currentRequestId=i,this.currentBranch=a,void this.logger.debug("Workspace already ready",{requestId:i,currentBranch:this.currentBranch})
5361
+ 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?`)
5362
+ 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
5363
+ 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
5364
+ 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)
5401
5365
  if(!i.isValid){const t="Invalid request ID: "+i.errors.join(", ")
5402
5366
  throw s.WorkspaceLogging.logOperation(this.logger,"error",t,e,"single-agent","switchToRequest"),Error(t)}const a=i.sanitized
5403
5367
  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"})
@@ -5407,13 +5371,13 @@ const o=Date.now()-r
5407
5371
  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
5408
5372
  this.metrics.recordValue("workspace.switch",n)
5409
5373
  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}`
5410
- 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(){const e=Date.now(),t=this.getCurrentContext()
5411
- try{const r=await this.gitAdapter.branchManager.getBaseBranch(),n=await this.gitAdapter.branchManager.switchToBranch(r)
5374
+ 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()
5375
+ try{const e=await this.gitAdapter.branchManager.getBaseBranch(),n=await this.gitAdapter.branchManager.switchToBranch(e)
5412
5376
  if(!n.success)throw Error("Failed to switch to main branch: "+n.error)
5413
- this.currentBranch=r,this.currentRequestId=null
5414
- const o=Date.now()-e
5415
- return this.metrics.recordValue("workspace.switch_main",o),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully switched to main branch",null,"single-agent","switchToMain",{mainBranch:r,previousBranch:t.branchName,duration:o,architecture:"aligned-with-multi-agent"}),{success:!0,message:"Switched to "+r,previousContext:t,newContext:this.getCurrentContext()}}catch(t){const r=Date.now()-e
5416
- 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)(t),duration:r}),new s.ConflictDetectionError("Failed to switch to main: "+(0,o.getErrorMessage)(t),"single-agent",[])}}async commitChanges(e,t){const r=Date.now()
5377
+ this.currentBranch=e,this.currentRequestId=null
5378
+ const o=Date.now()-t
5379
+ 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
5380
+ 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()
5417
5381
  try{t&&t.length>0?await this.git.add(t):await this.git.add("."),await this.git.commit(e)
5418
5382
  const n=await this.git.revparse(["HEAD"]),o=Date.now()-r
5419
5383
  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
@@ -5421,33 +5385,32 @@ throw this.metrics.recordValue("workspace.commit",n),this.logger.error("Failed t
5421
5385
  try{s.WorkspaceLogging.logOperation(this.logger,"info","Starting request completion (refactored)",e,"single-agent","completeRequest",{requestTitle:t,skipConflictDetection:r?.skipConflictDetection||!1,architecture:"shared-processor"})
5422
5386
  const o=await this.requestProcessor.completeRequest(e,t,{skipConflictDetection:r?.skipConflictDetection||!1}),i=Date.now()-n
5423
5387
  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
5424
- 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){return n.default.resolve(this.basePath,e)}async createCommit(e,t){return await this.commitChanges(e,t)}async cancelRequest(e){const t=s.WorkspaceValidation.validateRequestId(e)
5388
+ 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)
5425
5389
  if(!t.isValid)throw Error("Invalid request ID: "+t.errors.join(", "))
5426
5390
  const r="requests/"+t.sanitized
5427
- 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(){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)
5391
+ 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)
5428
5392
  if(!t.isValid)return null
5429
5393
  const r=t.sanitized,n="requests/"+r,o=await this.git.branch()
5430
- 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(){return this.git}async ensureReadonlyBranchIfNeeded(e,r,n,s){if(!this.readonlyBranchCheckDone){this.readonlyBranchCheckDone=!0
5431
- try{let o=s
5432
- if(!o){const{discoverCallingSession:n}=await Promise.resolve().then(t.bind(t,7617)),s=await n(e,r,this.logger)
5433
- o=s?.sessionId}if(!o)return void this.logger.debug("Could not discover calling session for readonly check")
5434
- this.logger.debug("Discovered calling session for readonly check",{sessionId:o,toolName:r})
5435
- const i=n?.getCLISessionClient?.()
5436
- if(!i)return void this.logger.debug("No CLI session client available for readonly check")
5437
- const a=await i.getByExternalId(o)
5438
- if(!a?.agentType)return void this.logger.debug("No agent type found for session",{sessionId:o})
5439
- this.logger.debug("Found session agent type",{sessionId:o,agentType:a.agentType})
5440
- const c=await this.fetchAgentConfig(a.agentType)
5441
- if(!c||"readonly"!==c.requestContextMode)return void this.logger.debug("Agent does not have readonly requestContextMode",{agentType:a.agentType})
5442
- this.logger.debug("Agent has readonly requestContextMode",{agentType:a.agentType})
5443
- const l=n?.getSessionRequestAssociationClient?.()
5444
- if(!l)return void this.logger.debug("No session association client available")
5445
- const d=await l.getActiveRequestsForSession(o,!0)
5446
- if(0===d.length)return void this.logger.debug("No active request association found for session",{sessionId:o})
5447
- const u=d[0].requestLocalId,h="requests/"+u
5448
- this.logger.info("Readonly agent with request association, switching to branch without locking",{sessionId:o,agentType:a.agentType,requestId:u,readonlyBranch:h})
5449
- const g=await this.git.branch()
5450
- g.all.includes(h)||g.all.includes("remotes/origin/"+h)?(await this.git.checkout(h),this.currentBranch=h,this.currentRequestId=u,this.logger.info("Successfully switched to readonly branch",{currentBranch:this.currentBranch,currentRequestId:this.currentRequestId})):this.logger.warn("Readonly branch does not exist",{readonlyBranch:h})}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)
5394
+ 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
5395
+ try{const e=n
5396
+ if(!e)return void this.logger.debug("No sessionId available for readonly check")
5397
+ this.logger.debug("Checking readonly branch for session",{sessionId:e,toolName:t})
5398
+ const o=r?.getCLISessionClient?.()
5399
+ if(!o)return void this.logger.debug("No CLI session client available for readonly check")
5400
+ const s=await o.getByExternalId(e)
5401
+ if(!s?.agentType)return void this.logger.debug("No agent type found for session",{sessionId:e})
5402
+ this.logger.debug("Found session agent type",{sessionId:e,agentType:s.agentType})
5403
+ const i=await this.fetchAgentConfig(s.agentType)
5404
+ if(!i||"readonly"!==i.requestContextMode)return void this.logger.debug("Agent does not have readonly requestContextMode",{agentType:s.agentType})
5405
+ this.logger.debug("Agent has readonly requestContextMode",{agentType:s.agentType})
5406
+ const a=r?.getSessionRequestAssociationClient?.()
5407
+ if(!a)return void this.logger.debug("No session association client available")
5408
+ const c=await a.getActiveRequestsForSession(e,!0)
5409
+ if(0===c.length)return void this.logger.debug("No active request association found for session",{sessionId:e})
5410
+ const l=c[0].requestLocalId,d="requests/"+l
5411
+ this.logger.info("Readonly agent with request association, switching to branch without locking",{sessionId:e,agentType:s.agentType,requestId:l,readonlyBranch:d})
5412
+ const u=await this.git.branch()
5413
+ u.all.includes(d)||u.all.includes("remotes/origin/"+d)?(await this.git.checkout(d),this.currentBranch=d,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:d})}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)
5451
5414
  if(!r.ok)return null
5452
5415
  const n=await r.json()
5453
5416
  return n.success?n.data??null:null}catch{return null}}async cleanup(){this.logger.info("Cleaning up single-agent workspace manager")}}},9671(e,exports){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])