alchemylab 1.1.0 → 1.1.1

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.
@@ -35,7 +35,7 @@ return r instanceof n.NotFoundError?o=`The request ID "${e.requestId}" was not f
35
35
  const r=t(6183),n=t(9860),o=t(2960),s=t(8824)},184(e,exports,t){"use strict"
36
36
  function r(e,t,r,n,o={}){const s=d.default.resolve(e)
37
37
  if(O.has(s))return t.child({component:"mcp-server-registry"}).debug("Using existing server for path",{path:s}),O.get(s)
38
- const i=new x(s,t,r,n,o)
38
+ const i=new M(s,t,r,n,o)
39
39
  return O.set(s,i),i}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
40
40
  var o=Object.getOwnPropertyDescriptor(t,r)
41
41
  o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||(n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[]
@@ -45,16 +45,16 @@ var t={}
45
45
  if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
46
46
  return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
47
47
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.McpServer=void 0,exports.resetStdoutWrite=function(){process.stdout.write=R},exports.getMcpServer=r,exports.createServer=function(e,t,n,o,s={}){return r(e,t,n,o,s)}
48
- const c=t(3807),l=t(8909),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=i(t(7478)),k=t(4139),I=new Set,b=t(9860),v=t(1472),C=t(3328),_=t(8955),E=t(3217),q=t(5278),S=t(446),P=t(9060),T=t(8824),j=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),R=process.stdout.write,M=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
49
- !(0,p.isDebugToolsEnabled)()||M&&"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}),R.call(process.stdout,e)}catch(e){return j.error("Error in safeStdoutWrite",{error:e+""}),!0}})
50
- class x{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=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 S.LockOverrideManager(t),this.configManager=new P.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),(0,y.setGlobalClientInfo)("OpenCode","1.0.0"),this.metrics.incrementCounter("mcp_server_init_started",1),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
48
+ 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=i(t(7478)),k=t(4139),I=new Set,b=t(9860),v=t(1472),C=t(3328),_=t(8955),E=t(3217),q=t(5278),S=t(446),T=t(9060),P=t(8824),j=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),R=process.stdout.write,x=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
49
+ !(0,p.isDebugToolsEnabled)()||x&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,p.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&j.debug("Stdout output",{content:e.substring(0,100),length:e.length}),R.call(process.stdout,e)}catch(e){return j.error("Error in safeStdoutWrite",{error:e+""}),!0}})
50
+ class M{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=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 S.LockOverrideManager(t),this.configManager=new T.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),(0,y.setGlobalClientInfo)("OpenCode","1.0.0"),this.metrics.incrementCounter("mcp_server_init_started",1),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
51
51
  const e=this.workspaceManager.getCurrentContext()
52
52
  return{currentBranch:e.branchName,activeRequestId:e.requestId,isOnMainBranch:e.isMainBranch}}async updateBranchState(e,t){this.logger.debug("updateBranchState called - managed by WorkspaceManager",{branch:e,requestId:t})}async getCurrentBranchContext(){if(!this.workspaceManager)return{branch:null,requestId:null,isMain:!0}
53
53
  const e=this.workspaceManager.getCurrentContext()
54
54
  return{branch:e.branchName,requestId:e.requestId,isMain:e.isMainBranch}}async syncBranchState(){this.logger.debug("syncBranchState called - managed by WorkspaceManager")}async switchToMainContext(){return this.workspaceManager?this.workspaceManager.switchToMain():{success:!1,message:"WorkspaceManager not available"}}getCurrentRequestId(){return this.workspaceManager?.getCurrentContext().requestId||null}async getNextId(e){try{const t=this.metrics.startTimer("remote_id_generation"),r=this.apiClient.getProjectClient()
55
55
  if(!r||"function"!=typeof r.getNextId)throw Error("Project client or getNextId method not available")
56
56
  const n=await r.getNextId(e)
57
- return t({success:!0,type:e}),this.metrics.incrementCounter("remote_id_success",1,{type:e}),n}catch(t){throw this.metrics.incrementCounter("remote_id_failure",1,{type:e,error:t instanceof Error?t.name:"unknown"}),this.logger.warn("Failed to get ID from remote server, unable to perform operation",{type:e,error:(0,T.getErrorMessage)(t)}),Error("Failed to get ID from remote server.")}}async initialize(){const e=this.remoteServerUrl||"https://api.alchemylabcode.com"
57
+ return t({success:!0,type:e}),this.metrics.incrementCounter("remote_id_success",1,{type:e}),n}catch(t){throw this.metrics.incrementCounter("remote_id_failure",1,{type:e,error:t instanceof Error?t.name:"unknown"}),this.logger.warn("Failed to get ID from remote server, unable to perform operation",{type:e,error:(0,P.getErrorMessage)(t)}),Error("Failed to get ID from remote server.")}}async initialize(){const e=this.remoteServerUrl||"https://api.alchemylabcode.com"
58
58
  this.logger.debug("Using remote server URL",{remoteServerUrl:e})
59
59
  const t=d.default.resolve(this.basePath)
60
60
  if(I.has(t))return this.logger.info("Path already initialized in global registry, skipping initialization",{path:t}),void(this.isInitialized=!0)
@@ -73,7 +73,7 @@ try{if(u.default.existsSync(e)){const r=await h.default.readFile(e,"utf8")
73
73
  if(r.split("\n").some((e=>e.trim()===t||e.trim()===t.slice(0,-1))))this.logger.info(k.ALCHEMY_DIR_NAME+"/ already present in .gitignore")
74
74
  else{const n=r.trimEnd()+"\n\n# AlchemyMCP working directory\n"+t+"\n"
75
75
  await h.default.writeFile(e,n),this.logger.info(`Added ${k.ALCHEMY_DIR_NAME}/ to existing .gitignore`)}}else{const r=["# Dependency directories\nnode_modules/\n.npm\n.yarn\n\n# Build outputs\ndist/\nbuild/\n\n# Logs\nlogs/\n*.log\n\n# Editor files\n.DS_Store\n.vscode/\n.idea/\n\n# Environment variables\n.env\n.env.local\n\n# AlchemyMCP working directory",t,""].join("\n")
76
- await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${k.ALCHEMY_DIR_NAME}/ entry`)}}catch(e){this.logger.warn("Failed to update .gitignore file",{error:(0,T.getErrorMessage)(e)})}}async initializeGitRepo(){try{this.logger.info("Initializing git repository"),await this.git.init(),await this.ensureGitignoreWithAlchemyLab()
76
+ await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${k.ALCHEMY_DIR_NAME}/ entry`)}}catch(e){this.logger.warn("Failed to update .gitignore file",{error:(0,P.getErrorMessage)(e)})}}async initializeGitRepo(){try{this.logger.info("Initializing git repository"),await this.git.init(),await this.ensureGitignoreWithAlchemyLab()
77
77
  const e=d.default.join(this.basePath,"README.md")
78
78
  if(!u.default.existsSync(e)){const t=`# Project at ${this.basePath}\n\nCreated with AlchemyMCP Server.\n`
79
79
  await h.default.writeFile(e,t)}this.logger.info("Git repository initialized successfully"),await this.git.add(".")
@@ -101,30 +101,30 @@ const t=await r.getSynchronizedProjectId()
101
101
  t&&t!==e&&(this.logger.info("Project ID changed after synchronization",{oldId:e,newId:t}),e=t,await this.projectContext.updateProjectId(t),this.logger.info("Successfully updated project.json with synchronized ID",{synchronizedProjectId:t}),this.apiClient.setProjectId(t),this.tokenManager.setProjectId(t))}}catch(e){this.logger.warn("Initial project synchronization failed, but continuing initialization",{error:e instanceof Error?e.message:e+""})}await this.initializeGitRepositories(),await this.initializeWorkspaceManager(),this.logger.info("Re-initializing all tools with full context...")
102
102
  const o=this.getContext();(0,v.registerTools)(this.server,o,this.apiClient,this.logger,this.metrics,this.tokenManager,this),this.tokenManager.setProjectId(this.getProjectId()),this.logger.info("Complete initialization finished - all tools available")}async getCurrentBranchInfo(){try{if(!this.git)return{available:!1,message:"No git repository available"}
103
103
  const e=await w.getRepositoryStatus(this.git,this.logger,this.metrics)
104
- return e.isGitRepository?{available:!0,currentBranch:e.currentBranch,isClean:e.isClean,branchCount:e.branches.length,message:`On branch ${e.currentBranch}${e.isClean?" (clean)":" (uncommitted changes)"}`}:{available:!1,message:"Not a git repository"}}catch(e){return this.logger.warn("Failed to get branch info",{error:(0,T.getErrorMessage)(e)}),{available:!1,message:"Git error: "+(0,T.getErrorMessage)(e)}}}async createSseConnection(e,t){await this.waitForInitialization(),this.cleanupSSEConnection(),this.logger.debug("Creating new SSE connection"),e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive")
104
+ return e.isGitRepository?{available:!0,currentBranch:e.currentBranch,isClean:e.isClean,branchCount:e.branches.length,message:`On branch ${e.currentBranch}${e.isClean?" (clean)":" (uncommitted changes)"}`}:{available:!1,message:"Not a git repository"}}catch(e){return this.logger.warn("Failed to get branch info",{error:(0,P.getErrorMessage)(e)}),{available:!1,message:"Git error: "+(0,P.getErrorMessage)(e)}}}async createSseConnection(e,t){await this.waitForInitialization(),this.cleanupSSEConnection(),this.logger.debug("Creating new SSE connection"),e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive")
105
105
  const r=new g.SSEServerTransport("/sse",e)
106
106
  this.currentSSEConnection={transport:r,response:e}
107
- try{await this.server.connect(r),this.logger.info("SSE transport connected successfully")}catch(e){this.logger.error("Error connecting SSE transport",{error:(0,T.getErrorMessage)(e)})}return r}async connectStdio(){await this.waitForInitialization(),this.logger.debug("Connecting stdio transport"),this.stdioTransport=new g.StdioServerTransport
108
- try{await this.server.connect(this.stdioTransport),this.logger.info("STDIO transport connected successfully")}catch(e){this.logger.error("Error connecting stdio transport",{error:(0,T.getErrorMessage)(e)})}}getCurrentSSEConnection(){return this.currentSSEConnection}setCurrentSSEConnection(e){this.currentSSEConnection=e}getServer(){return this.server}getCurrentGitInstance(){if(!this.workspaceManager)return this.git||void 0
107
+ try{await this.server.connect(r),this.logger.info("SSE transport connected successfully")}catch(e){this.logger.error("Error connecting SSE transport",{error:(0,P.getErrorMessage)(e)})}return r}async connectStdio(){await this.waitForInitialization(),this.logger.debug("Connecting stdio transport"),this.stdioTransport=new g.StdioServerTransport
108
+ try{await this.server.connect(this.stdioTransport),this.logger.info("STDIO transport connected successfully")}catch(e){this.logger.error("Error connecting stdio transport",{error:(0,P.getErrorMessage)(e)})}}getCurrentSSEConnection(){return this.currentSSEConnection}setCurrentSSEConnection(e){this.currentSSEConnection=e}getServer(){return this.server}getCurrentGitInstance(){if(!this.workspaceManager)return this.git||void 0
109
109
  const e=this.workspaceManager.getCurrentContext()
110
110
  return"multi-agent"===e.mode&&e.requestId?this.workspaceManager.getCurrentGit():this.git||void 0}getContext(){if(!this.workspaceManager)throw Error("WorkspaceManager not initialized")
111
111
  return{mainBasePath:this.basePath,alchemyPath:this.alchemyPath,basePath:this.workspaceManager.getCurrentContext().basePath,projectId:this.getProjectId(),git:this.getCurrentGitInstance(),gitBinary:this.gitBinary,apiClient:this.apiClient,workspaceManager:this.workspaceManager,documentFileManager:this.documentFileManager,lockOverrideManager:this.lockOverrideManager,configManager:this.configManager,getNextId:this.getNextId.bind(this),getCurrentBranchContext:this.getCurrentBranchContext.bind(this),syncBranchState:this.syncBranchState.bind(this),switchToMainContext:this.switchToMainContext.bind(this),getCurrentRequestId:this.getCurrentRequestId.bind(this),updateBranchState:this.updateBranchState.bind(this)}}isMainBranch(e){return"main"===e||"master"===e}extractRequestIdFromBranch(e){const t=e.match(/^feature\/req(\d+)-/)
112
- return t?"req"+t[1]:null}async getEnhancedContext(){return{...this.getContext(),branchInfo:await this.getCurrentBranchInfo()}}getTokenManager(){return this.tokenManager}getProjectId(){try{return this.projectContext.getProjectId()}catch(e){return this.logger.debug("ProjectContext not initialized, using fallback project ID",{error:(0,T.getErrorMessage)(e)}),"INITIALIZING"}}generateSessionId(){return`session_${Date.now().toString(36)}_${Math.random().toString(36).substring(2,8)}_${process.pid.toString(36)}`}async getActiveWorktrees(){return await this.workspaceManager.listActiveWorkspaces()}async initializeWorkspaceManager(){try{if(this.logger.debug("initializeWorkspaceManager called",{basePath:this.basePath}),!this.git)throw Error("Git must be initialized before WorkspaceManager")
112
+ return t?"req"+t[1]:null}async getEnhancedContext(){return{...this.getContext(),branchInfo:await this.getCurrentBranchInfo()}}getTokenManager(){return this.tokenManager}getProjectId(){try{return this.projectContext.getProjectId()}catch(e){return this.logger.debug("ProjectContext not initialized, using fallback project ID",{error:(0,P.getErrorMessage)(e)}),"INITIALIZING"}}generateSessionId(){return`session_${Date.now().toString(36)}_${Math.random().toString(36).substring(2,8)}_${process.pid.toString(36)}`}async getActiveWorktrees(){return await this.workspaceManager.listActiveWorkspaces()}async initializeWorkspaceManager(){try{if(this.logger.debug("initializeWorkspaceManager called",{basePath:this.basePath}),!this.git)throw Error("Git must be initialized before WorkspaceManager")
113
113
  this.workspaceManager=(0,E.createWorkspaceManager)(this.basePath,this.logger,this.git,this.metrics,this.apiClient),this.logger.debug("WorkspaceManager created successfully"),this.logger.info("Initialized unified workspace manager",{mode:"multi-agent",basePath:this.basePath})}catch(e){throw this.logger.error("Failed to initialize workspace manager",{error:e}),e}}async switchToRequestContext(e){return this.logger.debug("switchToRequestContext called",{requestId:e,hasWorkspaceManager:!!this.workspaceManager}),this.workspaceManager?this.switchToWorktreeContext(e):{success:!1,message:"Workspace manager not available"}}async switchToWorktreeContext(e){if(this.logger.debug("Using worktree context switching for multi-agent mode",{requestId:e}),!this.workspaceManager)return{success:!1,message:"Workspace manager not available"}
114
114
  try{let t="request-"+e
115
115
  try{this.logger.debug("Attempting to fetch request title from API",{requestId:e})
116
116
  const r=this.apiClient.getRequestClient(),n=await r.getRequest(e)
117
- n&&n.title?(t=n.title,this.logger.debug("Successfully fetched request title for worktree",{requestId:e,actualTitle:n.title})):this.logger.warn("Request info found but no title, using fallback",{requestId:e,requestInfo:n?"exists":"null",fallbackTitle:t})}catch(r){this.logger.warn("Failed to fetch request title, using fallback",{requestId:e,fallbackTitle:t,error:(0,T.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0})}const r=this.generateSessionId()
117
+ n&&n.title?(t=n.title,this.logger.debug("Successfully fetched request title for worktree",{requestId:e,actualTitle:n.title})):this.logger.warn("Request info found but no title, using fallback",{requestId:e,requestInfo:n?"exists":"null",fallbackTitle:t})}catch(r){this.logger.warn("Failed to fetch request title, using fallback",{requestId:e,fallbackTitle:t,error:(0,P.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0})}const r=this.generateSessionId()
118
118
  this.logger.info("Creating worktree for request using WorkspaceManager",{requestId:e,requestTitle:t,sessionId:r}),await this.workspaceManager.ensureWorkspaceReady(e)
119
119
  const n=this.workspaceManager.getCurrentContext()
120
120
  this.git=(0,c.simpleGit)({baseDir:n.basePath,binary:this.gitBinary})
121
121
  try{const t=await w.getCurrentBranch(this.git,this.logger,this.metrics)
122
122
  if(this.logger.info("Workspace Git instance branch status",{requestId:e,currentBranch:t,expectedBranch:n.branchName,workspacePath:n.basePath,isMainBranch:n.isMainBranch}),t!==n.branchName&&!n.isMainBranch){this.logger.warn("Workspace not on expected branch, attempting to switch",{requestId:e,currentBranch:t,expectedBranch:n.branchName})
123
123
  const r=await w.switchToBranch(this.git,n.branchName,this.logger,this.metrics)
124
- r.success?this.logger.info("Successfully switched workspace to correct branch",{requestId:e,branchName:n.branchName}):this.logger.error("Failed to switch workspace to correct branch",{requestId:e,expectedBranch:n.branchName,error:r.message})}}catch(t){this.logger.error("Failed to verify workspace branch status",{requestId:e,workspacePath:n.basePath,error:t instanceof Error?t.message:t+""})}return this.logger.info("Switched to request context",{requestId:e,workspacePath:n.basePath,branchName:n.branchName}),{success:!0,message:"Switched to workspace for request "+e,worktreePath:n.basePath}}catch(t){const r=(0,T.getErrorMessage)(t)
124
+ r.success?this.logger.info("Successfully switched workspace to correct branch",{requestId:e,branchName:n.branchName}):this.logger.error("Failed to switch workspace to correct branch",{requestId:e,expectedBranch:n.branchName,error:r.message})}}catch(t){this.logger.error("Failed to verify workspace branch status",{requestId:e,workspacePath:n.basePath,error:t instanceof Error?t.message:t+""})}return this.logger.info("Switched to request context",{requestId:e,workspacePath:n.basePath,branchName:n.branchName}),{success:!0,message:"Switched to workspace for request "+e,worktreePath:n.basePath}}catch(t){const r=(0,P.getErrorMessage)(t)
125
125
  return this.logger.error("Failed to switch to request context",{requestId:e,error:r}),{success:!1,message:"Failed to switch context: "+r}}}async getEffectiveBasePath(e){if(!this.workspaceManager||!e)return this.basePath
126
126
  const t=await this.workspaceManager.getWorkspaceInfo(e)
127
- return t?.path||this.basePath}}exports.McpServer=x
127
+ return t?.path||this.basePath}}exports.McpServer=M
128
128
  const O=new Map},213(e,exports,t){"use strict"
129
129
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
130
130
  const r=t(6183),n=t(3707)
@@ -440,23 +440,23 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
440
440
  var t={}
441
441
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
442
442
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
443
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerApiRoutes=async function(e,r,n,o){const s=n.child({component:"api"}),i=r.getTokenManager(),P=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com",T=new m.AuthenticationManager(i,n.child({component:"auth-manager"})),j=T.getTokenSynchronizer(),R=await T.getTokenString()||void 0
443
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerApiRoutes=async function(e,r,n,o){const s=n.child({component:"api"}),i=r.getTokenManager(),T=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com",P=new m.AuthenticationManager(i,n.child({component:"auth-manager"})),j=P.getTokenSynchronizer(),R=await P.getTokenString()||void 0
444
444
  n.debug("Token retrieved from authentication manager")
445
- const M=new k.ConnectionStatusManager(P,n.child({component:"connection-status-manager"}),o,{checkIntervalMs:3e4,timeoutMs:5e3}),x=new w.ProjectClient(P,n.child({component:"project-client"}),o,M,R)
446
- j.registerClient(x)
447
- const O=new b.TaskClient(P,n.child({component:"task-client"}),o,x,M,R)
445
+ const x=new k.ConnectionStatusManager(T,n.child({component:"connection-status-manager"}),o,{checkIntervalMs:3e4,timeoutMs:5e3}),M=new w.ProjectClient(T,n.child({component:"project-client"}),o,x,R)
446
+ j.registerClient(M)
447
+ const O=new b.TaskClient(T,n.child({component:"task-client"}),o,M,x,R)
448
448
  j.registerClient(O)
449
- const $=new v.FileOperationsClient(P,n.child({component:"file-client"}),o,x,R,M)
449
+ const $=new v.FileOperationsClient(T,n.child({component:"file-client"}),o,M,R,x)
450
450
  j.registerClient($)
451
- const D=new C.ProxyClient(P,n.child({component:"proxy-client"}),o,x,R,M)
451
+ const D=new C.ProxyClient(T,n.child({component:"proxy-client"}),o,M,R,x)
452
452
  j.registerClient(D)
453
- const A=new _.RequestClient(P,n.child({component:"request-client"}),o,x,R,M)
453
+ const A=new _.RequestClient(T,n.child({component:"request-client"}),o,M,R,x)
454
454
  A.setAuthToken(R),(0,d.isDebugToolsEnabled)()&&n.debug("Explicitly set token on RequestClient",{tokenPresent:!!R}),j.registerClient(A)
455
- const F=new E.DocumentClient(P,n.child({component:"document-client"}),o,x,R,M)
455
+ const F=new E.DocumentClient(T,n.child({component:"document-client"}),o,M,R,x)
456
456
  j.registerClient(F)
457
- const N=new q.ToolRecordClient(P,n.child({component:"tool-record-client"}),o,x,R,M)
457
+ const N=new q.ToolRecordClient(T,n.child({component:"tool-record-client"}),o,M,R,x)
458
458
  j.registerClient(N)
459
- const L=new S.ApiClient(T,x,O,$,A,F,N,D,n.child({component:"api-client"})),z=a.default.Router();(0,h.registerAuthRoutes)(z,{projectClient:x,taskClient:O,fileClient:$,authManager:T,apiClient:L},i,n)
459
+ const L=new S.ApiClient(P,M,O,$,A,F,N,D,n.child({component:"api-client"})),z=a.default.Router();(0,h.registerAuthRoutes)(z,{projectClient:M,taskClient:O,fileClient:$,authManager:P,apiClient:L},i,n)
460
460
  const H=r.getContext();(0,g.registerConfigRoutes)(z,n,H.basePath),e.use("/api",z)
461
461
  const B=e=>{const t=o.startTimer(e)
462
462
  return e=>t(e)},U=(e,t,n)=>{const o=e.query.path||e.body.path
@@ -519,10 +519,10 @@ const d=await l.commit(a)
519
519
  try{await l.revparse(["--abbrev-ref","HEAD"]),await l.revparse(["HEAD"]),await l.revparse(["--show-toplevel"])}catch(e){}s({endpoint:"git/commit",method:"POST",success:!0}),n.json({success:!0,data:{commit:d.commit,author:d.author,summary:d.summary,message:a}})}catch(e){s(e)}})),e.post("/api/sync/projects",(async(e,t,n)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"sync/projects",method:"POST"})
