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.
package/dist/index.js CHANGED
@@ -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,b=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),I=w.title||f.title,k=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,b=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),k=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:b,requestId:C,title:I})
25
+ w&&"object"==typeof w&&"_workingEndpoint"in w&&(E=w._workingEndpoint),u.info("Successfully extracted task data from response",{taskId:b,requestId:C,title:k})
26
26
  try{const e=i.getToolRecordClient()
27
- if(e){const t=await e.createToolRecord({taskId:b,requestId:C,projectId:l,type:"create-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:I,taskDescription:k,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:b,requestId:C})}h({success:!0,requestId:a.requestId,projectId:l}),u.info("Task created successfully",{taskId:b,requestId:C,title:I,projectId:l})
29
- let q=`Created Task ${b}: ${I}`
27
+ if(e){const t=await e.createToolRecord({taskId:b,requestId:C,projectId:l,type:"create-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:k,taskDescription:I,taskStatus:v},note:"Created task "+k})
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:b,requestId:C})}h({success:!0,requestId:a.requestId,projectId:l}),u.info("Task created successfully",{taskId:b,requestId:C,title:k,projectId:l})
29
+ let q=`Created Task ${b}: ${k}`
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,9 +44,9 @@ 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),b=i(t(7478)),I=t(4139),k=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),R=t(9060),M=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
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),b=i(t(7478)),k=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),R=t(9060),M=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
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 D{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 R.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.interceptConnectMethod(),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
49
+ class D{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,k.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new f.ProjectContext(e,t),this.tokenManager=new m.TokenManager(t,e,{remoteServerUrl:n}),this.lockOverrideManager=new P.LockOverrideManager(t),this.configManager=new R.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.interceptConnectMethod(),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
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()
@@ -56,7 +56,7 @@ const n=await r.getNextId(e)
56
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,M.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(k.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 b.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=k.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(k.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,M.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 ${k.ALCHEMY_DIR_NAME}/ to existing .gitignore`)}}else{const r=["# Dependency directories\nnode_modules/\n.npm\n.yarn\n\n# Build outputs\ndist/\nbuild/\n\n# Logs\nlogs/\n*.log\n\n# Editor files\n.DS_Store\n.vscode/\n.idea/\n\n# Environment variables\n.env\n.env.local\n\n# AlchemyMCP working directory",t,""].join("\n")
75
+ await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${k.ALCHEMY_DIR_NAME}/ entry`)}}catch(e){this.logger.warn("Failed to update .gitignore file",{error:(0,M.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(".")
@@ -195,13 +195,13 @@ const w=[],b=a.toLowerCase()
195
195
  for(const e of y){const t=[]
196
196
  if("all"!==l&&"title"!==l||!e.title||e.title.toLowerCase().includes(b)&&t.push({request:e,matchType:"title",matchSnippet:r(e.title,a)}),"all"!==l&&"description"!==l||!e.description||e.description.toLowerCase().includes(b)&&t.push({request:e,matchType:"description",matchSnippet:n(e.description,b,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(b)){t.push({request:e,matchType:"criteria",matchSnippet:n(o,b,150)})
198
- break}}t.length>0&&w.push(t[0])}const I=g.limit||20,k=w.slice(0,I)
199
- if(0===k.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 ${k.length} request${1===k.length?"":"s"} matching "${a}":\n\n`
201
- for(const e of k){const t=e.request,r=o(t.status)
198
+ break}}t.length>0&&w.push(t[0])}const k=g.limit||20,I=w.slice(0,k)
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:k.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 b=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
- b=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(b)try{(await b.status()).isClean()||(I=(await b.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 k=null
261
+ b=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 k=null
262
+ if(b)try{(await b.status()).isClean()||(k=(await b.commit(`Complete task ${o}: ${h}`)).commit,p.info("Created commit for task completion",{taskId:o,commitId:k}))}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&&(k={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:k?.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:k?.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:k,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:k,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(k?.id&&(a+=`\n[RECORD:${k.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}]`),k&&(a+="\nCommit: "+k.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)})
@@ -462,7 +461,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerApiRoutes
462
461
  n.debug("Token retrieved from authentication manager")
463
462
  const j=new b.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,M)
464
463
  R.registerClient(x)
465
- const O=new k.TaskClient(T,n.child({component:"task-client"}),o,x,j,M)
464
+ const O=new I.TaskClient(T,n.child({component:"task-client"}),o,x,j,M)
466
465
  R.registerClient(O)
467
466
  const D=new v.FileOperationsClient(T,n.child({component:"file-client"}),o,x,M,j)
468
467
  R.registerClient(D)
@@ -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,k.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",U,(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,k.getErrorMessage)(e)})}})),e.get("/api/files/exists",U,(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,k.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/*",W,(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/*",W,(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),b=t(5681),I=t(8824),k=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),b=t(5681),k=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)}}},1266(e,exports){Object.defineProperty(exports,"__esModule",{value:!0})},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>=k||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:k,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(k.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>=k)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>=k)return{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}
628
- o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=k)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<k;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 k={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 k=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 k.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(k.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
- k.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,b.getErrorMessage)(e)}`
677
- throw k.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 R=void 0!==v.contextLines?v.contextLines:0
679
- if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!_&&!T)throw k.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")')
678
+ if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!_&&!T)throw I.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,f.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
680
679
  let M,j=""
681
680
  if(_)j="*"
682
681
  else if("*"===T)j="*"
683
682
  else if(T){let e=T;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),j=e.startsWith(".")?e:"."+e}try{M=S?q?RegExp(n):RegExp(n,"i"):q?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${S?"regex":"search"} pattern: ${(0,b.getErrorMessage)(e)}`
684
- throw k.errors.push(t),(0,f.createValidationError)(t)}if(k.patternInfo={needle:n,regex:M.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:j},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
683
+ throw I.errors.push(t),(0,f.createValidationError)(t)}if(I.patternInfo={needle:n,regex:M.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:j},!_)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
- k.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},k.phases.directoryListingTime=k.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,b.getErrorMessage)(e)
687
- k.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(),k.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,b.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:j,searchIn:P}}),k=Date.now(),I.phases.initializationTime=k-u
689
688
  const O=Date.now()
690
689
  let D=[],A=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,b.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,M,{maxResults:E,fileExtension:j,searchIn:P,isFile:_,contextLines:R},j,l,k)
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,M,{maxResults:E,fileExtension:j,searchIn:P,isFile:_,contextLines:R},j,l,I)
707
706
  D=e.matches,A=e.totalFiles
708
707
  const t=1e3
709
708
  D.length>0&&D.length<=t?(D.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 ${D.length} matches by modification time (newest first)`)):D.length>t&&l.info(`Skipped sorting ${D.length} matches (exceeds hard cap of ${t} for performance)`),$=D.length,D.length>E&&(D=D.slice(0,E),l.info(`Limited results to ${E} (from ${$} total matches)`)),D.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 ${$||D.length} total matches in ${A} files, returning ${D.length} results`),k.phases.searchTime=Date.now()-O}catch(e){const t="Error during search: "+(0,b.getErrorMessage)(e)
711
- k.errors.push(t),l.error(t),k.phases.searchTime=Date.now()-O}k.totalFiles=A,k.totalMatches=D.length,k.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 ${$||D.length} total matches in ${A} files, returning ${D.length} results`),I.phases.searchTime=Date.now()-O}catch(e){const t="Error during search: "+(0,b.getErrorMessage)(e)
710
+ I.errors.push(t),l.error(t),I.phases.searchTime=Date.now()-O}I.totalFiles=A,I.totalMatches=D.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:k})
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($>D.length?(F=`Found ${$} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=`${N}. Showing first ${D.length}:\n\n`):(F=`Found ${D.length} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=N+":\n\n"),D.length>0)if(R>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
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")}(D)
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+""}),k.errors.push((0,b.getErrorMessage)(t)),k.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:k})
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,b.getErrorMessage)(t)),I.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:I})
738
737
  let r="Search failed: "+(0,b.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),b=t(8824),I=["node_modules"],k=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),b=t(8824),k=["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=b(),k=[]
817
- I.then((e=>{k=e})).catch((e=>{m.error("Error generating initial tools list",{error:(0,l.getErrorMessage)(e)}),k=[]})),e.setRequestHandler(a.ListToolsRequestSchema,(async()=>{try{return k=await b(),{tools:k}}catch(e){return m.error("Error generating tools list",{error:(0,l.getErrorMessage)(e)}),{tools:[]}}}))
815
+ let k=b(),I=[]
816
+ k.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 b(),{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 b=s.startTimer("tool_execution_time")
821
820
  Date.now()
822
- let I=Date.now()
823
- const k=r(a)
824
- if(Date.now(),I=Date.now(),y){const e=await w()
821
+ let k=Date.now()
822
+ const I=r(a)
823
+ if(Date.now(),k=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(k=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(),k=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){k=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(k,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(),b({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(),b({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:${R}/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:${M}/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,k.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:${R}/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,k.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:${M}/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,k.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:${R}/api/project-settings`)
1210
+ try{const t=await fetch(`http://localhost:${M}/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 M=w.id
1227
- r(t,"Pre-created session with parentID",{preCreatedSessionId:M,parentSessionId:i}),o.info("Pre-created session with parentID",{preCreatedSessionId:M,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,k.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:M,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:M,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 j
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:${R}/api/agents/by-name/${a}`})
1231
+ try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${M}/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,R.resolveAgentModel)(p,n,o)
1236
+ r(t,"Model resolution result",{agent:a,result:s}),s.resolved?(j=s.fullModel,r(t,"Resolved agent model",{agent:a,model:j,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:${R}/api/project-settings`,t=await fetch(e)
1239
+ const s=(0,R.resolveAgentModel)(p,n,o)
1240
+ r(t,"Built-in model resolution result",{agent:a,result:s}),s.resolved&&(j=s.fullModel,r(t,"Resolved built-in agent model",{agent:a,model:j,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:${M}/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,b.spawnDetachedSubagent)({agent:a,prompt:q,cwd:p,sessionId:M,model:x,initialBranch:C,allowParallel:d,serverUrl:g})
1251
- if(!O.success)throw Error("Failed to spawn subagent: "+O.error)
1252
- _=M,r(t,"CLI spawn successful with pre-created session",{sessionId:M,pid:O.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:M,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 M=y
1255
- return u?M+=`Prompt sent to existing session ${_}.`:(M+=`Background ${a} subagent spawned successfully.`,_&&"unknown"!==_&&"spawning"!==_&&(M+=`\n[SESSION:${_}]`)),l&&(M+="\nWorking on: "+l),M+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:M}]}}async function s(e,t,r,n,o,s,i){const a=await(0,I.getServerUrl)(r,n)
1243
+ if(e)if(j){const o=await n(a)
1244
+ "same"===(o?.preferredModelTier||"same")&&(j=e,r(t,"Applied user default model (same tier)",{agent:a,userDefaultModel:e}))}else j=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:j||"undefined (will use default)"}),await T,l&&y)try{await(0,k.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,b.spawnDetachedSubagent)({agent:a,prompt:E,cwd:p,sessionId:I,model:j,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,k.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:${R}/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:${M}/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:${R}/api/project-settings`)
1259
+ try{const e=await fetch(`http://localhost:${M}/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&&M>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&&j>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,b=y.status,I=y.isReady,k=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,b=y.status,k=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: ${b} (${y.detail})\nReady for input: ${I?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${k.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: ${b} (${y.detail})\nReady for input: ${k?"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 b={}
1326
1320
  if(r)try{const e=r.getCLISessionClient()
1327
- e&&(b=await e.batchEnrich(w.map((e=>e.id))))}catch{}const I=g.replace(/\/$/,""),k=await Promise.allSettled(w.map((e=>fetch(`${I}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),v=[]
1321
+ e&&(b=await e.batchEnrich(w.map((e=>e.id))))}catch{}const k=g.replace(/\/$/,""),I=await Promise.allSettled(w.map((e=>fetch(`${k}/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=k[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=b[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 k=[]
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
+ k.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&&!k.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:k,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,k.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),b=t(8035),I=t(7617),k=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),R=3456,M=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),b=t(8035),k=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),R=t(5671),M=3456,j=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,b,I=d.FileOperationPhase.VALIDATION
1677
- const k={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,b,k=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,k.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,k.metricsPrefix),q=E?.requestId,S=await d.validateWorkItemStates(u,_[0].source,r,o,t,m,i,k.metricsPrefix),T=await d.autoPromoteTaskStatus(u,E.status,q,S.request?.status,_[0].source,r,o,m,i,k.metricsPrefix)
1679
+ _.push({source:r,destination:o,fullSource:n,fullDestination:s})}k=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("move_files_phase",1,{phase:k})
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:k.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 R={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}),R={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){m.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),m.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId: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:M,localToolRecordId:j}=await d.createFileOperationRecords(u,q,t.projectId,k.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},r,n,m,i,k.metricsPrefix,f)
1695
- w=M,b=M,I=k.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}),R={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){m.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),m.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:u,moveOperationsCount:_.length,error:e instanceof Error?e.message:e+""})}m.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:_.length}),k=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("move_files_phase",1,{phase:k})
1688
+ const{toolRecordId:M,localToolRecordId:j}=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:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},r,n,m,i,I.metricsPrefix,f)
1689
+ w=M,b=M,k=I.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:k})
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 D=Date.now()-y
1703
1697
  i.recordValue("move_files_time",D),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 A=null
1705
- if(O>0){I=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:I})
1699
+ if(O>0){k=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:k})
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
- A=await d.commitToGit(u,_[0].destination,M,j,r,t,m,i,k.metricsPrefix)}I=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:I})
1701
+ A=await d.commitToGit(u,_[0].destination,M,j,r,t,m,i,I.metricsPrefix)}k=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:k})
1708
1702
  const $=x.filter((e=>e.success)),F=x.filter((e=>!e.success))
1709
- await d.updateFileOperationRecords(u,w,b,_[0].source,k.recordType,O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,{status:O===h.length?"completed":"partial_success",commitHash:A?.commitHash,previousCommitHash:A?.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:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,r,n,m,i,k.metricsPrefix)
1703
+ await d.updateFileOperationRecords(u,w,b,_[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:A?.commitHash,previousCommitHash:A?.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:R.hadUserMods,userModsCommitHash:R.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 A?.commitHash&&(L+="\nCommit: "+A.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||b)&&e.taskId){I=d.FileOperationPhase.RECORD_UPDATE_FAILURE
1718
- try{await d.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",k.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,k.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,k)}}
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:k,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||b)&&e.taskId){k=d.FileOperationPhase.RECORD_UPDATE_FAILURE
1712
+ try{await d.updateFileOperationRecords(e.taskId,w,b,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,k,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),b=t(9373),I=t(6111),k=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),R=t(8850),M=t(3556),j=t(1391),x=t(6315),O=t(7713),D=t(6252),A=t(213),$=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),U=t(5247),W=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(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)(b.def),(0,r.registerTool)(I.def),(0,r.registerTool)(k.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)(R.def),(0,r.registerTool)(M.def),(0,r.registerTool)(j.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.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)(U.testingDefs),(0,r.registerTools)(W.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),b=t(9373),k=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),R=t(8850),M=t(3556),j=t(1391),x=t(6315),O=t(7713),D=t(6252),A=t(213),$=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),U=t(5247),W=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(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)(b.def),(0,r.registerTool)(k.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)(R.def),(0,r.registerTool)(M.def),(0,r.registerTool)(j.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.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)(U.testingDefs),(0,r.registerTools)(W.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,k.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}=k.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}=k.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 b={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}=k.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}=k.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,b.ListDirectorySchema),{path:f,levels:m=1,sortBy:k="name"}=p
1783
+ let g=k.FileOperationPhase.VALIDATION
1784
+ k.FileOperationPhase.FILE_WRITE
1785
+ try{const p=k.validateArgs(e,b.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:_}=k.validateAndNormalizePath(f,t)
1788
+ g=k.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: ${k})`)
1790
- const e=await o(C,t,0,m,k,i)
1791
- if(e.length>0){const t=s(e,k)
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}=k.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,k),a=s.map((e=>n({name:e.name,isDirectory(){return e.isDirectory},isFile(){return!e.isDirectory}},k,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)),b=t(6183),I=f(t(5967)),k=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)),b=t(6183),k=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,b=f.length
1980
- let I="## Read Files/Documents\n\n"
1981
- m&&(I+=m),I+=`**Total Requests:** ${b} - **Successful:** ${y} - **Failed:** ${w}\n\n`
1982
+ let k="## Read Files/Documents\n\n"
1983
+ m&&(k+=m),k+=`**Total Requests:** ${b} - **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 k=0===w
1984
- return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:b,successfulReads:y,failedReads:w,success:k}),s.incrementCounter("read_files_total",1,{success:k}),{content:[{type:"text",text:I}],isError:!k}}catch(e){const t=Date.now()-a
1985
+ "file"===t.type?k+=`File ${e+1}: ${t.path}\n`:(k+=`Document ${e+1}: ${t.documentId}`,t.filename&&(k+=` (${t.filename})`),k+="\n"),t.success?(k+="**Status:** Success\n",t.lineCount&&t.totalLines&&(k+=`Lines Read / Total Lines ${t.lineCount} / ${t.totalLines}\n`),t.originalRequest?.lines&&t.totalLines&&(k+=`**Lines:** ${t.originalRequest.lines}\n`),k+=`\n**Content:**\n\`\`\`\n${t.content}\n\`\`\`\n`):(k+="**Status:** Failed\n",k+=`**Error:** ${t.error}\n`),k+="\n"}const I=0===w
1986
+ return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:b,successfulReads:y,failedReads:w,success:I}),s.incrementCounter("read_files_total",1,{success:I}),{content:[{type:"text",text:k}],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+""}),[])))]),b=(0,s.extractDataFromResponse)(m,{logger:d,operationName:"getRequest",throwOnNoData:!0}),I="data"in b?b.data:b,k={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+""}),[])))]),b=(0,s.extractDataFromResponse)(m,{logger:d,operationName:"getRequest",throwOnNoData:!0}),k="data"in b?b.data:b,I={id:k.id||c,title:k.title||"Unknown Request",description:k.description||"No description available",status:k.status||"unknown",type:k.type||"unknown",acceptanceCriteria:k.acceptanceCriteria||[],createdAt:k.createdAt||(new Date).toISOString(),updatedAt:k.updatedAt||(new Date).toISOString(),completedAt:k.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:k,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:** ${k.title} (${c})\n**Status:** ${k.status}\n**Type:** ${k.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)
@@ -2219,7 +2221,7 @@ var t={}
2219
2221
  if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
2220
2222
  return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
2221
2223
  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()
2222
- let b,I,k=u.FileOperationPhase.VALIDATION
2224
+ let b,k,I=u.FileOperationPhase.VALIDATION
2223
2225
  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"}
2224
2226
  try{const i=u.validateArgs(e,d.ReplaceStringsSchema),{taskId:C,operations:_,comment:E}=i
2225
2227
  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")
@@ -2232,7 +2234,7 @@ if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not ava
2232
2234
  for(const e of S)P.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
2233
2235
  if(P.length>0&&t.apiClient){const e=P.map((e=>e.documentId))
2234
2236
  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}
2235
- throw e}}k=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_strings_phase",1,{phase:k})
2237
+ throw e}}I=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_strings_phase",1,{phase:I})
2236
2238
  const R=T.length>0?T[0].path:"document-operation",M=await u.validateTaskId(C,R,r,y,a,v.metricsPrefix),j=M?.requestId
