alchemylab 1.4.1 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +130 -103
- package/dist/http-server.js +63 -46
- package/dist/index.js +621 -604
- package/dist/mcp-direct.js +591 -574
- package/package.json +2 -2
- package/dist/640.js +0 -14
package/dist/index.js
CHANGED
|
@@ -14,9 +14,9 @@ var t={}
|
|
|
14
14
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
15
15
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
16
16
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.McpServer=void 0,exports.resetStdoutWrite=function(){process.stdout.write=P},exports.getMcpServer=r,exports.createServer=function(e,t,n,o,s={}){return r(e,t,n,o,s)}
|
|
17
|
-
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),
|
|
18
|
-
!(0,
|
|
19
|
-
class R{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,w.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 m.ProjectContext(e,t),this.tokenManager=new f.TokenManager(t,e,{remoteServerUrl:n}),this.configManager=new S.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new
|
|
17
|
+
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),m=t(7660),f=t(1253),y=i(t(7478)),w=t(4139),b=new Set,I=t(9860),k=t(1472),v=t(3328),C=t(8955),_=t(3217),E=t(5278),S=t(9060),T=t(8824),q=(0,p.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),P=process.stdout.write,j=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
|
|
18
|
+
!(0,p.isDebugToolsEnabled)()||j&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,p.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&q.debug("Stdout output",{content:e.substring(0,100),length:e.length}),P.call(process.stdout,e)}catch(e){return q.error("Error in safeStdoutWrite",{error:e+""}),!0}})
|
|
19
|
+
class R{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,w.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 m.ProjectContext(e,t),this.tokenManager=new f.TokenManager(t,e,{remoteServerUrl:n}),this.configManager=new S.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:{listChanged:!0}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
|
|
20
20
|
const e=this.workspaceManager.getCurrentContext("__server__")
|
|
21
21
|
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}
|
|
22
22
|
const e=this.workspaceManager.getCurrentContext("__server__")
|
|
@@ -71,9 +71,9 @@ t&&t!==e&&(this.logger.info("Project ID changed after synchronization",{oldId:e,
|
|
|
71
71
|
const o=this.getContext();(0,k.registerTools)(this.server,o,this.apiClient,this.logger,this.metrics,this.tokenManager,this),this.tokenManager.setProjectId(this.getProjectId()),this.logger.info("Complete initialization finished - all tools available")}async getCurrentBranchInfo(){try{if(!this.git)return{available:!1,message:"No git repository available"}
|
|
72
72
|
const e=await y.getRepositoryStatus(this.git,this.logger,this.metrics)
|
|
73
73
|
return e.isGitRepository?{available:!0,currentBranch:e.currentBranch,isClean:e.isClean,branchCount:e.branches.length,message:`On branch ${e.currentBranch}${e.isClean?" (clean)":" (uncommitted changes)"}`}:{available:!1,message:"Not a git repository"}}catch(e){return this.logger.warn("Failed to get branch info",{error:(0,T.getErrorMessage)(e)}),{available:!1,message:"Git error: "+(0,T.getErrorMessage)(e)}}}async createSseConnection(e,t){await this.waitForInitialization(),this.cleanupSSEConnection(),this.logger.debug("Creating new SSE connection"),e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive")
|
|
74
|
-
const r=new
|
|
74
|
+
const r=new g.SSEServerTransport("/sse",e)
|
|
75
75
|
this.currentSSEConnection={transport:r,response:e}
|
|
76
|
-
try{await this.server.connect(r),this.logger.info("SSE transport connected successfully")}catch(e){this.logger.error("Error connecting SSE transport",{error:(0,T.getErrorMessage)(e)})}return r}async connectStdio(){await this.waitForInitialization(),this.logger.debug("Connecting stdio transport"),this.stdioTransport=new
|
|
76
|
+
try{await this.server.connect(r),this.logger.info("SSE transport connected successfully")}catch(e){this.logger.error("Error connecting SSE transport",{error:(0,T.getErrorMessage)(e)})}return r}async connectStdio(){await this.waitForInitialization(),this.logger.debug("Connecting stdio transport"),this.stdioTransport=new g.StdioServerTransport
|
|
77
77
|
try{await this.server.connect(this.stdioTransport),this.logger.info("STDIO transport connected successfully")}catch(e){this.logger.error("Error connecting stdio transport",{error:(0,T.getErrorMessage)(e)})}}getCurrentSSEConnection(){return this.currentSSEConnection}setCurrentSSEConnection(e){this.currentSSEConnection=e}getServer(){return this.server}getCurrentGitInstance(){if(!this.workspaceManager)return this.git||void 0
|
|
78
78
|
const e=this.workspaceManager.getCurrentContext("__server__")
|
|
79
79
|
return"multi-agent"===e.mode&&e.requestId?this.workspaceManager.getCurrentGit():this.git||void 0}getContext(){if(!this.workspaceManager)throw Error("WorkspaceManager not initialized")
|
|
@@ -112,26 +112,26 @@ default:return"\u2753"}}function s(e){switch(e){case"feature":return"\u2728"
|
|
|
112
112
|
case"bugfix":return"\u{1f41b}"
|
|
113
113
|
case"quick-edit":return"\u26a1"
|
|
114
114
|
default:return"\u{1f4e6}"}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearchRequests=async function(e,t,c,l,d){const u=l.child({tool:"search_requests"}),h=d.startTimer("tool_execution_time")
|
|
115
|
-
try{const{query:a,searchIn:l="all",filters:
|
|
115
|
+
try{const{query:a,searchIn:l="all",filters:g={}}=e.search||e
|
|
116
116
|
if(!a||0===a.trim().length)throw new i.ValidationError("Search query is required")
|
|
117
|
-
const
|
|
118
|
-
if(!
|
|
119
|
-
u.info("Searching requests",{query:a,searchIn:l,filters:
|
|
120
|
-
const m={limit:
|
|
121
|
-
|
|
117
|
+
const p=t.projectId
|
|
118
|
+
if(!p)throw new i.ValidationError("Project ID is required for searching requests")
|
|
119
|
+
u.info("Searching requests",{query:a,searchIn:l,filters:g,projectId:p})
|
|
120
|
+
const m={limit:g.limit||100,offset:g.offset||0,sortBy:"updated_at",sortDirection:"desc"}
|
|
121
|
+
g.status&&(m.status=g.status),g.type&&(m.type=g.type),g.dateFrom&&(m.dateFrom=g.dateFrom),g.dateTo&&(m.dateTo=g.dateTo),c.setProjectId(p)
|
|
122
122
|
const f=c.getRequestClient(),y=await f.listRequests(m)
|
|
123
123
|
u.debug("Fetched requests for search",{count:y.length})
|
|
124
124
|
const w=[],b=a.toLowerCase()
|
|
125
125
|
for(const e of y){const t=[]
|
|
126
126
|
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
|
|
127
127
|
if(o&&o.toLowerCase().includes(b)){t.push({request:e,matchType:"criteria",matchSnippet:n(o,b,150)})
|
|
128
|
-
break}}t.length>0&&w.push(t[0])}const I=
|
|
128
|
+
break}}t.length>0&&w.push(t[0])}const I=g.limit||20,k=w.slice(0,I)
|
|
129
129
|
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}`}]}
|
|
130
130
|
let v=`Found ${k.length} request${1===k.length?"":"s"} matching "${a}":\n\n`
|
|
131
131
|
for(const e of k){const t=e.request,r=o(t.status)
|
|
132
132
|
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: `
|
|
133
133
|
const C=[]
|
|
134
|
-
return
|
|
134
|
+
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}}}
|
|
135
135
|
const i=t(9860),a=t(8824)},260(e,exports,t){"use strict"
|
|
136
136
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
137
137
|
const r=t(6183),n=t(4221)
|
|
@@ -165,14 +165,14 @@ default:t="open"}else t="open"
|
|
|
165
165
|
const n=Array.isArray(e.acceptanceCriteria)?e.acceptanceCriteria.map(r):[]
|
|
166
166
|
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.skippedTestRunId?{skippedTestRunId:e.skippedTestRunId}:{},...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)}
|
|
167
167
|
const o=t(6756)},405(e,exports,t){"use strict"
|
|
168
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlanWrite=async function(e,t,l,d,u,h,
|
|
168
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlanWrite=async function(e,t,l,d,u,h,g){const p=d.child({tool:"plan_write"})
|
|
169
169
|
try{const a=e,{operation:d,planId:m}=a
|
|
170
|
-
switch(
|
|
170
|
+
switch(p.info("Processing plan_write",{operation:d}),d){case"create":{const e=await(0,s.handleCreatePlan)({name:a.name,content:a.content??"",kind:a.kind||"plan",criteria:a.criteria,tickIntervalSeconds:a.tickIntervalSeconds,maxInFlight:a.maxInFlight,maxPerDay:a.maxPerDay},t,l,p,u,h,g)
|
|
171
171
|
u.incrementCounter("plan_write_total",1,{operation:"create",success:!e.isError})
|
|
172
172
|
const r=a.kind||"plan"
|
|
173
|
-
return(0,c.withAlchemyKind)(e,i.KIND_META[r].alchemyKind)}case"update":{const e=await(0,r.handleUpdatePlan)({planId:m,content:a.content,name:a.name,metadata:{criteria:a.criteria,tickIntervalSeconds:a.tickIntervalSeconds,maxInFlight:a.maxInFlight,maxPerDay:a.maxPerDay,minIterations:a.minIterations,status:a.status}},t,l,
|
|
174
|
-
return u.incrementCounter("plan_write_total",1,{operation:"update",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-update")}case"append":{const e=await(0,n.handleAppendPlan)({planId:m,content:a.content,name:a.name},l,
|
|
175
|
-
return u.incrementCounter("plan_write_total",1,{operation:"append",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-append")}case"replace":{const e=await(0,o.handleReplacePlan)({planId:m,old:a.old,new:a.new,name:a.name},l,
|
|
173
|
+
return(0,c.withAlchemyKind)(e,i.KIND_META[r].alchemyKind)}case"update":{const e=await(0,r.handleUpdatePlan)({planId:m,content:a.content,name:a.name,metadata:{criteria:a.criteria,tickIntervalSeconds:a.tickIntervalSeconds,maxInFlight:a.maxInFlight,maxPerDay:a.maxPerDay,minIterations:a.minIterations,status:a.status}},t,l,p,u)
|
|
174
|
+
return u.incrementCounter("plan_write_total",1,{operation:"update",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-update")}case"append":{const e=await(0,n.handleAppendPlan)({planId:m,content:a.content,name:a.name},l,p,u)
|
|
175
|
+
return u.incrementCounter("plan_write_total",1,{operation:"append",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-append")}case"replace":{const e=await(0,o.handleReplacePlan)({planId:m,old:a.old,new:a.new,name:a.name},l,p,u)
|
|
176
176
|
return u.incrementCounter("plan_write_total",1,{operation:"replace",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-replace")}case"create-snapshot":{const{versionLabel:e,changeSummary:t}=a,r=l.getDocumentClient(),n=await r.createVersionSnapshot(m,e,t)
|
|
177
177
|
return u.incrementCounter("plan_write_total",1,{operation:"create-snapshot",success:!0}),(0,c.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Plan Snapshot Created**\n\n**Plan:** ${m}\n**Version:** ${n.versionNumber}\n**Label:** ${e||"None"}\n**Summary:** ${t||"None"}\n**Created:** `+new Date(n.createdAt).toLocaleString()}]},"plan-snapshot")}case"restore":{const{versionNumber:e}=a,t=l.getDocumentClient(),r=await t.restoreToVersion(m,e)
|
|
178
178
|
return u.incrementCounter("plan_write_total",1,{operation:"restore",success:!0}),(0,c.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Plan Restored**\n\n**Plan:** ${m}\n**Restored to Version:** ${e}\n**Filename:** ${r.filename}\n\nThe plan has been successfully restored to version ${e}.`}]},"plan-restore")}case"set-active":{const e=t.projectId
|
|
@@ -183,7 +183,7 @@ if("Plan"!==n.type)return{content:[{type:"text",text:`\u274c Document ${m} is no
|
|
|
183
183
|
const o=l.getProjectClient()
|
|
184
184
|
await o.updateProject(e,{activePlanId:m}),u.incrementCounter("plan_write_total",1,{operation:"set-active",success:!0})
|
|
185
185
|
const s=n.localId||n.id
|
|
186
|
-
return(0,c.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Active Plan Updated**\n\n**Plan:** ${s}\n**Filename:** ${n.filename}\n**Project:** ${e}\n\nThis plan is now the active project plan.`}]},"plan-set-active")}default:throw Error("Unknown plan_write operation: "+d)}}catch(e){return
|
|
186
|
+
return(0,c.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Active Plan Updated**\n\n**Plan:** ${s}\n**Filename:** ${n.filename}\n**Project:** ${e}\n\nThis plan is now the active project plan.`}]},"plan-set-active")}default:throw Error("Unknown plan_write operation: "+d)}}catch(e){return p.error("plan_write failed",{error:e instanceof Error?e.stack:e+""}),u.incrementCounter("plan_write_errors",1),{content:[{type:"text",text:"\u274c **Plan Write Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
187
187
|
const r=t(7609),n=t(4419),o=t(2352),s=t(6656),i=t(3416),a=t(8824),c=t(2272)},441(e,exports){"use strict"
|
|
188
188
|
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"},509(e,exports,t){"use strict"
|
|
189
189
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
@@ -250,24 +250,24 @@ if(t.response&&"object"==typeof t.response&&"number"==typeof t.response.status)r
|
|
|
250
250
|
if("string"==typeof t.message){const e=t.message.match(/status (\d+)/i)
|
|
251
251
|
if(e&&e[1]){const t=parseInt(e[1],10)
|
|
252
252
|
if(!isNaN(t))return t}}return null}}exports.ToolRecordClient=i},1020(e,exports,t){"use strict"
|
|
253
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQueryHistory=async function(e,c,l,d,u,h){const
|
|
254
|
-
try{const a=e,{queryType:
|
|
253
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQueryHistory=async function(e,c,l,d,u,h){const g=d.child({tool:"query_history"})
|
|
254
|
+
try{const a=e,{queryType:p}=a
|
|
255
255
|
let m
|
|
256
|
-
switch(
|
|
256
|
+
switch(g.info("Processing query_history request",{queryType:p}),p){case"file-history":g.info("Routing to file-history handler",{path:a.fileHistory.path}),m=await(0,r.handleFileHistory)({path:a.fileHistory.path,limit:a.fileHistory.limit,showDiff:a.fileHistory.showDiff,showTraceability:a.fileHistory.showTraceability,branch:a.fileHistory.branch,since:a.fileHistory.since},c,l,g,u)
|
|
257
257
|
break
|
|
258
|
-
case"request-file-history":
|
|
258
|
+
case"request-file-history":g.info("Routing to request-file-history handler",{requestId:a.requestHistory.requestId}),m=await(0,n.handleRequestFileHistory)({requestId:a.requestHistory.requestId,showDiff:a.requestHistory.showDiff,detailLevel:a.requestHistory.detailLevel,taskId:a.requestHistory.taskId,fileFilter:a.requestHistory.fileFilter},c,l,g,u)
|
|
259
259
|
break
|
|
260
|
-
case"recover":
|
|
260
|
+
case"recover":g.info("Routing to file-recover handler",{path:a.recover.path,commitHash:a.recover.commitHash})
|
|
261
261
|
let s=a.recover.commitHash
|
|
262
262
|
if(!s){const e=a.recover.path,r=c.workspaceManager?.getCurrentContext(c.currentSessionId)?.basePath||c.basePath||process.cwd(),{resolve:n}=await Promise.resolve().then(t.t.bind(t,6928,23)),o=n(r,e)
|
|
263
263
|
try{const{execSync:n}=await Promise.resolve().then(t.t.bind(t,5317,23)),i=n(`git log --format=%H -n 2 -- "${o}"`,{cwd:r,encoding:"utf8"}).trim().split("\n").filter(Boolean)
|
|
264
264
|
if(s=i[1]||i[0],!s)return{content:[{type:"text",text:"No previous versions found for "+e}],isError:!0}
|
|
265
|
-
|
|
266
|
-
return await e(c,l,d)||"untracked"})(),path:a.recover.path,commitHash:s,createBackup:a.recover.createBackup},c,l,l.getToolRecordClient(),
|
|
265
|
+
g.info("Auto-resolved previous version",{filePath:e,commitHash:s})}catch{return{content:[{type:"text",text:"Could not find previous versions of "+e}],isError:!0}}}m=await(0,o.handleFileRecover)({taskId:e.recover?.taskId||await(async()=>{const{resolveActiveTaskId:e}=await Promise.resolve().then(t.bind(t,3451))
|
|
266
|
+
return await e(c,l,d)||"untracked"})(),path:a.recover.path,commitHash:s,createBackup:a.recover.createBackup},c,l,l.getToolRecordClient(),g,u,h)
|
|
267
267
|
break
|
|
268
|
-
case"blame":
|
|
268
|
+
case"blame":g.info("Routing to file-blame handler",{path:a.blame.path,lines:a.blame.lines}),m=await(0,i.handleFileBlame)({path:a.blame.path,lines:a.blame.lines,branch:a.blame.branch},c,l,g,u)
|
|
269
269
|
break
|
|
270
|
-
default:throw Error("Unknown query type: "+
|
|
270
|
+
default:throw Error("Unknown query type: "+p)}return g.info("query_history request completed",{queryType:p,success:!m.isError}),u.incrementCounter("query_history_total",1,{success:!m.isError,queryType:p}),(0,s.withAlchemyKind)(m,"query-history")}catch(e){return g.error("query_history request failed",{error:e instanceof Error?e.stack:e+""}),u.incrementCounter("query_history_errors",1),{content:[{type:"text",text:"\u274c **Query History Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
271
271
|
const r=t(8828),n=t(8317),o=t(4640),s=t(2272),i=t(4811),a=t(8824)},1038(e,exports){"use strict"
|
|
272
272
|
function t(e){let t
|
|
273
273
|
if("string"==typeof e.metadata&&e.metadata)try{t=JSON.parse(e.metadata)}catch(e){t=void 0}else e.metadata&&"object"==typeof e.metadata&&(t=e.metadata)
|
|
@@ -343,7 +343,7 @@ j.registerClient(F)
|
|
|
343
343
|
const N=new S.ToolRecordClient(q,n.child({component:"tool-record-client"}),o,M,R,x)
|
|
344
344
|
j.registerClient(N)
|
|
345
345
|
const z=new T.ApiClient(P,M,O,$,A,F,N,D,n.child({component:"api-client"})),L=a.default.Router();(0,h.registerAuthRoutes)(L,{projectClient:M,taskClient:O,fileClient:$,authManager:P,apiClient:z},i,n)
|
|
346
|
-
const H=r.getContext();(0,
|
|
346
|
+
const H=r.getContext();(0,g.registerConfigRoutes)(L,n,H.basePath),e.use("/api",L)
|
|
347
347
|
const B=e=>{const t=o.startTimer(e)
|
|
348
348
|
return e=>t(e)},U=(e,t,n)=>{const o=e.query.path||e.body.path
|
|
349
349
|
if(!o)return t.status(400).json({success:!1,error:"Path parameter is required"})
|
|
@@ -381,7 +381,7 @@ const l=await(0,m.handleWriteFile)({taskId:a,path:e.relativePath,content:i,forma
|
|
|
381
381
|
s({endpoint:"files/write",method:"POST",success:!0}),t.json({success:!0,data:l})}catch(e){s(e)}})),e.post("/api/files/replace",U,G,(async(e,t,s)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/replace",method:"POST"})
|
|
382
382
|
const s=B("api_request_duration"),{replacements:i,mode:a="unique",taskId:c}=e.body
|
|
383
383
|
if(!i||!Array.isArray(i))throw(0,u.createValidationError)("Replacements array is required")
|
|
384
|
-
const l=await(0,
|
|
384
|
+
const l=await(0,p.handleReplaceStrings)({taskId:c,operations:[{path:e.relativePath,replacements:i,mode:a}],comment:"String replacement via API"},r.getContext(),O,N,A,n,o)
|
|
385
385
|
s({endpoint:"files/replace",method:"POST",success:!0}),t.json({success:!0,data:l})}catch(e){s(e)}})),e.delete("/api/files/delete",U,G,(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/delete",method:"DELETE"})
|
|
386
386
|
const r=B("api_request_duration"),{taskId:n}=e.body
|
|
387
387
|
try{await l.default.access(e.fullPath)}catch(t){throw r({endpoint:"files/delete",method:"DELETE",success:!1,error:"not_found"}),(0,u.createNotFoundError)("File not found: "+e.relativePath)}await l.default.unlink(e.fullPath),r({endpoint:"files/delete",method:"DELETE",success:!0}),t.json({success:!0,data:{path:e.relativePath,deleted:!0}})}catch(e){r(e)}})),e.post("/api/directories/create",U,G,(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"directories/create",method:"POST"})
|
|
@@ -418,7 +418,7 @@ throw e}}catch(e){r(e)}})),e.patch("/api/proxy/*",G,(async(e,t,r)=>{try{const r=
|
|
|
418
418
|
try{const n=await z.proxyPatch(r,e.body)
|
|
419
419
|
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})
|
|
420
420
|
throw e}}catch(e){r(e)}}))}
|
|
421
|
-
const a=i(t(7252)),c=i(t(6928)),l=i(t(1943)),d=t(3444),u=t(9860),h=t(6776),
|
|
421
|
+
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),m=t(4079),f=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),S=t(922),T=t(3328)},1253(e,exports,t){"use strict"
|
|
422
422
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
423
423
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.TokenManager=void 0
|
|
424
424
|
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"
|
|
@@ -483,10 +483,10 @@ const r=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Co
|
|
|
483
483
|
if(r.ok){const e=await r.json()
|
|
484
484
|
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){"use strict"
|
|
485
485
|
Object.defineProperty(exports,"__esModule",{value:!0})},1281(e,exports,t){"use strict"
|
|
486
|
-
async function r(e,t,o,s,i,a,c,l,d,u=0){let
|
|
486
|
+
async function r(e,t,o,s,i,a,c,l,d,u=0){let p=0,m=0,f=0
|
|
487
487
|
const y=[]
|
|
488
|
-
if(o.length>=v||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:v,depth:c}),{filesCount:
|
|
489
|
-
try{const w=await
|
|
488
|
+
if(o.length>=v||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:v,depth:c}),{filesCount:p,fileMatchesCount:m,subdirCount:f,subdirStats:y}
|
|
489
|
+
try{const w=await g.default.readdir(e,{withFileTypes:!0}),b=[],C=[]
|
|
490
490
|
for(const t of w){const r=h.default.join(e,t.name)
|
|
491
491
|
if(t.isDirectory()){if(k.includes(t.name)||t.name.startsWith(".")){a.debug("Skipping excluded directory: "+t.name)
|
|
492
492
|
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})
|
|
@@ -494,19 +494,19 @@ continue}b.push({entry:t,fullPath:r})}}if(b.length>0){const e=[]
|
|
|
494
494
|
for(let t=0;t<b.length;t+=16)e.push(b.slice(t,t+16))
|
|
495
495
|
for(const r of e){if(o.length>=v)break
|
|
496
496
|
const e=await Promise.all(r.map((({entry:e,fullPath:r})=>n(r,t,0,o,l,d,e.name,u))))
|
|
497
|
-
for(const t of e){
|
|
498
|
-
for(const e of t.matches){if(o.length>=v)return{filesCount:
|
|
497
|
+
for(const t of e){p++,t.hasMatches&&m++
|
|
498
|
+
for(const e of t.matches){if(o.length>=v)return{filesCount:p,fileMatchesCount:m,subdirCount:f,subdirStats:y}
|
|
499
499
|
o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=v)break
|
|
500
500
|
f++
|
|
501
501
|
const e={path:n,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
502
502
|
try{const l=await r(n,t,o,s,i,a,c+1,e,d,u)
|
|
503
|
-
|
|
503
|
+
p+=l.filesCount,m+=l.fileMatchesCount,e.filesProcessed=l.filesCount,e.filesMatched=l.fileMatchesCount,e.subdirectories=l.subdirCount,y.push(e),l.subdirStats&&l.subdirStats.length>0&&y.push(...l.subdirStats)}catch(t){const r=`Error processing subdirectory ${n}: ${(0,I.getErrorMessage)(t)}`
|
|
504
504
|
e.errors.push(r),y.push(e),a.error(r)}}}catch(t){const r=`Error searching directory ${e}: ${(0,I.getErrorMessage)(t)}`
|
|
505
|
-
l.errors.push(r),a.warn(r)}return{filesCount:
|
|
505
|
+
l.errors.push(r),a.warn(r)}return{filesCount:p,fileMatchesCount:m,subdirCount:f,subdirStats:y}}async function n(e,t,r,n,o,s,i,a=0){const c=[]
|
|
506
506
|
let l,d=!1
|
|
507
|
-
const u=async()=>{if(void 0===l)try{const t=await
|
|
507
|
+
const u=async()=>{if(void 0===l)try{const t=await g.default.stat(e)
|
|
508
508
|
l=t.mtime.getTime()}catch(e){l=void 0}return l}
|
|
509
|
-
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
|
|
509
|
+
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")
|
|
510
510
|
for(let o=0;o<r.length&&n.length<v;o++)if(t.test(r[o])){d=!0,await u()
|
|
511
511
|
const t={file:e,line:o+1,text:(0,y.truncate)(r[o].trim(),120),modifiedTime:l,matchType:"content"}
|
|
512
512
|
if(a>0){const e=Math.max(0,o-a)
|
|
@@ -522,10 +522,10 @@ for(let t=0;t<Math.min(e,n.contextAfter.length);t++)i.push({lineNumber:s+t,conte
|
|
|
522
522
|
for(let t=Math.max(s,e)-e;t<r.contextBefore.length;t++){const n=e+t
|
|
523
523
|
s>n||n>a||i.some((e=>e.lineNumber===n))||i.push({lineNumber:n,content:r.contextBefore[t],isMatch:!1})}}}}i.push({lineNumber:r.line,content:r.text,isMatch:!0})}if(n.contextAfter&&n.contextAfter.length>0){const e=n.line+1
|
|
524
524
|
n.contextAfter.forEach(((t,r)=>{i.push({lineNumber:e+r,content:t,isMatch:!1})}))}const a=Array.from(new Map(i.map((e=>[e.lineNumber,e]))).values()).sort(((e,t)=>e.lineNumber-t.lineNumber))
|
|
525
|
-
return{file:r.file,relativePath:r.relativePath||r.file,startLine:o,endLine:s,lines:a}}async function i(e){try{const t=await
|
|
525
|
+
return{file:r.file,relativePath:r.relativePath||r.file,startLine:o,endLine:s,lines:a}}async function i(e){try{const t=await g.default.stat(e),r=h.default.extname(e).toLowerCase()
|
|
526
526
|
if(!C.has(r))return
|
|
527
527
|
if(t.size>_)return
|
|
528
|
-
return 0===t.size?0:(await
|
|
528
|
+
return 0===t.size?0:(await g.default.readFile(e,"utf-8")).split("\n").length}catch{return}}var a,c=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
529
529
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
530
530
|
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]}),l=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),d=this&&this.__importStar||(a=function(e){return a=Object.getOwnPropertyNames||function(e){var t=[]
|
|
531
531
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -535,16 +535,16 @@ if(null!=e)for(var r=a(e),n=0;n<r.length;n++)"default"!==r[n]&&c(t,e,r[n])
|
|
|
535
535
|
return l(t,e),t}),u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
536
536
|
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()
|
|
537
537
|
let k=0
|
|
538
|
-
const v={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:
|
|
539
|
-
try{const{needle:n,directory:
|
|
540
|
-
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,b.handleListDirectory)({path:
|
|
538
|
+
const v={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:[]}
|
|
539
|
+
try{const{needle:n,directory:p,options:C={}}=e
|
|
540
|
+
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,b.handleListDirectory)({path:p||".",levels:C.levels||1,sortBy:C.sortBy||"name"},t,a,c)
|
|
541
541
|
if("string"!=typeof n)throw v.errors.push("Search term (needle) must be a string"),(0,m.createValidationError)("Search term (needle) must be a string")
|
|
542
542
|
let _
|
|
543
|
-
if(v.searchDirectory=
|
|
543
|
+
if(v.searchDirectory=p||".",p){const{normalizedPath:e,fullPath:r}=f.validateAndNormalizePath(p,t)
|
|
544
544
|
_=r}else _=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath
|
|
545
545
|
v.resolvedPath=_
|
|
546
546
|
let E=!1
|
|
547
|
-
try{E=(await
|
|
547
|
+
try{E=(await g.default.stat(_)).isFile()}catch(e){const t=`Cannot access path ${_}: ${(0,I.getErrorMessage)(e)}`
|
|
548
548
|
throw v.errors.push(t),Error(t)}const S=C.maxResults||50,T=C.caseSensitive||!1,q=C.useRegex||!1,P=C.fileExtension,j=C.searchIn||"content"
|
|
549
549
|
let R=void 0!==C.contextLines?C.contextLines:0
|
|
550
550
|
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!E&&!P)throw v.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,m.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
|
|
@@ -552,19 +552,19 @@ let x,M=""
|
|
|
552
552
|
if(E)M="*"
|
|
553
553
|
else if("*"===P)M="*"
|
|
554
554
|
else if(P){let e=P;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),M=e.startsWith(".")?e:"."+e}try{x=q?T?RegExp(n):RegExp(n,"i"):T?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${q?"regex":"search"} pattern: ${(0,I.getErrorMessage)(e)}`
|
|
555
|
-
throw v.errors.push(t),(0,m.createValidationError)(t)}if(v.patternInfo={needle:n,regex:x.toString(),caseSensitive:T,fileExtension:P,normalizedExtension:M},!E)try{const e=Date.now(),t=await
|
|
555
|
+
throw v.errors.push(t),(0,m.createValidationError)(t)}if(v.patternInfo={needle:n,regex:x.toString(),caseSensitive:T,fileExtension:P,normalizedExtension:M},!E)try{const e=Date.now(),t=await g.default.readdir(_,{withFileTypes:!0}),r=[],n=[]
|
|
556
556
|
for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
|
|
557
557
|
v.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},v.phases.directoryListingTime=v.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,I.getErrorMessage)(e)
|
|
558
558
|
v.errors.push(t),l.error(t)}const O=E?"file":"directory"
|
|
559
559
|
l.info(`Searching for "${n}" in ${O} ${_} (mode: ${j})`,{needle:n,searchTarget:O,path:_,options:{maxResults:S,caseSensitive:T,fileExtension:M,searchIn:j}}),k=Date.now(),v.phases.initializationTime=k-u
|
|
560
560
|
const $=Date.now()
|
|
561
561
|
let D=[],A=0,F=0
|
|
562
|
-
try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,
|
|
562
|
+
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=[]
|
|
563
563
|
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)
|
|
564
564
|
let c
|
|
565
565
|
n.info("Searching single file: "+e,{searchIn:r})
|
|
566
|
-
try{c=(await
|
|
567
|
-
return o.errors.push(r),n.error(r),{matches:i,totalFiles:0}}if("filename"!==r&&"both"!==r||t.test(a)&&(i.push({file:e,line:0,text:a,modifiedTime:c,matchType:"filename"}),n.info("Filename match found: "+a)),"content"===r||"both"===r)try{const r=(await
|
|
566
|
+
try{c=(await g.default.stat(e)).mtime.getTime()}catch(t){const r=`Cannot access file ${e}: ${(0,I.getErrorMessage)(t)}`
|
|
567
|
+
return o.errors.push(r),n.error(r),{matches:i,totalFiles:0}}if("filename"!==r&&"both"!==r||t.test(a)&&(i.push({file:e,line:0,text:a,modifiedTime:c,matchType:"filename"}),n.info("Filename match found: "+a)),"content"===r||"both"===r)try{const r=(await g.default.readFile(e,"utf8")).split("\n")
|
|
568
568
|
for(let n=0;n<r.length;n++)if(t.test(r[n])){const t={file:e,line:n+1,text:(0,y.truncate)(r[n].trim(),120),modifiedTime:c,matchType:"content"}
|
|
569
569
|
if(s>0){const e=Math.max(0,n-s)
|
|
570
570
|
t.contextBefore=r.slice(e,n).map((e=>(0,y.truncate)(e.trim(),120)))
|
|
@@ -572,9 +572,9 @@ const o=Math.min(r.length,n+1+s)
|
|
|
572
572
|
t.contextAfter=r.slice(n+1,o).map((e=>(0,y.truncate)(e.trim(),120)))}i.push(t)}n.info(`Found ${i.filter((e=>"content"===e.matchType)).length} content matches`)}catch(t){const r=`Error reading file ${e}: ${(0,I.getErrorMessage)(t)}`
|
|
573
573
|
o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
|
|
574
574
|
const m={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
575
|
-
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,
|
|
576
|
-
return m.filesProcessed=n,m.filesMatched=c,m.subdirectories=d,i.directoryStats.push(m),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:
|
|
577
|
-
return m.errors.push(r),i.directoryStats.push(m),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:
|
|
575
|
+
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,p,a,o,s,0,m,l,u)
|
|
576
|
+
return m.filesProcessed=n,m.filesMatched=c,m.subdirectories=d,i.directoryStats.push(m),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,I.getErrorMessage)(t)
|
|
577
|
+
return m.errors.push(r),i.directoryStats.push(m),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:p,totalFiles:m.filesProcessed}}}(_,x,{maxResults:S,fileExtension:M,searchIn:j,isFile:E,contextLines:R},M,l,v)
|
|
578
578
|
D=e.matches,A=e.totalFiles
|
|
579
579
|
const t=1e3
|
|
580
580
|
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)`),F=D.length,D.length>S&&(D=D.slice(0,S),l.info(`Limited results to ${S} (from ${F} total matches)`)),D.forEach((e=>{e.relativePath=function(e,t){const r=h.default.relative(e,t)
|
|
@@ -584,7 +584,7 @@ let N,z=""
|
|
|
584
584
|
try{if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
585
585
|
e.branchName&&!e.permanentBranch&&(z=e.isMainBranch?` (searched on main branch: ${e.branchName})`:` (searched on request branch: ${e.branchName}${e.requestId?" for "+e.requestId:""})`)}}catch(e){l.debug("Could not get branch context",{error:e}),z=" (branch context unavailable)"}l.debug("Search diagnostic information",{diagnostic:v})
|
|
586
586
|
const L="content"===j?"content":"filename"===j?"filenames":"content and filenames"
|
|
587
|
-
if(F>D.length?(N=`Found ${F} results for "${n}" (searching ${L})`,
|
|
587
|
+
if(F>D.length?(N=`Found ${F} results for "${n}" (searching ${L})`,p&&(N+=" in "+p),P&&(N+=" with extension "+P),N+=`${z}. Showing first ${D.length}:\n\n`):(N=`Found ${D.length} results for "${n}" (searching ${L})`,p&&(N+=" in "+p),P&&(N+=" with extension "+P),N+=z+":\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))
|
|
588
588
|
if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
|
|
589
589
|
const o=new Map
|
|
590
590
|
for(const e of n){const t=o.get(e.file)||[]
|
|
@@ -608,7 +608,7 @@ else N+="No matches found."
|
|
|
608
608
|
return d({success:!0}),{content:[{type:"text",text:N}],...(0,w.alchemyMeta)({kind:"search"})}}catch(t){l.error("Search failed",{args:e,error:t instanceof Error?t.stack:t+""}),v.errors.push((0,I.getErrorMessage)(t)),v.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:v})
|
|
609
609
|
let r="Search failed: "+(0,I.getErrorMessage)(t)
|
|
610
610
|
return d({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:r}],isError:!0}}}
|
|
611
|
-
const h=u(t(6928)),
|
|
611
|
+
const h=u(t(6928)),g=u(t(1943)),p=u(t(857)),m=t(9860),f=d(t(5967)),y=t(5967),w=t(2272),b=t(2537),I=t(8824),k=["node_modules"],v=1e4,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"]),_=1048576},1318(e,exports,t){"use strict"
|
|
612
612
|
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)
|
|
613
613
|
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}`])
|
|
614
614
|
if(!a||""===a.trim())return null
|
|
@@ -626,12 +626,12 @@ for(const e of r){const r=e.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/)
|
|
|
626
626
|
if(r){const e=parseInt(r[3],10),n=r[4]?parseInt(r[4],10):1,o=e+n-1
|
|
627
627
|
n>0&&t.push({start:e,end:o})}}return t}(s)
|
|
628
628
|
return{ranges:i,diff:s}}catch(e){return n.warn("Failed to get uncommitted changes",{filePath:t,error:(0,l.getErrorMessage)(e)}),{ranges:[],diff:""}}}(e,t.path,i),d=c.ranges,u=c.diff,h=await async function(e,t,n){try{const o=await r(e,t,n),s=await e.log({file:o,maxCount:1})
|
|
629
|
-
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),
|
|
629
|
+
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),g=!!h&&n(h),p=t.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),m=d.map((e=>`${e.start}-${e.end}`)).join(", ")||"none",f=u?u.substring(0,300):"no diff"
|
|
630
630
|
if(0===d.length){const r=[]
|
|
631
631
|
for(const s of t.lineRanges){const a=await o(e,t.path,s.start,s.end,i)
|
|
632
|
-
a&&(n(a.message)||r.push({range:`${s.start}-${s.end}`,commit:a}))}if(r.length>0){const e=r.map((e=>`Lines ${e.range}: ${e.commit.hash.substring(0,8)} - ${e.commit.message}`)).join("; "),n=[`\u26a0\ufe0f Warning: Lines ${
|
|
633
|
-
return{hasExternalEdits:!0,conflictingLines:t.lineRanges.flatMap((e=>Array.from({length:e.end-e.start+1},((t,r)=>e.start+r)))),message:n,debugInfo:{detectionRan:!0,affectedRegion:
|
|
634
|
-
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:
|
|
632
|
+
a&&(n(a.message)||r.push({range:`${s.start}-${s.end}`,commit:a}))}if(r.length>0){const e=r.map((e=>`Lines ${e.range}: ${e.commit.hash.substring(0,8)} - ${e.commit.message}`)).join("; "),n=[`\u26a0\ufe0f Warning: Lines ${p} were last modified by external commits (not alchemy).`,"","Commit details: "+e,"\nThese changes may have been made manually or by another tool.\nReview recent commits before proceeding."].join("\n")
|
|
633
|
+
return{hasExternalEdits:!0,conflictingLines:t.lineRanges.flatMap((e=>Array.from({length:e.end-e.start+1},((t,r)=>e.start+r)))),message:n,debugInfo:{detectionRan:!0,affectedRegion:p,uncommittedChanges:"none",lastCommit:r[0].commit.message,wasLastCommitAlchemy:!1,diffPreview:e,overlapDetected:!0}}}return{hasExternalEdits:!1,conflictingLines:[],debugInfo:{detectionRan:!0,affectedRegion:p,uncommittedChanges:"none",lastCommit:h,wasLastCommitAlchemy:g,diffPreview:"no uncommitted changes, last commits from alchemy",overlapDetected:!1}}}const y={path:t.path,lineRanges:d,totalLines:d.reduce(((e,t)=>e+(t.end-t.start+1)),0),operationType:"modification"},w=(0,a.getOverlappingLines)(t,y)
|
|
634
|
+
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:p,uncommittedChanges:m,lastCommit:h,wasLastCommitAlchemy:g,diffPreview:f,overlapDetected:!1}}:{hasExternalEdits:!0,conflictingLines:w,message:["\u26a0\ufe0f Warning: File has uncommitted changes in lines you're about to modify.\n","Affected lines: "+p,"Conflicting lines: "+s(w),"",g?"Last commit was by alchemy, but file has been edited since.":"Last commit was NOT from alchemy - these may be manual edits.","\nReview the changes before proceeding."].join("\n"),details:{totalExternalChanges:y.totalLines,overlappingChanges:w.length,changedLineRanges:d},debugInfo:{detectionRan:!0,affectedRegion:p,uncommittedChanges:m,lastCommit:h,wasLastCommitAlchemy:g,diffPreview:f,overlapDetected:!0}}}catch(e){return i.error("Failed to detect external edits",{path:t.path,error:(0,l.getErrorMessage)(e)}),{hasExternalEdits:!1,conflictingLines:[],message:"Unable to check for external edits (Git error). Proceeding with caution."}}},exports.hasUncommittedChanges=async function(e,t){try{return(await e.status([t])).files.some((e=>e.path===t))}catch(e){return!1}}
|
|
635
635
|
const a=t(9947),c=i(t(6928)),l=t(8824)},1387(e,exports,t){"use strict"
|
|
636
636
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.WorkspaceRequestProcessor=void 0
|
|
637
637
|
const r=t(7075),n=t(5964),o=t(8824)
|
|
@@ -688,11 +688,11 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
688
688
|
var t={}
|
|
689
689
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
690
690
|
return i(t,e),t})
|
|
691
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentity=void 0,exports.registerTools=function(e,o,s,i,a,
|
|
691
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentity=void 0,exports.registerTools=function(e,o,s,i,a,p,I){const k=i.child({component:"tools"})
|
|
692
692
|
k.info("Registering tools...")
|
|
693
693
|
let v=!1
|
|
694
|
-
const C=!!
|
|
695
|
-
try{return await
|
|
694
|
+
const C=!!p,_=async()=>{if(!C)return!0
|
|
695
|
+
try{return await p.hasValidToken()}catch(e){return k.error("Error checking authentication status",{error:(0,d.getErrorMessage)(e)}),!1}},E=async()=>{const e=(0,l.areTestsRequiredForCompletion)(),t=await _()
|
|
696
696
|
k.info(`Generating tools list with testsRequired=${e}, authenticated=${t}`)
|
|
697
697
|
const r={testsRequired:e,authenticated:t}
|
|
698
698
|
return(0,f.generateVisibleToolsList)(r)}
|
|
@@ -708,7 +708,7 @@ let P
|
|
|
708
708
|
if(T=Date.now(),s?(s.setOptions({createRecords:q?.createsRecords??!1}),k.info(`Setting record creation for tool ${n}: ${q?.createsRecords??!1}`)):k.debug(`No API client available for tool ${n} (minimal mode)`),Date.now(),Date.now(),T=Date.now(),E?.sessionId){const e=E.sessionId,t=E.messageId,r=h.sessionIdentity.getIdentity()
|
|
709
709
|
if(r)r.sessionId!==e&&((0,m.logSessionIdentity)(n,"_meta-session-switch",{prevSessionId:r.sessionId,prevAgentType:r.agentType,newSessionId:e}),h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r.serverUrl}),o?.workspaceManager?.resetCurrentContext?.(e))
|
|
710
710
|
else{const t=await(0,u.getServerUrl)(o,k)
|
|
711
|
-
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}P={providerId:"opencode",sessionId:e,messageId:t,createdAt:(new Date).toISOString()},(0,m.logSessionIdentity)(n,"_meta",{sessionId:e,messageId:t})}else if(l=n,
|
|
711
|
+
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}P={providerId:"opencode",sessionId:e,messageId:t,createdAt:(new Date).toISOString()},(0,m.logSessionIdentity)(n,"_meta",{sessionId:e,messageId:t})}else if(l=n,p=E,v||(v=!0,k.warn("No _meta.sessionId on tool call \u2014 caller not on alchemylab-opencode fork.",{tool:l,metaKeys:p?Object.keys(p):null})),!1!==q?.requiresSession)throw(0,g.createMcpProtocolError)(`_meta.sessionId required for tool '${n}'`,{tool:n})
|
|
712
712
|
h.sessionIdentity.setCurrentCallOrigin(P)
|
|
713
713
|
const j=P?.sessionId||E?.sessionId
|
|
714
714
|
if(o?.workspaceManager){T=Date.now()
|
|
@@ -721,20 +721,20 @@ try{if(q){(0,y.preNormalize)(n,c),await(0,w.expandTaskRefsInArgs)(c,s,P?.session
|
|
|
721
721
|
const e={context:R,apiClient:s,logger:i,metrics:a,mcpServer:I,cliOrigin:P}
|
|
722
722
|
O=await q.handler(c,e)}else k.info(`Tool ${n} not found, returning negative response`),O={content:[{type:"text",text:`The tool '${n}' does not exist.`}]}}finally{M("end")}return Date.now(),Date.now(),S({tool:n,success:!0}),O}catch(t){k.error("Error executing tool:",{error:t instanceof Error?t.stack:t+"",tool:e.params.name}),a.incrementCounter("tool_errors_total",1,{tool:e.params.name,error:t instanceof Error?t.name:"unknown"})
|
|
723
723
|
let r="Unknown error"
|
|
724
|
-
return r=t instanceof b.ZodError?function(e,t){return 1===e.issues.length?n(e.issues[0],t):e.issues.map((e=>n(e,t))).join("; ")}(t,c):(0,d.getStructuredErrorMessage)(t),{content:[{type:"text",text:"Error: "+r}],isError:!0}}var l,
|
|
725
|
-
const c=t(9150),l=t(2478),d=t(8824),u=t(7617),h=t(6688),
|
|
724
|
+
return r=t instanceof b.ZodError?function(e,t){return 1===e.issues.length?n(e.issues[0],t):e.issues.map((e=>n(e,t))).join("; ")}(t,c):(0,d.getStructuredErrorMessage)(t),{content:[{type:"text",text:"Error: "+r}],isError:!0}}var l,p})),k.info("Tools registration complete")}
|
|
725
|
+
const c=t(9150),l=t(2478),d=t(8824),u=t(7617),h=t(6688),g=t(9860)
|
|
726
726
|
a(t(9896)),a(t(6928))
|
|
727
|
-
var
|
|
728
|
-
Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return
|
|
727
|
+
var p=t(7280)
|
|
728
|
+
Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return p.logSessionIdentity}})
|
|
729
729
|
const m=t(7280)
|
|
730
730
|
t(2462)
|
|
731
731
|
const f=t(2245),y=t(8622),w=t(4466),b=(a(t(857)),t(1569))},1483(e,exports,t){"use strict"
|
|
732
732
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearchDocuments=async function(e,t,n,o,s){const i=o.child({tool:"search_documents"}),a=s.startTimer("tool_execution_time")
|
|
733
|
-
try{const o=e,{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,dateFrom:u,dateTo:h,searchIn:
|
|
734
|
-
i.info("Searching documents",{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,searchIn:
|
|
735
|
-
const
|
|
736
|
-
if(!
|
|
737
|
-
return i.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}n.setProjectId(
|
|
733
|
+
try{const o=e,{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,dateFrom:u,dateTo:h,searchIn:g}=o
|
|
734
|
+
i.info("Searching documents",{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,searchIn:g})
|
|
735
|
+
const p=t.projectId
|
|
736
|
+
if(!p){const e="Project ID is required. Make sure you are in a project context."
|
|
737
|
+
return i.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}n.setProjectId(p)
|
|
738
738
|
const m=n.getDocumentClient()
|
|
739
739
|
try{const e={limit:d||100,offset:0,sortBy:"updatedAt",sortDirection:"desc",searchQuery:s,includeArchived:l||!1}
|
|
740
740
|
a&&(e.type=a),c&&(e.requestId=c),i.debug("Fetching documents with filters",{filters:e})
|
|
@@ -744,7 +744,7 @@ t=t.filter((t=>new Date(t.createdAt)>=e))}if(h){const e=new Date(h)
|
|
|
744
744
|
t=t.filter((t=>new Date(t.createdAt)<=e))}i.info(`Fetched and filtered ${t.length} documents for search`)
|
|
745
745
|
const r=[],n=s.toLowerCase()
|
|
746
746
|
for(const e of t){let t,o=null
|
|
747
|
-
if("filename"!==
|
|
747
|
+
if("filename"!==g&&"both"!==g||!e.filename.toLowerCase().includes(n)||(o="filename",t=e.filename),("content"===g||"both"===g)&&e.content&&e.content.toLowerCase().includes(n)){o="content"
|
|
748
748
|
const r=e.content.split("\n")
|
|
749
749
|
for(let e=0;e<r.length;e++)if(r[e].toLowerCase().includes(n)){const n=Math.max(0,e-1),o=Math.min(r.length-1,e+1)
|
|
750
750
|
t=r.slice(n,o+1).map(((t,r)=>n+r===e?"> "+t.trim():" "+t.trim())).join("\n")
|
|
@@ -780,8 +780,8 @@ const i=await this.getOrCreateBranchName(e,t),u=await d.branchExists(this.mainGi
|
|
|
780
780
|
try{await a.default.rm(s,{recursive:!0,force:!0})}catch{}try{await this.mainGit.raw(["worktree","prune"])}catch(t){this.logger.warn("Failed to prune worktree registry before creation",{requestId:e,error:t instanceof Error?t.message:t+""})}if(u)this.logger.info("Creating worktree for existing branch",{requestId:e,branchName:i,worktreePath:s}),await this.mainGit.raw(["worktree","add",s,i])
|
|
781
781
|
else{const t=(await d.getRepositoryStatus(this.mainGit,this.logger,this.metrics)).defaultBranch
|
|
782
782
|
if(!t)throw Error(`No default branch found in repository. Cannot create branch '${i}'.`)
|
|
783
|
-
this.logger.info("Creating worktree and new branch for request",{requestId:e,branchName:i,fromBranch:t,worktreePath:s}),await this.mainGit.raw(["worktree","add","-b",i,s,t])}const
|
|
784
|
-
return this.activeWorktrees.set(e,
|
|
783
|
+
this.logger.info("Creating worktree and new branch for request",{requestId:e,branchName:i,fromBranch:t,worktreePath:s}),await this.mainGit.raw(["worktree","add","-b",i,s,t])}const g={requestId:e,branchName:i,worktreePath:s,created:new Date,lastAccessed:new Date,sessionId:r,status:"active"}
|
|
784
|
+
return this.activeWorktrees.set(e,g),this.logger.info("Successfully created worktree",{requestId:e,branchName:i,worktreePath:s}),this.metrics.incrementCounter("worktree_created",1),n({success:!0}),{success:!0,worktreePath:s,branchName:i,message:"Created new worktree",created:!0}}catch(t){const r=(0,h.getErrorMessage)(t)
|
|
785
785
|
return this.logger.error("Failed to ensure worktree exists",{requestId:e,error:r}),this.metrics.incrementCounter("worktree_create_failure",1),n({success:!1,error:t instanceof Error?t.name:"unknown"}),{success:!1,message:"Failed to create worktree: "+r}}}async ensureWorktreeForRequest(e,t,r){return this.ensureWorktreeExists(e,t,r)}async removeWorktree(e,t=!0){const r=this.metrics.startTimer("worktree_remove_duration")
|
|
786
786
|
try{const n=this.activeWorktrees.get(e)
|
|
787
787
|
if(!n)return r({success:!0,reason:"not_found"}),{success:!0,message:"Worktree not found (already removed)"}
|
|
@@ -837,8 +837,8 @@ if(r){const e=`\u274c A document with filename "${i}" already exists ${s?"for th
|
|
|
837
837
|
return c.warn("Duplicate filename detected",{filename:i,requestId:s||"standalone",existingDocId:r.id}),{content:[{type:"text",text:e}],isError:!0}}const o=await e.createDocument(s,{filename:i,content:l,type:d,...a&&{cliOrigin:a}})
|
|
838
838
|
c.info("Document created successfully",{documentId:o.id,filename:o.filename,requestId:s||"standalone"})
|
|
839
839
|
try{const e=n.getToolRecordClient()
|
|
840
|
-
await e.createToolRecord({type:"create-document",projectId:h,metadata:{documentId:o.id,filename:o.filename,type:o.type,contentLength:l.length,requestId:s,projectId:h},note:u})}catch(e){c.warn("Failed to create tool record",{recordError:e})}const
|
|
841
|
-
return{content:[{type:"text",text:`\u2705 Document created successfully!\n\n**Document ID:** ${o.id}\n**Filename:** ${o.filename}\n**Type:** ${o.type}\n**Size:** ${l.length} characters\n`+
|
|
840
|
+
await e.createToolRecord({type:"create-document",projectId:h,metadata:{documentId:o.id,filename:o.filename,type:o.type,contentLength:l.length,requestId:s,projectId:h},note:u})}catch(e){c.warn("Failed to create tool record",{recordError:e})}const g=s?`**Request:** ${s}\n`:"**Standalone:** Yes (not tied to a request)\n"
|
|
841
|
+
return{content:[{type:"text",text:`\u2705 Document created successfully!\n\n**Document ID:** ${o.id}\n**Filename:** ${o.filename}\n**Type:** ${o.type}\n**Size:** ${l.length} characters\n`+g+`**Created:** ${o.createdAt}\n\n`+`The document is now stored in the tracking system and can be edited using standard file modification tools by referencing its document ID (${o.id}) instead of a file path.\n\n**Examples:**\n`+`- \`replace_string\` with \`documentId: "${o.id}"\`\n`+`- \`write_file\` with \`documentId: "${o.id}"\`\n`+`- \`file_history\` with \`documentId: "${o.id}"\``}]}}catch(e){const t="Failed to create document: "+(0,r.getErrorMessage)(e)
|
|
842
842
|
return c.error("Failed to create document",{error:e}),{content:[{type:"text",text:"\u274c "+t}],isError:!0}}}catch(e){return c.error("Unexpected error in create document",{error:e}),{content:[{type:"text",text:"\u274c Unexpected error: "+(0,r.getErrorMessage)(e)}],isError:!0}}finally{l({tool:"create_document"})}}
|
|
843
843
|
const r=t(8824)},1599(e,exports,t){"use strict"
|
|
844
844
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SessionRequestAssociationClient=void 0
|
|
@@ -1045,15 +1045,15 @@ r(t,"Looking up agent type from action server",{sessionId:e,url:o})
|
|
|
1045
1045
|
const s=await fetch(o)
|
|
1046
1046
|
if(s.ok){const o=await s.json()
|
|
1047
1047
|
r(t,"Agent type response from action server",{sessionId:e,agentType:o.agentType||null,source:o.source||null,success:o.success}),o.success&&o.agentType&&(n=o.agentType,w.sessionIdentity.updateIdentity({agentType:n}))}else r(t,"Agent type lookup failed",{sessionId:e,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e,error:(0,I.getErrorMessage)(n)})}if(n){const e=(0,C.getAllowedSubagents)(n)
|
|
1048
|
-
if(e&&!e.includes(c))return{content:[{type:"text",text:`\u274c Agent type '${n}' cannot spawn '${c}'.\n\n**Allowed subagents for ${n}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,I.getErrorMessage)(e)})}let
|
|
1048
|
+
if(e&&!e.includes(c))return{content:[{type:"text",text:`\u274c Agent type '${n}' cannot spawn '${c}'.\n\n**Allowed subagents for ${n}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,I.getErrorMessage)(e)})}let g
|
|
1049
1049
|
try{const e=await async function(e){try{const t=`http://localhost:${S}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
|
|
1050
1050
|
if(!r.ok)return null
|
|
1051
1051
|
const n=await r.json()
|
|
1052
1052
|
return n.success?n.data??null:null}catch{return null}}(c)
|
|
1053
|
-
if(
|
|
1054
|
-
|
|
1055
|
-
const
|
|
1056
|
-
r(t,"serverUrl resolved",{serverUrl:
|
|
1053
|
+
if(g=e?.requestContextMode,!g){const e=(0,C.getBuiltInAgentConfig)(c)
|
|
1054
|
+
g=e?.requestContextMode}}catch{}if(g&&"none"!==g&&!d)return{content:[{type:"text",text:`\u274c Agent '${c}' requires a requestId to be provided.\n\nThis agent has requestContextMode: '${g}' which means it needs to work in the context of a specific request.\n\nPlease provide a requestId when spawning this agent.`}],isError:!0}
|
|
1055
|
+
const p=await(0,y.getServerUrl)(t,s)
|
|
1056
|
+
r(t,"serverUrl resolved",{serverUrl:p})
|
|
1057
1057
|
const k=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath
|
|
1058
1058
|
if(!k)throw new m.ValidationError("Working directory not available in context")
|
|
1059
1059
|
const v=a?.sessionId
|
|
@@ -1063,21 +1063,21 @@ if(e){const t=await e.getSessionsForRequest(d,!0),r=v?t.filter((e=>e.opencodeSes
|
|
|
1063
1063
|
if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
|
|
1064
1064
|
if(!u)return s.warn("Blocked spawn: request already has active workers",{requestId:d,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId))}),{content:[{type:"text",text:`\u274c Cannot spawn: Request ${d} already has ${r.length} active worker(s): ${e}\n\nOptions:\n\u2022 Use \`useExistingSession: "${r[0].opencodeSessionId}"\` to send work to the existing session\n\u2022 Use \`allowParallel: true\` if you really need multiple workers on the same request`}],isError:!0}
|
|
1065
1065
|
E=`\u26a0\ufe0f Warning: Request ${d} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,s.warn("Spawning parallel subagent for request with existing active workers",{requestId:d,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){s.debug("Failed to check for existing workers",{error:(0,I.getErrorMessage)(e)})}let T,q,P=l
|
|
1066
|
-
d&&(T="requests/"+d,r(t,"Setting initialBranch for agent",{agent:c,requestId:d,initialBranch:T,agentRequestContextMode:
|
|
1066
|
+
d&&(T="requests/"+d,r(t,"Setting initialBranch for agent",{agent:c,requestId:d,initialBranch:T,agentRequestContextMode:g||"undefined"}),P="readonly"===g?`Working on request ${d} (READONLY mode - you cannot modify files, only explore and report).\n\n${l}`:`Working on request ${d}.\n\n${l}`)
|
|
1067
1067
|
let j,R=!1
|
|
1068
|
-
if(h){if(q=h,s.info("Using existing session for spawn",{sessionId:q,requestId:d}),!
|
|
1068
|
+
if(h){if(q=h,s.info("Using existing session for spawn",{sessionId:q,requestId:d}),!p)throw new m.ValidationError("Could not determine OpenCode server URL")
|
|
1069
1069
|
try{let e
|
|
1070
1070
|
try{const t=await fetch(`http://localhost:${S}/api/project-settings`)
|
|
1071
1071
|
if(t.ok){const r=await t.json()
|
|
1072
1072
|
if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
|
|
1073
1073
|
e={providerID:t,modelID:n.join("/")}}}}catch{}j=await o({apiClient:i,fromSessionId:a?.sessionId,toSessionId:q,body:P,requestId:d,logger:s})
|
|
1074
|
-
const t=n(P,j),r=`${
|
|
1074
|
+
const t=n(P,j),r=`${p.replace(/\/$/,"")}/session/${q}/prompt_async`,l={alchemy:{kind:"agent-delegation",payload:{body:P,fromSessionId:a?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...d?{requestId:d}:{},...j?{instructionCode:j}:{}}}},u=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:t,metadata:l}],...c?{agent:c}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
|
|
1075
1075
|
if(!u.ok){const e=await u.text().catch((()=>"Unknown error"))
|
|
1076
1076
|
throw Error(`Failed to send to existing session: ${u.status} ${e}`)}s.info("Prompt sent to existing session",{sessionId:q,agent:c})}catch(e){throw Error("Failed to use existing session: "+(0,I.getErrorMessage)(e))}}else{R=!0,r(t,"Creating session via spawn-session endpoint")
|
|
1077
1077
|
const h=v;(0,b.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:h})
|
|
1078
|
-
try{const
|
|
1079
|
-
if(!
|
|
1080
|
-
throw Error(`Spawn session endpoint failed: ${
|
|
1078
|
+
try{const g=`http://localhost:${S}/api/spawn-session`,p=await fetch(g,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent:c,prompt:l,requestId:d,parentSessionId:h,title:e.title,specialization:e.specialization,specializationHeadline:e.specializationHeadline,allowParallel:u,callerAgentType:w.sessionIdentity.getIdentity()?.agentType}),signal:AbortSignal.timeout(15e3)})
|
|
1079
|
+
if(!p.ok){const e=await p.text().catch((()=>"Unknown error"))
|
|
1080
|
+
throw Error(`Spawn session endpoint failed: ${p.status} ${e}`)}const m=await p.json()
|
|
1081
1081
|
if(!m.success||!m.data)throw Error(m.error||"Spawn session returned unsuccessful")
|
|
1082
1082
|
const{sessionId:y,model:b,serverUrl:I,initialBranch:v}=m.data
|
|
1083
1083
|
T=v,j=await o({apiClient:i,fromSessionId:a?.sessionId,toSessionId:y,body:P,requestId:d,logger:s})
|
|
@@ -1107,9 +1107,9 @@ try{let r
|
|
|
1107
1107
|
try{const e=await fetch(`http://localhost:${S}/api/project-settings`)
|
|
1108
1108
|
if(e.ok){const t=await e.json()
|
|
1109
1109
|
if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
|
|
1110
|
-
r={providerID:e,modelID:n.join("/")}}}}catch{}const a=await o({apiClient:i,fromSessionId:c?.sessionId,toSessionId:e,body:t,logger:s}),u=n(t,a),h=`${l.replace(/\/$/,"")}/session/${e}/prompt_async`,
|
|
1111
|
-
if(!
|
|
1112
|
-
throw Error(`Failed to send message: ${
|
|
1110
|
+
r={providerID:e,modelID:n.join("/")}}}}catch{}const a=await o({apiClient:i,fromSessionId:c?.sessionId,toSessionId:e,body:t,logger:s}),u=n(t,a),h=`${l.replace(/\/$/,"")}/session/${e}/prompt_async`,g={alchemy:{kind:"agent-followup",payload:{body:t,fromSessionId:c?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...a?{instructionCode:a}:{}}}},p=await fetch(h,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:u,metadata:g}],...d?{agent:d}:{},...r?{model:r}:{}}),signal:AbortSignal.timeout(1e4)})
|
|
1111
|
+
if(!p.ok){const e=await p.text().catch((()=>"Unknown error"))
|
|
1112
|
+
throw Error(`Failed to send message: ${p.status} ${e}`)}return s.info("Message sent to subagent session",{sessionId:e,agent:d,instructionCode:a}),{content:[{type:"text",text:a?`Message sent to session ${e} (${a}).\nThe subagent will process it in the background.`:`Message sent to session ${e}.\nThe subagent will process it in the background.`}],...a?{_meta:{alchemy:{kind:"continue-subagent",instructionCode:a}},instructionCode:a}:{}}}catch(e){throw Error("Failed to continue session: "+(0,I.getErrorMessage)(e))}}function a(e){const t=Math.floor(e/1e3)
|
|
1113
1113
|
if(60>t)return t+"s"
|
|
1114
1114
|
const r=Math.floor(t/60)
|
|
1115
1115
|
return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function c(e){const t=[]
|
|
@@ -1127,9 +1127,9 @@ if(!s)throw new m.ValidationError("Could not determine OpenCode server URL")
|
|
|
1127
1127
|
n.info("Checking status of subagent session",{sessionId:e})
|
|
1128
1128
|
try{const i=`${s.replace(/\/$/,"")}/session/${e}`,l=await fetch(i)
|
|
1129
1129
|
if(!l.ok)return{content:[{type:"text",text:`Session ${e} not found or has exited.`}],isError:!0}
|
|
1130
|
-
const h=await l.json(),
|
|
1130
|
+
const h=await l.json(),g=`${s.replace(/\/$/,"")}/session/${e}/message`,p=await fetch(g)
|
|
1131
1131
|
let m={input:0,output:0,reasoning:0},f="",y=d(null,h.time.updated)
|
|
1132
|
-
if(
|
|
1132
|
+
if(p.ok){const e=await p.json()
|
|
1133
1133
|
for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(m.input+=t.info.tokens.input||0,m.output+=t.info.tokens.output||0,m.reasoning+=t.info.tokens.reasoning||0)
|
|
1134
1134
|
const t=c(e)
|
|
1135
1135
|
y=d(t.lastActivityTime,h.time.updated),t.current&&(f+="\nCurrent: "+t.current),t.recent.length>0&&(f+="\nRecent: "+t.recent.join(", "))}const w=Date.now()-h.time.created,b=y.status,I=y.isReady,k=m.input+m.output+m.reasoning
|
|
@@ -1147,22 +1147,22 @@ if(e.trim())return u(e)}try{const t=n(`git log main --merges --oneline -n 50 --g
|
|
|
1147
1147
|
if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
|
|
1148
1148
|
if(o.trim())return{...u(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
|
|
1149
1149
|
if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
|
|
1150
|
-
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: ${a(w)}\nTokens: ${k.toLocaleString()} (in: ${m.input.toLocaleString()}, out: ${m.output.toLocaleString()}${m.reasoning>0?", reasoning: "+m.reasoning.toLocaleString():""})${f}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,I.getErrorMessage)(e))}}async function
|
|
1150
|
+
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: ${a(w)}\nTokens: ${k.toLocaleString()} (in: ${m.input.toLocaleString()}, out: ${m.output.toLocaleString()}${m.reasoning>0?", reasoning: "+m.reasoning.toLocaleString():""})${f}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,I.getErrorMessage)(e))}}async function g(e,t,r){const n=await(0,y.getServerUrl)(t,r)
|
|
1151
1151
|
if(!n)throw new m.ValidationError("Could not determine OpenCode server URL")
|
|
1152
1152
|
r.info("Aborting subagent session",{sessionId:e})
|
|
1153
1153
|
try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
|
|
1154
1154
|
if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
|
|
1155
|
-
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,I.getErrorMessage)(e))}}async function
|
|
1156
|
-
if(!
|
|
1155
|
+
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,I.getErrorMessage)(e))}}async function p(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:i,minTokens:l,maxTokens:u,maxAgeHours:h}=n,g=await(0,y.getServerUrl)(e,t)
|
|
1156
|
+
if(!g)throw new m.ValidationError("Could not determine OpenCode server URL")
|
|
1157
1157
|
t.info("Listing sessions",{filters:n})
|
|
1158
|
-
try{const e=
|
|
1158
|
+
try{const e=g.replace(/\/$/,"")+"/session",t=await fetch(e)
|
|
1159
1159
|
if(!t.ok)throw Error("Failed to fetch sessions: "+t.status)
|
|
1160
|
-
let
|
|
1161
|
-
if(0===
|
|
1162
|
-
const m=
|
|
1163
|
-
n.parentSessionId&&(
|
|
1164
|
-
const f=
|
|
1165
|
-
let b=
|
|
1160
|
+
let p=await t.json()
|
|
1161
|
+
if(0===p.length)return{content:[{type:"text",text:"No sessions found."}]}
|
|
1162
|
+
const m=p
|
|
1163
|
+
n.parentSessionId&&(p=p.filter((e=>(e.parentId||e.parentID)===n.parentSessionId))),p.sort(((e,t)=>t.time.created-e.time.created))
|
|
1164
|
+
const f=g.replace(/\/$/,"")+"/session/status",y=await fetch(f),w=y.ok?await y.json():{}
|
|
1165
|
+
let b=p
|
|
1166
1166
|
if(o&&(b=b.filter((e=>"idle"!==(w[e.id]?.type||"idle")))),void 0!==h){const e=36e5*h,t=Date.now()-e
|
|
1167
1167
|
b=b.filter((e=>e.time.created>=t))}if(0===b.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1168
1168
|
let I={}
|
|
@@ -1172,12 +1172,12 @@ if("specialist"===n.agentType){const e=new Set(k)
|
|
|
1172
1172
|
for(const t of m){const r=t.parentId||t.parentID
|
|
1173
1173
|
r&&e.has(r)&&(v[r]||(v[r]=[]),v[r].push(t.id),C.push(t.id))}}if(r)try{const e=r.getCLISessionClient()
|
|
1174
1174
|
if(e){const t=[...k,...C]
|
|
1175
|
-
I=await e.batchEnrich(t)}}catch{}const _=
|
|
1175
|
+
I=await e.batchEnrich(t)}}catch{}const _=g.replace(/\/$/,""),E=await Promise.allSettled(b.map((e=>fetch(`${_}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),S=[]
|
|
1176
1176
|
for(let e=0;e<b.length;e++){const t=b[e],r=Date.now()-t.time.created
|
|
1177
1177
|
let o=0,i=null,a=[],h=d(null,t.time.updated)
|
|
1178
|
-
const
|
|
1179
|
-
for(const e of
|
|
1180
|
-
if(
|
|
1178
|
+
const g=E[e],p="fulfilled"===g.status?g.value:[]
|
|
1179
|
+
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))
|
|
1180
|
+
if(p.length>0){const e=c(p)
|
|
1181
1181
|
h=d(e.lastActivityTime,t.time.updated),i=e.current||null,a=e.recent}const m=h.status
|
|
1182
1182
|
if(void 0!==l&&l>o)continue
|
|
1183
1183
|
if(void 0!==u&&o>u)continue
|
|
@@ -1201,7 +1201,7 @@ const T=t.title||"Untitled",q=T.length>50?T.slice(0,47)+"...":T
|
|
|
1201
1201
|
S.push({id:t.id,title:q,status:m,age:r,totalTokens:o,requestsInfo:y,allRequestIds:k,statusDetail:h.detail,specialization:f?.specialization??null,currentAction:i,recentActions:a})}if(0===S.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1202
1202
|
const T=i?S.slice(0,i):S,q=T.map((e=>{const t=e.specialization?"\n Specialization: "+e.specialization:"",r=e.currentAction?"\n Current: "+e.currentAction:"",o="specialist"!==n.agentType&&e.recentActions.length>0?"\n Recent: "+e.recentActions.join(", "):""
|
|
1203
1203
|
return`\u2022 ${e.id}\n ${e.title}${t}\n Status: ${e.status} (${e.statusDetail}) | Age: ${a(e.age)} | ${e.totalTokens.toLocaleString()} tokens${e.requestsInfo}${r}${o}`})),P=i&&S.length>i?` (showing ${i} of ${S.length})`:""
|
|
1204
|
-
return{content:[{type:"text",text:`Found ${T.length} session${1!==T.length?"s":""}${P}:\n\n${q.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,I.getErrorMessage)(e))}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=s,exports.handleContinue=i,exports.handleCheckStatus=h,exports.handleAbort=
|
|
1204
|
+
return{content:[{type:"text",text:`Found ${T.length} session${1!==T.length?"s":""}${P}:\n\n${q.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,I.getErrorMessage)(e))}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=s,exports.handleContinue=i,exports.handleCheckStatus=h,exports.handleAbort=g,exports.handleListSessions=p,exports.handleSubagentOperations=async function(e,t,r,n,o,a){const c=r.child({tool:"subagent_operations"}),l=n.startTimer("tool_execution_time")
|
|
1205
1205
|
try{const r=e,{sessionId:d,operation:u}=r
|
|
1206
1206
|
let f
|
|
1207
1207
|
switch(c.info("Processing subagent_operations",{operation:u,sessionId:d}),u){case"spawn":f=await s({agent:r.agent,prompt:r.prompt,requestId:r.requestId,allowParallel:r.allowParallel,useExistingSession:r.useExistingSession},t,c,o,a)
|
|
@@ -1210,7 +1210,7 @@ case"continue":f=await i(d,r.prompt,t,c,o,void 0,a)
|
|
|
1210
1210
|
break
|
|
1211
1211
|
case"check-status":f=await h(d,t,c,o)
|
|
1212
1212
|
break
|
|
1213
|
-
case"abort":f=await
|
|
1213
|
+
case"abort":f=await g(d,t,c)
|
|
1214
1214
|
break
|
|
1215
1215
|
case"read-messages":const e=r.limit??1
|
|
1216
1216
|
f=await async function(e,t,r,n){const o=await(0,y.getServerUrl)(r,n)
|
|
@@ -1225,7 +1225,7 @@ return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n$
|
|
|
1225
1225
|
return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,I.getErrorMessage)(e))}}(d,e,t,c)
|
|
1226
1226
|
break
|
|
1227
1227
|
case"list-sessions":const n={activeOnly:r.activeOnly,requestId:r.requestId,limit:r.limit,minTokens:r.minTokens,maxTokens:r.maxTokens,maxAgeHours:r.maxAgeHours,parentSessionId:a?.sessionId}
|
|
1228
|
-
f=await
|
|
1228
|
+
f=await p(t,c,o,n)
|
|
1229
1229
|
break
|
|
1230
1230
|
default:throw new m.ValidationError("Unknown operation: "+u)}l({success:!0}),n.incrementCounter(`subagent_operations_${u}_success`,1)
|
|
1231
1231
|
const w=E[u]
|
|
@@ -1344,23 +1344,27 @@ if("setup"===e.commandName){const e=process.config.setup||[]
|
|
|
1344
1344
|
if(0===e.length)return a({success:!0}),{content:[{type:"text",text:"No setup commands configured for this test process."}]}
|
|
1345
1345
|
l=e.map(((e,t)=>({name:"setup-"+(t+1),command:e,timeout:120})))}else{const t=process.config.commands||[],r=t.find((t=>t.name===e.commandName))
|
|
1346
1346
|
if(!r){const r=t.map((e=>e.name)).join(", ")
|
|
1347
|
-
return a({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}l=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{
|
|
1347
|
+
return a({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}l=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{runShellCommand:d}=await Promise.resolve().then(t.bind(t,4600)),u=globalThis.process
|
|
1348
1348
|
let h=null
|
|
1349
|
-
const p=[]
|
|
1350
|
-
try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
|
|
1351
|
-
if(p.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
|
|
1352
|
-
if(p.push("reqId: "+(t||"NONE")),t){const e=await o.proxyGet(`/api/projects/${n.projectId}/requests/${t}/test-runs`),r=e?.data||e||[],s=Array.isArray(r)?r.find((e=>e.worktreePath||e.worktree_path)):null
|
|
1353
|
-
p.push(`runs: ${Array.isArray(r)?r.length:0}, withWorktree: ${s?.id||"NONE"}, path: ${s?.worktreePath||s?.worktree_path||"NONE"}`),s&&(h=s.worktreePath||s.worktree_path,c.info("Using test worktree from request test run",{worktreePath:h,reqId:t}))}}}catch(e){c.warn("Failed to resolve test worktree",{error:(0,r.getErrorMessage)(e)})}if(!h)return a({success:!1,error:"no_worktree"}),{content:[{type:"text",text:`No test worktree found.\n\nDiagnostics:\n${p.length>0?p.map((e=>"\u2022 "+e)).join("\n"):"\u2022 No session identity found"}\n\nEnsure this session is linked to a test process and a test run has been created.`}],isError:!0}
|
|
1354
1349
|
const g=[]
|
|
1350
|
+
try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
|
|
1351
|
+
if(g.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
|
|
1352
|
+
if(g.push("reqId: "+(t||"NONE")),t){const e=await o.proxyGet(`/api/projects/${n.projectId}/requests/${t}/test-runs`),r=e?.data||e||[],s=Array.isArray(r)?r.find((e=>e.worktreePath||e.worktree_path)):null
|
|
1353
|
+
g.push(`runs: ${Array.isArray(r)?r.length:0}, withWorktree: ${s?.id||"NONE"}, path: ${s?.worktreePath||s?.worktree_path||"NONE"}`),s&&(h=s.worktreePath||s.worktree_path,c.info("Using test worktree from request test run",{worktreePath:h,reqId:t}))}}}catch(e){c.warn("Failed to resolve test worktree",{error:(0,r.getErrorMessage)(e)})}if(!h)return a({success:!1,error:"no_worktree"}),{content:[{type:"text",text:`No test worktree found.\n\nDiagnostics:\n${g.length>0?g.map((e=>"\u2022 "+e)).join("\n"):"\u2022 No session identity found"}\n\nEnsure this session is linked to a test process and a test run has been created.`}],isError:!0}
|
|
1354
|
+
const p=[],{default:m}=await Promise.resolve().then(t.t.bind(t,6928,23)),{default:f}=await Promise.resolve().then(t.t.bind(t,9896,23)),{ALCHEMY_DIR_NAME:y}=await Promise.resolve().then(t.bind(t,4139)),w=m.join(h,y,"command-logs")
|
|
1355
|
+
try{f.mkdirSync(w,{recursive:!0})}catch{}const{runTrackedShellCommand:b}=await Promise.resolve().then(t.bind(t,4600)),{sessionIdentity:I}=await Promise.resolve().then(t.bind(t,6688)),k=I.getIdentity()?.sessionId
|
|
1355
1356
|
for(const t of l){c.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:h})
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1357
|
+
const r=`${t.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,n=m.join(w,r+".log")
|
|
1358
|
+
let o=null
|
|
1359
|
+
try{o=f.createWriteStream(n,{flags:"w"}),o.write(`# ${(new Date).toISOString()} starting: ${t.command}\n# cwd: ${h}\n# timeout: ${t.timeout}s\n\n`)}catch(e){c.warn("Failed to open command log file",{logPath:n,error:e+""})}const s=await b(t.command,{cwd:h,timeoutMs:1e3*t.timeout,env:{...u.env,FORCE_COLOR:"0"},onChunk:o?(e,t)=>{o?.write(t)}:void 0},{id:r,name:t.name,sessionId:k,logPath:n})
|
|
1360
|
+
o&&(o.write(`\n# exit: ${s.exitCode}${s.timedOut?" (timed out)":""}\n`),o.end())
|
|
1361
|
+
const i=(s.stdout+(s.stderr?"\n"+s.stderr:"")).trim().slice(-4e3)
|
|
1362
|
+
if(p.push({name:t.name,command:t.command,exitCode:s.exitCode,output:i,timedOut:s.timedOut}),"setup"===e.commandName&&0!==s.exitCode)break}const v=p.every((e=>0===e.exitCode)),C=p.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
|
|
1359
1363
|
return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\``})).join("\n\n")
|
|
1360
|
-
return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${
|
|
1364
|
+
return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${v?"PASSED":"FAILED"}\n\n${C}`}]}}catch(e){return a({success:!1,error:"execution_error"}),{content:[{type:"text",text:"Failed to execute test command: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleReportTestResults=async function(e,s,i,a,c,l){const d=c.startTimer("tool_execution_time")
|
|
1361
1365
|
try{const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=await u.getSessionRequestId(i,a,l?.sessionId)
|
|
1362
1366
|
if(!h)return d({success:!1,error:"no_request_association"}),{content:[{type:"text",text:"Cannot report test results: this session is not associated with a request."}],isError:!0}
|
|
1363
|
-
const
|
|
1367
|
+
const g=await i.proxyGet(`/api/projects/${s.projectId}/requests/${h}/test-runs`),p=g?.data||g||[],m=Array.isArray(p)?p:[],f=m.find((e=>"pending"===e.status||"running"===e.status))||m[0]
|
|
1364
1368
|
if(!f)return d({success:!1,error:"no_test_run"}),{content:[{type:"text",text:`No test run found for request ${h}.`}],isError:!0}
|
|
1365
1369
|
const y=f.id
|
|
1366
1370
|
await i.proxyPatch(`/api/projects/${s.projectId}/test-runs/${y}`,{status:e.status,results:e.results}),f.worktreePath&&fetch((0,o.getActionServerBaseUrl)()+"/api/release-pool-slot",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({worktreePath:f.worktreePath}),signal:AbortSignal.timeout(5e3)}).catch((e=>a.debug("release-pool-slot fire-and-forget failed (non-fatal)",{error:(0,r.getErrorMessage)(e)})))
|
|
@@ -1376,15 +1380,15 @@ const o=r.map((e=>`**${e.name}** (${e.id})${e.scope?` [scope: ${e.scope}]`:""}\n
|
|
|
1376
1380
|
return d({success:!0}),{content:[{type:"text",text:`## Test Processes (${r.length})\n\n${o}`}]}}if("run"===e.operation){let c=0
|
|
1377
1381
|
try{const e=await i.proxyGet(`/api/projects/${n.projectId}/test-processes`),t=e?.data||e||[]
|
|
1378
1382
|
c=Array.isArray(t)?t.length:0}catch(e){a.warn("tests run: existence check failed; proceeding optimistically",{error:(0,r.getErrorMessage)(e)})}if(0===c)return d({success:!1,error:"no_process"}),{content:[{type:"text",text:'No test process registered for this project. Run `tests` with `operation: "setup"` first to bootstrap one.'}],isError:!0}
|
|
1379
|
-
const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=l?.sessionId,
|
|
1380
|
-
if(!
|
|
1381
|
-
const
|
|
1382
|
-
try{const e=await fetch((0,o.getActionServerBaseUrl)()+"/api/run-tests-now",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:
|
|
1383
|
+
const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=l?.sessionId,g=h?await u.getSessionRequestId(i,a,h):void 0
|
|
1384
|
+
if(!g)return d({success:!1,error:"no_request"}),{content:[{type:"text",text:"tests run requires an associated request \u2014 your session is not currently linked to one. Open or create a request, then try again."}],isError:!0}
|
|
1385
|
+
const p=e.name?[e.name]:void 0
|
|
1386
|
+
try{const e=await fetch((0,o.getActionServerBaseUrl)()+"/api/run-tests-now",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:g,parentSessionId:h,commandNames:p}),signal:AbortSignal.timeout(15e3)})
|
|
1383
1387
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
1384
1388
|
return d({success:!1,error:"run_failed"}),{content:[{type:"text",text:`tests run failed: action server returned ${e.status}: ${t.slice(0,300)}`}],isError:!0}}const t=await e.json()
|
|
1385
1389
|
if(!t.success||!t.data)return d({success:!1,error:"run_failed"}),{content:[{type:"text",text:"tests run failed: "+(t.error||"unknown error")}],isError:!0}
|
|
1386
|
-
const r=t.data.spawnedSessionIds?.[0],n=
|
|
1387
|
-
return d({success:!0}),{content:[{type:"text",text:`Test run started${n}.\nSpawned ${t.data.agentsSpawned} runner(s) for ${t.data.processCount} process(es). Test runs: ${t.data.testRunIds.join(", ")}.\n\nThe auto-tester is executing the registered commands. You will receive a notification on your next turn when results are reported \u2014 continue with other work in the meantime.`}],...(0,s.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:r,agentType:"auto-tester",requestId:
|
|
1390
|
+
const r=t.data.spawnedSessionIds?.[0],n=p?` (filtered to: ${p.join(", ")})`:""
|
|
1391
|
+
return d({success:!0}),{content:[{type:"text",text:`Test run started${n}.\nSpawned ${t.data.agentsSpawned} runner(s) for ${t.data.processCount} process(es). Test runs: ${t.data.testRunIds.join(", ")}.\n\nThe auto-tester is executing the registered commands. You will receive a notification on your next turn when results are reported \u2014 continue with other work in the meantime.`}],...(0,s.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:r,agentType:"auto-tester",requestId:g,description:p?"Test run: "+p.join(", "):"Test run"})}}catch(e){return d({success:!1,error:"fetch_error"}),{content:[{type:"text",text:"tests run failed: could not reach action server: "+(0,r.getErrorMessage)(e)}],isError:!0}}}if("setup"===e.operation){try{const e=await i.proxyGet(`/api/projects/${n.projectId}/test-processes`),t=e?.data||e||[],r=Array.isArray(t)?t:[]
|
|
1388
1392
|
if(r.length>0)return d({success:!1,error:"already_configured"}),{content:[{type:"text",text:`A test process is already registered for this project (${r.length} configured). Edit it from the Test Processes page in the UI \u2014 \`tests setup\` only bootstraps the first one.`}],isError:!0}}catch(e){a.warn("tests setup: existence check failed; proceeding",{error:(0,r.getErrorMessage)(e)})}const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),c=l?.sessionId,u=c?await e.getSessionRequestId(i,a,c):void 0
|
|
1389
1393
|
try{const e=await fetch((0,o.getActionServerBaseUrl)()+"/api/setup-tests",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:u,parentSessionId:c}),signal:AbortSignal.timeout(15e3)})
|
|
1390
1394
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
@@ -1444,18 +1448,18 @@ t.info("commit_to_viewed_session:parsed",{callId:i,messagePreview:c.slice(0,80),
|
|
|
1444
1448
|
const l=o.sessionIdentity.getIdentity(),d=l?.sessionId,u=l?.serverUrl
|
|
1445
1449
|
if(!d||!u)return t.warn("commit_to_viewed_session: missing session identity",{hasHeraldId:!!d,hasServerUrl:!!u}),{content:[{type:"text",text:"Commit failed: herald session identity unavailable."}],isError:!0}
|
|
1446
1450
|
let h
|
|
1447
|
-
try{h=await r(u,d)}catch(e){return t.warn("commit_to_viewed_session: could not fetch herald messages",{heraldId:d,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:`Commit failed: unable to read herald context (${(0,n.getErrorMessage)(e)}).`}],isError:!0}}const
|
|
1451
|
+
try{h=await r(u,d)}catch(e){return t.warn("commit_to_viewed_session: could not fetch herald messages",{heraldId:d,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:`Commit failed: unable to read herald context (${(0,n.getErrorMessage)(e)}).`}],isError:!0}}const g=function(e){for(let t=e.length-1;t>=0;t--){const r=e[t]
|
|
1448
1452
|
if("user"===r.info?.role)for(const e of r.parts??[]){if("text"!==e.type||!e.text)continue
|
|
1449
1453
|
const t=e.text.match(/<viewed_session\s+id="([^"]+)"\s*\/?>/)
|
|
1450
1454
|
if(t)return t[1]}}return null}(h)
|
|
1451
|
-
if(!
|
|
1452
|
-
let
|
|
1453
|
-
try{
|
|
1454
|
-
if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,
|
|
1455
|
-
|
|
1456
|
-
try{const e=await fetch(`${u}/session/${
|
|
1455
|
+
if(!g)return{content:[{type:"text",text:"Commit failed: no <viewed_session/> tag in herald context. The UI must embed one in each dictation envelope."}],isError:!0}
|
|
1456
|
+
let p
|
|
1457
|
+
try{p=function(e){for(let t=e.length-1;t>=0;t--){const r=e[t]
|
|
1458
|
+
if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,g)),p||t.warn("commit_to_viewed_session: no agent resolvable for viewed session; omitting agent",{viewedId:g})}catch(e){t.warn("commit_to_viewed_session: could not fetch viewed messages; omitting agent",{viewedId:g,error:(0,n.getErrorMessage)(e)})}const m={parts:[{type:"text",text:c,metadata:(0,s.partMeta)("via-herald")}]}
|
|
1459
|
+
p&&(m.agent=p),t.info("commit_to_viewed_session:posting",{callId:i,viewedId:g,heraldId:d,agent:p})
|
|
1460
|
+
try{const e=await fetch(`${u}/session/${g}/prompt_async`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(m),signal:AbortSignal.timeout(1e4)})
|
|
1457
1461
|
if(t.info("commit_to_viewed_session:posted",{callId:i,status:e.status}),!e.ok){const t=await e.text().catch((()=>""))
|
|
1458
|
-
return{content:[{type:"text",text:`Commit failed: prompt_async returned ${e.status}${t?` (${t.slice(0,120)})`:""}.`}],isError:!0}}}catch(e){return t.warn("commit_to_viewed_session:post-failed",{callId:i,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:"Commit failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}return t.info("Translator forwarded message to viewed session",{callId:i,heraldId:d,viewedId:
|
|
1462
|
+
return{content:[{type:"text",text:`Commit failed: prompt_async returned ${e.status}${t?` (${t.slice(0,120)})`:""}.`}],isError:!0}}}catch(e){return t.warn("commit_to_viewed_session:post-failed",{callId:i,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:"Commit failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}return t.info("Translator forwarded message to viewed session",{callId:i,heraldId:d,viewedId:g,agent:p,messageLength:c.length,preview:c.slice(0,120),durationMs:Date.now()-a}),{content:[{type:"text",text:"Committed."}]}}
|
|
1459
1463
|
const n=t(8824),o=t(6688),s=t(2272)},2141(e,exports,t){"use strict"
|
|
1460
1464
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConflictResolver=void 0,exports.createConflictResolver=function(e){return new n(e)}
|
|
1461
1465
|
const r=t(8824)
|
|
@@ -1531,53 +1535,53 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
1531
1535
|
var t={}
|
|
1532
1536
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
1533
1537
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1534
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,r,n,o,s,i,
|
|
1538
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,r,n,o,s,i,p,m){const f=i.child({tool:"move_files"}),y=Date.now()
|
|
1535
1539
|
let w,b,I=l.FileOperationPhase.VALIDATION
|
|
1536
1540
|
const k={toolName:"move-files",operationName:"write",fileOperationPhase:l.FileOperationPhase.FILE_WRITE,recordType:"move-files",metricsPrefix:"move_files",successMessage:"Successfully moved files",failureMessage:"Failed to move files"}
|
|
1537
1541
|
try{const d=e,{operations:u,comment:v}=d,{enforceActiveTask:C}=await Promise.resolve().then(t.bind(t,3451)),_=await C(r,n,i,e.taskId)
|
|
1538
1542
|
if("errorResult"in _)return _.errorResult
|
|
1539
1543
|
const{taskId:E}=_
|
|
1540
1544
|
if(f.info("Moving multiple files and directories",{taskId:E,operationCount:u.length,comment:v}),!u||0===u.length)throw Error("At least one move operation must be specified")
|
|
1541
|
-
l.validateTaskIdFormat(E,f,
|
|
1545
|
+
l.validateTaskIdFormat(E,f,p,k.metricsPrefix)
|
|
1542
1546
|
const S=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1543
1547
|
f.info("Initial branch context",{initialBranch:S.branch,initialRequestId:S.requestId,isMain:S.isMain})
|
|
1544
1548
|
const T=[]
|
|
1545
1549
|
for(const e of u){const{normalizedPath:t,fullPath:n}=l.validateAndNormalizePath(e.source,r),{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(e.destination,r)
|
|
1546
|
-
T.push({source:t,destination:o,fullSource:n,fullDestination:s})}I=l.FileOperationPhase.TASK_VALIDATION,
|
|
1547
|
-
const q=await l.validateTaskId(E,T[0].source,n,f,
|
|
1550
|
+
T.push({source:t,destination:o,fullSource:n,fullDestination:s})}I=l.FileOperationPhase.TASK_VALIDATION,p.incrementCounter("move_files_phase",1,{phase:I})
|
|
1551
|
+
const q=await l.validateTaskId(E,T[0].source,n,f,p,k.metricsPrefix),P=q?.requestId,j=await l.validateWorkItemStates(E,T[0].source,n,s,r,f,p,k.metricsPrefix),R=await l.autoPromoteTaskStatus(E,q.status,P,j.request?.status,T[0].source,n,s,f,p,k.metricsPrefix)
|
|
1548
1552
|
R.taskPromoted&&f.info(`Auto-promoted task ${E} (${q.title||"Untitled"}) to in_progress for file operations`,{taskId:E,taskTitle:q.title,previousStatus:q.status,newStatus:R.newTaskStatus,operationCount:u.length}),R.requestPromoted&&f.info(`Auto-promoted request ${P} to in_progress for file operations`,{requestId:P,previousStatus:j.request?.status,newStatus:R.newRequestStatus,triggeringTaskId:E})
|
|
1549
|
-
const x=await l.ensureCorrectWorkspaceContext({taskPromoted:R.taskPromoted,requestId:P,context:r,operation:"move-files",logger:f,metrics:
|
|
1553
|
+
const x=await l.ensureCorrectWorkspaceContext({taskPromoted:R.taskPromoted,requestId:P,context:r,operation:"move-files",logger:f,metrics:p,metricsPrefix:k.metricsPrefix})
|
|
1550
1554
|
if(!x.success)throw Error(x.error)
|
|
1551
1555
|
let M={hadUserMods:!1,userModsCommitHash:void 0}
|
|
1552
1556
|
if(r.git)try{f.debug("[MOVE-FILES] Checking for user changes before move operations")
|
|
1553
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:P,taskId:E,workspaceManager:r.workspaceManager},f,
|
|
1554
|
-
e.userChangesCommitted&&(f.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),f.info("User changes committed before move-files operation",{taskId:E,moveOperationsCount:T.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),M={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){f.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),f.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:E,moveOperationsCount:T.length,error:e instanceof Error?e.message:e+""})}f.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:T.length}),I=l.FileOperationPhase.RECORD_CREATION,
|
|
1555
|
-
const{toolRecordId:O,localToolRecordId:$}=await l.createFileOperationRecords(E,P,r.projectId,k.recordType,T[0].source,{operationCount:u.length,operations:T.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},n,o,f,
|
|
1556
|
-
w=O,b=O,I=k.fileOperationPhase,
|
|
1557
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:P,taskId:E,workspaceManager:r.workspaceManager},f,p)
|
|
1558
|
+
e.userChangesCommitted&&(f.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),f.info("User changes committed before move-files operation",{taskId:E,moveOperationsCount:T.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),M={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){f.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),f.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:E,moveOperationsCount:T.length,error:e instanceof Error?e.message:e+""})}f.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:T.length}),I=l.FileOperationPhase.RECORD_CREATION,p.incrementCounter("move_files_phase",1,{phase:I})
|
|
1559
|
+
const{toolRecordId:O,localToolRecordId:$}=await l.createFileOperationRecords(E,P,r.projectId,k.recordType,T[0].source,{operationCount:u.length,operations:T.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},n,o,f,p,k.metricsPrefix,m)
|
|
1560
|
+
w=O,b=O,I=k.fileOperationPhase,p.incrementCounter("move_files_phase",1,{phase:I})
|
|
1557
1561
|
const D=[]
|
|
1558
1562
|
let A=0
|
|
1559
1563
|
for(const e of T){const t={operation:{source:e.source,destination:e.destination},success:!1}
|
|
1560
1564
|
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()
|
|
1561
1565
|
t.isDirectory=r
|
|
1562
1566
|
const n=c.default.dirname(e.fullDestination)
|
|
1563
|
-
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,A++,f.info("Successfully moved "+(r?"directory":"file"),{source:e.source,destination:e.destination,isDirectory:r})}catch(r){t.error=(0,
|
|
1564
|
-
|
|
1567
|
+
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,A++,f.info("Successfully moved "+(r?"directory":"file"),{source:e.source,destination:e.destination,isDirectory:r})}catch(r){t.error=(0,g.getErrorMessage)(r),f.warn(`Failed to move ${e.source} to ${e.destination}`,{error:t.error})}D.push(t)}const F=Date.now()-y
|
|
1568
|
+
p.recordValue("move_files_time",F),p.incrementCounter("move_files_operations_total",u.length),p.incrementCounter("move_files_operations_success",A),p.incrementCounter("move_files_operations_failed",u.length-A),A===u.length?p.incrementCounter("move_files_success",1):A>0?p.incrementCounter("move_files_partial_success",1):p.incrementCounter("move_files_total_failure",1)
|
|
1565
1569
|
let N=null
|
|
1566
|
-
if(A>0){I=l.FileOperationPhase.GIT_COMMIT,
|
|
1570
|
+
if(A>0){I=l.FileOperationPhase.GIT_COMMIT,p.incrementCounter("move_files_phase",1,{phase:I})
|
|
1567
1571
|
const e=D.filter((e=>e.success)),t=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}`
|
|
1568
|
-
N=await l.commitToGit(E,T[0].destination,O,$,t,r,f,
|
|
1572
|
+
N=await l.commitToGit(E,T[0].destination,O,$,t,r,f,p,k.metricsPrefix)}I=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,p.incrementCounter("move_files_phase",1,{phase:I})
|
|
1569
1573
|
const z=D.filter((e=>e.success)),L=D.filter((e=>!e.success))
|
|
1570
|
-
await l.updateFileOperationRecords(E,w,b,T[0].source,k.recordType,A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,{status:A===u.length?"completed":"partial_success",commitHash:N?.commitHash,previousCommitHash:N?.previousCommitHash,operationCount:u.length,successCount:A,failureCount:u.length-A,successfulOperations:z.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:L.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,n,o,f,
|
|
1574
|
+
await l.updateFileOperationRecords(E,w,b,T[0].source,k.recordType,A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,{status:A===u.length?"completed":"partial_success",commitHash:N?.commitHash,previousCommitHash:N?.previousCommitHash,operationCount:u.length,successCount:A,failureCount:u.length-A,successfulOperations:z.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:L.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,n,o,f,p,k.metricsPrefix)
|
|
1571
1575
|
const H=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1572
1576
|
let B=""
|
|
1573
1577
|
if(A===u.length)B=`Successfully moved all ${u.length} ${1===u.length?"item":"items"}`
|
|
1574
1578
|
else if(A>0){const e=D.filter((e=>!e.success))
|
|
1575
1579
|
B=`Successfully moved ${A}/${u.length} items.\n\nFailed operations:\n`+e.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")}else B="All move operations failed:\n"+D.map((e=>`\u2022 ${e.operation.source} \u2192 ${e.operation.destination}: ${e.error}`)).join("\n")
|
|
1576
1580
|
return N?.commitHash&&(B+="\nCommit: "+N.commitHash.substring(0,8)),H.requestId&&(B+="\nBranch: "+H.requestId),{content:[{type:"text",text:B}],isError:0===A}}catch(t){if(e.taskId&&o)try{const n=t instanceof d.NotFoundError||t instanceof d.ValidationError||t instanceof u.ZodError
|
|
1577
|
-
await o.createToolRecord({...n?{}:{taskId:e.taskId},projectId:r.projectId,type:"move-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment,error:(0,
|
|
1578
|
-
if(
|
|
1579
|
-
try{await l.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",k.recordType,"Failed to move files",{status:"failed",error:(0,
|
|
1580
|
-
const a=i(t(1943)),c=i(t(6928)),l=s(t(5967)),d=t(9860),u=t(1569),h=t(7478),
|
|
1581
|
+
await o.createToolRecord({...n?{}:{taskId:e.taskId},projectId:r.projectId,type:"move-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment,error:(0,g.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:I,attemptedTaskId:e.taskId,taskIdValidationFailed:n},note:"Failed to move files - "+(0,g.getErrorMessage)(t)})}catch(t){f.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
|
|
1582
|
+
if(p.recordValue("move_files_time",s),p.incrementCounter("move_files_errors",1),f.error("Error in move-files operation:",{error:(0,g.getErrorMessage)(t),time:s}),(w||b)&&e.taskId){I=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
1583
|
+
try{await l.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",k.recordType,"Failed to move files",{status:"failed",error:(0,g.getErrorMessage)(t),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",n,o,f,p,k.metricsPrefix)}catch(t){f.error("Failed to update record with failure status",{taskId:e.taskId,recordId:w,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(t,I,f,p,e,k)}}
|
|
1584
|
+
const a=i(t(1943)),c=i(t(6928)),l=s(t(5967)),d=t(9860),u=t(1569),h=t(7478),g=t(8824)},2422(module){"use strict"
|
|
1581
1585
|
module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){"use strict"
|
|
1582
1586
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1583
1587
|
const r=t(6183),n=t(3707)
|
|
@@ -1585,7 +1589,7 @@ exports.def={name:"quick_manage",description:"WHEN TO USE: trivial single-file e
|
|
|
1585
1589
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildTaskEndpoint=function(e,t,r){const n=r?"/"+r.replace(/^\//,""):""
|
|
1586
1590
|
return`/api/projects/${e}/tasks/${encodeURIComponent(t)}${n}`}},2462(e,exports,t){"use strict"
|
|
1587
1591
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
1588
|
-
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),
|
|
1592
|
+
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),m=t(260),f=t(2283),y=t(4165),w=t(7834),b=t(9373),I=t(6111),k=t(700),v=t(1535),C=t(7257),_=t(9230),E=t(4150),S=t(6473),T=t(6309),q=t(4921),P=t(8850),j=t(3556),R=t(1391),x=t(6315),M=t(7713),O=t(6252),$=t(213),D=t(7250),A=t(2425),F=t(1540),N=t(5767),z=t(4973),L=t(509),H=t(7613),B=t(8456),U=t(3322),G=t(5247),W=t(8849),V=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)(m.def),(0,r.registerTool)(f.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)(E.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(q.def),(0,r.registerTool)(P.def),(0,r.registerTool)(j.def),(0,r.registerTool)(R.def),(0,r.registerTool)(x.def),(0,r.registerTool)(M.def),(0,r.registerTool)(O.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(z.def),(0,r.registerTool)(L.def),(0,r.registerTool)(H.def),(0,r.registerTool)(B.def),(0,r.registerTools)(U.metaDefs),(0,r.registerTools)(G.testingDefs),(0,r.registerTools)(W.checkingDefs),(0,r.registerTools)(V.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
|
|
1589
1593
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.requestConfig=void 0,exports.areTestsRequiredForCompletion=function(){return exports.requestConfig.requireTestsForCompletion},exports.setTestsRequiredForCompletion=function(e){exports.requestConfig.requireTestsForCompletion=e},exports.getCompletionMode=function(e){return e&&["auto-merge","auto-test-then-merge","manual-review"].includes(e)?e:"auto-merge"},exports.getApprovalMode=function(e){return e&&["none","require-approval"].includes(e)?e:"none"},exports.requestConfig={requireTestsForCompletion:!1}},2537(e,exports,t){"use strict"
|
|
1590
1594
|
async function r(e,t,r){if(v.has(r)&&C>=t){if(0===t)return 0
|
|
1591
1595
|
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]"
|
|
@@ -1609,12 +1613,12 @@ case"size":s||"number"!=typeof o.size||(l+=` (${function(e){if(0===e)return"0 by
|
|
|
1609
1613
|
let t=e,r=0
|
|
1610
1614
|
for(;t>=1024&&4>r;)t/=1024,r++
|
|
1611
1615
|
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[]
|
|
1612
|
-
try{const{fullPath:d}=b.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),
|
|
1613
|
-
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=b.validateAndNormalizePath(u,t),
|
|
1616
|
+
try{const{fullPath:d}=b.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),g=[]
|
|
1617
|
+
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=b.validateAndNormalizePath(u,t),p=await y.default.stat(h),m=d.isFile()?w.default.extname(d.name).toLowerCase():""
|
|
1614
1618
|
let f
|
|
1615
|
-
d.isFile()&&(f=await r(h,
|
|
1616
|
-
const I={name:d.name,isDirectory:d.isDirectory(),depth:n,size:
|
|
1617
|
-
d.isDirectory()&&(s-1>n?(I.children=await o(u,t,n+1,s,i,l),I.children&&I.children.length>0&&(I.subtreeTotals=c(I.children))):I.subtreeTotals=await a(u,t,l)),
|
|
1619
|
+
d.isFile()&&(f=await r(h,p.size,m))
|
|
1620
|
+
const I={name:d.name,isDirectory:d.isDirectory(),depth:n,size:p.size,modified:p.mtime,extension:m,lineCount:f}
|
|
1621
|
+
d.isDirectory()&&(s-1>n?(I.children=await o(u,t,n+1,s,i,l),I.children&&I.children.length>0&&(I.subtreeTotals=c(I.children))):I.subtreeTotals=await a(u,t,l)),g.push(I)}catch(e){l.debug("Excluding entry from tree: "+d.name,{reason:(0,k.getErrorMessage)(e)})}return u(g,i)}catch(t){return l.debug(`Failed to build tree for ${e}:`,{error:(0,k.getErrorMessage)(t)}),[]}}function s(e,t="name",r=""){if(0===e.length)return""
|
|
1618
1622
|
const o=[]
|
|
1619
1623
|
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?"/":""
|
|
1620
1624
|
if(o.push(`${r}${l}${d}${u}`),i.children&&i.children.length>0){const e=r+(c?" ":"\u2502 "),n=s(i.children,t,e)
|
|
@@ -1637,21 +1641,21 @@ case"size":const t=e.size||0,n=r.size||0
|
|
|
1637
1641
|
return t!==n?n-t:e.name.localeCompare(r.name)
|
|
1638
1642
|
case"type":const o=e.extension||"",s=r.extension||""
|
|
1639
1643
|
return o!==s?o.localeCompare(s):e.name.localeCompare(r.name)
|
|
1640
|
-
default:return e.name.localeCompare(r.name)}}))}var h,
|
|
1644
|
+
default:return e.name.localeCompare(r.name)}}))}var h,g=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1641
1645
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1642
|
-
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]}),
|
|
1646
|
+
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),p=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),m=this&&this.__importStar||(h=function(e){return h=Object.getOwnPropertyNames||function(e){var t=[]
|
|
1643
1647
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
1644
1648
|
return t},h(e)},function(e){if(e&&e.__esModule)return e
|
|
1645
1649
|
var t={}
|
|
1646
|
-
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&
|
|
1647
|
-
return
|
|
1650
|
+
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&g(t,e,r[n])
|
|
1651
|
+
return p(t,e),t}),f=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1648
1652
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
|
|
1649
|
-
let
|
|
1653
|
+
let g=b.FileOperationPhase.VALIDATION
|
|
1650
1654
|
b.FileOperationPhase.FILE_WRITE
|
|
1651
|
-
try{const
|
|
1655
|
+
try{const p=e,{path:m,levels:f=1,sortBy:I="name"}=p
|
|
1652
1656
|
i.info("Listing directory: "+m)
|
|
1653
1657
|
const{normalizedPath:v,fullPath:C}=b.validateAndNormalizePath(m,t)
|
|
1654
|
-
|
|
1658
|
+
g=b.FileOperationPhase.FILE_WRITE
|
|
1655
1659
|
try{if(!(await y.default.stat(C)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+m}],isError:!0}
|
|
1656
1660
|
await y.default.access(C,y.default.constants.R_OK)}catch(e){return e instanceof Error&&"ENOENT"===e.code?{content:[{type:"text",text:"Directory does not exist: "+m}],isError:!0}:e instanceof Error&&"EACCES"===e.code?{content:[{type:"text",text:"Directory not accessible: "+m}],isError:!0}:{content:[{type:"text",text:"Cannot access directory: "+m}],isError:!0}}let _,E
|
|
1657
1661
|
if(f>1){i.info(`Building tree structure for: ${v} (levels: ${f}, sortBy: ${I})`)
|
|
@@ -1777,40 +1781,40 @@ return(0,n.safeGetResponseData)(i,[],this.logger)}async expirePendingQuestions()
|
|
|
1777
1781
|
this.logger.info("Expiring pending questions")
|
|
1778
1782
|
const t=await this.requestWithRetry("POST",`/api/projects/${e}/session-messages/expire`,{})
|
|
1779
1783
|
return(0,n.safeGetResponseData)(t,{expiredCount:0},this.logger).expiredCount}}exports.SessionMessageClient=o},2736(e,exports,t){"use strict"
|
|
1780
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,l,d,u,h){const
|
|
1781
|
-
|
|
1782
|
-
const
|
|
1784
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,l,d,u,h){const g=u.child({tool:"complete_task"})
|
|
1785
|
+
g.info("Completing task",{args:e})
|
|
1786
|
+
const p=h.startTimer("tool_handler_duration")
|
|
1783
1787
|
try{const o=function(e){try{return e}catch(e){if(e instanceof i.ZodError&&e.errors.length>0)throw new r.ValidationError(e.errors[0].message)
|
|
1784
1788
|
throw new r.ValidationError("Invalid input: "+(0,a.getErrorMessage)(e))}}(e)
|
|
1785
1789
|
let u=o.taskId
|
|
1786
|
-
const m=o.summary;(0,c.isTaskRef)(u)&&(u=await(0,c.resolveTaskRef)(u,d,
|
|
1790
|
+
const m=o.summary;(0,c.isTaskRef)(u)&&(u=await(0,c.resolveTaskRef)(u,d,g))
|
|
1787
1791
|
const f=l.projectId
|
|
1788
1792
|
if(!f)throw new r.ValidationError("Project ID is required for completing tasks with the new API structure")
|
|
1789
1793
|
h.incrementCounter("complete_task_attempts",1,{taskId:u}),d.setProjectId(f)
|
|
1790
1794
|
const y=d.getTaskClient()
|
|
1791
1795
|
let w
|
|
1792
1796
|
try{const e=await y.getTask(u)
|
|
1793
|
-
|
|
1794
|
-
const t=(0,s.extractDataFromResponse)(e,{logger:
|
|
1795
|
-
w="data"in t?t.data:t,
|
|
1797
|
+
g.info("Raw task response data",{responseData:JSON.stringify(e)}),g.debug("Task response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
|
|
1798
|
+
const t=(0,s.extractDataFromResponse)(e,{logger:g,operationName:"getTask",throwOnNoData:!0})
|
|
1799
|
+
w="data"in t?t.data:t,g.info("Current task status: "+w.status,{taskId:u,currentStatus:w.status})}catch(e){if(e instanceof r.ValidationError)throw e
|
|
1796
1800
|
throw new r.NotFoundError(`Task ${(0,c.formatTaskRefForAgent)(u)} not found in project ${f}. Please provide a valid task ID.`,{taskId:u,projectId:f,originalError:e})}if("completed"===w.status){const e="Task is already completed."
|
|
1797
|
-
throw
|
|
1798
|
-
throw
|
|
1801
|
+
throw g.warn(e,{taskId:u,currentStatus:w.status}),new r.ValidationError(e)}if("canceled"===w.status){const e="Task is canceled and can not be completed."
|
|
1802
|
+
throw g.warn(e,{taskId:u,currentStatus:w.status}),new r.ValidationError(e)}let b=l.git
|
|
1799
1803
|
if(l.workspaceManager){const e=l.workspaceManager.getCurrentContext(l.currentSessionId)
|
|
1800
1804
|
if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
|
|
1801
|
-
b=simpleGit({baseDir:e.basePath,binary:l.gitBinary}),
|
|
1802
|
-
if(b)try{(await b.status()).isClean()||(I=(await b.commit(`Complete task ${u}: ${m}`)).commit,
|
|
1805
|
+
b=simpleGit({baseDir:e.basePath,binary:l.gitBinary}),g.debug("Using workspace-aware git instance for task completion",{taskId:u,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let I=null
|
|
1806
|
+
if(b)try{(await b.status()).isClean()||(I=(await b.commit(`Complete task ${u}: ${m}`)).commit,g.info("Created commit for task completion",{taskId:u,commitId:I}))}catch(e){g.warn("Failed to commit changes",{error:(0,a.getErrorMessage)(e)})}let k=null
|
|
1803
1807
|
try{const e=d.getToolRecordClient()
|
|
1804
|
-
e&&(k={id:(await e.createToolRecord({taskId:u,requestId:w.requestId,projectId:f,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:m,lastCommit:I,completedAt:(new Date).toISOString()},note:`Completed task: ${m.substring(0,100)}${m.length>100?"...":""}`})).id})}catch(e){
|
|
1805
|
-
|
|
1808
|
+
e&&(k={id:(await e.createToolRecord({taskId:u,requestId:w.requestId,projectId:f,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:m,lastCommit:I,completedAt:(new Date).toISOString()},note:`Completed task: ${m.substring(0,100)}${m.length>100?"...":""}`})).id})}catch(e){g.error("Failed to create tool record for task completion, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:u,requestId:w.requestId})}try{const e=w.metadata||{},t=(new Date).toISOString(),r={status:"completed",metadata:{...e,lastCommit:I,completionSummary:m,completionRecordId:k?.id,completedAt:t}},o=await y.updateTask(u,r)
|
|
1809
|
+
g.info("Raw task update response data",{responseData:JSON.stringify(o)}),g.debug("Task update response structure",{type:typeof o,isArray:Array.isArray(o),hasData:null!=o,properties:o?Object.keys(o):[],dataPreview:o?JSON.stringify(o).substring(0,200)+"...":"null"}),(0,s.extractDataFromResponse)(o,{logger:g,operationName:"updateTask",defaultValue:{id:u,status:"completed"}}),g.info("Successfully completed task",{taskId:u,recordId:k?.id})
|
|
1806
1810
|
const i=w.requestId,l=w.requestId
|
|
1807
1811
|
let d=`Task ${w.sequenceNumber&&l?(0,c.formatTaskRef)(l,w.sequenceNumber):u} (${w.title}) has been marked as completed.`
|
|
1808
1812
|
if(I&&(d+="\nCommit: "+I.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
|
|
1809
|
-
|
|
1810
|
-
const t=(0,s.extractArrayFromResponse)(e,{logger:
|
|
1811
|
-
|
|
1813
|
+
g.info("Raw tasks list response data",{responseData:JSON.stringify(e)}),g.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"})
|
|
1814
|
+
const t=(0,s.extractArrayFromResponse)(e,{logger:g,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
|
|
1815
|
+
g.info("Task progress check",{requestId:i,totalTasks:r,completedTasks:n}),d+=`\n\nTask Progress: ${n}/${r} tasks completed`,n===r&&(d+=`\n\nAll tasks for request ${i} are now completed! You may consider marking the request as completed using the complete-request tool.`)}catch(e){g.warn("Failed to check task progress",{error:(0,a.getErrorMessage)(e),requestId:i})}return p({success:!0}),{content:[{type:"text",text:d}],...(0,n.alchemyMeta)({kind:"complete-task",toolRecordId:k?.id})}}catch(e){throw g.error("Failed to complete task",{error:e instanceof Error?e.stack:e+"",taskId:u}),Error("Failed to complete task: "+(0,a.getErrorMessage)(e))}}catch(t){if(g.error("Failed to complete task",{error:t instanceof Error?t.stack:t+"",args:e}),l.projectId)try{const n=d.getToolRecordClient()
|
|
1812
1816
|
if(n){const o=t instanceof r.NotFoundError||t instanceof r.ValidationError||t instanceof i.ZodError
|
|
1813
|
-
await n.createToolRecord({...o?{}:{taskId:e.taskId},projectId:l.projectId,type:"complete-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.summary?.substring(0,100)+(e.summary?.length>100?"...":""),error:(0,a.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",attemptedTaskId:e.taskId,taskIdValidationFailed:o},note:"Failed to complete task "+e.taskId})}}catch(e){
|
|
1817
|
+
await n.createToolRecord({...o?{}:{taskId:e.taskId},projectId:l.projectId,type:"complete-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.summary?.substring(0,100)+(e.summary?.length>100?"...":""),error:(0,a.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",attemptedTaskId:e.taskId,taskIdValidationFailed:o},note:"Failed to complete task "+e.taskId})}}catch(e){g.error("Failed to create failure record for task completion",{error:e instanceof Error?e.message:e+""})}p({success:!1,error:t instanceof Error?t.name:"unknown"})
|
|
1814
1818
|
let n=(0,a.getErrorMessage)(t)
|
|
1815
1819
|
return t instanceof r.NotFoundError&&(n=`The task ID "${e.taskId}" was not found. Please provide a valid task ID.`),t instanceof o.ConnectionError&&(n="Unable to complete task: Connection to the server failed. Please check your network connection and try again."),t instanceof i.ZodError&&t.errors.length>0&&(n=t.errors[0].message),{content:[{type:"text",text:"Error: "+n}],isError:!0}}}
|
|
1816
1820
|
const r=t(9860),n=t(2272),o=t(5674),s=t(2960),i=t(1569),a=t(8824),c=t(4466)},2782(e,exports,t){"use strict"
|
|
@@ -1819,19 +1823,19 @@ if(!r())return t.level=(0,l.isDevBuild)()?c.LogLevel.INFO:c.LogLevel.ERROR,t.log
|
|
|
1819
1823
|
if("true"===process.env.DEBUG_LOGGING?.toLowerCase()){t.level=c.LogLevel.DEBUG,t.logToFile=!0
|
|
1820
1824
|
const r=e||process.cwd()
|
|
1821
1825
|
t.logFilePath=i.default.join(r,"logs","debug.log")}const n=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
1822
|
-
return n&&Object.values(c.LogLevel).includes(n)&&(t.level=n),t}(e.baseDir),...e},{level:o=c.LogLevel.INFO,serviceName:
|
|
1823
|
-
if(console&&f.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),
|
|
1826
|
+
return n&&Object.values(c.LogLevel).includes(n)&&(t.level=n),t}(e.baseDir),...e},{level:o=c.LogLevel.INFO,serviceName:g="mcp-service",logToFile:p=!1,logFilePath:m="./logs/app.log",console=!0}=t,f=[]
|
|
1827
|
+
if(console&&f.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),p){!function(e){const t=i.default.dirname(e)
|
|
1824
1828
|
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(m)
|
|
1825
1829
|
const e=o===c.LogLevel.DEBUG&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()
|
|
1826
|
-
f.push(new s.default.transports.File({filename:m,format:e?h:u}))}const y=s.default.createLogger({level:o,defaultMeta:{service:
|
|
1827
|
-
return o===c.LogLevel.DEBUG&&
|
|
1828
|
-
return{error(e,t){r.error(e,t)},warn(e,t){r.warn(e,t)},info(e,t){r.info(e,t)},debug(e,t){r.debug(e,t)},child(e){return n({...t,serviceName:`${
|
|
1830
|
+
f.push(new s.default.transports.File({filename:m,format:e?h:u}))}const y=s.default.createLogger({level:o,defaultMeta:{service:g},transports:f})
|
|
1831
|
+
return o===c.LogLevel.DEBUG&&p&&r()&&y.info("Enhanced logging initialized",{level:o,serviceName:g,logToFile:p,logFilePath:m,debugLogging:process.env.DEBUG_LOGGING}),{error(e,t){y.error(e,t)},warn(e,t){y.warn(e,t)},info(e,t){y.info(e,t)},debug(e,t){y.debug(e,t)},child(e){const r=y.child(e)
|
|
1832
|
+
return{error(e,t){r.error(e,t)},warn(e,t){r.warn(e,t)},info(e,t){r.info(e,t)},debug(e,t){r.debug(e,t)},child(e){return n({...t,serviceName:`${g}:${e.component||"nested"}`})}}}}}var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1829
1833
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.createLogger=n,exports.createEnvLogger=function(e={}){return n(e)},exports.isDebugToolsEnabled=r,exports.isDebugLoggingEnabled=function(){return!!r()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()},exports.getDebugLevelFromEnv=function(){if(!r())return c.LogLevel.INFO
|
|
1830
1834
|
const e=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
1831
1835
|
return e&&Object.values(c.LogLevel).includes(e)?e:c.LogLevel.INFO}
|
|
1832
1836
|
const s=o(t(5124)),i=o(t(6928)),a=o(t(9896)),c=t(6540),l=t(7960),d=s.default.format.combine(s.default.format.timestamp(),s.default.format.colorize(),s.default.format.printf((({level:e,message:t,timestamp:r,...n})=>`${r} [${e}]: ${t}${Object.keys(n).length?" "+JSON.stringify(n,null,0):""}`))),u=s.default.format.combine(s.default.format.timestamp(),s.default.format.json()),h=s.default.format.combine(s.default.format.timestamp(),s.default.format.printf((({level:e,message:t,timestamp:r,service:n,component:o,...s})=>{const i=n?`[${n}]`:"",a=o?`[${o}]`:"",c=Object.keys(s).length?" "+JSON.stringify(s,null,2):""
|
|
1833
|
-
return`${r} ${i}${a} [${e.toUpperCase()}]: ${t}${c}`}))),
|
|
1834
|
-
exports.default=
|
|
1837
|
+
return`${r} ${i}${a} [${e.toUpperCase()}]: ${t}${c}`}))),g=n({logToFile:!1,console:!0,level:c.LogLevel.INFO})
|
|
1838
|
+
exports.default=g},2903(e,exports,t){"use strict"
|
|
1835
1839
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1836
1840
|
const r=t(6183),n=t(9442)
|
|
1837
1841
|
exports.def={name:"replace_in_files",description:'Replace text in multiple files/documents with progressive fuzzy matching in batch operations.\n\nAPI:\n\u2022 operations (required) - Array of file operations\n - path or documentId (required per operation) - Target file or document\n - replacements (required) - Array of {old, new, match_mode?} replacements\n - fuzzy_match (optional) - Override global fuzzy setting for this file\n\u2022 fuzzy_match (optional, default true) - Global fuzzy matching default\n\u2022 comment (required) - Description of changes\n\nSTRUCTURE: Each operation MUST contain a `replacements` array. Do NOT put old/new directly on the operation object.\n\nFUZZY MATCHING (progressive strategies):\n1. exact - Literal match\n2. whitespace_normalized - Collapse/trim whitespace\n3. whitespace_agnostic - Ignore all whitespace\n\nMATCH MODES (per replacement):\n\u2022 \'unique\' (default, safe) - Must find exactly 1 match. Fails with helpful candidates if multiple found.\n\u2022 \'all\' - Replaces all occurrences, returns details for each\n\nRETURNS:\nPer-operation, per-replacement results with line numbers, match types, and success/error details.\n\nEXAMPLES:\n- Single file: {"operations": [{"path": "file.ts", "replacements": [{"old": "oldAPI", "new": "newAPI"}]}], "comment": "Update API"}\n- Multi-file: {"operations": [{"path": "a.ts", "replacements": [...]}, {"path": "b.ts", "replacements": [...]}], "comment": "Refactor"}',schema:r.ReplaceInFilesSchema,annotations:{title:"Replace In Files (Fuzzy Batch)",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},createsRecords:!0,handler(e,t){return(0,n.handleReplaceInFiles)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},2960(e,exports){"use strict"
|
|
@@ -1882,17 +1886,17 @@ i.info("Request breakdown",{fileRequests:d.length,documentRequests:u.length})
|
|
|
1882
1886
|
const h=[]
|
|
1883
1887
|
for(const e of d)h.push(r(e,t,0,l))
|
|
1884
1888
|
for(const e of u)h.push(n(e,t,0,l))
|
|
1885
|
-
const
|
|
1889
|
+
const p=await Promise.all(h)
|
|
1886
1890
|
let m=""
|
|
1887
1891
|
if(t.workspaceManager)try{const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
1888
|
-
e.branchName&&!e.permanentBranch&&(m=`**Current Branch:** ${e.branchName}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const f=
|
|
1892
|
+
e.branchName&&!e.permanentBranch&&(m=`**Current Branch:** ${e.branchName}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const f=p.filter((e=>e.success)).length,y=p.filter((e=>!e.success)).length,w=p.length
|
|
1889
1893
|
let b="## Read Files/Documents\n\n"
|
|
1890
1894
|
m&&(b+=m),b+=`**Total Requests:** ${w} - **Successful:** ${f} - **Failed:** ${y}\n\n`
|
|
1891
|
-
for(let e=0;e<
|
|
1895
|
+
for(let e=0;e<p.length;e++){const t=p[e]
|
|
1892
1896
|
"file"===t.type?b+=`File ${e+1}: ${t.path}\n`:(b+=`Document ${e+1}: ${t.documentId}`,t.filename&&(b+=` (${t.filename})`),b+="\n"),t.success?(b+="**Status:** Success\n",t.lineCount&&t.totalLines&&(b+=`Lines Read / Total Lines ${t.lineCount} / ${t.totalLines}\n`),t.originalRequest?.lines&&t.totalLines&&(b+=`**Lines:** ${t.originalRequest.lines}\n`),b+=`\n**Content:**\n\`\`\`\n${t.content}\n\`\`\`\n`):(b+="**Status:** Failed\n",b+=`**Error:** ${t.error}\n`),b+="\n"}const I=0===y
|
|
1893
|
-
return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:w,successfulReads:f,failedReads:y,success:I}),s.incrementCounter("read_files_total",1,{success:I}),{content:[{type:"text",text:b}],...(0,
|
|
1897
|
+
return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:w,successfulReads:f,failedReads:y,success:I}),s.incrementCounter("read_files_total",1,{success:I}),{content:[{type:"text",text:b}],...(0,g.alchemyMeta)({kind:"read-files"}),isError:!I}}catch(e){const t=Date.now()-a
|
|
1894
1898
|
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,h.getErrorMessage)(e)}],isError:!0}}}
|
|
1895
|
-
const l=c(t(1943)),d=a(t(5967)),u=t(9470),h=t(8824),
|
|
1899
|
+
const l=c(t(1943)),d=a(t(5967)),u=t(9470),h=t(8824),g=t(2272)},2968(e,exports,t){"use strict"
|
|
1896
1900
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.TaskClient=void 0
|
|
1897
1901
|
const r=t(8824),n=t(7645),o=t(2161),s=t(2450)
|
|
1898
1902
|
class i extends n.ConnectionAwareClient{async createTask(e){if(this.logger.debug("Creating task",{taskInput:e}),!e.projectId){const t=this.projectClient.getProjectId()
|
|
@@ -1970,9 +1974,9 @@ throw c.error(`STRICT VALIDATION - File operation blocked on ${u.status} request
|
|
|
1970
1974
|
const n=(0,s.getErrorMessage)(r)
|
|
1971
1975
|
c.warn("Could not validate request status for "+a.requestId,{taskId:e,requestId:a.requestId,error:n,path:t}),l.incrementCounter(d+"_request_validation_warning",1)}return c.info("Work item state validation passed",{taskId:e,taskStatus:a.status,requestId:a.requestId,requestStatus:u?.status,path:t}),a.requestId&&(c.debug("Worktrees handle branch isolation, skipping branch switching",{taskId:e,requestId:a.requestId}),h={switched:!1,message:"Branch switching skipped (using worktrees)"}),l.incrementCounter(d+"_state_validation_success",1),{task:a,request:u,branchSwitch:h}}catch(r){if(r instanceof o.ValidationError)throw r
|
|
1972
1976
|
const n=(0,s.getErrorMessage)(r)
|
|
1973
|
-
throw c.error("Could not validate work item states for task "+e,{taskId:e,path:t,error:n}),l.incrementCounter(d+"_state_validation_error",1),new o.ValidationError("Could not validate work item states: "+n,{taskId:e,path:t,originalError:r})}},exports.autoPromoteTaskStatus=async function(e,t,r,o,i,a,c,l,d,u){try{let s,h,
|
|
1974
|
-
if("pending"===t&&(l.info(`Auto-promoting task ${e} from pending to in_progress`,{taskId:e,currentStatus:t,path:i}),await a.updateTaskStatus(e,"in_progress"),l.info(`Successfully auto-promoted task ${e} to in_progress`,{taskId:e,previousStatus:t,newStatus:"in_progress",path:i}),d.incrementCounter(u+"_auto_promotion_success",1),
|
|
1975
|
-
|
|
1977
|
+
throw c.error("Could not validate work item states for task "+e,{taskId:e,path:t,error:n}),l.incrementCounter(d+"_state_validation_error",1),new o.ValidationError("Could not validate work item states: "+n,{taskId:e,path:t,originalError:r})}},exports.autoPromoteTaskStatus=async function(e,t,r,o,i,a,c,l,d,u){try{let s,h,g=!1,p=!1
|
|
1978
|
+
if("pending"===t&&(l.info(`Auto-promoting task ${e} from pending to in_progress`,{taskId:e,currentStatus:t,path:i}),await a.updateTaskStatus(e,"in_progress"),l.info(`Successfully auto-promoted task ${e} to in_progress`,{taskId:e,previousStatus:t,newStatus:"in_progress",path:i}),d.incrementCounter(u+"_auto_promotion_success",1),g=!0,s="in_progress",r&&o)){const t=await n(r,o,e,"in_progress",c,l,d,u)
|
|
1979
|
+
p=t.promoted,h=t.newStatus}return{taskPromoted:g,newTaskStatus:s,requestPromoted:p,newRequestStatus:h}}catch(r){const n=(0,s.getErrorMessage)(r)
|
|
1976
1980
|
return l.warn(`Failed to auto-promote task ${e} from pending to in_progress`,{taskId:e,currentStatus:t,error:n,path:i}),d.incrementCounter(u+"_auto_promotion_failure",1),{taskPromoted:!1,requestPromoted:!1}}},exports.autoPromoteRequestStatus=n,exports.validateRequestCompletionEligibility=async function(e,t,r,n,i){try{const s=await t.listTasks({requestId:e})
|
|
1977
1981
|
if(r.info("Validating request completion eligibility for "+e,{requestId:e,totalTasks:s.length}),0===s.length){r.warn(`Request ${e} has no tasks - cannot be completed`,{requestId:e})
|
|
1978
1982
|
const t=`Cannot complete request ${e} - no tasks found. Create tasks for this request before attempting completion.`
|
|
@@ -1999,7 +2003,7 @@ l.info("Generating journal for request",{requestId:a})
|
|
|
1999
2003
|
const u=t.projectId
|
|
2000
2004
|
if(!u)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
|
|
2001
2005
|
o.setProjectId(u),l.info("Fetching request data, tasks, and file history in parallel")
|
|
2002
|
-
const h=o.getRequestClient(),
|
|
2006
|
+
const h=o.getRequestClient(),g=o.getTaskClient(),p=o.getToolRecordClient(),[m,f,y]=await Promise.all([h.getRequest(a),g.listTasks({requestId:a}),p.getToolRecordsByRequestId(a).catch((e=>(l.warn("Failed to fetch tool records",{error:e+""}),[])))]),w=(0,s.extractDataFromResponse)(m,{logger:l,operationName:"getRequest",throwOnNoData:!0}),b="data"in w?w.data:w,I={id:b.id||a,title:b.title||"Unknown Request",description:b.description||"No description available",status:b.status||"unknown",type:b.type||"unknown",acceptanceCriteria:b.acceptanceCriteria||[],createdAt:b.createdAt||(new Date).toISOString(),updatedAt:b.updatedAt||(new Date).toISOString(),completedAt:b.completedAt},k=(0,s.extractDataFromResponse)(f,{logger:l,operationName:"listTasks",throwOnNoData:!1}),v=(Array.isArray(k)?k:"data"in k?k.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})))
|
|
2003
2007
|
l.info(`Fetched request, ${v.length} tasks, ${y.length} tool records`)
|
|
2004
2008
|
const C=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()))
|
|
2005
2009
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
@@ -2027,7 +2031,7 @@ var o=Object.getOwnPropertyDescriptor(t,r)
|
|
|
2027
2031
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),n=this&&this.__exportStar||function(e,exports){for(var t in e)"default"===t||{}.hasOwnProperty.call(exports,t)||r(exports,e,t)}
|
|
2028
2032
|
Object.defineProperty(exports,"__esModule",{value:!0}),n(t(4118),exports),n(t(5498),exports),n(t(1178),exports),n(t(1266),exports),n(t(4628),exports)},3247(e,exports,t){"use strict"
|
|
2029
2033
|
function r(e){return{taskId:e.localId||e.id,title:e.title,sequenceNumber:e.sequenceNumber,status:e.status}}function n(e){return e.sequenceNumber?"#"+e.sequenceNumber:""+e.taskId}async function o(e,t){const n=e.getTaskClient(),o=await n.listTasks({requestId:t,sortBy:"created",sortDirection:"asc"}),s=o.find((e=>"in_progress"===e.status)),i=o.find((e=>"pending"===e.status))
|
|
2030
|
-
return{active:s?r(s):null,nextPending:i?r(i):null}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTasks=async function(e,t,d,u,h,
|
|
2034
|
+
return{active:s?r(s):null,nextPending:i?r(i):null}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTasks=async function(e,t,d,u,h,g){const p=u.child({tool:"tasks"}),{operation:m}=e
|
|
2031
2035
|
try{const h=t.projectId
|
|
2032
2036
|
if(!h)throw Error("Project ID not available")
|
|
2033
2037
|
d.setProjectId(h)
|
|
@@ -2035,15 +2039,15 @@ const f=await async function(e,t,r,n){const o=n?.sessionId||e.currentSessionId
|
|
|
2035
2039
|
if(!o||"__unknown__"===o||"__server__"===o)throw Error("Cannot resolve request: no session identity available")
|
|
2036
2040
|
const i=await s.sessionIdentity.getSessionRequestId(t,r,o)
|
|
2037
2041
|
if(!i)throw Error("No request associated with session "+o)
|
|
2038
|
-
return i}(t,d,u,
|
|
2042
|
+
return i}(t,d,u,g)
|
|
2039
2043
|
switch(m){case"create":{const{title:t,description:r}=e
|
|
2040
2044
|
if(!t)return{content:[{type:"text",text:"Error: title is required for create"}],isError:!0}
|
|
2041
2045
|
if(!r)return{content:[{type:"text",text:"Error: description is required for create"}],isError:!0}
|
|
2042
2046
|
const n=d.getTaskClient(),[{active:s},a]=await Promise.all([o(d,f),n.createTask({requestId:f,projectId:h,title:t,description:r})]),u=a.localId||a.id
|
|
2043
|
-
let
|
|
2044
|
-
if(!s)try{await n.updateTaskStatus(u,"in_progress"),
|
|
2047
|
+
let g=!1
|
|
2048
|
+
if(!s)try{await n.updateTaskStatus(u,"in_progress"),g=!0}catch(e){p.debug("Could not auto-start task",{taskId:u,error:(0,i.getErrorMessage)(e)})}const m=a.sequenceNumber??null
|
|
2045
2049
|
let y=m?`Created #${m}: ${t}`:`Created ${(0,l.formatTaskRefForAgent)(u)}: ${t}`
|
|
2046
|
-
return
|
|
2050
|
+
return g&&(y+=" (started)"),{content:[{type:"text",text:y}],...(0,c.alchemyMeta)({kind:"create-task",taskId:u,requestId:f})}}case"done":{const{summary:t}=e
|
|
2047
2051
|
if(!t)return{content:[{type:"text",text:"Error: summary is required for done"}],isError:!0}
|
|
2048
2052
|
const{active:r,nextPending:n}=await o(d,f)
|
|
2049
2053
|
if(!r)return{content:[{type:"text",text:"No active (in_progress) task to complete."}],isError:!0}
|
|
@@ -2053,7 +2057,7 @@ const u=r.sequenceNumber
|
|
|
2053
2057
|
let h=u?`Completed #${u}: ${r.title}`:`Completed ${(0,l.formatTaskRefForAgent)(r.taskId)}: ${r.title}`
|
|
2054
2058
|
if(n)try{await s.updateTaskStatus(n.taskId,"in_progress")
|
|
2055
2059
|
const e=n.sequenceNumber
|
|
2056
|
-
h+=e?`\nStarted #${e}: ${n.title}`:`\nStarted ${(0,l.formatTaskRefForAgent)(n.taskId)}: ${n.title}`}catch(e){
|
|
2060
|
+
h+=e?`\nStarted #${e}: ${n.title}`:`\nStarted ${(0,l.formatTaskRefForAgent)(n.taskId)}: ${n.title}`}catch(e){p.debug("Could not auto-start next task",{taskId:n.taskId,error:(0,i.getErrorMessage)(e)})}else h+="\nAll tasks completed."
|
|
2057
2061
|
return{content:[{type:"text",text:h}],...(0,c.alchemyMeta)({kind:"complete-task",taskId:r.taskId,requestId:f})}}case"current":{const e=d.getTaskClient(),t=await e.listTasks({requestId:f,sortBy:"created",sortDirection:"asc"}),o=t.find((e=>"in_progress"===e.status))
|
|
2058
2062
|
if(o){const e=r(o)
|
|
2059
2063
|
return{content:[{type:"text",text:`\u25b6 ${n(e)}: ${e.title}\n(file edits will attach to this task)`}],...(0,c.alchemyMeta)({kind:"current-task",taskId:e.taskId,requestId:f})}}const s=t.filter((e=>"pending"===e.status)).length
|
|
@@ -2068,7 +2072,7 @@ l&&await o.updateTaskStatus(l.localId||l.id,"pending"),await o.updateTaskStatus(
|
|
|
2068
2072
|
const u=r(i),h=l?` (paused ${n(r(l))}: ${l.title})`:""
|
|
2069
2073
|
return{content:[{type:"text",text:`Started ${n(u)}: ${u.title}${h}`}],...(0,c.alchemyMeta)({kind:"start-task",taskId:u.taskId,requestId:f})}}case"list":{const e=d.getTaskClient(),t=await e.listTasks({requestId:f,sortBy:"created",sortDirection:"asc"})
|
|
2070
2074
|
return 0===t.length?{content:[{type:"text",text:"No tasks."}],...(0,c.alchemyMeta)({kind:"list-tasks"})}:{content:[{type:"text",text:t.map(((e,t)=>{const r=e.sequenceNumber??t+1
|
|
2071
|
-
return`[${"in_progress"===e.status?"\u25b6 in_progress":e.status}] #${r}: ${e.title}`})).join("\n")}],...(0,c.alchemyMeta)({kind:"list-tasks"})}}default:return{content:[{type:"text",text:"Unknown operation: "+m}],isError:!0}}}catch(e){return
|
|
2075
|
+
return`[${"in_progress"===e.status?"\u25b6 in_progress":e.status}] #${r}: ${e.title}`})).join("\n")}],...(0,c.alchemyMeta)({kind:"list-tasks"})}}default:return{content:[{type:"text",text:"Unknown operation: "+m}],isError:!0}}}catch(e){return p.error("tasks operation failed",{operation:m,error:(0,i.getErrorMessage)(e)}),{content:[{type:"text",text:"Error: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
|
|
2072
2076
|
const s=t(6688),i=t(8824),a=t(3451),c=t(2272),l=t(4466)},3253(e,exports){"use strict"
|
|
2073
2077
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTimestamp=function(e,t){const r=e instanceof Date?e:new Date(e)
|
|
2074
2078
|
if(isNaN(r.getTime()))return"Invalid date"
|
|
@@ -2145,7 +2149,7 @@ R.push({type:"file",path:t,fullPath:n,replacements:e.replacements,mode:e.mode||"
|
|
|
2145
2149
|
if(j.length>0&&!r.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
2146
2150
|
for(const e of j)x.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
|
|
2147
2151
|
if(x.length>0&&r.apiClient){const e=x.map((e=>e.documentId))
|
|
2148
|
-
try{await(0,
|
|
2152
|
+
try{await(0,p.ensureDocumentsNotLocked)(e,r.apiClient,y,c,"replace-strings-documents")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2149
2153
|
throw e}}k=d.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
2150
2154
|
const M=R.length>0?R[0].path:"document-operation",O=await d.validateTaskId(q,M,o,y,c,v.metricsPrefix),$=O?.requestId
|
|
2151
2155
|
let D=null
|
|
@@ -2160,7 +2164,7 @@ R[e]={...t,path:o,fullPath:s}}}if(x.length>0&&$)try{await(0,h.validateRequestSta
|
|
|
2160
2164
|
throw e}k=d.FileOperationPhase.RECORD_CREATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
2161
2165
|
const N=[...R.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...x.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:z}=await d.createFileOperationRecords(q,$,r.projectId,v.recordType,M,{operationCount:_.length,fileOperations:R.length,documentOperations:x.length,operations:N,userComment:E},o,s,y,c,v.metricsPrefix,f)
|
|
2162
2166
|
if(b=z,I=z,k=v.fileOperationPhase,c.incrementCounter("replace_strings_phase",1,{phase:k}),R.length>0&&r.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
|
|
2163
|
-
const e=await(0,
|
|
2167
|
+
const e=await(0,g.commitUserChangesBeforeToolOperation)(r.git,"replace-strings",{requestId:$,taskId:q,workspaceManager:r.workspaceManager},y,c)
|
|
2164
2168
|
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:q,fileOperationsCount:R.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:q,fileOperationsCount:R.length,error:e instanceof Error?e.message:e+""})}y.debug("[REPLACE-STRINGS] Proceeding with file operations",{fileCount:R.length})
|
|
2165
2169
|
const L=[]
|
|
2166
2170
|
let H=0,B=0
|
|
@@ -2184,7 +2188,7 @@ for(const t of e.replacements.filter((e=>!e.success)))Z+=` - "${t.old_str}" \u2
|
|
|
2184
2188
|
const X=Date.now()-w
|
|
2185
2189
|
return y.info("Replace strings operation completed",{duration:X,success:J,totalOperations:L.length,successfulOperations:W,failedOperations:V}),c.incrementCounter("replace_strings_total",1,{success:J}),{content:[{type:"text",text:Z}],isError:!J}}catch(t){const r=Date.now()-w
|
|
2186
2190
|
if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await s.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 c.incrementCounter("replace_strings_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
2187
|
-
const l=c(t(1943)),d=a(t(5967)),u=t(9860),h=t(5003),
|
|
2191
|
+
const l=c(t(1943)),d=a(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),m=t(8824)},3322(e,exports,t){"use strict"
|
|
2188
2192
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
2189
2193
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
2190
2194
|
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=[]
|
|
@@ -2218,10 +2222,10 @@ var u=t(1887)
|
|
|
2218
2222
|
Object.defineProperty(exports,"ProxyClient",{enumerable:!0,get(){return u.ProxyClient}})
|
|
2219
2223
|
var h=t(4192)
|
|
2220
2224
|
Object.defineProperty(exports,"BaseApiClient",{enumerable:!0,get(){return h.BaseApiClient}})
|
|
2221
|
-
var
|
|
2222
|
-
Object.defineProperty(exports,"SessionRequestAssociationClient",{enumerable:!0,get(){return
|
|
2223
|
-
var
|
|
2224
|
-
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return
|
|
2225
|
+
var g=t(1599)
|
|
2226
|
+
Object.defineProperty(exports,"SessionRequestAssociationClient",{enumerable:!0,get(){return g.SessionRequestAssociationClient}})
|
|
2227
|
+
var p=t(5187)
|
|
2228
|
+
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return p.CLISessionClient}})
|
|
2225
2229
|
var m=t(6539)
|
|
2226
2230
|
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return m.ClientFactory}})
|
|
2227
2231
|
const f=t(6539)
|
|
@@ -2247,14 +2251,14 @@ if(t&&"object"==typeof t&&(n="description"in t&&!!t.description),t){const e={id:
|
|
|
2247
2251
|
"id"in t&&t.id&&(e.id=t.id+""),"title"in t&&t.title&&(e.title=t.title+""),"description"in t&&void 0!==t.description&&(null===t.description?e.description="":e.description=t.description+""),"status"in t&&t.status&&(e.status=t.status),"projectId"in t&&t.projectId&&(e.projectId=t.projectId+""),"requestId"in t&&t.requestId&&(e.requestId=t.requestId+""),"createdAt"in t&&t.createdAt&&(e.createdAt=t.createdAt+""),"updatedAt"in t&&t.updatedAt&&(e.updatedAt=t.updatedAt+"")
|
|
2248
2252
|
const n=e
|
|
2249
2253
|
"metadata"in t&&t.metadata&&(n.metadata=t.metadata),h=n}else h={id:r,title:"Untitled Task",description:"No description available.",status:"pending",projectId:a,requestId:"",createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}
|
|
2250
|
-
l.info("Retrieved task information",{taskId:r,title:h.title,status:h.status})}catch(e){throw new n.NotFoundError(`Task ${(0,s.formatTaskRefForAgent)(r)} not found in project ${a}. Please provide a valid task ID.`,{taskId:r,projectId:a,originalError:e})}let
|
|
2254
|
+
l.info("Retrieved task information",{taskId:r,title:h.title,status:h.status})}catch(e){throw new n.NotFoundError(`Task ${(0,s.formatTaskRefForAgent)(r)} not found in project ${a}. Please provide a valid task ID.`,{taskId:r,projectId:a,originalError:e})}let g=null
|
|
2251
2255
|
if(h.requestId)try{const e=i.getRequestClient()
|
|
2252
|
-
|
|
2256
|
+
g=await e.getRequest(h.requestId),l.info("Retrieved parent request information",{taskId:r,requestId:h.requestId})}catch(e){l.warn("Failed to retrieve parent request",{error:(0,o.getErrorMessage)(e),taskId:r,requestId:h.requestId})}const p=e=>{if(!e)return"Unknown date"
|
|
2253
2257
|
try{const t=new Date(e)
|
|
2254
|
-
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},m=
|
|
2258
|
+
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},m=p(h.createdAt),f=p(h.updatedAt),y=h.requestId||h.requestLocalId,w=h.sequenceNumber&&y?(0,s.formatTaskRef)(y,h.sequenceNumber):r,b=(0,s.formatTaskRefForAgent)(w)
|
|
2255
2259
|
let I=`# Task: ${h.title} (${b})\n\n`
|
|
2256
|
-
if(I+=`**Status**: ${h.status}\n`,I+=`**Created**: ${m}\n`,I+=`**Updated**: ${f}\n`,h.requestId&&(I+="**Parent Request**: "+h.requestId,I+=
|
|
2257
|
-
I+="\n## Metadata\n\n",e.lastCommit&&(I+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(I+=`**Completed At**: ${
|
|
2260
|
+
if(I+=`**Status**: ${h.status}\n`,I+=`**Created**: ${m}\n`,I+=`**Updated**: ${f}\n`,h.requestId&&(I+="**Parent Request**: "+h.requestId,I+=g?` (${g.title})\n`:"\n"),h.metadata){const e=h.metadata
|
|
2261
|
+
I+="\n## Metadata\n\n",e.lastCommit&&(I+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(I+=`**Completed At**: ${p(e.completedAt)}\n`),e.completionSummary&&(I+=`**Completion Summary**: ${e.completionSummary}\n`)
|
|
2258
2262
|
const t=["lastCommit","completedAt","completionSummary"]
|
|
2259
2263
|
Object.entries(e).filter((([e])=>!t.includes(e))).forEach((([e,t])=>{I+=`**${e}**: ${t}\n`}))}return I+="\n## Description\n\n",h.description&&h.description.trim().length>0?I+=h.description:I+="No description provided.",d({success:!0}),{content:[{type:"text",text:I}]}}catch(s){l.error("Failed to get task information",{error:s instanceof Error?s.stack:s+"",args:e})
|
|
2260
2264
|
try{const n=i.getToolRecordClient()
|
|
@@ -2292,7 +2296,7 @@ const r=t(6183),n=t(8317)
|
|
|
2292
2296
|
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){"use strict"
|
|
2293
2297
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2294
2298
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
2295
|
-
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(2568),u=t(3102),h=t(1152),
|
|
2299
|
+
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(2568),u=t(3102),h=t(1152),g=t(3884),p=t(7888),m=t(4139),f=t(6800),y=t(6539),w=t(8824),b=t(6975),I=t(1253),k=process.argv.slice(2),v=k[0]||process.cwd(),C=n.default.resolve(v),_=parseInt(process.env.LOCAL_SERVER_PORT||k[1]||"3002",10),E=(0,c.createEnvLogger)({serviceName:"mcp-http-server"});(0,c.isDebugToolsEnabled)()?E.info("HTTP server initializing",{baseDir:C,preferredPort:_,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL}):E.info("HTTP server starting",{port:_})
|
|
2296
2300
|
const S=(0,h.createMetricsCollector)(!0),T=(process.env.REMOTE_SERVER_PORT,process.env.REMOTE_SERVER_HOST,process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com")
|
|
2297
2301
|
E.info("Using remote server URL",{remoteServerUrl:T}),async function(){try{E.info("Finding available port...",{preferredPort:_,baseDir:C,remoteServerUrl:T})
|
|
2298
2302
|
const e=await(0,f.findAvailablePort)(_)
|
|
@@ -2302,14 +2306,14 @@ E.info(`Checking ${m.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensur
|
|
|
2302
2306
|
const h=new I.TokenManager(E,n.default.join(c,"auth-token.json")),k=(await y.ClientFactory.createClient(T,E,S,{tokenManager:h,workingDir:C,alchemyPath:c})).projectClient,v=new b.ProjectClientAdapter(k,E),q=new d.ProjectSynchronizer(E,t,v,r),P=await q.getOrCreateProject(C,{name:n.default.basename(C)||"Local Project",description:"Project for "+n.default.basename(C),status:"active",metadata:{basePath:C,alchemyPath:c,bootstrapped:!0}})
|
|
2303
2307
|
E.info("Using project",{projectId:P.id,projectName:P.name})
|
|
2304
2308
|
const j=(0,o.default)()
|
|
2305
|
-
j.use((0,s.default)()),j.use(o.default.json({limit:"50mb"})),j.use(o.default.urlencoded({extended:!0})),j.use((0,
|
|
2309
|
+
j.use((0,s.default)()),j.use(o.default.json({limit:"50mb"})),j.use(o.default.urlencoded({extended:!0})),j.use((0,g.requestLogger)(E))
|
|
2306
2310
|
try{E.info("Creating MCP server instance")
|
|
2307
2311
|
const t=await(0,i.createServer)(C,E,S,T,{existingProjectId:P.id})
|
|
2308
2312
|
E.info("MCP server instance created successfully")
|
|
2309
2313
|
const r=t.getContext()
|
|
2310
|
-
E.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(E.info("Adding connection status middleware"),j.use((0,
|
|
2314
|
+
E.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(E.info("Adding connection status middleware"),j.use((0,p.addConnectionStatusInfo)(t.connectionManager))):E.warn("Unable to add connection status middleware - connection manager not available")
|
|
2311
2315
|
try{const e=P.id
|
|
2312
|
-
E.info("Setting up project context middleware",{projectId:e}),j.use("/api",((t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}))}catch(e){E.warn("Failed to set up project context middleware",{error:(0,w.getErrorMessage)(e)})}(0,a.registerApiRoutes)(j,t,E,S),j.use((0,
|
|
2316
|
+
E.info("Setting up project context middleware",{projectId:e}),j.use("/api",((t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}))}catch(e){E.warn("Failed to set up project context middleware",{error:(0,w.getErrorMessage)(e)})}(0,a.registerApiRoutes)(j,t,E,S),j.use((0,g.errorHandler)(E,S)),j.listen(e,(()=>{E.info("HTTP API server listening on port "+e,{baseDir:C,port:e,nodeVersion:process.version})}))}catch(e){E.error("Failed to create or initialize MCP server",{error:e instanceof Error?e.stack:e+""})
|
|
2313
2317
|
let t=!1
|
|
2314
2318
|
e instanceof Error&&(t=e.message.includes("connection")||e.message.includes("timeout")||e.message.includes("network")||"ConnectionError"===e.name),S.incrementCounter("server_initialization_failure",1,{isConnectionError:t?"true":"false"}),j.use(((e,t,r)=>{t.set("X-Connection-Status","offline"),t.set("X-Server-Initialization-Failed","true"),r()})),j.use("/api",((t,r)=>{r.status(503).json({success:!1,error:{code:"CONNECTION_ERROR",message:"Server failed to initialize due to connection issues. Please check connectivity and try again.",details:{serverError:e instanceof Error?e.message:e+"",suggestions:["Check your network connection","Verify that the remote server is running","Try restarting the local server"],isConnectionIssue:!0},retryable:!0,statusCode:503}})})),E.warn("Continuing with limited functionality due to initialization error")}process.on("SIGINT",(()=>{E.info("Received SIGINT signal, shutting down..."),process.exit(0)})),process.on("SIGTERM",(()=>{E.info("Received SIGTERM signal, shutting down..."),process.exit(0)})),process.on("uncaughtException",(e=>{E.error("Uncaught exception",{error:e.stack}),process.exit(1)})),process.on("unhandledRejection",(e=>{E.error("Unhandled promise rejection",{reason:e}),process.exit(1)}))}catch(e){E.error("Failed to start HTTP API server",{error:e instanceof Error?e.stack:e+""}),process.exit(1)}}()},3626(e,exports,t){"use strict"
|
|
2315
2319
|
function r(e){if(!e)return!1
|
|
@@ -2335,8 +2339,8 @@ o=Math.max(o,s)}return o/Math.min(r.length,n.length)}Object.defineProperty(expor
|
|
|
2335
2339
|
let h=i(e,t)
|
|
2336
2340
|
if(h.length>0)return h
|
|
2337
2341
|
if(!a)return[]
|
|
2338
|
-
const
|
|
2339
|
-
if(
|
|
2342
|
+
const g=(0,d.tryLineBasedMatch)(e,t,5,u)
|
|
2343
|
+
if(g&&g.length>0)return g.map((e=>({line:e.startLine,actuallyMatched:e.actuallyMatched,matchType:"line_based",startPos:e.startPos,endPos:e.endPos})))
|
|
2340
2344
|
try{if(h=function(e,t,o=100,a){const c=[],l=n(t,a),d=Date.now()
|
|
2341
2345
|
if(t.length>500)return i(e,t)
|
|
2342
2346
|
const u=t.match(/^[ \t]*/)[0],h=u.length>0
|
|
@@ -2349,35 +2353,35 @@ const d=Math.min(Math.floor(.5*t.length),200),u=Math.min(r+t.length+d,e.length),
|
|
|
2349
2353
|
for(let t=i;u>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2350
2354
|
if(i.length>h)break
|
|
2351
2355
|
if(i===l){c.push({line:s+1,actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t})
|
|
2352
|
-
break}}}o+=i.length+1}return c}const
|
|
2353
|
-
if(!
|
|
2354
|
-
let
|
|
2356
|
+
break}}}o+=i.length+1}return c}const g=t.trim()[0]
|
|
2357
|
+
if(!g)return c
|
|
2358
|
+
let p=0,m=0
|
|
2355
2359
|
for(;;){if(m%100==0&&Date.now()-d>o){const r=Date.now()-d
|
|
2356
2360
|
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${o}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}m++
|
|
2357
|
-
const r=e.indexOf(p
|
|
2361
|
+
const r=e.indexOf(g,p)
|
|
2358
2362
|
if(-1===r)break
|
|
2359
2363
|
let i=r+t.length
|
|
2360
2364
|
const u=Math.min(Math.floor(.5*t.length),200),h=Math.min(r+t.length+u,e.length),f=l.length
|
|
2361
2365
|
let y=!1
|
|
2362
2366
|
for(let t=i;h>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2363
2367
|
if(i.length>f)break
|
|
2364
|
-
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),
|
|
2365
|
-
break}}y||(
|
|
2368
|
+
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),p=t,y=!0
|
|
2369
|
+
break}}y||(p=r+1)}return c}(e,t,c,u),h.length>0)return h}catch(e){if(e instanceof Error&&e.message.includes("timed out"))throw e}return h=function(e,t,n=100,a){if(r(a))return[]
|
|
2366
2370
|
const c=[],l=o(t),d=Date.now()
|
|
2367
2371
|
if(t.length>500)return i(e,t)
|
|
2368
2372
|
if(!l)return c
|
|
2369
2373
|
const u=t.replace(/\s/g,"")[0],h=l.length
|
|
2370
|
-
let
|
|
2371
|
-
for(;;){if(
|
|
2372
|
-
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${n}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}
|
|
2373
|
-
const r=e.indexOf(u,
|
|
2374
|
+
let g=0,p=0
|
|
2375
|
+
for(;;){if(p%100==0&&Date.now()-d>n){const r=Date.now()-d
|
|
2376
|
+
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${n}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}p++
|
|
2377
|
+
const r=e.indexOf(u,g)
|
|
2374
2378
|
if(-1===r)break
|
|
2375
2379
|
const i=r+h,a=Math.min(t.length,300),m=Math.min(r+h+a,e.length)
|
|
2376
2380
|
let f=!1
|
|
2377
2381
|
for(let t=i;m>=t;t++){const n=e.substring(r,t),i=o(n)
|
|
2378
2382
|
if(i.length>h)break
|
|
2379
|
-
if(i===l){c.push({line:s(e,r),actuallyMatched:n,matchType:"whitespace_agnostic",startPos:r,endPos:t}),
|
|
2380
|
-
break}}f||(
|
|
2383
|
+
if(i===l){c.push({line:s(e,r),actuallyMatched:n,matchType:"whitespace_agnostic",startPos:r,endPos:t}),g=t,f=!0
|
|
2384
|
+
break}}f||(g=r+1)}return c}(e,t,c,u),h},exports.replaceMatch=a,exports.replaceMatches=function(e,t,r){const n=[...t].sort(((e,t)=>t.startPos-e.startPos))
|
|
2381
2385
|
let o=e
|
|
2382
2386
|
for(const e of n)o=a(o,e,r)
|
|
2383
2387
|
return o},exports.findSimilarMatches=function(e,t,r=5,n=.3){const o=e.split("\n"),s=[]
|
|
@@ -2402,15 +2406,15 @@ let i=d.FileOperationPhase.VALIDATION
|
|
|
2402
2406
|
const a={toolName:"get-file-info",operationName:"read",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"write",metricsPrefix:"get_file_info",successMessage:"Successfully retrieved info for {path}",failureMessage:"Failed to retrieve info for {path}"}
|
|
2403
2407
|
try{const a=e,{path:u}=a
|
|
2404
2408
|
n.info("Getting file info: "+u)
|
|
2405
|
-
const{normalizedPath:
|
|
2409
|
+
const{normalizedPath:p,fullPath:m}=d.validateAndNormalizePath(u,t)
|
|
2406
2410
|
i=d.FileOperationPhase.FILE_WRITE
|
|
2407
|
-
try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+u)}const f=await c.default.stat(m),y=f.isFile()?l.default.extname(m).slice(1):"",w={path:
|
|
2411
|
+
try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+u)}const f=await c.default.stat(m),y=f.isFile()?l.default.extname(m).slice(1):"",w={path:p,type:f.isDirectory()?"directory":"file",size:f.size,sizeFormatted:(g=f.size,d.formatFileSize(g)),created:r(f.birthtime),modified:r(f.mtime),accessed:r(f.atime),permissions:(h=f.mode,(511&h).toString(8)),isDirectory:f.isDirectory(),isFile:f.isFile(),isSymbolicLink:f.isSymbolicLink(),extension:y},b=["File Information for: "+p,"Type: "+w.type,`Size: ${w.sizeFormatted} (${w.size} bytes)`,"Created: "+w.created,"Modified: "+w.modified,"Accessed: "+w.accessed,"Permissions: "+w.permissions,"Is Directory: "+w.isDirectory,"Is File: "+w.isFile,"Is Symbolic Link: "+w.isSymbolicLink]
|
|
2408
2412
|
w.isFile&&y&&b.push("Extension: "+y)
|
|
2409
2413
|
const I=Date.now()-s
|
|
2410
|
-
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+
|
|
2411
|
-
return o.recordValue("get_file_info_time",r),o.incrementCounter("get_file_info_errors",1),n.error("Error getting file info:",{error:(0,u.getErrorMessage)(t),time:r}),d.handleFileOperationError(t,i,n,o,e,a)}var h,
|
|
2414
|
+
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+p,{type:w.type,size:w.size,time:I}),{content:[{type:"text",text:b.join("\n")}]}}catch(t){const r=Date.now()-s
|
|
2415
|
+
return o.recordValue("get_file_info_time",r),o.incrementCounter("get_file_info_errors",1),n.error("Error getting file info:",{error:(0,u.getErrorMessage)(t),time:r}),d.handleFileOperationError(t,i,n,o,e,a)}var h,g}
|
|
2412
2416
|
const c=a(t(1943)),l=a(t(6928)),d=i(t(5967)),u=t(8824)},3707(e,exports,t){"use strict"
|
|
2413
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,u,h,p,
|
|
2417
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,u,h,g,p,m){const f=g.child({tool:"quick_edit"}),y=Date.now()
|
|
2414
2418
|
try{const w=h.getRequestClient(),b=h.getTaskClient(),I=h.getFileClient(),k=h.getToolRecordClient(),{title:v,description:C,..._}=e,E=e.comment||v
|
|
2415
2419
|
f.info("Starting quick_edit workflow",{title:v,operationType:t})
|
|
2416
2420
|
let S=!1
|
|
@@ -2421,23 +2425,23 @@ if(!T||!T.id)throw Error("Failed to create request")
|
|
|
2421
2425
|
const q=T.id
|
|
2422
2426
|
let P
|
|
2423
2427
|
f.info("Created request",{requestId:q})
|
|
2424
|
-
try{if(f.debug("Checking for uncommitted user changes before quick-edit branch creation"),u.git)try{const e=await(0,l.commitUserChangesBeforeToolOperation)(u.git,"quick-fix",{requestId:q,taskId:void 0,workspaceManager:u.workspaceManager},p
|
|
2428
|
+
try{if(f.debug("Checking for uncommitted user changes before quick-edit branch creation"),u.git)try{const e=await(0,l.commitUserChangesBeforeToolOperation)(u.git,"quick-fix",{requestId:q,taskId:void 0,workspaceManager:u.workspaceManager},g,p)
|
|
2425
2429
|
e.userChangesCommitted?f.info("Committed user changes to main before quick-edit branch creation",{requestId:q,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:q,error:e instanceof Error?e.message:e+""})}else f.debug("No git instance available, skipping uncommitted changes check")
|
|
2426
2430
|
f.debug("Creating task")
|
|
2427
2431
|
const e=await b.createTask({requestId:q,projectId:u.projectId,title:`Execute ${t} operation`,description:"Quick change: "+v})
|
|
2428
2432
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2429
2433
|
let C
|
|
2430
|
-
if(P=e.id,f.info("Created task",{taskId:P}),f.debug("Executing file operation",{operationType:t}),"write"===t)C=await(0,o.handleWriteFile)({taskId:P,..._,comment:E},u,I,b,k,w,p,
|
|
2431
|
-
else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:P,..._,comment:E},u,b,k,w,p,
|
|
2434
|
+
if(P=e.id,f.info("Created task",{taskId:P}),f.debug("Executing file operation",{operationType:t}),"write"===t)C=await(0,o.handleWriteFile)({taskId:P,..._,comment:E},u,I,b,k,w,g,p,m)
|
|
2435
|
+
else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:P,..._,comment:E},u,b,k,w,g,p,m)
|
|
2432
2436
|
else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
|
|
2433
|
-
C=await(0,i.handleManageFiles)({taskId:P,..._,comment:E||v},u,b,k,w,h,p,
|
|
2437
|
+
C=await(0,i.handleManageFiles)({taskId:P,..._,comment:E||v},u,b,k,w,h,g,p,m)}if(C.isError){f.error("File operation failed, cleaning up request and task",{requestId:q,taskId:P})
|
|
2434
2438
|
try{await b.updateTaskStatus(P,"canceled"),f.info("Canceled task after operation failure",{taskId:P})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:P,error:e instanceof Error?e.message:e+""})}try{await w.updateRequest(q,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:q}),u.workspaceManager&&(await u.workspaceManager.cancelRequest(q),f.info("Cleaned up branch/worktree after operation failure",{requestId:q}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:q,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${C.content[0].text}\n\nThe request (${q}) and task have been canceled and cleaned up.`}],isError:!0}}const T=C.content[0].text,j=T.includes("\u26a0\ufe0f Partial Success")||T.includes("\u274c Failed")||T.includes("\u274c 0 successful")
|
|
2435
2439
|
j?f.warn("File operation completed with partial failures",{requestId:q}):f.info("File operation completed successfully"),f.debug("Completing task")
|
|
2436
|
-
try{await(0,a.handleCompleteTask)({taskId:P,summary:`Executed ${t} operation for quick fix: ${v}${j?" (partial success)":""}`},u,h,p
|
|
2440
|
+
try{await(0,a.handleCompleteTask)({taskId:P,summary:`Executed ${t} operation for quick fix: ${v}${j?" (partial success)":""}`},u,h,g,p),f.info("Task completed successfully",{taskId:P})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:P,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
|
|
2437
2441
|
try{await b.updateTaskStatus(P,"completed"),f.info("Task completed via direct updateTaskStatus call",{taskId:P})}catch(e){return f.error("Direct task completion ALSO failed - task may be stuck in in_progress",{taskId:P,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0,operationType:t,isDocumentOperation:!!_.documentId}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but task completion failed.\n\n**Request:** ${q}\n**Task:** ${P}\n**Issue:** Could not mark task as completed - it remains in 'in_progress' state\n\nThe ${t} operation was successful, but we couldn't automatically complete the task. Please use the complete-task tool manually with taskId: ${P}\n\nError: `+(e instanceof Error?e.message:e+"")}],isError:!0}}}f.debug("Completing request")
|
|
2438
2442
|
const R=j?`Quick change completed with partial success: ${v}. Some replacements failed - see details below.`:"Quick change completed: "+v,x=j?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
|
|
2439
2443
|
let M=!1
|
|
2440
|
-
try{const e=await(0,c.handleCompleteRequest)({requestId:q,summary:R,acceptanceEvidence:[{evidence:x}],testVerification:void 0},u,h,p,
|
|
2444
|
+
try{const e=await(0,c.handleCompleteRequest)({requestId:q,summary:R,acceptanceEvidence:[{evidence:x}],testVerification:void 0},u,h,g,p,m)
|
|
2441
2445
|
if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:q,error:e.content[0].text})
|
|
2442
2446
|
else{try{await w.updateRequest(q,{status:"completed",completionSummary:R}),f.info("Request finalized to completed",{requestId:q})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:q,error:(0,d.getErrorMessage)(e)})}M=!0,f.info("Request completed successfully",{requestId:q})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:q,error:e instanceof Error?e.message:e+""})}if(!M)try{f.info("Attempting direct request completion via API",{requestId:q}),await w.updateRequest(q,{status:"completed",completionSummary:R}),M=!0,f.info("Request completed successfully via direct API call",{requestId:q})}catch(e){return f.error("Direct request completion also failed",{requestId:q,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${q}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const O=Date.now()-y
|
|
2443
2447
|
f.info("Quick fix completed",{requestId:q,duration:O,hasPartialFailure:j})
|
|
@@ -2539,7 +2543,7 @@ const{taskId:M}=x,O=!!S,$=!!m
|
|
|
2539
2543
|
b.info("Writing content to "+(O?"document":"file"),{taskId:M,filePath:$?m:void 0,documentId:O?S:void 0,contentLength:"string"==typeof T?T.length:JSON.stringify(T).length,format:q,append:P,comment:j})
|
|
2540
2544
|
let D,A,F,N="",z=!1,L=!1
|
|
2541
2545
|
const H=$?m:void 0
|
|
2542
|
-
if(O){if(r.apiClient)try{await(0,
|
|
2546
|
+
if(O){if(r.apiClient)try{await(0,p.ensureDocumentNotLocked)(S,r.apiClient,b,y,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2543
2547
|
throw e}if(!r.documentFileManager)throw Error("Document file manager not available")
|
|
2544
2548
|
N=await r.documentFileManager.getDocumentAsFile(S)
|
|
2545
2549
|
const e=r.documentFileManager.getCachedDocumentInfo(S)
|
|
@@ -2561,7 +2565,7 @@ if(v=J,C=J,_=E.fileOperationPhase,y.incrementCounter("write_file_phase",1,{phase
|
|
|
2561
2565
|
else Q="string"==typeof T?T:JSON.stringify(T,null,2)
|
|
2562
2566
|
let Y=Q
|
|
2563
2567
|
if($&&r.git)try{b.debug("[WRITE-FILE] Checking for user changes before write operation")
|
|
2564
|
-
const e=await(0,
|
|
2568
|
+
const e=await(0,g.commitUserChangesBeforeToolOperation)(r.git,"write_file",{requestId:r.workspaceManager?.getCurrentContext(r.currentSessionId)?.requestId,taskId:M},b,y)
|
|
2565
2569
|
e.userChangesCommitted&&(b.debug("[WRITE-FILE] User changes committed before write operation",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),b.info("User changes committed before write-file operation",{taskId:M,path:D,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){b.debug("[WRITE-FILE] Pre-tool commit failed, continuing with write",{error:e instanceof Error?e.message:e+""}),b.warn("Pre-tool user changes commit failed, continuing with write operation",{taskId:M,path:D,error:e instanceof Error?e.message:e+""})}if(!N)throw Error("Target path not properly initialized")
|
|
2566
2570
|
if(b.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:N}),P&&L)try{Y=await c.default.readFile(N,"utf8")+Q}catch(e){b.warn("Failed to read existing content for append",{error:e})}const Z=a.default.dirname(N)
|
|
2567
2571
|
if(await c.default.mkdir(Z,{recursive:!0}),await c.default.writeFile(N,Y,"utf8"),b.info("Content written successfully",{path:$?D:"document:"+S,finalLength:Y.length,append:P,wasCreated:z}),O){r.documentFileManager.markForSync(S)
|
|
@@ -2575,7 +2579,7 @@ b.info("Write operation completed successfully",{duration:oe-k,path:$?D:"documen
|
|
|
2575
2579
|
const se=r.workspaceManager?.consumeLargeFileWarning(r.currentSessionId)
|
|
2576
2580
|
return se&&(ne+=se),{content:[{type:"text",text:ne}],...(0,l.alchemyMeta)({kind:"write-file",toolRecordId:C})}}catch(t){const r=Date.now()-k
|
|
2577
2581
|
if(b.error("Write operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:_}),C)try{await s.updateToolRecord(C,{metadata:{path:e?.path,status:"failed",error:(0,m.getErrorMessage)(t),phase:_,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return I({tool:"write_file",success:!1}),y.incrementCounter("write_file_errors",1,{phase:_}),{content:[{type:"text",text:"\u274c **Write Operation Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
2578
|
-
const a=i(t(6928)),c=i(t(1943)),l=t(2272),d=s(t(5967)),u=t(9860),h=t(5003),
|
|
2582
|
+
const a=i(t(6928)),c=i(t(1943)),l=t(2272),d=s(t(5967)),u=t(9860),h=t(5003),g=t(7478),p=t(9949),m=t(8824)},4118(e,exports){"use strict"
|
|
2579
2583
|
Object.defineProperty(exports,"__esModule",{value:!0})},4139(e,exports){"use strict"
|
|
2580
2584
|
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"},4150(e,exports,t){"use strict"
|
|
2581
2585
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=exports.TasksSchema=void 0
|
|
@@ -2596,14 +2600,14 @@ this.authToken?(a.Authorization="Bearer "+this.authToken,this.logger.debug("Usin
|
|
|
2596
2600
|
const c=process.env.SERVICE_SHARED_SECRET||"dev-service-secret-change-in-production"
|
|
2597
2601
|
a["X-Service-Secret"]=c
|
|
2598
2602
|
let l=0
|
|
2599
|
-
const d=this.options.retryAttempts,u={method:e,path:s},h=this.metrics.startTimer("api_request_duration"),
|
|
2603
|
+
const d=this.options.retryAttempts,u={method:e,path:s},h=this.metrics.startTimer("api_request_duration"),g=e=>h({...u,...e})
|
|
2600
2604
|
for(;d>l;){l++
|
|
2601
2605
|
try{this.logger.debug(`Making ${e} request to ${i}`,{attempt:l,maxAttempts:d,hasAuth:!!a.Authorization,hasServiceIdentifier:!!a["X-Client-Type"]})
|
|
2602
2606
|
const t={method:e,headers:{...a},signal:AbortSignal.timeout(this.options.timeout||1e4)}
|
|
2603
2607
|
if("GET"!==e&&void 0!==r&&(t.body=JSON.stringify(r)),this.logger.debug("Request details",{method:e,url:i}),t.headers){const e={}
|
|
2604
2608
|
Object.entries(t.headers).forEach((([t,r])=>{"authorization"===t.toLowerCase()?e[t]="Bearer [redacted]":e[t]=r})),this.logger.debug("Request headers",{headers:e})}if("GET"!==e&&t.body){const e="string"==typeof t.body?t.body:JSON.stringify(t.body)
|
|
2605
2609
|
this.logger.debug("Request body",{bodyPreview:e.substring(0,200)+(e.length>200?"...":""),bodyLength:e.length})}const n=await fetch(i,t)
|
|
2606
|
-
if(!n.ok){if(this.logger.error("API request failed with status "+n.status,{method:e,url:i,status:n.status,statusText:n.statusText,attempt:l}),401===n.status)throw
|
|
2610
|
+
if(!n.ok){if(this.logger.error("API request failed with status "+n.status,{method:e,url:i,status:n.status,statusText:n.statusText,attempt:l}),401===n.status)throw g({success:!1,status:n.status,retries:l-1}),Error("Authentication failed - invalid or expired token")
|
|
2607
2611
|
if(429===n.status){const e=n.headers.get("Retry-After"),t=e?1e3*parseInt(e):2*(this.options.retryDelay||1e3)
|
|
2608
2612
|
if(this.logger.warn(`Rate limited (429), retrying after ${t}ms`,{attempt:l,maxAttempts:d,retryAfter:e}),d>l){await new Promise((e=>setTimeout(e,t)))
|
|
2609
2613
|
continue}}if(n.status>=500&&d>l){const e=(this.options.retryDelay||1e3)*Math.pow(2,l-1)
|
|
@@ -2612,17 +2616,17 @@ continue}let t=`API request failed with status ${n.status}: ${n.statusText}`,r={
|
|
|
2612
2616
|
try{const e=await n.json()
|
|
2613
2617
|
if(e&&"object"==typeof e&&!1===e.success&&e.error){const n=e.error
|
|
2614
2618
|
n.message&&(t=n.message),r={code:n.code,statusCode:n.statusCode,retryable:n.retryable,details:n.details}}else e&&"object"==typeof e&&e.message&&(t=e.message)}catch(e){try{const e=await n.text()
|
|
2615
|
-
e&&e.trim()&&(t=`${t}. Response: ${e.substring(0,200)}`)}catch(t){this.logger.debug("Failed to parse error response",{jsonError:e instanceof Error?e.message:e+"",textError:t instanceof Error?t.message:t+""})}}
|
|
2619
|
+
e&&e.trim()&&(t=`${t}. Response: ${e.substring(0,200)}`)}catch(t){this.logger.debug("Failed to parse error response",{jsonError:e instanceof Error?e.message:e+"",textError:t instanceof Error?t.message:t+""})}}g({success:!1,status:n.status,retries:l-1})
|
|
2616
2620
|
const o=Error(t)
|
|
2617
2621
|
throw o.status=n.status,o.statusText=n.statusText,o.method=e,o.url=i,o.errorDetails=r,o}this.resetFailureCount()
|
|
2618
2622
|
const o=await n.json()
|
|
2619
2623
|
if(null===o||"object"!=typeof o)throw Error("Invalid API response: expected object, got "+typeof o)
|
|
2620
2624
|
if(o&&"object"==typeof o&&!("success"in o)){this.logger.warn("Non-standard API response detected - wrapping in standard format",{responseKeys:Object.keys(o)})
|
|
2621
2625
|
const e={success:!0,data:o}
|
|
2622
|
-
return
|
|
2623
|
-
throw this.logger.error("API returned error response",{errorCode:e.error?.code,errorMessage:e.error?.message,statusCode:e.error?.statusCode}),
|
|
2624
|
-
return
|
|
2625
|
-
throw void 0!==r&&500>r||this.incrementFailureCount(),this.logger.error(`API request failed after ${l} attempts`,{method:e,url:i,error:t.message||t+"",status:t.status}),
|
|
2626
|
+
return g({success:!0,status:n.status,retries:l-1,standardFormat:!1}),e}if(o&&"object"==typeof o&&"success"in o&&!1===o.success){const e=o
|
|
2627
|
+
throw this.logger.error("API returned error response",{errorCode:e.error?.code,errorMessage:e.error?.message,statusCode:e.error?.statusCode}),g({success:!1,status:n.status,retries:l-1,errorCode:e.error?.code}),Error(`API error: ${e.error?.code}: ${e.error?.message}`)}if(o&&"object"==typeof o&&"success"in o&&!0===o.success&&"data"in o){const t=o
|
|
2628
|
+
return g({success:!0,status:n.status,retries:l-1,standardFormat:!0}),this.logger.debug("API request succeeded with status "+n.status,{method:e,url:i,status:n.status,retries:l-1,hasMetadata:"metadata"in t}),t}return this.logger.warn("Invalid API response format: Unexpected structure",{responseType:typeof o,responseKeys:"object"==typeof o?Object.keys(o):[]}),{success:!0,data:o}}catch(t){if(l>=d){const r=t?.status
|
|
2629
|
+
throw void 0!==r&&500>r||this.incrementFailureCount(),this.logger.error(`API request failed after ${l} attempts`,{method:e,url:i,error:t.message||t+"",status:t.status}),g({success:!1,error:!0,retries:l-1}),t}const r=Math.min((this.options.retryDelay||1e3)*Math.pow(2,l-1),5e3)
|
|
2626
2630
|
this.logger.warn(`API request failed, retrying in ${r}ms`,{method:e,url:i,error:t.message||t+"",attempt:l,maxAttempts:d}),await new Promise((e=>setTimeout(e,r)))}}throw Error("Unexpected end of requestWithRetry")}incrementFailureCount(){this.failureCount++,this.metrics.setGauge("api_failure_count",this.failureCount),"half-open"!==this.circuitState?this.failureCount<this.options.circuitBreakerThreshold||"closed"!==this.circuitState||this.openCircuit():this.logger.warn("Half-open probe failed, will retry on next request")}resetFailureCount(){const e="closed"!==this.circuitState
|
|
2627
2631
|
this.failureCount=0,this.circuitState="closed",this.metrics.setGauge("api_failure_count",0),this.metrics.setGauge("circuit_breaker_open",0),this.circuitResetTimeout&&(clearTimeout(this.circuitResetTimeout),this.circuitResetTimeout=null),e&&this.logger.info("Circuit breaker closed after successful request")}openCircuit(){this.circuitState="open",this.metrics.setGauge("circuit_breaker_open",1),this.logger.warn(`Circuit breaker opened after ${this.failureCount} failures`),this.circuitResetTimeout&&clearTimeout(this.circuitResetTimeout)
|
|
2628
2632
|
const e=this.options.circuitBreakerResetTime||5e3
|
|
@@ -2644,17 +2648,17 @@ if(!c.startsWith(s+a.sep))return{content:[{type:"text",text:"\u274c Invalid file
|
|
|
2644
2648
|
try{await i.access(c)}catch{return{content:[{type:"text",text:"\u274c Asset not found: "+r}],isError:!0}}const u=a.extname(r).toLowerCase().slice(1),h=d[u]
|
|
2645
2649
|
if(!h)return{content:[{type:"text",text:"\u274c Unsupported image type: ."+u}],isError:!0}
|
|
2646
2650
|
if("svg"===u)return{content:[{type:"text",text:`**Asset: ${r}**\n\n\`\`\`svg\n${await i.readFile(c,"utf-8")}\n\`\`\``}]}
|
|
2647
|
-
const
|
|
2648
|
-
return o.info("Asset viewed",{filename:r,size:
|
|
2651
|
+
const g=await i.readFile(c),p=g.toString("base64")
|
|
2652
|
+
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}}}
|
|
2649
2653
|
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"}},4245(module){function e(e){var t=Error("Cannot find module '"+e+"'")
|
|
2650
2654
|
throw t.code="MODULE_NOT_FOUND",t}e.keys=()=>[],e.resolve=e,e.id=4245,module.exports=e},4306(e,exports,t){"use strict"
|
|
2651
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMergeRequest=async function(e,t,a,c,l){const d=c.child({tool:"merge_request"}),u=l.startTimer("tool_execution_time"),{requestId:h,verifications:
|
|
2655
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMergeRequest=async function(e,t,a,c,l){const d=c.child({tool:"merge_request"}),u=l.startTimer("tool_execution_time"),{requestId:h,verifications:g}=e
|
|
2652
2656
|
try{if(!h)throw(0,n.createValidationError)("requestId is required")
|
|
2653
|
-
d.info("Starting merge request",{requestId:h,verificationCount:
|
|
2657
|
+
d.info("Starting merge request",{requestId:h,verificationCount:g.length})
|
|
2654
2658
|
const e=a.getRequestClient(),s=await e.getRequest(h)
|
|
2655
2659
|
if("ready_for_review"===s?.status)return u({success:!1,reason:"testing_in_progress"}),{content:[{type:"text",text:`STOP: Cannot merge request ${h} \u2014 testing is in progress. Wait for tests to complete. The request will be moved to ready_for_merge when tests pass.`}],isError:!0}
|
|
2656
|
-
if(
|
|
2657
|
-
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,
|
|
2660
|
+
if(g.length>0)try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/verify-criteria`,{verifications:g}),d.info("Criteria verified",{requestId:h,count:g.length})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2661
|
+
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,p
|
|
2658
2662
|
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/validate-completion`,{})
|
|
2659
2663
|
c=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2660
2664
|
return u({success:!1,error:"validation_failed"}),{content:[{type:"text",text:"Failed to validate merge: "+t}],isError:!0}}if(!c.canComplete){let e=`Cannot merge request ${h}: ${c.reason}\n`
|
|
@@ -2662,10 +2666,10 @@ return c.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\
|
|
|
2662
2666
|
try{const e=t.workspaceManager.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,n=t.git??(0,r.simpleGit)({baseDir:e,binary:t.gitBinary}),o=await async function(e){for(const t of["main","master"])try{return await e.raw(["rev-parse","--verify",t]),t}catch{}return"main"}(n)
|
|
2663
2667
|
l=(await n.raw(["merge-base",o,"requests/"+h])).trim()||void 0}catch(e){d.warn("Could not compute merge-base; mergeBaseSha will not be recorded",{requestId:h,error:(0,i.getErrorMessage)(e)})}let m="workspace-manager"
|
|
2664
2668
|
const f=await e.getRequest(h),y=f?.title||"Request "+h,w="resolving_conflicts"===f?.status
|
|
2665
|
-
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),
|
|
2669
|
+
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),p=await t.workspaceManager.completeRequest(h,y,{skipConflictDetection:!0}),m="retry-theirs"):(p=await t.workspaceManager.completeRequest(h,y),m=p.autoMergeInfo?.strategy||"workspace-manager"),d.info("Merge completed",{requestId:h,mergeCommitHash:p.mergeCommitHash,mergeMethod:m})}catch(r){if(r.conflictInfo){const n=r.conflictInfo,s=n.workingDirectory||t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||process.cwd(),c=(0,o.createConflictResolutionManager)(d,a,s,t.git),l=await c.handleConflicts(n)
|
|
2666
2670
|
try{await e.updateRequest(h,{status:"resolving_conflicts"}),d.info("Set status to resolving_conflicts",{requestId:h})}catch(e){d.error("Failed to set resolving_conflicts status",{requestId:h,error:(0,i.getErrorMessage)(e)})}return u({success:!1,reason:"merge_conflicts"}),{content:[{type:"text",text:l.userMessage}],isError:!1}}const n=(0,i.getErrorMessage)(r)
|
|
2667
|
-
return u({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Merge failed: "+n}],isError:!0}}try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/finalize-completion`,{summary:f?.completionSummary||"Merged request "+h,acceptanceEvidence:
|
|
2668
|
-
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:
|
|
2671
|
+
return u({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Merge failed: "+n}],isError:!0}}try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/finalize-completion`,{summary:f?.completionSummary||"Merged request "+h,acceptanceEvidence:g.map((e=>({evidence:e.evidence}))),mergeResult:{mergeCommitHash:p.mergeCommitHash,mergeBaseSha:l,mergedFiles:p.mergedFiles,cleanedUp:p.cleanedUp,method:m}})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2672
|
+
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:p.mergeCommitHash,error:t}),u({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${p.mergeCommitHash.substring(0,8)}) but failed to update server: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:`Request ${h} merged successfully.\nCommit: ${p.mergeCommitHash.substring(0,8)}`}]}}catch(e){const r=(0,i.getErrorMessage)(e)
|
|
2669
2673
|
d.error("Merge request failed",{error:r})
|
|
2670
2674
|
try{await(0,s.createFailureToolRecord)("merge-request",e,{error:r,requestId:h},a.getToolRecordClient(),d,l,{requestId:h,projectId:t.projectId,note:"Failed to merge request"})}catch{}return u({success:!1,error:e instanceof Error?e.name:"unknown"}),{content:[{type:"text",text:"Error: "+r}],isError:!0}}}
|
|
2671
2675
|
const r=t(3807),n=t(9860),o=t(1651),s=t(8616),i=t(8824)},4394(e,exports,t){"use strict"
|
|
@@ -2685,48 +2689,51 @@ const a=await r.updateDocument(e.planId,i),c=a.localId||a.id
|
|
|
2685
2689
|
return o.info("Plan appended",{planId:c,appendedLength:e.content.length}),{content:[{type:"text",text:`\u2705 **Plan Appended**\n\n**Plan ID:** ${c}\n**Appended:** ${e.content.length} characters\n**Total Length:** ${s.length} characters`}]}}catch(e){return o.error("Failed to append to plan",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to append to plan:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
2686
2690
|
const r=t(8824)},4425(e,exports,t){"use strict"
|
|
2687
2691
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2688
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,
|
|
2689
|
-
try{const
|
|
2690
|
-
if("list"===
|
|
2692
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,u,h,g,p){const m=h.startTimer("tool_execution_time"),f=e.operation||"run"
|
|
2693
|
+
try{const h=await r.proxyGet(`/api/projects/${t.projectId}/check-commands`),y=h?.data||h||[],w=y.filter((e=>e.isActive)),b=y.filter((e=>!e.isActive))
|
|
2694
|
+
if("list"===f){if(0===y.length)return m({success:!0}),{content:[{type:"text",text:'No commands configured for this project yet.\n\nUse `commands({ operation: "register", commands: [{ name: "typecheck", command: "tsc --noEmit", description: "..." }] })` to add one, or `commands({ operation: "setup" })` to spawn the architect for an interview.'}],...(0,a.alchemyMeta)({kind:"list-commands"})}
|
|
2691
2695
|
const e=[]
|
|
2692
|
-
return
|
|
2693
|
-
try{const r=await fetch((0,
|
|
2696
|
+
return w.length>0&&(e.push(`## Available Commands (${w.length})\n`),e.push(...w.map((e=>`- **${e.name}**: \`${e.command}\`${e.cwd?` (in \`${e.cwd}\`)`:""}${e.description?" \u2014 "+e.description:""}`)))),b.length>0&&(e.push(`\n## Pending Approval (${b.length})\n`),e.push(...b.map((e=>`- **${e.name}**: \`${e.command}\`${e.cwd?` (in \`${e.cwd}\`)`:""} \u2014 \u23f3 waiting for user approval`)))),e.push('\nRun: `commands({ name: "name" })`\nRegister: `commands({ operation: "register", commands: [{ name, command, description, cwd? }, ...] })` \u2014 submits 1+ commands for approval. Single-item arrays work for one command; multiples bundle into one batch notification.\nRemove: `commands({ operation: "remove", name: "..." })`\nSetup (interactive): `commands({ operation: "setup" })` \u2014 spawns the command-architect for guided setup'),m({success:!0}),{content:[{type:"text",text:e.join("\n")}],...(0,a.alchemyMeta)({kind:"list-commands"})}}if("setup"===f){const t=p?.sessionId,n=t?await l.sessionIdentity.getSessionRequestId(r,u,t):void 0
|
|
2697
|
+
try{const r=await fetch((0,d.getActionServerBaseUrl)()+"/api/setup-commands",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:n,parentSessionId:t,context:e.context}),signal:AbortSignal.timeout(15e3)})
|
|
2694
2698
|
if(!r.ok){const e=await r.text().catch((()=>""))
|
|
2695
|
-
return
|
|
2696
|
-
return o.success&&o.data?(
|
|
2697
|
-
const n=function(e){return e?.sessionId||
|
|
2698
|
-
if(!n)return
|
|
2699
|
-
const o=new Set(
|
|
2699
|
+
return m({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:`commands setup failed: action server returned ${r.status}: ${e.slice(0,300)}`}],isError:!0}}const o=await r.json()
|
|
2700
|
+
return o.success&&o.data?(m({success:!0}),{content:[{type:"text",text:`Commands setup session started.\nWorktree: ${o.data.worktreePath} (branch: ${o.data.branch})\n\nThe command-architect agent is now interviewing the user. You will receive a notification on your next turn when configuration completes \u2014 continue with other work in the meantime.`}],...(0,a.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:o.data.sessionId,agentType:"command-architect",description:"Commands setup"})}):(m({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(o.error||"unknown error")}],isError:!0})}catch(e){return m({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(0,c.getErrorMessage)(e)}],isError:!0}}}if("register"===f){if(!Array.isArray(e.commands)||0===e.commands.length)return m({success:!1,error:"missing_commands"}),{content:[{type:"text",text:"Error: `commands` array is required and must be non-empty for the register operation."}],isError:!0}
|
|
2701
|
+
const n=function(e){return e?.sessionId||l.sessionIdentity.getIdentity()?.sessionId||null}(p)
|
|
2702
|
+
if(!n)return m({success:!1,error:"no_session"}),{content:[{type:"text",text:"Error: no session context available to attribute approval notifications."}],isError:!0}
|
|
2703
|
+
const o=new Set(y.map((e=>e.name.toLowerCase()))),s=[],i=[]
|
|
2700
2704
|
for(const t of e.commands){const e=t.name?.trim(),r=t.command?.trim(),n=t.description?.trim()
|
|
2701
|
-
e&&r&&n?o.has(e.toLowerCase())?
|
|
2705
|
+
e&&r&&n?o.has(e.toLowerCase())?i.push({name:e,reason:"already exists"}):(o.add(e.toLowerCase()),s.push({name:e,command:r,description:n,cwd:t.cwd?.trim(),timeout:t.timeout})):i.push({name:e||"(unnamed)",reason:"missing required fields (name, command, description)"})}const d=await Promise.all(s.map((async e=>{try{const n=await r.proxyPost(`/api/projects/${t.projectId}/check-commands`,{name:e.name,command:e.command,description:e.description,timeout:e.timeout||60,cwd:e.cwd||void 0,addedBySessionId:p?.sessionId,isActive:!1}),o=n?.data?.id||n?.id
|
|
2702
2706
|
if(!o)throw Error("command create returned no id")
|
|
2703
|
-
return{ok:!0,proposal:e,commandId:o}}catch(t){return{ok:!1,proposal:e,error:(0,
|
|
2704
|
-
for(const e of
|
|
2705
|
-
const
|
|
2706
|
-
if(
|
|
2707
|
+
return{ok:!0,proposal:e,commandId:o}}catch(t){return{ok:!1,proposal:e,error:(0,c.getErrorMessage)(t)}}}))),h=d.filter((e=>e.ok))
|
|
2708
|
+
for(const e of d)e.ok||i.push({name:e.proposal.name,reason:e.error})
|
|
2709
|
+
const g=[]
|
|
2710
|
+
if(h.length>0)try{const e=r.getSessionMessageClient()
|
|
2707
2711
|
if(!e)throw Error("session message client unavailable")
|
|
2708
|
-
await e.createQuestion({fromSessionId:n,questionType:"alternatives",question:`Command batch approval: ${
|
|
2709
|
-
for(const e of g
|
|
2710
|
-
for(const t of
|
|
2711
|
-
const
|
|
2712
|
-
return
|
|
2713
|
-
const n=
|
|
2714
|
-
if(!n)return
|
|
2715
|
-
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),
|
|
2716
|
-
return
|
|
2717
|
-
if(!
|
|
2718
|
-
return
|
|
2719
|
-
e.grep&&(
|
|
2720
|
-
const
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2712
|
+
await e.createQuestion({fromSessionId:n,questionType:"alternatives",question:`Command batch approval: ${h.length} command${1===h.length?"":"s"}`,options:[{id:"approve-all",label:"Approve all",description:`Activate all ${h.length} commands`},{id:"deny-all",label:"Deny all",description:"Delete all proposed commands"},{id:"select",label:"Select\u2026",description:"Pick which to approve individually"}],context:JSON.stringify({type:"command-approval-batch",commands:h.map((e=>({commandId:e.commandId,name:e.proposal.name,command:e.proposal.command,description:e.proposal.description,cwd:e.proposal.cwd})))}),category:"action-required",priority:"high"})
|
|
2713
|
+
for(const e of h)g.push(e.proposal.name)}catch(e){await Promise.allSettled(h.map((e=>r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${e.commandId}`).catch((t=>u.warn("Rollback delete after batch question failure",{commandId:e.commandId,error:(0,c.getErrorMessage)(t)}))))))
|
|
2714
|
+
for(const t of h)i.push({name:t.proposal.name,reason:(0,c.getErrorMessage)(e)})}u.info("Register submitted commands for approval",{total:e.commands.length,submitted:g.length,skipped:i.length}),m({success:!0})
|
|
2715
|
+
const f=[`## Submitted ${g.length} command${1===g.length?"":"s"} for approval${i.length?`, ${i.length} skipped`:""}`]
|
|
2716
|
+
return g.length>0&&(f.push("","### Pending approval"),f.push(...g.map((e=>`- **${e}**`))),f.push("","The user will see one approval notification per command. Approved commands become runnable; denied ones are removed.")),i.length>0&&(f.push("",`### Skipped (${i.length})`),f.push(...i.map((e=>`- **${e.name}** \u2014 ${e.reason}`)))),f.push("",'Use `commands({ operation: "list" })` to see status.'),{content:[{type:"text",text:f.join("\n")}],...(0,a.alchemyMeta)({kind:"register-commands"})}}if("remove"===f){if(!e.name?.trim())return m({success:!1,error:"missing_name"}),{content:[{type:"text",text:"Error: `name` is required when removing a command."}],isError:!0}
|
|
2717
|
+
const n=y.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2718
|
+
if(!n)return m({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.`}],isError:!0}
|
|
2719
|
+
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),u.info("Removed command",{name:n.name,id:n.id}),m({success:!0}),{content:[{type:"text",text:`Removed command **${n.name}**.`}]}}catch(e){return m({success:!1,error:"remove_failed"}),{content:[{type:"text",text:"Failed to remove command: "+(0,c.getErrorMessage)(e)}],isError:!0}}}if(!e.name){const e=w.map((e=>e.name)).join(", ")
|
|
2720
|
+
return m({success:!1,error:"missing_name"}),{content:[{type:"text",text:"Error: `name` is required when running a command.\n\nAvailable commands: "+(e||"(none configured)")}],isError:!0}}const I=w.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2721
|
+
if(!I){const t=w.map((e=>e.name)).join(", ")
|
|
2722
|
+
return m({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.\n\nAvailable commands: ${t||"(none configured)"}`}],isError:!0}}let k=e.args?`${I.command} ${e.args}`:I.command
|
|
2723
|
+
e.grep&&(k=`${k} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
|
|
2724
|
+
const v=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,C=I.cwd?o.default.resolve(v,I.cwd):v,_=o.default.join(v,i.ALCHEMY_DIR_NAME,"command-logs"),E=`${I.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,S=o.default.join(_,E+".log")
|
|
2725
|
+
let T=null
|
|
2726
|
+
try{s.default.mkdirSync(_,{recursive:!0}),T=s.default.createWriteStream(S,{flags:"w"}),T.write(`# ${(new Date).toISOString()} starting: ${k}\n# cwd: ${C}\n# timeout: ${I.timeout||60}s\n\n`)}catch(e){u.warn("Failed to open command log file",{logPath:S,error:(0,c.getErrorMessage)(e)})}u.info("Running command",{name:I.name,command:k,cwd:C,configuredCwd:I.cwd,logPath:S})
|
|
2727
|
+
const q=await(0,n.runTrackedShellCommand)(k,{cwd:C,timeoutMs:1e3*(I.timeout||60),env:{...process.env,FORCE_COLOR:"0"},onChunk:T?(e,t)=>{T?.write(t)}:void 0},{id:E,name:I.name,sessionId:p?.sessionId,logPath:S})
|
|
2728
|
+
T&&(T.write(`\n# exit: ${q.exitCode}${q.timedOut?" (timed out)":""}\n`),T.end())
|
|
2729
|
+
let P=q.stdout,j=q.stderr
|
|
2730
|
+
const R=q.exitCode,x=q.timedOut,M=8e3,O=4e3
|
|
2731
|
+
P.length>M&&(P="\u2026"+P.slice(-M)),j.length>O&&(j="\u2026"+j.slice(-O))
|
|
2732
|
+
const $=x?"TIMEOUT":null,D=[P,j].filter(Boolean).join("\n")||"(no output)"
|
|
2733
|
+
let A
|
|
2734
|
+
if(g)try{const e=await g.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:I.name,command:k,exitCode:R,timedOut:x,status:x?"timeout":0===R?"success":"failed",timestamp:(new Date).toISOString()}})
|
|
2735
|
+
A=e?.id}catch(e){u.debug("Failed to create tool record for command run",{error:(0,c.getErrorMessage)(e)})}return m({success:!0}),{content:[{type:"text",text:`## ${I.name}${$?` \u2014 ${$} (killed after ${I.timeout}s)`:""}\n\`\`\`\n$ ${k}\n${D}\n\`\`\`\n\nExit code: ${R}\nFull log: ${S}`}],...(0,a.alchemyMeta)({kind:"run-command",toolRecordId:A})}}catch(e){return m({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,c.getErrorMessage)(e)}],isError:!0}}}
|
|
2736
|
+
const n=t(4600),o=r(t(6928)),s=r(t(9896)),i=t(4139),a=t(2272),c=t(8824),l=t(6688),d=t(9414)},4466(e,exports,t){"use strict"
|
|
2730
2737
|
function r(e,t){return`${e}#${t.toString().padStart(2,"0")}`}async function n(e,t,n,s){if(exports.TASK_REF_PATTERN.test(e))return e
|
|
2731
2738
|
const i=e.match(exports.TASK_REF_SHORT_PATTERN)
|
|
2732
2739
|
if(!i)return e
|
|
@@ -2748,10 +2755,10 @@ if(1>parseInt(t[2],10))throw Error(`Invalid task number in ${e}: must be >= 1`)
|
|
|
2748
2755
|
return e}
|
|
2749
2756
|
const o=t(6688),s=t(8955)
|
|
2750
2757
|
exports.TASK_REF_PATTERN=/^(req\d{6})#(\d+)$/,exports.TASK_REF_SHORT_PATTERN=/^#?(\d{1,3})$/},4592(e,exports,t){"use strict"
|
|
2751
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlannerOps=async function(e,t,c,l,d,u){const h=c.child({tool:"planner_ops"}),
|
|
2752
|
-
try{const c=e,{operation:
|
|
2758
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlannerOps=async function(e,t,c,l,d,u){const h=c.child({tool:"planner_ops"}),g=l.startTimer("tool_execution_time")
|
|
2759
|
+
try{const c=e,{operation:p,sessionId:m}=c
|
|
2753
2760
|
let f
|
|
2754
|
-
switch(h.info("Processing planner_ops",{operation:
|
|
2761
|
+
switch(h.info("Processing planner_ops",{operation:p,sessionId:m}),p){case"request":{const e=await async function(e,t,r){if(!e)return"ask"
|
|
2755
2762
|
try{const s=r?.sessionId||o.sessionIdentity.getIdentity()?.sessionId
|
|
2756
2763
|
if(!s)return"ask"
|
|
2757
2764
|
const i=e.getCLISessionClient()
|
|
@@ -2772,18 +2779,28 @@ break}const r="auto-planner"
|
|
|
2772
2779
|
if(h.info("Spawning planner",{planningMode:e,agent:r}),f=await(0,s.handleSpawn)({agent:r,prompt:c.prompt,title:c.description},t,h,d,u),!f.isError&&f.content.length>0){const t=f.content[0].text
|
|
2773
2780
|
f.content[0].text=`Planning mode: ${e} (agent: ${r}). Planning is running in the background \u2014 continue with your other work.\n${t}`}break}case"check-status":f=await(0,s.handleCheckStatus)(m,t,h,d)
|
|
2774
2781
|
break
|
|
2775
|
-
case"list":const e=u?.sessionId||o.sessionIdentity.getIdentity()?.sessionId,[a,l]=await Promise.all([(0,s.handleListSessions)(t,h,d,{activeOnly:c.activeOnly,limit:c.limit,agentType:"auto-planner",parentSessionId:e}),(0,s.handleListSessions)(t,h,d,{activeOnly:c.activeOnly,limit:c.limit,agentType:"planner",parentSessionId:e})]),
|
|
2776
|
-
if(
|
|
2777
|
-
|
|
2782
|
+
case"list":const e=u?.sessionId||o.sessionIdentity.getIdentity()?.sessionId,[a,l]=await Promise.all([(0,s.handleListSessions)(t,h,d,{activeOnly:c.activeOnly,limit:c.limit,agentType:"auto-planner",parentSessionId:e}),(0,s.handleListSessions)(t,h,d,{activeOnly:c.activeOnly,limit:c.limit,agentType:"planner",parentSessionId:e})]),g=a.content[0]?.text??"",y=l.content[0]?.text??""
|
|
2783
|
+
if(g.trim()||y.trim()){const e=[]
|
|
2784
|
+
g.trim()&&e.push("## Auto-planner sessions\n"+g),y.trim()&&e.push("## Interactive plan sessions\n"+y),f={content:[{type:"text",text:e.join("\n\n")}]}}else f={content:[{type:"text",text:"No planning sessions found."}]}
|
|
2778
2785
|
break
|
|
2779
|
-
default:throw new r.ValidationError("Unknown operation: "+
|
|
2780
|
-
const y=a[
|
|
2781
|
-
return(0,i.withAlchemyKind)(f,y)}catch(e){return h.error("Planner ops failed",{error:e instanceof Error?e.stack:e+""}),
|
|
2786
|
+
default:throw new r.ValidationError("Unknown operation: "+p)}g({success:!0}),l.incrementCounter(`planner_ops_${p}_success`,1)
|
|
2787
|
+
const y=a[p]??"planner-request"
|
|
2788
|
+
return(0,i.withAlchemyKind)(f,y)}catch(e){return h.error("Planner ops failed",{error:e instanceof Error?e.stack:e+""}),g({success:!1}),l.incrementCounter("planner_ops_errors",1),{content:[{type:"text",text:"Planner operation failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}}
|
|
2782
2789
|
const r=t(9860),n=t(8824),o=t(6688),s=t(1725),i=t(2272),a={request:"planner-request","check-status":"planner-check-status",list:"planner-list"}},4600(e,exports,t){"use strict"
|
|
2783
|
-
|
|
2790
|
+
async function r(e,r={}){const{spawn:n}=await Promise.resolve().then(t.t.bind(t,5317,23))
|
|
2791
|
+
return new Promise((t=>{const o="win32"===process.platform,s=n(e,{cwd:r.cwd??process.cwd(),env:r.env,shell:o?"cmd.exe":"/bin/sh",stdio:["pipe","pipe","pipe"],detached:!o}),i=[],a=[]
|
|
2792
|
+
let c=!1,l=!1
|
|
2793
|
+
const d=e=>{if(s.pid)try{o?s.kill(e):process.kill(-s.pid,e)}catch{}}
|
|
2794
|
+
let u,h
|
|
2795
|
+
r.timeoutMs&&r.timeoutMs>0&&(h=setTimeout((()=>{c=!0,d("SIGTERM"),u=setTimeout((()=>{l||d("SIGKILL")}),2e3)}),r.timeoutMs)),s.stdout?.on("data",(e=>{i.push(e),r.onChunk?.("stdout",e)})),s.stderr?.on("data",(e=>{a.push(e),r.onChunk?.("stderr",e)}))
|
|
2796
|
+
const g=e=>{l||(l=!0,h&&clearTimeout(h),u&&clearTimeout(u),t({stdout:Buffer.concat(i).toString("utf-8"),stderr:Buffer.concat(a).toString("utf-8"),exitCode:e,timedOut:c}))}
|
|
2797
|
+
s.on("close",(e=>g(e??(c?124:1)))),s.on("error",(()=>g(1)))}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.execAsync=async function(e,t={}){return new Promise(((r,o)=>{const[s,...i]=e.split(" "),a=(0,n.spawn)(s,i,{cwd:t.cwd||process.cwd(),stdio:["pipe","pipe","pipe"]})
|
|
2784
2798
|
let c="",l=""
|
|
2785
|
-
a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{
|
|
2786
|
-
|
|
2799
|
+
a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{r({stdout:c,stderr:l,exitCode:e||0})})),a.on("error",(t=>{o(Error(`Command failed: ${e}\nError: ${t.message}`))})),t.timeout&&setTimeout((()=>{a.kill(),o(Error("Command timed out: "+e))}),t.timeout)}))},exports.runShellCommand=r,exports.runTrackedShellCommand=async function(e,n,o){const{getActionServerBaseUrl:s}=await Promise.resolve().then(t.bind(t,9414)),i=s(),a=(new Date).toISOString(),c=n.cwd??process.cwd()
|
|
2800
|
+
fetch(i+"/api/commands/start",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:o.id,name:o.name,command:e,cwd:c,sessionId:o.sessionId,startedAt:a,logPath:o.logPath}),signal:AbortSignal.timeout(2e3)}).catch((()=>{}))
|
|
2801
|
+
const l=await r(e,n)
|
|
2802
|
+
return fetch(i+"/api/commands/end",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:o.id,exitCode:l.exitCode,timedOut:l.timedOut,finishedAt:(new Date).toISOString()}),signal:AbortSignal.timeout(2e3)}).catch((()=>{})),l}
|
|
2803
|
+
const n=t(5317)},4607(e,exports,t){"use strict"
|
|
2787
2804
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2788
2805
|
const r=t(6183),n=t(3306)
|
|
2789
2806
|
exports.def={name:"replace_strings",description:'Replace text strings across multiple files and documents in a single operation.\n\nMODES:\n\u2022 \'unique\' (default, safer) - Fails if string appears multiple times\n\u2022 \'all\' - Replaces all occurrences\n\nOPERATIONS:\nEach operation specifies:\n\u2022 Target: \'path\' (for files) or \'documentId\' (for documents)\n\u2022 Replacements: Array of {old_str, new_str} pairs\n\u2022 Mode: \'unique\' or \'all\'\n\nEXAMPLES:\n- Replace in file: {"path": "file.ts", "replacements": [{"old_str": "foo", "new_str": "bar"}], "mode": "unique"}\n- Replace in document: {"documentId": "doc123", "replacements": [{"old_str": "old", "new_str": "new"}]}\n\nSupports multiple files/documents and multiple replacements per operation. All changes are committed atomically to Git for files.',schema:r.ReplaceStringsSchema,annotations:{title:"Replace Strings in Files/Documents",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},hidden:!0,createsRecords:!0,handler(e,t){return(0,n.handleReplaceStrings)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},4628(e,exports){"use strict"
|
|
@@ -2796,10 +2813,10 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2796
2813
|
var t={}
|
|
2797
2814
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2798
2815
|
return o(t,e),t})
|
|
2799
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,r,n,o,s,u,h){const
|
|
2800
|
-
try{const
|
|
2801
|
-
return
|
|
2802
|
-
try{const{normalizedPath:y,fullPath:w}=c.validateAndNormalizePath(t,o),b=await c.validateTaskId(e,y,s.getTaskClient(),h,
|
|
2816
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,r,n,o,s,u,h){const g=s.child({tool:"file_recover"}),p=u.startTimer("tool_execution_time"),m=Date.now()
|
|
2817
|
+
try{const p=e,{path:f,commitHash:y,createBackup:w}=p,{resolveActiveTaskId:b}=await Promise.resolve().then(t.bind(t,3451)),I=e.taskId||await b(r,n,s)||"untracked"
|
|
2818
|
+
return g.info("Recovering file to previous version",{taskId:I,filePath:f,commitHash:y,createBackup:w}),await async function(e,t,r,n,o,s,u,h,g,p,m){let f
|
|
2819
|
+
try{const{normalizedPath:y,fullPath:w}=c.validateAndNormalizePath(t,o),b=await c.validateTaskId(e,y,s.getTaskClient(),h,g,"file-recover"),{toolRecordId:I}=await c.createFileOperationRecords(e,b?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),u,h,g,"file-recover",m)
|
|
2803
2820
|
f=I
|
|
2804
2821
|
let k,v=!1
|
|
2805
2822
|
try{await a.access(w),v=!0,n&&(k=`${w}.backup-${(new Date).toISOString().replace(/[:.]/g,"-")}`,await a.copyFile(w,k),h.info("Created backup",{originalPath:w,backupPath:k}))}catch{v=!1}const C=o.git
|
|
@@ -2811,31 +2828,31 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
|
|
|
2811
2828
|
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await a.writeFile(w,_,"utf8")
|
|
2812
2829
|
let E={}
|
|
2813
2830
|
try{const t=`Recover ${y} from ${r.substring(0,8)}`
|
|
2814
|
-
E=await c.commitToGit(e,y,f,f,t,o,h,
|
|
2831
|
+
E=await c.commitToGit(e,y,f,f,t,o,h,g,"file-recover"),h.info("Recovery committed via shared utility",{path:y,sourceCommitHash:r,newCommitHash:E.commitHash?.substring(0,8),commitMessage:t})}catch(e){h.warn("Failed to commit recovery via shared utility",{error:e})}if(f)try{await u.updateToolRecord(f,{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){h.warn("Failed to update tool record",{recordError:e})}const S=v?"recovered":"created from recovery"
|
|
2815
2832
|
let T=`\u2705 **File ${S.charAt(0).toUpperCase()+S.slice(1)} Successfully**\n\n`
|
|
2816
|
-
return T+=`**File:** ${y}\n`,T+=`**Recovered from:** ${r.substring(0,8)}\n`,T+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(T+=`**Backup created:** ${i.basename(k)}\n`),T+="**Git status:** Recovery committed\n",T+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",h.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-
|
|
2817
|
-
return
|
|
2833
|
+
return T+=`**File:** ${y}\n`,T+=`**Recovered from:** ${r.substring(0,8)}\n`,T+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(T+=`**Backup created:** ${i.basename(k)}\n`),T+="**Git status:** Recovery committed\n",T+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",h.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:T}]}}catch(e){throw e}}(I,f,y,w,r,n,o,g,u,m,h)}catch(e){const t=Date.now()-m
|
|
2834
|
+
return g.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),p({tool:"file_recover",success:!1}),u.incrementCounter("file_recover_errors",1),{content:[{type:"text",text:"\u274c **Recovery Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
2818
2835
|
const i=s(t(6928)),a=s(t(1943)),c=s(t(5967)),l=t(3922),d=t(8824)},4648(e,exports,t){"use strict"
|
|
2819
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,h,p,
|
|
2836
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,h,g,p,m,f){const y=p.child({tool:"request_operations"})
|
|
2820
2837
|
try{const w=e
|
|
2821
2838
|
let{requestId:b}=w
|
|
2822
2839
|
const{operation:I}=w
|
|
2823
2840
|
if("list"!==I&&"search"!==I&&!b){const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=h.currentSessionId
|
|
2824
|
-
if(r&&"__unknown__"!==r&&"__server__"!==r&&(b=await e.getSessionRequestId(
|
|
2841
|
+
if(r&&"__unknown__"!==r&&"__server__"!==r&&(b=await e.getSessionRequestId(g,y,r)||void 0),!b)return{content:[{type:"text",text:`Error: requestId is required for '${I}' and could not be resolved from session`}],isError:!0}}switch(y.info("Processing request operation",{requestId:b,operation:I}),I){case"complete":{y.info("Routing to complete-request handler")
|
|
2825
2842
|
const e={requestId:b,summary:w.complete.summary}
|
|
2826
|
-
return(0,d.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,h,p,
|
|
2843
|
+
return(0,d.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,h,g,p,m,f),u.complete)}case"merge":return y.info("Routing to merge handler"),(0,d.withAlchemyKind)(await(0,c.handleMergeRequest)({requestId:b,verifications:w.merge?.verifications||[]},h,g,p,m,f),u.merge)
|
|
2827
2844
|
case"approve":{y.info("Routing to approve-request handler")
|
|
2828
2845
|
const e={requestId:b}
|
|
2829
|
-
return(0,d.withAlchemyKind)(await(0,a.handleApproveRequest)(e,h,p,
|
|
2846
|
+
return(0,d.withAlchemyKind)(await(0,a.handleApproveRequest)(e,h,g,p,m,f),u.approve)}case"revert":{y.info("Routing to revert-request handler")
|
|
2830
2847
|
const e={requestId:b,reason:w.revert.reason,confirmDestructive:w.revert.confirmDestructive}
|
|
2831
|
-
return(0,d.withAlchemyKind)(await(0,n.handleRevertRequest)(e,h,p,
|
|
2848
|
+
return(0,d.withAlchemyKind)(await(0,n.handleRevertRequest)(e,h,g,p,m),u.revert)}case"get-info":{y.info("Routing to get-request-information handler")
|
|
2832
2849
|
const e={requestId:b}
|
|
2833
|
-
return(0,d.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,h,p,
|
|
2850
|
+
return(0,d.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,h,g,p,m),u["get-info"])}case"list":{y.info("Routing to list-requests handler")
|
|
2834
2851
|
const e={filters:w.list?.filters}
|
|
2835
|
-
return(0,d.withAlchemyKind)(await(0,s.handleListRequests)(e,h,p,
|
|
2852
|
+
return(0,d.withAlchemyKind)(await(0,s.handleListRequests)(e,h,g,p,m),u.list)}case"search":{y.info("Routing to search-requests handler")
|
|
2836
2853
|
const e={search:w.search}
|
|
2837
|
-
return(0,d.withAlchemyKind)(await(0,i.handleSearchRequests)(e,h,p,
|
|
2838
|
-
try{const e=
|
|
2854
|
+
return(0,d.withAlchemyKind)(await(0,i.handleSearchRequests)(e,h,g,p,m),u.search)}case"delete-empty":if(y.info("Routing to delete-empty handler"),!b)return{content:[{type:"text",text:"\u274c **Request Operations Failed:** requestId is required for delete-empty"}],isError:!0}
|
|
2855
|
+
try{const e=g.getProxyClient(),t=await e.proxyGet(`/api/projects/${h.projectId}/tasks`,{requestLocalId:b,limit:1}),r=t?.data||t||[]
|
|
2839
2856
|
return(Array.isArray(r)?r.length:0)>0?{content:[{type:"text",text:`\u274c Cannot delete ${b}: it has tasks. Only empty requests (no tasks created) can be deleted.`}],isError:!0}:(await e.proxyDelete(`/api/projects/${h.projectId}/requests/${b}`),y.info("Empty request deleted",{requestId:b}),(0,d.withAlchemyKind)({content:[{type:"text",text:`\u2705 Request ${b} deleted (had no tasks).`}]},u["delete-empty"]))}catch(e){return{content:[{type:"text",text:"\u274c **Failed to delete request:** "+(0,l.getErrorMessage)(e)}],isError:!0}}default:{const e="Unknown operation type: "+I
|
|
2840
2857
|
return y.error(e),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+e}],isError:!0}}}}catch(e){return y.error("Request operations failed",{error:e instanceof Error?e.stack:e+""}),m.incrementCounter("request_operations_errors",1),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
2841
2858
|
const r=t(5715),n=t(6416),o=t(5434),s=t(8037),i=t(233),a=t(1537),c=t(4306),l=t(8824),d=t(2272),u={complete:"complete-request",merge:"finalize-request",approve:"approve-request",revert:"revert-request","get-info":"get-request-info",list:"list-requests",search:"search-requests","delete-empty":"delete-empty-request"}},4710(e,exports,t){"use strict"
|
|
@@ -2953,16 +2970,16 @@ return t},s(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2953
2970
|
var t={}
|
|
2954
2971
|
if(null!=e)for(var r=s(e),n=0;n<r.length;n++)"default"!==r[n]&&i(t,e,r[n])
|
|
2955
2972
|
return a(t,e),t})
|
|
2956
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileBlame=async function(e,t,s,i,a){const c=i.child({tool:"file_blame"}),
|
|
2957
|
-
try{const{path:i,lines:
|
|
2958
|
-
c.info("Processing blame request",{filePath:i,lines:
|
|
2973
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileBlame=async function(e,t,s,i,a){const c=i.child({tool:"file_blame"}),g=Date.now()
|
|
2974
|
+
try{const{path:i,lines:p,branch:m}=e
|
|
2975
|
+
c.info("Processing blame request",{filePath:i,lines:p,branch:m})
|
|
2959
2976
|
const f=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,y=d.isAbsolute(i)?i:d.join(f,i),w=d.relative(f,y)
|
|
2960
2977
|
try{await u.access(y)}catch{return{content:[{type:"text",text:"\u274c File not found: "+w}],isError:!0}}const b=function(e){if(!e)return null
|
|
2961
2978
|
if(/^\d+$/.test(e)){const t=parseInt(e,10)
|
|
2962
2979
|
return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
|
|
2963
2980
|
if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
|
|
2964
2981
|
if(e.match(/^(\d+(?:,\d+)+)$/)){const t=e.split(",").map((e=>parseInt(e,10)))
|
|
2965
|
-
return{start:Math.min(...t),end:Math.max(...t)}}return null}(
|
|
2982
|
+
return{start:Math.min(...t),end:Math.max(...t)}}return null}(p),I=["blame","--porcelain"]
|
|
2966
2983
|
let k
|
|
2967
2984
|
b&&I.push(`-L${b.start},${b.end}`),m&&I.push(m),I.push("--",w),c.debug("Executing git blame",{args:I})
|
|
2968
2985
|
try{if(!t.git)throw Error("Git context not available")
|
|
@@ -2999,7 +3016,7 @@ if(d+=t,e.requestId){const r=a.get(e.requestId)
|
|
|
2999
3016
|
r?r.lines+=t:a.set(e.requestId,{title:e.requestTitle||"Untitled",lines:t})}else e.recordId||r(e.commitMessage)?c+=t:l+=t}if(a.size>0||c>0||l>0){i+="## Summary by Request\n\n"
|
|
3000
3017
|
const e=[...a.entries()].sort(((e,t)=>t[1].lines-e[1].lines))
|
|
3001
3018
|
for(const[t,r]of e){const e=Math.round(r.lines/d*100)
|
|
3002
|
-
i+=`- **${t}** "${n(r.title,40)}": ${r.lines} lines (${e}%)\n`}c>0&&(i+=`- **Alchemy (unlinked)**: ${c} lines (${Math.round(c/d*100)}%)\n`),l>0&&(i+=`- **External commits**: ${l} lines (${Math.round(l/d*100)}%)\n`)}return i}(w,C,b),T=Date.now()-
|
|
3019
|
+
i+=`- **${t}** "${n(r.title,40)}": ${r.lines} lines (${e}%)\n`}c>0&&(i+=`- **Alchemy (unlinked)**: ${c} lines (${Math.round(c/d*100)}%)\n`),l>0&&(i+=`- **External commits**: ${l} lines (${Math.round(l/d*100)}%)\n`)}return i}(w,C,b),T=Date.now()-g
|
|
3003
3020
|
return c.info("Blame request completed",{duration:T,groups:C.length,alchemyCommits:C.filter((e=>e.requestId)).length,externalCommits:C.filter((e=>!e.requestId)).length}),a.incrementCounter("file_blame_total",1,{success:!0}),{content:[{type:"text",text:S}]}}catch(e){return c.error("Blame request failed",{error:e instanceof Error?e.stack:e+""}),a.incrementCounter("file_blame_errors",1),{content:[{type:"text",text:"\u274c **Blame Failed:** "+(0,h.getErrorMessage)(e)}],isError:!0}}}
|
|
3004
3021
|
const l=t(1181),d=c(t(6928)),u=c(t(1943)),h=t(8824)},4921(e,exports,t){"use strict"
|
|
3005
3022
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
@@ -3161,20 +3178,20 @@ if(!/^req\d{6}$/.test(t))throw new r.ValidationError(`Invalid request ID format:
|
|
|
3161
3178
|
d.info("Getting information for request "+t)
|
|
3162
3179
|
const n=a.getRequestClient(),s=a.getTaskClient(),[c,l]=await Promise.all([n.getRequest(t),s.listTasks({requestId:t})])
|
|
3163
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"})
|
|
3164
|
-
const h=(0,o.extractDataFromResponse)(c,{logger:d,operationName:"getRequestInformation",throwOnNoData:!0}),
|
|
3181
|
+
const h=(0,o.extractDataFromResponse)(c,{logger:d,operationName:"getRequestInformation",throwOnNoData:!0}),g="data"in h?h.data:h
|
|
3165
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"})
|
|
3166
|
-
const
|
|
3167
|
-
d.info(`Successfully extracted ${
|
|
3168
|
-
const m={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:
|
|
3169
|
-
|
|
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 m={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
|
|
3170
3187
|
t in m&&m[t]++}))
|
|
3171
|
-
const f=
|
|
3188
|
+
const f=g.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_verified:0,total:f.length}
|
|
3172
3189
|
f.forEach((e=>{const t=e.status||"unverified"
|
|
3173
3190
|
t in y&&y[t]++}))
|
|
3174
|
-
let w=
|
|
3175
|
-
const b=
|
|
3176
|
-
let k=`# ${"feature"===I?"Feature":"quick-edit"===I?"Quick Edit":"Bug Fix"} Request: ${b} (${t})\nStatus: ${
|
|
3177
|
-
return k+=`\n## Task Status\n- Pending: ${m.pending}\n- In Progress: ${m.in_progress}\n- Blocked: ${m.blocked}\n- Ready for Review: ${m.ready_for_review}\n- Completed: ${m.completed}\n- Reverted: ${m.reverted}\n`,k+="\n## Tasks\n",0===
|
|
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: ${m.completed}/${m.total} completed (${Math.round(m.completed/m.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: ${m.pending}\n- In Progress: ${m.in_progress}\n- Blocked: ${m.blocked}\n- Ready for Review: ${m.ready_for_review}\n- Completed: ${m.completed}\n- Reverted: ${m.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)(f)+"\n","ready_for_review"===g.status&&f.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()
|
|
3178
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}}}
|
|
3179
3196
|
const r=t(9860),n=t(5674),o=t(2960),s=t(8824),i=t(5454)},5454(e,exports){"use strict"
|
|
3180
3197
|
function t(e,t){let r=0
|
|
@@ -3215,7 +3232,7 @@ if(c.incrementCounter("document_operations_total",1,{operation:"list-annotations
|
|
|
3215
3232
|
let r=`## Annotations on ${h} (${t.length})\n\n`
|
|
3216
3233
|
for(const e of t){if(r+=`### ${"resolved"===e.status?"\u2705":"\u{1f4ac}"} ${e.id} [${e.status}]\n`,r+=`> "${e.anchor?.selectedText?.substring(0,80)||""}"\n\n`,r+=e.body+"\n",e.createdByAgent&&(r+=`*By agent: ${e.createdByAgent}*\n`),e.replies&&e.replies.length>0){r+=`\n**Replies (${e.replies.length}):**\n`
|
|
3217
3234
|
for(const t of e.replies)r+="- "+t.body,t.createdByAgent&&(r+=` *(${t.createdByAgent})*`),r+="\n"}r+="\n---\n\n"}return(0,s.withAlchemyKind)({content:[{type:"text",text:r}]},"list-annotations")}case"create-annotation":{u.info("Creating annotation")
|
|
3218
|
-
const e=o.selectedText,t=o.body,{prefixContext:r,suffixContext:n,lineHint:a}=o,l=i.getDocumentClient(),
|
|
3235
|
+
const e=o.selectedText,t=o.body,{prefixContext:r,suffixContext:n,lineHint:a}=o,l=i.getDocumentClient(),g=d?"agent":void 0,p=d?.sessionId,m=await l.createAnnotation(h,{selectedText:e,prefixContext:r,suffixContext:n,lineHint:a,body:t,createdByAgent:g,createdBySessionId:p})
|
|
3219
3236
|
return c.incrementCounter("document_operations_total",1,{operation:"create-annotation",success:!0}),(0,s.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Annotation Created**\n\n**ID:** ${m.id}\n**Document:** ${h}\n**Selected text:** "${e.substring(0,60)}"\n**Comment:** `+t}]},"create-annotation")}case"reply-to-annotation":{u.info("Replying to annotation")
|
|
3220
3237
|
const e=o.annotationId,t=o.body,r=i.getDocumentClient(),n=await r.replyToAnnotation(h,e,{body:t,createdByAgent:d?"agent":void 0,createdBySessionId:d?.sessionId})
|
|
3221
3238
|
return c.incrementCounter("document_operations_total",1,{operation:"reply-to-annotation",success:!0}),(0,s.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Reply Added**\n\n**Reply ID:** ${n.id}\n**Annotation:** ${e}\n**Body:** `+t}]},"reply-to-annotation")}case"resolve-annotation":{u.info("Resolving annotation")
|
|
@@ -3244,31 +3261,31 @@ return{isOffline:this.isInOfflineMode(),consecutiveFailures:e.consecutiveFailure
|
|
|
3244
3261
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3245
3262
|
const r=t(6183),n=t(2965)
|
|
3246
3263
|
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){"use strict"
|
|
3247
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const
|
|
3264
|
+
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")
|
|
3248
3265
|
try{const{requestId:n,summary:o}=e
|
|
3249
3266
|
if(!n)throw(0,r.createValidationError)("Request ID is required")
|
|
3250
3267
|
if(!o)throw(0,r.createValidationError)("Summary is required")
|
|
3251
|
-
|
|
3268
|
+
g.info("Starting request completion",{requestId:n})
|
|
3252
3269
|
const l=h?.sessionId
|
|
3253
3270
|
let d
|
|
3254
3271
|
try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:l})
|
|
3255
3272
|
d=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3256
|
-
return
|
|
3257
|
-
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`}))),
|
|
3273
|
+
return g.error("Server validation failed",{requestId:n,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 ${n}: ${d.reason}\n`
|
|
3274
|
+
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()
|
|
3258
3275
|
let m,f="auto-test-then-merge"===d.completionMode,y=null
|
|
3259
|
-
if(f)try{const[e,r]=await Promise.all([c.proxyGet(`/api/projects/${t.projectId}/requests/${n}/test-runs`),fetch(`${(0,a.getActionServerBaseUrl)()}/api/branch-head?requestId=${encodeURIComponent(n)}`,{signal:AbortSignal.timeout(5e3)}).catch((e=>(
|
|
3276
|
+
if(f)try{const[e,r]=await Promise.all([c.proxyGet(`/api/projects/${t.projectId}/requests/${n}/test-runs`),fetch(`${(0,a.getActionServerBaseUrl)()}/api/branch-head?requestId=${encodeURIComponent(n)}`,{signal:AbortSignal.timeout(5e3)}).catch((e=>(g.debug("branch-head fetch failed; proceeding with ready_for_review",{error:(0,s.getErrorMessage)(e)}),null)))]),o=e?.data||e||[],i=Array.isArray(o)&&o.length>0?o[0]:null
|
|
3260
3277
|
if(i&&"passed"===i.status&&i.commitSha){let e=null
|
|
3261
3278
|
if(r&&r.ok){const t=await r.json()
|
|
3262
|
-
e=t?.data?.sha??null}e&&e===i.commitSha&&(f=!1,y=`latest test run ${i.id} passed against current branch HEAD ${e.slice(0,7)}`,m=i.id,
|
|
3279
|
+
e=t?.data?.sha??null}e&&e===i.commitSha&&(f=!1,y=`latest test run ${i.id} passed against current branch HEAD ${e.slice(0,7)}`,m=i.id,g.info("Skip-if-fresh: SHA match, bypassing ready_for_review",{requestId:n,runId:i.id,sha:e}))}}catch(e){g.debug("Skip-if-fresh lookup failed; proceeding with ready_for_review",{error:(0,s.getErrorMessage)(e)})}const w=f?"ready_for_review":"ready_for_merge"
|
|
3263
3280
|
try{await u.updateRequest(n,{status:w,completionSummary:o,...m?{skippedTestRunId:m}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3264
|
-
return
|
|
3281
|
+
return p({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let b
|
|
3265
3282
|
try{b=await u.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3266
|
-
return
|
|
3267
|
-
if(
|
|
3283
|
+
return p({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const I=b?.acceptanceCriteria||[]
|
|
3284
|
+
if(p({success:!0}),f)return{content:[{type:"text",text:`Request ${n} moved to ready_for_review. Testing is active \u2014 a notification has been created for the user to choose testing mode. Do NOT call merge or any other tool. Your work is done. Stop here and wait.`}]}
|
|
3268
3285
|
const k=y?`\n\n_Skipped re-running tests: ${y}._\n`:""
|
|
3269
3286
|
return 0===I.length?{content:[{type:"text",text:`Request ${n} is ready. ${k}No acceptance criteria defined \u2014 call merge directly.`}]}:{content:[{type:"text",text:`Request ${n} completion started (${w}).${k}\n\n## Next Step: Verify & Merge\n\n${(0,i.formatVerifyInstructions)(I)}\n\nUse the merge operation with your verification evidence to merge to main.`}]}}catch(r){let s="An unexpected error occurred",i=""
|
|
3270
|
-
r instanceof n.ZodError?(s="Validation error",i=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")):r instanceof Error?(s=r.message,i=r.stack||""):i=r+"",
|
|
3271
|
-
try{await(0,o.createFailureToolRecord)("complete-request",r,{error:s,details:i,requestId:e?.requestId},c.getToolRecordClient(),
|
|
3287
|
+
r instanceof n.ZodError?(s="Validation error",i=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")):r instanceof Error?(s=r.message,i=r.stack||""):i=r+"",g.error("Complete request failed",{error:s,details:i})
|
|
3288
|
+
try{await(0,o.createFailureToolRecord)("complete-request",r,{error:s,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: "+s}],isError:!0}}}
|
|
3272
3289
|
const r=t(9860),n=t(1569),o=t(8616),s=t(8824),i=t(5454),a=t(9414)},5767(e,exports,t){"use strict"
|
|
3273
3290
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3274
3291
|
const r=t(6183),n=t(6285)
|
|
@@ -3329,13 +3346,13 @@ let W=0
|
|
|
3329
3346
|
x.length>0&&n.setProjectId(r.projectId)
|
|
3330
3347
|
for(let e=0;e<$.length;e++){const t=$[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3331
3348
|
try{try{await a.default.access(t.full)}catch(e){throw Error("File not found: "+t.normalized)}if((await a.default.stat(t.full)).isDirectory())throw Error("Cannot 'delete' a directory: "+t.normalized)
|
|
3332
|
-
await a.default.unlink(t.full),r.success=!0,W++,m.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,
|
|
3349
|
+
await a.default.unlink(t.full),r.success=!0,W++,m.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,p.getErrorMessage)(e),m.warn("Failed to delete file "+t.normalized,{error:r.error})}G.push(r)}const V=x.length>0?n.getDocumentClient():null
|
|
3333
3350
|
for(const e of x){const t=e.target,r={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3334
3351
|
try{let e
|
|
3335
3352
|
try{if(e=await V.getDocument(t),r.filename=e.filename,m.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,h.validateRequestStatusForDocumentOperation)(e.requestId,v,m,s,"delete-document")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
|
|
3336
|
-
throw e}try{await(0,
|
|
3337
|
-
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,
|
|
3338
|
-
r.success=!0,r.filename=o.filename,W++,m.info("Document archived successfully",{documentId:o.id,filename:o.filename,archivedAt:o.archived_at})}catch(e){r.error=(0,
|
|
3353
|
+
throw e}try{await(0,g.ensureDocumentNotLocked)(t,n,m,s,"delete-document-archive")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
|
|
3354
|
+
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,p.getErrorMessage)(e)}`)}const o=await V.archiveDocument(t)
|
|
3355
|
+
r.success=!0,r.filename=o.filename,W++,m.info("Document archived successfully",{documentId:o.id,filename:o.filename,archivedAt:o.archived_at})}catch(e){r.error=(0,p.getErrorMessage)(e),m.warn("Failed to delete document "+t,{error:r.error})}G.push(r)}const K=Date.now()-f
|
|
3339
3356
|
s.recordValue("delete_files_time",K),s.incrementCounter("delete_files_operations_total",M),s.incrementCounter("delete_files_operations_success",W),s.incrementCounter("delete_files_operations_failed",M-W),s.incrementCounter("delete_files_file_operations",R.length),s.incrementCounter("delete_files_document_operations",x.length),W===M?s.incrementCounter("delete_files_success",1):W>0?s.incrementCounter("delete_files_partial_success",1):s.incrementCounter("delete_files_total_failure",1)
|
|
3340
3357
|
let J=null
|
|
3341
3358
|
if(W>0){b=c.FileOperationPhase.GIT_COMMIT,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
@@ -3351,11 +3368,11 @@ X=e>0&&t>0?`Successfully deleted ${e} files and ${t} documents`:e>0?`Successfull
|
|
|
3351
3368
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n"):"All delete operations failed:\n"+G.map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
|
|
3352
3369
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
|
|
3353
3370
|
return J?.commitHash&&(X+="\nCommit: "+J.commitHash.substring(0,8)),Z.requestId&&(X+="\nBranch: "+Z.requestId),{content:[{type:"text",text:X}],isError:0===W}}catch(t){if(e.taskId&&n)try{const o=n.getToolRecordClient(),s=t instanceof l.NotFoundError||t instanceof l.ValidationError||t instanceof d.ZodError
|
|
3354
|
-
await o.createToolRecord({...s?{}:{taskId:e.taskId},projectId:r.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,
|
|
3355
|
-
if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),m.error("Error in delete-files operation:",{error:(0,
|
|
3371
|
+
await o.createToolRecord({...s?{}:{taskId:e.taskId},projectId:r.projectId,type:"delete-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment,error:(0,p.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,p.getErrorMessage)(t)})}catch(t){m.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 o=Date.now()-f
|
|
3372
|
+
if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),m.error("Error in delete-files operation:",{error:(0,p.getErrorMessage)(t),time:o}),(y||w)&&e.taskId){b=c.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
3356
3373
|
try{const r=n.getTaskClient(),o=n.getToolRecordClient()
|
|
3357
|
-
await c.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,
|
|
3358
|
-
const a=i(t(1943)),c=s(t(5967)),l=t(9860),d=t(1569),u=t(7478),h=t(5003),
|
|
3374
|
+
await c.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",I.recordType,"Failed to delete operations",{status:"failed",error:(0,p.getErrorMessage)(t),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",r,o,m,s,I.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return c.handleFileOperationError(t,b,m,s,e,I)}}
|
|
3375
|
+
const a=i(t(1943)),c=s(t(5967)),l=t(9860),d=t(1569),u=t(7478),h=t(5003),g=t(9949),p=t(8824)},5997(e,exports,t){"use strict"
|
|
3359
3376
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3360
3377
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3361
3378
|
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=[]
|
|
@@ -3428,17 +3445,17 @@ if("create"===r?(e.name||t.addIssue({code:"custom",message:"name is required for
|
|
|
3428
3445
|
r||n||t.addIssue({code:"custom",message:"update requires either 'content' (plan or quest body) or at least one metadata field (criteria, tickIntervalSeconds, maxInFlight, maxPerDay, minIterations, status \u2014 quest only)."})}"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()}),exports.RevertRequestSchema=r.z.object({requestId:a,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.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()}).transform(l).refine(d,{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({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:c.optional()}).transform(l).refine(d,{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:a.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search","delete-empty"]),complete:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({summary:r.z.string()})).optional(),merge:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({verifications:r.z.array(r.z.object({key:r.z.string().min(2).max(4),evidence:r.z.string().min(1)})).min(1)})).optional(),revert:r.z.object({reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}).optional(),list:r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),approve:r.z.object({}).optional()}).superRefine(((e,t)=>{e.requestId
|
|
3429
3446
|
const r=e.operation,n={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: "..." } }'}}[r]
|
|
3430
3447
|
n&&!e[n.field]&&t.addIssue({code:"custom",message:`'${r}' operation requires '${n.field}' data. ${n.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:c.optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"}),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:c.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()}).transform(l).refine(d,{message:"path or documentId required"})).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:c.optional()}).transform(l).refine(d,{message:"path or documentId required"}))}).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")})
|
|
3431
|
-
const
|
|
3432
|
-
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(p).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"),fingerprint:r.z.array(r.z.string()).optional().describe('Files whose content invalidates setup. Setup commands re-run only when these files change between runs (e.g. ["package-lock.json"], ["Cargo.lock"], ["uv.lock", "poetry.lock"]). Polyglot repos list multiple. Omit / empty list = always re-run setup (existing behavior).'),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool. Default 2. Set to 1 for languages with very large build artifacts (Rust target/, C++ build/). Higher values allow more parallel test runs at the cost of disk.")}),exports.TestingProcessDeleteSchema=r.z.object({processId:r.z.string().describe("Test process ID to delete")}),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().optional().describe('New scope to limit when this process runs (e.g., "packages/api/"). Omit to leave unchanged.'),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(p).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe("Files whose content invalidates setup (replaces existing list)."),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool (replaces existing).")}),exports.TestingReferenceSchema=r.z.object({}),exports.TestsSchema=r.z.object({operation:r.z.enum(["list","setup","run"]).describe('"list" to see registered test processes for this project. "setup" to spawn an interactive test-architect session that helps configure a process. "run" to fire an async test run against the active process for your current request \u2014 optional `name` filters to one registered command. The call returns immediately and you receive a report on your next turn.'),name:r.z.string().optional().describe("Only used by `run`. Filters execution to a single test command by name (matches a command name registered in the test process). Omit to run all required commands.")}),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.CommandsSchema=r.z.object({operation:r.z.enum(["run","list","remove","register","setup"]).default("run").describe('"run" to execute a command, "list" to see available commands, "register" to submit one or more commands for user approval (a single-item array works for one command; multiple items get bundled into a single batch approval notification), "remove" to delete one, "setup" to spawn the command-architect for an interactive setup interview (mirrors tests.setup)'),name:r.z.string().optional().describe('Command name (required for "run", "add", and "remove")'),args:r.z.string().optional().describe('Additional arguments appended to the base command (optional, for "run")'),grep:r.z.string().optional().describe('Filter output through grep (optional, for "run"). Pipes command output through grep -i with this pattern.'),command:r.z.string().optional().describe('Shell command to register (required for "add", e.g. "tsc --noEmit")'),description:r.z.string().optional().describe('What this command verifies. REQUIRED when operation is "add" \u2014 must articulate the command\'s purpose so the audit trail (added_by_session_id + description) is meaningful in the project commands UI.'),timeout:r.z.number().optional().describe('Timeout in seconds (optional, for "add", default 60)'),cwd:r.z.string().optional().describe('Working directory relative to project root (optional, for "add", e.g. "apps/web"). Omit to run at project root \u2014 use this for monorepos where the command lives in a subdir.'),context:r.z.string().optional().describe('Optional caller hint for the "setup" operation \u2014 short note about what the calling agent thinks the user needs (e.g. "specialist asked for npm run build with strict TS"). The architect treats this as a hint but still does its own discovery + user confirmation.'),commands:r.z.array(r.z.object({name:r.z.string().min(1).describe('Command name (e.g. "test:web")'),command:r.z.string().min(1).describe("Shell command to execute"),description:r.z.string().min(1).describe("What this command verifies"),cwd:r.z.string().optional().describe("Working directory relative to project root (omit for root)"),timeout:r.z.number().optional().describe("Timeout in seconds (default 60)")})).optional().describe('Batch of commands to register (required for "register", ignored otherwise). Each item must have name, command, and description. cwd is optional and supports monorepo subdirs.')}),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"),relatesTo:r.z.string().regex(/^I-[A-Za-z0-9]+-\d+$/,'relatesTo must be an instruction code like "I-abc12345-001"').optional().describe("Optional instruction code (I-...) this question or report relates to"),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. Optional \u2014 auto-filled from the caller's session (_meta.sessionId) when omitted; only pass explicitly to answer on behalf of a different session (e.g. UI passing 'user')."),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","instruction","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"}),exports.UpdateSpecializationSchema=r.z.object({specialization:r.z.string().min(1).max(500).describe("Your updated specialization summary \u2014 a concise description of your accumulated domain expertise"),specializationHeadline:r.z.string().min(1).max(80).optional().describe("Short tagline (\u226480 chars) summarising your domain at a glance \u2014 shown next to your name in the alchemist\u2019s specialist directory. Keep it current alongside the longer specialization.")}),exports.CommitToViewedSessionSchema=r.z.object({message:r.z.coerce.string().min(1).describe("The cleaned-up user message to post to the viewed session. Fix obvious dictation errors, add punctuation, but preserve the user's intent exactly.")})},6252(e,exports,t){"use strict"
|
|
3448
|
+
const g=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)")})
|
|
3449
|
+
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(g).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"),fingerprint:r.z.array(r.z.string()).optional().describe('Files whose content invalidates setup. Setup commands re-run only when these files change between runs (e.g. ["package-lock.json"], ["Cargo.lock"], ["uv.lock", "poetry.lock"]). Polyglot repos list multiple. Omit / empty list = always re-run setup (existing behavior).'),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool. Default 2. Set to 1 for languages with very large build artifacts (Rust target/, C++ build/). Higher values allow more parallel test runs at the cost of disk.")}),exports.TestingProcessDeleteSchema=r.z.object({processId:r.z.string().describe("Test process ID to delete")}),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().optional().describe('New scope to limit when this process runs (e.g., "packages/api/"). Omit to leave unchanged.'),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(g).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe("Files whose content invalidates setup (replaces existing list)."),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool (replaces existing).")}),exports.TestingReferenceSchema=r.z.object({}),exports.TestsSchema=r.z.object({operation:r.z.enum(["list","setup","run"]).describe('"list" to see registered test processes for this project. "setup" to spawn an interactive test-architect session that helps configure a process. "run" to fire an async test run against the active process for your current request \u2014 optional `name` filters to one registered command. The call returns immediately and you receive a report on your next turn.'),name:r.z.string().optional().describe("Only used by `run`. Filters execution to a single test command by name (matches a command name registered in the test process). Omit to run all required commands.")}),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.CommandsSchema=r.z.object({operation:r.z.enum(["run","list","remove","register","setup"]).default("run").describe('"run" to execute a command, "list" to see available commands, "register" to submit one or more commands for user approval (a single-item array works for one command; multiple items get bundled into a single batch approval notification), "remove" to delete one, "setup" to spawn the command-architect for an interactive setup interview (mirrors tests.setup)'),name:r.z.string().optional().describe('Command name (required for "run", "add", and "remove")'),args:r.z.string().optional().describe('Additional arguments appended to the base command (optional, for "run")'),grep:r.z.string().optional().describe('Filter output through grep (optional, for "run"). Pipes command output through grep -i with this pattern.'),command:r.z.string().optional().describe('Shell command to register (required for "add", e.g. "tsc --noEmit")'),description:r.z.string().optional().describe('What this command verifies. REQUIRED when operation is "add" \u2014 must articulate the command\'s purpose so the audit trail (added_by_session_id + description) is meaningful in the project commands UI.'),timeout:r.z.number().optional().describe('Timeout in seconds (optional, for "add", default 60)'),cwd:r.z.string().optional().describe('Working directory relative to project root (optional, for "add", e.g. "apps/web"). Omit to run at project root \u2014 use this for monorepos where the command lives in a subdir.'),context:r.z.string().optional().describe('Optional caller hint for the "setup" operation \u2014 short note about what the calling agent thinks the user needs (e.g. "specialist asked for npm run build with strict TS"). The architect treats this as a hint but still does its own discovery + user confirmation.'),commands:r.z.array(r.z.object({name:r.z.string().min(1).describe('Command name (e.g. "test:web")'),command:r.z.string().min(1).describe("Shell command to execute"),description:r.z.string().min(1).describe("What this command verifies"),cwd:r.z.string().optional().describe("Working directory relative to project root (omit for root)"),timeout:r.z.number().optional().describe("Timeout in seconds (default 60)")})).optional().describe('Batch of commands to register (required for "register", ignored otherwise). Each item must have name, command, and description. cwd is optional and supports monorepo subdirs.')}),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"),relatesTo:r.z.string().regex(/^I-[A-Za-z0-9]+-\d+$/,'relatesTo must be an instruction code like "I-abc12345-001"').optional().describe("Optional instruction code (I-...) this question or report relates to"),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. Optional \u2014 auto-filled from the caller's session (_meta.sessionId) when omitted; only pass explicitly to answer on behalf of a different session (e.g. UI passing 'user')."),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","instruction","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"}),exports.UpdateSpecializationSchema=r.z.object({specialization:r.z.string().min(1).max(500).describe("Your updated specialization summary \u2014 a concise description of your accumulated domain expertise"),specializationHeadline:r.z.string().min(1).max(80).optional().describe("Short tagline (\u226480 chars) summarising your domain at a glance \u2014 shown next to your name in the alchemist\u2019s specialist directory. Keep it current alongside the longer specialization.")}),exports.CommitToViewedSessionSchema=r.z.object({message:r.z.coerce.string().min(1).describe("The cleaned-up user message to post to the viewed session. Fix obvious dictation errors, add punctuation, but preserve the user's intent exactly.")})},6252(e,exports,t){"use strict"
|
|
3433
3450
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3434
3451
|
const r=t(6183),n=t(405)
|
|
3435
3452
|
exports.def={name:"plan_write",description:"Create and modify project plans (and quests).\n\nOperations:\n\u2022 create - Create a new plan or quest. Pass kind='quest' with criteria/tickIntervalSeconds/maxInFlight/maxPerDay to create a quest.\n\u2022 update - Update plan/quest content. For quests, also accepts criteria / tickIntervalSeconds / maxInFlight / maxPerDay / minIterations / status (open|closed). Provide at least content or one metadata field.\n\u2022 append - Append content to an existing plan\n\u2022 replace - Find and replace text within a plan\n\u2022 create-snapshot - Create a version snapshot\n\u2022 restore - Restore to a previous version\n\u2022 set-active - Set a plan as the project's active plan",schema:r.PlanWriteSchema,annotations:{title:"Plan Write",readOnlyHint:!1,destructiveHint:!1},handler(e,t){return(0,n.handlePlanWrite)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer,t.cliOrigin)}}},6261(module){"use strict"
|
|
3436
3453
|
module.exports=require("events")},6285(e,exports,t){"use strict"
|
|
3437
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,d,u,h,p
|
|
3454
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,d,u,h,g,p){const m=u.child({tool:"specialist_ops"}),f=h.startTimer("tool_execution_time")
|
|
3438
3455
|
try{const u=e,{operation:y,sessionId:w}=u
|
|
3439
3456
|
let b
|
|
3440
|
-
switch(m.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=
|
|
3441
|
-
if(r&&
|
|
3457
|
+
switch(m.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=p?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3458
|
+
if(r&&g){const t=await async function(e,t,r,o,s){o.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
|
|
3442
3459
|
const a=await(0,i.getServerUrl)(r,o)
|
|
3443
3460
|
if(a)try{const r=await fetch(a.replace(/\/$/,"")+"/session")
|
|
3444
3461
|
if(!r.ok)return
|
|
@@ -3449,9 +3466,9 @@ if(!i)return
|
|
|
3449
3466
|
const c=n.map((e=>e.id)),l=await i.batchEnrich(c),d=await fetch(a.replace(/\/$/,"")+"/session/status"),u=d.ok?await d.json():{},h=n.filter((e=>{const t=l[e.id]
|
|
3450
3467
|
return"specialist"===t?.agentType&&"archived"!==t?.status}))
|
|
3451
3468
|
if(o.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
|
|
3452
|
-
const
|
|
3469
|
+
const g=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
|
|
3453
3470
|
return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
|
|
3454
|
-
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`+
|
|
3471
|
+
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 o.warn("Pool limit check failed, allowing spawn",{error:(0,n.getErrorMessage)(e)})}}(r,e,d,m,g)
|
|
3455
3472
|
if(t){b=t
|
|
3456
3473
|
break}}let c=u.description||u.prompt.slice(0,60)
|
|
3457
3474
|
const l=await Promise.resolve().then(t.t.bind(t,9896,23)),h=e=>l.appendFileSync(t(6928).join(t(857).tmpdir(),"specialist-name-debug.log"),`${(new Date).toISOString()} ${e}\n`)
|
|
@@ -3461,18 +3478,18 @@ if(h("session fetch status="+t.status),t.ok){const e=(await t.json()).filter((e=
|
|
|
3461
3478
|
h(`siblings=${e.length}: ${e.join(", ")}`)
|
|
3462
3479
|
const n=(0,o.pickSpecialistName)(e)
|
|
3463
3480
|
c=n,h("picked name: "+n)}}else h("no serverUrl")}catch(e){h("error: "+(e instanceof Error?e.message:e+""))}else h("no parentId")
|
|
3464
|
-
b=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,m,p
|
|
3481
|
+
b=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,m,g,p)
|
|
3465
3482
|
break}case"follow-up":{const e=await(0,i.getServerUrl)(d,m)
|
|
3466
3483
|
if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
|
|
3467
3484
|
if(t.ok){const e=await t.json(),r=e[w]?.type
|
|
3468
3485
|
if(r&&"idle"!==r&&"prompting"!==r){b={content:[{type:"text",text:`\u274c Specialist ${w} is currently busy (status: ${r}).\nUse \`delegate\` to spawn a new specialist instead.`}],isError:!0}
|
|
3469
|
-
break}}}catch{}b=await(0,s.handleContinue)(w,u.prompt,d,m,
|
|
3470
|
-
break}case"check-status":b=await(0,s.handleCheckStatus)(w,d,m,
|
|
3486
|
+
break}}}catch{}b=await(0,s.handleContinue)(w,u.prompt,d,m,g,"specialist",p)
|
|
3487
|
+
break}case"check-status":b=await(0,s.handleCheckStatus)(w,d,m,g)
|
|
3471
3488
|
break
|
|
3472
|
-
case"abort":if(b=await(0,s.handleAbort)(w,d,m),!b.isError&&
|
|
3489
|
+
case"abort":if(b=await(0,s.handleAbort)(w,d,m),!b.isError&&g)try{const e=g.getCLISessionClient()
|
|
3473
3490
|
e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
|
|
3474
|
-
case"list":{const e=
|
|
3475
|
-
b=await(0,s.handleListSessions)(d,m,
|
|
3491
|
+
case"list":{const e=p?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3492
|
+
b=await(0,s.handleListSessions)(d,m,g,{activeOnly:u.activeOnly,requestId:u.requestId,limit:u.limit,agentType:"specialist",parentSessionId:e})
|
|
3476
3493
|
break}default:throw new r.ValidationError("Unknown operation: "+y)}f({success:!0}),h.incrementCounter(`specialist_ops_${y}_success`,1)
|
|
3477
3494
|
const I=l[y]??"specialist-delegate"
|
|
3478
3495
|
return(0,c.withAlchemyKind)(b,I)}catch(e){return m.error("Specialist ops failed",{error:e instanceof Error?e.stack:e+""}),f({success:!1}),h.incrementCounter("specialist_ops_errors",1),{content:[{type:"text",text:"Specialist operation failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}}
|
|
@@ -3492,17 +3509,17 @@ var t={}
|
|
|
3492
3509
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3493
3510
|
return o(t,e),t})
|
|
3494
3511
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRevertRequest=async function(e,t,r,n,o){const s=n.child({tool:"revert_request"}),u=o.startTimer("tool_execution_time")
|
|
3495
|
-
try{const n=e,{requestId:l,reason:h,confirmDestructive:
|
|
3496
|
-
if(s.info("Starting revert/cancel process",{requestId:l,reason:h}),!
|
|
3497
|
-
let
|
|
3512
|
+
try{const n=e,{requestId:l,reason:h,confirmDestructive:g}=n
|
|
3513
|
+
if(s.info("Starting revert/cancel process",{requestId:l,reason:h}),!g)return u({success:!1,reason:"confirmation_required"}),{content:[{type:"text",text:"Error: This operation requires confirmation. Set confirmDestructive: true to proceed.\n\nThis tool will:\n- **For open/in_progress requests:** Cancel the request (no git changes)\n- **For completed requests:** Revert using git (affects git history)\n\nBoth operations make the request read-only and block further tool use."}],isError:!0}
|
|
3514
|
+
let p
|
|
3498
3515
|
try{const e=await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/validate-revert`,{})
|
|
3499
|
-
|
|
3500
|
-
return s.error("Server validation failed",{requestId:l,error:t}),u({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate revert: "+t}],isError:!0}}if(s.info("Server validation result",{requestId:l,canRevert:
|
|
3501
|
-
return
|
|
3502
|
-
try{return await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/finalize-revert`,{reason:h,operationType:"cancel"}),u({success:!0}),{content:[{type:"text",text:`Successfully canceled request ${l}.\n\nOperation: Cancel (no git changes)\nTasks updated: ${
|
|
3516
|
+
p=e?.data||e}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3517
|
+
return s.error("Server validation failed",{requestId:l,error:t}),u({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate revert: "+t}],isError:!0}}if(s.info("Server validation result",{requestId:l,canRevert:p.canRevert,operationType:p.operationType,mergeCommitHash:p.mergeCommitHash?.substring(0,8),reason:p.reason}),!p.canRevert){let e=`Cannot revert request ${l}: ${p.reason}\n`
|
|
3518
|
+
return p.lifoViolation?.blockingRequests?.length&&(e+="\n**Requests that must be reverted first (in reverse order):**\n",p.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (${t.status})\n`})),e+="\n**Why:** Requests must be reverted in reverse order (LIFO) to maintain safe git history.\n",e+="Revert the above request(s) first, then retry this one."),u({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if("cancel"===p.operationType){s.info("Cancel operation \u2014 delegating to server",{requestId:l})
|
|
3519
|
+
try{return await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/finalize-revert`,{reason:h,operationType:"cancel"}),u({success:!0}),{content:[{type:"text",text:`Successfully canceled request ${l}.\n\nOperation: Cancel (no git changes)\nTasks updated: ${p.tasksToUpdate.length} task(s) marked as canceled\nReason: ${h}`}]}}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3503
3520
|
return u({success:!1,error:"cancel_finalization_failed"}),{content:[{type:"text",text:"Failed to cancel request: "+t}],isError:!0}}}if(s.info("Revert operation \u2014 performing git revert",{requestId:l}),!t.git)throw(0,i.createServiceError)("Git repository not available for revert",{requestId:l})
|
|
3504
3521
|
t.syncBranchState&&await t.syncBranchState()
|
|
3505
|
-
let m=
|
|
3522
|
+
let m=p.mergeCommitHash
|
|
3506
3523
|
if(!m){s.info("No merge commit hash from server, searching git log",{requestId:l})
|
|
3507
3524
|
const e=await async function(e,t,r){try{const r=t.workspaceManager.getMainGit(),n=await r.raw(["log","--merges","--format=%H %s","HEAD"]),o=n.trim()?n.trim().split("\n").map((e=>{const t=e.indexOf(" ")
|
|
3508
3525
|
return-1===t?{hash:e,message:""}:{hash:e.substring(0,t),message:e.substring(t+1)}})):[],s=a.generateMergeMessagePatterns(e)
|
|
@@ -3518,7 +3535,7 @@ try{s.info("Executing git revert",{mergeCommitHash:m.substring(0,8)}),await f.ra
|
|
|
3518
3535
|
const e=await(0,c.verifyGitStateConsistency)(f,w,s,`revert-request-${l}-verification`)
|
|
3519
3536
|
e.consistent||s.error("Git state inconsistency after revert",{issues:e.issues}),s.info("Git revert completed",{requestId:l,originalMergeCommit:m.substring(0,8),revertCommitHash:w.substring(0,8)})}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3520
3537
|
return s.error("Git revert failed",{requestId:l,error:t}),u({success:!1,error:"git_revert_failed"}),{content:[{type:"text",text:"Git revert failed: "+t}],isError:!0}}try{await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/finalize-revert`,{reason:h,operationType:"revert",revertCommitHash:w,originalMergeCommitHash:m})}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3521
|
-
return s.error("CRITICAL: Git revert succeeded but server finalization failed",{requestId:l,revertCommitHash:w,error:t}),u({success:!1,error:"finalization_failed"}),{content:[{type:"text",text:`CRITICAL: Git revert succeeded (commit: ${w.substring(0,8)}) but failed to update server state: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:`Successfully reverted request ${l}.\n\nOperation: Revert (git revert of merge commit)\nTasks updated: ${
|
|
3538
|
+
return s.error("CRITICAL: Git revert succeeded but server finalization failed",{requestId:l,revertCommitHash:w,error:t}),u({success:!1,error:"finalization_failed"}),{content:[{type:"text",text:`CRITICAL: Git revert succeeded (commit: ${w.substring(0,8)}) but failed to update server state: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:`Successfully reverted request ${l}.\n\nOperation: Revert (git revert of merge commit)\nTasks updated: ${p.tasksToUpdate.length} task(s) marked as reverted\nReason: ${h}\n\nYou can re-complete the request if the revert was a mistake.`}]}}catch(n){if(n instanceof i.ValidationError||n instanceof i.NotFoundError)return s.warn("Revert validation failed",{error:n.message,requestId:e.requestId}),u({success:!1,error:"validation"}),{content:[{type:"text",text:"Error: "+n.message}],isError:!0}
|
|
3522
3539
|
if(n instanceof l.ZodError)return u({success:!1,error:"zod_validation"}),{content:[{type:"text",text:"Validation error: "+n.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")}],isError:!0}
|
|
3523
3540
|
if(t.projectId&&e.requestId)try{const o=r.getToolRecordClient()
|
|
3524
3541
|
await o.createToolRecord({requestId:e.requestId,projectId:t.projectId,type:"revert-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),reason:e.reason,error:(0,d.getErrorMessage)(n)},note:"Failed to revert request: "+(0,d.getErrorMessage)(n)})}catch{}return s.error("Revert request failed",{error:(0,d.getErrorMessage)(n),requestId:e.requestId}),u({success:!1,error:n instanceof Error?n.name:"unknown"}),{content:[{type:"text",text:"Failed to revert request: "+(0,d.getErrorMessage)(n)}],isError:!0}}}
|
|
@@ -3552,7 +3569,7 @@ break
|
|
|
3552
3569
|
case"between":if(void 0===e.afterLine||void 0===e.beforeLine)throw Error("Both afterLine and beforeLine are required for between insertion")
|
|
3553
3570
|
n=(0,m.insertBetweenLines)(r,e.afterLine,e.beforeLine,e.content)
|
|
3554
3571
|
break
|
|
3555
|
-
default:throw Error("Unknown insertion type: "+e.type)}r=n.newContent,t.success=!0,t.linesAdded=n.linesAdded,t.insertionPoint=n.insertionPoint,o+=n.linesAdded}catch(e){t.error=(0,
|
|
3572
|
+
default:throw Error("Unknown insertion type: "+e.type)}r=n.newContent,t.success=!0,t.linesAdded=n.linesAdded,t.insertionPoint=n.insertionPoint,o+=n.linesAdded}catch(e){t.error=(0,p.getErrorMessage)(e)}n.push(t)}return{newContent:r,results:n}}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3556
3573
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3557
3574
|
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=[]
|
|
3558
3575
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3575,7 +3592,7 @@ R.push({type:"file",path:t,fullPath:r,insertions:e.insertions})}const x=[]
|
|
|
3575
3592
|
if(j.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3576
3593
|
for(const e of j)x.push({type:"document",documentId:e.documentId,insertions:e.insertions})
|
|
3577
3594
|
if(x.length>0&&n.apiClient){const e=x.map((e=>e.documentId))
|
|
3578
|
-
try{await(0,
|
|
3595
|
+
try{await(0,g.ensureDocumentsNotLocked)(e,n.apiClient,y,m,"insert-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3579
3596
|
throw e}}k=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3580
3597
|
const M=R.length>0?R[0].path:"document-operation",O=await l.validateTaskId(q,M,o,y,m,v.metricsPrefix),$=O?.requestId
|
|
3581
3598
|
let D=null
|
|
@@ -3597,11 +3614,11 @@ let H=0,B=0,U=0
|
|
|
3597
3614
|
for(const e of R){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3598
3615
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3599
3616
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.insertions)
|
|
3600
|
-
t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,U++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3617
|
+
t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,U++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,p.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}L.push(t)}for(const e of x){const t={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3601
3618
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3602
3619
|
t.filename=s?.filename
|
|
3603
3620
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
|
|
3604
|
-
t.insertions=l,t.successfulInsertions=l.filter((e=>e.success)).length,t.failedInsertions=l.filter((e=>!e.success)).length,t.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&t.successfulInsertions>0?(await c.default.writeFile(o,a,"utf8"),n.documentFileManager.markForSync(e.documentId),t.success=!0,U++,y.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3621
|
+
t.insertions=l,t.successfulInsertions=l.filter((e=>e.success)).length,t.failedInsertions=l.filter((e=>!e.success)).length,t.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&t.successfulInsertions>0?(await c.default.writeFile(o,a,"utf8"),n.documentFileManager.markForSync(e.documentId),t.success=!0,U++,y.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,p.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:t.error})}L.push(t)}if(x.length>0)try{for(const e of x){const t=L.find((t=>t.documentId===e.documentId))
|
|
3605
3622
|
t?.success&&await n.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const G=await l.handleMultiFileGitCommit(q,R,L,U,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:m,metricsPrefix:"insert_lines"},n),W=l.processMultiFileOperationResults(L,"successfulInsertions"),{successfulOperations:V,failedOperations:K,totalSuccessfulChanges:J,overallSuccess:Q,successfulFiles:Y,failedFiles:Z}=W
|
|
3606
3623
|
try{await s.updateToolRecord(I,{metadata:{path:R.length>0?R[0].path:"document:"+x[0]?.documentId,status:Q?"completed":"failed",error:Q?void 0:K+" operations failed",totalOperations:L.length,successfulFiles:Y,failedFiles:Z,operations:N,totalSuccessfulInsertions:J,totalFailedInsertions:H,totalLinesAdded:B,operationsWithChanges:U,processingTime:Date.now()-w,userComment:E,...R.length>0&&G.success&&G.commitHash&&{commitHash:G.commitHash,previousCommitHash:G.previousCommitHash||void 0}},note:Q?`Line insertion completed: ${V}/${L.length} operations successful${R.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${K}/${L.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let X="## Line Insertion Results\n\n"
|
|
3607
3624
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
@@ -3614,22 +3631,22 @@ for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?
|
|
|
3614
3631
|
X+=` - ${t.type} insertion ${e}: ${t.error}\n`}}X+="\n"}}x.length>0&&(X+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3615
3632
|
const ee=Date.now()-w
|
|
3616
3633
|
return y.info("Insert lines operation completed",{duration:ee,success:Q,totalOperations:L.length,successfulOperations:V,failedOperations:K}),m.incrementCounter("insert_lines_total",1,{success:Q}),{content:[{type:"text",text:X}],isError:!Q}}catch(t){const r=Date.now()-w
|
|
3617
|
-
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await s.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,
|
|
3618
|
-
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),
|
|
3634
|
+
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await s.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,p.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,p.getErrorMessage)(t)})}catch(e){}return m.incrementCounter("insert_lines_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,p.getErrorMessage)(t)}],isError:!0}}}
|
|
3635
|
+
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),g=t(9949),p=t(8824),m=t(3255)},6539(e,exports,t){"use strict"
|
|
3619
3636
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
|
|
3620
|
-
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),
|
|
3637
|
+
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),m=t(922)
|
|
3621
3638
|
exports.ClientFactory=class{static async createClient(e,f,y,w={}){(f=f.child({component:"client-factory"})).info("Creating API client with components")
|
|
3622
3639
|
const b=w.tokenManager||new r.TokenManager(f,w.workingDir||process.cwd())
|
|
3623
3640
|
await b.initialize()
|
|
3624
3641
|
const I=w.tokenSynchronizer||new i.ClientTokenSynchronizer(f),k=new s.AuthenticationManager(b,f,I),v=await k.getTokenString(),C=w.connectionStatusManager||new n.ConnectionStatusManager(e,f,y,{alchemyPath:w.alchemyPath,checkIntervalMs:w.offlineCheckIntervalMs,timeoutMs:w.timeout,retryCount:w.retryAttempts}),_=new c.ProjectClient(e,f,y,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3625
3642
|
I.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3626
|
-
const E=new
|
|
3643
|
+
const E=new p.TaskClient(e,f,y,_,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3627
3644
|
I.registerClient(E)
|
|
3628
3645
|
const S=new a.FileOperationsClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3629
3646
|
I.registerClient(S),f.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
3630
3647
|
const T=new u.RequestClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3631
3648
|
I.registerClient(T),f.info("RequestClient post-constructor token: "+(T.getAuthToken()?"present":"missing"))
|
|
3632
|
-
const q=new
|
|
3649
|
+
const q=new g.DocumentClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3633
3650
|
I.registerClient(q)
|
|
3634
3651
|
const P=new m.ToolRecordClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3635
3652
|
I.registerClient(P)
|
|
@@ -3651,7 +3668,7 @@ if(_)try{await _.connectStdio(),(0,a.isDebugToolsEnabled)()&&b.info("Connected s
|
|
|
3651
3668
|
throw b.error("Failed to connect stdio transport",{errorDetails:t}),e}else b.error("No global server instance available to connect transport")
|
|
3652
3669
|
return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3653
3670
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
3654
|
-
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),
|
|
3671
|
+
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(8824),p=t(9939),m=t(7960),f=process.argv.slice(2),y=f[0]||process.cwd(),w=s.default.resolve(y)
|
|
3655
3672
|
console.error("\n=== MCP STARTUP DIAGNOSTICS ==="),console.error("Script path (process.argv[1]):",process.argv[1]),console.error("Base directory:",w),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")
|
|
3656
3673
|
const b=(0,a.createEnvLogger)({serviceName:"direct-mcp-server",console:!0,baseDir:w});(0,a.isDebugToolsEnabled)()?b.info("MCP Direct server initializing",{baseDir:w,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL,pid:process.pid}):b.info("MCP Direct server starting"),console.log=function(...e){console.error("[LOG]",...e)},console.info=function(...e){console.error("[INFO]",...e)},console.warn=function(...e){console.error("[WARN]",...e)},process.on("uncaughtException",(e=>{if(b.error("UNCAUGHT EXCEPTION: "+e,{stack:e.stack||"No stack available"}),_)try{_.cleanupSSEConnection()}catch(e){b.error("Error during cleanup after uncaught exception: "+e)}setTimeout((()=>process.exit(1)),500)})),process.on("unhandledRejection",(e=>{b.error("UNHANDLED REJECTION: "+e,{stack:e instanceof Error?e.stack:"No stack available"})})),process.on("exit",(e=>{b.info("Process exiting with code: "+e)}))
|
|
3657
3674
|
const I=process.stdout.write
|
|
@@ -3662,7 +3679,7 @@ let v=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com"
|
|
|
3662
3679
|
const C=global.__serverInitialized
|
|
3663
3680
|
void 0===C?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&b.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&b.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
|
|
3664
3681
|
let _=null
|
|
3665
|
-
try{(0,d.acquireProcessLock)(w)||(b.error(`Process lock acquisition failed for ${w}. Another instance may be running.`),b.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&b.info("Multi-agent mode enabled - allowing concurrent access to "+w)}catch(e){b.error("Lock acquisition threw exception",{error:(0,
|
|
3682
|
+
try{(0,d.acquireProcessLock)(w)||(b.error(`Process lock acquisition failed for ${w}. Another instance may be running.`),b.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&b.info("Multi-agent mode enabled - allowing concurrent access to "+w)}catch(e){b.error("Lock acquisition threw exception",{error:(0,g.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(b.info("============================================================"),b.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),b.info("BASE DIR: "+w),b.info("ALCHEMY PATH: "+s.default.join(w,h.ALCHEMY_DIR_NAME)),b.info("PROJECT PATH: "+s.default.join(w,h.ALCHEMY_DIR_NAME+"/project.json")),b.info("MULTI-AGENT MODE: true"),b.info("MCP client information will be captured during protocol initialization")),b.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(b.info("============================================================"),b.info("Base directory: "+w),b.info("Remote server URL: "+v),b.info("Node version: "+process.version),b.info("Current working directory: "+process.cwd()),b.info("ALLOWED_DIRECTORIES env var: not used"),b.info("Server already initialized: "+(C?"YES":"NO"))),C&&((0,a.isDebugToolsEnabled)()&&(b.info("Server already initialized globally, reusing existing server instance"),b.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3666
3683
|
b.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
|
|
3667
3684
|
try{const e=u.default.existsSync(w)
|
|
3668
3685
|
if((0,a.isDebugToolsEnabled)()&&b.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=u.default.statSync(w)
|
|
@@ -3670,8 +3687,8 @@ b.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(
|
|
|
3670
3687
|
if(!u.default.existsSync(E))try{u.default.mkdirSync(E,{recursive:!0}),(0,a.isDebugToolsEnabled)()&&b.info("Created alchemy lab directory: "+E)}catch(e){b.error("Failed to create alchemy lab directory: "+e)}try{(async function(){try{v=await async function(){if(process.env.REMOTE_SERVER_URL)return process.env.REMOTE_SERVER_URL
|
|
3671
3688
|
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(b),n=await r.getInstallationConfig()
|
|
3672
3689
|
if(n.remoteServerUrl)return(0,a.isDebugToolsEnabled)()&&b.info("Loaded REMOTE_SERVER_URL from installation config",{remoteServerUrl:n.remoteServerUrl}),n.remoteServerUrl}catch(e){(0,a.isDebugToolsEnabled)()&&b.debug("Could not read REMOTE_SERVER_URL from installation config",{error:e instanceof Error?e.message:"Unknown error"})}return"https://api.alchemylabcode.com"}()
|
|
3673
|
-
try{const e=await(0,
|
|
3674
|
-
e.errors.length>0&&b.warn("Some plugins failed to sync",{errors:e.errors}),await(0,
|
|
3690
|
+
try{const e=await(0,p.syncPluginsGlobal)((0,m.isDevBuild)(),b)
|
|
3691
|
+
e.errors.length>0&&b.warn("Some plugins failed to sync",{errors:e.errors}),await(0,p.cleanupLegacyProjectPlugins)(w,b)}catch(e){b.warn("Plugin sync failed",{error:e instanceof Error?e.message:"Unknown error"})}(0,a.isDebugToolsEnabled)()&&(b.info("Creating MCP server with base dir: "+w),b.info("Using remote server URL: "+v))
|
|
3675
3692
|
const e=await(0,i.createServer)(w,b,k,v)
|
|
3676
3693
|
_=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&b.info("MCP server created successfully")
|
|
3677
3694
|
const n=r()
|
|
@@ -3706,7 +3723,7 @@ const n=[],o=[...t].sort(((e,t)=>{const r=e=>"number"==typeof e?e:Array.isArray(
|
|
|
3706
3723
|
return r(t.lines)-r(e.lines)}))
|
|
3707
3724
|
for(const e of o){const t={lines:e.lines,success:!1}
|
|
3708
3725
|
try{const n=(0,m.replaceLines)(r,e.lines,e.content)
|
|
3709
|
-
r=n.newContent,t.success=!0,t.linesReplaced=n.linesReplaced,t.linesAdded=n.linesAdded,t.startLine=n.startLine,t.endLine=n.endLine}catch(e){t.error=(0,
|
|
3726
|
+
r=n.newContent,t.success=!0,t.linesReplaced=n.linesReplaced,t.linesAdded=n.linesAdded,t.startLine=n.startLine,t.endLine=n.endLine}catch(e){t.error=(0,p.getErrorMessage)(e)}n.push(t)}return{newContent:r,results:n}}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3710
3727
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3711
3728
|
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=[]
|
|
3712
3729
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3729,7 +3746,7 @@ x.push({type:"file",path:t,fullPath:r,replacements:e.replacements.map((e=>({line
|
|
|
3729
3746
|
if(R.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3730
3747
|
for(const e of R)M.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,f.parseLineSpec)(e.lines),content:e.content})))})
|
|
3731
3748
|
if(M.length>0&&n.apiClient){const e=M.map((e=>e.documentId))
|
|
3732
|
-
try{await(0,
|
|
3749
|
+
try{await(0,g.ensureDocumentsNotLocked)(e,n.apiClient,w,m,"replace-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3733
3750
|
throw e}}v=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3734
3751
|
const O=x.length>0?x[0].path:"document-operation",$=await l.validateTaskId(P,O,o,w,m,C.metricsPrefix),D=$?.requestId
|
|
3735
3752
|
let A=null
|
|
@@ -3751,11 +3768,11 @@ let B=0,U=0,G=0,W=0
|
|
|
3751
3768
|
for(const e of x){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3752
3769
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3753
3770
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.replacements)
|
|
3754
|
-
t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,t.totalLinesReplaced=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulReplacements>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,W++,w.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),B+=t.failedReplacements,U+=t.totalLinesReplaced,G+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3771
|
+
t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,t.totalLinesReplaced=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulReplacements>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,W++,w.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),B+=t.failedReplacements,U+=t.totalLinesReplaced,G+=t.totalLinesAdded}catch(r){t.error=(0,p.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("File operation failed",{path:e.path,error:t.error})}H.push(t)}for(const e of M){const t={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3755
3772
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3756
3773
|
t.filename=s?.filename
|
|
3757
3774
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
|
|
3758
|
-
t.replacements=l,t.successfulReplacements=l.filter((e=>e.success)).length,t.failedReplacements=l.filter((e=>!e.success)).length,t.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&t.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),n.documentFileManager.markForSync(e.documentId),t.success=!0,W++,w.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),B+=t.failedReplacements,U+=t.totalLinesReplaced,G+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3775
|
+
t.replacements=l,t.successfulReplacements=l.filter((e=>e.success)).length,t.failedReplacements=l.filter((e=>!e.success)).length,t.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&t.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),n.documentFileManager.markForSync(e.documentId),t.success=!0,W++,w.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),B+=t.failedReplacements,U+=t.totalLinesReplaced,G+=t.totalLinesAdded}catch(r){t.error=(0,p.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:t.error})}H.push(t)}if(M.length>0)try{for(const e of M){const t=H.find((t=>t.documentId===e.documentId))
|
|
3759
3776
|
t?.success&&await n.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const V=await l.handleMultiFileGitCommit(P,x,H,W,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:m,metricsPrefix:"replace_lines"},n),K=l.processMultiFileOperationResults(H,"successfulReplacements"),{successfulOperations:J,failedOperations:Q,totalSuccessfulChanges:Y,overallSuccess:Z,successfulFiles:X,failedFiles:ee}=K
|
|
3760
3777
|
try{await s.updateToolRecord(k,{metadata:{path:x.length>0?x[0].path:"document:"+M[0]?.documentId,status:Z?"completed":"failed",error:Z?void 0:Q+" operations failed",totalOperations:H.length,successfulFiles:X,failedFiles:ee,operations:z,totalSuccessfulReplacements:Y,totalFailedReplacements:B,totalLinesReplaced:U,totalLinesAdded:G,operationsWithChanges:W,processingTime:Date.now()-b,userComment:S,...x.length>0&&V.success&&V.commitHash&&{commitHash:V.commitHash,previousCommitHash:V.previousCommitHash||void 0}},note:Z?`Line replacement completed: ${J}/${H.length} operations successful${x.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${Q}/${H.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let te="## Line Replacement Results\n\n"
|
|
3761
3778
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
@@ -3766,14 +3783,14 @@ for(const e of H){if("file"===e.type?te+=`### File: ${e.path}\n`:(te+="### Docum
|
|
|
3766
3783
|
for(const t of e.replacements.filter((e=>!e.success)))te+=` - 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`}te+="\n"}}M.length>0&&(te+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3767
3784
|
const re=Date.now()-b
|
|
3768
3785
|
return w.info("Replace lines operation completed",{duration:re,success:Z,totalOperations:H.length,successfulOperations:J,failedOperations:Q}),m.incrementCounter("replace_lines_total",1,{success:Z}),{content:[{type:"text",text:te}],isError:!Z}}catch(t){const r=Date.now()-b
|
|
3769
|
-
if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),k)try{await s.updateToolRecord(k,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,
|
|
3770
|
-
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),
|
|
3786
|
+
if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),k)try{await s.updateToolRecord(k,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,p.getErrorMessage)(t),phase:v,duration:r,userComment:e?.comment},note:"Line replacement failed: "+(0,p.getErrorMessage)(t)})}catch(e){}return m.incrementCounter("replace_lines_errors",1,{phase:v}),{content:[{type:"text",text:"\u274c **Replace Lines Failed:** "+(0,p.getErrorMessage)(t)}],isError:!0}}}
|
|
3787
|
+
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),g=t(9949),p=t(8824),m=t(3255),f=t(9470)},6656(e,exports,t){"use strict"
|
|
3771
3788
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreatePlan=async function(e,t,o,s,i,a,c){const l=e.kind??"plan",d=n.KIND_META[l],u="quest"===l,h=s.child({tool:"plan_operations",operation:u?"create-quest":"create"})
|
|
3772
3789
|
try{const s=t.projectId
|
|
3773
3790
|
if(!s)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
|
|
3774
|
-
const i=e.name.replace(/\.md$/i,""),a=`${d.filenamePrefix}${i}.md`,l=o.getDocumentClient(),
|
|
3775
|
-
if(
|
|
3776
|
-
const
|
|
3791
|
+
const i=e.name.replace(/\.md$/i,""),a=`${d.filenamePrefix}${i}.md`,l=o.getDocumentClient(),g=await l.listDocuments({type:d.docType,filename:a,limit:1,offset:0})
|
|
3792
|
+
if(g&&g.length>0)return{content:[{type:"text",text:`\u274c A ${d.label} with filename "${a}" already exists (${g[0].localId||g[0].id}). Choose a different name.`}],isError:!0}
|
|
3793
|
+
const p=u?{criteria:e.criteria||"",status:n.QUEST_STATUS_OPEN,tickIntervalSeconds:e.tickIntervalSeconds??n.QUEST_DEFAULTS.tickIntervalSeconds,maxInFlight:e.maxInFlight??n.QUEST_DEFAULTS.maxInFlight,maxPerDay:e.maxPerDay??n.QUEST_DEFAULTS.maxPerDay,minIterations:e.minIterations??n.QUEST_DEFAULTS.minIterations}:void 0,m=await l.createDocument(void 0,{filename:a,content:e.content,type:d.docType,...p&&{metadata:p},...c&&{cliOrigin:c}}),f=m.localId||m.id,y=m.id
|
|
3777
3794
|
let w=!1
|
|
3778
3795
|
if(d.canBeActivePlan)try{const e=o.getProjectClient(),t=await e.getProject(s)
|
|
3779
3796
|
t&&!t.activePlanId&&(await e.updateProject(s,{activePlanId:y}),w=!0,h.info("Auto-set as active plan",{planId:f,projectId:s}))}catch(e){h.warn("Failed to auto-set active plan",{error:(0,r.getErrorMessage)(e)})}return h.info(""+d.headingCreated,{planId:f,filename:a}),{content:[{type:"text",text:`\u2705 **${d.headingCreated}**\n\n**${d.idLabel}:** ${f}\n**Filename:** ${a}\n**Created:** `+new Date(m.createdAt).toLocaleString()+(w?"\n\n\u{1f4cc} _Automatically set as the active project plan._":"")}]}}catch(e){return h.error("Failed to "+d.errorVerb,{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:`\u274c **Failed to ${d.errorVerb}:** ${(0,r.getErrorMessage)(e)}`}],isError:!0}}}
|
|
@@ -3853,19 +3870,19 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3853
3870
|
var t={}
|
|
3854
3871
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3855
3872
|
return o(t,e),t})
|
|
3856
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTaskFileHistory=async function(e,t,r,n,o){const s=n.child({tool:"task_file_history"}),
|
|
3857
|
-
try{const{taskId:
|
|
3858
|
-
if(!
|
|
3859
|
-
if(!(0,h.isTaskRef)(
|
|
3860
|
-
s.info("Getting file changes for task "+
|
|
3873
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTaskFileHistory=async function(e,t,r,n,o){const s=n.child({tool:"task_file_history"}),g=o.startTimer("tool_execution_time")
|
|
3874
|
+
try{const{taskId:p,showDiff:m=!1}=e
|
|
3875
|
+
if(!p)throw(0,i.createValidationError)("Task ID is required")
|
|
3876
|
+
if(!(0,h.isTaskRef)(p))throw(0,i.createValidationError)(`Invalid task ID format: ${p}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
|
|
3877
|
+
s.info("Getting file changes for task "+p,{showDiff:m})
|
|
3861
3878
|
const f=r.getTaskClient(),y=r.getToolRecordClient(),w=t.projectId
|
|
3862
3879
|
let b
|
|
3863
3880
|
r.setProjectId(w)
|
|
3864
|
-
try{const j=await f.getTask(
|
|
3865
|
-
s.info("Raw task response data",{responseDataType:typeof j,isArray:Array.isArray(j),hasData:null!=j,properties:j&&"object"==typeof j?Object.keys(j):[]}),b=(0,l.extractDataFromResponse)(j,{logger:s,operationName:"getTask",defaultValue:{id:
|
|
3866
|
-
try{const x=await y.getToolRecordsByTaskId(
|
|
3867
|
-
if(s.info("Raw records response data",{responseDataType:typeof x,isArray:Array.isArray(x),hasData:null!=x,properties:x&&"object"==typeof x?Object.keys(x):[]}),I=(0,l.extractArrayFromResponse)(x,{logger:s,operationName:"searchRecords",defaultValue:[]}),I.length>0&&s.info("First record summary:",{id:I[0].id,type:I[0].type,hasMetadata:!!I[0].metadata,hasCommitHash:!!I[0].metadata?.commitHash}),s.info(`Extracted ${I.length} records for task ${
|
|
3868
|
-
I.forEach((e=>{M[e.type]=(M[e.type]||0)+1})),s.info("Record type distribution:",M)}}catch(O){s.warn("Error fetching records for task "+
|
|
3881
|
+
try{const j=await f.getTask(p)
|
|
3882
|
+
s.info("Raw task response data",{responseDataType:typeof j,isArray:Array.isArray(j),hasData:null!=j,properties:j&&"object"==typeof j?Object.keys(j):[]}),b=(0,l.extractDataFromResponse)(j,{logger:s,operationName:"getTask",defaultValue:{id:p,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+b.title)}catch(R){s.warn("Could not fetch task information: "+(0,u.getErrorMessage)(R)),b={id:p,title:"Unknown Task",status:"unknown",description:"No description available"}}let I=[]
|
|
3883
|
+
try{const x=await y.getToolRecordsByTaskId(p)
|
|
3884
|
+
if(s.info("Raw records response data",{responseDataType:typeof x,isArray:Array.isArray(x),hasData:null!=x,properties:x&&"object"==typeof x?Object.keys(x):[]}),I=(0,l.extractArrayFromResponse)(x,{logger:s,operationName:"searchRecords",defaultValue:[]}),I.length>0&&s.info("First record summary:",{id:I[0].id,type:I[0].type,hasMetadata:!!I[0].metadata,hasCommitHash:!!I[0].metadata?.commitHash}),s.info(`Extracted ${I.length} records for task ${p}`),I.length>0){const M={}
|
|
3885
|
+
I.forEach((e=>{M[e.type]=(M[e.type]||0)+1})),s.info("Record type distribution:",M)}}catch(O){s.warn("Error fetching records for task "+p,{error:(0,u.getErrorMessage)(O)}),I=[]}if(0===I.length)return g({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${p}.`}]}
|
|
3869
3886
|
function k(e){const t=new Map,r=new Map,n=[]
|
|
3870
3887
|
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
|
|
3871
3888
|
if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
|
|
@@ -3886,7 +3903,7 @@ if(t&&(n=e.metadata.successfulOperations.some((e=>e&&e.source&&e.destination))),
|
|
|
3886
3903
|
if(!Array.isArray(t)||0===t.length)return s.warn("Skipping delete-files record without valid paths array: "+e.id),!1
|
|
3887
3904
|
if(!t.every((e=>"string"==typeof e&&e.trim().length>0)))return s.warn("Skipping delete-files record without valid file paths: "+e.id),!1}return!0}))
|
|
3888
3905
|
if(s.info(`Found ${C.length} file operation records`),C.length>0){const $={}
|
|
3889
|
-
C.forEach((e=>{$[e.type]=($[e.type]||0)+1})),s.info("Filtered record type distribution:",$)}if(0===C.length)return
|
|
3906
|
+
C.forEach((e=>{$[e.type]=($[e.type]||0)+1})),s.info("Filtered record type distribution:",$)}if(0===C.length)return g({success:!0,fileChanges:0}),{content:[{type:"text",text:`No file changes found for task ${p}.`}]}
|
|
3890
3907
|
const _=new Map
|
|
3891
3908
|
C.forEach((e=>{let t=null
|
|
3892
3909
|
if(e.metadata){if(!e.metadata.commitHash){const t=["gitCommitId","commitId","commit","gitCommit"]
|
|
@@ -3938,9 +3955,9 @@ s.info(`Getting new file content using git show: ${B.commitHash?B.commitHash.sub
|
|
|
3938
3955
|
const de=await t.git.show(le)
|
|
3939
3956
|
if(de&&de.trim().length>0){let ue=""
|
|
3940
3957
|
const he=de.split("\n")
|
|
3941
|
-
for(const
|
|
3958
|
+
for(const ge of he)ue+=`+${ge}\n`
|
|
3942
3959
|
E.set(F,{firstChange:W,lastChange:B,hasDiff:!0,diffText:ue}),s.info(`Formatted new file content as diff, ${he.length} lines`)
|
|
3943
|
-
continue}}catch(
|
|
3960
|
+
continue}}catch(pe){s.warn("Error getting new file content for "+F,{error:(0,u.getErrorMessage)(pe)})}E.set(F,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"Only one commit available for this file"})
|
|
3944
3961
|
continue}if(H.commitHash===B.commitHash&&G){if(U===H.commitHash){E.set(F,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"No changes detected"})
|
|
3945
3962
|
continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let V="",K=!1
|
|
3946
3963
|
if(m||"pre-task"!==W.status){try{if(t.git){try{await t.git.show([`${B.commitHash}:${F}`])}catch(fe){s.warn(`File ${F} does not exist in commit ${B.commitHash}, might be deleted or moved`),V="File was deleted or moved from this location during the task",K=!0,E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V})
|
|
@@ -3955,7 +3972,7 @@ if(_e&&_e.trim().length>0){if(m){let Ee=""
|
|
|
3955
3972
|
const Se=_e.split("\n")
|
|
3956
3973
|
for(const Te of Se)Ee+=`+${Te}\n`
|
|
3957
3974
|
V=Ee}else V="File created during this task. Content:\n"+_e
|
|
3958
|
-
K=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(qe){s.warn("Fallback also failed for "+F,{error:qe instanceof Error?qe.message:qe+""})}}E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V||"No changes detected between commits"})}else K=W.commitHash!==B.commitHash,V=K?"File has changes":"No changes detected between commits",E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V})}let S=`# File Changes for Task: ${
|
|
3975
|
+
K=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(qe){s.warn("Fallback also failed for "+F,{error:qe instanceof Error?qe.message:qe+""})}}E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V||"No changes detected between commits"})}else K=W.commitHash!==B.commitHash,V=K?"File has changes":"No changes detected between commits",E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V})}let S=`# File Changes for Task: ${p}\n\n`
|
|
3959
3976
|
b&&"object"==typeof b&&(S+="## Task Information\n",S+=`- **Title**: ${b.title||"Unknown"}\n`,S+=`- **Status**: ${b.status||"Unknown"}\n`,S+=`- **Description**: ${b.description||"No description"}\n\n`)
|
|
3960
3977
|
const T=3e3
|
|
3961
3978
|
let q=0,P=!1
|
|
@@ -3968,7 +3985,7 @@ try{await a.access(Oe),$e=!0}catch{}S+=`### ${Re} ${$e?"":"(Deleted)"}\n\n`
|
|
|
3968
3985
|
const De=new Date(xe.firstChange.timestamp).toLocaleString(),Ae=new Date(xe.lastChange.timestamp).toLocaleString()
|
|
3969
3986
|
S+=`**First Change**: ${De}\n`,S+=`**Last Change**: ${Ae}\n`,"pre-task"===xe.firstChange.status&&xe.firstChange.commitHash?S+=`**Pre-Task Commit**: ${xe.firstChange.commitHash.substring(0,8)}\n`:xe.firstChange.commitHash&&(S+=`**File Created During Task**: ${xe.firstChange.commitHash.substring(0,8)}\n`),xe.lastChange.commitHash&&(S+=`**Final Commit**: ${xe.lastChange.commitHash.substring(0,8)}\n`)
|
|
3970
3987
|
const Fe=v.sourceToMove.get(Re),Ne=v.destToMove.get(Re)
|
|
3971
|
-
Fe?S+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Fe.destination}**\n`:Ne&&(S+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Ne.source}**\n`),m&&!P?xe.hasDiff?(S+="\n**Changes**:\n",S+="```diff\n",S+=xe.diffText,S+="\n```\n\n"):S+=`\n**Note**: ${xe.diffText}\n\n`:P&&xe.hasDiff?(S+=`\n**Note**: File has changes (${xe.diffText?xe.diffText.split("\n").length:0} lines). `,S+=`Compare ${xe.firstChange.commitHash?xe.firstChange.commitHash.substring(0,8):"unknown"}..${xe.lastChange.commitHash?xe.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):xe.hasDiff?S+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":S+=`\n**Note**: ${xe.diffText}\n\n`,S+="---\n\n"}return
|
|
3988
|
+
Fe?S+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Fe.destination}**\n`:Ne&&(S+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Ne.source}**\n`),m&&!P?xe.hasDiff?(S+="\n**Changes**:\n",S+="```diff\n",S+=xe.diffText,S+="\n```\n\n"):S+=`\n**Note**: ${xe.diffText}\n\n`:P&&xe.hasDiff?(S+=`\n**Note**: File has changes (${xe.diffText?xe.diffText.split("\n").length:0} lines). `,S+=`Compare ${xe.firstChange.commitHash?xe.firstChange.commitHash.substring(0,8):"unknown"}..${xe.lastChange.commitHash?xe.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):xe.hasDiff?S+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":S+=`\n**Note**: ${xe.diffText}\n\n`,S+="---\n\n"}return g({success:!0,fileCount:_.size}),{content:[{type:"text",text:S}]}}catch(ze){return s.error("Error in task file history tool",{error:ze instanceof Error?ze.stack:ze+""}),g({success:!1,error:ze instanceof Error?ze.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,u.getErrorMessage)(ze)}],isError:!0}}}
|
|
3972
3989
|
const i=t(9860),a=s(t(1943)),c=t(9671),l=t(2960),d=s(t(5967)),u=t(8824),h=t(4466)},6928(module){"use strict"
|
|
3973
3990
|
module.exports=require("path")},6975(e,exports,t){"use strict"
|
|
3974
3991
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
|
|
@@ -4102,9 +4119,9 @@ i.existsSync(n)||i.mkdirSync(n,{recursive:!0})
|
|
|
4102
4119
|
const s=(new Date).toISOString(),l=Object.keys(r).length?" "+JSON.stringify(r):""
|
|
4103
4120
|
i.appendFileSync(o,`[${s}] ${e} | ${t}${l}\n`)}catch(e){}}
|
|
4104
4121
|
const i=s(t(9896)),a=s(t(6928)),c=s(t(857))},7334(e,exports,t){"use strict"
|
|
4105
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,c,l,d,u,h){const
|
|
4106
|
-
|
|
4107
|
-
const
|
|
4122
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,c,l,d,u,h){const g=l.child({tool:"create_request"})
|
|
4123
|
+
g.info("Creating new request",{args:e})
|
|
4124
|
+
const p=d.startTimer("tool_handler_duration")
|
|
4108
4125
|
try{const l=function(e){try{return e}catch(e){if(e instanceof s.ZodError&&e.errors.length>0)throw new r.ValidationError(e.errors[0].message)
|
|
4109
4126
|
throw new r.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
|
|
4110
4127
|
d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
|
|
@@ -4118,25 +4135,25 @@ if(e){const t=c.getCLISessionClient()
|
|
|
4118
4135
|
if(t){const r=await t.getByExternalId(e)
|
|
4119
4136
|
if(r?.workflowId){const e=await c.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
|
|
4120
4137
|
t?.approvalMode&&(y=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===y)try{const e=await c.proxyGet("/api/projects/"+m),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
|
|
4121
|
-
r&&(y=(0,a.getApprovalMode)(r))}catch(e){
|
|
4138
|
+
r&&(y=(0,a.getApprovalMode)(r))}catch(e){g.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){g.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const w="require-approval"===y&&"quick-edit"!==l.type?"pending_approval":"open"
|
|
4122
4139
|
let b=h
|
|
4123
4140
|
if(h?.sessionId)try{const e=c.getCLISessionClient()
|
|
4124
4141
|
if(e){const t=await e.getByExternalId(h.sessionId)
|
|
4125
|
-
"planner"!==t?.agentType&&"auto-planner"!==t?.agentType||(b=void 0,
|
|
4126
|
-
|
|
4142
|
+
"planner"!==t?.agentType&&"auto-planner"!==t?.agentType||(b=void 0,g.info("Skipping cliOrigin for planner-created request",{agentType:t.agentType}))}}catch{}const I={title:l.title,description:l.description,type:l.type,acceptanceCriteria:l.acceptanceCriteria,status:w,...l.planDocumentId&&{planDocumentId:l.planDocumentId},...l.questDocumentId&&{questDocumentId:l.questDocumentId},...b&&{cliOrigin:b}}
|
|
4143
|
+
g.info("Creating request via request client",{projectId:m,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
|
|
4127
4144
|
const k=await f.createRequest(I)
|
|
4128
|
-
|
|
4129
|
-
const v=(0,o.extractDataFromResponse)(k,{logger:
|
|
4145
|
+
g.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"})
|
|
4146
|
+
const v=(0,o.extractDataFromResponse)(k,{logger:g,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
|
|
4130
4147
|
let _,E={created:!1}
|
|
4131
|
-
if(u?.workspaceManager)try{await u.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},
|
|
4132
|
-
|
|
4148
|
+
if(u?.workspaceManager)try{await u.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},g.info("Request branch initialized successfully",{requestId:C.id,branchName:E.branchName,title:C.title})}catch(e){g.warn("Failed to initialize request branch, will retry on first operation",{requestId:C.id,error:(0,i.getErrorMessage)(e)})}else"quick-edit"===l.type?g.info("Quick-edit request - skipping branch creation, will work directly on main",{requestId:C.id}):g.debug("No workspace manager available, branch creation deferred",{requestId:C.id})
|
|
4149
|
+
g.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
|
|
4133
4150
|
try{const e=c.getToolRecordClient()
|
|
4134
4151
|
if(e){const t=await e.createToolRecord({requestId:C.id,projectId:m,type:"create-request",metadata:{status:"completed",timestamp:(new Date).toISOString(),requestType:C.type,requestTitle:C.title,requestDescription:C.description,criteriaCount:C.acceptanceCriteria.length,branchCreated:E.created,branchName:E.created?E.branchName:null},note:`Created request "${C.title}" of type ${C.type}${E.created?" with branch "+E.branchName:" - branch will be created on first file operation"}`})
|
|
4135
|
-
_=t?.id}}catch(e){
|
|
4152
|
+
_=t?.id}}catch(e){g.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:C.id})}p({success:!0,type:l.type,hasProjectId:!0}),g.info("Request created successfully",{requestId:C.id,title:C.title,type:C.type,projectId:m})
|
|
4136
4153
|
const S=C.localId||C.id
|
|
4137
|
-
return{content:[{type:"text",text:"pending_approval"===w?`Created Request ${S} (pending approval)`:"Created Request "+S}],...(0,n.alchemyMeta)({kind:"create-request",toolRecordId:_})}}catch(r){if(
|
|
4154
|
+
return{content:[{type:"text",text:"pending_approval"===w?`Created Request ${S} (pending approval)`:"Created Request "+S}],...(0,n.alchemyMeta)({kind:"create-request",toolRecordId:_})}}catch(r){if(g.error("Failed to create request",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new requests")||r.message.includes("disabled due to tier limits")))g.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
|
|
4138
4155
|
else{const n=c.getToolRecordClient()
|
|
4139
|
-
n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){
|
|
4156
|
+
n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){g.error("Failed to create failure record for request creation",{error:e instanceof Error?e.message:e+""})}if(p({success:!1,error:r instanceof Error?r.name:"unknown"}),r instanceof s.ZodError&&r.errors.length>0){const e=r.errors[0]
|
|
4140
4157
|
let t=e.message
|
|
4141
4158
|
return e.path.includes("acceptanceCriteria")&&(t=`Acceptance criteria: ${t}. Please provide a list of criteria descriptions.`),{content:[{type:"text",text:"Error: "+t}],isError:!0}}let n=(0,i.getErrorMessage)(r),o="Unable to create request. Please check your input and try again."
|
|
4142
4159
|
return(n.includes("Project cannot accept new requests")||n.includes("Project is inactive due to tier limits"))&&(o="This project is currently inactive due to tier limits. Only your oldest projects can accept new requests. Please use an active project or upgrade your tier for more simultaneous projects."),{content:[{type:"text",text:`Error: ${n}\n\n${o}`}],isError:!0}}}
|
|
@@ -4156,13 +4173,13 @@ default:throw Error(`Unknown operation: ${c}. Valid operations: get-info, list`)
|
|
|
4156
4173
|
const h=i[c]
|
|
4157
4174
|
return h?(0,s.withAlchemyKind)(u,h):u}catch(e){return d.error("task_inspect failed",{error:e instanceof Error?e.stack:e+""}),l.incrementCounter("task_inspect_errors",1),{content:[{type:"text",text:"\u274c **Task Inspect Failed:** "+(0,o.getErrorMessage)(e)}],isError:!0}}}
|
|
4158
4175
|
const r=t(3420),n=t(9863),o=t(8824),s=t(2272),i={"get-info":"get-task-info",list:"list-tasks"}},7456(e,exports,t){"use strict"
|
|
4159
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,i,a,c,l,d,u,h){const
|
|
4160
|
-
try{const s=e,{operations:
|
|
4176
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,i,a,c,l,d,u,h){const g=d.child({tool:"modify_file"})
|
|
4177
|
+
try{const s=e,{operations:p,comment:m}=s,{enforceActiveTask:f}=await Promise.resolve().then(t.bind(t,3451)),y=await f(i,a,d,e.taskId)
|
|
4161
4178
|
if("errorResult"in y)return y.errorResult
|
|
4162
4179
|
const{taskId:w}=y
|
|
4163
|
-
|
|
4180
|
+
g.info("Processing modify-file operations",{taskId:w,operationCount:p.length,comment:m})
|
|
4164
4181
|
const b=[],I=[],k=[],v=[],C=[]
|
|
4165
|
-
for(const e of
|
|
4182
|
+
for(const e of p){const t={path:e.path,documentId:e.documentId}
|
|
4166
4183
|
switch(e.operationType){case"replace-string":b.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
|
|
4167
4184
|
break
|
|
4168
4185
|
case"insert-lines":I.push({...t,insertions:e.insertLines.insertions})
|
|
@@ -4172,42 +4189,42 @@ break
|
|
|
4172
4189
|
case"delete-string":v.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
|
|
4173
4190
|
break
|
|
4174
4191
|
case"delete-lines":C.push({...t,lines:e.deleteLines.lines})}}const _=[]
|
|
4175
|
-
if(b.length>0){
|
|
4176
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:b,comment:m+" [via modify-file: replace-string]"},i,a,c,l,
|
|
4177
|
-
_.push({type:"replace-string",result:e})}if(I.length>0){
|
|
4178
|
-
const e=await(0,n.handleInsertLines)({taskId:w,operations:I,comment:m+" [via modify-file: insert-lines]"},i,a,c,l,
|
|
4179
|
-
_.push({type:"insert-lines",result:e})}if(k.length>0){
|
|
4180
|
-
const e=await(0,o.handleReplaceLines)({taskId:w,operations:k,comment:m+" [via modify-file: replace-lines]"},i,a,c,l,
|
|
4181
|
-
_.push({type:"replace-lines",result:e})}if(v.length>0){
|
|
4182
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:v,comment:m+" [via modify-file: delete-string]"},i,a,c,l,
|
|
4183
|
-
_.push({type:"delete-string",result:e})}if(C.length>0){
|
|
4184
|
-
const e=C.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),t=await(0,o.handleReplaceLines)({taskId:w,operations:e,comment:m+" [via modify-file: delete-lines]"},i,a,c,l,
|
|
4192
|
+
if(b.length>0){g.info("Routing to replace-strings handler",{operationCount:b.length})
|
|
4193
|
+
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:b,comment:m+" [via modify-file: replace-string]"},i,a,c,l,g,u,h)
|
|
4194
|
+
_.push({type:"replace-string",result:e})}if(I.length>0){g.info("Routing to insert-lines handler",{operationCount:I.length})
|
|
4195
|
+
const e=await(0,n.handleInsertLines)({taskId:w,operations:I,comment:m+" [via modify-file: insert-lines]"},i,a,c,l,g,u,h)
|
|
4196
|
+
_.push({type:"insert-lines",result:e})}if(k.length>0){g.info("Routing to replace-lines handler",{operationCount:k.length})
|
|
4197
|
+
const e=await(0,o.handleReplaceLines)({taskId:w,operations:k,comment:m+" [via modify-file: replace-lines]"},i,a,c,l,g,u,h)
|
|
4198
|
+
_.push({type:"replace-lines",result:e})}if(v.length>0){g.info("Routing delete-string to replace-strings handler",{operationCount:v.length})
|
|
4199
|
+
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:v,comment:m+" [via modify-file: delete-string]"},i,a,c,l,g,u,h)
|
|
4200
|
+
_.push({type:"delete-string",result:e})}if(C.length>0){g.info("Processing delete-lines operations",{operationCount:C.length})
|
|
4201
|
+
const e=C.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),t=await(0,o.handleReplaceLines)({taskId:w,operations:e,comment:m+" [via modify-file: delete-lines]"},i,a,c,l,g,u,h)
|
|
4185
4202
|
_.push({type:"delete-lines",result:t})}const E=_.some((e=>e.result.isError)),S=_.filter((e=>!e.result.isError)).length,T=_.filter((e=>e.result.isError)).length
|
|
4186
4203
|
let q="## Modify File Results\n\n"
|
|
4187
4204
|
q+="**Summary:**\n",q+=`- **Total operation types:** ${_.length}\n`,q+=`- **Successful:** ${S}\n`,q+=`- **Failed:** ${T}\n\n`
|
|
4188
4205
|
for(const{type:e,result:t}of _)q+=`### ${e} operations\n`,q+=t.content[0].text+"\n\n"
|
|
4189
|
-
return
|
|
4206
|
+
return g.info("Modify-file operations completed",{totalOperationTypes:_.length,successCount:S,errorCount:T}),u.incrementCounter("modify_file_total",1,{success:!E}),{content:[{type:"text",text:q}],isError:E}}catch(e){return g.error("Modify-file operation failed",{error:e instanceof Error?e.stack:e+""}),u.incrementCounter("modify_file_errors",1),{content:[{type:"text",text:"\u274c **Modify File Failed:** "+(0,s.getErrorMessage)(e)}],isError:!0}}}
|
|
4190
4207
|
const r=t(3306),n=t(6486),o=t(6651),s=t(8824)},7478(e,exports,t){"use strict"
|
|
4191
4208
|
async function r(e,t,r){const n=r.startTimer("git_get_current_branch_duration")
|
|
4192
4209
|
try{const o=(await e.status()).current
|
|
4193
|
-
if(!o)throw new
|
|
4210
|
+
if(!o)throw new g.ValidationError("Repository is in detached HEAD state or branch detection failed")
|
|
4194
4211
|
return t.debug("Retrieved current branch",{branch:o}),r.incrementCounter("git_get_current_branch_success",1),n({success:!0}),o}catch(e){const o=(0,m.getErrorMessage)(e)
|
|
4195
|
-
throw t.error("Failed to get current branch",{error:o}),r.incrementCounter("git_get_current_branch_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4212
|
+
throw t.error("Failed to get current branch",{error:o}),r.incrementCounter("git_get_current_branch_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to get current branch: "+o)}}async function n(e,t,r,n){const o=n.startTimer("git_branch_exists_duration")
|
|
4196
4213
|
try{const s=(await e.branch(["-l"])).all.includes(t)
|
|
4197
4214
|
return r.debug("Checked branch existence",{branchName:t,exists:s}),n.incrementCounter("git_branch_exists_check",1,{exists:s.toString()}),o({success:!0}),s}catch(e){const s=(0,m.getErrorMessage)(e)
|
|
4198
4215
|
return r.error("Failed to check branch existence",{branchName:t,error:s}),n.incrementCounter("git_branch_exists_failure",1),o({success:!1,error:e instanceof Error?e.name:"unknown"}),!1}}async function o(e,t,o,s){const i=s.startTimer("git_switch_branch_duration")
|
|
4199
4216
|
try{const a=await r(e,o,s)
|
|
4200
4217
|
if(a===t)return o.debug("Already on target branch",{branchName:t}),s.incrementCounter("git_switch_branch_noop",1),i({success:!0,reason:"already_on_branch"}),{success:!0,branchName:t,previousBranch:a,message:`Already on branch '${t}'`}
|
|
4201
4218
|
if(!await n(e,t,o,s)){const e=`Branch '${t}' does not exist`
|
|
4202
|
-
throw o.error(e),s.incrementCounter("git_switch_branch_not_found",1),i({success:!1,reason:"branch_not_found"}),new
|
|
4219
|
+
throw o.error(e),s.incrementCounter("git_switch_branch_not_found",1),i({success:!1,reason:"branch_not_found"}),new g.ValidationError(e)}await e.checkout(t)
|
|
4203
4220
|
const c=await e.revparse(["HEAD"])
|
|
4204
4221
|
return o.info("Switched to branch",{branchName:t,previousBranch:a,commitHash:c.substring(0,8)}),s.incrementCounter("git_switch_branch_success",1),i({success:!0}),{success:!0,branchName:t,previousBranch:a,commitHash:c,message:`Switched from '${a}' to '${t}'`}}catch(e){const r=(0,m.getErrorMessage)(e)
|
|
4205
|
-
throw o.error("Failed to switch branch",{branchName:t,error:r}),s.incrementCounter("git_switch_branch_failure",1),i({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4222
|
+
throw o.error("Failed to switch branch",{branchName:t,error:r}),s.incrementCounter("git_switch_branch_failure",1),i({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError(`Failed to switch to branch '${t}': ${r}`)}}async function s(e,t,r){const n=r.startTimer("git_repository_status_duration")
|
|
4206
4223
|
try{let o,s=!0
|
|
4207
4224
|
try{o=await e.status()}catch(e){return s=!1,t.warn("Not a git repository or git not available"),r.incrementCounter("git_repository_status_not_git",1),n({success:!0,reason:"not_git_repo"}),{isGitRepository:!1,currentBranch:"",isClean:!1,hasMainBranch:!1,hasMasterBranch:!1,defaultBranch:"",uncommittedChanges:[],branches:[]}}const i=o.current||"",a=0===o.files.length,c=o.files.map((e=>e.path)),l=await e.branch(["-l"]),d=l.all.map((e=>({name:e,isCurrentBranch:e===i}))),u=l.all.includes("main"),h=l.all.includes("master")
|
|
4208
|
-
let
|
|
4209
|
-
return u?
|
|
4210
|
-
throw t.error("Failed to get repository status",{error:o}),r.incrementCounter("git_repository_status_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4225
|
+
let g=""
|
|
4226
|
+
return u?g="main":h?g="master":d.length>0&&(g=d[0].name),t.debug("Retrieved repository status",{currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:g,branchCount:d.length,uncommittedCount:c.length}),r.incrementCounter("git_repository_status_success",1),n({success:!0}),{isGitRepository:s,currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:g,uncommittedChanges:c,branches:d}}catch(e){const o=(0,m.getErrorMessage)(e)
|
|
4227
|
+
throw t.error("Failed to get repository status",{error:o}),r.incrementCounter("git_repository_status_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to get repository status: "+o)}}function i(e){return"requests/"+e}async function a(e,t,r){const n=r.startTimer("git_uncommitted_changes_check_duration")
|
|
4211
4228
|
try{t.debug("Starting uncommitted changes check"),t.debug("Checking for uncommitted changes before merge"),Date.now()
|
|
4212
4229
|
const o=await e.status()
|
|
4213
4230
|
Date.now(),t.debug("Git status result",{files:o.files.map((e=>({path:e.path,index:e.index,working_dir:e.working_dir}))),totalFiles:o.files.length})
|
|
@@ -4219,7 +4236,7 @@ let d=""
|
|
|
4219
4236
|
if(l){const e=[]
|
|
4220
4237
|
s.length>0&&e.push(s.length+" staged file(s)"),i.length>0&&e.push(i.length+" unstaged file(s)"),a.length>0&&e.push(a.length+" untracked file(s)"),d=`Found ${c} uncommitted change(s): ${e.join(", ")}`}else d="No uncommitted changes detected"
|
|
4221
4238
|
return(0,h.isDebugToolsEnabled)()&&t.debug("Summary",{summary:d}),t.debug("Uncommitted changes check completed",{hasChanges:l,staged:s.length,unstaged:i.length,untracked:a.length,total:c,summary:d}),r.incrementCounter("git_uncommitted_changes_check_success",1),r.recordValue("git_uncommitted_changes_total_files",c),n({success:!0}),{hasChanges:l,stagedFiles:s,unstagedFiles:i,untrackedFiles:a,totalFiles:c,summary:d}}catch(e){const o=(0,m.getErrorMessage)(e)
|
|
4222
|
-
throw t.error("Failed to check uncommitted changes",{error:o}),r.incrementCounter("git_uncommitted_changes_check_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4239
|
+
throw t.error("Failed to check uncommitted changes",{error:o}),r.incrementCounter("git_uncommitted_changes_check_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to check uncommitted changes: "+o)}}var c,l=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
4223
4240
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
4224
4241
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),d=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),u=this&&this.__importStar||(c=function(e){return c=Object.getOwnPropertyNames||function(e){var t=[]
|
|
4225
4242
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -4233,29 +4250,29 @@ return s.warn(e),i.incrementCounter("git_create_branch_already_exists",1),c({suc
|
|
|
4233
4250
|
await e.checkoutBranch(t,o)
|
|
4234
4251
|
const d=await e.revparse(["HEAD"]),u=a||l
|
|
4235
4252
|
return await e.checkout(u),s.info("Created new branch",{branchName:t,fromBranch:o,currentBranch:l,returnedToBranch:u,commitHash:d.substring(0,8)}),i.incrementCounter("git_create_branch_success",1),c({success:!0}),{success:!0,branchName:t,previousBranch:l,commitHash:d,message:`Created branch '${t}' from '${o}'`}}catch(e){const r=(0,m.getErrorMessage)(e)
|
|
4236
|
-
throw s.error("Failed to create branch",{branchName:t,fromBranch:o,error:r}),i.incrementCounter("git_create_branch_failure",1),c({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4253
|
+
throw s.error("Failed to create branch",{branchName:t,fromBranch:o,error:r}),i.incrementCounter("git_create_branch_failure",1),c({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError(`Failed to create branch '${t}': ${r}`)}},exports.switchToBranch=o,exports.mergeBranch=async function(e,t,s,i,a,c){const l=a.startTimer("git_merge_branch_duration")
|
|
4237
4254
|
try{const d=await r(e,i,a)
|
|
4238
4255
|
if(d!==s&&await o(e,s,i,a),!await n(e,t,i,a)){const e=`Source branch '${t}' does not exist`
|
|
4239
|
-
throw i.error(e),a.incrementCounter("git_merge_branch_source_not_found",1),l({success:!1,reason:"source_not_found"}),new
|
|
4256
|
+
throw i.error(e),a.incrementCounter("git_merge_branch_source_not_found",1),l({success:!1,reason:"source_not_found"}),new g.ValidationError(e)}const u=c?["--no-ff","-m",c,t]:["--no-ff",t],h=(await e.merge(u),await e.revparse(["HEAD"]))
|
|
4240
4257
|
return i.info("Successfully merged branch",{sourceBranch:t,targetBranch:s,commitHash:h.substring(0,8),mergeMessage:c||"default merge message"}),a.incrementCounter("git_merge_branch_success",1),l({success:!0}),{success:!0,branchName:s,previousBranch:d,commitHash:h,message:`Merged '${t}' into '${s}'`}}catch(e){const r=(0,m.getErrorMessage)(e)
|
|
4241
|
-
throw i.error("Failed to merge branch",{sourceBranch:t,targetBranch:s,error:r}),a.incrementCounter("git_merge_branch_failure",1),l({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4258
|
+
throw i.error("Failed to merge branch",{sourceBranch:t,targetBranch:s,error:r}),a.incrementCounter("git_merge_branch_failure",1),l({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError(`Failed to merge '${t}' into '${s}': ${r}`)}},exports.deleteBranch=async function(e,t,o=!1,s,i){const a=i.startTimer("git_delete_branch_duration")
|
|
4242
4259
|
try{const c=await r(e,s,i)
|
|
4243
4260
|
if(c===t){const e=`Cannot delete current branch '${t}'`
|
|
4244
|
-
throw s.error(e),i.incrementCounter("git_delete_branch_current_branch",1),a({success:!1,reason:"current_branch"}),new
|
|
4245
|
-
throw s.error(e),i.incrementCounter("git_delete_branch_protected",1),a({success:!1,reason:"protected_branch"}),new
|
|
4261
|
+
throw s.error(e),i.incrementCounter("git_delete_branch_current_branch",1),a({success:!1,reason:"current_branch"}),new g.ValidationError(e)}if("main"===t||"master"===t){const e=`Cannot delete protected branch '${t}'`
|
|
4262
|
+
throw s.error(e),i.incrementCounter("git_delete_branch_protected",1),a({success:!1,reason:"protected_branch"}),new g.ValidationError(e)}if(!await n(e,t,s,i)){const e=`Branch '${t}' does not exist`
|
|
4246
4263
|
return s.warn(e),i.incrementCounter("git_delete_branch_not_found",1),a({success:!1,reason:"not_found"}),{success:!1,branchName:t,message:e}}const l=o?["-D",t]:["-d",t]
|
|
4247
4264
|
return await e.branch(l),s.info("Deleted branch",{branchName:t,force:o,currentBranch:c}),i.incrementCounter("git_delete_branch_success",1),a({success:!0}),{success:!0,branchName:t,previousBranch:c,message:`Deleted branch '${t}'${o?" (forced)":""}`}}catch(e){const r=(0,m.getErrorMessage)(e)
|
|
4248
|
-
throw s.error("Failed to delete branch",{branchName:t,force:o,error:r}),i.incrementCounter("git_delete_branch_failure",1),a({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4265
|
+
throw s.error("Failed to delete branch",{branchName:t,force:o,error:r}),i.incrementCounter("git_delete_branch_failure",1),a({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError(`Failed to delete branch '${t}': ${r}`)}},exports.getRepositoryStatus=s,exports.validateGitRepository=async function(e,t,r){const n=r.startTimer("git_validate_repository_duration")
|
|
4249
4266
|
try{const o=await s(e,t,r)
|
|
4250
4267
|
return o.isGitRepository?(o.currentBranch||(t.warn("Git repository in detached HEAD state"),r.incrementCounter("git_validate_repository_detached_head",1)),o.isClean||(t.warn("Git repository has uncommitted changes",{count:o.uncommittedChanges.length,files:o.uncommittedChanges.slice(0,5)}),r.incrementCounter("git_validate_repository_dirty",1)),o.defaultBranch||(t.warn("No default branch found in git repository"),r.incrementCounter("git_validate_repository_no_default_branch",1)),t.info("Git repository validation completed",{currentBranch:o.currentBranch,isClean:o.isClean,defaultBranch:o.defaultBranch,branchCount:o.branches.length}),r.incrementCounter("git_validate_repository_success",1),n({success:!0}),o):(t.warn("Git repository validation failed: not a git repository"),r.incrementCounter("git_validate_repository_not_git",1),n({success:!1,reason:"not_git_repo"}),o)}catch(e){const o=(0,m.getErrorMessage)(e)
|
|
4251
|
-
throw t.error("Git repository validation failed",{error:o}),r.incrementCounter("git_validate_repository_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4268
|
+
throw t.error("Git repository validation failed",{error:o}),r.incrementCounter("git_validate_repository_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Git repository validation failed: "+o)}},exports.sanitizeBranchName=function(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").substring(0,50)},exports.generateRequestBranchName=i,exports.generateMergeMessagePatterns=function(e){const t=i(e)
|
|
4252
4269
|
return[`Merge ${t}-`,"Merge "+t,`Merge ${t}-.*\\(resolved conflicts\\)`,`Merge ${t} \\(resolved conflicts\\)`]},exports.parseRequestIdFromBranchName=function(e){const t=e.match(/^feature\/(req\d{6})-/)
|
|
4253
4270
|
return t?t[1]:null},exports.switchToDefaultBranch=async function(e,t,r){const n=r.startTimer("git_switch_to_default_duration")
|
|
4254
4271
|
try{const i=await s(e,t,r)
|
|
4255
4272
|
if(!i.defaultBranch){const e="No default branch found"
|
|
4256
4273
|
return t.warn(e),r.incrementCounter("git_switch_to_default_no_branch",1),n({success:!1,reason:"no_default_branch"}),{success:!1,branchName:"",message:e}}const a=await o(e,i.defaultBranch,t,r)
|
|
4257
4274
|
return a.success?(t.info("Switched to default branch",{defaultBranch:i.defaultBranch,previousBranch:a.previousBranch}),r.incrementCounter("git_switch_to_default_success",1),n({success:!0})):(r.incrementCounter("git_switch_to_default_failed",1),n({success:!1,reason:"switch_failed"})),a}catch(e){const o=(0,m.getErrorMessage)(e)
|
|
4258
|
-
throw t.error("Failed to switch to default branch",{error:o}),r.incrementCounter("git_switch_to_default_error",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4275
|
+
throw t.error("Failed to switch to default branch",{error:o}),r.incrementCounter("git_switch_to_default_error",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to switch to default branch: "+o)}},exports.ensureRepositoryReady=async function(e,t,r){const n=r.startTimer("git_ensure_repository_ready_duration")
|
|
4259
4276
|
try{const o=await s(e,t,r),i=[]
|
|
4260
4277
|
o.isGitRepository||i.push("Not a git repository"),o.currentBranch||i.push("Repository is in detached HEAD state"),o.defaultBranch||i.push("No default branch (main/master) found")
|
|
4261
4278
|
const a=0===i.length
|
|
@@ -4265,9 +4282,9 @@ try{r.debug("Starting main branch change detection",{providedRevertCommitHash:t.
|
|
|
4265
4282
|
const n=await e.revparse(["HEAD"])
|
|
4266
4283
|
r.debug("Git state captured",{currentMainHash:n.substring(0,8),fullCurrentMainHash:n,revertCommitHash:t.substring(0,8),fullRevertCommitHash:t,hashesMatch:n===t})
|
|
4267
4284
|
try{const t=await e.revparse(["--abbrev-ref","HEAD"]),n=await e.status(),o=await e.log(["--oneline","-5"])
|
|
4268
|
-
r.debug("Additional git context",{currentBranch:t,gitStatus:{ahead:n.ahead,behind:n.behind,current:n.current,tracking:n.tracking,staged:n.staged.length,modified:n.modified.length},recentCommits:o.all.map((e=>({hash:e.hash.substring(0,8),message:e.message})))})}catch(e){r.warn("Failed to gather additional git context",{error:e instanceof Error?e.message:e+""})}const s=await(0,
|
|
4285
|
+
r.debug("Additional git context",{currentBranch:t,gitStatus:{ahead:n.ahead,behind:n.behind,current:n.current,tracking:n.tracking,staged:n.staged.length,modified:n.modified.length},recentCommits:o.all.map((e=>({hash:e.hash.substring(0,8),message:e.message})))})}catch(e){r.warn("Failed to gather additional git context",{error:e instanceof Error?e.message:e+""})}const s=await(0,p.validateCommitHash)(e,t,r,"hasMainChangedSinceRevert-revert-validation")
|
|
4269
4286
|
if(!s.valid)throw r.error("Revert commit validation failed",{revertCommitHash:t.substring(0,8),error:s.error}),Error(`Revert commit ${t.substring(0,8)} not found or not reachable: ${s.error}`)
|
|
4270
|
-
const i=await(0,
|
|
4287
|
+
const i=await(0,p.validateCommitHash)(e,n,r,"hasMainChangedSinceRevert-head-validation")
|
|
4271
4288
|
if(!i.valid)throw r.error("Current HEAD validation failed",{currentMainHash:n.substring(0,8),error:i.error}),Error(`Current HEAD ${n.substring(0,8)} validation failed: ${i.error}`)
|
|
4272
4289
|
if(n===t)return r.info("Main branch unchanged since revert - exact hash match",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),fullHashMatch:!0}),o({success:!0,changed:"false"}),{hasChanged:!1,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:0,message:"Main branch has not changed since revert"}
|
|
4273
4290
|
r.debug("Hash comparison shows difference, checking ancestor relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),hashesEqual:!1})
|
|
@@ -4289,7 +4306,7 @@ try{if(!/^[a-f0-9]{40}$/i.test(o)){r.warn("Invalid commit hash format found in t
|
|
|
4289
4306
|
continue}return r.info("Found valid revert commit hash from tool records",{requestId:e,revertCommitHash:o.substring(0,8),fullRevertCommitHash:o,revertType:n,recordId:t.id,revertedAt:t.createdAt,hashFormat:"valid"}),{found:!0,revertCommitHash:o,revertType:n,revertedAt:t.createdAt,message:`Found ${n} revert commit from ${t.createdAt}`}}catch(n){r.warn("Revert commit hash validation failed, trying next record",{requestId:e,revertCommitHash:o.substring(0,8),recordId:t.id,error:n instanceof Error?n.message:n+""})
|
|
4290
4307
|
continue}}return r.warn("Found revert tool records but none have completed status with commit hash",{requestId:e,recordCount:n.length,records:n.map((e=>({type:e.type,status:e.metadata?.status,hasCommitHash:!!e.metadata?.revertCommitHash})))}),{found:!1,message:"Found revert records but none were completed successfully"}}catch(t){const n=(0,m.getErrorMessage)(t)
|
|
4291
4308
|
return r.error("Failed to find revert commit hash from tool records",{requestId:e,error:n}),{found:!1,message:"Failed to search tool records: "+n}}},exports.checkUncommittedChanges=a,exports.commitUserChanges=async function(e,t,r,n,o){const s=o.startTimer("git_commit_user_changes_duration")
|
|
4292
|
-
try{if(!r.hasChanges)throw new
|
|
4309
|
+
try{if(!r.hasChanges)throw new g.ValidationError("No uncommitted changes to commit")
|
|
4293
4310
|
n.debug("Starting user changes commit process",{staged:r.stagedFiles.length,unstaged:r.unstagedFiles.length,untracked:r.untrackedFiles.length,total:r.totalFiles}),n.info("Committing user changes before merge",{requestId:t,staged:r.stagedFiles.length,unstaged:r.unstagedFiles.length,untracked:r.untrackedFiles.length,total:r.totalFiles})
|
|
4294
4311
|
const i=[...r.unstagedFiles,...r.untrackedFiles]
|
|
4295
4312
|
i.length>0?(n.debug("Staging files",{files:i.slice(0,10),total:i.length}),await e.add(i),n.debug("Staged uncommitted files",{files:i.slice(0,10),total:i.length}),n.debug("Successfully staged files")):n.debug("No additional files to stage (already staged)")
|
|
@@ -4297,7 +4314,7 @@ const a=`chore: commit user changes before merging request ${t}\n\n${r.summary}\
|
|
|
4297
4314
|
n.debug("Commit message",{message:a.split("\n")[0]}),n.debug("Creating commit"),await e.commit(a)
|
|
4298
4315
|
const c=await e.revparse(["HEAD"])
|
|
4299
4316
|
return n.debug("Commit created successfully",{commitHash:c.substring(0,8),filesCommitted:r.totalFiles}),n.info("Successfully committed user changes",{requestId:t,commitHash:c.substring(0,8),filesCommitted:r.totalFiles,message:a.split("\n")[0]}),o.incrementCounter("git_commit_user_changes_success",1),o.recordValue("git_commit_user_changes_files",r.totalFiles),s({success:!0}),{commitHash:c,message:a,filesCommitted:r.totalFiles}}catch(e){const i=(0,m.getErrorMessage)(e)
|
|
4300
|
-
throw n.error("Failed to commit user changes",{requestId:t,error:i,uncommittedFiles:r.totalFiles}),o.incrementCounter("git_commit_user_changes_failure",1),s({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4317
|
+
throw n.error("Failed to commit user changes",{requestId:t,error:i,uncommittedFiles:r.totalFiles}),o.incrementCounter("git_commit_user_changes_failure",1),s({success:!1,error:e instanceof Error?e.name:"unknown"}),new g.ValidationError("Failed to commit user changes: "+i)}},exports.commitUserChangesBeforeToolOperation=async function(e,r,n,o,s){const i=s.startTimer("git_pre_tool_user_changes_duration")
|
|
4301
4318
|
try{let c=Date.now()
|
|
4302
4319
|
o.debug("Checking for user changes before tool operation",{toolName:r})
|
|
4303
4320
|
let l=e
|
|
@@ -4311,10 +4328,10 @@ let u
|
|
|
4311
4328
|
o.debug("Found user changes before tool, committing them first",{toolName:r}),o.info("Found user changes before tool operation, committing separately",{toolName:r,requestId:n.requestId,taskId:n.taskId,totalFiles:d.totalFiles,summary:d.summary}),u=n.requestId&&n.taskId?`chore: commit user changes before ${r} (task ${n.taskId})`:n.requestId?`chore: commit user changes before ${r} (request ${n.requestId})`:`chore: commit user changes before ${r} operation`
|
|
4312
4329
|
const h=`${u}\n\n${{...d,summary:`User changes detected before ${r}: ${d.summary.replace("Found ","").toLowerCase()}`}.summary}\n\nThis commit preserves user modifications made before the ${r} tool operation\nto maintain clear separation between user changes and tool changes.`
|
|
4313
4330
|
o.debug("Committing user changes with message",{firstLine:h.split("\n")[0]})
|
|
4314
|
-
const
|
|
4315
|
-
c=Date.now(),
|
|
4316
|
-
const
|
|
4317
|
-
return o.debug("User changes committed successfully before tool",{commitHash:
|
|
4331
|
+
const g=[...d.unstagedFiles,...d.untrackedFiles]
|
|
4332
|
+
c=Date.now(),g.length>0&&(o.debug("Staging files before tool operation",{files:g.slice(0,10),total:g.length}),await l.add(g)),Date.now(),c=Date.now(),await l.commit(h),Date.now()
|
|
4333
|
+
const p=await l.revparse(["HEAD"])
|
|
4334
|
+
return o.debug("User changes committed successfully before tool",{commitHash:p.substring(0,8),filesCommitted:d.totalFiles,toolName:r}),o.info("Successfully committed user changes before tool operation",{toolName:r,requestId:n.requestId,taskId:n.taskId,commitHash:p.substring(0,8),filesCommitted:d.totalFiles}),s.incrementCounter("git_pre_tool_user_changes_committed",1),s.recordValue("git_pre_tool_user_changes_files",d.totalFiles),i({success:!0,reason:"changes_committed"}),{userChangesCommitted:!0,commitHash:p,filesCommitted:d.totalFiles}}catch(e){const t=(0,m.getErrorMessage)(e)
|
|
4318
4335
|
return o.debug("Failed to commit user changes before tool",{toolName:r,error:t}),o.warn("Failed to commit user changes before tool operation",{toolName:r,requestId:n.requestId,taskId:n.taskId,error:t}),s.incrementCounter("git_pre_tool_user_changes_failed",1),i({success:!1,error:e instanceof Error?e.name:"unknown"}),{userChangesCommitted:!1}}},exports.findLargeUntrackedFiles=async function(e,r=104857600){const n=[]
|
|
4319
4336
|
try{const o=t(3807).simpleGit(e),s=(await o.status()).not_added||[]
|
|
4320
4337
|
for(const t of s)try{const o=y.join(e,t),s=f.statSync(o)
|
|
@@ -4323,7 +4340,7 @@ const t=e.reduce(((e,t)=>e+t.sizeMB),0)
|
|
|
4323
4340
|
let r=`\n\n\u26a0\ufe0f **Performance Warning**: Large untracked files detected (${Math.round(t)} MB total) that may slow git operations:\n`
|
|
4324
4341
|
for(const t of e.slice(0,5))r+=`- \`${t.path}\` (${t.sizeMB} MB)\n`
|
|
4325
4342
|
return e.length>5&&(r+=`- ... and ${e.length-5} more large files\n`),r+="\nConsider adding these to `.gitignore` or moving them outside the repository.",r}
|
|
4326
|
-
const h=t(3444),
|
|
4343
|
+
const h=t(3444),g=t(9860),p=t(3922),m=t(8824),f=u(t(9896)),y=u(t(6928))
|
|
4327
4344
|
t(857)},7575(e,exports){"use strict"
|
|
4328
4345
|
var t
|
|
4329
4346
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileOperationPhase=void 0,function(e){e.VALIDATION="validation",e.TASK_VALIDATION="task_validation",e.RECORD_CREATION="record_creation",e.FILE_WRITE="file_write",e.STRING_REPLACEMENT="string_replacement",e.GIT_COMMIT="git_commit",e.RECORD_UPDATE_SUCCESS="record_update_success",e.RECORD_UPDATE_FAILURE="record_update_failure"}(t||(exports.FileOperationPhase=t={}))},7609(e,exports,t){"use strict"
|
|
@@ -4527,8 +4544,8 @@ const r=t(4055)
|
|
|
4527
4544
|
Object.defineProperty(exports,"ProjectID",{enumerable:!0,get(){return r.ProjectID}}),Object.defineProperty(exports,"ProjectIDFactory",{enumerable:!0,get(){return r.ProjectIDFactory}})
|
|
4528
4545
|
const n=t(1791)
|
|
4529
4546
|
Object.defineProperty(exports,"ProjectContext",{enumerable:!0,get(){return n.ProjectContext}}),Object.defineProperty(exports,"projectContextMiddleware",{enumerable:!0,get(){return n.projectContextMiddleware}})},7684(e,exports,t){"use strict"
|
|
4530
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,c,l,d,u,h,p,
|
|
4531
|
-
try{const a=e,{operations:y,comment:w}=a,{enforceActiveTask:b}=await Promise.resolve().then(t.bind(t,3451)),I=await b(c,h,
|
|
4547
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,c,l,d,u,h,g,p,m){const f=g.child({tool:"manage_files"})
|
|
4548
|
+
try{const a=e,{operations:y,comment:w}=a,{enforceActiveTask:b}=await Promise.resolve().then(t.bind(t,3451)),I=await b(c,h,g,e.taskId)
|
|
4532
4549
|
if("errorResult"in I)return I.errorResult
|
|
4533
4550
|
const{taskId:k}=I
|
|
4534
4551
|
f.info("Processing manage-files operations",{taskId:k,operationCount:y.length,comment:w})
|
|
@@ -4541,18 +4558,18 @@ case"delete-files":_.push(...e.deleteFiles.targets)
|
|
|
4541
4558
|
break
|
|
4542
4559
|
case"get-file-info":E.push({path:e.getFileInfo.path})}const S=[]
|
|
4543
4560
|
for(const e of v){f.info("Routing to create-directory handler",{path:e.path})
|
|
4544
|
-
const t=await(0,r.handleCreateDirectory)({taskId:k,path:e.path,comment:w+" [via manage-files: create-directory]"},c,l,d,u,f,
|
|
4561
|
+
const t=await(0,r.handleCreateDirectory)({taskId:k,path:e.path,comment:w+" [via manage-files: create-directory]"},c,l,d,u,f,p,m)
|
|
4545
4562
|
S.push({type:"create-directory",result:t})}if(C.length>0){f.info("Routing to move-files handler",{operationCount:C.length})
|
|
4546
|
-
const e=await(0,n.handleMoveFiles)({taskId:k,operations:C,comment:w+" [via manage-files: move-files]"},c,l,d,u,f,
|
|
4563
|
+
const e=await(0,n.handleMoveFiles)({taskId:k,operations:C,comment:w+" [via manage-files: move-files]"},c,l,d,u,f,p,m)
|
|
4547
4564
|
S.push({type:"move-files",result:e})}if(_.length>0){f.info("Routing to delete-files handler",{operationCount:_.length})
|
|
4548
|
-
const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,
|
|
4565
|
+
const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,p,m)
|
|
4549
4566
|
S.push({type:"delete-files",result:e})}for(const e of E){f.info("Routing to get-file-info handler",{path:e.path})
|
|
4550
|
-
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,
|
|
4567
|
+
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,p)
|
|
4551
4568
|
S.push({type:"get-file-info",result:t})}const T=S.some((e=>e.result.isError)),q=S.filter((e=>!e.result.isError)).length,P=S.filter((e=>e.result.isError)).length
|
|
4552
4569
|
let j="## Manage Files Results\n\n"
|
|
4553
4570
|
j+="**Summary:**\n",j+=`- **Total operation types:** ${S.length}\n`,j+=`- **Successful:** ${q}\n`,j+=`- **Failed:** ${P}\n\n`
|
|
4554
4571
|
for(const{type:e,result:t}of S)j+=`### ${e} operations\n`,j+=t.content[0].text+"\n\n"
|
|
4555
|
-
return f.info("Manage-files operations completed",{totalOperationTypes:S.length,successCount:q,errorCount:P}),
|
|
4572
|
+
return f.info("Manage-files operations completed",{totalOperationTypes:S.length,successCount:q,errorCount:P}),p.incrementCounter("manage_files_total",1,{success:!T}),{content:[{type:"text",text:j}],...(0,s.alchemyMeta)({kind:"manage-files"}),isError:T}}catch(e){return f.error("Manage-files operation failed",{error:e instanceof Error?e.stack:e+""}),p.incrementCounter("manage_files_errors",1),{content:[{type:"text",text:"\u274c **Manage Files Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
4556
4573
|
const r=t(8309),n=t(2414),o=t(3628),s=t(2272),i=t(5992),a=t(8824)},7713(e,exports,t){"use strict"
|
|
4557
4574
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4558
4575
|
const r=t(6183),n=t(5303)
|
|
@@ -4577,8 +4594,8 @@ const r=t(5806),n=t(5715)
|
|
|
4577
4594
|
exports.def={name:"complete_request",description(e){return e.testsRequired?"Mark request as complete with test verification":"Mark request as complete (no test verification needed)"},schema(){return(0,r.getDynamicCompleteRequestSchema)()},annotations:{title:"Complete Request",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},hidden:!0,handler(e,t){return(0,n.handleCompleteRequest)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer,t.cliOrigin)}}},7849(e,exports,t){"use strict"
|
|
4578
4595
|
async function r(e,t,r,n,o,s,a,l,d,u){const h=Date.now()
|
|
4579
4596
|
if(!r||""===r.trim())throw new c.ValidationError("Project ID is required and cannot be empty for tool record creation")
|
|
4580
|
-
try{const c=await a.createToolRecord({taskId:e,requestId:t,projectId:r,type:n,metadata:{path:o,operation:n,status:"pending",timestamp:(new Date).toISOString(),fileExtension:i.default.extname(o).slice(1),fileOperationId:`${e}-${Date.now()}`,...s},note:`${"write-file"===n?"Writing":"Modifying"} file: ${o}`}),
|
|
4581
|
-
return l.info("Tool record created with IDs",{recordId:
|
|
4597
|
+
try{const c=await a.createToolRecord({taskId:e,requestId:t,projectId:r,type:n,metadata:{path:o,operation:n,status:"pending",timestamp:(new Date).toISOString(),fileExtension:i.default.extname(o).slice(1),fileOperationId:`${e}-${Date.now()}`,...s},note:`${"write-file"===n?"Writing":"Modifying"} file: ${o}`}),g=c.id,p=c.localId
|
|
4598
|
+
return l.info("Tool record created with IDs",{recordId:g,localRecordId:p,hasLocalId:!!c.localId,recordKeys:Object.keys(c),fullRecord:JSON.stringify(c)}),l.info("Created tool record for file operation: "+n,{taskId:e,projectId:r,path:o,recordId:g,localRecordId:p}),d.recordValue(u+"_tool_record_creation_time",Date.now()-h),d.incrementCounter(u+"_tool_record_creation_success",1),{recordId:g,localRecordId:p}}catch(t){d.incrementCounter(u+"_tool_record_creation_failure",1),d.recordValue(u+"_tool_record_creation_time",Date.now()-h)
|
|
4582
4599
|
const n=t instanceof Error?`${t.message} (${JSON.stringify(t)})`:t+""
|
|
4583
4600
|
return l.warn("Failed to create tool record for file operation: "+n,{taskId:e,projectId:r,path:o,error:t instanceof Error?t.stack:t+""}),{}}}async function n(e,t,r,n,o,s,a,c,l){const u=Date.now()
|
|
4584
4601
|
try{await s.updateToolRecord(e,{metadata:{path:t,operation:r,timestamp:(new Date).toISOString(),fileExtension:i.default.extname(t).slice(1),fileUpdateId:`${e}-${Date.now()}`,...n},note:o}),a.info("Updated tool record for file operation: "+r,{path:t,recordId:e,status:n.status}),c.recordValue(l+"_tool_record_update_time",Date.now()-u),c.incrementCounter(l+"_tool_record_update_success",1)}catch(n){c.incrementCounter(l+"_tool_record_update_failure",1),c.recordValue(l+"_tool_record_update_time",Date.now()-u),a.warn("Failed to update tool record for file operation: "+r,{path:t,recordId:e,error:(0,d.getErrorMessage)(n)})}}async function o(e,t,r,n,o){const{operationType:s,toolRecordId:i,successField:c,logger:l,metrics:u,metricsPrefix:h}=n
|
|
@@ -4589,22 +4606,22 @@ l.info("Staging modified files for git commit",{files:n,count:n.length,operation
|
|
|
4589
4606
|
let d=o.git
|
|
4590
4607
|
if(o.workspaceManager){const t=o.workspaceManager.getCurrentContext(o.currentSessionId)
|
|
4591
4608
|
"multi-agent"===t.mode&&t.requestId&&(d=(0,a.simpleGit)(t.basePath),l.debug("Using WorkspaceManager git instance for multi-file commit",{taskId:e,mode:t.mode,requestId:t.requestId,basePath:t.basePath,branchName:t.branchName,filesCount:n.length}))}if(!d)return l.debug("No git repository available, skipping commit"),{filesCommitted:[],success:!0}
|
|
4592
|
-
let
|
|
4593
|
-
try{
|
|
4594
|
-
const
|
|
4595
|
-
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:
|
|
4609
|
+
let g=null
|
|
4610
|
+
try{g=(await d.revparse(["HEAD"])).trim()}catch(e){l.warn("Failed to get current commit hash",{error:e})}for(const e of n)await d.add(e)
|
|
4611
|
+
const p=1===n.length?`${s} in ${n[0]} (${i})`:`${s} in ${n.length} files (${i})`,m=(await d.commit(p)).commit
|
|
4612
|
+
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:p,filesCommitted:n.length,commitHash:m?.substring(0,8),previousCommitHash:g?.substring(0,8),toolRecordId:i,operationType:s}),u.incrementCounter(h+"_git_commit_success",1),u.recordValue(h+"_files_committed",n.length),{commitHash:m,previousCommitHash:g,filesCommitted:n,success:!0}}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
4596
4613
|
return l.warn("Git operations failed via shared multi-file utility",{error:t,operationType:s,note:"File changes were saved but not committed to git"}),u.incrementCounter(h+"_git_commit_failure",1),{filesCommitted:[],success:!1,error:t}}}var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4597
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.createToolRecord=r,exports.updateToolRecord=n,exports.createFileOperationRecords=async function(e,t,n,o,s,i,a,c,l,u,h){const
|
|
4598
|
-
let
|
|
4614
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.createToolRecord=r,exports.updateToolRecord=n,exports.createFileOperationRecords=async function(e,t,n,o,s,i,a,c,l,u,h){const g=Date.now()
|
|
4615
|
+
let p,m
|
|
4599
4616
|
l.debug("createFileOperationRecords called",{taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,operationType:o,path:s})
|
|
4600
4617
|
try{const a=await r(e,t,n,o,s,i,c,l,u,h)
|
|
4601
|
-
return
|
|
4618
|
+
return p=a.recordId,m=a.localRecordId,l.info("Created tool record for file operation: "+o,{taskId:e,path:s,toolRecordId:p,localToolRecordId:m}),{toolRecordId:p,localToolRecordId:m}}catch(r){throw l.error("Failed to create tool record for file operation: "+o,{error:(0,d.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0,taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,path:s}),u.recordValue(h+"_record_creation_time",Date.now()-g),u.incrementCounter(h+"_record_creation_error",1),r}},exports.updateFileOperationRecords=async function(e,t,r,o,s,i,a,c,l,u,h,g,p){try{t&&h.info("Task record update skipped (task records removed): "+t,{taskId:e,path:o}),r&&await n(r,o,s,a,c,u,h,g,p)}catch(t){h.warn("Error updating tool record for operation: "+s,{error:(0,d.getErrorMessage)(t),taskId:e,normalizedPath:o,toolRecordId:r})}},exports.checkAndCommitUserMods=async function(e,t,r,n,o){if(!t.git)return{hadUserMods:!1}
|
|
4602
4619
|
try{let s=t.git
|
|
4603
4620
|
if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
4604
4621
|
"multi-agent"===e.mode&&e.requestId&&(s=(0,a.simpleGit)(e.basePath))}if((await s.diff(["--name-only","HEAD","--",e])).trim().length>0){r.info(`File ${e} has uncommitted changes, preserving user modifications`),await s.add(e)
|
|
4605
4622
|
const t=await s.commit("[USER-MODS] Preserve user modifications before tool operation: "+e)
|
|
4606
4623
|
return r.info("Created user modifications commit",{filePath:e,userModsCommitHash:t.commit}),n.incrementCounter(o+"_user_mods_commits_created",1),{hadUserMods:!0,userModsCommitHash:t.commit}}return{hadUserMods:!1}}catch(t){return r.warn("Failed to check/preserve user modifications for "+e,{error:(0,d.getErrorMessage)(t)}),n.incrementCounter(o+"_user_mods_check_failures",1),{hadUserMods:!1}}},exports.commitToGit=async function(e,t,r,n,o,s,i,c,u){const h=Date.now()
|
|
4607
|
-
let p
|
|
4624
|
+
let g,p=null
|
|
4608
4625
|
try{let m=s.git
|
|
4609
4626
|
if(s.workspaceManager){const t=s.workspaceManager.getCurrentContext(s.currentSessionId)
|
|
4610
4627
|
if("multi-agent"===t.mode&&t.requestId){if(!t.basePath.includes("/worktrees/")&&!t.basePath.includes("\\worktrees\\"))throw i.error("CRITICAL BUG: Multi-agent mode but basePath is not a worktree path",{taskId:e,requestId:t.requestId,basePath:t.basePath,expectedPattern:"should contain /worktrees/ or \\worktrees\\",issue:"workspace_context_incorrect"}),Error(`Multi-agent mode context error: basePath '${t.basePath}' is not a worktree path. This will cause commits to go to main branch instead of the request branch.`)
|
|
@@ -4615,11 +4632,11 @@ i.info("Git repository status before commit:",{taskId:e,currentBranch:r.trim(),c
|
|
|
4615
4632
|
const a=r.trim(),c=s.getCurrentRequestId?s.getCurrentRequestId():null
|
|
4616
4633
|
if(c){const t="requests/"+c
|
|
4617
4634
|
a!=="requests/"+c?i.warn("Multi-agent file operation may be on wrong branch",{taskId:e,actualBranch:a,expectedPattern:t,requestId:c}):i.info("Multi-agent file operation on expected branch",{taskId:e,branchName:a,requestId:c})}}catch(e){i.warn("Failed to get Git status before commit:",{error:e instanceof Error?e.message:e+""})}try{if(m){const r=await m.revparse(["HEAD"])
|
|
4618
|
-
|
|
4619
|
-
await m.add(t),
|
|
4635
|
+
p=await(0,l.findPreviousCommit)(m,t,r),i.info(`Previous commit hash for ${t}: ${p||"none (new file)"}`,{taskId:e,gitInstancePath:f||"unknown",isWorktreeOperation:a,usingCorrectGitInstance:!0})}else i.warn("Git not available for previous commit detection: "+t,{taskId:e,reason:"no_git_instance"})}catch(e){i.warn(`Failed to find previous commit for ${t}:`,{error:(0,d.getErrorMessage)(e)})}const y=n?`[RECORD:${n}] ${o}`:o
|
|
4636
|
+
await m.add(t),g=(await m.commit(y)).commit
|
|
4620
4637
|
try{const r=await m.revparse(["--abbrev-ref","HEAD"]),n=await m.revparse(["HEAD"])
|
|
4621
|
-
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(
|
|
4622
|
-
return{commitHash:
|
|
4638
|
+
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(p||""),targetFile:t}),g&&n.trim()!==g&&i.warn("Commit hash mismatch after commit",{taskId:e,expectedCommitHash:g,actualHeadHash:n.trim(),targetFile:t})}catch(e){i.warn("Failed to verify post-commit status:",{error:e instanceof Error?e.message:e+""})}i.info("Committed file changes to Git: "+t,{taskId:e,path:t,recordId:r,localRecordId:n,commitHash:g,previousCommitHash:p}),c.recordValue(u+"_git_commit_time",Date.now()-h),c.incrementCounter(u+"_git_commit_success",1)}else i.warn("No Git repository available, skipping commit",{taskId:e,path:t})
|
|
4639
|
+
return{commitHash:g,previousCommitHash:p}}catch(r){return c.incrementCounter(u+"_git_commit_failure",1),c.recordValue(u+"_git_commit_time",Date.now()-h),i.warn("Failed to commit file changes to Git: "+t,{taskId:e,path:t,error:r instanceof Error?r.stack:r+""}),{commitHash:void 0,previousCommitHash:p}}},exports.commitMultipleFilesToGit=o,exports.handleMultiFileGitCommit=async function(e,t,r,n,s,i){const{logger:a,metricsPrefix:c,metrics:l}=s
|
|
4623
4640
|
return 0===t.length||0===n?(a.debug("No file operations with changes to commit"),{filesCommitted:[],success:!0}):(l.incrementCounter(c+"_phase",1,{phase:u.FileOperationPhase.GIT_COMMIT}),await o(e,t,r,s,i))}
|
|
4624
4641
|
const i=s(t(6928)),a=t(3807),c=t(9860),l=t(9671),d=t(8824),u=t(7575)},7888(e,exports,t){"use strict"
|
|
4625
4642
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.addConnectionStatusInfo=function(e){return async(t,n,o)=>{try{const t=e.isInOfflineMode()
|
|
@@ -4641,11 +4658,11 @@ class o{static create(){return exports.ProjectIDFactory.create()}static fromStri
|
|
|
4641
4658
|
return o.fromString(`prj_${e}_${t}`)},fromString(e){return this.isValid(e)?new o(e):null},isValid(e){if(!e||"string"!=typeof e||5>e.length||!e.startsWith("prj"))return!1
|
|
4642
4659
|
if(e.includes("_")){const t=e.split("_")
|
|
4643
4660
|
return t.length>=3&&"prj"===t[0]}return!1}},exports.ProjectIDBackwardCompat={create:exports.ProjectIDFactory.create,fromString:exports.ProjectIDFactory.fromString,isValid:exports.ProjectIDFactory.isValid},Object.assign(o,exports.ProjectIDBackwardCompat)},8035(e,exports,t){"use strict"
|
|
4644
|
-
function r(e,t,r){try{const n=`[${(new Date).toISOString()}] [detached-subagent] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,i.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,s.appendFileSync)(o,n)}catch{}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=function(e){const{agent:t,prompt:d,cwd:u,sessionId:h,model:
|
|
4661
|
+
function r(e,t,r){try{const n=`[${(new Date).toISOString()}] [detached-subagent] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,i.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,s.appendFileSync)(o,n)}catch{}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=function(e){const{agent:t,prompt:d,cwd:u,sessionId:h,model:g,initialBranch:p,serverUrl:m,onSpawn:f}=e
|
|
4645
4662
|
try{const e=u||process.cwd(),o={...process.env,...(0,c.getOpencodeSpawnEnv)(e,(0,l.isDevMode)())}
|
|
4646
4663
|
let y
|
|
4647
|
-
if(
|
|
4648
|
-
e>0?y.splice(e,0,"--model",
|
|
4664
|
+
if(p&&(o.ALCHEMY_INITIAL_BRANCH=p),r(u,"Spawn env setup",{agent:t,initialBranch:p||"none",sessionId:h||"new",attachMode:!!m}),y=m&&h&&d?["run","--attach",m,"--session",h,"--agent",t,d]:h&&d?["run","--session",h,"--agent",t,d]:d?["run","--agent",t,d]:["run","--agent",t],g){const e=y.findIndex((e=>e===d))
|
|
4665
|
+
e>0?y.splice(e,0,"--model",g):y.push("--model",g)}r(u,"Spawning opencode",{args:y.map((e=>e===d?`[prompt:${e.length}chars]`:e)),model:g||"not specified",promptLength:d?.length,promptPreview:d?.slice(0,100),cwd:u,hasSessionId:!!h})
|
|
4649
4666
|
const w=(0,i.join)(u||process.cwd(),".alchemy_lab"),b=(0,i.join)(w,"spawn-stderr.log")
|
|
4650
4667
|
let I
|
|
4651
4668
|
try{I=(0,s.openSync)(b,"a")}catch{}const k=(0,a.resolveRunCommand)(),v=(0,n.spawn)(k.command,[...k.prependArgs,...y],{detached:!0,stdio:["ignore","ignore",I??"ignore"],cwd:u||process.cwd(),env:o})
|
|
@@ -4663,10 +4680,10 @@ const d={}
|
|
|
4663
4680
|
o.status&&"undefined"!==o.status&&(d.status=o.status),o.type&&"undefined"!==o.type&&(d.type=o.type),o.dateFrom&&(d.dateFrom=o.dateFrom),o.dateTo&&(d.dateTo=o.dateTo),o.planDocumentId&&(d.planDocumentId=o.planDocumentId),o.questDocumentId&&(d.questDocumentId=o.questDocumentId),d.limit=o.limit||20,d.offset=o.offset||0,d.sortBy="created"===o.sortBy?"created_at":(o.sortBy,"updated_at"),d.sortDirection=o.sortDirection||"desc",s.setProjectId(a),c.info("Sending query parameters",{queryParams:d})
|
|
4664
4681
|
const u=s.getRequestClient(),h=await u.listRequests(d)
|
|
4665
4682
|
c.debug("=== RAW SERVER RESPONSE DEBUG ===",{responseType:typeof h,isArray:Array.isArray(h),responseKeys:h?Object.keys(h):[],fullResponse:JSON.stringify(h,null,2)}),c.debug("Raw requests response data",{responseData:JSON.stringify(h)}),c.debug("Requests response structure",{type:typeof h,isArray:Array.isArray(h),hasData:null!=h,properties:h?Object.keys(h):[],dataPreview:h?JSON.stringify(h).substring(0,200)+"...":"null"})
|
|
4666
|
-
const
|
|
4667
|
-
if(c.info(`Extracted ${
|
|
4668
|
-
const g
|
|
4669
|
-
return l({success:!0,requestCount:
|
|
4683
|
+
const g=(0,n.extractArrayFromResponse)(h,{logger:c,operationName:"listRequests",defaultValue:[]})
|
|
4684
|
+
if(c.info(`Extracted ${g.length} requests from response`),0===g.length)return l({success:!0,requestCount:0}),{content:[{type:"text",text:"No requests found with the specified filters."}]}
|
|
4685
|
+
const p=g.map((e=>`**${e.title}** (${e.id}) [${e.type}]\nStatus: ${e.status}\nType: ${e.type}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}\n`)).join("\n---\n"),m=`Found ${g.length} request${1===g.length?"":"s"}:`
|
|
4686
|
+
return l({success:!0,requestCount:g.length}),{content:[{type:"text",text:`${m}\n\n${p}`}]}}catch(t){return c.error("Error listing requests",{args:e,error:t instanceof Error?t.stack:t+""}),l({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:"Error listing requests: "+(0,o.getErrorMessage)(t)}],isError:!0}}}
|
|
4670
4687
|
const r=t(9860),n=t(2960),o=t(8824)},8045(e,exports,t){"use strict"
|
|
4671
4688
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4672
4689
|
const r=t(6183),n=t(7456)
|
|
@@ -4693,14 +4710,14 @@ var u=t(184)
|
|
|
4693
4710
|
Object.defineProperty(exports,"createServer",{enumerable:!0,get(){return u.createServer}})
|
|
4694
4711
|
var h=t(3884)
|
|
4695
4712
|
Object.defineProperty(exports,"middleware",{enumerable:!0,get(){return h.middleware}}),Object.defineProperty(exports,"requestLogger",{enumerable:!0,get(){return h.requestLogger}}),Object.defineProperty(exports,"errorHandler",{enumerable:!0,get(){return h.errorHandler}}),Object.defineProperty(exports,"authenticate",{enumerable:!0,get(){return h.authenticate}}),Object.defineProperty(exports,"validateRequest",{enumerable:!0,get(){return h.validateRequest}}),Object.defineProperty(exports,"corsOptions",{enumerable:!0,get(){return h.corsOptions}})
|
|
4696
|
-
var
|
|
4697
|
-
Object.defineProperty(exports,"addConnectionStatusInfo",{enumerable:!0,get(){return
|
|
4713
|
+
var g=t(7888)
|
|
4714
|
+
Object.defineProperty(exports,"addConnectionStatusInfo",{enumerable:!0,get(){return g.addConnectionStatusInfo}}),t(3611),t(6552),t(1791),t(1152),t(3328),t(3884),t(6800),t(9955),t(2568),t(3102),t(8625),t(184),t(1472),t(1213),n(t(3444),exports),n(t(3227),exports),n(t(9914),exports),n(t(4055),exports),n(t(9860),exports),n(t(3611),exports),n(t(6552),exports)},8184(e,exports,t){"use strict"
|
|
4698
4715
|
function r(e,t=!1){return{content:[{type:"text",text:JSON.stringify(e,null,2)}],...(0,s.alchemyMeta)({kind:"request-diff"}),...t?{isError:!0}:{}}}function n(e){return{content:[{type:"text",text:"\u274c "+e}],...(0,s.alchemyMeta)({kind:"request-diff"}),isError:!0}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestDiff=async function(e,t,s,c,l){const d=c.child({tool:"request_diff"}),u=l.startTimer("tool_execution_time")
|
|
4699
|
-
try{const i=e,{requestId:c,format:d="summary",path:h}=i,
|
|
4700
|
-
if(!
|
|
4701
|
-
const m=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,f=t.git??(0,o.simpleGit)({baseDir:m,binary:t.gitBinary}),y="completed"===
|
|
4716
|
+
try{const i=e,{requestId:c,format:d="summary",path:h}=i,g=s.getRequestClient(),p=await g.getRequest(c)
|
|
4717
|
+
if(!p)return u({success:!1,reason:"not_found"}),n("Request not found: "+c)
|
|
4718
|
+
const m=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,f=t.git??(0,o.simpleGit)({baseDir:m,binary:t.gitBinary}),y="completed"===p.status,w="requests/"+c
|
|
4702
4719
|
let b,I
|
|
4703
|
-
if(y){const e=
|
|
4720
|
+
if(y){const e=p.metadata?.mergeBaseSha,t=p.metadata?.mergeCommitSha
|
|
4704
4721
|
if(!e||!t)return u({success:!1,reason:"legacy_no_metadata"}),n(`Completed request ${c} predates merge-metadata tracking and cannot be diffed by request_diff. Use query_history with queryType="request-file-history" for per-task file changes.`)
|
|
4705
4722
|
b=e,I=t}else{const e=await async function(e){for(const t of["main","master"])try{return await e.raw(["rev-parse","--verify",t]),t}catch{}return"main"}(f)
|
|
4706
4723
|
try{b=(await f.raw(["merge-base",e,w])).trim()}catch{return u({success:!1,reason:"no_merge_base"}),n(`Could not compute merge-base for ${w} against ${e}. Branch may not exist.`)}try{I=(await f.raw(["rev-parse",w])).trim()}catch{return u({success:!1,reason:"no_branch"}),n(`Branch ${w} not found.`)}}const k=h?["--",h]:[]
|
|
@@ -4738,35 +4755,35 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4738
4755
|
var t={}
|
|
4739
4756
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
4740
4757
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4741
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,r,n,o,s,i,p
|
|
4758
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,r,n,o,s,i,g,p){const m=i.child({tool:"create_directory"}),f=Date.now()
|
|
4742
4759
|
let y,w,b=l.FileOperationPhase.VALIDATION
|
|
4743
4760
|
const I={toolName:"create-directory",operationName:"create",fileOperationPhase:l.FileOperationPhase.FILE_WRITE,recordType:"create-directory",metricsPrefix:"create_directory",successMessage:"Successfully created directory {path}",failureMessage:"Failed to create directory {path}"}
|
|
4744
4761
|
try{const d=e,{path:u,comment:h}=d,{enforceActiveTask:k}=await Promise.resolve().then(t.bind(t,3451)),v=await k(r,n,i,e.taskId)
|
|
4745
4762
|
if("errorResult"in v)return v.errorResult
|
|
4746
4763
|
const{taskId:C}=v
|
|
4747
|
-
m.info("Creating directory: "+u,{taskId:C,path:u,comment:h}),l.validateTaskIdFormat(C,m,
|
|
4764
|
+
m.info("Creating directory: "+u,{taskId:C,path:u,comment:h}),l.validateTaskIdFormat(C,m,g,I.metricsPrefix),r.getCurrentBranchContext&&await r.getCurrentBranchContext()
|
|
4748
4765
|
const{normalizedPath:_,fullPath:E}=l.validateAndNormalizePath(u,r)
|
|
4749
|
-
b=l.FileOperationPhase.TASK_VALIDATION,
|
|
4750
|
-
const S=await l.validateTaskId(C,_,n,m,
|
|
4766
|
+
b=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4767
|
+
const S=await l.validateTaskId(C,_,n,m,g,I.metricsPrefix),T=S?.requestId,q=await l.validateWorkItemStates(C,_,n,s,r,m,g,I.metricsPrefix),P=await l.autoPromoteTaskStatus(C,S.status,T,q.request?.status,_,n,s,m,g,I.metricsPrefix)
|
|
4751
4768
|
P.taskPromoted&&m.info(`Auto-promoted task ${C} (${S.title||"Untitled"}) to in_progress for file operation`,{taskId:C,taskTitle:S.title,previousStatus:S.status,newStatus:P.newTaskStatus,path:_}),P.requestPromoted&&m.info(`Auto-promoted request ${T} to in_progress for file operation`,{requestId:T,previousStatus:q.request?.status,newStatus:P.newRequestStatus,triggeringTaskId:C})
|
|
4752
|
-
const j=await l.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:T,context:r,operation:"create-directory",logger:m,metrics:
|
|
4769
|
+
const j=await l.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:T,context:r,operation:"create-directory",logger:m,metrics:g,metricsPrefix:I.metricsPrefix})
|
|
4753
4770
|
if(!j.success)throw Error(j.error)
|
|
4754
4771
|
let R=!1
|
|
4755
|
-
try{R=(await a.default.stat(E)).isDirectory()}catch{R=!1}b=l.FileOperationPhase.RECORD_CREATION,
|
|
4756
|
-
const{toolRecordId:x,localToolRecordId:M}=await l.createFileOperationRecords(C,T,r.projectId,I.recordType,_,{directoryExists:R,userComment:h},n,o,m,
|
|
4757
|
-
y=x,w=x,b=I.fileOperationPhase,
|
|
4772
|
+
try{R=(await a.default.stat(E)).isDirectory()}catch{R=!1}b=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4773
|
+
const{toolRecordId:x,localToolRecordId:M}=await l.createFileOperationRecords(C,T,r.projectId,I.recordType,_,{directoryExists:R,userComment:h},n,o,m,g,I.metricsPrefix,p)
|
|
4774
|
+
y=x,w=x,b=I.fileOperationPhase,g.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4758
4775
|
let O=R
|
|
4759
4776
|
if(!R){await a.default.mkdir(E,{recursive:!0}),m.info("Successfully created directory "+_)
|
|
4760
4777
|
try{const e=c.default.join(E,".gitkeep")
|
|
4761
4778
|
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),O=!0,m.info("Created .gitkeep file for Git tracking")}catch(e){m.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),O=!1}}const $=Date.now()-f
|
|
4762
|
-
|
|
4763
|
-
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!R&&O?_+"/.gitkeep":_,F=await l.commitToGit(C,A,x,M,D,r,m,
|
|
4764
|
-
b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,
|
|
4779
|
+
g.recordValue("create_directory_time",$),g.incrementCounter("create_directory_success",1),b=l.FileOperationPhase.GIT_COMMIT,g.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4780
|
+
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!R&&O?_+"/.gitkeep":_,F=await l.commitToGit(C,A,x,M,D,r,m,g,I.metricsPrefix)
|
|
4781
|
+
b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,g.incrementCounter("create_directory_phase",1,{phase:b}),await l.updateFileOperationRecords(C,y,w,_,I.recordType,`Successfully ${R?"verified":"created"} directory: ${_}`,{status:"completed",commitHash:F.commitHash,previousCommitHash:F.previousCommitHash,directoryExists:R,isDirectory:!0,userComment:h},`Successfully ${R?"verified":"created"} directory: ${_}`,n,o,m,g,I.metricsPrefix)
|
|
4765
4782
|
const N=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4766
4783
|
return{content:[{type:"text",text:R?"Directory already exists":`Successfully created directory${F.commitHash?"\nCommit: "+F.commitHash.substring(0,8):""}${N.requestId&&!N.permanentBranch?"\nBranch: "+N.requestId:""}`}]}}catch(t){if(e.taskId&&o)try{const n=t instanceof d.NotFoundError||t instanceof d.ValidationError||t instanceof u.ZodError
|
|
4767
4784
|
await o.createToolRecord({...n?{}:{taskId:e.taskId},projectId:r.projectId,type:"create-directory",metadata:{status:"failed",timestamp:(new Date).toISOString(),path:e.path,userComment:e.comment,error:(0,h.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:n},note:`Failed to create directory ${e.path} - ${(0,h.getErrorMessage)(t)}`})}catch(t){m.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()-f
|
|
4768
|
-
if(
|
|
4769
|
-
try{await l.updateFileOperationRecords(e.taskId,y,w,e.path,I.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,h.getErrorMessage)(t),userComment:e.comment},"Failed to create directory "+e.path,n,o,m,
|
|
4785
|
+
if(g.recordValue("create_directory_time",s),g.incrementCounter("create_directory_errors",1),m.error("Error creating directory:",{error:(0,h.getErrorMessage)(t),time:s}),(y||w)&&e.taskId){b=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
4786
|
+
try{await l.updateFileOperationRecords(e.taskId,y,w,e.path,I.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,h.getErrorMessage)(t),userComment:e.comment},"Failed to create directory "+e.path,n,o,m,g,I.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(t,b,m,g,e,I)}}
|
|
4770
4787
|
const a=i(t(1943)),c=i(t(6928)),l=s(t(5967)),d=t(9860),u=t(1569),h=t(8824)},8317(e,exports,t){"use strict"
|
|
4771
4788
|
function r(e){const t=[]
|
|
4772
4789
|
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"
|
|
@@ -4775,20 +4792,20 @@ case"move-files":return"\u{1f4cb} Move Files"
|
|
|
4775
4792
|
case"delete-files":return"\u{1f5d1}\ufe0f Delete Files"
|
|
4776
4793
|
case"manage-files":return"\u{1f4c1} Manage Files"
|
|
4777
4794
|
default:return e}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestFileHistory=async function(e,t,c,l,d){const u=l.child({tool:"request_file_history"}),h=d.startTimer("tool_execution_time")
|
|
4778
|
-
try{const{requestId:l,detailLevel:
|
|
4795
|
+
try{const{requestId:l,detailLevel:g="summary",taskId:p,showDiff:m=!1,fileFilter:f}=e
|
|
4779
4796
|
if(!l)throw(0,o.createValidationError)("Request ID is required")
|
|
4780
4797
|
if(!/^req[_\d].+$/.test(l))throw(0,o.createValidationError)(`Invalid request ID format: ${l}. Expected format: req_[26 chars] or req######`)
|
|
4781
|
-
if(
|
|
4782
|
-
if(u.info("Getting file changes for request "+l,{detailLevel:
|
|
4798
|
+
if(p&&!(0,a.isTaskRef)(p))throw(0,o.createValidationError)(`Invalid task ID format: ${p}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
|
|
4799
|
+
if(u.info("Getting file changes for request "+l,{detailLevel:g,taskId:p,showDiff:m}),!t.git)throw Error("Git integration not available in this context")
|
|
4783
4800
|
const y=t.projectId
|
|
4784
4801
|
let w
|
|
4785
4802
|
c.setProjectId(y)
|
|
4786
4803
|
try{const e=c.getRequestClient(),t=await e.getRequest(l),r=(0,s.extractDataFromResponse)(t,{logger:u,operationName:"getRequest",throwOnNoData:!1}),n="data"in r?r.data:r
|
|
4787
4804
|
w={id:n.id||l,title:n.title||"Unknown Request",description:n.description||"No description available",status:n.status||"unknown",type:n.type||"unknown",createdAt:n.createdAt||(new Date).toISOString(),updatedAt:n.updatedAt||(new Date).toISOString()},u.info("Found request: "+w.title)}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
4788
4805
|
if(t.includes("not found")||t.includes("Not found"))return u.warn("Request not found: "+l),h({tool:"request_file_history",success:!1}),d.incrementCounter("request_file_history_errors",1),{content:[{type:"text",text:`\u274c **Request not found:** ${l}\n\nThe request ID does not exist in the system. Please verify the request ID is correct.`}],isError:!0}
|
|
4789
|
-
u.warn("Could not fetch request information: "+t),w={id:l,title:"Unknown Request",description:"No description available",status:"unknown",type:"unknown",createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}if("detailed"===
|
|
4806
|
+
u.warn("Could not fetch request information: "+t),w={id:l,title:"Unknown Request",description:"No description available",status:"unknown",type:"unknown",createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}if("detailed"===g){const e=c.getToolRecordClient()
|
|
4790
4807
|
let o=[]
|
|
4791
|
-
try{
|
|
4808
|
+
try{p?(o=await e.getToolRecordsByTaskId(p),u.info(`Fetched ${o.length} records for task ${p}`)):(o=await e.getToolRecordsByRequestId(l),u.info(`Fetched ${o.length} records for request ${l}`))}catch(e){u.warn("Error fetching tool records: "+(0,i.getErrorMessage)(e)),o=[]}const s=await async function(e,t,o,s,a,c,l){let d="# File Operations - Detailed View\n\n"
|
|
4792
4809
|
if(d+=`## Request: ${e.title}\n`,d+=`**ID**: ${e.id}\n`,d+=`**Type**: ${e.type}\n`,d+=`**Status**: ${e.status}\n\n`,o&&(d+=`**Filtered to Task**: ${o}\n`),l&&(d+=`**File Filter**: \`${l}\`\n`),(o||l)&&(d+="\n"),0===t.length)return d+="No file operations found.\n",d
|
|
4793
4810
|
let u=t.filter((e=>{const t=e.type
|
|
4794
4811
|
return["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(t)})).sort(((e,t)=>new Date(e.createdAt).getTime()-new Date(t.createdAt).getTime()))
|
|
@@ -4802,10 +4819,10 @@ let r=0
|
|
|
4802
4819
|
e.forEach((e=>{e.replacements&&(r+=e.replacements.length)})),d+=`**Replacements**: ${r}\n`}if(t.metadata?.commitHash&&(d+=`**Commit**: ${t.metadata.commitHash.substring(0,8)}\n`,s||5>=h.length))try{const e=await a.diff([t.metadata.commitHash+"^",t.metadata.commitHash])
|
|
4803
4820
|
if(e&&e.trim()){const r=500,n=e.length
|
|
4804
4821
|
if(n>r){const o=e.substring(0,r),s=(n/1024).toFixed(1)
|
|
4805
|
-
d+=`\n**Changes preview** (first ${r} chars):\n\`\`\`diff\n${o}\n\`\`\`\n`,d+=`... (diff truncated, ${s}KB total)\n`,d+=`\u{1f4a1} Use \`file-history\` tool with commit \`${t.metadata.commitHash.substring(0,8)}\` to see full diff\n`}else d+=`\n**Changes:**\n\`\`\`diff\n${e}\n\`\`\`\n`}}catch(e){c.debug("Could not fetch diff for commit",{commit:t.metadata.commitHash,error:(0,i.getErrorMessage)(e)})}d+="\n---\n\n"}return d}(w,o,
|
|
4822
|
+
d+=`\n**Changes preview** (first ${r} chars):\n\`\`\`diff\n${o}\n\`\`\`\n`,d+=`... (diff truncated, ${s}KB total)\n`,d+=`\u{1f4a1} Use \`file-history\` tool with commit \`${t.metadata.commitHash.substring(0,8)}\` to see full diff\n`}else d+=`\n**Changes:**\n\`\`\`diff\n${e}\n\`\`\`\n`}}catch(e){c.debug("Could not fetch diff for commit",{commit:t.metadata.commitHash,error:(0,i.getErrorMessage)(e)})}d+="\n---\n\n"}return d}(w,o,p,m,t.git,u,f)
|
|
4806
4823
|
return h({success:!0,recordCount:o.length}),{content:[{type:"text",text:s}]}}{const e=c.getToolRecordClient()
|
|
4807
4824
|
let n=[]
|
|
4808
|
-
try{
|
|
4825
|
+
try{p?(n=await e.getToolRecordsByTaskId(p),u.info(`Fetched ${n.length} records for task ${p}`)):(n=await e.getToolRecordsByRequestId(l),u.info(`Fetched ${n.length} records for request ${l}`))}catch(e){u.warn("Error fetching tool records: "+(0,i.getErrorMessage)(e)),n=[]}const o=await async function(e,t){const n=new Map
|
|
4809
4826
|
let o=0
|
|
4810
4827
|
for(const s of e){const e=s.type
|
|
4811
4828
|
if(!["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(e))continue
|
|
@@ -4847,17 +4864,17 @@ return s.default.writeFileSync(t,JSON.stringify(c,null,2)),n(e,t,r),h.info("Crea
|
|
|
4847
4864
|
i.processes=i.processes.filter((e=>e.pid!==r)),i.count=i.processes.length,i.count>0?(s.default.writeFileSync(t,JSON.stringify(i,null,2)),h.debug("Removed process from multi-agent references",{signal:n,pid:r,remaining:i.count})):(s.default.unlinkSync(t),s.default.existsSync(e)&&s.default.unlinkSync(e),h.debug("Removed multi-agent lock files (last process)",{signal:n,pid:r}))}}catch(e){h.error("Error removing multi-agent lock files",{error:e instanceof Error?e.message:e+"",signal:n})}"exit"!==n&&process.exit(0)}))}))}var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4848
4865
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.acquireProcessLock=function(e){const t=i.default.join(e,c.ALCHEMY_DIR_NAME)
|
|
4849
4866
|
let o,l
|
|
4850
|
-
try{s.default.existsSync(t)||(s.default.mkdirSync(t,{recursive:!0}),h.debug(`Created ${c.ALCHEMY_DIR_NAME} directory for lock file`,{alchemyLabDir:t})),o=i.default.join(t,".mcp-server.lock"),l=i.default.join(t,".mcp-agents.refs"),h.debug(`Using ${c.ALCHEMY_DIR_NAME} directory for lock files`,{lockFilePath:o,refsFilePath:l})}catch(r){h.error(`Failed to create ${c.ALCHEMY_DIR_NAME} directory`,{alchemyLabDir:t,error:r instanceof Error?r.message:r+""}),o=i.default.join(e,".mcp-server.lock"),l=i.default.join(e,".mcp-agents.refs"),h.warn("Falling back to base directory for lock files",{lockFilePath:o,refsFilePath:l})}const
|
|
4867
|
+
try{s.default.existsSync(t)||(s.default.mkdirSync(t,{recursive:!0}),h.debug(`Created ${c.ALCHEMY_DIR_NAME} directory for lock file`,{alchemyLabDir:t})),o=i.default.join(t,".mcp-server.lock"),l=i.default.join(t,".mcp-agents.refs"),h.debug(`Using ${c.ALCHEMY_DIR_NAME} directory for lock files`,{lockFilePath:o,refsFilePath:l})}catch(r){h.error(`Failed to create ${c.ALCHEMY_DIR_NAME} directory`,{alchemyLabDir:t,error:r instanceof Error?r.message:r+""}),o=i.default.join(e,".mcp-server.lock"),l=i.default.join(e,".mcp-agents.refs"),h.warn("Falling back to base directory for lock files",{lockFilePath:o,refsFilePath:l})}const g=process.pid,p=(new Date).toISOString()
|
|
4851
4868
|
try{const e=function(e){if(!s.default.existsSync(e))return null
|
|
4852
4869
|
try{const t=s.default.readFileSync(e,"utf8").trim()
|
|
4853
4870
|
try{const e=JSON.parse(t)
|
|
4854
4871
|
return h.debug("Read JSON lock data",e),e}catch{if(isNaN(parseInt(t,10)))return h.warn("Invalid lock file content",{content:t}),null
|
|
4855
4872
|
const e={mode:"multi-agent",created:(new Date).toISOString(),hostname:"unknown"}
|
|
4856
4873
|
return h.debug("Read legacy PID lock data",e),e}}catch(e){return h.error("Error reading lock file",{error:(0,d.getErrorMessage)(e)}),null}}(o)
|
|
4857
|
-
if(h.info("Lock acquisition attempt",{pid:
|
|
4858
|
-
return i?(h.warn("\u26a0\ufe0f Clearing stale lock (older than 24 hours)",{lockAge:Math.round(t/1e3/60/60)+" hours",lockCreated:e.created,lockHostname:e.hostname}),r(o,l,p
|
|
4874
|
+
if(h.info("Lock acquisition attempt",{pid:g,lockFilePath:o,lockExists:!!e,lockData:e?{mode:e.mode,hostname:e.hostname,created:e.created}:null}),e){const t=Date.now()-new Date(e.created).getTime(),i=t>u,c=a.default.hostname(),m=e.hostname!==c&&"unknown"!==e.hostname
|
|
4875
|
+
return i?(h.warn("\u26a0\ufe0f Clearing stale lock (older than 24 hours)",{lockAge:Math.round(t/1e3/60/60)+" hours",lockCreated:e.created,lockHostname:e.hostname}),r(o,l,g,p)):m?(h.warn("\u26a0\ufe0f Clearing lock from different machine",{lockHostname:e.hostname,currentHostname:c}),r(o,l,g,p)):"multi-agent"===e.mode?function(e,t,r){try{let o={count:0,processes:[]}
|
|
4859
4876
|
if(s.default.existsSync(e)){const t=s.default.readFileSync(e,"utf8")
|
|
4860
|
-
o=JSON.parse(t),o.processes=o.processes.filter((e=>function(e){try{return process.kill(e,0),!0}catch{return!1}}(e.pid))),o.count=o.processes.length}return o.processes.push({pid:t,started:r}),o.count=o.processes.length,s.default.writeFileSync(e,JSON.stringify(o,null,2)),n(e.replace(".mcp-agents.refs",".mcp-server.lock"),e,t),h.info("Joined multi-agent lock",{pid:t,totalAgents:o.count}),!0}catch(e){return h.error("Error joining multi-agent lock",{error:(0,d.getErrorMessage)(e)}),!1}}(l,p
|
|
4877
|
+
o=JSON.parse(t),o.processes=o.processes.filter((e=>function(e){try{return process.kill(e,0),!0}catch{return!1}}(e.pid))),o.count=o.processes.length}return o.processes.push({pid:t,started:r}),o.count=o.processes.length,s.default.writeFileSync(e,JSON.stringify(o,null,2)),n(e.replace(".mcp-agents.refs",".mcp-server.lock"),e,t),h.info("Joined multi-agent lock",{pid:t,totalAgents:o.count}),!0}catch(e){return h.error("Error joining multi-agent lock",{error:(0,d.getErrorMessage)(e)}),!1}}(l,g,p):(h.info("Taking over legacy lock",{currentPid:g,oldMode:e.mode}),r(o,l,g,p))}return h.info("No existing lock - creating new lock",{pid:g,mode:"multi-agent"}),r(o,l,g,p)}catch(e){return h.error("Error acquiring lock",{error:(0,d.getErrorMessage)(e),pid:g}),!1}}
|
|
4861
4878
|
const s=o(t(9896)),i=o(t(6928)),a=o(t(857)),c=t(4139),l=t(3444),d=t(8824),u=864e5,h=(0,l.createLogger)({serviceName:"process-lock",level:l.LogLevel.DEBUG,logToFile:!1})},8451(e,exports,t){"use strict"
|
|
4862
4879
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatFileSize=function(e){return 1024>e?e+" bytes":1048576>e?(e/1024).toFixed(2)+" KB":1073741824>e?(e/1048576).toFixed(2)+" MB":(e/1073741824).toFixed(2)+" GB"},exports.truncate=function(e,t){return e.length>t?e.substring(0,t-3)+"...":e},exports.escapeRegExp=function(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},exports.countOccurrences=function(e,t){if(0===t.length)return 0
|
|
4863
4880
|
let r=0,n=0
|
|
@@ -4906,16 +4923,16 @@ function r(e){const t=c[e]
|
|
|
4906
4923
|
if(!t)throw Error(`Tool "${e}" does not have a defined RecordType mapping. This is a type safety violation. Please add this tool to the TOOL_NAME_TO_RECORD_TYPE_MAP in failure-record-utils.ts.`)
|
|
4907
4924
|
return t}function n(e){return!!e&&(0,a.isTaskRef)(e)}function o(e){return!!e&&(/^req\d{6}$/.test(e)||/^req_[\w-]+$/.test(e))}function s(e){return!!e&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.toolNameToRecordType=r,exports.isValidTaskId=n,exports.isValidRequestId=o,exports.isValidProjectId=s,exports.createFailureToolRecord=async function(e,t,a,c,l,d,u){if(!c)return void l.warn("ToolRecordClient is not available, skipping failure record creation for "+e)
|
|
4908
4925
|
if(!s(u.projectId)){const t=Error(`Invalid projectId format: ${u.projectId}. Cannot create failure record without valid projectId.`)
|
|
4909
|
-
throw l.error("Cannot create failure record due to invalid projectId",{toolName:e,projectId:u.projectId,error:t.message}),t}const h=Date.now(),
|
|
4926
|
+
throw l.error("Cannot create failure record due to invalid projectId",{toolName:e,projectId:u.projectId,error:t.message}),t}const h=Date.now(),g=e.replace(/-/g,"_"),p=(0,i.getErrorMessage)(t),m=t instanceof Error?t.stack:void 0
|
|
4910
4927
|
try{const t=r(e),s={}
|
|
4911
4928
|
let i,f
|
|
4912
4929
|
u.taskId&&(n(u.taskId)?i=u.taskId:(s.taskId=u.taskId,l.warn(`Invalid taskId format: ${u.taskId}, not associating failure record with this ID`,{toolName:e,invalidTaskId:u.taskId}))),u.requestId&&(o(u.requestId)?f=u.requestId:(s.requestId=u.requestId,l.warn(`Invalid requestId format: ${u.requestId}, not associating failure record with this ID`,{toolName:e,invalidRequestId:u.requestId})))
|
|
4913
|
-
let y=u.note||`Failed to execute ${e}: ${
|
|
4930
|
+
let y=u.note||`Failed to execute ${e}: ${p.substring(0,100)}${p.length>100?"...":""}`
|
|
4914
4931
|
Object.keys(s).length>0&&(y+=` (Warning: Invalid IDs provided: ${Object.entries(s).map((([e,t])=>`${e}: ${t}`)).join(", ")})`)
|
|
4915
|
-
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:
|
|
4916
|
-
i&&(w.taskId=i),f&&(w.requestId=f),l.info("Creating failure tool record for "+e,{toolName:e,recordType:w.type,...i&&{taskId:i},...f&&{requestId:f},projectId:u.projectId,invalidIds:Object.keys(s).length>0?s:void 0,error:
|
|
4932
|
+
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:p,errorStack:m,originalToolName:e,timestamp:(new Date).toISOString(),invalidIds:Object.keys(s).length>0?s:void 0,...a}}
|
|
4933
|
+
i&&(w.taskId=i),f&&(w.requestId=f),l.info("Creating failure tool record for "+e,{toolName:e,recordType:w.type,...i&&{taskId:i},...f&&{requestId:f},projectId:u.projectId,invalidIds:Object.keys(s).length>0?s:void 0,error:p})
|
|
4917
4934
|
const b=await c.createToolRecord(w)
|
|
4918
|
-
d.recordValue(
|
|
4935
|
+
d.recordValue(g+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(g+"_failure_record_creation_success",1),l.info("Successfully created failure tool record for "+e,{toolName:e,recordType:w.type,...i&&{taskId:i},...f&&{requestId:f},projectId:u.projectId,toolRecordId:b.id})}catch(t){throw d.recordValue(g+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(g+"_failure_record_creation_failure",1),l.error("Failed to create failure tool record for "+e,{error:t instanceof Error?t.stack:t+"",toolName:e,...u.taskId&&{originalTaskId:u.taskId},...u.requestId&&{originalRequestId:u.requestId},projectId:u.projectId,originalError:p}),t}}
|
|
4919
4936
|
const i=t(8824),a=t(4466),c={write_file:"write-file","delete-file":"delete-file",delete_files:"delete-files",move_files:"move-files","replace-string":"replace-string",replace_strings:"replace-strings",insert_lines:"insert-lines",replace_lines:"replace-lines","file-recover":"file-recover",complete_task:"complete-task","update-task-status":"update-task-status","create-task":"create-task",create_request:"create-request",complete_request:"complete-request",read_files:"discovery","list-directory":"discovery",search:"discovery",file_history:"discovery",request_file_history:"discovery",get_request_information:"discovery",get_task_information:"discovery",list_requests:"discovery",list_tasks:"discovery",create_directory:"write",authenticate:"discovery","find-previous-commit":"discovery"}},8622(e,exports){"use strict"
|
|
4920
4937
|
function t(e,t){if(e&&"string"==typeof e[t])try{e[t]=JSON.parse(e[t])}catch{}}function r(e){if(Array.isArray(e))for(const t of e)t&&"object"==typeof t&&r(t)
|
|
4921
4938
|
else if(e&&"object"==typeof e)for(const t of Object.keys(e)){const n=e[t]
|
|
@@ -4940,13 +4957,13 @@ function r(e,t,r){const n=exports.ERROR_TYPE_PROPERTIES[e]||exports.ERROR_TYPE_P
|
|
|
4940
4957
|
return{success:!1,error:{code:e,message:t||n.defaultMessage,details:r,retryable:n.retryable,statusCode:n.statusCode}}}function n(e){return"object"==typeof e&&null!==e&&"code"in e&&"statusCode"in e&&"details"in e&&"retryable"in e&&"string"==typeof e.code&&"number"==typeof e.statusCode}function o(e){if(n(e)){const t=r(e.code,e.message,e.details)
|
|
4941
4958
|
return{statusCode:e.statusCode,body:t}}if(e instanceof Error&&"ConnectionError"===e.name){const t=e
|
|
4942
4959
|
return{statusCode:503,body:r("CONNECTION_ERROR",t.message||"Connection to remote server failed",{operation:t.operation||"unknown",lastConnectionAttempt:t.lastConnectionAttempt||null,suggestions:["Check your network connection","Verify that the remote server is running","Try again in a few moments"],isConnectionIssue:!0})}}const t=e instanceof Error?e:Error(e+""),o=r(i.INTERNAL_ERROR,t.message||"An unexpected error occurred")
|
|
4943
|
-
return{statusCode:o.error.statusCode,body:o}}function s(e){return!n(e)||e.isRetryable()}Object.defineProperty(exports,"__esModule",{value:!0}),exports.UnauthorizedError=exports.McpProtocolError=exports.FileOperationError=exports.ServiceError=exports.DatabaseError=exports.AuthorizationError=exports.AuthenticationError=exports.ValidationError=exports.NotFoundError=exports.AppError=exports.ErrorUtils=exports.ERROR_TYPE_PROPERTIES=void 0,exports.createErrorResponse=r,exports.createAppError=function(e,t="INTERNAL_ERROR",r=500,n){return new a(e,t,r,n)},exports.createNotFoundError=function(e="Resource not found",t){return new c(e,t)},exports.createValidationError=function(e="Invalid input",t){return new l(e,t)},exports.createAuthenticationError=function(e="Authentication required",t){return new d(e,t)},exports.createAuthorizationError=function(e="Not authorized",t){return new u(e,t)},exports.createDatabaseError=function(e="Database error",t){return new h(e,t)},exports.createServiceError=function(e="Service unavailable",t){return new
|
|
4960
|
+
return{statusCode:o.error.statusCode,body:o}}function s(e){return!n(e)||e.isRetryable()}Object.defineProperty(exports,"__esModule",{value:!0}),exports.UnauthorizedError=exports.McpProtocolError=exports.FileOperationError=exports.ServiceError=exports.DatabaseError=exports.AuthorizationError=exports.AuthenticationError=exports.ValidationError=exports.NotFoundError=exports.AppError=exports.ErrorUtils=exports.ERROR_TYPE_PROPERTIES=void 0,exports.createErrorResponse=r,exports.createAppError=function(e,t="INTERNAL_ERROR",r=500,n){return new a(e,t,r,n)},exports.createNotFoundError=function(e="Resource not found",t){return new c(e,t)},exports.createValidationError=function(e="Invalid input",t){return new l(e,t)},exports.createAuthenticationError=function(e="Authentication required",t){return new d(e,t)},exports.createAuthorizationError=function(e="Not authorized",t){return new u(e,t)},exports.createDatabaseError=function(e="Database error",t){return new h(e,t)},exports.createServiceError=function(e="Service unavailable",t){return new g(e,t)},exports.createFileOperationError=function(e="File operation error",t){return new p(e,t)},exports.createMcpProtocolError=function(e="MCP protocol error",t){return new m(e,t)},exports.isAppError=n,exports.errorToResponse=o,exports.isRetryableError=s
|
|
4944
4961
|
const i=t(7388)
|
|
4945
4962
|
exports.ERROR_TYPE_PROPERTIES={[i.TASK_NOT_FOUND]:{statusCode:404,retryable:!1,defaultMessage:"Task ID does not exist"},[i.TASK_ID_INVALID_FORMAT]:{statusCode:400,retryable:!1,defaultMessage:"Task ID format is invalid"},[i.TASK_VALIDATION_FAILED]:{statusCode:400,retryable:!1,defaultMessage:"Task validation failed"},[i.NETWORK_ERROR]:{statusCode:503,retryable:!0,defaultMessage:"Network error occurred"},[i.SERVER_ERROR]:{statusCode:500,retryable:!0,defaultMessage:"Server error occurred"},[i.CONNECTION_TIMEOUT]:{statusCode:504,retryable:!0,defaultMessage:"Connection timed out"},[i.SERVICE_UNAVAILABLE]:{statusCode:503,retryable:!0,defaultMessage:"Service is currently unavailable"},[i.CONNECTION_ERROR]:{statusCode:503,retryable:!0,defaultMessage:"Connection to remote server failed"},[i.REQUEST_NOT_FOUND]:{statusCode:404,retryable:!1,defaultMessage:"Request ID does not exist"},[i.REQUEST_ID_INVALID_FORMAT]:{statusCode:400,retryable:!1,defaultMessage:"Request ID format is invalid"},[i.REQUEST_VALIDATION_FAILED]:{statusCode:400,retryable:!1,defaultMessage:"Request validation failed"},[i.VALIDATION_ERROR]:{statusCode:400,retryable:!1,defaultMessage:"Validation error"},[i.UNAUTHORIZED]:{statusCode:401,retryable:!1,defaultMessage:"Authentication required"},[i.FORBIDDEN]:{statusCode:403,retryable:!1,defaultMessage:"Access forbidden"},[i.NOT_FOUND]:{statusCode:404,retryable:!1,defaultMessage:"Resource not found"},[i.INTERNAL_ERROR]:{statusCode:500,retryable:!0,defaultMessage:"Internal server error"},[i.BAD_REQUEST]:{statusCode:400,retryable:!1,defaultMessage:"Bad request"},[i.MCP_PROTOCOL_ERROR]:{statusCode:500,retryable:!0,defaultMessage:"MCP protocol error"}},exports.ErrorUtils={isAppError:n,errorToResponse:o,isRetryableError:s,createErrorResponse:r}
|
|
4946
4963
|
class a extends Error{constructor(e,t="INTERNAL_ERROR",r=500,n){super(e),this.name=this.constructor.name,this.code=t,this.statusCode=r,this.details=n||{},n&&"code"in n&&"string"==typeof n.code&&(this.code=n.code)
|
|
4947
4964
|
const o=exports.ERROR_TYPE_PROPERTIES[this.code]
|
|
4948
|
-
this.retryable=o?o.retryable:!n||!("retryable"in n)||!!n.retryable,Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,message:this.message,code:this.code,statusCode:this.statusCode,details:this.details,retryable:this.retryable,stack:this.stack}}get metadata(){return this.details}isRetryable(){return this.retryable}}class c extends a{constructor(e="Resource not found",t){super(e,i.NOT_FOUND,404,t),this.resourceType="unknown",t&&("taskId"in t?(this.code=i.TASK_NOT_FOUND,this.resourceType="task"):"requestId"in t&&(this.code=i.REQUEST_NOT_FOUND,this.resourceType="request"))}}class l extends a{constructor(e="Invalid input",t){super(e,i.VALIDATION_ERROR,400,t)}}class d extends a{constructor(e="Authentication required",t){super(e,i.UNAUTHORIZED,401,t)}}class u extends a{constructor(e="Not authorized",t){super(e,i.FORBIDDEN,403,t)}}class h extends a{constructor(e="Database error",t){super(e,"DATABASE_ERROR",500,t)}}class
|
|
4949
|
-
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class
|
|
4965
|
+
this.retryable=o?o.retryable:!n||!("retryable"in n)||!!n.retryable,Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,message:this.message,code:this.code,statusCode:this.statusCode,details:this.details,retryable:this.retryable,stack:this.stack}}get metadata(){return this.details}isRetryable(){return this.retryable}}class c extends a{constructor(e="Resource not found",t){super(e,i.NOT_FOUND,404,t),this.resourceType="unknown",t&&("taskId"in t?(this.code=i.TASK_NOT_FOUND,this.resourceType="task"):"requestId"in t&&(this.code=i.REQUEST_NOT_FOUND,this.resourceType="request"))}}class l extends a{constructor(e="Invalid input",t){super(e,i.VALIDATION_ERROR,400,t)}}class d extends a{constructor(e="Authentication required",t){super(e,i.UNAUTHORIZED,401,t)}}class u extends a{constructor(e="Not authorized",t){super(e,i.FORBIDDEN,403,t)}}class h extends a{constructor(e="Database error",t){super(e,"DATABASE_ERROR",500,t)}}class g extends a{constructor(e="Service unavailable",t){if(super(e,i.SERVICE_UNAVAILABLE,503,t),t&&"structuredError"in t){const e=t.structuredError
|
|
4966
|
+
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class p extends a{constructor(e="File operation error",t){super(e,"FILE_OPERATION_ERROR",500,t)}}class m extends a{constructor(e="MCP protocol error",t){super(e,i.MCP_PROTOCOL_ERROR,500,t)}}exports.AppError=a,exports.NotFoundError=c,exports.ValidationError=l,exports.AuthenticationError=d,exports.AuthorizationError=u,exports.DatabaseError=h,exports.ServiceError=g,exports.FileOperationError=p,exports.McpProtocolError=m,exports.UnauthorizedError=d},8712(e,exports){"use strict"
|
|
4950
4967
|
function t(e,t){return!(!e||!e.trim())&&RegExp(`^\\s*\\${t}{7}(?:\\s|$)`).test(e)}function r(e,r,n){if(!e||!e.trim())return{cleanContent:"",filesParsed:[],hasConflictMarkers:!1}
|
|
4951
4968
|
const o=e.split("\n"),s=[],i=new Set
|
|
4952
4969
|
let a=!1,c=""
|
|
@@ -5000,9 +5017,9 @@ for(const a of r){const r=await n(a,t,o,s,i,e,c,l)
|
|
|
5000
5017
|
d.push(r)}return d}return l.debug(`Raw git log returned empty result for ${i}:${t}`),[]}catch(e){return l.warn(`Raw git log also failed for ${i}:${t}`,{error:e}),[]}}const h=a
|
|
5001
5018
|
if(!h||!h.all||0===h.all.length)return l.debug(`No commits found in standard git log for ${i}:${t}`),[]
|
|
5002
5019
|
l.info(`Found ${h.all.length} commits for ${i}:${t}`)
|
|
5003
|
-
const
|
|
5020
|
+
const g=[]
|
|
5004
5021
|
for(const r of h.all){const a=await n(r,t,o,s,i,e,c,l)
|
|
5005
|
-
|
|
5022
|
+
g.push(a)}return g}catch(e){return l.warn(`Failed to get history for ${i}:${t}`,{error:e}),[]}}async function n(e,t,r,n,o,s,i,a){let c=null,l=null
|
|
5006
5023
|
if(r)try{c=await s.show(["--format=",e.hash,"--",t])}catch(t){a.warn("Failed to get diff for commit",{commit:e.hash,error:t})}if(n){const t=(0,d.extractRecordId)(e.message)
|
|
5007
5024
|
if(t)try{l=await(0,d.getCachedTraceabilityInfo)(t,i,a)}catch(e){a.warn("Failed to get traceability info",{recordId:t,error:e})}}return{hash:e.hash,author:e.author_name,date:e.date,message:e.message,diff:c,traceability:l,branch:o}}var o,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
5008
5025
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
@@ -5012,7 +5029,7 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
5012
5029
|
var t={}
|
|
5013
5030
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
5014
5031
|
return i(t,e),t})
|
|
5015
|
-
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"),
|
|
5032
|
+
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"),p=Date.now()
|
|
5016
5033
|
try{const o=e,{path:a,limit:m,showDiff:f,showTraceability:y,branch:w,commit:b,since:I}=o
|
|
5017
5034
|
return b?(i.info("Getting diff for specific commit",{filePath:a,commit:b}),await async function(e,t,r,n){const o=r.git,s=c.normalize(e).replace(/\\/g,"/")
|
|
5018
5035
|
if(n.info("Getting full diff for commit",{filePath:e,commit:t}),!o)return{content:[{type:"text",text:"\u274c Git not initialized"}],isError:!0}
|
|
@@ -5020,18 +5037,18 @@ try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
|
|
|
5020
5037
|
if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
|
|
5021
5038
|
const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
|
|
5022
5039
|
let a="# File History - Commit Diff\n\n"
|
|
5023
|
-
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,h.getErrorMessage)(r)}`}],isError:!0}}}(a,b,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:m,showDiff:f,showTraceability:y,branch:w}),await async function(e,t,n,o,s,i,a,c,h,
|
|
5040
|
+
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,h.getErrorMessage)(r)}`}],isError:!0}}}(a,b,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:m,showDiff:f,showTraceability:y,branch:w}),await async function(e,t,n,o,s,i,a,c,h,p,m){try{const{normalizedPath:f,fullPath:y}=g.validateAndNormalizePath(e,a)
|
|
5024
5041
|
try{await l.access(y)}catch(e){throw Error("File not found: "+f)}const w=a.git
|
|
5025
5042
|
if(!w)throw Error("Git is not available in this context")
|
|
5026
5043
|
let b={branch:null,requestId:null,isMain:!0}
|
|
5027
5044
|
if(a.getCurrentBranchContext)try{b=await a.getCurrentBranchContext(),h.info("Current branch context detected",{branch:b.branch,requestId:b.requestId,isMain:b.isMain})}catch(e){h.warn("Could not get current branch context",{error:e})}let I=[],k=""
|
|
5028
|
-
if(s)I=await r(w,f,t,n,o,s,i,c,h,
|
|
5029
|
-
else{if(b.isMain&&!o)return h.info("Showing request-level timeline on main branch"),{content:[{type:"text",text:await(0,u.getRequestTimelineForFile)(w,f,c,h,
|
|
5030
|
-
if(b.requestId)return h.info("Showing operation-level detail on request branch",{requestId:b.requestId}),{content:[{type:"text",text:await(0,u.getOperationDetailForFile)(f,b.requestId,c,h,
|
|
5045
|
+
if(s)I=await r(w,f,t,n,o,s,i,c,h,p),k=`## File History: ${f} (Branch: ${s})\n\n`
|
|
5046
|
+
else{if(b.isMain&&!o)return h.info("Showing request-level timeline on main branch"),{content:[{type:"text",text:await(0,u.getRequestTimelineForFile)(w,f,c,h,p)}]}
|
|
5047
|
+
if(b.requestId)return h.info("Showing operation-level detail on request branch",{requestId:b.requestId}),{content:[{type:"text",text:await(0,u.getOperationDetailForFile)(f,b.requestId,c,h,p)}]}
|
|
5031
5048
|
{const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
|
|
5032
|
-
if(!i.isMain&&i.branch){const
|
|
5033
|
-
u.push(...
|
|
5034
|
-
return u.push(...m),
|
|
5049
|
+
if(!i.isMain&&i.branch){const g=await r(e,t,n,o,s,i.branch,a,c,l,d)
|
|
5050
|
+
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))),m=g.filter((e=>!p.has(e.hash)))
|
|
5051
|
+
return u.push(...m),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,f,t,n,o,b,i,c,h,p)
|
|
5035
5052
|
I=e.versions,k=`## File History: ${f} (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}]}
|
|
5036
5053
|
const v=I.length,C=Math.min(I.length,t)
|
|
5037
5054
|
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:** "
|
|
@@ -5040,9 +5057,9 @@ for(let e=0;e<I.length;e++){const t=I[e]
|
|
|
5040
5057
|
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,d.formatTraceabilityInfo)(t.traceability)}\n`),n&&t.diff){const e=t.diff.split("\n")
|
|
5041
5058
|
let r=0,n=0
|
|
5042
5059
|
for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
|
|
5043
|
-
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',h.info("Branch-aware file history retrieved successfully",{path:f,versions:I.length,targetBranch:s,currentBranch:b.branch,duration:Date.now()-m}),
|
|
5060
|
+
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',h.info("Branch-aware file history retrieved successfully",{path:f,versions:I.length,targetBranch:s,currentBranch:b.branch,duration:Date.now()-m}),p.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:k}]}}catch(e){throw e}}(a,m,f,y,w,I,t,n,i,s,p))}catch(e){const t=Date.now()-p
|
|
5044
5061
|
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,h.getErrorMessage)(e)}],isError:!0}}}
|
|
5045
|
-
const c=a(t(6928)),l=a(t(1943)),d=t(1181),u=t(2085),h=t(8824),
|
|
5062
|
+
const c=a(t(6928)),l=a(t(1943)),d=t(1181),u=t(2085),h=t(8824),g=a(t(5967)),p=a(t(7478)),{getCurrentBranch:m}=p},8849(e,exports,t){"use strict"
|
|
5046
5063
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
5047
5064
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5048
5065
|
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=[]
|
|
@@ -5166,63 +5183,63 @@ return"string"==typeof e&&e.startsWith("R-")?"acknowledge-report":"string"==type
|
|
|
5166
5183
|
if(t)return t
|
|
5167
5184
|
try{const t=await fetch(`http://localhost:${b}/api/sessions/${encodeURIComponent(e)}/agent-type`)
|
|
5168
5185
|
if(t.ok){const r=await t.json()
|
|
5169
|
-
if(r.success&&r.agentType)return I.set(e,r.agentType),r.agentType}}catch{}return null}async function o(e,t,r,o,s){try{const i=await(0,
|
|
5186
|
+
if(r.success&&r.agentType)return I.set(e,r.agentType),r.agentType}}catch{}return null}async function o(e,t,r,o,s){try{const i=await(0,g.getServerUrl)(r,o)
|
|
5170
5187
|
if(!i)return o.warn("Could not get server URL for notification",{sessionId:e}),!1
|
|
5171
5188
|
const a=await n(e)??void 0
|
|
5172
5189
|
let c
|
|
5173
5190
|
try{const e=await fetch(`http://localhost:${b}/api/project-settings`)
|
|
5174
5191
|
if(e.ok){const t=await e.json()
|
|
5175
5192
|
if(t.data?.defaultModel){const[e,...r]=t.data.defaultModel.split("/")
|
|
5176
|
-
c={providerID:e,modelID:r.join("/")}}}}catch{}const l=`${i.replace(/\/$/,"")}/session/${e}/prompt_async`,d={type:"text",text:t,metadata:s??(0,
|
|
5193
|
+
c={providerID:e,modelID:r.join("/")}}}}catch{}const l=`${i.replace(/\/$/,"")}/session/${e}/prompt_async`,d={type:"text",text:t,metadata:s??(0,p.partMeta)("inserted-prompt")},u=await fetch(l,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[d],...a?{agent:a}:{},...c?{model:c}:{}})})
|
|
5177
5194
|
return u.ok?(o.info("Notified session",{sessionId:e}),!0):(o.warn("Failed to notify session",{sessionId:e,status:u.status}),!1)}catch(t){return o.warn("Error notifying session",{sessionId:e,error:(0,h.getErrorMessage)(t)}),!1}}function s(e,t,r){return f.sessionIdentity.getParentSessionId(e,t,r)}function i(e,t,r,n,o){const s=o?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
|
|
5178
5195
|
if(!s)throw new u.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
|
|
5179
5196
|
return(0,w.logSessionIdentity)(""+r,"identity",{sessionId:s,fromCliOrigin:!!o?.sessionId}),s}function a(e){const t=[],r=e.content||{}
|
|
5180
5197
|
if(t.push("**Message Code:** "+e.messageCode),t.push(`**Type:** question (${r.questionType})`),t.push("**Status:** "+e.status),t.push("**Priority:** "+e.priority),t.push("**From:** "+e.fromSessionId),t.push(e.toSessionId?"**To:** "+e.toSessionId:"**To:** (broadcast)"),t.push("**Created:** "+e.createdAt),t.push("**Expires:** "+e.expiresAt),t.push(""),t.push("**Question:** "+r.question),r.context&&t.push("**Context:** "+r.context),"alternatives"===r.questionType&&r.options){t.push(""),t.push("**Options:**")
|
|
5181
5198
|
for(const e of r.options)t.push(` - [${e.id}] ${e.label}${e.description?" - "+e.description:""}`)}return"responded"===e.status&&e.response&&(t.push(""),t.push("---"),t.push("**Answered by:** "+e.respondedBySessionId),t.push("**Answered at:** "+e.respondedAt),e.response.text&&t.push("**Answer:** "+e.response.text),e.response.selectedOptions&&t.push("**Selected:** "+e.response.selectedOptions.join(", ")),e.response.notes&&t.push("**Notes:** "+e.response.notes)),c(r,t),t.join("\n")}function c(e,t){e?.relatesTo&&(t.push(""),t.push("**Relates to:** "+e.relatesTo))}function l(e){const t=[],r=e.content||{}
|
|
5182
5199
|
return t.push("**Status:** "+(r.reportStatus||"unknown")),t.push("**Summary:** "+(r.summary||"")),r.details&&(t.push(""),t.push("**Details:**"),t.push(r.details)),c(r,t),t.join("\n")}function d(e){return"question"===e.messageType?a(e):"instruction"===e.messageType?function(e){const t=[],r=e.content||{}
|
|
5183
|
-
return t.push("**Message Code:** "+e.messageCode),t.push("**Type:** instruction"),t.push("**Status:** "+e.status),t.push("**From:** "+e.fromSessionId),t.push("**To:** "+e.toSessionId),t.push("**Created:** "+e.createdAt),r.requestId&&t.push("**Request:** "+r.requestId),t.push(""),t.push("**Body:**"),t.push(r.body||""),t.join("\n")}(e):l(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSessionMessageOperations=async function(e,t,c,
|
|
5200
|
+
return t.push("**Message Code:** "+e.messageCode),t.push("**Type:** instruction"),t.push("**Status:** "+e.status),t.push("**From:** "+e.fromSessionId),t.push("**To:** "+e.toSessionId),t.push("**Created:** "+e.createdAt),r.requestId&&t.push("**Request:** "+r.requestId),t.push(""),t.push("**Body:**"),t.push(r.body||""),t.join("\n")}(e):l(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSessionMessageOperations=async function(e,t,c,g,b,I){const k=c.child({component:"session_message_operations"})
|
|
5184
5201
|
if(!b)throw new u.ValidationError("API client not available")
|
|
5185
5202
|
const{operation:v}=e
|
|
5186
|
-
k.info("Session message operation",{operation:v}),
|
|
5203
|
+
k.info("Session message operation",{operation:v}),g.incrementCounter("session_message_operations",1,{operation:v})
|
|
5187
5204
|
try{switch(v){case"send":if(!e.type)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
5188
|
-
return(0,
|
|
5205
|
+
return(0,p.withAlchemyKind)(await async function(e,t,r,c,d){const{type:h}=e
|
|
5189
5206
|
if(!h)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
5190
|
-
const
|
|
5191
|
-
if(!
|
|
5192
|
-
if("question"===h)return await async function(e,t,r,c,l,d){const{toSessionId:h,questionType:
|
|
5193
|
-
if(!p
|
|
5207
|
+
const g=c.getSessionMessageClient()
|
|
5208
|
+
if(!g)throw new u.ValidationError("Session message client not available")
|
|
5209
|
+
if("question"===h)return await async function(e,t,r,c,l,d){const{toSessionId:h,questionType:g,questionContent:p,priority:m,expiresInHours:f,relatesTo:w}=e
|
|
5210
|
+
if(!g||!p?.question)throw new u.ValidationError("Question requires questionType and questionContent.question")
|
|
5194
5211
|
const b=i(0,0,"session_message_operations",0,d),I=await async function(e,t,r,n){if("parent"===e){const e=await s(t,r,n)
|
|
5195
5212
|
if(!e)throw new u.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
|
|
5196
5213
|
return n.info('Resolved toSessionId "parent" to actual ID',{parentId:e}),e}return void 0===e?void 0:(0,y.asExternal)(e)}(h,b,c,r)
|
|
5197
|
-
if(!("alternatives"!==p
|
|
5198
|
-
r.info("Creating question",{fromSessionId:b,toSessionId:I,questionType:
|
|
5199
|
-
const k=await l.createQuestion({fromSessionId:b,toSessionId:I,questionType:
|
|
5214
|
+
if(!("alternatives"!==g||p.options&&Array.isArray(p.options)))throw new u.ValidationError("Alternatives questions require options array")
|
|
5215
|
+
r.info("Creating question",{fromSessionId:b,toSessionId:I,questionType:g})
|
|
5216
|
+
const k=await l.createQuestion({fromSessionId:b,toSessionId:I,questionType:g,question:p.question,options:p.options,context:p.context,allowMultiple:p.allowMultiple,priority:m,expiresInHours:f,...w?{relatesTo:w}:{}})
|
|
5200
5217
|
let v=""
|
|
5201
|
-
if(I){const e=await n(b)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:
|
|
5218
|
+
if(I){const e=await n(b)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:p.question,questionType:g,options:p.options,context:p.context,allowMultiple:p.allowMultiple,fromAgent:e,fromSessionId:b,priority:k.priority,expiresAt:k.expiresAt,...w?{relatesTo:w}:{}}}}
|
|
5202
5219
|
v=await o(I,function(e){const t=e.content||{},r=["\u{1f4e8} **You have a new question!**","","**Question Code:** "+e.messageCode,"**From:** "+e.fromSessionId,"**Priority:** "+e.priority,"","**Question:** "+t.question]
|
|
5203
5220
|
if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&&t.options){r.push(""),r.push("**Options:**")
|
|
5204
|
-
for(const e of t.options)r.push(` - [${e.id}] ${e.label}${e.description?" - "+e.description:""}`)}return r.push(""),r.push(`Use \`session_message_operations\` with \`reply\` operation and message code \`${e.messageCode}\` to respond.`),r.join("\n")}(k),t,r,s)?"\n\n\u{1f4ec} The target session has been notified.":"\n\n\u26a0\ufe0f Could not notify the target session (may be offline)."}return{content:[{type:"text",text:`\u2705 Question created!${v}\n\n**Message Code: ${k.messageCode}**\n\nUse this code to check for answers or share with other sessions.\n\n${a(k)}`}]}}(e,t,r,c,
|
|
5205
|
-
if("report"===h)return await async function(e,t,r,a,c,d){const{status:h,summary:
|
|
5206
|
-
if(!h||!
|
|
5221
|
+
for(const e of t.options)r.push(` - [${e.id}] ${e.label}${e.description?" - "+e.description:""}`)}return r.push(""),r.push(`Use \`session_message_operations\` with \`reply\` operation and message code \`${e.messageCode}\` to respond.`),r.join("\n")}(k),t,r,s)?"\n\n\u{1f4ec} The target session has been notified.":"\n\n\u26a0\ufe0f Could not notify the target session (may be offline)."}return{content:[{type:"text",text:`\u2705 Question created!${v}\n\n**Message Code: ${k.messageCode}**\n\nUse this code to check for answers or share with other sessions.\n\n${a(k)}`}]}}(e,t,r,c,g,d)
|
|
5222
|
+
if("report"===h)return await async function(e,t,r,a,c,d){const{status:h,summary:g,details:p,finish:f,relatesTo:w}=e
|
|
5223
|
+
if(!h||!g)throw new u.ValidationError("Report requires status and summary")
|
|
5207
5224
|
const b=i(0,0,"session_message_operations",0,d),I=await(async()=>{if(e.toSessionId&&"parent"!==e.toSessionId)return r.info("Using explicit toSessionId for report",{parentSessionId:e.toSessionId}),(0,y.asExternal)(e.toSessionId)
|
|
5208
5225
|
const t=await s(b,a,r)
|
|
5209
5226
|
if(t)return r.info("Auto-resolved parent session",{parentSessionId:t}),t
|
|
5210
5227
|
throw new u.ValidationError("Could not find parent session. Ensure this session was created with a parent link, or provide an explicit toSessionId.")})()
|
|
5211
5228
|
r.info("Submitting report",{sessionId:b,parentSessionId:I,status:h})
|
|
5212
|
-
const k=await c.createReport({fromSessionId:b,toSessionId:I,status:h,summary:
|
|
5229
|
+
const k=await c.createReport({fromSessionId:b,toSessionId:I,status:h,summary:g,details:p,...w?{relatesTo:w}:{}}),v=await n(b)??"agent",C={alchemy:{kind:"worker-report",payload:{status:h,summary:g,details:p,fromAgent:v,fromSessionId:b,...w?{relatesTo:w}:{}}}},_=await o(I,function(e,t="agent"){const r=e.content||{}
|
|
5213
5230
|
return(0,m.formatReportNotification)({messageCode:e.messageCode,status:r.reportStatus,summary:r.summary,details:r.details,fromSessionId:e.fromSessionId,senderAgent:t})}(k,v),t,r,C)
|
|
5214
|
-
return{content:[{type:"text",text:`\u2705 Report submitted.${_?"\n\n\u{1f4ec} The parent session has been notified.":"\n\n\u26a0\ufe0f Could not notify the parent session (may be offline)."}\n\n${l(k)}`}]}}(e,t,r,c,
|
|
5231
|
+
return{content:[{type:"text",text:`\u2705 Report submitted.${_?"\n\n\u{1f4ec} The parent session has been notified.":"\n\n\u26a0\ufe0f Could not notify the parent session (may be offline)."}\n\n${l(k)}`}]}}(e,t,r,c,g,d)
|
|
5215
5232
|
throw new u.ValidationError(`Unknown message type: ${h}. Use "question" or "report".`)}(e,t,k,b,I),r("send",e))
|
|
5216
5233
|
case"reply":if(!e.messageCode)throw new u.ValidationError("reply operation requires messageCode")
|
|
5217
|
-
return(0,
|
|
5234
|
+
return(0,p.withAlchemyKind)(await async function(e,t,r,s,i){const{messageCode:c}=e
|
|
5218
5235
|
if(!c)throw new u.ValidationError("reply operation requires messageCode")
|
|
5219
5236
|
const d=s.getSessionMessageClient()
|
|
5220
5237
|
if(!d)throw new u.ValidationError("Session message client not available")
|
|
5221
5238
|
if(c.startsWith("Q-")){const{text:s,selectedOptions:l,notes:u}=e,h=e.respondedBySessionId??i?.sessionId
|
|
5222
5239
|
r.info("Answering question",{messageCode:c,respondedBySessionId:h,autoDerived:!e.respondedBySessionId})
|
|
5223
|
-
const
|
|
5224
|
-
return r.text&&n.push("**Answer:** "+r.text),r.selectedOptions&&n.push("**Selected:** "+r.selectedOptions.join(", ")),r.notes&&n.push("**Notes:** "+r.notes),n.join("\n")}(
|
|
5225
|
-
return{content:[{type:"text",text:`\u2705 Question answered!${w?"\n\n\u{1f4ec} The asking session has been notified.":"\n\n\u26a0\ufe0f Could not notify the asking session (may be offline)."}\n\n${a(
|
|
5240
|
+
const g=await d.answerQuestion(c,{respondedBySessionId:h,text:s,selectedOptions:l,notes:u}),p=h?await n(h)??"agent":"agent",m=g.content||{},f=g.response||{},y={alchemy:{kind:"question-answered",payload:{messageCode:g.messageCode,question:m.question,answer:f.text,selectedOptions:f.selectedOptions,notes:f.notes,answeredByAgent:p,answeredBySessionId:h}}},w=await o(g.fromSessionId,function(e){const t=e.content||{},r=e.response||{},n=["\u{1f4ec} **Your question has been answered!**","","**Question Code:** "+e.messageCode,"**Question:** "+t.question,"","---","**Answered by:** "+e.respondedBySessionId]
|
|
5241
|
+
return r.text&&n.push("**Answer:** "+r.text),r.selectedOptions&&n.push("**Selected:** "+r.selectedOptions.join(", ")),r.notes&&n.push("**Notes:** "+r.notes),n.join("\n")}(g),t,r,y)
|
|
5242
|
+
return{content:[{type:"text",text:`\u2705 Question answered!${w?"\n\n\u{1f4ec} The asking session has been notified.":"\n\n\u26a0\ufe0f Could not notify the asking session (may be offline)."}\n\n${a(g)}`}]}}if(c.startsWith("R-")){r.info("Acknowledging report",{messageCode:c})
|
|
5226
5243
|
const e=await d.acknowledgeReport(c)
|
|
5227
5244
|
let s=""
|
|
5228
5245
|
if(e?.fromSessionId){const a=i?.sessionId,c=a?await n(a)??"agent":"agent",l=e.content||{},d={alchemy:{kind:"report-acknowledged",payload:{messageCode:e.messageCode,summary:l.summary,acknowledgedByAgent:c,acknowledgedBySessionId:a}}}
|
|
@@ -5235,13 +5252,13 @@ let l
|
|
|
5235
5252
|
try{const e=b.getSessionMessageClient()
|
|
5236
5253
|
if(e){const n=t.requestIds?.length||0,s=await e.createQuestion({fromSessionId:r,toSessionId:o||void 0,questionType:"alternatives",question:"Plan ready: "+(t.summary||"Plan complete"),options:[{id:"build",label:"Start Building",description:`Begin building ${n} request${1!==n?"s":""}`},{id:"plan",label:"Keep Planning",description:"Continue refining the plan"}],context:JSON.stringify({type:"plan-completion",plannerSessionId:r,parentSessionId:o,requestIds:t.requestIds,summary:t.summary}),category:"action-required",priority:"high"})
|
|
5237
5254
|
l=s?.messageCode,k.info("offer-handoff: notification question created",{fromSessionId:r,parentSessionId:o,messageCode:l})}else k.warn("offer-handoff: skipping notification question \u2014 no message client")}catch(e){k.warn("offer-handoff: failed to create notification question",{error:(0,h.getErrorMessage)(e)})}if(c&&l)try{const e=b.getSessionMessageClient()
|
|
5238
|
-
e&&(await e.answerQuestion(l,{respondedBySessionId:"system",selectedOptions:["build"]}),a=!0,k.info("offer-handoff: auto-confirmed for auto-planner",{fromSessionId:r,messageCode:l}))}catch(e){k.warn("offer-handoff: failed to auto-confirm for auto-planner",{error:(0,h.getErrorMessage)(e)})}return(0,
|
|
5255
|
+
e&&(await e.answerQuestion(l,{respondedBySessionId:"system",selectedOptions:["build"]}),a=!0,k.info("offer-handoff: auto-confirmed for auto-planner",{fromSessionId:r,messageCode:l}))}catch(e){k.warn("offer-handoff: failed to auto-confirm for auto-planner",{error:(0,h.getErrorMessage)(e)})}return(0,p.withAlchemyKind)({content:[{type:"text",text:a?"Handoff auto-confirmed (auto-planner). Start-building has been queued \u2014 you can stop now.":'Handoff offered to user. STOP here and wait \u2014 the user will choose "Start Building" or "Keep Planning". You will receive their choice as a new message. Do NOT generate any further output until then.'}],isError:!1,...(0,p.alchemyMeta)({pendingAction:{kind:"plan-handoff",payload:{summary:t.summary,requestIds:t.requestIds,parentSessionId:o,fromSessionId:r,autoConfirmed:a}}})},"offer-handoff")}case"list":return(0,p.withAlchemyKind)(await async function(e,t,r,n,o){let{sessionId:s,messageType:i,direction:a,status:c,readStatus:l,reportStatus:h,limit:g,offset:p}=e
|
|
5239
5256
|
const m=n.getSessionMessageClient()
|
|
5240
5257
|
if(!m)throw new u.ValidationError("Session message client not available")
|
|
5241
5258
|
if(!s){const e=o?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
|
|
5242
5259
|
if(!e)return r.warn("No session identity for list operation"),{content:[{type:"text",text:"\u26a0\ufe0f Could not determine current session ID. Unable to list messages without a session context."}]}
|
|
5243
5260
|
s=e,(0,w.logSessionIdentity)("session_message_operations.list","identity",{sessionId:s,fromCliOrigin:!!o?.sessionId})}r.debug("Listing messages",{sessionId:s,messageType:i,direction:a,status:c,readStatus:l})
|
|
5244
|
-
const y={sessionId:s,direction:a,limit:
|
|
5261
|
+
const y={sessionId:s,direction:a,limit:g,offset:p}
|
|
5245
5262
|
i&&"all"!==i&&(y.messageType=i),c&&"all"!==c&&("report"===i?y.reportStatus=c:y.status=c),l&&"all"!==l&&(y.readStatus=l),h&&"all"!==h&&(y.reportStatus=h)
|
|
5246
5263
|
const b=await m.listMessages(y)
|
|
5247
5264
|
if(0===b.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
|
|
@@ -5249,7 +5266,7 @@ const I=[`Found ${b.length} message(s):\n`]
|
|
|
5249
5266
|
for(const e of b)I.push("---\n"),I.push(d(e)),I.push("")
|
|
5250
5267
|
return{content:[{type:"text",text:I.join("\n")}]}}(e.list||{},0,k,b,I),"list-messages")
|
|
5251
5268
|
case"get":if(!e.messageCode)throw new u.ValidationError("get operation requires messageCode")
|
|
5252
|
-
return(0,
|
|
5269
|
+
return(0,p.withAlchemyKind)(await async function(e,t,r){const{messageCode:n}=e
|
|
5253
5270
|
if(!n)throw new u.ValidationError("get operation requires messageCode")
|
|
5254
5271
|
const o=r.getSessionMessageClient()
|
|
5255
5272
|
if(!o)throw new u.ValidationError("Session message client not available")
|
|
@@ -5257,7 +5274,7 @@ t.debug("Getting message",{messageCode:n})
|
|
|
5257
5274
|
const s=await o.getMessage(n)
|
|
5258
5275
|
return s?{content:[{type:"text",text:d(s)}]}:{content:[{type:"text",text:`\u274c Message with code ${n} not found.`}],isError:!0}}(e,k,b),"get-message")
|
|
5259
5276
|
default:throw new u.ValidationError(`Unknown operation: ${v}. Valid operations: send, reply, list, get`)}}catch(e){return k.error("Session message operation failed",{operation:v,error:(0,h.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c Error: "+(0,h.getErrorMessage)(e)}],isError:!0}}}
|
|
5260
|
-
const u=t(9860),h=t(8824),
|
|
5277
|
+
const u=t(9860),h=t(8824),g=t(7617),p=t(2272),m=t(7904),f=t(6688),y=t(3545),w=t(7280),b=(0,t(9414).getActionServerPort)(),I=new Map},9080(e,exports,t){"use strict"
|
|
5261
5278
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
5262
5279
|
const r=t(6183),n=t(1281)
|
|
5263
5280
|
exports.def={name:"search",description:"Search for text patterns in files on the currently active branch. Supports regex patterns and sorts results by file modification time (newest first).\n\nFile extensions: 'ts', '.ts', '*.ts' (all valid). Use '*' for any file type.\n\nCONTEXT LINES: Use contextLines option (0-10) to show surrounding lines before and after matches, reducing need for follow-up reads.\n\nLIST-ALL MODE: Omit 'needle' to list all files in a directory with tree structure (like ls/tree). Options: levels (1-4 depth), sortBy (name/modified/size/type).",schema:r.SearchSchema,annotations:{title:"Search Files",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleSearch)(e,t.context,t.apiClient,t.logger,t.metrics)}}},9089(e,exports){"use strict"
|
|
@@ -5283,12 +5300,12 @@ let l,d
|
|
|
5283
5300
|
try{l=await this.git.raw(["merge-base",i,c])}catch(t){return r.warn("Could not find merge-base, commits may be unrelated",{worktreeCommit:i.substring(0,8),targetCommit:c.substring(0,8),error:t}),{hasConflicts:!0,conflictedFiles:[{path:"<multiple files>",conflictType:"content",description:"Branches have diverged significantly (no merge-base found)"}],summary:"Branches have diverged significantly",resolutionInstructions:this.generateMultiAgentInstructions([{path:"<multiple files>",conflictType:"content",description:"Significant divergence"}],e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:"merge-base failed: "+t}}r.debug("Commits for merge-tree analysis",{worktreeCommit:i.substring(0,8),targetCommit:c.substring(0,8),mergeBase:l.trim().substring(0,8)})
|
|
5284
5301
|
let u=0
|
|
5285
5302
|
try{d=await this.git.raw(["merge-tree",l.trim(),c.trim(),i.trim()]),u=0}catch(e){d=e.message||"",u=e.exitCode||1,r.debug("merge-tree failed with error",{exitCode:u,error:e.message})}r.debug("Merge-tree analysis completed",{outputLength:d.length,hasOutput:!!d.trim(),exitCode:u})
|
|
5286
|
-
let h=!1,
|
|
5287
|
-
if(0!==u?(h=!0,
|
|
5288
|
-
!
|
|
5303
|
+
let h=!1,g="",p=null
|
|
5304
|
+
if(0!==u?(h=!0,g="merge-tree-exit-code"):d&&d.trim()?(p=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch),p.hasConflictMarkers?(h=!0,g="conflict-parser-detected-markers",r.warn("Git exit code 0 but conflict parser found conflict markers - treating as conflict")):(h=!1,g="clean-merge-with-changes",r.info("Git exit code 0 and conflict parser found no markers - treating as clean merge",{hasOutput:!0,outputLength:d.length}))):(h=!1,g="clean-merge-no-changes"),r.info("FINAL conflict detection result (trusting Git exit codes)",{hasConflicts:h,exitCode:u,hasOutput:!!d.trim(),outputLength:d?d.length:0,conflictReason:g,method:"git-exit-code-primary",trustedGitExitCode:0===u}),!h)return{hasConflicts:!1,conflictedFiles:[],summary:"No conflicts detected (merge-tree clean)",resolutionInstructions:"",detectionMethod:"merge-tree-analysis",rawOutput:d}
|
|
5305
|
+
!p&&d&&d.trim()&&(p=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch))
|
|
5289
5306
|
let m=[]
|
|
5290
|
-
if(
|
|
5291
|
-
else try{m=this.parseMergeTreeOutput(d,r),r.debug("Used fallback merge-tree parsing",{conflictedFilesCount:m.length})}catch(e){r.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),m=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===m.length&&(r.warn("Git detected conflicts but no files could be determined - using fallback"),m=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:m,summary:m.length>0&&"<parsing failed>"!==m[0].path&&"<unknown files>"!==m[0].path?m.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateMultiAgentInstructions(m,e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:d,rawConflictContent:
|
|
5307
|
+
if(p&&p.filesParsed&&p.filesParsed.length>0)m=p.filesParsed.map((e=>({path:e,conflictType:"content",description:"Merge conflict detected"}))),r.debug("Successfully extracted conflict files from parsed content",{conflictedFilesCount:m.length,files:m.map((e=>e.path))})
|
|
5308
|
+
else try{m=this.parseMergeTreeOutput(d,r),r.debug("Used fallback merge-tree parsing",{conflictedFilesCount:m.length})}catch(e){r.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),m=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===m.length&&(r.warn("Git detected conflicts but no files could be determined - using fallback"),m=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:m,summary:m.length>0&&"<parsing failed>"!==m[0].path&&"<unknown files>"!==m[0].path?m.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateMultiAgentInstructions(m,e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:d,rawConflictContent:p?p.cleanContent:void 0}}catch(e){throw r.error("Pure multi-agent conflict detection failed",{error:e}),e}}parseMergeTreeOutput(e,t){const r=[]
|
|
5292
5309
|
if(!e||!e.trim())return t.debug("Empty merge-tree output - no conflicts to parse"),[]
|
|
5293
5310
|
let n
|
|
5294
5311
|
try{n=e.split("\n"),t.debug("Parsing merge-tree output",{linesCount:n.length,totalLength:e.length,firstFewLines:n.slice(0,5),hasNewlines:e.includes("\n")})}catch(r){throw t.error("Failed to split merge-tree output into lines",{error:r instanceof Error?r.message:r+"",outputLength:e.length}),Error("Failed to parse merge-tree output: "+r)}let o=!1
|
|
@@ -5345,23 +5362,23 @@ o+=`## Test 4: All commits containing "${n}" (not just merges)\n`,o+=`Found ${e?
|
|
|
5345
5362
|
o+=`## Current branch: ${e}\n\n`}catch(e){o+=`## Current branch: Error - ${(0,r.getErrorMessage)(e)}\n\n`}try{const e=await t.git.branch()
|
|
5346
5363
|
o+="## All branches:\n",e.all&&e.all.length>0?e.all.forEach((e=>{o+=`- ${e}\n`})):o+="No branches found\n",o+="\n"}catch(e){o+=`## Branches: Error - ${(0,r.getErrorMessage)(e)}\n\n`}return{content:[{type:"text",text:o}]}}catch(e){return s.error("Error in debug request file history",{error:e instanceof Error?e.stack:e+""}),{content:[{type:"text",text:"Error: "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
5347
5364
|
const r=t(8824)},9442(e,exports,t){"use strict"
|
|
5348
|
-
function r(e){return{line:e.line,actually_matched:e.actuallyMatched,match_type:e.matchType}}async function n(e,t,n,o,s,i,a){const{path:c,documentId:d,replacements:
|
|
5365
|
+
function r(e){return{line:e.line,actually_matched:e.actuallyMatched,match_type:e.matchType}}async function n(e,t,n,o,s,i,a){const{path:c,documentId:d,replacements:g,fuzzy_match:p}=e,m=!!d,f=void 0!==p?p:t,y={type:m?"document":"file",path:c,documentId:d,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,externalEditDebugInfo:{detectionRan:!1,reason:m?"Skipped: Document operation":n.git?"Pending":"Skipped: No Git context"}}
|
|
5349
5366
|
try{let t,o
|
|
5350
5367
|
if(m){t=await n.documentFileManager.getDocumentAsFile(d)
|
|
5351
5368
|
const e=n.documentFileManager.getCachedDocumentInfo(d)
|
|
5352
5369
|
y.filename=e?.filename,o="document:"+d}else{const e=u.validateAndNormalizePath(c,n)
|
|
5353
|
-
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),
|
|
5354
|
-
for(const t of
|
|
5370
|
+
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),p=[]
|
|
5371
|
+
for(const t of g){const{old:n,new:o,match_mode:i="unique"}=t,a={old:n,new:o,success:!1}
|
|
5355
5372
|
try{if(n===o){a.error="No-op replacement (old and new values are identical)",a.success=!1,a.matchesFound=0,y.failedReplacements++,y.replacements.push(a)
|
|
5356
5373
|
continue}const t=(0,h.findMatches)(s,n,f,100,e.path)
|
|
5357
5374
|
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(f?" (tried fuzzy matching)":""),a.success=!1
|
|
5358
5375
|
const e=(0,h.findSimilarMatches)(s,n,5,.3)
|
|
5359
|
-
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++):
|
|
5376
|
+
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
|
|
5360
5377
|
const I=[]
|
|
5361
|
-
for(const e of
|
|
5378
|
+
for(const e of p)for(const t of e.matches)I.push({match:t,newText:e.newText,repResult:e.repResult})
|
|
5362
5379
|
I.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5363
5380
|
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++)
|
|
5364
|
-
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),m&&(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=
|
|
5381
|
+
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),m&&(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)
|
|
5365
5382
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5366
5383
|
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=[]
|
|
5367
5384
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -5376,7 +5393,7 @@ if("errorResult"in T)return T.errorResult
|
|
|
5376
5393
|
const{taskId:q}=T,{operations:P,fuzzy_match:j=!0,comment:R}=E
|
|
5377
5394
|
k.info("Replace in files batch operation",{taskId:q,operationCount:P.length,totalReplacements:P.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:j,comment:R})
|
|
5378
5395
|
const x=P.filter((e=>e.documentId)).map((e=>e.documentId))
|
|
5379
|
-
if(x.length>0&&r.apiClient)try{await(0,f.ensureDocumentsNotLocked)(x,r.apiClient,k,c,"replace_in_files-documents")}catch(e){if(e instanceof
|
|
5396
|
+
if(x.length>0&&r.apiClient)try{await(0,f.ensureDocumentsNotLocked)(x,r.apiClient,k,c,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5380
5397
|
throw e}_=u.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_in_files_phase",1,{phase:_})
|
|
5381
5398
|
const M=P[0],O=M.documentId?"document:"+M.documentId:M.path
|
|
5382
5399
|
let $=Date.now()
|
|
@@ -5391,7 +5408,7 @@ const t=await u.autoPromoteTaskStatus(q,D.status,A,e.request?.status,O,o,i,k,c,"
|
|
|
5391
5408
|
t.taskPromoted&&k.info("Auto-promoted task to in_progress",{taskId:q,requestId:A,previousStatus:D.status,newStatus:t.newTaskStatus}),Date.now(),$=Date.now()
|
|
5392
5409
|
const n=await u.ensureCorrectWorkspaceContext({taskPromoted:t.taskPromoted,requestId:A,context:r,operation:"replace_in_files",logger:k,metrics:c,metricsPrefix:"replace_in_files"})
|
|
5393
5410
|
if(!n.success)throw Error(n.error)
|
|
5394
|
-
Date.now(),N=!0}if(x.length>0&&A)try{await(0,
|
|
5411
|
+
Date.now(),N=!0}if(x.length>0&&A)try{await(0,p.validateRequestStatusForDocumentOperation)(A,i,k,c,"replace_in_files-documents")}catch(e){if(e instanceof g.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5395
5412
|
throw e}$=Date.now()
|
|
5396
5413
|
const z=new Map
|
|
5397
5414
|
if(k.info("\u{1f50d} Starting external edit detection",{hasFileOperations:F,hasGit:!!r.git,operationCount:P.length}),F&&r.git)for(const e of P)if(e.path&&!e.documentId)try{const t=u.validateAndNormalizePath(e.path,r),n=await l.default.readFile(t.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:j,s=[]
|
|
@@ -5427,7 +5444,7 @@ const d=o.workspaceManager?.consumeLargeFileWarning(o.currentSessionId)
|
|
|
5427
5444
|
return d&&(c+=d),c}(H,W,J,Q,r)
|
|
5428
5445
|
return{content:[{type:"text",text:ee}],isError:0===J,...(0,d.alchemyMeta)({kind:"replace-in-files",toolRecordId:C,failed:Q>0})}}catch(e){const t=Date.now()-v
|
|
5429
5446
|
if(k.error("Replace in files batch operation failed",{error:e instanceof Error?e.stack:e+"",duration:t,phase:_}),C)try{await s.updateToolRecord(C,{metadata:{status:"failed",error:(0,b.getErrorMessage)(e),phase:_,duration:t}})}catch(e){}return c.incrementCounter("replace_in_files_errors",1,{phase:_}),{content:[{type:"text",text:"\u274c **Replace In Files Failed:** "+(0,b.getErrorMessage)(e)}],isError:!0}}},c(t(857))
|
|
5430
|
-
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(2272)),u=a(t(5967)),h=t(3626),
|
|
5447
|
+
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(2272)),u=a(t(5967)),h=t(3626),g=t(9860),p=t(5003),m=t(7478),f=t(9949),y=t(9947),w=t(1318),b=t(8824)},9470(e,exports){"use strict"
|
|
5431
5448
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
|
|
5432
5449
|
const t=e.trim()
|
|
5433
5450
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|
|
@@ -5496,12 +5513,12 @@ const s=n.sortDirection??"desc"
|
|
|
5496
5513
|
return o.sortDirection="asc"===s||"desc"===s?s:"desc",{requestId:r,filters:o}}catch(t){throw new r.ValidationError("Invalid input: "+(0,n.getErrorMessage)(t),{args:e,error:t})}}(e),u=t.projectId
|
|
5497
5514
|
if(!u)throw new r.ValidationError("Project ID is required for listing tasks with the new API structure")
|
|
5498
5515
|
a.incrementCounter("list_tasks_attempts",1,{hasRequestId:!!i,hasFilters:Object.keys(d).length>0}),s.setProjectId(u)
|
|
5499
|
-
const h=s.getTaskClient(),
|
|
5500
|
-
i&&(
|
|
5501
|
-
const
|
|
5502
|
-
c.info("Raw tasks response data",{responseData:JSON.stringify(
|
|
5516
|
+
const h=s.getTaskClient(),g=d
|
|
5517
|
+
i&&(g.requestId=i),c.info("Listing tasks with filters",{projectId:u,taskFilters:g})
|
|
5518
|
+
const p=await h.listTasks(g)
|
|
5519
|
+
c.info("Raw tasks response data",{responseData:JSON.stringify(p)}),c.info("Tasks response structure",{type:typeof p,isArray:Array.isArray(p),hasData:null!=p,properties:p?Object.keys(p):[],dataPreview:p?JSON.stringify(p).substring(0,200)+"...":"null"})
|
|
5503
5520
|
let m=[]
|
|
5504
|
-
|
|
5521
|
+
p&&"object"==typeof p?"success"in p&&"data"in p?Array.isArray(p.data)?(m=p.data,c.info("Extracted tasks from success/data wrapper",{count:m.length})):p.data&&"object"==typeof p.data&&(m=[p.data],c.info("Extracted single task from success/data wrapper")):"data"in p?Array.isArray(p.data)?(m=p.data,c.info("Extracted tasks from data wrapper",{count:m.length})):p.data&&"object"==typeof p.data&&(m=[p.data],c.info("Extracted single task from data wrapper")):Array.isArray(p)?(m=p,c.info("Tasks response is direct array",{count:m.length})):(m=[p],c.info("Tasks response is single object")):(c.warn("Unexpected response format, using empty array",{responseType:typeof p}),m=[])
|
|
5505
5522
|
const f=m
|
|
5506
5523
|
if(c.info(`Retrieved ${f.length} tasks`,{count:f.length,requestId:i,projectId:u}),0===f.length){let e=""
|
|
5507
5524
|
return e=i?`No tasks found for request ${i}.`:`No tasks found for project ${u} with the specified filters.`,l({success:!0,taskCount:0}),{content:[{type:"text",text:e}]}}const y=f.map(((e,t)=>{const r=e.sequenceNumber??t+1
|
|
@@ -5611,8 +5628,8 @@ function r(e){return a.default.createHash("md5").update(e).digest("hex")}async f
|
|
|
5611
5628
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.syncPluginsGlobal=async function(e,t,o){const a={synced:[],skipped:[],errors:[]},d=o||function(){const e=process.argv[1]
|
|
5612
5629
|
let t=e
|
|
5613
5630
|
try{t=s.default.realpathSync(e)}catch{}return i.default.dirname(t)}(),u=i.default.join((0,c.getGlobalConfigDir)(e),"plugin")
|
|
5614
|
-
try{await s.default.promises.mkdir(u,{recursive:!0})}catch(e){return t.error("Failed to create global plugin directory",{destDir:u,error:e instanceof Error?e.message:"Unknown error"}),a}const h=i.default.join(u,"package.json"),
|
|
5615
|
-
try{await s.default.promises.readFile(h,"utf8").catch((()=>null))!==
|
|
5631
|
+
try{await s.default.promises.mkdir(u,{recursive:!0})}catch(e){return t.error("Failed to create global plugin directory",{destDir:u,error:e instanceof Error?e.message:"Unknown error"}),a}const h=i.default.join(u,"package.json"),g='{"type":"module"}\n'
|
|
5632
|
+
try{await s.default.promises.readFile(h,"utf8").catch((()=>null))!==g&&await s.default.promises.writeFile(h,g,"utf8")}catch(e){t.warn("Failed to write global plugin package.json",{error:e instanceof Error?e.message:"Unknown error"})}for(const e of l){const o=i.default.join(d,e.sourceName),c=i.default.join(u,e.destName)
|
|
5616
5633
|
try{if(!s.default.existsSync(o)){t.warn("Plugin source not found: "+e.sourceName,{sourcePath:o}),a.errors.push(e.destName)
|
|
5617
5634
|
continue}const i=await s.default.promises.readFile(o,"utf8").catch((()=>null))
|
|
5618
5635
|
if(null===i){t.warn("Could not read plugin source: "+e.sourceName),a.errors.push(e.destName)
|