alchemylab 1.4.2 → 1.4.4
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 +175 -141
- package/dist/http-server.js +89 -69
- package/dist/index.js +89 -69
- package/dist/mcp-direct.js +617 -597
- 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)
|
|
@@ -1161,7 +1161,11 @@ try{if(o.default.existsSync(this.projectFilePath)){this.logger.debug("Updating e
|
|
|
1161
1161
|
const t=JSON.parse(o.default.readFileSync(this.projectFilePath,"utf8"))
|
|
1162
1162
|
t.id=e,t.updatedAt=(new Date).toISOString(),o.default.writeFileSync(this.projectFilePath,JSON.stringify(t,null,2)),this.logger.info("Successfully updated project.json file",{path:this.projectFilePath,oldId:this.projectId,newId:e})}else this.logger.warn("project.json file does not exist, cannot update",{path:this.projectFilePath,projectId:e})
|
|
1163
1163
|
this.projectId=e,this.initialized=!0,this.logger.info("Project ID update completed successfully",{projectId:e,filePath:this.projectFilePath})}catch(t){const r=(0,c.getErrorMessage)(t),n=`Cannot start AlchemyMCP: Unable to update project.json file.\nFile: ${this.projectFilePath}\nProject ID: ${e}\n\nPlease check:\n\u2022 File permissions - ensure you can write to the alchemy_lab directory\n\u2022 Disk space - ensure sufficient space available\n\u2022 File not in use - close any editors that might have project.json open\n\u2022 Directory exists - alchemy_lab folder should be writable\n\nOriginal error: `+r
|
|
1164
|
-
throw this.logger.error("Critical: Project ID update failed, cannot start server",{error:t instanceof Error?t.stack:t+"",projectId:e,filePath:this.projectFilePath,directory:this.alchemyPath}),Error(n)}}isInitialized(){return this.initialized}createMiddleware(){return r(this.getProjectId(),this.logger)}}},
|
|
1164
|
+
throw this.logger.error("Critical: Project ID update failed, cannot start server",{error:t instanceof Error?t.stack:t+"",projectId:e,filePath:this.projectFilePath,directory:this.alchemyPath}),Error(n)}}isInitialized(){return this.initialized}createMiddleware(){return r(this.getProjectId(),this.logger)}}},1816(e,exports){"use strict"
|
|
1165
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatCommandOutput=function(e,n,o){const s=o.maxOut??t,i=o.maxErr??r,a=e.length>s,c=n.length>i,l=a||c
|
|
1166
|
+
return{output:[a?"\u2026"+e.slice(-s):e,c?"\u2026"+n.slice(-i):n].filter(Boolean).join("\n")||"(no output)",truncatedNote:l?`\n_(output truncated \u2014 view full with \`log:${o.invocationId}\`)_`:"",logFooter:`Log: \`log:${o.invocationId}\``}},exports.formatCombinedOutput=function(e,r){const n=r.maxOut??t,o=e.length>n
|
|
1167
|
+
return{output:o?"\u2026"+e.slice(-n):e,truncatedNote:o?`\n_(output truncated \u2014 view full with \`log:${r.invocationId}\`)_`:"",logFooter:`Log: \`log:${r.invocationId}\``}}
|
|
1168
|
+
const t=3e3,r=1500},1887(e,exports,t){"use strict"
|
|
1165
1169
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProxyClient=void 0
|
|
1166
1170
|
const r=t(9860),n=t(5674),o=t(4192),s=t(2161),i=t(8824)
|
|
1167
1171
|
class a extends o.BaseApiClient{constructor(e,t,r,n,o,s,i){super(e,t.child({component:"proxy-client"}),r,o,i),this.projectClient=n,this.connectionStatusManager=s,this.logger.info("Proxy client initialized")}setConnectionStatusManager(e){this.logger.debug("Setting connection status manager in ProxyClient"),this.connectionStatusManager=e,this.logger.info("Connection status manager set on "+this.constructor.name)}setAlchemyPath(e){this.logger.info(`Set alchemy path to ${e} on ${this.constructor.name}`)}isNetworkError(e){return"ECONNREFUSED"===e?.code||"ECONNRESET"===e?.code||"ETIMEDOUT"===e?.code||e?.message?.includes("network")||e?.message?.includes("connection")||"ConnectionError"===e?.name||503===e?.status||504===e?.status}isOffline(){return this.connectionStatusManager?.isOffline()||!1}async handlePotentialOfflineOperation(e,t,r){if(this.isOffline()){this.logger.info(`Operation ${e} attempted while offline`,{params:JSON.stringify(t).substring(0,100)+"..."})
|
|
@@ -1248,15 +1252,20 @@ try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.ge
|
|
|
1248
1252
|
if(p.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
|
|
1249
1253
|
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
1254
|
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
|
|
1255
|
+
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")
|
|
1256
|
+
try{f.mkdirSync(w,{recursive:!0})}catch{}const{runTrackedShellCommand:b}=await Promise.resolve().then(t.bind(t,4600)),{formatCombinedOutput:I}=await Promise.resolve().then(t.bind(t,1816)),{sessionIdentity:k}=await Promise.resolve().then(t.bind(t,6688)),v=k.getIdentity()?.sessionId
|
|
1252
1257
|
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
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1258
|
+
const r=`${t.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,n=g.join(w,r+".log")
|
|
1259
|
+
let o=null
|
|
1260
|
+
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:v,logPath:n})
|
|
1261
|
+
o&&(o.write(`\n# exit: ${s.exitCode}${s.timedOut?" (timed out)":""}\n`),o.end())
|
|
1262
|
+
const i=(s.stdout+(s.stderr?"\n"+s.stderr:"")).trim(),{output:a,truncatedNote:l,logFooter:d}=I(i,{invocationId:r})
|
|
1263
|
+
if(m.push({name:t.name,command:t.command,exitCode:s.exitCode,output:a,timedOut:s.timedOut,invocationId:r,truncatedNote:l,logFooter:d}),"setup"===e.commandName&&0!==s.exitCode)break}const C=m.every((e=>0===e.exitCode)),_=m.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
|
|
1264
|
+
return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\`${e.truncatedNote}\n${e.logFooter}`})).join("\n\n")
|
|
1265
|
+
return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${C?"PASSED":"FAILED"}\n\n${_}`}]}}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
1266
|
try{const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=await u.getSessionRequestId(i,a,l?.sessionId)
|
|
1258
1267
|
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`),
|
|
1268
|
+
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
1269
|
if(!f)return d({success:!1,error:"no_test_run"}),{content:[{type:"text",text:`No test run found for request ${h}.`}],isError:!0}
|
|
1261
1270
|
const y=f.id
|
|
1262
1271
|
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 +1283,13 @@ try{const e=await i.proxyGet(`/api/projects/${n.projectId}/test-processes`),t=e?
|
|
|
1274
1283
|
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
1284
|
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
1285
|
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:
|
|
1286
|
+
const m=e.name?[e.name]:void 0
|
|
1287
|
+
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
1288
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
1280
1289
|
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
1290
|
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:
|
|
1291
|
+
const r=t.data.spawnedSessionIds?.[0],n=m?` (filtered to: ${m.join(", ")})`:""
|
|
1292
|
+
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
1293
|
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
1294
|
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
1295
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
@@ -1328,13 +1337,13 @@ if("user"===r.info?.role)for(const e of r.parts??[]){if("text"!==e.type||!e.text
|
|
|
1328
1337
|
const t=e.text.match(/<viewed_session\s+id="([^"]+)"\s*\/?>/)
|
|
1329
1338
|
if(t)return t[1]}}return null}(h)
|
|
1330
1339
|
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(
|
|
1340
|
+
let m
|
|
1341
|
+
try{m=function(e){for(let t=e.length-1;t>=0;t--){const r=e[t]
|
|
1342
|
+
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")}]}
|
|
1343
|
+
m&&(g.agent=m),t.info("commit_to_viewed_session:posting",{callId:i,viewedId:p,heraldId:d,agent:m})
|
|
1344
|
+
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
1345
|
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:
|
|
1346
|
+
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
1347
|
const n=t(8824),o=t(6688),s=t(2272)},2141(e,exports,t){"use strict"
|
|
1339
1348
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConflictResolver=void 0,exports.createConflictResolver=function(e){return new n(e)}
|
|
1340
1349
|
const r=t(8824)
|
|
@@ -1410,29 +1419,29 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
1410
1419
|
var t={}
|
|
1411
1420
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
1412
1421
|
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
|
|
1422
|
+
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
1423
|
let w,b,I=l.FileOperationPhase.VALIDATION
|
|
1415
1424
|
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
1425
|
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
1426
|
if("errorResult"in _)return _.errorResult
|
|
1418
1427
|
const{taskId:E}=_
|
|
1419
1428
|
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,
|
|
1429
|
+
l.validateTaskIdFormat(E,f,m,k.metricsPrefix)
|
|
1421
1430
|
const S=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1422
1431
|
f.info("Initial branch context",{initialBranch:S.branch,initialRequestId:S.requestId,isMain:S.isMain})
|
|
1423
1432
|
const q=[]
|
|
1424
1433
|
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,
|
|
1434
|
+
q.push({source:t,destination:o,fullSource:n,fullDestination:s})}I=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("move_files_phase",1,{phase:I})
|
|
1435
|
+
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
1436
|
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:
|
|
1437
|
+
const M=await l.ensureCorrectWorkspaceContext({taskPromoted:R.taskPromoted,requestId:x,context:r,operation:"move-files",logger:f,metrics:m,metricsPrefix:k.metricsPrefix})
|
|
1429
1438
|
if(!M.success)throw Error(M.error)
|
|
1430
1439
|
let $={hadUserMods:!1,userModsCommitHash:void 0}
|
|
1431
1440
|
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,
|
|
1441
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:x,taskId:E,workspaceManager:r.workspaceManager},f,m)
|
|
1442
|
+
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})
|
|
1443
|
+
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)
|
|
1444
|
+
w=j,b=j,I=k.fileOperationPhase,m.incrementCounter("move_files_phase",1,{phase:I})
|
|
1436
1445
|
const D=[]
|
|
1437
1446
|
let A=0
|
|
1438
1447
|
for(const e of q){const t={operation:{source:e.source,destination:e.destination},success:!1}
|
|
@@ -1440,13 +1449,13 @@ try{try{await a.default.access(e.fullSource)}catch(t){throw Error("Source path n
|
|
|
1440
1449
|
t.isDirectory=r
|
|
1441
1450
|
const n=c.default.dirname(e.fullDestination)
|
|
1442
1451
|
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
|
-
|
|
1452
|
+
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
1453
|
let N=null
|
|
1445
|
-
if(A>0){I=l.FileOperationPhase.GIT_COMMIT,
|
|
1454
|
+
if(A>0){I=l.FileOperationPhase.GIT_COMMIT,m.incrementCounter("move_files_phase",1,{phase:I})
|
|
1446
1455
|
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,
|
|
1456
|
+
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
1457
|
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,
|
|
1458
|
+
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
1459
|
const H=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1451
1460
|
let B=""
|
|
1452
1461
|
if(A===u.length)B=`Successfully moved all ${u.length} ${1===u.length?"item":"items"}`
|
|
@@ -1454,8 +1463,8 @@ else if(A>0){const e=D.filter((e=>!e.success))
|
|
|
1454
1463
|
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
1464
|
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
1465
|
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,
|
|
1466
|
+
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
|
|
1467
|
+
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
1468
|
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
1469
|
module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){"use strict"
|
|
1461
1470
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
@@ -1464,7 +1473,7 @@ exports.def={name:"quick_manage",description:"WHEN TO USE: trivial single-file e
|
|
|
1464
1473
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildTaskEndpoint=function(e,t,r){const n=r?"/"+r.replace(/^\//,""):""
|
|
1465
1474
|
return`/api/projects/${e}/tasks/${encodeURIComponent(t)}${n}`}},2462(e,exports,t){"use strict"
|
|
1466
1475
|
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),
|
|
1476
|
+
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
1477
|
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
1478
|
async function r(e,t,r){if(v.has(r)&&C>=t){if(0===t)return 0
|
|
1470
1479
|
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 +1498,10 @@ let t=e,r=0
|
|
|
1489
1498
|
for(;t>=1024&&4>r;)t/=1024,r++
|
|
1490
1499
|
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
1500
|
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),
|
|
1501
|
+
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
1502
|
let f
|
|
1494
|
-
d.isFile()&&(f=await r(h,
|
|
1495
|
-
const I={name:d.name,isDirectory:d.isDirectory(),depth:n,size:
|
|
1503
|
+
d.isFile()&&(f=await r(h,m.size,g))
|
|
1504
|
+
const I={name:d.name,isDirectory:d.isDirectory(),depth:n,size:m.size,modified:m.mtime,extension:g,lineCount:f}
|
|
1496
1505
|
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
1506
|
const o=[]
|
|
1498
1507
|
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 +1527,21 @@ case"type":const o=e.extension||"",s=r.extension||""
|
|
|
1518
1527
|
return o!==s?o.localeCompare(s):e.name.localeCompare(r.name)
|
|
1519
1528
|
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
1529
|
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]}),
|
|
1530
|
+
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
1531
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
1523
1532
|
return t},h(e)},function(e){if(e&&e.__esModule)return e
|
|
1524
1533
|
var t={}
|
|
1525
1534
|
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&p(t,e,r[n])
|
|
1526
|
-
return
|
|
1535
|
+
return m(t,e),t}),f=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1527
1536
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
|
|
1528
1537
|
let p=b.FileOperationPhase.VALIDATION
|
|
1529
1538
|
b.FileOperationPhase.FILE_WRITE
|
|
1530
|
-
try{const
|
|
1531
|
-
i.info("Listing directory: "+
|
|
1532
|
-
const{normalizedPath:v,fullPath:C}=b.validateAndNormalizePath(
|
|
1539
|
+
try{const m=e,{path:g,levels:f=1,sortBy:I="name"}=m
|
|
1540
|
+
i.info("Listing directory: "+g)
|
|
1541
|
+
const{normalizedPath:v,fullPath:C}=b.validateAndNormalizePath(g,t)
|
|
1533
1542
|
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: "+
|
|
1543
|
+
try{if(!(await y.default.stat(C)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+g}],isError:!0}
|
|
1544
|
+
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
1545
|
if(f>1){i.info(`Building tree structure for: ${v} (levels: ${f}, sortBy: ${I})`)
|
|
1537
1546
|
const e=await o(v,t,0,f,I,i)
|
|
1538
1547
|
if(e.length>0){const t=s(e,I)
|
|
@@ -1545,7 +1554,7 @@ _+="\n\nBranch: "+(S?.branchName||"unknown")
|
|
|
1545
1554
|
const q=Date.now()-h
|
|
1546
1555
|
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
1556
|
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=
|
|
1557
|
+
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
1558
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SessionMessageClient=void 0
|
|
1550
1559
|
const r=t(7645),n=t(2161)
|
|
1551
1560
|
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 +1608,11 @@ const t=await this.requestWithRetry("POST",`/api/projects/${e}/session-messages/
|
|
|
1599
1608
|
return(0,n.safeGetResponseData)(t,{expiredCount:0},this.logger).expiredCount}}exports.SessionMessageClient=o},2736(e,exports,t){"use strict"
|
|
1600
1609
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,l,d,u,h){const p=u.child({tool:"complete_task"})
|
|
1601
1610
|
p.info("Completing task",{args:e})
|
|
1602
|
-
const
|
|
1611
|
+
const m=h.startTimer("tool_handler_duration")
|
|
1603
1612
|
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
1613
|
throw new r.ValidationError("Invalid input: "+(0,a.getErrorMessage)(e))}}(e)
|
|
1605
1614
|
let u=o.taskId
|
|
1606
|
-
const
|
|
1615
|
+
const g=o.summary;(0,c.isTaskRef)(u)&&(u=await(0,c.resolveTaskRef)(u,d,p))
|
|
1607
1616
|
const f=l.projectId
|
|
1608
1617
|
if(!f)throw new r.ValidationError("Project ID is required for completing tasks with the new API structure")
|
|
1609
1618
|
h.incrementCounter("complete_task_attempts",1,{taskId:u}),d.setProjectId(f)
|
|
@@ -1619,18 +1628,18 @@ throw p.warn(e,{taskId:u,currentStatus:w.status}),new r.ValidationError(e)}let b
|
|
|
1619
1628
|
if(l.workspaceManager){const e=l.workspaceManager.getCurrentContext(l.currentSessionId)
|
|
1620
1629
|
if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
|
|
1621
1630
|
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}: ${
|
|
1631
|
+
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
1632
|
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:
|
|
1633
|
+
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
1634
|
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
1635
|
const i=w.requestId,l=w.requestId
|
|
1627
1636
|
let d=`Task ${w.sequenceNumber&&l?(0,c.formatTaskRef)(l,w.sequenceNumber):u} (${w.title}) has been marked as completed.`
|
|
1628
1637
|
if(I&&(d+="\nCommit: "+I.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
|
|
1629
1638
|
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
1639
|
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
|
|
1640
|
+
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
1641
|
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+""})}
|
|
1642
|
+
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
1643
|
let n=(0,a.getErrorMessage)(t)
|
|
1635
1644
|
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
1645
|
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 +1648,12 @@ if(!r())return t.level=(0,l.isDevBuild)()?c.LogLevel.INFO:c.LogLevel.ERROR,t.log
|
|
|
1639
1648
|
if("true"===process.env.DEBUG_LOGGING?.toLowerCase()){t.level=c.LogLevel.DEBUG,t.logToFile=!0
|
|
1640
1649
|
const r=e||process.cwd()
|
|
1641
1650
|
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})}(
|
|
1651
|
+
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=[]
|
|
1652
|
+
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)
|
|
1653
|
+
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(g)
|
|
1645
1654
|
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&&
|
|
1655
|
+
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})
|
|
1656
|
+
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
1657
|
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
1658
|
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
1659
|
const e=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
@@ -1702,13 +1711,13 @@ i.info("Request breakdown",{fileRequests:d.length,documentRequests:u.length})
|
|
|
1702
1711
|
const h=[]
|
|
1703
1712
|
for(const e of d)h.push(r(e,t,0,l))
|
|
1704
1713
|
for(const e of u)h.push(n(e,t,0,l))
|
|
1705
|
-
const
|
|
1706
|
-
let
|
|
1714
|
+
const m=await Promise.all(h)
|
|
1715
|
+
let g=""
|
|
1707
1716
|
if(t.workspaceManager)try{const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
1708
|
-
e.branchName&&!e.permanentBranch&&(
|
|
1717
|
+
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
1718
|
let b="## Read Files/Documents\n\n"
|
|
1710
|
-
|
|
1711
|
-
for(let e=0;e<
|
|
1719
|
+
g&&(b+=g),b+=`**Total Requests:** ${w} - **Successful:** ${f} - **Failed:** ${y}\n\n`
|
|
1720
|
+
for(let e=0;e<m.length;e++){const t=m[e]
|
|
1712
1721
|
"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
1722
|
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
1723
|
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 +1799,9 @@ throw c.error(`STRICT VALIDATION - File operation blocked on ${u.status} request
|
|
|
1790
1799
|
const n=(0,s.getErrorMessage)(r)
|
|
1791
1800
|
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
1801
|
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,
|
|
1802
|
+
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
1803
|
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
|
-
|
|
1804
|
+
m=t.promoted,h=t.newStatus}return{taskPromoted:p,newTaskStatus:s,requestPromoted:m,newRequestStatus:h}}catch(r){const n=(0,s.getErrorMessage)(r)
|
|
1796
1805
|
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
1806
|
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
1807
|
const t=`Cannot complete request ${e} - no tasks found. Create tasks for this request before attempting completion.`
|
|
@@ -1819,7 +1828,7 @@ l.info("Generating journal for request",{requestId:a})
|
|
|
1819
1828
|
const u=t.projectId
|
|
1820
1829
|
if(!u)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
|
|
1821
1830
|
o.setProjectId(u),l.info("Fetching request data, tasks, and file history in parallel")
|
|
1822
|
-
const h=o.getRequestClient(),p=o.getTaskClient(),
|
|
1831
|
+
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
1832
|
l.info(`Fetched request, ${v.length} tasks, ${y.length} tool records`)
|
|
1824
1833
|
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
1834
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
@@ -1832,7 +1841,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentWorkspa
|
|
|
1832
1841
|
const r=t(7636)
|
|
1833
1842
|
Object.defineProperty(exports,"MultiAgentWorkspaceManager",{enumerable:!0,get(){return r.MultiAgentWorkspaceManager}})},3247(e,exports,t){"use strict"
|
|
1834
1843
|
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
|
|
1844
|
+
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
1845
|
try{const h=t.projectId
|
|
1837
1846
|
if(!h)throw Error("Project ID not available")
|
|
1838
1847
|
d.setProjectId(h)
|
|
@@ -1841,13 +1850,13 @@ if(!o||"__unknown__"===o||"__server__"===o)throw Error("Cannot resolve request:
|
|
|
1841
1850
|
const i=await s.sessionIdentity.getSessionRequestId(t,r,o)
|
|
1842
1851
|
if(!i)throw Error("No request associated with session "+o)
|
|
1843
1852
|
return i}(t,d,u,p)
|
|
1844
|
-
switch(
|
|
1853
|
+
switch(g){case"create":{const{title:t,description:r}=e
|
|
1845
1854
|
if(!t)return{content:[{type:"text",text:"Error: title is required for create"}],isError:!0}
|
|
1846
1855
|
if(!r)return{content:[{type:"text",text:"Error: description is required for create"}],isError:!0}
|
|
1847
1856
|
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
1857
|
let p=!1
|
|
1849
|
-
if(!s)try{await n.updateTaskStatus(u,"in_progress"),p=!0}catch(e){
|
|
1850
|
-
let y=
|
|
1858
|
+
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
|
|
1859
|
+
let y=g?`Created #${g}: ${t}`:`Created ${(0,l.formatTaskRefForAgent)(u)}: ${t}`
|
|
1851
1860
|
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
1861
|
if(!t)return{content:[{type:"text",text:"Error: summary is required for done"}],isError:!0}
|
|
1853
1862
|
const{active:r,nextPending:n}=await o(d,f)
|
|
@@ -1858,7 +1867,7 @@ const u=r.sequenceNumber
|
|
|
1858
1867
|
let h=u?`Completed #${u}: ${r.title}`:`Completed ${(0,l.formatTaskRefForAgent)(r.taskId)}: ${r.title}`
|
|
1859
1868
|
if(n)try{await s.updateTaskStatus(n.taskId,"in_progress")
|
|
1860
1869
|
const e=n.sequenceNumber
|
|
1861
|
-
h+=e?`\nStarted #${e}: ${n.title}`:`\nStarted ${(0,l.formatTaskRefForAgent)(n.taskId)}: ${n.title}`}catch(e){
|
|
1870
|
+
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
1871
|
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
1872
|
if(o){const e=r(o)
|
|
1864
1873
|
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 +1882,7 @@ l&&await o.updateTaskStatus(l.localId||l.id,"pending"),await o.updateTaskStatus(
|
|
|
1873
1882
|
const u=r(i),h=l?` (paused ${n(r(l))}: ${l.title})`:""
|
|
1874
1883
|
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
1884
|
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: "+
|
|
1885
|
+
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
1886
|
const s=t(6688),i=t(8824),a=t(3451),c=t(2272),l=t(4466)},3253(e,exports){"use strict"
|
|
1878
1887
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTimestamp=function(e,t){const r=e instanceof Date?e:new Date(e)
|
|
1879
1888
|
if(isNaN(r.getTime()))return"Invalid date"
|
|
@@ -1927,7 +1936,7 @@ if(0===a)throw Error(`String "${s}" not found`)
|
|
|
1927
1936
|
if(a>1)throw Error(`String "${s}" appears ${a} times (expected exactly 1 in unique mode)`)
|
|
1928
1937
|
o=o.replace(s,i),t.success=!0,t.occurrences=1}else{const e=(o.match(RegExp(r(s),"g"))||[]).length
|
|
1929
1938
|
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,
|
|
1939
|
+
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
1940
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1932
1941
|
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
1942
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -1950,7 +1959,7 @@ R.push({type:"file",path:t,fullPath:n,replacements:e.replacements,mode:e.mode||"
|
|
|
1950
1959
|
if(P.length>0&&!r.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
1951
1960
|
for(const e of P)M.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
|
|
1952
1961
|
if(M.length>0&&r.apiClient){const e=M.map((e=>e.documentId))
|
|
1953
|
-
try{await(0,
|
|
1962
|
+
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
1963
|
throw e}}k=d.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
1955
1964
|
const $=R.length>0?R[0].path:"document-operation",j=await d.validateTaskId(T,$,o,y,c,v.metricsPrefix),O=j?.requestId
|
|
1956
1965
|
let D=null
|
|
@@ -1972,11 +1981,11 @@ let H=0,B=0
|
|
|
1972
1981
|
for(const e of R){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
1973
1982
|
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
1983
|
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,
|
|
1984
|
+
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
1985
|
try{const o=await r.documentFileManager.getDocumentAsFile(e.documentId),s=r.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
1977
1986
|
t.filename=s?.filename
|
|
1978
1987
|
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,
|
|
1988
|
+
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
1989
|
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
1990
|
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
1991
|
let Z="## String Replacement Results\n\n"
|
|
@@ -1988,8 +1997,8 @@ for(const e of L){if("file"===e.type?Z+=`### File: ${e.path}\n`:(Z+="### Documen
|
|
|
1988
1997
|
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
1998
|
const X=Date.now()-w
|
|
1990
1999
|
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),
|
|
2000
|
+
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}}}
|
|
2001
|
+
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
2002
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1994
2003
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1995
2004
|
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 +2034,10 @@ var h=t(4192)
|
|
|
2025
2034
|
Object.defineProperty(exports,"BaseApiClient",{enumerable:!0,get(){return h.BaseApiClient}})
|
|
2026
2035
|
var p=t(1599)
|
|
2027
2036
|
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
|
|
2037
|
+
var m=t(5187)
|
|
2038
|
+
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return m.CLISessionClient}})
|
|
2039
|
+
var g=t(6539)
|
|
2040
|
+
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return g.ClientFactory}})
|
|
2032
2041
|
const f=t(6539)
|
|
2033
2042
|
exports.default={ClientFactory:f.ClientFactory}},3416(e,exports){"use strict"
|
|
2034
2043
|
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 +2063,12 @@ const n=e
|
|
|
2054
2063
|
"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
2064
|
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
2065
|
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
|
|
2066
|
+
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
2067
|
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
|
|
2068
|
+
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
2069
|
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**: ${
|
|
2070
|
+
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
|
|
2071
|
+
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
2072
|
const t=["lastCommit","completedAt","completionSummary"]
|
|
2064
2073
|
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
2074
|
try{const n=i.getToolRecordClient()
|
|
@@ -2134,30 +2143,30 @@ if(i.length>h)break
|
|
|
2134
2143
|
if(i===l){c.push({line:s+1,actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t})
|
|
2135
2144
|
break}}}o+=i.length+1}return c}const p=t.trim()[0]
|
|
2136
2145
|
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,
|
|
2146
|
+
let m=0,g=0
|
|
2147
|
+
for(;;){if(g%100==0&&Date.now()-d>o){const r=Date.now()-d
|
|
2148
|
+
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++
|
|
2149
|
+
const r=e.indexOf(p,m)
|
|
2141
2150
|
if(-1===r)break
|
|
2142
2151
|
let i=r+t.length
|
|
2143
2152
|
const u=Math.min(Math.floor(.5*t.length),200),h=Math.min(r+t.length+u,e.length),f=l.length
|
|
2144
2153
|
let y=!1
|
|
2145
2154
|
for(let t=i;h>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2146
2155
|
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||(
|
|
2156
|
+
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),m=t,y=!0
|
|
2157
|
+
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
2158
|
const c=[],l=o(t),d=Date.now()
|
|
2150
2159
|
if(t.length>500)return i(e,t)
|
|
2151
2160
|
if(!l)return c
|
|
2152
2161
|
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`)}
|
|
2162
|
+
let p=0,m=0
|
|
2163
|
+
for(;;){if(m%100==0&&Date.now()-d>n){const r=Date.now()-d
|
|
2164
|
+
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
2165
|
const r=e.indexOf(u,p)
|
|
2157
2166
|
if(-1===r)break
|
|
2158
|
-
const i=r+h,a=Math.min(t.length,300),
|
|
2167
|
+
const i=r+h,a=Math.min(t.length,300),g=Math.min(r+h+a,e.length)
|
|
2159
2168
|
let f=!1
|
|
2160
|
-
for(let t=i;
|
|
2169
|
+
for(let t=i;g>=t;t++){const n=e.substring(r,t),i=o(n)
|
|
2161
2170
|
if(i.length>h)break
|
|
2162
2171
|
if(i===l){c.push({line:s(e,r),actuallyMatched:n,matchType:"whitespace_agnostic",startPos:r,endPos:t}),p=t,f=!0
|
|
2163
2172
|
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 +2194,15 @@ let i=d.FileOperationPhase.VALIDATION
|
|
|
2185
2194
|
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
2195
|
try{const a=e,{path:u}=a
|
|
2187
2196
|
n.info("Getting file info: "+u)
|
|
2188
|
-
const{normalizedPath:
|
|
2197
|
+
const{normalizedPath:m,fullPath:g}=d.validateAndNormalizePath(u,t)
|
|
2189
2198
|
i=d.FileOperationPhase.FILE_WRITE
|
|
2190
|
-
try{await c.default.access(
|
|
2199
|
+
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
2200
|
w.isFile&&y&&b.push("Extension: "+y)
|
|
2192
2201
|
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: "+
|
|
2202
|
+
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
2203
|
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
2204
|
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
|
|
2205
|
+
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
2206
|
try{const w=h.getRequestClient(),b=h.getTaskClient(),I=h.getFileClient(),k=h.getToolRecordClient(),{title:v,description:C,..._}=e,E=e.comment||v
|
|
2198
2207
|
f.info("Starting quick_edit workflow",{title:v,operationType:t})
|
|
2199
2208
|
let S=!1
|
|
@@ -2204,23 +2213,23 @@ if(!q||!q.id)throw Error("Failed to create request")
|
|
|
2204
2213
|
const T=q.id
|
|
2205
2214
|
let x
|
|
2206
2215
|
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,
|
|
2216
|
+
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
2217
|
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
2218
|
f.debug("Creating task")
|
|
2210
2219
|
const e=await b.createTask({requestId:T,projectId:u.projectId,title:`Execute ${t} operation`,description:"Quick change: "+v})
|
|
2211
2220
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2212
2221
|
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
|
|
2222
|
+
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)
|
|
2223
|
+
else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:x,..._,comment:E},u,b,k,w,p,m,g)
|
|
2215
2224
|
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
|
|
2225
|
+
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
2226
|
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
2227
|
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,
|
|
2228
|
+
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
2229
|
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
2230
|
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
2231
|
let $=!1
|
|
2223
|
-
try{const e=await(0,c.handleCompleteRequest)({requestId:T,summary:R,acceptanceEvidence:[{evidence:M}],testVerification:void 0},u,h,p,g
|
|
2232
|
+
try{const e=await(0,c.handleCompleteRequest)({requestId:T,summary:R,acceptanceEvidence:[{evidence:M}],testVerification:void 0},u,h,p,m,g)
|
|
2224
2233
|
if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:T,error:e.content[0].text})
|
|
2225
2234
|
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
2235
|
f.info("Quick fix completed",{requestId:T,duration:j,hasPartialFailure:P})
|
|
@@ -2300,15 +2309,15 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleWriteFile=a
|
|
|
2300
2309
|
let v,C,_=d.FileOperationPhase.VALIDATION
|
|
2301
2310
|
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
2311
|
try{const n=e
|
|
2303
|
-
let{path:
|
|
2312
|
+
let{path:g,documentId:S,content:q,format:T,append:x,comment:P}=n
|
|
2304
2313
|
Array.isArray(q)&&(q=q.join("\n"))
|
|
2305
2314
|
const{enforceActiveTask:R}=await Promise.resolve().then(t.bind(t,3451)),M=await R(r,o,f,e.taskId)
|
|
2306
2315
|
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?
|
|
2316
|
+
const{taskId:$}=M,j=!!S,O=!!g
|
|
2317
|
+
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
2318
|
let D,A,F,N="",z=!1,L=!1
|
|
2310
|
-
const H=O?
|
|
2311
|
-
if(j){if(r.apiClient)try{await(0,
|
|
2319
|
+
const H=O?g:void 0
|
|
2320
|
+
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
2321
|
throw e}if(!r.documentFileManager)throw Error("Document file manager not available")
|
|
2313
2322
|
N=await r.documentFileManager.getDocumentAsFile(S)
|
|
2314
2323
|
const e=r.documentFileManager.getCachedDocumentInfo(S)
|
|
@@ -2343,8 +2352,8 @@ const oe=Date.now()
|
|
|
2343
2352
|
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
2353
|
const se=r.workspaceManager?.consumeLargeFileWarning(r.currentSessionId)
|
|
2345
2354
|
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),
|
|
2355
|
+
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}}}
|
|
2356
|
+
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
2357
|
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
2358
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=exports.TasksSchema=void 0
|
|
2350
2359
|
const r=t(1569),n=t(3247)
|
|
@@ -2412,8 +2421,8 @@ if(!c.startsWith(s+a.sep))return{content:[{type:"text",text:"\u274c Invalid file
|
|
|
2412
2421
|
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
2422
|
if(!h)return{content:[{type:"text",text:"\u274c Unsupported image type: ."+u}],isError:!0}
|
|
2414
2423
|
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:
|
|
2424
|
+
const p=await i.readFile(c),m=p.toString("base64")
|
|
2425
|
+
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
2426
|
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
2427
|
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
2428
|
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 +2431,18 @@ d.info("Starting merge request",{requestId:h,verificationCount:p.length})
|
|
|
2422
2431
|
const e=a.getRequestClient(),s=await e.getRequest(h)
|
|
2423
2432
|
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
2433
|
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,
|
|
2434
|
+
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,m
|
|
2426
2435
|
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/validate-completion`,{})
|
|
2427
2436
|
c=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2428
2437
|
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
2438
|
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
2439
|
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
|
|
2440
|
+
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
2441
|
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}),
|
|
2442
|
+
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
2443
|
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:
|
|
2444
|
+
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)
|
|
2445
|
+
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
2446
|
d.error("Merge request failed",{error:r})
|
|
2438
2447
|
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
2448
|
const r=t(3807),n=t(9860),o=t(1651),s=t(8616),i=t(8824)},4394(e,exports,t){"use strict"
|
|
@@ -2453,49 +2462,48 @@ const a=await r.updateDocument(e.planId,i),c=a.localId||a.id
|
|
|
2453
2462
|
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
2463
|
const r=t(8824)},4425(e,exports,t){"use strict"
|
|
2455
2464
|
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"===
|
|
2465
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,h,p,m,g){const f=p.startTimer("tool_execution_time"),y=e.operation||"run"
|
|
2466
|
+
try{const p=await r.proxyGet(`/api/projects/${t.projectId}/check-commands`),w=p?.data||p||[],b=w.filter((e=>e.isActive)),I=w.filter((e=>!e.isActive))
|
|
2467
|
+
if("list"===y){if(0===w.length)return f({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,c.alchemyMeta)({kind:"list-commands"})}
|
|
2459
2468
|
const e=[]
|
|
2460
|
-
return
|
|
2461
|
-
try{const r=await fetch((0,
|
|
2469
|
+
return b.length>0&&(e.push(`## Available Commands (${b.length})\n`),e.push(...b.map((e=>`- **${e.name}**: \`${e.command}\`${e.cwd?` (in \`${e.cwd}\`)`:""}${e.description?" \u2014 "+e.description:""}`)))),I.length>0&&(e.push(`\n## Pending Approval (${I.length})\n`),e.push(...I.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'),f({success:!0}),{content:[{type:"text",text:e.join("\n")}],...(0,c.alchemyMeta)({kind:"list-commands"})}}if("setup"===y){const t=g?.sessionId,n=t?await d.sessionIdentity.getSessionRequestId(r,h,t):void 0
|
|
2470
|
+
try{const r=await fetch((0,u.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
2471
|
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(
|
|
2472
|
+
return f({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()
|
|
2473
|
+
return o.success&&o.data?(f({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,c.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:o.data.sessionId,agentType:"command-architect",description:"Commands setup"})}):(f({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(o.error||"unknown error")}],isError:!0})}catch(e){return f({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}if("register"===y){if(!Array.isArray(e.commands)||0===e.commands.length)return f({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}
|
|
2474
|
+
const n=function(e){return e?.sessionId||d.sessionIdentity.getIdentity()?.sessionId||null}(g)
|
|
2475
|
+
if(!n)return f({success:!1,error:"no_session"}),{content:[{type:"text",text:"Error: no session context available to attribute approval notifications."}],isError:!0}
|
|
2476
|
+
const o=new Set(w.map((e=>e.name.toLowerCase()))),s=[],i=[]
|
|
2468
2477
|
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())?
|
|
2478
|
+
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 a=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:g?.sessionId,isActive:!1}),o=n?.data?.id||n?.id
|
|
2470
2479
|
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(
|
|
2480
|
+
return{ok:!0,proposal:e,commandId:o}}catch(t){return{ok:!1,proposal:e,error:(0,l.getErrorMessage)(t)}}}))),u=a.filter((e=>e.ok))
|
|
2481
|
+
for(const e of a)e.ok||i.push({name:e.proposal.name,reason:e.error})
|
|
2482
|
+
const p=[]
|
|
2483
|
+
if(u.length>0)try{const e=r.getSessionMessageClient()
|
|
2475
2484
|
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
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
const n=t(4600),o=r(t(6928)),s=t(2272),i=t(8824),a=t(6688),c=t(9414)},4466(e,exports,t){"use strict"
|
|
2485
|
+
await e.createQuestion({fromSessionId:n,questionType:"alternatives",question:`Command batch approval: ${u.length} command${1===u.length?"":"s"}`,options:[{id:"approve-all",label:"Approve all",description:`Activate all ${u.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:u.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"})
|
|
2486
|
+
for(const e of u)p.push(e.proposal.name)}catch(e){await Promise.allSettled(u.map((e=>r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${e.commandId}`).catch((t=>h.warn("Rollback delete after batch question failure",{commandId:e.commandId,error:(0,l.getErrorMessage)(t)}))))))
|
|
2487
|
+
for(const t of u)i.push({name:t.proposal.name,reason:(0,l.getErrorMessage)(e)})}h.info("Register submitted commands for approval",{total:e.commands.length,submitted:p.length,skipped:i.length}),f({success:!0})
|
|
2488
|
+
const m=[`## Submitted ${p.length} command${1===p.length?"":"s"} for approval${i.length?`, ${i.length} skipped`:""}`]
|
|
2489
|
+
return p.length>0&&(m.push("","### Pending approval"),m.push(...p.map((e=>`- **${e}**`))),m.push("","The user will see one approval notification per command. Approved commands become runnable; denied ones are removed.")),i.length>0&&(m.push("",`### Skipped (${i.length})`),m.push(...i.map((e=>`- **${e.name}** \u2014 ${e.reason}`)))),m.push("",'Use `commands({ operation: "list" })` to see status.'),{content:[{type:"text",text:m.join("\n")}],...(0,c.alchemyMeta)({kind:"register-commands"})}}if("remove"===y){if(!e.name?.trim())return f({success:!1,error:"missing_name"}),{content:[{type:"text",text:"Error: `name` is required when removing a command."}],isError:!0}
|
|
2490
|
+
const n=w.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2491
|
+
if(!n)return f({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.`}],isError:!0}
|
|
2492
|
+
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),h.info("Removed command",{name:n.name,id:n.id}),f({success:!0}),{content:[{type:"text",text:`Removed command **${n.name}**.`}]}}catch(e){return f({success:!1,error:"remove_failed"}),{content:[{type:"text",text:"Failed to remove command: "+(0,l.getErrorMessage)(e)}],isError:!0}}}if(!e.name){const e=b.map((e=>e.name)).join(", ")
|
|
2493
|
+
return f({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 k=b.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2494
|
+
if(!k){const t=b.map((e=>e.name)).join(", ")
|
|
2495
|
+
return f({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.\n\nAvailable commands: ${t||"(none configured)"}`}],isError:!0}}let v=e.args?`${k.command} ${e.args}`:k.command
|
|
2496
|
+
e.grep&&(v=`${v} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
|
|
2497
|
+
const C=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,_=k.cwd?s.default.resolve(C,k.cwd):C,E=s.default.join(C,a.ALCHEMY_DIR_NAME,"command-logs"),S=`${k.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,q=s.default.join(E,S+".log")
|
|
2498
|
+
let T=null
|
|
2499
|
+
try{i.default.mkdirSync(E,{recursive:!0}),T=i.default.createWriteStream(q,{flags:"w"}),T.write(`# ${(new Date).toISOString()} starting: ${v}\n# cwd: ${_}\n# timeout: ${k.timeout||60}s\n\n`)}catch(e){h.warn("Failed to open command log file",{logPath:q,error:(0,l.getErrorMessage)(e)})}h.info("Running command",{name:k.name,command:v,cwd:_,configuredCwd:k.cwd,logPath:q})
|
|
2500
|
+
const x=await(0,n.runTrackedShellCommand)(v,{cwd:_,timeoutMs:1e3*(k.timeout||60),env:{...process.env,FORCE_COLOR:"0"},onChunk:T?(e,t)=>{T?.write(t)}:void 0},{id:S,name:k.name,sessionId:g?.sessionId,logPath:q})
|
|
2501
|
+
T&&(T.write(`\n# exit: ${x.exitCode}${x.timedOut?" (timed out)":""}\n`),T.end())
|
|
2502
|
+
const{stdout:P,stderr:R,exitCode:M,timedOut:$}=x,{output:j,truncatedNote:O,logFooter:D}=(0,o.formatCommandOutput)(P,R,{invocationId:S}),A=$?"TIMEOUT":null
|
|
2503
|
+
let F
|
|
2504
|
+
if(m)try{const e=await m.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:k.name,command:v,exitCode:M,timedOut:$,status:$?"timeout":0===M?"success":"failed",timestamp:(new Date).toISOString()}})
|
|
2505
|
+
F=e?.id}catch(e){h.debug("Failed to create tool record for command run",{error:(0,l.getErrorMessage)(e)})}return f({success:!0}),{content:[{type:"text",text:`## ${k.name}${A?` \u2014 ${A} (killed after ${k.timeout}s)`:""}\n\`\`\`\n$ ${v}\n${j}\n\`\`\`${O}\n\nExit code: ${M}\n${D} (pass to read_files or search)`}],...(0,c.alchemyMeta)({kind:"run-command",toolRecordId:F})}}catch(e){return f({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
2506
|
+
const n=t(4600),o=t(1816),s=r(t(6928)),i=r(t(9896)),a=t(4139),c=t(2272),l=t(8824),d=t(6688),u=t(9414)},4466(e,exports,t){"use strict"
|
|
2499
2507
|
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
2508
|
const i=e.match(exports.TASK_REF_SHORT_PATTERN)
|
|
2501
2509
|
if(!i)return e
|
|
@@ -2518,9 +2526,9 @@ return e}
|
|
|
2518
2526
|
const o=t(6688),s=t(8955)
|
|
2519
2527
|
exports.TASK_REF_PATTERN=/^(req\d{6})#(\d+)$/,exports.TASK_REF_SHORT_PATTERN=/^#?(\d{1,3})$/},4592(e,exports,t){"use strict"
|
|
2520
2528
|
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:
|
|
2529
|
+
try{const c=e,{operation:m,sessionId:g}=c
|
|
2522
2530
|
let f
|
|
2523
|
-
switch(h.info("Processing planner_ops",{operation:
|
|
2531
|
+
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
2532
|
try{const s=r?.sessionId||o.sessionIdentity.getIdentity()?.sessionId
|
|
2525
2533
|
if(!s)return"ask"
|
|
2526
2534
|
const i=e.getCLISessionClient()
|
|
@@ -2536,28 +2544,33 @@ if("interactive"===n)return"interactive"}catch(e){t.warn("Failed to read project
|
|
|
2536
2544
|
if("ask"===e||"interactive"===e){h.info("Returning planner choice pending",{planningMode:e})
|
|
2537
2545
|
try{const e=u?.sessionId||o.sessionIdentity.getIdentity()?.sessionId,t=d?.getSessionMessageClient()
|
|
2538
2546
|
if(t&&e){const r=await o.sessionIdentity.getParentSessionId(e,d,h),n=c.description||c.prompt
|
|
2539
|
-
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}}})}
|
|
2547
|
+
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:{type:"planner-request",prompt:c.prompt,description:c.description},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
2548
|
break}const r="auto-planner"
|
|
2541
2549
|
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)(
|
|
2550
|
+
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
2551
|
break
|
|
2544
2552
|
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
2553
|
if(p.trim()||y.trim()){const e=[]
|
|
2546
2554
|
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
2555
|
break
|
|
2548
|
-
default:throw new r.ValidationError("Unknown operation: "+
|
|
2549
|
-
const y=a[
|
|
2556
|
+
default:throw new r.ValidationError("Unknown operation: "+m)}p({success:!0}),l.incrementCounter(`planner_ops_${m}_success`,1)
|
|
2557
|
+
const y=a[m]??"planner-request"
|
|
2550
2558
|
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
2559
|
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
|
-
|
|
2560
|
+
async function r(e,r={}){const{spawn:n}=await Promise.resolve().then(t.t.bind(t,5317,23))
|
|
2561
|
+
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=[]
|
|
2562
|
+
let c=!1,l=!1
|
|
2563
|
+
const d=e=>{if(s.pid)try{o?s.kill(e):process.kill(-s.pid,e)}catch{}}
|
|
2564
|
+
let u,h
|
|
2565
|
+
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)}))
|
|
2566
|
+
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}))}
|
|
2567
|
+
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
2568
|
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"
|
|
2569
|
+
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()
|
|
2570
|
+
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((()=>{}))
|
|
2571
|
+
const l=await r(e,n)
|
|
2572
|
+
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}
|
|
2573
|
+
const n=t(5317)},4607(e,exports,t){"use strict"
|
|
2561
2574
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2562
2575
|
const r=t(6183),n=t(3306)
|
|
2563
2576
|
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 +2582,10 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2569
2582
|
var t={}
|
|
2570
2583
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2571
2584
|
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",
|
|
2585
|
+
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()
|
|
2586
|
+
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"
|
|
2587
|
+
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
|
|
2588
|
+
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
2589
|
f=I
|
|
2577
2590
|
let k,v=!1
|
|
2578
2591
|
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 +2597,33 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
|
|
|
2584
2597
|
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await a.writeFile(w,_,"utf8")
|
|
2585
2598
|
let E={}
|
|
2586
2599
|
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()-
|
|
2600
|
+
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
2601
|
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}),
|
|
2602
|
+
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
|
|
2603
|
+
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
2604
|
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,
|
|
2605
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,h,p,m,g,f){const y=m.child({tool:"request_operations"})
|
|
2593
2606
|
try{const w=e
|
|
2594
2607
|
let{requestId:b}=w
|
|
2595
2608
|
const{operation:I}=w
|
|
2596
2609
|
if("list"!==I&&"search"!==I&&!b){const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=h.currentSessionId
|
|
2597
2610
|
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
2611
|
const e={requestId:b,summary:w.complete.summary}
|
|
2599
|
-
return(0,d.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,h,p,g,
|
|
2612
|
+
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
2613
|
case"approve":{y.info("Routing to approve-request handler")
|
|
2601
2614
|
const e={requestId:b}
|
|
2602
|
-
return(0,d.withAlchemyKind)(await(0,a.handleApproveRequest)(e,h,p,g,
|
|
2615
|
+
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
2616
|
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
|
|
2617
|
+
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
2618
|
const e={requestId:b}
|
|
2606
|
-
return(0,d.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,h,p,g
|
|
2619
|
+
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
2620
|
const e={filters:w.list?.filters}
|
|
2608
|
-
return(0,d.withAlchemyKind)(await(0,s.handleListRequests)(e,h,p,g
|
|
2621
|
+
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
2622
|
const e={search:w.search}
|
|
2610
|
-
return(0,d.withAlchemyKind)(await(0,i.handleSearchRequests)(e,h,p,g
|
|
2623
|
+
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
2624
|
try{const e=p.getProxyClient(),t=await e.proxyGet(`/api/projects/${h.projectId}/tasks`,{requestLocalId:b,limit:1}),r=t?.data||t||[]
|
|
2612
2625
|
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+""}),
|
|
2626
|
+
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
2627
|
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
2628
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2616
2629
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClient=void 0
|
|
@@ -2727,17 +2740,17 @@ var t={}
|
|
|
2727
2740
|
if(null!=e)for(var r=s(e),n=0;n<r.length;n++)"default"!==r[n]&&i(t,e,r[n])
|
|
2728
2741
|
return a(t,e),t})
|
|
2729
2742
|
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:
|
|
2743
|
+
try{const{path:i,lines:m,branch:g}=e
|
|
2744
|
+
c.info("Processing blame request",{filePath:i,lines:m,branch:g})
|
|
2732
2745
|
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
2746
|
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
2747
|
if(/^\d+$/.test(e)){const t=parseInt(e,10)
|
|
2735
2748
|
return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
|
|
2736
2749
|
if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
|
|
2737
2750
|
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}(
|
|
2751
|
+
return{start:Math.min(...t),end:Math.max(...t)}}return null}(m),I=["blame","--porcelain"]
|
|
2739
2752
|
let k
|
|
2740
|
-
b&&I.push(`-L${b.start},${b.end}`),
|
|
2753
|
+
b&&I.push(`-L${b.start},${b.end}`),g&&I.push(g),I.push("--",w),c.debug("Executing git blame",{args:I})
|
|
2741
2754
|
try{if(!t.git)throw Error("Git context not available")
|
|
2742
2755
|
k=await t.git.raw(I)}catch(e){const t=(0,h.getErrorMessage)(e)
|
|
2743
2756
|
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 +2949,18 @@ const n=a.getRequestClient(),s=a.getTaskClient(),[c,l]=await Promise.all([n.getR
|
|
|
2936
2949
|
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
2950
|
const h=(0,o.extractDataFromResponse)(c,{logger:d,operationName:"getRequestInformation",throwOnNoData:!0}),p="data"in h?h.data:h
|
|
2938
2951
|
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
|
|
2952
|
+
const m=(0,o.extractArrayFromResponse)(l,{logger:d,operationName:"listTasksForRequest",defaultValue:[]})
|
|
2953
|
+
d.info(`Successfully extracted ${m.length} tasks using data extraction utility`)
|
|
2954
|
+
const g={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:m.length}
|
|
2955
|
+
m.forEach((e=>{const t=e.status
|
|
2956
|
+
t in g&&g[t]++}))
|
|
2944
2957
|
const f=p.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_verified:0,total:f.length}
|
|
2945
2958
|
f.forEach((e=>{const t=e.status||"unverified"
|
|
2946
2959
|
t in y&&y[t]++}))
|
|
2947
2960
|
let w=p.testVerification||null
|
|
2948
2961
|
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: ${
|
|
2962
|
+
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`
|
|
2963
|
+
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
2964
|
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
2965
|
const r=t(9860),n=t(5674),o=t(2960),s=t(8824),i=t(5454)},5454(e,exports){"use strict"
|
|
2953
2966
|
function t(e,t){let r=0
|
|
@@ -2987,8 +3000,8 @@ if(c.incrementCounter("document_operations_total",1,{operation:"list-annotations
|
|
|
2987
3000
|
let r=`## Annotations on ${h} (${t.length})\n\n`
|
|
2988
3001
|
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
3002
|
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:** ${
|
|
3003
|
+
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})
|
|
3004
|
+
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
3005
|
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
3006
|
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
3007
|
const e=o.annotationId,t=i.getDocumentClient()
|
|
@@ -3016,7 +3029,7 @@ return{isOffline:this.isInOfflineMode(),consecutiveFailures:e.consecutiveFailure
|
|
|
3016
3029
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3017
3030
|
const r=t(6183),n=t(2965)
|
|
3018
3031
|
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"}),
|
|
3032
|
+
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
3033
|
try{const{requestId:n,summary:o}=e
|
|
3021
3034
|
if(!n)throw(0,r.createValidationError)("Request ID is required")
|
|
3022
3035
|
if(!o)throw(0,r.createValidationError)("Summary is required")
|
|
@@ -3025,18 +3038,18 @@ const l=h?.sessionId
|
|
|
3025
3038
|
let d
|
|
3026
3039
|
try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:l})
|
|
3027
3040
|
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
|
|
3041
|
+
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`
|
|
3042
|
+
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()
|
|
3043
|
+
let g,f="auto-test-then-merge"===d.completionMode,y=null
|
|
3031
3044
|
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
3045
|
if(i&&"passed"===i.status&&i.commitSha){let e=null
|
|
3033
3046
|
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
|
|
3047
|
+
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"
|
|
3048
|
+
try{await u.updateRequest(n,{status:w,completionSummary:o,...g?{skippedTestRunId:g}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3049
|
+
return m({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let b
|
|
3037
3050
|
try{b=await u.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3038
|
-
return
|
|
3039
|
-
if(
|
|
3051
|
+
return m({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const I=b?.acceptanceCriteria||[]
|
|
3052
|
+
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
3053
|
const k=y?`\n\n_Skipped re-running tests: ${y}._\n`:""
|
|
3041
3054
|
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
3055
|
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 +3080,7 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3067
3080
|
var t={}
|
|
3068
3081
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3069
3082
|
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
|
|
3083
|
+
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
3084
|
let y,w,b=c.FileOperationPhase.VALIDATION
|
|
3072
3085
|
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
3086
|
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 +3093,42 @@ P=E.map((e=>{if(e.path)return{type:"file",target:e.path}
|
|
|
3080
3093
|
if(e.documentId)return{type:"document",target:e.documentId}
|
|
3081
3094
|
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
3095
|
const R=P.filter((e=>"file"===e.type)),M=P.filter((e=>"document"===e.type)),$=P.length
|
|
3083
|
-
|
|
3096
|
+
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
3097
|
const j=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3085
|
-
|
|
3098
|
+
g.info("Initial branch context",{initialBranch:j.branch,initialRequestId:j.requestId,isMain:j.isMain})
|
|
3086
3099
|
const O=[]
|
|
3087
3100
|
for(const e of R){const{normalizedPath:t,fullPath:n}=c.validateAndNormalizePath(e.target,r)
|
|
3088
3101
|
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:
|
|
3102
|
+
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)
|
|
3103
|
+
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})
|
|
3104
|
+
const L=await c.ensureCorrectWorkspaceContext({taskPromoted:z.taskPromoted,requestId:F,context:r,operation:"delete-files",logger:g,metrics:s,metricsPrefix:I.metricsPrefix})
|
|
3092
3105
|
if(!L.success)throw Error(L.error)
|
|
3093
3106
|
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,
|
|
3107
|
+
if(r.git)try{g.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
|
|
3108
|
+
const e=await(0,u.commitUserChangesBeforeToolOperation)(r.git,"delete-files",{requestId:F,taskId:x,workspaceManager:r.workspaceManager},g,s)
|
|
3109
|
+
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})
|
|
3110
|
+
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
3111
|
y=B,w=B,b=I.fileOperationPhase,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3099
3112
|
const G=[]
|
|
3100
3113
|
let W=0
|
|
3101
3114
|
M.length>0&&n.setProjectId(r.projectId)
|
|
3102
3115
|
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
3116
|
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++,
|
|
3117
|
+
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
3118
|
for(const e of M){const t=e.target,r={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3106
3119
|
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++,
|
|
3120
|
+
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)
|
|
3121
|
+
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)
|
|
3122
|
+
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,m.getErrorMessage)(e)}`)}const o=await V.archiveDocument(t)
|
|
3123
|
+
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
3124
|
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
3125
|
let J=null
|
|
3113
3126
|
if(W>0){b=c.FileOperationPhase.GIT_COMMIT,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
3114
3127
|
const e=G.filter((e=>e.success)),t=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
|
|
3115
3128
|
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,
|
|
3129
|
+
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
3130
|
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,
|
|
3131
|
+
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
3132
|
const Z=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3120
3133
|
let X=""
|
|
3121
3134
|
if(W===$){const e=Q.filter((e=>"file"===e.type)).length,t=Q.filter((e=>"document"===e.type)).length
|
|
@@ -3123,11 +3136,11 @@ X=e>0&&t>0?`Successfully deleted ${e} files and ${t} documents`:e>0?`Successfull
|
|
|
3123
3136
|
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
3137
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
|
|
3125
3138
|
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),
|
|
3139
|
+
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
|
|
3140
|
+
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
3141
|
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),
|
|
3142
|
+
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)}}
|
|
3143
|
+
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
3144
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3132
3145
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3133
3146
|
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 +3219,10 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
|
3206
3219
|
const r=t(6183),n=t(405)
|
|
3207
3220
|
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
3221
|
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,
|
|
3222
|
+
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
3223
|
try{const u=e,{operation:y,sessionId:w}=u
|
|
3211
3224
|
let b
|
|
3212
|
-
switch(
|
|
3225
|
+
switch(g.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=m?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3213
3226
|
if(r&&p){const t=await async function(e,t,r,o,s){o.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
|
|
3214
3227
|
const a=await(0,i.getServerUrl)(r,o)
|
|
3215
3228
|
if(a)try{const r=await fetch(a.replace(/\/$/,"")+"/session")
|
|
@@ -3223,31 +3236,31 @@ return"specialist"===t?.agentType&&"archived"!==t?.status}))
|
|
|
3223
3236
|
if(o.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
|
|
3224
3237
|
const p=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
|
|
3225
3238
|
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,
|
|
3239
|
+
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
3240
|
if(t){b=t
|
|
3228
3241
|
break}}let c=u.description||u.prompt.slice(0,60)
|
|
3229
3242
|
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,
|
|
3243
|
+
if(r)try{const e=await(0,i.getServerUrl)(d,g)
|
|
3231
3244
|
if(h(`serverUrl=${e}, parentId=${r}`),e){const t=await fetch(e.replace(/\/$/,"")+"/session")
|
|
3232
3245
|
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
3246
|
h(`siblings=${e.length}: ${e.join(", ")}`)
|
|
3234
3247
|
const n=(0,o.pickSpecialistName)(e)
|
|
3235
3248
|
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,
|
|
3249
|
+
b=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,g,p,m)
|
|
3250
|
+
break}case"follow-up":{const e=await(0,i.getServerUrl)(d,g)
|
|
3238
3251
|
if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
|
|
3239
3252
|
if(t.ok){const e=await t.json(),r=e[w]?.type
|
|
3240
3253
|
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,
|
|
3254
|
+
break}}}catch{}b=await(0,s.handleContinue)(w,u.prompt,d,g,p,"specialist",m)
|
|
3255
|
+
break}case"check-status":b=await(0,s.handleCheckStatus)(w,d,g,p)
|
|
3243
3256
|
break
|
|
3244
|
-
case"abort":if(b=await(0,s.handleAbort)(w,d,
|
|
3257
|
+
case"abort":if(b=await(0,s.handleAbort)(w,d,g),!b.isError&&p)try{const e=p.getCLISessionClient()
|
|
3245
3258
|
e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
|
|
3246
|
-
case"list":{const e=
|
|
3247
|
-
b=await(0,s.handleListSessions)(d,
|
|
3259
|
+
case"list":{const e=m?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3260
|
+
b=await(0,s.handleListSessions)(d,g,p,{activeOnly:u.activeOnly,requestId:u.requestId,limit:u.limit,agentType:"specialist",parentSessionId:e})
|
|
3248
3261
|
break}default:throw new r.ValidationError("Unknown operation: "+y)}f({success:!0}),h.incrementCounter(`specialist_ops_${y}_success`,1)
|
|
3249
3262
|
const I=l[y]??"specialist-delegate"
|
|
3250
|
-
return(0,c.withAlchemyKind)(b,I)}catch(e){return
|
|
3263
|
+
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
3264
|
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
3265
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3253
3266
|
const r=t(6183),n=t(8184)
|
|
@@ -3266,16 +3279,16 @@ return o(t,e),t})
|
|
|
3266
3279
|
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
3280
|
try{const n=e,{requestId:l,reason:h,confirmDestructive:p}=n
|
|
3268
3281
|
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
|
|
3282
|
+
let m
|
|
3270
3283
|
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: ${
|
|
3284
|
+
m=e?.data||e}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3285
|
+
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`
|
|
3286
|
+
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})
|
|
3287
|
+
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
3288
|
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
3289
|
t.syncBranchState&&await t.syncBranchState()
|
|
3277
|
-
let m
|
|
3278
|
-
if(!
|
|
3290
|
+
let g=m.mergeCommitHash
|
|
3291
|
+
if(!g){s.info("No merge commit hash from server, searching git log",{requestId:l})
|
|
3279
3292
|
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
3293
|
return-1===t?{hash:e,message:""}:{hash:e.substring(0,t),message:e.substring(t+1)}})):[],s=a.generateMergeMessagePatterns(e)
|
|
3281
3294
|
for(const e of s){let t
|
|
@@ -3283,14 +3296,14 @@ if(e.includes("\\")||e.includes(".*")){const r=RegExp(e,"i")
|
|
|
3283
3296
|
t=o.find((e=>r.test(e.message)))}else t=o.find((t=>t.message.includes(e)))
|
|
3284
3297
|
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
3298
|
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
|
-
|
|
3299
|
+
g=e.commitHash}const f=t.workspaceManager.getMainGit(),y=await a.getRepositoryStatus(f,s,o)
|
|
3287
3300
|
if(y.currentBranch!==y.defaultBranch){const e=await a.switchToBranch(f,y.defaultBranch||"main",s,o)
|
|
3288
3301
|
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:
|
|
3302
|
+
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
3303
|
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: ${
|
|
3304
|
+
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)
|
|
3305
|
+
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)
|
|
3306
|
+
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
3307
|
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
3308
|
if(t.projectId&&e.requestId)try{const o=r.getToolRecordClient()
|
|
3296
3309
|
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 +3318,15 @@ const s=[...t].sort(((e,t)=>"between"===e.type&&"between"===t.type?(t.afterLine|
|
|
|
3305
3318
|
for(const e of s){const t={type:e.type,line:e.line,afterLine:e.afterLine,beforeLine:e.beforeLine,success:!1}
|
|
3306
3319
|
try{let n
|
|
3307
3320
|
switch(e.type){case"before":if(void 0===e.line)throw Error("Line number is required for before insertion")
|
|
3308
|
-
n=(0,
|
|
3321
|
+
n=(0,g.insertBeforeLine)(r,e.line,e.content)
|
|
3309
3322
|
break
|
|
3310
3323
|
case"after":if(void 0===e.line)throw Error("Line number is required for after insertion")
|
|
3311
|
-
n=(0,
|
|
3324
|
+
n=(0,g.insertAfterLine)(r,e.line,e.content)
|
|
3312
3325
|
break
|
|
3313
3326
|
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,
|
|
3327
|
+
n=(0,g.insertBetweenLines)(r,e.afterLine,e.beforeLine,e.content)
|
|
3315
3328
|
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,
|
|
3329
|
+
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
3330
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3318
3331
|
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
3332
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3321,7 +3334,7 @@ return t},n(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3321
3334
|
var t={}
|
|
3322
3335
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3323
3336
|
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,
|
|
3337
|
+
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
3338
|
let b,I,k=l.FileOperationPhase.VALIDATION
|
|
3326
3339
|
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
3340
|
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 +3349,34 @@ R.push({type:"file",path:t,fullPath:r,insertions:e.insertions})}const M=[]
|
|
|
3336
3349
|
if(P.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3337
3350
|
for(const e of P)M.push({type:"document",documentId:e.documentId,insertions:e.insertions})
|
|
3338
3351
|
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,
|
|
3352
|
+
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}
|
|
3353
|
+
throw e}}k=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3354
|
+
const $=R.length>0?R[0].path:"document-operation",j=await l.validateTaskId(T,$,o,y,g,v.metricsPrefix),O=j?.requestId
|
|
3342
3355
|
let D=null
|
|
3343
|
-
R.length>0&&O&&(D=await l.validateWorkItemStates(T,R[0].path,o,i,n,y,
|
|
3356
|
+
R.length>0&&O&&(D=await l.validateWorkItemStates(T,R[0].path,o,i,n,y,g,v.metricsPrefix))
|
|
3344
3357
|
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:
|
|
3358
|
+
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"}))
|
|
3359
|
+
const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:O,context:n,operation:"insert-lines",logger:y,metrics:g,metricsPrefix:v.metricsPrefix})
|
|
3347
3360
|
if(!F.success)throw Error(F.error)
|
|
3348
3361
|
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
3362
|
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,
|
|
3363
|
+
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}
|
|
3364
|
+
throw e}k=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3365
|
+
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)
|
|
3366
|
+
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")
|
|
3367
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"insert-lines",{requestId:O,taskId:T,workspaceManager:n.workspaceManager},y,g)
|
|
3355
3368
|
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
3369
|
const L=[]
|
|
3357
3370
|
let H=0,B=0,U=0
|
|
3358
3371
|
for(const e of R){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3359
3372
|
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
3373
|
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,
|
|
3374
|
+
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
3375
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3363
3376
|
t.filename=s?.filename
|
|
3364
3377
|
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:
|
|
3378
|
+
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))
|
|
3379
|
+
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
3380
|
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
3381
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
3369
3382
|
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 +3387,17 @@ for(const e of L){if("file"===e.type?X+=`### File: ${e.path}\n`:(X+="### Documen
|
|
|
3374
3387
|
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
3388
|
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
3389
|
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),
|
|
3390
|
+
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
|
|
3391
|
+
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}}}
|
|
3392
|
+
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
3393
|
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),
|
|
3394
|
+
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
3395
|
exports.ClientFactory=class{static async createClient(e,f,y,w={}){(f=f.child({component:"client-factory"})).info("Creating API client with components")
|
|
3383
3396
|
const b=w.tokenManager||new r.TokenManager(f,w.workingDir||process.cwd())
|
|
3384
3397
|
await b.initialize()
|
|
3385
3398
|
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
3399
|
I.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3387
|
-
const E=new
|
|
3400
|
+
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
3401
|
I.registerClient(E)
|
|
3389
3402
|
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
3403
|
I.registerClient(S),f.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
@@ -3392,7 +3405,7 @@ const q=new u.RequestClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts
|
|
|
3392
3405
|
I.registerClient(q),f.info("RequestClient post-constructor token: "+(q.getAuthToken()?"present":"missing"))
|
|
3393
3406
|
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
3407
|
I.registerClient(T)
|
|
3395
|
-
const x=new
|
|
3408
|
+
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
3409
|
I.registerClient(x)
|
|
3397
3410
|
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
3411
|
if(I.registerClient(P),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
|
|
@@ -3412,8 +3425,8 @@ if(_)try{await _.connectStdio(),(0,a.isDebugToolsEnabled)()&&b.info("Connected s
|
|
|
3412
3425
|
throw b.error("Failed to connect stdio transport",{errorDetails:t}),e}else b.error("No global server instance available to connect transport")
|
|
3413
3426
|
return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3414
3427
|
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,
|
|
3428
|
+
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)
|
|
3429
|
+
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
3430
|
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
3431
|
const I=process.stdout.write
|
|
3419
3432
|
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 +3444,8 @@ b.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(
|
|
|
3431
3444
|
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
3445
|
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(b),n=await r.getInstallationConfig()
|
|
3433
3446
|
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,
|
|
3447
|
+
try{const e=await(0,m.syncPluginsGlobal)((0,g.isDevBuild)(),b)
|
|
3448
|
+
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
3449
|
const e=await(0,i.createServer)(w,b,k,v)
|
|
3437
3450
|
_=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&b.info("MCP server created successfully")
|
|
3438
3451
|
const n=r()
|
|
@@ -3466,8 +3479,8 @@ async function r(e,t){let r=e
|
|
|
3466
3479
|
const n=[],o=[...t].sort(((e,t)=>{const r=e=>"number"==typeof e?e:Array.isArray(e)?Math.max(...e):e.end
|
|
3467
3480
|
return r(t.lines)-r(e.lines)}))
|
|
3468
3481
|
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,
|
|
3482
|
+
try{const n=(0,g.replaceLines)(r,e.lines,e.content)
|
|
3483
|
+
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
3484
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3472
3485
|
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
3486
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3475,7 +3488,7 @@ return t},n(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3475
3488
|
var t={}
|
|
3476
3489
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3477
3490
|
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,
|
|
3491
|
+
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
3492
|
let I,k,v=l.FileOperationPhase.VALIDATION
|
|
3480
3493
|
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
3494
|
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 +3503,34 @@ M.push({type:"file",path:t,fullPath:r,replacements:e.replacements.map((e=>({line
|
|
|
3490
3503
|
if(R.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3491
3504
|
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
3505
|
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,
|
|
3506
|
+
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}
|
|
3507
|
+
throw e}}v=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3508
|
+
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
3509
|
let A=null
|
|
3497
|
-
M.length>0&&D&&(A=await l.validateWorkItemStates(x,M[0].path,o,i,n,w,
|
|
3510
|
+
M.length>0&&D&&(A=await l.validateWorkItemStates(x,M[0].path,o,i,n,w,g,C.metricsPrefix))
|
|
3498
3511
|
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:
|
|
3512
|
+
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"}))
|
|
3513
|
+
const N=await l.ensureCorrectWorkspaceContext({taskPromoted:F.taskPromoted,requestId:D,context:n,operation:"replace-lines",logger:w,metrics:g,metricsPrefix:C.metricsPrefix})
|
|
3501
3514
|
if(!N.success)throw Error(N.error)
|
|
3502
3515
|
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
3516
|
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,
|
|
3517
|
+
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}
|
|
3518
|
+
throw e}v=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3519
|
+
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)
|
|
3520
|
+
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")
|
|
3521
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"replace-lines",{requestId:D,taskId:x,workspaceManager:n.workspaceManager},w,g)
|
|
3509
3522
|
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
3523
|
const H=[]
|
|
3511
3524
|
let B=0,U=0,G=0,W=0
|
|
3512
3525
|
for(const e of M){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3513
3526
|
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
3527
|
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,
|
|
3528
|
+
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
3529
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3517
3530
|
t.filename=s?.filename
|
|
3518
3531
|
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:
|
|
3532
|
+
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))
|
|
3533
|
+
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
3534
|
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
3535
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
3523
3536
|
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 +3539,18 @@ for(const t of e.replacements.filter((e=>!e.success)))te+=`- Replace ${"number"=
|
|
|
3526
3539
|
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
3540
|
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
3541
|
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),
|
|
3542
|
+
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
|
|
3543
|
+
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}}}
|
|
3544
|
+
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
3545
|
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
3546
|
try{const s=t.projectId
|
|
3534
3547
|
if(!s)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
|
|
3535
3548
|
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
3549
|
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
|
|
3538
|
-
let w=!1
|
|
3550
|
+
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
|
|
3551
|
+
if(c?.sessionId)try{await o.proxyPost(`/api/projects/${s}/session-plan-associations`,{opencodeSessionId:c.sessionId,documentId:y})}catch(e){h.warn("Failed to create session-plan association",{error:(0,r.getErrorMessage)(e)})}let w=!1
|
|
3539
3552
|
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(
|
|
3553
|
+
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
3554
|
const r=t(8824),n=t(3416)},6688(e,exports,t){"use strict"
|
|
3542
3555
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
|
|
3543
3556
|
const r=t(9896),n=t(6928),o=t(3545)
|
|
@@ -3593,18 +3606,18 @@ var t={}
|
|
|
3593
3606
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3594
3607
|
return o(t,e),t})
|
|
3595
3608
|
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 "+
|
|
3609
|
+
try{const{taskId:m,showDiff:g=!1}=e
|
|
3610
|
+
if(!m)throw(0,i.createValidationError)("Task ID is required")
|
|
3611
|
+
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.`)
|
|
3612
|
+
s.info("Getting file changes for task "+m,{showDiff:g})
|
|
3600
3613
|
const f=r.getTaskClient(),y=r.getToolRecordClient(),w=t.projectId
|
|
3601
3614
|
let b
|
|
3602
3615
|
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 "+
|
|
3616
|
+
try{const P=await f.getTask(m)
|
|
3617
|
+
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=[]
|
|
3618
|
+
try{const M=await y.getToolRecordsByTaskId(m)
|
|
3619
|
+
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 $={}
|
|
3620
|
+
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
3621
|
function k(e){const t=new Map,r=new Map,n=[]
|
|
3609
3622
|
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
3623
|
if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
|
|
@@ -3625,7 +3638,7 @@ if(t&&(n=e.metadata.successfulOperations.some((e=>e&&e.source&&e.destination))),
|
|
|
3625
3638
|
if(!Array.isArray(t)||0===t.length)return s.warn("Skipping delete-files record without valid paths array: "+e.id),!1
|
|
3626
3639
|
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
3640
|
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 ${
|
|
3641
|
+
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
3642
|
const _=new Map
|
|
3630
3643
|
C.forEach((e=>{let t=null
|
|
3631
3644
|
if(e.metadata){if(!e.metadata.commitHash){const t=["gitCommitId","commitId","commit","gitCommit"]
|
|
@@ -3672,34 +3685,34 @@ continue}const H=L[0],B=L[L.length-1]
|
|
|
3672
3685
|
s.info(`First commit: ${H.commitHash?H.commitHash:"unknown"}, Last commit: ${B.commitHash?B.commitHash:"unknown"}`)
|
|
3673
3686
|
let U=null,G=!1
|
|
3674
3687
|
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(
|
|
3688
|
+
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
3689
|
s.info(`Getting new file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${F}`)
|
|
3677
3690
|
const de=await t.git.show(le)
|
|
3678
3691
|
if(de&&de.trim().length>0){let ue=""
|
|
3679
3692
|
const he=de.split("\n")
|
|
3680
3693
|
for(const pe of he)ue+=`+${pe}\n`
|
|
3681
3694
|
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(
|
|
3695
|
+
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
3696
|
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
3697
|
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?(
|
|
3698
|
+
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})
|
|
3699
|
+
continue}let ge
|
|
3700
|
+
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
3701
|
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)",
|
|
3702
|
+
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
3703
|
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
3704
|
s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${F}`)
|
|
3692
3705
|
const _e=await t.git.show(Ce)
|
|
3693
|
-
if(_e&&_e.trim().length>0){if(
|
|
3706
|
+
if(_e&&_e.trim().length>0){if(g){let Ee=""
|
|
3694
3707
|
const Se=_e.split("\n")
|
|
3695
3708
|
for(const qe of Se)Ee+=`+${qe}\n`
|
|
3696
3709
|
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: ${
|
|
3710
|
+
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
3711
|
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
3712
|
const q=3e3
|
|
3700
3713
|
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**: ${
|
|
3714
|
+
if(g){for(const xe of E.values())xe.hasDiff&&xe.diffText&&(T+=xe.diffText.split("\n").length)
|
|
3715
|
+
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
3716
|
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
3717
|
for(const[Re,Me]of E.entries()){const{normalizedPath:$e,fullPath:je}=d.validateAndNormalizePath(Re,t)
|
|
3705
3718
|
let Oe=!1
|
|
@@ -3707,7 +3720,7 @@ try{await a.access(je),Oe=!0}catch{}S+=`### ${Re} ${Oe?"":"(Deleted)"}\n\n`
|
|
|
3707
3720
|
const De=new Date(Me.firstChange.timestamp).toLocaleString(),Ae=new Date(Me.lastChange.timestamp).toLocaleString()
|
|
3708
3721
|
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
3722
|
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`),
|
|
3723
|
+
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
3724
|
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
3725
|
module.exports=require("path")},6975(e,exports,t){"use strict"
|
|
3713
3726
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
|
|
@@ -3842,26 +3855,26 @@ i.appendFileSync(o,`[${s}] ${e} | ${t}${l}\n`)}catch(e){}}
|
|
|
3842
3855
|
const i=s(t(9896)),a=s(t(6928)),c=s(t(857))},7334(e,exports,t){"use strict"
|
|
3843
3856
|
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
3857
|
p.info("Creating new request",{args:e})
|
|
3845
|
-
const
|
|
3858
|
+
const m=d.startTimer("tool_handler_duration")
|
|
3846
3859
|
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
3860
|
throw new r.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
|
|
3848
3861
|
d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
|
|
3849
|
-
const
|
|
3850
|
-
if(!
|
|
3851
|
-
c.setProjectId(
|
|
3862
|
+
const g=t.projectId
|
|
3863
|
+
if(!g)throw new r.ValidationError("Project ID is required for creating requests.")
|
|
3864
|
+
c.setProjectId(g)
|
|
3852
3865
|
const f=c.getRequestClient()
|
|
3853
3866
|
let y=(0,a.getApprovalMode)()
|
|
3854
3867
|
try{const e=h?.sessionId
|
|
3855
3868
|
if(e){const t=c.getCLISessionClient()
|
|
3856
3869
|
if(t){const r=await t.getByExternalId(e)
|
|
3857
3870
|
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/"+
|
|
3871
|
+
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
3872
|
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
3873
|
let b=h
|
|
3861
3874
|
if(h?.sessionId)try{const e=c.getCLISessionClient()
|
|
3862
3875
|
if(e){const t=await e.getByExternalId(h.sessionId)
|
|
3863
3876
|
"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:
|
|
3877
|
+
p.info("Creating request via request client",{projectId:g,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
|
|
3865
3878
|
const k=await f.createRequest(I)
|
|
3866
3879
|
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
3880
|
const v=(0,o.extractDataFromResponse)(k,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
|
|
@@ -3869,12 +3882,12 @@ let _,E={created:!1}
|
|
|
3869
3882
|
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
3883
|
p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
|
|
3871
3884
|
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})}
|
|
3885
|
+
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"}`})
|
|
3886
|
+
_=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
3887
|
const S=C.localId||C.id
|
|
3875
3888
|
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
3889
|
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(
|
|
3890
|
+
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
3891
|
let t=e.message
|
|
3879
3892
|
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
3893
|
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 +3908,12 @@ const h=i[c]
|
|
|
3895
3908
|
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
3909
|
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
3910
|
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:
|
|
3911
|
+
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
3912
|
if("errorResult"in y)return y.errorResult
|
|
3900
3913
|
const{taskId:w}=y
|
|
3901
|
-
p.info("Processing modify-file operations",{taskId:w,operationCount:
|
|
3914
|
+
p.info("Processing modify-file operations",{taskId:w,operationCount:m.length,comment:g})
|
|
3902
3915
|
const b=[],I=[],k=[],v=[],C=[]
|
|
3903
|
-
for(const e of
|
|
3916
|
+
for(const e of m){const t={path:e.path,documentId:e.documentId}
|
|
3904
3917
|
switch(e.operationType){case"replace-string":b.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
|
|
3905
3918
|
break
|
|
3906
3919
|
case"insert-lines":I.push({...t,insertions:e.insertLines.insertions})
|
|
@@ -3911,15 +3924,15 @@ case"delete-string":v.push({...t,replacements:e.deleteString.patterns.map((e=>({
|
|
|
3911
3924
|
break
|
|
3912
3925
|
case"delete-lines":C.push({...t,lines:e.deleteLines.lines})}}const _=[]
|
|
3913
3926
|
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:
|
|
3927
|
+
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
3928
|
_.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:
|
|
3929
|
+
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
3930
|
_.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:
|
|
3931
|
+
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
3932
|
_.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:
|
|
3933
|
+
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
3934
|
_.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:
|
|
3935
|
+
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
3936
|
_.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
3937
|
let T="## Modify File Results\n\n"
|
|
3925
3938
|
T+="**Summary:**\n",T+=`- **Total operation types:** ${_.length}\n`,T+=`- **Successful:** ${S}\n`,T+=`- **Failed:** ${q}\n\n`
|
|
@@ -3929,22 +3942,22 @@ const r=t(3306),n=t(6486),o=t(6651),s=t(8824)},7478(e,exports,t){"use strict"
|
|
|
3929
3942
|
async function r(e,t,r){const n=r.startTimer("git_get_current_branch_duration")
|
|
3930
3943
|
try{const o=(await e.status()).current
|
|
3931
3944
|
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,
|
|
3945
|
+
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
3946
|
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
3947
|
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,
|
|
3948
|
+
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
3949
|
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
3950
|
try{const a=await r(e,o,s)
|
|
3938
3951
|
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
3952
|
if(!await n(e,t,o,s)){const e=`Branch '${t}' does not exist`
|
|
3940
3953
|
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
3954
|
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,
|
|
3955
|
+
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
3956
|
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
3957
|
try{let o,s=!0
|
|
3945
3958
|
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
3959
|
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,
|
|
3960
|
+
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
3961
|
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
3962
|
try{t.debug("Starting uncommitted changes check"),t.debug("Checking for uncommitted changes before merge"),Date.now()
|
|
3950
3963
|
const o=await e.status()
|
|
@@ -3956,7 +3969,7 @@ t.debug("Uncommitted changes summary",{hasChanges:l,totalFiles:c,staged:s.length
|
|
|
3956
3969
|
let d=""
|
|
3957
3970
|
if(l){const e=[]
|
|
3958
3971
|
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,
|
|
3972
|
+
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
3973
|
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
3974
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3962
3975
|
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 +3983,42 @@ try{if(await n(e,t,s,i)){const e=`Branch '${t}' already exists`
|
|
|
3970
3983
|
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
3984
|
await e.checkoutBranch(t,o)
|
|
3972
3985
|
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,
|
|
3986
|
+
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
3987
|
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
3988
|
try{const d=await r(e,i,a)
|
|
3976
3989
|
if(d!==s&&await o(e,s,i,a),!await n(e,t,i,a)){const e=`Source branch '${t}' does not exist`
|
|
3977
3990
|
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,
|
|
3991
|
+
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
3992
|
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
3993
|
try{const c=await r(e,s,i)
|
|
3981
3994
|
if(c===t){const e=`Cannot delete current branch '${t}'`
|
|
3982
3995
|
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
3996
|
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
3997
|
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,
|
|
3998
|
+
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
3999
|
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
4000
|
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,
|
|
4001
|
+
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
4002
|
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
4003
|
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
4004
|
return t?t[1]:null},exports.switchToDefaultBranch=async function(e,t,r){const n=r.startTimer("git_switch_to_default_duration")
|
|
3992
4005
|
try{const i=await s(e,t,r)
|
|
3993
4006
|
if(!i.defaultBranch){const e="No default branch found"
|
|
3994
4007
|
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,
|
|
4008
|
+
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
4009
|
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
4010
|
try{const o=await s(e,t,r),i=[]
|
|
3998
4011
|
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
4012
|
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,
|
|
4013
|
+
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
4014
|
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
4015
|
try{r.debug("Starting main branch change detection",{providedRevertCommitHash:t.substring(0,8),fullRevertCommitHash:t})
|
|
4003
4016
|
const n=await e.revparse(["HEAD"])
|
|
4004
4017
|
r.debug("Git state captured",{currentMainHash:n.substring(0,8),fullCurrentMainHash:n,revertCommitHash:t.substring(0,8),fullRevertCommitHash:t,hashesMatch:n===t})
|
|
4005
4018
|
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,
|
|
4019
|
+
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
4020
|
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,
|
|
4021
|
+
const i=await(0,m.validateCommitHash)(e,n,r,"hasMainChangedSinceRevert-head-validation")
|
|
4009
4022
|
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
4023
|
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
4024
|
r.debug("Hash comparison shows difference, checking ancestor relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),hashesEqual:!1})
|
|
@@ -4013,10 +4026,10 @@ let a=!1,c=0,l=null
|
|
|
4013
4026
|
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
4027
|
const o=await e.raw(["rev-list","--count",t+"..HEAD"])
|
|
4015
4028
|
c=parseInt(o.trim(),10),a=!0
|
|
4016
|
-
break}catch(e){l=e,r.debug("Ancestor check attempt failed",{attempt:n,error:(0,
|
|
4029
|
+
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
4030
|
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
4031
|
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,
|
|
4032
|
+
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
4033
|
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
4034
|
const n=await t.getToolRecordsByRequestId(e,"revert-request")
|
|
4022
4035
|
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 +4038,7 @@ for(const t of n)if(r.debug("Examining tool record",{requestId:e,recordId:t.id,r
|
|
|
4025
4038
|
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
4039
|
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
4040
|
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,
|
|
4041
|
+
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
4042
|
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
4043
|
try{if(!r.hasChanges)throw new p.ValidationError("No uncommitted changes to commit")
|
|
4031
4044
|
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 +4047,7 @@ i.length>0?(n.debug("Staging files",{files:i.slice(0,10),total:i.length}),await
|
|
|
4034
4047
|
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
4048
|
n.debug("Commit message",{message:a.split("\n")[0]}),n.debug("Creating commit"),await e.commit(a)
|
|
4036
4049
|
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,
|
|
4050
|
+
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
4051
|
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
4052
|
try{let c=Date.now()
|
|
4040
4053
|
o.debug("Checking for user changes before tool operation",{toolName:r})
|
|
@@ -4051,8 +4064,8 @@ const h=`${u}\n\n${{...d,summary:`User changes detected before ${r}: ${d.summary
|
|
|
4051
4064
|
o.debug("Committing user changes with message",{firstLine:h.split("\n")[0]})
|
|
4052
4065
|
const p=[...d.unstagedFiles,...d.untrackedFiles]
|
|
4053
4066
|
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:
|
|
4067
|
+
const m=await l.revparse(["HEAD"])
|
|
4068
|
+
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
4069
|
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
4070
|
try{const o=t(3807).simpleGit(e),s=(await o.status()).not_added||[]
|
|
4058
4071
|
for(const t of s)try{const o=y.join(e,t),s=f.statSync(o)
|
|
@@ -4061,7 +4074,7 @@ const t=e.reduce(((e,t)=>e+t.sizeMB),0)
|
|
|
4061
4074
|
let r=`\n\n\u26a0\ufe0f **Performance Warning**: Large untracked files detected (${Math.round(t)} MB total) that may slow git operations:\n`
|
|
4062
4075
|
for(const t of e.slice(0,5))r+=`- \`${t.path}\` (${t.sizeMB} MB)\n`
|
|
4063
4076
|
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),
|
|
4077
|
+
const h=t(3444),p=t(9860),m=t(3922),g=t(8824),f=u(t(9896)),y=u(t(6928))
|
|
4065
4078
|
t(857)},7575(e,exports){"use strict"
|
|
4066
4079
|
var t
|
|
4067
4080
|
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 +4278,7 @@ const r=t(4055)
|
|
|
4265
4278
|
Object.defineProperty(exports,"ProjectID",{enumerable:!0,get(){return r.ProjectID}}),Object.defineProperty(exports,"ProjectIDFactory",{enumerable:!0,get(){return r.ProjectIDFactory}})
|
|
4266
4279
|
const n=t(1791)
|
|
4267
4280
|
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
|
|
4281
|
+
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
4282
|
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
4283
|
if("errorResult"in I)return I.errorResult
|
|
4271
4284
|
const{taskId:k}=I
|
|
@@ -4279,18 +4292,18 @@ case"delete-files":_.push(...e.deleteFiles.targets)
|
|
|
4279
4292
|
break
|
|
4280
4293
|
case"get-file-info":E.push({path:e.getFileInfo.path})}const S=[]
|
|
4281
4294
|
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
|
|
4295
|
+
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
4296
|
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
|
|
4297
|
+
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
4298
|
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
|
|
4299
|
+
const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,m,g)
|
|
4287
4300
|
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,
|
|
4301
|
+
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,m)
|
|
4289
4302
|
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
4303
|
let P="## Manage Files Results\n\n"
|
|
4291
4304
|
P+="**Summary:**\n",P+=`- **Total operation types:** ${S.length}\n`,P+=`- **Successful:** ${T}\n`,P+=`- **Failed:** ${x}\n\n`
|
|
4292
4305
|
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}),
|
|
4306
|
+
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
4307
|
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
4308
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4296
4309
|
const r=t(6183),n=t(5303)
|
|
@@ -4315,8 +4328,8 @@ const r=t(5806),n=t(5715)
|
|
|
4315
4328
|
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
4329
|
async function r(e,t,r,n,o,s,a,l,d,u){const h=Date.now()
|
|
4317
4330
|
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:
|
|
4331
|
+
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
|
|
4332
|
+
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
4333
|
const n=t instanceof Error?`${t.message} (${JSON.stringify(t)})`:t+""
|
|
4321
4334
|
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
4335
|
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 +4342,35 @@ if(o.workspaceManager){const t=o.workspaceManager.getCurrentContext(o.currentSes
|
|
|
4329
4342
|
"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
4343
|
let p=null
|
|
4331
4344
|
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:
|
|
4345
|
+
const m=1===n.length?`${s} in ${n[0]} (${i})`:`${s} in ${n.length} files (${i})`,g=(await d.commit(m)).commit
|
|
4346
|
+
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
4347
|
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
4348
|
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
|
|
4349
|
+
let m,g
|
|
4337
4350
|
l.debug("createFileOperationRecords called",{taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,operationType:o,path:s})
|
|
4338
4351
|
try{const a=await r(e,t,n,o,s,i,c,l,u,h)
|
|
4339
|
-
return
|
|
4352
|
+
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
4353
|
try{let s=t.git
|
|
4341
4354
|
if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
4342
4355
|
"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
4356
|
const t=await s.commit("[USER-MODS] Preserve user modifications before tool operation: "+e)
|
|
4344
4357
|
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
|
|
4358
|
+
let p,m=null
|
|
4359
|
+
try{let g=s.git
|
|
4347
4360
|
if(s.workspaceManager){const t=s.workspaceManager.getCurrentContext(s.currentSessionId)
|
|
4348
4361
|
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
|
-
|
|
4362
|
+
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
4363
|
let a=!1,f=""
|
|
4351
|
-
try{if(f=(await
|
|
4364
|
+
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
4365
|
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
4366
|
const a=r.trim(),c=s.getCurrentRequestId?s.getCurrentRequestId():null
|
|
4354
4367
|
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:
|
|
4368
|
+
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"])
|
|
4369
|
+
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
|
|
4370
|
+
await g.add(t),p=(await g.commit(y)).commit
|
|
4371
|
+
try{const r=await g.revparse(["--abbrev-ref","HEAD"]),n=await g.revparse(["HEAD"])
|
|
4372
|
+
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})
|
|
4373
|
+
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
4374
|
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
4375
|
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
4376
|
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 +4380,10 @@ if(e.includes("/dist-dev/")||e.includes("\\dist-dev\\"))return!0
|
|
|
4367
4380
|
if(e.includes("/dist/")||e.includes("\\dist\\"))return!1
|
|
4368
4381
|
const t=process.cwd()
|
|
4369
4382
|
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:
|
|
4383
|
+
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
4384
|
try{const e=u||process.cwd(),o={...process.env,...(0,c.getOpencodeSpawnEnv)(e,(0,l.isDevMode)())}
|
|
4372
4385
|
let y
|
|
4373
|
-
if(
|
|
4386
|
+
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
4387
|
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
4388
|
const w=(0,i.join)(u||process.cwd(),".alchemy_lab"),b=(0,i.join)(w,"spawn-stderr.log")
|
|
4376
4389
|
let I
|
|
@@ -4391,18 +4404,18 @@ const u=s.getRequestClient(),h=await u.listRequests(d)
|
|
|
4391
4404
|
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
4405
|
const p=(0,n.extractArrayFromResponse)(h,{logger:c,operationName:"listRequests",defaultValue:[]})
|
|
4393
4406
|
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:`${
|
|
4407
|
+
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"}:`
|
|
4408
|
+
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
4409
|
const r=t(9860),n=t(2960),o=t(8824)},8045(e,exports,t){"use strict"
|
|
4397
4410
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4398
4411
|
const r=t(6183),n=t(7456)
|
|
4399
4412
|
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
4413
|
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
|
|
4414
|
+
try{const i=e,{requestId:c,format:d="summary",path:h}=i,p=s.getRequestClient(),m=await p.getRequest(c)
|
|
4415
|
+
if(!m)return u({success:!1,reason:"not_found"}),n("Request not found: "+c)
|
|
4416
|
+
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
4417
|
let b,I
|
|
4405
|
-
if(y){const e=
|
|
4418
|
+
if(y){const e=m.metadata?.mergeBaseSha,t=m.metadata?.mergeCommitSha
|
|
4406
4419
|
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
4420
|
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
4421
|
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]:[]
|
|
@@ -4417,21 +4430,28 @@ if(r.startsWith("R")){const e=t[1],n=t[2],o=_.get(n)||{additions:0,deletions:0,b
|
|
|
4417
4430
|
Number.isFinite(s)&&(i.similarity=s),o.binary&&(i.binary=!0),E.push(i)}else{const e=t[1],n=_.get(e)||{additions:0,deletions:0,binary:!1},o={path:e,status:"A"===r?"added":"D"===r?"deleted":"modified",additions:n.additions,deletions:n.deletions}
|
|
4418
4431
|
n.binary&&(o.binary=!0),E.push(o)}}return E.sort(((e,t)=>e.path.localeCompare(t.path))),u({success:!0}),l.incrementCounter("request_diff_total",1,{format:"summary"}),r({baseSha:b,headSha:I,branch:y?null:w,files:E})}catch(e){return d.error("request_diff failed",{error:e instanceof Error?e.stack:e+""}),u({success:!1}),l.incrementCounter("request_diff_errors",1),n("request_diff failed: "+(0,i.getErrorMessage)(e))}}
|
|
4419
4432
|
const o=t(3807),s=t(2272),i=t(8824),a=5e5},8291(e,exports,t){"use strict"
|
|
4420
|
-
var
|
|
4421
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.validateAndNormalizePath=function(e,t){
|
|
4422
|
-
const
|
|
4423
|
-
if(
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4433
|
+
function r(e){return e.workspaceManager?e.workspaceManager.getCurrentContext(e.currentSessionId).basePath:e.basePath}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4434
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.validateAndNormalizePath=function(e,t){const n=function(e,t){if(!e.startsWith("log:"))return null
|
|
4435
|
+
const r=e.slice(4).replace(/^\/+/,""),n=r?`${i.ALCHEMY_DIR_NAME}/command-logs/${r}.log`:i.ALCHEMY_DIR_NAME+"/command-logs"
|
|
4436
|
+
if(r&&(!/^[a-zA-Z0-9._-]+$/.test(r)||r.includes("..")))throw(0,s.createValidationError)(`Invalid log id in '${e}'. Expected alphanumeric characters, dots, underscores, hyphens.`)
|
|
4437
|
+
const a=o.default.resolve(t,n)
|
|
4438
|
+
if(!a.startsWith(t+o.default.sep))throw(0,s.createValidationError)("Log path resolves outside the workspace: "+e)
|
|
4439
|
+
return{normalizedPath:n,fullPath:a}}(e,r(t))
|
|
4440
|
+
if(n)return n
|
|
4441
|
+
let a=e.replace(/\\/g,"/")
|
|
4442
|
+
const d=r(t)
|
|
4443
|
+
if(o.default.isAbsolute(a)){const e=o.default.normalize(a)
|
|
4444
|
+
if(e.startsWith(d))a=o.default.relative(d,e),a=a.replace(/\\/g,"/")
|
|
4445
|
+
else{const r=t.basePath
|
|
4446
|
+
if(!r||!e.startsWith(r)){const n=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.mode||"unknown",o=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.requestId||"none"
|
|
4447
|
+
throw(0,s.createValidationError)(`File path is outside the allowed directory\n Requested path (absolute): ${e}\n Allowed base (current workspace): ${d}\n Allowed base (main repo): ${r||"N/A"}\n Workspace mode: ${n}\n Current request: ${o}\n Note: Use relative paths (e.g., 'src/file.txt') instead of absolute paths`)}a=o.default.relative(r,e),a=a.replace(/\\/g,"/")}}if(function(e){const t=e.replace(/\\/g,"/").replace(/^\//g,"")
|
|
4448
|
+
for(const e of c)if(t===e||t.startsWith(e+"/"))return!0
|
|
4449
|
+
for(const e of l)if(t===e||t.endsWith("/"+e))return!0
|
|
4450
|
+
return!1}(a))throw(0,s.createValidationError)(`Access to '${a}' is not allowed - this directory contains system files`)
|
|
4451
|
+
const u=o.default.resolve(d,a)
|
|
4452
|
+
if(!u.startsWith(d)){const e=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.mode||"unknown",r=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.requestId||"none"
|
|
4453
|
+
throw(0,s.createValidationError)(`File path is outside the allowed directory\n Requested path: ${a}\n Resolved to: ${u}\n Allowed base: ${d}\n Workspace mode: ${e}\n Current request: `+r)}return{normalizedPath:a,fullPath:u}},exports.validateTaskIdFormat=function(e,t,r,n){e&&(0,a.isTaskRef)(e)||(t.warn("Invalid task ID format provided",{taskId:e}),r.incrementCounter(n+"_invalid_task_format",1))}
|
|
4454
|
+
const o=n(t(6928)),s=t(9860),i=t(4139),a=t(4466),c=[i.ALCHEMY_DIR_NAME,".opencode",".git"],l=[".mcp-server.lock"]},8309(e,exports,t){"use strict"
|
|
4435
4455
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
4436
4456
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
4437
4457
|
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=[]
|
|
@@ -4440,35 +4460,35 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4440
4460
|
var t={}
|
|
4441
4461
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
4442
4462
|
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,
|
|
4463
|
+
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
4464
|
let y,w,b=l.FileOperationPhase.VALIDATION
|
|
4445
4465
|
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
4466
|
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
4467
|
if("errorResult"in v)return v.errorResult
|
|
4448
4468
|
const{taskId:C}=v
|
|
4449
|
-
|
|
4469
|
+
g.info("Creating directory: "+u,{taskId:C,path:u,comment:h}),l.validateTaskIdFormat(C,g,p,I.metricsPrefix),r.getCurrentBranchContext&&await r.getCurrentBranchContext()
|
|
4450
4470
|
const{normalizedPath:_,fullPath:E}=l.validateAndNormalizePath(u,r)
|
|
4451
4471
|
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:
|
|
4472
|
+
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)
|
|
4473
|
+
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})
|
|
4474
|
+
const P=await l.ensureCorrectWorkspaceContext({taskPromoted:x.taskPromoted,requestId:q,context:r,operation:"create-directory",logger:g,metrics:p,metricsPrefix:I.metricsPrefix})
|
|
4455
4475
|
if(!P.success)throw Error(P.error)
|
|
4456
4476
|
let R=!1
|
|
4457
4477
|
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,
|
|
4478
|
+
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
4479
|
y=M,w=M,b=I.fileOperationPhase,p.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4460
4480
|
let j=R
|
|
4461
|
-
if(!R){await a.default.mkdir(E,{recursive:!0}),
|
|
4481
|
+
if(!R){await a.default.mkdir(E,{recursive:!0}),g.info("Successfully created directory "+_)
|
|
4462
4482
|
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,
|
|
4483
|
+
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
4484
|
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,
|
|
4485
|
+
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!R&&j?_+"/.gitkeep":_,F=await l.commitToGit(C,A,M,$,D,r,g,p,I.metricsPrefix)
|
|
4486
|
+
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
4487
|
const N=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4468
4488
|
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,
|
|
4489
|
+
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
|
|
4490
|
+
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
|
|
4491
|
+
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
4492
|
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
4493
|
function r(e){const t=[]
|
|
4474
4494
|
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 +4497,11 @@ case"move-files":return"\u{1f4cb} Move Files"
|
|
|
4477
4497
|
case"delete-files":return"\u{1f5d1}\ufe0f Delete Files"
|
|
4478
4498
|
case"manage-files":return"\u{1f4c1} Manage Files"
|
|
4479
4499
|
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:
|
|
4500
|
+
try{const{requestId:l,detailLevel:p="summary",taskId:m,showDiff:g=!1,fileFilter:f}=e
|
|
4481
4501
|
if(!l)throw(0,o.createValidationError)("Request ID is required")
|
|
4482
4502
|
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:
|
|
4503
|
+
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.`)
|
|
4504
|
+
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
4505
|
const y=t.projectId
|
|
4486
4506
|
let w
|
|
4487
4507
|
c.setProjectId(y)
|
|
@@ -4490,7 +4510,7 @@ w={id:n.id||l,title:n.title||"Unknown Request",description:n.description||"No de
|
|
|
4490
4510
|
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
4511
|
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
4512
|
let o=[]
|
|
4493
|
-
try{
|
|
4513
|
+
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
4514
|
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
4515
|
let u=t.filter((e=>{const t=e.type
|
|
4496
4516
|
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 +4524,10 @@ let r=0
|
|
|
4504
4524
|
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
4525
|
if(e&&e.trim()){const r=500,n=e.length
|
|
4506
4526
|
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,
|
|
4527
|
+
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
4528
|
return h({success:!0,recordCount:o.length}),{content:[{type:"text",text:s}]}}{const e=c.getToolRecordClient()
|
|
4509
4529
|
let n=[]
|
|
4510
|
-
try{
|
|
4530
|
+
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
4531
|
let o=0
|
|
4512
4532
|
for(const s of e){const e=s.type
|
|
4513
4533
|
if(!["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(e))continue
|
|
@@ -4549,17 +4569,17 @@ return s.default.writeFileSync(t,JSON.stringify(c,null,2)),n(e,t,r),h.info("Crea
|
|
|
4549
4569
|
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
4570
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.acquireProcessLock=function(e){const t=i.default.join(e,c.ALCHEMY_DIR_NAME)
|
|
4551
4571
|
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,
|
|
4572
|
+
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
4573
|
try{const e=function(e){if(!s.default.existsSync(e))return null
|
|
4554
4574
|
try{const t=s.default.readFileSync(e,"utf8").trim()
|
|
4555
4575
|
try{const e=JSON.parse(t)
|
|
4556
4576
|
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
4577
|
const e={mode:"multi-agent",created:(new Date).toISOString(),hostname:"unknown"}
|
|
4558
4578
|
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,
|
|
4579
|
+
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
|
|
4580
|
+
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
4581
|
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,
|
|
4582
|
+
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
4583
|
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
4584
|
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
4585
|
let r=0,n=0
|
|
@@ -4607,16 +4627,16 @@ function r(e){const t=c[e]
|
|
|
4607
4627
|
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
4628
|
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
4629
|
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,"_"),
|
|
4630
|
+
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
4631
|
try{const t=r(e),s={}
|
|
4612
4632
|
let i,f
|
|
4613
4633
|
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}: ${
|
|
4634
|
+
let y=u.note||`Failed to execute ${e}: ${m.substring(0,100)}${m.length>100?"...":""}`
|
|
4615
4635
|
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:
|
|
4636
|
+
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}}
|
|
4637
|
+
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
4638
|
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:
|
|
4639
|
+
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
4640
|
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
4641
|
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
4642
|
else if(e&&"object"==typeof e)for(const t of Object.keys(e)){const n=e[t]
|
|
@@ -4641,13 +4661,13 @@ function r(e,t,r){const n=exports.ERROR_TYPE_PROPERTIES[e]||exports.ERROR_TYPE_P
|
|
|
4641
4661
|
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
4662
|
return{statusCode:e.statusCode,body:t}}if(e instanceof Error&&"ConnectionError"===e.name){const t=e
|
|
4643
4663
|
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
|
|
4664
|
+
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
4665
|
const i=t(7388)
|
|
4646
4666
|
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
4667
|
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
4668
|
const o=exports.ERROR_TYPE_PROPERTIES[this.code]
|
|
4649
4669
|
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
|
|
4670
|
+
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
4671
|
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
4672
|
const o=e.split("\n"),s=[],i=new Set
|
|
4653
4673
|
let a=!1,c=""
|
|
@@ -4690,7 +4710,7 @@ if("string"==typeof r&&r.length>0)return`${e}: ${r}`}return"Unknown error (no re
|
|
|
4690
4710
|
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
4711
|
return t?`${parseInt(t[1],10)}.${{m:"minutes",h:"hours",d:"days",w:"weeks"}[t[2]]}.ago`:e}(a):void 0
|
|
4692
4712
|
try{let a
|
|
4693
|
-
if(i===await
|
|
4713
|
+
if(i===await g(e,l,d))a=await e.log({file:t,maxCount:r,...u&&{"--since":u}})
|
|
4694
4714
|
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
4715
|
try{const a=await e.raw(["log","--max-count="+r,"--pretty=format:%H|%an|%ad|%s","--date=iso",...u?["--since="+u]:[],i,"--",t])
|
|
4696
4716
|
if(a&&a.trim()){const r=a.trim().split("\n").map((e=>{const[t,r,n,o]=e.split("|")
|
|
@@ -4713,26 +4733,26 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4713
4733
|
var t={}
|
|
4714
4734
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
4715
4735
|
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:
|
|
4736
|
+
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()
|
|
4737
|
+
try{const o=e,{path:a,limit:g,showDiff:f,showTraceability:y,branch:w,commit:b,since:I}=o
|
|
4718
4738
|
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
4739
|
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
4740
|
try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
|
|
4721
4741
|
if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
|
|
4722
4742
|
const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
|
|
4723
4743
|
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:
|
|
4744
|
+
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
4745
|
try{await l.access(y)}catch(e){throw Error("File not found: "+f)}const w=a.git
|
|
4726
4746
|
if(!w)throw Error("Git is not available in this context")
|
|
4727
4747
|
let b={branch:null,requestId:null,isMain:!0}
|
|
4728
4748
|
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,
|
|
4749
|
+
if(s)I=await r(w,f,t,n,o,s,i,c,h,m),k=`## File History: ${f} (Branch: ${s})\n\n`
|
|
4750
|
+
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)}]}
|
|
4751
|
+
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
4752
|
{const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
|
|
4733
4753
|
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(...
|
|
4754
|
+
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)))
|
|
4755
|
+
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
4756
|
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
4757
|
const v=I.length,C=Math.min(I.length,t)
|
|
4738
4758
|
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 +4761,9 @@ for(let e=0;e<I.length;e++){const t=I[e]
|
|
|
4741
4761
|
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
4762
|
let r=0,n=0
|
|
4743
4763
|
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()-
|
|
4764
|
+
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
4765
|
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)),
|
|
4766
|
+
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
4767
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
4748
4768
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
4749
4769
|
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 +4894,7 @@ let c
|
|
|
4874
4894
|
try{const e=await fetch(`http://localhost:${b}/api/project-settings`)
|
|
4875
4895
|
if(e.ok){const t=await e.json()
|
|
4876
4896
|
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,
|
|
4897
|
+
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
4898
|
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
4899
|
if(!s)throw new u.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
|
|
4880
4900
|
return(0,w.logSessionIdentity)(""+r,"identity",{sessionId:s,fromCliOrigin:!!o?.sessionId}),s}function a(e){const t=[],r=e.content||{}
|
|
@@ -4886,42 +4906,42 @@ if(!b)throw new u.ValidationError("API client not available")
|
|
|
4886
4906
|
const{operation:v}=e
|
|
4887
4907
|
k.info("Session message operation",{operation:v}),p.incrementCounter("session_message_operations",1,{operation:v})
|
|
4888
4908
|
try{switch(v){case"send":if(!e.type)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
4889
|
-
return(0,
|
|
4909
|
+
return(0,m.withAlchemyKind)(await async function(e,t,r,c,d){const{type:h}=e
|
|
4890
4910
|
if(!h)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
4891
4911
|
const p=c.getSessionMessageClient()
|
|
4892
4912
|
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||!
|
|
4913
|
+
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
|
|
4914
|
+
if(!p||!m?.question)throw new u.ValidationError("Question requires questionType and questionContent.question")
|
|
4895
4915
|
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
4916
|
if(!e)throw new u.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
|
|
4897
4917
|
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||
|
|
4918
|
+
if(!("alternatives"!==p||m.options&&Array.isArray(m.options)))throw new u.ValidationError("Alternatives questions require options array")
|
|
4899
4919
|
r.info("Creating question",{fromSessionId:b,toSessionId:I,questionType:p})
|
|
4900
|
-
const k=await l.createQuestion({fromSessionId:b,toSessionId:I,questionType:p,question:
|
|
4920
|
+
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
4921
|
let v=""
|
|
4902
|
-
if(I){const e=await n(b)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:
|
|
4922
|
+
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
4923
|
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
4924
|
if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&&t.options){r.push(""),r.push("**Options:**")
|
|
4905
4925
|
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:
|
|
4926
|
+
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
4927
|
if(!h||!p)throw new u.ValidationError("Report requires status and summary")
|
|
4908
4928
|
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
4929
|
const t=await s(b,a,r)
|
|
4910
4930
|
if(t)return r.info("Auto-resolved parent session",{parentSessionId:t}),t
|
|
4911
4931
|
throw new u.ValidationError("Could not find parent session. Ensure this session was created with a parent link, or provide an explicit toSessionId.")})()
|
|
4912
4932
|
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,
|
|
4933
|
+
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||{}
|
|
4934
|
+
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
4935
|
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
4936
|
throw new u.ValidationError(`Unknown message type: ${h}. Use "question" or "report".`)}(e,t,k,b,I),r("send",e))
|
|
4917
4937
|
case"reply":if(!e.messageCode)throw new u.ValidationError("reply operation requires messageCode")
|
|
4918
|
-
return(0,
|
|
4938
|
+
return(0,m.withAlchemyKind)(await async function(e,t,r,s,i){const{messageCode:c}=e
|
|
4919
4939
|
if(!c)throw new u.ValidationError("reply operation requires messageCode")
|
|
4920
4940
|
const d=s.getSessionMessageClient()
|
|
4921
4941
|
if(!d)throw new u.ValidationError("Session message client not available")
|
|
4922
4942
|
if(c.startsWith("Q-")){const{text:s,selectedOptions:l,notes:u}=e,h=e.respondedBySessionId??i?.sessionId
|
|
4923
4943
|
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}),
|
|
4944
|
+
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
4945
|
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
4946
|
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
4947
|
const e=await d.acknowledgeReport(c)
|
|
@@ -4936,21 +4956,21 @@ let l
|
|
|
4936
4956
|
try{const e=b.getSessionMessageClient()
|
|
4937
4957
|
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
4958
|
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(!
|
|
4959
|
+
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
|
|
4960
|
+
const g=n.getSessionMessageClient()
|
|
4961
|
+
if(!g)throw new u.ValidationError("Session message client not available")
|
|
4942
4962
|
if(!s){const e=o?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
|
|
4943
4963
|
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
4964
|
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:
|
|
4965
|
+
const y={sessionId:s,direction:a,limit:p,offset:m}
|
|
4946
4966
|
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
|
|
4967
|
+
const b=await g.listMessages(y)
|
|
4948
4968
|
if(0===b.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
|
|
4949
4969
|
const I=[`Found ${b.length} message(s):\n`]
|
|
4950
4970
|
for(const e of b)I.push("---\n"),I.push(d(e)),I.push("")
|
|
4951
4971
|
return{content:[{type:"text",text:I.join("\n")}]}}(e.list||{},0,k,b,I),"list-messages")
|
|
4952
4972
|
case"get":if(!e.messageCode)throw new u.ValidationError("get operation requires messageCode")
|
|
4953
|
-
return(0,
|
|
4973
|
+
return(0,m.withAlchemyKind)(await async function(e,t,r){const{messageCode:n}=e
|
|
4954
4974
|
if(!n)throw new u.ValidationError("get operation requires messageCode")
|
|
4955
4975
|
const o=r.getSessionMessageClient()
|
|
4956
4976
|
if(!o)throw new u.ValidationError("Session message client not available")
|
|
@@ -4958,7 +4978,7 @@ t.debug("Getting message",{messageCode:n})
|
|
|
4958
4978
|
const s=await o.getMessage(n)
|
|
4959
4979
|
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
4980
|
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),
|
|
4981
|
+
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
4982
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4963
4983
|
const r=t(6183),n=t(1281)
|
|
4964
4984
|
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 +5004,12 @@ let l,d
|
|
|
4984
5004
|
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
5005
|
let u=0
|
|
4986
5006
|
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{
|
|
5007
|
+
let h=!1,p="",m=null
|
|
5008
|
+
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}
|
|
5009
|
+
!m&&d&&d.trim()&&(m=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch))
|
|
5010
|
+
let g=[]
|
|
5011
|
+
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))})
|
|
5012
|
+
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
5013
|
if(!e||!e.trim())return t.debug("Empty merge-tree output - no conflicts to parse"),[]
|
|
4994
5014
|
let n
|
|
4995
5015
|
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 +5065,23 @@ o+=`## Test 4: All commits containing "${n}" (not just merges)\n`,o+=`Found ${e?
|
|
|
5045
5065
|
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
5066
|
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
5067
|
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:
|
|
5068
|
+
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
5069
|
try{let t,o
|
|
5050
|
-
if(
|
|
5070
|
+
if(g){t=await n.documentFileManager.getDocumentAsFile(d)
|
|
5051
5071
|
const e=n.documentFileManager.getCachedDocumentInfo(d)
|
|
5052
5072
|
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"),
|
|
5073
|
+
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),m=[]
|
|
5054
5074
|
for(const t of p){const{old:n,new:o,match_mode:i="unique"}=t,a={old:n,new:o,success:!1}
|
|
5055
5075
|
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
5076
|
continue}const t=(0,h.findMatches)(s,n,f,100,e.path)
|
|
5057
5077
|
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(f?" (tried fuzzy matching)":""),a.success=!1
|
|
5058
5078
|
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++):
|
|
5079
|
+
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
5080
|
const I=[]
|
|
5061
|
-
for(const e of
|
|
5081
|
+
for(const e of m)for(const t of e.matches)I.push({match:t,newText:e.newText,repResult:e.repResult})
|
|
5062
5082
|
I.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5063
5083
|
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"),
|
|
5084
|
+
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
5085
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5066
5086
|
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
5087
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -5091,7 +5111,7 @@ const t=await u.autoPromoteTaskStatus(T,D.status,A,e.request?.status,j,o,i,k,c,"
|
|
|
5091
5111
|
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
5112
|
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
5113
|
if(!n.success)throw Error(n.error)
|
|
5094
|
-
Date.now(),N=!0}if(M.length>0&&A)try{await(0,
|
|
5114
|
+
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
5115
|
throw e}O=Date.now()
|
|
5096
5116
|
const z=new Map
|
|
5097
5117
|
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 +5120,7 @@ s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,t.fullP
|
|
|
5100
5120
|
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
5121
|
const i=await(0,w.detectExternalEdits)(r.git,o,k)
|
|
5102
5122
|
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,
|
|
5123
|
+
const e=await(0,g.commitUserChangesBeforeToolOperation)(r.git,"replace_in_files",{requestId:A,taskId:T,workspaceManager:r.workspaceManager},k,c)
|
|
5104
5124
|
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
5125
|
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
5126
|
C=L,Date.now(),O=Date.now(),_=u.FileOperationPhase.STRING_REPLACEMENT,c.incrementCounter("replace_in_files_phase",1,{phase:_})
|
|
@@ -5127,7 +5147,7 @@ const d=o.workspaceManager?.consumeLargeFileWarning(o.currentSessionId)
|
|
|
5127
5147
|
return d&&(c+=d),c}(H,W,J,Q,r)
|
|
5128
5148
|
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
5149
|
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),
|
|
5150
|
+
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
5151
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
|
|
5132
5152
|
const t=e.trim()
|
|
5133
5153
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|
|
@@ -5198,11 +5218,11 @@ if(!u)throw new r.ValidationError("Project ID is required for listing tasks with
|
|
|
5198
5218
|
a.incrementCounter("list_tasks_attempts",1,{hasRequestId:!!i,hasFilters:Object.keys(d).length>0}),s.setProjectId(u)
|
|
5199
5219
|
const h=s.getTaskClient(),p=d
|
|
5200
5220
|
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=
|
|
5221
|
+
const m=await h.listTasks(p)
|
|
5222
|
+
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"})
|
|
5223
|
+
let g=[]
|
|
5224
|
+
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=[])
|
|
5225
|
+
const f=g
|
|
5206
5226
|
if(c.info(`Retrieved ${f.length} tasks`,{count:f.length,requestId:i,projectId:u}),0===f.length){let e=""
|
|
5207
5227
|
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
5228
|
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")
|