2237
2239
  let x=null
2238
2240
  T.length>0&&j&&(x=await u.validateWorkItemStates(C,T[0].path,r,s,t,y,a,v.metricsPrefix))
@@ -2243,9 +2245,9 @@ if(!D.success){if(D.isLockConflict)return{content:[{type:"text",text:"\u274c "+D
2243
2245
  throw Error(D.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
2244
2246
  for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
2245
2247
  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}
2246
- throw e}k=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:k})
2248
+ throw e}I=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:I})
2247
2249
  const A=[...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,R,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:A,userComment:E},r,o,y,a,v.metricsPrefix,c)
2248
- if(b=$,I=$,k=v.fileOperationPhase,a.incrementCounter("replace_strings_phase",1,{phase:k}),T.length>0&&t.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
2250
+ if(b=$,k=$,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")
2249
2251
  const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:j,taskId:C,workspaceManager:t.workspaceManager},y,a)
2250
2252
  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})
2251
2253
  const F=[]
@@ -2258,8 +2260,8 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
2258
2260
  r.filename=s?.filename
2259
2261
  const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
2260
2262
  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))
2261
- 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:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J}=B
2262
- 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:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:A,totalSuccessfulReplacements:W,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:E,...T.length>0&&z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}},note:G?`String replacement completed: ${H}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`String replacement partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}u.formatMultiFileToolResponse("String Replacement",{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J},z,D)
2263
+ 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:k,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),B=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J}=B
2264
+ try{await o.updateToolRecord(k,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:G?"completed":"failed",error:G?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:A,totalSuccessfulReplacements:W,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:E,...T.length>0&&z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}},note:G?`String replacement completed: ${H}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`String replacement partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}u.formatMultiFileToolResponse("String Replacement",{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J},z,D)
2263
2265
  let K="## String Replacement Results\n\n"
2264
2266
  if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${H+U}\n`,K+=`- **Successful operations:** ${H}\n`,K+=`- **Failed operations:** ${U}\n`,K+=`- **Total replacements:** ${W} successful, ${N} failed\n\n`,z.success&&z.commitHash&&(K+="**Git Commit:**\n",K+=`- **Commit Hash:** ${z.commitHash.substring(0,8)}\n`,K+=`- **Files Committed:** ${z.filesCommitted.length}\n`,z.previousCommitHash&&(K+=`- **Previous Commit:** ${z.previousCommitHash.substring(0,8)}\n`),K+="\n"),D.lockAcquired&&D.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${D.lockedRequestId}\n\n`),1===F.length){const e=F[0]
2265
2267
  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"
@@ -2268,7 +2270,7 @@ for(const e of F){if("file"===e.type?K+=`### File: ${e.path}\n`:(K+="### Documen
2268
2270
  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")
2269
2271
  const Y=Date.now()-w
2270
2272
  return y.info("Replace strings operation completed",{duration:Y,success:G,totalOperations:F.length,successfulOperations:H,failedOperations:U}),a.incrementCounter("replace_strings_total",1,{success:G}),{content:[{type:"text",text:K}],isError:!G}}catch(t){const r=Date.now()-w
2271
- if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_strings_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
2273
+ if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:I}),k)try{await o.updateToolRecord(k,{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}}}
2272
2274
  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)
2273
2275
  var o=Object.getOwnPropertyDescriptor(t,r)
2274
2276
  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=[]
@@ -2354,14 +2356,14 @@ Object.defineProperty(exports,"LogLevel",{enumerable:!0,get(){return s.LogLevel}
2354
2356
  const r=t(6183),n=t(8317)
2355
2357
  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}}
2356
2358
  Object.defineProperty(exports,"__esModule",{value:!0})
2357
- 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),b=t(8824),I=t(6975),k=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})
2359
+ 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),b=t(8824),k=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})
2358
2360
  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")
2359
2361
  q.info("Using remote server URL",{remoteServerUrl:T}),async function(){try{q.info("Finding available port...",{preferredPort:E,baseDir:_,remoteServerUrl:T})
2360
2362
  const e=await(0,y.findAvailablePort)(E)
2361
2363
  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})
2362
2364
  const t=new l.ProjectRegistry(q),r=new h.DefaultProjectFileSystem(q),c=n.default.join(_,m.ALCHEMY_DIR_NAME)
2363
2365
  q.info(`Checking ${m.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensureDirectoryExists(c)
2364
- const g=new k.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),R=await P.getOrCreateProject(_,{name:n.default.basename(_)||"Local Project",description:"Project for "+n.default.basename(_),status:"active",metadata:{basePath:_,alchemyPath:c,bootstrapped:!0}})
2366
+ 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 k.ProjectClientAdapter(v,q),P=new u.ProjectSynchronizer(q,t,C,r),R=await P.getOrCreateProject(_,{name:n.default.basename(_)||"Local Project",description:"Project for "+n.default.basename(_),status:"active",metadata:{basePath:_,alchemyPath:c,bootstrapped:!0}})
2365
2367
  q.info("Using project",{projectId:R.id,projectName:R.name})
2366
2368
  const M=(0,o.default)()
2367
2369
  M.use((0,s.default)()),M.use(o.default.json({limit:"50mb"})),M.use(o.default.urlencoded({extended:!0})),M.use((0,p.requestLogger)(q))
@@ -2464,18 +2466,18 @@ try{const a=u.validateArgs(e,d.GetFileInfoSchema),{path:h}=a
2464
2466
  n.info("Getting file info: "+h)
2465
2467
  const{normalizedPath:f,fullPath:m}=u.validateAndNormalizePath(h,t)
2466
2468
  i=u.FileOperationPhase.FILE_WRITE
2467
- 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):"",b={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: "+b.type,`Size: ${b.sizeFormatted} (${b.size} bytes)`,"Created: "+b.created,"Modified: "+b.modified,"Accessed: "+b.accessed,"Permissions: "+b.permissions,"Is Directory: "+b.isDirectory,"Is File: "+b.isFile,"Is Symbolic Link: "+b.isSymbolicLink]
2468
- b.isFile&&w&&I.push("Extension: "+w)
2469
- const k=Date.now()-s
2470
- return o.recordValue("get_file_info_time",k),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+f,{type:b.type,size:b.size,time:k}),{content:[{type:"text",text:I.join("\n")}]}}catch(t){const r=Date.now()-s
2469
+ 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):"",b={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},k=["File Information for: "+f,"Type: "+b.type,`Size: ${b.sizeFormatted} (${b.size} bytes)`,"Created: "+b.created,"Modified: "+b.modified,"Accessed: "+b.accessed,"Permissions: "+b.permissions,"Is Directory: "+b.isDirectory,"Is File: "+b.isFile,"Is Symbolic Link: "+b.isSymbolicLink]
2470
+ b.isFile&&w&&k.push("Extension: "+w)
2471
+ const I=Date.now()-s
2472
+ return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+f,{type:b.type,size:b.size,time:I}),{content:[{type:"text",text:k.join("\n")}]}}catch(t){const r=Date.now()-s
2471
2473
  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}
2472
2474
  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()
2473
- try{const y=u.getRequestClient(),w=u.getTaskClient(),b=u.getFileClient(),I=u.getToolRecordClient(),{title:k,description:v,...C}=e,_=e.comment||k
2474
- f.info("Starting quick_edit workflow",{title:k,operationType:t})
2475
+ try{const y=u.getRequestClient(),w=u.getTaskClient(),b=u.getFileClient(),k=u.getToolRecordClient(),{title:I,description:v,...C}=e,_=e.comment||I
2476
+ f.info("Starting quick_edit workflow",{title:I,operationType:t})
2475
2477
  let E=!1
2476
2478
  try{const e=await y.listRequests({limit:2,sortBy:"created_at",sortDirection:"desc"})
2477
2479
  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")
2478
- const q=await y.createRequest({title:k,description:v,type:"quick-edit",acceptanceCriteria:["Quick change completed successfully"]})
2480
+ const q=await y.createRequest({title:I,description:v,type:"quick-edit",acceptanceCriteria:["Quick change completed successfully"]})
2479
2481
  if(!q||!q.id)throw Error("Failed to create request")
2480
2482
  const S=q.id
2481
2483
  let T
@@ -2483,24 +2485,24 @@ f.info("Created request",{requestId:S})
2483
2485
  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)
2484
2486
  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")
2485
2487
  f.debug("Creating task")
2486
- const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+k})
2488
+ const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+I})
2487
2489
  if(!e||!e.id)throw Error("Failed to create task")
2488
2490
  let v
2489
- 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,b,w,I,y,h,g,p)
2490
- else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,I,y,h,g,p)
2491
+ 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,b,w,k,y,h,g,p)
2492
+ else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,k,y,h,g,p)
2491
2493
  else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
2492
- v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||k},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})
2494
+ v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||I},d,w,k,y,u,h,g,p)}if(v.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
2493
2495
  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")
2494
2496
  P?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
2495
- try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${k}${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})
2497
+ 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})
2496
2498
  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")
2497
- const R=P?`Quick change completed with partial success: ${k}. Some replacements failed - see details below.`:"Quick change completed: "+k,M=P?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2499
+ const R=P?`Quick change completed with partial success: ${I}. Some replacements failed - see details below.`:"Quick change completed: "+I,M=P?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2498
2500
  let j=!1
2499
2501
  try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:R,acceptanceEvidence:[{evidence:M}],testVerification:void 0},d,u,h,g,p)
2500
2502
  if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text})
2501
2503
  else{try{await y.updateRequest(S,{status:"completed",completionSummary:R}),f.info("Request finalized to completed",{requestId:S})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:S,error:(0,l.getErrorMessage)(e)})}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:R}),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
2502
2504
  let O
2503
- 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:** ${k}\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:** ${k}\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
2505
+ 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
2504
2506
  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}}}
2505
2507
  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
2506
2508
  const r=t(9860),n=t(5674)
@@ -2573,8 +2575,8 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
2573
2575
  var t={}
2574
2576
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
2575
2577
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
2576
- 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"}),b=m.startTimer("tool_execution_time"),I=Date.now()
2577
- let k,v,C=d.FileOperationPhase.VALIDATION
2578
+ 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"}),b=m.startTimer("tool_execution_time"),k=Date.now()
2579
+ let I,v,C=d.FileOperationPhase.VALIDATION
2578
2580
  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"}
2579
2581
  try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:E,content:q,format:S,append:T,comment:P}=r,R=!!E,M=!!f
2580
2582
  w.info("Writing content to "+(R?"document":"file"),{taskId:i,filePath:M?f:void 0,documentId:R?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:T,comment:P})
@@ -2598,7 +2600,7 @@ try{await c.default.access(x),$=!0}catch{$=!1,A=!0}w.debug("Path validated with
2598
2600
  throw e}C=d.FileOperationPhase.RECORD_CREATION,m.incrementCounter("write_file_phase",1,{phase:C})
2599
2601
  const{toolRecordId:W}=await d.createFileOperationRecords(i,z,t.projectId,_.recordType,N,{operationType:R?"document":"file",documentId:R?E:void 0,documentFilename:O,filePath:M?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)
2600
2602
  let G
2601
- if(k=W,v=W,C=_.fileOperationPhase,m.incrementCounter("write_file_phase",1,{phase:C}),"json"===S)if("string"==typeof q)try{JSON.parse(q),G=q}catch(e){throw new u.ValidationError("Content is not valid JSON")}else G=JSON.stringify(q,null,2)
2603
+ if(I=W,v=W,C=_.fileOperationPhase,m.incrementCounter("write_file_phase",1,{phase:C}),"json"===S)if("string"==typeof q)try{JSON.parse(q),G=q}catch(e){throw new u.ValidationError("Content is not valid JSON")}else G=JSON.stringify(q,null,2)
2602
2604
  else G="string"==typeof q?q:JSON.stringify(q,null,2)
2603
2605
  let V=G
2604
2606
  if(M&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
@@ -2609,10 +2611,10 @@ if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile(D,V,"utf8")
2609
2611
  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
2610
2612
  if(M){if(C=d.FileOperationPhase.GIT_COMMIT,m.incrementCounter("write_file_phase",1,{phase:C}),t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
2611
2613
  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=`${A?"Create":T?"Append to":"Update"} ${j} (${v})`,r=await d.commitToGit(i,j,v,v,e,t,w,m,_.metricsPrefix)
2612
- K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:j,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:M?j:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:A,wasAppended:T&&$,operationType:R?"document":"file",processingTime:Date.now()-I,userComment:P,...M&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(R?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${A?"Created":T?"Appended to":"Updated"} ${R?`document ${E}${O?` (${O})`:""}`:"file "+j}**\n`
2614
+ K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:j,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:M?j:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:A,wasAppended:T&&$,operationType:R?"document":"file",processingTime:Date.now()-k,userComment:P,...M&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(R?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${A?"Created":T?"Appended to":"Updated"} ${R?`document ${E}${O?` (${O})`:""}`:"file "+j}**\n`
2613
2615
  Z+=`**Content Length:** ${V.length} characters\n`,M&&Y&&(Z+=`**Branch:** ${Y}\n`),U.lockAcquired&&U.lockedRequestId&&(Z+=`**Locked request:** ${U.lockedRequestId}\n`),M&&K&&(Z+=`**Commit Hash:** ${K.substring(0,8)}\n`,Q&&(Z+=`**Previous Commit:** ${Q.substring(0,8)}\n`)),v&&(Z+=`[RECORD:${v}]\n`),R&&(Z+=`\n**Document Update:** The document content has been updated and synced back to the tracking system. You can continue editing using other file modification tools with documentId \`${E}\`.`)
2614
2616
  const X=Date.now()
2615
- return w.info("Write operation completed successfully",{duration:X-I,path:M?j:"document:"+E,contentLength:V.length,wasCreated:A}),b({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
2617
+ return w.info("Write operation completed successfully",{duration:X-k,path:M?j:"document:"+E,contentLength:V.length,wasCreated:A}),b({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()-k
2616
2618
  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 b({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}}}
2617
2619
  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)},4118(e,exports){Object.defineProperty(exports,"__esModule",{value:!0})},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
2618
2620
  const r=t(6183),n=t(4648)
@@ -2783,10 +2785,10 @@ try{let o
2783
2785
  try{o=i.FileRecoverSchema.parse(e)}catch(t){if(t instanceof a.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
2784
2786
  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:b}=o
2785
2787
  return p.info("Recovering file to previous version",{taskId:f,filePath:y,commitHash:w,createBackup:b}),await async function(e,t,r,n,o,s,i,a,g,p,f){let m
2786
- try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),b=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:I}=await d.createFileOperationRecords(e,b?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),i,a,g,"file-recover",f)
2787
- m=I
2788
- let k,v=!1
2789
- try{await l.access(w),v=!0,n&&(k=`${w}.backup-${(new Date).toISOString().replace(/[:.]/g,"-")}`,await l.copyFile(w,k),a.info("Created backup",{originalPath:w,backupPath:k}))}catch{v=!1}const C=o.git
2788
+ try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),b=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:k}=await d.createFileOperationRecords(e,b?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),i,a,g,"file-recover",f)
2789
+ m=k
2790
+ let I,v=!1
2791
+ 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
2790
2792
  if(!C)throw Error("Git is not available")
2791
2793
  if(!(await(0,u.validateCommitHash)(C,r,a,"file-recover")).valid)throw Error(`Commit hash '${r}' is invalid or not found`)
2792
2794
  let _
@@ -2795,9 +2797,9 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
2795
2797
  throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await l.writeFile(w,_,"utf8")
2796
2798
  let E={}
2797
2799
  try{const t=`Recover ${y} from ${r.substring(0,8)}`
2798
- 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:k,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"
2800
+ 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"
2799
2801
  let S=`\u2705 **File ${q.charAt(0).toUpperCase()+q.slice(1)} Successfully**\n\n`
2800
- return S+=`**File:** ${y}\n`,S+=`**Recovered from:** ${r.substring(0,8)}\n`,S+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(S+=`**Backup created:** ${c.basename(k)}\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,b,t,r,n,p,s,m,g)}catch(e){const t=Date.now()-m
2802
+ 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,b,t,r,n,p,s,m,g)}catch(e){const t=Date.now()-m
2801
2803
  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}}}
2802
2804
  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"})
2803
2805
  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)
@@ -2945,15 +2947,15 @@ if(/^\d+$/.test(e)){const t=parseInt(e,10)
2945
2947
  return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
2946
2948
  if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
2947
2949
  if(e.match(/^(\d+(?:,\d+)+)$/)){const t=e.split(",").map((e=>parseInt(e,10)))
2948
- return{start:Math.min(...t),end:Math.max(...t)}}return null}(p),I=["blame","--porcelain"]
2949
- let k
2950
- b&&I.push(`-L${b.start},${b.end}`),f&&I.push(f),I.push("--",w),c.debug("Executing git blame",{args:I})
2950
+ return{start:Math.min(...t),end:Math.max(...t)}}return null}(p),k=["blame","--porcelain"]
2951
+ let I
2952
+ b&&k.push(`-L${b.start},${b.end}`),f&&k.push(f),k.push("--",w),c.debug("Executing git blame",{args:k})
2951
2953
  try{if(!t.git)throw Error("Git context not available")
2952
- k=await t.git.raw(I)}catch(e){const t=(0,h.getErrorMessage)(e)
2954
+ I=await t.git.raw(k)}catch(e){const t=(0,h.getErrorMessage)(e)
2953
2955
  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")
2954
2956
  let n="",o="",s="",i=0,a=0,c=new Map
2955
2957
  for(let e=0;e<r.length;e++){const l=r[e],d=l.match(/^([0-9a-f]{40})\s+\d+\s+(\d+)/)
2956
- 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}(k)
2958
+ 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)
2957
2959
  if(0===v.length)return{content:[{type:"text",text:"\u274c No blame information found for "+w}],isError:!0}
2958
2960
  const C=function(e){if(0===e.length)return[]
2959
2961
  const t=[]
@@ -3189,10 +3191,10 @@ const m=g.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_
3189
3191
  m.forEach((e=>{const t=e.status||"unverified"
3190
3192
  t in y&&y[t]++}))
3191
3193
  let w=g.testVerification||null
3192
- const b=g.title,I=g.type
3193
- let k=`# ${"feature"===I?"Feature":"quick-edit"===I?"Quick Edit":"Bug Fix"} Request: ${b} (${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`
3194
- return k+=`\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`,k+="\n## Tasks\n",0===p.length?k+="No tasks found for this request.\n":p.forEach((e=>{k+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${p.length} tasks`),k+="\n## Acceptance Criteria\n",k+=(0,i.formatCriteriaWithHashes)(m)+"\n","ready_for_review"===g.status&&m.some((e=>"verified"!==e.status))&&(k+="\n> **Status: ready_for_review** \u2014 Use the merge operation to verify criteria and merge to main.\n"),w&&(k+=`\n## Test Coverage\n- Test Cases: ${w.totalTestCases||0}\n- Criteria Tested: ${w.criteriaTestedCount||0}/${y.total}\n`,w.criterionCoverage&&Array.isArray(w.criterionCoverage)&&(k+="\n### Detailed Test Coverage:\n",w.criterionCoverage.forEach((e=>{k+=`- Criterion ${e.criterionId}: ${e.coverage} coverage\n`})))),g.recentActivity&&Array.isArray(g.recentActivity)&&(k+="\n## Recent Activity\n",g.recentActivity.slice(0,5).forEach((e=>{const t=new Date(e.timestamp).toLocaleString()
3195
- k+=`- ${t}: ${e.description}\n`}))),u({success:!0}),{content:[{type:"text",text:k}]}}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}}}
3194
+ const b=g.title,k=g.type
3195
+ let I=`# ${"feature"===k?"Feature":"quick-edit"===k?"Quick Edit":"Bug Fix"} Request: ${b} (${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`
3196
+ 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()
3197
+ 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}}}
3196
3198
  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