520
520
  const e=B("api_request_duration")
521
521
  r.getContext(),s.info("Manual project synchronization requested"),s.info("Starting manual project synchronization")
522
- 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"})
522
+ try{await M.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"})
523
523
  const e=B("api_request_duration")
524
- try{const r=await x.pingDetailed(),n="online"===r.status,o=r.latency
525
- 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:P,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:P,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)
524
+ try{const r=await M.pingDetailed(),n="online"===r.status,o=r.latency
525
+ 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:M.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)
526
526
  try{const n=await L.proxyGet(r,e.query)
527
527
  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})
528
528
  throw e}}catch(e){r(e)}})),e.post("/api/proxy/*",G,(async(e,t,r)=>{try{const r=e.path.substring(11)
@@ -658,18 +658,18 @@ C=r}else C=t.basePath
658
658
  b.resolvedPath=C
659
659
  let _=!1
660
660
  try{_=(await g.default.stat(C)).isFile()}catch(e){const t=`Cannot access path ${C}: ${(0,k.getErrorMessage)(e)}`
661
- throw b.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,P=v.fileExtension,T=v.searchIn||"content"
661
+ throw b.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,T=v.fileExtension,P=v.searchIn||"content"
662
662
  let j=void 0!==v.contextLines?v.contextLines:0
663
- if(0>j?j=0:j>10&&(l.warn(`contextLines ${j} exceeds maximum of 10, clamping to 10`),j=10),!_&&!P)throw b.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,f.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
664
- let R,M=""
665
- if(_)M="*"
666
- else if("*"===P)M="*"
667
- else if(P){let e=P;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),M=e.startsWith(".")?e:"."+e}try{R=S?q?RegExp(n):RegExp(n,"i"):q?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${S?"regex":"search"} pattern: ${(0,k.getErrorMessage)(e)}`
668
- throw b.errors.push(t),(0,f.createValidationError)(t)}if(b.patternInfo={needle:n,regex:R.toString(),caseSensitive:q,fileExtension:P,normalizedExtension:M},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
663
+ if(0>j?j=0:j>10&&(l.warn(`contextLines ${j} exceeds maximum of 10, clamping to 10`),j=10),!_&&!T)throw b.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,f.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
664
+ let R,x=""
665
+ if(_)x="*"
666
+ else if("*"===T)x="*"
667
+ else if(T){let e=T;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),x=e.startsWith(".")?e:"."+e}try{R=S?q?RegExp(n):RegExp(n,"i"):q?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${S?"regex":"search"} pattern: ${(0,k.getErrorMessage)(e)}`
668
+ throw b.errors.push(t),(0,f.createValidationError)(t)}if(b.patternInfo={needle:n,regex:R.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:x},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
669
669
  for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
670
670
  b.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},b.phases.directoryListingTime=b.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,k.getErrorMessage)(e)
671
- b.errors.push(t),l.error(t)}const x=_?"file":"directory"
672
- l.info(`Searching for "${n}" in ${x} ${C} (mode: ${T})`,{needle:n,searchTarget:x,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:M,searchIn:T}}),I=Date.now(),b.phases.initializationTime=I-u
671
+ b.errors.push(t),l.error(t)}const M=_?"file":"directory"
672
+ l.info(`Searching for "${n}" in ${M} ${C} (mode: ${P})`,{needle:n,searchTarget:M,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:x,searchIn:P}}),I=Date.now(),b.phases.initializationTime=I-u
673
673
  const O=Date.now()
674
674
  let $=[],D=0,A=0
675
675
  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=[]
@@ -687,7 +687,7 @@ o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
687
687
  const f={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
688
688
  try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,p,a,o,s,0,f,l,u)
689
689
  return f.filesProcessed=n,f.filesMatched=c,f.subdirectories=d,i.directoryStats.push(f),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:p.length,directories:d+1}),{matches:p,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,k.getErrorMessage)(t)
690
- return f.errors.push(r),i.directoryStats.push(f),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:p,totalFiles:f.filesProcessed}}}(C,R,{maxResults:E,fileExtension:M,searchIn:T,isFile:_,contextLines:j},M,l,b)
690
+ return f.errors.push(r),i.directoryStats.push(f),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:p,totalFiles:f.filesProcessed}}}(C,R,{maxResults:E,fileExtension:x,searchIn:P,isFile:_,contextLines:j},x,l,b)
691
691
  $=e.matches,D=e.totalFiles
692
692
  const t=1e3
693
693
  $.length>0&&$.length<=t?($.sort(((e,t)=>void 0!==e.modifiedTime&&void 0!==t.modifiedTime?t.modifiedTime-e.modifiedTime:void 0!==e.modifiedTime&&void 0===t.modifiedTime?-1:void 0===e.modifiedTime&&void 0!==t.modifiedTime?1:0)),l.info(`Sorted ${$.length} matches by modification time (newest first)`)):$.length>t&&l.info(`Skipped sorting ${$.length} matches (exceeds hard cap of ${t} for performance)`),A=$.length,$.length>E&&($=$.slice(0,E),l.info(`Limited results to ${E} (from ${A} total matches)`)),$.forEach((e=>{e.relativePath=function(e,t){const r=h.default.relative(e,t)
@@ -696,8 +696,8 @@ b.errors.push(t),l.error(t),b.phases.searchTime=Date.now()-O}b.totalFiles=D,b.to
696
696
  let F,N=""
697
697
  try{if(t.getCurrentBranchContext){const e=await t.getCurrentBranchContext()
698
698
  e.branch&&(N=e.isMain?` (searched on main branch: ${e.branch})`:` (searched on request branch: ${e.branch}${e.requestId?" for "+e.requestId:""})`)}}catch(e){l.debug("Could not get branch context",{error:e}),N=" (branch context unavailable)"}l.debug("Search diagnostic information",{diagnostic:b})
699
- const L="content"===T?"content":"filename"===T?"filenames":"content and filenames"
700
- if(A>$.length?(F=`Found ${A} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),P&&(F+=" with extension "+P),F+=`${N}. Showing first ${$.length}:\n\n`):(F=`Found ${$.length} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),P&&(F+=" with extension "+P),F+=N+":\n\n"),$.length>0)if(j>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
699
+ const L="content"===P?"content":"filename"===P?"filenames":"content and filenames"
700
+ if(A>$.length?(F=`Found ${A} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=`${N}. Showing first ${$.length}:\n\n`):(F=`Found ${$.length} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=N+":\n\n"),$.length>0)if(j>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
701
701
  if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
702
702
  const o=new Map
703
703
  for(const e of n){const t=o.get(e.file)||[]
@@ -1179,13 +1179,13 @@ function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.st
1179
1179
  if(r(t,"handleSpawn called",{agent:i,promptLength:a.length,requestId:c,useExistingSession:d,cliOriginSessionId:s?.sessionId||null}),!(0,S.isValidAgent)(i))return{content:[{type:"text",text:`\u274c Unknown agent '${i}'.\n\n**Available agents:** ${(0,S.getAgentNames)().join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}
1180
1180
  try{const e=s?.sessionId
1181
1181
  let n=I.sessionIdentity.getIdentity()?.agentType
1182
- if(r(t,"Spawn agent type check",{callerSessionId:e||null,cachedAgentType:n||null,pid:process.pid}),!n&&e)try{const o=`http://localhost:${P}/api/sessions/${encodeURIComponent(e)}/agent-type`
1182
+ if(r(t,"Spawn agent type check",{callerSessionId:e||null,cachedAgentType:n||null,pid:process.pid}),!n&&e)try{const o=`http://localhost:${T}/api/sessions/${encodeURIComponent(e)}/agent-type`
1183
1183
  r(t,"Looking up agent type from action server",{sessionId:e,url:o})
1184
1184
  const s=await fetch(o)
1185
1185
  if(s.ok){const o=await s.json()
1186
1186
  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,I.sessionIdentity.updateIdentity({agentType:n}))}else r(t,"Agent type lookup failed",{sessionId:e,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e,error:(0,_.getErrorMessage)(n)})}if(n){const e=(0,S.getAllowedSubagents)(n)
1187
1187
  if(e&&!e.includes(i))return{content:[{type:"text",text:`\u274c Agent type '${n}' cannot spawn '${i}'.\n\n**Allowed subagents for ${n}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,_.getErrorMessage)(e)})}let u
1188
- try{const e=await async function(e){try{const t=`http://localhost:${P}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
1188
+ try{const e=await async function(e){try{const t=`http://localhost:${T}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
1189
1189
  if(!r.ok)return null
1190
1190
  const n=await r.json()
1191
1191
  return n.success?n.data??null:null}catch{return null}}(i)
@@ -1206,14 +1206,14 @@ c&&(m="requests/"+c,r(t,"Setting initialBranch for agent",{agent:i,requestId:c,i
1206
1206
  let E=!1
1207
1207
  if(d){if(v=d,n.info("Using existing session for spawn",{sessionId:v,requestId:c}),!h)throw new y.ValidationError("Could not determine OpenCode server URL")
1208
1208
  try{let e
1209
- try{const t=await fetch(`http://localhost:${P}/api/project-settings`)
1209
+ try{const t=await fetch(`http://localhost:${T}/api/project-settings`)
1210
1210
  if(t.ok){const r=await t.json()
1211
1211
  if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
1212
1212
  e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${h.replace(/\/$/,"")}/session/${v}/prompt_async`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:C}],...i?{agent:i}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
1213
1213
  if(!r.ok){const e=await r.text().catch((()=>"Unknown error"))
1214
1214
  throw Error(`Failed to send to existing session: ${r.status} ${e}`)}n.info("Prompt sent to existing session",{sessionId:v,agent:i})}catch(e){throw Error("Failed to use existing session: "+(0,_.getErrorMessage)(e))}}else{E=!0,r(t,"Creating session via spawn-session endpoint")
1215
1215
  const o=p;(0,b.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:o})
1216
- try{const s=`http://localhost:${P}/api/spawn-session`,d=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent:i,prompt:a,requestId:c,parentSessionId:o,title:e.title,specialization:e.specialization,allowParallel:l,callerAgentType:I.sessionIdentity.getIdentity()?.agentType}),signal:AbortSignal.timeout(15e3)})
1216
+ try{const s=`http://localhost:${T}/api/spawn-session`,d=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent:i,prompt:a,requestId:c,parentSessionId:o,title:e.title,specialization:e.specialization,allowParallel:l,callerAgentType:I.sessionIdentity.getIdentity()?.agentType}),signal:AbortSignal.timeout(15e3)})
1217
1217
  if(!d.ok){const e=await d.text().catch((()=>"Unknown error"))
1218
1218
  throw Error(`Spawn session endpoint failed: ${d.status} ${e}`)}const u=await d.json()
1219
1219
  if(!u.success||!u.data)throw Error(u.error||"Spawn session returned unsuccessful")
@@ -1228,11 +1228,11 @@ if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.leng
1228
1228
  if(t){const r=o.getCLISessionClient()
1229
1229
  if(r){let o=await r.getByExternalId(t)
1230
1230
  o||(o=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),n.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:o?.id})),o&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:o.id,status:"active"}),n.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){n.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,_.getErrorMessage)(e)})}let c=s
1231
- if(!c)try{const t=`http://localhost:${P}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
1231
+ if(!c)try{const t=`http://localhost:${T}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
1232
1232
  if(r.ok){const e=await r.json()
1233
1233
  e.success&&e.agentType&&(c=e.agentType)}}catch{n.warn("Agent type lookup failed for session",{sessionId:e})}if(!c)throw new y.ValidationError(`Cannot continue session ${e}: unable to determine agent type. The session's agent type could not be looked up from the action server.`)
1234
1234
  try{let r
1235
- try{const e=await fetch(`http://localhost:${P}/api/project-settings`)
1235
+ try{const e=await fetch(`http://localhost:${T}/api/project-settings`)
1236
1236
  if(e.ok){const t=await e.json()
1237
1237
  if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
1238
1238
  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)})
@@ -1247,7 +1247,7 @@ const s=n.path||n.file||n.directory,i=n.needle||n.query||n.pattern
1247
1247
  "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))
1248
1248
  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
1249
1249
  return{current:r?.name??null,recent:n.map((e=>e.name)),lastActivityTime:o}}function a(e){return 1e3>e?"<1s ago":6e4>e?Math.floor(e/1e3)+"s ago":36e5>e?Math.floor(e/6e4)+"m ago":Math.floor(e/36e5)+"h ago"}function c(e,t){const r=e||t,n=Date.now()-r
1250
- return e&&T>n?{status:"working",detail:"last action "+a(n),isReady:!1}:n>j&&e?{status:"stalled",detail:"no activity for "+a(n),isReady:!0}:e?{status:"idle",detail:"no activity for "+a(n),isReady:!0}:{status:"idle",detail:"no tool activity",isReady:!0}}function l(e){let t=0,r=0,n=0
1250
+ return e&&P>n?{status:"working",detail:"last action "+a(n),isReady:!1}:n>j&&e?{status:"stalled",detail:"no activity for "+a(n),isReady:!0}:e?{status:"idle",detail:"no activity for "+a(n),isReady:!0}:{status:"idle",detail:"no tool activity",isReady:!0}}function l(e){let t=0,r=0,n=0
1251
1251
  for(const o of e.trim().split("\n")){if(!o)continue
1252
1252
  const[e,s]=o.split("\t")
1253
1253
  "-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function d(e,r,n,o){const a=await(0,k.getServerUrl)(r,n)
@@ -1325,11 +1325,11 @@ b.push(...t,...r)
1325
1325
  const n=[]
1326
1326
  if(t.length>0&&n.push("active: "+t.join(", ")),r.length>0){const e=5,t=r.slice(0,e),o=r.length-t.length
1327
1327
  n.push(`prev: ${t.join(", ")}${o>0?` +${o} more`:""}`)}n.length>0&&(y=` [${n.join(" | ")}]`)}if(a&&!b.includes(a))continue
1328
- const S=t.title||"Untitled",P=S.length>50?S.slice(0,47)+"...":S
1329
- q.push({id:t.id,title:P,status:f,age:r,totalTokens:o,requestsInfo:y,allRequestIds:b,statusDetail:h.detail,specialization:m?.specialization??null,currentAction:s,recentActions:l})}if(0===q.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
1330
- const S=l?q.slice(0,l):q,P=S.map((e=>{const t=e.specialization?"\n Specialization: "+e.specialization:"",r=e.currentAction?"\n Current: "+e.currentAction:"",o="specialist"!==n.agentType&&e.recentActions.length>0?"\n Recent: "+e.recentActions.join(", "):""
1331
- return`\u2022 ${e.id}\n ${e.title}${t}\n Status: ${e.status} (${e.statusDetail}) | Age: ${s(e.age)} | ${e.totalTokens.toLocaleString()} tokens${e.requestsInfo}${r}${o}`})),T=l&&q.length>l?` (showing ${l} of ${q.length})`:""
1332
- return{content:[{type:"text",text:`Found ${S.length} session${1!==S.length?"s":""}${T}:\n\n${P.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,_.getErrorMessage)(e))}}var g,p=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
1328
+ const S=t.title||"Untitled",T=S.length>50?S.slice(0,47)+"...":S
1329
+ q.push({id:t.id,title:T,status:f,age:r,totalTokens:o,requestsInfo:y,allRequestIds:b,statusDetail:h.detail,specialization:m?.specialization??null,currentAction:s,recentActions:l})}if(0===q.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
1330
+ const S=l?q.slice(0,l):q,T=S.map((e=>{const t=e.specialization?"\n Specialization: "+e.specialization:"",r=e.currentAction?"\n Current: "+e.currentAction:"",o="specialist"!==n.agentType&&e.recentActions.length>0?"\n Recent: "+e.recentActions.join(", "):""
1331
+ return`\u2022 ${e.id}\n ${e.title}${t}\n Status: ${e.status} (${e.statusDetail}) | Age: ${s(e.age)} | ${e.totalTokens.toLocaleString()} tokens${e.requestsInfo}${r}${o}`})),P=l&&q.length>l?` (showing ${l} of ${q.length})`:""
1332
+ return{content:[{type:"text",text:`Found ${S.length} session${1!==S.length?"s":""}${P}:\n\n${T.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,_.getErrorMessage)(e))}}var g,p=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
1333
1333
  var o=Object.getOwnPropertyDescriptor(t,r)
1334
1334
  o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),f=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),m=this&&this.__importStar||(g=function(e){return g=Object.getOwnPropertyNames||function(e){var t=[]
1335
1335
  for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
@@ -1365,7 +1365,7 @@ case"list-sessions":const s={activeOnly:r.listSessions?.activeOnly,requestId:r.l
1365
1365
  f=await h(t,c,i,s)
1366
1366
  break
1367
1367
  default:throw new y.ValidationError("Unknown operation: "+p)}return l({success:!0}),s.incrementCounter(`subagent_operations_${p}_success`,1),f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),s.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,_.getErrorMessage)(e)}],isError:!0}}}
1368
- const y=t(9860),w=t(8035),k=t(7617),I=t(6688),b=t(7280),v=t(6183),C=m(t(5967)),_=t(8824),E=t(9896),q=t(6928),S=t(8955),P=3456,T=6e4,j=3e5},1791(e,exports,t){"use strict"
1368
+ const y=t(9860),w=t(8035),k=t(7617),I=t(6688),b=t(7280),v=t(6183),C=m(t(5967)),_=t(8824),E=t(9896),q=t(6928),S=t(8955),T=3456,P=6e4,j=3e5},1791(e,exports,t){"use strict"
1369
1369
  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}}
