alchemylab 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +17 -9
- package/dist/http-server.js +78 -71
- package/dist/index.js +78 -71
- package/dist/mcp-direct.js +352 -345
- package/package.json +1 -1
package/dist/mcp-direct.js
CHANGED
|
@@ -20,13 +20,13 @@ const p={requestId:a.requestId,projectId:l,title:a.title,description:a.descripti
|
|
|
20
20
|
u.info("Task input prepared",{taskInput:JSON.stringify(p)}),u.info("Creating task via task client",{projectId:l,requestId:a.requestId,title:a.title})
|
|
21
21
|
const m=await f.createTask(p)
|
|
22
22
|
u.debug("Task creation response structure",{type:typeof m,isArray:Array.isArray(m),hasData:null!=m,properties:m?Object.keys(m):[],dataPreview:m?JSON.stringify(m).substring(0,200)+"...":"null"})
|
|
23
|
-
const y=(0,o.extractDataFromResponse)(m,{logger:u,operationName:"createTask",defaultValue:{id:"tas"+Date.now().toString().substring(5,11),title:p.title,description:p.description,status:"pending",requestId:p.requestId,projectId:l,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}),w="data"in y?y.data:y,k=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),
|
|
23
|
+
const y=(0,o.extractDataFromResponse)(m,{logger:u,operationName:"createTask",defaultValue:{id:"tas"+Date.now().toString().substring(5,11),title:p.title,description:p.description,status:"pending",requestId:p.requestId,projectId:l,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}),w="data"in y?y.data:y,k=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),I=w.title||p.title,b=w.description||p.description,v=w.status||"pending",C=w.requestId||p.requestId
|
|
24
24
|
let _,E="unknown"
|
|
25
|
-
w&&"object"==typeof w&&"_workingEndpoint"in w&&(E=w._workingEndpoint),u.info("Successfully extracted task data from response",{taskId:k,requestId:C,title:
|
|
25
|
+
w&&"object"==typeof w&&"_workingEndpoint"in w&&(E=w._workingEndpoint),u.info("Successfully extracted task data from response",{taskId:k,requestId:C,title:I})
|
|
26
26
|
try{const e=i.getToolRecordClient()
|
|
27
|
-
if(e){const t=await e.createToolRecord({taskId:k,requestId:C,projectId:l,type:"create-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:
|
|
28
|
-
_=t?.id}}catch(e){u.error("Failed to create tool record for task creation, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:k,requestId:C})}h({success:!0,requestId:a.requestId,projectId:l}),u.info("Task created successfully",{taskId:k,requestId:C,title:
|
|
29
|
-
let q=`Created Task ${k}: ${
|
|
27
|
+
if(e){const t=await e.createToolRecord({taskId:k,requestId:C,projectId:l,type:"create-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:I,taskDescription:b,taskStatus:v},note:"Created task "+I})
|
|
28
|
+
_=t?.id}}catch(e){u.error("Failed to create tool record for task creation, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:k,requestId:C})}h({success:!0,requestId:a.requestId,projectId:l}),u.info("Task created successfully",{taskId:k,requestId:C,title:I,projectId:l})
|
|
29
|
+
let q=`Created Task ${k}: ${I}`
|
|
30
30
|
return _&&(q+=`\n[RECORD:${_}]`),{content:[{type:"text",text:q}]}}catch(r){if(u.error("Failed to create task",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new tasks")||r.message.includes("disabled due to tier limits")||r.message.includes("Project is inactive due to tier limits")))u.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
|
|
31
31
|
else{const n=i.getToolRecordClient()
|
|
32
32
|
n&&await n.createToolRecord({requestId:e.requestId,projectId:t.projectId,type:"create-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.title,taskDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),error:(0,s.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create task: "+e.title})}}catch(e){u.error("Failed to create failure record for task creation",{error:e instanceof Error?e.message:e+""})}h({success:!1,error:r instanceof Error?r.name:"unknown"})
|
|
@@ -44,9 +44,9 @@ var t={}
|
|
|
44
44
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
45
45
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
46
46
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.McpServer=void 0,exports.resetStdoutWrite=function(){process.stdout.write=O},exports.getMcpServer=r,exports.createServer=function(e,t,n,o,s={}){return r(e,t,n,o,s)}
|
|
47
|
-
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),g=t(9567),f=t(3444),p=t(7660),m=t(1253),y=t(5172),w=t(7976),k=i(t(7478)),
|
|
47
|
+
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),g=t(9567),f=t(3444),p=t(7660),m=t(1253),y=t(5172),w=t(7976),k=i(t(7478)),I=t(4139),b=new Set,v=t(9860),C=t(1472),_=t(3328),E=t(8955),q=t(3217),S=t(8411),T=t(5278),M=t(446),R=t(9060),P=t(8824),x=(0,f.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),O=process.stdout.write,j=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
|
|
48
48
|
!(0,f.isDebugToolsEnabled)()||j&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,f.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&x.debug("Stdout output",{content:e.substring(0,100),length:e.length}),O.call(process.stdout,e)}catch(e){return x.error("Error in safeStdoutWrite",{error:e+""}),!0}})
|
|
49
|
-
class ${constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.clientInfo=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.multiAgentMode=o.multiAgentMode||!1,this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,multiAgentMode:o.multiAgentMode||!1,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,
|
|
49
|
+
class ${constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.clientInfo=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.multiAgentMode=o.multiAgentMode||!1,this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,multiAgentMode:o.multiAgentMode||!1,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,I.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new p.ProjectContext(e,t),this.tokenManager=new m.TokenManager(t,e,{remoteServerUrl:n}),this.lockOverrideManager=new M.LockOverrideManager(t),this.configManager=new R.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.interceptConnectMethod(),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
|
|
50
50
|
const e=this.workspaceManager.getCurrentContext()
|
|
51
51
|
return{currentBranch:e.branchName,activeRequestId:e.requestId,isOnMainBranch:e.isMainBranch}}async updateBranchState(e,t){this.logger.debug("updateBranchState called - managed by WorkspaceManager",{branch:e,requestId:t})}async getCurrentBranchContext(){if(!this.workspaceManager)return{branch:null,requestId:null,isMain:!0}
|
|
52
52
|
const e=this.workspaceManager.getCurrentContext()
|
|
@@ -56,7 +56,7 @@ const n=await r.getNextId(e)
|
|
|
56
56
|
return t({success:!0,type:e}),this.metrics.incrementCounter("remote_id_success",1,{type:e}),n}catch(t){throw this.metrics.incrementCounter("remote_id_failure",1,{type:e,error:t instanceof Error?t.name:"unknown"}),this.logger.warn("Failed to get ID from remote server, unable to perform operation",{type:e,error:(0,P.getErrorMessage)(t)}),Error("Failed to get ID from remote server.")}}async initialize(){const e=this.remoteServerUrl||"https://api.alchemylabcode.com"
|
|
57
57
|
this.logger.debug("Using remote server URL",{remoteServerUrl:e})
|
|
58
58
|
const t=d.default.resolve(this.basePath)
|
|
59
|
-
if(
|
|
59
|
+
if(b.has(t))return this.logger.info("Path already initialized in global registry, skipping initialization",{path:t}),void(this.isInitialized=!0)
|
|
60
60
|
if(this.isInitialized)this.logger.info("Server already initialized, skipping initialization")
|
|
61
61
|
else{if(this.isInitializing)return this.logger.info("Initialization already in progress, waiting..."),void await this.initializationPromise
|
|
62
62
|
this.isInitializing=!0,this.logger.info("SERVER INITIALIZATION STARTING",{path:t,pid:process.pid,time:(new Date).toISOString()}),this.metrics.setGauge("mcp_initialization",0,{status:"starting"})
|
|
@@ -67,12 +67,12 @@ try{this.logger.info("Validating git repository for branch management...")
|
|
|
67
67
|
const e=await k.validateGitRepository(this.git,this.logger,this.metrics)
|
|
68
68
|
if(e.isGitRepository){this.logger.info("Git repository validation completed",{currentBranch:e.currentBranch,isClean:e.isClean,defaultBranch:e.defaultBranch,branchCount:e.branches.length,hasMainBranch:e.hasMainBranch,hasMasterBranch:e.hasMasterBranch})
|
|
69
69
|
const t=[],r=[]
|
|
70
|
-
e.currentBranch||(t.push("Repository is in detached HEAD state"),r.push("Switch to a proper branch: git checkout main")),e.isClean||(t.push(`Repository has ${e.uncommittedChanges.length} uncommitted changes`),r.push("Commit or stash changes before creating requests")),e.defaultBranch||(t.push("No default branch (main/master) found"),r.push("Create a default branch: git checkout -b main")),t.length>0?this.logger.warn("Git repository has potential issues for branch management",{issues:t,recommendations:r}):this.logger.info("Git repository is ready for automatic branch management"),this.metrics.setGauge("git_repository_ready",0===t.length?1:0),this.metrics.setGauge("git_repository_branch_count",e.branches.length),this.metrics.incrementCounter("git_repository_validation_success",1)}else this.logger.error("Git repository validation failed - not a valid git repository"),this.metrics.incrementCounter("git_repository_validation_failed",1)}catch(e){this.logger.warn("Git repository validation encountered an error",{error:e instanceof Error?e.message:e+""}),this.metrics.incrementCounter("git_repository_validation_error",1)}}async ensureGitignoreWithAlchemyLab(){const e=d.default.join(this.basePath,".gitignore"),t=
|
|
70
|
+
e.currentBranch||(t.push("Repository is in detached HEAD state"),r.push("Switch to a proper branch: git checkout main")),e.isClean||(t.push(`Repository has ${e.uncommittedChanges.length} uncommitted changes`),r.push("Commit or stash changes before creating requests")),e.defaultBranch||(t.push("No default branch (main/master) found"),r.push("Create a default branch: git checkout -b main")),t.length>0?this.logger.warn("Git repository has potential issues for branch management",{issues:t,recommendations:r}):this.logger.info("Git repository is ready for automatic branch management"),this.metrics.setGauge("git_repository_ready",0===t.length?1:0),this.metrics.setGauge("git_repository_branch_count",e.branches.length),this.metrics.incrementCounter("git_repository_validation_success",1)}else this.logger.error("Git repository validation failed - not a valid git repository"),this.metrics.incrementCounter("git_repository_validation_failed",1)}catch(e){this.logger.warn("Git repository validation encountered an error",{error:e instanceof Error?e.message:e+""}),this.metrics.incrementCounter("git_repository_validation_error",1)}}async ensureGitignoreWithAlchemyLab(){const e=d.default.join(this.basePath,".gitignore"),t=I.ALCHEMY_DIR_NAME+"/"
|
|
71
71
|
try{if(u.default.existsSync(e)){const r=await h.default.readFile(e,"utf8")
|
|
72
|
-
if(r.split("\n").some((e=>e.trim()===t||e.trim()===t.slice(0,-1))))this.logger.info(
|
|
72
|
+
if(r.split("\n").some((e=>e.trim()===t||e.trim()===t.slice(0,-1))))this.logger.info(I.ALCHEMY_DIR_NAME+"/ already present in .gitignore")
|
|
73
73
|
else{const n=r.trimEnd()+"\n\n# AlchemyMCP working directory\n"+t+"\n"
|
|
74
|
-
await h.default.writeFile(e,n),this.logger.info(`Added ${
|
|
75
|
-
await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${
|
|
74
|
+
await h.default.writeFile(e,n),this.logger.info(`Added ${I.ALCHEMY_DIR_NAME}/ to existing .gitignore`)}}else{const r=["# Dependency directories\nnode_modules/\n.npm\n.yarn\n\n# Build outputs\ndist/\nbuild/\n\n# Logs\nlogs/\n*.log\n\n# Editor files\n.DS_Store\n.vscode/\n.idea/\n\n# Environment variables\n.env\n.env.local\n\n# AlchemyMCP working directory",t,""].join("\n")
|
|
75
|
+
await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${I.ALCHEMY_DIR_NAME}/ entry`)}}catch(e){this.logger.warn("Failed to update .gitignore file",{error:(0,P.getErrorMessage)(e)})}}async initializeGitRepo(){try{this.logger.info("Initializing git repository"),await this.git.init(),await this.ensureGitignoreWithAlchemyLab()
|
|
76
76
|
const e=d.default.join(this.basePath,"README.md")
|
|
77
77
|
if(!u.default.existsSync(e)){const t=`# Project at ${this.basePath}\n\nCreated with AlchemyMCP Server.\n`
|
|
78
78
|
await h.default.writeFile(e,t)}this.logger.info("Git repository initialized successfully"),await this.git.add(".")
|
|
@@ -195,13 +195,13 @@ const w=[],k=a.toLowerCase()
|
|
|
195
195
|
for(const e of y){const t=[]
|
|
196
196
|
if("all"!==l&&"title"!==l||!e.title||e.title.toLowerCase().includes(k)&&t.push({request:e,matchType:"title",matchSnippet:r(e.title,a)}),"all"!==l&&"description"!==l||!e.description||e.description.toLowerCase().includes(k)&&t.push({request:e,matchType:"description",matchSnippet:n(e.description,k,150)}),("all"===l||"criteria"===l)&&e.acceptanceCriteria)for(const r of e.acceptanceCriteria){const o="string"==typeof r?r:r.description
|
|
197
197
|
if(o&&o.toLowerCase().includes(k)){t.push({request:e,matchType:"criteria",matchSnippet:n(o,k,150)})
|
|
198
|
-
break}}t.length>0&&w.push(t[0])}const
|
|
199
|
-
if(0===
|
|
200
|
-
let v=`Found ${
|
|
201
|
-
for(const e of
|
|
198
|
+
break}}t.length>0&&w.push(t[0])}const I=g.limit||20,b=w.slice(0,I)
|
|
199
|
+
if(0===b.length)return h({success:!0,resultCount:0}),{content:[{type:"text",text:`No requests found matching "${a}".\n\nSearched in: ${l}\nTotal requests checked: ${y.length}`}]}
|
|
200
|
+
let v=`Found ${b.length} request${1===b.length?"":"s"} matching "${a}":\n\n`
|
|
201
|
+
for(const e of b){const t=e.request,r=o(t.status)
|
|
202
202
|
v+=`${s(t.type)} **${t.title}** (${t.id}) ${r}\n`,v+=" \u{1f4cd} Match in "+e.matchType,e.matchSnippet&&(v+=": "+e.matchSnippet),v+="\n\n"}v+=`---\nSearched ${y.length} requests (filtered by: `
|
|
203
203
|
const C=[]
|
|
204
|
-
return g.status&&C.push("status="+g.status),g.type&&C.push("type="+g.type),g.dateFrom&&C.push("from="+g.dateFrom),g.dateTo&&C.push("to="+g.dateTo),v+=C.length>0?C.join(", "):"none",v+=")",h({success:!0,resultCount:
|
|
204
|
+
return g.status&&C.push("status="+g.status),g.type&&C.push("type="+g.type),g.dateFrom&&C.push("from="+g.dateFrom),g.dateTo&&C.push("to="+g.dateTo),v+=C.length>0?C.join(", "):"none",v+=")",h({success:!0,resultCount:b.length}),d.incrementCounter("search_requests_success",1),{content:[{type:"text",text:v}]}}catch(e){return u.error("Search requests failed",{error:e instanceof Error?e.stack:e+""}),h({success:!1,error:(0,a.getErrorMessage)(e)}),d.incrementCounter("search_requests_errors",1),{content:[{type:"text",text:"\u274c **Search Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
205
205
|
const i=t(9860),a=t(8824)},260(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
206
206
|
const r=t(6183),n=t(4221)
|
|
207
207
|
exports.def={name:"view_asset",description:"View an image from the project's .alchemy_lab/assets/ folder. Returns the image so you can see it. Use this when you encounter asset:filename.png references in plans or documents and need to understand the image content.",schema:r.ViewAssetSchema,annotations:{title:"View Asset Image",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleViewAsset)(e,t.context,t.logger,t.metrics)}}},270(e,exports){Object.defineProperty(exports,"__esModule",{value:!0})},293(e,exports,t){function r(e){let t
|
|
@@ -258,14 +258,14 @@ throw f.error("Failed to check request lock status",{taskId:o,requestId:w.reques
|
|
|
258
258
|
let k=d.git
|
|
259
259
|
if(d.workspaceManager){const e=d.workspaceManager.getCurrentContext()
|
|
260
260
|
if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
|
|
261
|
-
k=simpleGit({baseDir:e.basePath,binary:d.gitBinary}),f.debug("Using workspace-aware git instance for task completion",{taskId:o,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let
|
|
262
|
-
if(k)try{(await k.status()).isClean()||(
|
|
261
|
+
k=simpleGit({baseDir:e.basePath,binary:d.gitBinary}),f.debug("Using workspace-aware git instance for task completion",{taskId:o,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let I=null
|
|
262
|
+
if(k)try{(await k.status()).isClean()||(I=(await k.commit(`Complete task ${o}: ${h}`)).commit,f.info("Created commit for task completion",{taskId:o,commitId:I}))}catch(e){f.warn("Failed to commit changes",{error:(0,l.getErrorMessage)(e)})}let b=null
|
|
263
263
|
try{const e=u.getToolRecordClient()
|
|
264
|
-
e&&(
|
|
265
|
-
f.info("Raw task update response data",{responseData:JSON.stringify(n)}),f.debug("Task update response structure",{type:typeof n,isArray:Array.isArray(n),hasData:null!=n,properties:n?Object.keys(n):[],dataPreview:n?JSON.stringify(n).substring(0,200)+"...":"null"}),(0,s.extractDataFromResponse)(n,{logger:f,operationName:"updateTask",defaultValue:{id:o,status:"completed"}}),f.info("Successfully completed task",{taskId:o,recordId:
|
|
264
|
+
e&&(b={id:(await e.createToolRecord({taskId:o,requestId:w.requestId,projectId:m,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:h,lastCommit:I,completedAt:(new Date).toISOString()},note:`Completed task: ${h.substring(0,100)}${h.length>100?"...":""}`})).id})}catch(e){f.error("Failed to create tool record for task completion, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:o,requestId:w.requestId})}try{const e=w.metadata||{},t=(new Date).toISOString(),r={status:"completed",metadata:{...e,lastCommit:I,completionSummary:h,completionRecordId:b?.id,completedAt:t}},n=await y.updateTask(o,r)
|
|
265
|
+
f.info("Raw task update response data",{responseData:JSON.stringify(n)}),f.debug("Task update response structure",{type:typeof n,isArray:Array.isArray(n),hasData:null!=n,properties:n?Object.keys(n):[],dataPreview:n?JSON.stringify(n).substring(0,200)+"...":"null"}),(0,s.extractDataFromResponse)(n,{logger:f,operationName:"updateTask",defaultValue:{id:o,status:"completed"}}),f.info("Successfully completed task",{taskId:o,recordId:b?.id})
|
|
266
266
|
const i=w.requestId
|
|
267
267
|
let a=`Task ${o} (${w.title}) has been marked as completed.`
|
|
268
|
-
if(
|
|
268
|
+
if(b?.id&&(a+=`\n[RECORD:${b.id}]`),I&&(a+="\nCommit: "+I.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
|
|
269
269
|
f.info("Raw tasks list response data",{responseData:JSON.stringify(e)}),f.debug("Tasks list response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
|
|
270
270
|
const t=(0,s.extractArrayFromResponse)(e,{logger:f,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
|
|
271
271
|
f.info("Task progress check",{requestId:i,totalTasks:r,completedTasks:n}),a+=`\n\nTask Progress: ${n}/${r} tasks completed`,n===r&&(a+=`\n\nAll tasks for request ${i} are now completed! You may consider marking the request as completed using the complete-request tool.`)}catch(e){f.warn("Failed to check task progress",{error:(0,l.getErrorMessage)(e),requestId:i})}return p({success:!0}),{content:[{type:"text",text:a}]}}catch(e){throw f.error("Failed to complete task",{error:e instanceof Error?e.stack:e+"",taskId:o}),Error("Failed to complete task: "+(0,l.getErrorMessage)(e))}}catch(t){if(f.error("Failed to complete task",{error:t instanceof Error?t.stack:t+"",args:e}),d.projectId)try{const r=u.getToolRecordClient()
|
|
@@ -514,18 +514,18 @@ const r=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Co
|
|
|
514
514
|
if(r.ok){const e=await r.json()
|
|
515
515
|
return this.logger.info("Token validation successful",{status:e.status||"unknown",username:e.username||"unknown"}),!0}return this.logger.info("Token validation failed - token may be invalid or expired",{status:r.status,statusText:r.statusText}),this.invalidateCache(),!1}catch(e){return e instanceof Error&&"AbortError"===e.name?(this.logger.info("Token validation request timed out - assuming offline or server unavailable"),!0):(this.logger.info("Token validation request failed",{error:(0,c.getErrorMessage)(e)}),!0)}}async hasValidAndWorkingToken(){return!!await this.hasValidToken()&&await this.validateTokenWithRemoteServer()}async isGoogleOAuthAvailable(){return await this.authFlow.isGoogleOAuthAvailable()}async startGoogleOAuthFlow(){return await this.authFlow.startGoogleOAuthFlow()}async startGoogleOAuthPolling(e,t,r,n,o){return await this.authFlow.startGoogleOAuthPolling(e,t,r,n,o)}}},1281(e,exports,t){async function r(e,t,o,s,i,a,c,l,d,u=0){let f=0,p=0,m=0
|
|
516
516
|
const y=[]
|
|
517
|
-
if(o.length>=
|
|
517
|
+
if(o.length>=b||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:b,depth:c}),{filesCount:f,fileMatchesCount:p,subdirCount:m,subdirStats:y}
|
|
518
518
|
try{const w=await g.default.readdir(e,{withFileTypes:!0}),v=[],C=[]
|
|
519
519
|
for(const t of w){const r=h.default.join(e,t.name)
|
|
520
|
-
if(t.isDirectory()){if(
|
|
520
|
+
if(t.isDirectory()){if(I.includes(t.name)||t.name.startsWith(".")){a.debug("Skipping excluded directory: "+t.name)
|
|
521
521
|
continue}C.push({entry:t,fullPath:r})}else if(t.isFile()){if("*"!==i&&!t.name.endsWith(i)){a.debug("Skipping file due to extension mismatch",{filename:t.name,requiredExtension:i})
|
|
522
522
|
continue}v.push({entry:t,fullPath:r})}}if(v.length>0){const e=[]
|
|
523
523
|
for(let t=0;t<v.length;t+=16)e.push(v.slice(t,t+16))
|
|
524
|
-
for(const r of e){if(o.length>=
|
|
524
|
+
for(const r of e){if(o.length>=b)break
|
|
525
525
|
const e=await Promise.all(r.map((({entry:e,fullPath:r})=>n(r,t,0,o,l,d,e.name,u))))
|
|
526
526
|
for(const t of e){f++,t.hasMatches&&p++
|
|
527
|
-
for(const e of t.matches){if(o.length>=
|
|
528
|
-
o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=
|
|
527
|
+
for(const e of t.matches){if(o.length>=b)return{filesCount:f,fileMatchesCount:p,subdirCount:m,subdirStats:y}
|
|
528
|
+
o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=b)break
|
|
529
529
|
m++
|
|
530
530
|
const e={path:n,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
531
531
|
try{const l=await r(n,t,o,s,i,a,c+1,e,d,u)
|
|
@@ -536,7 +536,7 @@ let l,d=!1
|
|
|
536
536
|
const u=async()=>{if(void 0===l)try{const t=await g.default.stat(e)
|
|
537
537
|
l=t.mtime.getTime()}catch(e){l=void 0}return l}
|
|
538
538
|
if("filename"!==s&&"both"!==s||t.test(i)&&(d=!0,await u(),c.push({file:e,line:0,text:i,modifiedTime:l,matchType:"filename"})),"content"===s||"both"===s)try{const r=(await g.default.readFile(e,"utf8")).split("\n")
|
|
539
|
-
for(let o=0;o<r.length&&n.length<
|
|
539
|
+
for(let o=0;o<r.length&&n.length<b;o++)if(t.test(r[o])){d=!0,await u()
|
|
540
540
|
const t={file:e,line:o+1,text:(0,y.truncate)(r[o].trim(),120),modifiedTime:l,matchType:"content"}
|
|
541
541
|
if(a>0){const e=Math.max(0,o-a)
|
|
542
542
|
t.contextBefore=r.slice(e,o).map((e=>(0,y.truncate)(e.trim(),120)))
|
|
@@ -563,29 +563,29 @@ var t={}
|
|
|
563
563
|
if(null!=e)for(var r=a(e),n=0;n<r.length;n++)"default"!==r[n]&&c(t,e,r[n])
|
|
564
564
|
return l(t,e),t}),u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
565
565
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearch=async function(e,t,n,a,c){const l=a.child({tool:"search"}),d=c.startTimer("tool_execution_time"),u=Date.now()
|
|
566
|
-
let
|
|
567
|
-
const
|
|
566
|
+
let I=0
|
|
567
|
+
const b={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:f.default.hostname(),username:f.default.userInfo().username,workingDirectory:process.cwd(),contextBasePath:t?.basePath||"unknown"},startTime:u,endTime:0,phases:{initializationTime:0,searchTime:0,directoryListingTime:0},totalFiles:0,totalMatches:0,directoryStats:[],errors:[]}
|
|
568
568
|
try{const{needle:n,directory:f,options:v={}}=e
|
|
569
569
|
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,w.handleListDirectory)({path:f||".",levels:v.levels||1,sortBy:v.sortBy||"name"},t,a,c)
|
|
570
|
-
if("string"!=typeof n)throw
|
|
570
|
+
if("string"!=typeof n)throw b.errors.push("Search term (needle) must be a string"),(0,p.createValidationError)("Search term (needle) must be a string")
|
|
571
571
|
let C
|
|
572
|
-
if(
|
|
572
|
+
if(b.searchDirectory=f||".",f){const{normalizedPath:e,fullPath:r}=m.validateAndNormalizePath(f,t)
|
|
573
573
|
C=r}else C=t.basePath
|
|
574
|
-
|
|
574
|
+
b.resolvedPath=C
|
|
575
575
|
let _=!1
|
|
576
576
|
try{_=(await g.default.stat(C)).isFile()}catch(e){const t=`Cannot access path ${C}: ${(0,k.getErrorMessage)(e)}`
|
|
577
|
-
throw
|
|
577
|
+
throw b.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,T=v.fileExtension,M=v.searchIn||"content"
|
|
578
578
|
let R=void 0!==v.contextLines?v.contextLines:0
|
|
579
|
-
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!_&&!T)throw
|
|
579
|
+
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!_&&!T)throw b.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,p.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
|
|
580
580
|
let P,x=""
|
|
581
581
|
if(_)x="*"
|
|
582
582
|
else if("*"===T)x="*"
|
|
583
583
|
else if(T){let e=T;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),x=e.startsWith(".")?e:"."+e}try{P=S?q?RegExp(n):RegExp(n,"i"):q?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${S?"regex":"search"} pattern: ${(0,k.getErrorMessage)(e)}`
|
|
584
|
-
throw
|
|
584
|
+
throw b.errors.push(t),(0,p.createValidationError)(t)}if(b.patternInfo={needle:n,regex:P.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:x},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
|
|
585
585
|
for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
l.info(`Searching for "${n}" in ${O} ${C} (mode: ${M})`,{needle:n,searchTarget:O,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:x,searchIn:M}}),
|
|
586
|
+
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)
|
|
587
|
+
b.errors.push(t),l.error(t)}const O=_?"file":"directory"
|
|
588
|
+
l.info(`Searching for "${n}" in ${O} ${C} (mode: ${M})`,{needle:n,searchTarget:O,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:x,searchIn:M}}),I=Date.now(),b.phases.initializationTime=I-u
|
|
589
589
|
const j=Date.now()
|
|
590
590
|
let $=[],D=0,A=0
|
|
591
591
|
try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,f=[]
|
|
@@ -603,15 +603,15 @@ o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
|
|
|
603
603
|
const p={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
604
604
|
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,f,a,o,s,0,p,l,u)
|
|
605
605
|
return p.filesProcessed=n,p.filesMatched=c,p.subdirectories=d,i.directoryStats.push(p),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:f.length,directories:d+1}),{matches:f,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,k.getErrorMessage)(t)
|
|
606
|
-
return p.errors.push(r),i.directoryStats.push(p),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:f,totalFiles:p.filesProcessed}}}(C,P,{maxResults:E,fileExtension:x,searchIn:M,isFile:_,contextLines:R},x,l,
|
|
606
|
+
return p.errors.push(r),i.directoryStats.push(p),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:f,totalFiles:p.filesProcessed}}}(C,P,{maxResults:E,fileExtension:x,searchIn:M,isFile:_,contextLines:R},x,l,b)
|
|
607
607
|
$=e.matches,D=e.totalFiles
|
|
608
608
|
const t=1e3
|
|
609
609
|
$.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)
|
|
610
|
-
return r?r===h.default.basename(t)?r:r.startsWith("./")?r.substring(2):r:h.default.basename(t)}(C,e.file)})),l.info(`Local search completed: found ${A||$.length} total matches in ${D} files, returning ${$.length} results`),
|
|
611
|
-
|
|
610
|
+
return r?r===h.default.basename(t)?r:r.startsWith("./")?r.substring(2):r:h.default.basename(t)}(C,e.file)})),l.info(`Local search completed: found ${A||$.length} total matches in ${D} files, returning ${$.length} results`),b.phases.searchTime=Date.now()-j}catch(e){const t="Error during search: "+(0,k.getErrorMessage)(e)
|
|
611
|
+
b.errors.push(t),l.error(t),b.phases.searchTime=Date.now()-j}b.totalFiles=D,b.totalMatches=$.length,b.endTime=Date.now()
|
|
612
612
|
let F,N=""
|
|
613
613
|
try{if(t.getCurrentBranchContext){const e=await t.getCurrentBranchContext()
|
|
614
|
-
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:
|
|
614
|
+
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})
|
|
615
615
|
const L="content"===M?"content":"filename"===M?"filenames":"content and filenames"
|
|
616
616
|
if(A>$.length?(F=`Found ${A} results for "${n}" (searching ${L})`,f&&(F+=" in "+f),T&&(F+=" with extension "+T),F+=`${N}. Showing first ${$.length}:\n\n`):(F=`Found ${$.length} results for "${n}" (searching ${L})`,f&&(F+=" in "+f),T&&(F+=" with extension "+T),F+=N+":\n\n"),$.length>0)if(R>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
|
|
617
617
|
if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
|
|
@@ -634,10 +634,10 @@ void 0!==s&&(a+=` (${s} lines)`),a+=` - ${o} ${1===o?"match":"matches"}:`
|
|
|
634
634
|
const c=t.map((e=>` :${e.line} - ${e.text}`))
|
|
635
635
|
n.push(a+"\n"+c.join("\n"))}return n.join("\n\n")}($)
|
|
636
636
|
else F+="No matches found."
|
|
637
|
-
return d({success:!0}),{content:[{type:"text",text:F}]}}catch(t){l.error("Search failed",{args:e,error:t instanceof Error?t.stack:t+""}),
|
|
637
|
+
return d({success:!0}),{content:[{type:"text",text:F}]}}catch(t){l.error("Search failed",{args:e,error:t instanceof Error?t.stack:t+""}),b.errors.push((0,k.getErrorMessage)(t)),b.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:b})
|
|
638
638
|
let r="Search failed: "+(0,k.getErrorMessage)(t)
|
|
639
639
|
return d({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:r}],isError:!0}}}
|
|
640
|
-
const h=u(t(6928)),g=u(t(1943)),f=u(t(857)),p=t(9860),m=d(t(5967)),y=t(5967),w=t(2537),k=t(8824),
|
|
640
|
+
const h=u(t(6928)),g=u(t(1943)),f=u(t(857)),p=t(9860),m=d(t(5967)),y=t(5967),w=t(2537),k=t(8824),I=["node_modules"],b=1e4,v=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore"]),C=1048576},1318(e,exports,t){async function r(e,t,r){try{const r=(await e.revparse(["--show-toplevel"])).trim(),n=c.default.isAbsolute(t)?t:c.default.resolve(t)
|
|
641
641
|
return c.default.relative(r,n)}catch(e){return r.warn("Failed to get repo-relative path, using original",{filePath:t,error:(0,l.getErrorMessage)(e)}),t}}function n(e){return/\(trec\d{6}\)/.test(e)}async function o(e,t,n,o,s){try{const i=await r(e,t,s),a=await e.raw(["log","-1","--pretty=format:%H|%s",`-L${n},${o}:${i}`])
|
|
642
642
|
if(!a||""===a.trim())return null
|
|
643
643
|
const c=a.trim().split("\n")[0],[l,...d]=c.split("|"),u=d.join("|")
|
|
@@ -713,20 +713,19 @@ try{return await i.hasValidToken()}catch(e){return m.error("Error checking authe
|
|
|
713
713
|
m.info(`Generating tools list with testsRequired=${e}, authenticated=${t}`)
|
|
714
714
|
const r={testsRequired:e,authenticated:t}
|
|
715
715
|
return(0,p.generateVisibleToolsList)(r)}
|
|
716
|
-
let
|
|
717
|
-
|
|
716
|
+
let I=k(),b=[]
|
|
717
|
+
I.then((e=>{b=e})).catch((e=>{m.error("Error generating initial tools list",{error:(0,l.getErrorMessage)(e)}),b=[]})),e.setRequestHandler(a.ListToolsRequestSchema,(async()=>{try{return b=await k(),{tools:b}}catch(e){return m.error("Error generating tools list",{error:(0,l.getErrorMessage)(e)}),{tools:[]}}}))
|
|
718
718
|
let v=!1
|
|
719
719
|
e.setRequestHandler(a.CallToolRequestSchema,(async e=>{try{const{name:i,arguments:a={},_meta:c}=e.params;(0,f.logSessionIdentity)(i,"_meta-debug",{has_meta:!!c,sessionId:c?.sessionId||null,messageId:c?.messageId||null,paramKeys:Object.keys(e.params)}),m.info("Tool call received: "+i,{tool:i}),s.incrementCounter("tool_calls_total",1,{tool:i})
|
|
720
720
|
const k=s.startTimer("tool_execution_time")
|
|
721
721
|
Date.now()
|
|
722
|
-
let
|
|
723
|
-
const
|
|
724
|
-
if(Date.now(),
|
|
722
|
+
let I=Date.now()
|
|
723
|
+
const b=r(a)
|
|
724
|
+
if(Date.now(),I=Date.now(),y){const e=await w()
|
|
725
725
|
if(Date.now(),!e)return m.warn("Unauthenticated tool call attempt",{tool:i}),{content:[{type:"text",text:"Authentication required. Please run 'alchemylab setup' to authenticate and configure your project."}],isError:!0}}const C=(0,p.getToolByName)(i)
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if(
|
|
729
|
-
if(n)n.sessionId!==e&&((0,f.logSessionIdentity)(i,"_meta-session-switch",{prevSessionId:n.sessionId,prevAgentType:n.agentType,newSessionId:e}),u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:n.serverUrl}))
|
|
726
|
+
let _,E
|
|
727
|
+
if(I=Date.now(),n?(n.setOptions({createRecords:C?.createsRecords??!1}),m.info(`Setting record creation for tool ${i}: ${C?.createsRecords??!1}`)):m.debug(`No API client available for tool ${i} (minimal mode)`),Date.now(),Date.now(),I=Date.now(),C&&!C.readOnly)if(c?.sessionId){const e=c.sessionId,r=c.messageId,n=u.sessionIdentity.getIdentity()
|
|
728
|
+
if(n)n.sessionId!==e&&((0,f.logSessionIdentity)(i,"_meta-session-switch",{prevSessionId:n.sessionId,prevAgentType:n.agentType,newSessionId:e}),u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:n.serverUrl}),t?.workspaceManager?.resetCurrentContext?.())
|
|
730
729
|
else{const r=await(0,d.getServerUrl)(t,m)
|
|
731
730
|
u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r||""}),u.sessionIdentity.markDiscoveryAttempted()}_={providerId:"opencode",sessionId:e,messageId:r,createdAt:(new Date).toISOString()},(0,f.logSessionIdentity)(i,"_meta",{sessionId:e,messageId:r})}else{const e=u.sessionIdentity.getIdentity()
|
|
732
731
|
if(e){let r,n=!1
|
|
@@ -736,13 +735,15 @@ else{m.info("Session identity mismatch: tool call not found in cached session, r
|
|
|
736
735
|
try{const t=await(0,d.getAndStoreSessionId)(e.serverUrl,m,i)
|
|
737
736
|
t?(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e.serverUrl}),(0,f.logSessionIdentity)(i,"re-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId)):(u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),m.info("Re-discovery found no other session, keeping current identity",{sessionId:e.sessionId})),u.sessionIdentity.markDiscoveryAttempted()}catch(t){u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),u.sessionIdentity.markDiscoveryAttempted(),m.warn("Re-discovery failed, keeping current identity (may be stale)",{error:(0,l.getErrorMessage)(t),tool:i,sessionId:e.sessionId})}}}else if(!u.sessionIdentity.hasDiscoveryBeenAttempted())try{const e=await(0,d.getServerUrl)(t,m)
|
|
738
737
|
if(e){const t=await(0,d.getAndStoreSessionId)(e,m,i)
|
|
739
|
-
t&&(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e}),(0,f.logSessionIdentity)(i,"http-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId))}u.sessionIdentity.markDiscoveryAttempted()}catch(e){u.sessionIdentity.markDiscoveryAttempted(),(0,f.logSessionIdentity)(i,"discovery-failed",{error:(0,l.getErrorMessage)(e)}),m.debug("cliOrigin discovery failed",{error:(0,l.getErrorMessage)(e),tool:i})}}if(u.sessionIdentity.setCurrentCallOrigin(_)
|
|
738
|
+
t&&(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e}),(0,f.logSessionIdentity)(i,"http-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId))}u.sessionIdentity.markDiscoveryAttempted()}catch(e){u.sessionIdentity.markDiscoveryAttempted(),(0,f.logSessionIdentity)(i,"discovery-failed",{error:(0,l.getErrorMessage)(e)}),m.debug("cliOrigin discovery failed",{error:(0,l.getErrorMessage)(e),tool:i})}}if(u.sessionIdentity.setCurrentCallOrigin(_),t?.workspaceManager&&!t.workspaceManager.readonlyBranchCheckDone){I=Date.now()
|
|
739
|
+
try{const e=await(0,d.getServerUrl)(t,m)
|
|
740
|
+
e&&n&&await t.workspaceManager.ensureReadonlyBranchIfNeeded(e,i,n,c?.sessionId)}catch(e){m.debug("Error during workspace check",{error:(0,l.getErrorMessage)(e)})}Date.now()}if(!v&&n){const e=u.sessionIdentity.getIdentity(),t=process.env.ALCHEMY_INITIAL_BRANCH
|
|
740
741
|
if(e?.sessionId&&t){const r=t.match(/^requests\/(.+)$/),o="1"===process.env.ALCHEMY_ALLOW_PARALLEL
|
|
741
742
|
if(r&&!o){const t=r[1]
|
|
742
743
|
v=!0
|
|
743
744
|
try{const{sessionTag:r}=(0,h.getGlobalClientInfo)(),o=n.getSessionTagMappingClient(),s=n.getRequestClient(),i=o?o.getMappingByOpencodeSessionId(e.sessionId).then((t=>{t?((0,h.setSessionTag)(t.sessionTag),m.info("Recovered session tag from mapping",{opencodeSessionId:e.sessionId,sessionTag:t.sessionTag})):(o.createOrUpdateMapping(r,e.sessionId).catch((()=>{})),m.info("Registered session tag mapping",{opencodeSessionId:e.sessionId,sessionTag:r}))}),(e=>m.debug("Mapping lookup failed",{error:(0,l.getErrorMessage)(e)}))):Promise.resolve(),a=s.lockRequest?s.lockRequest(t,r).then((e=>{e.locked?m.info("Acquired request lock",{requestId:t,sessionTag:r}):m.warn("Failed to acquire request lock",{requestId:t,sessionTag:r})}),(e=>m.warn("Lock acquisition failed",{error:(0,l.getErrorMessage)(e)}))):Promise.resolve()
|
|
744
745
|
await Promise.all([i,a])}catch(e){m.warn("Error in session tag mapping / lock acquisition",{error:(0,l.getErrorMessage)(e)})}}}}if(C){const e={context:t,apiClient:n,logger:o,metrics:s,mcpServer:g,cliOrigin:_}
|
|
745
|
-
E=await C.handler(
|
|
746
|
+
E=await C.handler(b,e)}else m.info(`Tool ${i} not found, returning negative response`),E={content:[{type:"text",text:`The tool '${i}' does not exist.`}]}
|
|
746
747
|
return Date.now(),Date.now(),k({tool:i,success:!0}),E}catch(t){m.error("Error executing tool:",{error:t instanceof Error?t.stack:t+"",tool:e.params.name}),s.incrementCounter("tool_errors_total",1,{tool:e.params.name,error:t instanceof Error?t.name:"unknown"})
|
|
747
748
|
let r="Unknown error"
|
|
748
749
|
if(t instanceof Error)r=t.message
|
|
@@ -1080,94 +1081,93 @@ const e=this.online,t=await this.performHealthCheck()
|
|
|
1080
1081
|
return e!==t&&(t?(this.logger.info("Health check status changed to ONLINE"),this.options.onOnlineCallback()):(this.logger.info("Health check status changed to OFFLINE"),this.options.onOfflineCallback())),t}isOffline(){return this.forcedOfflineMode||!1}scheduleNextCheck(e=this.options.checkIntervalMs){this.checkInterval&&(clearInterval(this.checkInterval),this.checkInterval=null),0!==e?setTimeout((()=>{this.performHealthCheck().catch((()=>{}))}),e||this.options.checkIntervalMs||3e4):this.performHealthCheck().catch((()=>{}))}setOfflineMode(e){const t=this.forcedOfflineMode
|
|
1081
1082
|
this.forcedOfflineMode=e,t!==e&&(this.logger.info("Offline mode "+(e?"ENABLED":"DISABLED")),this.metrics.setGauge("health_check_forced_offline",e?1:0),e||this.scheduleNextCheck(0))}getStats(){return{consecutiveFailures:this.consecutiveFailures,currentBackoffMs:this.currentBackoffMs,lastCheckTime:this.lastCheckTime}}}},1722(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1082
1083
|
const r=t(6183),n=t(355)
|
|
1083
|
-
exports.def={name:"complete_task",description:"Mark a task as completed with a summary of work done.",schema:r.CompleteTaskSchema,annotations:{title:"Complete Task",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},handler(e,t){return(0,n.handleCompleteTask)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},1725(e,exports,t){function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,
|
|
1084
|
+
exports.def={name:"complete_task",description:"Mark a task as completed with a summary of work done.",schema:r.CompleteTaskSchema,annotations:{title:"Complete Task",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},handler(e,t){return(0,n.handleCompleteTask)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},1725(e,exports,t){function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,T.join)(e.basePath||process.cwd(),".alchemy_lab","spawn-debug.log");(0,S.appendFileSync)(o,n)}catch{}}async function n(e){try{const t=`http://localhost:${P}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
|
|
1084
1085
|
if(!r.ok)return null
|
|
1085
1086
|
const n=await r.json()
|
|
1086
1087
|
return n.success?n.data??null:null}catch{return null}}async function o(e,t,o,s,i){const{agent:a="work",prompt:c,requestId:l,allowParallel:d=!1,useExistingSession:u}=e
|
|
1087
|
-
if(r(t,"handleSpawn called",{agent:a,promptLength:c.length,requestId:l,useExistingSession:u,cliOriginSessionId:i?.sessionId||null}),!(0,
|
|
1088
|
-
return{content:[{type:"text",text:`\u274c Unknown agent '${a}'.\n\n**Available agents:** ${e.join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}}try{const e=(0,
|
|
1088
|
+
if(r(t,"handleSpawn called",{agent:a,promptLength:c.length,requestId:l,useExistingSession:u,cliOriginSessionId:i?.sessionId||null}),!(0,M.isValidAgent)(a)){const e=(0,M.getAgentNames)()
|
|
1089
|
+
return{content:[{type:"text",text:`\u274c Unknown agent '${a}'.\n\n**Available agents:** ${e.join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}}try{const e=(0,v.getCachedSession)(),n=i?.sessionId||e?.sessionId
|
|
1089
1090
|
let o=e?.agentType
|
|
1090
|
-
if(r(t,"Spawn agent type check",{cliOriginSessionId:i?.sessionId||null,cachedSessionId:e?.sessionId||null,cachedAgentType:e?.agentType||null,pid:process.pid,envSessionTag:process.env.ALCHEMY_SESSION_TAG||null,envInitialBranch:process.env.ALCHEMY_INITIAL_BRANCH||null}),!o&&n)try{const e=`http://localhost:${
|
|
1091
|
+
if(r(t,"Spawn agent type check",{cliOriginSessionId:i?.sessionId||null,cachedSessionId:e?.sessionId||null,cachedAgentType:e?.agentType||null,pid:process.pid,envSessionTag:process.env.ALCHEMY_SESSION_TAG||null,envInitialBranch:process.env.ALCHEMY_INITIAL_BRANCH||null}),!o&&n)try{const e=`http://localhost:${P}/api/sessions/${encodeURIComponent(n)}/agent-type`
|
|
1091
1092
|
r(t,"Looking up agent type from action server",{sessionId:n,url:e})
|
|
1092
1093
|
const s=await fetch(e)
|
|
1093
1094
|
if(s.ok){const e=await s.json()
|
|
1094
|
-
r(t,"Agent type response from action server",{sessionId:n,agentType:e.agentType||null,source:e.source||null,success:e.success}),e.success&&e.agentType&&(o=e.agentType,(0,
|
|
1095
|
-
if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${o}' cannot spawn '${a}'.\n\n**Allowed subagents for ${o}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,
|
|
1095
|
+
r(t,"Agent type response from action server",{sessionId:n,agentType:e.agentType||null,source:e.source||null,success:e.success}),e.success&&e.agentType&&(o=e.agentType,(0,v.updateCachedSession)({agentType:o}))}else r(t,"Agent type lookup failed",{sessionId:n,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e?.sessionId,error:(0,q.getErrorMessage)(n)})}if(o){const e=(0,M.getAllowedSubagents)(o)
|
|
1096
|
+
if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${o}' cannot spawn '${a}'.\n\n**Allowed subagents for ${o}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,q.getErrorMessage)(e)})}let h
|
|
1096
1097
|
try{const e=await n(a)
|
|
1097
|
-
if(h=e?.requestContextMode,!h){const e=(0,
|
|
1098
|
+
if(h=e?.requestContextMode,!h){const e=(0,M.getBuiltInAgentConfig)(a)
|
|
1098
1099
|
h=e?.requestContextMode}}catch{}if(h&&"none"!==h&&!l)return{content:[{type:"text",text:`\u274c Agent '${a}' requires a requestId to be provided.\n\nThis agent has requestContextMode: '${h}' which means it needs to work in the context of a specific request.\n\nPlease provide a requestId when spawning this agent.`}],isError:!0}
|
|
1099
1100
|
const g=await(0,b.getServerUrl)(t,o)
|
|
1100
1101
|
r(t,"serverUrl resolved",{serverUrl:g})
|
|
1101
1102
|
const f=t.basePath
|
|
1102
1103
|
if(!f)throw new w.ValidationError("Working directory not available in context")
|
|
1103
|
-
const p=(0,
|
|
1104
|
+
const p=(0,v.getCachedSession)()
|
|
1104
1105
|
let m
|
|
1105
1106
|
if(g)try{m=i?.sessionId||p?.sessionId||await(0,b.discoverParentSessionId)(g,o)}catch{}let y=""
|
|
1106
1107
|
if(s&&l)try{const e=s.getSessionRequestAssociationClient()
|
|
1107
1108
|
if(e){const t=await e.getSessionsForRequest(l,!0),r=m?t.filter((e=>e.opencodeSessionId!==m)):t
|
|
1108
1109
|
if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
|
|
1109
1110
|
if(!d)return o.warn("Blocked spawn: request already has active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId))}),{content:[{type:"text",text:`\u274c Cannot spawn: Request ${l} already has ${r.length} active worker(s): ${e}\n\nOptions:\n\u2022 Use \`useExistingSession: "${r[0].opencodeSessionId}"\` to send work to the existing session\n\u2022 Use \`allowParallel: true\` if you really need multiple workers on the same request`}],isError:!0}
|
|
1110
|
-
y=`\u26a0\ufe0f Warning: Request ${l} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,o.warn("Spawning parallel subagent for request with existing active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){o.debug("Failed to check for existing workers",{error:(0,
|
|
1111
|
-
l&&(
|
|
1112
|
-
let
|
|
1113
|
-
if(u){if(
|
|
1111
|
+
y=`\u26a0\ufe0f Warning: Request ${l} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,o.warn("Spawning parallel subagent for request with existing active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){o.debug("Failed to check for existing workers",{error:(0,q.getErrorMessage)(e)})}let _,E,S=c
|
|
1112
|
+
l&&(_="requests/"+l,r(t,"Setting initialBranch for agent",{agent:a,requestId:l,initialBranch:_,agentRequestContextMode:h||"undefined"}),S="readonly"===h?`Working on request ${l} (READONLY mode - you cannot modify files, only explore and report).\n\n${c}`:`Working on request ${l}.\n\n${c}`)
|
|
1113
|
+
let T=!1
|
|
1114
|
+
if(u){if(E=u,o.info("Using existing session for spawn",{sessionId:E,requestId:l}),!g)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1114
1115
|
try{let e
|
|
1115
|
-
try{const t=await fetch(`http://localhost:${
|
|
1116
|
+
try{const t=await fetch(`http://localhost:${P}/api/project-settings`)
|
|
1116
1117
|
if(t.ok){const r=await t.json()
|
|
1117
1118
|
if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
|
|
1118
|
-
e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${
|
|
1119
|
+
e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${E}/prompt_async`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:S}],...a?{agent:a}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
|
|
1119
1120
|
if(!r.ok){const e=await r.text().catch((()=>"Unknown error"))
|
|
1120
|
-
throw Error(`Failed to send to existing session: ${r.status} ${e}`)}o.info("Prompt sent to existing session",{sessionId:
|
|
1121
|
-
const i=m||p?.sessionId||await(0,b.discoverParentSessionId)(g,o);(0,
|
|
1121
|
+
throw Error(`Failed to send to existing session: ${r.status} ${e}`)}o.info("Prompt sent to existing session",{sessionId:E,agent:a})}catch(e){throw Error("Failed to use existing session: "+(0,q.getErrorMessage)(e))}}else{if(T=!0,r(t,"Creating session via HTTP and spawning CLI"),!g)throw Error("Cannot spawn subagent: no server URL available")
|
|
1122
|
+
const i=m||p?.sessionId||await(0,b.discoverParentSessionId)(g,o);(0,C.logSessionIdentity)("subagent_operations.spawn",m?"early-discovery":p?"_meta":"http-discovery",{parentSessionId:i}),r(t,"Parent session discovered",{parentSessionId:i})
|
|
1122
1123
|
const u=g.replace(/\/$/,"")+"/session",h=e.title?e.title:l?`[${l}] ${c.slice(0,40)}${c.length>40?"...":""}`:`${c.slice(0,50)}${c.length>50?"...":""}`,y=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentID:i,title:h})})
|
|
1123
1124
|
if(!y.ok)throw Error("Failed to create session: "+y.status)
|
|
1124
1125
|
const w=await y.json()
|
|
1125
1126
|
if(!w.id)throw Error("Session created but no ID returned")
|
|
1126
|
-
const
|
|
1127
|
-
r(t,"Pre-created session with parentID",{preCreatedSessionId:
|
|
1128
|
-
const
|
|
1127
|
+
const x=w.id
|
|
1128
|
+
r(t,"Pre-created session with parentID",{preCreatedSessionId:x,parentSessionId:i}),o.info("Pre-created session with parentID",{preCreatedSessionId:x,parentSessionId:i})
|
|
1129
|
+
const O=(async()=>{if(s)try{const n=s.getCLISessionClient()
|
|
1129
1130
|
if(!n)return
|
|
1130
1131
|
let o,c
|
|
1131
|
-
if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:(0,
|
|
1132
|
-
o=e.id,c=e.workflowId,r(t,"Registered parent session in DB",{parentSessionId:i,parentDbId:o,parentWorkflowId:c})}const l=await n.createOrUpdateSession({externalSessionId:
|
|
1133
|
-
r(t,"Registered child session in DB",{childSessionId:
|
|
1134
|
-
let
|
|
1132
|
+
if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:(0,v.getCachedSession)()?.agentType||void 0})
|
|
1133
|
+
o=e.id,c=e.workflowId,r(t,"Registered parent session in DB",{parentSessionId:i,parentDbId:o,parentWorkflowId:c})}const l=await n.createOrUpdateSession({externalSessionId:x,providerId:"opencode",parentSessionId:o||null,title:h,status:"active",agentType:a,specialization:e.specialization,workflowId:c||void 0})
|
|
1134
|
+
r(t,"Registered child session in DB",{childSessionId:x,childDbId:l.id,parentDbId:o})}catch(e){r(t,"Failed to register sessions in DB",{error:(0,q.getErrorMessage)(e)}),o.warn("Failed to register sessions in alchemy DB",{error:(0,q.getErrorMessage)(e)})}})()
|
|
1135
|
+
let j
|
|
1135
1136
|
r(t,"Starting model resolution",{agent:a,cwd:f})
|
|
1136
|
-
try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${
|
|
1137
|
+
try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${P}/api/agents/by-name/${a}`})
|
|
1137
1138
|
const e=await n(a)
|
|
1138
1139
|
if(r(t,"Agent config result",{agent:a,agentConfig:e||"null",hasConfig:!!e}),e){const n=e.preferredProvider||"inherit",o=e.preferredModelTier||"same"
|
|
1139
1140
|
r(t,"Agent preferences",{agent:a,preferredProvider:n,preferredTier:o,rawProvider:e.preferredProvider,rawTier:e.preferredModelTier})
|
|
1140
|
-
const s=(0,
|
|
1141
|
-
r(t,"Model resolution result",{agent:a,result:s}),s.resolved?(
|
|
1141
|
+
const s=(0,R.resolveAgentModel)(f,n,o)
|
|
1142
|
+
r(t,"Model resolution result",{agent:a,result:s}),s.resolved?(j=s.fullModel,r(t,"Resolved agent model",{agent:a,model:j,preferredProvider:n,preferredTier:o})):r(t,"Model resolution fallback",{agent:a,reason:s.reason})}else{const e=(0,M.getBuiltInAgentConfig)(a)
|
|
1142
1143
|
if(r(t,"No API agent config, checking built-in defaults",{agent:a,builtInConfig:e||"null"}),e){const n=e.preferredProvider||"inherit",o=e.preferredModelTier||"same"
|
|
1143
1144
|
r(t,"Using built-in agent preferences",{agent:a,preferredProvider:n,preferredTier:o})
|
|
1144
|
-
const s=(0,
|
|
1145
|
-
r(t,"Built-in model resolution result",{agent:a,result:s}),s.resolved&&(
|
|
1145
|
+
const s=(0,R.resolveAgentModel)(f,n,o)
|
|
1146
|
+
r(t,"Built-in model resolution result",{agent:a,result:s}),s.resolved&&(j=s.fullModel,r(t,"Resolved built-in agent model",{agent:a,model:j,preferredProvider:n,preferredTier:o}))}else r(t,"No built-in config found - using default model",{agent:a})}}catch(e){r(t,"Error resolving agent model",{agent:a,error:(0,q.getErrorMessage)(e)})}try{const e=await async function(){try{const e=`http://localhost:${P}/api/project-settings`,t=await fetch(e)
|
|
1146
1147
|
if(t.ok){const e=await t.json()
|
|
1147
1148
|
return e?.data?.defaultModel||null}}catch{}return null}()
|
|
1148
|
-
if(e)if(
|
|
1149
|
-
"same"===(o?.preferredModelTier||"same")&&(
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
return u?P+=`Prompt sent to existing session ${_}.`:(P+=`Background ${a} subagent spawned successfully.`,_&&"unknown"!==_&&"spawning"!==_&&(P+=`\n[SESSION:${_}]`)),l&&(P+="\nWorking on: "+l),P+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:P}]}}async function s(e,t,r,n,o,s,i){const a=await(0,b.getServerUrl)(r,n)
|
|
1149
|
+
if(e)if(j){const o=await n(a)
|
|
1150
|
+
"same"===(o?.preferredModelTier||"same")&&(j=e,r(t,"Applied user default model (same tier)",{agent:a,userDefaultModel:e}))}else j=e,r(t,"Using user default model (no agent resolution)",{agent:a,userDefaultModel:e})}catch(e){r(t,"Failed to fetch user default model",{error:(0,q.getErrorMessage)(e)})}if(r(t,"Final resolved model before spawn",{agent:a,resolvedModel:j||"undefined (will use default)"}),await O,l&&_)try{await(0,I.ensureRequestWorktree)(f,l,o)}catch(e){r(t,"Pre-spawn worktree creation failed (non-fatal)",{requestId:l,error:(0,q.getErrorMessage)(e)})}const $=(0,k.spawnDetachedSubagent)({agent:a,prompt:S,cwd:f,sessionId:x,model:j,initialBranch:_,allowParallel:d,serverUrl:g})
|
|
1151
|
+
if(!$.success)throw Error("Failed to spawn subagent: "+$.error)
|
|
1152
|
+
E=x,r(t,"CLI spawn successful with pre-created session",{sessionId:x,pid:$.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:x,pid:$.pid,parentSessionId:i})}if(s&&l&&E&&"unknown"!==E&&"spawning"!==E)try{const e=s.getSessionRequestAssociationClient()
|
|
1153
|
+
if(e&&(e.createAssociation(E,l).then((()=>o.info("Created session-request association",{sessionId:E,requestId:l}))).catch((e=>o.warn("Failed to create session-request association",{error:(0,q.getErrorMessage)(e),sessionId:E,requestId:l}))),"coder"===a)){const e=s.getRequestClient()
|
|
1154
|
+
e&&e.updateRequest(l,{cliOrigin:{providerId:"opencode",sessionId:E,createdAt:(new Date).toISOString()}}).catch((e=>o.debug("Failed to update request cliOrigin",{error:(0,q.getErrorMessage)(e)})))}}catch(e){o.warn("Failed to create session-request association",{error:(0,q.getErrorMessage)(e),sessionId:E,requestId:l})}let x=y
|
|
1155
|
+
return u?x+=`Prompt sent to existing session ${E}.`:(x+=`Background ${a} subagent spawned successfully.`,E&&"unknown"!==E&&"spawning"!==E&&(x+=`\n[SESSION:${E}]`)),l&&(x+="\nWorking on: "+l),x+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:x}]}}async function s(e,t,r,n,o,s,i){const a=await(0,b.getServerUrl)(r,n)
|
|
1156
1156
|
if(!a)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1157
|
-
if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId||(0,
|
|
1157
|
+
if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId||(0,v.getCachedSession)()?.sessionId||await(0,b.discoverParentSessionId)(a,n)
|
|
1158
1158
|
if(t){const r=o.getCLISessionClient()
|
|
1159
1159
|
if(r){let o=await r.getByExternalId(t)
|
|
1160
|
-
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,
|
|
1161
|
-
if(!c)try{const t=`http://localhost:${
|
|
1160
|
+
o||(o=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),n.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:o?.id})),o&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:o.id,status:"active"}),n.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){n.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,q.getErrorMessage)(e)})}let c=s
|
|
1161
|
+
if(!c)try{const t=`http://localhost:${P}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
|
|
1162
1162
|
if(r.ok){const e=await r.json()
|
|
1163
1163
|
e.success&&e.agentType&&(c=e.agentType)}}catch{n.warn("Agent type lookup failed for session",{sessionId:e})}if(!c)throw new w.ValidationError(`Cannot continue session ${e}: unable to determine agent type. The session's agent type could not be looked up from the action server.`)
|
|
1164
1164
|
try{let r
|
|
1165
|
-
try{const e=await fetch(`http://localhost:${
|
|
1165
|
+
try{const e=await fetch(`http://localhost:${P}/api/project-settings`)
|
|
1166
1166
|
if(e.ok){const t=await e.json()
|
|
1167
1167
|
if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
|
|
1168
1168
|
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)})
|
|
1169
1169
|
if(!s.ok){const e=await s.text().catch((()=>"Unknown error"))
|
|
1170
|
-
throw Error(`Failed to send message: ${s.status} ${e}`)}return n.info("Message sent to subagent session",{sessionId:e,agent:c}),{content:[{type:"text",text:`Message sent to session ${e}.\nThe subagent will process it in the background.`}]}}catch(e){throw Error("Failed to continue session: "+(0,
|
|
1170
|
+
throw Error(`Failed to send message: ${s.status} ${e}`)}return n.info("Message sent to subagent session",{sessionId:e,agent:c}),{content:[{type:"text",text:`Message sent to session ${e}.\nThe subagent will process it in the background.`}]}}catch(e){throw Error("Failed to continue session: "+(0,q.getErrorMessage)(e))}}function i(e){const t=Math.floor(e/1e3)
|
|
1171
1171
|
if(60>t)return t+"s"
|
|
1172
1172
|
const r=Math.floor(t/60)
|
|
1173
1173
|
return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function a(e){const t=[]
|
|
@@ -1177,7 +1177,7 @@ const s=n.path||n.file||n.directory,i=n.needle||n.query||n.pattern
|
|
|
1177
1177
|
"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))
|
|
1178
1178
|
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
|
|
1179
1179
|
return{current:r?.name??null,recent:n.map((e=>e.name)),lastActivityTime:o}}function c(e){return 1e3>e?"<1s ago":6e4>e?Math.floor(e/1e3)+"s ago":36e5>e?Math.floor(e/6e4)+"m ago":Math.floor(e/36e5)+"h ago"}function l(e,t){const r=e||t,n=Date.now()-r
|
|
1180
|
-
return e&&
|
|
1180
|
+
return e&&x>n?{status:"working",detail:"last action "+c(n),isReady:!1}:n>O&&e?{status:"stalled",detail:"no activity for "+c(n),isReady:!0}:e?{status:"idle",detail:"no activity for "+c(n),isReady:!0}:{status:"idle",detail:"no tool activity",isReady:!0}}function d(e){let t=0,r=0,n=0
|
|
1181
1181
|
for(const o of e.trim().split("\n")){if(!o)continue
|
|
1182
1182
|
const[e,s]=o.split("\t")
|
|
1183
1183
|
"-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function u(e,r,n,o){const s=await(0,b.getServerUrl)(r,n)
|
|
@@ -1190,7 +1190,7 @@ let p={input:0,output:0,reasoning:0},m="",y=l(null,h.time.updated)
|
|
|
1190
1190
|
if(f.ok){const e=await f.json()
|
|
1191
1191
|
for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(p.input+=t.info.tokens.input||0,p.output+=t.info.tokens.output||0,p.reasoning+=t.info.tokens.reasoning||0)
|
|
1192
1192
|
const t=a(e)
|
|
1193
|
-
y=l(t.lastActivityTime,h.time.updated),t.current&&(m+="\nCurrent: "+t.current),t.recent.length>0&&(m+="\nRecent: "+t.recent.join(", "))}const w=Date.now()-h.time.created,k=y.status,
|
|
1193
|
+
y=l(t.lastActivityTime,h.time.updated),t.current&&(m+="\nCurrent: "+t.current),t.recent.length>0&&(m+="\nRecent: "+t.recent.join(", "))}const w=Date.now()-h.time.created,k=y.status,I=y.isReady,b=p.input+p.output+p.reasoning
|
|
1194
1194
|
let v="",C="",_=null
|
|
1195
1195
|
if(o)try{const t=o.getSessionRequestAssociationClient()
|
|
1196
1196
|
if(t){const r=await t.getActiveRequestsForSession(e,!1)
|
|
@@ -1205,12 +1205,12 @@ if(e.trim())return d(e)}try{const t=n(`git log main --merges --oneline -n 50 --g
|
|
|
1205
1205
|
if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
|
|
1206
1206
|
if(o.trim())return{...d(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
|
|
1207
1207
|
if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
|
|
1208
|
-
v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${k} (${y.detail})\nReady for input: ${
|
|
1208
|
+
v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${k} (${y.detail})\nReady for input: ${I?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${b.toLocaleString()} (in: ${p.input.toLocaleString()}, out: ${p.output.toLocaleString()}${p.reasoning>0?", reasoning: "+p.reasoning.toLocaleString():""})${m}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,q.getErrorMessage)(e))}}async function h(e,t,r){const n=await(0,b.getServerUrl)(t,r)
|
|
1209
1209
|
if(!n)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1210
1210
|
r.info("Aborting subagent session",{sessionId:e})
|
|
1211
1211
|
try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
|
|
1212
1212
|
if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
|
|
1213
|
-
throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,
|
|
1213
|
+
throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,q.getErrorMessage)(e))}}async function g(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:c,minTokens:d,maxTokens:u,maxAgeHours:h}=n,g=await(0,b.getServerUrl)(e,t)
|
|
1214
1214
|
if(!g)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1215
1215
|
t.info("Listing sessions",{filters:n})
|
|
1216
1216
|
try{const e=g.replace(/\/$/,"")+"/session",t=await fetch(e)
|
|
@@ -1224,10 +1224,10 @@ if(o&&(w=w.filter((e=>"idle"!==(y[e.id]?.type||"idle")))),void 0!==h){const e=36
|
|
|
1224
1224
|
w=w.filter((e=>e.time.created>=t))}if(0===w.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1225
1225
|
let k={}
|
|
1226
1226
|
if(r)try{const e=r.getCLISessionClient()
|
|
1227
|
-
e&&(k=await e.batchEnrich(w.map((e=>e.id))))}catch{}const
|
|
1227
|
+
e&&(k=await e.batchEnrich(w.map((e=>e.id))))}catch{}const I=g.replace(/\/$/,""),b=await Promise.allSettled(w.map((e=>fetch(`${I}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),v=[]
|
|
1228
1228
|
for(let e=0;e<w.length;e++){const t=w[e],r=Date.now()-t.time.created
|
|
1229
1229
|
let o=0,i=null,c=[],h=l(null,t.time.updated)
|
|
1230
|
-
const g=
|
|
1230
|
+
const g=b[e],f="fulfilled"===g.status?g.value:[]
|
|
1231
1231
|
for(const e of f)"assistant"===e.info.role&&e.info.tokens&&(o+=(e.info.tokens.input||0)+(e.info.tokens.output||0)+(e.info.tokens.reasoning||0))
|
|
1232
1232
|
if(f.length>0){const e=a(f)
|
|
1233
1233
|
h=l(e.lastActivityTime,t.time.updated),i=e.current||null,c=e.recent}const p=h.status
|
|
@@ -1237,16 +1237,16 @@ const m=k[t.id]
|
|
|
1237
1237
|
if(n.agentType&&(!m||m.agentType!==n.agentType))continue
|
|
1238
1238
|
if("archived"===m?.status)continue
|
|
1239
1239
|
let y=""
|
|
1240
|
-
const
|
|
1240
|
+
const I=[]
|
|
1241
1241
|
if(m?.associations&&m.associations.length>0){const e=m.associations.filter((e=>!e.endedAt)).map((e=>e.requestLocalId)),t=m.associations.filter((e=>e.endedAt)).map((e=>e.requestLocalId))
|
|
1242
|
-
|
|
1242
|
+
I.push(...e,...t)
|
|
1243
1243
|
const r=[]
|
|
1244
|
-
e.length>0&&r.push("active: "+e.join(", ")),t.length>0&&r.push("prev: "+t.join(", ")),r.length>0&&(y=` [${r.join(" | ")}]`)}if(s&&!
|
|
1244
|
+
e.length>0&&r.push("active: "+e.join(", ")),t.length>0&&r.push("prev: "+t.join(", ")),r.length>0&&(y=` [${r.join(" | ")}]`)}if(s&&!I.includes(s))continue
|
|
1245
1245
|
const C=t.title||"Untitled",_=C.length>50?C.slice(0,47)+"...":C
|
|
1246
|
-
v.push({id:t.id,title:_,status:p,age:r,totalTokens:o,requestsInfo:y,allRequestIds:
|
|
1246
|
+
v.push({id:t.id,title:_,status:p,age:r,totalTokens:o,requestsInfo:y,allRequestIds:I,statusDetail:h.detail,specialization:m?.specialization??null,currentAction:i,recentActions:c})}if(0===v.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1247
1247
|
const C=c?v.slice(0,c):v,_=C.map((e=>{const t=e.specialization?"\n Specialization: "+e.specialization:"",r=e.currentAction?"\n Current: "+e.currentAction:"",n=e.recentActions.length>0?"\n Recent: "+e.recentActions.join(", "):""
|
|
1248
1248
|
return`\u2022 ${e.id}\n ${e.title}${t}\n Status: ${e.status} (${e.statusDetail}) | Age: ${i(e.age)} | ${e.totalTokens.toLocaleString()} tokens${e.requestsInfo}${r}${n}`})),E=c&&v.length>c?` (showing ${c} of ${v.length})`:""
|
|
1249
|
-
return{content:[{type:"text",text:`Found ${C.length} session${1!==C.length?"s":""}${E}:\n\n${_.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,
|
|
1249
|
+
return{content:[{type:"text",text:`Found ${C.length} session${1!==C.length?"s":""}${E}:\n\n${_.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,q.getErrorMessage)(e))}}var f,p=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1250
1250
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1251
1251
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),m=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),y=this&&this.__importStar||(f=function(e){return f=Object.getOwnPropertyNames||function(e){var t=[]
|
|
1252
1252
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -1256,7 +1256,7 @@ if(null!=e)for(var r=f(e),n=0;n<r.length;n++)"default"!==r[n]&&p(t,e,r[n])
|
|
|
1256
1256
|
return m(t,e),t})
|
|
1257
1257
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=o,exports.handleContinue=s,exports.handleCheckStatus=u,exports.handleAbort=h,exports.handleListSessions=g,exports.handleSubagentOperations=async function(e,t,r,n,i,a){const c=r.child({tool:"subagent_operations"}),l=n.startTimer("tool_execution_time")
|
|
1258
1258
|
try{if(e&&!e.operation&&(e.spawn?e.operation="spawn":e.continue?e.operation="continue":e.readMessages?e.operation="read-messages":e.listSessions?e.operation="list-sessions":e.prompt&&(e.agent||e.description)?e={operation:"spawn",spawn:{agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId,allowParallel:e.allowParallel,useExistingSession:e.useExistingSession}}:e.sessionId&&e.prompt&&!e.spawn?e={operation:"continue",sessionId:e.sessionId,continue:{prompt:e.prompt}}:e.sessionId&&(e={operation:"check-status",sessionId:e.sessionId})),e?.spawn&&"string"==typeof e.spawn)try{e.spawn=JSON.parse(e.spawn)}catch{}if(e?.continue&&"string"==typeof e.continue)try{e.continue=JSON.parse(e.continue)}catch{}"spawn"===e?.operation&&e?.prompt&&!e?.spawn&&(e.spawn={agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId},delete e.prompt,delete e.agent,delete e.description,delete e.requestId),"continue"===e?.operation&&e?.prompt&&!e?.continue&&(e.continue={prompt:e.prompt},delete e.prompt)
|
|
1259
|
-
const r=
|
|
1259
|
+
const r=E.validateArgs(e,_.SubagentOperationsSchema),{sessionId:d,operation:f}=r
|
|
1260
1260
|
let p
|
|
1261
1261
|
switch(c.info("Processing subagent_operations",{operation:f,sessionId:d}),f){case"spawn":p=await o(r.spawn,t,c,i,a)
|
|
1262
1262
|
break
|
|
@@ -1276,13 +1276,13 @@ throw Error("Failed to fetch messages: "+n.status)}const s=await n.json()
|
|
|
1276
1276
|
if(0===s.length)return{content:[{type:"text",text:`Session ${e} has no messages yet.`}]}
|
|
1277
1277
|
const i=s.map(((e,t)=>{const r="user"===e.info.role?"USER":"ASSISTANT",n=e.parts.filter((e=>"text"===e.type&&e.text)).map((e=>e.text)).join("\n"),o=n.length>5e3?n.slice(0,5e3)+"...[truncated]":n
|
|
1278
1278
|
return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n${o}`})).join("\n\n---\n\n")
|
|
1279
|
-
return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,
|
|
1279
|
+
return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,q.getErrorMessage)(e))}}(d,e,t,c)
|
|
1280
1280
|
break
|
|
1281
|
-
case"list-sessions":const n={activeOnly:r.listSessions?.activeOnly,requestId:r.listSessions?.requestId,limit:r.listSessions?.limit,minTokens:r.listSessions?.minTokens,maxTokens:r.listSessions?.maxTokens,maxAgeHours:r.listSessions?.maxAgeHours,parentSessionId:a?.sessionId||(0,
|
|
1281
|
+
case"list-sessions":const n={activeOnly:r.listSessions?.activeOnly,requestId:r.listSessions?.requestId,limit:r.listSessions?.limit,minTokens:r.listSessions?.minTokens,maxTokens:r.listSessions?.maxTokens,maxAgeHours:r.listSessions?.maxAgeHours,parentSessionId:a?.sessionId||(0,v.getCachedSession)()?.sessionId}
|
|
1282
1282
|
p=await g(t,c,i,n)
|
|
1283
1283
|
break
|
|
1284
|
-
default:throw new w.ValidationError("Unknown operation: "+f)}return l({success:!0}),n.incrementCounter(`subagent_operations_${f}_success`,1),p}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,
|
|
1285
|
-
const w=t(9860),k=t(8035),b=t(7617),
|
|
1284
|
+
default:throw new w.ValidationError("Unknown operation: "+f)}return l({success:!0}),n.incrementCounter(`subagent_operations_${f}_success`,1),p}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,q.getErrorMessage)(e)}],isError:!0}}}
|
|
1285
|
+
const w=t(9860),k=t(8035),I=t(2424),b=t(7617),v=t(715),C=t(7280),_=t(6183),E=y(t(5967)),q=t(8824),S=t(9896),T=t(6928),M=t(8955),R=t(5671),P=3456,x=6e4,O=3e5},1791(e,exports,t){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}}
|
|
1286
1286
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
|
|
1287
1287
|
const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
|
|
1288
1288
|
exports.ProjectContext=class{constructor(e,t){this.projectId=null,this.initialized=!1,this.initializationInProgress=!1,this.initializationPromise=null,this.basePath=e,this.alchemyPath=s.default.join(e,i.ALCHEMY_DIR_NAME),this.projectFilePath=s.default.join(this.alchemyPath,"project.json"),this.logger=t.child({component:"project-context"}),this.logger.debug("Project context constructed",{basePath:this.basePath,alchemyPath:this.alchemyPath,projectFilePath:this.projectFilePath})}initialize(){return this.initialized&&this.projectId?(this.logger.info("Project context already initialized",{projectId:this.projectId}),Promise.resolve(this.projectId)):this.initializationInProgress&&this.initializationPromise?(this.logger.info("Project context initialization already in progress, reusing promise"),this.initializationPromise):(this.initializationInProgress=!0,this.logger.debug("Starting initialization",{basePath:this.basePath}),this.initializationPromise=this.doInitialize(),this.initializationPromise)}async doInitialize(){try{if(o.default.existsSync(this.alchemyPath))this.logger.debug("alchemy_lab directory already exists")
|
|
@@ -1557,26 +1557,26 @@ var t={}
|
|
|
1557
1557
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
1558
1558
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1559
1559
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,t,r,n,o,s,i,p){const m=s.child({tool:"move_files"}),y=Date.now()
|
|
1560
|
-
let w,k,
|
|
1561
|
-
const
|
|
1560
|
+
let w,k,I=d.FileOperationPhase.VALIDATION
|
|
1561
|
+
const b={toolName:"move-files",operationName:"write",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"move-files",metricsPrefix:"move_files",successMessage:"Successfully moved files",failureMessage:"Failed to move files"}
|
|
1562
1562
|
try{const s=d.validateArgs(e,l.MoveFilesSchema),{taskId:u,operations:h,comment:v}=s
|
|
1563
1563
|
if(m.info("Moving multiple files and directories",{taskId:u,operationCount:h.length,comment:v}),!h||0===h.length)throw Error("At least one move operation must be specified")
|
|
1564
|
-
d.validateTaskIdFormat(u,m,i,
|
|
1564
|
+
d.validateTaskIdFormat(u,m,i,b.metricsPrefix)
|
|
1565
1565
|
const C=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1566
1566
|
m.info("Initial branch context",{initialBranch:C.branch,initialRequestId:C.requestId,isMain:C.isMain})
|
|
1567
1567
|
const _=[]
|
|
1568
1568
|
for(const e of h){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.source,t),{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(e.destination,t)
|
|
1569
|
-
_.push({source:r,destination:o,fullSource:n,fullDestination:s})}
|
|
1570
|
-
const E=await d.validateTaskId(u,_[0].source,r,m,i,
|
|
1569
|
+
_.push({source:r,destination:o,fullSource:n,fullDestination:s})}I=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1570
|
+
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)
|
|
1571
1571
|
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})
|
|
1572
|
-
const M=await d.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:
|
|
1572
|
+
const M=await d.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:b.metricsPrefix})
|
|
1573
1573
|
if(!M.success){if(M.isLockConflict)return{content:[{type:"text",text:"\u274c "+M.error}],isError:!0}
|
|
1574
1574
|
throw Error(M.error)}let R={hadUserMods:!1,userModsCommitHash:void 0}
|
|
1575
1575
|
if(t.git)try{m.debug("[MOVE-FILES] Checking for user changes before move operations")
|
|
1576
1576
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"move-files",{requestId:q,taskId:u,workspaceManager:t.workspaceManager},m,i)
|
|
1577
|
-
e.userChangesCommitted&&(m.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),m.info("User changes committed before move-files operation",{taskId:u,moveOperationsCount:_.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),R={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){m.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),m.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:u,moveOperationsCount:_.length,error:e instanceof Error?e.message:e+""})}m.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:_.length}),
|
|
1578
|
-
const{toolRecordId:P,localToolRecordId:x}=await d.createFileOperationRecords(u,q,t.projectId,
|
|
1579
|
-
w=P,k=P,b
|
|
1577
|
+
e.userChangesCommitted&&(m.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),m.info("User changes committed before move-files operation",{taskId:u,moveOperationsCount:_.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),R={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){m.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),m.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:u,moveOperationsCount:_.length,error:e instanceof Error?e.message:e+""})}m.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:_.length}),I=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1578
|
+
const{toolRecordId:P,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:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},r,n,m,i,b.metricsPrefix,p)
|
|
1579
|
+
w=P,k=P,I=b.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1580
1580
|
const O=[]
|
|
1581
1581
|
let j=0
|
|
1582
1582
|
for(const e of _){const t={operation:{source:e.source,destination:e.destination},success:!1}
|
|
@@ -1586,24 +1586,32 @@ const n=c.default.dirname(e.fullDestination)
|
|
|
1586
1586
|
try{await a.default.mkdir(n,{recursive:!0})}catch(e){throw Error("Failed to create destination directory: "+n)}try{throw await a.default.access(e.fullDestination),Error("Destination already exists: "+e.destination)}catch(e){if(!(e instanceof Error&&e.message.includes("ENOENT")))throw e}await a.default.rename(e.fullSource,e.fullDestination),t.success=!0,j++,m.info("Successfully moved "+(r?"directory":"file"),{source:e.source,destination:e.destination,isDirectory:r})}catch(r){t.error=(0,f.getErrorMessage)(r),m.warn(`Failed to move ${e.source} to ${e.destination}`,{error:t.error})}O.push(t)}const $=Date.now()-y
|
|
1587
1587
|
i.recordValue("move_files_time",$),i.incrementCounter("move_files_operations_total",h.length),i.incrementCounter("move_files_operations_success",j),i.incrementCounter("move_files_operations_failed",h.length-j),j===h.length?i.incrementCounter("move_files_success",1):j>0?i.incrementCounter("move_files_partial_success",1):i.incrementCounter("move_files_total_failure",1)
|
|
1588
1588
|
let D=null
|
|
1589
|
-
if(j>0){
|
|
1589
|
+
if(j>0){I=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1590
1590
|
const e=O.filter((e=>e.success)),r=1===e.length?`Move ${e[0].isDirectory?"directory":"file"} from ${e[0].operation.source} to ${e[0].operation.destination} - ${v}`:`Move ${e.length} ${1===e.length?"item":"items"} - ${v}`
|
|
1591
|
-
D=await d.commitToGit(u,_[0].destination,P,x,r,t,m,i,
|
|
1591
|
+
D=await d.commitToGit(u,_[0].destination,P,x,r,t,m,i,b.metricsPrefix)}I=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1592
1592
|
const A=O.filter((e=>e.success)),F=O.filter((e=>!e.success))
|
|
1593
|
-
await d.updateFileOperationRecords(u,w,k,_[0].source,
|
|
1593
|
+
await d.updateFileOperationRecords(u,w,k,_[0].source,b.recordType,j===h.length?`Successfully moved all ${h.length} items`:`Moved ${j}/${h.length} items successfully`,{status:j===h.length?"completed":"partial_success",commitHash:D?.commitHash,previousCommitHash:D?.previousCommitHash,operationCount:h.length,successCount:j,failureCount:h.length-j,successfulOperations:A.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:F.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},j===h.length?`Successfully moved all ${h.length} items`:`Moved ${j}/${h.length} items successfully`,r,n,m,i,b.metricsPrefix)
|
|
1594
1594
|
const N=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1595
1595
|
let L=""
|
|
1596
1596
|
if(j===h.length)L=`Successfully moved all ${h.length} ${1===h.length?"item":"items"}`
|
|
1597
1597
|
else if(j>0){const e=O.filter((e=>!e.success))
|
|
1598
1598
|
L=`Successfully moved ${j}/${h.length} items.\n\nFailed operations:\n`+e.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")}else L="All move operations failed:\n"+O.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")
|
|
1599
1599
|
return D?.commitHash&&(L+="\nCommit: "+D.commitHash.substring(0,8)),N.requestId&&(L+="\nBranch: "+N.requestId),M.lockAcquired&&M.lockedRequestId&&(L+="\n\u{1f512} **Locked request:** "+M.lockedRequestId),{content:[{type:"text",text:L}],isError:0===j}}catch(o){if(e.taskId&&n)try{const r=o instanceof u.NotFoundError||o instanceof u.ValidationError||o instanceof h.ZodError
|
|
1600
|
-
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,f.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:
|
|
1601
|
-
if(i.recordValue("move_files_time",s),i.incrementCounter("move_files_errors",1),m.error("Error in move-files operation:",{error:(0,f.getErrorMessage)(o),time:s}),(w||k)&&e.taskId){
|
|
1602
|
-
try{await d.updateFileOperationRecords(e.taskId,w,k,e.operations?.[0]?.source||"unknown",
|
|
1603
|
-
const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(7478),f=t(8824)},2422(module){module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},
|
|
1600
|
+
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,f.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:I,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:"Failed to move files - "+(0,f.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
|
|
1601
|
+
if(i.recordValue("move_files_time",s),i.incrementCounter("move_files_errors",1),m.error("Error in move-files operation:",{error:(0,f.getErrorMessage)(o),time:s}),(w||k)&&e.taskId){I=d.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
1602
|
+
try{await d.updateFileOperationRecords(e.taskId,w,k,e.operations?.[0]?.source||"unknown",b.recordType,"Failed to move files",{status:"failed",error:(0,f.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)}}
|
|
1603
|
+
const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(7478),f=t(8824)},2422(module){module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2424(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ensureRequestWorktree=async function(e,t,i){const a="requests/"+t,c=(0,n.join)(e,s.ALCHEMY_DIR_NAME,"worktrees"),l=(0,n.join)(c,t)
|
|
1604
|
+
if((0,r.existsSync)(l))return void i.info("Worktree already exists on disk, skipping pre-spawn creation",{requestId:t,worktreePath:l})
|
|
1605
|
+
const d=(0,o.simpleGit)(e);(0,r.mkdirSync)(c,{recursive:!0})
|
|
1606
|
+
try{await d.raw(["worktree","prune"])}catch{}const u=await d.branch(),h=u.all.includes(a)
|
|
1607
|
+
try{if(h)await d.raw(["worktree","add",l,a]),i.info("Pre-spawn: created worktree for existing branch",{requestId:t,branchName:a,worktreePath:l})
|
|
1608
|
+
else{const e=u.all.includes("main")?"main":"master"
|
|
1609
|
+
await d.raw(["worktree","add","-b",a,l,e]),i.info("Pre-spawn: created worktree with new branch from latest main",{requestId:t,branchName:a,mainBranch:e,worktreePath:l})}}catch(e){const r=e instanceof Error?e.message:e+""
|
|
1610
|
+
i.warn("Pre-spawn: failed to create worktree (MCP process will retry)",{requestId:t,error:r})}}
|
|
1611
|
+
const r=t(9896),n=t(6928),o=t(3807),s=t(4139)},2425(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1604
1612
|
const r=t(6183),n=t(3707)
|
|
1605
1613
|
exports.def={name:"quick_manage",description:"Move, delete, or create directories. Wraps the change in a request/task workflow that auto-completes.\n\nProvide an array of operations, each with operationType and corresponding data:\n\u2022 create-directory: { createDirectory: { path } }\n\u2022 move-files: { moveFiles: { moves: [{ source, destination }] } }\n\u2022 delete-files: { deleteFiles: { targets: [{ path }] } }\n\nFor read-only operations like get-file-info, use manage_files instead.\n\nRequires: title, description, operations.",schema:r.QuickManageSchema,annotations:{title:"Quick Manage",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleQuickChange)(e,"manage",t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},2462(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0})
|
|
1606
|
-
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),f=t(4805),p=t(260),m=t(2283),y=t(4165),w=t(7834),k=t(9373),
|
|
1614
|
+
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),f=t(4805),p=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),M=t(4921),R=t(8850),P=t(3556),x=t(1391),O=t(6315),j=t(7713),$=t(6252),D=t(213),A=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),W=t(5247),U=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(g.def),(0,r.registerTool)(f.def),(0,r.registerTool)(p.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)(M.def),(0,r.registerTool)(R.def),(0,r.registerTool)(P.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(j.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(L.def),(0,r.registerTool)(z.def),(0,r.registerTool)(B.def),(0,r.registerTools)(H.metaDefs),(0,r.registerTools)(W.testingDefs),(0,r.registerTools)(U.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.requestConfig=void 0,exports.areTestsRequiredForCompletion=function(){return exports.requestConfig.requireTestsForCompletion},exports.setTestsRequiredForCompletion=function(e){exports.requestConfig.requireTestsForCompletion=e},exports.getCompletionMode=function(e){return e&&["auto-merge","auto-test-then-merge","manual-review"].includes(e)?e:"auto-merge"},exports.getApprovalMode=function(e){return e&&["none","require-approval"].includes(e)?e:"none"},exports.requestConfig={requireTestsForCompletion:!1}},2537(e,exports,t){async function r(e,t,r){if(C.has(r)&&_>=t){if(0===t)return 0
|
|
1607
1615
|
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]"
|
|
1608
1616
|
let l=""
|
|
1609
1617
|
if(s||void 0===o?.lineCount||(l=` (${i(o.lineCount)} lines)`),s&&o?.subtreeTotals){const{files:e,lines:t}=o.subtreeTotals
|
|
@@ -1619,14 +1627,14 @@ if(30>s)return`${s} day${1===s?"":"s"} ago`
|
|
|
1619
1627
|
const i=Math.floor(s/30)
|
|
1620
1628
|
if(12>i)return`${i} month${1===i?"":"s"} ago`
|
|
1621
1629
|
const a=Math.floor(i/12)
|
|
1622
|
-
return`${a} year${1===a?"":"s"} ago`}(o.modified)} | ${(0,
|
|
1630
|
+
return`${a} year${1===a?"":"s"} ago`}(o.modified)} | ${(0,b.formatTimestamp)(o.modified)})`)
|
|
1623
1631
|
break
|
|
1624
1632
|
case"size":s||"number"!=typeof o.size||(l+=` (${function(e){if(0===e)return"0 bytes"
|
|
1625
1633
|
let t=e,r=0
|
|
1626
1634
|
for(;t>=1024&&4>r;)t/=1024,r++
|
|
1627
1635
|
return`${0===r?t.toString():t.toFixed(10>t?1:0)}${["bytes","KB","MB","GB","TB"][r]}`}(o.size)})`)}return`${c} ${a}${l}`}async function o(e,t,n=0,s,i,l){if(n>=s)return[]
|
|
1628
|
-
try{const{fullPath:d}=
|
|
1629
|
-
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=
|
|
1636
|
+
try{const{fullPath:d}=I.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),g=[]
|
|
1637
|
+
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=I.validateAndNormalizePath(u,t),f=await y.default.stat(h),p=d.isFile()?w.default.extname(d.name).toLowerCase():""
|
|
1630
1638
|
let m
|
|
1631
1639
|
d.isFile()&&(m=await r(h,f.size,p))
|
|
1632
1640
|
const k={name:d.name,isDirectory:d.isDirectory(),depth:n,size:f.size,modified:f.mtime,extension:p,lineCount:m}
|
|
@@ -1635,8 +1643,8 @@ const o=[]
|
|
|
1635
1643
|
return e.forEach(((i,a)=>{const c=a===e.length-1,l=c?"\u2514\u2500\u2500 ":"\u251c\u2500\u2500 ",d=n(i,t),u=i.isDirectory?"/":""
|
|
1636
1644
|
if(o.push(`${r}${l}${d}${u}`),i.children&&i.children.length>0){const e=r+(c?" ":"\u2502 "),n=s(i.children,t,e)
|
|
1637
1645
|
n&&o.push(n)}})),o.join("\n")}function i(e){return e.toLocaleString()}async function a(e,t,n){const o={files:0,directories:0,lines:0}
|
|
1638
|
-
try{const{fullPath:n}=
|
|
1639
|
-
for(const n of s)try{const s=w.default.join(e,n.name).replace(/\\/g,"/"),{fullPath:i}=
|
|
1646
|
+
try{const{fullPath:n}=I.validateAndNormalizePath(e,t),s=await y.default.readdir(n,{withFileTypes:!0})
|
|
1647
|
+
for(const n of s)try{const s=w.default.join(e,n.name).replace(/\\/g,"/"),{fullPath:i}=I.validateAndNormalizePath(s,t)
|
|
1640
1648
|
if(n.isDirectory())o.directories+=1
|
|
1641
1649
|
else{o.files+=1
|
|
1642
1650
|
const e=await y.default.stat(i),t=w.default.extname(n.name).toLowerCase(),s=await r(i,e.size,t)
|
|
@@ -1662,27 +1670,27 @@ var t={}
|
|
|
1662
1670
|
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&g(t,e,r[n])
|
|
1663
1671
|
return f(t,e),t}),m=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1664
1672
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
|
|
1665
|
-
let g=
|
|
1666
|
-
|
|
1667
|
-
try{const f=
|
|
1673
|
+
let g=I.FileOperationPhase.VALIDATION
|
|
1674
|
+
I.FileOperationPhase.FILE_WRITE
|
|
1675
|
+
try{const f=I.validateArgs(e,k.ListDirectorySchema),{path:p,levels:m=1,sortBy:b="name"}=f
|
|
1668
1676
|
i.info("Listing directory: "+p)
|
|
1669
|
-
const{normalizedPath:C,fullPath:_}=
|
|
1670
|
-
g=
|
|
1677
|
+
const{normalizedPath:C,fullPath:_}=I.validateAndNormalizePath(p,t)
|
|
1678
|
+
g=I.FileOperationPhase.FILE_WRITE
|
|
1671
1679
|
try{if(!(await y.default.stat(_)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+p}],isError:!0}
|
|
1672
1680
|
await y.default.access(_,y.default.constants.R_OK)}catch(e){return e instanceof Error&&"ENOENT"===e.code?{content:[{type:"text",text:"Directory does not exist: "+p}],isError:!0}:e instanceof Error&&"EACCES"===e.code?{content:[{type:"text",text:"Directory not accessible: "+p}],isError:!0}:{content:[{type:"text",text:"Cannot access directory: "+p}],isError:!0}}let E,q
|
|
1673
|
-
if(m>1){i.info(`Building tree structure for: ${C} (levels: ${m}, sortBy: ${
|
|
1674
|
-
const e=await o(C,t,0,m,
|
|
1675
|
-
if(e.length>0){const t=s(e,
|
|
1681
|
+
if(m>1){i.info(`Building tree structure for: ${C} (levels: ${m}, sortBy: ${b})`)
|
|
1682
|
+
const e=await o(C,t,0,m,b,i)
|
|
1683
|
+
if(e.length>0){const t=s(e,b)
|
|
1676
1684
|
E=`Directory tree for ${C} (${m} levels):\n${l(c(e))}\n\n${t}`,q=d(e)}else E=`Directory ${C} is empty or inaccessible.`,q=0}else{const e=await y.default.readdir(_,{withFileTypes:!0}),o=[]
|
|
1677
|
-
for(const n of e)try{const e=w.default.join(C,n.name).replace(/\\/g,"/"),{fullPath:s}=
|
|
1685
|
+
for(const n of e)try{const e=w.default.join(C,n.name).replace(/\\/g,"/"),{fullPath:s}=I.validateAndNormalizePath(e,t),i=await y.default.stat(s),a=n.isFile()?w.default.extname(n.name).toLowerCase():""
|
|
1678
1686
|
let c
|
|
1679
|
-
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,
|
|
1687
|
+
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)))
|
|
1680
1688
|
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()
|
|
1681
1689
|
E+="\n\nBranch: "+(S?.branchName||"unknown")
|
|
1682
1690
|
const T=Date.now()-h
|
|
1683
1691
|
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
|
|
1684
1692
|
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}}}
|
|
1685
|
-
const y=m(t(1943)),w=m(t(6928)),k=t(6183),
|
|
1693
|
+
const y=m(t(1943)),w=m(t(6928)),k=t(6183),I=p(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},2601(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1686
1694
|
const r=t(6183),n=t(76)
|
|
1687
1695
|
exports.def={name:"create_task",description:"Create a new task under an existing request.",schema:r.CreateTaskSchema,annotations:{title:"Create Task",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleCreateTask)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer,t.cliOrigin)}}},2690(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.SessionMessageClient=void 0
|
|
1688
1696
|
const r=t(7645),n=t(2161)
|
|
@@ -1803,11 +1811,11 @@ const p=await Promise.all(f)
|
|
|
1803
1811
|
let m=""
|
|
1804
1812
|
if(t.getCurrentBranchContext)try{const e=await t.getCurrentBranchContext()
|
|
1805
1813
|
e.branch&&(m=`**Current Branch:** ${e.branch}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const y=p.filter((e=>e.success)).length,w=p.filter((e=>!e.success)).length,k=p.length
|
|
1806
|
-
let
|
|
1807
|
-
m&&(
|
|
1814
|
+
let I="## Read Files/Documents\n\n"
|
|
1815
|
+
m&&(I+=m),I+=`**Total Requests:** ${k} - **Successful:** ${y} - **Failed:** ${w}\n\n`
|
|
1808
1816
|
for(let e=0;e<p.length;e++){const t=p[e]
|
|
1809
|
-
"file"===t.type?
|
|
1810
|
-
return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:k,successfulReads:y,failedReads:w,success:
|
|
1817
|
+
"file"===t.type?I+=`File ${e+1}: ${t.path}\n`:(I+=`Document ${e+1}: ${t.documentId}`,t.filename&&(I+=` (${t.filename})`),I+="\n"),t.success?(I+="**Status:** Success\n",t.lineCount&&t.totalLines&&(I+=`Lines Read / Total Lines ${t.lineCount} / ${t.totalLines}\n`),t.originalRequest?.lines&&t.totalLines&&(I+=`**Lines:** ${t.originalRequest.lines}\n`),I+=`\n**Content:**\n\`\`\`\n${t.content}\n\`\`\`\n`):(I+="**Status:** Failed\n",I+=`**Error:** ${t.error}\n`),I+="\n"}const b=0===w
|
|
1818
|
+
return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:k,successfulReads:y,failedReads:w,success:b}),s.incrementCounter("read_files_total",1,{success:b}),{content:[{type:"text",text:I}],isError:!b}}catch(e){const t=Date.now()-a
|
|
1811
1819
|
return i.error("Read multiple files operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),s.incrementCounter("read_files_errors",1),{content:[{type:"text",text:"\u274c **Read Operation Failed:** "+(0,f.getErrorMessage)(e)}],isError:!0}}}
|
|
1812
1820
|
const l=c(t(1943)),d=t(6183),u=t(1569),h=a(t(5967)),g=t(9470),f=t(8824)},2968(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.TaskClient=void 0
|
|
1813
1821
|
const r=t(8824),n=t(7645),o=t(2161),s=t(5172)
|
|
@@ -1920,12 +1928,12 @@ d.info("Generating journal for request",{requestId:c})
|
|
|
1920
1928
|
const h=t.projectId
|
|
1921
1929
|
if(!h)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
|
|
1922
1930
|
o.setProjectId(h),d.info("Fetching request data, tasks, and file history in parallel")
|
|
1923
|
-
const g=o.getRequestClient(),f=o.getTaskClient(),p=o.getToolRecordClient(),[m,y,w]=await Promise.all([g.getRequest(c),f.listTasks({requestId:c}),p.getToolRecordsByRequestId(c).catch((e=>(d.warn("Failed to fetch tool records",{error:e+""}),[])))]),k=(0,s.extractDataFromResponse)(m,{logger:d,operationName:"getRequest",throwOnNoData:!0}),
|
|
1931
|
+
const g=o.getRequestClient(),f=o.getTaskClient(),p=o.getToolRecordClient(),[m,y,w]=await Promise.all([g.getRequest(c),f.listTasks({requestId:c}),p.getToolRecordsByRequestId(c).catch((e=>(d.warn("Failed to fetch tool records",{error:e+""}),[])))]),k=(0,s.extractDataFromResponse)(m,{logger:d,operationName:"getRequest",throwOnNoData:!0}),I="data"in k?k.data:k,b={id:I.id||c,title:I.title||"Unknown Request",description:I.description||"No description available",status:I.status||"unknown",type:I.type||"unknown",acceptanceCriteria:I.acceptanceCriteria||[],createdAt:I.createdAt||(new Date).toISOString(),updatedAt:I.updatedAt||(new Date).toISOString(),completedAt:I.completedAt},v=(0,s.extractDataFromResponse)(y,{logger:d,operationName:"listTasks",throwOnNoData:!1}),C=(Array.isArray(v)?v:"data"in v?v.data:[]).map((e=>({id:e.id,title:e.title||"Untitled Task",description:e.description||"No description",status:e.status||"unknown",createdAt:e.createdAt||(new Date).toISOString(),completedAt:e.metadata?.completedAt})))
|
|
1924
1932
|
d.info(`Fetched request, ${C.length} tasks, ${w.length} tool records`)
|
|
1925
1933
|
const _=await async function(e){const t=new Map,n=[],o=e.filter((e=>["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(e.type))).sort(((e,t)=>new Date(e.createdAt).getTime()-new Date(t.createdAt).getTime()))
|
|
1926
1934
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
1927
1935
|
n.push({type:e.type,timestamp:e.createdAt,comment:s,files:o,recordId:e.localId||e.id})
|
|
1928
|
-
for(const e of o)t.set(e,(t.get(e)||0)+1)}return{files:Array.from(t.entries()).map((([e,t])=>({path:e,operations:t}))).sort(((e,t)=>t.operations-e.operations)),operations:n}}(w),E={request:
|
|
1936
|
+
for(const e of o)t.set(e,(t.get(e)||0)+1)}return{files:Array.from(t.entries()).map((([e,t])=>({path:e,operations:t}))).sort(((e,t)=>t.operations-e.operations)),operations:n}}(w),E={request:b,tasks:C,fileChanges:{summary:{totalFiles:_.files.length,totalOperations:_.operations.length,files:_.files},operations:_.operations},suggestedFilename:`JOURNAL-${c}.md`,metadata:{projectId:h,requestId:c,generatedAt:(new Date).toISOString()}},q=`\u2705 **Request Data Fetched Successfully!**\n\n**Request:** ${b.title} (${c})\n**Status:** ${b.status}\n**Type:** ${b.type}\n**Tasks:** ${C.length}\n**Files Changed:** ${_.files.length}\n**File Operations:** ${_.operations.length}\n\n**Data Summary:**\n\`\`\`json\n${JSON.stringify(E,null,2)}\n\`\`\`\n\n**Next Steps:**\nWrite a **compact technical narrative** and save as \`JOURNAL-${c}.md\` using document_operations (create).\n\n**Style Guide:**\n- Be concise and direct - no fluff, repetition, or unnecessary elaboration\n- Write in narrative flow connecting the changes chronologically\n- Reference files with paths: "Modified \\\`src/tools/example.ts\\\` to add X..."\n- Include operation comments inline: ("comment: 'Fix bug in parser'")\n- **Link to tool records**: Use \\\`[RECORD:trec######]\\\` format to reference operations (e.g., "Modified parser.ts [RECORD:trec004123]")\n- Show key code changes with brief snippets where they add clarity\n- Explain what changed and why, skip obvious details\n- Focus on technical substance over structure\n\n**Example:** "Modified \\\`parser.ts\\\` [RECORD:trec004123] to handle edge cases (comment: 'Fix null handling'). Added \\\`if (!input) return null;\\\` check at line 45. Then updated \\\`validator.ts\\\` [RECORD:trec004124] to use the new parser behavior..."`
|
|
1929
1937
|
return u({tool:"generate_request_journal",success:!0}),l.incrementCounter("generate_request_journal_total",1,{success:!0}),{content:[{type:"text",text:q}]}}catch(e){return d.error("Error generating request journal",{error:e instanceof Error?e.stack:e+""}),u({tool:"generate_request_journal",success:!1}),l.incrementCounter("generate_request_journal_errors",1),{content:[{type:"text",text:"\u274c **Failed to generate journal:** "+(0,i.getErrorMessage)(e)}],isError:!0}}}
|
|
1930
1938
|
const n=t(9860),o=t(1569),s=t(2960),i=t(8824),a=o.z.object({requestId:o.z.string().regex(/^req[_\d].+$/,"Invalid request ID format")})},3064(e,exports,t){async function r(e,t,r,n){if(!r.lockOverrideManager||!r.configManager)return e
|
|
1931
1939
|
try{const n=await r.configManager.getEffectiveConfig(r.mainBasePath)
|
|
@@ -2032,7 +2040,7 @@ var t={}
|
|
|
2032
2040
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
2033
2041
|
return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2034
2042
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceStrings=async function(e,t,r,o,s,i,a,c){const y=i.child({tool:"replace_strings"}),w=Date.now()
|
|
2035
|
-
let k,b
|
|
2043
|
+
let k,I,b=u.FileOperationPhase.VALIDATION
|
|
2036
2044
|
const v={toolName:"replace-strings",operationName:"replace-string",fileOperationPhase:u.FileOperationPhase.STRING_REPLACEMENT,recordType:"replace-strings",metricsPrefix:"replace_strings",successMessage:"Successfully replaced strings across files and documents",failureMessage:"Failed to replace strings across files and documents"}
|
|
2037
2045
|
try{const i=u.validateArgs(e,d.ReplaceStringsSchema),{taskId:C,operations:_,comment:E}=i
|
|
2038
2046
|
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")
|
|
@@ -2045,7 +2053,7 @@ if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not ava
|
|
|
2045
2053
|
for(const e of S)M.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
|
|
2046
2054
|
if(M.length>0&&t.apiClient){const e=M.map((e=>e.documentId))
|
|
2047
2055
|
try{await(0,p.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}
|
|
2048
|
-
throw e}}
|
|
2056
|
+
throw e}}b=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_strings_phase",1,{phase:b})
|
|
2049
2057
|
const R=T.length>0?T[0].path:"document-operation",P=await u.validateTaskId(C,R,r,y,a,v.metricsPrefix),x=P?.requestId
|
|
2050
2058
|
let O=null
|
|
2051
2059
|
T.length>0&&x&&(O=await u.validateWorkItemStates(C,T[0].path,r,s,t,y,a,v.metricsPrefix))
|
|
@@ -2056,9 +2064,9 @@ if(!$.success){if($.isLockConflict)return{content:[{type:"text",text:"\u274c "+$
|
|
|
2056
2064
|
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})
|
|
2057
2065
|
for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
|
|
2058
2066
|
T[e]={...r,path:o,fullPath:s}}}if(M.length>0&&x)try{await(0,g.validateRequestStatusForDocumentOperation)(x,s,y,a,"replace-strings-document")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2059
|
-
throw e}
|
|
2067
|
+
throw e}b=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:b})
|
|
2060
2068
|
const D=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...M.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:A}=await u.createFileOperationRecords(C,x,t.projectId,v.recordType,R,{operationCount:_.length,fileOperations:T.length,documentOperations:M.length,operations:D,userComment:E},r,o,y,a,v.metricsPrefix,c)
|
|
2061
|
-
if(k=A,
|
|
2069
|
+
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")
|
|
2062
2070
|
const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:x,taskId:C,workspaceManager:t.workspaceManager},y,a)
|
|
2063
2071
|
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})
|
|
2064
2072
|
const F=[]
|
|
@@ -2071,8 +2079,8 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
|
|
|
2071
2079
|
r.filename=s?.filename
|
|
2072
2080
|
const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
|
|
2073
2081
|
r.replacements=c,r.successfulReplacements=c.filter((e=>e.success)).length,r.failedReplacements=c.filter((e=>!e.success)).length,a!==i?(await l.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),r.success=!0,L++,y.info("Document updated successfully",{documentId:e.documentId,filename:r.filename,successfulReplacements:r.successfulReplacements,failedReplacements:r.failedReplacements})):0===r.failedReplacements&&(r.success=!0),N+=r.failedReplacements}catch(t){r.error=(0,m.getErrorMessage)(t),r.failedReplacements=e.replacements.length,N+=r.failedReplacements,y.error("Document operation failed",{documentId:e.documentId,error:r.error})}F.push(r)}if(M.length>0)try{for(const e of M){const r=F.find((t=>t.documentId===e.documentId))
|
|
2074
|
-
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:
|
|
2075
|
-
try{await o.updateToolRecord(
|
|
2082
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const z=await u.handleMultiFileGitCommit(C,T,F,L,{operationType:"Replace strings",toolRecordId:I,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),B=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:H,failedOperations:W,totalSuccessfulChanges:U,overallSuccess:G,successfulFiles:V,failedFiles:J}=B
|
|
2083
|
+
try{await o.updateToolRecord(I,{metadata:{path:T.length>0?T[0].path:"document:"+M[0]?.documentId,status:G?"completed":"failed",error:G?void 0:W+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:D,totalSuccessfulReplacements:U,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:E,...T.length>0&&z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}},note:G?`String replacement completed: ${H}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`String replacement partially failed: ${W}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}u.formatMultiFileToolResponse("String Replacement",{successfulOperations:H,failedOperations:W,totalSuccessfulChanges:U,overallSuccess:G,successfulFiles:V,failedFiles:J},z,$)
|
|
2076
2084
|
let K="## String Replacement Results\n\n"
|
|
2077
2085
|
if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${H+W}\n`,K+=`- **Successful operations:** ${H}\n`,K+=`- **Failed operations:** ${W}\n`,K+=`- **Total replacements:** ${U} successful, ${N} failed\n\n`,z.success&&z.commitHash&&(K+="**Git Commit:**\n",K+=`- **Commit Hash:** ${z.commitHash.substring(0,8)}\n`,K+=`- **Files Committed:** ${z.filesCommitted.length}\n`,z.previousCommitHash&&(K+=`- **Previous Commit:** ${z.previousCommitHash.substring(0,8)}\n`),K+="\n"),$.lockAcquired&&$.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
|
|
2078
2086
|
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"
|
|
@@ -2081,7 +2089,7 @@ for(const e of F){if("file"===e.type?K+=`### File: ${e.path}\n`:(K+="### Documen
|
|
|
2081
2089
|
for(const t of e.replacements.filter((e=>!e.success)))K+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}K+="\n"}}M.length>0&&(K+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
2082
2090
|
const Y=Date.now()-w
|
|
2083
2091
|
return y.info("Replace strings operation completed",{duration:Y,success:G,totalOperations:F.length,successfulOperations:H,failedOperations:W}),a.incrementCounter("replace_strings_total",1,{success:G}),{content:[{type:"text",text:K}],isError:!G}}catch(t){const r=Date.now()-w
|
|
2084
|
-
if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:
|
|
2092
|
+
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}}}
|
|
2085
2093
|
const l=c(t(1943)),d=t(6183),u=a(t(5967)),h=t(9860),g=t(5003),f=t(7478),p=t(9949),m=t(8824)},3322(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
2086
2094
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
2087
2095
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
|
|
@@ -2256,18 +2264,18 @@ try{const a=u.validateArgs(e,d.GetFileInfoSchema),{path:h}=a
|
|
|
2256
2264
|
n.info("Getting file info: "+h)
|
|
2257
2265
|
const{normalizedPath:p,fullPath:m}=u.validateAndNormalizePath(h,t)
|
|
2258
2266
|
i=u.FileOperationPhase.FILE_WRITE
|
|
2259
|
-
try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+h)}const y=await c.default.stat(m),w=y.isFile()?l.default.extname(m).slice(1):"",k={path:p,type:y.isDirectory()?"directory":"file",size:y.size,sizeFormatted:(f=y.size,u.formatFileSize(f)),created:r(y.birthtime),modified:r(y.mtime),accessed:r(y.atime),permissions:(g=y.mode,(511&g).toString(8)),isDirectory:y.isDirectory(),isFile:y.isFile(),isSymbolicLink:y.isSymbolicLink(),extension:w},
|
|
2260
|
-
k.isFile&&w&&
|
|
2261
|
-
const
|
|
2262
|
-
return o.recordValue("get_file_info_time",
|
|
2267
|
+
try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+h)}const y=await c.default.stat(m),w=y.isFile()?l.default.extname(m).slice(1):"",k={path:p,type:y.isDirectory()?"directory":"file",size:y.size,sizeFormatted:(f=y.size,u.formatFileSize(f)),created:r(y.birthtime),modified:r(y.mtime),accessed:r(y.atime),permissions:(g=y.mode,(511&g).toString(8)),isDirectory:y.isDirectory(),isFile:y.isFile(),isSymbolicLink:y.isSymbolicLink(),extension:w},I=["File Information for: "+p,"Type: "+k.type,`Size: ${k.sizeFormatted} (${k.size} bytes)`,"Created: "+k.created,"Modified: "+k.modified,"Accessed: "+k.accessed,"Permissions: "+k.permissions,"Is Directory: "+k.isDirectory,"Is File: "+k.isFile,"Is Symbolic Link: "+k.isSymbolicLink]
|
|
2268
|
+
k.isFile&&w&&I.push("Extension: "+w)
|
|
2269
|
+
const b=Date.now()-s
|
|
2270
|
+
return o.recordValue("get_file_info_time",b),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+p,{type:k.type,size:k.size,time:b}),{content:[{type:"text",text:I.join("\n")}]}}catch(t){const r=Date.now()-s
|
|
2263
2271
|
return o.recordValue("get_file_info_time",r),o.incrementCounter("get_file_info_errors",1),n.error("Error getting file info:",{error:(0,h.getErrorMessage)(t),time:r}),u.handleFileOperationError(t,i,n,o,e,a)}var g,f}
|
|
2264
2272
|
const c=a(t(1943)),l=a(t(6928)),d=t(6183),u=i(t(5967)),h=t(8824)},3707(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,d,u,h,g,f){const p=h.child({tool:"quick_edit"}),m=Date.now()
|
|
2265
|
-
try{const y=u.getRequestClient(),w=u.getTaskClient(),k=u.getFileClient(),
|
|
2266
|
-
p.info("Starting quick_edit workflow",{title:
|
|
2273
|
+
try{const y=u.getRequestClient(),w=u.getTaskClient(),k=u.getFileClient(),I=u.getToolRecordClient(),{title:b,description:v,...C}=e,_=e.comment||b
|
|
2274
|
+
p.info("Starting quick_edit workflow",{title:b,operationType:t})
|
|
2267
2275
|
let E=!1
|
|
2268
2276
|
try{const e=await y.listRequests({limit:2,sortBy:"created_at",sortDirection:"desc"})
|
|
2269
2277
|
e&&2===e.length&&e.every((e=>"quick-edit"===e.type))&&(E=!0,p.info("Detected two consecutive quick-edits, will recommend normal request"))}catch(e){p.warn("Could not check recent requests for recommendation",{error:e})}p.debug("Creating quick_edit request")
|
|
2270
|
-
const q=await y.createRequest({title:
|
|
2278
|
+
const q=await y.createRequest({title:b,description:v,type:"quick-edit",acceptanceCriteria:["Quick change completed successfully"]})
|
|
2271
2279
|
if(!q||!q.id)throw Error("Failed to create request")
|
|
2272
2280
|
const S=q.id
|
|
2273
2281
|
let T
|
|
@@ -2275,24 +2283,24 @@ p.info("Created request",{requestId:S})
|
|
|
2275
2283
|
try{if(p.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)
|
|
2276
2284
|
e.userChangesCommitted?p.info("Committed user changes to main before quick-edit branch creation",{requestId:S,commitHash:e.commitHash?.substring(0,8)}):p.debug("No uncommitted changes found, proceeding with quick-edit")}catch(e){p.warn("Failed to commit user changes before quick-edit, proceeding anyway",{requestId:S,error:e instanceof Error?e.message:e+""})}else p.debug("No git instance available, skipping uncommitted changes check")
|
|
2277
2285
|
p.debug("Creating task")
|
|
2278
|
-
const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+
|
|
2286
|
+
const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+b})
|
|
2279
2287
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2280
2288
|
let v
|
|
2281
|
-
if(T=e.id,p.info("Created task",{taskId:T}),p.debug("Executing file operation",{operationType:t}),"write"===t)v=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,k,w,
|
|
2282
|
-
else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,
|
|
2289
|
+
if(T=e.id,p.info("Created task",{taskId:T}),p.debug("Executing file operation",{operationType:t}),"write"===t)v=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,k,w,I,y,h,g,f)
|
|
2290
|
+
else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,I,y,h,g,f)
|
|
2283
2291
|
else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
|
|
2284
|
-
v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||
|
|
2292
|
+
v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||b},d,w,I,y,u,h,g,f)}if(v.isError){p.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
|
|
2285
2293
|
try{await w.updateTaskStatus(T,"canceled"),p.info("Canceled task after operation failure",{taskId:T})}catch(e){p.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),p.info("Canceled request after operation failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),p.info("Cleaned up branch/worktree after operation failure",{requestId:S}))}catch(e){p.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${v.content[0].text}\n\nThe request (${S}) and task have been canceled and cleaned up.`}],isError:!0}}const q=v.content[0].text,M=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
|
|
2286
2294
|
M?p.warn("File operation completed with partial failures",{requestId:S}):p.info("File operation completed successfully"),p.debug("Completing task")
|
|
2287
|
-
try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${
|
|
2295
|
+
try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${b}${M?" (partial success)":""}`},d,u,h,g),p.info("Task completed successfully",{taskId:T})}catch(e){p.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})
|
|
2288
2296
|
try{await w.updateTaskStatus(T,"completed"),p.info("Task completed via direct updateTaskStatus call",{taskId:T})}catch(e){return p.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}}}p.debug("Completing request")
|
|
2289
|
-
const R=M?`Quick change completed with partial success: ${
|
|
2297
|
+
const R=M?`Quick change completed with partial success: ${b}. Some replacements failed - see details below.`:"Quick change completed: "+b,P=M?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
|
|
2290
2298
|
let x=!1
|
|
2291
2299
|
try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:R,acceptanceEvidence:[{evidence:P}],testVerification:void 0},d,u,h,g,f)
|
|
2292
2300
|
if(e.isError)p.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text})
|
|
2293
2301
|
else{try{await y.updateRequest(S,{status:"completed",completionSummary:R}),p.info("Request finalized to completed",{requestId:S})}catch(e){p.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:S,error:(0,l.getErrorMessage)(e)})}x=!0,p.info("Request completed successfully",{requestId:S})}}catch(e){p.error("Request completion threw exception, attempting direct completion",{requestId:S,error:e instanceof Error?e.message:e+""})}if(!x)try{p.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:R}),x=!0,p.info("Request completed successfully via direct API call",{requestId:S})}catch(e){return p.error("Direct request completion also failed",{requestId:S,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${S}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const O=Date.now()-m
|
|
2294
2302
|
let j
|
|
2295
|
-
return p.info("Quick fix completed",{requestId:S,duration:O,hasPartialFailure:M}),j=M?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${
|
|
2303
|
+
return p.info("Quick fix completed",{requestId:S,duration:O,hasPartialFailure:M}),j=M?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${O}ms\n**Status:** Some operations succeeded, some failed\n\nThe successful changes have been applied and automatically merged to main.\n**Active branch:** main\n\n**\u26a0\ufe0f Note:** This quick-fix had partial failures. See operation details below:\n\n`+q:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${O}ms\n\nThe change has been applied and automatically merged to main.\n**Active branch:** main`+(q.match(/\[RECORD:trec\d{6}\]/)?.[0]?"\n"+q.match(/\[RECORD:trec\d{6}\]/)?.[0]:""),E&&(j+="\n\n\u{1f4a1} **Recommendation:** You've created several quick-edits in a row. For better traceability and organization, consider creating a proper feature or bugfix request with multiple tasks for your next change."),{content:[{type:"text",text:j}]}}catch(e){if(p.error("Quick change workflow failed after request creation, cleaning up",{requestId:S,error:(0,l.getErrorMessage)(e)}),T)try{await w.updateTaskStatus(T,"canceled"),p.info("Canceled task after workflow failure",{taskId:T})}catch(e){p.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),p.info("Canceled request after workflow failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),p.info("Cleaned up branch/worktree after workflow failure",{requestId:S}))}catch(e){p.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
|
|
2296
2304
|
return p.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}}}
|
|
2297
2305
|
const r=t(9860),n=t(4079),o=t(9442),s=t(7684),i=t(355),a=t(5715),c=t(7478),l=t(8824)},3807(module){module.exports=require("simple-git")},3895(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.AuthenticationManager=void 0
|
|
2298
2306
|
const r=t(6848)
|
|
@@ -2352,8 +2360,8 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2352
2360
|
var t={}
|
|
2353
2361
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2354
2362
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2355
|
-
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"),
|
|
2356
|
-
let
|
|
2363
|
+
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()
|
|
2364
|
+
let b,v,C=d.FileOperationPhase.VALIDATION
|
|
2357
2365
|
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"}
|
|
2358
2366
|
try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:p,documentId:E,content:q,format:S,append:T,comment:M}=r,R=!!E,P=!!p
|
|
2359
2367
|
w.info("Writing content to "+(R?"document":"file"),{taskId:i,filePath:P?p:void 0,documentId:R?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:T,comment:M})
|
|
@@ -2377,7 +2385,7 @@ try{await c.default.access(O),A=!0}catch{A=!1,D=!0}w.debug("Path validated with
|
|
|
2377
2385
|
throw e}C=d.FileOperationPhase.RECORD_CREATION,m.incrementCounter("write_file_phase",1,{phase:C})
|
|
2378
2386
|
const{toolRecordId:U}=await d.createFileOperationRecords(i,z,t.projectId,_.recordType,N,{operationType:R?"document":"file",documentId:R?E:void 0,documentFilename:j,filePath:P?x:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S||"text",append:T||!1,wasFileCreated:!A,userComment:M},n,o,w,m,_.metricsPrefix,y)
|
|
2379
2387
|
let G
|
|
2380
|
-
if(
|
|
2388
|
+
if(b=U,v=U,C=_.fileOperationPhase,m.incrementCounter("write_file_phase",1,{phase:C}),"json"===S)if("string"==typeof q)try{JSON.parse(q),G=q}catch(e){throw new u.ValidationError("Content is not valid JSON")}else G=JSON.stringify(q,null,2)
|
|
2381
2389
|
else G="string"==typeof q?q:JSON.stringify(q,null,2)
|
|
2382
2390
|
let V=G
|
|
2383
2391
|
if(P&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
|
|
@@ -2388,10 +2396,10 @@ if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile($,V,"utf8")
|
|
|
2388
2396
|
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
|
|
2389
2397
|
if(P){if(C=d.FileOperationPhase.GIT_COMMIT,m.incrementCounter("write_file_phase",1,{phase:C}),t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
|
|
2390
2398
|
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)
|
|
2391
|
-
K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:x,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:P?x:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:T&&A,operationType:R?"document":"file",processingTime:Date.now()-
|
|
2399
|
+
K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:x,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:P?x:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:T&&A,operationType:R?"document":"file",processingTime:Date.now()-I,userComment:M,...P&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(R?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${D?"Created":T?"Appended to":"Updated"} ${R?`document ${E}${j?` (${j})`:""}`:"file "+x}**\n`
|
|
2392
2400
|
Z+=`**Content Length:** ${V.length} characters\n`,P&&Y&&(Z+=`**Branch:** ${Y}\n`),W.lockAcquired&&W.lockedRequestId&&(Z+=`**Locked request:** ${W.lockedRequestId}\n`),P&&K&&(Z+=`**Commit Hash:** ${K.substring(0,8)}\n`,Q&&(Z+=`**Previous Commit:** ${Q.substring(0,8)}\n`)),v&&(Z+=`[RECORD:${v}]\n`),R&&(Z+=`\n**Document Update:** The document content has been updated and synced back to the tracking system. You can continue editing using other file modification tools with documentId \`${E}\`.`)
|
|
2393
2401
|
const X=Date.now()
|
|
2394
|
-
return w.info("Write operation completed successfully",{duration:X-
|
|
2402
|
+
return w.info("Write operation completed successfully",{duration:X-I,path:P?x:"document:"+E,contentLength:V.length,wasCreated:D}),k({tool:"write_file",success:!0}),m.incrementCounter("write_file_total",1,{success:!0}),t.workspaceManager?.largeFileWarning&&(Z+=t.workspaceManager.largeFileWarning,t.workspaceManager.largeFileWarning=""),{content:[{type:"text",text:Z}]}}catch(t){const r=Date.now()-I
|
|
2395
2403
|
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,p.getErrorMessage)(t),phase:C,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,p.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,p.getErrorMessage)(t)}],isError:!0}}}
|
|
2396
2404
|
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),f=t(9949),p=t(8824)},4139(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ALCHEMY_DIR_NAME=exports.TOKEN_DIR_NAME=void 0,exports.TOKEN_DIR_NAME="alchemy-key",exports.ALCHEMY_DIR_NAME=".alchemy_lab"},4165(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2397
2405
|
const r=t(6183),n=t(4648)
|
|
@@ -2562,10 +2570,10 @@ try{let o
|
|
|
2562
2570
|
try{o=i.FileRecoverSchema.parse(e)}catch(t){if(t instanceof a.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
|
|
2563
2571
|
return f.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{taskId:p,path:y,commitHash:w,createBackup:k}=o
|
|
2564
2572
|
return f.info("Recovering file to previous version",{taskId:p,filePath:y,commitHash:w,createBackup:k}),await async function(e,t,r,n,o,s,i,a,g,f,p){let m
|
|
2565
|
-
try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),k=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:
|
|
2566
|
-
m=
|
|
2567
|
-
let
|
|
2568
|
-
try{await l.access(w),v=!0,n&&(
|
|
2573
|
+
try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),k=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:I}=await d.createFileOperationRecords(e,k?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),i,a,g,"file-recover",p)
|
|
2574
|
+
m=I
|
|
2575
|
+
let b,v=!1
|
|
2576
|
+
try{await l.access(w),v=!0,n&&(b=`${w}.backup-${(new Date).toISOString().replace(/[:.]/g,"-")}`,await l.copyFile(w,b),a.info("Created backup",{originalPath:w,backupPath:b}))}catch{v=!1}const C=o.git
|
|
2569
2577
|
if(!C)throw Error("Git is not available")
|
|
2570
2578
|
if(!(await(0,u.validateCommitHash)(C,r,a,"file-recover")).valid)throw Error(`Commit hash '${r}' is invalid or not found`)
|
|
2571
2579
|
let _
|
|
@@ -2574,9 +2582,9 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
|
|
|
2574
2582
|
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await l.writeFile(w,_,"utf8")
|
|
2575
2583
|
let E={}
|
|
2576
2584
|
try{const t=`Recover ${y} from ${r.substring(0,8)}`
|
|
2577
|
-
E=await d.commitToGit(e,y,m,m,t,o,a,g,"file-recover"),a.info("Recovery committed via shared utility",{path:y,sourceCommitHash:r,newCommitHash:E.commitHash?.substring(0,8),commitMessage:t})}catch(e){a.warn("Failed to commit recovery via shared utility",{error:e})}if(m)try{await i.updateToolRecord(m,{metadata:{path:y,status:"completed",recoveredLength:_.length,hadBackup:n&&v,backupPath:
|
|
2585
|
+
E=await d.commitToGit(e,y,m,m,t,o,a,g,"file-recover"),a.info("Recovery committed via shared utility",{path:y,sourceCommitHash:r,newCommitHash:E.commitHash?.substring(0,8),commitMessage:t})}catch(e){a.warn("Failed to commit recovery via shared utility",{error:e})}if(m)try{await i.updateToolRecord(m,{metadata:{path:y,status:"completed",recoveredLength:_.length,hadBackup:n&&v,backupPath:b,wasFileCreated:!v,processingTime:Date.now()-f,...E.commitHash&&{commitHash:E.commitHash,previousCommitHash:E.previousCommitHash||void 0}},note:"File recovered successfully from "+r.substring(0,8)})}catch(e){a.warn("Failed to update tool record",{recordError:e})}const q=v?"recovered":"created from recovery"
|
|
2578
2586
|
let S=`\u2705 **File ${q.charAt(0).toUpperCase()+q.slice(1)} Successfully**\n\n`
|
|
2579
|
-
return S+=`**File:** ${y}\n`,S+=`**Recovered from:** ${r.substring(0,8)}\n`,S+=`**Content length:** ${_.length} characters\n`,n&&v&&
|
|
2587
|
+
return S+=`**File:** ${y}\n`,S+=`**Recovered from:** ${r.substring(0,8)}\n`,S+=`**Content length:** ${_.length} characters\n`,n&&v&&b&&(S+=`**Backup created:** ${c.basename(b)}\n`),S+="**Git status:** Recovery committed\n",S+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",a.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-f}),g.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:S}]}}catch(e){throw e}}(p,y,w,k,t,r,n,f,s,m,g)}catch(e){const t=Date.now()-m
|
|
2580
2588
|
return f.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),p({tool:"file_recover",success:!1}),s.incrementCounter("file_recover_errors",1),{content:[{type:"text",text:"\u274c **Recovery Failed:** "+(0,h.getErrorMessage)(e)}],isError:!0}}}
|
|
2581
2589
|
const i=t(6183),a=t(1569),c=s(t(6928)),l=s(t(1943)),d=s(t(5967)),u=t(3922),h=t(8824)},4648(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,t,u,h,g,f){const p=h.child({tool:"request_operations"})
|
|
2582
2590
|
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)
|
|
@@ -2724,15 +2732,15 @@ if(/^\d+$/.test(e)){const t=parseInt(e,10)
|
|
|
2724
2732
|
return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
|
|
2725
2733
|
if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
|
|
2726
2734
|
if(e.match(/^(\d+(?:,\d+)+)$/)){const t=e.split(",").map((e=>parseInt(e,10)))
|
|
2727
|
-
return{start:Math.min(...t),end:Math.max(...t)}}return null}(f),
|
|
2728
|
-
let
|
|
2729
|
-
k&&
|
|
2735
|
+
return{start:Math.min(...t),end:Math.max(...t)}}return null}(f),I=["blame","--porcelain"]
|
|
2736
|
+
let b
|
|
2737
|
+
k&&I.push(`-L${k.start},${k.end}`),p&&I.push(p),I.push("--",w),c.debug("Executing git blame",{args:I})
|
|
2730
2738
|
try{if(!t.git)throw Error("Git context not available")
|
|
2731
|
-
|
|
2739
|
+
b=await t.git.raw(I)}catch(e){const t=(0,h.getErrorMessage)(e)
|
|
2732
2740
|
return c.error("Git blame failed",{error:t}),{content:[{type:"text",text:"\u274c Git blame failed: "+t}],isError:!0}}const v=function(e){const t=[],r=e.split("\n")
|
|
2733
2741
|
let n="",o="",s="",i=0,a=0,c=new Map
|
|
2734
2742
|
for(let e=0;e<r.length;e++){const l=r[e],d=l.match(/^([0-9a-f]{40})\s+\d+\s+(\d+)/)
|
|
2735
|
-
d?(n=d[1],a=parseInt(d[2],10)):l.startsWith("author ")?o=l.substring(7):l.startsWith("author-mail ")?s=l.substring(12).replace(/[<>]/g,""):l.startsWith("author-time ")?i=parseInt(l.substring(12),10):l.startsWith("summary ")?c.set(n,l.substring(8)):l.startsWith("\t")&&t.push({lineNumber:a,commitHash:n,author:o,authorEmail:s,timestamp:i,content:l.substring(1),commitMessage:c.get(n)})}return t}(
|
|
2743
|
+
d?(n=d[1],a=parseInt(d[2],10)):l.startsWith("author ")?o=l.substring(7):l.startsWith("author-mail ")?s=l.substring(12).replace(/[<>]/g,""):l.startsWith("author-time ")?i=parseInt(l.substring(12),10):l.startsWith("summary ")?c.set(n,l.substring(8)):l.startsWith("\t")&&t.push({lineNumber:a,commitHash:n,author:o,authorEmail:s,timestamp:i,content:l.substring(1),commitMessage:c.get(n)})}return t}(b)
|
|
2736
2744
|
if(0===v.length)return{content:[{type:"text",text:"\u274c No blame information found for "+w}],isError:!0}
|
|
2737
2745
|
const C=function(e){if(0===e.length)return[]
|
|
2738
2746
|
const t=[]
|
|
@@ -2968,10 +2976,10 @@ const m=g.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_
|
|
|
2968
2976
|
m.forEach((e=>{const t=e.status||"unverified"
|
|
2969
2977
|
t in y&&y[t]++}))
|
|
2970
2978
|
let w=g.testVerification||null
|
|
2971
|
-
const k=g.title,
|
|
2972
|
-
let
|
|
2973
|
-
return
|
|
2974
|
-
|
|
2979
|
+
const k=g.title,I=g.type
|
|
2980
|
+
let b=`# ${"feature"===I?"Feature":"quick-edit"===I?"Quick Edit":"Bug Fix"} Request: ${k} (${t})\nStatus: ${g.status}\nCreated: ${new Date(g.createdAt).toLocaleString()}\nUpdated: ${new Date(g.updatedAt).toLocaleString()}\n\n## Description\n${g.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${p.completed}/${p.total} completed (${Math.round(p.completed/p.total*100)||0}%)\n- Acceptance Criteria: ${y.verified}/${y.total} verified (${Math.round(y.verified/y.total*100)||0}%)\n`
|
|
2981
|
+
return b+=`\n## Task Status\n- Pending: ${p.pending}\n- In Progress: ${p.in_progress}\n- Blocked: ${p.blocked}\n- Ready for Review: ${p.ready_for_review}\n- Completed: ${p.completed}\n- Reverted: ${p.reverted}\n`,b+="\n## Tasks\n",0===f.length?b+="No tasks found for this request.\n":f.forEach((e=>{b+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${f.length} tasks`),b+="\n## Acceptance Criteria\n",b+=(0,i.formatCriteriaWithHashes)(m)+"\n","ready_for_review"===g.status&&m.some((e=>"verified"!==e.status))&&(b+="\n> **Status: ready_for_review** \u2014 Use the merge operation to verify criteria and merge to main.\n"),w&&(b+=`\n## Test Coverage\n- Test Cases: ${w.totalTestCases||0}\n- Criteria Tested: ${w.criteriaTestedCount||0}/${y.total}\n`,w.criterionCoverage&&Array.isArray(w.criterionCoverage)&&(b+="\n### Detailed Test Coverage:\n",w.criterionCoverage.forEach((e=>{b+=`- Criterion ${e.criterionId}: ${e.coverage} coverage\n`})))),g.recentActivity&&Array.isArray(g.recentActivity)&&(b+="\n## Recent Activity\n",g.recentActivity.slice(0,5).forEach((e=>{const t=new Date(e.timestamp).toLocaleString()
|
|
2982
|
+
b+=`- ${t}: ${e.description}\n`}))),u({success:!0}),{content:[{type:"text",text:b}]}}catch(t){return d.error("Error getting request information",{args:e,error:t instanceof Error?t.stack:t+""}),u({success:!1,error:t instanceof Error?t.name:"unknown"}),t instanceof n.ConnectionError?{content:[{type:"text",text:"Unable to get request information: Connection to the server failed. Please check your network connection and try again."}],isError:!0}:{content:[{type:"text",text:"Error getting request information: "+(0,s.getErrorMessage)(t)}],isError:!0}}}
|
|
2975
2983
|
const r=t(9860),n=t(5674),o=t(2960),s=t(8824),i=t(5454)},5454(e,exports){function t(e,t){let r=0
|
|
2976
2984
|
for(let t=0;t<e.length;t++)r=(r<<5)-r+e.charCodeAt(t)|0
|
|
2977
2985
|
return`${t+1}${String.fromCharCode(97+Math.abs(r)%26)}`}function r(e){const r=new Map
|
|
@@ -3106,8 +3114,8 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
|
3106
3114
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3107
3115
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDeleteFiles=async function(e,t,r,n,o,s){const i=n.child({tool:"delete_files"}),m=Date.now()
|
|
3108
3116
|
let y,w,k=l.FileOperationPhase.VALIDATION
|
|
3109
|
-
const
|
|
3110
|
-
try{const n=r.getTaskClient(),u=r.getToolRecordClient(),
|
|
3117
|
+
const I={toolName:"delete-files",operationName:"delete",fileOperationPhase:l.FileOperationPhase.FILE_WRITE,recordType:"delete-files",metricsPrefix:"delete_files",successMessage:"Successfully deleted files",failureMessage:"Failed to delete files"}
|
|
3118
|
+
try{const n=r.getTaskClient(),u=r.getToolRecordClient(),b=r.getRequestClient(),v=l.validateArgs(e,c.DeleteFilesSchema),{taskId:C,paths:_,operations:E,comment:q}=v
|
|
3111
3119
|
let S=[]
|
|
3112
3120
|
if(_)S=_.map((e=>({type:"file",target:e})))
|
|
3113
3121
|
else{if(!E)throw Error("Either paths or operations must be specified")
|
|
@@ -3115,22 +3123,22 @@ S=E.map((e=>{if(e.path)return{type:"file",target:e.path}
|
|
|
3115
3123
|
if(e.documentId)return{type:"document",target:e.documentId}
|
|
3116
3124
|
throw Error("Invalid operation: neither path nor documentId specified")}))}if(0===S.length)throw Error("At least one file or document must be specified for deletion")
|
|
3117
3125
|
const T=S.filter((e=>"file"===e.type)),M=S.filter((e=>"document"===e.type)),R=S.length
|
|
3118
|
-
i.info("Starting mixed file and document deletion operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:M.length,comment:q}),l.validateTaskIdFormat(C,i,o,
|
|
3126
|
+
i.info("Starting mixed file and document deletion operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:M.length,comment:q}),l.validateTaskIdFormat(C,i,o,I.metricsPrefix)
|
|
3119
3127
|
const P=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3120
3128
|
i.info("Initial branch context",{initialBranch:P.branch,initialRequestId:P.requestId,isMain:P.isMain})
|
|
3121
3129
|
const x=[]
|
|
3122
3130
|
for(const e of T){const{normalizedPath:r,fullPath:n}=l.validateAndNormalizePath(e.target,t)
|
|
3123
3131
|
x.push({normalized:r,full:n})}k=l.FileOperationPhase.TASK_VALIDATION,o.incrementCounter("delete_files_phase",1,{phase:k})
|
|
3124
|
-
const O=x.length>0?x[0].normalized:"document_operations",j=await l.validateTaskId(C,O,n,i,o,
|
|
3132
|
+
const O=x.length>0?x[0].normalized:"document_operations",j=await l.validateTaskId(C,O,n,i,o,I.metricsPrefix),$=j?.requestId,D=await l.validateWorkItemStates(C,O,n,b,t,i,o,I.metricsPrefix),A=await l.autoPromoteTaskStatus(C,j.status,$,D.request?.status,O,n,b,i,o,I.metricsPrefix)
|
|
3125
3133
|
A.taskPromoted&&i.info(`Auto-promoted task ${C} (${j.title||"Untitled"}) to in_progress for mixed operations`,{taskId:C,taskTitle:j.title,previousStatus:j.status,newStatus:A.newTaskStatus,totalOperations:S.length,fileOperations:T.length,documentOperations:M.length}),A.requestPromoted&&i.info(`Auto-promoted request ${$} to in_progress for file operations`,{requestId:$,previousStatus:D.request?.status,newStatus:A.newRequestStatus,triggeringTaskId:C})
|
|
3126
|
-
const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:$,context:t,operation:"delete-files",logger:i,metrics:o,metricsPrefix:
|
|
3134
|
+
const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:$,context:t,operation:"delete-files",logger:i,metrics:o,metricsPrefix:I.metricsPrefix})
|
|
3127
3135
|
if(!F.success){if(F.isLockConflict)return{content:[{type:"text",text:"\u274c "+F.error}],isError:!0}
|
|
3128
3136
|
throw Error(F.error)}let N={hadUserMods:!1,userModsCommitHash:void 0}
|
|
3129
3137
|
if(t.git)try{i.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
|
|
3130
3138
|
const e=await(0,h.commitUserChangesBeforeToolOperation)(t.git,"delete-files",{requestId:$,taskId:C,workspaceManager:t.workspaceManager},i,o)
|
|
3131
3139
|
e.userChangesCommitted&&(i.debug("[DELETE-FILES] User changes committed before mixed delete operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),i.info("User changes committed before mixed delete-files operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:M.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),N={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){i.debug("[DELETE-FILES] Pre-tool commit failed, continuing with mixed delete operations",{error:e instanceof Error?e.message:e+""}),i.warn("Pre-tool user changes commit failed, continuing with mixed delete operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:M.length,error:e instanceof Error?e.message:e+""})}i.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:S.length,fileDeletes:T.length,documentDeletes:M.length}),k=l.FileOperationPhase.RECORD_CREATION,o.incrementCounter("delete_files_phase",1,{phase:k})
|
|
3132
|
-
const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,$,t.projectId,
|
|
3133
|
-
y=L,w=L,k=
|
|
3140
|
+
const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,$,t.projectId,I.recordType,O,{totalOperations:S.length,fileOperations:T.length,documentOperations:M.length,filePaths:x.map((e=>e.normalized)),documentIds:M.map((e=>e.target)),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},n,u,i,o,I.metricsPrefix,s)
|
|
3141
|
+
y=L,w=L,k=I.fileOperationPhase,o.incrementCounter("delete_files_phase",1,{phase:k})
|
|
3134
3142
|
const B=[]
|
|
3135
3143
|
let H=0
|
|
3136
3144
|
M.length>0&&r.setProjectId(t.projectId)
|
|
@@ -3139,7 +3147,7 @@ try{try{await a.default.access(t.full)}catch(e){throw Error("File not found: "+t
|
|
|
3139
3147
|
await a.default.unlink(t.full),r.success=!0,H++,i.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,p.getErrorMessage)(e),i.warn("Failed to delete file "+t.normalized,{error:r.error})}B.push(r)}const W=M.length>0?r.getDocumentClient():null
|
|
3140
3148
|
for(const e of M){const t=e.target,n={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3141
3149
|
try{let e
|
|
3142
|
-
try{if(e=await W.getDocument(t),n.filename=e.filename,i.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,g.validateRequestStatusForDocumentOperation)(e.requestId,
|
|
3150
|
+
try{if(e=await W.getDocument(t),n.filename=e.filename,i.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,g.validateRequestStatusForDocumentOperation)(e.requestId,b,i,o,"delete-document")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
|
|
3143
3151
|
throw e}try{await(0,f.ensureDocumentNotLocked)(t,r,i,o,"delete-document-archive")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
|
|
3144
3152
|
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,p.getErrorMessage)(e)}`)}const s=await W.archiveDocument(t)
|
|
3145
3153
|
n.success=!0,n.filename=s.filename,H++,i.info("Document archived successfully",{documentId:s.id,filename:s.filename,archivedAt:s.archived_at})}catch(e){n.error=(0,p.getErrorMessage)(e),i.warn("Failed to delete document "+t,{error:n.error})}B.push(n)}const U=Date.now()-m
|
|
@@ -3148,9 +3156,9 @@ let G=null
|
|
|
3148
3156
|
if(H>0){k=l.FileOperationPhase.GIT_COMMIT,o.incrementCounter("delete_files_phase",1,{phase:k})
|
|
3149
3157
|
const e=B.filter((e=>e.success)),r=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
|
|
3150
3158
|
let s
|
|
3151
|
-
s=r>0&&n>0?`Delete ${r} files and ${n} documents - ${q}`:r>0?1===r?"Delete file - "+q:`Delete ${r} files - ${q}`:1===n?"Delete document - "+q:`Delete ${n} documents - ${q}`,G=await l.commitToGit(C,O,L,z,s,t,i,o,
|
|
3159
|
+
s=r>0&&n>0?`Delete ${r} files and ${n} documents - ${q}`:r>0?1===r?"Delete file - "+q:`Delete ${r} files - ${q}`:1===n?"Delete document - "+q:`Delete ${n} documents - ${q}`,G=await l.commitToGit(C,O,L,z,s,t,i,o,I.metricsPrefix)}k=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:k})
|
|
3152
3160
|
const V=B.filter((e=>e.success)),J=B.filter((e=>!e.success))
|
|
3153
|
-
await l.updateFileOperationRecords(C,y,w,O,
|
|
3161
|
+
await l.updateFileOperationRecords(C,y,w,O,I.recordType,H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,{status:H===R?"completed":"partial_success",commitHash:G?.commitHash,previousCommitHash:G?.previousCommitHash,totalOperations:R,fileOperations:T.length,documentOperations:M.length,successCount:H,failureCount:R-H,successfulOperations:V.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:J.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,n,u,i,o,I.metricsPrefix)
|
|
3154
3162
|
const K=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3155
3163
|
let Y=""
|
|
3156
3164
|
if(H===R){const e=V.filter((e=>"file"===e.type)).length,t=V.filter((e=>"document"===e.type)).length
|
|
@@ -3161,7 +3169,7 @@ return G?.commitHash&&(Y+="\nCommit: "+G.commitHash.substring(0,8)),K.requestId&
|
|
|
3161
3169
|
await o.createToolRecord({...s?{}:{taskId:e.taskId},projectId:t.projectId,type:"delete-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment,error:(0,p.getErrorMessage)(n),errorDetails:n instanceof Error?n.stack:n+"",phase:k,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,p.getErrorMessage)(n)})}catch(t){i.error("Failed to create failure record for delete-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0})}const s=Date.now()-m
|
|
3162
3170
|
if(o.recordValue("delete_files_time",s),o.incrementCounter("delete_files_errors",1),i.error("Error in delete-files operation:",{error:(0,p.getErrorMessage)(n),time:s}),(y||w)&&e.taskId){k=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
3163
3171
|
try{const t=r.getTaskClient(),s=r.getToolRecordClient()
|
|
3164
|
-
await l.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",
|
|
3172
|
+
await l.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",I.recordType,"Failed to delete operations",{status:"failed",error:(0,p.getErrorMessage)(n),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment},"Failed to delete operations",t,s,i,o,I.metricsPrefix)}catch(t){i.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(n,k,i,o,e,I)}}
|
|
3165
3173
|
const a=i(t(1943)),c=t(6183),l=s(t(5967)),d=t(9860),u=t(1569),h=t(7478),g=t(5003),f=t(9949),p=t(8824)},5997(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3166
3174
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3167
3175
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
|
|
@@ -3249,7 +3257,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistO
|
|
|
3249
3257
|
try{if(!e?.operation&&e&&(e.prompt&&!e.sessionId?e.operation="delegate":e.prompt&&e.sessionId?e.operation="follow-up":e.sessionId&&(e.operation="check-status")),e?.followUp&&"string"==typeof e.followUp)try{e.followUp=JSON.parse(e.followUp)}catch{}if(e?.delegate&&"string"==typeof e.delegate)try{e.delegate=JSON.parse(e.delegate)}catch{}if("string"==typeof e?.delegate){const t=e.delegate
|
|
3250
3258
|
e.delegate={prompt:e.prompt||t,description:e.description||t.slice(0,60),specialization:e.specialization||"general",requestId:e.requestId},e.operation=e.operation||"delegate",delete e.prompt,delete e.description,delete e.specialization,delete e.requestId}"follow-up"===e?.operation&&e?.prompt&&!e?.followUp&&(e.followUp={prompt:e.prompt,specialization:e.specialization},delete e.prompt,e.specialization&&delete e.specialization),"delegate"===e?.operation&&e?.prompt&&!e?.delegate&&(e.delegate={prompt:e.prompt,description:e.description||e.prompt.slice(0,60),specialization:e.specialization||"general",requestId:e.requestId},delete e.prompt,delete e.description,delete e.specialization,delete e.requestId)
|
|
3251
3259
|
const n=c.validateArgs(e,a.SpecialistOpsSchema),{operation:w,sessionId:k}=n
|
|
3252
|
-
let
|
|
3260
|
+
let I
|
|
3253
3261
|
switch(m.info("Processing specialist_ops",{operation:w,sessionId:k}),w){case"delegate":{const e=n.delegate,o=10
|
|
3254
3262
|
let i=p?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
|
|
3255
3263
|
if(!i){const e=await(0,h.getServerUrl)(r,m)
|
|
@@ -3267,7 +3275,7 @@ if(n.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t
|
|
|
3267
3275
|
const g=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
|
|
3268
3276
|
return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
|
|
3269
3277
|
return{content:[{type:"text",text:`\u274c Specialist pool is full (${h.length}/${t}).\nAbort an idle specialist first with \`specialist_ops abort\`, then delegate again.\n\nCurrent pool:\n`+g}],isError:!0}}catch(e){return void n.warn("Pool limit check failed, allowing spawn",{error:(0,l.getErrorMessage)(e)})}}(i,o,r,m,s)
|
|
3270
|
-
if(e){
|
|
3278
|
+
if(e){I=e
|
|
3271
3279
|
break}}let a=e.description
|
|
3272
3280
|
const c=await Promise.resolve().then(t.t.bind(t,9896,23)),y=e=>c.appendFileSync("/tmp/specialist-name-debug.log",`${(new Date).toISOString()} ${e}\n`)
|
|
3273
3281
|
if(i)try{const e=await(0,h.getServerUrl)(r,m)
|
|
@@ -3277,22 +3285,22 @@ y(`siblings=${e.length}: ${e.join(", ")}`)
|
|
|
3277
3285
|
const r=(0,d.pickSpecialistName)(e)
|
|
3278
3286
|
a=r,y("picked name: "+r)}}else y("no serverUrl")}catch(e){y("error: "+(e instanceof Error?e.message:e+""))}else y("no parentId")
|
|
3279
3287
|
const w=e.requestId,k=w?`Working on request ${w}.\n\n${e.prompt}`:e.prompt
|
|
3280
|
-
|
|
3288
|
+
I=await(0,u.handleSpawn)({agent:"specialist",prompt:k,title:a,specialization:e.specialization},r,m,s,p)
|
|
3281
3289
|
break}case"follow-up":{const e=await(0,h.getServerUrl)(r,m)
|
|
3282
3290
|
if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
|
|
3283
3291
|
if(t.ok){const e=await t.json(),r=e[k]?.type
|
|
3284
|
-
if(r&&"idle"!==r&&"prompting"!==r){
|
|
3285
|
-
break}}}catch{}
|
|
3292
|
+
if(r&&"idle"!==r&&"prompting"!==r){I={content:[{type:"text",text:`\u274c Specialist ${k} is currently busy (status: ${r}).\nUse \`delegate\` to spawn a new specialist instead.`}],isError:!0}
|
|
3293
|
+
break}}}catch{}I=await(0,u.handleContinue)(k,n.followUp.prompt,r,m,s,"specialist",p)
|
|
3286
3294
|
const t=n.followUp.specialization
|
|
3287
3295
|
if(t&&s)try{const e=s.getCLISessionClient()
|
|
3288
|
-
e&&(await e.createOrUpdateSession({externalSessionId:k,specialization:t}),
|
|
3296
|
+
e&&(await e.createOrUpdateSession({externalSessionId:k,specialization:t}),I.content[0].text+="\nSpecialization updated to: "+t)}catch{}break}case"check-status":I=await(0,u.handleCheckStatus)(k,r,m,s)
|
|
3289
3297
|
break
|
|
3290
|
-
case"abort":if(
|
|
3298
|
+
case"abort":if(I=await(0,u.handleAbort)(k,r,m),!I.isError&&s)try{const e=s.getCLISessionClient()
|
|
3291
3299
|
e&&await e.createOrUpdateSession({externalSessionId:k,status:"archived"})}catch{}break
|
|
3292
3300
|
case"list":{let e=p?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
|
|
3293
3301
|
if(!e){const t=await(0,h.getServerUrl)(r,m)
|
|
3294
|
-
if(t)try{e=(0,g.getCachedSession)()?.sessionId||await(0,h.discoverParentSessionId)(t,m)}catch{}}
|
|
3295
|
-
break}default:throw new i.ValidationError("Unknown operation: "+w)}return y({success:!0}),o.incrementCounter(`specialist_ops_${w}_success`,1),
|
|
3302
|
+
if(t)try{e=(0,g.getCachedSession)()?.sessionId||await(0,h.discoverParentSessionId)(t,m)}catch{}}I=await(0,u.handleListSessions)(r,m,s,{activeOnly:n.list?.activeOnly,requestId:n.list?.requestId,limit:n.list?.limit,agentType:"specialist",parentSessionId:e})
|
|
3303
|
+
break}default:throw new i.ValidationError("Unknown operation: "+w)}return y({success:!0}),o.incrementCounter(`specialist_ops_${w}_success`,1),I}catch(e){return m.error("Specialist ops failed",{error:e instanceof Error?e.stack:e+""}),y({success:!1}),o.incrementCounter("specialist_ops_errors",1),{content:[{type:"text",text:"Specialist operation failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
3296
3304
|
const i=t(9860),a=t(6183),c=s(t(5967)),l=t(8824),d=t(9089),u=t(1725),h=t(7617),g=t(715),f=t(6688)},6315(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3297
3305
|
const r=t(6183),n=t(2982)
|
|
3298
3306
|
exports.def={name:"generate_request_journal",description:"Fetch comprehensive data about a request for writing a journal entry.\n\nReturns structured data including:\n\u2022 Request details (title, description, type, status, acceptance criteria)\n\u2022 All tasks with descriptions and status\n\u2022 File changes summary (files modified, operations performed)\n\u2022 Chronological operation history\n\nUse this data to write a narrative journal entry and save it as:\nJOURNAL-{requestId}.md using document-operations (create).",schema:r.GenerateRequestJournalSchema,annotations:{title:"Generate Request Journal",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0},readOnly:!0,hidden(){return"journal"!==process.env.ALCHEMY_MODE},handler(e,t){return(0,n.handleGenerateRequestJournal)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},6416(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
@@ -3360,7 +3368,7 @@ var t={}
|
|
|
3360
3368
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3361
3369
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3362
3370
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleInsertLines=async function(e,t,n,o,s,i,a,m){const y=i.child({tool:"insert_lines"}),w=Date.now()
|
|
3363
|
-
let k,b
|
|
3371
|
+
let k,I,b=d.FileOperationPhase.VALIDATION
|
|
3364
3372
|
const v={toolName:"insert-lines",operationName:"insert-lines",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"insert-lines",metricsPrefix:"insert_lines",successMessage:"Successfully inserted lines into files and documents",failureMessage:"Failed to insert lines into files and documents"}
|
|
3365
3373
|
try{const i=d.validateArgs(e,l.InsertLinesSchema),{taskId:C,operations:_,comment:E}=i
|
|
3366
3374
|
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")
|
|
@@ -3373,7 +3381,7 @@ if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not ava
|
|
|
3373
3381
|
for(const e of S)M.push({type:"document",documentId:e.documentId,insertions:e.insertions})
|
|
3374
3382
|
if(M.length>0&&t.apiClient){const e=M.map((e=>e.documentId))
|
|
3375
3383
|
try{await(0,f.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}
|
|
3376
|
-
throw e}}
|
|
3384
|
+
throw e}}b=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("insert_lines_phase",1,{phase:b})
|
|
3377
3385
|
const R=T.length>0?T[0].path:"document-operation",P=await d.validateTaskId(C,R,n,y,a,v.metricsPrefix),x=P?.requestId
|
|
3378
3386
|
let O=null
|
|
3379
3387
|
T.length>0&&x&&(O=await d.validateWorkItemStates(C,T[0].path,n,s,t,y,a,v.metricsPrefix))
|
|
@@ -3384,9 +3392,9 @@ if(!$.success){if($.isLockConflict)return{content:[{type:"text",text:"\u274c "+$
|
|
|
3384
3392
|
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})
|
|
3385
3393
|
for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
|
|
3386
3394
|
T[e]={...r,path:o,fullPath:s}}}if(M.length>0&&x)try{await(0,h.validateRequestStatusForDocumentOperation)(x,s,y,a,"insert-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3387
|
-
throw e}
|
|
3395
|
+
throw e}b=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("insert_lines_phase",1,{phase:b})
|
|
3388
3396
|
const D=[...T.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...M.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:A}=await d.createFileOperationRecords(C,x,t.projectId,v.recordType,R,{operationCount:_.length,fileOperations:T.length,documentOperations:M.length,operations:D,userComment:E},n,o,y,a,v.metricsPrefix,m)
|
|
3389
|
-
if(k=A,
|
|
3397
|
+
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")
|
|
3390
3398
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"insert-lines",{requestId:x,taskId:C,workspaceManager:t.workspaceManager},y,a)
|
|
3391
3399
|
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})
|
|
3392
3400
|
const F=[]
|
|
@@ -3399,8 +3407,8 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
|
|
|
3399
3407
|
n.filename=s?.filename
|
|
3400
3408
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
|
|
3401
3409
|
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,p.getErrorMessage)(t),n.failedInsertions=e.insertions.length,N+=n.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:n.error})}F.push(n)}if(M.length>0)try{for(const e of M){const r=F.find((t=>t.documentId===e.documentId))
|
|
3402
|
-
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const B=await d.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:
|
|
3403
|
-
try{await o.updateToolRecord(
|
|
3410
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const B=await d.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),H=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:W,failedOperations:U,totalSuccessfulChanges:G,overallSuccess:V,successfulFiles:J,failedFiles:K}=H
|
|
3411
|
+
try{await o.updateToolRecord(I,{metadata:{path:T.length>0?T[0].path:"document:"+M[0]?.documentId,status:V?"completed":"failed",error:V?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:D,totalSuccessfulInsertions:G,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:E,...T.length>0&&B.success&&B.commitHash&&{commitHash:B.commitHash,previousCommitHash:B.previousCommitHash||void 0}},note:V?`Line insertion completed: ${W}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
|
|
3404
3412
|
if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${W+U}\n`,Y+=`- **Successful operations:** ${W}\n`,Y+=`- **Failed operations:** ${U}\n`,Y+=`- **Total insertions:** ${G} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n`,Y+="\n",B.success&&B.commitHash&&(Y+="**Git Commit:**\n",Y+=`- **Commit Hash:** ${B.commitHash.substring(0,8)}\n`,Y+=`- **Files Committed:** ${B.filesCommitted.length}\n`,B.previousCommitHash&&(Y+=`- **Previous Commit:** ${B.previousCommitHash.substring(0,8)}\n`),Y+="\n"),$.lockAcquired&&$.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
|
|
3405
3413
|
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"
|
|
3406
3414
|
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}`
|
|
@@ -3410,68 +3418,68 @@ for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?
|
|
|
3410
3418
|
Y+=` - ${t.type} insertion ${e}: ${t.error}\n`}}Y+="\n"}}M.length>0&&(Y+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3411
3419
|
const Q=Date.now()-w
|
|
3412
3420
|
return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:W,failedOperations:U}),a.incrementCounter("insert_lines_total",1,{success:V}),{content:[{type:"text",text:Y}],isError:!V}}catch(t){const r=Date.now()-w
|
|
3413
|
-
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:
|
|
3421
|
+
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,p.getErrorMessage)(t),phase:b,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,p.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("insert_lines_errors",1,{phase:b}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,p.getErrorMessage)(t)}],isError:!0}}}
|
|
3414
3422
|
const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),f=t(9949),p=t(8824),m=t(3255)},6539(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
|
|
3415
3423
|
const r=t(1253),n=t(5681),o=t(6595),s=t(3895),i=t(6848),a=t(6153),c=t(4710),l=t(6975),d=t(1887),u=t(1666),h=t(8824),g=t(9884),f=t(2968),p=t(922)
|
|
3416
3424
|
exports.ClientFactory=class{static async createClient(e,m,y,w={}){(m=m.child({component:"client-factory"})).info("Creating API client with components")
|
|
3417
3425
|
const k=w.tokenManager||new r.TokenManager(m,w.workingDir||process.cwd())
|
|
3418
3426
|
await k.initialize()
|
|
3419
|
-
const
|
|
3420
|
-
|
|
3427
|
+
const I=w.tokenSynchronizer||new i.ClientTokenSynchronizer(m),b=new s.AuthenticationManager(k,m,I),v=await b.getTokenString(),C=w.connectionStatusManager||new n.ConnectionStatusManager(e,m,y,{alchemyPath:w.alchemyPath,checkIntervalMs:w.offlineCheckIntervalMs,timeoutMs:w.timeout,retryCount:w.retryAttempts}),_=new c.ProjectClient(e,m,y,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3428
|
+
I.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3421
3429
|
const E=new f.TaskClient(e,m,y,_,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3422
|
-
|
|
3430
|
+
I.registerClient(E)
|
|
3423
3431
|
const q=new a.FileOperationsClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3424
|
-
|
|
3432
|
+
I.registerClient(q),m.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
3425
3433
|
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})
|
|
3426
|
-
|
|
3434
|
+
I.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
|
|
3427
3435
|
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})
|
|
3428
|
-
|
|
3436
|
+
I.registerClient(T)
|
|
3429
3437
|
const M=new p.ToolRecordClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3430
|
-
|
|
3438
|
+
I.registerClient(M)
|
|
3431
3439
|
const R=new d.ProxyClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3432
|
-
if(
|
|
3440
|
+
if(I.registerClient(R),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
|
|
3433
3441
|
try{m.info("Creating ProjectSynchronizer components")
|
|
3434
3442
|
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})
|
|
3435
3443
|
_.setProjectSynchronizer(n),m.info("ProjectSynchronizer created and connected to ProjectClient")}catch(e){const t="Failed to create required ProjectSynchronizer components: "+(0,h.getErrorMessage)(e)
|
|
3436
|
-
throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const P=new o.ApiClient(
|
|
3444
|
+
throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const P=new o.ApiClient(b,_,E,q,S,T,M,R,m)
|
|
3437
3445
|
m.info("API client initialized with specialized clients"),v?(P.setAuthToken(v),m.info("Auth token set on ApiClient during creation",{hasToken:!0,tokenLength:v.length})):m.warn("No auth token available during ApiClient creation",{info:"Client will need to authenticate before making requests"})
|
|
3438
|
-
const x=
|
|
3446
|
+
const x=I.verifyAllClients()
|
|
3439
3447
|
x.success?m.info("Token consistency verified across all clients"):m.error(`Token inconsistency detected in ${x.failedClients.length} clients: ${x.failedClients.join(", ")}`)
|
|
3440
3448
|
const O=P.getAuthToken()
|
|
3441
3449
|
return v&&!O?(m.error("CRITICAL: ApiClient token was not set properly!"),P.setAuthToken(v)):O&&m.info("ApiClient token verified",{tokenLength:O.length,matches:O===v}),m.info("API client creation completed successfully"),P}}},6540(e,exports){var t
|
|
3442
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6552(e,exports,t){async function r(){const e=new o.StdioServerTransport,t=(0,l.setupParentProcessDetection)((()=>{
|
|
3443
|
-
if(E)try{await E.connectStdio(),(0,a.isDebugToolsEnabled)()&&
|
|
3444
|
-
throw
|
|
3450
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6552(e,exports,t){async function r(){const e=new o.StdioServerTransport,t=(0,l.setupParentProcessDetection)((()=>{I.info("Parent process gone or orphan detected. Shutting down."),process.exit(0)}))
|
|
3451
|
+
if(E)try{await E.connectStdio(),(0,a.isDebugToolsEnabled)()&&I.info("Connected stdio transport to server")}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3452
|
+
throw I.error("Failed to connect stdio transport",{errorDetails:t}),e}else I.error("No global server instance available to connect transport")
|
|
3445
3453
|
return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3446
3454
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
3447
3455
|
const o=t(5802),s=n(t(6928)),i=t(184),a=t(3444),c=t(1152),l=t(8851),d=t(8411),u=n(t(9896)),h=t(4139),g=t(5218),f=t(8824),p=t(9939),m=t(7960),y=process.argv.slice(2),w=y[0]||process.cwd(),k=s.default.resolve(w)
|
|
3448
3456
|
console.error("\n=== MCP STARTUP DIAGNOSTICS ==="),console.error("Script path (process.argv[1]):",process.argv[1]),console.error("Base directory:",k),console.error("ENABLE_DEBUG_TOOLS env:",process.env.ENABLE_DEBUG_TOOLS),console.error("DEBUG_LOGGING env:",process.env.DEBUG_LOGGING),console.error("isDevBuild():",(0,m.isDevBuild)()),console.error("isDebugToolsEnabled():",(0,a.isDebugToolsEnabled)()),console.error("===============================\n")
|
|
3449
|
-
const
|
|
3450
|
-
const
|
|
3451
|
-
process.stdout.write=function(e,t,r){try{if("string"==typeof e)try{JSON.parse(e)}catch(t){return e.includes('"__message_type"')||(process.stderr.write("[STDOUT REDIRECTED]: "+e),r&&r()),!0}return"string"==typeof t&&"function"==typeof r?
|
|
3452
|
-
try{if(u.default.existsSync(k)||(
|
|
3453
|
-
u.default.writeFileSync(e,(new Date).toISOString()),
|
|
3457
|
+
const I=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:k});(0,a.isDebugToolsEnabled)()?I.info("MCP Direct server initializing",{baseDir:k,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):I.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(I.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),E)try{E.cleanupSSEConnection()}catch(e){I.error("Error during cleanup after uncaught exception: "+e)}setTimeout((()=>process.exit(1)),500)})),process.on("unhandledRejection",(e=>{I.error("UNHANDLED REJECTION: "+e,{stack:e instanceof Error?e.stack:"No stack available"})})),process.on("exit",(e=>{I.info("Process exiting with code: "+e)}))
|
|
3458
|
+
const b=process.stdout.write
|
|
3459
|
+
process.stdout.write=function(e,t,r){try{if("string"==typeof e)try{JSON.parse(e)}catch(t){return e.includes('"__message_type"')||(process.stderr.write("[STDOUT REDIRECTED]: "+e),r&&r()),!0}return"string"==typeof t&&"function"==typeof r?b.call(process.stdout,e,t,r):"function"==typeof t?b.call(process.stdout,e,void 0,t):b.call(process.stdout,e)}catch(e){return process.stderr.write("[STDOUT ERROR]: "+e),!0}},(0,a.isDebugToolsEnabled)()&&(I.info("Initialized stdout filtering to ensure only valid JSON is sent"),I.info("!!!MARKER!!! COMMAND-LINE ARGS:",{args:JSON.stringify(y)}),I.info("!!!MARKER!!! BASE DIRECTORY:",{baseDir:w}),I.info("!!!MARKER!!! ABSOLUTE BASE DIR:",{absBaseDir:k}),I.info("Working with base directory:",{absBaseDir:k}))
|
|
3460
|
+
try{if(u.default.existsSync(k)||(I.warn(`Base directory ${k} does not exist. Creating it...`),u.default.mkdirSync(k,{recursive:!0})),(0,a.isDebugToolsEnabled)()){const e=s.default.join(k,".mcp-test-file")
|
|
3461
|
+
u.default.writeFileSync(e,(new Date).toISOString()),I.info("Successfully wrote test file to "+e),u.default.unlinkSync(e),I.info("Successfully deleted test file"),I.info(`Confirmed base directory ${k} exists and is accessible`)}}catch(e){I.error(`Error accessing base directory ${k}:`,{error:e}),I.warn("This may cause issues with file operations - please check permissions")}const v=(0,c.createMetricsCollector)(!1)
|
|
3454
3462
|
let C=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com"
|
|
3455
3463
|
const _=global.__serverInitialized
|
|
3456
|
-
void 0===_?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&
|
|
3464
|
+
void 0===_?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&I.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&I.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
|
|
3457
3465
|
let E=null
|
|
3458
3466
|
const q=(0,g.isMultiAgentModeEnabled)(k)
|
|
3459
|
-
try{(0,d.acquireProcessLock)(k,q)||(
|
|
3460
|
-
|
|
3467
|
+
try{(0,d.acquireProcessLock)(k,q)||(I.error(`Process lock acquisition failed for ${k}. Another instance may be running.`),I.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&(q?I.info("Multi-agent mode enabled - allowing concurrent access to "+k):I.info("Successfully acquired process lock for "+k))}catch(e){I.error("Lock acquisition threw exception",{error:(0,f.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),I.error("Cannot continue without lock in single-agent mode"),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(I.info("============================================================"),I.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),I.info("BASE DIR: "+k),I.info("ALCHEMY PATH: "+s.default.join(k,h.ALCHEMY_DIR_NAME)),I.info("PROJECT PATH: "+s.default.join(k,h.ALCHEMY_DIR_NAME+"/project.json")),I.info("MULTI-AGENT MODE: "+q),I.info("MCP client information will be captured during protocol initialization")),I.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(I.info("============================================================"),I.info("Base directory: "+k),I.info("Remote server URL: "+C),I.info("Node version: "+process.version),I.info("Current working directory: "+process.cwd()),I.info("ALLOWED_DIRECTORIES env var: not used (single working directory mode)"),I.info("Server already initialized: "+(_?"YES":"NO"))),_&&((0,a.isDebugToolsEnabled)()&&(I.info("Server already initialized globally, reusing existing server instance"),I.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3468
|
+
I.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
|
|
3461
3469
|
try{const e=u.default.existsSync(k)
|
|
3462
|
-
if((0,a.isDebugToolsEnabled)()&&
|
|
3463
|
-
|
|
3464
|
-
if(!u.default.existsSync(S))try{u.default.mkdirSync(S,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&
|
|
3465
|
-
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(
|
|
3466
|
-
if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&
|
|
3467
|
-
try{const e=await(0,p.syncPlugins)(k,(0,m.isDevBuild)(),
|
|
3468
|
-
e.synced.length>0&&
|
|
3469
|
-
const e=await(0,i.createServer)(k,
|
|
3470
|
-
E=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&
|
|
3470
|
+
if((0,a.isDebugToolsEnabled)()&&I.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=u.default.statSync(k)
|
|
3471
|
+
I.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(8)}`)}else(0,a.isDebugToolsEnabled)()&&I.info("Directory does not exist, trying to create it"),u.default.mkdirSync(k,{recursive:!0})}catch(e){I.error("Error checking directory: "+e)}if(!u.default.existsSync(k))try{u.default.mkdirSync(k,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&I.info("Created base directory: "+k)}catch(e){I.error("Failed to create base directory: "+e)}const S=s.default.join(k,h.ALCHEMY_DIR_NAME)
|
|
3472
|
+
if(!u.default.existsSync(S))try{u.default.mkdirSync(S,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&I.info("Created alchemy lab directory: "+S)}catch(e){I.error("Failed to create alchemy lab directory: "+e)}try{(async function(){try{C=await async function(){if(process.env.REMOTE_SERVER_URL)return process.env.REMOTE_SERVER_URL
|
|
3473
|
+
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(I),n=await r.getInstallationConfig()
|
|
3474
|
+
if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&I.info("Loaded REMOTE_SERVER_URL from installation config",{remoteServerUrl:n.remoteServerUrl}),n.remoteServerUrl}catch(e){(0,a.isDebugToolsEnabled)()&&I.debug("Could not read REMOTE_SERVER_URL from installation config",{error:e instanceof Error?e.message:"Unknown error"})}return"https://api.alchemylabcode.com"}()
|
|
3475
|
+
try{const e=await(0,p.syncPlugins)(k,(0,m.isDevBuild)(),I)
|
|
3476
|
+
e.synced.length>0&&I.info("Synced plugins on startup",{synced:e.synced}),e.errors.length>0&&I.warn("Some plugins failed to sync",{errors:e.errors})}catch(e){I.warn("Plugin sync failed",{error:e instanceof Error?e.message:"Unknown error"})}(0,a.isDebugToolsEnabled)()&&(I.info("Creating MCP server with base dir: "+k),I.info("Using remote server URL: "+C))
|
|
3477
|
+
const e=await(0,i.createServer)(k,I,v,C,{multiAgentMode:(0,g.isMultiAgentModeEnabled)(k)})
|
|
3478
|
+
E=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&I.info("MCP server created successfully")
|
|
3471
3479
|
const n=r()
|
|
3472
|
-
return(0,a.isDebugToolsEnabled)()&&
|
|
3473
|
-
|
|
3474
|
-
|
|
3480
|
+
return(0,a.isDebugToolsEnabled)()&&I.info("Stdio transport registered with server"),{server:E,transportInfo:n}}catch(e){throw I.error("Failed to initialize MCP server",{error:e}),e}})().then((()=>{(0,a.isDebugToolsEnabled)()&&I.info("MCP server initialization complete")})).catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3481
|
+
I.error("Server initialization failed",{errorDetails:t}),process.exit(1)}))}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3482
|
+
I.error("Exception during server initialization",{errorDetails:t}),process.exit(1)}process.on("SIGTERM",(()=>{I.info("SIGTERM received, shutting down"),setTimeout((()=>process.exit(0)),500)})),process.on("SIGINT",(()=>{I.info("SIGINT received, shutting down"),setTimeout((()=>process.exit(0)),500)}))},6595(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ApiClient=void 0
|
|
3475
3483
|
const r=t(1599),n=t(2690),o=t(4465),s=t(5187),i=t(5674),a=t(8824)
|
|
3476
3484
|
exports.ApiClient=class{constructor(e,t,r,n,o,s,i,a,c){this.options={createRecords:!0},this.alchemyPath="",this.sessionRequestAssociationClient=null,this.sessionMessageClient=null,this.sessionTagMappingClient=null,this.cliSessionClient=null,this.logger=c,this.authManager=e,this.projectClient=t,this.taskClient=r,this.fileClient=n,this.requestClient=o,this.documentClient=s,this.toolRecordClient=i,this.proxyClient=a,this.tokenSynchronizer=e.getTokenSynchronizer(),this.baseUrl=a.baseUrl||"",this.documentClient&&"function"==typeof this.documentClient.setParentApiClient&&this.documentClient.setParentApiClient(this),this.logger.info("API client initialized with specialized clients")}async setToken(e){return this.authManager.setToken(e)}async getToken(){return this.authManager.getToken()}async hasValidToken(){return this.authManager.hasValidToken()}async removeToken(){return this.authManager.removeToken()}setOptions(e){this.options={...this.options,...e},this.logger.info("API client options updated",{options:this.options})}getOptions(){return{...this.options}}isOffline(){const e=this.projectClient.isOffline?.()||!1,t=this.fileClient.isOffline?.()||!1,r=this.proxyClient.isOffline?.()||!1,n=e||t||r
|
|
3477
3485
|
return this.logger.debug("ApiClient.isOffline called - reporting actual connection status",{isOffline:n,client:"ApiClient"}),n}checkConnectivity(e,t){if(this.isOffline()){let r
|
|
@@ -3508,7 +3516,7 @@ var t={}
|
|
|
3508
3516
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3509
3517
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3510
3518
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceLines=async function(e,t,n,o,s,i,a,m){const w=i.child({tool:"replace_lines"}),k=Date.now()
|
|
3511
|
-
let b,
|
|
3519
|
+
let I,b,v=d.FileOperationPhase.VALIDATION
|
|
3512
3520
|
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"}
|
|
3513
3521
|
try{const i=d.validateArgs(e,l.ReplaceLinesSchema),{taskId:_,operations:E,comment:q}=i
|
|
3514
3522
|
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")
|
|
@@ -3534,7 +3542,7 @@ for(let e=0;e<M.length;e++){const r=M[e],n=S[e],{normalizedPath:o,fullPath:s}=d.
|
|
|
3534
3542
|
M[e]={...r,path:o,fullPath:s}}}if(R.length>0&&O)try{await(0,h.validateRequestStatusForDocumentOperation)(O,s,w,a,"replace-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3535
3543
|
throw e}v=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3536
3544
|
const A=[...M.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...R.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await d.createFileOperationRecords(_,O,t.projectId,C.recordType,P,{operationCount:E.length,fileOperations:M.length,documentOperations:R.length,operations:A,userComment:q},n,o,w,a,C.metricsPrefix,m)
|
|
3537
|
-
if(
|
|
3545
|
+
if(I=F,b=F,v=C.fileOperationPhase,a.incrementCounter("replace_lines_phase",1,{phase:v}),M.length>0&&t.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
|
|
3538
3546
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:O,taskId:_,workspaceManager:t.workspaceManager},w,a)
|
|
3539
3547
|
e.userChangesCommitted&&(w.debug("[REPLACE-LINES] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before replace-lines operation",{taskId:_,fileOperationsCount:M.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[REPLACE-LINES] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:_,fileOperationsCount:M.length,error:e instanceof Error?e.message:e+""})}w.debug("[REPLACE-LINES] Proceeding with file operations",{fileCount:M.length})
|
|
3540
3548
|
const N=[]
|
|
@@ -3547,8 +3555,8 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
|
|
|
3547
3555
|
n.filename=s?.filename
|
|
3548
3556
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
|
|
3549
3557
|
n.replacements=l,n.successfulReplacements=l.filter((e=>e.success)).length,n.failedReplacements=l.filter((e=>!e.success)).length,n.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,H++,w.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulReplacements:n.successfulReplacements,failedReplacements:n.failedReplacements,linesReplaced:n.totalLinesReplaced,linesAdded:n.totalLinesAdded})):0===n.failedReplacements&&(n.success=!0),L+=n.failedReplacements,z+=n.totalLinesReplaced,B+=n.totalLinesAdded}catch(t){n.error=(0,p.getErrorMessage)(t),n.failedReplacements=e.replacements.length,L+=n.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:n.error})}N.push(n)}if(R.length>0)try{for(const e of R){const r=N.find((t=>t.documentId===e.documentId))
|
|
3550
|
-
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const W=await d.handleMultiFileGitCommit(_,M,N,H,{operationType:"Replace lines",toolRecordId:
|
|
3551
|
-
try{await o.updateToolRecord(
|
|
3558
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const W=await d.handleMultiFileGitCommit(_,M,N,H,{operationType:"Replace lines",toolRecordId:b,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),U=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=U
|
|
3559
|
+
try{await o.updateToolRecord(b,{metadata:{path:M.length>0?M[0].path:"document:"+R[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:A,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-k,userComment:q,...M.length>0&&W.success&&W.commitHash&&{commitHash:W.commitHash,previousCommitHash:W.previousCommitHash||void 0}},note:K?`Line replacement completed: ${G}/${N.length} operations successful${M.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${V}/${N.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z="## Line Replacement Results\n\n"
|
|
3552
3560
|
if(t.workspaceManager&&(Z+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Z+="**Summary:**\n",Z+=`- **Files processed:** ${G+V}\n`,Z+=`- **Successful operations:** ${G}\n`,Z+=`- **Failed operations:** ${V}\n`,Z+=`- **Total replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,B>0&&(Z+=`- **Total Lines Added:** ${B}\n`),Z+="\n",W.success&&W.commitHash&&(Z+="**Git Commit:**\n",Z+=`- **Commit Hash:** ${W.commitHash.substring(0,8)}\n`,Z+=`- **Files Committed:** ${W.filesCommitted.length}\n`,W.previousCommitHash&&(Z+=`- **Previous Commit:** ${W.previousCommitHash.substring(0,8)}\n`),Z+="\n"),D.lockAcquired&&D.lockedRequestId&&(Z+=`\u{1f512} **Locked request:** ${D.lockedRequestId}\n\n`),1===N.length){const e=N[0]
|
|
3553
3561
|
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"
|
|
3554
3562
|
for(const t of e.replacements.filter((e=>!e.success)))Z+=`- Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}}else{Z+="**Summary:**\n",Z+=`- **Total Operations:** ${N.length}\n`,Z+=`- **Successful:** ${G}\n`,Z+=`- **Failed:** ${V}\n`,Z+=`- **Total Replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,B>0&&(Z+=`- **Total Lines Added:** ${B}\n`),Z+="\n",Z+="**Detailed Results:**\n\n"
|
|
@@ -3556,7 +3564,7 @@ for(const e of N){if("file"===e.type?Z+=`### File: ${e.path}\n`:(Z+="### Documen
|
|
|
3556
3564
|
for(const t of e.replacements.filter((e=>!e.success)))Z+=` - Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}Z+="\n"}}R.length>0&&(Z+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3557
3565
|
const X=Date.now()-k
|
|
3558
3566
|
return w.info("Replace lines operation completed",{duration:X,success:K,totalOperations:N.length,successfulOperations:G,failedOperations:V}),a.incrementCounter("replace_lines_total",1,{success:K}),{content:[{type:"text",text:Z}],isError:!K}}catch(t){const r=Date.now()-k
|
|
3559
|
-
if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),
|
|
3567
|
+
if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),b)try{await o.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,p.getErrorMessage)(t),phase:v,duration:r,userComment:e?.comment},note:"Line replacement failed: "+(0,p.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_lines_errors",1,{phase:v}),{content:[{type:"text",text:"\u274c **Replace Lines Failed:** "+(0,p.getErrorMessage)(t)}],isError:!0}}}
|
|
3560
3568
|
const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),f=t(9949),p=t(8824),m=t(3255),y=t(9470)},6688(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
|
|
3561
3569
|
const r=t(9896),n=t(6928)
|
|
3562
3570
|
exports.sessionIdentity=new class{constructor(){this.discoveryAttempted=!1,this.parentCache=new Map}setIdentity(e){const t=this.identity
|
|
@@ -3616,13 +3624,13 @@ s.info("Raw task response data",{responseDataType:typeof M,isArray:Array.isArray
|
|
|
3616
3624
|
try{const P=await m.getToolRecordsByTaskId(g)
|
|
3617
3625
|
if(s.info("Raw records response data",{responseDataType:typeof P,isArray:Array.isArray(P),hasData:null!=P,properties:P&&"object"==typeof P?Object.keys(P):[]}),k=(0,l.extractArrayFromResponse)(P,{logger:s,operationName:"searchRecords",defaultValue:[]}),k.length>0&&s.info("First record summary:",{id:k[0].id,type:k[0].type,hasMetadata:!!k[0].metadata,hasCommitHash:!!k[0].metadata?.commitHash}),s.info(`Extracted ${k.length} records for task ${g}`),k.length>0){const x={}
|
|
3618
3626
|
k.forEach((e=>{x[e.type]=(x[e.type]||0)+1})),s.info("Record type distribution:",x)}}catch(O){s.warn("Error fetching records for task "+g,{error:(0,u.getErrorMessage)(O)}),k=[]}if(0===k.length)return h({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
|
|
3619
|
-
function
|
|
3627
|
+
function I(e){const t=new Map,r=new Map,n=[]
|
|
3620
3628
|
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
|
|
3621
3629
|
if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
|
|
3622
3630
|
t.set(e,i),r.set(s,i),n.push(i)}}else if("move-files"===o.type&&o.metadata){const e=[...o.metadata.successfulOperations||[],...o.metadata.failedOperations||[]]
|
|
3623
3631
|
for(const s of e)if(s.source&&s.destination){const e={source:s.source,destination:s.destination,recordId:o.id,timestamp:o.createdAt,type:"move-files"}
|
|
3624
|
-
t.set(s.source,e),r.set(s.destination,e),n.push(e)}}return{sourceToMove:t,destToMove:r,allMoves:n}}const I
|
|
3625
|
-
s.info(`Detected ${
|
|
3632
|
+
t.set(s.source,e),r.set(s.destination,e),n.push(e)}}return{sourceToMove:t,destToMove:r,allMoves:n}}const b=I(k)
|
|
3633
|
+
s.info(`Detected ${b.allMoves.length} move operations`)
|
|
3626
3634
|
const v=k.filter((e=>{if(!e||"object"!=typeof e)return s.warn("Skipping invalid record (not an object)"),!1
|
|
3627
3635
|
if(!["write-file","replace-in-files","move-file","move-files","delete-file","delete-files","manage-files"].includes(e.type))return s.debug("Skipping record with non-file operation type: "+e.type),!1
|
|
3628
3636
|
if(!e.metadata)return s.warn("Skipping record without metadata: "+e.id),!1
|
|
@@ -3698,7 +3706,7 @@ continue}let fe
|
|
|
3698
3706
|
if("pre-task"===U.status?(fe=[`${U.commitHash}..${B.commitHash}`,"--",A],s.info(`Comparing pre-task commit with final commit: ${U.commitHash?U.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${A}`)):(fe=["4b825dc642cb6eb9a060e54bf8d69288fbee4904.."+B.commitHash,"--",A],s.info(`File created during task, showing full file diff using empty tree object: ${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${A}`)),G=await t.git.diff(fe),V=!!G&&G.trim().length>0,!V&&U.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
|
|
3699
3707
|
try{const me=await t.git.show([`${U.commitHash}:${A}`]),ye=await t.git.show([`${B.commitHash}:${A}`])
|
|
3700
3708
|
if(me!==ye&&(V=!0,G="Changes detected through direct content comparison (not visible in standard diff)",f)){const we=me.split("\n"),ke=ye.split("\n")
|
|
3701
|
-
Math.abs(we.length-ke.length)>0&&(G+=`\n\nLine count changed: ${we.length} \u2192 ${ke.length}`),me.includes("\0")||ye.includes("\0")?G+="\n\nBinary content detected - changes not displayed":me.replace(/\s+/g,"")===ye.replace(/\s+/g,"")&&(G+="\n\nWhitespace-only changes detected")}}catch(
|
|
3709
|
+
Math.abs(we.length-ke.length)>0&&(G+=`\n\nLine count changed: ${we.length} \u2192 ${ke.length}`),me.includes("\0")||ye.includes("\0")?G+="\n\nBinary content detected - changes not displayed":me.replace(/\s+/g,"")===ye.replace(/\s+/g,"")&&(G+="\n\nWhitespace-only changes detected")}}catch(Ie){s.warn("Error in direct file comparison: "+(Ie instanceof Error?Ie.message:Ie+""))}}s.info(`Diff generation result for ${A}: hasDiff=${V}, length=${G.length}`)}}catch(be){if(s.warn("Error getting diff for "+A,{error:(0,u.getErrorMessage)(be),firstCommit:z.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),G="Error getting diff: "+(0,u.getErrorMessage)(be),"pre-task"!==z.status&&t.git)try{const ve=[`${B.commitHash}:${A}`]
|
|
3702
3710
|
s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${A}`)
|
|
3703
3711
|
const Ce=await t.git.show(ve)
|
|
3704
3712
|
if(Ce&&Ce.trim().length>0){if(f){let _e=""
|
|
@@ -3710,14 +3718,14 @@ w&&"object"==typeof w&&(E+="## Task Information\n",E+=`- **Title**: ${w.title||"
|
|
|
3710
3718
|
const q=3e3
|
|
3711
3719
|
let S=0,T=!1
|
|
3712
3720
|
if(f){for(const Te of _.values())Te.hasDiff&&Te.diffText&&(S+=Te.diffText.split("\n").length)
|
|
3713
|
-
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**: ${f?"Enabled":"Disabled"} (use showDiff=${!f} to ${f?"hide":"show"} diffs)\n\n`,
|
|
3714
|
-
for(const Me of
|
|
3721
|
+
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**: ${f?"Enabled":"Disabled"} (use showDiff=${!f} to ${f?"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`
|
|
3722
|
+
for(const Me of b.allMoves)E+=`- **${Me.source}** \u2192 **${Me.destination}**\n`,E+=` - Operation: ${Me.type}\n`,E+=` - Timestamp: ${new Date(Me.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Me.recordId}\n\n`}E+="## Modified Files\n\n"
|
|
3715
3723
|
for(const[Re,Pe]of _.entries()){const{normalizedPath:xe,fullPath:Oe}=d.validateAndNormalizePath(Re,t)
|
|
3716
3724
|
let je=!1
|
|
3717
3725
|
try{await a.access(Oe),je=!0}catch{}E+=`### ${Re} ${je?"":"(Deleted)"}\n\n`
|
|
3718
3726
|
const $e=new Date(Pe.firstChange.timestamp).toLocaleString(),De=new Date(Pe.lastChange.timestamp).toLocaleString()
|
|
3719
3727
|
E+=`**First Change**: ${$e}\n`,E+=`**Last Change**: ${De}\n`,"pre-task"===Pe.firstChange.status&&Pe.firstChange.commitHash?E+=`**Pre-Task Commit**: ${Pe.firstChange.commitHash.substring(0,8)}\n`:Pe.firstChange.commitHash&&(E+=`**File Created During Task**: ${Pe.firstChange.commitHash.substring(0,8)}\n`),Pe.lastChange.commitHash&&(E+=`**Final Commit**: ${Pe.lastChange.commitHash.substring(0,8)}\n`)
|
|
3720
|
-
const Ae=
|
|
3728
|
+
const Ae=b.sourceToMove.get(Re),Fe=b.destToMove.get(Re)
|
|
3721
3729
|
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`),f&&!T?Pe.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=Pe.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${Pe.diffText}\n\n`:T&&Pe.hasDiff?(E+=`\n**Note**: File has changes (${Pe.diffText?Pe.diffText.split("\n").length:0} lines). `,E+=`Compare ${Pe.firstChange.commitHash?Pe.firstChange.commitHash.substring(0,8):"unknown"}..${Pe.lastChange.commitHash?Pe.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Pe.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${Pe.diffText}\n\n`,E+="---\n\n"}return h({success:!0,fileCount:C.size}),{content:[{type:"text",text:E}]}}catch(Ne){return s.error("Error in task file history tool",{error:Ne instanceof Error?Ne.stack:Ne+""}),h({success:!1,error:Ne instanceof Error?Ne.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,u.getErrorMessage)(Ne)}],isError:!0}}}
|
|
3722
3730
|
const i=t(9860),a=s(t(1943)),c=t(9671),l=t(2960),d=s(t(5967)),u=t(8824)},6928(module){module.exports=require("path")},6975(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
|
|
3723
3731
|
const r=t(1058)
|
|
@@ -3856,11 +3864,11 @@ if(e){const t=l.getCLISessionClient()
|
|
|
3856
3864
|
if(t){const r=await t.getByExternalId(e)
|
|
3857
3865
|
if(r?.workflowId){const e=await l.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
|
|
3858
3866
|
t?.approvalMode&&(w=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===w)try{const e=await l.proxyGet("/api/projects/"+m),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
|
|
3859
|
-
r&&(w=(0,a.getApprovalMode)(r))}catch(e){f.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){f.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const k="require-approval"===w&&"quick-edit"!==d.type?"pending_approval":"open",
|
|
3867
|
+
r&&(w=(0,a.getApprovalMode)(r))}catch(e){f.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){f.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const k="require-approval"===w&&"quick-edit"!==d.type?"pending_approval":"open",I={title:d.title,description:d.description,type:d.type,acceptanceCriteria:d.acceptanceCriteria,status:k,...d.planDocumentId&&{planDocumentId:d.planDocumentId},...g&&{cliOrigin:g}}
|
|
3860
3868
|
f.info("Creating request via request client",{projectId:m,title:d.title,type:d.type,criteriaCount:d.acceptanceCriteria.length})
|
|
3861
|
-
const
|
|
3862
|
-
f.debug("Create request response structure",{type:typeof
|
|
3863
|
-
const v=(0,o.extractDataFromResponse)(
|
|
3869
|
+
const b=await y.createRequest(I)
|
|
3870
|
+
f.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"})
|
|
3871
|
+
const v=(0,o.extractDataFromResponse)(b,{logger:f,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
|
|
3864
3872
|
let _,E={created:!1}
|
|
3865
3873
|
if(h?.workspaceManager)try{await h.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},f.info("Request branch initialized successfully",{requestId:C.id,branchName:E.branchName,title:C.title})}catch(e){f.warn("Failed to initialize request branch, will retry on first operation",{requestId:C.id,error:(0,i.getErrorMessage)(e)})}else"quick-edit"===d.type?f.info("Quick-edit request - skipping branch creation, will work directly on main",{requestId:C.id}):f.debug("No workspace manager available, branch creation deferred",{requestId:C.id})
|
|
3866
3874
|
f.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
|
|
@@ -3889,7 +3897,7 @@ return o(t,e),t})
|
|
|
3889
3897
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,t,r,n,o,s,h,g){const f=s.child({tool:"modify_file"})
|
|
3890
3898
|
try{const s=a.validateArgs(e,i.ModifyFileSchema),{taskId:u,operations:p,comment:m}=s
|
|
3891
3899
|
f.info("Processing modify-file operations",{taskId:u,operationCount:p.length,comment:m})
|
|
3892
|
-
const y=[],w=[],k=[],
|
|
3900
|
+
const y=[],w=[],k=[],I=[],b=[]
|
|
3893
3901
|
for(const e of p){const t={path:e.path,documentId:e.documentId}
|
|
3894
3902
|
switch(e.operationType){case"replace-string":y.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
|
|
3895
3903
|
break
|
|
@@ -3897,19 +3905,19 @@ case"insert-lines":w.push({...t,insertions:e.insertLines.insertions})
|
|
|
3897
3905
|
break
|
|
3898
3906
|
case"replace-lines":k.push({...t,replacements:e.replaceLines.replacements})
|
|
3899
3907
|
break
|
|
3900
|
-
case"delete-string":
|
|
3908
|
+
case"delete-string":I.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
|
|
3901
3909
|
break
|
|
3902
|
-
case"delete-lines":
|
|
3910
|
+
case"delete-lines":b.push({...t,lines:e.deleteLines.lines})}}const v=[]
|
|
3903
3911
|
if(y.length>0){f.info("Routing to replace-strings handler",{operationCount:y.length})
|
|
3904
3912
|
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:y,comment:m+" [via modify-file: replace-string]"},t,r,n,o,f,h,g)
|
|
3905
3913
|
v.push({type:"replace-string",result:e})}if(w.length>0){f.info("Routing to insert-lines handler",{operationCount:w.length})
|
|
3906
3914
|
const e=await(0,l.handleInsertLines)({taskId:u,operations:w,comment:m+" [via modify-file: insert-lines]"},t,r,n,o,f,h,g)
|
|
3907
3915
|
v.push({type:"insert-lines",result:e})}if(k.length>0){f.info("Routing to replace-lines handler",{operationCount:k.length})
|
|
3908
3916
|
const e=await(0,d.handleReplaceLines)({taskId:u,operations:k,comment:m+" [via modify-file: replace-lines]"},t,r,n,o,f,h,g)
|
|
3909
|
-
v.push({type:"replace-lines",result:e})}if(
|
|
3910
|
-
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:
|
|
3911
|
-
v.push({type:"delete-string",result:e})}if(
|
|
3912
|
-
const e=
|
|
3917
|
+
v.push({type:"replace-lines",result:e})}if(I.length>0){f.info("Routing delete-string to replace-strings handler",{operationCount:I.length})
|
|
3918
|
+
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:I,comment:m+" [via modify-file: delete-string]"},t,r,n,o,f,h,g)
|
|
3919
|
+
v.push({type:"delete-string",result:e})}if(b.length>0){f.info("Processing delete-lines operations",{operationCount:b.length})
|
|
3920
|
+
const e=b.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),s=await(0,d.handleReplaceLines)({taskId:u,operations:e,comment:m+" [via modify-file: delete-lines]"},t,r,n,o,f,h,g)
|
|
3913
3921
|
v.push({type:"delete-lines",result:s})}const C=v.some((e=>e.result.isError)),_=v.filter((e=>!e.result.isError)).length,E=v.filter((e=>e.result.isError)).length
|
|
3914
3922
|
let q="## Modify File Results\n\n"
|
|
3915
3923
|
q+="**Summary:**\n",q+=`- **Total operation types:** ${v.length}\n`,q+=`- **Successful:** ${_}\n`,q+=`- **Failed:** ${E}\n\n`
|
|
@@ -4214,12 +4222,9 @@ this.logger.info("ALCHEMY_INITIAL_BRANCH set, switching to worktree",{initialBra
|
|
|
4214
4222
|
try{await this.ensureWorkspaceReady(r),this.readonlyBranchCheckDone=!0,this.logger.info("Successfully switched to worktree from ALCHEMY_INITIAL_BRANCH",{requestId:r,worktreePath:this.currentWorktreePath})}catch(t){this.logger.warn("Failed to switch to worktree from ALCHEMY_INITIAL_BRANCH",{initialBranch:e,requestId:r,error:(0,i.getErrorMessage)(t)})}}hasExactConflictMarkers(e){return!(!e||!e.trim())&&[/^\s*<{7}(?:\s|$)/m,/^\s*={7}(?:\s|$)/m,/^\s*>{7}(?:\s|$)/m].some((t=>t.test(e)))}async initializeWorktreeManager(){try{await this.worktreeManager.initialize(),this.logger.debug("Initialized multi-agent workspace manager with worktrees")}catch(e){throw this.logger.error("Failed to initialize worktree manager",{error:e}),e}}setTaskCreator(e){this.taskCreator=e}async initializeRequest(e,t){const r=Date.now(),n=a.WorkspaceValidation.validateRequestId(e)
|
|
4215
4223
|
if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
|
|
4216
4224
|
const o=n.sanitized
|
|
4217
|
-
try{
|
|
4218
|
-
const
|
|
4219
|
-
|
|
4220
|
-
await this.mainGit.checkout(["-b",n,t]),this.logger.info("Created branch for request",{requestId:o,branchName:n,fromBranch:t}),await this.mainGit.checkout(e),this.logger.info("Returned to original branch after creation",{returnedTo:e,createdBranch:n})}this.workspaceStates.set(o,"initialized")
|
|
4221
|
-
const i=Date.now()-r
|
|
4222
|
-
this.metrics.recordValue("workspace.initialize",i),a.WorkspaceLogging.logOperation(this.logger,"info","Successfully initialized request with branch (no worktree)",e,"multi-agent","initializeRequest",{branchName:n,branchExisted:s,duration:i,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
|
|
4225
|
+
try{this.workspaceStates.set(o,"initialized")
|
|
4226
|
+
const t=Date.now()-r
|
|
4227
|
+
this.metrics.recordValue("workspace.initialize",t),a.WorkspaceLogging.logOperation(this.logger,"info","Successfully initialized request (branch deferred)",e,"multi-agent","initializeRequest",{duration:t,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
|
|
4223
4228
|
throw this.metrics.recordValue("workspace.initialize",n),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to initialize request",e,"multi-agent","initializeRequest",{error:(0,i.getErrorMessage)(t),duration:n}),t}}async ensureWorkspaceReady(e){const t=Date.now(),r=a.WorkspaceValidation.validateRequestId(e)
|
|
4224
4229
|
if(!r.isValid)throw Error("Invalid request ID: "+r.errors.join(", "))
|
|
4225
4230
|
const n=r.sanitized
|
|
@@ -4267,17 +4272,19 @@ try{this.currentRequestId===r&&await this.switchToMain()
|
|
|
4267
4272
|
const e=await this.worktreeManager.removeWorktree(r,!1)
|
|
4268
4273
|
if(!e.success)throw Error(e.message||"Failed to remove worktree")
|
|
4269
4274
|
this.logger.info("Successfully cancelled request",{requestId:r})}catch(e){throw this.logger.error("Failed to cancel request",{requestId:r,error:(0,i.getErrorMessage)(e)}),e}}getCurrentContext(){const e={requestId:this.currentRequestId,basePath:this.currentWorktreePath||this.basePath,branchName:this.currentRequestId?"requests/"+this.currentRequestId:"main",isMainBranch:!this.currentRequestId,mode:"multi-agent"}
|
|
4270
|
-
return this.logger.debug("getCurrentContext returning",{context:e}),e}resetCurrentContext(){this.currentRequestId&&this.logger.info("Resetting workspace context (session switch)",{prevRequestId:this.currentRequestId,prevWorktreePath:this.currentWorktreePath}),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit}async getWorkspaceInfo(e){try{const t=a.WorkspaceValidation.validateRequestId(e)
|
|
4275
|
+
return this.logger.debug("getCurrentContext returning",{context:e}),e}resetCurrentContext(){this.currentRequestId&&this.logger.info("Resetting workspace context (session switch)",{prevRequestId:this.currentRequestId,prevWorktreePath:this.currentWorktreePath}),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit,this.readonlyBranchCheckDone=!1}async getWorkspaceInfo(e){try{const t=a.WorkspaceValidation.validateRequestId(e)
|
|
4271
4276
|
if(!t.isValid)return null
|
|
4272
4277
|
const r=t.sanitized,n=await this.getWorktreeInfo(r)
|
|
4273
4278
|
return n?{requestId:r,path:n.worktreePath,branchName:n.branchName,isActive:this.currentRequestId===r,created:new Date,lastAccessed:new Date}:null}catch(t){return this.logger.error("Failed to get workspace info",{requestId:e,error:(0,i.getErrorMessage)(t)}),null}}async listActiveWorkspaces(){try{return(await this.worktreeManager.listActiveWorktrees()).map((e=>this.convertWorktreeInfoToWorkspaceInfo(e)))}catch(e){return this.logger.error("Failed to list active workspaces",{error:(0,i.getErrorMessage)(e)}),[]}}extractRequestIdFromBranch(e){const t=e.match(/^requests\/(.+)$/)
|
|
4274
4279
|
return t?t[1]:null}convertWorktreeInfoToWorkspaceInfo(e){return{requestId:e.requestId,path:e.worktreePath,branchName:e.branchName,isActive:this.currentRequestId===e.requestId,created:e.created,lastAccessed:e.lastAccessed}}async getWorktreeInfo(e){try{const t=e.replace(/[^a-zA-Z0-9_-]/g,"_")
|
|
4275
|
-
return this.worktreeManager.getWorktreeInfo(t)}catch(t){return void this.logger.warn("Failed to get worktree info",{requestId:e,error:(0,i.getErrorMessage)(t)})}}getMainGit(){return this.gitAdapter.getMainGit()}getCurrentGit(){return this.currentGit}async ensureReadonlyBranchIfNeeded(e,
|
|
4280
|
+
return this.worktreeManager.getWorktreeInfo(t)}catch(t){return void this.logger.warn("Failed to get worktree info",{requestId:e,error:(0,i.getErrorMessage)(t)})}}getMainGit(){return this.gitAdapter.getMainGit()}getCurrentGit(){return this.currentGit}async ensureReadonlyBranchIfNeeded(e,r,n,o){if(this.readonlyBranchCheckDone)return
|
|
4276
4281
|
this.readonlyBranchCheckDone=!0
|
|
4277
|
-
const
|
|
4278
|
-
if(
|
|
4282
|
+
try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
|
|
4283
|
+
if(r&&n){const t=await e.getSessionRequestId(n,this.logger)
|
|
4284
|
+
if(t)return await this.ensureWorkspaceReady(t),void this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready from session DB lookup",{requestId:t,sessionId:r.sessionId})}}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: session DB lookup failed, falling back to env var",{error:(0,i.getErrorMessage)(e)})}const s=process.env.ALCHEMY_INITIAL_BRANCH
|
|
4285
|
+
if(s){const e=s.match(/^requests\/(.+)$/)
|
|
4279
4286
|
if(e){const t=e[1]
|
|
4280
|
-
try{await this.ensureWorkspaceReady(t),this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready",{requestId:t})}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: failed to ensure workspace",{requestId:t,error:(0,i.getErrorMessage)(e)})}}}}async cleanup(){this.logger.info("Cleaning up multi-agent workspace manager"),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit}}},7645(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionAwareClient=void 0
|
|
4287
|
+
try{await this.ensureWorkspaceReady(t),this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready from env var",{requestId:t})}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: failed to ensure workspace",{requestId:t,error:(0,i.getErrorMessage)(e)})}}}}async cleanup(){this.logger.info("Cleaning up multi-agent workspace manager"),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit}}},7645(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionAwareClient=void 0
|
|
4281
4288
|
const r=t(4192),n=t(7163)
|
|
4282
4289
|
class o extends r.BaseApiClient{constructor(e,t,r,o,s,i){t.debug("ConnectionAwareClient constructor parameters:",{hasAuthToken:!!o,hasOptions:!!s,optionsType:s?typeof s:"undefined",options:s?JSON.stringify(s):"undefined",hasConnectionManager:!!i}),super(e,t,r,o,s),this.isGettingAuthToken=!1,this.connectionStatusManager=i||{isInOfflineMode(){return!1},isOffline(){return!1},setOfflineMode(){},async checkConnectivity(){return!0},getHealthCheckStats(){return{isOffline:!1,consecutiveFailures:0,currentBackoffMs:0,lastCheckTime:0}},cleanup(){}},o&&this.logger.debug("Client initialized with auth token",{clientType:this.constructor.name,tokenPrefix:o.substring(0,10)+"..."})
|
|
4283
4290
|
try{(0,n.debugTokenAccess)(this,"ConnectionAwareClient constructor")}catch(e){this.logger.debug("Error accessing token details during init",{error:e instanceof Error?e.message:e+""})}}setConnectionStatusManager(e){this.logger.debug("Setting connection status manager in ConnectionAwareClient"),this.connectionStatusManager=e}}exports.ConnectionAwareClient=o},7660(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.projectContextMiddleware=exports.ProjectContext=exports.ProjectIDFactory=exports.ProjectID=void 0
|
|
@@ -4295,20 +4302,20 @@ return o(t,e),t})
|
|
|
4295
4302
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,t,r,n,o,s,g,f,p){const m=g.child({tool:"manage_files"})
|
|
4296
4303
|
try{const h=a.validateArgs(e,i.ManageFilesSchema),{taskId:g,operations:y,comment:w}=h
|
|
4297
4304
|
m.info("Processing manage-files operations",{taskId:g,operationCount:y.length,comment:w})
|
|
4298
|
-
const k=[],
|
|
4305
|
+
const k=[],I=[],b=[],v=[]
|
|
4299
4306
|
for(const e of y)switch(e.operationType){case"create-directory":k.push({path:e.createDirectory.path})
|
|
4300
4307
|
break
|
|
4301
|
-
case"move-files":for(const t of e.moveFiles.moves)
|
|
4308
|
+
case"move-files":for(const t of e.moveFiles.moves)I.push(t)
|
|
4302
4309
|
break
|
|
4303
|
-
case"delete-files":
|
|
4310
|
+
case"delete-files":b.push(...e.deleteFiles.targets)
|
|
4304
4311
|
break
|
|
4305
4312
|
case"get-file-info":v.push({path:e.getFileInfo.path})}const C=[]
|
|
4306
4313
|
for(const e of k){m.info("Routing to create-directory handler",{path:e.path})
|
|
4307
4314
|
const s=await(0,c.handleCreateDirectory)({taskId:g,path:e.path,comment:w+" [via manage-files: create-directory]"},t,r,n,o,m,f,p)
|
|
4308
|
-
C.push({type:"create-directory",result:s})}if(
|
|
4309
|
-
const e=await(0,l.handleMoveFiles)({taskId:g,operations:
|
|
4310
|
-
C.push({type:"move-files",result:e})}if(
|
|
4311
|
-
const e=await(0,u.handleDeleteFiles)({taskId:g,operations:
|
|
4315
|
+
C.push({type:"create-directory",result:s})}if(I.length>0){m.info("Routing to move-files handler",{operationCount:I.length})
|
|
4316
|
+
const e=await(0,l.handleMoveFiles)({taskId:g,operations:I,comment:w+" [via manage-files: move-files]"},t,r,n,o,m,f,p)
|
|
4317
|
+
C.push({type:"move-files",result:e})}if(b.length>0){m.info("Routing to delete-files handler",{operationCount:b.length})
|
|
4318
|
+
const e=await(0,u.handleDeleteFiles)({taskId:g,operations:b,comment:w+" [via manage-files: delete-files]"},t,s,m,f,p)
|
|
4312
4319
|
C.push({type:"delete-files",result:e})}for(const e of v){m.info("Routing to get-file-info handler",{path:e.path})
|
|
4313
4320
|
const r=await(0,d.handleGetFileInfo)({path:e.path},t,m,f)
|
|
4314
4321
|
C.push({type:"get-file-info",result:r})}const _=C.some((e=>e.result.isError)),E=C.filter((e=>!e.result.isError)).length,q=C.filter((e=>e.result.isError)).length
|
|
@@ -4395,9 +4402,9 @@ const d=new Date,m=`${(d.getHours()+"").padStart(2,"0")}${(d.getMinutes()+"").pa
|
|
|
4395
4402
|
let w
|
|
4396
4403
|
if(s.ALCHEMY_SESSION_TAG=`mcp-${m}-${y}`,r(c,"Spawn env setup",{agent:t,initialBranch:g||"none",hasParentServer:!!l,sessionId:u||"new",attachMode:!!f}),w=f&&u&&n?["run","--attach",f,"--session",u,"--agent",t,n]:u&&n?["run","--session",u,"--agent",t,n]:n?["run","--agent",t,n]:["run","--agent",t],h){const e=w.findIndex((e=>e===n))
|
|
4397
4404
|
e>0?w.splice(e,0,"--model",h):w.push("--model",h)}r(c,"Spawning opencode",{args:w.map((e=>e===n?`[prompt:${e.length}chars]`:e)),model:h||"not specified",promptLength:n?.length,promptPreview:n?.slice(0,100),cwd:c,hasSessionId:!!u,hasParentServerUrl:!!l})
|
|
4398
|
-
const k=(0,a.join)(c||process.cwd(),".alchemy_lab"),
|
|
4399
|
-
let
|
|
4400
|
-
try{
|
|
4405
|
+
const k=(0,a.join)(c||process.cwd(),".alchemy_lab"),I=(0,a.join)(k,"spawn-stderr.log")
|
|
4406
|
+
let b
|
|
4407
|
+
try{b=(0,i.openSync)(I,"a")}catch{}const v=(0,o.spawn)("opencode",w,{detached:!0,stdio:["ignore","ignore",b??"ignore"],cwd:c||process.cwd(),env:s})
|
|
4401
4408
|
return v.unref(),p&&p(v.pid),{success:!0,pid:v.pid}}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
4402
4409
|
return m&&e instanceof Error&&m(e),{success:!1,error:t}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=n,exports.spawnJournalSubagent=function(e,t,r,o){return n({agent:"journal",prompt:`Generate a journal entry for request ${e}.\n\nSteps:\n1. Use ${t}__generate_request_journal tool with requestId: ${e}\n2. Write a concise narrative journal entry based on the returned data covering:\n - What was implemented and why\n - Key decisions and trade-offs made\n - Challenges encountered and solutions\n - Files modified and their purposes\n - How acceptance criteria were met\n3. Save as JOURNAL-${e}.md using ${t}__document_operations (operation: create, type: Report)\n\nKeep it story-focused and informative.`,cwd:r,parentServerUrl:o})},exports.spawnWorkSubagent=function(e,t,r){return n({agent:"work",prompt:e,cwd:t,parentServerUrl:r})}
|
|
4403
4410
|
const o=t(5317),s=t(8824),i=t(9896),a=t(6928)},8037(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListRequests=async function(e,t,i,a,c){const l=a.child({tool:"list_requests"}),d=c.startTimer("tool_execution_time")
|
|
@@ -4453,31 +4460,31 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
|
4453
4460
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4454
4461
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,t,r,n,o,s,i,f){const p=s.child({tool:"create_directory"}),m=Date.now()
|
|
4455
4462
|
let y,w,k=d.FileOperationPhase.VALIDATION
|
|
4456
|
-
const
|
|
4463
|
+
const I={toolName:"create-directory",operationName:"create",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"create-directory",metricsPrefix:"create_directory",successMessage:"Successfully created directory {path}",failureMessage:"Failed to create directory {path}"}
|
|
4457
4464
|
try{const s=d.validateArgs(e,l.CreateDirectorySchema),{taskId:u,path:h,comment:g}=s
|
|
4458
|
-
p.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,p,i,
|
|
4459
|
-
const{normalizedPath:
|
|
4465
|
+
p.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,p,i,I.metricsPrefix),t.getCurrentBranchContext&&await t.getCurrentBranchContext()
|
|
4466
|
+
const{normalizedPath:b,fullPath:v}=d.validateAndNormalizePath(h,t)
|
|
4460
4467
|
k=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("create_directory_phase",1,{phase:k})
|
|
4461
|
-
const C=await d.validateTaskId(u,
|
|
4462
|
-
q.taskPromoted&&p.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:
|
|
4463
|
-
const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:p,metrics:i,metricsPrefix:
|
|
4468
|
+
const C=await d.validateTaskId(u,b,r,p,i,I.metricsPrefix),_=C?.requestId,E=await d.validateWorkItemStates(u,b,r,o,t,p,i,I.metricsPrefix),q=await d.autoPromoteTaskStatus(u,C.status,_,E.request?.status,b,r,o,p,i,I.metricsPrefix)
|
|
4469
|
+
q.taskPromoted&&p.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&&p.info(`Auto-promoted request ${_} to in_progress for file operation`,{requestId:_,previousStatus:E.request?.status,newStatus:q.newRequestStatus,triggeringTaskId:u})
|
|
4470
|
+
const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:p,metrics:i,metricsPrefix:I.metricsPrefix})
|
|
4464
4471
|
if(!S.success){if(S.isLockConflict)return{content:[{type:"text",text:"\u274c "+S.error}],isError:!0}
|
|
4465
4472
|
throw Error(S.error)}let T=!1
|
|
4466
4473
|
try{T=(await a.default.stat(v)).isDirectory()}catch{T=!1}k=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("create_directory_phase",1,{phase:k})
|
|
4467
|
-
const{toolRecordId:M,localToolRecordId:R}=await d.createFileOperationRecords(u,_,t.projectId,
|
|
4468
|
-
y=M,w=M,k=
|
|
4474
|
+
const{toolRecordId:M,localToolRecordId:R}=await d.createFileOperationRecords(u,_,t.projectId,I.recordType,b,{directoryExists:T,userComment:g},r,n,p,i,I.metricsPrefix,f)
|
|
4475
|
+
y=M,w=M,k=I.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:k})
|
|
4469
4476
|
let P=T
|
|
4470
|
-
if(!T){await a.default.mkdir(v,{recursive:!0}),p.info("Successfully created directory "+
|
|
4477
|
+
if(!T){await a.default.mkdir(v,{recursive:!0}),p.info("Successfully created directory "+b)
|
|
4471
4478
|
try{const e=c.default.join(v,".gitkeep")
|
|
4472
4479
|
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),P=!0,p.info("Created .gitkeep file for Git tracking")}catch(e){p.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),P=!1}}const x=Date.now()-m
|
|
4473
4480
|
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})
|
|
4474
|
-
const O=`Create directory: ${
|
|
4475
|
-
k=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:k}),await d.updateFileOperationRecords(u,y,w,I
|
|
4481
|
+
const O=`Create directory: ${b} - ${g||"Create directory"}`,j=!T&&P?b+"/.gitkeep":b,$=await d.commitToGit(u,j,M,R,O,t,p,i,I.metricsPrefix)
|
|
4482
|
+
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,p,i,I.metricsPrefix)
|
|
4476
4483
|
const D=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4477
4484
|
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
|
|
4478
4485
|
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){p.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
|
|
4479
4486
|
if(i.recordValue("create_directory_time",s),i.incrementCounter("create_directory_errors",1),p.error("Error creating directory:",{error:(0,g.getErrorMessage)(o),time:s}),(y||w)&&e.taskId){k=d.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
4480
|
-
try{await d.updateFileOperationRecords(e.taskId,y,w,e.path,
|
|
4487
|
+
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,p,i,I.metricsPrefix)}catch(t){p.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,p,i,e,I)}}
|
|
4481
4488
|
const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(8824)},8317(e,exports,t){function r(e){const t=[]
|
|
4482
4489
|
return"write-file"===e.type&&e.metadata?.path?t.push(e.metadata.path):"replace-in-files"===e.type&&e.metadata?.operations?e.metadata.operations.forEach((e=>{e.path&&t.push(e.path)})):"move-files"===e.type&&e.metadata?.successfulOperations?e.metadata.successfulOperations.forEach((e=>{e.destination&&t.push(e.destination)})):"delete-files"===e.type&&e.metadata?.paths?t.push(...e.metadata.paths):"manage-files"===e.type&&e.metadata?.operations&&e.metadata.operations.forEach((e=>{e.createDirectory?.path&&t.push(e.createDirectory.path),e.moveFiles?.moves&&e.moveFiles.moves.forEach((e=>{e.destination&&t.push(e.destination)})),e.deleteFiles?.targets&&e.deleteFiles.targets.forEach((e=>{e.path&&t.push(e.path)}))})),[...new Set(t)]}function n(e){switch(e){case"write-file":return"\u{1f4dd} Write File"
|
|
4483
4490
|
case"replace-in-files":return"\u{1f504} Replace in Files"
|
|
@@ -4686,34 +4693,34 @@ return i(t,e),t})
|
|
|
4686
4693
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileHistory=async function(e,t,n,o,s){const i=o.child({tool:"file_history"}),a=s.startTimer("tool_execution_time"),m=Date.now()
|
|
4687
4694
|
try{let o
|
|
4688
4695
|
try{o=d.FileHistorySchema.parse(e)}catch(t){if(t instanceof u.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
|
|
4689
|
-
return i.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{path:a,limit:y,showDiff:w,showTraceability:k,branch:
|
|
4690
|
-
return
|
|
4696
|
+
return i.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{path:a,limit:y,showDiff:w,showTraceability:k,branch:I,commit:b,since:v}=o
|
|
4697
|
+
return b?(i.info("Getting diff for specific commit",{filePath:a,commit:b}),await async function(e,t,r,n){const o=r.git,s=c.normalize(e).replace(/\\/g,"/")
|
|
4691
4698
|
if(n.info("Getting full diff for commit",{filePath:e,commit:t}),!o)return{content:[{type:"text",text:"\u274c Git not initialized"}],isError:!0}
|
|
4692
4699
|
try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
|
|
4693
4700
|
if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
|
|
4694
4701
|
const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
|
|
4695
4702
|
let a="# File History - Commit Diff\n\n"
|
|
4696
|
-
return a+=`**File:** ${e}\n`,a+=`**Commit:** ${t.substring(0,8)}\n`,a+=`**Author:** ${n.author_name}\n`,a+=`**Date:** ${n.date}\n`,a+=`**Message:** ${n.message}\n\n`,i&&i.trim()?a+=`## Full Diff\n\n\`\`\`diff\n${i}\n\`\`\`\n`:a+="*No diff available for this commit*\n",{content:[{type:"text",text:a}]}}catch(r){return n.error("Failed to get commit diff",{error:r,commit:t,filePath:e}),{content:[{type:"text",text:`\u274c Failed to get diff for commit ${t}: ${(0,f.getErrorMessage)(r)}`}],isError:!0}}}(a,
|
|
4703
|
+
return a+=`**File:** ${e}\n`,a+=`**Commit:** ${t.substring(0,8)}\n`,a+=`**Author:** ${n.author_name}\n`,a+=`**Date:** ${n.date}\n`,a+=`**Message:** ${n.message}\n\n`,i&&i.trim()?a+=`## Full Diff\n\n\`\`\`diff\n${i}\n\`\`\`\n`:a+="*No diff available for this commit*\n",{content:[{type:"text",text:a}]}}catch(r){return n.error("Failed to get commit diff",{error:r,commit:t,filePath:e}),{content:[{type:"text",text:`\u274c Failed to get diff for commit ${t}: ${(0,f.getErrorMessage)(r)}`}],isError:!0}}}(a,b,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:y,showDiff:w,showTraceability:k,branch:I}),await async function(e,t,n,o,s,i,a,c,d,u,f){try{const{normalizedPath:m,fullPath:y}=p.validateAndNormalizePath(e,a)
|
|
4697
4704
|
try{await l.access(y)}catch(e){throw Error("File not found: "+m)}const w=a.git
|
|
4698
4705
|
if(!w)throw Error("Git is not available in this context")
|
|
4699
4706
|
let k={branch:null,requestId:null,isMain:!0}
|
|
4700
|
-
if(a.getCurrentBranchContext)try{k=await a.getCurrentBranchContext(),d.info("Current branch context detected",{branch:k.branch,requestId:k.requestId,isMain:k.isMain})}catch(e){d.warn("Could not get current branch context",{error:e})}let
|
|
4701
|
-
if(s)
|
|
4707
|
+
if(a.getCurrentBranchContext)try{k=await a.getCurrentBranchContext(),d.info("Current branch context detected",{branch:k.branch,requestId:k.requestId,isMain:k.isMain})}catch(e){d.warn("Could not get current branch context",{error:e})}let I=[],b=""
|
|
4708
|
+
if(s)I=await r(w,m,t,n,o,s,i,c,d,u),b=`## File History: ${m} (Branch: ${s})\n\n`
|
|
4702
4709
|
else{if(k.isMain&&!o)return d.info("Showing request-level timeline on main branch"),{content:[{type:"text",text:await(0,g.getRequestTimelineForFile)(w,m,c,d,u)}]}
|
|
4703
4710
|
if(k.requestId)return d.info("Showing operation-level detail on request branch",{requestId:k.requestId}),{content:[{type:"text",text:await(0,g.getOperationDetailForFile)(m,k.requestId,c,d,u)}]}
|
|
4704
4711
|
{const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
|
|
4705
4712
|
if(!i.isMain&&i.branch){const g=await r(e,t,n,o,s,i.branch,a,c,l,d)
|
|
4706
4713
|
u.push(...g),g.length>0&&h.push(i.branch+" (current)")}const g=await r(e,t,n,o,s,"main",a,c,l,d),f=new Set(u.map((e=>e.hash))),p=g.filter((e=>!f.has(e.hash)))
|
|
4707
4714
|
return u.push(...p),g.length>0&&h.push("main"),u.sort(((e,t)=>new Date(t.date).getTime()-new Date(e.date).getTime())),{versions:u.slice(0,n),sources:h}}(w,m,t,n,o,k,i,c,d,u)
|
|
4708
|
-
|
|
4709
|
-
const v=
|
|
4710
|
-
v>t?
|
|
4711
|
-
try{
|
|
4712
|
-
for(let e=0;e<
|
|
4713
|
-
if(
|
|
4715
|
+
I=e.versions,b=`## File History: ${m} (Combined View)\n\n`,b+=`**Current Context:** ${k.isMain?"main":`${k.branch} (${k.requestId})`}\n`,b+=`**History Sources:** ${e.sources.join(", ")}\n\n`}}if(0===I.length)return b+="\u274c **No history found**\n\nThis file has no git history. It may be:\n- A new file that hasn't been committed\n- Located outside the git repository\n- The path may be incorrect\n- No history exists in the specified branch context",{content:[{type:"text",text:b}]}
|
|
4716
|
+
const v=I.length,C=Math.min(I.length,t)
|
|
4717
|
+
v>t?b+=`\u{1f4ca} **Summary:** ${v} versions found, showing ${C} most recent\n\n`:v>0&&(b+=`\u{1f4ca} **Summary:** ${v} version${v>1?"s":""} found\n\n`),b+=`**Total Versions:** ${I.length}\n`,b+="**Current File Size:** "
|
|
4718
|
+
try{b+=(await l.stat(y)).size+" bytes\n"}catch{b+="Unknown\n"}b+="\n"
|
|
4719
|
+
for(let e=0;e<I.length;e++){const t=I[e]
|
|
4720
|
+
if(b+=`### Version ${e+1} (${t.hash.substring(0,8)})\n`,t.branch&&(b+=`- **Branch:** ${t.branch}\n`),b+=`- **Author:** ${t.author}\n`,b+=`- **Date:** ${t.date}\n`,b+=`- **Message:** ${t.message}\n`,o&&t.traceability&&(b+=`\n${(0,h.formatTraceabilityInfo)(t.traceability)}\n`),n&&t.diff){const e=t.diff.split("\n")
|
|
4714
4721
|
let r=0,n=0
|
|
4715
4722
|
for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
|
|
4716
|
-
|
|
4723
|
+
b+=`\n**Changes:**${r>0||n>0?` (Added ${r} lines, removed ${n} lines)`:""}\n\`\`\`diff\n${t.diff}\n\`\`\`\n`}b+="\n"}return b+="\u{1f4a1} **Tips:**\n",b+="- Use `file-recover` with a commit hash to restore the file to a previous version\n",b+='- Use `{"branch": "main"}` to see only main branch history\n',b+='- Use `{"branch": "req123456"}` to see only request branch history\n\n',d.info("Branch-aware file history retrieved successfully",{path:m,versions:I.length,targetBranch:s,currentBranch:k.branch,duration:Date.now()-f}),u.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:b}]}}catch(e){throw e}}(a,y,w,k,I,v,t,n,i,s,m))}catch(e){const t=Date.now()-m
|
|
4717
4724
|
return i.error("File/Document history operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),a({tool:"file_history",success:!1}),s.incrementCounter("file_history_errors",1),{content:[{type:"text",text:"\u274c **History Operation Failed:** "+(0,f.getErrorMessage)(e)}],isError:!0}}}
|
|
4718
4725
|
const c=a(t(6928)),l=a(t(1943)),d=t(6183),u=t(1569),h=t(1181),g=t(2085),f=t(8824),p=a(t(5967)),m=a(t(7478)),{getCurrentBranch:y}=m},8850(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4719
4726
|
const r=t(6183),n=t(6891)
|
|
@@ -5045,10 +5052,10 @@ continue}const t=(0,h.findMatches)(s,n,m,100,e.path)
|
|
|
5045
5052
|
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(m?" (tried fuzzy matching)":""),a.success=!1
|
|
5046
5053
|
const e=(0,h.findSimilarMatches)(s,n,5,.3)
|
|
5047
5054
|
e.length>0&&(a.similarMatches=e),y.failedReplacements++}else"unique"===i&&t.length>1?(a.error=`Multiple matches found (${t.length}) - expected unique match`,a.success=!1,a.details=t.map(r),y.failedReplacements++):f.push({matches:t,newText:o,matchMode:i,repResult:a})}catch(e){a.error=(0,k.getErrorMessage)(e),a.success=!1,y.failedReplacements++}y.replacements.push(a)}let w=s
|
|
5048
|
-
const
|
|
5049
|
-
for(const e of f)for(const t of e.matches)
|
|
5050
|
-
|
|
5051
|
-
for(const{match:e,newText:t,repResult:n}of
|
|
5055
|
+
const I=[]
|
|
5056
|
+
for(const e of f)for(const t of e.matches)I.push({match:t,newText:e.newText,repResult:e.repResult})
|
|
5057
|
+
I.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5058
|
+
for(const{match:e,newText:t,repResult:n}of I)w=(0,h.replaceMatch)(w,e,t),n.success?(n.lines.push(e.line),n.details.push(r(e))):(n.success=!0,n.matchType=e.matchType,n.lines=[e.line],n.details=[r(e)],y.successfulReplacements++)
|
|
5052
5059
|
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),p&&(n.documentFileManager.markForSync(d),await n.documentFileManager.syncDocument(d))),i&&(y.externalEditWarning=i),a&&(y.externalEditDebugInfo={detectionRan:!0,...a}),y.success=0===y.failedReplacements}catch(e){y.error=(0,k.getErrorMessage)(e),y.success=!1,y.failedReplacements=g.length,y.replacements=g.map((e=>({old:e.old,new:e.new,success:!1,error:y.error})))}return y}var o,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
5053
5060
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5054
5061
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||(o=function(e){return o=Object.getOwnPropertyNames||function(e){var t=[]
|
|
@@ -5057,47 +5064,47 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
5057
5064
|
var t={}
|
|
5058
5065
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
5059
5066
|
return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
5060
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFiles=async function(e,t,r,o,s,i,a,c){const
|
|
5067
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFiles=async function(e,t,r,o,s,i,a,c){const I=i.child({tool:"replace_in_files"}),b=Date.now()
|
|
5061
5068
|
let v,C=u.FileOperationPhase.VALIDATION
|
|
5062
5069
|
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)
|
|
5063
5070
|
const i=u.validateArgs(e,d.ReplaceInFilesSchema),{taskId:_,operations:E,fuzzy_match:q=!0,comment:S}=i
|
|
5064
|
-
|
|
5071
|
+
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})
|
|
5065
5072
|
const T=E.filter((e=>e.documentId)).map((e=>e.documentId))
|
|
5066
|
-
if(T.length>0&&t.apiClient)try{await(0,m.ensureDocumentsNotLocked)(T,t.apiClient,
|
|
5073
|
+
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}
|
|
5067
5074
|
throw e}C=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5068
5075
|
const M=E[0],R=M.documentId?"document:"+M.documentId:M.path
|
|
5069
5076
|
let P=Date.now()
|
|
5070
|
-
const x=await u.validateTaskId(_,R,r,
|
|
5077
|
+
const x=await u.validateTaskId(_,R,r,I,a,"replace_in_files")
|
|
5071
5078
|
Date.now()
|
|
5072
5079
|
const O=x?.requestId,j=E.some((e=>e.path))
|
|
5073
5080
|
let $=!1
|
|
5074
5081
|
if(j&&O){P=Date.now()
|
|
5075
|
-
const e=await u.validateWorkItemStates(_,R,r,s,t,
|
|
5082
|
+
const e=await u.validateWorkItemStates(_,R,r,s,t,I,a,"replace_in_files")
|
|
5076
5083
|
Date.now(),P=Date.now()
|
|
5077
|
-
const n=await u.autoPromoteTaskStatus(_,x.status,O,e.request?.status,R,r,s,
|
|
5078
|
-
n.taskPromoted&&
|
|
5079
|
-
const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:O,context:t,operation:"replace_in_files",logger:
|
|
5084
|
+
const n=await u.autoPromoteTaskStatus(_,x.status,O,e.request?.status,R,r,s,I,a,"replace_in_files")
|
|
5085
|
+
n.taskPromoted&&I.info("Auto-promoted task to in_progress",{taskId:_,requestId:O,previousStatus:x.status,newStatus:n.newTaskStatus}),Date.now(),P=Date.now()
|
|
5086
|
+
const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:O,context:t,operation:"replace_in_files",logger:I,metrics:a,metricsPrefix:"replace_in_files"})
|
|
5080
5087
|
if(!o.success){if(o.isLockConflict)return{content:[{type:"text",text:"\u274c "+o.error}],isError:!0}
|
|
5081
|
-
throw Error(o.error)}Date.now(),$=!0}if(T.length>0&&O)try{await(0,f.validateRequestStatusForDocumentOperation)(O,s,
|
|
5088
|
+
throw Error(o.error)}Date.now(),$=!0}if(T.length>0&&O)try{await(0,f.validateRequestStatusForDocumentOperation)(O,s,I,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5082
5089
|
throw e}P=Date.now()
|
|
5083
5090
|
const D=new Map
|
|
5084
|
-
if(
|
|
5091
|
+
if(I.info("\u{1f50d} Starting external edit detection",{hasFileOperations:j,hasGit:!!t.git,operationCount:E.length}),j&&t.git)for(const e of E)if(e.path&&!e.documentId)try{const r=u.validateAndNormalizePath(e.path,t),n=await l.default.readFile(r.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:q,s=[]
|
|
5085
5092
|
for(const t of e.replacements){const r=(0,h.findMatches)(n,t.old,o,100,e.path)
|
|
5086
5093
|
s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,r.fullPath)
|
|
5087
|
-
|
|
5088
|
-
const i=await(0,w.detectExternalEdits)(t.git,o,
|
|
5089
|
-
|
|
5090
|
-
const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:O,taskId:_,workspaceManager:t.workspaceManager},
|
|
5091
|
-
e.userChangesCommitted&&(
|
|
5092
|
-
const{toolRecordId:A}=await u.createFileOperationRecords(_,O,t.projectId,"replace-in-files",R,{operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,userComment:S},r,o,
|
|
5094
|
+
I.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
|
|
5095
|
+
const i=await(0,w.detectExternalEdits)(t.git,o,I)
|
|
5096
|
+
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(),P=Date.now(),j&&t.git)try{I.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
|
|
5097
|
+
const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:O,taskId:_,workspaceManager:t.workspaceManager},I,a)
|
|
5098
|
+
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(),P=Date.now(),C=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5099
|
+
const{toolRecordId:A}=await u.createFileOperationRecords(_,O,t.projectId,"replace-in-files",R,{operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,userComment:S},r,o,I,a,"replace_in_files",c)
|
|
5093
5100
|
v=A,Date.now(),P=Date.now(),C=u.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5094
5101
|
const F=[],N=[]
|
|
5095
5102
|
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)
|
|
5096
5103
|
F.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&N.push(o.path)}Date.now(),P=Date.now()
|
|
5097
|
-
const L=E.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),z=await u.handleMultiFileGitCommit(_,L,F,N.length,{operationType:"Replace in files",toolRecordId:A||v||"unknown",successField:"successfulReplacements",logger:
|
|
5104
|
+
const L=E.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),z=await u.handleMultiFileGitCommit(_,L,F,N.length,{operationType:"Replace in files",toolRecordId:A||v||"unknown",successField:"successfulReplacements",logger:I,metrics:a,metricsPrefix:"replace_in_files"},t),B=z.commitHash
|
|
5098
5105
|
Date.now(),Date.now()
|
|
5099
5106
|
const H=F.filter((e=>e.success)).length,W=F.length-H,U=F.reduce(((e,t)=>e+t.successfulReplacements),0),G=F.reduce(((e,t)=>e+t.failedReplacements),0),V=F.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,replacements:e.replacements.map((e=>({old_str:e.old,new_str:e.new,success:e.success,error:e.error,matchesFound:e.matchesFound,matchType:e.matchType,lines:e.lines})))}))),J=F.filter((e=>e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements}))),K=F.filter((e=>!e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,error:e.error,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements})))
|
|
5100
|
-
await o.updateToolRecord(v,{metadata:{path:R,status:0===W?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:K,successfulReplacements:U,failedReplacements:G,processingTime:Date.now()-
|
|
5107
|
+
await o.updateToolRecord(v,{metadata:{path:R,status:0===W?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:K,successfulReplacements:U,failedReplacements:G,processingTime:Date.now()-b,userComment:S,...z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}}})
|
|
5101
5108
|
const Y=await async function(e,t,r,n,o,s){const i=e.filter((e=>e.success)).length,a=e.length-i,c=e.filter((e=>!e.success&&!e.error&&e.successfulReplacements>0)).length
|
|
5102
5109
|
let l="## Replace In Files - Batch Results\n\n"
|
|
5103
5110
|
if(o.getCurrentBranchContext)try{const e=await o.getCurrentBranchContext()
|
|
@@ -5110,8 +5117,8 @@ for(const e of o)l+=`- \u2705 \`${e.old.substring(0,40)}${e.old.length>40?"...":
|
|
|
5110
5117
|
if(s.length>0){l+="\n**Failed Replacement Details:**\n"
|
|
5111
5118
|
for(const e of s)l+=`- \u274c \`${e.old.substring(0,40)}${e.old.length>40?"...":""}\` \u2192 \`${e.new.substring(0,40)}${e.new.length>40?"...":""}\`: ${e.error}\n`,e.details&&e.details.length>0&&(l+=" **Candidates found:**\n",l+=e.details.slice(0,5).map((e=>` - Line ${e.line}: \`${e.actually_matched.substring(0,40)}${e.actually_matched.length>40?"...":""}\` (${e.match_type})`)).join("\n")+"\n",e.details.length>5&&(l+=` ... and ${e.details.length-5} more matches\n`)),e.similarMatches&&e.similarMatches.length>0&&(l+=" **Did you mean? (Similar matches found):**\n",l+=e.similarMatches.map((e=>` - Line ${e.line}: \`${e.text.substring(0,60)}${e.text.length>60?"...":""}\` (${e.reason}, similarity: ${(100*e.similarity).toFixed(0)}%)`)).join("\n")+"\n")}l+="\n"}const d=e.filter((e=>"document"===e.type&&(e.success||e.successfulReplacements>0)))
|
|
5112
5119
|
return d.length>0&&(l+=`\n**Document Changes:** ${d.length} modified document(s) synced back to tracking system.\n`),o.workspaceManager?.largeFileWarning&&(l+=o.workspaceManager.largeFileWarning,o.workspaceManager.largeFileWarning=""),l}(F,B,U,G,t,v)
|
|
5113
|
-
return{content:[{type:"text",text:Y}],isError:0===U}}catch(e){const t=Date.now()-
|
|
5114
|
-
if(
|
|
5120
|
+
return{content:[{type:"text",text:Y}],isError:0===U}}catch(e){const t=Date.now()-b
|
|
5121
|
+
if(I.error("Replace in files batch operation failed",{error:e instanceof Error?e.stack:e+"",duration:t,phase:C}),v)try{await o.updateToolRecord(v,{metadata:{status:"failed",error:(0,k.getErrorMessage)(e),phase:C,duration:t}})}catch(e){}return a.incrementCounter("replace_in_files_errors",1,{phase:C}),{content:[{type:"text",text:"\u274c **Replace In Files Failed:** "+(0,k.getErrorMessage)(e)}],isError:!0}}}
|
|
5115
5122
|
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(6183)),u=a(t(5967)),h=t(3626),g=t(9860),f=t(5003),p=t(7478),m=t(9949),y=t(9947),w=t(1318),k=t(8824)},9470(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
|
|
5116
5123
|
const t=e.trim()
|
|
5117
5124
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|