3197
3199
  for(let t=0;t<e.length;t++)r=(r<<5)-r+e.charCodeAt(t)|0
3198
3200
  return`${t+1}${String.fromCharCode(97+Math.abs(r)%26)}`}function r(e){const r=new Map
@@ -3290,25 +3292,25 @@ if(t){const e=Date.now()-t
3290
3292
  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()
3291
3293
  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
3292
3294
  const r=t(6183),n=t(2965)
3293
- 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")
3294
- try{const{requestId:o,summary:s}=e
3295
- if(!o)throw(0,r.createValidationError)("Request ID is required")
3296
- if(!s)throw(0,r.createValidationError)("Summary is required")
3297
- g.info("Starting request completion",{requestId:o})
3298
- const l=h?.sessionId||(0,n.getCachedSession)()?.sessionId
3299
- let d
3300
- try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${o}/validate-completion`,{sessionId:l})
3301
- d=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
3302
- 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`
3303
- 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"
3304
- try{await u.updateRequest(o,{status:m,completionSummary:s})}catch(e){const t=(0,i.getErrorMessage)(e)
3305
- return p({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let y
3306
- try{y=await u.getRequest(o)}catch(e){const t=(0,i.getErrorMessage)(e)
3307
- return p({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const w=y?.acceptanceCriteria||[]
3308
- 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=""
3309
- 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})
3310
- 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}}}
3311
- 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
3295
+ 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")
3296
+ try{const{requestId:n,summary:o}=e
3297
+ if(!n)throw(0,r.createValidationError)("Request ID is required")
3298
+ if(!o)throw(0,r.createValidationError)("Summary is required")
3299
+ h.info("Starting request completion",{requestId:n})
3300
+ const c=u?.sessionId
3301
+ let l
3302
+ try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:c})
3303
+ l=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
3304
+ 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`
3305
+ 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"
3306
+ try{await d.updateRequest(n,{status:f,completionSummary:o})}catch(e){const t=(0,s.getErrorMessage)(e)
3307
+ return g({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let m
3308
+ try{m=await d.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
3309
+ return g({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const y=m?.acceptanceCriteria||[]
3310
+ 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=""
3311
+ 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})
3312
+ 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}}}
3313
+ 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
3312
3314
  const r=t(6183),n=t(6285)
3313
3315
  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())}))})
3314
3316
  return(0,o.areTestsRequiredForCompletion)()?e.extend({testVerification:t}):e}Object.defineProperty(exports,"__esModule",{value:!0}),exports.DynamicCompleteRequestSchema=void 0,exports.getDynamicCompleteRequestSchema=r
@@ -3327,8 +3329,8 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
3327
3329
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3328
3330
  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()
3329
3331
  let y,w,b=l.FileOperationPhase.VALIDATION
3330
- 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"}
3331
- try{const n=r.getTaskClient(),u=r.getToolRecordClient(),k=r.getRequestClient(),v=l.validateArgs(e,c.DeleteFilesSchema),{taskId:C,paths:_,operations:E,comment:q}=v
3332
+ const k={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"}
3333
+ 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
3332
3334
  let S=[]
3333
3335
  if(_)S=_.map((e=>({type:"file",target:e})))
3334
3336
  else{if(!E)throw Error("Either paths or operations must be specified")
@@ -3336,22 +3338,22 @@ S=E.map((e=>{if(e.path)return{type:"file",target:e.path}
3336
3338
  if(e.documentId)return{type:"document",target:e.documentId}
3337
3339
  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")
3338
3340
  const T=S.filter((e=>"file"===e.type)),P=S.filter((e=>"document"===e.type)),R=S.length
3339
- 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)
3341
+ 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,k.metricsPrefix)
3340
3342
  const M=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3341
3343
  i.info("Initial branch context",{initialBranch:M.branch,initialRequestId:M.requestId,isMain:M.isMain})
3342
3344
  const j=[]
3343
3345
  for(const e of T){const{normalizedPath:r,fullPath:n}=l.validateAndNormalizePath(e.target,t)
3344
3346
  j.push({normalized:r,full:n})}b=l.FileOperationPhase.TASK_VALIDATION,o.incrementCounter("delete_files_phase",1,{phase:b})
3345
- const x=j.length>0?j[0].normalized:"document_operations",O=await l.validateTaskId(C,x,n,i,o,I.metricsPrefix),D=O?.requestId,A=await l.validateWorkItemStates(C,x,n,k,t,i,o,I.metricsPrefix),$=await l.autoPromoteTaskStatus(C,O.status,D,A.request?.status,x,n,k,i,o,I.metricsPrefix)
3347
+ const x=j.length>0?j[0].normalized:"document_operations",O=await l.validateTaskId(C,x,n,i,o,k.metricsPrefix),D=O?.requestId,A=await l.validateWorkItemStates(C,x,n,I,t,i,o,k.metricsPrefix),$=await l.autoPromoteTaskStatus(C,O.status,D,A.request?.status,x,n,I,i,o,k.metricsPrefix)
3346
3348
  $.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 ${D} to in_progress for file operations`,{requestId:D,previousStatus:A.request?.status,newStatus:$.newRequestStatus,triggeringTaskId:C})
3347
- const F=await l.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:D,context:t,operation:"delete-files",logger:i,metrics:o,metricsPrefix:I.metricsPrefix})
3349
+ const F=await l.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:D,context:t,operation:"delete-files",logger:i,metrics:o,metricsPrefix:k.metricsPrefix})
3348
3350
  if(!F.success){if(F.isLockConflict)return{content:[{type:"text",text:"\u274c "+F.error}],isError:!0}
3349
3351
  throw Error(F.error)}let N={hadUserMods:!1,userModsCommitHash:void 0}
3350
3352
  if(t.git)try{i.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
3351
3353
  const e=await(0,h.commitUserChangesBeforeToolOperation)(t.git,"delete-files",{requestId:D,taskId:C,workspaceManager:t.workspaceManager},i,o)
3352
3354
  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}),b=l.FileOperationPhase.RECORD_CREATION,o.incrementCounter("delete_files_phase",1,{phase:b})
3353
- const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,D,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)
3354
- y=L,w=L,b=I.fileOperationPhase,o.incrementCounter("delete_files_phase",1,{phase:b})
3355
+ const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,D,t.projectId,k.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,k.metricsPrefix,s)
3356
+ y=L,w=L,b=k.fileOperationPhase,o.incrementCounter("delete_files_phase",1,{phase:b})
3355
3357
  const B=[]
3356
3358
  let H=0
3357
3359
  P.length>0&&r.setProjectId(t.projectId)
@@ -3360,7 +3362,7 @@ try{try{await a.default.access(t.full)}catch(e){throw Error("File not found: "+t
3360
3362
  await a.default.unlink(t.full),r.success=!0,H++,i.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete file "+t.normalized,{error:r.error})}B.push(r)}const U=P.length>0?r.getDocumentClient():null
3361
3363
  for(const e of P){const t=e.target,n={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3362
3364
  try{let e
3363
- try{if(e=await U.getDocument(t),n.filename=e.filename,i.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,g.validateRequestStatusForDocumentOperation)(e.requestId,k,i,o,"delete-document")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
3365
+ try{if(e=await U.getDocument(t),n.filename=e.filename,i.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,g.validateRequestStatusForDocumentOperation)(e.requestId,I,i,o,"delete-document")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
3364
3366
  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)
3365
3367
  throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,f.getErrorMessage)(e)}`)}const s=await U.archiveDocument(t)
3366
3368
  n.success=!0,n.filename=s.filename,H++,i.info("Document archived successfully",{documentId:s.id,filename:s.filename,archivedAt:s.archived_at})}catch(e){n.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete document "+t,{error:n.error})}B.push(n)}const W=Date.now()-m
@@ -3369,9 +3371,9 @@ let G=null
3369
3371
  if(H>0){b=l.FileOperationPhase.GIT_COMMIT,o.incrementCounter("delete_files_phase",1,{phase:b})
3370
3372
  const e=B.filter((e=>e.success)),r=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
3371
3373
  let s
3372
- 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)}b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:b})
3374
+ 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,k.metricsPrefix)}b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:b})
3373
3375
  const V=B.filter((e=>e.success)),J=B.filter((e=>!e.success))
3374
- await l.updateFileOperationRecords(C,y,w,x,I.recordType,H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,{status:H===R?"completed":"partial_success",commitHash:G?.commitHash,previousCommitHash:G?.previousCommitHash,totalOperations:R,fileOperations:T.length,documentOperations:P.length,successCount:H,failureCount:R-H,successfulOperations:V.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:J.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,n,u,i,o,I.metricsPrefix)
3376
+ await l.updateFileOperationRecords(C,y,w,x,k.recordType,H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,{status:H===R?"completed":"partial_success",commitHash:G?.commitHash,previousCommitHash:G?.previousCommitHash,totalOperations:R,fileOperations:T.length,documentOperations:P.length,successCount:H,failureCount:R-H,successfulOperations:V.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:J.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,n,u,i,o,k.metricsPrefix)
3375
3377
  const K=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3376
3378
  let Y=""
3377
3379
  if(H===R){const e=V.filter((e=>"file"===e.type)).length,t=V.filter((e=>"document"===e.type)).length
@@ -3382,7 +3384,7 @@ return G?.commitHash&&(Y+="\nCommit: "+G.commitHash.substring(0,8)),K.requestId&
3382
3384
  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:b,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
3383
3385
  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){b=l.FileOperationPhase.RECORD_UPDATE_FAILURE
3384
3386
  try{const t=r.getTaskClient(),s=r.getToolRecordClient()
3385
- 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,b,i,o,e,I)}}
3387
+ await l.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",k.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,k.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,b,i,o,e,k)}}
3386
3388
  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)
3387
3389
  var o=Object.getOwnPropertyDescriptor(t,r)
3388
3390
  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=[]
@@ -3466,15 +3468,13 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
3466
3468
  var t={}
3467
3469
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
3468
3470
  return o(t,e),t})
3469
- 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")
3471
+ 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")
3470
3472
  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
3471
3473
  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)
3472
- const n=c.validateArgs(e,a.SpecialistOpsSchema),{operation:w,sessionId:b}=n
3473
- let I
3474
- switch(m.info("Processing specialist_ops",{operation:w,sessionId:b}),w){case"delegate":{const e=n.delegate,o=10
3475
- let i=f?.sessionId||p.sessionIdentity.getIdentity()?.sessionId
3476
- if(!i){const e=await(0,h.getServerUrl)(r,m)
3477
- 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})
3474
+ const n=c.validateArgs(e,a.SpecialistOpsSchema),{operation:y,sessionId:w}=n
3475
+ let b
3476
+ 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
3477
+ if(i&&s){const e=await async function(e,t,r,n,o){n.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
3478
3478
  const s=await(0,h.getServerUrl)(r,n)
3479
3479
  if(s)try{const r=await fetch(s.replace(/\/$/,"")+"/session")
3480
3480
  if(!r.ok)return
@@ -3487,34 +3487,33 @@ return"specialist"===t?.agentType&&"archived"!==t?.status}))
3487
3487
  if(n.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
3488
3488
  const g=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
3489
3489
  return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
3490
- 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)
3491
- if(e){I=e
3490
+ 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)
3491
+ if(e){b=e
3492
3492
  break}}let a=e.description
3493
- 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`)
3494
- if(i)try{const e=await(0,h.getServerUrl)(r,m)
3495
- if(y(`serverUrl=${e}, parentId=${i}`),e){const t=await fetch(e.replace(/\/$/,"")+"/session")
3496
- 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||""))
3497
- y(`siblings=${e.length}: ${e.join(", ")}`)
3493
+ 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`)
3494
+ if(i)try{const e=await(0,h.getServerUrl)(r,f)
3495
+ if(m(`serverUrl=${e}, parentId=${i}`),e){const t=await fetch(e.replace(/\/$/,"")+"/session")
3496
+ 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||""))
3497
+ m(`siblings=${e.length}: ${e.join(", ")}`)
3498
3498
  const r=(0,d.pickSpecialistName)(e)
3499
- a=r,y("picked name: "+r)}}else y("no serverUrl")}catch(e){y("error: "+(e instanceof Error?e.message:e+""))}else y("no parentId")
3500
- const w=e.requestId,b=w?`Working on request ${w}.\n\n${e.prompt}`:e.prompt
3501
- I=await(0,u.handleSpawn)({agent:"specialist",prompt:b,title:a,specialization:e.specialization},r,m,s,f)
3502
- break}case"follow-up":{const e=await(0,h.getServerUrl)(r,m)
3499
+ a=r,m("picked name: "+r)}}else m("no serverUrl")}catch(e){m("error: "+(e instanceof Error?e.message:e+""))}else m("no parentId")
3500
+ const y=e.requestId,w=y?`Working on request ${y}.\n\n${e.prompt}`:e.prompt
3501
+ b=await(0,u.handleSpawn)({agent:"specialist",prompt:w,title:a,specialization:e.specialization},r,f,s,p)
3502
+ break}case"follow-up":{const e=await(0,h.getServerUrl)(r,f)
3503
3503
  if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
3504
- if(t.ok){const e=await t.json(),r=e[b]?.type
3505
- if(r&&"idle"!==r&&"prompting"!==r){I={content:[{type:"text",text:`\u274c Specialist ${b} is currently busy (status: ${r}).\nUse \`delegate\` to spawn a new specialist instead.`}],isError:!0}
3506
- break}}}catch{}I=await(0,u.handleContinue)(b,n.followUp.prompt,r,m,s,"specialist",f)
3504
+ if(t.ok){const e=await t.json(),r=e[w]?.type
3505
+ if(r&&"idle"!==r&&"prompting"!==r){b={content:[{type:"text",text:`\u274c Specialist ${w} is currently busy (status: ${r}).\nUse \`delegate\` to spawn a new specialist instead.`}],isError:!0}
3506
+ break}}}catch{}b=await(0,u.handleContinue)(w,n.followUp.prompt,r,f,s,"specialist",p)
3507
3507
  const t=n.followUp.specialization
3508
3508
  if(t&&s)try{const e=s.getCLISessionClient()
3509
- e&&(await e.createOrUpdateSession({externalSessionId:b,specialization:t}),I.content[0].text+="\nSpecialization updated to: "+t)}catch{}break}case"check-status":I=await(0,u.handleCheckStatus)(b,r,m,s)
3509
+ e&&(await e.createOrUpdateSession({externalSessionId:w,specialization:t}),b.content[0].text+="\nSpecialization updated to: "+t)}catch{}break}case"check-status":b=await(0,u.handleCheckStatus)(w,r,f,s)
3510
3510
  break
3511
- case"abort":if(I=await(0,u.handleAbort)(b,r,m),!I.isError&&s)try{const e=s.getCLISessionClient()
3512
- e&&await e.createOrUpdateSession({externalSessionId:b,status:"archived"})}catch{}break
3513
- case"list":{let e=f?.sessionId||p.sessionIdentity.getIdentity()?.sessionId
3514
- if(!e){const t=await(0,h.getServerUrl)(r,m)
3515
- 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})
3516
- 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}}}
3517
- 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
3511
+ case"abort":if(b=await(0,u.handleAbort)(w,r,f),!b.isError&&s)try{const e=s.getCLISessionClient()
3512
+ e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
3513
+ case"list":{const e=p?.sessionId||g.sessionIdentity.getIdentity()?.sessionId
3514
+ b=await(0,u.handleListSessions)(r,f,s,{activeOnly:n.list?.activeOnly,requestId:n.list?.requestId,limit:n.list?.limit,agentType:"specialist",parentSessionId:e})
3515
+ break}default:throw new i.ValidationError("Unknown operation: "+y)}return m({success:!0}),o.incrementCounter(`specialist_ops_${y}_success`,1),b}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}}}
3516
+ 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
3518
3517
  const r=t(6183),n=t(2982)
3519
3518
  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)
3520
3519
  var o=Object.getOwnPropertyDescriptor(t,r)
@@ -3591,7 +3590,7 @@ var t={}
3591
3590
  if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
3592
3591
  return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3593
3592
  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()
3594
- let b,I,k=d.FileOperationPhase.VALIDATION
3593
+ let b,k,I=d.FileOperationPhase.VALIDATION
3595
3594
  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"}
3596
3595
  try{const i=d.validateArgs(e,l.InsertLinesSchema),{taskId:C,operations:_,comment:E}=i
3597
3596
  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")
@@ -3604,7 +3603,7 @@ if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not ava
3604
3603
  for(const e of S)P.push({type:"document",documentId:e.documentId,insertions:e.insertions})
3605
3604
  if(P.length>0&&t.apiClient){const e=P.map((e=>e.documentId))
3606
3605
  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}
3607
- throw e}}k=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("insert_lines_phase",1,{phase:k})
3606
+ throw e}}I=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("insert_lines_phase",1,{phase:I})
3608
3607
  const R=T.length>0?T[0].path:"document-operation",M=await d.validateTaskId(C,R,n,y,a,v.metricsPrefix),j=M?.requestId
3609
3608
  let x=null
3610
3609
  T.length>0&&j&&(x=await d.validateWorkItemStates(C,T[0].path,n,s,t,y,a,v.metricsPrefix))
@@ -3615,9 +3614,9 @@ if(!D.success){if(D.isLockConflict)return{content:[{type:"text",text:"\u274c "+D
3615
3614
  throw Error(D.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3616
3615
  for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
3617
3616
  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}
3618
- throw e}k=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("insert_lines_phase",1,{phase:k})
3617
+ throw e}I=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("insert_lines_phase",1,{phase:I})
3619
3618
  const A=[...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,R,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:A,userComment:E},n,o,y,a,v.metricsPrefix,m)
3620
- if(b=$,I=$,k=v.fileOperationPhase,a.incrementCounter("insert_lines_phase",1,{phase:k}),T.length>0&&t.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
3619
+ if(b=$,k=$,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")
3621
3620
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"insert-lines",{requestId:j,taskId:C,workspaceManager:t.workspaceManager},y,a)
3622
3621
  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})
3623
3622
  const F=[]
@@ -3630,8 +3629,8 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
3630
3629
  n.filename=s?.filename