1370
1370
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
1371
1371
  const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
@@ -1680,36 +1680,36 @@ m.info("Initial branch context",{initialBranch:C.branch,initialRequestId:C.reque
1680
1680
  const _=[]
1681
1681
  for(const e of h){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.source,t),{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(e.destination,t)
1682
1682
  _.push({source:r,destination:o,fullSource:n,fullDestination:s})}I=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("move_files_phase",1,{phase:I})
1683
- const E=await d.validateTaskId(u,_[0].source,r,m,i,b.metricsPrefix),q=E?.requestId,S=await d.validateWorkItemStates(u,_[0].source,r,o,t,m,i,b.metricsPrefix),P=await d.autoPromoteTaskStatus(u,E.status,q,S.request?.status,_[0].source,r,o,m,i,b.metricsPrefix)
1684
- P.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:P.newTaskStatus,operationCount:h.length}),P.requestPromoted&&m.info(`Auto-promoted request ${q} to in_progress for file operations`,{requestId:q,previousStatus:S.request?.status,newStatus:P.newRequestStatus,triggeringTaskId:u})
1685
- const T=await d.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:b.metricsPrefix})
1686
- if(!T.success){if(T.isLockConflict)return{content:[{type:"text",text:"\u274c "+T.error}],isError:!0}
1687
- throw Error(T.error)}let j={hadUserMods:!1,userModsCommitHash:void 0}
1683
+ const E=await d.validateTaskId(u,_[0].source,r,m,i,b.metricsPrefix),q=E?.requestId,S=await d.validateWorkItemStates(u,_[0].source,r,o,t,m,i,b.metricsPrefix),T=await d.autoPromoteTaskStatus(u,E.status,q,S.request?.status,_[0].source,r,o,m,i,b.metricsPrefix)
1684
+ 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})
1685
+ const P=await d.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:b.metricsPrefix})
1686
+ if(!P.success){if(P.isLockConflict)return{content:[{type:"text",text:"\u274c "+P.error}],isError:!0}
1687
+ throw Error(P.error)}let j={hadUserMods:!1,userModsCommitHash:void 0}
1688
1688
  if(t.git)try{m.debug("[MOVE-FILES] Checking for user changes before move operations")
1689
1689
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"move-files",{requestId:q,taskId:u,workspaceManager:t.workspaceManager},m,i)
1690
1690
  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}),j={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})
1691
- const{toolRecordId:R,localToolRecordId:M}=await d.createFileOperationRecords(u,q,t.projectId,b.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:j.hadUserMods,userModsCommitHash:j.userModsCommitHash},r,n,m,i,b.metricsPrefix,f)
1691
+ const{toolRecordId:R,localToolRecordId:x}=await d.createFileOperationRecords(u,q,t.projectId,b.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:j.hadUserMods,userModsCommitHash:j.userModsCommitHash},r,n,m,i,b.metricsPrefix,f)
1692
1692
  w=R,k=R,I=b.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:I})
1693
- const x=[]
1693
+ const M=[]
1694
1694
  let O=0
1695
1695
  for(const e of _){const t={operation:{source:e.source,destination:e.destination},success:!1}
1696
1696
  try{try{await a.default.access(e.fullSource)}catch(t){throw Error("Source path not accessible: "+e.source)}const r=(await a.default.stat(e.fullSource)).isDirectory()
1697
1697
  t.isDirectory=r
1698
1698
  const n=c.default.dirname(e.fullDestination)
1699
- 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 $=Date.now()-y
1699
+ 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})}M.push(t)}const $=Date.now()-y
1700
1700
  i.recordValue("move_files_time",$),i.incrementCounter("move_files_operations_total",h.length),i.incrementCounter("move_files_operations_success",O),i.incrementCounter("move_files_operations_failed",h.length-O),O===h.length?i.incrementCounter("move_files_success",1):O>0?i.incrementCounter("move_files_partial_success",1):i.incrementCounter("move_files_total_failure",1)
1701
1701
  let D=null
1702
1702
  if(O>0){I=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:I})
1703
- 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}`
1704
- D=await d.commitToGit(u,_[0].destination,R,M,r,t,m,i,b.metricsPrefix)}I=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:I})
1705
- const A=x.filter((e=>e.success)),F=x.filter((e=>!e.success))
1703
+ const e=M.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}`
1704
+ D=await d.commitToGit(u,_[0].destination,R,x,r,t,m,i,b.metricsPrefix)}I=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:I})
1705
+ const A=M.filter((e=>e.success)),F=M.filter((e=>!e.success))
1706
1706
  await d.updateFileOperationRecords(u,w,k,_[0].source,b.recordType,O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,{status:O===h.length?"completed":"partial_success",commitHash:D?.commitHash,previousCommitHash:D?.previousCommitHash,operationCount:h.length,successCount:O,failureCount:h.length-O,successfulOperations:A.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:F.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:j.hadUserMods,userModsCommitHash:j.userModsCommitHash},O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,r,n,m,i,b.metricsPrefix)
1707
1707
  const N=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
1708
1708
  let L=""
1709
1709
  if(O===h.length)L=`Successfully moved all ${h.length} ${1===h.length?"item":"items"}`
1710
- else if(O>0){const e=x.filter((e=>!e.success))
1711
- 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")
1712
- return D?.commitHash&&(L+="\nCommit: "+D.commitHash.substring(0,8)),N.requestId&&(L+="\nBranch: "+N.requestId),T.lockAcquired&&T.lockedRequestId&&(L+="\n\u{1f512} **Locked request:** "+T.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
1710
+ else if(O>0){const e=M.filter((e=>!e.success))
1711
+ 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"+M.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")
1712
+ return D?.commitHash&&(L+="\nCommit: "+D.commitHash.substring(0,8)),N.requestId&&(L+="\nBranch: "+N.requestId),P.lockAcquired&&P.lockedRequestId&&(L+="\n\u{1f512} **Locked request:** "+P.lockedRequestId),{content:[{type:"text",text:L}],isError:0===O}}catch(o){if(e.taskId&&n)try{const r=o instanceof u.NotFoundError||o instanceof u.ValidationError||o instanceof h.ZodError
1713
1713
  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
1714
1714
  if(i.recordValue("move_files_time",s),i.incrementCounter("move_files_errors",1),m.error("Error in move-files operation:",{error:(0,p.getErrorMessage)(o),time:s}),(w||k)&&e.taskId){I=d.FileOperationPhase.RECORD_UPDATE_FAILURE
1715
1715
  try{await d.updateFileOperationRecords(e.taskId,w,k,e.operations?.[0]?.source||"unknown",b.recordType,"Failed to move files",{status:"failed",error:(0,p.getErrorMessage)(o),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",r,n,m,i,b.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:w,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,I,m,i,e,b)}}
@@ -1719,7 +1719,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
1719
1719
  const r=t(6183),n=t(3707)
1720
1720
  exports.def={name:"quick_manage",description:"Move, delete, or create directories. Wraps the change in a request/task workflow that auto-completes.\n\nProvide an array of operations, each with operationType and corresponding data:\n\u2022 create-directory: { createDirectory: { path } }\n\u2022 move-files: { moveFiles: { moves: [{ source, destination }] } }\n\u2022 delete-files: { deleteFiles: { targets: [{ path }] } }\n\nFor read-only operations like get-file-info, use manage_files instead.\n\nRequires: title, description, operations.",schema:r.QuickManageSchema,annotations:{title:"Quick Manage",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleQuickChange)(e,"manage",t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},2462(e,exports,t){"use strict"
1721
1721
  Object.defineProperty(exports,"__esModule",{value:!0})
1722
- const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),g=t(5459),p=t(4805),f=t(260),m=t(2283),y=t(4165),w=t(7834),k=t(9373),I=t(6111),b=t(700),v=t(2783),C=t(2601),_=t(1722),E=t(7257),q=t(9230),S=t(5216),P=t(6473),T=t(4921),j=t(8850),R=t(3556),M=t(1391),x=t(6315),O=t(7713),$=t(6252),D=t(213),A=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),H=t(509),B=t(7613),U=t(3322),G=t(5247),W=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(g.def),(0,r.registerTool)(p.def),(0,r.registerTool)(f.def),(0,r.registerTool)(m.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(k.def),(0,r.registerTool)(I.def),(0,r.registerTool)(b.def),(0,r.registerTool)(v.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(E.def),(0,r.registerTool)(q.def),(0,r.registerTool)(S.def),(0,r.registerTool)(P.def),(0,r.registerTool)(T.def),(0,r.registerTool)(j.def),(0,r.registerTool)(R.def),(0,r.registerTool)(M.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(L.def),(0,r.registerTool)(z.def),(0,r.registerTool)(H.def),(0,r.registerTool)(B.def),(0,r.registerTools)(U.metaDefs),(0,r.registerTools)(G.testingDefs),(0,r.registerTools)(W.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
1722
+ const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),g=t(5459),p=t(4805),f=t(260),m=t(2283),y=t(4165),w=t(7834),k=t(9373),I=t(6111),b=t(700),v=t(2783),C=t(2601),_=t(1722),E=t(7257),q=t(9230),S=t(5216),T=t(6473),P=t(4921),j=t(8850),R=t(3556),x=t(1391),M=t(6315),O=t(7713),$=t(6252),D=t(213),A=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),H=t(509),B=t(7613),U=t(3322),G=t(5247),W=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(g.def),(0,r.registerTool)(p.def),(0,r.registerTool)(f.def),(0,r.registerTool)(m.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(k.def),(0,r.registerTool)(I.def),(0,r.registerTool)(b.def),(0,r.registerTool)(v.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(E.def),(0,r.registerTool)(q.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(P.def),(0,r.registerTool)(j.def),(0,r.registerTool)(R.def),(0,r.registerTool)(x.def),(0,r.registerTool)(M.def),(0,r.registerTool)(O.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(L.def),(0,r.registerTool)(z.def),(0,r.registerTool)(H.def),(0,r.registerTool)(B.def),(0,r.registerTools)(U.metaDefs),(0,r.registerTools)(G.testingDefs),(0,r.registerTools)(W.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
1723
1723
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.requestConfig=void 0,exports.areTestsRequiredForCompletion=function(){return exports.requestConfig.requireTestsForCompletion},exports.setTestsRequiredForCompletion=function(e){exports.requestConfig.requireTestsForCompletion=e},exports.getCompletionMode=function(e){return e&&["auto-merge","auto-test-then-merge","manual-review"].includes(e)?e:"auto-merge"},exports.getApprovalMode=function(e){return e&&["none","require-approval"].includes(e)?e:"none"},exports.requestConfig={requireTestsForCompletion:!1}},2537(e,exports,t){"use strict"
1724
1724
  async function r(e,t,r){if(C.has(r)&&_>=t){if(0===t)return 0
1725
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]"
@@ -1797,8 +1797,8 @@ let c
1797
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,b),a=s.map((e=>n({name:e.name,isDirectory(){return e.isDirectory},isFile(){return!e.isDirectory}},b,e)))
1798
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()
1799
1799
  E+="\n\nBranch: "+(S?.branchName||"unknown")
1800
- const P=Date.now()-h
1801
- return a.recordValue("list_directory_time",P),a.recordValue("list_directory_entries",q),a.incrementCounter("list_directory_success",1),i.info("Successfully listed directory: "+C,{entryCount:q,levels:m,time:P}),{content:[{type:"text",text:E}]}}catch(e){const t=Date.now()-h
1800
+ const T=Date.now()-h
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
1802
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}}}
1803
1803
  const y=m(t(1943)),w=m(t(6928)),k=t(6183),I=f(t(5967)),b=t(3253),v=t(8824),C=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore",".config",".conf",".ini",".cfg"]),_=1048576},2568(e,exports,t){"use strict"
1804
1804
  var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
@@ -2236,47 +2236,47 @@ try{const i=u.validateArgs(e,d.ReplaceStringsSchema),{taskId:C,operations:_,comm
2236
2236
  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")
2237
2237
  const q=_.filter((e=>e.path)),S=_.filter((e=>e.documentId))
2238
2238
  y.info("Operation breakdown",{fileOperations:q.length,documentOperations:S.length})
2239
- const P=[]
2239
+ const T=[]
2240
2240
  for(const e of q){const{normalizedPath:r,fullPath:n}=u.validateAndNormalizePath(e.path,t)
2241
- P.push({type:"file",path:r,fullPath:n,replacements:e.replacements,mode:e.mode||"unique"})}const T=[]
2241
+ T.push({type:"file",path:r,fullPath:n,replacements:e.replacements,mode:e.mode||"unique"})}const P=[]
2242
2242
  if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
2243
- for(const e of S)T.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
2244
- if(T.length>0&&t.apiClient){const e=T.map((e=>e.documentId))
2243
+ for(const e of S)P.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
2244
+ if(P.length>0&&t.apiClient){const e=P.map((e=>e.documentId))
2245
2245
  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}
2246
2246
  throw e}}b=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_strings_phase",1,{phase:b})
2247
- const j=P.length>0?P[0].path:"document-operation",R=await u.validateTaskId(C,j,r,y,a,v.metricsPrefix),M=R?.requestId
2248
- let x=null
2249
- P.length>0&&M&&(x=await u.validateWorkItemStates(C,P[0].path,r,s,t,y,a,v.metricsPrefix))
2247
+ const j=T.length>0?T[0].path:"document-operation",R=await u.validateTaskId(C,j,r,y,a,v.metricsPrefix),x=R?.requestId
2248
+ let M=null
2249
+ T.length>0&&x&&(M=await u.validateWorkItemStates(C,T[0].path,r,s,t,y,a,v.metricsPrefix))
2250
2250
  let O={taskPromoted:!1,requestPromoted:!1}
2251
- P.length>0&&M&&x&&(O=await u.autoPromoteTaskStatus(C,R.status,M,x.request?.status,P[0].path,r,s,y,a,v.metricsPrefix),O.taskPromoted&&y.info("Auto-promoted task to in_progress for replace-strings operation",{taskId:C,requestId:M,previousStatus:R.status,newStatus:O.newTaskStatus,triggeringOperation:"replace-strings"}))
2252
- const $=await u.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:M,context:t,operation:"replace-strings",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
2251
+ T.length>0&&x&&M&&(O=await u.autoPromoteTaskStatus(C,R.status,x,M.request?.status,T[0].path,r,s,y,a,v.metricsPrefix),O.taskPromoted&&y.info("Auto-promoted task to in_progress for replace-strings operation",{taskId:C,requestId:x,previousStatus:R.status,newStatus:O.newTaskStatus,triggeringOperation:"replace-strings"}))
2252
+ const $=await u.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:x,context:t,operation:"replace-strings",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
2253
2253
  if(!$.success){if($.isLockConflict)return{content:[{type:"text",text:"\u274c "+$.error}],isError:!0}
2254
- throw Error($.error)}if(P.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:P.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
2255
- for(let e=0;e<P.length;e++){const r=P[e],n=q[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
2256
- P[e]={...r,path:o,fullPath:s}}}if(T.length>0&&M)try{await(0,g.validateRequestStatusForDocumentOperation)(M,s,y,a,"replace-strings-document")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2254
+ throw Error($.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
2255
+ for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
2256
+ T[e]={...r,path:o,fullPath:s}}}if(P.length>0&&x)try{await(0,g.validateRequestStatusForDocumentOperation)(x,s,y,a,"replace-strings-document")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2257
2257
  throw e}b=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:b})
2258
- const D=[...P.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...T.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:A}=await u.createFileOperationRecords(C,M,t.projectId,v.recordType,j,{operationCount:_.length,fileOperations:P.length,documentOperations:T.length,operations:D,userComment:E},r,o,y,a,v.metricsPrefix,c)
2259
- if(k=A,I=A,b=v.fileOperationPhase,a.incrementCounter("replace_strings_phase",1,{phase:b}),P.length>0&&t.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
2260
- const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:M,taskId:C,workspaceManager:t.workspaceManager},y,a)
2261
- 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:P.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:P.length,error:e instanceof Error?e.message:e+""})}y.debug("[REPLACE-STRINGS] Proceeding with file operations",{fileCount:P.length})
2258
+ const D=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...P.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:A}=await u.createFileOperationRecords(C,x,t.projectId,v.recordType,j,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:D,userComment:E},r,o,y,a,v.metricsPrefix,c)
2259
+ if(k=A,I=A,b=v.fileOperationPhase,a.incrementCounter("replace_strings_phase",1,{phase:b}),T.length>0&&t.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
2260
+ const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:x,taskId:C,workspaceManager:t.workspaceManager},y,a)
2261
+ 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})
2262
2262
  const F=[]
2263
2263
  let N=0,L=0
2264
- for(const e of P){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2264
+ for(const e of T){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2265
2265
  try{if(await l.default.access(e.fullPath),!(await l.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
2266
2266
  const r=await l.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await n(r,e.replacements,e.mode)
2267
- t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,o!==r?(await l.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,L++,y.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),N+=t.failedReplacements}catch(r){t.error=(0,m.getErrorMessage)(r),t.failedReplacements=e.replacements.length,N+=t.failedReplacements,y.error("File operation failed",{path:e.path,error:t.error})}F.push(t)}for(const e of T){const r={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2267
+ t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,o!==r?(await l.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,L++,y.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),N+=t.failedReplacements}catch(r){t.error=(0,m.getErrorMessage)(r),t.failedReplacements=e.replacements.length,N+=t.failedReplacements,y.error("File operation failed",{path:e.path,error:t.error})}F.push(t)}for(const e of P){const r={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2268
2268
  try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.documentFileManager.getCachedDocumentInfo(e.documentId)
2269
2269
  r.filename=s?.filename
2270
2270
  const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
2271
- 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(T.length>0)try{for(const e of T){const r=F.find((t=>t.documentId===e.documentId))
2272
- 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,P,F,L,{operationType:"Replace strings",toolRecordId:I,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),H=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:B,failedOperations:U,totalSuccessfulChanges:G,overallSuccess:W,successfulFiles:V,failedFiles:J}=H
2273
- try{await o.updateToolRecord(I,{metadata:{path:P.length>0?P[0].path:"document:"+T[0]?.documentId,status:W?"completed":"failed",error:W?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:D,totalSuccessfulReplacements:G,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:E,...P.length>0&&z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}},note:W?`String replacement completed: ${B}/${F.length} operations successful${P.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:B,failedOperations:U,totalSuccessfulChanges:G,overallSuccess:W,successfulFiles:V,failedFiles:J},z,$)
2271
+ 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))
2272
+ 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),H=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:B,failedOperations:U,totalSuccessfulChanges:G,overallSuccess:W,successfulFiles:V,failedFiles:J}=H
2273
+ try{await o.updateToolRecord(I,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:W?"completed":"failed",error:W?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:D,totalSuccessfulReplacements:G,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:E,...T.length>0&&z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}},note:W?`String replacement completed: ${B}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`String replacement partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}u.formatMultiFileToolResponse("String Replacement",{successfulOperations:B,failedOperations:U,totalSuccessfulChanges:G,overallSuccess:W,successfulFiles:V,failedFiles:J},z,$)
2274
2274
  let K="## String Replacement Results\n\n"
2275
2275
  if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${B+U}\n`,K+=`- **Successful operations:** ${B}\n`,K+=`- **Failed operations:** ${U}\n`,K+=`- **Total replacements:** ${G} successful, ${N} failed\n\n`,z.success&&z.commitHash&&(K+="**Git Commit:**\n",K+=`- **Commit Hash:** ${z.commitHash.substring(0,8)}\n`,K+=`- **Files Committed:** ${z.filesCommitted.length}\n`,z.previousCommitHash&&(K+=`- **Previous Commit:** ${z.previousCommitHash.substring(0,8)}\n`),K+="\n"),$.lockAcquired&&$.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
2276
2276
  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"
2277
2277
  for(const t of e.replacements.filter((e=>!e.success)))K+=`- "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}}else{K+="**Summary:**\n",K+=`- **Total Operations:** ${F.length}\n`,K+=`- **Successful:** ${B}\n`,K+=`- **Failed:** ${U}\n`,K+=`- **Total Replacements:** ${G} successful, ${N} failed\n\n`,K+="**Detailed Results:**\n\n"
2278
2278
  for(const e of F){if("file"===e.type?K+=`### File: ${e.path}\n`:(K+="### Document: "+e.documentId,e.filename&&(K+=` (${e.filename})`),K+="\n"),K+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error?K+=`- **Error:** ${e.error}\n`:(K+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(K+=`, ${e.failedReplacements} failed`),K+="\n"),e.replacements.some((e=>!e.success))){K+="- **Failed Replacement Details:**\n"
2279
- for(const t of e.replacements.filter((e=>!e.success)))K+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}K+="\n"}}T.length>0&&(K+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
2279
+ 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")
2280
2280
  const Y=Date.now()-w
2281
2281
  return y.info("Replace strings operation completed",{duration:Y,success:W,totalOperations:F.length,successfulOperations:B,failedOperations:U}),a.incrementCounter("replace_strings_total",1,{success:W}),{content:[{type:"text",text:K}],isError:!W}}catch(t){const r=Date.now()-w
2282
2282
  if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:b}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:b,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_strings_errors",1,{phase:b}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
@@ -2378,16 +2378,16 @@ const e=await(0,m.findAvailablePort)(_)
2378
2378
  e!==_&&E.info(`Preferred port ${_} is in use, using port ${e} instead`),E.info("Starting HTTP API server...",{port:e,baseDir:C,remoteServerUrl:S})
2379
2379
  const t=new l.ProjectRegistry(E),r=new u.DefaultProjectFileSystem(E),c=n.default.join(C,f.ALCHEMY_DIR_NAME)
2380
2380
  E.info(`Checking ${f.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensureDirectoryExists(c)
2381
- const h=new I.TokenManager(E,n.default.join(c,"auth-token.json")),b=(await y.ClientFactory.createClient(S,E,q,{tokenManager:h,workingDir:C,alchemyPath:c})).projectClient,v=new k.ProjectClientAdapter(b,E),P=new d.ProjectSynchronizer(E,t,v,r),T=await P.getOrCreateProject(C,{name:n.default.basename(C)||"Local Project",description:"Project for "+n.default.basename(C),status:"active",metadata:{basePath:C,alchemyPath:c,bootstrapped:!0}})
2382
- E.info("Using project",{projectId:T.id,projectName:T.name})
2381
+ const h=new I.TokenManager(E,n.default.join(c,"auth-token.json")),b=(await y.ClientFactory.createClient(S,E,q,{tokenManager:h,workingDir:C,alchemyPath:c})).projectClient,v=new k.ProjectClientAdapter(b,E),T=new d.ProjectSynchronizer(E,t,v,r),P=await T.getOrCreateProject(C,{name:n.default.basename(C)||"Local Project",description:"Project for "+n.default.basename(C),status:"active",metadata:{basePath:C,alchemyPath:c,bootstrapped:!0}})
2382
+ E.info("Using project",{projectId:P.id,projectName:P.name})
2383
2383
  const j=(0,o.default)()
2384
2384
  j.use((0,s.default)()),j.use(o.default.json({limit:"50mb"})),j.use(o.default.urlencoded({extended:!0})),j.use((0,g.requestLogger)(E))
2385
2385
  try{E.info("Creating MCP server instance")
2386
- const t=await(0,i.createServer)(C,E,q,S,{existingProjectId:T.id})
2386
+ const t=await(0,i.createServer)(C,E,q,S,{existingProjectId:P.id})
2387
2387
  E.info("MCP server instance created successfully")
2388
2388
  const r=t.getContext()
2389
2389
  E.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(E.info("Adding connection status middleware"),j.use((0,p.addConnectionStatusInfo)(t.connectionManager))):E.warn("Unable to add connection status middleware - connection manager not available")
2390
- try{const e=T.id
2390
+ try{const e=P.id
2391
2391
  E.info("Setting up project context middleware",{projectId:e}),j.use("/api",((t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}))}catch(e){E.warn("Failed to set up project context middleware",{error:(0,w.getErrorMessage)(e)})}(0,a.registerApiRoutes)(j,t,E,q),j.use((0,g.errorHandler)(E,q)),j.listen(e,(()=>{E.info("HTTP API server listening on port "+e,{baseDir:C,port:e,nodeVersion:process.version})}))}catch(e){E.error("Failed to create or initialize MCP server",{error:e instanceof Error?e.stack:e+""})
2392
2392
  let t=!1
2393
2393
  e instanceof Error&&(t=e.message.includes("connection")||e.message.includes("timeout")||e.message.includes("network")||"ConnectionError"===e.name),q.incrementCounter("server_initialization_failure",1,{isConnectionError:t?"true":"false"}),j.use(((e,t,r)=>{t.set("X-Connection-Status","offline"),t.set("X-Server-Initialization-Failed","true"),r()})),j.use("/api",((t,r)=>{r.status(503).json({success:!1,error:{code:"CONNECTION_ERROR",message:"Server failed to initialize due to connection issues. Please check connectivity and try again.",details:{serverError:e instanceof Error?e.message:e+"",suggestions:["Check your network connection","Verify that the remote server is running","Try restarting the local server"],isConnectionIssue:!0},retryable:!0,statusCode:503}})})),E.warn("Continuing with limited functionality due to initialization error")}process.on("SIGINT",(()=>{E.info("Received SIGINT signal, shutting down..."),process.exit(0)})),process.on("SIGTERM",(()=>{E.info("Received SIGTERM signal, shutting down..."),process.exit(0)})),process.on("uncaughtException",(e=>{E.error("Uncaught exception",{error:e.stack}),process.exit(1)})),process.on("unhandledRejection",(e=>{E.error("Unhandled promise rejection",{reason:e}),process.exit(1)}))}catch(e){E.error("Failed to start HTTP API server",{error:e instanceof Error?e.stack:e+""}),process.exit(1)}}()},3626(e,exports,t){"use strict"
@@ -2498,7 +2498,7 @@ e&&2===e.length&&e.every((e=>"quick-edit"===e.type))&&(E=!0,f.info("Detected two
2498
2498
  const q=await y.createRequest({title:b,description:v,type:"quick-edit",acceptanceCriteria:["Quick change completed successfully"]})
2499
2499
  if(!q||!q.id)throw Error("Failed to create request")
2500
2500
  const S=q.id
2501
- let P
2501
+ let T
2502
2502
  f.info("Created request",{requestId:S})
2503
2503
  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)
2504
2504
  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")
@@ -2506,21 +2506,21 @@ f.debug("Creating task")
2506
2506
  const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+b})
2507
2507
  if(!e||!e.id)throw Error("Failed to create task")
2508
2508
  let v
2509
- if(P=e.id,f.info("Created task",{taskId:P}),f.debug("Executing file operation",{operationType:t}),"write"===t)v=await(0,n.handleWriteFile)({taskId:P,...C,comment:_},d,k,w,I,y,h,g,p)
2510
- else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:P,...C,comment:_},d,w,I,y,h,g,p)
2509
+ if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{operationType:t}),"write"===t)v=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,k,w,I,y,h,g,p)
2510
+ else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,I,y,h,g,p)
2511
2511
  else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
2512
- v=await(0,s.handleManageFiles)({taskId:P,...C,comment:_||b},d,w,I,y,u,h,g,p)}if(v.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:P})
2513
- try{await w.updateTaskStatus(P,"canceled"),f.info("Canceled task after operation failure",{taskId:P})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:P,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,T=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
2514
- T?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
2515
- try{await(0,i.handleCompleteTask)({taskId:P,summary:`Executed ${t} operation for quick fix: ${b}${T?" (partial success)":""}`},d,u,h,g),f.info("Task completed successfully",{taskId:P})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:P,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
2516
- try{await w.updateTaskStatus(P,"completed"),f.info("Task completed via direct updateTaskStatus call",{taskId:P})}catch(e){return f.error("Direct task completion ALSO failed - task may be stuck in in_progress",{taskId:P,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:** ${P}\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: ${P}\n\nError: `+(e instanceof Error?e.message:e+"")}],isError:!0}}}f.debug("Completing request")
2517
- const j=T?`Quick change completed with partial success: ${b}. Some replacements failed - see details below.`:"Quick change completed: "+b,R=T?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2518
- let M=!1
2512
+ v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||b},d,w,I,y,u,h,g,p)}if(v.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
2513
+ 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")
2514
+ P?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
2515
+ try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${b}${P?" (partial success)":""}`},d,u,h,g),f.info("Task completed successfully",{taskId:T})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
2516
+ 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")
2517
+ const j=P?`Quick change completed with partial success: ${b}. Some replacements failed - see details below.`:"Quick change completed: "+b,R=P?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2518
+ let x=!1
2519
2519
  try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:j,acceptanceEvidence:[{evidence:R}],testVerification:void 0},d,u,h,g,p)
2520
2520
  if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text})
2521
- else{try{await y.updateRequest(S,{status:"completed",completionSummary:j}),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)})}M=!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(!M)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:j}),M=!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
2521
+ else{try{await y.updateRequest(S,{status:"completed",completionSummary:j}),f.info("Request finalized to completed",{requestId:S})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:S,error:(0,l.getErrorMessage)(e)})}x=!0,f.info("Request completed successfully",{requestId:S})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:S,error:e instanceof Error?e.message:e+""})}if(!x)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:j}),x=!0,f.info("Request completed successfully via direct API call",{requestId:S})}catch(e){return f.error("Direct request completion also failed",{requestId:S,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${S}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const M=Date.now()-m
2522
2522
  let O
2523
- return f.info("Quick fix completed",{requestId:S,duration:x,hasPartialFailure:T}),O=T?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${x}ms\n**Status:** Some operations succeeded, some failed\n\nThe successful changes have been applied and automatically merged to main.\n**Active branch:** main\n\n**\u26a0\ufe0f Note:** This quick-fix had partial failures. See operation details below:\n\n`+q:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${x}ms\n\nThe change has been applied and automatically merged to main.\n**Active branch:** main`+(q.match(/\[RECORD:trec\d{6}\]/)?.[0]?"\n"+q.match(/\[RECORD:trec\d{6}\]/)?.[0]:""),E&&(O+="\n\n\u{1f4a1} **Recommendation:** You've created several quick-edits in a row. For better traceability and organization, consider creating a proper feature or bugfix request with multiple tasks for your next change."),{content:[{type:"text",text:O}]}}catch(e){if(f.error("Quick change workflow failed after request creation, cleaning up",{requestId:S,error:(0,l.getErrorMessage)(e)}),P)try{await w.updateTaskStatus(P,"canceled"),f.info("Canceled task after workflow failure",{taskId:P})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:P,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
2523
+ return f.info("Quick fix completed",{requestId:S,duration:M,hasPartialFailure:P}),O=P?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${M}ms\n**Status:** Some operations succeeded, some failed\n\nThe successful changes have been applied and automatically merged to main.\n**Active branch:** main\n\n**\u26a0\ufe0f Note:** This quick-fix had partial failures. See operation details below:\n\n`+q:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${M}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
2524
2524
  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}}}
