alchemylab 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/60.js +1 -1
- package/dist/cli.js +114 -106
- package/dist/http-server.js +154 -155
- package/dist/index.js +352 -353
- package/dist/mcp-direct.js +154 -155
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -21,13 +21,13 @@ u.info("Task input prepared",{taskInput:JSON.stringify(f)}),u.info("Creating tas
|
|
|
21
21
|
const m=await p.createTask(f)
|
|
22
22
|
u.debug("Task creation response structure",{type:typeof m,isArray:Array.isArray(m),hasData:null!=m,properties:m?Object.keys(m):[],dataPreview:m?JSON.stringify(m).substring(0,200)+"...":"null"})
|
|
23
23
|
const y=(0,o.extractDataFromResponse)(m,{logger:u,operationName:"createTask",defaultValue:{id:"tas"+Date.now().toString().substring(5,11),title:f.title,description:f.description,status:"pending",requestId:f.requestId,projectId:l,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}),w="data"in y?y.data:y,b=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),k=w.title||f.title,I=w.description||f.description,v=w.status||"pending",C=w.requestId||f.requestId
|
|
24
|
-
let E
|
|
25
|
-
w&&"object"==typeof w&&"_workingEndpoint"in w&&(
|
|
24
|
+
let _,E="unknown"
|
|
25
|
+
w&&"object"==typeof w&&"_workingEndpoint"in w&&(E=w._workingEndpoint),u.info("Successfully extracted task data from response",{taskId:b,requestId:C,title:k})
|
|
26
26
|
try{const e=i.getToolRecordClient()
|
|
27
27
|
if(e){const t=await e.createToolRecord({taskId:b,requestId:C,projectId:l,type:"create-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:k,taskDescription:I,taskStatus:v},note:"Created task "+k})
|
|
28
|
-
|
|
28
|
+
_=t?.id}}catch(e){u.error("Failed to create tool record for task creation, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:b,requestId:C})}h({success:!0,requestId:a.requestId,projectId:l}),u.info("Task created successfully",{taskId:b,requestId:C,title:k,projectId:l})
|
|
29
29
|
let q="Created Task "+b
|
|
30
|
-
return
|
|
30
|
+
return _&&(q+=`\n[RECORD:${_}]`),{content:[{type:"text",text:q}]}}catch(r){if(u.error("Failed to create task",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new tasks")||r.message.includes("disabled due to tier limits")||r.message.includes("Project is inactive due to tier limits")))u.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
|
|
31
31
|
else{const n=i.getToolRecordClient()
|
|
32
32
|
n&&await n.createToolRecord({requestId:e.requestId,projectId:t.projectId,type:"create-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.title,taskDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),error:(0,s.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create task: "+e.title})}}catch(e){u.error("Failed to create failure record for task creation",{error:e instanceof Error?e.message:e+""})}h({success:!1,error:r instanceof Error?r.name:"unknown"})
|
|
33
33
|
let o=(0,s.getErrorMessage)(r),c=""
|
|
@@ -44,9 +44,9 @@ var t={}
|
|
|
44
44
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
45
45
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
46
46
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.McpServer=void 0,exports.resetStdoutWrite=function(){process.stdout.write=x},exports.getMcpServer=r,exports.createServer=function(e,t,n,o,s={}){return r(e,t,n,o,s)}
|
|
47
|
-
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),g=t(9567),p=t(3444),f=t(7660),m=t(1253),y=t(5172),w=t(7976),b=i(t(7478)),k=t(4139),I=new Set,v=t(9860),C=t(1472),
|
|
47
|
+
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),g=t(9567),p=t(3444),f=t(7660),m=t(1253),y=t(5172),w=t(7976),b=i(t(7478)),k=t(4139),I=new Set,v=t(9860),C=t(1472),_=t(3328),E=t(8955),q=t(3217),S=t(8411),T=t(5278),P=t(446),R=t(9060),M=t(8824),j=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),x=process.stdout.write,O=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
|
|
48
48
|
!(0,p.isDebugToolsEnabled)()||O&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,p.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&j.debug("Stdout output",{content:e.substring(0,100),length:e.length}),x.call(process.stdout,e)}catch(e){return j.error("Error in safeStdoutWrite",{error:e+""}),!0}})
|
|
49
|
-
class A{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.clientInfo=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.multiAgentMode=o.multiAgentMode||!1,this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,multiAgentMode:o.multiAgentMode||!1,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,k.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new f.ProjectContext(e,t),this.tokenManager=new m.TokenManager(t,e,{remoteServerUrl:n}),this.lockOverrideManager=new P.LockOverrideManager(t),this.configManager=new R.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},
|
|
49
|
+
class A{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.clientInfo=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.multiAgentMode=o.multiAgentMode||!1,this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,multiAgentMode:o.multiAgentMode||!1,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,k.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new f.ProjectContext(e,t),this.tokenManager=new m.TokenManager(t,e,{remoteServerUrl:n}),this.lockOverrideManager=new P.LockOverrideManager(t),this.configManager=new R.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.interceptConnectMethod(),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
|
|
50
50
|
const e=this.workspaceManager.getCurrentContext()
|
|
51
51
|
return{currentBranch:e.branchName,activeRequestId:e.requestId,isOnMainBranch:e.isMainBranch}}async updateBranchState(e,t){this.logger.debug("updateBranchState called - managed by WorkspaceManager",{branch:e,requestId:t})}async getCurrentBranchContext(){if(!this.workspaceManager)return{branch:null,requestId:null,isMain:!0}
|
|
52
52
|
const e=this.workspaceManager.getCurrentContext()
|
|
@@ -92,8 +92,8 @@ const o=t(6982)
|
|
|
92
92
|
e=`prj_${Date.now().toString().substring(5)}_${o.randomBytes(4).toString("hex")}`,this.logger.warn("Using fallback project ID",{projectId:e,reason:"initialization_failure"})
|
|
93
93
|
try{const t={id:e,name:d.default.basename(this.basePath)||"Local Project",description:"Project for "+d.default.basename(this.basePath),status:"active",createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString(),metadata:{basePath:this.basePath,alchemyPath:this.alchemyPath,fallback:!0}},r=d.default.join(this.alchemyPath,"project.json")
|
|
94
94
|
u.default.writeFileSync(r,JSON.stringify(t,null,2)),this.logger.debug("Successfully wrote fallback project.json file")}catch(e){this.logger.error("Failed to write fallback project.json",{error:e instanceof Error?e.message:e+""})}}this.logger.info("Server using project ID",{projectId:e})
|
|
95
|
-
const r=this.remoteServerUrl||"https://api.alchemylabcode.com",n=await
|
|
96
|
-
this.apiClient=n,await(0,
|
|
95
|
+
const r=this.remoteServerUrl||"https://api.alchemylabcode.com",n=await _.ClientFactory.createClient(r,this.logger,this.metrics,{workingDir:this.basePath,alchemyPath:this.alchemyPath,tokenManager:this.tokenManager,circuitBreakerThreshold:5,circuitBreakerResetTime:3e4,retryAttempts:3,retryDelay:1e3})
|
|
96
|
+
this.apiClient=n,await(0,E.initializeAgentRegistry)(this.apiClient,this.logger),this.logger.debug("Agent registry initialized"),this.documentFileManager=new T.DocumentFileManager(this.apiClient,this.logger),await this.documentFileManager.initialize(),this.logger.debug("Document file manager initialized"),e&&"PENDING_REMOTE_CREATION"!==e&&(this.apiClient.setProjectId(e),this.logger.debug("Set project ID on API client",{projectId:e}))
|
|
97
97
|
try{const r=this.apiClient.getProjectClient()
|
|
98
98
|
if(this.existingProjectId)this.logger.info("Skipping project synchronization - using existing project from HTTP server",{projectId:e})
|
|
99
99
|
else if("PENDING_REMOTE_CREATION"===e){const{SimpleProjectCreationLock}=await t.e(800).then(t.t.bind(t,3800,23)),n=new SimpleProjectCreationLock(this.basePath,this.logger),o=await n.acquireLock()
|
|
@@ -166,7 +166,9 @@ try{const t=await b.getCurrentBranch(this.git,this.logger,this.metrics)
|
|
|
166
166
|
return this.logger.info("Single-agent Git instance branch status",{requestId:e,currentBranch:t,expectedBranch:n.branchName,basePath:n.basePath}),{success:!0,message:`Switched to request ${e} context`}}catch(t){return this.logger.warn("Branch verification failed but continuing",{requestId:e,error:t instanceof Error?t.message:t+""}),{success:!0,message:`Switched to request ${e} context (branch verification warning)`}}}catch(t){return this.logger.error("Failed to switch to single-agent request context",{requestId:e,error:(0,M.getErrorMessage)(t)}),{success:!1,message:"Failed to switch to request context: "+(0,M.getErrorMessage)(t)}}}async getEffectiveBasePath(e){if(!this.multiAgentMode||!this.workspaceManager||!e)return this.basePath
|
|
167
167
|
const t=await this.workspaceManager.getWorkspaceInfo(e)
|
|
168
168
|
return t?.path||this.basePath}}exports.McpServer=A
|
|
169
|
-
const D=new Map},
|
|
169
|
+
const D=new Map},213(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
170
|
+
const r=t(6183),n=t(3707)
|
|
171
|
+
exports.def={name:"quick_write",description:"Create or update a file or document. Wraps the change in a request/task workflow that auto-completes.\n\nUse 'path' for filesystem files or 'documentId' for tracked documents.\nSet append:true to add content to existing content.\n\nRequires: title, description, path/documentId, content.",schema:r.QuickWriteSchema,annotations:{title:"Quick Write",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleQuickChange)(e,"write",t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},233(e,exports,t){function r(e,t){const r=e.toLowerCase().indexOf(t.toLowerCase())
|
|
170
172
|
return-1===r?e:`${e.substring(0,r)}**${e.substring(r,r+t.length)}**${e.substring(r+t.length)}`}function n(e,t,r){const n=e.toLowerCase().indexOf(t)
|
|
171
173
|
if(-1===n)return e.substring(0,r)+"..."
|
|
172
174
|
const o=Math.max(0,n-50),s=Math.min(e.length,n+t.length+100)
|
|
@@ -295,20 +297,15 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
295
297
|
var t={}
|
|
296
298
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
297
299
|
return o(t,e),t})
|
|
298
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTaskOperations=async function(e,t,r,n,o
|
|
299
|
-
try{
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
switch(p.info("Processing task_operations",{taskId:h,operation:f}),f){case"create":p.info("Routing to create-task handler",{requestId:n.requestId,title:n.create.title}),y=await(0,u.handleCreateTask)({requestId:n.requestId,title:n.create.title,description:n.create.description},t,r,p,o,s,g)
|
|
303
|
-
break
|
|
304
|
-
case"complete":p.info("Routing to complete-task handler",{taskId:h,summary:m.summary}),y=await(0,c.handleCompleteTask)({taskId:h,summary:m.summary},t,r,p,o)
|
|
305
|
-
break
|
|
306
|
-
case"get-info":p.info("Routing to get-task-information handler",{taskId:h}),y=await(0,l.handleGetTaskInformation)({taskId:h},t,r,p,o)
|
|
300
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTaskOperations=async function(e,t,r,n,o){const s=n.child({tool:"task_operations"})
|
|
301
|
+
try{const n=a.validateArgs(e,i.TaskOperationsSchema),{taskId:d,operation:u}=n
|
|
302
|
+
let h
|
|
303
|
+
switch(s.info("Processing task_operations",{taskId:d,operation:u}),u){case"get-info":s.info("Routing to get-task-information handler",{taskId:d}),h=await(0,c.handleGetTaskInformation)({taskId:d},t,r,s,o)
|
|
307
304
|
break
|
|
308
|
-
case"list":
|
|
305
|
+
case"list":s.info("Routing to list-tasks handler",{requestId:n.requestId}),h=await(0,l.handleListTasks)({requestId:n.requestId,filters:n.list?.filters},t,r,s,o)
|
|
309
306
|
break
|
|
310
|
-
default:throw Error("Unknown operation type: "+
|
|
311
|
-
const i=t(6183),a=s(t(5967)),c=t(
|
|
307
|
+
default:throw Error("Unknown operation type: "+u)}return s.info("task_operations completed",{taskId:d,operation:u,success:!h.isError}),o.incrementCounter("task_operations_total",1,{operation:u,success:!h.isError}),h}catch(e){return s.error("task_operations failed",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("task_operations_errors",1),{content:[{type:"text",text:"\u274c **Task Operations Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
308
|
+
const i=t(6183),a=s(t(5967)),c=t(3420),l=t(9863),d=t(8824)},441(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.BAD_REQUEST=exports.INTERNAL_ERROR=exports.NOT_FOUND=exports.FORBIDDEN=exports.UNAUTHORIZED=exports.VALIDATION_ERROR=exports.MCP_PROTOCOL_ERROR=exports.REQUEST_VALIDATION_FAILED=exports.REQUEST_ID_INVALID_FORMAT=exports.REQUEST_NOT_FOUND=exports.CONNECTION_ERROR=exports.SERVICE_UNAVAILABLE=exports.CONNECTION_TIMEOUT=exports.SERVER_ERROR=exports.NETWORK_ERROR=exports.TASK_VALIDATION_FAILED=exports.TASK_ID_INVALID_FORMAT=exports.TASK_NOT_FOUND=void 0,exports.TASK_NOT_FOUND="TASK_NOT_FOUND",exports.TASK_ID_INVALID_FORMAT="TASK_ID_INVALID_FORMAT",exports.TASK_VALIDATION_FAILED="TASK_VALIDATION_FAILED",exports.NETWORK_ERROR="NETWORK_ERROR",exports.SERVER_ERROR="SERVER_ERROR",exports.CONNECTION_TIMEOUT="CONNECTION_TIMEOUT",exports.SERVICE_UNAVAILABLE="SERVICE_UNAVAILABLE",exports.CONNECTION_ERROR="CONNECTION_ERROR",exports.REQUEST_NOT_FOUND="REQUEST_NOT_FOUND",exports.REQUEST_ID_INVALID_FORMAT="REQUEST_ID_INVALID_FORMAT",exports.REQUEST_VALIDATION_FAILED="REQUEST_VALIDATION_FAILED",exports.MCP_PROTOCOL_ERROR="MCP_PROTOCOL_ERROR",exports.VALIDATION_ERROR="VALIDATION_ERROR",exports.UNAUTHORIZED="UNAUTHORIZED",exports.FORBIDDEN="FORBIDDEN",exports.NOT_FOUND="NOT_FOUND",exports.INTERNAL_ERROR="INTERNAL_ERROR",exports.BAD_REQUEST="BAD_REQUEST"},446(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.LockOverrideManager=void 0,exports.createLockOverrideManager=function(e){return new n(e)}
|
|
312
309
|
const r=t(6982)
|
|
313
310
|
class n{constructor(e){this.passwords=new Map,this.cleanupInterval=null,this.logger=e.child({component:"lock-override-manager"}),this.cleanupInterval=setInterval((()=>{this.cleanupExpiredPasswords()}),6e4)}generatePassword(e,t){const n=(0,r.randomBytes)(6).toString("base64url").substring(0,8),o={password:n,requestId:e,createdAt:Date.now(),validityMinutes:t}
|
|
314
311
|
return this.passwords.set(e,o),this.logger.debug("Generated lock override password",{requestId:e,validityMinutes:t,expiresAt:new Date(o.createdAt+6e4*t).toISOString()}),n}validatePassword(e,t){const r=this.passwords.get(e)
|
|
@@ -462,9 +459,9 @@ const A=new v.FileOperationsClient(T,n.child({component:"file-client"}),o,x,M,j)
|
|
|
462
459
|
R.registerClient(A)
|
|
463
460
|
const D=new C.ProxyClient(T,n.child({component:"proxy-client"}),o,x,M,j)
|
|
464
461
|
R.registerClient(D)
|
|
465
|
-
const $=new
|
|
462
|
+
const $=new _.RequestClient(T,n.child({component:"request-client"}),o,x,M,j)
|
|
466
463
|
$.setAuthToken(M),(0,d.isDebugToolsEnabled)()&&n.debug("Explicitly set token on RequestClient",{tokenPresent:!!M}),R.registerClient($)
|
|
467
|
-
const F=new
|
|
464
|
+
const F=new E.DocumentClient(T,n.child({component:"document-client"}),o,x,M,j)
|
|
468
465
|
R.registerClient(F)
|
|
469
466
|
const N=new q.ToolRecordClient(T,n.child({component:"tool-record-client"}),o,x,M,j)
|
|
470
467
|
R.registerClient(N)
|
|
@@ -544,22 +541,22 @@ throw e}}catch(e){r(e)}})),e.patch("/api/proxy/*",W,(async(e,t,r)=>{try{const r=
|
|
|
544
541
|
try{const n=await L.proxyPatch(r,e.body)
|
|
545
542
|
t.json(n)}catch(e){if(e instanceof Error&&e.message.includes("ECONNREFUSED"))return t.status(503).json({success:!1,error:"Remote server is unreachable",remotePath:r})
|
|
546
543
|
throw e}}catch(e){r(e)}}))}
|
|
547
|
-
const a=i(t(7252)),c=i(t(6928)),l=i(t(1943)),d=t(3444),u=t(9860),h=t(6776),g=t(6476),p=t(3306),f=t(4079),m=t(3895),y=s(t(5967)),w=t(4710),b=t(5681),k=t(8824),I=t(2968),v=t(6153),C=t(1887),
|
|
544
|
+
const a=i(t(7252)),c=i(t(6928)),l=i(t(1943)),d=t(3444),u=t(9860),h=t(6776),g=t(6476),p=t(3306),f=t(4079),m=t(3895),y=s(t(5967)),w=t(4710),b=t(5681),k=t(8824),I=t(2968),v=t(6153),C=t(1887),_=t(1666),E=t(9884),q=t(922),S=t(3328)},1253(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
548
545
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.TokenManager=void 0
|
|
549
|
-
const n=r(t(6928)),o=r(t(1943)),s=r(t(6982)),i=r(t(857)),a=t(
|
|
550
|
-
exports.TokenManager=class{constructor(e,t,r={}){this.projectId=null,this.encryptionKey=null,this.pendingAuthCheck=!1,this.tempAuthCode=null,this.CACHE_TTL_MS=6e4,this.TOKEN_CACHE={manualToken:null,encryptedToken:null,hasValidToken:null},this.initPromise=null,this.initialized=!1,this.logger=e.child({component:"token-manager"}),this.remoteServerUrl=r.remoteServerUrl||"https://api.alchemylabcode.com",this.allowInteractiveAuth=!1!==r.allowInteractiveAuth,void 0!==r.cacheTtlMs&&r.cacheTtlMs>0&&(this.CACHE_TTL_MS=r.cacheTtlMs),this.serverInstallDir=this.getModuleDir(),this.tokenDirPath=
|
|
551
|
-
return e.includes("node_modules")?n.default.join(t,".
|
|
546
|
+
const n=r(t(6928)),o=r(t(1943)),s=r(t(6982)),i=r(t(857)),a=t(9067),c=t(8824),l="alchemy-lab"
|
|
547
|
+
exports.TokenManager=class{constructor(e,t,r={}){this.projectId=null,this.encryptionKey=null,this.pendingAuthCheck=!1,this.tempAuthCode=null,this.CACHE_TTL_MS=6e4,this.TOKEN_CACHE={manualToken:null,encryptedToken:null,hasValidToken:null},this.initPromise=null,this.initialized=!1,this.logger=e.child({component:"token-manager"}),this.remoteServerUrl=r.remoteServerUrl||"https://api.alchemylabcode.com",this.allowInteractiveAuth=!1!==r.allowInteractiveAuth,void 0!==r.cacheTtlMs&&r.cacheTtlMs>0&&(this.CACHE_TTL_MS=r.cacheTtlMs),this.serverInstallDir=this.getModuleDir(),this.tokenDirPath=this.serverInstallDir,this.authFlow=new a.ExternalAuthFlow(e,this.remoteServerUrl),this.logger.info("TokenManager initialized",{workingDir:t,serverInstallDir:this.serverInstallDir,tokenDirPath:this.tokenDirPath,allowInteractiveAuth:this.allowInteractiveAuth,cacheTtlMs:this.CACHE_TTL_MS}),this.generateEncryptionKey()}getModuleDir(){const e=__dirname||process.cwd(),t=i.default.homedir()
|
|
548
|
+
return e.includes("node_modules")?n.default.join(t,".alchemy_lab","tokens"):n.default.join(t,".alchemy_lab","tokens-dev")}async initialize(){return this.initPromise||(this.initPromise=this.ensureTokenDirectoryExists().then((()=>{this.initialized=!0,this.logger.info("TokenManager initialization completed")})).catch((e=>{throw this.logger.error("TokenManager initialization failed",{error:e instanceof Error?e.stack:e+""}),Error("TokenManager initialization failed")}))),this.initPromise}getStableMachineId(){try{const e=t(857),r=n.default.join(this.serverInstallDir,".machine-id")
|
|
552
549
|
try{const e=t(9896).readFileSync(r,"utf8").trim()
|
|
553
550
|
if(e&&e.length>0)return e}catch{}const o=e.platform(),i=e.arch(),a=e.homedir(),c=e.cpus(),l=`${o}-${i}-${c&&c.length>0?c[0].model:"unknown"}-${a}`,d=s.default.createHash("sha256").update(l).digest("hex")
|
|
554
|
-
try{t(9896).writeFileSync(r,d,"utf8"),this.logger.debug("Created new machine ID file",{path:r})}catch(e){this.logger.warn("Could not persist machine ID, will regenerate on restart",{error:e instanceof Error?e.message:e+""})}return d}catch(e){return this.logger.error("Error getting stable machine ID",{error:(0,
|
|
555
|
-
this.encryptionKey=s.default.createHash("sha256").update(n).digest(),this.logger.debug("Generated encryption key using stable machine ID")}catch(e){this.logger.error("Error generating encryption key",{error:(0,
|
|
556
|
-
return s.default.createHash("sha256").update(n).digest()}catch(e){return this.logger.error("Error generating legacy encryption key",{error:(0,
|
|
551
|
+
try{t(9896).writeFileSync(r,d,"utf8"),this.logger.debug("Created new machine ID file",{path:r})}catch(e){this.logger.warn("Could not persist machine ID, will regenerate on restart",{error:e instanceof Error?e.message:e+""})}return d}catch(e){return this.logger.error("Error getting stable machine ID",{error:(0,c.getErrorMessage)(e)}),s.default.randomBytes(32).toString("hex")}}generateEncryptionKey(){try{const e=t(857).platform(),r=this.getStableMachineId(),n=`${l}-${e}-${r}`
|
|
552
|
+
this.encryptionKey=s.default.createHash("sha256").update(n).digest(),this.logger.debug("Generated encryption key using stable machine ID")}catch(e){this.logger.error("Error generating encryption key",{error:(0,c.getErrorMessage)(e)}),this.encryptionKey=Buffer.from(l.repeat(4),"utf8")}}generateLegacyEncryptionKey(){try{const e=t(857).platform(),r=t(857).hostname(),n=`${l}-${e}-${r}`
|
|
553
|
+
return s.default.createHash("sha256").update(n).digest()}catch(e){return this.logger.error("Error generating legacy encryption key",{error:(0,c.getErrorMessage)(e)}),Buffer.from(l.repeat(4),"utf8")}}async ensureTokenDirectoryExists(){try{await o.default.mkdir(this.tokenDirPath,{recursive:!0}),this.logger.debug("Token directory ensured exists",{path:this.tokenDirPath})}catch(e){throw this.logger.error("Error creating token directory",{path:this.tokenDirPath,error:(0,c.getErrorMessage)(e)}),Error("Error creating token directory: "+this.tokenDirPath)}}setProjectId(e){this.projectId=e,this.logger.info("Set project ID for token manager",{projectId:e})}getAccountKey(){return"default-user-"+s.default.createHash("sha256").update(this.remoteServerUrl).digest("hex").substring(0,8)}getTokenFilePath(e){const t=e.replace(/[^a-zA-Z0-9]/g,"_")
|
|
557
554
|
return n.default.join(this.tokenDirPath,t+".token")}invalidateCache(){this.logger.debug("Invalidating all token caches"),this.TOKEN_CACHE.manualToken=null,this.TOKEN_CACHE.encryptedToken=null,this.TOKEN_CACHE.hasValidToken=null}async checkForManualToken(){const e=Date.now(),t=n.default.join(this.tokenDirPath,"manual-token.json")
|
|
558
555
|
if(this.TOKEN_CACHE.manualToken&&e<this.TOKEN_CACHE.manualToken.expiresAt){const t=this.TOKEN_CACHE.manualToken
|
|
559
556
|
return this.logger.debug("Using cached manual token check result",{ageSecs:Math.round((e-t.timestamp)/1e3),exists:t.exists,hasToken:null!==t.value}),t.exists&&t.value?t.value:null}this.TOKEN_CACHE.manualToken&&e-(this.TOKEN_CACHE.manualToken.lastCheck||0)<=2*this.CACHE_TTL_MS||this.logger.debug("Checking for manual token file",{tokenFilePath:t})
|
|
560
557
|
try{let r=!1,n=null
|
|
561
558
|
try{await o.default.stat(t),r=!0,this.TOKEN_CACHE.manualToken&&e-(this.TOKEN_CACHE.manualToken.lastCheck||0)<=2*this.CACHE_TTL_MS||this.logger.debug("Manual token file exists")}catch{this.TOKEN_CACHE.manualToken&&e-(this.TOKEN_CACHE.manualToken.lastCheck||0)<=2*this.CACHE_TTL_MS||this.logger.debug("Manual token file does not exist")}if(r)try{const r=await o.default.readFile(t,"utf8"),s=JSON.parse(r)
|
|
562
|
-
new Date(s.expiresAt)>new Date?(n=s,this.TOKEN_CACHE.manualToken&&e-(this.TOKEN_CACHE.manualToken.lastCheck||0)<=2*this.CACHE_TTL_MS||this.logger.debug("Valid manual token found",{username:n.username,expiresAt:n.expiresAt})):this.logger.debug("Manual token has expired",{expiresAt:s.expiresAt})}catch(e){this.logger.error("Error parsing manual token file",{error:e instanceof Error?e.message:e+""})}return this.TOKEN_CACHE.manualToken={value:n,timestamp:e,expiresAt:e+this.CACHE_TTL_MS,lastCheck:e,exists:r},n}catch(e){return this.logger.error("Error checking for manual token",{error:(0,
|
|
559
|
+
new Date(s.expiresAt)>new Date?(n=s,this.TOKEN_CACHE.manualToken&&e-(this.TOKEN_CACHE.manualToken.lastCheck||0)<=2*this.CACHE_TTL_MS||this.logger.debug("Valid manual token found",{username:n.username,expiresAt:n.expiresAt})):this.logger.debug("Manual token has expired",{expiresAt:s.expiresAt})}catch(e){this.logger.error("Error parsing manual token file",{error:e instanceof Error?e.message:e+""})}return this.TOKEN_CACHE.manualToken={value:n,timestamp:e,expiresAt:e+this.CACHE_TTL_MS,lastCheck:e,exists:r},n}catch(e){return this.logger.error("Error checking for manual token",{error:(0,c.getErrorMessage)(e)}),null}}encrypt(e){if(!this.encryptionKey)throw Error("Encryption key not available")
|
|
563
560
|
const t=s.default.randomBytes(16),r=s.default.createCipheriv("aes-256-cbc",this.encryptionKey,t)
|
|
564
561
|
let n=r.update(e,"utf8","hex")
|
|
565
562
|
return n+=r.final("hex"),`${t.toString("hex")}:${n}`}decrypt(e){if(!this.encryptionKey)throw Error("Encryption key not available")
|
|
@@ -573,7 +570,7 @@ const o=Buffer.from(r,"hex"),i=s.default.createDecipheriv("aes-256-cbc",t,o)
|
|
|
573
570
|
let a=i.update(n,"hex","utf8")
|
|
574
571
|
return a+=i.final("utf8"),a}catch(e){throw e}}async storeToken(e){!this.initPromise&&this.initialized?await this.initPromise:this.initialized||await this.initialize()
|
|
575
572
|
try{const t=this.getAccountKey(),r=this.getTokenFilePath(t),n=JSON.stringify(e),s=this.encrypt(n)
|
|
576
|
-
await o.default.writeFile(r,s,"utf8"),this.logger.info("Token stored securely",{username:e.username,expiresAt:e.expiresAt}),this.invalidateCache()}catch(e){throw this.logger.error("Error storing token",{error:(0,
|
|
573
|
+
await o.default.writeFile(r,s,"utf8"),this.logger.info("Token stored securely",{username:e.username,expiresAt:e.expiresAt}),this.invalidateCache()}catch(e){throw this.logger.error("Error storing token",{error:(0,c.getErrorMessage)(e)}),Error("Failed to store token securely")}}async getToken(){!this.initPromise&&this.initialized?await this.initPromise:this.initialized||await this.initialize()
|
|
577
574
|
try{if(this.hasPendingAuth()&&this.tempAuthCode){const e=await this.checkAuthStatus(this.tempAuthCode)
|
|
578
575
|
if(e)return e}const e=await this.checkForManualToken()
|
|
579
576
|
if(e)return e
|
|
@@ -581,32 +578,32 @@ const t=Date.now()
|
|
|
581
578
|
if(this.TOKEN_CACHE.encryptedToken&&t<this.TOKEN_CACHE.encryptedToken.expiresAt){const e=this.TOKEN_CACHE.encryptedToken
|
|
582
579
|
return this.logger.debug("Using cached encrypted token",{ageSecs:Math.round((t-e.timestamp)/1e3),hasToken:null!==e.value}),e.value}const r=this.getAccountKey(),n=this.getTokenFilePath(r)
|
|
583
580
|
try{await o.default.stat(n)}catch{return this.logger.debug("No encrypted token file found"),this.TOKEN_CACHE.encryptedToken={value:null,timestamp:t,expiresAt:t+this.CACHE_TTL_MS,lastCheck:t,exists:!1},this.allowInteractiveAuth&&!this.hasPendingAuth()?(this.logger.debug("No stored token found, starting authentication flow"),this.startAuthenticationFlow().catch((e=>{this.logger.error("Failed to start authentication flow",{error:e instanceof Error?e.message:e+""})}))):this.logger.debug("Interactive authentication disabled or already pending"),null}try{const e=await o.default.readFile(n,"utf8"),t=this.decrypt(e),r=JSON.parse(t),s=new Date(r.expiresAt),i=new Date,a=s.getTime()-i.getTime(),c=a/36e5
|
|
584
|
-
return this.logger.info("Token expiration check details",{tokenExpiresAt:r.expiresAt,currentTime:i.toISOString(),isExpired:i>=s,timeUntilExpiryMs:a,timeUntilExpiryHours:Math.round(100*c)/100,username:r.username,systemTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone}),s>i?(this.logger.info("Retrieved valid token from storage",{username:r.username,expiresAt:r.expiresAt}),this.TOKEN_CACHE.encryptedToken={value:r,timestamp:Date.now(),expiresAt:Date.now()+this.CACHE_TTL_MS,lastCheck:Date.now(),exists:!0},r):(this.logger.info("Stored token has expired",{expiresAt:r.expiresAt,expiredByMs:i.getTime()-s.getTime(),expiredByHours:Math.round((i.getTime()-s.getTime())/36e5*100)/100}),this.TOKEN_CACHE.encryptedToken={value:null,timestamp:Date.now(),expiresAt:Date.now()+this.CACHE_TTL_MS,lastCheck:Date.now(),exists:!1},null)}catch(e){this.logger.error("Error reading/decrypting token file",{error:(0,
|
|
581
|
+
return this.logger.info("Token expiration check details",{tokenExpiresAt:r.expiresAt,currentTime:i.toISOString(),isExpired:i>=s,timeUntilExpiryMs:a,timeUntilExpiryHours:Math.round(100*c)/100,username:r.username,systemTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone}),s>i?(this.logger.info("Retrieved valid token from storage",{username:r.username,expiresAt:r.expiresAt}),this.TOKEN_CACHE.encryptedToken={value:r,timestamp:Date.now(),expiresAt:Date.now()+this.CACHE_TTL_MS,lastCheck:Date.now(),exists:!0},r):(this.logger.info("Stored token has expired",{expiresAt:r.expiresAt,expiredByMs:i.getTime()-s.getTime(),expiredByHours:Math.round((i.getTime()-s.getTime())/36e5*100)/100}),this.TOKEN_CACHE.encryptedToken={value:null,timestamp:Date.now(),expiresAt:Date.now()+this.CACHE_TTL_MS,lastCheck:Date.now(),exists:!1},null)}catch(e){this.logger.error("Error reading/decrypting token file",{error:(0,c.getErrorMessage)(e),path:n})
|
|
585
582
|
try{const e=n+".backup"
|
|
586
|
-
await o.default.rename(n,e),this.logger.info("Moved corrupted token file to backup",{from:n,to:e})}catch(e){this.logger.error("Error creating backup of corrupted token file",{error:e instanceof Error?e.message:e+""})}return this.TOKEN_CACHE.encryptedToken={value:null,timestamp:Date.now(),expiresAt:Date.now()+this.CACHE_TTL_MS,lastCheck:Date.now(),exists:!1},null}}catch(e){return this.logger.error("Error retrieving token",{error:(0,
|
|
583
|
+
await o.default.rename(n,e),this.logger.info("Moved corrupted token file to backup",{from:n,to:e})}catch(e){this.logger.error("Error creating backup of corrupted token file",{error:e instanceof Error?e.message:e+""})}return this.TOKEN_CACHE.encryptedToken={value:null,timestamp:Date.now(),expiresAt:Date.now()+this.CACHE_TTL_MS,lastCheck:Date.now(),exists:!1},null}}catch(e){return this.logger.error("Error retrieving token",{error:(0,c.getErrorMessage)(e)}),null}}async removeToken(){!this.initPromise&&this.initialized?await this.initPromise:this.initialized||await this.initialize()
|
|
587
584
|
try{const e=this.getAccountKey(),t=this.getTokenFilePath(e)
|
|
588
|
-
try{await o.default.stat(t)}catch{return this.logger.info("No token file to remove"),!1}return await o.default.unlink(t),this.logger.info("Token removed from secure storage"),this.invalidateCache(),!0}catch(e){return this.logger.error("Error removing token",{error:(0,
|
|
585
|
+
try{await o.default.stat(t)}catch{return this.logger.info("No token file to remove"),!1}return await o.default.unlink(t),this.logger.info("Token removed from secure storage"),this.invalidateCache(),!0}catch(e){return this.logger.error("Error removing token",{error:(0,c.getErrorMessage)(e)}),!1}}async hasValidToken(){const e=Date.now()
|
|
589
586
|
if(this.TOKEN_CACHE.hasValidToken&&e<this.TOKEN_CACHE.hasValidToken.expiresAt){const t=this.TOKEN_CACHE.hasValidToken
|
|
590
587
|
return this.logger.debug("Using cached hasValidToken result",{ageSecs:Math.round((e-t.timestamp)/1e3),hasToken:t.value}),t.value}this.logger.debug("Checking if valid token exists (cache miss or expired)")
|
|
591
588
|
const t=null!==await this.getToken()
|
|
592
589
|
return this.TOKEN_CACHE.hasValidToken={value:t,timestamp:e,expiresAt:e+this.CACHE_TTL_MS,lastCheck:e,exists:t},t}getTokenDirectoryPath(){return this.tokenDirPath}getManualTokenFilePath(){return n.default.join(this.tokenDirPath,"manual-token.json")}logTokenLocationInstructions(){const e=this.getManualTokenFilePath()
|
|
593
590
|
console.log("========================================"),console.log("To use MCP server, you need to authenticate."),console.log("Token file location: "+e),console.log("You can either:"),console.log('\n1. Use the authenticate tool (recommended)\n2. Manually place a token file at the above location\n3. Set up automatic authentication flow\n\nFor manual token placement, create a JSON file with:\n{\n "token": "your_token_here",\n "userId": "your_user_id",\n "username": "your_username", \n "role": "user",\n "expiresAt": "2025-12-31T23:59:59.000Z"\n}\n'),console.log("For more information, see the authentication documentation."),console.log("========================================")}async startAuthenticationFlow(){this.pendingAuthCheck=!0
|
|
594
591
|
try{const{tempCode:e,authUrl:t}=await this.authFlow.startAuthFlow()
|
|
595
|
-
return this.tempAuthCode=e,this.logger.info("Started external authentication flow",{tempCode:e,authUrl:t}),this.authFlow.startPolling(e,(async t=>{this.logger.info("Authentication flow completed",{tempCode:e.substring(0,4)+"***",username:t.username}),await this.storeToken(t),this.pendingAuthCheck=!1,this.tempAuthCode=null,this.invalidateCache(),console.log("Authentication successful!"),console.log(`Welcome, ${t.username}!`),console.log("You can now use all MCP tools and features."),console.log("========================================")}),(()=>{this.logger.info("Authentication flow timed out",{tempCode:e.substring(0,4)+"***"}),this.pendingAuthCheck=!1,this.tempAuthCode=null,console.log("Authentication flow timed out."),console.log("Please try again or manually place a token file."),console.log("Token file location:"),console.log(""+this.getManualTokenFilePath()),console.log("========================================")}),(t=>{this.logger.error("Authentication flow error",{tempCode:e.substring(0,4)+"***",error:t}),this.pendingAuthCheck=!1,this.tempAuthCode=null,console.log("Authentication flow error."),console.log("Error: "+t),console.log("Please try again or manually place a token file."),console.log(""+this.getManualTokenFilePath()),console.log("========================================")})),{tempCode:e,authUrl:t}}catch(e){throw this.logger.error("Error starting authentication flow",{error:(0,
|
|
592
|
+
return this.tempAuthCode=e,this.logger.info("Started external authentication flow",{tempCode:e,authUrl:t}),this.authFlow.startPolling(e,(async t=>{this.logger.info("Authentication flow completed",{tempCode:e.substring(0,4)+"***",username:t.username}),await this.storeToken(t),this.pendingAuthCheck=!1,this.tempAuthCode=null,this.invalidateCache(),console.log("Authentication successful!"),console.log(`Welcome, ${t.username}!`),console.log("You can now use all MCP tools and features."),console.log("========================================")}),(()=>{this.logger.info("Authentication flow timed out",{tempCode:e.substring(0,4)+"***"}),this.pendingAuthCheck=!1,this.tempAuthCode=null,console.log("Authentication flow timed out."),console.log("Please try again or manually place a token file."),console.log("Token file location:"),console.log(""+this.getManualTokenFilePath()),console.log("========================================")}),(t=>{this.logger.error("Authentication flow error",{tempCode:e.substring(0,4)+"***",error:t}),this.pendingAuthCheck=!1,this.tempAuthCode=null,console.log("Authentication flow error."),console.log("Error: "+t),console.log("Please try again or manually place a token file."),console.log(""+this.getManualTokenFilePath()),console.log("========================================")})),{tempCode:e,authUrl:t}}catch(e){throw this.logger.error("Error starting authentication flow",{error:(0,c.getErrorMessage)(e)}),this.pendingAuthCheck=!1,this.tempAuthCode=null,e}}hasPendingAuth(){return this.pendingAuthCheck||!!this.tempAuthCode}getAuthStatus(){return this.hasPendingAuth()?{hasToken:!1,isPendingAuth:!0,tempCode:this.tempAuthCode,authUrl:this.authFlow.getAuthUrl(this.tempAuthCode)}:{hasToken:!1,isPendingAuth:!1}}async checkAuthStatus(e){if(!e)return null
|
|
596
593
|
try{const t=this.authFlow.getPollingStatus()
|
|
597
|
-
if(t.status===
|
|
598
|
-
if(t.status===
|
|
594
|
+
if(t.status===a.PollingStatus.AUTHENTICATED&&t.tokenInfo)return this.logger.info("Authentication polling has token available",{tempCode:e.substring(0,4)+"***",username:t.tokenInfo.username}),t.tokenInfo
|
|
595
|
+
if(t.status===a.PollingStatus.ERROR||t.status===a.PollingStatus.TIMEOUT)return this.pendingAuthCheck=!1,this.tempAuthCode=null,null
|
|
599
596
|
const r=this.authFlow.getPollingUrl(e),n=await fetch(r)
|
|
600
597
|
if(n.ok){const e=await n.json()
|
|
601
598
|
if(e.authenticated&&e.token){const t=this.authFlow.parseTokenResponse(e)
|
|
602
|
-
if(t)return await this.storeToken(t),this.pendingAuthCheck=!1,this.tempAuthCode=null,this.invalidateCache(),t}}return null}catch(e){return this.logger.error("Error checking authentication status",{error:(0,
|
|
599
|
+
if(t)return await this.storeToken(t),this.pendingAuthCheck=!1,this.tempAuthCode=null,this.invalidateCache(),t}}return null}catch(e){return this.logger.error("Error checking authentication status",{error:(0,c.getErrorMessage)(e)}),this.pendingAuthCheck=!1,this.tempAuthCode=null,null}}async validateTokenWithRemoteServer(){this.logger.debug("Validating stored token with remote server")
|
|
603
600
|
try{const e=await this.getToken()
|
|
604
601
|
if(!e)return this.logger.debug("No token available for validation"),!1
|
|
605
602
|
const t=this.remoteServerUrl+"/auth/validate"
|
|
606
603
|
this.logger.debug("Making token validation request",{validationUrl:t})
|
|
607
604
|
const r=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Content-Type":"application/json"},signal:AbortSignal.timeout(1e4)})
|
|
608
605
|
if(r.ok){const e=await r.json()
|
|
609
|
-
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,
|
|
606
|
+
return this.logger.info("Token validation successful",{status:e.status||"unknown",username:e.username||"unknown"}),!0}return this.logger.info("Token validation failed - token may be invalid or expired",{status:r.status,statusText:r.statusText}),this.invalidateCache(),!1}catch(e){return e instanceof Error&&"AbortError"===e.name?(this.logger.info("Token validation request timed out - assuming offline or server unavailable"),!0):(this.logger.info("Token validation request failed",{error:(0,c.getErrorMessage)(e)}),!0)}}async hasValidAndWorkingToken(){return!!await this.hasValidToken()&&await this.validateTokenWithRemoteServer()}async isGoogleOAuthAvailable(){return await this.authFlow.isGoogleOAuthAvailable()}async startGoogleOAuthFlow(){return await this.authFlow.startGoogleOAuthFlow()}async startGoogleOAuthPolling(e,t,r,n,o){return await this.authFlow.startGoogleOAuthPolling(e,t,r,n,o)}}},1266(e,exports){Object.defineProperty(exports,"__esModule",{value:!0})},1281(e,exports,t){async function r(e,t,o,s,i,a,c,l,d,u=0){let p=0,f=0,m=0
|
|
610
607
|
const y=[]
|
|
611
608
|
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}
|
|
612
609
|
try{const w=await g.default.readdir(e,{withFileTypes:!0}),v=[],C=[]
|
|
@@ -666,20 +663,20 @@ let C
|
|
|
666
663
|
if(I.searchDirectory=p||".",p){const{normalizedPath:e,fullPath:r}=m.validateAndNormalizePath(p,t)
|
|
667
664
|
C=r}else C=t.basePath
|
|
668
665
|
I.resolvedPath=C
|
|
669
|
-
let
|
|
670
|
-
try{
|
|
671
|
-
throw I.errors.push(t),Error(t)}const
|
|
666
|
+
let _=!1
|
|
667
|
+
try{_=(await g.default.stat(C)).isFile()}catch(e){const t=`Cannot access path ${C}: ${(0,b.getErrorMessage)(e)}`
|
|
668
|
+
throw I.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,T=v.fileExtension,P=v.searchIn||"content"
|
|
672
669
|
let R=void 0!==v.contextLines?v.contextLines:0
|
|
673
|
-
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!
|
|
670
|
+
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")')
|
|
674
671
|
let M,j=""
|
|
675
|
-
if(
|
|
672
|
+
if(_)j="*"
|
|
676
673
|
else if("*"===T)j="*"
|
|
677
674
|
else if(T){let e=T;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),j=e.startsWith(".")?e:"."+e}try{M=S?q?RegExp(n):RegExp(n,"i"):q?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${S?"regex":"search"} pattern: ${(0,b.getErrorMessage)(e)}`
|
|
678
|
-
throw I.errors.push(t),(0,f.createValidationError)(t)}if(I.patternInfo={needle:n,regex:M.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:j},!
|
|
675
|
+
throw I.errors.push(t),(0,f.createValidationError)(t)}if(I.patternInfo={needle:n,regex:M.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:j},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
|
|
679
676
|
for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
|
|
680
677
|
I.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},I.phases.directoryListingTime=I.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,b.getErrorMessage)(e)
|
|
681
|
-
I.errors.push(t),l.error(t)}const x=
|
|
682
|
-
l.info(`Searching for "${n}" in ${x} ${C} (mode: ${P})`,{needle:n,searchTarget:x,path:C,options:{maxResults:
|
|
678
|
+
I.errors.push(t),l.error(t)}const x=_?"file":"directory"
|
|
679
|
+
l.info(`Searching for "${n}" in ${x} ${C} (mode: ${P})`,{needle:n,searchTarget:x,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:j,searchIn:P}}),k=Date.now(),I.phases.initializationTime=k-u
|
|
683
680
|
const O=Date.now()
|
|
684
681
|
let A=[],D=0,$=0
|
|
685
682
|
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=[]
|
|
@@ -697,10 +694,10 @@ o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
|
|
|
697
694
|
const f={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
698
695
|
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,p,a,o,s,0,f,l,u)
|
|
699
696
|
return f.filesProcessed=n,f.filesMatched=c,f.subdirectories=d,i.directoryStats.push(f),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:p.length,directories:d+1}),{matches:p,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,b.getErrorMessage)(t)
|
|
700
|
-
return f.errors.push(r),i.directoryStats.push(f),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:p,totalFiles:f.filesProcessed}}}(C,M,{maxResults:
|
|
697
|
+
return f.errors.push(r),i.directoryStats.push(f),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:p,totalFiles:f.filesProcessed}}}(C,M,{maxResults:E,fileExtension:j,searchIn:P,isFile:_,contextLines:R},j,l,I)
|
|
701
698
|
A=e.matches,D=e.totalFiles
|
|
702
699
|
const t=1e3
|
|
703
|
-
A.length>0&&A.length<=t?(A.sort(((e,t)=>void 0!==e.modifiedTime&&void 0!==t.modifiedTime?t.modifiedTime-e.modifiedTime:void 0!==e.modifiedTime&&void 0===t.modifiedTime?-1:void 0===e.modifiedTime&&void 0!==t.modifiedTime?1:0)),l.info(`Sorted ${A.length} matches by modification time (newest first)`)):A.length>t&&l.info(`Skipped sorting ${A.length} matches (exceeds hard cap of ${t} for performance)`),$=A.length,A.length>
|
|
700
|
+
A.length>0&&A.length<=t?(A.sort(((e,t)=>void 0!==e.modifiedTime&&void 0!==t.modifiedTime?t.modifiedTime-e.modifiedTime:void 0!==e.modifiedTime&&void 0===t.modifiedTime?-1:void 0===e.modifiedTime&&void 0!==t.modifiedTime?1:0)),l.info(`Sorted ${A.length} matches by modification time (newest first)`)):A.length>t&&l.info(`Skipped sorting ${A.length} matches (exceeds hard cap of ${t} for performance)`),$=A.length,A.length>E&&(A=A.slice(0,E),l.info(`Limited results to ${E} (from ${$} total matches)`)),A.forEach((e=>{e.relativePath=function(e,t){const r=h.default.relative(e,t)
|
|
704
701
|
return r?r===h.default.basename(t)?r:r.startsWith("./")?r.substring(2):r:h.default.basename(t)}(C,e.file)})),l.info(`Local search completed: found ${$||A.length} total matches in ${D} files, returning ${A.length} results`),I.phases.searchTime=Date.now()-O}catch(e){const t="Error during search: "+(0,b.getErrorMessage)(e)
|
|
705
702
|
I.errors.push(t),l.error(t),I.phases.searchTime=Date.now()-O}I.totalFiles=D,I.totalMatches=A.length,I.endTime=Date.now()
|
|
706
703
|
let F,N=""
|
|
@@ -818,26 +815,26 @@ const I=r(a)
|
|
|
818
815
|
if(Date.now(),k=Date.now(),y){const e=await w()
|
|
819
816
|
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)
|
|
820
817
|
if(k=Date.now(),n?(n.setOptions({createRecords:C?.createsRecords??!1}),m.info(`Setting record creation for tool ${i}: ${C?.createsRecords??!1}`)):m.debug(`No API client available for tool ${i} (minimal mode)`),Date.now(),k=Date.now(),t?.workspaceManager&&!t.workspaceManager.readonlyBranchCheckDone)try{const e=await(0,d.getServerUrl)(t,m)
|
|
821
|
-
e&&n&&await t.workspaceManager.ensureReadonlyBranchIfNeeded(e,i,n,c?.sessionId)}catch(e){m.debug("Error during readonly branch check",{error:(0,l.getErrorMessage)(e)})}let E
|
|
818
|
+
e&&n&&await t.workspaceManager.ensureReadonlyBranchIfNeeded(e,i,n,c?.sessionId)}catch(e){m.debug("Error during readonly branch check",{error:(0,l.getErrorMessage)(e)})}let _,E
|
|
822
819
|
if(Date.now(),Date.now(),k=Date.now(),C&&!C.readOnly)if(c?.sessionId){const e=c.sessionId,r=c.messageId,n=u.sessionIdentity.getIdentity()
|
|
823
820
|
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}))
|
|
824
821
|
else{const r=await(0,d.getServerUrl)(t,m)
|
|
825
|
-
u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r||""}),u.sessionIdentity.markDiscoveryAttempted()}
|
|
822
|
+
u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r||""}),u.sessionIdentity.markDiscoveryAttempted()}_={providerId:"opencode",sessionId:e,messageId:r,createdAt:(new Date).toISOString()},(0,p.logSessionIdentity)(i,"_meta",{sessionId:e,messageId:r})}else{const e=u.sessionIdentity.getIdentity()
|
|
826
823
|
if(e){let t,r=!1
|
|
827
|
-
try{t=await(0,d.findMessageIdForTool)(e.serverUrl,e.sessionId,i)}catch{r=!0}if(t)
|
|
828
|
-
else if(r)
|
|
824
|
+
try{t=await(0,d.findMessageIdForTool)(e.serverUrl,e.sessionId,i)}catch{r=!0}if(t)_=u.sessionIdentity.buildCliOrigin(t)
|
|
825
|
+
else if(r)_=u.sessionIdentity.buildCliOrigin()
|
|
829
826
|
else{m.info("Session identity mismatch: tool call not found in cached session, re-discovering",{prevSessionId:e.sessionId,prevAgentType:e.agentType,tool:i}),u.sessionIdentity.reset()
|
|
830
827
|
try{const t=await(0,d.getAndStoreSessionId)(e.serverUrl,m,i)
|
|
831
|
-
t?(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e.serverUrl}),(0,p.logSessionIdentity)(i,"re-discovery",{sessionId:t.sessionId,messageId:t.messageId}),
|
|
828
|
+
t?(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e.serverUrl}),(0,p.logSessionIdentity)(i,"re-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId)):(u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),m.info("Re-discovery found no other session, keeping current identity",{sessionId:e.sessionId})),u.sessionIdentity.markDiscoveryAttempted()}catch(t){u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),u.sessionIdentity.markDiscoveryAttempted(),m.warn("Re-discovery failed, keeping current identity (may be stale)",{error:(0,l.getErrorMessage)(t),tool:i,sessionId:e.sessionId})}}}else if(!u.sessionIdentity.hasDiscoveryBeenAttempted())try{const e=await(0,d.getServerUrl)(t,m)
|
|
832
829
|
if(e){const t=await(0,d.getAndStoreSessionId)(e,m,i)
|
|
833
|
-
t&&(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e}),(0,p.logSessionIdentity)(i,"http-discovery",{sessionId:t.sessionId,messageId:t.messageId}),
|
|
830
|
+
t&&(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e}),(0,p.logSessionIdentity)(i,"http-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId))}u.sessionIdentity.markDiscoveryAttempted()}catch(e){u.sessionIdentity.markDiscoveryAttempted(),(0,p.logSessionIdentity)(i,"discovery-failed",{error:(0,l.getErrorMessage)(e)}),m.debug("cliOrigin discovery failed",{error:(0,l.getErrorMessage)(e),tool:i})}}if(u.sessionIdentity.setCurrentCallOrigin(_),!v&&n){const e=u.sessionIdentity.getIdentity(),t=process.env.ALCHEMY_INITIAL_BRANCH
|
|
834
831
|
if(e?.sessionId&&t){const r=t.match(/^requests\/(.+)$/),o="1"===process.env.ALCHEMY_ALLOW_PARALLEL
|
|
835
832
|
if(r&&!o){const t=r[1]
|
|
836
833
|
v=!0
|
|
837
834
|
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()
|
|
838
|
-
await Promise.all([i,a])}catch(e){m.warn("Error in session tag mapping / lock acquisition",{error:(0,l.getErrorMessage)(e)})}}}}if(C){const e={context:t,apiClient:n,logger:o,metrics:s,mcpServer:g,cliOrigin:
|
|
839
|
-
|
|
840
|
-
return Date.now(),Date.now(),b({tool:i,success:!0}),
|
|
835
|
+
await Promise.all([i,a])}catch(e){m.warn("Error in session tag mapping / lock acquisition",{error:(0,l.getErrorMessage)(e)})}}}}if(C){const e={context:t,apiClient:n,logger:o,metrics:s,mcpServer:g,cliOrigin:_}
|
|
836
|
+
E=await C.handler(I,e)}else m.info(`Tool ${i} not found, returning negative response`),E={content:[{type:"text",text:`The tool '${i}' does not exist.`}]}
|
|
837
|
+
return Date.now(),Date.now(),b({tool:i,success:!0}),E}catch(t){m.error("Error executing tool:",{error:t instanceof Error?t.stack:t+"",tool:e.params.name}),s.incrementCounter("tool_errors_total",1,{tool:e.params.name,error:t instanceof Error?t.name:"unknown"})
|
|
841
838
|
let r="Unknown error"
|
|
842
839
|
if(t instanceof Error)r=t.message
|
|
843
840
|
else if("string"==typeof t)r=t
|
|
@@ -1163,9 +1160,7 @@ return this.logger.info("Expired lock cleanup completed",{requestId:e,wasCleaned
|
|
|
1163
1160
|
try{const t=this.projectClient.getProjectId()
|
|
1164
1161
|
if(!t)throw Error("Project ID is required for checking request lock status")
|
|
1165
1162
|
const r=await this.requestWithRetry("GET",`/api/projects/${t}/requests/${e}/lock-status`),n=(0,o.safeGetResponseData)(r,{isLocked:!1,lockedAt:void 0,lockedBySessionTag:void 0,timeRemainingMs:0,timeRemainingFormatted:"No lock",isExpired:!0},this.logger)
|
|
1166
|
-
return this.logger.debug("Request lock status retrieved",{requestId:e,isLocked:n.isLocked,lockedBySessionTag:n.lockedBySessionTag,timeRemainingFormatted:n.timeRemainingFormatted,isExpired:n.isExpired}),n}catch(t){throw this.logger.error("Failed to get request lock status",{requestId:e,error:(0,a.getErrorMessage)(t)}),t}}setConnectionStatusManager(e){super.setConnectionStatusManager(e),this.logger.debug("Updated connection status manager in RequestClient")}}exports.RequestClient=c},
|
|
1167
|
-
const r=t(6183),n=t(3707)
|
|
1168
|
-
exports.def={name:"quick_edit",description:"Streamlined workflow for atomic changes to files or documents. Creates request \u2192 task \u2192 executes operation \u2192 completes automatically.\n\nSupports:\n\u2022 write - Create or update a file or document (accepts path or documentId)\n\u2022 replace - Replace text in files or documents (accepts path or documentId)\n\nUse this for small changes like typos, quick edits, status updates, or minor tweaks. The entire workflow is handled in one call.",schema:r.QuickEditSchema,annotations:{title:"Quick Edit",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleQuickChange)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},1695(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.HealthCheckManager=void 0
|
|
1163
|
+
return this.logger.debug("Request lock status retrieved",{requestId:e,isLocked:n.isLocked,lockedBySessionTag:n.lockedBySessionTag,timeRemainingFormatted:n.timeRemainingFormatted,isExpired:n.isExpired}),n}catch(t){throw this.logger.error("Failed to get request lock status",{requestId:e,error:(0,a.getErrorMessage)(t)}),t}}setConnectionStatusManager(e){super.setConnectionStatusManager(e),this.logger.debug("Updated connection status manager in RequestClient")}}exports.RequestClient=c},1695(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.HealthCheckManager=void 0
|
|
1169
1164
|
const r=t(8824)
|
|
1170
1165
|
exports.HealthCheckManager=class{constructor(e,t,r,n={}){this.online=!1,this.forcedOfflineMode=!1,this.checkInterval=null,this.lastSuccessTime=0,this.lastFailureTime=0,this.successCount=0,this.failureCount=0,this.consecutiveFailures=0,this.currentBackoffMs=0,this.lastCheckTime=0,this.baseUrl=e,this.logger=t.child({component:"health-check-manager"}),this.metrics=r,this.options={checkIntervalMs:n.checkIntervalMs??3e4,timeoutMs:n.timeoutMs??5e3,retryCount:n.retryCount??2,onOfflineCallback:n.onOfflineCallback??(()=>{}),onOnlineCallback:n.onOnlineCallback??(()=>{})},this.metrics.setGauge("health_check_success_count",0),this.metrics.setGauge("health_check_failure_count",0),this.metrics.setGauge("health_check_last_success",0),this.metrics.setGauge("health_check_last_failure",0)}async performHealthCheck(){const e=Date.now()
|
|
1171
1166
|
try{this.logger.debug("Performing health check against remote server")
|
|
@@ -1177,7 +1172,7 @@ const e=this.online,t=await this.performHealthCheck()
|
|
|
1177
1172
|
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
|
|
1178
1173
|
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
|
|
1179
1174
|
const r=t(6183),n=t(355)
|
|
1180
|
-
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},
|
|
1175
|
+
exports.def={name:"complete_task",description:"Mark a task as completed with a summary of work done.",schema:r.CompleteTaskSchema,annotations:{title:"Complete Task",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},handler(e,t){return(0,n.handleCompleteTask)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},1725(e,exports,t){function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,S.join)(e.basePath||process.cwd(),".alchemy_lab","spawn-debug.log");(0,q.appendFileSync)(o,n)}catch{}}async function n(e){try{const t=`http://localhost:${R}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
|
|
1181
1176
|
if(!r.ok)return null
|
|
1182
1177
|
const n=await r.json()
|
|
1183
1178
|
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
|
|
@@ -1188,8 +1183,8 @@ if(r(t,"Spawn agent type check",{cliOriginSessionId:i?.sessionId||null,cachedSes
|
|
|
1188
1183
|
r(t,"Looking up agent type from action server",{sessionId:n,url:e})
|
|
1189
1184
|
const s=await fetch(e)
|
|
1190
1185
|
if(s.ok){const e=await s.json()
|
|
1191
|
-
r(t,"Agent type response from action server",{sessionId:n,agentType:e.agentType||null,source:e.source||null,success:e.success}),e.success&&e.agentType&&(o=e.agentType,(0,I.updateCachedSession)({agentType:o}))}else r(t,"Agent type lookup failed",{sessionId:n,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e?.sessionId,error:(0,
|
|
1192
|
-
if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${o}' cannot spawn '${a}'.\n\n**Allowed subagents for ${o}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,
|
|
1186
|
+
r(t,"Agent type response from action server",{sessionId:n,agentType:e.agentType||null,source:e.source||null,success:e.success}),e.success&&e.agentType&&(o=e.agentType,(0,I.updateCachedSession)({agentType:o}))}else r(t,"Agent type lookup failed",{sessionId:n,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e?.sessionId,error:(0,E.getErrorMessage)(n)})}if(o){const e=(0,T.getAllowedSubagents)(o)
|
|
1187
|
+
if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${o}' cannot spawn '${a}'.\n\n**Allowed subagents for ${o}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,E.getErrorMessage)(e)})}let h
|
|
1193
1188
|
try{const e=await n(a)
|
|
1194
1189
|
if(h=e?.requestContextMode,!h){const e=(0,T.getBuiltInAgentConfig)(a)
|
|
1195
1190
|
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}
|
|
@@ -1204,17 +1199,17 @@ if(s&&l)try{const e=s.getSessionRequestAssociationClient()
|
|
|
1204
1199
|
if(e){const t=await e.getSessionsForRequest(l,!0),r=m?t.filter((e=>e.opencodeSessionId!==m)):t
|
|
1205
1200
|
if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
|
|
1206
1201
|
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}
|
|
1207
|
-
y=`\u26a0\ufe0f Warning: Request ${l} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,o.warn("Spawning parallel subagent for request with existing active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){o.debug("Failed to check for existing workers",{error:(0,
|
|
1202
|
+
y=`\u26a0\ufe0f Warning: Request ${l} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,o.warn("Spawning parallel subagent for request with existing active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){o.debug("Failed to check for existing workers",{error:(0,E.getErrorMessage)(e)})}let C,_,q=c
|
|
1208
1203
|
l&&(C="requests/"+l,r(t,"Setting initialBranch for agent",{agent:a,requestId:l,initialBranch:C,agentRequestContextMode:h||"undefined"}),q="readonly"===h?`Working on request ${l} (READONLY mode - you cannot modify files, only explore and report).\n\n${c}`:`Working on request ${l}.\n\n${c}`)
|
|
1209
1204
|
let S=!1
|
|
1210
|
-
if(u){if(
|
|
1205
|
+
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")
|
|
1211
1206
|
try{let e
|
|
1212
1207
|
try{const t=await fetch(`http://localhost:${R}/api/project-settings`)
|
|
1213
1208
|
if(t.ok){const r=await t.json()
|
|
1214
1209
|
if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
|
|
1215
|
-
e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${
|
|
1210
|
+
e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${_}/message`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:q}],...a?{agent:a}:{},...e?{model:e}:{}})})
|
|
1216
1211
|
if(!r.ok){const e=await r.text().catch((()=>"Unknown error"))
|
|
1217
|
-
throw Error(`Failed to send to existing session: ${r.status} ${e}`)}o.info("Prompt sent to existing session",{sessionId:
|
|
1212
|
+
throw Error(`Failed to send to existing session: ${r.status} ${e}`)}o.info("Prompt sent to existing session",{sessionId:_,agent:a})}catch(e){throw Error("Failed to use existing session: "+(0,E.getErrorMessage)(e))}}else{if(S=!0,r(t,"Creating session via HTTP and spawning CLI"),!g)throw Error("Cannot spawn subagent: no server URL available")
|
|
1218
1213
|
const i=m||f?.sessionId||await(0,k.discoverParentSessionId)(g,o);(0,v.logSessionIdentity)("subagent_operations.spawn",m?"early-discovery":f?"_meta":"http-discovery",{parentSessionId:i}),r(t,"Parent session discovered",{parentSessionId:i})
|
|
1219
1214
|
const u=g.replace(/\/$/,"")+"/session",h=e.title?e.title:l?`[${l}] ${c.slice(0,40)}${c.length>40?"...":""}`:`${c.slice(0,50)}${c.length>50?"...":""}`,y=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentID:i,title:h})})
|
|
1220
1215
|
if(!y.ok)throw Error("Failed to create session: "+y.status)
|
|
@@ -1227,7 +1222,7 @@ if(!n)return
|
|
|
1227
1222
|
let o,c
|
|
1228
1223
|
if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:(0,I.getCachedSession)()?.agentType||void 0})
|
|
1229
1224
|
o=e.id,c=e.workflowId,r(t,"Registered parent session in DB",{parentSessionId:i,parentDbId:o,parentWorkflowId:c})}const l=await n.createOrUpdateSession({externalSessionId:M,providerId:"opencode",parentSessionId:o||null,title:h,status:"active",agentType:a,specialization:e.specialization,workflowId:c||void 0})
|
|
1230
|
-
r(t,"Registered child session in DB",{childSessionId:M,childDbId:l.id,parentDbId:o})}catch(e){r(t,"Failed to register sessions in DB",{error:(0,
|
|
1225
|
+
r(t,"Registered child session in DB",{childSessionId:M,childDbId:l.id,parentDbId:o})}catch(e){r(t,"Failed to register sessions in DB",{error:(0,E.getErrorMessage)(e)}),o.warn("Failed to register sessions in alchemy DB",{error:(0,E.getErrorMessage)(e)})}})()
|
|
1231
1226
|
let x
|
|
1232
1227
|
r(t,"Starting model resolution",{agent:a,cwd:p})
|
|
1233
1228
|
try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${R}/api/agents/by-name/${a}`})
|
|
@@ -1239,22 +1234,22 @@ r(t,"Model resolution result",{agent:a,result:s}),s.resolved?(x=s.fullModel,r(t,
|
|
|
1239
1234
|
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"
|
|
1240
1235
|
r(t,"Using built-in agent preferences",{agent:a,preferredProvider:n,preferredTier:o})
|
|
1241
1236
|
const s=(0,P.resolveAgentModel)(p,n,o)
|
|
1242
|
-
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,
|
|
1237
|
+
r(t,"Built-in model resolution result",{agent:a,result:s}),s.resolved&&(x=s.fullModel,r(t,"Resolved built-in agent model",{agent:a,model:x,preferredProvider:n,preferredTier:o}))}else r(t,"No built-in config found - using default model",{agent:a})}}catch(e){r(t,"Error resolving agent model",{agent:a,error:(0,E.getErrorMessage)(e)})}try{const e=await async function(){try{const e=`http://localhost:${R}/api/project-settings`,t=await fetch(e)
|
|
1243
1238
|
if(t.ok){const e=await t.json()
|
|
1244
1239
|
return e?.data?.defaultModel||null}}catch{}return null}()
|
|
1245
1240
|
if(e)if(x){const o=await n(a)
|
|
1246
|
-
"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,
|
|
1241
|
+
"same"===(o?.preferredModelTier||"same")&&(x=e,r(t,"Applied user default model (same tier)",{agent:a,userDefaultModel:e}))}else x=e,r(t,"Using user default model (no agent resolution)",{agent:a,userDefaultModel:e})}catch(e){r(t,"Failed to fetch user default model",{error:(0,E.getErrorMessage)(e)})}r(t,"Final resolved model before spawn",{agent:a,resolvedModel:x||"undefined (will use default)"}),await j
|
|
1247
1242
|
const O=(0,b.spawnDetachedSubagent)({agent:a,prompt:q,cwd:p,sessionId:M,model:x,initialBranch:C,allowParallel:d,serverUrl:g})
|
|
1248
1243
|
if(!O.success)throw Error("Failed to spawn subagent: "+O.error)
|
|
1249
|
-
|
|
1250
|
-
if(e&&(e.createAssociation(
|
|
1251
|
-
e&&e.updateRequest(l,{cliOrigin:{providerId:"opencode",sessionId:
|
|
1252
|
-
return u?M+=`Prompt sent to existing session ${
|
|
1244
|
+
_=M,r(t,"CLI spawn successful with pre-created session",{sessionId:M,pid:O.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:M,pid:O.pid,parentSessionId:i})}if(s&&l&&_&&"unknown"!==_&&"spawning"!==_)try{const e=s.getSessionRequestAssociationClient()
|
|
1245
|
+
if(e&&(e.createAssociation(_,l).then((()=>o.info("Created session-request association",{sessionId:_,requestId:l}))).catch((e=>o.warn("Failed to create session-request association",{error:(0,E.getErrorMessage)(e),sessionId:_,requestId:l}))),"coder"===a)){const e=s.getRequestClient()
|
|
1246
|
+
e&&e.updateRequest(l,{cliOrigin:{providerId:"opencode",sessionId:_,createdAt:(new Date).toISOString()}}).catch((e=>o.debug("Failed to update request cliOrigin",{error:(0,E.getErrorMessage)(e)})))}}catch(e){o.warn("Failed to create session-request association",{error:(0,E.getErrorMessage)(e),sessionId:_,requestId:l})}let M=y
|
|
1247
|
+
return u?M+=`Prompt sent to existing session ${_}.`:(M+=`Background ${a} subagent spawned successfully.`,_&&"unknown"!==_&&"spawning"!==_&&(M+=`\n[SESSION:${_}]`)),l&&(M+="\nWorking on: "+l),M+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:M}]}}async function s(e,t,r,n,o,s,i){const a=await(0,k.getServerUrl)(r,n)
|
|
1253
1248
|
if(!a)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1254
1249
|
if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId||(0,I.getCachedSession)()?.sessionId||await(0,k.discoverParentSessionId)(a,n)
|
|
1255
1250
|
if(t){const r=o.getCLISessionClient()
|
|
1256
1251
|
if(r){let o=await r.getByExternalId(t)
|
|
1257
|
-
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,
|
|
1252
|
+
o||(o=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),n.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:o?.id})),o&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:o.id,status:"active"}),n.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){n.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,E.getErrorMessage)(e)})}let c=s
|
|
1258
1253
|
if(!c)try{const t=`http://localhost:${R}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
|
|
1259
1254
|
if(r.ok){const e=await r.json()
|
|
1260
1255
|
e.success&&e.agentType&&(c=e.agentType)}}catch{n.warn("Agent type lookup failed for session",{sessionId:e})}if(!c)throw new w.ValidationError(`Cannot continue session ${e}: unable to determine agent type. The session's agent type could not be looked up from the action server.`)
|
|
@@ -1264,7 +1259,7 @@ if(e.ok){const t=await e.json()
|
|
|
1264
1259
|
if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
|
|
1265
1260
|
r={providerID:e,modelID:n.join("/")}}}}catch{}const o=`${a.replace(/\/$/,"")}/session/${e}/message`,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}:{}})})
|
|
1266
1261
|
if(!s.ok){const e=await s.text().catch((()=>"Unknown error"))
|
|
1267
|
-
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,
|
|
1262
|
+
throw Error(`Failed to send message: ${s.status} ${e}`)}return n.info("Message sent to subagent session",{sessionId:e,agent:c}),{content:[{type:"text",text:`Message sent to session ${e}.\nThe subagent will process it in the background.`}]}}catch(e){throw Error("Failed to continue session: "+(0,E.getErrorMessage)(e))}}function i(e){const t=Math.floor(e/1e3)
|
|
1268
1263
|
if(60>t)return t+"s"
|
|
1269
1264
|
const r=Math.floor(t/60)
|
|
1270
1265
|
return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function a(e){const t=[]
|
|
@@ -1288,26 +1283,26 @@ if(p.ok){const e=await p.json()
|
|
|
1288
1283
|
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)
|
|
1289
1284
|
const t=a(e)
|
|
1290
1285
|
y=l(t.lastActivityTime,h.time.updated),t.current&&(m+="\nCurrent: "+t.current),t.recent.length>0&&(m+="\nRecent: "+t.recent.join(", "))}const w=Date.now()-h.time.created,b=y.status,k=y.isReady,I=f.input+f.output+f.reasoning
|
|
1291
|
-
let v="",C="",
|
|
1286
|
+
let v="",C="",_=null
|
|
1292
1287
|
if(o)try{const t=o.getSessionRequestAssociationClient()
|
|
1293
1288
|
if(t){const r=await t.getActiveRequestsForSession(e,!1)
|
|
1294
1289
|
if(r.length>0){const t=r.filter((e=>!e.endedAt)).sort(((e,t)=>new Date(t.startedAt).getTime()-new Date(e.startedAt).getTime())),o=r.filter((e=>e.endedAt)).sort(((e,t)=>new Date(t.endedAt).getTime()-new Date(e.endedAt).getTime())),s=o[0],i=t[0]
|
|
1295
|
-
s&&i?
|
|
1290
|
+
s&&i?_=new Date(s.endedAt).getTime()>new Date(i.startedAt).getTime()?s.requestLocalId:i.requestLocalId:s?_=s.requestLocalId:i&&(_=i.requestLocalId)
|
|
1296
1291
|
const a=[]
|
|
1297
|
-
t.length>0&&a.push("Active: "+t.map((e=>e.requestLocalId)).join(", ")),o.length>0&&a.push("Previous: "+o.map((e=>e.requestLocalId)).join(", ")),a.length>0&&(C="\nRequests: "+a.join(" | ")),n.debug("Found request associations",{sessionId:e,activeCount:t.length,historicalCount:o.length})}}}catch(e){n.debug("Failed to get request associations, falling back to title extraction",{error:e instanceof Error?e.message:e+""})}if(
|
|
1298
|
-
return t?t[1]:null}(h.title||"")),
|
|
1292
|
+
t.length>0&&a.push("Active: "+t.map((e=>e.requestLocalId)).join(", ")),o.length>0&&a.push("Previous: "+o.map((e=>e.requestLocalId)).join(", ")),a.length>0&&(C="\nRequests: "+a.join(" | ")),n.debug("Found request associations",{sessionId:e,activeCount:t.length,historicalCount:o.length})}}}catch(e){n.debug("Failed to get request associations, falling back to title extraction",{error:e instanceof Error?e.message:e+""})}if(_||(_=function(e){const t=e.match(/\[(req\d{6})\]/)
|
|
1293
|
+
return t?t[1]:null}(h.title||"")),_&&r.basePath){const e=await async function(e,r){try{const{execSync:n}=await Promise.resolve().then(t.t.bind(t,5317,23)),o="requests/"+e
|
|
1299
1294
|
let s=!1
|
|
1300
1295
|
try{n("git rev-parse --verify "+o,{cwd:r,stdio:"pipe"}),s=!0}catch{s=!1}if(s){const e=n(`git diff main...${o} --numstat`,{cwd:r,encoding:"utf8"})
|
|
1301
1296
|
if(e.trim())return d(e)}try{const t=n(`git log main --merges --oneline -n 50 --grep="${e}"`,{cwd:r,encoding:"utf8"}).trim()
|
|
1302
1297
|
if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
|
|
1303
|
-
if(o.trim())return{...d(o),merged:!0}}}catch{}return null}catch{return null}}(
|
|
1298
|
+
if(o.trim())return{...d(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
|
|
1304
1299
|
if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
|
|
1305
|
-
v=`\nDiff vs main (${
|
|
1300
|
+
v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${b} (${y.detail})\nReady for input: ${k?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${I.toLocaleString()} (in: ${f.input.toLocaleString()}, out: ${f.output.toLocaleString()}${f.reasoning>0?", reasoning: "+f.reasoning.toLocaleString():""})${m}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,E.getErrorMessage)(e))}}async function h(e,t,r){const n=await(0,k.getServerUrl)(t,r)
|
|
1306
1301
|
if(!n)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1307
1302
|
r.info("Aborting subagent session",{sessionId:e})
|
|
1308
1303
|
try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
|
|
1309
1304
|
if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
|
|
1310
|
-
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,
|
|
1305
|
+
throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,E.getErrorMessage)(e))}}async function g(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:c,minTokens:d,maxTokens:u,maxAgeHours:h}=n,g=await(0,k.getServerUrl)(e,t)
|
|
1311
1306
|
if(!g)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1312
1307
|
t.info("Listing sessions",{filters:n})
|
|
1313
1308
|
try{const e=g.replace(/\/$/,"")+"/session",t=await fetch(e)
|
|
@@ -1339,11 +1334,11 @@ if(m?.associations&&m.associations.length>0){const e=m.associations.filter((e=>!
|
|
|
1339
1334
|
k.push(...e,...t)
|
|
1340
1335
|
const r=[]
|
|
1341
1336
|
e.length>0&&r.push("active: "+e.join(", ")),t.length>0&&r.push("prev: "+t.join(", ")),r.length>0&&(y=` [${r.join(" | ")}]`)}if(s&&!k.includes(s))continue
|
|
1342
|
-
const C=t.title||"Untitled",
|
|
1343
|
-
v.push({id:t.id,title:
|
|
1344
|
-
const C=c?v.slice(0,c):v,
|
|
1345
|
-
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}`})),
|
|
1346
|
-
return{content:[{type:"text",text:`Found ${C.length} session${1!==C.length?"s":""}${
|
|
1337
|
+
const C=t.title||"Untitled",_=C.length>50?C.slice(0,47)+"...":C
|
|
1338
|
+
v.push({id:t.id,title:_,status:f,age:r,totalTokens:o,requestsInfo:y,allRequestIds:k,statusDetail:h.detail,specialization:m?.specialization??null,currentAction:i,recentActions:c})}if(0===v.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1339
|
+
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(", "):""
|
|
1340
|
+
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})`:""
|
|
1341
|
+
return{content:[{type:"text",text:`Found ${C.length} session${1!==C.length?"s":""}${E}:\n\n${_.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,E.getErrorMessage)(e))}}var p,f=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1347
1342
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1348
1343
|
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=[]
|
|
1349
1344
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -1353,7 +1348,7 @@ if(null!=e)for(var r=p(e),n=0;n<r.length;n++)"default"!==r[n]&&f(t,e,r[n])
|
|
|
1353
1348
|
return m(t,e),t})
|
|
1354
1349
|
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")
|
|
1355
1350
|
try{e&&!e.operation&&(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})),"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)
|
|
1356
|
-
const r=
|
|
1351
|
+
const r=_.validateArgs(e,C.SubagentOperationsSchema),{sessionId:d,operation:p}=r
|
|
1357
1352
|
let f
|
|
1358
1353
|
switch(c.info("Processing subagent_operations",{operation:p,sessionId:d}),p){case"spawn":f=await o(r.spawn,t,c,i,a)
|
|
1359
1354
|
break
|
|
@@ -1373,13 +1368,13 @@ throw Error("Failed to fetch messages: "+n.status)}const s=await n.json()
|
|
|
1373
1368
|
if(0===s.length)return{content:[{type:"text",text:`Session ${e} has no messages yet.`}]}
|
|
1374
1369
|
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
|
|
1375
1370
|
return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n${o}`})).join("\n\n---\n\n")
|
|
1376
|
-
return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,
|
|
1371
|
+
return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,E.getErrorMessage)(e))}}(d,e,t,c)
|
|
1377
1372
|
break
|
|
1378
1373
|
case"list-sessions":const n={activeOnly:r.listSessions?.activeOnly,requestId:r.listSessions?.requestId,limit:r.listSessions?.limit,minTokens:r.listSessions?.minTokens,maxTokens:r.listSessions?.maxTokens,maxAgeHours:r.listSessions?.maxAgeHours,parentSessionId:a?.sessionId||(0,I.getCachedSession)()?.sessionId}
|
|
1379
1374
|
f=await g(t,c,i,n)
|
|
1380
1375
|
break
|
|
1381
|
-
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,
|
|
1382
|
-
const w=t(9860),b=t(8035),k=t(7617),I=t(715),v=t(7280),C=t(6183),
|
|
1376
|
+
default:throw new w.ValidationError("Unknown operation: "+p)}return l({success:!0}),n.incrementCounter(`subagent_operations_${p}_success`,1),f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,E.getErrorMessage)(e)}],isError:!0}}}
|
|
1377
|
+
const w=t(9860),b=t(8035),k=t(7617),I=t(715),v=t(7280),C=t(6183),_=y(t(5967)),E=t(8824),q=t(9896),S=t(6928),T=t(8955),P=t(5671),R=3456,M=6e4,j=3e5},1791(e,exports,t){function r(e,t){return t.info("Creating project context middleware",{projectId:e}),(t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1383
1378
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
|
|
1384
1379
|
const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
|
|
1385
1380
|
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")
|
|
@@ -1675,22 +1670,22 @@ if(m.info("Moving multiple files and directories",{taskId:u,operationCount:h.len
|
|
|
1675
1670
|
d.validateTaskIdFormat(u,m,i,I.metricsPrefix)
|
|
1676
1671
|
const C=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1677
1672
|
m.info("Initial branch context",{initialBranch:C.branch,initialRequestId:C.requestId,isMain:C.isMain})
|
|
1678
|
-
const
|
|
1673
|
+
const _=[]
|
|
1679
1674
|
for(const e of h){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.source,t),{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(e.destination,t)
|
|
1680
|
-
|
|
1681
|
-
const
|
|
1682
|
-
T.taskPromoted&&m.info(`Auto-promoted task ${u} (${
|
|
1675
|
+
_.push({source:r,destination:o,fullSource:n,fullDestination:s})}k=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("move_files_phase",1,{phase:k})
|
|
1676
|
+
const E=await d.validateTaskId(u,_[0].source,r,m,i,I.metricsPrefix),q=E?.requestId,S=await d.validateWorkItemStates(u,_[0].source,r,o,t,m,i,I.metricsPrefix),T=await d.autoPromoteTaskStatus(u,E.status,q,S.request?.status,_[0].source,r,o,m,i,I.metricsPrefix)
|
|
1677
|
+
T.taskPromoted&&m.info(`Auto-promoted task ${u} (${E.title||"Untitled"}) to in_progress for file operations`,{taskId:u,taskTitle:E.title,previousStatus:E.status,newStatus:T.newTaskStatus,operationCount:h.length}),T.requestPromoted&&m.info(`Auto-promoted request ${q} to in_progress for file operations`,{requestId:q,previousStatus:S.request?.status,newStatus:T.newRequestStatus,triggeringTaskId:u})
|
|
1683
1678
|
const P=await d.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:I.metricsPrefix})
|
|
1684
1679
|
if(!P.success){if(P.isLockConflict)return{content:[{type:"text",text:"\u274c "+P.error}],isError:!0}
|
|
1685
1680
|
throw Error(P.error)}let R={hadUserMods:!1,userModsCommitHash:void 0}
|
|
1686
1681
|
if(t.git)try{m.debug("[MOVE-FILES] Checking for user changes before move operations")
|
|
1687
1682
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"move-files",{requestId:q,taskId:u,workspaceManager:t.workspaceManager},m,i)
|
|
1688
|
-
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:
|
|
1689
|
-
const{toolRecordId:M,localToolRecordId:j}=await d.createFileOperationRecords(u,q,t.projectId,I.recordType,
|
|
1683
|
+
e.userChangesCommitted&&(m.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),m.info("User changes committed before move-files operation",{taskId:u,moveOperationsCount:_.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),R={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){m.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),m.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:u,moveOperationsCount:_.length,error:e instanceof Error?e.message:e+""})}m.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:_.length}),k=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("move_files_phase",1,{phase:k})
|
|
1684
|
+
const{toolRecordId:M,localToolRecordId:j}=await d.createFileOperationRecords(u,q,t.projectId,I.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},r,n,m,i,I.metricsPrefix,f)
|
|
1690
1685
|
w=M,b=M,k=I.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:k})
|
|
1691
1686
|
const x=[]
|
|
1692
1687
|
let O=0
|
|
1693
|
-
for(const e of
|
|
1688
|
+
for(const e of _){const t={operation:{source:e.source,destination:e.destination},success:!1}
|
|
1694
1689
|
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()
|
|
1695
1690
|
t.isDirectory=r
|
|
1696
1691
|
const n=c.default.dirname(e.fullDestination)
|
|
@@ -1699,9 +1694,9 @@ i.recordValue("move_files_time",A),i.incrementCounter("move_files_operations_tot
|
|
|
1699
1694
|
let D=null
|
|
1700
1695
|
if(O>0){k=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:k})
|
|
1701
1696
|
const e=x.filter((e=>e.success)),r=1===e.length?`Move ${e[0].isDirectory?"directory":"file"} from ${e[0].operation.source} to ${e[0].operation.destination} - ${v}`:`Move ${e.length} ${1===e.length?"item":"items"} - ${v}`
|
|
1702
|
-
D=await d.commitToGit(u,
|
|
1697
|
+
D=await d.commitToGit(u,_[0].destination,M,j,r,t,m,i,I.metricsPrefix)}k=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:k})
|
|
1703
1698
|
const $=x.filter((e=>e.success)),F=x.filter((e=>!e.success))
|
|
1704
|
-
await d.updateFileOperationRecords(u,w,b,
|
|
1699
|
+
await d.updateFileOperationRecords(u,w,b,_[0].source,I.recordType,O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,{status:O===h.length?"completed":"partial_success",commitHash:D?.commitHash,previousCommitHash:D?.previousCommitHash,operationCount:h.length,successCount:O,failureCount:h.length-O,successfulOperations:$.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:F.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,r,n,m,i,I.metricsPrefix)
|
|
1705
1700
|
const N=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1706
1701
|
let L=""
|
|
1707
1702
|
if(O===h.length)L=`Successfully moved all ${h.length} ${1===h.length?"item":"items"}`
|
|
@@ -1711,8 +1706,10 @@ return D?.commitHash&&(L+="\nCommit: "+D.commitHash.substring(0,8)),N.requestId&
|
|
|
1711
1706
|
await n.createToolRecord({...r?{}:{taskId:e.taskId},projectId:t.projectId,type:"move-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment,error:(0,p.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:k,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:"Failed to move files - "+(0,p.getErrorMessage)(o)})}catch(t){m.error("Failed to create failure record for move-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,operationCount:e.operations?.length||0})}const s=Date.now()-y
|
|
1712
1707
|
if(i.recordValue("move_files_time",s),i.incrementCounter("move_files_errors",1),m.error("Error in move-files operation:",{error:(0,p.getErrorMessage)(o),time:s}),(w||b)&&e.taskId){k=d.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
1713
1708
|
try{await d.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",I.recordType,"Failed to move files",{status:"failed",error:(0,p.getErrorMessage)(o),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",r,n,m,i,I.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:w,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,k,m,i,e,I)}}
|
|
1714
|
-
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")},
|
|
1715
|
-
const r=t(
|
|
1709
|
+
const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(7478),p=t(8824)},2422(module){module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1710
|
+
const r=t(6183),n=t(3707)
|
|
1711
|
+
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})
|
|
1712
|
+
const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),g=t(5459),p=t(4805),f=t(260),m=t(2283),y=t(4165),w=t(7834),b=t(9373),k=t(6111),I=t(700),v=t(2783),C=t(2601),_=t(1722),E=t(7257),q=t(9230),S=t(5216),T=t(6473),P=t(4921),R=t(8850),M=t(3556),j=t(1391),x=t(6315),O=t(7713),A=t(6252),D=t(213),$=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),U=t(5247),W=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(g.def),(0,r.registerTool)(p.def),(0,r.registerTool)(f.def),(0,r.registerTool)(m.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(b.def),(0,r.registerTool)(k.def),(0,r.registerTool)(I.def),(0,r.registerTool)(v.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(E.def),(0,r.registerTool)(q.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(P.def),(0,r.registerTool)(R.def),(0,r.registerTool)(M.def),(0,r.registerTool)(j.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(A.def),(0,r.registerTool)(D.def),(0,r.registerTool)($.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(L.def),(0,r.registerTool)(z.def),(0,r.registerTool)(B.def),(0,r.registerTools)(H.metaDefs),(0,r.registerTools)(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
|
|
1716
1713
|
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]"
|
|
1717
1714
|
let l=""
|
|
1718
1715
|
if(s||void 0===o?.lineCount||(l=` (${i(o.lineCount)} lines)`),s&&o?.subtreeTotals){const{files:e,lines:t}=o.subtreeTotals
|
|
@@ -1775,23 +1772,23 @@ let g=k.FileOperationPhase.VALIDATION
|
|
|
1775
1772
|
k.FileOperationPhase.FILE_WRITE
|
|
1776
1773
|
try{const p=k.validateArgs(e,b.ListDirectorySchema),{path:f,levels:m=1,sortBy:I="name"}=p
|
|
1777
1774
|
i.info("Listing directory: "+f)
|
|
1778
|
-
const{normalizedPath:C,fullPath:
|
|
1775
|
+
const{normalizedPath:C,fullPath:_}=k.validateAndNormalizePath(f,t)
|
|
1779
1776
|
g=k.FileOperationPhase.FILE_WRITE
|
|
1780
|
-
try{if(!(await y.default.stat(
|
|
1781
|
-
await y.default.access(
|
|
1777
|
+
try{if(!(await y.default.stat(_)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+f}],isError:!0}
|
|
1778
|
+
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
|
|
1782
1779
|
if(m>1){i.info(`Building tree structure for: ${C} (levels: ${m}, sortBy: ${I})`)
|
|
1783
1780
|
const e=await o(C,t,0,m,I,i)
|
|
1784
1781
|
if(e.length>0){const t=s(e,I)
|
|
1785
|
-
|
|
1782
|
+
E=`Directory tree for ${C} (${m} levels):\n${l(c(e))}\n\n${t}`,q=d(e)}else E=`Directory ${C} is empty or inaccessible.`,q=0}else{const e=await y.default.readdir(_,{withFileTypes:!0}),o=[]
|
|
1786
1783
|
for(const n of e)try{const e=w.default.join(C,n.name).replace(/\\/g,"/"),{fullPath:s}=k.validateAndNormalizePath(e,t),i=await y.default.stat(s),a=n.isFile()?w.default.extname(n.name).toLowerCase():""
|
|
1787
1784
|
let c
|
|
1788
1785
|
n.isFile()&&(c=await r(s,i.size,a)),o.push({name:n.name,isDirectory:n.isDirectory(),depth:0,size:i.size,modified:i.mtime,extension:a,lineCount:c})}catch(e){i.debug("Excluding directory entry from listing: "+n.name,{reason:(0,v.getErrorMessage)(e)})}const s=u(o,I),a=s.map((e=>n({name:e.name,isDirectory(){return e.isDirectory},isFile(){return!e.isDirectory}},I,e)))
|
|
1789
|
-
|
|
1790
|
-
|
|
1786
|
+
E=a.length>0?`Directory listing for ${C}:\n${l(c(s))}\n\n${a.join("\n")}`:`Directory ${C} is empty.`,q=s.length}const S=t.workspaceManager?.getCurrentContext()
|
|
1787
|
+
E+="\n\nBranch: "+(S?.branchName||"unknown")
|
|
1791
1788
|
const T=Date.now()-h
|
|
1792
|
-
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:
|
|
1789
|
+
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
|
|
1793
1790
|
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}}}
|
|
1794
|
-
const y=m(t(1943)),w=m(t(6928)),b=t(6183),k=f(t(5967)),I=t(3253),v=t(8824),C=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore",".config",".conf",".ini",".cfg"]),
|
|
1791
|
+
const y=m(t(1943)),w=m(t(6928)),b=t(6183),k=f(t(5967)),I=t(3253),v=t(8824),C=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore",".config",".conf",".ini",".cfg"]),_=1048576},2568(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1795
1792
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectSynchronizer=void 0
|
|
1796
1793
|
const n=r(t(6928)),o=t(8029),s=t(8824),i=t(2096)
|
|
1797
1794
|
exports.ProjectSynchronizer=class{constructor(e,t,r,n,o={}){this.logger=e.child({component:"project-synchronizer"}),this.registry=t,this.remoteApi=r,this.fileSystem=n,this.options={createRemoteProjects:o.createRemoteProjects??!0,maxRetryAttempts:o.maxRetryAttempts??3,retryDelayMs:o.retryDelayMs??1e3},this.logger.info("ProjectSynchronizer initialized",{options:this.options})}async ensureProjectExists(e){const t=Math.random().toString(36).substring(2,8)
|
|
@@ -1849,7 +1846,9 @@ let r=null
|
|
|
1849
1846
|
if(t&&(r=await this.loadLocalProject(t),r&&r.id!==e&&(this.logger.warn("Project ID mismatch between request and loaded project",{requestedId:e,loadedId:r.id}),r=null)),!r){const t=this.registry.getProject(e)
|
|
1850
1847
|
t&&(r=t)}if(!r)return this.logger.info("Project not found locally, attempting to fetch from remote",{projectId:e}),r=await this.remoteApi.fetchProject(e),r?(this.registry.register(r),t&&await this.fileSystem.writeProjectFile(r,t),!0):(this.logger.warn("Project not found locally or remotely",{projectId:e}),!1)
|
|
1851
1848
|
if(!await this.ensureProjectExists(e))return!1
|
|
1852
|
-
if(await this.verifyAndFixProjectName(r)||this.logger.warn("Failed to verify/fix project name",{projectId:r.id,projectName:r.name}),r.metadata&&Object.keys(r.metadata).length>0)try{this.logger.info("Syncing project metadata to remote",{projectId:r.id,metadataKeys:Object.keys(r.metadata)}),await this.remoteApi.updateProject(r.id,{metadata:r.metadata}),this.logger.info("Project metadata synced successfully",{projectId:r.id})}catch(e){this.logger.warn("Failed to sync project metadata",{projectId:r.id,error:e instanceof Error?e.message:e+""})}return this.logger.info("Project synchronization completed successfully",{projectId:e}),!0}catch(r){return this.logger.error("Error synchronizing project",{projectId:e,basePath:t,error:r instanceof Error?r.stack:r+""}),!1}}}},
|
|
1849
|
+
if(await this.verifyAndFixProjectName(r)||this.logger.warn("Failed to verify/fix project name",{projectId:r.id,projectName:r.name}),r.metadata&&Object.keys(r.metadata).length>0)try{this.logger.info("Syncing project metadata to remote",{projectId:r.id,metadataKeys:Object.keys(r.metadata)}),await this.remoteApi.updateProject(r.id,{metadata:r.metadata}),this.logger.info("Project metadata synced successfully",{projectId:r.id})}catch(e){this.logger.warn("Failed to sync project metadata",{projectId:r.id,error:e instanceof Error?e.message:e+""})}return this.logger.info("Project synchronization completed successfully",{projectId:e}),!0}catch(r){return this.logger.error("Error synchronizing project",{projectId:e,basePath:t,error:r instanceof Error?r.stack:r+""}),!1}}}},2601(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1850
|
+
const r=t(6183),n=t(76)
|
|
1851
|
+
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
|
|
1853
1852
|
const r=t(7645),n=t(2161)
|
|
1854
1853
|
class o extends r.ConnectionAwareClient{constructor(e,t,r,n,o,s,i){const a=t.child({component:"session-message-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(){}}
|
|
1855
1854
|
super(e,a,r,o,i),this.connectionStatusManager=c,this.projectClient=n}getProjectId(){const e=this.projectClient.getProjectId()
|
|
@@ -1914,9 +1913,9 @@ const s=o(t(5124)),i=o(t(6928)),a=o(t(9896)),c=t(6540),l=t(7960),d=s.default.for
|
|
|
1914
1913
|
return`${r} ${i}${a} [${e.toUpperCase()}]: ${t}${c}`}))),g=n({logToFile:!1,console:!0,level:c.LogLevel.INFO})
|
|
1915
1914
|
exports.default=g},2783(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1916
1915
|
const r=t(6183),n=t(410)
|
|
1917
|
-
exports.def={name:"task_operations",description:"Perform operations on existing tasks.\n\nOperations:\n\u2022
|
|
1916
|
+
exports.def={name:"task_operations",description:"Perform operations on existing tasks.\n\nOperations:\n\u2022 get-info - Get detailed information about a task\n\u2022 list - List and filter tasks for a request\n\nNote: To create a task, use the separate create-task tool. To complete a task, use complete-task.",schema:r.TaskOperationsSchema,annotations:{title:"Task Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleTaskOperations)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer,t.cliOrigin)}}},2903(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1918
1917
|
const r=t(6183),n=t(9442)
|
|
1919
|
-
exports.def={name:"replace_in_files",description:'Replace text in multiple files/documents with progressive fuzzy matching in batch operations.\n\nAPI:\n\u2022 operations (required) - Array of file operations\n - path or documentId (required per operation) - Target file or document\n - replacements (required) - Array of {old, new, match_mode?} replacements\n - fuzzy_match (optional) - Override global fuzzy setting for this file\n
|
|
1918
|
+
exports.def={name:"replace_in_files",description:'Replace text in multiple files/documents with progressive fuzzy matching in batch operations.\n\nAPI:\n\u2022 operations (required) - Array of file operations\n - path or documentId (required per operation) - Target file or document\n - replacements (required) - Array of {old, new, match_mode?} replacements\n - fuzzy_match (optional) - Override global fuzzy setting for this file\n\u2022 fuzzy_match (optional, default true) - Global fuzzy matching default\n\u2022 comment (required) - Description of changes\n\nSTRUCTURE: Each operation MUST contain a `replacements` array. Do NOT put old/new directly on the operation object.\n\nFUZZY MATCHING (progressive strategies):\n1. exact - Literal match\n2. whitespace_normalized - Collapse/trim whitespace\n3. whitespace_agnostic - Ignore all whitespace\n\nMATCH MODES (per replacement):\n\u2022 \'unique\' (default, safe) - Must find exactly 1 match. Fails with helpful candidates if multiple found.\n\u2022 \'all\' - Replaces all occurrences, returns details for each\n\nRETURNS:\nPer-operation, per-replacement results with line numbers, match types, and success/error details.\n\nEXAMPLES:\n- Single file: {"operations": [{"path": "file.ts", "replacements": [{"old": "oldAPI", "new": "newAPI"}]}], "comment": "Update API"}\n- Multi-file: {"operations": [{"path": "a.ts", "replacements": [...]}, {"path": "b.ts", "replacements": [...]}], "comment": "Refactor"}',schema:r.ReplaceInFilesSchema,annotations:{title:"Replace In Files (Fuzzy Batch)",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},createsRecords:!0,handler(e,t){return(0,n.handleReplaceInFiles)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},2960(e,exports){function t(e,t={}){const{logger:r,operationName:n="API operation",throwOnNoData:o=!1,defaultValue:s=null,includeMetadata:i=!1}=t
|
|
1920
1919
|
if(r&&r.debug(n+" - Response structure analysis",{type:typeof e,isApiResponse:e&&"object"==typeof e&&"success"in e,isSuccessResponse:e&&"object"==typeof e&&!0===e.success,isErrorResponse:e&&"object"==typeof e&&!1===e.success,hasData:e&&"object"==typeof e&&"data"in e,hasMetadata:e&&"object"==typeof e&&"metadata"in e,properties:e&&"object"==typeof e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"}),null==e){if(r&&r.warn(n+" - Response is null or undefined"),o)throw Error(n+": Response is null or undefined")
|
|
1921
1920
|
return i?{data:s,metadata:void 0}:s}if("object"!=typeof e||!("success"in e))return r&&(r.warn(n+" - Response is not a standard API response (missing success property)"),r.debug(n+" - Attempting to use response directly as data")),i?{data:e,metadata:void 0}:e
|
|
1922
1921
|
if(!1===e.success){const t=e,a=t.error?`${t.error.code}: ${t.error.message}`:"Unknown error"
|
|
@@ -2087,10 +2086,10 @@ if(!h)throw(0,n.createValidationError)("Project ID is required. Make sure you ar
|
|
|
2087
2086
|
o.setProjectId(h),d.info("Fetching request data, tasks, and file history in parallel")
|
|
2088
2087
|
const g=o.getRequestClient(),p=o.getTaskClient(),f=o.getToolRecordClient(),[m,y,w]=await Promise.all([g.getRequest(c),p.listTasks({requestId:c}),f.getToolRecordsByRequestId(c).catch((e=>(d.warn("Failed to fetch tool records",{error:e+""}),[])))]),b=(0,s.extractDataFromResponse)(m,{logger:d,operationName:"getRequest",throwOnNoData:!0}),k="data"in b?b.data:b,I={id:k.id||c,title:k.title||"Unknown Request",description:k.description||"No description available",status:k.status||"unknown",type:k.type||"unknown",acceptanceCriteria:k.acceptanceCriteria||[],createdAt:k.createdAt||(new Date).toISOString(),updatedAt:k.updatedAt||(new Date).toISOString(),completedAt:k.completedAt},v=(0,s.extractDataFromResponse)(y,{logger:d,operationName:"listTasks",throwOnNoData:!1}),C=(Array.isArray(v)?v:"data"in v?v.data:[]).map((e=>({id:e.id,title:e.title||"Untitled Task",description:e.description||"No description",status:e.status||"unknown",createdAt:e.createdAt||(new Date).toISOString(),completedAt:e.metadata?.completedAt})))
|
|
2089
2088
|
d.info(`Fetched request, ${C.length} tasks, ${w.length} tool records`)
|
|
2090
|
-
const
|
|
2089
|
+
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()))
|
|
2091
2090
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
2092
2091
|
n.push({type:e.type,timestamp:e.createdAt,comment:s,files:o,recordId:e.localId||e.id})
|
|
2093
|
-
for(const e of o)t.set(e,(t.get(e)||0)+1)}return{files:Array.from(t.entries()).map((([e,t])=>({path:e,operations:t}))).sort(((e,t)=>t.operations-e.operations)),operations:n}}(w),
|
|
2092
|
+
for(const e of o)t.set(e,(t.get(e)||0)+1)}return{files:Array.from(t.entries()).map((([e,t])=>({path:e,operations:t}))).sort(((e,t)=>t.operations-e.operations)),operations:n}}(w),E={request:I,tasks:C,fileChanges:{summary:{totalFiles:_.files.length,totalOperations:_.operations.length,files:_.files},operations:_.operations},suggestedFilename:`JOURNAL-${c}.md`,metadata:{projectId:h,requestId:c,generatedAt:(new Date).toISOString()}},q=`\u2705 **Request Data Fetched Successfully!**\n\n**Request:** ${I.title} (${c})\n**Status:** ${I.status}\n**Type:** ${I.type}\n**Tasks:** ${C.length}\n**Files Changed:** ${_.files.length}\n**File Operations:** ${_.operations.length}\n\n**Data Summary:**\n\`\`\`json\n${JSON.stringify(E,null,2)}\n\`\`\`\n\n**Next Steps:**\nWrite a **compact technical narrative** and save as \`JOURNAL-${c}.md\` using document_operations (create).\n\n**Style Guide:**\n- Be concise and direct - no fluff, repetition, or unnecessary elaboration\n- Write in narrative flow connecting the changes chronologically\n- Reference files with paths: "Modified \\\`src/tools/example.ts\\\` to add X..."\n- Include operation comments inline: ("comment: 'Fix bug in parser'")\n- **Link to tool records**: Use \\\`[RECORD:trec######]\\\` format to reference operations (e.g., "Modified parser.ts [RECORD:trec004123]")\n- Show key code changes with brief snippets where they add clarity\n- Explain what changed and why, skip obvious details\n- Focus on technical substance over structure\n\n**Example:** "Modified \\\`parser.ts\\\` [RECORD:trec004123] to handle edge cases (comment: 'Fix null handling'). Added \\\`if (!input) return null;\\\` check at line 45. Then updated \\\`validator.ts\\\` [RECORD:trec004124] to use the new parser behavior..."`
|
|
2094
2093
|
return u({tool:"generate_request_journal",success:!0}),l.incrementCounter("generate_request_journal_total",1,{success:!0}),{content:[{type:"text",text:q}]}}catch(e){return d.error("Error generating request journal",{error:e instanceof Error?e.stack:e+""}),u({tool:"generate_request_journal",success:!1}),l.incrementCounter("generate_request_journal_errors",1),{content:[{type:"text",text:"\u274c **Failed to generate journal:** "+(0,i.getErrorMessage)(e)}],isError:!0}}}
|
|
2095
2094
|
const n=t(9860),o=t(1569),s=t(2960),i=t(8824),a=o.z.object({requestId:o.z.string().regex(/^req[_\d].+$/,"Invalid request ID format")})},3064(e,exports,t){async function r(e,t,r,n){if(!r.lockOverrideManager||!r.configManager)return e
|
|
2096
2095
|
try{const n=await r.configManager.getEffectiveConfig(r.mainBasePath)
|
|
@@ -2212,9 +2211,9 @@ return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModu
|
|
|
2212
2211
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceStrings=async function(e,t,r,o,s,i,a,c){const y=i.child({tool:"replace_strings"}),w=Date.now()
|
|
2213
2212
|
let b,k,I=u.FileOperationPhase.VALIDATION
|
|
2214
2213
|
const v={toolName:"replace-strings",operationName:"replace-string",fileOperationPhase:u.FileOperationPhase.STRING_REPLACEMENT,recordType:"replace-strings",metricsPrefix:"replace_strings",successMessage:"Successfully replaced strings across files and documents",failureMessage:"Failed to replace strings across files and documents"}
|
|
2215
|
-
try{const i=u.validateArgs(e,d.ReplaceStringsSchema),{taskId:C,operations:
|
|
2216
|
-
if(y.info("Replacing strings across files and documents",{taskId:C,operationCount:
|
|
2217
|
-
const q=
|
|
2214
|
+
try{const i=u.validateArgs(e,d.ReplaceStringsSchema),{taskId:C,operations:_,comment:E}=i
|
|
2215
|
+
if(y.info("Replacing strings across files and documents",{taskId:C,operationCount:_.length,comment:E}),!_||0===_.length)throw new h.ValidationError("At least one operation is required")
|
|
2216
|
+
const q=_.filter((e=>e.path)),S=_.filter((e=>e.documentId))
|
|
2218
2217
|
y.info("Operation breakdown",{fileOperations:q.length,documentOperations:S.length})
|
|
2219
2218
|
const T=[]
|
|
2220
2219
|
for(const e of q){const{normalizedPath:r,fullPath:n}=u.validateAndNormalizePath(e.path,t)
|
|
@@ -2235,7 +2234,7 @@ throw Error(A.error)}if(T.length>0){y.debug("Re-validating file paths with corre
|
|
|
2235
2234
|
for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
|
|
2236
2235
|
T[e]={...r,path:o,fullPath:s}}}if(P.length>0&&j)try{await(0,g.validateRequestStatusForDocumentOperation)(j,s,y,a,"replace-strings-document")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2237
2236
|
throw e}I=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:I})
|
|
2238
|
-
const D=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...P.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:$}=await u.createFileOperationRecords(C,j,t.projectId,v.recordType,R,{operationCount:
|
|
2237
|
+
const D=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...P.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:$}=await u.createFileOperationRecords(C,j,t.projectId,v.recordType,R,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:D,userComment:E},r,o,y,a,v.metricsPrefix,c)
|
|
2239
2238
|
if(b=$,k=$,I=v.fileOperationPhase,a.incrementCounter("replace_strings_phase",1,{phase:I}),T.length>0&&t.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
|
|
2240
2239
|
const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:j,taskId:C,workspaceManager:t.workspaceManager},y,a)
|
|
2241
2240
|
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})
|
|
@@ -2250,7 +2249,7 @@ r.filename=s?.filename
|
|
|
2250
2249
|
const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
|
|
2251
2250
|
r.replacements=c,r.successfulReplacements=c.filter((e=>e.success)).length,r.failedReplacements=c.filter((e=>!e.success)).length,a!==i?(await l.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),r.success=!0,L++,y.info("Document updated successfully",{documentId:e.documentId,filename:r.filename,successfulReplacements:r.successfulReplacements,failedReplacements:r.failedReplacements})):0===r.failedReplacements&&(r.success=!0),N+=r.failedReplacements}catch(t){r.error=(0,m.getErrorMessage)(t),r.failedReplacements=e.replacements.length,N+=r.failedReplacements,y.error("Document operation failed",{documentId:e.documentId,error:r.error})}F.push(r)}if(P.length>0)try{for(const e of P){const r=F.find((t=>t.documentId===e.documentId))
|
|
2252
2251
|
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const z=await u.handleMultiFileGitCommit(C,T,F,L,{operationType:"Replace strings",toolRecordId:k,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),B=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J}=B
|
|
2253
|
-
try{await o.updateToolRecord(k,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:G?"completed":"failed",error:G?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:D,totalSuccessfulReplacements:W,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:
|
|
2252
|
+
try{await o.updateToolRecord(k,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:G?"completed":"failed",error:G?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations: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,A)
|
|
2254
2253
|
let K="## String Replacement Results\n\n"
|
|
2255
2254
|
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"),A.lockAcquired&&A.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${A.lockedRequestId}\n\n`),1===F.length){const e=F[0]
|
|
2256
2255
|
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"
|
|
@@ -2369,24 +2368,24 @@ r instanceof n.ZodError?s=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`))
|
|
|
2369
2368
|
try{await(0,o.createFailureToolRecord)("complete-request",r,{error:s,requestId:e?.requestId},a.getToolRecordClient(),d,l,{requestId:e?.requestId,projectId:t.projectId,note:"Failed to finalize request"})}catch{}return u({success:!1,error:r instanceof Error?r.name:"unknown"}),{content:[{type:"text",text:"Error: "+s}],isError:!0}}}
|
|
2370
2369
|
const r=t(9860),n=t(1569),o=t(8616),s=t(1651),i=t(8824)},3611(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2371
2370
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
2372
|
-
const n=r(t(6928)),o=r(t(7252)),s=r(t(8577)),i=t(184),a=t(1213),c=t(3444),l=t(9955),d=t(5218),u=t(2568),h=t(3102),g=t(1152),p=t(3884),f=t(7888),m=t(4139),y=t(6800),w=t(6539),b=t(8824),k=t(6975),I=t(1253),v=process.argv.slice(2),C=v[0]||process.cwd(),
|
|
2371
|
+
const n=r(t(6928)),o=r(t(7252)),s=r(t(8577)),i=t(184),a=t(1213),c=t(3444),l=t(9955),d=t(5218),u=t(2568),h=t(3102),g=t(1152),p=t(3884),f=t(7888),m=t(4139),y=t(6800),w=t(6539),b=t(8824),k=t(6975),I=t(1253),v=process.argv.slice(2),C=v[0]||process.cwd(),_=n.default.resolve(C),E=parseInt(process.env.LOCAL_SERVER_PORT||v[1]||"3002",10),q=(0,c.createEnvLogger)({serviceName:"mcp-http-server"});(0,c.isDebugToolsEnabled)()?q.info("HTTP server initializing",{baseDir:_,preferredPort:E,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL}):q.info("HTTP server starting",{port:E})
|
|
2373
2372
|
const S=(0,g.createMetricsCollector)(!0),T=(process.env.REMOTE_SERVER_PORT,process.env.REMOTE_SERVER_HOST,process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com")
|
|
2374
|
-
q.info("Using remote server URL",{remoteServerUrl:T}),async function(){try{q.info("Finding available port...",{preferredPort:
|
|
2375
|
-
const e=await(0,y.findAvailablePort)(
|
|
2376
|
-
e!==
|
|
2377
|
-
const t=new l.ProjectRegistry(q),r=new h.DefaultProjectFileSystem(q),c=n.default.join(
|
|
2373
|
+
q.info("Using remote server URL",{remoteServerUrl:T}),async function(){try{q.info("Finding available port...",{preferredPort:E,baseDir:_,remoteServerUrl:T})
|
|
2374
|
+
const e=await(0,y.findAvailablePort)(E)
|
|
2375
|
+
e!==E&&q.info(`Preferred port ${E} is in use, using port ${e} instead`),q.info("Starting HTTP API server...",{port:e,baseDir:_,remoteServerUrl:T})
|
|
2376
|
+
const t=new l.ProjectRegistry(q),r=new h.DefaultProjectFileSystem(q),c=n.default.join(_,m.ALCHEMY_DIR_NAME)
|
|
2378
2377
|
q.info(`Checking ${m.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensureDirectoryExists(c)
|
|
2379
|
-
const g=new I.TokenManager(q,n.default.join(c,"auth-token.json")),v=(await w.ClientFactory.createClient(T,q,S,{tokenManager:g,workingDir:
|
|
2378
|
+
const g=new I.TokenManager(q,n.default.join(c,"auth-token.json")),v=(await w.ClientFactory.createClient(T,q,S,{tokenManager:g,workingDir:_,alchemyPath:c})).projectClient,C=new k.ProjectClientAdapter(v,q),P=new u.ProjectSynchronizer(q,t,C,r),R=await P.getOrCreateProject(_,{name:n.default.basename(_)||"Local Project",description:"Project for "+n.default.basename(_),status:"active",metadata:{basePath:_,alchemyPath:c,bootstrapped:!0}})
|
|
2380
2379
|
q.info("Using project",{projectId:R.id,projectName:R.name})
|
|
2381
2380
|
const M=(0,o.default)()
|
|
2382
2381
|
M.use((0,s.default)()),M.use(o.default.json({limit:"50mb"})),M.use(o.default.urlencoded({extended:!0})),M.use((0,p.requestLogger)(q))
|
|
2383
2382
|
try{q.info("Creating MCP server instance")
|
|
2384
|
-
const t=await(0,i.createServer)(
|
|
2383
|
+
const t=await(0,i.createServer)(_,q,S,T,{existingProjectId:R.id,multiAgentMode:(0,d.isMultiAgentModeEnabled)(_)})
|
|
2385
2384
|
q.info("MCP server instance created successfully")
|
|
2386
2385
|
const r=t.getContext()
|
|
2387
2386
|
q.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(q.info("Adding connection status middleware"),M.use((0,f.addConnectionStatusInfo)(t.connectionManager))):q.warn("Unable to add connection status middleware - connection manager not available")
|
|
2388
2387
|
try{const e=R.id
|
|
2389
|
-
q.info("Setting up project context middleware",{projectId:e}),M.use("/api",((t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}))}catch(e){q.warn("Failed to set up project context middleware",{error:(0,b.getErrorMessage)(e)})}(0,a.registerApiRoutes)(M,t,q,S),M.use((0,p.errorHandler)(q,S)),M.listen(e,(()=>{q.info("HTTP API server listening on port "+e,{baseDir:
|
|
2388
|
+
q.info("Setting up project context middleware",{projectId:e}),M.use("/api",((t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}))}catch(e){q.warn("Failed to set up project context middleware",{error:(0,b.getErrorMessage)(e)})}(0,a.registerApiRoutes)(M,t,q,S),M.use((0,p.errorHandler)(q,S)),M.listen(e,(()=>{q.info("HTTP API server listening on port "+e,{baseDir:_,port:e,nodeVersion:process.version})}))}catch(e){q.error("Failed to create or initialize MCP server",{error:e instanceof Error?e.stack:e+""})
|
|
2390
2389
|
let t=!1
|
|
2391
2390
|
e instanceof Error&&(t=e.message.includes("connection")||e.message.includes("timeout")||e.message.includes("network")||"ConnectionError"===e.name),S.incrementCounter("server_initialization_failure",1,{isConnectionError:t?"true":"false"}),M.use(((e,t,r)=>{t.set("X-Connection-Status","offline"),t.set("X-Server-Initialization-Failed","true"),r()})),M.use("/api",((t,r)=>{r.status(503).json({success:!1,error:{code:"CONNECTION_ERROR",message:"Server failed to initialize due to connection issues. Please check connectivity and try again.",details:{serverError:e instanceof Error?e.message:e+"",suggestions:["Check your network connection","Verify that the remote server is running","Try restarting the local server"],isConnectionIssue:!0},retryable:!0,statusCode:503}})})),q.warn("Continuing with limited functionality due to initialization error")}process.on("SIGINT",(()=>{q.info("Received SIGINT signal, shutting down..."),process.exit(0)})),process.on("SIGTERM",(()=>{q.info("Received SIGTERM signal, shutting down..."),process.exit(0)})),process.on("uncaughtException",(e=>{q.error("Uncaught exception",{error:e.stack}),process.exit(1)})),process.on("unhandledRejection",(e=>{q.error("Unhandled promise rejection",{reason:e}),process.exit(1)}))}catch(e){q.error("Failed to start HTTP API server",{error:e instanceof Error?e.stack:e+""}),process.exit(1)}}()},3626(e,exports,t){function r(e){if(!e)return!1
|
|
2392
2391
|
const t=e.toLowerCase().replace(/^\./,"")
|
|
@@ -2484,38 +2483,39 @@ b.isFile&&w&&k.push("Extension: "+w)
|
|
|
2484
2483
|
const I=Date.now()-s
|
|
2485
2484
|
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+f,{type:b.type,size:b.size,time:I}),{content:[{type:"text",text:k.join("\n")}]}}catch(t){const r=Date.now()-s
|
|
2486
2485
|
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}
|
|
2487
|
-
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){const
|
|
2488
|
-
try{const
|
|
2489
|
-
|
|
2490
|
-
let
|
|
2491
|
-
try{const e=await
|
|
2492
|
-
e&&2===e.length&&e.every((e=>"quick-edit"===e.type))&&(
|
|
2493
|
-
const
|
|
2494
|
-
if(!
|
|
2495
|
-
const
|
|
2496
|
-
let
|
|
2497
|
-
|
|
2498
|
-
try{if(
|
|
2499
|
-
e.userChangesCommitted?
|
|
2500
|
-
|
|
2501
|
-
const e=await
|
|
2486
|
+
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()
|
|
2487
|
+
try{const y=u.getRequestClient(),w=u.getTaskClient(),b=u.getFileClient(),k=u.getToolRecordClient(),{title:I,description:v,...C}=e,_=e.comment||I
|
|
2488
|
+
f.info("Starting quick_edit workflow",{title:I,operationType:t})
|
|
2489
|
+
let E=!1
|
|
2490
|
+
try{const e=await y.listRequests({limit:2,sortBy:"created_at",sortDirection:"desc"})
|
|
2491
|
+
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")
|
|
2492
|
+
const q=await y.createRequest({title:I,description:v,type:"quick-edit",acceptanceCriteria:["Quick change completed successfully"]})
|
|
2493
|
+
if(!q||!q.id)throw Error("Failed to create request")
|
|
2494
|
+
const S=q.id
|
|
2495
|
+
let T
|
|
2496
|
+
f.info("Created request",{requestId:S})
|
|
2497
|
+
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)
|
|
2498
|
+
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")
|
|
2499
|
+
f.debug("Creating task")
|
|
2500
|
+
const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+I})
|
|
2502
2501
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2503
|
-
let
|
|
2504
|
-
if(
|
|
2505
|
-
else
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
try{await
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
return
|
|
2518
|
-
|
|
2502
|
+
let l
|
|
2503
|
+
if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{operationType:t}),"write"===t)l=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,b,w,k,y,h,g,p)
|
|
2504
|
+
else if("replace"===t)l=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,k,y,h,g,p)
|
|
2505
|
+
else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
|
|
2506
|
+
l=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||I},d,w,k,y,u,h,g,p)}if(l.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
|
|
2507
|
+
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${l.content[0].text}\n\nThe request (${S}) and task have been canceled and cleaned up.`}],isError:!0}}const v=l.content[0].text,q=v.includes("\u26a0\ufe0f Partial Success")||v.includes("\u274c Failed")||v.includes("\u274c 0 successful")
|
|
2508
|
+
q?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
|
|
2509
|
+
try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${I}${q?" (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})
|
|
2510
|
+
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")
|
|
2511
|
+
const P=q?`Quick change completed with partial success: ${I}. Some replacements failed - see details below.`:"Quick change completed: "+I,R=q?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
|
|
2512
|
+
let M=!1
|
|
2513
|
+
try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:P,acceptanceEvidence:[{evidence:R}],testVerification:void 0},d,u,h,g,p)
|
|
2514
|
+
e.isError?f.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text}):(M=!0,f.info("Request completed successfully via handleCompleteRequest",{requestId:S}))}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:S,error:e instanceof Error?e.message:e+""})}if(!M)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:P}),M=!0,f.info("Request completed successfully via direct API call",{requestId:S})}catch(e){return f.error("Direct request completion also failed",{requestId:S,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${S}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const j=Date.now()-m
|
|
2515
|
+
let x
|
|
2516
|
+
return f.info("Quick fix completed",{requestId:S,duration:j,hasPartialFailure:q}),x=q?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${I}\n**Operation:** ${t}\n**Duration:** ${j}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`+v:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${I}\n**Operation:** ${t}\n**Duration:** ${j}ms\n\nThe change has been applied and automatically merged to main.\n**Active branch:** main`+(v.match(/\[RECORD:trec\d{6}\]/)?.[0]?"\n"+v.match(/\[RECORD:trec\d{6}\]/)?.[0]:""),E&&(x+="\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:x}]}}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
|
|
2517
|
+
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}}}
|
|
2518
|
+
const r=t(9860),n=t(4079),o=t(9442),s=t(7684),i=t(355),a=t(5715),c=t(7478),l=t(8824)},3807(module){module.exports=require("simple-git")},3884(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.middleware=exports.validateRequest=exports.authenticate=exports.corsOptions=exports.errorHandler=exports.requestLogger=void 0
|
|
2519
2519
|
const r=t(9860),n=t(5674)
|
|
2520
2520
|
exports.requestLogger=e=>(t,r,n)=>{const o=Date.now()
|
|
2521
2521
|
e.info(`${t.method} ${t.path}`,{query:t.query,headers:{"user-agent":t.get("user-agent"),"content-type":t.get("content-type"),accept:t.get("accept")},ip:t.ip}),r.on("finish",(()=>{const n=Date.now()-o
|
|
@@ -2588,44 +2588,44 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
|
2588
2588
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2589
2589
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleWriteFile=async function(e,t,r,n,o,s,i,m,y){const w=i.child({tool:"write_file"}),b=m.startTimer("tool_execution_time"),k=Date.now()
|
|
2590
2590
|
let I,v,C=d.FileOperationPhase.VALIDATION
|
|
2591
|
-
const
|
|
2592
|
-
try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:
|
|
2593
|
-
w.info("Writing content to "+(R?"document":"file"),{taskId:i,filePath:M?f:void 0,documentId:R?
|
|
2591
|
+
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"}
|
|
2592
|
+
try{const r=d.validateArgs(e,l.WriteFileSchema),{taskId:i,path:f,documentId:E,content:q,format:S,append:T,comment:P}=r,R=!!E,M=!!f
|
|
2593
|
+
w.info("Writing content to "+(R?"document":"file"),{taskId:i,filePath:M?f:void 0,documentId:R?E:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S,append:T,comment:P})
|
|
2594
2594
|
let j,x,O,A="",D=!1,$=!1
|
|
2595
2595
|
const F=M?f:void 0
|
|
2596
|
-
if(R){if(t.apiClient)try{await(0,p.ensureDocumentNotLocked)(
|
|
2596
|
+
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}
|
|
2597
2597
|
throw e}if(!t.documentFileManager)throw Error("Document file manager not available")
|
|
2598
|
-
A=await t.documentFileManager.getDocumentAsFile(
|
|
2599
|
-
const e=t.documentFileManager.getCachedDocumentInfo(
|
|
2598
|
+
A=await t.documentFileManager.getDocumentAsFile(E)
|
|
2599
|
+
const e=t.documentFileManager.getCachedDocumentInfo(E)
|
|
2600
2600
|
O=e?.filename,$=!0,D=!1}C=d.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("write_file_phase",1,{phase:C})
|
|
2601
|
-
const N=M?F:"document:"+
|
|
2601
|
+
const N=M?F:"document:"+E,L=await d.validateTaskId(i,N,n,w,m,_.metricsPrefix),z=L?.requestId
|
|
2602
2602
|
let B=null
|
|
2603
|
-
M&&z&&(B=await d.validateWorkItemStates(i,N,n,s,t,w,m,
|
|
2603
|
+
M&&z&&(B=await d.validateWorkItemStates(i,N,n,s,t,w,m,_.metricsPrefix))
|
|
2604
2604
|
let H={taskPromoted:!1,requestPromoted:!1}
|
|
2605
|
-
M&&z&&B&&(H=await d.autoPromoteTaskStatus(i,L.status,z,B.request?.status,N,n,s,w,m,
|
|
2606
|
-
const U=await d.ensureCorrectWorkspaceContext({taskPromoted:H.taskPromoted,requestId:z,context:t,operation:"write_file",logger:w,metrics:m,metricsPrefix:
|
|
2605
|
+
M&&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"}))
|
|
2606
|
+
const U=await d.ensureCorrectWorkspaceContext({taskPromoted:H.taskPromoted,requestId:z,context:t,operation:"write_file",logger:w,metrics:m,metricsPrefix:_.metricsPrefix,requireRequestContext:M})
|
|
2607
2607
|
if(!U.success){if(U.isLockConflict)return{content:[{type:"text",text:"\u274c "+U.error}],isError:!0}
|
|
2608
2608
|
throw Error(U.error)}if(U.switched&&w.info("Workspace context successfully established",{requestId:z,branchName:U.branchName,operation:"write_file"}),M&&F){const e=d.validateAndNormalizePath(F,t)
|
|
2609
2609
|
j=e.normalizedPath,x=e.fullPath,A=x
|
|
2610
2610
|
try{await c.default.access(x),$=!0}catch{$=!1,D=!0}w.debug("Path validated with correct workspace context",{rawPath:F,normalizedPath:j,fullPath:x,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})}if(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}
|
|
2611
2611
|
throw e}C=d.FileOperationPhase.RECORD_CREATION,m.incrementCounter("write_file_phase",1,{phase:C})
|
|
2612
|
-
const{toolRecordId:W}=await d.createFileOperationRecords(i,z,t.projectId,
|
|
2612
|
+
const{toolRecordId:W}=await d.createFileOperationRecords(i,z,t.projectId,_.recordType,N,{operationType:R?"document":"file",documentId:R?E:void 0,documentFilename:O,filePath:M?j:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:S||"text",append:T||!1,wasFileCreated:!$,userComment:P},n,o,w,m,_.metricsPrefix,y)
|
|
2613
2613
|
let G
|
|
2614
|
-
if(I=W,v=W,C=
|
|
2614
|
+
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)
|
|
2615
2615
|
else G="string"==typeof q?q:JSON.stringify(q,null,2)
|
|
2616
2616
|
let V=G
|
|
2617
2617
|
if(M&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
|
|
2618
2618
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"write_file",{requestId:t.workspaceManager?.getCurrentContext()?.requestId,taskId:i},w,m)
|
|
2619
2619
|
e.userChangesCommitted&&(w.debug("[WRITE-FILE] User changes committed before write operation",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before write-file operation",{taskId:i,path:j,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[WRITE-FILE] Pre-tool commit failed, continuing with write",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with write operation",{taskId:i,path:j,error:e instanceof Error?e.message:e+""})}if(!A)throw Error("Target path not properly initialized")
|
|
2620
2620
|
if(w.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:A}),T&&$)try{V=await c.default.readFile(A,"utf8")+G}catch(e){w.warn("Failed to read existing content for append",{error:e})}const J=a.default.dirname(A)
|
|
2621
|
-
if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile(A,V,"utf8"),w.info("Content written successfully",{path:M?j:"document:"+
|
|
2622
|
-
try{await t.documentFileManager.syncDocument(
|
|
2621
|
+
if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile(A,V,"utf8"),w.info("Content written successfully",{path:M?j:"document:"+E,finalLength:V.length,append:T,wasCreated:D}),R){t.documentFileManager.markForSync(E)
|
|
2622
|
+
try{await t.documentFileManager.syncDocument(E),w.info("Document synced successfully",{documentId:E})}catch(e){w.warn("Failed to sync document immediately",{documentId:E,error:e})}}let K,Y,Q=null
|
|
2623
2623
|
if(M){if(C=d.FileOperationPhase.GIT_COMMIT,m.incrementCounter("write_file_phase",1,{phase:C}),t.workspaceManager){const e=t.workspaceManager.getCurrentContext()
|
|
2624
|
-
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"} ${j} (${v})`,r=await d.commitToGit(i,j,v,v,e,t,w,m,
|
|
2625
|
-
K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:j,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:M?j:"document:"+
|
|
2626
|
-
Z+=`**Content Length:** ${V.length} characters\n`,M&&Y&&(Z+=`**Branch:** ${Y}\n`),U.lockAcquired&&U.lockedRequestId&&(Z
|
|
2624
|
+
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"} ${j} (${v})`,r=await d.commitToGit(i,j,v,v,e,t,w,m,_.metricsPrefix)
|
|
2625
|
+
K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:j,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:M?j:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:D,wasAppended:T&&$,operationType:R?"document":"file",processingTime:Date.now()-k,userComment:P,...M&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(R?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${D?"Created":T?"Appended to":"Updated"} ${R?`document ${E}${O?` (${O})`:""}`:"file "+j}**\n`
|
|
2626
|
+
Z+=`**Content Length:** ${V.length} characters\n`,M&&Y&&(Z+=`**Branch:** ${Y}\n`),U.lockAcquired&&U.lockedRequestId&&(Z+=`**Locked request:** ${U.lockedRequestId}\n`),M&&K&&(Z+=`**Commit Hash:** ${K.substring(0,8)}\n`,Q&&(Z+=`**Previous Commit:** ${Q.substring(0,8)}\n`)),v&&(Z+=`[RECORD:${v}]\n`),R&&(Z+=`\n**Document Update:** The document content has been updated and synced back to the tracking system. You can continue editing using other file modification tools with documentId \`${E}\`.`)
|
|
2627
2627
|
const X=Date.now()
|
|
2628
|
-
return w.info("Write operation completed successfully",{duration:X-k,path:M?j:"document:"+
|
|
2628
|
+
return w.info("Write operation completed successfully",{duration:X-k,path:M?j:"document:"+E,contentLength:V.length,wasCreated:D}),b({tool:"write_file",success:!0}),m.incrementCounter("write_file_total",1,{success:!0}),t.workspaceManager?.largeFileWarning&&(Z+=t.workspaceManager.largeFileWarning,t.workspaceManager.largeFileWarning=""),{content:[{type:"text",text:Z}]}}catch(t){const r=Date.now()-k
|
|
2629
2629
|
if(w.error("Write operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:C}),v)try{await o.updateToolRecord(v,{metadata:{path:e?.path,status:"failed",error:(0,f.getErrorMessage)(t),phase:C,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return b({tool:"write_file",success:!1}),m.incrementCounter("write_file_errors",1,{phase:C}),{content:[{type:"text",text:"\u274c **Write Operation Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
|
|
2630
2630
|
const a=i(t(6928)),c=i(t(1943)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824)},4118(e,exports){Object.defineProperty(exports,"__esModule",{value:!0})},4139(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ALCHEMY_DIR_NAME=exports.TOKEN_DIR_NAME=void 0,exports.TOKEN_DIR_NAME="alchemy-key",exports.ALCHEMY_DIR_NAME=".alchemy_lab"},4165(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2631
2631
|
const r=t(6183),n=t(4648)
|
|
@@ -2783,34 +2783,36 @@ let I,v=!1
|
|
|
2783
2783
|
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
|
|
2784
2784
|
if(!C)throw Error("Git is not available")
|
|
2785
2785
|
if(!(await(0,u.validateCommitHash)(C,r,a,"file-recover")).valid)throw Error(`Commit hash '${r}' is invalid or not found`)
|
|
2786
|
-
let
|
|
2787
|
-
try{
|
|
2786
|
+
let _
|
|
2787
|
+
try{_=await C.show([`${r}:${y}`])}catch(e){const t=(0,h.getErrorMessage)(e)
|
|
2788
2788
|
if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))throw Error(`File '${y}' does not exist in commit '${r}'`)
|
|
2789
|
-
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await l.writeFile(w,
|
|
2790
|
-
let
|
|
2789
|
+
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await l.writeFile(w,_,"utf8")
|
|
2790
|
+
let E={}
|
|
2791
2791
|
try{const t=`Recover ${y} from ${r.substring(0,8)}`
|
|
2792
|
-
|
|
2792
|
+
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"
|
|
2793
2793
|
let S=`\u2705 **File ${q.charAt(0).toUpperCase()+q.slice(1)} Successfully**\n\n`
|
|
2794
|
-
return S+=`**File:** ${y}\n`,S+=`**Recovered from:** ${r.substring(0,8)}\n`,S+=`**Content length:** ${
|
|
2794
|
+
return S+=`**File:** ${y}\n`,S+=`**Recovered from:** ${r.substring(0,8)}\n`,S+=`**Content length:** ${_.length} characters\n`,n&&v&&I&&(S+=`**Backup created:** ${c.basename(I)}\n`),S+="**Git status:** Recovery committed\n",S+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",a.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-p}),g.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:S}]}}catch(e){throw e}}(f,y,w,b,t,r,n,p,s,m,g)}catch(e){const t=Date.now()-m
|
|
2795
2795
|
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}}}
|
|
2796
2796
|
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"})
|
|
2797
2797
|
try{"complete"===e?.operation&&e?.summary&&!e?.complete&&(e.complete={summary:e.summary,acceptanceEvidence:e.acceptanceEvidence||[],testVerification:e.testVerification},delete e.summary,delete e.acceptanceEvidence,delete e.testVerification),"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)
|
|
2798
|
-
const d=
|
|
2799
|
-
|
|
2800
|
-
const
|
|
2798
|
+
const d=e?.complete?.acceptanceEvidence
|
|
2799
|
+
Array.isArray(d)&&(e.complete.acceptanceEvidence=d.map((e=>"object"==typeof e&&e.evidence?e.evidence:e)))
|
|
2800
|
+
const m=r.RequestOperationsSchema.parse(e),{requestId:y,operation:w}=m
|
|
2801
|
+
switch(f.info("Processing request operation",{requestId:y,operation:w}),w){case"complete":{f.info("Routing to complete-request handler")
|
|
2802
|
+
const e={requestId:y,summary:m.complete.summary,acceptanceEvidence:m.complete.acceptanceEvidence.map((e=>"string"==typeof e?{evidence:e}:e)),testVerification:m.complete.testVerification}
|
|
2801
2803
|
return await(0,n.handleCompleteRequest)(e,t,u,h,g,p)}case"finalize":{f.info("Routing to finalize-request handler")
|
|
2802
|
-
const e={requestId:
|
|
2804
|
+
const e={requestId:y}
|
|
2803
2805
|
return await(0,c.handleFinalizeRequest)(e,t,u,h,g,p)}case"approve":{f.info("Routing to approve-request handler")
|
|
2804
|
-
const e={requestId:
|
|
2806
|
+
const e={requestId:y}
|
|
2805
2807
|
return await(0,l.handleApproveRequest)(e,t,u,h,g,p)}case"revert":{f.info("Routing to revert-request handler")
|
|
2806
|
-
const e={requestId:
|
|
2808
|
+
const e={requestId:y,reason:m.revert.reason,confirmDestructive:m.revert.confirmDestructive}
|
|
2807
2809
|
return await(0,o.handleRevertRequest)(e,t,u,h,g)}case"get-info":{f.info("Routing to get-request-information handler")
|
|
2808
|
-
const e={requestId:
|
|
2810
|
+
const e={requestId:y}
|
|
2809
2811
|
return await(0,s.handleGetRequestInformation)(e,t,u,h,g)}case"list":{f.info("Routing to list-requests handler")
|
|
2810
|
-
const e={filters:
|
|
2812
|
+
const e={filters:m.list?.filters}
|
|
2811
2813
|
return await(0,i.handleListRequests)(e,t,u,h,g)}case"search":{f.info("Routing to search-requests handler")
|
|
2812
|
-
const e={search:
|
|
2813
|
-
return await(0,a.handleSearchRequests)(e,t,u,h,g)}default:{const e="Unknown operation type: "+
|
|
2814
|
+
const e={search:m.search}
|
|
2815
|
+
return await(0,a.handleSearchRequests)(e,t,u,h,g)}default:{const e="Unknown operation type: "+w
|
|
2814
2816
|
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}}}
|
|
2815
2817
|
const r=t(6183),n=t(5715),o=t(6416),s=t(5434),i=t(8037),a=t(233),c=t(3596),l=t(1537),d=t(8824)},4710(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2816
2818
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClient=void 0
|
|
@@ -2956,12 +2958,12 @@ let r=null
|
|
|
2956
2958
|
for(const n of e)r&&r.commitHash===n.commitHash?r.endLine=n.lineNumber:(r&&t.push(r),r={startLine:n.lineNumber,endLine:n.lineNumber,commitHash:n.commitHash,author:n.author,authorEmail:n.authorEmail,date:new Date(1e3*n.timestamp),commitMessage:n.commitMessage||"",firstLineContent:n.content,recordId:null,taskId:null,taskTitle:null,requestId:null,requestTitle:null})
|
|
2957
2959
|
return r&&t.push(r),t}(v)
|
|
2958
2960
|
c.info("Parsed blame output",{totalLines:v.length,groups:C.length})
|
|
2959
|
-
const
|
|
2960
|
-
for(const e of
|
|
2961
|
+
const _=new Set(C.map((e=>e.commitHash))),E=new Map
|
|
2962
|
+
for(const e of _){const t=C.find((t=>t.commitHash===e))
|
|
2961
2963
|
if(!t)continue
|
|
2962
2964
|
const r=(0,l.extractRecordId)(t.commitMessage)
|
|
2963
2965
|
if(r)try{const t=await(0,l.getCachedTraceabilityInfo)(r,s,c)
|
|
2964
|
-
|
|
2966
|
+
E.set(e,t)}catch(t){c.warn("Failed to get traceability info",{recordId:r,error:(0,h.getErrorMessage)(t)}),E.set(e,null)}else E.set(e,null)}for(const e of C){const t=E.get(e.commitHash)
|
|
2965
2967
|
t&&(e.recordId=t.record?.id||null,e.taskId=t.task?.id||null,e.taskTitle=t.task?.title||null,e.requestId=t.request?.id||null,e.requestTitle=t.request?.title||null)}const q=function(e,t,s){let i=`## Blame: ${e}${s?` (lines ${s.start}-${s.end})`:""}\n\n`
|
|
2966
2968
|
if(0===t.length)return i+="_No blame information available._\n",i
|
|
2967
2969
|
for(const e of t){const t=e.startLine===e.endLine?"Line "+e.startLine:`Lines ${e.startLine}-${e.endLine}`
|
|
@@ -3342,11 +3344,11 @@ return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModu
|
|
|
3342
3344
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDeleteFiles=async function(e,t,r,n,o,s){const i=n.child({tool:"delete_files"}),m=Date.now()
|
|
3343
3345
|
let y,w,b=l.FileOperationPhase.VALIDATION
|
|
3344
3346
|
const k={toolName:"delete-files",operationName:"delete",fileOperationPhase:l.FileOperationPhase.FILE_WRITE,recordType:"delete-files",metricsPrefix:"delete_files",successMessage:"Successfully deleted files",failureMessage:"Failed to delete files"}
|
|
3345
|
-
try{const n=r.getTaskClient(),u=r.getToolRecordClient(),I=r.getRequestClient(),v=l.validateArgs(e,c.DeleteFilesSchema),{taskId:C,paths:
|
|
3347
|
+
try{const n=r.getTaskClient(),u=r.getToolRecordClient(),I=r.getRequestClient(),v=l.validateArgs(e,c.DeleteFilesSchema),{taskId:C,paths:_,operations:E,comment:q}=v
|
|
3346
3348
|
let S=[]
|
|
3347
|
-
if(
|
|
3348
|
-
else{if(!
|
|
3349
|
-
S=
|
|
3349
|
+
if(_)S=_.map((e=>({type:"file",target:e})))
|
|
3350
|
+
else{if(!E)throw Error("Either paths or operations must be specified")
|
|
3351
|
+
S=E.map((e=>{if(e.path)return{type:"file",target:e.path}
|
|
3350
3352
|
if(e.documentId)return{type:"document",target:e.documentId}
|
|
3351
3353
|
throw Error("Invalid operation: neither path nor documentId specified")}))}if(0===S.length)throw Error("At least one file or document must be specified for deletion")
|
|
3352
3354
|
const T=S.filter((e=>"file"===e.type)),P=S.filter((e=>"document"===e.type)),R=S.length
|
|
@@ -3455,10 +3457,10 @@ try{this.logger.info(`Recovering file ${e.path} to commit ${e.commitHash}`,{path
|
|
|
3455
3457
|
const n=await this.requestWithRetry("POST","/api/files/recover",t)
|
|
3456
3458
|
if(!(0,i.safeGetResponseData)(n,null))throw new r.ServiceError("Empty response when recovering file")
|
|
3457
3459
|
const o=(0,i.safeGetResponseData)(n,{success:!0,path:e.path,commitHash:e.commitHash,backupPath:void 0})
|
|
3458
|
-
return this.logger.info("Successfully recovered file "+e.path,{path:o.path,commitHash:o.commitHash,backupPath:o.backupPath}),o}catch(t){throw this.logger.error("Failed to recover file "+e.path,{path:e.path,commitHash:e.commitHash,error:t instanceof Error?t.stack:t+""}),t}}}exports.FileOperationsClient=a},6183(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.PlanWriteSchema=exports.PlanReadSchema=exports.DocumentOperationsSchema=exports.SearchDocumentsSchema=exports.CreateDocumentSchema=exports.ReplaceLinesSchema=exports.InsertLinesSchema=exports.SwitchToRequestBranchSchema=exports.PlannerOpsSchema=exports.SpecialistOpsSchema=exports.SubagentOperationsSchema=exports.TaskOperationsSchema=exports.CompleteTaskSchema=exports.GetTaskInformationSchema=exports.GetRequestInformationSchema=exports.ListRequestsSchema=exports.ListTasksSchema=exports.SearchSchema=exports.QueryHistorySchema=exports.FileRecoverSchema=exports.FileHistorySchema=exports.DeleteFilesSchema=exports.DeleteFileSchema=exports.ReplaceInFileSchema=exports.ReplaceInFilesSchema=exports.ReplaceStringsSchema=exports.ReplaceStringSchema=exports.MoveFilesSchema=exports.CreateDirectorySchema=exports.GetFileInfoSchema=exports.ListDirectorySchema=exports.ReadFilesSchema=exports.ViewAssetSchema=exports.WriteFileSchema=exports.UpdateTaskStatusSchema=exports.CreateTaskSchema=exports.CreateRequestSchema=exports.CompleteRequestSchema=exports.ExecutedTestSchema=exports.TestVerificationSchema=exports.TestDefinitionSchema=exports.AcceptanceCriterionSchema=exports.RecordTypeEnum=exports.EvidenceTypeEnum=exports.CriterionStatusEnum=exports.RequestStatusEnum=exports.TaskStatusEnum=exports.RequestTypeEnum=exports.TestCoverageTypeEnum=exports.CompletionStatusEnum=void 0,exports.SessionMessageOperationsSchema=exports.ReportTestResultsSchema=exports.ExecuteTestCommandSchema=exports.TestingReferenceSchema=exports.TestingProcessUpdateSchema=exports.TestingProcessCreateSchema=exports.TestingProcessGetSchema=exports.TestingProcessListSchema=exports.MetaReferenceSchema=exports.MetaAgentListSchema=exports.MetaWorkflowRemoveRecipeSchema=exports.MetaWorkflowAddRecipeSchema=exports.MetaHookCreateSchema=exports.MetaHookListSchema=exports.MetaRecipeRemoveHookSchema=exports.MetaRecipeAddHookSchema=exports.MetaRecipeCreateSchema=exports.MetaRecipeGetSchema=exports.MetaRecipeListSchema=exports.MetaWorkflowUpdateSchema=exports.MetaWorkflowCreateSchema=exports.MetaWorkflowGetSchema=exports.MetaWorkflowListSchema=exports.GenerateRequestJournalSchema=exports.
|
|
3459
|
-
const r=t(1569),n=t(8955),o=r.z.string().refine((e=>!!e
|
|
3460
|
-
exports.CompletionStatusEnum=r.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=r.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=r.z.enum(["feature","bugfix","quick-edit"]),exports.TaskStatusEnum=r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=r.z.enum(["open","in_progress","ready_for_review","completed","canceled","reverted","conflicted"]),exports.CriterionStatusEnum=r.z.enum(["unverified","verified"]),exports.EvidenceTypeEnum=r.z.enum(["test","manual","other"]),exports.RecordTypeEnum=r.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=r.z.object({description:r.z.string(),status:r.z.enum(["unverified","verified"]).default("unverified"),evidence:r.z.string().nullable().optional(),evidenceType:r.z.enum(["test","manual","other"]).nullable().optional(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.TestDefinitionSchema=r.z.object({id:r.z.string(),description:r.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:r.z.array(r.z.string())}),exports.TestVerificationSchema=r.z.object({criteria:r.z.array(r.z.string()),tests:r.z.array(r.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:r.z.number(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.ExecutedTestSchema=r.z.object({id:r.z.string(),testId:r.z.string(),status:exports.CompletionStatusEnum,results:r.z.string(),coverage:r.z.array(r.z.string()),executedAt:r.z.string()}),exports.CompleteRequestSchema=r.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:r.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:r.z.string().optional()}),exports.CreateRequestSchema=r.z.object({title:r.z.string(),type:r.z.enum(["feature","bugfix"]),description:r.z.string(),acceptanceCriteria:r.z.array(r.z.string()),planDocumentId:r.z.string().optional()}),exports.CreateTaskSchema=r.z.object({requestId:s,title:r.z.string(),description:r.z.string()}),exports.UpdateTaskStatusSchema=r.z.object({taskId:o,status:exports.TaskStatusEnum,note:r.z.string()}),exports.WriteFileSchema=r.z.object({taskId:o,path:r.z.string().optional(),documentId:i.optional(),content:r.z.union([r.z.string(),r.z.record(r.z.any()),r.z.array(r.z.unknown())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional(),comment:r.z.string()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}),exports.ViewAssetSchema=r.z.object({filename:r.z.string().describe("The asset filename (e.g., 01JMXYZ.png)")}),exports.ReadFilesSchema=r.z.object({paths:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),lines:r.z.string().optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),encoding:r.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=r.z.object({path:r.z.string(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=r.z.object({path:r.z.string()}),exports.CreateDirectorySchema=r.z.object({path:r.z.string(),taskId:o,comment:r.z.string().optional()}),exports.MoveFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()})),comment:r.z.string()}),exports.ReplaceStringSchema=r.z.object({taskId:o,path:r.z.string(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional(),comment:r.z.string()}),exports.ReplaceStringsSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceInFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1,"old string cannot be empty"),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:r.z.boolean().optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"Either path or documentId is required, but not both"})).min(1,"At least one operation required"),fuzzy_match:r.z.boolean().optional().default(!0),comment:r.z.string()}),exports.ReplaceInFileSchema=exports.ReplaceInFilesSchema,exports.DeleteFileSchema=r.z.object({taskId:o,path:r.z.string(),comment:r.z.string()}),exports.DeleteFilesSchema=r.z.object({taskId:o,paths:r.z.array(r.z.string()).optional(),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})).optional(),comment:r.z.string()}).refine((e=>e.paths&&!e.operations||!e.paths&&e.operations),{message:"paths or operations required"}).refine((e=>e.paths?.length||e.operations?.length),{message:"path/operation required"}),exports.FileHistorySchema=r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}),exports.FileRecoverSchema=r.z.object({taskId:o,path:r.z.string(),commitHash:r.z.string(),createBackup:r.z.boolean().default(!0)}),exports.QueryHistorySchema=r.z.object({queryType:r.z.enum(["file-history","request-file-history","recover","blame"]),fileHistory:r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}).optional(),requestHistory:r.z.object({requestId:s,detailLevel:r.z.enum(["summary","detailed"]).default("summary"),taskId:o.optional(),showDiff:r.z.boolean().optional(),fileFilter:r.z.string().optional()}).optional(),recover:r.z.object({taskId:o,path:r.z.string(),commitHash:r.z.string().optional(),createBackup:r.z.boolean().default(!0)}).optional(),blame:r.z.object({path:r.z.string(),lines:r.z.string().optional(),branch:r.z.string().optional()}).optional()}).refine((e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"request-file-history"===e.queryType?e.requestHistory&&!e.fileHistory&&!e.recover:"recover"===e.queryType?e.recover&&!e.fileHistory&&!e.requestHistory&&!e.blame:"blame"===e.queryType&&e.blame&&!e.fileHistory&&!e.requestHistory&&!e.recover),{message:"Invalid query data"}),exports.SearchSchema=r.z.object({needle:r.z.string().optional(),directory:r.z.string().optional(),options:r.z.object({caseSensitive:r.z.boolean().optional(),fileExtension:r.z.string().optional(),maxResults:r.z.number().optional(),useRegex:r.z.boolean().optional(),searchIn:r.z.enum(["content","filename","both"]).default("content").optional(),contextLines:r.z.number().min(0).max(10).optional(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=r.z.object({requestId:s,filters:r.z.object({status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.ListRequestsSchema=r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["open","in_progress","ready_for_review","completed","canceled"]).optional(),planDocumentId:r.z.string().optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.GetRequestInformationSchema=r.z.object({requestId:s}),exports.GetTaskInformationSchema=r.z.object({taskId:o}),exports.CompleteTaskSchema=r.z.object({taskId:o,summary:r.z.string()}),exports.TaskOperationsSchema=r.z.object({taskId:o.optional(),requestId:s.optional(),operation:r.z.enum(["
|
|
3461
|
-
return"
|
|
3460
|
+
return this.logger.info("Successfully recovered file "+e.path,{path:o.path,commitHash:o.commitHash,backupPath:o.backupPath}),o}catch(t){throw this.logger.error("Failed to recover file "+e.path,{path:e.path,commitHash:e.commitHash,error:t instanceof Error?t.stack:t+""}),t}}}exports.FileOperationsClient=a},6183(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.PlanWriteSchema=exports.PlanReadSchema=exports.DocumentOperationsSchema=exports.SearchDocumentsSchema=exports.CreateDocumentSchema=exports.ReplaceLinesSchema=exports.InsertLinesSchema=exports.SwitchToRequestBranchSchema=exports.PlannerOpsSchema=exports.SpecialistOpsSchema=exports.SubagentOperationsSchema=exports.TaskOperationsSchema=exports.CompleteTaskSchema=exports.GetTaskInformationSchema=exports.GetRequestInformationSchema=exports.ListRequestsSchema=exports.ListTasksSchema=exports.SearchSchema=exports.QueryHistorySchema=exports.FileRecoverSchema=exports.FileHistorySchema=exports.DeleteFilesSchema=exports.DeleteFileSchema=exports.ReplaceInFileSchema=exports.ReplaceInFilesSchema=exports.ReplaceStringsSchema=exports.ReplaceStringSchema=exports.MoveFilesSchema=exports.CreateDirectorySchema=exports.GetFileInfoSchema=exports.ListDirectorySchema=exports.ReadFilesSchema=exports.ViewAssetSchema=exports.WriteFileSchema=exports.UpdateTaskStatusSchema=exports.CreateTaskSchema=exports.CreateRequestSchema=exports.CompleteRequestSchema=exports.ExecutedTestSchema=exports.TestVerificationSchema=exports.TestDefinitionSchema=exports.AcceptanceCriterionSchema=exports.RecordTypeEnum=exports.EvidenceTypeEnum=exports.CriterionStatusEnum=exports.RequestStatusEnum=exports.TaskStatusEnum=exports.RequestTypeEnum=exports.TestCoverageTypeEnum=exports.CompletionStatusEnum=void 0,exports.SessionMessageOperationsSchema=exports.ReportTestResultsSchema=exports.ExecuteTestCommandSchema=exports.TestingReferenceSchema=exports.TestingProcessUpdateSchema=exports.TestingProcessCreateSchema=exports.TestingProcessGetSchema=exports.TestingProcessListSchema=exports.MetaReferenceSchema=exports.MetaAgentListSchema=exports.MetaWorkflowRemoveRecipeSchema=exports.MetaWorkflowAddRecipeSchema=exports.MetaHookCreateSchema=exports.MetaHookListSchema=exports.MetaRecipeRemoveHookSchema=exports.MetaRecipeAddHookSchema=exports.MetaRecipeCreateSchema=exports.MetaRecipeGetSchema=exports.MetaRecipeListSchema=exports.MetaWorkflowUpdateSchema=exports.MetaWorkflowCreateSchema=exports.MetaWorkflowGetSchema=exports.MetaWorkflowListSchema=exports.GenerateRequestJournalSchema=exports.QuickManageSchema=exports.QuickReplaceSchema=exports.QuickWriteSchema=exports.RequestOperationsSchema=exports.ManageFilesSchema=exports.ModifyFileSchema=exports.RevertRequestSchema=exports.SwitchToBranchSchema=exports.SwitchToMainBranchSchema=void 0
|
|
3461
|
+
const r=t(1569),n=t(8955),o=r.z.string().refine((e=>!!e&&/^tas\d{6}$/.test(e)),{message:"Task ID must match format: tas###### (e.g. tas000001)"}),s=r.z.string().refine((e=>!!e&&/^req\d{6}$/.test(e)),{message:"Request ID must match format: req###### (e.g. req000001)"}),i=r.z.string().refine((e=>!!e&&(/^doc_[0-9A-Z]{26}$/i.test(e)||/^(doc|plan|jour)\d{6}$/.test(e))),{message:"Document ID must match format: doc_[26 alphanumeric] (ULID) or doc######/plan######/jour###### (local ID)"})
|
|
3462
|
+
exports.CompletionStatusEnum=r.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=r.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=r.z.enum(["feature","bugfix","quick-edit"]),exports.TaskStatusEnum=r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=r.z.enum(["open","in_progress","ready_for_review","completed","canceled","reverted","conflicted"]),exports.CriterionStatusEnum=r.z.enum(["unverified","verified"]),exports.EvidenceTypeEnum=r.z.enum(["test","manual","other"]),exports.RecordTypeEnum=r.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=r.z.object({description:r.z.string(),status:r.z.enum(["unverified","verified"]).default("unverified"),evidence:r.z.string().nullable().optional(),evidenceType:r.z.enum(["test","manual","other"]).nullable().optional(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.TestDefinitionSchema=r.z.object({id:r.z.string(),description:r.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:r.z.array(r.z.string())}),exports.TestVerificationSchema=r.z.object({criteria:r.z.array(r.z.string()),tests:r.z.array(r.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:r.z.number(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.ExecutedTestSchema=r.z.object({id:r.z.string(),testId:r.z.string(),status:exports.CompletionStatusEnum,results:r.z.string(),coverage:r.z.array(r.z.string()),executedAt:r.z.string()}),exports.CompleteRequestSchema=r.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:r.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:r.z.string().optional()}),exports.CreateRequestSchema=r.z.object({title:r.z.string(),type:r.z.enum(["feature","bugfix"]),description:r.z.string(),acceptanceCriteria:r.z.array(r.z.string()),planDocumentId:r.z.string().optional()}),exports.CreateTaskSchema=r.z.object({requestId:s,title:r.z.string(),description:r.z.string()}),exports.UpdateTaskStatusSchema=r.z.object({taskId:o,status:exports.TaskStatusEnum,note:r.z.string()}),exports.WriteFileSchema=r.z.object({taskId:o,path:r.z.string().optional(),documentId:i.optional(),content:r.z.union([r.z.string(),r.z.record(r.z.any()),r.z.array(r.z.unknown())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional(),comment:r.z.string()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}),exports.ViewAssetSchema=r.z.object({filename:r.z.string().describe("The asset filename (e.g., 01JMXYZ.png)")}),exports.ReadFilesSchema=r.z.object({paths:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),lines:r.z.string().optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),encoding:r.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=r.z.object({path:r.z.string(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=r.z.object({path:r.z.string()}),exports.CreateDirectorySchema=r.z.object({path:r.z.string(),taskId:o,comment:r.z.string().optional()}),exports.MoveFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()})),comment:r.z.string()}),exports.ReplaceStringSchema=r.z.object({taskId:o,path:r.z.string(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional(),comment:r.z.string()}),exports.ReplaceStringsSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceInFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1,"old string cannot be empty"),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:r.z.boolean().optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"Either path or documentId is required, but not both"})).min(1,"At least one operation required"),fuzzy_match:r.z.boolean().optional().default(!0),comment:r.z.string()}),exports.ReplaceInFileSchema=exports.ReplaceInFilesSchema,exports.DeleteFileSchema=r.z.object({taskId:o,path:r.z.string(),comment:r.z.string()}),exports.DeleteFilesSchema=r.z.object({taskId:o,paths:r.z.array(r.z.string()).optional(),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})).optional(),comment:r.z.string()}).refine((e=>e.paths&&!e.operations||!e.paths&&e.operations),{message:"paths or operations required"}).refine((e=>e.paths?.length||e.operations?.length),{message:"path/operation required"}),exports.FileHistorySchema=r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}),exports.FileRecoverSchema=r.z.object({taskId:o,path:r.z.string(),commitHash:r.z.string(),createBackup:r.z.boolean().default(!0)}),exports.QueryHistorySchema=r.z.object({queryType:r.z.enum(["file-history","request-file-history","recover","blame"],{errorMap(){return{message:"Invalid queryType. Valid options: file-history, request-file-history, recover, blame"}}}),fileHistory:r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}).optional(),requestHistory:r.z.object({requestId:s,detailLevel:r.z.enum(["summary","detailed"]).default("summary"),taskId:o.optional(),showDiff:r.z.boolean().optional(),fileFilter:r.z.string().optional()}).optional(),recover:r.z.object({taskId:o,path:r.z.string(),commitHash:r.z.string().optional(),createBackup:r.z.boolean().default(!0)}).optional(),blame:r.z.object({path:r.z.string(),lines:r.z.string().optional(),branch:r.z.string().optional()}).optional()}).refine((e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"request-file-history"===e.queryType?e.requestHistory&&!e.fileHistory&&!e.recover:"recover"===e.queryType?e.recover&&!e.fileHistory&&!e.requestHistory&&!e.blame:"blame"===e.queryType&&e.blame&&!e.fileHistory&&!e.requestHistory&&!e.recover),{message:"Invalid query data"}),exports.SearchSchema=r.z.object({needle:r.z.string().optional(),directory:r.z.string().optional(),options:r.z.object({caseSensitive:r.z.boolean().optional(),fileExtension:r.z.string().optional(),maxResults:r.z.number().optional(),useRegex:r.z.boolean().optional(),searchIn:r.z.enum(["content","filename","both"]).default("content").optional(),contextLines:r.z.number().min(0).max(10).optional(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=r.z.object({requestId:s,filters:r.z.object({status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.ListRequestsSchema=r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["open","in_progress","ready_for_review","completed","canceled"]).optional(),planDocumentId:r.z.string().optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.GetRequestInformationSchema=r.z.object({requestId:s}),exports.GetTaskInformationSchema=r.z.object({taskId:o}),exports.CompleteTaskSchema=r.z.object({taskId:o,summary:r.z.string()}),exports.TaskOperationsSchema=r.z.object({taskId:o.optional(),requestId:s.optional(),operation:r.z.enum(["get-info","list"]),create:r.z.object({title:r.z.string(),description:r.z.string()}).optional(),complete:r.z.object({summary:r.z.string()}).optional(),list:r.z.object({filters:r.z.object({status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional()}).refine((e=>{const t=!!e.list,r=!!e.taskId,n=!!e.requestId
|
|
3463
|
+
return"get-info"===e.operation?!t&&r&&!n:"list"===e.operation&&!r&&n}),{message:"Invalid operation data"})
|
|
3462
3464
|
const a=r.z.string().min(1).describe("OpenCode session ID")
|
|
3463
3465
|
exports.SubagentOperationsSchema=r.z.object({sessionId:a.optional(),operation:r.z.enum(["spawn","continue","check-status","abort","read-messages","list-sessions"]),spawn:r.z.object({agent:r.z.string().default("work").refine((e=>(0,n.isValidAgent)(e)),{message:"Invalid agent. Check tool description for available agents."}).describe("The subagent type to spawn (see tool description for available agents)"),prompt:r.z.string().min(1).describe("The task/prompt for the subagent to work on"),description:r.z.string().max(60).describe('Brief label for the UI, e.g. "Plan auth refactor" (max 60 chars)'),requestId:r.z.string().regex(/^req\d{6}$/).optional().describe("Optional request ID to associate with the work"),allowParallel:r.z.boolean().default(!1).optional().describe("Allow spawning even if request already has active workers (default: false, will block)"),useExistingSession:r.z.string().optional().describe("Optional existing session ID to send prompt to instead of creating new session")}).optional(),continue:r.z.object({prompt:r.z.string().min(1).describe("New instructions/feedback to send to the subagent")}).optional(),readMessages:r.z.object({limit:r.z.number().min(1).max(50).default(1).describe("Number of recent messages to fetch (default 10, max 50)")}).optional(),listSessions:r.z.object({activeOnly:r.z.boolean().default(!1).describe("Only show sessions that are currently active/busy"),requestId:r.z.string().optional().describe("Find sessions that worked on a specific request"),limit:r.z.number().min(1).max(100).optional().describe("Only show N most recent sessions"),minTokens:r.z.number().min(0).optional().describe("Only show sessions with at least this many tokens"),maxTokens:r.z.number().min(0).optional().describe("Only show sessions with at most this many tokens"),maxAgeHours:r.z.number().min(0).optional().describe("Only show sessions newer than X hours")}).optional()}).refine((e=>{const t=!!e.sessionId,r=!!e.spawn,n=!!e.continue,o=!!e.readMessages
|
|
3464
3466
|
return"spawn"===e.operation?r&&!n&&!o:"continue"===e.operation?n&&!r&&!o&&t:"check-status"===e.operation||"abort"===e.operation?!r&&!n&&!o&&t:"read-messages"===e.operation?!r&&!n&&t:"list-sessions"===e.operation&&!(r||n||o||t)}),{message:"Invalid operation data: spawn requires spawn object, continue/check-status/abort/read-messages require sessionId"}),exports.SpecialistOpsSchema=r.z.object({operation:r.z.enum(["delegate","follow-up","check-status","list","abort"]),sessionId:a.optional(),delegate:r.z.object({prompt:r.z.string().min(1).describe("Detailed instructions for the specialist"),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars)"),requestId:r.z.string().regex(/^req\d{6}$/).describe("Request ID to associate with the work").optional(),specialization:r.z.string().max(100).describe('Domain description for the specialist (e.g. "Frontend UI components", "Database migrations")')}).optional(),followUp:r.z.object({prompt:r.z.string().min(1).describe("Follow-up instructions or feedback for the specialist"),specialization:r.z.string().max(100).describe("Update the specialist's domain description if their focus has shifted").optional()}).optional(),list:r.z.object({activeOnly:r.z.boolean().default(!1).describe("Only show active/busy specialists"),requestId:r.z.string().optional().describe("Filter to specialists working on a specific request"),limit:r.z.number().min(1).max(100).optional().describe("Max sessions to return")}).optional()}).refine((e=>{const t=!!e.sessionId,r=!!e.delegate,n=!!e.followUp
|
|
@@ -3469,8 +3471,8 @@ exports.PlanReadSchema=r.z.object({operation:r.z.enum(["get","get-active","list"
|
|
|
3469
3471
|
return null===t||"list"===e.operation?!r||"list"===e.operation&&void 0!==e.list:void 0!==e[t]}),{message:"Invalid operation data: ensure the correct sub-object is provided for the chosen operation"}),exports.PlanWriteSchema=r.z.object({operation:r.z.enum(["update","append","replace","create-snapshot","restore","set-active"]),setActive:r.z.object({planId:c}).optional(),update:r.z.object({planId:c,content:r.z.string(),name:r.z.string().optional().describe("Optional new name for the plan (omit to keep current name)")}).optional(),append:r.z.object({planId:c,content:r.z.string().describe("Content to append to the end of the plan"),name:r.z.string().optional().describe("Optional new name for the plan (omit to keep current name)")}).optional(),replace:r.z.object({planId:c,old:r.z.string().min(1).describe("Text to find in the plan"),new:r.z.string().describe("Replacement text"),name:r.z.string().optional().describe("Optional new name for the plan (omit to keep current name)")}).optional(),createSnapshot:r.z.object({planId:c,versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional()}).optional(),restore:r.z.object({planId:c,versionNumber:r.z.number().int().min(1)}).optional()}).refine((e=>{const t={update:"update",append:"append",replace:"replace","create-snapshot":"createSnapshot",restore:"restore","set-active":"setActive"}[e.operation]
|
|
3470
3472
|
if(!t)return!1
|
|
3471
3473
|
const r=["create","update","append","replace","createSnapshot","restore","setActive"].filter((e=>e!==t)).some((t=>void 0!==e[t]))
|
|
3472
|
-
return void 0!==e[t]&&!r}),{message:"Invalid operation data: ensure the correct sub-object is provided for the chosen operation"}),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional(),password:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:s,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),operationType:r.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:r.z.object({replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).optional(),insertLines:r.z.object({insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).optional(),replaceLines:r.z.object({replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).optional(),deleteString:r.z.object({patterns:r.z.array(r.z.string()),mode:r.z.enum(["all","unique"]).optional()}).optional(),deleteLines:r.z.object({lines:r.z.string()}).optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}).refine((e=>"replace-string"===e.operationType?e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"insert-lines"===e.operationType?e.insertLines&&!e.replaceString&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"replace-lines"===e.operationType?e.replaceLines&&!e.replaceString&&!e.insertLines&&!e.deleteString&&!e.deleteLines:"delete-string"===e.operationType?e.deleteString&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteLines:"delete-lines"===e.operationType&&e.deleteLines&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString),{message:"Invalid operation data"})),comment:r.z.string()}),exports.ManageFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}))}).optional(),getFileInfo:r.z.object({path:r.z.string()}).optional()}).refine((e=>"create-directory"===e.operationType?e.createDirectory&&!e.moveFiles&&!e.deleteFiles&&!e.getFileInfo:"move-files"===e.operationType?e.moveFiles&&!e.createDirectory&&!e.deleteFiles&&!e.getFileInfo:"delete-files"===e.operationType?e.deleteFiles&&!e.createDirectory&&!e.moveFiles&&!e.getFileInfo:"get-file-info"===e.operationType&&e.getFileInfo&&!e.createDirectory&&!e.moveFiles&&!e.deleteFiles),{message:"Invalid operation data"})),comment:r.z.string()}),exports.RequestOperationsSchema=r.z.object({requestId:s.optional(),operation:r.z.enum(["complete","finalize","approve","revert","get-info","list","search"]),complete:r.z.object({summary:r.z.string(),acceptanceEvidence:r.z.array(r.z.
|
|
3473
|
-
return"complete"===e.operation?t&&!r&&!n&&!o&&!s&&!i&&a:"finalize"===e.operation?!t&&!n&&!o&&!s&&!i&&a:"approve"===e.operation?!t&&!r&&!o&&!s&&!i&&a:"revert"===e.operation?o&&!t&&!r&&!n&&!s&&!i&&a:"get-info"===e.operation?!t&&!r&&!n&&!o&&!s&&!i&&a:"list"===e.operation?!(t||r||n||o||i):"search"===e.operation&&i&&!t&&!r&&!n&&!o&&!s}),{message:"Invalid operation data"}),exports.
|
|
3474
|
+
return void 0!==e[t]&&!r}),{message:"Invalid operation data: ensure the correct sub-object is provided for the chosen operation"}),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional(),password:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:s,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),operationType:r.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:r.z.object({replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).optional(),insertLines:r.z.object({insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).optional(),replaceLines:r.z.object({replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).optional(),deleteString:r.z.object({patterns:r.z.array(r.z.string()),mode:r.z.enum(["all","unique"]).optional()}).optional(),deleteLines:r.z.object({lines:r.z.string()}).optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}).refine((e=>"replace-string"===e.operationType?e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"insert-lines"===e.operationType?e.insertLines&&!e.replaceString&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"replace-lines"===e.operationType?e.replaceLines&&!e.replaceString&&!e.insertLines&&!e.deleteString&&!e.deleteLines:"delete-string"===e.operationType?e.deleteString&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteLines:"delete-lines"===e.operationType&&e.deleteLines&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString),{message:"Invalid operation data"})),comment:r.z.string()}),exports.ManageFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}))}).optional(),getFileInfo:r.z.object({path:r.z.string()}).optional()}).refine((e=>"create-directory"===e.operationType?e.createDirectory&&!e.moveFiles&&!e.deleteFiles&&!e.getFileInfo:"move-files"===e.operationType?e.moveFiles&&!e.createDirectory&&!e.deleteFiles&&!e.getFileInfo:"delete-files"===e.operationType?e.deleteFiles&&!e.createDirectory&&!e.moveFiles&&!e.getFileInfo:"get-file-info"===e.operationType&&e.getFileInfo&&!e.createDirectory&&!e.moveFiles&&!e.deleteFiles),{message:"Invalid operation data"})),comment:r.z.string()}),exports.RequestOperationsSchema=r.z.object({requestId:s.optional(),operation:r.z.enum(["complete","finalize","approve","revert","get-info","list","search"]),complete:r.z.object({summary:r.z.string(),acceptanceEvidence:r.z.array(r.z.string()),testVerification:r.z.object({testRecords:r.z.array(r.z.string()),coverage:r.z.object({criteriaTestedCount:r.z.number(),totalTestCases:r.z.number()}),criterionCoverage:r.z.array(r.z.object({coverage:r.z.enum(["none","partial","full"]),testRecords:r.z.array(r.z.string())}))}).optional()}).optional(),revert:r.z.object({reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}).optional(),list:r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),finalize:r.z.object({}).optional(),approve:r.z.object({}).optional()}).refine((e=>{const t=!!e.complete,r=!!e.finalize,n=!!e.approve,o=!!e.revert,s=!!e.list,i=!!e.search,a=!!e.requestId
|
|
3475
|
+
return"complete"===e.operation?t&&!r&&!n&&!o&&!s&&!i&&a:"finalize"===e.operation?!t&&!n&&!o&&!s&&!i&&a:"approve"===e.operation?!t&&!r&&!o&&!s&&!i&&a:"revert"===e.operation?o&&!t&&!r&&!n&&!s&&!i&&a:"get-info"===e.operation?!t&&!r&&!n&&!o&&!s&&!i&&a:"list"===e.operation?!(t||r||n||o||i):"search"===e.operation&&i&&!t&&!r&&!n&&!o&&!s}),{message:"Invalid operation data"}),exports.QuickWriteSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),path:r.z.string().optional(),documentId:i.optional(),content:r.z.union([r.z.string(),r.z.record(r.z.any()),r.z.array(r.z.unknown())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}),exports.QuickReplaceSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:r.z.boolean().optional()})).min(1),fuzzy_match:r.z.boolean().optional(),comment:r.z.string().min(1,"Comment describing the change is required")}),exports.QuickManageSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}))}).optional()})).min(1)}),exports.GenerateRequestJournalSchema=r.z.object({requestId:r.z.string().regex(/^req[_\d].+$/,"Invalid request ID format. Expected format: req_[26 chars] or req######")}),exports.MetaWorkflowListSchema=r.z.object({}),exports.MetaWorkflowGetSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the workflow"),shortName:r.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:r.z.string().optional().describe("Description of what the workflow does"),documentation:r.z.string().optional().describe("Detailed documentation"),defaultAgent:r.z.string().optional().describe("Default agent template to use"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior: auto-merge (default), auto-test-then-merge, or manual-review"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaWorkflowUpdateSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to update"),name:r.z.string().min(1).optional().describe("New name"),shortName:r.z.string().max(10).optional().describe("New short name (max 10 chars)"),description:r.z.string().optional().describe("New description"),documentation:r.z.string().optional().describe("New documentation"),defaultAgent:r.z.string().optional().describe("New default agent"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaRecipeListSchema=r.z.object({}),exports.MetaRecipeGetSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to retrieve")}),exports.MetaRecipeCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the recipe"),description:r.z.string().optional().describe("Description of what the recipe does"),documentation:r.z.string().optional().describe("Detailed documentation")}),exports.MetaRecipeAddHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to add the hook to"),hookId:r.z.string().describe("Hook template ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the recipe (0-based, appended if omitted)")}),exports.MetaRecipeRemoveHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to remove the hook from"),hookId:r.z.string().describe("Hook template ID to remove")}),exports.MetaHookListSchema=r.z.object({}),exports.MetaHookCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the hook"),description:r.z.string().optional().describe("Description of what the hook does"),eventType:r.z.string().describe("Event type that triggers this hook (e.g., session_idle, request_completed, custom:plan_ready)"),category:r.z.enum(["alchemy","session","message","editing","reading","file_management","documents","history","tool"]).default("session").describe("Hook category"),agent:r.z.string().describe("Agent template to execute when hook fires"),promptTemplate:r.z.string().describe("Prompt template with {{variable}} substitution"),condition:r.z.record(r.z.any()).optional().describe("Condition object for filtering when hook fires"),executionMode:r.z.enum(["same_session","sub_agent","background","notification","direct_report"]).default("background").describe("How to execute the hook"),timing:r.z.enum(["before","after"]).default("after").describe("When to fire relative to the event"),maxIterations:r.z.number().int().min(1).optional().describe("Maximum times to fire per session"),emitEvent:r.z.string().optional().describe("Custom event to emit on completion"),emitEventOnCondition:r.z.union([r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}),r.z.array(r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}))]).optional().describe("Conditional event emission based on output")}),exports.MetaWorkflowAddRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to add the recipe to"),recipeId:r.z.string().describe("Recipe ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the workflow (0-based, appended if omitted)")}),exports.MetaWorkflowRemoveRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to remove the recipe from"),recipeId:r.z.string().describe("Recipe ID to remove")}),exports.MetaAgentListSchema=r.z.object({}),exports.MetaReferenceSchema=r.z.object({}),exports.TestingProcessListSchema=r.z.object({}),exports.TestingProcessGetSchema=r.z.object({processId:r.z.string().describe("Test process ID to retrieve")})
|
|
3474
3476
|
const l=r.z.object({name:r.z.string().min(1).describe('Command name (e.g., "Build", "Unit Tests")'),command:r.z.string().min(1).describe('Shell command to run (e.g., "npm test")'),required:r.z.boolean().default(!0).describe("If true, failure blocks the request (default: true)"),timeout:r.z.number().int().min(10).max(3600).default(300).describe("Max execution time in seconds (default: 300)")})
|
|
3475
3477
|
exports.TestingProcessCreateSchema=r.z.object({name:r.z.string().min(1).describe("Name for the test process"),description:r.z.string().optional().describe("Description of what this process verifies"),scope:r.z.string().optional().describe('Path prefix for monorepo scoping (e.g., "packages/api/"). Omit for global.'),setup:r.z.array(r.z.string()).optional().describe('Commands to prepare the environment (e.g., ["ln -s ../../node_modules node_modules"])'),commands:r.z.array(l).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands")}),exports.TestingProcessUpdateSchema=r.z.object({processId:r.z.string().describe("Test process ID to update"),name:r.z.string().min(1).optional().describe("New name"),description:r.z.string().optional().describe("New description"),scope:r.z.string().nullable().optional().describe("New scope (null to remove)"),isActive:r.z.boolean().optional().describe("Enable or disable the process"),setup:r.z.array(r.z.string()).optional().describe("New setup commands (replaces existing)"),commands:r.z.array(l).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands")}),exports.TestingReferenceSchema=r.z.object({}),exports.ExecuteTestCommandSchema=r.z.object({processId:r.z.string().describe("Test process ID containing the command"),commandName:r.z.string().describe('Name of the test command to run, or "setup" to run all setup commands in sequence')}),exports.ReportTestResultsSchema=r.z.object({status:r.z.enum(["passed","failed","error"]).describe("Overall result"),results:r.z.object({commands:r.z.array(r.z.object({name:r.z.string().describe("Command name"),status:r.z.enum(["passed","failed","skipped","error"]).describe("Command result"),output:r.z.string().optional().describe("Relevant output snippet"),diagnosis:r.z.string().optional().describe("Why it failed, if applicable")})).describe("Per-command results"),summary:r.z.string().describe("Brief overall summary"),acceptanceCriteria:r.z.array(r.z.object({criterion:r.z.string().describe("The acceptance criterion text"),status:r.z.enum(["verified","unverified","unclear"]),evidence:r.z.string().describe("How verified, or why not")})).optional().describe("AC verification results, if applicable")}).describe("Structured test results")}),exports.SessionMessageOperationsSchema=r.z.object({operation:r.z.enum(["send","reply","list","get","offer-handoff"]),type:r.z.enum(["question","report"]).optional().describe("Message type to send (required for send)"),toSessionId:r.z.string().optional().describe('Target session ID, or "parent" to auto-resolve to parent session (omit for broadcast questions)'),questionType:r.z.enum(["free-form","alternatives"]).optional().describe('Type of question (required for send type="question")'),questionContent:r.z.object({question:r.z.string().min(1).describe("The question text"),context:r.z.string().optional().describe("Additional context"),options:r.z.array(r.z.object({id:r.z.string(),label:r.z.string(),description:r.z.string().optional()})).optional().describe("Options for alternatives questions"),allowMultiple:r.z.boolean().optional().describe("Allow selecting multiple options")}).optional().describe('Question content (required for send type="question")'),priority:r.z.enum(["low","normal","high"]).optional().describe("Question priority"),expiresInHours:r.z.number().optional().describe("Question expiry in hours"),status:r.z.enum(["success","partial","failure","blocked"]).optional().describe('Report status (required for send type="report")'),summary:r.z.string().optional().describe('Report summary (required for send type="report")'),details:r.z.string().optional().describe("Report details"),finish:r.z.boolean().optional().describe("Release request associations after report"),messageCode:r.z.string().optional().describe("Message code (required for reply and get operations)"),respondedBySessionId:r.z.string().optional().describe("Session ID answering the question"),text:r.z.string().optional().describe("Text answer for free-form questions"),selectedOptions:r.z.array(r.z.string()).optional().describe("Selected option IDs for alternatives"),notes:r.z.string().optional().describe("Additional notes"),list:r.z.object({sessionId:r.z.string().optional().describe("Filter by session ID (auto-discovered if omitted)"),messageType:r.z.enum(["question","report","all"]).default("all").describe("Filter by message type"),direction:r.z.enum(["incoming","outgoing","all"]).default("all"),status:r.z.enum(["pending","answered","expired","success","partial","failure","blocked","all"]).default("all").describe("Filter by status"),readStatus:r.z.enum(["unread","read","acknowledged","all"]).default("all").describe("Filter by read status (reports only)"),limit:r.z.number().min(1).max(100).default(50),offset:r.z.number().min(0).default(0)}).optional().describe('List filters (operation: "list" only)'),offerHandoff:r.z.object({summary:r.z.string().describe("Summary of what was planned/created"),requestIds:r.z.array(r.z.string()).describe("Request IDs that were created from the plan")}).optional().describe('Handoff offer details (operation: "offer-handoff" only)')}).refine((e=>"send"===e.operation?!!e.type:"reply"===e.operation?!!e.messageCode:"list"===e.operation||("get"===e.operation?!!e.messageCode:"offer-handoff"===e.operation)),{message:"Invalid operation data: send requires type, reply requires messageCode, get requires messageCode"})},6252(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3476
3478
|
const r=t(6183),n=t(405)
|
|
@@ -3609,9 +3611,9 @@ return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModu
|
|
|
3609
3611
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleInsertLines=async function(e,t,n,o,s,i,a,m){const y=i.child({tool:"insert_lines"}),w=Date.now()
|
|
3610
3612
|
let b,k,I=d.FileOperationPhase.VALIDATION
|
|
3611
3613
|
const v={toolName:"insert-lines",operationName:"insert-lines",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"insert-lines",metricsPrefix:"insert_lines",successMessage:"Successfully inserted lines into files and documents",failureMessage:"Failed to insert lines into files and documents"}
|
|
3612
|
-
try{const i=d.validateArgs(e,l.InsertLinesSchema),{taskId:C,operations:
|
|
3613
|
-
if(y.info("Inserting lines into files and documents",{taskId:C,operationCount:
|
|
3614
|
-
const q=
|
|
3614
|
+
try{const i=d.validateArgs(e,l.InsertLinesSchema),{taskId:C,operations:_,comment:E}=i
|
|
3615
|
+
if(y.info("Inserting lines into files and documents",{taskId:C,operationCount:_.length,comment:E}),!_||0===_.length)throw new u.ValidationError("At least one operation is required")
|
|
3616
|
+
const q=_.filter((e=>e.path)),S=_.filter((e=>e.documentId))
|
|
3615
3617
|
y.info("Operation breakdown",{fileOperations:q.length,documentOperations:S.length})
|
|
3616
3618
|
const T=[]
|
|
3617
3619
|
for(const e of q){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.path,t)
|
|
@@ -3632,7 +3634,7 @@ throw Error(A.error)}if(T.length>0){y.debug("Re-validating file paths with corre
|
|
|
3632
3634
|
for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
|
|
3633
3635
|
T[e]={...r,path:o,fullPath:s}}}if(P.length>0&&j)try{await(0,h.validateRequestStatusForDocumentOperation)(j,s,y,a,"insert-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3634
3636
|
throw e}I=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("insert_lines_phase",1,{phase:I})
|
|
3635
|
-
const D=[...T.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...P.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:$}=await d.createFileOperationRecords(C,j,t.projectId,v.recordType,R,{operationCount:
|
|
3637
|
+
const D=[...T.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...P.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:$}=await d.createFileOperationRecords(C,j,t.projectId,v.recordType,R,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:D,userComment:E},n,o,y,a,v.metricsPrefix,m)
|
|
3636
3638
|
if(b=$,k=$,I=v.fileOperationPhase,a.incrementCounter("insert_lines_phase",1,{phase:I}),T.length>0&&t.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
|
|
3637
3639
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"insert-lines",{requestId:j,taskId:C,workspaceManager:t.workspaceManager},y,a)
|
|
3638
3640
|
e.userChangesCommitted&&(y.debug("[INSERT-LINES] User changes committed before insert operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),y.info("User changes committed before insert-lines operation",{taskId:C,fileOperationsCount:T.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){y.debug("[INSERT-LINES] Pre-tool commit failed, continuing with insertions",{error:e instanceof Error?e.message:e+""}),y.warn("Pre-tool user changes commit failed, continuing with insert operation",{taskId:C,fileOperationsCount:T.length,error:e instanceof Error?e.message:e+""})}y.debug("[INSERT-LINES] Proceeding with file operations",{fileCount:T.length})
|
|
@@ -3647,7 +3649,7 @@ n.filename=s?.filename
|
|
|
3647
3649
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
|
|
3648
3650
|
n.insertions=l,n.successfulInsertions=l.filter((e=>e.success)).length,n.failedInsertions=l.filter((e=>!e.success)).length,n.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&n.successfulInsertions>0?(await c.default.writeFile(o,a,"utf8"),t.documentFileManager.markForSync(e.documentId),n.success=!0,z++,y.info("Document updated successfully",{documentId:e.documentId,filename:n.filename,successfulInsertions:n.successfulInsertions,failedInsertions:n.failedInsertions,linesAdded:n.totalLinesAdded})):0===n.failedInsertions&&(n.success=!0),N+=n.failedInsertions,L+=n.totalLinesAdded}catch(t){n.error=(0,f.getErrorMessage)(t),n.failedInsertions=e.insertions.length,N+=n.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:n.error})}F.push(n)}if(P.length>0)try{for(const e of P){const r=F.find((t=>t.documentId===e.documentId))
|
|
3649
3651
|
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const B=await d.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:k,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),H=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:U,failedOperations:W,totalSuccessfulChanges:G,overallSuccess:V,successfulFiles:J,failedFiles:K}=H
|
|
3650
|
-
try{await o.updateToolRecord(k,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:V?"completed":"failed",error:V?void 0:W+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:D,totalSuccessfulInsertions:G,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:
|
|
3652
|
+
try{await o.updateToolRecord(k,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:V?"completed":"failed",error:V?void 0:W+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations: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"
|
|
3651
3653
|
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"),A.lockAcquired&&A.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${A.lockedRequestId}\n\n`),1===F.length){const e=F[0]
|
|
3652
3654
|
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"
|
|
3653
3655
|
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}`
|
|
@@ -3663,47 +3665,47 @@ const r=t(1253),n=t(5681),o=t(6595),s=t(3895),i=t(6848),a=t(6153),c=t(4710),l=t(
|
|
|
3663
3665
|
exports.ClientFactory=class{static async createClient(e,m,y,w={}){(m=m.child({component:"client-factory"})).info("Creating API client with components")
|
|
3664
3666
|
const b=w.tokenManager||new r.TokenManager(m,w.workingDir||process.cwd())
|
|
3665
3667
|
await b.initialize()
|
|
3666
|
-
const k=w.tokenSynchronizer||new i.ClientTokenSynchronizer(m),I=new s.AuthenticationManager(b,m,k),v=await I.getTokenString(),C=w.connectionStatusManager||new n.ConnectionStatusManager(e,m,y,{alchemyPath:w.alchemyPath,checkIntervalMs:w.offlineCheckIntervalMs,timeoutMs:w.timeout,retryCount:w.retryAttempts}),
|
|
3667
|
-
k.registerClient(
|
|
3668
|
-
const
|
|
3669
|
-
k.registerClient(
|
|
3670
|
-
const q=new a.FileOperationsClient(e,m,y,
|
|
3668
|
+
const k=w.tokenSynchronizer||new i.ClientTokenSynchronizer(m),I=new s.AuthenticationManager(b,m,k),v=await I.getTokenString(),C=w.connectionStatusManager||new n.ConnectionStatusManager(e,m,y,{alchemyPath:w.alchemyPath,checkIntervalMs:w.offlineCheckIntervalMs,timeoutMs:w.timeout,retryCount:w.retryAttempts}),_=new c.ProjectClient(e,m,y,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3669
|
+
k.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3670
|
+
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})
|
|
3671
|
+
k.registerClient(E)
|
|
3672
|
+
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})
|
|
3671
3673
|
k.registerClient(q),m.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
3672
|
-
const S=new u.RequestClient(e,m,y,
|
|
3674
|
+
const S=new u.RequestClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3673
3675
|
k.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
|
|
3674
|
-
const T=new g.DocumentClient(e,m,y,
|
|
3676
|
+
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})
|
|
3675
3677
|
k.registerClient(T)
|
|
3676
|
-
const P=new f.ToolRecordClient(e,m,y,
|
|
3678
|
+
const P=new f.ToolRecordClient(e,m,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3677
3679
|
k.registerClient(P)
|
|
3678
|
-
const R=new d.ProxyClient(e,m,y,
|
|
3680
|
+
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})
|
|
3679
3681
|
if(k.registerClient(R),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
|
|
3680
3682
|
try{m.info("Creating ProjectSynchronizer components")
|
|
3681
|
-
const{ProjectRegistry,ProjectFileSystem,ProjectSynchronizer}=await t.e(478).then(t.bind(t,5478)),e=new ProjectRegistry(m),r=new ProjectFileSystem(m),n=new ProjectSynchronizer(m,e,new l.ProjectClientAdapter(
|
|
3682
|
-
|
|
3683
|
-
throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const M=new o.ApiClient(I,E,
|
|
3683
|
+
const{ProjectRegistry,ProjectFileSystem,ProjectSynchronizer}=await t.e(478).then(t.bind(t,5478)),e=new ProjectRegistry(m),r=new ProjectFileSystem(m),n=new ProjectSynchronizer(m,e,new l.ProjectClientAdapter(_,m),r,{createRemoteProjects:!0})
|
|
3684
|
+
_.setProjectSynchronizer(n),m.info("ProjectSynchronizer created and connected to ProjectClient")}catch(e){const t="Failed to create required ProjectSynchronizer components: "+(0,h.getErrorMessage)(e)
|
|
3685
|
+
throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const M=new o.ApiClient(I,_,E,q,S,T,P,R,m)
|
|
3684
3686
|
m.info("API client initialized with specialized clients"),v?(M.setAuthToken(v),m.info("Auth token set on ApiClient during creation",{hasToken:!0,tokenLength:v.length})):m.warn("No auth token available during ApiClient creation",{info:"Client will need to authenticate before making requests"})
|
|
3685
3687
|
const j=k.verifyAllClients()
|
|
3686
3688
|
j.success?m.info("Token consistency verified across all clients"):m.error(`Token inconsistency detected in ${j.failedClients.length} clients: ${j.failedClients.join(", ")}`)
|
|
3687
3689
|
const x=M.getAuthToken()
|
|
3688
3690
|
return v&&!x?(m.error("CRITICAL: ApiClient token was not set properly!"),M.setAuthToken(v)):x&&m.info("ApiClient token verified",{tokenLength:x.length,matches:x===v}),m.info("API client creation completed successfully"),M}}},6540(e,exports){var t
|
|
3689
3691
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6552(e,exports,t){async function r(){const e=new o.StdioServerTransport,t=(0,l.setupParentProcessDetection)((()=>{k.info("Parent process gone or orphan detected. Shutting down."),process.exit(0)}))
|
|
3690
|
-
if(
|
|
3692
|
+
if(E)try{await E.connectStdio(),(0,a.isDebugToolsEnabled)()&&k.info("Connected stdio transport to server")}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3691
3693
|
throw k.error("Failed to connect stdio transport",{errorDetails:t}),e}else k.error("No global server instance available to connect transport")
|
|
3692
3694
|
return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3693
3695
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
3694
3696
|
const o=t(5802),s=n(t(6928)),i=t(184),a=t(3444),c=t(1152),l=t(8851),d=t(8411),u=n(t(9896)),h=t(4139),g=t(5218),p=t(8824),f=t(9939),m=t(7960),y=process.argv.slice(2),w=y[0]||process.cwd(),b=s.default.resolve(w)
|
|
3695
3697
|
console.error("\n=== MCP STARTUP DIAGNOSTICS ==="),console.error("Script path (process.argv[1]):",process.argv[1]),console.error("Base directory:",b),console.error("ENABLE_DEBUG_TOOLS env:",process.env.ENABLE_DEBUG_TOOLS),console.error("DEBUG_LOGGING env:",process.env.DEBUG_LOGGING),console.error("isDevBuild():",(0,m.isDevBuild)()),console.error("isDebugToolsEnabled():",(0,a.isDebugToolsEnabled)()),console.error("===============================\n")
|
|
3696
|
-
const k=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:b});(0,a.isDebugToolsEnabled)()?k.info("MCP Direct server initializing",{baseDir:b,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):k.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(k.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),
|
|
3698
|
+
const k=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:b});(0,a.isDebugToolsEnabled)()?k.info("MCP Direct server initializing",{baseDir:b,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):k.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(k.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),E)try{E.cleanupSSEConnection()}catch(e){k.error("Error during cleanup after uncaught exception: "+e)}setTimeout((()=>process.exit(1)),500)})),process.on("unhandledRejection",(e=>{k.error("UNHANDLED REJECTION: "+e,{stack:e instanceof Error?e.stack:"No stack available"})})),process.on("exit",(e=>{k.info("Process exiting with code: "+e)}))
|
|
3697
3699
|
const I=process.stdout.write
|
|
3698
3700
|
process.stdout.write=function(e,t,r){try{if("string"==typeof e)try{JSON.parse(e)}catch(t){return e.includes('"__message_type"')||(process.stderr.write("[STDOUT REDIRECTED]: "+e),r&&r()),!0}return"string"==typeof t&&"function"==typeof r?I.call(process.stdout,e,t,r):"function"==typeof t?I.call(process.stdout,e,void 0,t):I.call(process.stdout,e)}catch(e){return process.stderr.write("[STDOUT ERROR]: "+e),!0}},(0,a.isDebugToolsEnabled)()&&(k.info("Initialized stdout filtering to ensure only valid JSON is sent"),k.info("!!!MARKER!!! COMMAND-LINE ARGS:",{args:JSON.stringify(y)}),k.info("!!!MARKER!!! BASE DIRECTORY:",{baseDir:w}),k.info("!!!MARKER!!! ABSOLUTE BASE DIR:",{absBaseDir:b}),k.info("Working with base directory:",{absBaseDir:b}))
|
|
3699
3701
|
try{if(u.default.existsSync(b)||(k.warn(`Base directory ${b} does not exist. Creating it...`),u.default.mkdirSync(b,{recursive:!0})),(0,a.isDebugToolsEnabled)()){const e=s.default.join(b,".mcp-test-file")
|
|
3700
3702
|
u.default.writeFileSync(e,(new Date).toISOString()),k.info("Successfully wrote test file to "+e),u.default.unlinkSync(e),k.info("Successfully deleted test file"),k.info(`Confirmed base directory ${b} exists and is accessible`)}}catch(e){k.error(`Error accessing base directory ${b}:`,{error:e}),k.warn("This may cause issues with file operations - please check permissions")}const v=(0,c.createMetricsCollector)(!1)
|
|
3701
3703
|
let C=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com"
|
|
3702
|
-
const
|
|
3703
|
-
void 0===
|
|
3704
|
-
let
|
|
3704
|
+
const _=global.__serverInitialized
|
|
3705
|
+
void 0===_?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&k.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&k.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
|
|
3706
|
+
let E=null
|
|
3705
3707
|
const q=(0,g.isMultiAgentModeEnabled)(b)
|
|
3706
|
-
try{(0,d.acquireProcessLock)(b,q)||(k.error(`Process lock acquisition failed for ${b}. Another instance may be running.`),k.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&(q?k.info("Multi-agent mode enabled - allowing concurrent access to "+b):k.info("Successfully acquired process lock for "+b))}catch(e){k.error("Lock acquisition threw exception",{error:(0,p.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),k.error("Cannot continue without lock in single-agent mode"),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(k.info("============================================================"),k.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),k.info("BASE DIR: "+b),k.info("ALCHEMY PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME)),k.info("PROJECT PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME+"/project.json")),k.info("MULTI-AGENT MODE: "+q),k.info("MCP client information will be captured during protocol initialization")),k.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(k.info("============================================================"),k.info("Base directory: "+b),k.info("Remote server URL: "+C),k.info("Node version: "+process.version),k.info("Current working directory: "+process.cwd()),k.info("ALLOWED_DIRECTORIES env var: not used (single working directory mode)"),k.info("Server already initialized: "+(
|
|
3708
|
+
try{(0,d.acquireProcessLock)(b,q)||(k.error(`Process lock acquisition failed for ${b}. Another instance may be running.`),k.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&(q?k.info("Multi-agent mode enabled - allowing concurrent access to "+b):k.info("Successfully acquired process lock for "+b))}catch(e){k.error("Lock acquisition threw exception",{error:(0,p.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),k.error("Cannot continue without lock in single-agent mode"),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(k.info("============================================================"),k.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),k.info("BASE DIR: "+b),k.info("ALCHEMY PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME)),k.info("PROJECT PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME+"/project.json")),k.info("MULTI-AGENT MODE: "+q),k.info("MCP client information will be captured during protocol initialization")),k.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(k.info("============================================================"),k.info("Base directory: "+b),k.info("Remote server URL: "+C),k.info("Node version: "+process.version),k.info("Current working directory: "+process.cwd()),k.info("ALLOWED_DIRECTORIES env var: not used (single working directory mode)"),k.info("Server already initialized: "+(_?"YES":"NO"))),_&&((0,a.isDebugToolsEnabled)()&&(k.info("Server already initialized globally, reusing existing server instance"),k.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3707
3709
|
k.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
|
|
3708
3710
|
try{const e=u.default.existsSync(b)
|
|
3709
3711
|
if((0,a.isDebugToolsEnabled)()&&k.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=u.default.statSync(b)
|
|
@@ -3714,9 +3716,9 @@ if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&k.info("Loaded REMOTE_SE
|
|
|
3714
3716
|
try{const e=await(0,f.syncPlugins)(b,(0,m.isDevBuild)(),k)
|
|
3715
3717
|
e.synced.length>0&&k.info("Synced plugins on startup",{synced:e.synced}),e.errors.length>0&&k.warn("Some plugins failed to sync",{errors:e.errors})}catch(e){k.warn("Plugin sync failed",{error:e instanceof Error?e.message:"Unknown error"})}(0,a.isDebugToolsEnabled)()&&(k.info("Creating MCP server with base dir: "+b),k.info("Using remote server URL: "+C))
|
|
3716
3718
|
const e=await(0,i.createServer)(b,k,v,C,{multiAgentMode:(0,g.isMultiAgentModeEnabled)(b)})
|
|
3717
|
-
|
|
3719
|
+
E=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&k.info("MCP server created successfully")
|
|
3718
3720
|
const n=r()
|
|
3719
|
-
return(0,a.isDebugToolsEnabled)()&&k.info("Stdio transport registered with server"),{server:
|
|
3721
|
+
return(0,a.isDebugToolsEnabled)()&&k.info("Stdio transport registered with server"),{server:E,transportInfo:n}}catch(e){throw k.error("Failed to initialize MCP server",{error:e}),e}})().then((()=>{(0,a.isDebugToolsEnabled)()&&k.info("MCP server initialization complete")})).catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3720
3722
|
k.error("Server initialization failed",{errorDetails:t}),process.exit(1)}))}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3721
3723
|
k.error("Exception during server initialization",{errorDetails:t}),process.exit(1)}process.on("SIGTERM",(()=>{k.info("SIGTERM received, shutting down"),setTimeout((()=>process.exit(0)),500)})),process.on("SIGINT",(()=>{k.info("SIGINT received, shutting down"),setTimeout((()=>process.exit(0)),500)}))},6595(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ApiClient=void 0
|
|
3722
3724
|
const r=t(1599),n=t(2690),o=t(4465),s=t(5187),i=t(5674),a=t(8824)
|
|
@@ -3757,9 +3759,9 @@ return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModu
|
|
|
3757
3759
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceLines=async function(e,t,n,o,s,i,a,m){const w=i.child({tool:"replace_lines"}),b=Date.now()
|
|
3758
3760
|
let k,I,v=d.FileOperationPhase.VALIDATION
|
|
3759
3761
|
const C={toolName:"replace-lines",operationName:"replace-lines",fileOperationPhase:d.FileOperationPhase.STRING_REPLACEMENT,recordType:"replace-lines",metricsPrefix:"replace_lines",successMessage:"Successfully replaced lines in files and documents",failureMessage:"Failed to replace lines in files and documents"}
|
|
3760
|
-
try{const i=d.validateArgs(e,l.ReplaceLinesSchema),{taskId:
|
|
3761
|
-
if(w.info("Replacing lines in files and documents",{taskId:
|
|
3762
|
-
const S=
|
|
3762
|
+
try{const i=d.validateArgs(e,l.ReplaceLinesSchema),{taskId:_,operations:E,comment:q}=i
|
|
3763
|
+
if(w.info("Replacing lines in files and documents",{taskId:_,operationCount:E.length,comment:q}),!E||0===E.length)throw new u.ValidationError("At least one operation is required")
|
|
3764
|
+
const S=E.filter((e=>e.path)),T=E.filter((e=>e.documentId))
|
|
3763
3765
|
w.info("Operation breakdown",{fileOperations:S.length,documentOperations:T.length})
|
|
3764
3766
|
const P=[]
|
|
3765
3767
|
for(const e of S){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.path,t)
|
|
@@ -3769,21 +3771,21 @@ for(const e of T)R.push({type:"document",documentId:e.documentId,replacements:e.
|
|
|
3769
3771
|
if(R.length>0&&t.apiClient){const e=R.map((e=>e.documentId))
|
|
3770
3772
|
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}
|
|
3771
3773
|
throw e}}v=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3772
|
-
const M=P.length>0?P[0].path:"document-operation",j=await d.validateTaskId(
|
|
3774
|
+
const M=P.length>0?P[0].path:"document-operation",j=await d.validateTaskId(_,M,n,w,a,C.metricsPrefix),x=j?.requestId
|
|
3773
3775
|
let O=null
|
|
3774
|
-
P.length>0&&x&&(O=await d.validateWorkItemStates(
|
|
3776
|
+
P.length>0&&x&&(O=await d.validateWorkItemStates(_,P[0].path,n,s,t,w,a,C.metricsPrefix))
|
|
3775
3777
|
let A={taskPromoted:!1,requestPromoted:!1}
|
|
3776
|
-
P.length>0&&x&&O&&(A=await d.autoPromoteTaskStatus(
|
|
3778
|
+
P.length>0&&x&&O&&(A=await d.autoPromoteTaskStatus(_,j.status,x,O.request?.status,P[0].path,n,s,w,a,C.metricsPrefix),A.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:_,requestId:x,previousStatus:j.status,newStatus:A.newTaskStatus,triggeringOperation:"replace-lines"}))
|
|
3777
3779
|
const D=await d.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:x,context:t,operation:"replace-lines",logger:w,metrics:a,metricsPrefix:C.metricsPrefix})
|
|
3778
3780
|
if(!D.success){if(D.isLockConflict)return{content:[{type:"text",text:"\u274c "+D.error}],isError:!0}
|
|
3779
3781
|
throw Error(D.error)}if(P.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:P.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
|
|
3780
3782
|
for(let e=0;e<P.length;e++){const r=P[e],n=S[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
|
|
3781
3783
|
P[e]={...r,path:o,fullPath:s}}}if(R.length>0&&x)try{await(0,h.validateRequestStatusForDocumentOperation)(x,s,w,a,"replace-lines-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3782
3784
|
throw e}v=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3783
|
-
const $=[...P.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...R.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await d.createFileOperationRecords(
|
|
3785
|
+
const $=[...P.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...R.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:F}=await d.createFileOperationRecords(_,x,t.projectId,C.recordType,M,{operationCount:E.length,fileOperations:P.length,documentOperations:R.length,operations:$,userComment:q},n,o,w,a,C.metricsPrefix,m)
|
|
3784
3786
|
if(k=F,I=F,v=C.fileOperationPhase,a.incrementCounter("replace_lines_phase",1,{phase:v}),P.length>0&&t.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
|
|
3785
|
-
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:x,taskId:
|
|
3786
|
-
e.userChangesCommitted&&(w.debug("[REPLACE-LINES] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before replace-lines operation",{taskId:
|
|
3787
|
+
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},w,a)
|
|
3788
|
+
e.userChangesCommitted&&(w.debug("[REPLACE-LINES] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before replace-lines operation",{taskId:_,fileOperationsCount:P.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[REPLACE-LINES] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:_,fileOperationsCount:P.length,error:e instanceof Error?e.message:e+""})}w.debug("[REPLACE-LINES] Proceeding with file operations",{fileCount:P.length})
|
|
3787
3789
|
const N=[]
|
|
3788
3790
|
let L=0,z=0,B=0,H=0
|
|
3789
3791
|
for(const e of P){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
@@ -3794,7 +3796,7 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
|
|
|
3794
3796
|
n.filename=s?.filename
|
|
3795
3797
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
|
|
3796
3798
|
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))
|
|
3797
|
-
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(
|
|
3799
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const U=await d.handleMultiFileGitCommit(_,P,N,H,{operationType:"Replace lines",toolRecordId:I,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),W=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=W
|
|
3798
3800
|
try{await o.updateToolRecord(I,{metadata:{path:P.length>0?P[0].path:"document:"+R[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:$,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-b,userComment:q,...P.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:K?`Line replacement completed: ${G}/${N.length} operations successful${P.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${V}/${N.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z="## Line Replacement Results\n\n"
|
|
3799
3801
|
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]
|
|
3800
3802
|
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"
|
|
@@ -3931,7 +3933,7 @@ C.has(t)||C.set(t,[])
|
|
|
3931
3933
|
const r=C.get(t)
|
|
3932
3934
|
r&&r.push({filePath:t,recordId:e.id,type:e.type,timestamp:e.createdAt,commitHash:e.metadata.commitHash,status:e.metadata.status||"",record:e})})),s.info(`Grouped records by file path. Found ${C.size} unique files.`)
|
|
3933
3935
|
for(const[A,D]of C.entries())D.sort(((e,t)=>new Date(e.timestamp).getTime()-new Date(t.timestamp).getTime())),s.info(`File ${A} has ${D.length} records.`),s.info("Records with commit hashes: "+D.filter((e=>e.commitHash)).length)
|
|
3934
|
-
const
|
|
3936
|
+
const _=new Map
|
|
3935
3937
|
for(const[$,F]of C.entries()){s.info(`Processing file: ${$} (${F.length} records)`)
|
|
3936
3938
|
const N=new Map
|
|
3937
3939
|
F.forEach((e=>{e.recordId&&e.record?.metadata?.status&&(N.has(e.recordId)||N.set(e.recordId,[]),N.get(e.recordId)?.push(e.record.metadata.status))})),N.forEach(((e,t)=>{s.info(`Record ${t} status updates: ${e.join(" -> ")}`)}))
|
|
@@ -3944,8 +3946,8 @@ if(Y.length>0){const Q=Y.length>1?Y[Y.length-1]:Y[0],Z=Y[0],X=1===Y.length
|
|
|
3944
3946
|
s.info(X?`Using single git commit for ${$}: ${Z.commitHash?Z.commitHash.substring(0,8):"unknown"}`:`Using git commits for ${$}: ${Q.commitHash?Q.commitHash.substring(0,8):"unknown"} to ${Z.commitHash?Z.commitHash.substring(0,8):"unknown"}`)
|
|
3945
3947
|
let ee=""
|
|
3946
3948
|
try{if(X)try{const te=[`${Z.commitHash}:${$}`],re=await t.git.show(te)
|
|
3947
|
-
re&&re.trim().length>0?(ee=re.split("\n").map((e=>"+"+e)).join("\n"),
|
|
3948
|
-
ee=await t.git.diff(oe),
|
|
3949
|
+
re&&re.trim().length>0?(ee=re.split("\n").map((e=>"+"+e)).join("\n"),_.set($,{firstChange:Q,lastChange:Z,hasDiff:!0,diffText:ee})):_.set($,{firstChange:Q,lastChange:Z,hasDiff:!1,diffText:"File exists in git history but has no content"})}catch(ne){s.warn("Error getting file content for "+$,{error:ne instanceof Error?ne.message:ne+""}),_.set($,{firstChange:Q,lastChange:Z,hasDiff:!1,diffText:"Error getting file content from git"})}else{const oe=[`${Q.commitHash}..${Z.commitHash}`,"--",$]
|
|
3950
|
+
ee=await t.git.diff(oe),_.set($,{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 "+$,{error:se instanceof Error?se.message:se+""}),_.set($,{firstChange:Q,lastChange:Z,hasDiff:!0,diffText:"Error generating diff, but git history is available"})}continue}}else s.info("No git history found for "+$)}}catch(ie){s.warn("Error getting git history for "+$,{error:(0,u.getErrorMessage)(ie)})}_.set($,{firstChange:F[0],lastChange:F[F.length-1],hasDiff:!1,diffText:"No commit hashes available for this file"})
|
|
3949
3951
|
continue}const z=L[0],B=L[L.length-1]
|
|
3950
3952
|
s.info(`First commit: ${z.commitHash?z.commitHash:"unknown"}, Last commit: ${B.commitHash?B.commitHash:"unknown"}`)
|
|
3951
3953
|
let H=null,U=!1
|
|
@@ -3956,11 +3958,11 @@ const le=await t.git.show(ce)
|
|
|
3956
3958
|
if(le&&le.trim().length>0){let de=""
|
|
3957
3959
|
const ue=le.split("\n")
|
|
3958
3960
|
for(const he of ue)de+=`+${he}\n`
|
|
3959
|
-
|
|
3960
|
-
continue}}catch(ge){s.warn("Error getting new file content for "+$,{error:(0,u.getErrorMessage)(ge)})}
|
|
3961
|
-
continue}if(z.commitHash===B.commitHash&&U){if(H===z.commitHash){
|
|
3961
|
+
_.set($,{firstChange:W,lastChange:B,hasDiff:!0,diffText:de}),s.info(`Formatted new file content as diff, ${ue.length} lines`)
|
|
3962
|
+
continue}}catch(ge){s.warn("Error getting new file content for "+$,{error:(0,u.getErrorMessage)(ge)})}_.set($,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"Only one commit available for this file"})
|
|
3963
|
+
continue}if(z.commitHash===B.commitHash&&U){if(H===z.commitHash){_.set($,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"No changes detected"})
|
|
3962
3964
|
continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let G="",V=!1
|
|
3963
|
-
if(p||"pre-task"!==W.status){try{if(t.git){try{await t.git.show([`${B.commitHash}:${$}`])}catch(fe){s.warn(`File ${$} 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,
|
|
3965
|
+
if(p||"pre-task"!==W.status){try{if(t.git){try{await t.git.show([`${B.commitHash}:${$}`])}catch(fe){s.warn(`File ${$} 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($,{firstChange:W,lastChange:B,hasDiff:V,diffText:G})
|
|
3964
3966
|
continue}let pe
|
|
3965
3967
|
if("pre-task"===W.status?(pe=[`${W.commitHash}..${B.commitHash}`,"--",$],s.info(`Comparing pre-task commit with final commit: ${W.commitHash?W.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${$}`)):(pe=["4b825dc642cb6eb9a060e54bf8d69288fbee4904.."+B.commitHash,"--",$],s.info(`File created during task, showing full file diff using empty tree object: ${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${$}`)),G=await t.git.diff(pe),V=!!G&&G.trim().length>0,!V&&W.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
|
|
3966
3968
|
try{const me=await t.git.show([`${W.commitHash}:${$}`]),ye=await t.git.show([`${B.commitHash}:${$}`])
|
|
@@ -3968,24 +3970,24 @@ if(me!==ye&&(V=!0,G="Changes detected through direct content comparison (not vis
|
|
|
3968
3970
|
Math.abs(we.length-be.length)>0&&(G+=`\n\nLine count changed: ${we.length} \u2192 ${be.length}`),me.includes("\0")||ye.includes("\0")?G+="\n\nBinary content detected - changes not displayed":me.replace(/\s+/g,"")===ye.replace(/\s+/g,"")&&(G+="\n\nWhitespace-only changes detected")}}catch(ke){s.warn("Error in direct file comparison: "+(ke instanceof Error?ke.message:ke+""))}}s.info(`Diff generation result for ${$}: hasDiff=${V}, length=${G.length}`)}}catch(Ie){if(s.warn("Error getting diff for "+$,{error:(0,u.getErrorMessage)(Ie),firstCommit:z.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),G="Error getting diff: "+(0,u.getErrorMessage)(Ie),"pre-task"!==z.status&&t.git)try{const ve=[`${B.commitHash}:${$}`]
|
|
3969
3971
|
s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${$}`)
|
|
3970
3972
|
const Ce=await t.git.show(ve)
|
|
3971
|
-
if(Ce&&Ce.trim().length>0){if(p){let
|
|
3972
|
-
const
|
|
3973
|
-
for(const qe of _e
|
|
3974
|
-
G=
|
|
3975
|
-
V=!0,s.info("Fallback succeeded, got file content of length "+Ce.length)}}catch(Se){s.warn("Fallback also failed for "+$,{error:Se instanceof Error?Se.message:Se+""})}}
|
|
3976
|
-
w&&"object"==typeof w&&(
|
|
3973
|
+
if(Ce&&Ce.trim().length>0){if(p){let _e=""
|
|
3974
|
+
const Ee=Ce.split("\n")
|
|
3975
|
+
for(const qe of Ee)_e+=`+${qe}\n`
|
|
3976
|
+
G=_e}else G="File created during this task. Content:\n"+Ce
|
|
3977
|
+
V=!0,s.info("Fallback succeeded, got file content of length "+Ce.length)}}catch(Se){s.warn("Fallback also failed for "+$,{error:Se instanceof Error?Se.message:Se+""})}}_.set($,{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($,{firstChange:W,lastChange:B,hasDiff:V,diffText:G})}let E=`# File Changes for Task: ${g}\n\n`
|
|
3978
|
+
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`)
|
|
3977
3979
|
const q=3e3
|
|
3978
3980
|
let S=0,T=!1
|
|
3979
|
-
if(p){for(const Te of
|
|
3980
|
-
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(
|
|
3981
|
-
for(const Pe of I.allMoves)
|
|
3982
|
-
for(const[Re,Me]of
|
|
3981
|
+
if(p){for(const Te of _.values())Te.hasDiff&&Te.diffText&&(S+=Te.diffText.split("\n").length)
|
|
3982
|
+
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`
|
|
3983
|
+
for(const Pe of I.allMoves)E+=`- **${Pe.source}** \u2192 **${Pe.destination}**\n`,E+=` - Operation: ${Pe.type}\n`,E+=` - Timestamp: ${new Date(Pe.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Pe.recordId}\n\n`}E+="## Modified Files\n\n"
|
|
3984
|
+
for(const[Re,Me]of _.entries()){const{normalizedPath:je,fullPath:xe}=d.validateAndNormalizePath(Re,t)
|
|
3983
3985
|
let Oe=!1
|
|
3984
|
-
try{await a.access(xe),Oe=!0}catch{}
|
|
3986
|
+
try{await a.access(xe),Oe=!0}catch{}E+=`### ${Re} ${Oe?"":"(Deleted)"}\n\n`
|
|
3985
3987
|
const Ae=new Date(Me.firstChange.timestamp).toLocaleString(),De=new Date(Me.lastChange.timestamp).toLocaleString()
|
|
3986
|
-
|
|
3988
|
+
E+=`**First Change**: ${Ae}\n`,E+=`**Last Change**: ${De}\n`,"pre-task"===Me.firstChange.status&&Me.firstChange.commitHash?E+=`**Pre-Task Commit**: ${Me.firstChange.commitHash.substring(0,8)}\n`:Me.firstChange.commitHash&&(E+=`**File Created During Task**: ${Me.firstChange.commitHash.substring(0,8)}\n`),Me.lastChange.commitHash&&(E+=`**Final Commit**: ${Me.lastChange.commitHash.substring(0,8)}\n`)
|
|
3987
3989
|
const $e=I.sourceToMove.get(Re),Fe=I.destToMove.get(Re)
|
|
3988
|
-
$e?
|
|
3990
|
+
$e?E+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${$e.destination}**\n`:Fe&&(E+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Fe.source}**\n`),p&&!T?Me.hasDiff?(E+="\n**Changes**:\n",E+="```diff\n",E+=Me.diffText,E+="\n```\n\n"):E+=`\n**Note**: ${Me.diffText}\n\n`:T&&Me.hasDiff?(E+=`\n**Note**: File has changes (${Me.diffText?Me.diffText.split("\n").length:0} lines). `,E+=`Compare ${Me.firstChange.commitHash?Me.firstChange.commitHash.substring(0,8):"unknown"}..${Me.lastChange.commitHash?Me.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Me.hasDiff?E+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":E+=`\n**Note**: ${Me.diffText}\n\n`,E+="---\n\n"}return h({success:!0,fileCount:C.size}),{content:[{type:"text",text:E}]}}catch(Ne){return s.error("Error in task file history tool",{error:Ne instanceof Error?Ne.stack:Ne+""}),h({success:!1,error:Ne instanceof Error?Ne.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,u.getErrorMessage)(Ne)}],isError:!0}}}
|
|
3989
3991
|
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
|
|
3990
3992
|
const r=t(1058)
|
|
3991
3993
|
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)})
|
|
@@ -4091,7 +4093,9 @@ return this.logger.error("Failed to switch to branch",{branchName:e,requestId:t,
|
|
|
4091
4093
|
if(o.success||o.existed)return o
|
|
4092
4094
|
if(n>=t)return o
|
|
4093
4095
|
this.logger.debug("Branch creation failed, retrying",{attempt:n,maxRetries:t,requestId:e.requestId,error:o.error}),await new Promise((e=>setTimeout(e,r*n)))}catch(o){if(n===t)throw o
|
|
4094
|
-
this.logger.debug("Branch creation attempt failed, retrying",{attempt:n,maxRetries:t,requestId:e.requestId,error:(0,a.getErrorMessage)(o)}),await new Promise((e=>setTimeout(e,r*n)))}throw Error("Unexpected end of retry loop")}}exports.SharedBranchManager=c},
|
|
4096
|
+
this.logger.debug("Branch creation attempt failed, retrying",{attempt:n,maxRetries:t,requestId:e.requestId,error:(0,a.getErrorMessage)(o)}),await new Promise((e=>setTimeout(e,r*n)))}throw Error("Unexpected end of retry loop")}}exports.SharedBranchManager=c},7250(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4097
|
+
const r=t(6183),n=t(3707)
|
|
4098
|
+
exports.def={name:"quick_replace",description:"Replace text in files or documents. Wraps the change in a request/task workflow that auto-completes.\n\nProvide an array of operations, each with path/documentId and replacements [{old, new}].\nSupports fuzzy matching (default: true) and match_mode ('unique' or 'all').\n\nRequires: title, description, comment, operations.",schema:r.QuickReplaceSchema,annotations:{title:"Quick Replace",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleQuickChange)(e,"replace",t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},7252(module){module.exports=require("express")},7257(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4095
4099
|
const r=t(6183),n=t(3420)
|
|
4096
4100
|
exports.def={name:"get_task_information",description:"Get detailed information about a specific task.",schema:r.GetTaskInformationSchema,annotations:{title:"Get Task Information",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleGetTaskInformation)(e,t.context,t.apiClient,t.logger,t.metrics)}}},7280(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
4097
4101
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
@@ -4126,15 +4130,15 @@ p.info("Creating request via request client",{projectId:m,title:d.title,type:d.t
|
|
|
4126
4130
|
const I=await y.createRequest(k)
|
|
4127
4131
|
p.debug("Create request response structure",{type:typeof I,isArray:Array.isArray(I),hasData:null!=I,properties:I?Object.keys(I):[],dataPreview:I?JSON.stringify(I).substring(0,200)+"...":"null"})
|
|
4128
4132
|
const v=(0,o.extractDataFromResponse)(I,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
|
|
4129
|
-
let E
|
|
4130
|
-
if(h?.workspaceManager)try{await h.workspaceManager.initializeRequest(C.id,C.title),
|
|
4131
|
-
p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:
|
|
4133
|
+
let _,E={created:!1}
|
|
4134
|
+
if(h?.workspaceManager)try{await h.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},p.info("Request branch initialized successfully",{requestId:C.id,branchName:E.branchName,title:C.title})}catch(e){p.warn("Failed to initialize request branch, will retry on first operation",{requestId:C.id,error:(0,i.getErrorMessage)(e)})}else"quick-edit"===d.type?p.info("Quick-edit request - skipping branch creation, will work directly on main",{requestId:C.id}):p.debug("No workspace manager available, branch creation deferred",{requestId:C.id})
|
|
4135
|
+
p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
|
|
4132
4136
|
try{const e=l.getToolRecordClient()
|
|
4133
|
-
if(e){const t=await e.createToolRecord({requestId:C.id,projectId:m,type:"create-request",metadata:{status:"completed",timestamp:(new Date).toISOString(),requestType:C.type,requestTitle:C.title,requestDescription:C.description,criteriaCount:C.acceptanceCriteria.length,branchCreated:
|
|
4134
|
-
|
|
4137
|
+
if(e){const t=await e.createToolRecord({requestId:C.id,projectId:m,type:"create-request",metadata:{status:"completed",timestamp:(new Date).toISOString(),requestType:C.type,requestTitle:C.title,requestDescription:C.description,criteriaCount:C.acceptanceCriteria.length,branchCreated:E.created,branchName:E.created?E.branchName:null},note:`Created request "${C.title}" of type ${C.type}${E.created?" with branch "+E.branchName:" - branch will be created on first file operation"}`})
|
|
4138
|
+
_=t?.id}}catch(e){p.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:C.id})}f({success:!0,type:d.type,hasProjectId:!0}),p.info("Request created successfully",{requestId:C.id,title:C.title,type:C.type,projectId:m})
|
|
4135
4139
|
const q=C.localId||C.id
|
|
4136
4140
|
let S="pending_approval"===b?`Created Request ${q} (pending approval)`:"Created Request "+q
|
|
4137
|
-
return
|
|
4141
|
+
return _&&(S+=`\n[RECORD:${_}]`),{content:[{type:"text",text:S}]}}catch(r){if(p.error("Failed to create request",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new requests")||r.message.includes("disabled due to tier limits")))p.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
|
|
4138
4142
|
else{const n=l.getToolRecordClient()
|
|
4139
4143
|
n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){p.error("Failed to create failure record for request creation",{error:e instanceof Error?e.message:e+""})}if(f({success:!1,error:r instanceof Error?r.name:"unknown"}),r instanceof s.ZodError&&r.errors.length>0){const e=r.errors[0]
|
|
4140
4144
|
let t=e.message
|
|
@@ -4175,11 +4179,11 @@ v.push({type:"replace-lines",result:e})}if(k.length>0){p.info("Routing delete-st
|
|
|
4175
4179
|
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:k,comment:m+" [via modify-file: delete-string]"},t,r,n,o,p,h,g)
|
|
4176
4180
|
v.push({type:"delete-string",result:e})}if(I.length>0){p.info("Processing delete-lines operations",{operationCount:I.length})
|
|
4177
4181
|
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)
|
|
4178
|
-
v.push({type:"delete-lines",result:s})}const C=v.some((e=>e.result.isError)),
|
|
4182
|
+
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
|
|
4179
4183
|
let q="## Modify File Results\n\n"
|
|
4180
|
-
q+="**Summary:**\n",q+=`- **Total operation types:** ${v.length}\n`,q+=`- **Successful:** ${
|
|
4184
|
+
q+="**Summary:**\n",q+=`- **Total operation types:** ${v.length}\n`,q+=`- **Successful:** ${_}\n`,q+=`- **Failed:** ${E}\n\n`
|
|
4181
4185
|
for(const{type:e,result:t}of v)q+=`### ${e} operations\n`,q+=t.content[0].text+"\n\n"
|
|
4182
|
-
return p.info("Modify-file operations completed",{totalOperationTypes:v.length,successCount:
|
|
4186
|
+
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}}}
|
|
4183
4187
|
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")
|
|
4184
4188
|
try{const o=(await e.status()).current
|
|
4185
4189
|
if(!o)throw new g.ValidationError("Repository is in detached HEAD state or branch detection failed")
|
|
@@ -4575,11 +4579,11 @@ C.push({type:"move-files",result:e})}if(I.length>0){m.info("Routing to delete-fi
|
|
|
4575
4579
|
const e=await(0,u.handleDeleteFiles)({taskId:g,operations:I,comment:w+" [via manage-files: delete-files]"},t,s,m,p,f)
|
|
4576
4580
|
C.push({type:"delete-files",result:e})}for(const e of v){m.info("Routing to get-file-info handler",{path:e.path})
|
|
4577
4581
|
const r=await(0,d.handleGetFileInfo)({path:e.path},t,m,p)
|
|
4578
|
-
C.push({type:"get-file-info",result:r})}const
|
|
4582
|
+
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
|
|
4579
4583
|
let S="## Manage Files Results\n\n"
|
|
4580
|
-
S+="**Summary:**\n",S+=`- **Total operation types:** ${C.length}\n`,S+=`- **Successful:** ${
|
|
4584
|
+
S+="**Summary:**\n",S+=`- **Total operation types:** ${C.length}\n`,S+=`- **Successful:** ${E}\n`,S+=`- **Failed:** ${q}\n\n`
|
|
4581
4585
|
for(const{type:e,result:t}of C)S+=`### ${e} operations\n`,S+=t.content[0].text+"\n\n"
|
|
4582
|
-
return m.info("Manage-files operations completed",{totalOperationTypes:C.length,successCount:
|
|
4586
|
+
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}}}
|
|
4583
4587
|
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
|
|
4584
4588
|
const r=t(6183),n=t(5303)
|
|
4585
4589
|
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
|
|
@@ -4692,20 +4696,13 @@ l.info("=== AFTER EXTRACTION ===",{extractedCount:p.length,firstItemAfterExtract
|
|
|
4692
4696
|
const f=t.multiAgentMode||!1
|
|
4693
4697
|
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."}]}
|
|
4694
4698
|
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)})}))
|
|
4695
|
-
const m=p.map((e=>{
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
case"quick-edit":return"\u26a1"
|
|
4701
|
-
default:return"\u{1f4c4}"}}(e.type)
|
|
4702
|
-
let n=""
|
|
4703
|
-
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:t}=(0,o.getGlobalClientInfo)(),r=e.lockInfo.lockedBySessionTag||"unknown"
|
|
4704
|
-
n=r===t?" \u{1f512} Locked by me, expires in "+e.lockInfo.timeRemainingFormatted:` \u{1f512} ${r.length>20?r.substring(0,17)+"...":r}, expires in ${e.lockInfo.timeRemainingFormatted}`}else n=" \u{1f513} Available"
|
|
4705
|
-
l.debug(`Generated lock info for ${e.id}: "${n}"`)}else l.debug("No lock info available for "+e.id)
|
|
4706
|
-
return`**${r} ${e.title}** (${e.id})${n}\nStatus: ${t} ${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))
|
|
4699
|
+
const m=p.map((e=>{let t=""
|
|
4700
|
+
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"
|
|
4701
|
+
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]"
|
|
4702
|
+
l.debug(`Generated lock info for ${e.id}: "${t}"`)}else l.debug("No lock info available for "+e.id)
|
|
4703
|
+
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))
|
|
4707
4704
|
let w=`Found ${p.length} request${1===p.length?"":"s"}:`
|
|
4708
|
-
return y&&f&&(w+="\n\n**Lock Status
|
|
4705
|
+
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}}}
|
|
4709
4706
|
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
|
|
4710
4707
|
const r=t(6183),n=t(7456)
|
|
4711
4708
|
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)}}},8156(e,exports,t){var r=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
@@ -4732,7 +4729,8 @@ var h=t(3884)
|
|
|
4732
4729
|
Object.defineProperty(exports,"middleware",{enumerable:!0,get(){return h.middleware}}),Object.defineProperty(exports,"requestLogger",{enumerable:!0,get(){return h.requestLogger}}),Object.defineProperty(exports,"errorHandler",{enumerable:!0,get(){return h.errorHandler}}),Object.defineProperty(exports,"authenticate",{enumerable:!0,get(){return h.authenticate}}),Object.defineProperty(exports,"validateRequest",{enumerable:!0,get(){return h.validateRequest}}),Object.defineProperty(exports,"corsOptions",{enumerable:!0,get(){return h.corsOptions}})
|
|
4733
4730
|
var g=t(7888)
|
|
4734
4731
|
Object.defineProperty(exports,"addConnectionStatusInfo",{enumerable:!0,get(){return g.addConnectionStatusInfo}}),t(3611),t(6552),t(1791),t(1152),t(3328),t(3884),t(6800),t(9955),t(2568),t(3102),t(8625),t(184),t(1472),t(1213),n(t(3444),exports),n(t(3227),exports),n(t(9914),exports),n(t(4055),exports),n(t(9860),exports),n(t(3611),exports),n(t(6552),exports)},8291(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4735
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.validateArgs=function(e,t){
|
|
4732
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.validateArgs=function(e,t){if(e&&"object"==typeof e)for(const t of Object.keys(e)){const r=e[t]
|
|
4733
|
+
if("string"==typeof r&&(r.startsWith("[")||r.startsWith("{")))try{e[t]=JSON.parse(r)}catch{}}try{return t.parse(e)}catch(e){if(e instanceof o.z.ZodError){const t=e.issues.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")
|
|
4736
4734
|
throw(0,s.createValidationError)("Invalid arguments: "+t)}throw e}},exports.validateAndNormalizePath=function(e,t){let r=e.replace(/\\/g,"/")
|
|
4737
4735
|
const o=function(e){return e.workspaceManager?e.workspaceManager.getCurrentContext().basePath:e.basePath}(t)
|
|
4738
4736
|
if(n.default.isAbsolute(r)){const e=n.default.normalize(r)
|
|
@@ -4761,13 +4759,13 @@ try{const s=d.validateArgs(e,l.CreateDirectorySchema),{taskId:u,path:h,comment:g
|
|
|
4761
4759
|
f.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,f,i,k.metricsPrefix),t.getCurrentBranchContext&&await t.getCurrentBranchContext()
|
|
4762
4760
|
const{normalizedPath:I,fullPath:v}=d.validateAndNormalizePath(h,t)
|
|
4763
4761
|
b=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4764
|
-
const C=await d.validateTaskId(u,I,r,f,i,k.metricsPrefix),
|
|
4765
|
-
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 ${
|
|
4766
|
-
const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:
|
|
4762
|
+
const C=await d.validateTaskId(u,I,r,f,i,k.metricsPrefix),_=C?.requestId,E=await d.validateWorkItemStates(u,I,r,o,t,f,i,k.metricsPrefix),q=await d.autoPromoteTaskStatus(u,C.status,_,E.request?.status,I,r,o,f,i,k.metricsPrefix)
|
|
4763
|
+
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})
|
|
4764
|
+
const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:f,metrics:i,metricsPrefix:k.metricsPrefix})
|
|
4767
4765
|
if(!S.success){if(S.isLockConflict)return{content:[{type:"text",text:"\u274c "+S.error}],isError:!0}
|
|
4768
4766
|
throw Error(S.error)}let T=!1
|
|
4769
4767
|
try{T=(await a.default.stat(v)).isDirectory()}catch{T=!1}b=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4770
|
-
const{toolRecordId:P,localToolRecordId:R}=await d.createFileOperationRecords(u,
|
|
4768
|
+
const{toolRecordId:P,localToolRecordId:R}=await d.createFileOperationRecords(u,_,t.projectId,k.recordType,I,{directoryExists:T,userComment:g},r,n,f,i,k.metricsPrefix,p)
|
|
4771
4769
|
y=P,w=P,b=k.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4772
4770
|
let M=T
|
|
4773
4771
|
if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+I)
|
|
@@ -5043,7 +5041,7 @@ t.info("Fetching available agents from API")
|
|
|
5043
5041
|
const r=await e.proxyGet("/api/agents/templates")
|
|
5044
5042
|
r&&Array.isArray(r)&&r.length>0?(s=r.map((e=>({id:e.id||e.name,name:e.name,description:e.description,mode:e.mode,builtIn:e.builtIn}))),t.info("Agent registry initialized",{agentCount:s.length})):(t.warn("No agents returned from API, using defaults"),s=n),i=!0}catch(e){t.warn("Failed to fetch agents from API, using defaults",{error:e instanceof Error?e.message:e+""}),s=n,i=!0}})(),a)},exports.getAvailableAgents=t,exports.getAgentNames=r,exports.isValidAgent=function(e){return r().includes(e)},exports.getDefaultAgent=function(){return"work"},exports.formatAgentsForDescription=function(){return t().map((e=>`'${e.name}'${e.description?" - "+e.description:""}`)).join(", ")},exports.isAgentRegistryInitialized=function(){return i},exports.getBuiltInAgentConfig=function(e){const t=n.find((t=>t.name===e))
|
|
5045
5043
|
return t?{preferredProvider:t.preferredProvider||"inherit",preferredModelTier:t.preferredModelTier||"same",requestContextMode:t.requestContextMode}:null},exports.getAllowedSubagents=function(e){return o[e]||null},exports.resetAgentRegistry=function(){s=null,i=!1,a=null}
|
|
5046
|
-
const n=[{id:"coder",name:"coder",description:"Development and implementation agent",builtIn:!0,preferredModelTier:"same",requestContextMode:"required"},{id:"research",name:"research",description:"Codebase research and exploration agent",builtIn:!0,preferredModelTier:"two_down",requestContextMode:"none"},{id:"
|
|
5044
|
+
const n=[{id:"coder",name:"coder",description:"Development and implementation agent",builtIn:!0,preferredModelTier:"same",requestContextMode:"required"},{id:"research",name:"research",description:"Codebase research and exploration agent",builtIn:!0,preferredModelTier:"two_down",requestContextMode:"none"},{id:"journal",name:"journal",description:"Journal generation agent",builtIn:!0,preferredModelTier:"one_down"},{id:"planner",name:"planner",description:"Planning and architecture agent",builtIn:!0,preferredModelTier:"same"},{id:"specialist",name:"specialist",description:"Domain specialist for development tasks",builtIn:!0,preferredModelTier:"same"},{id:"auto-planner",name:"auto-planner",description:"Autonomous background planner",builtIn:!0,preferredModelTier:"same"},{id:"alchemist",name:"alchemist",description:"Persistent orchestrator",builtIn:!0,preferredModelTier:"same"}],o={alchemist:["specialist","research","planner"],specialist:["coder","research","auto-planner","planner"],tester:["research"],"auto-tester":["research"]}
|
|
5047
5045
|
let s=null,i=!1,a=null},9013(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.BranchGitAdapter=void 0
|
|
5048
5046
|
const r=t(7225),n=t(7075),o=t(7478),s=t(8824)
|
|
5049
5047
|
exports.BranchGitAdapter=class{constructor(e,t,n,o,s){this.basePath=e,this.git=t,this.conflictDetector=n,this.logger=o,this.metrics=s,this.mode="single-agent",this.currentRequestId=null,this.currentBranch="main",this.branchManager=(0,r.createSharedBranchManager)(t,o,s)}async setupWorkspace(e){const t=Date.now()
|
|
@@ -5098,7 +5096,7 @@ exports.def={name:"write_file",description:"Write content to files or documents.
|
|
|
5098
5096
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConfigManager=void 0,exports.createConfigManager=function(e){return new d(e)}
|
|
5099
5097
|
const n=r(t(1943)),o=r(t(6928)),s=r(t(857)),i=t(4139),a=t(8824),c={multiAgent:!1,lockOverride:{enabled:!0,passwordValidityMinutes:5}},l={remoteServerUrl:"https://api.alchemylabcode.com",nodePath:"node"}
|
|
5100
5098
|
class d{constructor(e){this.logger=e.child({component:"config-manager"}),this.installationConfigDir=this.getInstallationConfigDir()}getInstallationConfigDir(){const e=__dirname||process.cwd(),t=s.default.homedir()
|
|
5101
|
-
return e.includes("node_modules")?o.default.join(t,".
|
|
5099
|
+
return e.includes("node_modules")?o.default.join(t,".alchemy_lab","config"):o.default.join(t,".alchemy_lab","config-dev")}async ensureDirectory(e){try{await n.default.access(e)}catch(t){await n.default.mkdir(e,{recursive:!0}),this.logger.debug("Created directory",{dirPath:e})}}async readConfig(e,t){try{const r=await n.default.readFile(e,"utf8"),o=JSON.parse(r)
|
|
5102
5100
|
return{...t,...o}}catch(r){return"ENOENT"===r.code||this.logger.warn("Error reading config file, using defaults",{filePath:e,error:(0,a.getErrorMessage)(r)}),t}}async writeConfig(e,t){await this.ensureDirectory(o.default.dirname(e)),await n.default.writeFile(e,JSON.stringify(t,null,2),"utf8"),this.logger.debug("Wrote config file",{filePath:e})}async getProjectConfig(e){const t=o.default.join(e,i.ALCHEMY_DIR_NAME,"config.json")
|
|
5103
5101
|
return this.readConfig(t,c)}async updateProjectConfig(e,t){const r=o.default.join(e,i.ALCHEMY_DIR_NAME,"config.json"),n={...await this.getProjectConfig(e),...t}
|
|
5104
5102
|
await this.writeConfig(r,n),this.logger.info("Updated project config",{projectPath:e,updates:t})}async getProjectMetadata(e){const t=o.default.join(e,i.ALCHEMY_DIR_NAME,"project.json")
|
|
@@ -5110,10 +5108,10 @@ return{remoteServerUrl:n.remoteServerUrl||l.remoteServerUrl,nodePath:n.nodePath|
|
|
|
5110
5108
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ExternalAuthFlow=exports.PollingStatus=void 0
|
|
5111
5109
|
const n=r(t(6982)),o=t(8824)
|
|
5112
5110
|
var s
|
|
5113
|
-
!function(e){e.NOT_STARTED="not_started",e.POLLING="polling",e.AUTHENTICATED="authenticated",e.TIMEOUT="timeout",e.ERROR="error"}(s||(exports.PollingStatus=s={})),exports.ExternalAuthFlow=class{constructor(e,t,r=5e3,n=9e5){this.pollingStatus=s.NOT_STARTED,this.pollingStartTime=0,this.pollingIntervalId=null,this.tokenResult=null,this.pollingError=null,this.logger=e.child({component:"auth-flow"}),this.remoteServerUrl=t,this.pollingIntervalMs=r,this.maxPollingTimeMs=n}getAuthUrl(e){let
|
|
5114
|
-
|
|
5115
|
-
const
|
|
5116
|
-
return this.logger.info("Generated auth URL",{url:
|
|
5111
|
+
!function(e){e.NOT_STARTED="not_started",e.POLLING="polling",e.AUTHENTICATED="authenticated",e.TIMEOUT="timeout",e.ERROR="error"}(s||(exports.PollingStatus=s={})),exports.ExternalAuthFlow=class{constructor(e,t,r=5e3,n=9e5){this.pollingStatus=s.NOT_STARTED,this.pollingStartTime=0,this.pollingIntervalId=null,this.tokenResult=null,this.pollingError=null,this.logger=e.child({component:"auth-flow"}),this.remoteServerUrl=t,this.pollingIntervalMs=r,this.maxPollingTimeMs=n}getAuthUrl(e){let r=this.remoteServerUrl
|
|
5112
|
+
r=r.includes("api.alchemylabcode.com")?r.replace("api.alchemylabcode.com","alchemylabcode.com"):r.match(/localhost:\d+/)?r.replace(/localhost:\d+/,"localhost:3000"):r.replace(/\/\/api\./g,"//")
|
|
5113
|
+
const n=t(6928).basename(process.cwd()),o=`${r}/login?mcp_code=${e}&project=${encodeURIComponent(n)}`
|
|
5114
|
+
return this.logger.info("Generated auth URL",{url:o,frontendUrl:r,backendUrl:this.remoteServerUrl}),o}getPollingUrl(e){const t=`${this.remoteServerUrl}/auth/check-auth?code=${e}`
|
|
5117
5115
|
return this.logger.info("Generated polling URL",{url:t}),t}async requestTemporaryCode(){const e=this.remoteServerUrl+"/auth/generate-code"
|
|
5118
5116
|
this.logger.info("Requesting temporary code from remote server",{url:e})
|
|
5119
5117
|
try{const t=await fetch(e)
|
|
@@ -5336,23 +5334,23 @@ o+="## Test 3: Recent merge commits (to see actual patterns)\n",o+=`Found ${e?.a
|
|
|
5336
5334
|
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"])
|
|
5337
5335
|
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()
|
|
5338
5336
|
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}}}
|
|
5339
|
-
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:
|
|
5337
|
+
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"}}
|
|
5340
5338
|
try{let t,o
|
|
5341
|
-
if(
|
|
5342
|
-
const e=n.documentFileManager.getCachedDocumentInfo(
|
|
5343
|
-
|
|
5344
|
-
o=e.normalizedPath,t=e.fullPath,
|
|
5345
|
-
for(const t of
|
|
5346
|
-
try{if(n===o){a.error="No-op replacement (old and new values are identical)",a.success=!1,a.matchesFound=0,
|
|
5347
|
-
continue}const t=(0,
|
|
5348
|
-
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(
|
|
5349
|
-
const e=(0,
|
|
5350
|
-
e.length>0&&(a.similarMatches=e),
|
|
5351
|
-
const
|
|
5352
|
-
for(const e of
|
|
5353
|
-
|
|
5354
|
-
for(const{match:e,newText:t,repResult:n}of
|
|
5355
|
-
|
|
5339
|
+
if(f){t=await n.documentFileManager.getDocumentAsFile(d)
|
|
5340
|
+
const e=n.documentFileManager.getCachedDocumentInfo(d)
|
|
5341
|
+
y.filename=e?.filename,o="document:"+d}else{const e=u.validateAndNormalizePath(c,n)
|
|
5342
|
+
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),p=[]
|
|
5343
|
+
for(const t of g){const{old:n,new:o,match_mode:i="unique"}=t,a={old:n,new:o,success:!1}
|
|
5344
|
+
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)
|
|
5345
|
+
continue}const t=(0,h.findMatches)(s,n,m,100,e.path)
|
|
5346
|
+
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(m?" (tried fuzzy matching)":""),a.success=!1
|
|
5347
|
+
const e=(0,h.findSimilarMatches)(s,n,5,.3)
|
|
5348
|
+
e.length>0&&(a.similarMatches=e),y.failedReplacements++}else"unique"===i&&t.length>1?(a.error=`Multiple matches found (${t.length}) - expected unique match`,a.success=!1,a.details=t.map(r),y.failedReplacements++):p.push({matches:t,newText:o,matchMode:i,repResult:a})}catch(e){a.error=(0,b.getErrorMessage)(e),a.success=!1,y.failedReplacements++}y.replacements.push(a)}let w=s
|
|
5349
|
+
const k=[]
|
|
5350
|
+
for(const e of p)for(const t of e.matches)k.push({match:t,newText:e.newText,repResult:e.repResult})
|
|
5351
|
+
k.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5352
|
+
for(const{match:e,newText:t,repResult:n}of k)w=(0,h.replaceMatch)(w,e,t),n.success?(n.lines.push(e.line),n.details.push(r(e))):(n.success=!0,n.matchType=e.matchType,n.lines=[e.line],n.details=[r(e)],y.successfulReplacements++)
|
|
5353
|
+
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),f&&(n.documentFileManager.markForSync(d),await n.documentFileManager.syncDocument(d))),i&&(y.externalEditWarning=i),a&&(y.externalEditDebugInfo={detectionRan:!0,...a}),y.success=0===y.failedReplacements}catch(e){y.error=(0,b.getErrorMessage)(e),y.success=!1,y.failedReplacements=g.length,y.replacements=g.map((e=>({old:e.old,new:e.new,success:!1,error:y.error})))}return y}var o,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
5356
5354
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5357
5355
|
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=[]
|
|
5358
5356
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -5360,61 +5358,62 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
5360
5358
|
var t={}
|
|
5361
5359
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
5362
5360
|
return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
5363
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFiles=async function(e,t,r,o,s,i,a,c){const
|
|
5364
|
-
let v,C=
|
|
5365
|
-
try{const
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5361
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFiles=async function(e,t,r,o,s,i,a,c){const k=i.child({tool:"replace_in_files"}),I=Date.now()
|
|
5362
|
+
let v,C=u.FileOperationPhase.VALIDATION
|
|
5363
|
+
try{if(e&&Array.isArray(e.operations))for(const t of e.operations)t.old&&t.new&&!t.replacements&&(t.replacements=[{old:t.old,new:t.new,match_mode:t.match_mode}],delete t.old,delete t.new,delete t.match_mode)
|
|
5364
|
+
const i=u.validateArgs(e,d.ReplaceInFilesSchema),{taskId:_,operations:E,fuzzy_match:q=!0,comment:S}=i
|
|
5365
|
+
k.info("Replace in files batch operation",{taskId:_,operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,comment:S})
|
|
5366
|
+
const T=E.filter((e=>e.documentId)).map((e=>e.documentId))
|
|
5367
|
+
if(T.length>0&&t.apiClient)try{await(0,m.ensureDocumentsNotLocked)(T,t.apiClient,k,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5368
|
+
throw e}C=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5369
|
+
const P=E[0],R=P.documentId?"document:"+P.documentId:P.path
|
|
5371
5370
|
let M=Date.now()
|
|
5372
|
-
const j=await
|
|
5371
|
+
const j=await u.validateTaskId(_,R,r,k,a,"replace_in_files")
|
|
5373
5372
|
Date.now()
|
|
5374
|
-
const x=j?.requestId,O=
|
|
5373
|
+
const x=j?.requestId,O=E.some((e=>e.path))
|
|
5375
5374
|
let A=!1
|
|
5376
5375
|
if(O&&x){M=Date.now()
|
|
5377
|
-
const e=await
|
|
5376
|
+
const e=await u.validateWorkItemStates(_,R,r,s,t,k,a,"replace_in_files")
|
|
5378
5377
|
Date.now(),M=Date.now()
|
|
5379
|
-
const n=await
|
|
5380
|
-
n.taskPromoted&&
|
|
5381
|
-
const o=await
|
|
5378
|
+
const n=await u.autoPromoteTaskStatus(_,j.status,x,e.request?.status,R,r,s,k,a,"replace_in_files")
|
|
5379
|
+
n.taskPromoted&&k.info("Auto-promoted task to in_progress",{taskId:_,requestId:x,previousStatus:j.status,newStatus:n.newTaskStatus}),Date.now(),M=Date.now()
|
|
5380
|
+
const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:x,context:t,operation:"replace_in_files",logger:k,metrics:a,metricsPrefix:"replace_in_files"})
|
|
5382
5381
|
if(!o.success){if(o.isLockConflict)return{content:[{type:"text",text:"\u274c "+o.error}],isError:!0}
|
|
5383
|
-
throw Error(o.error)}Date.now(),A=!0}if(T.length>0&&x)try{await(0,
|
|
5382
|
+
throw Error(o.error)}Date.now(),A=!0}if(T.length>0&&x)try{await(0,p.validateRequestStatusForDocumentOperation)(x,s,k,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5384
5383
|
throw e}M=Date.now()
|
|
5385
5384
|
const D=new Map
|
|
5386
|
-
if(
|
|
5387
|
-
for(const t of e.replacements){const r=(0,
|
|
5388
|
-
s.push(...r)}if(s.length>0){const o=(0,
|
|
5389
|
-
|
|
5390
|
-
const i=await(0,
|
|
5391
|
-
|
|
5392
|
-
const e=await(0,
|
|
5393
|
-
e.userChangesCommitted&&(
|
|
5394
|
-
const{toolRecordId:$}=await
|
|
5395
|
-
v=$,Date.now(),M=Date.now(),C=
|
|
5385
|
+
if(k.info("\u{1f50d} Starting external edit detection",{hasFileOperations:O,hasGit:!!t.git,operationCount:E.length}),O&&t.git)for(const e of E)if(e.path&&!e.documentId)try{const r=u.validateAndNormalizePath(e.path,t),n=await l.default.readFile(r.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:q,s=[]
|
|
5386
|
+
for(const t of e.replacements){const r=(0,h.findMatches)(n,t.old,o,100,e.path)
|
|
5387
|
+
s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,r.fullPath)
|
|
5388
|
+
k.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
|
|
5389
|
+
const i=await(0,w.detectExternalEdits)(t.git,o,k)
|
|
5390
|
+
k.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}),k.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}),k.info("\u2705 No external edit conflicts detected",{path:r.normalizedPath}))}else k.info("\u2139\ufe0f No matches found for external edit detection",{path:r.normalizedPath}),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){k.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,b.getErrorMessage)(t)})}if(Date.now(),M=Date.now(),O&&t.git)try{k.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
|
|
5391
|
+
const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},k,a)
|
|
5392
|
+
e.userChangesCommitted&&(k.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),k.info("User changes committed before batch operation",{taskId:_,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){k.warn("Pre-tool user changes commit failed",{taskId:_,error:e instanceof Error?e.message:e+""})}Date.now(),M=Date.now(),C=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5393
|
+
const{toolRecordId:$}=await u.createFileOperationRecords(_,x,t.projectId,"replace-in-files",R,{operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,userComment:S},r,o,k,a,"replace_in_files",c)
|
|
5394
|
+
v=$,Date.now(),M=Date.now(),C=u.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5396
5395
|
const F=[],N=[]
|
|
5397
|
-
for(const e of
|
|
5396
|
+
for(const e of E){const r=e.path?D.get(e.path):void 0,o=await n(e,q,t,0,0,r?.message,r?.debugInfo)
|
|
5398
5397
|
F.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&N.push(o.path)}Date.now(),M=Date.now()
|
|
5399
|
-
const L=
|
|
5398
|
+
const L=E.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),z=await u.handleMultiFileGitCommit(_,L,F,N.length,{operationType:"Replace in files",toolRecordId:$||v||"unknown",successField:"successfulReplacements",logger:k,metrics:a,metricsPrefix:"replace_in_files"},t),B=z.commitHash
|
|
5400
5399
|
Date.now(),Date.now()
|
|
5401
5400
|
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})))
|
|
5402
|
-
await o.updateToolRecord(v,{metadata:{path:R,status:0===U?"completed":"partial",operationCount:
|
|
5401
|
+
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}}})
|
|
5403
5402
|
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
|
|
5404
5403
|
let l="## Replace In Files - Batch Results\n\n"
|
|
5405
5404
|
if(o.getCurrentBranchContext)try{const e=await o.getCurrentBranchContext()
|
|
5406
5405
|
e.branch&&(l+=`**Current Branch:** ${e.branch}\n\n`)}catch(e){}l+="**Summary:**\n",l+=`- **Files/Documents:** ${e.length} total`,l+=c>0?` (\u2705 ${i} fully succeeded, \u26a0\ufe0f ${c} partial, \u274c ${a-c} failed)\n`:` (\u2705 ${i} successful, \u274c ${a} failed)\n`,l+=`- **Replacements:** ${r+n} total (\u2705 ${r} successful, \u274c ${n} failed)\n`,t&&(l+=`- **Git Commit:** ${t.substring(0,8)}\n`),s&&(l+=`[RECORD:${s}]\n`),l+="\n---\n\n"
|
|
5407
5406
|
for(let t=0;t<e.length;t++){const r=e[t],n="document"===r.type?""+(r.filename||r.documentId):r.path
|
|
5408
|
-
l+=`### ${"document"===r.type?"
|
|
5407
|
+
l+=`### ${"document"===r.type?"DOC":"FILE"} ${n}\n\n`,r.error?(l+="- **Status:** \u274c Failed\n",l+="- **File Modified:** No\n",l+=`- **Error:** ${r.error}\n\n`):r.success?(l+="- **Status:** \u2705 Success\n",l+="- **File Modified:** Yes\n",l+=`- **Replacements:** ${r.successfulReplacements} successful\n`):(r.successfulReplacements>0?(l+="- **Status:** \u26a0\ufe0f Partial Success\n",l+="- **File Modified:** Yes (partial changes applied)\n"):(l+="- **Status:** \u274c Failed\n",l+="- **File Modified:** No\n"),l+=`- **Replacements:** ${r.successfulReplacements} successful, ${r.failedReplacements} failed\n`),r.externalEditWarning&&(l+=`\n${r.externalEditWarning}\n`)
|
|
5409
5408
|
const o=r.replacements.filter((e=>e.success))
|
|
5410
5409
|
if(o.length>0){l+="\n**Successful Replacements:**\n"
|
|
5411
5410
|
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))
|
|
5412
5411
|
if(s.length>0){l+="\n**Failed Replacement Details:**\n"
|
|
5413
|
-
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+="
|
|
5414
|
-
return d.length>0&&(l+=`\n
|
|
5412
|
+
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)))
|
|
5413
|
+
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)
|
|
5415
5414
|
return{content:[{type:"text",text:Y}],isError:0===W}}catch(e){const t=Date.now()-I
|
|
5416
|
-
if(
|
|
5417
|
-
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982))
|
|
5415
|
+
if(k.error("Replace in files batch operation failed",{error:e instanceof Error?e.stack:e+"",duration:t,phase:C}),v)try{await o.updateToolRecord(v,{metadata:{status:"failed",error:(0,b.getErrorMessage)(e),phase:C,duration:t}})}catch(e){}return a.incrementCounter("replace_in_files_errors",1,{phase:C}),{content:[{type:"text",text:"\u274c **Replace In Files Failed:** "+(0,b.getErrorMessage)(e)}],isError:!0}}}
|
|
5416
|
+
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(6183)),u=a(t(5967)),h=t(3626),g=t(9860),p=t(5003),f=t(7478),m=t(9949),y=t(9947),w=t(1318),b=t(8824)},9470(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
|
|
5418
5417
|
const t=e.trim()
|
|
5419
5418
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|
|
5420
5419
|
if(2!==r.length)throw Error(`Invalid line range format: "${e}". Expected format: "start-end" (e.g., "5-15")`)
|
|
@@ -5433,13 +5432,13 @@ if(1>r)throw Error(`Invalid line number: ${r}. Line numbers must be >= 1`)
|
|
|
5433
5432
|
return r},exports.extractLines=function(e,t){const r=e.split("\n"),n=r.length
|
|
5434
5433
|
if(!t)return{text:e,startLine:1,endLine:n}
|
|
5435
5434
|
if("number"==typeof t){const e=t-1
|
|
5436
|
-
if(0>e||e>=n)throw Error(`Line number ${t} is out of range
|
|
5435
|
+
if(0>e||e>=n)throw Error(`Line number ${t} is out of range. Valid range: 1-${n}`)
|
|
5437
5436
|
return{text:r[e],startLine:t,endLine:t}}if(Array.isArray(t)){const e=[],o=[...t].sort(((e,t)=>e-t))
|
|
5438
5437
|
let s=1/0,i=-1/0
|
|
5439
5438
|
for(const t of o){const o=t-1
|
|
5440
|
-
o>=0&&n>o&&(e.push(`${t}: ${r[o]}`),s=Math.min(s,t),i=Math.max(i,t))}if(0===e.length)throw Error(
|
|
5439
|
+
o>=0&&n>o&&(e.push(`${t}: ${r[o]}`),s=Math.min(s,t),i=Math.max(i,t))}if(0===e.length)throw Error("None of the specified line numbers are within range. Valid range: 1-"+n)
|
|
5441
5440
|
return{text:e.join("\n"),startLine:s===1/0?1:s,endLine:i===-1/0?n:i}}const o=t.start||1,s=Math.min(t.end||n,n)
|
|
5442
|
-
if(o>s||o>n||1>s)throw Error(`Invalid line range: ${o}-${s}
|
|
5441
|
+
if(o>s||o>n||1>s)throw Error(`Invalid line range: ${o}-${s}. Valid range: 1-${n}`)
|
|
5443
5442
|
const i=Math.max(0,o-1),a=Math.min(n-1,s-1)
|
|
5444
5443
|
return{text:r.slice(i,a+1).join("\n"),startLine:o,endLine:s}}},9499(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
5445
5444
|
const r=t(6183),n=t(6486)
|