3631
3630
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
3632
3631
  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))
3633
- 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:U,failedOperations:W,totalSuccessfulChanges:G,overallSuccess:V,successfulFiles:J,failedFiles:K}=H
3634
- 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:W+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:A,totalSuccessfulInsertions:G,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:E,...T.length>0&&B.success&&B.commitHash&&{commitHash:B.commitHash,previousCommitHash:B.previousCommitHash||void 0}},note:V?`Line insertion completed: ${U}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${W}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
3632
+ 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:k,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),H=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:U,failedOperations:W,totalSuccessfulChanges:G,overallSuccess:V,successfulFiles:J,failedFiles:K}=H
3633
+ try{await o.updateToolRecord(k,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:V?"completed":"failed",error:V?void 0:W+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:A,totalSuccessfulInsertions:G,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:E,...T.length>0&&B.success&&B.commitHash&&{commitHash:B.commitHash,previousCommitHash:B.previousCommitHash||void 0}},note:V?`Line insertion completed: ${U}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${W}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
3635
3634
  if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${U+W}\n`,Y+=`- **Successful operations:** ${U}\n`,Y+=`- **Failed operations:** ${W}\n`,Y+=`- **Total insertions:** ${G} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n`,Y+="\n",B.success&&B.commitHash&&(Y+="**Git Commit:**\n",Y+=`- **Commit Hash:** ${B.commitHash.substring(0,8)}\n`,Y+=`- **Files Committed:** ${B.filesCommitted.length}\n`,B.previousCommitHash&&(Y+=`- **Previous Commit:** ${B.previousCommitHash.substring(0,8)}\n`),Y+="\n"),D.lockAcquired&&D.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${D.lockedRequestId}\n\n`),1===F.length){const e=F[0]
3636
3635
  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"
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}`
@@ -3641,68 +3640,68 @@ for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?
3641
3640
  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")
3642
3641
  const Q=Date.now()-w
3643
3642
  return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:U,failedOperations:W}),a.incrementCounter("insert_lines_total",1,{success:V}),{content:[{type:"text",text:Y}],isError:!V}}catch(t){const r=Date.now()-w
3644
- if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,f.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("insert_lines_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
3643
+ if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:I}),k)try{await o.updateToolRecord(k,{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}}}
3645
3644
  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
3646
3645
  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)
3647
3646
  exports.ClientFactory=class{static async createClient(e,m,y,w={}){(m=m.child({component:"client-factory"})).info("Creating API client with components")
3648
3647
  const b=w.tokenManager||new r.TokenManager(m,w.workingDir||process.cwd())
3649
3648
  await b.initialize()
3650
- const I=w.tokenSynchronizer||new i.ClientTokenSynchronizer(m),k=new s.AuthenticationManager(b,m,I),v=await k.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})
3651
- I.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
3649
+ const k=w.tokenSynchronizer||new i.ClientTokenSynchronizer(m),I=new s.AuthenticationManager(b,m,k),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})
3650
+ k.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
3652
3651
  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})
3653
- I.registerClient(E)
3652
+ k.registerClient(E)
3654
3653
  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})
3655
- I.registerClient(q),m.info("RequestClient constructor received token: "+(v?"present":"missing"))
3654
+ k.registerClient(q),m.info("RequestClient constructor received token: "+(v?"present":"missing"))
3656
3655
  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})
3657
- I.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
3656
+ k.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
3658
3657
  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})
3659
- I.registerClient(T)
3658
+ k.registerClient(T)
3660
3659
  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})
3661
- I.registerClient(P)
3660
+ k.registerClient(P)
3662
3661
  const R=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})
3663
- if(I.registerClient(R),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
3662
+ if(k.registerClient(R),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
3664
3663
  try{m.info("Creating ProjectSynchronizer components")
3665
3664
  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})
3666
3665
  _.setProjectSynchronizer(n),m.info("ProjectSynchronizer created and connected to ProjectClient")}catch(e){const t="Failed to create required ProjectSynchronizer components: "+(0,h.getErrorMessage)(e)
3667
- throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const M=new o.ApiClient(k,_,E,q,S,T,P,R,m)
3666
+ throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const M=new o.ApiClient(I,_,E,q,S,T,P,R,m)
3668
3667
  m.info("API client initialized with specialized clients"),v?(M.setAuthToken(v),m.info("Auth token set on ApiClient during creation",{hasToken:!0,tokenLength:v.length})):m.warn("No auth token available during ApiClient creation",{info:"Client will need to authenticate before making requests"})
3669
- const j=I.verifyAllClients()
3668
+ const j=k.verifyAllClients()
3670
3669
  j.success?m.info("Token consistency verified across all clients"):m.error(`Token inconsistency detected in ${j.failedClients.length} clients: ${j.failedClients.join(", ")}`)
3671
3670
  const x=M.getAuthToken()
3672
3671
  return v&&!x?(m.error("CRITICAL: ApiClient token was not set properly!"),M.setAuthToken(v)):x&&m.info("ApiClient token verified",{tokenLength:x.length,matches:x===v}),m.info("API client creation completed successfully"),M}}},6540(e,exports){var t
3673
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6552(e,exports,t){async function r(){const e=new o.StdioServerTransport,t=(0,l.setupParentProcessDetection)((()=>{I.info("Parent process gone or orphan detected. Shutting down."),process.exit(0)}))
3674
- if(E)try{await E.connectStdio(),(0,a.isDebugToolsEnabled)()&&I.info("Connected stdio transport to server")}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3675
- throw I.error("Failed to connect stdio transport",{errorDetails:t}),e}else I.error("No global server instance available to connect transport")
3672
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6552(e,exports,t){async function r(){const e=new o.StdioServerTransport,t=(0,l.setupParentProcessDetection)((()=>{k.info("Parent process gone or orphan detected. Shutting down."),process.exit(0)}))
3673
+ if(E)try{await E.connectStdio(),(0,a.isDebugToolsEnabled)()&&k.info("Connected stdio transport to server")}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3674
+ throw k.error("Failed to connect stdio transport",{errorDetails:t}),e}else k.error("No global server instance available to connect transport")
3676
3675
  return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3677
3676
  Object.defineProperty(exports,"__esModule",{value:!0})
3678
3677
  const o=t(5802),s=n(t(6928)),i=t(184),a=t(3444),c=t(1152),l=t(8851),d=t(8411),u=n(t(9896)),h=t(4139),g=t(5218),p=t(8824),f=t(9939),m=t(7960),y=process.argv.slice(2),w=y[0]||process.cwd(),b=s.default.resolve(w)
3679
3678
  console.error("\n=== MCP STARTUP DIAGNOSTICS ==="),console.error("Script path (process.argv[1]):",process.argv[1]),console.error("Base directory:",b),console.error("ENABLE_DEBUG_TOOLS env:",process.env.ENABLE_DEBUG_TOOLS),console.error("DEBUG_LOGGING env:",process.env.DEBUG_LOGGING),console.error("isDevBuild():",(0,m.isDevBuild)()),console.error("isDebugToolsEnabled():",(0,a.isDebugToolsEnabled)()),console.error("===============================\n")
3680
- const I=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:b});(0,a.isDebugToolsEnabled)()?I.info("MCP Direct server initializing",{baseDir:b,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):I.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(I.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),E)try{E.cleanupSSEConnection()}catch(e){I.error("Error during cleanup after uncaught exception: "+e)}setTimeout((()=>process.exit(1)),500)})),process.on("unhandledRejection",(e=>{I.error("UNHANDLED REJECTION: "+e,{stack:e instanceof Error?e.stack:"No stack available"})})),process.on("exit",(e=>{I.info("Process exiting with code: "+e)}))
3681
- const k=process.stdout.write
3682
- process.stdout.write=function(e,t,r){try{if("string"==typeof e)try{JSON.parse(e)}catch(t){return e.includes('"__message_type"')||(process.stderr.write("[STDOUT REDIRECTED]: "+e),r&&r()),!0}return"string"==typeof t&&"function"==typeof r?k.call(process.stdout,e,t,r):"function"==typeof t?k.call(process.stdout,e,void 0,t):k.call(process.stdout,e)}catch(e){return process.stderr.write("[STDOUT ERROR]: "+e),!0}},(0,a.isDebugToolsEnabled)()&&(I.info("Initialized stdout filtering to ensure only valid JSON is sent"),I.info("!!!MARKER!!! COMMAND-LINE ARGS:",{args:JSON.stringify(y)}),I.info("!!!MARKER!!! BASE DIRECTORY:",{baseDir:w}),I.info("!!!MARKER!!! ABSOLUTE BASE DIR:",{absBaseDir:b}),I.info("Working with base directory:",{absBaseDir:b}))
3683
- try{if(u.default.existsSync(b)||(I.warn(`Base directory ${b} does not exist. Creating it...`),u.default.mkdirSync(b,{recursive:!0})),(0,a.isDebugToolsEnabled)()){const e=s.default.join(b,".mcp-test-file")
3684
- u.default.writeFileSync(e,(new Date).toISOString()),I.info("Successfully wrote test file to "+e),u.default.unlinkSync(e),I.info("Successfully deleted test file"),I.info(`Confirmed base directory ${b} exists and is accessible`)}}catch(e){I.error(`Error accessing base directory ${b}:`,{error:e}),I.warn("This may cause issues with file operations - please check permissions")}const v=(0,c.createMetricsCollector)(!1)
3679
+ const k=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:b});(0,a.isDebugToolsEnabled)()?k.info("MCP Direct server initializing",{baseDir:b,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):k.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(k.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),E)try{E.cleanupSSEConnection()}catch(e){k.error("Error during cleanup after uncaught exception: "+e)}setTimeout((()=>process.exit(1)),500)})),process.on("unhandledRejection",(e=>{k.error("UNHANDLED REJECTION: "+e,{stack:e instanceof Error?e.stack:"No stack available"})})),process.on("exit",(e=>{k.info("Process exiting with code: "+e)}))
3680
+ const I=process.stdout.write
3681
+ process.stdout.write=function(e,t,r){try{if("string"==typeof e)try{JSON.parse(e)}catch(t){return e.includes('"__message_type"')||(process.stderr.write("[STDOUT REDIRECTED]: "+e),r&&r()),!0}return"string"==typeof t&&"function"==typeof r?I.call(process.stdout,e,t,r):"function"==typeof t?I.call(process.stdout,e,void 0,t):I.call(process.stdout,e)}catch(e){return process.stderr.write("[STDOUT ERROR]: "+e),!0}},(0,a.isDebugToolsEnabled)()&&(k.info("Initialized stdout filtering to ensure only valid JSON is sent"),k.info("!!!MARKER!!! COMMAND-LINE ARGS:",{args:JSON.stringify(y)}),k.info("!!!MARKER!!! BASE DIRECTORY:",{baseDir:w}),k.info("!!!MARKER!!! ABSOLUTE BASE DIR:",{absBaseDir:b}),k.info("Working with base directory:",{absBaseDir:b}))
3682
+ try{if(u.default.existsSync(b)||(k.warn(`Base directory ${b} does not exist. Creating it...`),u.default.mkdirSync(b,{recursive:!0})),(0,a.isDebugToolsEnabled)()){const e=s.default.join(b,".mcp-test-file")
3683
+ u.default.writeFileSync(e,(new Date).toISOString()),k.info("Successfully wrote test file to "+e),u.default.unlinkSync(e),k.info("Successfully deleted test file"),k.info(`Confirmed base directory ${b} exists and is accessible`)}}catch(e){k.error(`Error accessing base directory ${b}:`,{error:e}),k.warn("This may cause issues with file operations - please check permissions")}const v=(0,c.createMetricsCollector)(!1)
3685
3684
  let C=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com"
3686
3685
  const _=global.__serverInitialized
3687
- void 0===_?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&I.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&I.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
3686
+ void 0===_?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&k.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&k.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
3688
3687
  let E=null
3689
3688
  const q=(0,g.isMultiAgentModeEnabled)(b)
3690
- try{(0,d.acquireProcessLock)(b,q)||(I.error(`Process lock acquisition failed for ${b}. Another instance may be running.`),I.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&(q?I.info("Multi-agent mode enabled - allowing concurrent access to "+b):I.info("Successfully acquired process lock for "+b))}catch(e){I.error("Lock acquisition threw exception",{error:(0,p.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),I.error("Cannot continue without lock in single-agent mode"),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(I.info("============================================================"),I.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),I.info("BASE DIR: "+b),I.info("ALCHEMY PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME)),I.info("PROJECT PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME+"/project.json")),I.info("MULTI-AGENT MODE: "+q),I.info("MCP client information will be captured during protocol initialization")),I.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(I.info("============================================================"),I.info("Base directory: "+b),I.info("Remote server URL: "+C),I.info("Node version: "+process.version),I.info("Current working directory: "+process.cwd()),I.info("ALLOWED_DIRECTORIES env var: not used (single working directory mode)"),I.info("Server already initialized: "+(_?"YES":"NO"))),_&&((0,a.isDebugToolsEnabled)()&&(I.info("Server already initialized globally, reusing existing server instance"),I.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3691
- I.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
3689
+ try{(0,d.acquireProcessLock)(b,q)||(k.error(`Process lock acquisition failed for ${b}. Another instance may be running.`),k.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&(q?k.info("Multi-agent mode enabled - allowing concurrent access to "+b):k.info("Successfully acquired process lock for "+b))}catch(e){k.error("Lock acquisition threw exception",{error:(0,p.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),k.error("Cannot continue without lock in single-agent mode"),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(k.info("============================================================"),k.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),k.info("BASE DIR: "+b),k.info("ALCHEMY PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME)),k.info("PROJECT PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME+"/project.json")),k.info("MULTI-AGENT MODE: "+q),k.info("MCP client information will be captured during protocol initialization")),k.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(k.info("============================================================"),k.info("Base directory: "+b),k.info("Remote server URL: "+C),k.info("Node version: "+process.version),k.info("Current working directory: "+process.cwd()),k.info("ALLOWED_DIRECTORIES env var: not used (single working directory mode)"),k.info("Server already initialized: "+(_?"YES":"NO"))),_&&((0,a.isDebugToolsEnabled)()&&(k.info("Server already initialized globally, reusing existing server instance"),k.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3690
+ k.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
3692
3691
  try{const e=u.default.existsSync(b)
3693
- if((0,a.isDebugToolsEnabled)()&&I.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=u.default.statSync(b)
3694
- I.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(8)}`)}else(0,a.isDebugToolsEnabled)()&&I.info("Directory does not exist, trying to create it"),u.default.mkdirSync(b,{recursive:!0})}catch(e){I.error("Error checking directory: "+e)}if(!u.default.existsSync(b))try{u.default.mkdirSync(b,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&I.info("Created base directory: "+b)}catch(e){I.error("Failed to create base directory: "+e)}const S=s.default.join(b,h.ALCHEMY_DIR_NAME)
3695
- if(!u.default.existsSync(S))try{u.default.mkdirSync(S,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&I.info("Created alchemy lab directory: "+S)}catch(e){I.error("Failed to create alchemy lab directory: "+e)}try{(async function(){try{C=await async function(){if(process.env.REMOTE_SERVER_URL)return process.env.REMOTE_SERVER_URL
3696
- try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(I),n=await r.getInstallationConfig()
3697
- if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&I.info("Loaded REMOTE_SERVER_URL from installation config",{remoteServerUrl:n.remoteServerUrl}),n.remoteServerUrl}catch(e){(0,a.isDebugToolsEnabled)()&&I.debug("Could not read REMOTE_SERVER_URL from installation config",{error:e instanceof Error?e.message:"Unknown error"})}return"https://api.alchemylabcode.com"}()
3698
- try{const e=await(0,f.syncPlugins)(b,(0,m.isDevBuild)(),I)
3699
- e.synced.length>0&&I.info("Synced plugins on startup",{synced:e.synced}),e.errors.length>0&&I.warn("Some plugins failed to sync",{errors:e.errors})}catch(e){I.warn("Plugin sync failed",{error:e instanceof Error?e.message:"Unknown error"})}(0,a.isDebugToolsEnabled)()&&(I.info("Creating MCP server with base dir: "+b),I.info("Using remote server URL: "+C))
3700
- const e=await(0,i.createServer)(b,I,v,C,{multiAgentMode:(0,g.isMultiAgentModeEnabled)(b)})
3701
- E=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&I.info("MCP server created successfully")
3692
+ if((0,a.isDebugToolsEnabled)()&&k.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=u.default.statSync(b)
3693
+ k.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(8)}`)}else(0,a.isDebugToolsEnabled)()&&k.info("Directory does not exist, trying to create it"),u.default.mkdirSync(b,{recursive:!0})}catch(e){k.error("Error checking directory: "+e)}if(!u.default.existsSync(b))try{u.default.mkdirSync(b,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&k.info("Created base directory: "+b)}catch(e){k.error("Failed to create base directory: "+e)}const S=s.default.join(b,h.ALCHEMY_DIR_NAME)
3694
+ if(!u.default.existsSync(S))try{u.default.mkdirSync(S,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&k.info("Created alchemy lab directory: "+S)}catch(e){k.error("Failed to create alchemy lab directory: "+e)}try{(async function(){try{C=await async function(){if(process.env.REMOTE_SERVER_URL)return process.env.REMOTE_SERVER_URL
3695
+ try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(k),n=await r.getInstallationConfig()
3696
+ if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&k.info("Loaded REMOTE_SERVER_URL from installation config",{remoteServerUrl:n.remoteServerUrl}),n.remoteServerUrl}catch(e){(0,a.isDebugToolsEnabled)()&&k.debug("Could not read REMOTE_SERVER_URL from installation config",{error:e instanceof Error?e.message:"Unknown error"})}return"https://api.alchemylabcode.com"}()
3697
+ try{const e=await(0,f.syncPlugins)(b,(0,m.isDevBuild)(),k)
3698
+ e.synced.length>0&&k.info("Synced plugins on startup",{synced:e.synced}),e.errors.length>0&&k.warn("Some plugins failed to sync",{errors:e.errors})}catch(e){k.warn("Plugin sync failed",{error:e instanceof Error?e.message:"Unknown error"})}(0,a.isDebugToolsEnabled)()&&(k.info("Creating MCP server with base dir: "+b),k.info("Using remote server URL: "+C))
3699
+ const e=await(0,i.createServer)(b,k,v,C,{multiAgentMode:(0,g.isMultiAgentModeEnabled)(b)})
3700
+ E=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&k.info("MCP server created successfully")
3702
3701
  const n=r()
3703
- return(0,a.isDebugToolsEnabled)()&&I.info("Stdio transport registered with server"),{server:E,transportInfo:n}}catch(e){throw I.error("Failed to initialize MCP server",{error:e}),e}})().then((()=>{(0,a.isDebugToolsEnabled)()&&I.info("MCP server initialization complete")})).catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3704
- I.error("Server initialization failed",{errorDetails:t}),process.exit(1)}))}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3705
- I.error("Exception during server initialization",{errorDetails:t}),process.exit(1)}process.on("SIGTERM",(()=>{I.info("SIGTERM received, shutting down"),setTimeout((()=>process.exit(0)),500)})),process.on("SIGINT",(()=>{I.info("SIGINT received, shutting down"),setTimeout((()=>process.exit(0)),500)}))},6595(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ApiClient=void 0
3702
+ return(0,a.isDebugToolsEnabled)()&&k.info("Stdio transport registered with server"),{server:E,transportInfo:n}}catch(e){throw k.error("Failed to initialize MCP server",{error:e}),e}})().then((()=>{(0,a.isDebugToolsEnabled)()&&k.info("MCP server initialization complete")})).catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3703
+ k.error("Server initialization failed",{errorDetails:t}),process.exit(1)}))}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
3704
+ k.error("Exception during server initialization",{errorDetails:t}),process.exit(1)}process.on("SIGTERM",(()=>{k.info("SIGTERM received, shutting down"),setTimeout((()=>process.exit(0)),500)})),process.on("SIGINT",(()=>{k.info("SIGINT received, shutting down"),setTimeout((()=>process.exit(0)),500)}))},6595(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ApiClient=void 0
3706
3705
  const r=t(1599),n=t(2690),o=t(4465),s=t(5187),i=t(5674),a=t(8824)
3707
3706
  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
3708
3707
  return this.logger.debug("ApiClient.isOffline called - reporting actual connection status",{isOffline:n,client:"ApiClient"}),n}checkConnectivity(e,t){if(this.isOffline()){let r
@@ -3739,7 +3738,7 @@ var t={}
3739
3738
  if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
3740
3739
  return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
3741
3740
  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"}),b=Date.now()
3742
- let I,k,v=d.FileOperationPhase.VALIDATION
3741
+ let k,I,v=d.FileOperationPhase.VALIDATION
3743
3742
  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"}
3744
3743
  try{const i=d.validateArgs(e,l.ReplaceLinesSchema),{taskId:_,operations:E,comment:q}=i
3745
3744
  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")
@@ -3765,7 +3764,7 @@ for(let e=0;e<P.length;e++){const r=P[e],n=S[e],{normalizedPath:o,fullPath:s}=d.
3765
3764
  P[e]={...r,path:o,fullPath:s}}}if(R.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}
3766
3765
  throw e}v=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
3767
3766
  const $=[...P.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...R.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await d.createFileOperationRecords(_,x,t.projectId,C.recordType,M,{operationCount:E.length,fileOperations:P.length,documentOperations:R.length,operations:$,userComment:q},n,o,w,a,C.metricsPrefix,m)
3768
- if(I=F,k=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")
3767
+ if(k=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")
3769
3768
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},w,a)
3770
3769
  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})
3771
3770
  const N=[]
@@ -3778,8 +3777,8 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
3778
3777
  n.filename=s?.filename
3779
3778
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
3780
3779
  n.replacements=l,n.successfulReplacements=l.filter((e=>e.success)).length,n.failedReplacements=l.filter((e=>!e.success)).length,n.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,H++,w.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulReplacements:n.successfulReplacements,failedReplacements:n.failedReplacements,linesReplaced:n.totalLinesReplaced,linesAdded:n.totalLinesAdded})):0===n.failedReplacements&&(n.success=!0),L+=n.failedReplacements,z+=n.totalLinesReplaced,B+=n.totalLinesAdded}catch(t){n.error=(0,f.getErrorMessage)(t),n.failedReplacements=e.replacements.length,L+=n.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:n.error})}N.push(n)}if(R.length>0)try{for(const e of R){const r=N.find((t=>t.documentId===e.documentId))
3781
- r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const U=await d.handleMultiFileGitCommit(_,P,N,H,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),W=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=W
3782
- try{await o.updateToolRecord(k,{metadata:{path:P.length>0?P[0].path:"document:"+R[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:$,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-b,userComment:q,...P.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.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"
3780
+ r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const U=await d.handleMultiFileGitCommit(_,P,N,H,{operationType:"Replace lines",toolRecordId:I,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),W=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=W
3781
+ try{await o.updateToolRecord(I,{metadata:{path:P.length>0?P[0].path:"document:"+R[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:$,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-b,userComment:q,...P.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.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"
3783
3782
  if(t.workspaceManager&&(Z+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Z+="**Summary:**\n",Z+=`- **Files processed:** ${G+V}\n`,Z+=`- **Successful operations:** ${G}\n`,Z+=`- **Failed operations:** ${V}\n`,Z+=`- **Total replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,B>0&&(Z+=`- **Total Lines Added:** ${B}\n`),Z+="\n",U.success&&U.commitHash&&(Z+="**Git Commit:**\n",Z+=`- **Commit Hash:** ${U.commitHash.substring(0,8)}\n`,Z+=`- **Files Committed:** ${U.filesCommitted.length}\n`,U.previousCommitHash&&(Z+=`- **Previous Commit:** ${U.previousCommitHash.substring(0,8)}\n`),Z+="\n"),A.lockAcquired&&A.lockedRequestId&&(Z+=`\u{1f512} **Locked request:** ${A.lockedRequestId}\n\n`),1===N.length){const e=N[0]
3784
3783
  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"
3785
3784
  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"
@@ -3787,24 +3786,24 @@ for(const e of N){if("file"===e.type?Z+=`### File: ${e.path}\n`:(Z+="### Documen
3787
3786
  for(const t of e.replacements.filter((e=>!e.success)))Z+=` - Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}Z+="\n"}}R.length>0&&(Z+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3788
3787
  const X=Date.now()-b
3789
3788
  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()-b
3790
- if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),k)try{await o.updateToolRecord(k,{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}}}
3789
+ 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}}}
3791
3790
  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
3792
3791
  const r=t(9896),n=t(6928)
3793
- exports.sessionIdentity=new class{constructor(){this.discoveryAttempted=!1,this.parentCache=new Map}setIdentity(e){const t=this.identity
3792
+ exports.sessionIdentity=new class{constructor(){this.parentCache=new Map}setIdentity(e){const t=this.identity
3794
3793
  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}
3795
- 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
3796
- 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)
3794
+ 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)
3797
3795
  return this.log("getParentSessionId.cache-hit",{childExternalId:e,parentExternalId:t}),t}try{const n=t.getCLISessionClient()
3798
3796
  if(!n)return r.warn("CLI session client not available"),null
3799
3797
  const o=await n.getParent(e),s=o?.externalSessionId||null
3800
3798
  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+""
3801
- 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
3799
+ 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
3800
+ if(!n)return t.warn("Cannot get session request: no session identity"),null
3802
3801
  try{const r=e.getSessionRequestAssociationClient?.()
3803
3802
  if(!r)return t.warn("Session request association client not available"),null
3804
- const n=await r.getActiveRequestsForSession(this.identity.sessionId)
3805
- if(n?.length>0){const e=n[0].requestLocalId||n[0].request_local_id
3806
- 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+""
3807
- 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})
3803
+ const o=await r.getActiveRequestsForSession(n)
3804
+ if(o?.length>0){const e=o[0].requestLocalId||o[0].request_local_id
3805
+ 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+""
3806
+ 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})
3808
3807
  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
3809
3808
  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
3810
3809
  const r=t(6183),n=t(6651)
@@ -3867,13 +3866,13 @@ s.info("Raw task response data",{responseDataType:typeof P,isArray:Array.isArray
3867
3866
  try{const M=await m.getToolRecordsByTaskId(g)
3868
3867
  if(s.info("Raw records response data",{responseDataType:typeof M,isArray:Array.isArray(M),hasData:null!=M,properties:M&&"object"==typeof M?Object.keys(M):[]}),b=(0,l.extractArrayFromResponse)(M,{logger:s,operationName:"searchRecords",defaultValue:[]}),b.length>0&&s.info("First record summary:",{id:b[0].id,type:b[0].type,hasMetadata:!!b[0].metadata,hasCommitHash:!!b[0].metadata?.commitHash}),s.info(`Extracted ${b.length} records for task ${g}`),b.length>0){const j={}
3869
3868
  b.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)}),b=[]}if(0===b.length)return h({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
3870
- function I(e){const t=new Map,r=new Map,n=[]
3869
+ function k(e){const t=new Map,r=new Map,n=[]
3871
3870
  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
3872
3871
  if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
3873
3872
  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||[]]
3874
3873
  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"}
3875
- t.set(s.source,e),r.set(s.destination,e),n.push(e)}}return{sourceToMove:t,destToMove:r,allMoves:n}}const k=I(b)
3876
- s.info(`Detected ${k.allMoves.length} move operations`)
3874
+ t.set(s.source,e),r.set(s.destination,e),n.push(e)}}return{sourceToMove:t,destToMove:r,allMoves:n}}const I=k(b)
3875
+ s.info(`Detected ${I.allMoves.length} move operations`)
3877
3876
  const v=b.filter((e=>{if(!e||"object"!=typeof e)return s.warn("Skipping invalid record (not an object)"),!1
3878
3877
  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
3879
3878
  if(!e.metadata)return s.warn("Skipping record without metadata: "+e.id),!1
@@ -3949,7 +3948,7 @@ continue}let pe
3949
3948
  if("pre-task"===W.status?(pe=[`${W.commitHash}..${B.commitHash}`,"--",$],s.info(`Comparing pre-task commit with final commit: ${W.commitHash?W.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${$}`)):(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&&W.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
3950
3949
  try{const me=await t.git.show([`${W.commitHash}:${$}`]),ye=await t.git.show([`${B.commitHash}:${$}`])
3951
3950
  if(me!==ye&&(V=!0,G="Changes detected through direct content comparison (not visible in standard diff)",p)){const we=me.split("\n"),be=ye.split("\n")
3952
- Math.abs(we.length-be.length)>0&&(G+=`\n\nLine count changed: ${we.length} \u2192 ${be.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(ke){if(s.warn("Error getting diff for "+$,{error:(0,u.getErrorMessage)(ke),firstCommit:z.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),G="Error getting diff: "+(0,u.getErrorMessage)(ke),"pre-task"!==z.status&&t.git)try{const ve=[`${B.commitHash}:${$}`]
3951
+ Math.abs(we.length-be.length)>0&&(G+=`\n\nLine count changed: ${we.length} \u2192 ${be.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(ke){s.warn("Error in direct file comparison: "+(ke instanceof Error?ke.message:ke+""))}}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}:${$}`]
3953
3952
  s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${$}`)
3954
3953
  const Ce=await t.git.show(ve)
3955
3954
  if(Ce&&Ce.trim().length>0){if(p){let _e=""
@@ -3961,14 +3960,14 @@ w&&"object"==typeof w&&(E+="## Task Information\n",E+=`- **Title**: ${w.title||"
3961
3960
  const q=3e3
3962
3961
  let S=0,T=!1
3963
3962
  if(p){for(const Te of _.values())Te.hasDiff&&Te.diffText&&(S+=Te.diffText.split("\n").length)
3964
- 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`,k.allMoves.length>0){E+="## Move Operations\n\n",E+=`Detected ${k.allMoves.length} file move operation(s):\n\n`
3965
- for(const Pe of k.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"
3963
+ 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`
3964
+ 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"
3966
3965
  for(const[Re,Me]of _.entries()){const{normalizedPath:je,fullPath:xe}=d.validateAndNormalizePath(Re,t)
3967
3966
  let Oe=!1
3968
3967
  try{await a.access(xe),Oe=!0}catch{}E+=`### ${Re} ${Oe?"":"(Deleted)"}\n\n`
3969
3968
  const De=new Date(Me.firstChange.timestamp).toLocaleString(),Ae=new Date(Me.lastChange.timestamp).toLocaleString()
3970
3969
  E+=`**First Change**: ${De}\n`,E+=`**Last Change**: ${Ae}\n`,"pre-task"===Me.firstChange.status&&Me.firstChange.commitHash?E+=`**Pre-Task Commit**: ${Me.firstChange.commitHash.substring(0,8)}\n`:Me.firstChange.commitHash&&(E+=`**File Created During Task**: ${Me.firstChange.commitHash.substring(0,8)}\n`),Me.lastChange.commitHash&&(E+=`**Final Commit**: ${Me.lastChange.commitHash.substring(0,8)}\n`)
3971
- const $e=k.sourceToMove.get(Re),Fe=k.destToMove.get(Re)
3970
+ const $e=I.sourceToMove.get(Re),Fe=I.destToMove.get(Re)
3972
3971
  $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?Me.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=Me.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${Me.diffText}\n\n`:T&&Me.hasDiff?(E+=`\n**Note**: File has changes (${Me.diffText?Me.diffText.split("\n").length:0} lines). `,E+=`Compare ${Me.firstChange.commitHash?Me.firstChange.commitHash.substring(0,8):"unknown"}..${Me.lastChange.commitHash?Me.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Me.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${Me.diffText}\n\n`,E+="---\n\n"}return h({success:!0,fileCount:C.size}),{content:[{type:"text",text:E}]}}catch(Ne){return s.error("Error in task file history tool",{error:Ne instanceof Error?Ne.stack:Ne+""}),h({success:!1,error:Ne instanceof Error?Ne.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,u.getErrorMessage)(Ne)}],isError:!0}}}
3973
3972
  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
3974
3973
  const r=t(1058)
@@ -4091,42 +4090,42 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentit
4091
4090
  i.existsSync(n)||i.mkdirSync(n,{recursive:!0})
4092
4091
  const s=(new Date).toISOString(),c=Object.keys(r).length?" "+JSON.stringify(r):""
4093
4092
  i.appendFileSync(o,`[${s}] ${e} | ${t}${c}\n`)}catch(e){}}
4094
- 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"})
4095
- p.info("Creating new request",{args:e})
4096
- const f=u.startTimer("tool_handler_duration")
4097
- 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)
4093
+ 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"})
4094
+ g.info("Creating new request",{args:e})
4095
+ const p=d.startTimer("tool_handler_duration")
4096
+ 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)
4098
4097
  throw new n.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
4099
- u.incrementCounter("create_request_attempts",1,{type:d.type,criteriaCounts:d.acceptanceCriteria.length})
4100
- const m=t.projectId
4101
- if(!m)throw new n.ValidationError("Project ID is required for creating requests.")
4102
- l.setProjectId(m)
4103
- const y=l.getRequestClient()
4104
- let w=(0,a.getApprovalMode)()
4105
- try{const e=g?.sessionId||(0,c.getCachedSession)()?.sessionId
4106
- if(e){const t=l.getCLISessionClient()
4098
+ d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
4099
+ const f=t.projectId
4100
+ if(!f)throw new n.ValidationError("Project ID is required for creating requests.")
4101
+ c.setProjectId(f)
4102
+ const m=c.getRequestClient()
4103
+ let y=(0,a.getApprovalMode)()
4104
+ try{const e=h?.sessionId
4105
+ if(e){const t=c.getCLISessionClient()
4107
4106
  if(t){const r=await t.getByExternalId(e)
4108
- if(r?.workflowId){const e=await l.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
4109
- 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
4110
- 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 b="require-approval"===w&&"quick-edit"!==d.type?"pending_approval":"open",I={title:d.title,description:d.description,type:d.type,acceptanceCriteria:d.acceptanceCriteria,status:b,...d.planDocumentId&&{planDocumentId:d.planDocumentId},...g&&{cliOrigin:g}}
4111
- p.info("Creating request via request client",{projectId:m,title:d.title,type:d.type,criteriaCount:d.acceptanceCriteria.length})
4112
- const k=await y.createRequest(I)
4113
- p.debug("Create request response structure",{type:typeof k,isArray:Array.isArray(k),hasData:null!=k,properties:k?Object.keys(k):[],dataPreview:k?JSON.stringify(k).substring(0,200)+"...":"null"})
4114
- const v=(0,o.extractDataFromResponse)(k,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
4115
- let _,E={created:!1}
4116
- 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})
4117
- p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
4118
- try{const e=l.getToolRecordClient()
4119
- 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"}`})
4120
- _=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})
4121
- const q=C.localId||C.id
4122
- let S="pending_approval"===b?`Created Request ${q} (pending approval)`:"Created Request "+q
4123
- 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})
4124
- else{const n=l.getToolRecordClient()
4125
- 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]
4107
+ if(r?.workflowId){const e=await c.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
4108
+ 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
4109
+ 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",b={title:l.title,description:l.description,type:l.type,acceptanceCriteria:l.acceptanceCriteria,status:w,...l.planDocumentId&&{planDocumentId:l.planDocumentId},...h&&{cliOrigin:h}}
4110
+ g.info("Creating request via request client",{projectId:f,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
4111
+ const k=await m.createRequest(b)
4112
+ g.debug("Create request response structure",{type:typeof k,isArray:Array.isArray(k),hasData:null!=k,properties:k?Object.keys(k):[],dataPreview:k?JSON.stringify(k).substring(0,200)+"...":"null"})
4113
+ const I=(0,o.extractDataFromResponse)(k,{logger:g,operationName:"createRequest",throwOnNoData:!0}),v="data"in I?I.data:I
4114
+ let C,_={created:!1}
4115
+ 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})
4116
+ g.info("Request created successfully",{requestId:v.id,title:v.title,branchCreated:_.created,branchName:_.branchName})
4117
+ try{const e=c.getToolRecordClient()
4118
+ 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"}`})
4119
+ 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})
4120
+ const E=v.localId||v.id
4121
+ let q="pending_approval"===w?`Created Request ${E} (pending approval)`:"Created Request "+E
4122
+ 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})
4123
+ else{const n=c.getToolRecordClient()
4124
+ 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]
4126
4125
  let t=e.message
4127
4126
  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."
4128
4127
  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}}}
4129
- 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)
4128
+ 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)
4130
4129
  var o=Object.getOwnPropertyDescriptor(t,r)
4131
4130
  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)}
4132
4131
  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)
@@ -4140,7 +4139,7 @@ return o(t,e),t})
4140
4139
  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"})
