alchemylab 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/939.js +1 -1
- package/dist/cli.js +734 -671
- package/dist/http-server.js +196 -213
- package/dist/index.js +543 -560
- package/dist/mcp-direct.js +751 -768
- package/dist/plugins/hooks/plugin.js +63 -14
- package/package.json +2 -2
- package/dist/plugins/anthropic-auth.js +0 -399
- package/dist/plugins/auto-journal.js +0 -83
- package/dist/plugins/hooks/condition-evaluator.js +0 -109
- package/dist/plugins/hooks/dedup-utils.js +0 -66
- package/dist/plugins/hooks/hook-utils.js +0 -85
- package/dist/plugins/notify-parent.js +0 -95
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ u.info("Using project ID from context",{projectId:l}),c.incrementCounter("create
|
|
|
12
12
|
try{const e=i.getRequestClient(),t=await e.getRequest(a.requestId)
|
|
13
13
|
u.info("Raw request verification response data",{responseData:JSON.stringify(t)})
|
|
14
14
|
const r=(0,o.extractDataFromResponse)(t,{logger:u,operationName:"verifyRequestExists",throwOnNoData:!0})
|
|
15
|
-
g="object"==typeof r&&null!==r&&"data"in r?r.data:r,u.info(`Verified request ${a.requestId} exists`,{requestId:a.requestId,projectId:l,requestStatus:g.status})}catch(e){throw new n.NotFoundError(`Request ${a.requestId} not found in project ${l}. Please provide a valid request ID.`,{requestId:a.requestId,projectId:l,originalError:e})}if("pending_approval"
|
|
15
|
+
g="object"==typeof r&&null!==r&&"data"in r?r.data:r,u.info(`Verified request ${a.requestId} exists`,{requestId:a.requestId,projectId:l,requestStatus:g.status})}catch(e){throw new n.NotFoundError(`Request ${a.requestId} not found in project ${l}. Please provide a valid request ID.`,{requestId:a.requestId,projectId:l,originalError:e})}if(["pending_approval","completed","canceled","ready_for_review","ready_for_merge","reverted"].includes(g.status)){const e={pending_approval:"is pending approval. Approve the request before creating tasks.",completed:"is already completed and merged. Create a new request for additional changes.",canceled:"was canceled. Create a new request or reopen this one if needed.",ready_for_review:"is being tested. Wait for test results before making changes.",ready_for_merge:"is ready to merge. Call merge to complete it.",reverted:"was reverted and cannot accept new tasks. Re-complete the request first or create a new request."}[g.status]||`has status '${g.status}' and cannot accept new tasks.`
|
|
16
16
|
throw u.warn(`Task creation blocked on ${g.status} request`,{requestId:a.requestId,requestStatus:g.status,projectId:l}),new n.ValidationError(`The request ID "${a.requestId}" ${e}`,{requestId:a.requestId,requestStatus:g.status,reason:"request_"+g.status})}u.info("Request status validation passed for "+a.requestId,{requestId:a.requestId,requestStatus:g.status,projectId:l})
|
|
17
17
|
const p=i.getTaskClient()
|
|
18
18
|
u.info("Creating task with project context",{projectId:l})
|
|
@@ -20,22 +20,22 @@ const f={requestId:a.requestId,projectId:l,title:a.title,description:a.descripti
|
|
|
20
20
|
u.info("Task input prepared",{taskInput:JSON.stringify(f)}),u.info("Creating task via task client",{projectId:l,requestId:a.requestId,title:a.title})
|
|
21
21
|
const m=await p.createTask(f)
|
|
22
22
|
u.debug("Task creation response structure",{type:typeof m,isArray:Array.isArray(m),hasData:null!=m,properties:m?Object.keys(m):[],dataPreview:m?JSON.stringify(m).substring(0,200)+"...":"null"})
|
|
23
|
-
const y=(0,o.extractDataFromResponse)(m,{logger:u,operationName:"createTask",defaultValue:{id:"tas"+Date.now().toString().substring(5,11),title:f.title,description:f.description,status:"pending",requestId:f.requestId,projectId:l,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}),w="data"in y?y.data:y,b=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),
|
|
23
|
+
const y=(0,o.extractDataFromResponse)(m,{logger:u,operationName:"createTask",defaultValue:{id:"tas"+Date.now().toString().substring(5,11),title:f.title,description:f.description,status:"pending",requestId:f.requestId,projectId:l,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}),w="data"in y?y.data:y,b=w.localId||w.id||"tas"+Date.now().toString().substring(5,11),I=w.title||f.title,k=w.description||f.description,v=w.status||"pending",C=w.requestId||f.requestId
|
|
24
24
|
let _,E="unknown"
|
|
25
|
-
w&&"object"==typeof w&&"_workingEndpoint"in w&&(E=w._workingEndpoint),u.info("Successfully extracted task data from response",{taskId:b,requestId:C,title:
|
|
25
|
+
w&&"object"==typeof w&&"_workingEndpoint"in w&&(E=w._workingEndpoint),u.info("Successfully extracted task data from response",{taskId:b,requestId:C,title:I})
|
|
26
26
|
try{const e=i.getToolRecordClient()
|
|
27
|
-
if(e){const t=await e.createToolRecord({taskId:b,requestId:C,projectId:l,type:"create-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:
|
|
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:
|
|
29
|
-
let q
|
|
27
|
+
if(e){const t=await e.createToolRecord({taskId:b,requestId:C,projectId:l,type:"create-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:I,taskDescription:k,taskStatus:v},note:"Created task "+I})
|
|
28
|
+
_=t?.id}}catch(e){u.error("Failed to create tool record for task creation, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:b,requestId:C})}h({success:!0,requestId:a.requestId,projectId:l}),u.info("Task created successfully",{taskId:b,requestId:C,title:I,projectId:l})
|
|
29
|
+
let q=`Created Task ${b}: ${I}`
|
|
30
30
|
return _&&(q+=`\n[RECORD:${_}]`),{content:[{type:"text",text:q}]}}catch(r){if(u.error("Failed to create task",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new tasks")||r.message.includes("disabled due to tier limits")||r.message.includes("Project is inactive due to tier limits")))u.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
|
|
31
31
|
else{const n=i.getToolRecordClient()
|
|
32
32
|
n&&await n.createToolRecord({requestId:e.requestId,projectId:t.projectId,type:"create-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.title,taskDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),error:(0,s.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create task: "+e.title})}}catch(e){u.error("Failed to create failure record for task creation",{error:e instanceof Error?e.message:e+""})}h({success:!1,error:r instanceof Error?r.name:"unknown"})
|
|
33
33
|
let o=(0,s.getErrorMessage)(r),c=""
|
|
34
34
|
return r instanceof n.NotFoundError?o=`The request ID "${e.requestId}" was not found. Please provide a valid request ID.`:r instanceof n.ValidationError&&(o.includes("Project cannot accept new tasks")||o.includes("Project is inactive due to tier limits")?c="\n\nThis project is currently inactive due to tier limits. Only your oldest projects can accept new tasks. Please use an active project or upgrade your tier for more simultaneous projects.":o="Invalid input: "+o),a.error("Detailed error when creating task",{error:(0,s.getErrorMessage)(r),stack:r instanceof Error?r.stack:void 0}),i.isOffline,i.apiClient,{content:[{type:"text",text:`Error: ${o}${c}`}],isError:!0}}}
|
|
35
35
|
const r=t(6183),n=t(9860),o=t(2960),s=t(8824)},184(e,exports,t){function r(e,t,r,n,o={}){const s=d.default.resolve(e)
|
|
36
|
-
if(
|
|
37
|
-
const i=new
|
|
38
|
-
return
|
|
36
|
+
if(A.has(s))return t.child({component:"mcp-server-registry"}).debug("Using existing server for path",{path:s}),A.get(s)
|
|
37
|
+
const i=new D(s,t,r,n,o)
|
|
38
|
+
return A.set(s,i),i}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
39
39
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
40
40
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||(n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[]
|
|
41
41
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -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)),
|
|
47
|
+
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),g=t(9567),p=t(3444),f=t(7660),m=t(1253),y=t(5172),w=t(7976),b=i(t(7478)),I=t(4139),k=new Set,v=t(9860),C=t(1472),_=t(3328),E=t(8955),q=t(3217),S=t(8411),T=t(5278),P=t(446),R=t(9060),M=t(8824),j=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),x=process.stdout.write,O=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
|
|
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
|
|
49
|
+
class D{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.clientInfo=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.multiAgentMode=o.multiAgentMode||!1,this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,multiAgentMode:o.multiAgentMode||!1,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,I.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new f.ProjectContext(e,t),this.tokenManager=new m.TokenManager(t,e,{remoteServerUrl:n}),this.lockOverrideManager=new P.LockOverrideManager(t),this.configManager=new R.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new g.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{search:{},create_request:{},complete_task:{},get_task_information:{},complete_request:{},revert_request:{},get_request_information:{},list_tasks:{},list_requests:{},switch_to_branch:{},read_files:{},create_directory:{},move_files:{},write_file:{},replace_strings:{},insert_lines:{},replace_lines:{},delete_files:{},document_operations:{},file_history:{},task_file_history:{},request_file_history:{},quick_write:{},quick_replace:{},quick_manage:{}}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.interceptConnectMethod(),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
|
|
50
50
|
const e=this.workspaceManager.getCurrentContext()
|
|
51
51
|
return{currentBranch:e.branchName,activeRequestId:e.requestId,isOnMainBranch:e.isMainBranch}}async updateBranchState(e,t){this.logger.debug("updateBranchState called - managed by WorkspaceManager",{branch:e,requestId:t})}async getCurrentBranchContext(){if(!this.workspaceManager)return{branch:null,requestId:null,isMain:!0}
|
|
52
52
|
const e=this.workspaceManager.getCurrentContext()
|
|
@@ -56,7 +56,7 @@ const n=await r.getNextId(e)
|
|
|
56
56
|
return t({success:!0,type:e}),this.metrics.incrementCounter("remote_id_success",1,{type:e}),n}catch(t){throw this.metrics.incrementCounter("remote_id_failure",1,{type:e,error:t instanceof Error?t.name:"unknown"}),this.logger.warn("Failed to get ID from remote server, unable to perform operation",{type:e,error:(0,M.getErrorMessage)(t)}),Error("Failed to get ID from remote server.")}}async initialize(){const e=this.remoteServerUrl||"https://api.alchemylabcode.com"
|
|
57
57
|
this.logger.debug("Using remote server URL",{remoteServerUrl:e})
|
|
58
58
|
const t=d.default.resolve(this.basePath)
|
|
59
|
-
if(
|
|
59
|
+
if(k.has(t))return this.logger.info("Path already initialized in global registry, skipping initialization",{path:t}),void(this.isInitialized=!0)
|
|
60
60
|
if(this.isInitialized)this.logger.info("Server already initialized, skipping initialization")
|
|
61
61
|
else{if(this.isInitializing)return this.logger.info("Initialization already in progress, waiting..."),void await this.initializationPromise
|
|
62
62
|
this.isInitializing=!0,this.logger.info("SERVER INITIALIZATION STARTING",{path:t,pid:process.pid,time:(new Date).toISOString()}),this.metrics.setGauge("mcp_initialization",0,{status:"starting"})
|
|
@@ -67,12 +67,12 @@ try{this.logger.info("Validating git repository for branch management...")
|
|
|
67
67
|
const e=await b.validateGitRepository(this.git,this.logger,this.metrics)
|
|
68
68
|
if(e.isGitRepository){this.logger.info("Git repository validation completed",{currentBranch:e.currentBranch,isClean:e.isClean,defaultBranch:e.defaultBranch,branchCount:e.branches.length,hasMainBranch:e.hasMainBranch,hasMasterBranch:e.hasMasterBranch})
|
|
69
69
|
const t=[],r=[]
|
|
70
|
-
e.currentBranch||(t.push("Repository is in detached HEAD state"),r.push("Switch to a proper branch: git checkout main")),e.isClean||(t.push(`Repository has ${e.uncommittedChanges.length} uncommitted changes`),r.push("Commit or stash changes before creating requests")),e.defaultBranch||(t.push("No default branch (main/master) found"),r.push("Create a default branch: git checkout -b main")),t.length>0?this.logger.warn("Git repository has potential issues for branch management",{issues:t,recommendations:r}):this.logger.info("Git repository is ready for automatic branch management"),this.metrics.setGauge("git_repository_ready",0===t.length?1:0),this.metrics.setGauge("git_repository_branch_count",e.branches.length),this.metrics.incrementCounter("git_repository_validation_success",1)}else this.logger.error("Git repository validation failed - not a valid git repository"),this.metrics.incrementCounter("git_repository_validation_failed",1)}catch(e){this.logger.warn("Git repository validation encountered an error",{error:e instanceof Error?e.message:e+""}),this.metrics.incrementCounter("git_repository_validation_error",1)}}async ensureGitignoreWithAlchemyLab(){const e=d.default.join(this.basePath,".gitignore"),t=
|
|
70
|
+
e.currentBranch||(t.push("Repository is in detached HEAD state"),r.push("Switch to a proper branch: git checkout main")),e.isClean||(t.push(`Repository has ${e.uncommittedChanges.length} uncommitted changes`),r.push("Commit or stash changes before creating requests")),e.defaultBranch||(t.push("No default branch (main/master) found"),r.push("Create a default branch: git checkout -b main")),t.length>0?this.logger.warn("Git repository has potential issues for branch management",{issues:t,recommendations:r}):this.logger.info("Git repository is ready for automatic branch management"),this.metrics.setGauge("git_repository_ready",0===t.length?1:0),this.metrics.setGauge("git_repository_branch_count",e.branches.length),this.metrics.incrementCounter("git_repository_validation_success",1)}else this.logger.error("Git repository validation failed - not a valid git repository"),this.metrics.incrementCounter("git_repository_validation_failed",1)}catch(e){this.logger.warn("Git repository validation encountered an error",{error:e instanceof Error?e.message:e+""}),this.metrics.incrementCounter("git_repository_validation_error",1)}}async ensureGitignoreWithAlchemyLab(){const e=d.default.join(this.basePath,".gitignore"),t=I.ALCHEMY_DIR_NAME+"/"
|
|
71
71
|
try{if(u.default.existsSync(e)){const r=await h.default.readFile(e,"utf8")
|
|
72
|
-
if(r.split("\n").some((e=>e.trim()===t||e.trim()===t.slice(0,-1))))this.logger.info(
|
|
72
|
+
if(r.split("\n").some((e=>e.trim()===t||e.trim()===t.slice(0,-1))))this.logger.info(I.ALCHEMY_DIR_NAME+"/ already present in .gitignore")
|
|
73
73
|
else{const n=r.trimEnd()+"\n\n# AlchemyMCP working directory\n"+t+"\n"
|
|
74
|
-
await h.default.writeFile(e,n),this.logger.info(`Added ${
|
|
75
|
-
await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${
|
|
74
|
+
await h.default.writeFile(e,n),this.logger.info(`Added ${I.ALCHEMY_DIR_NAME}/ to existing .gitignore`)}}else{const r=["# Dependency directories\nnode_modules/\n.npm\n.yarn\n\n# Build outputs\ndist/\nbuild/\n\n# Logs\nlogs/\n*.log\n\n# Editor files\n.DS_Store\n.vscode/\n.idea/\n\n# Environment variables\n.env\n.env.local\n\n# AlchemyMCP working directory",t,""].join("\n")
|
|
75
|
+
await h.default.writeFile(e,r),this.logger.info(`Created new .gitignore with ${I.ALCHEMY_DIR_NAME}/ entry`)}}catch(e){this.logger.warn("Failed to update .gitignore file",{error:(0,M.getErrorMessage)(e)})}}async initializeGitRepo(){try{this.logger.info("Initializing git repository"),await this.git.init(),await this.ensureGitignoreWithAlchemyLab()
|
|
76
76
|
const e=d.default.join(this.basePath,"README.md")
|
|
77
77
|
if(!u.default.existsSync(e)){const t=`# Project at ${this.basePath}\n\nCreated with AlchemyMCP Server.\n`
|
|
78
78
|
await h.default.writeFile(e,t)}this.logger.info("Git repository initialized successfully"),await this.git.add(".")
|
|
@@ -165,8 +165,8 @@ this.git=(0,c.simpleGit)({baseDir:n.basePath,binary:this.gitBinary})
|
|
|
165
165
|
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
|
-
return t?.path||this.basePath}}exports.McpServer=
|
|
169
|
-
const
|
|
168
|
+
return t?.path||this.basePath}}exports.McpServer=D
|
|
169
|
+
const A=new Map},213(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
170
170
|
const r=t(6183),n=t(3707)
|
|
171
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())
|
|
172
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)
|
|
@@ -195,13 +195,13 @@ const w=[],b=a.toLowerCase()
|
|
|
195
195
|
for(const e of y){const t=[]
|
|
196
196
|
if("all"!==l&&"title"!==l||!e.title||e.title.toLowerCase().includes(b)&&t.push({request:e,matchType:"title",matchSnippet:r(e.title,a)}),"all"!==l&&"description"!==l||!e.description||e.description.toLowerCase().includes(b)&&t.push({request:e,matchType:"description",matchSnippet:n(e.description,b,150)}),("all"===l||"criteria"===l)&&e.acceptanceCriteria)for(const r of e.acceptanceCriteria){const o="string"==typeof r?r:r.description
|
|
197
197
|
if(o&&o.toLowerCase().includes(b)){t.push({request:e,matchType:"criteria",matchSnippet:n(o,b,150)})
|
|
198
|
-
break}}t.length>0&&w.push(t[0])}const
|
|
199
|
-
if(0===
|
|
200
|
-
let v=`Found ${
|
|
201
|
-
for(const e of
|
|
198
|
+
break}}t.length>0&&w.push(t[0])}const I=g.limit||20,k=w.slice(0,I)
|
|
199
|
+
if(0===k.length)return h({success:!0,resultCount:0}),{content:[{type:"text",text:`No requests found matching "${a}".\n\nSearched in: ${l}\nTotal requests checked: ${y.length}`}]}
|
|
200
|
+
let v=`Found ${k.length} request${1===k.length?"":"s"} matching "${a}":\n\n`
|
|
201
|
+
for(const e of k){const t=e.request,r=o(t.status)
|
|
202
202
|
v+=`${s(t.type)} **${t.title}** (${t.id}) ${r}\n`,v+=" \u{1f4cd} Match in "+e.matchType,e.matchSnippet&&(v+=": "+e.matchSnippet),v+="\n\n"}v+=`---\nSearched ${y.length} requests (filtered by: `
|
|
203
203
|
const C=[]
|
|
204
|
-
return g.status&&C.push("status="+g.status),g.type&&C.push("type="+g.type),g.dateFrom&&C.push("from="+g.dateFrom),g.dateTo&&C.push("to="+g.dateTo),v+=C.length>0?C.join(", "):"none",v+=")",h({success:!0,resultCount:
|
|
204
|
+
return g.status&&C.push("status="+g.status),g.type&&C.push("type="+g.type),g.dateFrom&&C.push("from="+g.dateFrom),g.dateTo&&C.push("to="+g.dateTo),v+=C.length>0?C.join(", "):"none",v+=")",h({success:!0,resultCount:k.length}),d.incrementCounter("search_requests_success",1),{content:[{type:"text",text:v}]}}catch(e){return u.error("Search requests failed",{error:e instanceof Error?e.stack:e+""}),h({success:!1,error:(0,a.getErrorMessage)(e)}),d.incrementCounter("search_requests_errors",1),{content:[{type:"text",text:"\u274c **Search Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
205
205
|
const i=t(9860),a=t(8824)},260(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
206
206
|
const r=t(6183),n=t(4221)
|
|
207
207
|
exports.def={name:"view_asset",description:"View an image from the project's .alchemy_lab/assets/ folder. Returns the image so you can see it. Use this when you encounter asset:filename.png references in plans or documents and need to understand the image content.",schema:r.ViewAssetSchema,annotations:{title:"View Asset Image",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleViewAsset)(e,t.context,t.logger,t.metrics)}}},270(e,exports){Object.defineProperty(exports,"__esModule",{value:!0})},293(e,exports,t){function r(e){let t
|
|
@@ -222,6 +222,12 @@ case"ready_for_review":t="ready_for_review"
|
|
|
222
222
|
break
|
|
223
223
|
case"pending_approval":case o.RequestStatus.PENDING_APPROVAL:t="pending_approval"
|
|
224
224
|
break
|
|
225
|
+
case"pending_verification":t="ready_for_review"
|
|
226
|
+
break
|
|
227
|
+
case"ready_for_merge":t="ready_for_merge"
|
|
228
|
+
break
|
|
229
|
+
case"resolving_conflicts":t="resolving_conflicts"
|
|
230
|
+
break
|
|
225
231
|
default:t="open"}else t="open"
|
|
226
232
|
const n=Array.isArray(e.acceptanceCriteria)?e.acceptanceCriteria.map(r):[]
|
|
227
233
|
return{id:e.id,title:e.title,description:e.description,type:e.type,status:t,acceptanceCriteria:n,createdAt:e.createdAt,updatedAt:e.updatedAt,...e.projectId?{projectId:e.projectId}:{},...e.completionSummary?{completionSummary:e.completionSummary}:{},...e.completedAt?{completedAt:e.completedAt}:{},...e.metadata?{metadata:e.metadata}:{},...e.lockInfo?{lockInfo:e.lockInfo}:{}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.adaptApiAcceptanceCriterionToDomain=r,exports.adaptApiRequestToDomain=n,exports.adaptApiRequestsToDomain=function(e){return e.map(n)}
|
|
@@ -252,14 +258,14 @@ throw p.error("Failed to check request lock status",{taskId:o,requestId:w.reques
|
|
|
252
258
|
let b=d.git
|
|
253
259
|
if(d.workspaceManager){const e=d.workspaceManager.getCurrentContext()
|
|
254
260
|
if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
|
|
255
|
-
b=simpleGit({baseDir:e.basePath,binary:d.gitBinary}),p.debug("Using workspace-aware git instance for task completion",{taskId:o,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let
|
|
256
|
-
if(b)try{(await b.status()).isClean()||(
|
|
261
|
+
b=simpleGit({baseDir:e.basePath,binary:d.gitBinary}),p.debug("Using workspace-aware git instance for task completion",{taskId:o,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let I=null
|
|
262
|
+
if(b)try{(await b.status()).isClean()||(I=(await b.commit(`Complete task ${o}: ${h}`)).commit,p.info("Created commit for task completion",{taskId:o,commitId:I}))}catch(e){p.warn("Failed to commit changes",{error:(0,l.getErrorMessage)(e)})}let k=null
|
|
257
263
|
try{const e=u.getToolRecordClient()
|
|
258
|
-
e&&(
|
|
259
|
-
p.info("Raw task update response data",{responseData:JSON.stringify(n)}),p.debug("Task update response structure",{type:typeof n,isArray:Array.isArray(n),hasData:null!=n,properties:n?Object.keys(n):[],dataPreview:n?JSON.stringify(n).substring(0,200)+"...":"null"}),(0,s.extractDataFromResponse)(n,{logger:p,operationName:"updateTask",defaultValue:{id:o,status:"completed"}}),p.info("Successfully completed task",{taskId:o,recordId:
|
|
264
|
+
e&&(k={id:(await e.createToolRecord({taskId:o,requestId:w.requestId,projectId:m,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:h,lastCommit:I,completedAt:(new Date).toISOString()},note:`Completed task: ${h.substring(0,100)}${h.length>100?"...":""}`})).id})}catch(e){p.error("Failed to create tool record for task completion, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:o,requestId:w.requestId})}try{const e=w.metadata||{},t=(new Date).toISOString(),r={status:"completed",metadata:{...e,lastCommit:I,completionSummary:h,completionRecordId:k?.id,completedAt:t}},n=await y.updateTask(o,r)
|
|
265
|
+
p.info("Raw task update response data",{responseData:JSON.stringify(n)}),p.debug("Task update response structure",{type:typeof n,isArray:Array.isArray(n),hasData:null!=n,properties:n?Object.keys(n):[],dataPreview:n?JSON.stringify(n).substring(0,200)+"...":"null"}),(0,s.extractDataFromResponse)(n,{logger:p,operationName:"updateTask",defaultValue:{id:o,status:"completed"}}),p.info("Successfully completed task",{taskId:o,recordId:k?.id})
|
|
260
266
|
const i=w.requestId
|
|
261
|
-
let a=`Task ${o} has been marked as completed.`
|
|
262
|
-
if(
|
|
267
|
+
let a=`Task ${o} (${w.title}) has been marked as completed.`
|
|
268
|
+
if(k?.id&&(a+=`\n[RECORD:${k.id}]`),I&&(a+="\nCommit: "+I.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
|
|
263
269
|
p.info("Raw tasks list response data",{responseData:JSON.stringify(e)}),p.debug("Tasks list response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
|
|
264
270
|
const t=(0,s.extractArrayFromResponse)(e,{logger:p,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
|
|
265
271
|
p.info("Task progress check",{requestId:i,totalTasks:r,completedTasks:n}),a+=`\n\nTask Progress: ${n}/${r} tasks completed`,n===r&&(a+=`\n\nAll tasks for request ${i} are now completed! You may consider marking the request as completed using the complete-request tool.`)}catch(e){p.warn("Failed to check task progress",{error:(0,l.getErrorMessage)(e),requestId:i})}return f({success:!0}),{content:[{type:"text",text:a}]}}catch(e){throw p.error("Failed to complete task",{error:e instanceof Error?e.stack:e+"",taskId:o}),Error("Failed to complete task: "+(0,l.getErrorMessage)(e))}}catch(t){if(p.error("Failed to complete task",{error:t instanceof Error?t.stack:t+"",args:e}),d.projectId)try{const r=u.getToolRecordClient()
|
|
@@ -276,19 +282,21 @@ var t={}
|
|
|
276
282
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
277
283
|
return o(t,e),t})
|
|
278
284
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlanWrite=async function(e,t,r,n,o){const s=n.child({tool:"plan_write"})
|
|
279
|
-
try{const n=
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
return o.incrementCounter("plan_write_total",1,{operation:"
|
|
284
|
-
return o.incrementCounter("plan_write_total",1,{operation:"
|
|
285
|
-
return o.incrementCounter("plan_write_total",1,{operation:"
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
if(!
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
285
|
+
try{const n=["update","append","replace","createSnapshot","restore","setActive"]
|
|
286
|
+
for(const t of n)e?.[t]&&"object"==typeof e[t]&&(Object.assign(e,e[t]),delete e[t])
|
|
287
|
+
const u=a.validateArgs(e,i.PlanWriteSchema),{operation:h,planId:g}=u
|
|
288
|
+
switch(s.info("Processing plan_write",{operation:h}),h){case"update":{const e=await(0,c.handleUpdatePlan)({planId:g,content:u.content,name:u.name},t,r,s,o)
|
|
289
|
+
return o.incrementCounter("plan_write_total",1,{operation:"update",success:!e.isError}),e}case"append":{const e=await(0,l.handleAppendPlan)({planId:g,content:u.content,name:u.name},r,s,o)
|
|
290
|
+
return o.incrementCounter("plan_write_total",1,{operation:"append",success:!e.isError}),e}case"replace":{const e=await(0,d.handleReplacePlan)({planId:g,old:u.old,new:u.new,name:u.name},r,s,o)
|
|
291
|
+
return o.incrementCounter("plan_write_total",1,{operation:"replace",success:!e.isError}),e}case"create-snapshot":{const{versionLabel:e,changeSummary:t}=u,n=r.getDocumentClient(),s=await n.createVersionSnapshot(g,e,t)
|
|
292
|
+
return o.incrementCounter("plan_write_total",1,{operation:"create-snapshot",success:!0}),{content:[{type:"text",text:`\u2705 **Plan Snapshot Created**\n\n**Plan:** ${g}\n**Version:** ${s.versionNumber}\n**Label:** ${e||"None"}\n**Summary:** ${t||"None"}\n**Created:** `+new Date(s.createdAt).toLocaleString()}]}}case"restore":{const{versionNumber:e}=u,t=r.getDocumentClient(),n=await t.restoreToVersion(g,e)
|
|
293
|
+
return o.incrementCounter("plan_write_total",1,{operation:"restore",success:!0}),{content:[{type:"text",text:`\u2705 **Plan Restored**\n\n**Plan:** ${g}\n**Restored to Version:** ${e}\n**Filename:** ${n.filename}\n\nThe plan has been successfully restored to version ${e}.`}]}}case"set-active":{const e=t.projectId
|
|
294
|
+
if(!e)return{content:[{type:"text",text:"\u274c No project context available."}],isError:!0}
|
|
295
|
+
const n=r.getDocumentClient(),s=await n.getDocument(g)
|
|
296
|
+
if(!s)return{content:[{type:"text",text:"\u274c Plan not found: "+g}],isError:!0}
|
|
297
|
+
if("Plan"!==s.type)return{content:[{type:"text",text:`\u274c Document ${g} is not a Plan (type: ${s.type}).`}],isError:!0}
|
|
298
|
+
const i=r.getProjectClient()
|
|
299
|
+
return await i.updateProject(e,{activePlanId:g}),o.incrementCounter("plan_write_total",1,{operation:"set-active",success:!0}),{content:[{type:"text",text:`\u2705 **Active Plan Updated**\n\n**Plan:** ${s.localId||s.id}\n**Filename:** ${s.filename}\n**Project:** ${e}\n\nThis plan is now the active project plan.`}]}}default:throw Error("Unknown plan_write operation: "+h)}}catch(e){return s.error("plan_write failed",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("plan_write_errors",1),{content:[{type:"text",text:"\u274c **Plan Write Failed:** "+(0,u.getErrorMessage)(e)}],isError:!0}}}
|
|
292
300
|
const i=t(6183),a=s(t(5967)),c=t(7609),l=t(4419),d=t(2352),u=t(8824)},410(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
293
301
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
294
302
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
|
|
@@ -298,11 +306,12 @@ var t={}
|
|
|
298
306
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
299
307
|
return o(t,e),t})
|
|
300
308
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTaskOperations=async function(e,t,r,n,o){const s=n.child({tool:"task_operations"})
|
|
301
|
-
try{
|
|
309
|
+
try{e?.list?.filters&&"object"==typeof e.list.filters?(Object.assign(e,e.list.filters),delete e.list):e?.list&&"object"==typeof e.list&&(Object.assign(e,e.list),delete e.list)
|
|
310
|
+
const n=a.validateArgs(e,i.TaskOperationsSchema),{taskId:d,operation:u}=n
|
|
302
311
|
let h
|
|
303
312
|
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)
|
|
304
313
|
break
|
|
305
|
-
case"list":s.info("Routing to list-tasks handler",{requestId:n.requestId}),h=await(0,l.handleListTasks)({requestId:n.requestId,filters:n.
|
|
314
|
+
case"list":s.info("Routing to list-tasks handler",{requestId:n.requestId}),h=await(0,l.handleListTasks)({requestId:n.requestId,filters:{status:n.status,limit:n.limit,offset:n.offset,sortBy:n.sortBy,sortDirection:n.sortDirection}},t,r,s,o)
|
|
306
315
|
break
|
|
307
316
|
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
317
|
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)}
|
|
@@ -453,19 +462,19 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerApiRoutes
|
|
|
453
462
|
n.debug("Token retrieved from authentication manager")
|
|
454
463
|
const j=new b.ConnectionStatusManager(T,n.child({component:"connection-status-manager"}),o,{checkIntervalMs:3e4,timeoutMs:5e3}),x=new w.ProjectClient(T,n.child({component:"project-client"}),o,j,M)
|
|
455
464
|
R.registerClient(x)
|
|
456
|
-
const O=new
|
|
465
|
+
const O=new k.TaskClient(T,n.child({component:"task-client"}),o,x,j,M)
|
|
457
466
|
R.registerClient(O)
|
|
458
|
-
const
|
|
459
|
-
R.registerClient(A)
|
|
460
|
-
const D=new C.ProxyClient(T,n.child({component:"proxy-client"}),o,x,M,j)
|
|
467
|
+
const D=new v.FileOperationsClient(T,n.child({component:"file-client"}),o,x,M,j)
|
|
461
468
|
R.registerClient(D)
|
|
469
|
+
const A=new C.ProxyClient(T,n.child({component:"proxy-client"}),o,x,M,j)
|
|
470
|
+
R.registerClient(A)
|
|
462
471
|
const $=new _.RequestClient(T,n.child({component:"request-client"}),o,x,M,j)
|
|
463
472
|
$.setAuthToken(M),(0,d.isDebugToolsEnabled)()&&n.debug("Explicitly set token on RequestClient",{tokenPresent:!!M}),R.registerClient($)
|
|
464
473
|
const F=new E.DocumentClient(T,n.child({component:"document-client"}),o,x,M,j)
|
|
465
474
|
R.registerClient(F)
|
|
466
475
|
const N=new q.ToolRecordClient(T,n.child({component:"tool-record-client"}),o,x,M,j)
|
|
467
476
|
R.registerClient(N)
|
|
468
|
-
const L=new S.ApiClient(P,x,O,
|
|
477
|
+
const L=new S.ApiClient(P,x,O,D,$,F,N,A,n.child({component:"api-client"})),z=a.default.Router();(0,h.registerAuthRoutes)(z,{projectClient:x,taskClient:O,fileClient:D,authManager:P,apiClient:L},i,n)
|
|
469
478
|
const B=r.getContext();(0,g.registerConfigRoutes)(z,n,B.basePath),e.use("/api",z)
|
|
470
479
|
const H=e=>{const t=o.startTimer(e)
|
|
471
480
|
return e=>t(e)},U=(e,t,n)=>{const o=e.query.path||e.body.path
|
|
@@ -479,9 +488,9 @@ if((0,d.isDebugToolsEnabled)()&&s.debug("Task validation response received",{tas
|
|
|
479
488
|
let o=!1
|
|
480
489
|
if("object"==typeof e&&null!==e){404===e.statusCode&&(o=!0),404===e.response?.statusCode&&(o=!0)
|
|
481
490
|
const t=(e.message||e.error||e)+"";(t.includes("404")||t.toLowerCase().includes("not found"))&&(o=!0)}if(o)return s.info("Task ID not found - blocking operation",{taskId:n,statusCode:404,action:"blocking"}),t.status(400).json({success:!1,error:{code:"TASK_NOT_FOUND",message:"Task ID does not exist: "+n,retryable:!1,statusCode:400}})
|
|
482
|
-
s.warn("Error validating task ID",{taskId:n,error:(0,
|
|
491
|
+
s.warn("Error validating task ID",{taskId:n,error:(0,I.getErrorMessage)(e)}),s.warn("Error validating task ID, but continuing as fallback",{taskId:n,action:"continuing"}),r()}}
|
|
483
492
|
e.get("/health",((e,t)=>{o.incrementCounter("api_requests_total",1,{endpoint:"health",method:"GET"}),t.json({success:!0,data:{status:"ok",version:"0.1.0",serverType:"mcp-local-server",timestamp:(new Date).toISOString()}})})),e.get("/mcp/sse",(async(e,t)=>{s.info("New SSE connection requested",{ip:e.ip,userAgent:e.headers["user-agent"]}),o.incrementCounter("mcp_connections_total",1,{type:"sse"})
|
|
484
|
-
try{await r.createSseConnection(t,e.headers["user-agent"]),t.on("close",(()=>{s.info("SSE connection closed"),o.setGauge("mcp_active_connections",0,{type:"sse"}),r.cleanupSSEConnection()}))}catch(e){s.error("Failed to establish MCP SSE connection",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("mcp_connection_errors",1,{type:"sse",error:e instanceof Error?e.name:"unknown"}),t.headersSent?t.end():t.status(500).json({success:!1,error:"Failed to establish SSE connection",message:(0,
|
|
493
|
+
try{await r.createSseConnection(t,e.headers["user-agent"]),t.on("close",(()=>{s.info("SSE connection closed"),o.setGauge("mcp_active_connections",0,{type:"sse"}),r.cleanupSSEConnection()}))}catch(e){s.error("Failed to establish MCP SSE connection",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("mcp_connection_errors",1,{type:"sse",error:e instanceof Error?e.name:"unknown"}),t.headersSent?t.end():t.status(500).json({success:!1,error:"Failed to establish SSE connection",message:(0,I.getErrorMessage)(e)})}})),e.get("/api/files/exists",U,(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/exists",method:"GET"})
|
|
485
494
|
const r=H("api_request_duration")
|
|
486
495
|
try{const n=await l.default.stat(e.fullPath)
|
|
487
496
|
r({endpoint:"files/exists",method:"GET",success:!0}),t.json({success:!0,data:{exists:!0,isDirectory:n.isDirectory(),isFile:n.isFile(),size:n.size,modified:n.mtime}})}catch(e){if("ENOENT"!==e.code)throw e
|
|
@@ -500,7 +509,7 @@ return r({endpoint:"files/content",method:"GET",success:!0,encoding:"binary"}),t
|
|
|
500
509
|
r({endpoint:"files/content",method:"GET",success:!0,encoding:o}),t.json({success:!0,data:{path:e.relativePath,content:s,size:n.size,modified:n.mtime}})}catch(t){throw"ENOENT"===t.code?(r({endpoint:"files/content",method:"GET",success:!1,error:"not_found"}),(0,u.createNotFoundError)("File not found: "+e.relativePath)):t}}catch(e){r(e)}})),e.post("/api/files/write",U,W,(async(e,t,s)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/write",method:"POST"})
|
|
501
510
|
const s=H("api_request_duration"),{content:i,taskId:a,format:c="text"}=e.body
|
|
502
511
|
if(void 0===i)throw(0,u.createValidationError)("Content parameter is required")
|
|
503
|
-
const l=await(0,f.handleWriteFile)({taskId:a,path:e.relativePath,content:i,format:c},r.getContext(),
|
|
512
|
+
const l=await(0,f.handleWriteFile)({taskId:a,path:e.relativePath,content:i,format:c},r.getContext(),D,O,N,$,n,o)
|
|
504
513
|
s({endpoint:"files/write",method:"POST",success:!0}),t.json({success:!0,data:l})}catch(e){s(e)}})),e.post("/api/files/replace",U,W,(async(e,t,s)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/replace",method:"POST"})
|
|
505
514
|
const s=H("api_request_duration"),{replacements:i,mode:a="unique",taskId:c}=e.body
|
|
506
515
|
if(!i||!Array.isArray(i))throw(0,u.createValidationError)("Replacements array is required")
|
|
@@ -531,7 +540,7 @@ r.getContext(),s.info("Manual project synchronization requested"),s.info("Starti
|
|
|
531
540
|
try{await x.syncProjects(),e({endpoint:"sync/projects",method:"POST",success:!0}),t.json({success:!0,data:{message:"Project synchronization completed successfully",timestamp:(new Date).toISOString()}})}catch(r){s.error("Project synchronization failed",{error:r instanceof Error?r.stack:r+""}),e({endpoint:"sync/projects",method:"POST",success:!1}),t.status(500).json({success:!1,error:"Project synchronization failed",message:r instanceof Error?r.message:r+"",timestamp:(new Date).toISOString()})}}catch(e){n(e)}})),e.get("/api/remote/status",(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"remote/status",method:"GET"})
|
|
532
541
|
const e=H("api_request_duration")
|
|
533
542
|
try{const r=await x.pingDetailed(),n="online"===r.status,o=r.latency
|
|
534
|
-
e({endpoint:"remote/status",method:"GET",success:!0,connected:n}),s.info("Remote server status check",{status:n?"ONLINE":"OFFLINE",latencyMs:o}),t.json({success:!0,data:{connected:n,url:T,latency:o,queueStats:{total:0,pending:0,inProgress:0,completed:0,failed:0},isOffline:x.isOffline(),serverTime:(new Date).toISOString()}})}catch(r){e({endpoint:"remote/status",method:"GET",success:!0,connected:!1}),t.json({success:!0,data:{connected:!1,url:T,error:(0,
|
|
543
|
+
e({endpoint:"remote/status",method:"GET",success:!0,connected:n}),s.info("Remote server status check",{status:n?"ONLINE":"OFFLINE",latencyMs:o}),t.json({success:!0,data:{connected:n,url:T,latency:o,queueStats:{total:0,pending:0,inProgress:0,completed:0,failed:0},isOffline:x.isOffline(),serverTime:(new Date).toISOString()}})}catch(r){e({endpoint:"remote/status",method:"GET",success:!0,connected:!1}),t.json({success:!0,data:{connected:!1,url:T,error:(0,I.getErrorMessage)(r),serverTime:(new Date).toISOString()}})}}catch(e){r(e)}})),e.get("/api/proxy/*",(async(e,t,r)=>{try{const r=e.path.substring(11)
|
|
535
544
|
try{const n=await L.proxyGet(r,e.query)
|
|
536
545
|
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})
|
|
537
546
|
throw e}}catch(e){r(e)}})),e.post("/api/proxy/*",W,(async(e,t,r)=>{try{const r=e.path.substring(11)
|
|
@@ -541,7 +550,7 @@ throw e}}catch(e){r(e)}})),e.patch("/api/proxy/*",W,(async(e,t,r)=>{try{const r=
|
|
|
541
550
|
try{const n=await L.proxyPatch(r,e.body)
|
|
542
551
|
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})
|
|
543
552
|
throw e}}catch(e){r(e)}}))}
|
|
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),
|
|
553
|
+
const a=i(t(7252)),c=i(t(6928)),l=i(t(1943)),d=t(3444),u=t(9860),h=t(6776),g=t(6476),p=t(3306),f=t(4079),m=t(3895),y=s(t(5967)),w=t(4710),b=t(5681),I=t(8824),k=t(2968),v=t(6153),C=t(1887),_=t(1666),E=t(9884),q=t(922),S=t(3328)},1253(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
545
554
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.TokenManager=void 0
|
|
546
555
|
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
556
|
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()
|
|
@@ -605,18 +614,18 @@ const r=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Co
|
|
|
605
614
|
if(r.ok){const e=await r.json()
|
|
606
615
|
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
|
|
607
616
|
const y=[]
|
|
608
|
-
if(o.length>=
|
|
617
|
+
if(o.length>=k||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:k,depth:c}),{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}
|
|
609
618
|
try{const w=await g.default.readdir(e,{withFileTypes:!0}),v=[],C=[]
|
|
610
619
|
for(const t of w){const r=h.default.join(e,t.name)
|
|
611
|
-
if(t.isDirectory()){if(
|
|
620
|
+
if(t.isDirectory()){if(I.includes(t.name)||t.name.startsWith(".")){a.debug("Skipping excluded directory: "+t.name)
|
|
612
621
|
continue}C.push({entry:t,fullPath:r})}else if(t.isFile()){if("*"!==i&&!t.name.endsWith(i)){a.debug("Skipping file due to extension mismatch",{filename:t.name,requiredExtension:i})
|
|
613
622
|
continue}v.push({entry:t,fullPath:r})}}if(v.length>0){const e=[]
|
|
614
623
|
for(let t=0;t<v.length;t+=16)e.push(v.slice(t,t+16))
|
|
615
|
-
for(const r of e){if(o.length>=
|
|
624
|
+
for(const r of e){if(o.length>=k)break
|
|
616
625
|
const e=await Promise.all(r.map((({entry:e,fullPath:r})=>n(r,t,0,o,l,d,e.name,u))))
|
|
617
626
|
for(const t of e){p++,t.hasMatches&&f++
|
|
618
|
-
for(const e of t.matches){if(o.length>=
|
|
619
|
-
o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=
|
|
627
|
+
for(const e of t.matches){if(o.length>=k)return{filesCount:p,fileMatchesCount:f,subdirCount:m,subdirStats:y}
|
|
628
|
+
o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=k)break
|
|
620
629
|
m++
|
|
621
630
|
const e={path:n,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
622
631
|
try{const l=await r(n,t,o,s,i,a,c+1,e,d,u)
|
|
@@ -627,7 +636,7 @@ let l,d=!1
|
|
|
627
636
|
const u=async()=>{if(void 0===l)try{const t=await g.default.stat(e)
|
|
628
637
|
l=t.mtime.getTime()}catch(e){l=void 0}return l}
|
|
629
638
|
if("filename"!==s&&"both"!==s||t.test(i)&&(d=!0,await u(),c.push({file:e,line:0,text:i,modifiedTime:l,matchType:"filename"})),"content"===s||"both"===s)try{const r=(await g.default.readFile(e,"utf8")).split("\n")
|
|
630
|
-
for(let o=0;o<r.length&&n.length<
|
|
639
|
+
for(let o=0;o<r.length&&n.length<k;o++)if(t.test(r[o])){d=!0,await u()
|
|
631
640
|
const t={file:e,line:o+1,text:(0,y.truncate)(r[o].trim(),120),modifiedTime:l,matchType:"content"}
|
|
632
641
|
if(a>0){const e=Math.max(0,o-a)
|
|
633
642
|
t.contextBefore=r.slice(e,o).map((e=>(0,y.truncate)(e.trim(),120)))
|
|
@@ -654,31 +663,31 @@ var t={}
|
|
|
654
663
|
if(null!=e)for(var r=a(e),n=0;n<r.length;n++)"default"!==r[n]&&c(t,e,r[n])
|
|
655
664
|
return l(t,e),t}),u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
656
665
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearch=async function(e,t,n,a,c){const l=a.child({tool:"search"}),d=c.startTimer("tool_execution_time"),u=Date.now()
|
|
657
|
-
let
|
|
658
|
-
const
|
|
666
|
+
let I=0
|
|
667
|
+
const k={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:p.default.hostname(),username:p.default.userInfo().username,workingDirectory:process.cwd(),contextBasePath:t?.basePath||"unknown"},startTime:u,endTime:0,phases:{initializationTime:0,searchTime:0,directoryListingTime:0},totalFiles:0,totalMatches:0,directoryStats:[],errors:[]}
|
|
659
668
|
try{const{needle:n,directory:p,options:v={}}=e
|
|
660
669
|
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,w.handleListDirectory)({path:p||".",levels:v.levels||1,sortBy:v.sortBy||"name"},t,a,c)
|
|
661
|
-
if("string"!=typeof n)throw
|
|
670
|
+
if("string"!=typeof n)throw k.errors.push("Search term (needle) must be a string"),(0,f.createValidationError)("Search term (needle) must be a string")
|
|
662
671
|
let C
|
|
663
|
-
if(
|
|
672
|
+
if(k.searchDirectory=p||".",p){const{normalizedPath:e,fullPath:r}=m.validateAndNormalizePath(p,t)
|
|
664
673
|
C=r}else C=t.basePath
|
|
665
|
-
|
|
674
|
+
k.resolvedPath=C
|
|
666
675
|
let _=!1
|
|
667
676
|
try{_=(await g.default.stat(C)).isFile()}catch(e){const t=`Cannot access path ${C}: ${(0,b.getErrorMessage)(e)}`
|
|
668
|
-
throw
|
|
677
|
+
throw k.errors.push(t),Error(t)}const E=v.maxResults||50,q=v.caseSensitive||!1,S=v.useRegex||!1,T=v.fileExtension,P=v.searchIn||"content"
|
|
669
678
|
let R=void 0!==v.contextLines?v.contextLines:0
|
|
670
|
-
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!_&&!T)throw
|
|
679
|
+
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!_&&!T)throw k.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,f.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
|
|
671
680
|
let M,j=""
|
|
672
681
|
if(_)j="*"
|
|
673
682
|
else if("*"===T)j="*"
|
|
674
683
|
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)}`
|
|
675
|
-
throw
|
|
684
|
+
throw k.errors.push(t),(0,f.createValidationError)(t)}if(k.patternInfo={needle:n,regex:M.toString(),caseSensitive:q,fileExtension:T,normalizedExtension:j},!_)try{const e=Date.now(),t=await g.default.readdir(C,{withFileTypes:!0}),r=[],n=[]
|
|
676
685
|
for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
|
|
677
|
-
|
|
678
|
-
|
|
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}}),
|
|
686
|
+
k.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},k.phases.directoryListingTime=k.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,b.getErrorMessage)(e)
|
|
687
|
+
k.errors.push(t),l.error(t)}const x=_?"file":"directory"
|
|
688
|
+
l.info(`Searching for "${n}" in ${x} ${C} (mode: ${P})`,{needle:n,searchTarget:x,path:C,options:{maxResults:E,caseSensitive:q,fileExtension:j,searchIn:P}}),I=Date.now(),k.phases.initializationTime=I-u
|
|
680
689
|
const O=Date.now()
|
|
681
|
-
let
|
|
690
|
+
let D=[],A=0,$=0
|
|
682
691
|
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=[]
|
|
683
692
|
if(s.info("performLocalSearch started",{searchPath:e,pattern:t.toString(),options:n}),d)return await async function(e,t,r,n,o,s=0){const i=[],a=h.default.basename(e)
|
|
684
693
|
let c
|
|
@@ -694,17 +703,17 @@ o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
|
|
|
694
703
|
const f={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
695
704
|
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,p,a,o,s,0,f,l,u)
|
|
696
705
|
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)
|
|
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,
|
|
698
|
-
|
|
706
|
+
return f.errors.push(r),i.directoryStats.push(f),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:p,totalFiles:f.filesProcessed}}}(C,M,{maxResults:E,fileExtension:j,searchIn:P,isFile:_,contextLines:R},j,l,k)
|
|
707
|
+
D=e.matches,A=e.totalFiles
|
|
699
708
|
const t=1e3
|
|
700
|
-
|
|
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 ${$||
|
|
702
|
-
|
|
709
|
+
D.length>0&&D.length<=t?(D.sort(((e,t)=>void 0!==e.modifiedTime&&void 0!==t.modifiedTime?t.modifiedTime-e.modifiedTime:void 0!==e.modifiedTime&&void 0===t.modifiedTime?-1:void 0===e.modifiedTime&&void 0!==t.modifiedTime?1:0)),l.info(`Sorted ${D.length} matches by modification time (newest first)`)):D.length>t&&l.info(`Skipped sorting ${D.length} matches (exceeds hard cap of ${t} for performance)`),$=D.length,D.length>E&&(D=D.slice(0,E),l.info(`Limited results to ${E} (from ${$} total matches)`)),D.forEach((e=>{e.relativePath=function(e,t){const r=h.default.relative(e,t)
|
|
710
|
+
return r?r===h.default.basename(t)?r:r.startsWith("./")?r.substring(2):r:h.default.basename(t)}(C,e.file)})),l.info(`Local search completed: found ${$||D.length} total matches in ${A} files, returning ${D.length} results`),k.phases.searchTime=Date.now()-O}catch(e){const t="Error during search: "+(0,b.getErrorMessage)(e)
|
|
711
|
+
k.errors.push(t),l.error(t),k.phases.searchTime=Date.now()-O}k.totalFiles=A,k.totalMatches=D.length,k.endTime=Date.now()
|
|
703
712
|
let F,N=""
|
|
704
713
|
try{if(t.getCurrentBranchContext){const e=await t.getCurrentBranchContext()
|
|
705
|
-
e.branch&&(N=e.isMain?` (searched on main branch: ${e.branch})`:` (searched on request branch: ${e.branch}${e.requestId?" for "+e.requestId:""})`)}}catch(e){l.debug("Could not get branch context",{error:e}),N=" (branch context unavailable)"}l.debug("Search diagnostic information",{diagnostic:
|
|
714
|
+
e.branch&&(N=e.isMain?` (searched on main branch: ${e.branch})`:` (searched on request branch: ${e.branch}${e.requestId?" for "+e.requestId:""})`)}}catch(e){l.debug("Could not get branch context",{error:e}),N=" (branch context unavailable)"}l.debug("Search diagnostic information",{diagnostic:k})
|
|
706
715
|
const L="content"===P?"content":"filename"===P?"filenames":"content and filenames"
|
|
707
|
-
if($>
|
|
716
|
+
if($>D.length?(F=`Found ${$} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=`${N}. Showing first ${D.length}:\n\n`):(F=`Found ${D.length} results for "${n}" (searching ${L})`,p&&(F+=" in "+p),T&&(F+=" with extension "+T),F+=N+":\n\n"),D.length>0)if(R>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
|
|
708
717
|
if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
|
|
709
718
|
const o=new Map
|
|
710
719
|
for(const e of n){const t=o.get(e.file)||[]
|
|
@@ -712,7 +721,7 @@ t.push(e),o.set(e.file,t)}const i=[]
|
|
|
712
721
|
for(const[e,r]of o.entries()){r.sort(((e,t)=>e.line-t.line))
|
|
713
722
|
let e=[r[0]]
|
|
714
723
|
for(let n=1;n<r.length;n++){const o=e[e.length-1],a=r[n],c=o.line+t
|
|
715
|
-
a.line-t>c+1?(i.push(s(e,t)),e=[a]):e.push(a)}e.length>0&&i.push(s(e,t))}return{filenameMatches:r,mergedGroups:i}}(
|
|
724
|
+
a.line-t>c+1?(i.push(s(e,t)),e=[a]):e.push(a)}e.length>0&&i.push(s(e,t))}return{filenameMatches:r,mergedGroups:i}}(D,R),r=[]
|
|
716
725
|
e.forEach((e=>{r.push(e.relativePath+" [filename match]")})),t.forEach((e=>{const t=[]
|
|
717
726
|
e.lines.forEach((e=>{e.isMatch?t.push(`> ${e.lineNumber}: ${e.content}`):t.push(` ${e.lineNumber}: ${e.content}`)})),r.push(`${e.relativePath}:\n${t.join("\n")}`)})),F+=r.join("\n\n")}else F+=await async function(e){const t=e.filter((e=>"filename"===e.matchType)),r=e.filter((e=>"content"===e.matchType)),n=[]
|
|
718
727
|
t.length>0&&t.forEach((e=>{n.push(e.relativePath+" [filename match]")}))
|
|
@@ -723,12 +732,12 @@ const r=t[0].relativePath||e,o=t.length,s=await i(e)
|
|
|
723
732
|
let a=r
|
|
724
733
|
void 0!==s&&(a+=` (${s} lines)`),a+=` - ${o} ${1===o?"match":"matches"}:`
|
|
725
734
|
const c=t.map((e=>` :${e.line} - ${e.text}`))
|
|
726
|
-
n.push(a+"\n"+c.join("\n"))}return n.join("\n\n")}(
|
|
735
|
+
n.push(a+"\n"+c.join("\n"))}return n.join("\n\n")}(D)
|
|
727
736
|
else F+="No matches found."
|
|
728
|
-
return d({success:!0}),{content:[{type:"text",text:F}]}}catch(t){l.error("Search failed",{args:e,error:t instanceof Error?t.stack:t+""}),
|
|
737
|
+
return d({success:!0}),{content:[{type:"text",text:F}]}}catch(t){l.error("Search failed",{args:e,error:t instanceof Error?t.stack:t+""}),k.errors.push((0,b.getErrorMessage)(t)),k.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:k})
|
|
729
738
|
let r="Search failed: "+(0,b.getErrorMessage)(t)
|
|
730
739
|
return d({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:r}],isError:!0}}}
|
|
731
|
-
const h=u(t(6928)),g=u(t(1943)),p=u(t(857)),f=t(9860),m=d(t(5967)),y=t(5967),w=t(2537),b=t(8824),
|
|
740
|
+
const h=u(t(6928)),g=u(t(1943)),p=u(t(857)),f=t(9860),m=d(t(5967)),y=t(5967),w=t(2537),b=t(8824),I=["node_modules"],k=1e4,v=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore"]),C=1048576},1318(e,exports,t){async function r(e,t,r){try{const r=(await e.revparse(["--show-toplevel"])).trim(),n=c.default.isAbsolute(t)?t:c.default.resolve(t)
|
|
732
741
|
return c.default.relative(r,n)}catch(e){return r.warn("Failed to get repo-relative path, using original",{filePath:t,error:(0,l.getErrorMessage)(e)}),t}}function n(e){return/\(trec\d{6}\)/.test(e)}async function o(e,t,n,o,s){try{const i=await r(e,t,s),a=await e.raw(["log","-1","--pretty=format:%H|%s",`-L${n},${o}:${i}`])
|
|
733
742
|
if(!a||""===a.trim())return null
|
|
734
743
|
const c=a.trim().split("\n")[0],[l,...d]=c.split("|"),u=d.join("|")
|
|
@@ -804,26 +813,26 @@ try{return await i.hasValidToken()}catch(e){return m.error("Error checking authe
|
|
|
804
813
|
m.info(`Generating tools list with testsRequired=${e}, authenticated=${t}`)
|
|
805
814
|
const r={testsRequired:e,authenticated:t}
|
|
806
815
|
return(0,f.generateVisibleToolsList)(r)}
|
|
807
|
-
let
|
|
808
|
-
|
|
816
|
+
let I=b(),k=[]
|
|
817
|
+
I.then((e=>{k=e})).catch((e=>{m.error("Error generating initial tools list",{error:(0,l.getErrorMessage)(e)}),k=[]})),e.setRequestHandler(a.ListToolsRequestSchema,(async()=>{try{return k=await b(),{tools:k}}catch(e){return m.error("Error generating tools list",{error:(0,l.getErrorMessage)(e)}),{tools:[]}}}))
|
|
809
818
|
let v=!1
|
|
810
819
|
e.setRequestHandler(a.CallToolRequestSchema,(async e=>{try{const{name:i,arguments:a={},_meta:c}=e.params;(0,p.logSessionIdentity)(i,"_meta-debug",{has_meta:!!c,sessionId:c?.sessionId||null,messageId:c?.messageId||null,paramKeys:Object.keys(e.params)}),m.info("Tool call received: "+i,{tool:i}),s.incrementCounter("tool_calls_total",1,{tool:i})
|
|
811
820
|
const b=s.startTimer("tool_execution_time")
|
|
812
821
|
Date.now()
|
|
813
|
-
let
|
|
814
|
-
const
|
|
815
|
-
if(Date.now(),
|
|
822
|
+
let I=Date.now()
|
|
823
|
+
const k=r(a)
|
|
824
|
+
if(Date.now(),I=Date.now(),y){const e=await w()
|
|
816
825
|
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)
|
|
817
|
-
if(
|
|
826
|
+
if(I=Date.now(),n?(n.setOptions({createRecords:C?.createsRecords??!1}),m.info(`Setting record creation for tool ${i}: ${C?.createsRecords??!1}`)):m.debug(`No API client available for tool ${i} (minimal mode)`),Date.now(),I=Date.now(),t?.workspaceManager&&!t.workspaceManager.readonlyBranchCheckDone)try{const e=await(0,d.getServerUrl)(t,m)
|
|
818
827
|
e&&n&&await t.workspaceManager.ensureReadonlyBranchIfNeeded(e,i,n,c?.sessionId)}catch(e){m.debug("Error during readonly branch check",{error:(0,l.getErrorMessage)(e)})}let _,E
|
|
819
|
-
if(Date.now(),Date.now(),
|
|
828
|
+
if(Date.now(),Date.now(),I=Date.now(),C&&!C.readOnly)if(c?.sessionId){const e=c.sessionId,r=c.messageId,n=u.sessionIdentity.getIdentity()
|
|
820
829
|
if(n)n.sessionId!==e&&((0,p.logSessionIdentity)(i,"_meta-session-switch",{prevSessionId:n.sessionId,prevAgentType:n.agentType,newSessionId:e}),u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:n.serverUrl}))
|
|
821
830
|
else{const r=await(0,d.getServerUrl)(t,m)
|
|
822
831
|
u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r||""}),u.sessionIdentity.markDiscoveryAttempted()}_={providerId:"opencode",sessionId:e,messageId:r,createdAt:(new Date).toISOString()},(0,p.logSessionIdentity)(i,"_meta",{sessionId:e,messageId:r})}else{const e=u.sessionIdentity.getIdentity()
|
|
823
|
-
if(e){let
|
|
824
|
-
try{
|
|
825
|
-
else if(
|
|
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()
|
|
832
|
+
if(e){let r,n=!1
|
|
833
|
+
try{r=await(0,d.findMessageIdForTool)(e.serverUrl,e.sessionId,i)}catch{n=!0}if(r)_=u.sessionIdentity.buildCliOrigin(r)
|
|
834
|
+
else if(n)_=u.sessionIdentity.buildCliOrigin()
|
|
835
|
+
else{m.info("Session identity mismatch: tool call not found in cached session, re-discovering",{prevSessionId:e.sessionId,prevAgentType:e.agentType,tool:i}),u.sessionIdentity.reset(),t?.workspaceManager?.resetCurrentContext?.()
|
|
827
836
|
try{const t=await(0,d.getAndStoreSessionId)(e.serverUrl,m,i)
|
|
828
837
|
t?(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e.serverUrl}),(0,p.logSessionIdentity)(i,"re-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId)):(u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),m.info("Re-discovery found no other session, keeping current identity",{sessionId:e.sessionId})),u.sessionIdentity.markDiscoveryAttempted()}catch(t){u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),u.sessionIdentity.markDiscoveryAttempted(),m.warn("Re-discovery failed, keeping current identity (may be stale)",{error:(0,l.getErrorMessage)(t),tool:i,sessionId:e.sessionId})}}}else if(!u.sessionIdentity.hasDiscoveryBeenAttempted())try{const e=await(0,d.getServerUrl)(t,m)
|
|
829
838
|
if(e){const t=await(0,d.getAndStoreSessionId)(e,m,i)
|
|
@@ -833,7 +842,7 @@ if(r&&!o){const t=r[1]
|
|
|
833
842
|
v=!0
|
|
834
843
|
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()
|
|
835
844
|
await Promise.all([i,a])}catch(e){m.warn("Error in session tag mapping / lock acquisition",{error:(0,l.getErrorMessage)(e)})}}}}if(C){const e={context:t,apiClient:n,logger:o,metrics:s,mcpServer:g,cliOrigin:_}
|
|
836
|
-
E=await C.handler(
|
|
845
|
+
E=await C.handler(k,e)}else m.info(`Tool ${i} not found, returning negative response`),E={content:[{type:"text",text:`The tool '${i}' does not exist.`}]}
|
|
837
846
|
return Date.now(),Date.now(),b({tool:i,success:!0}),E}catch(t){m.error("Error executing tool:",{error:t instanceof Error?t.stack:t+"",tool:e.params.name}),s.incrementCounter("tool_errors_total",1,{tool:e.params.name,error:t instanceof Error?t.name:"unknown"})
|
|
838
847
|
let r="Unknown error"
|
|
839
848
|
if(t instanceof Error)r=t.message
|
|
@@ -1004,11 +1013,10 @@ this.logger.debug("Retrieved main branch hash via direct rev-parse",{branch:n,co
|
|
|
1004
1013
|
try{if(i=await this.git.revparse(["HEAD"]),!/^[a-f0-9]{40}$/i.test(i))throw Error("Invalid HEAD commit hash format: "+i)
|
|
1005
1014
|
this.logger.warn("Used HEAD as fallback for main branch commit hash",{originalBranch:n,fallbackCommit:i.substring(0,8)+"..."})}catch(e){throw Error(`Failed to get commit hash for branch '${n}' and HEAD fallback failed: ${e instanceof Error?e.message:e+""}`)}}return this.logger.info("Main branch commit hash detection completed",{selectedBranch:n,detectionMethod:o,commitHashShort:i.substring(0,8)+"...",currentBranchContext:t,validFormat:/^[a-f0-9]{40}$/i.test(i),strategy:"context-aware-detection"}),i}catch(e){throw this.logger.error("Failed to get main branch commit hash",{error:(0,n.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),Error("Failed to get main branch commit hash: "+(0,n.getErrorMessage)(e))}}hasExactConflictMarkers(e){return!(!e||!e.trim())&&[/^\s*<{7}(?:\s|$)/m,/^\s*={7}(?:\s|$)/m,/^\s*>{7}(?:\s|$)/m].some((t=>t.test(e)))}async handleConflicts(e){const{requestId:t}=e
|
|
1006
1015
|
this.logger.info("Starting conflict resolution workflow",{requestId:t,conflictedFiles:e.conflictedFiles.length,mode:e.mode})
|
|
1007
|
-
try{await this.
|
|
1008
|
-
const r=await this.writeConflictMarkersToFiles(e)
|
|
1016
|
+
try{const r=await this.writeConflictMarkersToFiles(e)
|
|
1009
1017
|
this.logger.info("Wrote conflict markers to files",{requestId:t,filesWritten:r})
|
|
1010
1018
|
const n=await this.createConflictResolutionTask(e)
|
|
1011
|
-
return this.logger.info("Created conflict resolution task",{requestId:t,taskId:n}),{statusUpdated:!
|
|
1019
|
+
return this.logger.info("Created conflict resolution task",{requestId:t,taskId:n}),{statusUpdated:!1,taskCreated:!0,taskId:n,conflictFilesWritten:r,userMessage:this.generateConflictResolutionMessage(e,n)}}catch(e){return this.logger.error("Conflict resolution workflow failed",{requestId:t,error:(0,n.getErrorMessage)(e)}),{statusUpdated:!1,taskCreated:!1,conflictFilesWritten:0,userMessage:"Conflict resolution workflow failed: "+(0,n.getErrorMessage)(e)}}}async updateRequestStatus(e,t){const r=this.apiClient.getRequestClient(),n={status:t}
|
|
1012
1020
|
this.logger.info("Updating request status",{requestId:e,status:t}),await r.updateRequest(e,n)}async runStructuredMergeTree(e){const t="git merge-tree --write-tree --name-only main requests/"+e
|
|
1013
1021
|
this.logger.debug("Running structured merge-tree command",{requestId:e,command:t,cwd:this.workingDirectory})
|
|
1014
1022
|
try{const r=await(0,c.execAsync)(t,{cwd:this.workingDirectory}),n=r.stdout.trim().split("\n").filter((e=>e.trim()))
|
|
@@ -1052,7 +1060,7 @@ if(!r)throw Error("Project ID is required for task creation but not available")
|
|
|
1052
1060
|
const o=`**Merge conflicts detected during request completion.**\n\n## Conflicted Files:\n${e.conflictedFiles.map((e=>"- "+e.path)).join("\n")}\n\n## Resolution Instructions:\n1. **Review the conflict markers** in the files above\n2. **Resolve conflicts using standard file editing tools**:\n - Use \`write-file\` to replace entire file content with resolved version\n - Use \`replace-string\` for targeted conflict resolution\n - Remove ALL conflict markers: \`<<<<<<<\`, \`=======\`, \`>>>>>>>\`\n3. **Ensure no conflict markers remain** in any file\n4. **Test your resolution** if applicable\n5. **Try completing the request again** when conflicts are resolved\n\n## Conflict Details:\n- **Detection Method**: ${e.detectionMethod}\n- **Mode**: ${e.mode}\n- **Summary**: ${e.summary}\n\n${e.safetyAnalysis?`\n## Auto-Merge Analysis:\n- **Attempted**: ${e.autoMergeAttempted?"Yes":"No"}\n- **Safe for auto-merge**: ${e.safetyAnalysis.isSafe?"Yes":"No"}\n- **Reason**: ${e.safetyAnalysis.reason}\n${e.safetyAnalysis.failureReasons.length>0?"- **Issues**: "+e.safetyAnalysis.failureReasons.join(", "):""}\n`:""}\n\n## Next Steps:\n1. Resolve the conflicts in the files listed above\n2. Call \`complete-request\` again with the same requestId\n3. The system will detect the resolution and complete the merge\n\n**Note**: The request status has been set to 'conflicted' and will remain so until conflicts are resolved.`
|
|
1053
1061
|
let s
|
|
1054
1062
|
try{s=await this.getCurrentMainCommitHash(),this.logger.info("Storing main branch commit hash for conflict tracking",{requestId:e.requestId,mainCommitHash:s.substring(0,8)+"..."})}catch(t){this.logger.warn("Could not get main branch commit hash, conflict re-detection will be disabled",{requestId:e.requestId,error:(0,n.getErrorMessage)(t)})}const i={requestId:e.requestId,projectId:r,title:t,description:o,metadata:{conflictedFiles:e.conflictedFiles.map((e=>e.path)),detectionTime:(new Date).toISOString(),mainBranchCommitHash:s,detectionMethod:e.detectionMethod,mode:e.mode,originalRequestId:e.requestId,safetyAnalysis:e.safetyAnalysis,conflictType:"merge-conflicts"}},a=this.apiClient.getTaskClient()
|
|
1055
|
-
return(await a.createTask(i)).id}generateConflictResolutionMessage(e,t){return`## \u26a0\ufe0f Merge Conflicts Detected\n\nRequest **${e.requestId}** has merge conflicts that need to be resolved before completion.\n\n### Status Update:\n- **
|
|
1063
|
+
return(await a.createTask(i)).id}generateConflictResolutionMessage(e,t){return`## \u26a0\ufe0f Merge Conflicts Detected\n\nRequest **${e.requestId}** has merge conflicts that need to be resolved before completion.\n\n### Status Update:\n- **Conflict Resolution Task**: Created task \`${t}\`\n- **Files with Conflicts**: ${e.conflictedFiles.length} files\n\n### Conflicted Files:\n${e.conflictedFiles.map((e=>`- \`${e.path}\``)).join("\n")}\n\n### What Happened:\n${e.summary}\n\n### How to Resolve:\n1. **Use standard file editing tools** to resolve conflicts:\n - \`write-file\` to replace entire file content\n - \`replace-string\` for targeted edits\n - Remove all \`<<<<<<<\`, \`=======\`, \`>>>>>>>\` markers\n\n2. **Ensure all conflict markers are removed** from all files\n\n3. **Complete the conflict resolution task** when done\n\n4. **Call \`merge\` again** with the same requestId to merge to main\n\n**Note**: You can use any file editing approach. Remove all conflict markers, complete the task, then call merge.`}async validateConflictsResolved(e){const t=[]
|
|
1056
1064
|
for(const r of e.conflictedFiles)try{const e=i.default.resolve(this.workingDirectory,r.path)
|
|
1057
1065
|
if(a.default.existsSync(e)){const n=a.default.readFileSync(e,"utf8")
|
|
1058
1066
|
this.hasExactConflictMarkers(n)&&t.push(r.path)}}catch(e){this.logger.warn("Failed to check conflict resolution in file",{filePath:r.path,error:(0,n.getErrorMessage)(e)}),t.push(r.path)}return{resolved:0===t.length,remainingConflicts:t}}async hasMainBranchChanged(e){try{const t=this.apiClient.getTaskClient(),r=await t.listTasks({requestId:e})
|
|
@@ -1177,24 +1185,24 @@ if(!r.ok)return null
|
|
|
1177
1185
|
const n=await r.json()
|
|
1178
1186
|
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
|
|
1179
1187
|
if(r(t,"handleSpawn called",{agent:a,promptLength:c.length,requestId:l,useExistingSession:u,cliOriginSessionId:i?.sessionId||null}),!(0,T.isValidAgent)(a)){const e=(0,T.getAgentNames)()
|
|
1180
|
-
return{content:[{type:"text",text:`\u274c Unknown agent '${a}'.\n\n**Available agents:** ${e.join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}}try{const e=(0,
|
|
1188
|
+
return{content:[{type:"text",text:`\u274c Unknown agent '${a}'.\n\n**Available agents:** ${e.join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}}try{const e=(0,k.getCachedSession)(),n=i?.sessionId||e?.sessionId
|
|
1181
1189
|
let o=e?.agentType
|
|
1182
1190
|
if(r(t,"Spawn agent type check",{cliOriginSessionId:i?.sessionId||null,cachedSessionId:e?.sessionId||null,cachedAgentType:e?.agentType||null,pid:process.pid,envSessionTag:process.env.ALCHEMY_SESSION_TAG||null,envInitialBranch:process.env.ALCHEMY_INITIAL_BRANCH||null}),!o&&n)try{const e=`http://localhost:${R}/api/sessions/${encodeURIComponent(n)}/agent-type`
|
|
1183
1191
|
r(t,"Looking up agent type from action server",{sessionId:n,url:e})
|
|
1184
1192
|
const s=await fetch(e)
|
|
1185
1193
|
if(s.ok){const e=await s.json()
|
|
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,
|
|
1194
|
+
r(t,"Agent type response from action server",{sessionId:n,agentType:e.agentType||null,source:e.source||null,success:e.success}),e.success&&e.agentType&&(o=e.agentType,(0,k.updateCachedSession)({agentType:o}))}else r(t,"Agent type lookup failed",{sessionId:n,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e?.sessionId,error:(0,E.getErrorMessage)(n)})}if(o){const e=(0,T.getAllowedSubagents)(o)
|
|
1187
1195
|
if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${o}' cannot spawn '${a}'.\n\n**Allowed subagents for ${o}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,E.getErrorMessage)(e)})}let h
|
|
1188
1196
|
try{const e=await n(a)
|
|
1189
1197
|
if(h=e?.requestContextMode,!h){const e=(0,T.getBuiltInAgentConfig)(a)
|
|
1190
1198
|
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}
|
|
1191
|
-
const g=await(0,
|
|
1199
|
+
const g=await(0,I.getServerUrl)(t,o)
|
|
1192
1200
|
r(t,"serverUrl resolved",{serverUrl:g})
|
|
1193
1201
|
const p=t.basePath
|
|
1194
1202
|
if(!p)throw new w.ValidationError("Working directory not available in context")
|
|
1195
|
-
const f=(0,
|
|
1203
|
+
const f=(0,k.getCachedSession)()
|
|
1196
1204
|
let m
|
|
1197
|
-
if(g)try{m=i?.sessionId||f?.sessionId||await(0,
|
|
1205
|
+
if(g)try{m=i?.sessionId||f?.sessionId||await(0,I.discoverParentSessionId)(g,o)}catch{}let y=""
|
|
1198
1206
|
if(s&&l)try{const e=s.getSessionRequestAssociationClient()
|
|
1199
1207
|
if(e){const t=await e.getSessionsForRequest(l,!0),r=m?t.filter((e=>e.opencodeSessionId!==m)):t
|
|
1200
1208
|
if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
|
|
@@ -1207,10 +1215,10 @@ try{let e
|
|
|
1207
1215
|
try{const t=await fetch(`http://localhost:${R}/api/project-settings`)
|
|
1208
1216
|
if(t.ok){const r=await t.json()
|
|
1209
1217
|
if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
|
|
1210
|
-
e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${_}/
|
|
1218
|
+
e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${_}/prompt_async`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:q}],...a?{agent:a}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
|
|
1211
1219
|
if(!r.ok){const e=await r.text().catch((()=>"Unknown error"))
|
|
1212
1220
|
throw Error(`Failed to send to existing session: ${r.status} ${e}`)}o.info("Prompt sent to existing session",{sessionId:_,agent:a})}catch(e){throw Error("Failed to use existing session: "+(0,E.getErrorMessage)(e))}}else{if(S=!0,r(t,"Creating session via HTTP and spawning CLI"),!g)throw Error("Cannot spawn subagent: no server URL available")
|
|
1213
|
-
const i=m||f?.sessionId||await(0,
|
|
1221
|
+
const i=m||f?.sessionId||await(0,I.discoverParentSessionId)(g,o);(0,v.logSessionIdentity)("subagent_operations.spawn",m?"early-discovery":f?"_meta":"http-discovery",{parentSessionId:i}),r(t,"Parent session discovered",{parentSessionId:i})
|
|
1214
1222
|
const u=g.replace(/\/$/,"")+"/session",h=e.title?e.title:l?`[${l}] ${c.slice(0,40)}${c.length>40?"...":""}`:`${c.slice(0,50)}${c.length>50?"...":""}`,y=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentID:i,title:h})})
|
|
1215
1223
|
if(!y.ok)throw Error("Failed to create session: "+y.status)
|
|
1216
1224
|
const w=await y.json()
|
|
@@ -1220,7 +1228,7 @@ r(t,"Pre-created session with parentID",{preCreatedSessionId:M,parentSessionId:i
|
|
|
1220
1228
|
const j=(async()=>{if(s)try{const n=s.getCLISessionClient()
|
|
1221
1229
|
if(!n)return
|
|
1222
1230
|
let o,c
|
|
1223
|
-
if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:(0,
|
|
1231
|
+
if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:(0,k.getCachedSession)()?.agentType||void 0})
|
|
1224
1232
|
o=e.id,c=e.workflowId,r(t,"Registered parent session in DB",{parentSessionId:i,parentDbId:o,parentWorkflowId:c})}const l=await n.createOrUpdateSession({externalSessionId:M,providerId:"opencode",parentSessionId:o||null,title:h,status:"active",agentType:a,specialization:e.specialization,workflowId:c||void 0})
|
|
1225
1233
|
r(t,"Registered child session in DB",{childSessionId:M,childDbId:l.id,parentDbId:o})}catch(e){r(t,"Failed to register sessions in DB",{error:(0,E.getErrorMessage)(e)}),o.warn("Failed to register sessions in alchemy DB",{error:(0,E.getErrorMessage)(e)})}})()
|
|
1226
1234
|
let x
|
|
@@ -1244,9 +1252,9 @@ if(!O.success)throw Error("Failed to spawn subagent: "+O.error)
|
|
|
1244
1252
|
_=M,r(t,"CLI spawn successful with pre-created session",{sessionId:M,pid:O.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:M,pid:O.pid,parentSessionId:i})}if(s&&l&&_&&"unknown"!==_&&"spawning"!==_)try{const e=s.getSessionRequestAssociationClient()
|
|
1245
1253
|
if(e&&(e.createAssociation(_,l).then((()=>o.info("Created session-request association",{sessionId:_,requestId:l}))).catch((e=>o.warn("Failed to create session-request association",{error:(0,E.getErrorMessage)(e),sessionId:_,requestId:l}))),"coder"===a)){const e=s.getRequestClient()
|
|
1246
1254
|
e&&e.updateRequest(l,{cliOrigin:{providerId:"opencode",sessionId:_,createdAt:(new Date).toISOString()}}).catch((e=>o.debug("Failed to update request cliOrigin",{error:(0,E.getErrorMessage)(e)})))}}catch(e){o.warn("Failed to create session-request association",{error:(0,E.getErrorMessage)(e),sessionId:_,requestId:l})}let M=y
|
|
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,
|
|
1255
|
+
return u?M+=`Prompt sent to existing session ${_}.`:(M+=`Background ${a} subagent spawned successfully.`,_&&"unknown"!==_&&"spawning"!==_&&(M+=`\n[SESSION:${_}]`)),l&&(M+="\nWorking on: "+l),M+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:M}]}}async function s(e,t,r,n,o,s,i){const a=await(0,I.getServerUrl)(r,n)
|
|
1248
1256
|
if(!a)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1249
|
-
if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId||(0,
|
|
1257
|
+
if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId||(0,k.getCachedSession)()?.sessionId||await(0,I.discoverParentSessionId)(a,n)
|
|
1250
1258
|
if(t){const r=o.getCLISessionClient()
|
|
1251
1259
|
if(r){let o=await r.getByExternalId(t)
|
|
1252
1260
|
o||(o=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),n.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:o?.id})),o&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:o.id,status:"active"}),n.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){n.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,E.getErrorMessage)(e)})}let c=s
|
|
@@ -1257,7 +1265,7 @@ try{let r
|
|
|
1257
1265
|
try{const e=await fetch(`http://localhost:${R}/api/project-settings`)
|
|
1258
1266
|
if(e.ok){const t=await e.json()
|
|
1259
1267
|
if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
|
|
1260
|
-
r={providerID:e,modelID:n.join("/")}}}}catch{}const o=`${a.replace(/\/$/,"")}/session/${e}/
|
|
1268
|
+
r={providerID:e,modelID:n.join("/")}}}}catch{}const o=`${a.replace(/\/$/,"")}/session/${e}/prompt_async`,s=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:t}],...c?{agent:c}:{},...r?{model:r}:{}}),signal:AbortSignal.timeout(1e4)})
|
|
1261
1269
|
if(!s.ok){const e=await s.text().catch((()=>"Unknown error"))
|
|
1262
1270
|
throw Error(`Failed to send message: ${s.status} ${e}`)}return n.info("Message sent to subagent session",{sessionId:e,agent:c}),{content:[{type:"text",text:`Message sent to session ${e}.\nThe subagent will process it in the background.`}]}}catch(e){throw Error("Failed to continue session: "+(0,E.getErrorMessage)(e))}}function i(e){const t=Math.floor(e/1e3)
|
|
1263
1271
|
if(60>t)return t+"s"
|
|
@@ -1272,7 +1280,7 @@ return{current:r?.name??null,recent:n.map((e=>e.name)),lastActivityTime:o}}funct
|
|
|
1272
1280
|
return e&&M>n?{status:"working",detail:"last action "+c(n),isReady:!1}:n>j&&e?{status:"stalled",detail:"no activity for "+c(n),isReady:!0}:e?{status:"idle",detail:"no activity for "+c(n),isReady:!0}:{status:"idle",detail:"no tool activity",isReady:!0}}function d(e){let t=0,r=0,n=0
|
|
1273
1281
|
for(const o of e.trim().split("\n")){if(!o)continue
|
|
1274
1282
|
const[e,s]=o.split("\t")
|
|
1275
|
-
"-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function u(e,r,n,o){const s=await(0,
|
|
1283
|
+
"-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function u(e,r,n,o){const s=await(0,I.getServerUrl)(r,n)
|
|
1276
1284
|
if(!s)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1277
1285
|
n.info("Checking status of subagent session",{sessionId:e})
|
|
1278
1286
|
try{const c=`${s.replace(/\/$/,"")}/session/${e}`,u=await fetch(c)
|
|
@@ -1282,7 +1290,7 @@ let f={input:0,output:0,reasoning:0},m="",y=l(null,h.time.updated)
|
|
|
1282
1290
|
if(p.ok){const e=await p.json()
|
|
1283
1291
|
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)
|
|
1284
1292
|
const t=a(e)
|
|
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,
|
|
1293
|
+
y=l(t.lastActivityTime,h.time.updated),t.current&&(m+="\nCurrent: "+t.current),t.recent.length>0&&(m+="\nRecent: "+t.recent.join(", "))}const w=Date.now()-h.time.created,b=y.status,I=y.isReady,k=f.input+f.output+f.reasoning
|
|
1286
1294
|
let v="",C="",_=null
|
|
1287
1295
|
if(o)try{const t=o.getSessionRequestAssociationClient()
|
|
1288
1296
|
if(t){const r=await t.getActiveRequestsForSession(e,!1)
|
|
@@ -1297,12 +1305,12 @@ if(e.trim())return d(e)}try{const t=n(`git log main --merges --oneline -n 50 --g
|
|
|
1297
1305
|
if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
|
|
1298
1306
|
if(o.trim())return{...d(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
|
|
1299
1307
|
if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
|
|
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: ${
|
|
1308
|
+
v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${b} (${y.detail})\nReady for input: ${I?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${k.toLocaleString()} (in: ${f.input.toLocaleString()}, out: ${f.output.toLocaleString()}${f.reasoning>0?", reasoning: "+f.reasoning.toLocaleString():""})${m}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,E.getErrorMessage)(e))}}async function h(e,t,r){const n=await(0,I.getServerUrl)(t,r)
|
|
1301
1309
|
if(!n)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1302
1310
|
r.info("Aborting subagent session",{sessionId:e})
|
|
1303
1311
|
try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
|
|
1304
1312
|
if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
|
|
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,
|
|
1313
|
+
throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,E.getErrorMessage)(e))}}async function g(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:c,minTokens:d,maxTokens:u,maxAgeHours:h}=n,g=await(0,I.getServerUrl)(e,t)
|
|
1306
1314
|
if(!g)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1307
1315
|
t.info("Listing sessions",{filters:n})
|
|
1308
1316
|
try{const e=g.replace(/\/$/,"")+"/session",t=await fetch(e)
|
|
@@ -1316,10 +1324,10 @@ if(o&&(w=w.filter((e=>"idle"!==(y[e.id]?.type||"idle")))),void 0!==h){const e=36
|
|
|
1316
1324
|
w=w.filter((e=>e.time.created>=t))}if(0===w.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1317
1325
|
let b={}
|
|
1318
1326
|
if(r)try{const e=r.getCLISessionClient()
|
|
1319
|
-
e&&(b=await e.batchEnrich(w.map((e=>e.id))))}catch{}const
|
|
1327
|
+
e&&(b=await e.batchEnrich(w.map((e=>e.id))))}catch{}const I=g.replace(/\/$/,""),k=await Promise.allSettled(w.map((e=>fetch(`${I}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),v=[]
|
|
1320
1328
|
for(let e=0;e<w.length;e++){const t=w[e],r=Date.now()-t.time.created
|
|
1321
1329
|
let o=0,i=null,c=[],h=l(null,t.time.updated)
|
|
1322
|
-
const g=
|
|
1330
|
+
const g=k[e],p="fulfilled"===g.status?g.value:[]
|
|
1323
1331
|
for(const e of p)"assistant"===e.info.role&&e.info.tokens&&(o+=(e.info.tokens.input||0)+(e.info.tokens.output||0)+(e.info.tokens.reasoning||0))
|
|
1324
1332
|
if(p.length>0){const e=a(p)
|
|
1325
1333
|
h=l(e.lastActivityTime,t.time.updated),i=e.current||null,c=e.recent}const f=h.status
|
|
@@ -1329,13 +1337,13 @@ const m=b[t.id]
|
|
|
1329
1337
|
if(n.agentType&&(!m||m.agentType!==n.agentType))continue
|
|
1330
1338
|
if("archived"===m?.status)continue
|
|
1331
1339
|
let y=""
|
|
1332
|
-
const
|
|
1340
|
+
const I=[]
|
|
1333
1341
|
if(m?.associations&&m.associations.length>0){const e=m.associations.filter((e=>!e.endedAt)).map((e=>e.requestLocalId)),t=m.associations.filter((e=>e.endedAt)).map((e=>e.requestLocalId))
|
|
1334
|
-
|
|
1342
|
+
I.push(...e,...t)
|
|
1335
1343
|
const r=[]
|
|
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&&!
|
|
1344
|
+
e.length>0&&r.push("active: "+e.join(", ")),t.length>0&&r.push("prev: "+t.join(", ")),r.length>0&&(y=` [${r.join(" | ")}]`)}if(s&&!I.includes(s))continue
|
|
1337
1345
|
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:
|
|
1346
|
+
v.push({id:t.id,title:_,status:f,age:r,totalTokens:o,requestsInfo:y,allRequestIds:I,statusDetail:h.detail,specialization:m?.specialization??null,currentAction:i,recentActions:c})}if(0===v.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1339
1347
|
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
1348
|
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
1349
|
return{content:[{type:"text",text:`Found ${C.length} session${1!==C.length?"s":""}${E}:\n\n${_.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,E.getErrorMessage)(e))}}var p,f=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
@@ -1347,7 +1355,7 @@ var t={}
|
|
|
1347
1355
|
if(null!=e)for(var r=p(e),n=0;n<r.length;n++)"default"!==r[n]&&f(t,e,r[n])
|
|
1348
1356
|
return m(t,e),t})
|
|
1349
1357
|
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")
|
|
1350
|
-
try{e&&!e.operation&&(e.spawn?e.operation="spawn":e.continue?e.operation="continue":e.readMessages?e.operation="read-messages":e.listSessions?e.operation="list-sessions":e.prompt&&(e.agent||e.description)?e={operation:"spawn",spawn:{agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId,allowParallel:e.allowParallel,useExistingSession:e.useExistingSession}}:e.sessionId&&e.prompt&&!e.spawn?e={operation:"continue",sessionId:e.sessionId,continue:{prompt:e.prompt}}:e.sessionId&&(e={operation:"check-status",sessionId:e.sessionId})),"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)
|
|
1358
|
+
try{if(e&&!e.operation&&(e.spawn?e.operation="spawn":e.continue?e.operation="continue":e.readMessages?e.operation="read-messages":e.listSessions?e.operation="list-sessions":e.prompt&&(e.agent||e.description)?e={operation:"spawn",spawn:{agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId,allowParallel:e.allowParallel,useExistingSession:e.useExistingSession}}:e.sessionId&&e.prompt&&!e.spawn?e={operation:"continue",sessionId:e.sessionId,continue:{prompt:e.prompt}}:e.sessionId&&(e={operation:"check-status",sessionId:e.sessionId})),e?.spawn&&"string"==typeof e.spawn)try{e.spawn=JSON.parse(e.spawn)}catch{}if(e?.continue&&"string"==typeof e.continue)try{e.continue=JSON.parse(e.continue)}catch{}"spawn"===e?.operation&&e?.prompt&&!e?.spawn&&(e.spawn={agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId},delete e.prompt,delete e.agent,delete e.description,delete e.requestId),"continue"===e?.operation&&e?.prompt&&!e?.continue&&(e.continue={prompt:e.prompt},delete e.prompt)
|
|
1351
1359
|
const r=_.validateArgs(e,C.SubagentOperationsSchema),{sessionId:d,operation:p}=r
|
|
1352
1360
|
let f
|
|
1353
1361
|
switch(c.info("Processing subagent_operations",{operation:p,sessionId:d}),p){case"spawn":f=await o(r.spawn,t,c,i,a)
|
|
@@ -1359,7 +1367,7 @@ break
|
|
|
1359
1367
|
case"abort":f=await h(d,t,c)
|
|
1360
1368
|
break
|
|
1361
1369
|
case"read-messages":const e=r.readMessages?.limit??1
|
|
1362
|
-
f=await async function(e,t,r,n){const o=await(0,
|
|
1370
|
+
f=await async function(e,t,r,n){const o=await(0,I.getServerUrl)(r,n)
|
|
1363
1371
|
if(!o)throw new w.ValidationError("Could not determine OpenCode server URL")
|
|
1364
1372
|
n.info("Reading messages from subagent session",{sessionId:e,limit:t})
|
|
1365
1373
|
try{const r=`${o.replace(/\/$/,"")}/session/${e}/message?limit=${t}`,n=await fetch(r)
|
|
@@ -1370,11 +1378,11 @@ const i=s.map(((e,t)=>{const r="user"===e.info.role?"USER":"ASSISTANT",n=e.parts
|
|
|
1370
1378
|
return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n${o}`})).join("\n\n---\n\n")
|
|
1371
1379
|
return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,E.getErrorMessage)(e))}}(d,e,t,c)
|
|
1372
1380
|
break
|
|
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,
|
|
1381
|
+
case"list-sessions":const n={activeOnly:r.listSessions?.activeOnly,requestId:r.listSessions?.requestId,limit:r.listSessions?.limit,minTokens:r.listSessions?.minTokens,maxTokens:r.listSessions?.maxTokens,maxAgeHours:r.listSessions?.maxAgeHours,parentSessionId:a?.sessionId||(0,k.getCachedSession)()?.sessionId}
|
|
1374
1382
|
f=await g(t,c,i,n)
|
|
1375
1383
|
break
|
|
1376
1384
|
default:throw new w.ValidationError("Unknown operation: "+p)}return l({success:!0}),n.incrementCounter(`subagent_operations_${p}_success`,1),f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,E.getErrorMessage)(e)}],isError:!0}}}
|
|
1377
|
-
const w=t(9860),b=t(8035),
|
|
1385
|
+
const w=t(9860),b=t(8035),I=t(7617),k=t(715),v=t(7280),C=t(6183),_=y(t(5967)),E=t(8824),q=t(9896),S=t(6928),T=t(8955),P=t(5671),R=3456,M=6e4,j=3e5},1791(e,exports,t){function r(e,t){return t.info("Creating project context middleware",{projectId:e}),(t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1378
1386
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
|
|
1379
1387
|
const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
|
|
1380
1388
|
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")
|
|
@@ -1534,7 +1542,9 @@ const u=await s.proxyGet(`/api/projects/${o.projectId}/requests/${d}/test-runs`)
|
|
|
1534
1542
|
if(!p)return c({success:!1,error:"no_test_run"}),{content:[{type:"text",text:`No test run found for request ${d}.`}],isError:!0}
|
|
1535
1543
|
const f=p.id
|
|
1536
1544
|
await s.proxyPatch(`/api/projects/${o.projectId}/test-runs/${f}`,{status:e.status,results:e.results})
|
|
1537
|
-
const m="passed"===e.status?"\u2705":"failed"===e.status?"\u274c":"\u26a0\ufe0f"
|
|
1545
|
+
const m="passed"===e.status?"\u2705":"failed"===e.status?"\u274c":"\u26a0\ufe0f"
|
|
1546
|
+
try{const t=s.getRequestClient()
|
|
1547
|
+
"passed"===e.status?(await t.updateRequest(d,{status:"ready_for_merge"}),i.info("Tests passed, set request to ready_for_merge",{requestId:d})):(await t.updateRequest(d,{status:"in_progress"}),i.info("Tests failed, set request back to in_progress",{requestId:d}))}catch(e){i.warn("Failed to update request status after test results",{requestId:d,error:(0,r.getErrorMessage)(e)})}const y="passed"===e.status?"\n\nAll tests passed \u2014 the coder can now call `merge` to merge this request.":"\n\nTests failed \u2014 the coder should fix the issues and call `complete` again.",w=`${m} Test run ${e.status} for request ${d}\n\n${e.results.summary}${y}`
|
|
1538
1548
|
try{const t=await(0,n.handleSessionMessageOperations)({operation:"send",type:"report",status:"passed"===e.status?"success":"failure",summary:w,details:e.results.commands?.map((e=>`${"passed"===e.status?"\u2705":"\u274c"} ${e.name}: ${e.status}${e.diagnosis?" - "+e.diagnosis:""}`)).join("\n"),finish:!0},o,i,a,s),r=t?.content?.[0]?.text||"unknown",l=t?.isError
|
|
1539
1549
|
return c({success:!0}),{content:[{type:"text",text:`Test run for request ${d} reported as **${e.status}**.${l?" Parent notification FAILED: "+r:" Parent session notified."}\n\n${e.results.summary}`}]}}catch(t){return c({success:!0}),{content:[{type:"text",text:`Test run for request ${d} reported as **${e.status}** but failed to notify parent: ${(0,r.getErrorMessage)(t)}\n\n${e.results.summary}`}]}}}catch(e){return c({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to report test results: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleTestingReference=async function(e,t,r,n,o){return o.startTimer("tool_execution_time")({success:!0}),{content:[{type:"text",text:'# Test Process Design Guide\n\n## Overview\n\nA test process defines how to verify code changes for a project. It consists of:\n- **Setup**: Commands to prepare the environment (install deps, link node_modules, etc.) \u2014 runs once per worktree\n- **Commands**: The actual test commands (build, lint, test, etc.) \u2014 the verification steps\n\n## Command Properties\n\n- **name**: Human-readable name (e.g., "Build", "Unit Tests")\n- **command**: Shell command to run (e.g., `npm test`)\n- **required** (default: true): If a required command fails, the request won\'t be merged\n- **timeout** (default: 300s): Maximum execution time. Exit code 0 = pass, non-zero = fail.\n\n## Scope (Monorepo Support)\n\nSet `scope` to a path prefix to limit when a process runs:\n- `scope: "packages/api/"` \u2192 only runs when files under packages/api/ change\n- `scope: null` \u2192 runs for all changes (global process)\n\nMultiple active processes per project are supported.\n\n## Common Patterns\n\n### Node.js / TypeScript\n```json\n{\n "setup": ["ln -s ../../node_modules node_modules"],\n "commands": [\n { "name": "Build", "command": "npm run build" },\n { "name": "Lint", "command": "npm run lint", "required": false },\n { "name": "Unit Tests", "command": "npm test" }\n ]\n}\n```\n\n### Python\n```json\n{\n "setup": ["pip install -e \'.[dev]\'"],\n "commands": [\n { "name": "Type Check", "command": "mypy src/" },\n { "name": "Lint", "command": "ruff check .", "required": false },\n { "name": "Tests", "command": "pytest" }\n ]\n}\n```\n\n### Go\n```json\n{\n "setup": ["go mod download"],\n "commands": [\n { "name": "Build", "command": "go build ./..." },\n { "name": "Vet", "command": "go vet ./...", "required": false },\n { "name": "Tests", "command": "go test ./..." }\n ]\n}\n```\n\n### Rust\n```json\n{\n "setup": ["cargo fetch"],\n "commands": [\n { "name": "Build", "command": "cargo build" },\n { "name": "Clippy", "command": "cargo clippy -- -D warnings", "required": false },\n { "name": "Tests", "command": "cargo test" }\n ]\n}\n```\n\n## Project Analysis Checklist\n\nWhen setting up testing for a new project, check for:\n1. **package.json** \u2192 Node.js/TypeScript (check "scripts" for test/build/lint commands)\n2. **Cargo.toml** \u2192 Rust\n3. **go.mod** \u2192 Go\n4. **pyproject.toml** / **requirements.txt** \u2192 Python\n5. **Makefile** \u2192 Custom build system (check for test/build targets)\n6. **.github/workflows/** \u2192 Existing CI configuration (great source of test commands)\n7. **.gitlab-ci.yml** \u2192 GitLab CI\n8. **tsconfig.json** \u2192 TypeScript type checking\n9. **.eslintrc** / **biome.json** \u2192 Linting configuration\n10. **vitest.config.ts** / **jest.config.ts** / **pytest.ini** \u2192 Test framework configuration'}]}}
|
|
1540
1550
|
const r=t(8824),n=t(9072)},2085(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.getRequestTimelineForFile=async function(e,t,s,i){let a=`# File History: ${t}\n\n`
|
|
@@ -1663,53 +1673,53 @@ var t={}
|
|
|
1663
1673
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
1664
1674
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1665
1675
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,t,r,n,o,s,i,f){const m=s.child({tool:"move_files"}),y=Date.now()
|
|
1666
|
-
let w,b,
|
|
1667
|
-
const
|
|
1676
|
+
let w,b,I=d.FileOperationPhase.VALIDATION
|
|
1677
|
+
const k={toolName:"move-files",operationName:"write",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"move-files",metricsPrefix:"move_files",successMessage:"Successfully moved files",failureMessage:"Failed to move files"}
|
|
1668
1678
|
try{const s=d.validateArgs(e,l.MoveFilesSchema),{taskId:u,operations:h,comment:v}=s
|
|
1669
1679
|
if(m.info("Moving multiple files and directories",{taskId:u,operationCount:h.length,comment:v}),!h||0===h.length)throw Error("At least one move operation must be specified")
|
|
1670
|
-
d.validateTaskIdFormat(u,m,i,
|
|
1680
|
+
d.validateTaskIdFormat(u,m,i,k.metricsPrefix)
|
|
1671
1681
|
const C=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1672
1682
|
m.info("Initial branch context",{initialBranch:C.branch,initialRequestId:C.requestId,isMain:C.isMain})
|
|
1673
1683
|
const _=[]
|
|
1674
1684
|
for(const e of h){const{normalizedPath:r,fullPath:n}=d.validateAndNormalizePath(e.source,t),{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(e.destination,t)
|
|
1675
|
-
_.push({source:r,destination:o,fullSource:n,fullDestination:s})}
|
|
1676
|
-
const E=await d.validateTaskId(u,_[0].source,r,m,i,
|
|
1685
|
+
_.push({source:r,destination:o,fullSource:n,fullDestination:s})}I=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1686
|
+
const E=await d.validateTaskId(u,_[0].source,r,m,i,k.metricsPrefix),q=E?.requestId,S=await d.validateWorkItemStates(u,_[0].source,r,o,t,m,i,k.metricsPrefix),T=await d.autoPromoteTaskStatus(u,E.status,q,S.request?.status,_[0].source,r,o,m,i,k.metricsPrefix)
|
|
1677
1687
|
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})
|
|
1678
|
-
const P=await d.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:
|
|
1688
|
+
const P=await d.ensureCorrectWorkspaceContext({taskPromoted:T.taskPromoted,requestId:q,context:t,operation:"move-files",logger:m,metrics:i,metricsPrefix:k.metricsPrefix})
|
|
1679
1689
|
if(!P.success){if(P.isLockConflict)return{content:[{type:"text",text:"\u274c "+P.error}],isError:!0}
|
|
1680
1690
|
throw Error(P.error)}let R={hadUserMods:!1,userModsCommitHash:void 0}
|
|
1681
1691
|
if(t.git)try{m.debug("[MOVE-FILES] Checking for user changes before move operations")
|
|
1682
1692
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"move-files",{requestId:q,taskId:u,workspaceManager:t.workspaceManager},m,i)
|
|
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}),
|
|
1684
|
-
const{toolRecordId:M,localToolRecordId:j}=await d.createFileOperationRecords(u,q,t.projectId,
|
|
1685
|
-
w=M,b=M,k
|
|
1693
|
+
e.userChangesCommitted&&(m.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),m.info("User changes committed before move-files operation",{taskId:u,moveOperationsCount:_.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),R={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){m.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),m.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:u,moveOperationsCount:_.length,error:e instanceof Error?e.message:e+""})}m.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:_.length}),I=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1694
|
+
const{toolRecordId:M,localToolRecordId:j}=await d.createFileOperationRecords(u,q,t.projectId,k.recordType,_[0].source,{operationCount:h.length,operations:_.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},r,n,m,i,k.metricsPrefix,f)
|
|
1695
|
+
w=M,b=M,I=k.fileOperationPhase,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1686
1696
|
const x=[]
|
|
1687
1697
|
let O=0
|
|
1688
1698
|
for(const e of _){const t={operation:{source:e.source,destination:e.destination},success:!1}
|
|
1689
1699
|
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()
|
|
1690
1700
|
t.isDirectory=r
|
|
1691
1701
|
const n=c.default.dirname(e.fullDestination)
|
|
1692
|
-
try{await a.default.mkdir(n,{recursive:!0})}catch(e){throw Error("Failed to create destination directory: "+n)}try{throw await a.default.access(e.fullDestination),Error("Destination already exists: "+e.destination)}catch(e){if(!(e instanceof Error&&e.message.includes("ENOENT")))throw e}await a.default.rename(e.fullSource,e.fullDestination),t.success=!0,O++,m.info("Successfully moved "+(r?"directory":"file"),{source:e.source,destination:e.destination,isDirectory:r})}catch(r){t.error=(0,p.getErrorMessage)(r),m.warn(`Failed to move ${e.source} to ${e.destination}`,{error:t.error})}x.push(t)}const
|
|
1693
|
-
i.recordValue("move_files_time",
|
|
1694
|
-
let
|
|
1695
|
-
if(O>0){
|
|
1702
|
+
try{await a.default.mkdir(n,{recursive:!0})}catch(e){throw Error("Failed to create destination directory: "+n)}try{throw await a.default.access(e.fullDestination),Error("Destination already exists: "+e.destination)}catch(e){if(!(e instanceof Error&&e.message.includes("ENOENT")))throw e}await a.default.rename(e.fullSource,e.fullDestination),t.success=!0,O++,m.info("Successfully moved "+(r?"directory":"file"),{source:e.source,destination:e.destination,isDirectory:r})}catch(r){t.error=(0,p.getErrorMessage)(r),m.warn(`Failed to move ${e.source} to ${e.destination}`,{error:t.error})}x.push(t)}const D=Date.now()-y
|
|
1703
|
+
i.recordValue("move_files_time",D),i.incrementCounter("move_files_operations_total",h.length),i.incrementCounter("move_files_operations_success",O),i.incrementCounter("move_files_operations_failed",h.length-O),O===h.length?i.incrementCounter("move_files_success",1):O>0?i.incrementCounter("move_files_partial_success",1):i.incrementCounter("move_files_total_failure",1)
|
|
1704
|
+
let A=null
|
|
1705
|
+
if(O>0){I=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1696
1706
|
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}`
|
|
1697
|
-
|
|
1707
|
+
A=await d.commitToGit(u,_[0].destination,M,j,r,t,m,i,k.metricsPrefix)}I=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("move_files_phase",1,{phase:I})
|
|
1698
1708
|
const $=x.filter((e=>e.success)),F=x.filter((e=>!e.success))
|
|
1699
|
-
await d.updateFileOperationRecords(u,w,b,_[0].source,
|
|
1709
|
+
await d.updateFileOperationRecords(u,w,b,_[0].source,k.recordType,O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,{status:O===h.length?"completed":"partial_success",commitHash:A?.commitHash,previousCommitHash:A?.previousCommitHash,operationCount:h.length,successCount:O,failureCount:h.length-O,successfulOperations:$.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:F.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:R.hadUserMods,userModsCommitHash:R.userModsCommitHash},O===h.length?`Successfully moved all ${h.length} items`:`Moved ${O}/${h.length} items successfully`,r,n,m,i,k.metricsPrefix)
|
|
1700
1710
|
const N=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1701
1711
|
let L=""
|
|
1702
1712
|
if(O===h.length)L=`Successfully moved all ${h.length} ${1===h.length?"item":"items"}`
|
|
1703
1713
|
else if(O>0){const e=x.filter((e=>!e.success))
|
|
1704
1714
|
L=`Successfully moved ${O}/${h.length} items.\n\nFailed operations:\n`+e.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")}else L="All move operations failed:\n"+x.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")
|
|
1705
|
-
return
|
|
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:
|
|
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){
|
|
1708
|
-
try{await d.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",
|
|
1715
|
+
return A?.commitHash&&(L+="\nCommit: "+A.commitHash.substring(0,8)),N.requestId&&(L+="\nBranch: "+N.requestId),P.lockAcquired&&P.lockedRequestId&&(L+="\n\u{1f512} **Locked request:** "+P.lockedRequestId),{content:[{type:"text",text:L}],isError:0===O}}catch(o){if(e.taskId&&n)try{const r=o instanceof u.NotFoundError||o instanceof u.ValidationError||o instanceof h.ZodError
|
|
1716
|
+
await n.createToolRecord({...r?{}:{taskId:e.taskId},projectId:t.projectId,type:"move-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment,error:(0,p.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:I,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:"Failed to move files - "+(0,p.getErrorMessage)(o)})}catch(t){m.error("Failed to create failure record for move-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,operationCount:e.operations?.length||0})}const s=Date.now()-y
|
|
1717
|
+
if(i.recordValue("move_files_time",s),i.incrementCounter("move_files_errors",1),m.error("Error in move-files operation:",{error:(0,p.getErrorMessage)(o),time:s}),(w||b)&&e.taskId){I=d.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
1718
|
+
try{await d.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",k.recordType,"Failed to move files",{status:"failed",error:(0,p.getErrorMessage)(o),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",r,n,m,i,k.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:w,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,I,m,i,e,k)}}
|
|
1709
1719
|
const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(7478),p=t(8824)},2422(module){module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1710
1720
|
const r=t(6183),n=t(3707)
|
|
1711
1721
|
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),
|
|
1722
|
+
const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),g=t(5459),p=t(4805),f=t(260),m=t(2283),y=t(4165),w=t(7834),b=t(9373),I=t(6111),k=t(700),v=t(2783),C=t(2601),_=t(1722),E=t(7257),q=t(9230),S=t(5216),T=t(6473),P=t(4921),R=t(8850),M=t(3556),j=t(1391),x=t(6315),O=t(7713),D=t(6252),A=t(213),$=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),U=t(5247),W=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(g.def),(0,r.registerTool)(p.def),(0,r.registerTool)(f.def),(0,r.registerTool)(m.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(b.def),(0,r.registerTool)(I.def),(0,r.registerTool)(k.def),(0,r.registerTool)(v.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(E.def),(0,r.registerTool)(q.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(P.def),(0,r.registerTool)(R.def),(0,r.registerTool)(M.def),(0,r.registerTool)(j.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)($.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(L.def),(0,r.registerTool)(z.def),(0,r.registerTool)(B.def),(0,r.registerTools)(H.metaDefs),(0,r.registerTools)(U.testingDefs),(0,r.registerTools)(W.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.requestConfig=void 0,exports.areTestsRequiredForCompletion=function(){return exports.requestConfig.requireTestsForCompletion},exports.setTestsRequiredForCompletion=function(e){exports.requestConfig.requireTestsForCompletion=e},exports.getCompletionMode=function(e){return e&&["auto-merge","auto-test-then-merge","manual-review"].includes(e)?e:"auto-merge"},exports.getApprovalMode=function(e){return e&&["none","require-approval"].includes(e)?e:"none"},exports.requestConfig={requireTestsForCompletion:!1}},2537(e,exports,t){async function r(e,t,r){if(C.has(r)&&_>=t){if(0===t)return 0
|
|
1713
1723
|
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]"
|
|
1714
1724
|
let l=""
|
|
1715
1725
|
if(s||void 0===o?.lineCount||(l=` (${i(o.lineCount)} lines)`),s&&o?.subtreeTotals){const{files:e,lines:t}=o.subtreeTotals
|
|
@@ -1725,14 +1735,14 @@ if(30>s)return`${s} day${1===s?"":"s"} ago`
|
|
|
1725
1735
|
const i=Math.floor(s/30)
|
|
1726
1736
|
if(12>i)return`${i} month${1===i?"":"s"} ago`
|
|
1727
1737
|
const a=Math.floor(i/12)
|
|
1728
|
-
return`${a} year${1===a?"":"s"} ago`}(o.modified)} | ${(0,
|
|
1738
|
+
return`${a} year${1===a?"":"s"} ago`}(o.modified)} | ${(0,k.formatTimestamp)(o.modified)})`)
|
|
1729
1739
|
break
|
|
1730
1740
|
case"size":s||"number"!=typeof o.size||(l+=` (${function(e){if(0===e)return"0 bytes"
|
|
1731
1741
|
let t=e,r=0
|
|
1732
1742
|
for(;t>=1024&&4>r;)t/=1024,r++
|
|
1733
1743
|
return`${0===r?t.toString():t.toFixed(10>t?1:0)}${["bytes","KB","MB","GB","TB"][r]}`}(o.size)})`)}return`${c} ${a}${l}`}async function o(e,t,n=0,s,i,l){if(n>=s)return[]
|
|
1734
|
-
try{const{fullPath:d}=
|
|
1735
|
-
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=
|
|
1744
|
+
try{const{fullPath:d}=I.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),g=[]
|
|
1745
|
+
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=I.validateAndNormalizePath(u,t),p=await y.default.stat(h),f=d.isFile()?w.default.extname(d.name).toLowerCase():""
|
|
1736
1746
|
let m
|
|
1737
1747
|
d.isFile()&&(m=await r(h,p.size,f))
|
|
1738
1748
|
const b={name:d.name,isDirectory:d.isDirectory(),depth:n,size:p.size,modified:p.mtime,extension:f,lineCount:m}
|
|
@@ -1741,8 +1751,8 @@ const o=[]
|
|
|
1741
1751
|
return e.forEach(((i,a)=>{const c=a===e.length-1,l=c?"\u2514\u2500\u2500 ":"\u251c\u2500\u2500 ",d=n(i,t),u=i.isDirectory?"/":""
|
|
1742
1752
|
if(o.push(`${r}${l}${d}${u}`),i.children&&i.children.length>0){const e=r+(c?" ":"\u2502 "),n=s(i.children,t,e)
|
|
1743
1753
|
n&&o.push(n)}})),o.join("\n")}function i(e){return e.toLocaleString()}async function a(e,t,n){const o={files:0,directories:0,lines:0}
|
|
1744
|
-
try{const{fullPath:n}=
|
|
1745
|
-
for(const n of s)try{const s=w.default.join(e,n.name).replace(/\\/g,"/"),{fullPath:i}=
|
|
1754
|
+
try{const{fullPath:n}=I.validateAndNormalizePath(e,t),s=await y.default.readdir(n,{withFileTypes:!0})
|
|
1755
|
+
for(const n of s)try{const s=w.default.join(e,n.name).replace(/\\/g,"/"),{fullPath:i}=I.validateAndNormalizePath(s,t)
|
|
1746
1756
|
if(n.isDirectory())o.directories+=1
|
|
1747
1757
|
else{o.files+=1
|
|
1748
1758
|
const e=await y.default.stat(i),t=w.default.extname(n.name).toLowerCase(),s=await r(i,e.size,t)
|
|
@@ -1768,27 +1778,27 @@ var t={}
|
|
|
1768
1778
|
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&g(t,e,r[n])
|
|
1769
1779
|
return p(t,e),t}),m=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1770
1780
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
|
|
1771
|
-
let g=
|
|
1772
|
-
|
|
1773
|
-
try{const p=
|
|
1781
|
+
let g=I.FileOperationPhase.VALIDATION
|
|
1782
|
+
I.FileOperationPhase.FILE_WRITE
|
|
1783
|
+
try{const p=I.validateArgs(e,b.ListDirectorySchema),{path:f,levels:m=1,sortBy:k="name"}=p
|
|
1774
1784
|
i.info("Listing directory: "+f)
|
|
1775
|
-
const{normalizedPath:C,fullPath:_}=
|
|
1776
|
-
g=
|
|
1785
|
+
const{normalizedPath:C,fullPath:_}=I.validateAndNormalizePath(f,t)
|
|
1786
|
+
g=I.FileOperationPhase.FILE_WRITE
|
|
1777
1787
|
try{if(!(await y.default.stat(_)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+f}],isError:!0}
|
|
1778
1788
|
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
|
|
1779
|
-
if(m>1){i.info(`Building tree structure for: ${C} (levels: ${m}, sortBy: ${
|
|
1780
|
-
const e=await o(C,t,0,m,
|
|
1781
|
-
if(e.length>0){const t=s(e,
|
|
1789
|
+
if(m>1){i.info(`Building tree structure for: ${C} (levels: ${m}, sortBy: ${k})`)
|
|
1790
|
+
const e=await o(C,t,0,m,k,i)
|
|
1791
|
+
if(e.length>0){const t=s(e,k)
|
|
1782
1792
|
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=[]
|
|
1783
|
-
for(const n of e)try{const e=w.default.join(C,n.name).replace(/\\/g,"/"),{fullPath:s}=
|
|
1793
|
+
for(const n of e)try{const e=w.default.join(C,n.name).replace(/\\/g,"/"),{fullPath:s}=I.validateAndNormalizePath(e,t),i=await y.default.stat(s),a=n.isFile()?w.default.extname(n.name).toLowerCase():""
|
|
1784
1794
|
let c
|
|
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,
|
|
1795
|
+
n.isFile()&&(c=await r(s,i.size,a)),o.push({name:n.name,isDirectory:n.isDirectory(),depth:0,size:i.size,modified:i.mtime,extension:a,lineCount:c})}catch(e){i.debug("Excluding directory entry from listing: "+n.name,{reason:(0,v.getErrorMessage)(e)})}const s=u(o,k),a=s.map((e=>n({name:e.name,isDirectory(){return e.isDirectory},isFile(){return!e.isDirectory}},k,e)))
|
|
1786
1796
|
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
1797
|
E+="\n\nBranch: "+(S?.branchName||"unknown")
|
|
1788
1798
|
const T=Date.now()-h
|
|
1789
1799
|
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
|
|
1790
1800
|
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}}}
|
|
1791
|
-
const y=m(t(1943)),w=m(t(6928)),b=t(6183),
|
|
1801
|
+
const y=m(t(1943)),w=m(t(6928)),b=t(6183),I=f(t(5967)),k=t(3253),v=t(8824),C=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore",".config",".conf",".ini",".cfg"]),_=1048576},2568(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1792
1802
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectSynchronizer=void 0
|
|
1793
1803
|
const n=r(t(6928)),o=t(8029),s=t(8824),i=t(2096)
|
|
1794
1804
|
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)
|
|
@@ -1967,11 +1977,11 @@ const f=await Promise.all(p)
|
|
|
1967
1977
|
let m=""
|
|
1968
1978
|
if(t.getCurrentBranchContext)try{const e=await t.getCurrentBranchContext()
|
|
1969
1979
|
e.branch&&(m=`**Current Branch:** ${e.branch}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const y=f.filter((e=>e.success)).length,w=f.filter((e=>!e.success)).length,b=f.length
|
|
1970
|
-
let
|
|
1971
|
-
m&&(
|
|
1980
|
+
let I="## Read Files/Documents\n\n"
|
|
1981
|
+
m&&(I+=m),I+=`**Total Requests:** ${b} - **Successful:** ${y} - **Failed:** ${w}\n\n`
|
|
1972
1982
|
for(let e=0;e<f.length;e++){const t=f[e]
|
|
1973
|
-
"file"===t.type?
|
|
1974
|
-
return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:b,successfulReads:y,failedReads:w,success:
|
|
1983
|
+
"file"===t.type?I+=`File ${e+1}: ${t.path}\n`:(I+=`Document ${e+1}: ${t.documentId}`,t.filename&&(I+=` (${t.filename})`),I+="\n"),t.success?(I+="**Status:** Success\n",t.lineCount&&t.totalLines&&(I+=`Lines Read / Total Lines ${t.lineCount} / ${t.totalLines}\n`),t.originalRequest?.lines&&t.totalLines&&(I+=`**Lines:** ${t.originalRequest.lines}\n`),I+=`\n**Content:**\n\`\`\`\n${t.content}\n\`\`\`\n`):(I+="**Status:** Failed\n",I+=`**Error:** ${t.error}\n`),I+="\n"}const k=0===w
|
|
1984
|
+
return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:b,successfulReads:y,failedReads:w,success:k}),s.incrementCounter("read_files_total",1,{success:k}),{content:[{type:"text",text:I}],isError:!k}}catch(e){const t=Date.now()-a
|
|
1975
1985
|
return i.error("Read multiple files operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),s.incrementCounter("read_files_errors",1),{content:[{type:"text",text:"\u274c **Read Operation Failed:** "+(0,p.getErrorMessage)(e)}],isError:!0}}}
|
|
1976
1986
|
const l=c(t(1943)),d=t(6183),u=t(1569),h=a(t(5967)),g=t(9470),p=t(8824)},2968(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.TaskClient=void 0
|
|
1977
1987
|
const r=t(8824),n=t(7645),o=t(2161),s=t(5172)
|
|
@@ -2084,12 +2094,12 @@ d.info("Generating journal for request",{requestId:c})
|
|
|
2084
2094
|
const h=t.projectId
|
|
2085
2095
|
if(!h)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
|
|
2086
2096
|
o.setProjectId(h),d.info("Fetching request data, tasks, and file history in parallel")
|
|
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}),
|
|
2097
|
+
const g=o.getRequestClient(),p=o.getTaskClient(),f=o.getToolRecordClient(),[m,y,w]=await Promise.all([g.getRequest(c),p.listTasks({requestId:c}),f.getToolRecordsByRequestId(c).catch((e=>(d.warn("Failed to fetch tool records",{error:e+""}),[])))]),b=(0,s.extractDataFromResponse)(m,{logger:d,operationName:"getRequest",throwOnNoData:!0}),I="data"in b?b.data:b,k={id:I.id||c,title:I.title||"Unknown Request",description:I.description||"No description available",status:I.status||"unknown",type:I.type||"unknown",acceptanceCriteria:I.acceptanceCriteria||[],createdAt:I.createdAt||(new Date).toISOString(),updatedAt:I.updatedAt||(new Date).toISOString(),completedAt:I.completedAt},v=(0,s.extractDataFromResponse)(y,{logger:d,operationName:"listTasks",throwOnNoData:!1}),C=(Array.isArray(v)?v:"data"in v?v.data:[]).map((e=>({id:e.id,title:e.title||"Untitled Task",description:e.description||"No description",status:e.status||"unknown",createdAt:e.createdAt||(new Date).toISOString(),completedAt:e.metadata?.completedAt})))
|
|
2088
2098
|
d.info(`Fetched request, ${C.length} tasks, ${w.length} tool records`)
|
|
2089
2099
|
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()))
|
|
2090
2100
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
2091
2101
|
n.push({type:e.type,timestamp:e.createdAt,comment:s,files:o,recordId:e.localId||e.id})
|
|
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:
|
|
2102
|
+
for(const e of o)t.set(e,(t.get(e)||0)+1)}return{files:Array.from(t.entries()).map((([e,t])=>({path:e,operations:t}))).sort(((e,t)=>t.operations-e.operations)),operations:n}}(w),E={request:k,tasks:C,fileChanges:{summary:{totalFiles:_.files.length,totalOperations:_.operations.length,files:_.files},operations:_.operations},suggestedFilename:`JOURNAL-${c}.md`,metadata:{projectId:h,requestId:c,generatedAt:(new Date).toISOString()}},q=`\u2705 **Request Data Fetched Successfully!**\n\n**Request:** ${k.title} (${c})\n**Status:** ${k.status}\n**Type:** ${k.type}\n**Tasks:** ${C.length}\n**Files Changed:** ${_.files.length}\n**File Operations:** ${_.operations.length}\n\n**Data Summary:**\n\`\`\`json\n${JSON.stringify(E,null,2)}\n\`\`\`\n\n**Next Steps:**\nWrite a **compact technical narrative** and save as \`JOURNAL-${c}.md\` using document_operations (create).\n\n**Style Guide:**\n- Be concise and direct - no fluff, repetition, or unnecessary elaboration\n- Write in narrative flow connecting the changes chronologically\n- Reference files with paths: "Modified \\\`src/tools/example.ts\\\` to add X..."\n- Include operation comments inline: ("comment: 'Fix bug in parser'")\n- **Link to tool records**: Use \\\`[RECORD:trec######]\\\` format to reference operations (e.g., "Modified parser.ts [RECORD:trec004123]")\n- Show key code changes with brief snippets where they add clarity\n- Explain what changed and why, skip obvious details\n- Focus on technical substance over structure\n\n**Example:** "Modified \\\`parser.ts\\\` [RECORD:trec004123] to handle edge cases (comment: 'Fix null handling'). Added \\\`if (!input) return null;\\\` check at line 45. Then updated \\\`validator.ts\\\` [RECORD:trec004124] to use the new parser behavior..."`
|
|
2093
2103
|
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}}}
|
|
2094
2104
|
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
|
|
2095
2105
|
try{const n=await r.configManager.getEffectiveConfig(r.mainBasePath)
|
|
@@ -2209,7 +2219,7 @@ var t={}
|
|
|
2209
2219
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
2210
2220
|
return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2211
2221
|
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()
|
|
2212
|
-
let b,k
|
|
2222
|
+
let b,I,k=u.FileOperationPhase.VALIDATION
|
|
2213
2223
|
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"}
|
|
2214
2224
|
try{const i=u.validateArgs(e,d.ReplaceStringsSchema),{taskId:C,operations:_,comment:E}=i
|
|
2215
2225
|
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")
|
|
@@ -2222,20 +2232,20 @@ if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not ava
|
|
|
2222
2232
|
for(const e of S)P.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
|
|
2223
2233
|
if(P.length>0&&t.apiClient){const e=P.map((e=>e.documentId))
|
|
2224
2234
|
try{await(0,f.ensureDocumentsNotLocked)(e,t.apiClient,y,a,"replace-strings-documents")}catch(e){if(e instanceof h.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2225
|
-
throw e}}
|
|
2235
|
+
throw e}}k=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
2226
2236
|
const R=T.length>0?T[0].path:"document-operation",M=await u.validateTaskId(C,R,r,y,a,v.metricsPrefix),j=M?.requestId
|
|
2227
2237
|
let x=null
|
|
2228
2238
|
T.length>0&&j&&(x=await u.validateWorkItemStates(C,T[0].path,r,s,t,y,a,v.metricsPrefix))
|
|
2229
2239
|
let O={taskPromoted:!1,requestPromoted:!1}
|
|
2230
2240
|
T.length>0&&j&&x&&(O=await u.autoPromoteTaskStatus(C,M.status,j,x.request?.status,T[0].path,r,s,y,a,v.metricsPrefix),O.taskPromoted&&y.info("Auto-promoted task to in_progress for replace-strings operation",{taskId:C,requestId:j,previousStatus:M.status,newStatus:O.newTaskStatus,triggeringOperation:"replace-strings"}))
|
|
2231
|
-
const
|
|
2232
|
-
if(!
|
|
2233
|
-
throw Error(
|
|
2241
|
+
const D=await u.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:j,context:t,operation:"replace-strings",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
|
|
2242
|
+
if(!D.success){if(D.isLockConflict)return{content:[{type:"text",text:"\u274c "+D.error}],isError:!0}
|
|
2243
|
+
throw Error(D.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
|
|
2234
2244
|
for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=u.validateAndNormalizePath(n.path,t)
|
|
2235
2245
|
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}
|
|
2236
|
-
throw e}
|
|
2237
|
-
const
|
|
2238
|
-
if(b=$,k
|
|
2246
|
+
throw e}k=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
2247
|
+
const A=[...T.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...P.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:$}=await u.createFileOperationRecords(C,j,t.projectId,v.recordType,R,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:A,userComment:E},r,o,y,a,v.metricsPrefix,c)
|
|
2248
|
+
if(b=$,I=$,k=v.fileOperationPhase,a.incrementCounter("replace_strings_phase",1,{phase:k}),T.length>0&&t.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
|
|
2239
2249
|
const e=await(0,p.commitUserChangesBeforeToolOperation)(t.git,"replace-strings",{requestId:j,taskId:C,workspaceManager:t.workspaceManager},y,a)
|
|
2240
2250
|
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})
|
|
2241
2251
|
const F=[]
|
|
@@ -2248,17 +2258,17 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
|
|
|
2248
2258
|
r.filename=s?.filename
|
|
2249
2259
|
const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
|
|
2250
2260
|
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))
|
|
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:
|
|
2252
|
-
try{await o.updateToolRecord(
|
|
2261
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const z=await u.handleMultiFileGitCommit(C,T,F,L,{operationType:"Replace strings",toolRecordId:I,successField:"successfulReplacements",logger:y,metrics:a,metricsPrefix:"replace_strings"},t),B=u.processMultiFileOperationResults(F,"successfulReplacements"),{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J}=B
|
|
2262
|
+
try{await o.updateToolRecord(I,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:G?"completed":"failed",error:G?void 0:U+" operations failed",totalOperations:F.length,successfulFiles:V,failedFiles:J,operations:A,totalSuccessfulReplacements:W,totalFailedReplacements:N,operationsWithChanges:L,processingTime:Date.now()-w,userComment:E,...T.length>0&&z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}},note:G?`String replacement completed: ${H}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`String replacement partially failed: ${U}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}u.formatMultiFileToolResponse("String Replacement",{successfulOperations:H,failedOperations:U,totalSuccessfulChanges:W,overallSuccess:G,successfulFiles:V,failedFiles:J},z,D)
|
|
2253
2263
|
let K="## String Replacement Results\n\n"
|
|
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"),
|
|
2264
|
+
if(t.workspaceManager&&(K+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),K+="**Summary:**\n",K+=`- **Files processed:** ${H+U}\n`,K+=`- **Successful operations:** ${H}\n`,K+=`- **Failed operations:** ${U}\n`,K+=`- **Total replacements:** ${W} successful, ${N} failed\n\n`,z.success&&z.commitHash&&(K+="**Git Commit:**\n",K+=`- **Commit Hash:** ${z.commitHash.substring(0,8)}\n`,K+=`- **Files Committed:** ${z.filesCommitted.length}\n`,z.previousCommitHash&&(K+=`- **Previous Commit:** ${z.previousCommitHash.substring(0,8)}\n`),K+="\n"),D.lockAcquired&&D.lockedRequestId&&(K+=`\u{1f512} **Locked request:** ${D.lockedRequestId}\n\n`),1===F.length){const e=F[0]
|
|
2255
2265
|
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"
|
|
2256
2266
|
for(const t of e.replacements.filter((e=>!e.success)))K+=`- "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}}else{K+="**Summary:**\n",K+=`- **Total Operations:** ${F.length}\n`,K+=`- **Successful:** ${H}\n`,K+=`- **Failed:** ${U}\n`,K+=`- **Total Replacements:** ${W} successful, ${N} failed\n\n`,K+="**Detailed Results:**\n\n"
|
|
2257
2267
|
for(const e of F){if("file"===e.type?K+=`### File: ${e.path}\n`:(K+="### Document: "+e.documentId,e.filename&&(K+=` (${e.filename})`),K+="\n"),K+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error?K+=`- **Error:** ${e.error}\n`:(K+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(K+=`, ${e.failedReplacements} failed`),K+="\n"),e.replacements.some((e=>!e.success))){K+="- **Failed Replacement Details:**\n"
|
|
2258
2268
|
for(const t of e.replacements.filter((e=>!e.success)))K+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}K+="\n"}}P.length>0&&(K+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
2259
2269
|
const Y=Date.now()-w
|
|
2260
2270
|
return y.info("Replace strings operation completed",{duration:Y,success:G,totalOperations:F.length,successfulOperations:H,failedOperations:U}),a.incrementCounter("replace_strings_total",1,{success:G}),{content:[{type:"text",text:K}],isError:!G}}catch(t){const r=Date.now()-w
|
|
2261
|
-
if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:
|
|
2271
|
+
if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_strings_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
2262
2272
|
const l=c(t(1943)),d=t(6183),u=a(t(5967)),h=t(9860),g=t(5003),p=t(7478),f=t(9949),m=t(8824)},3322(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
2263
2273
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
2264
2274
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
|
|
@@ -2342,40 +2352,16 @@ exports.defaultLogger=o.default
|
|
|
2342
2352
|
const s=t(6540)
|
|
2343
2353
|
Object.defineProperty(exports,"LogLevel",{enumerable:!0,get(){return s.LogLevel}}),exports.default=o.default},3556(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2344
2354
|
const r=t(6183),n=t(8317)
|
|
2345
|
-
exports.def={name:"request_file_history",description:"Get file change history for an entire request. Supports summary mode (net diffs) or detailed mode (chronological operations). Can be filtered to specific task. Use query_history tool instead.",schema:r.QueryHistorySchema,annotations:{title:"Request File History",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleRequestFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}},
|
|
2346
|
-
try{const{requestId:n}=e
|
|
2347
|
-
if(!n)throw(0,r.createValidationError)("Request ID is required")
|
|
2348
|
-
let o,c
|
|
2349
|
-
d.info("Starting request finalization",{requestId:n})
|
|
2350
|
-
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{})
|
|
2351
|
-
o=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2352
|
-
return d.error("Server validation failed",{requestId:n,error:t}),u({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate finalization: "+t}],isError:!0}}if(!o.canComplete){let e=`Cannot finalize request ${n}: ${o.reason}\n`
|
|
2353
|
-
return o.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\n",o.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (${t.status})\n`}))),u({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(!t.workspaceManager)throw Error("WorkspaceManager not available for request finalization")
|
|
2354
|
-
let l="workspace-manager"
|
|
2355
|
-
try{const e=a.getRequestClient(),r=await e.getRequest(n),o=r?.title||"Request "+n
|
|
2356
|
-
if("conflicted"===r?.status){d.info("Request is conflicted, attempting fast-path merge",{requestId:n})
|
|
2357
|
-
const e=t.workspaceManager.getCurrentContext()
|
|
2358
|
-
let r=e?.basePath||process.cwd()
|
|
2359
|
-
if("multi-agent"===e?.mode)try{const e=await t.workspaceManager.getWorktreeInfo(n)
|
|
2360
|
-
e?.worktreePath&&(r=e.worktreePath)}catch{}const i=(0,s.createConflictResolutionManager)(d,a,r,t.git),h=await i.validateMarkersRemoved(n)
|
|
2361
|
-
if(!h.resolved)return u({success:!1,reason:"conflicts_unresolved"}),{content:[{type:"text",text:`## \u26a0\ufe0f Conflicts Still Need Resolution\n\nConflict markers still exist in:\n\n${h.remainingConflicts.map((e=>`- \`${e}\``)).join("\n")}\n\nRemove all conflict markers and try again.`}]}
|
|
2362
|
-
const g=await i.hasMainBranchChanged(n)
|
|
2363
|
-
g.hasChanged&&g.canDetermine?(d.info("Main branch changed since conflict detection, using full merge",{requestId:n,originalHash:g.originalHash?.substring(0,8),currentHash:g.currentHash?.substring(0,8)}),c=await t.workspaceManager.completeRequest(n,o),l=c.autoMergeInfo?.strategy||"main-changed-remerge"):(c=await t.workspaceManager.completeRequest(n,o,{skipConflictDetection:!0}),l="conflict-fast-path",d.info("Conflict fast-path merge completed",{requestId:n,mergeCommitHash:c.mergeCommitHash}))}else c=await t.workspaceManager.completeRequest(n,o),l=c.autoMergeInfo?.strategy||"workspace-manager",d.info("Merge completed",{requestId:n,mergeCommitHash:c.mergeCommitHash,cleanedUp:c.cleanedUp})}catch(e){if(e.conflictInfo){const r=e.conflictInfo,n=r.workingDirectory||t.workspaceManager?.getCurrentContext()?.basePath||process.cwd(),o=(0,s.createConflictResolutionManager)(d,a,n,t.git),i=await o.handleConflicts(r)
|
|
2364
|
-
return u({success:!1,reason:"merge_conflicts"}),{content:[{type:"text",text:i.userMessage}],isError:!1}}const r=(0,i.getErrorMessage)(e)
|
|
2365
|
-
return u({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Request finalization failed during merge: "+r}],isError:!0}}try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${n}/finalize-completion`,{summary:"Finalized request "+n,acceptanceEvidence:[{evidence:"Finalized after review"}],mergeResult:{mergeCommitHash:c.mergeCommitHash,mergedFiles:c.mergedFiles,cleanedUp:c.cleanedUp,method:l}})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2366
|
-
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:n,mergeCommitHash:c.mergeCommitHash,error:t}),u({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${c.mergeCommitHash.substring(0,8)}) but failed to update server state: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:"Request finalized: "+n}]}}catch(r){let s="An unexpected error occurred"
|
|
2367
|
-
r instanceof n.ZodError?s=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", "):r instanceof Error&&(s=r.message),d.error("Finalize request failed",{error:s})
|
|
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}}}
|
|
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}}
|
|
2355
|
+
exports.def={name:"request_file_history",description:"Get file change history for an entire request. Supports summary mode (net diffs) or detailed mode (chronological operations). Can be filtered to specific task. Use query_history tool instead.",schema:r.QueryHistorySchema,annotations:{title:"Request File History",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleRequestFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}},3611(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2370
2356
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
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),
|
|
2357
|
+
const n=r(t(6928)),o=r(t(7252)),s=r(t(8577)),i=t(184),a=t(1213),c=t(3444),l=t(9955),d=t(5218),u=t(2568),h=t(3102),g=t(1152),p=t(3884),f=t(7888),m=t(4139),y=t(6800),w=t(6539),b=t(8824),I=t(6975),k=t(1253),v=process.argv.slice(2),C=v[0]||process.cwd(),_=n.default.resolve(C),E=parseInt(process.env.LOCAL_SERVER_PORT||v[1]||"3002",10),q=(0,c.createEnvLogger)({serviceName:"mcp-http-server"});(0,c.isDebugToolsEnabled)()?q.info("HTTP server initializing",{baseDir:_,preferredPort:E,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL}):q.info("HTTP server starting",{port:E})
|
|
2372
2358
|
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")
|
|
2373
2359
|
q.info("Using remote server URL",{remoteServerUrl:T}),async function(){try{q.info("Finding available port...",{preferredPort:E,baseDir:_,remoteServerUrl:T})
|
|
2374
2360
|
const e=await(0,y.findAvailablePort)(E)
|
|
2375
2361
|
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
2362
|
const t=new l.ProjectRegistry(q),r=new h.DefaultProjectFileSystem(q),c=n.default.join(_,m.ALCHEMY_DIR_NAME)
|
|
2377
2363
|
q.info(`Checking ${m.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensureDirectoryExists(c)
|
|
2378
|
-
const g=new
|
|
2364
|
+
const g=new k.TokenManager(q,n.default.join(c,"auth-token.json")),v=(await w.ClientFactory.createClient(T,q,S,{tokenManager:g,workingDir:_,alchemyPath:c})).projectClient,C=new I.ProjectClientAdapter(v,q),P=new u.ProjectSynchronizer(q,t,C,r),R=await P.getOrCreateProject(_,{name:n.default.basename(_)||"Local Project",description:"Project for "+n.default.basename(_),status:"active",metadata:{basePath:_,alchemyPath:c,bootstrapped:!0}})
|
|
2379
2365
|
q.info("Using project",{projectId:R.id,projectName:R.name})
|
|
2380
2366
|
const M=(0,o.default)()
|
|
2381
2367
|
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))
|
|
@@ -2478,18 +2464,18 @@ try{const a=u.validateArgs(e,d.GetFileInfoSchema),{path:h}=a
|
|
|
2478
2464
|
n.info("Getting file info: "+h)
|
|
2479
2465
|
const{normalizedPath:f,fullPath:m}=u.validateAndNormalizePath(h,t)
|
|
2480
2466
|
i=u.FileOperationPhase.FILE_WRITE
|
|
2481
|
-
try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+h)}const y=await c.default.stat(m),w=y.isFile()?l.default.extname(m).slice(1):"",b={path:f,type:y.isDirectory()?"directory":"file",size:y.size,sizeFormatted:(p=y.size,u.formatFileSize(p)),created:r(y.birthtime),modified:r(y.mtime),accessed:r(y.atime),permissions:(g=y.mode,(511&g).toString(8)),isDirectory:y.isDirectory(),isFile:y.isFile(),isSymbolicLink:y.isSymbolicLink(),extension:w},
|
|
2482
|
-
b.isFile&&w&&
|
|
2483
|
-
const
|
|
2484
|
-
return o.recordValue("get_file_info_time",
|
|
2467
|
+
try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+h)}const y=await c.default.stat(m),w=y.isFile()?l.default.extname(m).slice(1):"",b={path:f,type:y.isDirectory()?"directory":"file",size:y.size,sizeFormatted:(p=y.size,u.formatFileSize(p)),created:r(y.birthtime),modified:r(y.mtime),accessed:r(y.atime),permissions:(g=y.mode,(511&g).toString(8)),isDirectory:y.isDirectory(),isFile:y.isFile(),isSymbolicLink:y.isSymbolicLink(),extension:w},I=["File Information for: "+f,"Type: "+b.type,`Size: ${b.sizeFormatted} (${b.size} bytes)`,"Created: "+b.created,"Modified: "+b.modified,"Accessed: "+b.accessed,"Permissions: "+b.permissions,"Is Directory: "+b.isDirectory,"Is File: "+b.isFile,"Is Symbolic Link: "+b.isSymbolicLink]
|
|
2468
|
+
b.isFile&&w&&I.push("Extension: "+w)
|
|
2469
|
+
const k=Date.now()-s
|
|
2470
|
+
return o.recordValue("get_file_info_time",k),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+f,{type:b.type,size:b.size,time:k}),{content:[{type:"text",text:I.join("\n")}]}}catch(t){const r=Date.now()-s
|
|
2485
2471
|
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}
|
|
2486
2472
|
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(),
|
|
2488
|
-
f.info("Starting quick_edit workflow",{title:
|
|
2473
|
+
try{const y=u.getRequestClient(),w=u.getTaskClient(),b=u.getFileClient(),I=u.getToolRecordClient(),{title:k,description:v,...C}=e,_=e.comment||k
|
|
2474
|
+
f.info("Starting quick_edit workflow",{title:k,operationType:t})
|
|
2489
2475
|
let E=!1
|
|
2490
2476
|
try{const e=await y.listRequests({limit:2,sortBy:"created_at",sortDirection:"desc"})
|
|
2491
2477
|
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:
|
|
2478
|
+
const q=await y.createRequest({title:k,description:v,type:"quick-edit",acceptanceCriteria:["Quick change completed successfully"]})
|
|
2493
2479
|
if(!q||!q.id)throw Error("Failed to create request")
|
|
2494
2480
|
const S=q.id
|
|
2495
2481
|
let T
|
|
@@ -2497,23 +2483,24 @@ f.info("Created request",{requestId:S})
|
|
|
2497
2483
|
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
2484
|
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
2485
|
f.debug("Creating task")
|
|
2500
|
-
const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+
|
|
2486
|
+
const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+k})
|
|
2501
2487
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2502
|
-
let
|
|
2503
|
-
if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{operationType:t}),"write"===t)
|
|
2504
|
-
else if("replace"===t)
|
|
2488
|
+
let v
|
|
2489
|
+
if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{operationType:t}),"write"===t)v=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,b,w,I,y,h,g,p)
|
|
2490
|
+
else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,I,y,h,g,p)
|
|
2505
2491
|
else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
|
|
2506
|
-
|
|
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${
|
|
2508
|
-
|
|
2509
|
-
try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${
|
|
2492
|
+
v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||k},d,w,I,y,u,h,g,p)}if(v.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
|
|
2493
|
+
try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after operation failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after operation failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${v.content[0].text}\n\nThe request (${S}) and task have been canceled and cleaned up.`}],isError:!0}}const q=v.content[0].text,P=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
|
|
2494
|
+
P?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
|
|
2495
|
+
try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${k}${P?" (partial success)":""}`},d,u,h,g),f.info("Task completed successfully",{taskId:T})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
|
|
2510
2496
|
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
|
|
2512
|
-
let
|
|
2513
|
-
try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:
|
|
2514
|
-
e.isError
|
|
2515
|
-
|
|
2516
|
-
|
|
2497
|
+
const R=P?`Quick change completed with partial success: ${k}. Some replacements failed - see details below.`:"Quick change completed: "+k,M=P?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
|
|
2498
|
+
let j=!1
|
|
2499
|
+
try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:R,acceptanceEvidence:[{evidence:M}],testVerification:void 0},d,u,h,g,p)
|
|
2500
|
+
if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text})
|
|
2501
|
+
else{try{await y.updateRequest(S,{status:"completed",completionSummary:R}),f.info("Request finalized to completed",{requestId:S})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:S,error:(0,l.getErrorMessage)(e)})}j=!0,f.info("Request completed successfully",{requestId:S})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:S,error:e instanceof Error?e.message:e+""})}if(!j)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:R}),j=!0,f.info("Request completed successfully via direct API call",{requestId:S})}catch(e){return f.error("Direct request completion also failed",{requestId:S,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${S}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const x=Date.now()-m
|
|
2502
|
+
let O
|
|
2503
|
+
return f.info("Quick fix completed",{requestId:S,duration:x,hasPartialFailure:P}),O=P?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${k}\n**Operation:** ${t}\n**Duration:** ${x}ms\n**Status:** Some operations succeeded, some failed\n\nThe successful changes have been applied and automatically merged to main.\n**Active branch:** main\n\n**\u26a0\ufe0f Note:** This quick-fix had partial failures. See operation details below:\n\n`+q:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${k}\n**Operation:** ${t}\n**Duration:** ${x}ms\n\nThe change has been applied and automatically merged to main.\n**Active branch:** main`+(q.match(/\[RECORD:trec\d{6}\]/)?.[0]?"\n"+q.match(/\[RECORD:trec\d{6}\]/)?.[0]:""),E&&(O+="\n\n\u{1f4a1} **Recommendation:** You've created several quick-edits in a row. For better traceability and organization, consider creating a proper feature or bugfix request with multiple tasks for your next change."),{content:[{type:"text",text:O}]}}catch(e){if(f.error("Quick change workflow failed after request creation, cleaning up",{requestId:S,error:(0,l.getErrorMessage)(e)}),T)try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after workflow failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after workflow failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after workflow failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}throw e}}catch(e){const t=Date.now()-m
|
|
2517
2504
|
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
2505
|
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
2506
|
const r=t(9860),n=t(5674)
|
|
@@ -2586,18 +2573,18 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2586
2573
|
var t={}
|
|
2587
2574
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2588
2575
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
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"),
|
|
2590
|
-
let
|
|
2576
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleWriteFile=async function(e,t,r,n,o,s,i,m,y){const w=i.child({tool:"write_file"}),b=m.startTimer("tool_execution_time"),I=Date.now()
|
|
2577
|
+
let k,v,C=d.FileOperationPhase.VALIDATION
|
|
2591
2578
|
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
2579
|
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
2580
|
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
|
-
let j,x,O,
|
|
2581
|
+
let j,x,O,D="",A=!1,$=!1
|
|
2595
2582
|
const F=M?f:void 0
|
|
2596
2583
|
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
2584
|
throw e}if(!t.documentFileManager)throw Error("Document file manager not available")
|
|
2598
|
-
|
|
2585
|
+
D=await t.documentFileManager.getDocumentAsFile(E)
|
|
2599
2586
|
const e=t.documentFileManager.getCachedDocumentInfo(E)
|
|
2600
|
-
O=e?.filename,$=!0,
|
|
2587
|
+
O=e?.filename,$=!0,A=!1}C=d.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("write_file_phase",1,{phase:C})
|
|
2601
2588
|
const N=M?F:"document:"+E,L=await d.validateTaskId(i,N,n,w,m,_.metricsPrefix),z=L?.requestId
|
|
2602
2589
|
let B=null
|
|
2603
2590
|
M&&z&&(B=await d.validateWorkItemStates(i,N,n,s,t,w,m,_.metricsPrefix))
|
|
@@ -2606,30 +2593,30 @@ M&&z&&B&&(H=await d.autoPromoteTaskStatus(i,L.status,z,B.request?.status,N,n,s,w
|
|
|
2606
2593
|
const U=await d.ensureCorrectWorkspaceContext({taskPromoted:H.taskPromoted,requestId:z,context:t,operation:"write_file",logger:w,metrics:m,metricsPrefix:_.metricsPrefix,requireRequestContext:M})
|
|
2607
2594
|
if(!U.success){if(U.isLockConflict)return{content:[{type:"text",text:"\u274c "+U.error}],isError:!0}
|
|
2608
2595
|
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
|
-
j=e.normalizedPath,x=e.fullPath,
|
|
2610
|
-
try{await c.default.access(x),$=!0}catch{$=!1,
|
|
2596
|
+
j=e.normalizedPath,x=e.fullPath,D=x
|
|
2597
|
+
try{await c.default.access(x),$=!0}catch{$=!1,A=!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
2598
|
throw e}C=d.FileOperationPhase.RECORD_CREATION,m.incrementCounter("write_file_phase",1,{phase:C})
|
|
2612
2599
|
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
2600
|
let G
|
|
2614
|
-
if(
|
|
2601
|
+
if(k=W,v=W,C=_.fileOperationPhase,m.incrementCounter("write_file_phase",1,{phase:C}),"json"===S)if("string"==typeof q)try{JSON.parse(q),G=q}catch(e){throw new u.ValidationError("Content is not valid JSON")}else G=JSON.stringify(q,null,2)
|
|
2615
2602
|
else G="string"==typeof q?q:JSON.stringify(q,null,2)
|
|
2616
2603
|
let V=G
|
|
2617
2604
|
if(M&&t.git)try{w.debug("[WRITE-FILE] Checking for user changes before write operation")
|
|
2618
2605
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"write_file",{requestId:t.workspaceManager?.getCurrentContext()?.requestId,taskId:i},w,m)
|
|
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(!
|
|
2620
|
-
if(w.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:
|
|
2621
|
-
if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile(
|
|
2606
|
+
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(!D)throw Error("Target path not properly initialized")
|
|
2607
|
+
if(w.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:D}),T&&$)try{V=await c.default.readFile(D,"utf8")+G}catch(e){w.warn("Failed to read existing content for append",{error:e})}const J=a.default.dirname(D)
|
|
2608
|
+
if(await c.default.mkdir(J,{recursive:!0}),await c.default.writeFile(D,V,"utf8"),w.info("Content written successfully",{path:M?j:"document:"+E,finalLength:V.length,append:T,wasCreated:A}),R){t.documentFileManager.markForSync(E)
|
|
2622
2609
|
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
2610
|
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=`${
|
|
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:
|
|
2611
|
+
Y=e.branchName,w.debug("Retrieved branch name from workspace manager",{branchName:Y,requestId:e.requestId,mode:e.mode,isMainBranch:e.isMainBranch})}try{const e=`${A?"Create":T?"Append to":"Update"} ${j} (${v})`,r=await d.commitToGit(i,j,v,v,e,t,w,m,_.metricsPrefix)
|
|
2612
|
+
K=r.commitHash,Q=r.previousCommitHash,w.info("Changes committed to git via shared utility",{path:j,commitMessage:e,commitHash:K?.substring(0,8),previousCommitHash:Q?.substring(0,8),branchName:Y,toolRecordId:v})}catch(e){w.warn("Git operations failed via shared utility",{error:e})}}try{await o.updateToolRecord(v,{metadata:{path:M?j:"document:"+E,status:"completed",finalContentLength:V.length,wasFileCreated:A,wasAppended:T&&$,operationType:R?"document":"file",processingTime:Date.now()-I,userComment:P,...M&&K&&{commitHash:K,previousCommitHash:Q||void 0}},note:"Write operation completed successfully"+(R?" (document synced)":" (committed to git)")})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z=`**${A?"Created":T?"Appended to":"Updated"} ${R?`document ${E}${O?` (${O})`:""}`:"file "+j}**\n`
|
|
2626
2613
|
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
2614
|
const X=Date.now()
|
|
2628
|
-
return w.info("Write operation completed successfully",{duration:X-
|
|
2615
|
+
return w.info("Write operation completed successfully",{duration:X-I,path:M?j:"document:"+E,contentLength:V.length,wasCreated:A}),b({tool:"write_file",success:!0}),m.incrementCounter("write_file_total",1,{success:!0}),t.workspaceManager?.largeFileWarning&&(Z+=t.workspaceManager.largeFileWarning,t.workspaceManager.largeFileWarning=""),{content:[{type:"text",text:Z}]}}catch(t){const r=Date.now()-I
|
|
2629
2616
|
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
2617
|
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
2618
|
const r=t(6183),n=t(4648)
|
|
2632
|
-
exports.def={name:"request_operations",description:"Perform operations on existing requests.\n\nOperations:\n\u2022 complete -
|
|
2619
|
+
exports.def={name:"request_operations",description:"Perform operations on existing requests.\n\nOperations:\n\u2022 complete - Begin completion: provide summary, get criteria keys for verification\n\u2022 verify-criteria - Verify acceptance criteria with evidence per key (triggers merge when all verified)\n\u2022 finalize - Approve and merge a request that is ready for review\n\u2022 approve - Approve a pending request so work can begin\n\u2022 revert - Completely revert a completed request, undoing all changes\n\u2022 get-info - Get comprehensive request information\n\u2022 list - List and filter requests\n\nCompletion is two-phase: first call complete with a summary, then call verify-criteria with evidence for each criterion key.\n\nNote: To create a new request, use the separate create-request tool.",schema:r.RequestOperationsSchema,annotations:{title:"Request Operations",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleRequestOperations)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},4192(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.BaseApiClient=void 0
|
|
2633
2620
|
const r=t(7163)
|
|
2634
2621
|
exports.BaseApiClient=class{constructor(e,t,n,o,s){this.failureCount=0,this.circuitState="closed",this.circuitResetTimeout=null,this.baseUrl=e,this.logger=t,this.metrics=n,this.authToken=o,this.options={retryAttempts:3,retryDelay:1e3,timeout:1e4,circuitBreakerThreshold:5,circuitBreakerResetTime:3e4,...s},this.logger.debug("BaseApiClient constructor options:",{providedOptions:s?JSON.stringify(s):"undefined",mergedOptions:JSON.stringify(this.options)})
|
|
2635
2622
|
try{(0,r.debugTokenAccess)(this,"BaseApiClient constructor")}catch(e){}}setAuthToken(e){this.authToken=e||void 0,this.logger.debug("Auth token updated",{hasToken:!!e,tokenLength:e?e.length:0})}getAuthToken(){return this.authToken}async requestWithRetry(e,t,r,n,o){if("open"===this.circuitState)throw this.logger.warn(`Circuit breaker open - rejecting request to ${e} ${t}`),Error("Service unavailable - circuit breaker open")
|
|
@@ -2690,7 +2677,26 @@ if(!h)return{content:[{type:"text",text:"\u274c Unsupported image type: ."+u}],i
|
|
|
2690
2677
|
if("svg"===u)return{content:[{type:"text",text:`**Asset: ${r}**\n\n\`\`\`svg\n${await i.readFile(c,"utf-8")}\n\`\`\``}]}
|
|
2691
2678
|
const g=await i.readFile(c),p=g.toString("base64")
|
|
2692
2679
|
return o.info("Asset viewed",{filename:r,size:g.length}),{content:[{type:"text",text:`**Asset: ${r}** (${(g.length/1024).toFixed(1)} KB)`},{type:"image",data:p,mimeType:h}]}}catch(e){return o.error("Failed to view asset",{error:(0,c.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to view asset:** "+(0,c.getErrorMessage)(e)}],isError:!0}}}
|
|
2693
|
-
const i=s(t(1943)),a=s(t(6928)),c=t(8824),l=t(4139),d={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml"}},
|
|
2680
|
+
const i=s(t(1943)),a=s(t(6928)),c=t(8824),l=t(4139),d={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml"}},4306(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMergeRequest=async function(e,t,i,a,c){const l=a.child({tool:"merge_request"}),d=c.startTimer("tool_execution_time"),{requestId:u,verifications:h}=e
|
|
2681
|
+
try{if(!u)throw(0,r.createValidationError)("requestId is required")
|
|
2682
|
+
l.info("Starting merge request",{requestId:u,verificationCount:h.length})
|
|
2683
|
+
const e=i.getRequestClient(),o=await e.getRequest(u)
|
|
2684
|
+
if("ready_for_review"===o?.status)return d({success:!1,reason:"testing_in_progress"}),{content:[{type:"text",text:`STOP: Cannot merge request ${u} \u2014 testing is in progress. Wait for tests to complete. The request will be moved to ready_for_merge when tests pass.`}],isError:!0}
|
|
2685
|
+
if(h.length>0)try{await i.proxyPost(`/api/projects/${t.projectId}/requests/${u}/verify-criteria`,{verifications:h}),l.info("Criteria verified",{requestId:u,count:h.length})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
2686
|
+
l.warn("Criteria verification failed, continuing with merge",{requestId:u,error:t})}let a,c
|
|
2687
|
+
try{const e=await i.proxyPost(`/api/projects/${t.projectId}/requests/${u}/validate-completion`,{})
|
|
2688
|
+
a=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
2689
|
+
return d({success:!1,error:"validation_failed"}),{content:[{type:"text",text:"Failed to validate merge: "+t}],isError:!0}}if(!a.canComplete){let e=`Cannot merge request ${u}: ${a.reason}\n`
|
|
2690
|
+
return a.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\n",a.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (${t.status})\n`}))),d({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(!t.workspaceManager)throw Error("WorkspaceManager not available")
|
|
2691
|
+
let g="workspace-manager"
|
|
2692
|
+
const p=await e.getRequest(u),f=p?.title||"Request "+u,m="resolving_conflicts"===p?.status
|
|
2693
|
+
try{m?(l.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:u}),c=await t.workspaceManager.completeRequest(u,f,{skipConflictDetection:!0}),g="retry-theirs"):(c=await t.workspaceManager.completeRequest(u,f),g=c.autoMergeInfo?.strategy||"workspace-manager"),l.info("Merge completed",{requestId:u,mergeCommitHash:c.mergeCommitHash,mergeMethod:g})}catch(r){if(r.conflictInfo){const o=r.conflictInfo,a=o.workingDirectory||t.workspaceManager?.getCurrentContext()?.basePath||process.cwd(),c=(0,n.createConflictResolutionManager)(l,i,a,t.git),h=await c.handleConflicts(o)
|
|
2694
|
+
try{await e.updateRequest(u,{status:"resolving_conflicts"}),l.info("Set status to resolving_conflicts",{requestId:u})}catch(e){l.error("Failed to set resolving_conflicts status",{requestId:u,error:(0,s.getErrorMessage)(e)})}return d({success:!1,reason:"merge_conflicts"}),{content:[{type:"text",text:h.userMessage}],isError:!1}}const o=(0,s.getErrorMessage)(r)
|
|
2695
|
+
return d({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Merge failed: "+o}],isError:!0}}try{await i.proxyPost(`/api/projects/${t.projectId}/requests/${u}/finalize-completion`,{summary:p?.completionSummary||"Merged request "+u,acceptanceEvidence:h.map((e=>({evidence:e.evidence}))),mergeResult:{mergeCommitHash:c.mergeCommitHash,mergedFiles:c.mergedFiles,cleanedUp:c.cleanedUp,method:g}})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
2696
|
+
return l.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:u,mergeCommitHash:c.mergeCommitHash,error:t}),d({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${c.mergeCommitHash.substring(0,8)}) but failed to update server: ${t}`}],isError:!0}}return d({success:!0}),{content:[{type:"text",text:`Request ${u} merged successfully.\nCommit: ${c.mergeCommitHash.substring(0,8)}`}]}}catch(e){const r=(0,s.getErrorMessage)(e)
|
|
2697
|
+
l.error("Merge request failed",{error:r})
|
|
2698
|
+
try{await(0,o.createFailureToolRecord)("merge-request",e,{error:r,requestId:u},i.getToolRecordClient(),l,c,{requestId:u,projectId:t.projectId,note:"Failed to merge request"})}catch{}return d({success:!1,error:e instanceof Error?e.name:"unknown"}),{content:[{type:"text",text:"Error: "+r}],isError:!0}}}
|
|
2699
|
+
const r=t(9860),n=t(1651),o=t(8616),s=t(8824)},4394(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.getOrCreateHealthCheckManager=function(e,t,o,s={}){const i=e.endsWith("/")?e.slice(0,-1):e,a=n.get(i)
|
|
2694
2700
|
if(a)return t.debug("Reusing existing HealthCheckManager instance",{baseUrl:i,totalInstances:n.size}),a
|
|
2695
2701
|
t.info("Creating new HealthCheckManager instance",{baseUrl:i,totalInstancesBefore:n.size})
|
|
2696
2702
|
const c=new r.HealthCheckManager(i,t,o,{checkIntervalMs:s.checkIntervalMs||3e4,timeoutMs:s.timeoutMs||5e3,retryCount:s.retryCount||2,onOfflineCallback:s.onOfflineCallback,onOnlineCallback:s.onOnlineCallback})
|
|
@@ -2730,7 +2736,7 @@ var t={}
|
|
|
2730
2736
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2731
2737
|
return o(t,e),t})
|
|
2732
2738
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlannerOps=async function(e,t,r,n,o,s){const h=r.child({tool:"planner_ops"}),g=n.startTimer("tool_execution_time")
|
|
2733
|
-
try{"request"===e?.operation&&e?.prompt&&!e?.request&&(e.request={prompt:e.prompt,description:e.description||e.prompt.slice(0,60)},delete e.prompt,delete e.description)
|
|
2739
|
+
try{if(e?.request&&"string"==typeof e.request)try{e.request=JSON.parse(e.request)}catch{}"request"===e?.operation&&e?.prompt&&!e?.request&&(e.request={prompt:e.prompt,description:e.description||e.prompt.slice(0,60)},delete e.prompt,delete e.description)
|
|
2734
2740
|
const r=c.validateArgs(e,a.PlannerOpsSchema),{operation:p,sessionId:f}=r
|
|
2735
2741
|
let m
|
|
2736
2742
|
switch(h.info("Processing planner_ops",{operation:p,sessionId:f}),p){case"request":{const e=await async function(e,t,r){if(!e)return"ask"
|
|
@@ -2777,10 +2783,10 @@ try{let o
|
|
|
2777
2783
|
try{o=i.FileRecoverSchema.parse(e)}catch(t){if(t instanceof a.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
|
|
2778
2784
|
return p.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{taskId:f,path:y,commitHash:w,createBackup:b}=o
|
|
2779
2785
|
return p.info("Recovering file to previous version",{taskId:f,filePath:y,commitHash:w,createBackup:b}),await async function(e,t,r,n,o,s,i,a,g,p,f){let m
|
|
2780
|
-
try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),b=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:
|
|
2781
|
-
m=
|
|
2782
|
-
let
|
|
2783
|
-
try{await l.access(w),v=!0,n&&(
|
|
2786
|
+
try{const{normalizedPath:y,fullPath:w}=d.validateAndNormalizePath(t,o),b=await d.validateTaskId(e,y,s.getTaskClient(),a,g,"file-recover"),{toolRecordId:I}=await d.createFileOperationRecords(e,b?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),i,a,g,"file-recover",f)
|
|
2787
|
+
m=I
|
|
2788
|
+
let k,v=!1
|
|
2789
|
+
try{await l.access(w),v=!0,n&&(k=`${w}.backup-${(new Date).toISOString().replace(/[:.]/g,"-")}`,await l.copyFile(w,k),a.info("Created backup",{originalPath:w,backupPath:k}))}catch{v=!1}const C=o.git
|
|
2784
2790
|
if(!C)throw Error("Git is not available")
|
|
2785
2791
|
if(!(await(0,u.validateCommitHash)(C,r,a,"file-recover")).valid)throw Error(`Commit hash '${r}' is invalid or not found`)
|
|
2786
2792
|
let _
|
|
@@ -2789,32 +2795,29 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
|
|
|
2789
2795
|
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await l.writeFile(w,_,"utf8")
|
|
2790
2796
|
let E={}
|
|
2791
2797
|
try{const t=`Recover ${y} from ${r.substring(0,8)}`
|
|
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:
|
|
2798
|
+
E=await d.commitToGit(e,y,m,m,t,o,a,g,"file-recover"),a.info("Recovery committed via shared utility",{path:y,sourceCommitHash:r,newCommitHash:E.commitHash?.substring(0,8),commitMessage:t})}catch(e){a.warn("Failed to commit recovery via shared utility",{error:e})}if(m)try{await i.updateToolRecord(m,{metadata:{path:y,status:"completed",recoveredLength:_.length,hadBackup:n&&v,backupPath:k,wasFileCreated:!v,processingTime:Date.now()-p,...E.commitHash&&{commitHash:E.commitHash,previousCommitHash:E.previousCommitHash||void 0}},note:"File recovered successfully from "+r.substring(0,8)})}catch(e){a.warn("Failed to update tool record",{recordError:e})}const q=v?"recovered":"created from recovery"
|
|
2793
2799
|
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:** ${_.length} characters\n`,n&&v&&
|
|
2800
|
+
return S+=`**File:** ${y}\n`,S+=`**Recovered from:** ${r.substring(0,8)}\n`,S+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(S+=`**Backup created:** ${c.basename(k)}\n`),S+="**Git status:** Recovery committed\n",S+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",a.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-p}),g.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:S}]}}catch(e){throw e}}(f,y,w,b,t,r,n,p,s,m,g)}catch(e){const t=Date.now()-m
|
|
2795
2801
|
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
2802
|
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
|
-
try{"complete"===e?.operation&&e?.summary&&!e?.complete&&(e.complete={summary:e.summary,
|
|
2798
|
-
const d=e
|
|
2799
|
-
|
|
2800
|
-
const
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
const e={requestId:y}
|
|
2807
|
-
return await(0,l.handleApproveRequest)(e,t,u,h,g,p)}case"revert":{f.info("Routing to revert-request handler")
|
|
2808
|
-
const e={requestId:y,reason:m.revert.reason,confirmDestructive:m.revert.confirmDestructive}
|
|
2803
|
+
try{for(const t of["complete","verifyCriteria","merge","revert","search","list"])if(e&&"string"==typeof e[t])try{e[t]=JSON.parse(e[t])}catch{}"complete"===e?.operation&&e?.summary&&!e?.complete&&(e.complete={summary:e.summary},delete e.summary),"complete"!==e?.operation||e?.complete||e?.summary||(e.complete={summary:""}),"merge"===e?.operation&&e?.verifications&&!e?.merge&&(e.merge={verifications:e.verifications},delete e.verifications),e?.merge&&Array.isArray(e.merge)&&(e.merge={verifications:e.merge}),"verify-criteria"===e?.operation&&(e.operation="merge",e.verifyCriteria&&!e.merge&&(e.merge=e.verifyCriteria,delete e.verifyCriteria)),"finalize"===e?.operation&&(e.operation="merge",e.merge||(e.merge={verifications:[]})),"revert"===e?.operation&&e?.reason&&!e?.revert&&(e.revert={reason:e.reason,confirmDestructive:e.confirmDestructive},delete e.reason,delete e.confirmDestructive),"search"===e?.operation&&e?.query&&!e?.search&&(e.search={query:e.query,searchIn:e.searchIn||"all",filters:e.filters},delete e.query,delete e.searchIn,delete e.filters)
|
|
2804
|
+
const d=r.RequestOperationsSchema.parse(e),{requestId:m,operation:y}=d
|
|
2805
|
+
switch(f.info("Processing request operation",{requestId:m,operation:y}),y){case"complete":{f.info("Routing to complete-request handler")
|
|
2806
|
+
const e={requestId:m,summary:d.complete.summary}
|
|
2807
|
+
return await(0,n.handleCompleteRequest)(e,t,u,h,g,p)}case"merge":return f.info("Routing to merge handler"),await(0,l.handleMergeRequest)({requestId:m,verifications:d.merge?.verifications||[]},t,u,h,g,p)
|
|
2808
|
+
case"approve":{f.info("Routing to approve-request handler")
|
|
2809
|
+
const e={requestId:m}
|
|
2810
|
+
return await(0,c.handleApproveRequest)(e,t,u,h,g,p)}case"revert":{f.info("Routing to revert-request handler")
|
|
2811
|
+
const e={requestId:m,reason:d.revert.reason,confirmDestructive:d.revert.confirmDestructive}
|
|
2809
2812
|
return await(0,o.handleRevertRequest)(e,t,u,h,g)}case"get-info":{f.info("Routing to get-request-information handler")
|
|
2810
|
-
const e={requestId:
|
|
2813
|
+
const e={requestId:m}
|
|
2811
2814
|
return await(0,s.handleGetRequestInformation)(e,t,u,h,g)}case"list":{f.info("Routing to list-requests handler")
|
|
2812
|
-
const e={filters:
|
|
2815
|
+
const e={filters:d.list?.filters}
|
|
2813
2816
|
return await(0,i.handleListRequests)(e,t,u,h,g)}case"search":{f.info("Routing to search-requests handler")
|
|
2814
|
-
const e={search:
|
|
2815
|
-
return await(0,a.handleSearchRequests)(e,t,u,h,g)}default:{const e="Unknown operation type: "+
|
|
2817
|
+
const e={search:d.search}
|
|
2818
|
+
return await(0,a.handleSearchRequests)(e,t,u,h,g)}default:{const e="Unknown operation type: "+y
|
|
2816
2819
|
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}}}
|
|
2817
|
-
const r=t(6183),n=t(5715),o=t(6416),s=t(5434),i=t(8037),a=t(233),c=t(
|
|
2820
|
+
const r=t(6183),n=t(5715),o=t(6416),s=t(5434),i=t(8037),a=t(233),c=t(1537),l=t(4306),d=t(8824)},4710(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2818
2821
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClient=void 0
|
|
2819
2822
|
const n=r(t(9896)),o=r(t(6928)),s=t(7645),i=t(2161),a=t(1058),c=t(8824)
|
|
2820
2823
|
class l extends s.ConnectionAwareClient{isOffline(){return!!this.connectionStatusManager&&this.connectionStatusManager.isOffline()}isOnline(){return!this.isOffline()}setProjectSynchronizer(e){this.logger.info("Setting ProjectSynchronizer on ProjectClient"),this.projectSynchronizer=e}getProjectSynchronizer(){return this.projectSynchronizer}async fetchProject(e){return this.getProject(e)}async pingDetailed(){this.logger.debug("Pinging remote server")
|
|
@@ -2942,15 +2945,15 @@ if(/^\d+$/.test(e)){const t=parseInt(e,10)
|
|
|
2942
2945
|
return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
|
|
2943
2946
|
if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
|
|
2944
2947
|
if(e.match(/^(\d+(?:,\d+)+)$/)){const t=e.split(",").map((e=>parseInt(e,10)))
|
|
2945
|
-
return{start:Math.min(...t),end:Math.max(...t)}}return null}(p),
|
|
2946
|
-
let
|
|
2947
|
-
b&&
|
|
2948
|
+
return{start:Math.min(...t),end:Math.max(...t)}}return null}(p),I=["blame","--porcelain"]
|
|
2949
|
+
let k
|
|
2950
|
+
b&&I.push(`-L${b.start},${b.end}`),f&&I.push(f),I.push("--",w),c.debug("Executing git blame",{args:I})
|
|
2948
2951
|
try{if(!t.git)throw Error("Git context not available")
|
|
2949
|
-
|
|
2952
|
+
k=await t.git.raw(I)}catch(e){const t=(0,h.getErrorMessage)(e)
|
|
2950
2953
|
return c.error("Git blame failed",{error:t}),{content:[{type:"text",text:"\u274c Git blame failed: "+t}],isError:!0}}const v=function(e){const t=[],r=e.split("\n")
|
|
2951
2954
|
let n="",o="",s="",i=0,a=0,c=new Map
|
|
2952
2955
|
for(let e=0;e<r.length;e++){const l=r[e],d=l.match(/^([0-9a-f]{40})\s+\d+\s+(\d+)/)
|
|
2953
|
-
d?(n=d[1],a=parseInt(d[2],10)):l.startsWith("author ")?o=l.substring(7):l.startsWith("author-mail ")?s=l.substring(12).replace(/[<>]/g,""):l.startsWith("author-time ")?i=parseInt(l.substring(12),10):l.startsWith("summary ")?c.set(n,l.substring(8)):l.startsWith("\t")&&t.push({lineNumber:a,commitHash:n,author:o,authorEmail:s,timestamp:i,content:l.substring(1),commitMessage:c.get(n)})}return t}(
|
|
2956
|
+
d?(n=d[1],a=parseInt(d[2],10)):l.startsWith("author ")?o=l.substring(7):l.startsWith("author-mail ")?s=l.substring(12).replace(/[<>]/g,""):l.startsWith("author-time ")?i=parseInt(l.substring(12),10):l.startsWith("summary ")?c.set(n,l.substring(8)):l.startsWith("\t")&&t.push({lineNumber:a,commitHash:n,author:o,authorEmail:s,timestamp:i,content:l.substring(1),commitMessage:c.get(n)})}return t}(k)
|
|
2954
2957
|
if(0===v.length)return{content:[{type:"text",text:"\u274c No blame information found for "+w}],isError:!0}
|
|
2955
2958
|
const C=function(e){if(0===e.length)return[]
|
|
2956
2959
|
const t=[]
|
|
@@ -3019,7 +3022,7 @@ const r=t(6183),n=t(4592)
|
|
|
3019
3022
|
exports.def={name:"planner_ops",description:"Request a planning session and check on planner progress.\n\nOperations:\n\u2022 request - Start a planning session for a feature or architecture question\n\u2022 check-status - Check if a planner is busy or idle\n\u2022 list - List planning sessions",schema:r.PlannerOpsSchema,annotations:{title:"Planner Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handlePlannerOps)(e,t.context,t.logger,t.metrics,t.apiClient??void 0,t.cliOrigin)}}},5003(e,exports,t){async function r(e,t,r,s,i){const a=r.child({requestId:e,operation:"request-status-validation"})
|
|
3020
3023
|
try{a.info("Validating request status for document operation",{requestId:e})
|
|
3021
3024
|
const r=await t.getRequest(e)
|
|
3022
|
-
if(a.info("Request status retrieved",{requestId:e,status:r.status}),"completed"
|
|
3025
|
+
if(a.info("Request status retrieved",{requestId:e,status:r.status}),["completed","canceled","pending_approval","ready_for_review","ready_for_merge","reverted"].includes(r.status)){const t=r.status.replace(/_/g," "),o=`\u274c **Document operations are not allowed on ${t} requests.**\n\n**Request:** ${e}\n**Status:** ${r.status}\n\n**Reason:** Once a request is ${t}, its associated documents become read-only to maintain audit trail integrity.\n\n**What you can do:**\n- Create a new request for additional changes\n- Use the revert-request tool if you need to make corrections\n- Contact your administrator if you believe this is an error`
|
|
3023
3026
|
a.warn("Document operation blocked on terminal request",{requestId:e,requestStatus:r.status,reason:"completed"===r.status?"request_completed":"request_canceled"})
|
|
3024
3027
|
const c="completed"===r.status?i+"_blocked_completed_request":i+"_blocked_canceled_request"
|
|
3025
3028
|
throw s.incrementCounter(c,1),new n.ValidationError(o,{requestId:e,requestStatus:r.status,reason:"request_completed"})}return a.info("Request status validation passed",{requestId:e,status:r.status}),r}catch(t){if(t instanceof n.ValidationError)throw t
|
|
@@ -3149,48 +3152,57 @@ var t={}
|
|
|
3149
3152
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3150
3153
|
return o(t,e),t})
|
|
3151
3154
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlanRead=async function(e,t,r,n,o){const s=n.child({tool:"plan_read"})
|
|
3152
|
-
try{
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
return o.incrementCounter("plan_read_total",1,{operation:"
|
|
3155
|
+
try{e?.get?.planId&&!e.planId&&(e.planId=e.get.planId,delete e.get),e?.getHistory?.planId&&!e.planId&&(e.planId=e.getHistory.planId,delete e.getHistory),e?.getRequests?.planId&&!e.planId&&(e.planId=e.getRequests.planId,delete e.getRequests),e?.list&&!e.searchQuery&&(Object.assign(e,e.list),delete e.list)
|
|
3156
|
+
const n=a.validateArgs(e,i.PlanReadSchema),{operation:d,planId:u}=n
|
|
3157
|
+
switch(s.info("Processing plan_read",{operation:d}),d){case"get":{const e=await(0,c.handleGetPlan)({planId:u},t,r,s,o)
|
|
3158
|
+
return o.incrementCounter("plan_read_total",1,{operation:"get",success:!e.isError}),e}case"list":{const e=await(0,l.handleListPlans)({searchQuery:n.searchQuery,limit:n.limit,offset:n.offset,sortBy:n.sortBy,sortDirection:n.sortDirection},t,r,s,o)
|
|
3159
|
+
return o.incrementCounter("plan_read_total",1,{operation:"list",success:!e.isError}),e}case"get-history":{const e=r.getDocumentClient(),t=await e.getVersionHistory(u)
|
|
3156
3160
|
o.incrementCounter("plan_read_total",1,{operation:"get-history",success:!0})
|
|
3157
|
-
let
|
|
3158
|
-
|
|
3159
|
-
let
|
|
3160
|
-
return
|
|
3161
|
+
let n=""
|
|
3162
|
+
t.snapshots&&t.snapshots.length>0?(n="### Version Snapshots\n\n",t.snapshots.forEach((e=>{n+=`**Version ${e.versionNumber}** - ${new Date(e.createdAt).toLocaleString()}\n`,e.versionLabel&&(n+=` Label: ${e.versionLabel}\n`),e.changeSummary&&(n+=` Summary: ${e.changeSummary}\n`),n+="\n"}))):n="### Version Snapshots\n\nNo version snapshots created yet.\n\n"
|
|
3163
|
+
let s=""
|
|
3164
|
+
return t.changeHistory&&t.changeHistory.length>0?(s="### Recent Changes\n\n",t.changeHistory.slice(0,10).forEach((e=>{s+=`**${e.toolName}** - ${new Date(e.createdAt).toLocaleString()}\n`,e.createdBy&&(s+=` By: ${e.createdBy}\n`),s+="\n"}))):s="### Recent Changes\n\nNo changes recorded.\n",{content:[{type:"text",text:`## Version History for ${u}\n\n${n}${s}`}]}}case"get-active":{const e=r.getProjectClient(),n=t.projectId
|
|
3161
3165
|
if(!n)return{content:[{type:"text",text:"\u274c No project context available."}],isError:!0}
|
|
3162
3166
|
const i=await e.getProject(n)
|
|
3163
3167
|
if(!i||!i.activePlanId)return o.incrementCounter("plan_read_total",1,{operation:"get-active",success:!0}),{content:[{type:"text",text:"No active plan set for this project. Use `plan_write` with `set-active` to designate one, or create a new plan."}]}
|
|
3164
3168
|
const a=await(0,c.handleGetPlan)({planId:i.activePlanId},t,r,s,o)
|
|
3165
|
-
return o.incrementCounter("plan_read_total",1,{operation:"get-active",success:!a.isError}),!a.isError&&a.content.length>0&&(a.content[0].text="\u{1f4cc} **Active Project Plan**\n\n"+a.content[0].text),a}case"get-requests":{const
|
|
3166
|
-
if(o.incrementCounter("plan_read_total",1,{operation:"get-requests",success:!0}),!
|
|
3167
|
-
let
|
|
3168
|
-
for(const e of
|
|
3169
|
-
return{content:[{type:"text",text:
|
|
3170
|
-
const i=t(6183),a=s(t(5967)),c=t(8800),l=t(8391),d=t(8824)},5317(module){module.exports=require("child_process")},5434(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleGetRequestInformation=async function(e,t,
|
|
3169
|
+
return o.incrementCounter("plan_read_total",1,{operation:"get-active",success:!a.isError}),!a.isError&&a.content.length>0&&(a.content[0].text="\u{1f4cc} **Active Project Plan**\n\n"+a.content[0].text),a}case"get-requests":{const e=r.getRequestClient(),t=await e.listRequests({planDocumentId:u})
|
|
3170
|
+
if(o.incrementCounter("plan_read_total",1,{operation:"get-requests",success:!0}),!t||0===t.length)return{content:[{type:"text",text:`No requests linked to plan ${u}.`}]}
|
|
3171
|
+
let n=`## Requests Linked to ${u} (${t.length})\n\n`
|
|
3172
|
+
for(const e of t)n+=`**${e.localId||e.id}** \u2014 ${e.title}\n`,n+=` Status: ${e.status} | Type: ${e.type}\n`,n+=` Updated: ${new Date(e.updatedAt).toLocaleString()}\n\n`
|
|
3173
|
+
return{content:[{type:"text",text:n}]}}default:throw Error("Unknown plan_read operation: "+d)}}catch(e){return s.error("plan_read failed",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("plan_read_errors",1),{content:[{type:"text",text:"\u274c **Plan Read Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
3174
|
+
const i=t(6183),a=s(t(5967)),c=t(8800),l=t(8391),d=t(8824)},5317(module){module.exports=require("child_process")},5434(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleGetRequestInformation=async function(e,t,a,c,l){const d=c.child({tool:"get_request_information"}),u=l.startTimer("tool_execution_time")
|
|
3171
3175
|
try{const{requestId:t}=e
|
|
3172
3176
|
if(!t)throw new r.ValidationError("Request ID is required")
|
|
3173
3177
|
if(!/^req\d{6}$/.test(t))throw new r.ValidationError(`Invalid request ID format: ${t}. Expected format: req######`)
|
|
3174
|
-
|
|
3175
|
-
const n=
|
|
3176
|
-
|
|
3177
|
-
const
|
|
3178
|
-
|
|
3179
|
-
const
|
|
3180
|
-
|
|
3181
|
-
const
|
|
3182
|
-
|
|
3183
|
-
t in
|
|
3184
|
-
const
|
|
3185
|
-
|
|
3186
|
-
t in
|
|
3187
|
-
let
|
|
3188
|
-
const
|
|
3189
|
-
let k=`# ${"feature"===
|
|
3190
|
-
return k+=`\n## Task Status\n- Pending: ${
|
|
3191
|
-
k
|
|
3192
|
-
|
|
3193
|
-
|
|
3178
|
+
d.info("Getting information for request "+t)
|
|
3179
|
+
const n=a.getRequestClient(),s=a.getTaskClient(),[c,l]=await Promise.all([n.getRequest(t),s.listTasks({requestId:t})])
|
|
3180
|
+
d.info("Raw request response data",{responseData:JSON.stringify(c)}),d.debug("Request response structure",{type:typeof c,isArray:Array.isArray(c),hasData:null!=c,properties:c?Object.keys(c):[],dataPreview:c?JSON.stringify(c).substring(0,200)+"...":"null"})
|
|
3181
|
+
const h=(0,o.extractDataFromResponse)(c,{logger:d,operationName:"getRequestInformation",throwOnNoData:!0}),g="data"in h?h.data:h
|
|
3182
|
+
d.info("Successfully extracted request data using data extraction utility"),d.info("Raw tasks response data",{responseData:JSON.stringify(l)}),d.debug("Tasks response structure",{type:typeof l,isArray:Array.isArray(l),hasData:null!=l,properties:l?Object.keys(l):[],dataPreview:l?JSON.stringify(l).substring(0,200)+"...":"null"})
|
|
3183
|
+
const p=(0,o.extractArrayFromResponse)(l,{logger:d,operationName:"listTasksForRequest",defaultValue:[]})
|
|
3184
|
+
d.info(`Successfully extracted ${p.length} tasks using data extraction utility`)
|
|
3185
|
+
const f={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:p.length}
|
|
3186
|
+
p.forEach((e=>{const t=e.status
|
|
3187
|
+
t in f&&f[t]++}))
|
|
3188
|
+
const m=g.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_verified:0,total:m.length}
|
|
3189
|
+
m.forEach((e=>{const t=e.status||"unverified"
|
|
3190
|
+
t in y&&y[t]++}))
|
|
3191
|
+
let w=g.testVerification||null
|
|
3192
|
+
const b=g.title,I=g.type
|
|
3193
|
+
let k=`# ${"feature"===I?"Feature":"quick-edit"===I?"Quick Edit":"Bug Fix"} Request: ${b} (${t})\nStatus: ${g.status}\nCreated: ${new Date(g.createdAt).toLocaleString()}\nUpdated: ${new Date(g.updatedAt).toLocaleString()}\n\n## Description\n${g.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${f.completed}/${f.total} completed (${Math.round(f.completed/f.total*100)||0}%)\n- Acceptance Criteria: ${y.verified}/${y.total} verified (${Math.round(y.verified/y.total*100)||0}%)\n`
|
|
3194
|
+
return k+=`\n## Task Status\n- Pending: ${f.pending}\n- In Progress: ${f.in_progress}\n- Blocked: ${f.blocked}\n- Ready for Review: ${f.ready_for_review}\n- Completed: ${f.completed}\n- Reverted: ${f.reverted}\n`,k+="\n## Tasks\n",0===p.length?k+="No tasks found for this request.\n":p.forEach((e=>{k+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${p.length} tasks`),k+="\n## Acceptance Criteria\n",k+=(0,i.formatCriteriaWithHashes)(m)+"\n","ready_for_review"===g.status&&m.some((e=>"verified"!==e.status))&&(k+="\n> **Status: ready_for_review** \u2014 Use the merge operation to verify criteria and merge to main.\n"),w&&(k+=`\n## Test Coverage\n- Test Cases: ${w.totalTestCases||0}\n- Criteria Tested: ${w.criteriaTestedCount||0}/${y.total}\n`,w.criterionCoverage&&Array.isArray(w.criterionCoverage)&&(k+="\n### Detailed Test Coverage:\n",w.criterionCoverage.forEach((e=>{k+=`- Criterion ${e.criterionId}: ${e.coverage} coverage\n`})))),g.recentActivity&&Array.isArray(g.recentActivity)&&(k+="\n## Recent Activity\n",g.recentActivity.slice(0,5).forEach((e=>{const t=new Date(e.timestamp).toLocaleString()
|
|
3195
|
+
k+=`- ${t}: ${e.description}\n`}))),u({success:!0}),{content:[{type:"text",text:k}]}}catch(t){return d.error("Error getting request information",{args:e,error:t instanceof Error?t.stack:t+""}),u({success:!1,error:t instanceof Error?t.name:"unknown"}),t instanceof n.ConnectionError?{content:[{type:"text",text:"Unable to get request information: Connection to the server failed. Please check your network connection and try again."}],isError:!0}:{content:[{type:"text",text:"Error getting request information: "+(0,s.getErrorMessage)(t)}],isError:!0}}}
|
|
3196
|
+
const r=t(9860),n=t(5674),o=t(2960),s=t(8824),i=t(5454)},5454(e,exports){function t(e,t){let r=0
|
|
3197
|
+
for(let t=0;t<e.length;t++)r=(r<<5)-r+e.charCodeAt(t)|0
|
|
3198
|
+
return`${t+1}${String.fromCharCode(97+Math.abs(r)%26)}`}function r(e){const r=new Map
|
|
3199
|
+
for(let n=0;n<e.length;n++){const o=t(e[n].id,n)
|
|
3200
|
+
r.set(o,e[n])}return r}function n(e){if(0===e.length)return"No acceptance criteria defined."
|
|
3201
|
+
const t=r(e),n=[]
|
|
3202
|
+
for(const[e,r]of t){const t=(r.status||"unverified").toUpperCase()
|
|
3203
|
+
n.push(`[${e}] [${t}] ${r.description}`)}return n.join("\n")}function o(e){const t=r(e),o=[]
|
|
3204
|
+
for(const[e,r]of t)o.push(` {"key": "${e}", "evidence": "<your evidence for: ${r.description}>"}`)
|
|
3205
|
+
return`Use the merge operation with evidence for each criterion:\n\n${n(e)}\n\nExample call:\n{\n "operation": "merge",\n "requestId": "<requestId>",\n "merge": {\n "verifications": [\n${o.join(",\n")}\n ]\n }\n}`}Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatEvidenceInstructions=exports.formatCriteriaWithHashes=exports.buildCriteriaHashMap=exports.criterionHash=void 0,exports.criterionShortKey=t,exports.buildCriteriaKeyMap=r,exports.formatCriteriaWithKeys=n,exports.formatVerifyInstructions=o,exports.criterionHash=t,exports.buildCriteriaHashMap=r,exports.formatCriteriaWithHashes=n,exports.formatEvidenceInstructions=o},5459(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3194
3206
|
const r=t(6183),n=t(2414)
|
|
3195
3207
|
exports.def={name:"move_files",description:"Move or rename multiple files and directories in a single operation. Requires a taskId and a comment explaining the purpose of the modifications. All operations are processed sequentially and committed together. If any operation fails, the tool reports which operations succeeded and which failed.",schema:r.MoveFilesSchema,annotations:{title:"Move or Rename Multiple Files",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},hidden:!0,createsRecords:!0,handler(e,t){return(0,n.handleMoveFiles)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},5498(e,exports){Object.defineProperty(exports,"__esModule",{value:!0})},5626(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3196
3208
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
@@ -3201,35 +3213,37 @@ var t={}
|
|
|
3201
3213
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3202
3214
|
return o(t,e),t})
|
|
3203
3215
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDocumentOperations=async function(e,t,r,n,o,s,u){const h=n.child({tool:"document_operations"})
|
|
3204
|
-
try{const n=
|
|
3205
|
-
|
|
3206
|
-
const
|
|
3216
|
+
try{const n=["create","search","createSnapshot","getHistory","getVersion","restoreVersion","listAnnotations","createAnnotation","replyToAnnotation","resolveAnnotation"]
|
|
3217
|
+
for(const t of n)e?.[t]&&"object"==typeof e[t]&&(Object.assign(e,e[t]),delete e[t])
|
|
3218
|
+
const d=a.validateArgs(e,i.DocumentOperationsSchema),{operation:g}=d,p=d.documentId
|
|
3219
|
+
switch(h.info("Processing document_operations",{operation:g}),g){case"create":{h.info("Routing to create-document handler")
|
|
3220
|
+
const e=await(0,c.handleCreateDocument)({requestId:d.requestId,filename:d.filename,content:d.content,type:d.type,comment:d.comment},t,r,h,o,s,u)
|
|
3207
3221
|
return o.incrementCounter("document_operations_total",1,{operation:"create",success:!e.isError}),e}case"search":{h.info("Routing to search-documents handler")
|
|
3208
|
-
const e=await(0,l.handleSearchDocuments)(
|
|
3222
|
+
const e=await(0,l.handleSearchDocuments)({query:d.query,type:d.type,requestId:d.requestId,includeArchived:d.includeArchived,maxResults:d.maxResults,dateFrom:d.dateFrom,dateTo:d.dateTo,searchIn:d.searchIn},t,r,h,o,s)
|
|
3209
3223
|
return o.incrementCounter("document_operations_total",1,{operation:"search",success:!e.isError}),e}case"create-snapshot":{h.info("Creating version snapshot")
|
|
3210
|
-
const{
|
|
3211
|
-
return o.incrementCounter("document_operations_total",1,{operation:"create-snapshot",success:!0}),{content:[{type:"text",text:`\u2705 **Version Snapshot Created**\n\n**Document:** ${
|
|
3212
|
-
const
|
|
3213
|
-
h.info("Version history data received",{hasSnapshots:!!
|
|
3214
|
-
let
|
|
3215
|
-
|
|
3216
|
-
let
|
|
3217
|
-
return
|
|
3218
|
-
const
|
|
3219
|
-
return o.incrementCounter("document_operations_total",1,{operation:"get-version",success:!0}),{content:[{type:"text",text:`## Version ${
|
|
3220
|
-
const
|
|
3221
|
-
return o.incrementCounter("document_operations_total",1,{operation:"restore-version",success:!0}),{content:[{type:"text",text:`\u2705 **Document Restored**\n\n**Document:** ${
|
|
3222
|
-
const
|
|
3223
|
-
if(o.incrementCounter("document_operations_total",1,{operation:"list-annotations",success:!0}),!
|
|
3224
|
-
let
|
|
3225
|
-
for(const e of
|
|
3226
|
-
for(const t of e.replies)
|
|
3227
|
-
const
|
|
3228
|
-
return o.incrementCounter("document_operations_total",1,{operation:"create-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Annotation Created**\n\n**ID:** ${
|
|
3229
|
-
const
|
|
3230
|
-
return o.incrementCounter("document_operations_total",1,{operation:"reply-to-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Reply Added**\n\n**Reply ID:** ${
|
|
3231
|
-
const
|
|
3232
|
-
return await
|
|
3224
|
+
const{versionLabel:e,changeSummary:t}=d,n=r.getDocumentClient(),s=await n.createVersionSnapshot(p,e,t)
|
|
3225
|
+
return o.incrementCounter("document_operations_total",1,{operation:"create-snapshot",success:!0}),{content:[{type:"text",text:`\u2705 **Version Snapshot Created**\n\n**Document:** ${p}\n**Version:** ${s.versionNumber}\n**Label:** ${e||"None"}\n**Summary:** ${t||"None"}\n**Created:** `+new Date(s.createdAt).toLocaleString()}]}}case"get-history":{h.info("Retrieving version history")
|
|
3226
|
+
const e=r.getDocumentClient(),t=await e.getVersionHistory(p)
|
|
3227
|
+
h.info("Version history data received",{hasSnapshots:!!t.snapshots,snapshotCount:t.snapshots?.length||0,hasChangeHistory:!!t.changeHistory,changeCount:t.changeHistory?.length||0,keys:Object.keys(t)}),o.incrementCounter("document_operations_total",1,{operation:"get-history",success:!0})
|
|
3228
|
+
let n=""
|
|
3229
|
+
t.snapshots&&t.snapshots.length>0?(n="### \u{1f4da} Version Snapshots\n\n",t.snapshots.forEach((e=>{n+=`**Version ${e.versionNumber}** - ${new Date(e.createdAt).toLocaleString()}\n`,e.versionLabel&&(n+=` Label: ${e.versionLabel}\n`),e.changeSummary&&(n+=` Summary: ${e.changeSummary}\n`),n+="\n"}))):n="### \u{1f4da} Version Snapshots\n\nNo version snapshots created yet.\n\n"
|
|
3230
|
+
let s=""
|
|
3231
|
+
return t.changeHistory&&t.changeHistory.length>0?(s="### \u{1f4dd} Recent Changes\n\n",t.changeHistory.slice(0,10).forEach((e=>{s+=`**${e.toolName}** - ${new Date(e.createdAt).toLocaleString()}\n`,e.createdBy&&(s+=` By: ${e.createdBy}\n`),s+="\n"}))):s="### \u{1f4dd} Recent Changes\n\nNo changes recorded.\n",{content:[{type:"text",text:`## Version History for ${p}\n\n${n}${s}`}]}}case"get-version":{h.info("Retrieving specific version")
|
|
3232
|
+
const e=r.getDocumentClient(),t=await e.getVersion(p,d.versionNumber)
|
|
3233
|
+
return o.incrementCounter("document_operations_total",1,{operation:"get-version",success:!0}),{content:[{type:"text",text:`## Version ${d.versionNumber} of ${p}\n\n**Created:** ${new Date(t.createdAt).toLocaleString()}\n**Label:** ${t.versionLabel||"None"}\n**Summary:** ${t.changeSummary||"None"}\n\n### Content:\n\n\`\`\`\n${t.content}\n\`\`\``}]}}case"restore-version":{h.info("Restoring to version")
|
|
3234
|
+
const e=r.getDocumentClient(),t=await e.restoreToVersion(p,d.versionNumber)
|
|
3235
|
+
return o.incrementCounter("document_operations_total",1,{operation:"restore-version",success:!0}),{content:[{type:"text",text:`\u2705 **Document Restored**\n\n**Document:** ${p}\n**Restored to Version:** ${d.versionNumber}\n**Filename:** ${t.filename}\n\nThe document has been successfully restored to version ${d.versionNumber}.`}]}}case"list-annotations":{h.info("Listing annotations")
|
|
3236
|
+
const e=r.getDocumentClient(),t=await e.listAnnotations(p)
|
|
3237
|
+
if(o.incrementCounter("document_operations_total",1,{operation:"list-annotations",success:!0}),!t||0===t.length)return{content:[{type:"text",text:`No annotations found on document ${p}.`}]}
|
|
3238
|
+
let n=`## Annotations on ${p} (${t.length})\n\n`
|
|
3239
|
+
for(const e of t){if(n+=`### ${"resolved"===e.status?"\u2705":"\u{1f4ac}"} ${e.id} [${e.status}]\n`,n+=`> "${e.anchor?.selectedText?.substring(0,80)||""}"\n\n`,n+=e.body+"\n",e.createdByAgent&&(n+=`*By agent: ${e.createdByAgent}*\n`),e.replies&&e.replies.length>0){n+=`\n**Replies (${e.replies.length}):**\n`
|
|
3240
|
+
for(const t of e.replies)n+="- "+t.body,t.createdByAgent&&(n+=` *(${t.createdByAgent})*`),n+="\n"}n+="\n---\n\n"}return{content:[{type:"text",text:n}]}}case"create-annotation":{h.info("Creating annotation")
|
|
3241
|
+
const e=d.selectedText,t=d.body,{prefixContext:n,suffixContext:s,lineHint:i}=d,a=r.getDocumentClient(),c=u?"agent":void 0,l=u?.sessionId,g=await a.createAnnotation(p,{selectedText:e,prefixContext:n,suffixContext:s,lineHint:i,body:t,createdByAgent:c,createdBySessionId:l})
|
|
3242
|
+
return o.incrementCounter("document_operations_total",1,{operation:"create-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Annotation Created**\n\n**ID:** ${g.id}\n**Document:** ${p}\n**Selected text:** "${e.substring(0,60)}"\n**Comment:** `+t}]}}case"reply-to-annotation":{h.info("Replying to annotation")
|
|
3243
|
+
const e=d.annotationId,t=d.body,n=r.getDocumentClient(),s=await n.replyToAnnotation(p,e,{body:t,createdByAgent:u?"agent":void 0,createdBySessionId:u?.sessionId})
|
|
3244
|
+
return o.incrementCounter("document_operations_total",1,{operation:"reply-to-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Reply Added**\n\n**Reply ID:** ${s.id}\n**Annotation:** ${e}\n**Body:** `+t}]}}case"resolve-annotation":{h.info("Resolving annotation")
|
|
3245
|
+
const e=d.annotationId,t=r.getDocumentClient()
|
|
3246
|
+
return await t.resolveAnnotation(p,e,u?"agent":void 0),o.incrementCounter("document_operations_total",1,{operation:"resolve-annotation",success:!0}),{content:[{type:"text",text:`\u2705 **Annotation Resolved**\n\n**Annotation:** ${e}\n**Status:** resolved`}]}}default:throw Error("Unknown operation type: "+g)}}catch(e){return h.error("document_operations failed",{error:e instanceof Error?e.stack:e+""}),o.incrementCounter("document_operations_errors",1),{content:[{type:"text",text:"\u274c **Document Operations Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
3233
3247
|
const i=t(6183),a=s(t(5967)),c=t(1572),l=t(1483),d=t(8824)},5671(e,exports,t){function r(e){const[t,...r]=e.split("/")
|
|
3234
3248
|
return{provider:t||"anthropic",modelId:r.join("/")||e}}function n(e){const t={anthropic:!1,openai:!1}
|
|
3235
3249
|
try{const n=(0,a.join)(e,"opencode.json")
|
|
@@ -3276,55 +3290,25 @@ if(t){const e=Date.now()-t
|
|
|
3276
3290
|
try{this.metrics.observeHistogram("offline_duration_ms",e,{reconnection_type:"manual"}),this.logger.info(`System was offline for ${Math.round(e/1e3)} seconds before manual reconnection`)}catch(e){this.logger.warn("Error observing histogram for offline duration on manual reconnection",{error:e instanceof Error?e.message:e+""})}}}}catch(e){this.logger.warn("Error calculating offline duration during manual mode change",{error:(0,s.getErrorMessage)(e)})}this.notifyOnlineStatus()}else!t&&e&&(this.logger.info("Manually setting connection mode to OFFLINE"),this.safeSetGauge("connection_status",0),this.safeSetGauge("last_connection_failure_timestamp",Date.now()),this.safeIncrementCounter("manual_disconnections",1),process.nextTick((()=>{exports.eventBus.emit(exports.EVENTS.OFFLINE,{timestamp:(new Date).toISOString()})})))}isOffline(){return this.isInOfflineMode()}async checkConnectivity(){return this.logger.debug("Explicit connectivity check requested"),this.healthCheckManager.requestHealthCheck()}getHealthCheckStats(){const e=this.healthCheckManager.getStats()
|
|
3277
3291
|
return{isOffline:this.isInOfflineMode(),consecutiveFailures:e.consecutiveFailures,currentBackoffMs:e.currentBackoffMs,lastCheckTime:e.lastCheckTime}}cleanup(){this.logger.debug("Cleaning up connection status manager resources"),this.healthCheckManager.stopHealthChecks(),exports.eventBus.removeAllListeners(exports.EVENTS.ONLINE),exports.eventBus.removeAllListeners(exports.EVENTS.OFFLINE)}}},5692(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3278
3292
|
const r=t(6183),n=t(2965)
|
|
3279
|
-
exports.def={name:"read_files",description:'Read the contents of multiple files and documents with flexible line selection.\n\nLINE SELECTION (string format):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "5-15"\n- Entire file: omit "lines" parameter\n\nEXAMPLES:\n- Read first 10 lines: {"path": "file.txt", "lines": "1-10"}\n- Read specific lines: {"path": "file.txt", "lines": "1,5,25"}\n- Read line 42 only: {"path": "file.txt", "lines": "42"}\n- Read entire file: {"path": "file.txt"}\n\nSupports both filesystem files (using \'path\') and tracked documents (using \'documentId\'). More efficient than reading files one by one. Failed reads won\'t stop the entire operation.',schema:r.ReadFilesSchema,annotations:{title:"Read Files/Documents",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleReadFiles)(e,t.context,t.logger,t.metrics)}}},5715(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,l,d,u,h
|
|
3280
|
-
try{const{requestId:o,summary:s
|
|
3293
|
+
exports.def={name:"read_files",description:'Read the contents of multiple files and documents with flexible line selection.\n\nLINE SELECTION (string format):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "5-15"\n- Entire file: omit "lines" parameter\n\nEXAMPLES:\n- Read first 10 lines: {"path": "file.txt", "lines": "1-10"}\n- Read specific lines: {"path": "file.txt", "lines": "1,5,25"}\n- Read line 42 only: {"path": "file.txt", "lines": "42"}\n- Read entire file: {"path": "file.txt"}\n\nSupports both filesystem files (using \'path\') and tracked documents (using \'documentId\'). More efficient than reading files one by one. Failed reads won\'t stop the entire operation.',schema:r.ReadFilesSchema,annotations:{title:"Read Files/Documents",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleReadFiles)(e,t.context,t.logger,t.metrics)}}},5715(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const g=l.child({tool:"complete_request"}),p=d.startTimer("tool_execution_time")
|
|
3294
|
+
try{const{requestId:o,summary:s}=e
|
|
3281
3295
|
if(!o)throw(0,r.createValidationError)("Request ID is required")
|
|
3282
3296
|
if(!s)throw(0,r.createValidationError)("Summary is required")
|
|
3283
|
-
|
|
3284
|
-
const h
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
let
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
return p
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
let
|
|
3295
|
-
|
|
3296
|
-
return
|
|
3297
|
-
|
|
3298
|
-
return f({success:!1,error:"no_tasks_completion_failure"}),{content:[{type:"text",text:"Failed to complete request with no tasks: "+t}],isError:!0}}}let b={merged:!1,deleted:!1,method:"",message:""}
|
|
3299
|
-
if("revert-removal"===y.mergeStrategy&&y.revertInfo){if(p.info("Using revert removal strategy",{requestId:o,revertCommitHash:y.revertInfo.revertCommitHash.substring(0,8)}),t.git&&y.revertInfo.revertCommitHash){const e=await(0,a.hasMainChangedSinceRevert)(t.git,y.revertInfo.revertCommitHash,p,u)
|
|
3300
|
-
if(e.hasChanged)return f({success:!1,reason:"main_changed_since_revert"}),{content:[{type:"text",text:`Cannot re-complete reverted request: Main branch has changed since revert\n\n${e.message}\n\nCreate a new request to implement the desired changes.`}],isError:!0}}try{const e=(await t.git.raw(["rev-parse",y.revertInfo.revertCommitHash+"^"])).trim()
|
|
3301
|
-
await t.git.reset(["--hard",e])
|
|
3302
|
-
const r=await t.git.revparse(["HEAD"])
|
|
3303
|
-
if(r.trim()!==e)throw Error(`Git reset verification failed: expected ${e.substring(0,8)}, got ${r.substring(0,8)}`)
|
|
3304
|
-
w={mergeCommitHash:r.trim(),mergedFiles:[],cleanedUp:!1},b={merged:!0,deleted:!1,method:"revert-removal",message:"Removed revert commit "+y.revertInfo.revertCommitHash.substring(0,8)},p.info("Revert removal succeeded",{requestId:o,newHead:r.trim().substring(0,8)})}catch(e){const t=(0,c.getErrorMessage)(e)
|
|
3305
|
-
return f({success:!1,reason:"revert_removal_failed"}),{content:[{type:"text",text:"Failed to re-complete reverted request: "+t}],isError:!0}}}const k=l.getRequestClient(),I=await k.getRequest(o)
|
|
3306
|
-
if(!w&&"conflicted"===I?.status){p.info("Request is conflicted, attempting fast-path merge",{requestId:o})
|
|
3307
|
-
const e=t.workspaceManager?.getCurrentContext()
|
|
3308
|
-
let r=e?.basePath||process.cwd()
|
|
3309
|
-
if("multi-agent"===e?.mode&&t.workspaceManager)try{const e=await t.workspaceManager.getWorktreeInfo(o)
|
|
3310
|
-
e?.worktreePath&&(r=e.worktreePath)}catch{}const n=(0,i.createConflictResolutionManager)(p,l,r,t.git),s=await n.validateMarkersRemoved(o)
|
|
3311
|
-
if(!s.resolved)return{content:[{type:"text",text:`## \u26a0\ufe0f Conflicts Still Need Resolution\n\nConflict markers still exist in:\n\n${s.remainingConflicts.map((e=>`- \`${e}\``)).join("\n")}\n\nRemove all conflict markers and try again.`}]}
|
|
3312
|
-
const a=await n.hasMainBranchChanged(o)
|
|
3313
|
-
if(a.hasChanged&&a.canDetermine)p.info("Main branch changed since conflict detection, skipping fast-path",{requestId:o,originalHash:a.originalHash?.substring(0,8),currentHash:a.currentHash?.substring(0,8)})
|
|
3314
|
-
else try{const e=await async function(e,t,r){r.info("Executing branch-version merge for resolved conflicts",{requestId:e})
|
|
3315
|
-
try{return await t.completeRequest(e,"Request "+e,{skipConflictDetection:!0})}catch(t){throw r.warn("Branch-version merge failed",{requestId:e,error:(0,c.getErrorMessage)(t)}),t}}(o,t.workspaceManager,p)
|
|
3316
|
-
w=e,b={merged:!0,deleted:e.cleanedUp,method:"conflict-fast-path",message:"Fast-path branch-version merge after conflict resolution"}}catch(e){const t=(0,c.getErrorMessage)(e)
|
|
3317
|
-
return f({success:!1,reason:"conflict_fast_path_failed"}),{content:[{type:"text",text:"Fast-path merge failed: "+t}],isError:!0}}}if(!w){if(p.info("Normal merge via WorkspaceManager",{requestId:o}),!t.workspaceManager)return f({success:!1,error:"no_workspace_manager"}),{content:[{type:"text",text:"WorkspaceManager not available for request completion"}],isError:!0}
|
|
3318
|
-
const e=t.workspaceManager.getCurrentContext()
|
|
3319
|
-
if(!e.requestId||e.requestId!==o)try{await t.workspaceManager.ensureWorkspaceReady(o)}catch(e){return f({success:!1,error:"workspace_switch_failed"}),{content:[{type:"text",text:`Cannot complete request ${o}: ${(0,c.getErrorMessage)(e)}`}],isError:!0}}try{w=await t.workspaceManager.completeRequest(o,"Request "+o),b={merged:!0,deleted:w.cleanedUp,method:w.autoMergeInfo?.strategy||"workspace-manager",message:w.autoMergeInfo?.wasAutoMerged?"Auto-merged using "+w.autoMergeInfo.strategy:"Merged via WorkspaceManager"}}catch(e){if(e.conflictInfo){const r=e.conflictInfo,n=r.workingDirectory||t.workspaceManager.getCurrentContext()?.basePath||process.cwd(),s=(0,i.createConflictResolutionManager)(p,l,n,t.git)
|
|
3320
|
-
let a
|
|
3321
|
-
if("conflicted"===I?.status)try{a=await s.updateConflictResolution(o,r)}catch{a=await s.handleConflicts(r)}else a=await s.handleConflicts(r)
|
|
3322
|
-
return f({success:!1,reason:"merge_conflicts_handled"}),{content:[{type:"text",text:a.userMessage}],isError:!1}}const r=(0,c.getErrorMessage)(e)
|
|
3323
|
-
return f({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Request completion failed during merge: "+r}],isError:!0}}}try{await l.proxyPost(`/api/projects/${t.projectId}/requests/${o}/finalize-completion`,{summary:s,acceptanceEvidence:d,mergeResult:{mergeCommitHash:w.mergeCommitHash,mergedFiles:w.mergedFiles,cleanedUp:w.cleanedUp,method:b.method}})}catch(e){const t=(0,c.getErrorMessage)(e)
|
|
3324
|
-
return p.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:o,mergeCommitHash:w.mergeCommitHash,error:t}),f({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was successfully merged (commit: ${w.mergeCommitHash.substring(0,8)}) but failed to update request status: ${t}`}],isError:!0}}return f({success:!0}),{content:[{type:"text",text:"Request completed: "+o}]}}catch(r){let n="An unexpected error occurred",i=""
|
|
3325
|
-
r instanceof o.ZodError?(n="Validation error",i=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")):r instanceof Error?(n=r.message,i=r.stack||""):i=r+"",p.error("Complete request failed",{error:n,details:i})
|
|
3326
|
-
try{await(0,s.createFailureToolRecord)("complete-request",r,{error:n,details:i,requestId:e?.requestId},l.getToolRecordClient(),p,u,{requestId:e?.requestId,projectId:t.projectId,note:"Failed to complete request"})}catch{}return f({success:!1,error:r instanceof Error?r.name:"unknown"}),{content:[{type:"text",text:"Error: "+n}],isError:!0}}}
|
|
3327
|
-
const r=t(9860),n=t(715),o=t(1569),s=t(8616),i=t(1651),a=t(7478),c=t(8824)},5767(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3297
|
+
g.info("Starting request completion",{requestId:o})
|
|
3298
|
+
const l=h?.sessionId||(0,n.getCachedSession)()?.sessionId
|
|
3299
|
+
let d
|
|
3300
|
+
try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${o}/validate-completion`,{sessionId:l})
|
|
3301
|
+
d=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
3302
|
+
return g.error("Server validation failed",{requestId:o,error:t}),p({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate completion: "+t}],isError:!0}}if(!d.canComplete){let e=`Cannot complete request ${o}: ${d.reason}\n`
|
|
3303
|
+
return d.blockedByTasks&&d.blockedByTasks.length>0&&(e+="\n**Tasks that must be completed or canceled first:**\n",d.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (Status: ${t.status})\n`}))),d.lifoViolation&&(e+="\n**Requests that must be re-completed first (LIFO order):**\n",d.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (Status: ${t.status})\n`}))),p({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}const u=c.getRequestClient(),f="auto-test-then-merge"===d.completionMode,m=f?"ready_for_review":"ready_for_merge"
|
|
3304
|
+
try{await u.updateRequest(o,{status:m,completionSummary:s})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
3305
|
+
return p({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let y
|
|
3306
|
+
try{y=await u.getRequest(o)}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
3307
|
+
return p({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const w=y?.acceptanceCriteria||[]
|
|
3308
|
+
return p({success:!0}),f?{content:[{type:"text",text:`Request ${o} moved to ready_for_review. Testing is active \u2014 a notification has been created for the user to choose testing mode. Do NOT call merge or any other tool. Your work is done. Stop here and wait.`}]}:0===w.length?{content:[{type:"text",text:`Request ${o} is ready. No acceptance criteria defined \u2014 call merge directly.`}]}:{content:[{type:"text",text:`Request ${o} completion started (${m}).\n\n## Next Step: Verify & Merge\n\n${(0,a.formatVerifyInstructions)(w)}\n\nUse the merge operation with your verification evidence to merge to main.`}]}}catch(r){let n="An unexpected error occurred",i=""
|
|
3309
|
+
r instanceof o.ZodError?(n="Validation error",i=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")):r instanceof Error?(n=r.message,i=r.stack||""):i=r+"",g.error("Complete request failed",{error:n,details:i})
|
|
3310
|
+
try{await(0,s.createFailureToolRecord)("complete-request",r,{error:n,details:i,requestId:e?.requestId},c.getToolRecordClient(),g,d,{requestId:e?.requestId,projectId:t.projectId,note:"Failed to complete request"})}catch{}return d.startTimer("tool_execution_time")({success:!1,error:r instanceof Error?r.name:"unknown"}),{content:[{type:"text",text:"Error: "+n}],isError:!0}}}
|
|
3311
|
+
const r=t(9860),n=t(715),o=t(1569),s=t(8616),i=t(8824),a=t(5454)},5767(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3328
3312
|
const r=t(6183),n=t(6285)
|
|
3329
3313
|
exports.def={name:"specialist_ops",description:"Manage your pool of up to 10 specialists. Each has a specialization describing their domain. Reuse specialists via follow-up before spawning new ones.\n\nOperations:\n\u2022 delegate - Spawn a new specialist (include specialization). Abort an idle specialist first if pool is full.\n\u2022 follow-up - Send follow-up instructions to an existing specialist (can update specialization)\n\u2022 check-status - Check if a specialist is busy or idle\n\u2022 list - List specialist sessions with specializations\n\u2022 abort - Cancel a stuck specialist",schema:r.SpecialistOpsSchema,annotations:{title:"Specialist Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleSpecialistOps)(e,t.context,t.logger,t.metrics,t.apiClient??void 0,t.cliOrigin)}}},5802(module){module.exports=require("@modelcontextprotocol/sdk/server/stdio.js")},5806(e,exports,t){function r(){const e=n.z.object({requestId:n.z.string(),summary:n.z.string(),acceptanceEvidence:n.z.array(n.z.object({evidence:n.z.string()}))}),t=n.z.object({testRecords:n.z.array(n.z.string()),coverage:n.z.object({criteriaTestedCount:n.z.number(),totalTestCases:n.z.number()}),criterionCoverage:n.z.array(n.z.object({coverage:n.z.enum(["none","partial","full"]),testRecords:n.z.array(n.z.string())}))})
|
|
3330
3314
|
return(0,o.areTestsRequiredForCompletion)()?e.extend({testVerification:t}):e}Object.defineProperty(exports,"__esModule",{value:!0}),exports.DynamicCompleteRequestSchema=void 0,exports.getDynamicCompleteRequestSchema=r
|
|
@@ -3343,8 +3327,8 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
|
3343
3327
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3344
3328
|
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()
|
|
3345
3329
|
let y,w,b=l.FileOperationPhase.VALIDATION
|
|
3346
|
-
const
|
|
3347
|
-
try{const n=r.getTaskClient(),u=r.getToolRecordClient(),
|
|
3330
|
+
const I={toolName:"delete-files",operationName:"delete",fileOperationPhase:l.FileOperationPhase.FILE_WRITE,recordType:"delete-files",metricsPrefix:"delete_files",successMessage:"Successfully deleted files",failureMessage:"Failed to delete files"}
|
|
3331
|
+
try{const n=r.getTaskClient(),u=r.getToolRecordClient(),k=r.getRequestClient(),v=l.validateArgs(e,c.DeleteFilesSchema),{taskId:C,paths:_,operations:E,comment:q}=v
|
|
3348
3332
|
let S=[]
|
|
3349
3333
|
if(_)S=_.map((e=>({type:"file",target:e})))
|
|
3350
3334
|
else{if(!E)throw Error("Either paths or operations must be specified")
|
|
@@ -3352,22 +3336,22 @@ S=E.map((e=>{if(e.path)return{type:"file",target:e.path}
|
|
|
3352
3336
|
if(e.documentId)return{type:"document",target:e.documentId}
|
|
3353
3337
|
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")
|
|
3354
3338
|
const T=S.filter((e=>"file"===e.type)),P=S.filter((e=>"document"===e.type)),R=S.length
|
|
3355
|
-
i.info("Starting mixed file and document deletion operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,comment:q}),l.validateTaskIdFormat(C,i,o,
|
|
3339
|
+
i.info("Starting mixed file and document deletion operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,comment:q}),l.validateTaskIdFormat(C,i,o,I.metricsPrefix)
|
|
3356
3340
|
const M=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3357
3341
|
i.info("Initial branch context",{initialBranch:M.branch,initialRequestId:M.requestId,isMain:M.isMain})
|
|
3358
3342
|
const j=[]
|
|
3359
3343
|
for(const e of T){const{normalizedPath:r,fullPath:n}=l.validateAndNormalizePath(e.target,t)
|
|
3360
3344
|
j.push({normalized:r,full:n})}b=l.FileOperationPhase.TASK_VALIDATION,o.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3361
|
-
const x=j.length>0?j[0].normalized:"document_operations",O=await l.validateTaskId(C,x,n,i,o,
|
|
3362
|
-
$.taskPromoted&&i.info(`Auto-promoted task ${C} (${O.title||"Untitled"}) to in_progress for mixed operations`,{taskId:C,taskTitle:O.title,previousStatus:O.status,newStatus:$.newTaskStatus,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length}),$.requestPromoted&&i.info(`Auto-promoted request ${
|
|
3363
|
-
const F=await l.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:
|
|
3345
|
+
const x=j.length>0?j[0].normalized:"document_operations",O=await l.validateTaskId(C,x,n,i,o,I.metricsPrefix),D=O?.requestId,A=await l.validateWorkItemStates(C,x,n,k,t,i,o,I.metricsPrefix),$=await l.autoPromoteTaskStatus(C,O.status,D,A.request?.status,x,n,k,i,o,I.metricsPrefix)
|
|
3346
|
+
$.taskPromoted&&i.info(`Auto-promoted task ${C} (${O.title||"Untitled"}) to in_progress for mixed operations`,{taskId:C,taskTitle:O.title,previousStatus:O.status,newStatus:$.newTaskStatus,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length}),$.requestPromoted&&i.info(`Auto-promoted request ${D} to in_progress for file operations`,{requestId:D,previousStatus:A.request?.status,newStatus:$.newRequestStatus,triggeringTaskId:C})
|
|
3347
|
+
const F=await l.ensureCorrectWorkspaceContext({taskPromoted:$.taskPromoted,requestId:D,context:t,operation:"delete-files",logger:i,metrics:o,metricsPrefix:I.metricsPrefix})
|
|
3364
3348
|
if(!F.success){if(F.isLockConflict)return{content:[{type:"text",text:"\u274c "+F.error}],isError:!0}
|
|
3365
3349
|
throw Error(F.error)}let N={hadUserMods:!1,userModsCommitHash:void 0}
|
|
3366
3350
|
if(t.git)try{i.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
|
|
3367
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(t.git,"delete-files",{requestId:
|
|
3351
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(t.git,"delete-files",{requestId:D,taskId:C,workspaceManager:t.workspaceManager},i,o)
|
|
3368
3352
|
e.userChangesCommitted&&(i.debug("[DELETE-FILES] User changes committed before mixed delete operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),i.info("User changes committed before mixed delete-files operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),N={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){i.debug("[DELETE-FILES] Pre-tool commit failed, continuing with mixed delete operations",{error:e instanceof Error?e.message:e+""}),i.warn("Pre-tool user changes commit failed, continuing with mixed delete operation",{taskId:C,totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,error:e instanceof Error?e.message:e+""})}i.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:S.length,fileDeletes:T.length,documentDeletes:P.length}),b=l.FileOperationPhase.RECORD_CREATION,o.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3369
|
-
const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,
|
|
3370
|
-
y=L,w=L,b=
|
|
3353
|
+
const{toolRecordId:L,localToolRecordId:z}=await l.createFileOperationRecords(C,D,t.projectId,I.recordType,x,{totalOperations:S.length,fileOperations:T.length,documentOperations:P.length,filePaths:j.map((e=>e.normalized)),documentIds:P.map((e=>e.target)),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},n,u,i,o,I.metricsPrefix,s)
|
|
3354
|
+
y=L,w=L,b=I.fileOperationPhase,o.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3371
3355
|
const B=[]
|
|
3372
3356
|
let H=0
|
|
3373
3357
|
P.length>0&&r.setProjectId(t.projectId)
|
|
@@ -3376,7 +3360,7 @@ try{try{await a.default.access(t.full)}catch(e){throw Error("File not found: "+t
|
|
|
3376
3360
|
await a.default.unlink(t.full),r.success=!0,H++,i.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete file "+t.normalized,{error:r.error})}B.push(r)}const U=P.length>0?r.getDocumentClient():null
|
|
3377
3361
|
for(const e of P){const t=e.target,n={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3378
3362
|
try{let e
|
|
3379
|
-
try{if(e=await U.getDocument(t),n.filename=e.filename,i.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,g.validateRequestStatusForDocumentOperation)(e.requestId,
|
|
3363
|
+
try{if(e=await U.getDocument(t),n.filename=e.filename,i.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,g.validateRequestStatusForDocumentOperation)(e.requestId,k,i,o,"delete-document")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
|
|
3380
3364
|
throw e}try{await(0,p.ensureDocumentNotLocked)(t,r,i,o,"delete-document-archive")}catch(e){if(e instanceof d.ValidationError)throw Error(e.message)
|
|
3381
3365
|
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,f.getErrorMessage)(e)}`)}const s=await U.archiveDocument(t)
|
|
3382
3366
|
n.success=!0,n.filename=s.filename,H++,i.info("Document archived successfully",{documentId:s.id,filename:s.filename,archivedAt:s.archived_at})}catch(e){n.error=(0,f.getErrorMessage)(e),i.warn("Failed to delete document "+t,{error:n.error})}B.push(n)}const W=Date.now()-m
|
|
@@ -3385,9 +3369,9 @@ let G=null
|
|
|
3385
3369
|
if(H>0){b=l.FileOperationPhase.GIT_COMMIT,o.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3386
3370
|
const e=B.filter((e=>e.success)),r=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
|
|
3387
3371
|
let s
|
|
3388
|
-
s=r>0&&n>0?`Delete ${r} files and ${n} documents - ${q}`:r>0?1===r?"Delete file - "+q:`Delete ${r} files - ${q}`:1===n?"Delete document - "+q:`Delete ${n} documents - ${q}`,G=await l.commitToGit(C,x,L,z,s,t,i,o,
|
|
3372
|
+
s=r>0&&n>0?`Delete ${r} files and ${n} documents - ${q}`:r>0?1===r?"Delete file - "+q:`Delete ${r} files - ${q}`:1===n?"Delete document - "+q:`Delete ${n} documents - ${q}`,G=await l.commitToGit(C,x,L,z,s,t,i,o,I.metricsPrefix)}b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,o.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3389
3373
|
const V=B.filter((e=>e.success)),J=B.filter((e=>!e.success))
|
|
3390
|
-
await l.updateFileOperationRecords(C,y,w,x,
|
|
3374
|
+
await l.updateFileOperationRecords(C,y,w,x,I.recordType,H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,{status:H===R?"completed":"partial_success",commitHash:G?.commitHash,previousCommitHash:G?.previousCommitHash,totalOperations:R,fileOperations:T.length,documentOperations:P.length,successCount:H,failureCount:R-H,successfulOperations:V.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:J.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:q,hadUserMods:N.hadUserMods,userModsCommitHash:N.userModsCommitHash},H===R?`Successfully deleted all ${R} operations`:`Deleted ${H}/${R} operations successfully`,n,u,i,o,I.metricsPrefix)
|
|
3391
3375
|
const K=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3392
3376
|
let Y=""
|
|
3393
3377
|
if(H===R){const e=V.filter((e=>"file"===e.type)).length,t=V.filter((e=>"document"===e.type)).length
|
|
@@ -3398,7 +3382,7 @@ return G?.commitHash&&(Y+="\nCommit: "+G.commitHash.substring(0,8)),K.requestId&
|
|
|
3398
3382
|
await o.createToolRecord({...s?{}:{taskId:e.taskId},projectId:t.projectId,type:"delete-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment,error:(0,f.getErrorMessage)(n),errorDetails:n instanceof Error?n.stack:n+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,f.getErrorMessage)(n)})}catch(t){i.error("Failed to create failure record for delete-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0})}const s=Date.now()-m
|
|
3399
3383
|
if(o.recordValue("delete_files_time",s),o.incrementCounter("delete_files_errors",1),i.error("Error in delete-files operation:",{error:(0,f.getErrorMessage)(n),time:s}),(y||w)&&e.taskId){b=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
3400
3384
|
try{const t=r.getTaskClient(),s=r.getToolRecordClient()
|
|
3401
|
-
await l.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",
|
|
3385
|
+
await l.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",I.recordType,"Failed to delete operations",{status:"failed",error:(0,f.getErrorMessage)(n),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment},"Failed to delete operations",t,s,i,o,I.metricsPrefix)}catch(t){i.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(n,b,i,o,e,I)}}
|
|
3402
3386
|
const a=i(t(1943)),c=t(6183),l=s(t(5967)),d=t(9860),u=t(1569),h=t(7478),g=t(5003),p=t(9949),f=t(8824)},5997(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3403
3387
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3404
3388
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
|
|
@@ -3458,21 +3442,19 @@ const n=await this.requestWithRetry("POST","/api/files/recover",t)
|
|
|
3458
3442
|
if(!(0,i.safeGetResponseData)(n,null))throw new r.ServiceError("Empty response when recovering file")
|
|
3459
3443
|
const o=(0,i.safeGetResponseData)(n,{success:!0,path:e.path,commitHash:e.commitHash,backupPath:void 0})
|
|
3460
3444
|
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({
|
|
3463
|
-
return"get-info"===e.operation?!t&&r&&!n:"list"===e.operation&&!r&&n}),{message:"Invalid operation data"})
|
|
3445
|
+
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). If you don't have a task yet, create one first using task_operations with operation 'create'."}),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)"})
|
|
3446
|
+
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","ready_for_merge","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({operation:r.z.enum(["get-info","list"]),taskId:o.optional(),requestId:s.optional(),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")}).superRefine(((e,t)=>{"get-info"!==e.operation||e.taskId||t.addIssue({code:"custom",message:'taskId is required for get-info. Example: { "operation": "get-info", "taskId": "tas000001" }'}),"list"!==e.operation||e.requestId||t.addIssue({code:"custom",message:'requestId is required for list. Example: { "operation": "list", "requestId": "req000001" }'})}))
|
|
3464
3447
|
const a=r.z.string().min(1).describe("OpenCode session ID")
|
|
3465
3448
|
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
|
|
3466
3449
|
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
|
|
3467
3450
|
return"delegate"===e.operation?r&&!n&&!t:"follow-up"===e.operation?n&&!r&&t:"check-status"===e.operation||"abort"===e.operation?!r&&!n&&t:"list"===e.operation&&!r&&!n&&!t}),{message:"Invalid operation data: delegate requires delegate object, follow-up/check-status/abort require sessionId"}),exports.PlannerOpsSchema=r.z.object({operation:r.z.enum(["request","check-status","list"]),request:r.z.object({prompt:r.z.string().min(1).describe("What to plan \u2014 feature description, architecture question, etc."),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars)")}).optional(),sessionId:a.optional(),list:r.z.object({activeOnly:r.z.boolean().default(!1).describe("Only show active/busy planning sessions"),limit:r.z.number().min(1).max(100).optional().describe("Max sessions to return")}).optional()}).refine((e=>{const t=!!e.request,r=!!e.sessionId
|
|
3468
|
-
return"request"===e.operation?t&&!r:"check-status"===e.operation?!t&&r:"list"===e.operation&&!t&&!r}),{message:"Invalid operation data: request requires request object, check-status requires sessionId"}),exports.SwitchToRequestBranchSchema=r.z.object({requestId:s}),exports.InsertLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.CreateDocumentSchema=r.z.object({requestId:s.optional(),filename:r.z.string().refine((e=>e.toLowerCase().endsWith(".md")),{message:"Filename must end with .md extension"}),content:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"],{errorMap(){return{message:"Document type must be one of: Report, Documentation, Plan, Other"}}}),comment:r.z.string()}),exports.SearchDocumentsSchema=r.z.object({query:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),requestId:s.optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both")}),exports.DocumentOperationsSchema=r.z.object({operation:r.z.enum(["create","search","create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"]),
|
|
3451
|
+
return"request"===e.operation?t&&!r:"check-status"===e.operation?!t&&r:"list"===e.operation&&!t&&!r}),{message:"Invalid operation data: request requires request object, check-status requires sessionId"}),exports.SwitchToRequestBranchSchema=r.z.object({requestId:s}),exports.InsertLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.CreateDocumentSchema=r.z.object({requestId:s.optional(),filename:r.z.string().refine((e=>e.toLowerCase().endsWith(".md")),{message:"Filename must end with .md extension"}),content:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"],{errorMap(){return{message:"Document type must be one of: Report, Documentation, Plan, Other"}}}),comment:r.z.string()}),exports.SearchDocumentsSchema=r.z.object({query:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),requestId:s.optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both")}),exports.DocumentOperationsSchema=r.z.object({operation:r.z.enum(["create","search","create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"]),documentId:i.optional(),requestId:s.optional(),filename:r.z.string().optional(),content:r.z.string().optional(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),comment:r.z.string().optional(),query:r.z.string().optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both"),versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional(),versionNumber:r.z.number().int().min(1).optional(),selectedText:r.z.string().optional(),prefixContext:r.z.string().optional(),suffixContext:r.z.string().optional(),lineHint:r.z.number().int().optional(),body:r.z.string().optional(),annotationId:r.z.string().optional()}).superRefine(((e,t)=>{const r=e.operation;["create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"].includes(r)&&!e.documentId&&t.addIssue({code:"custom",message:`documentId is required for '${r}'. Example: { "operation": "${r}", "documentId": "doc000001" }`}),"create"===r&&(e.filename?e.filename.toLowerCase().endsWith(".md")||t.addIssue({code:"custom",message:"Filename must end with .md extension"}):t.addIssue({code:"custom",message:"filename is required for create (must end with .md)"}),e.content||t.addIssue({code:"custom",message:"content is required for create"}),e.type||t.addIssue({code:"custom",message:"type is required for create (Report, Documentation, Plan, or Other)"}),e.comment||t.addIssue({code:"custom",message:"comment is required for create"})),"search"!==r||e.query||t.addIssue({code:"custom",message:'query is required for search. Example: { "operation": "search", "query": "search term" }'}),"get-version"!==r&&"restore-version"!==r||e.versionNumber||t.addIssue({code:"custom",message:`versionNumber is required for '${r}'`}),"create-annotation"===r&&(e.selectedText||t.addIssue({code:"custom",message:"selectedText is required for create-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for create-annotation"})),"reply-to-annotation"===r&&(e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for reply-to-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for reply-to-annotation"})),"resolve-annotation"!==r||e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for resolve-annotation"})}))
|
|
3469
3452
|
const c=r.z.string().refine((e=>!!e&&(/^doc_[0-9A-Z]{26}$/i.test(e)||/^plan\d{6}$/.test(e))),{message:"Plan ID must match format: doc_[26 alphanumeric] (ULID) or plan###### (local ID)"})
|
|
3470
|
-
exports.PlanReadSchema=r.z.object({operation:r.z.enum(["get","get-active","list","get-history","get-requests"]),
|
|
3471
|
-
|
|
3472
|
-
if(
|
|
3473
|
-
const
|
|
3474
|
-
|
|
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")})
|
|
3453
|
+
exports.PlanReadSchema=r.z.object({operation:r.z.enum(["get","get-active","list","get-history","get-requests"]),planId:c.optional(),searchQuery:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["createdAt","updatedAt","filename"]).default("updatedAt"),sortDirection:r.z.enum(["ASC","DESC"]).default("DESC")}).superRefine(((e,t)=>{["get","get-history","get-requests"].includes(e.operation)&&!e.planId&&t.addIssue({code:"custom",message:`planId is required for '${e.operation}'. Example: { "operation": "${e.operation}", "planId": "plan000001" }`})})),exports.PlanWriteSchema=r.z.object({operation:r.z.enum(["update","append","replace","create-snapshot","restore","set-active"]),planId:c,content:r.z.string().optional(),name:r.z.string().optional().describe("Optional new name for the plan"),old:r.z.string().optional().describe("Text to find in the plan (for replace)"),new:r.z.string().optional().describe("Replacement text (for replace)"),versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional(),versionNumber:r.z.number().int().min(1).optional()}).superRefine(((e,t)=>{const r=e.operation
|
|
3454
|
+
"update"!==r&&"append"!==r||e.content||t.addIssue({code:"custom",message:`content is required for '${r}'. Example: { "operation": "${r}", "planId": "plan000001", "content": "..." }`}),"replace"===r&&(e.old||t.addIssue({code:"custom",message:'old is required for replace. Example: { "operation": "replace", "planId": "plan000001", "old": "find this", "new": "replace with" }'}),void 0===e.new&&t.addIssue({code:"custom",message:"new is required for replace"})),"restore"!==r||e.versionNumber||t.addIssue({code:"custom",message:'versionNumber is required for restore. Example: { "operation": "restore", "planId": "plan000001", "versionNumber": 1 }'})})),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional(),password:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:s,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),operationType:r.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:r.z.object({replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).optional(),insertLines:r.z.object({insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).optional(),replaceLines:r.z.object({replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).optional(),deleteString:r.z.object({patterns:r.z.array(r.z.string()),mode:r.z.enum(["all","unique"]).optional()}).optional(),deleteLines:r.z.object({lines:r.z.string()}).optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}).refine((e=>"replace-string"===e.operationType?e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"insert-lines"===e.operationType?e.insertLines&&!e.replaceString&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"replace-lines"===e.operationType?e.replaceLines&&!e.replaceString&&!e.insertLines&&!e.deleteString&&!e.deleteLines:"delete-string"===e.operationType?e.deleteString&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteLines:"delete-lines"===e.operationType&&e.deleteLines&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString),{message:"Invalid operation data"})),comment:r.z.string()}),exports.ManageFilesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"}))}).optional(),getFileInfo:r.z.object({path:r.z.string()}).optional()}).refine((e=>"create-directory"===e.operationType?e.createDirectory&&!e.moveFiles&&!e.deleteFiles&&!e.getFileInfo:"move-files"===e.operationType?e.moveFiles&&!e.createDirectory&&!e.deleteFiles&&!e.getFileInfo:"delete-files"===e.operationType?e.deleteFiles&&!e.createDirectory&&!e.moveFiles&&!e.getFileInfo:"get-file-info"===e.operationType&&e.getFileInfo&&!e.createDirectory&&!e.moveFiles&&!e.deleteFiles),{message:"Invalid operation data"})),comment:r.z.string()}),exports.RequestOperationsSchema=r.z.object({requestId:s.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search"]),complete:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({summary:r.z.string()})).optional(),merge:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({verifications:r.z.array(r.z.object({key:r.z.string().min(2).max(4),evidence:r.z.string().min(1)})).min(1)})).optional(),revert:r.z.object({reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}).optional(),list:r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),approve:r.z.object({}).optional()}).superRefine(((e,t)=>{const r=!!e.requestId,n=e.operation
|
|
3455
|
+
if(["complete","merge","approve","revert","get-info"].includes(n)&&!r)return void t.addIssue({code:"custom",message:`requestId is required for '${n}' operation`})
|
|
3456
|
+
const o={complete:{field:"complete",hint:'Provide: { complete: { summary: "..." } }'},merge:{field:"merge",hint:'Provide: { merge: { verifications: [{key: "1a", evidence: "..."}] } }'},revert:{field:"revert",hint:'Provide: { revert: { reason: "..." } }'},search:{field:"search",hint:'Provide: { search: { query: "..." } }'}}[n]
|
|
3457
|
+
o&&!e[o.field]&&t.addIssue({code:"custom",message:`'${n}' operation requires '${o.field}' data. ${o.hint}`})})),exports.QuickWriteSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),path:r.z.string().optional(),documentId:i.optional(),content:r.z.union([r.z.string(),r.z.record(r.z.any()),r.z.array(r.z.unknown())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}),exports.QuickReplaceSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:r.z.boolean().optional()})).min(1),fuzzy_match:r.z.boolean().optional(),comment:r.z.string().min(1,"Comment describing the change is required")}),exports.QuickManageSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.optional()}))}).optional()})).min(1)}),exports.GenerateRequestJournalSchema=r.z.object({requestId:r.z.string().regex(/^req[_\d].+$/,"Invalid request ID format. Expected format: req_[26 chars] or req######")}),exports.MetaWorkflowListSchema=r.z.object({}),exports.MetaWorkflowGetSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the workflow"),shortName:r.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:r.z.string().optional().describe("Description of what the workflow does"),documentation:r.z.string().optional().describe("Detailed documentation"),defaultAgent:r.z.string().optional().describe("Default agent template to use"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior: auto-merge (default), auto-test-then-merge, or manual-review"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaWorkflowUpdateSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to update"),name:r.z.string().min(1).optional().describe("New name"),shortName:r.z.string().max(10).optional().describe("New short name (max 10 chars)"),description:r.z.string().optional().describe("New description"),documentation:r.z.string().optional().describe("New documentation"),defaultAgent:r.z.string().optional().describe("New default agent"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaRecipeListSchema=r.z.object({}),exports.MetaRecipeGetSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to retrieve")}),exports.MetaRecipeCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the recipe"),description:r.z.string().optional().describe("Description of what the recipe does"),documentation:r.z.string().optional().describe("Detailed documentation")}),exports.MetaRecipeAddHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to add the hook to"),hookId:r.z.string().describe("Hook template ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the recipe (0-based, appended if omitted)")}),exports.MetaRecipeRemoveHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to remove the hook from"),hookId:r.z.string().describe("Hook template ID to remove")}),exports.MetaHookListSchema=r.z.object({}),exports.MetaHookCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the hook"),description:r.z.string().optional().describe("Description of what the hook does"),eventType:r.z.string().describe("Event type that triggers this hook (e.g., session_idle, request_completed, custom:plan_ready)"),category:r.z.enum(["alchemy","session","message","editing","reading","file_management","documents","history","tool"]).default("session").describe("Hook category"),agent:r.z.string().describe("Agent template to execute when hook fires"),promptTemplate:r.z.string().describe("Prompt template with {{variable}} substitution"),condition:r.z.record(r.z.any()).optional().describe("Condition object for filtering when hook fires"),executionMode:r.z.enum(["same_session","sub_agent","background","notification","direct_report"]).default("background").describe("How to execute the hook"),timing:r.z.enum(["before","after"]).default("after").describe("When to fire relative to the event"),maxIterations:r.z.number().int().min(1).optional().describe("Maximum times to fire per session"),emitEvent:r.z.string().optional().describe("Custom event to emit on completion"),emitEventOnCondition:r.z.union([r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}),r.z.array(r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}))]).optional().describe("Conditional event emission based on output")}),exports.MetaWorkflowAddRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to add the recipe to"),recipeId:r.z.string().describe("Recipe ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the workflow (0-based, appended if omitted)")}),exports.MetaWorkflowRemoveRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to remove the recipe from"),recipeId:r.z.string().describe("Recipe ID to remove")}),exports.MetaAgentListSchema=r.z.object({}),exports.MetaReferenceSchema=r.z.object({}),exports.TestingProcessListSchema=r.z.object({}),exports.TestingProcessGetSchema=r.z.object({processId:r.z.string().describe("Test process ID to retrieve")})
|
|
3476
3458
|
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)")})
|
|
3477
3459
|
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
|
|
3478
3460
|
const r=t(6183),n=t(405)
|
|
@@ -3485,10 +3467,10 @@ var t={}
|
|
|
3485
3467
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3486
3468
|
return o(t,e),t})
|
|
3487
3469
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,r,n,o,s,f){const m=n.child({tool:"specialist_ops"}),y=o.startTimer("tool_execution_time")
|
|
3488
|
-
try{if(!e?.operation&&e&&(e.prompt&&!e.sessionId?e.operation="delegate":e.prompt&&e.sessionId?e.operation="follow-up":e.sessionId&&(e.operation="check-status")),"string"==typeof e?.delegate){const t=e.delegate
|
|
3470
|
+
try{if(!e?.operation&&e&&(e.prompt&&!e.sessionId?e.operation="delegate":e.prompt&&e.sessionId?e.operation="follow-up":e.sessionId&&(e.operation="check-status")),e?.followUp&&"string"==typeof e.followUp)try{e.followUp=JSON.parse(e.followUp)}catch{}if(e?.delegate&&"string"==typeof e.delegate)try{e.delegate=JSON.parse(e.delegate)}catch{}if("string"==typeof e?.delegate){const t=e.delegate
|
|
3489
3471
|
e.delegate={prompt:e.prompt||t,description:e.description||t.slice(0,60),specialization:e.specialization||"general",requestId:e.requestId},e.operation=e.operation||"delegate",delete e.prompt,delete e.description,delete e.specialization,delete e.requestId}"follow-up"===e?.operation&&e?.prompt&&!e?.followUp&&(e.followUp={prompt:e.prompt,specialization:e.specialization},delete e.prompt,e.specialization&&delete e.specialization),"delegate"===e?.operation&&e?.prompt&&!e?.delegate&&(e.delegate={prompt:e.prompt,description:e.description||e.prompt.slice(0,60),specialization:e.specialization||"general",requestId:e.requestId},delete e.prompt,delete e.description,delete e.specialization,delete e.requestId)
|
|
3490
3472
|
const n=c.validateArgs(e,a.SpecialistOpsSchema),{operation:w,sessionId:b}=n
|
|
3491
|
-
let
|
|
3473
|
+
let I
|
|
3492
3474
|
switch(m.info("Processing specialist_ops",{operation:w,sessionId:b}),w){case"delegate":{const e=n.delegate,o=10
|
|
3493
3475
|
let i=f?.sessionId||p.sessionIdentity.getIdentity()?.sessionId
|
|
3494
3476
|
if(!i){const e=await(0,h.getServerUrl)(r,m)
|
|
@@ -3506,7 +3488,7 @@ if(n.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t
|
|
|
3506
3488
|
const g=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
|
|
3507
3489
|
return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
|
|
3508
3490
|
return{content:[{type:"text",text:`\u274c Specialist pool is full (${h.length}/${t}).\nAbort an idle specialist first with \`specialist_ops abort\`, then delegate again.\n\nCurrent pool:\n`+g}],isError:!0}}catch(e){return void n.warn("Pool limit check failed, allowing spawn",{error:(0,l.getErrorMessage)(e)})}}(i,o,r,m,s)
|
|
3509
|
-
if(e){
|
|
3491
|
+
if(e){I=e
|
|
3510
3492
|
break}}let a=e.description
|
|
3511
3493
|
const c=await Promise.resolve().then(t.t.bind(t,9896,23)),y=e=>c.appendFileSync("/tmp/specialist-name-debug.log",`${(new Date).toISOString()} ${e}\n`)
|
|
3512
3494
|
if(i)try{const e=await(0,h.getServerUrl)(r,m)
|
|
@@ -3516,22 +3498,22 @@ y(`siblings=${e.length}: ${e.join(", ")}`)
|
|
|
3516
3498
|
const r=(0,d.pickSpecialistName)(e)
|
|
3517
3499
|
a=r,y("picked name: "+r)}}else y("no serverUrl")}catch(e){y("error: "+(e instanceof Error?e.message:e+""))}else y("no parentId")
|
|
3518
3500
|
const w=e.requestId,b=w?`Working on request ${w}.\n\n${e.prompt}`:e.prompt
|
|
3519
|
-
|
|
3501
|
+
I=await(0,u.handleSpawn)({agent:"specialist",prompt:b,title:a,specialization:e.specialization},r,m,s,f)
|
|
3520
3502
|
break}case"follow-up":{const e=await(0,h.getServerUrl)(r,m)
|
|
3521
3503
|
if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
|
|
3522
3504
|
if(t.ok){const e=await t.json(),r=e[b]?.type
|
|
3523
|
-
if(r&&"idle"!==r&&"prompting"!==r){
|
|
3524
|
-
break}}}catch{}
|
|
3505
|
+
if(r&&"idle"!==r&&"prompting"!==r){I={content:[{type:"text",text:`\u274c Specialist ${b} is currently busy (status: ${r}).\nUse \`delegate\` to spawn a new specialist instead.`}],isError:!0}
|
|
3506
|
+
break}}}catch{}I=await(0,u.handleContinue)(b,n.followUp.prompt,r,m,s,"specialist",f)
|
|
3525
3507
|
const t=n.followUp.specialization
|
|
3526
3508
|
if(t&&s)try{const e=s.getCLISessionClient()
|
|
3527
|
-
e&&(await e.createOrUpdateSession({externalSessionId:b,specialization:t}),
|
|
3509
|
+
e&&(await e.createOrUpdateSession({externalSessionId:b,specialization:t}),I.content[0].text+="\nSpecialization updated to: "+t)}catch{}break}case"check-status":I=await(0,u.handleCheckStatus)(b,r,m,s)
|
|
3528
3510
|
break
|
|
3529
|
-
case"abort":if(
|
|
3511
|
+
case"abort":if(I=await(0,u.handleAbort)(b,r,m),!I.isError&&s)try{const e=s.getCLISessionClient()
|
|
3530
3512
|
e&&await e.createOrUpdateSession({externalSessionId:b,status:"archived"})}catch{}break
|
|
3531
3513
|
case"list":{let e=f?.sessionId||p.sessionIdentity.getIdentity()?.sessionId
|
|
3532
3514
|
if(!e){const t=await(0,h.getServerUrl)(r,m)
|
|
3533
|
-
if(t)try{e=(0,g.getCachedSession)()?.sessionId||await(0,h.discoverParentSessionId)(t,m)}catch{}}
|
|
3534
|
-
break}default:throw new i.ValidationError("Unknown operation: "+w)}return y({success:!0}),o.incrementCounter(`specialist_ops_${w}_success`,1),
|
|
3515
|
+
if(t)try{e=(0,g.getCachedSession)()?.sessionId||await(0,h.discoverParentSessionId)(t,m)}catch{}}I=await(0,u.handleListSessions)(r,m,s,{activeOnly:n.list?.activeOnly,requestId:n.list?.requestId,limit:n.list?.limit,agentType:"specialist",parentSessionId:e})
|
|
3516
|
+
break}default:throw new i.ValidationError("Unknown operation: "+w)}return y({success:!0}),o.incrementCounter(`specialist_ops_${w}_success`,1),I}catch(e){return m.error("Specialist ops failed",{error:e instanceof Error?e.stack:e+""}),y({success:!1}),o.incrementCounter("specialist_ops_errors",1),{content:[{type:"text",text:"Specialist operation failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
3535
3517
|
const i=t(9860),a=t(6183),c=s(t(5967)),l=t(8824),d=t(9089),u=t(1725),h=t(7617),g=t(715),p=t(6688)},6315(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3536
3518
|
const r=t(6183),n=t(2982)
|
|
3537
3519
|
exports.def={name:"generate_request_journal",description:"Fetch comprehensive data about a request for writing a journal entry.\n\nReturns structured data including:\n\u2022 Request details (title, description, type, status, acceptance criteria)\n\u2022 All tasks with descriptions and status\n\u2022 File changes summary (files modified, operations performed)\n\u2022 Chronological operation history\n\nUse this data to write a narrative journal entry and save it as:\nJOURNAL-{requestId}.md using document-operations (create).",schema:r.GenerateRequestJournalSchema,annotations:{title:"Generate Request Journal",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0},readOnly:!0,hidden(){return"journal"!==process.env.ALCHEMY_MODE},handler(e,t){return(0,n.handleGenerateRequestJournal)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},6416(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
@@ -3609,7 +3591,7 @@ var t={}
|
|
|
3609
3591
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3610
3592
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3611
3593
|
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()
|
|
3612
|
-
let b,k
|
|
3594
|
+
let b,I,k=d.FileOperationPhase.VALIDATION
|
|
3613
3595
|
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"}
|
|
3614
3596
|
try{const i=d.validateArgs(e,l.InsertLinesSchema),{taskId:C,operations:_,comment:E}=i
|
|
3615
3597
|
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")
|
|
@@ -3622,20 +3604,20 @@ if(S.length>0&&!t.documentFileManager)throw Error("Document file manager not ava
|
|
|
3622
3604
|
for(const e of S)P.push({type:"document",documentId:e.documentId,insertions:e.insertions})
|
|
3623
3605
|
if(P.length>0&&t.apiClient){const e=P.map((e=>e.documentId))
|
|
3624
3606
|
try{await(0,p.ensureDocumentsNotLocked)(e,t.apiClient,y,a,"insert-lines-documents")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3625
|
-
throw e}}
|
|
3607
|
+
throw e}}k=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3626
3608
|
const R=T.length>0?T[0].path:"document-operation",M=await d.validateTaskId(C,R,n,y,a,v.metricsPrefix),j=M?.requestId
|
|
3627
3609
|
let x=null
|
|
3628
3610
|
T.length>0&&j&&(x=await d.validateWorkItemStates(C,T[0].path,n,s,t,y,a,v.metricsPrefix))
|
|
3629
3611
|
let O={taskPromoted:!1,requestPromoted:!1}
|
|
3630
3612
|
T.length>0&&j&&x&&(O=await d.autoPromoteTaskStatus(C,M.status,j,x.request?.status,T[0].path,n,s,y,a,v.metricsPrefix),O.taskPromoted&&y.info("Auto-promoted task to in_progress for insert-lines operation",{taskId:C,requestId:j,previousStatus:M.status,newStatus:O.newTaskStatus,triggeringOperation:"insert-lines"}))
|
|
3631
|
-
const
|
|
3632
|
-
if(!
|
|
3633
|
-
throw Error(
|
|
3613
|
+
const D=await d.ensureCorrectWorkspaceContext({taskPromoted:O.taskPromoted,requestId:j,context:t,operation:"insert-lines",logger:y,metrics:a,metricsPrefix:v.metricsPrefix})
|
|
3614
|
+
if(!D.success){if(D.isLockConflict)return{content:[{type:"text",text:"\u274c "+D.error}],isError:!0}
|
|
3615
|
+
throw Error(D.error)}if(T.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:T.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
|
|
3634
3616
|
for(let e=0;e<T.length;e++){const r=T[e],n=q[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
|
|
3635
3617
|
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}
|
|
3636
|
-
throw e}
|
|
3637
|
-
const
|
|
3638
|
-
if(b=$,k
|
|
3618
|
+
throw e}k=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3619
|
+
const A=[...T.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...P.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:$}=await d.createFileOperationRecords(C,j,t.projectId,v.recordType,R,{operationCount:_.length,fileOperations:T.length,documentOperations:P.length,operations:A,userComment:E},n,o,y,a,v.metricsPrefix,m)
|
|
3620
|
+
if(b=$,I=$,k=v.fileOperationPhase,a.incrementCounter("insert_lines_phase",1,{phase:k}),T.length>0&&t.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
|
|
3639
3621
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"insert-lines",{requestId:j,taskId:C,workspaceManager:t.workspaceManager},y,a)
|
|
3640
3622
|
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})
|
|
3641
3623
|
const F=[]
|
|
@@ -3648,9 +3630,9 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
|
|
|
3648
3630
|
n.filename=s?.filename
|
|
3649
3631
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
|
|
3650
3632
|
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))
|
|
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:
|
|
3652
|
-
try{await o.updateToolRecord(
|
|
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"),
|
|
3633
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const B=await d.handleMultiFileGitCommit(C,T,F,z,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:a,metricsPrefix:"insert_lines"},t),H=d.processMultiFileOperationResults(F,"successfulInsertions"),{successfulOperations:U,failedOperations:W,totalSuccessfulChanges:G,overallSuccess:V,successfulFiles:J,failedFiles:K}=H
|
|
3634
|
+
try{await o.updateToolRecord(I,{metadata:{path:T.length>0?T[0].path:"document:"+P[0]?.documentId,status:V?"completed":"failed",error:V?void 0:W+" operations failed",totalOperations:F.length,successfulFiles:J,failedFiles:K,operations:A,totalSuccessfulInsertions:G,totalFailedInsertions:N,totalLinesAdded:L,operationsWithChanges:z,processingTime:Date.now()-w,userComment:E,...T.length>0&&B.success&&B.commitHash&&{commitHash:B.commitHash,previousCommitHash:B.previousCommitHash||void 0}},note:V?`Line insertion completed: ${U}/${F.length} operations successful${T.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${W}/${F.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let Y="## Line Insertion Results\n\n"
|
|
3635
|
+
if(t.workspaceManager&&(Y+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Y+="**Summary:**\n",Y+=`- **Files processed:** ${U+W}\n`,Y+=`- **Successful operations:** ${U}\n`,Y+=`- **Failed operations:** ${W}\n`,Y+=`- **Total insertions:** ${G} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n`,Y+="\n",B.success&&B.commitHash&&(Y+="**Git Commit:**\n",Y+=`- **Commit Hash:** ${B.commitHash.substring(0,8)}\n`,Y+=`- **Files Committed:** ${B.filesCommitted.length}\n`,B.previousCommitHash&&(Y+=`- **Previous Commit:** ${B.previousCommitHash.substring(0,8)}\n`),Y+="\n"),D.lockAcquired&&D.lockedRequestId&&(Y+=`\u{1f512} **Locked request:** ${D.lockedRequestId}\n\n`),1===F.length){const e=F[0]
|
|
3654
3636
|
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"
|
|
3655
3637
|
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}`
|
|
3656
3638
|
Y+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{Y+="**Summary:**\n",Y+=`- **Total Operations:** ${F.length}\n`,Y+=`- **Successful:** ${U}\n`,Y+=`- **Failed:** ${W}\n`,Y+=`- **Total Insertions:** ${G} successful, ${N} failed\n`,Y+=`- **Total Lines Added:** ${L}\n\n`,Y+="**Detailed Results:**\n\n"
|
|
@@ -3659,68 +3641,68 @@ for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?
|
|
|
3659
3641
|
Y+=` - ${t.type} insertion ${e}: ${t.error}\n`}}Y+="\n"}}P.length>0&&(Y+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3660
3642
|
const Q=Date.now()-w
|
|
3661
3643
|
return y.info("Insert lines operation completed",{duration:Q,success:V,totalOperations:F.length,successfulOperations:U,failedOperations:W}),a.incrementCounter("insert_lines_total",1,{success:V}),{content:[{type:"text",text:Y}],isError:!V}}catch(t){const r=Date.now()-w
|
|
3662
|
-
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:
|
|
3644
|
+
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await o.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,f.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("insert_lines_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
|
|
3663
3645
|
const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824),m=t(3255)},6539(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
|
|
3664
3646
|
const r=t(1253),n=t(5681),o=t(6595),s=t(3895),i=t(6848),a=t(6153),c=t(4710),l=t(6975),d=t(1887),u=t(1666),h=t(8824),g=t(9884),p=t(2968),f=t(922)
|
|
3665
3647
|
exports.ClientFactory=class{static async createClient(e,m,y,w={}){(m=m.child({component:"client-factory"})).info("Creating API client with components")
|
|
3666
3648
|
const b=w.tokenManager||new r.TokenManager(m,w.workingDir||process.cwd())
|
|
3667
3649
|
await b.initialize()
|
|
3668
|
-
const
|
|
3669
|
-
|
|
3650
|
+
const I=w.tokenSynchronizer||new i.ClientTokenSynchronizer(m),k=new s.AuthenticationManager(b,m,I),v=await k.getTokenString(),C=w.connectionStatusManager||new n.ConnectionStatusManager(e,m,y,{alchemyPath:w.alchemyPath,checkIntervalMs:w.offlineCheckIntervalMs,timeoutMs:w.timeout,retryCount:w.retryAttempts}),_=new c.ProjectClient(e,m,y,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3651
|
+
I.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3670
3652
|
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
|
-
|
|
3653
|
+
I.registerClient(E)
|
|
3672
3654
|
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})
|
|
3673
|
-
|
|
3655
|
+
I.registerClient(q),m.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
3674
3656
|
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})
|
|
3675
|
-
|
|
3657
|
+
I.registerClient(S),m.info("RequestClient post-constructor token: "+(S.getAuthToken()?"present":"missing"))
|
|
3676
3658
|
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})
|
|
3677
|
-
|
|
3659
|
+
I.registerClient(T)
|
|
3678
3660
|
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})
|
|
3679
|
-
|
|
3661
|
+
I.registerClient(P)
|
|
3680
3662
|
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})
|
|
3681
|
-
if(
|
|
3663
|
+
if(I.registerClient(R),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
|
|
3682
3664
|
try{m.info("Creating ProjectSynchronizer components")
|
|
3683
3665
|
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
3666
|
_.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(
|
|
3667
|
+
throw m.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const M=new o.ApiClient(k,_,E,q,S,T,P,R,m)
|
|
3686
3668
|
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"})
|
|
3687
|
-
const j=
|
|
3669
|
+
const j=I.verifyAllClients()
|
|
3688
3670
|
j.success?m.info("Token consistency verified across all clients"):m.error(`Token inconsistency detected in ${j.failedClients.length} clients: ${j.failedClients.join(", ")}`)
|
|
3689
3671
|
const x=M.getAuthToken()
|
|
3690
3672
|
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
|
|
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)((()=>{
|
|
3692
|
-
if(E)try{await E.connectStdio(),(0,a.isDebugToolsEnabled)()&&
|
|
3693
|
-
throw
|
|
3673
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6552(e,exports,t){async function r(){const e=new o.StdioServerTransport,t=(0,l.setupParentProcessDetection)((()=>{I.info("Parent process gone or orphan detected. Shutting down."),process.exit(0)}))
|
|
3674
|
+
if(E)try{await E.connectStdio(),(0,a.isDebugToolsEnabled)()&&I.info("Connected stdio transport to server")}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3675
|
+
throw I.error("Failed to connect stdio transport",{errorDetails:t}),e}else I.error("No global server instance available to connect transport")
|
|
3694
3676
|
return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3695
3677
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
3696
3678
|
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)
|
|
3697
3679
|
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")
|
|
3698
|
-
const
|
|
3699
|
-
const
|
|
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?
|
|
3701
|
-
try{if(u.default.existsSync(b)||(
|
|
3702
|
-
u.default.writeFileSync(e,(new Date).toISOString()),
|
|
3680
|
+
const I=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:b});(0,a.isDebugToolsEnabled)()?I.info("MCP Direct server initializing",{baseDir:b,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):I.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(I.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),E)try{E.cleanupSSEConnection()}catch(e){I.error("Error during cleanup after uncaught exception: "+e)}setTimeout((()=>process.exit(1)),500)})),process.on("unhandledRejection",(e=>{I.error("UNHANDLED REJECTION: "+e,{stack:e instanceof Error?e.stack:"No stack available"})})),process.on("exit",(e=>{I.info("Process exiting with code: "+e)}))
|
|
3681
|
+
const k=process.stdout.write
|
|
3682
|
+
process.stdout.write=function(e,t,r){try{if("string"==typeof e)try{JSON.parse(e)}catch(t){return e.includes('"__message_type"')||(process.stderr.write("[STDOUT REDIRECTED]: "+e),r&&r()),!0}return"string"==typeof t&&"function"==typeof r?k.call(process.stdout,e,t,r):"function"==typeof t?k.call(process.stdout,e,void 0,t):k.call(process.stdout,e)}catch(e){return process.stderr.write("[STDOUT ERROR]: "+e),!0}},(0,a.isDebugToolsEnabled)()&&(I.info("Initialized stdout filtering to ensure only valid JSON is sent"),I.info("!!!MARKER!!! COMMAND-LINE ARGS:",{args:JSON.stringify(y)}),I.info("!!!MARKER!!! BASE DIRECTORY:",{baseDir:w}),I.info("!!!MARKER!!! ABSOLUTE BASE DIR:",{absBaseDir:b}),I.info("Working with base directory:",{absBaseDir:b}))
|
|
3683
|
+
try{if(u.default.existsSync(b)||(I.warn(`Base directory ${b} does not exist. Creating it...`),u.default.mkdirSync(b,{recursive:!0})),(0,a.isDebugToolsEnabled)()){const e=s.default.join(b,".mcp-test-file")
|
|
3684
|
+
u.default.writeFileSync(e,(new Date).toISOString()),I.info("Successfully wrote test file to "+e),u.default.unlinkSync(e),I.info("Successfully deleted test file"),I.info(`Confirmed base directory ${b} exists and is accessible`)}}catch(e){I.error(`Error accessing base directory ${b}:`,{error:e}),I.warn("This may cause issues with file operations - please check permissions")}const v=(0,c.createMetricsCollector)(!1)
|
|
3703
3685
|
let C=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com"
|
|
3704
3686
|
const _=global.__serverInitialized
|
|
3705
|
-
void 0===_?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&
|
|
3687
|
+
void 0===_?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&I.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&I.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
|
|
3706
3688
|
let E=null
|
|
3707
3689
|
const q=(0,g.isMultiAgentModeEnabled)(b)
|
|
3708
|
-
try{(0,d.acquireProcessLock)(b,q)||(
|
|
3709
|
-
|
|
3690
|
+
try{(0,d.acquireProcessLock)(b,q)||(I.error(`Process lock acquisition failed for ${b}. Another instance may be running.`),I.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&(q?I.info("Multi-agent mode enabled - allowing concurrent access to "+b):I.info("Successfully acquired process lock for "+b))}catch(e){I.error("Lock acquisition threw exception",{error:(0,p.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),I.error("Cannot continue without lock in single-agent mode"),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(I.info("============================================================"),I.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),I.info("BASE DIR: "+b),I.info("ALCHEMY PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME)),I.info("PROJECT PATH: "+s.default.join(b,h.ALCHEMY_DIR_NAME+"/project.json")),I.info("MULTI-AGENT MODE: "+q),I.info("MCP client information will be captured during protocol initialization")),I.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(I.info("============================================================"),I.info("Base directory: "+b),I.info("Remote server URL: "+C),I.info("Node version: "+process.version),I.info("Current working directory: "+process.cwd()),I.info("ALLOWED_DIRECTORIES env var: not used (single working directory mode)"),I.info("Server already initialized: "+(_?"YES":"NO"))),_&&((0,a.isDebugToolsEnabled)()&&(I.info("Server already initialized globally, reusing existing server instance"),I.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3691
|
+
I.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
|
|
3710
3692
|
try{const e=u.default.existsSync(b)
|
|
3711
|
-
if((0,a.isDebugToolsEnabled)()&&
|
|
3712
|
-
|
|
3713
|
-
if(!u.default.existsSync(S))try{u.default.mkdirSync(S,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&
|
|
3714
|
-
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(
|
|
3715
|
-
if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&
|
|
3716
|
-
try{const e=await(0,f.syncPlugins)(b,(0,m.isDevBuild)(),
|
|
3717
|
-
e.synced.length>0&&
|
|
3718
|
-
const e=await(0,i.createServer)(b,
|
|
3719
|
-
E=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&
|
|
3693
|
+
if((0,a.isDebugToolsEnabled)()&&I.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=u.default.statSync(b)
|
|
3694
|
+
I.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(8)}`)}else(0,a.isDebugToolsEnabled)()&&I.info("Directory does not exist, trying to create it"),u.default.mkdirSync(b,{recursive:!0})}catch(e){I.error("Error checking directory: "+e)}if(!u.default.existsSync(b))try{u.default.mkdirSync(b,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&I.info("Created base directory: "+b)}catch(e){I.error("Failed to create base directory: "+e)}const S=s.default.join(b,h.ALCHEMY_DIR_NAME)
|
|
3695
|
+
if(!u.default.existsSync(S))try{u.default.mkdirSync(S,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&I.info("Created alchemy lab directory: "+S)}catch(e){I.error("Failed to create alchemy lab directory: "+e)}try{(async function(){try{C=await async function(){if(process.env.REMOTE_SERVER_URL)return process.env.REMOTE_SERVER_URL
|
|
3696
|
+
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(I),n=await r.getInstallationConfig()
|
|
3697
|
+
if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&I.info("Loaded REMOTE_SERVER_URL from installation config",{remoteServerUrl:n.remoteServerUrl}),n.remoteServerUrl}catch(e){(0,a.isDebugToolsEnabled)()&&I.debug("Could not read REMOTE_SERVER_URL from installation config",{error:e instanceof Error?e.message:"Unknown error"})}return"https://api.alchemylabcode.com"}()
|
|
3698
|
+
try{const e=await(0,f.syncPlugins)(b,(0,m.isDevBuild)(),I)
|
|
3699
|
+
e.synced.length>0&&I.info("Synced plugins on startup",{synced:e.synced}),e.errors.length>0&&I.warn("Some plugins failed to sync",{errors:e.errors})}catch(e){I.warn("Plugin sync failed",{error:e instanceof Error?e.message:"Unknown error"})}(0,a.isDebugToolsEnabled)()&&(I.info("Creating MCP server with base dir: "+b),I.info("Using remote server URL: "+C))
|
|
3700
|
+
const e=await(0,i.createServer)(b,I,v,C,{multiAgentMode:(0,g.isMultiAgentModeEnabled)(b)})
|
|
3701
|
+
E=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&I.info("MCP server created successfully")
|
|
3720
3702
|
const n=r()
|
|
3721
|
-
return(0,a.isDebugToolsEnabled)()&&
|
|
3722
|
-
|
|
3723
|
-
|
|
3703
|
+
return(0,a.isDebugToolsEnabled)()&&I.info("Stdio transport registered with server"),{server:E,transportInfo:n}}catch(e){throw I.error("Failed to initialize MCP server",{error:e}),e}})().then((()=>{(0,a.isDebugToolsEnabled)()&&I.info("MCP server initialization complete")})).catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3704
|
+
I.error("Server initialization failed",{errorDetails:t}),process.exit(1)}))}catch(e){const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3705
|
+
I.error("Exception during server initialization",{errorDetails:t}),process.exit(1)}process.on("SIGTERM",(()=>{I.info("SIGTERM received, shutting down"),setTimeout((()=>process.exit(0)),500)})),process.on("SIGINT",(()=>{I.info("SIGINT received, shutting down"),setTimeout((()=>process.exit(0)),500)}))},6595(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ApiClient=void 0
|
|
3724
3706
|
const r=t(1599),n=t(2690),o=t(4465),s=t(5187),i=t(5674),a=t(8824)
|
|
3725
3707
|
exports.ApiClient=class{constructor(e,t,r,n,o,s,i,a,c){this.options={createRecords:!0},this.alchemyPath="",this.sessionRequestAssociationClient=null,this.sessionMessageClient=null,this.sessionTagMappingClient=null,this.cliSessionClient=null,this.logger=c,this.authManager=e,this.projectClient=t,this.taskClient=r,this.fileClient=n,this.requestClient=o,this.documentClient=s,this.toolRecordClient=i,this.proxyClient=a,this.tokenSynchronizer=e.getTokenSynchronizer(),this.baseUrl=a.baseUrl||"",this.documentClient&&"function"==typeof this.documentClient.setParentApiClient&&this.documentClient.setParentApiClient(this),this.logger.info("API client initialized with specialized clients")}async setToken(e){return this.authManager.setToken(e)}async getToken(){return this.authManager.getToken()}async hasValidToken(){return this.authManager.hasValidToken()}async removeToken(){return this.authManager.removeToken()}setOptions(e){this.options={...this.options,...e},this.logger.info("API client options updated",{options:this.options})}getOptions(){return{...this.options}}isOffline(){const e=this.projectClient.isOffline?.()||!1,t=this.fileClient.isOffline?.()||!1,r=this.proxyClient.isOffline?.()||!1,n=e||t||r
|
|
3726
3708
|
return this.logger.debug("ApiClient.isOffline called - reporting actual connection status",{isOffline:n,client:"ApiClient"}),n}checkConnectivity(e,t){if(this.isOffline()){let r
|
|
@@ -3757,7 +3739,7 @@ var t={}
|
|
|
3757
3739
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3758
3740
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3759
3741
|
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()
|
|
3760
|
-
let k,
|
|
3742
|
+
let I,k,v=d.FileOperationPhase.VALIDATION
|
|
3761
3743
|
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"}
|
|
3762
3744
|
try{const i=d.validateArgs(e,l.ReplaceLinesSchema),{taskId:_,operations:E,comment:q}=i
|
|
3763
3745
|
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")
|
|
@@ -3774,16 +3756,16 @@ throw e}}v=d.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_line
|
|
|
3774
3756
|
const M=P.length>0?P[0].path:"document-operation",j=await d.validateTaskId(_,M,n,w,a,C.metricsPrefix),x=j?.requestId
|
|
3775
3757
|
let O=null
|
|
3776
3758
|
P.length>0&&x&&(O=await d.validateWorkItemStates(_,P[0].path,n,s,t,w,a,C.metricsPrefix))
|
|
3777
|
-
let
|
|
3778
|
-
P.length>0&&x&&O&&(
|
|
3779
|
-
const
|
|
3780
|
-
if(!
|
|
3781
|
-
throw Error(
|
|
3759
|
+
let D={taskPromoted:!1,requestPromoted:!1}
|
|
3760
|
+
P.length>0&&x&&O&&(D=await d.autoPromoteTaskStatus(_,j.status,x,O.request?.status,P[0].path,n,s,w,a,C.metricsPrefix),D.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:_,requestId:x,previousStatus:j.status,newStatus:D.newTaskStatus,triggeringOperation:"replace-lines"}))
|
|
3761
|
+
const A=await d.ensureCorrectWorkspaceContext({taskPromoted:D.taskPromoted,requestId:x,context:t,operation:"replace-lines",logger:w,metrics:a,metricsPrefix:C.metricsPrefix})
|
|
3762
|
+
if(!A.success){if(A.isLockConflict)return{content:[{type:"text",text:"\u274c "+A.error}],isError:!0}
|
|
3763
|
+
throw Error(A.error)}if(P.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:P.length,workspaceBasePath:t.workspaceManager?.getCurrentContext().basePath})
|
|
3782
3764
|
for(let e=0;e<P.length;e++){const r=P[e],n=S[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,t)
|
|
3783
3765
|
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}
|
|
3784
3766
|
throw e}v=d.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3785
3767
|
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)
|
|
3786
|
-
if(
|
|
3768
|
+
if(I=F,k=F,v=C.fileOperationPhase,a.incrementCounter("replace_lines_phase",1,{phase:v}),P.length>0&&t.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
|
|
3787
3769
|
const e=await(0,g.commitUserChangesBeforeToolOperation)(t.git,"replace-lines",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},w,a)
|
|
3788
3770
|
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})
|
|
3789
3771
|
const N=[]
|
|
@@ -3796,16 +3778,16 @@ try{const o=await t.documentFileManager.getDocumentAsFile(e.documentId),s=t.docu
|
|
|
3796
3778
|
n.filename=s?.filename
|
|
3797
3779
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
|
|
3798
3780
|
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))
|
|
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:
|
|
3800
|
-
try{await o.updateToolRecord(
|
|
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"),
|
|
3781
|
+
r?.success&&await t.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const U=await d.handleMultiFileGitCommit(_,P,N,H,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:a,metricsPrefix:"replace_lines"},t),W=d.processMultiFileOperationResults(N,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:J,overallSuccess:K,successfulFiles:Y,failedFiles:Q}=W
|
|
3782
|
+
try{await o.updateToolRecord(k,{metadata:{path:P.length>0?P[0].path:"document:"+R[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:N.length,successfulFiles:Y,failedFiles:Q,operations:$,totalSuccessfulReplacements:J,totalFailedReplacements:L,totalLinesReplaced:z,totalLinesAdded:B,operationsWithChanges:H,processingTime:Date.now()-b,userComment:q,...P.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:K?`Line replacement completed: ${G}/${N.length} operations successful${P.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${V}/${N.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let Z="## Line Replacement Results\n\n"
|
|
3783
|
+
if(t.workspaceManager&&(Z+=`**Branch:** \`${t.workspaceManager.getCurrentContext().branchName}\`\n\n`),Z+="**Summary:**\n",Z+=`- **Files processed:** ${G+V}\n`,Z+=`- **Successful operations:** ${G}\n`,Z+=`- **Failed operations:** ${V}\n`,Z+=`- **Total replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,B>0&&(Z+=`- **Total Lines Added:** ${B}\n`),Z+="\n",U.success&&U.commitHash&&(Z+="**Git Commit:**\n",Z+=`- **Commit Hash:** ${U.commitHash.substring(0,8)}\n`,Z+=`- **Files Committed:** ${U.filesCommitted.length}\n`,U.previousCommitHash&&(Z+=`- **Previous Commit:** ${U.previousCommitHash.substring(0,8)}\n`),Z+="\n"),A.lockAcquired&&A.lockedRequestId&&(Z+=`\u{1f512} **Locked request:** ${A.lockedRequestId}\n\n`),1===N.length){const e=N[0]
|
|
3802
3784
|
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"
|
|
3803
3785
|
for(const t of e.replacements.filter((e=>!e.success)))Z+=`- Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}}else{Z+="**Summary:**\n",Z+=`- **Total Operations:** ${N.length}\n`,Z+=`- **Successful:** ${G}\n`,Z+=`- **Failed:** ${V}\n`,Z+=`- **Total Replacements:** ${J} successful, ${L} failed\n`,Z+=`- **Total Lines Replaced:** ${z}\n`,B>0&&(Z+=`- **Total Lines Added:** ${B}\n`),Z+="\n",Z+="**Detailed Results:**\n\n"
|
|
3804
3786
|
for(const e of N){if("file"===e.type?Z+=`### File: ${e.path}\n`:(Z+="### Document: "+e.documentId,e.filename&&(Z+=` (${e.filename})`),Z+="\n"),Z+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error&&(Z+=`- **Error:** ${e.error}\n`),Z+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(Z+=`, ${e.failedReplacements} failed`),Z+="\n",Z+=`- **Lines Replaced:** ${e.totalLinesReplaced}\n`,e.totalLinesAdded>0&&(Z+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.replacements.some((e=>!e.success))){Z+="- **Failed Replacement Details:**\n"
|
|
3805
3787
|
for(const t of e.replacements.filter((e=>!e.success)))Z+=` - Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}Z+="\n"}}R.length>0&&(Z+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3806
3788
|
const X=Date.now()-b
|
|
3807
3789
|
return w.info("Replace lines operation completed",{duration:X,success:K,totalOperations:N.length,successfulOperations:G,failedOperations:V}),a.incrementCounter("replace_lines_total",1,{success:K}),{content:[{type:"text",text:Z}],isError:!K}}catch(t){const r=Date.now()-b
|
|
3808
|
-
if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),
|
|
3790
|
+
if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),k)try{await o.updateToolRecord(k,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,f.getErrorMessage)(t),phase:v,duration:r,userComment:e?.comment},note:"Line replacement failed: "+(0,f.getErrorMessage)(t)})}catch(e){}return a.incrementCounter("replace_lines_errors",1,{phase:v}),{content:[{type:"text",text:"\u274c **Replace Lines Failed:** "+(0,f.getErrorMessage)(t)}],isError:!0}}}
|
|
3809
3791
|
const c=a(t(1943)),l=t(6183),d=i(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),f=t(8824),m=t(3255),y=t(9470)},6688(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
|
|
3810
3792
|
const r=t(9896),n=t(6928)
|
|
3811
3793
|
exports.sessionIdentity=new class{constructor(){this.discoveryAttempted=!1,this.parentCache=new Map}setIdentity(e){const t=this.identity
|
|
@@ -3885,13 +3867,13 @@ s.info("Raw task response data",{responseDataType:typeof P,isArray:Array.isArray
|
|
|
3885
3867
|
try{const M=await m.getToolRecordsByTaskId(g)
|
|
3886
3868
|
if(s.info("Raw records response data",{responseDataType:typeof M,isArray:Array.isArray(M),hasData:null!=M,properties:M&&"object"==typeof M?Object.keys(M):[]}),b=(0,l.extractArrayFromResponse)(M,{logger:s,operationName:"searchRecords",defaultValue:[]}),b.length>0&&s.info("First record summary:",{id:b[0].id,type:b[0].type,hasMetadata:!!b[0].metadata,hasCommitHash:!!b[0].metadata?.commitHash}),s.info(`Extracted ${b.length} records for task ${g}`),b.length>0){const j={}
|
|
3887
3869
|
b.forEach((e=>{j[e.type]=(j[e.type]||0)+1})),s.info("Record type distribution:",j)}}catch(x){s.warn("Error fetching records for task "+g,{error:(0,u.getErrorMessage)(x)}),b=[]}if(0===b.length)return h({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
|
|
3888
|
-
function
|
|
3870
|
+
function I(e){const t=new Map,r=new Map,n=[]
|
|
3889
3871
|
for(const o of e)if("move-file"===o.type&&o.metadata){const e=o.metadata.source||o.metadata.oldPath,s=o.metadata.destination||o.metadata.newPath
|
|
3890
3872
|
if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
|
|
3891
3873
|
t.set(e,i),r.set(s,i),n.push(i)}}else if("move-files"===o.type&&o.metadata){const e=[...o.metadata.successfulOperations||[],...o.metadata.failedOperations||[]]
|
|
3892
3874
|
for(const s of e)if(s.source&&s.destination){const e={source:s.source,destination:s.destination,recordId:o.id,timestamp:o.createdAt,type:"move-files"}
|
|
3893
|
-
t.set(s.source,e),r.set(s.destination,e),n.push(e)}}return{sourceToMove:t,destToMove:r,allMoves:n}}const I
|
|
3894
|
-
s.info(`Detected ${
|
|
3875
|
+
t.set(s.source,e),r.set(s.destination,e),n.push(e)}}return{sourceToMove:t,destToMove:r,allMoves:n}}const k=I(b)
|
|
3876
|
+
s.info(`Detected ${k.allMoves.length} move operations`)
|
|
3895
3877
|
const v=b.filter((e=>{if(!e||"object"!=typeof e)return s.warn("Skipping invalid record (not an object)"),!1
|
|
3896
3878
|
if(!["write-file","replace-in-files","move-file","move-files","delete-file","delete-files","manage-files"].includes(e.type))return s.debug("Skipping record with non-file operation type: "+e.type),!1
|
|
3897
3879
|
if(!e.metadata)return s.warn("Skipping record without metadata: "+e.id),!1
|
|
@@ -3932,7 +3914,7 @@ n&&n.push({filePath:r,recordId:e.id,type:"replace-in-files",timestamp:e.createdA
|
|
|
3932
3914
|
C.has(t)||C.set(t,[])
|
|
3933
3915
|
const r=C.get(t)
|
|
3934
3916
|
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.`)
|
|
3935
|
-
for(const[A
|
|
3917
|
+
for(const[D,A]of C.entries())A.sort(((e,t)=>new Date(e.timestamp).getTime()-new Date(t.timestamp).getTime())),s.info(`File ${D} has ${A.length} records.`),s.info("Records with commit hashes: "+A.filter((e=>e.commitHash)).length)
|
|
3936
3918
|
const _=new Map
|
|
3937
3919
|
for(const[$,F]of C.entries()){s.info(`Processing file: ${$} (${F.length} records)`)
|
|
3938
3920
|
const N=new Map
|
|
@@ -3967,7 +3949,7 @@ continue}let pe
|
|
|
3967
3949
|
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")
|
|
3968
3950
|
try{const me=await t.git.show([`${W.commitHash}:${$}`]),ye=await t.git.show([`${B.commitHash}:${$}`])
|
|
3969
3951
|
if(me!==ye&&(V=!0,G="Changes detected through direct content comparison (not visible in standard diff)",p)){const we=me.split("\n"),be=ye.split("\n")
|
|
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(
|
|
3952
|
+
Math.abs(we.length-be.length)>0&&(G+=`\n\nLine count changed: ${we.length} \u2192 ${be.length}`),me.includes("\0")||ye.includes("\0")?G+="\n\nBinary content detected - changes not displayed":me.replace(/\s+/g,"")===ye.replace(/\s+/g,"")&&(G+="\n\nWhitespace-only changes detected")}}catch(Ie){s.warn("Error in direct file comparison: "+(Ie instanceof Error?Ie.message:Ie+""))}}s.info(`Diff generation result for ${$}: hasDiff=${V}, length=${G.length}`)}}catch(ke){if(s.warn("Error getting diff for "+$,{error:(0,u.getErrorMessage)(ke),firstCommit:z.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),G="Error getting diff: "+(0,u.getErrorMessage)(ke),"pre-task"!==z.status&&t.git)try{const ve=[`${B.commitHash}:${$}`]
|
|
3971
3953
|
s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${$}`)
|
|
3972
3954
|
const Ce=await t.git.show(ve)
|
|
3973
3955
|
if(Ce&&Ce.trim().length>0){if(p){let _e=""
|
|
@@ -3979,14 +3961,14 @@ w&&"object"==typeof w&&(E+="## Task Information\n",E+=`- **Title**: ${w.title||"
|
|
|
3979
3961
|
const q=3e3
|
|
3980
3962
|
let S=0,T=!1
|
|
3981
3963
|
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`,
|
|
3983
|
-
for(const Pe of
|
|
3964
|
+
T=S>q,s.info(`Total diff size: ${S} lines (limit: ${q} lines)`),s.info(`Diffs ${T?"will be limited":"will be shown"} based on size`)}if(E+="## Summary\n",E+=`- **Files Modified**: ${C.size}\n`,E+=`- **Total File Operations**: ${v.length}\n`,E+="- **What's Shown**: For existing files, comparing state before task started with final state.\n",E+=" For files created during task, showing the entire file as created.\n",T?(E+=`- **Diff Display**: Limited (total diff size of ${S} lines exceeds limit of ${q} lines)\n`,E+=" Use file-history tool with individual files to see detailed changes\n\n"):E+=`- **Diff Display**: ${p?"Enabled":"Disabled"} (use showDiff=${!p} to ${p?"hide":"show"} diffs)\n\n`,k.allMoves.length>0){E+="## Move Operations\n\n",E+=`Detected ${k.allMoves.length} file move operation(s):\n\n`
|
|
3965
|
+
for(const Pe of k.allMoves)E+=`- **${Pe.source}** \u2192 **${Pe.destination}**\n`,E+=` - Operation: ${Pe.type}\n`,E+=` - Timestamp: ${new Date(Pe.timestamp).toLocaleString()}\n`,E+=` - Record ID: ${Pe.recordId}\n\n`}E+="## Modified Files\n\n"
|
|
3984
3966
|
for(const[Re,Me]of _.entries()){const{normalizedPath:je,fullPath:xe}=d.validateAndNormalizePath(Re,t)
|
|
3985
3967
|
let Oe=!1
|
|
3986
3968
|
try{await a.access(xe),Oe=!0}catch{}E+=`### ${Re} ${Oe?"":"(Deleted)"}\n\n`
|
|
3987
|
-
const
|
|
3988
|
-
E+=`**First Change**: ${
|
|
3989
|
-
const $e=
|
|
3969
|
+
const De=new Date(Me.firstChange.timestamp).toLocaleString(),Ae=new Date(Me.lastChange.timestamp).toLocaleString()
|
|
3970
|
+
E+=`**First Change**: ${De}\n`,E+=`**Last Change**: ${Ae}\n`,"pre-task"===Me.firstChange.status&&Me.firstChange.commitHash?E+=`**Pre-Task Commit**: ${Me.firstChange.commitHash.substring(0,8)}\n`:Me.firstChange.commitHash&&(E+=`**File Created During Task**: ${Me.firstChange.commitHash.substring(0,8)}\n`),Me.lastChange.commitHash&&(E+=`**Final Commit**: ${Me.lastChange.commitHash.substring(0,8)}\n`)
|
|
3971
|
+
const $e=k.sourceToMove.get(Re),Fe=k.destToMove.get(Re)
|
|
3990
3972
|
$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}}}
|
|
3991
3973
|
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
|
|
3992
3974
|
const r=t(1058)
|
|
@@ -4112,7 +4094,7 @@ i.appendFileSync(o,`[${s}] ${e} | ${t}${c}\n`)}catch(e){}}
|
|
|
4112
4094
|
const i=s(t(9896)),a=s(t(6928))},7334(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,l,d,u,h,g){const p=d.child({tool:"create_request"})
|
|
4113
4095
|
p.info("Creating new request",{args:e})
|
|
4114
4096
|
const f=u.startTimer("tool_handler_duration")
|
|
4115
|
-
try{const d=function(e){try{return r.CreateRequestSchema.parse(e)}catch(e){if(e instanceof s.ZodError&&e.errors.length>0)throw new n.ValidationError(e.errors[0].message)
|
|
4097
|
+
try{if(e&&"string"==typeof e.acceptanceCriteria)try{e.acceptanceCriteria=JSON.parse(e.acceptanceCriteria)}catch{}const d=function(e){try{return r.CreateRequestSchema.parse(e)}catch(e){if(e instanceof s.ZodError&&e.errors.length>0)throw new n.ValidationError(e.errors[0].message)
|
|
4116
4098
|
throw new n.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
|
|
4117
4099
|
u.incrementCounter("create_request_attempts",1,{type:d.type,criteriaCounts:d.acceptanceCriteria.length})
|
|
4118
4100
|
const m=t.projectId
|
|
@@ -4125,11 +4107,11 @@ if(e){const t=l.getCLISessionClient()
|
|
|
4125
4107
|
if(t){const r=await t.getByExternalId(e)
|
|
4126
4108
|
if(r?.workflowId){const e=await l.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
|
|
4127
4109
|
t?.approvalMode&&(w=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===w)try{const e=await l.proxyGet("/api/projects/"+m),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
|
|
4128
|
-
r&&(w=(0,a.getApprovalMode)(r))}catch(e){p.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){p.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const b="require-approval"===w&&"quick-edit"!==d.type?"pending_approval":"open",
|
|
4110
|
+
r&&(w=(0,a.getApprovalMode)(r))}catch(e){p.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){p.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const b="require-approval"===w&&"quick-edit"!==d.type?"pending_approval":"open",I={title:d.title,description:d.description,type:d.type,acceptanceCriteria:d.acceptanceCriteria,status:b,...d.planDocumentId&&{planDocumentId:d.planDocumentId},...g&&{cliOrigin:g}}
|
|
4129
4111
|
p.info("Creating request via request client",{projectId:m,title:d.title,type:d.type,criteriaCount:d.acceptanceCriteria.length})
|
|
4130
|
-
const
|
|
4131
|
-
p.debug("Create request response structure",{type:typeof
|
|
4132
|
-
const v=(0,o.extractDataFromResponse)(
|
|
4112
|
+
const k=await y.createRequest(I)
|
|
4113
|
+
p.debug("Create request response structure",{type:typeof k,isArray:Array.isArray(k),hasData:null!=k,properties:k?Object.keys(k):[],dataPreview:k?JSON.stringify(k).substring(0,200)+"...":"null"})
|
|
4114
|
+
const v=(0,o.extractDataFromResponse)(k,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
|
|
4133
4115
|
let _,E={created:!1}
|
|
4134
4116
|
if(h?.workspaceManager)try{await h.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},p.info("Request branch initialized successfully",{requestId:C.id,branchName:E.branchName,title:C.title})}catch(e){p.warn("Failed to initialize request branch, will retry on first operation",{requestId:C.id,error:(0,i.getErrorMessage)(e)})}else"quick-edit"===d.type?p.info("Quick-edit request - skipping branch creation, will work directly on main",{requestId:C.id}):p.debug("No workspace manager available, branch creation deferred",{requestId:C.id})
|
|
4135
4117
|
p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
|
|
@@ -4158,7 +4140,7 @@ return o(t,e),t})
|
|
|
4158
4140
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,t,r,n,o,s,h,g){const p=s.child({tool:"modify_file"})
|
|
4159
4141
|
try{const s=a.validateArgs(e,i.ModifyFileSchema),{taskId:u,operations:f,comment:m}=s
|
|
4160
4142
|
p.info("Processing modify-file operations",{taskId:u,operationCount:f.length,comment:m})
|
|
4161
|
-
const y=[],w=[],b=[],
|
|
4143
|
+
const y=[],w=[],b=[],I=[],k=[]
|
|
4162
4144
|
for(const e of f){const t={path:e.path,documentId:e.documentId}
|
|
4163
4145
|
switch(e.operationType){case"replace-string":y.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
|
|
4164
4146
|
break
|
|
@@ -4166,19 +4148,19 @@ case"insert-lines":w.push({...t,insertions:e.insertLines.insertions})
|
|
|
4166
4148
|
break
|
|
4167
4149
|
case"replace-lines":b.push({...t,replacements:e.replaceLines.replacements})
|
|
4168
4150
|
break
|
|
4169
|
-
case"delete-string":
|
|
4151
|
+
case"delete-string":I.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
|
|
4170
4152
|
break
|
|
4171
|
-
case"delete-lines":
|
|
4153
|
+
case"delete-lines":k.push({...t,lines:e.deleteLines.lines})}}const v=[]
|
|
4172
4154
|
if(y.length>0){p.info("Routing to replace-strings handler",{operationCount:y.length})
|
|
4173
4155
|
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:y,comment:m+" [via modify-file: replace-string]"},t,r,n,o,p,h,g)
|
|
4174
4156
|
v.push({type:"replace-string",result:e})}if(w.length>0){p.info("Routing to insert-lines handler",{operationCount:w.length})
|
|
4175
4157
|
const e=await(0,l.handleInsertLines)({taskId:u,operations:w,comment:m+" [via modify-file: insert-lines]"},t,r,n,o,p,h,g)
|
|
4176
4158
|
v.push({type:"insert-lines",result:e})}if(b.length>0){p.info("Routing to replace-lines handler",{operationCount:b.length})
|
|
4177
4159
|
const e=await(0,d.handleReplaceLines)({taskId:u,operations:b,comment:m+" [via modify-file: replace-lines]"},t,r,n,o,p,h,g)
|
|
4178
|
-
v.push({type:"replace-lines",result:e})}if(
|
|
4179
|
-
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:
|
|
4180
|
-
v.push({type:"delete-string",result:e})}if(
|
|
4181
|
-
const e=
|
|
4160
|
+
v.push({type:"replace-lines",result:e})}if(I.length>0){p.info("Routing delete-string to replace-strings handler",{operationCount:I.length})
|
|
4161
|
+
const e=await(0,c.handleReplaceStrings)({taskId:u,operations:I,comment:m+" [via modify-file: delete-string]"},t,r,n,o,p,h,g)
|
|
4162
|
+
v.push({type:"delete-string",result:e})}if(k.length>0){p.info("Processing delete-lines operations",{operationCount:k.length})
|
|
4163
|
+
const e=k.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),s=await(0,d.handleReplaceLines)({taskId:u,operations:e,comment:m+" [via modify-file: delete-lines]"},t,r,n,o,p,h,g)
|
|
4182
4164
|
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
|
|
4183
4165
|
let q="## Modify File Results\n\n"
|
|
4184
4166
|
q+="**Summary:**\n",q+=`- **Total operation types:** ${v.length}\n`,q+=`- **Successful:** ${_}\n`,q+=`- **Failed:** ${E}\n\n`
|
|
@@ -4501,8 +4483,9 @@ const e=this.worktreeManager.getWorktreeInfo(n)
|
|
|
4501
4483
|
if(e&&e.worktreePath)return this.currentRequestId=n,this.currentWorktreePath=e.worktreePath,this.currentGit=(0,o.simpleGit)(e.worktreePath),void this.logger.info("Switched to existing ready workspace",{requestId:n,worktreePath:e.worktreePath})}try{a.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by creating/switching to worktree",e,"multi-agent","ensureWorkspaceReady",{currentState:this.workspaceStates.get(n)||"not-initialized",currentRequestId:this.currentRequestId,architecture:"hybrid-creation"})
|
|
4502
4484
|
const r=await this.worktreeManager.ensureWorktreeExists(n,void 0,void 0)
|
|
4503
4485
|
if(!r.success)throw Error("Failed to create worktree: "+r.message)
|
|
4504
|
-
this.currentRequestId=n,this.currentWorktreePath=r.worktreePath,this.currentGit=(0,o.simpleGit)(r.worktreePath),this.workspaceStates.set(n,"ready"),r.created
|
|
4505
|
-
const s=
|
|
4486
|
+
if(this.currentRequestId=n,this.currentWorktreePath=r.worktreePath,this.currentGit=(0,o.simpleGit)(r.worktreePath),this.workspaceStates.set(n,"ready"),r.created){this.workspaceKnownClean=!0
|
|
4487
|
+
try{const e=(0,o.simpleGit)(r.worktreePath),t=(await this.mainGit.branch()).all.includes("main")?"main":"master",s=await this.mainGit.revparse([t]),i=await e.revparse(["HEAD"])
|
|
4488
|
+
s!==i&&0===(await e.log({from:t,to:"HEAD"})).total&&(await e.rebase([t]),this.logger.info("Rebased fresh request branch onto latest main",{requestId:n,mainHead:s.substring(0,8),previousHead:i.substring(0,8)}))}catch(e){this.logger.warn("Failed to rebase onto main, proceeding with existing branch",{requestId:n,error:(0,i.getErrorMessage)(e)})}}const s=Date.now()-t
|
|
4506
4489
|
this.metrics.recordValue("workspace.ensure_ready",s),a.WorkspaceLogging.logOperation(this.logger,"info","Workspace is ready with worktree",e,"multi-agent","ensureWorkspaceReady",{worktreePath:r.worktreePath,branchName:r.branchName,duration:s,architecture:"hybrid-creation"})}catch(r){const n=Date.now()-t
|
|
4507
4490
|
throw this.metrics.recordValue("workspace.ensure_ready",n),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure workspace ready",e,"multi-agent","ensureWorkspaceReady",{error:(0,i.getErrorMessage)(r),duration:n}),r}}else this.logger.debug("Workspace already ready and in correct context",{requestId:n,worktreePath:this.currentWorktreePath})}async switchToRequest(e,t){this.logger.debug("switchToRequest called",{requestId:e,options:t})
|
|
4508
4491
|
const r=Date.now(),n=this.getCurrentContext()
|
|
@@ -4535,7 +4518,7 @@ try{this.currentRequestId===r&&await this.switchToMain()
|
|
|
4535
4518
|
const e=await this.worktreeManager.removeWorktree(r,!1)
|
|
4536
4519
|
if(!e.success)throw Error(e.message||"Failed to remove worktree")
|
|
4537
4520
|
this.logger.info("Successfully cancelled request",{requestId:r})}catch(e){throw this.logger.error("Failed to cancel request",{requestId:r,error:(0,i.getErrorMessage)(e)}),e}}getCurrentContext(){const e={requestId:this.currentRequestId,basePath:this.currentWorktreePath||this.basePath,branchName:this.currentRequestId?"requests/"+this.currentRequestId:"main",isMainBranch:!this.currentRequestId,mode:"multi-agent"}
|
|
4538
|
-
return this.logger.debug("getCurrentContext returning",{context:e}),e}async getWorkspaceInfo(e){try{const t=a.WorkspaceValidation.validateRequestId(e)
|
|
4521
|
+
return this.logger.debug("getCurrentContext returning",{context:e}),e}resetCurrentContext(){this.currentRequestId&&this.logger.info("Resetting workspace context (session switch)",{prevRequestId:this.currentRequestId,prevWorktreePath:this.currentWorktreePath}),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit}async getWorkspaceInfo(e){try{const t=a.WorkspaceValidation.validateRequestId(e)
|
|
4539
4522
|
if(!t.isValid)return null
|
|
4540
4523
|
const r=t.sanitized,n=await this.getWorktreeInfo(r)
|
|
4541
4524
|
return n?{requestId:r,path:n.worktreePath,branchName:n.branchName,isActive:this.currentRequestId===r,created:new Date,lastAccessed:new Date}:null}catch(t){return this.logger.error("Failed to get workspace info",{requestId:e,error:(0,i.getErrorMessage)(t)}),null}}async listActiveWorkspaces(){try{return(await this.worktreeManager.listActiveWorktrees()).map((e=>this.convertWorktreeInfoToWorkspaceInfo(e)))}catch(e){return this.logger.error("Failed to list active workspaces",{error:(0,i.getErrorMessage)(e)}),[]}}extractRequestIdFromBranch(e){const t=e.match(/^requests\/(.+)$/)
|
|
@@ -4563,20 +4546,20 @@ return o(t,e),t})
|
|
|
4563
4546
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,t,r,n,o,s,g,p,f){const m=g.child({tool:"manage_files"})
|
|
4564
4547
|
try{const h=a.validateArgs(e,i.ManageFilesSchema),{taskId:g,operations:y,comment:w}=h
|
|
4565
4548
|
m.info("Processing manage-files operations",{taskId:g,operationCount:y.length,comment:w})
|
|
4566
|
-
const b=[],
|
|
4549
|
+
const b=[],I=[],k=[],v=[]
|
|
4567
4550
|
for(const e of y)switch(e.operationType){case"create-directory":b.push({path:e.createDirectory.path})
|
|
4568
4551
|
break
|
|
4569
|
-
case"move-files":for(const t of e.moveFiles.moves)
|
|
4552
|
+
case"move-files":for(const t of e.moveFiles.moves)I.push(t)
|
|
4570
4553
|
break
|
|
4571
|
-
case"delete-files":
|
|
4554
|
+
case"delete-files":k.push(...e.deleteFiles.targets)
|
|
4572
4555
|
break
|
|
4573
4556
|
case"get-file-info":v.push({path:e.getFileInfo.path})}const C=[]
|
|
4574
4557
|
for(const e of b){m.info("Routing to create-directory handler",{path:e.path})
|
|
4575
4558
|
const s=await(0,c.handleCreateDirectory)({taskId:g,path:e.path,comment:w+" [via manage-files: create-directory]"},t,r,n,o,m,p,f)
|
|
4576
|
-
C.push({type:"create-directory",result:s})}if(
|
|
4577
|
-
const e=await(0,l.handleMoveFiles)({taskId:g,operations:
|
|
4578
|
-
C.push({type:"move-files",result:e})}if(
|
|
4579
|
-
const e=await(0,u.handleDeleteFiles)({taskId:g,operations:
|
|
4559
|
+
C.push({type:"create-directory",result:s})}if(I.length>0){m.info("Routing to move-files handler",{operationCount:I.length})
|
|
4560
|
+
const e=await(0,l.handleMoveFiles)({taskId:g,operations:I,comment:w+" [via manage-files: move-files]"},t,r,n,o,m,p,f)
|
|
4561
|
+
C.push({type:"move-files",result:e})}if(k.length>0){m.info("Routing to delete-files handler",{operationCount:k.length})
|
|
4562
|
+
const e=await(0,u.handleDeleteFiles)({taskId:g,operations:k,comment:w+" [via manage-files: delete-files]"},t,s,m,p,f)
|
|
4580
4563
|
C.push({type:"delete-files",result:e})}for(const e of v){m.info("Routing to get-file-info handler",{path:e.path})
|
|
4581
4564
|
const r=await(0,d.handleGetFileInfo)({path:e.path},t,m,p)
|
|
4582
4565
|
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
|
|
@@ -4673,9 +4656,9 @@ const d=new Date,m=`${(d.getHours()+"").padStart(2,"0")}${(d.getMinutes()+"").pa
|
|
|
4673
4656
|
let w
|
|
4674
4657
|
if(s.ALCHEMY_SESSION_TAG=`mcp-${m}-${y}`,r(c,"Spawn env setup",{agent:t,initialBranch:g||"none",hasParentServer:!!l,sessionId:u||"new",attachMode:!!p}),w=p&&u&&n?["run","--attach",p,"--session",u,"--agent",t,n]:u&&n?["run","--session",u,"--agent",t,n]:n?["run","--agent",t,n]:["run","--agent",t],h){const e=w.findIndex((e=>e===n))
|
|
4675
4658
|
e>0?w.splice(e,0,"--model",h):w.push("--model",h)}r(c,"Spawning opencode",{args:w.map((e=>e===n?`[prompt:${e.length}chars]`:e)),model:h||"not specified",promptLength:n?.length,promptPreview:n?.slice(0,100),cwd:c,hasSessionId:!!u,hasParentServerUrl:!!l})
|
|
4676
|
-
const b=(0,a.join)(c||process.cwd(),".alchemy_lab"),
|
|
4677
|
-
let
|
|
4678
|
-
try{
|
|
4659
|
+
const b=(0,a.join)(c||process.cwd(),".alchemy_lab"),I=(0,a.join)(b,"spawn-stderr.log")
|
|
4660
|
+
let k
|
|
4661
|
+
try{k=(0,i.openSync)(I,"a")}catch{}const v=(0,o.spawn)("opencode",w,{detached:!0,stdio:["ignore","ignore",k??"ignore"],cwd:c||process.cwd(),env:s})
|
|
4679
4662
|
return v.unref(),f&&f(v.pid),{success:!0,pid:v.pid}}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
4680
4663
|
return m&&e instanceof Error&&m(e),{success:!1,error:t}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=n,exports.spawnJournalSubagent=function(e,t,r,o){return n({agent:"journal",prompt:`Generate a journal entry for request ${e}.\n\nSteps:\n1. Use ${t}__generate_request_journal tool with requestId: ${e}\n2. Write a concise narrative journal entry based on the returned data covering:\n - What was implemented and why\n - Key decisions and trade-offs made\n - Challenges encountered and solutions\n - Files modified and their purposes\n - How acceptance criteria were met\n3. Save as JOURNAL-${e}.md using ${t}__document_operations (operation: create, type: Report)\n\nKeep it story-focused and informative.`,cwd:r,parentServerUrl:o})},exports.spawnWorkSubagent=function(e,t,r){return n({agent:"work",prompt:e,cwd:t,parentServerUrl:r})}
|
|
4681
4664
|
const o=t(5317),s=t(8824),i=t(9896),a=t(6928)},8037(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListRequests=async function(e,t,i,a,c){const l=a.child({tool:"list_requests"}),d=c.startTimer("tool_execution_time")
|
|
@@ -4754,31 +4737,31 @@ if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
|
4754
4737
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4755
4738
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,t,r,n,o,s,i,p){const f=s.child({tool:"create_directory"}),m=Date.now()
|
|
4756
4739
|
let y,w,b=d.FileOperationPhase.VALIDATION
|
|
4757
|
-
const
|
|
4740
|
+
const I={toolName:"create-directory",operationName:"create",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"create-directory",metricsPrefix:"create_directory",successMessage:"Successfully created directory {path}",failureMessage:"Failed to create directory {path}"}
|
|
4758
4741
|
try{const s=d.validateArgs(e,l.CreateDirectorySchema),{taskId:u,path:h,comment:g}=s
|
|
4759
|
-
f.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,f,i,
|
|
4760
|
-
const{normalizedPath:
|
|
4742
|
+
f.info("Creating directory: "+h,{taskId:u,path:h,comment:g}),d.validateTaskIdFormat(u,f,i,I.metricsPrefix),t.getCurrentBranchContext&&await t.getCurrentBranchContext()
|
|
4743
|
+
const{normalizedPath:k,fullPath:v}=d.validateAndNormalizePath(h,t)
|
|
4761
4744
|
b=d.FileOperationPhase.TASK_VALIDATION,i.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4762
|
-
const C=await d.validateTaskId(u,
|
|
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:
|
|
4764
|
-
const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:f,metrics:i,metricsPrefix:
|
|
4745
|
+
const C=await d.validateTaskId(u,k,r,f,i,I.metricsPrefix),_=C?.requestId,E=await d.validateWorkItemStates(u,k,r,o,t,f,i,I.metricsPrefix),q=await d.autoPromoteTaskStatus(u,C.status,_,E.request?.status,k,r,o,f,i,I.metricsPrefix)
|
|
4746
|
+
q.taskPromoted&&f.info(`Auto-promoted task ${u} (${C.title||"Untitled"}) to in_progress for file operation`,{taskId:u,taskTitle:C.title,previousStatus:C.status,newStatus:q.newTaskStatus,path:k}),q.requestPromoted&&f.info(`Auto-promoted request ${_} to in_progress for file operation`,{requestId:_,previousStatus:E.request?.status,newStatus:q.newRequestStatus,triggeringTaskId:u})
|
|
4747
|
+
const S=await d.ensureCorrectWorkspaceContext({taskPromoted:q.taskPromoted,requestId:_,context:t,operation:"create-directory",logger:f,metrics:i,metricsPrefix:I.metricsPrefix})
|
|
4765
4748
|
if(!S.success){if(S.isLockConflict)return{content:[{type:"text",text:"\u274c "+S.error}],isError:!0}
|
|
4766
4749
|
throw Error(S.error)}let T=!1
|
|
4767
4750
|
try{T=(await a.default.stat(v)).isDirectory()}catch{T=!1}b=d.FileOperationPhase.RECORD_CREATION,i.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4768
|
-
const{toolRecordId:P,localToolRecordId:R}=await d.createFileOperationRecords(u,_,t.projectId,
|
|
4769
|
-
y=P,w=P,b=
|
|
4751
|
+
const{toolRecordId:P,localToolRecordId:R}=await d.createFileOperationRecords(u,_,t.projectId,I.recordType,k,{directoryExists:T,userComment:g},r,n,f,i,I.metricsPrefix,p)
|
|
4752
|
+
y=P,w=P,b=I.fileOperationPhase,i.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4770
4753
|
let M=T
|
|
4771
|
-
if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+
|
|
4754
|
+
if(!T){await a.default.mkdir(v,{recursive:!0}),f.info("Successfully created directory "+k)
|
|
4772
4755
|
try{const e=c.default.join(v,".gitkeep")
|
|
4773
4756
|
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),M=!0,f.info("Created .gitkeep file for Git tracking")}catch(e){f.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),M=!1}}const j=Date.now()-m
|
|
4774
4757
|
i.recordValue("create_directory_time",j),i.incrementCounter("create_directory_success",1),b=d.FileOperationPhase.GIT_COMMIT,i.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4775
|
-
const x=`Create directory: ${
|
|
4776
|
-
b=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:b}),await d.updateFileOperationRecords(u,y,w,I
|
|
4777
|
-
const
|
|
4778
|
-
return{content:[{type:"text",text:T?"Directory already exists":`Successfully created directory${
|
|
4758
|
+
const x=`Create directory: ${k} - ${g||"Create directory"}`,O=!T&&M?k+"/.gitkeep":k,D=await d.commitToGit(u,O,P,R,x,t,f,i,I.metricsPrefix)
|
|
4759
|
+
b=d.FileOperationPhase.RECORD_UPDATE_SUCCESS,i.incrementCounter("create_directory_phase",1,{phase:b}),await d.updateFileOperationRecords(u,y,w,k,I.recordType,`Successfully ${T?"verified":"created"} directory: ${k}`,{status:"completed",commitHash:D.commitHash,previousCommitHash:D.previousCommitHash,directoryExists:T,isDirectory:!0,userComment:g},`Successfully ${T?"verified":"created"} directory: ${k}`,r,n,f,i,I.metricsPrefix)
|
|
4760
|
+
const A=t.getCurrentBranchContext?await t.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4761
|
+
return{content:[{type:"text",text:T?"Directory already exists":`Successfully created directory${D.commitHash?"\nCommit: "+D.commitHash.substring(0,8):""}${A.requestId?"\nBranch: "+A.requestId:""}${S.lockAcquired&&S.lockedRequestId?"\n\u{1f512} **Locked request:** "+S.lockedRequestId:""}`}]}}catch(o){if(e.taskId&&n)try{const r=o instanceof u.NotFoundError||o instanceof u.ValidationError||o instanceof h.ZodError
|
|
4779
4762
|
await n.createToolRecord({...r?{}:{taskId:e.taskId},projectId:t.projectId,type:"create-directory",metadata:{status:"failed",timestamp:(new Date).toISOString(),path:e.path,userComment:e.comment,error:(0,g.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:`Failed to create directory ${e.path} - ${(0,g.getErrorMessage)(o)}`})}catch(t){f.error("Failed to create failure record for create directory operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,path:e.path})}const s=Date.now()-m
|
|
4780
4763
|
if(i.recordValue("create_directory_time",s),i.incrementCounter("create_directory_errors",1),f.error("Error creating directory:",{error:(0,g.getErrorMessage)(o),time:s}),(y||w)&&e.taskId){b=d.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
4781
|
-
try{await d.updateFileOperationRecords(e.taskId,y,w,e.path,
|
|
4764
|
+
try{await d.updateFileOperationRecords(e.taskId,y,w,e.path,I.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,g.getErrorMessage)(o),userComment:e.comment},"Failed to create directory "+e.path,r,n,f,i,I.metricsPrefix)}catch(t){f.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,b,f,i,e,I)}}
|
|
4782
4765
|
const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(8824)},8317(e,exports,t){function r(e){const t=[]
|
|
4783
4766
|
return"write-file"===e.type&&e.metadata?.path?t.push(e.metadata.path):"replace-in-files"===e.type&&e.metadata?.operations?e.metadata.operations.forEach((e=>{e.path&&t.push(e.path)})):"move-files"===e.type&&e.metadata?.successfulOperations?e.metadata.successfulOperations.forEach((e=>{e.destination&&t.push(e.destination)})):"delete-files"===e.type&&e.metadata?.paths?t.push(...e.metadata.paths):"manage-files"===e.type&&e.metadata?.operations&&e.metadata.operations.forEach((e=>{e.createDirectory?.path&&t.push(e.createDirectory.path),e.moveFiles?.moves&&e.moveFiles.moves.forEach((e=>{e.destination&&t.push(e.destination)})),e.deleteFiles?.targets&&e.deleteFiles.targets.forEach((e=>{e.path&&t.push(e.path)}))})),[...new Set(t)]}function n(e){switch(e){case"write-file":return"\u{1f4dd} Write File"
|
|
4784
4767
|
case"replace-in-files":return"\u{1f504} Replace in Files"
|
|
@@ -4987,34 +4970,34 @@ return i(t,e),t})
|
|
|
4987
4970
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileHistory=async function(e,t,n,o,s){const i=o.child({tool:"file_history"}),a=s.startTimer("tool_execution_time"),m=Date.now()
|
|
4988
4971
|
try{let o
|
|
4989
4972
|
try{o=d.FileHistorySchema.parse(e)}catch(t){if(t instanceof u.ZodError){const r="Invalid arguments: "+t.errors.map((e=>e.message)).join(", ")
|
|
4990
|
-
return i.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{path:a,limit:y,showDiff:w,showTraceability:b,branch:
|
|
4991
|
-
return
|
|
4973
|
+
return i.warn("Validation error",{error:r,args:e}),{content:[{type:"text",text:"\u274c "+r}],isError:!0}}throw t}const{path:a,limit:y,showDiff:w,showTraceability:b,branch:I,commit:k,since:v}=o
|
|
4974
|
+
return k?(i.info("Getting diff for specific commit",{filePath:a,commit:k}),await async function(e,t,r,n){const o=r.git,s=c.normalize(e).replace(/\\/g,"/")
|
|
4992
4975
|
if(n.info("Getting full diff for commit",{filePath:e,commit:t}),!o)return{content:[{type:"text",text:"\u274c Git not initialized"}],isError:!0}
|
|
4993
4976
|
try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
|
|
4994
4977
|
if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
|
|
4995
4978
|
const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
|
|
4996
4979
|
let a="# File History - Commit Diff\n\n"
|
|
4997
|
-
return a+=`**File:** ${e}\n`,a+=`**Commit:** ${t.substring(0,8)}\n`,a+=`**Author:** ${n.author_name}\n`,a+=`**Date:** ${n.date}\n`,a+=`**Message:** ${n.message}\n\n`,i&&i.trim()?a+=`## Full Diff\n\n\`\`\`diff\n${i}\n\`\`\`\n`:a+="*No diff available for this commit*\n",{content:[{type:"text",text:a}]}}catch(r){return n.error("Failed to get commit diff",{error:r,commit:t,filePath:e}),{content:[{type:"text",text:`\u274c Failed to get diff for commit ${t}: ${(0,p.getErrorMessage)(r)}`}],isError:!0}}}(a,
|
|
4980
|
+
return a+=`**File:** ${e}\n`,a+=`**Commit:** ${t.substring(0,8)}\n`,a+=`**Author:** ${n.author_name}\n`,a+=`**Date:** ${n.date}\n`,a+=`**Message:** ${n.message}\n\n`,i&&i.trim()?a+=`## Full Diff\n\n\`\`\`diff\n${i}\n\`\`\`\n`:a+="*No diff available for this commit*\n",{content:[{type:"text",text:a}]}}catch(r){return n.error("Failed to get commit diff",{error:r,commit:t,filePath:e}),{content:[{type:"text",text:`\u274c Failed to get diff for commit ${t}: ${(0,p.getErrorMessage)(r)}`}],isError:!0}}}(a,k,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:y,showDiff:w,showTraceability:b,branch:I}),await async function(e,t,n,o,s,i,a,c,d,u,p){try{const{normalizedPath:m,fullPath:y}=f.validateAndNormalizePath(e,a)
|
|
4998
4981
|
try{await l.access(y)}catch(e){throw Error("File not found: "+m)}const w=a.git
|
|
4999
4982
|
if(!w)throw Error("Git is not available in this context")
|
|
5000
4983
|
let b={branch:null,requestId:null,isMain:!0}
|
|
5001
|
-
if(a.getCurrentBranchContext)try{b=await a.getCurrentBranchContext(),d.info("Current branch context detected",{branch:b.branch,requestId:b.requestId,isMain:b.isMain})}catch(e){d.warn("Could not get current branch context",{error:e})}let
|
|
5002
|
-
if(s)
|
|
4984
|
+
if(a.getCurrentBranchContext)try{b=await a.getCurrentBranchContext(),d.info("Current branch context detected",{branch:b.branch,requestId:b.requestId,isMain:b.isMain})}catch(e){d.warn("Could not get current branch context",{error:e})}let I=[],k=""
|
|
4985
|
+
if(s)I=await r(w,m,t,n,o,s,i,c,d,u),k=`## File History: ${m} (Branch: ${s})\n\n`
|
|
5003
4986
|
else{if(b.isMain&&!o)return d.info("Showing request-level timeline on main branch"),{content:[{type:"text",text:await(0,g.getRequestTimelineForFile)(w,m,c,d,u)}]}
|
|
5004
4987
|
if(b.requestId)return d.info("Showing operation-level detail on request branch",{requestId:b.requestId}),{content:[{type:"text",text:await(0,g.getOperationDetailForFile)(m,b.requestId,c,d,u)}]}
|
|
5005
4988
|
{const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
|
|
5006
4989
|
if(!i.isMain&&i.branch){const g=await r(e,t,n,o,s,i.branch,a,c,l,d)
|
|
5007
4990
|
u.push(...g),g.length>0&&h.push(i.branch+" (current)")}const g=await r(e,t,n,o,s,"main",a,c,l,d),p=new Set(u.map((e=>e.hash))),f=g.filter((e=>!p.has(e.hash)))
|
|
5008
4991
|
return u.push(...f),g.length>0&&h.push("main"),u.sort(((e,t)=>new Date(t.date).getTime()-new Date(e.date).getTime())),{versions:u.slice(0,n),sources:h}}(w,m,t,n,o,b,i,c,d,u)
|
|
5009
|
-
|
|
5010
|
-
const v=
|
|
5011
|
-
v>t?
|
|
5012
|
-
try{
|
|
5013
|
-
for(let e=0;e<
|
|
5014
|
-
if(
|
|
4992
|
+
I=e.versions,k=`## File History: ${m} (Combined View)\n\n`,k+=`**Current Context:** ${b.isMain?"main":`${b.branch} (${b.requestId})`}\n`,k+=`**History Sources:** ${e.sources.join(", ")}\n\n`}}if(0===I.length)return k+="\u274c **No history found**\n\nThis file has no git history. It may be:\n- A new file that hasn't been committed\n- Located outside the git repository\n- The path may be incorrect\n- No history exists in the specified branch context",{content:[{type:"text",text:k}]}
|
|
4993
|
+
const v=I.length,C=Math.min(I.length,t)
|
|
4994
|
+
v>t?k+=`\u{1f4ca} **Summary:** ${v} versions found, showing ${C} most recent\n\n`:v>0&&(k+=`\u{1f4ca} **Summary:** ${v} version${v>1?"s":""} found\n\n`),k+=`**Total Versions:** ${I.length}\n`,k+="**Current File Size:** "
|
|
4995
|
+
try{k+=(await l.stat(y)).size+" bytes\n"}catch{k+="Unknown\n"}k+="\n"
|
|
4996
|
+
for(let e=0;e<I.length;e++){const t=I[e]
|
|
4997
|
+
if(k+=`### Version ${e+1} (${t.hash.substring(0,8)})\n`,t.branch&&(k+=`- **Branch:** ${t.branch}\n`),k+=`- **Author:** ${t.author}\n`,k+=`- **Date:** ${t.date}\n`,k+=`- **Message:** ${t.message}\n`,o&&t.traceability&&(k+=`\n${(0,h.formatTraceabilityInfo)(t.traceability)}\n`),n&&t.diff){const e=t.diff.split("\n")
|
|
5015
4998
|
let r=0,n=0
|
|
5016
4999
|
for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
|
|
5017
|
-
|
|
5000
|
+
k+=`\n**Changes:**${r>0||n>0?` (Added ${r} lines, removed ${n} lines)`:""}\n\`\`\`diff\n${t.diff}\n\`\`\`\n`}k+="\n"}return k+="\u{1f4a1} **Tips:**\n",k+="- Use `file-recover` with a commit hash to restore the file to a previous version\n",k+='- Use `{"branch": "main"}` to see only main branch history\n',k+='- Use `{"branch": "req123456"}` to see only request branch history\n\n',d.info("Branch-aware file history retrieved successfully",{path:m,versions:I.length,targetBranch:s,currentBranch:b.branch,duration:Date.now()-p}),u.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:k}]}}catch(e){throw e}}(a,y,w,b,I,v,t,n,i,s,m))}catch(e){const t=Date.now()-m
|
|
5018
5001
|
return i.error("File/Document history operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),a({tool:"file_history",success:!1}),s.incrementCounter("file_history_errors",1),{content:[{type:"text",text:"\u274c **History Operation Failed:** "+(0,p.getErrorMessage)(e)}],isError:!0}}}
|
|
5019
5002
|
const c=a(t(6928)),l=a(t(1943)),d=t(6183),u=t(1569),h=t(1181),g=t(2085),p=t(8824),f=a(t(5967)),m=a(t(7478)),{getCurrentBranch:y}=m},8850(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
5020
5003
|
const r=t(6183),n=t(6891)
|
|
@@ -5346,10 +5329,10 @@ continue}const t=(0,h.findMatches)(s,n,m,100,e.path)
|
|
|
5346
5329
|
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(m?" (tried fuzzy matching)":""),a.success=!1
|
|
5347
5330
|
const e=(0,h.findSimilarMatches)(s,n,5,.3)
|
|
5348
5331
|
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
|
|
5350
|
-
for(const e of p)for(const t of e.matches)
|
|
5351
|
-
|
|
5352
|
-
for(const{match:e,newText:t,repResult:n}of
|
|
5332
|
+
const I=[]
|
|
5333
|
+
for(const e of p)for(const t of e.matches)I.push({match:t,newText:e.newText,repResult:e.repResult})
|
|
5334
|
+
I.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5335
|
+
for(const{match:e,newText:t,repResult:n}of I)w=(0,h.replaceMatch)(w,e,t),n.success?(n.lines.push(e.line),n.details.push(r(e))):(n.success=!0,n.matchType=e.matchType,n.lines=[e.line],n.details=[r(e)],y.successfulReplacements++)
|
|
5353
5336
|
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)
|
|
5354
5337
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5355
5338
|
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,47 +5341,47 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
5358
5341
|
var t={}
|
|
5359
5342
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
5360
5343
|
return i(t,e),t}),c=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
5361
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFiles=async function(e,t,r,o,s,i,a,c){const
|
|
5344
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFiles=async function(e,t,r,o,s,i,a,c){const I=i.child({tool:"replace_in_files"}),k=Date.now()
|
|
5362
5345
|
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)
|
|
5346
|
+
try{if(e&&"string"==typeof e.operations)try{e.operations=JSON.parse(e.operations)}catch{}if(e&&Array.isArray(e.operations))for(const t of e.operations)t.old&&t.new&&!t.replacements&&(t.replacements=[{old:t.old,new:t.new,match_mode:t.match_mode}],delete t.old,delete t.new,delete t.match_mode)
|
|
5364
5347
|
const i=u.validateArgs(e,d.ReplaceInFilesSchema),{taskId:_,operations:E,fuzzy_match:q=!0,comment:S}=i
|
|
5365
|
-
|
|
5348
|
+
I.info("Replace in files batch operation",{taskId:_,operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,comment:S})
|
|
5366
5349
|
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,
|
|
5350
|
+
if(T.length>0&&t.apiClient)try{await(0,m.ensureDocumentsNotLocked)(T,t.apiClient,I,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5368
5351
|
throw e}C=u.FileOperationPhase.TASK_VALIDATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5369
5352
|
const P=E[0],R=P.documentId?"document:"+P.documentId:P.path
|
|
5370
5353
|
let M=Date.now()
|
|
5371
|
-
const j=await u.validateTaskId(_,R,r,
|
|
5354
|
+
const j=await u.validateTaskId(_,R,r,I,a,"replace_in_files")
|
|
5372
5355
|
Date.now()
|
|
5373
5356
|
const x=j?.requestId,O=E.some((e=>e.path))
|
|
5374
|
-
let
|
|
5357
|
+
let D=!1
|
|
5375
5358
|
if(O&&x){M=Date.now()
|
|
5376
|
-
const e=await u.validateWorkItemStates(_,R,r,s,t,
|
|
5359
|
+
const e=await u.validateWorkItemStates(_,R,r,s,t,I,a,"replace_in_files")
|
|
5377
5360
|
Date.now(),M=Date.now()
|
|
5378
|
-
const n=await u.autoPromoteTaskStatus(_,j.status,x,e.request?.status,R,r,s,
|
|
5379
|
-
n.taskPromoted&&
|
|
5380
|
-
const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:x,context:t,operation:"replace_in_files",logger:
|
|
5361
|
+
const n=await u.autoPromoteTaskStatus(_,j.status,x,e.request?.status,R,r,s,I,a,"replace_in_files")
|
|
5362
|
+
n.taskPromoted&&I.info("Auto-promoted task to in_progress",{taskId:_,requestId:x,previousStatus:j.status,newStatus:n.newTaskStatus}),Date.now(),M=Date.now()
|
|
5363
|
+
const o=await u.ensureCorrectWorkspaceContext({taskPromoted:n.taskPromoted,requestId:x,context:t,operation:"replace_in_files",logger:I,metrics:a,metricsPrefix:"replace_in_files"})
|
|
5381
5364
|
if(!o.success){if(o.isLockConflict)return{content:[{type:"text",text:"\u274c "+o.error}],isError:!0}
|
|
5382
|
-
throw Error(o.error)}Date.now(),
|
|
5365
|
+
throw Error(o.error)}Date.now(),D=!0}if(T.length>0&&x)try{await(0,p.validateRequestStatusForDocumentOperation)(x,s,I,a,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5383
5366
|
throw e}M=Date.now()
|
|
5384
|
-
const
|
|
5385
|
-
if(
|
|
5367
|
+
const A=new Map
|
|
5368
|
+
if(I.info("\u{1f50d} Starting external edit detection",{hasFileOperations:O,hasGit:!!t.git,operationCount:E.length}),O&&t.git)for(const e of E)if(e.path&&!e.documentId)try{const r=u.validateAndNormalizePath(e.path,t),n=await l.default.readFile(r.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:q,s=[]
|
|
5386
5369
|
for(const t of e.replacements){const r=(0,h.findMatches)(n,t.old,o,100,e.path)
|
|
5387
5370
|
s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,r.fullPath)
|
|
5388
|
-
|
|
5389
|
-
const i=await(0,w.detectExternalEdits)(t.git,o,
|
|
5390
|
-
|
|
5391
|
-
const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},
|
|
5392
|
-
e.userChangesCommitted&&(
|
|
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,
|
|
5371
|
+
I.info("\u{1f50d} Checking for external edits",{path:r.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
|
|
5372
|
+
const i=await(0,w.detectExternalEdits)(t.git,o,I)
|
|
5373
|
+
I.info("\u{1f50d} External edit detection result",{path:r.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(A.set(e.path,{message:i.message,debugInfo:i.debugInfo}),I.warn("\u26a0\ufe0f External edits detected before auto-commit",{path:r.normalizedPath,conflictingLines:i.conflictingLines})):(i.debugInfo&&A.set(e.path,{message:"",debugInfo:i.debugInfo}),I.info("\u2705 No external edit conflicts detected",{path:r.normalizedPath}))}else I.info("\u2139\ufe0f No matches found for external edit detection",{path:r.normalizedPath}),A.set(e.path,{message:"",debugInfo:{detectionRan:!1,reason:"No matches found - patterns not found in file",affectedRegion:"none",uncommittedChanges:"not checked",overlapDetected:!1}})}catch(t){I.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,b.getErrorMessage)(t)})}if(Date.now(),M=Date.now(),O&&t.git)try{I.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
|
|
5374
|
+
const e=await(0,f.commitUserChangesBeforeToolOperation)(t.git,"replace_in_files",{requestId:x,taskId:_,workspaceManager:t.workspaceManager},I,a)
|
|
5375
|
+
e.userChangesCommitted&&(I.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),I.info("User changes committed before batch operation",{taskId:_,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){I.warn("Pre-tool user changes commit failed",{taskId:_,error:e instanceof Error?e.message:e+""})}Date.now(),M=Date.now(),C=u.FileOperationPhase.RECORD_CREATION,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5376
|
+
const{toolRecordId:$}=await u.createFileOperationRecords(_,x,t.projectId,"replace-in-files",R,{operationCount:E.length,totalReplacements:E.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:q,userComment:S},r,o,I,a,"replace_in_files",c)
|
|
5394
5377
|
v=$,Date.now(),M=Date.now(),C=u.FileOperationPhase.STRING_REPLACEMENT,a.incrementCounter("replace_in_files_phase",1,{phase:C})
|
|
5395
5378
|
const F=[],N=[]
|
|
5396
|
-
for(const e of E){const r=e.path?
|
|
5379
|
+
for(const e of E){const r=e.path?A.get(e.path):void 0,o=await n(e,q,t,0,0,r?.message,r?.debugInfo)
|
|
5397
5380
|
F.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&N.push(o.path)}Date.now(),M=Date.now()
|
|
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:
|
|
5381
|
+
const L=E.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),z=await u.handleMultiFileGitCommit(_,L,F,N.length,{operationType:"Replace in files",toolRecordId:$||v||"unknown",successField:"successfulReplacements",logger:I,metrics:a,metricsPrefix:"replace_in_files"},t),B=z.commitHash
|
|
5399
5382
|
Date.now(),Date.now()
|
|
5400
5383
|
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})))
|
|
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()-
|
|
5384
|
+
await o.updateToolRecord(v,{metadata:{path:R,status:0===U?"completed":"partial",operationCount:E.length,operations:V,successfulFiles:J,failedFiles:K,successfulReplacements:W,failedReplacements:G,processingTime:Date.now()-k,userComment:S,...z.success&&z.commitHash&&{commitHash:z.commitHash,previousCommitHash:z.previousCommitHash||void 0}}})
|
|
5402
5385
|
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
|
|
5403
5386
|
let l="## Replace In Files - Batch Results\n\n"
|
|
5404
5387
|
if(o.getCurrentBranchContext)try{const e=await o.getCurrentBranchContext()
|
|
@@ -5411,8 +5394,8 @@ for(const e of o)l+=`- \u2705 \`${e.old.substring(0,40)}${e.old.length>40?"...":
|
|
|
5411
5394
|
if(s.length>0){l+="\n**Failed Replacement Details:**\n"
|
|
5412
5395
|
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
5396
|
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)
|
|
5414
|
-
return{content:[{type:"text",text:Y}],isError:0===W}}catch(e){const t=Date.now()-
|
|
5415
|
-
if(
|
|
5397
|
+
return{content:[{type:"text",text:Y}],isError:0===W}}catch(e){const t=Date.now()-k
|
|
5398
|
+
if(I.error("Replace in files batch operation failed",{error:e instanceof Error?e.stack:e+"",duration:t,phase:C}),v)try{await o.updateToolRecord(v,{metadata:{status:"failed",error:(0,b.getErrorMessage)(e),phase:C,duration:t}})}catch(e){}return a.incrementCounter("replace_in_files_errors",1,{phase:C}),{content:[{type:"text",text:"\u274c **Replace In Files Failed:** "+(0,b.getErrorMessage)(e)}],isError:!0}}}
|
|
5416
5399
|
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")
|
|
5417
5400
|
const t=e.trim()
|
|
5418
5401
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|
|
@@ -5671,7 +5654,7 @@ if(null===c){n.warn("Could not read plugin source: "+e.sourceName),l.errors.push
|
|
|
5671
5654
|
continue}const d=e.destName.startsWith("lib/")?c:["const __plugin = (function() {\n const module = { exports: {} };\n const exports = module.exports;\n (function() {",c," })();\n return module.exports.default || module.exports;\n})();\nexport default __plugin;"].join("\n"),h=i.default.createHash("md5").update(d).digest("hex"),g=r(a)
|
|
5672
5655
|
if(null===g||h!==g){const t=s.default.dirname(a)
|
|
5673
5656
|
t!==u&&await o.default.promises.mkdir(t,{recursive:!0}),await o.default.promises.writeFile(a,d,"utf8"),n.info("Synced plugin: "+e.destName,{reason:null===g?"not installed":"updated"}),l.synced.push(e.destName)}else l.skipped.push(e.destName)}catch(t){n.error("Failed to sync plugin: "+e.destName,{error:t instanceof Error?t.message:"Unknown error"}),l.errors.push(e.destName)}}return l}
|
|
5674
|
-
const o=n(t(9896)),s=n(t(6928)),i=n(t(6982)),a=[{sourceName:"plugins/hooks/plugin.js",destName:"event-hooks.js"},{sourceName:"plugins/hooks/lib/condition-evaluator.js",destName:"lib/condition-evaluator.js"},{sourceName:"plugins/hooks/lib/hook-utils.js",destName:"lib/hook-utils.js"},{sourceName:"plugins/hooks/lib/dedup-utils.js",destName:"lib/dedup-utils.js"},{sourceName:"plugins/inject-session.js",destName:"inject-session.js"},{sourceName:"plugins/
|
|
5657
|
+
const o=n(t(9896)),s=n(t(6928)),i=n(t(6982)),a=[{sourceName:"plugins/hooks/plugin.js",destName:"event-hooks.js"},{sourceName:"plugins/hooks/lib/condition-evaluator.js",destName:"lib/condition-evaluator.js"},{sourceName:"plugins/hooks/lib/hook-utils.js",destName:"lib/hook-utils.js"},{sourceName:"plugins/hooks/lib/dedup-utils.js",destName:"lib/dedup-utils.js"},{sourceName:"plugins/inject-session.js",destName:"inject-session.js"},{sourceName:"plugins/system-logger.js",destName:"system-logger.js"}]},9947(e,exports){function t(e,t){return e.substring(0,t).split("\n").length}function r(e){if(0===e.length)return[]
|
|
5675
5658
|
const t=[...e].sort(((e,t)=>e.start-t.start)),r=[t[0]]
|
|
5676
5659
|
for(let e=1;e<t.length;e++){const n=t[e],o=r[r.length-1]
|
|
5677
5660
|
n.start>o.end+1?r.push(n):o.end=Math.max(o.end,n.end)}return r}function n(e,t){return e.start<=t.end&&t.start<=e.end}Object.defineProperty(exports,"__esModule",{value:!0}),exports.calculateReplacementRegion=function(e,n,o){const s=[]
|