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/mcp-direct.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=x},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)),p=t(9567),
|
|
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
|
|
17
|
+
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),p=t(9567),m=t(3444),g=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),q=t(8824),T=(0,m.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),x=process.stdout.write,P=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
|
|
18
|
+
!(0,m.isDebugToolsEnabled)()||P&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,m.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&T.debug("Stdout output",{content:e.substring(0,100),length:e.length}),x.call(process.stdout,e)}catch(e){return T.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 g.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 p.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__")
|
|
@@ -114,12 +114,12 @@ 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
115
|
try{const{query:a,searchIn:l="all",filters:p={}}=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:p,projectId:
|
|
120
|
-
const
|
|
121
|
-
p.status&&(
|
|
122
|
-
const f=c.getRequestClient(),y=await f.listRequests(
|
|
117
|
+
const m=t.projectId
|
|
118
|
+
if(!m)throw new i.ValidationError("Project ID is required for searching requests")
|
|
119
|
+
u.info("Searching requests",{query:a,searchIn:l,filters:p,projectId:m})
|
|
120
|
+
const g={limit:p.limit||100,offset:p.offset||0,sortBy:"updated_at",sortDirection:"desc"}
|
|
121
|
+
p.status&&(g.status=p.status),p.type&&(g.type=p.type),p.dateFrom&&(g.dateFrom=p.dateFrom),p.dateTo&&(g.dateTo=p.dateTo),c.setProjectId(m)
|
|
122
|
+
const f=c.getRequestClient(),y=await f.listRequests(g)
|
|
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=[]
|
|
@@ -165,25 +165,25 @@ 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,p){const
|
|
169
|
-
try{const a=e,{operation:d,planId:
|
|
170
|
-
switch(
|
|
168
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlanWrite=async function(e,t,l,d,u,h,p){const m=d.child({tool:"plan_write"})
|
|
169
|
+
try{const a=e,{operation:d,planId:g}=a
|
|
170
|
+
switch(m.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,m,u,h,p)
|
|
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:
|
|
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:
|
|
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:
|
|
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(
|
|
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:** ${
|
|
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:** ${
|
|
173
|
+
return(0,c.withAlchemyKind)(e,i.KIND_META[r].alchemyKind)}case"update":{const e=await(0,r.handleUpdatePlan)({planId:g,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,m,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:g,content:a.content,name:a.name},l,m,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:g,old:a.old,new:a.new,name:a.name},l,m,u)
|
|
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(g,e,t)
|
|
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:** ${g}\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(g,e)
|
|
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:** ${g}\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
|
|
179
179
|
if(!e)return{content:[{type:"text",text:"\u274c No project context available."}],isError:!0}
|
|
180
|
-
const r=l.getDocumentClient(),n=await r.getDocument(
|
|
181
|
-
if(!n)return{content:[{type:"text",text:"\u274c Plan not found: "+
|
|
182
|
-
if("Plan"!==n.type)return{content:[{type:"text",text:`\u274c Document ${
|
|
180
|
+
const r=l.getDocumentClient(),n=await r.getDocument(g)
|
|
181
|
+
if(!n)return{content:[{type:"text",text:"\u274c Plan not found: "+g}],isError:!0}
|
|
182
|
+
if("Plan"!==n.type)return{content:[{type:"text",text:`\u274c Document ${g} is not a Plan (type: ${n.type}).`}],isError:!0}
|
|
183
183
|
const o=l.getProjectClient()
|
|
184
|
-
await o.updateProject(e,{activePlanId:
|
|
184
|
+
await o.updateProject(e,{activePlanId:g}),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 m.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
|
|
@@ -251,23 +251,23 @@ 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
253
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQueryHistory=async function(e,c,l,d,u,h){const p=d.child({tool:"query_history"})
|
|
254
|
-
try{const a=e,{queryType:
|
|
255
|
-
let
|
|
256
|
-
switch(p.info("Processing query_history request",{queryType:
|
|
254
|
+
try{const a=e,{queryType:m}=a
|
|
255
|
+
let g
|
|
256
|
+
switch(p.info("Processing query_history request",{queryType:m}),m){case"file-history":p.info("Routing to file-history handler",{path:a.fileHistory.path}),g=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,p,u)
|
|
257
257
|
break
|
|
258
|
-
case"request-file-history":p.info("Routing to request-file-history handler",{requestId:a.requestHistory.requestId}),
|
|
258
|
+
case"request-file-history":p.info("Routing to request-file-history handler",{requestId:a.requestHistory.requestId}),g=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,p,u)
|
|
259
259
|
break
|
|
260
260
|
case"recover":p.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
|
-
p.info("Auto-resolved previous version",{filePath:e,commitHash:s})}catch{return{content:[{type:"text",text:"Could not find previous versions of "+e}],isError:!0}}}
|
|
265
|
+
p.info("Auto-resolved previous version",{filePath:e,commitHash:s})}catch{return{content:[{type:"text",text:"Could not find previous versions of "+e}],isError:!0}}}g=await(0,o.handleFileRecover)({taskId:e.recover?.taskId||await(async()=>{const{resolveActiveTaskId:e}=await Promise.resolve().then(t.bind(t,3451))
|
|
266
266
|
return await e(c,l,d)||"untracked"})(),path:a.recover.path,commitHash:s,createBackup:a.recover.createBackup},c,l,l.getToolRecordClient(),p,u,h)
|
|
267
267
|
break
|
|
268
|
-
case"blame":p.info("Routing to file-blame handler",{path:a.blame.path,lines:a.blame.lines}),
|
|
268
|
+
case"blame":p.info("Routing to file-blame handler",{path:a.blame.path,lines:a.blame.lines}),g=await(0,i.handleFileBlame)({path:a.blame.path,lines:a.blame.lines,branch:a.blame.branch},c,l,p,u)
|
|
269
269
|
break
|
|
270
|
-
default:throw Error("Unknown query type: "+
|
|
270
|
+
default:throw Error("Unknown query type: "+m)}return p.info("query_history request completed",{queryType:m,success:!g.isError}),u.incrementCounter("query_history_total",1,{success:!g.isError,queryType:m}),(0,s.withAlchemyKind)(g,"query-history")}catch(e){return p.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)
|
|
@@ -380,9 +380,9 @@ this.logger.debug("Making token validation request",{validationUrl:t})
|
|
|
380
380
|
const r=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Content-Type":"application/json"},signal:AbortSignal.timeout(1e4)})
|
|
381
381
|
if(r.ok){const e=await r.json()
|
|
382
382
|
return this.logger.info("Token validation successful",{status:e.status||"unknown",username:e.username||"unknown"}),!0}return this.logger.info("Token validation failed - token may be invalid or expired",{status:r.status,statusText:r.statusText}),this.invalidateCache(),!1}catch(e){return e instanceof Error&&"AbortError"===e.name?(this.logger.info("Token validation request timed out - assuming offline or server unavailable"),!0):(this.logger.info("Token validation request failed",{error:(0,c.getErrorMessage)(e)}),!0)}}async hasValidAndWorkingToken(){return!!await this.hasValidToken()&&await this.validateTokenWithRemoteServer()}async isGoogleOAuthAvailable(){return await this.authFlow.isGoogleOAuthAvailable()}async startGoogleOAuthFlow(){return await this.authFlow.startGoogleOAuthFlow()}async startGoogleOAuthPolling(e,t,r,n,o){return await this.authFlow.startGoogleOAuthPolling(e,t,r,n,o)}}},1281(e,exports,t){"use strict"
|
|
383
|
-
async function r(e,t,o,s,i,a,c,l,d,u=0){let
|
|
383
|
+
async function r(e,t,o,s,i,a,c,l,d,u=0){let m=0,g=0,f=0
|
|
384
384
|
const y=[]
|
|
385
|
-
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:
|
|
385
|
+
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:m,fileMatchesCount:g,subdirCount:f,subdirStats:y}
|
|
386
386
|
try{const w=await p.default.readdir(e,{withFileTypes:!0}),b=[],C=[]
|
|
387
387
|
for(const t of w){const r=h.default.join(e,t.name)
|
|
388
388
|
if(t.isDirectory()){if(k.includes(t.name)||t.name.startsWith(".")){a.debug("Skipping excluded directory: "+t.name)
|
|
@@ -391,15 +391,15 @@ continue}b.push({entry:t,fullPath:r})}}if(b.length>0){const e=[]
|
|
|
391
391
|
for(let t=0;t<b.length;t+=16)e.push(b.slice(t,t+16))
|
|
392
392
|
for(const r of e){if(o.length>=v)break
|
|
393
393
|
const e=await Promise.all(r.map((({entry:e,fullPath:r})=>n(r,t,0,o,l,d,e.name,u))))
|
|
394
|
-
for(const t of e){
|
|
395
|
-
for(const e of t.matches){if(o.length>=v)return{filesCount:
|
|
394
|
+
for(const t of e){m++,t.hasMatches&&g++
|
|
395
|
+
for(const e of t.matches){if(o.length>=v)return{filesCount:m,fileMatchesCount:g,subdirCount:f,subdirStats:y}
|
|
396
396
|
o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=v)break
|
|
397
397
|
f++
|
|
398
398
|
const e={path:n,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
399
399
|
try{const l=await r(n,t,o,s,i,a,c+1,e,d,u)
|
|
400
|
-
|
|
400
|
+
m+=l.filesCount,g+=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)}`
|
|
401
401
|
e.errors.push(r),y.push(e),a.error(r)}}}catch(t){const r=`Error searching directory ${e}: ${(0,I.getErrorMessage)(t)}`
|
|
402
|
-
l.errors.push(r),a.warn(r)}return{filesCount:
|
|
402
|
+
l.errors.push(r),a.warn(r)}return{filesCount:m,fileMatchesCount:g,subdirCount:f,subdirStats:y}}async function n(e,t,r,n,o,s,i,a=0){const c=[]
|
|
403
403
|
let l,d=!1
|
|
404
404
|
const u=async()=>{if(void 0===l)try{const t=await p.default.stat(e)
|
|
405
405
|
l=t.mtime.getTime()}catch(e){l=void 0}return l}
|
|
@@ -432,31 +432,31 @@ if(null!=e)for(var r=a(e),n=0;n<r.length;n++)"default"!==r[n]&&c(t,e,r[n])
|
|
|
432
432
|
return l(t,e),t}),u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
433
433
|
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()
|
|
434
434
|
let k=0
|
|
435
|
-
const v={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:
|
|
436
|
-
try{const{needle:n,directory:
|
|
437
|
-
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,b.handleListDirectory)({path:
|
|
438
|
-
if("string"!=typeof n)throw v.errors.push("Search term (needle) must be a string"),(0,
|
|
435
|
+
const v={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:m.default.hostname(),username:m.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:[]}
|
|
436
|
+
try{const{needle:n,directory:m,options:C={}}=e
|
|
437
|
+
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,b.handleListDirectory)({path:m||".",levels:C.levels||1,sortBy:C.sortBy||"name"},t,a,c)
|
|
438
|
+
if("string"!=typeof n)throw v.errors.push("Search term (needle) must be a string"),(0,g.createValidationError)("Search term (needle) must be a string")
|
|
439
439
|
let _
|
|
440
|
-
if(v.searchDirectory=
|
|
440
|
+
if(v.searchDirectory=m||".",m){const{normalizedPath:e,fullPath:r}=f.validateAndNormalizePath(m,t)
|
|
441
441
|
_=r}else _=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath
|
|
442
442
|
v.resolvedPath=_
|
|
443
443
|
let E=!1
|
|
444
444
|
try{E=(await p.default.stat(_)).isFile()}catch(e){const t=`Cannot access path ${_}: ${(0,I.getErrorMessage)(e)}`
|
|
445
445
|
throw v.errors.push(t),Error(t)}const S=C.maxResults||50,q=C.caseSensitive||!1,T=C.useRegex||!1,x=C.fileExtension,P=C.searchIn||"content"
|
|
446
446
|
let R=void 0!==C.contextLines?C.contextLines:0
|
|
447
|
-
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!E&&!x)throw v.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,
|
|
447
|
+
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!E&&!x)throw v.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,g.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
|
|
448
448
|
let M,$=""
|
|
449
449
|
if(E)$="*"
|
|
450
450
|
else if("*"===x)$="*"
|
|
451
451
|
else if(x){let e=x;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),$=e.startsWith(".")?e:"."+e}try{M=T?q?RegExp(n):RegExp(n,"i"):q?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${T?"regex":"search"} pattern: ${(0,I.getErrorMessage)(e)}`
|
|
452
|
-
throw v.errors.push(t),(0,
|
|
452
|
+
throw v.errors.push(t),(0,g.createValidationError)(t)}if(v.patternInfo={needle:n,regex:M.toString(),caseSensitive:q,fileExtension:x,normalizedExtension:$},!E)try{const e=Date.now(),t=await p.default.readdir(_,{withFileTypes:!0}),r=[],n=[]
|
|
453
453
|
for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
|
|
454
454
|
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)
|
|
455
455
|
v.errors.push(t),l.error(t)}const j=E?"file":"directory"
|
|
456
456
|
l.info(`Searching for "${n}" in ${j} ${_} (mode: ${P})`,{needle:n,searchTarget:j,path:_,options:{maxResults:S,caseSensitive:q,fileExtension:$,searchIn:P}}),k=Date.now(),v.phases.initializationTime=k-u
|
|
457
457
|
const O=Date.now()
|
|
458
458
|
let D=[],A=0,F=0
|
|
459
|
-
try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,
|
|
459
|
+
try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,m=[]
|
|
460
460
|
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)
|
|
461
461
|
let c
|
|
462
462
|
n.info("Searching single file: "+e,{searchIn:r})
|
|
@@ -468,10 +468,10 @@ t.contextBefore=r.slice(e,n).map((e=>(0,y.truncate)(e.trim(),120)))
|
|
|
468
468
|
const o=Math.min(r.length,n+1+s)
|
|
469
469
|
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)}`
|
|
470
470
|
o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
|
|
471
|
-
const
|
|
472
|
-
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,
|
|
473
|
-
return
|
|
474
|
-
return
|
|
471
|
+
const g={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
472
|
+
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,m,a,o,s,0,g,l,u)
|
|
473
|
+
return g.filesProcessed=n,g.filesMatched=c,g.subdirectories=d,i.directoryStats.push(g),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:m.length,directories:d+1}),{matches:m,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,I.getErrorMessage)(t)
|
|
474
|
+
return g.errors.push(r),i.directoryStats.push(g),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:m,totalFiles:g.filesProcessed}}}(_,M,{maxResults:S,fileExtension:$,searchIn:P,isFile:E,contextLines:R},$,l,v)
|
|
475
475
|
D=e.matches,A=e.totalFiles
|
|
476
476
|
const t=1e3
|
|
477
477
|
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)
|
|
@@ -481,7 +481,7 @@ let N,z=""
|
|
|
481
481
|
try{if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
482
482
|
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})
|
|
483
483
|
const L="content"===P?"content":"filename"===P?"filenames":"content and filenames"
|
|
484
|
-
if(F>D.length?(N=`Found ${F} results for "${n}" (searching ${L})`,
|
|
484
|
+
if(F>D.length?(N=`Found ${F} results for "${n}" (searching ${L})`,m&&(N+=" in "+m),x&&(N+=" with extension "+x),N+=`${z}. Showing first ${D.length}:\n\n`):(N=`Found ${D.length} results for "${n}" (searching ${L})`,m&&(N+=" in "+m),x&&(N+=" with extension "+x),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))
|
|
485
485
|
if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
|
|
486
486
|
const o=new Map
|
|
487
487
|
for(const e of n){const t=o.get(e.file)||[]
|
|
@@ -505,7 +505,7 @@ else N+="No matches found."
|
|
|
505
505
|
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})
|
|
506
506
|
let r="Search failed: "+(0,I.getErrorMessage)(t)
|
|
507
507
|
return d({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:r}],isError:!0}}}
|
|
508
|
-
const h=u(t(6928)),p=u(t(1943)),
|
|
508
|
+
const h=u(t(6928)),p=u(t(1943)),m=u(t(857)),g=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"
|
|
509
509
|
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)
|
|
510
510
|
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}`])
|
|
511
511
|
if(!a||""===a.trim())return null
|
|
@@ -523,12 +523,12 @@ for(const e of r){const r=e.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/)
|
|
|
523
523
|
if(r){const e=parseInt(r[3],10),n=r[4]?parseInt(r[4],10):1,o=e+n-1
|
|
524
524
|
n>0&&t.push({start:e,end:o})}}return t}(s)
|
|
525
525
|
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})
|
|
526
|
-
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),p=!!h&&n(h),
|
|
526
|
+
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),p=!!h&&n(h),m=t.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),g=d.map((e=>`${e.start}-${e.end}`)).join(", ")||"none",f=u?u.substring(0,300):"no diff"
|
|
527
527
|
if(0===d.length){const r=[]
|
|
528
528
|
for(const s of t.lineRanges){const a=await o(e,t.path,s.start,s.end,i)
|
|
529
|
-
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 ${
|
|
530
|
-
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:
|
|
531
|
-
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:
|
|
529
|
+
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 ${m} 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")
|
|
530
|
+
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:m,uncommittedChanges:"none",lastCommit:r[0].commit.message,wasLastCommitAlchemy:!1,diffPreview:e,overlapDetected:!0}}}return{hasExternalEdits:!1,conflictingLines:[],debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:"none",lastCommit:h,wasLastCommitAlchemy:p,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)
|
|
531
|
+
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:g,lastCommit:h,wasLastCommitAlchemy:p,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: "+m,"Conflicting lines: "+s(w),"",p?"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:m,uncommittedChanges:g,lastCommit:h,wasLastCommitAlchemy:p,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}}
|
|
532
532
|
const a=t(9947),c=i(t(6928)),l=t(8824)},1387(e,exports,t){"use strict"
|
|
533
533
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.WorkspaceRequestProcessor=void 0
|
|
534
534
|
const r=t(7075),n=t(5964),o=t(8824)
|
|
@@ -585,17 +585,17 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
585
585
|
var t={}
|
|
586
586
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
587
587
|
return i(t,e),t})
|
|
588
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentity=void 0,exports.registerTools=function(e,o,s,i,a,
|
|
588
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentity=void 0,exports.registerTools=function(e,o,s,i,a,m,I){const k=i.child({component:"tools"})
|
|
589
589
|
k.info("Registering tools...")
|
|
590
590
|
let v=!1
|
|
591
|
-
const C=!!
|
|
592
|
-
try{return await
|
|
591
|
+
const C=!!m,_=async()=>{if(!C)return!0
|
|
592
|
+
try{return await m.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 _()
|
|
593
593
|
k.info(`Generating tools list with testsRequired=${e}, authenticated=${t}`)
|
|
594
594
|
const r={testsRequired:e,authenticated:t}
|
|
595
595
|
return(0,f.generateVisibleToolsList)(r)}
|
|
596
596
|
let S=E(),q=[]
|
|
597
597
|
S.then((e=>{q=e})).catch((e=>{k.error("Error generating initial tools list",{error:(0,d.getErrorMessage)(e)}),q=[]})),e.setRequestHandler(c.ListToolsRequestSchema,(async()=>{try{return q=await E(),{tools:q}}catch(e){return k.error("Error generating tools list",{error:(0,d.getErrorMessage)(e)}),{tools:[]}}})),e.setRequestHandler(c.CallToolRequestSchema,(async e=>{let c
|
|
598
|
-
try{const{name:n,arguments:b={},_meta:E}=e.params;(0,
|
|
598
|
+
try{const{name:n,arguments:b={},_meta:E}=e.params;(0,g.logSessionIdentity)(n,"_meta-debug",{has_meta:!!E,sessionId:E?.sessionId||null,messageId:E?.messageId||null,paramKeys:Object.keys(e.params)}),k.info("Tool call received: "+n,{tool:n}),a.incrementCounter("tool_calls_total",1,{tool:n})
|
|
599
599
|
const S=a.startTimer("tool_execution_time")
|
|
600
600
|
Date.now()
|
|
601
601
|
let q=Date.now()
|
|
@@ -603,9 +603,9 @@ if(c=r(b),Date.now(),q=Date.now(),C){const e=await _()
|
|
|
603
603
|
if(Date.now(),!e)return k.warn("Unauthenticated tool call attempt",{tool:n}),{content:[{type:"text",text:"Authentication required. Please run 'alchemylab setup' to authenticate and configure your project."}],isError:!0}}const T=(0,f.getToolByName)(n)
|
|
604
604
|
let x
|
|
605
605
|
if(q=Date.now(),s?(s.setOptions({createRecords:T?.createsRecords??!1}),k.info(`Setting record creation for tool ${n}: ${T?.createsRecords??!1}`)):k.debug(`No API client available for tool ${n} (minimal mode)`),Date.now(),Date.now(),q=Date.now(),E?.sessionId){const e=E.sessionId,t=E.messageId,r=h.sessionIdentity.getIdentity()
|
|
606
|
-
if(r)r.sessionId!==e&&((0,
|
|
606
|
+
if(r)r.sessionId!==e&&((0,g.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))
|
|
607
607
|
else{const t=await(0,u.getServerUrl)(o,k)
|
|
608
|
-
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}x={providerId:"opencode",sessionId:e,messageId:t,createdAt:(new Date).toISOString()},(0,
|
|
608
|
+
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}x={providerId:"opencode",sessionId:e,messageId:t,createdAt:(new Date).toISOString()},(0,g.logSessionIdentity)(n,"_meta",{sessionId:e,messageId:t})}else if(l=n,m=E,v||(v=!0,k.warn("No _meta.sessionId on tool call \u2014 caller not on alchemylab-opencode fork.",{tool:l,metaKeys:m?Object.keys(m):null})),!1!==T?.requiresSession)throw(0,p.createMcpProtocolError)(`_meta.sessionId required for tool '${n}'`,{tool:n})
|
|
609
609
|
h.sessionIdentity.setCurrentCallOrigin(x)
|
|
610
610
|
const P=x?.sessionId||E?.sessionId
|
|
611
611
|
if(o?.workspaceManager){q=Date.now()
|
|
@@ -618,24 +618,24 @@ try{if(T){(0,y.preNormalize)(n,c),await(0,w.expandTaskRefsInArgs)(c,s,x?.session
|
|
|
618
618
|
const e={context:R,apiClient:s,logger:i,metrics:a,mcpServer:I,cliOrigin:x}
|
|
619
619
|
j=await T.handler(c,e)}else k.info(`Tool ${n} not found, returning negative response`),j={content:[{type:"text",text:`The tool '${n}' does not exist.`}]}}finally{$("end")}return Date.now(),Date.now(),S({tool:n,success:!0}),j}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"})
|
|
620
620
|
let r="Unknown error"
|
|
621
|
-
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,
|
|
621
|
+
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,m})),k.info("Tools registration complete")}
|
|
622
622
|
const c=t(9150),l=t(2478),d=t(8824),u=t(7617),h=t(6688),p=t(9860)
|
|
623
623
|
a(t(9896)),a(t(6928))
|
|
624
|
-
var
|
|
625
|
-
Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return
|
|
626
|
-
const
|
|
624
|
+
var m=t(7280)
|
|
625
|
+
Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return m.logSessionIdentity}})
|
|
626
|
+
const g=t(7280)
|
|
627
627
|
t(2462)
|
|
628
628
|
const f=t(2245),y=t(8622),w=t(4466),b=(a(t(857)),t(1569))},1483(e,exports,t){"use strict"
|
|
629
629
|
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")
|
|
630
630
|
try{const o=e,{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,dateFrom:u,dateTo:h,searchIn:p}=o
|
|
631
631
|
i.info("Searching documents",{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,searchIn:p})
|
|
632
|
-
const
|
|
633
|
-
if(!
|
|
634
|
-
return i.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}n.setProjectId(
|
|
635
|
-
const
|
|
632
|
+
const m=t.projectId
|
|
633
|
+
if(!m){const e="Project ID is required. Make sure you are in a project context."
|
|
634
|
+
return i.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}n.setProjectId(m)
|
|
635
|
+
const g=n.getDocumentClient()
|
|
636
636
|
try{const e={limit:d||100,offset:0,sortBy:"updatedAt",sortDirection:"desc",searchQuery:s,includeArchived:l||!1}
|
|
637
637
|
a&&(e.type=a),c&&(e.requestId=c),i.debug("Fetching documents with filters",{filters:e})
|
|
638
|
-
let t=await
|
|
638
|
+
let t=await g.listDocuments(e)
|
|
639
639
|
if(u){const e=new Date(u)
|
|
640
640
|
t=t.filter((t=>new Date(t.createdAt)>=e))}if(h){const e=new Date(h)
|
|
641
641
|
t=t.filter((t=>new Date(t.createdAt)<=e))}i.info(`Fetched and filtered ${t.length} documents for search`)
|
|
@@ -949,10 +949,10 @@ const n=await r.json()
|
|
|
949
949
|
return n.success?n.data??null:null}catch{return null}}(c)
|
|
950
950
|
if(p=e?.requestContextMode,!p){const e=(0,C.getBuiltInAgentConfig)(c)
|
|
951
951
|
p=e?.requestContextMode}}catch{}if(p&&"none"!==p&&!d)return{content:[{type:"text",text:`\u274c Agent '${c}' requires a requestId to be provided.\n\nThis agent has requestContextMode: '${p}' which means it needs to work in the context of a specific request.\n\nPlease provide a requestId when spawning this agent.`}],isError:!0}
|
|
952
|
-
const
|
|
953
|
-
r(t,"serverUrl resolved",{serverUrl:
|
|
952
|
+
const m=await(0,y.getServerUrl)(t,s)
|
|
953
|
+
r(t,"serverUrl resolved",{serverUrl:m})
|
|
954
954
|
const k=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath
|
|
955
|
-
if(!k)throw new
|
|
955
|
+
if(!k)throw new g.ValidationError("Working directory not available in context")
|
|
956
956
|
const v=a?.sessionId
|
|
957
957
|
let E=""
|
|
958
958
|
if(i&&d)try{const e=i.getSessionRequestAssociationClient()
|
|
@@ -962,21 +962,21 @@ if(!u)return s.warn("Blocked spawn: request already has active workers",{request
|
|
|
962
962
|
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 q,T,x=l
|
|
963
963
|
d&&(q="requests/"+d,r(t,"Setting initialBranch for agent",{agent:c,requestId:d,initialBranch:q,agentRequestContextMode:p||"undefined"}),x="readonly"===p?`Working on request ${d} (READONLY mode - you cannot modify files, only explore and report).\n\n${l}`:`Working on request ${d}.\n\n${l}`)
|
|
964
964
|
let P,R=!1
|
|
965
|
-
if(h){if(T=h,s.info("Using existing session for spawn",{sessionId:T,requestId:d}),!
|
|
965
|
+
if(h){if(T=h,s.info("Using existing session for spawn",{sessionId:T,requestId:d}),!m)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
966
966
|
try{let e
|
|
967
967
|
try{const t=await fetch(`http://localhost:${S}/api/project-settings`)
|
|
968
968
|
if(t.ok){const r=await t.json()
|
|
969
969
|
if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
|
|
970
970
|
e={providerID:t,modelID:n.join("/")}}}}catch{}P=await o({apiClient:i,fromSessionId:a?.sessionId,toSessionId:T,body:x,requestId:d,logger:s})
|
|
971
|
-
const t=n(x,P),r=`${
|
|
971
|
+
const t=n(x,P),r=`${m.replace(/\/$/,"")}/session/${T}/prompt_async`,l={alchemy:{kind:"agent-delegation",payload:{body:x,fromSessionId:a?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...d?{requestId:d}:{},...P?{instructionCode:P}:{}}}},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)})
|
|
972
972
|
if(!u.ok){const e=await u.text().catch((()=>"Unknown error"))
|
|
973
973
|
throw Error(`Failed to send to existing session: ${u.status} ${e}`)}s.info("Prompt sent to existing session",{sessionId:T,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")
|
|
974
974
|
const h=v;(0,b.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:h})
|
|
975
|
-
try{const p=`http://localhost:${S}/api/spawn-session`,
|
|
976
|
-
if(!
|
|
977
|
-
throw Error(`Spawn session endpoint failed: ${
|
|
978
|
-
if(!
|
|
979
|
-
const{sessionId:y,model:b,serverUrl:I,initialBranch:v}=
|
|
975
|
+
try{const p=`http://localhost:${S}/api/spawn-session`,m=await fetch(p,{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)})
|
|
976
|
+
if(!m.ok){const e=await m.text().catch((()=>"Unknown error"))
|
|
977
|
+
throw Error(`Spawn session endpoint failed: ${m.status} ${e}`)}const g=await m.json()
|
|
978
|
+
if(!g.success||!g.data)throw Error(g.error||"Spawn session returned unsuccessful")
|
|
979
|
+
const{sessionId:y,model:b,serverUrl:I,initialBranch:v}=g.data
|
|
980
980
|
q=v,P=await o({apiClient:i,fromSessionId:a?.sessionId,toSessionId:y,body:x,requestId:d,logger:s})
|
|
981
981
|
const C=n(x,P),_=(0,f.spawnDetachedSubagent)({agent:c,prompt:C,cwd:k,sessionId:y,model:b,initialBranch:q,allowParallel:u,serverUrl:I})
|
|
982
982
|
if(!_.success)throw Error("Failed to spawn subagent: "+_.error)
|
|
@@ -992,21 +992,21 @@ o.warn("PATCH initial delegation failed",{sessionId:r,status:l.status,body:d.sli
|
|
|
992
992
|
M+=h?`Prompt sent to existing session ${T}.`:`Background ${c} subagent spawned successfully.`,d&&(M+="\nWorking on: "+d),P&&(M+=`\nInstruction code: ${P} (the specialist will cite this on their reports/questions via relatesTo)`),M+="\n\nThe subagent is now working independently. You can continue with other tasks.","coder"===c&&(M+="\n\nIf this work has shifted or expanded your area of expertise, update your specialization summary with `update_specialization`.")
|
|
993
993
|
const $=!!T&&"unknown"!==T&&"spawning"!==T
|
|
994
994
|
return{content:[{type:"text",text:M}],...(0,_.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:$?T:void 0,agentType:c,requestId:d||void 0,description:e.title||l.slice(0,50)||c,...P?{instructionCode:P}:{}}),...P?{instructionCode:P}:{}}}async function i(e,t,r,s,i,a,c){const l=await(0,y.getServerUrl)(r,s)
|
|
995
|
-
if(!l)throw new
|
|
995
|
+
if(!l)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
996
996
|
if(s.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),i)try{const t=c?.sessionId
|
|
997
997
|
if(t){const r=i.getCLISessionClient()
|
|
998
998
|
if(r){let n=await r.getByExternalId(t)
|
|
999
999
|
n||(n=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),s.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:n?.id})),n&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:n.id,status:"active"}),s.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){s.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,I.getErrorMessage)(e)})}let d=a
|
|
1000
1000
|
if(!d)try{const t=`http://localhost:${S}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
|
|
1001
1001
|
if(r.ok){const e=await r.json()
|
|
1002
|
-
e.success&&e.agentType&&(d=e.agentType)}}catch{s.warn("Agent type lookup failed for session",{sessionId:e})}if(!d)throw new
|
|
1002
|
+
e.success&&e.agentType&&(d=e.agentType)}}catch{s.warn("Agent type lookup failed for session",{sessionId:e})}if(!d)throw new g.ValidationError(`Cannot continue session ${e}: unable to determine agent type. The session's agent type could not be looked up from the action server.`)
|
|
1003
1003
|
try{let r
|
|
1004
1004
|
try{const e=await fetch(`http://localhost:${S}/api/project-settings`)
|
|
1005
1005
|
if(e.ok){const t=await e.json()
|
|
1006
1006
|
if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
|
|
1007
|
-
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`,p={alchemy:{kind:"agent-followup",payload:{body:t,fromSessionId:c?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...a?{instructionCode:a}:{}}}},
|
|
1008
|
-
if(!
|
|
1009
|
-
throw Error(`Failed to send message: ${
|
|
1007
|
+
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`,p={alchemy:{kind:"agent-followup",payload:{body:t,fromSessionId:c?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...a?{instructionCode:a}:{}}}},m=await fetch(h,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:u,metadata:p}],...d?{agent:d}:{},...r?{model:r}:{}}),signal:AbortSignal.timeout(1e4)})
|
|
1008
|
+
if(!m.ok){const e=await m.text().catch((()=>"Unknown error"))
|
|
1009
|
+
throw Error(`Failed to send message: ${m.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)
|
|
1010
1010
|
if(60>t)return t+"s"
|
|
1011
1011
|
const r=Math.floor(t/60)
|
|
1012
1012
|
return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function c(e){const t=[]
|
|
@@ -1020,16 +1020,16 @@ return e&&q>n?{status:"working",detail:"last action "+l(n),isReady:!1}:n>T&&e?{s
|
|
|
1020
1020
|
for(const o of e.trim().split("\n")){if(!o)continue
|
|
1021
1021
|
const[e,s]=o.split("\t")
|
|
1022
1022
|
"-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function h(e,r,n,o){const s=await(0,y.getServerUrl)(r,n)
|
|
1023
|
-
if(!s)throw new
|
|
1023
|
+
if(!s)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1024
1024
|
n.info("Checking status of subagent session",{sessionId:e})
|
|
1025
1025
|
try{const i=`${s.replace(/\/$/,"")}/session/${e}`,l=await fetch(i)
|
|
1026
1026
|
if(!l.ok)return{content:[{type:"text",text:`Session ${e} not found or has exited.`}],isError:!0}
|
|
1027
|
-
const h=await l.json(),p=`${s.replace(/\/$/,"")}/session/${e}/message`,
|
|
1028
|
-
let
|
|
1029
|
-
if(
|
|
1030
|
-
for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(
|
|
1027
|
+
const h=await l.json(),p=`${s.replace(/\/$/,"")}/session/${e}/message`,m=await fetch(p)
|
|
1028
|
+
let g={input:0,output:0,reasoning:0},f="",y=d(null,h.time.updated)
|
|
1029
|
+
if(m.ok){const e=await m.json()
|
|
1030
|
+
for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(g.input+=t.info.tokens.input||0,g.output+=t.info.tokens.output||0,g.reasoning+=t.info.tokens.reasoning||0)
|
|
1031
1031
|
const t=c(e)
|
|
1032
|
-
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=
|
|
1032
|
+
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=g.input+g.output+g.reasoning
|
|
1033
1033
|
let v="",C="",_=null
|
|
1034
1034
|
if(o)try{const t=o.getSessionRequestAssociationClient()
|
|
1035
1035
|
if(t){const r=await t.getActiveRequestsForSession(e,!1)
|
|
@@ -1044,38 +1044,38 @@ if(e.trim())return u(e)}try{const t=n(`git log main --merges --oneline -n 50 --g
|
|
|
1044
1044
|
if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
|
|
1045
1045
|
if(o.trim())return{...u(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
|
|
1046
1046
|
if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
|
|
1047
|
-
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: ${
|
|
1048
|
-
if(!n)throw new
|
|
1047
|
+
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: ${g.input.toLocaleString()}, out: ${g.output.toLocaleString()}${g.reasoning>0?", reasoning: "+g.reasoning.toLocaleString():""})${f}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,I.getErrorMessage)(e))}}async function p(e,t,r){const n=await(0,y.getServerUrl)(t,r)
|
|
1048
|
+
if(!n)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1049
1049
|
r.info("Aborting subagent session",{sessionId:e})
|
|
1050
1050
|
try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
|
|
1051
1051
|
if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
|
|
1052
|
-
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
|
|
1053
|
-
if(!p)throw new
|
|
1052
|
+
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 m(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:i,minTokens:l,maxTokens:u,maxAgeHours:h}=n,p=await(0,y.getServerUrl)(e,t)
|
|
1053
|
+
if(!p)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1054
1054
|
t.info("Listing sessions",{filters:n})
|
|
1055
1055
|
try{const e=p.replace(/\/$/,"")+"/session",t=await fetch(e)
|
|
1056
1056
|
if(!t.ok)throw Error("Failed to fetch sessions: "+t.status)
|
|
1057
|
-
let
|
|
1058
|
-
if(0===
|
|
1059
|
-
const m
|
|
1060
|
-
n.parentSessionId&&(
|
|
1057
|
+
let m=await t.json()
|
|
1058
|
+
if(0===m.length)return{content:[{type:"text",text:"No sessions found."}]}
|
|
1059
|
+
const g=m
|
|
1060
|
+
n.parentSessionId&&(m=m.filter((e=>(e.parentId||e.parentID)===n.parentSessionId))),m.sort(((e,t)=>t.time.created-e.time.created))
|
|
1061
1061
|
const f=p.replace(/\/$/,"")+"/session/status",y=await fetch(f),w=y.ok?await y.json():{}
|
|
1062
|
-
let b=
|
|
1062
|
+
let b=m
|
|
1063
1063
|
if(o&&(b=b.filter((e=>"idle"!==(w[e.id]?.type||"idle")))),void 0!==h){const e=36e5*h,t=Date.now()-e
|
|
1064
1064
|
b=b.filter((e=>e.time.created>=t))}if(0===b.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1065
1065
|
let I={}
|
|
1066
1066
|
const k=b.map((e=>e.id))
|
|
1067
1067
|
let v={},C=[]
|
|
1068
1068
|
if("specialist"===n.agentType){const e=new Set(k)
|
|
1069
|
-
for(const t of
|
|
1069
|
+
for(const t of g){const r=t.parentId||t.parentID
|
|
1070
1070
|
r&&e.has(r)&&(v[r]||(v[r]=[]),v[r].push(t.id),C.push(t.id))}}if(r)try{const e=r.getCLISessionClient()
|
|
1071
1071
|
if(e){const t=[...k,...C]
|
|
1072
1072
|
I=await e.batchEnrich(t)}}catch{}const _=p.replace(/\/$/,""),E=await Promise.allSettled(b.map((e=>fetch(`${_}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),S=[]
|
|
1073
1073
|
for(let e=0;e<b.length;e++){const t=b[e],r=Date.now()-t.time.created
|
|
1074
1074
|
let o=0,i=null,a=[],h=d(null,t.time.updated)
|
|
1075
|
-
const p=E[e],
|
|
1076
|
-
for(const e of
|
|
1077
|
-
if(
|
|
1078
|
-
h=d(e.lastActivityTime,t.time.updated),i=e.current||null,a=e.recent}const
|
|
1075
|
+
const p=E[e],m="fulfilled"===p.status?p.value:[]
|
|
1076
|
+
for(const e of m)"assistant"===e.info.role&&e.info.tokens&&(o+=(e.info.tokens.input||0)+(e.info.tokens.output||0)+(e.info.tokens.reasoning||0))
|
|
1077
|
+
if(m.length>0){const e=c(m)
|
|
1078
|
+
h=d(e.lastActivityTime,t.time.updated),i=e.current||null,a=e.recent}const g=h.status
|
|
1079
1079
|
if(void 0!==l&&l>o)continue
|
|
1080
1080
|
if(void 0!==u&&o>u)continue
|
|
1081
1081
|
const f=I[t.id]
|
|
@@ -1095,10 +1095,10 @@ const n=[]
|
|
|
1095
1095
|
if(t.length>0&&n.push("active: "+t.join(", ")),r.length>0){const e=5,t=r.slice(0,e),o=r.length-t.length
|
|
1096
1096
|
n.push(`prev: ${t.join(", ")}${o>0?` +${o} more`:""}`)}n.length>0&&(y=` [${n.join(" | ")}]`)}if(s&&!k.includes(s))continue
|
|
1097
1097
|
const q=t.title||"Untitled",T=q.length>50?q.slice(0,47)+"...":q
|
|
1098
|
-
S.push({id:t.id,title:T,status:
|
|
1098
|
+
S.push({id:t.id,title:T,status:g,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."}]}
|
|
1099
1099
|
const q=i?S.slice(0,i):S,T=q.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(", "):""
|
|
1100
1100
|
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}`})),x=i&&S.length>i?` (showing ${i} of ${S.length})`:""
|
|
1101
|
-
return{content:[{type:"text",text:`Found ${q.length} session${1!==q.length?"s":""}${x}:\n\n${T.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=p,exports.handleListSessions=
|
|
1101
|
+
return{content:[{type:"text",text:`Found ${q.length} session${1!==q.length?"s":""}${x}:\n\n${T.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=p,exports.handleListSessions=m,exports.handleSubagentOperations=async function(e,t,r,n,o,a){const c=r.child({tool:"subagent_operations"}),l=n.startTimer("tool_execution_time")
|
|
1102
1102
|
try{const r=e,{sessionId:d,operation:u}=r
|
|
1103
1103
|
let f
|
|
1104
1104
|
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)
|
|
@@ -1111,7 +1111,7 @@ case"abort":f=await p(d,t,c)
|
|
|
1111
1111
|
break
|
|
1112
1112
|
case"read-messages":const e=r.limit??1
|
|
1113
1113
|
f=await async function(e,t,r,n){const o=await(0,y.getServerUrl)(r,n)
|
|
1114
|
-
if(!o)throw new
|
|
1114
|
+
if(!o)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1115
1115
|
n.info("Reading messages from subagent session",{sessionId:e,limit:t})
|
|
1116
1116
|
try{const r=`${o.replace(/\/$/,"")}/session/${e}/message?limit=${t}`,n=await fetch(r)
|
|
1117
1117
|
if(!n.ok){if(404===n.status)return{content:[{type:"text",text:`Session ${e} not found.`}],isError:!0}
|
|
@@ -1122,12 +1122,12 @@ return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n$
|
|
|
1122
1122
|
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)
|
|
1123
1123
|
break
|
|
1124
1124
|
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}
|
|
1125
|
-
f=await
|
|
1125
|
+
f=await m(t,c,o,n)
|
|
1126
1126
|
break
|
|
1127
|
-
default:throw new
|
|
1127
|
+
default:throw new g.ValidationError("Unknown operation: "+u)}l({success:!0}),n.incrementCounter(`subagent_operations_${u}_success`,1)
|
|
1128
1128
|
const w=E[u]
|
|
1129
1129
|
return w?(0,_.withAlchemyKind)(f,w):f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,I.getErrorMessage)(e)}],isError:!0}}}
|
|
1130
|
-
const
|
|
1130
|
+
const g=t(9860),f=t(8035),y=t(7617),w=t(6688),b=t(7280),I=t(8824),k=t(9896),v=t(6928),C=t(8955),_=t(2272),E={spawn:"spawn-subagent",continue:"continue-subagent","check-status":"check-subagent-status",abort:"abort-subagent","read-messages":"read-subagent-messages","list-sessions":"list-subagent-sessions"},S=(0,t(9414).getActionServerPort)(),q=6e4,T=3e5},1791(e,exports,t){"use strict"
|
|
1131
1131
|
function r(e,t){return t.info("Creating project context middleware",{projectId:e}),(t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1132
1132
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
|
|
1133
1133
|
const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
|
|
@@ -1248,15 +1248,20 @@ try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.ge
|
|
|
1248
1248
|
if(p.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
|
|
1249
1249
|
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
|
|
1250
1250
|
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}
|
|
1251
|
-
const
|
|
1251
|
+
const m=[],{default:g}=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=g.join(h,y,"command-logs")
|
|
1252
|
+
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
|
|
1252
1253
|
for(const t of l){c.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:h})
|
|
1253
|
-
const r
|
|
1254
|
-
|
|
1254
|
+
const r=`${t.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,n=g.join(w,r+".log")
|
|
1255
|
+
let o=null
|
|
1256
|
+
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})
|
|
1257
|
+
o&&(o.write(`\n# exit: ${s.exitCode}${s.timedOut?" (timed out)":""}\n`),o.end())
|
|
1258
|
+
const i=(s.stdout+(s.stderr?"\n"+s.stderr:"")).trim().slice(-4e3)
|
|
1259
|
+
if(m.push({name:t.name,command:t.command,exitCode:s.exitCode,output:i,timedOut:s.timedOut}),"setup"===e.commandName&&0!==s.exitCode)break}const v=m.every((e=>0===e.exitCode)),C=m.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
|
|
1255
1260
|
return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\``})).join("\n\n")
|
|
1256
|
-
return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${
|
|
1261
|
+
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")
|
|
1257
1262
|
try{const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=await u.getSessionRequestId(i,a,l?.sessionId)
|
|
1258
1263
|
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}
|
|
1259
|
-
const p=await i.proxyGet(`/api/projects/${s.projectId}/requests/${h}/test-runs`),
|
|
1264
|
+
const p=await i.proxyGet(`/api/projects/${s.projectId}/requests/${h}/test-runs`),m=p?.data||p||[],g=Array.isArray(m)?m:[],f=g.find((e=>"pending"===e.status||"running"===e.status))||g[0]
|
|
1260
1265
|
if(!f)return d({success:!1,error:"no_test_run"}),{content:[{type:"text",text:`No test run found for request ${h}.`}],isError:!0}
|
|
1261
1266
|
const y=f.id
|
|
1262
1267
|
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)})))
|
|
@@ -1274,13 +1279,13 @@ try{const e=await i.proxyGet(`/api/projects/${n.projectId}/test-processes`),t=e?
|
|
|
1274
1279
|
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}
|
|
1275
1280
|
const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=l?.sessionId,p=h?await u.getSessionRequestId(i,a,h):void 0
|
|
1276
1281
|
if(!p)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}
|
|
1277
|
-
const
|
|
1278
|
-
try{const e=await fetch((0,o.getActionServerBaseUrl)()+"/api/run-tests-now",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:p,parentSessionId:h,commandNames:
|
|
1282
|
+
const m=e.name?[e.name]:void 0
|
|
1283
|
+
try{const e=await fetch((0,o.getActionServerBaseUrl)()+"/api/run-tests-now",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:p,parentSessionId:h,commandNames:m}),signal:AbortSignal.timeout(15e3)})
|
|
1279
1284
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
1280
1285
|
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()
|
|
1281
1286
|
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}
|
|
1282
|
-
const r=t.data.spawnedSessionIds?.[0],n=
|
|
1283
|
-
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:p,description:
|
|
1287
|
+
const r=t.data.spawnedSessionIds?.[0],n=m?` (filtered to: ${m.join(", ")})`:""
|
|
1288
|
+
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:p,description:m?"Test run: "+m.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:[]
|
|
1284
1289
|
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
|
|
1285
1290
|
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)})
|
|
1286
1291
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
@@ -1328,13 +1333,13 @@ if("user"===r.info?.role)for(const e of r.parts??[]){if("text"!==e.type||!e.text
|
|
|
1328
1333
|
const t=e.text.match(/<viewed_session\s+id="([^"]+)"\s*\/?>/)
|
|
1329
1334
|
if(t)return t[1]}}return null}(h)
|
|
1330
1335
|
if(!p)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}
|
|
1331
|
-
let
|
|
1332
|
-
try{
|
|
1333
|
-
if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,p)),
|
|
1334
|
-
|
|
1335
|
-
try{const e=await fetch(`${u}/session/${p}/prompt_async`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(
|
|
1336
|
+
let m
|
|
1337
|
+
try{m=function(e){for(let t=e.length-1;t>=0;t--){const r=e[t]
|
|
1338
|
+
if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,p)),m||t.warn("commit_to_viewed_session: no agent resolvable for viewed session; omitting agent",{viewedId:p})}catch(e){t.warn("commit_to_viewed_session: could not fetch viewed messages; omitting agent",{viewedId:p,error:(0,n.getErrorMessage)(e)})}const g={parts:[{type:"text",text:c,metadata:(0,s.partMeta)("via-herald")}]}
|
|
1339
|
+
m&&(g.agent=m),t.info("commit_to_viewed_session:posting",{callId:i,viewedId:p,heraldId:d,agent:m})
|
|
1340
|
+
try{const e=await fetch(`${u}/session/${p}/prompt_async`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(g),signal:AbortSignal.timeout(1e4)})
|
|
1336
1341
|
if(t.info("commit_to_viewed_session:posted",{callId:i,status:e.status}),!e.ok){const t=await e.text().catch((()=>""))
|
|
1337
|
-
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:p,agent:
|
|
1342
|
+
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:p,agent:m,messageLength:c.length,preview:c.slice(0,120),durationMs:Date.now()-a}),{content:[{type:"text",text:"Committed."}]}}
|
|
1338
1343
|
const n=t(8824),o=t(6688),s=t(2272)},2141(e,exports,t){"use strict"
|
|
1339
1344
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConflictResolver=void 0,exports.createConflictResolver=function(e){return new n(e)}
|
|
1340
1345
|
const r=t(8824)
|
|
@@ -1410,29 +1415,29 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
1410
1415
|
var t={}
|
|
1411
1416
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
1412
1417
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1413
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,r,n,o,s,i,g
|
|
1418
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,r,n,o,s,i,m,g){const f=i.child({tool:"move_files"}),y=Date.now()
|
|
1414
1419
|
let w,b,I=l.FileOperationPhase.VALIDATION
|
|
1415
1420
|
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"}
|
|
1416
1421
|
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)
|
|
1417
1422
|
if("errorResult"in _)return _.errorResult
|
|
1418
1423
|
const{taskId:E}=_
|
|
1419
1424
|
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")
|
|
1420
|
-
l.validateTaskIdFormat(E,f,
|
|
1425
|
+
l.validateTaskIdFormat(E,f,m,k.metricsPrefix)
|
|
1421
1426
|
const S=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1422
1427
|
f.info("Initial branch context",{initialBranch:S.branch,initialRequestId:S.requestId,isMain:S.isMain})
|
|
1423
1428
|
const q=[]
|
|
1424
1429
|
for(const e of u){const{normalizedPath:t,fullPath:n}=l.validateAndNormalizePath(e.source,r),{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(e.destination,r)
|
|
1425
|
-
q.push({source:t,destination:o,fullSource:n,fullDestination:s})}I=l.FileOperationPhase.TASK_VALIDATION,
|
|
1426
|
-
const T=await l.validateTaskId(E,q[0].source,n,f,
|
|
1430
|
+
q.push({source:t,destination:o,fullSource:n,fullDestination:s})}I=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("move_files_phase",1,{phase:I})
|
|
1431
|
+
const T=await l.validateTaskId(E,q[0].source,n,f,m,k.metricsPrefix),x=T?.requestId,P=await l.validateWorkItemStates(E,q[0].source,n,s,r,f,m,k.metricsPrefix),R=await l.autoPromoteTaskStatus(E,T.status,x,P.request?.status,q[0].source,n,s,f,m,k.metricsPrefix)
|
|
1427
1432
|
R.taskPromoted&&f.info(`Auto-promoted task ${E} (${T.title||"Untitled"}) to in_progress for file operations`,{taskId:E,taskTitle:T.title,previousStatus:T.status,newStatus:R.newTaskStatus,operationCount:u.length}),R.requestPromoted&&f.info(`Auto-promoted request ${x} to in_progress for file operations`,{requestId:x,previousStatus:P.request?.status,newStatus:R.newRequestStatus,triggeringTaskId:E})
|
|
1428
|
-
const M=await l.ensureCorrectWorkspaceContext({taskPromoted:R.taskPromoted,requestId:x,context:r,operation:"move-files",logger:f,metrics:
|
|
1433
|
+
const M=await l.ensureCorrectWorkspaceContext({taskPromoted:R.taskPromoted,requestId:x,context:r,operation:"move-files",logger:f,metrics:m,metricsPrefix:k.metricsPrefix})
|
|
1429
1434
|
if(!M.success)throw Error(M.error)
|
|
1430
1435
|
let $={hadUserMods:!1,userModsCommitHash:void 0}
|
|
1431
1436
|
if(r.git)try{f.debug("[MOVE-FILES] Checking for user changes before move operations")
|
|
1432
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:x,taskId:E,workspaceManager:r.workspaceManager},f,
|
|
1433
|
-
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:q.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),$={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:q.length,error:e instanceof Error?e.message:e+""})}f.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:q.length}),I=l.FileOperationPhase.RECORD_CREATION,
|
|
1434
|
-
const{toolRecordId:j,localToolRecordId:O}=await l.createFileOperationRecords(E,x,r.projectId,k.recordType,q[0].source,{operationCount:u.length,operations:q.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:$.hadUserMods,userModsCommitHash:$.userModsCommitHash},n,o,f,
|
|
1435
|
-
w=j,b=j,I=k.fileOperationPhase,
|
|
1437
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:x,taskId:E,workspaceManager:r.workspaceManager},f,m)
|
|
1438
|
+
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:q.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),$={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:q.length,error:e instanceof Error?e.message:e+""})}f.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:q.length}),I=l.FileOperationPhase.RECORD_CREATION,m.incrementCounter("move_files_phase",1,{phase:I})
|
|
1439
|
+
const{toolRecordId:j,localToolRecordId:O}=await l.createFileOperationRecords(E,x,r.projectId,k.recordType,q[0].source,{operationCount:u.length,operations:q.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:$.hadUserMods,userModsCommitHash:$.userModsCommitHash},n,o,f,m,k.metricsPrefix,g)
|
|
1440
|
+
w=j,b=j,I=k.fileOperationPhase,m.incrementCounter("move_files_phase",1,{phase:I})
|
|
1436
1441
|
const D=[]
|
|
1437
1442
|
let A=0
|
|
1438
1443
|
for(const e of q){const t={operation:{source:e.source,destination:e.destination},success:!1}
|
|
@@ -1440,13 +1445,13 @@ try{try{await a.default.access(e.fullSource)}catch(t){throw Error("Source path n
|
|
|
1440
1445
|
t.isDirectory=r
|
|
1441
1446
|
const n=c.default.dirname(e.fullDestination)
|
|
1442
1447
|
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,p.getErrorMessage)(r),f.warn(`Failed to move ${e.source} to ${e.destination}`,{error:t.error})}D.push(t)}const F=Date.now()-y
|
|
1443
|
-
|
|
1448
|
+
m.recordValue("move_files_time",F),m.incrementCounter("move_files_operations_total",u.length),m.incrementCounter("move_files_operations_success",A),m.incrementCounter("move_files_operations_failed",u.length-A),A===u.length?m.incrementCounter("move_files_success",1):A>0?m.incrementCounter("move_files_partial_success",1):m.incrementCounter("move_files_total_failure",1)
|
|
1444
1449
|
let N=null
|
|
1445
|
-
if(A>0){I=l.FileOperationPhase.GIT_COMMIT,
|
|
1450
|
+
if(A>0){I=l.FileOperationPhase.GIT_COMMIT,m.incrementCounter("move_files_phase",1,{phase:I})
|
|
1446
1451
|
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}`
|
|
1447
|
-
N=await l.commitToGit(E,q[0].destination,j,O,t,r,f,
|
|
1452
|
+
N=await l.commitToGit(E,q[0].destination,j,O,t,r,f,m,k.metricsPrefix)}I=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,m.incrementCounter("move_files_phase",1,{phase:I})
|
|
1448
1453
|
const z=D.filter((e=>e.success)),L=D.filter((e=>!e.success))
|
|
1449
|
-
await l.updateFileOperationRecords(E,w,b,q[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:$.hadUserMods,userModsCommitHash:$.userModsCommitHash},A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,n,o,f,
|
|
1454
|
+
await l.updateFileOperationRecords(E,w,b,q[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:$.hadUserMods,userModsCommitHash:$.userModsCommitHash},A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,n,o,f,m,k.metricsPrefix)
|
|
1450
1455
|
const H=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1451
1456
|
let B=""
|
|
1452
1457
|
if(A===u.length)B=`Successfully moved all ${u.length} ${1===u.length?"item":"items"}`
|
|
@@ -1454,8 +1459,8 @@ else if(A>0){const e=D.filter((e=>!e.success))
|
|
|
1454
1459
|
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")
|
|
1455
1460
|
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
|
|
1456
1461
|
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,p.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:I,attemptedTaskId:e.taskId,taskIdValidationFailed:n},note:"Failed to move files - "+(0,p.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
|
|
1457
|
-
if(
|
|
1458
|
-
try{await l.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",k.recordType,"Failed to move files",{status:"failed",error:(0,p.getErrorMessage)(t),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",n,o,f,
|
|
1462
|
+
if(m.recordValue("move_files_time",s),m.incrementCounter("move_files_errors",1),f.error("Error in move-files operation:",{error:(0,p.getErrorMessage)(t),time:s}),(w||b)&&e.taskId){I=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
1463
|
+
try{await l.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",k.recordType,"Failed to move files",{status:"failed",error:(0,p.getErrorMessage)(t),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",n,o,f,m,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,m,e,k)}}
|
|
1459
1464
|
const a=i(t(1943)),c=i(t(6928)),l=s(t(5967)),d=t(9860),u=t(1569),h=t(7478),p=t(8824)},2422(module){"use strict"
|
|
1460
1465
|
module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){"use strict"
|
|
1461
1466
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
@@ -1464,7 +1469,7 @@ exports.def={name:"quick_manage",description:"WHEN TO USE: trivial single-file e
|
|
|
1464
1469
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildTaskEndpoint=function(e,t,r){const n=r?"/"+r.replace(/^\//,""):""
|
|
1465
1470
|
return`/api/projects/${e}/tasks/${encodeURIComponent(t)}${n}`}},2462(e,exports,t){"use strict"
|
|
1466
1471
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
1467
|
-
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),p=t(5459),
|
|
1472
|
+
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),p=t(5459),m=t(4805),g=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),q=t(6309),T=t(4921),x=t(8850),P=t(3556),R=t(1391),M=t(6315),$=t(7713),j=t(6252),O=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)(p.def),(0,r.registerTool)(m.def),(0,r.registerTool)(g.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)(q.def),(0,r.registerTool)(T.def),(0,r.registerTool)(x.def),(0,r.registerTool)(P.def),(0,r.registerTool)(R.def),(0,r.registerTool)(M.def),(0,r.registerTool)($.def),(0,r.registerTool)(j.def),(0,r.registerTool)(O.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"
|
|
1468
1473
|
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"
|
|
1469
1474
|
async function r(e,t,r){if(v.has(r)&&C>=t){if(0===t)return 0
|
|
1470
1475
|
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]"
|
|
@@ -1489,10 +1494,10 @@ let t=e,r=0
|
|
|
1489
1494
|
for(;t>=1024&&4>r;)t/=1024,r++
|
|
1490
1495
|
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[]
|
|
1491
1496
|
try{const{fullPath:d}=b.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),p=[]
|
|
1492
|
-
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=b.validateAndNormalizePath(u,t),
|
|
1497
|
+
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=b.validateAndNormalizePath(u,t),m=await y.default.stat(h),g=d.isFile()?w.default.extname(d.name).toLowerCase():""
|
|
1493
1498
|
let f
|
|
1494
|
-
d.isFile()&&(f=await r(h,
|
|
1495
|
-
const I={name:d.name,isDirectory:d.isDirectory(),depth:n,size:
|
|
1499
|
+
d.isFile()&&(f=await r(h,m.size,g))
|
|
1500
|
+
const I={name:d.name,isDirectory:d.isDirectory(),depth:n,size:m.size,modified:m.mtime,extension:g,lineCount:f}
|
|
1496
1501
|
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)),p.push(I)}catch(e){l.debug("Excluding entry from tree: "+d.name,{reason:(0,k.getErrorMessage)(e)})}return u(p,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""
|
|
1497
1502
|
const o=[]
|
|
1498
1503
|
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?"/":""
|
|
@@ -1518,21 +1523,21 @@ case"type":const o=e.extension||"",s=r.extension||""
|
|
|
1518
1523
|
return o!==s?o.localeCompare(s):e.name.localeCompare(r.name)
|
|
1519
1524
|
default:return e.name.localeCompare(r.name)}}))}var h,p=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1520
1525
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1521
|
-
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]}),
|
|
1526
|
+
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),m=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),g=this&&this.__importStar||(h=function(e){return h=Object.getOwnPropertyNames||function(e){var t=[]
|
|
1522
1527
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
1523
1528
|
return t},h(e)},function(e){if(e&&e.__esModule)return e
|
|
1524
1529
|
var t={}
|
|
1525
1530
|
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&p(t,e,r[n])
|
|
1526
|
-
return
|
|
1531
|
+
return m(t,e),t}),f=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1527
1532
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
|
|
1528
1533
|
let p=b.FileOperationPhase.VALIDATION
|
|
1529
1534
|
b.FileOperationPhase.FILE_WRITE
|
|
1530
|
-
try{const
|
|
1531
|
-
i.info("Listing directory: "+
|
|
1532
|
-
const{normalizedPath:v,fullPath:C}=b.validateAndNormalizePath(
|
|
1535
|
+
try{const m=e,{path:g,levels:f=1,sortBy:I="name"}=m
|
|
1536
|
+
i.info("Listing directory: "+g)
|
|
1537
|
+
const{normalizedPath:v,fullPath:C}=b.validateAndNormalizePath(g,t)
|
|
1533
1538
|
p=b.FileOperationPhase.FILE_WRITE
|
|
1534
|
-
try{if(!(await y.default.stat(C)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+
|
|
1535
|
-
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: "+
|
|
1539
|
+
try{if(!(await y.default.stat(C)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+g}],isError:!0}
|
|
1540
|
+
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: "+g}],isError:!0}:e instanceof Error&&"EACCES"===e.code?{content:[{type:"text",text:"Directory not accessible: "+g}],isError:!0}:{content:[{type:"text",text:"Cannot access directory: "+g}],isError:!0}}let _,E
|
|
1536
1541
|
if(f>1){i.info(`Building tree structure for: ${v} (levels: ${f}, sortBy: ${I})`)
|
|
1537
1542
|
const e=await o(v,t,0,f,I,i)
|
|
1538
1543
|
if(e.length>0){const t=s(e,I)
|
|
@@ -1545,7 +1550,7 @@ _+="\n\nBranch: "+(S?.branchName||"unknown")
|
|
|
1545
1550
|
const q=Date.now()-h
|
|
1546
1551
|
return a.recordValue("list_directory_time",q),a.recordValue("list_directory_entries",E),a.incrementCounter("list_directory_success",1),i.info("Successfully listed directory: "+v,{entryCount:E,levels:f,time:q}),{content:[{type:"text",text:_}]}}catch(e){const t=Date.now()-h
|
|
1547
1552
|
return a.recordValue("list_directory_time",t),a.incrementCounter("list_directory_errors",1),i.error("Error listing directory:",{error:(0,k.getErrorMessage)(e),time:t}),{content:[{type:"text",text:(0,k.getErrorMessage)(e)}],isError:!0}}}
|
|
1548
|
-
const y=f(t(1943)),w=f(t(6928)),b=
|
|
1553
|
+
const y=f(t(1943)),w=f(t(6928)),b=g(t(5967)),I=t(3253),k=t(8824),v=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore",".config",".conf",".ini",".cfg"]),C=1048576},2690(e,exports,t){"use strict"
|
|
1549
1554
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SessionMessageClient=void 0
|
|
1550
1555
|
const r=t(7645),n=t(2161)
|
|
1551
1556
|
class o extends r.ConnectionAwareClient{constructor(e,t,r,n,o,s,i){const a=t.child({component:"session-message-client"}),c=s||{isInOfflineMode(){return!1},isOffline(){return!1},setOfflineMode(){},async checkConnectivity(){return!0},getHealthCheckStats(){return{isOffline:!1,consecutiveFailures:0,currentBackoffMs:0,lastCheckTime:0}},cleanup(){}}
|
|
@@ -1599,11 +1604,11 @@ const t=await this.requestWithRetry("POST",`/api/projects/${e}/session-messages/
|
|
|
1599
1604
|
return(0,n.safeGetResponseData)(t,{expiredCount:0},this.logger).expiredCount}}exports.SessionMessageClient=o},2736(e,exports,t){"use strict"
|
|
1600
1605
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,l,d,u,h){const p=u.child({tool:"complete_task"})
|
|
1601
1606
|
p.info("Completing task",{args:e})
|
|
1602
|
-
const
|
|
1607
|
+
const m=h.startTimer("tool_handler_duration")
|
|
1603
1608
|
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)
|
|
1604
1609
|
throw new r.ValidationError("Invalid input: "+(0,a.getErrorMessage)(e))}}(e)
|
|
1605
1610
|
let u=o.taskId
|
|
1606
|
-
const
|
|
1611
|
+
const g=o.summary;(0,c.isTaskRef)(u)&&(u=await(0,c.resolveTaskRef)(u,d,p))
|
|
1607
1612
|
const f=l.projectId
|
|
1608
1613
|
if(!f)throw new r.ValidationError("Project ID is required for completing tasks with the new API structure")
|
|
1609
1614
|
h.incrementCounter("complete_task_attempts",1,{taskId:u}),d.setProjectId(f)
|
|
@@ -1619,18 +1624,18 @@ throw p.warn(e,{taskId:u,currentStatus:w.status}),new r.ValidationError(e)}let b
|
|
|
1619
1624
|
if(l.workspaceManager){const e=l.workspaceManager.getCurrentContext(l.currentSessionId)
|
|
1620
1625
|
if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
|
|
1621
1626
|
b=simpleGit({baseDir:e.basePath,binary:l.gitBinary}),p.debug("Using workspace-aware git instance for task completion",{taskId:u,mode:e.mode,requestId:e.requestId,basePath:e.basePath})}}let I=null
|
|
1622
|
-
if(b)try{(await b.status()).isClean()||(I=(await b.commit(`Complete task ${u}: ${
|
|
1627
|
+
if(b)try{(await b.status()).isClean()||(I=(await b.commit(`Complete task ${u}: ${g}`)).commit,p.info("Created commit for task completion",{taskId:u,commitId:I}))}catch(e){p.warn("Failed to commit changes",{error:(0,a.getErrorMessage)(e)})}let k=null
|
|
1623
1628
|
try{const e=d.getToolRecordClient()
|
|
1624
|
-
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:
|
|
1629
|
+
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:g,lastCommit:I,completedAt:(new Date).toISOString()},note:`Completed task: ${g.substring(0,100)}${g.length>100?"...":""}`})).id})}catch(e){p.error("Failed to create tool record for task completion, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:u,requestId:w.requestId})}try{const e=w.metadata||{},t=(new Date).toISOString(),r={status:"completed",metadata:{...e,lastCommit:I,completionSummary:g,completionRecordId:k?.id,completedAt:t}},o=await y.updateTask(u,r)
|
|
1625
1630
|
p.info("Raw task update response data",{responseData:JSON.stringify(o)}),p.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:p,operationName:"updateTask",defaultValue:{id:u,status:"completed"}}),p.info("Successfully completed task",{taskId:u,recordId:k?.id})
|
|
1626
1631
|
const i=w.requestId,l=w.requestId
|
|
1627
1632
|
let d=`Task ${w.sequenceNumber&&l?(0,c.formatTaskRef)(l,w.sequenceNumber):u} (${w.title}) has been marked as completed.`
|
|
1628
1633
|
if(I&&(d+="\nCommit: "+I.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
|
|
1629
1634
|
p.info("Raw tasks list response data",{responseData:JSON.stringify(e)}),p.debug("Tasks list response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
|
|
1630
1635
|
const t=(0,s.extractArrayFromResponse)(e,{logger:p,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
|
|
1631
|
-
p.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){p.warn("Failed to check task progress",{error:(0,a.getErrorMessage)(e),requestId:i})}return
|
|
1636
|
+
p.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){p.warn("Failed to check task progress",{error:(0,a.getErrorMessage)(e),requestId:i})}return m({success:!0}),{content:[{type:"text",text:d}],...(0,n.alchemyMeta)({kind:"complete-task",toolRecordId:k?.id})}}catch(e){throw p.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(p.error("Failed to complete task",{error:t instanceof Error?t.stack:t+"",args:e}),l.projectId)try{const n=d.getToolRecordClient()
|
|
1632
1637
|
if(n){const o=t instanceof r.NotFoundError||t instanceof r.ValidationError||t instanceof i.ZodError
|
|
1633
|
-
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){p.error("Failed to create failure record for task completion",{error:e instanceof Error?e.message:e+""})}
|
|
1638
|
+
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){p.error("Failed to create failure record for task completion",{error:e instanceof Error?e.message:e+""})}m({success:!1,error:t instanceof Error?t.name:"unknown"})
|
|
1634
1639
|
let n=(0,a.getErrorMessage)(t)
|
|
1635
1640
|
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}}}
|
|
1636
1641
|
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"
|
|
@@ -1639,12 +1644,12 @@ if(!r())return t.level=(0,l.isDevBuild)()?c.LogLevel.INFO:c.LogLevel.ERROR,t.log
|
|
|
1639
1644
|
if("true"===process.env.DEBUG_LOGGING?.toLowerCase()){t.level=c.LogLevel.DEBUG,t.logToFile=!0
|
|
1640
1645
|
const r=e||process.cwd()
|
|
1641
1646
|
t.logFilePath=i.default.join(r,"logs","debug.log")}const n=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
1642
|
-
return n&&Object.values(c.LogLevel).includes(n)&&(t.level=n),t}(e.baseDir),...e},{level:o=c.LogLevel.INFO,serviceName:p="mcp-service",logToFile:
|
|
1643
|
-
if(console&&f.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),
|
|
1644
|
-
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(
|
|
1647
|
+
return n&&Object.values(c.LogLevel).includes(n)&&(t.level=n),t}(e.baseDir),...e},{level:o=c.LogLevel.INFO,serviceName:p="mcp-service",logToFile:m=!1,logFilePath:g="./logs/app.log",console=!0}=t,f=[]
|
|
1648
|
+
if(console&&f.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),m){!function(e){const t=i.default.dirname(e)
|
|
1649
|
+
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(g)
|
|
1645
1650
|
const e=o===c.LogLevel.DEBUG&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()
|
|
1646
|
-
f.push(new s.default.transports.File({filename:
|
|
1647
|
-
return o===c.LogLevel.DEBUG&&
|
|
1651
|
+
f.push(new s.default.transports.File({filename:g,format:e?h:u}))}const y=s.default.createLogger({level:o,defaultMeta:{service:p},transports:f})
|
|
1652
|
+
return o===c.LogLevel.DEBUG&&m&&r()&&y.info("Enhanced logging initialized",{level:o,serviceName:p,logToFile:m,logFilePath:g,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)
|
|
1648
1653
|
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:`${p}:${e.component||"nested"}`})}}}}}var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1649
1654
|
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
|
|
1650
1655
|
const e=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
@@ -1702,13 +1707,13 @@ i.info("Request breakdown",{fileRequests:d.length,documentRequests:u.length})
|
|
|
1702
1707
|
const h=[]
|
|
1703
1708
|
for(const e of d)h.push(r(e,t,0,l))
|
|
1704
1709
|
for(const e of u)h.push(n(e,t,0,l))
|
|
1705
|
-
const
|
|
1706
|
-
let
|
|
1710
|
+
const m=await Promise.all(h)
|
|
1711
|
+
let g=""
|
|
1707
1712
|
if(t.workspaceManager)try{const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
1708
|
-
e.branchName&&!e.permanentBranch&&(
|
|
1713
|
+
e.branchName&&!e.permanentBranch&&(g=`**Current Branch:** ${e.branchName}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const f=m.filter((e=>e.success)).length,y=m.filter((e=>!e.success)).length,w=m.length
|
|
1709
1714
|
let b="## Read Files/Documents\n\n"
|
|
1710
|
-
|
|
1711
|
-
for(let e=0;e<
|
|
1715
|
+
g&&(b+=g),b+=`**Total Requests:** ${w} - **Successful:** ${f} - **Failed:** ${y}\n\n`
|
|
1716
|
+
for(let e=0;e<m.length;e++){const t=m[e]
|
|
1712
1717
|
"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
|
|
1713
1718
|
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,p.alchemyMeta)({kind:"read-files"}),isError:!I}}catch(e){const t=Date.now()-a
|
|
1714
1719
|
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}}}
|
|
@@ -1790,9 +1795,9 @@ throw c.error(`STRICT VALIDATION - File operation blocked on ${u.status} request
|
|
|
1790
1795
|
const n=(0,s.getErrorMessage)(r)
|
|
1791
1796
|
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
|
|
1792
1797
|
const n=(0,s.getErrorMessage)(r)
|
|
1793
|
-
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,p=!1,
|
|
1798
|
+
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,p=!1,m=!1
|
|
1794
1799
|
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),p=!0,s="in_progress",r&&o)){const t=await n(r,o,e,"in_progress",c,l,d,u)
|
|
1795
|
-
|
|
1800
|
+
m=t.promoted,h=t.newStatus}return{taskPromoted:p,newTaskStatus:s,requestPromoted:m,newRequestStatus:h}}catch(r){const n=(0,s.getErrorMessage)(r)
|
|
1796
1801
|
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})
|
|
1797
1802
|
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})
|
|
1798
1803
|
const t=`Cannot complete request ${e} - no tasks found. Create tasks for this request before attempting completion.`
|
|
@@ -1819,7 +1824,7 @@ l.info("Generating journal for request",{requestId:a})
|
|
|
1819
1824
|
const u=t.projectId
|
|
1820
1825
|
if(!u)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
|
|
1821
1826
|
o.setProjectId(u),l.info("Fetching request data, tasks, and file history in parallel")
|
|
1822
|
-
const h=o.getRequestClient(),p=o.getTaskClient(),
|
|
1827
|
+
const h=o.getRequestClient(),p=o.getTaskClient(),m=o.getToolRecordClient(),[g,f,y]=await Promise.all([h.getRequest(a),p.listTasks({requestId:a}),m.getToolRecordsByRequestId(a).catch((e=>(l.warn("Failed to fetch tool records",{error:e+""}),[])))]),w=(0,s.extractDataFromResponse)(g,{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})))
|
|
1823
1828
|
l.info(`Fetched request, ${v.length} tasks, ${y.length} tool records`)
|
|
1824
1829
|
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()))
|
|
1825
1830
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
@@ -1832,7 +1837,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentWorkspa
|
|
|
1832
1837
|
const r=t(7636)
|
|
1833
1838
|
Object.defineProperty(exports,"MultiAgentWorkspaceManager",{enumerable:!0,get(){return r.MultiAgentWorkspaceManager}})},3247(e,exports,t){"use strict"
|
|
1834
1839
|
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))
|
|
1835
|
-
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,p){const
|
|
1840
|
+
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,p){const m=u.child({tool:"tasks"}),{operation:g}=e
|
|
1836
1841
|
try{const h=t.projectId
|
|
1837
1842
|
if(!h)throw Error("Project ID not available")
|
|
1838
1843
|
d.setProjectId(h)
|
|
@@ -1841,13 +1846,13 @@ if(!o||"__unknown__"===o||"__server__"===o)throw Error("Cannot resolve request:
|
|
|
1841
1846
|
const i=await s.sessionIdentity.getSessionRequestId(t,r,o)
|
|
1842
1847
|
if(!i)throw Error("No request associated with session "+o)
|
|
1843
1848
|
return i}(t,d,u,p)
|
|
1844
|
-
switch(
|
|
1849
|
+
switch(g){case"create":{const{title:t,description:r}=e
|
|
1845
1850
|
if(!t)return{content:[{type:"text",text:"Error: title is required for create"}],isError:!0}
|
|
1846
1851
|
if(!r)return{content:[{type:"text",text:"Error: description is required for create"}],isError:!0}
|
|
1847
1852
|
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
|
|
1848
1853
|
let p=!1
|
|
1849
|
-
if(!s)try{await n.updateTaskStatus(u,"in_progress"),p=!0}catch(e){
|
|
1850
|
-
let y=
|
|
1854
|
+
if(!s)try{await n.updateTaskStatus(u,"in_progress"),p=!0}catch(e){m.debug("Could not auto-start task",{taskId:u,error:(0,i.getErrorMessage)(e)})}const g=a.sequenceNumber??null
|
|
1855
|
+
let y=g?`Created #${g}: ${t}`:`Created ${(0,l.formatTaskRefForAgent)(u)}: ${t}`
|
|
1851
1856
|
return p&&(y+=" (started)"),{content:[{type:"text",text:y}],...(0,c.alchemyMeta)({kind:"create-task",taskId:u,requestId:f})}}case"done":{const{summary:t}=e
|
|
1852
1857
|
if(!t)return{content:[{type:"text",text:"Error: summary is required for done"}],isError:!0}
|
|
1853
1858
|
const{active:r,nextPending:n}=await o(d,f)
|
|
@@ -1858,7 +1863,7 @@ const u=r.sequenceNumber
|
|
|
1858
1863
|
let h=u?`Completed #${u}: ${r.title}`:`Completed ${(0,l.formatTaskRefForAgent)(r.taskId)}: ${r.title}`
|
|
1859
1864
|
if(n)try{await s.updateTaskStatus(n.taskId,"in_progress")
|
|
1860
1865
|
const e=n.sequenceNumber
|
|
1861
|
-
h+=e?`\nStarted #${e}: ${n.title}`:`\nStarted ${(0,l.formatTaskRefForAgent)(n.taskId)}: ${n.title}`}catch(e){
|
|
1866
|
+
h+=e?`\nStarted #${e}: ${n.title}`:`\nStarted ${(0,l.formatTaskRefForAgent)(n.taskId)}: ${n.title}`}catch(e){m.debug("Could not auto-start next task",{taskId:n.taskId,error:(0,i.getErrorMessage)(e)})}else h+="\nAll tasks completed."
|
|
1862
1867
|
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))
|
|
1863
1868
|
if(o){const e=r(o)
|
|
1864
1869
|
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
|
|
@@ -1873,7 +1878,7 @@ l&&await o.updateTaskStatus(l.localId||l.id,"pending"),await o.updateTaskStatus(
|
|
|
1873
1878
|
const u=r(i),h=l?` (paused ${n(r(l))}: ${l.title})`:""
|
|
1874
1879
|
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"})
|
|
1875
1880
|
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
|
|
1876
|
-
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: "+
|
|
1881
|
+
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: "+g}],isError:!0}}}catch(e){return m.error("tasks operation failed",{operation:g,error:(0,i.getErrorMessage)(e)}),{content:[{type:"text",text:"Error: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
|
|
1877
1882
|
const s=t(6688),i=t(8824),a=t(3451),c=t(2272),l=t(4466)},3253(e,exports){"use strict"
|
|
1878
1883
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTimestamp=function(e,t){const r=e instanceof Date?e:new Date(e)
|
|
1879
1884
|
if(isNaN(r.getTime()))return"Invalid date"
|
|
@@ -1927,7 +1932,7 @@ if(0===a)throw Error(`String "${s}" not found`)
|
|
|
1927
1932
|
if(a>1)throw Error(`String "${s}" appears ${a} times (expected exactly 1 in unique mode)`)
|
|
1928
1933
|
o=o.replace(s,i),t.success=!0,t.occurrences=1}else{const e=(o.match(RegExp(r(s),"g"))||[]).length
|
|
1929
1934
|
if(0===e)throw Error(`String "${s}" not found`)
|
|
1930
|
-
o=o.replace(RegExp(r(s),"g"),i),t.success=!0,t.occurrences=e}}catch(e){t.error=(0,
|
|
1935
|
+
o=o.replace(RegExp(r(s),"g"),i),t.success=!0,t.occurrences=e}}catch(e){t.error=(0,g.getErrorMessage)(e)}s.push(t)}return{newContent:o,results:s}}var o,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1931
1936
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1932
1937
|
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=[]
|
|
1933
1938
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -1950,7 +1955,7 @@ R.push({type:"file",path:t,fullPath:n,replacements:e.replacements,mode:e.mode||"
|
|
|
1950
1955
|
if(P.length>0&&!r.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
1951
1956
|
for(const e of P)M.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
|
|
1952
1957
|
if(M.length>0&&r.apiClient){const e=M.map((e=>e.documentId))
|
|
1953
|
-
try{await(0,
|
|
1958
|
+
try{await(0,m.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}
|
|
1954
1959
|
throw e}}k=d.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
1955
1960
|
const $=R.length>0?R[0].path:"document-operation",j=await d.validateTaskId(T,$,o,y,c,v.metricsPrefix),O=j?.requestId
|
|
1956
1961
|
let D=null
|
|
@@ -1972,11 +1977,11 @@ let H=0,B=0
|
|
|
1972
1977
|
for(const e of R){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
1973
1978
|
try{if(await l.default.access(e.fullPath),!(await l.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
1974
1979
|
const r=await l.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await n(r,e.replacements,e.mode)
|
|
1975
|
-
t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,o!==r?(await l.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,B++,y.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),H+=t.failedReplacements}catch(r){t.error=(0,
|
|
1980
|
+
t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,o!==r?(await l.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,B++,y.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),H+=t.failedReplacements}catch(r){t.error=(0,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,H+=t.failedReplacements,y.error("File operation failed",{path:e.path,error:t.error})}L.push(t)}for(const e of M){const t={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
1976
1981
|
try{const o=await r.documentFileManager.getDocumentAsFile(e.documentId),s=r.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
1977
1982
|
t.filename=s?.filename
|
|
1978
1983
|
const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
|
|
1979
|
-
t.replacements=c,t.successfulReplacements=c.filter((e=>e.success)).length,t.failedReplacements=c.filter((e=>!e.success)).length,a!==i?(await l.default.writeFile(o,a,"utf8"),r.documentFileManager.markForSync(e.documentId),t.success=!0,B++,y.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),H+=t.failedReplacements}catch(r){t.error=(0,
|
|
1984
|
+
t.replacements=c,t.successfulReplacements=c.filter((e=>e.success)).length,t.failedReplacements=c.filter((e=>!e.success)).length,a!==i?(await l.default.writeFile(o,a,"utf8"),r.documentFileManager.markForSync(e.documentId),t.success=!0,B++,y.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),H+=t.failedReplacements}catch(r){t.error=(0,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,H+=t.failedReplacements,y.error("Document operation failed",{documentId:e.documentId,error:t.error})}L.push(t)}if(M.length>0)try{for(const e of M){const t=L.find((t=>t.documentId===e.documentId))
|
|
1980
1985
|
t?.success&&await r.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const U=await d.handleMultiFileGitCommit(T,R,L,B,{operationType:"Replace strings",toolRecordId:I,successField:"successfulReplacements",logger:y,metrics:c,metricsPrefix:"replace_strings"},r),G=d.processMultiFileOperationResults(L,"successfulReplacements"),{successfulOperations:W,failedOperations:V,totalSuccessfulChanges:K,overallSuccess:J,successfulFiles:Q,failedFiles:Y}=G
|
|
1981
1986
|
try{await s.updateToolRecord(I,{metadata:{path:R.length>0?R[0].path:"document:"+M[0]?.documentId,status:J?"completed":"failed",error:J?void 0:V+" operations failed",totalOperations:L.length,successfulFiles:Q,failedFiles:Y,operations:N,totalSuccessfulReplacements:K,totalFailedReplacements:H,operationsWithChanges:B,processingTime:Date.now()-w,userComment:E,...R.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:J?`String replacement completed: ${W}/${L.length} operations successful${R.length>0?" (committed to git)":""}`:`String replacement partially failed: ${V}/${L.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}d.formatMultiFileToolResponse("String Replacement",{successfulOperations:W,failedOperations:V,totalSuccessfulChanges:K,overallSuccess:J,successfulFiles:Q,failedFiles:Y},U,F)
|
|
1982
1987
|
let Z="## String Replacement Results\n\n"
|
|
@@ -1988,8 +1993,8 @@ for(const e of L){if("file"===e.type?Z+=`### File: ${e.path}\n`:(Z+="### Documen
|
|
|
1988
1993
|
for(const t of e.replacements.filter((e=>!e.success)))Z+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}Z+="\n"}}M.length>0&&(Z+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
1989
1994
|
const X=Date.now()-w
|
|
1990
1995
|
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
|
|
1991
|
-
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,
|
|
1992
|
-
const l=c(t(1943)),d=a(t(5967)),u=t(9860),h=t(5003),p=t(7478),
|
|
1996
|
+
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,g.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,g.getErrorMessage)(t)})}catch(e){}return c.incrementCounter("replace_strings_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,g.getErrorMessage)(t)}],isError:!0}}}
|
|
1997
|
+
const l=c(t(1943)),d=a(t(5967)),u=t(9860),h=t(5003),p=t(7478),m=t(9949),g=t(8824)},3322(e,exports,t){"use strict"
|
|
1993
1998
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1994
1999
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1995
2000
|
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=[]
|
|
@@ -2025,10 +2030,10 @@ var h=t(4192)
|
|
|
2025
2030
|
Object.defineProperty(exports,"BaseApiClient",{enumerable:!0,get(){return h.BaseApiClient}})
|
|
2026
2031
|
var p=t(1599)
|
|
2027
2032
|
Object.defineProperty(exports,"SessionRequestAssociationClient",{enumerable:!0,get(){return p.SessionRequestAssociationClient}})
|
|
2028
|
-
var
|
|
2029
|
-
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return
|
|
2030
|
-
var
|
|
2031
|
-
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return
|
|
2033
|
+
var m=t(5187)
|
|
2034
|
+
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return m.CLISessionClient}})
|
|
2035
|
+
var g=t(6539)
|
|
2036
|
+
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return g.ClientFactory}})
|
|
2032
2037
|
const f=t(6539)
|
|
2033
2038
|
exports.default={ClientFactory:f.ClientFactory}},3416(e,exports){"use strict"
|
|
2034
2039
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.KIND_META=exports.QUEST_STATUS_CLOSED=exports.QUEST_STATUS_OPEN=exports.QUEST_DEFAULTS=exports.PLAN_KINDS=void 0,exports.PLAN_KINDS=["plan","quest"],exports.QUEST_DEFAULTS={tickIntervalSeconds:1800,maxInFlight:1,maxPerDay:24,minIterations:3},exports.QUEST_STATUS_OPEN="open",exports.QUEST_STATUS_CLOSED="closed",exports.KIND_META={plan:{docType:"Plan",filenamePrefix:"PLAN-",label:"plan",idLabel:"Plan ID",headingCreated:"Plan Created",errorVerb:"create plan",alchemyKind:"plan-create",canBeActivePlan:!0},quest:{docType:"Quest",filenamePrefix:"QUEST-",label:"quest",idLabel:"Quest ID",headingCreated:"Quest Created",errorVerb:"create quest",alchemyKind:"quest-create",canBeActivePlan:!1}}},3420(e,exports,t){"use strict"
|
|
@@ -2054,12 +2059,12 @@ const n=e
|
|
|
2054
2059
|
"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()}
|
|
2055
2060
|
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 p=null
|
|
2056
2061
|
if(h.requestId)try{const e=i.getRequestClient()
|
|
2057
|
-
p=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
|
|
2062
|
+
p=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 m=e=>{if(!e)return"Unknown date"
|
|
2058
2063
|
try{const t=new Date(e)
|
|
2059
|
-
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},m
|
|
2064
|
+
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},g=m(h.createdAt),f=m(h.updatedAt),y=h.requestId||h.requestLocalId,w=h.sequenceNumber&&y?(0,s.formatTaskRef)(y,h.sequenceNumber):r,b=(0,s.formatTaskRefForAgent)(w)
|
|
2060
2065
|
let I=`# Task: ${h.title} (${b})\n\n`
|
|
2061
|
-
if(I+=`**Status**: ${h.status}\n`,I+=`**Created**: ${
|
|
2062
|
-
I+="\n## Metadata\n\n",e.lastCommit&&(I+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(I+=`**Completed At**: ${
|
|
2066
|
+
if(I+=`**Status**: ${h.status}\n`,I+=`**Created**: ${g}\n`,I+=`**Updated**: ${f}\n`,h.requestId&&(I+="**Parent Request**: "+h.requestId,I+=p?` (${p.title})\n`:"\n"),h.metadata){const e=h.metadata
|
|
2067
|
+
I+="\n## Metadata\n\n",e.lastCommit&&(I+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(I+=`**Completed At**: ${m(e.completedAt)}\n`),e.completionSummary&&(I+=`**Completion Summary**: ${e.completionSummary}\n`)
|
|
2063
2068
|
const t=["lastCommit","completedAt","completionSummary"]
|
|
2064
2069
|
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})
|
|
2065
2070
|
try{const n=i.getToolRecordClient()
|
|
@@ -2134,30 +2139,30 @@ if(i.length>h)break
|
|
|
2134
2139
|
if(i===l){c.push({line:s+1,actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t})
|
|
2135
2140
|
break}}}o+=i.length+1}return c}const p=t.trim()[0]
|
|
2136
2141
|
if(!p)return c
|
|
2137
|
-
let
|
|
2138
|
-
for(;;){if(
|
|
2139
|
-
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`)}
|
|
2140
|
-
const r=e.indexOf(p,
|
|
2142
|
+
let m=0,g=0
|
|
2143
|
+
for(;;){if(g%100==0&&Date.now()-d>o){const r=Date.now()-d
|
|
2144
|
+
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`)}g++
|
|
2145
|
+
const r=e.indexOf(p,m)
|
|
2141
2146
|
if(-1===r)break
|
|
2142
2147
|
let i=r+t.length
|
|
2143
2148
|
const u=Math.min(Math.floor(.5*t.length),200),h=Math.min(r+t.length+u,e.length),f=l.length
|
|
2144
2149
|
let y=!1
|
|
2145
2150
|
for(let t=i;h>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2146
2151
|
if(i.length>f)break
|
|
2147
|
-
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),
|
|
2148
|
-
break}}y||(
|
|
2152
|
+
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),m=t,y=!0
|
|
2153
|
+
break}}y||(m=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[]
|
|
2149
2154
|
const c=[],l=o(t),d=Date.now()
|
|
2150
2155
|
if(t.length>500)return i(e,t)
|
|
2151
2156
|
if(!l)return c
|
|
2152
2157
|
const u=t.replace(/\s/g,"")[0],h=l.length
|
|
2153
|
-
let p=0,
|
|
2154
|
-
for(;;){if(
|
|
2155
|
-
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`)}
|
|
2158
|
+
let p=0,m=0
|
|
2159
|
+
for(;;){if(m%100==0&&Date.now()-d>n){const r=Date.now()-d
|
|
2160
|
+
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`)}m++
|
|
2156
2161
|
const r=e.indexOf(u,p)
|
|
2157
2162
|
if(-1===r)break
|
|
2158
|
-
const i=r+h,a=Math.min(t.length,300),
|
|
2163
|
+
const i=r+h,a=Math.min(t.length,300),g=Math.min(r+h+a,e.length)
|
|
2159
2164
|
let f=!1
|
|
2160
|
-
for(let t=i;
|
|
2165
|
+
for(let t=i;g>=t;t++){const n=e.substring(r,t),i=o(n)
|
|
2161
2166
|
if(i.length>h)break
|
|
2162
2167
|
if(i===l){c.push({line:s(e,r),actuallyMatched:n,matchType:"whitespace_agnostic",startPos:r,endPos:t}),p=t,f=!0
|
|
2163
2168
|
break}}f||(p=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))
|
|
@@ -2185,15 +2190,15 @@ let i=d.FileOperationPhase.VALIDATION
|
|
|
2185
2190
|
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}"}
|
|
2186
2191
|
try{const a=e,{path:u}=a
|
|
2187
2192
|
n.info("Getting file info: "+u)
|
|
2188
|
-
const{normalizedPath:
|
|
2193
|
+
const{normalizedPath:m,fullPath:g}=d.validateAndNormalizePath(u,t)
|
|
2189
2194
|
i=d.FileOperationPhase.FILE_WRITE
|
|
2190
|
-
try{await c.default.access(
|
|
2195
|
+
try{await c.default.access(g)}catch(e){throw Error("Path not accessible: "+u)}const f=await c.default.stat(g),y=f.isFile()?l.default.extname(g).slice(1):"",w={path:m,type:f.isDirectory()?"directory":"file",size:f.size,sizeFormatted:(p=f.size,d.formatFileSize(p)),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: "+m,"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]
|
|
2191
2196
|
w.isFile&&y&&b.push("Extension: "+y)
|
|
2192
2197
|
const I=Date.now()-s
|
|
2193
|
-
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+
|
|
2198
|
+
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+m,{type:w.type,size:w.size,time:I}),{content:[{type:"text",text:b.join("\n")}]}}catch(t){const r=Date.now()-s
|
|
2194
2199
|
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,p}
|
|
2195
2200
|
const c=a(t(1943)),l=a(t(6928)),d=i(t(5967)),u=t(8824)},3707(e,exports,t){"use strict"
|
|
2196
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,u,h,p,g
|
|
2201
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,u,h,p,m,g){const f=p.child({tool:"quick_edit"}),y=Date.now()
|
|
2197
2202
|
try{const w=h.getRequestClient(),b=h.getTaskClient(),I=h.getFileClient(),k=h.getToolRecordClient(),{title:v,description:C,..._}=e,E=e.comment||v
|
|
2198
2203
|
f.info("Starting quick_edit workflow",{title:v,operationType:t})
|
|
2199
2204
|
let S=!1
|
|
@@ -2204,23 +2209,23 @@ if(!q||!q.id)throw Error("Failed to create request")
|
|
|
2204
2209
|
const T=q.id
|
|
2205
2210
|
let x
|
|
2206
2211
|
f.info("Created request",{requestId:T})
|
|
2207
|
-
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:T,taskId:void 0,workspaceManager:u.workspaceManager},p,
|
|
2212
|
+
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:T,taskId:void 0,workspaceManager:u.workspaceManager},p,m)
|
|
2208
2213
|
e.userChangesCommitted?f.info("Committed user changes to main before quick-edit branch creation",{requestId:T,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:T,error:e instanceof Error?e.message:e+""})}else f.debug("No git instance available, skipping uncommitted changes check")
|
|
2209
2214
|
f.debug("Creating task")
|
|
2210
2215
|
const e=await b.createTask({requestId:T,projectId:u.projectId,title:`Execute ${t} operation`,description:"Quick change: "+v})
|
|
2211
2216
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2212
2217
|
let C
|
|
2213
|
-
if(x=e.id,f.info("Created task",{taskId:x}),f.debug("Executing file operation",{operationType:t}),"write"===t)C=await(0,o.handleWriteFile)({taskId:x,..._,comment:E},u,I,b,k,w,p,g
|
|
2214
|
-
else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:x,..._,comment:E},u,b,k,w,p,g
|
|
2218
|
+
if(x=e.id,f.info("Created task",{taskId:x}),f.debug("Executing file operation",{operationType:t}),"write"===t)C=await(0,o.handleWriteFile)({taskId:x,..._,comment:E},u,I,b,k,w,p,m,g)
|
|
2219
|
+
else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:x,..._,comment:E},u,b,k,w,p,m,g)
|
|
2215
2220
|
else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
|
|
2216
|
-
C=await(0,i.handleManageFiles)({taskId:x,..._,comment:E||v},u,b,k,w,h,p,g
|
|
2221
|
+
C=await(0,i.handleManageFiles)({taskId:x,..._,comment:E||v},u,b,k,w,h,p,m,g)}if(C.isError){f.error("File operation failed, cleaning up request and task",{requestId:T,taskId:x})
|
|
2217
2222
|
try{await b.updateTaskStatus(x,"canceled"),f.info("Canceled task after operation failure",{taskId:x})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:x,error:e instanceof Error?e.message:e+""})}try{await w.updateRequest(T,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:T}),u.workspaceManager&&(await u.workspaceManager.cancelRequest(T),f.info("Cleaned up branch/worktree after operation failure",{requestId:T}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:T,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 (${T}) and task have been canceled and cleaned up.`}],isError:!0}}const q=C.content[0].text,P=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
|
|
2218
2223
|
P?f.warn("File operation completed with partial failures",{requestId:T}):f.info("File operation completed successfully"),f.debug("Completing task")
|
|
2219
|
-
try{await(0,a.handleCompleteTask)({taskId:x,summary:`Executed ${t} operation for quick fix: ${v}${P?" (partial success)":""}`},u,h,p,
|
|
2224
|
+
try{await(0,a.handleCompleteTask)({taskId:x,summary:`Executed ${t} operation for quick fix: ${v}${P?" (partial success)":""}`},u,h,p,m),f.info("Task completed successfully",{taskId:x})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:x,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
|
|
2220
2225
|
try{await b.updateTaskStatus(x,"completed"),f.info("Task completed via direct updateTaskStatus call",{taskId:x})}catch(e){return f.error("Direct task completion ALSO failed - task may be stuck in in_progress",{taskId:x,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:** ${T}\n**Task:** ${x}\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: ${x}\n\nError: `+(e instanceof Error?e.message:e+"")}],isError:!0}}}f.debug("Completing request")
|
|
2221
2226
|
const R=P?`Quick change completed with partial success: ${v}. Some replacements failed - see details below.`:"Quick change completed: "+v,M=P?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
|
|
2222
2227
|
let $=!1
|
|
2223
|
-
try{const e=await(0,c.handleCompleteRequest)({requestId:T,summary:R,acceptanceEvidence:[{evidence:M}],testVerification:void 0},u,h,p,g
|
|
2228
|
+
try{const e=await(0,c.handleCompleteRequest)({requestId:T,summary:R,acceptanceEvidence:[{evidence:M}],testVerification:void 0},u,h,p,m,g)
|
|
2224
2229
|
if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:T,error:e.content[0].text})
|
|
2225
2230
|
else{try{await w.updateRequest(T,{status:"completed",completionSummary:R}),f.info("Request finalized to completed",{requestId:T})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:T,error:(0,d.getErrorMessage)(e)})}$=!0,f.info("Request completed successfully",{requestId:T})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:T,error:e instanceof Error?e.message:e+""})}if(!$)try{f.info("Attempting direct request completion via API",{requestId:T}),await w.updateRequest(T,{status:"completed",completionSummary:R}),$=!0,f.info("Request completed successfully via direct API call",{requestId:T})}catch(e){return f.error("Direct request completion also failed",{requestId:T,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${T}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const j=Date.now()-y
|
|
2226
2231
|
f.info("Quick fix completed",{requestId:T,duration:j,hasPartialFailure:P})
|
|
@@ -2300,15 +2305,15 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleWriteFile=a
|
|
|
2300
2305
|
let v,C,_=d.FileOperationPhase.VALIDATION
|
|
2301
2306
|
const E={toolName:"write_file",operationName:"write",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"write-file",metricsPrefix:"write_file",successMessage:"Successfully wrote content",failureMessage:"Failed to write content"}
|
|
2302
2307
|
try{const n=e
|
|
2303
|
-
let{path:
|
|
2308
|
+
let{path:g,documentId:S,content:q,format:T,append:x,comment:P}=n
|
|
2304
2309
|
Array.isArray(q)&&(q=q.join("\n"))
|
|
2305
2310
|
const{enforceActiveTask:R}=await Promise.resolve().then(t.bind(t,3451)),M=await R(r,o,f,e.taskId)
|
|
2306
2311
|
if("errorResult"in M)return M.errorResult
|
|
2307
|
-
const{taskId:$}=M,j=!!S,O=!!
|
|
2308
|
-
b.info("Writing content to "+(j?"document":"file"),{taskId:$,filePath:O?
|
|
2312
|
+
const{taskId:$}=M,j=!!S,O=!!g
|
|
2313
|
+
b.info("Writing content to "+(j?"document":"file"),{taskId:$,filePath:O?g:void 0,documentId:j?S:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:T,append:x,comment:P})
|
|
2309
2314
|
let D,A,F,N="",z=!1,L=!1
|
|
2310
|
-
const H=O?
|
|
2311
|
-
if(j){if(r.apiClient)try{await(0,
|
|
2315
|
+
const H=O?g:void 0
|
|
2316
|
+
if(j){if(r.apiClient)try{await(0,m.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}
|
|
2312
2317
|
throw e}if(!r.documentFileManager)throw Error("Document file manager not available")
|
|
2313
2318
|
N=await r.documentFileManager.getDocumentAsFile(S)
|
|
2314
2319
|
const e=r.documentFileManager.getCachedDocumentInfo(S)
|
|
@@ -2343,8 +2348,8 @@ const oe=Date.now()
|
|
|
2343
2348
|
b.info("Write operation completed successfully",{duration:oe-k,path:O?D:"document:"+S,contentLength:Y.length,wasCreated:z}),I({tool:"write_file",success:!0}),y.incrementCounter("write_file_total",1,{success:!0})
|
|
2344
2349
|
const se=r.workspaceManager?.consumeLargeFileWarning(r.currentSessionId)
|
|
2345
2350
|
return se&&(ne+=se),{content:[{type:"text",text:ne}],...(0,l.alchemyMeta)({kind:"write-file",toolRecordId:C})}}catch(t){const r=Date.now()-k
|
|
2346
|
-
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,
|
|
2347
|
-
const a=i(t(6928)),c=i(t(1943)),l=t(2272),d=s(t(5967)),u=t(9860),h=t(5003),p=t(7478),
|
|
2351
|
+
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,g.getErrorMessage)(t),phase:_,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,g.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,g.getErrorMessage)(t)}],isError:!0}}}
|
|
2352
|
+
const a=i(t(6928)),c=i(t(1943)),l=t(2272),d=s(t(5967)),u=t(9860),h=t(5003),p=t(7478),m=t(9949),g=t(8824)},4139(e,exports){"use strict"
|
|
2348
2353
|
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"
|
|
2349
2354
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=exports.TasksSchema=void 0
|
|
2350
2355
|
const r=t(1569),n=t(3247)
|
|
@@ -2412,8 +2417,8 @@ if(!c.startsWith(s+a.sep))return{content:[{type:"text",text:"\u274c Invalid file
|
|
|
2412
2417
|
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]
|
|
2413
2418
|
if(!h)return{content:[{type:"text",text:"\u274c Unsupported image type: ."+u}],isError:!0}
|
|
2414
2419
|
if("svg"===u)return{content:[{type:"text",text:`**Asset: ${r}**\n\n\`\`\`svg\n${await i.readFile(c,"utf-8")}\n\`\`\``}]}
|
|
2415
|
-
const p=await i.readFile(c),
|
|
2416
|
-
return o.info("Asset viewed",{filename:r,size:p.length}),{content:[{type:"text",text:`**Asset: ${r}** (${(p.length/1024).toFixed(1)} KB)`},{type:"image",data:
|
|
2420
|
+
const p=await i.readFile(c),m=p.toString("base64")
|
|
2421
|
+
return o.info("Asset viewed",{filename:r,size:p.length}),{content:[{type:"text",text:`**Asset: ${r}** (${(p.length/1024).toFixed(1)} KB)`},{type:"image",data:m,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}}}
|
|
2417
2422
|
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+"'")
|
|
2418
2423
|
throw t.code="MODULE_NOT_FOUND",t}e.keys=()=>[],e.resolve=e,e.id=4245,module.exports=e},4306(e,exports,t){"use strict"
|
|
2419
2424
|
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:p}=e
|
|
@@ -2422,18 +2427,18 @@ d.info("Starting merge request",{requestId:h,verificationCount:p.length})
|
|
|
2422
2427
|
const e=a.getRequestClient(),s=await e.getRequest(h)
|
|
2423
2428
|
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}
|
|
2424
2429
|
if(p.length>0)try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/verify-criteria`,{verifications:p}),d.info("Criteria verified",{requestId:h,count:p.length})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2425
|
-
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,
|
|
2430
|
+
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,m
|
|
2426
2431
|
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/validate-completion`,{})
|
|
2427
2432
|
c=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2428
2433
|
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`
|
|
2429
2434
|
return c.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\n",c.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (${t.status})\n`}))),u({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(!t.workspaceManager)throw Error("WorkspaceManager not available")
|
|
2430
2435
|
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)
|
|
2431
|
-
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
|
|
2436
|
+
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 g="workspace-manager"
|
|
2432
2437
|
const f=await e.getRequest(h),y=f?.title||"Request "+h,w="resolving_conflicts"===f?.status
|
|
2433
|
-
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),
|
|
2438
|
+
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),m=await t.workspaceManager.completeRequest(h,y,{skipConflictDetection:!0}),g="retry-theirs"):(m=await t.workspaceManager.completeRequest(h,y),g=m.autoMergeInfo?.strategy||"workspace-manager"),d.info("Merge completed",{requestId:h,mergeCommitHash:m.mergeCommitHash,mergeMethod:g})}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)
|
|
2434
2439
|
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)
|
|
2435
|
-
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:p.map((e=>({evidence:e.evidence}))),mergeResult:{mergeCommitHash:
|
|
2436
|
-
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:
|
|
2440
|
+
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:p.map((e=>({evidence:e.evidence}))),mergeResult:{mergeCommitHash:m.mergeCommitHash,mergeBaseSha:l,mergedFiles:m.mergedFiles,cleanedUp:m.cleanedUp,method:g}})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2441
|
+
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:m.mergeCommitHash,error:t}),u({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${m.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: ${m.mergeCommitHash.substring(0,8)}`}]}}catch(e){const r=(0,i.getErrorMessage)(e)
|
|
2437
2442
|
d.error("Merge request failed",{error:r})
|
|
2438
2443
|
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}}}
|
|
2439
2444
|
const r=t(3807),n=t(9860),o=t(1651),s=t(8616),i=t(8824)},4394(e,exports,t){"use strict"
|
|
@@ -2453,49 +2458,51 @@ const a=await r.updateDocument(e.planId,i),c=a.localId||a.id
|
|
|
2453
2458
|
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}}}
|
|
2454
2459
|
const r=t(8824)},4425(e,exports,t){"use strict"
|
|
2455
2460
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2456
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,
|
|
2457
|
-
try{const
|
|
2458
|
-
if("list"===
|
|
2461
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,u,h,p,m){const g=h.startTimer("tool_execution_time"),f=e.operation||"run"
|
|
2462
|
+
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))
|
|
2463
|
+
if("list"===f){if(0===y.length)return g({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"})}
|
|
2459
2464
|
const e=[]
|
|
2460
|
-
return
|
|
2461
|
-
try{const r=await fetch((0,
|
|
2465
|
+
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'),g({success:!0}),{content:[{type:"text",text:e.join("\n")}],...(0,a.alchemyMeta)({kind:"list-commands"})}}if("setup"===f){const t=m?.sessionId,n=t?await l.sessionIdentity.getSessionRequestId(r,u,t):void 0
|
|
2466
|
+
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)})
|
|
2462
2467
|
if(!r.ok){const e=await r.text().catch((()=>""))
|
|
2463
|
-
return
|
|
2464
|
-
return o.success&&o.data?(
|
|
2465
|
-
const n=function(e){return e?.sessionId||
|
|
2466
|
-
if(!n)return
|
|
2467
|
-
const o=new Set(
|
|
2468
|
+
return g({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()
|
|
2469
|
+
return o.success&&o.data?(g({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"})}):(g({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(o.error||"unknown error")}],isError:!0})}catch(e){return g({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 g({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}
|
|
2470
|
+
const n=function(e){return e?.sessionId||l.sessionIdentity.getIdentity()?.sessionId||null}(m)
|
|
2471
|
+
if(!n)return g({success:!1,error:"no_session"}),{content:[{type:"text",text:"Error: no session context available to attribute approval notifications."}],isError:!0}
|
|
2472
|
+
const o=new Set(y.map((e=>e.name.toLowerCase()))),s=[],i=[]
|
|
2468
2473
|
for(const t of e.commands){const e=t.name?.trim(),r=t.command?.trim(),n=t.description?.trim()
|
|
2469
|
-
e&&r&&n?o.has(e.toLowerCase())?
|
|
2474
|
+
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:m?.sessionId,isActive:!1}),o=n?.data?.id||n?.id
|
|
2470
2475
|
if(!o)throw Error("command create returned no id")
|
|
2471
|
-
return{ok:!0,proposal:e,commandId:o}}catch(t){return{ok:!1,proposal:e,error:(0,
|
|
2472
|
-
for(const e of
|
|
2473
|
-
const
|
|
2474
|
-
if(
|
|
2476
|
+
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))
|
|
2477
|
+
for(const e of d)e.ok||i.push({name:e.proposal.name,reason:e.error})
|
|
2478
|
+
const p=[]
|
|
2479
|
+
if(h.length>0)try{const e=r.getSessionMessageClient()
|
|
2475
2480
|
if(!e)throw Error("session message client unavailable")
|
|
2476
|
-
await e.createQuestion({fromSessionId:n,questionType:"alternatives",question:`Command batch approval: ${
|
|
2477
|
-
for(const e of
|
|
2478
|
-
for(const t of
|
|
2479
|
-
const
|
|
2480
|
-
return
|
|
2481
|
-
const n=
|
|
2482
|
-
if(!n)return
|
|
2483
|
-
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),
|
|
2484
|
-
return
|
|
2485
|
-
if(!
|
|
2486
|
-
return
|
|
2487
|
-
e.grep&&(
|
|
2488
|
-
const
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
const
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
const
|
|
2481
|
+
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"})
|
|
2482
|
+
for(const e of h)p.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)}))))))
|
|
2483
|
+
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:p.length,skipped:i.length}),g({success:!0})
|
|
2484
|
+
const f=[`## Submitted ${p.length} command${1===p.length?"":"s"} for approval${i.length?`, ${i.length} skipped`:""}`]
|
|
2485
|
+
return p.length>0&&(f.push("","### Pending approval"),f.push(...p.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 g({success:!1,error:"missing_name"}),{content:[{type:"text",text:"Error: `name` is required when removing a command."}],isError:!0}
|
|
2486
|
+
const n=y.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2487
|
+
if(!n)return g({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.`}],isError:!0}
|
|
2488
|
+
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),u.info("Removed command",{name:n.name,id:n.id}),g({success:!0}),{content:[{type:"text",text:`Removed command **${n.name}**.`}]}}catch(e){return g({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(", ")
|
|
2489
|
+
return g({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()))
|
|
2490
|
+
if(!I){const t=w.map((e=>e.name)).join(", ")
|
|
2491
|
+
return g({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
|
|
2492
|
+
e.grep&&(k=`${k} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
|
|
2493
|
+
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")
|
|
2494
|
+
let q=null
|
|
2495
|
+
try{s.default.mkdirSync(_,{recursive:!0}),q=s.default.createWriteStream(S,{flags:"w"}),q.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})
|
|
2496
|
+
const T=await(0,n.runTrackedShellCommand)(k,{cwd:C,timeoutMs:1e3*(I.timeout||60),env:{...process.env,FORCE_COLOR:"0"},onChunk:q?(e,t)=>{q?.write(t)}:void 0},{id:E,name:I.name,sessionId:m?.sessionId,logPath:S})
|
|
2497
|
+
q&&(q.write(`\n# exit: ${T.exitCode}${T.timedOut?" (timed out)":""}\n`),q.end())
|
|
2498
|
+
let x=T.stdout,P=T.stderr
|
|
2499
|
+
const R=T.exitCode,M=T.timedOut,$=8e3,j=4e3
|
|
2500
|
+
x.length>$&&(x="\u2026"+x.slice(-$)),P.length>j&&(P="\u2026"+P.slice(-j))
|
|
2501
|
+
const O=M?"TIMEOUT":null,D=[x,P].filter(Boolean).join("\n")||"(no output)"
|
|
2502
|
+
let A
|
|
2503
|
+
if(p)try{const e=await p.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:I.name,command:k,exitCode:R,timedOut:M,status:M?"timeout":0===R?"success":"failed",timestamp:(new Date).toISOString()}})
|
|
2504
|
+
A=e?.id}catch(e){u.debug("Failed to create tool record for command run",{error:(0,c.getErrorMessage)(e)})}return g({success:!0}),{content:[{type:"text",text:`## ${I.name}${O?` \u2014 ${O} (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 g({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,c.getErrorMessage)(e)}],isError:!0}}}
|
|
2505
|
+
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"
|
|
2499
2506
|
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
|
|
2500
2507
|
const i=e.match(exports.TASK_REF_SHORT_PATTERN)
|
|
2501
2508
|
if(!i)return e
|
|
@@ -2518,9 +2525,9 @@ return e}
|
|
|
2518
2525
|
const o=t(6688),s=t(8955)
|
|
2519
2526
|
exports.TASK_REF_PATTERN=/^(req\d{6})#(\d+)$/,exports.TASK_REF_SHORT_PATTERN=/^#?(\d{1,3})$/},4592(e,exports,t){"use strict"
|
|
2520
2527
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlannerOps=async function(e,t,c,l,d,u){const h=c.child({tool:"planner_ops"}),p=l.startTimer("tool_execution_time")
|
|
2521
|
-
try{const c=e,{operation:
|
|
2528
|
+
try{const c=e,{operation:m,sessionId:g}=c
|
|
2522
2529
|
let f
|
|
2523
|
-
switch(h.info("Processing planner_ops",{operation:
|
|
2530
|
+
switch(h.info("Processing planner_ops",{operation:m,sessionId:g}),m){case"request":{const e=await async function(e,t,r){if(!e)return"ask"
|
|
2524
2531
|
try{const s=r?.sessionId||o.sessionIdentity.getIdentity()?.sessionId
|
|
2525
2532
|
if(!s)return"ask"
|
|
2526
2533
|
const i=e.getCLISessionClient()
|
|
@@ -2539,25 +2546,30 @@ if(t&&e){const r=await o.sessionIdentity.getParentSessionId(e,d,h),n=c.descripti
|
|
|
2539
2546
|
await t.createQuestion({fromSessionId:e,toSessionId:r||void 0,questionType:"alternatives",question:"Planning requested: "+n,options:[{id:"auto",label:"Auto Plan",description:"Spawn an autonomous planner agent"},{id:"manual",label:"Manual Plan",description:"Open the interactive plan editor"},{id:"cancel",label:"Skip",description:"Dismiss this planning request"}],context:c.prompt,category:"action-required",priority:"high"}),h.info("planner-request: notification created",{fromSessionId:e})}else h.warn("planner-request: skipping notification",{hasClient:!!t,hasCallerSessionId:!!e})}catch(e){h.warn("planner-request: failed to create notification",{error:(0,n.getErrorMessage)(e)})}f={content:[{type:"text",text:"Planning request submitted. The user will choose the planning approach. This is non-blocking \u2014 continue with your other work."}],...(0,i.alchemyMeta)({pendingAction:{kind:"planner-choice",payload:{prompt:c.prompt,description:c.description}}})}
|
|
2540
2547
|
break}const r="auto-planner"
|
|
2541
2548
|
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
|
|
2542
|
-
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)(
|
|
2549
|
+
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)(g,t,h,d)
|
|
2543
2550
|
break
|
|
2544
2551
|
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})]),p=a.content[0]?.text??"",y=l.content[0]?.text??""
|
|
2545
2552
|
if(p.trim()||y.trim()){const e=[]
|
|
2546
2553
|
p.trim()&&e.push("## Auto-planner sessions\n"+p),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."}]}
|
|
2547
2554
|
break
|
|
2548
|
-
default:throw new r.ValidationError("Unknown operation: "+
|
|
2549
|
-
const y=a[
|
|
2555
|
+
default:throw new r.ValidationError("Unknown operation: "+m)}p({success:!0}),l.incrementCounter(`planner_ops_${m}_success`,1)
|
|
2556
|
+
const y=a[m]??"planner-request"
|
|
2550
2557
|
return(0,i.withAlchemyKind)(f,y)}catch(e){return h.error("Planner ops failed",{error:e instanceof Error?e.stack:e+""}),p({success:!1}),l.incrementCounter("planner_ops_errors",1),{content:[{type:"text",text:"Planner operation failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}}
|
|
2551
2558
|
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"
|
|
2552
|
-
|
|
2559
|
+
async function r(e,r={}){const{spawn:n}=await Promise.resolve().then(t.t.bind(t,5317,23))
|
|
2560
|
+
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=[]
|
|
2561
|
+
let c=!1,l=!1
|
|
2562
|
+
const d=e=>{if(s.pid)try{o?s.kill(e):process.kill(-s.pid,e)}catch{}}
|
|
2563
|
+
let u,h
|
|
2564
|
+
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)}))
|
|
2565
|
+
const p=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}))}
|
|
2566
|
+
s.on("close",(e=>p(e??(c?124:1)))),s.on("error",(()=>p(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"]})
|
|
2553
2567
|
let c="",l=""
|
|
2554
|
-
a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
const
|
|
2559
|
-
s.on("close",(e=>h(e??(d?124:1)))),s.on("error",(()=>h(1)))}))}
|
|
2560
|
-
const r=t(5317)},4607(e,exports,t){"use strict"
|
|
2568
|
+
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()
|
|
2569
|
+
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((()=>{}))
|
|
2570
|
+
const l=await r(e,n)
|
|
2571
|
+
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}
|
|
2572
|
+
const n=t(5317)},4607(e,exports,t){"use strict"
|
|
2561
2573
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2562
2574
|
const r=t(6183),n=t(3306)
|
|
2563
2575
|
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)}}},4640(e,exports,t){"use strict"
|
|
@@ -2569,10 +2581,10 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2569
2581
|
var t={}
|
|
2570
2582
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2571
2583
|
return o(t,e),t})
|
|
2572
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,r,n,o,s,u,h){const p=s.child({tool:"file_recover"}),
|
|
2573
|
-
try{const
|
|
2574
|
-
return p.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,p,g
|
|
2575
|
-
try{const{normalizedPath:y,fullPath:w}=c.validateAndNormalizePath(t,o),b=await c.validateTaskId(e,y,s.getTaskClient(),h,p,"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,p,"file-recover",
|
|
2584
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,r,n,o,s,u,h){const p=s.child({tool:"file_recover"}),m=u.startTimer("tool_execution_time"),g=Date.now()
|
|
2585
|
+
try{const m=e,{path:f,commitHash:y,createBackup:w}=m,{resolveActiveTaskId:b}=await Promise.resolve().then(t.bind(t,3451)),I=e.taskId||await b(r,n,s)||"untracked"
|
|
2586
|
+
return p.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,p,m,g){let f
|
|
2587
|
+
try{const{normalizedPath:y,fullPath:w}=c.validateAndNormalizePath(t,o),b=await c.validateTaskId(e,y,s.getTaskClient(),h,p,"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,p,"file-recover",g)
|
|
2576
2588
|
f=I
|
|
2577
2589
|
let k,v=!1
|
|
2578
2590
|
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
|
|
@@ -2584,33 +2596,33 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
|
|
|
2584
2596
|
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await a.writeFile(w,_,"utf8")
|
|
2585
2597
|
let E={}
|
|
2586
2598
|
try{const t=`Recover ${y} from ${r.substring(0,8)}`
|
|
2587
|
-
E=await c.commitToGit(e,y,f,f,t,o,h,p,"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()-
|
|
2599
|
+
E=await c.commitToGit(e,y,f,f,t,o,h,p,"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()-m,...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"
|
|
2588
2600
|
let q=`\u2705 **File ${S.charAt(0).toUpperCase()+S.slice(1)} Successfully**\n\n`
|
|
2589
|
-
return q+=`**File:** ${y}\n`,q+=`**Recovered from:** ${r.substring(0,8)}\n`,q+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(q+=`**Backup created:** ${i.basename(k)}\n`),q+="**Git status:** Recovery committed\n",q+="\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()-
|
|
2590
|
-
return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),
|
|
2601
|
+
return q+=`**File:** ${y}\n`,q+=`**Recovered from:** ${r.substring(0,8)}\n`,q+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(q+=`**Backup created:** ${i.basename(k)}\n`),q+="**Git status:** Recovery committed\n",q+="\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()-m}),p.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:q}]}}catch(e){throw e}}(I,f,y,w,r,n,o,p,u,g,h)}catch(e){const t=Date.now()-g
|
|
2602
|
+
return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),m({tool:"file_recover",success:!1}),u.incrementCounter("file_recover_errors",1),{content:[{type:"text",text:"\u274c **Recovery Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
2591
2603
|
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"
|
|
2592
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,h,p,g,
|
|
2604
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,h,p,m,g,f){const y=m.child({tool:"request_operations"})
|
|
2593
2605
|
try{const w=e
|
|
2594
2606
|
let{requestId:b}=w
|
|
2595
2607
|
const{operation:I}=w
|
|
2596
2608
|
if("list"!==I&&"search"!==I&&!b){const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=h.currentSessionId
|
|
2597
2609
|
if(r&&"__unknown__"!==r&&"__server__"!==r&&(b=await e.getSessionRequestId(p,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")
|
|
2598
2610
|
const e={requestId:b,summary:w.complete.summary}
|
|
2599
|
-
return(0,d.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,h,p,g,
|
|
2611
|
+
return(0,d.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,h,p,m,g,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,p,m,g,f),u.merge)
|
|
2600
2612
|
case"approve":{y.info("Routing to approve-request handler")
|
|
2601
2613
|
const e={requestId:b}
|
|
2602
|
-
return(0,d.withAlchemyKind)(await(0,a.handleApproveRequest)(e,h,p,g,
|
|
2614
|
+
return(0,d.withAlchemyKind)(await(0,a.handleApproveRequest)(e,h,p,m,g,f),u.approve)}case"revert":{y.info("Routing to revert-request handler")
|
|
2603
2615
|
const e={requestId:b,reason:w.revert.reason,confirmDestructive:w.revert.confirmDestructive}
|
|
2604
|
-
return(0,d.withAlchemyKind)(await(0,n.handleRevertRequest)(e,h,p,g
|
|
2616
|
+
return(0,d.withAlchemyKind)(await(0,n.handleRevertRequest)(e,h,p,m,g),u.revert)}case"get-info":{y.info("Routing to get-request-information handler")
|
|
2605
2617
|
const e={requestId:b}
|
|
2606
|
-
return(0,d.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,h,p,g
|
|
2618
|
+
return(0,d.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,h,p,m,g),u["get-info"])}case"list":{y.info("Routing to list-requests handler")
|
|
2607
2619
|
const e={filters:w.list?.filters}
|
|
2608
|
-
return(0,d.withAlchemyKind)(await(0,s.handleListRequests)(e,h,p,g
|
|
2620
|
+
return(0,d.withAlchemyKind)(await(0,s.handleListRequests)(e,h,p,m,g),u.list)}case"search":{y.info("Routing to search-requests handler")
|
|
2609
2621
|
const e={search:w.search}
|
|
2610
|
-
return(0,d.withAlchemyKind)(await(0,i.handleSearchRequests)(e,h,p,g
|
|
2622
|
+
return(0,d.withAlchemyKind)(await(0,i.handleSearchRequests)(e,h,p,m,g),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}
|
|
2611
2623
|
try{const e=p.getProxyClient(),t=await e.proxyGet(`/api/projects/${h.projectId}/tasks`,{requestLocalId:b,limit:1}),r=t?.data||t||[]
|
|
2612
2624
|
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
|
|
2613
|
-
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+""}),
|
|
2625
|
+
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+""}),g.incrementCounter("request_operations_errors",1),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
2614
2626
|
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"
|
|
2615
2627
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2616
2628
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClient=void 0
|
|
@@ -2727,17 +2739,17 @@ var t={}
|
|
|
2727
2739
|
if(null!=e)for(var r=s(e),n=0;n<r.length;n++)"default"!==r[n]&&i(t,e,r[n])
|
|
2728
2740
|
return a(t,e),t})
|
|
2729
2741
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileBlame=async function(e,t,s,i,a){const c=i.child({tool:"file_blame"}),p=Date.now()
|
|
2730
|
-
try{const{path:i,lines:
|
|
2731
|
-
c.info("Processing blame request",{filePath:i,lines:
|
|
2742
|
+
try{const{path:i,lines:m,branch:g}=e
|
|
2743
|
+
c.info("Processing blame request",{filePath:i,lines:m,branch:g})
|
|
2732
2744
|
const f=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,y=d.isAbsolute(i)?i:d.join(f,i),w=d.relative(f,y)
|
|
2733
2745
|
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
|
|
2734
2746
|
if(/^\d+$/.test(e)){const t=parseInt(e,10)
|
|
2735
2747
|
return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
|
|
2736
2748
|
if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
|
|
2737
2749
|
if(e.match(/^(\d+(?:,\d+)+)$/)){const t=e.split(",").map((e=>parseInt(e,10)))
|
|
2738
|
-
return{start:Math.min(...t),end:Math.max(...t)}}return null}(
|
|
2750
|
+
return{start:Math.min(...t),end:Math.max(...t)}}return null}(m),I=["blame","--porcelain"]
|
|
2739
2751
|
let k
|
|
2740
|
-
b&&I.push(`-L${b.start},${b.end}`),
|
|
2752
|
+
b&&I.push(`-L${b.start},${b.end}`),g&&I.push(g),I.push("--",w),c.debug("Executing git blame",{args:I})
|
|
2741
2753
|
try{if(!t.git)throw Error("Git context not available")
|
|
2742
2754
|
k=await t.git.raw(I)}catch(e){const t=(0,h.getErrorMessage)(e)
|
|
2743
2755
|
return c.error("Git blame failed",{error:t}),{content:[{type:"text",text:"\u274c Git blame failed: "+t}],isError:!0}}const v=function(e){const t=[],r=e.split("\n")
|
|
@@ -2936,18 +2948,18 @@ const n=a.getRequestClient(),s=a.getTaskClient(),[c,l]=await Promise.all([n.getR
|
|
|
2936
2948
|
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"})
|
|
2937
2949
|
const h=(0,o.extractDataFromResponse)(c,{logger:d,operationName:"getRequestInformation",throwOnNoData:!0}),p="data"in h?h.data:h
|
|
2938
2950
|
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"})
|
|
2939
|
-
const
|
|
2940
|
-
d.info(`Successfully extracted ${
|
|
2941
|
-
const
|
|
2942
|
-
|
|
2943
|
-
t in
|
|
2951
|
+
const m=(0,o.extractArrayFromResponse)(l,{logger:d,operationName:"listTasksForRequest",defaultValue:[]})
|
|
2952
|
+
d.info(`Successfully extracted ${m.length} tasks using data extraction utility`)
|
|
2953
|
+
const g={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:m.length}
|
|
2954
|
+
m.forEach((e=>{const t=e.status
|
|
2955
|
+
t in g&&g[t]++}))
|
|
2944
2956
|
const f=p.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_verified:0,total:f.length}
|
|
2945
2957
|
f.forEach((e=>{const t=e.status||"unverified"
|
|
2946
2958
|
t in y&&y[t]++}))
|
|
2947
2959
|
let w=p.testVerification||null
|
|
2948
2960
|
const b=p.title,I=p.type
|
|
2949
|
-
let k=`# ${"feature"===I?"Feature":"quick-edit"===I?"Quick Edit":"Bug Fix"} Request: ${b} (${t})\nStatus: ${p.status}\nCreated: ${new Date(p.createdAt).toLocaleString()}\nUpdated: ${new Date(p.updatedAt).toLocaleString()}\n\n## Description\n${p.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${
|
|
2950
|
-
return k+=`\n## Task Status\n- Pending: ${
|
|
2961
|
+
let k=`# ${"feature"===I?"Feature":"quick-edit"===I?"Quick Edit":"Bug Fix"} Request: ${b} (${t})\nStatus: ${p.status}\nCreated: ${new Date(p.createdAt).toLocaleString()}\nUpdated: ${new Date(p.updatedAt).toLocaleString()}\n\n## Description\n${p.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${g.completed}/${g.total} completed (${Math.round(g.completed/g.total*100)||0}%)\n- Acceptance Criteria: ${y.verified}/${y.total} verified (${Math.round(y.verified/y.total*100)||0}%)\n`
|
|
2962
|
+
return k+=`\n## Task Status\n- Pending: ${g.pending}\n- In Progress: ${g.in_progress}\n- Blocked: ${g.blocked}\n- Ready for Review: ${g.ready_for_review}\n- Completed: ${g.completed}\n- Reverted: ${g.reverted}\n`,k+="\n## Tasks\n",0===m.length?k+="No tasks found for this request.\n":m.forEach((e=>{k+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${m.length} tasks`),k+="\n## Acceptance Criteria\n",k+=(0,i.formatCriteriaWithHashes)(f)+"\n","ready_for_review"===p.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`})))),p.recentActivity&&Array.isArray(p.recentActivity)&&(k+="\n## Recent Activity\n",p.recentActivity.slice(0,5).forEach((e=>{const t=new Date(e.timestamp).toLocaleString()
|
|
2951
2963
|
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}}}
|
|
2952
2964
|
const r=t(9860),n=t(5674),o=t(2960),s=t(8824),i=t(5454)},5454(e,exports){"use strict"
|
|
2953
2965
|
function t(e,t){let r=0
|
|
@@ -2987,8 +2999,8 @@ if(c.incrementCounter("document_operations_total",1,{operation:"list-annotations
|
|
|
2987
2999
|
let r=`## Annotations on ${h} (${t.length})\n\n`
|
|
2988
3000
|
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`
|
|
2989
3001
|
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")
|
|
2990
|
-
const e=o.selectedText,t=o.body,{prefixContext:r,suffixContext:n,lineHint:a}=o,l=i.getDocumentClient(),p=d?"agent":void 0,
|
|
2991
|
-
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:** ${
|
|
3002
|
+
const e=o.selectedText,t=o.body,{prefixContext:r,suffixContext:n,lineHint:a}=o,l=i.getDocumentClient(),p=d?"agent":void 0,m=d?.sessionId,g=await l.createAnnotation(h,{selectedText:e,prefixContext:r,suffixContext:n,lineHint:a,body:t,createdByAgent:p,createdBySessionId:m})
|
|
3003
|
+
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:** ${g.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")
|
|
2992
3004
|
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})
|
|
2993
3005
|
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")
|
|
2994
3006
|
const e=o.annotationId,t=i.getDocumentClient()
|
|
@@ -3016,7 +3028,7 @@ return{isOffline:this.isInOfflineMode(),consecutiveFailures:e.consecutiveFailure
|
|
|
3016
3028
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3017
3029
|
const r=t(6183),n=t(2965)
|
|
3018
3030
|
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"
|
|
3019
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const p=l.child({tool:"complete_request"}),
|
|
3031
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const p=l.child({tool:"complete_request"}),m=d.startTimer("tool_execution_time")
|
|
3020
3032
|
try{const{requestId:n,summary:o}=e
|
|
3021
3033
|
if(!n)throw(0,r.createValidationError)("Request ID is required")
|
|
3022
3034
|
if(!o)throw(0,r.createValidationError)("Summary is required")
|
|
@@ -3025,18 +3037,18 @@ const l=h?.sessionId
|
|
|
3025
3037
|
let d
|
|
3026
3038
|
try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:l})
|
|
3027
3039
|
d=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3028
|
-
return p.error("Server validation failed",{requestId:n,error:t}),
|
|
3029
|
-
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`}))),
|
|
3030
|
-
let
|
|
3040
|
+
return p.error("Server validation failed",{requestId:n,error:t}),m({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`
|
|
3041
|
+
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`}))),m({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}const u=c.getRequestClient()
|
|
3042
|
+
let g,f="auto-test-then-merge"===d.completionMode,y=null
|
|
3031
3043
|
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=>(p.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
|
|
3032
3044
|
if(i&&"passed"===i.status&&i.commitSha){let e=null
|
|
3033
3045
|
if(r&&r.ok){const t=await r.json()
|
|
3034
|
-
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)}`,
|
|
3035
|
-
try{await u.updateRequest(n,{status:w,completionSummary:o,...
|
|
3036
|
-
return
|
|
3046
|
+
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)}`,g=i.id,p.info("Skip-if-fresh: SHA match, bypassing ready_for_review",{requestId:n,runId:i.id,sha:e}))}}catch(e){p.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"
|
|
3047
|
+
try{await u.updateRequest(n,{status:w,completionSummary:o,...g?{skippedTestRunId:g}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3048
|
+
return m({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let b
|
|
3037
3049
|
try{b=await u.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3038
|
-
return
|
|
3039
|
-
if(
|
|
3050
|
+
return m({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const I=b?.acceptanceCriteria||[]
|
|
3051
|
+
if(m({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.`}]}
|
|
3040
3052
|
const k=y?`\n\n_Skipped re-running tests: ${y}._\n`:""
|
|
3041
3053
|
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=""
|
|
3042
3054
|
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+"",p.error("Complete request failed",{error:s,details:i})
|
|
@@ -3067,7 +3079,7 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3067
3079
|
var t={}
|
|
3068
3080
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3069
3081
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3070
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDeleteFiles=async function(e,r,n,o,s,i){const
|
|
3082
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDeleteFiles=async function(e,r,n,o,s,i){const g=o.child({tool:"delete_files"}),f=Date.now()
|
|
3071
3083
|
let y,w,b=c.FileOperationPhase.VALIDATION
|
|
3072
3084
|
const I={toolName:"delete-files",operationName:"delete",fileOperationPhase:c.FileOperationPhase.FILE_WRITE,recordType:"delete-files",metricsPrefix:"delete_files",successMessage:"Successfully deleted files",failureMessage:"Failed to delete files"}
|
|
3073
3085
|
try{const d=n.getTaskClient(),k=n.getToolRecordClient(),v=n.getRequestClient(),C=e,{paths:_,operations:E,comment:S}=C,{enforceActiveTask:q}=await Promise.resolve().then(t.bind(t,3451)),T=await q(r,n,o,e.taskId)
|
|
@@ -3080,42 +3092,42 @@ P=E.map((e=>{if(e.path)return{type:"file",target:e.path}
|
|
|
3080
3092
|
if(e.documentId)return{type:"document",target:e.documentId}
|
|
3081
3093
|
throw Error("Invalid operation: neither path nor documentId specified")}))}if(0===P.length)throw Error("At least one file or document must be specified for deletion")
|
|
3082
3094
|
const R=P.filter((e=>"file"===e.type)),M=P.filter((e=>"document"===e.type)),$=P.length
|
|
3083
|
-
|
|
3095
|
+
g.info("Starting mixed file and document deletion operation",{taskId:x,totalOperations:P.length,fileOperations:R.length,documentOperations:M.length,comment:S}),c.validateTaskIdFormat(x,g,s,I.metricsPrefix)
|
|
3084
3096
|
const j=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3085
|
-
|
|
3097
|
+
g.info("Initial branch context",{initialBranch:j.branch,initialRequestId:j.requestId,isMain:j.isMain})
|
|
3086
3098
|
const O=[]
|
|
3087
3099
|
for(const e of R){const{normalizedPath:t,fullPath:n}=c.validateAndNormalizePath(e.target,r)
|
|
3088
3100
|
O.push({normalized:t,full:n})}b=c.FileOperationPhase.TASK_VALIDATION,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3089
|
-
const D=O.length>0?O[0].normalized:"document_operations",A=await c.validateTaskId(x,D,d,
|
|
3090
|
-
z.taskPromoted&&
|
|
3091
|
-
const L=await c.ensureCorrectWorkspaceContext({taskPromoted:z.taskPromoted,requestId:F,context:r,operation:"delete-files",logger:
|
|
3101
|
+
const D=O.length>0?O[0].normalized:"document_operations",A=await c.validateTaskId(x,D,d,g,s,I.metricsPrefix),F=A?.requestId,N=await c.validateWorkItemStates(x,D,d,v,r,g,s,I.metricsPrefix),z=await c.autoPromoteTaskStatus(x,A.status,F,N.request?.status,D,d,v,g,s,I.metricsPrefix)
|
|
3102
|
+
z.taskPromoted&&g.info(`Auto-promoted task ${x} (${A.title||"Untitled"}) to in_progress for mixed operations`,{taskId:x,taskTitle:A.title,previousStatus:A.status,newStatus:z.newTaskStatus,totalOperations:P.length,fileOperations:R.length,documentOperations:M.length}),z.requestPromoted&&g.info(`Auto-promoted request ${F} to in_progress for file operations`,{requestId:F,previousStatus:N.request?.status,newStatus:z.newRequestStatus,triggeringTaskId:x})
|
|
3103
|
+
const L=await c.ensureCorrectWorkspaceContext({taskPromoted:z.taskPromoted,requestId:F,context:r,operation:"delete-files",logger:g,metrics:s,metricsPrefix:I.metricsPrefix})
|
|
3092
3104
|
if(!L.success)throw Error(L.error)
|
|
3093
3105
|
let H={hadUserMods:!1,userModsCommitHash:void 0}
|
|
3094
|
-
if(r.git)try{
|
|
3095
|
-
const e=await(0,u.commitUserChangesBeforeToolOperation)(r.git,"delete-files",{requestId:F,taskId:x,workspaceManager:r.workspaceManager},
|
|
3096
|
-
e.userChangesCommitted&&(
|
|
3097
|
-
const{toolRecordId:B,localToolRecordId:U}=await c.createFileOperationRecords(x,F,r.projectId,I.recordType,D,{totalOperations:P.length,fileOperations:R.length,documentOperations:M.length,filePaths:O.map((e=>e.normalized)),documentIds:M.map((e=>e.target)),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},d,k,
|
|
3106
|
+
if(r.git)try{g.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
|
|
3107
|
+
const e=await(0,u.commitUserChangesBeforeToolOperation)(r.git,"delete-files",{requestId:F,taskId:x,workspaceManager:r.workspaceManager},g,s)
|
|
3108
|
+
e.userChangesCommitted&&(g.debug("[DELETE-FILES] User changes committed before mixed delete operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),g.info("User changes committed before mixed delete-files operation",{taskId:x,totalOperations:P.length,fileOperations:R.length,documentOperations:M.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),H={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){g.debug("[DELETE-FILES] Pre-tool commit failed, continuing with mixed delete operations",{error:e instanceof Error?e.message:e+""}),g.warn("Pre-tool user changes commit failed, continuing with mixed delete operation",{taskId:x,totalOperations:P.length,fileOperations:R.length,documentOperations:M.length,error:e instanceof Error?e.message:e+""})}g.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:P.length,fileDeletes:R.length,documentDeletes:M.length}),b=c.FileOperationPhase.RECORD_CREATION,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3109
|
+
const{toolRecordId:B,localToolRecordId:U}=await c.createFileOperationRecords(x,F,r.projectId,I.recordType,D,{totalOperations:P.length,fileOperations:R.length,documentOperations:M.length,filePaths:O.map((e=>e.normalized)),documentIds:M.map((e=>e.target)),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},d,k,g,s,I.metricsPrefix,i)
|
|
3098
3110
|
y=B,w=B,b=I.fileOperationPhase,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3099
3111
|
const G=[]
|
|
3100
3112
|
let W=0
|
|
3101
3113
|
M.length>0&&n.setProjectId(r.projectId)
|
|
3102
3114
|
for(let e=0;e<O.length;e++){const t=O[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3103
3115
|
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)
|
|
3104
|
-
await a.default.unlink(t.full),r.success=!0,W++,
|
|
3116
|
+
await a.default.unlink(t.full),r.success=!0,W++,g.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,m.getErrorMessage)(e),g.warn("Failed to delete file "+t.normalized,{error:r.error})}G.push(r)}const V=M.length>0?n.getDocumentClient():null
|
|
3105
3117
|
for(const e of M){const t=e.target,r={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3106
3118
|
try{let e
|
|
3107
|
-
try{if(e=await V.getDocument(t),r.filename=e.filename,
|
|
3108
|
-
throw e}try{await(0,p.ensureDocumentNotLocked)(t,n,
|
|
3109
|
-
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,
|
|
3110
|
-
r.success=!0,r.filename=o.filename,W++,
|
|
3119
|
+
try{if(e=await V.getDocument(t),r.filename=e.filename,g.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,g,s,"delete-document")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
|
|
3120
|
+
throw e}try{await(0,p.ensureDocumentNotLocked)(t,n,g,s,"delete-document-archive")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
|
|
3121
|
+
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,m.getErrorMessage)(e)}`)}const o=await V.archiveDocument(t)
|
|
3122
|
+
r.success=!0,r.filename=o.filename,W++,g.info("Document archived successfully",{documentId:o.id,filename:o.filename,archivedAt:o.archived_at})}catch(e){r.error=(0,m.getErrorMessage)(e),g.warn("Failed to delete document "+t,{error:r.error})}G.push(r)}const K=Date.now()-f
|
|
3111
3123
|
s.recordValue("delete_files_time",K),s.incrementCounter("delete_files_operations_total",$),s.incrementCounter("delete_files_operations_success",W),s.incrementCounter("delete_files_operations_failed",$-W),s.incrementCounter("delete_files_file_operations",R.length),s.incrementCounter("delete_files_document_operations",M.length),W===$?s.incrementCounter("delete_files_success",1):W>0?s.incrementCounter("delete_files_partial_success",1):s.incrementCounter("delete_files_total_failure",1)
|
|
3112
3124
|
let J=null
|
|
3113
3125
|
if(W>0){b=c.FileOperationPhase.GIT_COMMIT,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3114
3126
|
const e=G.filter((e=>e.success)),t=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
|
|
3115
3127
|
let o
|
|
3116
|
-
o=t>0&&n>0?`Delete ${t} files and ${n} documents - ${S}`:t>0?1===t?"Delete file - "+S:`Delete ${t} files - ${S}`:1===n?"Delete document - "+S:`Delete ${n} documents - ${S}`,J=await c.commitToGit(x,D,B,U,o,r,
|
|
3128
|
+
o=t>0&&n>0?`Delete ${t} files and ${n} documents - ${S}`:t>0?1===t?"Delete file - "+S:`Delete ${t} files - ${S}`:1===n?"Delete document - "+S:`Delete ${n} documents - ${S}`,J=await c.commitToGit(x,D,B,U,o,r,g,s,I.metricsPrefix)}b=c.FileOperationPhase.RECORD_UPDATE_SUCCESS,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3117
3129
|
const Q=G.filter((e=>e.success)),Y=G.filter((e=>!e.success))
|
|
3118
|
-
await c.updateFileOperationRecords(x,y,w,D,I.recordType,W===$?`Successfully deleted all ${$} operations`:`Deleted ${W}/${$} operations successfully`,{status:W===$?"completed":"partial_success",commitHash:J?.commitHash,previousCommitHash:J?.previousCommitHash,totalOperations:$,fileOperations:R.length,documentOperations:M.length,successCount:W,failureCount:$-W,successfulOperations:Q.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:Y.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},W===$?`Successfully deleted all ${$} operations`:`Deleted ${W}/${$} operations successfully`,d,k,
|
|
3130
|
+
await c.updateFileOperationRecords(x,y,w,D,I.recordType,W===$?`Successfully deleted all ${$} operations`:`Deleted ${W}/${$} operations successfully`,{status:W===$?"completed":"partial_success",commitHash:J?.commitHash,previousCommitHash:J?.previousCommitHash,totalOperations:$,fileOperations:R.length,documentOperations:M.length,successCount:W,failureCount:$-W,successfulOperations:Q.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:Y.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},W===$?`Successfully deleted all ${$} operations`:`Deleted ${W}/${$} operations successfully`,d,k,g,s,I.metricsPrefix)
|
|
3119
3131
|
const Z=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3120
3132
|
let X=""
|
|
3121
3133
|
if(W===$){const e=Q.filter((e=>"file"===e.type)).length,t=Q.filter((e=>"document"===e.type)).length
|
|
@@ -3123,11 +3135,11 @@ X=e>0&&t>0?`Successfully deleted ${e} files and ${t} documents`:e>0?`Successfull
|
|
|
3123
3135
|
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})`
|
|
3124
3136
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
|
|
3125
3137
|
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
|
|
3126
|
-
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,
|
|
3127
|
-
if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),
|
|
3138
|
+
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,m.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,m.getErrorMessage)(t)})}catch(t){g.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
|
|
3139
|
+
if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),g.error("Error in delete-files operation:",{error:(0,m.getErrorMessage)(t),time:o}),(y||w)&&e.taskId){b=c.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
3128
3140
|
try{const r=n.getTaskClient(),o=n.getToolRecordClient()
|
|
3129
|
-
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,
|
|
3130
|
-
const a=i(t(1943)),c=s(t(5967)),l=t(9860),d=t(1569),u=t(7478),h=t(5003),p=t(9949),
|
|
3141
|
+
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,m.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,g,s,I.metricsPrefix)}catch(t){g.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,g,s,e,I)}}
|
|
3142
|
+
const a=i(t(1943)),c=s(t(5967)),l=t(9860),d=t(1569),u=t(7478),h=t(5003),p=t(9949),m=t(8824)},5997(e,exports,t){"use strict"
|
|
3131
3143
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3132
3144
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3133
3145
|
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=[]
|
|
@@ -3206,10 +3218,10 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
|
3206
3218
|
const r=t(6183),n=t(405)
|
|
3207
3219
|
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"
|
|
3208
3220
|
module.exports=require("events")},6285(e,exports,t){"use strict"
|
|
3209
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,d,u,h,p,
|
|
3221
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,d,u,h,p,m){const g=u.child({tool:"specialist_ops"}),f=h.startTimer("tool_execution_time")
|
|
3210
3222
|
try{const u=e,{operation:y,sessionId:w}=u
|
|
3211
3223
|
let b
|
|
3212
|
-
switch(
|
|
3224
|
+
switch(g.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=m?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3213
3225
|
if(r&&p){const t=await async function(e,t,r,o,s){o.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
|
|
3214
3226
|
const a=await(0,i.getServerUrl)(r,o)
|
|
3215
3227
|
if(a)try{const r=await fetch(a.replace(/\/$/,"")+"/session")
|
|
@@ -3223,31 +3235,31 @@ return"specialist"===t?.agentType&&"archived"!==t?.status}))
|
|
|
3223
3235
|
if(o.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
|
|
3224
3236
|
const p=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
|
|
3225
3237
|
return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
|
|
3226
|
-
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`+p}],isError:!0}}catch(e){return void o.warn("Pool limit check failed, allowing spawn",{error:(0,n.getErrorMessage)(e)})}}(r,e,d,
|
|
3238
|
+
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`+p}],isError:!0}}catch(e){return void o.warn("Pool limit check failed, allowing spawn",{error:(0,n.getErrorMessage)(e)})}}(r,e,d,g,p)
|
|
3227
3239
|
if(t){b=t
|
|
3228
3240
|
break}}let c=u.description||u.prompt.slice(0,60)
|
|
3229
3241
|
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`)
|
|
3230
|
-
if(r)try{const e=await(0,i.getServerUrl)(d,
|
|
3242
|
+
if(r)try{const e=await(0,i.getServerUrl)(d,g)
|
|
3231
3243
|
if(h(`serverUrl=${e}, parentId=${r}`),e){const t=await fetch(e.replace(/\/$/,"")+"/session")
|
|
3232
3244
|
if(h("session fetch status="+t.status),t.ok){const e=(await t.json()).filter((e=>(e.parentId||e.parentID)===r)).map((e=>e.title||""))
|
|
3233
3245
|
h(`siblings=${e.length}: ${e.join(", ")}`)
|
|
3234
3246
|
const n=(0,o.pickSpecialistName)(e)
|
|
3235
3247
|
c=n,h("picked name: "+n)}}else h("no serverUrl")}catch(e){h("error: "+(e instanceof Error?e.message:e+""))}else h("no parentId")
|
|
3236
|
-
b=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,
|
|
3237
|
-
break}case"follow-up":{const e=await(0,i.getServerUrl)(d,
|
|
3248
|
+
b=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,g,p,m)
|
|
3249
|
+
break}case"follow-up":{const e=await(0,i.getServerUrl)(d,g)
|
|
3238
3250
|
if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
|
|
3239
3251
|
if(t.ok){const e=await t.json(),r=e[w]?.type
|
|
3240
3252
|
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}
|
|
3241
|
-
break}}}catch{}b=await(0,s.handleContinue)(w,u.prompt,d,
|
|
3242
|
-
break}case"check-status":b=await(0,s.handleCheckStatus)(w,d,
|
|
3253
|
+
break}}}catch{}b=await(0,s.handleContinue)(w,u.prompt,d,g,p,"specialist",m)
|
|
3254
|
+
break}case"check-status":b=await(0,s.handleCheckStatus)(w,d,g,p)
|
|
3243
3255
|
break
|
|
3244
|
-
case"abort":if(b=await(0,s.handleAbort)(w,d,
|
|
3256
|
+
case"abort":if(b=await(0,s.handleAbort)(w,d,g),!b.isError&&p)try{const e=p.getCLISessionClient()
|
|
3245
3257
|
e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
|
|
3246
|
-
case"list":{const e=
|
|
3247
|
-
b=await(0,s.handleListSessions)(d,
|
|
3258
|
+
case"list":{const e=m?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3259
|
+
b=await(0,s.handleListSessions)(d,g,p,{activeOnly:u.activeOnly,requestId:u.requestId,limit:u.limit,agentType:"specialist",parentSessionId:e})
|
|
3248
3260
|
break}default:throw new r.ValidationError("Unknown operation: "+y)}f({success:!0}),h.incrementCounter(`specialist_ops_${y}_success`,1)
|
|
3249
3261
|
const I=l[y]??"specialist-delegate"
|
|
3250
|
-
return(0,c.withAlchemyKind)(b,I)}catch(e){return
|
|
3262
|
+
return(0,c.withAlchemyKind)(b,I)}catch(e){return g.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}}}
|
|
3251
3263
|
const r=t(9860),n=t(8824),o=t(9089),s=t(1725),i=t(7617),a=t(6688),c=t(2272),l={delegate:"specialist-delegate","follow-up":"specialist-follow-up","check-status":"specialist-check-status",abort:"specialist-abort",list:"specialist-list"}},6309(e,exports,t){"use strict"
|
|
3252
3264
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3253
3265
|
const r=t(6183),n=t(8184)
|
|
@@ -3266,16 +3278,16 @@ return o(t,e),t})
|
|
|
3266
3278
|
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")
|
|
3267
3279
|
try{const n=e,{requestId:l,reason:h,confirmDestructive:p}=n
|
|
3268
3280
|
if(s.info("Starting revert/cancel process",{requestId:l,reason:h}),!p)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}
|
|
3269
|
-
let
|
|
3281
|
+
let m
|
|
3270
3282
|
try{const e=await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/validate-revert`,{})
|
|
3271
|
-
|
|
3272
|
-
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:
|
|
3273
|
-
return
|
|
3274
|
-
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: ${
|
|
3283
|
+
m=e?.data||e}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3284
|
+
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:m.canRevert,operationType:m.operationType,mergeCommitHash:m.mergeCommitHash?.substring(0,8),reason:m.reason}),!m.canRevert){let e=`Cannot revert request ${l}: ${m.reason}\n`
|
|
3285
|
+
return m.lifoViolation?.blockingRequests?.length&&(e+="\n**Requests that must be reverted first (in reverse order):**\n",m.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"===m.operationType){s.info("Cancel operation \u2014 delegating to server",{requestId:l})
|
|
3286
|
+
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: ${m.tasksToUpdate.length} task(s) marked as canceled\nReason: ${h}`}]}}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3275
3287
|
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})
|
|
3276
3288
|
t.syncBranchState&&await t.syncBranchState()
|
|
3277
|
-
let m
|
|
3278
|
-
if(!
|
|
3289
|
+
let g=m.mergeCommitHash
|
|
3290
|
+
if(!g){s.info("No merge commit hash from server, searching git log",{requestId:l})
|
|
3279
3291
|
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(" ")
|
|
3280
3292
|
return-1===t?{hash:e,message:""}:{hash:e.substring(0,t),message:e.substring(t+1)}})):[],s=a.generateMergeMessagePatterns(e)
|
|
3281
3293
|
for(const e of s){let t
|
|
@@ -3283,14 +3295,14 @@ if(e.includes("\\")||e.includes(".*")){const r=RegExp(e,"i")
|
|
|
3283
3295
|
t=o.find((e=>r.test(e.message)))}else t=o.find((t=>t.message.includes(e)))
|
|
3284
3296
|
if(t)return{found:!0,commitHash:t.hash}}return{found:!1}}catch(t){return r.error("Failed to find merge commit",{requestId:e,error:(0,d.getErrorMessage)(t)}),{found:!1}}}(l,t,s)
|
|
3285
3297
|
if(!e.found||!e.commitHash)return u({success:!1,error:"merge_commit_not_found"}),{content:[{type:"text",text:"Could not find merge commit for request "+l}],isError:!0}
|
|
3286
|
-
|
|
3298
|
+
g=e.commitHash}const f=t.workspaceManager.getMainGit(),y=await a.getRepositoryStatus(f,s,o)
|
|
3287
3299
|
if(y.currentBranch!==y.defaultBranch){const e=await a.switchToBranch(f,y.defaultBranch||"main",s,o)
|
|
3288
3300
|
if(!e.success)return u({success:!1,error:"branch_switch_failed"}),{content:[{type:"text",text:"Failed to switch to main branch: "+e.message}],isError:!0}}let w
|
|
3289
|
-
try{s.info("Executing git revert",{mergeCommitHash:
|
|
3301
|
+
try{s.info("Executing git revert",{mergeCommitHash:g.substring(0,8)}),await f.raw(["revert","-m","1","--no-edit",g]),w=await(0,c.captureCommitHashRobustly)(f,s,"revert-request-"+l,3,150)
|
|
3290
3302
|
const e=await(0,c.verifyGitStateConsistency)(f,w,s,`revert-request-${l}-verification`)
|
|
3291
|
-
e.consistent||s.error("Git state inconsistency after revert",{issues:e.issues}),s.info("Git revert completed",{requestId:l,originalMergeCommit:
|
|
3292
|
-
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:
|
|
3293
|
-
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: ${
|
|
3303
|
+
e.consistent||s.error("Git state inconsistency after revert",{issues:e.issues}),s.info("Git revert completed",{requestId:l,originalMergeCommit:g.substring(0,8),revertCommitHash:w.substring(0,8)})}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3304
|
+
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:g})}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3305
|
+
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: ${m.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}
|
|
3294
3306
|
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}
|
|
3295
3307
|
if(t.projectId&&e.requestId)try{const o=r.getToolRecordClient()
|
|
3296
3308
|
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}}}
|
|
@@ -3305,15 +3317,15 @@ const s=[...t].sort(((e,t)=>"between"===e.type&&"between"===t.type?(t.afterLine|
|
|
|
3305
3317
|
for(const e of s){const t={type:e.type,line:e.line,afterLine:e.afterLine,beforeLine:e.beforeLine,success:!1}
|
|
3306
3318
|
try{let n
|
|
3307
3319
|
switch(e.type){case"before":if(void 0===e.line)throw Error("Line number is required for before insertion")
|
|
3308
|
-
n=(0,
|
|
3320
|
+
n=(0,g.insertBeforeLine)(r,e.line,e.content)
|
|
3309
3321
|
break
|
|
3310
3322
|
case"after":if(void 0===e.line)throw Error("Line number is required for after insertion")
|
|
3311
|
-
n=(0,
|
|
3323
|
+
n=(0,g.insertAfterLine)(r,e.line,e.content)
|
|
3312
3324
|
break
|
|
3313
3325
|
case"between":if(void 0===e.afterLine||void 0===e.beforeLine)throw Error("Both afterLine and beforeLine are required for between insertion")
|
|
3314
|
-
n=(0,
|
|
3326
|
+
n=(0,g.insertBetweenLines)(r,e.afterLine,e.beforeLine,e.content)
|
|
3315
3327
|
break
|
|
3316
|
-
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,
|
|
3328
|
+
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,m.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)
|
|
3317
3329
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3318
3330
|
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=[]
|
|
3319
3331
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3321,7 +3333,7 @@ return t},n(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3321
3333
|
var t={}
|
|
3322
3334
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3323
3335
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3324
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleInsertLines=async function(e,n,o,s,i,a,
|
|
3336
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleInsertLines=async function(e,n,o,s,i,a,g,f){const y=a.child({tool:"insert_lines"}),w=Date.now()
|
|
3325
3337
|
let b,I,k=l.FileOperationPhase.VALIDATION
|
|
3326
3338
|
const v={toolName:"insert-lines",operationName:"insert-lines",fileOperationPhase:l.FileOperationPhase.FILE_WRITE,recordType:"insert-lines",metricsPrefix:"insert_lines",successMessage:"Successfully inserted lines into files and documents",failureMessage:"Failed to insert lines into files and documents"}
|
|
3327
3339
|
try{const C=e,{operations:_,comment:E}=C,{enforceActiveTask:S}=await Promise.resolve().then(t.bind(t,3451)),q=await S(n,o,a)
|
|
@@ -3336,34 +3348,34 @@ R.push({type:"file",path:t,fullPath:r,insertions:e.insertions})}const M=[]
|
|
|
3336
3348
|
if(P.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3337
3349
|
for(const e of P)M.push({type:"document",documentId:e.documentId,insertions:e.insertions})
|
|
3338
3350
|
if(M.length>0&&n.apiClient){const e=M.map((e=>e.documentId))
|
|
3339
|
-
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,y,
|
|
3340
|
-
throw e}}k=l.FileOperationPhase.TASK_VALIDATION,
|
|
3341
|
-
const $=R.length>0?R[0].path:"document-operation",j=await l.validateTaskId(T,$,o,y,
|
|
3351
|
+
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,y,g,"insert-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3352
|
+
throw e}}k=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3353
|
+
const $=R.length>0?R[0].path:"document-operation",j=await l.validateTaskId(T,$,o,y,g,v.metricsPrefix),O=j?.requestId
|
|
3342
3354
|
let D=null
|
|
3343
|
-
R.length>0&&O&&(D=await l.validateWorkItemStates(T,R[0].path,o,i,n,y,
|
|
3355
|
+
R.length>0&&O&&(D=await l.validateWorkItemStates(T,R[0].path,o,i,n,y,g,v.metricsPrefix))
|
|
3344
3356
|
let A={taskPromoted:!1,requestPromoted:!1}
|
|
3345
|
-
R.length>0&&O&&D&&(A=await l.autoPromoteTaskStatus(T,j.status,O,D.request?.status,R[0].path,o,i,y,
|
|
3346
|
-
const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:O,context:n,operation:"insert-lines",logger:y,metrics:
|
|
3357
|
+
R.length>0&&O&&D&&(A=await l.autoPromoteTaskStatus(T,j.status,O,D.request?.status,R[0].path,o,i,y,g,v.metricsPrefix),A.taskPromoted&&y.info("Auto-promoted task to in_progress for insert-lines operation",{taskId:T,requestId:O,previousStatus:j.status,newStatus:A.newTaskStatus,triggeringOperation:"insert-lines"}))
|
|
3358
|
+
const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:O,context:n,operation:"insert-lines",logger:y,metrics:g,metricsPrefix:v.metricsPrefix})
|
|
3347
3359
|
if(!F.success)throw Error(F.error)
|
|
3348
3360
|
if(R.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:R.length,workspaceBasePath:n.workspaceManager?.getCurrentContext(n.currentSessionId).basePath})
|
|
3349
3361
|
for(let e=0;e<R.length;e++){const t=R[e],r=x[e],{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(r.path,n)
|
|
3350
|
-
R[e]={...t,path:o,fullPath:s}}}if(M.length>0&&O)try{await(0,u.validateRequestStatusForDocumentOperation)(O,i,y,
|
|
3351
|
-
throw e}k=l.FileOperationPhase.RECORD_CREATION,
|
|
3352
|
-
const N=[...R.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...M.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:z}=await l.createFileOperationRecords(T,O,n.projectId,v.recordType,$,{operationCount:_.length,fileOperations:R.length,documentOperations:M.length,operations:N,userComment:E},o,s,y,
|
|
3353
|
-
if(b=z,I=z,k=v.fileOperationPhase,
|
|
3354
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"insert-lines",{requestId:O,taskId:T,workspaceManager:n.workspaceManager},y,
|
|
3362
|
+
R[e]={...t,path:o,fullPath:s}}}if(M.length>0&&O)try{await(0,u.validateRequestStatusForDocumentOperation)(O,i,y,g,"insert-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3363
|
+
throw e}k=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3364
|
+
const N=[...R.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...M.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:z}=await l.createFileOperationRecords(T,O,n.projectId,v.recordType,$,{operationCount:_.length,fileOperations:R.length,documentOperations:M.length,operations:N,userComment:E},o,s,y,g,v.metricsPrefix,f)
|
|
3365
|
+
if(b=z,I=z,k=v.fileOperationPhase,g.incrementCounter("insert_lines_phase",1,{phase:k}),R.length>0&&n.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
|
|
3366
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"insert-lines",{requestId:O,taskId:T,workspaceManager:n.workspaceManager},y,g)
|
|
3355
3367
|
e.userChangesCommitted&&(y.debug("[INSERT-LINES] User changes committed before insert operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),y.info("User changes committed before insert-lines operation",{taskId:T,fileOperationsCount:R.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){y.debug("[INSERT-LINES] Pre-tool commit failed, continuing with insertions",{error:e instanceof Error?e.message:e+""}),y.warn("Pre-tool user changes commit failed, continuing with insert operation",{taskId:T,fileOperationsCount:R.length,error:e instanceof Error?e.message:e+""})}y.debug("[INSERT-LINES] Proceeding with file operations",{fileCount:R.length})
|
|
3356
3368
|
const L=[]
|
|
3357
3369
|
let H=0,B=0,U=0
|
|
3358
3370
|
for(const e of R){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3359
3371
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3360
3372
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.insertions)
|
|
3361
|
-
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,
|
|
3373
|
+
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,m.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 M){const t={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3362
3374
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3363
3375
|
t.filename=s?.filename
|
|
3364
3376
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
|
|
3365
|
-
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,
|
|
3366
|
-
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(T,R,L,U,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:
|
|
3377
|
+
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,m.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(M.length>0)try{for(const e of M){const t=L.find((t=>t.documentId===e.documentId))
|
|
3378
|
+
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(T,R,L,U,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:g,metricsPrefix:"insert_lines"},n),W=l.processMultiFileOperationResults(L,"successfulInsertions"),{successfulOperations:V,failedOperations:K,totalSuccessfulChanges:J,overallSuccess:Q,successfulFiles:Y,failedFiles:Z}=W
|
|
3367
3379
|
try{await s.updateToolRecord(I,{metadata:{path:R.length>0?R[0].path:"document:"+M[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"
|
|
3368
3380
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
3369
3381
|
e.permanentBranch||(X+=`**Branch:** \`${e.branchName}\`\n\n`)}if(X+="**Summary:**\n",X+=`- **Files processed:** ${V+K}\n`,X+=`- **Successful operations:** ${V}\n`,X+=`- **Failed operations:** ${K}\n`,X+=`- **Total insertions:** ${J} successful, ${H} failed\n`,X+=`- **Total Lines Added:** ${B}\n`,X+="\n",G.success&&G.commitHash&&(X+="**Git Commit:**\n",X+=`- **Commit Hash:** ${G.commitHash.substring(0,8)}\n`,X+=`- **Files Committed:** ${G.filesCommitted.length}\n`,G.previousCommitHash&&(X+=`- **Previous Commit:** ${G.previousCommitHash.substring(0,8)}\n`),X+="\n"),1===L.length){const e=L[0]
|
|
@@ -3374,17 +3386,17 @@ for(const e of L){if("file"===e.type?X+=`### File: ${e.path}\n`:(X+="### Documen
|
|
|
3374
3386
|
for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?`between lines ${t.afterLine} and ${t.beforeLine}`:`${t.type} line ${t.line}`
|
|
3375
3387
|
X+=` - ${t.type} insertion ${e}: ${t.error}\n`}}X+="\n"}}M.length>0&&(X+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3376
3388
|
const ee=Date.now()-w
|
|
3377
|
-
return y.info("Insert lines operation completed",{duration:ee,success:Q,totalOperations:L.length,successfulOperations:V,failedOperations:K}),
|
|
3378
|
-
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,
|
|
3379
|
-
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),
|
|
3389
|
+
return y.info("Insert lines operation completed",{duration:ee,success:Q,totalOperations:L.length,successfulOperations:V,failedOperations:K}),g.incrementCounter("insert_lines_total",1,{success:Q}),{content:[{type:"text",text:X}],isError:!Q}}catch(t){const r=Date.now()-w
|
|
3390
|
+
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,m.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return g.incrementCounter("insert_lines_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
3391
|
+
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),m=t(8824),g=t(3255)},6539(e,exports,t){"use strict"
|
|
3380
3392
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
|
|
3381
|
-
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),p=t(9884),
|
|
3393
|
+
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),p=t(9884),m=t(2968),g=t(922)
|
|
3382
3394
|
exports.ClientFactory=class{static async createClient(e,f,y,w={}){(f=f.child({component:"client-factory"})).info("Creating API client with components")
|
|
3383
3395
|
const b=w.tokenManager||new r.TokenManager(f,w.workingDir||process.cwd())
|
|
3384
3396
|
await b.initialize()
|
|
3385
3397
|
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})
|
|
3386
3398
|
I.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3387
|
-
const E=new
|
|
3399
|
+
const E=new m.TaskClient(e,f,y,_,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3388
3400
|
I.registerClient(E)
|
|
3389
3401
|
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})
|
|
3390
3402
|
I.registerClient(S),f.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
@@ -3392,7 +3404,7 @@ const q=new u.RequestClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts
|
|
|
3392
3404
|
I.registerClient(q),f.info("RequestClient post-constructor token: "+(q.getAuthToken()?"present":"missing"))
|
|
3393
3405
|
const T=new p.DocumentClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3394
3406
|
I.registerClient(T)
|
|
3395
|
-
const x=new
|
|
3407
|
+
const x=new g.ToolRecordClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3396
3408
|
I.registerClient(x)
|
|
3397
3409
|
const P=new d.ProxyClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3398
3410
|
if(I.registerClient(P),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
|
|
@@ -3412,8 +3424,8 @@ if(_)try{await _.connectStdio(),(0,a.isDebugToolsEnabled)()&&b.info("Connected s
|
|
|
3412
3424
|
throw b.error("Failed to connect stdio transport",{errorDetails:t}),e}else b.error("No global server instance available to connect transport")
|
|
3413
3425
|
return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3414
3426
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
3415
|
-
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),p=t(8824),
|
|
3416
|
-
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,
|
|
3427
|
+
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),p=t(8824),m=t(9939),g=t(7960),f=process.argv.slice(2),y=f[0]||process.cwd(),w=s.default.resolve(y)
|
|
3428
|
+
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,g.isDevBuild)()),console.error("isDebugToolsEnabled():",(0,a.isDebugToolsEnabled)()),console.error("===============================\n")
|
|
3417
3429
|
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)}))
|
|
3418
3430
|
const I=process.stdout.write
|
|
3419
3431
|
process.stdout.write=function(e,t,r){try{if("string"==typeof e)try{JSON.parse(e)}catch(t){return e.includes('"__message_type"')||(process.stderr.write("[STDOUT REDIRECTED]: "+e),r&&r()),!0}return"string"==typeof t&&"function"==typeof r?I.call(process.stdout,e,t,r):"function"==typeof t?I.call(process.stdout,e,void 0,t):I.call(process.stdout,e)}catch(e){return process.stderr.write("[STDOUT ERROR]: "+e),!0}},(0,a.isDebugToolsEnabled)()&&(b.info("Initialized stdout filtering to ensure only valid JSON is sent"),b.info("!!!MARKER!!! COMMAND-LINE ARGS:",{args:JSON.stringify(f)}),b.info("!!!MARKER!!! BASE DIRECTORY:",{baseDir:y}),b.info("!!!MARKER!!! ABSOLUTE BASE DIR:",{absBaseDir:w}),b.info("Working with base directory:",{absBaseDir:w}))
|
|
@@ -3431,8 +3443,8 @@ b.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(
|
|
|
3431
3443
|
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
|
|
3432
3444
|
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(b),n=await r.getInstallationConfig()
|
|
3433
3445
|
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"}()
|
|
3434
|
-
try{const e=await(0,
|
|
3435
|
-
e.errors.length>0&&b.warn("Some plugins failed to sync",{errors:e.errors}),await(0,
|
|
3446
|
+
try{const e=await(0,m.syncPluginsGlobal)((0,g.isDevBuild)(),b)
|
|
3447
|
+
e.errors.length>0&&b.warn("Some plugins failed to sync",{errors:e.errors}),await(0,m.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))
|
|
3436
3448
|
const e=await(0,i.createServer)(w,b,k,v)
|
|
3437
3449
|
_=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&b.info("MCP server created successfully")
|
|
3438
3450
|
const n=r()
|
|
@@ -3466,8 +3478,8 @@ async function r(e,t){let r=e
|
|
|
3466
3478
|
const n=[],o=[...t].sort(((e,t)=>{const r=e=>"number"==typeof e?e:Array.isArray(e)?Math.max(...e):e.end
|
|
3467
3479
|
return r(t.lines)-r(e.lines)}))
|
|
3468
3480
|
for(const e of o){const t={lines:e.lines,success:!1}
|
|
3469
|
-
try{const n=(0,
|
|
3470
|
-
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,
|
|
3481
|
+
try{const n=(0,g.replaceLines)(r,e.lines,e.content)
|
|
3482
|
+
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,m.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)
|
|
3471
3483
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3472
3484
|
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=[]
|
|
3473
3485
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3475,7 +3487,7 @@ return t},n(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3475
3487
|
var t={}
|
|
3476
3488
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3477
3489
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3478
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceLines=async function(e,n,o,s,i,a,
|
|
3490
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceLines=async function(e,n,o,s,i,a,g,y){const w=a.child({tool:"replace_lines"}),b=Date.now()
|
|
3479
3491
|
let I,k,v=l.FileOperationPhase.VALIDATION
|
|
3480
3492
|
const C={toolName:"replace-lines",operationName:"replace-lines",fileOperationPhase:l.FileOperationPhase.STRING_REPLACEMENT,recordType:"replace-lines",metricsPrefix:"replace_lines",successMessage:"Successfully replaced lines in files and documents",failureMessage:"Failed to replace lines in files and documents"}
|
|
3481
3493
|
try{const _=e,{operations:E,comment:S}=_,{enforceActiveTask:q}=await Promise.resolve().then(t.bind(t,3451)),T=await q(n,o,a,e.taskId)
|
|
@@ -3490,34 +3502,34 @@ M.push({type:"file",path:t,fullPath:r,replacements:e.replacements.map((e=>({line
|
|
|
3490
3502
|
if(R.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3491
3503
|
for(const e of R)$.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,f.parseLineSpec)(e.lines),content:e.content})))})
|
|
3492
3504
|
if($.length>0&&n.apiClient){const e=$.map((e=>e.documentId))
|
|
3493
|
-
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,w,
|
|
3494
|
-
throw e}}v=l.FileOperationPhase.TASK_VALIDATION,
|
|
3495
|
-
const j=M.length>0?M[0].path:"document-operation",O=await l.validateTaskId(x,j,o,w,
|
|
3505
|
+
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,w,g,"replace-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3506
|
+
throw e}}v=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3507
|
+
const j=M.length>0?M[0].path:"document-operation",O=await l.validateTaskId(x,j,o,w,g,C.metricsPrefix),D=O?.requestId
|
|
3496
3508
|
let A=null
|
|
3497
|
-
M.length>0&&D&&(A=await l.validateWorkItemStates(x,M[0].path,o,i,n,w,
|
|
3509
|
+
M.length>0&&D&&(A=await l.validateWorkItemStates(x,M[0].path,o,i,n,w,g,C.metricsPrefix))
|
|
3498
3510
|
let F={taskPromoted:!1,requestPromoted:!1}
|
|
3499
|
-
M.length>0&&D&&A&&(F=await l.autoPromoteTaskStatus(x,O.status,D,A.request?.status,M[0].path,o,i,w,
|
|
3500
|
-
const N=await l.ensureCorrectWorkspaceContext({taskPromoted:F.taskPromoted,requestId:D,context:n,operation:"replace-lines",logger:w,metrics:
|
|
3511
|
+
M.length>0&&D&&A&&(F=await l.autoPromoteTaskStatus(x,O.status,D,A.request?.status,M[0].path,o,i,w,g,C.metricsPrefix),F.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:x,requestId:D,previousStatus:O.status,newStatus:F.newTaskStatus,triggeringOperation:"replace-lines"}))
|
|
3512
|
+
const N=await l.ensureCorrectWorkspaceContext({taskPromoted:F.taskPromoted,requestId:D,context:n,operation:"replace-lines",logger:w,metrics:g,metricsPrefix:C.metricsPrefix})
|
|
3501
3513
|
if(!N.success)throw Error(N.error)
|
|
3502
3514
|
if(M.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:M.length,workspaceBasePath:n.workspaceManager?.getCurrentContext(n.currentSessionId).basePath})
|
|
3503
3515
|
for(let e=0;e<M.length;e++){const t=M[e],r=P[e],{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(r.path,n)
|
|
3504
|
-
M[e]={...t,path:o,fullPath:s}}}if($.length>0&&D)try{await(0,u.validateRequestStatusForDocumentOperation)(D,i,w,
|
|
3505
|
-
throw e}v=l.FileOperationPhase.RECORD_CREATION,
|
|
3506
|
-
const z=[...M.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...$.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:L}=await l.createFileOperationRecords(x,D,n.projectId,C.recordType,j,{operationCount:E.length,fileOperations:M.length,documentOperations:$.length,operations:z,userComment:S},o,s,w,
|
|
3507
|
-
if(I=L,k=L,v=C.fileOperationPhase,
|
|
3508
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"replace-lines",{requestId:D,taskId:x,workspaceManager:n.workspaceManager},w,
|
|
3516
|
+
M[e]={...t,path:o,fullPath:s}}}if($.length>0&&D)try{await(0,u.validateRequestStatusForDocumentOperation)(D,i,w,g,"replace-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3517
|
+
throw e}v=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3518
|
+
const z=[...M.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...$.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:L}=await l.createFileOperationRecords(x,D,n.projectId,C.recordType,j,{operationCount:E.length,fileOperations:M.length,documentOperations:$.length,operations:z,userComment:S},o,s,w,g,C.metricsPrefix,y)
|
|
3519
|
+
if(I=L,k=L,v=C.fileOperationPhase,g.incrementCounter("replace_lines_phase",1,{phase:v}),M.length>0&&n.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
|
|
3520
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"replace-lines",{requestId:D,taskId:x,workspaceManager:n.workspaceManager},w,g)
|
|
3509
3521
|
e.userChangesCommitted&&(w.debug("[REPLACE-LINES] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before replace-lines operation",{taskId:x,fileOperationsCount:M.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[REPLACE-LINES] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:x,fileOperationsCount:M.length,error:e instanceof Error?e.message:e+""})}w.debug("[REPLACE-LINES] Proceeding with file operations",{fileCount:M.length})
|
|
3510
3522
|
const H=[]
|
|
3511
3523
|
let B=0,U=0,G=0,W=0
|
|
3512
3524
|
for(const e of M){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3513
3525
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3514
3526
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.replacements)
|
|
3515
|
-
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,
|
|
3527
|
+
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,m.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 $){const t={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3516
3528
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3517
3529
|
t.filename=s?.filename
|
|
3518
3530
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
|
|
3519
|
-
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,
|
|
3520
|
-
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(x,M,H,W,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:
|
|
3531
|
+
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,m.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($.length>0)try{for(const e of $){const t=H.find((t=>t.documentId===e.documentId))
|
|
3532
|
+
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(x,M,H,W,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:g,metricsPrefix:"replace_lines"},n),K=l.processMultiFileOperationResults(H,"successfulReplacements"),{successfulOperations:J,failedOperations:Q,totalSuccessfulChanges:Y,overallSuccess:Z,successfulFiles:X,failedFiles:ee}=K
|
|
3521
3533
|
try{await s.updateToolRecord(k,{metadata:{path:M.length>0?M[0].path:"document:"+$[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,...M.length>0&&V.success&&V.commitHash&&{commitHash:V.commitHash,previousCommitHash:V.previousCommitHash||void 0}},note:Z?`Line replacement completed: ${J}/${H.length} operations successful${M.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"
|
|
3522
3534
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
3523
3535
|
e.permanentBranch||(te+=`**Branch:** \`${e.branchName}\`\n\n`)}if(te+="**Summary:**\n",te+=`- **Files processed:** ${J+Q}\n`,te+=`- **Successful operations:** ${J}\n`,te+=`- **Failed operations:** ${Q}\n`,te+=`- **Total replacements:** ${Y} successful, ${B} failed\n`,te+=`- **Total Lines Replaced:** ${U}\n`,G>0&&(te+=`- **Total Lines Added:** ${G}\n`),te+="\n",V.success&&V.commitHash&&(te+="**Git Commit:**\n",te+=`- **Commit Hash:** ${V.commitHash.substring(0,8)}\n`,te+=`- **Files Committed:** ${V.filesCommitted.length}\n`,V.previousCommitHash&&(te+=`- **Previous Commit:** ${V.previousCommitHash.substring(0,8)}\n`),te+="\n"),1===H.length){const e=H[0]
|
|
@@ -3526,18 +3538,18 @@ for(const t of e.replacements.filter((e=>!e.success)))te+=`- Replace ${"number"=
|
|
|
3526
3538
|
for(const e of H){if("file"===e.type?te+=`### File: ${e.path}\n`:(te+="### Document: "+e.documentId,e.filename&&(te+=` (${e.filename})`),te+="\n"),te+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error&&(te+=`- **Error:** ${e.error}\n`),te+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(te+=`, ${e.failedReplacements} failed`),te+="\n",te+=`- **Lines Replaced:** ${e.totalLinesReplaced}\n`,e.totalLinesAdded>0&&(te+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.replacements.some((e=>!e.success))){te+="- **Failed Replacement Details:**\n"
|
|
3527
3539
|
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"}}$.length>0&&(te+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3528
3540
|
const re=Date.now()-b
|
|
3529
|
-
return w.info("Replace lines operation completed",{duration:re,success:Z,totalOperations:H.length,successfulOperations:J,failedOperations:Q}),
|
|
3530
|
-
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,
|
|
3531
|
-
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),
|
|
3541
|
+
return w.info("Replace lines operation completed",{duration:re,success:Z,totalOperations:H.length,successfulOperations:J,failedOperations:Q}),g.incrementCounter("replace_lines_total",1,{success:Z}),{content:[{type:"text",text:te}],isError:!Z}}catch(t){const r=Date.now()-b
|
|
3542
|
+
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,m.getErrorMessage)(t),phase:v,duration:r,userComment:e?.comment},note:"Line replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return g.incrementCounter("replace_lines_errors",1,{phase:v}),{content:[{type:"text",text:"\u274c **Replace Lines Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
3543
|
+
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),m=t(8824),g=t(3255),f=t(9470)},6656(e,exports,t){"use strict"
|
|
3532
3544
|
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"})
|
|
3533
3545
|
try{const s=t.projectId
|
|
3534
3546
|
if(!s)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
|
|
3535
3547
|
const i=e.name.replace(/\.md$/i,""),a=`${d.filenamePrefix}${i}.md`,l=o.getDocumentClient(),p=await l.listDocuments({type:d.docType,filename:a,limit:1,offset:0})
|
|
3536
3548
|
if(p&&p.length>0)return{content:[{type:"text",text:`\u274c A ${d.label} with filename "${a}" already exists (${p[0].localId||p[0].id}). Choose a different name.`}],isError:!0}
|
|
3537
|
-
const
|
|
3549
|
+
const m=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,g=await l.createDocument(void 0,{filename:a,content:e.content,type:d.docType,...m&&{metadata:m},...c&&{cliOrigin:c}}),f=g.localId||g.id,y=g.id
|
|
3538
3550
|
let w=!1
|
|
3539
3551
|
if(d.canBeActivePlan)try{const e=o.getProjectClient(),t=await e.getProject(s)
|
|
3540
|
-
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(
|
|
3552
|
+
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(g.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}}}
|
|
3541
3553
|
const r=t(8824),n=t(3416)},6688(e,exports,t){"use strict"
|
|
3542
3554
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
|
|
3543
3555
|
const r=t(9896),n=t(6928),o=t(3545)
|
|
@@ -3593,18 +3605,18 @@ var t={}
|
|
|
3593
3605
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3594
3606
|
return o(t,e),t})
|
|
3595
3607
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTaskFileHistory=async function(e,t,r,n,o){const s=n.child({tool:"task_file_history"}),p=o.startTimer("tool_execution_time")
|
|
3596
|
-
try{const{taskId:
|
|
3597
|
-
if(!
|
|
3598
|
-
if(!(0,h.isTaskRef)(
|
|
3599
|
-
s.info("Getting file changes for task "+
|
|
3608
|
+
try{const{taskId:m,showDiff:g=!1}=e
|
|
3609
|
+
if(!m)throw(0,i.createValidationError)("Task ID is required")
|
|
3610
|
+
if(!(0,h.isTaskRef)(m))throw(0,i.createValidationError)(`Invalid task ID format: ${m}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
|
|
3611
|
+
s.info("Getting file changes for task "+m,{showDiff:g})
|
|
3600
3612
|
const f=r.getTaskClient(),y=r.getToolRecordClient(),w=t.projectId
|
|
3601
3613
|
let b
|
|
3602
3614
|
r.setProjectId(w)
|
|
3603
|
-
try{const P=await f.getTask(
|
|
3604
|
-
s.info("Raw task response data",{responseDataType:typeof P,isArray:Array.isArray(P),hasData:null!=P,properties:P&&"object"==typeof P?Object.keys(P):[]}),b=(0,l.extractDataFromResponse)(P,{logger:s,operationName:"getTask",defaultValue:{id:
|
|
3605
|
-
try{const M=await y.getToolRecordsByTaskId(
|
|
3606
|
-
if(s.info("Raw records response data",{responseDataType:typeof M,isArray:Array.isArray(M),hasData:null!=M,properties:M&&"object"==typeof M?Object.keys(M):[]}),I=(0,l.extractArrayFromResponse)(M,{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 ${
|
|
3607
|
-
I.forEach((e=>{$[e.type]=($[e.type]||0)+1})),s.info("Record type distribution:",$)}}catch(j){s.warn("Error fetching records for task "+
|
|
3615
|
+
try{const P=await f.getTask(m)
|
|
3616
|
+
s.info("Raw task response data",{responseDataType:typeof P,isArray:Array.isArray(P),hasData:null!=P,properties:P&&"object"==typeof P?Object.keys(P):[]}),b=(0,l.extractDataFromResponse)(P,{logger:s,operationName:"getTask",defaultValue:{id:m,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:m,title:"Unknown Task",status:"unknown",description:"No description available"}}let I=[]
|
|
3617
|
+
try{const M=await y.getToolRecordsByTaskId(m)
|
|
3618
|
+
if(s.info("Raw records response data",{responseDataType:typeof M,isArray:Array.isArray(M),hasData:null!=M,properties:M&&"object"==typeof M?Object.keys(M):[]}),I=(0,l.extractArrayFromResponse)(M,{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 ${m}`),I.length>0){const $={}
|
|
3619
|
+
I.forEach((e=>{$[e.type]=($[e.type]||0)+1})),s.info("Record type distribution:",$)}}catch(j){s.warn("Error fetching records for task "+m,{error:(0,u.getErrorMessage)(j)}),I=[]}if(0===I.length)return p({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${m}.`}]}
|
|
3608
3620
|
function k(e){const t=new Map,r=new Map,n=[]
|
|
3609
3621
|
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
|
|
3610
3622
|
if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
|
|
@@ -3625,7 +3637,7 @@ if(t&&(n=e.metadata.successfulOperations.some((e=>e&&e.source&&e.destination))),
|
|
|
3625
3637
|
if(!Array.isArray(t)||0===t.length)return s.warn("Skipping delete-files record without valid paths array: "+e.id),!1
|
|
3626
3638
|
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}))
|
|
3627
3639
|
if(s.info(`Found ${C.length} file operation records`),C.length>0){const O={}
|
|
3628
|
-
C.forEach((e=>{O[e.type]=(O[e.type]||0)+1})),s.info("Filtered record type distribution:",O)}if(0===C.length)return p({success:!0,fileChanges:0}),{content:[{type:"text",text:`No file changes found for task ${
|
|
3640
|
+
C.forEach((e=>{O[e.type]=(O[e.type]||0)+1})),s.info("Filtered record type distribution:",O)}if(0===C.length)return p({success:!0,fileChanges:0}),{content:[{type:"text",text:`No file changes found for task ${m}.`}]}
|
|
3629
3641
|
const _=new Map
|
|
3630
3642
|
C.forEach((e=>{let t=null
|
|
3631
3643
|
if(e.metadata){if(!e.metadata.commitHash){const t=["gitCommitId","commitId","commit","gitCommit"]
|
|
@@ -3672,34 +3684,34 @@ continue}const H=L[0],B=L[L.length-1]
|
|
|
3672
3684
|
s.info(`First commit: ${H.commitHash?H.commitHash:"unknown"}, Last commit: ${B.commitHash?B.commitHash:"unknown"}`)
|
|
3673
3685
|
let U=null,G=!1
|
|
3674
3686
|
if(t.git&&H.commitHash)try{U=await(0,c.findPreviousCommit)(t.git,F,H.commitHash),U?(G=!0,s.info(`Found previous commit: ${U} for ${F}`)):s.info(`No previous commit found for ${F}, likely a new file`)}catch(ce){s.warn("Error finding previous commit for "+F,{error:(0,u.getErrorMessage)(ce)})}const W=G&&U?{...H,commitHash:U,status:"pre-task"}:H
|
|
3675
|
-
if(s.info(`Using ${G?"pre-task":"first task"} commit as baseline for ${F}: ${W.commitHash}`),s.info(`Last commit for ${F}: ${B.commitHash}`),s.info("Commits are "+(W.commitHash===B.commitHash?"identical":"different")),H.commitHash===B.commitHash&&!G){if(
|
|
3687
|
+
if(s.info(`Using ${G?"pre-task":"first task"} commit as baseline for ${F}: ${W.commitHash}`),s.info(`Last commit for ${F}: ${B.commitHash}`),s.info("Commits are "+(W.commitHash===B.commitHash?"identical":"different")),H.commitHash===B.commitHash&&!G){if(g&&!G&&t.git&&B.commitHash)try{const le=[`${B.commitHash}:${F}`]
|
|
3676
3688
|
s.info(`Getting new file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${F}`)
|
|
3677
3689
|
const de=await t.git.show(le)
|
|
3678
3690
|
if(de&&de.trim().length>0){let ue=""
|
|
3679
3691
|
const he=de.split("\n")
|
|
3680
3692
|
for(const pe of he)ue+=`+${pe}\n`
|
|
3681
3693
|
E.set(F,{firstChange:W,lastChange:B,hasDiff:!0,diffText:ue}),s.info(`Formatted new file content as diff, ${he.length} lines`)
|
|
3682
|
-
continue}}catch(
|
|
3694
|
+
continue}}catch(me){s.warn("Error getting new file content for "+F,{error:(0,u.getErrorMessage)(me)})}E.set(F,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"Only one commit available for this file"})
|
|
3683
3695
|
continue}if(H.commitHash===B.commitHash&&G){if(U===H.commitHash){E.set(F,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"No changes detected"})
|
|
3684
3696
|
continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let V="",K=!1
|
|
3685
|
-
if(
|
|
3686
|
-
continue}let
|
|
3687
|
-
if("pre-task"===W.status?(
|
|
3697
|
+
if(g||"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})
|
|
3698
|
+
continue}let ge
|
|
3699
|
+
if("pre-task"===W.status?(ge=[`${W.commitHash}..${B.commitHash}`,"--",F],s.info(`Comparing pre-task commit with final commit: ${W.commitHash?W.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${F}`)):(ge=["4b825dc642cb6eb9a060e54bf8d69288fbee4904.."+B.commitHash,"--",F],s.info(`File created during task, showing full file diff using empty tree object: ${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${F}`)),V=await t.git.diff(ge),K=!!V&&V.trim().length>0,!K&&W.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
|
|
3688
3700
|
try{const ye=await t.git.show([`${W.commitHash}:${F}`]),we=await t.git.show([`${B.commitHash}:${F}`])
|
|
3689
|
-
if(ye!==we&&(K=!0,V="Changes detected through direct content comparison (not visible in standard diff)",
|
|
3701
|
+
if(ye!==we&&(K=!0,V="Changes detected through direct content comparison (not visible in standard diff)",g)){const be=ye.split("\n"),Ie=we.split("\n")
|
|
3690
3702
|
Math.abs(be.length-Ie.length)>0&&(V+=`\n\nLine count changed: ${be.length} \u2192 ${Ie.length}`),ye.includes("\0")||we.includes("\0")?V+="\n\nBinary content detected - changes not displayed":ye.replace(/\s+/g,"")===we.replace(/\s+/g,"")&&(V+="\n\nWhitespace-only changes detected")}}catch(ke){s.warn("Error in direct file comparison: "+(ke instanceof Error?ke.message:ke+""))}}s.info(`Diff generation result for ${F}: hasDiff=${K}, length=${V.length}`)}}catch(ve){if(s.warn("Error getting diff for "+F,{error:(0,u.getErrorMessage)(ve),firstCommit:H.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),V="Error getting diff: "+(0,u.getErrorMessage)(ve),"pre-task"!==H.status&&t.git)try{const Ce=[`${B.commitHash}:${F}`]
|
|
3691
3703
|
s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${F}`)
|
|
3692
3704
|
const _e=await t.git.show(Ce)
|
|
3693
|
-
if(_e&&_e.trim().length>0){if(
|
|
3705
|
+
if(_e&&_e.trim().length>0){if(g){let Ee=""
|
|
3694
3706
|
const Se=_e.split("\n")
|
|
3695
3707
|
for(const qe of Se)Ee+=`+${qe}\n`
|
|
3696
3708
|
V=Ee}else V="File created during this task. Content:\n"+_e
|
|
3697
|
-
K=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(Te){s.warn("Fallback also failed for "+F,{error:Te instanceof Error?Te.message:Te+""})}}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: ${
|
|
3709
|
+
K=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(Te){s.warn("Fallback also failed for "+F,{error:Te instanceof Error?Te.message:Te+""})}}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: ${m}\n\n`
|
|
3698
3710
|
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`)
|
|
3699
3711
|
const q=3e3
|
|
3700
3712
|
let T=0,x=!1
|
|
3701
|
-
if(
|
|
3702
|
-
x=T>q,s.info(`Total diff size: ${T} lines (limit: ${q} lines)`),s.info(`Diffs ${x?"will be limited":"will be shown"} based on size`)}if(S+="## Summary\n",S+=`- **Files Modified**: ${_.size}\n`,S+=`- **Total File Operations**: ${C.length}\n`,S+="- **What's Shown**: For existing files, comparing state before task started with final state.\n",S+=" For files created during task, showing the entire file as created.\n",x?(S+=`- **Diff Display**: Limited (total diff size of ${T} lines exceeds limit of ${q} lines)\n`,S+=" Use file-history tool with individual files to see detailed changes\n\n"):S+=`- **Diff Display**: ${
|
|
3713
|
+
if(g){for(const xe of E.values())xe.hasDiff&&xe.diffText&&(T+=xe.diffText.split("\n").length)
|
|
3714
|
+
x=T>q,s.info(`Total diff size: ${T} lines (limit: ${q} lines)`),s.info(`Diffs ${x?"will be limited":"will be shown"} based on size`)}if(S+="## Summary\n",S+=`- **Files Modified**: ${_.size}\n`,S+=`- **Total File Operations**: ${C.length}\n`,S+="- **What's Shown**: For existing files, comparing state before task started with final state.\n",S+=" For files created during task, showing the entire file as created.\n",x?(S+=`- **Diff Display**: Limited (total diff size of ${T} lines exceeds limit of ${q} lines)\n`,S+=" Use file-history tool with individual files to see detailed changes\n\n"):S+=`- **Diff Display**: ${g?"Enabled":"Disabled"} (use showDiff=${!g} to ${g?"hide":"show"} diffs)\n\n`,v.allMoves.length>0){S+="## Move Operations\n\n",S+=`Detected ${v.allMoves.length} file move operation(s):\n\n`
|
|
3703
3715
|
for(const Pe of v.allMoves)S+=`- **${Pe.source}** \u2192 **${Pe.destination}**\n`,S+=` - Operation: ${Pe.type}\n`,S+=` - Timestamp: ${new Date(Pe.timestamp).toLocaleString()}\n`,S+=` - Record ID: ${Pe.recordId}\n\n`}S+="## Modified Files\n\n"
|
|
3704
3716
|
for(const[Re,Me]of E.entries()){const{normalizedPath:$e,fullPath:je}=d.validateAndNormalizePath(Re,t)
|
|
3705
3717
|
let Oe=!1
|
|
@@ -3707,7 +3719,7 @@ try{await a.access(je),Oe=!0}catch{}S+=`### ${Re} ${Oe?"":"(Deleted)"}\n\n`
|
|
|
3707
3719
|
const De=new Date(Me.firstChange.timestamp).toLocaleString(),Ae=new Date(Me.lastChange.timestamp).toLocaleString()
|
|
3708
3720
|
S+=`**First Change**: ${De}\n`,S+=`**Last Change**: ${Ae}\n`,"pre-task"===Me.firstChange.status&&Me.firstChange.commitHash?S+=`**Pre-Task Commit**: ${Me.firstChange.commitHash.substring(0,8)}\n`:Me.firstChange.commitHash&&(S+=`**File Created During Task**: ${Me.firstChange.commitHash.substring(0,8)}\n`),Me.lastChange.commitHash&&(S+=`**Final Commit**: ${Me.lastChange.commitHash.substring(0,8)}\n`)
|
|
3709
3721
|
const Fe=v.sourceToMove.get(Re),Ne=v.destToMove.get(Re)
|
|
3710
|
-
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`),
|
|
3722
|
+
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`),g&&!x?Me.hasDiff?(S+="\n**Changes**:\n",S+="```diff\n",S+=Me.diffText,S+="\n```\n\n"):S+=`\n**Note**: ${Me.diffText}\n\n`:x&&Me.hasDiff?(S+=`\n**Note**: File has changes (${Me.diffText?Me.diffText.split("\n").length:0} lines). `,S+=`Compare ${Me.firstChange.commitHash?Me.firstChange.commitHash.substring(0,8):"unknown"}..${Me.lastChange.commitHash?Me.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Me.hasDiff?S+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":S+=`\n**Note**: ${Me.diffText}\n\n`,S+="---\n\n"}return p({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+""}),p({success:!1,error:ze instanceof Error?ze.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,u.getErrorMessage)(ze)}],isError:!0}}}
|
|
3711
3723
|
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"
|
|
3712
3724
|
module.exports=require("path")},6975(e,exports,t){"use strict"
|
|
3713
3725
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
|
|
@@ -3842,26 +3854,26 @@ i.appendFileSync(o,`[${s}] ${e} | ${t}${l}\n`)}catch(e){}}
|
|
|
3842
3854
|
const i=s(t(9896)),a=s(t(6928)),c=s(t(857))},7334(e,exports,t){"use strict"
|
|
3843
3855
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,c,l,d,u,h){const p=l.child({tool:"create_request"})
|
|
3844
3856
|
p.info("Creating new request",{args:e})
|
|
3845
|
-
const
|
|
3857
|
+
const m=d.startTimer("tool_handler_duration")
|
|
3846
3858
|
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)
|
|
3847
3859
|
throw new r.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
|
|
3848
3860
|
d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
|
|
3849
|
-
const
|
|
3850
|
-
if(!
|
|
3851
|
-
c.setProjectId(
|
|
3861
|
+
const g=t.projectId
|
|
3862
|
+
if(!g)throw new r.ValidationError("Project ID is required for creating requests.")
|
|
3863
|
+
c.setProjectId(g)
|
|
3852
3864
|
const f=c.getRequestClient()
|
|
3853
3865
|
let y=(0,a.getApprovalMode)()
|
|
3854
3866
|
try{const e=h?.sessionId
|
|
3855
3867
|
if(e){const t=c.getCLISessionClient()
|
|
3856
3868
|
if(t){const r=await t.getByExternalId(e)
|
|
3857
3869
|
if(r?.workflowId){const e=await c.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
|
|
3858
|
-
t?.approvalMode&&(y=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===y)try{const e=await c.proxyGet("/api/projects/"+
|
|
3870
|
+
t?.approvalMode&&(y=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===y)try{const e=await c.proxyGet("/api/projects/"+g),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
|
|
3859
3871
|
r&&(y=(0,a.getApprovalMode)(r))}catch(e){p.warn("Failed to read project metadata for approvalMode fallback",{error:(0,i.getErrorMessage)(e)})}}catch(e){p.warn("Failed to resolve approval mode, using default",{error:(0,i.getErrorMessage)(e)})}const w="require-approval"===y&&"quick-edit"!==l.type?"pending_approval":"open"
|
|
3860
3872
|
let b=h
|
|
3861
3873
|
if(h?.sessionId)try{const e=c.getCLISessionClient()
|
|
3862
3874
|
if(e){const t=await e.getByExternalId(h.sessionId)
|
|
3863
3875
|
"planner"!==t?.agentType&&"auto-planner"!==t?.agentType||(b=void 0,p.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}}
|
|
3864
|
-
p.info("Creating request via request client",{projectId:
|
|
3876
|
+
p.info("Creating request via request client",{projectId:g,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
|
|
3865
3877
|
const k=await f.createRequest(I)
|
|
3866
3878
|
p.debug("Create request response structure",{type:typeof k,isArray:Array.isArray(k),hasData:null!=k,properties:k?Object.keys(k):[],dataPreview:k?JSON.stringify(k).substring(0,200)+"...":"null"})
|
|
3867
3879
|
const v=(0,o.extractDataFromResponse)(k,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
|
|
@@ -3869,12 +3881,12 @@ let _,E={created:!1}
|
|
|
3869
3881
|
if(u?.workspaceManager)try{await u.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},p.info("Request branch initialized successfully",{requestId:C.id,branchName:E.branchName,title:C.title})}catch(e){p.warn("Failed to initialize request branch, will retry on first operation",{requestId:C.id,error:(0,i.getErrorMessage)(e)})}else"quick-edit"===l.type?p.info("Quick-edit request - skipping branch creation, will work directly on main",{requestId:C.id}):p.debug("No workspace manager available, branch creation deferred",{requestId:C.id})
|
|
3870
3882
|
p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
|
|
3871
3883
|
try{const e=c.getToolRecordClient()
|
|
3872
|
-
if(e){const t=await e.createToolRecord({requestId:C.id,projectId:
|
|
3873
|
-
_=t?.id}}catch(e){p.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:C.id})}
|
|
3884
|
+
if(e){const t=await e.createToolRecord({requestId:C.id,projectId:g,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"}`})
|
|
3885
|
+
_=t?.id}}catch(e){p.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:C.id})}m({success:!0,type:l.type,hasProjectId:!0}),p.info("Request created successfully",{requestId:C.id,title:C.title,type:C.type,projectId:g})
|
|
3874
3886
|
const S=C.localId||C.id
|
|
3875
3887
|
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(p.error("Failed to create request",{error:r instanceof Error?r.stack:r+"",args:e}),t.projectId)try{if(r instanceof Error&&(r.message.includes("Project is disabled")||r.message.includes("Project cannot accept new requests")||r.message.includes("disabled due to tier limits")))p.info("Skipping tool record creation for disabled project error",{projectId:t.projectId,error:r.message})
|
|
3876
3888
|
else{const n=c.getToolRecordClient()
|
|
3877
|
-
n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){p.error("Failed to create failure record for request creation",{error:e instanceof Error?e.message:e+""})}if(
|
|
3889
|
+
n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){p.error("Failed to create failure record for request creation",{error:e instanceof Error?e.message:e+""})}if(m({success:!1,error:r instanceof Error?r.name:"unknown"}),r instanceof s.ZodError&&r.errors.length>0){const e=r.errors[0]
|
|
3878
3890
|
let t=e.message
|
|
3879
3891
|
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."
|
|
3880
3892
|
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}}}
|
|
@@ -3895,12 +3907,12 @@ const h=i[c]
|
|
|
3895
3907
|
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}}}
|
|
3896
3908
|
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"
|
|
3897
3909
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,i,a,c,l,d,u,h){const p=d.child({tool:"modify_file"})
|
|
3898
|
-
try{const s=e,{operations:
|
|
3910
|
+
try{const s=e,{operations:m,comment:g}=s,{enforceActiveTask:f}=await Promise.resolve().then(t.bind(t,3451)),y=await f(i,a,d,e.taskId)
|
|
3899
3911
|
if("errorResult"in y)return y.errorResult
|
|
3900
3912
|
const{taskId:w}=y
|
|
3901
|
-
p.info("Processing modify-file operations",{taskId:w,operationCount:
|
|
3913
|
+
p.info("Processing modify-file operations",{taskId:w,operationCount:m.length,comment:g})
|
|
3902
3914
|
const b=[],I=[],k=[],v=[],C=[]
|
|
3903
|
-
for(const e of
|
|
3915
|
+
for(const e of m){const t={path:e.path,documentId:e.documentId}
|
|
3904
3916
|
switch(e.operationType){case"replace-string":b.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
|
|
3905
3917
|
break
|
|
3906
3918
|
case"insert-lines":I.push({...t,insertions:e.insertLines.insertions})
|
|
@@ -3911,15 +3923,15 @@ case"delete-string":v.push({...t,replacements:e.deleteString.patterns.map((e=>({
|
|
|
3911
3923
|
break
|
|
3912
3924
|
case"delete-lines":C.push({...t,lines:e.deleteLines.lines})}}const _=[]
|
|
3913
3925
|
if(b.length>0){p.info("Routing to replace-strings handler",{operationCount:b.length})
|
|
3914
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:b,comment:
|
|
3926
|
+
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:b,comment:g+" [via modify-file: replace-string]"},i,a,c,l,p,u,h)
|
|
3915
3927
|
_.push({type:"replace-string",result:e})}if(I.length>0){p.info("Routing to insert-lines handler",{operationCount:I.length})
|
|
3916
|
-
const e=await(0,n.handleInsertLines)({taskId:w,operations:I,comment:
|
|
3928
|
+
const e=await(0,n.handleInsertLines)({taskId:w,operations:I,comment:g+" [via modify-file: insert-lines]"},i,a,c,l,p,u,h)
|
|
3917
3929
|
_.push({type:"insert-lines",result:e})}if(k.length>0){p.info("Routing to replace-lines handler",{operationCount:k.length})
|
|
3918
|
-
const e=await(0,o.handleReplaceLines)({taskId:w,operations:k,comment:
|
|
3930
|
+
const e=await(0,o.handleReplaceLines)({taskId:w,operations:k,comment:g+" [via modify-file: replace-lines]"},i,a,c,l,p,u,h)
|
|
3919
3931
|
_.push({type:"replace-lines",result:e})}if(v.length>0){p.info("Routing delete-string to replace-strings handler",{operationCount:v.length})
|
|
3920
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:v,comment:
|
|
3932
|
+
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:v,comment:g+" [via modify-file: delete-string]"},i,a,c,l,p,u,h)
|
|
3921
3933
|
_.push({type:"delete-string",result:e})}if(C.length>0){p.info("Processing delete-lines operations",{operationCount:C.length})
|
|
3922
|
-
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:
|
|
3934
|
+
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:g+" [via modify-file: delete-lines]"},i,a,c,l,p,u,h)
|
|
3923
3935
|
_.push({type:"delete-lines",result:t})}const E=_.some((e=>e.result.isError)),S=_.filter((e=>!e.result.isError)).length,q=_.filter((e=>e.result.isError)).length
|
|
3924
3936
|
let T="## Modify File Results\n\n"
|
|
3925
3937
|
T+="**Summary:**\n",T+=`- **Total operation types:** ${_.length}\n`,T+=`- **Successful:** ${S}\n`,T+=`- **Failed:** ${q}\n\n`
|
|
@@ -3929,22 +3941,22 @@ const r=t(3306),n=t(6486),o=t(6651),s=t(8824)},7478(e,exports,t){"use strict"
|
|
|
3929
3941
|
async function r(e,t,r){const n=r.startTimer("git_get_current_branch_duration")
|
|
3930
3942
|
try{const o=(await e.status()).current
|
|
3931
3943
|
if(!o)throw new p.ValidationError("Repository is in detached HEAD state or branch detection failed")
|
|
3932
|
-
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,
|
|
3944
|
+
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,g.getErrorMessage)(e)
|
|
3933
3945
|
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 p.ValidationError("Failed to get current branch: "+o)}}async function n(e,t,r,n){const o=n.startTimer("git_branch_exists_duration")
|
|
3934
3946
|
try{const s=(await e.branch(["-l"])).all.includes(t)
|
|
3935
|
-
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,
|
|
3947
|
+
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,g.getErrorMessage)(e)
|
|
3936
3948
|
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")
|
|
3937
3949
|
try{const a=await r(e,o,s)
|
|
3938
3950
|
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}'`}
|
|
3939
3951
|
if(!await n(e,t,o,s)){const e=`Branch '${t}' does not exist`
|
|
3940
3952
|
throw o.error(e),s.incrementCounter("git_switch_branch_not_found",1),i({success:!1,reason:"branch_not_found"}),new p.ValidationError(e)}await e.checkout(t)
|
|
3941
3953
|
const c=await e.revparse(["HEAD"])
|
|
3942
|
-
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,
|
|
3954
|
+
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,g.getErrorMessage)(e)
|
|
3943
3955
|
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 p.ValidationError(`Failed to switch to branch '${t}': ${r}`)}}async function s(e,t,r){const n=r.startTimer("git_repository_status_duration")
|
|
3944
3956
|
try{let o,s=!0
|
|
3945
3957
|
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")
|
|
3946
3958
|
let p=""
|
|
3947
|
-
return u?p="main":h?p="master":d.length>0&&(p=d[0].name),t.debug("Retrieved repository status",{currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:p,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:p,uncommittedChanges:c,branches:d}}catch(e){const o=(0,
|
|
3959
|
+
return u?p="main":h?p="master":d.length>0&&(p=d[0].name),t.debug("Retrieved repository status",{currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:p,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:p,uncommittedChanges:c,branches:d}}catch(e){const o=(0,g.getErrorMessage)(e)
|
|
3948
3960
|
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 p.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")
|
|
3949
3961
|
try{t.debug("Starting uncommitted changes check"),t.debug("Checking for uncommitted changes before merge"),Date.now()
|
|
3950
3962
|
const o=await e.status()
|
|
@@ -3956,7 +3968,7 @@ t.debug("Uncommitted changes summary",{hasChanges:l,totalFiles:c,staged:s.length
|
|
|
3956
3968
|
let d=""
|
|
3957
3969
|
if(l){const e=[]
|
|
3958
3970
|
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"
|
|
3959
|
-
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,
|
|
3971
|
+
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,g.getErrorMessage)(e)
|
|
3960
3972
|
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 p.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)
|
|
3961
3973
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3962
3974
|
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=[]
|
|
@@ -3970,42 +3982,42 @@ try{if(await n(e,t,s,i)){const e=`Branch '${t}' already exists`
|
|
|
3970
3982
|
return s.warn(e),i.incrementCounter("git_create_branch_already_exists",1),c({success:!1,reason:"already_exists"}),{success:!1,branchName:t,message:e}}const l=await r(e,s,i)
|
|
3971
3983
|
await e.checkoutBranch(t,o)
|
|
3972
3984
|
const d=await e.revparse(["HEAD"]),u=a||l
|
|
3973
|
-
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,
|
|
3985
|
+
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,g.getErrorMessage)(e)
|
|
3974
3986
|
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 p.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")
|
|
3975
3987
|
try{const d=await r(e,i,a)
|
|
3976
3988
|
if(d!==s&&await o(e,s,i,a),!await n(e,t,i,a)){const e=`Source branch '${t}' does not exist`
|
|
3977
3989
|
throw i.error(e),a.incrementCounter("git_merge_branch_source_not_found",1),l({success:!1,reason:"source_not_found"}),new p.ValidationError(e)}const u=c?["--no-ff","-m",c,t]:["--no-ff",t],h=(await e.merge(u),await e.revparse(["HEAD"]))
|
|
3978
|
-
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,
|
|
3990
|
+
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,g.getErrorMessage)(e)
|
|
3979
3991
|
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 p.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")
|
|
3980
3992
|
try{const c=await r(e,s,i)
|
|
3981
3993
|
if(c===t){const e=`Cannot delete current branch '${t}'`
|
|
3982
3994
|
throw s.error(e),i.incrementCounter("git_delete_branch_current_branch",1),a({success:!1,reason:"current_branch"}),new p.ValidationError(e)}if("main"===t||"master"===t){const e=`Cannot delete protected branch '${t}'`
|
|
3983
3995
|
throw s.error(e),i.incrementCounter("git_delete_branch_protected",1),a({success:!1,reason:"protected_branch"}),new p.ValidationError(e)}if(!await n(e,t,s,i)){const e=`Branch '${t}' does not exist`
|
|
3984
3996
|
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]
|
|
3985
|
-
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,
|
|
3997
|
+
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,g.getErrorMessage)(e)
|
|
3986
3998
|
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 p.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")
|
|
3987
3999
|
try{const o=await s(e,t,r)
|
|
3988
|
-
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,
|
|
4000
|
+
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,g.getErrorMessage)(e)
|
|
3989
4001
|
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 p.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)
|
|
3990
4002
|
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})-/)
|
|
3991
4003
|
return t?t[1]:null},exports.switchToDefaultBranch=async function(e,t,r){const n=r.startTimer("git_switch_to_default_duration")
|
|
3992
4004
|
try{const i=await s(e,t,r)
|
|
3993
4005
|
if(!i.defaultBranch){const e="No default branch found"
|
|
3994
4006
|
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)
|
|
3995
|
-
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,
|
|
4007
|
+
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,g.getErrorMessage)(e)
|
|
3996
4008
|
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 p.ValidationError("Failed to switch to default branch: "+o)}},exports.ensureRepositoryReady=async function(e,t,r){const n=r.startTimer("git_ensure_repository_ready_duration")
|
|
3997
4009
|
try{const o=await s(e,t,r),i=[]
|
|
3998
4010
|
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")
|
|
3999
4011
|
const a=0===i.length
|
|
4000
|
-
return t.debug("Repository readiness check completed",{ready:a,issueCount:i.length,issues:i}),r.incrementCounter("git_ensure_repository_ready_check",1,{ready:a.toString()}),n({success:!0,ready:a.toString()}),{ready:a,status:o,issues:i}}catch(e){const o=(0,
|
|
4012
|
+
return t.debug("Repository readiness check completed",{ready:a,issueCount:i.length,issues:i}),r.incrementCounter("git_ensure_repository_ready_check",1,{ready:a.toString()}),n({success:!0,ready:a.toString()}),{ready:a,status:o,issues:i}}catch(e){const o=(0,g.getErrorMessage)(e)
|
|
4001
4013
|
return t.error("Failed to check repository readiness",{error:o}),r.incrementCounter("git_ensure_repository_ready_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),{ready:!1,status:{isGitRepository:!1,currentBranch:"",isClean:!1,hasMainBranch:!1,hasMasterBranch:!1,defaultBranch:"",uncommittedChanges:[],branches:[]},issues:["Repository check failed: "+o]}}},exports.hasMainChangedSinceRevert=async function(e,t,r,n){const o=n.startTimer("git_check_main_changed_since_revert")
|
|
4002
4014
|
try{r.debug("Starting main branch change detection",{providedRevertCommitHash:t.substring(0,8),fullRevertCommitHash:t})
|
|
4003
4015
|
const n=await e.revparse(["HEAD"])
|
|
4004
4016
|
r.debug("Git state captured",{currentMainHash:n.substring(0,8),fullCurrentMainHash:n,revertCommitHash:t.substring(0,8),fullRevertCommitHash:t,hashesMatch:n===t})
|
|
4005
4017
|
try{const t=await e.revparse(["--abbrev-ref","HEAD"]),n=await e.status(),o=await e.log(["--oneline","-5"])
|
|
4006
|
-
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,
|
|
4018
|
+
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,m.validateCommitHash)(e,t,r,"hasMainChangedSinceRevert-revert-validation")
|
|
4007
4019
|
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}`)
|
|
4008
|
-
const i=await(0,
|
|
4020
|
+
const i=await(0,m.validateCommitHash)(e,n,r,"hasMainChangedSinceRevert-head-validation")
|
|
4009
4021
|
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}`)
|
|
4010
4022
|
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"}
|
|
4011
4023
|
r.debug("Hash comparison shows difference, checking ancestor relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),hashesEqual:!1})
|
|
@@ -4013,10 +4025,10 @@ let a=!1,c=0,l=null
|
|
|
4013
4025
|
for(let n=1;3>=n;n++)try{r.debug("Checking ancestor relationship with merge-base",{revertCommitHash:t.substring(0,8),currentHead:"HEAD",attempt:n}),n>1&&(await new Promise((e=>setTimeout(e,100))),r.debug("Retry attempt after delay",{attempt:n,delay:100})),await e.raw(["merge-base","--is-ancestor",t,"HEAD"]),r.debug("Revert commit is ancestor of HEAD, counting commits between them",{attempt:n})
|
|
4014
4026
|
const o=await e.raw(["rev-list","--count",t+"..HEAD"])
|
|
4015
4027
|
c=parseInt(o.trim(),10),a=!0
|
|
4016
|
-
break}catch(e){l=e,r.debug("Ancestor check attempt failed",{attempt:n,error:(0,
|
|
4028
|
+
break}catch(e){l=e,r.debug("Ancestor check attempt failed",{attempt:n,error:(0,g.getErrorMessage)(e)}),3===n&&r.debug("All ancestor check attempts failed, treating as non-ancestor")}if(a){try{const n=await e.raw(["rev-list","--oneline",t+"..HEAD"])
|
|
4017
4029
|
r.debug("Commits found between revert and HEAD",{count:c,commits:n.trim().split("\n").filter((e=>e.length>0))})}catch(e){r.warn("Could not list commits between revert and HEAD",{error:e instanceof Error?e.message:e+""})}return r.info("Main branch has changed since revert - ancestor relationship confirmed",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),commitsSinceRevert:c,isAncestor:!0}),o({success:!0,changed:"true"}),{hasChanged:!0,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:c,message:`Main branch has ${c} new commit${c>1?"s":""} since revert`}}r.warn("Revert commit is not an ancestor of current HEAD after retries - investigating relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),lastAncestorError:l instanceof Error?l.message:l+"",attempts:3})
|
|
4018
4030
|
try{const o=await e.raw(["merge-base",t,"HEAD"])
|
|
4019
|
-
r.debug("Merge base found between revert commit and HEAD",{mergeBase:o.trim().substring(0,8),revertCommitHash:t.substring(0,8),currentMainHash:n.substring(0,8)})}catch(e){r.warn("Could not find merge base",{error:e instanceof Error?e.message:e+""})}try{await e.raw(["merge-base","--is-ancestor","HEAD",t]),r.error("CRITICAL: Current HEAD is ancestor of revert commit - possible git state corruption or incorrect revert hash",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),implication:"This suggests the stored revert commit hash may be incorrect or from a different branch state"})}catch(e){r.debug("HEAD is not ancestor of revert commit either - commits may be on divergent paths",{error:e instanceof Error?e.message:e+""})}return o({success:!0,changed:"unknown"}),{hasChanged:!0,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:-1,message:"Cannot determine relationship between revert commit and current HEAD - assuming changed for safety. This may indicate a stored revert commit hash issue."}}catch(e){const n=(0,
|
|
4031
|
+
r.debug("Merge base found between revert commit and HEAD",{mergeBase:o.trim().substring(0,8),revertCommitHash:t.substring(0,8),currentMainHash:n.substring(0,8)})}catch(e){r.warn("Could not find merge base",{error:e instanceof Error?e.message:e+""})}try{await e.raw(["merge-base","--is-ancestor","HEAD",t]),r.error("CRITICAL: Current HEAD is ancestor of revert commit - possible git state corruption or incorrect revert hash",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),implication:"This suggests the stored revert commit hash may be incorrect or from a different branch state"})}catch(e){r.debug("HEAD is not ancestor of revert commit either - commits may be on divergent paths",{error:e instanceof Error?e.message:e+""})}return o({success:!0,changed:"unknown"}),{hasChanged:!0,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:-1,message:"Cannot determine relationship between revert commit and current HEAD - assuming changed for safety. This may indicate a stored revert commit hash issue."}}catch(e){const n=(0,g.getErrorMessage)(e)
|
|
4020
4032
|
throw r.error("Failed to check if main changed since revert",{revertCommitHash:t.substring(0,8),error:n}),o({success:!1,error:e instanceof Error?e.name:"unknown"}),Error("Failed to check main branch changes: "+n)}},exports.findRevertCommitHash=async function(e,t,r){try{r.debug("Searching for revert commit hash in tool records",{requestId:e})
|
|
4021
4033
|
const n=await t.getToolRecordsByRequestId(e,"revert-request")
|
|
4022
4034
|
if(n.sort(((e,t)=>new Date(t.createdAt).getTime()-new Date(e.createdAt).getTime())),!n||0===n.length)return r.debug("No revert tool records found for request",{requestId:e}),{found:!1,message:"No revert operations found for this request"}
|
|
@@ -4025,7 +4037,7 @@ for(const t of n)if(r.debug("Examining tool record",{requestId:e,recordId:t.id,r
|
|
|
4025
4037
|
r.debug("Found potential revert commit hash, validating...",{requestId:e,revertCommitHash:o.substring(0,8),fullRevertCommitHash:o,revertType:n,recordId:t.id,revertedAt:t.createdAt})
|
|
4026
4038
|
try{if(!/^[a-f0-9]{40}$/i.test(o)){r.warn("Invalid commit hash format found in tool record",{requestId:e,invalidHash:o,recordId:t.id,format:"Expected 40-character hex string"})
|
|
4027
4039
|
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+""})
|
|
4028
|
-
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,
|
|
4040
|
+
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,g.getErrorMessage)(t)
|
|
4029
4041
|
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")
|
|
4030
4042
|
try{if(!r.hasChanges)throw new p.ValidationError("No uncommitted changes to commit")
|
|
4031
4043
|
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})
|
|
@@ -4034,7 +4046,7 @@ i.length>0?(n.debug("Staging files",{files:i.slice(0,10),total:i.length}),await
|
|
|
4034
4046
|
const a=`chore: commit user changes before merging request ${t}\n\n${r.summary}\n\nThis commit preserves user modifications made during the request lifecycle\nbefore proceeding with the branch merge operation.`
|
|
4035
4047
|
n.debug("Commit message",{message:a.split("\n")[0]}),n.debug("Creating commit"),await e.commit(a)
|
|
4036
4048
|
const c=await e.revparse(["HEAD"])
|
|
4037
|
-
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,
|
|
4049
|
+
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,g.getErrorMessage)(e)
|
|
4038
4050
|
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 p.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")
|
|
4039
4051
|
try{let c=Date.now()
|
|
4040
4052
|
o.debug("Checking for user changes before tool operation",{toolName:r})
|
|
@@ -4051,8 +4063,8 @@ const h=`${u}\n\n${{...d,summary:`User changes detected before ${r}: ${d.summary
|
|
|
4051
4063
|
o.debug("Committing user changes with message",{firstLine:h.split("\n")[0]})
|
|
4052
4064
|
const p=[...d.unstagedFiles,...d.untrackedFiles]
|
|
4053
4065
|
c=Date.now(),p.length>0&&(o.debug("Staging files before tool operation",{files:p.slice(0,10),total:p.length}),await l.add(p)),Date.now(),c=Date.now(),await l.commit(h),Date.now()
|
|
4054
|
-
const
|
|
4055
|
-
return o.debug("User changes committed successfully before tool",{commitHash:
|
|
4066
|
+
const m=await l.revparse(["HEAD"])
|
|
4067
|
+
return o.debug("User changes committed successfully before tool",{commitHash:m.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:m.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:m,filesCommitted:d.totalFiles}}catch(e){const t=(0,g.getErrorMessage)(e)
|
|
4056
4068
|
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=[]
|
|
4057
4069
|
try{const o=t(3807).simpleGit(e),s=(await o.status()).not_added||[]
|
|
4058
4070
|
for(const t of s)try{const o=y.join(e,t),s=f.statSync(o)
|
|
@@ -4061,7 +4073,7 @@ const t=e.reduce(((e,t)=>e+t.sizeMB),0)
|
|
|
4061
4073
|
let r=`\n\n\u26a0\ufe0f **Performance Warning**: Large untracked files detected (${Math.round(t)} MB total) that may slow git operations:\n`
|
|
4062
4074
|
for(const t of e.slice(0,5))r+=`- \`${t.path}\` (${t.sizeMB} MB)\n`
|
|
4063
4075
|
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}
|
|
4064
|
-
const h=t(3444),p=t(9860),
|
|
4076
|
+
const h=t(3444),p=t(9860),m=t(3922),g=t(8824),f=u(t(9896)),y=u(t(6928))
|
|
4065
4077
|
t(857)},7575(e,exports){"use strict"
|
|
4066
4078
|
var t
|
|
4067
4079
|
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"
|
|
@@ -4265,7 +4277,7 @@ const r=t(4055)
|
|
|
4265
4277
|
Object.defineProperty(exports,"ProjectID",{enumerable:!0,get(){return r.ProjectID}}),Object.defineProperty(exports,"ProjectIDFactory",{enumerable:!0,get(){return r.ProjectIDFactory}})
|
|
4266
4278
|
const n=t(1791)
|
|
4267
4279
|
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"
|
|
4268
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,c,l,d,u,h,p,g
|
|
4280
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,c,l,d,u,h,p,m,g){const f=p.child({tool:"manage_files"})
|
|
4269
4281
|
try{const a=e,{operations:y,comment:w}=a,{enforceActiveTask:b}=await Promise.resolve().then(t.bind(t,3451)),I=await b(c,h,p,e.taskId)
|
|
4270
4282
|
if("errorResult"in I)return I.errorResult
|
|
4271
4283
|
const{taskId:k}=I
|
|
@@ -4279,18 +4291,18 @@ case"delete-files":_.push(...e.deleteFiles.targets)
|
|
|
4279
4291
|
break
|
|
4280
4292
|
case"get-file-info":E.push({path:e.getFileInfo.path})}const S=[]
|
|
4281
4293
|
for(const e of v){f.info("Routing to create-directory handler",{path:e.path})
|
|
4282
|
-
const t=await(0,r.handleCreateDirectory)({taskId:k,path:e.path,comment:w+" [via manage-files: create-directory]"},c,l,d,u,f,g
|
|
4294
|
+
const t=await(0,r.handleCreateDirectory)({taskId:k,path:e.path,comment:w+" [via manage-files: create-directory]"},c,l,d,u,f,m,g)
|
|
4283
4295
|
S.push({type:"create-directory",result:t})}if(C.length>0){f.info("Routing to move-files handler",{operationCount:C.length})
|
|
4284
|
-
const e=await(0,n.handleMoveFiles)({taskId:k,operations:C,comment:w+" [via manage-files: move-files]"},c,l,d,u,f,g
|
|
4296
|
+
const e=await(0,n.handleMoveFiles)({taskId:k,operations:C,comment:w+" [via manage-files: move-files]"},c,l,d,u,f,m,g)
|
|
4285
4297
|
S.push({type:"move-files",result:e})}if(_.length>0){f.info("Routing to delete-files handler",{operationCount:_.length})
|
|
4286
|
-
const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,g
|
|
4298
|
+
const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,m,g)
|
|
4287
4299
|
S.push({type:"delete-files",result:e})}for(const e of E){f.info("Routing to get-file-info handler",{path:e.path})
|
|
4288
|
-
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,
|
|
4300
|
+
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,m)
|
|
4289
4301
|
S.push({type:"get-file-info",result:t})}const q=S.some((e=>e.result.isError)),T=S.filter((e=>!e.result.isError)).length,x=S.filter((e=>e.result.isError)).length
|
|
4290
4302
|
let P="## Manage Files Results\n\n"
|
|
4291
4303
|
P+="**Summary:**\n",P+=`- **Total operation types:** ${S.length}\n`,P+=`- **Successful:** ${T}\n`,P+=`- **Failed:** ${x}\n\n`
|
|
4292
4304
|
for(const{type:e,result:t}of S)P+=`### ${e} operations\n`,P+=t.content[0].text+"\n\n"
|
|
4293
|
-
return f.info("Manage-files operations completed",{totalOperationTypes:S.length,successCount:T,errorCount:x}),
|
|
4305
|
+
return f.info("Manage-files operations completed",{totalOperationTypes:S.length,successCount:T,errorCount:x}),m.incrementCounter("manage_files_total",1,{success:!q}),{content:[{type:"text",text:P}],...(0,s.alchemyMeta)({kind:"manage-files"}),isError:q}}catch(e){return f.error("Manage-files operation failed",{error:e instanceof Error?e.stack:e+""}),m.incrementCounter("manage_files_errors",1),{content:[{type:"text",text:"\u274c **Manage Files Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
4294
4306
|
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"
|
|
4295
4307
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4296
4308
|
const r=t(6183),n=t(5303)
|
|
@@ -4315,8 +4327,8 @@ const r=t(5806),n=t(5715)
|
|
|
4315
4327
|
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"
|
|
4316
4328
|
async function r(e,t,r,n,o,s,a,l,d,u){const h=Date.now()
|
|
4317
4329
|
if(!r||""===r.trim())throw new c.ValidationError("Project ID is required and cannot be empty for tool record creation")
|
|
4318
|
-
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}`}),p=c.id,
|
|
4319
|
-
return l.info("Tool record created with IDs",{recordId:p,localRecordId:
|
|
4330
|
+
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}`}),p=c.id,m=c.localId
|
|
4331
|
+
return l.info("Tool record created with IDs",{recordId:p,localRecordId:m,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:p,localRecordId:m}),d.recordValue(u+"_tool_record_creation_time",Date.now()-h),d.incrementCounter(u+"_tool_record_creation_success",1),{recordId:p,localRecordId:m}}catch(t){d.incrementCounter(u+"_tool_record_creation_failure",1),d.recordValue(u+"_tool_record_creation_time",Date.now()-h)
|
|
4320
4332
|
const n=t instanceof Error?`${t.message} (${JSON.stringify(t)})`:t+""
|
|
4321
4333
|
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()
|
|
4322
4334
|
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
|
|
@@ -4329,35 +4341,35 @@ if(o.workspaceManager){const t=o.workspaceManager.getCurrentContext(o.currentSes
|
|
|
4329
4341
|
"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}
|
|
4330
4342
|
let p=null
|
|
4331
4343
|
try{p=(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)
|
|
4332
|
-
const
|
|
4333
|
-
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:
|
|
4344
|
+
const m=1===n.length?`${s} in ${n[0]} (${i})`:`${s} in ${n.length} files (${i})`,g=(await d.commit(m)).commit
|
|
4345
|
+
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:m,filesCommitted:n.length,commitHash:g?.substring(0,8),previousCommitHash:p?.substring(0,8),toolRecordId:i,operationType:s}),u.incrementCounter(h+"_git_commit_success",1),u.recordValue(h+"_files_committed",n.length),{commitHash:g,previousCommitHash:p,filesCommitted:n,success:!0}}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
4334
4346
|
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}}
|
|
4335
4347
|
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 p=Date.now()
|
|
4336
|
-
let g
|
|
4348
|
+
let m,g
|
|
4337
4349
|
l.debug("createFileOperationRecords called",{taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,operationType:o,path:s})
|
|
4338
4350
|
try{const a=await r(e,t,n,o,s,i,c,l,u,h)
|
|
4339
|
-
return
|
|
4351
|
+
return m=a.recordId,g=a.localRecordId,l.info("Created tool record for file operation: "+o,{taskId:e,path:s,toolRecordId:m,localToolRecordId:g}),{toolRecordId:m,localToolRecordId:g}}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()-p),u.incrementCounter(h+"_record_creation_error",1),r}},exports.updateFileOperationRecords=async function(e,t,r,o,s,i,a,c,l,u,h,p,m){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,p,m)}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}
|
|
4340
4352
|
try{let s=t.git
|
|
4341
4353
|
if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
4342
4354
|
"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)
|
|
4343
4355
|
const t=await s.commit("[USER-MODS] Preserve user modifications before tool operation: "+e)
|
|
4344
4356
|
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()
|
|
4345
|
-
let p,
|
|
4346
|
-
try{let
|
|
4357
|
+
let p,m=null
|
|
4358
|
+
try{let g=s.git
|
|
4347
4359
|
if(s.workspaceManager){const t=s.workspaceManager.getCurrentContext(s.currentSessionId)
|
|
4348
4360
|
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.`)
|
|
4349
|
-
|
|
4361
|
+
g=(0,a.simpleGit)(t.basePath),i.debug("Using WorkspaceManager git instance for commit",{taskId:e,mode:t.mode,requestId:t.requestId,basePath:t.basePath,branchName:t.branchName,worktreeValidated:!0})}}if(g){i.info("commitToGit called with:",{taskId:e,recordId:r,localRecordId:n,hasLocalRecordId:!!n,localRecordIdType:typeof n,normalizedPath:t})
|
|
4350
4362
|
let a=!1,f=""
|
|
4351
|
-
try{if(f=(await
|
|
4363
|
+
try{if(f=(await g.raw(["rev-parse","--show-toplevel"])).trim(),a=f.includes("/worktrees/")||f.includes("\\worktrees\\"),i.info("Git context detection for commit operation:",{taskId:e,gitRepoPath:f,isWorktreeOperation:a,targetFile:t,expectedContext:"worktree"}),!a)throw i.error("CRITICAL: Multi-agent operation using main repo Git instead of worktree",{taskId:e,detectedPath:f,targetFile:t,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"unknown"}),Error(`Git context mismatch: Multi-agent operation attempted to commit ${t} using main repository Git instance at ${f}, but should use worktree Git instance. This will fail due to .gitignore rules.`)}catch(e){i.warn("Failed to get Git instance info:",{error:e instanceof Error?e.message:e+""})}try{const r=await g.revparse(["--abbrev-ref","HEAD"]),n=await g.revparse(["HEAD"]),o=await g.revparse(["--show-toplevel"])
|
|
4352
4364
|
i.info("Git repository status before commit:",{taskId:e,currentBranch:r.trim(),currentCommit:n.trim().substring(0,8),repoPath:o.trim(),targetFile:t,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"none"})
|
|
4353
4365
|
const a=r.trim(),c=s.getCurrentRequestId?s.getCurrentRequestId():null
|
|
4354
4366
|
if(c){const t="requests/"+c
|
|
4355
|
-
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(
|
|
4356
|
-
|
|
4357
|
-
await
|
|
4358
|
-
try{const r=await
|
|
4359
|
-
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(
|
|
4360
|
-
return{commitHash:p,previousCommitHash:
|
|
4367
|
+
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(g){const r=await g.revparse(["HEAD"])
|
|
4368
|
+
m=await(0,l.findPreviousCommit)(g,t,r),i.info(`Previous commit hash for ${t}: ${m||"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
|
|
4369
|
+
await g.add(t),p=(await g.commit(y)).commit
|
|
4370
|
+
try{const r=await g.revparse(["--abbrev-ref","HEAD"]),n=await g.revparse(["HEAD"])
|
|
4371
|
+
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(m||""),targetFile:t}),p&&n.trim()!==p&&i.warn("Commit hash mismatch after commit",{taskId:e,expectedCommitHash:p,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:p,previousCommitHash:m}),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})
|
|
4372
|
+
return{commitHash:p,previousCommitHash:m}}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:m}}},exports.commitMultipleFilesToGit=o,exports.handleMultiFileGitCommit=async function(e,t,r,n,s,i){const{logger:a,metricsPrefix:c,metrics:l}=s
|
|
4361
4373
|
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))}
|
|
4362
4374
|
const i=s(t(6928)),a=t(3807),c=t(9860),l=t(9671),d=t(8824),u=t(7575)},7904(e,exports){"use strict"
|
|
4363
4375
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.REPORT_STATUS_EMOJI=void 0,exports.formatReportNotification=function(e){const{messageCode:t,status:r,summary:n,details:o,fromSessionId:s,senderAgent:i}=e,a=[`${exports.REPORT_STATUS_EMOJI[r]||"\u{1f4cb}"} **Report \u2014 ${r}**`]
|
|
@@ -4367,10 +4379,10 @@ if(e.includes("/dist-dev/")||e.includes("\\dist-dev\\"))return!0
|
|
|
4367
4379
|
if(e.includes("/dist/")||e.includes("\\dist\\"))return!1
|
|
4368
4380
|
const t=process.cwd()
|
|
4369
4381
|
return!(!t.includes("/dist-dev")&&!t.includes("\\dist-dev"))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.isDevBuild=t,exports.getBuildMode=function(){return t()?"development":"production"},exports.enableDebugMode=function(){return"true"===process.env.ENABLE_DEBUG_TOOLS&&(process.env.DEBUG_LOGGING="true",!0)}},8035(e,exports,t){"use strict"
|
|
4370
|
-
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:p,initialBranch:
|
|
4382
|
+
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:p,initialBranch:m,serverUrl:g,onSpawn:f}=e
|
|
4371
4383
|
try{const e=u||process.cwd(),o={...process.env,...(0,c.getOpencodeSpawnEnv)(e,(0,l.isDevMode)())}
|
|
4372
4384
|
let y
|
|
4373
|
-
if(
|
|
4385
|
+
if(m&&(o.ALCHEMY_INITIAL_BRANCH=m),r(u,"Spawn env setup",{agent:t,initialBranch:m||"none",sessionId:h||"new",attachMode:!!g}),y=g&&h&&d?["run","--attach",g,"--session",h,"--agent",t,d]:h&&d?["run","--session",h,"--agent",t,d]:d?["run","--agent",t,d]:["run","--agent",t],p){const e=y.findIndex((e=>e===d))
|
|
4374
4386
|
e>0?y.splice(e,0,"--model",p):y.push("--model",p)}r(u,"Spawning opencode",{args:y.map((e=>e===d?`[prompt:${e.length}chars]`:e)),model:p||"not specified",promptLength:d?.length,promptPreview:d?.slice(0,100),cwd:u,hasSessionId:!!h})
|
|
4375
4387
|
const w=(0,i.join)(u||process.cwd(),".alchemy_lab"),b=(0,i.join)(w,"spawn-stderr.log")
|
|
4376
4388
|
let I
|
|
@@ -4391,18 +4403,18 @@ const u=s.getRequestClient(),h=await u.listRequests(d)
|
|
|
4391
4403
|
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"})
|
|
4392
4404
|
const p=(0,n.extractArrayFromResponse)(h,{logger:c,operationName:"listRequests",defaultValue:[]})
|
|
4393
4405
|
if(c.info(`Extracted ${p.length} requests from response`),0===p.length)return l({success:!0,requestCount:0}),{content:[{type:"text",text:"No requests found with the specified filters."}]}
|
|
4394
|
-
const
|
|
4395
|
-
return l({success:!0,requestCount:p.length}),{content:[{type:"text",text:`${
|
|
4406
|
+
const m=p.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"),g=`Found ${p.length} request${1===p.length?"":"s"}:`
|
|
4407
|
+
return l({success:!0,requestCount:p.length}),{content:[{type:"text",text:`${g}\n\n${m}`}]}}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}}}
|
|
4396
4408
|
const r=t(9860),n=t(2960),o=t(8824)},8045(e,exports,t){"use strict"
|
|
4397
4409
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4398
4410
|
const r=t(6183),n=t(7456)
|
|
4399
4411
|
exports.def={name:"modify_file",description:'Make targeted edits to existing files and documents.\n\nOperations:\n\u2022 replace-string - Find and replace text\n - mode: \'unique\' (default, safer - fails if multiple matches)\n - mode: \'all\' (replaces all occurrences)\n\u2022 delete-string - Remove text patterns (same modes as replace-string)\n\u2022 insert-lines - Insert content before/after/between lines\n\u2022 replace-lines - Replace specific line numbers\n\u2022 delete-lines - Remove specific line numbers\n\nLine specification (string format for line-based operations):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "10-15"\n\nRead file first to know line numbers. Supports multiple files and operations in one call. Works with both filesystem files (path) and tracked documents (documentId).',schema:r.ModifyFileSchema,annotations:{title:"Modify File",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},hidden:!0,handler(e,t){return(0,n.handleModifyFile)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},8184(e,exports,t){"use strict"
|
|
4400
4412
|
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")
|
|
4401
|
-
try{const i=e,{requestId:c,format:d="summary",path:h}=i,p=s.getRequestClient(),
|
|
4402
|
-
if(!
|
|
4403
|
-
const
|
|
4413
|
+
try{const i=e,{requestId:c,format:d="summary",path:h}=i,p=s.getRequestClient(),m=await p.getRequest(c)
|
|
4414
|
+
if(!m)return u({success:!1,reason:"not_found"}),n("Request not found: "+c)
|
|
4415
|
+
const g=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,f=t.git??(0,o.simpleGit)({baseDir:g,binary:t.gitBinary}),y="completed"===m.status,w="requests/"+c
|
|
4404
4416
|
let b,I
|
|
4405
|
-
if(y){const e=
|
|
4417
|
+
if(y){const e=m.metadata?.mergeBaseSha,t=m.metadata?.mergeCommitSha
|
|
4406
4418
|
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.`)
|
|
4407
4419
|
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)
|
|
4408
4420
|
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]:[]
|
|
@@ -4440,35 +4452,35 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4440
4452
|
var t={}
|
|
4441
4453
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
4442
4454
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4443
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,r,n,o,s,i,p,
|
|
4455
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,r,n,o,s,i,p,m){const g=i.child({tool:"create_directory"}),f=Date.now()
|
|
4444
4456
|
let y,w,b=l.FileOperationPhase.VALIDATION
|
|
4445
4457
|
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}"}
|
|
4446
4458
|
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)
|
|
4447
4459
|
if("errorResult"in v)return v.errorResult
|
|
4448
4460
|
const{taskId:C}=v
|
|
4449
|
-
|
|
4461
|
+
g.info("Creating directory: "+u,{taskId:C,path:u,comment:h}),l.validateTaskIdFormat(C,g,p,I.metricsPrefix),r.getCurrentBranchContext&&await r.getCurrentBranchContext()
|
|
4450
4462
|
const{normalizedPath:_,fullPath:E}=l.validateAndNormalizePath(u,r)
|
|
4451
4463
|
b=l.FileOperationPhase.TASK_VALIDATION,p.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4452
|
-
const S=await l.validateTaskId(C,_,n,
|
|
4453
|
-
x.taskPromoted&&
|
|
4454
|
-
const P=await l.ensureCorrectWorkspaceContext({taskPromoted:x.taskPromoted,requestId:q,context:r,operation:"create-directory",logger:
|
|
4464
|
+
const S=await l.validateTaskId(C,_,n,g,p,I.metricsPrefix),q=S?.requestId,T=await l.validateWorkItemStates(C,_,n,s,r,g,p,I.metricsPrefix),x=await l.autoPromoteTaskStatus(C,S.status,q,T.request?.status,_,n,s,g,p,I.metricsPrefix)
|
|
4465
|
+
x.taskPromoted&&g.info(`Auto-promoted task ${C} (${S.title||"Untitled"}) to in_progress for file operation`,{taskId:C,taskTitle:S.title,previousStatus:S.status,newStatus:x.newTaskStatus,path:_}),x.requestPromoted&&g.info(`Auto-promoted request ${q} to in_progress for file operation`,{requestId:q,previousStatus:T.request?.status,newStatus:x.newRequestStatus,triggeringTaskId:C})
|
|
4466
|
+
const P=await l.ensureCorrectWorkspaceContext({taskPromoted:x.taskPromoted,requestId:q,context:r,operation:"create-directory",logger:g,metrics:p,metricsPrefix:I.metricsPrefix})
|
|
4455
4467
|
if(!P.success)throw Error(P.error)
|
|
4456
4468
|
let R=!1
|
|
4457
4469
|
try{R=(await a.default.stat(E)).isDirectory()}catch{R=!1}b=l.FileOperationPhase.RECORD_CREATION,p.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4458
|
-
const{toolRecordId:M,localToolRecordId:$}=await l.createFileOperationRecords(C,q,r.projectId,I.recordType,_,{directoryExists:R,userComment:h},n,o,
|
|
4470
|
+
const{toolRecordId:M,localToolRecordId:$}=await l.createFileOperationRecords(C,q,r.projectId,I.recordType,_,{directoryExists:R,userComment:h},n,o,g,p,I.metricsPrefix,m)
|
|
4459
4471
|
y=M,w=M,b=I.fileOperationPhase,p.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4460
4472
|
let j=R
|
|
4461
|
-
if(!R){await a.default.mkdir(E,{recursive:!0}),
|
|
4473
|
+
if(!R){await a.default.mkdir(E,{recursive:!0}),g.info("Successfully created directory "+_)
|
|
4462
4474
|
try{const e=c.default.join(E,".gitkeep")
|
|
4463
|
-
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),j=!0,
|
|
4475
|
+
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),j=!0,g.info("Created .gitkeep file for Git tracking")}catch(e){g.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),j=!1}}const O=Date.now()-f
|
|
4464
4476
|
p.recordValue("create_directory_time",O),p.incrementCounter("create_directory_success",1),b=l.FileOperationPhase.GIT_COMMIT,p.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4465
|
-
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!R&&j?_+"/.gitkeep":_,F=await l.commitToGit(C,A,M,$,D,r,
|
|
4466
|
-
b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,p.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,
|
|
4477
|
+
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!R&&j?_+"/.gitkeep":_,F=await l.commitToGit(C,A,M,$,D,r,g,p,I.metricsPrefix)
|
|
4478
|
+
b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,p.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,g,p,I.metricsPrefix)
|
|
4467
4479
|
const N=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4468
4480
|
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
|
|
4469
|
-
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){
|
|
4470
|
-
if(p.recordValue("create_directory_time",s),p.incrementCounter("create_directory_errors",1),
|
|
4471
|
-
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,
|
|
4481
|
+
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){g.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
|
|
4482
|
+
if(p.recordValue("create_directory_time",s),p.incrementCounter("create_directory_errors",1),g.error("Error creating directory:",{error:(0,h.getErrorMessage)(t),time:s}),(y||w)&&e.taskId){b=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
4483
|
+
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,g,p,I.metricsPrefix)}catch(t){g.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,g,p,e,I)}}
|
|
4472
4484
|
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"
|
|
4473
4485
|
function r(e){const t=[]
|
|
4474
4486
|
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"
|
|
@@ -4477,11 +4489,11 @@ case"move-files":return"\u{1f4cb} Move Files"
|
|
|
4477
4489
|
case"delete-files":return"\u{1f5d1}\ufe0f Delete Files"
|
|
4478
4490
|
case"manage-files":return"\u{1f4c1} Manage Files"
|
|
4479
4491
|
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")
|
|
4480
|
-
try{const{requestId:l,detailLevel:p="summary",taskId:
|
|
4492
|
+
try{const{requestId:l,detailLevel:p="summary",taskId:m,showDiff:g=!1,fileFilter:f}=e
|
|
4481
4493
|
if(!l)throw(0,o.createValidationError)("Request ID is required")
|
|
4482
4494
|
if(!/^req[_\d].+$/.test(l))throw(0,o.createValidationError)(`Invalid request ID format: ${l}. Expected format: req_[26 chars] or req######`)
|
|
4483
|
-
if(
|
|
4484
|
-
if(u.info("Getting file changes for request "+l,{detailLevel:p,taskId:
|
|
4495
|
+
if(m&&!(0,a.isTaskRef)(m))throw(0,o.createValidationError)(`Invalid task ID format: ${m}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
|
|
4496
|
+
if(u.info("Getting file changes for request "+l,{detailLevel:p,taskId:m,showDiff:g}),!t.git)throw Error("Git integration not available in this context")
|
|
4485
4497
|
const y=t.projectId
|
|
4486
4498
|
let w
|
|
4487
4499
|
c.setProjectId(y)
|
|
@@ -4490,7 +4502,7 @@ w={id:n.id||l,title:n.title||"Unknown Request",description:n.description||"No de
|
|
|
4490
4502
|
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}
|
|
4491
4503
|
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"===p){const e=c.getToolRecordClient()
|
|
4492
4504
|
let o=[]
|
|
4493
|
-
try{
|
|
4505
|
+
try{m?(o=await e.getToolRecordsByTaskId(m),u.info(`Fetched ${o.length} records for task ${m}`)):(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"
|
|
4494
4506
|
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
|
|
4495
4507
|
let u=t.filter((e=>{const t=e.type
|
|
4496
4508
|
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()))
|
|
@@ -4504,10 +4516,10 @@ let r=0
|
|
|
4504
4516
|
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])
|
|
4505
4517
|
if(e&&e.trim()){const r=500,n=e.length
|
|
4506
4518
|
if(n>r){const o=e.substring(0,r),s=(n/1024).toFixed(1)
|
|
4507
|
-
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,g,
|
|
4519
|
+
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,m,g,t.git,u,f)
|
|
4508
4520
|
return h({success:!0,recordCount:o.length}),{content:[{type:"text",text:s}]}}{const e=c.getToolRecordClient()
|
|
4509
4521
|
let n=[]
|
|
4510
|
-
try{
|
|
4522
|
+
try{m?(n=await e.getToolRecordsByTaskId(m),u.info(`Fetched ${n.length} records for task ${m}`)):(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
|
|
4511
4523
|
let o=0
|
|
4512
4524
|
for(const s of e){const e=s.type
|
|
4513
4525
|
if(!["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(e))continue
|
|
@@ -4549,17 +4561,17 @@ return s.default.writeFileSync(t,JSON.stringify(c,null,2)),n(e,t,r),h.info("Crea
|
|
|
4549
4561
|
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}}
|
|
4550
4562
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.acquireProcessLock=function(e){const t=i.default.join(e,c.ALCHEMY_DIR_NAME)
|
|
4551
4563
|
let o,l
|
|
4552
|
-
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 p=process.pid,
|
|
4564
|
+
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 p=process.pid,m=(new Date).toISOString()
|
|
4553
4565
|
try{const e=function(e){if(!s.default.existsSync(e))return null
|
|
4554
4566
|
try{const t=s.default.readFileSync(e,"utf8").trim()
|
|
4555
4567
|
try{const e=JSON.parse(t)
|
|
4556
4568
|
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
|
|
4557
4569
|
const e={mode:"multi-agent",created:(new Date).toISOString(),hostname:"unknown"}
|
|
4558
4570
|
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)
|
|
4559
|
-
if(h.info("Lock acquisition attempt",{pid:p,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(),
|
|
4560
|
-
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,
|
|
4571
|
+
if(h.info("Lock acquisition attempt",{pid:p,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(),g=e.hostname!==c&&"unknown"!==e.hostname
|
|
4572
|
+
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,m)):g?(h.warn("\u26a0\ufe0f Clearing lock from different machine",{lockHostname:e.hostname,currentHostname:c}),r(o,l,p,m)):"multi-agent"===e.mode?function(e,t,r){try{let o={count:0,processes:[]}
|
|
4561
4573
|
if(s.default.existsSync(e)){const t=s.default.readFileSync(e,"utf8")
|
|
4562
|
-
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,
|
|
4574
|
+
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,m):(h.info("Taking over legacy lock",{currentPid:p,oldMode:e.mode}),r(o,l,p,m))}return h.info("No existing lock - creating new lock",{pid:p,mode:"multi-agent"}),r(o,l,p,m)}catch(e){return h.error("Error acquiring lock",{error:(0,d.getErrorMessage)(e),pid:p}),!1}}
|
|
4563
4575
|
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"
|
|
4564
4576
|
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
|
|
4565
4577
|
let r=0,n=0
|
|
@@ -4607,16 +4619,16 @@ function r(e){const t=c[e]
|
|
|
4607
4619
|
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.`)
|
|
4608
4620
|
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)
|
|
4609
4621
|
if(!s(u.projectId)){const t=Error(`Invalid projectId format: ${u.projectId}. Cannot create failure record without valid projectId.`)
|
|
4610
|
-
throw l.error("Cannot create failure record due to invalid projectId",{toolName:e,projectId:u.projectId,error:t.message}),t}const h=Date.now(),p=e.replace(/-/g,"_"),
|
|
4622
|
+
throw l.error("Cannot create failure record due to invalid projectId",{toolName:e,projectId:u.projectId,error:t.message}),t}const h=Date.now(),p=e.replace(/-/g,"_"),m=(0,i.getErrorMessage)(t),g=t instanceof Error?t.stack:void 0
|
|
4611
4623
|
try{const t=r(e),s={}
|
|
4612
4624
|
let i,f
|
|
4613
4625
|
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})))
|
|
4614
|
-
let y=u.note||`Failed to execute ${e}: ${
|
|
4626
|
+
let y=u.note||`Failed to execute ${e}: ${m.substring(0,100)}${m.length>100?"...":""}`
|
|
4615
4627
|
Object.keys(s).length>0&&(y+=` (Warning: Invalid IDs provided: ${Object.entries(s).map((([e,t])=>`${e}: ${t}`)).join(", ")})`)
|
|
4616
|
-
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:
|
|
4617
|
-
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:
|
|
4628
|
+
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:m,errorStack:g,originalToolName:e,timestamp:(new Date).toISOString(),invalidIds:Object.keys(s).length>0?s:void 0,...a}}
|
|
4629
|
+
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:m})
|
|
4618
4630
|
const b=await c.createToolRecord(w)
|
|
4619
|
-
d.recordValue(p+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(p+"_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(p+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(p+"_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:
|
|
4631
|
+
d.recordValue(p+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(p+"_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(p+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(p+"_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:m}),t}}
|
|
4620
4632
|
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"
|
|
4621
4633
|
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)
|
|
4622
4634
|
else if(e&&"object"==typeof e)for(const t of Object.keys(e)){const n=e[t]
|
|
@@ -4641,13 +4653,13 @@ function r(e,t,r){const n=exports.ERROR_TYPE_PROPERTIES[e]||exports.ERROR_TYPE_P
|
|
|
4641
4653
|
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)
|
|
4642
4654
|
return{statusCode:e.statusCode,body:t}}if(e instanceof Error&&"ConnectionError"===e.name){const t=e
|
|
4643
4655
|
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")
|
|
4644
|
-
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 p(e,t)},exports.createFileOperationError=function(e="File operation error",t){return new
|
|
4656
|
+
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 p(e,t)},exports.createFileOperationError=function(e="File operation error",t){return new m(e,t)},exports.createMcpProtocolError=function(e="MCP protocol error",t){return new g(e,t)},exports.isAppError=n,exports.errorToResponse=o,exports.isRetryableError=s
|
|
4645
4657
|
const i=t(7388)
|
|
4646
4658
|
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}
|
|
4647
4659
|
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)
|
|
4648
4660
|
const o=exports.ERROR_TYPE_PROPERTIES[this.code]
|
|
4649
4661
|
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 p extends a{constructor(e="Service unavailable",t){if(super(e,i.SERVICE_UNAVAILABLE,503,t),t&&"structuredError"in t){const e=t.structuredError
|
|
4650
|
-
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class
|
|
4662
|
+
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class m extends a{constructor(e="File operation error",t){super(e,"FILE_OPERATION_ERROR",500,t)}}class g 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=p,exports.FileOperationError=m,exports.McpProtocolError=g,exports.UnauthorizedError=d},8712(e,exports){"use strict"
|
|
4651
4663
|
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}
|
|
4652
4664
|
const o=e.split("\n"),s=[],i=new Set
|
|
4653
4665
|
let a=!1,c=""
|
|
@@ -4690,7 +4702,7 @@ if("string"==typeof r&&r.length>0)return`${e}: ${r}`}return"Unknown error (no re
|
|
|
4690
4702
|
async function r(e,t,r,o,s,i,a,c,l,d){const u=a?function(e){const t=e.match(/^(\d+)([mhdw])$/)
|
|
4691
4703
|
return t?`${parseInt(t[1],10)}.${{m:"minutes",h:"hours",d:"days",w:"weeks"}[t[2]]}.ago`:e}(a):void 0
|
|
4692
4704
|
try{let a
|
|
4693
|
-
if(i===await
|
|
4705
|
+
if(i===await g(e,l,d))a=await e.log({file:t,maxCount:r,...u&&{"--since":u}})
|
|
4694
4706
|
else try{a=await e.log({from:i,file:t,maxCount:r,...u&&{"--since":u}})}catch(a){l.debug("git.log with 'from' failed, trying raw command",{fromError:a})
|
|
4695
4707
|
try{const a=await e.raw(["log","--max-count="+r,"--pretty=format:%H|%an|%ad|%s","--date=iso",...u?["--since="+u]:[],i,"--",t])
|
|
4696
4708
|
if(a&&a.trim()){const r=a.trim().split("\n").map((e=>{const[t,r,n,o]=e.split("|")
|
|
@@ -4713,26 +4725,26 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4713
4725
|
var t={}
|
|
4714
4726
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
4715
4727
|
return i(t,e),t})
|
|
4716
|
-
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"),
|
|
4717
|
-
try{const o=e,{path:a,limit:
|
|
4728
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileHistory=async function(e,t,n,o,s){const i=o.child({tool:"file_history"}),a=s.startTimer("tool_execution_time"),m=Date.now()
|
|
4729
|
+
try{const o=e,{path:a,limit:g,showDiff:f,showTraceability:y,branch:w,commit:b,since:I}=o
|
|
4718
4730
|
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,"/")
|
|
4719
4731
|
if(n.info("Getting full diff for commit",{filePath:e,commit:t}),!o)return{content:[{type:"text",text:"\u274c Git not initialized"}],isError:!0}
|
|
4720
4732
|
try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
|
|
4721
4733
|
if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
|
|
4722
4734
|
const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
|
|
4723
4735
|
let a="# File History - Commit Diff\n\n"
|
|
4724
|
-
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:
|
|
4736
|
+
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:g,showDiff:f,showTraceability:y,branch:w}),await async function(e,t,n,o,s,i,a,c,h,m,g){try{const{normalizedPath:f,fullPath:y}=p.validateAndNormalizePath(e,a)
|
|
4725
4737
|
try{await l.access(y)}catch(e){throw Error("File not found: "+f)}const w=a.git
|
|
4726
4738
|
if(!w)throw Error("Git is not available in this context")
|
|
4727
4739
|
let b={branch:null,requestId:null,isMain:!0}
|
|
4728
4740
|
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=""
|
|
4729
|
-
if(s)I=await r(w,f,t,n,o,s,i,c,h,
|
|
4730
|
-
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,
|
|
4731
|
-
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,
|
|
4741
|
+
if(s)I=await r(w,f,t,n,o,s,i,c,h,m),k=`## File History: ${f} (Branch: ${s})\n\n`
|
|
4742
|
+
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,m)}]}
|
|
4743
|
+
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,m)}]}
|
|
4732
4744
|
{const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
|
|
4733
4745
|
if(!i.isMain&&i.branch){const p=await r(e,t,n,o,s,i.branch,a,c,l,d)
|
|
4734
|
-
u.push(...p),p.length>0&&h.push(i.branch+" (current)")}const p=await r(e,t,n,o,s,"main",a,c,l,d),
|
|
4735
|
-
return u.push(...
|
|
4746
|
+
u.push(...p),p.length>0&&h.push(i.branch+" (current)")}const p=await r(e,t,n,o,s,"main",a,c,l,d),m=new Set(u.map((e=>e.hash))),g=p.filter((e=>!m.has(e.hash)))
|
|
4747
|
+
return u.push(...g),p.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,m)
|
|
4736
4748
|
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}]}
|
|
4737
4749
|
const v=I.length,C=Math.min(I.length,t)
|
|
4738
4750
|
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:** "
|
|
@@ -4741,9 +4753,9 @@ for(let e=0;e<I.length;e++){const t=I[e]
|
|
|
4741
4753
|
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")
|
|
4742
4754
|
let r=0,n=0
|
|
4743
4755
|
for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
|
|
4744
|
-
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()-
|
|
4756
|
+
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()-g}),m.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:k}]}}catch(e){throw e}}(a,g,f,y,w,I,t,n,i,s,m))}catch(e){const t=Date.now()-m
|
|
4745
4757
|
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}}}
|
|
4746
|
-
const c=a(t(6928)),l=a(t(1943)),d=t(1181),u=t(2085),h=t(8824),p=a(t(5967)),
|
|
4758
|
+
const c=a(t(6928)),l=a(t(1943)),d=t(1181),u=t(2085),h=t(8824),p=a(t(5967)),m=a(t(7478)),{getCurrentBranch:g}=m},8849(e,exports,t){"use strict"
|
|
4747
4759
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
4748
4760
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
4749
4761
|
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=[]
|
|
@@ -4874,7 +4886,7 @@ let c
|
|
|
4874
4886
|
try{const e=await fetch(`http://localhost:${b}/api/project-settings`)
|
|
4875
4887
|
if(e.ok){const t=await e.json()
|
|
4876
4888
|
if(t.data?.defaultModel){const[e,...r]=t.data.defaultModel.split("/")
|
|
4877
|
-
c={providerID:e,modelID:r.join("/")}}}}catch{}const l=`${i.replace(/\/$/,"")}/session/${e}/prompt_async`,d={type:"text",text:t,metadata:s??(0,
|
|
4889
|
+
c={providerID:e,modelID:r.join("/")}}}}catch{}const l=`${i.replace(/\/$/,"")}/session/${e}/prompt_async`,d={type:"text",text:t,metadata:s??(0,m.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}:{}})})
|
|
4878
4890
|
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
|
|
4879
4891
|
if(!s)throw new u.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
|
|
4880
4892
|
return(0,w.logSessionIdentity)(""+r,"identity",{sessionId:s,fromCliOrigin:!!o?.sessionId}),s}function a(e){const t=[],r=e.content||{}
|
|
@@ -4886,42 +4898,42 @@ if(!b)throw new u.ValidationError("API client not available")
|
|
|
4886
4898
|
const{operation:v}=e
|
|
4887
4899
|
k.info("Session message operation",{operation:v}),p.incrementCounter("session_message_operations",1,{operation:v})
|
|
4888
4900
|
try{switch(v){case"send":if(!e.type)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
4889
|
-
return(0,
|
|
4901
|
+
return(0,m.withAlchemyKind)(await async function(e,t,r,c,d){const{type:h}=e
|
|
4890
4902
|
if(!h)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
4891
4903
|
const p=c.getSessionMessageClient()
|
|
4892
4904
|
if(!p)throw new u.ValidationError("Session message client not available")
|
|
4893
|
-
if("question"===h)return await async function(e,t,r,c,l,d){const{toSessionId:h,questionType:p,questionContent:
|
|
4894
|
-
if(!p||!
|
|
4905
|
+
if("question"===h)return await async function(e,t,r,c,l,d){const{toSessionId:h,questionType:p,questionContent:m,priority:g,expiresInHours:f,relatesTo:w}=e
|
|
4906
|
+
if(!p||!m?.question)throw new u.ValidationError("Question requires questionType and questionContent.question")
|
|
4895
4907
|
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)
|
|
4896
4908
|
if(!e)throw new u.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
|
|
4897
4909
|
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)
|
|
4898
|
-
if(!("alternatives"!==p||
|
|
4910
|
+
if(!("alternatives"!==p||m.options&&Array.isArray(m.options)))throw new u.ValidationError("Alternatives questions require options array")
|
|
4899
4911
|
r.info("Creating question",{fromSessionId:b,toSessionId:I,questionType:p})
|
|
4900
|
-
const k=await l.createQuestion({fromSessionId:b,toSessionId:I,questionType:p,question:
|
|
4912
|
+
const k=await l.createQuestion({fromSessionId:b,toSessionId:I,questionType:p,question:m.question,options:m.options,context:m.context,allowMultiple:m.allowMultiple,priority:g,expiresInHours:f,...w?{relatesTo:w}:{}})
|
|
4901
4913
|
let v=""
|
|
4902
|
-
if(I){const e=await n(b)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:
|
|
4914
|
+
if(I){const e=await n(b)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:m.question,questionType:p,options:m.options,context:m.context,allowMultiple:m.allowMultiple,fromAgent:e,fromSessionId:b,priority:k.priority,expiresAt:k.expiresAt,...w?{relatesTo:w}:{}}}}
|
|
4903
4915
|
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]
|
|
4904
4916
|
if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&&t.options){r.push(""),r.push("**Options:**")
|
|
4905
4917
|
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,p,d)
|
|
4906
|
-
if("report"===h)return await async function(e,t,r,a,c,d){const{status:h,summary:p,details:
|
|
4918
|
+
if("report"===h)return await async function(e,t,r,a,c,d){const{status:h,summary:p,details:m,finish:f,relatesTo:w}=e
|
|
4907
4919
|
if(!h||!p)throw new u.ValidationError("Report requires status and summary")
|
|
4908
4920
|
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)
|
|
4909
4921
|
const t=await s(b,a,r)
|
|
4910
4922
|
if(t)return r.info("Auto-resolved parent session",{parentSessionId:t}),t
|
|
4911
4923
|
throw new u.ValidationError("Could not find parent session. Ensure this session was created with a parent link, or provide an explicit toSessionId.")})()
|
|
4912
4924
|
r.info("Submitting report",{sessionId:b,parentSessionId:I,status:h})
|
|
4913
|
-
const k=await c.createReport({fromSessionId:b,toSessionId:I,status:h,summary:p,details:
|
|
4914
|
-
return(0,
|
|
4925
|
+
const k=await c.createReport({fromSessionId:b,toSessionId:I,status:h,summary:p,details:m,...w?{relatesTo:w}:{}}),v=await n(b)??"agent",C={alchemy:{kind:"worker-report",payload:{status:h,summary:p,details:m,fromAgent:v,fromSessionId:b,...w?{relatesTo:w}:{}}}},_=await o(I,function(e,t="agent"){const r=e.content||{}
|
|
4926
|
+
return(0,g.formatReportNotification)({messageCode:e.messageCode,status:r.reportStatus,summary:r.summary,details:r.details,fromSessionId:e.fromSessionId,senderAgent:t})}(k,v),t,r,C)
|
|
4915
4927
|
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,p,d)
|
|
4916
4928
|
throw new u.ValidationError(`Unknown message type: ${h}. Use "question" or "report".`)}(e,t,k,b,I),r("send",e))
|
|
4917
4929
|
case"reply":if(!e.messageCode)throw new u.ValidationError("reply operation requires messageCode")
|
|
4918
|
-
return(0,
|
|
4930
|
+
return(0,m.withAlchemyKind)(await async function(e,t,r,s,i){const{messageCode:c}=e
|
|
4919
4931
|
if(!c)throw new u.ValidationError("reply operation requires messageCode")
|
|
4920
4932
|
const d=s.getSessionMessageClient()
|
|
4921
4933
|
if(!d)throw new u.ValidationError("Session message client not available")
|
|
4922
4934
|
if(c.startsWith("Q-")){const{text:s,selectedOptions:l,notes:u}=e,h=e.respondedBySessionId??i?.sessionId
|
|
4923
4935
|
r.info("Answering question",{messageCode:c,respondedBySessionId:h,autoDerived:!e.respondedBySessionId})
|
|
4924
|
-
const p=await d.answerQuestion(c,{respondedBySessionId:h,text:s,selectedOptions:l,notes:u}),
|
|
4936
|
+
const p=await d.answerQuestion(c,{respondedBySessionId:h,text:s,selectedOptions:l,notes:u}),m=h?await n(h)??"agent":"agent",g=p.content||{},f=p.response||{},y={alchemy:{kind:"question-answered",payload:{messageCode:p.messageCode,question:g.question,answer:f.text,selectedOptions:f.selectedOptions,notes:f.notes,answeredByAgent:m,answeredBySessionId:h}}},w=await o(p.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]
|
|
4925
4937
|
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")}(p),t,r,y)
|
|
4926
4938
|
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(p)}`}]}}if(c.startsWith("R-")){r.info("Acknowledging report",{messageCode:c})
|
|
4927
4939
|
const e=await d.acknowledgeReport(c)
|
|
@@ -4936,21 +4948,21 @@ let l
|
|
|
4936
4948
|
try{const e=b.getSessionMessageClient()
|
|
4937
4949
|
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"})
|
|
4938
4950
|
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()
|
|
4939
|
-
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,
|
|
4940
|
-
const
|
|
4941
|
-
if(!
|
|
4951
|
+
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,m.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,m.alchemyMeta)({pendingAction:{kind:"plan-handoff",payload:{summary:t.summary,requestIds:t.requestIds,parentSessionId:o,fromSessionId:r,autoConfirmed:a}}})},"offer-handoff")}case"list":return(0,m.withAlchemyKind)(await async function(e,t,r,n,o){let{sessionId:s,messageType:i,direction:a,status:c,readStatus:l,reportStatus:h,limit:p,offset:m}=e
|
|
4952
|
+
const g=n.getSessionMessageClient()
|
|
4953
|
+
if(!g)throw new u.ValidationError("Session message client not available")
|
|
4942
4954
|
if(!s){const e=o?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
|
|
4943
4955
|
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."}]}
|
|
4944
4956
|
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})
|
|
4945
|
-
const y={sessionId:s,direction:a,limit:p,offset:
|
|
4957
|
+
const y={sessionId:s,direction:a,limit:p,offset:m}
|
|
4946
4958
|
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)
|
|
4947
|
-
const b=await
|
|
4959
|
+
const b=await g.listMessages(y)
|
|
4948
4960
|
if(0===b.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
|
|
4949
4961
|
const I=[`Found ${b.length} message(s):\n`]
|
|
4950
4962
|
for(const e of b)I.push("---\n"),I.push(d(e)),I.push("")
|
|
4951
4963
|
return{content:[{type:"text",text:I.join("\n")}]}}(e.list||{},0,k,b,I),"list-messages")
|
|
4952
4964
|
case"get":if(!e.messageCode)throw new u.ValidationError("get operation requires messageCode")
|
|
4953
|
-
return(0,
|
|
4965
|
+
return(0,m.withAlchemyKind)(await async function(e,t,r){const{messageCode:n}=e
|
|
4954
4966
|
if(!n)throw new u.ValidationError("get operation requires messageCode")
|
|
4955
4967
|
const o=r.getSessionMessageClient()
|
|
4956
4968
|
if(!o)throw new u.ValidationError("Session message client not available")
|
|
@@ -4958,7 +4970,7 @@ t.debug("Getting message",{messageCode:n})
|
|
|
4958
4970
|
const s=await o.getMessage(n)
|
|
4959
4971
|
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")
|
|
4960
4972
|
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}}}
|
|
4961
|
-
const u=t(9860),h=t(8824),p=t(7617),
|
|
4973
|
+
const u=t(9860),h=t(8824),p=t(7617),m=t(2272),g=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"
|
|
4962
4974
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4963
4975
|
const r=t(6183),n=t(1281)
|
|
4964
4976
|
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"
|
|
@@ -4984,12 +4996,12 @@ let l,d
|
|
|
4984
4996
|
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)})
|
|
4985
4997
|
let u=0
|
|
4986
4998
|
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})
|
|
4987
|
-
let h=!1,p="",
|
|
4988
|
-
if(0!==u?(h=!0,p="merge-tree-exit-code"):d&&d.trim()?(
|
|
4989
|
-
!
|
|
4990
|
-
let
|
|
4991
|
-
if(
|
|
4992
|
-
else try{
|
|
4999
|
+
let h=!1,p="",m=null
|
|
5000
|
+
if(0!==u?(h=!0,p="merge-tree-exit-code"):d&&d.trim()?(m=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch),m.hasConflictMarkers?(h=!0,p="conflict-parser-detected-markers",r.warn("Git exit code 0 but conflict parser found conflict markers - treating as conflict")):(h=!1,p="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,p="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:p,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}
|
|
5001
|
+
!m&&d&&d.trim()&&(m=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch))
|
|
5002
|
+
let g=[]
|
|
5003
|
+
if(m&&m.filesParsed&&m.filesParsed.length>0)g=m.filesParsed.map((e=>({path:e,conflictType:"content",description:"Merge conflict detected"}))),r.debug("Successfully extracted conflict files from parsed content",{conflictedFilesCount:g.length,files:g.map((e=>e.path))})
|
|
5004
|
+
else try{g=this.parseMergeTreeOutput(d,r),r.debug("Used fallback merge-tree parsing",{conflictedFilesCount:g.length})}catch(e){r.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),g=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===g.length&&(r.warn("Git detected conflicts but no files could be determined - using fallback"),g=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:g,summary:g.length>0&&"<parsing failed>"!==g[0].path&&"<unknown files>"!==g[0].path?g.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateMultiAgentInstructions(g,e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:d,rawConflictContent:m?m.cleanContent:void 0}}catch(e){throw r.error("Pure multi-agent conflict detection failed",{error:e}),e}}parseMergeTreeOutput(e,t){const r=[]
|
|
4993
5005
|
if(!e||!e.trim())return t.debug("Empty merge-tree output - no conflicts to parse"),[]
|
|
4994
5006
|
let n
|
|
4995
5007
|
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
|
|
@@ -5045,23 +5057,23 @@ o+=`## Test 4: All commits containing "${n}" (not just merges)\n`,o+=`Found ${e?
|
|
|
5045
5057
|
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()
|
|
5046
5058
|
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}}}
|
|
5047
5059
|
const r=t(8824)},9442(e,exports,t){"use strict"
|
|
5048
|
-
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:p,fuzzy_match:
|
|
5060
|
+
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:p,fuzzy_match:m}=e,g=!!d,f=void 0!==m?m:t,y={type:g?"document":"file",path:c,documentId:d,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,externalEditDebugInfo:{detectionRan:!1,reason:g?"Skipped: Document operation":n.git?"Pending":"Skipped: No Git context"}}
|
|
5049
5061
|
try{let t,o
|
|
5050
|
-
if(
|
|
5062
|
+
if(g){t=await n.documentFileManager.getDocumentAsFile(d)
|
|
5051
5063
|
const e=n.documentFileManager.getCachedDocumentInfo(d)
|
|
5052
5064
|
y.filename=e?.filename,o="document:"+d}else{const e=u.validateAndNormalizePath(c,n)
|
|
5053
|
-
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),
|
|
5065
|
+
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),m=[]
|
|
5054
5066
|
for(const t of p){const{old:n,new:o,match_mode:i="unique"}=t,a={old:n,new:o,success:!1}
|
|
5055
5067
|
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)
|
|
5056
5068
|
continue}const t=(0,h.findMatches)(s,n,f,100,e.path)
|
|
5057
5069
|
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(f?" (tried fuzzy matching)":""),a.success=!1
|
|
5058
5070
|
const e=(0,h.findSimilarMatches)(s,n,5,.3)
|
|
5059
|
-
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++):
|
|
5071
|
+
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++):m.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
|
|
5060
5072
|
const I=[]
|
|
5061
|
-
for(const e of
|
|
5073
|
+
for(const e of m)for(const t of e.matches)I.push({match:t,newText:e.newText,repResult:e.repResult})
|
|
5062
5074
|
I.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5063
5075
|
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++)
|
|
5064
|
-
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),
|
|
5076
|
+
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),g&&(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=p.length,y.replacements=p.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)
|
|
5065
5077
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5066
5078
|
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=[]
|
|
5067
5079
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -5091,7 +5103,7 @@ const t=await u.autoPromoteTaskStatus(T,D.status,A,e.request?.status,j,o,i,k,c,"
|
|
|
5091
5103
|
t.taskPromoted&&k.info("Auto-promoted task to in_progress",{taskId:T,requestId:A,previousStatus:D.status,newStatus:t.newTaskStatus}),Date.now(),O=Date.now()
|
|
5092
5104
|
const n=await u.ensureCorrectWorkspaceContext({taskPromoted:t.taskPromoted,requestId:A,context:r,operation:"replace_in_files",logger:k,metrics:c,metricsPrefix:"replace_in_files"})
|
|
5093
5105
|
if(!n.success)throw Error(n.error)
|
|
5094
|
-
Date.now(),N=!0}if(M.length>0&&A)try{await(0,
|
|
5106
|
+
Date.now(),N=!0}if(M.length>0&&A)try{await(0,m.validateRequestStatusForDocumentOperation)(A,i,k,c,"replace_in_files-documents")}catch(e){if(e instanceof p.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5095
5107
|
throw e}O=Date.now()
|
|
5096
5108
|
const z=new Map
|
|
5097
5109
|
if(k.info("\u{1f50d} Starting external edit detection",{hasFileOperations:F,hasGit:!!r.git,operationCount:x.length}),F&&r.git)for(const e of x)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:P,s=[]
|
|
@@ -5100,7 +5112,7 @@ s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,t.fullP
|
|
|
5100
5112
|
k.info("\u{1f50d} Checking for external edits",{path:t.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
|
|
5101
5113
|
const i=await(0,w.detectExternalEdits)(r.git,o,k)
|
|
5102
5114
|
k.info("\u{1f50d} External edit detection result",{path:t.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(z.set(e.path,{message:i.message,debugInfo:i.debugInfo}),k.warn("\u26a0\ufe0f External edits detected before auto-commit",{path:t.normalizedPath,conflictingLines:i.conflictingLines})):(i.debugInfo&&z.set(e.path,{message:"",debugInfo:i.debugInfo}),k.info("\u2705 No external edit conflicts detected",{path:t.normalizedPath}))}else k.info("\u2139\ufe0f No matches found for external edit detection",{path:t.normalizedPath}),z.set(e.path,{message:"",debugInfo:{detectionRan:!1,reason:"No matches found - patterns not found in file",affectedRegion:"none",uncommittedChanges:"not checked",overlapDetected:!1}})}catch(t){k.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,b.getErrorMessage)(t)})}if(Date.now(),O=Date.now(),F&&r.git)try{k.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
|
|
5103
|
-
const e=await(0,
|
|
5115
|
+
const e=await(0,g.commitUserChangesBeforeToolOperation)(r.git,"replace_in_files",{requestId:A,taskId:T,workspaceManager:r.workspaceManager},k,c)
|
|
5104
5116
|
e.userChangesCommitted&&(k.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),k.info("User changes committed before batch operation",{taskId:T,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){k.warn("Pre-tool user changes commit failed",{taskId:T,error:e instanceof Error?e.message:e+""})}Date.now(),O=Date.now(),_=u.FileOperationPhase.RECORD_CREATION,c.incrementCounter("replace_in_files_phase",1,{phase:_})
|
|
5105
5117
|
const{toolRecordId:L}=await u.createFileOperationRecords(T,A,r.projectId,"replace-in-files",j,{operationCount:x.length,totalReplacements:x.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:P,userComment:R},o,s,k,c,"replace_in_files",I)
|
|
5106
5118
|
C=L,Date.now(),O=Date.now(),_=u.FileOperationPhase.STRING_REPLACEMENT,c.incrementCounter("replace_in_files_phase",1,{phase:_})
|
|
@@ -5127,7 +5139,7 @@ const d=o.workspaceManager?.consumeLargeFileWarning(o.currentSessionId)
|
|
|
5127
5139
|
return d&&(c+=d),c}(H,W,J,Q,r)
|
|
5128
5140
|
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
|
|
5129
5141
|
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))
|
|
5130
|
-
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(2272)),u=a(t(5967)),h=t(3626),p=t(9860),
|
|
5142
|
+
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(2272)),u=a(t(5967)),h=t(3626),p=t(9860),m=t(5003),g=t(7478),f=t(9949),y=t(9947),w=t(1318),b=t(8824)},9470(e,exports){"use strict"
|
|
5131
5143
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
|
|
5132
5144
|
const t=e.trim()
|
|
5133
5145
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|
|
@@ -5198,11 +5210,11 @@ if(!u)throw new r.ValidationError("Project ID is required for listing tasks with
|
|
|
5198
5210
|
a.incrementCounter("list_tasks_attempts",1,{hasRequestId:!!i,hasFilters:Object.keys(d).length>0}),s.setProjectId(u)
|
|
5199
5211
|
const h=s.getTaskClient(),p=d
|
|
5200
5212
|
i&&(p.requestId=i),c.info("Listing tasks with filters",{projectId:u,taskFilters:p})
|
|
5201
|
-
const
|
|
5202
|
-
c.info("Raw tasks response data",{responseData:JSON.stringify(
|
|
5203
|
-
let
|
|
5204
|
-
|
|
5205
|
-
const f=
|
|
5213
|
+
const m=await h.listTasks(p)
|
|
5214
|
+
c.info("Raw tasks response data",{responseData:JSON.stringify(m)}),c.info("Tasks response structure",{type:typeof m,isArray:Array.isArray(m),hasData:null!=m,properties:m?Object.keys(m):[],dataPreview:m?JSON.stringify(m).substring(0,200)+"...":"null"})
|
|
5215
|
+
let g=[]
|
|
5216
|
+
m&&"object"==typeof m?"success"in m&&"data"in m?Array.isArray(m.data)?(g=m.data,c.info("Extracted tasks from success/data wrapper",{count:g.length})):m.data&&"object"==typeof m.data&&(g=[m.data],c.info("Extracted single task from success/data wrapper")):"data"in m?Array.isArray(m.data)?(g=m.data,c.info("Extracted tasks from data wrapper",{count:g.length})):m.data&&"object"==typeof m.data&&(g=[m.data],c.info("Extracted single task from data wrapper")):Array.isArray(m)?(g=m,c.info("Tasks response is direct array",{count:g.length})):(g=[m],c.info("Tasks response is single object")):(c.warn("Unexpected response format, using empty array",{responseType:typeof m}),g=[])
|
|
5217
|
+
const f=g
|
|
5206
5218
|
if(c.info(`Retrieved ${f.length} tasks`,{count:f.length,requestId:i,projectId:u}),0===f.length){let e=""
|
|
5207
5219
|
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
|
|
5208
5220
|
return`**[${(0,o.formatTaskRefForAgent)(i?(0,o.formatTaskRef)(i,r):e.localId||e.id)}]** ${e.title}\nStatus: ${e.status}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}`})).join("\n\n")
|