4141
4140
  try{const s=a.validateArgs(e,i.ModifyFileSchema),{taskId:u,operations:f,comment:m}=s
4142
4141
  p.info("Processing modify-file operations",{taskId:u,operationCount:f.length,comment:m})
4143
- const y=[],w=[],b=[],I=[],k=[]
4142
+ const y=[],w=[],b=[],k=[],I=[]
4144
4143
  for(const e of f){const t={path:e.path,documentId:e.documentId}
4145
4144
  switch(e.operationType){case"replace-string":y.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
4146
4145
  break
@@ -4148,19 +4147,19 @@ case"insert-lines":w.push({...t,insertions:e.insertLines.insertions})
4148
4147
  break
4149
4148
  case"replace-lines":b.push({...t,replacements:e.replaceLines.replacements})
4150
4149
  break
4151
- case"delete-string":I.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
4150
+ case"delete-string":k.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
4152
4151
  break
4153
- case"delete-lines":k.push({...t,lines:e.deleteLines.lines})}}const v=[]
4152
+ case"delete-lines":I.push({...t,lines:e.deleteLines.lines})}}const v=[]
4154
4153
  if(y.length>0){p.info("Routing to replace-strings handler",{operationCount:y.length})
4155
4154
  const e=await(0,c.handleReplaceStrings)({taskId:u,operations:y,comment:m+" [via modify-file: replace-string]"},t,r,n,o,p,h,g)
4156
4155
  v.push({type:"replace-string",result:e})}if(w.length>0){p.info("Routing to insert-lines handler",{operationCount:w.length})
4157
4156
  const e=await(0,l.handleInsertLines)({taskId:u,operations:w,comment:m+" [via modify-file: insert-lines]"},t,r,n,o,p,h,g)
4158
4157
  v.push({type:"insert-lines",result:e})}if(b.length>0){p.info("Routing to replace-lines handler",{operationCount:b.length})
4159
4158
  const e=await(0,d.handleReplaceLines)({taskId:u,operations:b,comment:m+" [via modify-file: replace-lines]"},t,r,n,o,p,h,g)
4160
- v.push({type:"replace-lines",result:e})}if(I.length>0){p.info("Routing delete-string to replace-strings handler",{operationCount:I.length})
4161
- const e=await(0,c.handleReplaceStrings)({taskId:u,operations:I,comment:m+" [via modify-file: delete-string]"},t,r,n,o,p,h,g)
4162
- v.push({type:"delete-string",result:e})}if(k.length>0){p.info("Processing delete-lines operations",{operationCount:k.length})
4163
- const e=k.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)
4159
+ v.push({type:"replace-lines",result:e})}if(k.length>0){p.info("Routing delete-string to replace-strings handler",{operationCount:k.length})
4160
+ const e=await(0,c.handleReplaceStrings)({taskId:u,operations:k,comment:m+" [via modify-file: delete-string]"},t,r,n,o,p,h,g)
4161
+ v.push({type:"delete-string",result:e})}if(I.length>0){p.info("Processing delete-lines operations",{operationCount:I.length})
4162
+ 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)
4164
4163
  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