2525
2525
  const r=t(9860),n=t(4079),o=t(9442),s=t(7684),i=t(355),a=t(5715),c=t(7478),l=t(8824)},3807(module){"use strict"
2526
2526
  module.exports=require("simple-git")},3884(e,exports,t){"use strict"
@@ -2603,9 +2603,9 @@ return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModu
2603
2603
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleWriteFile=async function(e,t,r,n,o,s,i,m,y){const w=i.child({tool:"write_file"}),k=m.startTimer("tool_execution_time"),I=Date.now()
2604
2604
  let b,v,C=d.FileOperationPhase.VALIDATION
2605
2605
  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"}
2606
- try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:E,content:q,format:S,append:P,comment:T}=r,j=!!E,R=!!f
2607
- w.info("Writing content to "+(j?"document":"file"),{taskId:i,filePath:R?f:void 0,documentId:j?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:P,comment:T})
2608
- let M,x,O,$="",D=!1,A=!1
2606
+ try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:E,content:q,format:S,append:T,comment:P}=r,j=!!E,R=!!f
2607
+ w.info("Writing content to "+(j?"document":"file"),{taskId:i,filePath:R?f:void 0,documentId:j?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:T,comment:P})
2608
+ let x,M,O,$="",D=!1,A=!1
2609
2609
  const F=R?f:void 0
