alchemylab 1.4.3 → 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 +48 -41
- package/dist/http-server.js +71 -63
- package/dist/index.js +633 -625
- package/dist/mcp-direct.js +71 -63
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14,9 +14,9 @@ var t={}
|
|
|
14
14
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
15
15
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
16
16
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.McpServer=void 0,exports.resetStdoutWrite=function(){process.stdout.write=P},exports.getMcpServer=r,exports.createServer=function(e,t,n,o,s={}){return r(e,t,n,o,s)}
|
|
17
|
-
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),
|
|
18
|
-
!(0,
|
|
19
|
-
class R{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,w.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new m.ProjectContext(e,t),this.tokenManager=new f.TokenManager(t,e,{remoteServerUrl:n}),this.configManager=new S.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new
|
|
17
|
+
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),p=t(9567),g=t(3444),m=t(7660),f=t(1253),y=i(t(7478)),w=t(4139),b=new Set,I=t(9860),k=t(1472),v=t(3328),C=t(8955),_=t(3217),E=t(5278),S=t(9060),T=t(8824),q=(0,g.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),P=process.stdout.write,j=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
|
|
18
|
+
!(0,g.isDebugToolsEnabled)()||j&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,g.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&q.debug("Stdout output",{content:e.substring(0,100),length:e.length}),P.call(process.stdout,e)}catch(e){return q.error("Error in safeStdoutWrite",{error:e+""}),!0}})
|
|
19
|
+
class R{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,w.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new m.ProjectContext(e,t),this.tokenManager=new f.TokenManager(t,e,{remoteServerUrl:n}),this.configManager=new S.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new 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__")
|
|
@@ -71,9 +71,9 @@ t&&t!==e&&(this.logger.info("Project ID changed after synchronization",{oldId:e,
|
|
|
71
71
|
const o=this.getContext();(0,k.registerTools)(this.server,o,this.apiClient,this.logger,this.metrics,this.tokenManager,this),this.tokenManager.setProjectId(this.getProjectId()),this.logger.info("Complete initialization finished - all tools available")}async getCurrentBranchInfo(){try{if(!this.git)return{available:!1,message:"No git repository available"}
|
|
72
72
|
const e=await y.getRepositoryStatus(this.git,this.logger,this.metrics)
|
|
73
73
|
return e.isGitRepository?{available:!0,currentBranch:e.currentBranch,isClean:e.isClean,branchCount:e.branches.length,message:`On branch ${e.currentBranch}${e.isClean?" (clean)":" (uncommitted changes)"}`}:{available:!1,message:"Not a git repository"}}catch(e){return this.logger.warn("Failed to get branch info",{error:(0,T.getErrorMessage)(e)}),{available:!1,message:"Git error: "+(0,T.getErrorMessage)(e)}}}async createSseConnection(e,t){await this.waitForInitialization(),this.cleanupSSEConnection(),this.logger.debug("Creating new SSE connection"),e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive")
|
|
74
|
-
const r=new
|
|
74
|
+
const r=new p.SSEServerTransport("/sse",e)
|
|
75
75
|
this.currentSSEConnection={transport:r,response:e}
|
|
76
|
-
try{await this.server.connect(r),this.logger.info("SSE transport connected successfully")}catch(e){this.logger.error("Error connecting SSE transport",{error:(0,T.getErrorMessage)(e)})}return r}async connectStdio(){await this.waitForInitialization(),this.logger.debug("Connecting stdio transport"),this.stdioTransport=new
|
|
76
|
+
try{await this.server.connect(r),this.logger.info("SSE transport connected successfully")}catch(e){this.logger.error("Error connecting SSE transport",{error:(0,T.getErrorMessage)(e)})}return r}async connectStdio(){await this.waitForInitialization(),this.logger.debug("Connecting stdio transport"),this.stdioTransport=new p.StdioServerTransport
|
|
77
77
|
try{await this.server.connect(this.stdioTransport),this.logger.info("STDIO transport connected successfully")}catch(e){this.logger.error("Error connecting stdio transport",{error:(0,T.getErrorMessage)(e)})}}getCurrentSSEConnection(){return this.currentSSEConnection}setCurrentSSEConnection(e){this.currentSSEConnection=e}getServer(){return this.server}getCurrentGitInstance(){if(!this.workspaceManager)return this.git||void 0
|
|
78
78
|
const e=this.workspaceManager.getCurrentContext("__server__")
|
|
79
79
|
return"multi-agent"===e.mode&&e.requestId?this.workspaceManager.getCurrentGit():this.git||void 0}getContext(){if(!this.workspaceManager)throw Error("WorkspaceManager not initialized")
|
|
@@ -112,26 +112,26 @@ default:return"\u2753"}}function s(e){switch(e){case"feature":return"\u2728"
|
|
|
112
112
|
case"bugfix":return"\u{1f41b}"
|
|
113
113
|
case"quick-edit":return"\u26a1"
|
|
114
114
|
default:return"\u{1f4e6}"}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearchRequests=async function(e,t,c,l,d){const u=l.child({tool:"search_requests"}),h=d.startTimer("tool_execution_time")
|
|
115
|
-
try{const{query:a,searchIn:l="all",filters:
|
|
115
|
+
try{const{query:a,searchIn:l="all",filters: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:
|
|
120
|
-
const m={limit:
|
|
121
|
-
|
|
117
|
+
const g=t.projectId
|
|
118
|
+
if(!g)throw new i.ValidationError("Project ID is required for searching requests")
|
|
119
|
+
u.info("Searching requests",{query:a,searchIn:l,filters:p,projectId:g})
|
|
120
|
+
const m={limit:p.limit||100,offset:p.offset||0,sortBy:"updated_at",sortDirection:"desc"}
|
|
121
|
+
p.status&&(m.status=p.status),p.type&&(m.type=p.type),p.dateFrom&&(m.dateFrom=p.dateFrom),p.dateTo&&(m.dateTo=p.dateTo),c.setProjectId(g)
|
|
122
122
|
const f=c.getRequestClient(),y=await f.listRequests(m)
|
|
123
123
|
u.debug("Fetched requests for search",{count:y.length})
|
|
124
124
|
const w=[],b=a.toLowerCase()
|
|
125
125
|
for(const e of y){const t=[]
|
|
126
126
|
if("all"!==l&&"title"!==l||!e.title||e.title.toLowerCase().includes(b)&&t.push({request:e,matchType:"title",matchSnippet:r(e.title,a)}),"all"!==l&&"description"!==l||!e.description||e.description.toLowerCase().includes(b)&&t.push({request:e,matchType:"description",matchSnippet:n(e.description,b,150)}),("all"===l||"criteria"===l)&&e.acceptanceCriteria)for(const r of e.acceptanceCriteria){const o="string"==typeof r?r:r.description
|
|
127
127
|
if(o&&o.toLowerCase().includes(b)){t.push({request:e,matchType:"criteria",matchSnippet:n(o,b,150)})
|
|
128
|
-
break}}t.length>0&&w.push(t[0])}const I=
|
|
128
|
+
break}}t.length>0&&w.push(t[0])}const I=p.limit||20,k=w.slice(0,I)
|
|
129
129
|
if(0===k.length)return h({success:!0,resultCount:0}),{content:[{type:"text",text:`No requests found matching "${a}".\n\nSearched in: ${l}\nTotal requests checked: ${y.length}`}]}
|
|
130
130
|
let v=`Found ${k.length} request${1===k.length?"":"s"} matching "${a}":\n\n`
|
|
131
131
|
for(const e of k){const t=e.request,r=o(t.status)
|
|
132
132
|
v+=`${s(t.type)} **${t.title}** (${t.id}) ${r}\n`,v+=" \u{1f4cd} Match in "+e.matchType,e.matchSnippet&&(v+=": "+e.matchSnippet),v+="\n\n"}v+=`---\nSearched ${y.length} requests (filtered by: `
|
|
133
133
|
const C=[]
|
|
134
|
-
return
|
|
134
|
+
return p.status&&C.push("status="+p.status),p.type&&C.push("type="+p.type),p.dateFrom&&C.push("from="+p.dateFrom),p.dateTo&&C.push("to="+p.dateTo),v+=C.length>0?C.join(", "):"none",v+=")",h({success:!0,resultCount:k.length}),d.incrementCounter("search_requests_success",1),{content:[{type:"text",text:v}]}}catch(e){return u.error("Search requests failed",{error:e instanceof Error?e.stack:e+""}),h({success:!1,error:(0,a.getErrorMessage)(e)}),d.incrementCounter("search_requests_errors",1),{content:[{type:"text",text:"\u274c **Search Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
135
135
|
const i=t(9860),a=t(8824)},260(e,exports,t){"use strict"
|
|
136
136
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
137
137
|
const r=t(6183),n=t(4221)
|
|
@@ -165,14 +165,14 @@ default:t="open"}else t="open"
|
|
|
165
165
|
const n=Array.isArray(e.acceptanceCriteria)?e.acceptanceCriteria.map(r):[]
|
|
166
166
|
return{id:e.id,title:e.title,description:e.description,type:e.type,status:t,acceptanceCriteria:n,createdAt:e.createdAt,updatedAt:e.updatedAt,...e.projectId?{projectId:e.projectId}:{},...e.completionSummary?{completionSummary:e.completionSummary}:{},...e.skippedTestRunId?{skippedTestRunId:e.skippedTestRunId}:{},...e.completedAt?{completedAt:e.completedAt}:{},...e.metadata?{metadata:e.metadata}:{},...e.lockInfo?{lockInfo:e.lockInfo}:{}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.adaptApiAcceptanceCriterionToDomain=r,exports.adaptApiRequestToDomain=n,exports.adaptApiRequestsToDomain=function(e){return e.map(n)}
|
|
167
167
|
const o=t(6756)},405(e,exports,t){"use strict"
|
|
168
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlanWrite=async function(e,t,l,d,u,h,
|
|
168
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlanWrite=async function(e,t,l,d,u,h,p){const g=d.child({tool:"plan_write"})
|
|
169
169
|
try{const a=e,{operation:d,planId:m}=a
|
|
170
|
-
switch(
|
|
170
|
+
switch(g.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,g,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:m,content:a.content,name:a.name,metadata:{criteria:a.criteria,tickIntervalSeconds:a.tickIntervalSeconds,maxInFlight:a.maxInFlight,maxPerDay:a.maxPerDay,minIterations:a.minIterations,status:a.status}},t,l,
|
|
174
|
-
return u.incrementCounter("plan_write_total",1,{operation:"update",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-update")}case"append":{const e=await(0,n.handleAppendPlan)({planId:m,content:a.content,name:a.name},l,
|
|
175
|
-
return u.incrementCounter("plan_write_total",1,{operation:"append",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-append")}case"replace":{const e=await(0,o.handleReplacePlan)({planId:m,old:a.old,new:a.new,name:a.name},l,
|
|
173
|
+
return(0,c.withAlchemyKind)(e,i.KIND_META[r].alchemyKind)}case"update":{const e=await(0,r.handleUpdatePlan)({planId:m,content:a.content,name:a.name,metadata:{criteria:a.criteria,tickIntervalSeconds:a.tickIntervalSeconds,maxInFlight:a.maxInFlight,maxPerDay:a.maxPerDay,minIterations:a.minIterations,status:a.status}},t,l,g,u)
|
|
174
|
+
return u.incrementCounter("plan_write_total",1,{operation:"update",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-update")}case"append":{const e=await(0,n.handleAppendPlan)({planId:m,content:a.content,name:a.name},l,g,u)
|
|
175
|
+
return u.incrementCounter("plan_write_total",1,{operation:"append",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-append")}case"replace":{const e=await(0,o.handleReplacePlan)({planId:m,old:a.old,new:a.new,name:a.name},l,g,u)
|
|
176
176
|
return u.incrementCounter("plan_write_total",1,{operation:"replace",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-replace")}case"create-snapshot":{const{versionLabel:e,changeSummary:t}=a,r=l.getDocumentClient(),n=await r.createVersionSnapshot(m,e,t)
|
|
177
177
|
return u.incrementCounter("plan_write_total",1,{operation:"create-snapshot",success:!0}),(0,c.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Plan Snapshot Created**\n\n**Plan:** ${m}\n**Version:** ${n.versionNumber}\n**Label:** ${e||"None"}\n**Summary:** ${t||"None"}\n**Created:** `+new Date(n.createdAt).toLocaleString()}]},"plan-snapshot")}case"restore":{const{versionNumber:e}=a,t=l.getDocumentClient(),r=await t.restoreToVersion(m,e)
|
|
178
178
|
return u.incrementCounter("plan_write_total",1,{operation:"restore",success:!0}),(0,c.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Plan Restored**\n\n**Plan:** ${m}\n**Restored to Version:** ${e}\n**Filename:** ${r.filename}\n\nThe plan has been successfully restored to version ${e}.`}]},"plan-restore")}case"set-active":{const e=t.projectId
|
|
@@ -183,7 +183,7 @@ if("Plan"!==n.type)return{content:[{type:"text",text:`\u274c Document ${m} is no
|
|
|
183
183
|
const o=l.getProjectClient()
|
|
184
184
|
await o.updateProject(e,{activePlanId:m}),u.incrementCounter("plan_write_total",1,{operation:"set-active",success:!0})
|
|
185
185
|
const s=n.localId||n.id
|
|
186
|
-
return(0,c.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Active Plan Updated**\n\n**Plan:** ${s}\n**Filename:** ${n.filename}\n**Project:** ${e}\n\nThis plan is now the active project plan.`}]},"plan-set-active")}default:throw Error("Unknown plan_write operation: "+d)}}catch(e){return
|
|
186
|
+
return(0,c.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Active Plan Updated**\n\n**Plan:** ${s}\n**Filename:** ${n.filename}\n**Project:** ${e}\n\nThis plan is now the active project plan.`}]},"plan-set-active")}default:throw Error("Unknown plan_write operation: "+d)}}catch(e){return g.error("plan_write failed",{error:e instanceof Error?e.stack:e+""}),u.incrementCounter("plan_write_errors",1),{content:[{type:"text",text:"\u274c **Plan Write Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
187
187
|
const r=t(7609),n=t(4419),o=t(2352),s=t(6656),i=t(3416),a=t(8824),c=t(2272)},441(e,exports){"use strict"
|
|
188
188
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.BAD_REQUEST=exports.INTERNAL_ERROR=exports.NOT_FOUND=exports.FORBIDDEN=exports.UNAUTHORIZED=exports.VALIDATION_ERROR=exports.MCP_PROTOCOL_ERROR=exports.REQUEST_VALIDATION_FAILED=exports.REQUEST_ID_INVALID_FORMAT=exports.REQUEST_NOT_FOUND=exports.CONNECTION_ERROR=exports.SERVICE_UNAVAILABLE=exports.CONNECTION_TIMEOUT=exports.SERVER_ERROR=exports.NETWORK_ERROR=exports.TASK_VALIDATION_FAILED=exports.TASK_ID_INVALID_FORMAT=exports.TASK_NOT_FOUND=void 0,exports.TASK_NOT_FOUND="TASK_NOT_FOUND",exports.TASK_ID_INVALID_FORMAT="TASK_ID_INVALID_FORMAT",exports.TASK_VALIDATION_FAILED="TASK_VALIDATION_FAILED",exports.NETWORK_ERROR="NETWORK_ERROR",exports.SERVER_ERROR="SERVER_ERROR",exports.CONNECTION_TIMEOUT="CONNECTION_TIMEOUT",exports.SERVICE_UNAVAILABLE="SERVICE_UNAVAILABLE",exports.CONNECTION_ERROR="CONNECTION_ERROR",exports.REQUEST_NOT_FOUND="REQUEST_NOT_FOUND",exports.REQUEST_ID_INVALID_FORMAT="REQUEST_ID_INVALID_FORMAT",exports.REQUEST_VALIDATION_FAILED="REQUEST_VALIDATION_FAILED",exports.MCP_PROTOCOL_ERROR="MCP_PROTOCOL_ERROR",exports.VALIDATION_ERROR="VALIDATION_ERROR",exports.UNAUTHORIZED="UNAUTHORIZED",exports.FORBIDDEN="FORBIDDEN",exports.NOT_FOUND="NOT_FOUND",exports.INTERNAL_ERROR="INTERNAL_ERROR",exports.BAD_REQUEST="BAD_REQUEST"},509(e,exports,t){"use strict"
|
|
189
189
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
@@ -250,24 +250,24 @@ if(t.response&&"object"==typeof t.response&&"number"==typeof t.response.status)r
|
|
|
250
250
|
if("string"==typeof t.message){const e=t.message.match(/status (\d+)/i)
|
|
251
251
|
if(e&&e[1]){const t=parseInt(e[1],10)
|
|
252
252
|
if(!isNaN(t))return t}}return null}}exports.ToolRecordClient=i},1020(e,exports,t){"use strict"
|
|
253
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQueryHistory=async function(e,c,l,d,u,h){const
|
|
254
|
-
try{const a=e,{queryType:
|
|
253
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQueryHistory=async function(e,c,l,d,u,h){const p=d.child({tool:"query_history"})
|
|
254
|
+
try{const a=e,{queryType:g}=a
|
|
255
255
|
let m
|
|
256
|
-
switch(
|
|
256
|
+
switch(p.info("Processing query_history request",{queryType:g}),g){case"file-history":p.info("Routing to file-history handler",{path:a.fileHistory.path}),m=await(0,r.handleFileHistory)({path:a.fileHistory.path,limit:a.fileHistory.limit,showDiff:a.fileHistory.showDiff,showTraceability:a.fileHistory.showTraceability,branch:a.fileHistory.branch,since:a.fileHistory.since},c,l,p,u)
|
|
257
257
|
break
|
|
258
|
-
case"request-file-history":
|
|
258
|
+
case"request-file-history":p.info("Routing to request-file-history handler",{requestId:a.requestHistory.requestId}),m=await(0,n.handleRequestFileHistory)({requestId:a.requestHistory.requestId,showDiff:a.requestHistory.showDiff,detailLevel:a.requestHistory.detailLevel,taskId:a.requestHistory.taskId,fileFilter:a.requestHistory.fileFilter},c,l,p,u)
|
|
259
259
|
break
|
|
260
|
-
case"recover":
|
|
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
|
-
|
|
266
|
-
return await e(c,l,d)||"untracked"})(),path:a.recover.path,commitHash:s,createBackup:a.recover.createBackup},c,l,l.getToolRecordClient(),
|
|
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}}}m=await(0,o.handleFileRecover)({taskId:e.recover?.taskId||await(async()=>{const{resolveActiveTaskId:e}=await Promise.resolve().then(t.bind(t,3451))
|
|
266
|
+
return await e(c,l,d)||"untracked"})(),path:a.recover.path,commitHash:s,createBackup:a.recover.createBackup},c,l,l.getToolRecordClient(),p,u,h)
|
|
267
267
|
break
|
|
268
|
-
case"blame":
|
|
268
|
+
case"blame":p.info("Routing to file-blame handler",{path:a.blame.path,lines:a.blame.lines}),m=await(0,i.handleFileBlame)({path:a.blame.path,lines:a.blame.lines,branch:a.blame.branch},c,l,p,u)
|
|
269
269
|
break
|
|
270
|
-
default:throw Error("Unknown query type: "+
|
|
270
|
+
default:throw Error("Unknown query type: "+g)}return p.info("query_history request completed",{queryType:g,success:!m.isError}),u.incrementCounter("query_history_total",1,{success:!m.isError,queryType:g}),(0,s.withAlchemyKind)(m,"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)
|
|
@@ -343,7 +343,7 @@ j.registerClient(F)
|
|
|
343
343
|
const N=new S.ToolRecordClient(q,n.child({component:"tool-record-client"}),o,M,R,x)
|
|
344
344
|
j.registerClient(N)
|
|
345
345
|
const z=new T.ApiClient(P,M,O,$,A,F,N,D,n.child({component:"api-client"})),L=a.default.Router();(0,h.registerAuthRoutes)(L,{projectClient:M,taskClient:O,fileClient:$,authManager:P,apiClient:z},i,n)
|
|
346
|
-
const H=r.getContext();(0,
|
|
346
|
+
const H=r.getContext();(0,p.registerConfigRoutes)(L,n,H.basePath),e.use("/api",L)
|
|
347
347
|
const B=e=>{const t=o.startTimer(e)
|
|
348
348
|
return e=>t(e)},U=(e,t,n)=>{const o=e.query.path||e.body.path
|
|
349
349
|
if(!o)return t.status(400).json({success:!1,error:"Path parameter is required"})
|
|
@@ -381,7 +381,7 @@ const l=await(0,m.handleWriteFile)({taskId:a,path:e.relativePath,content:i,forma
|
|
|
381
381
|
s({endpoint:"files/write",method:"POST",success:!0}),t.json({success:!0,data:l})}catch(e){s(e)}})),e.post("/api/files/replace",U,G,(async(e,t,s)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/replace",method:"POST"})
|
|
382
382
|
const s=B("api_request_duration"),{replacements:i,mode:a="unique",taskId:c}=e.body
|
|
383
383
|
if(!i||!Array.isArray(i))throw(0,u.createValidationError)("Replacements array is required")
|
|
384
|
-
const l=await(0,
|
|
384
|
+
const l=await(0,g.handleReplaceStrings)({taskId:c,operations:[{path:e.relativePath,replacements:i,mode:a}],comment:"String replacement via API"},r.getContext(),O,N,A,n,o)
|
|
385
385
|
s({endpoint:"files/replace",method:"POST",success:!0}),t.json({success:!0,data:l})}catch(e){s(e)}})),e.delete("/api/files/delete",U,G,(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/delete",method:"DELETE"})
|
|
386
386
|
const r=B("api_request_duration"),{taskId:n}=e.body
|
|
387
387
|
try{await l.default.access(e.fullPath)}catch(t){throw r({endpoint:"files/delete",method:"DELETE",success:!1,error:"not_found"}),(0,u.createNotFoundError)("File not found: "+e.relativePath)}await l.default.unlink(e.fullPath),r({endpoint:"files/delete",method:"DELETE",success:!0}),t.json({success:!0,data:{path:e.relativePath,deleted:!0}})}catch(e){r(e)}})),e.post("/api/directories/create",U,G,(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"directories/create",method:"POST"})
|
|
@@ -418,7 +418,7 @@ throw e}}catch(e){r(e)}})),e.patch("/api/proxy/*",G,(async(e,t,r)=>{try{const r=
|
|
|
418
418
|
try{const n=await z.proxyPatch(r,e.body)
|
|
419
419
|
t.json(n)}catch(e){if(e instanceof Error&&e.message.includes("ECONNREFUSED"))return t.status(503).json({success:!1,error:"Remote server is unreachable",remotePath:r})
|
|
420
420
|
throw e}}catch(e){r(e)}}))}
|
|
421
|
-
const a=i(t(7252)),c=i(t(6928)),l=i(t(1943)),d=t(3444),u=t(9860),h=t(6776),
|
|
421
|
+
const a=i(t(7252)),c=i(t(6928)),l=i(t(1943)),d=t(3444),u=t(9860),h=t(6776),p=t(6476),g=t(3306),m=t(4079),f=t(3895),y=s(t(5967)),w=t(4710),b=t(5681),I=t(8824),k=t(2968),v=t(6153),C=t(1887),_=t(1666),E=t(9884),S=t(922),T=t(3328)},1253(e,exports,t){"use strict"
|
|
422
422
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
423
423
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.TokenManager=void 0
|
|
424
424
|
const n=r(t(6928)),o=r(t(1943)),s=r(t(6982)),i=r(t(857)),a=t(9067),c=t(8824),l="alchemy-lab"
|
|
@@ -483,10 +483,10 @@ const r=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Co
|
|
|
483
483
|
if(r.ok){const e=await r.json()
|
|
484
484
|
return this.logger.info("Token validation successful",{status:e.status||"unknown",username:e.username||"unknown"}),!0}return this.logger.info("Token validation failed - token may be invalid or expired",{status:r.status,statusText:r.statusText}),this.invalidateCache(),!1}catch(e){return e instanceof Error&&"AbortError"===e.name?(this.logger.info("Token validation request timed out - assuming offline or server unavailable"),!0):(this.logger.info("Token validation request failed",{error:(0,c.getErrorMessage)(e)}),!0)}}async hasValidAndWorkingToken(){return!!await this.hasValidToken()&&await this.validateTokenWithRemoteServer()}async isGoogleOAuthAvailable(){return await this.authFlow.isGoogleOAuthAvailable()}async startGoogleOAuthFlow(){return await this.authFlow.startGoogleOAuthFlow()}async startGoogleOAuthPolling(e,t,r,n,o){return await this.authFlow.startGoogleOAuthPolling(e,t,r,n,o)}}},1266(e,exports){"use strict"
|
|
485
485
|
Object.defineProperty(exports,"__esModule",{value:!0})},1281(e,exports,t){"use strict"
|
|
486
|
-
async function r(e,t,o,s,i,a,c,l,d,u=0){let
|
|
486
|
+
async function r(e,t,o,s,i,a,c,l,d,u=0){let g=0,m=0,f=0
|
|
487
487
|
const y=[]
|
|
488
|
-
if(o.length>=v||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:v,depth:c}),{filesCount:
|
|
489
|
-
try{const w=await
|
|
488
|
+
if(o.length>=v||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:v,depth:c}),{filesCount:g,fileMatchesCount:m,subdirCount:f,subdirStats:y}
|
|
489
|
+
try{const w=await p.default.readdir(e,{withFileTypes:!0}),b=[],C=[]
|
|
490
490
|
for(const t of w){const r=h.default.join(e,t.name)
|
|
491
491
|
if(t.isDirectory()){if(k.includes(t.name)||t.name.startsWith(".")){a.debug("Skipping excluded directory: "+t.name)
|
|
492
492
|
continue}C.push({entry:t,fullPath:r})}else if(t.isFile()){if("*"!==i&&!t.name.endsWith(i)){a.debug("Skipping file due to extension mismatch",{filename:t.name,requiredExtension:i})
|
|
@@ -494,19 +494,19 @@ continue}b.push({entry:t,fullPath:r})}}if(b.length>0){const e=[]
|
|
|
494
494
|
for(let t=0;t<b.length;t+=16)e.push(b.slice(t,t+16))
|
|
495
495
|
for(const r of e){if(o.length>=v)break
|
|
496
496
|
const e=await Promise.all(r.map((({entry:e,fullPath:r})=>n(r,t,0,o,l,d,e.name,u))))
|
|
497
|
-
for(const t of e){
|
|
498
|
-
for(const e of t.matches){if(o.length>=v)return{filesCount:
|
|
497
|
+
for(const t of e){g++,t.hasMatches&&m++
|
|
498
|
+
for(const e of t.matches){if(o.length>=v)return{filesCount:g,fileMatchesCount:m,subdirCount:f,subdirStats:y}
|
|
499
499
|
o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=v)break
|
|
500
500
|
f++
|
|
501
501
|
const e={path:n,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
502
502
|
try{const l=await r(n,t,o,s,i,a,c+1,e,d,u)
|
|
503
|
-
|
|
503
|
+
g+=l.filesCount,m+=l.fileMatchesCount,e.filesProcessed=l.filesCount,e.filesMatched=l.fileMatchesCount,e.subdirectories=l.subdirCount,y.push(e),l.subdirStats&&l.subdirStats.length>0&&y.push(...l.subdirStats)}catch(t){const r=`Error processing subdirectory ${n}: ${(0,I.getErrorMessage)(t)}`
|
|
504
504
|
e.errors.push(r),y.push(e),a.error(r)}}}catch(t){const r=`Error searching directory ${e}: ${(0,I.getErrorMessage)(t)}`
|
|
505
|
-
l.errors.push(r),a.warn(r)}return{filesCount:
|
|
505
|
+
l.errors.push(r),a.warn(r)}return{filesCount:g,fileMatchesCount:m,subdirCount:f,subdirStats:y}}async function n(e,t,r,n,o,s,i,a=0){const c=[]
|
|
506
506
|
let l,d=!1
|
|
507
|
-
const u=async()=>{if(void 0===l)try{const t=await
|
|
507
|
+
const u=async()=>{if(void 0===l)try{const t=await p.default.stat(e)
|
|
508
508
|
l=t.mtime.getTime()}catch(e){l=void 0}return l}
|
|
509
|
-
if("filename"!==s&&"both"!==s||t.test(i)&&(d=!0,await u(),c.push({file:e,line:0,text:i,modifiedTime:l,matchType:"filename"})),"content"===s||"both"===s)try{const r=(await
|
|
509
|
+
if("filename"!==s&&"both"!==s||t.test(i)&&(d=!0,await u(),c.push({file:e,line:0,text:i,modifiedTime:l,matchType:"filename"})),"content"===s||"both"===s)try{const r=(await p.default.readFile(e,"utf8")).split("\n")
|
|
510
510
|
for(let o=0;o<r.length&&n.length<v;o++)if(t.test(r[o])){d=!0,await u()
|
|
511
511
|
const t={file:e,line:o+1,text:(0,y.truncate)(r[o].trim(),120),modifiedTime:l,matchType:"content"}
|
|
512
512
|
if(a>0){const e=Math.max(0,o-a)
|
|
@@ -522,10 +522,10 @@ for(let t=0;t<Math.min(e,n.contextAfter.length);t++)i.push({lineNumber:s+t,conte
|
|
|
522
522
|
for(let t=Math.max(s,e)-e;t<r.contextBefore.length;t++){const n=e+t
|
|
523
523
|
s>n||n>a||i.some((e=>e.lineNumber===n))||i.push({lineNumber:n,content:r.contextBefore[t],isMatch:!1})}}}}i.push({lineNumber:r.line,content:r.text,isMatch:!0})}if(n.contextAfter&&n.contextAfter.length>0){const e=n.line+1
|
|
524
524
|
n.contextAfter.forEach(((t,r)=>{i.push({lineNumber:e+r,content:t,isMatch:!1})}))}const a=Array.from(new Map(i.map((e=>[e.lineNumber,e]))).values()).sort(((e,t)=>e.lineNumber-t.lineNumber))
|
|
525
|
-
return{file:r.file,relativePath:r.relativePath||r.file,startLine:o,endLine:s,lines:a}}async function i(e){try{const t=await
|
|
525
|
+
return{file:r.file,relativePath:r.relativePath||r.file,startLine:o,endLine:s,lines:a}}async function i(e){try{const t=await p.default.stat(e),r=h.default.extname(e).toLowerCase()
|
|
526
526
|
if(!C.has(r))return
|
|
527
527
|
if(t.size>_)return
|
|
528
|
-
return 0===t.size?0:(await
|
|
528
|
+
return 0===t.size?0:(await p.default.readFile(e,"utf-8")).split("\n").length}catch{return}}var a,c=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
529
529
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
530
530
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),l=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),d=this&&this.__importStar||(a=function(e){return a=Object.getOwnPropertyNames||function(e){var t=[]
|
|
531
531
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -535,16 +535,16 @@ if(null!=e)for(var r=a(e),n=0;n<r.length;n++)"default"!==r[n]&&c(t,e,r[n])
|
|
|
535
535
|
return l(t,e),t}),u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
536
536
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearch=async function(e,t,n,a,c){const l=a.child({tool:"search"}),d=c.startTimer("tool_execution_time"),u=Date.now()
|
|
537
537
|
let k=0
|
|
538
|
-
const v={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:
|
|
539
|
-
try{const{needle:n,directory:
|
|
540
|
-
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,b.handleListDirectory)({path:
|
|
538
|
+
const v={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:g.default.hostname(),username:g.default.userInfo().username,workingDirectory:process.cwd(),contextBasePath:t?.basePath||"unknown"},startTime:u,endTime:0,phases:{initializationTime:0,searchTime:0,directoryListingTime:0},totalFiles:0,totalMatches:0,directoryStats:[],errors:[]}
|
|
539
|
+
try{const{needle:n,directory:g,options:C={}}=e
|
|
540
|
+
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,b.handleListDirectory)({path:g||".",levels:C.levels||1,sortBy:C.sortBy||"name"},t,a,c)
|
|
541
541
|
if("string"!=typeof n)throw v.errors.push("Search term (needle) must be a string"),(0,m.createValidationError)("Search term (needle) must be a string")
|
|
542
542
|
let _
|
|
543
|
-
if(v.searchDirectory=
|
|
543
|
+
if(v.searchDirectory=g||".",g){const{normalizedPath:e,fullPath:r}=f.validateAndNormalizePath(g,t)
|
|
544
544
|
_=r}else _=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath
|
|
545
545
|
v.resolvedPath=_
|
|
546
546
|
let E=!1
|
|
547
|
-
try{E=(await
|
|
547
|
+
try{E=(await p.default.stat(_)).isFile()}catch(e){const t=`Cannot access path ${_}: ${(0,I.getErrorMessage)(e)}`
|
|
548
548
|
throw v.errors.push(t),Error(t)}const S=C.maxResults||50,T=C.caseSensitive||!1,q=C.useRegex||!1,P=C.fileExtension,j=C.searchIn||"content"
|
|
549
549
|
let R=void 0!==C.contextLines?C.contextLines:0
|
|
550
550
|
if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!E&&!P)throw v.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,m.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
|
|
@@ -552,19 +552,19 @@ let x,M=""
|
|
|
552
552
|
if(E)M="*"
|
|
553
553
|
else if("*"===P)M="*"
|
|
554
554
|
else if(P){let e=P;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),M=e.startsWith(".")?e:"."+e}try{x=q?T?RegExp(n):RegExp(n,"i"):T?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${q?"regex":"search"} pattern: ${(0,I.getErrorMessage)(e)}`
|
|
555
|
-
throw v.errors.push(t),(0,m.createValidationError)(t)}if(v.patternInfo={needle:n,regex:x.toString(),caseSensitive:T,fileExtension:P,normalizedExtension:M},!E)try{const e=Date.now(),t=await
|
|
555
|
+
throw v.errors.push(t),(0,m.createValidationError)(t)}if(v.patternInfo={needle:n,regex:x.toString(),caseSensitive:T,fileExtension:P,normalizedExtension:M},!E)try{const e=Date.now(),t=await p.default.readdir(_,{withFileTypes:!0}),r=[],n=[]
|
|
556
556
|
for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
|
|
557
557
|
v.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},v.phases.directoryListingTime=v.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,I.getErrorMessage)(e)
|
|
558
558
|
v.errors.push(t),l.error(t)}const O=E?"file":"directory"
|
|
559
559
|
l.info(`Searching for "${n}" in ${O} ${_} (mode: ${j})`,{needle:n,searchTarget:O,path:_,options:{maxResults:S,caseSensitive:T,fileExtension:M,searchIn:j}}),k=Date.now(),v.phases.initializationTime=k-u
|
|
560
560
|
const $=Date.now()
|
|
561
561
|
let D=[],A=0,F=0
|
|
562
|
-
try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,
|
|
562
|
+
try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,g=[]
|
|
563
563
|
if(s.info("performLocalSearch started",{searchPath:e,pattern:t.toString(),options:n}),d)return await async function(e,t,r,n,o,s=0){const i=[],a=h.default.basename(e)
|
|
564
564
|
let c
|
|
565
565
|
n.info("Searching single file: "+e,{searchIn:r})
|
|
566
|
-
try{c=(await
|
|
567
|
-
return o.errors.push(r),n.error(r),{matches:i,totalFiles:0}}if("filename"!==r&&"both"!==r||t.test(a)&&(i.push({file:e,line:0,text:a,modifiedTime:c,matchType:"filename"}),n.info("Filename match found: "+a)),"content"===r||"both"===r)try{const r=(await
|
|
566
|
+
try{c=(await p.default.stat(e)).mtime.getTime()}catch(t){const r=`Cannot access file ${e}: ${(0,I.getErrorMessage)(t)}`
|
|
567
|
+
return o.errors.push(r),n.error(r),{matches:i,totalFiles:0}}if("filename"!==r&&"both"!==r||t.test(a)&&(i.push({file:e,line:0,text:a,modifiedTime:c,matchType:"filename"}),n.info("Filename match found: "+a)),"content"===r||"both"===r)try{const r=(await p.default.readFile(e,"utf8")).split("\n")
|
|
568
568
|
for(let n=0;n<r.length;n++)if(t.test(r[n])){const t={file:e,line:n+1,text:(0,y.truncate)(r[n].trim(),120),modifiedTime:c,matchType:"content"}
|
|
569
569
|
if(s>0){const e=Math.max(0,n-s)
|
|
570
570
|
t.contextBefore=r.slice(e,n).map((e=>(0,y.truncate)(e.trim(),120)))
|
|
@@ -572,9 +572,9 @@ const o=Math.min(r.length,n+1+s)
|
|
|
572
572
|
t.contextAfter=r.slice(n+1,o).map((e=>(0,y.truncate)(e.trim(),120)))}i.push(t)}n.info(`Found ${i.filter((e=>"content"===e.matchType)).length} content matches`)}catch(t){const r=`Error reading file ${e}: ${(0,I.getErrorMessage)(t)}`
|
|
573
573
|
o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
|
|
574
574
|
const m={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
575
|
-
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,
|
|
576
|
-
return m.filesProcessed=n,m.filesMatched=c,m.subdirectories=d,i.directoryStats.push(m),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:
|
|
577
|
-
return m.errors.push(r),i.directoryStats.push(m),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:
|
|
575
|
+
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,g,a,o,s,0,m,l,u)
|
|
576
|
+
return m.filesProcessed=n,m.filesMatched=c,m.subdirectories=d,i.directoryStats.push(m),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:g.length,directories:d+1}),{matches:g,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,I.getErrorMessage)(t)
|
|
577
|
+
return m.errors.push(r),i.directoryStats.push(m),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:g,totalFiles:m.filesProcessed}}}(_,x,{maxResults:S,fileExtension:M,searchIn:j,isFile:E,contextLines:R},M,l,v)
|
|
578
578
|
D=e.matches,A=e.totalFiles
|
|
579
579
|
const t=1e3
|
|
580
580
|
D.length>0&&D.length<=t?(D.sort(((e,t)=>void 0!==e.modifiedTime&&void 0!==t.modifiedTime?t.modifiedTime-e.modifiedTime:void 0!==e.modifiedTime&&void 0===t.modifiedTime?-1:void 0===e.modifiedTime&&void 0!==t.modifiedTime?1:0)),l.info(`Sorted ${D.length} matches by modification time (newest first)`)):D.length>t&&l.info(`Skipped sorting ${D.length} matches (exceeds hard cap of ${t} for performance)`),F=D.length,D.length>S&&(D=D.slice(0,S),l.info(`Limited results to ${S} (from ${F} total matches)`)),D.forEach((e=>{e.relativePath=function(e,t){const r=h.default.relative(e,t)
|
|
@@ -584,7 +584,7 @@ let N,z=""
|
|
|
584
584
|
try{if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
585
585
|
e.branchName&&!e.permanentBranch&&(z=e.isMainBranch?` (searched on main branch: ${e.branchName})`:` (searched on request branch: ${e.branchName}${e.requestId?" for "+e.requestId:""})`)}}catch(e){l.debug("Could not get branch context",{error:e}),z=" (branch context unavailable)"}l.debug("Search diagnostic information",{diagnostic:v})
|
|
586
586
|
const L="content"===j?"content":"filename"===j?"filenames":"content and filenames"
|
|
587
|
-
if(F>D.length?(N=`Found ${F} results for "${n}" (searching ${L})`,
|
|
587
|
+
if(F>D.length?(N=`Found ${F} results for "${n}" (searching ${L})`,g&&(N+=" in "+g),P&&(N+=" with extension "+P),N+=`${z}. Showing first ${D.length}:\n\n`):(N=`Found ${D.length} results for "${n}" (searching ${L})`,g&&(N+=" in "+g),P&&(N+=" with extension "+P),N+=z+":\n\n"),D.length>0)if(R>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
|
|
588
588
|
if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
|
|
589
589
|
const o=new Map
|
|
590
590
|
for(const e of n){const t=o.get(e.file)||[]
|
|
@@ -608,7 +608,7 @@ else N+="No matches found."
|
|
|
608
608
|
return d({success:!0}),{content:[{type:"text",text:N}],...(0,w.alchemyMeta)({kind:"search"})}}catch(t){l.error("Search failed",{args:e,error:t instanceof Error?t.stack:t+""}),v.errors.push((0,I.getErrorMessage)(t)),v.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:v})
|
|
609
609
|
let r="Search failed: "+(0,I.getErrorMessage)(t)
|
|
610
610
|
return d({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:r}],isError:!0}}}
|
|
611
|
-
const h=u(t(6928)),
|
|
611
|
+
const h=u(t(6928)),p=u(t(1943)),g=u(t(857)),m=t(9860),f=d(t(5967)),y=t(5967),w=t(2272),b=t(2537),I=t(8824),k=["node_modules"],v=1e4,C=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore"]),_=1048576},1318(e,exports,t){"use strict"
|
|
612
612
|
async function r(e,t,r){try{const r=(await e.revparse(["--show-toplevel"])).trim(),n=c.default.isAbsolute(t)?t:c.default.resolve(t)
|
|
613
613
|
return c.default.relative(r,n)}catch(e){return r.warn("Failed to get repo-relative path, using original",{filePath:t,error:(0,l.getErrorMessage)(e)}),t}}function n(e){return/\(trec\d{6}\)/.test(e)}async function o(e,t,n,o,s){try{const i=await r(e,t,s),a=await e.raw(["log","-1","--pretty=format:%H|%s",`-L${n},${o}:${i}`])
|
|
614
614
|
if(!a||""===a.trim())return null
|
|
@@ -626,12 +626,12 @@ for(const e of r){const r=e.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/)
|
|
|
626
626
|
if(r){const e=parseInt(r[3],10),n=r[4]?parseInt(r[4],10):1,o=e+n-1
|
|
627
627
|
n>0&&t.push({start:e,end:o})}}return t}(s)
|
|
628
628
|
return{ranges:i,diff:s}}catch(e){return n.warn("Failed to get uncommitted changes",{filePath:t,error:(0,l.getErrorMessage)(e)}),{ranges:[],diff:""}}}(e,t.path,i),d=c.ranges,u=c.diff,h=await async function(e,t,n){try{const o=await r(e,t,n),s=await e.log({file:o,maxCount:1})
|
|
629
|
-
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),
|
|
629
|
+
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),p=!!h&&n(h),g=t.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),m=d.map((e=>`${e.start}-${e.end}`)).join(", ")||"none",f=u?u.substring(0,300):"no diff"
|
|
630
630
|
if(0===d.length){const r=[]
|
|
631
631
|
for(const s of t.lineRanges){const a=await o(e,t.path,s.start,s.end,i)
|
|
632
|
-
a&&(n(a.message)||r.push({range:`${s.start}-${s.end}`,commit:a}))}if(r.length>0){const e=r.map((e=>`Lines ${e.range}: ${e.commit.hash.substring(0,8)} - ${e.commit.message}`)).join("; "),n=[`\u26a0\ufe0f Warning: Lines ${
|
|
633
|
-
return{hasExternalEdits:!0,conflictingLines:t.lineRanges.flatMap((e=>Array.from({length:e.end-e.start+1},((t,r)=>e.start+r)))),message:n,debugInfo:{detectionRan:!0,affectedRegion:
|
|
634
|
-
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:
|
|
632
|
+
a&&(n(a.message)||r.push({range:`${s.start}-${s.end}`,commit:a}))}if(r.length>0){const e=r.map((e=>`Lines ${e.range}: ${e.commit.hash.substring(0,8)} - ${e.commit.message}`)).join("; "),n=[`\u26a0\ufe0f Warning: Lines ${g} were last modified by external commits (not alchemy).`,"","Commit details: "+e,"\nThese changes may have been made manually or by another tool.\nReview recent commits before proceeding."].join("\n")
|
|
633
|
+
return{hasExternalEdits:!0,conflictingLines:t.lineRanges.flatMap((e=>Array.from({length:e.end-e.start+1},((t,r)=>e.start+r)))),message:n,debugInfo:{detectionRan:!0,affectedRegion:g,uncommittedChanges:"none",lastCommit:r[0].commit.message,wasLastCommitAlchemy:!1,diffPreview:e,overlapDetected:!0}}}return{hasExternalEdits:!1,conflictingLines:[],debugInfo:{detectionRan:!0,affectedRegion:g,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)
|
|
634
|
+
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:g,uncommittedChanges:m,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: "+g,"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:g,uncommittedChanges:m,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}}
|
|
635
635
|
const a=t(9947),c=i(t(6928)),l=t(8824)},1387(e,exports,t){"use strict"
|
|
636
636
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.WorkspaceRequestProcessor=void 0
|
|
637
637
|
const r=t(7075),n=t(5964),o=t(8824)
|
|
@@ -688,11 +688,11 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
688
688
|
var t={}
|
|
689
689
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
690
690
|
return i(t,e),t})
|
|
691
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentity=void 0,exports.registerTools=function(e,o,s,i,a,
|
|
691
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentity=void 0,exports.registerTools=function(e,o,s,i,a,g,I){const k=i.child({component:"tools"})
|
|
692
692
|
k.info("Registering tools...")
|
|
693
693
|
let v=!1
|
|
694
|
-
const C=!!
|
|
695
|
-
try{return await
|
|
694
|
+
const C=!!g,_=async()=>{if(!C)return!0
|
|
695
|
+
try{return await g.hasValidToken()}catch(e){return k.error("Error checking authentication status",{error:(0,d.getErrorMessage)(e)}),!1}},E=async()=>{const e=(0,l.areTestsRequiredForCompletion)(),t=await _()
|
|
696
696
|
k.info(`Generating tools list with testsRequired=${e}, authenticated=${t}`)
|
|
697
697
|
const r={testsRequired:e,authenticated:t}
|
|
698
698
|
return(0,f.generateVisibleToolsList)(r)}
|
|
@@ -708,7 +708,7 @@ let P
|
|
|
708
708
|
if(T=Date.now(),s?(s.setOptions({createRecords:q?.createsRecords??!1}),k.info(`Setting record creation for tool ${n}: ${q?.createsRecords??!1}`)):k.debug(`No API client available for tool ${n} (minimal mode)`),Date.now(),Date.now(),T=Date.now(),E?.sessionId){const e=E.sessionId,t=E.messageId,r=h.sessionIdentity.getIdentity()
|
|
709
709
|
if(r)r.sessionId!==e&&((0,m.logSessionIdentity)(n,"_meta-session-switch",{prevSessionId:r.sessionId,prevAgentType:r.agentType,newSessionId:e}),h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r.serverUrl}),o?.workspaceManager?.resetCurrentContext?.(e))
|
|
710
710
|
else{const t=await(0,u.getServerUrl)(o,k)
|
|
711
|
-
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}P={providerId:"opencode",sessionId:e,messageId:t,createdAt:(new Date).toISOString()},(0,m.logSessionIdentity)(n,"_meta",{sessionId:e,messageId:t})}else if(l=n,
|
|
711
|
+
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}P={providerId:"opencode",sessionId:e,messageId:t,createdAt:(new Date).toISOString()},(0,m.logSessionIdentity)(n,"_meta",{sessionId:e,messageId:t})}else if(l=n,g=E,v||(v=!0,k.warn("No _meta.sessionId on tool call \u2014 caller not on alchemylab-opencode fork.",{tool:l,metaKeys:g?Object.keys(g):null})),!1!==q?.requiresSession)throw(0,p.createMcpProtocolError)(`_meta.sessionId required for tool '${n}'`,{tool:n})
|
|
712
712
|
h.sessionIdentity.setCurrentCallOrigin(P)
|
|
713
713
|
const j=P?.sessionId||E?.sessionId
|
|
714
714
|
if(o?.workspaceManager){T=Date.now()
|
|
@@ -721,20 +721,20 @@ try{if(q){(0,y.preNormalize)(n,c),await(0,w.expandTaskRefsInArgs)(c,s,P?.session
|
|
|
721
721
|
const e={context:R,apiClient:s,logger:i,metrics:a,mcpServer:I,cliOrigin:P}
|
|
722
722
|
O=await q.handler(c,e)}else k.info(`Tool ${n} not found, returning negative response`),O={content:[{type:"text",text:`The tool '${n}' does not exist.`}]}}finally{M("end")}return Date.now(),Date.now(),S({tool:n,success:!0}),O}catch(t){k.error("Error executing tool:",{error:t instanceof Error?t.stack:t+"",tool:e.params.name}),a.incrementCounter("tool_errors_total",1,{tool:e.params.name,error:t instanceof Error?t.name:"unknown"})
|
|
723
723
|
let r="Unknown error"
|
|
724
|
-
return r=t instanceof b.ZodError?function(e,t){return 1===e.issues.length?n(e.issues[0],t):e.issues.map((e=>n(e,t))).join("; ")}(t,c):(0,d.getStructuredErrorMessage)(t),{content:[{type:"text",text:"Error: "+r}],isError:!0}}var l,
|
|
725
|
-
const c=t(9150),l=t(2478),d=t(8824),u=t(7617),h=t(6688),
|
|
724
|
+
return r=t instanceof b.ZodError?function(e,t){return 1===e.issues.length?n(e.issues[0],t):e.issues.map((e=>n(e,t))).join("; ")}(t,c):(0,d.getStructuredErrorMessage)(t),{content:[{type:"text",text:"Error: "+r}],isError:!0}}var l,g})),k.info("Tools registration complete")}
|
|
725
|
+
const c=t(9150),l=t(2478),d=t(8824),u=t(7617),h=t(6688),p=t(9860)
|
|
726
726
|
a(t(9896)),a(t(6928))
|
|
727
|
-
var
|
|
728
|
-
Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return
|
|
727
|
+
var g=t(7280)
|
|
728
|
+
Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return g.logSessionIdentity}})
|
|
729
729
|
const m=t(7280)
|
|
730
730
|
t(2462)
|
|
731
731
|
const f=t(2245),y=t(8622),w=t(4466),b=(a(t(857)),t(1569))},1483(e,exports,t){"use strict"
|
|
732
732
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearchDocuments=async function(e,t,n,o,s){const i=o.child({tool:"search_documents"}),a=s.startTimer("tool_execution_time")
|
|
733
|
-
try{const o=e,{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,dateFrom:u,dateTo:h,searchIn:
|
|
734
|
-
i.info("Searching documents",{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,searchIn:
|
|
735
|
-
const
|
|
736
|
-
if(!
|
|
737
|
-
return i.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}n.setProjectId(
|
|
733
|
+
try{const o=e,{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,dateFrom:u,dateTo:h,searchIn:p}=o
|
|
734
|
+
i.info("Searching documents",{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,searchIn:p})
|
|
735
|
+
const g=t.projectId
|
|
736
|
+
if(!g){const e="Project ID is required. Make sure you are in a project context."
|
|
737
|
+
return i.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}n.setProjectId(g)
|
|
738
738
|
const m=n.getDocumentClient()
|
|
739
739
|
try{const e={limit:d||100,offset:0,sortBy:"updatedAt",sortDirection:"desc",searchQuery:s,includeArchived:l||!1}
|
|
740
740
|
a&&(e.type=a),c&&(e.requestId=c),i.debug("Fetching documents with filters",{filters:e})
|
|
@@ -744,7 +744,7 @@ t=t.filter((t=>new Date(t.createdAt)>=e))}if(h){const e=new Date(h)
|
|
|
744
744
|
t=t.filter((t=>new Date(t.createdAt)<=e))}i.info(`Fetched and filtered ${t.length} documents for search`)
|
|
745
745
|
const r=[],n=s.toLowerCase()
|
|
746
746
|
for(const e of t){let t,o=null
|
|
747
|
-
if("filename"!==
|
|
747
|
+
if("filename"!==p&&"both"!==p||!e.filename.toLowerCase().includes(n)||(o="filename",t=e.filename),("content"===p||"both"===p)&&e.content&&e.content.toLowerCase().includes(n)){o="content"
|
|
748
748
|
const r=e.content.split("\n")
|
|
749
749
|
for(let e=0;e<r.length;e++)if(r[e].toLowerCase().includes(n)){const n=Math.max(0,e-1),o=Math.min(r.length-1,e+1)
|
|
750
750
|
t=r.slice(n,o+1).map(((t,r)=>n+r===e?"> "+t.trim():" "+t.trim())).join("\n")
|
|
@@ -780,8 +780,8 @@ const i=await this.getOrCreateBranchName(e,t),u=await d.branchExists(this.mainGi
|
|
|
780
780
|
try{await a.default.rm(s,{recursive:!0,force:!0})}catch{}try{await this.mainGit.raw(["worktree","prune"])}catch(t){this.logger.warn("Failed to prune worktree registry before creation",{requestId:e,error:t instanceof Error?t.message:t+""})}if(u)this.logger.info("Creating worktree for existing branch",{requestId:e,branchName:i,worktreePath:s}),await this.mainGit.raw(["worktree","add",s,i])
|
|
781
781
|
else{const t=(await d.getRepositoryStatus(this.mainGit,this.logger,this.metrics)).defaultBranch
|
|
782
782
|
if(!t)throw Error(`No default branch found in repository. Cannot create branch '${i}'.`)
|
|
783
|
-
this.logger.info("Creating worktree and new branch for request",{requestId:e,branchName:i,fromBranch:t,worktreePath:s}),await this.mainGit.raw(["worktree","add","-b",i,s,t])}const
|
|
784
|
-
return this.activeWorktrees.set(e,
|
|
783
|
+
this.logger.info("Creating worktree and new branch for request",{requestId:e,branchName:i,fromBranch:t,worktreePath:s}),await this.mainGit.raw(["worktree","add","-b",i,s,t])}const p={requestId:e,branchName:i,worktreePath:s,created:new Date,lastAccessed:new Date,sessionId:r,status:"active"}
|
|
784
|
+
return this.activeWorktrees.set(e,p),this.logger.info("Successfully created worktree",{requestId:e,branchName:i,worktreePath:s}),this.metrics.incrementCounter("worktree_created",1),n({success:!0}),{success:!0,worktreePath:s,branchName:i,message:"Created new worktree",created:!0}}catch(t){const r=(0,h.getErrorMessage)(t)
|
|
785
785
|
return this.logger.error("Failed to ensure worktree exists",{requestId:e,error:r}),this.metrics.incrementCounter("worktree_create_failure",1),n({success:!1,error:t instanceof Error?t.name:"unknown"}),{success:!1,message:"Failed to create worktree: "+r}}}async ensureWorktreeForRequest(e,t,r){return this.ensureWorktreeExists(e,t,r)}async removeWorktree(e,t=!0){const r=this.metrics.startTimer("worktree_remove_duration")
|
|
786
786
|
try{const n=this.activeWorktrees.get(e)
|
|
787
787
|
if(!n)return r({success:!0,reason:"not_found"}),{success:!0,message:"Worktree not found (already removed)"}
|
|
@@ -837,8 +837,8 @@ if(r){const e=`\u274c A document with filename "${i}" already exists ${s?"for th
|
|
|
837
837
|
return c.warn("Duplicate filename detected",{filename:i,requestId:s||"standalone",existingDocId:r.id}),{content:[{type:"text",text:e}],isError:!0}}const o=await e.createDocument(s,{filename:i,content:l,type:d,...a&&{cliOrigin:a}})
|
|
838
838
|
c.info("Document created successfully",{documentId:o.id,filename:o.filename,requestId:s||"standalone"})
|
|
839
839
|
try{const e=n.getToolRecordClient()
|
|
840
|
-
await e.createToolRecord({type:"create-document",projectId:h,metadata:{documentId:o.id,filename:o.filename,type:o.type,contentLength:l.length,requestId:s,projectId:h},note:u})}catch(e){c.warn("Failed to create tool record",{recordError:e})}const
|
|
841
|
-
return{content:[{type:"text",text:`\u2705 Document created successfully!\n\n**Document ID:** ${o.id}\n**Filename:** ${o.filename}\n**Type:** ${o.type}\n**Size:** ${l.length} characters\n`+
|
|
840
|
+
await e.createToolRecord({type:"create-document",projectId:h,metadata:{documentId:o.id,filename:o.filename,type:o.type,contentLength:l.length,requestId:s,projectId:h},note:u})}catch(e){c.warn("Failed to create tool record",{recordError:e})}const p=s?`**Request:** ${s}\n`:"**Standalone:** Yes (not tied to a request)\n"
|
|
841
|
+
return{content:[{type:"text",text:`\u2705 Document created successfully!\n\n**Document ID:** ${o.id}\n**Filename:** ${o.filename}\n**Type:** ${o.type}\n**Size:** ${l.length} characters\n`+p+`**Created:** ${o.createdAt}\n\n`+`The document is now stored in the tracking system and can be edited using standard file modification tools by referencing its document ID (${o.id}) instead of a file path.\n\n**Examples:**\n`+`- \`replace_string\` with \`documentId: "${o.id}"\`\n`+`- \`write_file\` with \`documentId: "${o.id}"\`\n`+`- \`file_history\` with \`documentId: "${o.id}"\``}]}}catch(e){const t="Failed to create document: "+(0,r.getErrorMessage)(e)
|
|
842
842
|
return c.error("Failed to create document",{error:e}),{content:[{type:"text",text:"\u274c "+t}],isError:!0}}}catch(e){return c.error("Unexpected error in create document",{error:e}),{content:[{type:"text",text:"\u274c Unexpected error: "+(0,r.getErrorMessage)(e)}],isError:!0}}finally{l({tool:"create_document"})}}
|
|
843
843
|
const r=t(8824)},1599(e,exports,t){"use strict"
|
|
844
844
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SessionRequestAssociationClient=void 0
|
|
@@ -1045,15 +1045,15 @@ r(t,"Looking up agent type from action server",{sessionId:e,url:o})
|
|
|
1045
1045
|
const s=await fetch(o)
|
|
1046
1046
|
if(s.ok){const o=await s.json()
|
|
1047
1047
|
r(t,"Agent type response from action server",{sessionId:e,agentType:o.agentType||null,source:o.source||null,success:o.success}),o.success&&o.agentType&&(n=o.agentType,w.sessionIdentity.updateIdentity({agentType:n}))}else r(t,"Agent type lookup failed",{sessionId:e,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e,error:(0,I.getErrorMessage)(n)})}if(n){const e=(0,C.getAllowedSubagents)(n)
|
|
1048
|
-
if(e&&!e.includes(c))return{content:[{type:"text",text:`\u274c Agent type '${n}' cannot spawn '${c}'.\n\n**Allowed subagents for ${n}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,I.getErrorMessage)(e)})}let
|
|
1048
|
+
if(e&&!e.includes(c))return{content:[{type:"text",text:`\u274c Agent type '${n}' cannot spawn '${c}'.\n\n**Allowed subagents for ${n}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,I.getErrorMessage)(e)})}let p
|
|
1049
1049
|
try{const e=await async function(e){try{const t=`http://localhost:${S}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
|
|
1050
1050
|
if(!r.ok)return null
|
|
1051
1051
|
const n=await r.json()
|
|
1052
1052
|
return n.success?n.data??null:null}catch{return null}}(c)
|
|
1053
|
-
if(
|
|
1054
|
-
|
|
1055
|
-
const
|
|
1056
|
-
r(t,"serverUrl resolved",{serverUrl:
|
|
1053
|
+
if(p=e?.requestContextMode,!p){const e=(0,C.getBuiltInAgentConfig)(c)
|
|
1054
|
+
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}
|
|
1055
|
+
const g=await(0,y.getServerUrl)(t,s)
|
|
1056
|
+
r(t,"serverUrl resolved",{serverUrl:g})
|
|
1057
1057
|
const k=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath
|
|
1058
1058
|
if(!k)throw new m.ValidationError("Working directory not available in context")
|
|
1059
1059
|
const v=a?.sessionId
|
|
@@ -1063,21 +1063,21 @@ if(e){const t=await e.getSessionsForRequest(d,!0),r=v?t.filter((e=>e.opencodeSes
|
|
|
1063
1063
|
if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
|
|
1064
1064
|
if(!u)return s.warn("Blocked spawn: request already has active workers",{requestId:d,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId))}),{content:[{type:"text",text:`\u274c Cannot spawn: Request ${d} already has ${r.length} active worker(s): ${e}\n\nOptions:\n\u2022 Use \`useExistingSession: "${r[0].opencodeSessionId}"\` to send work to the existing session\n\u2022 Use \`allowParallel: true\` if you really need multiple workers on the same request`}],isError:!0}
|
|
1065
1065
|
E=`\u26a0\ufe0f Warning: Request ${d} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,s.warn("Spawning parallel subagent for request with existing active workers",{requestId:d,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){s.debug("Failed to check for existing workers",{error:(0,I.getErrorMessage)(e)})}let T,q,P=l
|
|
1066
|
-
d&&(T="requests/"+d,r(t,"Setting initialBranch for agent",{agent:c,requestId:d,initialBranch:T,agentRequestContextMode:
|
|
1066
|
+
d&&(T="requests/"+d,r(t,"Setting initialBranch for agent",{agent:c,requestId:d,initialBranch:T,agentRequestContextMode:p||"undefined"}),P="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}`)
|
|
1067
1067
|
let j,R=!1
|
|
1068
|
-
if(h){if(q=h,s.info("Using existing session for spawn",{sessionId:q,requestId:d}),!
|
|
1068
|
+
if(h){if(q=h,s.info("Using existing session for spawn",{sessionId:q,requestId:d}),!g)throw new m.ValidationError("Could not determine OpenCode server URL")
|
|
1069
1069
|
try{let e
|
|
1070
1070
|
try{const t=await fetch(`http://localhost:${S}/api/project-settings`)
|
|
1071
1071
|
if(t.ok){const r=await t.json()
|
|
1072
1072
|
if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
|
|
1073
1073
|
e={providerID:t,modelID:n.join("/")}}}}catch{}j=await o({apiClient:i,fromSessionId:a?.sessionId,toSessionId:q,body:P,requestId:d,logger:s})
|
|
1074
|
-
const t=n(P,j),r=`${
|
|
1074
|
+
const t=n(P,j),r=`${g.replace(/\/$/,"")}/session/${q}/prompt_async`,l={alchemy:{kind:"agent-delegation",payload:{body:P,fromSessionId:a?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...d?{requestId:d}:{},...j?{instructionCode:j}:{}}}},u=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:t,metadata:l}],...c?{agent:c}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
|
|
1075
1075
|
if(!u.ok){const e=await u.text().catch((()=>"Unknown error"))
|
|
1076
1076
|
throw Error(`Failed to send to existing session: ${u.status} ${e}`)}s.info("Prompt sent to existing session",{sessionId:q,agent:c})}catch(e){throw Error("Failed to use existing session: "+(0,I.getErrorMessage)(e))}}else{R=!0,r(t,"Creating session via spawn-session endpoint")
|
|
1077
1077
|
const h=v;(0,b.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:h})
|
|
1078
|
-
try{const
|
|
1079
|
-
if(!
|
|
1080
|
-
throw Error(`Spawn session endpoint failed: ${
|
|
1078
|
+
try{const p=`http://localhost:${S}/api/spawn-session`,g=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)})
|
|
1079
|
+
if(!g.ok){const e=await g.text().catch((()=>"Unknown error"))
|
|
1080
|
+
throw Error(`Spawn session endpoint failed: ${g.status} ${e}`)}const m=await g.json()
|
|
1081
1081
|
if(!m.success||!m.data)throw Error(m.error||"Spawn session returned unsuccessful")
|
|
1082
1082
|
const{sessionId:y,model:b,serverUrl:I,initialBranch:v}=m.data
|
|
1083
1083
|
T=v,j=await o({apiClient:i,fromSessionId:a?.sessionId,toSessionId:y,body:P,requestId:d,logger:s})
|
|
@@ -1107,9 +1107,9 @@ try{let r
|
|
|
1107
1107
|
try{const e=await fetch(`http://localhost:${S}/api/project-settings`)
|
|
1108
1108
|
if(e.ok){const t=await e.json()
|
|
1109
1109
|
if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
|
|
1110
|
-
r={providerID:e,modelID:n.join("/")}}}}catch{}const a=await o({apiClient:i,fromSessionId:c?.sessionId,toSessionId:e,body:t,logger:s}),u=n(t,a),h=`${l.replace(/\/$/,"")}/session/${e}/prompt_async`,
|
|
1111
|
-
if(!
|
|
1112
|
-
throw Error(`Failed to send message: ${
|
|
1110
|
+
r={providerID:e,modelID:n.join("/")}}}}catch{}const a=await o({apiClient:i,fromSessionId:c?.sessionId,toSessionId:e,body:t,logger:s}),u=n(t,a),h=`${l.replace(/\/$/,"")}/session/${e}/prompt_async`,p={alchemy:{kind:"agent-followup",payload:{body:t,fromSessionId:c?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...a?{instructionCode:a}:{}}}},g=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)})
|
|
1111
|
+
if(!g.ok){const e=await g.text().catch((()=>"Unknown error"))
|
|
1112
|
+
throw Error(`Failed to send message: ${g.status} ${e}`)}return s.info("Message sent to subagent session",{sessionId:e,agent:d,instructionCode:a}),{content:[{type:"text",text:a?`Message sent to session ${e} (${a}).\nThe subagent will process it in the background.`:`Message sent to session ${e}.\nThe subagent will process it in the background.`}],...a?{_meta:{alchemy:{kind:"continue-subagent",instructionCode:a}},instructionCode:a}:{}}}catch(e){throw Error("Failed to continue session: "+(0,I.getErrorMessage)(e))}}function a(e){const t=Math.floor(e/1e3)
|
|
1113
1113
|
if(60>t)return t+"s"
|
|
1114
1114
|
const r=Math.floor(t/60)
|
|
1115
1115
|
return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function c(e){const t=[]
|
|
@@ -1127,9 +1127,9 @@ if(!s)throw new m.ValidationError("Could not determine OpenCode server URL")
|
|
|
1127
1127
|
n.info("Checking status of subagent session",{sessionId:e})
|
|
1128
1128
|
try{const i=`${s.replace(/\/$/,"")}/session/${e}`,l=await fetch(i)
|
|
1129
1129
|
if(!l.ok)return{content:[{type:"text",text:`Session ${e} not found or has exited.`}],isError:!0}
|
|
1130
|
-
const h=await l.json(),
|
|
1130
|
+
const h=await l.json(),p=`${s.replace(/\/$/,"")}/session/${e}/message`,g=await fetch(p)
|
|
1131
1131
|
let m={input:0,output:0,reasoning:0},f="",y=d(null,h.time.updated)
|
|
1132
|
-
if(
|
|
1132
|
+
if(g.ok){const e=await g.json()
|
|
1133
1133
|
for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(m.input+=t.info.tokens.input||0,m.output+=t.info.tokens.output||0,m.reasoning+=t.info.tokens.reasoning||0)
|
|
1134
1134
|
const t=c(e)
|
|
1135
1135
|
y=d(t.lastActivityTime,h.time.updated),t.current&&(f+="\nCurrent: "+t.current),t.recent.length>0&&(f+="\nRecent: "+t.recent.join(", "))}const w=Date.now()-h.time.created,b=y.status,I=y.isReady,k=m.input+m.output+m.reasoning
|
|
@@ -1147,22 +1147,22 @@ if(e.trim())return u(e)}try{const t=n(`git log main --merges --oneline -n 50 --g
|
|
|
1147
1147
|
if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
|
|
1148
1148
|
if(o.trim())return{...u(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
|
|
1149
1149
|
if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
|
|
1150
|
-
v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${b} (${y.detail})\nReady for input: ${I?"Yes":"No"}\nAge: ${a(w)}\nTokens: ${k.toLocaleString()} (in: ${m.input.toLocaleString()}, out: ${m.output.toLocaleString()}${m.reasoning>0?", reasoning: "+m.reasoning.toLocaleString():""})${f}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,I.getErrorMessage)(e))}}async function
|
|
1150
|
+
v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${b} (${y.detail})\nReady for input: ${I?"Yes":"No"}\nAge: ${a(w)}\nTokens: ${k.toLocaleString()} (in: ${m.input.toLocaleString()}, out: ${m.output.toLocaleString()}${m.reasoning>0?", reasoning: "+m.reasoning.toLocaleString():""})${f}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,I.getErrorMessage)(e))}}async function p(e,t,r){const n=await(0,y.getServerUrl)(t,r)
|
|
1151
1151
|
if(!n)throw new m.ValidationError("Could not determine OpenCode server URL")
|
|
1152
1152
|
r.info("Aborting subagent session",{sessionId:e})
|
|
1153
1153
|
try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
|
|
1154
1154
|
if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
|
|
1155
|
-
throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,I.getErrorMessage)(e))}}async function
|
|
1156
|
-
if(!
|
|
1155
|
+
throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,I.getErrorMessage)(e))}}async function g(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)
|
|
1156
|
+
if(!p)throw new m.ValidationError("Could not determine OpenCode server URL")
|
|
1157
1157
|
t.info("Listing sessions",{filters:n})
|
|
1158
|
-
try{const e=
|
|
1158
|
+
try{const e=p.replace(/\/$/,"")+"/session",t=await fetch(e)
|
|
1159
1159
|
if(!t.ok)throw Error("Failed to fetch sessions: "+t.status)
|
|
1160
|
-
let
|
|
1161
|
-
if(0===
|
|
1162
|
-
const m=
|
|
1163
|
-
n.parentSessionId&&(
|
|
1164
|
-
const f=
|
|
1165
|
-
let b=
|
|
1160
|
+
let g=await t.json()
|
|
1161
|
+
if(0===g.length)return{content:[{type:"text",text:"No sessions found."}]}
|
|
1162
|
+
const m=g
|
|
1163
|
+
n.parentSessionId&&(g=g.filter((e=>(e.parentId||e.parentID)===n.parentSessionId))),g.sort(((e,t)=>t.time.created-e.time.created))
|
|
1164
|
+
const f=p.replace(/\/$/,"")+"/session/status",y=await fetch(f),w=y.ok?await y.json():{}
|
|
1165
|
+
let b=g
|
|
1166
1166
|
if(o&&(b=b.filter((e=>"idle"!==(w[e.id]?.type||"idle")))),void 0!==h){const e=36e5*h,t=Date.now()-e
|
|
1167
1167
|
b=b.filter((e=>e.time.created>=t))}if(0===b.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1168
1168
|
let I={}
|
|
@@ -1172,12 +1172,12 @@ if("specialist"===n.agentType){const e=new Set(k)
|
|
|
1172
1172
|
for(const t of m){const r=t.parentId||t.parentID
|
|
1173
1173
|
r&&e.has(r)&&(v[r]||(v[r]=[]),v[r].push(t.id),C.push(t.id))}}if(r)try{const e=r.getCLISessionClient()
|
|
1174
1174
|
if(e){const t=[...k,...C]
|
|
1175
|
-
I=await e.batchEnrich(t)}}catch{}const _=
|
|
1175
|
+
I=await e.batchEnrich(t)}}catch{}const _=p.replace(/\/$/,""),E=await Promise.allSettled(b.map((e=>fetch(`${_}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),S=[]
|
|
1176
1176
|
for(let e=0;e<b.length;e++){const t=b[e],r=Date.now()-t.time.created
|
|
1177
1177
|
let o=0,i=null,a=[],h=d(null,t.time.updated)
|
|
1178
|
-
const
|
|
1179
|
-
for(const e of
|
|
1180
|
-
if(
|
|
1178
|
+
const p=E[e],g="fulfilled"===p.status?p.value:[]
|
|
1179
|
+
for(const e of g)"assistant"===e.info.role&&e.info.tokens&&(o+=(e.info.tokens.input||0)+(e.info.tokens.output||0)+(e.info.tokens.reasoning||0))
|
|
1180
|
+
if(g.length>0){const e=c(g)
|
|
1181
1181
|
h=d(e.lastActivityTime,t.time.updated),i=e.current||null,a=e.recent}const m=h.status
|
|
1182
1182
|
if(void 0!==l&&l>o)continue
|
|
1183
1183
|
if(void 0!==u&&o>u)continue
|
|
@@ -1201,7 +1201,7 @@ const T=t.title||"Untitled",q=T.length>50?T.slice(0,47)+"...":T
|
|
|
1201
1201
|
S.push({id:t.id,title:q,status:m,age:r,totalTokens:o,requestsInfo:y,allRequestIds:k,statusDetail:h.detail,specialization:f?.specialization??null,currentAction:i,recentActions:a})}if(0===S.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1202
1202
|
const T=i?S.slice(0,i):S,q=T.map((e=>{const t=e.specialization?"\n Specialization: "+e.specialization:"",r=e.currentAction?"\n Current: "+e.currentAction:"",o="specialist"!==n.agentType&&e.recentActions.length>0?"\n Recent: "+e.recentActions.join(", "):""
|
|
1203
1203
|
return`\u2022 ${e.id}\n ${e.title}${t}\n Status: ${e.status} (${e.statusDetail}) | Age: ${a(e.age)} | ${e.totalTokens.toLocaleString()} tokens${e.requestsInfo}${r}${o}`})),P=i&&S.length>i?` (showing ${i} of ${S.length})`:""
|
|
1204
|
-
return{content:[{type:"text",text:`Found ${T.length} session${1!==T.length?"s":""}${P}:\n\n${q.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,I.getErrorMessage)(e))}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=s,exports.handleContinue=i,exports.handleCheckStatus=h,exports.handleAbort=
|
|
1204
|
+
return{content:[{type:"text",text:`Found ${T.length} session${1!==T.length?"s":""}${P}:\n\n${q.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,I.getErrorMessage)(e))}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=s,exports.handleContinue=i,exports.handleCheckStatus=h,exports.handleAbort=p,exports.handleListSessions=g,exports.handleSubagentOperations=async function(e,t,r,n,o,a){const c=r.child({tool:"subagent_operations"}),l=n.startTimer("tool_execution_time")
|
|
1205
1205
|
try{const r=e,{sessionId:d,operation:u}=r
|
|
1206
1206
|
let f
|
|
1207
1207
|
switch(c.info("Processing subagent_operations",{operation:u,sessionId:d}),u){case"spawn":f=await s({agent:r.agent,prompt:r.prompt,requestId:r.requestId,allowParallel:r.allowParallel,useExistingSession:r.useExistingSession},t,c,o,a)
|
|
@@ -1210,7 +1210,7 @@ case"continue":f=await i(d,r.prompt,t,c,o,void 0,a)
|
|
|
1210
1210
|
break
|
|
1211
1211
|
case"check-status":f=await h(d,t,c,o)
|
|
1212
1212
|
break
|
|
1213
|
-
case"abort":f=await
|
|
1213
|
+
case"abort":f=await p(d,t,c)
|
|
1214
1214
|
break
|
|
1215
1215
|
case"read-messages":const e=r.limit??1
|
|
1216
1216
|
f=await async function(e,t,r,n){const o=await(0,y.getServerUrl)(r,n)
|
|
@@ -1225,7 +1225,7 @@ return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n$
|
|
|
1225
1225
|
return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,I.getErrorMessage)(e))}}(d,e,t,c)
|
|
1226
1226
|
break
|
|
1227
1227
|
case"list-sessions":const n={activeOnly:r.activeOnly,requestId:r.requestId,limit:r.limit,minTokens:r.minTokens,maxTokens:r.maxTokens,maxAgeHours:r.maxAgeHours,parentSessionId:a?.sessionId}
|
|
1228
|
-
f=await
|
|
1228
|
+
f=await g(t,c,o,n)
|
|
1229
1229
|
break
|
|
1230
1230
|
default:throw new m.ValidationError("Unknown operation: "+u)}l({success:!0}),n.incrementCounter(`subagent_operations_${u}_success`,1)
|
|
1231
1231
|
const w=E[u]
|
|
@@ -1264,7 +1264,11 @@ try{if(o.default.existsSync(this.projectFilePath)){this.logger.debug("Updating e
|
|
|
1264
1264
|
const t=JSON.parse(o.default.readFileSync(this.projectFilePath,"utf8"))
|
|
1265
1265
|
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})
|
|
1266
1266
|
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
|
|
1267
|
-
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)}}},
|
|
1267
|
+
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"
|
|
1268
|
+
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
|
|
1269
|
+
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
|
|
1270
|
+
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}\``}}
|
|
1271
|
+
const t=3e3,r=1500},1887(e,exports,t){"use strict"
|
|
1268
1272
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProxyClient=void 0
|
|
1269
1273
|
const r=t(9860),n=t(5674),o=t(4192),s=t(2161),i=t(8824)
|
|
1270
1274
|
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)+"..."})
|
|
@@ -1346,25 +1350,25 @@ l=e.map(((e,t)=>({name:"setup-"+(t+1),command:e,timeout:120})))}else{const t=pro
|
|
|
1346
1350
|
if(!r){const r=t.map((e=>e.name)).join(", ")
|
|
1347
1351
|
return a({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}l=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{runShellCommand:d}=await Promise.resolve().then(t.bind(t,4600)),u=globalThis.process
|
|
1348
1352
|
let h=null
|
|
1349
|
-
const
|
|
1353
|
+
const p=[]
|
|
1350
1354
|
try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
|
|
1351
|
-
if(
|
|
1352
|
-
if(
|
|
1353
|
-
|
|
1354
|
-
const
|
|
1355
|
-
try{f.mkdirSync(w,{recursive:!0})}catch{}const{runTrackedShellCommand:b}=await Promise.resolve().then(t.bind(t,4600)),{
|
|
1355
|
+
if(p.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
|
|
1356
|
+
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
|
|
1357
|
+
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}
|
|
1358
|
+
const g=[],{default:m}=await Promise.resolve().then(t.t.bind(t,6928,23)),{default:f}=await Promise.resolve().then(t.t.bind(t,9896,23)),{ALCHEMY_DIR_NAME:y}=await Promise.resolve().then(t.bind(t,4139)),w=m.join(h,y,"command-logs")
|
|
1359
|
+
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
|
|
1356
1360
|
for(const t of l){c.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:h})
|
|
1357
1361
|
const r=`${t.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,n=m.join(w,r+".log")
|
|
1358
1362
|
let o=null
|
|
1359
|
-
try{o=f.createWriteStream(n,{flags:"w"}),o.write(`# ${(new Date).toISOString()} starting: ${t.command}\n# cwd: ${h}\n# timeout: ${t.timeout}s\n\n`)}catch(e){c.warn("Failed to open command log file",{logPath:n,error:e+""})}const s=await b(t.command,{cwd:h,timeoutMs:1e3*t.timeout,env:{...u.env,FORCE_COLOR:"0"},onChunk:o?(e,t)=>{o?.write(t)}:void 0},{id:r,name:t.name,sessionId:
|
|
1363
|
+
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})
|
|
1360
1364
|
o&&(o.write(`\n# exit: ${s.exitCode}${s.timedOut?" (timed out)":""}\n`),o.end())
|
|
1361
|
-
const i=(s.stdout+(s.stderr?"\n"+s.stderr:"")).trim()
|
|
1362
|
-
if(
|
|
1363
|
-
return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n
|
|
1364
|
-
return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${
|
|
1365
|
+
const i=(s.stdout+(s.stderr?"\n"+s.stderr:"")).trim(),{output:a,truncatedNote:l,logFooter:d}=I(i,{invocationId:r})
|
|
1366
|
+
if(g.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=g.every((e=>0===e.exitCode)),_=g.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
|
|
1367
|
+
return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\`${e.truncatedNote}\n${e.logFooter}`})).join("\n\n")
|
|
1368
|
+
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")
|
|
1365
1369
|
try{const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=await u.getSessionRequestId(i,a,l?.sessionId)
|
|
1366
1370
|
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}
|
|
1367
|
-
const
|
|
1371
|
+
const p=await i.proxyGet(`/api/projects/${s.projectId}/requests/${h}/test-runs`),g=p?.data||p||[],m=Array.isArray(g)?g:[],f=m.find((e=>"pending"===e.status||"running"===e.status))||m[0]
|
|
1368
1372
|
if(!f)return d({success:!1,error:"no_test_run"}),{content:[{type:"text",text:`No test run found for request ${h}.`}],isError:!0}
|
|
1369
1373
|
const y=f.id
|
|
1370
1374
|
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)})))
|
|
@@ -1380,15 +1384,15 @@ const o=r.map((e=>`**${e.name}** (${e.id})${e.scope?` [scope: ${e.scope}]`:""}\n
|
|
|
1380
1384
|
return d({success:!0}),{content:[{type:"text",text:`## Test Processes (${r.length})\n\n${o}`}]}}if("run"===e.operation){let c=0
|
|
1381
1385
|
try{const e=await i.proxyGet(`/api/projects/${n.projectId}/test-processes`),t=e?.data||e||[]
|
|
1382
1386
|
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}
|
|
1383
|
-
const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=l?.sessionId,
|
|
1384
|
-
if(!
|
|
1385
|
-
const
|
|
1386
|
-
try{const e=await fetch((0,o.getActionServerBaseUrl)()+"/api/run-tests-now",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:
|
|
1387
|
+
const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=l?.sessionId,p=h?await u.getSessionRequestId(i,a,h):void 0
|
|
1388
|
+
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}
|
|
1389
|
+
const g=e.name?[e.name]:void 0
|
|
1390
|
+
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:g}),signal:AbortSignal.timeout(15e3)})
|
|
1387
1391
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
1388
1392
|
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()
|
|
1389
1393
|
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}
|
|
1390
|
-
const r=t.data.spawnedSessionIds?.[0],n=
|
|
1391
|
-
return d({success:!0}),{content:[{type:"text",text:`Test run started${n}.\nSpawned ${t.data.agentsSpawned} runner(s) for ${t.data.processCount} process(es). Test runs: ${t.data.testRunIds.join(", ")}.\n\nThe auto-tester is executing the registered commands. You will receive a notification on your next turn when results are reported \u2014 continue with other work in the meantime.`}],...(0,s.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:r,agentType:"auto-tester",requestId:
|
|
1394
|
+
const r=t.data.spawnedSessionIds?.[0],n=g?` (filtered to: ${g.join(", ")})`:""
|
|
1395
|
+
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:g?"Test run: "+g.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:[]
|
|
1392
1396
|
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
|
|
1393
1397
|
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)})
|
|
1394
1398
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
@@ -1448,18 +1452,18 @@ t.info("commit_to_viewed_session:parsed",{callId:i,messagePreview:c.slice(0,80),
|
|
|
1448
1452
|
const l=o.sessionIdentity.getIdentity(),d=l?.sessionId,u=l?.serverUrl
|
|
1449
1453
|
if(!d||!u)return t.warn("commit_to_viewed_session: missing session identity",{hasHeraldId:!!d,hasServerUrl:!!u}),{content:[{type:"text",text:"Commit failed: herald session identity unavailable."}],isError:!0}
|
|
1450
1454
|
let h
|
|
1451
|
-
try{h=await r(u,d)}catch(e){return t.warn("commit_to_viewed_session: could not fetch herald messages",{heraldId:d,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:`Commit failed: unable to read herald context (${(0,n.getErrorMessage)(e)}).`}],isError:!0}}const
|
|
1455
|
+
try{h=await r(u,d)}catch(e){return t.warn("commit_to_viewed_session: could not fetch herald messages",{heraldId:d,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:`Commit failed: unable to read herald context (${(0,n.getErrorMessage)(e)}).`}],isError:!0}}const p=function(e){for(let t=e.length-1;t>=0;t--){const r=e[t]
|
|
1452
1456
|
if("user"===r.info?.role)for(const e of r.parts??[]){if("text"!==e.type||!e.text)continue
|
|
1453
1457
|
const t=e.text.match(/<viewed_session\s+id="([^"]+)"\s*\/?>/)
|
|
1454
1458
|
if(t)return t[1]}}return null}(h)
|
|
1455
|
-
if(!
|
|
1456
|
-
let
|
|
1457
|
-
try{
|
|
1458
|
-
if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,
|
|
1459
|
-
|
|
1460
|
-
try{const e=await fetch(`${u}/session/${
|
|
1459
|
+
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}
|
|
1460
|
+
let g
|
|
1461
|
+
try{g=function(e){for(let t=e.length-1;t>=0;t--){const r=e[t]
|
|
1462
|
+
if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,p)),g||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 m={parts:[{type:"text",text:c,metadata:(0,s.partMeta)("via-herald")}]}
|
|
1463
|
+
g&&(m.agent=g),t.info("commit_to_viewed_session:posting",{callId:i,viewedId:p,heraldId:d,agent:g})
|
|
1464
|
+
try{const e=await fetch(`${u}/session/${p}/prompt_async`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(m),signal:AbortSignal.timeout(1e4)})
|
|
1461
1465
|
if(t.info("commit_to_viewed_session:posted",{callId:i,status:e.status}),!e.ok){const t=await e.text().catch((()=>""))
|
|
1462
|
-
return{content:[{type:"text",text:`Commit failed: prompt_async returned ${e.status}${t?` (${t.slice(0,120)})`:""}.`}],isError:!0}}}catch(e){return t.warn("commit_to_viewed_session:post-failed",{callId:i,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:"Commit failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}return t.info("Translator forwarded message to viewed session",{callId:i,heraldId:d,viewedId:
|
|
1466
|
+
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:g,messageLength:c.length,preview:c.slice(0,120),durationMs:Date.now()-a}),{content:[{type:"text",text:"Committed."}]}}
|
|
1463
1467
|
const n=t(8824),o=t(6688),s=t(2272)},2141(e,exports,t){"use strict"
|
|
1464
1468
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConflictResolver=void 0,exports.createConflictResolver=function(e){return new n(e)}
|
|
1465
1469
|
const r=t(8824)
|
|
@@ -1535,53 +1539,53 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
1535
1539
|
var t={}
|
|
1536
1540
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
1537
1541
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1538
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,r,n,o,s,i,
|
|
1542
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,r,n,o,s,i,g,m){const f=i.child({tool:"move_files"}),y=Date.now()
|
|
1539
1543
|
let w,b,I=l.FileOperationPhase.VALIDATION
|
|
1540
1544
|
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"}
|
|
1541
1545
|
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)
|
|
1542
1546
|
if("errorResult"in _)return _.errorResult
|
|
1543
1547
|
const{taskId:E}=_
|
|
1544
1548
|
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")
|
|
1545
|
-
l.validateTaskIdFormat(E,f,
|
|
1549
|
+
l.validateTaskIdFormat(E,f,g,k.metricsPrefix)
|
|
1546
1550
|
const S=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1547
1551
|
f.info("Initial branch context",{initialBranch:S.branch,initialRequestId:S.requestId,isMain:S.isMain})
|
|
1548
1552
|
const T=[]
|
|
1549
1553
|
for(const e of u){const{normalizedPath:t,fullPath:n}=l.validateAndNormalizePath(e.source,r),{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(e.destination,r)
|
|
1550
|
-
T.push({source:t,destination:o,fullSource:n,fullDestination:s})}I=l.FileOperationPhase.TASK_VALIDATION,
|
|
1551
|
-
const q=await l.validateTaskId(E,T[0].source,n,f,
|
|
1554
|
+
T.push({source:t,destination:o,fullSource:n,fullDestination:s})}I=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("move_files_phase",1,{phase:I})
|
|
1555
|
+
const q=await l.validateTaskId(E,T[0].source,n,f,g,k.metricsPrefix),P=q?.requestId,j=await l.validateWorkItemStates(E,T[0].source,n,s,r,f,g,k.metricsPrefix),R=await l.autoPromoteTaskStatus(E,q.status,P,j.request?.status,T[0].source,n,s,f,g,k.metricsPrefix)
|
|
1552
1556
|
R.taskPromoted&&f.info(`Auto-promoted task ${E} (${q.title||"Untitled"}) to in_progress for file operations`,{taskId:E,taskTitle:q.title,previousStatus:q.status,newStatus:R.newTaskStatus,operationCount:u.length}),R.requestPromoted&&f.info(`Auto-promoted request ${P} to in_progress for file operations`,{requestId:P,previousStatus:j.request?.status,newStatus:R.newRequestStatus,triggeringTaskId:E})
|
|
1553
|
-
const x=await l.ensureCorrectWorkspaceContext({taskPromoted:R.taskPromoted,requestId:P,context:r,operation:"move-files",logger:f,metrics:
|
|
1557
|
+
const x=await l.ensureCorrectWorkspaceContext({taskPromoted:R.taskPromoted,requestId:P,context:r,operation:"move-files",logger:f,metrics:g,metricsPrefix:k.metricsPrefix})
|
|
1554
1558
|
if(!x.success)throw Error(x.error)
|
|
1555
1559
|
let M={hadUserMods:!1,userModsCommitHash:void 0}
|
|
1556
1560
|
if(r.git)try{f.debug("[MOVE-FILES] Checking for user changes before move operations")
|
|
1557
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:P,taskId:E,workspaceManager:r.workspaceManager},f,
|
|
1558
|
-
e.userChangesCommitted&&(f.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),f.info("User changes committed before move-files operation",{taskId:E,moveOperationsCount:T.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),M={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){f.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),f.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:E,moveOperationsCount:T.length,error:e instanceof Error?e.message:e+""})}f.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:T.length}),I=l.FileOperationPhase.RECORD_CREATION,
|
|
1559
|
-
const{toolRecordId:O,localToolRecordId:$}=await l.createFileOperationRecords(E,P,r.projectId,k.recordType,T[0].source,{operationCount:u.length,operations:T.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},n,o,f,
|
|
1560
|
-
w=O,b=O,I=k.fileOperationPhase,
|
|
1561
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:P,taskId:E,workspaceManager:r.workspaceManager},f,g)
|
|
1562
|
+
e.userChangesCommitted&&(f.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),f.info("User changes committed before move-files operation",{taskId:E,moveOperationsCount:T.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),M={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){f.debug("[MOVE-FILES] Pre-tool commit failed, continuing with move operations",{error:e instanceof Error?e.message:e+""}),f.warn("Pre-tool user changes commit failed, continuing with move operation",{taskId:E,moveOperationsCount:T.length,error:e instanceof Error?e.message:e+""})}f.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:T.length}),I=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("move_files_phase",1,{phase:I})
|
|
1563
|
+
const{toolRecordId:O,localToolRecordId:$}=await l.createFileOperationRecords(E,P,r.projectId,k.recordType,T[0].source,{operationCount:u.length,operations:T.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},n,o,f,g,k.metricsPrefix,m)
|
|
1564
|
+
w=O,b=O,I=k.fileOperationPhase,g.incrementCounter("move_files_phase",1,{phase:I})
|
|
1561
1565
|
const D=[]
|
|
1562
1566
|
let A=0
|
|
1563
1567
|
for(const e of T){const t={operation:{source:e.source,destination:e.destination},success:!1}
|
|
1564
1568
|
try{try{await a.default.access(e.fullSource)}catch(t){throw Error("Source path not accessible: "+e.source)}const r=(await a.default.stat(e.fullSource)).isDirectory()
|
|
1565
1569
|
t.isDirectory=r
|
|
1566
1570
|
const n=c.default.dirname(e.fullDestination)
|
|
1567
|
-
try{await a.default.mkdir(n,{recursive:!0})}catch(e){throw Error("Failed to create destination directory: "+n)}try{throw await a.default.access(e.fullDestination),Error("Destination already exists: "+e.destination)}catch(e){if(!(e instanceof Error&&e.message.includes("ENOENT")))throw e}await a.default.rename(e.fullSource,e.fullDestination),t.success=!0,A++,f.info("Successfully moved "+(r?"directory":"file"),{source:e.source,destination:e.destination,isDirectory:r})}catch(r){t.error=(0,
|
|
1568
|
-
|
|
1571
|
+
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
|
|
1572
|
+
g.recordValue("move_files_time",F),g.incrementCounter("move_files_operations_total",u.length),g.incrementCounter("move_files_operations_success",A),g.incrementCounter("move_files_operations_failed",u.length-A),A===u.length?g.incrementCounter("move_files_success",1):A>0?g.incrementCounter("move_files_partial_success",1):g.incrementCounter("move_files_total_failure",1)
|
|
1569
1573
|
let N=null
|
|
1570
|
-
if(A>0){I=l.FileOperationPhase.GIT_COMMIT,
|
|
1574
|
+
if(A>0){I=l.FileOperationPhase.GIT_COMMIT,g.incrementCounter("move_files_phase",1,{phase:I})
|
|
1571
1575
|
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}`
|
|
1572
|
-
N=await l.commitToGit(E,T[0].destination,O,$,t,r,f,
|
|
1576
|
+
N=await l.commitToGit(E,T[0].destination,O,$,t,r,f,g,k.metricsPrefix)}I=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,g.incrementCounter("move_files_phase",1,{phase:I})
|
|
1573
1577
|
const z=D.filter((e=>e.success)),L=D.filter((e=>!e.success))
|
|
1574
|
-
await l.updateFileOperationRecords(E,w,b,T[0].source,k.recordType,A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,{status:A===u.length?"completed":"partial_success",commitHash:N?.commitHash,previousCommitHash:N?.previousCommitHash,operationCount:u.length,successCount:A,failureCount:u.length-A,successfulOperations:z.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:L.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,n,o,f,
|
|
1578
|
+
await l.updateFileOperationRecords(E,w,b,T[0].source,k.recordType,A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,{status:A===u.length?"completed":"partial_success",commitHash:N?.commitHash,previousCommitHash:N?.previousCommitHash,operationCount:u.length,successCount:A,failureCount:u.length-A,successfulOperations:z.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:L.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,n,o,f,g,k.metricsPrefix)
|
|
1575
1579
|
const H=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1576
1580
|
let B=""
|
|
1577
1581
|
if(A===u.length)B=`Successfully moved all ${u.length} ${1===u.length?"item":"items"}`
|
|
1578
1582
|
else if(A>0){const e=D.filter((e=>!e.success))
|
|
1579
1583
|
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")
|
|
1580
1584
|
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
|
|
1581
|
-
await o.createToolRecord({...n?{}:{taskId:e.taskId},projectId:r.projectId,type:"move-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment,error:(0,
|
|
1582
|
-
if(
|
|
1583
|
-
try{await l.updateFileOperationRecords(e.taskId,w,b,e.operations?.[0]?.source||"unknown",k.recordType,"Failed to move files",{status:"failed",error:(0,
|
|
1584
|
-
const a=i(t(1943)),c=i(t(6928)),l=s(t(5967)),d=t(9860),u=t(1569),h=t(7478),
|
|
1585
|
+
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
|
|
1586
|
+
if(g.recordValue("move_files_time",s),g.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
|
|
1587
|
+
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,g,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,g,e,k)}}
|
|
1588
|
+
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"
|
|
1585
1589
|
module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){"use strict"
|
|
1586
1590
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1587
1591
|
const r=t(6183),n=t(3707)
|
|
@@ -1589,7 +1593,7 @@ exports.def={name:"quick_manage",description:"WHEN TO USE: trivial single-file e
|
|
|
1589
1593
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildTaskEndpoint=function(e,t,r){const n=r?"/"+r.replace(/^\//,""):""
|
|
1590
1594
|
return`/api/projects/${e}/tasks/${encodeURIComponent(t)}${n}`}},2462(e,exports,t){"use strict"
|
|
1591
1595
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
1592
|
-
const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),
|
|
1596
|
+
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),g=t(4805),m=t(260),f=t(2283),y=t(4165),w=t(7834),b=t(9373),I=t(6111),k=t(700),v=t(1535),C=t(7257),_=t(9230),E=t(4150),S=t(6473),T=t(6309),q=t(4921),P=t(8850),j=t(3556),R=t(1391),x=t(6315),M=t(7713),O=t(6252),$=t(213),D=t(7250),A=t(2425),F=t(1540),N=t(5767),z=t(4973),L=t(509),H=t(7613),B=t(8456),U=t(3322),G=t(5247),W=t(8849),V=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(p.def),(0,r.registerTool)(g.def),(0,r.registerTool)(m.def),(0,r.registerTool)(f.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(b.def),(0,r.registerTool)(I.def),(0,r.registerTool)(k.def),(0,r.registerTool)(v.def),(0,r.registerTool)(E.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(q.def),(0,r.registerTool)(P.def),(0,r.registerTool)(j.def),(0,r.registerTool)(R.def),(0,r.registerTool)(x.def),(0,r.registerTool)(M.def),(0,r.registerTool)(O.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(z.def),(0,r.registerTool)(L.def),(0,r.registerTool)(H.def),(0,r.registerTool)(B.def),(0,r.registerTools)(U.metaDefs),(0,r.registerTools)(G.testingDefs),(0,r.registerTools)(W.checkingDefs),(0,r.registerTools)(V.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
|
|
1593
1597
|
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"
|
|
1594
1598
|
async function r(e,t,r){if(v.has(r)&&C>=t){if(0===t)return 0
|
|
1595
1599
|
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]"
|
|
@@ -1613,12 +1617,12 @@ case"size":s||"number"!=typeof o.size||(l+=` (${function(e){if(0===e)return"0 by
|
|
|
1613
1617
|
let t=e,r=0
|
|
1614
1618
|
for(;t>=1024&&4>r;)t/=1024,r++
|
|
1615
1619
|
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[]
|
|
1616
|
-
try{const{fullPath:d}=b.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),
|
|
1617
|
-
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=b.validateAndNormalizePath(u,t),
|
|
1620
|
+
try{const{fullPath:d}=b.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),p=[]
|
|
1621
|
+
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=b.validateAndNormalizePath(u,t),g=await y.default.stat(h),m=d.isFile()?w.default.extname(d.name).toLowerCase():""
|
|
1618
1622
|
let f
|
|
1619
|
-
d.isFile()&&(f=await r(h,
|
|
1620
|
-
const I={name:d.name,isDirectory:d.isDirectory(),depth:n,size:
|
|
1621
|
-
d.isDirectory()&&(s-1>n?(I.children=await o(u,t,n+1,s,i,l),I.children&&I.children.length>0&&(I.subtreeTotals=c(I.children))):I.subtreeTotals=await a(u,t,l)),
|
|
1623
|
+
d.isFile()&&(f=await r(h,g.size,m))
|
|
1624
|
+
const I={name:d.name,isDirectory:d.isDirectory(),depth:n,size:g.size,modified:g.mtime,extension:m,lineCount:f}
|
|
1625
|
+
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""
|
|
1622
1626
|
const o=[]
|
|
1623
1627
|
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?"/":""
|
|
1624
1628
|
if(o.push(`${r}${l}${d}${u}`),i.children&&i.children.length>0){const e=r+(c?" ":"\u2502 "),n=s(i.children,t,e)
|
|
@@ -1641,21 +1645,21 @@ case"size":const t=e.size||0,n=r.size||0
|
|
|
1641
1645
|
return t!==n?n-t:e.name.localeCompare(r.name)
|
|
1642
1646
|
case"type":const o=e.extension||"",s=r.extension||""
|
|
1643
1647
|
return o!==s?o.localeCompare(s):e.name.localeCompare(r.name)
|
|
1644
|
-
default:return e.name.localeCompare(r.name)}}))}var h,
|
|
1648
|
+
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)
|
|
1645
1649
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1646
|
-
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),
|
|
1650
|
+
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]}),g=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),m=this&&this.__importStar||(h=function(e){return h=Object.getOwnPropertyNames||function(e){var t=[]
|
|
1647
1651
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
1648
1652
|
return t},h(e)},function(e){if(e&&e.__esModule)return e
|
|
1649
1653
|
var t={}
|
|
1650
|
-
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&
|
|
1651
|
-
return
|
|
1654
|
+
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&p(t,e,r[n])
|
|
1655
|
+
return g(t,e),t}),f=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1652
1656
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
|
|
1653
|
-
let
|
|
1657
|
+
let p=b.FileOperationPhase.VALIDATION
|
|
1654
1658
|
b.FileOperationPhase.FILE_WRITE
|
|
1655
|
-
try{const
|
|
1659
|
+
try{const g=e,{path:m,levels:f=1,sortBy:I="name"}=g
|
|
1656
1660
|
i.info("Listing directory: "+m)
|
|
1657
1661
|
const{normalizedPath:v,fullPath:C}=b.validateAndNormalizePath(m,t)
|
|
1658
|
-
|
|
1662
|
+
p=b.FileOperationPhase.FILE_WRITE
|
|
1659
1663
|
try{if(!(await y.default.stat(C)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+m}],isError:!0}
|
|
1660
1664
|
await y.default.access(C,y.default.constants.R_OK)}catch(e){return e instanceof Error&&"ENOENT"===e.code?{content:[{type:"text",text:"Directory does not exist: "+m}],isError:!0}:e instanceof Error&&"EACCES"===e.code?{content:[{type:"text",text:"Directory not accessible: "+m}],isError:!0}:{content:[{type:"text",text:"Cannot access directory: "+m}],isError:!0}}let _,E
|
|
1661
1665
|
if(f>1){i.info(`Building tree structure for: ${v} (levels: ${f}, sortBy: ${I})`)
|
|
@@ -1781,40 +1785,40 @@ return(0,n.safeGetResponseData)(i,[],this.logger)}async expirePendingQuestions()
|
|
|
1781
1785
|
this.logger.info("Expiring pending questions")
|
|
1782
1786
|
const t=await this.requestWithRetry("POST",`/api/projects/${e}/session-messages/expire`,{})
|
|
1783
1787
|
return(0,n.safeGetResponseData)(t,{expiredCount:0},this.logger).expiredCount}}exports.SessionMessageClient=o},2736(e,exports,t){"use strict"
|
|
1784
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,l,d,u,h){const
|
|
1785
|
-
|
|
1786
|
-
const
|
|
1788
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,l,d,u,h){const p=u.child({tool:"complete_task"})
|
|
1789
|
+
p.info("Completing task",{args:e})
|
|
1790
|
+
const g=h.startTimer("tool_handler_duration")
|
|
1787
1791
|
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)
|
|
1788
1792
|
throw new r.ValidationError("Invalid input: "+(0,a.getErrorMessage)(e))}}(e)
|
|
1789
1793
|
let u=o.taskId
|
|
1790
|
-
const m=o.summary;(0,c.isTaskRef)(u)&&(u=await(0,c.resolveTaskRef)(u,d,
|
|
1794
|
+
const m=o.summary;(0,c.isTaskRef)(u)&&(u=await(0,c.resolveTaskRef)(u,d,p))
|
|
1791
1795
|
const f=l.projectId
|
|
1792
1796
|
if(!f)throw new r.ValidationError("Project ID is required for completing tasks with the new API structure")
|
|
1793
1797
|
h.incrementCounter("complete_task_attempts",1,{taskId:u}),d.setProjectId(f)
|
|
1794
1798
|
const y=d.getTaskClient()
|
|
1795
1799
|
let w
|
|
1796
1800
|
try{const e=await y.getTask(u)
|
|
1797
|
-
|
|
1798
|
-
const t=(0,s.extractDataFromResponse)(e,{logger:
|
|
1799
|
-
w="data"in t?t.data:t,
|
|
1801
|
+
p.info("Raw task response data",{responseData:JSON.stringify(e)}),p.debug("Task response structure",{type:typeof e,isArray:Array.isArray(e),hasData:null!=e,properties:e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"})
|
|
1802
|
+
const t=(0,s.extractDataFromResponse)(e,{logger:p,operationName:"getTask",throwOnNoData:!0})
|
|
1803
|
+
w="data"in t?t.data:t,p.info("Current task status: "+w.status,{taskId:u,currentStatus:w.status})}catch(e){if(e instanceof r.ValidationError)throw e
|
|
1800
1804
|
throw new r.NotFoundError(`Task ${(0,c.formatTaskRefForAgent)(u)} not found in project ${f}. Please provide a valid task ID.`,{taskId:u,projectId:f,originalError:e})}if("completed"===w.status){const e="Task is already completed."
|
|
1801
|
-
throw
|
|
1802
|
-
throw
|
|
1805
|
+
throw p.warn(e,{taskId:u,currentStatus:w.status}),new r.ValidationError(e)}if("canceled"===w.status){const e="Task is canceled and can not be completed."
|
|
1806
|
+
throw p.warn(e,{taskId:u,currentStatus:w.status}),new r.ValidationError(e)}let b=l.git
|
|
1803
1807
|
if(l.workspaceManager){const e=l.workspaceManager.getCurrentContext(l.currentSessionId)
|
|
1804
1808
|
if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
|
|
1805
|
-
b=simpleGit({baseDir:e.basePath,binary:l.gitBinary}),
|
|
1806
|
-
if(b)try{(await b.status()).isClean()||(I=(await b.commit(`Complete task ${u}: ${m}`)).commit,
|
|
1809
|
+
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
|
|
1810
|
+
if(b)try{(await b.status()).isClean()||(I=(await b.commit(`Complete task ${u}: ${m}`)).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
|
|
1807
1811
|
try{const e=d.getToolRecordClient()
|
|
1808
|
-
e&&(k={id:(await e.createToolRecord({taskId:u,requestId:w.requestId,projectId:f,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:m,lastCommit:I,completedAt:(new Date).toISOString()},note:`Completed task: ${m.substring(0,100)}${m.length>100?"...":""}`})).id})}catch(e){
|
|
1809
|
-
|
|
1812
|
+
e&&(k={id:(await e.createToolRecord({taskId:u,requestId:w.requestId,projectId:f,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:m,lastCommit:I,completedAt:(new Date).toISOString()},note:`Completed task: ${m.substring(0,100)}${m.length>100?"...":""}`})).id})}catch(e){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:m,completionRecordId:k?.id,completedAt:t}},o=await y.updateTask(u,r)
|
|
1813
|
+
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})
|
|
1810
1814
|
const i=w.requestId,l=w.requestId
|
|
1811
1815
|
let d=`Task ${w.sequenceNumber&&l?(0,c.formatTaskRef)(l,w.sequenceNumber):u} (${w.title}) has been marked as completed.`
|
|
1812
1816
|
if(I&&(d+="\nCommit: "+I.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
|
|
1813
|
-
|
|
1814
|
-
const t=(0,s.extractArrayFromResponse)(e,{logger:
|
|
1815
|
-
|
|
1817
|
+
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"})
|
|
1818
|
+
const t=(0,s.extractArrayFromResponse)(e,{logger:p,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
|
|
1819
|
+
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 g({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()
|
|
1816
1820
|
if(n){const o=t instanceof r.NotFoundError||t instanceof r.ValidationError||t instanceof i.ZodError
|
|
1817
|
-
await n.createToolRecord({...o?{}:{taskId:e.taskId},projectId:l.projectId,type:"complete-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.summary?.substring(0,100)+(e.summary?.length>100?"...":""),error:(0,a.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",attemptedTaskId:e.taskId,taskIdValidationFailed:o},note:"Failed to complete task "+e.taskId})}}catch(e){
|
|
1821
|
+
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+""})}g({success:!1,error:t instanceof Error?t.name:"unknown"})
|
|
1818
1822
|
let n=(0,a.getErrorMessage)(t)
|
|
1819
1823
|
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}}}
|
|
1820
1824
|
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"
|
|
@@ -1823,19 +1827,19 @@ if(!r())return t.level=(0,l.isDevBuild)()?c.LogLevel.INFO:c.LogLevel.ERROR,t.log
|
|
|
1823
1827
|
if("true"===process.env.DEBUG_LOGGING?.toLowerCase()){t.level=c.LogLevel.DEBUG,t.logToFile=!0
|
|
1824
1828
|
const r=e||process.cwd()
|
|
1825
1829
|
t.logFilePath=i.default.join(r,"logs","debug.log")}const n=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
1826
|
-
return n&&Object.values(c.LogLevel).includes(n)&&(t.level=n),t}(e.baseDir),...e},{level:o=c.LogLevel.INFO,serviceName:
|
|
1827
|
-
if(console&&f.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),
|
|
1830
|
+
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:g=!1,logFilePath:m="./logs/app.log",console=!0}=t,f=[]
|
|
1831
|
+
if(console&&f.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),g){!function(e){const t=i.default.dirname(e)
|
|
1828
1832
|
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(m)
|
|
1829
1833
|
const e=o===c.LogLevel.DEBUG&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()
|
|
1830
|
-
f.push(new s.default.transports.File({filename:m,format:e?h:u}))}const y=s.default.createLogger({level:o,defaultMeta:{service:
|
|
1831
|
-
return o===c.LogLevel.DEBUG&&
|
|
1832
|
-
return{error(e,t){r.error(e,t)},warn(e,t){r.warn(e,t)},info(e,t){r.info(e,t)},debug(e,t){r.debug(e,t)},child(e){return n({...t,serviceName:`${
|
|
1834
|
+
f.push(new s.default.transports.File({filename:m,format:e?h:u}))}const y=s.default.createLogger({level:o,defaultMeta:{service:p},transports:f})
|
|
1835
|
+
return o===c.LogLevel.DEBUG&&g&&r()&&y.info("Enhanced logging initialized",{level:o,serviceName:p,logToFile:g,logFilePath:m,debugLogging:process.env.DEBUG_LOGGING}),{error(e,t){y.error(e,t)},warn(e,t){y.warn(e,t)},info(e,t){y.info(e,t)},debug(e,t){y.debug(e,t)},child(e){const r=y.child(e)
|
|
1836
|
+
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}}
|
|
1833
1837
|
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
|
|
1834
1838
|
const e=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
1835
1839
|
return e&&Object.values(c.LogLevel).includes(e)?e:c.LogLevel.INFO}
|
|
1836
1840
|
const s=o(t(5124)),i=o(t(6928)),a=o(t(9896)),c=t(6540),l=t(7960),d=s.default.format.combine(s.default.format.timestamp(),s.default.format.colorize(),s.default.format.printf((({level:e,message:t,timestamp:r,...n})=>`${r} [${e}]: ${t}${Object.keys(n).length?" "+JSON.stringify(n,null,0):""}`))),u=s.default.format.combine(s.default.format.timestamp(),s.default.format.json()),h=s.default.format.combine(s.default.format.timestamp(),s.default.format.printf((({level:e,message:t,timestamp:r,service:n,component:o,...s})=>{const i=n?`[${n}]`:"",a=o?`[${o}]`:"",c=Object.keys(s).length?" "+JSON.stringify(s,null,2):""
|
|
1837
|
-
return`${r} ${i}${a} [${e.toUpperCase()}]: ${t}${c}`}))),
|
|
1838
|
-
exports.default=
|
|
1841
|
+
return`${r} ${i}${a} [${e.toUpperCase()}]: ${t}${c}`}))),p=n({logToFile:!1,console:!0,level:c.LogLevel.INFO})
|
|
1842
|
+
exports.default=p},2903(e,exports,t){"use strict"
|
|
1839
1843
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
1840
1844
|
const r=t(6183),n=t(9442)
|
|
1841
1845
|
exports.def={name:"replace_in_files",description:'Replace text in multiple files/documents with progressive fuzzy matching in batch operations.\n\nAPI:\n\u2022 operations (required) - Array of file operations\n - path or documentId (required per operation) - Target file or document\n - replacements (required) - Array of {old, new, match_mode?} replacements\n - fuzzy_match (optional) - Override global fuzzy setting for this file\n\u2022 fuzzy_match (optional, default true) - Global fuzzy matching default\n\u2022 comment (required) - Description of changes\n\nSTRUCTURE: Each operation MUST contain a `replacements` array. Do NOT put old/new directly on the operation object.\n\nFUZZY MATCHING (progressive strategies):\n1. exact - Literal match\n2. whitespace_normalized - Collapse/trim whitespace\n3. whitespace_agnostic - Ignore all whitespace\n\nMATCH MODES (per replacement):\n\u2022 \'unique\' (default, safe) - Must find exactly 1 match. Fails with helpful candidates if multiple found.\n\u2022 \'all\' - Replaces all occurrences, returns details for each\n\nRETURNS:\nPer-operation, per-replacement results with line numbers, match types, and success/error details.\n\nEXAMPLES:\n- Single file: {"operations": [{"path": "file.ts", "replacements": [{"old": "oldAPI", "new": "newAPI"}]}], "comment": "Update API"}\n- Multi-file: {"operations": [{"path": "a.ts", "replacements": [...]}, {"path": "b.ts", "replacements": [...]}], "comment": "Refactor"}',schema:r.ReplaceInFilesSchema,annotations:{title:"Replace In Files (Fuzzy Batch)",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},createsRecords:!0,handler(e,t){return(0,n.handleReplaceInFiles)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},2960(e,exports){"use strict"
|
|
@@ -1886,17 +1890,17 @@ i.info("Request breakdown",{fileRequests:d.length,documentRequests:u.length})
|
|
|
1886
1890
|
const h=[]
|
|
1887
1891
|
for(const e of d)h.push(r(e,t,0,l))
|
|
1888
1892
|
for(const e of u)h.push(n(e,t,0,l))
|
|
1889
|
-
const
|
|
1893
|
+
const g=await Promise.all(h)
|
|
1890
1894
|
let m=""
|
|
1891
1895
|
if(t.workspaceManager)try{const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
1892
|
-
e.branchName&&!e.permanentBranch&&(m=`**Current Branch:** ${e.branchName}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const f=
|
|
1896
|
+
e.branchName&&!e.permanentBranch&&(m=`**Current Branch:** ${e.branchName}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const f=g.filter((e=>e.success)).length,y=g.filter((e=>!e.success)).length,w=g.length
|
|
1893
1897
|
let b="## Read Files/Documents\n\n"
|
|
1894
1898
|
m&&(b+=m),b+=`**Total Requests:** ${w} - **Successful:** ${f} - **Failed:** ${y}\n\n`
|
|
1895
|
-
for(let e=0;e<
|
|
1899
|
+
for(let e=0;e<g.length;e++){const t=g[e]
|
|
1896
1900
|
"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
|
|
1897
|
-
return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:w,successfulReads:f,failedReads:y,success:I}),s.incrementCounter("read_files_total",1,{success:I}),{content:[{type:"text",text:b}],...(0,
|
|
1901
|
+
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
|
|
1898
1902
|
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}}}
|
|
1899
|
-
const l=c(t(1943)),d=a(t(5967)),u=t(9470),h=t(8824),
|
|
1903
|
+
const l=c(t(1943)),d=a(t(5967)),u=t(9470),h=t(8824),p=t(2272)},2968(e,exports,t){"use strict"
|
|
1900
1904
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.TaskClient=void 0
|
|
1901
1905
|
const r=t(8824),n=t(7645),o=t(2161),s=t(2450)
|
|
1902
1906
|
class i extends n.ConnectionAwareClient{async createTask(e){if(this.logger.debug("Creating task",{taskInput:e}),!e.projectId){const t=this.projectClient.getProjectId()
|
|
@@ -1974,9 +1978,9 @@ throw c.error(`STRICT VALIDATION - File operation blocked on ${u.status} request
|
|
|
1974
1978
|
const n=(0,s.getErrorMessage)(r)
|
|
1975
1979
|
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
|
|
1976
1980
|
const n=(0,s.getErrorMessage)(r)
|
|
1977
|
-
throw c.error("Could not validate work item states for task "+e,{taskId:e,path:t,error:n}),l.incrementCounter(d+"_state_validation_error",1),new o.ValidationError("Could not validate work item states: "+n,{taskId:e,path:t,originalError:r})}},exports.autoPromoteTaskStatus=async function(e,t,r,o,i,a,c,l,d,u){try{let s,h,
|
|
1978
|
-
if("pending"===t&&(l.info(`Auto-promoting task ${e} from pending to in_progress`,{taskId:e,currentStatus:t,path:i}),await a.updateTaskStatus(e,"in_progress"),l.info(`Successfully auto-promoted task ${e} to in_progress`,{taskId:e,previousStatus:t,newStatus:"in_progress",path:i}),d.incrementCounter(u+"_auto_promotion_success",1),
|
|
1979
|
-
|
|
1981
|
+
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,g=!1
|
|
1982
|
+
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)
|
|
1983
|
+
g=t.promoted,h=t.newStatus}return{taskPromoted:p,newTaskStatus:s,requestPromoted:g,newRequestStatus:h}}catch(r){const n=(0,s.getErrorMessage)(r)
|
|
1980
1984
|
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})
|
|
1981
1985
|
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})
|
|
1982
1986
|
const t=`Cannot complete request ${e} - no tasks found. Create tasks for this request before attempting completion.`
|
|
@@ -2003,7 +2007,7 @@ l.info("Generating journal for request",{requestId:a})
|
|
|
2003
2007
|
const u=t.projectId
|
|
2004
2008
|
if(!u)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
|
|
2005
2009
|
o.setProjectId(u),l.info("Fetching request data, tasks, and file history in parallel")
|
|
2006
|
-
const h=o.getRequestClient(),
|
|
2010
|
+
const h=o.getRequestClient(),p=o.getTaskClient(),g=o.getToolRecordClient(),[m,f,y]=await Promise.all([h.getRequest(a),p.listTasks({requestId:a}),g.getToolRecordsByRequestId(a).catch((e=>(l.warn("Failed to fetch tool records",{error:e+""}),[])))]),w=(0,s.extractDataFromResponse)(m,{logger:l,operationName:"getRequest",throwOnNoData:!0}),b="data"in w?w.data:w,I={id:b.id||a,title:b.title||"Unknown Request",description:b.description||"No description available",status:b.status||"unknown",type:b.type||"unknown",acceptanceCriteria:b.acceptanceCriteria||[],createdAt:b.createdAt||(new Date).toISOString(),updatedAt:b.updatedAt||(new Date).toISOString(),completedAt:b.completedAt},k=(0,s.extractDataFromResponse)(f,{logger:l,operationName:"listTasks",throwOnNoData:!1}),v=(Array.isArray(k)?k:"data"in k?k.data:[]).map((e=>({id:e.id,title:e.title||"Untitled Task",description:e.description||"No description",status:e.status||"unknown",createdAt:e.createdAt||(new Date).toISOString(),completedAt:e.metadata?.completedAt})))
|
|
2007
2011
|
l.info(`Fetched request, ${v.length} tasks, ${y.length} tool records`)
|
|
2008
2012
|
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()))
|
|
2009
2013
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
@@ -2031,7 +2035,7 @@ var o=Object.getOwnPropertyDescriptor(t,r)
|
|
|
2031
2035
|
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),n=this&&this.__exportStar||function(e,exports){for(var t in e)"default"===t||{}.hasOwnProperty.call(exports,t)||r(exports,e,t)}
|
|
2032
2036
|
Object.defineProperty(exports,"__esModule",{value:!0}),n(t(4118),exports),n(t(5498),exports),n(t(1178),exports),n(t(1266),exports),n(t(4628),exports)},3247(e,exports,t){"use strict"
|
|
2033
2037
|
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))
|
|
2034
|
-
return{active:s?r(s):null,nextPending:i?r(i):null}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTasks=async function(e,t,d,u,h,
|
|
2038
|
+
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 g=u.child({tool:"tasks"}),{operation:m}=e
|
|
2035
2039
|
try{const h=t.projectId
|
|
2036
2040
|
if(!h)throw Error("Project ID not available")
|
|
2037
2041
|
d.setProjectId(h)
|
|
@@ -2039,15 +2043,15 @@ const f=await async function(e,t,r,n){const o=n?.sessionId||e.currentSessionId
|
|
|
2039
2043
|
if(!o||"__unknown__"===o||"__server__"===o)throw Error("Cannot resolve request: no session identity available")
|
|
2040
2044
|
const i=await s.sessionIdentity.getSessionRequestId(t,r,o)
|
|
2041
2045
|
if(!i)throw Error("No request associated with session "+o)
|
|
2042
|
-
return i}(t,d,u,
|
|
2046
|
+
return i}(t,d,u,p)
|
|
2043
2047
|
switch(m){case"create":{const{title:t,description:r}=e
|
|
2044
2048
|
if(!t)return{content:[{type:"text",text:"Error: title is required for create"}],isError:!0}
|
|
2045
2049
|
if(!r)return{content:[{type:"text",text:"Error: description is required for create"}],isError:!0}
|
|
2046
2050
|
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
|
|
2047
|
-
let
|
|
2048
|
-
if(!s)try{await n.updateTaskStatus(u,"in_progress"),
|
|
2051
|
+
let p=!1
|
|
2052
|
+
if(!s)try{await n.updateTaskStatus(u,"in_progress"),p=!0}catch(e){g.debug("Could not auto-start task",{taskId:u,error:(0,i.getErrorMessage)(e)})}const m=a.sequenceNumber??null
|
|
2049
2053
|
let y=m?`Created #${m}: ${t}`:`Created ${(0,l.formatTaskRefForAgent)(u)}: ${t}`
|
|
2050
|
-
return
|
|
2054
|
+
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
|
|
2051
2055
|
if(!t)return{content:[{type:"text",text:"Error: summary is required for done"}],isError:!0}
|
|
2052
2056
|
const{active:r,nextPending:n}=await o(d,f)
|
|
2053
2057
|
if(!r)return{content:[{type:"text",text:"No active (in_progress) task to complete."}],isError:!0}
|
|
@@ -2057,7 +2061,7 @@ const u=r.sequenceNumber
|
|
|
2057
2061
|
let h=u?`Completed #${u}: ${r.title}`:`Completed ${(0,l.formatTaskRefForAgent)(r.taskId)}: ${r.title}`
|
|
2058
2062
|
if(n)try{await s.updateTaskStatus(n.taskId,"in_progress")
|
|
2059
2063
|
const e=n.sequenceNumber
|
|
2060
|
-
h+=e?`\nStarted #${e}: ${n.title}`:`\nStarted ${(0,l.formatTaskRefForAgent)(n.taskId)}: ${n.title}`}catch(e){
|
|
2064
|
+
h+=e?`\nStarted #${e}: ${n.title}`:`\nStarted ${(0,l.formatTaskRefForAgent)(n.taskId)}: ${n.title}`}catch(e){g.debug("Could not auto-start next task",{taskId:n.taskId,error:(0,i.getErrorMessage)(e)})}else h+="\nAll tasks completed."
|
|
2061
2065
|
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))
|
|
2062
2066
|
if(o){const e=r(o)
|
|
2063
2067
|
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
|
|
@@ -2072,7 +2076,7 @@ l&&await o.updateTaskStatus(l.localId||l.id,"pending"),await o.updateTaskStatus(
|
|
|
2072
2076
|
const u=r(i),h=l?` (paused ${n(r(l))}: ${l.title})`:""
|
|
2073
2077
|
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"})
|
|
2074
2078
|
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
|
|
2075
|
-
return`[${"in_progress"===e.status?"\u25b6 in_progress":e.status}] #${r}: ${e.title}`})).join("\n")}],...(0,c.alchemyMeta)({kind:"list-tasks"})}}default:return{content:[{type:"text",text:"Unknown operation: "+m}],isError:!0}}}catch(e){return
|
|
2079
|
+
return`[${"in_progress"===e.status?"\u25b6 in_progress":e.status}] #${r}: ${e.title}`})).join("\n")}],...(0,c.alchemyMeta)({kind:"list-tasks"})}}default:return{content:[{type:"text",text:"Unknown operation: "+m}],isError:!0}}}catch(e){return g.error("tasks operation failed",{operation:m,error:(0,i.getErrorMessage)(e)}),{content:[{type:"text",text:"Error: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
|
|
2076
2080
|
const s=t(6688),i=t(8824),a=t(3451),c=t(2272),l=t(4466)},3253(e,exports){"use strict"
|
|
2077
2081
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTimestamp=function(e,t){const r=e instanceof Date?e:new Date(e)
|
|
2078
2082
|
if(isNaN(r.getTime()))return"Invalid date"
|
|
@@ -2149,7 +2153,7 @@ R.push({type:"file",path:t,fullPath:n,replacements:e.replacements,mode:e.mode||"
|
|
|
2149
2153
|
if(j.length>0&&!r.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
2150
2154
|
for(const e of j)x.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
|
|
2151
2155
|
if(x.length>0&&r.apiClient){const e=x.map((e=>e.documentId))
|
|
2152
|
-
try{await(0,
|
|
2156
|
+
try{await(0,g.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}
|
|
2153
2157
|
throw e}}k=d.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
2154
2158
|
const M=R.length>0?R[0].path:"document-operation",O=await d.validateTaskId(q,M,o,y,c,v.metricsPrefix),$=O?.requestId
|
|
2155
2159
|
let D=null
|
|
@@ -2164,7 +2168,7 @@ R[e]={...t,path:o,fullPath:s}}}if(x.length>0&&$)try{await(0,h.validateRequestSta
|
|
|
2164
2168
|
throw e}k=d.FileOperationPhase.RECORD_CREATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
2165
2169
|
const N=[...R.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...x.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:z}=await d.createFileOperationRecords(q,$,r.projectId,v.recordType,M,{operationCount:_.length,fileOperations:R.length,documentOperations:x.length,operations:N,userComment:E},o,s,y,c,v.metricsPrefix,f)
|
|
2166
2170
|
if(b=z,I=z,k=v.fileOperationPhase,c.incrementCounter("replace_strings_phase",1,{phase:k}),R.length>0&&r.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
|
|
2167
|
-
const e=await(0,
|
|
2171
|
+
const e=await(0,p.commitUserChangesBeforeToolOperation)(r.git,"replace-strings",{requestId:$,taskId:q,workspaceManager:r.workspaceManager},y,c)
|
|
2168
2172
|
e.userChangesCommitted&&(y.debug("[REPLACE-STRINGS] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),y.info("User changes committed before replace-strings operation",{taskId:q,fileOperationsCount:R.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){y.debug("[REPLACE-STRINGS] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),y.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:q,fileOperationsCount:R.length,error:e instanceof Error?e.message:e+""})}y.debug("[REPLACE-STRINGS] Proceeding with file operations",{fileCount:R.length})
|
|
2169
2173
|
const L=[]
|
|
2170
2174
|
let H=0,B=0
|
|
@@ -2188,7 +2192,7 @@ for(const t of e.replacements.filter((e=>!e.success)))Z+=` - "${t.old_str}" \u2
|
|
|
2188
2192
|
const X=Date.now()-w
|
|
2189
2193
|
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
|
|
2190
2194
|
if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await s.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return c.incrementCounter("replace_strings_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
2191
|
-
const l=c(t(1943)),d=a(t(5967)),u=t(9860),h=t(5003),
|
|
2195
|
+
const l=c(t(1943)),d=a(t(5967)),u=t(9860),h=t(5003),p=t(7478),g=t(9949),m=t(8824)},3322(e,exports,t){"use strict"
|
|
2192
2196
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
2193
2197
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
2194
2198
|
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=[]
|
|
@@ -2222,10 +2226,10 @@ var u=t(1887)
|
|
|
2222
2226
|
Object.defineProperty(exports,"ProxyClient",{enumerable:!0,get(){return u.ProxyClient}})
|
|
2223
2227
|
var h=t(4192)
|
|
2224
2228
|
Object.defineProperty(exports,"BaseApiClient",{enumerable:!0,get(){return h.BaseApiClient}})
|
|
2225
|
-
var
|
|
2226
|
-
Object.defineProperty(exports,"SessionRequestAssociationClient",{enumerable:!0,get(){return
|
|
2227
|
-
var
|
|
2228
|
-
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return
|
|
2229
|
+
var p=t(1599)
|
|
2230
|
+
Object.defineProperty(exports,"SessionRequestAssociationClient",{enumerable:!0,get(){return p.SessionRequestAssociationClient}})
|
|
2231
|
+
var g=t(5187)
|
|
2232
|
+
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return g.CLISessionClient}})
|
|
2229
2233
|
var m=t(6539)
|
|
2230
2234
|
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return m.ClientFactory}})
|
|
2231
2235
|
const f=t(6539)
|
|
@@ -2251,14 +2255,14 @@ if(t&&"object"==typeof t&&(n="description"in t&&!!t.description),t){const e={id:
|
|
|
2251
2255
|
"id"in t&&t.id&&(e.id=t.id+""),"title"in t&&t.title&&(e.title=t.title+""),"description"in t&&void 0!==t.description&&(null===t.description?e.description="":e.description=t.description+""),"status"in t&&t.status&&(e.status=t.status),"projectId"in t&&t.projectId&&(e.projectId=t.projectId+""),"requestId"in t&&t.requestId&&(e.requestId=t.requestId+""),"createdAt"in t&&t.createdAt&&(e.createdAt=t.createdAt+""),"updatedAt"in t&&t.updatedAt&&(e.updatedAt=t.updatedAt+"")
|
|
2252
2256
|
const n=e
|
|
2253
2257
|
"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()}
|
|
2254
|
-
l.info("Retrieved task information",{taskId:r,title:h.title,status:h.status})}catch(e){throw new n.NotFoundError(`Task ${(0,s.formatTaskRefForAgent)(r)} not found in project ${a}. Please provide a valid task ID.`,{taskId:r,projectId:a,originalError:e})}let
|
|
2258
|
+
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
|
|
2255
2259
|
if(h.requestId)try{const e=i.getRequestClient()
|
|
2256
|
-
|
|
2260
|
+
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 g=e=>{if(!e)return"Unknown date"
|
|
2257
2261
|
try{const t=new Date(e)
|
|
2258
|
-
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},m=
|
|
2262
|
+
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},m=g(h.createdAt),f=g(h.updatedAt),y=h.requestId||h.requestLocalId,w=h.sequenceNumber&&y?(0,s.formatTaskRef)(y,h.sequenceNumber):r,b=(0,s.formatTaskRefForAgent)(w)
|
|
2259
2263
|
let I=`# Task: ${h.title} (${b})\n\n`
|
|
2260
|
-
if(I+=`**Status**: ${h.status}\n`,I+=`**Created**: ${m}\n`,I+=`**Updated**: ${f}\n`,h.requestId&&(I+="**Parent Request**: "+h.requestId,I+=
|
|
2261
|
-
I+="\n## Metadata\n\n",e.lastCommit&&(I+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(I+=`**Completed At**: ${
|
|
2264
|
+
if(I+=`**Status**: ${h.status}\n`,I+=`**Created**: ${m}\n`,I+=`**Updated**: ${f}\n`,h.requestId&&(I+="**Parent Request**: "+h.requestId,I+=p?` (${p.title})\n`:"\n"),h.metadata){const e=h.metadata
|
|
2265
|
+
I+="\n## Metadata\n\n",e.lastCommit&&(I+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(I+=`**Completed At**: ${g(e.completedAt)}\n`),e.completionSummary&&(I+=`**Completion Summary**: ${e.completionSummary}\n`)
|
|
2262
2266
|
const t=["lastCommit","completedAt","completionSummary"]
|
|
2263
2267
|
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})
|
|
2264
2268
|
try{const n=i.getToolRecordClient()
|
|
@@ -2296,7 +2300,7 @@ const r=t(6183),n=t(8317)
|
|
|
2296
2300
|
exports.def={name:"request_file_history",description:"Get file change history for an entire request. Supports summary mode (net diffs) or detailed mode (chronological operations). Can be filtered to specific task. Use query_history tool instead.",schema:r.QueryHistorySchema,annotations:{title:"Request File History",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleRequestFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}},3611(e,exports,t){"use strict"
|
|
2297
2301
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2298
2302
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
2299
|
-
const n=r(t(6928)),o=r(t(7252)),s=r(t(8577)),i=t(184),a=t(1213),c=t(3444),l=t(9955),d=t(2568),u=t(3102),h=t(1152),
|
|
2303
|
+
const n=r(t(6928)),o=r(t(7252)),s=r(t(8577)),i=t(184),a=t(1213),c=t(3444),l=t(9955),d=t(2568),u=t(3102),h=t(1152),p=t(3884),g=t(7888),m=t(4139),f=t(6800),y=t(6539),w=t(8824),b=t(6975),I=t(1253),k=process.argv.slice(2),v=k[0]||process.cwd(),C=n.default.resolve(v),_=parseInt(process.env.LOCAL_SERVER_PORT||k[1]||"3002",10),E=(0,c.createEnvLogger)({serviceName:"mcp-http-server"});(0,c.isDebugToolsEnabled)()?E.info("HTTP server initializing",{baseDir:C,preferredPort:_,debugLogging:process.env.DEBUG_LOGGING,debugLevel:process.env.DEBUG_LEVEL}):E.info("HTTP server starting",{port:_})
|
|
2300
2304
|
const S=(0,h.createMetricsCollector)(!0),T=(process.env.REMOTE_SERVER_PORT,process.env.REMOTE_SERVER_HOST,process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com")
|
|
2301
2305
|
E.info("Using remote server URL",{remoteServerUrl:T}),async function(){try{E.info("Finding available port...",{preferredPort:_,baseDir:C,remoteServerUrl:T})
|
|
2302
2306
|
const e=await(0,f.findAvailablePort)(_)
|
|
@@ -2306,14 +2310,14 @@ E.info(`Checking ${m.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensur
|
|
|
2306
2310
|
const h=new I.TokenManager(E,n.default.join(c,"auth-token.json")),k=(await y.ClientFactory.createClient(T,E,S,{tokenManager:h,workingDir:C,alchemyPath:c})).projectClient,v=new b.ProjectClientAdapter(k,E),q=new d.ProjectSynchronizer(E,t,v,r),P=await q.getOrCreateProject(C,{name:n.default.basename(C)||"Local Project",description:"Project for "+n.default.basename(C),status:"active",metadata:{basePath:C,alchemyPath:c,bootstrapped:!0}})
|
|
2307
2311
|
E.info("Using project",{projectId:P.id,projectName:P.name})
|
|
2308
2312
|
const j=(0,o.default)()
|
|
2309
|
-
j.use((0,s.default)()),j.use(o.default.json({limit:"50mb"})),j.use(o.default.urlencoded({extended:!0})),j.use((0,
|
|
2313
|
+
j.use((0,s.default)()),j.use(o.default.json({limit:"50mb"})),j.use(o.default.urlencoded({extended:!0})),j.use((0,p.requestLogger)(E))
|
|
2310
2314
|
try{E.info("Creating MCP server instance")
|
|
2311
2315
|
const t=await(0,i.createServer)(C,E,S,T,{existingProjectId:P.id})
|
|
2312
2316
|
E.info("MCP server instance created successfully")
|
|
2313
2317
|
const r=t.getContext()
|
|
2314
|
-
E.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(E.info("Adding connection status middleware"),j.use((0,
|
|
2318
|
+
E.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(E.info("Adding connection status middleware"),j.use((0,g.addConnectionStatusInfo)(t.connectionManager))):E.warn("Unable to add connection status middleware - connection manager not available")
|
|
2315
2319
|
try{const e=P.id
|
|
2316
|
-
E.info("Setting up project context middleware",{projectId:e}),j.use("/api",((t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}))}catch(e){E.warn("Failed to set up project context middleware",{error:(0,w.getErrorMessage)(e)})}(0,a.registerApiRoutes)(j,t,E,S),j.use((0,
|
|
2320
|
+
E.info("Setting up project context middleware",{projectId:e}),j.use("/api",((t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}))}catch(e){E.warn("Failed to set up project context middleware",{error:(0,w.getErrorMessage)(e)})}(0,a.registerApiRoutes)(j,t,E,S),j.use((0,p.errorHandler)(E,S)),j.listen(e,(()=>{E.info("HTTP API server listening on port "+e,{baseDir:C,port:e,nodeVersion:process.version})}))}catch(e){E.error("Failed to create or initialize MCP server",{error:e instanceof Error?e.stack:e+""})
|
|
2317
2321
|
let t=!1
|
|
2318
2322
|
e instanceof Error&&(t=e.message.includes("connection")||e.message.includes("timeout")||e.message.includes("network")||"ConnectionError"===e.name),S.incrementCounter("server_initialization_failure",1,{isConnectionError:t?"true":"false"}),j.use(((e,t,r)=>{t.set("X-Connection-Status","offline"),t.set("X-Server-Initialization-Failed","true"),r()})),j.use("/api",((t,r)=>{r.status(503).json({success:!1,error:{code:"CONNECTION_ERROR",message:"Server failed to initialize due to connection issues. Please check connectivity and try again.",details:{serverError:e instanceof Error?e.message:e+"",suggestions:["Check your network connection","Verify that the remote server is running","Try restarting the local server"],isConnectionIssue:!0},retryable:!0,statusCode:503}})})),E.warn("Continuing with limited functionality due to initialization error")}process.on("SIGINT",(()=>{E.info("Received SIGINT signal, shutting down..."),process.exit(0)})),process.on("SIGTERM",(()=>{E.info("Received SIGTERM signal, shutting down..."),process.exit(0)})),process.on("uncaughtException",(e=>{E.error("Uncaught exception",{error:e.stack}),process.exit(1)})),process.on("unhandledRejection",(e=>{E.error("Unhandled promise rejection",{reason:e}),process.exit(1)}))}catch(e){E.error("Failed to start HTTP API server",{error:e instanceof Error?e.stack:e+""}),process.exit(1)}}()},3626(e,exports,t){"use strict"
|
|
2319
2323
|
function r(e){if(!e)return!1
|
|
@@ -2339,8 +2343,8 @@ o=Math.max(o,s)}return o/Math.min(r.length,n.length)}Object.defineProperty(expor
|
|
|
2339
2343
|
let h=i(e,t)
|
|
2340
2344
|
if(h.length>0)return h
|
|
2341
2345
|
if(!a)return[]
|
|
2342
|
-
const
|
|
2343
|
-
if(
|
|
2346
|
+
const p=(0,d.tryLineBasedMatch)(e,t,5,u)
|
|
2347
|
+
if(p&&p.length>0)return p.map((e=>({line:e.startLine,actuallyMatched:e.actuallyMatched,matchType:"line_based",startPos:e.startPos,endPos:e.endPos})))
|
|
2344
2348
|
try{if(h=function(e,t,o=100,a){const c=[],l=n(t,a),d=Date.now()
|
|
2345
2349
|
if(t.length>500)return i(e,t)
|
|
2346
2350
|
const u=t.match(/^[ \t]*/)[0],h=u.length>0
|
|
@@ -2353,35 +2357,35 @@ const d=Math.min(Math.floor(.5*t.length),200),u=Math.min(r+t.length+d,e.length),
|
|
|
2353
2357
|
for(let t=i;u>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2354
2358
|
if(i.length>h)break
|
|
2355
2359
|
if(i===l){c.push({line:s+1,actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t})
|
|
2356
|
-
break}}}o+=i.length+1}return c}const
|
|
2357
|
-
if(!
|
|
2358
|
-
let
|
|
2360
|
+
break}}}o+=i.length+1}return c}const p=t.trim()[0]
|
|
2361
|
+
if(!p)return c
|
|
2362
|
+
let g=0,m=0
|
|
2359
2363
|
for(;;){if(m%100==0&&Date.now()-d>o){const r=Date.now()-d
|
|
2360
2364
|
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${o}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}m++
|
|
2361
|
-
const r=e.indexOf(g
|
|
2365
|
+
const r=e.indexOf(p,g)
|
|
2362
2366
|
if(-1===r)break
|
|
2363
2367
|
let i=r+t.length
|
|
2364
2368
|
const u=Math.min(Math.floor(.5*t.length),200),h=Math.min(r+t.length+u,e.length),f=l.length
|
|
2365
2369
|
let y=!1
|
|
2366
2370
|
for(let t=i;h>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2367
2371
|
if(i.length>f)break
|
|
2368
|
-
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),
|
|
2369
|
-
break}}y||(
|
|
2372
|
+
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),g=t,y=!0
|
|
2373
|
+
break}}y||(g=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[]
|
|
2370
2374
|
const c=[],l=o(t),d=Date.now()
|
|
2371
2375
|
if(t.length>500)return i(e,t)
|
|
2372
2376
|
if(!l)return c
|
|
2373
2377
|
const u=t.replace(/\s/g,"")[0],h=l.length
|
|
2374
|
-
let
|
|
2375
|
-
for(;;){if(
|
|
2376
|
-
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${n}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}
|
|
2377
|
-
const r=e.indexOf(u,
|
|
2378
|
+
let p=0,g=0
|
|
2379
|
+
for(;;){if(g%100==0&&Date.now()-d>n){const r=Date.now()-d
|
|
2380
|
+
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`)}g++
|
|
2381
|
+
const r=e.indexOf(u,p)
|
|
2378
2382
|
if(-1===r)break
|
|
2379
2383
|
const i=r+h,a=Math.min(t.length,300),m=Math.min(r+h+a,e.length)
|
|
2380
2384
|
let f=!1
|
|
2381
2385
|
for(let t=i;m>=t;t++){const n=e.substring(r,t),i=o(n)
|
|
2382
2386
|
if(i.length>h)break
|
|
2383
|
-
if(i===l){c.push({line:s(e,r),actuallyMatched:n,matchType:"whitespace_agnostic",startPos:r,endPos:t}),
|
|
2384
|
-
break}}f||(
|
|
2387
|
+
if(i===l){c.push({line:s(e,r),actuallyMatched:n,matchType:"whitespace_agnostic",startPos:r,endPos:t}),p=t,f=!0
|
|
2388
|
+
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))
|
|
2385
2389
|
let o=e
|
|
2386
2390
|
for(const e of n)o=a(o,e,r)
|
|
2387
2391
|
return o},exports.findSimilarMatches=function(e,t,r=5,n=.3){const o=e.split("\n"),s=[]
|
|
@@ -2406,15 +2410,15 @@ let i=d.FileOperationPhase.VALIDATION
|
|
|
2406
2410
|
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}"}
|
|
2407
2411
|
try{const a=e,{path:u}=a
|
|
2408
2412
|
n.info("Getting file info: "+u)
|
|
2409
|
-
const{normalizedPath:
|
|
2413
|
+
const{normalizedPath:g,fullPath:m}=d.validateAndNormalizePath(u,t)
|
|
2410
2414
|
i=d.FileOperationPhase.FILE_WRITE
|
|
2411
|
-
try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+u)}const f=await c.default.stat(m),y=f.isFile()?l.default.extname(m).slice(1):"",w={path:
|
|
2415
|
+
try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+u)}const f=await c.default.stat(m),y=f.isFile()?l.default.extname(m).slice(1):"",w={path:g,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: "+g,"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]
|
|
2412
2416
|
w.isFile&&y&&b.push("Extension: "+y)
|
|
2413
2417
|
const I=Date.now()-s
|
|
2414
|
-
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+
|
|
2415
|
-
return o.recordValue("get_file_info_time",r),o.incrementCounter("get_file_info_errors",1),n.error("Error getting file info:",{error:(0,u.getErrorMessage)(t),time:r}),d.handleFileOperationError(t,i,n,o,e,a)}var h,
|
|
2418
|
+
return o.recordValue("get_file_info_time",I),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+g,{type:w.type,size:w.size,time:I}),{content:[{type:"text",text:b.join("\n")}]}}catch(t){const r=Date.now()-s
|
|
2419
|
+
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}
|
|
2416
2420
|
const c=a(t(1943)),l=a(t(6928)),d=i(t(5967)),u=t(8824)},3707(e,exports,t){"use strict"
|
|
2417
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,u,h,g,
|
|
2421
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,u,h,p,g,m){const f=p.child({tool:"quick_edit"}),y=Date.now()
|
|
2418
2422
|
try{const w=h.getRequestClient(),b=h.getTaskClient(),I=h.getFileClient(),k=h.getToolRecordClient(),{title:v,description:C,..._}=e,E=e.comment||v
|
|
2419
2423
|
f.info("Starting quick_edit workflow",{title:v,operationType:t})
|
|
2420
2424
|
let S=!1
|
|
@@ -2425,23 +2429,23 @@ if(!T||!T.id)throw Error("Failed to create request")
|
|
|
2425
2429
|
const q=T.id
|
|
2426
2430
|
let P
|
|
2427
2431
|
f.info("Created request",{requestId:q})
|
|
2428
|
-
try{if(f.debug("Checking for uncommitted user changes before quick-edit branch creation"),u.git)try{const e=await(0,l.commitUserChangesBeforeToolOperation)(u.git,"quick-fix",{requestId:q,taskId:void 0,workspaceManager:u.workspaceManager},g
|
|
2432
|
+
try{if(f.debug("Checking for uncommitted user changes before quick-edit branch creation"),u.git)try{const e=await(0,l.commitUserChangesBeforeToolOperation)(u.git,"quick-fix",{requestId:q,taskId:void 0,workspaceManager:u.workspaceManager},p,g)
|
|
2429
2433
|
e.userChangesCommitted?f.info("Committed user changes to main before quick-edit branch creation",{requestId:q,commitHash:e.commitHash?.substring(0,8)}):f.debug("No uncommitted changes found, proceeding with quick-edit")}catch(e){f.warn("Failed to commit user changes before quick-edit, proceeding anyway",{requestId:q,error:e instanceof Error?e.message:e+""})}else f.debug("No git instance available, skipping uncommitted changes check")
|
|
2430
2434
|
f.debug("Creating task")
|
|
2431
2435
|
const e=await b.createTask({requestId:q,projectId:u.projectId,title:`Execute ${t} operation`,description:"Quick change: "+v})
|
|
2432
2436
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2433
2437
|
let C
|
|
2434
|
-
if(P=e.id,f.info("Created task",{taskId:P}),f.debug("Executing file operation",{operationType:t}),"write"===t)C=await(0,o.handleWriteFile)({taskId:P,..._,comment:E},u,I,b,k,w,g,
|
|
2435
|
-
else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:P,..._,comment:E},u,b,k,w,g,
|
|
2438
|
+
if(P=e.id,f.info("Created task",{taskId:P}),f.debug("Executing file operation",{operationType:t}),"write"===t)C=await(0,o.handleWriteFile)({taskId:P,..._,comment:E},u,I,b,k,w,p,g,m)
|
|
2439
|
+
else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:P,..._,comment:E},u,b,k,w,p,g,m)
|
|
2436
2440
|
else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
|
|
2437
|
-
C=await(0,i.handleManageFiles)({taskId:P,..._,comment:E||v},u,b,k,w,h,g,
|
|
2441
|
+
C=await(0,i.handleManageFiles)({taskId:P,..._,comment:E||v},u,b,k,w,h,p,g,m)}if(C.isError){f.error("File operation failed, cleaning up request and task",{requestId:q,taskId:P})
|
|
2438
2442
|
try{await b.updateTaskStatus(P,"canceled"),f.info("Canceled task after operation failure",{taskId:P})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:P,error:e instanceof Error?e.message:e+""})}try{await w.updateRequest(q,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:q}),u.workspaceManager&&(await u.workspaceManager.cancelRequest(q),f.info("Cleaned up branch/worktree after operation failure",{requestId:q}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:q,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${C.content[0].text}\n\nThe request (${q}) and task have been canceled and cleaned up.`}],isError:!0}}const T=C.content[0].text,j=T.includes("\u26a0\ufe0f Partial Success")||T.includes("\u274c Failed")||T.includes("\u274c 0 successful")
|
|
2439
2443
|
j?f.warn("File operation completed with partial failures",{requestId:q}):f.info("File operation completed successfully"),f.debug("Completing task")
|
|
2440
|
-
try{await(0,a.handleCompleteTask)({taskId:P,summary:`Executed ${t} operation for quick fix: ${v}${j?" (partial success)":""}`},u,h,g
|
|
2444
|
+
try{await(0,a.handleCompleteTask)({taskId:P,summary:`Executed ${t} operation for quick fix: ${v}${j?" (partial success)":""}`},u,h,p,g),f.info("Task completed successfully",{taskId:P})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:P,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
|
|
2441
2445
|
try{await b.updateTaskStatus(P,"completed"),f.info("Task completed via direct updateTaskStatus call",{taskId:P})}catch(e){return f.error("Direct task completion ALSO failed - task may be stuck in in_progress",{taskId:P,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0,operationType:t,isDocumentOperation:!!_.documentId}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but task completion failed.\n\n**Request:** ${q}\n**Task:** ${P}\n**Issue:** Could not mark task as completed - it remains in 'in_progress' state\n\nThe ${t} operation was successful, but we couldn't automatically complete the task. Please use the complete-task tool manually with taskId: ${P}\n\nError: `+(e instanceof Error?e.message:e+"")}],isError:!0}}}f.debug("Completing request")
|
|
2442
2446
|
const R=j?`Quick change completed with partial success: ${v}. Some replacements failed - see details below.`:"Quick change completed: "+v,x=j?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
|
|
2443
2447
|
let M=!1
|
|
2444
|
-
try{const e=await(0,c.handleCompleteRequest)({requestId:q,summary:R,acceptanceEvidence:[{evidence:x}],testVerification:void 0},u,h,g,
|
|
2448
|
+
try{const e=await(0,c.handleCompleteRequest)({requestId:q,summary:R,acceptanceEvidence:[{evidence:x}],testVerification:void 0},u,h,p,g,m)
|
|
2445
2449
|
if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:q,error:e.content[0].text})
|
|
2446
2450
|
else{try{await w.updateRequest(q,{status:"completed",completionSummary:R}),f.info("Request finalized to completed",{requestId:q})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:q,error:(0,d.getErrorMessage)(e)})}M=!0,f.info("Request completed successfully",{requestId:q})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:q,error:e instanceof Error?e.message:e+""})}if(!M)try{f.info("Attempting direct request completion via API",{requestId:q}),await w.updateRequest(q,{status:"completed",completionSummary:R}),M=!0,f.info("Request completed successfully via direct API call",{requestId:q})}catch(e){return f.error("Direct request completion also failed",{requestId:q,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${q}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const O=Date.now()-y
|
|
2447
2451
|
f.info("Quick fix completed",{requestId:q,duration:O,hasPartialFailure:j})
|
|
@@ -2543,7 +2547,7 @@ const{taskId:M}=x,O=!!S,$=!!m
|
|
|
2543
2547
|
b.info("Writing content to "+(O?"document":"file"),{taskId:M,filePath:$?m:void 0,documentId:O?S:void 0,contentLength:"string"==typeof T?T.length:JSON.stringify(T).length,format:q,append:P,comment:j})
|
|
2544
2548
|
let D,A,F,N="",z=!1,L=!1
|
|
2545
2549
|
const H=$?m:void 0
|
|
2546
|
-
if(O){if(r.apiClient)try{await(0,
|
|
2550
|
+
if(O){if(r.apiClient)try{await(0,g.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}
|
|
2547
2551
|
throw e}if(!r.documentFileManager)throw Error("Document file manager not available")
|
|
2548
2552
|
N=await r.documentFileManager.getDocumentAsFile(S)
|
|
2549
2553
|
const e=r.documentFileManager.getCachedDocumentInfo(S)
|
|
@@ -2565,7 +2569,7 @@ if(v=J,C=J,_=E.fileOperationPhase,y.incrementCounter("write_file_phase",1,{phase
|
|
|
2565
2569
|
else Q="string"==typeof T?T:JSON.stringify(T,null,2)
|
|
2566
2570
|
let Y=Q
|
|
2567
2571
|
if($&&r.git)try{b.debug("[WRITE-FILE] Checking for user changes before write operation")
|
|
2568
|
-
const e=await(0,
|
|
2572
|
+
const e=await(0,p.commitUserChangesBeforeToolOperation)(r.git,"write_file",{requestId:r.workspaceManager?.getCurrentContext(r.currentSessionId)?.requestId,taskId:M},b,y)
|
|
2569
2573
|
e.userChangesCommitted&&(b.debug("[WRITE-FILE] User changes committed before write operation",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),b.info("User changes committed before write-file operation",{taskId:M,path:D,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){b.debug("[WRITE-FILE] Pre-tool commit failed, continuing with write",{error:e instanceof Error?e.message:e+""}),b.warn("Pre-tool user changes commit failed, continuing with write operation",{taskId:M,path:D,error:e instanceof Error?e.message:e+""})}if(!N)throw Error("Target path not properly initialized")
|
|
2570
2574
|
if(b.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:N}),P&&L)try{Y=await c.default.readFile(N,"utf8")+Q}catch(e){b.warn("Failed to read existing content for append",{error:e})}const Z=a.default.dirname(N)
|
|
2571
2575
|
if(await c.default.mkdir(Z,{recursive:!0}),await c.default.writeFile(N,Y,"utf8"),b.info("Content written successfully",{path:$?D:"document:"+S,finalLength:Y.length,append:P,wasCreated:z}),O){r.documentFileManager.markForSync(S)
|
|
@@ -2579,7 +2583,7 @@ b.info("Write operation completed successfully",{duration:oe-k,path:$?D:"documen
|
|
|
2579
2583
|
const se=r.workspaceManager?.consumeLargeFileWarning(r.currentSessionId)
|
|
2580
2584
|
return se&&(ne+=se),{content:[{type:"text",text:ne}],...(0,l.alchemyMeta)({kind:"write-file",toolRecordId:C})}}catch(t){const r=Date.now()-k
|
|
2581
2585
|
if(b.error("Write operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:_}),C)try{await s.updateToolRecord(C,{metadata:{path:e?.path,status:"failed",error:(0,m.getErrorMessage)(t),phase:_,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return I({tool:"write_file",success:!1}),y.incrementCounter("write_file_errors",1,{phase:_}),{content:[{type:"text",text:"\u274c **Write Operation Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
2582
|
-
const a=i(t(6928)),c=i(t(1943)),l=t(2272),d=s(t(5967)),u=t(9860),h=t(5003),
|
|
2586
|
+
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),g=t(9949),m=t(8824)},4118(e,exports){"use strict"
|
|
2583
2587
|
Object.defineProperty(exports,"__esModule",{value:!0})},4139(e,exports){"use strict"
|
|
2584
2588
|
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"
|
|
2585
2589
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=exports.TasksSchema=void 0
|
|
@@ -2600,14 +2604,14 @@ this.authToken?(a.Authorization="Bearer "+this.authToken,this.logger.debug("Usin
|
|
|
2600
2604
|
const c=process.env.SERVICE_SHARED_SECRET||"dev-service-secret-change-in-production"
|
|
2601
2605
|
a["X-Service-Secret"]=c
|
|
2602
2606
|
let l=0
|
|
2603
|
-
const d=this.options.retryAttempts,u={method:e,path:s},h=this.metrics.startTimer("api_request_duration"),
|
|
2607
|
+
const d=this.options.retryAttempts,u={method:e,path:s},h=this.metrics.startTimer("api_request_duration"),p=e=>h({...u,...e})
|
|
2604
2608
|
for(;d>l;){l++
|
|
2605
2609
|
try{this.logger.debug(`Making ${e} request to ${i}`,{attempt:l,maxAttempts:d,hasAuth:!!a.Authorization,hasServiceIdentifier:!!a["X-Client-Type"]})
|
|
2606
2610
|
const t={method:e,headers:{...a},signal:AbortSignal.timeout(this.options.timeout||1e4)}
|
|
2607
2611
|
if("GET"!==e&&void 0!==r&&(t.body=JSON.stringify(r)),this.logger.debug("Request details",{method:e,url:i}),t.headers){const e={}
|
|
2608
2612
|
Object.entries(t.headers).forEach((([t,r])=>{"authorization"===t.toLowerCase()?e[t]="Bearer [redacted]":e[t]=r})),this.logger.debug("Request headers",{headers:e})}if("GET"!==e&&t.body){const e="string"==typeof t.body?t.body:JSON.stringify(t.body)
|
|
2609
2613
|
this.logger.debug("Request body",{bodyPreview:e.substring(0,200)+(e.length>200?"...":""),bodyLength:e.length})}const n=await fetch(i,t)
|
|
2610
|
-
if(!n.ok){if(this.logger.error("API request failed with status "+n.status,{method:e,url:i,status:n.status,statusText:n.statusText,attempt:l}),401===n.status)throw
|
|
2614
|
+
if(!n.ok){if(this.logger.error("API request failed with status "+n.status,{method:e,url:i,status:n.status,statusText:n.statusText,attempt:l}),401===n.status)throw p({success:!1,status:n.status,retries:l-1}),Error("Authentication failed - invalid or expired token")
|
|
2611
2615
|
if(429===n.status){const e=n.headers.get("Retry-After"),t=e?1e3*parseInt(e):2*(this.options.retryDelay||1e3)
|
|
2612
2616
|
if(this.logger.warn(`Rate limited (429), retrying after ${t}ms`,{attempt:l,maxAttempts:d,retryAfter:e}),d>l){await new Promise((e=>setTimeout(e,t)))
|
|
2613
2617
|
continue}}if(n.status>=500&&d>l){const e=(this.options.retryDelay||1e3)*Math.pow(2,l-1)
|
|
@@ -2616,17 +2620,17 @@ continue}let t=`API request failed with status ${n.status}: ${n.statusText}`,r={
|
|
|
2616
2620
|
try{const e=await n.json()
|
|
2617
2621
|
if(e&&"object"==typeof e&&!1===e.success&&e.error){const n=e.error
|
|
2618
2622
|
n.message&&(t=n.message),r={code:n.code,statusCode:n.statusCode,retryable:n.retryable,details:n.details}}else e&&"object"==typeof e&&e.message&&(t=e.message)}catch(e){try{const e=await n.text()
|
|
2619
|
-
e&&e.trim()&&(t=`${t}. Response: ${e.substring(0,200)}`)}catch(t){this.logger.debug("Failed to parse error response",{jsonError:e instanceof Error?e.message:e+"",textError:t instanceof Error?t.message:t+""})}}
|
|
2623
|
+
e&&e.trim()&&(t=`${t}. Response: ${e.substring(0,200)}`)}catch(t){this.logger.debug("Failed to parse error response",{jsonError:e instanceof Error?e.message:e+"",textError:t instanceof Error?t.message:t+""})}}p({success:!1,status:n.status,retries:l-1})
|
|
2620
2624
|
const o=Error(t)
|
|
2621
2625
|
throw o.status=n.status,o.statusText=n.statusText,o.method=e,o.url=i,o.errorDetails=r,o}this.resetFailureCount()
|
|
2622
2626
|
const o=await n.json()
|
|
2623
2627
|
if(null===o||"object"!=typeof o)throw Error("Invalid API response: expected object, got "+typeof o)
|
|
2624
2628
|
if(o&&"object"==typeof o&&!("success"in o)){this.logger.warn("Non-standard API response detected - wrapping in standard format",{responseKeys:Object.keys(o)})
|
|
2625
2629
|
const e={success:!0,data:o}
|
|
2626
|
-
return
|
|
2627
|
-
throw this.logger.error("API returned error response",{errorCode:e.error?.code,errorMessage:e.error?.message,statusCode:e.error?.statusCode}),
|
|
2628
|
-
return
|
|
2629
|
-
throw void 0!==r&&500>r||this.incrementFailureCount(),this.logger.error(`API request failed after ${l} attempts`,{method:e,url:i,error:t.message||t+"",status:t.status}),
|
|
2630
|
+
return p({success:!0,status:n.status,retries:l-1,standardFormat:!1}),e}if(o&&"object"==typeof o&&"success"in o&&!1===o.success){const e=o
|
|
2631
|
+
throw this.logger.error("API returned error response",{errorCode:e.error?.code,errorMessage:e.error?.message,statusCode:e.error?.statusCode}),p({success:!1,status:n.status,retries:l-1,errorCode:e.error?.code}),Error(`API error: ${e.error?.code}: ${e.error?.message}`)}if(o&&"object"==typeof o&&"success"in o&&!0===o.success&&"data"in o){const t=o
|
|
2632
|
+
return p({success:!0,status:n.status,retries:l-1,standardFormat:!0}),this.logger.debug("API request succeeded with status "+n.status,{method:e,url:i,status:n.status,retries:l-1,hasMetadata:"metadata"in t}),t}return this.logger.warn("Invalid API response format: Unexpected structure",{responseType:typeof o,responseKeys:"object"==typeof o?Object.keys(o):[]}),{success:!0,data:o}}catch(t){if(l>=d){const r=t?.status
|
|
2633
|
+
throw void 0!==r&&500>r||this.incrementFailureCount(),this.logger.error(`API request failed after ${l} attempts`,{method:e,url:i,error:t.message||t+"",status:t.status}),p({success:!1,error:!0,retries:l-1}),t}const r=Math.min((this.options.retryDelay||1e3)*Math.pow(2,l-1),5e3)
|
|
2630
2634
|
this.logger.warn(`API request failed, retrying in ${r}ms`,{method:e,url:i,error:t.message||t+"",attempt:l,maxAttempts:d}),await new Promise((e=>setTimeout(e,r)))}}throw Error("Unexpected end of requestWithRetry")}incrementFailureCount(){this.failureCount++,this.metrics.setGauge("api_failure_count",this.failureCount),"half-open"!==this.circuitState?this.failureCount<this.options.circuitBreakerThreshold||"closed"!==this.circuitState||this.openCircuit():this.logger.warn("Half-open probe failed, will retry on next request")}resetFailureCount(){const e="closed"!==this.circuitState
|
|
2631
2635
|
this.failureCount=0,this.circuitState="closed",this.metrics.setGauge("api_failure_count",0),this.metrics.setGauge("circuit_breaker_open",0),this.circuitResetTimeout&&(clearTimeout(this.circuitResetTimeout),this.circuitResetTimeout=null),e&&this.logger.info("Circuit breaker closed after successful request")}openCircuit(){this.circuitState="open",this.metrics.setGauge("circuit_breaker_open",1),this.logger.warn(`Circuit breaker opened after ${this.failureCount} failures`),this.circuitResetTimeout&&clearTimeout(this.circuitResetTimeout)
|
|
2632
2636
|
const e=this.options.circuitBreakerResetTime||5e3
|
|
@@ -2648,17 +2652,17 @@ if(!c.startsWith(s+a.sep))return{content:[{type:"text",text:"\u274c Invalid file
|
|
|
2648
2652
|
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]
|
|
2649
2653
|
if(!h)return{content:[{type:"text",text:"\u274c Unsupported image type: ."+u}],isError:!0}
|
|
2650
2654
|
if("svg"===u)return{content:[{type:"text",text:`**Asset: ${r}**\n\n\`\`\`svg\n${await i.readFile(c,"utf-8")}\n\`\`\``}]}
|
|
2651
|
-
const
|
|
2652
|
-
return o.info("Asset viewed",{filename:r,size:
|
|
2655
|
+
const p=await i.readFile(c),g=p.toString("base64")
|
|
2656
|
+
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:g,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}}}
|
|
2653
2657
|
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+"'")
|
|
2654
2658
|
throw t.code="MODULE_NOT_FOUND",t}e.keys=()=>[],e.resolve=e,e.id=4245,module.exports=e},4306(e,exports,t){"use strict"
|
|
2655
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMergeRequest=async function(e,t,a,c,l){const d=c.child({tool:"merge_request"}),u=l.startTimer("tool_execution_time"),{requestId:h,verifications:
|
|
2659
|
+
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
|
|
2656
2660
|
try{if(!h)throw(0,n.createValidationError)("requestId is required")
|
|
2657
|
-
d.info("Starting merge request",{requestId:h,verificationCount:
|
|
2661
|
+
d.info("Starting merge request",{requestId:h,verificationCount:p.length})
|
|
2658
2662
|
const e=a.getRequestClient(),s=await e.getRequest(h)
|
|
2659
2663
|
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}
|
|
2660
|
-
if(
|
|
2661
|
-
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,
|
|
2664
|
+
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)
|
|
2665
|
+
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,g
|
|
2662
2666
|
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/validate-completion`,{})
|
|
2663
2667
|
c=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2664
2668
|
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`
|
|
@@ -2666,10 +2670,10 @@ return c.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\
|
|
|
2666
2670
|
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)
|
|
2667
2671
|
l=(await n.raw(["merge-base",o,"requests/"+h])).trim()||void 0}catch(e){d.warn("Could not compute merge-base; mergeBaseSha will not be recorded",{requestId:h,error:(0,i.getErrorMessage)(e)})}let m="workspace-manager"
|
|
2668
2672
|
const f=await e.getRequest(h),y=f?.title||"Request "+h,w="resolving_conflicts"===f?.status
|
|
2669
|
-
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),
|
|
2673
|
+
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),g=await t.workspaceManager.completeRequest(h,y,{skipConflictDetection:!0}),m="retry-theirs"):(g=await t.workspaceManager.completeRequest(h,y),m=g.autoMergeInfo?.strategy||"workspace-manager"),d.info("Merge completed",{requestId:h,mergeCommitHash:g.mergeCommitHash,mergeMethod:m})}catch(r){if(r.conflictInfo){const n=r.conflictInfo,s=n.workingDirectory||t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||process.cwd(),c=(0,o.createConflictResolutionManager)(d,a,s,t.git),l=await c.handleConflicts(n)
|
|
2670
2674
|
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)
|
|
2671
|
-
return u({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Merge failed: "+n}],isError:!0}}try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/finalize-completion`,{summary:f?.completionSummary||"Merged request "+h,acceptanceEvidence:
|
|
2672
|
-
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:
|
|
2675
|
+
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:g.mergeCommitHash,mergeBaseSha:l,mergedFiles:g.mergedFiles,cleanedUp:g.cleanedUp,method:m}})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2676
|
+
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:g.mergeCommitHash,error:t}),u({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${g.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: ${g.mergeCommitHash.substring(0,8)}`}]}}catch(e){const r=(0,i.getErrorMessage)(e)
|
|
2673
2677
|
d.error("Merge request failed",{error:r})
|
|
2674
2678
|
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}}}
|
|
2675
2679
|
const r=t(3807),n=t(9860),o=t(1651),s=t(8616),i=t(8824)},4394(e,exports,t){"use strict"
|
|
@@ -2689,51 +2693,48 @@ const a=await r.updateDocument(e.planId,i),c=a.localId||a.id
|
|
|
2689
2693
|
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}}}
|
|
2690
2694
|
const r=t(8824)},4425(e,exports,t){"use strict"
|
|
2691
2695
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2692
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,
|
|
2693
|
-
try{const
|
|
2694
|
-
if("list"===
|
|
2696
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,h,p,g,m){const f=p.startTimer("tool_execution_time"),y=e.operation||"run"
|
|
2697
|
+
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))
|
|
2698
|
+
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"})}
|
|
2695
2699
|
const e=[]
|
|
2696
|
-
return
|
|
2697
|
-
try{const r=await fetch((0,
|
|
2700
|
+
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=m?.sessionId,n=t?await d.sessionIdentity.getSessionRequestId(r,h,t):void 0
|
|
2701
|
+
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)})
|
|
2698
2702
|
if(!r.ok){const e=await r.text().catch((()=>""))
|
|
2699
|
-
return
|
|
2700
|
-
return o.success&&o.data?(
|
|
2701
|
-
const n=function(e){return e?.sessionId||
|
|
2702
|
-
if(!n)return
|
|
2703
|
-
const o=new Set(
|
|
2703
|
+
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()
|
|
2704
|
+
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}
|
|
2705
|
+
const n=function(e){return e?.sessionId||d.sessionIdentity.getIdentity()?.sessionId||null}(m)
|
|
2706
|
+
if(!n)return f({success:!1,error:"no_session"}),{content:[{type:"text",text:"Error: no session context available to attribute approval notifications."}],isError:!0}
|
|
2707
|
+
const o=new Set(w.map((e=>e.name.toLowerCase()))),s=[],i=[]
|
|
2704
2708
|
for(const t of e.commands){const e=t.name?.trim(),r=t.command?.trim(),n=t.description?.trim()
|
|
2705
|
-
e&&r&&n?o.has(e.toLowerCase())?i.push({name:e,reason:"already exists"}):(o.add(e.toLowerCase()),s.push({name:e,command:r,description:n,cwd:t.cwd?.trim(),timeout:t.timeout})):i.push({name:e||"(unnamed)",reason:"missing required fields (name, command, description)"})}const
|
|
2709
|
+
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:m?.sessionId,isActive:!1}),o=n?.data?.id||n?.id
|
|
2706
2710
|
if(!o)throw Error("command create returned no id")
|
|
2707
|
-
return{ok:!0,proposal:e,commandId:o}}catch(t){return{ok:!1,proposal:e,error:(0,
|
|
2708
|
-
for(const e of
|
|
2709
|
-
const
|
|
2710
|
-
if(
|
|
2711
|
+
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))
|
|
2712
|
+
for(const e of a)e.ok||i.push({name:e.proposal.name,reason:e.error})
|
|
2713
|
+
const p=[]
|
|
2714
|
+
if(u.length>0)try{const e=r.getSessionMessageClient()
|
|
2711
2715
|
if(!e)throw Error("session message client unavailable")
|
|
2712
|
-
await e.createQuestion({fromSessionId:n,questionType:"alternatives",question:`Command batch approval: ${
|
|
2713
|
-
for(const e of
|
|
2714
|
-
for(const t of
|
|
2715
|
-
const
|
|
2716
|
-
return
|
|
2717
|
-
const n=
|
|
2718
|
-
if(!n)return
|
|
2719
|
-
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),
|
|
2720
|
-
return
|
|
2721
|
-
if(!
|
|
2722
|
-
return
|
|
2723
|
-
e.grep&&(
|
|
2724
|
-
const
|
|
2725
|
-
let
|
|
2726
|
-
try{
|
|
2727
|
-
const
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
if(g)try{const e=await g.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:I.name,command:k,exitCode:R,timedOut:x,status:x?"timeout":0===R?"success":"failed",timestamp:(new Date).toISOString()}})
|
|
2735
|
-
A=e?.id}catch(e){u.debug("Failed to create tool record for command run",{error:(0,c.getErrorMessage)(e)})}return m({success:!0}),{content:[{type:"text",text:`## ${I.name}${$?` \u2014 ${$} (killed after ${I.timeout}s)`:""}\n\`\`\`\n$ ${k}\n${D}\n\`\`\`\n\nExit code: ${R}\nFull log: ${S}`}],...(0,a.alchemyMeta)({kind:"run-command",toolRecordId:A})}}catch(e){return m({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,c.getErrorMessage)(e)}],isError:!0}}}
|
|
2736
|
-
const n=t(4600),o=r(t(6928)),s=r(t(9896)),i=t(4139),a=t(2272),c=t(8824),l=t(6688),d=t(9414)},4466(e,exports,t){"use strict"
|
|
2716
|
+
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"})
|
|
2717
|
+
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)}))))))
|
|
2718
|
+
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})
|
|
2719
|
+
const g=[`## Submitted ${p.length} command${1===p.length?"":"s"} for approval${i.length?`, ${i.length} skipped`:""}`]
|
|
2720
|
+
return p.length>0&&(g.push("","### Pending approval"),g.push(...p.map((e=>`- **${e}**`))),g.push("","The user will see one approval notification per command. Approved commands become runnable; denied ones are removed.")),i.length>0&&(g.push("",`### Skipped (${i.length})`),g.push(...i.map((e=>`- **${e.name}** \u2014 ${e.reason}`)))),g.push("",'Use `commands({ operation: "list" })` to see status.'),{content:[{type:"text",text:g.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}
|
|
2721
|
+
const n=w.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2722
|
+
if(!n)return f({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.`}],isError:!0}
|
|
2723
|
+
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(", ")
|
|
2724
|
+
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()))
|
|
2725
|
+
if(!k){const t=b.map((e=>e.name)).join(", ")
|
|
2726
|
+
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
|
|
2727
|
+
e.grep&&(v=`${v} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
|
|
2728
|
+
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()}`,T=s.default.join(E,S+".log")
|
|
2729
|
+
let q=null
|
|
2730
|
+
try{i.default.mkdirSync(E,{recursive:!0}),q=i.default.createWriteStream(T,{flags:"w"}),q.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:T,error:(0,l.getErrorMessage)(e)})}h.info("Running command",{name:k.name,command:v,cwd:_,configuredCwd:k.cwd,logPath:T})
|
|
2731
|
+
const P=await(0,n.runTrackedShellCommand)(v,{cwd:_,timeoutMs:1e3*(k.timeout||60),env:{...process.env,FORCE_COLOR:"0"},onChunk:q?(e,t)=>{q?.write(t)}:void 0},{id:S,name:k.name,sessionId:m?.sessionId,logPath:T})
|
|
2732
|
+
q&&(q.write(`\n# exit: ${P.exitCode}${P.timedOut?" (timed out)":""}\n`),q.end())
|
|
2733
|
+
const{stdout:j,stderr:R,exitCode:x,timedOut:M}=P,{output:O,truncatedNote:$,logFooter:D}=(0,o.formatCommandOutput)(j,R,{invocationId:S}),A=M?"TIMEOUT":null
|
|
2734
|
+
let F
|
|
2735
|
+
if(g)try{const e=await g.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:k.name,command:v,exitCode:x,timedOut:M,status:M?"timeout":0===x?"success":"failed",timestamp:(new Date).toISOString()}})
|
|
2736
|
+
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${O}\n\`\`\`${$}\n\nExit code: ${x}\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}}}
|
|
2737
|
+
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"
|
|
2737
2738
|
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
|
|
2738
2739
|
const i=e.match(exports.TASK_REF_SHORT_PATTERN)
|
|
2739
2740
|
if(!i)return e
|
|
@@ -2755,10 +2756,10 @@ if(1>parseInt(t[2],10))throw Error(`Invalid task number in ${e}: must be >= 1`)
|
|
|
2755
2756
|
return e}
|
|
2756
2757
|
const o=t(6688),s=t(8955)
|
|
2757
2758
|
exports.TASK_REF_PATTERN=/^(req\d{6})#(\d+)$/,exports.TASK_REF_SHORT_PATTERN=/^#?(\d{1,3})$/},4592(e,exports,t){"use strict"
|
|
2758
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlannerOps=async function(e,t,c,l,d,u){const h=c.child({tool:"planner_ops"}),
|
|
2759
|
-
try{const c=e,{operation:
|
|
2759
|
+
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")
|
|
2760
|
+
try{const c=e,{operation:g,sessionId:m}=c
|
|
2760
2761
|
let f
|
|
2761
|
-
switch(h.info("Processing planner_ops",{operation:
|
|
2762
|
+
switch(h.info("Processing planner_ops",{operation:g,sessionId:m}),g){case"request":{const e=await async function(e,t,r){if(!e)return"ask"
|
|
2762
2763
|
try{const s=r?.sessionId||o.sessionIdentity.getIdentity()?.sessionId
|
|
2763
2764
|
if(!s)return"ask"
|
|
2764
2765
|
const i=e.getCLISessionClient()
|
|
@@ -2774,18 +2775,18 @@ if("interactive"===n)return"interactive"}catch(e){t.warn("Failed to read project
|
|
|
2774
2775
|
if("ask"===e||"interactive"===e){h.info("Returning planner choice pending",{planningMode:e})
|
|
2775
2776
|
try{const e=u?.sessionId||o.sessionIdentity.getIdentity()?.sessionId,t=d?.getSessionMessageClient()
|
|
2776
2777
|
if(t&&e){const r=await o.sessionIdentity.getParentSessionId(e,d,h),n=c.description||c.prompt
|
|
2777
|
-
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}}})}
|
|
2778
|
+
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}}})}
|
|
2778
2779
|
break}const r="auto-planner"
|
|
2779
2780
|
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
|
|
2780
2781
|
f.content[0].text=`Planning mode: ${e} (agent: ${r}). Planning is running in the background \u2014 continue with your other work.\n${t}`}break}case"check-status":f=await(0,s.handleCheckStatus)(m,t,h,d)
|
|
2781
2782
|
break
|
|
2782
|
-
case"list":const e=u?.sessionId||o.sessionIdentity.getIdentity()?.sessionId,[a,l]=await Promise.all([(0,s.handleListSessions)(t,h,d,{activeOnly:c.activeOnly,limit:c.limit,agentType:"auto-planner",parentSessionId:e}),(0,s.handleListSessions)(t,h,d,{activeOnly:c.activeOnly,limit:c.limit,agentType:"planner",parentSessionId:e})]),
|
|
2783
|
-
if(
|
|
2784
|
-
|
|
2783
|
+
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??""
|
|
2784
|
+
if(p.trim()||y.trim()){const e=[]
|
|
2785
|
+
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."}]}
|
|
2785
2786
|
break
|
|
2786
|
-
default:throw new r.ValidationError("Unknown operation: "+
|
|
2787
|
-
const y=a[
|
|
2788
|
-
return(0,i.withAlchemyKind)(f,y)}catch(e){return h.error("Planner ops failed",{error:e instanceof Error?e.stack:e+""}),
|
|
2787
|
+
default:throw new r.ValidationError("Unknown operation: "+g)}p({success:!0}),l.incrementCounter(`planner_ops_${g}_success`,1)
|
|
2788
|
+
const y=a[g]??"planner-request"
|
|
2789
|
+
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}}}
|
|
2789
2790
|
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"
|
|
2790
2791
|
async function r(e,r={}){const{spawn:n}=await Promise.resolve().then(t.t.bind(t,5317,23))
|
|
2791
2792
|
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=[]
|
|
@@ -2793,8 +2794,8 @@ let c=!1,l=!1
|
|
|
2793
2794
|
const d=e=>{if(s.pid)try{o?s.kill(e):process.kill(-s.pid,e)}catch{}}
|
|
2794
2795
|
let u,h
|
|
2795
2796
|
r.timeoutMs&&r.timeoutMs>0&&(h=setTimeout((()=>{c=!0,d("SIGTERM"),u=setTimeout((()=>{l||d("SIGKILL")}),2e3)}),r.timeoutMs)),s.stdout?.on("data",(e=>{i.push(e),r.onChunk?.("stdout",e)})),s.stderr?.on("data",(e=>{a.push(e),r.onChunk?.("stderr",e)}))
|
|
2796
|
-
const
|
|
2797
|
-
s.on("close",(e=>
|
|
2797
|
+
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}))}
|
|
2798
|
+
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"]})
|
|
2798
2799
|
let c="",l=""
|
|
2799
2800
|
a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{r({stdout:c,stderr:l,exitCode:e||0})})),a.on("error",(t=>{o(Error(`Command failed: ${e}\nError: ${t.message}`))})),t.timeout&&setTimeout((()=>{a.kill(),o(Error("Command timed out: "+e))}),t.timeout)}))},exports.runShellCommand=r,exports.runTrackedShellCommand=async function(e,n,o){const{getActionServerBaseUrl:s}=await Promise.resolve().then(t.bind(t,9414)),i=s(),a=(new Date).toISOString(),c=n.cwd??process.cwd()
|
|
2800
2801
|
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((()=>{}))
|
|
@@ -2813,10 +2814,10 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2813
2814
|
var t={}
|
|
2814
2815
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2815
2816
|
return o(t,e),t})
|
|
2816
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,r,n,o,s,u,h){const
|
|
2817
|
-
try{const
|
|
2818
|
-
return
|
|
2819
|
-
try{const{normalizedPath:y,fullPath:w}=c.validateAndNormalizePath(t,o),b=await c.validateTaskId(e,y,s.getTaskClient(),h,
|
|
2817
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,r,n,o,s,u,h){const p=s.child({tool:"file_recover"}),g=u.startTimer("tool_execution_time"),m=Date.now()
|
|
2818
|
+
try{const g=e,{path:f,commitHash:y,createBackup:w}=g,{resolveActiveTaskId:b}=await Promise.resolve().then(t.bind(t,3451)),I=e.taskId||await b(r,n,s)||"untracked"
|
|
2819
|
+
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,m){let f
|
|
2820
|
+
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",m)
|
|
2820
2821
|
f=I
|
|
2821
2822
|
let k,v=!1
|
|
2822
2823
|
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
|
|
@@ -2828,31 +2829,31 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
|
|
|
2828
2829
|
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await a.writeFile(w,_,"utf8")
|
|
2829
2830
|
let E={}
|
|
2830
2831
|
try{const t=`Recover ${y} from ${r.substring(0,8)}`
|
|
2831
|
-
E=await c.commitToGit(e,y,f,f,t,o,h,
|
|
2832
|
+
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()-g,...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"
|
|
2832
2833
|
let T=`\u2705 **File ${S.charAt(0).toUpperCase()+S.slice(1)} Successfully**\n\n`
|
|
2833
|
-
return T+=`**File:** ${y}\n`,T+=`**Recovered from:** ${r.substring(0,8)}\n`,T+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(T+=`**Backup created:** ${i.basename(k)}\n`),T+="**Git status:** Recovery committed\n",T+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",h.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-
|
|
2834
|
-
return
|
|
2834
|
+
return T+=`**File:** ${y}\n`,T+=`**Recovered from:** ${r.substring(0,8)}\n`,T+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(T+=`**Backup created:** ${i.basename(k)}\n`),T+="**Git status:** Recovery committed\n",T+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",h.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-g}),p.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:T}]}}catch(e){throw e}}(I,f,y,w,r,n,o,p,u,m,h)}catch(e){const t=Date.now()-m
|
|
2835
|
+
return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),g({tool:"file_recover",success:!1}),u.incrementCounter("file_recover_errors",1),{content:[{type:"text",text:"\u274c **Recovery Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
2835
2836
|
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"
|
|
2836
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,h,g,
|
|
2837
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,h,p,g,m,f){const y=g.child({tool:"request_operations"})
|
|
2837
2838
|
try{const w=e
|
|
2838
2839
|
let{requestId:b}=w
|
|
2839
2840
|
const{operation:I}=w
|
|
2840
2841
|
if("list"!==I&&"search"!==I&&!b){const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=h.currentSessionId
|
|
2841
|
-
if(r&&"__unknown__"!==r&&"__server__"!==r&&(b=await e.getSessionRequestId(
|
|
2842
|
+
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")
|
|
2842
2843
|
const e={requestId:b,summary:w.complete.summary}
|
|
2843
|
-
return(0,d.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,h,g,
|
|
2844
|
+
return(0,d.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,h,p,g,m,f),u.complete)}case"merge":return y.info("Routing to merge handler"),(0,d.withAlchemyKind)(await(0,c.handleMergeRequest)({requestId:b,verifications:w.merge?.verifications||[]},h,p,g,m,f),u.merge)
|
|
2844
2845
|
case"approve":{y.info("Routing to approve-request handler")
|
|
2845
2846
|
const e={requestId:b}
|
|
2846
|
-
return(0,d.withAlchemyKind)(await(0,a.handleApproveRequest)(e,h,g,
|
|
2847
|
+
return(0,d.withAlchemyKind)(await(0,a.handleApproveRequest)(e,h,p,g,m,f),u.approve)}case"revert":{y.info("Routing to revert-request handler")
|
|
2847
2848
|
const e={requestId:b,reason:w.revert.reason,confirmDestructive:w.revert.confirmDestructive}
|
|
2848
|
-
return(0,d.withAlchemyKind)(await(0,n.handleRevertRequest)(e,h,g,
|
|
2849
|
+
return(0,d.withAlchemyKind)(await(0,n.handleRevertRequest)(e,h,p,g,m),u.revert)}case"get-info":{y.info("Routing to get-request-information handler")
|
|
2849
2850
|
const e={requestId:b}
|
|
2850
|
-
return(0,d.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,h,g,
|
|
2851
|
+
return(0,d.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,h,p,g,m),u["get-info"])}case"list":{y.info("Routing to list-requests handler")
|
|
2851
2852
|
const e={filters:w.list?.filters}
|
|
2852
|
-
return(0,d.withAlchemyKind)(await(0,s.handleListRequests)(e,h,g,
|
|
2853
|
+
return(0,d.withAlchemyKind)(await(0,s.handleListRequests)(e,h,p,g,m),u.list)}case"search":{y.info("Routing to search-requests handler")
|
|
2853
2854
|
const e={search:w.search}
|
|
2854
|
-
return(0,d.withAlchemyKind)(await(0,i.handleSearchRequests)(e,h,g,
|
|
2855
|
-
try{const e=
|
|
2855
|
+
return(0,d.withAlchemyKind)(await(0,i.handleSearchRequests)(e,h,p,g,m),u.search)}case"delete-empty":if(y.info("Routing to delete-empty handler"),!b)return{content:[{type:"text",text:"\u274c **Request Operations Failed:** requestId is required for delete-empty"}],isError:!0}
|
|
2856
|
+
try{const e=p.getProxyClient(),t=await e.proxyGet(`/api/projects/${h.projectId}/tasks`,{requestLocalId:b,limit:1}),r=t?.data||t||[]
|
|
2856
2857
|
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
|
|
2857
2858
|
return y.error(e),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+e}],isError:!0}}}}catch(e){return y.error("Request operations failed",{error:e instanceof Error?e.stack:e+""}),m.incrementCounter("request_operations_errors",1),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
2858
2859
|
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"
|
|
@@ -2970,16 +2971,16 @@ return t},s(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2970
2971
|
var t={}
|
|
2971
2972
|
if(null!=e)for(var r=s(e),n=0;n<r.length;n++)"default"!==r[n]&&i(t,e,r[n])
|
|
2972
2973
|
return a(t,e),t})
|
|
2973
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileBlame=async function(e,t,s,i,a){const c=i.child({tool:"file_blame"}),
|
|
2974
|
-
try{const{path:i,lines:
|
|
2975
|
-
c.info("Processing blame request",{filePath:i,lines:
|
|
2974
|
+
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()
|
|
2975
|
+
try{const{path:i,lines:g,branch:m}=e
|
|
2976
|
+
c.info("Processing blame request",{filePath:i,lines:g,branch:m})
|
|
2976
2977
|
const f=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,y=d.isAbsolute(i)?i:d.join(f,i),w=d.relative(f,y)
|
|
2977
2978
|
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
|
|
2978
2979
|
if(/^\d+$/.test(e)){const t=parseInt(e,10)
|
|
2979
2980
|
return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
|
|
2980
2981
|
if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
|
|
2981
2982
|
if(e.match(/^(\d+(?:,\d+)+)$/)){const t=e.split(",").map((e=>parseInt(e,10)))
|
|
2982
|
-
return{start:Math.min(...t),end:Math.max(...t)}}return null}(
|
|
2983
|
+
return{start:Math.min(...t),end:Math.max(...t)}}return null}(g),I=["blame","--porcelain"]
|
|
2983
2984
|
let k
|
|
2984
2985
|
b&&I.push(`-L${b.start},${b.end}`),m&&I.push(m),I.push("--",w),c.debug("Executing git blame",{args:I})
|
|
2985
2986
|
try{if(!t.git)throw Error("Git context not available")
|
|
@@ -3016,7 +3017,7 @@ if(d+=t,e.requestId){const r=a.get(e.requestId)
|
|
|
3016
3017
|
r?r.lines+=t:a.set(e.requestId,{title:e.requestTitle||"Untitled",lines:t})}else e.recordId||r(e.commitMessage)?c+=t:l+=t}if(a.size>0||c>0||l>0){i+="## Summary by Request\n\n"
|
|
3017
3018
|
const e=[...a.entries()].sort(((e,t)=>t[1].lines-e[1].lines))
|
|
3018
3019
|
for(const[t,r]of e){const e=Math.round(r.lines/d*100)
|
|
3019
|
-
i+=`- **${t}** "${n(r.title,40)}": ${r.lines} lines (${e}%)\n`}c>0&&(i+=`- **Alchemy (unlinked)**: ${c} lines (${Math.round(c/d*100)}%)\n`),l>0&&(i+=`- **External commits**: ${l} lines (${Math.round(l/d*100)}%)\n`)}return i}(w,C,b),T=Date.now()-
|
|
3020
|
+
i+=`- **${t}** "${n(r.title,40)}": ${r.lines} lines (${e}%)\n`}c>0&&(i+=`- **Alchemy (unlinked)**: ${c} lines (${Math.round(c/d*100)}%)\n`),l>0&&(i+=`- **External commits**: ${l} lines (${Math.round(l/d*100)}%)\n`)}return i}(w,C,b),T=Date.now()-p
|
|
3020
3021
|
return c.info("Blame request completed",{duration:T,groups:C.length,alchemyCommits:C.filter((e=>e.requestId)).length,externalCommits:C.filter((e=>!e.requestId)).length}),a.incrementCounter("file_blame_total",1,{success:!0}),{content:[{type:"text",text:S}]}}catch(e){return c.error("Blame request failed",{error:e instanceof Error?e.stack:e+""}),a.incrementCounter("file_blame_errors",1),{content:[{type:"text",text:"\u274c **Blame Failed:** "+(0,h.getErrorMessage)(e)}],isError:!0}}}
|
|
3021
3022
|
const l=t(1181),d=c(t(6928)),u=c(t(1943)),h=t(8824)},4921(e,exports,t){"use strict"
|
|
3022
3023
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
@@ -3178,20 +3179,20 @@ if(!/^req\d{6}$/.test(t))throw new r.ValidationError(`Invalid request ID format:
|
|
|
3178
3179
|
d.info("Getting information for request "+t)
|
|
3179
3180
|
const n=a.getRequestClient(),s=a.getTaskClient(),[c,l]=await Promise.all([n.getRequest(t),s.listTasks({requestId:t})])
|
|
3180
3181
|
d.info("Raw request response data",{responseData:JSON.stringify(c)}),d.debug("Request response structure",{type:typeof c,isArray:Array.isArray(c),hasData:null!=c,properties:c?Object.keys(c):[],dataPreview:c?JSON.stringify(c).substring(0,200)+"...":"null"})
|
|
3181
|
-
const h=(0,o.extractDataFromResponse)(c,{logger:d,operationName:"getRequestInformation",throwOnNoData:!0}),
|
|
3182
|
+
const h=(0,o.extractDataFromResponse)(c,{logger:d,operationName:"getRequestInformation",throwOnNoData:!0}),p="data"in h?h.data:h
|
|
3182
3183
|
d.info("Successfully extracted request data using data extraction utility"),d.info("Raw tasks response data",{responseData:JSON.stringify(l)}),d.debug("Tasks response structure",{type:typeof l,isArray:Array.isArray(l),hasData:null!=l,properties:l?Object.keys(l):[],dataPreview:l?JSON.stringify(l).substring(0,200)+"...":"null"})
|
|
3183
|
-
const
|
|
3184
|
-
d.info(`Successfully extracted ${
|
|
3185
|
-
const m={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:
|
|
3186
|
-
|
|
3184
|
+
const g=(0,o.extractArrayFromResponse)(l,{logger:d,operationName:"listTasksForRequest",defaultValue:[]})
|
|
3185
|
+
d.info(`Successfully extracted ${g.length} tasks using data extraction utility`)
|
|
3186
|
+
const m={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:g.length}
|
|
3187
|
+
g.forEach((e=>{const t=e.status
|
|
3187
3188
|
t in m&&m[t]++}))
|
|
3188
|
-
const f=
|
|
3189
|
+
const f=p.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_verified:0,total:f.length}
|
|
3189
3190
|
f.forEach((e=>{const t=e.status||"unverified"
|
|
3190
3191
|
t in y&&y[t]++}))
|
|
3191
|
-
let w=
|
|
3192
|
-
const b=
|
|
3193
|
-
let k=`# ${"feature"===I?"Feature":"quick-edit"===I?"Quick Edit":"Bug Fix"} Request: ${b} (${t})\nStatus: ${
|
|
3194
|
-
return k+=`\n## Task Status\n- Pending: ${m.pending}\n- In Progress: ${m.in_progress}\n- Blocked: ${m.blocked}\n- Ready for Review: ${m.ready_for_review}\n- Completed: ${m.completed}\n- Reverted: ${m.reverted}\n`,k+="\n## Tasks\n",0===
|
|
3192
|
+
let w=p.testVerification||null
|
|
3193
|
+
const b=p.title,I=p.type
|
|
3194
|
+
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: ${m.completed}/${m.total} completed (${Math.round(m.completed/m.total*100)||0}%)\n- Acceptance Criteria: ${y.verified}/${y.total} verified (${Math.round(y.verified/y.total*100)||0}%)\n`
|
|
3195
|
+
return k+=`\n## Task Status\n- Pending: ${m.pending}\n- In Progress: ${m.in_progress}\n- Blocked: ${m.blocked}\n- Ready for Review: ${m.ready_for_review}\n- Completed: ${m.completed}\n- Reverted: ${m.reverted}\n`,k+="\n## Tasks\n",0===g.length?k+="No tasks found for this request.\n":g.forEach((e=>{k+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${g.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()
|
|
3195
3196
|
k+=`- ${t}: ${e.description}\n`}))),u({success:!0}),{content:[{type:"text",text:k}]}}catch(t){return d.error("Error getting request information",{args:e,error:t instanceof Error?t.stack:t+""}),u({success:!1,error:t instanceof Error?t.name:"unknown"}),t instanceof n.ConnectionError?{content:[{type:"text",text:"Unable to get request information: Connection to the server failed. Please check your network connection and try again."}],isError:!0}:{content:[{type:"text",text:"Error getting request information: "+(0,s.getErrorMessage)(t)}],isError:!0}}}
|
|
3196
3197
|
const r=t(9860),n=t(5674),o=t(2960),s=t(8824),i=t(5454)},5454(e,exports){"use strict"
|
|
3197
3198
|
function t(e,t){let r=0
|
|
@@ -3232,7 +3233,7 @@ if(c.incrementCounter("document_operations_total",1,{operation:"list-annotations
|
|
|
3232
3233
|
let r=`## Annotations on ${h} (${t.length})\n\n`
|
|
3233
3234
|
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`
|
|
3234
3235
|
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")
|
|
3235
|
-
const e=o.selectedText,t=o.body,{prefixContext:r,suffixContext:n,lineHint:a}=o,l=i.getDocumentClient(),
|
|
3236
|
+
const e=o.selectedText,t=o.body,{prefixContext:r,suffixContext:n,lineHint:a}=o,l=i.getDocumentClient(),p=d?"agent":void 0,g=d?.sessionId,m=await l.createAnnotation(h,{selectedText:e,prefixContext:r,suffixContext:n,lineHint:a,body:t,createdByAgent:p,createdBySessionId:g})
|
|
3236
3237
|
return c.incrementCounter("document_operations_total",1,{operation:"create-annotation",success:!0}),(0,s.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Annotation Created**\n\n**ID:** ${m.id}\n**Document:** ${h}\n**Selected text:** "${e.substring(0,60)}"\n**Comment:** `+t}]},"create-annotation")}case"reply-to-annotation":{u.info("Replying to annotation")
|
|
3237
3238
|
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})
|
|
3238
3239
|
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")
|
|
@@ -3261,31 +3262,31 @@ return{isOffline:this.isInOfflineMode(),consecutiveFailures:e.consecutiveFailure
|
|
|
3261
3262
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3262
3263
|
const r=t(6183),n=t(2965)
|
|
3263
3264
|
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"
|
|
3264
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const
|
|
3265
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const p=l.child({tool:"complete_request"}),g=d.startTimer("tool_execution_time")
|
|
3265
3266
|
try{const{requestId:n,summary:o}=e
|
|
3266
3267
|
if(!n)throw(0,r.createValidationError)("Request ID is required")
|
|
3267
3268
|
if(!o)throw(0,r.createValidationError)("Summary is required")
|
|
3268
|
-
|
|
3269
|
+
p.info("Starting request completion",{requestId:n})
|
|
3269
3270
|
const l=h?.sessionId
|
|
3270
3271
|
let d
|
|
3271
3272
|
try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:l})
|
|
3272
3273
|
d=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3273
|
-
return
|
|
3274
|
-
return d.blockedByTasks&&d.blockedByTasks.length>0&&(e+="\n**Tasks that must be completed or canceled first:**\n",d.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (Status: ${t.status})\n`}))),d.lifoViolation&&(e+="\n**Requests that must be re-completed first (LIFO order):**\n",d.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (Status: ${t.status})\n`}))),
|
|
3274
|
+
return p.error("Server validation failed",{requestId:n,error:t}),g({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`
|
|
3275
|
+
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`}))),g({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}const u=c.getRequestClient()
|
|
3275
3276
|
let m,f="auto-test-then-merge"===d.completionMode,y=null
|
|
3276
|
-
if(f)try{const[e,r]=await Promise.all([c.proxyGet(`/api/projects/${t.projectId}/requests/${n}/test-runs`),fetch(`${(0,a.getActionServerBaseUrl)()}/api/branch-head?requestId=${encodeURIComponent(n)}`,{signal:AbortSignal.timeout(5e3)}).catch((e=>(
|
|
3277
|
+
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
|
|
3277
3278
|
if(i&&"passed"===i.status&&i.commitSha){let e=null
|
|
3278
3279
|
if(r&&r.ok){const t=await r.json()
|
|
3279
|
-
e=t?.data?.sha??null}e&&e===i.commitSha&&(f=!1,y=`latest test run ${i.id} passed against current branch HEAD ${e.slice(0,7)}`,m=i.id,
|
|
3280
|
+
e=t?.data?.sha??null}e&&e===i.commitSha&&(f=!1,y=`latest test run ${i.id} passed against current branch HEAD ${e.slice(0,7)}`,m=i.id,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"
|
|
3280
3281
|
try{await u.updateRequest(n,{status:w,completionSummary:o,...m?{skippedTestRunId:m}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3281
|
-
return
|
|
3282
|
+
return g({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let b
|
|
3282
3283
|
try{b=await u.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3283
|
-
return
|
|
3284
|
-
if(
|
|
3284
|
+
return g({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const I=b?.acceptanceCriteria||[]
|
|
3285
|
+
if(g({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.`}]}
|
|
3285
3286
|
const k=y?`\n\n_Skipped re-running tests: ${y}._\n`:""
|
|
3286
3287
|
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=""
|
|
3287
|
-
r instanceof n.ZodError?(s="Validation error",i=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")):r instanceof Error?(s=r.message,i=r.stack||""):i=r+"",
|
|
3288
|
-
try{await(0,o.createFailureToolRecord)("complete-request",r,{error:s,details:i,requestId:e?.requestId},c.getToolRecordClient(),
|
|
3288
|
+
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})
|
|
3289
|
+
try{await(0,o.createFailureToolRecord)("complete-request",r,{error:s,details:i,requestId:e?.requestId},c.getToolRecordClient(),p,d,{requestId:e?.requestId,projectId:t.projectId,note:"Failed to complete request"})}catch{}return d.startTimer("tool_execution_time")({success:!1,error:r instanceof Error?r.name:"unknown"}),{content:[{type:"text",text:"Error: "+s}],isError:!0}}}
|
|
3289
3290
|
const r=t(9860),n=t(1569),o=t(8616),s=t(8824),i=t(5454),a=t(9414)},5767(e,exports,t){"use strict"
|
|
3290
3291
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3291
3292
|
const r=t(6183),n=t(6285)
|
|
@@ -3346,13 +3347,13 @@ let W=0
|
|
|
3346
3347
|
x.length>0&&n.setProjectId(r.projectId)
|
|
3347
3348
|
for(let e=0;e<$.length;e++){const t=$[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3348
3349
|
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)
|
|
3349
|
-
await a.default.unlink(t.full),r.success=!0,W++,m.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,
|
|
3350
|
+
await a.default.unlink(t.full),r.success=!0,W++,m.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,g.getErrorMessage)(e),m.warn("Failed to delete file "+t.normalized,{error:r.error})}G.push(r)}const V=x.length>0?n.getDocumentClient():null
|
|
3350
3351
|
for(const e of x){const t=e.target,r={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3351
3352
|
try{let e
|
|
3352
3353
|
try{if(e=await V.getDocument(t),r.filename=e.filename,m.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,h.validateRequestStatusForDocumentOperation)(e.requestId,v,m,s,"delete-document")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
|
|
3353
|
-
throw e}try{await(0,
|
|
3354
|
-
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,
|
|
3355
|
-
r.success=!0,r.filename=o.filename,W++,m.info("Document archived successfully",{documentId:o.id,filename:o.filename,archivedAt:o.archived_at})}catch(e){r.error=(0,
|
|
3354
|
+
throw e}try{await(0,p.ensureDocumentNotLocked)(t,n,m,s,"delete-document-archive")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
|
|
3355
|
+
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,g.getErrorMessage)(e)}`)}const o=await V.archiveDocument(t)
|
|
3356
|
+
r.success=!0,r.filename=o.filename,W++,m.info("Document archived successfully",{documentId:o.id,filename:o.filename,archivedAt:o.archived_at})}catch(e){r.error=(0,g.getErrorMessage)(e),m.warn("Failed to delete document "+t,{error:r.error})}G.push(r)}const K=Date.now()-f
|
|
3356
3357
|
s.recordValue("delete_files_time",K),s.incrementCounter("delete_files_operations_total",M),s.incrementCounter("delete_files_operations_success",W),s.incrementCounter("delete_files_operations_failed",M-W),s.incrementCounter("delete_files_file_operations",R.length),s.incrementCounter("delete_files_document_operations",x.length),W===M?s.incrementCounter("delete_files_success",1):W>0?s.incrementCounter("delete_files_partial_success",1):s.incrementCounter("delete_files_total_failure",1)
|
|
3357
3358
|
let J=null
|
|
3358
3359
|
if(W>0){b=c.FileOperationPhase.GIT_COMMIT,s.incrementCounter("delete_files_phase",1,{phase:b})
|
|
@@ -3368,11 +3369,11 @@ X=e>0&&t>0?`Successfully deleted ${e} files and ${t} documents`:e>0?`Successfull
|
|
|
3368
3369
|
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})`
|
|
3369
3370
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
|
|
3370
3371
|
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
|
|
3371
|
-
await o.createToolRecord({...s?{}:{taskId:e.taskId},projectId:r.projectId,type:"delete-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment,error:(0,
|
|
3372
|
-
if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),m.error("Error in delete-files operation:",{error:(0,
|
|
3372
|
+
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,g.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,g.getErrorMessage)(t)})}catch(t){m.error("Failed to create failure record for delete-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0})}const o=Date.now()-f
|
|
3373
|
+
if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),m.error("Error in delete-files operation:",{error:(0,g.getErrorMessage)(t),time:o}),(y||w)&&e.taskId){b=c.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
3373
3374
|
try{const r=n.getTaskClient(),o=n.getToolRecordClient()
|
|
3374
|
-
await c.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",I.recordType,"Failed to delete operations",{status:"failed",error:(0,
|
|
3375
|
-
const a=i(t(1943)),c=s(t(5967)),l=t(9860),d=t(1569),u=t(7478),h=t(5003),
|
|
3375
|
+
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,g.getErrorMessage)(t),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment},"Failed to delete operations",r,o,m,s,I.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return c.handleFileOperationError(t,b,m,s,e,I)}}
|
|
3376
|
+
const a=i(t(1943)),c=s(t(5967)),l=t(9860),d=t(1569),u=t(7478),h=t(5003),p=t(9949),g=t(8824)},5997(e,exports,t){"use strict"
|
|
3376
3377
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3377
3378
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3378
3379
|
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=[]
|
|
@@ -3445,17 +3446,17 @@ if("create"===r?(e.name||t.addIssue({code:"custom",message:"name is required for
|
|
|
3445
3446
|
r||n||t.addIssue({code:"custom",message:"update requires either 'content' (plan or quest body) or at least one metadata field (criteria, tickIntervalSeconds, maxInFlight, maxPerDay, minIterations, status \u2014 quest only)."})}"replace"===r&&(e.old||t.addIssue({code:"custom",message:'old is required for replace. Example: { "operation": "replace", "planId": "plan000001", "old": "find this", "new": "replace with" }'}),void 0===e.new&&t.addIssue({code:"custom",message:"new is required for replace"})),"restore"!==r||e.versionNumber||t.addIssue({code:"custom",message:'versionNumber is required for restore. Example: { "operation": "restore", "planId": "plan000001", "versionNumber": 1 }'})})),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:a,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),operationType:r.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:r.z.object({replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).optional(),insertLines:r.z.object({insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).optional(),replaceLines:r.z.object({replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).optional(),deleteString:r.z.object({patterns:r.z.array(r.z.string()),mode:r.z.enum(["all","unique"]).optional()}).optional(),deleteLines:r.z.object({lines:r.z.string()}).optional()}).transform(l).refine(d,{message:"path or documentId required"}).refine((e=>"replace-string"===e.operationType?e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"insert-lines"===e.operationType?e.insertLines&&!e.replaceString&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"replace-lines"===e.operationType?e.replaceLines&&!e.replaceString&&!e.insertLines&&!e.deleteString&&!e.deleteLines:"delete-string"===e.operationType?e.deleteString&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteLines:"delete-lines"===e.operationType&&e.deleteLines&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString),{message:"Invalid operation data"})),comment:r.z.string()}),exports.ManageFilesSchema=r.z.object({operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"}))}).optional(),getFileInfo:r.z.object({path:r.z.string()}).optional()}).refine((e=>"create-directory"===e.operationType?e.createDirectory&&!e.moveFiles&&!e.deleteFiles&&!e.getFileInfo:"move-files"===e.operationType?e.moveFiles&&!e.createDirectory&&!e.deleteFiles&&!e.getFileInfo:"delete-files"===e.operationType?e.deleteFiles&&!e.createDirectory&&!e.moveFiles&&!e.getFileInfo:"get-file-info"===e.operationType&&e.getFileInfo&&!e.createDirectory&&!e.moveFiles&&!e.deleteFiles),{message:"Invalid operation data"})),comment:r.z.string()}),exports.RequestOperationsSchema=r.z.object({requestId:a.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search","delete-empty"]),complete:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({summary:r.z.string()})).optional(),merge:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({verifications:r.z.array(r.z.object({key:r.z.string().min(2).max(4),evidence:r.z.string().min(1)})).min(1)})).optional(),revert:r.z.object({reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}).optional(),list:r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),approve:r.z.object({}).optional()}).superRefine(((e,t)=>{e.requestId
|
|
3446
3447
|
const r=e.operation,n={complete:{field:"complete",hint:'Provide: { complete: { summary: "..." } }'},merge:{field:"merge",hint:'Provide: { merge: { verifications: [{key: "1a", evidence: "..."}] } }'},revert:{field:"revert",hint:'Provide: { revert: { reason: "..." } }'},search:{field:"search",hint:'Provide: { search: { query: "..." } }'}}[r]
|
|
3447
3448
|
n&&!e[n.field]&&t.addIssue({code:"custom",message:`'${r}' operation requires '${n.field}' data. ${n.hint}`})})),exports.QuickWriteSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),path:r.z.string().optional(),documentId:c.optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"}),exports.QuickReplaceSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"})).min(1),fuzzy_match:r.z.boolean().optional(),comment:r.z.string().min(1,"Comment describing the change is required")}),exports.QuickManageSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"}))}).optional()})).min(1)}),exports.GenerateRequestJournalSchema=r.z.object({requestId:r.z.string().regex(/^req[_\d].+$/,"Invalid request ID format. Expected format: req_[26 chars] or req######")}),exports.MetaWorkflowListSchema=r.z.object({}),exports.MetaWorkflowGetSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the workflow"),shortName:r.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:r.z.string().optional().describe("Description of what the workflow does"),documentation:r.z.string().optional().describe("Detailed documentation"),defaultAgent:r.z.string().optional().describe("Default agent template to use"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior: auto-merge (default), auto-test-then-merge, or manual-review"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaWorkflowUpdateSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to update"),name:r.z.string().min(1).optional().describe("New name"),shortName:r.z.string().max(10).optional().describe("New short name (max 10 chars)"),description:r.z.string().optional().describe("New description"),documentation:r.z.string().optional().describe("New documentation"),defaultAgent:r.z.string().optional().describe("New default agent"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaRecipeListSchema=r.z.object({}),exports.MetaRecipeGetSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to retrieve")}),exports.MetaRecipeCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the recipe"),description:r.z.string().optional().describe("Description of what the recipe does"),documentation:r.z.string().optional().describe("Detailed documentation")}),exports.MetaRecipeAddHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to add the hook to"),hookId:r.z.string().describe("Hook template ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the recipe (0-based, appended if omitted)")}),exports.MetaRecipeRemoveHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to remove the hook from"),hookId:r.z.string().describe("Hook template ID to remove")}),exports.MetaHookListSchema=r.z.object({}),exports.MetaHookCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the hook"),description:r.z.string().optional().describe("Description of what the hook does"),eventType:r.z.string().describe("Event type that triggers this hook (e.g., session_idle, request_completed, custom:plan_ready)"),category:r.z.enum(["alchemy","session","message","editing","reading","file_management","documents","history","tool"]).default("session").describe("Hook category"),agent:r.z.string().describe("Agent template to execute when hook fires"),promptTemplate:r.z.string().describe("Prompt template with {{variable}} substitution"),condition:r.z.record(r.z.any()).optional().describe("Condition object for filtering when hook fires"),executionMode:r.z.enum(["same_session","sub_agent","background","notification","direct_report"]).default("background").describe("How to execute the hook"),timing:r.z.enum(["before","after"]).default("after").describe("When to fire relative to the event"),maxIterations:r.z.number().int().min(1).optional().describe("Maximum times to fire per session"),emitEvent:r.z.string().optional().describe("Custom event to emit on completion"),emitEventOnCondition:r.z.union([r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}),r.z.array(r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}))]).optional().describe("Conditional event emission based on output")}),exports.MetaWorkflowAddRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to add the recipe to"),recipeId:r.z.string().describe("Recipe ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the workflow (0-based, appended if omitted)")}),exports.MetaWorkflowRemoveRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to remove the recipe from"),recipeId:r.z.string().describe("Recipe ID to remove")}),exports.MetaAgentListSchema=r.z.object({}),exports.MetaReferenceSchema=r.z.object({}),exports.TestingProcessListSchema=r.z.object({}),exports.TestingProcessGetSchema=r.z.object({processId:r.z.string().describe("Test process ID to retrieve")})
|
|
3448
|
-
const
|
|
3449
|
-
exports.TestingProcessCreateSchema=r.z.object({name:r.z.string().min(1).describe("Name for the test process"),description:r.z.string().optional().describe("Description of what this process verifies"),scope:r.z.string().optional().describe('Path prefix for monorepo scoping (e.g., "packages/api/"). Omit for global.'),setup:r.z.array(r.z.string()).optional().describe('Commands to prepare the environment (e.g., ["ln -s ../../node_modules node_modules"])'),commands:r.z.array(g).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe('Files whose content invalidates setup. Setup commands re-run only when these files change between runs (e.g. ["package-lock.json"], ["Cargo.lock"], ["uv.lock", "poetry.lock"]). Polyglot repos list multiple. Omit / empty list = always re-run setup (existing behavior).'),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool. Default 2. Set to 1 for languages with very large build artifacts (Rust target/, C++ build/). Higher values allow more parallel test runs at the cost of disk.")}),exports.TestingProcessDeleteSchema=r.z.object({processId:r.z.string().describe("Test process ID to delete")}),exports.TestingProcessUpdateSchema=r.z.object({processId:r.z.string().describe("Test process ID to update"),name:r.z.string().min(1).optional().describe("New name"),description:r.z.string().optional().describe("New description"),scope:r.z.string().optional().describe('New scope to limit when this process runs (e.g., "packages/api/"). Omit to leave unchanged.'),isActive:r.z.boolean().optional().describe("Enable or disable the process"),setup:r.z.array(r.z.string()).optional().describe("New setup commands (replaces existing)"),commands:r.z.array(g).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe("Files whose content invalidates setup (replaces existing list)."),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool (replaces existing).")}),exports.TestingReferenceSchema=r.z.object({}),exports.TestsSchema=r.z.object({operation:r.z.enum(["list","setup","run"]).describe('"list" to see registered test processes for this project. "setup" to spawn an interactive test-architect session that helps configure a process. "run" to fire an async test run against the active process for your current request \u2014 optional `name` filters to one registered command. The call returns immediately and you receive a report on your next turn.'),name:r.z.string().optional().describe("Only used by `run`. Filters execution to a single test command by name (matches a command name registered in the test process). Omit to run all required commands.")}),exports.ExecuteTestCommandSchema=r.z.object({processId:r.z.string().describe("Test process ID containing the command"),commandName:r.z.string().describe('Name of the test command to run, or "setup" to run all setup commands in sequence')}),exports.CommandsSchema=r.z.object({operation:r.z.enum(["run","list","remove","register","setup"]).default("run").describe('"run" to execute a command, "list" to see available commands, "register" to submit one or more commands for user approval (a single-item array works for one command; multiple items get bundled into a single batch approval notification), "remove" to delete one, "setup" to spawn the command-architect for an interactive setup interview (mirrors tests.setup)'),name:r.z.string().optional().describe('Command name (required for "run", "add", and "remove")'),args:r.z.string().optional().describe('Additional arguments appended to the base command (optional, for "run")'),grep:r.z.string().optional().describe('Filter output through grep (optional, for "run"). Pipes command output through grep -i with this pattern.'),command:r.z.string().optional().describe('Shell command to register (required for "add", e.g. "tsc --noEmit")'),description:r.z.string().optional().describe('What this command verifies. REQUIRED when operation is "add" \u2014 must articulate the command\'s purpose so the audit trail (added_by_session_id + description) is meaningful in the project commands UI.'),timeout:r.z.number().optional().describe('Timeout in seconds (optional, for "add", default 60)'),cwd:r.z.string().optional().describe('Working directory relative to project root (optional, for "add", e.g. "apps/web"). Omit to run at project root \u2014 use this for monorepos where the command lives in a subdir.'),context:r.z.string().optional().describe('Optional caller hint for the "setup" operation \u2014 short note about what the calling agent thinks the user needs (e.g. "specialist asked for npm run build with strict TS"). The architect treats this as a hint but still does its own discovery + user confirmation.'),commands:r.z.array(r.z.object({name:r.z.string().min(1).describe('Command name (e.g. "test:web")'),command:r.z.string().min(1).describe("Shell command to execute"),description:r.z.string().min(1).describe("What this command verifies"),cwd:r.z.string().optional().describe("Working directory relative to project root (omit for root)"),timeout:r.z.number().optional().describe("Timeout in seconds (default 60)")})).optional().describe('Batch of commands to register (required for "register", ignored otherwise). Each item must have name, command, and description. cwd is optional and supports monorepo subdirs.')}),exports.ReportTestResultsSchema=r.z.object({status:r.z.enum(["passed","failed","error"]).describe("Overall result"),results:r.z.object({commands:r.z.array(r.z.object({name:r.z.string().describe("Command name"),status:r.z.enum(["passed","failed","skipped","error"]).describe("Command result"),output:r.z.string().optional().describe("Relevant output snippet"),diagnosis:r.z.string().optional().describe("Why it failed, if applicable")})).describe("Per-command results"),summary:r.z.string().describe("Brief overall summary"),acceptanceCriteria:r.z.array(r.z.object({criterion:r.z.string().describe("The acceptance criterion text"),status:r.z.enum(["verified","unverified","unclear"]),evidence:r.z.string().describe("How verified, or why not")})).optional().describe("AC verification results, if applicable")}).describe("Structured test results")}),exports.SessionMessageOperationsSchema=r.z.object({operation:r.z.enum(["send","reply","list","get","offer-handoff"]),type:r.z.enum(["question","report"]).optional().describe("Message type to send (required for send)"),toSessionId:r.z.string().optional().describe('Target session ID, or "parent" to auto-resolve to parent session (omit for broadcast questions)'),questionType:r.z.enum(["free-form","alternatives"]).optional().describe('Type of question (required for send type="question")'),questionContent:r.z.object({question:r.z.string().min(1).describe("The question text"),context:r.z.string().optional().describe("Additional context"),options:r.z.array(r.z.object({id:r.z.string(),label:r.z.string(),description:r.z.string().optional()})).optional().describe("Options for alternatives questions"),allowMultiple:r.z.boolean().optional().describe("Allow selecting multiple options")}).optional().describe('Question content (required for send type="question")'),priority:r.z.enum(["low","normal","high"]).optional().describe("Question priority"),expiresInHours:r.z.number().optional().describe("Question expiry in hours"),status:r.z.enum(["success","partial","failure","blocked"]).optional().describe('Report status (required for send type="report")'),summary:r.z.string().optional().describe('Report summary (required for send type="report")'),details:r.z.string().optional().describe("Report details"),finish:r.z.boolean().optional().describe("Release request associations after report"),relatesTo:r.z.string().regex(/^I-[A-Za-z0-9]+-\d+$/,'relatesTo must be an instruction code like "I-abc12345-001"').optional().describe("Optional instruction code (I-...) this question or report relates to"),messageCode:r.z.string().optional().describe("Message code (required for reply and get operations)"),respondedBySessionId:r.z.string().optional().describe("Session ID answering the question. Optional \u2014 auto-filled from the caller's session (_meta.sessionId) when omitted; only pass explicitly to answer on behalf of a different session (e.g. UI passing 'user')."),text:r.z.string().optional().describe("Text answer for free-form questions"),selectedOptions:r.z.array(r.z.string()).optional().describe("Selected option IDs for alternatives"),notes:r.z.string().optional().describe("Additional notes"),list:r.z.object({sessionId:r.z.string().optional().describe("Filter by session ID (auto-discovered if omitted)"),messageType:r.z.enum(["question","report","instruction","all"]).default("all").describe("Filter by message type"),direction:r.z.enum(["incoming","outgoing","all"]).default("all"),status:r.z.enum(["pending","answered","expired","success","partial","failure","blocked","all"]).default("all").describe("Filter by status"),readStatus:r.z.enum(["unread","read","acknowledged","all"]).default("all").describe("Filter by read status (reports only)"),limit:r.z.number().min(1).max(100).default(50),offset:r.z.number().min(0).default(0)}).optional().describe('List filters (operation: "list" only)'),offerHandoff:r.z.object({summary:r.z.string().describe("Summary of what was planned/created"),requestIds:r.z.array(r.z.string()).describe("Request IDs that were created from the plan")}).optional().describe('Handoff offer details (operation: "offer-handoff" only)')}).refine((e=>"send"===e.operation?!!e.type:"reply"===e.operation?!!e.messageCode:"list"===e.operation||("get"===e.operation?!!e.messageCode:"offer-handoff"===e.operation)),{message:"Invalid operation data: send requires type, reply requires messageCode, get requires messageCode"}),exports.UpdateSpecializationSchema=r.z.object({specialization:r.z.string().min(1).max(500).describe("Your updated specialization summary \u2014 a concise description of your accumulated domain expertise"),specializationHeadline:r.z.string().min(1).max(80).optional().describe("Short tagline (\u226480 chars) summarising your domain at a glance \u2014 shown next to your name in the alchemist\u2019s specialist directory. Keep it current alongside the longer specialization.")}),exports.CommitToViewedSessionSchema=r.z.object({message:r.z.coerce.string().min(1).describe("The cleaned-up user message to post to the viewed session. Fix obvious dictation errors, add punctuation, but preserve the user's intent exactly.")})},6252(e,exports,t){"use strict"
|
|
3449
|
+
const p=r.z.object({name:r.z.string().min(1).describe('Command name (e.g., "Build", "Unit Tests")'),command:r.z.string().min(1).describe('Shell command to run (e.g., "npm test")'),required:r.z.boolean().default(!0).describe("If true, failure blocks the request (default: true)"),timeout:r.z.number().int().min(10).max(3600).default(300).describe("Max execution time in seconds (default: 300)")})
|
|
3450
|
+
exports.TestingProcessCreateSchema=r.z.object({name:r.z.string().min(1).describe("Name for the test process"),description:r.z.string().optional().describe("Description of what this process verifies"),scope:r.z.string().optional().describe('Path prefix for monorepo scoping (e.g., "packages/api/"). Omit for global.'),setup:r.z.array(r.z.string()).optional().describe('Commands to prepare the environment (e.g., ["ln -s ../../node_modules node_modules"])'),commands:r.z.array(p).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe('Files whose content invalidates setup. Setup commands re-run only when these files change between runs (e.g. ["package-lock.json"], ["Cargo.lock"], ["uv.lock", "poetry.lock"]). Polyglot repos list multiple. Omit / empty list = always re-run setup (existing behavior).'),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool. Default 2. Set to 1 for languages with very large build artifacts (Rust target/, C++ build/). Higher values allow more parallel test runs at the cost of disk.")}),exports.TestingProcessDeleteSchema=r.z.object({processId:r.z.string().describe("Test process ID to delete")}),exports.TestingProcessUpdateSchema=r.z.object({processId:r.z.string().describe("Test process ID to update"),name:r.z.string().min(1).optional().describe("New name"),description:r.z.string().optional().describe("New description"),scope:r.z.string().optional().describe('New scope to limit when this process runs (e.g., "packages/api/"). Omit to leave unchanged.'),isActive:r.z.boolean().optional().describe("Enable or disable the process"),setup:r.z.array(r.z.string()).optional().describe("New setup commands (replaces existing)"),commands:r.z.array(p).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe("Files whose content invalidates setup (replaces existing list)."),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool (replaces existing).")}),exports.TestingReferenceSchema=r.z.object({}),exports.TestsSchema=r.z.object({operation:r.z.enum(["list","setup","run"]).describe('"list" to see registered test processes for this project. "setup" to spawn an interactive test-architect session that helps configure a process. "run" to fire an async test run against the active process for your current request \u2014 optional `name` filters to one registered command. The call returns immediately and you receive a report on your next turn.'),name:r.z.string().optional().describe("Only used by `run`. Filters execution to a single test command by name (matches a command name registered in the test process). Omit to run all required commands.")}),exports.ExecuteTestCommandSchema=r.z.object({processId:r.z.string().describe("Test process ID containing the command"),commandName:r.z.string().describe('Name of the test command to run, or "setup" to run all setup commands in sequence')}),exports.CommandsSchema=r.z.object({operation:r.z.enum(["run","list","remove","register","setup"]).default("run").describe('"run" to execute a command, "list" to see available commands, "register" to submit one or more commands for user approval (a single-item array works for one command; multiple items get bundled into a single batch approval notification), "remove" to delete one, "setup" to spawn the command-architect for an interactive setup interview (mirrors tests.setup)'),name:r.z.string().optional().describe('Command name (required for "run", "add", and "remove")'),args:r.z.string().optional().describe('Additional arguments appended to the base command (optional, for "run")'),grep:r.z.string().optional().describe('Filter output through grep (optional, for "run"). Pipes command output through grep -i with this pattern.'),command:r.z.string().optional().describe('Shell command to register (required for "add", e.g. "tsc --noEmit")'),description:r.z.string().optional().describe('What this command verifies. REQUIRED when operation is "add" \u2014 must articulate the command\'s purpose so the audit trail (added_by_session_id + description) is meaningful in the project commands UI.'),timeout:r.z.number().optional().describe('Timeout in seconds (optional, for "add", default 60)'),cwd:r.z.string().optional().describe('Working directory relative to project root (optional, for "add", e.g. "apps/web"). Omit to run at project root \u2014 use this for monorepos where the command lives in a subdir.'),context:r.z.string().optional().describe('Optional caller hint for the "setup" operation \u2014 short note about what the calling agent thinks the user needs (e.g. "specialist asked for npm run build with strict TS"). The architect treats this as a hint but still does its own discovery + user confirmation.'),commands:r.z.array(r.z.object({name:r.z.string().min(1).describe('Command name (e.g. "test:web")'),command:r.z.string().min(1).describe("Shell command to execute"),description:r.z.string().min(1).describe("What this command verifies"),cwd:r.z.string().optional().describe("Working directory relative to project root (omit for root)"),timeout:r.z.number().optional().describe("Timeout in seconds (default 60)")})).optional().describe('Batch of commands to register (required for "register", ignored otherwise). Each item must have name, command, and description. cwd is optional and supports monorepo subdirs.')}),exports.ReportTestResultsSchema=r.z.object({status:r.z.enum(["passed","failed","error"]).describe("Overall result"),results:r.z.object({commands:r.z.array(r.z.object({name:r.z.string().describe("Command name"),status:r.z.enum(["passed","failed","skipped","error"]).describe("Command result"),output:r.z.string().optional().describe("Relevant output snippet"),diagnosis:r.z.string().optional().describe("Why it failed, if applicable")})).describe("Per-command results"),summary:r.z.string().describe("Brief overall summary"),acceptanceCriteria:r.z.array(r.z.object({criterion:r.z.string().describe("The acceptance criterion text"),status:r.z.enum(["verified","unverified","unclear"]),evidence:r.z.string().describe("How verified, or why not")})).optional().describe("AC verification results, if applicable")}).describe("Structured test results")}),exports.SessionMessageOperationsSchema=r.z.object({operation:r.z.enum(["send","reply","list","get","offer-handoff"]),type:r.z.enum(["question","report"]).optional().describe("Message type to send (required for send)"),toSessionId:r.z.string().optional().describe('Target session ID, or "parent" to auto-resolve to parent session (omit for broadcast questions)'),questionType:r.z.enum(["free-form","alternatives"]).optional().describe('Type of question (required for send type="question")'),questionContent:r.z.object({question:r.z.string().min(1).describe("The question text"),context:r.z.string().optional().describe("Additional context"),options:r.z.array(r.z.object({id:r.z.string(),label:r.z.string(),description:r.z.string().optional()})).optional().describe("Options for alternatives questions"),allowMultiple:r.z.boolean().optional().describe("Allow selecting multiple options")}).optional().describe('Question content (required for send type="question")'),priority:r.z.enum(["low","normal","high"]).optional().describe("Question priority"),expiresInHours:r.z.number().optional().describe("Question expiry in hours"),status:r.z.enum(["success","partial","failure","blocked"]).optional().describe('Report status (required for send type="report")'),summary:r.z.string().optional().describe('Report summary (required for send type="report")'),details:r.z.string().optional().describe("Report details"),finish:r.z.boolean().optional().describe("Release request associations after report"),relatesTo:r.z.string().regex(/^I-[A-Za-z0-9]+-\d+$/,'relatesTo must be an instruction code like "I-abc12345-001"').optional().describe("Optional instruction code (I-...) this question or report relates to"),messageCode:r.z.string().optional().describe("Message code (required for reply and get operations)"),respondedBySessionId:r.z.string().optional().describe("Session ID answering the question. Optional \u2014 auto-filled from the caller's session (_meta.sessionId) when omitted; only pass explicitly to answer on behalf of a different session (e.g. UI passing 'user')."),text:r.z.string().optional().describe("Text answer for free-form questions"),selectedOptions:r.z.array(r.z.string()).optional().describe("Selected option IDs for alternatives"),notes:r.z.string().optional().describe("Additional notes"),list:r.z.object({sessionId:r.z.string().optional().describe("Filter by session ID (auto-discovered if omitted)"),messageType:r.z.enum(["question","report","instruction","all"]).default("all").describe("Filter by message type"),direction:r.z.enum(["incoming","outgoing","all"]).default("all"),status:r.z.enum(["pending","answered","expired","success","partial","failure","blocked","all"]).default("all").describe("Filter by status"),readStatus:r.z.enum(["unread","read","acknowledged","all"]).default("all").describe("Filter by read status (reports only)"),limit:r.z.number().min(1).max(100).default(50),offset:r.z.number().min(0).default(0)}).optional().describe('List filters (operation: "list" only)'),offerHandoff:r.z.object({summary:r.z.string().describe("Summary of what was planned/created"),requestIds:r.z.array(r.z.string()).describe("Request IDs that were created from the plan")}).optional().describe('Handoff offer details (operation: "offer-handoff" only)')}).refine((e=>"send"===e.operation?!!e.type:"reply"===e.operation?!!e.messageCode:"list"===e.operation||("get"===e.operation?!!e.messageCode:"offer-handoff"===e.operation)),{message:"Invalid operation data: send requires type, reply requires messageCode, get requires messageCode"}),exports.UpdateSpecializationSchema=r.z.object({specialization:r.z.string().min(1).max(500).describe("Your updated specialization summary \u2014 a concise description of your accumulated domain expertise"),specializationHeadline:r.z.string().min(1).max(80).optional().describe("Short tagline (\u226480 chars) summarising your domain at a glance \u2014 shown next to your name in the alchemist\u2019s specialist directory. Keep it current alongside the longer specialization.")}),exports.CommitToViewedSessionSchema=r.z.object({message:r.z.coerce.string().min(1).describe("The cleaned-up user message to post to the viewed session. Fix obvious dictation errors, add punctuation, but preserve the user's intent exactly.")})},6252(e,exports,t){"use strict"
|
|
3450
3451
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3451
3452
|
const r=t(6183),n=t(405)
|
|
3452
3453
|
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"
|
|
3453
3454
|
module.exports=require("events")},6285(e,exports,t){"use strict"
|
|
3454
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,d,u,h,g
|
|
3455
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,d,u,h,p,g){const m=u.child({tool:"specialist_ops"}),f=h.startTimer("tool_execution_time")
|
|
3455
3456
|
try{const u=e,{operation:y,sessionId:w}=u
|
|
3456
3457
|
let b
|
|
3457
|
-
switch(m.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=
|
|
3458
|
-
if(r&&
|
|
3458
|
+
switch(m.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=g?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3459
|
+
if(r&&p){const t=await async function(e,t,r,o,s){o.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
|
|
3459
3460
|
const a=await(0,i.getServerUrl)(r,o)
|
|
3460
3461
|
if(a)try{const r=await fetch(a.replace(/\/$/,"")+"/session")
|
|
3461
3462
|
if(!r.ok)return
|
|
@@ -3466,9 +3467,9 @@ if(!i)return
|
|
|
3466
3467
|
const c=n.map((e=>e.id)),l=await i.batchEnrich(c),d=await fetch(a.replace(/\/$/,"")+"/session/status"),u=d.ok?await d.json():{},h=n.filter((e=>{const t=l[e.id]
|
|
3467
3468
|
return"specialist"===t?.agentType&&"archived"!==t?.status}))
|
|
3468
3469
|
if(o.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
|
|
3469
|
-
const
|
|
3470
|
+
const p=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
|
|
3470
3471
|
return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
|
|
3471
|
-
return{content:[{type:"text",text:`\u274c Specialist pool is full (${h.length}/${t}).\nAbort an idle specialist first with \`specialist_ops abort\`, then delegate again.\n\nCurrent pool:\n`+
|
|
3472
|
+
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,m,p)
|
|
3472
3473
|
if(t){b=t
|
|
3473
3474
|
break}}let c=u.description||u.prompt.slice(0,60)
|
|
3474
3475
|
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`)
|
|
@@ -3478,18 +3479,18 @@ if(h("session fetch status="+t.status),t.ok){const e=(await t.json()).filter((e=
|
|
|
3478
3479
|
h(`siblings=${e.length}: ${e.join(", ")}`)
|
|
3479
3480
|
const n=(0,o.pickSpecialistName)(e)
|
|
3480
3481
|
c=n,h("picked name: "+n)}}else h("no serverUrl")}catch(e){h("error: "+(e instanceof Error?e.message:e+""))}else h("no parentId")
|
|
3481
|
-
b=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,m,g
|
|
3482
|
+
b=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,m,p,g)
|
|
3482
3483
|
break}case"follow-up":{const e=await(0,i.getServerUrl)(d,m)
|
|
3483
3484
|
if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
|
|
3484
3485
|
if(t.ok){const e=await t.json(),r=e[w]?.type
|
|
3485
3486
|
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}
|
|
3486
|
-
break}}}catch{}b=await(0,s.handleContinue)(w,u.prompt,d,m,
|
|
3487
|
-
break}case"check-status":b=await(0,s.handleCheckStatus)(w,d,m,
|
|
3487
|
+
break}}}catch{}b=await(0,s.handleContinue)(w,u.prompt,d,m,p,"specialist",g)
|
|
3488
|
+
break}case"check-status":b=await(0,s.handleCheckStatus)(w,d,m,p)
|
|
3488
3489
|
break
|
|
3489
|
-
case"abort":if(b=await(0,s.handleAbort)(w,d,m),!b.isError&&
|
|
3490
|
+
case"abort":if(b=await(0,s.handleAbort)(w,d,m),!b.isError&&p)try{const e=p.getCLISessionClient()
|
|
3490
3491
|
e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
|
|
3491
|
-
case"list":{const e=
|
|
3492
|
-
b=await(0,s.handleListSessions)(d,m,
|
|
3492
|
+
case"list":{const e=g?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3493
|
+
b=await(0,s.handleListSessions)(d,m,p,{activeOnly:u.activeOnly,requestId:u.requestId,limit:u.limit,agentType:"specialist",parentSessionId:e})
|
|
3493
3494
|
break}default:throw new r.ValidationError("Unknown operation: "+y)}f({success:!0}),h.incrementCounter(`specialist_ops_${y}_success`,1)
|
|
3494
3495
|
const I=l[y]??"specialist-delegate"
|
|
3495
3496
|
return(0,c.withAlchemyKind)(b,I)}catch(e){return m.error("Specialist ops failed",{error:e instanceof Error?e.stack:e+""}),f({success:!1}),h.incrementCounter("specialist_ops_errors",1),{content:[{type:"text",text:"Specialist operation failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}}
|
|
@@ -3509,17 +3510,17 @@ var t={}
|
|
|
3509
3510
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3510
3511
|
return o(t,e),t})
|
|
3511
3512
|
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")
|
|
3512
|
-
try{const n=e,{requestId:l,reason:h,confirmDestructive:
|
|
3513
|
-
if(s.info("Starting revert/cancel process",{requestId:l,reason:h}),!
|
|
3514
|
-
let
|
|
3513
|
+
try{const n=e,{requestId:l,reason:h,confirmDestructive:p}=n
|
|
3514
|
+
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}
|
|
3515
|
+
let g
|
|
3515
3516
|
try{const e=await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/validate-revert`,{})
|
|
3516
|
-
|
|
3517
|
-
return s.error("Server validation failed",{requestId:l,error:t}),u({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate revert: "+t}],isError:!0}}if(s.info("Server validation result",{requestId:l,canRevert:
|
|
3518
|
-
return
|
|
3519
|
-
try{return await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/finalize-revert`,{reason:h,operationType:"cancel"}),u({success:!0}),{content:[{type:"text",text:`Successfully canceled request ${l}.\n\nOperation: Cancel (no git changes)\nTasks updated: ${
|
|
3517
|
+
g=e?.data||e}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3518
|
+
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:g.canRevert,operationType:g.operationType,mergeCommitHash:g.mergeCommitHash?.substring(0,8),reason:g.reason}),!g.canRevert){let e=`Cannot revert request ${l}: ${g.reason}\n`
|
|
3519
|
+
return g.lifoViolation?.blockingRequests?.length&&(e+="\n**Requests that must be reverted first (in reverse order):**\n",g.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"===g.operationType){s.info("Cancel operation \u2014 delegating to server",{requestId:l})
|
|
3520
|
+
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: ${g.tasksToUpdate.length} task(s) marked as canceled\nReason: ${h}`}]}}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3520
3521
|
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})
|
|
3521
3522
|
t.syncBranchState&&await t.syncBranchState()
|
|
3522
|
-
let m=
|
|
3523
|
+
let m=g.mergeCommitHash
|
|
3523
3524
|
if(!m){s.info("No merge commit hash from server, searching git log",{requestId:l})
|
|
3524
3525
|
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(" ")
|
|
3525
3526
|
return-1===t?{hash:e,message:""}:{hash:e.substring(0,t),message:e.substring(t+1)}})):[],s=a.generateMergeMessagePatterns(e)
|
|
@@ -3535,7 +3536,7 @@ try{s.info("Executing git revert",{mergeCommitHash:m.substring(0,8)}),await f.ra
|
|
|
3535
3536
|
const e=await(0,c.verifyGitStateConsistency)(f,w,s,`revert-request-${l}-verification`)
|
|
3536
3537
|
e.consistent||s.error("Git state inconsistency after revert",{issues:e.issues}),s.info("Git revert completed",{requestId:l,originalMergeCommit:m.substring(0,8),revertCommitHash:w.substring(0,8)})}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3537
3538
|
return s.error("Git revert failed",{requestId:l,error:t}),u({success:!1,error:"git_revert_failed"}),{content:[{type:"text",text:"Git revert failed: "+t}],isError:!0}}try{await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/finalize-revert`,{reason:h,operationType:"revert",revertCommitHash:w,originalMergeCommitHash:m})}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3538
|
-
return s.error("CRITICAL: Git revert succeeded but server finalization failed",{requestId:l,revertCommitHash:w,error:t}),u({success:!1,error:"finalization_failed"}),{content:[{type:"text",text:`CRITICAL: Git revert succeeded (commit: ${w.substring(0,8)}) but failed to update server state: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:`Successfully reverted request ${l}.\n\nOperation: Revert (git revert of merge commit)\nTasks updated: ${
|
|
3539
|
+
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: ${g.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}
|
|
3539
3540
|
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}
|
|
3540
3541
|
if(t.projectId&&e.requestId)try{const o=r.getToolRecordClient()
|
|
3541
3542
|
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}}}
|
|
@@ -3569,7 +3570,7 @@ break
|
|
|
3569
3570
|
case"between":if(void 0===e.afterLine||void 0===e.beforeLine)throw Error("Both afterLine and beforeLine are required for between insertion")
|
|
3570
3571
|
n=(0,m.insertBetweenLines)(r,e.afterLine,e.beforeLine,e.content)
|
|
3571
3572
|
break
|
|
3572
|
-
default:throw Error("Unknown insertion type: "+e.type)}r=n.newContent,t.success=!0,t.linesAdded=n.linesAdded,t.insertionPoint=n.insertionPoint,o+=n.linesAdded}catch(e){t.error=(0,
|
|
3573
|
+
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,g.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)
|
|
3573
3574
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3574
3575
|
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=[]
|
|
3575
3576
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3592,7 +3593,7 @@ R.push({type:"file",path:t,fullPath:r,insertions:e.insertions})}const x=[]
|
|
|
3592
3593
|
if(j.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3593
3594
|
for(const e of j)x.push({type:"document",documentId:e.documentId,insertions:e.insertions})
|
|
3594
3595
|
if(x.length>0&&n.apiClient){const e=x.map((e=>e.documentId))
|
|
3595
|
-
try{await(0,
|
|
3596
|
+
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,y,m,"insert-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3596
3597
|
throw e}}k=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3597
3598
|
const M=R.length>0?R[0].path:"document-operation",O=await l.validateTaskId(q,M,o,y,m,v.metricsPrefix),$=O?.requestId
|
|
3598
3599
|
let D=null
|
|
@@ -3614,11 +3615,11 @@ let H=0,B=0,U=0
|
|
|
3614
3615
|
for(const e of R){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3615
3616
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3616
3617
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.insertions)
|
|
3617
|
-
t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,U++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3618
|
+
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,g.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}L.push(t)}for(const e of x){const t={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3618
3619
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3619
3620
|
t.filename=s?.filename
|
|
3620
3621
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
|
|
3621
|
-
t.insertions=l,t.successfulInsertions=l.filter((e=>e.success)).length,t.failedInsertions=l.filter((e=>!e.success)).length,t.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&t.successfulInsertions>0?(await c.default.writeFile(o,a,"utf8"),n.documentFileManager.markForSync(e.documentId),t.success=!0,U++,y.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3622
|
+
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,g.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:t.error})}L.push(t)}if(x.length>0)try{for(const e of x){const t=L.find((t=>t.documentId===e.documentId))
|
|
3622
3623
|
t?.success&&await n.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const G=await l.handleMultiFileGitCommit(q,R,L,U,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:m,metricsPrefix:"insert_lines"},n),W=l.processMultiFileOperationResults(L,"successfulInsertions"),{successfulOperations:V,failedOperations:K,totalSuccessfulChanges:J,overallSuccess:Q,successfulFiles:Y,failedFiles:Z}=W
|
|
3623
3624
|
try{await s.updateToolRecord(I,{metadata:{path:R.length>0?R[0].path:"document:"+x[0]?.documentId,status:Q?"completed":"failed",error:Q?void 0:K+" operations failed",totalOperations:L.length,successfulFiles:Y,failedFiles:Z,operations:N,totalSuccessfulInsertions:J,totalFailedInsertions:H,totalLinesAdded:B,operationsWithChanges:U,processingTime:Date.now()-w,userComment:E,...R.length>0&&G.success&&G.commitHash&&{commitHash:G.commitHash,previousCommitHash:G.previousCommitHash||void 0}},note:Q?`Line insertion completed: ${V}/${L.length} operations successful${R.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${K}/${L.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let X="## Line Insertion Results\n\n"
|
|
3624
3625
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
@@ -3631,22 +3632,22 @@ for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?
|
|
|
3631
3632
|
X+=` - ${t.type} insertion ${e}: ${t.error}\n`}}X+="\n"}}x.length>0&&(X+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3632
3633
|
const ee=Date.now()-w
|
|
3633
3634
|
return y.info("Insert lines operation completed",{duration:ee,success:Q,totalOperations:L.length,successfulOperations:V,failedOperations:K}),m.incrementCounter("insert_lines_total",1,{success:Q}),{content:[{type:"text",text:X}],isError:!Q}}catch(t){const r=Date.now()-w
|
|
3634
|
-
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await s.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,
|
|
3635
|
-
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),
|
|
3635
|
+
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,g.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,g.getErrorMessage)(t)})}catch(e){}return m.incrementCounter("insert_lines_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,g.getErrorMessage)(t)}],isError:!0}}}
|
|
3636
|
+
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),g=t(8824),m=t(3255)},6539(e,exports,t){"use strict"
|
|
3636
3637
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
|
|
3637
|
-
const r=t(1253),n=t(5681),o=t(6595),s=t(3895),i=t(6848),a=t(6153),c=t(4710),l=t(6975),d=t(1887),u=t(1666),h=t(8824),
|
|
3638
|
+
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),g=t(2968),m=t(922)
|
|
3638
3639
|
exports.ClientFactory=class{static async createClient(e,f,y,w={}){(f=f.child({component:"client-factory"})).info("Creating API client with components")
|
|
3639
3640
|
const b=w.tokenManager||new r.TokenManager(f,w.workingDir||process.cwd())
|
|
3640
3641
|
await b.initialize()
|
|
3641
3642
|
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})
|
|
3642
3643
|
I.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3643
|
-
const E=new
|
|
3644
|
+
const E=new g.TaskClient(e,f,y,_,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3644
3645
|
I.registerClient(E)
|
|
3645
3646
|
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})
|
|
3646
3647
|
I.registerClient(S),f.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
3647
3648
|
const T=new u.RequestClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3648
3649
|
I.registerClient(T),f.info("RequestClient post-constructor token: "+(T.getAuthToken()?"present":"missing"))
|
|
3649
|
-
const q=new
|
|
3650
|
+
const q=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})
|
|
3650
3651
|
I.registerClient(q)
|
|
3651
3652
|
const P=new m.ToolRecordClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3652
3653
|
I.registerClient(P)
|
|
@@ -3668,7 +3669,7 @@ if(_)try{await _.connectStdio(),(0,a.isDebugToolsEnabled)()&&b.info("Connected s
|
|
|
3668
3669
|
throw b.error("Failed to connect stdio transport",{errorDetails:t}),e}else b.error("No global server instance available to connect transport")
|
|
3669
3670
|
return{transport:e,shutdownHandler:t}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3670
3671
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
3671
|
-
const o=t(5802),s=n(t(6928)),i=t(184),a=t(3444),c=t(1152),l=t(8851),d=t(8411),u=n(t(9896)),h=t(4139),
|
|
3672
|
+
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),g=t(9939),m=t(7960),f=process.argv.slice(2),y=f[0]||process.cwd(),w=s.default.resolve(y)
|
|
3672
3673
|
console.error("\n=== MCP STARTUP DIAGNOSTICS ==="),console.error("Script path (process.argv[1]):",process.argv[1]),console.error("Base directory:",w),console.error("ENABLE_DEBUG_TOOLS env:",process.env.ENABLE_DEBUG_TOOLS),console.error("DEBUG_LOGGING env:",process.env.DEBUG_LOGGING),console.error("isDevBuild():",(0,m.isDevBuild)()),console.error("isDebugToolsEnabled():",(0,a.isDebugToolsEnabled)()),console.error("===============================\n")
|
|
3673
3674
|
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)}))
|
|
3674
3675
|
const I=process.stdout.write
|
|
@@ -3679,7 +3680,7 @@ let v=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com"
|
|
|
3679
3680
|
const C=global.__serverInitialized
|
|
3680
3681
|
void 0===C?(global.__serverInitialized=!1,(0,a.isDebugToolsEnabled)()&&b.info("FIRST RUN: Setting global.__serverInitialized to false")):(0,a.isDebugToolsEnabled)()&&b.info("REUSE: global.__serverInitialized is already "+global.__serverInitialized)
|
|
3681
3682
|
let _=null
|
|
3682
|
-
try{(0,d.acquireProcessLock)(w)||(b.error(`Process lock acquisition failed for ${w}. Another instance may be running.`),b.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&b.info("Multi-agent mode enabled - allowing concurrent access to "+w)}catch(e){b.error("Lock acquisition threw exception",{error:(0,
|
|
3683
|
+
try{(0,d.acquireProcessLock)(w)||(b.error(`Process lock acquisition failed for ${w}. Another instance may be running.`),b.error("This instance will exit to prevent duplicate initialization"),process.exit(1)),(0,a.isDebugToolsEnabled)()&&b.info("Multi-agent mode enabled - allowing concurrent access to "+w)}catch(e){b.error("Lock acquisition threw exception",{error:(0,p.getErrorMessage)(e),stack:e instanceof Error?e.stack:void 0}),process.exit(1)}(0,a.isDebugToolsEnabled)()&&(b.info("============================================================"),b.info(`PROCESS START: PID=${process.pid}, TIME=${(new Date).toISOString()}`),b.info("BASE DIR: "+w),b.info("ALCHEMY PATH: "+s.default.join(w,h.ALCHEMY_DIR_NAME)),b.info("PROJECT PATH: "+s.default.join(w,h.ALCHEMY_DIR_NAME+"/project.json")),b.info("MULTI-AGENT MODE: true"),b.info("MCP client information will be captured during protocol initialization")),b.info("Starting MCP server"),(0,a.isDebugToolsEnabled)()&&(b.info("============================================================"),b.info("Base directory: "+w),b.info("Remote server URL: "+v),b.info("Node version: "+process.version),b.info("Current working directory: "+process.cwd()),b.info("ALLOWED_DIRECTORIES env var: not used"),b.info("Server already initialized: "+(C?"YES":"NO"))),C&&((0,a.isDebugToolsEnabled)()&&(b.info("Server already initialized globally, reusing existing server instance"),b.info("Reconnecting stdio to existing server...")),r().catch((e=>{const t=e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:e+""
|
|
3683
3684
|
b.error("Failed to connect stdio transport to existing server",{errorDetails:t}),process.exit(1)})))
|
|
3684
3685
|
try{const e=u.default.existsSync(w)
|
|
3685
3686
|
if((0,a.isDebugToolsEnabled)()&&b.info("Base directory exists: "+e),e&&(0,a.isDebugToolsEnabled)()){const e=u.default.statSync(w)
|
|
@@ -3687,8 +3688,8 @@ b.info(`Directory stats: isDirectory=${e.isDirectory()}, mode=${e.mode.toString(
|
|
|
3687
3688
|
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
|
|
3688
3689
|
try{const{createConfigManager:e}=await Promise.resolve().then(t.t.bind(t,9060,23)),r=e(b),n=await r.getInstallationConfig()
|
|
3689
3690
|
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"}()
|
|
3690
|
-
try{const e=await(0,
|
|
3691
|
-
e.errors.length>0&&b.warn("Some plugins failed to sync",{errors:e.errors}),await(0,
|
|
3691
|
+
try{const e=await(0,g.syncPluginsGlobal)((0,m.isDevBuild)(),b)
|
|
3692
|
+
e.errors.length>0&&b.warn("Some plugins failed to sync",{errors:e.errors}),await(0,g.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))
|
|
3692
3693
|
const e=await(0,i.createServer)(w,b,k,v)
|
|
3693
3694
|
_=e,global.__serverInitialized=!0,(0,a.isDebugToolsEnabled)()&&b.info("MCP server created successfully")
|
|
3694
3695
|
const n=r()
|
|
@@ -3723,7 +3724,7 @@ const n=[],o=[...t].sort(((e,t)=>{const r=e=>"number"==typeof e?e:Array.isArray(
|
|
|
3723
3724
|
return r(t.lines)-r(e.lines)}))
|
|
3724
3725
|
for(const e of o){const t={lines:e.lines,success:!1}
|
|
3725
3726
|
try{const n=(0,m.replaceLines)(r,e.lines,e.content)
|
|
3726
|
-
r=n.newContent,t.success=!0,t.linesReplaced=n.linesReplaced,t.linesAdded=n.linesAdded,t.startLine=n.startLine,t.endLine=n.endLine}catch(e){t.error=(0,
|
|
3727
|
+
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,g.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)
|
|
3727
3728
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3728
3729
|
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=[]
|
|
3729
3730
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3746,7 +3747,7 @@ x.push({type:"file",path:t,fullPath:r,replacements:e.replacements.map((e=>({line
|
|
|
3746
3747
|
if(R.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3747
3748
|
for(const e of R)M.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,f.parseLineSpec)(e.lines),content:e.content})))})
|
|
3748
3749
|
if(M.length>0&&n.apiClient){const e=M.map((e=>e.documentId))
|
|
3749
|
-
try{await(0,
|
|
3750
|
+
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,w,m,"replace-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3750
3751
|
throw e}}v=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3751
3752
|
const O=x.length>0?x[0].path:"document-operation",$=await l.validateTaskId(P,O,o,w,m,C.metricsPrefix),D=$?.requestId
|
|
3752
3753
|
let A=null
|
|
@@ -3768,11 +3769,11 @@ let B=0,U=0,G=0,W=0
|
|
|
3768
3769
|
for(const e of x){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3769
3770
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3770
3771
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.replacements)
|
|
3771
|
-
t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,t.totalLinesReplaced=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulReplacements>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,W++,w.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),B+=t.failedReplacements,U+=t.totalLinesReplaced,G+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3772
|
+
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,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("File operation failed",{path:e.path,error:t.error})}H.push(t)}for(const e of M){const t={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3772
3773
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3773
3774
|
t.filename=s?.filename
|
|
3774
3775
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
|
|
3775
|
-
t.replacements=l,t.successfulReplacements=l.filter((e=>e.success)).length,t.failedReplacements=l.filter((e=>!e.success)).length,t.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&t.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),n.documentFileManager.markForSync(e.documentId),t.success=!0,W++,w.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),B+=t.failedReplacements,U+=t.totalLinesReplaced,G+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3776
|
+
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,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:t.error})}H.push(t)}if(M.length>0)try{for(const e of M){const t=H.find((t=>t.documentId===e.documentId))
|
|
3776
3777
|
t?.success&&await n.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const V=await l.handleMultiFileGitCommit(P,x,H,W,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:m,metricsPrefix:"replace_lines"},n),K=l.processMultiFileOperationResults(H,"successfulReplacements"),{successfulOperations:J,failedOperations:Q,totalSuccessfulChanges:Y,overallSuccess:Z,successfulFiles:X,failedFiles:ee}=K
|
|
3777
3778
|
try{await s.updateToolRecord(k,{metadata:{path:x.length>0?x[0].path:"document:"+M[0]?.documentId,status:Z?"completed":"failed",error:Z?void 0:Q+" operations failed",totalOperations:H.length,successfulFiles:X,failedFiles:ee,operations:z,totalSuccessfulReplacements:Y,totalFailedReplacements:B,totalLinesReplaced:U,totalLinesAdded:G,operationsWithChanges:W,processingTime:Date.now()-b,userComment:S,...x.length>0&&V.success&&V.commitHash&&{commitHash:V.commitHash,previousCommitHash:V.previousCommitHash||void 0}},note:Z?`Line replacement completed: ${J}/${H.length} operations successful${x.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${Q}/${H.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let te="## Line Replacement Results\n\n"
|
|
3778
3779
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
@@ -3783,15 +3784,15 @@ for(const e of H){if("file"===e.type?te+=`### File: ${e.path}\n`:(te+="### Docum
|
|
|
3783
3784
|
for(const t of e.replacements.filter((e=>!e.success)))te+=` - Replace ${"number"==typeof t.lines?"line "+t.lines:Array.isArray(t.lines)?`lines [${t.lines.join(", ")}]`:`lines ${t.lines.start}-${t.lines.end}`}: ${t.error}\n`}te+="\n"}}M.length>0&&(te+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3784
3785
|
const re=Date.now()-b
|
|
3785
3786
|
return w.info("Replace lines operation completed",{duration:re,success:Z,totalOperations:H.length,successfulOperations:J,failedOperations:Q}),m.incrementCounter("replace_lines_total",1,{success:Z}),{content:[{type:"text",text:te}],isError:!Z}}catch(t){const r=Date.now()-b
|
|
3786
|
-
if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),k)try{await s.updateToolRecord(k,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,
|
|
3787
|
-
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),
|
|
3787
|
+
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,g.getErrorMessage)(t),phase:v,duration:r,userComment:e?.comment},note:"Line replacement failed: "+(0,g.getErrorMessage)(t)})}catch(e){}return m.incrementCounter("replace_lines_errors",1,{phase:v}),{content:[{type:"text",text:"\u274c **Replace Lines Failed:** "+(0,g.getErrorMessage)(t)}],isError:!0}}}
|
|
3788
|
+
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),g=t(8824),m=t(3255),f=t(9470)},6656(e,exports,t){"use strict"
|
|
3788
3789
|
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"})
|
|
3789
3790
|
try{const s=t.projectId
|
|
3790
3791
|
if(!s)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
|
|
3791
|
-
const i=e.name.replace(/\.md$/i,""),a=`${d.filenamePrefix}${i}.md`,l=o.getDocumentClient(),
|
|
3792
|
-
if(
|
|
3793
|
-
const
|
|
3794
|
-
let w=!1
|
|
3792
|
+
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})
|
|
3793
|
+
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}
|
|
3794
|
+
const g=u?{criteria:e.criteria||"",status:n.QUEST_STATUS_OPEN,tickIntervalSeconds:e.tickIntervalSeconds??n.QUEST_DEFAULTS.tickIntervalSeconds,maxInFlight:e.maxInFlight??n.QUEST_DEFAULTS.maxInFlight,maxPerDay:e.maxPerDay??n.QUEST_DEFAULTS.maxPerDay,minIterations:e.minIterations??n.QUEST_DEFAULTS.minIterations}:void 0,m=await l.createDocument(void 0,{filename:a,content:e.content,type:d.docType,...g&&{metadata:g},...c&&{cliOrigin:c}}),f=m.localId||m.id,y=m.id
|
|
3795
|
+
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
|
|
3795
3796
|
if(d.canBeActivePlan)try{const e=o.getProjectClient(),t=await e.getProject(s)
|
|
3796
3797
|
t&&!t.activePlanId&&(await e.updateProject(s,{activePlanId:y}),w=!0,h.info("Auto-set as active plan",{planId:f,projectId:s}))}catch(e){h.warn("Failed to auto-set active plan",{error:(0,r.getErrorMessage)(e)})}return h.info(""+d.headingCreated,{planId:f,filename:a}),{content:[{type:"text",text:`\u2705 **${d.headingCreated}**\n\n**${d.idLabel}:** ${f}\n**Filename:** ${a}\n**Created:** `+new Date(m.createdAt).toLocaleString()+(w?"\n\n\u{1f4cc} _Automatically set as the active project plan._":"")}]}}catch(e){return h.error("Failed to "+d.errorVerb,{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:`\u274c **Failed to ${d.errorVerb}:** ${(0,r.getErrorMessage)(e)}`}],isError:!0}}}
|
|
3797
3798
|
const r=t(8824),n=t(3416)},6688(e,exports,t){"use strict"
|
|
@@ -3870,19 +3871,19 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3870
3871
|
var t={}
|
|
3871
3872
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3872
3873
|
return o(t,e),t})
|
|
3873
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTaskFileHistory=async function(e,t,r,n,o){const s=n.child({tool:"task_file_history"}),
|
|
3874
|
-
try{const{taskId:
|
|
3875
|
-
if(!
|
|
3876
|
-
if(!(0,h.isTaskRef)(
|
|
3877
|
-
s.info("Getting file changes for task "+
|
|
3874
|
+
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")
|
|
3875
|
+
try{const{taskId:g,showDiff:m=!1}=e
|
|
3876
|
+
if(!g)throw(0,i.createValidationError)("Task ID is required")
|
|
3877
|
+
if(!(0,h.isTaskRef)(g))throw(0,i.createValidationError)(`Invalid task ID format: ${g}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
|
|
3878
|
+
s.info("Getting file changes for task "+g,{showDiff:m})
|
|
3878
3879
|
const f=r.getTaskClient(),y=r.getToolRecordClient(),w=t.projectId
|
|
3879
3880
|
let b
|
|
3880
3881
|
r.setProjectId(w)
|
|
3881
|
-
try{const j=await f.getTask(
|
|
3882
|
-
s.info("Raw task response data",{responseDataType:typeof j,isArray:Array.isArray(j),hasData:null!=j,properties:j&&"object"==typeof j?Object.keys(j):[]}),b=(0,l.extractDataFromResponse)(j,{logger:s,operationName:"getTask",defaultValue:{id:
|
|
3883
|
-
try{const x=await y.getToolRecordsByTaskId(
|
|
3884
|
-
if(s.info("Raw records response data",{responseDataType:typeof x,isArray:Array.isArray(x),hasData:null!=x,properties:x&&"object"==typeof x?Object.keys(x):[]}),I=(0,l.extractArrayFromResponse)(x,{logger:s,operationName:"searchRecords",defaultValue:[]}),I.length>0&&s.info("First record summary:",{id:I[0].id,type:I[0].type,hasMetadata:!!I[0].metadata,hasCommitHash:!!I[0].metadata?.commitHash}),s.info(`Extracted ${I.length} records for task ${
|
|
3885
|
-
I.forEach((e=>{M[e.type]=(M[e.type]||0)+1})),s.info("Record type distribution:",M)}}catch(O){s.warn("Error fetching records for task "+
|
|
3882
|
+
try{const j=await f.getTask(g)
|
|
3883
|
+
s.info("Raw task response data",{responseDataType:typeof j,isArray:Array.isArray(j),hasData:null!=j,properties:j&&"object"==typeof j?Object.keys(j):[]}),b=(0,l.extractDataFromResponse)(j,{logger:s,operationName:"getTask",defaultValue:{id:g,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:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let I=[]
|
|
3884
|
+
try{const x=await y.getToolRecordsByTaskId(g)
|
|
3885
|
+
if(s.info("Raw records response data",{responseDataType:typeof x,isArray:Array.isArray(x),hasData:null!=x,properties:x&&"object"==typeof x?Object.keys(x):[]}),I=(0,l.extractArrayFromResponse)(x,{logger:s,operationName:"searchRecords",defaultValue:[]}),I.length>0&&s.info("First record summary:",{id:I[0].id,type:I[0].type,hasMetadata:!!I[0].metadata,hasCommitHash:!!I[0].metadata?.commitHash}),s.info(`Extracted ${I.length} records for task ${g}`),I.length>0){const M={}
|
|
3886
|
+
I.forEach((e=>{M[e.type]=(M[e.type]||0)+1})),s.info("Record type distribution:",M)}}catch(O){s.warn("Error fetching records for task "+g,{error:(0,u.getErrorMessage)(O)}),I=[]}if(0===I.length)return p({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
|
|
3886
3887
|
function k(e){const t=new Map,r=new Map,n=[]
|
|
3887
3888
|
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
|
|
3888
3889
|
if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
|
|
@@ -3903,7 +3904,7 @@ if(t&&(n=e.metadata.successfulOperations.some((e=>e&&e.source&&e.destination))),
|
|
|
3903
3904
|
if(!Array.isArray(t)||0===t.length)return s.warn("Skipping delete-files record without valid paths array: "+e.id),!1
|
|
3904
3905
|
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}))
|
|
3905
3906
|
if(s.info(`Found ${C.length} file operation records`),C.length>0){const $={}
|
|
3906
|
-
C.forEach((e=>{$[e.type]=($[e.type]||0)+1})),s.info("Filtered record type distribution:",$)}if(0===C.length)return
|
|
3907
|
+
C.forEach((e=>{$[e.type]=($[e.type]||0)+1})),s.info("Filtered record type distribution:",$)}if(0===C.length)return p({success:!0,fileChanges:0}),{content:[{type:"text",text:`No file changes found for task ${g}.`}]}
|
|
3907
3908
|
const _=new Map
|
|
3908
3909
|
C.forEach((e=>{let t=null
|
|
3909
3910
|
if(e.metadata){if(!e.metadata.commitHash){const t=["gitCommitId","commitId","commit","gitCommit"]
|
|
@@ -3955,9 +3956,9 @@ s.info(`Getting new file content using git show: ${B.commitHash?B.commitHash.sub
|
|
|
3955
3956
|
const de=await t.git.show(le)
|
|
3956
3957
|
if(de&&de.trim().length>0){let ue=""
|
|
3957
3958
|
const he=de.split("\n")
|
|
3958
|
-
for(const
|
|
3959
|
+
for(const pe of he)ue+=`+${pe}\n`
|
|
3959
3960
|
E.set(F,{firstChange:W,lastChange:B,hasDiff:!0,diffText:ue}),s.info(`Formatted new file content as diff, ${he.length} lines`)
|
|
3960
|
-
continue}}catch(
|
|
3961
|
+
continue}}catch(ge){s.warn("Error getting new file content for "+F,{error:(0,u.getErrorMessage)(ge)})}E.set(F,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"Only one commit available for this file"})
|
|
3961
3962
|
continue}if(H.commitHash===B.commitHash&&G){if(U===H.commitHash){E.set(F,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"No changes detected"})
|
|
3962
3963
|
continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let V="",K=!1
|
|
3963
3964
|
if(m||"pre-task"!==W.status){try{if(t.git){try{await t.git.show([`${B.commitHash}:${F}`])}catch(fe){s.warn(`File ${F} does not exist in commit ${B.commitHash}, might be deleted or moved`),V="File was deleted or moved from this location during the task",K=!0,E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V})
|
|
@@ -3972,7 +3973,7 @@ if(_e&&_e.trim().length>0){if(m){let Ee=""
|
|
|
3972
3973
|
const Se=_e.split("\n")
|
|
3973
3974
|
for(const Te of Se)Ee+=`+${Te}\n`
|
|
3974
3975
|
V=Ee}else V="File created during this task. Content:\n"+_e
|
|
3975
|
-
K=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(qe){s.warn("Fallback also failed for "+F,{error:qe instanceof Error?qe.message:qe+""})}}E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V||"No changes detected between commits"})}else K=W.commitHash!==B.commitHash,V=K?"File has changes":"No changes detected between commits",E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V})}let S=`# File Changes for Task: ${
|
|
3976
|
+
K=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(qe){s.warn("Fallback also failed for "+F,{error:qe instanceof Error?qe.message:qe+""})}}E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V||"No changes detected between commits"})}else K=W.commitHash!==B.commitHash,V=K?"File has changes":"No changes detected between commits",E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V})}let S=`# File Changes for Task: ${g}\n\n`
|
|
3976
3977
|
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`)
|
|
3977
3978
|
const T=3e3
|
|
3978
3979
|
let q=0,P=!1
|
|
@@ -3985,7 +3986,7 @@ try{await a.access(Oe),$e=!0}catch{}S+=`### ${Re} ${$e?"":"(Deleted)"}\n\n`
|
|
|
3985
3986
|
const De=new Date(xe.firstChange.timestamp).toLocaleString(),Ae=new Date(xe.lastChange.timestamp).toLocaleString()
|
|
3986
3987
|
S+=`**First Change**: ${De}\n`,S+=`**Last Change**: ${Ae}\n`,"pre-task"===xe.firstChange.status&&xe.firstChange.commitHash?S+=`**Pre-Task Commit**: ${xe.firstChange.commitHash.substring(0,8)}\n`:xe.firstChange.commitHash&&(S+=`**File Created During Task**: ${xe.firstChange.commitHash.substring(0,8)}\n`),xe.lastChange.commitHash&&(S+=`**Final Commit**: ${xe.lastChange.commitHash.substring(0,8)}\n`)
|
|
3987
3988
|
const Fe=v.sourceToMove.get(Re),Ne=v.destToMove.get(Re)
|
|
3988
|
-
Fe?S+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Fe.destination}**\n`:Ne&&(S+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Ne.source}**\n`),m&&!P?xe.hasDiff?(S+="\n**Changes**:\n",S+="```diff\n",S+=xe.diffText,S+="\n```\n\n"):S+=`\n**Note**: ${xe.diffText}\n\n`:P&&xe.hasDiff?(S+=`\n**Note**: File has changes (${xe.diffText?xe.diffText.split("\n").length:0} lines). `,S+=`Compare ${xe.firstChange.commitHash?xe.firstChange.commitHash.substring(0,8):"unknown"}..${xe.lastChange.commitHash?xe.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):xe.hasDiff?S+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":S+=`\n**Note**: ${xe.diffText}\n\n`,S+="---\n\n"}return
|
|
3989
|
+
Fe?S+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Fe.destination}**\n`:Ne&&(S+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Ne.source}**\n`),m&&!P?xe.hasDiff?(S+="\n**Changes**:\n",S+="```diff\n",S+=xe.diffText,S+="\n```\n\n"):S+=`\n**Note**: ${xe.diffText}\n\n`:P&&xe.hasDiff?(S+=`\n**Note**: File has changes (${xe.diffText?xe.diffText.split("\n").length:0} lines). `,S+=`Compare ${xe.firstChange.commitHash?xe.firstChange.commitHash.substring(0,8):"unknown"}..${xe.lastChange.commitHash?xe.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):xe.hasDiff?S+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":S+=`\n**Note**: ${xe.diffText}\n\n`,S+="---\n\n"}return 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}}}
|
|
3989
3990
|
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"
|
|
3990
3991
|
module.exports=require("path")},6975(e,exports,t){"use strict"
|
|
3991
3992
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
|
|
@@ -4119,9 +4120,9 @@ i.existsSync(n)||i.mkdirSync(n,{recursive:!0})
|
|
|
4119
4120
|
const s=(new Date).toISOString(),l=Object.keys(r).length?" "+JSON.stringify(r):""
|
|
4120
4121
|
i.appendFileSync(o,`[${s}] ${e} | ${t}${l}\n`)}catch(e){}}
|
|
4121
4122
|
const i=s(t(9896)),a=s(t(6928)),c=s(t(857))},7334(e,exports,t){"use strict"
|
|
4122
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,c,l,d,u,h){const
|
|
4123
|
-
|
|
4124
|
-
const
|
|
4123
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,c,l,d,u,h){const p=l.child({tool:"create_request"})
|
|
4124
|
+
p.info("Creating new request",{args:e})
|
|
4125
|
+
const g=d.startTimer("tool_handler_duration")
|
|
4125
4126
|
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)
|
|
4126
4127
|
throw new r.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
|
|
4127
4128
|
d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
|
|
@@ -4135,25 +4136,25 @@ if(e){const t=c.getCLISessionClient()
|
|
|
4135
4136
|
if(t){const r=await t.getByExternalId(e)
|
|
4136
4137
|
if(r?.workflowId){const e=await c.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
|
|
4137
4138
|
t?.approvalMode&&(y=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===y)try{const e=await c.proxyGet("/api/projects/"+m),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
|
|
4138
|
-
r&&(y=(0,a.getApprovalMode)(r))}catch(e){
|
|
4139
|
+
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"
|
|
4139
4140
|
let b=h
|
|
4140
4141
|
if(h?.sessionId)try{const e=c.getCLISessionClient()
|
|
4141
4142
|
if(e){const t=await e.getByExternalId(h.sessionId)
|
|
4142
|
-
"planner"!==t?.agentType&&"auto-planner"!==t?.agentType||(b=void 0,
|
|
4143
|
-
|
|
4143
|
+
"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}}
|
|
4144
|
+
p.info("Creating request via request client",{projectId:m,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
|
|
4144
4145
|
const k=await f.createRequest(I)
|
|
4145
|
-
|
|
4146
|
-
const v=(0,o.extractDataFromResponse)(k,{logger:
|
|
4146
|
+
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"})
|
|
4147
|
+
const v=(0,o.extractDataFromResponse)(k,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
|
|
4147
4148
|
let _,E={created:!1}
|
|
4148
|
-
if(u?.workspaceManager)try{await u.workspaceManager.initializeRequest(C.id,C.title),E={created:!0,branchName:"requests/"+C.id,message:"Branch created successfully"},
|
|
4149
|
-
|
|
4149
|
+
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})
|
|
4150
|
+
p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
|
|
4150
4151
|
try{const e=c.getToolRecordClient()
|
|
4151
4152
|
if(e){const t=await e.createToolRecord({requestId:C.id,projectId:m,type:"create-request",metadata:{status:"completed",timestamp:(new Date).toISOString(),requestType:C.type,requestTitle:C.title,requestDescription:C.description,criteriaCount:C.acceptanceCriteria.length,branchCreated:E.created,branchName:E.created?E.branchName:null},note:`Created request "${C.title}" of type ${C.type}${E.created?" with branch "+E.branchName:" - branch will be created on first file operation"}`})
|
|
4152
|
-
_=t?.id}}catch(e){
|
|
4153
|
+
_=t?.id}}catch(e){p.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:C.id})}g({success:!0,type:l.type,hasProjectId:!0}),p.info("Request created successfully",{requestId:C.id,title:C.title,type:C.type,projectId:m})
|
|
4153
4154
|
const S=C.localId||C.id
|
|
4154
|
-
return{content:[{type:"text",text:"pending_approval"===w?`Created Request ${S} (pending approval)`:"Created Request "+S}],...(0,n.alchemyMeta)({kind:"create-request",toolRecordId:_})}}catch(r){if(
|
|
4155
|
+
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})
|
|
4155
4156
|
else{const n=c.getToolRecordClient()
|
|
4156
|
-
n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){
|
|
4157
|
+
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(g({success:!1,error:r instanceof Error?r.name:"unknown"}),r instanceof s.ZodError&&r.errors.length>0){const e=r.errors[0]
|
|
4157
4158
|
let t=e.message
|
|
4158
4159
|
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."
|
|
4159
4160
|
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}}}
|
|
@@ -4173,13 +4174,13 @@ default:throw Error(`Unknown operation: ${c}. Valid operations: get-info, list`)
|
|
|
4173
4174
|
const h=i[c]
|
|
4174
4175
|
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}}}
|
|
4175
4176
|
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"
|
|
4176
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleModifyFile=async function(e,i,a,c,l,d,u,h){const
|
|
4177
|
-
try{const s=e,{operations:
|
|
4177
|
+
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"})
|
|
4178
|
+
try{const s=e,{operations:g,comment:m}=s,{enforceActiveTask:f}=await Promise.resolve().then(t.bind(t,3451)),y=await f(i,a,d,e.taskId)
|
|
4178
4179
|
if("errorResult"in y)return y.errorResult
|
|
4179
4180
|
const{taskId:w}=y
|
|
4180
|
-
|
|
4181
|
+
p.info("Processing modify-file operations",{taskId:w,operationCount:g.length,comment:m})
|
|
4181
4182
|
const b=[],I=[],k=[],v=[],C=[]
|
|
4182
|
-
for(const e of
|
|
4183
|
+
for(const e of g){const t={path:e.path,documentId:e.documentId}
|
|
4183
4184
|
switch(e.operationType){case"replace-string":b.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
|
|
4184
4185
|
break
|
|
4185
4186
|
case"insert-lines":I.push({...t,insertions:e.insertLines.insertions})
|
|
@@ -4189,42 +4190,42 @@ break
|
|
|
4189
4190
|
case"delete-string":v.push({...t,replacements:e.deleteString.patterns.map((e=>({old_str:e,new_str:""}))),mode:e.deleteString.mode||"all"})
|
|
4190
4191
|
break
|
|
4191
4192
|
case"delete-lines":C.push({...t,lines:e.deleteLines.lines})}}const _=[]
|
|
4192
|
-
if(b.length>0){
|
|
4193
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:b,comment:m+" [via modify-file: replace-string]"},i,a,c,l,
|
|
4194
|
-
_.push({type:"replace-string",result:e})}if(I.length>0){
|
|
4195
|
-
const e=await(0,n.handleInsertLines)({taskId:w,operations:I,comment:m+" [via modify-file: insert-lines]"},i,a,c,l,
|
|
4196
|
-
_.push({type:"insert-lines",result:e})}if(k.length>0){
|
|
4197
|
-
const e=await(0,o.handleReplaceLines)({taskId:w,operations:k,comment:m+" [via modify-file: replace-lines]"},i,a,c,l,
|
|
4198
|
-
_.push({type:"replace-lines",result:e})}if(v.length>0){
|
|
4199
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:v,comment:m+" [via modify-file: delete-string]"},i,a,c,l,
|
|
4200
|
-
_.push({type:"delete-string",result:e})}if(C.length>0){
|
|
4201
|
-
const e=C.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),t=await(0,o.handleReplaceLines)({taskId:w,operations:e,comment:m+" [via modify-file: delete-lines]"},i,a,c,l,
|
|
4193
|
+
if(b.length>0){p.info("Routing to replace-strings handler",{operationCount:b.length})
|
|
4194
|
+
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:b,comment:m+" [via modify-file: replace-string]"},i,a,c,l,p,u,h)
|
|
4195
|
+
_.push({type:"replace-string",result:e})}if(I.length>0){p.info("Routing to insert-lines handler",{operationCount:I.length})
|
|
4196
|
+
const e=await(0,n.handleInsertLines)({taskId:w,operations:I,comment:m+" [via modify-file: insert-lines]"},i,a,c,l,p,u,h)
|
|
4197
|
+
_.push({type:"insert-lines",result:e})}if(k.length>0){p.info("Routing to replace-lines handler",{operationCount:k.length})
|
|
4198
|
+
const e=await(0,o.handleReplaceLines)({taskId:w,operations:k,comment:m+" [via modify-file: replace-lines]"},i,a,c,l,p,u,h)
|
|
4199
|
+
_.push({type:"replace-lines",result:e})}if(v.length>0){p.info("Routing delete-string to replace-strings handler",{operationCount:v.length})
|
|
4200
|
+
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:v,comment:m+" [via modify-file: delete-string]"},i,a,c,l,p,u,h)
|
|
4201
|
+
_.push({type:"delete-string",result:e})}if(C.length>0){p.info("Processing delete-lines operations",{operationCount:C.length})
|
|
4202
|
+
const e=C.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),t=await(0,o.handleReplaceLines)({taskId:w,operations:e,comment:m+" [via modify-file: delete-lines]"},i,a,c,l,p,u,h)
|
|
4202
4203
|
_.push({type:"delete-lines",result:t})}const E=_.some((e=>e.result.isError)),S=_.filter((e=>!e.result.isError)).length,T=_.filter((e=>e.result.isError)).length
|
|
4203
4204
|
let q="## Modify File Results\n\n"
|
|
4204
4205
|
q+="**Summary:**\n",q+=`- **Total operation types:** ${_.length}\n`,q+=`- **Successful:** ${S}\n`,q+=`- **Failed:** ${T}\n\n`
|
|
4205
4206
|
for(const{type:e,result:t}of _)q+=`### ${e} operations\n`,q+=t.content[0].text+"\n\n"
|
|
4206
|
-
return
|
|
4207
|
+
return p.info("Modify-file operations completed",{totalOperationTypes:_.length,successCount:S,errorCount:T}),u.incrementCounter("modify_file_total",1,{success:!E}),{content:[{type:"text",text:q}],isError:E}}catch(e){return p.error("Modify-file operation failed",{error:e instanceof Error?e.stack:e+""}),u.incrementCounter("modify_file_errors",1),{content:[{type:"text",text:"\u274c **Modify File Failed:** "+(0,s.getErrorMessage)(e)}],isError:!0}}}
|
|
4207
4208
|
const r=t(3306),n=t(6486),o=t(6651),s=t(8824)},7478(e,exports,t){"use strict"
|
|
4208
4209
|
async function r(e,t,r){const n=r.startTimer("git_get_current_branch_duration")
|
|
4209
4210
|
try{const o=(await e.status()).current
|
|
4210
|
-
if(!o)throw new
|
|
4211
|
+
if(!o)throw new p.ValidationError("Repository is in detached HEAD state or branch detection failed")
|
|
4211
4212
|
return t.debug("Retrieved current branch",{branch:o}),r.incrementCounter("git_get_current_branch_success",1),n({success:!0}),o}catch(e){const o=(0,m.getErrorMessage)(e)
|
|
4212
|
-
throw t.error("Failed to get current branch",{error:o}),r.incrementCounter("git_get_current_branch_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4213
|
+
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")
|
|
4213
4214
|
try{const s=(await e.branch(["-l"])).all.includes(t)
|
|
4214
4215
|
return r.debug("Checked branch existence",{branchName:t,exists:s}),n.incrementCounter("git_branch_exists_check",1,{exists:s.toString()}),o({success:!0}),s}catch(e){const s=(0,m.getErrorMessage)(e)
|
|
4215
4216
|
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")
|
|
4216
4217
|
try{const a=await r(e,o,s)
|
|
4217
4218
|
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}'`}
|
|
4218
4219
|
if(!await n(e,t,o,s)){const e=`Branch '${t}' does not exist`
|
|
4219
|
-
throw o.error(e),s.incrementCounter("git_switch_branch_not_found",1),i({success:!1,reason:"branch_not_found"}),new
|
|
4220
|
+
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)
|
|
4220
4221
|
const c=await e.revparse(["HEAD"])
|
|
4221
4222
|
return o.info("Switched to branch",{branchName:t,previousBranch:a,commitHash:c.substring(0,8)}),s.incrementCounter("git_switch_branch_success",1),i({success:!0}),{success:!0,branchName:t,previousBranch:a,commitHash:c,message:`Switched from '${a}' to '${t}'`}}catch(e){const r=(0,m.getErrorMessage)(e)
|
|
4222
|
-
throw o.error("Failed to switch branch",{branchName:t,error:r}),s.incrementCounter("git_switch_branch_failure",1),i({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4223
|
+
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")
|
|
4223
4224
|
try{let o,s=!0
|
|
4224
4225
|
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")
|
|
4225
|
-
let
|
|
4226
|
-
return u?
|
|
4227
|
-
throw t.error("Failed to get repository status",{error:o}),r.incrementCounter("git_repository_status_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4226
|
+
let p=""
|
|
4227
|
+
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,m.getErrorMessage)(e)
|
|
4228
|
+
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")
|
|
4228
4229
|
try{t.debug("Starting uncommitted changes check"),t.debug("Checking for uncommitted changes before merge"),Date.now()
|
|
4229
4230
|
const o=await e.status()
|
|
4230
4231
|
Date.now(),t.debug("Git status result",{files:o.files.map((e=>({path:e.path,index:e.index,working_dir:e.working_dir}))),totalFiles:o.files.length})
|
|
@@ -4236,7 +4237,7 @@ let d=""
|
|
|
4236
4237
|
if(l){const e=[]
|
|
4237
4238
|
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"
|
|
4238
4239
|
return(0,h.isDebugToolsEnabled)()&&t.debug("Summary",{summary:d}),t.debug("Uncommitted changes check completed",{hasChanges:l,staged:s.length,unstaged:i.length,untracked:a.length,total:c,summary:d}),r.incrementCounter("git_uncommitted_changes_check_success",1),r.recordValue("git_uncommitted_changes_total_files",c),n({success:!0}),{hasChanges:l,stagedFiles:s,unstagedFiles:i,untrackedFiles:a,totalFiles:c,summary:d}}catch(e){const o=(0,m.getErrorMessage)(e)
|
|
4239
|
-
throw t.error("Failed to check uncommitted changes",{error:o}),r.incrementCounter("git_uncommitted_changes_check_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4240
|
+
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)
|
|
4240
4241
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
4241
4242
|
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=[]
|
|
4242
4243
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -4250,29 +4251,29 @@ return s.warn(e),i.incrementCounter("git_create_branch_already_exists",1),c({suc
|
|
|
4250
4251
|
await e.checkoutBranch(t,o)
|
|
4251
4252
|
const d=await e.revparse(["HEAD"]),u=a||l
|
|
4252
4253
|
return await e.checkout(u),s.info("Created new branch",{branchName:t,fromBranch:o,currentBranch:l,returnedToBranch:u,commitHash:d.substring(0,8)}),i.incrementCounter("git_create_branch_success",1),c({success:!0}),{success:!0,branchName:t,previousBranch:l,commitHash:d,message:`Created branch '${t}' from '${o}'`}}catch(e){const r=(0,m.getErrorMessage)(e)
|
|
4253
|
-
throw s.error("Failed to create branch",{branchName:t,fromBranch:o,error:r}),i.incrementCounter("git_create_branch_failure",1),c({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4254
|
+
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")
|
|
4254
4255
|
try{const d=await r(e,i,a)
|
|
4255
4256
|
if(d!==s&&await o(e,s,i,a),!await n(e,t,i,a)){const e=`Source branch '${t}' does not exist`
|
|
4256
|
-
throw i.error(e),a.incrementCounter("git_merge_branch_source_not_found",1),l({success:!1,reason:"source_not_found"}),new
|
|
4257
|
+
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"]))
|
|
4257
4258
|
return i.info("Successfully merged branch",{sourceBranch:t,targetBranch:s,commitHash:h.substring(0,8),mergeMessage:c||"default merge message"}),a.incrementCounter("git_merge_branch_success",1),l({success:!0}),{success:!0,branchName:s,previousBranch:d,commitHash:h,message:`Merged '${t}' into '${s}'`}}catch(e){const r=(0,m.getErrorMessage)(e)
|
|
4258
|
-
throw i.error("Failed to merge branch",{sourceBranch:t,targetBranch:s,error:r}),a.incrementCounter("git_merge_branch_failure",1),l({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4259
|
+
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")
|
|
4259
4260
|
try{const c=await r(e,s,i)
|
|
4260
4261
|
if(c===t){const e=`Cannot delete current branch '${t}'`
|
|
4261
|
-
throw s.error(e),i.incrementCounter("git_delete_branch_current_branch",1),a({success:!1,reason:"current_branch"}),new
|
|
4262
|
-
throw s.error(e),i.incrementCounter("git_delete_branch_protected",1),a({success:!1,reason:"protected_branch"}),new
|
|
4262
|
+
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}'`
|
|
4263
|
+
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`
|
|
4263
4264
|
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]
|
|
4264
4265
|
return await e.branch(l),s.info("Deleted branch",{branchName:t,force:o,currentBranch:c}),i.incrementCounter("git_delete_branch_success",1),a({success:!0}),{success:!0,branchName:t,previousBranch:c,message:`Deleted branch '${t}'${o?" (forced)":""}`}}catch(e){const r=(0,m.getErrorMessage)(e)
|
|
4265
|
-
throw s.error("Failed to delete branch",{branchName:t,force:o,error:r}),i.incrementCounter("git_delete_branch_failure",1),a({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4266
|
+
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")
|
|
4266
4267
|
try{const o=await s(e,t,r)
|
|
4267
4268
|
return o.isGitRepository?(o.currentBranch||(t.warn("Git repository in detached HEAD state"),r.incrementCounter("git_validate_repository_detached_head",1)),o.isClean||(t.warn("Git repository has uncommitted changes",{count:o.uncommittedChanges.length,files:o.uncommittedChanges.slice(0,5)}),r.incrementCounter("git_validate_repository_dirty",1)),o.defaultBranch||(t.warn("No default branch found in git repository"),r.incrementCounter("git_validate_repository_no_default_branch",1)),t.info("Git repository validation completed",{currentBranch:o.currentBranch,isClean:o.isClean,defaultBranch:o.defaultBranch,branchCount:o.branches.length}),r.incrementCounter("git_validate_repository_success",1),n({success:!0}),o):(t.warn("Git repository validation failed: not a git repository"),r.incrementCounter("git_validate_repository_not_git",1),n({success:!1,reason:"not_git_repo"}),o)}catch(e){const o=(0,m.getErrorMessage)(e)
|
|
4268
|
-
throw t.error("Git repository validation failed",{error:o}),r.incrementCounter("git_validate_repository_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4269
|
+
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)
|
|
4269
4270
|
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})-/)
|
|
4270
4271
|
return t?t[1]:null},exports.switchToDefaultBranch=async function(e,t,r){const n=r.startTimer("git_switch_to_default_duration")
|
|
4271
4272
|
try{const i=await s(e,t,r)
|
|
4272
4273
|
if(!i.defaultBranch){const e="No default branch found"
|
|
4273
4274
|
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)
|
|
4274
4275
|
return a.success?(t.info("Switched to default branch",{defaultBranch:i.defaultBranch,previousBranch:a.previousBranch}),r.incrementCounter("git_switch_to_default_success",1),n({success:!0})):(r.incrementCounter("git_switch_to_default_failed",1),n({success:!1,reason:"switch_failed"})),a}catch(e){const o=(0,m.getErrorMessage)(e)
|
|
4275
|
-
throw t.error("Failed to switch to default branch",{error:o}),r.incrementCounter("git_switch_to_default_error",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4276
|
+
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")
|
|
4276
4277
|
try{const o=await s(e,t,r),i=[]
|
|
4277
4278
|
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")
|
|
4278
4279
|
const a=0===i.length
|
|
@@ -4282,9 +4283,9 @@ try{r.debug("Starting main branch change detection",{providedRevertCommitHash:t.
|
|
|
4282
4283
|
const n=await e.revparse(["HEAD"])
|
|
4283
4284
|
r.debug("Git state captured",{currentMainHash:n.substring(0,8),fullCurrentMainHash:n,revertCommitHash:t.substring(0,8),fullRevertCommitHash:t,hashesMatch:n===t})
|
|
4284
4285
|
try{const t=await e.revparse(["--abbrev-ref","HEAD"]),n=await e.status(),o=await e.log(["--oneline","-5"])
|
|
4285
|
-
r.debug("Additional git context",{currentBranch:t,gitStatus:{ahead:n.ahead,behind:n.behind,current:n.current,tracking:n.tracking,staged:n.staged.length,modified:n.modified.length},recentCommits:o.all.map((e=>({hash:e.hash.substring(0,8),message:e.message})))})}catch(e){r.warn("Failed to gather additional git context",{error:e instanceof Error?e.message:e+""})}const s=await(0,
|
|
4286
|
+
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,g.validateCommitHash)(e,t,r,"hasMainChangedSinceRevert-revert-validation")
|
|
4286
4287
|
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}`)
|
|
4287
|
-
const i=await(0,
|
|
4288
|
+
const i=await(0,g.validateCommitHash)(e,n,r,"hasMainChangedSinceRevert-head-validation")
|
|
4288
4289
|
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}`)
|
|
4289
4290
|
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"}
|
|
4290
4291
|
r.debug("Hash comparison shows difference, checking ancestor relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),hashesEqual:!1})
|
|
@@ -4306,7 +4307,7 @@ try{if(!/^[a-f0-9]{40}$/i.test(o)){r.warn("Invalid commit hash format found in t
|
|
|
4306
4307
|
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+""})
|
|
4307
4308
|
continue}}return r.warn("Found revert tool records but none have completed status with commit hash",{requestId:e,recordCount:n.length,records:n.map((e=>({type:e.type,status:e.metadata?.status,hasCommitHash:!!e.metadata?.revertCommitHash})))}),{found:!1,message:"Found revert records but none were completed successfully"}}catch(t){const n=(0,m.getErrorMessage)(t)
|
|
4308
4309
|
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")
|
|
4309
|
-
try{if(!r.hasChanges)throw new
|
|
4310
|
+
try{if(!r.hasChanges)throw new p.ValidationError("No uncommitted changes to commit")
|
|
4310
4311
|
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})
|
|
4311
4312
|
const i=[...r.unstagedFiles,...r.untrackedFiles]
|
|
4312
4313
|
i.length>0?(n.debug("Staging files",{files:i.slice(0,10),total:i.length}),await e.add(i),n.debug("Staged uncommitted files",{files:i.slice(0,10),total:i.length}),n.debug("Successfully staged files")):n.debug("No additional files to stage (already staged)")
|
|
@@ -4314,7 +4315,7 @@ const a=`chore: commit user changes before merging request ${t}\n\n${r.summary}\
|
|
|
4314
4315
|
n.debug("Commit message",{message:a.split("\n")[0]}),n.debug("Creating commit"),await e.commit(a)
|
|
4315
4316
|
const c=await e.revparse(["HEAD"])
|
|
4316
4317
|
return n.debug("Commit created successfully",{commitHash:c.substring(0,8),filesCommitted:r.totalFiles}),n.info("Successfully committed user changes",{requestId:t,commitHash:c.substring(0,8),filesCommitted:r.totalFiles,message:a.split("\n")[0]}),o.incrementCounter("git_commit_user_changes_success",1),o.recordValue("git_commit_user_changes_files",r.totalFiles),s({success:!0}),{commitHash:c,message:a,filesCommitted:r.totalFiles}}catch(e){const i=(0,m.getErrorMessage)(e)
|
|
4317
|
-
throw n.error("Failed to commit user changes",{requestId:t,error:i,uncommittedFiles:r.totalFiles}),o.incrementCounter("git_commit_user_changes_failure",1),s({success:!1,error:e instanceof Error?e.name:"unknown"}),new
|
|
4318
|
+
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")
|
|
4318
4319
|
try{let c=Date.now()
|
|
4319
4320
|
o.debug("Checking for user changes before tool operation",{toolName:r})
|
|
4320
4321
|
let l=e
|
|
@@ -4328,10 +4329,10 @@ let u
|
|
|
4328
4329
|
o.debug("Found user changes before tool, committing them first",{toolName:r}),o.info("Found user changes before tool operation, committing separately",{toolName:r,requestId:n.requestId,taskId:n.taskId,totalFiles:d.totalFiles,summary:d.summary}),u=n.requestId&&n.taskId?`chore: commit user changes before ${r} (task ${n.taskId})`:n.requestId?`chore: commit user changes before ${r} (request ${n.requestId})`:`chore: commit user changes before ${r} operation`
|
|
4329
4330
|
const h=`${u}\n\n${{...d,summary:`User changes detected before ${r}: ${d.summary.replace("Found ","").toLowerCase()}`}.summary}\n\nThis commit preserves user modifications made before the ${r} tool operation\nto maintain clear separation between user changes and tool changes.`
|
|
4330
4331
|
o.debug("Committing user changes with message",{firstLine:h.split("\n")[0]})
|
|
4331
|
-
const
|
|
4332
|
-
c=Date.now(),
|
|
4333
|
-
const
|
|
4334
|
-
return o.debug("User changes committed successfully before tool",{commitHash:
|
|
4332
|
+
const p=[...d.unstagedFiles,...d.untrackedFiles]
|
|
4333
|
+
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()
|
|
4334
|
+
const g=await l.revparse(["HEAD"])
|
|
4335
|
+
return o.debug("User changes committed successfully before tool",{commitHash:g.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:g.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:g,filesCommitted:d.totalFiles}}catch(e){const t=(0,m.getErrorMessage)(e)
|
|
4335
4336
|
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=[]
|
|
4336
4337
|
try{const o=t(3807).simpleGit(e),s=(await o.status()).not_added||[]
|
|
4337
4338
|
for(const t of s)try{const o=y.join(e,t),s=f.statSync(o)
|
|
@@ -4340,7 +4341,7 @@ const t=e.reduce(((e,t)=>e+t.sizeMB),0)
|
|
|
4340
4341
|
let r=`\n\n\u26a0\ufe0f **Performance Warning**: Large untracked files detected (${Math.round(t)} MB total) that may slow git operations:\n`
|
|
4341
4342
|
for(const t of e.slice(0,5))r+=`- \`${t.path}\` (${t.sizeMB} MB)\n`
|
|
4342
4343
|
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}
|
|
4343
|
-
const h=t(3444),
|
|
4344
|
+
const h=t(3444),p=t(9860),g=t(3922),m=t(8824),f=u(t(9896)),y=u(t(6928))
|
|
4344
4345
|
t(857)},7575(e,exports){"use strict"
|
|
4345
4346
|
var t
|
|
4346
4347
|
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"
|
|
@@ -4544,8 +4545,8 @@ const r=t(4055)
|
|
|
4544
4545
|
Object.defineProperty(exports,"ProjectID",{enumerable:!0,get(){return r.ProjectID}}),Object.defineProperty(exports,"ProjectIDFactory",{enumerable:!0,get(){return r.ProjectIDFactory}})
|
|
4545
4546
|
const n=t(1791)
|
|
4546
4547
|
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"
|
|
4547
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,c,l,d,u,h,g,
|
|
4548
|
-
try{const a=e,{operations:y,comment:w}=a,{enforceActiveTask:b}=await Promise.resolve().then(t.bind(t,3451)),I=await b(c,h,
|
|
4548
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,c,l,d,u,h,p,g,m){const f=p.child({tool:"manage_files"})
|
|
4549
|
+
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)
|
|
4549
4550
|
if("errorResult"in I)return I.errorResult
|
|
4550
4551
|
const{taskId:k}=I
|
|
4551
4552
|
f.info("Processing manage-files operations",{taskId:k,operationCount:y.length,comment:w})
|
|
@@ -4558,18 +4559,18 @@ case"delete-files":_.push(...e.deleteFiles.targets)
|
|
|
4558
4559
|
break
|
|
4559
4560
|
case"get-file-info":E.push({path:e.getFileInfo.path})}const S=[]
|
|
4560
4561
|
for(const e of v){f.info("Routing to create-directory handler",{path:e.path})
|
|
4561
|
-
const t=await(0,r.handleCreateDirectory)({taskId:k,path:e.path,comment:w+" [via manage-files: create-directory]"},c,l,d,u,f,
|
|
4562
|
+
const t=await(0,r.handleCreateDirectory)({taskId:k,path:e.path,comment:w+" [via manage-files: create-directory]"},c,l,d,u,f,g,m)
|
|
4562
4563
|
S.push({type:"create-directory",result:t})}if(C.length>0){f.info("Routing to move-files handler",{operationCount:C.length})
|
|
4563
|
-
const e=await(0,n.handleMoveFiles)({taskId:k,operations:C,comment:w+" [via manage-files: move-files]"},c,l,d,u,f,
|
|
4564
|
+
const e=await(0,n.handleMoveFiles)({taskId:k,operations:C,comment:w+" [via manage-files: move-files]"},c,l,d,u,f,g,m)
|
|
4564
4565
|
S.push({type:"move-files",result:e})}if(_.length>0){f.info("Routing to delete-files handler",{operationCount:_.length})
|
|
4565
|
-
const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,
|
|
4566
|
+
const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,g,m)
|
|
4566
4567
|
S.push({type:"delete-files",result:e})}for(const e of E){f.info("Routing to get-file-info handler",{path:e.path})
|
|
4567
|
-
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,
|
|
4568
|
+
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,g)
|
|
4568
4569
|
S.push({type:"get-file-info",result:t})}const T=S.some((e=>e.result.isError)),q=S.filter((e=>!e.result.isError)).length,P=S.filter((e=>e.result.isError)).length
|
|
4569
4570
|
let j="## Manage Files Results\n\n"
|
|
4570
4571
|
j+="**Summary:**\n",j+=`- **Total operation types:** ${S.length}\n`,j+=`- **Successful:** ${q}\n`,j+=`- **Failed:** ${P}\n\n`
|
|
4571
4572
|
for(const{type:e,result:t}of S)j+=`### ${e} operations\n`,j+=t.content[0].text+"\n\n"
|
|
4572
|
-
return f.info("Manage-files operations completed",{totalOperationTypes:S.length,successCount:q,errorCount:P}),
|
|
4573
|
+
return f.info("Manage-files operations completed",{totalOperationTypes:S.length,successCount:q,errorCount:P}),g.incrementCounter("manage_files_total",1,{success:!T}),{content:[{type:"text",text:j}],...(0,s.alchemyMeta)({kind:"manage-files"}),isError:T}}catch(e){return f.error("Manage-files operation failed",{error:e instanceof Error?e.stack:e+""}),g.incrementCounter("manage_files_errors",1),{content:[{type:"text",text:"\u274c **Manage Files Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
4573
4574
|
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"
|
|
4574
4575
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4575
4576
|
const r=t(6183),n=t(5303)
|
|
@@ -4594,8 +4595,8 @@ const r=t(5806),n=t(5715)
|
|
|
4594
4595
|
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"
|
|
4595
4596
|
async function r(e,t,r,n,o,s,a,l,d,u){const h=Date.now()
|
|
4596
4597
|
if(!r||""===r.trim())throw new c.ValidationError("Project ID is required and cannot be empty for tool record creation")
|
|
4597
|
-
try{const c=await a.createToolRecord({taskId:e,requestId:t,projectId:r,type:n,metadata:{path:o,operation:n,status:"pending",timestamp:(new Date).toISOString(),fileExtension:i.default.extname(o).slice(1),fileOperationId:`${e}-${Date.now()}`,...s},note:`${"write-file"===n?"Writing":"Modifying"} file: ${o}`}),
|
|
4598
|
-
return l.info("Tool record created with IDs",{recordId:
|
|
4598
|
+
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,g=c.localId
|
|
4599
|
+
return l.info("Tool record created with IDs",{recordId:p,localRecordId:g,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:g}),d.recordValue(u+"_tool_record_creation_time",Date.now()-h),d.incrementCounter(u+"_tool_record_creation_success",1),{recordId:p,localRecordId:g}}catch(t){d.incrementCounter(u+"_tool_record_creation_failure",1),d.recordValue(u+"_tool_record_creation_time",Date.now()-h)
|
|
4599
4600
|
const n=t instanceof Error?`${t.message} (${JSON.stringify(t)})`:t+""
|
|
4600
4601
|
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()
|
|
4601
4602
|
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
|
|
@@ -4606,22 +4607,22 @@ l.info("Staging modified files for git commit",{files:n,count:n.length,operation
|
|
|
4606
4607
|
let d=o.git
|
|
4607
4608
|
if(o.workspaceManager){const t=o.workspaceManager.getCurrentContext(o.currentSessionId)
|
|
4608
4609
|
"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}
|
|
4609
|
-
let
|
|
4610
|
-
try{
|
|
4611
|
-
const
|
|
4612
|
-
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:
|
|
4610
|
+
let p=null
|
|
4611
|
+
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)
|
|
4612
|
+
const g=1===n.length?`${s} in ${n[0]} (${i})`:`${s} in ${n.length} files (${i})`,m=(await d.commit(g)).commit
|
|
4613
|
+
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:g,filesCommitted:n.length,commitHash:m?.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:m,previousCommitHash:p,filesCommitted:n,success:!0}}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
4613
4614
|
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}}
|
|
4614
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.createToolRecord=r,exports.updateToolRecord=n,exports.createFileOperationRecords=async function(e,t,n,o,s,i,a,c,l,u,h){const
|
|
4615
|
-
let
|
|
4615
|
+
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()
|
|
4616
|
+
let g,m
|
|
4616
4617
|
l.debug("createFileOperationRecords called",{taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,operationType:o,path:s})
|
|
4617
4618
|
try{const a=await r(e,t,n,o,s,i,c,l,u,h)
|
|
4618
|
-
return
|
|
4619
|
+
return g=a.recordId,m=a.localRecordId,l.info("Created tool record for file operation: "+o,{taskId:e,path:s,toolRecordId:g,localToolRecordId:m}),{toolRecordId:g,localToolRecordId:m}}catch(r){throw l.error("Failed to create tool record for file operation: "+o,{error:(0,d.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0,taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,path:s}),u.recordValue(h+"_record_creation_time",Date.now()-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,g){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,g)}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}
|
|
4619
4620
|
try{let s=t.git
|
|
4620
4621
|
if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
4621
4622
|
"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)
|
|
4622
4623
|
const t=await s.commit("[USER-MODS] Preserve user modifications before tool operation: "+e)
|
|
4623
4624
|
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()
|
|
4624
|
-
let g
|
|
4625
|
+
let p,g=null
|
|
4625
4626
|
try{let m=s.git
|
|
4626
4627
|
if(s.workspaceManager){const t=s.workspaceManager.getCurrentContext(s.currentSessionId)
|
|
4627
4628
|
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.`)
|
|
@@ -4632,11 +4633,11 @@ i.info("Git repository status before commit:",{taskId:e,currentBranch:r.trim(),c
|
|
|
4632
4633
|
const a=r.trim(),c=s.getCurrentRequestId?s.getCurrentRequestId():null
|
|
4633
4634
|
if(c){const t="requests/"+c
|
|
4634
4635
|
a!=="requests/"+c?i.warn("Multi-agent file operation may be on wrong branch",{taskId:e,actualBranch:a,expectedPattern:t,requestId:c}):i.info("Multi-agent file operation on expected branch",{taskId:e,branchName:a,requestId:c})}}catch(e){i.warn("Failed to get Git status before commit:",{error:e instanceof Error?e.message:e+""})}try{if(m){const r=await m.revparse(["HEAD"])
|
|
4635
|
-
|
|
4636
|
-
await m.add(t),
|
|
4636
|
+
g=await(0,l.findPreviousCommit)(m,t,r),i.info(`Previous commit hash for ${t}: ${g||"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
|
|
4637
|
+
await m.add(t),p=(await m.commit(y)).commit
|
|
4637
4638
|
try{const r=await m.revparse(["--abbrev-ref","HEAD"]),n=await m.revparse(["HEAD"])
|
|
4638
|
-
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(
|
|
4639
|
-
return{commitHash:
|
|
4639
|
+
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(g||""),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:g}),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})
|
|
4640
|
+
return{commitHash:p,previousCommitHash:g}}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:g}}},exports.commitMultipleFilesToGit=o,exports.handleMultiFileGitCommit=async function(e,t,r,n,s,i){const{logger:a,metricsPrefix:c,metrics:l}=s
|
|
4640
4641
|
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))}
|
|
4641
4642
|
const i=s(t(6928)),a=t(3807),c=t(9860),l=t(9671),d=t(8824),u=t(7575)},7888(e,exports,t){"use strict"
|
|
4642
4643
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.addConnectionStatusInfo=function(e){return async(t,n,o)=>{try{const t=e.isInOfflineMode()
|
|
@@ -4658,11 +4659,11 @@ class o{static create(){return exports.ProjectIDFactory.create()}static fromStri
|
|
|
4658
4659
|
return o.fromString(`prj_${e}_${t}`)},fromString(e){return this.isValid(e)?new o(e):null},isValid(e){if(!e||"string"!=typeof e||5>e.length||!e.startsWith("prj"))return!1
|
|
4659
4660
|
if(e.includes("_")){const t=e.split("_")
|
|
4660
4661
|
return t.length>=3&&"prj"===t[0]}return!1}},exports.ProjectIDBackwardCompat={create:exports.ProjectIDFactory.create,fromString:exports.ProjectIDFactory.fromString,isValid:exports.ProjectIDFactory.isValid},Object.assign(o,exports.ProjectIDBackwardCompat)},8035(e,exports,t){"use strict"
|
|
4661
|
-
function r(e,t,r){try{const n=`[${(new Date).toISOString()}] [detached-subagent] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,i.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,s.appendFileSync)(o,n)}catch{}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=function(e){const{agent:t,prompt:d,cwd:u,sessionId:h,model:
|
|
4662
|
+
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:g,serverUrl:m,onSpawn:f}=e
|
|
4662
4663
|
try{const e=u||process.cwd(),o={...process.env,...(0,c.getOpencodeSpawnEnv)(e,(0,l.isDevMode)())}
|
|
4663
4664
|
let y
|
|
4664
|
-
if(
|
|
4665
|
-
e>0?y.splice(e,0,"--model",
|
|
4665
|
+
if(g&&(o.ALCHEMY_INITIAL_BRANCH=g),r(u,"Spawn env setup",{agent:t,initialBranch:g||"none",sessionId:h||"new",attachMode:!!m}),y=m&&h&&d?["run","--attach",m,"--session",h,"--agent",t,d]:h&&d?["run","--session",h,"--agent",t,d]:d?["run","--agent",t,d]:["run","--agent",t],p){const e=y.findIndex((e=>e===d))
|
|
4666
|
+
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})
|
|
4666
4667
|
const w=(0,i.join)(u||process.cwd(),".alchemy_lab"),b=(0,i.join)(w,"spawn-stderr.log")
|
|
4667
4668
|
let I
|
|
4668
4669
|
try{I=(0,s.openSync)(b,"a")}catch{}const k=(0,a.resolveRunCommand)(),v=(0,n.spawn)(k.command,[...k.prependArgs,...y],{detached:!0,stdio:["ignore","ignore",I??"ignore"],cwd:u||process.cwd(),env:o})
|
|
@@ -4680,10 +4681,10 @@ const d={}
|
|
|
4680
4681
|
o.status&&"undefined"!==o.status&&(d.status=o.status),o.type&&"undefined"!==o.type&&(d.type=o.type),o.dateFrom&&(d.dateFrom=o.dateFrom),o.dateTo&&(d.dateTo=o.dateTo),o.planDocumentId&&(d.planDocumentId=o.planDocumentId),o.questDocumentId&&(d.questDocumentId=o.questDocumentId),d.limit=o.limit||20,d.offset=o.offset||0,d.sortBy="created"===o.sortBy?"created_at":(o.sortBy,"updated_at"),d.sortDirection=o.sortDirection||"desc",s.setProjectId(a),c.info("Sending query parameters",{queryParams:d})
|
|
4681
4682
|
const u=s.getRequestClient(),h=await u.listRequests(d)
|
|
4682
4683
|
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"})
|
|
4683
|
-
const
|
|
4684
|
-
if(c.info(`Extracted ${
|
|
4685
|
-
const p
|
|
4686
|
-
return l({success:!0,requestCount:
|
|
4684
|
+
const p=(0,n.extractArrayFromResponse)(h,{logger:c,operationName:"listRequests",defaultValue:[]})
|
|
4685
|
+
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."}]}
|
|
4686
|
+
const g=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"),m=`Found ${p.length} request${1===p.length?"":"s"}:`
|
|
4687
|
+
return l({success:!0,requestCount:p.length}),{content:[{type:"text",text:`${m}\n\n${g}`}]}}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}}}
|
|
4687
4688
|
const r=t(9860),n=t(2960),o=t(8824)},8045(e,exports,t){"use strict"
|
|
4688
4689
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4689
4690
|
const r=t(6183),n=t(7456)
|
|
@@ -4710,14 +4711,14 @@ var u=t(184)
|
|
|
4710
4711
|
Object.defineProperty(exports,"createServer",{enumerable:!0,get(){return u.createServer}})
|
|
4711
4712
|
var h=t(3884)
|
|
4712
4713
|
Object.defineProperty(exports,"middleware",{enumerable:!0,get(){return h.middleware}}),Object.defineProperty(exports,"requestLogger",{enumerable:!0,get(){return h.requestLogger}}),Object.defineProperty(exports,"errorHandler",{enumerable:!0,get(){return h.errorHandler}}),Object.defineProperty(exports,"authenticate",{enumerable:!0,get(){return h.authenticate}}),Object.defineProperty(exports,"validateRequest",{enumerable:!0,get(){return h.validateRequest}}),Object.defineProperty(exports,"corsOptions",{enumerable:!0,get(){return h.corsOptions}})
|
|
4713
|
-
var
|
|
4714
|
-
Object.defineProperty(exports,"addConnectionStatusInfo",{enumerable:!0,get(){return
|
|
4714
|
+
var p=t(7888)
|
|
4715
|
+
Object.defineProperty(exports,"addConnectionStatusInfo",{enumerable:!0,get(){return p.addConnectionStatusInfo}}),t(3611),t(6552),t(1791),t(1152),t(3328),t(3884),t(6800),t(9955),t(2568),t(3102),t(8625),t(184),t(1472),t(1213),n(t(3444),exports),n(t(3227),exports),n(t(9914),exports),n(t(4055),exports),n(t(9860),exports),n(t(3611),exports),n(t(6552),exports)},8184(e,exports,t){"use strict"
|
|
4715
4716
|
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")
|
|
4716
|
-
try{const i=e,{requestId:c,format:d="summary",path:h}=i,
|
|
4717
|
-
if(!
|
|
4718
|
-
const m=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,f=t.git??(0,o.simpleGit)({baseDir:m,binary:t.gitBinary}),y="completed"===
|
|
4717
|
+
try{const i=e,{requestId:c,format:d="summary",path:h}=i,p=s.getRequestClient(),g=await p.getRequest(c)
|
|
4718
|
+
if(!g)return u({success:!1,reason:"not_found"}),n("Request not found: "+c)
|
|
4719
|
+
const m=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,f=t.git??(0,o.simpleGit)({baseDir:m,binary:t.gitBinary}),y="completed"===g.status,w="requests/"+c
|
|
4719
4720
|
let b,I
|
|
4720
|
-
if(y){const e=
|
|
4721
|
+
if(y){const e=g.metadata?.mergeBaseSha,t=g.metadata?.mergeCommitSha
|
|
4721
4722
|
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.`)
|
|
4722
4723
|
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)
|
|
4723
4724
|
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]:[]
|
|
@@ -4732,21 +4733,28 @@ if(r.startsWith("R")){const e=t[1],n=t[2],o=_.get(n)||{additions:0,deletions:0,b
|
|
|
4732
4733
|
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}
|
|
4733
4734
|
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))}}
|
|
4734
4735
|
const o=t(3807),s=t(2272),i=t(8824),a=5e5},8291(e,exports,t){"use strict"
|
|
4735
|
-
var
|
|
4736
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.validateAndNormalizePath=function(e,t){
|
|
4737
|
-
const
|
|
4738
|
-
if(
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4736
|
+
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}}
|
|
4737
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.validateAndNormalizePath=function(e,t){const n=function(e,t){if(!e.startsWith("log:"))return null
|
|
4738
|
+
const r=e.slice(4).replace(/^\/+/,""),n=r?`${i.ALCHEMY_DIR_NAME}/command-logs/${r}.log`:i.ALCHEMY_DIR_NAME+"/command-logs"
|
|
4739
|
+
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.`)
|
|
4740
|
+
const a=o.default.resolve(t,n)
|
|
4741
|
+
if(!a.startsWith(t+o.default.sep))throw(0,s.createValidationError)("Log path resolves outside the workspace: "+e)
|
|
4742
|
+
return{normalizedPath:n,fullPath:a}}(e,r(t))
|
|
4743
|
+
if(n)return n
|
|
4744
|
+
let a=e.replace(/\\/g,"/")
|
|
4745
|
+
const d=r(t)
|
|
4746
|
+
if(o.default.isAbsolute(a)){const e=o.default.normalize(a)
|
|
4747
|
+
if(e.startsWith(d))a=o.default.relative(d,e),a=a.replace(/\\/g,"/")
|
|
4748
|
+
else{const r=t.basePath
|
|
4749
|
+
if(!r||!e.startsWith(r)){const n=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.mode||"unknown",o=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.requestId||"none"
|
|
4750
|
+
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,"")
|
|
4751
|
+
for(const e of c)if(t===e||t.startsWith(e+"/"))return!0
|
|
4752
|
+
for(const e of l)if(t===e||t.endsWith("/"+e))return!0
|
|
4753
|
+
return!1}(a))throw(0,s.createValidationError)(`Access to '${a}' is not allowed - this directory contains system files`)
|
|
4754
|
+
const u=o.default.resolve(d,a)
|
|
4755
|
+
if(!u.startsWith(d)){const e=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.mode||"unknown",r=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.requestId||"none"
|
|
4756
|
+
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))}
|
|
4757
|
+
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"
|
|
4750
4758
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
4751
4759
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
4752
4760
|
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=[]
|
|
@@ -4755,35 +4763,35 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4755
4763
|
var t={}
|
|
4756
4764
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
4757
4765
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4758
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,r,n,o,s,i,g
|
|
4766
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,r,n,o,s,i,p,g){const m=i.child({tool:"create_directory"}),f=Date.now()
|
|
4759
4767
|
let y,w,b=l.FileOperationPhase.VALIDATION
|
|
4760
4768
|
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}"}
|
|
4761
4769
|
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)
|
|
4762
4770
|
if("errorResult"in v)return v.errorResult
|
|
4763
4771
|
const{taskId:C}=v
|
|
4764
|
-
m.info("Creating directory: "+u,{taskId:C,path:u,comment:h}),l.validateTaskIdFormat(C,m,
|
|
4772
|
+
m.info("Creating directory: "+u,{taskId:C,path:u,comment:h}),l.validateTaskIdFormat(C,m,p,I.metricsPrefix),r.getCurrentBranchContext&&await r.getCurrentBranchContext()
|
|
4765
4773
|
const{normalizedPath:_,fullPath:E}=l.validateAndNormalizePath(u,r)
|
|
4766
|
-
b=l.FileOperationPhase.TASK_VALIDATION,
|
|
4767
|
-
const S=await l.validateTaskId(C,_,n,m,
|
|
4774
|
+
b=l.FileOperationPhase.TASK_VALIDATION,p.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4775
|
+
const S=await l.validateTaskId(C,_,n,m,p,I.metricsPrefix),T=S?.requestId,q=await l.validateWorkItemStates(C,_,n,s,r,m,p,I.metricsPrefix),P=await l.autoPromoteTaskStatus(C,S.status,T,q.request?.status,_,n,s,m,p,I.metricsPrefix)
|
|
4768
4776
|
P.taskPromoted&&m.info(`Auto-promoted task ${C} (${S.title||"Untitled"}) to in_progress for file operation`,{taskId:C,taskTitle:S.title,previousStatus:S.status,newStatus:P.newTaskStatus,path:_}),P.requestPromoted&&m.info(`Auto-promoted request ${T} to in_progress for file operation`,{requestId:T,previousStatus:q.request?.status,newStatus:P.newRequestStatus,triggeringTaskId:C})
|
|
4769
|
-
const j=await l.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:T,context:r,operation:"create-directory",logger:m,metrics:
|
|
4777
|
+
const j=await l.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:T,context:r,operation:"create-directory",logger:m,metrics:p,metricsPrefix:I.metricsPrefix})
|
|
4770
4778
|
if(!j.success)throw Error(j.error)
|
|
4771
4779
|
let R=!1
|
|
4772
|
-
try{R=(await a.default.stat(E)).isDirectory()}catch{R=!1}b=l.FileOperationPhase.RECORD_CREATION,
|
|
4773
|
-
const{toolRecordId:x,localToolRecordId:M}=await l.createFileOperationRecords(C,T,r.projectId,I.recordType,_,{directoryExists:R,userComment:h},n,o,m,
|
|
4774
|
-
y=x,w=x,b=I.fileOperationPhase,
|
|
4780
|
+
try{R=(await a.default.stat(E)).isDirectory()}catch{R=!1}b=l.FileOperationPhase.RECORD_CREATION,p.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4781
|
+
const{toolRecordId:x,localToolRecordId:M}=await l.createFileOperationRecords(C,T,r.projectId,I.recordType,_,{directoryExists:R,userComment:h},n,o,m,p,I.metricsPrefix,g)
|
|
4782
|
+
y=x,w=x,b=I.fileOperationPhase,p.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4775
4783
|
let O=R
|
|
4776
4784
|
if(!R){await a.default.mkdir(E,{recursive:!0}),m.info("Successfully created directory "+_)
|
|
4777
4785
|
try{const e=c.default.join(E,".gitkeep")
|
|
4778
4786
|
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),O=!0,m.info("Created .gitkeep file for Git tracking")}catch(e){m.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),O=!1}}const $=Date.now()-f
|
|
4779
|
-
|
|
4780
|
-
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!R&&O?_+"/.gitkeep":_,F=await l.commitToGit(C,A,x,M,D,r,m,
|
|
4781
|
-
b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,
|
|
4787
|
+
p.recordValue("create_directory_time",$),p.incrementCounter("create_directory_success",1),b=l.FileOperationPhase.GIT_COMMIT,p.incrementCounter("create_directory_phase",1,{phase:b})
|
|
4788
|
+
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!R&&O?_+"/.gitkeep":_,F=await l.commitToGit(C,A,x,M,D,r,m,p,I.metricsPrefix)
|
|
4789
|
+
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,m,p,I.metricsPrefix)
|
|
4782
4790
|
const N=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4783
4791
|
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
|
|
4784
4792
|
await o.createToolRecord({...n?{}:{taskId:e.taskId},projectId:r.projectId,type:"create-directory",metadata:{status:"failed",timestamp:(new Date).toISOString(),path:e.path,userComment:e.comment,error:(0,h.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:n},note:`Failed to create directory ${e.path} - ${(0,h.getErrorMessage)(t)}`})}catch(t){m.error("Failed to create failure record for create directory operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,path:e.path})}const s=Date.now()-f
|
|
4785
|
-
if(
|
|
4786
|
-
try{await l.updateFileOperationRecords(e.taskId,y,w,e.path,I.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,h.getErrorMessage)(t),userComment:e.comment},"Failed to create directory "+e.path,n,o,m,
|
|
4793
|
+
if(p.recordValue("create_directory_time",s),p.incrementCounter("create_directory_errors",1),m.error("Error creating directory:",{error:(0,h.getErrorMessage)(t),time:s}),(y||w)&&e.taskId){b=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
4794
|
+
try{await l.updateFileOperationRecords(e.taskId,y,w,e.path,I.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,h.getErrorMessage)(t),userComment:e.comment},"Failed to create directory "+e.path,n,o,m,p,I.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(t,b,m,p,e,I)}}
|
|
4787
4795
|
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"
|
|
4788
4796
|
function r(e){const t=[]
|
|
4789
4797
|
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"
|
|
@@ -4792,20 +4800,20 @@ case"move-files":return"\u{1f4cb} Move Files"
|
|
|
4792
4800
|
case"delete-files":return"\u{1f5d1}\ufe0f Delete Files"
|
|
4793
4801
|
case"manage-files":return"\u{1f4c1} Manage Files"
|
|
4794
4802
|
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")
|
|
4795
|
-
try{const{requestId:l,detailLevel:
|
|
4803
|
+
try{const{requestId:l,detailLevel:p="summary",taskId:g,showDiff:m=!1,fileFilter:f}=e
|
|
4796
4804
|
if(!l)throw(0,o.createValidationError)("Request ID is required")
|
|
4797
4805
|
if(!/^req[_\d].+$/.test(l))throw(0,o.createValidationError)(`Invalid request ID format: ${l}. Expected format: req_[26 chars] or req######`)
|
|
4798
|
-
if(
|
|
4799
|
-
if(u.info("Getting file changes for request "+l,{detailLevel:
|
|
4806
|
+
if(g&&!(0,a.isTaskRef)(g))throw(0,o.createValidationError)(`Invalid task ID format: ${g}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
|
|
4807
|
+
if(u.info("Getting file changes for request "+l,{detailLevel:p,taskId:g,showDiff:m}),!t.git)throw Error("Git integration not available in this context")
|
|
4800
4808
|
const y=t.projectId
|
|
4801
4809
|
let w
|
|
4802
4810
|
c.setProjectId(y)
|
|
4803
4811
|
try{const e=c.getRequestClient(),t=await e.getRequest(l),r=(0,s.extractDataFromResponse)(t,{logger:u,operationName:"getRequest",throwOnNoData:!1}),n="data"in r?r.data:r
|
|
4804
4812
|
w={id:n.id||l,title:n.title||"Unknown Request",description:n.description||"No description available",status:n.status||"unknown",type:n.type||"unknown",createdAt:n.createdAt||(new Date).toISOString(),updatedAt:n.updatedAt||(new Date).toISOString()},u.info("Found request: "+w.title)}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
4805
4813
|
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}
|
|
4806
|
-
u.warn("Could not fetch request information: "+t),w={id:l,title:"Unknown Request",description:"No description available",status:"unknown",type:"unknown",createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()}}if("detailed"===
|
|
4814
|
+
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()
|
|
4807
4815
|
let o=[]
|
|
4808
|
-
try{
|
|
4816
|
+
try{g?(o=await e.getToolRecordsByTaskId(g),u.info(`Fetched ${o.length} records for task ${g}`)):(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"
|
|
4809
4817
|
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
|
|
4810
4818
|
let u=t.filter((e=>{const t=e.type
|
|
4811
4819
|
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()))
|
|
@@ -4819,10 +4827,10 @@ let r=0
|
|
|
4819
4827
|
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])
|
|
4820
4828
|
if(e&&e.trim()){const r=500,n=e.length
|
|
4821
4829
|
if(n>r){const o=e.substring(0,r),s=(n/1024).toFixed(1)
|
|
4822
|
-
d+=`\n**Changes preview** (first ${r} chars):\n\`\`\`diff\n${o}\n\`\`\`\n`,d+=`... (diff truncated, ${s}KB total)\n`,d+=`\u{1f4a1} Use \`file-history\` tool with commit \`${t.metadata.commitHash.substring(0,8)}\` to see full diff\n`}else d+=`\n**Changes:**\n\`\`\`diff\n${e}\n\`\`\`\n`}}catch(e){c.debug("Could not fetch diff for commit",{commit:t.metadata.commitHash,error:(0,i.getErrorMessage)(e)})}d+="\n---\n\n"}return d}(w,o,
|
|
4830
|
+
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,m,t.git,u,f)
|
|
4823
4831
|
return h({success:!0,recordCount:o.length}),{content:[{type:"text",text:s}]}}{const e=c.getToolRecordClient()
|
|
4824
4832
|
let n=[]
|
|
4825
|
-
try{
|
|
4833
|
+
try{g?(n=await e.getToolRecordsByTaskId(g),u.info(`Fetched ${n.length} records for task ${g}`)):(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
|
|
4826
4834
|
let o=0
|
|
4827
4835
|
for(const s of e){const e=s.type
|
|
4828
4836
|
if(!["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(e))continue
|
|
@@ -4864,17 +4872,17 @@ return s.default.writeFileSync(t,JSON.stringify(c,null,2)),n(e,t,r),h.info("Crea
|
|
|
4864
4872
|
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}}
|
|
4865
4873
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.acquireProcessLock=function(e){const t=i.default.join(e,c.ALCHEMY_DIR_NAME)
|
|
4866
4874
|
let o,l
|
|
4867
|
-
try{s.default.existsSync(t)||(s.default.mkdirSync(t,{recursive:!0}),h.debug(`Created ${c.ALCHEMY_DIR_NAME} directory for lock file`,{alchemyLabDir:t})),o=i.default.join(t,".mcp-server.lock"),l=i.default.join(t,".mcp-agents.refs"),h.debug(`Using ${c.ALCHEMY_DIR_NAME} directory for lock files`,{lockFilePath:o,refsFilePath:l})}catch(r){h.error(`Failed to create ${c.ALCHEMY_DIR_NAME} directory`,{alchemyLabDir:t,error:r instanceof Error?r.message:r+""}),o=i.default.join(e,".mcp-server.lock"),l=i.default.join(e,".mcp-agents.refs"),h.warn("Falling back to base directory for lock files",{lockFilePath:o,refsFilePath:l})}const
|
|
4875
|
+
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,g=(new Date).toISOString()
|
|
4868
4876
|
try{const e=function(e){if(!s.default.existsSync(e))return null
|
|
4869
4877
|
try{const t=s.default.readFileSync(e,"utf8").trim()
|
|
4870
4878
|
try{const e=JSON.parse(t)
|
|
4871
4879
|
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
|
|
4872
4880
|
const e={mode:"multi-agent",created:(new Date).toISOString(),hostname:"unknown"}
|
|
4873
4881
|
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)
|
|
4874
|
-
if(h.info("Lock acquisition attempt",{pid:
|
|
4875
|
-
return i?(h.warn("\u26a0\ufe0f Clearing stale lock (older than 24 hours)",{lockAge:Math.round(t/1e3/60/60)+" hours",lockCreated:e.created,lockHostname:e.hostname}),r(o,l,g
|
|
4882
|
+
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(),m=e.hostname!==c&&"unknown"!==e.hostname
|
|
4883
|
+
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,g)):m?(h.warn("\u26a0\ufe0f Clearing lock from different machine",{lockHostname:e.hostname,currentHostname:c}),r(o,l,p,g)):"multi-agent"===e.mode?function(e,t,r){try{let o={count:0,processes:[]}
|
|
4876
4884
|
if(s.default.existsSync(e)){const t=s.default.readFileSync(e,"utf8")
|
|
4877
|
-
o=JSON.parse(t),o.processes=o.processes.filter((e=>function(e){try{return process.kill(e,0),!0}catch{return!1}}(e.pid))),o.count=o.processes.length}return o.processes.push({pid:t,started:r}),o.count=o.processes.length,s.default.writeFileSync(e,JSON.stringify(o,null,2)),n(e.replace(".mcp-agents.refs",".mcp-server.lock"),e,t),h.info("Joined multi-agent lock",{pid:t,totalAgents:o.count}),!0}catch(e){return h.error("Error joining multi-agent lock",{error:(0,d.getErrorMessage)(e)}),!1}}(l,g
|
|
4885
|
+
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,g):(h.info("Taking over legacy lock",{currentPid:p,oldMode:e.mode}),r(o,l,p,g))}return h.info("No existing lock - creating new lock",{pid:p,mode:"multi-agent"}),r(o,l,p,g)}catch(e){return h.error("Error acquiring lock",{error:(0,d.getErrorMessage)(e),pid:p}),!1}}
|
|
4878
4886
|
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"
|
|
4879
4887
|
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
|
|
4880
4888
|
let r=0,n=0
|
|
@@ -4923,16 +4931,16 @@ function r(e){const t=c[e]
|
|
|
4923
4931
|
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.`)
|
|
4924
4932
|
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)
|
|
4925
4933
|
if(!s(u.projectId)){const t=Error(`Invalid projectId format: ${u.projectId}. Cannot create failure record without valid projectId.`)
|
|
4926
|
-
throw l.error("Cannot create failure record due to invalid projectId",{toolName:e,projectId:u.projectId,error:t.message}),t}const h=Date.now(),
|
|
4934
|
+
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,"_"),g=(0,i.getErrorMessage)(t),m=t instanceof Error?t.stack:void 0
|
|
4927
4935
|
try{const t=r(e),s={}
|
|
4928
4936
|
let i,f
|
|
4929
4937
|
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})))
|
|
4930
|
-
let y=u.note||`Failed to execute ${e}: ${
|
|
4938
|
+
let y=u.note||`Failed to execute ${e}: ${g.substring(0,100)}${g.length>100?"...":""}`
|
|
4931
4939
|
Object.keys(s).length>0&&(y+=` (Warning: Invalid IDs provided: ${Object.entries(s).map((([e,t])=>`${e}: ${t}`)).join(", ")})`)
|
|
4932
|
-
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:
|
|
4933
|
-
i&&(w.taskId=i),f&&(w.requestId=f),l.info("Creating failure tool record for "+e,{toolName:e,recordType:w.type,...i&&{taskId:i},...f&&{requestId:f},projectId:u.projectId,invalidIds:Object.keys(s).length>0?s:void 0,error:
|
|
4940
|
+
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:g,errorStack:m,originalToolName:e,timestamp:(new Date).toISOString(),invalidIds:Object.keys(s).length>0?s:void 0,...a}}
|
|
4941
|
+
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:g})
|
|
4934
4942
|
const b=await c.createToolRecord(w)
|
|
4935
|
-
d.recordValue(
|
|
4943
|
+
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:g}),t}}
|
|
4936
4944
|
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"
|
|
4937
4945
|
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)
|
|
4938
4946
|
else if(e&&"object"==typeof e)for(const t of Object.keys(e)){const n=e[t]
|
|
@@ -4957,13 +4965,13 @@ function r(e,t,r){const n=exports.ERROR_TYPE_PROPERTIES[e]||exports.ERROR_TYPE_P
|
|
|
4957
4965
|
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)
|
|
4958
4966
|
return{statusCode:e.statusCode,body:t}}if(e instanceof Error&&"ConnectionError"===e.name){const t=e
|
|
4959
4967
|
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")
|
|
4960
|
-
return{statusCode:o.error.statusCode,body:o}}function s(e){return!n(e)||e.isRetryable()}Object.defineProperty(exports,"__esModule",{value:!0}),exports.UnauthorizedError=exports.McpProtocolError=exports.FileOperationError=exports.ServiceError=exports.DatabaseError=exports.AuthorizationError=exports.AuthenticationError=exports.ValidationError=exports.NotFoundError=exports.AppError=exports.ErrorUtils=exports.ERROR_TYPE_PROPERTIES=void 0,exports.createErrorResponse=r,exports.createAppError=function(e,t="INTERNAL_ERROR",r=500,n){return new a(e,t,r,n)},exports.createNotFoundError=function(e="Resource not found",t){return new c(e,t)},exports.createValidationError=function(e="Invalid input",t){return new l(e,t)},exports.createAuthenticationError=function(e="Authentication required",t){return new d(e,t)},exports.createAuthorizationError=function(e="Not authorized",t){return new u(e,t)},exports.createDatabaseError=function(e="Database error",t){return new h(e,t)},exports.createServiceError=function(e="Service unavailable",t){return new
|
|
4968
|
+
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 g(e,t)},exports.createMcpProtocolError=function(e="MCP protocol error",t){return new m(e,t)},exports.isAppError=n,exports.errorToResponse=o,exports.isRetryableError=s
|
|
4961
4969
|
const i=t(7388)
|
|
4962
4970
|
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}
|
|
4963
4971
|
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)
|
|
4964
4972
|
const o=exports.ERROR_TYPE_PROPERTIES[this.code]
|
|
4965
|
-
this.retryable=o?o.retryable:!n||!("retryable"in n)||!!n.retryable,Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,message:this.message,code:this.code,statusCode:this.statusCode,details:this.details,retryable:this.retryable,stack:this.stack}}get metadata(){return this.details}isRetryable(){return this.retryable}}class c extends a{constructor(e="Resource not found",t){super(e,i.NOT_FOUND,404,t),this.resourceType="unknown",t&&("taskId"in t?(this.code=i.TASK_NOT_FOUND,this.resourceType="task"):"requestId"in t&&(this.code=i.REQUEST_NOT_FOUND,this.resourceType="request"))}}class l extends a{constructor(e="Invalid input",t){super(e,i.VALIDATION_ERROR,400,t)}}class d extends a{constructor(e="Authentication required",t){super(e,i.UNAUTHORIZED,401,t)}}class u extends a{constructor(e="Not authorized",t){super(e,i.FORBIDDEN,403,t)}}class h extends a{constructor(e="Database error",t){super(e,"DATABASE_ERROR",500,t)}}class
|
|
4966
|
-
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class
|
|
4973
|
+
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
|
|
4974
|
+
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class g extends a{constructor(e="File operation error",t){super(e,"FILE_OPERATION_ERROR",500,t)}}class m extends a{constructor(e="MCP protocol error",t){super(e,i.MCP_PROTOCOL_ERROR,500,t)}}exports.AppError=a,exports.NotFoundError=c,exports.ValidationError=l,exports.AuthenticationError=d,exports.AuthorizationError=u,exports.DatabaseError=h,exports.ServiceError=p,exports.FileOperationError=g,exports.McpProtocolError=m,exports.UnauthorizedError=d},8712(e,exports){"use strict"
|
|
4967
4975
|
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}
|
|
4968
4976
|
const o=e.split("\n"),s=[],i=new Set
|
|
4969
4977
|
let a=!1,c=""
|
|
@@ -5017,9 +5025,9 @@ for(const a of r){const r=await n(a,t,o,s,i,e,c,l)
|
|
|
5017
5025
|
d.push(r)}return d}return l.debug(`Raw git log returned empty result for ${i}:${t}`),[]}catch(e){return l.warn(`Raw git log also failed for ${i}:${t}`,{error:e}),[]}}const h=a
|
|
5018
5026
|
if(!h||!h.all||0===h.all.length)return l.debug(`No commits found in standard git log for ${i}:${t}`),[]
|
|
5019
5027
|
l.info(`Found ${h.all.length} commits for ${i}:${t}`)
|
|
5020
|
-
const
|
|
5028
|
+
const p=[]
|
|
5021
5029
|
for(const r of h.all){const a=await n(r,t,o,s,i,e,c,l)
|
|
5022
|
-
|
|
5030
|
+
p.push(a)}return p}catch(e){return l.warn(`Failed to get history for ${i}:${t}`,{error:e}),[]}}async function n(e,t,r,n,o,s,i,a){let c=null,l=null
|
|
5023
5031
|
if(r)try{c=await s.show(["--format=",e.hash,"--",t])}catch(t){a.warn("Failed to get diff for commit",{commit:e.hash,error:t})}if(n){const t=(0,d.extractRecordId)(e.message)
|
|
5024
5032
|
if(t)try{l=await(0,d.getCachedTraceabilityInfo)(t,i,a)}catch(e){a.warn("Failed to get traceability info",{recordId:t,error:e})}}return{hash:e.hash,author:e.author_name,date:e.date,message:e.message,diff:c,traceability:l,branch:o}}var o,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
5025
5033
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
@@ -5029,7 +5037,7 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
5029
5037
|
var t={}
|
|
5030
5038
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
5031
5039
|
return i(t,e),t})
|
|
5032
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileHistory=async function(e,t,n,o,s){const i=o.child({tool:"file_history"}),a=s.startTimer("tool_execution_time"),
|
|
5040
|
+
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"),g=Date.now()
|
|
5033
5041
|
try{const o=e,{path:a,limit:m,showDiff:f,showTraceability:y,branch:w,commit:b,since:I}=o
|
|
5034
5042
|
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,"/")
|
|
5035
5043
|
if(n.info("Getting full diff for commit",{filePath:e,commit:t}),!o)return{content:[{type:"text",text:"\u274c Git not initialized"}],isError:!0}
|
|
@@ -5037,18 +5045,18 @@ try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
|
|
|
5037
5045
|
if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
|
|
5038
5046
|
const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
|
|
5039
5047
|
let a="# File History - Commit Diff\n\n"
|
|
5040
|
-
return a+=`**File:** ${e}\n`,a+=`**Commit:** ${t.substring(0,8)}\n`,a+=`**Author:** ${n.author_name}\n`,a+=`**Date:** ${n.date}\n`,a+=`**Message:** ${n.message}\n\n`,i&&i.trim()?a+=`## Full Diff\n\n\`\`\`diff\n${i}\n\`\`\`\n`:a+="*No diff available for this commit*\n",{content:[{type:"text",text:a}]}}catch(r){return n.error("Failed to get commit diff",{error:r,commit:t,filePath:e}),{content:[{type:"text",text:`\u274c Failed to get diff for commit ${t}: ${(0,h.getErrorMessage)(r)}`}],isError:!0}}}(a,b,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:m,showDiff:f,showTraceability:y,branch:w}),await async function(e,t,n,o,s,i,a,c,h,
|
|
5048
|
+
return a+=`**File:** ${e}\n`,a+=`**Commit:** ${t.substring(0,8)}\n`,a+=`**Author:** ${n.author_name}\n`,a+=`**Date:** ${n.date}\n`,a+=`**Message:** ${n.message}\n\n`,i&&i.trim()?a+=`## Full Diff\n\n\`\`\`diff\n${i}\n\`\`\`\n`:a+="*No diff available for this commit*\n",{content:[{type:"text",text:a}]}}catch(r){return n.error("Failed to get commit diff",{error:r,commit:t,filePath:e}),{content:[{type:"text",text:`\u274c Failed to get diff for commit ${t}: ${(0,h.getErrorMessage)(r)}`}],isError:!0}}}(a,b,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:m,showDiff:f,showTraceability:y,branch:w}),await async function(e,t,n,o,s,i,a,c,h,g,m){try{const{normalizedPath:f,fullPath:y}=p.validateAndNormalizePath(e,a)
|
|
5041
5049
|
try{await l.access(y)}catch(e){throw Error("File not found: "+f)}const w=a.git
|
|
5042
5050
|
if(!w)throw Error("Git is not available in this context")
|
|
5043
5051
|
let b={branch:null,requestId:null,isMain:!0}
|
|
5044
5052
|
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=""
|
|
5045
|
-
if(s)I=await r(w,f,t,n,o,s,i,c,h,
|
|
5046
|
-
else{if(b.isMain&&!o)return h.info("Showing request-level timeline on main branch"),{content:[{type:"text",text:await(0,u.getRequestTimelineForFile)(w,f,c,h,
|
|
5047
|
-
if(b.requestId)return h.info("Showing operation-level detail on request branch",{requestId:b.requestId}),{content:[{type:"text",text:await(0,u.getOperationDetailForFile)(f,b.requestId,c,h,
|
|
5053
|
+
if(s)I=await r(w,f,t,n,o,s,i,c,h,g),k=`## File History: ${f} (Branch: ${s})\n\n`
|
|
5054
|
+
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,g)}]}
|
|
5055
|
+
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,g)}]}
|
|
5048
5056
|
{const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
|
|
5049
|
-
if(!i.isMain&&i.branch){const
|
|
5050
|
-
u.push(...
|
|
5051
|
-
return u.push(...m),
|
|
5057
|
+
if(!i.isMain&&i.branch){const p=await r(e,t,n,o,s,i.branch,a,c,l,d)
|
|
5058
|
+
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),g=new Set(u.map((e=>e.hash))),m=p.filter((e=>!g.has(e.hash)))
|
|
5059
|
+
return u.push(...m),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,g)
|
|
5052
5060
|
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}]}
|
|
5053
5061
|
const v=I.length,C=Math.min(I.length,t)
|
|
5054
5062
|
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:** "
|
|
@@ -5057,9 +5065,9 @@ for(let e=0;e<I.length;e++){const t=I[e]
|
|
|
5057
5065
|
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")
|
|
5058
5066
|
let r=0,n=0
|
|
5059
5067
|
for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
|
|
5060
|
-
k+=`\n**Changes:**${r>0||n>0?` (Added ${r} lines, removed ${n} lines)`:""}\n\`\`\`diff\n${t.diff}\n\`\`\`\n`}k+="\n"}return k+="\u{1f4a1} **Tips:**\n",k+="- Use `file-recover` with a commit hash to restore the file to a previous version\n",k+='- Use `{"branch": "main"}` to see only main branch history\n',k+='- Use `{"branch": "req123456"}` to see only request branch history\n\n',h.info("Branch-aware file history retrieved successfully",{path:f,versions:I.length,targetBranch:s,currentBranch:b.branch,duration:Date.now()-m}),
|
|
5068
|
+
k+=`\n**Changes:**${r>0||n>0?` (Added ${r} lines, removed ${n} lines)`:""}\n\`\`\`diff\n${t.diff}\n\`\`\`\n`}k+="\n"}return k+="\u{1f4a1} **Tips:**\n",k+="- Use `file-recover` with a commit hash to restore the file to a previous version\n",k+='- Use `{"branch": "main"}` to see only main branch history\n',k+='- Use `{"branch": "req123456"}` to see only request branch history\n\n',h.info("Branch-aware file history retrieved successfully",{path:f,versions:I.length,targetBranch:s,currentBranch:b.branch,duration:Date.now()-m}),g.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:k}]}}catch(e){throw e}}(a,m,f,y,w,I,t,n,i,s,g))}catch(e){const t=Date.now()-g
|
|
5061
5069
|
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}}}
|
|
5062
|
-
const c=a(t(6928)),l=a(t(1943)),d=t(1181),u=t(2085),h=t(8824),
|
|
5070
|
+
const c=a(t(6928)),l=a(t(1943)),d=t(1181),u=t(2085),h=t(8824),p=a(t(5967)),g=a(t(7478)),{getCurrentBranch:m}=g},8849(e,exports,t){"use strict"
|
|
5063
5071
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
5064
5072
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5065
5073
|
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=[]
|
|
@@ -5183,63 +5191,63 @@ return"string"==typeof e&&e.startsWith("R-")?"acknowledge-report":"string"==type
|
|
|
5183
5191
|
if(t)return t
|
|
5184
5192
|
try{const t=await fetch(`http://localhost:${b}/api/sessions/${encodeURIComponent(e)}/agent-type`)
|
|
5185
5193
|
if(t.ok){const r=await t.json()
|
|
5186
|
-
if(r.success&&r.agentType)return I.set(e,r.agentType),r.agentType}}catch{}return null}async function o(e,t,r,o,s){try{const i=await(0,
|
|
5194
|
+
if(r.success&&r.agentType)return I.set(e,r.agentType),r.agentType}}catch{}return null}async function o(e,t,r,o,s){try{const i=await(0,p.getServerUrl)(r,o)
|
|
5187
5195
|
if(!i)return o.warn("Could not get server URL for notification",{sessionId:e}),!1
|
|
5188
5196
|
const a=await n(e)??void 0
|
|
5189
5197
|
let c
|
|
5190
5198
|
try{const e=await fetch(`http://localhost:${b}/api/project-settings`)
|
|
5191
5199
|
if(e.ok){const t=await e.json()
|
|
5192
5200
|
if(t.data?.defaultModel){const[e,...r]=t.data.defaultModel.split("/")
|
|
5193
|
-
c={providerID:e,modelID:r.join("/")}}}}catch{}const l=`${i.replace(/\/$/,"")}/session/${e}/prompt_async`,d={type:"text",text:t,metadata:s??(0,
|
|
5201
|
+
c={providerID:e,modelID:r.join("/")}}}}catch{}const l=`${i.replace(/\/$/,"")}/session/${e}/prompt_async`,d={type:"text",text:t,metadata:s??(0,g.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}:{}})})
|
|
5194
5202
|
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
|
|
5195
5203
|
if(!s)throw new u.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
|
|
5196
5204
|
return(0,w.logSessionIdentity)(""+r,"identity",{sessionId:s,fromCliOrigin:!!o?.sessionId}),s}function a(e){const t=[],r=e.content||{}
|
|
5197
5205
|
if(t.push("**Message Code:** "+e.messageCode),t.push(`**Type:** question (${r.questionType})`),t.push("**Status:** "+e.status),t.push("**Priority:** "+e.priority),t.push("**From:** "+e.fromSessionId),t.push(e.toSessionId?"**To:** "+e.toSessionId:"**To:** (broadcast)"),t.push("**Created:** "+e.createdAt),t.push("**Expires:** "+e.expiresAt),t.push(""),t.push("**Question:** "+r.question),r.context&&t.push("**Context:** "+r.context),"alternatives"===r.questionType&&r.options){t.push(""),t.push("**Options:**")
|
|
5198
5206
|
for(const e of r.options)t.push(` - [${e.id}] ${e.label}${e.description?" - "+e.description:""}`)}return"responded"===e.status&&e.response&&(t.push(""),t.push("---"),t.push("**Answered by:** "+e.respondedBySessionId),t.push("**Answered at:** "+e.respondedAt),e.response.text&&t.push("**Answer:** "+e.response.text),e.response.selectedOptions&&t.push("**Selected:** "+e.response.selectedOptions.join(", ")),e.response.notes&&t.push("**Notes:** "+e.response.notes)),c(r,t),t.join("\n")}function c(e,t){e?.relatesTo&&(t.push(""),t.push("**Relates to:** "+e.relatesTo))}function l(e){const t=[],r=e.content||{}
|
|
5199
5207
|
return t.push("**Status:** "+(r.reportStatus||"unknown")),t.push("**Summary:** "+(r.summary||"")),r.details&&(t.push(""),t.push("**Details:**"),t.push(r.details)),c(r,t),t.join("\n")}function d(e){return"question"===e.messageType?a(e):"instruction"===e.messageType?function(e){const t=[],r=e.content||{}
|
|
5200
|
-
return t.push("**Message Code:** "+e.messageCode),t.push("**Type:** instruction"),t.push("**Status:** "+e.status),t.push("**From:** "+e.fromSessionId),t.push("**To:** "+e.toSessionId),t.push("**Created:** "+e.createdAt),r.requestId&&t.push("**Request:** "+r.requestId),t.push(""),t.push("**Body:**"),t.push(r.body||""),t.join("\n")}(e):l(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSessionMessageOperations=async function(e,t,c,
|
|
5208
|
+
return t.push("**Message Code:** "+e.messageCode),t.push("**Type:** instruction"),t.push("**Status:** "+e.status),t.push("**From:** "+e.fromSessionId),t.push("**To:** "+e.toSessionId),t.push("**Created:** "+e.createdAt),r.requestId&&t.push("**Request:** "+r.requestId),t.push(""),t.push("**Body:**"),t.push(r.body||""),t.join("\n")}(e):l(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSessionMessageOperations=async function(e,t,c,p,b,I){const k=c.child({component:"session_message_operations"})
|
|
5201
5209
|
if(!b)throw new u.ValidationError("API client not available")
|
|
5202
5210
|
const{operation:v}=e
|
|
5203
|
-
k.info("Session message operation",{operation:v}),
|
|
5211
|
+
k.info("Session message operation",{operation:v}),p.incrementCounter("session_message_operations",1,{operation:v})
|
|
5204
5212
|
try{switch(v){case"send":if(!e.type)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
5205
|
-
return(0,
|
|
5213
|
+
return(0,g.withAlchemyKind)(await async function(e,t,r,c,d){const{type:h}=e
|
|
5206
5214
|
if(!h)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
5207
|
-
const
|
|
5208
|
-
if(!
|
|
5209
|
-
if("question"===h)return await async function(e,t,r,c,l,d){const{toSessionId:h,questionType:
|
|
5210
|
-
if(!g
|
|
5215
|
+
const p=c.getSessionMessageClient()
|
|
5216
|
+
if(!p)throw new u.ValidationError("Session message client not available")
|
|
5217
|
+
if("question"===h)return await async function(e,t,r,c,l,d){const{toSessionId:h,questionType:p,questionContent:g,priority:m,expiresInHours:f,relatesTo:w}=e
|
|
5218
|
+
if(!p||!g?.question)throw new u.ValidationError("Question requires questionType and questionContent.question")
|
|
5211
5219
|
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)
|
|
5212
5220
|
if(!e)throw new u.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
|
|
5213
5221
|
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)
|
|
5214
|
-
if(!("alternatives"!==g
|
|
5215
|
-
r.info("Creating question",{fromSessionId:b,toSessionId:I,questionType:
|
|
5216
|
-
const k=await l.createQuestion({fromSessionId:b,toSessionId:I,questionType:
|
|
5222
|
+
if(!("alternatives"!==p||g.options&&Array.isArray(g.options)))throw new u.ValidationError("Alternatives questions require options array")
|
|
5223
|
+
r.info("Creating question",{fromSessionId:b,toSessionId:I,questionType:p})
|
|
5224
|
+
const k=await l.createQuestion({fromSessionId:b,toSessionId:I,questionType:p,question:g.question,options:g.options,context:g.context,allowMultiple:g.allowMultiple,priority:m,expiresInHours:f,...w?{relatesTo:w}:{}})
|
|
5217
5225
|
let v=""
|
|
5218
|
-
if(I){const e=await n(b)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:
|
|
5226
|
+
if(I){const e=await n(b)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:g.question,questionType:p,options:g.options,context:g.context,allowMultiple:g.allowMultiple,fromAgent:e,fromSessionId:b,priority:k.priority,expiresAt:k.expiresAt,...w?{relatesTo:w}:{}}}}
|
|
5219
5227
|
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]
|
|
5220
5228
|
if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&&t.options){r.push(""),r.push("**Options:**")
|
|
5221
|
-
for(const e of t.options)r.push(` - [${e.id}] ${e.label}${e.description?" - "+e.description:""}`)}return r.push(""),r.push(`Use \`session_message_operations\` with \`reply\` operation and message code \`${e.messageCode}\` to respond.`),r.join("\n")}(k),t,r,s)?"\n\n\u{1f4ec} The target session has been notified.":"\n\n\u26a0\ufe0f Could not notify the target session (may be offline)."}return{content:[{type:"text",text:`\u2705 Question created!${v}\n\n**Message Code: ${k.messageCode}**\n\nUse this code to check for answers or share with other sessions.\n\n${a(k)}`}]}}(e,t,r,c,
|
|
5222
|
-
if("report"===h)return await async function(e,t,r,a,c,d){const{status:h,summary:
|
|
5223
|
-
if(!h||!
|
|
5229
|
+
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)
|
|
5230
|
+
if("report"===h)return await async function(e,t,r,a,c,d){const{status:h,summary:p,details:g,finish:f,relatesTo:w}=e
|
|
5231
|
+
if(!h||!p)throw new u.ValidationError("Report requires status and summary")
|
|
5224
5232
|
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)
|
|
5225
5233
|
const t=await s(b,a,r)
|
|
5226
5234
|
if(t)return r.info("Auto-resolved parent session",{parentSessionId:t}),t
|
|
5227
5235
|
throw new u.ValidationError("Could not find parent session. Ensure this session was created with a parent link, or provide an explicit toSessionId.")})()
|
|
5228
5236
|
r.info("Submitting report",{sessionId:b,parentSessionId:I,status:h})
|
|
5229
|
-
const k=await c.createReport({fromSessionId:b,toSessionId:I,status:h,summary:
|
|
5237
|
+
const k=await c.createReport({fromSessionId:b,toSessionId:I,status:h,summary:p,details:g,...w?{relatesTo:w}:{}}),v=await n(b)??"agent",C={alchemy:{kind:"worker-report",payload:{status:h,summary:p,details:g,fromAgent:v,fromSessionId:b,...w?{relatesTo:w}:{}}}},_=await o(I,function(e,t="agent"){const r=e.content||{}
|
|
5230
5238
|
return(0,m.formatReportNotification)({messageCode:e.messageCode,status:r.reportStatus,summary:r.summary,details:r.details,fromSessionId:e.fromSessionId,senderAgent:t})}(k,v),t,r,C)
|
|
5231
|
-
return{content:[{type:"text",text:`\u2705 Report submitted.${_?"\n\n\u{1f4ec} The parent session has been notified.":"\n\n\u26a0\ufe0f Could not notify the parent session (may be offline)."}\n\n${l(k)}`}]}}(e,t,r,c,
|
|
5239
|
+
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)
|
|
5232
5240
|
throw new u.ValidationError(`Unknown message type: ${h}. Use "question" or "report".`)}(e,t,k,b,I),r("send",e))
|
|
5233
5241
|
case"reply":if(!e.messageCode)throw new u.ValidationError("reply operation requires messageCode")
|
|
5234
|
-
return(0,
|
|
5242
|
+
return(0,g.withAlchemyKind)(await async function(e,t,r,s,i){const{messageCode:c}=e
|
|
5235
5243
|
if(!c)throw new u.ValidationError("reply operation requires messageCode")
|
|
5236
5244
|
const d=s.getSessionMessageClient()
|
|
5237
5245
|
if(!d)throw new u.ValidationError("Session message client not available")
|
|
5238
5246
|
if(c.startsWith("Q-")){const{text:s,selectedOptions:l,notes:u}=e,h=e.respondedBySessionId??i?.sessionId
|
|
5239
5247
|
r.info("Answering question",{messageCode:c,respondedBySessionId:h,autoDerived:!e.respondedBySessionId})
|
|
5240
|
-
const
|
|
5241
|
-
return r.text&&n.push("**Answer:** "+r.text),r.selectedOptions&&n.push("**Selected:** "+r.selectedOptions.join(", ")),r.notes&&n.push("**Notes:** "+r.notes),n.join("\n")}(
|
|
5242
|
-
return{content:[{type:"text",text:`\u2705 Question answered!${w?"\n\n\u{1f4ec} The asking session has been notified.":"\n\n\u26a0\ufe0f Could not notify the asking session (may be offline)."}\n\n${a(
|
|
5248
|
+
const p=await d.answerQuestion(c,{respondedBySessionId:h,text:s,selectedOptions:l,notes:u}),g=h?await n(h)??"agent":"agent",m=p.content||{},f=p.response||{},y={alchemy:{kind:"question-answered",payload:{messageCode:p.messageCode,question:m.question,answer:f.text,selectedOptions:f.selectedOptions,notes:f.notes,answeredByAgent:g,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]
|
|
5249
|
+
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)
|
|
5250
|
+
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})
|
|
5243
5251
|
const e=await d.acknowledgeReport(c)
|
|
5244
5252
|
let s=""
|
|
5245
5253
|
if(e?.fromSessionId){const a=i?.sessionId,c=a?await n(a)??"agent":"agent",l=e.content||{},d={alchemy:{kind:"report-acknowledged",payload:{messageCode:e.messageCode,summary:l.summary,acknowledgedByAgent:c,acknowledgedBySessionId:a}}}
|
|
@@ -5252,13 +5260,13 @@ let l
|
|
|
5252
5260
|
try{const e=b.getSessionMessageClient()
|
|
5253
5261
|
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"})
|
|
5254
5262
|
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()
|
|
5255
|
-
e&&(await e.answerQuestion(l,{respondedBySessionId:"system",selectedOptions:["build"]}),a=!0,k.info("offer-handoff: auto-confirmed for auto-planner",{fromSessionId:r,messageCode:l}))}catch(e){k.warn("offer-handoff: failed to auto-confirm for auto-planner",{error:(0,h.getErrorMessage)(e)})}return(0,
|
|
5263
|
+
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,g.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,g.alchemyMeta)({pendingAction:{kind:"plan-handoff",payload:{summary:t.summary,requestIds:t.requestIds,parentSessionId:o,fromSessionId:r,autoConfirmed:a}}})},"offer-handoff")}case"list":return(0,g.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:g}=e
|
|
5256
5264
|
const m=n.getSessionMessageClient()
|
|
5257
5265
|
if(!m)throw new u.ValidationError("Session message client not available")
|
|
5258
5266
|
if(!s){const e=o?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
|
|
5259
5267
|
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."}]}
|
|
5260
5268
|
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})
|
|
5261
|
-
const y={sessionId:s,direction:a,limit:
|
|
5269
|
+
const y={sessionId:s,direction:a,limit:p,offset:g}
|
|
5262
5270
|
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)
|
|
5263
5271
|
const b=await m.listMessages(y)
|
|
5264
5272
|
if(0===b.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
|
|
@@ -5266,7 +5274,7 @@ const I=[`Found ${b.length} message(s):\n`]
|
|
|
5266
5274
|
for(const e of b)I.push("---\n"),I.push(d(e)),I.push("")
|
|
5267
5275
|
return{content:[{type:"text",text:I.join("\n")}]}}(e.list||{},0,k,b,I),"list-messages")
|
|
5268
5276
|
case"get":if(!e.messageCode)throw new u.ValidationError("get operation requires messageCode")
|
|
5269
|
-
return(0,
|
|
5277
|
+
return(0,g.withAlchemyKind)(await async function(e,t,r){const{messageCode:n}=e
|
|
5270
5278
|
if(!n)throw new u.ValidationError("get operation requires messageCode")
|
|
5271
5279
|
const o=r.getSessionMessageClient()
|
|
5272
5280
|
if(!o)throw new u.ValidationError("Session message client not available")
|
|
@@ -5274,7 +5282,7 @@ t.debug("Getting message",{messageCode:n})
|
|
|
5274
5282
|
const s=await o.getMessage(n)
|
|
5275
5283
|
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")
|
|
5276
5284
|
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}}}
|
|
5277
|
-
const u=t(9860),h=t(8824),
|
|
5285
|
+
const u=t(9860),h=t(8824),p=t(7617),g=t(2272),m=t(7904),f=t(6688),y=t(3545),w=t(7280),b=(0,t(9414).getActionServerPort)(),I=new Map},9080(e,exports,t){"use strict"
|
|
5278
5286
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
5279
5287
|
const r=t(6183),n=t(1281)
|
|
5280
5288
|
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"
|
|
@@ -5300,12 +5308,12 @@ let l,d
|
|
|
5300
5308
|
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)})
|
|
5301
5309
|
let u=0
|
|
5302
5310
|
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})
|
|
5303
|
-
let h=!1,
|
|
5304
|
-
if(0!==u?(h=!0,
|
|
5305
|
-
!
|
|
5311
|
+
let h=!1,p="",g=null
|
|
5312
|
+
if(0!==u?(h=!0,p="merge-tree-exit-code"):d&&d.trim()?(g=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch),g.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}
|
|
5313
|
+
!g&&d&&d.trim()&&(g=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch))
|
|
5306
5314
|
let m=[]
|
|
5307
|
-
if(
|
|
5308
|
-
else try{m=this.parseMergeTreeOutput(d,r),r.debug("Used fallback merge-tree parsing",{conflictedFilesCount:m.length})}catch(e){r.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),m=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===m.length&&(r.warn("Git detected conflicts but no files could be determined - using fallback"),m=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:m,summary:m.length>0&&"<parsing failed>"!==m[0].path&&"<unknown files>"!==m[0].path?m.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateMultiAgentInstructions(m,e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:d,rawConflictContent:
|
|
5315
|
+
if(g&&g.filesParsed&&g.filesParsed.length>0)m=g.filesParsed.map((e=>({path:e,conflictType:"content",description:"Merge conflict detected"}))),r.debug("Successfully extracted conflict files from parsed content",{conflictedFilesCount:m.length,files:m.map((e=>e.path))})
|
|
5316
|
+
else try{m=this.parseMergeTreeOutput(d,r),r.debug("Used fallback merge-tree parsing",{conflictedFilesCount:m.length})}catch(e){r.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),m=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===m.length&&(r.warn("Git detected conflicts but no files could be determined - using fallback"),m=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:m,summary:m.length>0&&"<parsing failed>"!==m[0].path&&"<unknown files>"!==m[0].path?m.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateMultiAgentInstructions(m,e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:d,rawConflictContent:g?g.cleanContent:void 0}}catch(e){throw r.error("Pure multi-agent conflict detection failed",{error:e}),e}}parseMergeTreeOutput(e,t){const r=[]
|
|
5309
5317
|
if(!e||!e.trim())return t.debug("Empty merge-tree output - no conflicts to parse"),[]
|
|
5310
5318
|
let n
|
|
5311
5319
|
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
|
|
@@ -5362,23 +5370,23 @@ o+=`## Test 4: All commits containing "${n}" (not just merges)\n`,o+=`Found ${e?
|
|
|
5362
5370
|
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()
|
|
5363
5371
|
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}}}
|
|
5364
5372
|
const r=t(8824)},9442(e,exports,t){"use strict"
|
|
5365
|
-
function r(e){return{line:e.line,actually_matched:e.actuallyMatched,match_type:e.matchType}}async function n(e,t,n,o,s,i,a){const{path:c,documentId:d,replacements:
|
|
5373
|
+
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:g}=e,m=!!d,f=void 0!==g?g:t,y={type:m?"document":"file",path:c,documentId:d,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,externalEditDebugInfo:{detectionRan:!1,reason:m?"Skipped: Document operation":n.git?"Pending":"Skipped: No Git context"}}
|
|
5366
5374
|
try{let t,o
|
|
5367
5375
|
if(m){t=await n.documentFileManager.getDocumentAsFile(d)
|
|
5368
5376
|
const e=n.documentFileManager.getCachedDocumentInfo(d)
|
|
5369
5377
|
y.filename=e?.filename,o="document:"+d}else{const e=u.validateAndNormalizePath(c,n)
|
|
5370
|
-
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),
|
|
5371
|
-
for(const t of
|
|
5378
|
+
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),g=[]
|
|
5379
|
+
for(const t of p){const{old:n,new:o,match_mode:i="unique"}=t,a={old:n,new:o,success:!1}
|
|
5372
5380
|
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)
|
|
5373
5381
|
continue}const t=(0,h.findMatches)(s,n,f,100,e.path)
|
|
5374
5382
|
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(f?" (tried fuzzy matching)":""),a.success=!1
|
|
5375
5383
|
const e=(0,h.findSimilarMatches)(s,n,5,.3)
|
|
5376
|
-
e.length>0&&(a.similarMatches=e),y.failedReplacements++}else"unique"===i&&t.length>1?(a.error=`Multiple matches found (${t.length}) - expected unique match`,a.success=!1,a.details=t.map(r),y.failedReplacements++):
|
|
5384
|
+
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++):g.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
|
|
5377
5385
|
const I=[]
|
|
5378
|
-
for(const e of
|
|
5386
|
+
for(const e of g)for(const t of e.matches)I.push({match:t,newText:e.newText,repResult:e.repResult})
|
|
5379
5387
|
I.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5380
5388
|
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++)
|
|
5381
|
-
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),m&&(n.documentFileManager.markForSync(d),await n.documentFileManager.syncDocument(d))),i&&(y.externalEditWarning=i),a&&(y.externalEditDebugInfo={detectionRan:!0,...a}),y.success=0===y.failedReplacements}catch(e){y.error=(0,b.getErrorMessage)(e),y.success=!1,y.failedReplacements=
|
|
5389
|
+
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),m&&(n.documentFileManager.markForSync(d),await n.documentFileManager.syncDocument(d))),i&&(y.externalEditWarning=i),a&&(y.externalEditDebugInfo={detectionRan:!0,...a}),y.success=0===y.failedReplacements}catch(e){y.error=(0,b.getErrorMessage)(e),y.success=!1,y.failedReplacements=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)
|
|
5382
5390
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5383
5391
|
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=[]
|
|
5384
5392
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -5393,7 +5401,7 @@ if("errorResult"in T)return T.errorResult
|
|
|
5393
5401
|
const{taskId:q}=T,{operations:P,fuzzy_match:j=!0,comment:R}=E
|
|
5394
5402
|
k.info("Replace in files batch operation",{taskId:q,operationCount:P.length,totalReplacements:P.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:j,comment:R})
|
|
5395
5403
|
const x=P.filter((e=>e.documentId)).map((e=>e.documentId))
|
|
5396
|
-
if(x.length>0&&r.apiClient)try{await(0,f.ensureDocumentsNotLocked)(x,r.apiClient,k,c,"replace_in_files-documents")}catch(e){if(e instanceof
|
|
5404
|
+
if(x.length>0&&r.apiClient)try{await(0,f.ensureDocumentsNotLocked)(x,r.apiClient,k,c,"replace_in_files-documents")}catch(e){if(e instanceof p.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5397
5405
|
throw e}_=u.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_in_files_phase",1,{phase:_})
|
|
5398
5406
|
const M=P[0],O=M.documentId?"document:"+M.documentId:M.path
|
|
5399
5407
|
let $=Date.now()
|
|
@@ -5408,7 +5416,7 @@ const t=await u.autoPromoteTaskStatus(q,D.status,A,e.request?.status,O,o,i,k,c,"
|
|
|
5408
5416
|
t.taskPromoted&&k.info("Auto-promoted task to in_progress",{taskId:q,requestId:A,previousStatus:D.status,newStatus:t.newTaskStatus}),Date.now(),$=Date.now()
|
|
5409
5417
|
const n=await u.ensureCorrectWorkspaceContext({taskPromoted:t.taskPromoted,requestId:A,context:r,operation:"replace_in_files",logger:k,metrics:c,metricsPrefix:"replace_in_files"})
|
|
5410
5418
|
if(!n.success)throw Error(n.error)
|
|
5411
|
-
Date.now(),N=!0}if(x.length>0&&A)try{await(0,
|
|
5419
|
+
Date.now(),N=!0}if(x.length>0&&A)try{await(0,g.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}
|
|
5412
5420
|
throw e}$=Date.now()
|
|
5413
5421
|
const z=new Map
|
|
5414
5422
|
if(k.info("\u{1f50d} Starting external edit detection",{hasFileOperations:F,hasGit:!!r.git,operationCount:P.length}),F&&r.git)for(const e of P)if(e.path&&!e.documentId)try{const t=u.validateAndNormalizePath(e.path,r),n=await l.default.readFile(t.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:j,s=[]
|
|
@@ -5444,7 +5452,7 @@ const d=o.workspaceManager?.consumeLargeFileWarning(o.currentSessionId)
|
|
|
5444
5452
|
return d&&(c+=d),c}(H,W,J,Q,r)
|
|
5445
5453
|
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
|
|
5446
5454
|
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))
|
|
5447
|
-
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(2272)),u=a(t(5967)),h=t(3626),
|
|
5455
|
+
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),g=t(5003),m=t(7478),f=t(9949),y=t(9947),w=t(1318),b=t(8824)},9470(e,exports){"use strict"
|
|
5448
5456
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
|
|
5449
5457
|
const t=e.trim()
|
|
5450
5458
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|
|
@@ -5513,12 +5521,12 @@ const s=n.sortDirection??"desc"
|
|
|
5513
5521
|
return o.sortDirection="asc"===s||"desc"===s?s:"desc",{requestId:r,filters:o}}catch(t){throw new r.ValidationError("Invalid input: "+(0,n.getErrorMessage)(t),{args:e,error:t})}}(e),u=t.projectId
|
|
5514
5522
|
if(!u)throw new r.ValidationError("Project ID is required for listing tasks with the new API structure")
|
|
5515
5523
|
a.incrementCounter("list_tasks_attempts",1,{hasRequestId:!!i,hasFilters:Object.keys(d).length>0}),s.setProjectId(u)
|
|
5516
|
-
const h=s.getTaskClient(),
|
|
5517
|
-
i&&(
|
|
5518
|
-
const
|
|
5519
|
-
c.info("Raw tasks response data",{responseData:JSON.stringify(
|
|
5524
|
+
const h=s.getTaskClient(),p=d
|
|
5525
|
+
i&&(p.requestId=i),c.info("Listing tasks with filters",{projectId:u,taskFilters:p})
|
|
5526
|
+
const g=await h.listTasks(p)
|
|
5527
|
+
c.info("Raw tasks response data",{responseData:JSON.stringify(g)}),c.info("Tasks response structure",{type:typeof g,isArray:Array.isArray(g),hasData:null!=g,properties:g?Object.keys(g):[],dataPreview:g?JSON.stringify(g).substring(0,200)+"...":"null"})
|
|
5520
5528
|
let m=[]
|
|
5521
|
-
|
|
5529
|
+
g&&"object"==typeof g?"success"in g&&"data"in g?Array.isArray(g.data)?(m=g.data,c.info("Extracted tasks from success/data wrapper",{count:m.length})):g.data&&"object"==typeof g.data&&(m=[g.data],c.info("Extracted single task from success/data wrapper")):"data"in g?Array.isArray(g.data)?(m=g.data,c.info("Extracted tasks from data wrapper",{count:m.length})):g.data&&"object"==typeof g.data&&(m=[g.data],c.info("Extracted single task from data wrapper")):Array.isArray(g)?(m=g,c.info("Tasks response is direct array",{count:m.length})):(m=[g],c.info("Tasks response is single object")):(c.warn("Unexpected response format, using empty array",{responseType:typeof g}),m=[])
|
|
5522
5530
|
const f=m
|
|
5523
5531
|
if(c.info(`Retrieved ${f.length} tasks`,{count:f.length,requestId:i,projectId:u}),0===f.length){let e=""
|
|
5524
5532
|
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
|
|
@@ -5628,8 +5636,8 @@ function r(e){return a.default.createHash("md5").update(e).digest("hex")}async f
|
|
|
5628
5636
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.syncPluginsGlobal=async function(e,t,o){const a={synced:[],skipped:[],errors:[]},d=o||function(){const e=process.argv[1]
|
|
5629
5637
|
let t=e
|
|
5630
5638
|
try{t=s.default.realpathSync(e)}catch{}return i.default.dirname(t)}(),u=i.default.join((0,c.getGlobalConfigDir)(e),"plugin")
|
|
5631
|
-
try{await s.default.promises.mkdir(u,{recursive:!0})}catch(e){return t.error("Failed to create global plugin directory",{destDir:u,error:e instanceof Error?e.message:"Unknown error"}),a}const h=i.default.join(u,"package.json"),
|
|
5632
|
-
try{await s.default.promises.readFile(h,"utf8").catch((()=>null))!==
|
|
5639
|
+
try{await s.default.promises.mkdir(u,{recursive:!0})}catch(e){return t.error("Failed to create global plugin directory",{destDir:u,error:e instanceof Error?e.message:"Unknown error"}),a}const h=i.default.join(u,"package.json"),p='{"type":"module"}\n'
|
|
5640
|
+
try{await s.default.promises.readFile(h,"utf8").catch((()=>null))!==p&&await s.default.promises.writeFile(h,p,"utf8")}catch(e){t.warn("Failed to write global plugin package.json",{error:e instanceof Error?e.message:"Unknown error"})}for(const e of l){const o=i.default.join(d,e.sourceName),c=i.default.join(u,e.destName)
|
|
5633
5641
|
try{if(!s.default.existsSync(o)){t.warn("Plugin source not found: "+e.sourceName,{sourcePath:o}),a.errors.push(e.destName)
|
|
5634
5642
|
continue}const i=await s.default.promises.readFile(o,"utf8").catch((()=>null))
|
|
5635
5643
|
if(null===i){t.warn("Could not read plugin source: "+e.sourceName),a.errors.push(e.destName)
|