4165
4164
  let q="## Modify File Results\n\n"
4166
4165
  q+="**Summary:**\n",q+=`- **Total operation types:** ${v.length}\n`,q+=`- **Successful:** ${_}\n`,q+=`- **Failed:** ${E}\n\n`
@@ -4312,55 +4311,9 @@ const i=await t.updateDocument(e.planId,o),a=i.localId||i.id
4312
4311
  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}}}
4313
4312
  const r=t(8824)},7613(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
4314
4313
  const r=t(6183),n=t(9072)
4315
- 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
4316
- if(e.operation!==t.operation)return!1
4317
- if("ask"===e.operation){let r=e.ask||e,n=t.ask||t
4318
- 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
4319
- return!(!o||!s)&&o===s}return!0}async function n(e,t,n,s){const i=n.child({component:"session-discovery"})
4320
- try{const n=e.replace(/\/$/,"")+"/session",o=await fetch(n)
4321
- if(!o.ok)return void i.warn("Failed to get session list",{status:o.status})
4322
- 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)
4323
- if(!d.ok)return void i.warn("Failed to get session status",{status:d.status})
4324
- 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)))]
4325
- let y=null
4326
- const w=[]
4327
- for(const n of m)try{const o=`${e.replace(/\/$/,"")}/session/${n.id}/message?limit=50`,a=await fetch(o)
4328
- if(!a.ok){i.debug("Failed to get messages for session",{sessionId:n.id,status:a.status})
4329
- continue}const c=await a.json()
4330
- let l=0
4331
- for(const e of c){const o=(e.info||e).role||e.role,i=e.parts
4332
- if("assistant"===o&&i)for(const o of i)if("tool"===o.type){const i=o.tool,a=o.state?.status,c=o.sessionID
4333
- if(l++,i&&i.includes(t)){if("running"!==a&&"pending"!==a){w.push({sessionId:n.id,tool:i,reason:"wrong state: "+a})
4334
- 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
4335
- if(l>0&&h>6e4){w.push({sessionId:n.id,tool:i,reason:`stale: running for ${Math.round(h/1e3)}s`})
4336
- continue}if(s&&t&&!r(s,t)){w.push({sessionId:n.id,tool:i,reason:"params mismatch"})
4337
- continue}const g=e.info?.id
4338
- 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+""})
4339
- 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
4314
+ 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
4340
4315
  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)
4341
- 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)
4342
- 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)
4343
- if(!o.ok)return
4344
- const s=await o.json()
4345
- let i,a=0
4346
- for(const e of s){const t=(e.info||e).role||e.role,n=e.parts
4347
- if("assistant"===t&&n)for(const t of n){if("tool"!==t.type)continue
4348
- const n=t.tool,o=t.state?.status
4349
- if(!n?.includes(r))continue
4350
- if("running"!==o&&"pending"!==o)continue
4351
- const s=t.state?.time?.start||0
4352
- 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)
4353
- if(!n.ok)return void t.warn("Failed to get session list",{status:n.status})
4354
- const o=[...await n.json()].sort(((e,t)=>t.time.updated-e.time.updated))
4355
- if(0===o.length)return void t.warn("No sessions found")
4356
- const s=e.replace(/\/$/,"")+"/session/status",i=await fetch(s)
4357
- if(!i.ok)return void t.warn("Failed to get session status",{status:i.status})
4358
- const a=await i.json(),c=o.filter((e=>"busy"===a[e.id]?.type))
4359
- for(const r of c)try{const n=`${e.replace(/\/$/,"")}/session/${r.id}/message?limit=20`,o=await fetch(n)
4360
- if(!o.ok)continue
4361
- const s=await o.json()
4362
- 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+""})}}
4363
- const o=t(8824)},7621(e,exports,t){async function r(e,t,r){const n=r.startTimer("get_current_git_branch_duration")
4316
+ 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")
4364
4317
  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
4365
4318
  const o=await u.getCurrentBranch(e.git,t,r)
4366
4319
  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)
@@ -4454,7 +4407,9 @@ var n=t(2037)
4454
4407
  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}}
4455
4408
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentWorkspaceManager=void 0
4456
4409
  const n=r(t(6928)),o=t(3807),s=t(7634),i=t(8824),a=t(7075),c=t(1387),l=t(4968)
4457
- 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
4410
+ class d{getSession(e){const t=e||d.DEFAULT_SESSION
4411
+ let r=this.sessions.get(t)
4412
+ 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
4458
4413
  const i=a.ConflictResolutionUtils.initializeDetectors(r,t)
4459
4414
  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
4460
4415
  if(!e)return
@@ -4462,73 +4417,81 @@ const t=e.match(/^requests\/(.+)$/)
4462
4417
  if(!t)return void this.logger.warn("ALCHEMY_INITIAL_BRANCH set but not a request branch",{initialBranch:e})
4463
4418
  const r=t[1]
4464
4419
  this.logger.info("ALCHEMY_INITIAL_BRANCH set, switching to worktree",{initialBranch:e,requestId:r})
4465
- 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)
4420
+ try{await this.ensureWorkspaceReady(r)
4421
+ const e=this.getSession()
4422
+ 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)
4466
4423
  if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
4467
4424
  const o=n.sanitized
4468
- try{a.WorkspaceLogging.logOperation(this.logger,"info","Initializing request by creating branch (no worktree yet)",e,"multi-agent","initializeRequest",{requestTitle:t,architecture:"hybrid-creation"})
4469
- const n="requests/"+o,s=await this.mainGit.branch().then((e=>e.all.includes(n)||e.all.includes("remotes/origin/"+n)))
4470
- if(!s){const e=await this.mainGit.revparse(["--abbrev-ref","HEAD"]),t=(await this.mainGit.branch()).all.includes("main")?"main":"master"
4471
- 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")
4472
- const i=Date.now()-r
4473
- 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
4474
- 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)
4475
- if(!r.isValid)throw Error("Invalid request ID: "+r.errors.join(", "))
4476
- const n=r.sanitized
4477
- let s=!1
4478
- if(this.apiClient)try{const e=this.apiClient.getRequestClient(),t=await e.getRequest(n)
4479
- 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})
4480
- const e="requests/"+n
4481
- 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"})
4482
- const e=this.worktreeManager.getWorktreeInfo(n)
4483
- 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"})
4484
- const r=await this.worktreeManager.ensureWorktreeExists(n,void 0,void 0)
4485
- if(!r.success)throw Error("Failed to create worktree: "+r.message)
4486
- 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
4487
- 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"])
4488
- 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
4489
- 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
4490
- 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})
4491
- const r=Date.now(),n=this.getCurrentContext()
4492
- 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)
4493
- const o=a.WorkspaceValidation.validateRequestId(e)
4494
- if(!o.isValid){const t="Invalid request ID: "+o.errors.join(", ")
4495
- 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})
4425
+ try{this.workspaceStates.set(o,"initialized")
4496
4426
  const t=Date.now()-r
4497
- 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
4498
- 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
4499
- 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
4500
- const o=Date.now()-t
4501
- 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
4502
- 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()
4503
- 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()
4504
- if(!this.currentRequestId||!this.currentWorktreePath)throw new a.ConflictDetectionError("No active request context for commit","multi-agent-commit",[])
4505
- try{t&&t.length>0?await this.currentGit.add(t):await this.currentGit.add("."),await this.currentGit.commit(e)
4506
- const n=await this.currentGit.revparse(["HEAD"]),o=Date.now()-r
4507
- 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
4508
- 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()
4427
+ 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
4428
+ 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)
4429
+ if(!s.isValid)throw Error("Invalid request ID: "+s.errors.join(", "))
4430
+ const c=s.sanitized
4431
+ let l=!1
4432
+ if(this.apiClient)try{const e=this.apiClient.getRequestClient(),t=await e.getRequest(c)
4433
+ 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})
4434
+ const e="requests/"+c
4435
+ 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"})
4436
+ const e=this.worktreeManager.getWorktreeInfo(c)
4437
+ 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"})
4438
+ const t=await this.worktreeManager.ensureWorktreeExists(c,void 0,void 0)
4439
+ if(!t.success)throw Error("Failed to create worktree: "+t.message)
4440
+ 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
4441
+ 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"])
4442
+ 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
4443
+ 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
4444
+ 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)
4445
+ this.logger.debug("switchToRequest called",{requestId:e,options:t,sessionId:r})
4446
+ const o=Date.now(),s=this.getCurrentContext(r)
4447
+ 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)
4448
+ const c=a.WorkspaceValidation.validateRequestId(e)
4449
+ if(!c.isValid){const t="Invalid request ID: "+c.errors.join(", ")
4450
+ 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})
4451
+ const t=Date.now()-o
4452
+ 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
4453
+ 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
4454
+ a.WorkspaceLogging.logOperation(this.logger,"info","Switching to completed request (no worktree)",e,"multi-agent","switchToCompletedRequest",{branchName:n}),await this.mainGit.checkout(n)
4455
+ const o=this.getSession()
4456
+ o.requestId=e,o.worktreePath=null,o.git=this.mainGit
4457
+ const s=Date.now()-t
4458
+ 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
4459
+ 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)
4460
+ 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()
4461
+ if(!n.requestId||!n.worktreePath)throw new a.ConflictDetectionError("No active request context for commit","multi-agent-commit",[])
4462
+ try{t&&t.length>0?await n.git.add(t):await n.git.add("."),await n.git.commit(e)
4463
+ const r=await n.git.revparse(["HEAD"]),s=Date.now()-o
4464
+ 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
4465
+ 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()
4509
4466
  try{a.WorkspaceLogging.logOperation(this.logger,"info","Starting request completion (refactored)",e,"multi-agent","completeRequest",{requestTitle:t,skipConflictDetection:r?.skipConflictDetection||!1,architecture:"shared-processor"})
4510
4467
  const o=await this.requestProcessor.completeRequest(e,t,{skipConflictDetection:r?.skipConflictDetection||!1}),s=Date.now()-n
4511
- 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
4512
- 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)
4513
- 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.`
4514
- 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)
4468
+ this.metrics?.recordValue("workspace_complete_duration",s),this.metrics?.incrementCounter("workspace_complete_success",1)
4469
+ for(const[t,r]of this.sessions)r.requestId===e&&(r.requestId=null,r.worktreePath=null,r.git=this.mainGit)
4470
+ 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
4471
+ 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)
4472
+ 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)
4473
+ 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.`
4474
+ 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)
4515
4475
  if(!t.isValid)throw Error("Invalid request ID: "+t.errors.join(", "))
4516
4476
  const r=t.sanitized
4517
- try{this.currentRequestId===r&&await this.switchToMain()
4477
+ try{for(const[e,t]of this.sessions)t.requestId===r&&(t.requestId=null,t.worktreePath=null,t.git=this.mainGit)
4518
4478
  const e=await this.worktreeManager.removeWorktree(r,!1)
4519
4479
  if(!e.success)throw Error(e.message||"Failed to remove worktree")
4520
- 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"}
4521
- 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)
4480
+ 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"}
4481
+ return this.logger.debug("getCurrentContext returning",{context:r,sessionId:e}),r}resetCurrentContext(e){const t=this.getSession(e)
4482
+ 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)
4522
4483
  if(!t.isValid)return null
4523
4484
  const r=t.sanitized,n=await this.getWorktreeInfo(r)
4524
- 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\/(.+)$/)
4525
- 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,"_")
4526
- 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
4527
- this.readonlyBranchCheckDone=!0
4528
- const o=process.env.ALCHEMY_INITIAL_BRANCH
4529
- if(o){const e=o.match(/^requests\/(.+)$/)
4485
+ 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\/(.+)$/)
4486
+ 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,"_")
4487
+ 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)
4488
+ if(s.readonlyBranchCheckDone)return
4489
+ 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)
4490
+ 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
4491
+ if(a){const e=a.match(/^requests\/(.+)$/)
4530
4492
  if(e){const t=e[1]
4531
- 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
4493
+ 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
4494
+ 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
4532
4495
  const r=t(4192),n=t(7163)
4533
4496
  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)+"..."})
4534
4497
  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
@@ -4546,20 +4509,20 @@ return o(t,e),t})
4546
4509
  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"})
4547
4510
  try{const h=a.validateArgs(e,i.ManageFilesSchema),{taskId:g,operations:y,comment:w}=h
4548
4511
  m.info("Processing manage-files operations",{taskId:g,operationCount:y.length,comment:w})
4549
- const b=[],I=[],k=[],v=[]
4512
+ const b=[],k=[],I=[],v=[]
4550
4513
  for(const e of y)switch(e.operationType){case"create-directory":b.push({path:e.createDirectory.path})
4551
4514
  break
4552
- case"move-files":for(const t of e.moveFiles.moves)I.push(t)
4515
+ case"move-files":for(const t of e.moveFiles.moves)k.push(t)
4553
4516
  break
4554
- case"delete-files":k.push(...e.deleteFiles.targets)
4517
+ case"delete-files":I.push(...e.deleteFiles.targets)
4555
4518
  break
4556
4519
  case"get-file-info":v.push({path:e.getFileInfo.path})}const C=[]
4557
4520
  for(const e of b){m.info("Routing to create-directory handler",{path:e.path})
4558
4521
  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)
4559
- C.push({type:"create-directory",result:s})}if(I.length>0){m.info("Routing to move-files handler",{operationCount:I.length})
4560
- const e=await(0,l.handleMoveFiles)({taskId:g,operations:I,comment:w+" [via manage-files: move-files]"},t,r,n,o,m,p,f)
4561
- C.push({type:"move-files",result:e})}if(k.length>0){m.info("Routing to delete-files handler",{operationCount:k.length})
4562
- const e=await(0,u.handleDeleteFiles)({taskId:g,operations:k,comment:w+" [via manage-files: delete-files]"},t,s,m,p,f)
4522
+ C.push({type:"create-directory",result:s})}if(k.length>0){m.info("Routing to move-files handler",{operationCount:k.length})
4523
+ const e=await(0,l.handleMoveFiles)({taskId:g,operations:k,comment:w+" [via manage-files: move-files]"},t,r,n,o,m,p,f)
4524
+ C.push({type:"move-files",result:e})}if(I.length>0){m.info("Routing to delete-files handler",{operationCount:I.length})
4525
+ const e=await(0,u.handleDeleteFiles)({taskId:g,operations:I,comment:w+" [via manage-files: delete-files]"},t,s,m,p,f)
4563
4526
  C.push({type:"delete-files",result:e})}for(const e of v){m.info("Routing to get-file-info handler",{path:e.path})
4564
4527
  const r=await(0,d.handleGetFileInfo)({path:e.path},t,m,p)
4565
4528
  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
@@ -4649,19 +4612,19 @@ const n=r(t(6982))
4649
4612
  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")
4650
4613
  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
4651
4614
  if(e.includes("_")){const t=e.split("_")
4652
- 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
4615
+ 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
4653
4616
  try{const s={...process.env}
4654
- l&&(s.OPENCODE_PARENT_SERVER=l),g&&(s.ALCHEMY_INITIAL_BRANCH=g),e.allowParallel&&(s.ALCHEMY_ALLOW_PARALLEL="1")
4655
- 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)
4656
- let w
4657
- 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))
4658
- 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})
4659
- const b=(0,a.join)(c||process.cwd(),".alchemy_lab"),I=(0,a.join)(b,"spawn-stderr.log")
4660
- let k
4661
- try{k=(0,i.openSync)(I,"a")}catch{}const v=(0,o.spawn)("opencode",w,{detached:!0,stdio:["ignore","ignore",k??"ignore"],cwd:c||process.cwd(),env:s})
4662
- return v.unref(),f&&f(v.pid),{success:!0,pid:v.pid}}catch(e){const t=(0,s.getErrorMessage)(e)
4663
- 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})}
4664
- 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")
4617
+ d&&(s.OPENCODE_PARENT_SERVER=d),p&&(s.ALCHEMY_INITIAL_BRANCH=p),e.allowParallel&&(s.ALCHEMY_ALLOW_PARALLEL="1")
4618
+ 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)
4619
+ let b
4620
+ 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}),b=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=b.findIndex((e=>e===n))
4621
+ e>0?b.splice(e,0,"--model",g):b.push("--model",g)}r(l,"Spawning opencode",{args:b.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})
4622
+ const k=(0,a.join)(l||process.cwd(),".alchemy_lab"),I=(0,a.join)(k,"spawn-stderr.log")
4623
+ let v
4624
+ try{v=(0,i.openSync)(I,"a")}catch{}const C=(0,c.resolveRunCommand)(),_=(0,o.spawn)(C.command,[...C.prependArgs,...b],{detached:!0,stdio:["ignore","ignore",v??"ignore"],cwd:l||process.cwd(),env:s})
4625
+ return _.unref(),m&&m(_.pid),{success:!0,pid:_.pid}}catch(e){const t=(0,s.getErrorMessage)(e)
4626
+ 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})}
4627
+ 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")
4665
4628
  try{const{filters:s={}}=e,a=["open","in_progress","ready_for_review","completed","canceled","reverted"]
4666
4629
  if(s.status&&!a.includes(s.status))throw new r.ValidationError(`Invalid status: ${s.status}. Must be one of: ${a.join(", ")}`)
4667
4630
  if(void 0!==s.limit&&1>s.limit)throw new r.ValidationError("Limit must be at least 1")
@@ -4737,31 +4700,31 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
4737
4700
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
4738
4701
  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()
4739
4702
  let y,w,b=d.FileOperationPhase.VALIDATION
4740
- 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}"}
4703
+ const k={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}"}
4741
4704
  try{const s=d.validateArgs(e,l.CreateDirectorySchema),{taskId:u,path:h,comment:g}=s
4742
- f.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,f,i,I.metricsPrefix),t.getCurrentBranchContext&&await t.getCurrentBranchContext()
4743
- const{normalizedPath:k,fullPath:v}=d.validateAndNormalizePath(h,t)
4705
+ f.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,f,i,k.metricsPrefix),t.getCurrentBranchContext&&await t.getCurrentBranchContext()
4706
+ const{normalizedPath:I,fullPath:v}=d.validateAndNormalizePath(h,t)
4744
4707
  b=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("create_directory_phase",1,{phase:b})