2610
2610
  if(j){if(t.apiClient)try{await(0,p.ensureDocumentNotLocked)(E,t.apiClient,w,m,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2611
2611
  throw e}if(!t.documentFileManager)throw Error("Document file manager not available")
@@ -2620,32 +2620,32 @@ R&&z&&H&&(B=await d.autoPromoteTaskStatus(i,L.status,z,H.request?.status,N,n,s,w
2620
2620
  const U=await d.ensureCorrectWorkspaceContext({taskPromoted:B.taskPromoted,requestId:z,context:t,operation:"write_file",logger:w,metrics:m,metricsPrefix:_.metricsPrefix,requireRequestContext:R})
2621
2621
  if(!U.success){if(U.isLockConflict)return{content:[{type:"text",text:"\u274c "+U.error}],isError:!0}
2622
2622
  throw Error(U.error)}if(U.switched&&w.info("Workspace context successfully established",{requestId:z,branchName:U.branchName,operation:"write_file"}),R&&F){const e=d.validateAndNormalizePath(F,t)
2623
- M=e.normalizedPath,x=e.fullPath,$=x
2624
- try{await c.default.access(x),A=!0}catch{A=!1,D=!0}w.debug("Path validated with correct workspace context",{rawPath:F,normalizedPath:M,fullPath:x,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})}if(j&&z)try{await(0,h.validateRequestStatusForDocumentOperation)(z,s,w,m,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2623
+ x=e.normalizedPath,M=e.fullPath,$=M
2624
+ try{await c.default.access(M),A=!0}catch{A=!1,D=!0}w.debug("Path validated with correct workspace context",{rawPath:F,normalizedPath:x,fullPath:M,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})}if(j&&z)try{await(0,h.validateRequestStatusForDocumentOperation)(z,s,w,m,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2625
2625
  throw e}C=d.FileOperationPhase.RECORD_CREATION,m.incrementCounter("write_file_phase",1,{phase:C})
2626
- const{toolRecordId:G}=await d.createFileOperationRecords(i,z,t.projectId,_.recordType,N,{operationType:j?"document":"file",documentId:j?E:void 0,documentFilename:O,filePath:R?M:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S||"text",append:P||!1,wasFileCreated:!A,userComment:T},n,o,w,m,_.metricsPrefix,y)
2626
+ const{toolRecordId:G}=await d.createFileOperationRecords(i,z,t.projectId,_.recordType,N,{operationType:j?"document":"file",documentId:j?E:void 0,documentFilename:O,filePath:R?x:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S||"text",append:T||!1,wasFileCreated:!A,userComment:P},n,o,w,m,_.metricsPrefix,y)
2627
2627
  let W
2628
2628
  if(b=G,v=G,C=_.fileOperationPhase,m.incrementCounter("write_file_phase",1,{phase:C}),"json"===S)if("string"==typeof q)try{JSON.parse(q),W=q}catch(e){throw new u.ValidationError("Content is not valid JSON")}else W=JSON.stringify(q,null,2)
2629
2629
  else W="string"==typeof q?q:JSON.stringify(q,null,2)
2630
2630
  let V=W
2631
2631
  if(R&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
2632
2632
  const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"write_file",{requestId:t.workspaceManager?.getCurrentContext()?.requestId,taskId:i},w,m)
2633
- e.userChangesCommitted&&(w.debug("[WRITE-FILE] User changes committed before write operation",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before write-file operation",{taskId:i,path:M,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[WRITE-FILE] Pre-tool commit failed, continuing with write",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with write operation",{taskId:i,path:M,error:e instanceof Error?e.message:e+""})}if(!$)throw Error("Target path not properly initialized")
2634
- if(w.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:$}),P&&A)try{V=await c.default.readFile($,"utf8")+W}catch(e){w.warn("Failed to read existing content for append",{error:e})}const J=a.default.dirname($)
2635
- if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile($,V,"utf8"),w.info("Content written successfully",{path:R?M:"document:"+E,finalLength:V.length,append:P,wasCreated:D}),j){t.documentFileManager.markForSync(E)
2633
+ e.userChangesCommitted&&(w.debug("[WRITE-FILE] User changes committed before write operation",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before write-file operation",{taskId:i,path:x,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[WRITE-FILE] Pre-tool commit failed, continuing with write",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with write operation",{taskId:i,path:x,error:e instanceof Error?e.message:e+""})}if(!$)throw Error("Target path not properly initialized")
2634
+ if(w.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:$}),T&&A)try{V=await c.default.readFile($,"utf8")+W}catch(e){w.warn("Failed to read existing content for append",{error:e})}const J=a.default.dirname($)
2635
+ if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile($,V,"utf8"),w.info("Content written successfully",{path:R?x:"document:"+E,finalLength:V.length,append:T,wasCreated:D}),j){t.documentFileManager.markForSync(E)
2636
2636
  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
2637
2637
  if(R){if(C=d.FileOperationPhase.GIT_COMMIT,m.incrementCounter("write_file_phase",1,{phase:C}),t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
2638
- Y=e.branchName,w.debug("Retrieved branch name from workspace manager",{branchName:Y,requestId:e.requestId,mode:e.mode,isMainBranch:e.isMainBranch})}try{const e=`${D?"Create":P?"Append to":"Update"} ${M} (${v})`,r=await d.commitToGit(i,M,v,v,e,t,w,m,_.metricsPrefix)
2639
- K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:M,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:R?M:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:P&&A,operationType:j?"document":"file",processingTime:Date.now()-I,userComment:T,...R&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(j?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${D?"Created":P?"Appended to":"Updated"} ${j?`document ${E}${O?` (${O})`:""}`:"file "+M}**\n`
2638
+ Y=e.branchName,w.debug("Retrieved branch name from workspace manager",{branchName:Y,requestId:e.requestId,mode:e.mode,isMainBranch:e.isMainBranch})}try{const e=`${D?"Create":T?"Append to":"Update"} ${x} (${v})`,r=await d.commitToGit(i,x,v,v,e,t,w,m,_.metricsPrefix)
2639
+ K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:x,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:R?x:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:T&&A,operationType:j?"document":"file",processingTime:Date.now()-I,userComment:P,...R&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(j?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${D?"Created":T?"Appended to":"Updated"} ${j?`document ${E}${O?` (${O})`:""}`:"file "+x}**\n`
2640
2640
  Z+=`**Content Length:** ${V.length} characters\n`,R&&Y&&(Z+=`**Branch:** ${Y}\n`),U.lockAcquired&&U.lockedRequestId&&(Z+=`**Locked request:** ${U.lockedRequestId}\n`),R&&K&&(Z+=`**Commit Hash:** ${K.substring(0,8)}\n`,Q&&(Z+=`**Previous Commit:** ${Q.substring(0,8)}\n`)),v&&(Z+=`[RECORD:${v}]\n`),j&&(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}\`.`)
2641
2641
  const X=Date.now()
2642
- return w.info("Write operation completed successfully",{duration:X-I,path:R?M:"document:"+E,contentLength:V.length,wasCreated:D}),k({tool:"write_file",success:!0}),m.incrementCounter("write_file_total",1,{success:!0}),t.workspaceManager?.largeFileWarning&&(Z+=t.workspaceManager.largeFileWarning,t.workspaceManager.largeFileWarning=""),{content:[{type:"text",text:Z}]}}catch(t){const r=Date.now()-I
2642
+ return w.info("Write operation completed successfully",{duration:X-I,path:R?x:"document:"+E,contentLength:V.length,wasCreated:D}),k({tool:"write_file",success:!0}),m.incrementCounter("write_file_total",1,{success:!0}),t.workspaceManager?.largeFileWarning&&(Z+=t.workspaceManager.largeFileWarning,t.workspaceManager.largeFileWarning=""),{content:[{type:"text",text:Z}]}}catch(t){const r=Date.now()-I
2643
2643
  if(w.error("Write operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:C}),v)try{await o.updateToolRecord(v,{metadata:{path:e?.path,status:"failed",error:(0,f.getErrorMessage)(t),phase:C,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return k({tool:"write_file",success:!1}),m.incrementCounter("write_file_errors",1,{phase:C}),{content:[{type:"text",text:"\u274c **Write Operation Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
2644
2644
  const a=i(t(6928)),c=i(t(1943)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824)},4139(e,exports){"use strict"
2645
2645
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ALCHEMY_DIR_NAME=exports.TOKEN_DIR_NAME=void 0,exports.TOKEN_DIR_NAME="alchemy-key",exports.ALCHEMY_DIR_NAME=".alchemy_lab"},4165(e,exports,t){"use strict"
2646
2646
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
2647
2647
  const r=t(6183),n=t(4648)
2648
- exports.def={name:"request_operations",description:"Perform operations on existing requests.\n\nOperations:\n\u2022 complete - Begin completion: provide summary, get criteria keys for verification\n\u2022 verify-criteria - Verify acceptance criteria with evidence per key (triggers merge when all verified)\n\u2022 finalize - Approve and merge a request that is ready for review\n\u2022 approve - Approve a pending request so work can begin\n\u2022 revert - Completely revert a completed request, undoing all changes\n\u2022 get-info - Get comprehensive request information\n\u2022 list - List and filter requests\n\nCompletion is two-phase: first call complete with a summary, then call verify-criteria with evidence for each criterion key.\n\nNote: To create a new request, use the separate create-request tool.",schema:r.RequestOperationsSchema,annotations:{title:"Request Operations",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleRequestOperations)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},4192(e,exports,t){"use strict"
2648
+ exports.def={name:"request_operations",description:"Perform operations on existing requests.\n\nOperations:\n\u2022 complete - Begin completion: provide summary, get criteria keys for verification\n\u2022 verify-criteria - Verify acceptance criteria with evidence per key (triggers merge when all verified)\n\u2022 finalize - Approve and merge a request that is ready for review\n\u2022 approve - Approve a pending request so work can begin\n\u2022 revert - Completely revert a completed request, undoing all changes\n\u2022 get-info - Get comprehensive request information\n\u2022 list - List and filter requests\n\u2022 delete-empty - Delete a request that has no tasks (safe cleanup for mistaken or obsolete requests)\n\nCompletion is two-phase: first call complete with a summary, then call verify-criteria with evidence for each criterion key.\n\nNote: To create a new request, use the separate create-request tool.",schema:r.RequestOperationsSchema,annotations:{title:"Request Operations",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleRequestOperations)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},4192(e,exports,t){"use strict"
2649
2649
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.BaseApiClient=void 0
2650
2650
  const r=t(7163)
2651
2651
  exports.BaseApiClient=class{constructor(e,t,n,o,s){this.failureCount=0,this.circuitState="closed",this.circuitResetTimeout=null,this.baseUrl=e,this.logger=t,this.metrics=n,this.authToken=o,this.options={retryAttempts:3,retryDelay:1e3,timeout:1e4,circuitBreakerThreshold:5,circuitBreakerResetTime:3e4,...s},this.logger.debug("BaseApiClient constructor options:",{providedOptions:s?JSON.stringify(s):"undefined",mergedOptions:JSON.stringify(this.options)})
@@ -2842,21 +2842,23 @@ return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"
2842
2842
  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){"use strict"
2843
2843
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,t,u,h,g,p){const f=h.child({tool:"request_operations"})
2844
2844
  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)
2845
- const d=r.RequestOperationsSchema.parse(e),{requestId:m,operation:y}=d
2846
- switch(f.info("Processing request operation",{requestId:m,operation:y}),y){case"complete":{f.info("Routing to complete-request handler")
2847
- const e={requestId:m,summary:d.complete.summary}
2848
- return await(0,n.handleCompleteRequest)(e,t,u,h,g,p)}case"merge":return f.info("Routing to merge handler"),await(0,l.handleMergeRequest)({requestId:m,verifications:d.merge?.verifications||[]},t,u,h,g,p)
2845
+ const m=r.RequestOperationsSchema.parse(e),{requestId:y,operation:w}=m
2846
+ switch(f.info("Processing request operation",{requestId:y,operation:w}),w){case"complete":{f.info("Routing to complete-request handler")
2847
+ const e={requestId:y,summary:m.complete.summary}
2848
+ return await(0,n.handleCompleteRequest)(e,t,u,h,g,p)}case"merge":return f.info("Routing to merge handler"),await(0,l.handleMergeRequest)({requestId:y,verifications:m.merge?.verifications||[]},t,u,h,g,p)
2849
2849
  case"approve":{f.info("Routing to approve-request handler")
2850
- const e={requestId:m}
2850
+ const e={requestId:y}
2851
2851
  return await(0,c.handleApproveRequest)(e,t,u,h,g,p)}case"revert":{f.info("Routing to revert-request handler")
2852
- const e={requestId:m,reason:d.revert.reason,confirmDestructive:d.revert.confirmDestructive}
2852
+ const e={requestId:y,reason:m.revert.reason,confirmDestructive:m.revert.confirmDestructive}
2853
2853
  return await(0,o.handleRevertRequest)(e,t,u,h,g)}case"get-info":{f.info("Routing to get-request-information handler")
2854
- const e={requestId:m}
2854
+ const e={requestId:y}
2855
2855
  return await(0,s.handleGetRequestInformation)(e,t,u,h,g)}case"list":{f.info("Routing to list-requests handler")
2856
- const e={filters:d.list?.filters}
2856
+ const e={filters:m.list?.filters}
2857
2857
  return await(0,i.handleListRequests)(e,t,u,h,g)}case"search":{f.info("Routing to search-requests handler")
2858
- const e={search:d.search}
2859
- return await(0,a.handleSearchRequests)(e,t,u,h,g)}default:{const e="Unknown operation type: "+y
2858
+ const e={search:m.search}
2859
+ return await(0,a.handleSearchRequests)(e,t,u,h,g)}case"delete-empty":if(f.info("Routing to delete-empty handler"),!y)return{content:[{type:"text",text:"\u274c **Request Operations Failed:** requestId is required for delete-empty"}],isError:!0}
2860
+ try{const e=u.getProxyClient(),r=await e.proxyGet(`/api/projects/${t.projectId}/tasks`,{requestLocalId:y,limit:1}),n=r?.data||r||[]
2861
+ return(Array.isArray(n)?n.length:0)>0?{content:[{type:"text",text:`\u274c Cannot delete ${y}: it has tasks. Only empty requests (no tasks created) can be deleted.`}],isError:!0}:(await e.proxyDelete(`/api/projects/${t.projectId}/requests/${y}`),f.info("Empty request deleted",{requestId:y}),{content:[{type:"text",text:`\u2705 Request ${y} deleted (had no tasks).`}]})}catch(e){return{content:[{type:"text",text:"\u274c **Failed to delete request:** "+(0,d.getErrorMessage)(e)}],isError:!0}}default:{const e="Unknown operation type: "+w
2860
2862
  return f.error(e),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+e}],isError:!0}}}}catch(e){return f.error("Request operations failed",{error:e instanceof Error?e.stack:e+""}),g.incrementCounter("request_operations_errors",1),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
2861
2863
  const r=t(6183),n=t(5715),o=t(6416),s=t(5434),i=t(8037),a=t(233),c=t(1537),l=t(4306),d=t(8824)},4710(e,exports,t){"use strict"
2862
2864
  var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
@@ -3346,43 +3348,43 @@ else{if(!E)throw Error("Either paths or operations must be specified")
3346
3348
  S=E.map((e=>{if(e.path)return{type:"file",target:e.path}
3347
3349
  if(e.documentId)return{type:"document",target:e.documentId}
3348
3350
  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")
3349
- const P=S.filter((e=>"file"===e.type)),T=S.filter((e=>"document"===e.type)),j=S.length
3350
- i.info("Starting mixed file and document deletion operation",{taskId:C,totalOperations:S.length,fileOperations:P.length,documentOperations:T.length,comment:q}),l.validateTaskIdFormat(C,i,o,I.metricsPrefix)
3351
+ const T=S.filter((e=>"file"===e.type)),P=S.filter((e=>"document"===e.type)),j=S.length
3352
+ 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)
3351
3353
  const R=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3352
3354
  i.info("Initial branch context",{initialBranch:R.branch,initialRequestId:R.requestId,isMain:R.isMain})
3353
- const M=[]
3354
- for(const e of P){const{normalizedPath:r,fullPath:n}=l.validateAndNormalizePath(e.target,t)
3355
- M.push({normalized:r,full:n})}k=l.FileOperationPhase.TASK_VALIDATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3356
- const x=M.length>0?M[0].normalized:"document_operations",O=await l.validateTaskId(C,x,n,i,o,I.metricsPrefix),$=O?.requestId,D=await l.validateWorkItemStates(C,x,n,b,t,i,o,I.metricsPrefix),A=await l.autoPromoteTaskStatus(C,O.status,$,D.request?.status,x,n,b,i,o,I.metricsPrefix)
3357
- A.taskPromoted&&i.info(`Auto-promoted task ${C} (${O.title||"Untitled"}) to in_progress for mixed operations`,{taskId:C,taskTitle:O.title,previousStatus:O.status,newStatus:A.newTaskStatus,totalOperations:S.length,fileOperations:P.length,documentOperations:T.length}),A.requestPromoted&&i.info(`Auto-promoted request ${$} to in_progress for file operations`,{requestId:$,previousStatus:D.request?.status,newStatus:A.newRequestStatus,triggeringTaskId:C})
3355
+ const x=[]
3356
+ for(const e of T){const{normalizedPath:r,fullPath:n}=l.validateAndNormalizePath(e.target,t)
3357
+ x.push({normalized:r,full:n})}k=l.FileOperationPhase.TASK_VALIDATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3358
+ const M=x.length>0?x[0].normalized:"document_operations",O=await l.validateTaskId(C,M,n,i,o,I.metricsPrefix),$=O?.requestId,D=await l.validateWorkItemStates(C,M,n,b,t,i,o,I.metricsPrefix),A=await l.autoPromoteTaskStatus(C,O.status,$,D.request?.status,M,n,b,i,o,I.metricsPrefix)
3359
+ A.taskPromoted&&i.info(`Auto-promoted task ${C} (${O.title||"Untitled"}) to in_progress for mixed operations`,{taskId:C,taskTitle:O.title,previousStatus:O.status,newStatus:A.newTaskStatus,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length}),A.requestPromoted&&i.info(`Auto-promoted request ${$} to in_progress for file operations`,{requestId:$,previousStatus:D.request?.status,newStatus:A.newRequestStatus,triggeringTaskId:C})
3358
3360
  const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:$,context:t,operation:"delete-files",logger:i,metrics:o,metricsPrefix:I.metricsPrefix})
3359
3361
  if(!F.success){if(F.isLockConflict)return{content:[{type:"text",text:"\u274c "+F.error}],isError:!0}
3360
3362
  throw Error(F.error)}let N={hadUserMods:!1,userModsCommitHash:void 0}
3361
3363
  if(t.git)try{i.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
3362
3364
  const e=await(0,h.commitUserChangesBeforeToolOperation)(t.git,"delete-files",{requestId:$,taskId:C,workspaceManager:t.workspaceManager},i,o)
3363
- 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:P.length,documentOperations:T.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:P.length,documentOperations:T.length,error:e instanceof Error?e.message:e+""})}i.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:S.length,fileDeletes:P.length,documentDeletes:T.length}),k=l.FileOperationPhase.RECORD_CREATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3364
- const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,$,t.projectId,I.recordType,x,{totalOperations:S.length,fileOperations:P.length,documentOperations:T.length,filePaths:M.map((e=>e.normalized)),documentIds:T.map((e=>e.target)),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},n,u,i,o,I.metricsPrefix,s)
3365
+ e.userChangesCommitted&&(i.debug("[DELETE-FILES] User changes committed before mixed delete operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),i.info("User changes committed before mixed delete-files operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),N={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){i.debug("[DELETE-FILES] Pre-tool commit failed, continuing with mixed delete operations",{error:e instanceof Error?e.message:e+""}),i.warn("Pre-tool user changes commit failed, continuing with mixed delete operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,error:e instanceof Error?e.message:e+""})}i.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:S.length,fileDeletes:T.length,documentDeletes:P.length}),k=l.FileOperationPhase.RECORD_CREATION,o.incrementCounter("delete_files_phase",1,{phase:k})
3366
+ const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,$,t.projectId,I.recordType,M,{totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,filePaths:x.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)
3365
3367
  y=L,w=L,k=I.fileOperationPhase,o.incrementCounter("delete_files_phase",1,{phase:k})
3366
3368
  const H=[]
3367
3369
  let B=0
3368
- T.length>0&&r.setProjectId(t.projectId)
3369
- for(let e=0;e<M.length;e++){const t=M[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3370
+ P.length>0&&r.setProjectId(t.projectId)
3371
+ for(let e=0;e<x.length;e++){const t=x[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3370
3372
  try{try{await a.default.access(t.full)}catch(e){throw Error("File not found: "+t.normalized)}if((await a.default.stat(t.full)).isDirectory())throw Error("Cannot 'delete' a directory: "+t.normalized)
3371
- await a.default.unlink(t.full),r.success=!0,B++,i.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete file "+t.normalized,{error:r.error})}H.push(r)}const U=T.length>0?r.getDocumentClient():null
3372
- for(const e of T){const t=e.target,n={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3373
+ await a.default.unlink(t.full),r.success=!0,B++,i.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete file "+t.normalized,{error:r.error})}H.push(r)}const U=P.length>0?r.getDocumentClient():null
3374
+ for(const e of P){const t=e.target,n={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3373
3375
  try{let e
3374
3376
  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,b,i,o,"delete-document")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
3375
3377
  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)
3376
3378
  throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,f.getErrorMessage)(e)}`)}const s=await U.archiveDocument(t)
3377
3379
  n.success=!0,n.filename=s.filename,B++,i.info("Document archived successfully",{documentId:s.id,filename:s.filename,archivedAt:s.archived_at})}catch(e){n.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete document "+t,{error:n.error})}H.push(n)}const G=Date.now()-m
3378
- o.recordValue("delete_files_time",G),o.incrementCounter("delete_files_operations_total",j),o.incrementCounter("delete_files_operations_success",B),o.incrementCounter("delete_files_operations_failed",j-B),o.incrementCounter("delete_files_file_operations",P.length),o.incrementCounter("delete_files_document_operations",T.length),B===j?o.incrementCounter("delete_files_success",1):B>0?o.incrementCounter("delete_files_partial_success",1):o.incrementCounter("delete_files_total_failure",1)
3380
+ o.recordValue("delete_files_time",G),o.incrementCounter("delete_files_operations_total",j),o.incrementCounter("delete_files_operations_success",B),o.incrementCounter("delete_files_operations_failed",j-B),o.incrementCounter("delete_files_file_operations",T.length),o.incrementCounter("delete_files_document_operations",P.length),B===j?o.incrementCounter("delete_files_success",1):B>0?o.incrementCounter("delete_files_partial_success",1):o.incrementCounter("delete_files_total_failure",1)
3379
3381
  let W=null
3380
3382
  if(B>0){k=l.FileOperationPhase.GIT_COMMIT,o.incrementCounter("delete_files_phase",1,{phase:k})
3381
3383
  const e=H.filter((e=>e.success)),r=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
3382
3384
  let s
3383
- s=r>0&&n>0?`Delete ${r} files and ${n} documents - ${q}`:r>0?1===r?"Delete file - "+q:`Delete ${r} files - ${q}`:1===n?"Delete document - "+q:`Delete ${n} documents - ${q}`,W=await l.commitToGit(C,x,L,z,s,t,i,o,I.metricsPrefix)}k=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:k})
3385
+ s=r>0&&n>0?`Delete ${r} files and ${n} documents - ${q}`:r>0?1===r?"Delete file - "+q:`Delete ${r} files - ${q}`:1===n?"Delete document - "+q:`Delete ${n} documents - ${q}`,W=await l.commitToGit(C,M,L,z,s,t,i,o,I.metricsPrefix)}k=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:k})
3384
3386
  const V=H.filter((e=>e.success)),J=H.filter((e=>!e.success))
3385
- await l.updateFileOperationRecords(C,y,w,x,I.recordType,B===j?`Successfully deleted all ${j} operations`:`Deleted ${B}/${j} operations successfully`,{status:B===j?"completed":"partial_success",commitHash:W?.commitHash,previousCommitHash:W?.previousCommitHash,totalOperations:j,fileOperations:P.length,documentOperations:T.length,successCount:B,failureCount:j-B,successfulOperations:V.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:J.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},B===j?`Successfully deleted all ${j} operations`:`Deleted ${B}/${j} operations successfully`,n,u,i,o,I.metricsPrefix)
3387
+ await l.updateFileOperationRecords(C,y,w,M,I.recordType,B===j?`Successfully deleted all ${j} operations`:`Deleted ${B}/${j} operations successfully`,{status:B===j?"completed":"partial_success",commitHash:W?.commitHash,previousCommitHash:W?.previousCommitHash,totalOperations:j,fileOperations:T.length,documentOperations:P.length,successCount:B,failureCount:j-B,successfulOperations:V.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:J.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},B===j?`Successfully deleted all ${j} operations`:`Deleted ${B}/${j} operations successfully`,n,u,i,o,I.metricsPrefix)
3386
3388
  const K=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3387
3389
  let Y=""
3388
3390
  if(B===j){const e=V.filter((e=>"file"===e.type)).length,t=V.filter((e=>"document"===e.type)).length
@@ -3466,7 +3468,7 @@ return"delegate"===e.operation?r&&!n&&!t:"follow-up"===e.operation?n&&!r&&t:"che
3466
3468
  return"request"===e.operation?t&&!r:"check-status"===e.operation?!t&&r:"list"===e.operation&&!t&&!r}),{message:"Invalid operation data: request requires request object, check-status requires sessionId"}),exports.SwitchToRequestBranchSchema=r.z.object({requestId:s}),exports.InsertLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.CreateDocumentSchema=r.z.object({requestId:s.optional(),filename:r.z.string().refine((e=>e.toLowerCase().endsWith(".md")),{message:"Filename must end with .md extension"}),content:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"],{errorMap(){return{message:"Document type must be one of: Report, Documentation, Plan, Other"}}}),comment:r.z.string()}),exports.SearchDocumentsSchema=r.z.object({query:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),requestId:s.optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both")}),exports.DocumentOperationsSchema=r.z.object({operation:r.z.enum(["create","search","create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"]),documentId:i.optional(),requestId:s.optional(),filename:r.z.string().optional(),content:r.z.string().optional(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),comment:r.z.string().optional(),query:r.z.string().optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both"),versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional(),versionNumber:r.z.number().int().min(1).optional(),selectedText:r.z.string().optional(),prefixContext:r.z.string().optional(),suffixContext:r.z.string().optional(),lineHint:r.z.number().int().optional(),body:r.z.string().optional(),annotationId:r.z.string().optional()}).superRefine(((e,t)=>{const r=e.operation;["create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"].includes(r)&&!e.documentId&&t.addIssue({code:"custom",message:`documentId is required for '${r}'. Example: { "operation": "${r}", "documentId": "doc000001" }`}),"create"===r&&(e.filename?e.filename.toLowerCase().endsWith(".md")||t.addIssue({code:"custom",message:"Filename must end with .md extension"}):t.addIssue({code:"custom",message:"filename is required for create (must end with .md)"}),e.content||t.addIssue({code:"custom",message:"content is required for create"}),e.type||t.addIssue({code:"custom",message:"type is required for create (Report, Documentation, Plan, or Other)"}),e.comment||t.addIssue({code:"custom",message:"comment is required for create"})),"search"!==r||e.query||t.addIssue({code:"custom",message:'query is required for search. Example: { "operation": "search", "query": "search term" }'}),"get-version"!==r&&"restore-version"!==r||e.versionNumber||t.addIssue({code:"custom",message:`versionNumber is required for '${r}'`}),"create-annotation"===r&&(e.selectedText||t.addIssue({code:"custom",message:"selectedText is required for create-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for create-annotation"})),"reply-to-annotation"===r&&(e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for reply-to-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for reply-to-annotation"})),"resolve-annotation"!==r||e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for resolve-annotation"})}))
3467
3469
  const c=r.z.string().refine((e=>!!e&&(/^doc_[0-9A-Z]{26}$/i.test(e)||/^plan\d{6}$/.test(e))),{message:"Plan ID must match format: doc_[26 alphanumeric] (ULID) or plan###### (local ID)"})
3468
3470
  exports.PlanReadSchema=r.z.object({operation:r.z.enum(["get","get-active","list","get-history","get-requests"]),planId:c.optional(),searchQuery:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["createdAt","updatedAt","filename"]).default("updatedAt"),sortDirection:r.z.enum(["ASC","DESC"]).default("DESC")}).superRefine(((e,t)=>{["get","get-history","get-requests"].includes(e.operation)&&!e.planId&&t.addIssue({code:"custom",message:`planId is required for '${e.operation}'. Example: { "operation": "${e.operation}", "planId": "plan000001" }`})})),exports.PlanWriteSchema=r.z.object({operation:r.z.enum(["update","append","replace","create-snapshot","restore","set-active"]),planId:c,content:r.z.string().optional(),name:r.z.string().optional().describe("Optional new name for the plan"),old:r.z.string().optional().describe("Text to find in the plan (for replace)"),new:r.z.string().optional().describe("Replacement text (for replace)"),versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional(),versionNumber:r.z.number().int().min(1).optional()}).superRefine(((e,t)=>{const r=e.operation
3469
- "update"!==r&&"append"!==r||e.content||t.addIssue({code:"custom",message:`content is required for '${r}'. Example: { "operation": "${r}", "planId": "plan000001", "content": "..." }`}),"replace"===r&&(e.old||t.addIssue({code:"custom",message:'old is required for replace. Example: { "operation": "replace", "planId": "plan000001", "old": "find this", "new": "replace with" }'}),void 0===e.new&&t.addIssue({code:"custom",message:"new is required for replace"})),"restore"!==r||e.versionNumber||t.addIssue({code:"custom",message:'versionNumber is required for restore. Example: { "operation": "restore", "planId": "plan000001", "versionNumber": 1 }'})})),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional(),password:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:s,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),operationType:r.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:r.z.object({replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).optional(),insertLines:r.z.object({insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).optional(),replaceLines:r.z.object({replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).optional(),deleteString:r.z.object({patterns:r.z.array(r.z.string()),mode:r.z.enum(["all","unique"]).optional()}).optional(),deleteLines:r.z.object({lines:r.z.string()}).optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}).refine((e=>"replace-string"===e.operationType?e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"insert-lines"===e.operationType?e.insertLines&&!e.replaceString&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"replace-lines"===e.operationType?e.replaceLines&&!e.replaceString&&!e.insertLines&&!e.deleteString&&!e.deleteLines:"delete-string"===e.operationType?e.deleteString&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteLines:"delete-lines"===e.operationType&&e.deleteLines&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString),{message:"Invalid operation data"})),comment:r.z.string()}),exports.ManageFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}))}).optional(),getFileInfo:r.z.object({path:r.z.string()}).optional()}).refine((e=>"create-directory"===e.operationType?e.createDirectory&&!e.moveFiles&&!e.deleteFiles&&!e.getFileInfo:"move-files"===e.operationType?e.moveFiles&&!e.createDirectory&&!e.deleteFiles&&!e.getFileInfo:"delete-files"===e.operationType?e.deleteFiles&&!e.createDirectory&&!e.moveFiles&&!e.getFileInfo:"get-file-info"===e.operationType&&e.getFileInfo&&!e.createDirectory&&!e.moveFiles&&!e.deleteFiles),{message:"Invalid operation data"})),comment:r.z.string()}),exports.RequestOperationsSchema=r.z.object({requestId:s.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search"]),complete:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({summary:r.z.string()})).optional(),merge:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({verifications:r.z.array(r.z.object({key:r.z.string().min(2).max(4),evidence:r.z.string().min(1)})).min(1)})).optional(),revert:r.z.object({reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}).optional(),list:r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),approve:r.z.object({}).optional()}).superRefine(((e,t)=>{const r=!!e.requestId,n=e.operation
3471
+ "update"!==r&&"append"!==r||e.content||t.addIssue({code:"custom",message:`content is required for '${r}'. Example: { "operation": "${r}", "planId": "plan000001", "content": "..." }`}),"replace"===r&&(e.old||t.addIssue({code:"custom",message:'old is required for replace. Example: { "operation": "replace", "planId": "plan000001", "old": "find this", "new": "replace with" }'}),void 0===e.new&&t.addIssue({code:"custom",message:"new is required for replace"})),"restore"!==r||e.versionNumber||t.addIssue({code:"custom",message:'versionNumber is required for restore. Example: { "operation": "restore", "planId": "plan000001", "versionNumber": 1 }'})})),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional(),password:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:s,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),operationType:r.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:r.z.object({replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).optional(),insertLines:r.z.object({insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).optional(),replaceLines:r.z.object({replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).optional(),deleteString:r.z.object({patterns:r.z.array(r.z.string()),mode:r.z.enum(["all","unique"]).optional()}).optional(),deleteLines:r.z.object({lines:r.z.string()}).optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}).refine((e=>"replace-string"===e.operationType?e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"insert-lines"===e.operationType?e.insertLines&&!e.replaceString&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"replace-lines"===e.operationType?e.replaceLines&&!e.replaceString&&!e.insertLines&&!e.deleteString&&!e.deleteLines:"delete-string"===e.operationType?e.deleteString&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteLines:"delete-lines"===e.operationType&&e.deleteLines&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString),{message:"Invalid operation data"})),comment:r.z.string()}),exports.ManageFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}))}).optional(),getFileInfo:r.z.object({path:r.z.string()}).optional()}).refine((e=>"create-directory"===e.operationType?e.createDirectory&&!e.moveFiles&&!e.deleteFiles&&!e.getFileInfo:"move-files"===e.operationType?e.moveFiles&&!e.createDirectory&&!e.deleteFiles&&!e.getFileInfo:"delete-files"===e.operationType?e.deleteFiles&&!e.createDirectory&&!e.moveFiles&&!e.getFileInfo:"get-file-info"===e.operationType&&e.getFileInfo&&!e.createDirectory&&!e.moveFiles&&!e.deleteFiles),{message:"Invalid operation data"})),comment:r.z.string()}),exports.RequestOperationsSchema=r.z.object({requestId:s.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search","delete-empty"]),complete:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({summary:r.z.string()})).optional(),merge:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({verifications:r.z.array(r.z.object({key:r.z.string().min(2).max(4),evidence:r.z.string().min(1)})).min(1)})).optional(),revert:r.z.object({reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}).optional(),list:r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),approve:r.z.object({}).optional()}).superRefine(((e,t)=>{const r=!!e.requestId,n=e.operation
3470
3472
  if(["complete","merge","approve","revert","get-info"].includes(n)&&!r)return void t.addIssue({code:"custom",message:`requestId is required for '${n}' operation`})
3471
3473
  const o={complete:{field:"complete",hint:'Provide: { complete: { summary: "..." } }'},merge:{field:"merge",hint:'Provide: { merge: { verifications: [{key: "1a", evidence: "..."}] } }'},revert:{field:"revert",hint:'Provide: { revert: { reason: "..." } }'},search:{field:"search",hint:'Provide: { search: { query: "..." } }'}}[n]
3472
3474
  o&&!e[o.field]&&t.addIssue({code:"custom",message:`'${n}' operation requires '${o.field}' data. ${o.hint}`})})),exports.QuickWriteSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),path:r.z.string().optional(),documentId:i.optional(),content:r.z.union([r.z.string(),r.z.record(r.z.any()),r.z.array(r.z.unknown())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}),exports.QuickReplaceSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:r.z.boolean().optional()})).min(1),fuzzy_match:r.z.boolean().optional(),comment:r.z.string().min(1,"Comment describing the change is required")}),exports.QuickManageSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}))}).optional()})).min(1)}),exports.GenerateRequestJournalSchema=r.z.object({requestId:r.z.string().regex(/^req[_\d].+$/,"Invalid request ID format. Expected format: req_[26 chars] or req######")}),exports.MetaWorkflowListSchema=r.z.object({}),exports.MetaWorkflowGetSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the workflow"),shortName:r.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:r.z.string().optional().describe("Description of what the workflow does"),documentation:r.z.string().optional().describe("Detailed documentation"),defaultAgent:r.z.string().optional().describe("Default agent template to use"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior: auto-merge (default), auto-test-then-merge, or manual-review"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaWorkflowUpdateSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to update"),name:r.z.string().min(1).optional().describe("New name"),shortName:r.z.string().max(10).optional().describe("New short name (max 10 chars)"),description:r.z.string().optional().describe("New description"),documentation:r.z.string().optional().describe("New documentation"),defaultAgent:r.z.string().optional().describe("New default agent"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaRecipeListSchema=r.z.object({}),exports.MetaRecipeGetSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to retrieve")}),exports.MetaRecipeCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the recipe"),description:r.z.string().optional().describe("Description of what the recipe does"),documentation:r.z.string().optional().describe("Detailed documentation")}),exports.MetaRecipeAddHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to add the hook to"),hookId:r.z.string().describe("Hook template ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the recipe (0-based, appended if omitted)")}),exports.MetaRecipeRemoveHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to remove the hook from"),hookId:r.z.string().describe("Hook template ID to remove")}),exports.MetaHookListSchema=r.z.object({}),exports.MetaHookCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the hook"),description:r.z.string().optional().describe("Description of what the hook does"),eventType:r.z.string().describe("Event type that triggers this hook (e.g., session_idle, request_completed, custom:plan_ready)"),category:r.z.enum(["alchemy","session","message","editing","reading","file_management","documents","history","tool"]).default("session").describe("Hook category"),agent:r.z.string().describe("Agent template to execute when hook fires"),promptTemplate:r.z.string().describe("Prompt template with {{variable}} substitution"),condition:r.z.record(r.z.any()).optional().describe("Condition object for filtering when hook fires"),executionMode:r.z.enum(["same_session","sub_agent","background","notification","direct_report"]).default("background").describe("How to execute the hook"),timing:r.z.enum(["before","after"]).default("after").describe("When to fire relative to the event"),maxIterations:r.z.number().int().min(1).optional().describe("Maximum times to fire per session"),emitEvent:r.z.string().optional().describe("Custom event to emit on completion"),emitEventOnCondition:r.z.union([r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}),r.z.array(r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}))]).optional().describe("Conditional event emission based on output")}),exports.MetaWorkflowAddRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to add the recipe to"),recipeId:r.z.string().describe("Recipe ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the workflow (0-based, appended if omitted)")}),exports.MetaWorkflowRemoveRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to remove the recipe from"),recipeId:r.z.string().describe("Recipe ID to remove")}),exports.MetaAgentListSchema=r.z.object({}),exports.MetaReferenceSchema=r.z.object({}),exports.TestingProcessListSchema=r.z.object({}),exports.TestingProcessGetSchema=r.z.object({processId:r.z.string().describe("Test process ID to retrieve")})
@@ -3617,48 +3619,48 @@ try{const i=d.validateArgs(e,l.InsertLinesSchema),{taskId:C,operations:_,comment
3617
3619
  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")
3618
3620
  const q=_.filter((e=>e.path)),S=_.filter((e=>e.documentId))
3619
3621
  y.info("Operation breakdown",{fileOperations:q.length,documentOperations:S.length})
3620
- const P=[]
3622
+ const T=[]
3621
3623
  for(const e of q){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.path,t)
3622
- P.push({type:"file",path:r,fullPath:n,insertions:e.insertions})}const T=[]
3624
+ T.push({type:"file",path:r,fullPath:n,insertions:e.insertions})}const P=[]
3623
3625
  if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3624
- for(const e of S)T.push({type:"document",documentId:e.documentId,insertions:e.insertions})
3625
- if(T.length>0&&t.apiClient){const e=T.map((e=>e.documentId))
3626
+ for(const e of S)P.push({type:"document",documentId:e.documentId,insertions:e.insertions})
3627
+ if(P.length>0&&t.apiClient){const e=P.map((e=>e.documentId))
3626
3628
  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}
3627
3629
  throw e}}b=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("insert_lines_phase",1,{phase:b})
3628
- const j=P.length>0?P[0].path:"document-operation",R=await d.validateTaskId(C,j,n,y,a,v.metricsPrefix),M=R?.requestId
3629
- let x=null
3630
- P.length>0&&M&&(x=await d.validateWorkItemStates(C,P[0].path,n,s,t,y,a,v.metricsPrefix))
3630
+ const j=T.length>0?T[0].path:"document-operation",R=await d.validateTaskId(C,j,n,y,a,v.metricsPrefix),x=R?.requestId
3631
+ let M=null
3632
+ T.length>0&&x&&(M=await d.validateWorkItemStates(C,T[0].path,n,s,t,y,a,v.metricsPrefix))
3631
3633
  let O={taskPromoted:!1,requestPromoted:!1}
3632
- P.length>0&&M&&x&&(O=await d.autoPromoteTaskStatus(C,R.status,M,x.request?.status,P[0].path,n,s,y,a,v.metricsPrefix),O.taskPromoted&&y.info("Auto-promoted task to in_progress for insert-lines operation",{taskId:C,requestId:M,previousStatus:R.status,newStatus:O.newTaskStatus,triggeringOperation:"insert-lines"}))
3633
- const $=await d.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:M,context:t,operation:"insert-lines",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
3634
+ T.length>0&&x&&M&&(O=await d.autoPromoteTaskStatus(C,R.status,x,M.request?.status,T[0].path,n,s,y,a,v.metricsPrefix),O.taskPromoted&&y.info("Auto-promoted task to in_progress for insert-lines operation",{taskId:C,requestId:x,previousStatus:R.status,newStatus:O.newTaskStatus,triggeringOperation:"insert-lines"}))
3635
+ const $=await d.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:x,context:t,operation:"insert-lines",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
3634
3636
  if(!$.success){if($.isLockConflict)return{content:[{type:"text",text:"\u274c "+$.error}],isError:!0}
3635
- throw Error($.error)}if(P.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:P.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3636
- for(let e=0;e<P.length;e++){const r=P[e],n=q[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
3637
- P[e]={...r,path:o,fullPath:s}}}if(T.length>0&&M)try{await(0,h.validateRequestStatusForDocumentOperation)(M,s,y,a,"insert-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3637
+ throw Error($.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3638
+ for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
3639
+ T[e]={...r,path:o,fullPath:s}}}if(P.length>0&&x)try{await(0,h.validateRequestStatusForDocumentOperation)(x,s,y,a,"insert-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3638
3640
  throw e}b=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("insert_lines_phase",1,{phase:b})
3639
- const D=[...P.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...T.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:A}=await d.createFileOperationRecords(C,M,t.projectId,v.recordType,j,{operationCount:_.length,fileOperations:P.length,documentOperations:T.length,operations:D,userComment:E},n,o,y,a,v.metricsPrefix,m)
3640
- if(k=A,I=A,b=v.fileOperationPhase,a.incrementCounter("insert_lines_phase",1,{phase:b}),P.length>0&&t.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
3641
- const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"insert-lines",{requestId:M,taskId:C,workspaceManager:t.workspaceManager},y,a)
3642
- 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:P.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:P.length,error:e instanceof Error?e.message:e+""})}y.debug("[INSERT-LINES] Proceeding with file operations",{fileCount:P.length})
3641
+ const D=[...T.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...P.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:A}=await d.createFileOperationRecords(C,x,t.projectId,v.recordType,j,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:D,userComment:E},n,o,y,a,v.metricsPrefix,m)
3642
+ if(k=A,I=A,b=v.fileOperationPhase,a.incrementCounter("insert_lines_phase",1,{phase:b}),T.length>0&&t.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
3643
+ const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"insert-lines",{requestId:x,taskId:C,workspaceManager:t.workspaceManager},y,a)
3644
+ 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})
3643
3645
  const F=[]
3644
3646
  let N=0,L=0,z=0
3645
- for(const e of P){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3647
+ for(const e of T){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3646
3648
  try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
3647
3649
  const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.insertions)
3648
- t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,z++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),N+=t.failedInsertions,L+=t.totalLinesAdded}catch(r){t.error=(0,f.getErrorMessage)(r),t.failedInsertions=e.insertions.length,N+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}F.push(t)}for(const e of T){const n={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3650
+ t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,z++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),N+=t.failedInsertions,L+=t.totalLinesAdded}catch(r){t.error=(0,f.getErrorMessage)(r),t.failedInsertions=e.insertions.length,N+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}F.push(t)}for(const e of P){const n={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3649
3651
  try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.documentFileManager.getCachedDocumentInfo(e.documentId)
3650
3652
  n.filename=s?.filename
3651
3653
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
3652
- 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(T.length>0)try{for(const e of T){const r=F.find((t=>t.documentId===e.documentId))
3653
- r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const H=await d.handleMultiFileGitCommit(C,P,F,z,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),B=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:U,failedOperations:G,totalSuccessfulChanges:W,overallSuccess:V,successfulFiles:J,failedFiles:K}=B
3654
- try{await o.updateToolRecord(I,{metadata:{path:P.length>0?P[0].path:"document:"+T[0]?.documentId,status:V?"completed":"failed",error:V?void 0:G+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:D,totalSuccessfulInsertions:W,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:E,...P.length>0&&H.success&&H.commitHash&&{commitHash:H.commitHash,previousCommitHash:H.previousCommitHash||void 0}},note:V?`Line insertion completed: ${U}/${F.length} operations successful${P.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${G}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
3654
+ 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))
3655
+ r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const H=await d.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),B=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:U,failedOperations:G,totalSuccessfulChanges:W,overallSuccess:V,successfulFiles:J,failedFiles:K}=B
3656
+ 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:G+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:D,totalSuccessfulInsertions:W,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:E,...T.length>0&&H.success&&H.commitHash&&{commitHash:H.commitHash,previousCommitHash:H.previousCommitHash||void 0}},note:V?`Line insertion completed: ${U}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${G}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
3655
3657
  if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${U+G}\n`,Y+=`- **Successful operations:** ${U}\n`,Y+=`- **Failed operations:** ${G}\n`,Y+=`- **Total insertions:** ${W} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n`,Y+="\n",H.success&&H.commitHash&&(Y+="**Git Commit:**\n",Y+=`- **Commit Hash:** ${H.commitHash.substring(0,8)}\n`,Y+=`- **Files Committed:** ${H.filesCommitted.length}\n`,H.previousCommitHash&&(Y+=`- **Previous Commit:** ${H.previousCommitHash.substring(0,8)}\n`),Y+="\n"),$.lockAcquired&&$.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
3656
3658
  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"
3657
3659
  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}`
3658
3660
  Y+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{Y+="**Summary:**\n",Y+=`- **Total Operations:** ${F.length}\n`,Y+=`- **Successful:** ${U}\n`,Y+=`- **Failed:** ${G}\n`,Y+=`- **Total Insertions:** ${W} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n\n`,Y+="**Detailed Results:**\n\n"
3659
3661
  for(const e of F){if("file"===e.type?Y+=`### File: ${e.path}\n`:(Y+="### Document: "+e.documentId,e.filename&&(Y+=` (${e.filename})`),Y+="\n"),Y+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error?Y+=`- **Error:** ${e.error}\n`:(Y+=`- **Insertions:** ${e.successfulInsertions} successful`,e.failedInsertions>0&&(Y+=`, ${e.failedInsertions} failed`),Y+="\n",Y+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.insertions.some((e=>!e.success))){Y+="- **Failed Insertion Details:**\n"
3660
3662
  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}`
3661
- Y+=` - ${t.type} insertion ${e}: ${t.error}\n`}}Y+="\n"}}T.length>0&&(Y+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3663
+ 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")
3662
3664
  const Q=Date.now()-w
3663
3665
  return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:U,failedOperations:G}),a.incrementCounter("insert_lines_total",1,{success:V}),{content:[{type:"text",text:Y}],isError:!V}}catch(t){const r=Date.now()-w
3664
3666
  if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:b}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,f.getErrorMessage)(t),phase:b,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("insert_lines_errors",1,{phase:b}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
@@ -3676,21 +3678,21 @@ const q=new a.FileOperationsClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryA
3676
3678
  I.registerClient(q),m.info("RequestClient constructor received token: "+(v?"present":"missing"))
3677
3679
  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})
3678
3680
  I.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
3679
- const P=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})
3680
- I.registerClient(P)
3681
- const T=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})
3681
+ 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})
3682
3682
  I.registerClient(T)
3683
+ 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})
3684
+ I.registerClient(P)
3683
3685
  const j=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})
3684
3686
  if(I.registerClient(j),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
3685
3687
  try{m.info("Creating ProjectSynchronizer components")
3686
3688
  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})
3687
3689
  _.setProjectSynchronizer(n),m.info("ProjectSynchronizer created and connected to ProjectClient")}catch(e){const t="Failed to create required ProjectSynchronizer components: "+(0,h.getErrorMessage)(e)
3688
- throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const R=new o.ApiClient(b,_,E,q,S,P,T,j,m)
3690
+ throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const R=new o.ApiClient(b,_,E,q,S,T,P,j,m)
3689
3691
  m.info("API client initialized with specialized clients"),v?(R.setAuthToken(v),m.info("Auth token set on ApiClient during creation",{hasToken:!0,tokenLength:v.length})):m.warn("No auth token available during ApiClient creation",{info:"Client will need to authenticate before making requests"})
3690
- const M=I.verifyAllClients()
3691
- M.success?m.info("Token consistency verified across all clients"):m.error(`Token inconsistency detected in ${M.failedClients.length} clients: ${M.failedClients.join(", ")}`)
3692
- const x=R.getAuthToken()
3693
- return v&&!x?(m.error("CRITICAL: ApiClient token was not set properly!"),R.setAuthToken(v)):x&&m.info("ApiClient token verified",{tokenLength:x.length,matches:x===v}),m.info("API client creation completed successfully"),R}}},6540(e,exports){"use strict"
3692
+ const x=I.verifyAllClients()
3693
+ x.success?m.info("Token consistency verified across all clients"):m.error(`Token inconsistency detected in ${x.failedClients.length} clients: ${x.failedClients.join(", ")}`)
3694
+ const M=R.getAuthToken()
3695
+ return v&&!M?(m.error("CRITICAL: ApiClient token was not set properly!"),R.setAuthToken(v)):M&&m.info("ApiClient token verified",{tokenLength:M.length,matches:M===v}),m.info("API client creation completed successfully"),R}}},6540(e,exports){"use strict"
3694
3696
  var t
3695
3697
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6595(e,exports,t){"use strict"
3696
3698
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ApiClient=void 0
@@ -3735,34 +3737,34 @@ let I,b,v=d.FileOperationPhase.VALIDATION
3735
3737
  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"}
3736
3738
  try{const i=d.validateArgs(e,l.ReplaceLinesSchema),{taskId:_,operations:E,comment:q}=i
3737
3739
  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")
3738
- const S=E.filter((e=>e.path)),P=E.filter((e=>e.documentId))
3739
- w.info("Operation breakdown",{fileOperations:S.length,documentOperations:P.length})
3740
- const T=[]
3740
+ const S=E.filter((e=>e.path)),T=E.filter((e=>e.documentId))
3741
+ w.info("Operation breakdown",{fileOperations:S.length,documentOperations:T.length})
3742
+ const P=[]
3741
3743
  for(const e of S){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.path,t)
3742
- T.push({type:"file",path:r,fullPath:n,replacements:e.replacements.map((e=>({lines:(0,y.parseLineSpec)(e.lines),content:e.content})))})}const j=[]
3743
- if(P.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3744
- for(const e of P)j.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,y.parseLineSpec)(e.lines),content:e.content})))})
3744
+ P.push({type:"file",path:r,fullPath:n,replacements:e.replacements.map((e=>({lines:(0,y.parseLineSpec)(e.lines),content:e.content})))})}const j=[]
3745
+ if(T.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3746
+ for(const e of T)j.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,y.parseLineSpec)(e.lines),content:e.content})))})
3745
3747
  if(j.length>0&&t.apiClient){const e=j.map((e=>e.documentId))
3746
3748
  try{await(0,p.ensureDocumentsNotLocked)(e,t.apiClient,w,a,"replace-lines-documents")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3747
3749
  throw e}}v=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
3748
- const R=T.length>0?T[0].path:"document-operation",M=await d.validateTaskId(_,R,n,w,a,C.metricsPrefix),x=M?.requestId
3750
+ const R=P.length>0?P[0].path:"document-operation",x=await d.validateTaskId(_,R,n,w,a,C.metricsPrefix),M=x?.requestId
3749
3751
  let O=null
3750
- T.length>0&&x&&(O=await d.validateWorkItemStates(_,T[0].path,n,s,t,w,a,C.metricsPrefix))
3752
+ P.length>0&&M&&(O=await d.validateWorkItemStates(_,P[0].path,n,s,t,w,a,C.metricsPrefix))
3751
3753
  let $={taskPromoted:!1,requestPromoted:!1}
3752
- T.length>0&&x&&O&&($=await d.autoPromoteTaskStatus(_,M.status,x,O.request?.status,T[0].path,n,s,w,a,C.metricsPrefix),$.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:_,requestId:x,previousStatus:M.status,newStatus:$.newTaskStatus,triggeringOperation:"replace-lines"}))
3753
- const D=await d.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:x,context:t,operation:"replace-lines",logger:w,metrics:a,metricsPrefix:C.metricsPrefix})
3754
+ P.length>0&&M&&O&&($=await d.autoPromoteTaskStatus(_,x.status,M,O.request?.status,P[0].path,n,s,w,a,C.metricsPrefix),$.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:_,requestId:M,previousStatus:x.status,newStatus:$.newTaskStatus,triggeringOperation:"replace-lines"}))
3755
+ const D=await d.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:M,context:t,operation:"replace-lines",logger:w,metrics:a,metricsPrefix:C.metricsPrefix})
3754
3756
  if(!D.success){if(D.isLockConflict)return{content:[{type:"text",text:"\u274c "+D.error}],isError:!0}
3755
- throw Error(D.error)}if(T.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3756
- for(let e=0;e<T.length;e++){const r=T[e],n=S[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
3757
- T[e]={...r,path:o,fullPath:s}}}if(j.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}
3757
+ throw Error(D.error)}if(P.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:P.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
3758
+ for(let e=0;e<P.length;e++){const r=P[e],n=S[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
3759
+ P[e]={...r,path:o,fullPath:s}}}if(j.length>0&&M)try{await(0,h.validateRequestStatusForDocumentOperation)(M,s,w,a,"replace-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3758
3760
  throw e}v=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
3759
- const A=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...j.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await d.createFileOperationRecords(_,x,t.projectId,C.recordType,R,{operationCount:E.length,fileOperations:T.length,documentOperations:j.length,operations:A,userComment:q},n,o,w,a,C.metricsPrefix,m)
3760
- if(I=F,b=F,v=C.fileOperationPhase,a.incrementCounter("replace_lines_phase",1,{phase:v}),T.length>0&&t.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
3761
- const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},w,a)
3762
- 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:T.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:T.length,error:e instanceof Error?e.message:e+""})}w.debug("[REPLACE-LINES] Proceeding with file operations",{fileCount:T.length})
3761
+ const A=[...P.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...j.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await d.createFileOperationRecords(_,M,t.projectId,C.recordType,R,{operationCount:E.length,fileOperations:P.length,documentOperations:j.length,operations:A,userComment:q},n,o,w,a,C.metricsPrefix,m)
3762
+ if(I=F,b=F,v=C.fileOperationPhase,a.incrementCounter("replace_lines_phase",1,{phase:v}),P.length>0&&t.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
3763
+ const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:M,taskId:_,workspaceManager:t.workspaceManager},w,a)
3764
+ 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})
3763
3765
  const N=[]
3764
3766
  let L=0,z=0,H=0,B=0
3765
- for(const e of T){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3767
+ for(const e of P){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3766
3768
  try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
3767
3769
  const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.replacements)
3768
3770
  t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,t.totalLinesReplaced=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulReplacements>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,B++,w.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),L+=t.failedReplacements,z+=t.totalLinesReplaced,H+=t.totalLinesAdded}catch(r){t.error=(0,f.getErrorMessage)(r),t.failedReplacements=e.replacements.length,L+=t.failedReplacements,w.error("File operation failed",{path:e.path,error:t.error})}N.push(t)}for(const e of j){const n={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
@@ -3770,8 +3772,8 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
3770
3772
  n.filename=s?.filename
3771
3773
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
3772
3774
  n.replacements=l,n.successfulReplacements=l.filter((e=>e.success)).length,n.failedReplacements=l.filter((e=>!e.success)).length,n.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,B++,w.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulReplacements:n.successfulReplacements,failedReplacements:n.failedReplacements,linesReplaced:n.totalLinesReplaced,linesAdded:n.totalLinesAdded})):0===n.failedReplacements&&(n.success=!0),L+=n.failedReplacements,z+=n.totalLinesReplaced,H+=n.totalLinesAdded}catch(t){n.error=(0,f.getErrorMessage)(t),n.failedReplacements=e.replacements.length,L+=n.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:n.error})}N.push(n)}if(j.length>0)try{for(const e of j){const r=N.find((t=>t.documentId===e.documentId))
3773
- 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(_,T,N,B,{operationType:"Replace lines",toolRecordId:b,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),G=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:W,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=G
3774
- try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+j[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:A,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:H,operationsWithChanges:B,processingTime:Date.now()-k,userComment:q,...T.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:K?`Line replacement completed: ${W}/${N.length} operations successful${T.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"
3775
+ 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,B,{operationType:"Replace lines",toolRecordId:b,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),G=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:W,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=G
3776
+ try{await o.updateToolRecord(b,{metadata:{path:P.length>0?P[0].path:"document:"+j[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:A,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:H,operationsWithChanges:B,processingTime:Date.now()-k,userComment:q,...P.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:K?`Line replacement completed: ${W}/${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"
3775
3777
  if(t.workspaceManager&&(Z+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Z+="**Summary:**\n",Z+=`- **Files processed:** ${W+V}\n`,Z+=`- **Successful operations:** ${W}\n`,Z+=`- **Failed operations:** ${V}\n`,Z+=`- **Total replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,H>0&&(Z+=`- **Total Lines Added:** ${H}\n`),Z+="\n",U.success&&U.commitHash&&(Z+="**Git Commit:**\n",Z+=`- **Commit Hash:** ${U.commitHash.substring(0,8)}\n`,Z+=`- **Files Committed:** ${U.filesCommitted.length}\n`,U.previousCommitHash&&(Z+=`- **Previous Commit:** ${U.previousCommitHash.substring(0,8)}\n`),Z+="\n"),D.lockAcquired&&D.lockedRequestId&&(Z+=`\u{1f512} **Locked request:** ${D.lockedRequestId}\n\n`),1===N.length){const e=N[0]
3776
3778
  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"
3777
3779
  for(const t of e.replacements.filter((e=>!e.success)))Z+=`- Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}}else{Z+="**Summary:**\n",Z+=`- **Total Operations:** ${N.length}\n`,Z+=`- **Successful:** ${W}\n`,Z+=`- **Failed:** ${V}\n`,Z+=`- **Total Replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,H>0&&(Z+=`- **Total Lines Added:** ${H}\n`),Z+="\n",Z+="**Detailed Results:**\n\n"
@@ -3862,11 +3864,11 @@ s.info("Getting file changes for task "+g,{showDiff:p})
3862
3864
  const f=r.getTaskClient(),m=r.getToolRecordClient(),y=t.projectId
3863
3865
  let w
3864
3866
  r.setProjectId(y)
3865
- try{const T=await f.getTask(g)
3866
- s.info("Raw task response data",{responseDataType:typeof T,isArray:Array.isArray(T),hasData:null!=T,properties:T&&"object"==typeof T?Object.keys(T):[]}),w=(0,l.extractDataFromResponse)(T,{logger:s,operationName:"getTask",defaultValue:{id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+w.title)}catch(j){s.warn("Could not fetch task information: "+(0,u.getErrorMessage)(j)),w={id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let k=[]
3867
+ try{const P=await f.getTask(g)
3868
+ s.info("Raw task response data",{responseDataType:typeof P,isArray:Array.isArray(P),hasData:null!=P,properties:P&&"object"==typeof P?Object.keys(P):[]}),w=(0,l.extractDataFromResponse)(P,{logger:s,operationName:"getTask",defaultValue:{id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+w.title)}catch(j){s.warn("Could not fetch task information: "+(0,u.getErrorMessage)(j)),w={id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let k=[]
3867
3869
  try{const R=await m.getToolRecordsByTaskId(g)
3868
- if(s.info("Raw records response data",{responseDataType:typeof R,isArray:Array.isArray(R),hasData:null!=R,properties:R&&"object"==typeof R?Object.keys(R):[]}),k=(0,l.extractArrayFromResponse)(R,{logger:s,operationName:"searchRecords",defaultValue:[]}),k.length>0&&s.info("First record summary:",{id:k[0].id,type:k[0].type,hasMetadata:!!k[0].metadata,hasCommitHash:!!k[0].metadata?.commitHash}),s.info(`Extracted ${k.length} records for task ${g}`),k.length>0){const M={}
3869
- k.forEach((e=>{M[e.type]=(M[e.type]||0)+1})),s.info("Record type distribution:",M)}}catch(x){s.warn("Error fetching records for task "+g,{error:(0,u.getErrorMessage)(x)}),k=[]}if(0===k.length)return h({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
3870
+ if(s.info("Raw records response data",{responseDataType:typeof R,isArray:Array.isArray(R),hasData:null!=R,properties:R&&"object"==typeof R?Object.keys(R):[]}),k=(0,l.extractArrayFromResponse)(R,{logger:s,operationName:"searchRecords",defaultValue:[]}),k.length>0&&s.info("First record summary:",{id:k[0].id,type:k[0].type,hasMetadata:!!k[0].metadata,hasCommitHash:!!k[0].metadata?.commitHash}),s.info(`Extracted ${k.length} records for task ${g}`),k.length>0){const x={}
3871
+ k.forEach((e=>{x[e.type]=(x[e.type]||0)+1})),s.info("Record type distribution:",x)}}catch(M){s.warn("Error fetching records for task "+g,{error:(0,u.getErrorMessage)(M)}),k=[]}if(0===k.length)return h({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
3870
3872
  function I(e){const t=new Map,r=new Map,n=[]
3871
3873
  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
3874
  if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
@@ -3959,17 +3961,17 @@ W=_e}else W="File created during this task. Content:\n"+Ce
3959
3961
  V=!0,s.info("Fallback succeeded, got file content of length "+Ce.length)}}catch(Se){s.warn("Fallback also failed for "+A,{error:Se instanceof Error?Se.message:Se+""})}}_.set(A,{firstChange:G,lastChange:H,hasDiff:V,diffText:W||"No changes detected between commits"})}else V=G.commitHash!==H.commitHash,W=V?"File has changes":"No changes detected between commits",_.set(A,{firstChange:G,lastChange:H,hasDiff:V,diffText:W})}let E=`# File Changes for Task: ${g}\n\n`
3960
3962
  w&&"object"==typeof w&&(E+="## Task Information\n",E+=`- **Title**: ${w.title||"Unknown"}\n`,E+=`- **Status**: ${w.status||"Unknown"}\n`,E+=`- **Description**: ${w.description||"No description"}\n\n`)
3961
3963
  const q=3e3
3962
- let S=0,P=!1
3963
- if(p){for(const Pe of _.values())Pe.hasDiff&&Pe.diffText&&(S+=Pe.diffText.split("\n").length)
3964
- P=S>q,s.info(`Total diff size: ${S} lines (limit: ${q} lines)`),s.info(`Diffs ${P?"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",P?(E+=`- **Diff Display**: Limited (total diff size of ${S} lines exceeds limit of ${q} lines)\n`,E+=" Use file-history tool with individual files to see detailed changes\n\n"):E+=`- **Diff Display**: ${p?"Enabled":"Disabled"} (use showDiff=${!p} to ${p?"hide":"show"} diffs)\n\n`,b.allMoves.length>0){E+="## Move Operations\n\n",E+=`Detected ${b.allMoves.length} file move operation(s):\n\n`
3965
- for(const Te of b.allMoves)E+=`- **${Te.source}** \u2192 **${Te.destination}**\n`,E+=` - Operation: ${Te.type}\n`,E+=` - Timestamp: ${new Date(Te.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Te.recordId}\n\n`}E+="## Modified Files\n\n"
3966
- for(const[je,Re]of _.entries()){const{normalizedPath:Me,fullPath:xe}=d.validateAndNormalizePath(je,t)
3964
+ let S=0,T=!1
3965
+ if(p){for(const Te of _.values())Te.hasDiff&&Te.diffText&&(S+=Te.diffText.split("\n").length)
3966
+ T=S>q,s.info(`Total diff size: ${S} lines (limit: ${q} lines)`),s.info(`Diffs ${T?"will be limited":"will be shown"} based on size`)}if(E+="## Summary\n",E+=`- **Files Modified**: ${C.size}\n`,E+=`- **Total File Operations**: ${v.length}\n`,E+="- **What's Shown**: For existing files, comparing state before task started with final state.\n",E+=" For files created during task, showing the entire file as created.\n",T?(E+=`- **Diff Display**: Limited (total diff size of ${S} lines exceeds limit of ${q} lines)\n`,E+=" Use file-history tool with individual files to see detailed changes\n\n"):E+=`- **Diff Display**: ${p?"Enabled":"Disabled"} (use showDiff=${!p} to ${p?"hide":"show"} diffs)\n\n`,b.allMoves.length>0){E+="## Move Operations\n\n",E+=`Detected ${b.allMoves.length} file move operation(s):\n\n`
3967
+ for(const Pe of b.allMoves)E+=`- **${Pe.source}** \u2192 **${Pe.destination}**\n`,E+=` - Operation: ${Pe.type}\n`,E+=` - Timestamp: ${new Date(Pe.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Pe.recordId}\n\n`}E+="## Modified Files\n\n"
3968
+ for(const[je,Re]of _.entries()){const{normalizedPath:xe,fullPath:Me}=d.validateAndNormalizePath(je,t)
3967
3969
  let Oe=!1
3968
- try{await a.access(xe),Oe=!0}catch{}E+=`### ${je} ${Oe?"":"(Deleted)"}\n\n`
3970
+ try{await a.access(Me),Oe=!0}catch{}E+=`### ${je} ${Oe?"":"(Deleted)"}\n\n`
3969
3971
  const $e=new Date(Re.firstChange.timestamp).toLocaleString(),De=new Date(Re.lastChange.timestamp).toLocaleString()
3970
3972
  E+=`**First Change**: ${$e}\n`,E+=`**Last Change**: ${De}\n`,"pre-task"===Re.firstChange.status&&Re.firstChange.commitHash?E+=`**Pre-Task Commit**: ${Re.firstChange.commitHash.substring(0,8)}\n`:Re.firstChange.commitHash&&(E+=`**File Created During Task**: ${Re.firstChange.commitHash.substring(0,8)}\n`),Re.lastChange.commitHash&&(E+=`**Final Commit**: ${Re.lastChange.commitHash.substring(0,8)}\n`)
3971
3973
  const Ae=b.sourceToMove.get(je),Fe=b.destToMove.get(je)
3972
- Ae?E+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Ae.destination}**\n`:Fe&&(E+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Fe.source}**\n`),p&&!P?Re.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=Re.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${Re.diffText}\n\n`:P&&Re.hasDiff?(E+=`\n**Note**: File has changes (${Re.diffText?Re.diffText.split("\n").length:0} lines). `,E+=`Compare ${Re.firstChange.commitHash?Re.firstChange.commitHash.substring(0,8):"unknown"}..${Re.lastChange.commitHash?Re.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Re.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${Re.diffText}\n\n`,E+="---\n\n"}return h({success:!0,fileCount:C.size}),{content:[{type:"text",text:E}]}}catch(Ne){return s.error("Error in task file history tool",{error:Ne instanceof Error?Ne.stack:Ne+""}),h({success:!1,error:Ne instanceof Error?Ne.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,u.getErrorMessage)(Ne)}],isError:!0}}}
3974
+ Ae?E+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Ae.destination}**\n`:Fe&&(E+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Fe.source}**\n`),p&&!T?Re.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=Re.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${Re.diffText}\n\n`:T&&Re.hasDiff?(E+=`\n**Note**: File has changes (${Re.diffText?Re.diffText.split("\n").length:0} lines). `,E+=`Compare ${Re.firstChange.commitHash?Re.firstChange.commitHash.substring(0,8):"unknown"}..${Re.lastChange.commitHash?Re.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Re.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${Re.diffText}\n\n`,E+="---\n\n"}return h({success:!0,fileCount:C.size}),{content:[{type:"text",text:E}]}}catch(Ne){return s.error("Error in task file history tool",{error:Ne instanceof Error?Ne.stack:Ne+""}),h({success:!1,error:Ne instanceof Error?Ne.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,u.getErrorMessage)(Ne)}],isError:!0}}}
3973
3975
  const i=t(9860),a=s(t(1943)),c=t(9671),l=t(2960),d=s(t(5967)),u=t(8824)},6928(module){"use strict"
3974
3976
  module.exports=require("path")},6975(e,exports,t){"use strict"
3975
3977
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
@@ -4119,20 +4121,24 @@ if(e){const t=c.getCLISessionClient()
4119
4121
  if(t){const r=await t.getByExternalId(e)
4120
4122
  if(r?.workflowId){const e=await c.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
4121
4123
  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
4122
- r&&(y=(0,a.getApprovalMode)(r))}catch(e){g.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){g.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const w="require-approval"===y&&"quick-edit"!==l.type?"pending_approval":"open",k={title:l.title,description:l.description,type:l.type,acceptanceCriteria:l.acceptanceCriteria,status:w,...l.planDocumentId&&{planDocumentId:l.planDocumentId},...h&&{cliOrigin:h}}
4124
+ 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"
4125
+ let k=h
4126
+ if(h?.sessionId)try{const e=c.getCLISessionClient()
4127
+ if(e){const t=await e.getByExternalId(h.sessionId)
4128
+ "planner"!==t?.agentType&&"auto-planner"!==t?.agentType||(k=void 0,g.info("Skipping cliOrigin for planner-created request",{agentType:t.agentType}))}}catch{}const I={title:l.title,description:l.description,type:l.type,acceptanceCriteria:l.acceptanceCriteria,status:w,...l.planDocumentId&&{planDocumentId:l.planDocumentId},...k&&{cliOrigin:k}}
4123
4129
  g.info("Creating request via request client",{projectId:f,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
4124
- const I=await m.createRequest(k)
4125
- g.debug("Create request response structure",{type:typeof I,isArray:Array.isArray(I),hasData:null!=I,properties:I?Object.keys(I):[],dataPreview:I?JSON.stringify(I).substring(0,200)+"...":"null"})
4126
- const b=(0,o.extractDataFromResponse)(I,{logger:g,operationName:"createRequest",throwOnNoData:!0}),v="data"in b?b.data:b
4127
- let C,_={created:!1}
4128
- 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})
4129
- g.info("Request created successfully",{requestId:v.id,title:v.title,branchCreated:_.created,branchName:_.branchName})
4130
+ const b=await m.createRequest(I)
4131
+ g.debug("Create request response structure",{type:typeof b,isArray:Array.isArray(b),hasData:null!=b,properties:b?Object.keys(b):[],dataPreview:b?JSON.stringify(b).substring(0,200)+"...":"null"})
4132
+ const v=(0,o.extractDataFromResponse)(b,{logger:g,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
4133
+ let _,E={created:!1}
4134
+ if(u?.workspaceManager)try{await u.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},g.info("Request branch initialized successfully",{requestId:C.id,branchName:E.branchName,title:C.title})}catch(e){g.warn("Failed to initialize request branch, will retry on first operation",{requestId:C.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:C.id}):g.debug("No workspace manager available, branch creation deferred",{requestId:C.id})
4135
+ g.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
4130
4136
  try{const e=c.getToolRecordClient()
4131
- 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"}`})
4132
- 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})
4133
- const E=v.localId||v.id
4134
- let q="pending_approval"===w?`Created Request ${E} (pending approval)`:"Created Request "+E
4135
- 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})
4137
+ if(e){const t=await e.createToolRecord({requestId:C.id,projectId:f,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"}`})
4138
+ _=t?.id}}catch(e){g.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:C.id})}p({success:!0,type:l.type,hasProjectId:!0}),g.info("Request created successfully",{requestId:C.id,title:C.title,type:C.type,projectId:f})
4139
+ const q=C.localId||C.id
4140
+ let S="pending_approval"===w?`Created Request ${q} (pending approval)`:"Created Request "+q
4141
+ return _&&(S+=`\n[RECORD:${_}]`),{content:[{type:"text",text:S}]}}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})
4136
4142
  else{const n=c.getToolRecordClient()
4137
4143
  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]
4138
4144
  let t=e.message
@@ -4711,19 +4717,19 @@ const C=await d.validateTaskId(u,b,r,f,i,I.metricsPrefix),_=C?.requestId,E=await
4711
4717
  q.taskPromoted&&f.info(`Auto-promoted task ${u} (${C.title||"Untitled"}) to in_progress for file operation`,{taskId:u,taskTitle:C.title,previousStatus:C.status,newStatus:q.newTaskStatus,path:b}),q.requestPromoted&&f.info(`Auto-promoted request ${_} to in_progress for file operation`,{requestId:_,previousStatus:E.request?.status,newStatus:q.newRequestStatus,triggeringTaskId:u})
4712
4718
  const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:f,metrics:i,metricsPrefix:I.metricsPrefix})
4713
4719
  if(!S.success){if(S.isLockConflict)return{content:[{type:"text",text:"\u274c "+S.error}],isError:!0}
4714
- throw Error(S.error)}let P=!1
4715
- try{P=(await a.default.stat(v)).isDirectory()}catch{P=!1}k=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("create_directory_phase",1,{phase:k})
4716
- const{toolRecordId:T,localToolRecordId:j}=await d.createFileOperationRecords(u,_,t.projectId,I.recordType,b,{directoryExists:P,userComment:g},r,n,f,i,I.metricsPrefix,p)
4717
- y=T,w=T,k=I.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:k})
4718
- let R=P
4719
- if(!P){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+b)
4720
+ throw Error(S.error)}let T=!1
4721
+ try{T=(await a.default.stat(v)).isDirectory()}catch{T=!1}k=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("create_directory_phase",1,{phase:k})
4722
+ const{toolRecordId:P,localToolRecordId:j}=await d.createFileOperationRecords(u,_,t.projectId,I.recordType,b,{directoryExists:T,userComment:g},r,n,f,i,I.metricsPrefix,p)
4723
+ y=P,w=P,k=I.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:k})
4724
+ let R=T
4725
+ if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+b)
4720
4726
  try{const e=c.default.join(v,".gitkeep")
4721
- await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),R=!0,f.info("Created .gitkeep file for Git tracking")}catch(e){f.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),R=!1}}const M=Date.now()-m
4722
- i.recordValue("create_directory_time",M),i.incrementCounter("create_directory_success",1),k=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("create_directory_phase",1,{phase:k})
4723
- const x=`Create directory: ${b} - ${g||"Create directory"}`,O=!P&&R?b+"/.gitkeep":b,$=await d.commitToGit(u,O,T,j,x,t,f,i,I.metricsPrefix)
4724
- k=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:k}),await d.updateFileOperationRecords(u,y,w,b,I.recordType,`Successfully ${P?"verified":"created"} directory: ${b}`,{status:"completed",commitHash:$.commitHash,previousCommitHash:$.previousCommitHash,directoryExists:P,isDirectory:!0,userComment:g},`Successfully ${P?"verified":"created"} directory: ${b}`,r,n,f,i,I.metricsPrefix)
4727
+ await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),R=!0,f.info("Created .gitkeep file for Git tracking")}catch(e){f.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),R=!1}}const x=Date.now()-m
4728
+ i.recordValue("create_directory_time",x),i.incrementCounter("create_directory_success",1),k=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("create_directory_phase",1,{phase:k})
4729
+ const M=`Create directory: ${b} - ${g||"Create directory"}`,O=!T&&R?b+"/.gitkeep":b,$=await d.commitToGit(u,O,P,j,M,t,f,i,I.metricsPrefix)
4730
+ k=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:k}),await d.updateFileOperationRecords(u,y,w,b,I.recordType,`Successfully ${T?"verified":"created"} directory: ${b}`,{status:"completed",commitHash:$.commitHash,previousCommitHash:$.previousCommitHash,directoryExists:T,isDirectory:!0,userComment:g},`Successfully ${T?"verified":"created"} directory: ${b}`,r,n,f,i,I.metricsPrefix)
4725
4731
  const D=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
