alchemylab 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/939.js +3 -3
- package/dist/cli.js +137 -110
- package/dist/http-server.js +680 -717
- package/dist/index.js +582 -619
- package/dist/mcp-direct.js +813 -850
- package/package.json +3 -2
package/dist/mcp-direct.js
CHANGED
|
@@ -14,13 +14,13 @@ u.info("Raw request verification response data",{responseData:JSON.stringify(t)}
|
|
|
14
14
|
const r=(0,o.extractDataFromResponse)(t,{logger:u,operationName:"verifyRequestExists",throwOnNoData:!0})
|
|
15
15
|
g="object"==typeof r&&null!==r&&"data"in r?r.data:r,u.info(`Verified request ${a.requestId} exists`,{requestId:a.requestId,projectId:l,requestStatus:g.status})}catch(e){throw new n.NotFoundError(`Request ${a.requestId} not found in project ${l}. Please provide a valid request ID.`,{requestId:a.requestId,projectId:l,originalError:e})}if(["pending_approval","completed","canceled","ready_for_review","ready_for_merge","reverted"].includes(g.status)){const e={pending_approval:"is pending approval. Approve the request before creating tasks.",completed:"is already completed and merged. Create a new request for additional changes.",canceled:"was canceled. Create a new request or reopen this one if needed.",ready_for_review:"is being tested. Wait for test results before making changes.",ready_for_merge:"is ready to merge. Call merge to complete it.",reverted:"was reverted and cannot accept new tasks. Re-complete the request first or create a new request."}[g.status]||`has status '${g.status}' and cannot accept new tasks.`
|
|
16
16
|
throw u.warn(`Task creation blocked on ${g.status} request`,{requestId:a.requestId,requestStatus:g.status,projectId:l}),new n.ValidationError(`The request ID "${a.requestId}" ${e}`,{requestId:a.requestId,requestStatus:g.status,reason:"request_"+g.status})}u.info("Request status validation passed for "+a.requestId,{requestId:a.requestId,requestStatus:g.status,projectId:l})
|
|
17
|
-
const
|
|
17
|
+
const p=i.getTaskClient()
|
|
18
18
|
u.info("Creating task with project context",{projectId:l})
|
|
19
|
-
const
|
|
20
|
-
u.info("Task input prepared",{taskInput:JSON.stringify(
|
|
21
|
-
const m=await
|
|
19
|
+
const f={requestId:a.requestId,projectId:l,title:a.title,description:a.description,status:"pending",...d&&{cliOrigin:d}}
|
|
20
|
+
u.info("Task input prepared",{taskInput:JSON.stringify(f)}),u.info("Creating task via task client",{projectId:l,requestId:a.requestId,title:a.title})
|
|
21
|
+
const m=await p.createTask(f)
|
|
22
22
|
u.debug("Task creation response structure",{type:typeof m,isArray:Array.isArray(m),hasData:null!=m,properties:m?Object.keys(m):[],dataPreview:m?JSON.stringify(m).substring(0,200)+"...":"null"})
|
|
23
|
-
const y=(0,o.extractDataFromResponse)(m,{logger:u,operationName:"createTask",defaultValue:{id:"tas"+Date.now().toString().substring(5,11),title:
|
|
23
|
+
const y=(0,o.extractDataFromResponse)(m,{logger:u,operationName:"createTask",defaultValue:{id:"tas"+Date.now().toString().substring(5,11),title:f.title,description:f.description,status:"pending",requestId:f.requestId,projectId:l,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}),w="data"in y?y.data:y,k=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),b=w.title||f.title,I=w.description||f.description,v=w.status||"pending",C=w.requestId||f.requestId
|
|
24
24
|
let _,E="unknown"
|
|
25
25
|
w&&"object"==typeof w&&"_workingEndpoint"in w&&(E=w._workingEndpoint),u.info("Successfully extracted task data from response",{taskId:k,requestId:C,title:b})
|
|
26
26
|
try{const e=i.getToolRecordClient()
|
|
@@ -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),
|
|
48
|
-
!(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,b.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new
|
|
47
|
+
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),g=t(9567),p=t(3444),f=t(7660),m=t(1253),y=t(5172),w=t(7976),k=i(t(7478)),b=t(4139),I=new Set,v=t(9860),C=t(1472),_=t(3328),E=t(8955),q=t(3217),S=t(8411),T=t(5278),M=t(446),R=t(9060),P=t(8824),x=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),O=process.stdout.write,j=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
|
|
48
|
+
!(0,p.isDebugToolsEnabled)()||j&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,p.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&x.debug("Stdout output",{content:e.substring(0,100),length:e.length}),O.call(process.stdout,e)}catch(e){return x.error("Error in safeStdoutWrite",{error:e+""}),!0}})
|
|
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,b.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new f.ProjectContext(e,t),this.tokenManager=new m.TokenManager(t,e,{remoteServerUrl:n}),this.lockOverrideManager=new M.LockOverrideManager(t),this.configManager=new R.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.interceptConnectMethod(),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
|
|
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()
|
|
@@ -184,12 +184,12 @@ case"quick-edit":return"\u26a1"
|
|
|
184
184
|
default:return"\u{1f4e6}"}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearchRequests=async function(e,t,c,l,d){const u=l.child({tool:"search_requests"}),h=d.startTimer("tool_execution_time")
|
|
185
185
|
try{const{query:a,searchIn:l="all",filters:g={}}=e.search||e
|
|
186
186
|
if(!a||0===a.trim().length)throw new i.ValidationError("Search query is required")
|
|
187
|
-
const
|
|
188
|
-
if(!
|
|
189
|
-
u.info("Searching requests",{query:a,searchIn:l,filters:g,projectId:
|
|
190
|
-
const
|
|
191
|
-
g.status&&(
|
|
192
|
-
const m=c.getRequestClient(),y=await m.listRequests(
|
|
187
|
+
const p=t.projectId
|
|
188
|
+
if(!p)throw new i.ValidationError("Project ID is required for searching requests")
|
|
189
|
+
u.info("Searching requests",{query:a,searchIn:l,filters:g,projectId:p})
|
|
190
|
+
const f={limit:g.limit||100,offset:g.offset||0,sortBy:"updated_at",sortDirection:"desc"}
|
|
191
|
+
g.status&&(f.status=g.status),g.type&&(f.type=g.type),g.dateFrom&&(f.dateFrom=g.dateFrom),g.dateTo&&(f.dateTo=g.dateTo),c.setProjectId(p)
|
|
192
|
+
const m=c.getRequestClient(),y=await m.listRequests(f)
|
|
193
193
|
u.debug("Fetched requests for search",{count:y.length})
|
|
194
194
|
const w=[],k=a.toLowerCase()
|
|
195
195
|
for(const e of y){const t=[]
|
|
@@ -231,9 +231,9 @@ break
|
|
|
231
231
|
default:t="open"}else t="open"
|
|
232
232
|
const n=Array.isArray(e.acceptanceCriteria)?e.acceptanceCriteria.map(r):[]
|
|
233
233
|
return{id:e.id,title:e.title,description:e.description,type:e.type,status:t,acceptanceCriteria:n,createdAt:e.createdAt,updatedAt:e.updatedAt,...e.projectId?{projectId:e.projectId}:{},...e.completionSummary?{completionSummary:e.completionSummary}:{},...e.completedAt?{completedAt:e.completedAt}:{},...e.metadata?{metadata:e.metadata}:{},...e.lockInfo?{lockInfo:e.lockInfo}:{}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.adaptApiAcceptanceCriterionToDomain=r,exports.adaptApiRequestToDomain=n,exports.adaptApiRequestsToDomain=function(e){return e.map(n)}
|
|
234
|
-
const o=t(6756)},355(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,d,u,h,g){const
|
|
235
|
-
|
|
236
|
-
const
|
|
234
|
+
const o=t(6756)},355(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,d,u,h,g){const p=h.child({tool:"complete_task"})
|
|
235
|
+
p.info("Completing task",{args:e})
|
|
236
|
+
const f=g.startTimer("tool_handler_duration")
|
|
237
237
|
try{const{taskId:o,summary:h}=function(e){if(void 0!==e.verificationSteps){const{verificationSteps:t,...r}=e
|
|
238
238
|
e=r}try{return r.CompleteTaskSchema.parse(e)}catch(e){if(e instanceof i.ZodError&&e.errors.length>0)throw new n.ValidationError(e.errors[0].message)
|
|
239
239
|
throw new n.ValidationError("Invalid input: "+(0,l.getErrorMessage)(e))}}(e),m=d.projectId
|
|
@@ -242,35 +242,35 @@ g.incrementCounter("complete_task_attempts",1,{taskId:o}),u.setProjectId(m)
|
|
|
242
242
|
const y=u.getTaskClient()
|
|
243
243
|
let w
|
|
244
244
|
try{const e=await y.getTask(o)
|
|
245
|
-
|
|
246
|
-
const t=(0,s.extractDataFromResponse)(e,{logger:
|
|
247
|
-
w="data"in t?t.data:t,
|
|
245
|
+
p.info("Raw task response data",{responseData:JSON.stringify(e)}),p.debug("Task response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
|
|
246
|
+
const t=(0,s.extractDataFromResponse)(e,{logger:p,operationName:"getTask",throwOnNoData:!0})
|
|
247
|
+
w="data"in t?t.data:t,p.info("Current task status: "+w.status,{taskId:o,currentStatus:w.status})}catch(e){if(e instanceof n.ValidationError)throw e
|
|
248
248
|
throw new n.NotFoundError(`Task ${o} not found in project ${m}. Please provide a valid task ID.`,{taskId:o,projectId:m,originalError:e})}if("completed"===w.status){const e="Task is already completed."
|
|
249
|
-
throw
|
|
250
|
-
throw
|
|
249
|
+
throw p.warn(e,{taskId:o,currentStatus:w.status}),new n.ValidationError(e)}if("canceled"===w.status){const e="Task is canceled and can not be completed."
|
|
250
|
+
throw p.warn(e,{taskId:o,currentStatus:w.status}),new n.ValidationError(e)}if(d.multiAgentMode&&w.requestId){p.debug("Multi-agent mode: checking request lock for task operation",{taskId:o,requestId:w.requestId})
|
|
251
251
|
try{const e=u.getRequestClient(),{sessionTag:t}=(0,a.getGlobalClientInfo)(),r=await e.getRequestLockStatus(w.requestId)
|
|
252
252
|
if(r.isLocked){if(r.lockedBySessionTag!==t){let e=`Request ${w.requestId} is locked by another agent (${r.lockedBySessionTag}). `
|
|
253
|
-
throw r.isExpired?e+="Lock has expired but cleanup may be pending. ":e+=`Lock expires in: ${r.timeRemainingFormatted}. `,e+="Only the agent that locked the request can modify its tasks.",new n.ValidationError(e,{taskId:o,requestId:w.requestId,lockedByAgent:r.lockedBySessionTag,currentAgent:t,timeRemainingMs:r.timeRemainingMs,isExpired:r.isExpired})}}else{
|
|
253
|
+
throw r.isExpired?e+="Lock has expired but cleanup may be pending. ":e+=`Lock expires in: ${r.timeRemainingFormatted}. `,e+="Only the agent that locked the request can modify its tasks.",new n.ValidationError(e,{taskId:o,requestId:w.requestId,lockedByAgent:r.lockedBySessionTag,currentAgent:t,timeRemainingMs:r.timeRemainingMs,isExpired:r.isExpired})}}else{p.debug("Lock not held, auto-acquiring for task completion",{requestId:w.requestId,sessionTag:t})
|
|
254
254
|
const r=await e.lockRequest(w.requestId,t)
|
|
255
255
|
if(!r.locked)throw new n.ValidationError(`Failed to acquire lock for request ${w.requestId}. Another agent may have just locked it. Try again shortly.`,{taskId:o,requestId:w.requestId})
|
|
256
|
-
|
|
257
|
-
throw
|
|
256
|
+
p.info("Auto-acquired lock for task completion",{requestId:w.requestId,sessionTag:t,lockedAt:r.lockedAt})}p.info("Request lock validation passed",{taskId:o,requestId:w.requestId,sessionTag:t})}catch(e){if(e instanceof n.ValidationError)throw e
|
|
257
|
+
throw p.error("Failed to check request lock status",{taskId:o,requestId:w.requestId,error:(0,l.getErrorMessage)(e)}),new n.ValidationError("Failed to verify request lock status: "+(0,l.getErrorMessage)(e),{taskId:o,requestId:w.requestId})}}else p.debug("Single-agent mode or task without requestId: skipping lock check",{taskId:o,isMultiAgent:(0,c.isMultiAgentModeEnabled)(),hasRequestId:!!w.requestId})
|
|
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}),
|
|
262
|
-
if(k)try{(await k.status()).isClean()||(b=(await k.commit(`Complete task ${o}: ${h}`)).commit,
|
|
261
|
+
k=simpleGit({baseDir:e.basePath,binary:d.gitBinary}),p.debug("Using workspace-aware git instance for task completion",{taskId:o,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let b=null
|
|
262
|
+
if(k)try{(await k.status()).isClean()||(b=(await k.commit(`Complete task ${o}: ${h}`)).commit,p.info("Created commit for task completion",{taskId:o,commitId:b}))}catch(e){p.warn("Failed to commit changes",{error:(0,l.getErrorMessage)(e)})}let I=null
|
|
263
263
|
try{const e=u.getToolRecordClient()
|
|
264
|
-
e&&(I={id:(await e.createToolRecord({taskId:o,requestId:w.requestId,projectId:m,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:h,lastCommit:b,completedAt:(new Date).toISOString()},note:`Completed task: ${h.substring(0,100)}${h.length>100?"...":""}`})).id})}catch(e){
|
|
265
|
-
|
|
264
|
+
e&&(I={id:(await e.createToolRecord({taskId:o,requestId:w.requestId,projectId:m,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:h,lastCommit:b,completedAt:(new Date).toISOString()},note:`Completed task: ${h.substring(0,100)}${h.length>100?"...":""}`})).id})}catch(e){p.error("Failed to create tool record for task completion, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:o,requestId:w.requestId})}try{const e=w.metadata||{},t=(new Date).toISOString(),r={status:"completed",metadata:{...e,lastCommit:b,completionSummary:h,completionRecordId:I?.id,completedAt:t}},n=await y.updateTask(o,r)
|
|
265
|
+
p.info("Raw task update response data",{responseData:JSON.stringify(n)}),p.debug("Task update response structure",{type:typeof n,isArray:Array.isArray(n),hasData:null!=n,properties:n?Object.keys(n):[],dataPreview:n?JSON.stringify(n).substring(0,200)+"...":"null"}),(0,s.extractDataFromResponse)(n,{logger:p,operationName:"updateTask",defaultValue:{id:o,status:"completed"}}),p.info("Successfully completed task",{taskId:o,recordId:I?.id})
|
|
266
266
|
const i=w.requestId
|
|
267
267
|
let a=`Task ${o} (${w.title}) has been marked as completed.`
|
|
268
268
|
if(I?.id&&(a+=`\n[RECORD:${I.id}]`),b&&(a+="\nCommit: "+b.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
|
|
269
|
-
|
|
270
|
-
const t=(0,s.extractArrayFromResponse)(e,{logger:
|
|
271
|
-
|
|
269
|
+
p.info("Raw tasks list response data",{responseData:JSON.stringify(e)}),p.debug("Tasks list response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
|
|
270
|
+
const t=(0,s.extractArrayFromResponse)(e,{logger:p,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
|
|
271
|
+
p.info("Task progress check",{requestId:i,totalTasks:r,completedTasks:n}),a+=`\n\nTask Progress: ${n}/${r} tasks completed`,n===r&&(a+=`\n\nAll tasks for request ${i} are now completed! You may consider marking the request as completed using the complete-request tool.`)}catch(e){p.warn("Failed to check task progress",{error:(0,l.getErrorMessage)(e),requestId:i})}return f({success:!0}),{content:[{type:"text",text:a}]}}catch(e){throw p.error("Failed to complete task",{error:e instanceof Error?e.stack:e+"",taskId:o}),Error("Failed to complete task: "+(0,l.getErrorMessage)(e))}}catch(t){if(p.error("Failed to complete task",{error:t instanceof Error?t.stack:t+"",args:e}),d.projectId)try{const r=u.getToolRecordClient()
|
|
272
272
|
if(r){const o=t instanceof n.NotFoundError||t instanceof n.ValidationError||t instanceof i.ZodError
|
|
273
|
-
await r.createToolRecord({...o?{}:{taskId:e.taskId},projectId:d.projectId,type:"complete-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.summary?.substring(0,100)+(e.summary?.length>100?"...":""),error:(0,l.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",attemptedTaskId:e.taskId,taskIdValidationFailed:o},note:"Failed to complete task "+e.taskId})}}catch(e){
|
|
273
|
+
await r.createToolRecord({...o?{}:{taskId:e.taskId},projectId:d.projectId,type:"complete-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.summary?.substring(0,100)+(e.summary?.length>100?"...":""),error:(0,l.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",attemptedTaskId:e.taskId,taskIdValidationFailed:o},note:"Failed to complete task "+e.taskId})}}catch(e){p.error("Failed to create failure record for task completion",{error:e instanceof Error?e.message:e+""})}f({success:!1,error:t instanceof Error?t.name:"unknown"})
|
|
274
274
|
let r=(0,l.getErrorMessage)(t)
|
|
275
275
|
return t instanceof n.NotFoundError&&(r=`The task ID "${e.taskId}" was not found. Please provide a valid task ID.`),t instanceof o.ConnectionError&&(r="Unable to complete task: Connection to the server failed. Please check your network connection and try again."),t instanceof i.ZodError&&t.errors.length>0&&(r=t.errors[0].message),{content:[{type:"text",text:"Error: "+r}],isError:!0}}}
|
|
276
276
|
const r=t(6183),n=t(9860),o=t(5674),s=t(2960),i=t(1569),a=t(5172),c=t(5218),l=t(8824)},405(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
@@ -328,9 +328,8 @@ t>0&&this.logger.debug("Cleaned up expired passwords",{count:t})}getActivePasswo
|
|
|
328
328
|
const r=t(1569),n=t(5997),o=t(8349),s=t(9852),i=t(9422),a=r.z.object({}),c=r.z.object({requestId:r.z.string().optional().describe("Request ID to search for")})
|
|
329
329
|
exports.debugDefs=[{name:"debug_multi_agent_status",description:"Debug tool to check multi-agent mode status, worktree state, and configuration",schema:a,annotations:{title:"Debug Multi-Agent Status",readOnlyHint:!0},debugOnly:!0,readOnly:!0,async handler(e,t){return{content:[{type:"text",text:await(0,n.handleDebugMultiAgentStatus)(e,t.context,t.logger,t.metrics)}]}}},{name:"debug_git_log",description:"Debug tool to examine git log and search for merge commits",schema:a,annotations:{title:"Debug Git Log",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,o.handleDebugGitLog)(e,t.context,t.logger,t.metrics)}},{name:"debug_git_log_request",description:"Debug tool to examine git log for a specific request",schema:c,annotations:{title:"Debug Git Log Request",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,s.handleDebugGitLogRequest)(e,t.context,t.logger,t.metrics)}},{name:"debug_request_file_history",description:"Debug tool to test git merge commit search patterns for request file history",schema:c,annotations:{title:"Debug Request File History",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,i.handleDebugRequestFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}]},700(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
330
330
|
const r=t(6183),n=t(8037),o=t(5218)
|
|
331
|
-
exports.def={name:"list_requests",description:`List requests with filtering options (status, type, dates) and pagination. Shows detailed request information${(0,o.isMultiAgentModeEnabled)()?" including lock status to indicate which requests are currently in use by other agents":""}.`,schema:r.ListRequestsSchema,annotations:{title:"List Requests",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleListRequests)(e,t.context,t.apiClient,t.logger,t.metrics)}}},
|
|
332
|
-
const r=t(
|
|
333
|
-
const r=t(7645),n=t(1038),o=t(2161),s=t(5172),i=t(715)
|
|
331
|
+
exports.def={name:"list_requests",description:`List requests with filtering options (status, type, dates) and pagination. Shows detailed request information${(0,o.isMultiAgentModeEnabled)()?" including lock status to indicate which requests are currently in use by other agents":""}.`,schema:r.ListRequestsSchema,annotations:{title:"List Requests",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleListRequests)(e,t.context,t.apiClient,t.logger,t.metrics)}}},857(module){module.exports=require("os")},922(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ToolRecordClient=void 0
|
|
332
|
+
const r=t(7645),n=t(1038),o=t(2161),s=t(5172),i=t(6688)
|
|
334
333
|
class a extends r.ConnectionAwareClient{constructor(e,t,r,n,o,s,i){const a=t.child({component:"tool-record-client"}),c=s||{isInOfflineMode(){return!1},isOffline(){return!1},setOfflineMode(){},async checkConnectivity(){return!0},getHealthCheckStats(){return{isOffline:!1,consecutiveFailures:0,currentBackoffMs:0,lastCheckTime:0}},cleanup(){}}
|
|
335
334
|
super(e,a,r,o,i),this.setConnectionStatusManager(c),this.projectClient=n,this.logger.info("ToolRecordClient initialized",{baseUrl:e,hasAuthToken:!!o,options:JSON.stringify(i)})}async createToolRecord(e){if(this.logger.debug("Creating tool record",{record:e}),!e.projectId)throw this.logger.error("No project ID provided for creating tool record"),Error("Project ID is required for tool record creation")
|
|
336
335
|
if(!e.type)throw this.logger.error("No record type provided for creating tool record"),Error("Record type is required for tool record creation")
|
|
@@ -339,7 +338,7 @@ try{const r=e.projectId||this.projectClient.getProjectId()
|
|
|
339
338
|
if(!r)throw this.logger.error("No project ID available for creating tool record"),Error("Project ID is required for tool record operations")
|
|
340
339
|
try{const a=`/api/projects/${r}/tool-records`
|
|
341
340
|
this.logger.debug("Using tool record endpoint",{endpoint:a,projectId:r}),this.getAuthToken(),this.logger.info("Sending tool record to server",{endpoint:a,recordType:e.type,taskId:e.taskId,requestId:e.requestId})
|
|
342
|
-
const c=(0,s.getGlobalClientInfo)(),l=
|
|
341
|
+
const c=(0,s.getGlobalClientInfo)(),l=i.sessionIdentity.getCurrentCallOrigin(),d={...e,...l&&{cliOrigin:l},metadata:{...e.metadata,clientName:c.clientName,clientVersion:c.clientVersion,sessionTag:c.sessionTag}},u=await this.requestWithRetry("POST",a,d)
|
|
343
342
|
this.logger.debug("Raw tool record creation response",{responseStatus:(0,o.isSuccessResponse)(u)?200:(0,o.isErrorResponse)(u)?u.error.statusCode:"unknown",responseData:(0,o.isSuccessResponse)(u)?JSON.stringify(u.data).substring(0,500):(0,o.isErrorResponse)(u)?JSON.stringify(u.error).substring(0,500):"unknown response format"})
|
|
344
343
|
const h=(0,o.safeGetResponseData)(u,{})
|
|
345
344
|
return t({success:!0}),this.metrics.incrementCounter("tool_record_creation_success",1),this.logger.info("Successfully created tool record",{recordId:h.id,type:h.type,taskId:h.task_id,requestId:h.request_id}),(0,n.adaptApiToolRecordToDomain)(h)}catch(s){if(404===this.extractErrorStatus(s)){this.logger.error("Tool record creation failed: Endpoint not found (404)",{endpoint:`/api/projects/${r}/tool-records`,error:this.getErrorMessage(s)})
|
|
@@ -390,23 +389,23 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
390
389
|
var t={}
|
|
391
390
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
392
391
|
return o(t,e),t})
|
|
393
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQueryHistory=async function(e,r,n,o,s,g){const
|
|
392
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQueryHistory=async function(e,r,n,o,s,g){const p=o.child({tool:"query_history"})
|
|
394
393
|
try{const o=a.validateArgs(e,i.QueryHistorySchema),{queryType:h}=o
|
|
395
|
-
let
|
|
396
|
-
switch(
|
|
394
|
+
let f
|
|
395
|
+
switch(p.info("Processing query_history request",{queryType:h}),h){case"file-history":p.info("Routing to file-history handler",{path:o.fileHistory.path}),f=await(0,c.handleFileHistory)({path:o.fileHistory.path,limit:o.fileHistory.limit,showDiff:o.fileHistory.showDiff,showTraceability:o.fileHistory.showTraceability,branch:o.fileHistory.branch,since:o.fileHistory.since},r,n,p,s)
|
|
397
396
|
break
|
|
398
|
-
case"request-file-history":
|
|
397
|
+
case"request-file-history":p.info("Routing to request-file-history handler",{requestId:o.requestHistory.requestId}),f=await(0,l.handleRequestFileHistory)({requestId:o.requestHistory.requestId,showDiff:o.requestHistory.showDiff,detailLevel:o.requestHistory.detailLevel,taskId:o.requestHistory.taskId,fileFilter:o.requestHistory.fileFilter},r,n,p,s)
|
|
399
398
|
break
|
|
400
|
-
case"recover":
|
|
399
|
+
case"recover":p.info("Routing to file-recover handler",{taskId:o.recover.taskId,path:o.recover.path,commitHash:o.recover.commitHash})
|
|
401
400
|
let e=o.recover.commitHash
|
|
402
401
|
if(!e){const n=o.recover.path,s=r.basePath||process.cwd(),{resolve:i}=await Promise.resolve().then(t.t.bind(t,6928,23)),a=i(s,n)
|
|
403
402
|
try{const{execSync:r}=await Promise.resolve().then(t.t.bind(t,5317,23)),o=r(`git log --format=%H -n 2 -- "${a}"`,{cwd:s,encoding:"utf8"}).trim().split("\n").filter(Boolean)
|
|
404
403
|
if(e=o[1]||o[0],!e)return{content:[{type:"text",text:"No previous versions found for "+n}],isError:!0}
|
|
405
|
-
|
|
404
|
+
p.info("Auto-resolved previous version",{filePath:n,commitHash:e})}catch{return{content:[{type:"text",text:"Could not find previous versions of "+n}],isError:!0}}}f=await(0,d.handleFileRecover)({taskId:o.recover.taskId,path:o.recover.path,commitHash:e,createBackup:o.recover.createBackup},r,n,n.getToolRecordClient(),p,s,g)
|
|
406
405
|
break
|
|
407
|
-
case"blame":
|
|
406
|
+
case"blame":p.info("Routing to file-blame handler",{path:o.blame.path,lines:o.blame.lines}),f=await(0,u.handleFileBlame)({path:o.blame.path,lines:o.blame.lines,branch:o.blame.branch},r,n,p,s)
|
|
408
407
|
break
|
|
409
|
-
default:throw Error("Unknown query type: "+h)}return
|
|
408
|
+
default:throw Error("Unknown query type: "+h)}return p.info("query_history request completed",{queryType:h,success:!f.isError}),s.incrementCounter("query_history_total",1,{success:!f.isError,queryType:h}),f}catch(e){return p.error("query_history request failed",{error:e instanceof Error?e.stack:e+""}),s.incrementCounter("query_history_errors",1),{content:[{type:"text",text:"\u274c **Query History Failed:** "+(0,h.getErrorMessage)(e)}],isError:!0}}}
|
|
410
409
|
const i=t(6183),a=s(t(5967)),c=t(8828),l=t(8317),d=t(4640),u=t(4811),h=t(8824)},1038(e,exports){function t(e){let t
|
|
411
410
|
if("string"==typeof e.metadata&&e.metadata)try{t=JSON.parse(e.metadata)}catch(e){t=void 0}else e.metadata&&"object"==typeof e.metadata&&(t=e.metadata)
|
|
412
411
|
return{id:e.id,localId:e.local_id||e.localId,taskId:e.task_id||e.taskId||void 0,requestId:e.request_id||e.requestId||void 0,projectId:e.project_id||e.projectId||e.id,type:e.type,metadata:t,note:e.note||void 0,createdAt:e.created_at||e.createdAt||"",updatedAt:e.updated_at||e.updatedAt||""}}function r(e){let t=null
|
|
@@ -512,9 +511,9 @@ const t=this.remoteServerUrl+"/auth/validate"
|
|
|
512
511
|
this.logger.debug("Making token validation request",{validationUrl:t})
|
|
513
512
|
const r=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Content-Type":"application/json"},signal:AbortSignal.timeout(1e4)})
|
|
514
513
|
if(r.ok){const e=await r.json()
|
|
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
|
|
514
|
+
return this.logger.info("Token validation successful",{status:e.status||"unknown",username:e.username||"unknown"}),!0}return this.logger.info("Token validation failed - token may be invalid or expired",{status:r.status,statusText:r.statusText}),this.invalidateCache(),!1}catch(e){return e instanceof Error&&"AbortError"===e.name?(this.logger.info("Token validation request timed out - assuming offline or server unavailable"),!0):(this.logger.info("Token validation request failed",{error:(0,c.getErrorMessage)(e)}),!0)}}async hasValidAndWorkingToken(){return!!await this.hasValidToken()&&await this.validateTokenWithRemoteServer()}async isGoogleOAuthAvailable(){return await this.authFlow.isGoogleOAuthAvailable()}async startGoogleOAuthFlow(){return await this.authFlow.startGoogleOAuthFlow()}async startGoogleOAuthPolling(e,t,r,n,o){return await this.authFlow.startGoogleOAuthPolling(e,t,r,n,o)}}},1281(e,exports,t){async function r(e,t,o,s,i,a,c,l,d,u=0){let p=0,f=0,m=0
|
|
516
515
|
const y=[]
|
|
517
|
-
if(o.length>=I||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:I,depth:c}),{filesCount:
|
|
516
|
+
if(o.length>=I||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:I,depth:c}),{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}
|
|
518
517
|
try{const w=await g.default.readdir(e,{withFileTypes:!0}),v=[],C=[]
|
|
519
518
|
for(const t of w){const r=h.default.join(e,t.name)
|
|
520
519
|
if(t.isDirectory()){if(b.includes(t.name)||t.name.startsWith(".")){a.debug("Skipping excluded directory: "+t.name)
|
|
@@ -523,15 +522,15 @@ continue}v.push({entry:t,fullPath:r})}}if(v.length>0){const e=[]
|
|
|
523
522
|
for(let t=0;t<v.length;t+=16)e.push(v.slice(t,t+16))
|
|
524
523
|
for(const r of e){if(o.length>=I)break
|
|
525
524
|
const e=await Promise.all(r.map((({entry:e,fullPath:r})=>n(r,t,0,o,l,d,e.name,u))))
|
|
526
|
-
for(const t of e){
|
|
527
|
-
for(const e of t.matches){if(o.length>=I)return{filesCount:
|
|
525
|
+
for(const t of e){p++,t.hasMatches&&f++
|
|
526
|
+
for(const e of t.matches){if(o.length>=I)return{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}
|
|
528
527
|
o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=I)break
|
|
529
528
|
m++
|
|
530
529
|
const e={path:n,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
531
530
|
try{const l=await r(n,t,o,s,i,a,c+1,e,d,u)
|
|
532
|
-
|
|
531
|
+
p+=l.filesCount,f+=l.fileMatchesCount,e.filesProcessed=l.filesCount,e.filesMatched=l.fileMatchesCount,e.subdirectories=l.subdirCount,y.push(e),l.subdirStats&&l.subdirStats.length>0&&y.push(...l.subdirStats)}catch(t){const r=`Error processing subdirectory ${n}: ${(0,k.getErrorMessage)(t)}`
|
|
533
532
|
e.errors.push(r),y.push(e),a.error(r)}}}catch(t){const r=`Error searching directory ${e}: ${(0,k.getErrorMessage)(t)}`
|
|
534
|
-
l.errors.push(r),a.warn(r)}return{filesCount:
|
|
533
|
+
l.errors.push(r),a.warn(r)}return{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}}async function n(e,t,r,n,o,s,i,a=0){const c=[]
|
|
535
534
|
let l,d=!1
|
|
536
535
|
const u=async()=>{if(void 0===l)try{const t=await g.default.stat(e)
|
|
537
536
|
l=t.mtime.getTime()}catch(e){l=void 0}return l}
|
|
@@ -564,31 +563,31 @@ if(null!=e)for(var r=a(e),n=0;n<r.length;n++)"default"!==r[n]&&c(t,e,r[n])
|
|
|
564
563
|
return l(t,e),t}),u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
565
564
|
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
565
|
let b=0
|
|
567
|
-
const I={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:
|
|
568
|
-
try{const{needle:n,directory:
|
|
569
|
-
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,w.handleListDirectory)({path:
|
|
570
|
-
if("string"!=typeof n)throw I.errors.push("Search term (needle) must be a string"),(0,
|
|
566
|
+
const I={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:p.default.hostname(),username:p.default.userInfo().username,workingDirectory:process.cwd(),contextBasePath:t?.basePath||"unknown"},startTime:u,endTime:0,phases:{initializationTime:0,searchTime:0,directoryListingTime:0},totalFiles:0,totalMatches:0,directoryStats:[],errors:[]}
|
|
567
|
+
try{const{needle:n,directory:p,options:v={}}=e
|
|
568
|
+
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,w.handleListDirectory)({path:p||".",levels:v.levels||1,sortBy:v.sortBy||"name"},t,a,c)
|
|
569
|
+
if("string"!=typeof n)throw I.errors.push("Search term (needle) must be a string"),(0,f.createValidationError)("Search term (needle) must be a string")
|
|
571
570
|
let C
|
|
572
|
-
if(I.searchDirectory=
|
|
571
|
+
if(I.searchDirectory=p||".",p){const{normalizedPath:e,fullPath:r}=m.validateAndNormalizePath(p,t)
|
|
573
572
|
C=r}else C=t.basePath
|
|
574
573
|
I.resolvedPath=C
|
|
575
574
|
let _=!1
|
|
576
575
|
try{_=(await g.default.stat(C)).isFile()}catch(e){const t=`Cannot access path ${C}: ${(0,k.getErrorMessage)(e)}`
|
|
577
576
|
throw I.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,T=v.fileExtension,M=v.searchIn||"content"
|
|
578
577
|
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 I.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,
|
|
578
|
+
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!_&&!T)throw I.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,f.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
|
|
580
579
|
let P,x=""
|
|
581
580
|
if(_)x="*"
|
|
582
581
|
else if("*"===T)x="*"
|
|
583
582
|
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 I.errors.push(t),(0,
|
|
583
|
+
throw I.errors.push(t),(0,f.createValidationError)(t)}if(I.patternInfo={needle:n,regex:P.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:x},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
|
|
585
584
|
for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
|
|
586
585
|
I.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},I.phases.directoryListingTime=I.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,k.getErrorMessage)(e)
|
|
587
586
|
I.errors.push(t),l.error(t)}const O=_?"file":"directory"
|
|
588
587
|
l.info(`Searching for "${n}" in ${O} ${C} (mode: ${M})`,{needle:n,searchTarget:O,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:x,searchIn:M}}),b=Date.now(),I.phases.initializationTime=b-u
|
|
589
588
|
const j=Date.now()
|
|
590
589
|
let $=[],D=0,A=0
|
|
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,
|
|
590
|
+
try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,p=[]
|
|
592
591
|
if(s.info("performLocalSearch started",{searchPath:e,pattern:t.toString(),options:n}),d)return await async function(e,t,r,n,o,s=0){const i=[],a=h.default.basename(e)
|
|
593
592
|
let c
|
|
594
593
|
n.info("Searching single file: "+e,{searchIn:r})
|
|
@@ -600,10 +599,10 @@ t.contextBefore=r.slice(e,n).map((e=>(0,y.truncate)(e.trim(),120)))
|
|
|
600
599
|
const o=Math.min(r.length,n+1+s)
|
|
601
600
|
t.contextAfter=r.slice(n+1,o).map((e=>(0,y.truncate)(e.trim(),120)))}i.push(t)}n.info(`Found ${i.filter((e=>"content"===e.matchType)).length} content matches`)}catch(t){const r=`Error reading file ${e}: ${(0,k.getErrorMessage)(t)}`
|
|
602
601
|
o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
|
|
603
|
-
const
|
|
604
|
-
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,
|
|
605
|
-
return
|
|
606
|
-
return
|
|
602
|
+
const f={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
603
|
+
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,p,a,o,s,0,f,l,u)
|
|
604
|
+
return f.filesProcessed=n,f.filesMatched=c,f.subdirectories=d,i.directoryStats.push(f),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:p.length,directories:d+1}),{matches:p,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,k.getErrorMessage)(t)
|
|
605
|
+
return f.errors.push(r),i.directoryStats.push(f),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:p,totalFiles:f.filesProcessed}}}(C,P,{maxResults:E,fileExtension:x,searchIn:M,isFile:_,contextLines:R},x,l,I)
|
|
607
606
|
$=e.matches,D=e.totalFiles
|
|
608
607
|
const t=1e3
|
|
609
608
|
$.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)
|
|
@@ -613,7 +612,7 @@ let F,N=""
|
|
|
613
612
|
try{if(t.getCurrentBranchContext){const e=await t.getCurrentBranchContext()
|
|
614
613
|
e.branch&&(N=e.isMain?` (searched on main branch: ${e.branch})`:` (searched on request branch: ${e.branch}${e.requestId?" for "+e.requestId:""})`)}}catch(e){l.debug("Could not get branch context",{error:e}),N=" (branch context unavailable)"}l.debug("Search diagnostic information",{diagnostic:I})
|
|
615
614
|
const L="content"===M?"content":"filename"===M?"filenames":"content and filenames"
|
|
616
|
-
if(A>$.length?(F=`Found ${A} results for "${n}" (searching ${L})`,
|
|
615
|
+
if(A>$.length?(F=`Found ${A} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=`${N}. Showing first ${$.length}:\n\n`):(F=`Found ${$.length} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=N+":\n\n"),$.length>0)if(R>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
|
|
617
616
|
if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
|
|
618
617
|
const o=new Map
|
|
619
618
|
for(const e of n){const t=o.get(e.file)||[]
|
|
@@ -637,7 +636,7 @@ else F+="No matches found."
|
|
|
637
636
|
return d({success:!0}),{content:[{type:"text",text:F}]}}catch(t){l.error("Search failed",{args:e,error:t instanceof Error?t.stack:t+""}),I.errors.push((0,k.getErrorMessage)(t)),I.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:I})
|
|
638
637
|
let r="Search failed: "+(0,k.getErrorMessage)(t)
|
|
639
638
|
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)),
|
|
639
|
+
const h=u(t(6928)),g=u(t(1943)),p=u(t(857)),f=t(9860),m=d(t(5967)),y=t(5967),w=t(2537),k=t(8824),b=["node_modules"],I=1e4,v=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore"]),C=1048576},1318(e,exports,t){async function r(e,t,r){try{const r=(await e.revparse(["--show-toplevel"])).trim(),n=c.default.isAbsolute(t)?t:c.default.resolve(t)
|
|
641
640
|
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
641
|
if(!a||""===a.trim())return null
|
|
643
642
|
const c=a.trim().split("\n")[0],[l,...d]=c.split("|"),u=d.join("|")
|
|
@@ -654,12 +653,12 @@ for(const e of r){const r=e.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/)
|
|
|
654
653
|
if(r){const e=parseInt(r[3],10),n=r[4]?parseInt(r[4],10):1,o=e+n-1
|
|
655
654
|
n>0&&t.push({start:e,end:o})}}return t}(s)
|
|
656
655
|
return{ranges:i,diff:s}}catch(e){return n.warn("Failed to get uncommitted changes",{filePath:t,error:(0,l.getErrorMessage)(e)}),{ranges:[],diff:""}}}(e,t.path,i),d=c.ranges,u=c.diff,h=await async function(e,t,n){try{const o=await r(e,t,n),s=await e.log({file:o,maxCount:1})
|
|
657
|
-
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),g=!!h&&n(h),
|
|
656
|
+
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),g=!!h&&n(h),p=t.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),f=d.map((e=>`${e.start}-${e.end}`)).join(", ")||"none",m=u?u.substring(0,300):"no diff"
|
|
658
657
|
if(0===d.length){const r=[]
|
|
659
658
|
for(const s of t.lineRanges){const a=await o(e,t.path,s.start,s.end,i)
|
|
660
|
-
a&&(n(a.message)||r.push({range:`${s.start}-${s.end}`,commit:a}))}if(r.length>0){const e=r.map((e=>`Lines ${e.range}: ${e.commit.hash.substring(0,8)} - ${e.commit.message}`)).join("; "),n=[`\u26a0\ufe0f Warning: Lines ${
|
|
661
|
-
return{hasExternalEdits:!0,conflictingLines:t.lineRanges.flatMap((e=>Array.from({length:e.end-e.start+1},((t,r)=>e.start+r)))),message:n,debugInfo:{detectionRan:!0,affectedRegion:
|
|
662
|
-
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:
|
|
659
|
+
a&&(n(a.message)||r.push({range:`${s.start}-${s.end}`,commit:a}))}if(r.length>0){const e=r.map((e=>`Lines ${e.range}: ${e.commit.hash.substring(0,8)} - ${e.commit.message}`)).join("; "),n=[`\u26a0\ufe0f Warning: Lines ${p} were last modified by external commits (not alchemy).`,"","Commit details: "+e,"\nThese changes may have been made manually or by another tool.\nReview recent commits before proceeding."].join("\n")
|
|
660
|
+
return{hasExternalEdits:!0,conflictingLines:t.lineRanges.flatMap((e=>Array.from({length:e.end-e.start+1},((t,r)=>e.start+r)))),message:n,debugInfo:{detectionRan:!0,affectedRegion:p,uncommittedChanges:"none",lastCommit:r[0].commit.message,wasLastCommitAlchemy:!1,diffPreview:e,overlapDetected:!0}}}return{hasExternalEdits:!1,conflictingLines:[],debugInfo:{detectionRan:!0,affectedRegion:p,uncommittedChanges:"none",lastCommit:h,wasLastCommitAlchemy:g,diffPreview:"no uncommitted changes, last commits from alchemy",overlapDetected:!1}}}const y={path:t.path,lineRanges:d,totalLines:d.reduce(((e,t)=>e+(t.end-t.start+1)),0),operationType:"modification"},w=(0,a.getOverlappingLines)(t,y)
|
|
661
|
+
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:p,uncommittedChanges:f,lastCommit:h,wasLastCommitAlchemy:g,diffPreview:m,overlapDetected:!1}}:{hasExternalEdits:!0,conflictingLines:w,message:["\u26a0\ufe0f Warning: File has uncommitted changes in lines you're about to modify.\n","Affected lines: "+p,"Conflicting lines: "+s(w),"",g?"Last commit was by alchemy, but file has been edited since.":"Last commit was NOT from alchemy - these may be manual edits.","\nReview the changes before proceeding."].join("\n"),details:{totalExternalChanges:y.totalLines,overlappingChanges:w.length,changedLineRanges:d},debugInfo:{detectionRan:!0,affectedRegion:p,uncommittedChanges:f,lastCommit:h,wasLastCommitAlchemy:g,diffPreview:m,overlapDetected:!0}}}catch(e){return i.error("Failed to detect external edits",{path:t.path,error:(0,l.getErrorMessage)(e)}),{hasExternalEdits:!1,conflictingLines:[],message:"Unable to check for external edits (Git error). Proceeding with caution."}}},exports.hasUncommittedChanges=async function(e,t){try{return(await e.status([t])).files.some((e=>e.path===t))}catch(e){return!1}}
|
|
663
662
|
const a=t(9947),c=i(t(6928)),l=t(8824)},1387(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.WorkspaceRequestProcessor=void 0
|
|
664
663
|
const r=t(7075),n=t(5964),o=t(8824)
|
|
665
664
|
exports.WorkspaceRequestProcessor=class{constructor(e,t,r,n,o){this.gitAdapter=e,this.conflictDetector=t,this.safetyAnalyzer=r,this.conflictResolver=n,this.logger=o}async completeRequest(e,t,s){const i=r.WorkspaceValidation.validateRequestId(e)
|
|
@@ -712,38 +711,35 @@ const y=!!i,w=async()=>{if(!y)return!0
|
|
|
712
711
|
try{return await i.hasValidToken()}catch(e){return m.error("Error checking authentication status",{error:(0,l.getErrorMessage)(e)}),!1}},k=async()=>{const e=(0,c.areTestsRequiredForCompletion)(),t=await w()
|
|
713
712
|
m.info(`Generating tools list with testsRequired=${e}, authenticated=${t}`)
|
|
714
713
|
const r={testsRequired:e,authenticated:t}
|
|
715
|
-
return(0,
|
|
714
|
+
return(0,f.generateVisibleToolsList)(r)}
|
|
716
715
|
let b=k(),I=[]
|
|
717
716
|
b.then((e=>{I=e})).catch((e=>{m.error("Error generating initial tools list",{error:(0,l.getErrorMessage)(e)}),I=[]})),e.setRequestHandler(a.ListToolsRequestSchema,(async()=>{try{return I=await k(),{tools:I}}catch(e){return m.error("Error generating tools list",{error:(0,l.getErrorMessage)(e)}),{tools:[]}}}))
|
|
718
717
|
let v=!1
|
|
719
|
-
e.setRequestHandler(a.CallToolRequestSchema,(async e=>{try{const{name:i,arguments:a={},_meta:c}=e.params;(0,
|
|
718
|
+
e.setRequestHandler(a.CallToolRequestSchema,(async e=>{try{const{name:i,arguments:a={},_meta:c}=e.params;(0,p.logSessionIdentity)(i,"_meta-debug",{has_meta:!!c,sessionId:c?.sessionId||null,messageId:c?.messageId||null,paramKeys:Object.keys(e.params)}),m.info("Tool call received: "+i,{tool:i}),s.incrementCounter("tool_calls_total",1,{tool:i})
|
|
720
719
|
const k=s.startTimer("tool_execution_time")
|
|
721
720
|
Date.now()
|
|
722
721
|
let b=Date.now()
|
|
723
722
|
const I=r(a)
|
|
724
723
|
if(Date.now(),b=Date.now(),y){const e=await w()
|
|
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,
|
|
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}))
|
|
724
|
+
if(Date.now(),!e)return m.warn("Unauthenticated tool call attempt",{tool:i}),{content:[{type:"text",text:"Authentication required. Please run 'alchemylab setup' to authenticate and configure your project."}],isError:!0}}const C=(0,f.getToolByName)(i)
|
|
725
|
+
let _
|
|
726
|
+
if(b=Date.now(),n?(n.setOptions({createRecords:C?.createsRecords??!1}),m.info(`Setting record creation for tool ${i}: ${C?.createsRecords??!1}`)):m.debug(`No API client available for tool ${i} (minimal mode)`),Date.now(),Date.now(),b=Date.now(),c?.sessionId){const e=c.sessionId,r=c.messageId,n=u.sessionIdentity.getIdentity()
|
|
727
|
+
if(n)n.sessionId!==e&&((0,p.logSessionIdentity)(i,"_meta-session-switch",{prevSessionId:n.sessionId,prevAgentType:n.agentType,newSessionId:e}),u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:n.serverUrl}),t?.workspaceManager?.resetCurrentContext?.(e))
|
|
730
728
|
else{const r=await(0,d.getServerUrl)(t,m)
|
|
731
|
-
u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r||""})
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
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
|
-
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(_),!v&&n){const e=u.sessionIdentity.getIdentity(),t=process.env.ALCHEMY_INITIAL_BRANCH
|
|
729
|
+
u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r||""})}_={providerId:"opencode",sessionId:e,messageId:r,createdAt:(new Date).toISOString()},(0,p.logSessionIdentity)(i,"_meta",{sessionId:e,messageId:r})}else m.warn("No _meta.sessionId on tool call \u2014 session identity unavailable",{tool:i})
|
|
730
|
+
u.sessionIdentity.setCurrentCallOrigin(_)
|
|
731
|
+
const E=_?.sessionId||c?.sessionId
|
|
732
|
+
if(t?.workspaceManager){b=Date.now()
|
|
733
|
+
try{const e=await(0,d.getServerUrl)(t,m)
|
|
734
|
+
e&&n&&await t.workspaceManager.ensureReadonlyBranchIfNeeded(e,i,n,E)}catch(e){m.debug("Error during workspace check",{error:(0,l.getErrorMessage)(e)})}Date.now()}if(!v&&n){const e=u.sessionIdentity.getIdentity(),t=process.env.ALCHEMY_INITIAL_BRANCH
|
|
740
735
|
if(e?.sessionId&&t){const r=t.match(/^requests\/(.+)$/),o="1"===process.env.ALCHEMY_ALLOW_PARALLEL
|
|
741
736
|
if(r&&!o){const t=r[1]
|
|
742
737
|
v=!0
|
|
743
738
|
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
|
-
await Promise.all([i,a])}catch(e){m.warn("Error in session tag mapping / lock acquisition",{error:(0,l.getErrorMessage)(e)})}}}}
|
|
745
|
-
|
|
746
|
-
|
|
739
|
+
await Promise.all([i,a])}catch(e){m.warn("Error in session tag mapping / lock acquisition",{error:(0,l.getErrorMessage)(e)})}}}}let q
|
|
740
|
+
if(C){const e={context:t,apiClient:n,logger:o,metrics:s,mcpServer:g,cliOrigin:_}
|
|
741
|
+
q=await C.handler(I,e)}else m.info(`Tool ${i} not found, returning negative response`),q={content:[{type:"text",text:`The tool '${i}' does not exist.`}]}
|
|
742
|
+
return Date.now(),Date.now(),k({tool:i,success:!0}),q}catch(t){m.error("Error executing tool:",{error:t instanceof Error?t.stack:t+"",tool:e.params.name}),s.incrementCounter("tool_errors_total",1,{tool:e.params.name,error:t instanceof Error?t.name:"unknown"})
|
|
747
743
|
let r="Unknown error"
|
|
748
744
|
if(t instanceof Error)r=t.message
|
|
749
745
|
else if("string"==typeof t)r=t
|
|
@@ -761,13 +757,13 @@ const a=t(9150),c=t(2478),l=t(8824),d=t(7617),u=t(6688),h=t(5172)
|
|
|
761
757
|
i(t(9896)),i(t(6928))
|
|
762
758
|
var g=t(7280)
|
|
763
759
|
Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return g.logSessionIdentity}})
|
|
764
|
-
const
|
|
760
|
+
const p=t(7280)
|
|
765
761
|
t(2462)
|
|
766
|
-
const
|
|
762
|
+
const f=t(2245)},1483(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearchDocuments=async function(e,t,s,i,a){const c=i.child({tool:"search_documents"}),l=a.startTimer("tool_execution_time")
|
|
767
763
|
try{let i
|
|
768
764
|
try{i=r.SearchDocumentsSchema.parse(e)}catch(t){if(t instanceof n.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
|
|
769
|
-
return c.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{query:a,type:l,requestId:d,includeArchived:u,maxResults:h,dateFrom:g,dateTo:
|
|
770
|
-
c.info("Searching documents",{query:a,type:l,requestId:d,includeArchived:u,maxResults:h,searchIn:
|
|
765
|
+
return c.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{query:a,type:l,requestId:d,includeArchived:u,maxResults:h,dateFrom:g,dateTo:p,searchIn:f}=i
|
|
766
|
+
c.info("Searching documents",{query:a,type:l,requestId:d,includeArchived:u,maxResults:h,searchIn:f})
|
|
771
767
|
const m=t.projectId
|
|
772
768
|
if(!m){const e="Project ID is required. Make sure you are in a project context."
|
|
773
769
|
return c.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}s.setProjectId(m)
|
|
@@ -776,11 +772,11 @@ try{const e={limit:h||100,offset:0,sortBy:"updatedAt",sortDirection:"desc",searc
|
|
|
776
772
|
l&&(e.type=l),d&&(e.requestId=d),c.debug("Fetching documents with filters",{filters:e})
|
|
777
773
|
let t=await y.listDocuments(e)
|
|
778
774
|
if(g){const e=new Date(g)
|
|
779
|
-
t=t.filter((t=>new Date(t.createdAt)>=e))}if(
|
|
775
|
+
t=t.filter((t=>new Date(t.createdAt)>=e))}if(p){const e=new Date(p)
|
|
780
776
|
t=t.filter((t=>new Date(t.createdAt)<=e))}c.info(`Fetched and filtered ${t.length} documents for search`)
|
|
781
777
|
const r=[],n=a.toLowerCase()
|
|
782
778
|
for(const e of t){let t,o=null
|
|
783
|
-
if("filename"!==
|
|
779
|
+
if("filename"!==f&&"both"!==f||!e.filename.toLowerCase().includes(n)||(o="filename",t=e.filename),("content"===f||"both"===f)&&e.content&&e.content.toLowerCase().includes(n)){o="content"
|
|
784
780
|
const r=e.content.split("\n")
|
|
785
781
|
for(let e=0;e<r.length;e++)if(r[e].toLowerCase().includes(n)){const n=Math.max(0,e-1),o=Math.min(r.length-1,e+1)
|
|
786
782
|
t=r.slice(n,o+1).map(((t,r)=>n+r===e?"> "+t.trim():" "+t.trim())).join("\n")
|
|
@@ -858,16 +854,16 @@ try{let i
|
|
|
858
854
|
try{i=r.CreateDocumentSchema.parse(e)}catch(t){if(t instanceof n.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
|
|
859
855
|
return d.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{requestId:a,filename:c,content:u,type:h,comment:g}=i
|
|
860
856
|
d.info("Creating new document",{requestId:a||"standalone",filename:c,contentLength:u.length,type:h,comment:g})
|
|
861
|
-
const
|
|
862
|
-
if(!
|
|
857
|
+
const p=t.projectId
|
|
858
|
+
if(!p){const e="Project ID is required. Make sure you are in a project context."
|
|
863
859
|
return d.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}if(!c.toLowerCase().endsWith(".md")){const e="Filename must end with .md extension: "+c
|
|
864
|
-
return d.warn("Invalid filename extension",{filename:c}),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}try{s.setProjectId(
|
|
860
|
+
return d.warn("Invalid filename extension",{filename:c}),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}try{s.setProjectId(p)
|
|
865
861
|
const e=s.getDocumentClient(),t=a?{requestId:a}:{},r=(await e.listDocuments(t)).find((e=>e.filename===c&&!e.archived))
|
|
866
862
|
if(r){const e=`\u274c A document with filename "${c}" already exists ${a?"for this request":"in this project"}.\n\n**Existing Document ID:** ${r.id}\n**Created:** ${r.createdAt}\n\nPlease either:\n- Use a different filename\n- Delete or archive the existing document first\n- Use write_file with documentId "${r.id}" to update the existing document`
|
|
867
863
|
return d.warn("Duplicate filename detected",{filename:c,requestId:a||"standalone",existingDocId:r.id}),{content:[{type:"text",text:e}],isError:!0}}const n=await e.createDocument(a,{filename:c,content:u,type:h,...l&&{cliOrigin:l}})
|
|
868
864
|
d.info("Document created successfully",{documentId:n.id,filename:n.filename,requestId:a||"standalone"})
|
|
869
865
|
try{const e=s.getToolRecordClient()
|
|
870
|
-
await e.createToolRecord({type:"create-document",projectId:
|
|
866
|
+
await e.createToolRecord({type:"create-document",projectId:p,metadata:{documentId:n.id,filename:n.filename,type:n.type,contentLength:u.length,requestId:a,projectId:p},note:g})}catch(e){d.warn("Failed to create tool record",{recordError:e})}const o=a?`**Request:** ${a}\n`:"**Standalone:** Yes (not tied to a request)\n"
|
|
871
867
|
return{content:[{type:"text",text:`\u2705 Document created successfully!\n\n**Document ID:** ${n.id}\n**Filename:** ${n.filename}\n**Type:** ${n.type}\n**Size:** ${u.length} characters\n`+o+`**Created:** ${n.createdAt}\n\n`+`The document is now stored in the tracking system and can be edited using standard file modification tools by referencing its document ID (${n.id}) instead of a file path.\n\n**Examples:**\n`+`- \`replace_string\` with \`documentId: "${n.id}"\`\n`+`- \`write_file\` with \`documentId: "${n.id}"\`\n`+`- \`file_history\` with \`documentId: "${n.id}"\``}]}}catch(e){const t="Failed to create document: "+(0,o.getErrorMessage)(e)
|
|
872
868
|
return d.error("Failed to create document",{error:e}),{content:[{type:"text",text:"\u274c "+t}],isError:!0}}}catch(e){return d.error("Unexpected error in create document",{error:e}),{content:[{type:"text",text:"\u274c Unexpected error: "+(0,o.getErrorMessage)(e)}],isError:!0}}finally{u({tool:"create_document"})}}
|
|
873
869
|
const r=t(6183),n=t(1569),o=t(8824)},1599(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.SessionRequestAssociationClient=void 0
|
|
@@ -1080,94 +1076,92 @@ const e=this.online,t=await this.performHealthCheck()
|
|
|
1080
1076
|
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
1077
|
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
1078
|
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,
|
|
1079
|
+
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
1080
|
if(!r.ok)return null
|
|
1085
1081
|
const n=await r.json()
|
|
1086
1082
|
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=
|
|
1089
|
-
let
|
|
1090
|
-
if(r(t,"Spawn agent type check",{
|
|
1091
|
-
r(t,"Looking up agent type from action server",{sessionId:
|
|
1092
|
-
const s=await fetch(
|
|
1093
|
-
if(s.ok){const
|
|
1094
|
-
r(t,"Agent type response from action server",{sessionId:
|
|
1095
|
-
if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${
|
|
1083
|
+
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)()
|
|
1084
|
+
return{content:[{type:"text",text:`\u274c Unknown agent '${a}'.\n\n**Available agents:** ${e.join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}}try{const e=i?.sessionId
|
|
1085
|
+
let n=v.sessionIdentity.getIdentity()?.agentType
|
|
1086
|
+
if(r(t,"Spawn agent type check",{callerSessionId:e||null,cachedAgentType:n||null,pid:process.pid}),!n&&e)try{const o=`http://localhost:${P}/api/sessions/${encodeURIComponent(e)}/agent-type`
|
|
1087
|
+
r(t,"Looking up agent type from action server",{sessionId:e,url:o})
|
|
1088
|
+
const s=await fetch(o)
|
|
1089
|
+
if(s.ok){const o=await s.json()
|
|
1090
|
+
r(t,"Agent type response from action server",{sessionId:e,agentType:o.agentType||null,source:o.source||null,success:o.success}),o.success&&o.agentType&&(n=o.agentType,v.sessionIdentity.updateIdentity({agentType:n}))}else r(t,"Agent type lookup failed",{sessionId:e,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e,error:(0,q.getErrorMessage)(n)})}if(n){const e=(0,M.getAllowedSubagents)(n)
|
|
1091
|
+
if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${n}' cannot spawn '${a}'.\n\n**Allowed subagents for ${n}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,q.getErrorMessage)(e)})}let h
|
|
1096
1092
|
try{const e=await n(a)
|
|
1097
|
-
if(h=e?.requestContextMode,!h){const e=(0,
|
|
1093
|
+
if(h=e?.requestContextMode,!h){const e=(0,M.getBuiltInAgentConfig)(a)
|
|
1098
1094
|
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
|
-
const g=await(0,
|
|
1095
|
+
const g=await(0,I.getServerUrl)(t,o)
|
|
1100
1096
|
r(t,"serverUrl resolved",{serverUrl:g})
|
|
1101
|
-
const
|
|
1102
|
-
if(!
|
|
1103
|
-
const
|
|
1104
|
-
let m
|
|
1105
|
-
if(g)try{m=i?.sessionId||p?.sessionId||await(0,b.discoverParentSessionId)(g,o)}catch{}let y=""
|
|
1097
|
+
const p=t.basePath
|
|
1098
|
+
if(!p)throw new w.ValidationError("Working directory not available in context")
|
|
1099
|
+
const f=i?.sessionId
|
|
1100
|
+
let m=""
|
|
1106
1101
|
if(s&&l)try{const e=s.getSessionRequestAssociationClient()
|
|
1107
|
-
if(e){const t=await e.getSessionsForRequest(l,!0),r=
|
|
1102
|
+
if(e){const t=await e.getSessionsForRequest(l,!0),r=f?t.filter((e=>e.opencodeSessionId!==f)):t
|
|
1108
1103
|
if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
|
|
1109
1104
|
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
|
-
|
|
1111
|
-
l&&(
|
|
1105
|
+
m=`\u26a0\ufe0f Warning: Request ${l} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,o.warn("Spawning parallel subagent for request with existing active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){o.debug("Failed to check for existing workers",{error:(0,q.getErrorMessage)(e)})}let y,_,E=c
|
|
1106
|
+
l&&(y="requests/"+l,r(t,"Setting initialBranch for agent",{agent:a,requestId:l,initialBranch:y,agentRequestContextMode:h||"undefined"}),E="readonly"===h?`Working on request ${l} (READONLY mode - you cannot modify files, only explore and report).\n\n${c}`:`Working on request ${l}.\n\n${c}`)
|
|
1112
1107
|
let S=!1
|
|
1113
1108
|
if(u){if(_=u,o.info("Using existing session for spawn",{sessionId:_,requestId:l}),!g)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1114
1109
|
try{let e
|
|
1115
|
-
try{const t=await fetch(`http://localhost:${
|
|
1110
|
+
try{const t=await fetch(`http://localhost:${P}/api/project-settings`)
|
|
1116
1111
|
if(t.ok){const r=await t.json()
|
|
1117
1112
|
if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
|
|
1118
|
-
e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${_}/prompt_async`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:
|
|
1113
|
+
e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${_}/prompt_async`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:E}],...a?{agent:a}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
|
|
1119
1114
|
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:_,agent:a})}catch(e){throw Error("Failed to use existing session: "+(0,
|
|
1121
|
-
const i=
|
|
1122
|
-
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?"...":""}`,
|
|
1123
|
-
if(!
|
|
1124
|
-
const w=await
|
|
1115
|
+
throw Error(`Failed to send to existing session: ${r.status} ${e}`)}o.info("Prompt sent to existing session",{sessionId:_,agent:a})}catch(e){throw Error("Failed to use existing session: "+(0,q.getErrorMessage)(e))}}else{if(S=!0,r(t,"Creating session via HTTP and spawning CLI"),!g)throw Error("Cannot spawn subagent: no server URL available")
|
|
1116
|
+
const i=f;(0,C.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:i}),r(t,"Parent session discovered",{parentSessionId:i})
|
|
1117
|
+
const u=g.replace(/\/$/,"")+"/session",h=e.title?e.title:l?`[${l}] ${c.slice(0,40)}${c.length>40?"...":""}`:`${c.slice(0,50)}${c.length>50?"...":""}`,m=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentID:i,title:h})})
|
|
1118
|
+
if(!m.ok)throw Error("Failed to create session: "+m.status)
|
|
1119
|
+
const w=await m.json()
|
|
1125
1120
|
if(!w.id)throw Error("Session created but no ID returned")
|
|
1126
|
-
const
|
|
1127
|
-
r(t,"Pre-created session with parentID",{preCreatedSessionId:
|
|
1128
|
-
const
|
|
1121
|
+
const I=w.id
|
|
1122
|
+
r(t,"Pre-created session with parentID",{preCreatedSessionId:I,parentSessionId:i}),o.info("Pre-created session with parentID",{preCreatedSessionId:I,parentSessionId:i})
|
|
1123
|
+
const T=(async()=>{if(s)try{const n=s.getCLISessionClient()
|
|
1129
1124
|
if(!n)return
|
|
1130
1125
|
let o,c
|
|
1131
|
-
if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:
|
|
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
|
|
1135
|
-
r(t,"Starting model resolution",{agent:a,cwd:
|
|
1136
|
-
try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${
|
|
1126
|
+
if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:v.sessionIdentity.getIdentity()?.agentType||void 0})
|
|
1127
|
+
o=e.id,c=e.workflowId,r(t,"Registered parent session in DB",{parentSessionId:i,parentDbId:o,parentWorkflowId:c})}const l=await n.createOrUpdateSession({externalSessionId:I,providerId:"opencode",parentSessionId:o||null,title:h,status:"active",agentType:a,specialization:e.specialization,workflowId:c||void 0})
|
|
1128
|
+
r(t,"Registered child session in DB",{childSessionId:I,childDbId:l.id,parentDbId:o})}catch(e){r(t,"Failed to register sessions in DB",{error:(0,q.getErrorMessage)(e)}),o.warn("Failed to register sessions in alchemy DB",{error:(0,q.getErrorMessage)(e)})}})()
|
|
1129
|
+
let x
|
|
1130
|
+
r(t,"Starting model resolution",{agent:a,cwd:p})
|
|
1131
|
+
try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${P}/api/agents/by-name/${a}`})
|
|
1137
1132
|
const e=await n(a)
|
|
1138
1133
|
if(r(t,"Agent config result",{agent:a,agentConfig:e||"null",hasConfig:!!e}),e){const n=e.preferredProvider||"inherit",o=e.preferredModelTier||"same"
|
|
1139
1134
|
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?(
|
|
1135
|
+
const s=(0,R.resolveAgentModel)(p,n,o)
|
|
1136
|
+
r(t,"Model resolution result",{agent:a,result:s}),s.resolved?(x=s.fullModel,r(t,"Resolved agent model",{agent:a,model:x,preferredProvider:n,preferredTier:o})):r(t,"Model resolution fallback",{agent:a,reason:s.reason})}else{const e=(0,M.getBuiltInAgentConfig)(a)
|
|
1142
1137
|
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
1138
|
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&&(
|
|
1139
|
+
const s=(0,R.resolveAgentModel)(p,n,o)
|
|
1140
|
+
r(t,"Built-in model resolution result",{agent:a,result:s}),s.resolved&&(x=s.fullModel,r(t,"Resolved built-in agent model",{agent:a,model:x,preferredProvider:n,preferredTier:o}))}else r(t,"No built-in config found - using default model",{agent:a})}}catch(e){r(t,"Error resolving agent model",{agent:a,error:(0,q.getErrorMessage)(e)})}try{const e=await async function(){try{const e=`http://localhost:${P}/api/project-settings`,t=await fetch(e)
|
|
1146
1141
|
if(t.ok){const e=await t.json()
|
|
1147
1142
|
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)
|
|
1143
|
+
if(e)if(x){const o=await n(a)
|
|
1144
|
+
"same"===(o?.preferredModelTier||"same")&&(x=e,r(t,"Applied user default model (same tier)",{agent:a,userDefaultModel:e}))}else x=e,r(t,"Using user default model (no agent resolution)",{agent:a,userDefaultModel:e})}catch(e){r(t,"Failed to fetch user default model",{error:(0,q.getErrorMessage)(e)})}if(r(t,"Final resolved model before spawn",{agent:a,resolvedModel:x||"undefined (will use default)"}),await T,l&&y)try{await(0,b.ensureRequestWorktree)(p,l,o)}catch(e){r(t,"Pre-spawn worktree creation failed (non-fatal)",{requestId:l,error:(0,q.getErrorMessage)(e)})}const O=(0,k.spawnDetachedSubagent)({agent:a,prompt:E,cwd:p,sessionId:I,model:x,initialBranch:y,allowParallel:d,serverUrl:g})
|
|
1145
|
+
if(!O.success)throw Error("Failed to spawn subagent: "+O.error)
|
|
1146
|
+
_=I,r(t,"CLI spawn successful with pre-created session",{sessionId:I,pid:O.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:I,pid:O.pid,parentSessionId:i})}if(s&&l&&_&&"unknown"!==_&&"spawning"!==_)try{const e=s.getSessionRequestAssociationClient()
|
|
1147
|
+
if(e&&(e.createAssociation(_,l).then((()=>o.info("Created session-request association",{sessionId:_,requestId:l}))).catch((e=>o.warn("Failed to create session-request association",{error:(0,q.getErrorMessage)(e),sessionId:_,requestId:l}))),"coder"===a)){const e=s.getRequestClient()
|
|
1148
|
+
e&&e.updateRequest(l,{cliOrigin:{providerId:"opencode",sessionId:_,createdAt:(new Date).toISOString()}}).catch((e=>o.debug("Failed to update request cliOrigin",{error:(0,q.getErrorMessage)(e)})))}}catch(e){o.warn("Failed to create session-request association",{error:(0,q.getErrorMessage)(e),sessionId:_,requestId:l})}let T=m
|
|
1149
|
+
return u?T+=`Prompt sent to existing session ${_}.`:(T+=`Background ${a} subagent spawned successfully.`,_&&"unknown"!==_&&"spawning"!==_&&(T+=`\n[SESSION:${_}]`)),l&&(T+="\nWorking on: "+l),T+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:T}]}}async function s(e,t,r,n,o,s,i){const a=await(0,I.getServerUrl)(r,n)
|
|
1156
1150
|
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
|
|
1151
|
+
if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId
|
|
1158
1152
|
if(t){const r=o.getCLISessionClient()
|
|
1159
1153
|
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:${
|
|
1154
|
+
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
|
|
1155
|
+
if(!c)try{const t=`http://localhost:${P}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
|
|
1162
1156
|
if(r.ok){const e=await r.json()
|
|
1163
1157
|
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
1158
|
try{let r
|
|
1165
|
-
try{const e=await fetch(`http://localhost:${
|
|
1159
|
+
try{const e=await fetch(`http://localhost:${P}/api/project-settings`)
|
|
1166
1160
|
if(e.ok){const t=await e.json()
|
|
1167
1161
|
if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
|
|
1168
1162
|
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
1163
|
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,
|
|
1164
|
+
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
1165
|
if(60>t)return t+"s"
|
|
1172
1166
|
const r=Math.floor(t/60)
|
|
1173
1167
|
return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function a(e){const t=[]
|
|
@@ -1177,20 +1171,20 @@ const s=n.path||n.file||n.directory,i=n.needle||n.query||n.pattern
|
|
|
1177
1171
|
"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
1172
|
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
1173
|
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&&
|
|
1174
|
+
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
1175
|
for(const o of e.trim().split("\n")){if(!o)continue
|
|
1182
1176
|
const[e,s]=o.split("\t")
|
|
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,
|
|
1177
|
+
"-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function u(e,r,n,o){const s=await(0,I.getServerUrl)(r,n)
|
|
1184
1178
|
if(!s)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1185
1179
|
n.info("Checking status of subagent session",{sessionId:e})
|
|
1186
1180
|
try{const c=`${s.replace(/\/$/,"")}/session/${e}`,u=await fetch(c)
|
|
1187
1181
|
if(!u.ok)return{content:[{type:"text",text:`Session ${e} not found or has exited.`}],isError:!0}
|
|
1188
|
-
const h=await u.json(),g=`${s.replace(/\/$/,"")}/session/${e}/message`,
|
|
1189
|
-
let
|
|
1190
|
-
if(
|
|
1191
|
-
for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(
|
|
1182
|
+
const h=await u.json(),g=`${s.replace(/\/$/,"")}/session/${e}/message`,p=await fetch(g)
|
|
1183
|
+
let f={input:0,output:0,reasoning:0},m="",y=l(null,h.time.updated)
|
|
1184
|
+
if(p.ok){const e=await p.json()
|
|
1185
|
+
for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(f.input+=t.info.tokens.input||0,f.output+=t.info.tokens.output||0,f.reasoning+=t.info.tokens.reasoning||0)
|
|
1192
1186
|
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,b=y.isReady,I=
|
|
1187
|
+
y=l(t.lastActivityTime,h.time.updated),t.current&&(m+="\nCurrent: "+t.current),t.recent.length>0&&(m+="\nRecent: "+t.recent.join(", "))}const w=Date.now()-h.time.created,k=y.status,b=y.isReady,I=f.input+f.output+f.reasoning
|
|
1194
1188
|
let v="",C="",_=null
|
|
1195
1189
|
if(o)try{const t=o.getSessionRequestAssociationClient()
|
|
1196
1190
|
if(t){const r=await t.getActiveRequestsForSession(e,!1)
|
|
@@ -1205,21 +1199,21 @@ if(e.trim())return d(e)}try{const t=n(`git log main --merges --oneline -n 50 --g
|
|
|
1205
1199
|
if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
|
|
1206
1200
|
if(o.trim())return{...d(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
|
|
1207
1201
|
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: ${b?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${I.toLocaleString()} (in: ${
|
|
1202
|
+
v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${k} (${y.detail})\nReady for input: ${b?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${I.toLocaleString()} (in: ${f.input.toLocaleString()}, out: ${f.output.toLocaleString()}${f.reasoning>0?", reasoning: "+f.reasoning.toLocaleString():""})${m}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,q.getErrorMessage)(e))}}async function h(e,t,r){const n=await(0,I.getServerUrl)(t,r)
|
|
1209
1203
|
if(!n)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1210
1204
|
r.info("Aborting subagent session",{sessionId:e})
|
|
1211
1205
|
try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
|
|
1212
1206
|
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,
|
|
1207
|
+
throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,q.getErrorMessage)(e))}}async function g(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:c,minTokens:d,maxTokens:u,maxAgeHours:h}=n,g=await(0,I.getServerUrl)(e,t)
|
|
1214
1208
|
if(!g)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1215
1209
|
t.info("Listing sessions",{filters:n})
|
|
1216
1210
|
try{const e=g.replace(/\/$/,"")+"/session",t=await fetch(e)
|
|
1217
1211
|
if(!t.ok)throw Error("Failed to fetch sessions: "+t.status)
|
|
1218
|
-
let
|
|
1219
|
-
if(0===
|
|
1220
|
-
n.parentSessionId&&(
|
|
1221
|
-
const
|
|
1222
|
-
let w=
|
|
1212
|
+
let p=await t.json()
|
|
1213
|
+
if(0===p.length)return{content:[{type:"text",text:"No sessions found."}]}
|
|
1214
|
+
n.parentSessionId&&(p=p.filter((e=>(e.parentId||e.parentID)===n.parentSessionId))),p.sort(((e,t)=>t.time.created-e.time.created))
|
|
1215
|
+
const f=g.replace(/\/$/,"")+"/session/status",m=await fetch(f),y=m.ok?await m.json():{}
|
|
1216
|
+
let w=p
|
|
1223
1217
|
if(o&&(w=w.filter((e=>"idle"!==(y[e.id]?.type||"idle")))),void 0!==h){const e=36e5*h,t=Date.now()-e
|
|
1224
1218
|
w=w.filter((e=>e.time.created>=t))}if(0===w.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1225
1219
|
let k={}
|
|
@@ -1227,10 +1221,10 @@ if(r)try{const e=r.getCLISessionClient()
|
|
|
1227
1221
|
e&&(k=await e.batchEnrich(w.map((e=>e.id))))}catch{}const b=g.replace(/\/$/,""),I=await Promise.allSettled(w.map((e=>fetch(`${b}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),v=[]
|
|
1228
1222
|
for(let e=0;e<w.length;e++){const t=w[e],r=Date.now()-t.time.created
|
|
1229
1223
|
let o=0,i=null,c=[],h=l(null,t.time.updated)
|
|
1230
|
-
const g=I[e],
|
|
1231
|
-
for(const e of
|
|
1232
|
-
if(
|
|
1233
|
-
h=l(e.lastActivityTime,t.time.updated),i=e.current||null,c=e.recent}const
|
|
1224
|
+
const g=I[e],p="fulfilled"===g.status?g.value:[]
|
|
1225
|
+
for(const e of p)"assistant"===e.info.role&&e.info.tokens&&(o+=(e.info.tokens.input||0)+(e.info.tokens.output||0)+(e.info.tokens.reasoning||0))
|
|
1226
|
+
if(p.length>0){const e=a(p)
|
|
1227
|
+
h=l(e.lastActivityTime,t.time.updated),i=e.current||null,c=e.recent}const f=h.status
|
|
1234
1228
|
if(void 0!==d&&d>o)continue
|
|
1235
1229
|
if(void 0!==u&&o>u)continue
|
|
1236
1230
|
const m=k[t.id]
|
|
@@ -1243,31 +1237,31 @@ b.push(...e,...t)
|
|
|
1243
1237
|
const r=[]
|
|
1244
1238
|
e.length>0&&r.push("active: "+e.join(", ")),t.length>0&&r.push("prev: "+t.join(", ")),r.length>0&&(y=` [${r.join(" | ")}]`)}if(s&&!b.includes(s))continue
|
|
1245
1239
|
const C=t.title||"Untitled",_=C.length>50?C.slice(0,47)+"...":C
|
|
1246
|
-
v.push({id:t.id,title:_,status:
|
|
1240
|
+
v.push({id:t.id,title:_,status:f,age:r,totalTokens:o,requestsInfo:y,allRequestIds:b,statusDetail:h.detail,specialization:m?.specialization??null,currentAction:i,recentActions:c})}if(0===v.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1247
1241
|
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
1242
|
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,
|
|
1243
|
+
return{content:[{type:"text",text:`Found ${C.length} session${1!==C.length?"s":""}${E}:\n\n${_.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,q.getErrorMessage)(e))}}var p,f=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1250
1244
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
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||(
|
|
1245
|
+
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),m=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),y=this&&this.__importStar||(p=function(e){return p=Object.getOwnPropertyNames||function(e){var t=[]
|
|
1252
1246
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
1253
|
-
return t},
|
|
1247
|
+
return t},p(e)},function(e){if(e&&e.__esModule)return e
|
|
1254
1248
|
var t={}
|
|
1255
|
-
if(null!=e)for(var r=
|
|
1249
|
+
if(null!=e)for(var r=p(e),n=0;n<r.length;n++)"default"!==r[n]&&f(t,e,r[n])
|
|
1256
1250
|
return m(t,e),t})
|
|
1257
1251
|
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
1252
|
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=
|
|
1260
|
-
let
|
|
1261
|
-
switch(c.info("Processing subagent_operations",{operation:
|
|
1253
|
+
const r=E.validateArgs(e,_.SubagentOperationsSchema),{sessionId:d,operation:p}=r
|
|
1254
|
+
let f
|
|
1255
|
+
switch(c.info("Processing subagent_operations",{operation:p,sessionId:d}),p){case"spawn":f=await o(r.spawn,t,c,i,a)
|
|
1262
1256
|
break
|
|
1263
|
-
case"continue":
|
|
1257
|
+
case"continue":f=await s(d,r.continue.prompt,t,c,i,void 0,a)
|
|
1264
1258
|
break
|
|
1265
|
-
case"check-status":
|
|
1259
|
+
case"check-status":f=await u(d,t,c,i)
|
|
1266
1260
|
break
|
|
1267
|
-
case"abort":
|
|
1261
|
+
case"abort":f=await h(d,t,c)
|
|
1268
1262
|
break
|
|
1269
1263
|
case"read-messages":const e=r.readMessages?.limit??1
|
|
1270
|
-
|
|
1264
|
+
f=await async function(e,t,r,n){const o=await(0,I.getServerUrl)(r,n)
|
|
1271
1265
|
if(!o)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1272
1266
|
n.info("Reading messages from subagent session",{sessionId:e,limit:t})
|
|
1273
1267
|
try{const r=`${o.replace(/\/$/,"")}/session/${e}/message?limit=${t}`,n=await fetch(r)
|
|
@@ -1276,13 +1270,13 @@ throw Error("Failed to fetch messages: "+n.status)}const s=await n.json()
|
|
|
1276
1270
|
if(0===s.length)return{content:[{type:"text",text:`Session ${e} has no messages yet.`}]}
|
|
1277
1271
|
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
1272
|
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,
|
|
1273
|
+
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
1274
|
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
|
|
1282
|
-
|
|
1275
|
+
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}
|
|
1276
|
+
f=await g(t,c,i,n)
|
|
1283
1277
|
break
|
|
1284
|
-
default:throw new w.ValidationError("Unknown operation: "+
|
|
1285
|
-
const w=t(9860),k=t(8035),b=t(
|
|
1278
|
+
default:throw new w.ValidationError("Unknown operation: "+p)}return l({success:!0}),n.incrementCounter(`subagent_operations_${p}_success`,1),f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,q.getErrorMessage)(e)}],isError:!0}}}
|
|
1279
|
+
const w=t(9860),k=t(8035),b=t(2424),I=t(7617),v=t(6688),C=t(7280),_=t(6183),E=y(t(5967)),q=t(8824),S=t(9896),T=t(6928),M=t(8955),R=t(5671),P=3456,x=6e4,O=3e5},1791(e,exports,t){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
1280
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
|
|
1287
1281
|
const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
|
|
1288
1282
|
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")
|
|
@@ -1429,19 +1423,19 @@ try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.ge
|
|
|
1429
1423
|
if(g.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
|
|
1430
1424
|
if(g.push("reqId: "+(t||"NONE")),t){const e=await o.proxyGet(`/api/projects/${n.projectId}/requests/${t}/test-runs`),r=e?.data||e||[],s=Array.isArray(r)?r.find((e=>e.worktreePath||e.worktree_path)):null
|
|
1431
1425
|
g.push(`runs: ${Array.isArray(r)?r.length:0}, withWorktree: ${s?.id||"NONE"}, path: ${s?.worktreePath||s?.worktree_path||"NONE"}`),s&&(h=s.worktreePath||s.worktree_path,c.info("Using test worktree from request test run",{worktreePath:h,reqId:t}))}}}catch(e){c.warn("Failed to resolve test worktree",{error:(0,r.getErrorMessage)(e)})}if(!h)return a({success:!1,error:"no_worktree"}),{content:[{type:"text",text:`No test worktree found.\n\nDiagnostics:\n${g.length>0?g.map((e=>"\u2022 "+e)).join("\n"):"\u2022 No session identity found"}\n\nEnsure this session is linked to a test process and a test run has been created.`}],isError:!0}
|
|
1432
|
-
const
|
|
1426
|
+
const p=[]
|
|
1433
1427
|
for(const t of l){c.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:h})
|
|
1434
1428
|
try{const e=d(t.command,{cwd:h,timeout:1e3*t.timeout,encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:"/bin/sh",env:{...u.env,FORCE_COLOR:"0"}})
|
|
1435
|
-
|
|
1436
|
-
if(
|
|
1429
|
+
p.push({name:t.name,command:t.command,exitCode:0,output:e.slice(-4e3),timedOut:!1})}catch(r){const n=!0===r.killed,o=((r.stdout||"")+"\n"+(r.stderr||"")).trim().slice(-4e3),s=r.status??1
|
|
1430
|
+
if(p.push({name:t.name,command:t.command,exitCode:s,output:o,timedOut:n}),"setup"===e.commandName)break}}const f=p.every((e=>0===e.exitCode)),m=p.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
|
|
1437
1431
|
return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\``})).join("\n\n")
|
|
1438
|
-
return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${
|
|
1432
|
+
return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${f?"PASSED":"FAILED"}\n\n${m}`}]}}catch(e){return a({success:!1,error:"execution_error"}),{content:[{type:"text",text:"Failed to execute test command: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleReportTestResults=async function(e,o,s,i,a){const c=a.startTimer("tool_execution_time")
|
|
1439
1433
|
try{const{sessionIdentity:l}=await Promise.resolve().then(t.bind(t,6688)),d=await l.getSessionRequestId(s,i)
|
|
1440
1434
|
if(!d)return c({success:!1,error:"no_request_association"}),{content:[{type:"text",text:"Cannot report test results: this session is not associated with a request."}],isError:!0}
|
|
1441
|
-
const u=await s.proxyGet(`/api/projects/${o.projectId}/requests/${d}/test-runs`),h=u?.data||u||[],g=Array.isArray(h)?h:[],
|
|
1442
|
-
if(!
|
|
1443
|
-
const p
|
|
1444
|
-
await s.proxyPatch(`/api/projects/${o.projectId}/test-runs/${
|
|
1435
|
+
const u=await s.proxyGet(`/api/projects/${o.projectId}/requests/${d}/test-runs`),h=u?.data||u||[],g=Array.isArray(h)?h:[],p=g.find((e=>"pending"===e.status||"running"===e.status))||g[0]
|
|
1436
|
+
if(!p)return c({success:!1,error:"no_test_run"}),{content:[{type:"text",text:`No test run found for request ${d}.`}],isError:!0}
|
|
1437
|
+
const f=p.id
|
|
1438
|
+
await s.proxyPatch(`/api/projects/${o.projectId}/test-runs/${f}`,{status:e.status,results:e.results})
|
|
1445
1439
|
const m="passed"===e.status?"\u2705":"failed"===e.status?"\u274c":"\u26a0\ufe0f"
|
|
1446
1440
|
try{const t=s.getRequestClient()
|
|
1447
1441
|
"passed"===e.status?(await t.updateRequest(d,{status:"ready_for_merge"}),i.info("Tests passed, set request to ready_for_merge",{requestId:d})):(await t.updateRequest(d,{status:"in_progress"}),i.info("Tests failed, set request back to in_progress",{requestId:d}))}catch(e){i.warn("Failed to update request status after test results",{requestId:d,error:(0,r.getErrorMessage)(e)})}const y="passed"===e.status?"\n\nAll tests passed \u2014 the coder can now call `merge` to merge this request.":"\n\nTests failed \u2014 the coder should fix the issues and call `complete` again.",w=`${m} Test run ${e.status} for request ${d}\n\n${e.results.summary}${y}`
|
|
@@ -1556,7 +1550,7 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
1556
1550
|
var t={}
|
|
1557
1551
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
1558
1552
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1559
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,t,r,n,o,s,i,
|
|
1553
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,t,r,n,o,s,i,f){const m=s.child({tool:"move_files"}),y=Date.now()
|
|
1560
1554
|
let w,k,b=d.FileOperationPhase.VALIDATION
|
|
1561
1555
|
const I={toolName:"move-files",operationName:"write",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"move-files",metricsPrefix:"move_files",successMessage:"Successfully moved files",failureMessage:"Failed to move files"}
|
|
1562
1556
|
try{const s=d.validateArgs(e,l.MoveFilesSchema),{taskId:u,operations:h,comment:v}=s
|
|
@@ -1575,7 +1569,7 @@ throw Error(M.error)}let R={hadUserMods:!1,userModsCommitHash:void 0}
|
|
|
1575
1569
|
if(t.git)try{m.debug("[MOVE-FILES] Checking for user changes before move operations")
|
|
1576
1570
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"move-files",{requestId:q,taskId:u,workspaceManager:t.workspaceManager},m,i)
|
|
1577
1571
|
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}),b=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("move_files_phase",1,{phase:b})
|
|
1578
|
-
const{toolRecordId:P,localToolRecordId:x}=await d.createFileOperationRecords(u,q,t.projectId,I.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},r,n,m,i,I.metricsPrefix,
|
|
1572
|
+
const{toolRecordId:P,localToolRecordId:x}=await d.createFileOperationRecords(u,q,t.projectId,I.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},r,n,m,i,I.metricsPrefix,f)
|
|
1579
1573
|
w=P,k=P,b=I.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:b})
|
|
1580
1574
|
const O=[]
|
|
1581
1575
|
let j=0
|
|
@@ -1583,7 +1577,7 @@ for(const e of _){const t={operation:{source:e.source,destination:e.destination}
|
|
|
1583
1577
|
try{try{await a.default.access(e.fullSource)}catch(t){throw Error("Source path not accessible: "+e.source)}const r=(await a.default.stat(e.fullSource)).isDirectory()
|
|
1584
1578
|
t.isDirectory=r
|
|
1585
1579
|
const n=c.default.dirname(e.fullDestination)
|
|
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,
|
|
1580
|
+
try{await a.default.mkdir(n,{recursive:!0})}catch(e){throw Error("Failed to create destination directory: "+n)}try{throw await a.default.access(e.fullDestination),Error("Destination already exists: "+e.destination)}catch(e){if(!(e instanceof Error&&e.message.includes("ENOENT")))throw e}await a.default.rename(e.fullSource,e.fullDestination),t.success=!0,j++,m.info("Successfully moved "+(r?"directory":"file"),{source:e.source,destination:e.destination,isDirectory:r})}catch(r){t.error=(0,p.getErrorMessage)(r),m.warn(`Failed to move ${e.source} to ${e.destination}`,{error:t.error})}O.push(t)}const $=Date.now()-y
|
|
1587
1581
|
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
1582
|
let D=null
|
|
1589
1583
|
if(j>0){b=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:b})
|
|
@@ -1597,13 +1591,21 @@ if(j===h.length)L=`Successfully moved all ${h.length} ${1===h.length?"item":"ite
|
|
|
1597
1591
|
else if(j>0){const e=O.filter((e=>!e.success))
|
|
1598
1592
|
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
1593
|
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,
|
|
1601
|
-
if(i.recordValue("move_files_time",s),i.incrementCounter("move_files_errors",1),m.error("Error in move-files operation:",{error:(0,
|
|
1602
|
-
try{await d.updateFileOperationRecords(e.taskId,w,k,e.operations?.[0]?.source||"unknown",I.recordType,"Failed to move files",{status:"failed",error:(0,
|
|
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),
|
|
1594
|
+
await n.createToolRecord({...r?{}:{taskId:e.taskId},projectId:t.projectId,type:"move-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment,error:(0,p.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:"Failed to move files - "+(0,p.getErrorMessage)(o)})}catch(t){m.error("Failed to create failure record for move-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,operationCount:e.operations?.length||0})}const s=Date.now()-y
|
|
1595
|
+
if(i.recordValue("move_files_time",s),i.incrementCounter("move_files_errors",1),m.error("Error in move-files operation:",{error:(0,p.getErrorMessage)(o),time:s}),(w||k)&&e.taskId){b=d.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
1596
|
+
try{await d.updateFileOperationRecords(e.taskId,w,k,e.operations?.[0]?.source||"unknown",I.recordType,"Failed to move files",{status:"failed",error:(0,p.getErrorMessage)(o),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",r,n,m,i,I.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:w,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,b,m,i,e,I)}}
|
|
1597
|
+
const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(7478),p=t(8824)},2422(module){module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2424(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ensureRequestWorktree=async function(e,t,i){const a="requests/"+t,c=(0,n.join)(e,s.ALCHEMY_DIR_NAME,"worktrees"),l=(0,n.join)(c,t)
|
|
1598
|
+
if((0,r.existsSync)(l))return void i.info("Worktree already exists on disk, skipping pre-spawn creation",{requestId:t,worktreePath:l})
|
|
1599
|
+
const d=(0,o.simpleGit)(e);(0,r.mkdirSync)(c,{recursive:!0})
|
|
1600
|
+
try{await d.raw(["worktree","prune"])}catch{}const u=await d.branch(),h=u.all.includes(a)
|
|
1601
|
+
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})
|
|
1602
|
+
else{const e=u.all.includes("main")?"main":"master"
|
|
1603
|
+
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+""
|
|
1604
|
+
i.warn("Pre-spawn: failed to create worktree (MCP process will retry)",{requestId:t,error:r})}}
|
|
1605
|
+
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
1606
|
const r=t(6183),n=t(3707)
|
|
1605
1607
|
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),
|
|
1608
|
+
const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),g=t(5459),p=t(4805),f=t(260),m=t(2283),y=t(4165),w=t(7834),k=t(9373),b=t(6111),I=t(700),v=t(2783),C=t(2601),_=t(1722),E=t(7257),q=t(9230),S=t(5216),T=t(6473),M=t(4921),R=t(8850),P=t(3556),x=t(1391),O=t(6315),j=t(7713),$=t(6252),D=t(213),A=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),U=t(5247),W=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(g.def),(0,r.registerTool)(p.def),(0,r.registerTool)(f.def),(0,r.registerTool)(m.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(k.def),(0,r.registerTool)(b.def),(0,r.registerTool)(I.def),(0,r.registerTool)(v.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(E.def),(0,r.registerTool)(q.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(M.def),(0,r.registerTool)(R.def),(0,r.registerTool)(P.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(j.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(L.def),(0,r.registerTool)(z.def),(0,r.registerTool)(B.def),(0,r.registerTools)(H.metaDefs),(0,r.registerTools)(U.testingDefs),(0,r.registerTools)(W.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){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
1609
|
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
1610
|
let l=""
|
|
1609
1611
|
if(s||void 0===o?.lineCount||(l=` (${i(o.lineCount)} lines)`),s&&o?.subtreeTotals){const{files:e,lines:t}=o.subtreeTotals
|
|
@@ -1626,10 +1628,10 @@ let t=e,r=0
|
|
|
1626
1628
|
for(;t>=1024&&4>r;)t/=1024,r++
|
|
1627
1629
|
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
1630
|
try{const{fullPath:d}=b.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),g=[]
|
|
1629
|
-
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=b.validateAndNormalizePath(u,t),
|
|
1631
|
+
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=b.validateAndNormalizePath(u,t),p=await y.default.stat(h),f=d.isFile()?w.default.extname(d.name).toLowerCase():""
|
|
1630
1632
|
let m
|
|
1631
|
-
d.isFile()&&(m=await r(h,
|
|
1632
|
-
const k={name:d.name,isDirectory:d.isDirectory(),depth:n,size:
|
|
1633
|
+
d.isFile()&&(m=await r(h,p.size,f))
|
|
1634
|
+
const k={name:d.name,isDirectory:d.isDirectory(),depth:n,size:p.size,modified:p.mtime,extension:f,lineCount:m}
|
|
1633
1635
|
d.isDirectory()&&(s-1>n?(k.children=await o(u,t,n+1,s,i,l),k.children&&k.children.length>0&&(k.subtreeTotals=c(k.children))):k.subtreeTotals=await a(u,t,l)),g.push(k)}catch(e){l.debug("Excluding entry from tree: "+d.name,{reason:(0,v.getErrorMessage)(e)})}return u(g,i)}catch(t){return l.debug(`Failed to build tree for ${e}:`,{error:(0,v.getErrorMessage)(t)}),[]}}function s(e,t="name",r=""){if(0===e.length)return""
|
|
1634
1636
|
const o=[]
|
|
1635
1637
|
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?"/":""
|
|
@@ -1655,21 +1657,21 @@ case"type":const o=e.extension||"",s=r.extension||""
|
|
|
1655
1657
|
return o!==s?o.localeCompare(s):e.name.localeCompare(r.name)
|
|
1656
1658
|
default:return e.name.localeCompare(r.name)}}))}var h,g=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1657
1659
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1658
|
-
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]}),
|
|
1660
|
+
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]}),p=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),f=this&&this.__importStar||(h=function(e){return h=Object.getOwnPropertyNames||function(e){var t=[]
|
|
1659
1661
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
1660
1662
|
return t},h(e)},function(e){if(e&&e.__esModule)return e
|
|
1661
1663
|
var t={}
|
|
1662
1664
|
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&g(t,e,r[n])
|
|
1663
|
-
return
|
|
1665
|
+
return p(t,e),t}),m=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1664
1666
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
|
|
1665
1667
|
let g=b.FileOperationPhase.VALIDATION
|
|
1666
1668
|
b.FileOperationPhase.FILE_WRITE
|
|
1667
|
-
try{const
|
|
1668
|
-
i.info("Listing directory: "+
|
|
1669
|
-
const{normalizedPath:C,fullPath:_}=b.validateAndNormalizePath(
|
|
1669
|
+
try{const p=b.validateArgs(e,k.ListDirectorySchema),{path:f,levels:m=1,sortBy:I="name"}=p
|
|
1670
|
+
i.info("Listing directory: "+f)
|
|
1671
|
+
const{normalizedPath:C,fullPath:_}=b.validateAndNormalizePath(f,t)
|
|
1670
1672
|
g=b.FileOperationPhase.FILE_WRITE
|
|
1671
|
-
try{if(!(await y.default.stat(_)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+
|
|
1672
|
-
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: "+
|
|
1673
|
+
try{if(!(await y.default.stat(_)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+f}],isError:!0}
|
|
1674
|
+
await y.default.access(_,y.default.constants.R_OK)}catch(e){return e instanceof Error&&"ENOENT"===e.code?{content:[{type:"text",text:"Directory does not exist: "+f}],isError:!0}:e instanceof Error&&"EACCES"===e.code?{content:[{type:"text",text:"Directory not accessible: "+f}],isError:!0}:{content:[{type:"text",text:"Cannot access directory: "+f}],isError:!0}}let E,q
|
|
1673
1675
|
if(m>1){i.info(`Building tree structure for: ${C} (levels: ${m}, sortBy: ${I})`)
|
|
1674
1676
|
const e=await o(C,t,0,m,I,i)
|
|
1675
1677
|
if(e.length>0){const t=s(e,I)
|
|
@@ -1682,7 +1684,7 @@ E+="\n\nBranch: "+(S?.branchName||"unknown")
|
|
|
1682
1684
|
const T=Date.now()-h
|
|
1683
1685
|
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
1686
|
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),b=
|
|
1687
|
+
const y=m(t(1943)),w=m(t(6928)),k=t(6183),b=f(t(5967)),I=t(3253),v=t(8824),C=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore",".config",".conf",".ini",".cfg"]),_=1048576},2601(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1686
1688
|
const r=t(6183),n=t(76)
|
|
1687
1689
|
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
1690
|
const r=t(7645),n=t(2161)
|
|
@@ -1735,12 +1737,12 @@ if(!r())return t.level=(0,l.isDevBuild)()?c.LogLevel.INFO:c.LogLevel.ERROR,t.log
|
|
|
1735
1737
|
if("true"===process.env.DEBUG_LOGGING?.toLowerCase()){t.level=c.LogLevel.DEBUG,t.logToFile=!0
|
|
1736
1738
|
const r=e||process.cwd()
|
|
1737
1739
|
t.logFilePath=i.default.join(r,"logs","debug.log")}const n=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
1738
|
-
return n&&Object.values(c.LogLevel).includes(n)&&(t.level=n),t}(e.baseDir),...e},{level:o=c.LogLevel.INFO,serviceName:g="mcp-service",logToFile:
|
|
1739
|
-
if(console&&m.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),
|
|
1740
|
-
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(
|
|
1740
|
+
return n&&Object.values(c.LogLevel).includes(n)&&(t.level=n),t}(e.baseDir),...e},{level:o=c.LogLevel.INFO,serviceName:g="mcp-service",logToFile:p=!1,logFilePath:f="./logs/app.log",console=!0}=t,m=[]
|
|
1741
|
+
if(console&&m.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),p){!function(e){const t=i.default.dirname(e)
|
|
1742
|
+
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(f)
|
|
1741
1743
|
const e=o===c.LogLevel.DEBUG&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()
|
|
1742
|
-
m.push(new s.default.transports.File({filename:
|
|
1743
|
-
return o===c.LogLevel.DEBUG&&
|
|
1744
|
+
m.push(new s.default.transports.File({filename:f,format:e?h:u}))}const y=s.default.createLogger({level:o,defaultMeta:{service:g},transports:m})
|
|
1745
|
+
return o===c.LogLevel.DEBUG&&p&&r()&&y.info("Enhanced logging initialized",{level:o,serviceName:g,logToFile:p,logFilePath:f,debugLogging:process.env.DEBUG_LOGGING}),{error(e,t){y.error(e,t)},warn(e,t){y.warn(e,t)},info(e,t){y.info(e,t)},debug(e,t){y.debug(e,t)},child(e){const r=y.child(e)
|
|
1744
1746
|
return{error(e,t){r.error(e,t)},warn(e,t){r.warn(e,t)},info(e,t){r.info(e,t)},debug(e,t){r.debug(e,t)},child(e){return n({...t,serviceName:`${g}:${e.component||"nested"}`})}}}}}var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1745
1747
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.createLogger=n,exports.createEnvLogger=function(e={}){return n(e)},exports.isDebugToolsEnabled=r,exports.isDebugLoggingEnabled=function(){return!!r()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()},exports.getDebugLevelFromEnv=function(){if(!r())return c.LogLevel.INFO
|
|
1746
1748
|
const e=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
@@ -1772,14 +1774,14 @@ const a="binary"!==n?i.split("\n").length:void 0
|
|
|
1772
1774
|
if(e.lines&&"binary"!==n){const t=(0,g.parseLineSpec)(e.lines)
|
|
1773
1775
|
i=(0,g.extractLines)(i,t).text}const c="binary"!==n?i.split("\n").length:void 0
|
|
1774
1776
|
return{type:"file",path:r,content:i,success:!0,lineCount:c,totalLines:a,size:s.size,originalRequest:e}}catch(t){let r
|
|
1775
|
-
return r=t instanceof Error&&"ENOENT"===t.code?"File not found: "+e.path:(0,
|
|
1777
|
+
return r=t instanceof Error&&"ENOENT"===t.code?"File not found: "+e.path:(0,p.getErrorMessage)(t),{type:"file",path:e.path,content:"",success:!1,error:r,originalRequest:e}}}async function n(e,t,r,n){try{if(!t.documentFileManager)return{type:"document",documentId:e.documentId,content:"",success:!1,error:"Document file manager not available"}
|
|
1776
1778
|
const r=await t.documentFileManager.getDocumentAsFile(e.documentId),o=t.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
1777
1779
|
let s
|
|
1778
1780
|
s="binary"===n?(await l.default.readFile(r)).toString("base64"):await l.default.readFile(r,n)
|
|
1779
1781
|
const i="binary"!==n?s.split("\n").length:void 0
|
|
1780
1782
|
if(e.lines&&"binary"!==n){const t=(0,g.parseLineSpec)(e.lines)
|
|
1781
1783
|
s=(0,g.extractLines)(s,t).text}const a="binary"!==n?s.split("\n").length:void 0,c=await l.default.stat(r)
|
|
1782
|
-
return{type:"document",documentId:e.documentId,filename:o?.filename,content:s,success:!0,lineCount:a,totalLines:i,size:c.size,originalRequest:e}}catch(t){return{type:"document",documentId:e.documentId,content:"",success:!1,error:(0,
|
|
1784
|
+
return{type:"document",documentId:e.documentId,filename:o?.filename,content:s,success:!0,lineCount:a,totalLines:i,size:c.size,originalRequest:e}}catch(t){return{type:"document",documentId:e.documentId,content:"",success:!1,error:(0,p.getErrorMessage)(t),originalRequest:e}}}var o,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1783
1785
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1784
1786
|
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=[]
|
|
1785
1787
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -1796,20 +1798,20 @@ i.info("Reading multiple files and documents",{totalRequests:c.length,encoding:l
|
|
|
1796
1798
|
const h=[],g=[]
|
|
1797
1799
|
for(const e of c)e.path?h.push({type:"file",path:e.path,lines:e.lines}):e.documentId&&g.push({type:"document",documentId:e.documentId,lines:e.lines})
|
|
1798
1800
|
i.info("Request breakdown",{fileRequests:h.length,documentRequests:g.length})
|
|
1799
|
-
const
|
|
1800
|
-
for(const e of h)
|
|
1801
|
-
for(const e of g)
|
|
1802
|
-
const
|
|
1801
|
+
const p=[]
|
|
1802
|
+
for(const e of h)p.push(r(e,t,0,l))
|
|
1803
|
+
for(const e of g)p.push(n(e,t,0,l))
|
|
1804
|
+
const f=await Promise.all(p)
|
|
1803
1805
|
let m=""
|
|
1804
1806
|
if(t.getCurrentBranchContext)try{const e=await t.getCurrentBranchContext()
|
|
1805
|
-
e.branch&&(m=`**Current Branch:** ${e.branch}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const y=
|
|
1807
|
+
e.branch&&(m=`**Current Branch:** ${e.branch}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const y=f.filter((e=>e.success)).length,w=f.filter((e=>!e.success)).length,k=f.length
|
|
1806
1808
|
let b="## Read Files/Documents\n\n"
|
|
1807
1809
|
m&&(b+=m),b+=`**Total Requests:** ${k} - **Successful:** ${y} - **Failed:** ${w}\n\n`
|
|
1808
|
-
for(let e=0;e<
|
|
1810
|
+
for(let e=0;e<f.length;e++){const t=f[e]
|
|
1809
1811
|
"file"===t.type?b+=`File ${e+1}: ${t.path}\n`:(b+=`Document ${e+1}: ${t.documentId}`,t.filename&&(b+=` (${t.filename})`),b+="\n"),t.success?(b+="**Status:** Success\n",t.lineCount&&t.totalLines&&(b+=`Lines Read / Total Lines ${t.lineCount} / ${t.totalLines}\n`),t.originalRequest?.lines&&t.totalLines&&(b+=`**Lines:** ${t.originalRequest.lines}\n`),b+=`\n**Content:**\n\`\`\`\n${t.content}\n\`\`\`\n`):(b+="**Status:** Failed\n",b+=`**Error:** ${t.error}\n`),b+="\n"}const I=0===w
|
|
1810
1812
|
return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:k,successfulReads:y,failedReads:w,success:I}),s.incrementCounter("read_files_total",1,{success:I}),{content:[{type:"text",text:b}],isError:!I}}catch(e){const t=Date.now()-a
|
|
1811
|
-
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,
|
|
1812
|
-
const l=c(t(1943)),d=t(6183),u=t(1569),h=a(t(5967)),g=t(9470),
|
|
1813
|
+
return i.error("Read multiple files operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),s.incrementCounter("read_files_errors",1),{content:[{type:"text",text:"\u274c **Read Operation Failed:** "+(0,p.getErrorMessage)(e)}],isError:!0}}}
|
|
1814
|
+
const l=c(t(1943)),d=t(6183),u=t(1569),h=a(t(5967)),g=t(9470),p=t(8824)},2968(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.TaskClient=void 0
|
|
1813
1815
|
const r=t(8824),n=t(7645),o=t(2161),s=t(5172)
|
|
1814
1816
|
class i extends n.ConnectionAwareClient{async createTask(e){if(this.logger.debug("Creating task",{taskInput:e}),!e.projectId){const t=this.projectClient.getProjectId()
|
|
1815
1817
|
if(!t)throw this.logger.error("No project ID available for task creation"),Error("Project ID is required for task creation")
|
|
@@ -1884,17 +1886,17 @@ return n.info(`Task ID ${e} validated successfully`,{taskId:e,requestId:o.reques
|
|
|
1884
1886
|
if(c.includes("404")||c.toLowerCase().includes("not found")||c.toLowerCase().includes("task not found"))throw n.error(`Task ID ${e} does not exist (404 Not Found)`,{taskId:e,path:t,error:c}),i.incrementCounter(a+"_task_not_found",1),new o.NotFoundError(`Task ${e} not found in project. Please provide a valid task ID.`,{taskId:e,path:t,originalError:r})
|
|
1885
1887
|
throw n.error("Could not validate task ID "+e,{taskId:e,path:t,error:c}),i.incrementCounter(a+"_task_validation_error",1),new o.ValidationError(`Could not validate task ${e}: ${c}`,{taskId:e,path:t,originalError:r})}},exports.createReopenGuidanceMessage=r,exports.validateWorkItemStates=async function(e,t,n,a,c,l,d,u){try{const h=await n.getTask(e)
|
|
1886
1888
|
if(l.info("Validating work item states for task "+e,{taskId:e,taskStatus:h.status,requestId:h.requestId,path:t}),l.info("STRICT VALIDATION - Task details",{taskId:e,taskStatus:h.status,requestId:h.requestId,taskTitle:h.title,path:t,timestamp:(new Date).toISOString()}),"completed"===h.status||"canceled"===h.status||"reverted"===h.status){const n=r(e,h.requestId,h.status)
|
|
1887
|
-
throw l.error(`STRICT VALIDATION - File operation blocked on ${h.status} task`,{taskId:e,taskStatus:h.status,path:t,errorMessage:n}),d.incrementCounter(`${u}_blocked_${h.status}_task`,1),new o.ValidationError(n,{taskId:e,taskStatus:h.status,path:t,reason:"task_"+h.status})}let g,
|
|
1889
|
+
throw l.error(`STRICT VALIDATION - File operation blocked on ${h.status} task`,{taskId:e,taskStatus:h.status,path:t,errorMessage:n}),d.incrementCounter(`${u}_blocked_${h.status}_task`,1),new o.ValidationError(n,{taskId:e,taskStatus:h.status,path:t,reason:"task_"+h.status})}let g,p
|
|
1888
1890
|
if(h.requestId)try{if(g=await a.getRequest(h.requestId),l.info("Validating request status for "+h.requestId,{requestId:h.requestId,requestStatus:g.status,taskId:e,path:t}),l.info("STRICT VALIDATION - Request details",{requestId:h.requestId,requestStatus:g.status,requestTitle:g.title,taskId:e,path:t,timestamp:(new Date).toISOString()}),"pending_approval"===g.status||"ready_for_review"===g.status||"completed"===g.status||"canceled"===g.status){const n=r(e,h.requestId,h.status,g.status)
|
|
1889
1891
|
throw l.error(`STRICT VALIDATION - File operation blocked on ${g.status} request`,{taskId:e,requestId:h.requestId,requestStatus:g.status,path:t,errorMessage:n}),d.incrementCounter(`${u}_blocked_${g.status}_request`,1),new o.ValidationError(n,{taskId:e,requestId:h.requestId,requestStatus:g.status,path:t,reason:"request_"+g.status})}}catch(r){if(r instanceof o.ValidationError)throw r
|
|
1890
1892
|
const n=(0,s.getErrorMessage)(r)
|
|
1891
1893
|
l.warn("Could not validate request status for "+h.requestId,{taskId:e,requestId:h.requestId,error:n,path:t}),d.incrementCounter(u+"_request_validation_warning",1)}if(l.info("Work item state validation passed",{taskId:e,taskStatus:h.status,requestId:h.requestId,requestStatus:g?.status,path:t}),h.requestId){const r=c.workspaceManager
|
|
1892
|
-
if("multi-agent"===r?.getCurrentContext().mode)l.debug("Skipping branch switching in multi-agent mode - worktrees handle branch isolation",{taskId:e,requestId:h.requestId,mode:"multi-agent",reason:"worktree_isolation"}),
|
|
1893
|
-
else try{
|
|
1894
|
+
if("multi-agent"===r?.getCurrentContext().mode)l.debug("Skipping branch switching in multi-agent mode - worktrees handle branch isolation",{taskId:e,requestId:h.requestId,mode:"multi-agent",reason:"worktree_isolation"}),p={switched:!1,message:"Branch switching skipped in multi-agent mode (using worktrees)"}
|
|
1895
|
+
else try{p=await(0,i.ensureCorrectBranch)(h.requestId,e,t,c,l,d,u),p.switched&&l.info("Automatically switched to feature branch for file operation",{taskId:e,requestId:h.requestId,branchName:p.branchName,filePath:t})}catch(r){l.warn("Error during automatic branch switching",{taskId:e,requestId:h.requestId,filePath:t,error:(0,s.getErrorMessage)(r)}),p={switched:!1,message:"Branch switching error: "+(0,s.getErrorMessage)(r)}}}return d.incrementCounter(u+"_state_validation_success",1),{task:h,request:g,branchSwitch:p}}catch(r){if(r instanceof o.ValidationError)throw r
|
|
1894
1896
|
const n=(0,s.getErrorMessage)(r)
|
|
1895
|
-
throw l.error("Could not validate work item states for task "+e,{taskId:e,path:t,error:n}),d.incrementCounter(u+"_state_validation_error",1),new o.ValidationError("Could not validate work item states: "+n,{taskId:e,path:t,originalError:r})}},exports.autoPromoteTaskStatus=async function(e,t,r,o,i,a,c,l,d,u){try{let s,h,g=!1,
|
|
1897
|
+
throw l.error("Could not validate work item states for task "+e,{taskId:e,path:t,error:n}),d.incrementCounter(u+"_state_validation_error",1),new o.ValidationError("Could not validate work item states: "+n,{taskId:e,path:t,originalError:r})}},exports.autoPromoteTaskStatus=async function(e,t,r,o,i,a,c,l,d,u){try{let s,h,g=!1,p=!1
|
|
1896
1898
|
if("pending"===t&&(l.info(`Auto-promoting task ${e} from pending to in_progress`,{taskId:e,currentStatus:t,path:i}),await a.updateTaskStatus(e,"in_progress"),l.info(`Successfully auto-promoted task ${e} to in_progress`,{taskId:e,previousStatus:t,newStatus:"in_progress",path:i}),d.incrementCounter(u+"_auto_promotion_success",1),g=!0,s="in_progress",r&&o)){const t=await n(r,o,e,"in_progress",c,l,d,u)
|
|
1897
|
-
|
|
1899
|
+
p=t.promoted,h=t.newStatus}return{taskPromoted:g,newTaskStatus:s,requestPromoted:p,newRequestStatus:h}}catch(r){const n=(0,s.getErrorMessage)(r)
|
|
1898
1900
|
return l.warn(`Failed to auto-promote task ${e} from pending to in_progress`,{taskId:e,currentStatus:t,error:n,path:i}),d.incrementCounter(u+"_auto_promotion_failure",1),{taskPromoted:!1,requestPromoted:!1}}},exports.autoPromoteRequestStatus=n,exports.validateRequestCompletionEligibility=async function(e,t,r,n,i){try{const s=await t.listTasks({requestId:e})
|
|
1899
1901
|
if(r.info("Validating request completion eligibility for "+e,{requestId:e,totalTasks:s.length}),0===s.length){r.warn(`Request ${e} has no tasks - cannot be completed`,{requestId:e})
|
|
1900
1902
|
const t=`Cannot complete request ${e} - no tasks found. Create tasks for this request before attempting completion.`
|
|
@@ -1920,7 +1922,7 @@ d.info("Generating journal for request",{requestId:c})
|
|
|
1920
1922
|
const h=t.projectId
|
|
1921
1923
|
if(!h)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
|
|
1922
1924
|
o.setProjectId(h),d.info("Fetching request data, tasks, and file history in parallel")
|
|
1923
|
-
const g=o.getRequestClient(),
|
|
1925
|
+
const g=o.getRequestClient(),p=o.getTaskClient(),f=o.getToolRecordClient(),[m,y,w]=await Promise.all([g.getRequest(c),p.listTasks({requestId:c}),f.getToolRecordsByRequestId(c).catch((e=>(d.warn("Failed to fetch tool records",{error:e+""}),[])))]),k=(0,s.extractDataFromResponse)(m,{logger:d,operationName:"getRequest",throwOnNoData:!0}),b="data"in k?k.data:k,I={id:b.id||c,title:b.title||"Unknown Request",description:b.description||"No description available",status:b.status||"unknown",type:b.type||"unknown",acceptanceCriteria:b.acceptanceCriteria||[],createdAt:b.createdAt||(new Date).toISOString(),updatedAt:b.updatedAt||(new Date).toISOString(),completedAt:b.completedAt},v=(0,s.extractDataFromResponse)(y,{logger:d,operationName:"listTasks",throwOnNoData:!1}),C=(Array.isArray(v)?v:"data"in v?v.data:[]).map((e=>({id:e.id,title:e.title||"Untitled Task",description:e.description||"No description",status:e.status||"unknown",createdAt:e.createdAt||(new Date).toISOString(),completedAt:e.metadata?.completedAt})))
|
|
1924
1926
|
d.info(`Fetched request, ${C.length} tasks, ${w.length} tool records`)
|
|
1925
1927
|
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
1928
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
@@ -1954,14 +1956,14 @@ d.info("Successfully acquired request lock",{requestId:h,sessionTag:e,lockedAt:t
|
|
|
1954
1956
|
const r=t instanceof Error?t.message:t+""
|
|
1955
1957
|
return r.includes("already locked")?{content:[{type:"text",text:`\u274c Request ${h} is already locked by another agent. ${r}`}],isError:!0}:{content:[{type:"text",text:`\u274c Failed to acquire lock for request ${h}: ${r}`}],isError:!0}}}}catch(e){return d.error("Error checking/acquiring request lock",{requestId:h,error:(0,i.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c Failed to check request lock status: "+(0,i.getErrorMessage)(e)}],isError:!0}}}else d.debug("Single-agent mode: skipping request locking",{requestId:h})
|
|
1956
1958
|
d.info("Using unified workspace switching",{requestId:h})
|
|
1957
|
-
const
|
|
1958
|
-
if(!
|
|
1959
|
-
d.warn("Workspace switch failed, attempting to release acquired lock",{requestId:h,sessionTag:e,switchError:
|
|
1959
|
+
const p=await t.workspaceManager.switchToRequest(h,{isCompleted:"completed"===g.status})
|
|
1960
|
+
if(!p.success){if(t.multiAgentMode)try{const{sessionTag:e}=(0,s.getGlobalClientInfo)()
|
|
1961
|
+
d.warn("Workspace switch failed, attempting to release acquired lock",{requestId:h,sessionTag:e,switchError:p.message}),await a.unlockRequest(h,e),d.info("Successfully released lock after workspace switch failure",{requestId:h})}catch(e){d.error("Failed to release lock after workspace switch failure",{requestId:h,unlockError:e instanceof Error?e.message:e+""})}const e=p.message||"Unknown error"
|
|
1960
1962
|
if(e.includes("does not exist")||e.includes("Branch for request"))return{content:[{type:"text",text:`\u274c Branch for request ${h} does not exist. This can happen if:\n- Request was reverted (branch deleted during revert)\n- Request was completed and branch was cleaned up\n- Branch was manually deleted\n\nUse 'get-request-information' to check the request status.`}],isError:!0}
|
|
1961
|
-
throw(0,o.createServiceError)(`Failed to switch to request ${h}: ${e}`,{requestId:h,error:e})}const
|
|
1962
|
-
l.recordValue("switch_to_request_branch_time",
|
|
1963
|
-
const m=["Successfully switched to branch: "+(
|
|
1964
|
-
return t.multiAgentMode&&m.push("\u{1f512} **Locked request:** "+h),d.info("Successfully switched to request workspace",{requestId:h,mode:
|
|
1963
|
+
throw(0,o.createServiceError)(`Failed to switch to request ${h}: ${e}`,{requestId:h,error:e})}const f=Date.now()-u
|
|
1964
|
+
l.recordValue("switch_to_request_branch_time",f),l.incrementCounter("switch_to_request_branch_success",1)
|
|
1965
|
+
const m=["Successfully switched to branch: "+(p.newContext?.branchName||"unknown"),"**Previous branch:** "+(p.previousContext?.branchName||"unknown")]
|
|
1966
|
+
return t.multiAgentMode&&m.push("\u{1f512} **Locked request:** "+h),d.info("Successfully switched to request workspace",{requestId:h,mode:p.newContext?.mode,branch:p.newContext?.branchName,duration:f}),{content:[{type:"text",text:m.join("\n")}]}}catch(t){const r=Date.now()-u
|
|
1965
1967
|
if(l.recordValue("switch_to_request_branch_time",r),l.incrementCounter("switch_to_request_branch_error",1),d.error("Failed to switch to request branch",{requestId:e.requestId,error:(0,i.getErrorMessage)(t),duration:r}),t instanceof o.ValidationError||t instanceof o.NotFoundError)return{content:[{type:"text",text:"\u274c "+t.message}],isError:!0}
|
|
1966
1968
|
throw t}}
|
|
1967
1969
|
const n=t(6183),o=t(9860),s=t(5172),i=t(8824)},3217(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentWorkspaceManager=exports.SingleAgentWorkspaceManager=void 0,exports.createWorkspaceManager=function(e,t,o,s,i,a){return t?new n.MultiAgentWorkspaceManager(e,o,s,i,a):new r.SingleAgentWorkspaceManager(e,o,s,i)}
|
|
@@ -2044,7 +2046,7 @@ T.push({type:"file",path:r,fullPath:n,replacements:e.replacements,mode:e.mode||"
|
|
|
2044
2046
|
if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
2045
2047
|
for(const e of S)M.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
|
|
2046
2048
|
if(M.length>0&&t.apiClient){const e=M.map((e=>e.documentId))
|
|
2047
|
-
try{await(0,
|
|
2049
|
+
try{await(0,f.ensureDocumentsNotLocked)(e,t.apiClient,y,a,"replace-strings-documents")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2048
2050
|
throw e}}I=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_strings_phase",1,{phase:I})
|
|
2049
2051
|
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
2052
|
let O=null
|
|
@@ -2059,7 +2061,7 @@ T[e]={...r,path:o,fullPath:s}}}if(M.length>0&&x)try{await(0,g.validateRequestSta
|
|
|
2059
2061
|
throw e}I=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:I})
|
|
2060
2062
|
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
2063
|
if(k=A,b=A,I=v.fileOperationPhase,a.incrementCounter("replace_strings_phase",1,{phase:I}),T.length>0&&t.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
|
|
2062
|
-
const e=await(0,
|
|
2064
|
+
const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:x,taskId:C,workspaceManager:t.workspaceManager},y,a)
|
|
2063
2065
|
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
2066
|
const F=[]
|
|
2065
2067
|
let N=0,L=0
|
|
@@ -2071,18 +2073,18 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
|
|
|
2071
2073
|
r.filename=s?.filename
|
|
2072
2074
|
const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
|
|
2073
2075
|
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:b,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),B=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:H,failedOperations:
|
|
2075
|
-
try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+M[0]?.documentId,status:G?"completed":"failed",error:G?void 0:
|
|
2076
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const z=await u.handleMultiFileGitCommit(C,T,F,L,{operationType:"Replace strings",toolRecordId:b,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),B=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J}=B
|
|
2077
|
+
try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+M[0]?.documentId,status:G?"completed":"failed",error:G?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:D,totalSuccessfulReplacements:W,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:E,...T.length>0&&z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}},note:G?`String replacement completed: ${H}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`String replacement partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}u.formatMultiFileToolResponse("String Replacement",{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J},z,$)
|
|
2076
2078
|
let K="## String Replacement Results\n\n"
|
|
2077
|
-
if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${H+
|
|
2079
|
+
if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${H+U}\n`,K+=`- **Successful operations:** ${H}\n`,K+=`- **Failed operations:** ${U}\n`,K+=`- **Total replacements:** ${W} successful, ${N} failed\n\n`,z.success&&z.commitHash&&(K+="**Git Commit:**\n",K+=`- **Commit Hash:** ${z.commitHash.substring(0,8)}\n`,K+=`- **Files Committed:** ${z.filesCommitted.length}\n`,z.previousCommitHash&&(K+=`- **Previous Commit:** ${z.previousCommitHash.substring(0,8)}\n`),K+="\n"),$.lockAcquired&&$.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
|
|
2078
2080
|
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"
|
|
2079
|
-
for(const t of e.replacements.filter((e=>!e.success)))K+=`- "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}}else{K+="**Summary:**\n",K+=`- **Total Operations:** ${F.length}\n`,K+=`- **Successful:** ${H}\n`,K+=`- **Failed:** ${
|
|
2081
|
+
for(const t of e.replacements.filter((e=>!e.success)))K+=`- "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}}else{K+="**Summary:**\n",K+=`- **Total Operations:** ${F.length}\n`,K+=`- **Successful:** ${H}\n`,K+=`- **Failed:** ${U}\n`,K+=`- **Total Replacements:** ${W} successful, ${N} failed\n\n`,K+="**Detailed Results:**\n\n"
|
|
2080
2082
|
for(const e of F){if("file"===e.type?K+=`### File: ${e.path}\n`:(K+="### Document: "+e.documentId,e.filename&&(K+=` (${e.filename})`),K+="\n"),K+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error?K+=`- **Error:** ${e.error}\n`:(K+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(K+=`, ${e.failedReplacements} failed`),K+="\n"),e.replacements.some((e=>!e.success))){K+="- **Failed Replacement Details:**\n"
|
|
2081
2083
|
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
2084
|
const Y=Date.now()-w
|
|
2083
|
-
return y.info("Replace strings operation completed",{duration:Y,success:G,totalOperations:F.length,successfulOperations:H,failedOperations:
|
|
2085
|
+
return y.info("Replace strings operation completed",{duration:Y,success:G,totalOperations:F.length,successfulOperations:H,failedOperations:U}),a.incrementCounter("replace_strings_total",1,{success:G}),{content:[{type:"text",text:K}],isError:!G}}catch(t){const r=Date.now()-w
|
|
2084
2086
|
if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:I}),b)try{await o.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:I,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_strings_errors",1,{phase:I}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
2085
|
-
const l=c(t(1943)),d=t(6183),u=a(t(5967)),h=t(9860),g=t(5003),
|
|
2087
|
+
const l=c(t(1943)),d=t(6183),u=a(t(5967)),h=t(9860),g=t(5003),p=t(7478),f=t(9949),m=t(8824)},3322(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
2086
2088
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
2087
2089
|
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=[]
|
|
2088
2090
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -2116,10 +2118,10 @@ var h=t(4192)
|
|
|
2116
2118
|
Object.defineProperty(exports,"BaseApiClient",{enumerable:!0,get(){return h.BaseApiClient}})
|
|
2117
2119
|
var g=t(1599)
|
|
2118
2120
|
Object.defineProperty(exports,"SessionRequestAssociationClient",{enumerable:!0,get(){return g.SessionRequestAssociationClient}})
|
|
2119
|
-
var
|
|
2120
|
-
Object.defineProperty(exports,"SessionTagMappingClient",{enumerable:!0,get(){return
|
|
2121
|
-
var
|
|
2122
|
-
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return
|
|
2121
|
+
var p=t(4465)
|
|
2122
|
+
Object.defineProperty(exports,"SessionTagMappingClient",{enumerable:!0,get(){return p.SessionTagMappingClient}})
|
|
2123
|
+
var f=t(5187)
|
|
2124
|
+
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return f.CLISessionClient}})
|
|
2123
2125
|
var m=t(6539)
|
|
2124
2126
|
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return m.ClientFactory}})
|
|
2125
2127
|
const y=t(6539)
|
|
@@ -2144,12 +2146,12 @@ const n=e
|
|
|
2144
2146
|
"metadata"in t&&t.metadata&&(n.metadata=t.metadata),h=n}else h={id:r,title:"Untitled Task",description:"No description available.",status:"pending",projectId:a,requestId:"",createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}
|
|
2145
2147
|
l.info("Retrieved task information",{taskId:r,title:h.title,status:h.status})}catch(e){throw new o.NotFoundError(`Task ${r} not found in project ${a}. Please provide a valid task ID.`,{taskId:r,projectId:a,originalError:e})}let g=null
|
|
2146
2148
|
if(h.requestId)try{const e=i.getRequestClient()
|
|
2147
|
-
g=await e.getRequest(h.requestId),l.info("Retrieved parent request information",{taskId:r,requestId:h.requestId})}catch(e){l.warn("Failed to retrieve parent request",{error:(0,s.getErrorMessage)(e),taskId:r,requestId:h.requestId})}const
|
|
2149
|
+
g=await e.getRequest(h.requestId),l.info("Retrieved parent request information",{taskId:r,requestId:h.requestId})}catch(e){l.warn("Failed to retrieve parent request",{error:(0,s.getErrorMessage)(e),taskId:r,requestId:h.requestId})}const p=e=>{if(!e)return"Unknown date"
|
|
2148
2150
|
try{const t=new Date(e)
|
|
2149
|
-
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},p
|
|
2151
|
+
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},f=p(h.createdAt),m=p(h.updatedAt)
|
|
2150
2152
|
let y=`# Task: ${h.title} (${r})\n\n`
|
|
2151
|
-
if(y+=`**Status**: ${h.status}\n`,y+=`**Created**: ${
|
|
2152
|
-
y+="\n## Metadata\n\n",e.lastCommit&&(y+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(y+=`**Completed At**: ${
|
|
2153
|
+
if(y+=`**Status**: ${h.status}\n`,y+=`**Created**: ${f}\n`,y+=`**Updated**: ${m}\n`,h.requestId&&(y+="**Parent Request**: "+h.requestId,y+=g?` (${g.title})\n`:"\n"),h.metadata){const e=h.metadata
|
|
2154
|
+
y+="\n## Metadata\n\n",e.lastCommit&&(y+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(y+=`**Completed At**: ${p(e.completedAt)}\n`),e.completionSummary&&(y+=`**Completion Summary**: ${e.completionSummary}\n`)
|
|
2153
2155
|
const t=["lastCommit","completedAt","completionSummary"]
|
|
2154
2156
|
Object.entries(e).filter((([e])=>!t.includes(e))).forEach((([e,t])=>{y+=`**${e}**: ${t}\n`}))}return y+="\n## Description\n\n",h.description&&h.description.trim().length>0?y+=h.description:y+="No description provided.",d({success:!0}),{content:[{type:"text",text:y}]}}catch(n){l.error("Failed to get task information",{error:n instanceof Error?n.stack:n+"",args:e})
|
|
2155
2157
|
try{const o=i.getToolRecordClient()
|
|
@@ -2204,30 +2206,30 @@ if(i.length>h)break
|
|
|
2204
2206
|
if(i===l){c.push({line:s+1,actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t})
|
|
2205
2207
|
break}}}o+=i.length+1}return c}const g=t.trim()[0]
|
|
2206
2208
|
if(!g)return c
|
|
2207
|
-
let
|
|
2208
|
-
for(;;){if(
|
|
2209
|
-
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${o}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}
|
|
2210
|
-
const r=e.indexOf(g,
|
|
2209
|
+
let p=0,f=0
|
|
2210
|
+
for(;;){if(f%100==0&&Date.now()-d>o){const r=Date.now()-d
|
|
2211
|
+
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${o}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}f++
|
|
2212
|
+
const r=e.indexOf(g,p)
|
|
2211
2213
|
if(-1===r)break
|
|
2212
2214
|
let i=r+t.length
|
|
2213
2215
|
const u=Math.min(Math.floor(.5*t.length),200),h=Math.min(r+t.length+u,e.length),m=l.length
|
|
2214
2216
|
let y=!1
|
|
2215
2217
|
for(let t=i;h>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2216
2218
|
if(i.length>m)break
|
|
2217
|
-
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),
|
|
2218
|
-
break}}y||(
|
|
2219
|
+
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),p=t,y=!0
|
|
2220
|
+
break}}y||(p=r+1)}return c}(e,t,c,u),h.length>0)return h}catch(e){if(e instanceof Error&&e.message.includes("timed out"))throw e}return h=function(e,t,n=100,a){if(r(a))return[]
|
|
2219
2221
|
const c=[],l=o(t),d=Date.now()
|
|
2220
2222
|
if(t.length>500)return i(e,t)
|
|
2221
2223
|
if(!l)return c
|
|
2222
2224
|
const u=t.replace(/\s/g,"")[0],h=l.length
|
|
2223
|
-
let g=0,
|
|
2224
|
-
for(;;){if(
|
|
2225
|
-
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${n}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}
|
|
2225
|
+
let g=0,p=0
|
|
2226
|
+
for(;;){if(p%100==0&&Date.now()-d>n){const r=Date.now()-d
|
|
2227
|
+
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${n}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}p++
|
|
2226
2228
|
const r=e.indexOf(u,g)
|
|
2227
2229
|
if(-1===r)break
|
|
2228
|
-
const i=r+h,a=Math.min(t.length,300),
|
|
2230
|
+
const i=r+h,a=Math.min(t.length,300),f=Math.min(r+h+a,e.length)
|
|
2229
2231
|
let m=!1
|
|
2230
|
-
for(let t=i;
|
|
2232
|
+
for(let t=i;f>=t;t++){const n=e.substring(r,t),i=o(n)
|
|
2231
2233
|
if(i.length>h)break
|
|
2232
2234
|
if(i===l){c.push({line:s(e,r),actuallyMatched:n,matchType:"whitespace_agnostic",startPos:r,endPos:t}),g=t,m=!0
|
|
2233
2235
|
break}}m||(g=r+1)}return c}(e,t,c,u),h},exports.replaceMatch=a,exports.replaceMatches=function(e,t,r){const n=[...t].sort(((e,t)=>t.startPos-e.startPos))
|
|
@@ -2254,46 +2256,46 @@ let i=u.FileOperationPhase.VALIDATION
|
|
|
2254
2256
|
const a={toolName:"get-file-info",operationName:"read",fileOperationPhase:u.FileOperationPhase.FILE_WRITE,recordType:"write",metricsPrefix:"get_file_info",successMessage:"Successfully retrieved info for {path}",failureMessage:"Failed to retrieve info for {path}"}
|
|
2255
2257
|
try{const a=u.validateArgs(e,d.GetFileInfoSchema),{path:h}=a
|
|
2256
2258
|
n.info("Getting file info: "+h)
|
|
2257
|
-
const{normalizedPath:
|
|
2259
|
+
const{normalizedPath:f,fullPath:m}=u.validateAndNormalizePath(h,t)
|
|
2258
2260
|
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:
|
|
2261
|
+
try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+h)}const y=await c.default.stat(m),w=y.isFile()?l.default.extname(m).slice(1):"",k={path:f,type:y.isDirectory()?"directory":"file",size:y.size,sizeFormatted:(p=y.size,u.formatFileSize(p)),created:r(y.birthtime),modified:r(y.mtime),accessed:r(y.atime),permissions:(g=y.mode,(511&g).toString(8)),isDirectory:y.isDirectory(),isFile:y.isFile(),isSymbolicLink:y.isSymbolicLink(),extension:w},b=["File Information for: "+f,"Type: "+k.type,`Size: ${k.sizeFormatted} (${k.size} bytes)`,"Created: "+k.created,"Modified: "+k.modified,"Accessed: "+k.accessed,"Permissions: "+k.permissions,"Is Directory: "+k.isDirectory,"Is File: "+k.isFile,"Is Symbolic Link: "+k.isSymbolicLink]
|
|
2260
2262
|
k.isFile&&w&&b.push("Extension: "+w)
|
|
2261
2263
|
const I=Date.now()-s
|
|
2262
|
-
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+
|
|
2263
|
-
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,
|
|
2264
|
-
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,
|
|
2264
|
+
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+f,{type:k.type,size:k.size,time:I}),{content:[{type:"text",text:b.join("\n")}]}}catch(t){const r=Date.now()-s
|
|
2265
|
+
return o.recordValue("get_file_info_time",r),o.incrementCounter("get_file_info_errors",1),n.error("Error getting file info:",{error:(0,h.getErrorMessage)(t),time:r}),u.handleFileOperationError(t,i,n,o,e,a)}var g,p}
|
|
2266
|
+
const c=a(t(1943)),l=a(t(6928)),d=t(6183),u=i(t(5967)),h=t(8824)},3707(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,d,u,h,g,p){const f=h.child({tool:"quick_edit"}),m=Date.now()
|
|
2265
2267
|
try{const y=u.getRequestClient(),w=u.getTaskClient(),k=u.getFileClient(),b=u.getToolRecordClient(),{title:I,description:v,...C}=e,_=e.comment||I
|
|
2266
|
-
|
|
2268
|
+
f.info("Starting quick_edit workflow",{title:I,operationType:t})
|
|
2267
2269
|
let E=!1
|
|
2268
2270
|
try{const e=await y.listRequests({limit:2,sortBy:"created_at",sortDirection:"desc"})
|
|
2269
|
-
e&&2===e.length&&e.every((e=>"quick-edit"===e.type))&&(E=!0,
|
|
2271
|
+
e&&2===e.length&&e.every((e=>"quick-edit"===e.type))&&(E=!0,f.info("Detected two consecutive quick-edits, will recommend normal request"))}catch(e){f.warn("Could not check recent requests for recommendation",{error:e})}f.debug("Creating quick_edit request")
|
|
2270
2272
|
const q=await y.createRequest({title:I,description:v,type:"quick-edit",acceptanceCriteria:["Quick change completed successfully"]})
|
|
2271
2273
|
if(!q||!q.id)throw Error("Failed to create request")
|
|
2272
2274
|
const S=q.id
|
|
2273
2275
|
let T
|
|
2274
|
-
|
|
2275
|
-
try{if(
|
|
2276
|
-
e.userChangesCommitted?
|
|
2277
|
-
|
|
2276
|
+
f.info("Created request",{requestId:S})
|
|
2277
|
+
try{if(f.debug("Checking for uncommitted user changes before quick-edit branch creation"),d.git)try{const e=await(0,c.commitUserChangesBeforeToolOperation)(d.git,"quick-fix",{requestId:S,taskId:void 0,workspaceManager:d.workspaceManager},h,g)
|
|
2278
|
+
e.userChangesCommitted?f.info("Committed user changes to main before quick-edit branch creation",{requestId:S,commitHash:e.commitHash?.substring(0,8)}):f.debug("No uncommitted changes found, proceeding with quick-edit")}catch(e){f.warn("Failed to commit user changes before quick-edit, proceeding anyway",{requestId:S,error:e instanceof Error?e.message:e+""})}else f.debug("No git instance available, skipping uncommitted changes check")
|
|
2279
|
+
f.debug("Creating task")
|
|
2278
2280
|
const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+I})
|
|
2279
2281
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2280
2282
|
let v
|
|
2281
|
-
if(T=e.id,
|
|
2282
|
-
else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,b,y,h,g,
|
|
2283
|
+
if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{operationType:t}),"write"===t)v=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,k,w,b,y,h,g,p)
|
|
2284
|
+
else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,b,y,h,g,p)
|
|
2283
2285
|
else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
|
|
2284
|
-
v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||I},d,w,b,y,u,h,g,
|
|
2285
|
-
try{await w.updateTaskStatus(T,"canceled"),
|
|
2286
|
-
M?
|
|
2287
|
-
try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${I}${M?" (partial success)":""}`},d,u,h,g),
|
|
2288
|
-
try{await w.updateTaskStatus(T,"completed"),
|
|
2286
|
+
v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||I},d,w,b,y,u,h,g,p)}if(v.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
|
|
2287
|
+
try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after operation failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after operation failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${v.content[0].text}\n\nThe request (${S}) and task have been canceled and cleaned up.`}],isError:!0}}const q=v.content[0].text,M=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
|
|
2288
|
+
M?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
|
|
2289
|
+
try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${I}${M?" (partial success)":""}`},d,u,h,g),f.info("Task completed successfully",{taskId:T})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
|
|
2290
|
+
try{await w.updateTaskStatus(T,"completed"),f.info("Task completed via direct updateTaskStatus call",{taskId:T})}catch(e){return f.error("Direct task completion ALSO failed - task may be stuck in in_progress",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0,operationType:t,isDocumentOperation:!!C.documentId}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but task completion failed.\n\n**Request:** ${S}\n**Task:** ${T}\n**Issue:** Could not mark task as completed - it remains in 'in_progress' state\n\nThe ${t} operation was successful, but we couldn't automatically complete the task. Please use the complete-task tool manually with taskId: ${T}\n\nError: `+(e instanceof Error?e.message:e+"")}],isError:!0}}}f.debug("Completing request")
|
|
2289
2291
|
const R=M?`Quick change completed with partial success: ${I}. Some replacements failed - see details below.`:"Quick change completed: "+I,P=M?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
|
|
2290
2292
|
let x=!1
|
|
2291
|
-
try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:R,acceptanceEvidence:[{evidence:P}],testVerification:void 0},d,u,h,g,
|
|
2292
|
-
if(e.isError)
|
|
2293
|
-
else{try{await y.updateRequest(S,{status:"completed",completionSummary:R}),
|
|
2293
|
+
try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:R,acceptanceEvidence:[{evidence:P}],testVerification:void 0},d,u,h,g,p)
|
|
2294
|
+
if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text})
|
|
2295
|
+
else{try{await y.updateRequest(S,{status:"completed",completionSummary:R}),f.info("Request finalized to completed",{requestId:S})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:S,error:(0,l.getErrorMessage)(e)})}x=!0,f.info("Request completed successfully",{requestId:S})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:S,error:e instanceof Error?e.message:e+""})}if(!x)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:R}),x=!0,f.info("Request completed successfully via direct API call",{requestId:S})}catch(e){return f.error("Direct request completion also failed",{requestId:S,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${S}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const O=Date.now()-m
|
|
2294
2296
|
let j
|
|
2295
|
-
return
|
|
2296
|
-
return
|
|
2297
|
+
return f.info("Quick fix completed",{requestId:S,duration:O,hasPartialFailure:M}),j=M?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${I}\n**Operation:** ${t}\n**Duration:** ${O}ms\n**Status:** Some operations succeeded, some failed\n\nThe successful changes have been applied and automatically merged to main.\n**Active branch:** main\n\n**\u26a0\ufe0f Note:** This quick-fix had partial failures. See operation details below:\n\n`+q:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${I}\n**Operation:** ${t}\n**Duration:** ${O}ms\n\nThe change has been applied and automatically merged to main.\n**Active branch:** main`+(q.match(/\[RECORD:trec\d{6}\]/)?.[0]?"\n"+q.match(/\[RECORD:trec\d{6}\]/)?.[0]:""),E&&(j+="\n\n\u{1f4a1} **Recommendation:** You've created several quick-edits in a row. For better traceability and organization, consider creating a proper feature or bugfix request with multiple tasks for your next change."),{content:[{type:"text",text:j}]}}catch(e){if(f.error("Quick change workflow failed after request creation, cleaning up",{requestId:S,error:(0,l.getErrorMessage)(e)}),T)try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after workflow failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after workflow failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after workflow failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}throw e}}catch(e){const t=Date.now()-m
|
|
2298
|
+
return f.error("Quick change failed",{error:(0,l.getErrorMessage)(e),duration:t}),e instanceof r.ValidationError?{content:[{type:"text",text:"\u274c "+e.message}],isError:!0}:{content:[{type:"text",text:"\u274c Quick change failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
2297
2299
|
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
2300
|
const r=t(6848)
|
|
2299
2301
|
exports.AuthenticationManager=class{constructor(e,t,n){this.cachedToken=null,this.tokenRefreshPromise=null,this.tokenManager=e,this.logger=t.child({component:"auth-manager"}),this.tokenSynchronizer=n||new r.ClientTokenSynchronizer(t)}async setToken(e){try{this.logger.info("Storing authentication token",{username:e.username,expiresAt:e.expiresAt,userId:e.userId}),await this.tokenManager.storeToken(e),this.cachedToken=e,this.tokenSynchronizer.updateToken(e.token),this.logger.info("Authentication token stored and synchronized to all clients")}catch(e){throw this.logger.error("Failed to store authentication token",{error:e instanceof Error?e.stack:e+""}),Error("Failed to store authentication token")}}async setTokenString(e){try{this.logger.info("Setting token string directly")
|
|
@@ -2355,11 +2357,11 @@ return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModu
|
|
|
2355
2357
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleWriteFile=async function(e,t,r,n,o,s,i,m,y){const w=i.child({tool:"write_file"}),k=m.startTimer("tool_execution_time"),b=Date.now()
|
|
2356
2358
|
let I,v,C=d.FileOperationPhase.VALIDATION
|
|
2357
2359
|
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
|
-
try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:
|
|
2359
|
-
w.info("Writing content to "+(R?"document":"file"),{taskId:i,filePath:P?
|
|
2360
|
+
try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:E,content:q,format:S,append:T,comment:M}=r,R=!!E,P=!!f
|
|
2361
|
+
w.info("Writing content to "+(R?"document":"file"),{taskId:i,filePath:P?f:void 0,documentId:R?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:T,comment:M})
|
|
2360
2362
|
let x,O,j,$="",D=!1,A=!1
|
|
2361
|
-
const F=P?
|
|
2362
|
-
if(R){if(t.apiClient)try{await(0,
|
|
2363
|
+
const F=P?f:void 0
|
|
2364
|
+
if(R){if(t.apiClient)try{await(0,p.ensureDocumentNotLocked)(E,t.apiClient,w,m,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2363
2365
|
throw e}if(!t.documentFileManager)throw Error("Document file manager not available")
|
|
2364
2366
|
$=await t.documentFileManager.getDocumentAsFile(E)
|
|
2365
2367
|
const e=t.documentFileManager.getCachedDocumentInfo(E)
|
|
@@ -2369,15 +2371,15 @@ let B=null
|
|
|
2369
2371
|
P&&z&&(B=await d.validateWorkItemStates(i,N,n,s,t,w,m,_.metricsPrefix))
|
|
2370
2372
|
let H={taskPromoted:!1,requestPromoted:!1}
|
|
2371
2373
|
P&&z&&B&&(H=await d.autoPromoteTaskStatus(i,L.status,z,B.request?.status,N,n,s,w,m,_.metricsPrefix),H.taskPromoted&&w.info("Auto-promoted task to in_progress for file operation",{taskId:i,requestId:z,previousStatus:L.status,newStatus:H.newTaskStatus,triggeringOperation:"write_file"}))
|
|
2372
|
-
const
|
|
2373
|
-
if(!
|
|
2374
|
-
throw Error(
|
|
2374
|
+
const U=await d.ensureCorrectWorkspaceContext({taskPromoted:H.taskPromoted,requestId:z,context:t,operation:"write_file",logger:w,metrics:m,metricsPrefix:_.metricsPrefix,requireRequestContext:P})
|
|
2375
|
+
if(!U.success){if(U.isLockConflict)return{content:[{type:"text",text:"\u274c "+U.error}],isError:!0}
|
|
2376
|
+
throw Error(U.error)}if(U.switched&&w.info("Workspace context successfully established",{requestId:z,branchName:U.branchName,operation:"write_file"}),P&&F){const e=d.validateAndNormalizePath(F,t)
|
|
2375
2377
|
x=e.normalizedPath,O=e.fullPath,$=O
|
|
2376
2378
|
try{await c.default.access(O),A=!0}catch{A=!1,D=!0}w.debug("Path validated with correct workspace context",{rawPath:F,normalizedPath:x,fullPath:O,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})}if(R&&z)try{await(0,h.validateRequestStatusForDocumentOperation)(z,s,w,m,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2377
2379
|
throw e}C=d.FileOperationPhase.RECORD_CREATION,m.incrementCounter("write_file_phase",1,{phase:C})
|
|
2378
|
-
const{toolRecordId:
|
|
2380
|
+
const{toolRecordId:W}=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
2381
|
let G
|
|
2380
|
-
if(I=
|
|
2382
|
+
if(I=W,v=W,C=_.fileOperationPhase,m.incrementCounter("write_file_phase",1,{phase:C}),"json"===S)if("string"==typeof q)try{JSON.parse(q),G=q}catch(e){throw new u.ValidationError("Content is not valid JSON")}else G=JSON.stringify(q,null,2)
|
|
2381
2383
|
else G="string"==typeof q?q:JSON.stringify(q,null,2)
|
|
2382
2384
|
let V=G
|
|
2383
2385
|
if(P&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
|
|
@@ -2389,11 +2391,11 @@ try{await t.documentFileManager.syncDocument(E),w.info("Document synced successf
|
|
|
2389
2391
|
if(P){if(C=d.FileOperationPhase.GIT_COMMIT,m.incrementCounter("write_file_phase",1,{phase:C}),t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
|
|
2390
2392
|
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
2393
|
K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:x,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:P?x:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:T&&A,operationType:R?"document":"file",processingTime:Date.now()-b,userComment:M,...P&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(R?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${D?"Created":T?"Appended to":"Updated"} ${R?`document ${E}${j?` (${j})`:""}`:"file "+x}**\n`
|
|
2392
|
-
Z+=`**Content Length:** ${V.length} characters\n`,P&&Y&&(Z+=`**Branch:** ${Y}\n`),
|
|
2394
|
+
Z+=`**Content Length:** ${V.length} characters\n`,P&&Y&&(Z+=`**Branch:** ${Y}\n`),U.lockAcquired&&U.lockedRequestId&&(Z+=`**Locked request:** ${U.lockedRequestId}\n`),P&&K&&(Z+=`**Commit Hash:** ${K.substring(0,8)}\n`,Q&&(Z+=`**Previous Commit:** ${Q.substring(0,8)}\n`)),v&&(Z+=`[RECORD:${v}]\n`),R&&(Z+=`\n**Document Update:** The document content has been updated and synced back to the tracking system. You can continue editing using other file modification tools with documentId \`${E}\`.`)
|
|
2393
2395
|
const X=Date.now()
|
|
2394
2396
|
return w.info("Write operation completed successfully",{duration:X-b,path:P?x:"document:"+E,contentLength:V.length,wasCreated:D}),k({tool:"write_file",success:!0}),m.incrementCounter("write_file_total",1,{success:!0}),t.workspaceManager?.largeFileWarning&&(Z+=t.workspaceManager.largeFileWarning,t.workspaceManager.largeFileWarning=""),{content:[{type:"text",text:Z}]}}catch(t){const r=Date.now()-b
|
|
2395
|
-
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,
|
|
2396
|
-
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),
|
|
2397
|
+
if(w.error("Write operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:C}),v)try{await o.updateToolRecord(v,{metadata:{path:e?.path,status:"failed",error:(0,f.getErrorMessage)(t),phase:C,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return k({tool:"write_file",success:!1}),m.incrementCounter("write_file_errors",1,{phase:C}),{content:[{type:"text",text:"\u274c **Write Operation Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
|
|
2398
|
+
const a=i(t(6928)),c=i(t(1943)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824)},4139(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ALCHEMY_DIR_NAME=exports.TOKEN_DIR_NAME=void 0,exports.TOKEN_DIR_NAME="alchemy-key",exports.ALCHEMY_DIR_NAME=".alchemy_lab"},4165(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2397
2399
|
const r=t(6183),n=t(4648)
|
|
2398
2400
|
exports.def={name:"request_operations",description:"Perform operations on existing requests.\n\nOperations:\n\u2022 complete - Begin completion: provide summary, get criteria keys for verification\n\u2022 verify-criteria - Verify acceptance criteria with evidence per key (triggers merge when all verified)\n\u2022 finalize - Approve and merge a request that is ready for review\n\u2022 approve - Approve a pending request so work can begin\n\u2022 revert - Completely revert a completed request, undoing all changes\n\u2022 get-info - Get comprehensive request information\n\u2022 list - List and filter requests\n\nCompletion is two-phase: first call complete with a summary, then call verify-criteria with evidence for each criterion key.\n\nNote: To create a new request, use the separate create-request tool.",schema:r.RequestOperationsSchema,annotations:{title:"Request Operations",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleRequestOperations)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},4192(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.BaseApiClient=void 0
|
|
2399
2401
|
const r=t(7163)
|
|
@@ -2454,8 +2456,8 @@ if(!c.startsWith(s+a.sep))return{content:[{type:"text",text:"\u274c Invalid file
|
|
|
2454
2456
|
try{await i.access(c)}catch{return{content:[{type:"text",text:"\u274c Asset not found: "+r}],isError:!0}}const u=a.extname(r).toLowerCase().slice(1),h=d[u]
|
|
2455
2457
|
if(!h)return{content:[{type:"text",text:"\u274c Unsupported image type: ."+u}],isError:!0}
|
|
2456
2458
|
if("svg"===u)return{content:[{type:"text",text:`**Asset: ${r}**\n\n\`\`\`svg\n${await i.readFile(c,"utf-8")}\n\`\`\``}]}
|
|
2457
|
-
const g=await i.readFile(c),
|
|
2458
|
-
return o.info("Asset viewed",{filename:r,size:g.length}),{content:[{type:"text",text:`**Asset: ${r}** (${(g.length/1024).toFixed(1)} KB)`},{type:"image",data:
|
|
2459
|
+
const g=await i.readFile(c),p=g.toString("base64")
|
|
2460
|
+
return o.info("Asset viewed",{filename:r,size:g.length}),{content:[{type:"text",text:`**Asset: ${r}** (${(g.length/1024).toFixed(1)} KB)`},{type:"image",data:p,mimeType:h}]}}catch(e){return o.error("Failed to view asset",{error:(0,c.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to view asset:** "+(0,c.getErrorMessage)(e)}],isError:!0}}}
|
|
2459
2461
|
const i=s(t(1943)),a=s(t(6928)),c=t(8824),l=t(4139),d={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml"}},4306(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMergeRequest=async function(e,t,i,a,c){const l=a.child({tool:"merge_request"}),d=c.startTimer("tool_execution_time"),{requestId:u,verifications:h}=e
|
|
2460
2462
|
try{if(!u)throw(0,r.createValidationError)("requestId is required")
|
|
2461
2463
|
l.info("Starting merge request",{requestId:u,verificationCount:h.length})
|
|
@@ -2468,10 +2470,10 @@ a=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
|
2468
2470
|
return d({success:!1,error:"validation_failed"}),{content:[{type:"text",text:"Failed to validate merge: "+t}],isError:!0}}if(!a.canComplete){let e=`Cannot merge request ${u}: ${a.reason}\n`
|
|
2469
2471
|
return a.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\n",a.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (${t.status})\n`}))),d({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(!t.workspaceManager)throw Error("WorkspaceManager not available")
|
|
2470
2472
|
let g="workspace-manager"
|
|
2471
|
-
const
|
|
2472
|
-
try{m?(l.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:u}),c=await t.workspaceManager.completeRequest(u,
|
|
2473
|
+
const p=await e.getRequest(u),f=p?.title||"Request "+u,m="resolving_conflicts"===p?.status
|
|
2474
|
+
try{m?(l.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:u}),c=await t.workspaceManager.completeRequest(u,f,{skipConflictDetection:!0}),g="retry-theirs"):(c=await t.workspaceManager.completeRequest(u,f),g=c.autoMergeInfo?.strategy||"workspace-manager"),l.info("Merge completed",{requestId:u,mergeCommitHash:c.mergeCommitHash,mergeMethod:g})}catch(r){if(r.conflictInfo){const o=r.conflictInfo,a=o.workingDirectory||t.workspaceManager?.getCurrentContext()?.basePath||process.cwd(),c=(0,n.createConflictResolutionManager)(l,i,a,t.git),h=await c.handleConflicts(o)
|
|
2473
2475
|
try{await e.updateRequest(u,{status:"resolving_conflicts"}),l.info("Set status to resolving_conflicts",{requestId:u})}catch(e){l.error("Failed to set resolving_conflicts status",{requestId:u,error:(0,s.getErrorMessage)(e)})}return d({success:!1,reason:"merge_conflicts"}),{content:[{type:"text",text:h.userMessage}],isError:!1}}const o=(0,s.getErrorMessage)(r)
|
|
2474
|
-
return d({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Merge failed: "+o}],isError:!0}}try{await i.proxyPost(`/api/projects/${t.projectId}/requests/${u}/finalize-completion`,{summary:
|
|
2476
|
+
return d({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Merge failed: "+o}],isError:!0}}try{await i.proxyPost(`/api/projects/${t.projectId}/requests/${u}/finalize-completion`,{summary:p?.completionSummary||"Merged request "+u,acceptanceEvidence:h.map((e=>({evidence:e.evidence}))),mergeResult:{mergeCommitHash:c.mergeCommitHash,mergedFiles:c.mergedFiles,cleanedUp:c.cleanedUp,method:g}})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
2475
2477
|
return l.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:u,mergeCommitHash:c.mergeCommitHash,error:t}),d({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${c.mergeCommitHash.substring(0,8)}) but failed to update server: ${t}`}],isError:!0}}return d({success:!0}),{content:[{type:"text",text:`Request ${u} merged successfully.\nCommit: ${c.mergeCommitHash.substring(0,8)}`}]}}catch(e){const r=(0,s.getErrorMessage)(e)
|
|
2476
2478
|
l.error("Merge request failed",{error:r})
|
|
2477
2479
|
try{await(0,o.createFailureToolRecord)("merge-request",e,{error:r,requestId:u},i.getToolRecordClient(),l,c,{requestId:u,projectId:t.projectId,note:"Failed to merge request"})}catch{}return d({success:!1,error:e instanceof Error?e.name:"unknown"}),{content:[{type:"text",text:"Error: "+r}],isError:!0}}}
|
|
@@ -2516,9 +2518,9 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
|
2516
2518
|
return o(t,e),t})
|
|
2517
2519
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlannerOps=async function(e,t,r,n,o,s){const h=r.child({tool:"planner_ops"}),g=n.startTimer("tool_execution_time")
|
|
2518
2520
|
try{if(e?.request&&"string"==typeof e.request)try{e.request=JSON.parse(e.request)}catch{}"request"===e?.operation&&e?.prompt&&!e?.request&&(e.request={prompt:e.prompt,description:e.description||e.prompt.slice(0,60)},delete e.prompt,delete e.description)
|
|
2519
|
-
const r=c.validateArgs(e,a.PlannerOpsSchema),{operation:
|
|
2521
|
+
const r=c.validateArgs(e,a.PlannerOpsSchema),{operation:p,sessionId:f}=r
|
|
2520
2522
|
let m
|
|
2521
|
-
switch(h.info("Processing planner_ops",{operation:
|
|
2523
|
+
switch(h.info("Processing planner_ops",{operation:p,sessionId:f}),p){case"request":{const e=await async function(e,t,r){if(!e)return"ask"
|
|
2522
2524
|
try{const n=r?.sessionId||d.sessionIdentity.getIdentity()?.sessionId
|
|
2523
2525
|
if(!n)return"ask"
|
|
2524
2526
|
const o=e.getCLISessionClient()
|
|
@@ -2537,13 +2539,13 @@ if(t&&e){const n=await d.sessionIdentity.getParentSessionId(e,o,h),s=r.request.d
|
|
|
2537
2539
|
await t.createQuestion({fromSessionId:e,toSessionId:n||void 0,questionType:"alternatives",question:"Planning requested: "+s,options:[{id:"auto",label:"Auto Plan",description:"Spawn an autonomous planner agent"},{id:"manual",label:"Manual Plan",description:"Open the interactive plan editor"},{id:"cancel",label:"Skip",description:"Dismiss this planning request"}],context:r.request.prompt,category:"action-required",priority:"high"}),h.info("planner-request: notification created",{fromSessionId:e})}else h.warn("planner-request: skipping notification",{hasClient:!!t,hasCallerSessionId:!!e})}catch(e){h.warn("planner-request: failed to create notification",{error:(0,l.getErrorMessage)(e)})}m={content:[{type:"text",text:"Planning request submitted. The user will choose the planning approach. This is non-blocking \u2014 continue with your other work.\nPLANNER_CHOICE_PENDING|"+JSON.stringify({prompt:r.request.prompt,description:r.request.description})}]}
|
|
2538
2540
|
break}const n="auto-planner"
|
|
2539
2541
|
if(h.info("Spawning planner",{planningMode:e,agent:n}),m=await(0,u.handleSpawn)({agent:n,prompt:r.request.prompt,title:r.request.description},t,h,o),!m.isError&&m.content.length>0){const t=m.content[0].text
|
|
2540
|
-
m.content[0].text=`Planning mode: ${e} (agent: ${n}). Planning is running in the background \u2014 continue with your other work.\n${t}`}break}case"check-status":m=await(0,u.handleCheckStatus)(
|
|
2542
|
+
m.content[0].text=`Planning mode: ${e} (agent: ${n}). Planning is running in the background \u2014 continue with your other work.\n${t}`}break}case"check-status":m=await(0,u.handleCheckStatus)(f,t,h,o)
|
|
2541
2543
|
break
|
|
2542
2544
|
case"list":const e=s?.sessionId||d.sessionIdentity.getIdentity()?.sessionId,[n,a]=await Promise.all([(0,u.handleListSessions)(t,h,o,{activeOnly:r.list?.activeOnly,limit:r.list?.limit,agentType:"auto-planner",parentSessionId:e}),(0,u.handleListSessions)(t,h,o,{activeOnly:r.list?.activeOnly,limit:r.list?.limit,agentType:"planner",parentSessionId:e})]),c=n.content[0]?.text??"",g=a.content[0]?.text??""
|
|
2543
2545
|
if(c.trim()||g.trim()){const e=[]
|
|
2544
2546
|
c.trim()&&e.push("## Auto-planner sessions\n"+c),g.trim()&&e.push("## Interactive plan sessions\n"+g),m={content:[{type:"text",text:e.join("\n\n")}]}}else m={content:[{type:"text",text:"No planning sessions found."}]}
|
|
2545
2547
|
break
|
|
2546
|
-
default:throw new i.ValidationError("Unknown operation: "+
|
|
2548
|
+
default:throw new i.ValidationError("Unknown operation: "+p)}return g({success:!0}),n.incrementCounter(`planner_ops_${p}_success`,1),m}catch(e){return h.error("Planner ops failed",{error:e instanceof Error?e.stack:e+""}),g({success:!1}),n.incrementCounter("planner_ops_errors",1),{content:[{type:"text",text:"Planner operation failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
2547
2549
|
const i=t(9860),a=t(6183),c=s(t(5967)),l=t(8824),d=t(6688),u=t(1725)},4600(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.execAsync=async function(e,t={}){return new Promise(((n,o)=>{const[s,...i]=e.split(" "),a=(0,r.spawn)(s,i,{cwd:t.cwd||process.cwd(),stdio:["pipe","pipe","pipe"]})
|
|
2548
2550
|
let c="",l=""
|
|
2549
2551
|
a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{n({stdout:c,stderr:l,exitCode:e||0})})),a.on("error",(t=>{o(Error(`Command failed: ${e}\nError: ${t.message}`))})),t.timeout&&setTimeout((()=>{a.kill(),o(Error("Command timed out: "+e))}),t.timeout)}))}
|
|
@@ -2557,12 +2559,12 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2557
2559
|
var t={}
|
|
2558
2560
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2559
2561
|
return o(t,e),t})
|
|
2560
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,t,r,n,o,s,g){const
|
|
2562
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,t,r,n,o,s,g){const p=o.child({tool:"file_recover"}),f=s.startTimer("tool_execution_time"),m=Date.now()
|
|
2561
2563
|
try{let o
|
|
2562
2564
|
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
|
-
return
|
|
2564
|
-
return
|
|
2565
|
-
try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),k=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:b}=await d.createFileOperationRecords(e,k?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),i,a,g,"file-recover",
|
|
2565
|
+
return p.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{taskId:f,path:y,commitHash:w,createBackup:k}=o
|
|
2566
|
+
return p.info("Recovering file to previous version",{taskId:f,filePath:y,commitHash:w,createBackup:k}),await async function(e,t,r,n,o,s,i,a,g,p,f){let m
|
|
2567
|
+
try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),k=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:b}=await d.createFileOperationRecords(e,k?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),i,a,g,"file-recover",f)
|
|
2566
2568
|
m=b
|
|
2567
2569
|
let I,v=!1
|
|
2568
2570
|
try{await l.access(w),v=!0,n&&(I=`${w}.backup-${(new Date).toISOString().replace(/[:.]/g,"-")}`,await l.copyFile(w,I),a.info("Created backup",{originalPath:w,backupPath:I}))}catch{v=!1}const C=o.git
|
|
@@ -2574,28 +2576,28 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
|
|
|
2574
2576
|
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await l.writeFile(w,_,"utf8")
|
|
2575
2577
|
let E={}
|
|
2576
2578
|
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:I,wasFileCreated:!v,processingTime:Date.now()-
|
|
2579
|
+
E=await d.commitToGit(e,y,m,m,t,o,a,g,"file-recover"),a.info("Recovery committed via shared utility",{path:y,sourceCommitHash:r,newCommitHash:E.commitHash?.substring(0,8),commitMessage:t})}catch(e){a.warn("Failed to commit recovery via shared utility",{error:e})}if(m)try{await i.updateToolRecord(m,{metadata:{path:y,status:"completed",recoveredLength:_.length,hadBackup:n&&v,backupPath:I,wasFileCreated:!v,processingTime:Date.now()-p,...E.commitHash&&{commitHash:E.commitHash,previousCommitHash:E.previousCommitHash||void 0}},note:"File recovered successfully from "+r.substring(0,8)})}catch(e){a.warn("Failed to update tool record",{recordError:e})}const q=v?"recovered":"created from recovery"
|
|
2578
2580
|
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&&I&&(S+=`**Backup created:** ${c.basename(I)}\n`),S+="**Git status:** Recovery committed\n",S+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",a.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-
|
|
2580
|
-
return
|
|
2581
|
-
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,
|
|
2581
|
+
return S+=`**File:** ${y}\n`,S+=`**Recovered from:** ${r.substring(0,8)}\n`,S+=`**Content length:** ${_.length} characters\n`,n&&v&&I&&(S+=`**Backup created:** ${c.basename(I)}\n`),S+="**Git status:** Recovery committed\n",S+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",a.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-p}),g.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:S}]}}catch(e){throw e}}(f,y,w,k,t,r,n,p,s,m,g)}catch(e){const t=Date.now()-m
|
|
2582
|
+
return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),f({tool:"file_recover",success:!1}),s.incrementCounter("file_recover_errors",1),{content:[{type:"text",text:"\u274c **Recovery Failed:** "+(0,h.getErrorMessage)(e)}],isError:!0}}}
|
|
2583
|
+
const i=t(6183),a=t(1569),c=s(t(6928)),l=s(t(1943)),d=s(t(5967)),u=t(3922),h=t(8824)},4648(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,t,u,h,g,p){const f=h.child({tool:"request_operations"})
|
|
2582
2584
|
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)
|
|
2583
2585
|
const d=r.RequestOperationsSchema.parse(e),{requestId:m,operation:y}=d
|
|
2584
|
-
switch(
|
|
2586
|
+
switch(f.info("Processing request operation",{requestId:m,operation:y}),y){case"complete":{f.info("Routing to complete-request handler")
|
|
2585
2587
|
const e={requestId:m,summary:d.complete.summary}
|
|
2586
|
-
return await(0,n.handleCompleteRequest)(e,t,u,h,g,
|
|
2587
|
-
case"approve":{
|
|
2588
|
+
return await(0,n.handleCompleteRequest)(e,t,u,h,g,p)}case"merge":return f.info("Routing to merge handler"),await(0,l.handleMergeRequest)({requestId:m,verifications:d.merge?.verifications||[]},t,u,h,g,p)
|
|
2589
|
+
case"approve":{f.info("Routing to approve-request handler")
|
|
2588
2590
|
const e={requestId:m}
|
|
2589
|
-
return await(0,c.handleApproveRequest)(e,t,u,h,g,
|
|
2591
|
+
return await(0,c.handleApproveRequest)(e,t,u,h,g,p)}case"revert":{f.info("Routing to revert-request handler")
|
|
2590
2592
|
const e={requestId:m,reason:d.revert.reason,confirmDestructive:d.revert.confirmDestructive}
|
|
2591
|
-
return await(0,o.handleRevertRequest)(e,t,u,h,g)}case"get-info":{
|
|
2593
|
+
return await(0,o.handleRevertRequest)(e,t,u,h,g)}case"get-info":{f.info("Routing to get-request-information handler")
|
|
2592
2594
|
const e={requestId:m}
|
|
2593
|
-
return await(0,s.handleGetRequestInformation)(e,t,u,h,g)}case"list":{
|
|
2595
|
+
return await(0,s.handleGetRequestInformation)(e,t,u,h,g)}case"list":{f.info("Routing to list-requests handler")
|
|
2594
2596
|
const e={filters:d.list?.filters}
|
|
2595
|
-
return await(0,i.handleListRequests)(e,t,u,h,g)}case"search":{
|
|
2597
|
+
return await(0,i.handleListRequests)(e,t,u,h,g)}case"search":{f.info("Routing to search-requests handler")
|
|
2596
2598
|
const e={search:d.search}
|
|
2597
2599
|
return await(0,a.handleSearchRequests)(e,t,u,h,g)}default:{const e="Unknown operation type: "+y
|
|
2598
|
-
return
|
|
2600
|
+
return f.error(e),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+e}],isError:!0}}}}catch(e){return f.error("Request operations failed",{error:e instanceof Error?e.stack:e+""}),g.incrementCounter("request_operations_errors",1),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
2599
2601
|
const r=t(6183),n=t(5715),o=t(6416),s=t(5434),i=t(8037),a=t(233),c=t(1537),l=t(4306),d=t(8824)},4710(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2600
2602
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClient=void 0
|
|
2601
2603
|
const n=r(t(9896)),o=r(t(6928)),s=t(7645),i=t(2161),a=t(1058),c=t(8824)
|
|
@@ -2716,17 +2718,17 @@ var t={}
|
|
|
2716
2718
|
if(null!=e)for(var r=s(e),n=0;n<r.length;n++)"default"!==r[n]&&i(t,e,r[n])
|
|
2717
2719
|
return a(t,e),t})
|
|
2718
2720
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileBlame=async function(e,t,s,i,a){const c=i.child({tool:"file_blame"}),g=Date.now()
|
|
2719
|
-
try{const{path:i,lines:
|
|
2720
|
-
c.info("Processing blame request",{filePath:i,lines:
|
|
2721
|
+
try{const{path:i,lines:p,branch:f}=e
|
|
2722
|
+
c.info("Processing blame request",{filePath:i,lines:p,branch:f})
|
|
2721
2723
|
const m=t.basePath,y=d.isAbsolute(i)?i:d.join(m,i),w=d.relative(m,y)
|
|
2722
2724
|
try{await u.access(y)}catch{return{content:[{type:"text",text:"\u274c File not found: "+w}],isError:!0}}const k=function(e){if(!e)return null
|
|
2723
2725
|
if(/^\d+$/.test(e)){const t=parseInt(e,10)
|
|
2724
2726
|
return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
|
|
2725
2727
|
if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
|
|
2726
2728
|
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}(
|
|
2729
|
+
return{start:Math.min(...t),end:Math.max(...t)}}return null}(p),b=["blame","--porcelain"]
|
|
2728
2730
|
let I
|
|
2729
|
-
k&&b.push(`-L${k.start},${k.end}`),
|
|
2731
|
+
k&&b.push(`-L${k.start},${k.end}`),f&&b.push(f),b.push("--",w),c.debug("Executing git blame",{args:b})
|
|
2730
2732
|
try{if(!t.git)throw Error("Git context not available")
|
|
2731
2733
|
I=await t.git.raw(b)}catch(e){const t=(0,h.getErrorMessage)(e)
|
|
2732
2734
|
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")
|
|
@@ -2959,18 +2961,18 @@ const n=a.getRequestClient(),s=a.getTaskClient(),[c,l]=await Promise.all([n.getR
|
|
|
2959
2961
|
d.info("Raw request response data",{responseData:JSON.stringify(c)}),d.debug("Request response structure",{type:typeof c,isArray:Array.isArray(c),hasData:null!=c,properties:c?Object.keys(c):[],dataPreview:c?JSON.stringify(c).substring(0,200)+"...":"null"})
|
|
2960
2962
|
const h=(0,o.extractDataFromResponse)(c,{logger:d,operationName:"getRequestInformation",throwOnNoData:!0}),g="data"in h?h.data:h
|
|
2961
2963
|
d.info("Successfully extracted request data using data extraction utility"),d.info("Raw tasks response data",{responseData:JSON.stringify(l)}),d.debug("Tasks response structure",{type:typeof l,isArray:Array.isArray(l),hasData:null!=l,properties:l?Object.keys(l):[],dataPreview:l?JSON.stringify(l).substring(0,200)+"...":"null"})
|
|
2962
|
-
const
|
|
2963
|
-
d.info(`Successfully extracted ${
|
|
2964
|
-
const
|
|
2965
|
-
|
|
2966
|
-
t in
|
|
2964
|
+
const p=(0,o.extractArrayFromResponse)(l,{logger:d,operationName:"listTasksForRequest",defaultValue:[]})
|
|
2965
|
+
d.info(`Successfully extracted ${p.length} tasks using data extraction utility`)
|
|
2966
|
+
const f={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:p.length}
|
|
2967
|
+
p.forEach((e=>{const t=e.status
|
|
2968
|
+
t in f&&f[t]++}))
|
|
2967
2969
|
const m=g.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_verified:0,total:m.length}
|
|
2968
2970
|
m.forEach((e=>{const t=e.status||"unverified"
|
|
2969
2971
|
t in y&&y[t]++}))
|
|
2970
2972
|
let w=g.testVerification||null
|
|
2971
2973
|
const k=g.title,b=g.type
|
|
2972
|
-
let I=`# ${"feature"===b?"Feature":"quick-edit"===b?"Quick Edit":"Bug Fix"} Request: ${k} (${t})\nStatus: ${g.status}\nCreated: ${new Date(g.createdAt).toLocaleString()}\nUpdated: ${new Date(g.updatedAt).toLocaleString()}\n\n## Description\n${g.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${
|
|
2973
|
-
return I+=`\n## Task Status\n- Pending: ${
|
|
2974
|
+
let I=`# ${"feature"===b?"Feature":"quick-edit"===b?"Quick Edit":"Bug Fix"} Request: ${k} (${t})\nStatus: ${g.status}\nCreated: ${new Date(g.createdAt).toLocaleString()}\nUpdated: ${new Date(g.updatedAt).toLocaleString()}\n\n## Description\n${g.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${f.completed}/${f.total} completed (${Math.round(f.completed/f.total*100)||0}%)\n- Acceptance Criteria: ${y.verified}/${y.total} verified (${Math.round(y.verified/y.total*100)||0}%)\n`
|
|
2975
|
+
return I+=`\n## Task Status\n- Pending: ${f.pending}\n- In Progress: ${f.in_progress}\n- Blocked: ${f.blocked}\n- Ready for Review: ${f.ready_for_review}\n- Completed: ${f.completed}\n- Reverted: ${f.reverted}\n`,I+="\n## Tasks\n",0===p.length?I+="No tasks found for this request.\n":p.forEach((e=>{I+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${p.length} tasks`),I+="\n## Acceptance Criteria\n",I+=(0,i.formatCriteriaWithHashes)(m)+"\n","ready_for_review"===g.status&&m.some((e=>"verified"!==e.status))&&(I+="\n> **Status: ready_for_review** \u2014 Use the merge operation to verify criteria and merge to main.\n"),w&&(I+=`\n## Test Coverage\n- Test Cases: ${w.totalTestCases||0}\n- Criteria Tested: ${w.criteriaTestedCount||0}/${y.total}\n`,w.criterionCoverage&&Array.isArray(w.criterionCoverage)&&(I+="\n### Detailed Test Coverage:\n",w.criterionCoverage.forEach((e=>{I+=`- Criterion ${e.criterionId}: ${e.coverage} coverage\n`})))),g.recentActivity&&Array.isArray(g.recentActivity)&&(I+="\n## Recent Activity\n",g.recentActivity.slice(0,5).forEach((e=>{const t=new Date(e.timestamp).toLocaleString()
|
|
2974
2976
|
I+=`- ${t}: ${e.description}\n`}))),u({success:!0}),{content:[{type:"text",text:I}]}}catch(t){return d.error("Error getting request information",{args:e,error:t instanceof Error?t.stack:t+""}),u({success:!1,error:t instanceof Error?t.name:"unknown"}),t instanceof n.ConnectionError?{content:[{type:"text",text:"Unable to get request information: Connection to the server failed. Please check your network connection and try again."}],isError:!0}:{content:[{type:"text",text:"Error getting request information: "+(0,s.getErrorMessage)(t)}],isError:!0}}}
|
|
2975
2977
|
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
2978
|
for(let t=0;t<e.length;t++)r=(r<<5)-r+e.charCodeAt(t)|0
|
|
@@ -2994,35 +2996,35 @@ return o(t,e),t})
|
|
|
2994
2996
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDocumentOperations=async function(e,t,r,n,o,s,u){const h=n.child({tool:"document_operations"})
|
|
2995
2997
|
try{const n=["create","search","createSnapshot","getHistory","getVersion","restoreVersion","listAnnotations","createAnnotation","replyToAnnotation","resolveAnnotation"]
|
|
2996
2998
|
for(const t of n)e?.[t]&&"object"==typeof e[t]&&(Object.assign(e,e[t]),delete e[t])
|
|
2997
|
-
const d=a.validateArgs(e,i.DocumentOperationsSchema),{operation:g}=d,
|
|
2999
|
+
const d=a.validateArgs(e,i.DocumentOperationsSchema),{operation:g}=d,p=d.documentId
|
|
2998
3000
|
switch(h.info("Processing document_operations",{operation:g}),g){case"create":{h.info("Routing to create-document handler")
|
|
2999
3001
|
const e=await(0,c.handleCreateDocument)({requestId:d.requestId,filename:d.filename,content:d.content,type:d.type,comment:d.comment},t,r,h,o,s,u)
|
|
3000
3002
|
return o.incrementCounter("document_operations_total",1,{operation:"create",success:!e.isError}),e}case"search":{h.info("Routing to search-documents handler")
|
|
3001
3003
|
const e=await(0,l.handleSearchDocuments)({query:d.query,type:d.type,requestId:d.requestId,includeArchived:d.includeArchived,maxResults:d.maxResults,dateFrom:d.dateFrom,dateTo:d.dateTo,searchIn:d.searchIn},t,r,h,o,s)
|
|
3002
3004
|
return o.incrementCounter("document_operations_total",1,{operation:"search",success:!e.isError}),e}case"create-snapshot":{h.info("Creating version snapshot")
|
|
3003
|
-
const{versionLabel:e,changeSummary:t}=d,n=r.getDocumentClient(),s=await n.createVersionSnapshot(
|
|
3004
|
-
return o.incrementCounter("document_operations_total",1,{operation:"create-snapshot",success:!0}),{content:[{type:"text",text:`\u2705 **Version Snapshot Created**\n\n**Document:** ${
|
|
3005
|
-
const e=r.getDocumentClient(),t=await e.getVersionHistory(
|
|
3005
|
+
const{versionLabel:e,changeSummary:t}=d,n=r.getDocumentClient(),s=await n.createVersionSnapshot(p,e,t)
|
|
3006
|
+
return o.incrementCounter("document_operations_total",1,{operation:"create-snapshot",success:!0}),{content:[{type:"text",text:`\u2705 **Version Snapshot Created**\n\n**Document:** ${p}\n**Version:** ${s.versionNumber}\n**Label:** ${e||"None"}\n**Summary:** ${t||"None"}\n**Created:** `+new Date(s.createdAt).toLocaleString()}]}}case"get-history":{h.info("Retrieving version history")
|
|
3007
|
+
const e=r.getDocumentClient(),t=await e.getVersionHistory(p)
|
|
3006
3008
|
h.info("Version history data received",{hasSnapshots:!!t.snapshots,snapshotCount:t.snapshots?.length||0,hasChangeHistory:!!t.changeHistory,changeCount:t.changeHistory?.length||0,keys:Object.keys(t)}),o.incrementCounter("document_operations_total",1,{operation:"get-history",success:!0})
|
|
3007
3009
|
let n=""
|
|
3008
3010
|
t.snapshots&&t.snapshots.length>0?(n="### \u{1f4da} Version Snapshots\n\n",t.snapshots.forEach((e=>{n+=`**Version ${e.versionNumber}** - ${new Date(e.createdAt).toLocaleString()}\n`,e.versionLabel&&(n+=` Label: ${e.versionLabel}\n`),e.changeSummary&&(n+=` Summary: ${e.changeSummary}\n`),n+="\n"}))):n="### \u{1f4da} Version Snapshots\n\nNo version snapshots created yet.\n\n"
|
|
3009
3011
|
let s=""
|
|
3010
|
-
return t.changeHistory&&t.changeHistory.length>0?(s="### \u{1f4dd} Recent Changes\n\n",t.changeHistory.slice(0,10).forEach((e=>{s+=`**${e.toolName}** - ${new Date(e.createdAt).toLocaleString()}\n`,e.createdBy&&(s+=` By: ${e.createdBy}\n`),s+="\n"}))):s="### \u{1f4dd} Recent Changes\n\nNo changes recorded.\n",{content:[{type:"text",text:`## Version History for ${
|
|
3011
|
-
const e=r.getDocumentClient(),t=await e.getVersion(
|
|
3012
|
-
return o.incrementCounter("document_operations_total",1,{operation:"get-version",success:!0}),{content:[{type:"text",text:`## Version ${d.versionNumber} of ${
|
|
3013
|
-
const e=r.getDocumentClient(),t=await e.restoreToVersion(
|
|
3014
|
-
return o.incrementCounter("document_operations_total",1,{operation:"restore-version",success:!0}),{content:[{type:"text",text:`\u2705 **Document Restored**\n\n**Document:** ${
|
|
3015
|
-
const e=r.getDocumentClient(),t=await e.listAnnotations(
|
|
3016
|
-
if(o.incrementCounter("document_operations_total",1,{operation:"list-annotations",success:!0}),!t||0===t.length)return{content:[{type:"text",text:`No annotations found on document ${
|
|
3017
|
-
let n=`## Annotations on ${
|
|
3012
|
+
return t.changeHistory&&t.changeHistory.length>0?(s="### \u{1f4dd} Recent Changes\n\n",t.changeHistory.slice(0,10).forEach((e=>{s+=`**${e.toolName}** - ${new Date(e.createdAt).toLocaleString()}\n`,e.createdBy&&(s+=` By: ${e.createdBy}\n`),s+="\n"}))):s="### \u{1f4dd} Recent Changes\n\nNo changes recorded.\n",{content:[{type:"text",text:`## Version History for ${p}\n\n${n}${s}`}]}}case"get-version":{h.info("Retrieving specific version")
|
|
3013
|
+
const e=r.getDocumentClient(),t=await e.getVersion(p,d.versionNumber)
|
|
3014
|
+
return o.incrementCounter("document_operations_total",1,{operation:"get-version",success:!0}),{content:[{type:"text",text:`## Version ${d.versionNumber} of ${p}\n\n**Created:** ${new Date(t.createdAt).toLocaleString()}\n**Label:** ${t.versionLabel||"None"}\n**Summary:** ${t.changeSummary||"None"}\n\n### Content:\n\n\`\`\`\n${t.content}\n\`\`\``}]}}case"restore-version":{h.info("Restoring to version")
|
|
3015
|
+
const e=r.getDocumentClient(),t=await e.restoreToVersion(p,d.versionNumber)
|
|
3016
|
+
return o.incrementCounter("document_operations_total",1,{operation:"restore-version",success:!0}),{content:[{type:"text",text:`\u2705 **Document Restored**\n\n**Document:** ${p}\n**Restored to Version:** ${d.versionNumber}\n**Filename:** ${t.filename}\n\nThe document has been successfully restored to version ${d.versionNumber}.`}]}}case"list-annotations":{h.info("Listing annotations")
|
|
3017
|
+
const e=r.getDocumentClient(),t=await e.listAnnotations(p)
|
|
3018
|
+
if(o.incrementCounter("document_operations_total",1,{operation:"list-annotations",success:!0}),!t||0===t.length)return{content:[{type:"text",text:`No annotations found on document ${p}.`}]}
|
|
3019
|
+
let n=`## Annotations on ${p} (${t.length})\n\n`
|
|
3018
3020
|
for(const e of t){if(n+=`### ${"resolved"===e.status?"\u2705":"\u{1f4ac}"} ${e.id} [${e.status}]\n`,n+=`> "${e.anchor?.selectedText?.substring(0,80)||""}"\n\n`,n+=e.body+"\n",e.createdByAgent&&(n+=`*By agent: ${e.createdByAgent}*\n`),e.replies&&e.replies.length>0){n+=`\n**Replies (${e.replies.length}):**\n`
|
|
3019
3021
|
for(const t of e.replies)n+="- "+t.body,t.createdByAgent&&(n+=` *(${t.createdByAgent})*`),n+="\n"}n+="\n---\n\n"}return{content:[{type:"text",text:n}]}}case"create-annotation":{h.info("Creating annotation")
|
|
3020
|
-
const e=d.selectedText,t=d.body,{prefixContext:n,suffixContext:s,lineHint:i}=d,a=r.getDocumentClient(),c=u?"agent":void 0,l=u?.sessionId,g=await a.createAnnotation(
|
|
3021
|
-
return o.incrementCounter("document_operations_total",1,{operation:"create-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Annotation Created**\n\n**ID:** ${g.id}\n**Document:** ${
|
|
3022
|
-
const e=d.annotationId,t=d.body,n=r.getDocumentClient(),s=await n.replyToAnnotation(
|
|
3022
|
+
const e=d.selectedText,t=d.body,{prefixContext:n,suffixContext:s,lineHint:i}=d,a=r.getDocumentClient(),c=u?"agent":void 0,l=u?.sessionId,g=await a.createAnnotation(p,{selectedText:e,prefixContext:n,suffixContext:s,lineHint:i,body:t,createdByAgent:c,createdBySessionId:l})
|
|
3023
|
+
return o.incrementCounter("document_operations_total",1,{operation:"create-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Annotation Created**\n\n**ID:** ${g.id}\n**Document:** ${p}\n**Selected text:** "${e.substring(0,60)}"\n**Comment:** `+t}]}}case"reply-to-annotation":{h.info("Replying to annotation")
|
|
3024
|
+
const e=d.annotationId,t=d.body,n=r.getDocumentClient(),s=await n.replyToAnnotation(p,e,{body:t,createdByAgent:u?"agent":void 0,createdBySessionId:u?.sessionId})
|
|
3023
3025
|
return o.incrementCounter("document_operations_total",1,{operation:"reply-to-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Reply Added**\n\n**Reply ID:** ${s.id}\n**Annotation:** ${e}\n**Body:** `+t}]}}case"resolve-annotation":{h.info("Resolving annotation")
|
|
3024
3026
|
const e=d.annotationId,t=r.getDocumentClient()
|
|
3025
|
-
return await t.resolveAnnotation(
|
|
3027
|
+
return await t.resolveAnnotation(p,e,u?"agent":void 0),o.incrementCounter("document_operations_total",1,{operation:"resolve-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Annotation Resolved**\n\n**Annotation:** ${e}\n**Status:** resolved`}]}}default:throw Error("Unknown operation type: "+g)}}catch(e){return h.error("document_operations failed",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("document_operations_errors",1),{content:[{type:"text",text:"\u274c **Document Operations Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
3026
3028
|
const i=t(6183),a=s(t(5967)),c=t(1572),l=t(1483),d=t(8824)},5671(e,exports,t){function r(e){const[t,...r]=e.split("/")
|
|
3027
3029
|
return{provider:t||"anthropic",modelId:r.join("/")||e}}function n(e){const t={anthropic:!1,openai:!1}
|
|
3028
3030
|
try{const n=(0,a.join)(e,"opencode.json")
|
|
@@ -3043,10 +3045,10 @@ let h,g=0
|
|
|
3043
3045
|
if("one_down"===n&&(g=1),"two_down"===n&&(g=2),i===s.provider)h=u+g
|
|
3044
3046
|
else{const e=l.length>1?u/(l.length-1):0
|
|
3045
3047
|
h=Math.round(e*(d.length-1))+g}h=Math.min(h,d.length-1),h=Math.max(h,0)
|
|
3046
|
-
const
|
|
3047
|
-
let
|
|
3048
|
+
const p=d[h]
|
|
3049
|
+
let f
|
|
3048
3050
|
var m,y
|
|
3049
|
-
return i===s.provider?(m=a,y=f
|
|
3051
|
+
return i===s.provider?(m=a,y=p,f=s.modelId.replace(m,y)):f=p,{provider:i,modelId:f,fullModel:`${i}/${f}`,resolved:!0}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseModelString=r,exports.getAvailableProviders=n,exports.getMainSessionModel=o,exports.resolveModelTier=s,exports.resolveAgentModel=function(e,t="inherit",i="same"){const a=o(e)
|
|
3050
3052
|
if(!a)return{provider:"anthropic",modelId:"claude-sonnet-4-5",fullModel:"anthropic/claude-sonnet-4-5",resolved:!1,reason:"Could not determine main session model, using default"}
|
|
3051
3053
|
if("inherit"===t&&"same"===i){const e=r(a)
|
|
3052
3054
|
return{provider:e.provider,modelId:e.modelId,fullModel:a,resolved:!0}}return s(a,t,i,n(e))}
|
|
@@ -3069,25 +3071,25 @@ if(t){const e=Date.now()-t
|
|
|
3069
3071
|
try{this.metrics.observeHistogram("offline_duration_ms",e,{reconnection_type:"manual"}),this.logger.info(`System was offline for ${Math.round(e/1e3)} seconds before manual reconnection`)}catch(e){this.logger.warn("Error observing histogram for offline duration on manual reconnection",{error:e instanceof Error?e.message:e+""})}}}}catch(e){this.logger.warn("Error calculating offline duration during manual mode change",{error:(0,s.getErrorMessage)(e)})}this.notifyOnlineStatus()}else!t&&e&&(this.logger.info("Manually setting connection mode to OFFLINE"),this.safeSetGauge("connection_status",0),this.safeSetGauge("last_connection_failure_timestamp",Date.now()),this.safeIncrementCounter("manual_disconnections",1),process.nextTick((()=>{exports.eventBus.emit(exports.EVENTS.OFFLINE,{timestamp:(new Date).toISOString()})})))}isOffline(){return this.isInOfflineMode()}async checkConnectivity(){return this.logger.debug("Explicit connectivity check requested"),this.healthCheckManager.requestHealthCheck()}getHealthCheckStats(){const e=this.healthCheckManager.getStats()
|
|
3070
3072
|
return{isOffline:this.isInOfflineMode(),consecutiveFailures:e.consecutiveFailures,currentBackoffMs:e.currentBackoffMs,lastCheckTime:e.lastCheckTime}}cleanup(){this.logger.debug("Cleaning up connection status manager resources"),this.healthCheckManager.stopHealthChecks(),exports.eventBus.removeAllListeners(exports.EVENTS.ONLINE),exports.eventBus.removeAllListeners(exports.EVENTS.OFFLINE)}}},5692(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3071
3073
|
const r=t(6183),n=t(2965)
|
|
3072
|
-
exports.def={name:"read_files",description:'Read the contents of multiple files and documents with flexible line selection.\n\nLINE SELECTION (string format):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "5-15"\n- Entire file: omit "lines" parameter\n\nEXAMPLES:\n- Read first 10 lines: {"path": "file.txt", "lines": "1-10"}\n- Read specific lines: {"path": "file.txt", "lines": "1,5,25"}\n- Read line 42 only: {"path": "file.txt", "lines": "42"}\n- Read entire file: {"path": "file.txt"}\n\nSupports both filesystem files (using \'path\') and tracked documents (using \'documentId\'). More efficient than reading files one by one. Failed reads won\'t stop the entire operation.',schema:r.ReadFilesSchema,annotations:{title:"Read Files/Documents",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleReadFiles)(e,t.context,t.logger,t.metrics)}}},5715(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u
|
|
3073
|
-
try{const{requestId:
|
|
3074
|
-
if(!
|
|
3075
|
-
if(!
|
|
3076
|
-
|
|
3077
|
-
const
|
|
3078
|
-
let
|
|
3079
|
-
try{const e=await
|
|
3080
|
-
|
|
3081
|
-
return
|
|
3082
|
-
return
|
|
3083
|
-
try{await
|
|
3084
|
-
return
|
|
3085
|
-
try{
|
|
3086
|
-
return
|
|
3087
|
-
return
|
|
3088
|
-
r instanceof
|
|
3089
|
-
try{await(0,
|
|
3090
|
-
const r=t(9860),n=t(
|
|
3074
|
+
exports.def={name:"read_files",description:'Read the contents of multiple files and documents with flexible line selection.\n\nLINE SELECTION (string format):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "5-15"\n- Entire file: omit "lines" parameter\n\nEXAMPLES:\n- Read first 10 lines: {"path": "file.txt", "lines": "1-10"}\n- Read specific lines: {"path": "file.txt", "lines": "1,5,25"}\n- Read line 42 only: {"path": "file.txt", "lines": "42"}\n- Read entire file: {"path": "file.txt"}\n\nSupports both filesystem files (using \'path\') and tracked documents (using \'documentId\'). More efficient than reading files one by one. Failed reads won\'t stop the entire operation.',schema:r.ReadFilesSchema,annotations:{title:"Read Files/Documents",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleReadFiles)(e,t.context,t.logger,t.metrics)}}},5715(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,a,c,l,d,u){const h=c.child({tool:"complete_request"}),g=l.startTimer("tool_execution_time")
|
|
3075
|
+
try{const{requestId:n,summary:o}=e
|
|
3076
|
+
if(!n)throw(0,r.createValidationError)("Request ID is required")
|
|
3077
|
+
if(!o)throw(0,r.createValidationError)("Summary is required")
|
|
3078
|
+
h.info("Starting request completion",{requestId:n})
|
|
3079
|
+
const c=u?.sessionId
|
|
3080
|
+
let l
|
|
3081
|
+
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:c})
|
|
3082
|
+
l=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3083
|
+
return h.error("Server validation failed",{requestId:n,error:t}),g({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate completion: "+t}],isError:!0}}if(!l.canComplete){let e=`Cannot complete request ${n}: ${l.reason}\n`
|
|
3084
|
+
return l.blockedByTasks&&l.blockedByTasks.length>0&&(e+="\n**Tasks that must be completed or canceled first:**\n",l.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (Status: ${t.status})\n`}))),l.lifoViolation&&(e+="\n**Requests that must be re-completed first (LIFO order):**\n",l.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (Status: ${t.status})\n`}))),g({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}const d=a.getRequestClient(),p="auto-test-then-merge"===l.completionMode,f=p?"ready_for_review":"ready_for_merge"
|
|
3085
|
+
try{await d.updateRequest(n,{status:f,completionSummary:o})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3086
|
+
return g({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let m
|
|
3087
|
+
try{m=await d.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3088
|
+
return g({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const y=m?.acceptanceCriteria||[]
|
|
3089
|
+
return g({success:!0}),p?{content:[{type:"text",text:`Request ${n} moved to ready_for_review. Testing is active \u2014 a notification has been created for the user to choose testing mode. Do NOT call merge or any other tool. Your work is done. Stop here and wait.`}]}:0===y.length?{content:[{type:"text",text:`Request ${n} is ready. No acceptance criteria defined \u2014 call merge directly.`}]}:{content:[{type:"text",text:`Request ${n} completion started (${f}).\n\n## Next Step: Verify & Merge\n\n${(0,i.formatVerifyInstructions)(y)}\n\nUse the merge operation with your verification evidence to merge to main.`}]}}catch(r){let s="An unexpected error occurred",i=""
|
|
3090
|
+
r instanceof n.ZodError?(s="Validation error",i=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")):r instanceof Error?(s=r.message,i=r.stack||""):i=r+"",h.error("Complete request failed",{error:s,details:i})
|
|
3091
|
+
try{await(0,o.createFailureToolRecord)("complete-request",r,{error:s,details:i,requestId:e?.requestId},a.getToolRecordClient(),h,l,{requestId:e?.requestId,projectId:t.projectId,note:"Failed to complete request"})}catch{}return l.startTimer("tool_execution_time")({success:!1,error:r instanceof Error?r.name:"unknown"}),{content:[{type:"text",text:"Error: "+s}],isError:!0}}}
|
|
3092
|
+
const r=t(9860),n=t(1569),o=t(8616),s=t(8824),i=t(5454)},5767(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3091
3093
|
const r=t(6183),n=t(6285)
|
|
3092
3094
|
exports.def={name:"specialist_ops",description:"Manage your pool of up to 10 specialists. Each has a specialization describing their domain. Reuse specialists via follow-up before spawning new ones.\n\nOperations:\n\u2022 delegate - Spawn a new specialist (include specialization). Abort an idle specialist first if pool is full.\n\u2022 follow-up - Send follow-up instructions to an existing specialist (can update specialization)\n\u2022 check-status - Check if a specialist is busy or idle\n\u2022 list - List specialist sessions with specializations\n\u2022 abort - Cancel a stuck specialist",schema:r.SpecialistOpsSchema,annotations:{title:"Specialist Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleSpecialistOps)(e,t.context,t.logger,t.metrics,t.apiClient??void 0,t.cliOrigin)}}},5802(module){module.exports=require("@modelcontextprotocol/sdk/server/stdio.js")},5806(e,exports,t){function r(){const e=n.z.object({requestId:n.z.string(),summary:n.z.string(),acceptanceEvidence:n.z.array(n.z.object({evidence:n.z.string()}))}),t=n.z.object({testRecords:n.z.array(n.z.string()),coverage:n.z.object({criteriaTestedCount:n.z.number(),totalTestCases:n.z.number()}),criterionCoverage:n.z.array(n.z.object({coverage:n.z.enum(["none","partial","full"]),testRecords:n.z.array(n.z.string())}))})
|
|
3093
3095
|
return(0,o.areTestsRequiredForCompletion)()?e.extend({testVerification:t}):e}Object.defineProperty(exports,"__esModule",{value:!0}),exports.DynamicCompleteRequestSchema=void 0,exports.getDynamicCompleteRequestSchema=r
|
|
@@ -3136,14 +3138,14 @@ let H=0
|
|
|
3136
3138
|
M.length>0&&r.setProjectId(t.projectId)
|
|
3137
3139
|
for(let e=0;e<x.length;e++){const t=x[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3138
3140
|
try{try{await a.default.access(t.full)}catch(e){throw Error("File not found: "+t.normalized)}if((await a.default.stat(t.full)).isDirectory())throw Error("Cannot 'delete' a directory: "+t.normalized)
|
|
3139
|
-
await a.default.unlink(t.full),r.success=!0,H++,i.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,
|
|
3141
|
+
await a.default.unlink(t.full),r.success=!0,H++,i.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete file "+t.normalized,{error:r.error})}B.push(r)}const U=M.length>0?r.getDocumentClient():null
|
|
3140
3142
|
for(const e of M){const t=e.target,n={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3141
3143
|
try{let e
|
|
3142
|
-
try{if(e=await
|
|
3143
|
-
throw e}try{await(0,
|
|
3144
|
-
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,
|
|
3145
|
-
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,
|
|
3146
|
-
o.recordValue("delete_files_time",
|
|
3144
|
+
try{if(e=await U.getDocument(t),n.filename=e.filename,i.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,g.validateRequestStatusForDocumentOperation)(e.requestId,I,i,o,"delete-document")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
|
|
3145
|
+
throw e}try{await(0,p.ensureDocumentNotLocked)(t,r,i,o,"delete-document-archive")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
|
|
3146
|
+
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,f.getErrorMessage)(e)}`)}const s=await U.archiveDocument(t)
|
|
3147
|
+
n.success=!0,n.filename=s.filename,H++,i.info("Document archived successfully",{documentId:s.id,filename:s.filename,archivedAt:s.archived_at})}catch(e){n.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete document "+t,{error:n.error})}B.push(n)}const W=Date.now()-m
|
|
3148
|
+
o.recordValue("delete_files_time",W),o.incrementCounter("delete_files_operations_total",R),o.incrementCounter("delete_files_operations_success",H),o.incrementCounter("delete_files_operations_failed",R-H),o.incrementCounter("delete_files_file_operations",T.length),o.incrementCounter("delete_files_document_operations",M.length),H===R?o.incrementCounter("delete_files_success",1):H>0?o.incrementCounter("delete_files_partial_success",1):o.incrementCounter("delete_files_total_failure",1)
|
|
3147
3149
|
let G=null
|
|
3148
3150
|
if(H>0){k=l.FileOperationPhase.GIT_COMMIT,o.incrementCounter("delete_files_phase",1,{phase:k})
|
|
3149
3151
|
const e=B.filter((e=>e.success)),r=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
|
|
@@ -3158,11 +3160,11 @@ Y=e>0&&t>0?`Successfully deleted ${e} files and ${t} documents`:e>0?`Successfull
|
|
|
3158
3160
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n"):"All delete operations failed:\n"+B.map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
|
|
3159
3161
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
|
|
3160
3162
|
return G?.commitHash&&(Y+="\nCommit: "+G.commitHash.substring(0,8)),K.requestId&&(Y+="\nBranch: "+K.requestId),F.lockAcquired&&F.lockedRequestId&&(Y+="\n\u{1f512} **Locked request:** "+F.lockedRequestId),{content:[{type:"text",text:Y}],isError:0===H}}catch(n){if(e.taskId&&r)try{const o=r.getToolRecordClient(),s=n instanceof d.NotFoundError||n instanceof d.ValidationError||n instanceof u.ZodError
|
|
3161
|
-
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,
|
|
3162
|
-
if(o.recordValue("delete_files_time",s),o.incrementCounter("delete_files_errors",1),i.error("Error in delete-files operation:",{error:(0,
|
|
3163
|
+
await o.createToolRecord({...s?{}:{taskId:e.taskId},projectId:t.projectId,type:"delete-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment,error:(0,f.getErrorMessage)(n),errorDetails:n instanceof Error?n.stack:n+"",phase:k,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,f.getErrorMessage)(n)})}catch(t){i.error("Failed to create failure record for delete-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0})}const s=Date.now()-m
|
|
3164
|
+
if(o.recordValue("delete_files_time",s),o.incrementCounter("delete_files_errors",1),i.error("Error in delete-files operation:",{error:(0,f.getErrorMessage)(n),time:s}),(y||w)&&e.taskId){k=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
3163
3165
|
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",b.recordType,"Failed to delete operations",{status:"failed",error:(0,
|
|
3165
|
-
const a=i(t(1943)),c=t(6183),l=s(t(5967)),d=t(9860),u=t(1569),h=t(7478),g=t(5003),
|
|
3166
|
+
await l.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",b.recordType,"Failed to delete operations",{status:"failed",error:(0,f.getErrorMessage)(n),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment},"Failed to delete operations",t,s,i,o,b.metricsPrefix)}catch(t){i.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(n,k,i,o,e,b)}}
|
|
3167
|
+
const a=i(t(1943)),c=t(6183),l=s(t(5967)),d=t(9860),u=t(1569),h=t(7478),g=t(5003),p=t(9949),f=t(8824)},5997(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3166
3168
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3167
3169
|
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=[]
|
|
3168
3170
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3245,15 +3247,13 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3245
3247
|
var t={}
|
|
3246
3248
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3247
3249
|
return o(t,e),t})
|
|
3248
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,r,n,o,s,p){const
|
|
3250
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,r,n,o,s,p){const f=n.child({tool:"specialist_ops"}),m=o.startTimer("tool_execution_time")
|
|
3249
3251
|
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
3252
|
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
|
-
const n=c.validateArgs(e,a.SpecialistOpsSchema),{operation:
|
|
3252
|
-
let
|
|
3253
|
-
switch(
|
|
3254
|
-
|
|
3255
|
-
if(!i){const e=await(0,h.getServerUrl)(r,m)
|
|
3256
|
-
if(e)try{i=(0,g.getCachedSession)()?.sessionId||await(0,h.discoverParentSessionId)(e,m)}catch{}}if(i&&s){const e=await async function(e,t,r,n,o){n.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
|
|
3253
|
+
const n=c.validateArgs(e,a.SpecialistOpsSchema),{operation:y,sessionId:w}=n
|
|
3254
|
+
let k
|
|
3255
|
+
switch(f.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=n.delegate,o=10,i=p?.sessionId||g.sessionIdentity.getIdentity()?.sessionId
|
|
3256
|
+
if(i&&s){const e=await async function(e,t,r,n,o){n.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
|
|
3257
3257
|
const s=await(0,h.getServerUrl)(r,n)
|
|
3258
3258
|
if(s)try{const r=await fetch(s.replace(/\/$/,"")+"/session")
|
|
3259
3259
|
if(!r.ok)return
|
|
@@ -3266,34 +3266,33 @@ return"specialist"===t?.agentType&&"archived"!==t?.status}))
|
|
|
3266
3266
|
if(n.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
|
|
3267
3267
|
const g=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
|
|
3268
3268
|
return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
|
|
3269
|
-
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,
|
|
3270
|
-
if(e){
|
|
3269
|
+
return{content:[{type:"text",text:`\u274c Specialist pool is full (${h.length}/${t}).\nAbort an idle specialist first with \`specialist_ops abort\`, then delegate again.\n\nCurrent pool:\n`+g}],isError:!0}}catch(e){return void n.warn("Pool limit check failed, allowing spawn",{error:(0,l.getErrorMessage)(e)})}}(i,o,r,f,s)
|
|
3270
|
+
if(e){k=e
|
|
3271
3271
|
break}}let a=e.description
|
|
3272
|
-
const c=await Promise.resolve().then(t.t.bind(t,9896,23)),
|
|
3273
|
-
if(i)try{const e=await(0,h.getServerUrl)(r,
|
|
3274
|
-
if(
|
|
3275
|
-
if(
|
|
3276
|
-
|
|
3272
|
+
const c=await Promise.resolve().then(t.t.bind(t,9896,23)),m=e=>c.appendFileSync("/tmp/specialist-name-debug.log",`${(new Date).toISOString()} ${e}\n`)
|
|
3273
|
+
if(i)try{const e=await(0,h.getServerUrl)(r,f)
|
|
3274
|
+
if(m(`serverUrl=${e}, parentId=${i}`),e){const t=await fetch(e.replace(/\/$/,"")+"/session")
|
|
3275
|
+
if(m("session fetch status="+t.status),t.ok){const e=(await t.json()).filter((e=>(e.parentId||e.parentID)===i)).map((e=>e.title||""))
|
|
3276
|
+
m(`siblings=${e.length}: ${e.join(", ")}`)
|
|
3277
3277
|
const r=(0,d.pickSpecialistName)(e)
|
|
3278
|
-
a=r,
|
|
3279
|
-
const
|
|
3280
|
-
|
|
3281
|
-
break}case"follow-up":{const e=await(0,h.getServerUrl)(r,
|
|
3278
|
+
a=r,m("picked name: "+r)}}else m("no serverUrl")}catch(e){m("error: "+(e instanceof Error?e.message:e+""))}else m("no parentId")
|
|
3279
|
+
const y=e.requestId,w=y?`Working on request ${y}.\n\n${e.prompt}`:e.prompt
|
|
3280
|
+
k=await(0,u.handleSpawn)({agent:"specialist",prompt:w,title:a,specialization:e.specialization},r,f,s,p)
|
|
3281
|
+
break}case"follow-up":{const e=await(0,h.getServerUrl)(r,f)
|
|
3282
3282
|
if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
|
|
3283
|
-
if(t.ok){const e=await t.json(),r=e[
|
|
3284
|
-
if(r&&"idle"!==r&&"prompting"!==r){
|
|
3285
|
-
break}}}catch{}
|
|
3283
|
+
if(t.ok){const e=await t.json(),r=e[w]?.type
|
|
3284
|
+
if(r&&"idle"!==r&&"prompting"!==r){k={content:[{type:"text",text:`\u274c Specialist ${w} is currently busy (status: ${r}).\nUse \`delegate\` to spawn a new specialist instead.`}],isError:!0}
|
|
3285
|
+
break}}}catch{}k=await(0,u.handleContinue)(w,n.followUp.prompt,r,f,s,"specialist",p)
|
|
3286
3286
|
const t=n.followUp.specialization
|
|
3287
3287
|
if(t&&s)try{const e=s.getCLISessionClient()
|
|
3288
|
-
e&&(await e.createOrUpdateSession({externalSessionId:
|
|
3288
|
+
e&&(await e.createOrUpdateSession({externalSessionId:w,specialization:t}),k.content[0].text+="\nSpecialization updated to: "+t)}catch{}break}case"check-status":k=await(0,u.handleCheckStatus)(w,r,f,s)
|
|
3289
3289
|
break
|
|
3290
|
-
case"abort":if(
|
|
3291
|
-
e&&await e.createOrUpdateSession({externalSessionId:
|
|
3292
|
-
case"list":{
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
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
|
|
3290
|
+
case"abort":if(k=await(0,u.handleAbort)(w,r,f),!k.isError&&s)try{const e=s.getCLISessionClient()
|
|
3291
|
+
e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
|
|
3292
|
+
case"list":{const e=p?.sessionId||g.sessionIdentity.getIdentity()?.sessionId
|
|
3293
|
+
k=await(0,u.handleListSessions)(r,f,s,{activeOnly:n.list?.activeOnly,requestId:n.list?.requestId,limit:n.list?.limit,agentType:"specialist",parentSessionId:e})
|
|
3294
|
+
break}default:throw new i.ValidationError("Unknown operation: "+y)}return m({success:!0}),o.incrementCounter(`specialist_ops_${y}_success`,1),k}catch(e){return f.error("Specialist ops failed",{error:e instanceof Error?e.stack:e+""}),m({success:!1}),o.incrementCounter("specialist_ops_errors",1),{content:[{type:"text",text:"Specialist operation failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
3295
|
+
const i=t(9860),a=t(6183),c=s(t(5967)),l=t(8824),d=t(9089),u=t(1725),h=t(7617),g=t(6688)},6315(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3297
3296
|
const r=t(6183),n=t(2982)
|
|
3298
3297
|
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)
|
|
3299
3298
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
@@ -3304,17 +3303,17 @@ var t={}
|
|
|
3304
3303
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3305
3304
|
return o(t,e),t})
|
|
3306
3305
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRevertRequest=async function(e,t,r,n,o){const s=n.child({tool:"revert_request"}),h=o.startTimer("tool_execution_time")
|
|
3307
|
-
try{const n=i.RevertRequestSchema.parse(e),{requestId:d,reason:g,confirmDestructive:
|
|
3308
|
-
if(s.info("Starting revert/cancel process",{requestId:d,reason:g}),!
|
|
3309
|
-
let
|
|
3306
|
+
try{const n=i.RevertRequestSchema.parse(e),{requestId:d,reason:g,confirmDestructive:p}=n
|
|
3307
|
+
if(s.info("Starting revert/cancel process",{requestId:d,reason:g}),!p)return h({success:!1,reason:"confirmation_required"}),{content:[{type:"text",text:"Error: This operation requires confirmation. Set confirmDestructive: true to proceed.\n\nThis tool will:\n- **For open/in_progress requests:** Cancel the request (no git changes)\n- **For completed requests:** Revert using git (affects git history)\n\nBoth operations make the request read-only and block further tool use."}],isError:!0}
|
|
3308
|
+
let f
|
|
3310
3309
|
try{const e=await r.proxyPost(`/api/projects/${t.projectId}/requests/${d}/validate-revert`,{})
|
|
3311
|
-
|
|
3312
|
-
return s.error("Server validation failed",{requestId:d,error:t}),h({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate revert: "+t}],isError:!0}}if(s.info("Server validation result",{requestId:d,canRevert:
|
|
3313
|
-
return
|
|
3314
|
-
try{return await r.proxyPost(`/api/projects/${t.projectId}/requests/${d}/finalize-revert`,{reason:g,operationType:"cancel"}),h({success:!0}),{content:[{type:"text",text:`Successfully canceled request ${d}.\n\nOperation: Cancel (no git changes)\nTasks updated: ${
|
|
3310
|
+
f=e?.data||e}catch(e){const t=(0,u.getErrorMessage)(e)
|
|
3311
|
+
return s.error("Server validation failed",{requestId:d,error:t}),h({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate revert: "+t}],isError:!0}}if(s.info("Server validation result",{requestId:d,canRevert:f.canRevert,operationType:f.operationType,mergeCommitHash:f.mergeCommitHash?.substring(0,8),reason:f.reason}),!f.canRevert){let e=`Cannot revert request ${d}: ${f.reason}\n`
|
|
3312
|
+
return f.lifoViolation?.blockingRequests?.length&&(e+="\n**Requests that must be reverted first (in reverse order):**\n",f.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (${t.status})\n`})),e+="\n**Why:** Requests must be reverted in reverse order (LIFO) to maintain safe git history.\n",e+="Revert the above request(s) first, then retry this one."),h({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if("cancel"===f.operationType){s.info("Cancel operation \u2014 delegating to server",{requestId:d})
|
|
3313
|
+
try{return await r.proxyPost(`/api/projects/${t.projectId}/requests/${d}/finalize-revert`,{reason:g,operationType:"cancel"}),h({success:!0}),{content:[{type:"text",text:`Successfully canceled request ${d}.\n\nOperation: Cancel (no git changes)\nTasks updated: ${f.tasksToUpdate.length} task(s) marked as canceled\nReason: ${g}`}]}}catch(e){const t=(0,u.getErrorMessage)(e)
|
|
3315
3314
|
return h({success:!1,error:"cancel_finalization_failed"}),{content:[{type:"text",text:"Failed to cancel request: "+t}],isError:!0}}}if(s.info("Revert operation \u2014 performing git revert",{requestId:d}),!t.git)throw(0,a.createServiceError)("Git repository not available for revert",{requestId:d})
|
|
3316
3315
|
t.syncBranchState&&await t.syncBranchState()
|
|
3317
|
-
let m=
|
|
3316
|
+
let m=f.mergeCommitHash
|
|
3318
3317
|
if(!m){s.info("No merge commit hash from server, searching git log",{requestId:d})
|
|
3319
3318
|
const e=await async function(e,t,r){try{const r=t.workspaceManager.getMainGit(),n=await r.raw(["log","--merges","--format=%H %s","HEAD"]),o=n.trim()?n.trim().split("\n").map((e=>{const t=e.indexOf(" ")
|
|
3320
3319
|
return-1===t?{hash:e,message:""}:{hash:e.substring(0,t),message:e.substring(t+1)}})):[],s=c.generateMergeMessagePatterns(e)
|
|
@@ -3330,7 +3329,7 @@ try{s.info("Executing git revert",{mergeCommitHash:m.substring(0,8)}),await y.ra
|
|
|
3330
3329
|
const e=await(0,l.verifyGitStateConsistency)(y,k,s,`revert-request-${d}-verification`)
|
|
3331
3330
|
e.consistent||s.error("Git state inconsistency after revert",{issues:e.issues}),s.info("Git revert completed",{requestId:d,originalMergeCommit:m.substring(0,8),revertCommitHash:k.substring(0,8)})}catch(e){const t=(0,u.getErrorMessage)(e)
|
|
3332
3331
|
return s.error("Git revert failed",{requestId:d,error:t}),h({success:!1,error:"git_revert_failed"}),{content:[{type:"text",text:"Git revert failed: "+t}],isError:!0}}try{await r.proxyPost(`/api/projects/${t.projectId}/requests/${d}/finalize-revert`,{reason:g,operationType:"revert",revertCommitHash:k,originalMergeCommitHash:m})}catch(e){const t=(0,u.getErrorMessage)(e)
|
|
3333
|
-
return s.error("CRITICAL: Git revert succeeded but server finalization failed",{requestId:d,revertCommitHash:k,error:t}),h({success:!1,error:"finalization_failed"}),{content:[{type:"text",text:`CRITICAL: Git revert succeeded (commit: ${k.substring(0,8)}) but failed to update server state: ${t}`}],isError:!0}}return h({success:!0}),{content:[{type:"text",text:`Successfully reverted request ${d}.\n\nOperation: Revert (git revert of merge commit)\nTasks updated: ${
|
|
3332
|
+
return s.error("CRITICAL: Git revert succeeded but server finalization failed",{requestId:d,revertCommitHash:k,error:t}),h({success:!1,error:"finalization_failed"}),{content:[{type:"text",text:`CRITICAL: Git revert succeeded (commit: ${k.substring(0,8)}) but failed to update server state: ${t}`}],isError:!0}}return h({success:!0}),{content:[{type:"text",text:`Successfully reverted request ${d}.\n\nOperation: Revert (git revert of merge commit)\nTasks updated: ${f.tasksToUpdate.length} task(s) marked as reverted\nReason: ${g}\n\nYou can re-complete the request if the revert was a mistake.`}]}}catch(n){if(n instanceof a.ValidationError||n instanceof a.NotFoundError)return s.warn("Revert validation failed",{error:n.message,requestId:e.requestId}),h({success:!1,error:"validation"}),{content:[{type:"text",text:"Error: "+n.message}],isError:!0}
|
|
3334
3333
|
if(n instanceof d.ZodError)return h({success:!1,error:"zod_validation"}),{content:[{type:"text",text:"Validation error: "+n.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")}],isError:!0}
|
|
3335
3334
|
if(t.projectId&&e.requestId)try{const o=r.getToolRecordClient()
|
|
3336
3335
|
await o.createToolRecord({requestId:e.requestId,projectId:t.projectId,type:"revert-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),reason:e.reason,error:(0,u.getErrorMessage)(n)},note:"Failed to revert request: "+(0,u.getErrorMessage)(n)})}catch{}return s.error("Revert request failed",{error:(0,u.getErrorMessage)(n),requestId:e.requestId}),h({success:!1,error:n instanceof Error?n.name:"unknown"}),{content:[{type:"text",text:"Failed to revert request: "+(0,u.getErrorMessage)(n)}],isError:!0}}}
|
|
@@ -3351,7 +3350,7 @@ break
|
|
|
3351
3350
|
case"between":if(void 0===e.afterLine||void 0===e.beforeLine)throw Error("Both afterLine and beforeLine are required for between insertion")
|
|
3352
3351
|
n=(0,m.insertBetweenLines)(r,e.afterLine,e.beforeLine,e.content)
|
|
3353
3352
|
break
|
|
3354
|
-
default:throw Error("Unknown insertion type: "+e.type)}r=n.newContent,t.success=!0,t.linesAdded=n.linesAdded,t.insertionPoint=n.insertionPoint,o+=n.linesAdded}catch(e){t.error=(0,
|
|
3353
|
+
default:throw Error("Unknown insertion type: "+e.type)}r=n.newContent,t.success=!0,t.linesAdded=n.linesAdded,t.insertionPoint=n.insertionPoint,o+=n.linesAdded}catch(e){t.error=(0,f.getErrorMessage)(e)}n.push(t)}return{newContent:r,results:n}}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3355
3354
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3356
3355
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||(n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[]
|
|
3357
3356
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3372,7 +3371,7 @@ T.push({type:"file",path:r,fullPath:n,insertions:e.insertions})}const M=[]
|
|
|
3372
3371
|
if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3373
3372
|
for(const e of S)M.push({type:"document",documentId:e.documentId,insertions:e.insertions})
|
|
3374
3373
|
if(M.length>0&&t.apiClient){const e=M.map((e=>e.documentId))
|
|
3375
|
-
try{await(0,
|
|
3374
|
+
try{await(0,p.ensureDocumentsNotLocked)(e,t.apiClient,y,a,"insert-lines-documents")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3376
3375
|
throw e}}I=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("insert_lines_phase",1,{phase:I})
|
|
3377
3376
|
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
3377
|
let O=null
|
|
@@ -3394,31 +3393,31 @@ let N=0,L=0,z=0
|
|
|
3394
3393
|
for(const e of T){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3395
3394
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3396
3395
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.insertions)
|
|
3397
|
-
t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,z++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),N+=t.failedInsertions,L+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3396
|
+
t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,z++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),N+=t.failedInsertions,L+=t.totalLinesAdded}catch(r){t.error=(0,f.getErrorMessage)(r),t.failedInsertions=e.insertions.length,N+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}F.push(t)}for(const e of M){const n={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3398
3397
|
try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3399
3398
|
n.filename=s?.filename
|
|
3400
3399
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
|
|
3401
|
-
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,
|
|
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:b,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),H=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:
|
|
3403
|
-
try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+M[0]?.documentId,status:V?"completed":"failed",error:V?void 0:
|
|
3404
|
-
if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${W
|
|
3400
|
+
n.insertions=l,n.successfulInsertions=l.filter((e=>e.success)).length,n.failedInsertions=l.filter((e=>!e.success)).length,n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulInsertions>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,z++,y.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulInsertions:n.successfulInsertions,failedInsertions:n.failedInsertions,linesAdded:n.totalLinesAdded})):0===n.failedInsertions&&(n.success=!0),N+=n.failedInsertions,L+=n.totalLinesAdded}catch(t){n.error=(0,f.getErrorMessage)(t),n.failedInsertions=e.insertions.length,N+=n.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:n.error})}F.push(n)}if(M.length>0)try{for(const e of M){const r=F.find((t=>t.documentId===e.documentId))
|
|
3401
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const B=await d.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:b,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),H=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:U,failedOperations:W,totalSuccessfulChanges:G,overallSuccess:V,successfulFiles:J,failedFiles:K}=H
|
|
3402
|
+
try{await o.updateToolRecord(b,{metadata:{path:T.length>0?T[0].path:"document:"+M[0]?.documentId,status:V?"completed":"failed",error:V?void 0:W+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:D,totalSuccessfulInsertions:G,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:E,...T.length>0&&B.success&&B.commitHash&&{commitHash:B.commitHash,previousCommitHash:B.previousCommitHash||void 0}},note:V?`Line insertion completed: ${U}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${W}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
|
|
3403
|
+
if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${U+W}\n`,Y+=`- **Successful operations:** ${U}\n`,Y+=`- **Failed operations:** ${W}\n`,Y+=`- **Total insertions:** ${G} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n`,Y+="\n",B.success&&B.commitHash&&(Y+="**Git Commit:**\n",Y+=`- **Commit Hash:** ${B.commitHash.substring(0,8)}\n`,Y+=`- **Files Committed:** ${B.filesCommitted.length}\n`,B.previousCommitHash&&(Y+=`- **Previous Commit:** ${B.previousCommitHash.substring(0,8)}\n`),Y+="\n"),$.lockAcquired&&$.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${$.lockedRequestId}\n\n`),1===F.length){const e=F[0]
|
|
3405
3404
|
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
3405
|
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}`
|
|
3407
|
-
Y+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{Y+="**Summary:**\n",Y+=`- **Total Operations:** ${F.length}\n`,Y+=`- **Successful:** ${
|
|
3406
|
+
Y+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{Y+="**Summary:**\n",Y+=`- **Total Operations:** ${F.length}\n`,Y+=`- **Successful:** ${U}\n`,Y+=`- **Failed:** ${W}\n`,Y+=`- **Total Insertions:** ${G} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n\n`,Y+="**Detailed Results:**\n\n"
|
|
3408
3407
|
for(const e of F){if("file"===e.type?Y+=`### File: ${e.path}\n`:(Y+="### Document: "+e.documentId,e.filename&&(Y+=` (${e.filename})`),Y+="\n"),Y+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error?Y+=`- **Error:** ${e.error}\n`:(Y+=`- **Insertions:** ${e.successfulInsertions} successful`,e.failedInsertions>0&&(Y+=`, ${e.failedInsertions} failed`),Y+="\n",Y+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.insertions.some((e=>!e.success))){Y+="- **Failed Insertion Details:**\n"
|
|
3409
3408
|
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
3409
|
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
3410
|
const Q=Date.now()-w
|
|
3412
|
-
return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:
|
|
3413
|
-
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:I}),b)try{await o.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,
|
|
3414
|
-
const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),
|
|
3415
|
-
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),
|
|
3411
|
+
return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:U,failedOperations:W}),a.incrementCounter("insert_lines_total",1,{success:V}),{content:[{type:"text",text:Y}],isError:!V}}catch(t){const r=Date.now()-w
|
|
3412
|
+
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:I}),b)try{await o.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,f.getErrorMessage)(t),phase:I,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("insert_lines_errors",1,{phase:I}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
|
|
3413
|
+
const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824),m=t(3255)},6539(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
|
|
3414
|
+
const r=t(1253),n=t(5681),o=t(6595),s=t(3895),i=t(6848),a=t(6153),c=t(4710),l=t(6975),d=t(1887),u=t(1666),h=t(8824),g=t(9884),p=t(2968),f=t(922)
|
|
3416
3415
|
exports.ClientFactory=class{static async createClient(e,m,y,w={}){(m=m.child({component:"client-factory"})).info("Creating API client with components")
|
|
3417
3416
|
const k=w.tokenManager||new r.TokenManager(m,w.workingDir||process.cwd())
|
|
3418
3417
|
await k.initialize()
|
|
3419
3418
|
const b=w.tokenSynchronizer||new i.ClientTokenSynchronizer(m),I=new s.AuthenticationManager(k,m,b),v=await I.getTokenString(),C=w.connectionStatusManager||new n.ConnectionStatusManager(e,m,y,{alchemyPath:w.alchemyPath,checkIntervalMs:w.offlineCheckIntervalMs,timeoutMs:w.timeout,retryCount:w.retryAttempts}),_=new c.ProjectClient(e,m,y,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3420
3419
|
b.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3421
|
-
const E=new
|
|
3420
|
+
const E=new p.TaskClient(e,m,y,_,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3422
3421
|
b.registerClient(E)
|
|
3423
3422
|
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
3423
|
b.registerClient(q),m.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
@@ -3426,7 +3425,7 @@ const S=new u.RequestClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts
|
|
|
3426
3425
|
b.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
|
|
3427
3426
|
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
3427
|
b.registerClient(T)
|
|
3429
|
-
const M=new
|
|
3428
|
+
const M=new f.ToolRecordClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3430
3429
|
b.registerClient(M)
|
|
3431
3430
|
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
3431
|
if(b.registerClient(R),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
|
|
@@ -3444,7 +3443,7 @@ if(E)try{await E.connectStdio(),(0,a.isDebugToolsEnabled)()&&b.info("Connected s
|
|
|
3444
3443
|
throw b.error("Failed to connect stdio transport",{errorDetails:t}),e}else b.error("No global server instance available to connect transport")
|
|
3445
3444
|
return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3446
3445
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
3447
|
-
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),
|
|
3446
|
+
const o=t(5802),s=n(t(6928)),i=t(184),a=t(3444),c=t(1152),l=t(8851),d=t(8411),u=n(t(9896)),h=t(4139),g=t(5218),p=t(8824),f=t(9939),m=t(7960),y=process.argv.slice(2),w=y[0]||process.cwd(),k=s.default.resolve(w)
|
|
3448
3447
|
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
3448
|
const b=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:k});(0,a.isDebugToolsEnabled)()?b.info("MCP Direct server initializing",{baseDir:k,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):b.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(b.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),E)try{E.cleanupSSEConnection()}catch(e){b.error("Error during cleanup after uncaught exception: "+e)}setTimeout((()=>process.exit(1)),500)})),process.on("unhandledRejection",(e=>{b.error("UNHANDLED REJECTION: "+e,{stack:e instanceof Error?e.stack:"No stack available"})})),process.on("exit",(e=>{b.info("Process exiting with code: "+e)}))
|
|
3450
3449
|
const I=process.stdout.write
|
|
@@ -3456,7 +3455,7 @@ const _=global.__serverInitialized
|
|
|
3456
3455
|
void 0===_?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&b.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&b.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
|
|
3457
3456
|
let E=null
|
|
3458
3457
|
const q=(0,g.isMultiAgentModeEnabled)(k)
|
|
3459
|
-
try{(0,d.acquireProcessLock)(k,q)||(b.error(`Process lock acquisition failed for ${k}. Another instance may be running.`),b.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&(q?b.info("Multi-agent mode enabled - allowing concurrent access to "+k):b.info("Successfully acquired process lock for "+k))}catch(e){b.error("Lock acquisition threw exception",{error:(0,
|
|
3458
|
+
try{(0,d.acquireProcessLock)(k,q)||(b.error(`Process lock acquisition failed for ${k}. Another instance may be running.`),b.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&(q?b.info("Multi-agent mode enabled - allowing concurrent access to "+k):b.info("Successfully acquired process lock for "+k))}catch(e){b.error("Lock acquisition threw exception",{error:(0,p.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),b.error("Cannot continue without lock in single-agent mode"),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(b.info("============================================================"),b.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),b.info("BASE DIR: "+k),b.info("ALCHEMY PATH: "+s.default.join(k,h.ALCHEMY_DIR_NAME)),b.info("PROJECT PATH: "+s.default.join(k,h.ALCHEMY_DIR_NAME+"/project.json")),b.info("MULTI-AGENT MODE: "+q),b.info("MCP client information will be captured during protocol initialization")),b.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(b.info("============================================================"),b.info("Base directory: "+k),b.info("Remote server URL: "+C),b.info("Node version: "+process.version),b.info("Current working directory: "+process.cwd()),b.info("ALLOWED_DIRECTORIES env var: not used (single working directory mode)"),b.info("Server already initialized: "+(_?"YES":"NO"))),_&&((0,a.isDebugToolsEnabled)()&&(b.info("Server already initialized globally, reusing existing server instance"),b.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3460
3459
|
b.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
|
|
3461
3460
|
try{const e=u.default.existsSync(k)
|
|
3462
3461
|
if((0,a.isDebugToolsEnabled)()&&b.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=u.default.statSync(k)
|
|
@@ -3464,7 +3463,7 @@ b.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(
|
|
|
3464
3463
|
if(!u.default.existsSync(S))try{u.default.mkdirSync(S,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&b.info("Created alchemy lab directory: "+S)}catch(e){b.error("Failed to create alchemy lab directory: "+e)}try{(async function(){try{C=await async function(){if(process.env.REMOTE_SERVER_URL)return process.env.REMOTE_SERVER_URL
|
|
3465
3464
|
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(b),n=await r.getInstallationConfig()
|
|
3466
3465
|
if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&b.info("Loaded REMOTE_SERVER_URL from installation config",{remoteServerUrl:n.remoteServerUrl}),n.remoteServerUrl}catch(e){(0,a.isDebugToolsEnabled)()&&b.debug("Could not read REMOTE_SERVER_URL from installation config",{error:e instanceof Error?e.message:"Unknown error"})}return"https://api.alchemylabcode.com"}()
|
|
3467
|
-
try{const e=await(0,
|
|
3466
|
+
try{const e=await(0,f.syncPlugins)(k,(0,m.isDevBuild)(),b)
|
|
3468
3467
|
e.synced.length>0&&b.info("Synced plugins on startup",{synced:e.synced}),e.errors.length>0&&b.warn("Some plugins failed to sync",{errors:e.errors})}catch(e){b.warn("Plugin sync failed",{error:e instanceof Error?e.message:"Unknown error"})}(0,a.isDebugToolsEnabled)()&&(b.info("Creating MCP server with base dir: "+k),b.info("Using remote server URL: "+C))
|
|
3469
3468
|
const e=await(0,i.createServer)(k,b,v,C,{multiAgentMode:(0,g.isMultiAgentModeEnabled)(k)})
|
|
3470
3469
|
E=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&b.info("MCP server created successfully")
|
|
@@ -3499,7 +3498,7 @@ const n=[],o=[...t].sort(((e,t)=>{const r=e=>"number"==typeof e?e:Array.isArray(
|
|
|
3499
3498
|
return r(t.lines)-r(e.lines)}))
|
|
3500
3499
|
for(const e of o){const t={lines:e.lines,success:!1}
|
|
3501
3500
|
try{const n=(0,m.replaceLines)(r,e.lines,e.content)
|
|
3502
|
-
r=n.newContent,t.success=!0,t.linesReplaced=n.linesReplaced,t.linesAdded=n.linesAdded,t.startLine=n.startLine,t.endLine=n.endLine}catch(e){t.error=(0,
|
|
3501
|
+
r=n.newContent,t.success=!0,t.linesReplaced=n.linesReplaced,t.linesAdded=n.linesAdded,t.startLine=n.startLine,t.endLine=n.endLine}catch(e){t.error=(0,f.getErrorMessage)(e)}n.push(t)}return{newContent:r,results:n}}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3503
3502
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3504
3503
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||(n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[]
|
|
3505
3504
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3520,7 +3519,7 @@ M.push({type:"file",path:r,fullPath:n,replacements:e.replacements.map((e=>({line
|
|
|
3520
3519
|
if(T.length>0&&!t.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3521
3520
|
for(const e of T)R.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,y.parseLineSpec)(e.lines),content:e.content})))})
|
|
3522
3521
|
if(R.length>0&&t.apiClient){const e=R.map((e=>e.documentId))
|
|
3523
|
-
try{await(0,
|
|
3522
|
+
try{await(0,p.ensureDocumentsNotLocked)(e,t.apiClient,w,a,"replace-lines-documents")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3524
3523
|
throw e}}v=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3525
3524
|
const P=M.length>0?M[0].path:"document-operation",x=await d.validateTaskId(_,P,n,w,a,C.metricsPrefix),O=x?.requestId
|
|
3526
3525
|
let j=null
|
|
@@ -3542,38 +3541,38 @@ let L=0,z=0,B=0,H=0
|
|
|
3542
3541
|
for(const e of M){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3543
3542
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3544
3543
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.replacements)
|
|
3545
|
-
t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,t.totalLinesReplaced=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulReplacements>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,H++,w.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),L+=t.failedReplacements,z+=t.totalLinesReplaced,B+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3544
|
+
t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,t.totalLinesReplaced=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulReplacements>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,H++,w.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),L+=t.failedReplacements,z+=t.totalLinesReplaced,B+=t.totalLinesAdded}catch(r){t.error=(0,f.getErrorMessage)(r),t.failedReplacements=e.replacements.length,L+=t.failedReplacements,w.error("File operation failed",{path:e.path,error:t.error})}N.push(t)}for(const e of R){const n={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3546
3545
|
try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3547
3546
|
n.filename=s?.filename
|
|
3548
3547
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
|
|
3549
|
-
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,
|
|
3550
|
-
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const
|
|
3551
|
-
try{await o.updateToolRecord(I,{metadata:{path:M.length>0?M[0].path:"document:"+R[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:A,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-k,userComment:q,...M.length>0&&
|
|
3552
|
-
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",
|
|
3548
|
+
n.replacements=l,n.successfulReplacements=l.filter((e=>e.success)).length,n.failedReplacements=l.filter((e=>!e.success)).length,n.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,H++,w.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulReplacements:n.successfulReplacements,failedReplacements:n.failedReplacements,linesReplaced:n.totalLinesReplaced,linesAdded:n.totalLinesAdded})):0===n.failedReplacements&&(n.success=!0),L+=n.failedReplacements,z+=n.totalLinesReplaced,B+=n.totalLinesAdded}catch(t){n.error=(0,f.getErrorMessage)(t),n.failedReplacements=e.replacements.length,L+=n.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:n.error})}N.push(n)}if(R.length>0)try{for(const e of R){const r=N.find((t=>t.documentId===e.documentId))
|
|
3549
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const U=await d.handleMultiFileGitCommit(_,M,N,H,{operationType:"Replace lines",toolRecordId:I,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),W=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=W
|
|
3550
|
+
try{await o.updateToolRecord(I,{metadata:{path:M.length>0?M[0].path:"document:"+R[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:A,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-k,userComment:q,...M.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:K?`Line replacement completed: ${G}/${N.length} operations successful${M.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${V}/${N.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z="## Line Replacement Results\n\n"
|
|
3551
|
+
if(t.workspaceManager&&(Z+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Z+="**Summary:**\n",Z+=`- **Files processed:** ${G+V}\n`,Z+=`- **Successful operations:** ${G}\n`,Z+=`- **Failed operations:** ${V}\n`,Z+=`- **Total replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,B>0&&(Z+=`- **Total Lines Added:** ${B}\n`),Z+="\n",U.success&&U.commitHash&&(Z+="**Git Commit:**\n",Z+=`- **Commit Hash:** ${U.commitHash.substring(0,8)}\n`,Z+=`- **Files Committed:** ${U.filesCommitted.length}\n`,U.previousCommitHash&&(Z+=`- **Previous Commit:** ${U.previousCommitHash.substring(0,8)}\n`),Z+="\n"),D.lockAcquired&&D.lockedRequestId&&(Z+=`\u{1f512} **Locked request:** ${D.lockedRequestId}\n\n`),1===N.length){const e=N[0]
|
|
3553
3552
|
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
3553
|
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"
|
|
3555
3554
|
for(const e of N){if("file"===e.type?Z+=`### File: ${e.path}\n`:(Z+="### Document: "+e.documentId,e.filename&&(Z+=` (${e.filename})`),Z+="\n"),Z+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error&&(Z+=`- **Error:** ${e.error}\n`),Z+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(Z+=`, ${e.failedReplacements} failed`),Z+="\n",Z+=`- **Lines Replaced:** ${e.totalLinesReplaced}\n`,e.totalLinesAdded>0&&(Z+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.replacements.some((e=>!e.success))){Z+="- **Failed Replacement Details:**\n"
|
|
3556
3555
|
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
3556
|
const X=Date.now()-k
|
|
3558
3557
|
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}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,
|
|
3560
|
-
const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),
|
|
3558
|
+
if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,f.getErrorMessage)(t),phase:v,duration:r,userComment:e?.comment},note:"Line replacement failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_lines_errors",1,{phase:v}),{content:[{type:"text",text:"\u274c **Replace Lines Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
|
|
3559
|
+
const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824),m=t(3255),y=t(9470)},6688(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
|
|
3561
3560
|
const r=t(9896),n=t(6928)
|
|
3562
|
-
exports.sessionIdentity=new class{constructor(){this.
|
|
3561
|
+
exports.sessionIdentity=new class{constructor(){this.parentCache=new Map}setIdentity(e){const t=this.identity
|
|
3563
3562
|
this.identity=e,this.log("setIdentity",{sessionId:e.sessionId,serverUrl:e.serverUrl,agentType:e.agentType||null,prevSessionId:t?.sessionId||null,changed:t?.sessionId!==e.sessionId})}getIdentity(){return this.identity}updateIdentity(e){if(this.identity){const t={...this.identity}
|
|
3564
|
-
this.identity={...this.identity,...e},this.log("updateIdentity",{sessionId:this.identity.sessionId,updates:Object.keys(e),agentTypeBefore:t.agentType||null,agentTypeAfter:this.identity.agentType||null})}}
|
|
3565
|
-
this.identity=void 0,this.discoveryAttempted=!1,this.log("reset",{prevSessionId:e?.sessionId||null,prevAgentType:e?.agentType||null})}hasDiscoveryBeenAttempted(){return this.discoveryAttempted}markDiscoveryAttempted(){this.discoveryAttempted=!0}async getParentSessionId(e,t,r){if(this.parentCache.has(e)){const t=this.parentCache.get(e)
|
|
3563
|
+
this.identity={...this.identity,...e},this.log("updateIdentity",{sessionId:this.identity.sessionId,updates:Object.keys(e),agentTypeBefore:t.agentType||null,agentTypeAfter:this.identity.agentType||null})}}async getParentSessionId(e,t,r){if(this.parentCache.has(e)){const t=this.parentCache.get(e)
|
|
3566
3564
|
return this.log("getParentSessionId.cache-hit",{childExternalId:e,parentExternalId:t}),t}try{const n=t.getCLISessionClient()
|
|
3567
3565
|
if(!n)return r.warn("CLI session client not available"),null
|
|
3568
3566
|
const o=await n.getParent(e),s=o?.externalSessionId||null
|
|
3569
3567
|
return this.parentCache.set(e,s),this.log("getParentSessionId.resolved",{childExternalId:e,parentExternalId:s}),s||r.warn("Parent session not found",{sessionId:e}),s}catch(t){const n=t instanceof Error?t.message:t+""
|
|
3570
|
-
return r.warn("Error getting parent session",{sessionId:e,error:n}),null}}setParentSessionId(e,t){this.parentCache.set(e,t)}async getSessionRequestId(e,t){
|
|
3568
|
+
return r.warn("Error getting parent session",{sessionId:e,error:n}),null}}setParentSessionId(e,t){this.parentCache.set(e,t)}async getSessionRequestId(e,t,r){const n=r||this.identity?.sessionId
|
|
3569
|
+
if(!n)return t.warn("Cannot get session request: no session identity"),null
|
|
3571
3570
|
try{const r=e.getSessionRequestAssociationClient?.()
|
|
3572
3571
|
if(!r)return t.warn("Session request association client not available"),null
|
|
3573
|
-
const
|
|
3574
|
-
if(
|
|
3575
|
-
return this.log("getSessionRequestId.resolved",{sessionId:
|
|
3576
|
-
return t.warn("Error getting session request",{sessionId:
|
|
3572
|
+
const o=await r.getActiveRequestsForSession(n)
|
|
3573
|
+
if(o?.length>0){const e=o[0].requestLocalId||o[0].request_local_id
|
|
3574
|
+
return this.log("getSessionRequestId.resolved",{sessionId:n,requestId:e}),e||null}return this.log("getSessionRequestId.none",{sessionId:n}),null}catch(e){const r=e instanceof Error?e.message:e+""
|
|
3575
|
+
return t.warn("Error getting session request",{sessionId:n,error:r}),null}}buildCliOrigin(e){if(this.identity)return{providerId:this.identity.providerId,sessionId:this.identity.sessionId,messageId:e,createdAt:(new Date).toISOString()}}setCurrentCallOrigin(e){this.currentCallOrigin=e}getCurrentCallOrigin(){return this.currentCallOrigin||this.buildCliOrigin()}log(e,t){try{const o=process.env.ALCHEMY_PROJECT_PATH||process.cwd(),s=(0,n.join)(o,".alchemy_lab");(0,r.existsSync)(s)||(0,r.mkdirSync)(s,{recursive:!0})
|
|
3577
3576
|
const i=(0,n.join)(s,"mcp-identity-debug.log"),a=(new Date).toISOString(),c=process.pid,l=t?" "+JSON.stringify(t):"";(0,r.appendFileSync)(i,`[${a}] [PID:${c}] identity.${e}${l}\n`)}catch{}}},exports.sessionIdentity.log("module-load",{ALCHEMY_SESSION_TAG:process.env.ALCHEMY_SESSION_TAG||null,ALCHEMY_INITIAL_BRANCH:process.env.ALCHEMY_INITIAL_BRANCH||null,ALCHEMY_ALLOW_PARALLEL:process.env.ALCHEMY_ALLOW_PARALLEL||null})},6756(e,exports){var t,r
|
|
3578
3577
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.TaskStatus=exports.RequestStatus=void 0,function(e){e.OPEN="open",e.IN_PROGRESS="in_progress",e.COMPLETED="completed",e.CONFLICTED="conflicted",e.READY_FOR_REVIEW="ready_for_review",e.PENDING_APPROVAL="pending_approval"}(t||(exports.RequestStatus=t={})),function(e){e.PENDING="pending",e.IN_PROGRESS="in_progress",e.READY_FOR_REVIEW="ready_for_review",e.COMPLETED="completed"}(r||(exports.TaskStatus=r={}))},6770(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3579
3578
|
const r=t(6183),n=t(6651)
|
|
@@ -3604,14 +3603,14 @@ var t={}
|
|
|
3604
3603
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3605
3604
|
return o(t,e),t})
|
|
3606
3605
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTaskFileHistory=async function(e,t,r,n,o){const s=n.child({tool:"task_file_history"}),h=o.startTimer("tool_execution_time")
|
|
3607
|
-
try{const{taskId:g,showDiff:
|
|
3606
|
+
try{const{taskId:g,showDiff:p=!1}=e
|
|
3608
3607
|
if(!g)throw(0,i.createValidationError)("Task ID is required")
|
|
3609
3608
|
if(!/^tas\d{6}$/.test(g))throw(0,i.createValidationError)(`Invalid task ID format: ${g}. Expected format: tas######`)
|
|
3610
|
-
s.info("Getting file changes for task "+g,{showDiff:
|
|
3611
|
-
const
|
|
3609
|
+
s.info("Getting file changes for task "+g,{showDiff:p})
|
|
3610
|
+
const f=r.getTaskClient(),m=r.getToolRecordClient(),y=t.projectId
|
|
3612
3611
|
let w
|
|
3613
3612
|
r.setProjectId(y)
|
|
3614
|
-
try{const M=await
|
|
3613
|
+
try{const M=await f.getTask(g)
|
|
3615
3614
|
s.info("Raw task response data",{responseDataType:typeof M,isArray:Array.isArray(M),hasData:null!=M,properties:M&&"object"==typeof M?Object.keys(M):[]}),w=(0,l.extractDataFromResponse)(M,{logger:s,operationName:"getTask",defaultValue:{id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+w.title)}catch(R){s.warn("Could not fetch task information: "+(0,u.getErrorMessage)(R)),w={id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let k=[]
|
|
3616
3615
|
try{const P=await m.getToolRecordsByTaskId(g)
|
|
3617
3616
|
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={}
|
|
@@ -3681,36 +3680,36 @@ re&&re.trim().length>0?(ee=re.split("\n").map((e=>"+"+e)).join("\n"),_.set(A,{fi
|
|
|
3681
3680
|
ee=await t.git.diff(oe),_.set(A,{firstChange:Q,lastChange:Z,hasDiff:!(!ee||0>=ee.trim().length),diffText:ee||"No changes detected in git diff"})}}catch(se){s.warn("Error generating diff for "+A,{error:se instanceof Error?se.message:se+""}),_.set(A,{firstChange:Q,lastChange:Z,hasDiff:!0,diffText:"Error generating diff, but git history is available"})}continue}}else s.info("No git history found for "+A)}}catch(ie){s.warn("Error getting git history for "+A,{error:(0,u.getErrorMessage)(ie)})}_.set(A,{firstChange:F[0],lastChange:F[F.length-1],hasDiff:!1,diffText:"No commit hashes available for this file"})
|
|
3682
3681
|
continue}const z=L[0],B=L[L.length-1]
|
|
3683
3682
|
s.info(`First commit: ${z.commitHash?z.commitHash:"unknown"}, Last commit: ${B.commitHash?B.commitHash:"unknown"}`)
|
|
3684
|
-
let H=null,
|
|
3685
|
-
if(t.git&&z.commitHash)try{H=await(0,c.findPreviousCommit)(t.git,A,z.commitHash),H?(
|
|
3686
|
-
if(s.info(`Using ${
|
|
3683
|
+
let H=null,U=!1
|
|
3684
|
+
if(t.git&&z.commitHash)try{H=await(0,c.findPreviousCommit)(t.git,A,z.commitHash),H?(U=!0,s.info(`Found previous commit: ${H} for ${A}`)):s.info(`No previous commit found for ${A}, likely a new file`)}catch(ae){s.warn("Error finding previous commit for "+A,{error:(0,u.getErrorMessage)(ae)})}const W=U&&H?{...z,commitHash:H,status:"pre-task"}:z
|
|
3685
|
+
if(s.info(`Using ${U?"pre-task":"first task"} commit as baseline for ${A}: ${W.commitHash}`),s.info(`Last commit for ${A}: ${B.commitHash}`),s.info("Commits are "+(W.commitHash===B.commitHash?"identical":"different")),z.commitHash===B.commitHash&&!U){if(p&&!U&&t.git&&B.commitHash)try{const ce=[`${B.commitHash}:${A}`]
|
|
3687
3686
|
s.info(`Getting new file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${A}`)
|
|
3688
3687
|
const le=await t.git.show(ce)
|
|
3689
3688
|
if(le&&le.trim().length>0){let de=""
|
|
3690
3689
|
const ue=le.split("\n")
|
|
3691
3690
|
for(const he of ue)de+=`+${he}\n`
|
|
3692
|
-
_.set(A,{firstChange:
|
|
3693
|
-
continue}}catch(ge){s.warn("Error getting new file content for "+A,{error:(0,u.getErrorMessage)(ge)})}_.set(A,{firstChange:
|
|
3694
|
-
continue}if(z.commitHash===B.commitHash&&
|
|
3691
|
+
_.set(A,{firstChange:W,lastChange:B,hasDiff:!0,diffText:de}),s.info(`Formatted new file content as diff, ${ue.length} lines`)
|
|
3692
|
+
continue}}catch(ge){s.warn("Error getting new file content for "+A,{error:(0,u.getErrorMessage)(ge)})}_.set(A,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"Only one commit available for this file"})
|
|
3693
|
+
continue}if(z.commitHash===B.commitHash&&U){if(H===z.commitHash){_.set(A,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"No changes detected"})
|
|
3695
3694
|
continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let G="",V=!1
|
|
3696
|
-
if(
|
|
3697
|
-
continue}let
|
|
3698
|
-
if("pre-task"===
|
|
3699
|
-
try{const me=await t.git.show([`${
|
|
3700
|
-
if(me!==ye&&(V=!0,G="Changes detected through direct content comparison (not visible in standard diff)",
|
|
3695
|
+
if(p||"pre-task"!==W.status){try{if(t.git){try{await t.git.show([`${B.commitHash}:${A}`])}catch(fe){s.warn(`File ${A} does not exist in commit ${B.commitHash}, might be deleted or moved`),G="File was deleted or moved from this location during the task",V=!0,_.set(A,{firstChange:W,lastChange:B,hasDiff:V,diffText:G})
|
|
3696
|
+
continue}let pe
|
|
3697
|
+
if("pre-task"===W.status?(pe=[`${W.commitHash}..${B.commitHash}`,"--",A],s.info(`Comparing pre-task commit with final commit: ${W.commitHash?W.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${A}`)):(pe=["4b825dc642cb6eb9a060e54bf8d69288fbee4904.."+B.commitHash,"--",A],s.info(`File created during task, showing full file diff using empty tree object: ${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${A}`)),G=await t.git.diff(pe),V=!!G&&G.trim().length>0,!V&&W.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
|
|
3698
|
+
try{const me=await t.git.show([`${W.commitHash}:${A}`]),ye=await t.git.show([`${B.commitHash}:${A}`])
|
|
3699
|
+
if(me!==ye&&(V=!0,G="Changes detected through direct content comparison (not visible in standard diff)",p)){const we=me.split("\n"),ke=ye.split("\n")
|
|
3701
3700
|
Math.abs(we.length-ke.length)>0&&(G+=`\n\nLine count changed: ${we.length} \u2192 ${ke.length}`),me.includes("\0")||ye.includes("\0")?G+="\n\nBinary content detected - changes not displayed":me.replace(/\s+/g,"")===ye.replace(/\s+/g,"")&&(G+="\n\nWhitespace-only changes detected")}}catch(be){s.warn("Error in direct file comparison: "+(be instanceof Error?be.message:be+""))}}s.info(`Diff generation result for ${A}: hasDiff=${V}, length=${G.length}`)}}catch(Ie){if(s.warn("Error getting diff for "+A,{error:(0,u.getErrorMessage)(Ie),firstCommit:z.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),G="Error getting diff: "+(0,u.getErrorMessage)(Ie),"pre-task"!==z.status&&t.git)try{const ve=[`${B.commitHash}:${A}`]
|
|
3702
3701
|
s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${A}`)
|
|
3703
3702
|
const Ce=await t.git.show(ve)
|
|
3704
|
-
if(Ce&&Ce.trim().length>0){if(
|
|
3703
|
+
if(Ce&&Ce.trim().length>0){if(p){let _e=""
|
|
3705
3704
|
const Ee=Ce.split("\n")
|
|
3706
3705
|
for(const qe of Ee)_e+=`+${qe}\n`
|
|
3707
3706
|
G=_e}else G="File created during this task. Content:\n"+Ce
|
|
3708
|
-
V=!0,s.info("Fallback succeeded, got file content of length "+Ce.length)}}catch(Se){s.warn("Fallback also failed for "+A,{error:Se instanceof Error?Se.message:Se+""})}}_.set(A,{firstChange:
|
|
3707
|
+
V=!0,s.info("Fallback succeeded, got file content of length "+Ce.length)}}catch(Se){s.warn("Fallback also failed for "+A,{error:Se instanceof Error?Se.message:Se+""})}}_.set(A,{firstChange:W,lastChange:B,hasDiff:V,diffText:G||"No changes detected between commits"})}else V=W.commitHash!==B.commitHash,G=V?"File has changes":"No changes detected between commits",_.set(A,{firstChange:W,lastChange:B,hasDiff:V,diffText:G})}let E=`# File Changes for Task: ${g}\n\n`
|
|
3709
3708
|
w&&"object"==typeof w&&(E+="## Task Information\n",E+=`- **Title**: ${w.title||"Unknown"}\n`,E+=`- **Status**: ${w.status||"Unknown"}\n`,E+=`- **Description**: ${w.description||"No description"}\n\n`)
|
|
3710
3709
|
const q=3e3
|
|
3711
3710
|
let S=0,T=!1
|
|
3712
|
-
if(
|
|
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**: ${
|
|
3711
|
+
if(p){for(const Te of _.values())Te.hasDiff&&Te.diffText&&(S+=Te.diffText.split("\n").length)
|
|
3712
|
+
T=S>q,s.info(`Total diff size: ${S} lines (limit: ${q} lines)`),s.info(`Diffs ${T?"will be limited":"will be shown"} based on size`)}if(E+="## Summary\n",E+=`- **Files Modified**: ${C.size}\n`,E+=`- **Total File Operations**: ${v.length}\n`,E+="- **What's Shown**: For existing files, comparing state before task started with final state.\n",E+=" For files created during task, showing the entire file as created.\n",T?(E+=`- **Diff Display**: Limited (total diff size of ${S} lines exceeds limit of ${q} lines)\n`,E+=" Use file-history tool with individual files to see detailed changes\n\n"):E+=`- **Diff Display**: ${p?"Enabled":"Disabled"} (use showDiff=${!p} to ${p?"hide":"show"} diffs)\n\n`,I.allMoves.length>0){E+="## Move Operations\n\n",E+=`Detected ${I.allMoves.length} file move operation(s):\n\n`
|
|
3714
3713
|
for(const Me of I.allMoves)E+=`- **${Me.source}** \u2192 **${Me.destination}**\n`,E+=` - Operation: ${Me.type}\n`,E+=` - Timestamp: ${new Date(Me.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Me.recordId}\n\n`}E+="## Modified Files\n\n"
|
|
3715
3714
|
for(const[Re,Pe]of _.entries()){const{normalizedPath:xe,fullPath:Oe}=d.validateAndNormalizePath(Re,t)
|
|
3716
3715
|
let je=!1
|
|
@@ -3718,7 +3717,7 @@ try{await a.access(Oe),je=!0}catch{}E+=`### ${Re} ${je?"":"(Deleted)"}\n\n`
|
|
|
3718
3717
|
const $e=new Date(Pe.firstChange.timestamp).toLocaleString(),De=new Date(Pe.lastChange.timestamp).toLocaleString()
|
|
3719
3718
|
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
3719
|
const Ae=I.sourceToMove.get(Re),Fe=I.destToMove.get(Re)
|
|
3721
|
-
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`),
|
|
3720
|
+
Ae?E+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Ae.destination}**\n`:Fe&&(E+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Fe.source}**\n`),p&&!T?Pe.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=Pe.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${Pe.diffText}\n\n`:T&&Pe.hasDiff?(E+=`\n**Note**: File has changes (${Pe.diffText?Pe.diffText.split("\n").length:0} lines). `,E+=`Compare ${Pe.firstChange.commitHash?Pe.firstChange.commitHash.substring(0,8):"unknown"}..${Pe.lastChange.commitHash?Pe.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Pe.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${Pe.diffText}\n\n`,E+="---\n\n"}return h({success:!0,fileCount:C.size}),{content:[{type:"text",text:E}]}}catch(Ne){return s.error("Error in task file history tool",{error:Ne instanceof Error?Ne.stack:Ne+""}),h({success:!1,error:Ne instanceof Error?Ne.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,u.getErrorMessage)(Ne)}],isError:!0}}}
|
|
3722
3721
|
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
3722
|
const r=t(1058)
|
|
3724
3723
|
exports.ProjectClientAdapter=class{constructor(e,t){this.client=e,this.logger=t.child({component:"project-client-adapter"}),this.logger.info("ProjectClientAdapter initialized")}isOnline(){return!this.client.isOffline()}async fetchProject(e){try{return this.logger.debug("ProjectClientAdapter.fetchProject called",{projectId:e}),await this.client.getProject(e)}catch(t){return this.logger.error("Error in ProjectClientAdapter.fetchProject",{projectId:e,error:t instanceof Error?t.stack:t+""}),null}}async createProject(e){try{this.logger.debug("ProjectClientAdapter.createProject called",{projectName:e.name,projectId:e.id}),this.logger.info("Creating project via adapter",{name:e.name,id:e.id,description:e.description?.substring(0,50)})
|
|
@@ -3840,42 +3839,42 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentit
|
|
|
3840
3839
|
i.existsSync(n)||i.mkdirSync(n,{recursive:!0})
|
|
3841
3840
|
const s=(new Date).toISOString(),c=Object.keys(r).length?" "+JSON.stringify(r):""
|
|
3842
3841
|
i.appendFileSync(o,`[${s}] ${e} | ${t}${c}\n`)}catch(e){}}
|
|
3843
|
-
const i=s(t(9896)),a=s(t(6928))},7334(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,l,d,u,h
|
|
3844
|
-
|
|
3845
|
-
const p=
|
|
3846
|
-
try{if(e&&"string"==typeof e.acceptanceCriteria)try{e.acceptanceCriteria=JSON.parse(e.acceptanceCriteria)}catch{}const
|
|
3842
|
+
const i=s(t(9896)),a=s(t(6928))},7334(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,c,l,d,u,h){const g=l.child({tool:"create_request"})
|
|
3843
|
+
g.info("Creating new request",{args:e})
|
|
3844
|
+
const p=d.startTimer("tool_handler_duration")
|
|
3845
|
+
try{if(e&&"string"==typeof e.acceptanceCriteria)try{e.acceptanceCriteria=JSON.parse(e.acceptanceCriteria)}catch{}const l=function(e){try{return r.CreateRequestSchema.parse(e)}catch(e){if(e instanceof s.ZodError&&e.errors.length>0)throw new n.ValidationError(e.errors[0].message)
|
|
3847
3846
|
throw new n.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
|
|
3848
|
-
|
|
3849
|
-
const
|
|
3850
|
-
if(!
|
|
3851
|
-
|
|
3852
|
-
const
|
|
3853
|
-
let
|
|
3854
|
-
try{const e=
|
|
3855
|
-
if(e){const t=
|
|
3847
|
+
d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
|
|
3848
|
+
const f=t.projectId
|
|
3849
|
+
if(!f)throw new n.ValidationError("Project ID is required for creating requests.")
|
|
3850
|
+
c.setProjectId(f)
|
|
3851
|
+
const m=c.getRequestClient()
|
|
3852
|
+
let y=(0,a.getApprovalMode)()
|
|
3853
|
+
try{const e=h?.sessionId
|
|
3854
|
+
if(e){const t=c.getCLISessionClient()
|
|
3856
3855
|
if(t){const r=await t.getByExternalId(e)
|
|
3857
|
-
if(r?.workflowId){const e=await
|
|
3858
|
-
t?.approvalMode&&(
|
|
3859
|
-
r&&(
|
|
3860
|
-
|
|
3861
|
-
const
|
|
3862
|
-
|
|
3863
|
-
const
|
|
3864
|
-
let _
|
|
3865
|
-
if(
|
|
3866
|
-
|
|
3867
|
-
try{const e=
|
|
3868
|
-
if(e){const t=await e.createToolRecord({requestId:
|
|
3869
|
-
|
|
3870
|
-
const
|
|
3871
|
-
let
|
|
3872
|
-
return
|
|
3873
|
-
else{const n=
|
|
3874
|
-
n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){
|
|
3856
|
+
if(r?.workflowId){const e=await c.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
|
|
3857
|
+
t?.approvalMode&&(y=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===y)try{const e=await c.proxyGet("/api/projects/"+f),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
|
|
3858
|
+
r&&(y=(0,a.getApprovalMode)(r))}catch(e){g.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){g.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const w="require-approval"===y&&"quick-edit"!==l.type?"pending_approval":"open",k={title:l.title,description:l.description,type:l.type,acceptanceCriteria:l.acceptanceCriteria,status:w,...l.planDocumentId&&{planDocumentId:l.planDocumentId},...h&&{cliOrigin:h}}
|
|
3859
|
+
g.info("Creating request via request client",{projectId:f,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
|
|
3860
|
+
const b=await m.createRequest(k)
|
|
3861
|
+
g.debug("Create request response structure",{type:typeof b,isArray:Array.isArray(b),hasData:null!=b,properties:b?Object.keys(b):[],dataPreview:b?JSON.stringify(b).substring(0,200)+"...":"null"})
|
|
3862
|
+
const I=(0,o.extractDataFromResponse)(b,{logger:g,operationName:"createRequest",throwOnNoData:!0}),v="data"in I?I.data:I
|
|
3863
|
+
let C,_={created:!1}
|
|
3864
|
+
if(u?.workspaceManager)try{await u.workspaceManager.initializeRequest(v.id,v.title),_={created:!0,branchName:"requests/"+v.id,message:"Branch created successfully"},g.info("Request branch initialized successfully",{requestId:v.id,branchName:_.branchName,title:v.title})}catch(e){g.warn("Failed to initialize request branch, will retry on first operation",{requestId:v.id,error:(0,i.getErrorMessage)(e)})}else"quick-edit"===l.type?g.info("Quick-edit request - skipping branch creation, will work directly on main",{requestId:v.id}):g.debug("No workspace manager available, branch creation deferred",{requestId:v.id})
|
|
3865
|
+
g.info("Request created successfully",{requestId:v.id,title:v.title,branchCreated:_.created,branchName:_.branchName})
|
|
3866
|
+
try{const e=c.getToolRecordClient()
|
|
3867
|
+
if(e){const t=await e.createToolRecord({requestId:v.id,projectId:f,type:"create-request",metadata:{status:"completed",timestamp:(new Date).toISOString(),requestType:v.type,requestTitle:v.title,requestDescription:v.description,criteriaCount:v.acceptanceCriteria.length,branchCreated:_.created,branchName:_.created?_.branchName:null},note:`Created request "${v.title}" of type ${v.type}${_.created?" with branch "+_.branchName:" - branch will be created on first file operation"}`})
|
|
3868
|
+
C=t?.id}}catch(e){g.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:v.id})}p({success:!0,type:l.type,hasProjectId:!0}),g.info("Request created successfully",{requestId:v.id,title:v.title,type:v.type,projectId:f})
|
|
3869
|
+
const E=v.localId||v.id
|
|
3870
|
+
let q="pending_approval"===w?`Created Request ${E} (pending approval)`:"Created Request "+E
|
|
3871
|
+
return C&&(q+=`\n[RECORD:${C}]`),{content:[{type:"text",text:q}]}}catch(r){if(g.error("Failed to create request",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new requests")||r.message.includes("disabled due to tier limits")))g.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
|
|
3872
|
+
else{const n=c.getToolRecordClient()
|
|
3873
|
+
n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){g.error("Failed to create failure record for request creation",{error:e instanceof Error?e.message:e+""})}if(p({success:!1,error:r instanceof Error?r.name:"unknown"}),r instanceof s.ZodError&&r.errors.length>0){const e=r.errors[0]
|
|
3875
3874
|
let t=e.message
|
|
3876
3875
|
return e.path.includes("acceptanceCriteria")&&(t=`Acceptance criteria: ${t}. Please provide a list of criteria descriptions.`),{content:[{type:"text",text:"Error: "+t}],isError:!0}}let n=(0,i.getErrorMessage)(r),o="Unable to create request. Please check your input and try again."
|
|
3877
3876
|
return(n.includes("Project cannot accept new requests")||n.includes("Project is inactive due to tier limits"))&&(o="This project is currently inactive due to tier limits. Only your oldest projects can accept new requests. Please use an active project or upgrade your tier for more simultaneous projects."),{content:[{type:"text",text:`Error: ${n}\n\n${o}`}],isError:!0}}}
|
|
3878
|
-
const r=t(6183),n=t(9860),o=t(2960),s=t(1569),i=t(8824),a=t(2478)
|
|
3877
|
+
const r=t(6183),n=t(9860),o=t(2960),s=t(1569),i=t(8824),a=t(2478)},7388(e,exports,t){var r=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3879
3878
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3880
3879
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),n=this&&this.__exportStar||function(e,exports){for(var t in e)"default"===t||{}.hasOwnProperty.call(exports,t)||r(exports,e,t)}
|
|
3881
3880
|
Object.defineProperty(exports,"__esModule",{value:!0}),n(t(441),exports),n(t(270),exports)},7456(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
@@ -3886,11 +3885,11 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3886
3885
|
var t={}
|
|
3887
3886
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3888
3887
|
return o(t,e),t})
|
|
3889
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,t,r,n,o,s,h,g){const
|
|
3890
|
-
try{const s=a.validateArgs(e,i.ModifyFileSchema),{taskId:u,operations:
|
|
3891
|
-
|
|
3888
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,t,r,n,o,s,h,g){const p=s.child({tool:"modify_file"})
|
|
3889
|
+
try{const s=a.validateArgs(e,i.ModifyFileSchema),{taskId:u,operations:f,comment:m}=s
|
|
3890
|
+
p.info("Processing modify-file operations",{taskId:u,operationCount:f.length,comment:m})
|
|
3892
3891
|
const y=[],w=[],k=[],b=[],I=[]
|
|
3893
|
-
for(const e of
|
|
3892
|
+
for(const e of f){const t={path:e.path,documentId:e.documentId}
|
|
3894
3893
|
switch(e.operationType){case"replace-string":y.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
|
|
3895
3894
|
break
|
|
3896
3895
|
case"insert-lines":w.push({...t,insertions:e.insertLines.insertions})
|
|
@@ -3900,40 +3899,40 @@ break
|
|
|
3900
3899
|
case"delete-string":b.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
|
|
3901
3900
|
break
|
|
3902
3901
|
case"delete-lines":I.push({...t,lines:e.deleteLines.lines})}}const v=[]
|
|
3903
|
-
if(y.length>0){
|
|
3904
|
-
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:y,comment:m+" [via modify-file: replace-string]"},t,r,n,o,
|
|
3905
|
-
v.push({type:"replace-string",result:e})}if(w.length>0){
|
|
3906
|
-
const e=await(0,l.handleInsertLines)({taskId:u,operations:w,comment:m+" [via modify-file: insert-lines]"},t,r,n,o,
|
|
3907
|
-
v.push({type:"insert-lines",result:e})}if(k.length>0){
|
|
3908
|
-
const e=await(0,d.handleReplaceLines)({taskId:u,operations:k,comment:m+" [via modify-file: replace-lines]"},t,r,n,o,
|
|
3909
|
-
v.push({type:"replace-lines",result:e})}if(b.length>0){
|
|
3910
|
-
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:b,comment:m+" [via modify-file: delete-string]"},t,r,n,o,
|
|
3911
|
-
v.push({type:"delete-string",result:e})}if(I.length>0){
|
|
3912
|
-
const e=I.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),s=await(0,d.handleReplaceLines)({taskId:u,operations:e,comment:m+" [via modify-file: delete-lines]"},t,r,n,o,
|
|
3902
|
+
if(y.length>0){p.info("Routing to replace-strings handler",{operationCount:y.length})
|
|
3903
|
+
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:y,comment:m+" [via modify-file: replace-string]"},t,r,n,o,p,h,g)
|
|
3904
|
+
v.push({type:"replace-string",result:e})}if(w.length>0){p.info("Routing to insert-lines handler",{operationCount:w.length})
|
|
3905
|
+
const e=await(0,l.handleInsertLines)({taskId:u,operations:w,comment:m+" [via modify-file: insert-lines]"},t,r,n,o,p,h,g)
|
|
3906
|
+
v.push({type:"insert-lines",result:e})}if(k.length>0){p.info("Routing to replace-lines handler",{operationCount:k.length})
|
|
3907
|
+
const e=await(0,d.handleReplaceLines)({taskId:u,operations:k,comment:m+" [via modify-file: replace-lines]"},t,r,n,o,p,h,g)
|
|
3908
|
+
v.push({type:"replace-lines",result:e})}if(b.length>0){p.info("Routing delete-string to replace-strings handler",{operationCount:b.length})
|
|
3909
|
+
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:b,comment:m+" [via modify-file: delete-string]"},t,r,n,o,p,h,g)
|
|
3910
|
+
v.push({type:"delete-string",result:e})}if(I.length>0){p.info("Processing delete-lines operations",{operationCount:I.length})
|
|
3911
|
+
const e=I.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),s=await(0,d.handleReplaceLines)({taskId:u,operations:e,comment:m+" [via modify-file: delete-lines]"},t,r,n,o,p,h,g)
|
|
3913
3912
|
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
3913
|
let q="## Modify File Results\n\n"
|
|
3915
3914
|
q+="**Summary:**\n",q+=`- **Total operation types:** ${v.length}\n`,q+=`- **Successful:** ${_}\n`,q+=`- **Failed:** ${E}\n\n`
|
|
3916
3915
|
for(const{type:e,result:t}of v)q+=`### ${e} operations\n`,q+=t.content[0].text+"\n\n"
|
|
3917
|
-
return
|
|
3916
|
+
return p.info("Modify-file operations completed",{totalOperationTypes:v.length,successCount:_,errorCount:E}),h.incrementCounter("modify_file_total",1,{success:!C}),{content:[{type:"text",text:q}],isError:C}}catch(e){return p.error("Modify-file operation failed",{error:e instanceof Error?e.stack:e+""}),h.incrementCounter("modify_file_errors",1),{content:[{type:"text",text:"\u274c **Modify File Failed:** "+(0,u.getErrorMessage)(e)}],isError:!0}}}
|
|
3918
3917
|
const i=t(6183),a=s(t(5967)),c=t(3306),l=t(6486),d=t(6651),u=t(8824)},7478(e,exports,t){async function r(e,t,r){const n=r.startTimer("git_get_current_branch_duration")
|
|
3919
3918
|
try{const o=(await e.status()).current
|
|
3920
3919
|
if(!o)throw new g.ValidationError("Repository is in detached HEAD state or branch detection failed")
|
|
3921
|
-
return t.debug("Retrieved current branch",{branch:o}),r.incrementCounter("git_get_current_branch_success",1),n({success:!0}),o}catch(e){const o=(0,
|
|
3920
|
+
return t.debug("Retrieved current branch",{branch:o}),r.incrementCounter("git_get_current_branch_success",1),n({success:!0}),o}catch(e){const o=(0,f.getErrorMessage)(e)
|
|
3922
3921
|
throw t.error("Failed to get current branch",{error:o}),r.incrementCounter("git_get_current_branch_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to get current branch: "+o)}}async function n(e,t,r,n){const o=n.startTimer("git_branch_exists_duration")
|
|
3923
3922
|
try{const s=(await e.branch(["-l"])).all.includes(t)
|
|
3924
|
-
return r.debug("Checked branch existence",{branchName:t,exists:s}),n.incrementCounter("git_branch_exists_check",1,{exists:s.toString()}),o({success:!0}),s}catch(e){const s=(0,
|
|
3923
|
+
return r.debug("Checked branch existence",{branchName:t,exists:s}),n.incrementCounter("git_branch_exists_check",1,{exists:s.toString()}),o({success:!0}),s}catch(e){const s=(0,f.getErrorMessage)(e)
|
|
3925
3924
|
return r.error("Failed to check branch existence",{branchName:t,error:s}),n.incrementCounter("git_branch_exists_failure",1),o({success:!1,error:e instanceof Error?e.name:"unknown"}),!1}}async function o(e,t,o,s){const i=s.startTimer("git_switch_branch_duration")
|
|
3926
3925
|
try{const a=await r(e,o,s)
|
|
3927
3926
|
if(a===t)return o.debug("Already on target branch",{branchName:t}),s.incrementCounter("git_switch_branch_noop",1),i({success:!0,reason:"already_on_branch"}),{success:!0,branchName:t,previousBranch:a,message:`Already on branch '${t}'`}
|
|
3928
3927
|
if(!await n(e,t,o,s)){const e=`Branch '${t}' does not exist`
|
|
3929
3928
|
throw o.error(e),s.incrementCounter("git_switch_branch_not_found",1),i({success:!1,reason:"branch_not_found"}),new g.ValidationError(e)}await e.checkout(t)
|
|
3930
3929
|
const c=await e.revparse(["HEAD"])
|
|
3931
|
-
return o.info("Switched to branch",{branchName:t,previousBranch:a,commitHash:c.substring(0,8)}),s.incrementCounter("git_switch_branch_success",1),i({success:!0}),{success:!0,branchName:t,previousBranch:a,commitHash:c,message:`Switched from '${a}' to '${t}'`}}catch(e){const r=(0,
|
|
3930
|
+
return o.info("Switched to branch",{branchName:t,previousBranch:a,commitHash:c.substring(0,8)}),s.incrementCounter("git_switch_branch_success",1),i({success:!0}),{success:!0,branchName:t,previousBranch:a,commitHash:c,message:`Switched from '${a}' to '${t}'`}}catch(e){const r=(0,f.getErrorMessage)(e)
|
|
3932
3931
|
throw o.error("Failed to switch branch",{branchName:t,error:r}),s.incrementCounter("git_switch_branch_failure",1),i({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError(`Failed to switch to branch '${t}': ${r}`)}}async function s(e,t,r){const n=r.startTimer("git_repository_status_duration")
|
|
3933
3932
|
try{let o,s=!0
|
|
3934
3933
|
try{o=await e.status()}catch(e){return s=!1,t.warn("Not a git repository or git not available"),r.incrementCounter("git_repository_status_not_git",1),n({success:!0,reason:"not_git_repo"}),{isGitRepository:!1,currentBranch:"",isClean:!1,hasMainBranch:!1,hasMasterBranch:!1,defaultBranch:"",uncommittedChanges:[],branches:[]}}const i=o.current||"",a=0===o.files.length,c=o.files.map((e=>e.path)),l=await e.branch(["-l"]),d=l.all.map((e=>({name:e,isCurrentBranch:e===i}))),u=l.all.includes("main"),h=l.all.includes("master")
|
|
3935
3934
|
let g=""
|
|
3936
|
-
return u?g="main":h?g="master":d.length>0&&(g=d[0].name),t.debug("Retrieved repository status",{currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:g,branchCount:d.length,uncommittedCount:c.length}),r.incrementCounter("git_repository_status_success",1),n({success:!0}),{isGitRepository:s,currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:g,uncommittedChanges:c,branches:d}}catch(e){const o=(0,
|
|
3935
|
+
return u?g="main":h?g="master":d.length>0&&(g=d[0].name),t.debug("Retrieved repository status",{currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:g,branchCount:d.length,uncommittedCount:c.length}),r.incrementCounter("git_repository_status_success",1),n({success:!0}),{isGitRepository:s,currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:g,uncommittedChanges:c,branches:d}}catch(e){const o=(0,f.getErrorMessage)(e)
|
|
3937
3936
|
throw t.error("Failed to get repository status",{error:o}),r.incrementCounter("git_repository_status_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to get repository status: "+o)}}function i(e){return"requests/"+e}async function a(e,t,r){const n=r.startTimer("git_uncommitted_changes_check_duration")
|
|
3938
3937
|
try{t.debug("Starting uncommitted changes check"),t.debug("Checking for uncommitted changes before merge"),Date.now()
|
|
3939
3938
|
const o=await e.status()
|
|
@@ -3945,7 +3944,7 @@ t.debug("Uncommitted changes summary",{hasChanges:l,totalFiles:c,staged:s.length
|
|
|
3945
3944
|
let d=""
|
|
3946
3945
|
if(l){const e=[]
|
|
3947
3946
|
s.length>0&&e.push(s.length+" staged file(s)"),i.length>0&&e.push(i.length+" unstaged file(s)"),a.length>0&&e.push(a.length+" untracked file(s)"),d=`Found ${c} uncommitted change(s): ${e.join(", ")}`}else d="No uncommitted changes detected"
|
|
3948
|
-
return(0,h.isDebugToolsEnabled)()&&t.debug("Summary",{summary:d}),t.debug("Uncommitted changes check completed",{hasChanges:l,staged:s.length,unstaged:i.length,untracked:a.length,total:c,summary:d}),r.incrementCounter("git_uncommitted_changes_check_success",1),r.recordValue("git_uncommitted_changes_total_files",c),n({success:!0}),{hasChanges:l,stagedFiles:s,unstagedFiles:i,untrackedFiles:a,totalFiles:c,summary:d}}catch(e){const o=(0,
|
|
3947
|
+
return(0,h.isDebugToolsEnabled)()&&t.debug("Summary",{summary:d}),t.debug("Uncommitted changes check completed",{hasChanges:l,staged:s.length,unstaged:i.length,untracked:a.length,total:c,summary:d}),r.incrementCounter("git_uncommitted_changes_check_success",1),r.recordValue("git_uncommitted_changes_total_files",c),n({success:!0}),{hasChanges:l,stagedFiles:s,unstagedFiles:i,untrackedFiles:a,totalFiles:c,summary:d}}catch(e){const o=(0,f.getErrorMessage)(e)
|
|
3949
3948
|
throw t.error("Failed to check uncommitted changes",{error:o}),r.incrementCounter("git_uncommitted_changes_check_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to check uncommitted changes: "+o)}}var c,l=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3950
3949
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3951
3950
|
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]}),d=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),u=this&&this.__importStar||(c=function(e){return c=Object.getOwnPropertyNames||function(e){var t=[]
|
|
@@ -3959,42 +3958,42 @@ try{if(await n(e,t,s,i)){const e=`Branch '${t}' already exists`
|
|
|
3959
3958
|
return s.warn(e),i.incrementCounter("git_create_branch_already_exists",1),c({success:!1,reason:"already_exists"}),{success:!1,branchName:t,message:e}}const l=await r(e,s,i)
|
|
3960
3959
|
await e.checkoutBranch(t,o)
|
|
3961
3960
|
const d=await e.revparse(["HEAD"]),u=a||l
|
|
3962
|
-
return await e.checkout(u),s.info("Created new branch",{branchName:t,fromBranch:o,currentBranch:l,returnedToBranch:u,commitHash:d.substring(0,8)}),i.incrementCounter("git_create_branch_success",1),c({success:!0}),{success:!0,branchName:t,previousBranch:l,commitHash:d,message:`Created branch '${t}' from '${o}'`}}catch(e){const r=(0,
|
|
3961
|
+
return await e.checkout(u),s.info("Created new branch",{branchName:t,fromBranch:o,currentBranch:l,returnedToBranch:u,commitHash:d.substring(0,8)}),i.incrementCounter("git_create_branch_success",1),c({success:!0}),{success:!0,branchName:t,previousBranch:l,commitHash:d,message:`Created branch '${t}' from '${o}'`}}catch(e){const r=(0,f.getErrorMessage)(e)
|
|
3963
3962
|
throw s.error("Failed to create branch",{branchName:t,fromBranch:o,error:r}),i.incrementCounter("git_create_branch_failure",1),c({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError(`Failed to create branch '${t}': ${r}`)}},exports.switchToBranch=o,exports.mergeBranch=async function(e,t,s,i,a,c){const l=a.startTimer("git_merge_branch_duration")
|
|
3964
3963
|
try{const d=await r(e,i,a)
|
|
3965
3964
|
if(d!==s&&await o(e,s,i,a),!await n(e,t,i,a)){const e=`Source branch '${t}' does not exist`
|
|
3966
3965
|
throw i.error(e),a.incrementCounter("git_merge_branch_source_not_found",1),l({success:!1,reason:"source_not_found"}),new g.ValidationError(e)}const u=c?["--no-ff","-m",c,t]:["--no-ff",t],h=(await e.merge(u),await e.revparse(["HEAD"]))
|
|
3967
|
-
return i.info("Successfully merged branch",{sourceBranch:t,targetBranch:s,commitHash:h.substring(0,8),mergeMessage:c||"default merge message"}),a.incrementCounter("git_merge_branch_success",1),l({success:!0}),{success:!0,branchName:s,previousBranch:d,commitHash:h,message:`Merged '${t}' into '${s}'`}}catch(e){const r=(0,
|
|
3966
|
+
return i.info("Successfully merged branch",{sourceBranch:t,targetBranch:s,commitHash:h.substring(0,8),mergeMessage:c||"default merge message"}),a.incrementCounter("git_merge_branch_success",1),l({success:!0}),{success:!0,branchName:s,previousBranch:d,commitHash:h,message:`Merged '${t}' into '${s}'`}}catch(e){const r=(0,f.getErrorMessage)(e)
|
|
3968
3967
|
throw i.error("Failed to merge branch",{sourceBranch:t,targetBranch:s,error:r}),a.incrementCounter("git_merge_branch_failure",1),l({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError(`Failed to merge '${t}' into '${s}': ${r}`)}},exports.deleteBranch=async function(e,t,o=!1,s,i){const a=i.startTimer("git_delete_branch_duration")
|
|
3969
3968
|
try{const c=await r(e,s,i)
|
|
3970
3969
|
if(c===t){const e=`Cannot delete current branch '${t}'`
|
|
3971
3970
|
throw s.error(e),i.incrementCounter("git_delete_branch_current_branch",1),a({success:!1,reason:"current_branch"}),new g.ValidationError(e)}if("main"===t||"master"===t){const e=`Cannot delete protected branch '${t}'`
|
|
3972
3971
|
throw s.error(e),i.incrementCounter("git_delete_branch_protected",1),a({success:!1,reason:"protected_branch"}),new g.ValidationError(e)}if(!await n(e,t,s,i)){const e=`Branch '${t}' does not exist`
|
|
3973
3972
|
return s.warn(e),i.incrementCounter("git_delete_branch_not_found",1),a({success:!1,reason:"not_found"}),{success:!1,branchName:t,message:e}}const l=o?["-D",t]:["-d",t]
|
|
3974
|
-
return await e.branch(l),s.info("Deleted branch",{branchName:t,force:o,currentBranch:c}),i.incrementCounter("git_delete_branch_success",1),a({success:!0}),{success:!0,branchName:t,previousBranch:c,message:`Deleted branch '${t}'${o?" (forced)":""}`}}catch(e){const r=(0,
|
|
3973
|
+
return await e.branch(l),s.info("Deleted branch",{branchName:t,force:o,currentBranch:c}),i.incrementCounter("git_delete_branch_success",1),a({success:!0}),{success:!0,branchName:t,previousBranch:c,message:`Deleted branch '${t}'${o?" (forced)":""}`}}catch(e){const r=(0,f.getErrorMessage)(e)
|
|
3975
3974
|
throw s.error("Failed to delete branch",{branchName:t,force:o,error:r}),i.incrementCounter("git_delete_branch_failure",1),a({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError(`Failed to delete branch '${t}': ${r}`)}},exports.getRepositoryStatus=s,exports.validateGitRepository=async function(e,t,r){const n=r.startTimer("git_validate_repository_duration")
|
|
3976
3975
|
try{const o=await s(e,t,r)
|
|
3977
|
-
return o.isGitRepository?(o.currentBranch||(t.warn("Git repository in detached HEAD state"),r.incrementCounter("git_validate_repository_detached_head",1)),o.isClean||(t.warn("Git repository has uncommitted changes",{count:o.uncommittedChanges.length,files:o.uncommittedChanges.slice(0,5)}),r.incrementCounter("git_validate_repository_dirty",1)),o.defaultBranch||(t.warn("No default branch found in git repository"),r.incrementCounter("git_validate_repository_no_default_branch",1)),t.info("Git repository validation completed",{currentBranch:o.currentBranch,isClean:o.isClean,defaultBranch:o.defaultBranch,branchCount:o.branches.length}),r.incrementCounter("git_validate_repository_success",1),n({success:!0}),o):(t.warn("Git repository validation failed: not a git repository"),r.incrementCounter("git_validate_repository_not_git",1),n({success:!1,reason:"not_git_repo"}),o)}catch(e){const o=(0,
|
|
3976
|
+
return o.isGitRepository?(o.currentBranch||(t.warn("Git repository in detached HEAD state"),r.incrementCounter("git_validate_repository_detached_head",1)),o.isClean||(t.warn("Git repository has uncommitted changes",{count:o.uncommittedChanges.length,files:o.uncommittedChanges.slice(0,5)}),r.incrementCounter("git_validate_repository_dirty",1)),o.defaultBranch||(t.warn("No default branch found in git repository"),r.incrementCounter("git_validate_repository_no_default_branch",1)),t.info("Git repository validation completed",{currentBranch:o.currentBranch,isClean:o.isClean,defaultBranch:o.defaultBranch,branchCount:o.branches.length}),r.incrementCounter("git_validate_repository_success",1),n({success:!0}),o):(t.warn("Git repository validation failed: not a git repository"),r.incrementCounter("git_validate_repository_not_git",1),n({success:!1,reason:"not_git_repo"}),o)}catch(e){const o=(0,f.getErrorMessage)(e)
|
|
3978
3977
|
throw t.error("Git repository validation failed",{error:o}),r.incrementCounter("git_validate_repository_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Git repository validation failed: "+o)}},exports.sanitizeBranchName=function(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").substring(0,50)},exports.generateRequestBranchName=i,exports.generateMergeMessagePatterns=function(e){const t=i(e)
|
|
3979
3978
|
return[`Merge ${t}-`,"Merge "+t,`Merge ${t}-.*\\(resolved conflicts\\)`,`Merge ${t} \\(resolved conflicts\\)`]},exports.parseRequestIdFromBranchName=function(e){const t=e.match(/^feature\/(req\d{6})-/)
|
|
3980
3979
|
return t?t[1]:null},exports.switchToDefaultBranch=async function(e,t,r){const n=r.startTimer("git_switch_to_default_duration")
|
|
3981
3980
|
try{const i=await s(e,t,r)
|
|
3982
3981
|
if(!i.defaultBranch){const e="No default branch found"
|
|
3983
3982
|
return t.warn(e),r.incrementCounter("git_switch_to_default_no_branch",1),n({success:!1,reason:"no_default_branch"}),{success:!1,branchName:"",message:e}}const a=await o(e,i.defaultBranch,t,r)
|
|
3984
|
-
return a.success?(t.info("Switched to default branch",{defaultBranch:i.defaultBranch,previousBranch:a.previousBranch}),r.incrementCounter("git_switch_to_default_success",1),n({success:!0})):(r.incrementCounter("git_switch_to_default_failed",1),n({success:!1,reason:"switch_failed"})),a}catch(e){const o=(0,
|
|
3983
|
+
return a.success?(t.info("Switched to default branch",{defaultBranch:i.defaultBranch,previousBranch:a.previousBranch}),r.incrementCounter("git_switch_to_default_success",1),n({success:!0})):(r.incrementCounter("git_switch_to_default_failed",1),n({success:!1,reason:"switch_failed"})),a}catch(e){const o=(0,f.getErrorMessage)(e)
|
|
3985
3984
|
throw t.error("Failed to switch to default branch",{error:o}),r.incrementCounter("git_switch_to_default_error",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to switch to default branch: "+o)}},exports.ensureRepositoryReady=async function(e,t,r){const n=r.startTimer("git_ensure_repository_ready_duration")
|
|
3986
3985
|
try{const o=await s(e,t,r),i=[]
|
|
3987
3986
|
o.isGitRepository||i.push("Not a git repository"),o.currentBranch||i.push("Repository is in detached HEAD state"),o.defaultBranch||i.push("No default branch (main/master) found")
|
|
3988
3987
|
const a=0===i.length
|
|
3989
|
-
return t.debug("Repository readiness check completed",{ready:a,issueCount:i.length,issues:i}),r.incrementCounter("git_ensure_repository_ready_check",1,{ready:a.toString()}),n({success:!0,ready:a.toString()}),{ready:a,status:o,issues:i}}catch(e){const o=(0,
|
|
3988
|
+
return t.debug("Repository readiness check completed",{ready:a,issueCount:i.length,issues:i}),r.incrementCounter("git_ensure_repository_ready_check",1,{ready:a.toString()}),n({success:!0,ready:a.toString()}),{ready:a,status:o,issues:i}}catch(e){const o=(0,f.getErrorMessage)(e)
|
|
3990
3989
|
return t.error("Failed to check repository readiness",{error:o}),r.incrementCounter("git_ensure_repository_ready_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),{ready:!1,status:{isGitRepository:!1,currentBranch:"",isClean:!1,hasMainBranch:!1,hasMasterBranch:!1,defaultBranch:"",uncommittedChanges:[],branches:[]},issues:["Repository check failed: "+o]}}},exports.hasMainChangedSinceRevert=async function(e,t,r,n){const o=n.startTimer("git_check_main_changed_since_revert")
|
|
3991
3990
|
try{r.debug("Starting main branch change detection",{providedRevertCommitHash:t.substring(0,8),fullRevertCommitHash:t})
|
|
3992
3991
|
const n=await e.revparse(["HEAD"])
|
|
3993
3992
|
r.debug("Git state captured",{currentMainHash:n.substring(0,8),fullCurrentMainHash:n,revertCommitHash:t.substring(0,8),fullRevertCommitHash:t,hashesMatch:n===t})
|
|
3994
3993
|
try{const t=await e.revparse(["--abbrev-ref","HEAD"]),n=await e.status(),o=await e.log(["--oneline","-5"])
|
|
3995
|
-
r.debug("Additional git context",{currentBranch:t,gitStatus:{ahead:n.ahead,behind:n.behind,current:n.current,tracking:n.tracking,staged:n.staged.length,modified:n.modified.length},recentCommits:o.all.map((e=>({hash:e.hash.substring(0,8),message:e.message})))})}catch(e){r.warn("Failed to gather additional git context",{error:e instanceof Error?e.message:e+""})}const s=await(0,
|
|
3994
|
+
r.debug("Additional git context",{currentBranch:t,gitStatus:{ahead:n.ahead,behind:n.behind,current:n.current,tracking:n.tracking,staged:n.staged.length,modified:n.modified.length},recentCommits:o.all.map((e=>({hash:e.hash.substring(0,8),message:e.message})))})}catch(e){r.warn("Failed to gather additional git context",{error:e instanceof Error?e.message:e+""})}const s=await(0,p.validateCommitHash)(e,t,r,"hasMainChangedSinceRevert-revert-validation")
|
|
3996
3995
|
if(!s.valid)throw r.error("Revert commit validation failed",{revertCommitHash:t.substring(0,8),error:s.error}),Error(`Revert commit ${t.substring(0,8)} not found or not reachable: ${s.error}`)
|
|
3997
|
-
const i=await(0,
|
|
3996
|
+
const i=await(0,p.validateCommitHash)(e,n,r,"hasMainChangedSinceRevert-head-validation")
|
|
3998
3997
|
if(!i.valid)throw r.error("Current HEAD validation failed",{currentMainHash:n.substring(0,8),error:i.error}),Error(`Current HEAD ${n.substring(0,8)} validation failed: ${i.error}`)
|
|
3999
3998
|
if(n===t)return r.info("Main branch unchanged since revert - exact hash match",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),fullHashMatch:!0}),o({success:!0,changed:"false"}),{hasChanged:!1,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:0,message:"Main branch has not changed since revert"}
|
|
4000
3999
|
r.debug("Hash comparison shows difference, checking ancestor relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),hashesEqual:!1})
|
|
@@ -4002,10 +4001,10 @@ let a=!1,c=0,l=null
|
|
|
4002
4001
|
for(let n=1;3>=n;n++)try{r.debug("Checking ancestor relationship with merge-base",{revertCommitHash:t.substring(0,8),currentHead:"HEAD",attempt:n}),n>1&&(await new Promise((e=>setTimeout(e,100))),r.debug("Retry attempt after delay",{attempt:n,delay:100})),await e.raw(["merge-base","--is-ancestor",t,"HEAD"]),r.debug("Revert commit is ancestor of HEAD, counting commits between them",{attempt:n})
|
|
4003
4002
|
const o=await e.raw(["rev-list","--count",t+"..HEAD"])
|
|
4004
4003
|
c=parseInt(o.trim(),10),a=!0
|
|
4005
|
-
break}catch(e){l=e,r.debug("Ancestor check attempt failed",{attempt:n,error:(0,
|
|
4004
|
+
break}catch(e){l=e,r.debug("Ancestor check attempt failed",{attempt:n,error:(0,f.getErrorMessage)(e)}),3===n&&r.debug("All ancestor check attempts failed, treating as non-ancestor")}if(a){try{const n=await e.raw(["rev-list","--oneline",t+"..HEAD"])
|
|
4006
4005
|
r.debug("Commits found between revert and HEAD",{count:c,commits:n.trim().split("\n").filter((e=>e.length>0))})}catch(e){r.warn("Could not list commits between revert and HEAD",{error:e instanceof Error?e.message:e+""})}return r.info("Main branch has changed since revert - ancestor relationship confirmed",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),commitsSinceRevert:c,isAncestor:!0}),o({success:!0,changed:"true"}),{hasChanged:!0,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:c,message:`Main branch has ${c} new commit${c>1?"s":""} since revert`}}r.warn("Revert commit is not an ancestor of current HEAD after retries - investigating relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),lastAncestorError:l instanceof Error?l.message:l+"",attempts:3})
|
|
4007
4006
|
try{const o=await e.raw(["merge-base",t,"HEAD"])
|
|
4008
|
-
r.debug("Merge base found between revert commit and HEAD",{mergeBase:o.trim().substring(0,8),revertCommitHash:t.substring(0,8),currentMainHash:n.substring(0,8)})}catch(e){r.warn("Could not find merge base",{error:e instanceof Error?e.message:e+""})}try{await e.raw(["merge-base","--is-ancestor","HEAD",t]),r.error("CRITICAL: Current HEAD is ancestor of revert commit - possible git state corruption or incorrect revert hash",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),implication:"This suggests the stored revert commit hash may be incorrect or from a different branch state"})}catch(e){r.debug("HEAD is not ancestor of revert commit either - commits may be on divergent paths",{error:e instanceof Error?e.message:e+""})}return o({success:!0,changed:"unknown"}),{hasChanged:!0,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:-1,message:"Cannot determine relationship between revert commit and current HEAD - assuming changed for safety. This may indicate a stored revert commit hash issue."}}catch(e){const n=(0,
|
|
4007
|
+
r.debug("Merge base found between revert commit and HEAD",{mergeBase:o.trim().substring(0,8),revertCommitHash:t.substring(0,8),currentMainHash:n.substring(0,8)})}catch(e){r.warn("Could not find merge base",{error:e instanceof Error?e.message:e+""})}try{await e.raw(["merge-base","--is-ancestor","HEAD",t]),r.error("CRITICAL: Current HEAD is ancestor of revert commit - possible git state corruption or incorrect revert hash",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),implication:"This suggests the stored revert commit hash may be incorrect or from a different branch state"})}catch(e){r.debug("HEAD is not ancestor of revert commit either - commits may be on divergent paths",{error:e instanceof Error?e.message:e+""})}return o({success:!0,changed:"unknown"}),{hasChanged:!0,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:-1,message:"Cannot determine relationship between revert commit and current HEAD - assuming changed for safety. This may indicate a stored revert commit hash issue."}}catch(e){const n=(0,f.getErrorMessage)(e)
|
|
4009
4008
|
throw r.error("Failed to check if main changed since revert",{revertCommitHash:t.substring(0,8),error:n}),o({success:!1,error:e instanceof Error?e.name:"unknown"}),Error("Failed to check main branch changes: "+n)}},exports.findRevertCommitHash=async function(e,t,r){try{r.debug("Searching for revert commit hash in tool records",{requestId:e})
|
|
4010
4009
|
const n=await t.getToolRecordsByRequestId(e,"revert-request")
|
|
4011
4010
|
if(n.sort(((e,t)=>new Date(t.createdAt).getTime()-new Date(e.createdAt).getTime())),!n||0===n.length)return r.debug("No revert tool records found for request",{requestId:e}),{found:!1,message:"No revert operations found for this request"}
|
|
@@ -4014,7 +4013,7 @@ for(const t of n)if(r.debug("Examining tool record",{requestId:e,recordId:t.id,r
|
|
|
4014
4013
|
r.debug("Found potential revert commit hash, validating...",{requestId:e,revertCommitHash:o.substring(0,8),fullRevertCommitHash:o,revertType:n,recordId:t.id,revertedAt:t.createdAt})
|
|
4015
4014
|
try{if(!/^[a-f0-9]{40}$/i.test(o)){r.warn("Invalid commit hash format found in tool record",{requestId:e,invalidHash:o,recordId:t.id,format:"Expected 40-character hex string"})
|
|
4016
4015
|
continue}return r.info("Found valid revert commit hash from tool records",{requestId:e,revertCommitHash:o.substring(0,8),fullRevertCommitHash:o,revertType:n,recordId:t.id,revertedAt:t.createdAt,hashFormat:"valid"}),{found:!0,revertCommitHash:o,revertType:n,revertedAt:t.createdAt,message:`Found ${n} revert commit from ${t.createdAt}`}}catch(n){r.warn("Revert commit hash validation failed, trying next record",{requestId:e,revertCommitHash:o.substring(0,8),recordId:t.id,error:n instanceof Error?n.message:n+""})
|
|
4017
|
-
continue}}return r.warn("Found revert tool records but none have completed status with commit hash",{requestId:e,recordCount:n.length,records:n.map((e=>({type:e.type,status:e.metadata?.status,hasCommitHash:!!e.metadata?.revertCommitHash})))}),{found:!1,message:"Found revert records but none were completed successfully"}}catch(t){const n=(0,
|
|
4016
|
+
continue}}return r.warn("Found revert tool records but none have completed status with commit hash",{requestId:e,recordCount:n.length,records:n.map((e=>({type:e.type,status:e.metadata?.status,hasCommitHash:!!e.metadata?.revertCommitHash})))}),{found:!1,message:"Found revert records but none were completed successfully"}}catch(t){const n=(0,f.getErrorMessage)(t)
|
|
4018
4017
|
return r.error("Failed to find revert commit hash from tool records",{requestId:e,error:n}),{found:!1,message:"Failed to search tool records: "+n}}},exports.checkUncommittedChanges=a,exports.commitUserChanges=async function(e,t,r,n,o){const s=o.startTimer("git_commit_user_changes_duration")
|
|
4019
4018
|
try{if(!r.hasChanges)throw new g.ValidationError("No uncommitted changes to commit")
|
|
4020
4019
|
n.debug("Starting user changes commit process",{staged:r.stagedFiles.length,unstaged:r.unstagedFiles.length,untracked:r.untrackedFiles.length,total:r.totalFiles}),n.info("Committing user changes before merge",{requestId:t,staged:r.stagedFiles.length,unstaged:r.unstagedFiles.length,untracked:r.untrackedFiles.length,total:r.totalFiles})
|
|
@@ -4023,7 +4022,7 @@ i.length>0?(n.debug("Staging files",{files:i.slice(0,10),total:i.length}),await
|
|
|
4023
4022
|
const a=`chore: commit user changes before merging request ${t}\n\n${r.summary}\n\nThis commit preserves user modifications made during the request lifecycle\nbefore proceeding with the branch merge operation.`
|
|
4024
4023
|
n.debug("Commit message",{message:a.split("\n")[0]}),n.debug("Creating commit"),await e.commit(a)
|
|
4025
4024
|
const c=await e.revparse(["HEAD"])
|
|
4026
|
-
return n.debug("Commit created successfully",{commitHash:c.substring(0,8),filesCommitted:r.totalFiles}),n.info("Successfully committed user changes",{requestId:t,commitHash:c.substring(0,8),filesCommitted:r.totalFiles,message:a.split("\n")[0]}),o.incrementCounter("git_commit_user_changes_success",1),o.recordValue("git_commit_user_changes_files",r.totalFiles),s({success:!0}),{commitHash:c,message:a,filesCommitted:r.totalFiles}}catch(e){const i=(0,
|
|
4025
|
+
return n.debug("Commit created successfully",{commitHash:c.substring(0,8),filesCommitted:r.totalFiles}),n.info("Successfully committed user changes",{requestId:t,commitHash:c.substring(0,8),filesCommitted:r.totalFiles,message:a.split("\n")[0]}),o.incrementCounter("git_commit_user_changes_success",1),o.recordValue("git_commit_user_changes_files",r.totalFiles),s({success:!0}),{commitHash:c,message:a,filesCommitted:r.totalFiles}}catch(e){const i=(0,f.getErrorMessage)(e)
|
|
4027
4026
|
throw n.error("Failed to commit user changes",{requestId:t,error:i,uncommittedFiles:r.totalFiles}),o.incrementCounter("git_commit_user_changes_failure",1),s({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to commit user changes: "+i)}},exports.commitUserChangesBeforeToolOperation=async function(e,r,n,o,s){const i=s.startTimer("git_pre_tool_user_changes_duration")
|
|
4028
4027
|
try{let c=Date.now()
|
|
4029
4028
|
o.debug("Checking for user changes before tool operation",{toolName:r})
|
|
@@ -4040,8 +4039,8 @@ const h=`${u}\n\n${{...d,summary:`User changes detected before ${r}: ${d.summary
|
|
|
4040
4039
|
o.debug("Committing user changes with message",{firstLine:h.split("\n")[0]})
|
|
4041
4040
|
const g=[...d.unstagedFiles,...d.untrackedFiles]
|
|
4042
4041
|
c=Date.now(),g.length>0&&(o.debug("Staging files before tool operation",{files:g.slice(0,10),total:g.length}),await l.add(g)),Date.now(),c=Date.now(),await l.commit(h),Date.now()
|
|
4043
|
-
const
|
|
4044
|
-
return o.debug("User changes committed successfully before tool",{commitHash:
|
|
4042
|
+
const p=await l.revparse(["HEAD"])
|
|
4043
|
+
return o.debug("User changes committed successfully before tool",{commitHash:p.substring(0,8),filesCommitted:d.totalFiles,toolName:r}),o.info("Successfully committed user changes before tool operation",{toolName:r,requestId:n.requestId,taskId:n.taskId,commitHash:p.substring(0,8),filesCommitted:d.totalFiles}),s.incrementCounter("git_pre_tool_user_changes_committed",1),s.recordValue("git_pre_tool_user_changes_files",d.totalFiles),i({success:!0,reason:"changes_committed"}),{userChangesCommitted:!0,commitHash:p,filesCommitted:d.totalFiles}}catch(e){const t=(0,f.getErrorMessage)(e)
|
|
4045
4044
|
return o.debug("Failed to commit user changes before tool",{toolName:r,error:t}),o.warn("Failed to commit user changes before tool operation",{toolName:r,requestId:n.requestId,taskId:n.taskId,error:t}),s.incrementCounter("git_pre_tool_user_changes_failed",1),i({success:!1,error:e instanceof Error?e.name:"unknown"}),{userChangesCommitted:!1}}},exports.findLargeUntrackedFiles=async function(e,r=104857600){const n=[]
|
|
4046
4045
|
try{const o=t(3807).simpleGit(e),s=(await o.status()).not_added||[]
|
|
4047
4046
|
for(const t of s)try{const o=y.join(e,t),s=m.statSync(o)
|
|
@@ -4050,7 +4049,7 @@ const t=e.reduce(((e,t)=>e+t.sizeMB),0)
|
|
|
4050
4049
|
let r=`\n\n\u26a0\ufe0f **Performance Warning**: Large untracked files detected (${Math.round(t)} MB total) that may slow git operations:\n`
|
|
4051
4050
|
for(const t of e.slice(0,5))r+=`- \`${t.path}\` (${t.sizeMB} MB)\n`
|
|
4052
4051
|
return e.length>5&&(r+=`- ... and ${e.length-5} more large files\n`),r+="\nConsider adding these to `.gitignore` or moving them outside the repository.",r}
|
|
4053
|
-
const h=t(3444),g=t(9860),
|
|
4052
|
+
const h=t(3444),g=t(9860),p=t(3922),f=t(8824),m=u(t(9896)),y=u(t(6928))},7575(e,exports){var t
|
|
4054
4053
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileOperationPhase=exports.RequestLockError=void 0,exports.RequestLockError=class extends Error{constructor(e,t,r,n){super(e),this.requestId=t,this.lockedByAgent=r,this.lockedAt=n,this.name="RequestLockError"}},function(e){e.VALIDATION="validation",e.TASK_VALIDATION="task_validation",e.RECORD_CREATION="record_creation",e.FILE_WRITE="file_write",e.STRING_REPLACEMENT="string_replacement",e.GIT_COMMIT="git_commit",e.RECORD_UPDATE_SUCCESS="record_update_success",e.RECORD_UPDATE_FAILURE="record_update_failure"}(t||(exports.FileOperationPhase=t={}))},7609(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleUpdatePlan=async function(e,t,n,o){const s=o.child({tool:"plan_operations",operation:"update"})
|
|
4055
4054
|
try{const t=n.getDocumentClient(),r=await t.getDocument(e.planId)
|
|
4056
4055
|
if(!r)return{content:[{type:"text",text:"\u274c Plan not found: "+e.planId}],isError:!0}
|
|
@@ -4061,55 +4060,9 @@ const i=await t.updateDocument(e.planId,o),a=i.localId||i.id
|
|
|
4061
4060
|
return s.info("Plan updated",{planId:a}),{content:[{type:"text",text:`\u2705 **Plan Updated**\n\n**Plan ID:** ${a}\n**Filename:** ${i.filename}\n**Updated:** `+new Date(i.updatedAt).toLocaleString()}]}}catch(e){return s.error("Failed to update plan",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to update plan:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
4062
4061
|
const r=t(8824)},7613(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4063
4062
|
const r=t(6183),n=t(9072)
|
|
4064
|
-
exports.def={name:"session_message_operations",description:'Inter-session messaging (questions and reports).\n\nOperations:\n\u2022 send - Send a message (type: "question" or "report")\n\u2022 reply - Reply to a message (answer a question or acknowledge a report). Type inferred from code prefix (Q-/R-).\n\u2022 list - List messages (filter by messageType, direction, status)\n\u2022 get - Get a message by its code\n\u2022 offer-handoff - Present the user with a choice to start building or keep planning\n\nMessage codes: Q-{id}-{seq} for questions, R-{id}-{seq} for reports.',schema:r.SessionMessageOperationsSchema,annotations:{title:"Session Message Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleSessionMessageOperations)(e,t.context,t.logger,t.metrics,t.apiClient??void 0)}}},7617(e,exports,t){function
|
|
4065
|
-
if(e.operation!==t.operation)return!1
|
|
4066
|
-
if("ask"===e.operation){let r=e.ask||e,n=t.ask||t
|
|
4067
|
-
if("string"==typeof n)try{n=JSON.parse(n)}catch{}if("string"==typeof r)try{r=JSON.parse(r)}catch{}const o=r?.questionContent?.question||r?.question,s=n?.questionContent?.question||n?.question
|
|
4068
|
-
return!(!o||!s)&&o===s}return!0}async function n(e,t,n,s){const i=n.child({component:"session-discovery"})
|
|
4069
|
-
try{const n=e.replace(/\/$/,"")+"/session",o=await fetch(n)
|
|
4070
|
-
if(!o.ok)return void i.warn("Failed to get session list",{status:o.status})
|
|
4071
|
-
const a=await o.json(),c=a.sort(((e,t)=>t.time.updated-e.time.updated)),l=e.replace(/\/$/,"")+"/session/status",d=await fetch(l)
|
|
4072
|
-
if(!d.ok)return void i.warn("Failed to get session status",{status:d.status})
|
|
4073
|
-
const u=await d.json(),h=c.filter((e=>"busy"===u[e.id]?.type)),g=5,f=c.slice(0,g),p=new Set(h.map((e=>e.id))),m=[...h,...f.filter((e=>!p.has(e.id)))]
|
|
4074
|
-
let y=null
|
|
4075
|
-
const w=[]
|
|
4076
|
-
for(const n of m)try{const o=`${e.replace(/\/$/,"")}/session/${n.id}/message?limit=50`,a=await fetch(o)
|
|
4077
|
-
if(!a.ok){i.debug("Failed to get messages for session",{sessionId:n.id,status:a.status})
|
|
4078
|
-
continue}const c=await a.json()
|
|
4079
|
-
let l=0
|
|
4080
|
-
for(const e of c){const o=(e.info||e).role||e.role,i=e.parts
|
|
4081
|
-
if("assistant"===o&&i)for(const o of i)if("tool"===o.type){const i=o.tool,a=o.state?.status,c=o.sessionID
|
|
4082
|
-
if(l++,i&&i.includes(t)){if("running"!==a&&"pending"!==a){w.push({sessionId:n.id,tool:i,reason:"wrong state: "+a})
|
|
4083
|
-
continue}const t=o.state?.input,l=o.state?.time?.start||0,d=c||n.id,u=Date.now(),h=l>0?u-l:0
|
|
4084
|
-
if(l>0&&h>6e4){w.push({sessionId:n.id,tool:i,reason:`stale: running for ${Math.round(h/1e3)}s`})
|
|
4085
|
-
continue}if(s&&t&&!r(s,t)){w.push({sessionId:n.id,tool:i,reason:"params mismatch"})
|
|
4086
|
-
continue}const g=e.info?.id
|
|
4087
|
-
y&&l<=y.startTime||(y={sessionId:d,messageId:g,startTime:l,toolName:i})}else i&&(i.includes("session-qa")||i.includes("subagent"))&&w.push({sessionId:n.id,tool:i,reason:"name mismatch: looking for "+t})}}}catch(e){i.debug("Error checking session",{sessionId:n.id,error:e+""})
|
|
4088
|
-
continue}return y?{sessionId:y.sessionId,messageId:y.messageId}:void i.warn("Session discovery failed - no matching tool call found",{toolName:t,totalSessions:a.length,busySessions:h.length,rejectionCount:w.length,rejections:w.slice(0,10)})}catch(e){return void i.warn("Failed to discover calling session",{error:(0,o.getErrorMessage)(e)})}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.getServerUrl=async function(e,r){let n=process.env.OPENCODE_TUI_URL
|
|
4063
|
+
exports.def={name:"session_message_operations",description:'Inter-session messaging (questions and reports).\n\nOperations:\n\u2022 send - Send a message (type: "question" or "report")\n\u2022 reply - Reply to a message (answer a question or acknowledge a report). Type inferred from code prefix (Q-/R-).\n\u2022 list - List messages (filter by messageType, direction, status)\n\u2022 get - Get a message by its code\n\u2022 offer-handoff - Present the user with a choice to start building or keep planning\n\nMessage codes: Q-{id}-{seq} for questions, R-{id}-{seq} for reports.',schema:r.SessionMessageOperationsSchema,annotations:{title:"Session Message Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleSessionMessageOperations)(e,t.context,t.logger,t.metrics,t.apiClient??void 0)}}},7617(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.getServerUrl=async function(e,r){let n=process.env.OPENCODE_TUI_URL
|
|
4089
4064
|
if(!n)try{const{readFileSync:o}=await Promise.resolve().then(t.t.bind(t,9896,23)),{join:s}=await Promise.resolve().then(t.t.bind(t,6928,23)),i=o(s(e.basePath,".alchemy_lab","opencode.json"),"utf8"),a=JSON.parse(i)
|
|
4090
|
-
a.port&&(n="http://127.0.0.1:"+a.port,r.debug("Discovered OpenCode server URL from .alchemy_lab/opencode.json",{serverUrl:n}))}catch(e){r.debug("Could not read .alchemy_lab/opencode.json",{error:e instanceof Error?e.message:e+""})}return n},exports
|
|
4091
|
-
if(s)return t.info("Found calling session by tool",{sessionId:s.sessionId,messageId:s.messageId,toolName:r}),s}},exports.findMessageIdForTool=async function(e,t,r){try{const n=`${e.replace(/\/$/,"")}/session/${t}/message?limit=50`,o=await fetch(n)
|
|
4092
|
-
if(!o.ok)return
|
|
4093
|
-
const s=await o.json()
|
|
4094
|
-
let i,a=0
|
|
4095
|
-
for(const e of s){const t=(e.info||e).role||e.role,n=e.parts
|
|
4096
|
-
if("assistant"===t&&n)for(const t of n){if("tool"!==t.type)continue
|
|
4097
|
-
const n=t.tool,o=t.state?.status
|
|
4098
|
-
if(!n?.includes(r))continue
|
|
4099
|
-
if("running"!==o&&"pending"!==o)continue
|
|
4100
|
-
const s=t.state?.time?.start||0
|
|
4101
|
-
s>a&&(a=s,i=e.info?.id)}}return i}catch{return}},exports.discoverCallingSession=n,exports.discoverParentSessionId=async function(e,t){try{const r=e.replace(/\/$/,"")+"/session",n=await fetch(r)
|
|
4102
|
-
if(!n.ok)return void t.warn("Failed to get session list",{status:n.status})
|
|
4103
|
-
const o=[...await n.json()].sort(((e,t)=>t.time.updated-e.time.updated))
|
|
4104
|
-
if(0===o.length)return void t.warn("No sessions found")
|
|
4105
|
-
const s=e.replace(/\/$/,"")+"/session/status",i=await fetch(s)
|
|
4106
|
-
if(!i.ok)return void t.warn("Failed to get session status",{status:i.status})
|
|
4107
|
-
const a=await i.json(),c=o.filter((e=>"busy"===a[e.id]?.type))
|
|
4108
|
-
for(const r of c)try{const n=`${e.replace(/\/$/,"")}/session/${r.id}/message?limit=20`,o=await fetch(n)
|
|
4109
|
-
if(!o.ok)continue
|
|
4110
|
-
const s=await o.json()
|
|
4111
|
-
for(const e of s)if("assistant"===e.role&&e.parts)for(const n of e.parts)if("tool-invocation"===n.type&&"subagent_operations"===n.toolInvocation?.toolName&&"spawn"===n.toolInvocation?.args?.operation&&"pending"===n.toolInvocation?.state)return t.info("Found parent session via spawn tool call",{parentSessionId:r.id}),r.id}catch{continue}return c.length>0?(t.info("Fallback: using first busy session",{parentSessionId:c[0].id}),c[0].id):(t.info("Last resort: using most recent session",{parentSessionId:o[0].id}),o[0].id)}catch(e){t.warn("Failed to query OpenCode API for parent session",{error:e instanceof Error?e.message:e+""})}}
|
|
4112
|
-
const o=t(8824)},7621(e,exports,t){async function r(e,t,r){const n=r.startTimer("get_current_git_branch_duration")
|
|
4065
|
+
a.port&&(n="http://127.0.0.1:"+a.port,r.debug("Discovered OpenCode server URL from .alchemy_lab/opencode.json",{serverUrl:n}))}catch(e){r.debug("Could not read .alchemy_lab/opencode.json",{error:e instanceof Error?e.message:e+""})}return n}},7621(e,exports,t){async function r(e,t,r){const n=r.startTimer("get_current_git_branch_duration")
|
|
4113
4066
|
try{if(!e.git)return t.debug("No git repository available"),r.incrementCounter("get_current_git_branch_no_git",1),n({success:!1,reason:"no_git"}),null
|
|
4114
4067
|
const o=await u.getCurrentBranch(e.git,t,r)
|
|
4115
4068
|
return t.debug("Retrieved current git branch",{currentBranch:o}),r.incrementCounter("get_current_git_branch_success",1),n({success:!0}),o}catch(e){const o=(0,g.getErrorMessage)(e)
|
|
@@ -4118,33 +4071,33 @@ try{if(!t.git)return r.debug("No git repository available"),n.incrementCounter("
|
|
|
4118
4071
|
const s=await u.getRepositoryStatus(t.git,r,n),i=s.branches.filter((t=>t.name==="requests/"+e)),a=i.length>0,c=a?i[0].name:void 0,l=i.map((e=>e.name))
|
|
4119
4072
|
return r.debug("Searched for feature branch",{requestId:e,found:a,branchName:c,matchingBranches:l.length,totalBranches:s.branches.length}),n.incrementCounter("find_feature_branch_success",1,{found:a.toString()}),o({success:!0,found:a.toString()}),{found:a,branchName:c,allBranches:l}}catch(t){const s=(0,g.getErrorMessage)(t)
|
|
4120
4073
|
return r.warn("Failed to find feature branch for request",{requestId:e,error:s}),n.incrementCounter("find_feature_branch_failure",1),o({success:!1,error:t instanceof Error?t.name:"unknown"}),{found:!1}}}async function o(e,o,s,i,a,c){if(!o||!s.git)return{switched:!1,message:"No branch switch needed"}
|
|
4121
|
-
let l=!1,
|
|
4122
|
-
try{s.syncBranchState&&await s.syncBranchState(),Date.now(),
|
|
4074
|
+
let l=!1,f=Date.now()
|
|
4075
|
+
try{s.syncBranchState&&await s.syncBranchState(),Date.now(),f=Date.now()
|
|
4123
4076
|
const e=s.getCurrentBranchContext?await s.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4124
4077
|
if(Date.now(),e.requestId===o)return i.debug("Already in correct request context",{requestId:o,currentBranch:e.branch}),{switched:!1,branchName:e.branch||void 0,message:`Already in request ${o} context`,lockAcquired:!1}
|
|
4125
4078
|
if(s.workspaceManager){i.debug("Using WorkspaceManager for request context switching",{requestId:o,currentMode:s.workspaceManager.getCurrentContext().mode})
|
|
4126
4079
|
try{if("multi-agent"===s.workspaceManager.getCurrentContext().mode)if(i.debug("Multi-agent mode: checking request lock before auto-switch",{requestId:o}),s.apiClient)try{const e=s.apiClient.getRequestClient(),{sessionTag:t}=(0,h.getGlobalClientInfo)()
|
|
4127
|
-
|
|
4080
|
+
f=Date.now()
|
|
4128
4081
|
const r=await e.getRequestLockStatus(o)
|
|
4129
4082
|
if(Date.now(),r.isLocked&&r.lockedBySessionTag!==t){i.warn("Auto-switch blocked by request lock",{requestId:o,lockedByAgent:r.lockedBySessionTag,currentAgent:t,lockedAt:r.lockedAt})
|
|
4130
4083
|
let e=`Request ${o} is currently locked by another agent (${r.lockedBySessionTag}).\n\nLocked since: ${r.lockedAt||"unknown"}\n\nIn multi-agent mode, only one agent can work on a request at a time. Please wait for the other agent to complete their work or contact an administrator if the lock appears stale.`
|
|
4131
4084
|
if(s.lockOverrideManager&&s.configManager)try{const t=await s.configManager.getEffectiveConfig(s.mainBasePath)
|
|
4132
|
-
t.lockOverride.enabled&&(e+=`\n\n**To take over this request (only if safe to do so), use switch_to_branch with password: \`${s.lockOverrideManager.generatePassword(o,t.lockOverride.passwordValidityMinutes)}\` (valid for ${t.lockOverride.passwordValidityMinutes} minutes)**`)}catch(e){i.warn("Failed to check lock override config",{error:e})}throw new
|
|
4085
|
+
t.lockOverride.enabled&&(e+=`\n\n**To take over this request (only if safe to do so), use switch_to_branch with password: \`${s.lockOverrideManager.generatePassword(o,t.lockOverride.passwordValidityMinutes)}\` (valid for ${t.lockOverride.passwordValidityMinutes} minutes)**`)}catch(e){i.warn("Failed to check lock override config",{error:e})}throw new p.RequestLockError(e,o,r.lockedBySessionTag,r.lockedAt)}if(!r.isLocked){f=Date.now(),i.debug("Acquiring lock for auto-switch",{requestId:o,sessionTag:t})
|
|
4133
4086
|
const r=await e.lockRequest(o,t)
|
|
4134
4087
|
if(Date.now(),!r.locked){const e=`Failed to acquire lock for request ${o} during auto-switch`
|
|
4135
4088
|
throw i.warn("Auto-switch lock acquisition failed",{requestId:o}),Error(e)}i.info("Successfully acquired lock for auto-switch",{requestId:o,sessionTag:t,lockedAt:r.lockedAt}),l=!0}}catch(e){throw i.error("Lock check/acquisition failed during auto-switch",{requestId:o,error:e instanceof Error?e.message:e+""}),e}else i.warn("Multi-agent mode but no API client available for locking",{requestId:o})
|
|
4136
|
-
i.debug("Ensuring workspace is ready for file operations",{requestId:o,reason:"first-file-operation"}),
|
|
4089
|
+
i.debug("Ensuring workspace is ready for file operations",{requestId:o,reason:"first-file-operation"}),f=Date.now(),await s.workspaceManager.ensureWorkspaceReady(o),Date.now()
|
|
4137
4090
|
const e=s.workspaceManager.getCurrentContext()
|
|
4138
4091
|
if(e.basePath&&(s.git=(0,d.simpleGit)(e.basePath),i.info("Updated git instance to worktree path",{requestId:o,gitWorkingDirectory:e.basePath,mode:e.mode,branchName:e.branchName})),e.requestId!==o){const t=`Workspace switch validation failed. Expected requestId: ${o}, but got: ${e.requestId}`
|
|
4139
4092
|
throw i.error("Post-switch context validation failed",{requestId:o,expectedRequestId:o,actualRequestId:e.requestId,actualBasePath:e.basePath,mode:e.mode}),Error(t)}i.info("Workspace is ready via WorkspaceManager",{requestId:o,mode:s.workspaceManager.getCurrentContext().mode,workflow:"hybrid-creation-lazy-worktree",validation:"context_validated"})
|
|
4140
4093
|
try{const{findLargeUntrackedFiles:r,formatLargeFileWarning:n}=await Promise.resolve().then(t.t.bind(t,7478,23)),a=await r(e.basePath)
|
|
4141
4094
|
if(a.length>0){const e=n(a)
|
|
4142
|
-
s.workspaceManager.largeFileWarning=e,i.warn("Large untracked files detected",{requestId:o,fileCount:a.length,files:a.map((e=>({path:e.path,sizeMB:e.sizeMB})))})}}catch(e){i.debug("Large file check failed",{error:e})}return a.incrementCounter(c+"_auto_context_switch_success",1),{switched:!0,branchName:s.workspaceManager.getCurrentContext().branchName,message:"Workspace ready for request "+o,lockAcquired:l,lockedRequestId:l?o:void 0}}catch(e){if(e instanceof
|
|
4095
|
+
s.workspaceManager.largeFileWarning=e,i.warn("Large untracked files detected",{requestId:o,fileCount:a.length,files:a.map((e=>({path:e.path,sizeMB:e.sizeMB})))})}}catch(e){i.debug("Large file check failed",{error:e})}return a.incrementCounter(c+"_auto_context_switch_success",1),{switched:!0,branchName:s.workspaceManager.getCurrentContext().branchName,message:"Workspace ready for request "+o,lockAcquired:l,lockedRequestId:l?o:void 0}}catch(e){if(e instanceof p.RequestLockError)throw i.warn("Auto-switch blocked by request lock, re-throwing lock error",{requestId:e.requestId,lockedByAgent:e.lockedByAgent,lockedAt:e.lockedAt}),e
|
|
4143
4096
|
return i.error("Error switching to request context",{requestId:o,error:(0,g.getErrorMessage)(e)}),a.incrementCounter(c+"_auto_context_switch_error",1),{switched:!1,message:"Context switch error: "+(0,g.getErrorMessage)(e)}}}i.warn("WorkspaceManager not available, falling back to legacy branch switching",{requestId:o})
|
|
4144
4097
|
const m=await n(o,s,i,a)
|
|
4145
4098
|
if(!m.found||!m.branchName)return i.warn("No feature branch found for request during auto-switch",{requestId:o,availableBranches:m.allBranches||[]}),a.incrementCounter(c+"_auto_branch_switch_no_branch",1),{switched:!1,message:"No feature branch found for request "+o}
|
|
4146
4099
|
const y=await r(s,i,a),w=await u.switchToBranch(s.git,m.branchName,i,a)
|
|
4147
|
-
return w.success?(s.updateBranchState&&await s.updateBranchState(m.branchName,o),i.info("Auto-switched to request branch after task promotion",{requestId:o,fromBranch:y,toBranch:m.branchName}),a.incrementCounter(c+"_auto_branch_switch_success",1),{switched:!0,branchName:m.branchName,message:"Switched to "+m.branchName}):(i.warn("Failed to auto-switch to request branch",{requestId:o,targetBranch:m.branchName,error:w.message}),a.incrementCounter(c+"_auto_branch_switch_failure",1),{switched:!1,message:"Failed to switch: "+w.message})}catch(e){if(e instanceof
|
|
4100
|
+
return w.success?(s.updateBranchState&&await s.updateBranchState(m.branchName,o),i.info("Auto-switched to request branch after task promotion",{requestId:o,fromBranch:y,toBranch:m.branchName}),a.incrementCounter(c+"_auto_branch_switch_success",1),{switched:!0,branchName:m.branchName,message:"Switched to "+m.branchName}):(i.warn("Failed to auto-switch to request branch",{requestId:o,targetBranch:m.branchName,error:w.message}),a.incrementCounter(c+"_auto_branch_switch_failure",1),{switched:!1,message:"Failed to switch: "+w.message})}catch(e){if(e instanceof p.RequestLockError)throw i.warn("Auto-switch blocked by request lock in legacy mode, re-throwing lock error",{requestId:e.requestId,lockedByAgent:e.lockedByAgent,lockedAt:e.lockedAt}),e
|
|
4148
4101
|
return i.error("Error during auto-switch to request branch",{requestId:o,error:(0,g.getErrorMessage)(e)}),a.incrementCounter(c+"_auto_branch_switch_error",1),{switched:!1,message:"Error during switch: "+(0,g.getErrorMessage)(e)}}}function s(e,t,r,n){if(!e.workspaceManager)return n.debug("No workspace manager available, skipping context validation",{operation:r,requestId:t}),{isValid:!0}
|
|
4149
4102
|
const o=e.workspaceManager.getCurrentContext()
|
|
4150
4103
|
if("multi-agent"!==o.mode)return n.debug("Single-agent mode detected, skipping multi-agent context validation",{operation:r,requestId:t,mode:o.mode}),{isValid:!0}
|
|
@@ -4194,8 +4147,8 @@ return r.debug("Single-agent mode: determined expected branch",{taskId:e,request
|
|
|
4194
4147
|
try{const e=await o(0,r,n,a,c,l)
|
|
4195
4148
|
if(e.switched&&a.info(`Auto-switched to request workspace during ${i} operation`,{requestId:r,branchName:e.branchName,message:e.message,taskPromoted:t,operation:i}),d&&r){const t=s(n,r,i,a)
|
|
4196
4149
|
if(!t.isValid)return a.error("Workspace context validation failed for "+i,{requestId:r,operation:i,error:t.errorMessage}),{success:!1,switched:e.switched,branchName:e.branchName,error:t.errorMessage,lockAcquired:e.lockAcquired,lockedRequestId:e.lockedRequestId}}return a.debug("Workspace context successfully ensured for "+i,{requestId:r,operation:i,switched:e.switched,branchName:e.branchName}),{success:!0,switched:e.switched,branchName:e.branchName,lockAcquired:e.lockAcquired,lockedRequestId:e.lockedRequestId}}catch(e){const t=(0,g.getErrorMessage)(e)
|
|
4197
|
-
return e instanceof
|
|
4198
|
-
const d=t(3807),u=l(t(7478)),h=t(5172),g=t(8824),
|
|
4150
|
+
return e instanceof p.RequestLockError?(a.warn(i+" operation blocked by request lock",{requestId:e.requestId,lockedByAgent:e.lockedByAgent,operation:i}),{success:!1,switched:!1,error:e.message,isLockConflict:!0}):(a.error("Error ensuring workspace context for "+i,{requestId:r,operation:i,error:t}),{success:!1,switched:!1,error:t})}}
|
|
4151
|
+
const d=t(3807),u=l(t(7478)),h=t(5172),g=t(8824),p=t(7575)
|
|
4199
4152
|
l(t(9896)),l(t(6928))},7634(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.RequestLockManager=exports.WorktreeManager=void 0
|
|
4200
4153
|
var r=t(1502)
|
|
4201
4154
|
Object.defineProperty(exports,"WorktreeManager",{enumerable:!0,get(){return r.WorktreeManager}})
|
|
@@ -4203,7 +4156,9 @@ var n=t(2037)
|
|
|
4203
4156
|
Object.defineProperty(exports,"RequestLockManager",{enumerable:!0,get(){return n.RequestLockManager}})},7636(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4204
4157
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentWorkspaceManager=void 0
|
|
4205
4158
|
const n=r(t(6928)),o=t(3807),s=t(7634),i=t(8824),a=t(7075),c=t(1387),l=t(4968)
|
|
4206
|
-
|
|
4159
|
+
class d{getSession(e){const t=e||d.DEFAULT_SESSION
|
|
4160
|
+
let r=this.sessions.get(t)
|
|
4161
|
+
return r||(r={requestId:null,worktreePath:null,git:this.mainGit,readonlyBranchCheckDone:!1,workspaceKnownClean:!1,largeFileWarning:""},this.sessions.set(t,r)),r}constructor(e,t,r,n,o){this.basePath=e,this.logger=t,this.mainGit=r,this.metrics=n,this.workspaceStates=new Map,this.sessions=new Map,this.apiClient=o
|
|
4207
4162
|
const i=a.ConflictResolutionUtils.initializeDetectors(r,t)
|
|
4208
4163
|
this.conflictDetector=i.conflictDetector,this.safetyAnalyzer=i.safetyAnalyzer,this.conflictResolver=i.conflictResolver,this.worktreeManager=new s.WorktreeManager(e,t,n),this.gitAdapter=new l.WorktreeGitAdapter(r,this.worktreeManager,this.conflictDetector,t,n),this.requestProcessor=new c.WorkspaceRequestProcessor(this.gitAdapter,this.conflictDetector,this.safetyAnalyzer,this.conflictResolver,t),this.initializeWorktreeManager(),this.initializeFromEnv()}async initializeFromEnv(){const e=process.env.ALCHEMY_INITIAL_BRANCH
|
|
4209
4164
|
if(!e)return
|
|
@@ -4211,73 +4166,81 @@ const t=e.match(/^requests\/(.+)$/)
|
|
|
4211
4166
|
if(!t)return void this.logger.warn("ALCHEMY_INITIAL_BRANCH set but not a request branch",{initialBranch:e})
|
|
4212
4167
|
const r=t[1]
|
|
4213
4168
|
this.logger.info("ALCHEMY_INITIAL_BRANCH set, switching to worktree",{initialBranch:e,requestId:r})
|
|
4214
|
-
try{await this.ensureWorkspaceReady(r)
|
|
4169
|
+
try{await this.ensureWorkspaceReady(r)
|
|
4170
|
+
const e=this.getSession()
|
|
4171
|
+
e.readonlyBranchCheckDone=!0,this.logger.info("Successfully switched to worktree from ALCHEMY_INITIAL_BRANCH",{requestId:r,worktreePath:e.worktreePath})}catch(t){this.logger.warn("Failed to switch to worktree from ALCHEMY_INITIAL_BRANCH",{initialBranch:e,requestId:r,error:(0,i.getErrorMessage)(t)})}}hasExactConflictMarkers(e){return!(!e||!e.trim())&&[/^\s*<{7}(?:\s|$)/m,/^\s*={7}(?:\s|$)/m,/^\s*>{7}(?:\s|$)/m].some((t=>t.test(e)))}async initializeWorktreeManager(){try{await this.worktreeManager.initialize(),this.logger.debug("Initialized multi-agent workspace manager with worktrees")}catch(e){throw this.logger.error("Failed to initialize worktree manager",{error:e}),e}}setTaskCreator(e){this.taskCreator=e}async initializeRequest(e,t){const r=Date.now(),n=a.WorkspaceValidation.validateRequestId(e)
|
|
4215
4172
|
if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
|
|
4216
4173
|
const o=n.sanitized
|
|
4217
|
-
try{
|
|
4218
|
-
const n="requests/"+o,s=await this.mainGit.branch().then((e=>e.all.includes(n)||e.all.includes("remotes/origin/"+n)))
|
|
4219
|
-
if(!s){const e=await this.mainGit.revparse(["--abbrev-ref","HEAD"]),t=(await this.mainGit.branch()).all.includes("main")?"main":"master"
|
|
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
|
|
4223
|
-
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
|
-
if(!r.isValid)throw Error("Invalid request ID: "+r.errors.join(", "))
|
|
4225
|
-
const n=r.sanitized
|
|
4226
|
-
let s=!1
|
|
4227
|
-
if(this.apiClient)try{const e=this.apiClient.getRequestClient(),t=await e.getRequest(n)
|
|
4228
|
-
if(t&&"quick-edit"===t.type){s=!0,this.logger.info("Quick-edit request detected - checking out branch in main repo (no worktree)",{requestId:n,requestType:t.type})
|
|
4229
|
-
const e="requests/"+n
|
|
4230
|
-
return(await this.mainGit.branch()).all.includes(e)?(await this.mainGit.checkout(e),this.logger.info("Checked out existing quick-edit branch in main repo",{requestId:n,branchName:e})):(await this.mainGit.checkoutLocalBranch(e),this.logger.info("Created and checked out quick-edit branch in main repo",{requestId:n,branchName:e})),this.currentRequestId=n,this.currentWorktreePath=null,this.currentGit=this.mainGit,void this.workspaceStates.set(n,"ready")}}catch(e){this.logger.warn("Failed to check request type, proceeding with normal workflow",{requestId:n,error:(0,i.getErrorMessage)(e)})}if("ready"!==this.workspaceStates.get(n)||this.currentRequestId!==n){if("ready"===this.workspaceStates.get(n)&&this.currentRequestId!==n){this.logger.info("Workspace ready but not in correct context, switching to it",{requestId:n,currentRequestId:this.currentRequestId,reason:"context_mismatch"})
|
|
4231
|
-
const e=this.worktreeManager.getWorktreeInfo(n)
|
|
4232
|
-
if(e&&e.worktreePath)return this.currentRequestId=n,this.currentWorktreePath=e.worktreePath,this.currentGit=(0,o.simpleGit)(e.worktreePath),void this.logger.info("Switched to existing ready workspace",{requestId:n,worktreePath:e.worktreePath})}try{a.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by creating/switching to worktree",e,"multi-agent","ensureWorkspaceReady",{currentState:this.workspaceStates.get(n)||"not-initialized",currentRequestId:this.currentRequestId,architecture:"hybrid-creation"})
|
|
4233
|
-
const r=await this.worktreeManager.ensureWorktreeExists(n,void 0,void 0)
|
|
4234
|
-
if(!r.success)throw Error("Failed to create worktree: "+r.message)
|
|
4235
|
-
if(this.currentRequestId=n,this.currentWorktreePath=r.worktreePath,this.currentGit=(0,o.simpleGit)(r.worktreePath),this.workspaceStates.set(n,"ready"),r.created){this.workspaceKnownClean=!0
|
|
4236
|
-
try{const e=(0,o.simpleGit)(r.worktreePath),t=(await this.mainGit.branch()).all.includes("main")?"main":"master",s=await this.mainGit.revparse([t]),i=await e.revparse(["HEAD"])
|
|
4237
|
-
s!==i&&0===(await e.log({from:t,to:"HEAD"})).total&&(await e.rebase([t]),this.logger.info("Rebased fresh request branch onto latest main",{requestId:n,mainHead:s.substring(0,8),previousHead:i.substring(0,8)}))}catch(e){this.logger.warn("Failed to rebase onto main, proceeding with existing branch",{requestId:n,error:(0,i.getErrorMessage)(e)})}}const s=Date.now()-t
|
|
4238
|
-
this.metrics.recordValue("workspace.ensure_ready",s),a.WorkspaceLogging.logOperation(this.logger,"info","Workspace is ready with worktree",e,"multi-agent","ensureWorkspaceReady",{worktreePath:r.worktreePath,branchName:r.branchName,duration:s,architecture:"hybrid-creation"})}catch(r){const n=Date.now()-t
|
|
4239
|
-
throw this.metrics.recordValue("workspace.ensure_ready",n),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure workspace ready",e,"multi-agent","ensureWorkspaceReady",{error:(0,i.getErrorMessage)(r),duration:n}),r}}else this.logger.debug("Workspace already ready and in correct context",{requestId:n,worktreePath:this.currentWorktreePath})}async switchToRequest(e,t){this.logger.debug("switchToRequest called",{requestId:e,options:t})
|
|
4240
|
-
const r=Date.now(),n=this.getCurrentContext()
|
|
4241
|
-
if(this.logger.debug("previousContext",{previousContext:n}),t?.isCompleted&&this.currentRequestId!==e)return this.logger.debug("Completed request detected - using simple checkout instead of worktree"),await this.switchToCompletedRequest(e,r,n)
|
|
4242
|
-
const o=a.WorkspaceValidation.validateRequestId(e)
|
|
4243
|
-
if(!o.isValid){const t="Invalid request ID: "+o.errors.join(", ")
|
|
4244
|
-
return a.WorkspaceLogging.logOperation(this.logger,"error",t,e,"multi-agent","switchToRequest"),{success:!1,message:t,previousContext:n,newContext:n}}try{this.logger.debug("About to call ensureWorkspaceReady",{requestId:o.sanitized}),await this.ensureWorkspaceReady(o.sanitized),this.logger.debug("ensureWorkspaceReady completed",{currentRequestId:this.currentRequestId,currentWorktreePath:this.currentWorktreePath})
|
|
4174
|
+
try{this.workspaceStates.set(o,"initialized")
|
|
4245
4175
|
const t=Date.now()-r
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
const
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
const
|
|
4256
|
-
return
|
|
4257
|
-
|
|
4176
|
+
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
|
|
4177
|
+
throw this.metrics.recordValue("workspace.initialize",n),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to initialize request",e,"multi-agent","initializeRequest",{error:(0,i.getErrorMessage)(t),duration:n}),t}}async ensureWorkspaceReady(e,t){const r=this.getSession(t),n=Date.now(),s=a.WorkspaceValidation.validateRequestId(e)
|
|
4178
|
+
if(!s.isValid)throw Error("Invalid request ID: "+s.errors.join(", "))
|
|
4179
|
+
const c=s.sanitized
|
|
4180
|
+
let l=!1
|
|
4181
|
+
if(this.apiClient)try{const e=this.apiClient.getRequestClient(),t=await e.getRequest(c)
|
|
4182
|
+
if(t&&"quick-edit"===t.type){l=!0,this.logger.info("Quick-edit request detected - checking out branch in main repo (no worktree)",{requestId:c,requestType:t.type})
|
|
4183
|
+
const e="requests/"+c
|
|
4184
|
+
return(await this.mainGit.branch()).all.includes(e)?(await this.mainGit.checkout(e),this.logger.info("Checked out existing quick-edit branch in main repo",{requestId:c,branchName:e})):(await this.mainGit.checkoutLocalBranch(e),this.logger.info("Created and checked out quick-edit branch in main repo",{requestId:c,branchName:e})),r.requestId=c,r.worktreePath=null,r.git=this.mainGit,void this.workspaceStates.set(c,"ready")}}catch(e){this.logger.warn("Failed to check request type, proceeding with normal workflow",{requestId:c,error:(0,i.getErrorMessage)(e)})}if("ready"!==this.workspaceStates.get(c)||r.requestId!==c){if("ready"===this.workspaceStates.get(c)&&r.requestId!==c){this.logger.info("Workspace ready but not in correct context, switching to it",{requestId:c,currentRequestId:r.requestId,reason:"context_mismatch"})
|
|
4185
|
+
const e=this.worktreeManager.getWorktreeInfo(c)
|
|
4186
|
+
if(e&&e.worktreePath)return r.requestId=c,r.worktreePath=e.worktreePath,r.git=(0,o.simpleGit)(e.worktreePath),void this.logger.info("Switched to existing ready workspace",{requestId:c,worktreePath:e.worktreePath})}try{a.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by creating/switching to worktree",e,"multi-agent","ensureWorkspaceReady",{currentState:this.workspaceStates.get(c)||"not-initialized",currentRequestId:r.requestId,architecture:"hybrid-creation"})
|
|
4187
|
+
const t=await this.worktreeManager.ensureWorktreeExists(c,void 0,void 0)
|
|
4188
|
+
if(!t.success)throw Error("Failed to create worktree: "+t.message)
|
|
4189
|
+
if(r.requestId=c,r.worktreePath=t.worktreePath,r.git=(0,o.simpleGit)(t.worktreePath),this.workspaceStates.set(c,"ready"),t.created){r.workspaceKnownClean=!0
|
|
4190
|
+
try{const e=(0,o.simpleGit)(t.worktreePath),r=(await this.mainGit.branch()).all.includes("main")?"main":"master",n=await this.mainGit.revparse([r]),s=await e.revparse(["HEAD"])
|
|
4191
|
+
n!==s&&0===(await e.log({from:r,to:"HEAD"})).total&&(await e.rebase([r]),this.logger.info("Rebased fresh request branch onto latest main",{requestId:c,mainHead:n.substring(0,8),previousHead:s.substring(0,8)}))}catch(e){this.logger.warn("Failed to rebase onto main, proceeding with existing branch",{requestId:c,error:(0,i.getErrorMessage)(e)})}}const s=Date.now()-n
|
|
4192
|
+
this.metrics.recordValue("workspace.ensure_ready",s),a.WorkspaceLogging.logOperation(this.logger,"info","Workspace is ready with worktree",e,"multi-agent","ensureWorkspaceReady",{worktreePath:t.worktreePath,branchName:t.branchName,duration:s,architecture:"hybrid-creation"})}catch(t){const r=Date.now()-n
|
|
4193
|
+
throw this.metrics.recordValue("workspace.ensure_ready",r),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure workspace ready",e,"multi-agent","ensureWorkspaceReady",{error:(0,i.getErrorMessage)(t),duration:r}),t}}else this.logger.debug("Workspace already ready and in correct context",{requestId:c,worktreePath:r.worktreePath})}async switchToRequest(e,t){const r=t?.sessionId,n=this.getSession(r)
|
|
4194
|
+
this.logger.debug("switchToRequest called",{requestId:e,options:t,sessionId:r})
|
|
4195
|
+
const o=Date.now(),s=this.getCurrentContext(r)
|
|
4196
|
+
if(this.logger.debug("previousContext",{previousContext:s}),t?.isCompleted&&n.requestId!==e)return this.logger.debug("Completed request detected - using simple checkout instead of worktree"),await this.switchToCompletedRequest(e,o,s)
|
|
4197
|
+
const c=a.WorkspaceValidation.validateRequestId(e)
|
|
4198
|
+
if(!c.isValid){const t="Invalid request ID: "+c.errors.join(", ")
|
|
4199
|
+
return a.WorkspaceLogging.logOperation(this.logger,"error",t,e,"multi-agent","switchToRequest"),{success:!1,message:t,previousContext:s,newContext:s}}try{this.logger.debug("About to call ensureWorkspaceReady",{requestId:c.sanitized}),await this.ensureWorkspaceReady(c.sanitized,r),this.logger.debug("ensureWorkspaceReady completed",{currentRequestId:n.requestId,currentWorktreePath:n.worktreePath})
|
|
4200
|
+
const t=Date.now()-o
|
|
4201
|
+
return this.metrics?.recordValue("workspace_switch_duration",t),a.WorkspaceLogging.logOperation(this.logger,"info","Switched to worktree for request",e,"multi-agent","switchToRequest",{worktreePath:n.worktreePath,duration:t}),{success:!0,message:"Switched to worktree for request: "+e,previousContext:s,newContext:this.getCurrentContext(r),worktreePath:n.worktreePath}}catch(t){const r=Date.now()-o
|
|
4202
|
+
return this.metrics?.recordValue("workspace_switch_duration",r),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to request",e,"multi-agent","switchToRequest",{error:(0,i.getErrorMessage)(t),duration:r}),{success:!1,message:"Failed to switch to request: "+(0,i.getErrorMessage)(t),previousContext:s,newContext:s}}}async switchToCompletedRequest(e,t,r){try{const n="requests/"+e
|
|
4203
|
+
a.WorkspaceLogging.logOperation(this.logger,"info","Switching to completed request (no worktree)",e,"multi-agent","switchToCompletedRequest",{branchName:n}),await this.mainGit.checkout(n)
|
|
4204
|
+
const o=this.getSession()
|
|
4205
|
+
o.requestId=e,o.worktreePath=null,o.git=this.mainGit
|
|
4206
|
+
const s=Date.now()-t
|
|
4207
|
+
return this.metrics?.recordValue("workspace_switch_duration",s),a.WorkspaceLogging.logOperation(this.logger,"info","Successfully switched to completed request branch",e,"multi-agent","switchToCompletedRequest",{branchName:n,duration:s,worktree:!1}),{success:!0,message:`Switched to completed request branch: ${n} (no worktree)`,previousContext:r,newContext:this.getCurrentContext()}}catch(n){const o=Date.now()-t
|
|
4208
|
+
return this.metrics?.recordValue("workspace_switch_duration",o),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to completed request",e,"multi-agent","switchToCompletedRequest",{error:(0,i.getErrorMessage)(n),duration:o}),{success:!1,message:"Failed to switch to completed request: "+(0,i.getErrorMessage)(n),previousContext:r,newContext:r}}}async switchToMain(e){const t=this.getSession(e),r=this.getCurrentContext(e)
|
|
4209
|
+
return t.requestId=null,t.worktreePath=null,t.git=this.mainGit,this.logger.info("Switched to main repository context"),{success:!0,message:"Switched to main repository",previousContext:r,newContext:this.getCurrentContext(e)}}async commitChanges(e,t,r){const n=this.getSession(r),o=Date.now()
|
|
4210
|
+
if(!n.requestId||!n.worktreePath)throw new a.ConflictDetectionError("No active request context for commit","multi-agent-commit",[])
|
|
4211
|
+
try{t&&t.length>0?await n.git.add(t):await n.git.add("."),await n.git.commit(e)
|
|
4212
|
+
const r=await n.git.revparse(["HEAD"]),s=Date.now()-o
|
|
4213
|
+
return this.metrics?.recordValue("workspace_commit_duration",s),this.logger.info("Successfully committed changes in worktree",{requestId:n.requestId,worktreePath:n.worktreePath,message:e,commitHash:r.substring(0,8),filesCount:t?.length||"all",duration:s}),{hash:r,message:e,files:t||[]}}catch(t){const r=Date.now()-o
|
|
4214
|
+
throw this.metrics?.recordValue("workspace_commit_duration",r),this.logger.error("Failed to commit changes in worktree",{requestId:n.requestId,worktreePath:n.worktreePath,message:e,error:(0,i.getErrorMessage)(t),duration:r}),new a.ConflictDetectionError("Failed to commit changes: "+(0,i.getErrorMessage)(t),"multi-agent-commit",[])}}async completeRequest(e,t,r){const n=Date.now()
|
|
4258
4215
|
try{a.WorkspaceLogging.logOperation(this.logger,"info","Starting request completion (refactored)",e,"multi-agent","completeRequest",{requestTitle:t,skipConflictDetection:r?.skipConflictDetection||!1,architecture:"shared-processor"})
|
|
4259
4216
|
const o=await this.requestProcessor.completeRequest(e,t,{skipConflictDetection:r?.skipConflictDetection||!1}),s=Date.now()-n
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
throw this.
|
|
4217
|
+
this.metrics?.recordValue("workspace_complete_duration",s),this.metrics?.incrementCounter("workspace_complete_success",1)
|
|
4218
|
+
for(const[t,r]of this.sessions)r.requestId===e&&(r.requestId=null,r.worktreePath=null,r.git=this.mainGit)
|
|
4219
|
+
return a.WorkspaceLogging.logOperation(this.logger,"info","Request completion successful (refactored)",e,"multi-agent","completeRequest",{mergeCommitHash:o.mergeCommitHash.substring(0,8),mergedFiles:o.mergedFiles?.length||0,cleanedUp:o.cleanedUp,wasAutoMerged:o.autoMergeInfo?.wasAutoMerged,strategy:o.autoMergeInfo?.strategy,duration:s,architecture:"shared-processor"}),o}catch(t){const r=Date.now()-n
|
|
4220
|
+
throw this.metrics?.recordValue("workspace_complete_duration",r),this.metrics?.incrementCounter("workspace_complete_error",1),a.WorkspaceLogging.logOperation(this.logger,"error","Request completion failed (refactored)",e,"multi-agent","completeRequest",{error:(0,i.getErrorMessage)(t),duration:r,architecture:"shared-processor"}),t}}resolveFilePath(e,t){const r=this.getSession(t)
|
|
4221
|
+
if(r.worktreePath)return this.logger.debug("Resolving file path in worktree context",{relativePath:e,worktreePath:r.worktreePath,requestId:r.requestId}),n.default.resolve(r.worktreePath,e)
|
|
4222
|
+
const o=`Cannot resolve file path in multi-agent mode without request context. Current state: requestId=${r.requestId}, worktreePath=${r.worktreePath}. Ensure you switch to a request workspace before performing file operations.`
|
|
4223
|
+
throw this.logger.error("Unsafe file path resolution attempt in multi-agent mode",{relativePath:e,currentRequestId:r.requestId,currentWorktreePath:r.worktreePath,basePath:this.basePath,action:"preventing_fallback_to_main"}),Error(o)}resolveMainBranchFilePath(e){return this.logger.debug("Resolving file path in main branch context",{relativePath:e,basePath:this.basePath,context:"explicit_main_branch_operation"}),n.default.resolve(this.basePath,e)}async createCommit(e,t,r){return await this.commitChanges(e,t,r)}async cancelRequest(e){const t=a.WorkspaceValidation.validateRequestId(e)
|
|
4264
4224
|
if(!t.isValid)throw Error("Invalid request ID: "+t.errors.join(", "))
|
|
4265
4225
|
const r=t.sanitized
|
|
4266
|
-
try{this.
|
|
4226
|
+
try{for(const[e,t]of this.sessions)t.requestId===r&&(t.requestId=null,t.worktreePath=null,t.git=this.mainGit)
|
|
4267
4227
|
const e=await this.worktreeManager.removeWorktree(r,!1)
|
|
4268
4228
|
if(!e.success)throw Error(e.message||"Failed to remove worktree")
|
|
4269
|
-
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:
|
|
4270
|
-
return this.logger.debug("getCurrentContext returning",{context:e}),
|
|
4229
|
+
this.logger.info("Successfully cancelled request",{requestId:r})}catch(e){throw this.logger.error("Failed to cancel request",{requestId:r,error:(0,i.getErrorMessage)(e)}),e}}getCurrentContext(e){const t=this.getSession(e),r={requestId:t.requestId,basePath:t.worktreePath||this.basePath,branchName:t.requestId?"requests/"+t.requestId:"main",isMainBranch:!t.requestId,mode:"multi-agent"}
|
|
4230
|
+
return this.logger.debug("getCurrentContext returning",{context:r,sessionId:e}),r}resetCurrentContext(e){const t=this.getSession(e)
|
|
4231
|
+
t.requestId&&this.logger.info("Resetting workspace context (session switch)",{prevRequestId:t.requestId,prevWorktreePath:t.worktreePath,sessionId:e}),t.requestId=null,t.worktreePath=null,t.git=this.mainGit,t.readonlyBranchCheckDone=!1}async getWorkspaceInfo(e){try{const t=a.WorkspaceValidation.validateRequestId(e)
|
|
4271
4232
|
if(!t.isValid)return null
|
|
4272
4233
|
const r=t.sanitized,n=await this.getWorktreeInfo(r)
|
|
4273
|
-
return n?{requestId:r,path:n.worktreePath,branchName:n.branchName,isActive:this.
|
|
4274
|
-
return t?t[1]:null}convertWorktreeInfoToWorkspaceInfo(e){return{requestId:e.requestId,path:e.worktreePath,branchName:e.branchName,isActive:this.
|
|
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.
|
|
4276
|
-
|
|
4277
|
-
const
|
|
4278
|
-
if(o){
|
|
4234
|
+
return n?{requestId:r,path:n.worktreePath,branchName:n.branchName,isActive:this.isActiveForAnySession(r),created:new Date,lastAccessed:new Date}:null}catch(t){return this.logger.error("Failed to get workspace info",{requestId:e,error:(0,i.getErrorMessage)(t)}),null}}async listActiveWorkspaces(){try{return(await this.worktreeManager.listActiveWorktrees()).map((e=>this.convertWorktreeInfoToWorkspaceInfo(e)))}catch(e){return this.logger.error("Failed to list active workspaces",{error:(0,i.getErrorMessage)(e)}),[]}}extractRequestIdFromBranch(e){const t=e.match(/^requests\/(.+)$/)
|
|
4235
|
+
return t?t[1]:null}convertWorktreeInfoToWorkspaceInfo(e){return{requestId:e.requestId,path:e.worktreePath,branchName:e.branchName,isActive:this.isActiveForAnySession(e.requestId),created:e.created,lastAccessed:e.lastAccessed}}async getWorktreeInfo(e){try{const t=e.replace(/[^a-zA-Z0-9_-]/g,"_")
|
|
4236
|
+
return this.worktreeManager.getWorktreeInfo(t)}catch(t){return void this.logger.warn("Failed to get worktree info",{requestId:e,error:(0,i.getErrorMessage)(t)})}}getMainGit(){return this.gitAdapter.getMainGit()}getCurrentGit(e){return this.getSession(e).git}get readonlyBranchCheckDone(){return this.getSession().readonlyBranchCheckDone}set readonlyBranchCheckDone(e){this.getSession().readonlyBranchCheckDone=e}get workspaceKnownClean(){return this.getSession().workspaceKnownClean}set workspaceKnownClean(e){this.getSession().workspaceKnownClean=e}get largeFileWarning(){return this.getSession().largeFileWarning}set largeFileWarning(e){this.getSession().largeFileWarning=e}async ensureReadonlyBranchIfNeeded(e,r,n,o){const s=this.getSession(o)
|
|
4237
|
+
if(s.readonlyBranchCheckDone)return
|
|
4238
|
+
if(s.readonlyBranchCheckDone=!0,o&&n)try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=await e.getSessionRequestId(n,this.logger,o)
|
|
4239
|
+
if(r)return await this.ensureWorkspaceReady(r,o),void this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready from session DB lookup",{requestId:r,sessionId:o})}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: session DB lookup failed, falling back to env var",{error:(0,i.getErrorMessage)(e)})}const a=process.env.ALCHEMY_INITIAL_BRANCH
|
|
4240
|
+
if(a){const e=a.match(/^requests\/(.+)$/)
|
|
4279
4241
|
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)})}}}}
|
|
4242
|
+
try{await this.ensureWorkspaceReady(t,o),this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready from env var",{requestId:t})}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: failed to ensure workspace",{requestId:t,error:(0,i.getErrorMessage)(e)})}}}}isActiveForAnySession(e){for(const[,t]of this.sessions)if(t.requestId===e)return!0
|
|
4243
|
+
return!1}async cleanup(){this.logger.info("Cleaning up multi-agent workspace manager"),this.sessions.clear()}}exports.MultiAgentWorkspaceManager=d,d.DEFAULT_SESSION="__default__"},7645(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionAwareClient=void 0
|
|
4281
4244
|
const r=t(4192),n=t(7163)
|
|
4282
4245
|
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
4246
|
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
|
|
@@ -4292,7 +4255,7 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4292
4255
|
var t={}
|
|
4293
4256
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
4294
4257
|
return o(t,e),t})
|
|
4295
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,t,r,n,o,s,g,f
|
|
4258
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,t,r,n,o,s,g,p,f){const m=g.child({tool:"manage_files"})
|
|
4296
4259
|
try{const h=a.validateArgs(e,i.ManageFilesSchema),{taskId:g,operations:y,comment:w}=h
|
|
4297
4260
|
m.info("Processing manage-files operations",{taskId:g,operationCount:y.length,comment:w})
|
|
4298
4261
|
const k=[],b=[],I=[],v=[]
|
|
@@ -4304,18 +4267,18 @@ case"delete-files":I.push(...e.deleteFiles.targets)
|
|
|
4304
4267
|
break
|
|
4305
4268
|
case"get-file-info":v.push({path:e.getFileInfo.path})}const C=[]
|
|
4306
4269
|
for(const e of k){m.info("Routing to create-directory handler",{path:e.path})
|
|
4307
|
-
const s=await(0,c.handleCreateDirectory)({taskId:g,path:e.path,comment:w+" [via manage-files: create-directory]"},t,r,n,o,m,f
|
|
4270
|
+
const s=await(0,c.handleCreateDirectory)({taskId:g,path:e.path,comment:w+" [via manage-files: create-directory]"},t,r,n,o,m,p,f)
|
|
4308
4271
|
C.push({type:"create-directory",result:s})}if(b.length>0){m.info("Routing to move-files handler",{operationCount:b.length})
|
|
4309
|
-
const e=await(0,l.handleMoveFiles)({taskId:g,operations:b,comment:w+" [via manage-files: move-files]"},t,r,n,o,m,f
|
|
4272
|
+
const e=await(0,l.handleMoveFiles)({taskId:g,operations:b,comment:w+" [via manage-files: move-files]"},t,r,n,o,m,p,f)
|
|
4310
4273
|
C.push({type:"move-files",result:e})}if(I.length>0){m.info("Routing to delete-files handler",{operationCount:I.length})
|
|
4311
|
-
const e=await(0,u.handleDeleteFiles)({taskId:g,operations:I,comment:w+" [via manage-files: delete-files]"},t,s,m,f
|
|
4274
|
+
const e=await(0,u.handleDeleteFiles)({taskId:g,operations:I,comment:w+" [via manage-files: delete-files]"},t,s,m,p,f)
|
|
4312
4275
|
C.push({type:"delete-files",result:e})}for(const e of v){m.info("Routing to get-file-info handler",{path:e.path})
|
|
4313
|
-
const r=await(0,d.handleGetFileInfo)({path:e.path},t,m,
|
|
4276
|
+
const r=await(0,d.handleGetFileInfo)({path:e.path},t,m,p)
|
|
4314
4277
|
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
|
|
4315
4278
|
let S="## Manage Files Results\n\n"
|
|
4316
4279
|
S+="**Summary:**\n",S+=`- **Total operation types:** ${C.length}\n`,S+=`- **Successful:** ${E}\n`,S+=`- **Failed:** ${q}\n\n`
|
|
4317
4280
|
for(const{type:e,result:t}of C)S+=`### ${e} operations\n`,S+=t.content[0].text+"\n\n"
|
|
4318
|
-
return m.info("Manage-files operations completed",{totalOperationTypes:C.length,successCount:E,errorCount:q}),
|
|
4281
|
+
return m.info("Manage-files operations completed",{totalOperationTypes:C.length,successCount:E,errorCount:q}),p.incrementCounter("manage_files_total",1,{success:!_}),{content:[{type:"text",text:S}],isError:_}}catch(e){return m.error("Manage-files operation failed",{error:e instanceof Error?e.stack:e+""}),p.incrementCounter("manage_files_errors",1),{content:[{type:"text",text:"\u274c **Manage Files Failed:** "+(0,h.getErrorMessage)(e)}],isError:!0}}}
|
|
4319
4282
|
const i=t(6183),a=s(t(5967)),c=t(8309),l=t(2414),d=t(3628),u=t(5992),h=t(8824)},7713(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4320
4283
|
const r=t(6183),n=t(5303)
|
|
4321
4284
|
exports.def={name:"plan_read",description:"Read project plans.\n\nOperations:\n\u2022 get - Get a plan by ID with full content\n\u2022 list - List all plans in the project\n\u2022 get-history - View version history of a plan\n\u2022 get-requests - List requests linked to a plan",schema:r.PlanReadSchema,annotations:{title:"Plan Read",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handlePlanRead)(e,t.context,t.apiClient,t.logger,t.metrics)}}},7784(e,exports,t){async function validateWorktreeForConflictResolution(e,r,s){const i=[],a=o.default.join(r,e),c="requests/"+e
|
|
@@ -4336,8 +4299,8 @@ const n=r(t(9896)),o=r(t(6928))},7834(e,exports,t){Object.defineProperty(exports
|
|
|
4336
4299
|
const r=t(5806),n=t(5715)
|
|
4337
4300
|
exports.def={name:"complete_request",description(e){return e.testsRequired?"Mark request as complete with test verification":"Mark request as complete (no test verification needed)"},schema(){return(0,r.getDynamicCompleteRequestSchema)()},annotations:{title:"Complete Request",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},hidden:!0,handler(e,t){return(0,n.handleCompleteRequest)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer,t.cliOrigin)}}},7849(e,exports,t){async function r(e,t,r,n,o,s,a,l,d,u){const h=Date.now()
|
|
4338
4301
|
if(!r||""===r.trim())throw new c.ValidationError("Project ID is required and cannot be empty for tool record creation")
|
|
4339
|
-
try{const c=await a.createToolRecord({taskId:e,requestId:t,projectId:r,type:n,metadata:{path:o,operation:n,status:"pending",timestamp:(new Date).toISOString(),fileExtension:i.default.extname(o).slice(1),fileOperationId:`${e}-${Date.now()}`,...s},note:`${"write-file"===n?"Writing":"Modifying"} file: ${o}`}),g=c.id,
|
|
4340
|
-
return l.info("Tool record created with IDs",{recordId:g,localRecordId:
|
|
4302
|
+
try{const c=await a.createToolRecord({taskId:e,requestId:t,projectId:r,type:n,metadata:{path:o,operation:n,status:"pending",timestamp:(new Date).toISOString(),fileExtension:i.default.extname(o).slice(1),fileOperationId:`${e}-${Date.now()}`,...s},note:`${"write-file"===n?"Writing":"Modifying"} file: ${o}`}),g=c.id,p=c.localId
|
|
4303
|
+
return l.info("Tool record created with IDs",{recordId:g,localRecordId:p,hasLocalId:!!c.localId,recordKeys:Object.keys(c),fullRecord:JSON.stringify(c)}),l.info("Created tool record for file operation: "+n,{taskId:e,projectId:r,path:o,recordId:g,localRecordId:p}),d.recordValue(u+"_tool_record_creation_time",Date.now()-h),d.incrementCounter(u+"_tool_record_creation_success",1),{recordId:g,localRecordId:p}}catch(t){d.incrementCounter(u+"_tool_record_creation_failure",1),d.recordValue(u+"_tool_record_creation_time",Date.now()-h)
|
|
4341
4304
|
const n=t instanceof Error?`${t.message} (${JSON.stringify(t)})`:t+""
|
|
4342
4305
|
return l.warn("Failed to create tool record for file operation: "+n,{taskId:e,projectId:r,path:o,error:t instanceof Error?t.stack:t+""}),{}}}async function n(e,t,r,n,o,s,a,c,l){const u=Date.now()
|
|
4343
4306
|
try{await s.updateToolRecord(e,{metadata:{path:t,operation:r,timestamp:(new Date).toISOString(),fileExtension:i.default.extname(t).slice(1),fileUpdateId:`${e}-${Date.now()}`,...n},note:o}),a.info("Updated tool record for file operation: "+r,{path:t,recordId:e,status:n.status}),c.recordValue(l+"_tool_record_update_time",Date.now()-u),c.incrementCounter(l+"_tool_record_update_success",1)}catch(n){c.incrementCounter(l+"_tool_record_update_failure",1),c.recordValue(l+"_tool_record_update_time",Date.now()-u),a.warn("Failed to update tool record for file operation: "+r,{path:t,recordId:e,error:(0,d.getErrorMessage)(n)})}}async function o(e,t,r,n,o){const{operationType:s,toolRecordId:i,successField:c,logger:l,metrics:u,metricsPrefix:h}=n
|
|
@@ -4350,35 +4313,35 @@ if(o.workspaceManager){const t=o.workspaceManager.getCurrentContext()
|
|
|
4350
4313
|
"multi-agent"===t.mode&&t.requestId&&(d=(0,a.simpleGit)(t.basePath),l.debug("Using WorkspaceManager git instance for multi-file commit",{taskId:e,mode:t.mode,requestId:t.requestId,basePath:t.basePath,branchName:t.branchName,filesCount:n.length}))}if(!d)return l.debug("No git repository available, skipping commit"),{filesCommitted:[],success:!0}
|
|
4351
4314
|
let g=null
|
|
4352
4315
|
try{g=(await d.revparse(["HEAD"])).trim()}catch(e){l.warn("Failed to get current commit hash",{error:e})}for(const e of n)await d.add(e)
|
|
4353
|
-
const
|
|
4354
|
-
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:
|
|
4316
|
+
const p=1===n.length?`${s} in ${n[0]} (${i})`:`${s} in ${n.length} files (${i})`,f=(await d.commit(p)).commit
|
|
4317
|
+
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:p,filesCommitted:n.length,commitHash:f?.substring(0,8),previousCommitHash:g?.substring(0,8),toolRecordId:i,operationType:s}),u.incrementCounter(h+"_git_commit_success",1),u.recordValue(h+"_files_committed",n.length),{commitHash:f,previousCommitHash:g,filesCommitted:n,success:!0}}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
4355
4318
|
return l.warn("Git operations failed via shared multi-file utility",{error:t,operationType:s,note:"File changes were saved but not committed to git"}),u.incrementCounter(h+"_git_commit_failure",1),{filesCommitted:[],success:!1,error:t}}}var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4356
4319
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.createToolRecord=r,exports.updateToolRecord=n,exports.createFileOperationRecords=async function(e,t,n,o,s,i,a,c,l,u,h){const g=Date.now()
|
|
4357
|
-
let f
|
|
4320
|
+
let p,f
|
|
4358
4321
|
l.debug("createFileOperationRecords called",{taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,operationType:o,path:s})
|
|
4359
4322
|
try{const a=await r(e,t,n,o,s,i,c,l,u,h)
|
|
4360
|
-
return
|
|
4323
|
+
return p=a.recordId,f=a.localRecordId,l.info("Created tool record for file operation: "+o,{taskId:e,path:s,toolRecordId:p,localToolRecordId:f}),{toolRecordId:p,localToolRecordId:f}}catch(r){throw l.error("Failed to create tool record for file operation: "+o,{error:(0,d.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0,taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,path:s}),u.recordValue(h+"_record_creation_time",Date.now()-g),u.incrementCounter(h+"_record_creation_error",1),r}},exports.updateFileOperationRecords=async function(e,t,r,o,s,i,a,c,l,u,h,g,p){try{t&&h.info("Task record update skipped (task records removed): "+t,{taskId:e,path:o}),r&&await n(r,o,s,a,c,u,h,g,p)}catch(t){h.warn("Error updating tool record for operation: "+s,{error:(0,d.getErrorMessage)(t),taskId:e,normalizedPath:o,toolRecordId:r})}},exports.checkAndCommitUserMods=async function(e,t,r,n,o){if(!t.git)return{hadUserMods:!1}
|
|
4361
4324
|
try{let s=t.git
|
|
4362
4325
|
if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
|
|
4363
4326
|
"multi-agent"===e.mode&&e.requestId&&(s=(0,a.simpleGit)(e.basePath))}if((await s.diff(["--name-only","HEAD","--",e])).trim().length>0){r.info(`File ${e} has uncommitted changes, preserving user modifications`),await s.add(e)
|
|
4364
4327
|
const t=await s.commit("[USER-MODS] Preserve user modifications before tool operation: "+e)
|
|
4365
4328
|
return r.info("Created user modifications commit",{filePath:e,userModsCommitHash:t.commit}),n.incrementCounter(o+"_user_mods_commits_created",1),{hadUserMods:!0,userModsCommitHash:t.commit}}return{hadUserMods:!1}}catch(t){return r.warn("Failed to check/preserve user modifications for "+e,{error:(0,d.getErrorMessage)(t)}),n.incrementCounter(o+"_user_mods_check_failures",1),{hadUserMods:!1}}},exports.commitToGit=async function(e,t,r,n,o,s,i,c,u){const h=Date.now()
|
|
4366
|
-
let g,
|
|
4367
|
-
try{let
|
|
4329
|
+
let g,p=null
|
|
4330
|
+
try{let f=s.git
|
|
4368
4331
|
if(s.workspaceManager){const t=s.workspaceManager.getCurrentContext()
|
|
4369
4332
|
if("multi-agent"===t.mode&&t.requestId){if(!t.basePath.includes("/worktrees/")&&!t.basePath.includes("\\worktrees\\"))throw i.error("CRITICAL BUG: Multi-agent mode but basePath is not a worktree path",{taskId:e,requestId:t.requestId,basePath:t.basePath,expectedPattern:"should contain /worktrees/ or \\worktrees\\",issue:"workspace_context_incorrect"}),Error(`Multi-agent mode context error: basePath '${t.basePath}' is not a worktree path. This will cause commits to go to main branch instead of the request branch.`)
|
|
4370
|
-
|
|
4333
|
+
f=(0,a.simpleGit)(t.basePath),i.debug("Using WorkspaceManager git instance for commit",{taskId:e,mode:t.mode,requestId:t.requestId,basePath:t.basePath,branchName:t.branchName,worktreeValidated:!0})}}if(f){i.info("commitToGit called with:",{taskId:e,recordId:r,localRecordId:n,hasLocalRecordId:!!n,localRecordIdType:typeof n,normalizedPath:t})
|
|
4371
4334
|
let a=!1,m=""
|
|
4372
|
-
try{if(m=(await
|
|
4335
|
+
try{if(m=(await f.raw(["rev-parse","--show-toplevel"])).trim(),a=m.includes("/worktrees/")||m.includes("\\worktrees\\"),i.info("Git context detection for commit operation:",{taskId:e,gitRepoPath:m,isWorktreeOperation:a,multiAgentMode:s.multiAgentMode,targetFile:t,expectedContext:s.multiAgentMode?"worktree":"main repo"}),s.multiAgentMode&&!a)throw i.error("CRITICAL: Multi-agent operation using main repo Git instead of worktree",{taskId:e,detectedPath:m,targetFile:t,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"unknown"}),Error(`Git context mismatch: Multi-agent operation attempted to commit ${t} using main repository Git instance at ${m}, but should use worktree Git instance. This will fail due to .gitignore rules.`)}catch(e){i.warn("Failed to get Git instance info:",{error:e instanceof Error?e.message:e+""})}try{const r=await f.revparse(["--abbrev-ref","HEAD"]),n=await f.revparse(["HEAD"]),o=await f.revparse(["--show-toplevel"])
|
|
4373
4336
|
i.info("Git repository status before commit:",{taskId:e,currentBranch:r.trim(),currentCommit:n.trim().substring(0,8),repoPath:o.trim(),targetFile:t,multiAgentMode:s.multiAgentMode||!1,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"none"})
|
|
4374
4337
|
const a=r.trim(),c=s.getCurrentRequestId?s.getCurrentRequestId():null
|
|
4375
4338
|
if(s.multiAgentMode&&c){const t="requests/"+c
|
|
4376
|
-
a!=="requests/"+c?i.warn("Multi-agent file operation may be on wrong branch",{taskId:e,actualBranch:a,expectedPattern:t,requestId:c}):i.info("Multi-agent file operation on expected branch",{taskId:e,branchName:a,requestId:c})}}catch(e){i.warn("Failed to get Git status before commit:",{error:e instanceof Error?e.message:e+""})}try{if(
|
|
4377
|
-
|
|
4378
|
-
await
|
|
4379
|
-
try{const r=await
|
|
4380
|
-
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(
|
|
4381
|
-
return{commitHash:g,previousCommitHash:
|
|
4339
|
+
a!=="requests/"+c?i.warn("Multi-agent file operation may be on wrong branch",{taskId:e,actualBranch:a,expectedPattern:t,requestId:c}):i.info("Multi-agent file operation on expected branch",{taskId:e,branchName:a,requestId:c})}}catch(e){i.warn("Failed to get Git status before commit:",{error:e instanceof Error?e.message:e+""})}try{if(f){const r=await f.revparse(["HEAD"])
|
|
4340
|
+
p=await(0,l.findPreviousCommit)(f,t,r),i.info(`Previous commit hash for ${t}: ${p||"none (new file)"}`,{taskId:e,gitInstancePath:m||"unknown",isWorktreeOperation:a,usingCorrectGitInstance:!0})}else i.warn("Git not available for previous commit detection: "+t,{taskId:e,reason:"no_git_instance"})}catch(e){i.warn(`Failed to find previous commit for ${t}:`,{error:(0,d.getErrorMessage)(e)})}const y=n?`[RECORD:${n}] ${o}`:o
|
|
4341
|
+
await f.add(t),g=(await f.commit(y)).commit
|
|
4342
|
+
try{const r=await f.revparse(["--abbrev-ref","HEAD"]),n=await f.revparse(["HEAD"])
|
|
4343
|
+
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(p||""),targetFile:t}),g&&n.trim()!==g&&i.warn("Commit hash mismatch after commit",{taskId:e,expectedCommitHash:g,actualHeadHash:n.trim(),targetFile:t})}catch(e){i.warn("Failed to verify post-commit status:",{error:e instanceof Error?e.message:e+""})}i.info("Committed file changes to Git: "+t,{taskId:e,path:t,recordId:r,localRecordId:n,commitHash:g,previousCommitHash:p}),c.recordValue(u+"_git_commit_time",Date.now()-h),c.incrementCounter(u+"_git_commit_success",1)}else i.warn("No Git repository available, skipping commit",{taskId:e,path:t})
|
|
4344
|
+
return{commitHash:g,previousCommitHash:p}}catch(r){return c.incrementCounter(u+"_git_commit_failure",1),c.recordValue(u+"_git_commit_time",Date.now()-h),i.warn("Failed to commit file changes to Git: "+t,{taskId:e,path:t,error:r instanceof Error?r.stack:r+""}),{commitHash:void 0,previousCommitHash:p}}},exports.commitMultipleFilesToGit=o,exports.handleMultiFileGitCommit=async function(e,t,r,n,s,i){const{logger:a,metricsPrefix:c,metrics:l}=s
|
|
4382
4345
|
return 0===t.length||0===n?(a.debug("No file operations with changes to commit"),{filesCommitted:[],success:!0}):(l.incrementCounter(c+"_phase",1,{phase:u.FileOperationPhase.GIT_COMMIT}),await o(e,t,r,s,i))}
|
|
4383
4346
|
const i=s(t(6928)),a=t(3807),c=t(9860),l=t(9671),d=t(8824),u=t(7575)},7960(e,exports){function t(){const e=process.argv[1]||""
|
|
4384
4347
|
if(e.includes("/dist-dev/")||e.includes("\\dist-dev\\"))return!0
|
|
@@ -4388,19 +4351,19 @@ return!(!t.includes("/dist-dev")&&!t.includes("\\dist-dev"))}Object.defineProper
|
|
|
4388
4351
|
if(r.debug("getClientInfoForMetadata called",{mcpServerExists:!!e,mcpServerType:typeof e,hasGetClientInfo:e?typeof e.getClientInfo:void 0,mcpServerKeys:e?Object.keys(e):void 0}),e&&"function"==typeof e.getClientInfo)try{t=e.getClientInfo(),r.debug("mcpServer.getClientInfo() returned",{clientInfo:t,clientInfoType:typeof t,name:t?.name,version:t?.version})}catch(e){r.debug("mcpServer.getClientInfo() failed",{error:e})}else r.debug("mcpServer not available or getClientInfo not a function")
|
|
4389
4352
|
const n={clientName:t.name,clientVersion:t.version}
|
|
4390
4353
|
return r.debug("getClientInfoForMetadata returning",{result:n}),n}
|
|
4391
|
-
const r=t(3444).defaultLogger.child({component:"client-info-utils"})},8035(e,exports,t){function r(e,t,r){try{const n=`[${(new Date).toISOString()}] [detached-subagent] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,a.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,i.appendFileSync)(o,n)}catch{}}function n(e){const{agent:t,prompt:n,cwd:
|
|
4354
|
+
const r=t(3444).defaultLogger.child({component:"client-info-utils"})},8035(e,exports,t){function r(e,t,r){try{const n=`[${(new Date).toISOString()}] [detached-subagent] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,a.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,i.appendFileSync)(o,n)}catch{}}function n(e){const{agent:t,prompt:n,cwd:l,parentServerUrl:d,parentSessionId:u,sessionId:h,model:g,initialBranch:p,serverUrl:f,onSpawn:m,onError:y}=e
|
|
4392
4355
|
try{const s={...process.env}
|
|
4393
|
-
|
|
4394
|
-
const
|
|
4395
|
-
let
|
|
4396
|
-
if(s.ALCHEMY_SESSION_TAG=`mcp-${
|
|
4397
|
-
e>0?
|
|
4398
|
-
const
|
|
4399
|
-
let
|
|
4400
|
-
try{
|
|
4401
|
-
return
|
|
4402
|
-
return
|
|
4403
|
-
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")
|
|
4356
|
+
d&&(s.OPENCODE_PARENT_SERVER=d),p&&(s.ALCHEMY_INITIAL_BRANCH=p),e.allowParallel&&(s.ALCHEMY_ALLOW_PARALLEL="1")
|
|
4357
|
+
const u=new Date,y=`${(u.getHours()+"").padStart(2,"0")}${(u.getMinutes()+"").padStart(2,"0")}${(u.getSeconds()+"").padStart(2,"0")}`,w=Math.random().toString(36).substring(2,7)
|
|
4358
|
+
let k
|
|
4359
|
+
if(s.ALCHEMY_SESSION_TAG=`mcp-${y}-${w}`,r(l,"Spawn env setup",{agent:t,initialBranch:p||"none",hasParentServer:!!d,sessionId:h||"new",attachMode:!!f}),k=f&&h&&n?["run","--attach",f,"--session",h,"--agent",t,n]:h&&n?["run","--session",h,"--agent",t,n]:n?["run","--agent",t,n]:["run","--agent",t],g){const e=k.findIndex((e=>e===n))
|
|
4360
|
+
e>0?k.splice(e,0,"--model",g):k.push("--model",g)}r(l,"Spawning opencode",{args:k.map((e=>e===n?`[prompt:${e.length}chars]`:e)),model:g||"not specified",promptLength:n?.length,promptPreview:n?.slice(0,100),cwd:l,hasSessionId:!!h,hasParentServerUrl:!!d})
|
|
4361
|
+
const b=(0,a.join)(l||process.cwd(),".alchemy_lab"),I=(0,a.join)(b,"spawn-stderr.log")
|
|
4362
|
+
let v
|
|
4363
|
+
try{v=(0,i.openSync)(I,"a")}catch{}const C=(0,c.resolveRunCommand)(),_=(0,o.spawn)(C.command,[...C.prependArgs,...k],{detached:!0,stdio:["ignore","ignore",v??"ignore"],cwd:l||process.cwd(),env:s})
|
|
4364
|
+
return _.unref(),m&&m(_.pid),{success:!0,pid:_.pid}}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
4365
|
+
return y&&e instanceof Error&&y(e),{success:!1,error:t}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=n,exports.spawnJournalSubagent=function(e,t,r,o){return n({agent:"journal",prompt:`Generate a journal entry for request ${e}.\n\nSteps:\n1. Use ${t}__generate_request_journal tool with requestId: ${e}\n2. Write a concise narrative journal entry based on the returned data covering:\n - What was implemented and why\n - Key decisions and trade-offs made\n - Challenges encountered and solutions\n - Files modified and their purposes\n - How acceptance criteria were met\n3. Save as JOURNAL-${e}.md using ${t}__document_operations (operation: create, type: Report)\n\nKeep it story-focused and informative.`,cwd:r,parentServerUrl:o})},exports.spawnWorkSubagent=function(e,t,r){return n({agent:"work",prompt:e,cwd:t,parentServerUrl:r})}
|
|
4366
|
+
const o=t(5317),s=t(8824),i=t(9896),a=t(6928),c=t(9068)},8037(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListRequests=async function(e,t,i,a,c){const l=a.child({tool:"list_requests"}),d=c.startTimer("tool_execution_time")
|
|
4404
4367
|
try{const{filters:s={}}=e,a=["open","in_progress","ready_for_review","completed","canceled","reverted"]
|
|
4405
4368
|
if(s.status&&!a.includes(s.status))throw new r.ValidationError(`Invalid status: ${s.status}. Must be one of: ${a.join(", ")}`)
|
|
4406
4369
|
if(void 0!==s.limit&&1>s.limit)throw new r.ValidationError("Limit must be at least 1")
|
|
@@ -4413,18 +4376,18 @@ s.status&&"undefined"!==s.status&&(u.status=s.status),s.type&&"undefined"!==s.ty
|
|
|
4413
4376
|
const h=i.getRequestClient(),g=await h.listRequests(u)
|
|
4414
4377
|
if(l.debug("=== RAW SERVER RESPONSE DEBUG ===",{responseType:typeof g,isArray:Array.isArray(g),responseKeys:g?Object.keys(g):[],fullResponse:JSON.stringify(g,null,2)}),g&&"object"==typeof g&&"data"in g){const e=g.data
|
|
4415
4378
|
l.debug("=== SERVER RESPONSE DATA SECTION ===",{dataType:typeof e,isDataArray:Array.isArray(e),dataLength:Array.isArray(e)?e.length:"not array",firstItemKeys:Array.isArray(e)&&e.length>0?Object.keys(e[0]):"no items",firstItemSample:Array.isArray(e)&&e.length>0?JSON.stringify(e[0],null,2):"no items"}),Array.isArray(e)&&e.length>0&&e.slice(0,3).forEach(((e,t)=>{l.info(`=== ITEM ${t+1} LOCK INFO CHECK ===`,{id:e.id,hasLockInfo:"lockInfo"in e,lockInfoValue:e.lockInfo,allKeys:Object.keys(e),lockRelatedKeys:Object.keys(e).filter((e=>e.toLowerCase().includes("lock")))})}))}l.debug("Raw requests response data",{responseData:JSON.stringify(g)}),l.debug("Requests response structure",{type:typeof g,isArray:Array.isArray(g),hasData:null!=g,properties:g?Object.keys(g):[],dataPreview:g?JSON.stringify(g).substring(0,200)+"...":"null"}),l.debug("=== BEFORE EXTRACTION ===",{responseHasData:g&&"data"in g,responseDataLength:g&&"data"in g&&Array.isArray(g.data)?g.data.length:"not array",firstItemBeforeExtraction:g&&"data"in g&&Array.isArray(g.data)&&g.data.length>0?{id:g.data[0].id,hasLockInfo:"lockInfo"in g.data[0],lockInfo:g.data[0].lockInfo,allKeys:Object.keys(g.data[0])}:"no data"})
|
|
4416
|
-
const
|
|
4417
|
-
l.info("=== AFTER EXTRACTION ===",{extractedCount:
|
|
4418
|
-
const
|
|
4419
|
-
if(l.debug("Lock info analysis",{multiAgentModeEnabled:
|
|
4420
|
-
l.info("=== PRE-DISPLAY REQUEST ANALYSIS ===",{totalRequests:
|
|
4421
|
-
const m=
|
|
4422
|
-
if(l.info(`=== FORMATTING REQUEST ${e.id} ===`,{multiAgentMode:
|
|
4379
|
+
const p=(0,n.extractArrayFromResponse)(g,{logger:l,operationName:"listRequests",defaultValue:[]})
|
|
4380
|
+
l.info("=== AFTER EXTRACTION ===",{extractedCount:p.length,firstItemAfterExtraction:p.length>0?{id:p[0].id,hasLockInfo:"lockInfo"in p[0],lockInfo:p[0].lockInfo,allKeys:Object.keys(p[0])}:"no items"}),l.info(`Extracted ${p.length} requests from response`)
|
|
4381
|
+
const f=t.multiAgentMode||!1
|
|
4382
|
+
if(l.debug("Lock info analysis",{multiAgentModeEnabled:f,requestCount:p.length,environmentVariable:process.env.ALCHEMY_MULTI_AGENT,firstRequestSample:p.length>0?{id:p[0].id,hasLockInfo:!!p[0].lockInfo,lockInfo:p[0].lockInfo,allProperties:Object.keys(p[0])}:"No requests to sample"}),p.length>0&&p.forEach(((e,t)=>{l.debug(`Request ${t+1} lock debug`,{id:e.id,title:e.title?.substring(0,50)+"...",hasLockInfo:!!e.lockInfo,lockInfoDetails:e.lockInfo||"NO LOCK INFO",allKeys:Object.keys(e).filter((e=>e.includes("lock")||e.includes("Lock")))})})),0===p.length)return d({success:!0,requestCount:0}),{content:[{type:"text",text:"No requests found with the specified filters."}]}
|
|
4383
|
+
l.info("=== PRE-DISPLAY REQUEST ANALYSIS ===",{totalRequests:p.length,multiAgentMode:f,environmentVar:process.env.ALCHEMY_MULTI_AGENT}),p.forEach(((e,t)=>{l.info(`=== REQUEST ${t+1}/${p.length} PRE-DISPLAY ANALYSIS ===`,{id:e.id,title:e.title?.substring(0,30)+"...",hasLockInfo:"lockInfo"in e,lockInfoType:typeof e.lockInfo,lockInfoValue:e.lockInfo,lockInfoIsNull:null===e.lockInfo,lockInfoIsUndefined:void 0===e.lockInfo,allProperties:Object.keys(e),lockRelatedProperties:Object.keys(e).filter((e=>e.toLowerCase().includes("lock")||e.toLowerCase().includes("session")||e.toLowerCase().includes("expire")))}),e.lockInfo&&l.info(`=== REQUEST ${e.id} LOCK INFO DEEP DIVE ===`,{lockInfoKeys:Object.keys(e.lockInfo),isLocked:e.lockInfo.isLocked,lockedBySessionTag:e.lockInfo.lockedBySessionTag,timeRemainingFormatted:e.lockInfo.timeRemainingFormatted,isExpired:e.lockInfo.isExpired,fullLockInfo:JSON.stringify(e.lockInfo,null,2)})}))
|
|
4384
|
+
const m=p.map((e=>{let t=""
|
|
4385
|
+
if(l.info(`=== FORMATTING REQUEST ${e.id} ===`,{multiAgentMode:f,hasLockInfo:!!e.lockInfo,lockInfoValue:e.lockInfo,willShowLockInfo:!!e.lockInfo,note:"Lock info displayed when available regardless of mode"}),e.lockInfo){if(l.debug(`Processing lock info for ${e.id}:`,e.lockInfo),e.lockInfo.isLocked&&!e.lockInfo.isExpired){const{sessionTag:r}=(0,o.getGlobalClientInfo)(),n=e.lockInfo.lockedBySessionTag||"unknown"
|
|
4423
4386
|
t=n===r?` [LOCKED by me, expires in ${e.lockInfo.timeRemainingFormatted}]`:` [LOCKED by ${n.length>20?n.substring(0,17)+"...":n}, expires in ${e.lockInfo.timeRemainingFormatted}]`}else t=" [AVAILABLE]"
|
|
4424
4387
|
l.debug(`Generated lock info for ${e.id}: "${t}"`)}else l.debug("No lock info available for "+e.id)
|
|
4425
|
-
return`**${e.title}** (${e.id}) [${e.type}]${t}\nStatus: ${e.status}\nType: ${e.type}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}\n`})).join("\n---\n"),y=
|
|
4426
|
-
let w=`Found ${
|
|
4427
|
-
return y&&
|
|
4388
|
+
return`**${e.title}** (${e.id}) [${e.type}]${t}\nStatus: ${e.status}\nType: ${e.type}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}\n`})).join("\n---\n"),y=p.some((e=>e.lockInfo))
|
|
4389
|
+
let w=`Found ${p.length} request${1===p.length?"":"s"}:`
|
|
4390
|
+
return y&&f&&(w+="\n\n**Lock Status:**\n",w+="LOCKED = Locked by an agent (shows session name and expiration)\n",w+="AVAILABLE = Not currently locked, safe to work on\n"),d({success:!0,requestCount:p.length}),{content:[{type:"text",text:`${w}\n\n${m}`}]}}catch(t){return l.error("Error listing requests",{args:e,error:t instanceof Error?t.stack:t+""}),d({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:"Error listing requests: "+(0,s.getErrorMessage)(t)}],isError:!0}}}
|
|
4428
4391
|
const r=t(9860),n=t(2960),o=t(5172),s=t(8824)},8045(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4429
4392
|
const r=t(6183),n=t(7456)
|
|
4430
4393
|
exports.def={name:"modify_file",description:'Make targeted edits to existing files and documents.\n\nOperations:\n\u2022 replace-string - Find and replace text\n - mode: \'unique\' (default, safer - fails if multiple matches)\n - mode: \'all\' (replaces all occurrences)\n\u2022 delete-string - Remove text patterns (same modes as replace-string)\n\u2022 insert-lines - Insert content before/after/between lines\n\u2022 replace-lines - Replace specific line numbers\n\u2022 delete-lines - Remove specific line numbers\n\nLine specification (string format for line-based operations):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "10-15"\n\nRead file first to know line numbers. Supports multiple files and operations in one call. Works with both filesystem files (path) and tracked documents (documentId).',schema:r.ModifyFileSchema,annotations:{title:"Modify File",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},hidden:!0,handler(e,t){return(0,n.handleModifyFile)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},8291(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
@@ -4451,33 +4414,33 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4451
4414
|
var t={}
|
|
4452
4415
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
4453
4416
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4454
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,t,r,n,o,s,i,
|
|
4417
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,t,r,n,o,s,i,p){const f=s.child({tool:"create_directory"}),m=Date.now()
|
|
4455
4418
|
let y,w,k=d.FileOperationPhase.VALIDATION
|
|
4456
4419
|
const b={toolName:"create-directory",operationName:"create",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"create-directory",metricsPrefix:"create_directory",successMessage:"Successfully created directory {path}",failureMessage:"Failed to create directory {path}"}
|
|
4457
4420
|
try{const s=d.validateArgs(e,l.CreateDirectorySchema),{taskId:u,path:h,comment:g}=s
|
|
4458
|
-
|
|
4421
|
+
f.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,f,i,b.metricsPrefix),t.getCurrentBranchContext&&await t.getCurrentBranchContext()
|
|
4459
4422
|
const{normalizedPath:I,fullPath:v}=d.validateAndNormalizePath(h,t)
|
|
4460
4423
|
k=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("create_directory_phase",1,{phase:k})
|
|
4461
|
-
const C=await d.validateTaskId(u,I,r,
|
|
4462
|
-
q.taskPromoted&&
|
|
4463
|
-
const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:
|
|
4424
|
+
const C=await d.validateTaskId(u,I,r,f,i,b.metricsPrefix),_=C?.requestId,E=await d.validateWorkItemStates(u,I,r,o,t,f,i,b.metricsPrefix),q=await d.autoPromoteTaskStatus(u,C.status,_,E.request?.status,I,r,o,f,i,b.metricsPrefix)
|
|
4425
|
+
q.taskPromoted&&f.info(`Auto-promoted task ${u} (${C.title||"Untitled"}) to in_progress for file operation`,{taskId:u,taskTitle:C.title,previousStatus:C.status,newStatus:q.newTaskStatus,path:I}),q.requestPromoted&&f.info(`Auto-promoted request ${_} to in_progress for file operation`,{requestId:_,previousStatus:E.request?.status,newStatus:q.newRequestStatus,triggeringTaskId:u})
|
|
4426
|
+
const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:f,metrics:i,metricsPrefix:b.metricsPrefix})
|
|
4464
4427
|
if(!S.success){if(S.isLockConflict)return{content:[{type:"text",text:"\u274c "+S.error}],isError:!0}
|
|
4465
4428
|
throw Error(S.error)}let T=!1
|
|
4466
4429
|
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,b.recordType,I,{directoryExists:T,userComment:g},r,n,
|
|
4430
|
+
const{toolRecordId:M,localToolRecordId:R}=await d.createFileOperationRecords(u,_,t.projectId,b.recordType,I,{directoryExists:T,userComment:g},r,n,f,i,b.metricsPrefix,p)
|
|
4468
4431
|
y=M,w=M,k=b.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:k})
|
|
4469
4432
|
let P=T
|
|
4470
|
-
if(!T){await a.default.mkdir(v,{recursive:!0}),
|
|
4433
|
+
if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+I)
|
|
4471
4434
|
try{const e=c.default.join(v,".gitkeep")
|
|
4472
|
-
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),P=!0,
|
|
4435
|
+
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),P=!0,f.info("Created .gitkeep file for Git tracking")}catch(e){f.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),P=!1}}const x=Date.now()-m
|
|
4473
4436
|
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: ${I} - ${g||"Create directory"}`,j=!T&&P?I+"/.gitkeep":I,$=await d.commitToGit(u,j,M,R,O,t,
|
|
4475
|
-
k=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:k}),await d.updateFileOperationRecords(u,y,w,I,b.recordType,`Successfully ${T?"verified":"created"} directory: ${I}`,{status:"completed",commitHash:$.commitHash,previousCommitHash:$.previousCommitHash,directoryExists:T,isDirectory:!0,userComment:g},`Successfully ${T?"verified":"created"} directory: ${I}`,r,n,
|
|
4437
|
+
const O=`Create directory: ${I} - ${g||"Create directory"}`,j=!T&&P?I+"/.gitkeep":I,$=await d.commitToGit(u,j,M,R,O,t,f,i,b.metricsPrefix)
|
|
4438
|
+
k=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:k}),await d.updateFileOperationRecords(u,y,w,I,b.recordType,`Successfully ${T?"verified":"created"} directory: ${I}`,{status:"completed",commitHash:$.commitHash,previousCommitHash:$.previousCommitHash,directoryExists:T,isDirectory:!0,userComment:g},`Successfully ${T?"verified":"created"} directory: ${I}`,r,n,f,i,b.metricsPrefix)
|
|
4476
4439
|
const D=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4477
4440
|
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
|
-
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){
|
|
4479
|
-
if(i.recordValue("create_directory_time",s),i.incrementCounter("create_directory_errors",1),
|
|
4480
|
-
try{await d.updateFileOperationRecords(e.taskId,y,w,e.path,b.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,g.getErrorMessage)(o),userComment:e.comment},"Failed to create directory "+e.path,r,n,
|
|
4441
|
+
await n.createToolRecord({...r?{}:{taskId:e.taskId},projectId:t.projectId,type:"create-directory",metadata:{status:"failed",timestamp:(new Date).toISOString(),path:e.path,userComment:e.comment,error:(0,g.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:k,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:`Failed to create directory ${e.path} - ${(0,g.getErrorMessage)(o)}`})}catch(t){f.error("Failed to create failure record for create directory operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,path:e.path})}const s=Date.now()-m
|
|
4442
|
+
if(i.recordValue("create_directory_time",s),i.incrementCounter("create_directory_errors",1),f.error("Error creating directory:",{error:(0,g.getErrorMessage)(o),time:s}),(y||w)&&e.taskId){k=d.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
4443
|
+
try{await d.updateFileOperationRecords(e.taskId,y,w,e.path,b.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,g.getErrorMessage)(o),userComment:e.comment},"Failed to create directory "+e.path,r,n,f,i,b.metricsPrefix)}catch(t){f.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,k,f,i,e,b)}}
|
|
4481
4444
|
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
4445
|
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
4446
|
case"replace-in-files":return"\u{1f504} Replace in Files"
|
|
@@ -4485,11 +4448,11 @@ case"move-files":return"\u{1f4cb} Move Files"
|
|
|
4485
4448
|
case"delete-files":return"\u{1f5d1}\ufe0f Delete Files"
|
|
4486
4449
|
case"manage-files":return"\u{1f4c1} Manage Files"
|
|
4487
4450
|
default:return e}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestFileHistory=async function(e,t,a,c,l){const d=c.child({tool:"request_file_history"}),u=l.startTimer("tool_execution_time")
|
|
4488
|
-
try{const{requestId:c,detailLevel:h="summary",taskId:g,showDiff:
|
|
4451
|
+
try{const{requestId:c,detailLevel:h="summary",taskId:g,showDiff:p=!1,fileFilter:f}=e
|
|
4489
4452
|
if(!c)throw(0,o.createValidationError)("Request ID is required")
|
|
4490
4453
|
if(!/^req[_\d].+$/.test(c))throw(0,o.createValidationError)(`Invalid request ID format: ${c}. Expected format: req_[26 chars] or req######`)
|
|
4491
4454
|
if(g&&!/^tas\d{6}$/.test(g))throw(0,o.createValidationError)(`Invalid task ID format: ${g}. Expected format: tas######`)
|
|
4492
|
-
if(d.info("Getting file changes for request "+c,{detailLevel:h,taskId:g,showDiff:
|
|
4455
|
+
if(d.info("Getting file changes for request "+c,{detailLevel:h,taskId:g,showDiff:p}),!t.git)throw Error("Git integration not available in this context")
|
|
4493
4456
|
const m=t.projectId
|
|
4494
4457
|
let y
|
|
4495
4458
|
a.setProjectId(m)
|
|
@@ -4512,7 +4475,7 @@ let r=0
|
|
|
4512
4475
|
e.forEach((e=>{e.replacements&&(r+=e.replacements.length)})),d+=`**Replacements**: ${r}\n`}if(t.metadata?.commitHash&&(d+=`**Commit**: ${t.metadata.commitHash.substring(0,8)}\n`,s||5>=h.length))try{const e=await a.diff([t.metadata.commitHash+"^",t.metadata.commitHash])
|
|
4513
4476
|
if(e&&e.trim()){const r=500,n=e.length
|
|
4514
4477
|
if(n>r){const o=e.substring(0,r),s=(n/1024).toFixed(1)
|
|
4515
|
-
d+=`\n**Changes preview** (first ${r} chars):\n\`\`\`diff\n${o}\n\`\`\`\n`,d+=`... (diff truncated, ${s}KB total)\n`,d+=`\u{1f4a1} Use \`file-history\` tool with commit \`${t.metadata.commitHash.substring(0,8)}\` to see full diff\n`}else d+=`\n**Changes:**\n\`\`\`diff\n${e}\n\`\`\`\n`}}catch(e){c.debug("Could not fetch diff for commit",{commit:t.metadata.commitHash,error:(0,i.getErrorMessage)(e)})}d+="\n---\n\n"}return d}(y,o,g,
|
|
4478
|
+
d+=`\n**Changes preview** (first ${r} chars):\n\`\`\`diff\n${o}\n\`\`\`\n`,d+=`... (diff truncated, ${s}KB total)\n`,d+=`\u{1f4a1} Use \`file-history\` tool with commit \`${t.metadata.commitHash.substring(0,8)}\` to see full diff\n`}else d+=`\n**Changes:**\n\`\`\`diff\n${e}\n\`\`\`\n`}}catch(e){c.debug("Could not fetch diff for commit",{commit:t.metadata.commitHash,error:(0,i.getErrorMessage)(e)})}d+="\n---\n\n"}return d}(y,o,g,p,t.git,d,f)
|
|
4516
4479
|
return u({success:!0,recordCount:o.length}),{content:[{type:"text",text:s}]}}{const e=a.getToolRecordClient()
|
|
4517
4480
|
let n=[]
|
|
4518
4481
|
try{g?(n=await e.getToolRecordsByTaskId(g),d.info(`Fetched ${n.length} records for task ${g}`)):(n=await e.getToolRecordsByRequestId(c),d.info(`Fetched ${n.length} records for request ${c}`))}catch(e){d.warn("Error fetching tool records: "+(0,i.getErrorMessage)(e)),n=[]}const o=await async function(e,t){const n=new Map
|
|
@@ -4522,7 +4485,7 @@ if(!["write-file","replace-in-files","move-files","delete-files","manage-files"]
|
|
|
4522
4485
|
o++
|
|
4523
4486
|
const i=r(s)
|
|
4524
4487
|
for(const e of i)t&&!RegExp(t.replace(/\./g,"\\.").replace(/\*/g,".*").replace(/\?/g,".")).test(e)||n.has(e)||n.set(e,{path:e,status:"M",linesAdded:0,linesDeleted:0,isBinary:!1})}const s=Array.from(n.values())
|
|
4525
|
-
return{summary:{filesChanged:s.length,linesAdded:0,linesDeleted:0,binaryFiles:0,renamedFiles:0,totalCommits:o,timespan:void 0},files:s}}(n,
|
|
4488
|
+
return{summary:{filesChanged:s.length,linesAdded:0,linesDeleted:0,binaryFiles:0,renamedFiles:0,totalCommits:o,timespan:void 0},files:s}}(n,f,t.git),s=function(e,t,r){const{requestInfo:n,branchInfo:o,summary:s,files:i,commits:a}=e
|
|
4526
4489
|
let c=`# File Changes for Request: ${n.id}\n\n`
|
|
4527
4490
|
if("Unknown Request"===n.title&&"unknown"===n.status||(c+=`**Request:** ${n.title}\n`,"unknown"!==n.status&&(c+=`**Status:** ${n.status}\n`),c+="\n"),r&&(c+=`**Filter:** \`${r}\`\n`),c+=`**Files Changed:** ${s.filesChanged}\n`,s.filesChanged>0&&(c+=`**Changes:** +${s.linesAdded} -${s.linesDeleted} lines\n`,s.totalCommits>0&&(c+=`**Commits:** ${s.totalCommits}\n`)),c+="\n",0===i.length)c+="No file changes found.\n\n"
|
|
4528
4491
|
else{const e=50,t=i.slice(0,e),r=i.length-e
|
|
@@ -4532,7 +4495,7 @@ case"D":return"\u{1f5d1}\ufe0f"
|
|
|
4532
4495
|
case"R":return"\u{1f4cb}"
|
|
4533
4496
|
case"C":return"\u{1f4d1}"
|
|
4534
4497
|
case"T":return"\u{1f504}"}}(e.status)
|
|
4535
|
-
c+=`- ${t} ${e.path}`,e.renamedFrom&&(c+=` (renamed from ${e.renamedFrom})`),c+="\n"})),r>0&&(c+=`\n... and ${r} more file${1===r?"":"s"}\n`,c+="\n\u{1f4a1} Use fileFilter to narrow results or use detailed mode to see all files.\n"),c+="\n"}return c}({requestInfo:y,branchInfo:{branchName:"requests/"+c,baseCommit:"",headCommit:"",exists:!1,isCompleted:"completed"===y.status},summary:o.summary,files:o.files,commits:[]},0,
|
|
4498
|
+
c+=`- ${t} ${e.path}`,e.renamedFrom&&(c+=` (renamed from ${e.renamedFrom})`),c+="\n"})),r>0&&(c+=`\n... and ${r} more file${1===r?"":"s"}\n`,c+="\n\u{1f4a1} Use fileFilter to narrow results or use detailed mode to see all files.\n"),c+="\n"}return c}({requestInfo:y,branchInfo:{branchName:"requests/"+c,baseCommit:"",headCommit:"",exists:!1,isCompleted:"completed"===y.status},summary:o.summary,files:o.files,commits:[]},0,f)
|
|
4536
4499
|
return u({success:!0,filesChanged:o.summary.filesChanged}),{content:[{type:"text",text:s}]}}}catch(e){return d.error("Error in request file history tool",{error:e instanceof Error?e.stack:e+""}),u({success:!1,error:e instanceof Error?e.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
|
|
4537
4500
|
const o=t(9860),s=t(2960),i=t(8824)},8349(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDebugGitLog=async function(e,t){try{if(!t.git)return{content:[{type:"text",text:"No git repository available"}]}
|
|
4538
4501
|
const e=await t.git.log(),r="req000010",n=e.all.filter((e=>e.message.includes(r))),o=e.all.filter((e=>e.message.toLowerCase().includes("merge"))),s=e.all.slice(0,10)
|
|
@@ -4550,28 +4513,28 @@ o+=`**${t}** \u2014 ${e.filename}\n`,o+=` Updated: ${r}\n`,n&&(o+=` ${n}\n`),o
|
|
|
4550
4513
|
const r=t(8824)},8411(e,exports,t){function r(e){if(!a.default.existsSync(e))return null
|
|
4551
4514
|
try{const t=a.default.readFileSync(e,"utf8").trim()
|
|
4552
4515
|
try{const e=JSON.parse(t)
|
|
4553
|
-
return
|
|
4554
|
-
if(isNaN(e))return
|
|
4516
|
+
return p.debug("Read JSON lock data",e),e}catch{const e=parseInt(t,10)
|
|
4517
|
+
if(isNaN(e))return p.warn("Invalid lock file content",{content:t}),null
|
|
4555
4518
|
const r={mode:"single-agent",created:(new Date).toISOString(),hostname:"unknown",pid:e}
|
|
4556
|
-
return
|
|
4519
|
+
return p.debug("Read legacy PID lock data",r),r}}catch(e){return p.error("Error reading lock file",{error:(0,h.getErrorMessage)(e)}),null}}function n(e){try{return process.kill(e,0),!0}catch{return!1}}function o(e,t,n,o,i){try{const c={mode:i?"multi-agent":"single-agent",created:o,hostname:l.default.hostname(),...i?{}:{pid:n}}
|
|
4557
4520
|
if(a.default.writeFileSync(e,JSON.stringify(c,null,2)),i){const r={count:1,processes:[{pid:n,started:o}]}
|
|
4558
4521
|
a.default.writeFileSync(t,JSON.stringify(r,null,2)),s(e,t,n)}else!function(e,t){["SIGINT","SIGTERM","exit"].forEach((n=>{process.on(n,(()=>{try{if(a.default.existsSync(e)){const o=r(e)
|
|
4559
|
-
o&&o.pid===t&&(a.default.unlinkSync(e),
|
|
4560
|
-
return
|
|
4561
|
-
s.processes=s.processes.filter((e=>e.pid!==r)),s.count=s.processes.length,s.count>0?(a.default.writeFileSync(t,JSON.stringify(s,null,2)),
|
|
4522
|
+
o&&o.pid===t&&(a.default.unlinkSync(e),p.debug("Removed single-agent lock file",{signal:n,pid:t}))}}catch(e){p.error("Error removing single-agent lock file",{error:e instanceof Error?e.message:e+"",signal:n})}"exit"!==n&&process.exit(0)}))}))}(e,n)
|
|
4523
|
+
return p.info("Created new lock",{mode:c.mode,pid:n}),!0}catch(e){return p.error("Error creating new lock",{error:(0,h.getErrorMessage)(e)}),!1}}function s(e,t,r){["SIGINT","SIGTERM","exit"].forEach((n=>{process.on(n,(()=>{try{if(a.default.existsSync(t)){const o=a.default.readFileSync(t,"utf8"),s=JSON.parse(o)
|
|
4524
|
+
s.processes=s.processes.filter((e=>e.pid!==r)),s.count=s.processes.length,s.count>0?(a.default.writeFileSync(t,JSON.stringify(s,null,2)),p.debug("Removed process from multi-agent references",{signal:n,pid:r,remaining:s.count})):(a.default.unlinkSync(t),a.default.existsSync(e)&&a.default.unlinkSync(e),p.debug("Removed multi-agent lock files (last process)",{signal:n,pid:r}))}}catch(e){p.error("Error removing multi-agent lock files",{error:e instanceof Error?e.message:e+"",signal:n})}"exit"!==n&&process.exit(0)}))}))}var i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4562
4525
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.acquireProcessLock=function(e,t=!1){const i=c.default.join(e,d.ALCHEMY_DIR_NAME)
|
|
4563
|
-
let u,
|
|
4564
|
-
try{a.default.existsSync(i)||(a.default.mkdirSync(i,{recursive:!0}),
|
|
4526
|
+
let u,f
|
|
4527
|
+
try{a.default.existsSync(i)||(a.default.mkdirSync(i,{recursive:!0}),p.debug(`Created ${d.ALCHEMY_DIR_NAME} directory for lock file`,{alchemyLabDir:i})),u=c.default.join(i,".mcp-server.lock"),f=c.default.join(i,".mcp-agents.refs"),p.debug(`Using ${d.ALCHEMY_DIR_NAME} directory for lock files`,{lockFilePath:u,refsFilePath:f})}catch(t){p.error(`Failed to create ${d.ALCHEMY_DIR_NAME} directory`,{alchemyLabDir:i,error:t instanceof Error?t.message:t+""}),u=c.default.join(e,".mcp-server.lock"),f=c.default.join(e,".mcp-agents.refs"),p.warn("Falling back to base directory for lock files",{lockFilePath:u,refsFilePath:f})}const m=process.pid,y=(new Date).toISOString()
|
|
4565
4528
|
try{const e=r(u)
|
|
4566
|
-
if(
|
|
4529
|
+
if(p.info("Lock acquisition attempt",{pid:m,multiAgentMode:t,lockFilePath:u,lockExists:!!e,lockData:e?{mode:e.mode,pid:e.pid,hostname:e.hostname,created:e.created}:null}),!e)return p.info("No existing lock - creating new lock",{pid:m,mode:t?"multi-agent":"single-agent"}),o(u,f,m,y,t)
|
|
4567
4530
|
{const r=Date.now()-new Date(e.created).getTime(),i=r>g,c=l.default.hostname(),d=e.hostname!==c&&"unknown"!==e.hostname
|
|
4568
|
-
if(i)return
|
|
4569
|
-
if(d)return
|
|
4570
|
-
if("single-agent"===e.mode)return e.pid===m?(
|
|
4531
|
+
if(i)return p.warn("\u26a0\ufe0f Clearing stale lock (older than 24 hours)",{lockAge:Math.round(r/1e3/60/60)+" hours",lockCreated:e.created,lockHostname:e.hostname}),o(u,f,m,y,t)
|
|
4532
|
+
if(d)return p.warn("\u26a0\ufe0f Clearing lock from different machine",{lockHostname:e.hostname,currentHostname:c}),o(u,f,m,y,t)
|
|
4533
|
+
if("single-agent"===e.mode)return e.pid===m?(p.debug("Same process already has lock",{pid:m}),!0):n(e.pid)?(p.warn("Cannot acquire lock - single-agent mode active",{existingPid:e.pid,currentPid:m,requestedMode:t?"multi-agent":"single-agent"}),!1):(p.info("Taking over lock from dead single-agent process",{deadPid:e.pid,currentPid:m,newMode:t?"multi-agent":"single-agent"}),o(u,f,m,y,t))
|
|
4571
4534
|
if("multi-agent"===e.mode)return t?function(e,t,r){try{let o={count:0,processes:[]}
|
|
4572
4535
|
if(a.default.existsSync(e)){const t=a.default.readFileSync(e,"utf8")
|
|
4573
|
-
o=JSON.parse(t),o.processes=o.processes.filter((e=>n(e.pid))),o.count=o.processes.length}return o.processes.push({pid:t,started:r}),o.count=o.processes.length,a.default.writeFileSync(e,JSON.stringify(o,null,2)),s(e.replace(".mcp-agents.refs",".mcp-server.lock"),e,t),
|
|
4574
|
-
const a=i(t(9896)),c=i(t(6928)),l=i(t(857)),d=t(4139),u=t(3444),h=t(8824),g=864e5,
|
|
4536
|
+
o=JSON.parse(t),o.processes=o.processes.filter((e=>n(e.pid))),o.count=o.processes.length}return o.processes.push({pid:t,started:r}),o.count=o.processes.length,a.default.writeFileSync(e,JSON.stringify(o,null,2)),s(e.replace(".mcp-agents.refs",".mcp-server.lock"),e,t),p.info("Joined multi-agent lock",{pid:t,totalAgents:o.count}),!0}catch(e){return p.error("Error joining multi-agent lock",{error:(0,h.getErrorMessage)(e)}),!1}}(f,m,y):(p.warn("Cannot acquire lock - multi-agent mode active",{currentPid:m,requestedMode:"single-agent"}),!1)}return!1}catch(e){return p.error("Error acquiring lock",{error:(0,h.getErrorMessage)(e),pid:m}),!1}}
|
|
4537
|
+
const a=i(t(9896)),c=i(t(6928)),l=i(t(857)),d=t(4139),u=t(3444),h=t(8824),g=864e5,p=(0,u.createLogger)({serviceName:"process-lock",level:u.LogLevel.DEBUG,logToFile:!1})},8451(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatFileSize=function(e){return 1024>e?e+" bytes":1048576>e?(e/1024).toFixed(2)+" KB":1073741824>e?(e/1048576).toFixed(2)+" MB":(e/1073741824).toFixed(2)+" GB"},exports.truncate=function(e,t){return e.length>t?e.substring(0,t-3)+"...":e},exports.escapeRegExp=function(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},exports.countOccurrences=function(e,t){if(0===t.length)return 0
|
|
4575
4538
|
let r=0,n=0
|
|
4576
4539
|
for(;n=e.indexOf(t,n),-1!==n;)r++,n+=t.length
|
|
4577
4540
|
return r},exports.handleFileOperationError=function(e,t,n,o,s,i){n.error(`${i.toolName} operation failed in phase: ${t}`,{args:s,phase:t,error:e instanceof Error?e.stack:e+""})
|
|
@@ -4612,27 +4575,27 @@ const o=new Set(["py","python","yaml","yml","pug","jade","haml","slim","sass","s
|
|
|
4612
4575
|
if(!t)throw Error(`Tool "${e}" does not have a defined RecordType mapping. This is a type safety violation. Please add this tool to the TOOL_NAME_TO_RECORD_TYPE_MAP in failure-record-utils.ts.`)
|
|
4613
4576
|
return t}function n(e){return!!e&&/^tas\d{6}$/.test(e)}function o(e){return!!e&&(/^req\d{6}$/.test(e)||/^req_[\w-]+$/.test(e))}function s(e){return!!e&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.toolNameToRecordType=r,exports.isValidTaskId=n,exports.isValidRequestId=o,exports.isValidProjectId=s,exports.createFailureToolRecord=async function(e,t,a,c,l,d,u){if(!c)return void l.warn("ToolRecordClient is not available, skipping failure record creation for "+e)
|
|
4614
4577
|
if(!s(u.projectId)){const t=Error(`Invalid projectId format: ${u.projectId}. Cannot create failure record without valid projectId.`)
|
|
4615
|
-
throw l.error("Cannot create failure record due to invalid projectId",{toolName:e,projectId:u.projectId,error:t.message}),t}const h=Date.now(),g=e.replace(/-/g,"_"),
|
|
4578
|
+
throw l.error("Cannot create failure record due to invalid projectId",{toolName:e,projectId:u.projectId,error:t.message}),t}const h=Date.now(),g=e.replace(/-/g,"_"),p=(0,i.getErrorMessage)(t),f=t instanceof Error?t.stack:void 0
|
|
4616
4579
|
try{const t=r(e),s={}
|
|
4617
4580
|
let i,m
|
|
4618
4581
|
u.taskId&&(n(u.taskId)?i=u.taskId:(s.taskId=u.taskId,l.warn(`Invalid taskId format: ${u.taskId}, not associating failure record with this ID`,{toolName:e,invalidTaskId:u.taskId}))),u.requestId&&(o(u.requestId)?m=u.requestId:(s.requestId=u.requestId,l.warn(`Invalid requestId format: ${u.requestId}, not associating failure record with this ID`,{toolName:e,invalidRequestId:u.requestId})))
|
|
4619
|
-
let y=u.note||`Failed to execute ${e}: ${
|
|
4582
|
+
let y=u.note||`Failed to execute ${e}: ${p.substring(0,100)}${p.length>100?"...":""}`
|
|
4620
4583
|
Object.keys(s).length>0&&(y+=` (Warning: Invalid IDs provided: ${Object.entries(s).map((([e,t])=>`${e}: ${t}`)).join(", ")})`)
|
|
4621
|
-
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:
|
|
4622
|
-
i&&(w.taskId=i),m&&(w.requestId=m),l.info("Creating failure tool record for "+e,{toolName:e,recordType:w.type,...i&&{taskId:i},...m&&{requestId:m},projectId:u.projectId,invalidIds:Object.keys(s).length>0?s:void 0,error:
|
|
4584
|
+
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:p,errorStack:f,originalToolName:e,timestamp:(new Date).toISOString(),invalidIds:Object.keys(s).length>0?s:void 0,...a}}
|
|
4585
|
+
i&&(w.taskId=i),m&&(w.requestId=m),l.info("Creating failure tool record for "+e,{toolName:e,recordType:w.type,...i&&{taskId:i},...m&&{requestId:m},projectId:u.projectId,invalidIds:Object.keys(s).length>0?s:void 0,error:p})
|
|
4623
4586
|
const k=await c.createToolRecord(w)
|
|
4624
|
-
d.recordValue(g+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(g+"_failure_record_creation_success",1),l.info("Successfully created failure tool record for "+e,{toolName:e,recordType:w.type,...i&&{taskId:i},...m&&{requestId:m},projectId:u.projectId,toolRecordId:k.id})}catch(t){throw d.recordValue(g+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(g+"_failure_record_creation_failure",1),l.error("Failed to create failure tool record for "+e,{error:t instanceof Error?t.stack:t+"",toolName:e,...u.taskId&&{originalTaskId:u.taskId},...u.requestId&&{originalRequestId:u.requestId},projectId:u.projectId,originalError:
|
|
4587
|
+
d.recordValue(g+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(g+"_failure_record_creation_success",1),l.info("Successfully created failure tool record for "+e,{toolName:e,recordType:w.type,...i&&{taskId:i},...m&&{requestId:m},projectId:u.projectId,toolRecordId:k.id})}catch(t){throw d.recordValue(g+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(g+"_failure_record_creation_failure",1),l.error("Failed to create failure tool record for "+e,{error:t instanceof Error?t.stack:t+"",toolName:e,...u.taskId&&{originalTaskId:u.taskId},...u.requestId&&{originalRequestId:u.requestId},projectId:u.projectId,originalError:p}),t}}
|
|
4625
4588
|
const i=t(8824),a={write_file:"write-file","delete-file":"delete-file",delete_files:"delete-files",move_files:"move-files","replace-string":"replace-string",replace_strings:"replace-strings",insert_lines:"insert-lines",replace_lines:"replace-lines","file-recover":"file-recover",complete_task:"complete-task","update-task-status":"update-task-status","create-task":"create-task",create_request:"create-request",complete_request:"complete-request",read_files:"discovery","list-directory":"discovery",search:"discovery",file_history:"discovery",request_file_history:"discovery",get_request_information:"discovery",get_task_information:"discovery",list_requests:"discovery",list_tasks:"discovery",create_directory:"write",authenticate:"discovery","find-previous-commit":"discovery"}},8625(e,exports,t){function r(e,t,r){const n=exports.ERROR_TYPE_PROPERTIES[e]||exports.ERROR_TYPE_PROPERTIES[i.INTERNAL_ERROR]
|
|
4626
4589
|
return{success:!1,error:{code:e,message:t||n.defaultMessage,details:r,retryable:n.retryable,statusCode:n.statusCode}}}function n(e){return"object"==typeof e&&null!==e&&"code"in e&&"statusCode"in e&&"details"in e&&"retryable"in e&&"string"==typeof e.code&&"number"==typeof e.statusCode}function o(e){if(n(e)){const t=r(e.code,e.message,e.details)
|
|
4627
4590
|
return{statusCode:e.statusCode,body:t}}if(e instanceof Error&&"ConnectionError"===e.name){const t=e
|
|
4628
4591
|
return{statusCode:503,body:r("CONNECTION_ERROR",t.message||"Connection to remote server failed",{operation:t.operation||"unknown",lastConnectionAttempt:t.lastConnectionAttempt||null,suggestions:["Check your network connection","Verify that the remote server is running","Try again in a few moments"],isConnectionIssue:!0})}}const t=e instanceof Error?e:Error(e+""),o=r(i.INTERNAL_ERROR,t.message||"An unexpected error occurred")
|
|
4629
|
-
return{statusCode:o.error.statusCode,body:o}}function s(e){return!n(e)||e.isRetryable()}Object.defineProperty(exports,"__esModule",{value:!0}),exports.UnauthorizedError=exports.McpProtocolError=exports.FileOperationError=exports.ServiceError=exports.DatabaseError=exports.AuthorizationError=exports.AuthenticationError=exports.ValidationError=exports.NotFoundError=exports.AppError=exports.ErrorUtils=exports.ERROR_TYPE_PROPERTIES=void 0,exports.createErrorResponse=r,exports.createAppError=function(e,t="INTERNAL_ERROR",r=500,n){return new a(e,t,r,n)},exports.createNotFoundError=function(e="Resource not found",t){return new c(e,t)},exports.createValidationError=function(e="Invalid input",t){return new l(e,t)},exports.createAuthenticationError=function(e="Authentication required",t){return new d(e,t)},exports.createAuthorizationError=function(e="Not authorized",t){return new u(e,t)},exports.createDatabaseError=function(e="Database error",t){return new h(e,t)},exports.createServiceError=function(e="Service unavailable",t){return new g(e,t)},exports.createFileOperationError=function(e="File operation error",t){return new
|
|
4592
|
+
return{statusCode:o.error.statusCode,body:o}}function s(e){return!n(e)||e.isRetryable()}Object.defineProperty(exports,"__esModule",{value:!0}),exports.UnauthorizedError=exports.McpProtocolError=exports.FileOperationError=exports.ServiceError=exports.DatabaseError=exports.AuthorizationError=exports.AuthenticationError=exports.ValidationError=exports.NotFoundError=exports.AppError=exports.ErrorUtils=exports.ERROR_TYPE_PROPERTIES=void 0,exports.createErrorResponse=r,exports.createAppError=function(e,t="INTERNAL_ERROR",r=500,n){return new a(e,t,r,n)},exports.createNotFoundError=function(e="Resource not found",t){return new c(e,t)},exports.createValidationError=function(e="Invalid input",t){return new l(e,t)},exports.createAuthenticationError=function(e="Authentication required",t){return new d(e,t)},exports.createAuthorizationError=function(e="Not authorized",t){return new u(e,t)},exports.createDatabaseError=function(e="Database error",t){return new h(e,t)},exports.createServiceError=function(e="Service unavailable",t){return new g(e,t)},exports.createFileOperationError=function(e="File operation error",t){return new p(e,t)},exports.createMcpProtocolError=function(e="MCP protocol error",t){return new f(e,t)},exports.isAppError=n,exports.errorToResponse=o,exports.isRetryableError=s
|
|
4630
4593
|
const i=t(7388)
|
|
4631
4594
|
exports.ERROR_TYPE_PROPERTIES={[i.TASK_NOT_FOUND]:{statusCode:404,retryable:!1,defaultMessage:"Task ID does not exist"},[i.TASK_ID_INVALID_FORMAT]:{statusCode:400,retryable:!1,defaultMessage:"Task ID format is invalid"},[i.TASK_VALIDATION_FAILED]:{statusCode:400,retryable:!1,defaultMessage:"Task validation failed"},[i.NETWORK_ERROR]:{statusCode:503,retryable:!0,defaultMessage:"Network error occurred"},[i.SERVER_ERROR]:{statusCode:500,retryable:!0,defaultMessage:"Server error occurred"},[i.CONNECTION_TIMEOUT]:{statusCode:504,retryable:!0,defaultMessage:"Connection timed out"},[i.SERVICE_UNAVAILABLE]:{statusCode:503,retryable:!0,defaultMessage:"Service is currently unavailable"},[i.CONNECTION_ERROR]:{statusCode:503,retryable:!0,defaultMessage:"Connection to remote server failed"},[i.REQUEST_NOT_FOUND]:{statusCode:404,retryable:!1,defaultMessage:"Request ID does not exist"},[i.REQUEST_ID_INVALID_FORMAT]:{statusCode:400,retryable:!1,defaultMessage:"Request ID format is invalid"},[i.REQUEST_VALIDATION_FAILED]:{statusCode:400,retryable:!1,defaultMessage:"Request validation failed"},[i.VALIDATION_ERROR]:{statusCode:400,retryable:!1,defaultMessage:"Validation error"},[i.UNAUTHORIZED]:{statusCode:401,retryable:!1,defaultMessage:"Authentication required"},[i.FORBIDDEN]:{statusCode:403,retryable:!1,defaultMessage:"Access forbidden"},[i.NOT_FOUND]:{statusCode:404,retryable:!1,defaultMessage:"Resource not found"},[i.INTERNAL_ERROR]:{statusCode:500,retryable:!0,defaultMessage:"Internal server error"},[i.BAD_REQUEST]:{statusCode:400,retryable:!1,defaultMessage:"Bad request"},[i.MCP_PROTOCOL_ERROR]:{statusCode:500,retryable:!0,defaultMessage:"MCP protocol error"}},exports.ErrorUtils={isAppError:n,errorToResponse:o,isRetryableError:s,createErrorResponse:r}
|
|
4632
4595
|
class a extends Error{constructor(e,t="INTERNAL_ERROR",r=500,n){super(e),this.name=this.constructor.name,this.code=t,this.statusCode=r,this.details=n||{},n&&"code"in n&&"string"==typeof n.code&&(this.code=n.code)
|
|
4633
4596
|
const o=exports.ERROR_TYPE_PROPERTIES[this.code]
|
|
4634
4597
|
this.retryable=o?o.retryable:!n||!("retryable"in n)||!!n.retryable,Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,message:this.message,code:this.code,statusCode:this.statusCode,details:this.details,retryable:this.retryable,stack:this.stack}}get metadata(){return this.details}isRetryable(){return this.retryable}}class c extends a{constructor(e="Resource not found",t){super(e,i.NOT_FOUND,404,t),this.resourceType="unknown",t&&("taskId"in t?(this.code=i.TASK_NOT_FOUND,this.resourceType="task"):"requestId"in t&&(this.code=i.REQUEST_NOT_FOUND,this.resourceType="request"))}}class l extends a{constructor(e="Invalid input",t){super(e,i.VALIDATION_ERROR,400,t)}}class d extends a{constructor(e="Authentication required",t){super(e,i.UNAUTHORIZED,401,t)}}class u extends a{constructor(e="Not authorized",t){super(e,i.FORBIDDEN,403,t)}}class h extends a{constructor(e="Database error",t){super(e,"DATABASE_ERROR",500,t)}}class g extends a{constructor(e="Service unavailable",t){if(super(e,i.SERVICE_UNAVAILABLE,503,t),t&&"structuredError"in t){const e=t.structuredError
|
|
4635
|
-
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class
|
|
4598
|
+
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class p extends a{constructor(e="File operation error",t){super(e,"FILE_OPERATION_ERROR",500,t)}}class f extends a{constructor(e="MCP protocol error",t){super(e,i.MCP_PROTOCOL_ERROR,500,t)}}exports.AppError=a,exports.NotFoundError=c,exports.ValidationError=l,exports.AuthenticationError=d,exports.AuthorizationError=u,exports.DatabaseError=h,exports.ServiceError=g,exports.FileOperationError=p,exports.McpProtocolError=f,exports.UnauthorizedError=d},8712(e,exports){function t(e,t){return!(!e||!e.trim())&&RegExp(`^\\s*\\${t}{7}(?:\\s|$)`).test(e)}function r(e,r,n){if(!e||!e.trim())return{cleanContent:"",filesParsed:[],hasConflictMarkers:!1}
|
|
4636
4599
|
const o=e.split("\n"),s=[],i=new Set
|
|
4637
4600
|
let a=!1,c=""
|
|
4638
4601
|
for(let e=0;e<o.length;e++){const l=o[e]
|
|
@@ -4693,7 +4656,7 @@ try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
|
|
|
4693
4656
|
if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
|
|
4694
4657
|
const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
|
|
4695
4658
|
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,
|
|
4659
|
+
return a+=`**File:** ${e}\n`,a+=`**Commit:** ${t.substring(0,8)}\n`,a+=`**Author:** ${n.author_name}\n`,a+=`**Date:** ${n.date}\n`,a+=`**Message:** ${n.message}\n\n`,i&&i.trim()?a+=`## Full Diff\n\n\`\`\`diff\n${i}\n\`\`\`\n`:a+="*No diff available for this commit*\n",{content:[{type:"text",text:a}]}}catch(r){return n.error("Failed to get commit diff",{error:r,commit:t,filePath:e}),{content:[{type:"text",text:`\u274c Failed to get diff for commit ${t}: ${(0,p.getErrorMessage)(r)}`}],isError:!0}}}(a,I,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:y,showDiff:w,showTraceability:k,branch:b}),await async function(e,t,n,o,s,i,a,c,d,u,p){try{const{normalizedPath:m,fullPath:y}=f.validateAndNormalizePath(e,a)
|
|
4697
4660
|
try{await l.access(y)}catch(e){throw Error("File not found: "+m)}const w=a.git
|
|
4698
4661
|
if(!w)throw Error("Git is not available in this context")
|
|
4699
4662
|
let k={branch:null,requestId:null,isMain:!0}
|
|
@@ -4703,8 +4666,8 @@ else{if(k.isMain&&!o)return d.info("Showing request-level timeline on main branc
|
|
|
4703
4666
|
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
4667
|
{const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
|
|
4705
4668
|
if(!i.isMain&&i.branch){const g=await r(e,t,n,o,s,i.branch,a,c,l,d)
|
|
4706
|
-
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),
|
|
4707
|
-
return u.push(...
|
|
4669
|
+
u.push(...g),g.length>0&&h.push(i.branch+" (current)")}const g=await r(e,t,n,o,s,"main",a,c,l,d),p=new Set(u.map((e=>e.hash))),f=g.filter((e=>!p.has(e.hash)))
|
|
4670
|
+
return u.push(...f),g.length>0&&h.push("main"),u.sort(((e,t)=>new Date(t.date).getTime()-new Date(e.date).getTime())),{versions:u.slice(0,n),sources:h}}(w,m,t,n,o,k,i,c,d,u)
|
|
4708
4671
|
b=e.versions,I=`## File History: ${m} (Combined View)\n\n`,I+=`**Current Context:** ${k.isMain?"main":`${k.branch} (${k.requestId})`}\n`,I+=`**History Sources:** ${e.sources.join(", ")}\n\n`}}if(0===b.length)return I+="\u274c **No history found**\n\nThis file has no git history. It may be:\n- A new file that hasn't been committed\n- Located outside the git repository\n- The path may be incorrect\n- No history exists in the specified branch context",{content:[{type:"text",text:I}]}
|
|
4709
4672
|
const v=b.length,C=Math.min(b.length,t)
|
|
4710
4673
|
v>t?I+=`\u{1f4ca} **Summary:** ${v} versions found, showing ${C} most recent\n\n`:v>0&&(I+=`\u{1f4ca} **Summary:** ${v} version${v>1?"s":""} found\n\n`),I+=`**Total Versions:** ${b.length}\n`,I+="**Current File Size:** "
|
|
@@ -4713,9 +4676,9 @@ for(let e=0;e<b.length;e++){const t=b[e]
|
|
|
4713
4676
|
if(I+=`### Version ${e+1} (${t.hash.substring(0,8)})\n`,t.branch&&(I+=`- **Branch:** ${t.branch}\n`),I+=`- **Author:** ${t.author}\n`,I+=`- **Date:** ${t.date}\n`,I+=`- **Message:** ${t.message}\n`,o&&t.traceability&&(I+=`\n${(0,h.formatTraceabilityInfo)(t.traceability)}\n`),n&&t.diff){const e=t.diff.split("\n")
|
|
4714
4677
|
let r=0,n=0
|
|
4715
4678
|
for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
|
|
4716
|
-
I+=`\n**Changes:**${r>0||n>0?` (Added ${r} lines, removed ${n} lines)`:""}\n\`\`\`diff\n${t.diff}\n\`\`\`\n`}I+="\n"}return I+="\u{1f4a1} **Tips:**\n",I+="- Use `file-recover` with a commit hash to restore the file to a previous version\n",I+='- Use `{"branch": "main"}` to see only main branch history\n',I+='- Use `{"branch": "req123456"}` to see only request branch history\n\n',d.info("Branch-aware file history retrieved successfully",{path:m,versions:b.length,targetBranch:s,currentBranch:k.branch,duration:Date.now()-
|
|
4717
|
-
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,
|
|
4718
|
-
const c=a(t(6928)),l=a(t(1943)),d=t(6183),u=t(1569),h=t(1181),g=t(2085),
|
|
4679
|
+
I+=`\n**Changes:**${r>0||n>0?` (Added ${r} lines, removed ${n} lines)`:""}\n\`\`\`diff\n${t.diff}\n\`\`\`\n`}I+="\n"}return I+="\u{1f4a1} **Tips:**\n",I+="- Use `file-recover` with a commit hash to restore the file to a previous version\n",I+='- Use `{"branch": "main"}` to see only main branch history\n',I+='- Use `{"branch": "req123456"}` to see only request branch history\n\n',d.info("Branch-aware file history retrieved successfully",{path:m,versions:b.length,targetBranch:s,currentBranch:k.branch,duration:Date.now()-p}),u.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:I}]}}catch(e){throw e}}(a,y,w,k,b,v,t,n,i,s,m))}catch(e){const t=Date.now()-m
|
|
4680
|
+
return i.error("File/Document history operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),a({tool:"file_history",success:!1}),s.incrementCounter("file_history_errors",1),{content:[{type:"text",text:"\u274c **History Operation Failed:** "+(0,p.getErrorMessage)(e)}],isError:!0}}}
|
|
4681
|
+
const c=a(t(6928)),l=a(t(1943)),d=t(6183),u=t(1569),h=t(1181),g=t(2085),p=t(8824),f=a(t(5967)),m=a(t(7478)),{getCurrentBranch:y}=m},8850(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4719
4682
|
const r=t(6183),n=t(6891)
|
|
4720
4683
|
exports.def={name:"task_file_history",description:"See all file changes made during a task. Use query_history tool instead.",schema:r.QueryHistorySchema,annotations:{title:"Task File History",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleTaskFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}},8851(e,exports,t){function r(e){try{n.debug("Running cleanup before exit"),e(),n.debug("Cleanup completed")}catch(e){n.error("Error during cleanup",{error:e})}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.setupParentProcessDetection=function(e){n.debug("Setting up parent process detection")
|
|
4721
4684
|
const t=process.ppid,o=setInterval((()=>{try{process.kill(t,0)}catch(t){n.info("Parent process exited (detected via PPID check), shutting down"),clearInterval(o),r(e),process.exit(0)}}),5e3)
|
|
@@ -4849,7 +4812,14 @@ if(!o.ok)return void this.logger.debug("Polling response not ok",{status:o.statu
|
|
|
4849
4812
|
const i=await o.json()
|
|
4850
4813
|
if(this.logger.debug("Google OAuth polling response",{data:i}),i.success&&i.data&&i.data.authenticated&&i.data.token){this.logger.info("Google OAuth authentication completed")
|
|
4851
4814
|
const e=this.parseTokenResponse(i.data)
|
|
4852
|
-
e&&(this.pollingStatus=s.AUTHENTICATED,this.tokenResult=e,this.stopPolling(),r&&r(e))}else this.logger.debug("Not authenticated yet, continuing to poll",{hasSuccess:!!i.success,hasData:!!i.data,authenticated:i.data?.authenticated})}catch(e){this.logger.error("Error during Google OAuth polling",{error:(0,o.getErrorMessage)(e)}),this.pollingStatus=s.ERROR,this.pollingError=(0,o.getErrorMessage)(e),this.stopPolling(),i&&i(this.pollingError)}}),this.pollingIntervalMs),{authUrl:e,state:t}}}},
|
|
4815
|
+
e&&(this.pollingStatus=s.AUTHENTICATED,this.tokenResult=e,this.stopPolling(),r&&r(e))}else this.logger.debug("Not authenticated yet, continuing to poll",{hasSuccess:!!i.success,hasData:!!i.data,authenticated:i.data?.authenticated})}catch(e){this.logger.error("Error during Google OAuth polling",{error:(0,o.getErrorMessage)(e)}),this.pollingStatus=s.ERROR,this.pollingError=(0,o.getErrorMessage)(e),this.stopPolling(),i&&i(this.pollingError)}}),this.pollingIntervalMs),{authUrl:e,state:t}}}},9068(e,exports,t){function r(){const e=process.env.ALCHEMY_OPENCODE_DIR
|
|
4816
|
+
if(e)return e
|
|
4817
|
+
try{const e=Object(function(){var e=Error("Cannot find module 'alchemylab-opencode/package.json'")
|
|
4818
|
+
throw e.code="MODULE_NOT_FOUND",e}())
|
|
4819
|
+
return(0,o.dirname)(e)}catch{}}function n(e,t){return{command:"node",prependArgs:["--experimental-strip-types","--experimental-transform-types","--no-warnings","--import",(0,o.join)(e,"node-preload.mjs"),(0,o.join)(e,t)]}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.resolveServeCommand=function(){const e=r()
|
|
4820
|
+
return e?n((0,o.join)(e,"packages","opencode","src"),"serve.ts"):{command:"opencode",prependArgs:["serve"]}},exports.resolveRunCommand=function(){const e=r()
|
|
4821
|
+
return e?n((0,o.join)(e,"packages","opencode","src"),"run.ts"):{command:"opencode",prependArgs:[]}}
|
|
4822
|
+
const o=t(6928)},9072(e,exports,t){async function r(e,t,r,n){try{const o=await(0,d.getServerUrl)(r,n)
|
|
4853
4823
|
if(!o)return n.warn("Could not get server URL for notification",{sessionId:e}),!1
|
|
4854
4824
|
let s,i
|
|
4855
4825
|
try{const t=`http://localhost:${g}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
|
|
@@ -4858,51 +4828,47 @@ e.success&&e.agentType&&(s=e.agentType)}}catch(t){n.warn("Agent type lookup fail
|
|
|
4858
4828
|
if(e.ok){const t=await e.json()
|
|
4859
4829
|
if(t.data?.defaultModel){const[e,...r]=t.data.defaultModel.split("/")
|
|
4860
4830
|
i={providerID:e,modelID:r.join("/")}}}}catch{}const a=`${o.replace(/\/$/,"")}/session/${e}/prompt_async`,c=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:"\x3c!-- inserted-prompt --\x3e"+t}],...s?{agent:s}:{},...i?{model:i}:{}})})
|
|
4861
|
-
return c.ok?(n.info("Notified session",{sessionId:e}),!0):(n.warn("Failed to notify session",{sessionId:e,status:c.status}),!1)}catch(t){return n.warn("Error notifying session",{sessionId:e,error:(0,l.getErrorMessage)(t)}),!1}}function n(e,t,r){return u.sessionIdentity.getParentSessionId(e,t,r)}
|
|
4862
|
-
if(
|
|
4863
|
-
|
|
4864
|
-
if(!s)throw new c.ValidationError("Could not determine OpenCode server URL")
|
|
4865
|
-
const i=await(0,d.getAndStoreSessionId)(s,t,r,n),a=i?.sessionId
|
|
4866
|
-
if(!a)throw new c.ValidationError("Could not discover current session ID. Make sure you are running within an OpenCode session.")
|
|
4867
|
-
return(0,h.logSessionIdentity)(""+r,"per-call-discovery",{sessionId:a}),a}function s(e){const t=[],r=e.content||{}
|
|
4831
|
+
return c.ok?(n.info("Notified session",{sessionId:e}),!0):(n.warn("Failed to notify session",{sessionId:e,status:c.status}),!1)}catch(t){return n.warn("Error notifying session",{sessionId:e,error:(0,l.getErrorMessage)(t)}),!1}}function n(e,t,r){return u.sessionIdentity.getParentSessionId(e,t,r)}function o(e,t,r){const n=u.sessionIdentity.getIdentity()
|
|
4832
|
+
if(!n?.sessionId)throw new c.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
|
|
4833
|
+
return(0,h.logSessionIdentity)(""+r,"identity",{sessionId:n.sessionId}),n.sessionId}function s(e){const t=[],r=e.content||{}
|
|
4868
4834
|
if(t.push("**Message Code:** "+e.messageCode),t.push(`**Type:** question (${r.questionType})`),t.push("**Status:** "+e.status),t.push("**Priority:** "+e.priority),t.push("**From:** "+e.fromSessionId),t.push(e.toSessionId?"**To:** "+e.toSessionId:"**To:** (broadcast)"),t.push("**Created:** "+e.createdAt),t.push("**Expires:** "+e.expiresAt),t.push(""),t.push("**Question:** "+r.question),r.context&&t.push("**Context:** "+r.context),"alternatives"===r.questionType&&r.options){t.push(""),t.push("**Options:**")
|
|
4869
4835
|
for(const e of r.options)t.push(` - [${e.id}] ${e.label}${e.description?" - "+e.description:""}`)}return"responded"===e.status&&e.response&&(t.push(""),t.push("---"),t.push("**Answered by:** "+e.respondedBySessionId),t.push("**Answered at:** "+e.respondedAt),e.response.text&&t.push("**Answer:** "+e.response.text),e.response.selectedOptions&&t.push("**Selected:** "+e.response.selectedOptions.join(", ")),e.response.notes&&t.push("**Notes:** "+e.response.notes)),t.join("\n")}function i(e){const t=[],r=e.content||{}
|
|
4870
|
-
return t.push("**Status:** "+(r.reportStatus||"unknown")),t.push("**Summary:** "+(r.summary||"")),r.details&&(t.push(""),t.push("**Details:**"),t.push(r.details)),t.join("\n")}function a(e){return"question"===e.messageType?s(e):i(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSessionMessageOperations=async function(e,t,
|
|
4871
|
-
if(!
|
|
4872
|
-
const{operation:
|
|
4873
|
-
|
|
4874
|
-
try{switch(
|
|
4836
|
+
return t.push("**Status:** "+(r.reportStatus||"unknown")),t.push("**Summary:** "+(r.summary||"")),r.details&&(t.push(""),t.push("**Details:**"),t.push(r.details)),t.join("\n")}function a(e){return"question"===e.messageType?s(e):i(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSessionMessageOperations=async function(e,t,d,p,f){const m=d.child({component:"session_message_operations"})
|
|
4837
|
+
if(!f)throw new c.ValidationError("API client not available")
|
|
4838
|
+
const{operation:y}=e
|
|
4839
|
+
m.info("Session message operation",{operation:y}),p.incrementCounter("session_message_operations",1,{operation:y})
|
|
4840
|
+
try{switch(y){case"send":if(!e.type)throw new c.ValidationError('send operation requires type ("question" or "report")')
|
|
4875
4841
|
return await async function(e,t,a,l){const{type:d}=e
|
|
4876
4842
|
if(!d)throw new c.ValidationError('send operation requires type ("question" or "report")')
|
|
4877
4843
|
const u=l.getSessionMessageClient()
|
|
4878
4844
|
if(!u)throw new c.ValidationError("Session message client not available")
|
|
4879
|
-
if("question"===d)return await async function(e,t,i,a,l){const{toSessionId:d,questionType:u,questionContent:h,priority:g,expiresInHours:
|
|
4845
|
+
if("question"===d)return await async function(e,t,i,a,l){const{toSessionId:d,questionType:u,questionContent:h,priority:g,expiresInHours:p}=e
|
|
4880
4846
|
if(!u||!h?.question)throw new c.ValidationError("Question requires questionType and questionContent.question")
|
|
4881
|
-
const
|
|
4847
|
+
const f=await o(0,0,"session_message_operations"),m=await async function(e,t,r,o){if("parent"===e){const e=await n(t,r,o)
|
|
4882
4848
|
if(!e)throw new c.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
|
|
4883
|
-
return o.info('Resolved toSessionId "parent" to actual ID',{parentId:e}),e}return e}(d,
|
|
4849
|
+
return o.info('Resolved toSessionId "parent" to actual ID',{parentId:e}),e}return e}(d,f,a,i)
|
|
4884
4850
|
if(!("alternatives"!==u||h.options&&Array.isArray(h.options)))throw new c.ValidationError("Alternatives questions require options array")
|
|
4885
|
-
i.info("Creating question",{fromSessionId:
|
|
4886
|
-
const y=await l.createQuestion({fromSessionId:
|
|
4851
|
+
i.info("Creating question",{fromSessionId:f,toSessionId:m,questionType:u})
|
|
4852
|
+
const y=await l.createQuestion({fromSessionId:f,toSessionId:m,questionType:u,question:h.question,options:h.options,context:h.context,allowMultiple:h.allowMultiple,priority:g,expiresInHours:p})
|
|
4887
4853
|
let w=""
|
|
4888
4854
|
return m&&(w=await r(m,function(e){const t=e.content||{},r=["\u{1f4e8} **You have a new question!**","","**Question Code:** "+e.messageCode,"**From:** "+e.fromSessionId,"**Priority:** "+e.priority,"","**Question:** "+t.question]
|
|
4889
4855
|
if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&&t.options){r.push(""),r.push("**Options:**")
|
|
4890
4856
|
for(const e of t.options)r.push(` - [${e.id}] ${e.label}${e.description?" - "+e.description:""}`)}return r.push(""),r.push(`Use \`session_message_operations\` with \`reply\` operation and message code \`${e.messageCode}\` to respond.`),r.join("\n")}(y),t,i)?"\n\n\u{1f4ec} The target session has been notified.":"\n\n\u26a0\ufe0f Could not notify the target session (may be offline)."),{content:[{type:"text",text:`\u2705 Question created!${w}\n\n**Message Code: ${y.messageCode}**\n\nUse this code to check for answers or share with other sessions.\n\n${s(y)}`}]}}(e,t,a,l,u)
|
|
4891
|
-
if("report"===d)return await async function(e,t,s,a,l){const{status:d,summary:u,details:h,finish:
|
|
4857
|
+
if("report"===d)return await async function(e,t,s,a,l){const{status:d,summary:u,details:h,finish:p}=e
|
|
4892
4858
|
if(!d||!u)throw new c.ValidationError("Report requires status and summary")
|
|
4893
|
-
const
|
|
4894
|
-
const t=await n(
|
|
4859
|
+
const f=await o(0,0,"session_message_operations"),m=await(async()=>{if(e.toSessionId&&"parent"!==e.toSessionId)return s.info("Using explicit toSessionId for report",{parentSessionId:e.toSessionId}),e.toSessionId
|
|
4860
|
+
const t=await n(f,a,s)
|
|
4895
4861
|
if(!t)throw new c.ValidationError("Could not find parent session. This tool should only be used by subagent sessions.")
|
|
4896
4862
|
return s.info("Auto-resolved parent session",{parentSessionId:t}),t})()
|
|
4897
|
-
s.info("Submitting report",{sessionId:
|
|
4898
|
-
const y=await l.createReport({fromSessionId:
|
|
4863
|
+
s.info("Submitting report",{sessionId:f,parentSessionId:m,status:d})
|
|
4864
|
+
const y=await l.createReport({fromSessionId:f,toSessionId:m,status:d,summary:u,details:h})
|
|
4899
4865
|
let w="agent"
|
|
4900
|
-
try{const e=await fetch(`http://localhost:${g}/api/sessions/${encodeURIComponent(
|
|
4866
|
+
try{const e=await fetch(`http://localhost:${g}/api/sessions/${encodeURIComponent(f)}/agent-type`)
|
|
4901
4867
|
if(e.ok){const t=await e.json()
|
|
4902
4868
|
t.success&&t.agentType&&(w=t.agentType)}}catch{}const k=await r(m,function(e,t="agent"){const r=e.content||{},n=[`${{success:"\u2705",partial:"\u26a0\ufe0f",failure:"\u274c",blocked:"\u{1f6ab}"}[r.reportStatus]||"\u{1f4cb}"} **Report \u2014 ${r.reportStatus}**`,`from: ${t} (${e.fromSessionId})`,"",r.summary]
|
|
4903
4869
|
return r.details&&(n.push(""),n.push(r.details)),n.join("\n")}(y,w),t,s)
|
|
4904
4870
|
return{content:[{type:"text",text:`\u2705 Report submitted.${k?"\n\n\u{1f4ec} The parent session has been notified.":"\n\n\u26a0\ufe0f Could not notify the parent session (may be offline)."}\n\n${i(y)}`}]}}(e,t,a,l,u)
|
|
4905
|
-
throw new c.ValidationError(`Unknown message type: ${d}. Use "question" or "report".`)}(e,t,
|
|
4871
|
+
throw new c.ValidationError(`Unknown message type: ${d}. Use "question" or "report".`)}(e,t,m,f)
|
|
4906
4872
|
case"reply":if(!e.messageCode)throw new c.ValidationError("reply operation requires messageCode")
|
|
4907
4873
|
return await async function(e,t,n,o){const{messageCode:a}=e
|
|
4908
4874
|
if(!a)throw new c.ValidationError("reply operation requires messageCode")
|
|
@@ -4913,26 +4879,24 @@ n.info("Answering question",{messageCode:a,respondedBySessionId:o})
|
|
|
4913
4879
|
const u=await l.answerQuestion(a,{respondedBySessionId:o,text:i,selectedOptions:c,notes:d})
|
|
4914
4880
|
return{content:[{type:"text",text:`\u2705 Question answered!${await r(u.fromSessionId,function(e){const t=e.content||{},r=e.response||{},n=["\u{1f4ec} **Your question has been answered!**","","**Question Code:** "+e.messageCode,"**Question:** "+t.question,"","---","**Answered by:** "+e.respondedBySessionId]
|
|
4915
4881
|
return r.text&&n.push("**Answer:** "+r.text),r.selectedOptions&&n.push("**Selected:** "+r.selectedOptions.join(", ")),r.notes&&n.push("**Notes:** "+r.notes),n.join("\n")}(u),t,n)?"\n\n\u{1f4ec} The asking session has been notified.":"\n\n\u26a0\ufe0f Could not notify the asking session (may be offline)."}\n\n${s(u)}`}]}}if(a.startsWith("R-"))return n.info("Acknowledging report",{messageCode:a}),{content:[{type:"text",text:"\u2705 Report acknowledged!\n\n"+i(await l.acknowledgeReport(a))}]}
|
|
4916
|
-
throw new c.ValidationError(`Cannot determine message type from code "${a}". Expected Q-xxx (question) or R-xxx (report).`)}(e,t,
|
|
4917
|
-
case"offer-handoff":{const
|
|
4918
|
-
let
|
|
4919
|
-
try{
|
|
4920
|
-
if(e
|
|
4921
|
-
|
|
4922
|
-
await e.createQuestion({fromSessionId:s,toSessionId:i||void 0,questionType:"alternatives",question:"Plan ready: "+(r.summary||"Plan complete"),options:[{id:"build",label:"Start Building",description:`Begin building ${t} request${1!==t?"s":""}`},{id:"plan",label:"Keep Planning",description:"Continue refining the plan"}],context:t>0?"Created requests: "+r.requestIds.join(", "):void 0,category:"action-required",priority:"high"}),y.info("offer-handoff: notification question created",{fromSessionId:s})}else y.warn("offer-handoff: skipping notification question",{hasClient:!!e,fromSessionId:s})}catch(e){y.warn("offer-handoff: failed to create notification question",{error:(0,l.getErrorMessage)(e)})}return{content:[{type:"text",text:'Handoff offered to user. STOP here and wait \u2014 the user will choose "Start Building" or "Keep Planning". You will receive their choice as a new message. Do NOT generate any further output until then.\nPLAN_HANDOFF_PENDING|'+JSON.stringify({summary:r.summary,requestIds:r.requestIds,parentSessionId:i})}],isError:!1}}case"list":return await async function(e,t,r,n){let{sessionId:o,messageType:s,direction:i,status:l,readStatus:u,reportStatus:g,limit:f,offset:p}=e
|
|
4882
|
+
throw new c.ValidationError(`Cannot determine message type from code "${a}". Expected Q-xxx (question) or R-xxx (report).`)}(e,t,m,f)
|
|
4883
|
+
case"offer-handoff":{const t=e.offerHandoff||{summary:e.summary||"",requestIds:e.requestIds||[]}
|
|
4884
|
+
let r=null,s=null
|
|
4885
|
+
try{r=o(0,0,"session_message_operations"),s=await n(r,f,m)}catch(e){m.warn("offer-handoff: could not resolve session/parent",{error:(0,l.getErrorMessage)(e)})}try{const e=f.getSessionMessageClient()
|
|
4886
|
+
if(e&&r){const n=t.requestIds?.length||0
|
|
4887
|
+
await e.createQuestion({fromSessionId:r,toSessionId:s||void 0,questionType:"alternatives",question:"Plan ready: "+(t.summary||"Plan complete"),options:[{id:"build",label:"Start Building",description:`Begin building ${n} request${1!==n?"s":""}`},{id:"plan",label:"Keep Planning",description:"Continue refining the plan"}],context:n>0?"Created requests: "+t.requestIds.join(", "):void 0,category:"action-required",priority:"high"}),m.info("offer-handoff: notification question created",{fromSessionId:r})}else m.warn("offer-handoff: skipping notification question",{hasClient:!!e,fromSessionId:r})}catch(e){m.warn("offer-handoff: failed to create notification question",{error:(0,l.getErrorMessage)(e)})}return{content:[{type:"text",text:'Handoff offered to user. STOP here and wait \u2014 the user will choose "Start Building" or "Keep Planning". You will receive their choice as a new message. Do NOT generate any further output until then.\nPLAN_HANDOFF_PENDING|'+JSON.stringify({summary:t.summary,requestIds:t.requestIds,parentSessionId:s})}],isError:!1}}case"list":return await async function(e,t,r,n){let{sessionId:o,messageType:s,direction:i,status:l,readStatus:d,reportStatus:g,limit:p,offset:f}=e
|
|
4923
4888
|
const m=n.getSessionMessageClient()
|
|
4924
4889
|
if(!m)throw new c.ValidationError("Session message client not available")
|
|
4925
|
-
if(!o){const e=
|
|
4926
|
-
if(!e)return{content:[{type:"text",text:"\u26a0\ufe0f Could not
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
s&&"all"!==s&&(y.messageType=s),l&&"all"!==l&&("report"===s?y.reportStatus=l:y.status=l),u&&"all"!==u&&(y.readStatus=u),g&&"all"!==g&&(y.reportStatus=g)
|
|
4890
|
+
if(!o){const e=u.sessionIdentity.getIdentity()
|
|
4891
|
+
if(!e?.sessionId)return r.warn("No session identity for list operation"),{content:[{type:"text",text:"\u26a0\ufe0f Could not determine current session ID. Unable to list messages without a session context."}]}
|
|
4892
|
+
o=e.sessionId,(0,h.logSessionIdentity)("session_message_operations.list","identity",{sessionId:o})}r.debug("Listing messages",{sessionId:o,messageType:s,direction:i,status:l,readStatus:d})
|
|
4893
|
+
const y={sessionId:o,direction:i,limit:p,offset:f}
|
|
4894
|
+
s&&"all"!==s&&(y.messageType=s),l&&"all"!==l&&("report"===s?y.reportStatus=l:y.status=l),d&&"all"!==d&&(y.readStatus=d),g&&"all"!==g&&(y.reportStatus=g)
|
|
4931
4895
|
const w=await m.listMessages(y)
|
|
4932
4896
|
if(0===w.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
|
|
4933
4897
|
const k=[`Found ${w.length} message(s):\n`]
|
|
4934
4898
|
for(const e of w)k.push("---\n"),k.push(a(e)),k.push("")
|
|
4935
|
-
return{content:[{type:"text",text:k.join("\n")}]}}(e.list||{},
|
|
4899
|
+
return{content:[{type:"text",text:k.join("\n")}]}}(e.list||{},0,m,f)
|
|
4936
4900
|
case"get":if(!e.messageCode)throw new c.ValidationError("get operation requires messageCode")
|
|
4937
4901
|
return await async function(e,t,r){const{messageCode:n}=e
|
|
4938
4902
|
if(!n)throw new c.ValidationError("get operation requires messageCode")
|
|
@@ -4940,8 +4904,8 @@ const o=r.getSessionMessageClient()
|
|
|
4940
4904
|
if(!o)throw new c.ValidationError("Session message client not available")
|
|
4941
4905
|
t.debug("Getting message",{messageCode:n})
|
|
4942
4906
|
const s=await o.getMessage(n)
|
|
4943
|
-
return s?{content:[{type:"text",text:a(s)}]}:{content:[{type:"text",text:`\u274c Message with code ${n} not found.`}],isError:!0}}(e,
|
|
4944
|
-
default:throw new c.ValidationError(`Unknown operation: ${
|
|
4907
|
+
return s?{content:[{type:"text",text:a(s)}]}:{content:[{type:"text",text:`\u274c Message with code ${n} not found.`}],isError:!0}}(e,m,f)
|
|
4908
|
+
default:throw new c.ValidationError(`Unknown operation: ${y}. Valid operations: send, reply, list, get`)}}catch(e){return m.error("Session message operation failed",{operation:y,error:(0,l.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c Error: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
4945
4909
|
const c=t(9860),l=t(8824),d=t(7617),u=t(6688),h=t(7280),g=3456},9080(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4946
4910
|
const r=t(6183),n=t(1281)
|
|
4947
4911
|
exports.def={name:"search",description:"Search for text patterns in files on the currently active branch. Supports regex patterns and sorts results by file modification time (newest first).\n\nFile extensions: 'ts', '.ts', '*.ts' (all valid). Use '*' for any file type.\n\nCONTEXT LINES: Use contextLines option (0-10) to show surrounding lines before and after matches, reducing need for follow-up reads.\n\nLIST-ALL MODE: Omit 'needle' to list all files in a directory with tree structure (like ls/tree). Options: levels (1-4 depth), sortBy (name/modified/size/type).",schema:r.SearchSchema,annotations:{title:"Search Files",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleSearch)(e,t.context,t.apiClient,t.logger,t.metrics)}}},9089(e,exports){function t(e){if(e.toLowerCase().startsWith("specialist:")){const t=e.slice(11).trim()
|
|
@@ -4976,12 +4940,12 @@ let l,d
|
|
|
4976
4940
|
try{l=await this.git.raw(["merge-base",i,c])}catch(t){return r.warn("Could not find merge-base, commits may be unrelated",{worktreeCommit:i.substring(0,8),targetCommit:c.substring(0,8),error:t}),{hasConflicts:!0,conflictedFiles:[{path:"<multiple files>",conflictType:"content",description:"Branches have diverged significantly (no merge-base found)"}],summary:"Branches have diverged significantly",resolutionInstructions:this.generateMultiAgentInstructions([{path:"<multiple files>",conflictType:"content",description:"Significant divergence"}],e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:"merge-base failed: "+t}}r.debug("Commits for merge-tree analysis",{worktreeCommit:i.substring(0,8),targetCommit:c.substring(0,8),mergeBase:l.trim().substring(0,8)})
|
|
4977
4941
|
let u=0
|
|
4978
4942
|
try{d=await this.git.raw(["merge-tree",l.trim(),c.trim(),i.trim()]),u=0}catch(e){d=e.message||"",u=e.exitCode||1,r.debug("merge-tree failed with error",{exitCode:u,error:e.message})}r.debug("Merge-tree analysis completed",{outputLength:d.length,hasOutput:!!d.trim(),exitCode:u})
|
|
4979
|
-
let h=!1,g="",
|
|
4980
|
-
if(0!==u?(h=!0,g="merge-tree-exit-code"):d&&d.trim()?(
|
|
4981
|
-
!
|
|
4982
|
-
let
|
|
4983
|
-
if(
|
|
4984
|
-
else try{
|
|
4943
|
+
let h=!1,g="",p=null
|
|
4944
|
+
if(0!==u?(h=!0,g="merge-tree-exit-code"):d&&d.trim()?(p=(0,s.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch),p.hasConflictMarkers?(h=!0,g="conflict-parser-detected-markers",r.warn("Git exit code 0 but conflict parser found conflict markers - treating as conflict")):(h=!1,g="clean-merge-with-changes",r.info("Git exit code 0 and conflict parser found no markers - treating as clean merge",{hasOutput:!0,outputLength:d.length}))):(h=!1,g="clean-merge-no-changes"),r.info("FINAL conflict detection result (trusting Git exit codes)",{hasConflicts:h,exitCode:u,hasOutput:!!d.trim(),outputLength:d?d.length:0,conflictReason:g,method:"git-exit-code-primary",trustedGitExitCode:0===u}),!h)return{hasConflicts:!1,conflictedFiles:[],summary:"No conflicts detected (merge-tree clean)",resolutionInstructions:"",detectionMethod:"merge-tree-analysis",rawOutput:d}
|
|
4945
|
+
!p&&d&&d.trim()&&(p=(0,s.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch))
|
|
4946
|
+
let f=[]
|
|
4947
|
+
if(p&&p.filesParsed&&p.filesParsed.length>0)f=p.filesParsed.map((e=>({path:e,conflictType:"content",description:"Merge conflict detected"}))),r.debug("Successfully extracted conflict files from parsed content",{conflictedFilesCount:f.length,files:f.map((e=>e.path))})
|
|
4948
|
+
else try{f=this.parseMergeTreeOutput(d,r),r.debug("Used fallback merge-tree parsing",{conflictedFilesCount:f.length})}catch(e){r.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),f=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===f.length&&(r.warn("Git detected conflicts but no files could be determined - using fallback"),f=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:f,summary:f.length>0&&"<parsing failed>"!==f[0].path&&"<unknown files>"!==f[0].path?f.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateMultiAgentInstructions(f,e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:d,rawConflictContent:p?p.cleanContent:void 0}}catch(e){throw r.error("Pure multi-agent conflict detection failed",{error:e}),e}}parseMergeTreeOutput(e,t){const r=[]
|
|
4985
4949
|
if(!e||!e.trim())return t.debug("Empty merge-tree output - no conflicts to parse"),[]
|
|
4986
4950
|
let n
|
|
4987
4951
|
try{n=e.split("\n"),t.debug("Parsing merge-tree output",{linesCount:n.length,totalLength:e.length,firstFewLines:n.slice(0,5),hasNewlines:e.includes("\n")})}catch(r){throw t.error("Failed to split merge-tree output into lines",{error:r instanceof Error?r.message:r+"",outputLength:e.length}),Error("Failed to parse merge-tree output: "+r)}let o=!1
|
|
@@ -5033,23 +4997,23 @@ o+="## Test 3: Recent merge commits (to see actual patterns)\n",o+=`Found ${e?.a
|
|
|
5033
4997
|
o+=`## Test 4: All commits containing "${n}" (not just merges)\n`,o+=`Found ${e?.all?.length||0} commits:\n`,e?.all?.length>0?e.all.forEach(((e,t)=>{o+=`${t+1}. ${e.hash.substring(0,8)} - ${e.message}\n`})):o+="No commits found\n",o+="\n"}catch(e){o+=`## Test 4: Error - ${(0,r.getErrorMessage)(e)}\n\n`}try{const e=await t.git.revparse(["--abbrev-ref","HEAD"])
|
|
5034
4998
|
o+=`## Current branch: ${e}\n\n`}catch(e){o+=`## Current branch: Error - ${(0,r.getErrorMessage)(e)}\n\n`}try{const e=await t.git.branch()
|
|
5035
4999
|
o+="## All branches:\n",e.all&&e.all.length>0?e.all.forEach((e=>{o+=`- ${e}\n`})):o+="No branches found\n",o+="\n"}catch(e){o+=`## Branches: Error - ${(0,r.getErrorMessage)(e)}\n\n`}return{content:[{type:"text",text:o}]}}catch(e){return s.error("Error in debug request file history",{error:e instanceof Error?e.stack:e+""}),{content:[{type:"text",text:"Error: "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
5036
|
-
const r=t(8824)},9442(e,exports,t){function r(e){return{line:e.line,actually_matched:e.actuallyMatched,match_type:e.matchType}}async function n(e,t,n,o,s,i,a){const{path:c,documentId:d,replacements:g,fuzzy_match:
|
|
5000
|
+
const r=t(8824)},9442(e,exports,t){function r(e){return{line:e.line,actually_matched:e.actuallyMatched,match_type:e.matchType}}async function n(e,t,n,o,s,i,a){const{path:c,documentId:d,replacements:g,fuzzy_match:p}=e,f=!!d,m=void 0!==p?p:t,y={type:f?"document":"file",path:c,documentId:d,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,externalEditDebugInfo:{detectionRan:!1,reason:f?"Skipped: Document operation":n.git?"Pending":"Skipped: No Git context"}}
|
|
5037
5001
|
try{let t,o
|
|
5038
|
-
if(
|
|
5002
|
+
if(f){t=await n.documentFileManager.getDocumentAsFile(d)
|
|
5039
5003
|
const e=n.documentFileManager.getCachedDocumentInfo(d)
|
|
5040
5004
|
y.filename=e?.filename,o="document:"+d}else{const e=u.validateAndNormalizePath(c,n)
|
|
5041
|
-
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),
|
|
5005
|
+
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),p=[]
|
|
5042
5006
|
for(const t of g){const{old:n,new:o,match_mode:i="unique"}=t,a={old:n,new:o,success:!1}
|
|
5043
5007
|
try{if(n===o){a.error="No-op replacement (old and new values are identical)",a.success=!1,a.matchesFound=0,y.failedReplacements++,y.replacements.push(a)
|
|
5044
5008
|
continue}const t=(0,h.findMatches)(s,n,m,100,e.path)
|
|
5045
5009
|
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(m?" (tried fuzzy matching)":""),a.success=!1
|
|
5046
5010
|
const e=(0,h.findSimilarMatches)(s,n,5,.3)
|
|
5047
|
-
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++):
|
|
5011
|
+
e.length>0&&(a.similarMatches=e),y.failedReplacements++}else"unique"===i&&t.length>1?(a.error=`Multiple matches found (${t.length}) - expected unique match`,a.success=!1,a.details=t.map(r),y.failedReplacements++):p.push({matches:t,newText:o,matchMode:i,repResult:a})}catch(e){a.error=(0,k.getErrorMessage)(e),a.success=!1,y.failedReplacements++}y.replacements.push(a)}let w=s
|
|
5048
5012
|
const b=[]
|
|
5049
|
-
for(const e of
|
|
5013
|
+
for(const e of p)for(const t of e.matches)b.push({match:t,newText:e.newText,repResult:e.repResult})
|
|
5050
5014
|
b.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5051
5015
|
for(const{match:e,newText:t,repResult:n}of b)w=(0,h.replaceMatch)(w,e,t),n.success?(n.lines.push(e.line),n.details.push(r(e))):(n.success=!0,n.matchType=e.matchType,n.lines=[e.line],n.details=[r(e)],y.successfulReplacements++)
|
|
5052
|
-
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),
|
|
5016
|
+
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),f&&(n.documentFileManager.markForSync(d),await n.documentFileManager.syncDocument(d))),i&&(y.externalEditWarning=i),a&&(y.externalEditDebugInfo={detectionRan:!0,...a}),y.success=0===y.failedReplacements}catch(e){y.error=(0,k.getErrorMessage)(e),y.success=!1,y.failedReplacements=g.length,y.replacements=g.map((e=>({old:e.old,new:e.new,success:!1,error:y.error})))}return y}var o,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
5053
5017
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5054
5018
|
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=[]
|
|
5055
5019
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -5078,7 +5042,7 @@ const n=await u.autoPromoteTaskStatus(_,x.status,O,e.request?.status,R,r,s,b,a,"
|
|
|
5078
5042
|
n.taskPromoted&&b.info("Auto-promoted task to in_progress",{taskId:_,requestId:O,previousStatus:x.status,newStatus:n.newTaskStatus}),Date.now(),P=Date.now()
|
|
5079
5043
|
const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:O,context:t,operation:"replace_in_files",logger:b,metrics:a,metricsPrefix:"replace_in_files"})
|
|
5080
5044
|
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,
|
|
5045
|
+
throw Error(o.error)}Date.now(),$=!0}if(T.length>0&&O)try{await(0,p.validateRequestStatusForDocumentOperation)(O,s,b,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5082
5046
|
throw e}P=Date.now()
|
|
5083
5047
|
const D=new Map
|
|
5084
5048
|
if(b.info("\u{1f50d} Starting external edit detection",{hasFileOperations:j,hasGit:!!t.git,operationCount:E.length}),j&&t.git)for(const e of E)if(e.path&&!e.documentId)try{const r=u.validateAndNormalizePath(e.path,t),n=await l.default.readFile(r.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:q,s=[]
|
|
@@ -5087,7 +5051,7 @@ s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,r.fullP
|
|
|
5087
5051
|
b.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
|
|
5088
5052
|
const i=await(0,w.detectExternalEdits)(t.git,o,b)
|
|
5089
5053
|
b.info("\u{1f50d} External edit detection result",{path:r.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(D.set(e.path,{message:i.message,debugInfo:i.debugInfo}),b.warn("\u26a0\ufe0f External edits detected before auto-commit",{path:r.normalizedPath,conflictingLines:i.conflictingLines})):(i.debugInfo&&D.set(e.path,{message:"",debugInfo:i.debugInfo}),b.info("\u2705 No external edit conflicts detected",{path:r.normalizedPath}))}else b.info("\u2139\ufe0f No matches found for external edit detection",{path:r.normalizedPath}),D.set(e.path,{message:"",debugInfo:{detectionRan:!1,reason:"No matches found - patterns not found in file",affectedRegion:"none",uncommittedChanges:"not checked",overlapDetected:!1}})}catch(t){b.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,k.getErrorMessage)(t)})}if(Date.now(),P=Date.now(),j&&t.git)try{b.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
|
|
5090
|
-
const e=await(0,
|
|
5054
|
+
const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:O,taskId:_,workspaceManager:t.workspaceManager},b,a)
|
|
5091
5055
|
e.userChangesCommitted&&(b.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),b.info("User changes committed before batch operation",{taskId:_,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){b.warn("Pre-tool user changes commit failed",{taskId:_,error:e instanceof Error?e.message:e+""})}Date.now(),P=Date.now(),C=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5092
5056
|
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,b,a,"replace_in_files",c)
|
|
5093
5057
|
v=A,Date.now(),P=Date.now(),C=u.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
@@ -5096,8 +5060,8 @@ for(const e of E){const r=e.path?D.get(e.path):void 0,o=await n(e,q,t,0,0,r?.mes
|
|
|
5096
5060
|
F.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&N.push(o.path)}Date.now(),P=Date.now()
|
|
5097
5061
|
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:b,metrics:a,metricsPrefix:"replace_in_files"},t),B=z.commitHash
|
|
5098
5062
|
Date.now(),Date.now()
|
|
5099
|
-
const H=F.filter((e=>e.success)).length,
|
|
5100
|
-
await o.updateToolRecord(v,{metadata:{path:R,status:0===
|
|
5063
|
+
const H=F.filter((e=>e.success)).length,U=F.length-H,W=F.reduce(((e,t)=>e+t.successfulReplacements),0),G=F.reduce(((e,t)=>e+t.failedReplacements),0),V=F.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,replacements:e.replacements.map((e=>({old_str:e.old,new_str:e.new,success:e.success,error:e.error,matchesFound:e.matchesFound,matchType:e.matchType,lines:e.lines})))}))),J=F.filter((e=>e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements}))),K=F.filter((e=>!e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,error:e.error,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements})))
|
|
5064
|
+
await o.updateToolRecord(v,{metadata:{path:R,status:0===U?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:K,successfulReplacements:W,failedReplacements:G,processingTime:Date.now()-I,userComment:S,...z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}}})
|
|
5101
5065
|
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
5066
|
let l="## Replace In Files - Batch Results\n\n"
|
|
5103
5067
|
if(o.getCurrentBranchContext)try{const e=await o.getCurrentBranchContext()
|
|
@@ -5109,10 +5073,10 @@ if(o.length>0){l+="\n**Successful Replacements:**\n"
|
|
|
5109
5073
|
for(const e of o)l+=`- \u2705 \`${e.old.substring(0,40)}${e.old.length>40?"...":""}\` \u2192 \`${e.new.substring(0,40)}${e.new.length>40?"...":""}\``,e.matchesFound&&(l+=` (${e.matchesFound} occurrence${e.matchesFound>1?"s":""})`),e.lines&&e.lines.length>0&&3>=e.lines.length?l+=` at line${e.lines.length>1?"s":""} ${e.lines.join(", ")}`:e.lines&&e.lines.length>3&&(l+=` at ${e.lines.length} locations`),l+="\n"}const s=r.replacements.filter((e=>!e.success))
|
|
5110
5074
|
if(s.length>0){l+="\n**Failed Replacement Details:**\n"
|
|
5111
5075
|
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
|
-
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,
|
|
5113
|
-
return{content:[{type:"text",text:Y}],isError:0===
|
|
5076
|
+
return d.length>0&&(l+=`\n**Document Changes:** ${d.length} modified document(s) synced back to tracking system.\n`),o.workspaceManager?.largeFileWarning&&(l+=o.workspaceManager.largeFileWarning,o.workspaceManager.largeFileWarning=""),l}(F,B,W,G,t,v)
|
|
5077
|
+
return{content:[{type:"text",text:Y}],isError:0===W}}catch(e){const t=Date.now()-I
|
|
5114
5078
|
if(b.error("Replace in files batch operation failed",{error:e instanceof Error?e.stack:e+"",duration:t,phase:C}),v)try{await o.updateToolRecord(v,{metadata:{status:"failed",error:(0,k.getErrorMessage)(e),phase:C,duration:t}})}catch(e){}return a.incrementCounter("replace_in_files_errors",1,{phase:C}),{content:[{type:"text",text:"\u274c **Replace In Files Failed:** "+(0,k.getErrorMessage)(e)}],isError:!0}}}
|
|
5115
|
-
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),
|
|
5079
|
+
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(6183)),u=a(t(5967)),h=t(3626),g=t(9860),p=t(5003),f=t(7478),m=t(9949),y=t(9947),w=t(1318),k=t(8824)},9470(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
|
|
5116
5080
|
const t=e.trim()
|
|
5117
5081
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|
|
5118
5082
|
if(2!==r.length)throw Error(`Invalid line range format: "${e}". Expected format: "start-end" (e.g., "5-15")`)
|
|
@@ -5167,14 +5131,14 @@ if(n)s.WorkspaceLogging.logOperation(this.logger,"info","Branch already exists,
|
|
|
5167
5131
|
else{const t=await this.git.revparse(["--abbrev-ref","HEAD"]),r=await this.gitAdapter.branchManager.getBaseBranch()
|
|
5168
5132
|
await this.git.checkout(["-b",i,r]),await this.git.checkout(t),s.WorkspaceLogging.logOperation(this.logger,"info","Created branch and returned to original",e,"single-agent","initializeRequest",{branchName:i,baseBranch:r,returnedTo:t})}const o=Date.now()-r
|
|
5169
5133
|
this.metrics.recordValue("workspace.initialize",o),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully initialized request with branch",e,"single-agent","initializeRequest",{branchName:i,existed:n,duration:o,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
|
|
5170
|
-
throw this.metrics.recordValue("workspace.initialize",n),s.WorkspaceLogging.logOperation(this.logger,"error","Failed to initialize request",e,"single-agent","initializeRequest",{error:(0,o.getErrorMessage)(t),duration:n}),t}}async ensureWorkspaceReady(e){const
|
|
5171
|
-
if(!
|
|
5172
|
-
const n
|
|
5173
|
-
if(a
|
|
5174
|
-
try{if(s.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by switching to branch",e,"single-agent","ensureWorkspaceReady",{currentBranch:
|
|
5175
|
-
try{await this.switchToRequest(
|
|
5176
|
-
this.metrics.recordValue("workspace.ensure_ready",
|
|
5177
|
-
throw this.metrics.recordValue("workspace.ensure_ready",n),s.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure workspace ready",e,"single-agent","ensureWorkspaceReady",{error:(0,o.getErrorMessage)(
|
|
5134
|
+
throw this.metrics.recordValue("workspace.initialize",n),s.WorkspaceLogging.logOperation(this.logger,"error","Failed to initialize request",e,"single-agent","initializeRequest",{error:(0,o.getErrorMessage)(t),duration:n}),t}}async ensureWorkspaceReady(e,t){const r=Date.now(),n=s.WorkspaceValidation.validateRequestId(e)
|
|
5135
|
+
if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
|
|
5136
|
+
const i=n.sanitized,a="requests/"+i,c=await this.git.revparse(["--abbrev-ref","HEAD"])
|
|
5137
|
+
if(c===a)return this.currentRequestId=i,this.currentBranch=a,void this.logger.debug("Workspace already ready",{requestId:i,currentBranch:this.currentBranch})
|
|
5138
|
+
try{if(s.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by switching to branch",e,"single-agent","ensureWorkspaceReady",{currentBranch:c,targetBranch:a,architecture:"hybrid-creation"}),!(await this.git.branch()).all.includes(a))throw Error(`Branch ${a} does not exist. Was initializeRequest() called?`)
|
|
5139
|
+
try{await this.switchToRequest(i)}catch(t){s.WorkspaceLogging.logOperation(this.logger,"warn","switchToRequest failed, trying direct checkout",e,"single-agent","ensureWorkspaceReady",{error:t instanceof Error?t.message:t+"",attempting:"direct-checkout",branchName:a}),await this.git.checkout(a),this.currentRequestId=i,this.currentBranch=a,s.WorkspaceLogging.logOperation(this.logger,"info","Direct checkout succeeded",e,"single-agent","ensureWorkspaceReady",{branchName:a})}const t=Date.now()-r
|
|
5140
|
+
this.metrics.recordValue("workspace.ensure_ready",t),s.WorkspaceLogging.logOperation(this.logger,"info","Workspace is ready",e,"single-agent","ensureWorkspaceReady",{branchName:this.currentBranch,duration:t,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
|
|
5141
|
+
throw this.metrics.recordValue("workspace.ensure_ready",n),s.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure workspace ready",e,"single-agent","ensureWorkspaceReady",{error:(0,o.getErrorMessage)(t),duration:n}),t}}async switchToRequest(e,t){const r=Date.now(),n=this.getCurrentContext(),i=s.WorkspaceValidation.validateRequestId(e)
|
|
5178
5142
|
if(!i.isValid){const t="Invalid request ID: "+i.errors.join(", ")
|
|
5179
5143
|
throw s.WorkspaceLogging.logOperation(this.logger,"error",t,e,"single-agent","switchToRequest"),Error(t)}const a=i.sanitized
|
|
5180
5144
|
try{s.WorkspaceLogging.logOperation(this.logger,"info","Switching to request (assuming branch exists)",e,"single-agent","switchToRequest",{previousBranch:n.branchName,architecture:"aligned-with-multi-agent"})
|
|
@@ -5184,13 +5148,13 @@ const o=Date.now()-r
|
|
|
5184
5148
|
return this.metrics.recordValue("workspace.switch",o),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully switched to request",e,"single-agent","switchToRequest",{branchName:t.branchName,previousBranch:n.branchName,duration:o,architecture:"aligned-with-multi-agent"}),{success:!0,message:"Switched to request "+a,previousContext:n,newContext:this.getCurrentContext()}}catch(t){const n=Date.now()-r
|
|
5185
5149
|
this.metrics.recordValue("workspace.switch",n)
|
|
5186
5150
|
const i=(0,o.getErrorMessage)(t),a=i.includes("does not exist"),c=a?`Branch for request ${e} does not exist. Use initializeRequest() first to create the branch.`:`Failed to switch to request ${e}: ${i}`
|
|
5187
|
-
throw s.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to request",e,"single-agent","switchToRequest",{error:i,isMissingBranch:a,duration:n,suggestion:a?"Call initializeRequest() first":"Check branch status"}),new s.ConflictDetectionError(c,"single-agent-switch-"+e,[])}}async switchToMain(){const
|
|
5188
|
-
try{const
|
|
5151
|
+
throw s.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to request",e,"single-agent","switchToRequest",{error:i,isMissingBranch:a,duration:n,suggestion:a?"Call initializeRequest() first":"Check branch status"}),new s.ConflictDetectionError(c,"single-agent-switch-"+e,[])}}async switchToMain(e){const t=Date.now(),r=this.getCurrentContext()
|
|
5152
|
+
try{const e=await this.gitAdapter.branchManager.getBaseBranch(),n=await this.gitAdapter.branchManager.switchToBranch(e)
|
|
5189
5153
|
if(!n.success)throw Error("Failed to switch to main branch: "+n.error)
|
|
5190
|
-
this.currentBranch=
|
|
5191
|
-
const o=Date.now()-
|
|
5192
|
-
return this.metrics.recordValue("workspace.switch_main",o),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully switched to main branch",null,"single-agent","switchToMain",{mainBranch:
|
|
5193
|
-
throw this.metrics.recordValue("workspace.switch_main",r),s.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to main branch",null,"single-agent","switchToMain",{error:(0,o.getErrorMessage)(
|
|
5154
|
+
this.currentBranch=e,this.currentRequestId=null
|
|
5155
|
+
const o=Date.now()-t
|
|
5156
|
+
return this.metrics.recordValue("workspace.switch_main",o),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully switched to main branch",null,"single-agent","switchToMain",{mainBranch:e,previousBranch:r.branchName,duration:o,architecture:"aligned-with-multi-agent"}),{success:!0,message:"Switched to "+e,previousContext:r,newContext:this.getCurrentContext()}}catch(e){const r=Date.now()-t
|
|
5157
|
+
throw this.metrics.recordValue("workspace.switch_main",r),s.WorkspaceLogging.logOperation(this.logger,"error","Failed to switch to main branch",null,"single-agent","switchToMain",{error:(0,o.getErrorMessage)(e),duration:r}),new s.ConflictDetectionError("Failed to switch to main: "+(0,o.getErrorMessage)(e),"single-agent",[])}}async commitChanges(e,t){const r=Date.now()
|
|
5194
5158
|
try{t&&t.length>0?await this.git.add(t):await this.git.add("."),await this.git.commit(e)
|
|
5195
5159
|
const n=await this.git.revparse(["HEAD"]),o=Date.now()-r
|
|
5196
5160
|
return this.metrics.recordValue("workspace.commit",o),this.logger.info("Successfully committed changes",{message:e,commitHash:n.substring(0,8),filesCount:t?.length||"all",duration:o}),{hash:n,message:e,files:t||[]}}catch(t){const n=Date.now()-r
|
|
@@ -5198,33 +5162,32 @@ throw this.metrics.recordValue("workspace.commit",n),this.logger.error("Failed t
|
|
|
5198
5162
|
try{s.WorkspaceLogging.logOperation(this.logger,"info","Starting request completion (refactored)",e,"single-agent","completeRequest",{requestTitle:t,skipConflictDetection:r?.skipConflictDetection||!1,architecture:"shared-processor"})
|
|
5199
5163
|
const o=await this.requestProcessor.completeRequest(e,t,{skipConflictDetection:r?.skipConflictDetection||!1}),i=Date.now()-n
|
|
5200
5164
|
return this.metrics.recordValue("workspace.complete",i),s.WorkspaceLogging.logOperation(this.logger,"info","Request completion successful (refactored)",e,"single-agent","completeRequest",{mergeCommitHash:o.mergeCommitHash.substring(0,8),mergedFiles:o.mergedFiles?.length||0,cleanedUp:o.cleanedUp,wasAutoMerged:o.autoMergeInfo?.wasAutoMerged,strategy:o.autoMergeInfo?.strategy,duration:i,architecture:"shared-processor"}),o}catch(t){const r=Date.now()-n
|
|
5201
|
-
throw this.metrics.recordValue("workspace.complete",r),s.WorkspaceLogging.logOperation(this.logger,"error","Request completion failed (refactored)",e,"single-agent","completeRequest",{error:(0,o.getErrorMessage)(t),duration:r,architecture:"shared-processor"}),t}}resolveFilePath(e){return n.default.resolve(this.basePath,e)}async createCommit(e,t){return await this.commitChanges(e,t)}async cancelRequest(e){const t=s.WorkspaceValidation.validateRequestId(e)
|
|
5165
|
+
throw this.metrics.recordValue("workspace.complete",r),s.WorkspaceLogging.logOperation(this.logger,"error","Request completion failed (refactored)",e,"single-agent","completeRequest",{error:(0,o.getErrorMessage)(t),duration:r,architecture:"shared-processor"}),t}}resolveFilePath(e,t){return n.default.resolve(this.basePath,e)}async createCommit(e,t,r){return await this.commitChanges(e,t)}async cancelRequest(e){const t=s.WorkspaceValidation.validateRequestId(e)
|
|
5202
5166
|
if(!t.isValid)throw Error("Invalid request ID: "+t.errors.join(", "))
|
|
5203
5167
|
const r="requests/"+t.sanitized
|
|
5204
|
-
try{s.WorkspaceLogging.logOperation(this.logger,"info","Cancelling request (deleting branch)",e,"single-agent","cancelRequest",{branchName:r,architecture:"aligned-with-multi-agent"}),this.currentBranch===r&&await this.switchToMain(),await this.git.deleteLocalBranch(r),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully cancelled request",e,"single-agent","cancelRequest",{branchName:r,switchedToMain:this.currentBranch!==r})}catch(t){throw s.WorkspaceLogging.logOperation(this.logger,"error","Failed to cancel request",e,"single-agent","cancelRequest",{branchName:r,error:(0,o.getErrorMessage)(t)}),t}}async listActiveWorkspaces(){try{return(await this.git.branch()).all.filter((e=>e.startsWith("requests/"))).map((e=>({requestId:e.replace("requests/",""),path:this.basePath,branchName:e,isActive:this.currentBranch===e,created:new Date,lastAccessed:new Date})))}catch(e){return this.logger.error("Failed to list active workspaces",{error:(0,o.getErrorMessage)(e)}),[]}}getCurrentContext(){return{requestId:this.currentRequestId,basePath:this.basePath,branchName:this.currentBranch,isMainBranch:"main"===this.currentBranch||"master"===this.currentBranch,mode:"single-agent"}}async getWorkspaceInfo(e){try{const t=s.WorkspaceValidation.validateRequestId(e)
|
|
5168
|
+
try{s.WorkspaceLogging.logOperation(this.logger,"info","Cancelling request (deleting branch)",e,"single-agent","cancelRequest",{branchName:r,architecture:"aligned-with-multi-agent"}),this.currentBranch===r&&await this.switchToMain(),await this.git.deleteLocalBranch(r),s.WorkspaceLogging.logOperation(this.logger,"info","Successfully cancelled request",e,"single-agent","cancelRequest",{branchName:r,switchedToMain:this.currentBranch!==r})}catch(t){throw s.WorkspaceLogging.logOperation(this.logger,"error","Failed to cancel request",e,"single-agent","cancelRequest",{branchName:r,error:(0,o.getErrorMessage)(t)}),t}}async listActiveWorkspaces(){try{return(await this.git.branch()).all.filter((e=>e.startsWith("requests/"))).map((e=>({requestId:e.replace("requests/",""),path:this.basePath,branchName:e,isActive:this.currentBranch===e,created:new Date,lastAccessed:new Date})))}catch(e){return this.logger.error("Failed to list active workspaces",{error:(0,o.getErrorMessage)(e)}),[]}}getCurrentContext(e){return{requestId:this.currentRequestId,basePath:this.basePath,branchName:this.currentBranch,isMainBranch:"main"===this.currentBranch||"master"===this.currentBranch,mode:"single-agent"}}async getWorkspaceInfo(e){try{const t=s.WorkspaceValidation.validateRequestId(e)
|
|
5205
5169
|
if(!t.isValid)return null
|
|
5206
5170
|
const r=t.sanitized,n="requests/"+r,o=await this.git.branch()
|
|
5207
|
-
return o.all.includes(n)||o.all.includes("remotes/origin/"+n)?{requestId:r,path:this.basePath,branchName:n,isActive:this.currentBranch===n,created:new Date,lastAccessed:new Date}:null}catch(t){return this.logger.error("Failed to get workspace info",{requestId:e,error:(0,o.getErrorMessage)(t)}),null}}getMainGit(){return this.gitAdapter.getMainGit()}async getWorktreeInfo(e){}getCurrentGit(){return this.git}async ensureReadonlyBranchIfNeeded(e,r,n
|
|
5208
|
-
try{
|
|
5209
|
-
if(!
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
this.
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
this.
|
|
5226
|
-
|
|
5227
|
-
g.all.includes(h)||g.all.includes("remotes/origin/"+h)?(await this.git.checkout(h),this.currentBranch=h,this.currentRequestId=u,this.logger.info("Successfully switched to readonly branch",{currentBranch:this.currentBranch,currentRequestId:this.currentRequestId})):this.logger.warn("Readonly branch does not exist",{readonlyBranch:h})}catch(e){this.logger.debug("Error during readonly branch check",{error:(0,o.getErrorMessage)(e)})}}}async fetchAgentConfig(e){try{const t="http://localhost:3456/api/agents/by-name/"+encodeURIComponent(e),r=await fetch(t)
|
|
5171
|
+
return o.all.includes(n)||o.all.includes("remotes/origin/"+n)?{requestId:r,path:this.basePath,branchName:n,isActive:this.currentBranch===n,created:new Date,lastAccessed:new Date}:null}catch(t){return this.logger.error("Failed to get workspace info",{requestId:e,error:(0,o.getErrorMessage)(t)}),null}}getMainGit(){return this.gitAdapter.getMainGit()}async getWorktreeInfo(e){}getCurrentGit(e){return this.git}async ensureReadonlyBranchIfNeeded(e,t,r,n){if(!this.readonlyBranchCheckDone){this.readonlyBranchCheckDone=!0
|
|
5172
|
+
try{const e=n
|
|
5173
|
+
if(!e)return void this.logger.debug("No sessionId available for readonly check")
|
|
5174
|
+
this.logger.debug("Checking readonly branch for session",{sessionId:e,toolName:t})
|
|
5175
|
+
const o=r?.getCLISessionClient?.()
|
|
5176
|
+
if(!o)return void this.logger.debug("No CLI session client available for readonly check")
|
|
5177
|
+
const s=await o.getByExternalId(e)
|
|
5178
|
+
if(!s?.agentType)return void this.logger.debug("No agent type found for session",{sessionId:e})
|
|
5179
|
+
this.logger.debug("Found session agent type",{sessionId:e,agentType:s.agentType})
|
|
5180
|
+
const i=await this.fetchAgentConfig(s.agentType)
|
|
5181
|
+
if(!i||"readonly"!==i.requestContextMode)return void this.logger.debug("Agent does not have readonly requestContextMode",{agentType:s.agentType})
|
|
5182
|
+
this.logger.debug("Agent has readonly requestContextMode",{agentType:s.agentType})
|
|
5183
|
+
const a=r?.getSessionRequestAssociationClient?.()
|
|
5184
|
+
if(!a)return void this.logger.debug("No session association client available")
|
|
5185
|
+
const c=await a.getActiveRequestsForSession(e,!0)
|
|
5186
|
+
if(0===c.length)return void this.logger.debug("No active request association found for session",{sessionId:e})
|
|
5187
|
+
const l=c[0].requestLocalId,d="requests/"+l
|
|
5188
|
+
this.logger.info("Readonly agent with request association, switching to branch without locking",{sessionId:e,agentType:s.agentType,requestId:l,readonlyBranch:d})
|
|
5189
|
+
const u=await this.git.branch()
|
|
5190
|
+
u.all.includes(d)||u.all.includes("remotes/origin/"+d)?(await this.git.checkout(d),this.currentBranch=d,this.currentRequestId=l,this.logger.info("Successfully switched to readonly branch",{currentBranch:this.currentBranch,currentRequestId:this.currentRequestId})):this.logger.warn("Readonly branch does not exist",{readonlyBranch:d})}catch(e){this.logger.debug("Error during readonly branch check",{error:(0,o.getErrorMessage)(e)})}}}async fetchAgentConfig(e){try{const t="http://localhost:3456/api/agents/by-name/"+encodeURIComponent(e),r=await fetch(t)
|
|
5228
5191
|
if(!r.ok)return null
|
|
5229
5192
|
const n=await r.json()
|
|
5230
5193
|
return n.success?n.data??null:null}catch{return null}}async cleanup(){this.logger.info("Cleaning up single-agent workspace manager")}}},9671(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.findPreviousCommit=async function(e,t,r){try{if(!r){const r=await e.raw(["rev-list","--max-count=1","HEAD","--",t])
|
|
@@ -5255,11 +5218,11 @@ if(!u)throw new n.ValidationError("Project ID is required for listing tasks with
|
|
|
5255
5218
|
a.incrementCounter("list_tasks_attempts",1,{hasRequestId:!!i,hasFilters:Object.keys(d).length>0}),s.setProjectId(u)
|
|
5256
5219
|
const h=s.getTaskClient(),g=d
|
|
5257
5220
|
i&&(g.requestId=i),c.info("Listing tasks with filters",{projectId:u,taskFilters:g})
|
|
5258
|
-
const
|
|
5259
|
-
c.info("Raw tasks response data",{responseData:JSON.stringify(
|
|
5260
|
-
let
|
|
5261
|
-
|
|
5262
|
-
const m=
|
|
5221
|
+
const p=await h.listTasks(g)
|
|
5222
|
+
c.info("Raw tasks response data",{responseData:JSON.stringify(p)}),c.info("Tasks response structure",{type:typeof p,isArray:Array.isArray(p),hasData:null!=p,properties:p?Object.keys(p):[],dataPreview:p?JSON.stringify(p).substring(0,200)+"...":"null"})
|
|
5223
|
+
let f=[]
|
|
5224
|
+
p&&"object"==typeof p?"success"in p&&"data"in p?Array.isArray(p.data)?(f=p.data,c.info("Extracted tasks from success/data wrapper",{count:f.length})):p.data&&"object"==typeof p.data&&(f=[p.data],c.info("Extracted single task from success/data wrapper")):"data"in p?Array.isArray(p.data)?(f=p.data,c.info("Extracted tasks from data wrapper",{count:f.length})):p.data&&"object"==typeof p.data&&(f=[p.data],c.info("Extracted single task from data wrapper")):Array.isArray(p)?(f=p,c.info("Tasks response is direct array",{count:f.length})):(f=[p],c.info("Tasks response is single object")):(c.warn("Unexpected response format, using empty array",{responseType:typeof p}),f=[])
|
|
5225
|
+
const m=f
|
|
5263
5226
|
if(c.info(`Retrieved ${m.length} tasks`,{count:m.length,requestId:i,projectId:u}),0===m.length){let e=""
|
|
5264
5227
|
return e=i?`No tasks found for request ${i}.`:`No tasks found for project ${u} with the specified filters.`,l({success:!0,taskCount:0}),{content:[{type:"text",text:e}]}}const y=m.map((e=>`**[${e.id}]** ${e.title}\nStatus: ${e.status}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}`)).join("\n\n")
|
|
5265
5228
|
let w
|
|
@@ -5367,7 +5330,7 @@ try{await o.default.promises.mkdir(u,{recursive:!0})}catch(e){return n.error("Fa
|
|
|
5367
5330
|
try{if(!o.default.existsSync(t)){n.warn("Plugin source not found: "+e.sourceName,{sourcePath:t}),l.errors.push(e.destName)
|
|
5368
5331
|
continue}const c=await o.default.promises.readFile(t,"utf8").catch((()=>null))
|
|
5369
5332
|
if(null===c){n.warn("Could not read plugin source: "+e.sourceName),l.errors.push(e.destName)
|
|
5370
|
-
continue}const d=e.destName.startsWith("lib/")?c:["
|
|
5333
|
+
continue}const d=e.destName.startsWith("lib/")?c:['import { createRequire as __createRequire } from "node:module";\nconst require = __createRequire(import.meta.url);\nconst __plugin = (function() {\n const module = { exports: {} };\n const exports = module.exports;\n (function() {',c," })();\n return module.exports.default || module.exports;\n})();\nexport default __plugin;"].join("\n"),h=i.default.createHash("md5").update(d).digest("hex"),g=r(a)
|
|
5371
5334
|
if(null===g||h!==g){const t=s.default.dirname(a)
|
|
5372
5335
|
t!==u&&await o.default.promises.mkdir(t,{recursive:!0}),await o.default.promises.writeFile(a,d,"utf8"),n.info("Synced plugin: "+e.destName,{reason:null===g?"not installed":"updated"}),l.synced.push(e.destName)}else l.skipped.push(e.destName)}catch(t){n.error("Failed to sync plugin: "+e.destName,{error:t instanceof Error?t.message:"Unknown error"}),l.errors.push(e.destName)}}return l}
|
|
5373
5336
|
const o=n(t(9896)),s=n(t(6928)),i=n(t(6982)),a=[{sourceName:"plugins/hooks/plugin.js",destName:"event-hooks.js"},{sourceName:"plugins/hooks/lib/condition-evaluator.js",destName:"lib/condition-evaluator.js"},{sourceName:"plugins/hooks/lib/hook-utils.js",destName:"lib/hook-utils.js"},{sourceName:"plugins/hooks/lib/dedup-utils.js",destName:"lib/dedup-utils.js"},{sourceName:"plugins/inject-session.js",destName:"inject-session.js"},{sourceName:"plugins/system-logger.js",destName:"system-logger.js"}]},9947(e,exports){function t(e,t){return e.substring(0,t).split("\n").length}function r(e){if(0===e.length)return[]
|