alchemylab 1.4.2 → 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 +129 -102
- package/dist/http-server.js +62 -50
- package/dist/index.js +620 -608
- package/dist/mcp-direct.js +590 -578
- package/package.json +1 -1
- 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]
|
|
@@ -1346,20 +1346,25 @@ l=e.map(((e,t)=>({name:"setup-"+(t+1),command:e,timeout:120})))}else{const t=pro
|
|
|
1346
1346
|
if(!r){const r=t.map((e=>e.name)).join(", ")
|
|
1347
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
|
-
const r
|
|
1357
|
-
|
|
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})`
|
|
1358
1363
|
return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\``})).join("\n\n")
|
|
1359
|
-
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")
|
|
1360
1365
|
try{const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=await u.getSessionRequestId(i,a,l?.sessionId)
|
|
1361
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}
|
|
1362
|
-
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]
|
|
1363
1368
|
if(!f)return d({success:!1,error:"no_test_run"}),{content:[{type:"text",text:`No test run found for request ${h}.`}],isError:!0}
|
|
1364
1369
|
const y=f.id
|
|
1365
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)})))
|
|
@@ -1375,15 +1380,15 @@ const o=r.map((e=>`**${e.name}** (${e.id})${e.scope?` [scope: ${e.scope}]`:""}\n
|
|
|
1375
1380
|
return d({success:!0}),{content:[{type:"text",text:`## Test Processes (${r.length})\n\n${o}`}]}}if("run"===e.operation){let c=0
|
|
1376
1381
|
try{const e=await i.proxyGet(`/api/projects/${n.projectId}/test-processes`),t=e?.data||e||[]
|
|
1377
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}
|
|
1378
|
-
const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=l?.sessionId,
|
|
1379
|
-
if(!
|
|
1380
|
-
const
|
|
1381
|
-
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)})
|
|
1382
1387
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
1383
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()
|
|
1384
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}
|
|
1385
|
-
const r=t.data.spawnedSessionIds?.[0],n=
|
|
1386
|
-
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:[]
|
|
1387
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
|
|
1388
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)})
|
|
1389
1394
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
@@ -1443,18 +1448,18 @@ t.info("commit_to_viewed_session:parsed",{callId:i,messagePreview:c.slice(0,80),
|
|
|
1443
1448
|
const l=o.sessionIdentity.getIdentity(),d=l?.sessionId,u=l?.serverUrl
|
|
1444
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}
|
|
1445
1450
|
let h
|
|
1446
|
-
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]
|
|
1447
1452
|
if("user"===r.info?.role)for(const e of r.parts??[]){if("text"!==e.type||!e.text)continue
|
|
1448
1453
|
const t=e.text.match(/<viewed_session\s+id="([^"]+)"\s*\/?>/)
|
|
1449
1454
|
if(t)return t[1]}}return null}(h)
|
|
1450
|
-
if(!
|
|
1451
|
-
let
|
|
1452
|
-
try{
|
|
1453
|
-
if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,
|
|
1454
|
-
|
|
1455
|
-
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)})
|
|
1456
1461
|
if(t.info("commit_to_viewed_session:posted",{callId:i,status:e.status}),!e.ok){const t=await e.text().catch((()=>""))
|
|
1457
|
-
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."}]}}
|
|
1458
1463
|
const n=t(8824),o=t(6688),s=t(2272)},2141(e,exports,t){"use strict"
|
|
1459
1464
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConflictResolver=void 0,exports.createConflictResolver=function(e){return new n(e)}
|
|
1460
1465
|
const r=t(8824)
|
|
@@ -1530,53 +1535,53 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
1530
1535
|
var t={}
|
|
1531
1536
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
1532
1537
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1533
|
-
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()
|
|
1534
1539
|
let w,b,I=l.FileOperationPhase.VALIDATION
|
|
1535
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"}
|
|
1536
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)
|
|
1537
1542
|
if("errorResult"in _)return _.errorResult
|
|
1538
1543
|
const{taskId:E}=_
|
|
1539
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")
|
|
1540
|
-
l.validateTaskIdFormat(E,f,
|
|
1545
|
+
l.validateTaskIdFormat(E,f,p,k.metricsPrefix)
|
|
1541
1546
|
const S=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1542
1547
|
f.info("Initial branch context",{initialBranch:S.branch,initialRequestId:S.requestId,isMain:S.isMain})
|
|
1543
1548
|
const T=[]
|
|
1544
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)
|
|
1545
|
-
T.push({source:t,destination:o,fullSource:n,fullDestination:s})}I=l.FileOperationPhase.TASK_VALIDATION,
|
|
1546
|
-
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)
|
|
1547
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})
|
|
1548
|
-
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})
|
|
1549
1554
|
if(!x.success)throw Error(x.error)
|
|
1550
1555
|
let M={hadUserMods:!1,userModsCommitHash:void 0}
|
|
1551
1556
|
if(r.git)try{f.debug("[MOVE-FILES] Checking for user changes before move operations")
|
|
1552
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:P,taskId:E,workspaceManager:r.workspaceManager},f,
|
|
1553
|
-
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,
|
|
1554
|
-
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,
|
|
1555
|
-
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})
|
|
1556
1561
|
const D=[]
|
|
1557
1562
|
let A=0
|
|
1558
1563
|
for(const e of T){const t={operation:{source:e.source,destination:e.destination},success:!1}
|
|
1559
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()
|
|
1560
1565
|
t.isDirectory=r
|
|
1561
1566
|
const n=c.default.dirname(e.fullDestination)
|
|
1562
|
-
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,
|
|
1563
|
-
|
|
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)
|
|
1564
1569
|
let N=null
|
|
1565
|
-
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})
|
|
1566
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}`
|
|
1567
|
-
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})
|
|
1568
1573
|
const z=D.filter((e=>e.success)),L=D.filter((e=>!e.success))
|
|
1569
|
-
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)
|
|
1570
1575
|
const H=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1571
1576
|
let B=""
|
|
1572
1577
|
if(A===u.length)B=`Successfully moved all ${u.length} ${1===u.length?"item":"items"}`
|
|
1573
1578
|
else if(A>0){const e=D.filter((e=>!e.success))
|
|
1574
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")
|
|
1575
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
|
|
1576
|
-
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,
|
|
1577
|
-
if(
|
|
1578
|
-
try{await l.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",k.recordType,"Failed to move files",{status:"failed",error:(0,
|
|
1579
|
-
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"
|
|
1580
1585
|
module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){"use strict"
|
|
1581
1586
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1582
1587
|
const r=t(6183),n=t(3707)
|
|
@@ -1584,7 +1589,7 @@ exports.def={name:"quick_manage",description:"WHEN TO USE: trivial single-file e
|
|
|
1584
1589
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildTaskEndpoint=function(e,t,r){const n=r?"/"+r.replace(/^\//,""):""
|
|
1585
1590
|
return`/api/projects/${e}/tasks/${encodeURIComponent(t)}${n}`}},2462(e,exports,t){"use strict"
|
|
1586
1591
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
1587
|
-
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"
|
|
1588
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"
|
|
1589
1594
|
async function r(e,t,r){if(v.has(r)&&C>=t){if(0===t)return 0
|
|
1590
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]"
|
|
@@ -1608,12 +1613,12 @@ case"size":s||"number"!=typeof o.size||(l+=` (${function(e){if(0===e)return"0 by
|
|
|
1608
1613
|
let t=e,r=0
|
|
1609
1614
|
for(;t>=1024&&4>r;)t/=1024,r++
|
|
1610
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[]
|
|
1611
|
-
try{const{fullPath:d}=b.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),
|
|
1612
|
-
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():""
|
|
1613
1618
|
let f
|
|
1614
|
-
d.isFile()&&(f=await r(h,
|
|
1615
|
-
const I={name:d.name,isDirectory:d.isDirectory(),depth:n,size:
|
|
1616
|
-
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""
|
|
1617
1622
|
const o=[]
|
|
1618
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?"/":""
|
|
1619
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)
|
|
@@ -1636,21 +1641,21 @@ case"size":const t=e.size||0,n=r.size||0
|
|
|
1636
1641
|
return t!==n?n-t:e.name.localeCompare(r.name)
|
|
1637
1642
|
case"type":const o=e.extension||"",s=r.extension||""
|
|
1638
1643
|
return o!==s?o.localeCompare(s):e.name.localeCompare(r.name)
|
|
1639
|
-
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)
|
|
1640
1645
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1641
|
-
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=[]
|
|
1642
1647
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
1643
1648
|
return t},h(e)},function(e){if(e&&e.__esModule)return e
|
|
1644
1649
|
var t={}
|
|
1645
|
-
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&
|
|
1646
|
-
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}}
|
|
1647
1652
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
|
|
1648
|
-
let
|
|
1653
|
+
let g=b.FileOperationPhase.VALIDATION
|
|
1649
1654
|
b.FileOperationPhase.FILE_WRITE
|
|
1650
|
-
try{const
|
|
1655
|
+
try{const p=e,{path:m,levels:f=1,sortBy:I="name"}=p
|
|
1651
1656
|
i.info("Listing directory: "+m)
|
|
1652
1657
|
const{normalizedPath:v,fullPath:C}=b.validateAndNormalizePath(m,t)
|
|
1653
|
-
|
|
1658
|
+
g=b.FileOperationPhase.FILE_WRITE
|
|
1654
1659
|
try{if(!(await y.default.stat(C)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+m}],isError:!0}
|
|
1655
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
|
|
1656
1661
|
if(f>1){i.info(`Building tree structure for: ${v} (levels: ${f}, sortBy: ${I})`)
|
|
@@ -1776,40 +1781,40 @@ return(0,n.safeGetResponseData)(i,[],this.logger)}async expirePendingQuestions()
|
|
|
1776
1781
|
this.logger.info("Expiring pending questions")
|
|
1777
1782
|
const t=await this.requestWithRetry("POST",`/api/projects/${e}/session-messages/expire`,{})
|
|
1778
1783
|
return(0,n.safeGetResponseData)(t,{expiredCount:0},this.logger).expiredCount}}exports.SessionMessageClient=o},2736(e,exports,t){"use strict"
|
|
1779
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,l,d,u,h){const
|
|
1780
|
-
|
|
1781
|
-
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")
|
|
1782
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)
|
|
1783
1788
|
throw new r.ValidationError("Invalid input: "+(0,a.getErrorMessage)(e))}}(e)
|
|
1784
1789
|
let u=o.taskId
|
|
1785
|
-
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))
|
|
1786
1791
|
const f=l.projectId
|
|
1787
1792
|
if(!f)throw new r.ValidationError("Project ID is required for completing tasks with the new API structure")
|
|
1788
1793
|
h.incrementCounter("complete_task_attempts",1,{taskId:u}),d.setProjectId(f)
|
|
1789
1794
|
const y=d.getTaskClient()
|
|
1790
1795
|
let w
|
|
1791
1796
|
try{const e=await y.getTask(u)
|
|
1792
|
-
|
|
1793
|
-
const t=(0,s.extractDataFromResponse)(e,{logger:
|
|
1794
|
-
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
|
|
1795
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."
|
|
1796
|
-
throw
|
|
1797
|
-
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
|
|
1798
1803
|
if(l.workspaceManager){const e=l.workspaceManager.getCurrentContext(l.currentSessionId)
|
|
1799
1804
|
if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
|
|
1800
|
-
b=simpleGit({baseDir:e.basePath,binary:l.gitBinary}),
|
|
1801
|
-
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
|
|
1802
1807
|
try{const e=d.getToolRecordClient()
|
|
1803
|
-
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){
|
|
1804
|
-
|
|
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})
|
|
1805
1810
|
const i=w.requestId,l=w.requestId
|
|
1806
1811
|
let d=`Task ${w.sequenceNumber&&l?(0,c.formatTaskRef)(l,w.sequenceNumber):u} (${w.title}) has been marked as completed.`
|
|
1807
1812
|
if(I&&(d+="\nCommit: "+I.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
|
|
1808
|
-
|
|
1809
|
-
const t=(0,s.extractArrayFromResponse)(e,{logger:
|
|
1810
|
-
|
|
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()
|
|
1811
1816
|
if(n){const o=t instanceof r.NotFoundError||t instanceof r.ValidationError||t instanceof i.ZodError
|
|
1812
|
-
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"})
|
|
1813
1818
|
let n=(0,a.getErrorMessage)(t)
|
|
1814
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}}}
|
|
1815
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"
|
|
@@ -1818,19 +1823,19 @@ if(!r())return t.level=(0,l.isDevBuild)()?c.LogLevel.INFO:c.LogLevel.ERROR,t.log
|
|
|
1818
1823
|
if("true"===process.env.DEBUG_LOGGING?.toLowerCase()){t.level=c.LogLevel.DEBUG,t.logToFile=!0
|
|
1819
1824
|
const r=e||process.cwd()
|
|
1820
1825
|
t.logFilePath=i.default.join(r,"logs","debug.log")}const n=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
1821
|
-
return n&&Object.values(c.LogLevel).includes(n)&&(t.level=n),t}(e.baseDir),...e},{level:o=c.LogLevel.INFO,serviceName:
|
|
1822
|
-
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)
|
|
1823
1828
|
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(m)
|
|
1824
1829
|
const e=o===c.LogLevel.DEBUG&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()
|
|
1825
|
-
f.push(new s.default.transports.File({filename:m,format:e?h:u}))}const y=s.default.createLogger({level:o,defaultMeta:{service:
|
|
1826
|
-
return o===c.LogLevel.DEBUG&&
|
|
1827
|
-
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}}
|
|
1828
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
|
|
1829
1834
|
const e=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
1830
1835
|
return e&&Object.values(c.LogLevel).includes(e)?e:c.LogLevel.INFO}
|
|
1831
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):""
|
|
1832
|
-
return`${r} ${i}${a} [${e.toUpperCase()}]: ${t}${c}`}))),
|
|
1833
|
-
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"
|
|
1834
1839
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1835
1840
|
const r=t(6183),n=t(9442)
|
|
1836
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"
|
|
@@ -1881,17 +1886,17 @@ i.info("Request breakdown",{fileRequests:d.length,documentRequests:u.length})
|
|
|
1881
1886
|
const h=[]
|
|
1882
1887
|
for(const e of d)h.push(r(e,t,0,l))
|
|
1883
1888
|
for(const e of u)h.push(n(e,t,0,l))
|
|
1884
|
-
const
|
|
1889
|
+
const p=await Promise.all(h)
|
|
1885
1890
|
let m=""
|
|
1886
1891
|
if(t.workspaceManager)try{const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
1887
|
-
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
|
|
1888
1893
|
let b="## Read Files/Documents\n\n"
|
|
1889
1894
|
m&&(b+=m),b+=`**Total Requests:** ${w} - **Successful:** ${f} - **Failed:** ${y}\n\n`
|
|
1890
|
-
for(let e=0;e<
|
|
1895
|
+
for(let e=0;e<p.length;e++){const t=p[e]
|
|
1891
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
|
|
1892
|
-
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
|
|
1893
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}}}
|
|
1894
|
-
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"
|
|
1895
1900
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.TaskClient=void 0
|
|
1896
1901
|
const r=t(8824),n=t(7645),o=t(2161),s=t(2450)
|
|
1897
1902
|
class i extends n.ConnectionAwareClient{async createTask(e){if(this.logger.debug("Creating task",{taskInput:e}),!e.projectId){const t=this.projectClient.getProjectId()
|
|
@@ -1969,9 +1974,9 @@ throw c.error(`STRICT VALIDATION - File operation blocked on ${u.status} request
|
|
|
1969
1974
|
const n=(0,s.getErrorMessage)(r)
|
|
1970
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
|
|
1971
1976
|
const n=(0,s.getErrorMessage)(r)
|
|
1972
|
-
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,
|
|
1973
|
-
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),
|
|
1974
|
-
|
|
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)
|
|
1975
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})
|
|
1976
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})
|
|
1977
1982
|
const t=`Cannot complete request ${e} - no tasks found. Create tasks for this request before attempting completion.`
|
|
@@ -1998,7 +2003,7 @@ l.info("Generating journal for request",{requestId:a})
|
|
|
1998
2003
|
const u=t.projectId
|
|
1999
2004
|
if(!u)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
|
|
2000
2005
|
o.setProjectId(u),l.info("Fetching request data, tasks, and file history in parallel")
|
|
2001
|
-
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})))
|
|
2002
2007
|
l.info(`Fetched request, ${v.length} tasks, ${y.length} tool records`)
|
|
2003
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()))
|
|
2004
2009
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
@@ -2026,7 +2031,7 @@ var o=Object.getOwnPropertyDescriptor(t,r)
|
|
|
2026
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)}
|
|
2027
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"
|
|
2028
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))
|
|
2029
|
-
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
|
|
2030
2035
|
try{const h=t.projectId
|
|
2031
2036
|
if(!h)throw Error("Project ID not available")
|
|
2032
2037
|
d.setProjectId(h)
|
|
@@ -2034,15 +2039,15 @@ const f=await async function(e,t,r,n){const o=n?.sessionId||e.currentSessionId
|
|
|
2034
2039
|
if(!o||"__unknown__"===o||"__server__"===o)throw Error("Cannot resolve request: no session identity available")
|
|
2035
2040
|
const i=await s.sessionIdentity.getSessionRequestId(t,r,o)
|
|
2036
2041
|
if(!i)throw Error("No request associated with session "+o)
|
|
2037
|
-
return i}(t,d,u,
|
|
2042
|
+
return i}(t,d,u,g)
|
|
2038
2043
|
switch(m){case"create":{const{title:t,description:r}=e
|
|
2039
2044
|
if(!t)return{content:[{type:"text",text:"Error: title is required for create"}],isError:!0}
|
|
2040
2045
|
if(!r)return{content:[{type:"text",text:"Error: description is required for create"}],isError:!0}
|
|
2041
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
|
|
2042
|
-
let
|
|
2043
|
-
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
|
|
2044
2049
|
let y=m?`Created #${m}: ${t}`:`Created ${(0,l.formatTaskRefForAgent)(u)}: ${t}`
|
|
2045
|
-
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
|
|
2046
2051
|
if(!t)return{content:[{type:"text",text:"Error: summary is required for done"}],isError:!0}
|
|
2047
2052
|
const{active:r,nextPending:n}=await o(d,f)
|
|
2048
2053
|
if(!r)return{content:[{type:"text",text:"No active (in_progress) task to complete."}],isError:!0}
|
|
@@ -2052,7 +2057,7 @@ const u=r.sequenceNumber
|
|
|
2052
2057
|
let h=u?`Completed #${u}: ${r.title}`:`Completed ${(0,l.formatTaskRefForAgent)(r.taskId)}: ${r.title}`
|
|
2053
2058
|
if(n)try{await s.updateTaskStatus(n.taskId,"in_progress")
|
|
2054
2059
|
const e=n.sequenceNumber
|
|
2055
|
-
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."
|
|
2056
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))
|
|
2057
2062
|
if(o){const e=r(o)
|
|
2058
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
|
|
@@ -2067,7 +2072,7 @@ l&&await o.updateTaskStatus(l.localId||l.id,"pending"),await o.updateTaskStatus(
|
|
|
2067
2072
|
const u=r(i),h=l?` (paused ${n(r(l))}: ${l.title})`:""
|
|
2068
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"})
|
|
2069
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
|
|
2070
|
-
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}}}
|
|
2071
2076
|
const s=t(6688),i=t(8824),a=t(3451),c=t(2272),l=t(4466)},3253(e,exports){"use strict"
|
|
2072
2077
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTimestamp=function(e,t){const r=e instanceof Date?e:new Date(e)
|
|
2073
2078
|
if(isNaN(r.getTime()))return"Invalid date"
|
|
@@ -2144,7 +2149,7 @@ R.push({type:"file",path:t,fullPath:n,replacements:e.replacements,mode:e.mode||"
|
|
|
2144
2149
|
if(j.length>0&&!r.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
2145
2150
|
for(const e of j)x.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
|
|
2146
2151
|
if(x.length>0&&r.apiClient){const e=x.map((e=>e.documentId))
|
|
2147
|
-
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}
|
|
2148
2153
|
throw e}}k=d.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
2149
2154
|
const M=R.length>0?R[0].path:"document-operation",O=await d.validateTaskId(q,M,o,y,c,v.metricsPrefix),$=O?.requestId
|
|
2150
2155
|
let D=null
|
|
@@ -2159,7 +2164,7 @@ R[e]={...t,path:o,fullPath:s}}}if(x.length>0&&$)try{await(0,h.validateRequestSta
|
|
|
2159
2164
|
throw e}k=d.FileOperationPhase.RECORD_CREATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
2160
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)
|
|
2161
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")
|
|
2162
|
-
const e=await(0,
|
|
2167
|
+
const e=await(0,g.commitUserChangesBeforeToolOperation)(r.git,"replace-strings",{requestId:$,taskId:q,workspaceManager:r.workspaceManager},y,c)
|
|
2163
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})
|
|
2164
2169
|
const L=[]
|
|
2165
2170
|
let H=0,B=0
|
|
@@ -2183,7 +2188,7 @@ for(const t of e.replacements.filter((e=>!e.success)))Z+=` - "${t.old_str}" \u2
|
|
|
2183
2188
|
const X=Date.now()-w
|
|
2184
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
|
|
2185
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}}}
|
|
2186
|
-
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"
|
|
2187
2192
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
2188
2193
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
2189
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=[]
|
|
@@ -2217,10 +2222,10 @@ var u=t(1887)
|
|
|
2217
2222
|
Object.defineProperty(exports,"ProxyClient",{enumerable:!0,get(){return u.ProxyClient}})
|
|
2218
2223
|
var h=t(4192)
|
|
2219
2224
|
Object.defineProperty(exports,"BaseApiClient",{enumerable:!0,get(){return h.BaseApiClient}})
|
|
2220
|
-
var
|
|
2221
|
-
Object.defineProperty(exports,"SessionRequestAssociationClient",{enumerable:!0,get(){return
|
|
2222
|
-
var
|
|
2223
|
-
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}})
|
|
2224
2229
|
var m=t(6539)
|
|
2225
2230
|
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return m.ClientFactory}})
|
|
2226
2231
|
const f=t(6539)
|
|
@@ -2246,14 +2251,14 @@ if(t&&"object"==typeof t&&(n="description"in t&&!!t.description),t){const e={id:
|
|
|
2246
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+"")
|
|
2247
2252
|
const n=e
|
|
2248
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()}
|
|
2249
|
-
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
|
|
2250
2255
|
if(h.requestId)try{const e=i.getRequestClient()
|
|
2251
|
-
|
|
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"
|
|
2252
2257
|
try{const t=new Date(e)
|
|
2253
|
-
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)
|
|
2254
2259
|
let I=`# Task: ${h.title} (${b})\n\n`
|
|
2255
|
-
if(I+=`**Status**: ${h.status}\n`,I+=`**Created**: ${m}\n`,I+=`**Updated**: ${f}\n`,h.requestId&&(I+="**Parent Request**: "+h.requestId,I+=
|
|
2256
|
-
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`)
|
|
2257
2262
|
const t=["lastCommit","completedAt","completionSummary"]
|
|
2258
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})
|
|
2259
2264
|
try{const n=i.getToolRecordClient()
|
|
@@ -2291,7 +2296,7 @@ const r=t(6183),n=t(8317)
|
|
|
2291
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"
|
|
2292
2297
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2293
2298
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
2294
|
-
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:_})
|
|
2295
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")
|
|
2296
2301
|
E.info("Using remote server URL",{remoteServerUrl:T}),async function(){try{E.info("Finding available port...",{preferredPort:_,baseDir:C,remoteServerUrl:T})
|
|
2297
2302
|
const e=await(0,f.findAvailablePort)(_)
|
|
@@ -2301,14 +2306,14 @@ E.info(`Checking ${m.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensur
|
|
|
2301
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}})
|
|
2302
2307
|
E.info("Using project",{projectId:P.id,projectName:P.name})
|
|
2303
2308
|
const j=(0,o.default)()
|
|
2304
|
-
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))
|
|
2305
2310
|
try{E.info("Creating MCP server instance")
|
|
2306
2311
|
const t=await(0,i.createServer)(C,E,S,T,{existingProjectId:P.id})
|
|
2307
2312
|
E.info("MCP server instance created successfully")
|
|
2308
2313
|
const r=t.getContext()
|
|
2309
|
-
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")
|
|
2310
2315
|
try{const e=P.id
|
|
2311
|
-
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+""})
|
|
2312
2317
|
let t=!1
|
|
2313
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"
|
|
2314
2319
|
function r(e){if(!e)return!1
|
|
@@ -2334,8 +2339,8 @@ o=Math.max(o,s)}return o/Math.min(r.length,n.length)}Object.defineProperty(expor
|
|
|
2334
2339
|
let h=i(e,t)
|
|
2335
2340
|
if(h.length>0)return h
|
|
2336
2341
|
if(!a)return[]
|
|
2337
|
-
const
|
|
2338
|
-
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})))
|
|
2339
2344
|
try{if(h=function(e,t,o=100,a){const c=[],l=n(t,a),d=Date.now()
|
|
2340
2345
|
if(t.length>500)return i(e,t)
|
|
2341
2346
|
const u=t.match(/^[ \t]*/)[0],h=u.length>0
|
|
@@ -2348,35 +2353,35 @@ const d=Math.min(Math.floor(.5*t.length),200),u=Math.min(r+t.length+d,e.length),
|
|
|
2348
2353
|
for(let t=i;u>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2349
2354
|
if(i.length>h)break
|
|
2350
2355
|
if(i===l){c.push({line:s+1,actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t})
|
|
2351
|
-
break}}}o+=i.length+1}return c}const
|
|
2352
|
-
if(!
|
|
2353
|
-
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
|
|
2354
2359
|
for(;;){if(m%100==0&&Date.now()-d>o){const r=Date.now()-d
|
|
2355
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++
|
|
2356
|
-
const r=e.indexOf(p
|
|
2361
|
+
const r=e.indexOf(g,p)
|
|
2357
2362
|
if(-1===r)break
|
|
2358
2363
|
let i=r+t.length
|
|
2359
2364
|
const u=Math.min(Math.floor(.5*t.length),200),h=Math.min(r+t.length+u,e.length),f=l.length
|
|
2360
2365
|
let y=!1
|
|
2361
2366
|
for(let t=i;h>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2362
2367
|
if(i.length>f)break
|
|
2363
|
-
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),
|
|
2364
|
-
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[]
|
|
2365
2370
|
const c=[],l=o(t),d=Date.now()
|
|
2366
2371
|
if(t.length>500)return i(e,t)
|
|
2367
2372
|
if(!l)return c
|
|
2368
2373
|
const u=t.replace(/\s/g,"")[0],h=l.length
|
|
2369
|
-
let
|
|
2370
|
-
for(;;){if(
|
|
2371
|
-
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`)}
|
|
2372
|
-
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)
|
|
2373
2378
|
if(-1===r)break
|
|
2374
2379
|
const i=r+h,a=Math.min(t.length,300),m=Math.min(r+h+a,e.length)
|
|
2375
2380
|
let f=!1
|
|
2376
2381
|
for(let t=i;m>=t;t++){const n=e.substring(r,t),i=o(n)
|
|
2377
2382
|
if(i.length>h)break
|
|
2378
|
-
if(i===l){c.push({line:s(e,r),actuallyMatched:n,matchType:"whitespace_agnostic",startPos:r,endPos:t}),
|
|
2379
|
-
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))
|
|
2380
2385
|
let o=e
|
|
2381
2386
|
for(const e of n)o=a(o,e,r)
|
|
2382
2387
|
return o},exports.findSimilarMatches=function(e,t,r=5,n=.3){const o=e.split("\n"),s=[]
|
|
@@ -2401,15 +2406,15 @@ let i=d.FileOperationPhase.VALIDATION
|
|
|
2401
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}"}
|
|
2402
2407
|
try{const a=e,{path:u}=a
|
|
2403
2408
|
n.info("Getting file info: "+u)
|
|
2404
|
-
const{normalizedPath:
|
|
2409
|
+
const{normalizedPath:p,fullPath:m}=d.validateAndNormalizePath(u,t)
|
|
2405
2410
|
i=d.FileOperationPhase.FILE_WRITE
|
|
2406
|
-
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]
|
|
2407
2412
|
w.isFile&&y&&b.push("Extension: "+y)
|
|
2408
2413
|
const I=Date.now()-s
|
|
2409
|
-
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+
|
|
2410
|
-
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}
|
|
2411
2416
|
const c=a(t(1943)),l=a(t(6928)),d=i(t(5967)),u=t(8824)},3707(e,exports,t){"use strict"
|
|
2412
|
-
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()
|
|
2413
2418
|
try{const w=h.getRequestClient(),b=h.getTaskClient(),I=h.getFileClient(),k=h.getToolRecordClient(),{title:v,description:C,..._}=e,E=e.comment||v
|
|
2414
2419
|
f.info("Starting quick_edit workflow",{title:v,operationType:t})
|
|
2415
2420
|
let S=!1
|
|
@@ -2420,23 +2425,23 @@ if(!T||!T.id)throw Error("Failed to create request")
|
|
|
2420
2425
|
const q=T.id
|
|
2421
2426
|
let P
|
|
2422
2427
|
f.info("Created request",{requestId:q})
|
|
2423
|
-
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)
|
|
2424
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")
|
|
2425
2430
|
f.debug("Creating task")
|
|
2426
2431
|
const e=await b.createTask({requestId:q,projectId:u.projectId,title:`Execute ${t} operation`,description:"Quick change: "+v})
|
|
2427
2432
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2428
2433
|
let C
|
|
2429
|
-
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,
|
|
2430
|
-
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)
|
|
2431
2436
|
else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
|
|
2432
|
-
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})
|
|
2433
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")
|
|
2434
2439
|
j?f.warn("File operation completed with partial failures",{requestId:q}):f.info("File operation completed successfully"),f.debug("Completing task")
|
|
2435
|
-
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})
|
|
2436
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")
|
|
2437
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"
|
|
2438
2443
|
let M=!1
|
|
2439
|
-
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)
|
|
2440
2445
|
if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:q,error:e.content[0].text})
|
|
2441
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
|
|
2442
2447
|
f.info("Quick fix completed",{requestId:q,duration:O,hasPartialFailure:j})
|
|
@@ -2538,7 +2543,7 @@ const{taskId:M}=x,O=!!S,$=!!m
|
|
|
2538
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})
|
|
2539
2544
|
let D,A,F,N="",z=!1,L=!1
|
|
2540
2545
|
const H=$?m:void 0
|
|
2541
|
-
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}
|
|
2542
2547
|
throw e}if(!r.documentFileManager)throw Error("Document file manager not available")
|
|
2543
2548
|
N=await r.documentFileManager.getDocumentAsFile(S)
|
|
2544
2549
|
const e=r.documentFileManager.getCachedDocumentInfo(S)
|
|
@@ -2560,7 +2565,7 @@ if(v=J,C=J,_=E.fileOperationPhase,y.incrementCounter("write_file_phase",1,{phase
|
|
|
2560
2565
|
else Q="string"==typeof T?T:JSON.stringify(T,null,2)
|
|
2561
2566
|
let Y=Q
|
|
2562
2567
|
if($&&r.git)try{b.debug("[WRITE-FILE] Checking for user changes before write operation")
|
|
2563
|
-
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)
|
|
2564
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")
|
|
2565
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)
|
|
2566
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)
|
|
@@ -2574,7 +2579,7 @@ b.info("Write operation completed successfully",{duration:oe-k,path:$?D:"documen
|
|
|
2574
2579
|
const se=r.workspaceManager?.consumeLargeFileWarning(r.currentSessionId)
|
|
2575
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
|
|
2576
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}}}
|
|
2577
|
-
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"
|
|
2578
2583
|
Object.defineProperty(exports,"__esModule",{value:!0})},4139(e,exports){"use strict"
|
|
2579
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"
|
|
2580
2585
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=exports.TasksSchema=void 0
|
|
@@ -2595,14 +2600,14 @@ this.authToken?(a.Authorization="Bearer "+this.authToken,this.logger.debug("Usin
|
|
|
2595
2600
|
const c=process.env.SERVICE_SHARED_SECRET||"dev-service-secret-change-in-production"
|
|
2596
2601
|
a["X-Service-Secret"]=c
|
|
2597
2602
|
let l=0
|
|
2598
|
-
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})
|
|
2599
2604
|
for(;d>l;){l++
|
|
2600
2605
|
try{this.logger.debug(`Making ${e} request to ${i}`,{attempt:l,maxAttempts:d,hasAuth:!!a.Authorization,hasServiceIdentifier:!!a["X-Client-Type"]})
|
|
2601
2606
|
const t={method:e,headers:{...a},signal:AbortSignal.timeout(this.options.timeout||1e4)}
|
|
2602
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={}
|
|
2603
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)
|
|
2604
2609
|
this.logger.debug("Request body",{bodyPreview:e.substring(0,200)+(e.length>200?"...":""),bodyLength:e.length})}const n=await fetch(i,t)
|
|
2605
|
-
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")
|
|
2606
2611
|
if(429===n.status){const e=n.headers.get("Retry-After"),t=e?1e3*parseInt(e):2*(this.options.retryDelay||1e3)
|
|
2607
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)))
|
|
2608
2613
|
continue}}if(n.status>=500&&d>l){const e=(this.options.retryDelay||1e3)*Math.pow(2,l-1)
|
|
@@ -2611,17 +2616,17 @@ continue}let t=`API request failed with status ${n.status}: ${n.statusText}`,r={
|
|
|
2611
2616
|
try{const e=await n.json()
|
|
2612
2617
|
if(e&&"object"==typeof e&&!1===e.success&&e.error){const n=e.error
|
|
2613
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()
|
|
2614
|
-
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})
|
|
2615
2620
|
const o=Error(t)
|
|
2616
2621
|
throw o.status=n.status,o.statusText=n.statusText,o.method=e,o.url=i,o.errorDetails=r,o}this.resetFailureCount()
|
|
2617
2622
|
const o=await n.json()
|
|
2618
2623
|
if(null===o||"object"!=typeof o)throw Error("Invalid API response: expected object, got "+typeof o)
|
|
2619
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)})
|
|
2620
2625
|
const e={success:!0,data:o}
|
|
2621
|
-
return
|
|
2622
|
-
throw this.logger.error("API returned error response",{errorCode:e.error?.code,errorMessage:e.error?.message,statusCode:e.error?.statusCode}),
|
|
2623
|
-
return
|
|
2624
|
-
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)
|
|
2625
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
|
|
2626
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)
|
|
2627
2632
|
const e=this.options.circuitBreakerResetTime||5e3
|
|
@@ -2643,17 +2648,17 @@ if(!c.startsWith(s+a.sep))return{content:[{type:"text",text:"\u274c Invalid file
|
|
|
2643
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]
|
|
2644
2649
|
if(!h)return{content:[{type:"text",text:"\u274c Unsupported image type: ."+u}],isError:!0}
|
|
2645
2650
|
if("svg"===u)return{content:[{type:"text",text:`**Asset: ${r}**\n\n\`\`\`svg\n${await i.readFile(c,"utf-8")}\n\`\`\``}]}
|
|
2646
|
-
const
|
|
2647
|
-
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}}}
|
|
2648
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+"'")
|
|
2649
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"
|
|
2650
|
-
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
|
|
2651
2656
|
try{if(!h)throw(0,n.createValidationError)("requestId is required")
|
|
2652
|
-
d.info("Starting merge request",{requestId:h,verificationCount:
|
|
2657
|
+
d.info("Starting merge request",{requestId:h,verificationCount:g.length})
|
|
2653
2658
|
const e=a.getRequestClient(),s=await e.getRequest(h)
|
|
2654
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}
|
|
2655
|
-
if(
|
|
2656
|
-
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
|
|
2657
2662
|
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/validate-completion`,{})
|
|
2658
2663
|
c=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2659
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`
|
|
@@ -2661,10 +2666,10 @@ return c.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\
|
|
|
2661
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)
|
|
2662
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"
|
|
2663
2668
|
const f=await e.getRequest(h),y=f?.title||"Request "+h,w="resolving_conflicts"===f?.status
|
|
2664
|
-
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)
|
|
2665
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)
|
|
2666
|
-
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:
|
|
2667
|
-
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)
|
|
2668
2673
|
d.error("Merge request failed",{error:r})
|
|
2669
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}}}
|
|
2670
2675
|
const r=t(3807),n=t(9860),o=t(1651),s=t(8616),i=t(8824)},4394(e,exports,t){"use strict"
|
|
@@ -2684,49 +2689,51 @@ const a=await r.updateDocument(e.planId,i),c=a.localId||a.id
|
|
|
2684
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}}}
|
|
2685
2690
|
const r=t(8824)},4425(e,exports,t){"use strict"
|
|
2686
2691
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2687
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,
|
|
2688
|
-
try{const
|
|
2689
|
-
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"})}
|
|
2690
2695
|
const e=[]
|
|
2691
|
-
return
|
|
2692
|
-
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)})
|
|
2693
2698
|
if(!r.ok){const e=await r.text().catch((()=>""))
|
|
2694
|
-
return
|
|
2695
|
-
return o.success&&o.data?(
|
|
2696
|
-
const n=function(e){return e?.sessionId||
|
|
2697
|
-
if(!n)return
|
|
2698
|
-
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=[]
|
|
2699
2704
|
for(const t of e.commands){const e=t.name?.trim(),r=t.command?.trim(),n=t.description?.trim()
|
|
2700
|
-
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
|
|
2701
2706
|
if(!o)throw Error("command create returned no id")
|
|
2702
|
-
return{ok:!0,proposal:e,commandId:o}}catch(t){return{ok:!1,proposal:e,error:(0,
|
|
2703
|
-
for(const e of
|
|
2704
|
-
const
|
|
2705
|
-
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()
|
|
2706
2711
|
if(!e)throw Error("session message client unavailable")
|
|
2707
|
-
await e.createQuestion({fromSessionId:n,questionType:"alternatives",question:`Command batch approval: ${
|
|
2708
|
-
for(const e of g
|
|
2709
|
-
for(const t of
|
|
2710
|
-
const
|
|
2711
|
-
return
|
|
2712
|
-
const n=
|
|
2713
|
-
if(!n)return
|
|
2714
|
-
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),
|
|
2715
|
-
return
|
|
2716
|
-
if(!
|
|
2717
|
-
return
|
|
2718
|
-
e.grep&&(
|
|
2719
|
-
const
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
const
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
const
|
|
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,23 +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
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
const
|
|
2790
|
-
s.on("close",(e=>h(e??(d?124:1)))),s.on("error",(()=>h(1)))}))}
|
|
2791
|
-
const r=t(5317)},4607(e,exports,t){"use strict"
|
|
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"
|
|
2792
2804
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2793
2805
|
const r=t(6183),n=t(3306)
|
|
2794
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"
|
|
@@ -2801,10 +2813,10 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2801
2813
|
var t={}
|
|
2802
2814
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2803
2815
|
return o(t,e),t})
|
|
2804
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,r,n,o,s,u,h){const
|
|
2805
|
-
try{const
|
|
2806
|
-
return
|
|
2807
|
-
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)
|
|
2808
2820
|
f=I
|
|
2809
2821
|
let k,v=!1
|
|
2810
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
|
|
@@ -2816,31 +2828,31 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
|
|
|
2816
2828
|
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await a.writeFile(w,_,"utf8")
|
|
2817
2829
|
let E={}
|
|
2818
2830
|
try{const t=`Recover ${y} from ${r.substring(0,8)}`
|
|
2819
|
-
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"
|
|
2820
2832
|
let T=`\u2705 **File ${S.charAt(0).toUpperCase()+S.slice(1)} Successfully**\n\n`
|
|
2821
|
-
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()-
|
|
2822
|
-
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}}}
|
|
2823
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"
|
|
2824
|
-
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"})
|
|
2825
2837
|
try{const w=e
|
|
2826
2838
|
let{requestId:b}=w
|
|
2827
2839
|
const{operation:I}=w
|
|
2828
2840
|
if("list"!==I&&"search"!==I&&!b){const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=h.currentSessionId
|
|
2829
|
-
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")
|
|
2830
2842
|
const e={requestId:b,summary:w.complete.summary}
|
|
2831
|
-
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)
|
|
2832
2844
|
case"approve":{y.info("Routing to approve-request handler")
|
|
2833
2845
|
const e={requestId:b}
|
|
2834
|
-
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")
|
|
2835
2847
|
const e={requestId:b,reason:w.revert.reason,confirmDestructive:w.revert.confirmDestructive}
|
|
2836
|
-
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")
|
|
2837
2849
|
const e={requestId:b}
|
|
2838
|
-
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")
|
|
2839
2851
|
const e={filters:w.list?.filters}
|
|
2840
|
-
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")
|
|
2841
2853
|
const e={search:w.search}
|
|
2842
|
-
return(0,d.withAlchemyKind)(await(0,i.handleSearchRequests)(e,h,p,
|
|
2843
|
-
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||[]
|
|
2844
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
|
|
2845
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}}}
|
|
2846
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"
|
|
@@ -2958,16 +2970,16 @@ return t},s(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2958
2970
|
var t={}
|
|
2959
2971
|
if(null!=e)for(var r=s(e),n=0;n<r.length;n++)"default"!==r[n]&&i(t,e,r[n])
|
|
2960
2972
|
return a(t,e),t})
|
|
2961
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileBlame=async function(e,t,s,i,a){const c=i.child({tool:"file_blame"}),
|
|
2962
|
-
try{const{path:i,lines:
|
|
2963
|
-
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})
|
|
2964
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)
|
|
2965
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
|
|
2966
2978
|
if(/^\d+$/.test(e)){const t=parseInt(e,10)
|
|
2967
2979
|
return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
|
|
2968
2980
|
if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
|
|
2969
2981
|
if(e.match(/^(\d+(?:,\d+)+)$/)){const t=e.split(",").map((e=>parseInt(e,10)))
|
|
2970
|
-
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"]
|
|
2971
2983
|
let k
|
|
2972
2984
|
b&&I.push(`-L${b.start},${b.end}`),m&&I.push(m),I.push("--",w),c.debug("Executing git blame",{args:I})
|
|
2973
2985
|
try{if(!t.git)throw Error("Git context not available")
|
|
@@ -3004,7 +3016,7 @@ if(d+=t,e.requestId){const r=a.get(e.requestId)
|
|
|
3004
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"
|
|
3005
3017
|
const e=[...a.entries()].sort(((e,t)=>t[1].lines-e[1].lines))
|
|
3006
3018
|
for(const[t,r]of e){const e=Math.round(r.lines/d*100)
|
|
3007
|
-
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
|
|
3008
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}}}
|
|
3009
3021
|
const l=t(1181),d=c(t(6928)),u=c(t(1943)),h=t(8824)},4921(e,exports,t){"use strict"
|
|
3010
3022
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
@@ -3166,20 +3178,20 @@ if(!/^req\d{6}$/.test(t))throw new r.ValidationError(`Invalid request ID format:
|
|
|
3166
3178
|
d.info("Getting information for request "+t)
|
|
3167
3179
|
const n=a.getRequestClient(),s=a.getTaskClient(),[c,l]=await Promise.all([n.getRequest(t),s.listTasks({requestId:t})])
|
|
3168
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"})
|
|
3169
|
-
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
|
|
3170
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"})
|
|
3171
|
-
const
|
|
3172
|
-
d.info(`Successfully extracted ${
|
|
3173
|
-
const m={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:
|
|
3174
|
-
|
|
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
|
|
3175
3187
|
t in m&&m[t]++}))
|
|
3176
|
-
const f=
|
|
3188
|
+
const f=g.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_verified:0,total:f.length}
|
|
3177
3189
|
f.forEach((e=>{const t=e.status||"unverified"
|
|
3178
3190
|
t in y&&y[t]++}))
|
|
3179
|
-
let w=
|
|
3180
|
-
const b=
|
|
3181
|
-
let k=`# ${"feature"===I?"Feature":"quick-edit"===I?"Quick Edit":"Bug Fix"} Request: ${b} (${t})\nStatus: ${
|
|
3182
|
-
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()
|
|
3183
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}}}
|
|
3184
3196
|
const r=t(9860),n=t(5674),o=t(2960),s=t(8824),i=t(5454)},5454(e,exports){"use strict"
|
|
3185
3197
|
function t(e,t){let r=0
|
|
@@ -3220,7 +3232,7 @@ if(c.incrementCounter("document_operations_total",1,{operation:"list-annotations
|
|
|
3220
3232
|
let r=`## Annotations on ${h} (${t.length})\n\n`
|
|
3221
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`
|
|
3222
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")
|
|
3223
|
-
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})
|
|
3224
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")
|
|
3225
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})
|
|
3226
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")
|
|
@@ -3249,31 +3261,31 @@ return{isOffline:this.isInOfflineMode(),consecutiveFailures:e.consecutiveFailure
|
|
|
3249
3261
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3250
3262
|
const r=t(6183),n=t(2965)
|
|
3251
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"
|
|
3252
|
-
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")
|
|
3253
3265
|
try{const{requestId:n,summary:o}=e
|
|
3254
3266
|
if(!n)throw(0,r.createValidationError)("Request ID is required")
|
|
3255
3267
|
if(!o)throw(0,r.createValidationError)("Summary is required")
|
|
3256
|
-
|
|
3268
|
+
g.info("Starting request completion",{requestId:n})
|
|
3257
3269
|
const l=h?.sessionId
|
|
3258
3270
|
let d
|
|
3259
3271
|
try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:l})
|
|
3260
3272
|
d=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3261
|
-
return
|
|
3262
|
-
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()
|
|
3263
3275
|
let m,f="auto-test-then-merge"===d.completionMode,y=null
|
|
3264
|
-
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
|
|
3265
3277
|
if(i&&"passed"===i.status&&i.commitSha){let e=null
|
|
3266
3278
|
if(r&&r.ok){const t=await r.json()
|
|
3267
|
-
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"
|
|
3268
3280
|
try{await u.updateRequest(n,{status:w,completionSummary:o,...m?{skippedTestRunId:m}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3269
|
-
return
|
|
3281
|
+
return p({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let b
|
|
3270
3282
|
try{b=await u.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3271
|
-
return
|
|
3272
|
-
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.`}]}
|
|
3273
3285
|
const k=y?`\n\n_Skipped re-running tests: ${y}._\n`:""
|
|
3274
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=""
|
|
3275
|
-
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+"",
|
|
3276
|
-
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}}}
|
|
3277
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"
|
|
3278
3290
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3279
3291
|
const r=t(6183),n=t(6285)
|
|
@@ -3334,13 +3346,13 @@ let W=0
|
|
|
3334
3346
|
x.length>0&&n.setProjectId(r.projectId)
|
|
3335
3347
|
for(let e=0;e<$.length;e++){const t=$[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3336
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)
|
|
3337
|
-
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
|
|
3338
3350
|
for(const e of x){const t=e.target,r={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3339
3351
|
try{let e
|
|
3340
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)
|
|
3341
|
-
throw e}try{await(0,
|
|
3342
|
-
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,
|
|
3343
|
-
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
|
|
3344
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)
|
|
3345
3357
|
let J=null
|
|
3346
3358
|
if(W>0){b=c.FileOperationPhase.GIT_COMMIT,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
@@ -3356,11 +3368,11 @@ X=e>0&&t>0?`Successfully deleted ${e} files and ${t} documents`:e>0?`Successfull
|
|
|
3356
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})`
|
|
3357
3369
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
|
|
3358
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
|
|
3359
|
-
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,
|
|
3360
|
-
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
|
|
3361
3373
|
try{const r=n.getTaskClient(),o=n.getToolRecordClient()
|
|
3362
|
-
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,
|
|
3363
|
-
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"
|
|
3364
3376
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3365
3377
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3366
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=[]
|
|
@@ -3433,17 +3445,17 @@ if("create"===r?(e.name||t.addIssue({code:"custom",message:"name is required for
|
|
|
3433
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
|
|
3434
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]
|
|
3435
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")})
|
|
3436
|
-
const
|
|
3437
|
-
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"
|
|
3438
3450
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3439
3451
|
const r=t(6183),n=t(405)
|
|
3440
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"
|
|
3441
3453
|
module.exports=require("events")},6285(e,exports,t){"use strict"
|
|
3442
|
-
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")
|
|
3443
3455
|
try{const u=e,{operation:y,sessionId:w}=u
|
|
3444
3456
|
let b
|
|
3445
|
-
switch(m.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=
|
|
3446
|
-
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})
|
|
3447
3459
|
const a=await(0,i.getServerUrl)(r,o)
|
|
3448
3460
|
if(a)try{const r=await fetch(a.replace(/\/$/,"")+"/session")
|
|
3449
3461
|
if(!r.ok)return
|
|
@@ -3454,9 +3466,9 @@ if(!i)return
|
|
|
3454
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]
|
|
3455
3467
|
return"specialist"===t?.agentType&&"archived"!==t?.status}))
|
|
3456
3468
|
if(o.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
|
|
3457
|
-
const
|
|
3469
|
+
const g=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
|
|
3458
3470
|
return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
|
|
3459
|
-
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)
|
|
3460
3472
|
if(t){b=t
|
|
3461
3473
|
break}}let c=u.description||u.prompt.slice(0,60)
|
|
3462
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`)
|
|
@@ -3466,18 +3478,18 @@ if(h("session fetch status="+t.status),t.ok){const e=(await t.json()).filter((e=
|
|
|
3466
3478
|
h(`siblings=${e.length}: ${e.join(", ")}`)
|
|
3467
3479
|
const n=(0,o.pickSpecialistName)(e)
|
|
3468
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")
|
|
3469
|
-
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)
|
|
3470
3482
|
break}case"follow-up":{const e=await(0,i.getServerUrl)(d,m)
|
|
3471
3483
|
if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
|
|
3472
3484
|
if(t.ok){const e=await t.json(),r=e[w]?.type
|
|
3473
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}
|
|
3474
|
-
break}}}catch{}b=await(0,s.handleContinue)(w,u.prompt,d,m,
|
|
3475
|
-
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)
|
|
3476
3488
|
break
|
|
3477
|
-
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()
|
|
3478
3490
|
e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
|
|
3479
|
-
case"list":{const e=
|
|
3480
|
-
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})
|
|
3481
3493
|
break}default:throw new r.ValidationError("Unknown operation: "+y)}f({success:!0}),h.incrementCounter(`specialist_ops_${y}_success`,1)
|
|
3482
3494
|
const I=l[y]??"specialist-delegate"
|
|
3483
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}}}
|
|
@@ -3497,17 +3509,17 @@ var t={}
|
|
|
3497
3509
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3498
3510
|
return o(t,e),t})
|
|
3499
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")
|
|
3500
|
-
try{const n=e,{requestId:l,reason:h,confirmDestructive:
|
|
3501
|
-
if(s.info("Starting revert/cancel process",{requestId:l,reason:h}),!
|
|
3502
|
-
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
|
|
3503
3515
|
try{const e=await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/validate-revert`,{})
|
|
3504
|
-
|
|
3505
|
-
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:
|
|
3506
|
-
return
|
|
3507
|
-
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)
|
|
3508
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})
|
|
3509
3521
|
t.syncBranchState&&await t.syncBranchState()
|
|
3510
|
-
let m=
|
|
3522
|
+
let m=p.mergeCommitHash
|
|
3511
3523
|
if(!m){s.info("No merge commit hash from server, searching git log",{requestId:l})
|
|
3512
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(" ")
|
|
3513
3525
|
return-1===t?{hash:e,message:""}:{hash:e.substring(0,t),message:e.substring(t+1)}})):[],s=a.generateMergeMessagePatterns(e)
|
|
@@ -3523,7 +3535,7 @@ try{s.info("Executing git revert",{mergeCommitHash:m.substring(0,8)}),await f.ra
|
|
|
3523
3535
|
const e=await(0,c.verifyGitStateConsistency)(f,w,s,`revert-request-${l}-verification`)
|
|
3524
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)
|
|
3525
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)
|
|
3526
|
-
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}
|
|
3527
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}
|
|
3528
3540
|
if(t.projectId&&e.requestId)try{const o=r.getToolRecordClient()
|
|
3529
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}}}
|
|
@@ -3557,7 +3569,7 @@ break
|
|
|
3557
3569
|
case"between":if(void 0===e.afterLine||void 0===e.beforeLine)throw Error("Both afterLine and beforeLine are required for between insertion")
|
|
3558
3570
|
n=(0,m.insertBetweenLines)(r,e.afterLine,e.beforeLine,e.content)
|
|
3559
3571
|
break
|
|
3560
|
-
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)
|
|
3561
3573
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3562
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=[]
|
|
3563
3575
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3580,7 +3592,7 @@ R.push({type:"file",path:t,fullPath:r,insertions:e.insertions})}const x=[]
|
|
|
3580
3592
|
if(j.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3581
3593
|
for(const e of j)x.push({type:"document",documentId:e.documentId,insertions:e.insertions})
|
|
3582
3594
|
if(x.length>0&&n.apiClient){const e=x.map((e=>e.documentId))
|
|
3583
|
-
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}
|
|
3584
3596
|
throw e}}k=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3585
3597
|
const M=R.length>0?R[0].path:"document-operation",O=await l.validateTaskId(q,M,o,y,m,v.metricsPrefix),$=O?.requestId
|
|
3586
3598
|
let D=null
|
|
@@ -3602,11 +3614,11 @@ let H=0,B=0,U=0
|
|
|
3602
3614
|
for(const e of R){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3603
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)
|
|
3604
3616
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.insertions)
|
|
3605
|
-
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}
|
|
3606
3618
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3607
3619
|
t.filename=s?.filename
|
|
3608
3620
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
|
|
3609
|
-
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))
|
|
3610
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
|
|
3611
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"
|
|
3612
3624
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
@@ -3619,22 +3631,22 @@ for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?
|
|
|
3619
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")
|
|
3620
3632
|
const ee=Date.now()-w
|
|
3621
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
|
|
3622
|
-
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,
|
|
3623
|
-
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"
|
|
3624
3636
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
|
|
3625
|
-
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)
|
|
3626
3638
|
exports.ClientFactory=class{static async createClient(e,f,y,w={}){(f=f.child({component:"client-factory"})).info("Creating API client with components")
|
|
3627
3639
|
const b=w.tokenManager||new r.TokenManager(f,w.workingDir||process.cwd())
|
|
3628
3640
|
await b.initialize()
|
|
3629
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})
|
|
3630
3642
|
I.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3631
|
-
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})
|
|
3632
3644
|
I.registerClient(E)
|
|
3633
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})
|
|
3634
3646
|
I.registerClient(S),f.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
3635
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})
|
|
3636
3648
|
I.registerClient(T),f.info("RequestClient post-constructor token: "+(T.getAuthToken()?"present":"missing"))
|
|
3637
|
-
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})
|
|
3638
3650
|
I.registerClient(q)
|
|
3639
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})
|
|
3640
3652
|
I.registerClient(P)
|
|
@@ -3656,7 +3668,7 @@ if(_)try{await _.connectStdio(),(0,a.isDebugToolsEnabled)()&&b.info("Connected s
|
|
|
3656
3668
|
throw b.error("Failed to connect stdio transport",{errorDetails:t}),e}else b.error("No global server instance available to connect transport")
|
|
3657
3669
|
return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3658
3670
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
3659
|
-
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)
|
|
3660
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")
|
|
3661
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)}))
|
|
3662
3674
|
const I=process.stdout.write
|
|
@@ -3667,7 +3679,7 @@ let v=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com"
|
|
|
3667
3679
|
const C=global.__serverInitialized
|
|
3668
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)
|
|
3669
3681
|
let _=null
|
|
3670
|
-
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+""
|
|
3671
3683
|
b.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
|
|
3672
3684
|
try{const e=u.default.existsSync(w)
|
|
3673
3685
|
if((0,a.isDebugToolsEnabled)()&&b.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=u.default.statSync(w)
|
|
@@ -3675,8 +3687,8 @@ b.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(
|
|
|
3675
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
|
|
3676
3688
|
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(b),n=await r.getInstallationConfig()
|
|
3677
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"}()
|
|
3678
|
-
try{const e=await(0,
|
|
3679
|
-
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))
|
|
3680
3692
|
const e=await(0,i.createServer)(w,b,k,v)
|
|
3681
3693
|
_=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&b.info("MCP server created successfully")
|
|
3682
3694
|
const n=r()
|
|
@@ -3711,7 +3723,7 @@ const n=[],o=[...t].sort(((e,t)=>{const r=e=>"number"==typeof e?e:Array.isArray(
|
|
|
3711
3723
|
return r(t.lines)-r(e.lines)}))
|
|
3712
3724
|
for(const e of o){const t={lines:e.lines,success:!1}
|
|
3713
3725
|
try{const n=(0,m.replaceLines)(r,e.lines,e.content)
|
|
3714
|
-
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)
|
|
3715
3727
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3716
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=[]
|
|
3717
3729
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3734,7 +3746,7 @@ x.push({type:"file",path:t,fullPath:r,replacements:e.replacements.map((e=>({line
|
|
|
3734
3746
|
if(R.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3735
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})))})
|
|
3736
3748
|
if(M.length>0&&n.apiClient){const e=M.map((e=>e.documentId))
|
|
3737
|
-
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}
|
|
3738
3750
|
throw e}}v=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3739
3751
|
const O=x.length>0?x[0].path:"document-operation",$=await l.validateTaskId(P,O,o,w,m,C.metricsPrefix),D=$?.requestId
|
|
3740
3752
|
let A=null
|
|
@@ -3756,11 +3768,11 @@ let B=0,U=0,G=0,W=0
|
|
|
3756
3768
|
for(const e of x){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3757
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)
|
|
3758
3770
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.replacements)
|
|
3759
|
-
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}
|
|
3760
3772
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3761
3773
|
t.filename=s?.filename
|
|
3762
3774
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
|
|
3763
|
-
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))
|
|
3764
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
|
|
3765
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"
|
|
3766
3778
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
@@ -3771,14 +3783,14 @@ for(const e of H){if("file"===e.type?te+=`### File: ${e.path}\n`:(te+="### Docum
|
|
|
3771
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")
|
|
3772
3784
|
const re=Date.now()-b
|
|
3773
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
|
|
3774
|
-
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,
|
|
3775
|
-
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"
|
|
3776
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"})
|
|
3777
3789
|
try{const s=t.projectId
|
|
3778
3790
|
if(!s)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
|
|
3779
|
-
const i=e.name.replace(/\.md$/i,""),a=`${d.filenamePrefix}${i}.md`,l=o.getDocumentClient(),
|
|
3780
|
-
if(
|
|
3781
|
-
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
|
|
3782
3794
|
let w=!1
|
|
3783
3795
|
if(d.canBeActivePlan)try{const e=o.getProjectClient(),t=await e.getProject(s)
|
|
3784
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}}}
|
|
@@ -3858,19 +3870,19 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3858
3870
|
var t={}
|
|
3859
3871
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3860
3872
|
return o(t,e),t})
|
|
3861
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTaskFileHistory=async function(e,t,r,n,o){const s=n.child({tool:"task_file_history"}),
|
|
3862
|
-
try{const{taskId:
|
|
3863
|
-
if(!
|
|
3864
|
-
if(!(0,h.isTaskRef)(
|
|
3865
|
-
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})
|
|
3866
3878
|
const f=r.getTaskClient(),y=r.getToolRecordClient(),w=t.projectId
|
|
3867
3879
|
let b
|
|
3868
3880
|
r.setProjectId(w)
|
|
3869
|
-
try{const j=await f.getTask(
|
|
3870
|
-
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:
|
|
3871
|
-
try{const x=await y.getToolRecordsByTaskId(
|
|
3872
|
-
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 ${
|
|
3873
|
-
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}.`}]}
|
|
3874
3886
|
function k(e){const t=new Map,r=new Map,n=[]
|
|
3875
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
|
|
3876
3888
|
if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
|
|
@@ -3891,7 +3903,7 @@ if(t&&(n=e.metadata.successfulOperations.some((e=>e&&e.source&&e.destination))),
|
|
|
3891
3903
|
if(!Array.isArray(t)||0===t.length)return s.warn("Skipping delete-files record without valid paths array: "+e.id),!1
|
|
3892
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}))
|
|
3893
3905
|
if(s.info(`Found ${C.length} file operation records`),C.length>0){const $={}
|
|
3894
|
-
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}.`}]}
|
|
3895
3907
|
const _=new Map
|
|
3896
3908
|
C.forEach((e=>{let t=null
|
|
3897
3909
|
if(e.metadata){if(!e.metadata.commitHash){const t=["gitCommitId","commitId","commit","gitCommit"]
|
|
@@ -3943,9 +3955,9 @@ s.info(`Getting new file content using git show: ${B.commitHash?B.commitHash.sub
|
|
|
3943
3955
|
const de=await t.git.show(le)
|
|
3944
3956
|
if(de&&de.trim().length>0){let ue=""
|
|
3945
3957
|
const he=de.split("\n")
|
|
3946
|
-
for(const
|
|
3958
|
+
for(const ge of he)ue+=`+${ge}\n`
|
|
3947
3959
|
E.set(F,{firstChange:W,lastChange:B,hasDiff:!0,diffText:ue}),s.info(`Formatted new file content as diff, ${he.length} lines`)
|
|
3948
|
-
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"})
|
|
3949
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"})
|
|
3950
3962
|
continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let V="",K=!1
|
|
3951
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})
|
|
@@ -3960,7 +3972,7 @@ if(_e&&_e.trim().length>0){if(m){let Ee=""
|
|
|
3960
3972
|
const Se=_e.split("\n")
|
|
3961
3973
|
for(const Te of Se)Ee+=`+${Te}\n`
|
|
3962
3974
|
V=Ee}else V="File created during this task. Content:\n"+_e
|
|
3963
|
-
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`
|
|
3964
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`)
|
|
3965
3977
|
const T=3e3
|
|
3966
3978
|
let q=0,P=!1
|
|
@@ -3973,7 +3985,7 @@ try{await a.access(Oe),$e=!0}catch{}S+=`### ${Re} ${$e?"":"(Deleted)"}\n\n`
|
|
|
3973
3985
|
const De=new Date(xe.firstChange.timestamp).toLocaleString(),Ae=new Date(xe.lastChange.timestamp).toLocaleString()
|
|
3974
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`)
|
|
3975
3987
|
const Fe=v.sourceToMove.get(Re),Ne=v.destToMove.get(Re)
|
|
3976
|
-
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}}}
|
|
3977
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"
|
|
3978
3990
|
module.exports=require("path")},6975(e,exports,t){"use strict"
|
|
3979
3991
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
|
|
@@ -4107,9 +4119,9 @@ i.existsSync(n)||i.mkdirSync(n,{recursive:!0})
|
|
|
4107
4119
|
const s=(new Date).toISOString(),l=Object.keys(r).length?" "+JSON.stringify(r):""
|
|
4108
4120
|
i.appendFileSync(o,`[${s}] ${e} | ${t}${l}\n`)}catch(e){}}
|
|
4109
4121
|
const i=s(t(9896)),a=s(t(6928)),c=s(t(857))},7334(e,exports,t){"use strict"
|
|
4110
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,c,l,d,u,h){const
|
|
4111
|
-
|
|
4112
|
-
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")
|
|
4113
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)
|
|
4114
4126
|
throw new r.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
|
|
4115
4127
|
d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
|
|
@@ -4123,25 +4135,25 @@ if(e){const t=c.getCLISessionClient()
|
|
|
4123
4135
|
if(t){const r=await t.getByExternalId(e)
|
|
4124
4136
|
if(r?.workflowId){const e=await c.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
|
|
4125
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
|
|
4126
|
-
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"
|
|
4127
4139
|
let b=h
|
|
4128
4140
|
if(h?.sessionId)try{const e=c.getCLISessionClient()
|
|
4129
4141
|
if(e){const t=await e.getByExternalId(h.sessionId)
|
|
4130
|
-
"planner"!==t?.agentType&&"auto-planner"!==t?.agentType||(b=void 0,
|
|
4131
|
-
|
|
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})
|
|
4132
4144
|
const k=await f.createRequest(I)
|
|
4133
|
-
|
|
4134
|
-
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
|
|
4135
4147
|
let _,E={created:!1}
|
|
4136
|
-
if(u?.workspaceManager)try{await u.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},
|
|
4137
|
-
|
|
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})
|
|
4138
4150
|
try{const e=c.getToolRecordClient()
|
|
4139
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"}`})
|
|
4140
|
-
_=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})
|
|
4141
4153
|
const S=C.localId||C.id
|
|
4142
|
-
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})
|
|
4143
4155
|
else{const n=c.getToolRecordClient()
|
|
4144
|
-
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]
|
|
4145
4157
|
let t=e.message
|
|
4146
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."
|
|
4147
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}}}
|
|
@@ -4161,13 +4173,13 @@ default:throw Error(`Unknown operation: ${c}. Valid operations: get-info, list`)
|
|
|
4161
4173
|
const h=i[c]
|
|
4162
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}}}
|
|
4163
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"
|
|
4164
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,i,a,c,l,d,u,h){const
|
|
4165
|
-
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)
|
|
4166
4178
|
if("errorResult"in y)return y.errorResult
|
|
4167
4179
|
const{taskId:w}=y
|
|
4168
|
-
|
|
4180
|
+
g.info("Processing modify-file operations",{taskId:w,operationCount:p.length,comment:m})
|
|
4169
4181
|
const b=[],I=[],k=[],v=[],C=[]
|
|
4170
|
-
for(const e of
|
|
4182
|
+
for(const e of p){const t={path:e.path,documentId:e.documentId}
|
|
4171
4183
|
switch(e.operationType){case"replace-string":b.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
|
|
4172
4184
|
break
|
|
4173
4185
|
case"insert-lines":I.push({...t,insertions:e.insertLines.insertions})
|
|
@@ -4177,42 +4189,42 @@ break
|
|
|
4177
4189
|
case"delete-string":v.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
|
|
4178
4190
|
break
|
|
4179
4191
|
case"delete-lines":C.push({...t,lines:e.deleteLines.lines})}}const _=[]
|
|
4180
|
-
if(b.length>0){
|
|
4181
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:b,comment:m+" [via modify-file: replace-string]"},i,a,c,l,
|
|
4182
|
-
_.push({type:"replace-string",result:e})}if(I.length>0){
|
|
4183
|
-
const e=await(0,n.handleInsertLines)({taskId:w,operations:I,comment:m+" [via modify-file: insert-lines]"},i,a,c,l,
|
|
4184
|
-
_.push({type:"insert-lines",result:e})}if(k.length>0){
|
|
4185
|
-
const e=await(0,o.handleReplaceLines)({taskId:w,operations:k,comment:m+" [via modify-file: replace-lines]"},i,a,c,l,
|
|
4186
|
-
_.push({type:"replace-lines",result:e})}if(v.length>0){
|
|
4187
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:v,comment:m+" [via modify-file: delete-string]"},i,a,c,l,
|
|
4188
|
-
_.push({type:"delete-string",result:e})}if(C.length>0){
|
|
4189
|
-
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)
|
|
4190
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
|
|
4191
4203
|
let q="## Modify File Results\n\n"
|
|
4192
4204
|
q+="**Summary:**\n",q+=`- **Total operation types:** ${_.length}\n`,q+=`- **Successful:** ${S}\n`,q+=`- **Failed:** ${T}\n\n`
|
|
4193
4205
|
for(const{type:e,result:t}of _)q+=`### ${e} operations\n`,q+=t.content[0].text+"\n\n"
|
|
4194
|
-
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}}}
|
|
4195
4207
|
const r=t(3306),n=t(6486),o=t(6651),s=t(8824)},7478(e,exports,t){"use strict"
|
|
4196
4208
|
async function r(e,t,r){const n=r.startTimer("git_get_current_branch_duration")
|
|
4197
4209
|
try{const o=(await e.status()).current
|
|
4198
|
-
if(!o)throw new
|
|
4210
|
+
if(!o)throw new g.ValidationError("Repository is in detached HEAD state or branch detection failed")
|
|
4199
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)
|
|
4200
|
-
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")
|
|
4201
4213
|
try{const s=(await e.branch(["-l"])).all.includes(t)
|
|
4202
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)
|
|
4203
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")
|
|
4204
4216
|
try{const a=await r(e,o,s)
|
|
4205
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}'`}
|
|
4206
4218
|
if(!await n(e,t,o,s)){const e=`Branch '${t}' does not exist`
|
|
4207
|
-
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)
|
|
4208
4220
|
const c=await e.revparse(["HEAD"])
|
|
4209
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)
|
|
4210
|
-
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")
|
|
4211
4223
|
try{let o,s=!0
|
|
4212
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")
|
|
4213
|
-
let
|
|
4214
|
-
return u?
|
|
4215
|
-
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")
|
|
4216
4228
|
try{t.debug("Starting uncommitted changes check"),t.debug("Checking for uncommitted changes before merge"),Date.now()
|
|
4217
4229
|
const o=await e.status()
|
|
4218
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})
|
|
@@ -4224,7 +4236,7 @@ let d=""
|
|
|
4224
4236
|
if(l){const e=[]
|
|
4225
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"
|
|
4226
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)
|
|
4227
|
-
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)
|
|
4228
4240
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
4229
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=[]
|
|
4230
4242
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -4238,29 +4250,29 @@ return s.warn(e),i.incrementCounter("git_create_branch_already_exists",1),c({suc
|
|
|
4238
4250
|
await e.checkoutBranch(t,o)
|
|
4239
4251
|
const d=await e.revparse(["HEAD"]),u=a||l
|
|
4240
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)
|
|
4241
|
-
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")
|
|
4242
4254
|
try{const d=await r(e,i,a)
|
|
4243
4255
|
if(d!==s&&await o(e,s,i,a),!await n(e,t,i,a)){const e=`Source branch '${t}' does not exist`
|
|
4244
|
-
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"]))
|
|
4245
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)
|
|
4246
|
-
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")
|
|
4247
4259
|
try{const c=await r(e,s,i)
|
|
4248
4260
|
if(c===t){const e=`Cannot delete current branch '${t}'`
|
|
4249
|
-
throw s.error(e),i.incrementCounter("git_delete_branch_current_branch",1),a({success:!1,reason:"current_branch"}),new
|
|
4250
|
-
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`
|
|
4251
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]
|
|
4252
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)
|
|
4253
|
-
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")
|
|
4254
4266
|
try{const o=await s(e,t,r)
|
|
4255
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)
|
|
4256
|
-
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)
|
|
4257
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})-/)
|
|
4258
4270
|
return t?t[1]:null},exports.switchToDefaultBranch=async function(e,t,r){const n=r.startTimer("git_switch_to_default_duration")
|
|
4259
4271
|
try{const i=await s(e,t,r)
|
|
4260
4272
|
if(!i.defaultBranch){const e="No default branch found"
|
|
4261
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)
|
|
4262
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)
|
|
4263
|
-
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")
|
|
4264
4276
|
try{const o=await s(e,t,r),i=[]
|
|
4265
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")
|
|
4266
4278
|
const a=0===i.length
|
|
@@ -4270,9 +4282,9 @@ try{r.debug("Starting main branch change detection",{providedRevertCommitHash:t.
|
|
|
4270
4282
|
const n=await e.revparse(["HEAD"])
|
|
4271
4283
|
r.debug("Git state captured",{currentMainHash:n.substring(0,8),fullCurrentMainHash:n,revertCommitHash:t.substring(0,8),fullRevertCommitHash:t,hashesMatch:n===t})
|
|
4272
4284
|
try{const t=await e.revparse(["--abbrev-ref","HEAD"]),n=await e.status(),o=await e.log(["--oneline","-5"])
|
|
4273
|
-
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")
|
|
4274
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}`)
|
|
4275
|
-
const i=await(0,
|
|
4287
|
+
const i=await(0,p.validateCommitHash)(e,n,r,"hasMainChangedSinceRevert-head-validation")
|
|
4276
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}`)
|
|
4277
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"}
|
|
4278
4290
|
r.debug("Hash comparison shows difference, checking ancestor relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),hashesEqual:!1})
|
|
@@ -4294,7 +4306,7 @@ try{if(!/^[a-f0-9]{40}$/i.test(o)){r.warn("Invalid commit hash format found in t
|
|
|
4294
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+""})
|
|
4295
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)
|
|
4296
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")
|
|
4297
|
-
try{if(!r.hasChanges)throw new
|
|
4309
|
+
try{if(!r.hasChanges)throw new g.ValidationError("No uncommitted changes to commit")
|
|
4298
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})
|
|
4299
4311
|
const i=[...r.unstagedFiles,...r.untrackedFiles]
|
|
4300
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)")
|
|
@@ -4302,7 +4314,7 @@ const a=`chore: commit user changes before merging request ${t}\n\n${r.summary}\
|
|
|
4302
4314
|
n.debug("Commit message",{message:a.split("\n")[0]}),n.debug("Creating commit"),await e.commit(a)
|
|
4303
4315
|
const c=await e.revparse(["HEAD"])
|
|
4304
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)
|
|
4305
|
-
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")
|
|
4306
4318
|
try{let c=Date.now()
|
|
4307
4319
|
o.debug("Checking for user changes before tool operation",{toolName:r})
|
|
4308
4320
|
let l=e
|
|
@@ -4316,10 +4328,10 @@ let u
|
|
|
4316
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`
|
|
4317
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.`
|
|
4318
4330
|
o.debug("Committing user changes with message",{firstLine:h.split("\n")[0]})
|
|
4319
|
-
const
|
|
4320
|
-
c=Date.now(),
|
|
4321
|
-
const
|
|
4322
|
-
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)
|
|
4323
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=[]
|
|
4324
4336
|
try{const o=t(3807).simpleGit(e),s=(await o.status()).not_added||[]
|
|
4325
4337
|
for(const t of s)try{const o=y.join(e,t),s=f.statSync(o)
|
|
@@ -4328,7 +4340,7 @@ const t=e.reduce(((e,t)=>e+t.sizeMB),0)
|
|
|
4328
4340
|
let r=`\n\n\u26a0\ufe0f **Performance Warning**: Large untracked files detected (${Math.round(t)} MB total) that may slow git operations:\n`
|
|
4329
4341
|
for(const t of e.slice(0,5))r+=`- \`${t.path}\` (${t.sizeMB} MB)\n`
|
|
4330
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}
|
|
4331
|
-
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))
|
|
4332
4344
|
t(857)},7575(e,exports){"use strict"
|
|
4333
4345
|
var t
|
|
4334
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"
|
|
@@ -4532,8 +4544,8 @@ const r=t(4055)
|
|
|
4532
4544
|
Object.defineProperty(exports,"ProjectID",{enumerable:!0,get(){return r.ProjectID}}),Object.defineProperty(exports,"ProjectIDFactory",{enumerable:!0,get(){return r.ProjectIDFactory}})
|
|
4533
4545
|
const n=t(1791)
|
|
4534
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"
|
|
4535
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,c,l,d,u,h,p,
|
|
4536
|
-
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)
|
|
4537
4549
|
if("errorResult"in I)return I.errorResult
|
|
4538
4550
|
const{taskId:k}=I
|
|
4539
4551
|
f.info("Processing manage-files operations",{taskId:k,operationCount:y.length,comment:w})
|
|
@@ -4546,18 +4558,18 @@ case"delete-files":_.push(...e.deleteFiles.targets)
|
|
|
4546
4558
|
break
|
|
4547
4559
|
case"get-file-info":E.push({path:e.getFileInfo.path})}const S=[]
|
|
4548
4560
|
for(const e of v){f.info("Routing to create-directory handler",{path:e.path})
|
|
4549
|
-
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)
|
|
4550
4562
|
S.push({type:"create-directory",result:t})}if(C.length>0){f.info("Routing to move-files handler",{operationCount:C.length})
|
|
4551
|
-
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)
|
|
4552
4564
|
S.push({type:"move-files",result:e})}if(_.length>0){f.info("Routing to delete-files handler",{operationCount:_.length})
|
|
4553
|
-
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)
|
|
4554
4566
|
S.push({type:"delete-files",result:e})}for(const e of E){f.info("Routing to get-file-info handler",{path:e.path})
|
|
4555
|
-
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,
|
|
4567
|
+
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,p)
|
|
4556
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
|
|
4557
4569
|
let j="## Manage Files Results\n\n"
|
|
4558
4570
|
j+="**Summary:**\n",j+=`- **Total operation types:** ${S.length}\n`,j+=`- **Successful:** ${q}\n`,j+=`- **Failed:** ${P}\n\n`
|
|
4559
4571
|
for(const{type:e,result:t}of S)j+=`### ${e} operations\n`,j+=t.content[0].text+"\n\n"
|
|
4560
|
-
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}}}
|
|
4561
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"
|
|
4562
4574
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4563
4575
|
const r=t(6183),n=t(5303)
|
|
@@ -4582,8 +4594,8 @@ const r=t(5806),n=t(5715)
|
|
|
4582
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"
|
|
4583
4595
|
async function r(e,t,r,n,o,s,a,l,d,u){const h=Date.now()
|
|
4584
4596
|
if(!r||""===r.trim())throw new c.ValidationError("Project ID is required and cannot be empty for tool record creation")
|
|
4585
|
-
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}`}),
|
|
4586
|
-
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)
|
|
4587
4599
|
const n=t instanceof Error?`${t.message} (${JSON.stringify(t)})`:t+""
|
|
4588
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()
|
|
4589
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
|
|
@@ -4594,22 +4606,22 @@ l.info("Staging modified files for git commit",{files:n,count:n.length,operation
|
|
|
4594
4606
|
let d=o.git
|
|
4595
4607
|
if(o.workspaceManager){const t=o.workspaceManager.getCurrentContext(o.currentSessionId)
|
|
4596
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}
|
|
4597
|
-
let
|
|
4598
|
-
try{
|
|
4599
|
-
const
|
|
4600
|
-
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)
|
|
4601
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}}
|
|
4602
|
-
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
|
|
4603
|
-
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
|
|
4604
4616
|
l.debug("createFileOperationRecords called",{taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,operationType:o,path:s})
|
|
4605
4617
|
try{const a=await r(e,t,n,o,s,i,c,l,u,h)
|
|
4606
|
-
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}
|
|
4607
4619
|
try{let s=t.git
|
|
4608
4620
|
if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
4609
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)
|
|
4610
4622
|
const t=await s.commit("[USER-MODS] Preserve user modifications before tool operation: "+e)
|
|
4611
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()
|
|
4612
|
-
let p
|
|
4624
|
+
let g,p=null
|
|
4613
4625
|
try{let m=s.git
|
|
4614
4626
|
if(s.workspaceManager){const t=s.workspaceManager.getCurrentContext(s.currentSessionId)
|
|
4615
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.`)
|
|
@@ -4620,11 +4632,11 @@ i.info("Git repository status before commit:",{taskId:e,currentBranch:r.trim(),c
|
|
|
4620
4632
|
const a=r.trim(),c=s.getCurrentRequestId?s.getCurrentRequestId():null
|
|
4621
4633
|
if(c){const t="requests/"+c
|
|
4622
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"])
|
|
4623
|
-
|
|
4624
|
-
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
|
|
4625
4637
|
try{const r=await m.revparse(["--abbrev-ref","HEAD"]),n=await m.revparse(["HEAD"])
|
|
4626
|
-
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(
|
|
4627
|
-
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
|
|
4628
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))}
|
|
4629
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"
|
|
4630
4642
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.addConnectionStatusInfo=function(e){return async(t,n,o)=>{try{const t=e.isInOfflineMode()
|
|
@@ -4646,11 +4658,11 @@ class o{static create(){return exports.ProjectIDFactory.create()}static fromStri
|
|
|
4646
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
|
|
4647
4659
|
if(e.includes("_")){const t=e.split("_")
|
|
4648
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"
|
|
4649
|
-
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
|
|
4650
4662
|
try{const e=u||process.cwd(),o={...process.env,...(0,c.getOpencodeSpawnEnv)(e,(0,l.isDevMode)())}
|
|
4651
4663
|
let y
|
|
4652
|
-
if(
|
|
4653
|
-
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})
|
|
4654
4666
|
const w=(0,i.join)(u||process.cwd(),".alchemy_lab"),b=(0,i.join)(w,"spawn-stderr.log")
|
|
4655
4667
|
let I
|
|
4656
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})
|
|
@@ -4668,10 +4680,10 @@ const d={}
|
|
|
4668
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})
|
|
4669
4681
|
const u=s.getRequestClient(),h=await u.listRequests(d)
|
|
4670
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"})
|
|
4671
|
-
const
|
|
4672
|
-
if(c.info(`Extracted ${
|
|
4673
|
-
const g
|
|
4674
|
-
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}}}
|
|
4675
4687
|
const r=t(9860),n=t(2960),o=t(8824)},8045(e,exports,t){"use strict"
|
|
4676
4688
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4677
4689
|
const r=t(6183),n=t(7456)
|
|
@@ -4698,14 +4710,14 @@ var u=t(184)
|
|
|
4698
4710
|
Object.defineProperty(exports,"createServer",{enumerable:!0,get(){return u.createServer}})
|
|
4699
4711
|
var h=t(3884)
|
|
4700
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}})
|
|
4701
|
-
var
|
|
4702
|
-
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"
|
|
4703
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")
|
|
4704
|
-
try{const i=e,{requestId:c,format:d="summary",path:h}=i,
|
|
4705
|
-
if(!
|
|
4706
|
-
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
|
|
4707
4719
|
let b,I
|
|
4708
|
-
if(y){const e=
|
|
4720
|
+
if(y){const e=p.metadata?.mergeBaseSha,t=p.metadata?.mergeCommitSha
|
|
4709
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.`)
|
|
4710
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)
|
|
4711
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]:[]
|
|
@@ -4743,35 +4755,35 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4743
4755
|
var t={}
|
|
4744
4756
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
4745
4757
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4746
|
-
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()
|
|
4747
4759
|
let y,w,b=l.FileOperationPhase.VALIDATION
|
|
4748
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}"}
|
|
4749
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)
|
|
4750
4762
|
if("errorResult"in v)return v.errorResult
|
|
4751
4763
|
const{taskId:C}=v
|
|
4752
|
-
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()
|
|
4753
4765
|
const{normalizedPath:_,fullPath:E}=l.validateAndNormalizePath(u,r)
|
|
4754
|
-
b=l.FileOperationPhase.TASK_VALIDATION,
|
|
4755
|
-
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)
|
|
4756
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})
|
|
4757
|
-
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})
|
|
4758
4770
|
if(!j.success)throw Error(j.error)
|
|
4759
4771
|
let R=!1
|
|
4760
|
-
try{R=(await a.default.stat(E)).isDirectory()}catch{R=!1}b=l.FileOperationPhase.RECORD_CREATION,
|
|
4761
|
-
const{toolRecordId:x,localToolRecordId:M}=await l.createFileOperationRecords(C,T,r.projectId,I.recordType,_,{directoryExists:R,userComment:h},n,o,m,
|
|
4762
|
-
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})
|
|
4763
4775
|
let O=R
|
|
4764
4776
|
if(!R){await a.default.mkdir(E,{recursive:!0}),m.info("Successfully created directory "+_)
|
|
4765
4777
|
try{const e=c.default.join(E,".gitkeep")
|
|
4766
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
|
|
4767
|
-
|
|
4768
|
-
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!R&&O?_+"/.gitkeep":_,F=await l.commitToGit(C,A,x,M,D,r,m,
|
|
4769
|
-
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)
|
|
4770
4782
|
const N=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4771
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
|
|
4772
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
|
|
4773
|
-
if(
|
|
4774
|
-
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)}}
|
|
4775
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"
|
|
4776
4788
|
function r(e){const t=[]
|
|
4777
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"
|
|
@@ -4780,20 +4792,20 @@ case"move-files":return"\u{1f4cb} Move Files"
|
|
|
4780
4792
|
case"delete-files":return"\u{1f5d1}\ufe0f Delete Files"
|
|
4781
4793
|
case"manage-files":return"\u{1f4c1} Manage Files"
|
|
4782
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")
|
|
4783
|
-
try{const{requestId:l,detailLevel:
|
|
4795
|
+
try{const{requestId:l,detailLevel:g="summary",taskId:p,showDiff:m=!1,fileFilter:f}=e
|
|
4784
4796
|
if(!l)throw(0,o.createValidationError)("Request ID is required")
|
|
4785
4797
|
if(!/^req[_\d].+$/.test(l))throw(0,o.createValidationError)(`Invalid request ID format: ${l}. Expected format: req_[26 chars] or req######`)
|
|
4786
|
-
if(
|
|
4787
|
-
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")
|
|
4788
4800
|
const y=t.projectId
|
|
4789
4801
|
let w
|
|
4790
4802
|
c.setProjectId(y)
|
|
4791
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
|
|
4792
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)
|
|
4793
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}
|
|
4794
|
-
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()
|
|
4795
4807
|
let o=[]
|
|
4796
|
-
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"
|
|
4797
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
|
|
4798
4810
|
let u=t.filter((e=>{const t=e.type
|
|
4799
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()))
|
|
@@ -4807,10 +4819,10 @@ let r=0
|
|
|
4807
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])
|
|
4808
4820
|
if(e&&e.trim()){const r=500,n=e.length
|
|
4809
4821
|
if(n>r){const o=e.substring(0,r),s=(n/1024).toFixed(1)
|
|
4810
|
-
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)
|
|
4811
4823
|
return h({success:!0,recordCount:o.length}),{content:[{type:"text",text:s}]}}{const e=c.getToolRecordClient()
|
|
4812
4824
|
let n=[]
|
|
4813
|
-
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
|
|
4814
4826
|
let o=0
|
|
4815
4827
|
for(const s of e){const e=s.type
|
|
4816
4828
|
if(!["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(e))continue
|
|
@@ -4852,17 +4864,17 @@ return s.default.writeFileSync(t,JSON.stringify(c,null,2)),n(e,t,r),h.info("Crea
|
|
|
4852
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}}
|
|
4853
4865
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.acquireProcessLock=function(e){const t=i.default.join(e,c.ALCHEMY_DIR_NAME)
|
|
4854
4866
|
let o,l
|
|
4855
|
-
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()
|
|
4856
4868
|
try{const e=function(e){if(!s.default.existsSync(e))return null
|
|
4857
4869
|
try{const t=s.default.readFileSync(e,"utf8").trim()
|
|
4858
4870
|
try{const e=JSON.parse(t)
|
|
4859
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
|
|
4860
4872
|
const e={mode:"multi-agent",created:(new Date).toISOString(),hostname:"unknown"}
|
|
4861
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)
|
|
4862
|
-
if(h.info("Lock acquisition attempt",{pid:
|
|
4863
|
-
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:[]}
|
|
4864
4876
|
if(s.default.existsSync(e)){const t=s.default.readFileSync(e,"utf8")
|
|
4865
|
-
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}}
|
|
4866
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"
|
|
4867
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
|
|
4868
4880
|
let r=0,n=0
|
|
@@ -4911,16 +4923,16 @@ function r(e){const t=c[e]
|
|
|
4911
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.`)
|
|
4912
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)
|
|
4913
4925
|
if(!s(u.projectId)){const t=Error(`Invalid projectId format: ${u.projectId}. Cannot create failure record without valid projectId.`)
|
|
4914
|
-
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
|
|
4915
4927
|
try{const t=r(e),s={}
|
|
4916
4928
|
let i,f
|
|
4917
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})))
|
|
4918
|
-
let y=u.note||`Failed to execute ${e}: ${
|
|
4930
|
+
let y=u.note||`Failed to execute ${e}: ${p.substring(0,100)}${p.length>100?"...":""}`
|
|
4919
4931
|
Object.keys(s).length>0&&(y+=` (Warning: Invalid IDs provided: ${Object.entries(s).map((([e,t])=>`${e}: ${t}`)).join(", ")})`)
|
|
4920
|
-
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:
|
|
4921
|
-
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})
|
|
4922
4934
|
const b=await c.createToolRecord(w)
|
|
4923
|
-
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}}
|
|
4924
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"
|
|
4925
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)
|
|
4926
4938
|
else if(e&&"object"==typeof e)for(const t of Object.keys(e)){const n=e[t]
|
|
@@ -4945,13 +4957,13 @@ function r(e,t,r){const n=exports.ERROR_TYPE_PROPERTIES[e]||exports.ERROR_TYPE_P
|
|
|
4945
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)
|
|
4946
4958
|
return{statusCode:e.statusCode,body:t}}if(e instanceof Error&&"ConnectionError"===e.name){const t=e
|
|
4947
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")
|
|
4948
|
-
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
|
|
4949
4961
|
const i=t(7388)
|
|
4950
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}
|
|
4951
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)
|
|
4952
4964
|
const o=exports.ERROR_TYPE_PROPERTIES[this.code]
|
|
4953
|
-
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
|
|
4954
|
-
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"
|
|
4955
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}
|
|
4956
4968
|
const o=e.split("\n"),s=[],i=new Set
|
|
4957
4969
|
let a=!1,c=""
|
|
@@ -5005,9 +5017,9 @@ for(const a of r){const r=await n(a,t,o,s,i,e,c,l)
|
|
|
5005
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
|
|
5006
5018
|
if(!h||!h.all||0===h.all.length)return l.debug(`No commits found in standard git log for ${i}:${t}`),[]
|
|
5007
5019
|
l.info(`Found ${h.all.length} commits for ${i}:${t}`)
|
|
5008
|
-
const
|
|
5020
|
+
const g=[]
|
|
5009
5021
|
for(const r of h.all){const a=await n(r,t,o,s,i,e,c,l)
|
|
5010
|
-
|
|
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
|
|
5011
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)
|
|
5012
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)
|
|
5013
5025
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
@@ -5017,7 +5029,7 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
5017
5029
|
var t={}
|
|
5018
5030
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
5019
5031
|
return i(t,e),t})
|
|
5020
|
-
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()
|
|
5021
5033
|
try{const o=e,{path:a,limit:m,showDiff:f,showTraceability:y,branch:w,commit:b,since:I}=o
|
|
5022
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,"/")
|
|
5023
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}
|
|
@@ -5025,18 +5037,18 @@ try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
|
|
|
5025
5037
|
if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
|
|
5026
5038
|
const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
|
|
5027
5039
|
let a="# File History - Commit Diff\n\n"
|
|
5028
|
-
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)
|
|
5029
5041
|
try{await l.access(y)}catch(e){throw Error("File not found: "+f)}const w=a.git
|
|
5030
5042
|
if(!w)throw Error("Git is not available in this context")
|
|
5031
5043
|
let b={branch:null,requestId:null,isMain:!0}
|
|
5032
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=""
|
|
5033
|
-
if(s)I=await r(w,f,t,n,o,s,i,c,h,
|
|
5034
|
-
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,
|
|
5035
|
-
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)}]}
|
|
5036
5048
|
{const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
|
|
5037
|
-
if(!i.isMain&&i.branch){const
|
|
5038
|
-
u.push(...
|
|
5039
|
-
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)
|
|
5040
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}]}
|
|
5041
5053
|
const v=I.length,C=Math.min(I.length,t)
|
|
5042
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:** "
|
|
@@ -5045,9 +5057,9 @@ for(let e=0;e<I.length;e++){const t=I[e]
|
|
|
5045
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")
|
|
5046
5058
|
let r=0,n=0
|
|
5047
5059
|
for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
|
|
5048
|
-
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
|
|
5049
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}}}
|
|
5050
|
-
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"
|
|
5051
5063
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
5052
5064
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5053
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=[]
|
|
@@ -5171,63 +5183,63 @@ return"string"==typeof e&&e.startsWith("R-")?"acknowledge-report":"string"==type
|
|
|
5171
5183
|
if(t)return t
|
|
5172
5184
|
try{const t=await fetch(`http://localhost:${b}/api/sessions/${encodeURIComponent(e)}/agent-type`)
|
|
5173
5185
|
if(t.ok){const r=await t.json()
|
|
5174
|
-
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)
|
|
5175
5187
|
if(!i)return o.warn("Could not get server URL for notification",{sessionId:e}),!1
|
|
5176
5188
|
const a=await n(e)??void 0
|
|
5177
5189
|
let c
|
|
5178
5190
|
try{const e=await fetch(`http://localhost:${b}/api/project-settings`)
|
|
5179
5191
|
if(e.ok){const t=await e.json()
|
|
5180
5192
|
if(t.data?.defaultModel){const[e,...r]=t.data.defaultModel.split("/")
|
|
5181
|
-
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}:{}})})
|
|
5182
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
|
|
5183
5195
|
if(!s)throw new u.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
|
|
5184
5196
|
return(0,w.logSessionIdentity)(""+r,"identity",{sessionId:s,fromCliOrigin:!!o?.sessionId}),s}function a(e){const t=[],r=e.content||{}
|
|
5185
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:**")
|
|
5186
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||{}
|
|
5187
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||{}
|
|
5188
|
-
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"})
|
|
5189
5201
|
if(!b)throw new u.ValidationError("API client not available")
|
|
5190
5202
|
const{operation:v}=e
|
|
5191
|
-
k.info("Session message operation",{operation:v}),
|
|
5203
|
+
k.info("Session message operation",{operation:v}),g.incrementCounter("session_message_operations",1,{operation:v})
|
|
5192
5204
|
try{switch(v){case"send":if(!e.type)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
5193
|
-
return(0,
|
|
5205
|
+
return(0,p.withAlchemyKind)(await async function(e,t,r,c,d){const{type:h}=e
|
|
5194
5206
|
if(!h)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
5195
|
-
const
|
|
5196
|
-
if(!
|
|
5197
|
-
if("question"===h)return await async function(e,t,r,c,l,d){const{toSessionId:h,questionType:
|
|
5198
|
-
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")
|
|
5199
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)
|
|
5200
5212
|
if(!e)throw new u.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
|
|
5201
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)
|
|
5202
|
-
if(!("alternatives"!==p
|
|
5203
|
-
r.info("Creating question",{fromSessionId:b,toSessionId:I,questionType:
|
|
5204
|
-
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}:{}})
|
|
5205
5217
|
let v=""
|
|
5206
|
-
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}:{}}}}
|
|
5207
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]
|
|
5208
5220
|
if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&&t.options){r.push(""),r.push("**Options:**")
|
|
5209
|
-
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,
|
|
5210
|
-
if("report"===h)return await async function(e,t,r,a,c,d){const{status:h,summary:
|
|
5211
|
-
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")
|
|
5212
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)
|
|
5213
5225
|
const t=await s(b,a,r)
|
|
5214
5226
|
if(t)return r.info("Auto-resolved parent session",{parentSessionId:t}),t
|
|
5215
5227
|
throw new u.ValidationError("Could not find parent session. Ensure this session was created with a parent link, or provide an explicit toSessionId.")})()
|
|
5216
5228
|
r.info("Submitting report",{sessionId:b,parentSessionId:I,status:h})
|
|
5217
|
-
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||{}
|
|
5218
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)
|
|
5219
|
-
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)
|
|
5220
5232
|
throw new u.ValidationError(`Unknown message type: ${h}. Use "question" or "report".`)}(e,t,k,b,I),r("send",e))
|
|
5221
5233
|
case"reply":if(!e.messageCode)throw new u.ValidationError("reply operation requires messageCode")
|
|
5222
|
-
return(0,
|
|
5234
|
+
return(0,p.withAlchemyKind)(await async function(e,t,r,s,i){const{messageCode:c}=e
|
|
5223
5235
|
if(!c)throw new u.ValidationError("reply operation requires messageCode")
|
|
5224
5236
|
const d=s.getSessionMessageClient()
|
|
5225
5237
|
if(!d)throw new u.ValidationError("Session message client not available")
|
|
5226
5238
|
if(c.startsWith("Q-")){const{text:s,selectedOptions:l,notes:u}=e,h=e.respondedBySessionId??i?.sessionId
|
|
5227
5239
|
r.info("Answering question",{messageCode:c,respondedBySessionId:h,autoDerived:!e.respondedBySessionId})
|
|
5228
|
-
const
|
|
5229
|
-
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")}(
|
|
5230
|
-
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})
|
|
5231
5243
|
const e=await d.acknowledgeReport(c)
|
|
5232
5244
|
let s=""
|
|
5233
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}}}
|
|
@@ -5240,13 +5252,13 @@ let l
|
|
|
5240
5252
|
try{const e=b.getSessionMessageClient()
|
|
5241
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"})
|
|
5242
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()
|
|
5243
|
-
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
|
|
5244
5256
|
const m=n.getSessionMessageClient()
|
|
5245
5257
|
if(!m)throw new u.ValidationError("Session message client not available")
|
|
5246
5258
|
if(!s){const e=o?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
|
|
5247
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."}]}
|
|
5248
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})
|
|
5249
|
-
const y={sessionId:s,direction:a,limit:
|
|
5261
|
+
const y={sessionId:s,direction:a,limit:g,offset:p}
|
|
5250
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)
|
|
5251
5263
|
const b=await m.listMessages(y)
|
|
5252
5264
|
if(0===b.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
|
|
@@ -5254,7 +5266,7 @@ const I=[`Found ${b.length} message(s):\n`]
|
|
|
5254
5266
|
for(const e of b)I.push("---\n"),I.push(d(e)),I.push("")
|
|
5255
5267
|
return{content:[{type:"text",text:I.join("\n")}]}}(e.list||{},0,k,b,I),"list-messages")
|
|
5256
5268
|
case"get":if(!e.messageCode)throw new u.ValidationError("get operation requires messageCode")
|
|
5257
|
-
return(0,
|
|
5269
|
+
return(0,p.withAlchemyKind)(await async function(e,t,r){const{messageCode:n}=e
|
|
5258
5270
|
if(!n)throw new u.ValidationError("get operation requires messageCode")
|
|
5259
5271
|
const o=r.getSessionMessageClient()
|
|
5260
5272
|
if(!o)throw new u.ValidationError("Session message client not available")
|
|
@@ -5262,7 +5274,7 @@ t.debug("Getting message",{messageCode:n})
|
|
|
5262
5274
|
const s=await o.getMessage(n)
|
|
5263
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")
|
|
5264
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}}}
|
|
5265
|
-
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"
|
|
5266
5278
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
5267
5279
|
const r=t(6183),n=t(1281)
|
|
5268
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"
|
|
@@ -5288,12 +5300,12 @@ let l,d
|
|
|
5288
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)})
|
|
5289
5301
|
let u=0
|
|
5290
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})
|
|
5291
|
-
let h=!1,
|
|
5292
|
-
if(0!==u?(h=!0,
|
|
5293
|
-
!
|
|
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))
|
|
5294
5306
|
let m=[]
|
|
5295
|
-
if(
|
|
5296
|
-
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=[]
|
|
5297
5309
|
if(!e||!e.trim())return t.debug("Empty merge-tree output - no conflicts to parse"),[]
|
|
5298
5310
|
let n
|
|
5299
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
|
|
@@ -5350,23 +5362,23 @@ o+=`## Test 4: All commits containing "${n}" (not just merges)\n`,o+=`Found ${e?
|
|
|
5350
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()
|
|
5351
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}}}
|
|
5352
5364
|
const r=t(8824)},9442(e,exports,t){"use strict"
|
|
5353
|
-
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"}}
|
|
5354
5366
|
try{let t,o
|
|
5355
5367
|
if(m){t=await n.documentFileManager.getDocumentAsFile(d)
|
|
5356
5368
|
const e=n.documentFileManager.getCachedDocumentInfo(d)
|
|
5357
5369
|
y.filename=e?.filename,o="document:"+d}else{const e=u.validateAndNormalizePath(c,n)
|
|
5358
|
-
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),
|
|
5359
|
-
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}
|
|
5360
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)
|
|
5361
5373
|
continue}const t=(0,h.findMatches)(s,n,f,100,e.path)
|
|
5362
5374
|
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(f?" (tried fuzzy matching)":""),a.success=!1
|
|
5363
5375
|
const e=(0,h.findSimilarMatches)(s,n,5,.3)
|
|
5364
|
-
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
|
|
5365
5377
|
const I=[]
|
|
5366
|
-
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})
|
|
5367
5379
|
I.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5368
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++)
|
|
5369
|
-
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)
|
|
5370
5382
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5371
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=[]
|
|
5372
5384
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -5381,7 +5393,7 @@ if("errorResult"in T)return T.errorResult
|
|
|
5381
5393
|
const{taskId:q}=T,{operations:P,fuzzy_match:j=!0,comment:R}=E
|
|
5382
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})
|
|
5383
5395
|
const x=P.filter((e=>e.documentId)).map((e=>e.documentId))
|
|
5384
|
-
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}
|
|
5385
5397
|
throw e}_=u.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_in_files_phase",1,{phase:_})
|
|
5386
5398
|
const M=P[0],O=M.documentId?"document:"+M.documentId:M.path
|
|
5387
5399
|
let $=Date.now()
|
|
@@ -5396,7 +5408,7 @@ const t=await u.autoPromoteTaskStatus(q,D.status,A,e.request?.status,O,o,i,k,c,"
|
|
|
5396
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()
|
|
5397
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"})
|
|
5398
5410
|
if(!n.success)throw Error(n.error)
|
|
5399
|
-
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}
|
|
5400
5412
|
throw e}$=Date.now()
|
|
5401
5413
|
const z=new Map
|
|
5402
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=[]
|
|
@@ -5432,7 +5444,7 @@ const d=o.workspaceManager?.consumeLargeFileWarning(o.currentSessionId)
|
|
|
5432
5444
|
return d&&(c+=d),c}(H,W,J,Q,r)
|
|
5433
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
|
|
5434
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))
|
|
5435
|
-
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"
|
|
5436
5448
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
|
|
5437
5449
|
const t=e.trim()
|
|
5438
5450
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|
|
@@ -5501,12 +5513,12 @@ const s=n.sortDirection??"desc"
|
|
|
5501
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
|
|
5502
5514
|
if(!u)throw new r.ValidationError("Project ID is required for listing tasks with the new API structure")
|
|
5503
5515
|
a.incrementCounter("list_tasks_attempts",1,{hasRequestId:!!i,hasFilters:Object.keys(d).length>0}),s.setProjectId(u)
|
|
5504
|
-
const h=s.getTaskClient(),
|
|
5505
|
-
i&&(
|
|
5506
|
-
const
|
|
5507
|
-
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"})
|
|
5508
5520
|
let m=[]
|
|
5509
|
-
|
|
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=[])
|
|
5510
5522
|
const f=m
|
|
5511
5523
|
if(c.info(`Retrieved ${f.length} tasks`,{count:f.length,requestId:i,projectId:u}),0===f.length){let e=""
|
|
5512
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
|
|
@@ -5616,8 +5628,8 @@ function r(e){return a.default.createHash("md5").update(e).digest("hex")}async f
|
|
|
5616
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]
|
|
5617
5629
|
let t=e
|
|
5618
5630
|
try{t=s.default.realpathSync(e)}catch{}return i.default.dirname(t)}(),u=i.default.join((0,c.getGlobalConfigDir)(e),"plugin")
|
|
5619
|
-
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"),
|
|
5620
|
-
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)
|
|
5621
5633
|
try{if(!s.default.existsSync(o)){t.warn("Plugin source not found: "+e.sourceName,{sourcePath:o}),a.errors.push(e.destName)
|
|
5622
5634
|
continue}const i=await s.default.promises.readFile(o,"utf8").catch((()=>null))
|
|
5623
5635
|
if(null===i){t.warn("Could not read plugin source: "+e.sourceName),a.errors.push(e.destName)
|