4726
- return{content:[{type:"text",text:P?"Directory already exists":`Successfully created directory${$.commitHash?"\nCommit: "+$.commitHash.substring(0,8):""}${D.requestId?"\nBranch: "+D.requestId:""}${S.lockAcquired&&S.lockedRequestId?"\n\u{1f512} **Locked request:** "+S.lockedRequestId:""}`}]}}catch(o){if(e.taskId&&n)try{const r=o instanceof u.NotFoundError||o instanceof u.ValidationError||o instanceof h.ZodError
4732
+ return{content:[{type:"text",text:T?"Directory already exists":`Successfully created directory${$.commitHash?"\nCommit: "+$.commitHash.substring(0,8):""}${D.requestId?"\nBranch: "+D.requestId:""}${S.lockAcquired&&S.lockedRequestId?"\n\u{1f512} **Locked request:** "+S.lockedRequestId:""}`}]}}catch(o){if(e.taskId&&n)try{const r=o instanceof u.NotFoundError||o instanceof u.ValidationError||o instanceof h.ZodError
4727
4733
  await n.createToolRecord({...r?{}:{taskId:e.taskId},projectId:t.projectId,type:"create-directory",metadata:{status:"failed",timestamp:(new Date).toISOString(),path:e.path,userComment:e.comment,error:(0,g.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:k,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:`Failed to create directory ${e.path} - ${(0,g.getErrorMessage)(o)}`})}catch(t){f.error("Failed to create failure record for create directory operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,path:e.path})}const s=Date.now()-m
4728
4734
  if(i.recordValue("create_directory_time",s),i.incrementCounter("create_directory_errors",1),f.error("Error creating directory:",{error:(0,g.getErrorMessage)(o),time:s}),(y||w)&&e.taskId){k=d.FileOperationPhase.RECORD_UPDATE_FAILURE
4729
4735
  try{await d.updateFileOperationRecords(e.taskId,y,w,e.path,I.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,g.getErrorMessage)(o),userComment:e.comment},"Failed to create directory "+e.path,r,n,f,i,I.metricsPrefix)}catch(t){f.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,k,f,i,e,I)}}
@@ -5250,23 +5256,23 @@ let v,C=u.FileOperationPhase.VALIDATION
5250
5256
  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)
5251
5257
  const i=u.validateArgs(e,d.ReplaceInFilesSchema),{taskId:_,operations:E,fuzzy_match:q=!0,comment:S}=i
5252
5258
  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})