4745
- const C=await d.validateTaskId(u,k,r,f,i,I.metricsPrefix),_=C?.requestId,E=await d.validateWorkItemStates(u,k,r,o,t,f,i,I.metricsPrefix),q=await d.autoPromoteTaskStatus(u,C.status,_,E.request?.status,k,r,o,f,i,I.metricsPrefix)
4746
- 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:k}),q.requestPromoted&&f.info(`Auto-promoted request ${_} to in_progress for file operation`,{requestId:_,previousStatus:E.request?.status,newStatus:q.newRequestStatus,triggeringTaskId:u})
4747
- const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:f,metrics:i,metricsPrefix:I.metricsPrefix})
4708
+ const C=await d.validateTaskId(u,I,r,f,i,k.metricsPrefix),_=C?.requestId,E=await d.validateWorkItemStates(u,I,r,o,t,f,i,k.metricsPrefix),q=await d.autoPromoteTaskStatus(u,C.status,_,E.request?.status,I,r,o,f,i,k.metricsPrefix)
4709
+ 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})
4710
+ const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:f,metrics:i,metricsPrefix:k.metricsPrefix})
4748
4711
  if(!S.success){if(S.isLockConflict)return{content:[{type:"text",text:"\u274c "+S.error}],isError:!0}
4749
4712
  throw Error(S.error)}let T=!1
4750
4713
  try{T=(await a.default.stat(v)).isDirectory()}catch{T=!1}b=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("create_directory_phase",1,{phase:b})
4751
- const{toolRecordId:P,localToolRecordId:R}=await d.createFileOperationRecords(u,_,t.projectId,I.recordType,k,{directoryExists:T,userComment:g},r,n,f,i,I.metricsPrefix,p)
4752
- y=P,w=P,b=I.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:b})
4714
+ const{toolRecordId:P,localToolRecordId:R}=await d.createFileOperationRecords(u,_,t.projectId,k.recordType,I,{directoryExists:T,userComment:g},r,n,f,i,k.metricsPrefix,p)
4715
+ y=P,w=P,b=k.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:b})
4753
4716
  let M=T
4754
- if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+k)
4717
+ if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+I)
4755
4718
  try{const e=c.default.join(v,".gitkeep")
4756
4719
  await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),M=!0,f.info("Created .gitkeep file for Git tracking")}catch(e){f.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),M=!1}}const j=Date.now()-m
4757
4720
  i.recordValue("create_directory_time",j),i.incrementCounter("create_directory_success",1),b=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("create_directory_phase",1,{phase:b})
4758
- const x=`Create directory: ${k} - ${g||"Create directory"}`,O=!T&&M?k+"/.gitkeep":k,D=await d.commitToGit(u,O,P,R,x,t,f,i,I.metricsPrefix)
4759
- b=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:b}),await d.updateFileOperationRecords(u,y,w,k,I.recordType,`Successfully ${T?"verified":"created"} directory: ${k}`,{status:"completed",commitHash:D.commitHash,previousCommitHash:D.previousCommitHash,directoryExists:T,isDirectory:!0,userComment:g},`Successfully ${T?"verified":"created"} directory: ${k}`,r,n,f,i,I.metricsPrefix)
4721
+ const x=`Create directory: ${I} - ${g||"Create directory"}`,O=!T&&M?I+"/.gitkeep":I,D=await d.commitToGit(u,O,P,R,x,t,f,i,k.metricsPrefix)
4722
+ b=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:b}),await d.updateFileOperationRecords(u,y,w,I,k.recordType,`Successfully ${T?"verified":"created"} directory: ${I}`,{status:"completed",commitHash:D.commitHash,previousCommitHash:D.previousCommitHash,directoryExists:T,isDirectory:!0,userComment:g},`Successfully ${T?"verified":"created"} directory: ${I}`,r,n,f,i,k.metricsPrefix)
4760
4723
  const A=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
4761
4724
  return{content:[{type:"text",text:T?"Directory already exists":`Successfully created directory${D.commitHash?"\nCommit: "+D.commitHash.substring(0,8):""}${A.requestId?"\nBranch: "+A.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
4762
4725
  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:b,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
4763
4726
  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){b=d.FileOperationPhase.RECORD_UPDATE_FAILURE
4764
- 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,b,f,i,e,I)}}
4727
+ try{await d.updateFileOperationRecords(e.taskId,y,w,e.path,k.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,k.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,b,f,i,e,k)}}
4765
4728
  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=[]
4766
4729
  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"
4767
4730
  case"replace-in-files":return"\u{1f504} Replace in Files"
@@ -4970,34 +4933,34 @@ return i(t,e),t})
4970
4933
  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()
4971
4934
  try{let o
4972
4935
  try{o=d.FileHistorySchema.parse(e)}catch(t){if(t instanceof u.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
4973
- 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:b,branch:I,commit:k,since:v}=o
4974
- return k?(i.info("Getting diff for specific commit",{filePath:a,commit:k}),await async function(e,t,r,n){const o=r.git,s=c.normalize(e).replace(/\\/g,"/")
4936
+ 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:b,branch:k,commit:I,since:v}=o
4937
+ 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,"/")
4975
4938
  if(n.info("Getting full diff for commit",{filePath:e,commit:t}),!o)return{content:[{type:"text",text:"\u274c Git not initialized"}],isError:!0}
4976
4939
  try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
4977
4940
  if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
4978
4941
  const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
4979
4942
  let a="# File History - Commit Diff\n\n"
4980
- 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,k,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:y,showDiff:w,showTraceability:b,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)
4943
+ 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:b,branch:k}),await async function(e,t,n,o,s,i,a,c,d,u,p){try{const{normalizedPath:m,fullPath:y}=f.validateAndNormalizePath(e,a)
4981
4944
  try{await l.access(y)}catch(e){throw Error("File not found: "+m)}const w=a.git
4982
4945
  if(!w)throw Error("Git is not available in this context")
4983
4946
  let b={branch:null,requestId:null,isMain:!0}
4984
- if(a.getCurrentBranchContext)try{b=await a.getCurrentBranchContext(),d.info("Current branch context detected",{branch:b.branch,requestId:b.requestId,isMain:b.isMain})}catch(e){d.warn("Could not get current branch context",{error:e})}let I=[],k=""
4985
- if(s)I=await r(w,m,t,n,o,s,i,c,d,u),k=`## File History: ${m} (Branch: ${s})\n\n`
4947
+ if(a.getCurrentBranchContext)try{b=await a.getCurrentBranchContext(),d.info("Current branch context detected",{branch:b.branch,requestId:b.requestId,isMain:b.isMain})}catch(e){d.warn("Could not get current branch context",{error:e})}let k=[],I=""
4948
+ if(s)k=await r(w,m,t,n,o,s,i,c,d,u),I=`## File History: ${m} (Branch: ${s})\n\n`
4986
4949
  else{if(b.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)}]}
4987
4950
  if(b.requestId)return d.info("Showing operation-level detail on request branch",{requestId:b.requestId}),{content:[{type:"text",text:await(0,g.getOperationDetailForFile)(m,b.requestId,c,d,u)}]}
4988
4951
  {const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
4989
4952
  if(!i.isMain&&i.branch){const g=await r(e,t,n,o,s,i.branch,a,c,l,d)
4990
4953
  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)))
4991
4954
  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,b,i,c,d,u)
4992
- I=e.versions,k=`## File History: ${m} (Combined View)\n\n`,k+=`**Current Context:** ${b.isMain?"main":`${b.branch} (${b.requestId})`}\n`,k+=`**History Sources:** ${e.sources.join(", ")}\n\n`}}if(0===I.length)return k+="\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:k}]}
4993
- const v=I.length,C=Math.min(I.length,t)
4994
- v>t?k+=`\u{1f4ca} **Summary:** ${v} versions found, showing ${C} most recent\n\n`:v>0&&(k+=`\u{1f4ca} **Summary:** ${v} version${v>1?"s":""} found\n\n`),k+=`**Total Versions:** ${I.length}\n`,k+="**Current File Size:** "
4995
- try{k+=(await l.stat(y)).size+" bytes\n"}catch{k+="Unknown\n"}k+="\n"
4996
- for(let e=0;e<I.length;e++){const t=I[e]
4997
- if(k+=`### Version ${e+1} (${t.hash.substring(0,8)})\n`,t.branch&&(k+=`- **Branch:** ${t.branch}\n`),k+=`- **Author:** ${t.author}\n`,k+=`- **Date:** ${t.date}\n`,k+=`- **Message:** ${t.message}\n`,o&&t.traceability&&(k+=`\n${(0,h.formatTraceabilityInfo)(t.traceability)}\n`),n&&t.diff){const e=t.diff.split("\n")
4955
+ k=e.versions,I=`## File History: ${m} (Combined View)\n\n`,I+=`**Current Context:** ${b.isMain?"main":`${b.branch} (${b.requestId})`}\n`,I+=`**History Sources:** ${e.sources.join(", ")}\n\n`}}if(0===k.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}]}
4956
+ const v=k.length,C=Math.min(k.length,t)
4957
+ 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:** ${k.length}\n`,I+="**Current File Size:** "
4958
+ try{I+=(await l.stat(y)).size+" bytes\n"}catch{I+="Unknown\n"}I+="\n"
4959
+ for(let e=0;e<k.length;e++){const t=k[e]
4960
+ 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")
4998
4961
  let r=0,n=0
4999
4962
  for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
5000
- k+=`\n**Changes:**${r>0||n>0?` (Added ${r} lines, removed ${n} lines)`:""}\n\`\`\`diff\n${t.diff}\n\`\`\`\n`}k+="\n"}return k+="\u{1f4a1} **Tips:**\n",k+="- Use `file-recover` with a commit hash to restore the file to a previous version\n",k+='- Use `{"branch": "main"}` to see only main branch history\n',k+='- 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:b.branch,duration:Date.now()-p}),u.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:k}]}}catch(e){throw e}}(a,y,w,b,I,v,t,n,i,s,m))}catch(e){const t=Date.now()-m
4963
+ 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:k.length,targetBranch:s,currentBranch:b.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,b,k,v,t,n,i,s,m))}catch(e){const t=Date.now()-m
5001
4964
  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}}}
5002
4965
  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
5003
4966
  const r=t(6183),n=t(6891)
@@ -5133,7 +5096,14 @@ if(!o.ok)return void this.logger.debug("Polling response not ok",{status:o.statu
5133
5096
  const i=await o.json()
5134
5097
  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")
5135
5098
  const e=this.parseTokenResponse(i.data)
5136
- 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)
5099
+ 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
5100
+ if(e)return e
5101
+ try{const e=Object(function(){var e=Error("Cannot find module 'alchemylab-opencode/package.json'")
5102
+ throw e.code="MODULE_NOT_FOUND",e}())
5103
+ 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()
5104
+ return e?n((0,o.join)(e,"packages","opencode","src"),"serve.ts"):{command:"opencode",prependArgs:["serve"]}},exports.resolveRunCommand=function(){const e=r()
5105
+ return e?n((0,o.join)(e,"packages","opencode","src"),"run.ts"):{command:"opencode",prependArgs:[]}}
5106
+ const o=t(6928)},9072(e,exports,t){async function r(e,t,r,n){try{const o=await(0,d.getServerUrl)(r,n)
5137
5107
  if(!o)return n.warn("Could not get server URL for notification",{sessionId:e}),!1
5138
5108
  let s,i
5139
5109
  try{const t=`http://localhost:${g}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
@@ -5142,27 +5112,23 @@ e.success&&e.agentType&&(s=e.agentType)}}catch(t){n.warn("Agent type lookup fail
5142
5112
  if(e.ok){const t=await e.json()
5143
5113
  if(t.data?.defaultModel){const[e,...r]=t.data.defaultModel.split("/")
5144
5114
  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}:{}})})
5145
- 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()
5146
- if(o?.sessionId)return(0,h.logSessionIdentity)(""+r,"identity-cache",{sessionId:o.sessionId}),o.sessionId
5147
- const s=await(0,d.getServerUrl)(e,t)
5148
- if(!s)throw new c.ValidationError("Could not determine OpenCode server URL")
5149
- const i=await(0,d.getAndStoreSessionId)(s,t,r,n),a=i?.sessionId
5150
- if(!a)throw new c.ValidationError("Could not discover current session ID. Make sure you are running within an OpenCode session.")
5151
- return(0,h.logSessionIdentity)(""+r,"per-call-discovery",{sessionId:a}),a}function s(e){const t=[],r=e.content||{}
5115
+ 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()
5116
+ if(!n?.sessionId)throw new c.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
5117
+ return(0,h.logSessionIdentity)(""+r,"identity",{sessionId:n.sessionId}),n.sessionId}function s(e){const t=[],r=e.content||{}
5152
5118
  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:**")
5153
5119
  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||{}
5154
- 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"})
5155
- if(!m)throw new c.ValidationError("API client not available")
5156
- const{operation:w}=e
5157
- y.info("Session message operation",{operation:w}),f.incrementCounter("session_message_operations",1,{operation:w})
5158
- try{switch(w){case"send":if(!e.type)throw new c.ValidationError('send operation requires type ("question" or "report")')
5120
+ 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"})
5121
+ if(!f)throw new c.ValidationError("API client not available")
5122
+ const{operation:y}=e
5123
+ m.info("Session message operation",{operation:y}),p.incrementCounter("session_message_operations",1,{operation:y})
5124
+ try{switch(y){case"send":if(!e.type)throw new c.ValidationError('send operation requires type ("question" or "report")')
5159
5125
  return await async function(e,t,a,l){const{type:d}=e
5160
5126
  if(!d)throw new c.ValidationError('send operation requires type ("question" or "report")')
5161
5127
  const u=l.getSessionMessageClient()
5162
5128
  if(!u)throw new c.ValidationError("Session message client not available")
5163
5129
  if("question"===d)return await async function(e,t,i,a,l){const{toSessionId:d,questionType:u,questionContent:h,priority:g,expiresInHours:p}=e
5164
5130
  if(!u||!h?.question)throw new c.ValidationError("Question requires questionType and questionContent.question")
5165
- 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)
5131
+ 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)
5166
5132
  if(!e)throw new c.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
5167
5133
  return o.info('Resolved toSessionId "parent" to actual ID',{parentId:e}),e}return e}(d,f,a,i)
5168
5134
  if(!("alternatives"!==u||h.options&&Array.isArray(h.options)))throw new c.ValidationError("Alternatives questions require options array")
@@ -5174,7 +5140,7 @@ if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&
5174
5140
  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)
5175
5141
  if("report"===d)return await async function(e,t,s,a,l){const{status:d,summary:u,details:h,finish:p}=e
5176
5142
  if(!d||!u)throw new c.ValidationError("Report requires status and summary")
5177
- 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
5143
+ 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
5178
5144
  const t=await n(f,a,s)
5179
5145
  if(!t)throw new c.ValidationError("Could not find parent session. This tool should only be used by subagent sessions.")
5180
5146
  return s.info("Auto-resolved parent session",{parentSessionId:t}),t})()
@@ -5186,7 +5152,7 @@ if(e.ok){const t=await e.json()
5186
5152
  t.success&&t.agentType&&(w=t.agentType)}}catch{}const b=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]
5187
5153
  return r.details&&(n.push(""),n.push(r.details)),n.join("\n")}(y,w),t,s)
5188
5154
  return{content:[{type:"text",text:`\u2705 Report submitted.${b?"\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)
5189
- throw new c.ValidationError(`Unknown message type: ${d}. Use "question" or "report".`)}(e,t,y,m)
5155
+ throw new c.ValidationError(`Unknown message type: ${d}. Use "question" or "report".`)}(e,t,m,f)
5190
5156
  case"reply":if(!e.messageCode)throw new c.ValidationError("reply operation requires messageCode")
5191
5157
  return await async function(e,t,n,o){const{messageCode:a}=e
5192
5158
  if(!a)throw new c.ValidationError("reply operation requires messageCode")
@@ -5197,26 +5163,24 @@ n.info("Answering question",{messageCode:a,respondedBySessionId:o})
5197
5163
  const u=await l.answerQuestion(a,{respondedBySessionId:o,text:i,selectedOptions:c,notes:d})
5198
5164
  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]
5199
5165
  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))}]}
5200
- throw new c.ValidationError(`Cannot determine message type from code "${a}". Expected Q-xxx (question) or R-xxx (report).`)}(e,t,y,m)
5201
- case"offer-handoff":{const r=e.offerHandoff||{summary:e.summary||"",requestIds:e.requestIds||[]}
5202
- let s=null,i=null
5203
- 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()
5204
- 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()
5205
- if(e&&s){const t=r.requestIds?.length||0
5206
- 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
5166
+ throw new c.ValidationError(`Cannot determine message type from code "${a}". Expected Q-xxx (question) or R-xxx (report).`)}(e,t,m,f)
5167
+ case"offer-handoff":{const t=e.offerHandoff||{summary:e.summary||"",requestIds:e.requestIds||[]}
5168
+ let r=null,s=null
5169
+ 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()
5170
+ if(e&&r){const n=t.requestIds?.length||0
5171
+ 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
5207
5172
  const m=n.getSessionMessageClient()
5208
5173
  if(!m)throw new c.ValidationError("Session message client not available")
5209
- if(!o){const e=await(0,d.getServerUrl)(t,r)
5210
- if(!e)return{content:[{type:"text",text:"\u26a0\ufe0f Could not connect to OpenCode server. Unable to list messages without a session context."}]}
5211
- {const t={operation:"list",list:{messageType:s,direction:i,status:l}},n=await(0,d.getAndStoreSessionId)(e,r,"session_message_operations",t)
5212
- 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})
5174
+ if(!o){const e=u.sessionIdentity.getIdentity()
5175
+ 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."}]}
5176
+ 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})
5213
5177
  const y={sessionId:o,direction:i,limit:p,offset:f}
5214
- 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)
5178
+ 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)
5215
5179
  const w=await m.listMessages(y)
5216
5180
  if(0===w.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
5217
5181
  const b=[`Found ${w.length} message(s):\n`]
5218
5182
  for(const e of w)b.push("---\n"),b.push(a(e)),b.push("")
5219
- return{content:[{type:"text",text:b.join("\n")}]}}(e.list||{},t,y,m)
5183
+ return{content:[{type:"text",text:b.join("\n")}]}}(e.list||{},0,m,f)
5220
5184
  case"get":if(!e.messageCode)throw new c.ValidationError("get operation requires messageCode")