5253
- const P=E.filter((e=>e.documentId)).map((e=>e.documentId))
5254
- if(P.length>0&&t.apiClient)try{await(0,m.ensureDocumentsNotLocked)(P,t.apiClient,I,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5259
+ const T=E.filter((e=>e.documentId)).map((e=>e.documentId))
5260
+ 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}
5255
5261
  throw e}C=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5256
- const T=E[0],j=T.documentId?"document:"+T.documentId:T.path
5262
+ const P=E[0],j=P.documentId?"document:"+P.documentId:P.path
5257
5263
  let R=Date.now()
5258
- const M=await u.validateTaskId(_,j,r,I,a,"replace_in_files")
5264
+ const x=await u.validateTaskId(_,j,r,I,a,"replace_in_files")
5259
5265
  Date.now()
5260
- const x=M?.requestId,O=E.some((e=>e.path))
5266
+ const M=x?.requestId,O=E.some((e=>e.path))
5261
5267
  let $=!1
5262
- if(O&&x){R=Date.now()
5268
+ if(O&&M){R=Date.now()
5263
5269
  const e=await u.validateWorkItemStates(_,j,r,s,t,I,a,"replace_in_files")
5264
5270
  Date.now(),R=Date.now()
5265
- const n=await u.autoPromoteTaskStatus(_,M.status,x,e.request?.status,j,r,s,I,a,"replace_in_files")
5266
- n.taskPromoted&&I.info("Auto-promoted task to in_progress",{taskId:_,requestId:x,previousStatus:M.status,newStatus:n.newTaskStatus}),Date.now(),R=Date.now()
5267
- const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:x,context:t,operation:"replace_in_files",logger:I,metrics:a,metricsPrefix:"replace_in_files"})
5271
+ const n=await u.autoPromoteTaskStatus(_,x.status,M,e.request?.status,j,r,s,I,a,"replace_in_files")
5272
+ n.taskPromoted&&I.info("Auto-promoted task to in_progress",{taskId:_,requestId:M,previousStatus:x.status,newStatus:n.newTaskStatus}),Date.now(),R=Date.now()
5273
+ const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:M,context:t,operation:"replace_in_files",logger:I,metrics:a,metricsPrefix:"replace_in_files"})
5268
5274
  if(!o.success){if(o.isLockConflict)return{content:[{type:"text",text:"\u274c "+o.error}],isError:!0}
5269
- throw Error(o.error)}Date.now(),$=!0}if(P.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}
5275
+ throw Error(o.error)}Date.now(),$=!0}if(T.length>0&&M)try{await(0,p.validateRequestStatusForDocumentOperation)(M,s,I,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5270
5276
  throw e}R=Date.now()
5271
5277
  const D=new Map
5272
5278
  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=[]
@@ -5275,9 +5281,9 @@ s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,r.fullP
5275
5281
  I.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
5276
5282
  const i=await(0,w.detectExternalEdits)(t.git,o,I)
5277
5283
  I.info("\u{1f50d} External edit detection result",{path:r.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(D.set(e.path,{message:i.message,debugInfo:i.debugInfo}),I.warn("\u26a0\ufe0f External edits detected before auto-commit",{path:r.normalizedPath,conflictingLines:i.conflictingLines})):(i.debugInfo&&D.set(e.path,{message:"",debugInfo:i.debugInfo}),I.info("\u2705 No external edit conflicts detected",{path:r.normalizedPath}))}else I.info("\u2139\ufe0f No matches found for external edit detection",{path:r.normalizedPath}),D.set(e.path,{message:"",debugInfo:{detectionRan:!1,reason:"No matches found - patterns not found in file",affectedRegion:"none",uncommittedChanges:"not checked",overlapDetected:!1}})}catch(t){I.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,k.getErrorMessage)(t)})}if(Date.now(),R=Date.now(),O&&t.git)try{I.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
5278
- const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},I,a)
5284
+ const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:M,taskId:_,workspaceManager:t.workspaceManager},I,a)
5279
5285
  e.userChangesCommitted&&(I.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),I.info("User changes committed before batch operation",{taskId:_,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){I.warn("Pre-tool user changes commit failed",{taskId:_,error:e instanceof Error?e.message:e+""})}Date.now(),R=Date.now(),C=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5280
- const{toolRecordId:A}=await u.createFileOperationRecords(_,x,t.projectId,"replace-in-files",j,{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)
5286
+ const{toolRecordId:A}=await u.createFileOperationRecords(_,M,t.projectId,"replace-in-files",j,{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)
5281
5287
  v=A,Date.now(),R=Date.now(),C=u.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
5282
5288
  const F=[],N=[]
5283
5289
  for(const e of E){const r=e.path?D.get(e.path):void 0,o=await n(e,q,t,0,0,r?.message,r?.debugInfo)