5221
5185
  return await async function(e,t,r){const{messageCode:n}=e
5222
5186
  if(!n)throw new c.ValidationError("get operation requires messageCode")
@@ -5224,8 +5188,8 @@ const o=r.getSessionMessageClient()
5224
5188
  if(!o)throw new c.ValidationError("Session message client not available")
5225
5189
  t.debug("Getting message",{messageCode:n})
5226
5190
  const s=await o.getMessage(n)
5227
- return s?{content:[{type:"text",text:a(s)}]}:{content:[{type:"text",text:`\u274c Message with code ${n} not found.`}],isError:!0}}(e,y,m)
5228
- 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}}}
5191
+ return s?{content:[{type:"text",text:a(s)}]}:{content:[{type:"text",text:`\u274c Message with code ${n} not found.`}],isError:!0}}(e,m,f)
5192
+ 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}}}
5229
5193
  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
5230
5194
  const r=t(6183),n=t(1281)
5231
5195
  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()
@@ -5329,10 +5293,10 @@ continue}const t=(0,h.findMatches)(s,n,m,100,e.path)
5329
5293
  if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(m?" (tried fuzzy matching)":""),a.success=!1
5330
5294
  const e=(0,h.findSimilarMatches)(s,n,5,.3)
5331
5295
  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,b.getErrorMessage)(e),a.success=!1,y.failedReplacements++}y.replacements.push(a)}let w=s
5332
- const I=[]
5333
- for(const e of p)for(const t of e.matches)I.push({match:t,newText:e.newText,repResult:e.repResult})
5334
- I.sort(((e,t)=>t.match.startPos-e.match.startPos))
5335
- 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++)
5296
+ const k=[]
5297
+ for(const e of p)for(const t of e.matches)k.push({match:t,newText:e.newText,repResult:e.repResult})
5298
+ k.sort(((e,t)=>t.match.startPos-e.match.startPos))
5299
+ for(const{match:e,newText:t,repResult:n}of k)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++)
5336
5300
  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,b.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)
5337
5301
  var o=Object.getOwnPropertyDescriptor(t,r)
5338
5302
  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=[]
@@ -5341,47 +5305,47 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
5341
5305
  var t={}
5342
5306
  if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
5343
5307
  return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
5344
- 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"}),k=Date.now()
5308
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFiles=async function(e,t,r,o,s,i,a,c){const k=i.child({tool:"replace_in_files"}),I=Date.now()
5345
5309
  let v,C=u.FileOperationPhase.VALIDATION
5346
5310
  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)
5347
5311
  const i=u.validateArgs(e,d.ReplaceInFilesSchema),{taskId:_,operations:E,fuzzy_match:q=!0,comment:S}=i
5348
- 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})
5312
+ k.info("Replace in files batch operation",{taskId:_,operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,comment:S})
5349
5313
  const T=E.filter((e=>e.documentId)).map((e=>e.documentId))
5350
- 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}
5314
+ if(T.length>0&&t.apiClient)try{await(0,m.ensureDocumentsNotLocked)(T,t.apiClient,k,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5351
5315
  throw e}C=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5352
5316
  const P=E[0],R=P.documentId?"document:"+P.documentId:P.path
5353
5317
  let M=Date.now()
5354
- const j=await u.validateTaskId(_,R,r,I,a,"replace_in_files")
5318
+ const j=await u.validateTaskId(_,R,r,k,a,"replace_in_files")
5355
5319
  Date.now()
5356
5320
  const x=j?.requestId,O=E.some((e=>e.path))
5357
5321
  let D=!1
5358
5322
  if(O&&x){M=Date.now()
5359
- const e=await u.validateWorkItemStates(_,R,r,s,t,I,a,"replace_in_files")
5323
+ const e=await u.validateWorkItemStates(_,R,r,s,t,k,a,"replace_in_files")
5360
5324
  Date.now(),M=Date.now()
5361
- const n=await u.autoPromoteTaskStatus(_,j.status,x,e.request?.status,R,r,s,I,a,"replace_in_files")
5362
- n.taskPromoted&&I.info("Auto-promoted task to in_progress",{taskId:_,requestId:x,previousStatus:j.status,newStatus:n.newTaskStatus}),Date.now(),M=Date.now()
5363
- const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:x,context:t,operation:"replace_in_files",logger:I,metrics:a,metricsPrefix:"replace_in_files"})
5325
+ const n=await u.autoPromoteTaskStatus(_,j.status,x,e.request?.status,R,r,s,k,a,"replace_in_files")
5326
+ n.taskPromoted&&k.info("Auto-promoted task to in_progress",{taskId:_,requestId:x,previousStatus:j.status,newStatus:n.newTaskStatus}),Date.now(),M=Date.now()
5327
+ const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:x,context:t,operation:"replace_in_files",logger:k,metrics:a,metricsPrefix:"replace_in_files"})
5364
5328
  if(!o.success){if(o.isLockConflict)return{content:[{type:"text",text:"\u274c "+o.error}],isError:!0}
5365
- throw Error(o.error)}Date.now(),D=!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}
5329
+ throw Error(o.error)}Date.now(),D=!0}if(T.length>0&&x)try{await(0,p.validateRequestStatusForDocumentOperation)(x,s,k,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5366
5330
  throw e}M=Date.now()
5367
5331
  const A=new Map
5368
- 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=[]
5332
+ if(k.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=[]
5369
5333
  for(const t of e.replacements){const r=(0,h.findMatches)(n,t.old,o,100,e.path)
5370
5334
  s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,r.fullPath)
5371
- I.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
5372
- const i=await(0,w.detectExternalEdits)(t.git,o,I)
5373
- I.info("\u{1f50d} External edit detection result",{path:r.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(A.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&&A.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}),A.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,b.getErrorMessage)(t)})}if(Date.now(),M=Date.now(),O&&t.git)try{I.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
5374
- const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},I,a)
5375
- 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(),M=Date.now(),C=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5376
- const{toolRecordId:$}=await u.createFileOperationRecords(_,x,t.projectId,"replace-in-files",R,{operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,userComment:S},r,o,I,a,"replace_in_files",c)
5335
+ k.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
5336
+ const i=await(0,w.detectExternalEdits)(t.git,o,k)
5337
+ k.info("\u{1f50d} External edit detection result",{path:r.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(A.set(e.path,{message:i.message,debugInfo:i.debugInfo}),k.warn("\u26a0\ufe0f External edits detected before auto-commit",{path:r.normalizedPath,conflictingLines:i.conflictingLines})):(i.debugInfo&&A.set(e.path,{message:"",debugInfo:i.debugInfo}),k.info("\u2705 No external edit conflicts detected",{path:r.normalizedPath}))}else k.info("\u2139\ufe0f No matches found for external edit detection",{path:r.normalizedPath}),A.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){k.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,b.getErrorMessage)(t)})}if(Date.now(),M=Date.now(),O&&t.git)try{k.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
5338
+ const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},k,a)
5339
+ e.userChangesCommitted&&(k.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),k.info("User changes committed before batch operation",{taskId:_,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){k.warn("Pre-tool user changes commit failed",{taskId:_,error:e instanceof Error?e.message:e+""})}Date.now(),M=Date.now(),C=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5340
+ const{toolRecordId:$}=await u.createFileOperationRecords(_,x,t.projectId,"replace-in-files",R,{operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,userComment:S},r,o,k,a,"replace_in_files",c)
5377
5341
  v=$,Date.now(),M=Date.now(),C=u.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5378
5342
  const F=[],N=[]
5379
5343
  for(const e of E){const r=e.path?A.get(e.path):void 0,o=await n(e,q,t,0,0,r?.message,r?.debugInfo)
5380
5344
  F.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&N.push(o.path)}Date.now(),M=Date.now()
5381
- 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
5345
+ 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:k,metrics:a,metricsPrefix:"replace_in_files"},t),B=z.commitHash
5382
5346
  Date.now(),Date.now()
5383
5347
  const H=F.filter((e=>e.success)).length,U=F.length-H,W=F.reduce(((e,t)=>e+t.successfulReplacements),0),G=F.reduce(((e,t)=>e+t.failedReplacements),0),V=F.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,replacements:e.replacements.map((e=>({old_str:e.old,new_str:e.new,success:e.success,error:e.error,matchesFound:e.matchesFound,matchType:e.matchType,lines:e.lines})))}))),J=F.filter((e=>e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements}))),K=F.filter((e=>!e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,error:e.error,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements})))
5384
- await o.updateToolRecord(v,{metadata:{path:R,status:0===U?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:K,successfulReplacements:W,failedReplacements:G,processingTime:Date.now()-k,userComment:S,...z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}}})
5348
+ await o.updateToolRecord(v,{metadata:{path:R,status:0===U?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:K,successfulReplacements:W,failedReplacements:G,processingTime:Date.now()-I,userComment:S,...z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}}})
5385
5349
  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
5386
5350
  let l="## Replace In Files - Batch Results\n\n"
5387
5351
  if(o.getCurrentBranchContext)try{const e=await o.getCurrentBranchContext()
@@ -5394,8 +5358,8 @@ for(const e of o)l+=`- \u2705 \`${e.old.substring(0,40)}${e.old.length>40?"...":
5394
5358
  if(s.length>0){l+="\n**Failed Replacement Details:**\n"
5395
5359
  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)))
5396
5360
  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,W,G,t,v)
5397
- return{content:[{type:"text",text:Y}],isError:0===W}}catch(e){const t=Date.now()-k
5398
- 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,b.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,b.getErrorMessage)(e)}],isError:!0}}}
5361
+ return{content:[{type:"text",text:Y}],isError:0===W}}catch(e){const t=Date.now()-I
5362
+ if(k.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,b.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,b.getErrorMessage)(e)}],isError:!0}}}
5399
5363
  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),b=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")
5400
5364
  const t=e.trim()
5401
5365
  if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
@@ -5451,14 +5415,14 @@ if(n)s.WorkspaceLogging.logOperation(this.logger,"info","Branch already exists,
5451
5415
  else{const t=await this.git.revparse(["--abbrev-ref","HEAD"]),r=await this.gitAdapter.branchManager.getBaseBranch()
5452
5416
  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
5453
5417
  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
5454
- 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)
5455
- if(!r.isValid)throw Error("Invalid request ID: "+r.errors.join(", "))
5456
- const n=r.sanitized,i="requests/"+n,a=await this.git.revparse(["--abbrev-ref","HEAD"])
5457
- if(a===i)return this.currentRequestId=n,this.currentBranch=i,void this.logger.debug("Workspace already ready",{requestId:n,currentBranch:this.currentBranch})
5458
- 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?`)
5459
- 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
5460
- 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
5461
- 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)
5418
+ 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)
5419
+ if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
5420
+ const i=n.sanitized,a="requests/"+i,c=await this.git.revparse(["--abbrev-ref","HEAD"])
5421
+ if(c===a)return this.currentRequestId=i,this.currentBranch=a,void this.logger.debug("Workspace already ready",{requestId:i,currentBranch:this.currentBranch})
5422
+ 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?`)
5423
+ 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
5424
+ 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
5425
+ 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)
5462
5426
  if(!i.isValid){const t="Invalid request ID: "+i.errors.join(", ")
5463
5427
  throw s.WorkspaceLogging.logOperation(this.logger,"error",t,e,"single-agent","switchToRequest"),Error(t)}const a=i.sanitized
5464
5428
  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"})
@@ -5468,13 +5432,13 @@ const o=Date.now()-r
5468
5432
  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
5469
5433
  this.metrics.recordValue("workspace.switch",n)
5470
5434
  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}`
5471
- 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()
5472
- try{const r=await this.gitAdapter.branchManager.getBaseBranch(),n=await this.gitAdapter.branchManager.switchToBranch(r)
5435
+ 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()
5436
+ try{const e=await this.gitAdapter.branchManager.getBaseBranch(),n=await this.gitAdapter.branchManager.switchToBranch(e)
5473
5437
  if(!n.success)throw Error("Failed to switch to main branch: "+n.error)
5474
- this.currentBranch=r,this.currentRequestId=null
5475
- const o=Date.now()-e
5476
- 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
5477
- 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()
5438
+ this.currentBranch=e,this.currentRequestId=null
5439
+ const o=Date.now()-t
5440
+ 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
5441
+ 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()
5478
5442
  try{t&&t.length>0?await this.git.add(t):await this.git.add("."),await this.git.commit(e)
5479
5443
  const n=await this.git.revparse(["HEAD"]),o=Date.now()-r
5480
5444
  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
@@ -5482,33 +5446,32 @@ throw this.metrics.recordValue("workspace.commit",n),this.logger.error("Failed t
5482
5446
  try{s.WorkspaceLogging.logOperation(this.logger,"info","Starting request completion (refactored)",e,"single-agent","completeRequest",{requestTitle:t,skipConflictDetection:r?.skipConflictDetection||!1,architecture:"shared-processor"})
5483
5447
  const o=await this.requestProcessor.completeRequest(e,t,{skipConflictDetection:r?.skipConflictDetection||!1}),i=Date.now()-n
5484
5448
  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
5485
- 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)
5449
+ 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)
5486
5450
  if(!t.isValid)throw Error("Invalid request ID: "+t.errors.join(", "))
5487
5451
  const r="requests/"+t.sanitized
5488
- 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)
5452
+ 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)
5489
5453
  if(!t.isValid)return null
5490
5454
  const r=t.sanitized,n="requests/"+r,o=await this.git.branch()
5491
- 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
5492
- try{let o=s
5493
- if(!o){const{discoverCallingSession:n}=await Promise.resolve().then(t.bind(t,7617)),s=await n(e,r,this.logger)
5494
- o=s?.sessionId}if(!o)return void this.logger.debug("Could not discover calling session for readonly check")
5495
- this.logger.debug("Discovered calling session for readonly check",{sessionId:o,toolName:r})
5496
- const i=n?.getCLISessionClient?.()
5497
- if(!i)return void this.logger.debug("No CLI session client available for readonly check")
5498
- const a=await i.getByExternalId(o)
5499
- if(!a?.agentType)return void this.logger.debug("No agent type found for session",{sessionId:o})
5500
- this.logger.debug("Found session agent type",{sessionId:o,agentType:a.agentType})
5501
- const c=await this.fetchAgentConfig(a.agentType)
5502
- if(!c||"readonly"!==c.requestContextMode)return void this.logger.debug("Agent does not have readonly requestContextMode",{agentType:a.agentType})
5503
- this.logger.debug("Agent has readonly requestContextMode",{agentType:a.agentType})
5504
- const l=n?.getSessionRequestAssociationClient?.()
5505
- if(!l)return void this.logger.debug("No session association client available")
5506
- const d=await l.getActiveRequestsForSession(o,!0)
5507
- if(0===d.length)return void this.logger.debug("No active request association found for session",{sessionId:o})
5508
- const u=d[0].requestLocalId,h="requests/"+u
5509
- this.logger.info("Readonly agent with request association, switching to branch without locking",{sessionId:o,agentType:a.agentType,requestId:u,readonlyBranch:h})
5510
- const g=await this.git.branch()
5511
- 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)
5455
+ 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
5456
+ try{const e=n
5457
+ if(!e)return void this.logger.debug("No sessionId available for readonly check")
5458
+ this.logger.debug("Checking readonly branch for session",{sessionId:e,toolName:t})
5459
+ const o=r?.getCLISessionClient?.()
5460
+ if(!o)return void this.logger.debug("No CLI session client available for readonly check")
5461
+ const s=await o.getByExternalId(e)
5462
+ if(!s?.agentType)return void this.logger.debug("No agent type found for session",{sessionId:e})
5463
+ this.logger.debug("Found session agent type",{sessionId:e,agentType:s.agentType})
5464
+ const i=await this.fetchAgentConfig(s.agentType)
5465
+ if(!i||"readonly"!==i.requestContextMode)return void this.logger.debug("Agent does not have readonly requestContextMode",{agentType:s.agentType})
5466
+ this.logger.debug("Agent has readonly requestContextMode",{agentType:s.agentType})
5467
+ const a=r?.getSessionRequestAssociationClient?.()
5468
+ if(!a)return void this.logger.debug("No session association client available")
5469
+ const c=await a.getActiveRequestsForSession(e,!0)
5470
+ if(0===c.length)return void this.logger.debug("No active request association found for session",{sessionId:e})
5471
+ const l=c[0].requestLocalId,d="requests/"+l
5472
+ this.logger.info("Readonly agent with request association, switching to branch without locking",{sessionId:e,agentType:s.agentType,requestId:l,readonlyBranch:d})
5473
+ const u=await this.git.branch()
5474
+ 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)
5512
5475
  if(!r.ok)return null
5513
5476
  const n=await r.json()
5514
5477
  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])
@@ -5651,7 +5614,7 @@ try{await o.default.promises.mkdir(u,{recursive:!0})}catch(e){return n.error("Fa
5651
5614
  try{if(!o.default.existsSync(t)){n.warn("Plugin source not found: "+e.sourceName,{sourcePath:t}),l.errors.push(e.destName)
5652
5615
  continue}const c=await o.default.promises.readFile(t,"utf8").catch((()=>null))
5653
5616
  if(null===c){n.warn("Could not read plugin source: "+e.sourceName),l.errors.push(e.destName)
5654
- continue}const d=e.destName.startsWith("lib/")?c:["const __plugin = (function() {\n const module = { exports: {} };\n const exports = module.exports;\n (function() {",c," })();\n return module.exports.default || module.exports;\n})();\nexport default __plugin;"].join("\n"),h=i.default.createHash("md5").update(d).digest("hex"),g=r(a)
5617
+ continue}const d=e.destName.startsWith("lib/")?c:['import { createRequire as __createRequire } from "node:module";\nconst require = __createRequire(import.meta.url);\nconst __plugin = (function() {\n const module = { exports: {} };\n const exports = module.exports;\n (function() {',c," })();\n return module.exports.default || module.exports;\n})();\nexport default __plugin;"].join("\n"),h=i.default.createHash("md5").update(d).digest("hex"),g=r(a)
5655
5618
  if(null===g||h!==g){const t=s.default.dirname(a)
5656
5619
  t!==u&&await o.default.promises.mkdir(t,{recursive:!0}),await o.default.promises.writeFile(a,d,"utf8"),n.info("Synced plugin: "+e.destName,{reason:null===g?"not installed":"updated"}),l.synced.push(e.destName)}else l.skipped.push(e.destName)}catch(t){n.error("Failed to sync plugin: "+e.destName,{error:t instanceof Error?t.message:"Unknown error"}),l.errors.push(e.destName)}}return l}
5657
5620
  const o=n(t(9896)),s=n(t(6928)),i=n(t(6982)),a=[{sourceName:"plugins/hooks/plugin.js",destName:"event-hooks.js"},{sourceName:"plugins/hooks/lib/condition-evaluator.js",destName:"lib/condition-evaluator.js"},{sourceName:"plugins/hooks/lib/hook-utils.js",destName:"lib/hook-utils.js"},{sourceName:"plugins/hooks/lib/dedup-utils.js",destName:"lib/dedup-utils.js"},{sourceName:"plugins/inject-session.js",destName:"inject-session.js"},{sourceName:"plugins/system-logger.js",destName:"system-logger.js"}]},9947(e,exports){function t(e,t){return e.substring(0,t).split("\n").length}function r(e){if(0===e.length)return[]