alchemylab 1.4.7 → 1.4.9
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 +107 -110
- package/dist/http-server.js +680 -632
- package/dist/index.js +303 -255
- package/dist/mcp-direct.js +2254 -2206
- package/package.json +1 -1
package/dist/http-server.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)),p=t(9567),
|
|
18
|
-
!(0,
|
|
19
|
-
class j{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,w.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new
|
|
17
|
+
const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),p=t(9567),m=t(3444),g=t(7660),f=t(1253),y=i(t(7478)),w=t(4139),I=new Set,b=t(9860),k=t(1472),v=t(3328),C=t(8955),_=t(3217),E=t(5278),S=t(9060),q=t(8824),T=(0,m.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),P=process.stdout.write,x=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
|
|
18
|
+
!(0,m.isDebugToolsEnabled)()||x&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,m.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&T.debug("Stdout output",{content:e.substring(0,100),length:e.length}),P.call(process.stdout,e)}catch(e){return T.error("Error in safeStdoutWrite",{error:e+""}),!0}})
|
|
19
|
+
class j{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,w.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new g.ProjectContext(e,t),this.tokenManager=new f.TokenManager(t,e,{remoteServerUrl:n}),this.configManager=new S.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new p.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{listChanged:!0}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
|
|
20
20
|
const e=this.workspaceManager.getCurrentContext("__server__")
|
|
21
21
|
return{currentBranch:e.branchName,activeRequestId:e.requestId,isOnMainBranch:e.isMainBranch}}async updateBranchState(e,t){this.logger.debug("updateBranchState called - managed by WorkspaceManager",{branch:e,requestId:t})}async getCurrentBranchContext(){if(!this.workspaceManager)return{branch:null,requestId:null,isMain:!0}
|
|
22
22
|
const e=this.workspaceManager.getCurrentContext("__server__")
|
|
@@ -114,12 +114,12 @@ case"quick-edit":return"\u26a1"
|
|
|
114
114
|
default:return"\u{1f4e6}"}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSearchRequests=async function(e,t,c,l,d){const u=l.child({tool:"search_requests"}),h=d.startTimer("tool_execution_time")
|
|
115
115
|
try{const{query:a,searchIn:l="all",filters:p={}}=e.search||e
|
|
116
116
|
if(!a||0===a.trim().length)throw new i.ValidationError("Search query is required")
|
|
117
|
-
const
|
|
118
|
-
if(!
|
|
119
|
-
u.info("Searching requests",{query:a,searchIn:l,filters:p,projectId:
|
|
120
|
-
const
|
|
121
|
-
p.status&&(
|
|
122
|
-
const f=c.getRequestClient(),y=await f.listRequests(
|
|
117
|
+
const m=t.projectId
|
|
118
|
+
if(!m)throw new i.ValidationError("Project ID is required for searching requests")
|
|
119
|
+
u.info("Searching requests",{query:a,searchIn:l,filters:p,projectId:m})
|
|
120
|
+
const g={limit:p.limit||100,offset:p.offset||0,sortBy:"updated_at",sortDirection:"desc"}
|
|
121
|
+
p.status&&(g.status=p.status),p.type&&(g.type=p.type),p.dateFrom&&(g.dateFrom=p.dateFrom),p.dateTo&&(g.dateTo=p.dateTo),c.setProjectId(m)
|
|
122
|
+
const f=c.getRequestClient(),y=await f.listRequests(g)
|
|
123
123
|
u.debug("Fetched requests for search",{count:y.length})
|
|
124
124
|
const w=[],I=a.toLowerCase()
|
|
125
125
|
for(const e of y){const t=[]
|
|
@@ -165,33 +165,34 @@ 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
|
|
169
|
-
try{const
|
|
170
|
-
switch(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return(0,
|
|
174
|
-
return
|
|
175
|
-
return
|
|
176
|
-
return
|
|
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
|
-
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
|
|
168
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlanWrite=async function(e,t,c,l,d,u,h){const p=l.child({tool:"plan_write"})
|
|
169
|
+
try{const i=e,{operation:l,planId:m}=i
|
|
170
|
+
switch(p.info("Processing plan_write",{operation:l}),l){case"create":{const e=await(0,s.handleCreatePlan)({name:i.name,content:i.content??""},t,c,p,d,u,h)
|
|
171
|
+
return d.incrementCounter("plan_write_total",1,{operation:"create",success:!e.isError}),(0,a.withAlchemyKind)(e,"plan-create")}case"update":{const e=await(0,r.handleUpdatePlan)({planId:m,content:i.content,name:i.name,metadata:{criteria:i.criteria,tickIntervalSeconds:i.tickIntervalSeconds,maxInFlight:i.maxInFlight,maxPerDay:i.maxPerDay,minIterations:i.minIterations,status:i.status,completionMode:i.completionMode}},t,c,p,d)
|
|
172
|
+
return d.incrementCounter("plan_write_total",1,{operation:"update",success:!e.isError}),(0,a.withAlchemyKind)(e,"plan-update")}case"append":{const e=await(0,n.handleAppendPlan)({planId:m,content:i.content,name:i.name},c,p,d)
|
|
173
|
+
return d.incrementCounter("plan_write_total",1,{operation:"append",success:!e.isError}),(0,a.withAlchemyKind)(e,"plan-append")}case"replace":{const e=await(0,o.handleReplacePlan)({planId:m,old:i.old,new:i.new,name:i.name},c,p,d)
|
|
174
|
+
return d.incrementCounter("plan_write_total",1,{operation:"replace",success:!e.isError}),(0,a.withAlchemyKind)(e,"plan-replace")}case"create-snapshot":{const{versionLabel:e,changeSummary:t}=i,r=c.getDocumentClient(),n=await r.createVersionSnapshot(m,e,t)
|
|
175
|
+
return d.incrementCounter("plan_write_total",1,{operation:"create-snapshot",success:!0}),(0,a.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}=i,t=c.getDocumentClient(),r=await t.restoreToVersion(m,e)
|
|
176
|
+
return d.incrementCounter("plan_write_total",1,{operation:"restore",success:!0}),(0,a.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
|
|
179
177
|
if(!e)return{content:[{type:"text",text:"\u274c No project context available."}],isError:!0}
|
|
180
|
-
const r=
|
|
178
|
+
const r=c.getDocumentClient(),n=await r.getDocument(m)
|
|
181
179
|
if(!n)return{content:[{type:"text",text:"\u274c Plan not found: "+m}],isError:!0}
|
|
182
180
|
if("Plan"!==n.type)return{content:[{type:"text",text:`\u274c Document ${m} is not a Plan (type: ${n.type}).`}],isError:!0}
|
|
183
|
-
const o=
|
|
184
|
-
await o.updateProject(e,{activePlanId:m}),
|
|
181
|
+
const o=c.getProjectClient()
|
|
182
|
+
await o.updateProject(e,{activePlanId:m}),d.incrementCounter("plan_write_total",1,{operation:"set-active",success:!0})
|
|
185
183
|
const s=n.localId||n.id
|
|
186
|
-
return(0,
|
|
187
|
-
const r=t(7609),n=t(4419),o=t(2352),s=t(6656),i=t(
|
|
184
|
+
return(0,a.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: "+l)}}catch(e){return p.error("plan_write failed",{error:e instanceof Error?e.stack:e+""}),d.incrementCounter("plan_write_errors",1),{content:[{type:"text",text:"\u274c **Plan Write Failed:** "+(0,i.getErrorMessage)(e)}],isError:!0}}}
|
|
185
|
+
const r=t(7609),n=t(4419),o=t(2352),s=t(6656),i=t(8824),a=t(2272)},441(e,exports){"use strict"
|
|
188
186
|
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
187
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
190
188
|
const r=t(6183),n=t(9968)
|
|
191
189
|
exports.def={name:"update_specialization",description:"Update your specialization summary (\u2264500 chars) \u2014 a description of your accumulated domain expertise. Optionally pass specializationHeadline (\u226480 chars) for a short tagline shown next to your name in compact UI surfaces. Keep both current as you work.",schema:r.UpdateSpecializationSchema,annotations:{title:"Update Specialization",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},handler(e,t){return(0,n.handleUpdateSpecialization)(e,t.logger,t.apiClient??void 0,t.cliOrigin)}}},542(e,exports,t){"use strict"
|
|
192
190
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.debugDefs=void 0
|
|
193
191
|
const r=t(1569),n=t(5997),o=t(8349),s=t(9852),i=t(9422),a=r.z.object({}),c=r.z.object({requestId:r.z.string().optional().describe("Request ID to search for")})
|
|
194
|
-
exports.debugDefs=[{name:"debug_multi_agent_status",description:"Debug tool to check multi-agent mode status, worktree state, and configuration",schema:a,annotations:{title:"Debug Multi-Agent Status",readOnlyHint:!0},debugOnly:!0,readOnly:!0,async handler(e,t){return{content:[{type:"text",text:await(0,n.handleDebugMultiAgentStatus)(e,t.context,t.logger,t.metrics)}]}}},{name:"debug_git_log",description:"Debug tool to examine git log and search for merge commits",schema:a,annotations:{title:"Debug Git Log",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,o.handleDebugGitLog)(e,t.context,t.logger,t.metrics)}},{name:"debug_git_log_request",description:"Debug tool to examine git log for a specific request",schema:c,annotations:{title:"Debug Git Log Request",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,s.handleDebugGitLogRequest)(e,t.context,t.logger,t.metrics)}},{name:"debug_request_file_history",description:"Debug tool to test git merge commit search patterns for request file history",schema:c,annotations:{title:"Debug Request File History",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,i.handleDebugRequestFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}]},
|
|
192
|
+
exports.debugDefs=[{name:"debug_multi_agent_status",description:"Debug tool to check multi-agent mode status, worktree state, and configuration",schema:a,annotations:{title:"Debug Multi-Agent Status",readOnlyHint:!0},debugOnly:!0,readOnly:!0,async handler(e,t){return{content:[{type:"text",text:await(0,n.handleDebugMultiAgentStatus)(e,t.context,t.logger,t.metrics)}]}}},{name:"debug_git_log",description:"Debug tool to examine git log and search for merge commits",schema:a,annotations:{title:"Debug Git Log",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,o.handleDebugGitLog)(e,t.context,t.logger,t.metrics)}},{name:"debug_git_log_request",description:"Debug tool to examine git log for a specific request",schema:c,annotations:{title:"Debug Git Log Request",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,s.handleDebugGitLogRequest)(e,t.context,t.logger,t.metrics)}},{name:"debug_request_file_history",description:"Debug tool to test git merge commit search patterns for request file history",schema:c,annotations:{title:"Debug Request File History",readOnlyHint:!0},debugOnly:!0,readOnly:!0,handler(e,t){return(0,i.handleDebugRequestFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}]},577(e,exports,t){"use strict"
|
|
193
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
194
|
+
const r=t(6183),n=t(5652)
|
|
195
|
+
exports.def={name:"quest_audit_complete",description:'Signal that the active quest\'s acceptance criteria are met (alchemist-only).\n\nUse this at the end of a quest tick when, after auditing the worktree and any new evidence against the quest\'s criteria, every requirement is satisfied. Calling this does NOT immediately close the quest \u2014 the server enforces a consecutive-audit gate.\n\nWhat happens per call:\n\u2022 consecutiveDoneAudits is bumped by 1.\n\u2022 If the new counter is below minIterations, the tool returns a "need more consistent audits" message. Do not spawn work to "fix" that \u2014 only spawn work if you find actual remaining criteria. Just audit again on the next tick.\n\u2022 If the counter reaches minIterations, status flips based on completionMode:\n - audit-then-pending (default): status \u2192 pending_review, your summary + evidence are stored on the quest. Ticks stop. The user reviews and either closes or reopens.\n - auto-close: status \u2192 closed. The quest is terminal.\n - never-close: the tool returns an error. Do not retry on never-close quests.\n\nWhat resets the counter:\n\u2022 A request being created with this quest\'s questDocumentId. Spawning work means criteria are not actually met yet; the streak breaks and starts over.\n\nRequired: questId, summary. Optional: evidence (array of paths, request IDs, test names, etc.).',schema:r.QuestAuditCompleteSchema,annotations:{title:"Quest Audit Complete",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleQuestAuditComplete)(e,t.context,t.apiClient,t.logger,t.metrics)}}},700(e,exports,t){"use strict"
|
|
195
196
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
196
197
|
const r=t(6183),n=t(8037)
|
|
197
198
|
exports.def={name:"list_requests",description:"List requests with filtering options (status, type, dates) and pagination. Shows detailed request information including lock status to indicate which requests are currently in use by other agents.",schema:r.ListRequestsSchema,annotations:{title:"List Requests",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleListRequests)(e,t.context,t.apiClient,t.logger,t.metrics)}}},857(module){"use strict"
|
|
@@ -251,23 +252,23 @@ if("string"==typeof t.message){const e=t.message.match(/status (\d+)/i)
|
|
|
251
252
|
if(e&&e[1]){const t=parseInt(e[1],10)
|
|
252
253
|
if(!isNaN(t))return t}}return null}}exports.ToolRecordClient=i},1020(e,exports,t){"use strict"
|
|
253
254
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQueryHistory=async function(e,c,l,d,u,h){const p=d.child({tool:"query_history"})
|
|
254
|
-
try{const a=e,{queryType:
|
|
255
|
-
let
|
|
256
|
-
switch(p.info("Processing query_history request",{queryType:
|
|
255
|
+
try{const a=e,{queryType:m}=a
|
|
256
|
+
let g
|
|
257
|
+
switch(p.info("Processing query_history request",{queryType:m}),m){case"file-history":p.info("Routing to file-history handler",{path:a.fileHistory.path}),g=await(0,r.handleFileHistory)({path:a.fileHistory.path,limit:a.fileHistory.limit,showDiff:a.fileHistory.showDiff,showTraceability:a.fileHistory.showTraceability,branch:a.fileHistory.branch,since:a.fileHistory.since},c,l,p,u)
|
|
257
258
|
break
|
|
258
|
-
case"request-file-history":p.info("Routing to request-file-history handler",{requestId:a.requestHistory.requestId}),
|
|
259
|
+
case"request-file-history":p.info("Routing to request-file-history handler",{requestId:a.requestHistory.requestId}),g=await(0,n.handleRequestFileHistory)({requestId:a.requestHistory.requestId,showDiff:a.requestHistory.showDiff,detailLevel:a.requestHistory.detailLevel,taskId:a.requestHistory.taskId,fileFilter:a.requestHistory.fileFilter},c,l,p,u)
|
|
259
260
|
break
|
|
260
261
|
case"recover":p.info("Routing to file-recover handler",{path:a.recover.path,commitHash:a.recover.commitHash})
|
|
261
262
|
let s=a.recover.commitHash
|
|
262
263
|
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
264
|
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
265
|
if(s=i[1]||i[0],!s)return{content:[{type:"text",text:"No previous versions found for "+e}],isError:!0}
|
|
265
|
-
p.info("Auto-resolved previous version",{filePath:e,commitHash:s})}catch{return{content:[{type:"text",text:"Could not find previous versions of "+e}],isError:!0}}}
|
|
266
|
+
p.info("Auto-resolved previous version",{filePath:e,commitHash:s})}catch{return{content:[{type:"text",text:"Could not find previous versions of "+e}],isError:!0}}}g=await(0,o.handleFileRecover)({taskId:e.recover?.taskId||await(async()=>{const{resolveActiveTaskId:e}=await Promise.resolve().then(t.bind(t,3451))
|
|
266
267
|
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
268
|
break
|
|
268
|
-
case"blame":p.info("Routing to file-blame handler",{path:a.blame.path,lines:a.blame.lines}),
|
|
269
|
+
case"blame":p.info("Routing to file-blame handler",{path:a.blame.path,lines:a.blame.lines}),g=await(0,i.handleFileBlame)({path:a.blame.path,lines:a.blame.lines,branch:a.blame.branch},c,l,p,u)
|
|
269
270
|
break
|
|
270
|
-
default:throw Error("Unknown query type: "+
|
|
271
|
+
default:throw Error("Unknown query type: "+m)}return p.info("query_history request completed",{queryType:m,success:!g.isError}),u.incrementCounter("query_history_total",1,{success:!g.isError,queryType:m}),(0,s.withAlchemyKind)(g,"query-history")}catch(e){return p.error("query_history request failed",{error:e instanceof Error?e.stack:e+""}),u.incrementCounter("query_history_errors",1),{content:[{type:"text",text:"\u274c **Query History Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
271
272
|
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
273
|
function t(e){let t
|
|
273
274
|
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)
|
|
@@ -376,11 +377,11 @@ return r({endpoint:"files/content",method:"GET",success:!0,encoding:"binary"}),t
|
|
|
376
377
|
r({endpoint:"files/content",method:"GET",success:!0,encoding:o}),t.json({success:!0,data:{path:e.relativePath,content:s,size:n.size,modified:n.mtime}})}catch(t){throw"ENOENT"===t.code?(r({endpoint:"files/content",method:"GET",success:!1,error:"not_found"}),(0,u.createNotFoundError)("File not found: "+e.relativePath)):t}}catch(e){r(e)}})),e.post("/api/files/write",U,W,(async(e,t,s)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/write",method:"POST"})
|
|
377
378
|
const s=B("api_request_duration"),{content:i,taskId:a,format:c="text"}=e.body
|
|
378
379
|
if(void 0===i)throw(0,u.createValidationError)("Content parameter is required")
|
|
379
|
-
const l=await(0,
|
|
380
|
+
const l=await(0,g.handleWriteFile)({taskId:a,path:e.relativePath,content:i,format:c},r.getContext(),O,$,N,A,n,o)
|
|
380
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,W,(async(e,t,s)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/replace",method:"POST"})
|
|
381
382
|
const s=B("api_request_duration"),{replacements:i,mode:a="unique",taskId:c}=e.body
|
|
382
383
|
if(!i||!Array.isArray(i))throw(0,u.createValidationError)("Replacements array is required")
|
|
383
|
-
const l=await(0,
|
|
384
|
+
const l=await(0,m.handleReplaceStrings)({taskId:c,operations:[{path:e.relativePath,replacements:i,mode:a}],comment:"String replacement via API"},r.getContext(),$,N,A,n,o)
|
|
384
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,W,(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"files/delete",method:"DELETE"})
|
|
385
386
|
const r=B("api_request_duration"),{taskId:n}=e.body
|
|
386
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,W,(async(e,t,r)=>{try{o.incrementCounter("api_requests_total",1,{endpoint:"directories/create",method:"POST"})
|
|
@@ -417,7 +418,7 @@ throw e}}catch(e){r(e)}})),e.patch("/api/proxy/*",W,(async(e,t,r)=>{try{const r=
|
|
|
417
418
|
try{const n=await z.proxyPatch(r,e.body)
|
|
418
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})
|
|
419
420
|
throw e}}catch(e){r(e)}}))}
|
|
420
|
-
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),
|
|
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),m=t(3306),g=t(4079),f=t(3895),y=s(t(5967)),w=t(4710),I=t(5681),b=t(8824),k=t(2968),v=t(6153),C=t(1887),_=t(1666),E=t(9884),S=t(922),q=t(3328)},1253(e,exports,t){"use strict"
|
|
421
422
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
422
423
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.TokenManager=void 0
|
|
423
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"
|
|
@@ -481,9 +482,9 @@ this.logger.debug("Making token validation request",{validationUrl:t})
|
|
|
481
482
|
const r=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Content-Type":"application/json"},signal:AbortSignal.timeout(1e4)})
|
|
482
483
|
if(r.ok){const e=await r.json()
|
|
483
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)}}},1281(e,exports,t){"use strict"
|
|
484
|
-
async function r(e,t,o,s,i,a,c,l,d,u=0){let
|
|
485
|
+
async function r(e,t,o,s,i,a,c,l,d,u=0){let m=0,g=0,f=0
|
|
485
486
|
const y=[]
|
|
486
|
-
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:
|
|
487
|
+
if(o.length>=v||c>10)return a.debug("Stopping search in directory - hard cap or depth limit reached",{dir:e,matchesCount:o.length,hardCap:v,depth:c}),{filesCount:m,fileMatchesCount:g,subdirCount:f,subdirStats:y}
|
|
487
488
|
try{const w=await p.default.readdir(e,{withFileTypes:!0}),I=[],C=[]
|
|
488
489
|
for(const t of w){const r=h.default.join(e,t.name)
|
|
489
490
|
if(t.isDirectory()){if(k.includes(t.name)||t.name.startsWith(".")){a.debug("Skipping excluded directory: "+t.name)
|
|
@@ -492,15 +493,15 @@ continue}I.push({entry:t,fullPath:r})}}if(I.length>0){const e=[]
|
|
|
492
493
|
for(let t=0;t<I.length;t+=16)e.push(I.slice(t,t+16))
|
|
493
494
|
for(const r of e){if(o.length>=v)break
|
|
494
495
|
const e=await Promise.all(r.map((({entry:e,fullPath:r})=>n(r,t,0,o,l,d,e.name,u))))
|
|
495
|
-
for(const t of e){
|
|
496
|
-
for(const e of t.matches){if(o.length>=v)return{filesCount:
|
|
496
|
+
for(const t of e){m++,t.hasMatches&&g++
|
|
497
|
+
for(const e of t.matches){if(o.length>=v)return{filesCount:m,fileMatchesCount:g,subdirCount:f,subdirStats:y}
|
|
497
498
|
o.push(e)}}}}for(const{entry:e,fullPath:n}of C){if(o.length>=v)break
|
|
498
499
|
f++
|
|
499
500
|
const e={path:n,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
500
501
|
try{const l=await r(n,t,o,s,i,a,c+1,e,d,u)
|
|
501
|
-
|
|
502
|
+
m+=l.filesCount,g+=l.fileMatchesCount,e.filesProcessed=l.filesCount,e.filesMatched=l.fileMatchesCount,e.subdirectories=l.subdirCount,y.push(e),l.subdirStats&&l.subdirStats.length>0&&y.push(...l.subdirStats)}catch(t){const r=`Error processing subdirectory ${n}: ${(0,b.getErrorMessage)(t)}`
|
|
502
503
|
e.errors.push(r),y.push(e),a.error(r)}}}catch(t){const r=`Error searching directory ${e}: ${(0,b.getErrorMessage)(t)}`
|
|
503
|
-
l.errors.push(r),a.warn(r)}return{filesCount:
|
|
504
|
+
l.errors.push(r),a.warn(r)}return{filesCount:m,fileMatchesCount:g,subdirCount:f,subdirStats:y}}async function n(e,t,r,n,o,s,i,a=0){const c=[]
|
|
504
505
|
let l,d=!1
|
|
505
506
|
const u=async()=>{if(void 0===l)try{const t=await p.default.stat(e)
|
|
506
507
|
l=t.mtime.getTime()}catch(e){l=void 0}return l}
|
|
@@ -533,31 +534,31 @@ if(null!=e)for(var r=a(e),n=0;n<r.length;n++)"default"!==r[n]&&c(t,e,r[n])
|
|
|
533
534
|
return l(t,e),t}),u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
534
535
|
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()
|
|
535
536
|
let k=0
|
|
536
|
-
const v={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:
|
|
537
|
-
try{const{needle:n,directory:
|
|
538
|
-
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,I.handleListDirectory)({path:
|
|
539
|
-
if("string"!=typeof n)throw v.errors.push("Search term (needle) must be a string"),(0,
|
|
537
|
+
const v={searchDirectory:"",resolvedPath:"",patternInfo:{needle:"",regex:"",caseSensitive:!1,fileExtension:"",normalizedExtension:""},environmentInfo:{platform:process.platform,nodeVersion:process.version,hostname:m.default.hostname(),username:m.default.userInfo().username,workingDirectory:process.cwd(),contextBasePath:t?.basePath||"unknown"},startTime:u,endTime:0,phases:{initializationTime:0,searchTime:0,directoryListingTime:0},totalFiles:0,totalMatches:0,directoryStats:[],errors:[]}
|
|
538
|
+
try{const{needle:n,directory:m,options:C={}}=e
|
|
539
|
+
if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,I.handleListDirectory)({path:m||".",levels:C.levels||1,sortBy:C.sortBy||"name"},t,a,c)
|
|
540
|
+
if("string"!=typeof n)throw v.errors.push("Search term (needle) must be a string"),(0,g.createValidationError)("Search term (needle) must be a string")
|
|
540
541
|
let _
|
|
541
|
-
if(v.searchDirectory=
|
|
542
|
+
if(v.searchDirectory=m||".",m){const{normalizedPath:e,fullPath:r}=f.validateAndNormalizePath(m,t)
|
|
542
543
|
_=r}else _=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath
|
|
543
544
|
v.resolvedPath=_
|
|
544
545
|
let E=!1
|
|
545
546
|
try{E=(await p.default.stat(_)).isFile()}catch(e){const t=`Cannot access path ${_}: ${(0,b.getErrorMessage)(e)}`
|
|
546
547
|
throw v.errors.push(t),Error(t)}const S=C.maxResults||50,q=C.caseSensitive||!1,T=C.useRegex||!1,P=C.fileExtension,x=C.searchIn||"content"
|
|
547
548
|
let j=void 0!==C.contextLines?C.contextLines:0
|
|
548
|
-
if(0>j?j=0:j>10&&(l.warn(`contextLines ${j} exceeds maximum of 10, clamping to 10`),j=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,
|
|
549
|
+
if(0>j?j=0:j>10&&(l.warn(`contextLines ${j} exceeds maximum of 10, clamping to 10`),j=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,g.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
|
|
549
550
|
let R,M=""
|
|
550
551
|
if(E)M="*"
|
|
551
552
|
else if("*"===P)M="*"
|
|
552
553
|
else if(P){let e=P;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),M=e.startsWith(".")?e:"."+e}try{R=T?q?RegExp(n):RegExp(n,"i"):q?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${T?"regex":"search"} pattern: ${(0,b.getErrorMessage)(e)}`
|
|
553
|
-
throw v.errors.push(t),(0,
|
|
554
|
+
throw v.errors.push(t),(0,g.createValidationError)(t)}if(v.patternInfo={needle:n,regex:R.toString(),caseSensitive:q,fileExtension:P,normalizedExtension:M},!E)try{const e=Date.now(),t=await p.default.readdir(_,{withFileTypes:!0}),r=[],n=[]
|
|
554
555
|
for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
|
|
555
556
|
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,b.getErrorMessage)(e)
|
|
556
557
|
v.errors.push(t),l.error(t)}const $=E?"file":"directory"
|
|
557
558
|
l.info(`Searching for "${n}" in ${$} ${_} (mode: ${x})`,{needle:n,searchTarget:$,path:_,options:{maxResults:S,caseSensitive:q,fileExtension:M,searchIn:x}}),k=Date.now(),v.phases.initializationTime=k-u
|
|
558
559
|
const O=Date.now()
|
|
559
560
|
let D=[],A=0,F=0
|
|
560
|
-
try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,
|
|
561
|
+
try{const e=await async function(e,t,n,o,s,i){const{maxResults:a,fileExtension:c,searchIn:l,isFile:d,contextLines:u}=n,m=[]
|
|
561
562
|
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)
|
|
562
563
|
let c
|
|
563
564
|
n.info("Searching single file: "+e,{searchIn:r})
|
|
@@ -569,10 +570,10 @@ t.contextBefore=r.slice(e,n).map((e=>(0,y.truncate)(e.trim(),120)))
|
|
|
569
570
|
const o=Math.min(r.length,n+1+s)
|
|
570
571
|
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,b.getErrorMessage)(t)}`
|
|
571
572
|
o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
|
|
572
|
-
const
|
|
573
|
-
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,
|
|
574
|
-
return
|
|
575
|
-
return
|
|
573
|
+
const g={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
|
|
574
|
+
try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,m,a,o,s,0,g,l,u)
|
|
575
|
+
return g.filesProcessed=n,g.filesMatched=c,g.subdirectories=d,i.directoryStats.push(g),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:m.length,directories:d+1}),{matches:m,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,b.getErrorMessage)(t)
|
|
576
|
+
return g.errors.push(r),i.directoryStats.push(g),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:m,totalFiles:g.filesProcessed}}}(_,R,{maxResults:S,fileExtension:M,searchIn:x,isFile:E,contextLines:j},M,l,v)
|
|
576
577
|
D=e.matches,A=e.totalFiles
|
|
577
578
|
const t=1e3
|
|
578
579
|
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)
|
|
@@ -582,7 +583,7 @@ let N,z=""
|
|
|
582
583
|
try{if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
583
584
|
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})
|
|
584
585
|
const L="content"===x?"content":"filename"===x?"filenames":"content and filenames"
|
|
585
|
-
if(F>D.length?(N=`Found ${F} results for "${n}" (searching ${L})`,
|
|
586
|
+
if(F>D.length?(N=`Found ${F} results for "${n}" (searching ${L})`,m&&(N+=" in "+m),P&&(N+=" with extension "+P),N+=`${z}. Showing first ${D.length}:\n\n`):(N=`Found ${D.length} results for "${n}" (searching ${L})`,m&&(N+=" in "+m),P&&(N+=" with extension "+P),N+=z+":\n\n"),D.length>0)if(j>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
|
|
586
587
|
if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
|
|
587
588
|
const o=new Map
|
|
588
589
|
for(const e of n){const t=o.get(e.file)||[]
|
|
@@ -606,7 +607,7 @@ else N+="No matches found."
|
|
|
606
607
|
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,b.getErrorMessage)(t)),v.endTime=Date.now(),l.debug("Search diagnostic information on error",{diagnostic:v})
|
|
607
608
|
let r="Search failed: "+(0,b.getErrorMessage)(t)
|
|
608
609
|
return d({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:r}],isError:!0}}}
|
|
609
|
-
const h=u(t(6928)),p=u(t(1943)),
|
|
610
|
+
const h=u(t(6928)),p=u(t(1943)),m=u(t(857)),g=t(9860),f=d(t(5967)),y=t(5967),w=t(2272),I=t(2537),b=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"
|
|
610
611
|
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)
|
|
611
612
|
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}`])
|
|
612
613
|
if(!a||""===a.trim())return null
|
|
@@ -624,12 +625,12 @@ for(const e of r){const r=e.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/)
|
|
|
624
625
|
if(r){const e=parseInt(r[3],10),n=r[4]?parseInt(r[4],10):1,o=e+n-1
|
|
625
626
|
n>0&&t.push({start:e,end:o})}}return t}(s)
|
|
626
627
|
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})
|
|
627
|
-
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),p=!!h&&n(h),
|
|
628
|
+
return s.latest?.message||null}catch(e){return null}}(e,t.path,i),p=!!h&&n(h),m=t.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),g=d.map((e=>`${e.start}-${e.end}`)).join(", ")||"none",f=u?u.substring(0,300):"no diff"
|
|
628
629
|
if(0===d.length){const r=[]
|
|
629
630
|
for(const s of t.lineRanges){const a=await o(e,t.path,s.start,s.end,i)
|
|
630
|
-
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 ${
|
|
631
|
-
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:
|
|
632
|
-
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:
|
|
631
|
+
a&&(n(a.message)||r.push({range:`${s.start}-${s.end}`,commit:a}))}if(r.length>0){const e=r.map((e=>`Lines ${e.range}: ${e.commit.hash.substring(0,8)} - ${e.commit.message}`)).join("; "),n=[`\u26a0\ufe0f Warning: Lines ${m} were last modified by external commits (not alchemy).`,"","Commit details: "+e,"\nThese changes may have been made manually or by another tool.\nReview recent commits before proceeding."].join("\n")
|
|
632
|
+
return{hasExternalEdits:!0,conflictingLines:t.lineRanges.flatMap((e=>Array.from({length:e.end-e.start+1},((t,r)=>e.start+r)))),message:n,debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:"none",lastCommit:r[0].commit.message,wasLastCommitAlchemy:!1,diffPreview:e,overlapDetected:!0}}}return{hasExternalEdits:!1,conflictingLines:[],debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:"none",lastCommit:h,wasLastCommitAlchemy:p,diffPreview:"no uncommitted changes, last commits from alchemy",overlapDetected:!1}}}const y={path:t.path,lineRanges:d,totalLines:d.reduce(((e,t)=>e+(t.end-t.start+1)),0),operationType:"modification"},w=(0,a.getOverlappingLines)(t,y)
|
|
633
|
+
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:g,lastCommit:h,wasLastCommitAlchemy:p,diffPreview:f,overlapDetected:!1}}:{hasExternalEdits:!0,conflictingLines:w,message:["\u26a0\ufe0f Warning: File has uncommitted changes in lines you're about to modify.\n","Affected lines: "+m,"Conflicting lines: "+s(w),"",p?"Last commit was by alchemy, but file has been edited since.":"Last commit was NOT from alchemy - these may be manual edits.","\nReview the changes before proceeding."].join("\n"),details:{totalExternalChanges:y.totalLines,overlappingChanges:w.length,changedLineRanges:d},debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:g,lastCommit:h,wasLastCommitAlchemy:p,diffPreview:f,overlapDetected:!0}}}catch(e){return i.error("Failed to detect external edits",{path:t.path,error:(0,l.getErrorMessage)(e)}),{hasExternalEdits:!1,conflictingLines:[],message:"Unable to check for external edits (Git error). Proceeding with caution."}}},exports.hasUncommittedChanges=async function(e,t){try{return(await e.status([t])).files.some((e=>e.path===t))}catch(e){return!1}}
|
|
633
634
|
const a=t(9947),c=i(t(6928)),l=t(8824)},1375(e,exports,t){"use strict"
|
|
634
635
|
async function r(e,t){const{progressToken:r,sendNotification:n}=e,o=e.intervalMs??1e4
|
|
635
636
|
if(null==r||!n)return t()
|
|
@@ -699,17 +700,17 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
699
700
|
var t={}
|
|
700
701
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
701
702
|
return i(t,e),t})
|
|
702
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentity=void 0,exports.registerTools=function(e,o,s,i,a,
|
|
703
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.logSessionIdentity=void 0,exports.registerTools=function(e,o,s,i,a,m,b){const k=i.child({component:"tools"})
|
|
703
704
|
k.info("Registering tools...")
|
|
704
705
|
let v=!1
|
|
705
|
-
const C=!!
|
|
706
|
-
try{return await
|
|
706
|
+
const C=!!m,_=async()=>{if(!C)return!0
|
|
707
|
+
try{return await m.hasValidToken()}catch(e){return k.error("Error checking authentication status",{error:(0,d.getErrorMessage)(e)}),!1}},E=async()=>{const e=(0,l.areTestsRequiredForCompletion)(),t=await _()
|
|
707
708
|
k.info(`Generating tools list with testsRequired=${e}, authenticated=${t}`)
|
|
708
709
|
const r={testsRequired:e,authenticated:t}
|
|
709
710
|
return(0,f.generateVisibleToolsList)(r)}
|
|
710
711
|
let S=E(),q=[]
|
|
711
712
|
S.then((e=>{q=e})).catch((e=>{k.error("Error generating initial tools list",{error:(0,d.getErrorMessage)(e)}),q=[]})),e.setRequestHandler(c.ListToolsRequestSchema,(async()=>{try{return q=await E(),{tools:q}}catch(e){return k.error("Error generating tools list",{error:(0,d.getErrorMessage)(e)}),{tools:[]}}})),e.setRequestHandler(c.CallToolRequestSchema,(async(e,c)=>{let l
|
|
712
|
-
try{const{name:n,arguments:I={},_meta:S}=e.params;(0,
|
|
713
|
+
try{const{name:n,arguments:I={},_meta:S}=e.params;(0,g.logSessionIdentity)(n,"_meta-debug",{has_meta:!!S,sessionId:S?.sessionId||null,messageId:S?.messageId||null,paramKeys:Object.keys(e.params)}),k.info("Tool call received: "+n,{tool:n}),a.incrementCounter("tool_calls_total",1,{tool:n})
|
|
713
714
|
const q=a.startTimer("tool_execution_time")
|
|
714
715
|
Date.now()
|
|
715
716
|
let T=Date.now()
|
|
@@ -717,9 +718,9 @@ if(l=r(I),Date.now(),T=Date.now(),C){const e=await _()
|
|
|
717
718
|
if(Date.now(),!e)return k.warn("Unauthenticated tool call attempt",{tool:n}),{content:[{type:"text",text:"Authentication required. Please run 'alchemylab setup' to authenticate and configure your project."}],isError:!0}}const P=(0,f.getToolByName)(n)
|
|
718
719
|
let x
|
|
719
720
|
if(T=Date.now(),s?(s.setOptions({createRecords:P?.createsRecords??!1}),k.info(`Setting record creation for tool ${n}: ${P?.createsRecords??!1}`)):k.debug(`No API client available for tool ${n} (minimal mode)`),Date.now(),Date.now(),T=Date.now(),S?.sessionId){const e=S.sessionId,t=S.messageId,r=h.sessionIdentity.getIdentity()
|
|
720
|
-
if(r)r.sessionId!==e&&((0,
|
|
721
|
+
if(r)r.sessionId!==e&&((0,g.logSessionIdentity)(n,"_meta-session-switch",{prevSessionId:r.sessionId,prevAgentType:r.agentType,newSessionId:e}),h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r.serverUrl}),o?.workspaceManager?.resetCurrentContext?.(e))
|
|
721
722
|
else{const t=await(0,u.getServerUrl)(o,k)
|
|
722
|
-
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}x={providerId:"opencode",sessionId:e,messageId:t,createdAt:(new Date).toISOString()},(0,
|
|
723
|
+
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}x={providerId:"opencode",sessionId:e,messageId:t,createdAt:(new Date).toISOString()},(0,g.logSessionIdentity)(n,"_meta",{sessionId:e,messageId:t})}else if(m=n,E=S,v||(v=!0,k.warn("No _meta.sessionId on tool call \u2014 caller not on alchemylab-opencode fork.",{tool:m,metaKeys:E?Object.keys(E):null})),!1!==P?.requiresSession)throw(0,p.createMcpProtocolError)(`_meta.sessionId required for tool '${n}'`,{tool:n})
|
|
723
724
|
h.sessionIdentity.setCurrentCallOrigin(x)
|
|
724
725
|
const j=x?.sessionId||S?.sessionId
|
|
725
726
|
if(o?.workspaceManager){T=Date.now()
|
|
@@ -732,24 +733,24 @@ try{if(P){(0,y.preNormalize)(n,l),await(0,w.expandTaskRefsInArgs)(l,s,x?.session
|
|
|
732
733
|
const t=e.params?._meta?.progressToken,r=c?.sendNotification,o={context:R,apiClient:s,logger:i,metrics:a,mcpServer:b,cliOrigin:x,progressToken:t,sendNotification:r}
|
|
733
734
|
O=await P.handler(l,o)}else k.info(`Tool ${n} not found, returning negative response`),O={content:[{type:"text",text:`The tool '${n}' does not exist.`}]}}finally{$("end")}return Date.now(),Date.now(),q({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"})
|
|
734
735
|
let r="Unknown error"
|
|
735
|
-
return r=t instanceof I.ZodError?function(e,t){return 1===e.issues.length?n(e.issues[0],t):e.issues.map((e=>n(e,t))).join("; ")}(t,l):(0,d.getStructuredErrorMessage)(t),{content:[{type:"text",text:"Error: "+r}],isError:!0}}var
|
|
736
|
+
return r=t instanceof I.ZodError?function(e,t){return 1===e.issues.length?n(e.issues[0],t):e.issues.map((e=>n(e,t))).join("; ")}(t,l):(0,d.getStructuredErrorMessage)(t),{content:[{type:"text",text:"Error: "+r}],isError:!0}}var m,E})),k.info("Tools registration complete")}
|
|
736
737
|
const c=t(9150),l=t(2478),d=t(8824),u=t(7617),h=t(6688),p=t(9860)
|
|
737
738
|
a(t(9896)),a(t(6928))
|
|
738
|
-
var
|
|
739
|
-
Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return
|
|
740
|
-
const
|
|
739
|
+
var m=t(7280)
|
|
740
|
+
Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return m.logSessionIdentity}})
|
|
741
|
+
const g=t(7280)
|
|
741
742
|
t(2462)
|
|
742
743
|
const f=t(2245),y=t(8622),w=t(4466),I=(a(t(857)),t(1569))},1483(e,exports,t){"use strict"
|
|
743
744
|
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")
|
|
744
745
|
try{const o=e,{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,dateFrom:u,dateTo:h,searchIn:p}=o
|
|
745
746
|
i.info("Searching documents",{query:s,type:a,requestId:c,includeArchived:l,maxResults:d,searchIn:p})
|
|
746
|
-
const
|
|
747
|
-
if(!
|
|
748
|
-
return i.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}n.setProjectId(
|
|
749
|
-
const
|
|
747
|
+
const m=t.projectId
|
|
748
|
+
if(!m){const e="Project ID is required. Make sure you are in a project context."
|
|
749
|
+
return i.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}n.setProjectId(m)
|
|
750
|
+
const g=n.getDocumentClient()
|
|
750
751
|
try{const e={limit:d||100,offset:0,sortBy:"updatedAt",sortDirection:"desc",searchQuery:s,includeArchived:l||!1}
|
|
751
752
|
a&&(e.type=a),c&&(e.requestId=c),i.debug("Fetching documents with filters",{filters:e})
|
|
752
|
-
let t=await
|
|
753
|
+
let t=await g.listDocuments(e)
|
|
753
754
|
if(u){const e=new Date(u)
|
|
754
755
|
t=t.filter((t=>new Date(t.createdAt)>=e))}if(h){const e=new Date(h)
|
|
755
756
|
t=t.filter((t=>new Date(t.createdAt)<=e))}i.info(`Fetched and filtered ${t.length} documents for search`)
|
|
@@ -1042,7 +1043,27 @@ const n=this.isOffline()
|
|
|
1042
1043
|
return t?(this.consecutiveFailures=0,this.currentBackoffMs=0,n&&this.setOfflineMode(!1)):(this.consecutiveFailures++,this.currentBackoffMs=Math.min(this.options.checkIntervalMs*Math.pow(2,this.consecutiveFailures-1),3e5),n||this.consecutiveFailures<this.options.retryCount||this.setOfflineMode(!0)),this.logger.debug("Health check complete",{isOnline:t,latency:r,consecutiveFailures:this.consecutiveFailures,currentBackoffMs:this.currentBackoffMs,statusChanged:n!==this.isOffline()}),this.lastCheckTime=Date.now(),t}catch(t){return this.logger.error("Health check failed with error",{error:(0,r.getErrorMessage)(t),elapsed:Date.now()-e}),this.metrics.incrementCounter("health_check_error",1),this.failureCount++,this.lastFailureTime=Date.now(),this.metrics.setGauge("health_check_failure_count",this.failureCount),this.metrics.setGauge("health_check_last_failure",this.lastFailureTime),this.consecutiveFailures++,this.currentBackoffMs=Math.min(this.options.checkIntervalMs*Math.pow(2,this.consecutiveFailures-1),3e5),this.isOffline()||this.consecutiveFailures<this.options.retryCount||this.setOfflineMode(!0),this.lastCheckTime=Date.now(),!1}}startHealthChecks(){this.checkInterval&&clearInterval(this.checkInterval),this.performHealthCheck().catch((()=>{})),this.checkInterval=setInterval((()=>{this.performHealthCheck().catch((()=>{}))}),this.options.checkIntervalMs),this.logger.info("Health check monitoring started",{checkIntervalMs:this.options.checkIntervalMs})}async checkConnectivity(){return await this.performHealthCheck()}stopHealthChecks(){this.checkInterval&&(clearInterval(this.checkInterval),this.checkInterval=null,this.logger.info("Health check monitoring stopped"))}async requestHealthCheck(){if(this.forcedOfflineMode)return this.logger.debug("Health check skipped - offline mode is forced"),!1
|
|
1043
1044
|
const e=this.online,t=await this.performHealthCheck()
|
|
1044
1045
|
return e!==t&&(t?(this.logger.info("Health check status changed to ONLINE"),this.options.onOnlineCallback()):(this.logger.info("Health check status changed to OFFLINE"),this.options.onOfflineCallback())),t}isOffline(){return this.forcedOfflineMode||!1}scheduleNextCheck(e=this.options.checkIntervalMs){this.checkInterval&&(clearInterval(this.checkInterval),this.checkInterval=null),0!==e?setTimeout((()=>{this.performHealthCheck().catch((()=>{}))}),e||this.options.checkIntervalMs||3e4):this.performHealthCheck().catch((()=>{}))}setOfflineMode(e){const t=this.forcedOfflineMode
|
|
1045
|
-
this.forcedOfflineMode=e,t!==e&&(this.logger.info("Offline mode "+(e?"ENABLED":"DISABLED")),this.metrics.setGauge("health_check_forced_offline",e?1:0),e||this.scheduleNextCheck(0))}getStats(){return{consecutiveFailures:this.consecutiveFailures,currentBackoffMs:this.currentBackoffMs,lastCheckTime:this.lastCheckTime}}}},
|
|
1046
|
+
this.forcedOfflineMode=e,t!==e&&(this.logger.info("Offline mode "+(e?"ENABLED":"DISABLED")),this.metrics.setGauge("health_check_forced_offline",e?1:0),e||this.scheduleNextCheck(0))}getStats(){return{consecutiveFailures:this.consecutiveFailures,currentBackoffMs:this.currentBackoffMs,lastCheckTime:this.lastCheckTime}}}},1719(e,exports,t){"use strict"
|
|
1047
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuestSetCriteriaStatuses=async function(e,t,o,s,i){const a=s.child({tool:"quest_set_criteria_statuses"})
|
|
1048
|
+
try{if(!t.projectId)return{content:[{type:"text",text:"\u274c No project context available."}],isError:!0}
|
|
1049
|
+
const r=o.getDocumentClient(),s=await r.getDocument(e.questId)
|
|
1050
|
+
if(!s)return{content:[{type:"text",text:"\u274c Quest not found: "+e.questId}],isError:!0}
|
|
1051
|
+
if("Quest"!==s.type)return{content:[{type:"text",text:`\u274c Document ${e.questId} is not a quest (type: ${s.type}).`}],isError:!0}
|
|
1052
|
+
const c=s.metadata||{},l=c.status||n.QUEST_STATUS_OPEN
|
|
1053
|
+
if(l!==n.QUEST_STATUS_OPEN)return{content:[{type:"text",text:`\u274c Quest status is "${l}", not "open". Criterion updates are only valid while the quest is open.`}],isError:!0}
|
|
1054
|
+
const d=Array.isArray(c.criteria)?c.criteria:[]
|
|
1055
|
+
if(0===d.length)return{content:[{type:"text",text:"\u274c Quest has no structured criteria checklist. Set metadata.criteria via plan_write update before calling this tool."}],isError:!0}
|
|
1056
|
+
const u=new Map(d.map((e=>[e.id,e]))),h=e.updates.map((e=>e.id)).filter((e=>!u.has(e)))
|
|
1057
|
+
if(h.length>0){const e=d.map((e=>`"${e.id}"`)).join(", ")
|
|
1058
|
+
return{content:[{type:"text",text:`\u274c Unknown criterion id(s): ${h.map((e=>`"${e}"`)).join(", ")}. Valid ids on this quest: ${e}.`}],isError:!0}}const p=new Map(e.updates.map((e=>[e.id,e]))),m=d.map((e=>{const t=p.get(e.id)
|
|
1059
|
+
if(!t)return e
|
|
1060
|
+
const r={...e,status:t.status}
|
|
1061
|
+
return void 0!==t.evidence&&(r.evidence=t.evidence),r})),g={...c,criteria:m}
|
|
1062
|
+
await r.updateDocument(e.questId,{metadata:g}),i.incrementCounter("quest_set_criteria_statuses_total",1,{updatedCount:e.updates.length+""})
|
|
1063
|
+
const f=s.localId||s.id,y=m.filter((e=>"verified"===e.status)).length,w=e.updates.map((e=>{const t=u.get(e.id)
|
|
1064
|
+
return`- ${e.id}: ${e.status}${e.evidence?` (evidence: ${e.evidence})`:""}${t?.description?" \u2014 "+t.description:""}`}))
|
|
1065
|
+
return a.info("quest_set_criteria_statuses processed",{questId:f,updatedCount:e.updates.length,verifiedAfter:y,totalCriteria:m.length}),{content:[{type:"text",text:`\u2705 **Criteria updated (${y}/${m.length} verified)**\n\nQuest **${f}**:\n`+w.join("\n")+(y===m.length?"\n\nAll criteria are now verified. Call quest_audit_complete when ready to flip the quest status.":"")}]}}catch(e){return a.error("quest_set_criteria_statuses failed",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **quest_set_criteria_statuses failed:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
1066
|
+
const r=t(8824),n=t(3416)},1725(e,exports,t){"use strict"
|
|
1046
1067
|
function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,v.join)(e.basePath||process.cwd(),".alchemy_lab","spawn-debug.log");(0,k.appendFileSync)(o,n)}catch{}}function n(e,t){return t?`Instruction code: ${t}. When you report back or ask a question via session_message_operations send, include relatesTo: "${t}" so the parent can trace this work.\n\n${e}`:e}async function o(e){const{apiClient:t,fromSessionId:r,toSessionId:n,body:o,requestId:s,logger:i}=e
|
|
1047
1068
|
if(!t||!r)return
|
|
1048
1069
|
const a=t.getSessionMessageClient()
|
|
@@ -1063,10 +1084,10 @@ const n=await r.json()
|
|
|
1063
1084
|
return n.success?n.data??null:null}catch{return null}}(c)
|
|
1064
1085
|
if(p=e?.requestContextMode,!p){const e=(0,C.getBuiltInAgentConfig)(c)
|
|
1065
1086
|
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}
|
|
1066
|
-
const
|
|
1067
|
-
r(t,"serverUrl resolved",{serverUrl:
|
|
1087
|
+
const m=await(0,y.getServerUrl)(t,s)
|
|
1088
|
+
r(t,"serverUrl resolved",{serverUrl:m})
|
|
1068
1089
|
const k=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath
|
|
1069
|
-
if(!k)throw new
|
|
1090
|
+
if(!k)throw new g.ValidationError("Working directory not available in context")
|
|
1070
1091
|
const v=a?.sessionId
|
|
1071
1092
|
let E=""
|
|
1072
1093
|
if(i&&d)try{const e=i.getSessionRequestAssociationClient()
|
|
@@ -1076,21 +1097,21 @@ if(!u)return s.warn("Blocked spawn: request already has active workers",{request
|
|
|
1076
1097
|
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,b.getErrorMessage)(e)})}let q,T,P=l
|
|
1077
1098
|
d&&(q="requests/"+d,r(t,"Setting initialBranch for agent",{agent:c,requestId:d,initialBranch:q,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}`)
|
|
1078
1099
|
let x,j=!1
|
|
1079
|
-
if(h){if(T=h,s.info("Using existing session for spawn",{sessionId:T,requestId:d}),!
|
|
1100
|
+
if(h){if(T=h,s.info("Using existing session for spawn",{sessionId:T,requestId:d}),!m)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1080
1101
|
try{let e
|
|
1081
1102
|
try{const t=await fetch(`http://localhost:${S}/api/project-settings`)
|
|
1082
1103
|
if(t.ok){const r=await t.json()
|
|
1083
1104
|
if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
|
|
1084
1105
|
e={providerID:t,modelID:n.join("/")}}}}catch{}x=await o({apiClient:i,fromSessionId:a?.sessionId,toSessionId:T,body:P,requestId:d,logger:s})
|
|
1085
|
-
const t=n(P,x),r=`${
|
|
1106
|
+
const t=n(P,x),r=`${m.replace(/\/$/,"")}/session/${T}/prompt_async`,l={alchemy:{kind:"agent-delegation",payload:{body:P,fromSessionId:a?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...d?{requestId:d}:{},...x?{instructionCode:x}:{}}}},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)})
|
|
1086
1107
|
if(!u.ok){const e=await u.text().catch((()=>"Unknown error"))
|
|
1087
1108
|
throw Error(`Failed to send to existing session: ${u.status} ${e}`)}s.info("Prompt sent to existing session",{sessionId:T,agent:c})}catch(e){throw Error("Failed to use existing session: "+(0,b.getErrorMessage)(e))}}else{j=!0,r(t,"Creating session via spawn-session endpoint")
|
|
1088
1109
|
const h=v;(0,I.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:h})
|
|
1089
|
-
try{const p=`http://localhost:${S}/api/spawn-session`,
|
|
1090
|
-
if(!
|
|
1091
|
-
throw Error(`Spawn session endpoint failed: ${
|
|
1092
|
-
if(!
|
|
1093
|
-
const{sessionId:y,model:I,serverUrl:b,initialBranch:v}=
|
|
1110
|
+
try{const p=`http://localhost:${S}/api/spawn-session`,m=await fetch(p,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent:c,prompt:l,requestId:d,parentSessionId:h,title:e.title,specialization:e.specialization,specializationHeadline:e.specializationHeadline,allowParallel:u,callerAgentType:w.sessionIdentity.getIdentity()?.agentType}),signal:AbortSignal.timeout(15e3)})
|
|
1111
|
+
if(!m.ok){const e=await m.text().catch((()=>"Unknown error"))
|
|
1112
|
+
throw Error(`Spawn session endpoint failed: ${m.status} ${e}`)}const g=await m.json()
|
|
1113
|
+
if(!g.success||!g.data)throw Error(g.error||"Spawn session returned unsuccessful")
|
|
1114
|
+
const{sessionId:y,model:I,serverUrl:b,initialBranch:v}=g.data
|
|
1094
1115
|
q=v,x=await o({apiClient:i,fromSessionId:a?.sessionId,toSessionId:y,body:P,requestId:d,logger:s})
|
|
1095
1116
|
const C=n(P,x),_=(0,f.spawnDetachedSubagent)({agent:c,prompt:C,cwd:k,sessionId:y,model:I,initialBranch:q,allowParallel:u,serverUrl:b})
|
|
1096
1117
|
if(!_.success)throw Error("Failed to spawn subagent: "+_.error)
|
|
@@ -1106,21 +1127,21 @@ o.warn("PATCH initial delegation failed",{sessionId:r,status:l.status,body:d.sli
|
|
|
1106
1127
|
R+=h?`Prompt sent to existing session ${T}.`:`Background ${c} subagent spawned successfully.`,d&&(R+="\nWorking on: "+d),x&&(R+=`\nInstruction code: ${x} (the specialist will cite this on their reports/questions via relatesTo)`),R+="\n\nThe subagent is now working independently. You can continue with other tasks.","coder"===c&&(R+="\n\nIf this work has shifted or expanded your area of expertise, update your specialization summary with `update_specialization`.")
|
|
1107
1128
|
const M=!!T&&"unknown"!==T&&"spawning"!==T
|
|
1108
1129
|
return{content:[{type:"text",text:R}],...(0,_.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:M?T:void 0,agentType:c,requestId:d||void 0,description:e.title||l.slice(0,50)||c,...x?{instructionCode:x}:{}}),...x?{instructionCode:x}:{}}}async function i(e,t,r,s,i,a,c){const l=await(0,y.getServerUrl)(r,s)
|
|
1109
|
-
if(!l)throw new
|
|
1130
|
+
if(!l)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1110
1131
|
if(s.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),i)try{const t=c?.sessionId
|
|
1111
1132
|
if(t){const r=i.getCLISessionClient()
|
|
1112
1133
|
if(r){let n=await r.getByExternalId(t)
|
|
1113
1134
|
n||(n=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),s.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:n?.id})),n&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:n.id,status:"active"}),s.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){s.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,b.getErrorMessage)(e)})}let d=a
|
|
1114
1135
|
if(!d)try{const t=`http://localhost:${S}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
|
|
1115
1136
|
if(r.ok){const e=await r.json()
|
|
1116
|
-
e.success&&e.agentType&&(d=e.agentType)}}catch{s.warn("Agent type lookup failed for session",{sessionId:e})}if(!d)throw new
|
|
1137
|
+
e.success&&e.agentType&&(d=e.agentType)}}catch{s.warn("Agent type lookup failed for session",{sessionId:e})}if(!d)throw new g.ValidationError(`Cannot continue session ${e}: unable to determine agent type. The session's agent type could not be looked up from the action server.`)
|
|
1117
1138
|
try{let r
|
|
1118
1139
|
try{const e=await fetch(`http://localhost:${S}/api/project-settings`)
|
|
1119
1140
|
if(e.ok){const t=await e.json()
|
|
1120
1141
|
if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
|
|
1121
|
-
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}:{}}}},
|
|
1122
|
-
if(!
|
|
1123
|
-
throw Error(`Failed to send message: ${
|
|
1142
|
+
r={providerID:e,modelID:n.join("/")}}}}catch{}const a=await o({apiClient:i,fromSessionId:c?.sessionId,toSessionId:e,body:t,logger:s}),u=n(t,a),h=`${l.replace(/\/$/,"")}/session/${e}/prompt_async`,p={alchemy:{kind:"agent-followup",payload:{body:t,fromSessionId:c?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...a?{instructionCode:a}:{}}}},m=await fetch(h,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:u,metadata:p}],...d?{agent:d}:{},...r?{model:r}:{}}),signal:AbortSignal.timeout(1e4)})
|
|
1143
|
+
if(!m.ok){const e=await m.text().catch((()=>"Unknown error"))
|
|
1144
|
+
throw Error(`Failed to send message: ${m.status} ${e}`)}return s.info("Message sent to subagent session",{sessionId:e,agent:d,instructionCode:a}),{content:[{type:"text",text:a?`Message sent to session ${e} (${a}).\nThe subagent will process it in the background.`:`Message sent to session ${e}.\nThe subagent will process it in the background.`}],...a?{_meta:{alchemy:{kind:"continue-subagent",instructionCode:a}},instructionCode:a}:{}}}catch(e){throw Error("Failed to continue session: "+(0,b.getErrorMessage)(e))}}function a(e){const t=Math.floor(e/1e3)
|
|
1124
1145
|
if(60>t)return t+"s"
|
|
1125
1146
|
const r=Math.floor(t/60)
|
|
1126
1147
|
return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function c(e){const t=[]
|
|
@@ -1134,16 +1155,16 @@ return e&&q>n?{status:"working",detail:"last action "+l(n),isReady:!1}:n>T&&e?{s
|
|
|
1134
1155
|
for(const o of e.trim().split("\n")){if(!o)continue
|
|
1135
1156
|
const[e,s]=o.split("\t")
|
|
1136
1157
|
"-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function h(e,r,n,o){const s=await(0,y.getServerUrl)(r,n)
|
|
1137
|
-
if(!s)throw new
|
|
1158
|
+
if(!s)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1138
1159
|
n.info("Checking status of subagent session",{sessionId:e})
|
|
1139
1160
|
try{const i=`${s.replace(/\/$/,"")}/session/${e}`,l=await fetch(i)
|
|
1140
1161
|
if(!l.ok)return{content:[{type:"text",text:`Session ${e} not found or has exited.`}],isError:!0}
|
|
1141
|
-
const h=await l.json(),p=`${s.replace(/\/$/,"")}/session/${e}/message`,
|
|
1142
|
-
let
|
|
1143
|
-
if(
|
|
1144
|
-
for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(
|
|
1162
|
+
const h=await l.json(),p=`${s.replace(/\/$/,"")}/session/${e}/message`,m=await fetch(p)
|
|
1163
|
+
let g={input:0,output:0,reasoning:0},f="",y=d(null,h.time.updated)
|
|
1164
|
+
if(m.ok){const e=await m.json()
|
|
1165
|
+
for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(g.input+=t.info.tokens.input||0,g.output+=t.info.tokens.output||0,g.reasoning+=t.info.tokens.reasoning||0)
|
|
1145
1166
|
const t=c(e)
|
|
1146
|
-
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,I=y.status,b=y.isReady,k=
|
|
1167
|
+
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,I=y.status,b=y.isReady,k=g.input+g.output+g.reasoning
|
|
1147
1168
|
let v="",C="",_=null
|
|
1148
1169
|
if(o)try{const t=o.getSessionRequestAssociationClient()
|
|
1149
1170
|
if(t){const r=await t.getActiveRequestsForSession(e,!1)
|
|
@@ -1158,38 +1179,38 @@ if(e.trim())return u(e)}try{const t=n(`git log main --merges --oneline -n 50 --g
|
|
|
1158
1179
|
if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
|
|
1159
1180
|
if(o.trim())return{...u(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
|
|
1160
1181
|
if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
|
|
1161
|
-
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: ${I} (${y.detail})\nReady for input: ${b?"Yes":"No"}\nAge: ${a(w)}\nTokens: ${k.toLocaleString()} (in: ${
|
|
1162
|
-
if(!n)throw new
|
|
1182
|
+
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: ${I} (${y.detail})\nReady for input: ${b?"Yes":"No"}\nAge: ${a(w)}\nTokens: ${k.toLocaleString()} (in: ${g.input.toLocaleString()}, out: ${g.output.toLocaleString()}${g.reasoning>0?", reasoning: "+g.reasoning.toLocaleString():""})${f}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,b.getErrorMessage)(e))}}async function p(e,t,r){const n=await(0,y.getServerUrl)(t,r)
|
|
1183
|
+
if(!n)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1163
1184
|
r.info("Aborting subagent session",{sessionId:e})
|
|
1164
1185
|
try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
|
|
1165
1186
|
if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
|
|
1166
|
-
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,b.getErrorMessage)(e))}}async function
|
|
1167
|
-
if(!p)throw new
|
|
1187
|
+
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,b.getErrorMessage)(e))}}async function m(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:i,minTokens:l,maxTokens:u,maxAgeHours:h}=n,p=await(0,y.getServerUrl)(e,t)
|
|
1188
|
+
if(!p)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1168
1189
|
t.info("Listing sessions",{filters:n})
|
|
1169
1190
|
try{const e=p.replace(/\/$/,"")+"/session",t=await fetch(e)
|
|
1170
1191
|
if(!t.ok)throw Error("Failed to fetch sessions: "+t.status)
|
|
1171
|
-
let
|
|
1172
|
-
if(0===
|
|
1173
|
-
const m
|
|
1174
|
-
n.parentSessionId&&(
|
|
1192
|
+
let m=await t.json()
|
|
1193
|
+
if(0===m.length)return{content:[{type:"text",text:"No sessions found."}]}
|
|
1194
|
+
const g=m
|
|
1195
|
+
n.parentSessionId&&(m=m.filter((e=>(e.parentId||e.parentID)===n.parentSessionId))),m.sort(((e,t)=>t.time.created-e.time.created))
|
|
1175
1196
|
const f=p.replace(/\/$/,"")+"/session/status",y=await fetch(f),w=y.ok?await y.json():{}
|
|
1176
|
-
let I=
|
|
1197
|
+
let I=m
|
|
1177
1198
|
if(o&&(I=I.filter((e=>"idle"!==(w[e.id]?.type||"idle")))),void 0!==h){const e=36e5*h,t=Date.now()-e
|
|
1178
1199
|
I=I.filter((e=>e.time.created>=t))}if(0===I.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1179
1200
|
let b={}
|
|
1180
1201
|
const k=I.map((e=>e.id))
|
|
1181
1202
|
let v={},C=[]
|
|
1182
1203
|
if("specialist"===n.agentType){const e=new Set(k)
|
|
1183
|
-
for(const t of
|
|
1204
|
+
for(const t of g){const r=t.parentId||t.parentID
|
|
1184
1205
|
r&&e.has(r)&&(v[r]||(v[r]=[]),v[r].push(t.id),C.push(t.id))}}if(r)try{const e=r.getCLISessionClient()
|
|
1185
1206
|
if(e){const t=[...k,...C]
|
|
1186
1207
|
b=await e.batchEnrich(t)}}catch{}const _=p.replace(/\/$/,""),E=await Promise.allSettled(I.map((e=>fetch(`${_}/session/${e.id}/message`).then((e=>e.ok?e.json():[])).catch((()=>[]))))),S=[]
|
|
1187
1208
|
for(let e=0;e<I.length;e++){const t=I[e],r=Date.now()-t.time.created
|
|
1188
1209
|
let o=0,i=null,a=[],h=d(null,t.time.updated)
|
|
1189
|
-
const p=E[e],
|
|
1190
|
-
for(const e of
|
|
1191
|
-
if(
|
|
1192
|
-
h=d(e.lastActivityTime,t.time.updated),i=e.current||null,a=e.recent}const
|
|
1210
|
+
const p=E[e],m="fulfilled"===p.status?p.value:[]
|
|
1211
|
+
for(const e of m)"assistant"===e.info.role&&e.info.tokens&&(o+=(e.info.tokens.input||0)+(e.info.tokens.output||0)+(e.info.tokens.reasoning||0))
|
|
1212
|
+
if(m.length>0){const e=c(m)
|
|
1213
|
+
h=d(e.lastActivityTime,t.time.updated),i=e.current||null,a=e.recent}const g=h.status
|
|
1193
1214
|
if(void 0!==l&&l>o)continue
|
|
1194
1215
|
if(void 0!==u&&o>u)continue
|
|
1195
1216
|
const f=b[t.id]
|
|
@@ -1209,10 +1230,10 @@ const n=[]
|
|
|
1209
1230
|
if(t.length>0&&n.push("active: "+t.join(", ")),r.length>0){const e=5,t=r.slice(0,e),o=r.length-t.length
|
|
1210
1231
|
n.push(`prev: ${t.join(", ")}${o>0?` +${o} more`:""}`)}n.length>0&&(y=` [${n.join(" | ")}]`)}if(s&&!k.includes(s))continue
|
|
1211
1232
|
const q=t.title||"Untitled",T=q.length>50?q.slice(0,47)+"...":q
|
|
1212
|
-
S.push({id:t.id,title:T,status:
|
|
1233
|
+
S.push({id:t.id,title:T,status:g,age:r,totalTokens:o,requestsInfo:y,allRequestIds:k,statusDetail:h.detail,specialization:f?.specialization??null,currentAction:i,recentActions:a})}if(0===S.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
|
|
1213
1234
|
const q=i?S.slice(0,i):S,T=q.map((e=>{const t=e.specialization?"\n Specialization: "+e.specialization:"",r=e.currentAction?"\n Current: "+e.currentAction:"",o="specialist"!==n.agentType&&e.recentActions.length>0?"\n Recent: "+e.recentActions.join(", "):""
|
|
1214
1235
|
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})`:""
|
|
1215
|
-
return{content:[{type:"text",text:`Found ${q.length} session${1!==q.length?"s":""}${P}:\n\n${T.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,b.getErrorMessage)(e))}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=s,exports.handleContinue=i,exports.handleCheckStatus=h,exports.handleAbort=p,exports.handleListSessions=
|
|
1236
|
+
return{content:[{type:"text",text:`Found ${q.length} session${1!==q.length?"s":""}${P}:\n\n${T.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,b.getErrorMessage)(e))}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=s,exports.handleContinue=i,exports.handleCheckStatus=h,exports.handleAbort=p,exports.handleListSessions=m,exports.handleSubagentOperations=async function(e,t,r,n,o,a){const c=r.child({tool:"subagent_operations"}),l=n.startTimer("tool_execution_time")
|
|
1216
1237
|
try{const r=e,{sessionId:d,operation:u}=r
|
|
1217
1238
|
let f
|
|
1218
1239
|
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)
|
|
@@ -1225,7 +1246,7 @@ case"abort":f=await p(d,t,c)
|
|
|
1225
1246
|
break
|
|
1226
1247
|
case"read-messages":const e=r.limit??1
|
|
1227
1248
|
f=await async function(e,t,r,n){const o=await(0,y.getServerUrl)(r,n)
|
|
1228
|
-
if(!o)throw new
|
|
1249
|
+
if(!o)throw new g.ValidationError("Could not determine OpenCode server URL")
|
|
1229
1250
|
n.info("Reading messages from subagent session",{sessionId:e,limit:t})
|
|
1230
1251
|
try{const r=`${o.replace(/\/$/,"")}/session/${e}/message?limit=${t}`,n=await fetch(r)
|
|
1231
1252
|
if(!n.ok){if(404===n.status)return{content:[{type:"text",text:`Session ${e} not found.`}],isError:!0}
|
|
@@ -1236,12 +1257,12 @@ return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n$
|
|
|
1236
1257
|
return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,b.getErrorMessage)(e))}}(d,e,t,c)
|
|
1237
1258
|
break
|
|
1238
1259
|
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}
|
|
1239
|
-
f=await
|
|
1260
|
+
f=await m(t,c,o,n)
|
|
1240
1261
|
break
|
|
1241
|
-
default:throw new
|
|
1262
|
+
default:throw new g.ValidationError("Unknown operation: "+u)}l({success:!0}),n.incrementCounter(`subagent_operations_${u}_success`,1)
|
|
1242
1263
|
const w=E[u]
|
|
1243
1264
|
return w?(0,_.withAlchemyKind)(f,w):f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,b.getErrorMessage)(e)}],isError:!0}}}
|
|
1244
|
-
const
|
|
1265
|
+
const g=t(9860),f=t(8035),y=t(7617),w=t(6688),I=t(7280),b=t(8824),k=t(9896),v=t(6928),C=t(8955),_=t(2272),E={spawn:"spawn-subagent",continue:"continue-subagent","check-status":"check-subagent-status",abort:"abort-subagent","read-messages":"read-subagent-messages","list-sessions":"list-subagent-sessions"},S=(0,t(9414).getActionServerPort)(),q=6e4,T=3e5},1791(e,exports,t){"use strict"
|
|
1245
1266
|
function r(e,t){return t.info("Creating project context middleware",{projectId:e}),(t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1246
1267
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
|
|
1247
1268
|
const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
|
|
@@ -1323,18 +1344,18 @@ d.info("Starting merge request",{requestId:h,verificationCount:p.length})
|
|
|
1323
1344
|
const e=a.getRequestClient(),s=await e.getRequest(h)
|
|
1324
1345
|
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}
|
|
1325
1346
|
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)
|
|
1326
|
-
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,
|
|
1347
|
+
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,m
|
|
1327
1348
|
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/validate-completion`,{})
|
|
1328
1349
|
c=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
1329
1350
|
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`
|
|
1330
1351
|
return c.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\n",c.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (${t.status})\n`}))),u({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(!t.workspaceManager)throw Error("WorkspaceManager not available")
|
|
1331
1352
|
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)
|
|
1332
|
-
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
|
|
1353
|
+
l=(await n.raw(["merge-base",o,"requests/"+h])).trim()||void 0}catch(e){d.warn("Could not compute merge-base; mergeBaseSha will not be recorded",{requestId:h,error:(0,i.getErrorMessage)(e)})}let g="workspace-manager"
|
|
1333
1354
|
const f=await e.getRequest(h),y=f?.title||"Request "+h,w="resolving_conflicts"===f?.status
|
|
1334
|
-
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),
|
|
1355
|
+
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),m=await t.workspaceManager.completeRequest(h,y,{skipConflictDetection:!0}),g="retry-theirs"):(m=await t.workspaceManager.completeRequest(h,y),g=m.autoMergeInfo?.strategy||"workspace-manager"),d.info("Merge completed",{requestId:h,mergeCommitHash:m.mergeCommitHash,mergeMethod:g})}catch(r){if(r.conflictInfo){const n=r.conflictInfo,s=n.workingDirectory||t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||process.cwd(),c=(0,o.createConflictResolutionManager)(d,a,s,t.git),l=await c.handleConflicts(n)
|
|
1335
1356
|
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)
|
|
1336
|
-
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:
|
|
1337
|
-
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:
|
|
1357
|
+
return u({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Merge failed: "+n}],isError:!0}}try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/finalize-completion`,{summary:f?.completionSummary||"Merged request "+h,acceptanceEvidence:p.map((e=>({evidence:e.evidence}))),mergeResult:{mergeCommitHash:m.mergeCommitHash,mergeBaseSha:l,mergedFiles:m.mergedFiles,cleanedUp:m.cleanedUp,method:g}})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
1358
|
+
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:m.mergeCommitHash,error:t}),u({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${m.mergeCommitHash.substring(0,8)}) but failed to update server: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:`Request ${h} merged successfully.\nCommit: ${m.mergeCommitHash.substring(0,8)}`}]}}catch(e){const r=(0,i.getErrorMessage)(e)
|
|
1338
1359
|
d.error("Merge request failed",{error:r})
|
|
1339
1360
|
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}}}
|
|
1340
1361
|
const r=t(3807),n=t(9860),o=t(1651),s=t(8616),i=t(8824)},1943(module){"use strict"
|
|
@@ -1381,18 +1402,18 @@ if(0===e.length)return d({success:!0}),{content:[{type:"text",text:"No setup com
|
|
|
1381
1402
|
c=e.map(((e,t)=>({name:"setup-"+(t+1),command:e,timeout:120})))}else{const t=process.config.commands||[],r=t.find((t=>t.name===e.commandName))
|
|
1382
1403
|
if(!r){const r=t.map((e=>e.name)).join(", ")
|
|
1383
1404
|
return d({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}}c=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{runShellCommand:h}=await Promise.resolve().then(t.bind(t,4600)),p=globalThis.process
|
|
1384
|
-
let
|
|
1385
|
-
const
|
|
1405
|
+
let m=null
|
|
1406
|
+
const g=[]
|
|
1386
1407
|
try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
|
|
1387
|
-
if(
|
|
1388
|
-
if(
|
|
1389
|
-
|
|
1390
|
-
const f=[],{default:y}=await Promise.resolve().then(t.t.bind(t,6928,23)),{default:w}=await Promise.resolve().then(t.t.bind(t,9896,23)),{ALCHEMY_DIR_NAME:I}=await Promise.resolve().then(t.bind(t,4139)),b=y.join(
|
|
1408
|
+
if(g.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
|
|
1409
|
+
if(g.push("reqId: "+(t||"NONE")),t){const e=await o.proxyGet(`/api/projects/${n.projectId}/requests/${t}/test-runs`),r=e?.data||e||[],s=Array.isArray(r)?r.find((e=>e.worktreePath||e.worktree_path)):null
|
|
1410
|
+
g.push(`runs: ${Array.isArray(r)?r.length:0}, withWorktree: ${s?.id||"NONE"}, path: ${s?.worktreePath||s?.worktree_path||"NONE"}`),s&&(m=s.worktreePath||s.worktree_path,u.info("Using test worktree from request test run",{worktreePath:m,reqId:t}))}}}catch(e){u.warn("Failed to resolve test worktree",{error:(0,r.getErrorMessage)(e)})}if(!m)return d({success:!1,error:"no_worktree"}),{content:[{type:"text",text:`No test worktree found.\n\nDiagnostics:\n${g.length>0?g.map((e=>"\u2022 "+e)).join("\n"):"\u2022 No session identity found"}\n\nEnsure this session is linked to a test process and a test run has been created.`}],isError:!0}
|
|
1411
|
+
const f=[],{default:y}=await Promise.resolve().then(t.t.bind(t,6928,23)),{default:w}=await Promise.resolve().then(t.t.bind(t,9896,23)),{ALCHEMY_DIR_NAME:I}=await Promise.resolve().then(t.bind(t,4139)),b=y.join(m,I,"command-logs")
|
|
1391
1412
|
try{w.mkdirSync(b,{recursive:!0})}catch{}const{runTrackedShellCommand:k}=await Promise.resolve().then(t.bind(t,4600)),{formatCombinedOutput:v}=await Promise.resolve().then(t.bind(t,1816)),{sessionIdentity:C}=await Promise.resolve().then(t.bind(t,6688)),_=C.getIdentity()?.sessionId
|
|
1392
|
-
for(const t of c){u.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:
|
|
1413
|
+
for(const t of c){u.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:m})
|
|
1393
1414
|
const r=`${t.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,n=y.join(b,r+".log")
|
|
1394
1415
|
let o=null
|
|
1395
|
-
try{o=w.createWriteStream(n,{flags:"w"}),o.write(`# ${(new Date).toISOString()} starting: ${t.command}\n# cwd: ${
|
|
1416
|
+
try{o=w.createWriteStream(n,{flags:"w"}),o.write(`# ${(new Date).toISOString()} starting: ${t.command}\n# cwd: ${m}\n# timeout: ${t.timeout}s\n\n`)}catch(e){u.warn("Failed to open command log file",{logPath:n,error:e+""})}const s=await(0,i.runTrackedShellWithHeartbeat)(t.command,{cwd:m,timeoutMs:1e3*t.timeout,env:{...p.env,FORCE_COLOR:"0"},onChunk:o?(e,t)=>{o?.write(t)}:void 0},{id:r,name:t.name,sessionId:_,logPath:n},l)
|
|
1396
1417
|
o&&(o.write(`\n# exit: ${s.exitCode}${s.timedOut?" (timed out)":""}\n`),o.end())
|
|
1397
1418
|
const a=(s.stdout+(s.stderr?"\n"+s.stderr:"")).trim(),{output:c,truncatedNote:d,logFooter:h}=v(a,{invocationId:r})
|
|
1398
1419
|
if(f.push({name:t.name,command:t.command,exitCode:s.exitCode,output:c,timedOut:s.timedOut,invocationId:r,truncatedNote:d,logFooter:h}),"setup"===e.commandName&&0!==s.exitCode)break}const E=f.every((e=>0===e.exitCode)),S=f.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
|
|
@@ -1400,7 +1421,7 @@ return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\`${e.trunc
|
|
|
1400
1421
|
return d({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${E?"PASSED":"FAILED"}\n\n${S}`}]}}catch(e){return d({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")
|
|
1401
1422
|
try{const{resolveRequestIdOrError:u}=await Promise.resolve().then(t.bind(t,9032)),h=await u(i,a,l?.sessionId,"Cannot report test results: this session is not associated with a request.")
|
|
1402
1423
|
if(!h.ok)return d({success:!1,error:"no_request_association"}),h.errorResult
|
|
1403
|
-
const p=h.requestId,
|
|
1424
|
+
const p=h.requestId,m=await i.proxyGet(`/api/projects/${s.projectId}/requests/${p}/test-runs`),g=m?.data||m||[],f=Array.isArray(g)?g:[],y=f.find((e=>"pending"===e.status||"running"===e.status))||f[0]
|
|
1404
1425
|
if(!y)return d({success:!1,error:"no_test_run"}),{content:[{type:"text",text:`No test run found for request ${p}.`}],isError:!0}
|
|
1405
1426
|
const w=y.id
|
|
1406
1427
|
await i.proxyPatch(`/api/projects/${s.projectId}/test-runs/${w}`,{status:e.status,results:e.results}),y.worktreePath&&fetch((0,o.getActionServerBaseUrl)()+"/api/release-pool-slot",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({worktreePath:y.worktreePath}),signal:AbortSignal.timeout(5e3)}).catch((e=>a.debug("release-pool-slot fire-and-forget failed (non-fatal)",{error:(0,r.getErrorMessage)(e)})))
|
|
@@ -1419,9 +1440,9 @@ u=Array.isArray(t)?t:[]}catch(e){a.warn("tests run: existence check failed; proc
|
|
|
1419
1440
|
const h=e.process
|
|
1420
1441
|
if(h){const e=h.toLowerCase(),t=u.find((t=>t.id===h||"string"==typeof t.name&&t.name.toLowerCase()===e))
|
|
1421
1442
|
if(!t){const e=u.map((e=>`- ${e.name} (${e.id})`)).join("\n")
|
|
1422
|
-
return d({success:!1,error:"process_not_found"}),{content:[{type:"text",text:`No test process matched "${h}". Available:\n${e}`}],isError:!0}}c=[t.id]}const p=l?.sessionId,{resolveRequestIdOrError:
|
|
1423
|
-
if(!
|
|
1424
|
-
const f=
|
|
1443
|
+
return d({success:!1,error:"process_not_found"}),{content:[{type:"text",text:`No test process matched "${h}". Available:\n${e}`}],isError:!0}}c=[t.id]}const p=l?.sessionId,{resolveRequestIdOrError:m}=await Promise.resolve().then(t.bind(t,9032)),g=await m(i,a,p,"tests run requires an associated request \u2014 your session is not currently linked to one. Open or create a request, then try again.")
|
|
1444
|
+
if(!g.ok)return d({success:!1,error:"no_request"}),g.errorResult
|
|
1445
|
+
const f=g.requestId,y=e.name?[e.name]:void 0
|
|
1425
1446
|
try{const e=await fetch((0,o.getActionServerBaseUrl)()+"/api/run-tests-now",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:f,parentSessionId:p,testProcessIds:c,commandNames:y}),signal:AbortSignal.timeout(15e3)})
|
|
1426
1447
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
1427
1448
|
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()
|
|
@@ -1494,13 +1515,13 @@ if("user"===r.info?.role)for(const e of r.parts??[]){if("text"!==e.type||!e.text
|
|
|
1494
1515
|
const t=e.text.match(/<viewed_session\s+id="([^"]+)"\s*\/?>/)
|
|
1495
1516
|
if(t)return t[1]}}return null}(h)
|
|
1496
1517
|
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}
|
|
1497
|
-
let
|
|
1498
|
-
try{
|
|
1499
|
-
if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,p)),
|
|
1500
|
-
|
|
1501
|
-
try{const e=await fetch(`${u}/session/${p}/prompt_async`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(
|
|
1518
|
+
let m
|
|
1519
|
+
try{m=function(e){for(let t=e.length-1;t>=0;t--){const r=e[t]
|
|
1520
|
+
if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,p)),m||t.warn("commit_to_viewed_session: no agent resolvable for viewed session; omitting agent",{viewedId:p})}catch(e){t.warn("commit_to_viewed_session: could not fetch viewed messages; omitting agent",{viewedId:p,error:(0,n.getErrorMessage)(e)})}const g={parts:[{type:"text",text:c,metadata:(0,s.partMeta)("via-herald")}]}
|
|
1521
|
+
m&&(g.agent=m),t.info("commit_to_viewed_session:posting",{callId:i,viewedId:p,heraldId:d,agent:m})
|
|
1522
|
+
try{const e=await fetch(`${u}/session/${p}/prompt_async`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(g),signal:AbortSignal.timeout(1e4)})
|
|
1502
1523
|
if(t.info("commit_to_viewed_session:posted",{callId:i,status:e.status}),!e.ok){const t=await e.text().catch((()=>""))
|
|
1503
|
-
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:
|
|
1524
|
+
return{content:[{type:"text",text:`Commit failed: prompt_async returned ${e.status}${t?` (${t.slice(0,120)})`:""}.`}],isError:!0}}}catch(e){return t.warn("commit_to_viewed_session:post-failed",{callId:i,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:"Commit failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}return t.info("Translator forwarded message to viewed session",{callId:i,heraldId:d,viewedId:p,agent:m,messageLength:c.length,preview:c.slice(0,120),durationMs:Date.now()-a}),{content:[{type:"text",text:"Committed."}]}}
|
|
1504
1525
|
const n=t(8824),o=t(6688),s=t(2272)},2141(e,exports,t){"use strict"
|
|
1505
1526
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConflictResolver=void 0,exports.createConflictResolver=function(e){return new n(e)}
|
|
1506
1527
|
const r=t(8824)
|
|
@@ -1576,29 +1597,29 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
1576
1597
|
var t={}
|
|
1577
1598
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
1578
1599
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1579
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,r,n,o,s,i,g
|
|
1600
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMoveFiles=async function(e,r,n,o,s,i,m,g){const f=i.child({tool:"move_files"}),y=Date.now()
|
|
1580
1601
|
let w,I,b=l.FileOperationPhase.VALIDATION
|
|
1581
1602
|
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"}
|
|
1582
1603
|
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)
|
|
1583
1604
|
if("errorResult"in _)return _.errorResult
|
|
1584
1605
|
const{taskId:E}=_
|
|
1585
1606
|
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")
|
|
1586
|
-
l.validateTaskIdFormat(E,f,
|
|
1607
|
+
l.validateTaskIdFormat(E,f,m,k.metricsPrefix)
|
|
1587
1608
|
const S=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1588
1609
|
f.info("Initial branch context",{initialBranch:S.branch,initialRequestId:S.requestId,isMain:S.isMain})
|
|
1589
1610
|
const q=[]
|
|
1590
1611
|
for(const e of u){const{normalizedPath:t,fullPath:n}=l.validateAndNormalizePath(e.source,r),{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(e.destination,r)
|
|
1591
|
-
q.push({source:t,destination:o,fullSource:n,fullDestination:s})}b=l.FileOperationPhase.TASK_VALIDATION,
|
|
1592
|
-
const T=await l.validateTaskId(E,q[0].source,n,f,
|
|
1612
|
+
q.push({source:t,destination:o,fullSource:n,fullDestination:s})}b=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("move_files_phase",1,{phase:b})
|
|
1613
|
+
const T=await l.validateTaskId(E,q[0].source,n,f,m,k.metricsPrefix),P=T?.requestId,x=await l.validateWorkItemStates(E,q[0].source,n,s,r,f,m,k.metricsPrefix),j=await l.autoPromoteTaskStatus(E,T.status,P,x.request?.status,q[0].source,n,s,f,m,k.metricsPrefix)
|
|
1593
1614
|
j.taskPromoted&&f.info(`Auto-promoted task ${E} (${T.title||"Untitled"}) to in_progress for file operations`,{taskId:E,taskTitle:T.title,previousStatus:T.status,newStatus:j.newTaskStatus,operationCount:u.length}),j.requestPromoted&&f.info(`Auto-promoted request ${P} to in_progress for file operations`,{requestId:P,previousStatus:x.request?.status,newStatus:j.newRequestStatus,triggeringTaskId:E})
|
|
1594
|
-
const R=await l.ensureCorrectWorkspaceContext({taskPromoted:j.taskPromoted,requestId:P,context:r,operation:"move-files",logger:f,metrics:
|
|
1615
|
+
const R=await l.ensureCorrectWorkspaceContext({taskPromoted:j.taskPromoted,requestId:P,context:r,operation:"move-files",logger:f,metrics:m,metricsPrefix:k.metricsPrefix})
|
|
1595
1616
|
if(!R.success)throw Error(R.error)
|
|
1596
1617
|
let M={hadUserMods:!1,userModsCommitHash:void 0}
|
|
1597
1618
|
if(r.git)try{f.debug("[MOVE-FILES] Checking for user changes before move operations")
|
|
1598
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:P,taskId:E,workspaceManager:r.workspaceManager},f,
|
|
1599
|
-
e.userChangesCommitted&&(f.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),f.info("User changes committed before move-files operation",{taskId:E,moveOperationsCount:q.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),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:q.length,error:e instanceof Error?e.message:e+""})}f.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:q.length}),b=l.FileOperationPhase.RECORD_CREATION,
|
|
1600
|
-
const{toolRecordId:$,localToolRecordId:O}=await l.createFileOperationRecords(E,P,r.projectId,k.recordType,q[0].source,{operationCount:u.length,operations:q.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},n,o,f,
|
|
1601
|
-
w=$,I=$,b=k.fileOperationPhase,
|
|
1619
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:P,taskId:E,workspaceManager:r.workspaceManager},f,m)
|
|
1620
|
+
e.userChangesCommitted&&(f.debug("[MOVE-FILES] User changes committed before move operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),f.info("User changes committed before move-files operation",{taskId:E,moveOperationsCount:q.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),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:q.length,error:e instanceof Error?e.message:e+""})}f.debug("[MOVE-FILES] Proceeding with move operations",{operationCount:q.length}),b=l.FileOperationPhase.RECORD_CREATION,m.incrementCounter("move_files_phase",1,{phase:b})
|
|
1621
|
+
const{toolRecordId:$,localToolRecordId:O}=await l.createFileOperationRecords(E,P,r.projectId,k.recordType,q[0].source,{operationCount:u.length,operations:q.map((e=>({source:e.source,destination:e.destination}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},n,o,f,m,k.metricsPrefix,g)
|
|
1622
|
+
w=$,I=$,b=k.fileOperationPhase,m.incrementCounter("move_files_phase",1,{phase:b})
|
|
1602
1623
|
const D=[]
|
|
1603
1624
|
let A=0
|
|
1604
1625
|
for(const e of q){const t={operation:{source:e.source,destination:e.destination},success:!1}
|
|
@@ -1606,13 +1627,13 @@ try{try{await a.default.access(e.fullSource)}catch(t){throw Error("Source path n
|
|
|
1606
1627
|
t.isDirectory=r
|
|
1607
1628
|
const n=c.default.dirname(e.fullDestination)
|
|
1608
1629
|
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
|
|
1609
|
-
|
|
1630
|
+
m.recordValue("move_files_time",F),m.incrementCounter("move_files_operations_total",u.length),m.incrementCounter("move_files_operations_success",A),m.incrementCounter("move_files_operations_failed",u.length-A),A===u.length?m.incrementCounter("move_files_success",1):A>0?m.incrementCounter("move_files_partial_success",1):m.incrementCounter("move_files_total_failure",1)
|
|
1610
1631
|
let N=null
|
|
1611
|
-
if(A>0){b=l.FileOperationPhase.GIT_COMMIT,
|
|
1632
|
+
if(A>0){b=l.FileOperationPhase.GIT_COMMIT,m.incrementCounter("move_files_phase",1,{phase:b})
|
|
1612
1633
|
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}`
|
|
1613
|
-
N=await l.commitToGit(E,q[0].destination,$,O,t,r,f,
|
|
1634
|
+
N=await l.commitToGit(E,q[0].destination,$,O,t,r,f,m,k.metricsPrefix)}b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,m.incrementCounter("move_files_phase",1,{phase:b})
|
|
1614
1635
|
const z=D.filter((e=>e.success)),L=D.filter((e=>!e.success))
|
|
1615
|
-
await l.updateFileOperationRecords(E,w,I,q[0].source,k.recordType,A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,{status:A===u.length?"completed":"partial_success",commitHash:N?.commitHash,previousCommitHash:N?.previousCommitHash,operationCount:u.length,successCount:A,failureCount:u.length-A,successfulOperations:z.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:L.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,n,o,f,
|
|
1636
|
+
await l.updateFileOperationRecords(E,w,I,q[0].source,k.recordType,A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,{status:A===u.length?"completed":"partial_success",commitHash:N?.commitHash,previousCommitHash:N?.previousCommitHash,operationCount:u.length,successCount:A,failureCount:u.length-A,successfulOperations:z.map((e=>({source:e.operation.source,destination:e.operation.destination,isDirectory:e.isDirectory}))),failedOperations:L.map((e=>({source:e.operation.source,destination:e.operation.destination,error:e.error}))),userComment:v,hadUserMods:M.hadUserMods,userModsCommitHash:M.userModsCommitHash},A===u.length?`Successfully moved all ${u.length} items`:`Moved ${A}/${u.length} items successfully`,n,o,f,m,k.metricsPrefix)
|
|
1616
1637
|
const H=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
1617
1638
|
let B=""
|
|
1618
1639
|
if(A===u.length)B=`Successfully moved all ${u.length} ${1===u.length?"item":"items"}`
|
|
@@ -1620,8 +1641,8 @@ else if(A>0){const e=D.filter((e=>!e.success))
|
|
|
1620
1641
|
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")
|
|
1621
1642
|
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
|
|
1622
1643
|
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:b,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
|
|
1623
|
-
if(
|
|
1624
|
-
try{await l.updateFileOperationRecords(e.taskId,w,I,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,
|
|
1644
|
+
if(m.recordValue("move_files_time",s),m.incrementCounter("move_files_errors",1),f.error("Error in move-files operation:",{error:(0,p.getErrorMessage)(t),time:s}),(w||I)&&e.taskId){b=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
1645
|
+
try{await l.updateFileOperationRecords(e.taskId,w,I,e.operations?.[0]?.source||"unknown",k.recordType,"Failed to move files",{status:"failed",error:(0,p.getErrorMessage)(t),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",n,o,f,m,k.metricsPrefix)}catch(t){f.error("Failed to update record with failure status",{taskId:e.taskId,recordId:w,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(t,b,f,m,e,k)}}
|
|
1625
1646
|
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"
|
|
1626
1647
|
module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){"use strict"
|
|
1627
1648
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
@@ -1630,7 +1651,7 @@ exports.def={name:"quick_manage",description:"WHEN TO USE: trivial single-file e
|
|
|
1630
1651
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildTaskEndpoint=function(e,t,r){const n=r?"/"+r.replace(/^\//,""):""
|
|
1631
1652
|
return`/api/projects/${e}/tasks/${encodeURIComponent(t)}${n}`}},2462(e,exports,t){"use strict"
|
|
1632
1653
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
1633
|
-
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),
|
|
1654
|
+
const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),p=t(5459),m=t(4805),g=t(260),f=t(2283),y=t(4165),w=t(7834),I=t(9373),b=t(6111),k=t(700),v=t(1535),C=t(7257),_=t(9230),E=t(4150),S=t(6473),q=t(6309),T=t(4921),P=t(8850),x=t(3556),j=t(1391),R=t(6315),M=t(7713),$=t(6252),O=t(577),D=t(4206),A=t(213),F=t(7250),N=t(2425),z=t(1540),L=t(5767),H=t(4973),B=t(509),U=t(7613),W=t(8456),G=t(3322),V=t(5247),Q=t(8849),K=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(p.def),(0,r.registerTool)(m.def),(0,r.registerTool)(g.def),(0,r.registerTool)(f.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(I.def),(0,r.registerTool)(b.def),(0,r.registerTool)(k.def),(0,r.registerTool)(v.def),(0,r.registerTool)(E.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(S.def),(0,r.registerTool)(q.def),(0,r.registerTool)(T.def),(0,r.registerTool)(P.def),(0,r.registerTool)(x.def),(0,r.registerTool)(j.def),(0,r.registerTool)(R.def),(0,r.registerTool)(M.def),(0,r.registerTool)($.def),(0,r.registerTool)(O.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(z.def),(0,r.registerTool)(L.def),(0,r.registerTool)(H.def),(0,r.registerTool)(B.def),(0,r.registerTool)(U.def),(0,r.registerTool)(W.def),(0,r.registerTools)(G.metaDefs),(0,r.registerTools)(V.testingDefs),(0,r.registerTools)(Q.checkingDefs),(0,r.registerTools)(K.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
|
|
1634
1655
|
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","ask-me","test-by-default","always-test"].includes(e)?e:"test-by-default"},exports.getReviewMode=function(e){return e&&["auto-finalize","manual-review"].includes(e)?e:"auto-finalize"},exports.getApprovalMode=function(e){return e&&["none","require-approval"].includes(e)?e:"none"},exports.requestConfig={requireTestsForCompletion:!1}},2537(e,exports,t){"use strict"
|
|
1635
1656
|
async function r(e,t,r){if(v.has(r)&&C>=t){if(0===t)return 0
|
|
1636
1657
|
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]"
|
|
@@ -1655,10 +1676,10 @@ let t=e,r=0
|
|
|
1655
1676
|
for(;t>=1024&&4>r;)t/=1024,r++
|
|
1656
1677
|
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[]
|
|
1657
1678
|
try{const{fullPath:d}=I.validateAndNormalizePath(e,t),h=await y.default.readdir(d,{withFileTypes:!0}),p=[]
|
|
1658
|
-
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=I.validateAndNormalizePath(u,t),
|
|
1679
|
+
for(const d of h)try{const u=w.default.join(e,d.name).replace(/\\/g,"/"),{fullPath:h}=I.validateAndNormalizePath(u,t),m=await y.default.stat(h),g=d.isFile()?w.default.extname(d.name).toLowerCase():""
|
|
1659
1680
|
let f
|
|
1660
|
-
d.isFile()&&(f=await r(h,
|
|
1661
|
-
const b={name:d.name,isDirectory:d.isDirectory(),depth:n,size:
|
|
1681
|
+
d.isFile()&&(f=await r(h,m.size,g))
|
|
1682
|
+
const b={name:d.name,isDirectory:d.isDirectory(),depth:n,size:m.size,modified:m.mtime,extension:g,lineCount:f}
|
|
1662
1683
|
d.isDirectory()&&(s-1>n?(b.children=await o(u,t,n+1,s,i,l),b.children&&b.children.length>0&&(b.subtreeTotals=c(b.children))):b.subtreeTotals=await a(u,t,l)),p.push(b)}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""
|
|
1663
1684
|
const o=[]
|
|
1664
1685
|
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?"/":""
|
|
@@ -1684,21 +1705,21 @@ case"type":const o=e.extension||"",s=r.extension||""
|
|
|
1684
1705
|
return o!==s?o.localeCompare(s):e.name.localeCompare(r.name)
|
|
1685
1706
|
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)
|
|
1686
1707
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
1687
|
-
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]}),
|
|
1708
|
+
o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),m=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),g=this&&this.__importStar||(h=function(e){return h=Object.getOwnPropertyNames||function(e){var t=[]
|
|
1688
1709
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
1689
1710
|
return t},h(e)},function(e){if(e&&e.__esModule)return e
|
|
1690
1711
|
var t={}
|
|
1691
1712
|
if(null!=e)for(var r=h(e),n=0;n<r.length;n++)"default"!==r[n]&&p(t,e,r[n])
|
|
1692
|
-
return
|
|
1713
|
+
return m(t,e),t}),f=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1693
1714
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleListDirectory=async function(e,t,i,a){const h=Date.now()
|
|
1694
1715
|
let p=I.FileOperationPhase.VALIDATION
|
|
1695
1716
|
I.FileOperationPhase.FILE_WRITE
|
|
1696
|
-
try{const
|
|
1697
|
-
i.info("Listing directory: "+
|
|
1698
|
-
const{normalizedPath:v,fullPath:C}=I.validateAndNormalizePath(
|
|
1717
|
+
try{const m=e,{path:g,levels:f=1,sortBy:b="name"}=m
|
|
1718
|
+
i.info("Listing directory: "+g)
|
|
1719
|
+
const{normalizedPath:v,fullPath:C}=I.validateAndNormalizePath(g,t)
|
|
1699
1720
|
p=I.FileOperationPhase.FILE_WRITE
|
|
1700
|
-
try{if(!(await y.default.stat(C)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+
|
|
1701
|
-
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: "+
|
|
1721
|
+
try{if(!(await y.default.stat(C)).isDirectory())return{content:[{type:"text",text:"Path is not a directory: "+g}],isError:!0}
|
|
1722
|
+
await y.default.access(C,y.default.constants.R_OK)}catch(e){return e instanceof Error&&"ENOENT"===e.code?{content:[{type:"text",text:"Directory does not exist: "+g}],isError:!0}:e instanceof Error&&"EACCES"===e.code?{content:[{type:"text",text:"Directory not accessible: "+g}],isError:!0}:{content:[{type:"text",text:"Cannot access directory: "+g}],isError:!0}}let _,E
|
|
1702
1723
|
if(f>1){i.info(`Building tree structure for: ${v} (levels: ${f}, sortBy: ${b})`)
|
|
1703
1724
|
const e=await o(v,t,0,f,b,i)
|
|
1704
1725
|
if(e.length>0){const t=s(e,b)
|
|
@@ -1711,7 +1732,7 @@ _+="\n\nBranch: "+(S?.branchName||"unknown")
|
|
|
1711
1732
|
const q=Date.now()-h
|
|
1712
1733
|
return a.recordValue("list_directory_time",q),a.recordValue("list_directory_entries",E),a.incrementCounter("list_directory_success",1),i.info("Successfully listed directory: "+v,{entryCount:E,levels:f,time:q}),{content:[{type:"text",text:_}]}}catch(e){const t=Date.now()-h
|
|
1713
1734
|
return a.recordValue("list_directory_time",t),a.incrementCounter("list_directory_errors",1),i.error("Error listing directory:",{error:(0,k.getErrorMessage)(e),time:t}),{content:[{type:"text",text:(0,k.getErrorMessage)(e)}],isError:!0}}}
|
|
1714
|
-
const y=f(t(1943)),w=f(t(6928)),I=
|
|
1735
|
+
const y=f(t(1943)),w=f(t(6928)),I=g(t(5967)),b=t(3253),k=t(8824),v=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".rb",".go",".rs",".java",".kt",".scala",".c",".cpp",".h",".hpp",".cs",".html",".css",".scss",".sass",".less",".json",".yaml",".yml",".toml",".xml",".md",".txt",".csv",".sql",".sh",".bash",".zsh",".fish",".vim",".lua",".php",".swift",".m",".vue",".svelte",".astro",".env",".gitignore",".dockerignore",".config",".conf",".ini",".cfg"]),C=1048576},2568(e,exports,t){"use strict"
|
|
1715
1736
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
1716
1737
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectSynchronizer=void 0
|
|
1717
1738
|
const n=r(t(6928)),o=t(8029),s=t(8824),i=t(2096)
|
|
@@ -1824,11 +1845,11 @@ const t=await this.requestWithRetry("POST",`/api/projects/${e}/session-messages/
|
|
|
1824
1845
|
return(0,n.safeGetResponseData)(t,{expiredCount:0},this.logger).expiredCount}}exports.SessionMessageClient=o},2736(e,exports,t){"use strict"
|
|
1825
1846
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteTask=async function(e,l,d,u,h){const p=u.child({tool:"complete_task"})
|
|
1826
1847
|
p.info("Completing task",{args:e})
|
|
1827
|
-
const
|
|
1848
|
+
const m=h.startTimer("tool_handler_duration")
|
|
1828
1849
|
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)
|
|
1829
1850
|
throw new r.ValidationError("Invalid input: "+(0,a.getErrorMessage)(e))}}(e)
|
|
1830
1851
|
let u=o.taskId
|
|
1831
|
-
const
|
|
1852
|
+
const g=o.summary;(0,c.isTaskRef)(u)&&(u=await(0,c.resolveTaskRef)(u,d,p))
|
|
1832
1853
|
const f=l.projectId
|
|
1833
1854
|
if(!f)throw new r.ValidationError("Project ID is required for completing tasks with the new API structure")
|
|
1834
1855
|
h.incrementCounter("complete_task_attempts",1,{taskId:u}),d.setProjectId(f)
|
|
@@ -1844,18 +1865,18 @@ throw p.warn(e,{taskId:u,currentStatus:w.status}),new r.ValidationError(e)}let I
|
|
|
1844
1865
|
if(l.workspaceManager){const e=l.workspaceManager.getCurrentContext(l.currentSessionId)
|
|
1845
1866
|
if("multi-agent"===e.mode&&e.requestId){const{simpleGit}=t(3807)
|
|
1846
1867
|
I=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 b=null
|
|
1847
|
-
if(I)try{(await I.status()).isClean()||(b=(await I.commit(`Complete task ${u}: ${
|
|
1868
|
+
if(I)try{(await I.status()).isClean()||(b=(await I.commit(`Complete task ${u}: ${g}`)).commit,p.info("Created commit for task completion",{taskId:u,commitId:b}))}catch(e){p.warn("Failed to commit changes",{error:(0,a.getErrorMessage)(e)})}let k=null
|
|
1848
1869
|
try{const e=d.getToolRecordClient()
|
|
1849
|
-
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:
|
|
1870
|
+
e&&(k={id:(await e.createToolRecord({taskId:u,requestId:w.requestId,projectId:f,type:"complete-task",metadata:{status:"completed",timestamp:(new Date).toISOString(),taskTitle:w.title,completionSummary:g,lastCommit:b,completedAt:(new Date).toISOString()},note:`Completed task: ${g.substring(0,100)}${g.length>100?"...":""}`})).id})}catch(e){p.error("Failed to create tool record for task completion, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:u,requestId:w.requestId})}try{const e=w.metadata||{},t=(new Date).toISOString(),r={status:"completed",metadata:{...e,lastCommit:b,completionSummary:g,completionRecordId:k?.id,completedAt:t}},o=await y.updateTask(u,r)
|
|
1850
1871
|
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})
|
|
1851
1872
|
const i=w.requestId,l=w.requestId
|
|
1852
1873
|
let d=`Task ${w.sequenceNumber&&l?(0,c.formatTaskRef)(l,w.sequenceNumber):u} (${w.title}) has been marked as completed.`
|
|
1853
1874
|
if(b&&(d+="\nCommit: "+b.substring(0,8)),i)try{const e=await y.listTasks({requestId:i})
|
|
1854
1875
|
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"})
|
|
1855
1876
|
const t=(0,s.extractArrayFromResponse)(e,{logger:p,operationName:"listTasksForProgress",defaultValue:[]}),r=t.length,n=t.filter((e=>"completed"===e.status)).length
|
|
1856
|
-
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
|
|
1877
|
+
p.info("Task progress check",{requestId:i,totalTasks:r,completedTasks:n}),d+=`\n\nTask Progress: ${n}/${r} tasks completed`,n===r&&(d+=`\n\nAll tasks for request ${i} are now completed! You may consider marking the request as completed using the complete-request tool.`)}catch(e){p.warn("Failed to check task progress",{error:(0,a.getErrorMessage)(e),requestId:i})}return m({success:!0}),{content:[{type:"text",text:d}],...(0,n.alchemyMeta)({kind:"complete-task",toolRecordId:k?.id})}}catch(e){throw p.error("Failed to complete task",{error:e instanceof Error?e.stack:e+"",taskId:u}),Error("Failed to complete task: "+(0,a.getErrorMessage)(e))}}catch(t){if(p.error("Failed to complete task",{error:t instanceof Error?t.stack:t+"",args:e}),l.projectId)try{const n=d.getToolRecordClient()
|
|
1857
1878
|
if(n){const o=t instanceof r.NotFoundError||t instanceof r.ValidationError||t instanceof i.ZodError
|
|
1858
|
-
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+""})}
|
|
1879
|
+
await n.createToolRecord({...o?{}:{taskId:e.taskId},projectId:l.projectId,type:"complete-task",metadata:{status:"failed",timestamp:(new Date).toISOString(),taskTitle:e.summary?.substring(0,100)+(e.summary?.length>100?"...":""),error:(0,a.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",attemptedTaskId:e.taskId,taskIdValidationFailed:o},note:"Failed to complete task "+e.taskId})}}catch(e){p.error("Failed to create failure record for task completion",{error:e instanceof Error?e.message:e+""})}m({success:!1,error:t instanceof Error?t.name:"unknown"})
|
|
1859
1880
|
let n=(0,a.getErrorMessage)(t)
|
|
1860
1881
|
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}}}
|
|
1861
1882
|
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"
|
|
@@ -1864,12 +1885,12 @@ if(!r())return t.level=(0,l.isDevBuild)()?c.LogLevel.INFO:c.LogLevel.ERROR,t.log
|
|
|
1864
1885
|
if("true"===process.env.DEBUG_LOGGING?.toLowerCase()){t.level=c.LogLevel.DEBUG,t.logToFile=!0
|
|
1865
1886
|
const r=e||process.cwd()
|
|
1866
1887
|
t.logFilePath=i.default.join(r,"logs","debug.log")}const n=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
1867
|
-
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:
|
|
1868
|
-
if(console&&f.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),
|
|
1869
|
-
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(
|
|
1888
|
+
return n&&Object.values(c.LogLevel).includes(n)&&(t.level=n),t}(e.baseDir),...e},{level:o=c.LogLevel.INFO,serviceName:p="mcp-service",logToFile:m=!1,logFilePath:g="./logs/app.log",console=!0}=t,f=[]
|
|
1889
|
+
if(console&&f.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),m){!function(e){const t=i.default.dirname(e)
|
|
1890
|
+
a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(g)
|
|
1870
1891
|
const e=o===c.LogLevel.DEBUG&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()
|
|
1871
|
-
f.push(new s.default.transports.File({filename:
|
|
1872
|
-
return o===c.LogLevel.DEBUG&&
|
|
1892
|
+
f.push(new s.default.transports.File({filename:g,format:e?h:u}))}const y=s.default.createLogger({level:o,defaultMeta:{service:p},transports:f})
|
|
1893
|
+
return o===c.LogLevel.DEBUG&&m&&r()&&y.info("Enhanced logging initialized",{level:o,serviceName:p,logToFile:m,logFilePath:g,debugLogging:process.env.DEBUG_LOGGING}),{error(e,t){y.error(e,t)},warn(e,t){y.warn(e,t)},info(e,t){y.info(e,t)},debug(e,t){y.debug(e,t)},child(e){const r=y.child(e)
|
|
1873
1894
|
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}}
|
|
1874
1895
|
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
|
|
1875
1896
|
const e=process.env.DEBUG_LEVEL?.toLowerCase()
|
|
@@ -1927,13 +1948,13 @@ i.info("Request breakdown",{fileRequests:d.length,documentRequests:u.length})
|
|
|
1927
1948
|
const h=[]
|
|
1928
1949
|
for(const e of d)h.push(r(e,t,0,l))
|
|
1929
1950
|
for(const e of u)h.push(n(e,t,0,l))
|
|
1930
|
-
const
|
|
1931
|
-
let
|
|
1951
|
+
const m=await Promise.all(h)
|
|
1952
|
+
let g=""
|
|
1932
1953
|
if(t.workspaceManager)try{const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
1933
|
-
e.branchName&&!e.permanentBranch&&(
|
|
1954
|
+
e.branchName&&!e.permanentBranch&&(g=`**Current Branch:** ${e.branchName}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const f=m.filter((e=>e.success)).length,y=m.filter((e=>!e.success)).length,w=m.length
|
|
1934
1955
|
let I="## Read Files/Documents\n\n"
|
|
1935
|
-
|
|
1936
|
-
for(let e=0;e<
|
|
1956
|
+
g&&(I+=g),I+=`**Total Requests:** ${w} - **Successful:** ${f} - **Failed:** ${y}\n\n`
|
|
1957
|
+
for(let e=0;e<m.length;e++){const t=m[e]
|
|
1937
1958
|
"file"===t.type?I+=`File ${e+1}: ${t.path}\n`:(I+=`Document ${e+1}: ${t.documentId}`,t.filename&&(I+=` (${t.filename})`),I+="\n"),t.success?(I+="**Status:** Success\n",t.lineCount&&t.totalLines&&(I+=`Lines Read / Total Lines ${t.lineCount} / ${t.totalLines}\n`),t.originalRequest?.lines&&t.totalLines&&(I+=`**Lines:** ${t.originalRequest.lines}\n`),I+=`\n**Content:**\n\`\`\`\n${t.content}\n\`\`\`\n`):(I+="**Status:** Failed\n",I+=`**Error:** ${t.error}\n`),I+="\n"}const b=0===y
|
|
1938
1959
|
return i.info("Multiple file/document read completed",{duration:Date.now()-a,totalRequests:w,successfulReads:f,failedReads:y,success:b}),s.incrementCounter("read_files_total",1,{success:b}),{content:[{type:"text",text:I}],...(0,p.alchemyMeta)({kind:"read-files"}),isError:!b}}catch(e){const t=Date.now()-a
|
|
1939
1960
|
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}}}
|
|
@@ -2015,9 +2036,9 @@ throw c.error(`STRICT VALIDATION - File operation blocked on ${u.status} request
|
|
|
2015
2036
|
const n=(0,s.getErrorMessage)(r)
|
|
2016
2037
|
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
|
|
2017
2038
|
const n=(0,s.getErrorMessage)(r)
|
|
2018
|
-
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,
|
|
2039
|
+
throw c.error("Could not validate work item states for task "+e,{taskId:e,path:t,error:n}),l.incrementCounter(d+"_state_validation_error",1),new o.ValidationError("Could not validate work item states: "+n,{taskId:e,path:t,originalError:r})}},exports.autoPromoteTaskStatus=async function(e,t,r,o,i,a,c,l,d,u){try{let s,h,p=!1,m=!1
|
|
2019
2040
|
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)
|
|
2020
|
-
|
|
2041
|
+
m=t.promoted,h=t.newStatus}return{taskPromoted:p,newTaskStatus:s,requestPromoted:m,newRequestStatus:h}}catch(r){const n=(0,s.getErrorMessage)(r)
|
|
2021
2042
|
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})
|
|
2022
2043
|
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})
|
|
2023
2044
|
const t=`Cannot complete request ${e} - no tasks found. Create tasks for this request before attempting completion.`
|
|
@@ -2044,7 +2065,7 @@ l.info("Generating journal for request",{requestId:a})
|
|
|
2044
2065
|
const u=t.projectId
|
|
2045
2066
|
if(!u)throw(0,n.createValidationError)("Project ID is required. Make sure you are in a project context.")
|
|
2046
2067
|
o.setProjectId(u),l.info("Fetching request data, tasks, and file history in parallel")
|
|
2047
|
-
const h=o.getRequestClient(),p=o.getTaskClient(),
|
|
2068
|
+
const h=o.getRequestClient(),p=o.getTaskClient(),m=o.getToolRecordClient(),[g,f,y]=await Promise.all([h.getRequest(a),p.listTasks({requestId:a}),m.getToolRecordsByRequestId(a).catch((e=>(l.warn("Failed to fetch tool records",{error:e+""}),[])))]),w=(0,s.extractDataFromResponse)(g,{logger:l,operationName:"getRequest",throwOnNoData:!0}),I="data"in w?w.data:w,b={id:I.id||a,title:I.title||"Unknown Request",description:I.description||"No description available",status:I.status||"unknown",type:I.type||"unknown",acceptanceCriteria:I.acceptanceCriteria||[],createdAt:I.createdAt||(new Date).toISOString(),updatedAt:I.updatedAt||(new Date).toISOString(),completedAt:I.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})))
|
|
2048
2069
|
l.info(`Fetched request, ${v.length} tasks, ${y.length} tool records`)
|
|
2049
2070
|
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()))
|
|
2050
2071
|
for(const e of o){const o=r(e),s=e.metadata?.comment||e.metadata?.userComment||"No comment"
|
|
@@ -2068,7 +2089,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.MultiAgentWorkspa
|
|
|
2068
2089
|
const r=t(7636)
|
|
2069
2090
|
Object.defineProperty(exports,"MultiAgentWorkspaceManager",{enumerable:!0,get(){return r.MultiAgentWorkspaceManager}})},3247(e,exports,t){"use strict"
|
|
2070
2091
|
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))
|
|
2071
|
-
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
|
|
2092
|
+
return{active:s?r(s):null,nextPending:i?r(i):null}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleTasks=async function(e,t,d,u,h,p){const m=u.child({tool:"tasks"}),{operation:g}=e
|
|
2072
2093
|
try{const h=t.projectId
|
|
2073
2094
|
if(!h)throw Error("Project ID not available")
|
|
2074
2095
|
d.setProjectId(h)
|
|
@@ -2077,13 +2098,13 @@ if(!o||"__unknown__"===o||"__server__"===o)throw Error("Cannot resolve request:
|
|
|
2077
2098
|
const i=await s.sessionIdentity.getSessionRequestId(t,r,o)
|
|
2078
2099
|
if(!i)throw Error("No request associated with session "+o)
|
|
2079
2100
|
return i}(t,d,u,p)
|
|
2080
|
-
switch(
|
|
2101
|
+
switch(g){case"create":{const{title:t,description:r}=e
|
|
2081
2102
|
if(!t)return{content:[{type:"text",text:"Error: title is required for create"}],isError:!0}
|
|
2082
2103
|
if(!r)return{content:[{type:"text",text:"Error: description is required for create"}],isError:!0}
|
|
2083
2104
|
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
|
|
2084
2105
|
let p=!1
|
|
2085
|
-
if(!s)try{await n.updateTaskStatus(u,"in_progress"),p=!0}catch(e){
|
|
2086
|
-
let y=
|
|
2106
|
+
if(!s)try{await n.updateTaskStatus(u,"in_progress"),p=!0}catch(e){m.debug("Could not auto-start task",{taskId:u,error:(0,i.getErrorMessage)(e)})}const g=a.sequenceNumber??null
|
|
2107
|
+
let y=g?`Created #${g}: ${t}`:`Created ${(0,l.formatTaskRefForAgent)(u)}: ${t}`
|
|
2087
2108
|
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
|
|
2088
2109
|
if(!t)return{content:[{type:"text",text:"Error: summary is required for done"}],isError:!0}
|
|
2089
2110
|
const{active:r,nextPending:n}=await o(d,f)
|
|
@@ -2094,7 +2115,7 @@ const u=r.sequenceNumber
|
|
|
2094
2115
|
let h=u?`Completed #${u}: ${r.title}`:`Completed ${(0,l.formatTaskRefForAgent)(r.taskId)}: ${r.title}`
|
|
2095
2116
|
if(n)try{await s.updateTaskStatus(n.taskId,"in_progress")
|
|
2096
2117
|
const e=n.sequenceNumber
|
|
2097
|
-
h+=e?`\nStarted #${e}: ${n.title}`:`\nStarted ${(0,l.formatTaskRefForAgent)(n.taskId)}: ${n.title}`}catch(e){
|
|
2118
|
+
h+=e?`\nStarted #${e}: ${n.title}`:`\nStarted ${(0,l.formatTaskRefForAgent)(n.taskId)}: ${n.title}`}catch(e){m.debug("Could not auto-start next task",{taskId:n.taskId,error:(0,i.getErrorMessage)(e)})}else h+="\nAll tasks completed."
|
|
2098
2119
|
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))
|
|
2099
2120
|
if(o){const e=r(o)
|
|
2100
2121
|
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
|
|
@@ -2109,7 +2130,7 @@ l&&await o.updateTaskStatus(l.localId||l.id,"pending"),await o.updateTaskStatus(
|
|
|
2109
2130
|
const u=r(i),h=l?` (paused ${n(r(l))}: ${l.title})`:""
|
|
2110
2131
|
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"})
|
|
2111
2132
|
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
|
|
2112
|
-
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: "+
|
|
2133
|
+
return`[${"in_progress"===e.status?"\u25b6 in_progress":e.status}] #${r}: ${e.title}`})).join("\n")}],...(0,c.alchemyMeta)({kind:"list-tasks"})}}default:return{content:[{type:"text",text:"Unknown operation: "+g}],isError:!0}}}catch(e){return m.error("tasks operation failed",{operation:g,error:(0,i.getErrorMessage)(e)}),{content:[{type:"text",text:"Error: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
|
|
2113
2134
|
const s=t(6688),i=t(8824),a=t(3451),c=t(2272),l=t(4466)},3253(e,exports){"use strict"
|
|
2114
2135
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTimestamp=function(e,t){const r=e instanceof Date?e:new Date(e)
|
|
2115
2136
|
if(isNaN(r.getTime()))return"Invalid date"
|
|
@@ -2163,7 +2184,7 @@ if(0===a)throw Error(`String "${s}" not found`)
|
|
|
2163
2184
|
if(a>1)throw Error(`String "${s}" appears ${a} times (expected exactly 1 in unique mode)`)
|
|
2164
2185
|
o=o.replace(s,i),t.success=!0,t.occurrences=1}else{const e=(o.match(RegExp(r(s),"g"))||[]).length
|
|
2165
2186
|
if(0===e)throw Error(`String "${s}" not found`)
|
|
2166
|
-
o=o.replace(RegExp(r(s),"g"),i),t.success=!0,t.occurrences=e}}catch(e){t.error=(0,
|
|
2187
|
+
o=o.replace(RegExp(r(s),"g"),i),t.success=!0,t.occurrences=e}}catch(e){t.error=(0,g.getErrorMessage)(e)}s.push(t)}return{newContent:o,results:s}}var o,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
2167
2188
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
2168
2189
|
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=[]
|
|
2169
2190
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -2186,7 +2207,7 @@ j.push({type:"file",path:t,fullPath:n,replacements:e.replacements,mode:e.mode||"
|
|
|
2186
2207
|
if(x.length>0&&!r.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
2187
2208
|
for(const e of x)R.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
|
|
2188
2209
|
if(R.length>0&&r.apiClient){const e=R.map((e=>e.documentId))
|
|
2189
|
-
try{await(0,
|
|
2210
|
+
try{await(0,m.ensureDocumentsNotLocked)(e,r.apiClient,y,c,"replace-strings-documents")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2190
2211
|
throw e}}k=d.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
|
|
2191
2212
|
const M=j.length>0?j[0].path:"document-operation",$=await d.validateTaskId(T,M,o,y,c,v.metricsPrefix),O=$?.requestId
|
|
2192
2213
|
let D=null
|
|
@@ -2208,24 +2229,24 @@ let H=0,B=0
|
|
|
2208
2229
|
for(const e of j){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
2209
2230
|
try{if(await l.default.access(e.fullPath),!(await l.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
2210
2231
|
const r=await l.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await n(r,e.replacements,e.mode)
|
|
2211
|
-
t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,o!==r?(await l.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,B++,y.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),H+=t.failedReplacements}catch(r){t.error=(0,
|
|
2232
|
+
t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,o!==r?(await l.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,B++,y.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),H+=t.failedReplacements}catch(r){t.error=(0,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,H+=t.failedReplacements,y.error("File operation failed",{path:e.path,error:t.error})}L.push(t)}for(const e of R){const t={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
2212
2233
|
try{const o=await r.documentFileManager.getDocumentAsFile(e.documentId),s=r.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
2213
2234
|
t.filename=s?.filename
|
|
2214
2235
|
const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
|
|
2215
|
-
t.replacements=c,t.successfulReplacements=c.filter((e=>e.success)).length,t.failedReplacements=c.filter((e=>!e.success)).length,a!==i?(await l.default.writeFile(o,a,"utf8"),r.documentFileManager.markForSync(e.documentId),t.success=!0,B++,y.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),H+=t.failedReplacements}catch(r){t.error=(0,
|
|
2216
|
-
t?.success&&await r.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const U=await d.handleMultiFileGitCommit(T,j,L,B,{operationType:"Replace strings",toolRecordId:b,successField:"successfulReplacements",logger:y,metrics:c,metricsPrefix:"replace_strings"},r),W=d.processMultiFileOperationResults(L,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:
|
|
2217
|
-
try{await s.updateToolRecord(b,{metadata:{path:j.length>0?j[0].path:"document:"+R[0]?.documentId,status:
|
|
2236
|
+
t.replacements=c,t.successfulReplacements=c.filter((e=>e.success)).length,t.failedReplacements=c.filter((e=>!e.success)).length,a!==i?(await l.default.writeFile(o,a,"utf8"),r.documentFileManager.markForSync(e.documentId),t.success=!0,B++,y.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements})):0===t.failedReplacements&&(t.success=!0),H+=t.failedReplacements}catch(r){t.error=(0,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,H+=t.failedReplacements,y.error("Document operation failed",{documentId:e.documentId,error:t.error})}L.push(t)}if(R.length>0)try{for(const e of R){const t=L.find((t=>t.documentId===e.documentId))
|
|
2237
|
+
t?.success&&await r.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const U=await d.handleMultiFileGitCommit(T,j,L,B,{operationType:"Replace strings",toolRecordId:b,successField:"successfulReplacements",logger:y,metrics:c,metricsPrefix:"replace_strings"},r),W=d.processMultiFileOperationResults(L,"successfulReplacements"),{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:Q,overallSuccess:K,successfulFiles:J,failedFiles:Y}=W
|
|
2238
|
+
try{await s.updateToolRecord(b,{metadata:{path:j.length>0?j[0].path:"document:"+R[0]?.documentId,status:K?"completed":"failed",error:K?void 0:V+" operations failed",totalOperations:L.length,successfulFiles:J,failedFiles:Y,operations:N,totalSuccessfulReplacements:Q,totalFailedReplacements:H,operationsWithChanges:B,processingTime:Date.now()-w,userComment:E,...j.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:K?`String replacement completed: ${G}/${L.length} operations successful${j.length>0?" (committed to git)":""}`:`String replacement partially failed: ${V}/${L.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}d.formatMultiFileToolResponse("String Replacement",{successfulOperations:G,failedOperations:V,totalSuccessfulChanges:Q,overallSuccess:K,successfulFiles:J,failedFiles:Y},U,F)
|
|
2218
2239
|
let Z="## String Replacement Results\n\n"
|
|
2219
2240
|
if(r.workspaceManager){const e=r.workspaceManager.getCurrentContext(r.currentSessionId)
|
|
2220
|
-
e.permanentBranch||(Z+=`**Branch:** \`${e.branchName}\`\n\n`)}if(Z+="**Summary:**\n",Z+=`- **Files processed:** ${G+V}\n`,Z+=`- **Successful operations:** ${G}\n`,Z+=`- **Failed operations:** ${V}\n`,Z+=`- **Total replacements:** ${
|
|
2241
|
+
e.permanentBranch||(Z+=`**Branch:** \`${e.branchName}\`\n\n`)}if(Z+="**Summary:**\n",Z+=`- **Files processed:** ${G+V}\n`,Z+=`- **Successful operations:** ${G}\n`,Z+=`- **Failed operations:** ${V}\n`,Z+=`- **Total replacements:** ${Q} successful, ${H} failed\n\n`,U.success&&U.commitHash&&(Z+="**Git Commit:**\n",Z+=`- **Commit Hash:** ${U.commitHash.substring(0,8)}\n`,Z+=`- **Files Committed:** ${U.filesCommitted.length}\n`,U.previousCommitHash&&(Z+=`- **Previous Commit:** ${U.previousCommitHash.substring(0,8)}\n`),Z+="\n"),1===L.length){const e=L[0]
|
|
2221
2242
|
if(Z+=`**Operation:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,"file"===e.type?Z+=`**File:** ${e.path}\n`:(Z+="**Document:** "+e.documentId,e.filename&&(Z+=` (${e.filename})`),Z+="\n"),e.error?Z+=`**Error:** ${e.error}\n`:(Z+=`**Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(Z+=`, ${e.failedReplacements} failed`),Z+="\n"),e.replacements.some((e=>!e.success))){Z+="**Failed Replacement Details:**\n"
|
|
2222
|
-
for(const t of e.replacements.filter((e=>!e.success)))Z+=`- "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}}else{Z+="**Summary:**\n",Z+=`- **Total Operations:** ${L.length}\n`,Z+=`- **Successful:** ${G}\n`,Z+=`- **Failed:** ${V}\n`,Z+=`- **Total Replacements:** ${
|
|
2243
|
+
for(const t of e.replacements.filter((e=>!e.success)))Z+=`- "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}}else{Z+="**Summary:**\n",Z+=`- **Total Operations:** ${L.length}\n`,Z+=`- **Successful:** ${G}\n`,Z+=`- **Failed:** ${V}\n`,Z+=`- **Total Replacements:** ${Q} successful, ${H} failed\n\n`,Z+="**Detailed Results:**\n\n"
|
|
2223
2244
|
for(const e of L){if("file"===e.type?Z+=`### File: ${e.path}\n`:(Z+="### Document: "+e.documentId,e.filename&&(Z+=` (${e.filename})`),Z+="\n"),Z+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error?Z+=`- **Error:** ${e.error}\n`:(Z+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(Z+=`, ${e.failedReplacements} failed`),Z+="\n"),e.replacements.some((e=>!e.success))){Z+="- **Failed Replacement Details:**\n"
|
|
2224
2245
|
for(const t of e.replacements.filter((e=>!e.success)))Z+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}Z+="\n"}}R.length>0&&(Z+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
2225
2246
|
const X=Date.now()-w
|
|
2226
|
-
return y.info("Replace strings operation completed",{duration:X,success:
|
|
2227
|
-
if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),b)try{await s.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,
|
|
2228
|
-
const l=c(t(1943)),d=a(t(5967)),u=t(9860),h=t(5003),p=t(7478),
|
|
2247
|
+
return y.info("Replace strings operation completed",{duration:X,success:K,totalOperations:L.length,successfulOperations:G,failedOperations:V}),c.incrementCounter("replace_strings_total",1,{success:K}),{content:[{type:"text",text:Z}],isError:!K}}catch(t){const r=Date.now()-w
|
|
2248
|
+
if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),b)try{await s.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,g.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,g.getErrorMessage)(t)})}catch(e){}return c.incrementCounter("replace_strings_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,g.getErrorMessage)(t)}],isError:!0}}}
|
|
2249
|
+
const l=c(t(1943)),d=a(t(5967)),u=t(9860),h=t(5003),p=t(7478),m=t(9949),g=t(8824)},3322(e,exports,t){"use strict"
|
|
2229
2250
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
2230
2251
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
2231
2252
|
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=[]
|
|
@@ -2261,13 +2282,13 @@ var h=t(4192)
|
|
|
2261
2282
|
Object.defineProperty(exports,"BaseApiClient",{enumerable:!0,get(){return h.BaseApiClient}})
|
|
2262
2283
|
var p=t(1599)
|
|
2263
2284
|
Object.defineProperty(exports,"SessionRequestAssociationClient",{enumerable:!0,get(){return p.SessionRequestAssociationClient}})
|
|
2264
|
-
var
|
|
2265
|
-
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return
|
|
2266
|
-
var
|
|
2267
|
-
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return
|
|
2285
|
+
var m=t(5187)
|
|
2286
|
+
Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return m.CLISessionClient}})
|
|
2287
|
+
var g=t(6539)
|
|
2288
|
+
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return g.ClientFactory}})
|
|
2268
2289
|
const f=t(6539)
|
|
2269
2290
|
exports.default={ClientFactory:f.ClientFactory}},3416(e,exports){"use strict"
|
|
2270
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.
|
|
2291
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.QUEST_METADATA_KEYS=exports.QUEST_COMPLETION_MODE_DEFAULT=exports.QUEST_COMPLETION_MODES=exports.QUEST_STATUSES=exports.QUEST_STATUS_DRAFT=exports.QUEST_STATUS_CLOSED=exports.QUEST_STATUS_PENDING_REVIEW=exports.QUEST_STATUS_OPEN=exports.QUEST_DEFAULTS=void 0,exports.defaultMinIterations=function(e){return"auto-close"===e?3:1},exports.QUEST_DEFAULTS={tickIntervalSeconds:1800,maxInFlight:1,maxPerDay:24,minIterations:3,consecutiveDoneAudits:0},exports.QUEST_STATUS_OPEN="open",exports.QUEST_STATUS_PENDING_REVIEW="pending_review",exports.QUEST_STATUS_CLOSED="closed",exports.QUEST_STATUS_DRAFT="draft",exports.QUEST_STATUSES=[exports.QUEST_STATUS_DRAFT,exports.QUEST_STATUS_OPEN,exports.QUEST_STATUS_PENDING_REVIEW,exports.QUEST_STATUS_CLOSED],exports.QUEST_COMPLETION_MODES=["auto-close","audit-then-pending"],exports.QUEST_COMPLETION_MODE_DEFAULT="audit-then-pending",exports.QUEST_METADATA_KEYS=["criteria","tickIntervalSeconds","maxInFlight","maxPerDay","minIterations","status","completionMode"]},3420(e,exports,t){"use strict"
|
|
2271
2292
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleGetTaskInformation=async function(e,t,i,a,c){const l=a.child({tool:"get_task_information"})
|
|
2272
2293
|
l.info("Getting task information",{args:e})
|
|
2273
2294
|
const d=c.startTimer("tool_handler_duration")
|
|
@@ -2290,12 +2311,12 @@ const n=e
|
|
|
2290
2311
|
"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()}
|
|
2291
2312
|
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
|
|
2292
2313
|
if(h.requestId)try{const e=i.getRequestClient()
|
|
2293
|
-
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
|
|
2314
|
+
p=await e.getRequest(h.requestId),l.info("Retrieved parent request information",{taskId:r,requestId:h.requestId})}catch(e){l.warn("Failed to retrieve parent request",{error:(0,o.getErrorMessage)(e),taskId:r,requestId:h.requestId})}const m=e=>{if(!e)return"Unknown date"
|
|
2294
2315
|
try{const t=new Date(e)
|
|
2295
|
-
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},m
|
|
2316
|
+
return isNaN(t.getTime())?"Unknown date":t.toLocaleString()}catch(t){return l.warn("Invalid date format: "+e),"Unknown date"}},g=m(h.createdAt),f=m(h.updatedAt),y=h.requestId||h.requestLocalId,w=h.sequenceNumber&&y?(0,s.formatTaskRef)(y,h.sequenceNumber):r,I=(0,s.formatTaskRefForAgent)(w)
|
|
2296
2317
|
let b=`# Task: ${h.title} (${I})\n\n`
|
|
2297
|
-
if(b+=`**Status**: ${h.status}\n`,b+=`**Created**: ${
|
|
2298
|
-
b+="\n## Metadata\n\n",e.lastCommit&&(b+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(b+=`**Completed At**: ${
|
|
2318
|
+
if(b+=`**Status**: ${h.status}\n`,b+=`**Created**: ${g}\n`,b+=`**Updated**: ${f}\n`,h.requestId&&(b+="**Parent Request**: "+h.requestId,b+=p?` (${p.title})\n`:"\n"),h.metadata){const e=h.metadata
|
|
2319
|
+
b+="\n## Metadata\n\n",e.lastCommit&&(b+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(b+=`**Completed At**: ${m(e.completedAt)}\n`),e.completionSummary&&(b+=`**Completion Summary**: ${e.completionSummary}\n`)
|
|
2299
2320
|
const t=["lastCommit","completedAt","completionSummary"]
|
|
2300
2321
|
Object.entries(e).filter((([e])=>!t.includes(e))).forEach((([e,t])=>{b+=`**${e}**: ${t}\n`}))}return b+="\n## Description\n\n",h.description&&h.description.trim().length>0?b+=h.description:b+="No description provided.",d({success:!0}),{content:[{type:"text",text:b}]}}catch(s){l.error("Failed to get task information",{error:s instanceof Error?s.stack:s+"",args:e})
|
|
2301
2322
|
try{const n=i.getToolRecordClient()
|
|
@@ -2333,13 +2354,13 @@ const r=t(6183),n=t(8317)
|
|
|
2333
2354
|
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"
|
|
2334
2355
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2335
2356
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
2336
|
-
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),
|
|
2357
|
+
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),m=t(7888),g=t(4139),f=t(6800),y=t(6539),w=t(8824),I=t(6975),b=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:_})
|
|
2337
2358
|
const S=(0,h.createMetricsCollector)(!0),q=(process.env.REMOTE_SERVER_PORT,process.env.REMOTE_SERVER_HOST,process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com")
|
|
2338
2359
|
E.info("Using remote server URL",{remoteServerUrl:q}),async function(){try{E.info("Finding available port...",{preferredPort:_,baseDir:C,remoteServerUrl:q})
|
|
2339
2360
|
const e=await(0,f.findAvailablePort)(_)
|
|
2340
2361
|
e!==_&&E.info(`Preferred port ${_} is in use, using port ${e} instead`),E.info("Starting HTTP API server...",{port:e,baseDir:C,remoteServerUrl:q})
|
|
2341
|
-
const t=new l.ProjectRegistry(E),r=new u.DefaultProjectFileSystem(E),c=n.default.join(C,
|
|
2342
|
-
E.info(`Checking ${
|
|
2362
|
+
const t=new l.ProjectRegistry(E),r=new u.DefaultProjectFileSystem(E),c=n.default.join(C,g.ALCHEMY_DIR_NAME)
|
|
2363
|
+
E.info(`Checking ${g.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensureDirectoryExists(c)
|
|
2343
2364
|
const h=new b.TokenManager(E,n.default.join(c,"auth-token.json")),k=(await y.ClientFactory.createClient(q,E,S,{tokenManager:h,workingDir:C,alchemyPath:c})).projectClient,v=new I.ProjectClientAdapter(k,E),T=new d.ProjectSynchronizer(E,t,v,r),P=await T.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}})
|
|
2344
2365
|
E.info("Using project",{projectId:P.id,projectName:P.name})
|
|
2345
2366
|
const x=(0,o.default)()
|
|
@@ -2348,7 +2369,7 @@ try{E.info("Creating MCP server instance")
|
|
|
2348
2369
|
const t=await(0,i.createServer)(C,E,S,q,{existingProjectId:P.id})
|
|
2349
2370
|
E.info("MCP server instance created successfully")
|
|
2350
2371
|
const r=t.getContext()
|
|
2351
|
-
E.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(E.info("Adding connection status middleware"),x.use((0,
|
|
2372
|
+
E.info("Got server context",{projectId:r.projectId}),t.getContext()&&t.connectionManager?(E.info("Adding connection status middleware"),x.use((0,m.addConnectionStatusInfo)(t.connectionManager))):E.warn("Unable to add connection status middleware - connection manager not available")
|
|
2352
2373
|
try{const e=P.id
|
|
2353
2374
|
E.info("Setting up project context middleware",{projectId:e}),x.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)(x,t,E,S),x.use((0,p.errorHandler)(E,S)),x.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+""})
|
|
2354
2375
|
let t=!1
|
|
@@ -2392,30 +2413,30 @@ if(i.length>h)break
|
|
|
2392
2413
|
if(i===l){c.push({line:s+1,actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t})
|
|
2393
2414
|
break}}}o+=i.length+1}return c}const p=t.trim()[0]
|
|
2394
2415
|
if(!p)return c
|
|
2395
|
-
let
|
|
2396
|
-
for(;;){if(
|
|
2397
|
-
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`)}
|
|
2398
|
-
const r=e.indexOf(p,
|
|
2416
|
+
let m=0,g=0
|
|
2417
|
+
for(;;){if(g%100==0&&Date.now()-d>o){const r=Date.now()-d
|
|
2418
|
+
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${o}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}g++
|
|
2419
|
+
const r=e.indexOf(p,m)
|
|
2399
2420
|
if(-1===r)break
|
|
2400
2421
|
let i=r+t.length
|
|
2401
2422
|
const u=Math.min(Math.floor(.5*t.length),200),h=Math.min(r+t.length+u,e.length),f=l.length
|
|
2402
2423
|
let y=!1
|
|
2403
2424
|
for(let t=i;h>=t;t++){const o=e.substring(r,t),i=n(o,a)
|
|
2404
2425
|
if(i.length>f)break
|
|
2405
|
-
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),
|
|
2406
|
-
break}}y||(
|
|
2426
|
+
if(i===l){c.push({line:s(e,r),actuallyMatched:o,matchType:"whitespace_normalized",startPos:r,endPos:t}),m=t,y=!0
|
|
2427
|
+
break}}y||(m=r+1)}return c}(e,t,c,u),h.length>0)return h}catch(e){if(e instanceof Error&&e.message.includes("timed out"))throw e}return h=function(e,t,n=100,a){if(r(a))return[]
|
|
2407
2428
|
const c=[],l=o(t),d=Date.now()
|
|
2408
2429
|
if(t.length>500)return i(e,t)
|
|
2409
2430
|
if(!l)return c
|
|
2410
2431
|
const u=t.replace(/\s/g,"")[0],h=l.length
|
|
2411
|
-
let p=0,
|
|
2412
|
-
for(;;){if(
|
|
2413
|
-
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`)}
|
|
2432
|
+
let p=0,m=0
|
|
2433
|
+
for(;;){if(m%100==0&&Date.now()-d>n){const r=Date.now()-d
|
|
2434
|
+
throw Error(`Fuzzy matching timed out after ${r}ms (limit: ${n}ms).\nPattern length: ${t.length} chars, Content length: ${e.length} chars.\nSuggestions:\n 1. Ensure whitespace in pattern matches file exactly (use exact match)\n 2. Break down large replacements into smaller chunks\n 3. Use a text editor to verify the exact text including hidden characters`)}m++
|
|
2414
2435
|
const r=e.indexOf(u,p)
|
|
2415
2436
|
if(-1===r)break
|
|
2416
|
-
const i=r+h,a=Math.min(t.length,300),
|
|
2437
|
+
const i=r+h,a=Math.min(t.length,300),g=Math.min(r+h+a,e.length)
|
|
2417
2438
|
let f=!1
|
|
2418
|
-
for(let t=i;
|
|
2439
|
+
for(let t=i;g>=t;t++){const n=e.substring(r,t),i=o(n)
|
|
2419
2440
|
if(i.length>h)break
|
|
2420
2441
|
if(i===l){c.push({line:s(e,r),actuallyMatched:n,matchType:"whitespace_agnostic",startPos:r,endPos:t}),p=t,f=!0
|
|
2421
2442
|
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))
|
|
@@ -2443,15 +2464,15 @@ let i=d.FileOperationPhase.VALIDATION
|
|
|
2443
2464
|
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}"}
|
|
2444
2465
|
try{const a=e,{path:u}=a
|
|
2445
2466
|
n.info("Getting file info: "+u)
|
|
2446
|
-
const{normalizedPath:
|
|
2467
|
+
const{normalizedPath:m,fullPath:g}=d.validateAndNormalizePath(u,t)
|
|
2447
2468
|
i=d.FileOperationPhase.FILE_WRITE
|
|
2448
|
-
try{await c.default.access(
|
|
2469
|
+
try{await c.default.access(g)}catch(e){throw Error("Path not accessible: "+u)}const f=await c.default.stat(g),y=f.isFile()?l.default.extname(g).slice(1):"",w={path:m,type:f.isDirectory()?"directory":"file",size:f.size,sizeFormatted:(p=f.size,d.formatFileSize(p)),created:r(f.birthtime),modified:r(f.mtime),accessed:r(f.atime),permissions:(h=f.mode,(511&h).toString(8)),isDirectory:f.isDirectory(),isFile:f.isFile(),isSymbolicLink:f.isSymbolicLink(),extension:y},I=["File Information for: "+m,"Type: "+w.type,`Size: ${w.sizeFormatted} (${w.size} bytes)`,"Created: "+w.created,"Modified: "+w.modified,"Accessed: "+w.accessed,"Permissions: "+w.permissions,"Is Directory: "+w.isDirectory,"Is File: "+w.isFile,"Is Symbolic Link: "+w.isSymbolicLink]
|
|
2449
2470
|
w.isFile&&y&&I.push("Extension: "+y)
|
|
2450
2471
|
const b=Date.now()-s
|
|
2451
|
-
return o.recordValue("get_file_info_time",b),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+
|
|
2472
|
+
return o.recordValue("get_file_info_time",b),o.incrementCounter("get_file_info_success",1),n.info("Successfully retrieved file info: "+m,{type:w.type,size:w.size,time:b}),{content:[{type:"text",text:I.join("\n")}]}}catch(t){const r=Date.now()-s
|
|
2452
2473
|
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}
|
|
2453
2474
|
const c=a(t(1943)),l=a(t(6928)),d=i(t(5967)),u=t(8824)},3707(e,exports,t){"use strict"
|
|
2454
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,u,h,p,g
|
|
2475
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuickChange=async function(e,t,u,h,p,m,g){const f=p.child({tool:"quick_edit"}),y=Date.now()
|
|
2455
2476
|
try{const w=h.getRequestClient(),I=h.getTaskClient(),b=h.getFileClient(),k=h.getToolRecordClient(),{title:v,description:C,..._}=e,E=e.comment||v
|
|
2456
2477
|
f.info("Starting quick_edit workflow",{title:v,operationType:t})
|
|
2457
2478
|
let S=!1
|
|
@@ -2462,23 +2483,23 @@ if(!q||!q.id)throw Error("Failed to create request")
|
|
|
2462
2483
|
const T=q.id
|
|
2463
2484
|
let P
|
|
2464
2485
|
f.info("Created request",{requestId:T})
|
|
2465
|
-
try{if(f.debug("Checking for uncommitted user changes before quick-edit branch creation"),u.git)try{const e=await(0,l.commitUserChangesBeforeToolOperation)(u.git,"quick-fix",{requestId:T,taskId:void 0,workspaceManager:u.workspaceManager},p,
|
|
2486
|
+
try{if(f.debug("Checking for uncommitted user changes before quick-edit branch creation"),u.git)try{const e=await(0,l.commitUserChangesBeforeToolOperation)(u.git,"quick-fix",{requestId:T,taskId:void 0,workspaceManager:u.workspaceManager},p,m)
|
|
2466
2487
|
e.userChangesCommitted?f.info("Committed user changes to main before quick-edit branch creation",{requestId:T,commitHash:e.commitHash?.substring(0,8)}):f.debug("No uncommitted changes found, proceeding with quick-edit")}catch(e){f.warn("Failed to commit user changes before quick-edit, proceeding anyway",{requestId:T,error:e instanceof Error?e.message:e+""})}else f.debug("No git instance available, skipping uncommitted changes check")
|
|
2467
2488
|
f.debug("Creating task")
|
|
2468
2489
|
const e=await I.createTask({requestId:T,projectId:u.projectId,title:`Execute ${t} operation`,description:"Quick change: "+v})
|
|
2469
2490
|
if(!e||!e.id)throw Error("Failed to create task")
|
|
2470
2491
|
let C
|
|
2471
|
-
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,b,I,k,w,p,g
|
|
2472
|
-
else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:P,..._,comment:E},u,I,k,w,p,g
|
|
2492
|
+
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,b,I,k,w,p,m,g)
|
|
2493
|
+
else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:P,..._,comment:E},u,I,k,w,p,m,g)
|
|
2473
2494
|
else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
|
|
2474
|
-
C=await(0,i.handleManageFiles)({taskId:P,..._,comment:E||v},u,I,k,w,h,p,g
|
|
2495
|
+
C=await(0,i.handleManageFiles)({taskId:P,..._,comment:E||v},u,I,k,w,h,p,m,g)}if(C.isError){f.error("File operation failed, cleaning up request and task",{requestId:T,taskId:P})
|
|
2475
2496
|
try{await I.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(T,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:T}),u.workspaceManager&&(await u.workspaceManager.cancelRequest(T),f.info("Cleaned up branch/worktree after operation failure",{requestId:T}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:T,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${C.content[0].text}\n\nThe request (${T}) and task have been canceled and cleaned up.`}],isError:!0}}const q=C.content[0].text,x=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
|
|
2476
2497
|
x?f.warn("File operation completed with partial failures",{requestId:T}):f.info("File operation completed successfully"),f.debug("Completing task")
|
|
2477
|
-
try{await(0,a.handleCompleteTask)({taskId:P,summary:`Executed ${t} operation for quick fix: ${v}${x?" (partial success)":""}`},u,h,p,
|
|
2498
|
+
try{await(0,a.handleCompleteTask)({taskId:P,summary:`Executed ${t} operation for quick fix: ${v}${x?" (partial success)":""}`},u,h,p,m),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})
|
|
2478
2499
|
try{await I.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:** ${T}\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")
|
|
2479
2500
|
const j=x?`Quick change completed with partial success: ${v}. Some replacements failed - see details below.`:"Quick change completed: "+v,R=x?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
|
|
2480
2501
|
let M=!1
|
|
2481
|
-
try{const e=await(0,c.handleCompleteRequest)({requestId:T,summary:j,acceptanceEvidence:[{evidence:R}],testVerification:void 0},u,h,p,g
|
|
2502
|
+
try{const e=await(0,c.handleCompleteRequest)({requestId:T,summary:j,acceptanceEvidence:[{evidence:R}],testVerification:void 0},u,h,p,m,g)
|
|
2482
2503
|
if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:T,error:e.content[0].text})
|
|
2483
2504
|
else{try{await w.updateRequest(T,{status:"completed",completionSummary:j}),f.info("Request finalized to completed",{requestId:T})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:T,error:(0,d.getErrorMessage)(e)})}M=!0,f.info("Request completed successfully",{requestId:T})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:T,error:e instanceof Error?e.message:e+""})}if(!M)try{f.info("Attempting direct request completion via API",{requestId:T}),await w.updateRequest(T,{status:"completed",completionSummary:j}),M=!0,f.info("Request completed successfully via direct API call",{requestId:T})}catch(e){return f.error("Direct request completion also failed",{requestId:T,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${T}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const $=Date.now()-y
|
|
2484
2505
|
f.info("Quick fix completed",{requestId:T,duration:$,hasPartialFailure:x})
|
|
@@ -2572,15 +2593,15 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleWriteFile=a
|
|
|
2572
2593
|
let v,C,_=d.FileOperationPhase.VALIDATION
|
|
2573
2594
|
const E={toolName:"write_file",operationName:"write",fileOperationPhase:d.FileOperationPhase.FILE_WRITE,recordType:"write-file",metricsPrefix:"write_file",successMessage:"Successfully wrote content",failureMessage:"Failed to write content"}
|
|
2574
2595
|
try{const n=e
|
|
2575
|
-
let{path:
|
|
2596
|
+
let{path:g,documentId:S,content:q,format:T,append:P,comment:x}=n
|
|
2576
2597
|
Array.isArray(q)&&(q=q.join("\n"))
|
|
2577
2598
|
const{enforceActiveTask:j}=await Promise.resolve().then(t.bind(t,3451)),R=await j(r,o,f,e.taskId)
|
|
2578
2599
|
if("errorResult"in R)return R.errorResult
|
|
2579
|
-
const{taskId:M}=R,$=!!S,O=!!
|
|
2580
|
-
I.info("Writing content to "+($?"document":"file"),{taskId:M,filePath:O?
|
|
2600
|
+
const{taskId:M}=R,$=!!S,O=!!g
|
|
2601
|
+
I.info("Writing content to "+($?"document":"file"),{taskId:M,filePath:O?g:void 0,documentId:$?S:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:T,append:P,comment:x})
|
|
2581
2602
|
let D,A,F,N="",z=!1,L=!1
|
|
2582
|
-
const H=O?
|
|
2583
|
-
if($){if(r.apiClient)try{await(0,
|
|
2603
|
+
const H=O?g:void 0
|
|
2604
|
+
if($){if(r.apiClient)try{await(0,m.ensureDocumentNotLocked)(S,r.apiClient,I,y,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2584
2605
|
throw e}if(!r.documentFileManager)throw Error("Document file manager not available")
|
|
2585
2606
|
N=await r.documentFileManager.getDocumentAsFile(S)
|
|
2586
2607
|
const e=r.documentFileManager.getCachedDocumentInfo(S)
|
|
@@ -2590,21 +2611,21 @@ let G=null
|
|
|
2590
2611
|
O&&W&&(G=await d.validateWorkItemStates(M,B,o,i,r,I,y,E.metricsPrefix))
|
|
2591
2612
|
let V={taskPromoted:!1,requestPromoted:!1}
|
|
2592
2613
|
O&&W&&G&&(V=await d.autoPromoteTaskStatus(M,U.status,W,G.request?.status,B,o,i,I,y,E.metricsPrefix),V.taskPromoted&&I.info("Auto-promoted task to in_progress for file operation",{taskId:M,requestId:W,previousStatus:U.status,newStatus:V.newTaskStatus,triggeringOperation:"write_file"}))
|
|
2593
|
-
const
|
|
2594
|
-
if(!
|
|
2595
|
-
if(
|
|
2614
|
+
const Q=await d.ensureCorrectWorkspaceContext({taskPromoted:V.taskPromoted,requestId:W,context:r,operation:"write_file",logger:I,metrics:y,metricsPrefix:E.metricsPrefix,requireRequestContext:O})
|
|
2615
|
+
if(!Q.success)throw Error(Q.error)
|
|
2616
|
+
if(Q.switched&&I.info("Workspace context successfully established",{requestId:W,branchName:Q.branchName,operation:"write_file"}),O&&H){const e=d.validateAndNormalizePath(H,r)
|
|
2596
2617
|
D=e.normalizedPath,A=e.fullPath,N=A
|
|
2597
2618
|
try{await c.default.access(A),L=!0}catch{L=!1,z=!0}I.debug("Path validated with correct workspace context",{rawPath:H,normalizedPath:D,fullPath:A,workspaceBasePath:r.workspaceManager?.getCurrentContext(r.currentSessionId).basePath})}if($&&W)try{await(0,h.validateRequestStatusForDocumentOperation)(W,i,I,y,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
2598
2619
|
throw e}_=d.FileOperationPhase.RECORD_CREATION,y.incrementCounter("write_file_phase",1,{phase:_})
|
|
2599
|
-
const{toolRecordId:
|
|
2600
|
-
let
|
|
2601
|
-
if(v=
|
|
2602
|
-
else
|
|
2603
|
-
let Y=
|
|
2620
|
+
const{toolRecordId:K}=await d.createFileOperationRecords(M,W,r.projectId,E.recordType,B,{operationType:$?"document":"file",documentId:$?S:void 0,documentFilename:F,filePath:O?D:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:T||"text",append:P||!1,wasFileCreated:!L,userComment:x},o,s,I,y,E.metricsPrefix,w)
|
|
2621
|
+
let J
|
|
2622
|
+
if(v=K,C=K,_=E.fileOperationPhase,y.incrementCounter("write_file_phase",1,{phase:_}),"json"===T)if("string"==typeof q)try{JSON.parse(q),J=q}catch(e){throw new u.ValidationError("Content is not valid JSON")}else J=JSON.stringify(q,null,2)
|
|
2623
|
+
else J="string"==typeof q?q:JSON.stringify(q,null,2)
|
|
2624
|
+
let Y=J
|
|
2604
2625
|
if(O&&r.git)try{I.debug("[WRITE-FILE] Checking for user changes before write operation")
|
|
2605
2626
|
const e=await(0,p.commitUserChangesBeforeToolOperation)(r.git,"write_file",{requestId:r.workspaceManager?.getCurrentContext(r.currentSessionId)?.requestId,taskId:M},I,y)
|
|
2606
2627
|
e.userChangesCommitted&&(I.debug("[WRITE-FILE] User changes committed before write operation",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),I.info("User changes committed before write-file operation",{taskId:M,path:D,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){I.debug("[WRITE-FILE] Pre-tool commit failed, continuing with write",{error:e instanceof Error?e.message:e+""}),I.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")
|
|
2607
|
-
if(I.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:N}),P&&L)try{Y=await c.default.readFile(N,"utf8")+
|
|
2628
|
+
if(I.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:N}),P&&L)try{Y=await c.default.readFile(N,"utf8")+J}catch(e){I.warn("Failed to read existing content for append",{error:e})}const Z=a.default.dirname(N)
|
|
2608
2629
|
if(await c.default.mkdir(Z,{recursive:!0}),await c.default.writeFile(N,Y,"utf8"),I.info("Content written successfully",{path:O?D:"document:"+S,finalLength:Y.length,append:P,wasCreated:z}),$){r.documentFileManager.markForSync(S)
|
|
2609
2630
|
try{await r.documentFileManager.syncDocument(S),I.info("Document synced successfully",{documentId:S})}catch(e){I.warn("Failed to sync document immediately",{documentId:S,error:e})}}let X,ee,te=null,re=!1
|
|
2610
2631
|
if(O){if(_=d.FileOperationPhase.GIT_COMMIT,y.incrementCounter("write_file_phase",1,{phase:_}),r.workspaceManager){const e=r.workspaceManager.getCurrentContext(r.currentSessionId)
|
|
@@ -2615,15 +2636,15 @@ const oe=Date.now()
|
|
|
2615
2636
|
I.info("Write operation completed successfully",{duration:oe-k,path:O?D:"document:"+S,contentLength:Y.length,wasCreated:z}),b({tool:"write_file",success:!0}),y.incrementCounter("write_file_total",1,{success:!0})
|
|
2616
2637
|
const se=r.workspaceManager?.consumeLargeFileWarning(r.currentSessionId)
|
|
2617
2638
|
return se&&(ne+=se),{content:[{type:"text",text:ne}],...(0,l.alchemyMeta)({kind:"write-file",toolRecordId:C})}}catch(t){const r=Date.now()-k
|
|
2618
|
-
if(I.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,
|
|
2619
|
-
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),
|
|
2639
|
+
if(I.error("Write operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:_}),C)try{await s.updateToolRecord(C,{metadata:{path:e?.path,status:"failed",error:(0,g.getErrorMessage)(t),phase:_,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,g.getErrorMessage)(t)})}catch(e){}return b({tool:"write_file",success:!1}),y.incrementCounter("write_file_errors",1,{phase:_}),{content:[{type:"text",text:"\u274c **Write Operation Failed:** "+(0,g.getErrorMessage)(t)}],isError:!0}}}
|
|
2640
|
+
const a=i(t(6928)),c=i(t(1943)),l=t(2272),d=s(t(5967)),u=t(9860),h=t(5003),p=t(7478),m=t(9949),g=t(8824)},4139(e,exports){"use strict"
|
|
2620
2641
|
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"
|
|
2621
2642
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=exports.TasksSchema=void 0
|
|
2622
2643
|
const r=t(1569),n=t(3247)
|
|
2623
2644
|
exports.TasksSchema=r.z.object({operation:r.z.enum(["create","done","list","current","start"]).describe("Operation to perform:\n\u2022 create - Create a new task (auto-starts if no other task is in_progress)\n\u2022 done - Complete the active (in_progress) task with a summary; auto-starts the next pending task\n\u2022 current - Show only the active (in_progress) task\n\u2022 start - Switch which task is active (pauses any currently in_progress task back to pending)\n\u2022 list - List all tasks for the current request"),title:r.z.string().optional().describe("Task title (required for create)"),description:r.z.string().optional().describe("Task description (required for create)"),summary:r.z.string().optional().describe("Completion summary (required for done)"),taskId:r.z.string().optional().describe("Task to start (required for start). Accepts short forms #01 / 01 / 1 or canonical req######+#NN.")}),exports.def={name:"tasks",description:"Manage tasks within your current request.\n\n\u2022 create { title, description } \u2014 creates a task. First task auto-starts.\n\u2022 done { summary } \u2014 completes the active task. Next pending task auto-starts.\n\u2022 current \u2014 shows just the active task (the one your file edits will attach to).\n\u2022 start { taskId } \u2014 switch which pending task is active. Pauses the current active task.\n\u2022 list \u2014 shows all tasks and their status.\n\nNo requestId needed \u2014 resolved automatically from your session. taskId only required for start (accepts short forms like #01 / 01 / 1).",schema:exports.TasksSchema,annotations:{title:"Tasks",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleTasks)(e,t.context,t.apiClient,t.logger,t.metrics,t.cliOrigin)}}},4165(e,exports,t){"use strict"
|
|
2624
2645
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2625
2646
|
const r=t(6183),n=t(4648)
|
|
2626
|
-
exports.def={name:"request_operations",description:"Perform operations on existing requests.\n\nOperations:\n\u2022 complete - Begin completion: provide summary, get criteria keys for verification\n\u2022 verify-criteria - Verify acceptance criteria with evidence per key (triggers merge when all verified)\n\u2022 finalize - Approve and merge a request that is ready for review\n\u2022 approve - Approve a pending request so work can begin\n\u2022 revert - Completely revert a completed request, undoing all changes\n\u2022 get-info - Get comprehensive request information\n\u2022 list - List and filter requests\n\u2022 delete-empty - Delete a request that has no tasks (safe cleanup for mistaken or obsolete requests)\n\nCompletion is two-phase: first call complete with a summary, then call verify-criteria with evidence for each criterion key.\n\nNote: To create a new request, use the separate create-request tool.",schema:r.RequestOperationsSchema,annotations:{title:"Request Operations",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleRequestOperations)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},4192(e,exports,t){"use strict"
|
|
2647
|
+
exports.def={name:"request_operations",description:"Perform operations on existing requests.\n\nOperations:\n\u2022 complete - Begin completion: provide summary, get criteria keys for verification\n\u2022 verify-criteria - Verify acceptance criteria with evidence per key (triggers merge when all verified)\n\u2022 finalize - Approve and merge a request that is ready for review\n\u2022 approve - Approve a pending request so work can begin\n\u2022 revert - Completely revert a completed request, undoing all changes\n\u2022 get-info - Get comprehensive request information\n\u2022 list - List and filter requests. Filters: type, status, dateFrom/dateTo, planDocumentId (narrow to one plan), questDocumentId (narrow to one quest), plus pagination + sort.\n\u2022 search - Full-text search across title/description/criteria with the same filters.\n\u2022 delete-empty - Delete a request that has no tasks (safe cleanup for mistaken or obsolete requests)\n\nCompletion is two-phase: first call complete with a summary, then call verify-criteria with evidence for each criterion key.\n\nNote: To create a new request, use the separate create-request tool.",schema:r.RequestOperationsSchema,annotations:{title:"Request Operations",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleRequestOperations)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},4192(e,exports,t){"use strict"
|
|
2627
2648
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.BaseApiClient=void 0
|
|
2628
2649
|
const r=t(7163)
|
|
2629
2650
|
exports.BaseApiClient=class{constructor(e,t,n,o,s){this.failureCount=0,this.circuitState="closed",this.circuitResetTimeout=null,this.baseUrl=e,this.logger=t,this.metrics=n,this.authToken=o,this.options={retryAttempts:3,retryDelay:1e3,timeout:1e4,circuitBreakerThreshold:10,circuitBreakerResetTime:1e4,...s},this.logger.debug("BaseApiClient constructor options:",{providedOptions:s?JSON.stringify(s):"undefined",mergedOptions:JSON.stringify(this.options)})
|
|
@@ -2666,7 +2687,10 @@ throw void 0!==r&&500>r||this.incrementFailureCount(),this.logger.error(`API req
|
|
|
2666
2687
|
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
|
|
2667
2688
|
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)
|
|
2668
2689
|
const e=this.options.circuitBreakerResetTime||5e3
|
|
2669
|
-
this.circuitResetTimeout=setTimeout((()=>{this.circuitState="half-open",this.logger.info("Circuit breaker half-open, next request will probe")}),e)}async get(e,t,r){return this.requestWithRetry("GET",e,void 0,r,t)}async post(e,t,r){return this.requestWithRetry("POST",e,t,r)}async put(e,t,r){return this.requestWithRetry("PUT",e,t,r)}async delete(e,t){return this.requestWithRetry("DELETE",e,void 0,t)}async patch(e,t,r){return this.requestWithRetry("PATCH",e,t,r)}}},
|
|
2690
|
+
this.circuitResetTimeout=setTimeout((()=>{this.circuitState="half-open",this.logger.info("Circuit breaker half-open, next request will probe")}),e)}async get(e,t,r){return this.requestWithRetry("GET",e,void 0,r,t)}async post(e,t,r){return this.requestWithRetry("POST",e,t,r)}async put(e,t,r){return this.requestWithRetry("PUT",e,t,r)}async delete(e,t){return this.requestWithRetry("DELETE",e,void 0,t)}async patch(e,t,r){return this.requestWithRetry("PATCH",e,t,r)}}},4206(e,exports,t){"use strict"
|
|
2691
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2692
|
+
const r=t(6183),n=t(1719)
|
|
2693
|
+
exports.def={name:"quest_set_criteria_statuses",description:"Update the status (and optional evidence) of one or more quest criteria (alchemist-only).\n\nUse this when a structured criteria checklist is present on a quest (metadata.criteria is a non-empty array) and you've verified or unverified one or more items.\n\nRequired: questId, updates (array of at least one { id, status, evidence? }).\n\n- id must match an existing criterion in metadata.criteria; unknown ids return an error listing the valid ids so you can correct.\n- status is 'verified' or 'unverified'.\n- evidence is optional free text (file path, request id, test name, command output, etc.) noting why the status changed.\n\nNotes:\n- Updates merge into the existing item (description and other fields preserved); only status and evidence change.\n- This tool only touches criterion statuses. It does NOT bump the audit streak or flip the quest status. Call quest_audit_complete separately when you believe the whole quest is done \u2014 that gate additionally requires all structured criteria to be verified.\n- Safe to call across many ticks as you verify items one by one. Spawning a request under the quest still resets the audit streak via the createRequest hook; per-criterion verification does not.",schema:r.QuestSetCriteriaStatusesSchema,annotations:{title:"Quest Set Criteria Statuses",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},handler(e,t){return(0,n.handleQuestSetCriteriaStatuses)(e,t.context,t.apiClient,t.logger,t.metrics)}}},4221(e,exports,t){"use strict"
|
|
2670
2694
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
2671
2695
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
2672
2696
|
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=[]
|
|
@@ -2684,8 +2708,8 @@ if(!c.startsWith(s+a.sep))return{content:[{type:"text",text:"\u274c Invalid file
|
|
|
2684
2708
|
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]
|
|
2685
2709
|
if(!h)return{content:[{type:"text",text:"\u274c Unsupported image type: ."+u}],isError:!0}
|
|
2686
2710
|
if("svg"===u)return{content:[{type:"text",text:`**Asset: ${r}**\n\n\`\`\`svg\n${await i.readFile(c,"utf-8")}\n\`\`\``}]}
|
|
2687
|
-
const p=await i.readFile(c),
|
|
2688
|
-
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:
|
|
2711
|
+
const p=await i.readFile(c),m=p.toString("base64")
|
|
2712
|
+
return o.info("Asset viewed",{filename:r,size:p.length}),{content:[{type:"text",text:`**Asset: ${r}** (${(p.length/1024).toFixed(1)} KB)`},{type:"image",data:m,mimeType:h}]}}catch(e){return o.error("Failed to view asset",{error:(0,c.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to view asset:** "+(0,c.getErrorMessage)(e)}],isError:!0}}}
|
|
2689
2713
|
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+"'")
|
|
2690
2714
|
throw t.code="MODULE_NOT_FOUND",t}e.keys=()=>[],e.resolve=e,e.id=4245,module.exports=e},4394(e,exports,t){"use strict"
|
|
2691
2715
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.getOrCreateHealthCheckManager=function(e,t,o,s={}){const i=e.endsWith("/")?e.slice(0,-1):e,a=n.get(i)
|
|
@@ -2704,20 +2728,20 @@ const a=await r.updateDocument(e.planId,i),c=a.localId||a.id
|
|
|
2704
2728
|
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}}}
|
|
2705
2729
|
const r=t(8824)},4425(e,exports,t){"use strict"
|
|
2706
2730
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2707
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,h,p,g,
|
|
2731
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,h,p,m,g,f){const y=p.startTimer("tool_execution_time"),w=e.operation||"run"
|
|
2708
2732
|
try{const p=await r.proxyGet(`/api/projects/${t.projectId}/check-commands`),I=p?.data||p||[],b=I.filter((e=>e.isActive)),k=I.filter((e=>!e.isActive))
|
|
2709
2733
|
if("list"===w){if(0===I.length)return y({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"})}
|
|
2710
2734
|
const e=[]
|
|
2711
|
-
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:""}`)))),k.length>0&&(e.push(`\n## Pending Approval (${k.length})\n`),e.push(...k.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'),y({success:!0}),{content:[{type:"text",text:e.join("\n")}],...(0,c.alchemyMeta)({kind:"list-commands"})}}if("setup"===w){const t=
|
|
2735
|
+
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:""}`)))),k.length>0&&(e.push(`\n## Pending Approval (${k.length})\n`),e.push(...k.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'),y({success:!0}),{content:[{type:"text",text:e.join("\n")}],...(0,c.alchemyMeta)({kind:"list-commands"})}}if("setup"===w){const t=g?.sessionId,n=t?await d.sessionIdentity.getSessionRequestId(r,h,t):void 0
|
|
2712
2736
|
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)})
|
|
2713
2737
|
if(!r.ok){const e=await r.text().catch((()=>""))
|
|
2714
2738
|
return y({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()
|
|
2715
2739
|
return o.success&&o.data?(y({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"})}):(y({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(o.error||"unknown error")}],isError:!0})}catch(e){return y({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}if("register"===w){if(!Array.isArray(e.commands)||0===e.commands.length)return y({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}
|
|
2716
|
-
const n=function(e){return e?.sessionId||d.sessionIdentity.getIdentity()?.sessionId||null}(
|
|
2740
|
+
const n=function(e){return e?.sessionId||d.sessionIdentity.getIdentity()?.sessionId||null}(g)
|
|
2717
2741
|
if(!n)return y({success:!1,error:"no_session"}),{content:[{type:"text",text:"Error: no session context available to attribute approval notifications."}],isError:!0}
|
|
2718
2742
|
const o=new Set(I.map((e=>e.name.toLowerCase()))),s=[],i=[]
|
|
2719
2743
|
for(const t of e.commands){const e=t.name?.trim(),r=t.command?.trim(),n=t.description?.trim()
|
|
2720
|
-
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:
|
|
2744
|
+
e&&r&&n?o.has(e.toLowerCase())?i.push({name:e,reason:"already exists"}):(o.add(e.toLowerCase()),s.push({name:e,command:r,description:n,cwd:t.cwd?.trim(),timeout:t.timeout})):i.push({name:e||"(unnamed)",reason:"missing required fields (name, command, description)"})}const a=await Promise.all(s.map((async e=>{try{const n=await r.proxyPost(`/api/projects/${t.projectId}/check-commands`,{name:e.name,command:e.command,description:e.description,timeout:e.timeout||60,cwd:e.cwd||void 0,addedBySessionId:g?.sessionId,isActive:!1}),o=n?.data?.id||n?.id
|
|
2721
2745
|
if(!o)throw Error("command create returned no id")
|
|
2722
2746
|
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))
|
|
2723
2747
|
for(const e of a)e.ok||i.push({name:e.proposal.name,reason:e.error})
|
|
@@ -2727,8 +2751,8 @@ if(!e)throw Error("session message client unavailable")
|
|
|
2727
2751
|
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"})
|
|
2728
2752
|
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)}))))))
|
|
2729
2753
|
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}),y({success:!0})
|
|
2730
|
-
const
|
|
2731
|
-
return p.length>0&&(
|
|
2754
|
+
const m=[`## Submitted ${p.length} command${1===p.length?"":"s"} for approval${i.length?`, ${i.length} skipped`:""}`]
|
|
2755
|
+
return p.length>0&&(m.push("","### Pending approval"),m.push(...p.map((e=>`- **${e}**`))),m.push("","The user will see one approval notification per command. Approved commands become runnable; denied ones are removed.")),i.length>0&&(m.push("",`### Skipped (${i.length})`),m.push(...i.map((e=>`- **${e.name}** \u2014 ${e.reason}`)))),m.push("",'Use `commands({ operation: "list" })` to see status.'),{content:[{type:"text",text:m.join("\n")}],...(0,c.alchemyMeta)({kind:"register-commands"})}}if("remove"===w){if(!e.name?.trim())return y({success:!1,error:"missing_name"}),{content:[{type:"text",text:"Error: `name` is required when removing a command."}],isError:!0}
|
|
2732
2756
|
const n=I.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2733
2757
|
if(!n)return y({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.`}],isError:!0}
|
|
2734
2758
|
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),h.info("Removed command",{name:n.name,id:n.id}),y({success:!0}),{content:[{type:"text",text:`Removed command **${n.name}**.`}]}}catch(e){return y({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(", ")
|
|
@@ -2739,11 +2763,11 @@ e.grep&&(C=`${C} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
|
|
|
2739
2763
|
const _=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,E=v.cwd?s.default.resolve(_,v.cwd):_,S=s.default.join(_,a.ALCHEMY_DIR_NAME,"command-logs"),q=`${v.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,T=s.default.join(S,q+".log")
|
|
2740
2764
|
let P=null
|
|
2741
2765
|
try{i.default.mkdirSync(S,{recursive:!0}),P=i.default.createWriteStream(T,{flags:"w"}),P.write(`# ${(new Date).toISOString()} starting: ${C}\n# cwd: ${E}\n# timeout: ${v.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:v.name,command:C,cwd:E,configuredCwd:v.cwd,logPath:T})
|
|
2742
|
-
const x=await(0,n.runTrackedShellWithHeartbeat)(C,{cwd:E,timeoutMs:1e3*(v.timeout||60),env:{...process.env,FORCE_COLOR:"0"},onChunk:P?(e,t)=>{P?.write(t)}:void 0},{id:q,name:v.name,sessionId:
|
|
2766
|
+
const x=await(0,n.runTrackedShellWithHeartbeat)(C,{cwd:E,timeoutMs:1e3*(v.timeout||60),env:{...process.env,FORCE_COLOR:"0"},onChunk:P?(e,t)=>{P?.write(t)}:void 0},{id:q,name:v.name,sessionId:g?.sessionId,logPath:T},f)
|
|
2743
2767
|
P&&(P.write(`\n# exit: ${x.exitCode}${x.timedOut?" (timed out)":""}\n`),P.end())
|
|
2744
2768
|
const{stdout:j,stderr:R,exitCode:M,timedOut:$}=x,{output:O,truncatedNote:D,logFooter:A}=(0,o.formatCommandOutput)(j,R,{invocationId:q}),F=$?"TIMEOUT":null
|
|
2745
2769
|
let N
|
|
2746
|
-
if(
|
|
2770
|
+
if(m)try{const e=await m.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:v.name,command:C,exitCode:M,timedOut:$,status:$?"timeout":0===M?"success":"failed",timestamp:(new Date).toISOString()}})
|
|
2747
2771
|
N=e?.id}catch(e){h.debug("Failed to create tool record for command run",{error:(0,l.getErrorMessage)(e)})}return y({success:!0}),{content:[{type:"text",text:`## ${v.name}${F?` \u2014 ${F} (killed after ${v.timeout}s)`:""}\n\`\`\`\n$ ${C}\n${O}\n\`\`\`${D}\n\nExit code: ${M}\n${A} (pass to read_files or search)`}],...(0,c.alchemyMeta)({kind:"run-command",toolRecordId:N})}}catch(e){return y({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
2748
2772
|
const n=t(1375),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"
|
|
2749
2773
|
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
|
|
@@ -2768,9 +2792,9 @@ return e}
|
|
|
2768
2792
|
const o=t(6688),s=t(8955)
|
|
2769
2793
|
exports.TASK_REF_PATTERN=/^(req\d{6})#(\d+)$/,exports.TASK_REF_SHORT_PATTERN=/^#?(\d{1,3})$/},4592(e,exports,t){"use strict"
|
|
2770
2794
|
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")
|
|
2771
|
-
try{const c=e,{operation:
|
|
2795
|
+
try{const c=e,{operation:m,sessionId:g}=c
|
|
2772
2796
|
let f
|
|
2773
|
-
switch(h.info("Processing planner_ops",{operation:
|
|
2797
|
+
switch(h.info("Processing planner_ops",{operation:m,sessionId:g}),m){case"request":{const e=await async function(e,t,r){if(!e)return"ask"
|
|
2774
2798
|
try{const s=r?.sessionId||o.sessionIdentity.getIdentity()?.sessionId
|
|
2775
2799
|
if(!s)return"ask"
|
|
2776
2800
|
const i=e.getCLISessionClient()
|
|
@@ -2789,14 +2813,14 @@ if(t&&e){const r=await o.sessionIdentity.getParentSessionId(e,d,h),n=c.descripti
|
|
|
2789
2813
|
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}}})}
|
|
2790
2814
|
break}const r="auto-planner"
|
|
2791
2815
|
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
|
|
2792
|
-
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)(
|
|
2816
|
+
f.content[0].text=`Planning mode: ${e} (agent: ${r}). Planning is running in the background \u2014 continue with your other work.\n${t}`}break}case"check-status":f=await(0,s.handleCheckStatus)(g,t,h,d)
|
|
2793
2817
|
break
|
|
2794
2818
|
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??""
|
|
2795
2819
|
if(p.trim()||y.trim()){const e=[]
|
|
2796
2820
|
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."}]}
|
|
2797
2821
|
break
|
|
2798
|
-
default:throw new r.ValidationError("Unknown operation: "+
|
|
2799
|
-
const y=a[
|
|
2822
|
+
default:throw new r.ValidationError("Unknown operation: "+m)}p({success:!0}),l.incrementCounter(`planner_ops_${m}_success`,1)
|
|
2823
|
+
const y=a[m]??"planner-request"
|
|
2800
2824
|
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}}}
|
|
2801
2825
|
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"
|
|
2802
2826
|
async function r(e,r={}){const{spawn:n}=await Promise.resolve().then(t.t.bind(t,5317,23))
|
|
@@ -2824,10 +2848,10 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
2824
2848
|
var t={}
|
|
2825
2849
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2826
2850
|
return o(t,e),t})
|
|
2827
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,r,n,o,s,u,h){const p=s.child({tool:"file_recover"}),
|
|
2828
|
-
try{const
|
|
2829
|
-
return p.info("Recovering file to previous version",{taskId:b,filePath:f,commitHash:y,createBackup:w}),await async function(e,t,r,n,o,s,u,h,p,g
|
|
2830
|
-
try{const{normalizedPath:y,fullPath:w}=c.validateAndNormalizePath(t,o),I=await c.validateTaskId(e,y,s.getTaskClient(),h,p,"file-recover"),{toolRecordId:b}=await c.createFileOperationRecords(e,I?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),u,h,p,"file-recover",
|
|
2851
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileRecover=async function(e,r,n,o,s,u,h){const p=s.child({tool:"file_recover"}),m=u.startTimer("tool_execution_time"),g=Date.now()
|
|
2852
|
+
try{const m=e,{path:f,commitHash:y,createBackup:w}=m,{resolveActiveTaskId:I}=await Promise.resolve().then(t.bind(t,3451)),b=e.taskId||await I(r,n,s)||"untracked"
|
|
2853
|
+
return p.info("Recovering file to previous version",{taskId:b,filePath:f,commitHash:y,createBackup:w}),await async function(e,t,r,n,o,s,u,h,p,m,g){let f
|
|
2854
|
+
try{const{normalizedPath:y,fullPath:w}=c.validateAndNormalizePath(t,o),I=await c.validateTaskId(e,y,s.getTaskClient(),h,p,"file-recover"),{toolRecordId:b}=await c.createFileOperationRecords(e,I?.requestId,o.projectId,"file-recover",y,{operationType:"file",filePath:y,commitHash:r,createBackup:n},s.getTaskClient(),u,h,p,"file-recover",g)
|
|
2831
2855
|
f=b
|
|
2832
2856
|
let k,v=!1
|
|
2833
2857
|
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
|
|
@@ -2839,12 +2863,12 @@ if(t.includes("does not exist")||t.includes("not found")||t.includes("Path"))thr
|
|
|
2839
2863
|
throw Error(`Failed to retrieve file '${y}' from commit '${r}': ${t}`)}await a.writeFile(w,_,"utf8")
|
|
2840
2864
|
let E={}
|
|
2841
2865
|
try{const t=`Recover ${y} from ${r.substring(0,8)}`
|
|
2842
|
-
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()-
|
|
2866
|
+
E=await c.commitToGit(e,y,f,f,t,o,h,p,"file-recover"),h.info("Recovery committed via shared utility",{path:y,sourceCommitHash:r,newCommitHash:E.commitHash?.substring(0,8),commitMessage:t})}catch(e){h.warn("Failed to commit recovery via shared utility",{error:e})}if(f)try{await u.updateToolRecord(f,{metadata:{path:y,status:"completed",recoveredLength:_.length,hadBackup:n&&v,backupPath:k,wasFileCreated:!v,processingTime:Date.now()-m,...E.commitHash&&{commitHash:E.commitHash,previousCommitHash:E.previousCommitHash||void 0}},note:"File recovered successfully from "+r.substring(0,8)})}catch(e){h.warn("Failed to update tool record",{recordError:e})}const S=v?"recovered":"created from recovery"
|
|
2843
2867
|
let q=`\u2705 **File ${S.charAt(0).toUpperCase()+S.slice(1)} Successfully**\n\n`
|
|
2844
|
-
return q+=`**File:** ${y}\n`,q+=`**Recovered from:** ${r.substring(0,8)}\n`,q+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(q+=`**Backup created:** ${i.basename(k)}\n`),q+="**Git status:** Recovery committed\n",q+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",h.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-
|
|
2845
|
-
return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),
|
|
2868
|
+
return q+=`**File:** ${y}\n`,q+=`**Recovered from:** ${r.substring(0,8)}\n`,q+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(q+=`**Backup created:** ${i.basename(k)}\n`),q+="**Git status:** Recovery committed\n",q+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",h.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-m}),p.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:q}]}}catch(e){throw e}}(b,f,y,w,r,n,o,p,u,g,h)}catch(e){const t=Date.now()-g
|
|
2869
|
+
return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),m({tool:"file_recover",success:!1}),u.incrementCounter("file_recover_errors",1),{content:[{type:"text",text:"\u274c **Recovery Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
2846
2870
|
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"
|
|
2847
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,t,p,g,
|
|
2871
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,t,p,m,g,f){const y=m.child({tool:"request_operations"})
|
|
2848
2872
|
try{const w=e
|
|
2849
2873
|
let{requestId:I}=w
|
|
2850
2874
|
const{operation:b}=w
|
|
@@ -2852,21 +2876,21 @@ if("list"!==b&&"search"!==b&&!I){const e=await(0,a.resolveRequestIdOrError)(p,y,
|
|
|
2852
2876
|
if(!e.ok)return e.errorResult
|
|
2853
2877
|
I=e.requestId}switch(y.info("Processing request operation",{requestId:I,operation:b}),b){case"complete":{y.info("Routing to complete-request handler")
|
|
2854
2878
|
const e={requestId:I,summary:w.complete.summary,skipTestsReason:w.complete.skipTestsReason,skipTests:w.complete.skipTests}
|
|
2855
|
-
return(0,u.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,t,p,g,
|
|
2879
|
+
return(0,u.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,t,p,m,g,f),h.complete)}case"merge":return y.info("Routing to merge handler"),(0,u.withAlchemyKind)(await(0,l.handleMergeRequest)({requestId:I,verifications:w.merge?.verifications||[]},t,p,m,g,f),h.merge)
|
|
2856
2880
|
case"approve":{y.info("Routing to approve-request handler")
|
|
2857
2881
|
const e={requestId:I}
|
|
2858
|
-
return(0,u.withAlchemyKind)(await(0,c.handleApproveRequest)(e,t,p,g,
|
|
2882
|
+
return(0,u.withAlchemyKind)(await(0,c.handleApproveRequest)(e,t,p,m,g,f),h.approve)}case"revert":{y.info("Routing to revert-request handler")
|
|
2859
2883
|
const e={requestId:I,reason:w.revert.reason,confirmDestructive:w.revert.confirmDestructive}
|
|
2860
|
-
return(0,u.withAlchemyKind)(await(0,n.handleRevertRequest)(e,t,p,g
|
|
2884
|
+
return(0,u.withAlchemyKind)(await(0,n.handleRevertRequest)(e,t,p,m,g),h.revert)}case"get-info":{y.info("Routing to get-request-information handler")
|
|
2861
2885
|
const e={requestId:I}
|
|
2862
|
-
return(0,u.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,t,p,g
|
|
2886
|
+
return(0,u.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,t,p,m,g),h["get-info"])}case"list":{y.info("Routing to list-requests handler")
|
|
2863
2887
|
const e={filters:w.list?.filters}
|
|
2864
|
-
return(0,u.withAlchemyKind)(await(0,s.handleListRequests)(e,t,p,g
|
|
2888
|
+
return(0,u.withAlchemyKind)(await(0,s.handleListRequests)(e,t,p,m,g),h.list)}case"search":{y.info("Routing to search-requests handler")
|
|
2865
2889
|
const e={search:w.search}
|
|
2866
|
-
return(0,u.withAlchemyKind)(await(0,i.handleSearchRequests)(e,t,p,g
|
|
2890
|
+
return(0,u.withAlchemyKind)(await(0,i.handleSearchRequests)(e,t,p,m,g),h.search)}case"delete-empty":if(y.info("Routing to delete-empty handler"),!I)return{content:[{type:"text",text:"\u274c **Request Operations Failed:** requestId is required for delete-empty"}],isError:!0}
|
|
2867
2891
|
try{const e=p.getProxyClient(),r=await e.proxyGet(`/api/projects/${t.projectId}/tasks`,{requestLocalId:I,limit:1}),n=r?.data||r||[]
|
|
2868
2892
|
return(Array.isArray(n)?n.length:0)>0?{content:[{type:"text",text:`\u274c Cannot delete ${I}: it has tasks. Only empty requests (no tasks created) can be deleted.`}],isError:!0}:(await e.proxyDelete(`/api/projects/${t.projectId}/requests/${I}`),y.info("Empty request deleted",{requestId:I}),(0,u.withAlchemyKind)({content:[{type:"text",text:`\u2705 Request ${I} deleted (had no tasks).`}]},h["delete-empty"]))}catch(e){return{content:[{type:"text",text:"\u274c **Failed to delete request:** "+(0,d.getErrorMessage)(e)}],isError:!0}}default:{const e="Unknown operation type: "+b
|
|
2869
|
-
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+""}),
|
|
2893
|
+
return y.error(e),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+e}],isError:!0}}}}catch(e){return y.error("Request operations failed",{error:e instanceof Error?e.stack:e+""}),g.incrementCounter("request_operations_errors",1),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
2870
2894
|
const r=t(5715),n=t(6416),o=t(5434),s=t(8037),i=t(233),a=t(9032),c=t(1537),l=t(1925),d=t(8824),u=t(2272),h={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"
|
|
2871
2895
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2872
2896
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClient=void 0
|
|
@@ -2983,17 +3007,17 @@ var t={}
|
|
|
2983
3007
|
if(null!=e)for(var r=s(e),n=0;n<r.length;n++)"default"!==r[n]&&i(t,e,r[n])
|
|
2984
3008
|
return a(t,e),t})
|
|
2985
3009
|
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()
|
|
2986
|
-
try{const{path:i,lines:
|
|
2987
|
-
c.info("Processing blame request",{filePath:i,lines:
|
|
3010
|
+
try{const{path:i,lines:m,branch:g}=e
|
|
3011
|
+
c.info("Processing blame request",{filePath:i,lines:m,branch:g})
|
|
2988
3012
|
const f=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,y=d.isAbsolute(i)?i:d.join(f,i),w=d.relative(f,y)
|
|
2989
3013
|
try{await u.access(y)}catch{return{content:[{type:"text",text:"\u274c File not found: "+w}],isError:!0}}const I=function(e){if(!e)return null
|
|
2990
3014
|
if(/^\d+$/.test(e)){const t=parseInt(e,10)
|
|
2991
3015
|
return{start:t,end:t}}const t=e.match(/^(\d+)-(\d+)$/)
|
|
2992
3016
|
if(t)return{start:parseInt(t[1],10),end:parseInt(t[2],10)}
|
|
2993
3017
|
if(e.match(/^(\d+(?:,\d+)+)$/)){const t=e.split(",").map((e=>parseInt(e,10)))
|
|
2994
|
-
return{start:Math.min(...t),end:Math.max(...t)}}return null}(
|
|
3018
|
+
return{start:Math.min(...t),end:Math.max(...t)}}return null}(m),b=["blame","--porcelain"]
|
|
2995
3019
|
let k
|
|
2996
|
-
I&&b.push(`-L${I.start},${I.end}`),
|
|
3020
|
+
I&&b.push(`-L${I.start},${I.end}`),g&&b.push(g),b.push("--",w),c.debug("Executing git blame",{args:b})
|
|
2997
3021
|
try{if(!t.git)throw Error("Git context not available")
|
|
2998
3022
|
k=await t.git.raw(b)}catch(e){const t=(0,h.getErrorMessage)(e)
|
|
2999
3023
|
return c.error("Git blame failed",{error:t}),{content:[{type:"text",text:"\u274c Git blame failed: "+t}],isError:!0}}const v=function(e){const t=[],r=e.split("\n")
|
|
@@ -3192,18 +3216,18 @@ const n=a.getRequestClient(),s=a.getTaskClient(),[c,l]=await Promise.all([n.getR
|
|
|
3192
3216
|
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"})
|
|
3193
3217
|
const h=(0,o.extractDataFromResponse)(c,{logger:d,operationName:"getRequestInformation",throwOnNoData:!0}),p="data"in h?h.data:h
|
|
3194
3218
|
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"})
|
|
3195
|
-
const
|
|
3196
|
-
d.info(`Successfully extracted ${
|
|
3197
|
-
const
|
|
3198
|
-
|
|
3199
|
-
t in
|
|
3219
|
+
const m=(0,o.extractArrayFromResponse)(l,{logger:d,operationName:"listTasksForRequest",defaultValue:[]})
|
|
3220
|
+
d.info(`Successfully extracted ${m.length} tasks using data extraction utility`)
|
|
3221
|
+
const g={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:m.length}
|
|
3222
|
+
m.forEach((e=>{const t=e.status
|
|
3223
|
+
t in g&&g[t]++}))
|
|
3200
3224
|
const f=p.acceptanceCriteria||[],y={unverified:0,partial:0,verified:0,partially_verified:0,total:f.length}
|
|
3201
3225
|
f.forEach((e=>{const t=e.status||"unverified"
|
|
3202
3226
|
t in y&&y[t]++}))
|
|
3203
3227
|
let w=p.testVerification||null
|
|
3204
3228
|
const I=p.title,b=p.type
|
|
3205
|
-
let k=`# ${"feature"===b?"Feature":"quick-edit"===b?"Quick Edit":"Bug Fix"} Request: ${I} (${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: ${
|
|
3206
|
-
return k+=`\n## Task Status\n- Pending: ${
|
|
3229
|
+
let k=`# ${"feature"===b?"Feature":"quick-edit"===b?"Quick Edit":"Bug Fix"} Request: ${I} (${t})\nStatus: ${p.status}\nCreated: ${new Date(p.createdAt).toLocaleString()}\nUpdated: ${new Date(p.updatedAt).toLocaleString()}\n\n## Description\n${p.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${g.completed}/${g.total} completed (${Math.round(g.completed/g.total*100)||0}%)\n- Acceptance Criteria: ${y.verified}/${y.total} verified (${Math.round(y.verified/y.total*100)||0}%)\n`
|
|
3230
|
+
return k+=`\n## Task Status\n- Pending: ${g.pending}\n- In Progress: ${g.in_progress}\n- Blocked: ${g.blocked}\n- Ready for Review: ${g.ready_for_review}\n- Completed: ${g.completed}\n- Reverted: ${g.reverted}\n`,k+="\n## Tasks\n",0===m.length?k+="No tasks found for this request.\n":m.forEach((e=>{k+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${m.length} tasks`),k+="\n## Acceptance Criteria\n",k+=(0,i.formatCriteriaWithHashes)(f)+"\n","ready_for_review"===p.status&&f.some((e=>"verified"!==e.status))&&(k+="\n> **Status: ready_for_review** \u2014 Use the merge operation to verify criteria and merge to main.\n"),w&&(k+=`\n## Test Coverage\n- Test Cases: ${w.totalTestCases||0}\n- Criteria Tested: ${w.criteriaTestedCount||0}/${y.total}\n`,w.criterionCoverage&&Array.isArray(w.criterionCoverage)&&(k+="\n### Detailed Test Coverage:\n",w.criterionCoverage.forEach((e=>{k+=`- Criterion ${e.criterionId}: ${e.coverage} coverage\n`})))),p.recentActivity&&Array.isArray(p.recentActivity)&&(k+="\n## Recent Activity\n",p.recentActivity.slice(0,5).forEach((e=>{const t=new Date(e.timestamp).toLocaleString()
|
|
3207
3231
|
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}}}
|
|
3208
3232
|
const r=t(9860),n=t(5674),o=t(2960),s=t(8824),i=t(5454)},5454(e,exports){"use strict"
|
|
3209
3233
|
function t(e,t){let r=0
|
|
@@ -3243,13 +3267,29 @@ if(c.incrementCounter("document_operations_total",1,{operation:"list-annotations
|
|
|
3243
3267
|
let r=`## Annotations on ${h} (${t.length})\n\n`
|
|
3244
3268
|
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`
|
|
3245
3269
|
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")
|
|
3246
|
-
const e=o.selectedText,t=o.body,{prefixContext:r,suffixContext:n,lineHint:a}=o,l=i.getDocumentClient(),p=d?"agent":void 0,
|
|
3247
|
-
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:** ${
|
|
3270
|
+
const e=o.selectedText,t=o.body,{prefixContext:r,suffixContext:n,lineHint:a}=o,l=i.getDocumentClient(),p=d?"agent":void 0,m=d?.sessionId,g=await l.createAnnotation(h,{selectedText:e,prefixContext:r,suffixContext:n,lineHint:a,body:t,createdByAgent:p,createdBySessionId:m})
|
|
3271
|
+
return c.incrementCounter("document_operations_total",1,{operation:"create-annotation",success:!0}),(0,s.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Annotation Created**\n\n**ID:** ${g.id}\n**Document:** ${h}\n**Selected text:** "${e.substring(0,60)}"\n**Comment:** `+t}]},"create-annotation")}case"reply-to-annotation":{u.info("Replying to annotation")
|
|
3248
3272
|
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})
|
|
3249
3273
|
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")
|
|
3250
3274
|
const e=o.annotationId,t=i.getDocumentClient()
|
|
3251
3275
|
return await t.resolveAnnotation(h,e,d?"agent":void 0),c.incrementCounter("document_operations_total",1,{operation:"resolve-annotation",success:!0}),(0,s.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Annotation Resolved**\n\n**Annotation:** ${e}\n**Status:** resolved`}]},"resolve-annotation")}default:throw Error("Unknown operation type: "+a)}}catch(e){return u.error("document_operations failed",{error:e instanceof Error?e.stack:e+""}),c.incrementCounter("document_operations_errors",1),{content:[{type:"text",text:"\u274c **Document Operations Failed:** "+(0,o.getErrorMessage)(e)}],isError:!0}}}
|
|
3252
|
-
const r=t(1572),n=t(1483),o=t(8824),s=t(2272)},
|
|
3276
|
+
const r=t(1572),n=t(1483),o=t(8824),s=t(2272)},5652(e,exports,t){"use strict"
|
|
3277
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuestAuditComplete=async function(e,t,o,s,i){const a=s.child({tool:"quest_audit_complete"})
|
|
3278
|
+
try{if(!t.projectId)return{content:[{type:"text",text:"\u274c No project context available."}],isError:!0}
|
|
3279
|
+
const r=o.getDocumentClient(),s=await r.getDocument(e.questId)
|
|
3280
|
+
if(!s)return{content:[{type:"text",text:"\u274c Quest not found: "+e.questId}],isError:!0}
|
|
3281
|
+
if("Quest"!==s.type)return{content:[{type:"text",text:`\u274c Document ${e.questId} is not a quest (type: ${s.type}). quest_audit_complete only applies to Quest documents.`}],isError:!0}
|
|
3282
|
+
const c=s.metadata||{},l=c.status||n.QUEST_STATUS_OPEN
|
|
3283
|
+
if(l!==n.QUEST_STATUS_OPEN)return{content:[{type:"text",text:`\u274c Quest status is "${l}", not "open". Audits are only valid while the quest is open.`}],isError:!0}
|
|
3284
|
+
const d=c.completionMode,u="auto-close"===d||"audit-then-pending"===d?d:n.QUEST_COMPLETION_MODE_DEFAULT,h=Array.isArray(c.criteria)?c.criteria:[]
|
|
3285
|
+
if(h.length>0){const e=h.filter((e=>"verified"!==e?.status))
|
|
3286
|
+
if(e.length>0){const t=e.map((e=>`- ${e?.id||"(no id)"}: ${e?.description||"(no description)"}`))
|
|
3287
|
+
return{content:[{type:"text",text:`\u274c Cannot complete audit \u2014 ${e.length} of ${h.length} criteria still unverified:\n\n`+t.join("\n")+"\n\nUse quest_set_criteria_statuses to mark each item verified (with evidence), or use plan_write update to remove a criterion that's no longer applicable."}],isError:!0}}}const p=c.minIterations??(0,n.defaultMinIterations)(u),m=c.consecutiveDoneAudits??0,g=m+1,f=g>=p,y=f?"auto-close"===u?n.QUEST_STATUS_CLOSED:n.QUEST_STATUS_PENDING_REVIEW:l,w={...c,consecutiveDoneAudits:f?0:g,status:y}
|
|
3288
|
+
f&&(w.lastAuditSummary=e.summary,w.lastAuditAt=(new Date).toISOString(),e.evidence&&e.evidence.length>0?w.lastAuditEvidence=e.evidence:delete w.lastAuditEvidence),await r.updateDocument(e.questId,{metadata:w}),i.incrementCounter("quest_audit_complete_total",1,{flipped:f+"",completionMode:u,newStatus:y})
|
|
3289
|
+
const I=s.localId||s.id
|
|
3290
|
+
if(a.info("quest_audit_complete processed",{questId:I,previousCounter:m,nextCounter:g,willFlip:f,completionMode:u,nextStatus:y}),!f){const e=p-g
|
|
3291
|
+
return{content:[{type:"text",text:`\u{1f4dd} **Audit recorded (${g}/${p})**\n\nQuest **${I}** still needs ${e} more consistent done-audit${1===e?"":"s"} before status will flip. Keep auditing on future ticks. If criteria regress (you find remaining work and spawn a request), the counter resets to 0.`}]}}return{content:[{type:"text",text:`\u2705 **Audit threshold reached (${g}/${p})**\n\nQuest **${I}**: ${y===n.QUEST_STATUS_CLOSED?"Quest status flipped to **closed** (auto-close mode). The quest is terminal.":"Quest status flipped to **pending_review**. Ticks are paused. The user will close or reopen."}\n\n**Summary stored:** `+e.summary}]}}catch(e){return a.error("quest_audit_complete failed",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **quest_audit_complete failed:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
3292
|
+
const r=t(8824),n=t(3416)},5674(e,exports,t){"use strict"
|
|
3253
3293
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionError=void 0
|
|
3254
3294
|
const r=t(441)
|
|
3255
3295
|
class n extends Error{constructor(e,t,o,s={}){super(e),this.statusCode=503,this.retryable=!0,this.metadata={},this.name="ConnectionError",this.code=r.CONNECTION_ERROR,this.operation=t,this.lastConnectionAttempt=o,this.details={...s,operation:t,lastConnectionAttempt:o},Object.setPrototypeOf(this,n.prototype)}static operationRequiresConnectivity(e,t="",r){const o=`Cannot perform ${e}${t?` (${t})`:""} - not connected to remote server. Please check your network connection and try again. If the problem persists, verify that the remote server is running and accessible.`,s={operationType:e,operationDetails:t,timestamp:(new Date).toISOString(),suggestions:["Check your internet connection","Verify the remote server URL is correct","Ensure the remote server is running","Check for any firewall or proxy settings that might be blocking the connection"]}
|
|
@@ -3272,34 +3312,34 @@ return{isOffline:this.isInOfflineMode(),consecutiveFailures:e.consecutiveFailure
|
|
|
3272
3312
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3273
3313
|
const r=t(6183),n=t(2965)
|
|
3274
3314
|
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"
|
|
3275
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const p=l.child({tool:"complete_request"}),
|
|
3315
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const p=l.child({tool:"complete_request"}),m=d.startTimer("tool_execution_time")
|
|
3276
3316
|
try{const{requestId:n,summary:o,skipTestsReason:l,skipTests:d}=e
|
|
3277
3317
|
if(!n)throw(0,r.createValidationError)("Request ID is required")
|
|
3278
3318
|
if(!o)throw(0,r.createValidationError)("Summary is required")
|
|
3279
3319
|
if(l&&d&&d.length>0)throw(0,r.createValidationError)("Provide either skipTestsReason (skip all) or skipTests (per-command), not both.")
|
|
3280
3320
|
p.info("Starting request completion",{requestId:n,skipAllRequested:!!l,perCommandSkipCount:d?.length||0})
|
|
3281
3321
|
const u=h?.sessionId
|
|
3282
|
-
let
|
|
3322
|
+
let g
|
|
3283
3323
|
try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:u,skipTestsReason:l,skipTests:d})
|
|
3284
|
-
|
|
3285
|
-
return p.error("Server validation failed",{requestId:n,error:t}),
|
|
3286
|
-
return
|
|
3287
|
-
e&&await e.createToolRecord({projectId:t.projectId,requestId:n,type:"tests-skipped",metadata:{...l?{reason:l}:{},...d&&d.length>0?{skipTests:d}:{},completionMode:
|
|
3288
|
-
let
|
|
3289
|
-
const
|
|
3290
|
-
let
|
|
3291
|
-
if(
|
|
3324
|
+
g=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3325
|
+
return p.error("Server validation failed",{requestId:n,error:t}),m({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate completion: "+t}],isError:!0}}if(!g.canComplete){let e=`Cannot complete request ${n}: ${g.reason}\n`
|
|
3326
|
+
return g.blockedByTasks&&g.blockedByTasks.length>0&&(e+="\n**Tasks that must be completed or canceled first:**\n",g.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (Status: ${t.status})\n`}))),g.lifoViolation&&(e+="\n**Requests that must be re-completed first (LIFO order):**\n",g.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (Status: ${t.status})\n`}))),m({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(g.testsSkipped&&(l||d&&d.length>0))try{const e=c.getToolRecordClient()
|
|
3327
|
+
e&&await e.createToolRecord({projectId:t.projectId,requestId:n,type:"tests-skipped",metadata:{...l?{reason:l}:{},...d&&d.length>0?{skipTests:d}:{},completionMode:g.completionMode,timestamp:(new Date).toISOString()}})}catch(e){p.warn("Failed to persist tests-skipped tool_record",{error:(0,s.getErrorMessage)(e)})}const f=c.getRequestClient(),y="auto-merge"!==g.completionMode&&!g.testsSkipped&&!1===g.hasActiveTestProcesses&&("test-by-default"===g.completionMode||"always-test"===g.completionMode)
|
|
3328
|
+
let w="auto-merge"!==g.completionMode&&!g.testsSkipped&&!y
|
|
3329
|
+
const I="manual-review"===g.reviewMode
|
|
3330
|
+
let b,k=null
|
|
3331
|
+
if(w)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
|
|
3292
3332
|
if(i&&"passed"===i.status&&i.commitSha){let e=null
|
|
3293
3333
|
if(r&&r.ok){const t=await r.json()
|
|
3294
|
-
e=t?.data?.sha??null}e&&e===i.commitSha&&(
|
|
3295
|
-
try{await f.updateRequest(n,{status:
|
|
3296
|
-
return
|
|
3297
|
-
try{
|
|
3298
|
-
return
|
|
3299
|
-
if(
|
|
3300
|
-
if(
|
|
3301
|
-
const
|
|
3302
|
-
return 0===
|
|
3334
|
+
e=t?.data?.sha??null}e&&e===i.commitSha&&(w=!1,k=`latest test run ${i.id} passed against current branch HEAD ${e.slice(0,7)}`,b=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 v=w||I?"ready_for_review":"ready_for_merge"
|
|
3335
|
+
try{await f.updateRequest(n,{status:v,completionSummary:o,...b?{skippedTestRunId:b}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3336
|
+
return m({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let C
|
|
3337
|
+
try{C=await f.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3338
|
+
return m({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const _=C?.acceptanceCriteria||[]
|
|
3339
|
+
if(m({success:!0}),w){const e=g.completionMode
|
|
3340
|
+
return{content:[{type:"text",text:`Request ${n} moved to ready_for_review. ${"ask-me"===e?"A notification has been created asking the user to choose how to handle testing (auto-test, interactive-test, or skip).":`Tests are running automatically in the background (${e} mode). When they pass and the project is set to auto-finalize, the request will be merged without further input; otherwise the user will click Finalize after reviewing.`} Do NOT call merge or any other tool. Your work is done. Stop here and wait.`}]}}if(I)return{content:[{type:"text",text:`Request ${n} submitted for human review.${g.testsSkipped&&l?`\n\n_Tests skipped: ${l}_`:""}\n\nThe project is set to manual-review \u2014 a person will approve and merge from the UI. Do NOT call merge yourself.`}]}
|
|
3341
|
+
const E=k?`\n\n_Skipped re-running tests: ${k}._\n`:"",S=y?`\n\n_No test processes are configured for this project; ${g.completionMode} mode is being treated as auto-merge._\n`:""
|
|
3342
|
+
return 0===_.length?{content:[{type:"text",text:`Request ${n} is ready. ${E}${S}No acceptance criteria defined \u2014 call merge directly.`}]}:{content:[{type:"text",text:`Request ${n} completion started (${v}).${E}${S}\n\n## Next Step: Verify & Merge\n\n${(0,i.formatVerifyInstructions)(_)}\n\nUse the merge operation with your verification evidence to merge to main.`}]}}catch(r){let s="An unexpected error occurred",i=""
|
|
3303
3343
|
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})
|
|
3304
3344
|
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}}}
|
|
3305
3345
|
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"
|
|
@@ -3328,7 +3368,7 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3328
3368
|
var t={}
|
|
3329
3369
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3330
3370
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3331
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDeleteFiles=async function(e,r,n,o,s,i){const
|
|
3371
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleDeleteFiles=async function(e,r,n,o,s,i){const g=o.child({tool:"delete_files"}),f=Date.now()
|
|
3332
3372
|
let y,w,I=c.FileOperationPhase.VALIDATION
|
|
3333
3373
|
const b={toolName:"delete-files",operationName:"delete",fileOperationPhase:c.FileOperationPhase.FILE_WRITE,recordType:"delete-files",metricsPrefix:"delete_files",successMessage:"Successfully deleted files",failureMessage:"Failed to delete files"}
|
|
3334
3374
|
try{const d=n.getTaskClient(),k=n.getToolRecordClient(),v=n.getRequestClient(),C=e,{paths:_,operations:E,comment:S}=C,{enforceActiveTask:q}=await Promise.resolve().then(t.bind(t,3451)),T=await q(r,n,o,e.taskId)
|
|
@@ -3341,54 +3381,54 @@ x=E.map((e=>{if(e.path)return{type:"file",target:e.path}
|
|
|
3341
3381
|
if(e.documentId)return{type:"document",target:e.documentId}
|
|
3342
3382
|
throw Error("Invalid operation: neither path nor documentId specified")}))}if(0===x.length)throw Error("At least one file or document must be specified for deletion")
|
|
3343
3383
|
const j=x.filter((e=>"file"===e.type)),R=x.filter((e=>"document"===e.type)),M=x.length
|
|
3344
|
-
|
|
3384
|
+
g.info("Starting mixed file and document deletion operation",{taskId:P,totalOperations:x.length,fileOperations:j.length,documentOperations:R.length,comment:S}),c.validateTaskIdFormat(P,g,s,b.metricsPrefix)
|
|
3345
3385
|
const $=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3346
|
-
|
|
3386
|
+
g.info("Initial branch context",{initialBranch:$.branch,initialRequestId:$.requestId,isMain:$.isMain})
|
|
3347
3387
|
const O=[]
|
|
3348
3388
|
for(const e of j){const{normalizedPath:t,fullPath:n}=c.validateAndNormalizePath(e.target,r)
|
|
3349
3389
|
O.push({normalized:t,full:n})}I=c.FileOperationPhase.TASK_VALIDATION,s.incrementCounter("delete_files_phase",1,{phase:I})
|
|
3350
|
-
const D=O.length>0?O[0].normalized:"document_operations",A=await c.validateTaskId(P,D,d,
|
|
3351
|
-
z.taskPromoted&&
|
|
3352
|
-
const L=await c.ensureCorrectWorkspaceContext({taskPromoted:z.taskPromoted,requestId:F,context:r,operation:"delete-files",logger:
|
|
3390
|
+
const D=O.length>0?O[0].normalized:"document_operations",A=await c.validateTaskId(P,D,d,g,s,b.metricsPrefix),F=A?.requestId,N=await c.validateWorkItemStates(P,D,d,v,r,g,s,b.metricsPrefix),z=await c.autoPromoteTaskStatus(P,A.status,F,N.request?.status,D,d,v,g,s,b.metricsPrefix)
|
|
3391
|
+
z.taskPromoted&&g.info(`Auto-promoted task ${P} (${A.title||"Untitled"}) to in_progress for mixed operations`,{taskId:P,taskTitle:A.title,previousStatus:A.status,newStatus:z.newTaskStatus,totalOperations:x.length,fileOperations:j.length,documentOperations:R.length}),z.requestPromoted&&g.info(`Auto-promoted request ${F} to in_progress for file operations`,{requestId:F,previousStatus:N.request?.status,newStatus:z.newRequestStatus,triggeringTaskId:P})
|
|
3392
|
+
const L=await c.ensureCorrectWorkspaceContext({taskPromoted:z.taskPromoted,requestId:F,context:r,operation:"delete-files",logger:g,metrics:s,metricsPrefix:b.metricsPrefix})
|
|
3353
3393
|
if(!L.success)throw Error(L.error)
|
|
3354
3394
|
let H={hadUserMods:!1,userModsCommitHash:void 0}
|
|
3355
|
-
if(r.git)try{
|
|
3356
|
-
const e=await(0,u.commitUserChangesBeforeToolOperation)(r.git,"delete-files",{requestId:F,taskId:P,workspaceManager:r.workspaceManager},
|
|
3357
|
-
e.userChangesCommitted&&(
|
|
3358
|
-
const{toolRecordId:B,localToolRecordId:U}=await c.createFileOperationRecords(P,F,r.projectId,b.recordType,D,{totalOperations:x.length,fileOperations:j.length,documentOperations:R.length,filePaths:O.map((e=>e.normalized)),documentIds:R.map((e=>e.target)),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},d,k,
|
|
3395
|
+
if(r.git)try{g.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
|
|
3396
|
+
const e=await(0,u.commitUserChangesBeforeToolOperation)(r.git,"delete-files",{requestId:F,taskId:P,workspaceManager:r.workspaceManager},g,s)
|
|
3397
|
+
e.userChangesCommitted&&(g.debug("[DELETE-FILES] User changes committed before mixed delete operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),g.info("User changes committed before mixed delete-files operation",{taskId:P,totalOperations:x.length,fileOperations:j.length,documentOperations:R.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}),H={hadUserMods:!0,userModsCommitHash:e.commitHash})}catch(e){g.debug("[DELETE-FILES] Pre-tool commit failed, continuing with mixed delete operations",{error:e instanceof Error?e.message:e+""}),g.warn("Pre-tool user changes commit failed, continuing with mixed delete operation",{taskId:P,totalOperations:x.length,fileOperations:j.length,documentOperations:R.length,error:e instanceof Error?e.message:e+""})}g.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:x.length,fileDeletes:j.length,documentDeletes:R.length}),I=c.FileOperationPhase.RECORD_CREATION,s.incrementCounter("delete_files_phase",1,{phase:I})
|
|
3398
|
+
const{toolRecordId:B,localToolRecordId:U}=await c.createFileOperationRecords(P,F,r.projectId,b.recordType,D,{totalOperations:x.length,fileOperations:j.length,documentOperations:R.length,filePaths:O.map((e=>e.normalized)),documentIds:R.map((e=>e.target)),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},d,k,g,s,b.metricsPrefix,i)
|
|
3359
3399
|
y=B,w=B,I=b.fileOperationPhase,s.incrementCounter("delete_files_phase",1,{phase:I})
|
|
3360
3400
|
const W=[]
|
|
3361
3401
|
let G=0
|
|
3362
3402
|
R.length>0&&n.setProjectId(r.projectId)
|
|
3363
3403
|
for(let e=0;e<O.length;e++){const t=O[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3364
3404
|
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)
|
|
3365
|
-
await a.default.unlink(t.full),r.success=!0,G++,
|
|
3405
|
+
await a.default.unlink(t.full),r.success=!0,G++,g.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,m.getErrorMessage)(e),g.warn("Failed to delete file "+t.normalized,{error:r.error})}W.push(r)}const V=R.length>0?n.getDocumentClient():null
|
|
3366
3406
|
for(const e of R){const t=e.target,r={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
|
|
3367
3407
|
try{let e
|
|
3368
|
-
try{if(e=await V.getDocument(t),r.filename=e.filename,
|
|
3369
|
-
throw e}try{await(0,p.ensureDocumentNotLocked)(t,n,
|
|
3370
|
-
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,
|
|
3371
|
-
r.success=!0,r.filename=o.filename,G++,
|
|
3372
|
-
s.recordValue("delete_files_time",
|
|
3373
|
-
let
|
|
3408
|
+
try{if(e=await V.getDocument(t),r.filename=e.filename,g.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,h.validateRequestStatusForDocumentOperation)(e.requestId,v,g,s,"delete-document")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
|
|
3409
|
+
throw e}try{await(0,p.ensureDocumentNotLocked)(t,n,g,s,"delete-document-archive")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
|
|
3410
|
+
throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,m.getErrorMessage)(e)}`)}const o=await V.archiveDocument(t)
|
|
3411
|
+
r.success=!0,r.filename=o.filename,G++,g.info("Document archived successfully",{documentId:o.id,filename:o.filename,archivedAt:o.archived_at})}catch(e){r.error=(0,m.getErrorMessage)(e),g.warn("Failed to delete document "+t,{error:r.error})}W.push(r)}const Q=Date.now()-f
|
|
3412
|
+
s.recordValue("delete_files_time",Q),s.incrementCounter("delete_files_operations_total",M),s.incrementCounter("delete_files_operations_success",G),s.incrementCounter("delete_files_operations_failed",M-G),s.incrementCounter("delete_files_file_operations",j.length),s.incrementCounter("delete_files_document_operations",R.length),G===M?s.incrementCounter("delete_files_success",1):G>0?s.incrementCounter("delete_files_partial_success",1):s.incrementCounter("delete_files_total_failure",1)
|
|
3413
|
+
let K=null
|
|
3374
3414
|
if(G>0){I=c.FileOperationPhase.GIT_COMMIT,s.incrementCounter("delete_files_phase",1,{phase:I})
|
|
3375
3415
|
const e=W.filter((e=>e.success)),t=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
|
|
3376
3416
|
let o
|
|
3377
|
-
o=t>0&&n>0?`Delete ${t} files and ${n} documents - ${S}`:t>0?1===t?"Delete file - "+S:`Delete ${t} files - ${S}`:1===n?"Delete document - "+S:`Delete ${n} documents - ${S}`,
|
|
3378
|
-
const
|
|
3379
|
-
await c.updateFileOperationRecords(P,y,w,D,b.recordType,G===M?`Successfully deleted all ${M} operations`:`Deleted ${G}/${M} operations successfully`,{status:G===M?"completed":"partial_success",commitHash:
|
|
3417
|
+
o=t>0&&n>0?`Delete ${t} files and ${n} documents - ${S}`:t>0?1===t?"Delete file - "+S:`Delete ${t} files - ${S}`:1===n?"Delete document - "+S:`Delete ${n} documents - ${S}`,K=await c.commitToGit(P,D,B,U,o,r,g,s,b.metricsPrefix)}I=c.FileOperationPhase.RECORD_UPDATE_SUCCESS,s.incrementCounter("delete_files_phase",1,{phase:I})
|
|
3418
|
+
const J=W.filter((e=>e.success)),Y=W.filter((e=>!e.success))
|
|
3419
|
+
await c.updateFileOperationRecords(P,y,w,D,b.recordType,G===M?`Successfully deleted all ${M} operations`:`Deleted ${G}/${M} operations successfully`,{status:G===M?"completed":"partial_success",commitHash:K?.commitHash,previousCommitHash:K?.previousCommitHash,totalOperations:M,fileOperations:j.length,documentOperations:R.length,successCount:G,failureCount:M-G,successfulOperations:J.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:Y.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},G===M?`Successfully deleted all ${M} operations`:`Deleted ${G}/${M} operations successfully`,d,k,g,s,b.metricsPrefix)
|
|
3380
3420
|
const Z=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
3381
3421
|
let X=""
|
|
3382
|
-
if(G===M){const e=
|
|
3422
|
+
if(G===M){const e=J.filter((e=>"file"===e.type)).length,t=J.filter((e=>"document"===e.type)).length
|
|
3383
3423
|
X=e>0&&t>0?`Successfully deleted ${e} files and ${t} documents`:e>0?`Successfully deleted all ${e} ${1===e?"file":"files"}`:`Successfully archived all ${t} ${1===t?"document":"documents"}`}else X=G>0?`Successfully deleted ${G}/${M} operations.\n\nFailed operations:\n`+W.filter((e=>!e.success)).map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
|
|
3384
3424
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n"):"All delete operations failed:\n"+W.map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
|
|
3385
3425
|
return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
|
|
3386
|
-
return
|
|
3387
|
-
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,
|
|
3388
|
-
if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),
|
|
3426
|
+
return K?.commitHash&&(X+="\nCommit: "+K.commitHash.substring(0,8)),Z.requestId&&(X+="\nBranch: "+Z.requestId),{content:[{type:"text",text:X}],isError:0===G}}catch(t){if(e.taskId&&n)try{const o=n.getToolRecordClient(),s=t instanceof l.NotFoundError||t instanceof l.ValidationError||t instanceof d.ZodError
|
|
3427
|
+
await o.createToolRecord({...s?{}:{taskId:e.taskId},projectId:r.projectId,type:"delete-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment,error:(0,m.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:I,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,m.getErrorMessage)(t)})}catch(t){g.error("Failed to create failure record for delete-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0})}const o=Date.now()-f
|
|
3428
|
+
if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),g.error("Error in delete-files operation:",{error:(0,m.getErrorMessage)(t),time:o}),(y||w)&&e.taskId){I=c.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
3389
3429
|
try{const r=n.getTaskClient(),o=n.getToolRecordClient()
|
|
3390
|
-
await c.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",b.recordType,"Failed to delete operations",{status:"failed",error:(0,
|
|
3391
|
-
const a=i(t(1943)),c=s(t(5967)),l=t(9860),d=t(1569),u=t(7478),h=t(5003),p=t(9949),
|
|
3430
|
+
await c.updateFileOperationRecords(e.taskId,y,w,e.paths?.[0]||e.operations?.[0]?.path||e.operations?.[0]?.documentId||"unknown",b.recordType,"Failed to delete operations",{status:"failed",error:(0,m.getErrorMessage)(t),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment},"Failed to delete operations",r,o,g,s,b.metricsPrefix)}catch(t){g.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return c.handleFileOperationError(t,I,g,s,e,b)}}
|
|
3431
|
+
const a=i(t(1943)),c=s(t(5967)),l=t(9860),d=t(1569),u=t(7478),h=t(5003),p=t(9949),m=t(8824)},5997(e,exports,t){"use strict"
|
|
3392
3432
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3393
3433
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3394
3434
|
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=[]
|
|
@@ -3450,27 +3490,30 @@ const n=await this.requestWithRetry("POST","/api/files/recover",t)
|
|
|
3450
3490
|
if(!(0,i.safeGetResponseData)(n,null))throw new r.ServiceError("Empty response when recovering file")
|
|
3451
3491
|
const o=(0,i.safeGetResponseData)(n,{success:!0,path:e.path,commitHash:e.commitHash,backupPath:void 0})
|
|
3452
3492
|
return this.logger.info("Successfully recovered file "+e.path,{path:o.path,commitHash:o.commitHash,backupPath:o.backupPath}),o}catch(t){throw this.logger.error("Failed to recover file "+e.path,{path:e.path,commitHash:e.commitHash,error:t instanceof Error?t.stack:t+""}),t}}}exports.FileOperationsClient=a},6183(e,exports,t){"use strict"
|
|
3453
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.DocumentOperationsSchema=exports.SearchDocumentsSchema=exports.CreateDocumentSchema=exports.ReplaceLinesSchema=exports.InsertLinesSchema=exports.SwitchToRequestBranchSchema=exports.PlannerOpsSchema=exports.SpecialistOpsSchema=exports.SubagentOperationsSchema=exports.TaskInspectSchema=exports.CompleteTaskSchema=exports.GetTaskInformationSchema=exports.GetRequestInformationSchema=exports.ListRequestsSchema=exports.ListTasksSchema=exports.SearchSchema=exports.QueryHistorySchema=exports.RequestDiffSchema=exports.FileRecoverSchema=exports.FileHistorySchema=exports.DeleteFilesSchema=exports.DeleteFileSchema=exports.ReplaceInFilesSchema=exports.ReplaceStringsSchema=exports.ReplaceStringSchema=exports.MoveFilesSchema=exports.CreateDirectorySchema=exports.GetFileInfoSchema=exports.ListDirectorySchema=exports.ReadFilesSchema=exports.ViewAssetSchema=exports.WriteFileSchema=exports.UpdateTaskStatusSchema=exports.CreateTaskSchema=exports.CreateRequestSchema=exports.CompleteRequestSchema=exports.skipTestsSchema=exports.skipTestsReasonSchema=exports.ExecutedTestSchema=exports.TestVerificationSchema=exports.TestDefinitionSchema=exports.AcceptanceCriterionSchema=exports.RecordTypeEnum=exports.EvidenceTypeEnum=exports.CriterionStatusEnum=exports.RequestStatusEnum=exports.TaskStatusEnum=exports.RequestTypeEnum=exports.TestCoverageTypeEnum=exports.CompletionStatusEnum=void 0,exports.CommitToViewedSessionSchema=exports.UpdateSpecializationSchema=exports.SessionMessageOperationsSchema=exports.ReportTestResultsSchema=exports.CommandsSchema=exports.ExecuteTestCommandSchema=exports.TestsSchema=exports.TestingReferenceSchema=exports.TestingProcessUpdateSchema=exports.TestingProcessDeleteSchema=exports.TestingProcessCreateSchema=exports.TestingProcessGetSchema=exports.TestingProcessListSchema=exports.MetaReferenceSchema=exports.MetaAgentListSchema=exports.MetaWorkflowRemoveRecipeSchema=exports.MetaWorkflowAddRecipeSchema=exports.MetaHookCreateSchema=exports.MetaHookListSchema=exports.MetaRecipeRemoveHookSchema=exports.MetaRecipeAddHookSchema=exports.MetaRecipeCreateSchema=exports.MetaRecipeGetSchema=exports.MetaRecipeListSchema=exports.MetaWorkflowUpdateSchema=exports.MetaWorkflowCreateSchema=exports.MetaWorkflowGetSchema=exports.MetaWorkflowListSchema=exports.GenerateRequestJournalSchema=exports.QuickManageSchema=exports.QuickReplaceSchema=exports.QuickWriteSchema=exports.RequestOperationsSchema=exports.ManageFilesSchema=exports.ModifyFileSchema=exports.RevertRequestSchema=exports.SwitchToBranchSchema=exports.SwitchToMainBranchSchema=exports.PlanWriteSchema=exports.PlanReadSchema=void 0
|
|
3454
|
-
const r=t(1569),n=t(8955),o=t(4466),s=(e,t,n={})=>r.z.string().refine((t=>!(!n.allowEmpty||""!==t)||!!t&&e.some((e=>e.test(t)))),{message:t}),i
|
|
3455
|
-
exports.CompletionStatusEnum=r.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=r.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=r.z.enum(["feature","bugfix","quick-edit"]),exports.TaskStatusEnum=r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=r.z.enum(["open","in_progress","ready_for_review","ready_for_merge","completed","canceled","reverted","conflicted"]),exports.CriterionStatusEnum=r.z.enum(["unverified","verified"]),exports.EvidenceTypeEnum=r.z.enum(["test","manual","other"]),exports.RecordTypeEnum=r.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=r.z.object({description:r.z.string(),status:r.z.enum(["unverified","verified"]).default("unverified"),evidence:r.z.string().optional(),evidenceType:r.z.enum(["test","manual","other"]).optional(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.TestDefinitionSchema=r.z.object({id:r.z.string(),description:r.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:r.z.array(r.z.string())}),exports.TestVerificationSchema=r.z.object({criteria:r.z.array(r.z.string()),tests:r.z.array(r.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:r.z.number(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.ExecutedTestSchema=r.z.object({id:r.z.string(),testId:r.z.string(),status:exports.CompletionStatusEnum,results:r.z.string(),coverage:r.z.array(r.z.string()),executedAt:r.z.string()}),exports.skipTestsReasonSchema=r.z.string().min(20).optional().describe("Optional: opt out of ALL tests for this completion. Provide >=20 chars explaining why. Rejected in always-test projects. For per-test opt-out use `skipTests` instead."),exports.skipTestsSchema=r.z.array(r.z.object({commandName:r.z.string().min(1).describe("Name of the test command to skip (must match a command registered in an active test_process)."),reason:r.z.string().min(20).describe("Why this specific command is irrelevant to the change (>=20 chars).")})).optional().describe("Optional: skip individual test commands by name. Mutually exclusive with skipTestsReason. Rejected in always-test projects."),exports.CompleteRequestSchema=r.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:r.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:r.z.string().optional()}),exports.CreateRequestSchema=r.z.object({title:r.z.string(),type:r.z.enum(["feature","bugfix"]),description:r.z.string(),acceptanceCriteria:r.z.array(r.z.string()),planDocumentId:r.z.string().optional(),questDocumentId:r.z.string().optional()}),exports.CreateTaskSchema=r.z.object({requestId:a,title:r.z.string(),description:r.z.string()}),exports.UpdateTaskStatusSchema=r.z.object({taskId:i,status:exports.TaskStatusEnum,note:r.z.string()}),exports.WriteFileSchema=r.z.object({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(),comment:r.z.string()}).transform(l).refine(d,{message:"path or documentId required"}),exports.ViewAssetSchema=r.z.object({filename:r.z.string().describe("The asset filename (e.g., 01JMXYZ.png)")}),exports.ReadFilesSchema=r.z.object({paths:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),lines:r.z.string().optional()}).transform(l).refine(d,{message:"path or documentId required"})),encoding:r.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=r.z.object({path:r.z.string(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=r.z.object({path:r.z.string()}),exports.CreateDirectorySchema=r.z.object({path:r.z.string(),comment:r.z.string().optional()}),exports.MoveFilesSchema=r.z.object({operations:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()})),comment:r.z.string()}),exports.ReplaceStringSchema=r.z.object({path:r.z.string(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional(),comment:r.z.string()}),exports.ReplaceStringsSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).transform(l).refine(d,{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceInFilesSchema=r.z.object({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,"old string cannot be empty"),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"})).min(1,"At least one operation required"),fuzzy_match:r.z.boolean().optional().default(!0),comment:r.z.string()}),exports.DeleteFileSchema=r.z.object({path:r.z.string(),comment:r.z.string()}),exports.DeleteFilesSchema=r.z.object({paths:r.z.array(r.z.string()).optional(),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"})).optional(),comment:r.z.string()}).refine((e=>e.paths&&!e.operations||!e.paths&&e.operations),{message:"paths or operations required"}).refine((e=>e.paths?.length||e.operations?.length),{message:"path/operation required"}),exports.FileHistorySchema=r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}),exports.FileRecoverSchema=r.z.object({path:r.z.string(),commitHash:r.z.string(),createBackup:r.z.boolean().default(!0)}),exports.RequestDiffSchema=r.z.object({requestId:a,format:r.z.enum(["summary","unified"]).default("summary"),path:r.z.string().optional()}),exports.QueryHistorySchema=r.z.object({queryType:r.z.enum(["file-history","request-file-history","recover","blame"],{errorMap(){return{message:"Invalid queryType. Valid options: file-history, request-file-history, recover, blame"}}}),fileHistory:r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}).optional(),requestHistory:r.z.object({requestId:a,detailLevel:r.z.enum(["summary","detailed"]).default("summary"),taskId:i.optional(),showDiff:r.z.boolean().optional(),fileFilter:r.z.string().optional()}).optional(),recover:r.z.object({path:r.z.string(),commitHash:r.z.string().optional(),createBackup:r.z.boolean().default(!0)}).optional(),blame:r.z.object({path:r.z.string(),lines:r.z.string().optional(),branch:r.z.string().optional()}).optional()}).refine((e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"request-file-history"===e.queryType?e.requestHistory&&!e.fileHistory&&!e.recover:"recover"===e.queryType?e.recover&&!e.fileHistory&&!e.requestHistory&&!e.blame:"blame"===e.queryType&&e.blame&&!e.fileHistory&&!e.requestHistory&&!e.recover),{message:"Invalid query data"}),exports.SearchSchema=r.z.object({needle:r.z.string().optional(),directory:r.z.string().optional(),options:r.z.object({caseSensitive:r.z.boolean().optional(),fileExtension:r.z.string().optional(),maxResults:r.z.number().optional(),useRegex:r.z.boolean().optional(),searchIn:r.z.enum(["content","filename","both"]).default("content").optional(),contextLines:r.z.number().min(0).max(10).optional(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=r.z.object({requestId:a,filters:r.z.object({status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).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()}),exports.ListRequestsSchema=r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["open","in_progress","ready_for_review","completed","canceled"]).optional(),planDocumentId:r.z.string().optional(),questDocumentId:r.z.string().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()}),exports.GetRequestInformationSchema=r.z.object({requestId:a}),exports.GetTaskInformationSchema=r.z.object({taskId:i}),exports.CompleteTaskSchema=r.z.object({taskId:i,summary:r.z.string()}),exports.TaskInspectSchema=r.z.object({operation:r.z.enum(["get-info","list"]),taskId:i.optional(),requestId:a.optional(),status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).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")}).superRefine(((e,t)=>{"get-info"!==e.operation||e.taskId||t.addIssue({code:"custom",message:'taskId is required for get-info. Example: { "operation": "get-info", "taskId": "req000001#01" }'}),"list"!==e.operation||e.requestId||t.addIssue({code:"custom",message:'requestId is required for list. Example: { "operation": "list", "requestId": "req000001" }'})}))
|
|
3456
|
-
const
|
|
3457
|
-
exports.SubagentOperationsSchema=r.z.object({sessionId:
|
|
3458
|
-
const
|
|
3459
|
-
exports.PlanReadSchema=r.z.object({operation:r.z.enum(["get","get-active","list","get-history","get-requests"]),planId:
|
|
3460
|
-
if("create"===r
|
|
3461
|
-
|
|
3493
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.DocumentOperationsSchema=exports.SearchDocumentsSchema=exports.CreateDocumentSchema=exports.ReplaceLinesSchema=exports.InsertLinesSchema=exports.SwitchToRequestBranchSchema=exports.PlannerOpsSchema=exports.SpecialistOpsSchema=exports.SubagentOperationsSchema=exports.TaskInspectSchema=exports.CompleteTaskSchema=exports.GetTaskInformationSchema=exports.GetRequestInformationSchema=exports.ListRequestsSchema=exports.ListTasksSchema=exports.SearchSchema=exports.QueryHistorySchema=exports.RequestDiffSchema=exports.FileRecoverSchema=exports.FileHistorySchema=exports.DeleteFilesSchema=exports.DeleteFileSchema=exports.ReplaceInFilesSchema=exports.ReplaceStringsSchema=exports.ReplaceStringSchema=exports.MoveFilesSchema=exports.CreateDirectorySchema=exports.GetFileInfoSchema=exports.ListDirectorySchema=exports.ReadFilesSchema=exports.ViewAssetSchema=exports.WriteFileSchema=exports.UpdateTaskStatusSchema=exports.CreateTaskSchema=exports.CreateRequestSchema=exports.CompleteRequestSchema=exports.skipTestsSchema=exports.skipTestsReasonSchema=exports.ExecutedTestSchema=exports.TestVerificationSchema=exports.TestDefinitionSchema=exports.AcceptanceCriterionSchema=exports.RecordTypeEnum=exports.EvidenceTypeEnum=exports.CriterionStatusEnum=exports.RequestStatusEnum=exports.TaskStatusEnum=exports.RequestTypeEnum=exports.TestCoverageTypeEnum=exports.CompletionStatusEnum=void 0,exports.CommitToViewedSessionSchema=exports.UpdateSpecializationSchema=exports.SessionMessageOperationsSchema=exports.ReportTestResultsSchema=exports.CommandsSchema=exports.ExecuteTestCommandSchema=exports.TestsSchema=exports.TestingReferenceSchema=exports.TestingProcessUpdateSchema=exports.TestingProcessDeleteSchema=exports.TestingProcessCreateSchema=exports.TestingProcessGetSchema=exports.TestingProcessListSchema=exports.MetaReferenceSchema=exports.MetaAgentListSchema=exports.MetaWorkflowRemoveRecipeSchema=exports.MetaWorkflowAddRecipeSchema=exports.MetaHookCreateSchema=exports.MetaHookListSchema=exports.MetaRecipeRemoveHookSchema=exports.MetaRecipeAddHookSchema=exports.MetaRecipeCreateSchema=exports.MetaRecipeGetSchema=exports.MetaRecipeListSchema=exports.MetaWorkflowUpdateSchema=exports.MetaWorkflowCreateSchema=exports.MetaWorkflowGetSchema=exports.MetaWorkflowListSchema=exports.GenerateRequestJournalSchema=exports.QuickManageSchema=exports.QuickReplaceSchema=exports.QuickWriteSchema=exports.RequestOperationsSchema=exports.ManageFilesSchema=exports.ModifyFileSchema=exports.RevertRequestSchema=exports.SwitchToBranchSchema=exports.SwitchToMainBranchSchema=exports.QuestAuditCompleteSchema=exports.QuestSetCriteriaStatusesSchema=exports.PlanWriteSchema=exports.PlanReadSchema=void 0
|
|
3494
|
+
const r=t(1569),n=t(8955),o=t(4466),s=t(3416),i=(e,t,n={})=>r.z.string().refine((t=>!(!n.allowEmpty||""!==t)||!!t&&e.some((e=>e.test(t)))),{message:t}),a=i([o.TASK_REF_PATTERN,o.TASK_REF_SHORT_PATTERN],"Task ID must be req######+#NN (e.g. req000005#03) or a short form like #01, 01, or 1 (resolved against the active request)."),c=i([/^req\d{6}$/],"Request ID must match format: req###### (e.g. req000001)"),l=i([/^doc_[0-9A-Z]{26}$/i,/^(doc|plan|quest|jour)\d{6}$/],"Document ID must match format: doc_[26 alphanumeric] (ULID) or doc######/plan######/quest######/jour###### (local ID)",{allowEmpty:!0}),d=e=>e.path&&e.documentId?{...e,documentId:void 0}:e,u=e=>!!e.path||!!e.documentId
|
|
3495
|
+
exports.CompletionStatusEnum=r.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=r.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=r.z.enum(["feature","bugfix","quick-edit"]),exports.TaskStatusEnum=r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=r.z.enum(["open","in_progress","ready_for_review","ready_for_merge","completed","canceled","reverted","conflicted"]),exports.CriterionStatusEnum=r.z.enum(["unverified","verified"]),exports.EvidenceTypeEnum=r.z.enum(["test","manual","other"]),exports.RecordTypeEnum=r.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=r.z.object({description:r.z.string(),status:r.z.enum(["unverified","verified"]).default("unverified"),evidence:r.z.string().optional(),evidenceType:r.z.enum(["test","manual","other"]).optional(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.TestDefinitionSchema=r.z.object({id:r.z.string(),description:r.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:r.z.array(r.z.string())}),exports.TestVerificationSchema=r.z.object({criteria:r.z.array(r.z.string()),tests:r.z.array(r.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:r.z.number(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.ExecutedTestSchema=r.z.object({id:r.z.string(),testId:r.z.string(),status:exports.CompletionStatusEnum,results:r.z.string(),coverage:r.z.array(r.z.string()),executedAt:r.z.string()}),exports.skipTestsReasonSchema=r.z.string().min(20).optional().describe("Optional: opt out of ALL tests for this completion. Provide >=20 chars explaining why. Rejected in always-test projects. For per-test opt-out use `skipTests` instead."),exports.skipTestsSchema=r.z.array(r.z.object({commandName:r.z.string().min(1).describe("Name of the test command to skip (must match a command registered in an active test_process)."),reason:r.z.string().min(20).describe("Why this specific command is irrelevant to the change (>=20 chars).")})).optional().describe("Optional: skip individual test commands by name. Mutually exclusive with skipTestsReason. Rejected in always-test projects."),exports.CompleteRequestSchema=r.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:r.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:r.z.string().optional()}),exports.CreateRequestSchema=r.z.object({title:r.z.string(),type:r.z.enum(["feature","bugfix"]),description:r.z.string(),acceptanceCriteria:r.z.array(r.z.string()),planDocumentId:r.z.string().optional(),questDocumentId:r.z.string().optional()}),exports.CreateTaskSchema=r.z.object({requestId:c,title:r.z.string(),description:r.z.string()}),exports.UpdateTaskStatusSchema=r.z.object({taskId:a,status:exports.TaskStatusEnum,note:r.z.string()}),exports.WriteFileSchema=r.z.object({path:r.z.string().optional(),documentId:l.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(),comment:r.z.string()}).transform(d).refine(u,{message:"path or documentId required"}),exports.ViewAssetSchema=r.z.object({filename:r.z.string().describe("The asset filename (e.g., 01JMXYZ.png)")}),exports.ReadFilesSchema=r.z.object({paths:r.z.array(r.z.object({path:r.z.string().optional(),documentId:l.optional(),lines:r.z.string().optional()}).transform(d).refine(u,{message:"path or documentId required"})),encoding:r.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=r.z.object({path:r.z.string(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=r.z.object({path:r.z.string()}),exports.CreateDirectorySchema=r.z.object({path:r.z.string(),comment:r.z.string().optional()}),exports.MoveFilesSchema=r.z.object({operations:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()})),comment:r.z.string()}),exports.ReplaceStringSchema=r.z.object({path:r.z.string(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional(),comment:r.z.string()}),exports.ReplaceStringsSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:l.optional(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).transform(d).refine(u,{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceInFilesSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:l.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1,"old string cannot be empty"),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:r.z.boolean().optional()}).transform(d).refine(u,{message:"path or documentId required"})).min(1,"At least one operation required"),fuzzy_match:r.z.boolean().optional().default(!0),comment:r.z.string()}),exports.DeleteFileSchema=r.z.object({path:r.z.string(),comment:r.z.string()}),exports.DeleteFilesSchema=r.z.object({paths:r.z.array(r.z.string()).optional(),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:l.optional()}).transform(d).refine(u,{message:"path or documentId required"})).optional(),comment:r.z.string()}).refine((e=>e.paths&&!e.operations||!e.paths&&e.operations),{message:"paths or operations required"}).refine((e=>e.paths?.length||e.operations?.length),{message:"path/operation required"}),exports.FileHistorySchema=r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}),exports.FileRecoverSchema=r.z.object({path:r.z.string(),commitHash:r.z.string(),createBackup:r.z.boolean().default(!0)}),exports.RequestDiffSchema=r.z.object({requestId:c,format:r.z.enum(["summary","unified"]).default("summary"),path:r.z.string().optional()}),exports.QueryHistorySchema=r.z.object({queryType:r.z.enum(["file-history","request-file-history","recover","blame"],{errorMap(){return{message:"Invalid queryType. Valid options: file-history, request-file-history, recover, blame"}}}),fileHistory:r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}).optional(),requestHistory:r.z.object({requestId:c,detailLevel:r.z.enum(["summary","detailed"]).default("summary"),taskId:a.optional(),showDiff:r.z.boolean().optional(),fileFilter:r.z.string().optional()}).optional(),recover:r.z.object({path:r.z.string(),commitHash:r.z.string().optional(),createBackup:r.z.boolean().default(!0)}).optional(),blame:r.z.object({path:r.z.string(),lines:r.z.string().optional(),branch:r.z.string().optional()}).optional()}).refine((e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"request-file-history"===e.queryType?e.requestHistory&&!e.fileHistory&&!e.recover:"recover"===e.queryType?e.recover&&!e.fileHistory&&!e.requestHistory&&!e.blame:"blame"===e.queryType&&e.blame&&!e.fileHistory&&!e.requestHistory&&!e.recover),{message:"Invalid query data"}),exports.SearchSchema=r.z.object({needle:r.z.string().optional(),directory:r.z.string().optional(),options:r.z.object({caseSensitive:r.z.boolean().optional(),fileExtension:r.z.string().optional(),maxResults:r.z.number().optional(),useRegex:r.z.boolean().optional(),searchIn:r.z.enum(["content","filename","both"]).default("content").optional(),contextLines:r.z.number().min(0).max(10).optional(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=r.z.object({requestId:c,filters:r.z.object({status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).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()}),exports.ListRequestsSchema=r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["open","in_progress","ready_for_review","completed","canceled"]).optional(),planDocumentId:r.z.string().optional(),questDocumentId:r.z.string().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()}),exports.GetRequestInformationSchema=r.z.object({requestId:c}),exports.GetTaskInformationSchema=r.z.object({taskId:a}),exports.CompleteTaskSchema=r.z.object({taskId:a,summary:r.z.string()}),exports.TaskInspectSchema=r.z.object({operation:r.z.enum(["get-info","list"]),taskId:a.optional(),requestId:c.optional(),status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).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")}).superRefine(((e,t)=>{"get-info"!==e.operation||e.taskId||t.addIssue({code:"custom",message:'taskId is required for get-info. Example: { "operation": "get-info", "taskId": "req000001#01" }'}),"list"!==e.operation||e.requestId||t.addIssue({code:"custom",message:'requestId is required for list. Example: { "operation": "list", "requestId": "req000001" }'})}))
|
|
3496
|
+
const h=r.z.string().min(1).describe("OpenCode session ID")
|
|
3497
|
+
exports.SubagentOperationsSchema=r.z.object({sessionId:h.optional(),operation:r.z.enum(["spawn","continue","check-status","abort","read-messages","list-sessions"]),prompt:r.z.string().min(1).describe("Instructions for the subagent (required for spawn and continue)").optional(),agent:r.z.string().default("work").refine((e=>(0,n.isValidAgent)(e)),{message:"Invalid agent. Check tool description for available agents."}).describe("The subagent type to spawn (see tool description for available agents)").optional(),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars, spawn only)").optional(),requestId:r.z.string().describe("Request ID \u2014 associates work (spawn) or filters results (list-sessions)").optional(),allowParallel:r.z.boolean().describe("Allow spawning even if request already has active workers (spawn only)").optional(),useExistingSession:r.z.string().describe("Existing session ID to send prompt to instead of creating new session (spawn only)").optional(),limit:r.z.number().min(1).max(100).describe("Max items to return (read-messages: max 50, list-sessions: max 100)").optional(),activeOnly:r.z.boolean().describe("Only show sessions that are currently active/busy (list-sessions only)").optional(),minTokens:r.z.number().min(0).describe("Only show sessions with at least this many tokens (list-sessions only)").optional(),maxTokens:r.z.number().min(0).describe("Only show sessions with at most this many tokens (list-sessions only)").optional(),maxAgeHours:r.z.number().min(0).describe("Only show sessions newer than X hours (list-sessions only)").optional()}).refine((e=>"spawn"===e.operation?!!e.prompt:"continue"===e.operation?!!e.prompt&&!!e.sessionId:"check-status"===e.operation||"abort"===e.operation||"read-messages"===e.operation?!!e.sessionId:"list-sessions"===e.operation),{message:"spawn requires prompt; continue requires prompt+sessionId; check-status/abort/read-messages require sessionId"}),exports.SpecialistOpsSchema=r.z.object({operation:r.z.enum(["delegate","follow-up","check-status","list","abort"]),sessionId:h.optional(),prompt:r.z.string().min(1).describe("Instructions for the specialist (required for delegate and follow-up)").optional(),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars, delegate only)").optional(),specialization:r.z.string().max(500).describe('Domain description (e.g. "Frontend UI components"). Required for delegate').optional(),specializationHeadline:r.z.string().max(80).describe("Optional short tagline (\u226480 chars) shown next to the specialist\u2019s name in the UI directory. The specialist can refine it later via update_specialization.").optional(),requestId:r.z.string().describe("Request ID \u2014 associates work (delegate) or filters results (list)").optional(),activeOnly:r.z.boolean().describe("Only show active/busy specialists (list only)").optional(),limit:r.z.number().min(1).max(100).describe("Max sessions to return (list only)").optional()}).refine((e=>"delegate"===e.operation?!!e.prompt&&!!e.specialization&&!e.sessionId:"follow-up"===e.operation?!!e.prompt&&!!e.sessionId:"check-status"===e.operation||"abort"===e.operation?!!e.sessionId:"list"===e.operation),{message:"delegate requires prompt+specialization; follow-up requires prompt+sessionId; check-status/abort require sessionId"}),exports.PlannerOpsSchema=r.z.object({operation:r.z.enum(["request","check-status","list"]),sessionId:h.optional(),prompt:r.z.string().min(1).describe("What to plan \u2014 feature description, architecture question, etc. (required for request)").optional(),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars, request only)").optional(),activeOnly:r.z.boolean().describe("Only show active/busy planning sessions (list only)").optional(),limit:r.z.number().min(1).max(100).describe("Max sessions to return (list only)").optional()}).refine((e=>"request"===e.operation?!!e.prompt:"check-status"===e.operation?!!e.sessionId:"list"===e.operation),{message:"request requires prompt; check-status requires sessionId"}),exports.SwitchToRequestBranchSchema=r.z.object({requestId:c}),exports.InsertLinesSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:l.optional(),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"}))}).transform(d).refine(u,{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceLinesSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:l.optional(),replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).transform(d).refine(u,{message:"path or documentId required"})),comment:r.z.string()}),exports.CreateDocumentSchema=r.z.object({requestId:c.optional(),filename:r.z.string().refine((e=>e.toLowerCase().endsWith(".md")),{message:"Filename must end with .md extension"}),content:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"],{errorMap(){return{message:"Document type must be one of: Report, Documentation, Plan, Other"}}}),comment:r.z.string()}),exports.SearchDocumentsSchema=r.z.object({query:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),requestId:c.optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both")}),exports.DocumentOperationsSchema=r.z.object({operation:r.z.enum(["create","search","create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"]),documentId:l.optional(),requestId:c.optional(),filename:r.z.string().optional(),content:r.z.string().optional(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),comment:r.z.string().optional(),query:r.z.string().optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both"),versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional(),versionNumber:r.z.number().int().min(1).optional(),selectedText:r.z.string().optional(),prefixContext:r.z.string().optional(),suffixContext:r.z.string().optional(),lineHint:r.z.number().int().optional(),body:r.z.string().optional(),annotationId:r.z.string().optional()}).superRefine(((e,t)=>{const r=e.operation;["create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"].includes(r)&&!e.documentId&&t.addIssue({code:"custom",message:`documentId is required for '${r}'. Example: { "operation": "${r}", "documentId": "doc000001" }`}),"create"===r&&(e.filename?e.filename.toLowerCase().endsWith(".md")||t.addIssue({code:"custom",message:"Filename must end with .md extension"}):t.addIssue({code:"custom",message:"filename is required for create (must end with .md)"}),e.content||t.addIssue({code:"custom",message:"content is required for create"}),e.type||t.addIssue({code:"custom",message:"type is required for create (Report, Documentation, Plan, or Other)"}),e.comment||t.addIssue({code:"custom",message:"comment is required for create"})),"search"!==r||e.query||t.addIssue({code:"custom",message:'query is required for search. Example: { "operation": "search", "query": "search term" }'}),"get-version"!==r&&"restore-version"!==r||e.versionNumber||t.addIssue({code:"custom",message:`versionNumber is required for '${r}'`}),"create-annotation"===r&&(e.selectedText||t.addIssue({code:"custom",message:"selectedText is required for create-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for create-annotation"})),"reply-to-annotation"===r&&(e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for reply-to-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for reply-to-annotation"})),"resolve-annotation"!==r||e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for resolve-annotation"})}))
|
|
3498
|
+
const p=i([/^doc_[0-9A-Z]{26}$/i,/^(plan|quest)\d{6}$/],"Plan ID must match format: doc_[26 alphanumeric] (ULID) or plan######/quest###### (local ID)")
|
|
3499
|
+
exports.PlanReadSchema=r.z.object({operation:r.z.enum(["get","get-active","list","get-history","get-requests"]),planId:p.optional(),searchQuery: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(["createdAt","updatedAt","filename"]).default("updatedAt"),sortDirection:r.z.enum(["ASC","DESC"]).default("DESC")}).superRefine(((e,t)=>{["get","get-history","get-requests"].includes(e.operation)&&!e.planId&&t.addIssue({code:"custom",message:`planId is required for '${e.operation}'. Example: { "operation": "${e.operation}", "planId": "plan000001" }`})})),exports.PlanWriteSchema=r.z.object({operation:r.z.enum(["create","update","append","replace","create-snapshot","restore","set-active"]),planId:p.optional(),kind:r.z.enum(["plan"]).default("plan").describe("Document kind to create. Plans only. Quests are created via the UI flow at /quests/new (Start Quest button); the MCP path was removed because no agent calls it. plan_write update still works on existing Quest documents."),criteria:r.z.array(r.z.object({id:r.z.string().min(1).describe("Stable identifier for this criterion (any unique string within the quest, e.g. a slug or ulid)."),description:r.z.string().min(1).describe("What the criterion is, in plain language."),status:r.z.enum(["unverified","verified"]).optional().describe("Per-item verification state. Defaults to unverified when omitted."),evidence:r.z.string().optional().describe("Optional notes / file references / test names that justify the status.")})).optional().describe("Optional structured criteria checklist for the quest. When present, each item has its own verifiable status and the UI shows per-item progress. When omitted, criteria prose lives in the document body (Goal / Criteria for done / Notes) and the alchemist audits it as free text. Update-only \u2014 settable via plan_write update on an existing Quest document. Replaces the entire array (no per-item merge)."),tickIntervalSeconds:r.z.number().int().min(300).optional().describe("Quest heartbeat interval (seconds). Update-only. Minimum 300 (5 min)."),maxInFlight:r.z.number().int().min(1).optional().describe("Quest fan-out width \u2014 max parallel requests per tick. Update-only."),maxPerDay:r.z.number().int().min(1).optional().describe("Quest daily spawn cap. Update-only."),minIterations:r.z.number().int().min(1).optional().describe("Quest minimum consecutive criteria-met audits before quest_audit_complete may flip status. Update-only. Each tick where the alchemist calls quest_audit_complete bumps the audit counter; creating a request under the quest resets it to 0. The state transition only fires once the counter reaches this threshold."),status:r.z.enum(["open","pending_review","closed"]).optional().describe('Quest lifecycle status. Update-only. "open" runs the tick loop; "pending_review" pauses ticks awaiting user adjudication (set by the LLM after its done-audit, in audit-then-pending completion mode); "closed" is terminal. The LLM cannot set "closed" directly \u2014 only the user closes a quest. Quest creation seeds status="draft" via the UI; the quest-planner flips to "open" once configuration is confirmed.'),completionMode:r.z.enum(["auto-close","audit-then-pending"]).optional().describe('Quest completion mode \u2014 controls what happens when the alchemist\'s audit reports criteria are met. Update-only. "auto-close": LLM closes the quest directly. "audit-then-pending" (UI default): LLM flips to pending_review for user adjudication.'),content:r.z.string().optional(),name:r.z.string().optional().describe("Plan/quest name (used in filename for create; optional new name for update)."),old:r.z.string().optional().describe("Text to find in the plan (for replace)"),new:r.z.string().optional().describe("Replacement text (for replace)"),versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional(),versionNumber:r.z.number().int().min(1).optional()}).superRefine(((e,t)=>{const r=e.operation
|
|
3500
|
+
if("create"===r){e.name||t.addIssue({code:"custom",message:"name is required for 'create'. Letters, numbers, hyphens, underscores only."}),void 0===e.content&&t.addIssue({code:"custom",message:"content is required for 'create' (use empty string for an empty body)."})
|
|
3501
|
+
const r=s.QUEST_METADATA_KEYS.filter((t=>void 0!==e[t]))
|
|
3502
|
+
r.length>0&&t.addIssue({code:"custom",message:`Quest metadata fields (${r.join(", ")}) are not allowed on plan_write create. Quests are created via the UI flow at /quests/new. plan_write update still works on existing Quest documents.`})}else e.planId||t.addIssue({code:"custom",message:`planId is required for '${r}'.`})
|
|
3503
|
+
if("append"!==r||e.content||t.addIssue({code:"custom",message:'content is required for \'append\'. Example: { "operation": "append", "planId": "plan000001", "content": "..." }'}),"update"===r){const r=void 0!==e.content,n=void 0!==e.criteria||void 0!==e.tickIntervalSeconds||void 0!==e.maxInFlight||void 0!==e.maxPerDay||void 0!==e.minIterations||void 0!==e.status||void 0!==e.completionMode
|
|
3504
|
+
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, completionMode \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.QuestSetCriteriaStatusesSchema=r.z.object({questId:r.z.string().min(1).describe("The quest documentId whose criteria to update."),updates:r.z.array(r.z.object({id:r.z.string().min(1).describe("Criterion id (must match an existing item in metadata.criteria)."),status:r.z.enum(["unverified","verified"]).describe("New status for this criterion."),evidence:r.z.string().optional().describe("Optional evidence note (file path, request id, test name, command output, etc.) describing why the status changed.")})).min(1).describe("One or more per-criterion updates. Each id must exist in the quest's metadata.criteria; unknown ids return an error listing the valid ids. Updates merge into the existing item (other fields preserved); only status and evidence change.")}),exports.QuestAuditCompleteSchema=r.z.object({questId:r.z.string().min(1).describe("The quest documentId to audit (the long uuid form returned by plan_write create, or the project-scoped doc000NN id)."),summary:r.z.string().min(1).describe("Short prose summary of what evidence the audit found. Stored on the quest if this call reaches the threshold and flips status \u2014 visible to the user when they review."),evidence:r.z.array(r.z.string()).optional().describe("Optional list of evidence references (file paths, request IDs, test names, command outputs) that support the audit conclusion. Stored on the quest alongside the summary if status flips.")}),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:c,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:l.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(d).refine(u,{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:l.optional()}).transform(d).refine(u,{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:c.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(),skipTestsReason:exports.skipTestsReasonSchema,skipTests:exports.skipTestsSchema})).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(),planDocumentId:r.z.string().optional().describe("Narrow to requests linked to this Plan document (use the plan's id or local id)."),questDocumentId:r.z.string().optional().describe("Narrow to requests spawned under this Quest document (use the quest's id or local id)."),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(),planDocumentId:r.z.string().optional().describe("Narrow to requests linked to this Plan document."),questDocumentId:r.z.string().optional().describe("Narrow to requests spawned under this Quest document."),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
|
|
3462
3505
|
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]
|
|
3463
|
-
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:
|
|
3464
|
-
const
|
|
3465
|
-
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 for your current request \u2014 optional `process` picks one configured process (by name or id), optional `name` filters to one registered command. The call returns immediately and you receive a report on your next turn.'),process:r.z.string().optional().describe('Only used by `run`. Picks a single test process by name (case-insensitive) or id. Omit to run every active test process for this project. Use `operation: "list"` to see available process names.'),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"
|
|
3506
|
+
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:l.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(d).refine(u,{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:l.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(d).refine(u,{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:l.optional()}).transform(d).refine(u,{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","ask-me","test-by-default","always-test"]).optional().describe("Testing axis: auto-merge (skip tests), ask-me (notify human on completion), test-by-default (tests run; opt-out allowed), always-test (tests required)"),reviewMode:r.z.enum(["auto-finalize","manual-review"]).optional().describe("Review axis: auto-finalize (server merges on pass/skip) or manual-review (human approves via UI)"),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","ask-me","test-by-default","always-test"]).optional().describe("Testing axis"),reviewMode:r.z.enum(["auto-finalize","manual-review"]).optional().describe("Review axis"),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")})
|
|
3507
|
+
const m=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)")})
|
|
3508
|
+
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(m).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(m).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 for your current request \u2014 optional `process` picks one configured process (by name or id), optional `name` filters to one registered command. The call returns immediately and you receive a report on your next turn.'),process:r.z.string().optional().describe('Only used by `run`. Picks a single test process by name (case-insensitive) or id. Omit to run every active test process for this project. Use `operation: "list"` to see available process names.'),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"
|
|
3466
3509
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3467
3510
|
const r=t(6183),n=t(405)
|
|
3468
|
-
exports.def={name:"plan_write",description:"Create and modify project plans (
|
|
3511
|
+
exports.def={name:"plan_write",description:"Create and modify project plans. Also supports metadata updates on existing Quest documents (quests are created via the UI flow at /quests/new, not through this tool).\n\nOperations:\n\u2022 create - Create a new Plan document. Pass name + content. Quest metadata fields (criteria, tickIntervalSeconds, maxInFlight, maxPerDay, minIterations, status, completionMode) are not allowed on create.\n\u2022 update - Update plan content or quest metadata. For Quest documents, accepts criteria / tickIntervalSeconds / maxInFlight / maxPerDay / minIterations / status (open|pending_review|closed) / completionMode (auto-close|audit-then-pending|never-close). The LLM cannot set status='closed' directly \u2014 only the user closes a quest; the LLM may set status='pending_review' to pause ticks for user adjudication.\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"
|
|
3469
3512
|
module.exports=require("events")},6285(e,exports,t){"use strict"
|
|
3470
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,d,u,h,p,
|
|
3513
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,d,u,h,p,m){const g=u.child({tool:"specialist_ops"}),f=h.startTimer("tool_execution_time")
|
|
3471
3514
|
try{const u=e,{operation:y,sessionId:w}=u
|
|
3472
3515
|
let I
|
|
3473
|
-
switch(
|
|
3516
|
+
switch(g.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=m?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3474
3517
|
if(r&&p){const t=await async function(e,t,r,o,s){o.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
|
|
3475
3518
|
const a=await(0,i.getServerUrl)(r,o)
|
|
3476
3519
|
if(a)try{const r=await fetch(a.replace(/\/$/,"")+"/session")
|
|
@@ -3484,31 +3527,31 @@ return"specialist"===t?.agentType&&"archived"!==t?.status}))
|
|
|
3484
3527
|
if(o.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
|
|
3485
3528
|
const p=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
|
|
3486
3529
|
return` \u2022 ${e.id} \u2014 ${n} [${r}]`})).join("\n")
|
|
3487
|
-
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,
|
|
3530
|
+
return{content:[{type:"text",text:`\u274c Specialist pool is full (${h.length}/${t}).\nAbort an idle specialist first with \`specialist_ops abort\`, then delegate again.\n\nCurrent pool:\n`+p}],isError:!0}}catch(e){return void o.warn("Pool limit check failed, allowing spawn",{error:(0,n.getErrorMessage)(e)})}}(r,e,d,g,p)
|
|
3488
3531
|
if(t){I=t
|
|
3489
3532
|
break}}let c=u.description||u.prompt.slice(0,60)
|
|
3490
3533
|
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`)
|
|
3491
|
-
if(r)try{const e=await(0,i.getServerUrl)(d,
|
|
3534
|
+
if(r)try{const e=await(0,i.getServerUrl)(d,g)
|
|
3492
3535
|
if(h(`serverUrl=${e}, parentId=${r}`),e){const t=await fetch(e.replace(/\/$/,"")+"/session")
|
|
3493
3536
|
if(h("session fetch status="+t.status),t.ok){const e=(await t.json()).filter((e=>(e.parentId||e.parentID)===r)).map((e=>e.title||""))
|
|
3494
3537
|
h(`siblings=${e.length}: ${e.join(", ")}`)
|
|
3495
3538
|
const n=(0,o.pickSpecialistName)(e)
|
|
3496
3539
|
c=n,h("picked name: "+n)}}else h("no serverUrl")}catch(e){h("error: "+(e instanceof Error?e.message:e+""))}else h("no parentId")
|
|
3497
|
-
I=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,
|
|
3498
|
-
break}case"follow-up":{const e=await(0,i.getServerUrl)(d,
|
|
3540
|
+
I=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,g,p,m)
|
|
3541
|
+
break}case"follow-up":{const e=await(0,i.getServerUrl)(d,g)
|
|
3499
3542
|
if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
|
|
3500
3543
|
if(t.ok){const e=await t.json(),r=e[w]?.type
|
|
3501
3544
|
if(r&&"idle"!==r&&"prompting"!==r){I={content:[{type:"text",text:`\u274c Specialist ${w} is currently busy (status: ${r}).\nUse \`delegate\` to spawn a new specialist instead.`}],isError:!0}
|
|
3502
|
-
break}}}catch{}I=await(0,s.handleContinue)(w,u.prompt,d,
|
|
3503
|
-
break}case"check-status":I=await(0,s.handleCheckStatus)(w,d,
|
|
3545
|
+
break}}}catch{}I=await(0,s.handleContinue)(w,u.prompt,d,g,p,"specialist",m)
|
|
3546
|
+
break}case"check-status":I=await(0,s.handleCheckStatus)(w,d,g,p)
|
|
3504
3547
|
break
|
|
3505
|
-
case"abort":if(I=await(0,s.handleAbort)(w,d,
|
|
3548
|
+
case"abort":if(I=await(0,s.handleAbort)(w,d,g),!I.isError&&p)try{const e=p.getCLISessionClient()
|
|
3506
3549
|
e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
|
|
3507
|
-
case"list":{const e=
|
|
3508
|
-
I=await(0,s.handleListSessions)(d,
|
|
3550
|
+
case"list":{const e=m?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
|
|
3551
|
+
I=await(0,s.handleListSessions)(d,g,p,{activeOnly:u.activeOnly,requestId:u.requestId,limit:u.limit,agentType:"specialist",parentSessionId:e})
|
|
3509
3552
|
break}default:throw new r.ValidationError("Unknown operation: "+y)}f({success:!0}),h.incrementCounter(`specialist_ops_${y}_success`,1)
|
|
3510
3553
|
const b=l[y]??"specialist-delegate"
|
|
3511
|
-
return(0,c.withAlchemyKind)(I,b)}catch(e){return
|
|
3554
|
+
return(0,c.withAlchemyKind)(I,b)}catch(e){return g.error("Specialist ops failed",{error:e instanceof Error?e.stack:e+""}),f({success:!1}),h.incrementCounter("specialist_ops_errors",1),{content:[{type:"text",text:"Specialist operation failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}}
|
|
3512
3555
|
const r=t(9860),n=t(8824),o=t(9089),s=t(1725),i=t(7617),a=t(6688),c=t(2272),l={delegate:"specialist-delegate","follow-up":"specialist-follow-up","check-status":"specialist-check-status",abort:"specialist-abort",list:"specialist-list"}},6309(e,exports,t){"use strict"
|
|
3513
3556
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3514
3557
|
const r=t(6183),n=t(8184)
|
|
@@ -3527,16 +3570,16 @@ return o(t,e),t})
|
|
|
3527
3570
|
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")
|
|
3528
3571
|
try{const n=e,{requestId:l,reason:h,confirmDestructive:p}=n
|
|
3529
3572
|
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}
|
|
3530
|
-
let
|
|
3573
|
+
let m
|
|
3531
3574
|
try{const e=await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/validate-revert`,{})
|
|
3532
|
-
|
|
3533
|
-
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:
|
|
3534
|
-
return
|
|
3535
|
-
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: ${
|
|
3575
|
+
m=e?.data||e}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3576
|
+
return s.error("Server validation failed",{requestId:l,error:t}),u({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate revert: "+t}],isError:!0}}if(s.info("Server validation result",{requestId:l,canRevert:m.canRevert,operationType:m.operationType,mergeCommitHash:m.mergeCommitHash?.substring(0,8),reason:m.reason}),!m.canRevert){let e=`Cannot revert request ${l}: ${m.reason}\n`
|
|
3577
|
+
return m.lifoViolation?.blockingRequests?.length&&(e+="\n**Requests that must be reverted first (in reverse order):**\n",m.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (${t.status})\n`})),e+="\n**Why:** Requests must be reverted in reverse order (LIFO) to maintain safe git history.\n",e+="Revert the above request(s) first, then retry this one."),u({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if("cancel"===m.operationType){s.info("Cancel operation \u2014 delegating to server",{requestId:l})
|
|
3578
|
+
try{return await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/finalize-revert`,{reason:h,operationType:"cancel"}),u({success:!0}),{content:[{type:"text",text:`Successfully canceled request ${l}.\n\nOperation: Cancel (no git changes)\nTasks updated: ${m.tasksToUpdate.length} task(s) marked as canceled\nReason: ${h}`}]}}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3536
3579
|
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})
|
|
3537
3580
|
t.syncBranchState&&await t.syncBranchState()
|
|
3538
|
-
let m
|
|
3539
|
-
if(!
|
|
3581
|
+
let g=m.mergeCommitHash
|
|
3582
|
+
if(!g){s.info("No merge commit hash from server, searching git log",{requestId:l})
|
|
3540
3583
|
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(" ")
|
|
3541
3584
|
return-1===t?{hash:e,message:""}:{hash:e.substring(0,t),message:e.substring(t+1)}})):[],s=a.generateMergeMessagePatterns(e)
|
|
3542
3585
|
for(const e of s){let t
|
|
@@ -3544,14 +3587,14 @@ if(e.includes("\\")||e.includes(".*")){const r=RegExp(e,"i")
|
|
|
3544
3587
|
t=o.find((e=>r.test(e.message)))}else t=o.find((t=>t.message.includes(e)))
|
|
3545
3588
|
if(t)return{found:!0,commitHash:t.hash}}return{found:!1}}catch(t){return r.error("Failed to find merge commit",{requestId:e,error:(0,d.getErrorMessage)(t)}),{found:!1}}}(l,t,s)
|
|
3546
3589
|
if(!e.found||!e.commitHash)return u({success:!1,error:"merge_commit_not_found"}),{content:[{type:"text",text:"Could not find merge commit for request "+l}],isError:!0}
|
|
3547
|
-
|
|
3590
|
+
g=e.commitHash}const f=t.workspaceManager.getMainGit(),y=await a.getRepositoryStatus(f,s,o)
|
|
3548
3591
|
if(y.currentBranch!==y.defaultBranch){const e=await a.switchToBranch(f,y.defaultBranch||"main",s,o)
|
|
3549
3592
|
if(!e.success)return u({success:!1,error:"branch_switch_failed"}),{content:[{type:"text",text:"Failed to switch to main branch: "+e.message}],isError:!0}}let w
|
|
3550
|
-
try{s.info("Executing git revert",{mergeCommitHash:
|
|
3593
|
+
try{s.info("Executing git revert",{mergeCommitHash:g.substring(0,8)}),await f.raw(["revert","-m","1","--no-edit",g]),w=await(0,c.captureCommitHashRobustly)(f,s,"revert-request-"+l,3,150)
|
|
3551
3594
|
const e=await(0,c.verifyGitStateConsistency)(f,w,s,`revert-request-${l}-verification`)
|
|
3552
|
-
e.consistent||s.error("Git state inconsistency after revert",{issues:e.issues}),s.info("Git revert completed",{requestId:l,originalMergeCommit:
|
|
3553
|
-
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:
|
|
3554
|
-
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: ${
|
|
3595
|
+
e.consistent||s.error("Git state inconsistency after revert",{issues:e.issues}),s.info("Git revert completed",{requestId:l,originalMergeCommit:g.substring(0,8),revertCommitHash:w.substring(0,8)})}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3596
|
+
return s.error("Git revert failed",{requestId:l,error:t}),u({success:!1,error:"git_revert_failed"}),{content:[{type:"text",text:"Git revert failed: "+t}],isError:!0}}try{await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/finalize-revert`,{reason:h,operationType:"revert",revertCommitHash:w,originalMergeCommitHash:g})}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
3597
|
+
return s.error("CRITICAL: Git revert succeeded but server finalization failed",{requestId:l,revertCommitHash:w,error:t}),u({success:!1,error:"finalization_failed"}),{content:[{type:"text",text:`CRITICAL: Git revert succeeded (commit: ${w.substring(0,8)}) but failed to update server state: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:`Successfully reverted request ${l}.\n\nOperation: Revert (git revert of merge commit)\nTasks updated: ${m.tasksToUpdate.length} task(s) marked as reverted\nReason: ${h}\n\nYou can re-complete the request if the revert was a mistake.`}]}}catch(n){if(n instanceof i.ValidationError||n instanceof i.NotFoundError)return s.warn("Revert validation failed",{error:n.message,requestId:e.requestId}),u({success:!1,error:"validation"}),{content:[{type:"text",text:"Error: "+n.message}],isError:!0}
|
|
3555
3598
|
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}
|
|
3556
3599
|
if(t.projectId&&e.requestId)try{const o=r.getToolRecordClient()
|
|
3557
3600
|
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}}}
|
|
@@ -3577,15 +3620,15 @@ const s=[...t].sort(((e,t)=>"between"===e.type&&"between"===t.type?(t.afterLine|
|
|
|
3577
3620
|
for(const e of s){const t={type:e.type,line:e.line,afterLine:e.afterLine,beforeLine:e.beforeLine,success:!1}
|
|
3578
3621
|
try{let n
|
|
3579
3622
|
switch(e.type){case"before":if(void 0===e.line)throw Error("Line number is required for before insertion")
|
|
3580
|
-
n=(0,
|
|
3623
|
+
n=(0,g.insertBeforeLine)(r,e.line,e.content)
|
|
3581
3624
|
break
|
|
3582
3625
|
case"after":if(void 0===e.line)throw Error("Line number is required for after insertion")
|
|
3583
|
-
n=(0,
|
|
3626
|
+
n=(0,g.insertAfterLine)(r,e.line,e.content)
|
|
3584
3627
|
break
|
|
3585
3628
|
case"between":if(void 0===e.afterLine||void 0===e.beforeLine)throw Error("Both afterLine and beforeLine are required for between insertion")
|
|
3586
|
-
n=(0,
|
|
3629
|
+
n=(0,g.insertBetweenLines)(r,e.afterLine,e.beforeLine,e.content)
|
|
3587
3630
|
break
|
|
3588
|
-
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,
|
|
3631
|
+
default:throw Error("Unknown insertion type: "+e.type)}r=n.newContent,t.success=!0,t.linesAdded=n.linesAdded,t.insertionPoint=n.insertionPoint,o+=n.linesAdded}catch(e){t.error=(0,m.getErrorMessage)(e)}n.push(t)}return{newContent:r,results:n}}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3589
3632
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3590
3633
|
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=[]
|
|
3591
3634
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3593,7 +3636,7 @@ return t},n(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3593
3636
|
var t={}
|
|
3594
3637
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3595
3638
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3596
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleInsertLines=async function(e,n,o,s,i,a,
|
|
3639
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleInsertLines=async function(e,n,o,s,i,a,g,f){const y=a.child({tool:"insert_lines"}),w=Date.now()
|
|
3597
3640
|
let I,b,k=l.FileOperationPhase.VALIDATION
|
|
3598
3641
|
const v={toolName:"insert-lines",operationName:"insert-lines",fileOperationPhase:l.FileOperationPhase.FILE_WRITE,recordType:"insert-lines",metricsPrefix:"insert_lines",successMessage:"Successfully inserted lines into files and documents",failureMessage:"Failed to insert lines into files and documents"}
|
|
3599
3642
|
try{const C=e,{operations:_,comment:E}=C,{enforceActiveTask:S}=await Promise.resolve().then(t.bind(t,3451)),q=await S(n,o,a)
|
|
@@ -3608,55 +3651,55 @@ j.push({type:"file",path:t,fullPath:r,insertions:e.insertions})}const R=[]
|
|
|
3608
3651
|
if(x.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3609
3652
|
for(const e of x)R.push({type:"document",documentId:e.documentId,insertions:e.insertions})
|
|
3610
3653
|
if(R.length>0&&n.apiClient){const e=R.map((e=>e.documentId))
|
|
3611
|
-
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,y,
|
|
3612
|
-
throw e}}k=l.FileOperationPhase.TASK_VALIDATION,
|
|
3613
|
-
const M=j.length>0?j[0].path:"document-operation",$=await l.validateTaskId(T,M,o,y,
|
|
3654
|
+
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,y,g,"insert-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3655
|
+
throw e}}k=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3656
|
+
const M=j.length>0?j[0].path:"document-operation",$=await l.validateTaskId(T,M,o,y,g,v.metricsPrefix),O=$?.requestId
|
|
3614
3657
|
let D=null
|
|
3615
|
-
j.length>0&&O&&(D=await l.validateWorkItemStates(T,j[0].path,o,i,n,y,
|
|
3658
|
+
j.length>0&&O&&(D=await l.validateWorkItemStates(T,j[0].path,o,i,n,y,g,v.metricsPrefix))
|
|
3616
3659
|
let A={taskPromoted:!1,requestPromoted:!1}
|
|
3617
|
-
j.length>0&&O&&D&&(A=await l.autoPromoteTaskStatus(T,$.status,O,D.request?.status,j[0].path,o,i,y,
|
|
3618
|
-
const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:O,context:n,operation:"insert-lines",logger:y,metrics:
|
|
3660
|
+
j.length>0&&O&&D&&(A=await l.autoPromoteTaskStatus(T,$.status,O,D.request?.status,j[0].path,o,i,y,g,v.metricsPrefix),A.taskPromoted&&y.info("Auto-promoted task to in_progress for insert-lines operation",{taskId:T,requestId:O,previousStatus:$.status,newStatus:A.newTaskStatus,triggeringOperation:"insert-lines"}))
|
|
3661
|
+
const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:O,context:n,operation:"insert-lines",logger:y,metrics:g,metricsPrefix:v.metricsPrefix})
|
|
3619
3662
|
if(!F.success)throw Error(F.error)
|
|
3620
3663
|
if(j.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:j.length,workspaceBasePath:n.workspaceManager?.getCurrentContext(n.currentSessionId).basePath})
|
|
3621
3664
|
for(let e=0;e<j.length;e++){const t=j[e],r=P[e],{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(r.path,n)
|
|
3622
|
-
j[e]={...t,path:o,fullPath:s}}}if(R.length>0&&O)try{await(0,u.validateRequestStatusForDocumentOperation)(O,i,y,
|
|
3623
|
-
throw e}k=l.FileOperationPhase.RECORD_CREATION,
|
|
3624
|
-
const N=[...j.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...R.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:z}=await l.createFileOperationRecords(T,O,n.projectId,v.recordType,M,{operationCount:_.length,fileOperations:j.length,documentOperations:R.length,operations:N,userComment:E},o,s,y,
|
|
3625
|
-
if(I=z,b=z,k=v.fileOperationPhase,
|
|
3626
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"insert-lines",{requestId:O,taskId:T,workspaceManager:n.workspaceManager},y,
|
|
3665
|
+
j[e]={...t,path:o,fullPath:s}}}if(R.length>0&&O)try{await(0,u.validateRequestStatusForDocumentOperation)(O,i,y,g,"insert-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3666
|
+
throw e}k=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("insert_lines_phase",1,{phase:k})
|
|
3667
|
+
const N=[...j.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...R.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:z}=await l.createFileOperationRecords(T,O,n.projectId,v.recordType,M,{operationCount:_.length,fileOperations:j.length,documentOperations:R.length,operations:N,userComment:E},o,s,y,g,v.metricsPrefix,f)
|
|
3668
|
+
if(I=z,b=z,k=v.fileOperationPhase,g.incrementCounter("insert_lines_phase",1,{phase:k}),j.length>0&&n.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
|
|
3669
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"insert-lines",{requestId:O,taskId:T,workspaceManager:n.workspaceManager},y,g)
|
|
3627
3670
|
e.userChangesCommitted&&(y.debug("[INSERT-LINES] User changes committed before insert operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),y.info("User changes committed before insert-lines operation",{taskId:T,fileOperationsCount:j.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){y.debug("[INSERT-LINES] Pre-tool commit failed, continuing with insertions",{error:e instanceof Error?e.message:e+""}),y.warn("Pre-tool user changes commit failed, continuing with insert operation",{taskId:T,fileOperationsCount:j.length,error:e instanceof Error?e.message:e+""})}y.debug("[INSERT-LINES] Proceeding with file operations",{fileCount:j.length})
|
|
3628
3671
|
const L=[]
|
|
3629
3672
|
let H=0,B=0,U=0
|
|
3630
3673
|
for(const e of j){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3631
3674
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3632
3675
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.insertions)
|
|
3633
|
-
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,
|
|
3676
|
+
t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,U++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,m.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}L.push(t)}for(const e of R){const t={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
|
|
3634
3677
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3635
3678
|
t.filename=s?.filename
|
|
3636
3679
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
|
|
3637
|
-
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,
|
|
3638
|
-
t?.success&&await n.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const W=await l.handleMultiFileGitCommit(T,j,L,U,{operationType:"Insert lines",toolRecordId:b,successField:"successfulInsertions",logger:y,metrics:
|
|
3639
|
-
try{await s.updateToolRecord(b,{metadata:{path:j.length>0?j[0].path:"document:"+R[0]?.documentId,status:
|
|
3680
|
+
t.insertions=l,t.successfulInsertions=l.filter((e=>e.success)).length,t.failedInsertions=l.filter((e=>!e.success)).length,t.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&t.successfulInsertions>0?(await c.default.writeFile(o,a,"utf8"),n.documentFileManager.markForSync(e.documentId),t.success=!0,U++,y.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,m.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:t.error})}L.push(t)}if(R.length>0)try{for(const e of R){const t=L.find((t=>t.documentId===e.documentId))
|
|
3681
|
+
t?.success&&await n.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const W=await l.handleMultiFileGitCommit(T,j,L,U,{operationType:"Insert lines",toolRecordId:b,successField:"successfulInsertions",logger:y,metrics:g,metricsPrefix:"insert_lines"},n),G=l.processMultiFileOperationResults(L,"successfulInsertions"),{successfulOperations:V,failedOperations:Q,totalSuccessfulChanges:K,overallSuccess:J,successfulFiles:Y,failedFiles:Z}=G
|
|
3682
|
+
try{await s.updateToolRecord(b,{metadata:{path:j.length>0?j[0].path:"document:"+R[0]?.documentId,status:J?"completed":"failed",error:J?void 0:Q+" operations failed",totalOperations:L.length,successfulFiles:Y,failedFiles:Z,operations:N,totalSuccessfulInsertions:K,totalFailedInsertions:H,totalLinesAdded:B,operationsWithChanges:U,processingTime:Date.now()-w,userComment:E,...j.length>0&&W.success&&W.commitHash&&{commitHash:W.commitHash,previousCommitHash:W.previousCommitHash||void 0}},note:J?`Line insertion completed: ${V}/${L.length} operations successful${j.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${Q}/${L.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let X="## Line Insertion Results\n\n"
|
|
3640
3683
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
3641
|
-
e.permanentBranch||(X+=`**Branch:** \`${e.branchName}\`\n\n`)}if(X+="**Summary:**\n",X+=`- **Files processed:** ${V+
|
|
3684
|
+
e.permanentBranch||(X+=`**Branch:** \`${e.branchName}\`\n\n`)}if(X+="**Summary:**\n",X+=`- **Files processed:** ${V+Q}\n`,X+=`- **Successful operations:** ${V}\n`,X+=`- **Failed operations:** ${Q}\n`,X+=`- **Total insertions:** ${K} successful, ${H} failed\n`,X+=`- **Total Lines Added:** ${B}\n`,X+="\n",W.success&&W.commitHash&&(X+="**Git Commit:**\n",X+=`- **Commit Hash:** ${W.commitHash.substring(0,8)}\n`,X+=`- **Files Committed:** ${W.filesCommitted.length}\n`,W.previousCommitHash&&(X+=`- **Previous Commit:** ${W.previousCommitHash.substring(0,8)}\n`),X+="\n"),1===L.length){const e=L[0]
|
|
3642
3685
|
if(X+=`**Operation:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,"file"===e.type?X+=`**File:** ${e.path}\n`:(X+="**Document:** "+e.documentId,e.filename&&(X+=` (${e.filename})`),X+="\n"),e.error?X+=`**Error:** ${e.error}\n`:(X+=`**Insertions:** ${e.successfulInsertions} successful`,e.failedInsertions>0&&(X+=`, ${e.failedInsertions} failed`),X+="\n",X+=`**Lines Added:** ${e.totalLinesAdded}\n`),e.insertions.some((e=>!e.success))){X+="**Failed Insertion Details:**\n"
|
|
3643
3686
|
for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?`between lines ${t.afterLine} and ${t.beforeLine}`:`${t.type} line ${t.line}`
|
|
3644
|
-
X+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{X+="**Summary:**\n",X+=`- **Total Operations:** ${L.length}\n`,X+=`- **Successful:** ${V}\n`,X+=`- **Failed:** ${
|
|
3687
|
+
X+=`- ${t.type} insertion ${e}: ${t.error}\n`}}}else{X+="**Summary:**\n",X+=`- **Total Operations:** ${L.length}\n`,X+=`- **Successful:** ${V}\n`,X+=`- **Failed:** ${Q}\n`,X+=`- **Total Insertions:** ${K} successful, ${H} failed\n`,X+=`- **Total Lines Added:** ${B}\n\n`,X+="**Detailed Results:**\n\n"
|
|
3645
3688
|
for(const e of L){if("file"===e.type?X+=`### File: ${e.path}\n`:(X+="### Document: "+e.documentId,e.filename&&(X+=` (${e.filename})`),X+="\n"),X+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error?X+=`- **Error:** ${e.error}\n`:(X+=`- **Insertions:** ${e.successfulInsertions} successful`,e.failedInsertions>0&&(X+=`, ${e.failedInsertions} failed`),X+="\n",X+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.insertions.some((e=>!e.success))){X+="- **Failed Insertion Details:**\n"
|
|
3646
3689
|
for(const t of e.insertions.filter((e=>!e.success))){const e="between"===t.type?`between lines ${t.afterLine} and ${t.beforeLine}`:`${t.type} line ${t.line}`
|
|
3647
3690
|
X+=` - ${t.type} insertion ${e}: ${t.error}\n`}}X+="\n"}}R.length>0&&(X+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
|
|
3648
3691
|
const ee=Date.now()-w
|
|
3649
|
-
return y.info("Insert lines operation completed",{duration:ee,success:
|
|
3650
|
-
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),b)try{await s.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,
|
|
3651
|
-
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),
|
|
3692
|
+
return y.info("Insert lines operation completed",{duration:ee,success:J,totalOperations:L.length,successfulOperations:V,failedOperations:Q}),g.incrementCounter("insert_lines_total",1,{success:J}),{content:[{type:"text",text:X}],isError:!J}}catch(t){const r=Date.now()-w
|
|
3693
|
+
if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),b)try{await s.updateToolRecord(b,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return g.incrementCounter("insert_lines_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
3694
|
+
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),m=t(8824),g=t(3255)},6539(e,exports,t){"use strict"
|
|
3652
3695
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
|
|
3653
|
-
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),
|
|
3696
|
+
const r=t(1253),n=t(5681),o=t(6595),s=t(3895),i=t(6848),a=t(6153),c=t(4710),l=t(6975),d=t(1887),u=t(1666),h=t(8824),p=t(9884),m=t(2968),g=t(922)
|
|
3654
3697
|
exports.ClientFactory=class{static async createClient(e,f,y,w={}){(f=f.child({component:"client-factory"})).info("Creating API client with components")
|
|
3655
3698
|
const I=w.tokenManager||new r.TokenManager(f,w.workingDir||process.cwd())
|
|
3656
3699
|
await I.initialize()
|
|
3657
3700
|
const b=w.tokenSynchronizer||new i.ClientTokenSynchronizer(f),k=new s.AuthenticationManager(I,f,b),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})
|
|
3658
3701
|
b.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
|
|
3659
|
-
const E=new
|
|
3702
|
+
const E=new m.TaskClient(e,f,y,_,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3660
3703
|
b.registerClient(E)
|
|
3661
3704
|
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})
|
|
3662
3705
|
b.registerClient(S),f.info("RequestClient constructor received token: "+(v?"present":"missing"))
|
|
@@ -3664,7 +3707,7 @@ const q=new u.RequestClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts
|
|
|
3664
3707
|
b.registerClient(q),f.info("RequestClient post-constructor token: "+(q.getAuthToken()?"present":"missing"))
|
|
3665
3708
|
const T=new p.DocumentClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3666
3709
|
b.registerClient(T)
|
|
3667
|
-
const P=new
|
|
3710
|
+
const P=new g.ToolRecordClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3668
3711
|
b.registerClient(P)
|
|
3669
3712
|
const x=new d.ProxyClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
|
|
3670
3713
|
if(b.registerClient(x),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
|
|
@@ -3706,8 +3749,8 @@ async function r(e,t){let r=e
|
|
|
3706
3749
|
const n=[],o=[...t].sort(((e,t)=>{const r=e=>"number"==typeof e?e:Array.isArray(e)?Math.max(...e):e.end
|
|
3707
3750
|
return r(t.lines)-r(e.lines)}))
|
|
3708
3751
|
for(const e of o){const t={lines:e.lines,success:!1}
|
|
3709
|
-
try{const n=(0,
|
|
3710
|
-
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,
|
|
3752
|
+
try{const n=(0,g.replaceLines)(r,e.lines,e.content)
|
|
3753
|
+
r=n.newContent,t.success=!0,t.linesReplaced=n.linesReplaced,t.linesAdded=n.linesAdded,t.startLine=n.startLine,t.endLine=n.endLine}catch(e){t.error=(0,m.getErrorMessage)(e)}n.push(t)}return{newContent:r,results:n}}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
3711
3754
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
3712
3755
|
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=[]
|
|
3713
3756
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -3715,7 +3758,7 @@ return t},n(e)},function(e){if(e&&e.__esModule)return e
|
|
|
3715
3758
|
var t={}
|
|
3716
3759
|
if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
|
|
3717
3760
|
return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
3718
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceLines=async function(e,n,o,s,i,a,
|
|
3761
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceLines=async function(e,n,o,s,i,a,g,y){const w=a.child({tool:"replace_lines"}),I=Date.now()
|
|
3719
3762
|
let b,k,v=l.FileOperationPhase.VALIDATION
|
|
3720
3763
|
const C={toolName:"replace-lines",operationName:"replace-lines",fileOperationPhase:l.FileOperationPhase.STRING_REPLACEMENT,recordType:"replace-lines",metricsPrefix:"replace_lines",successMessage:"Successfully replaced lines in files and documents",failureMessage:"Failed to replace lines in files and documents"}
|
|
3721
3764
|
try{const _=e,{operations:E,comment:S}=_,{enforceActiveTask:q}=await Promise.resolve().then(t.bind(t,3451)),T=await q(n,o,a,e.taskId)
|
|
@@ -3730,55 +3773,55 @@ R.push({type:"file",path:t,fullPath:r,replacements:e.replacements.map((e=>({line
|
|
|
3730
3773
|
if(j.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
|
|
3731
3774
|
for(const e of j)M.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,f.parseLineSpec)(e.lines),content:e.content})))})
|
|
3732
3775
|
if(M.length>0&&n.apiClient){const e=M.map((e=>e.documentId))
|
|
3733
|
-
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,w,
|
|
3734
|
-
throw e}}v=l.FileOperationPhase.TASK_VALIDATION,
|
|
3735
|
-
const $=R.length>0?R[0].path:"document-operation",O=await l.validateTaskId(P,$,o,w,
|
|
3776
|
+
try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,w,g,"replace-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3777
|
+
throw e}}v=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3778
|
+
const $=R.length>0?R[0].path:"document-operation",O=await l.validateTaskId(P,$,o,w,g,C.metricsPrefix),D=O?.requestId
|
|
3736
3779
|
let A=null
|
|
3737
|
-
R.length>0&&D&&(A=await l.validateWorkItemStates(P,R[0].path,o,i,n,w,
|
|
3780
|
+
R.length>0&&D&&(A=await l.validateWorkItemStates(P,R[0].path,o,i,n,w,g,C.metricsPrefix))
|
|
3738
3781
|
let F={taskPromoted:!1,requestPromoted:!1}
|
|
3739
|
-
R.length>0&&D&&A&&(F=await l.autoPromoteTaskStatus(P,O.status,D,A.request?.status,R[0].path,o,i,w,
|
|
3740
|
-
const N=await l.ensureCorrectWorkspaceContext({taskPromoted:F.taskPromoted,requestId:D,context:n,operation:"replace-lines",logger:w,metrics:
|
|
3782
|
+
R.length>0&&D&&A&&(F=await l.autoPromoteTaskStatus(P,O.status,D,A.request?.status,R[0].path,o,i,w,g,C.metricsPrefix),F.taskPromoted&&w.info("Auto-promoted task to in_progress for replace-lines operation",{taskId:P,requestId:D,previousStatus:O.status,newStatus:F.newTaskStatus,triggeringOperation:"replace-lines"}))
|
|
3783
|
+
const N=await l.ensureCorrectWorkspaceContext({taskPromoted:F.taskPromoted,requestId:D,context:n,operation:"replace-lines",logger:w,metrics:g,metricsPrefix:C.metricsPrefix})
|
|
3741
3784
|
if(!N.success)throw Error(N.error)
|
|
3742
3785
|
if(R.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:R.length,workspaceBasePath:n.workspaceManager?.getCurrentContext(n.currentSessionId).basePath})
|
|
3743
3786
|
for(let e=0;e<R.length;e++){const t=R[e],r=x[e],{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(r.path,n)
|
|
3744
|
-
R[e]={...t,path:o,fullPath:s}}}if(M.length>0&&D)try{await(0,u.validateRequestStatusForDocumentOperation)(D,i,w,
|
|
3745
|
-
throw e}v=l.FileOperationPhase.RECORD_CREATION,
|
|
3746
|
-
const z=[...R.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...M.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:L}=await l.createFileOperationRecords(P,D,n.projectId,C.recordType,$,{operationCount:E.length,fileOperations:R.length,documentOperations:M.length,operations:z,userComment:S},o,s,w,
|
|
3747
|
-
if(b=L,k=L,v=C.fileOperationPhase,
|
|
3748
|
-
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"replace-lines",{requestId:D,taskId:P,workspaceManager:n.workspaceManager},w,
|
|
3787
|
+
R[e]={...t,path:o,fullPath:s}}}if(M.length>0&&D)try{await(0,u.validateRequestStatusForDocumentOperation)(D,i,w,g,"replace-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
3788
|
+
throw e}v=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("replace_lines_phase",1,{phase:v})
|
|
3789
|
+
const z=[...R.map((e=>({type:"file",path:e.path,replacements:e.replacements}))),...M.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements})))],{toolRecordId:L}=await l.createFileOperationRecords(P,D,n.projectId,C.recordType,$,{operationCount:E.length,fileOperations:R.length,documentOperations:M.length,operations:z,userComment:S},o,s,w,g,C.metricsPrefix,y)
|
|
3790
|
+
if(b=L,k=L,v=C.fileOperationPhase,g.incrementCounter("replace_lines_phase",1,{phase:v}),R.length>0&&n.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
|
|
3791
|
+
const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"replace-lines",{requestId:D,taskId:P,workspaceManager:n.workspaceManager},w,g)
|
|
3749
3792
|
e.userChangesCommitted&&(w.debug("[REPLACE-LINES] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),w.info("User changes committed before replace-lines operation",{taskId:P,fileOperationsCount:R.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){w.debug("[REPLACE-LINES] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),w.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:P,fileOperationsCount:R.length,error:e instanceof Error?e.message:e+""})}w.debug("[REPLACE-LINES] Proceeding with file operations",{fileCount:R.length})
|
|
3750
3793
|
const H=[]
|
|
3751
3794
|
let B=0,U=0,W=0,G=0
|
|
3752
3795
|
for(const e of R){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3753
3796
|
try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
|
|
3754
3797
|
const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.replacements)
|
|
3755
|
-
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,G++,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,W+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3798
|
+
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,G++,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,W+=t.totalLinesAdded}catch(r){t.error=(0,m.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("File operation failed",{path:e.path,error:t.error})}H.push(t)}for(const e of M){const t={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
|
|
3756
3799
|
try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
|
|
3757
3800
|
t.filename=s?.filename
|
|
3758
3801
|
const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
|
|
3759
|
-
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,G++,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,W+=t.totalLinesAdded}catch(r){t.error=(0,
|
|
3760
|
-
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,R,H,G,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:
|
|
3761
|
-
try{await s.updateToolRecord(k,{metadata:{path:R.length>0?R[0].path:"document:"+M[0]?.documentId,status:Z?"completed":"failed",error:Z?void 0:
|
|
3802
|
+
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,G++,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,W+=t.totalLinesAdded}catch(r){t.error=(0,m.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:t.error})}H.push(t)}if(M.length>0)try{for(const e of M){const t=H.find((t=>t.documentId===e.documentId))
|
|
3803
|
+
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,R,H,G,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:g,metricsPrefix:"replace_lines"},n),Q=l.processMultiFileOperationResults(H,"successfulReplacements"),{successfulOperations:K,failedOperations:J,totalSuccessfulChanges:Y,overallSuccess:Z,successfulFiles:X,failedFiles:ee}=Q
|
|
3804
|
+
try{await s.updateToolRecord(k,{metadata:{path:R.length>0?R[0].path:"document:"+M[0]?.documentId,status:Z?"completed":"failed",error:Z?void 0:J+" operations failed",totalOperations:H.length,successfulFiles:X,failedFiles:ee,operations:z,totalSuccessfulReplacements:Y,totalFailedReplacements:B,totalLinesReplaced:U,totalLinesAdded:W,operationsWithChanges:G,processingTime:Date.now()-I,userComment:S,...R.length>0&&V.success&&V.commitHash&&{commitHash:V.commitHash,previousCommitHash:V.previousCommitHash||void 0}},note:Z?`Line replacement completed: ${K}/${H.length} operations successful${R.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${J}/${H.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let te="## Line Replacement Results\n\n"
|
|
3762
3805
|
if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
|
|
3763
|
-
e.permanentBranch||(te+=`**Branch:** \`${e.branchName}\`\n\n`)}if(te+="**Summary:**\n",te+=`- **Files processed:** ${J
|
|
3806
|
+
e.permanentBranch||(te+=`**Branch:** \`${e.branchName}\`\n\n`)}if(te+="**Summary:**\n",te+=`- **Files processed:** ${K+J}\n`,te+=`- **Successful operations:** ${K}\n`,te+=`- **Failed operations:** ${J}\n`,te+=`- **Total replacements:** ${Y} successful, ${B} failed\n`,te+=`- **Total Lines Replaced:** ${U}\n`,W>0&&(te+=`- **Total Lines Added:** ${W}\n`),te+="\n",V.success&&V.commitHash&&(te+="**Git Commit:**\n",te+=`- **Commit Hash:** ${V.commitHash.substring(0,8)}\n`,te+=`- **Files Committed:** ${V.filesCommitted.length}\n`,V.previousCommitHash&&(te+=`- **Previous Commit:** ${V.previousCommitHash.substring(0,8)}\n`),te+="\n"),1===H.length){const e=H[0]
|
|
3764
3807
|
if(te+=`**Operation:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,"file"===e.type?te+=`**File:** ${e.path}\n`:(te+="**Document:** "+e.documentId,e.filename&&(te+=` (${e.filename})`),te+="\n"),e.error?te+=`**Error:** ${e.error}\n`:(te+=`**Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(te+=`, ${e.failedReplacements} failed`),te+="\n",te+=`**Lines Replaced:** ${e.totalLinesReplaced}\n`,e.totalLinesAdded>0&&(te+=`**Lines Added:** ${e.totalLinesAdded}\n`)),e.replacements.some((e=>!e.success))){te+="**Failed Replacement Details:**\n"
|
|
3765
|
-
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`}}else{te+="**Summary:**\n",te+=`- **Total Operations:** ${H.length}\n`,te+=`- **Successful:** ${
|
|
3808
|
+
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`}}else{te+="**Summary:**\n",te+=`- **Total Operations:** ${H.length}\n`,te+=`- **Successful:** ${K}\n`,te+=`- **Failed:** ${J}\n`,te+=`- **Total Replacements:** ${Y} successful, ${B} failed\n`,te+=`- **Total Lines Replaced:** ${U}\n`,W>0&&(te+=`- **Total Lines Added:** ${W}\n`),te+="\n",te+="**Detailed Results:**\n\n"
|
|
3766
3809
|
for(const e of H){if("file"===e.type?te+=`### File: ${e.path}\n`:(te+="### Document: "+e.documentId,e.filename&&(te+=` (${e.filename})`),te+="\n"),te+=`- **Status:** ${e.success?"\u2705 Success":"\u274c Failed"}\n`,e.error&&(te+=`- **Error:** ${e.error}\n`),te+=`- **Replacements:** ${e.successfulReplacements} successful`,e.failedReplacements>0&&(te+=`, ${e.failedReplacements} failed`),te+="\n",te+=`- **Lines Replaced:** ${e.totalLinesReplaced}\n`,e.totalLinesAdded>0&&(te+=`- **Lines Added:** ${e.totalLinesAdded}\n`),e.replacements.some((e=>!e.success))){te+="- **Failed Replacement Details:**\n"
|
|
3767
3810
|
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")
|
|
3768
3811
|
const re=Date.now()-I
|
|
3769
|
-
return w.info("Replace lines operation completed",{duration:re,success:Z,totalOperations:H.length,successfulOperations:
|
|
3770
|
-
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,
|
|
3771
|
-
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),
|
|
3772
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreatePlan=async function(e,t,o,s,i,a
|
|
3773
|
-
try{const
|
|
3774
|
-
if(!
|
|
3775
|
-
const
|
|
3776
|
-
if(
|
|
3777
|
-
const
|
|
3778
|
-
if(
|
|
3779
|
-
|
|
3780
|
-
t&&!t.activePlanId&&(await e.updateProject(
|
|
3781
|
-
const r=t(8824)
|
|
3812
|
+
return w.info("Replace lines operation completed",{duration:re,success:Z,totalOperations:H.length,successfulOperations:K,failedOperations:J}),g.incrementCounter("replace_lines_total",1,{success:Z}),{content:[{type:"text",text:te}],isError:!Z}}catch(t){const r=Date.now()-I
|
|
3813
|
+
if(w.error("Replace lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:v}),k)try{await s.updateToolRecord(k,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:v,duration:r,userComment:e?.comment},note:"Line replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return g.incrementCounter("replace_lines_errors",1,{phase:v}),{content:[{type:"text",text:"\u274c **Replace Lines Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
|
|
3814
|
+
const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),m=t(8824),g=t(3255),f=t(9470)},6656(e,exports,t){"use strict"
|
|
3815
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreatePlan=async function(e,t,n,o,s,i,a){const c=o.child({tool:"plan_operations",operation:"create"})
|
|
3816
|
+
try{const o=t.projectId
|
|
3817
|
+
if(!o)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
|
|
3818
|
+
const s=`PLAN-${e.name.replace(/\.md$/i,"")}.md`,i=n.getDocumentClient(),l=await i.listDocuments({type:"Plan",filename:s,limit:1,offset:0})
|
|
3819
|
+
if(l&&l.length>0)return{content:[{type:"text",text:`\u274c A plan with filename "${s}" already exists (${l[0].localId||l[0].id}). Choose a different name.`}],isError:!0}
|
|
3820
|
+
const d=await i.createDocument(void 0,{filename:s,content:e.content,type:"Plan",metadata:{isStub:!0},...a&&{cliOrigin:a}}),u=d.localId||d.id,h=d.id
|
|
3821
|
+
if(a?.sessionId)try{await n.proxyPost(`/api/projects/${o}/session-plan-associations`,{opencodeSessionId:a.sessionId,documentId:h})}catch(e){c.warn("Failed to create session-plan association",{error:(0,r.getErrorMessage)(e)})}let p=!1
|
|
3822
|
+
try{const e=n.getProjectClient(),t=await e.getProject(o)
|
|
3823
|
+
t&&!t.activePlanId&&(await e.updateProject(o,{activePlanId:h}),p=!0,c.info("Auto-set as active plan",{planId:u,projectId:o}))}catch(e){c.warn("Failed to auto-set active plan",{error:(0,r.getErrorMessage)(e)})}return c.info("Plan Created",{planId:u,filename:s}),{content:[{type:"text",text:`\u2705 **Plan Created**\n\n**Plan ID:** ${u}\n**Filename:** ${s}\n**Created:** `+new Date(d.createdAt).toLocaleString()+(p?"\n\n\u{1f4cc} _Automatically set as the active project plan._":"")}]}}catch(e){return c.error("Failed to create plan",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to create plan:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
3824
|
+
const r=t(8824)},6688(e,exports,t){"use strict"
|
|
3782
3825
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
|
|
3783
3826
|
const r=t(9896),n=t(6928),o=t(3545)
|
|
3784
3827
|
exports.sessionIdentity=new class{constructor(){this.parentCache=new Map,this.sessionRequestCache=new Map}setIdentity(e){const t=this.identity
|
|
@@ -3855,18 +3898,18 @@ var t={}
|
|
|
3855
3898
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
3856
3899
|
return o(t,e),t})
|
|
3857
3900
|
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")
|
|
3858
|
-
try{const{taskId:
|
|
3859
|
-
if(!
|
|
3860
|
-
if(!(0,h.isTaskRef)(
|
|
3861
|
-
s.info("Getting file changes for task "+
|
|
3901
|
+
try{const{taskId:m,showDiff:g=!1}=e
|
|
3902
|
+
if(!m)throw(0,i.createValidationError)("Task ID is required")
|
|
3903
|
+
if(!(0,h.isTaskRef)(m))throw(0,i.createValidationError)(`Invalid task ID format: ${m}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
|
|
3904
|
+
s.info("Getting file changes for task "+m,{showDiff:g})
|
|
3862
3905
|
const f=r.getTaskClient(),y=r.getToolRecordClient(),w=t.projectId
|
|
3863
3906
|
let I
|
|
3864
3907
|
r.setProjectId(w)
|
|
3865
|
-
try{const x=await f.getTask(
|
|
3866
|
-
s.info("Raw task response data",{responseDataType:typeof x,isArray:Array.isArray(x),hasData:null!=x,properties:x&&"object"==typeof x?Object.keys(x):[]}),I=(0,l.extractDataFromResponse)(x,{logger:s,operationName:"getTask",defaultValue:{id:
|
|
3867
|
-
try{const R=await y.getToolRecordsByTaskId(
|
|
3868
|
-
if(s.info("Raw records response data",{responseDataType:typeof R,isArray:Array.isArray(R),hasData:null!=R,properties:R&&"object"==typeof R?Object.keys(R):[]}),b=(0,l.extractArrayFromResponse)(R,{logger:s,operationName:"searchRecords",defaultValue:[]}),b.length>0&&s.info("First record summary:",{id:b[0].id,type:b[0].type,hasMetadata:!!b[0].metadata,hasCommitHash:!!b[0].metadata?.commitHash}),s.info(`Extracted ${b.length} records for task ${
|
|
3869
|
-
b.forEach((e=>{M[e.type]=(M[e.type]||0)+1})),s.info("Record type distribution:",M)}}catch($){s.warn("Error fetching records for task "+
|
|
3908
|
+
try{const x=await f.getTask(m)
|
|
3909
|
+
s.info("Raw task response data",{responseDataType:typeof x,isArray:Array.isArray(x),hasData:null!=x,properties:x&&"object"==typeof x?Object.keys(x):[]}),I=(0,l.extractDataFromResponse)(x,{logger:s,operationName:"getTask",defaultValue:{id:m,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+I.title)}catch(j){s.warn("Could not fetch task information: "+(0,u.getErrorMessage)(j)),I={id:m,title:"Unknown Task",status:"unknown",description:"No description available"}}let b=[]
|
|
3910
|
+
try{const R=await y.getToolRecordsByTaskId(m)
|
|
3911
|
+
if(s.info("Raw records response data",{responseDataType:typeof R,isArray:Array.isArray(R),hasData:null!=R,properties:R&&"object"==typeof R?Object.keys(R):[]}),b=(0,l.extractArrayFromResponse)(R,{logger:s,operationName:"searchRecords",defaultValue:[]}),b.length>0&&s.info("First record summary:",{id:b[0].id,type:b[0].type,hasMetadata:!!b[0].metadata,hasCommitHash:!!b[0].metadata?.commitHash}),s.info(`Extracted ${b.length} records for task ${m}`),b.length>0){const M={}
|
|
3912
|
+
b.forEach((e=>{M[e.type]=(M[e.type]||0)+1})),s.info("Record type distribution:",M)}}catch($){s.warn("Error fetching records for task "+m,{error:(0,u.getErrorMessage)($)}),b=[]}if(0===b.length)return p({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${m}.`}]}
|
|
3870
3913
|
function k(e){const t=new Map,r=new Map,n=[]
|
|
3871
3914
|
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
|
|
3872
3915
|
if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
|
|
@@ -3887,7 +3930,7 @@ if(t&&(n=e.metadata.successfulOperations.some((e=>e&&e.source&&e.destination))),
|
|
|
3887
3930
|
if(!Array.isArray(t)||0===t.length)return s.warn("Skipping delete-files record without valid paths array: "+e.id),!1
|
|
3888
3931
|
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}))
|
|
3889
3932
|
if(s.info(`Found ${C.length} file operation records`),C.length>0){const O={}
|
|
3890
|
-
C.forEach((e=>{O[e.type]=(O[e.type]||0)+1})),s.info("Filtered record type distribution:",O)}if(0===C.length)return p({success:!0,fileChanges:0}),{content:[{type:"text",text:`No file changes found for task ${
|
|
3933
|
+
C.forEach((e=>{O[e.type]=(O[e.type]||0)+1})),s.info("Filtered record type distribution:",O)}if(0===C.length)return p({success:!0,fileChanges:0}),{content:[{type:"text",text:`No file changes found for task ${m}.`}]}
|
|
3891
3934
|
const _=new Map
|
|
3892
3935
|
C.forEach((e=>{let t=null
|
|
3893
3936
|
if(e.metadata){if(!e.metadata.commitHash){const t=["gitCommitId","commitId","commit","gitCommit"]
|
|
@@ -3921,9 +3964,9 @@ const z=new Map
|
|
|
3921
3964
|
N.forEach((e=>{e.recordId&&e.record?.metadata?.status&&(z.has(e.recordId)||z.set(e.recordId,[]),z.get(e.recordId)?.push(e.record.metadata.status))})),z.forEach(((e,t)=>{s.info(`Record ${t} status updates: ${e.join(" -> ")}`)}))
|
|
3922
3965
|
const L=N.filter((e=>e.commitHash))
|
|
3923
3966
|
if(s.info(`Found ${L.length} records with commit hash for ${F}`),0===L.length){s.info(`No commit hashes found in record metadata for ${F}, trying git log`)
|
|
3924
|
-
try{if(t.git){const
|
|
3925
|
-
if(
|
|
3926
|
-
const Y=
|
|
3967
|
+
try{if(t.git){const K={file:F,n:10},J=await t.git.log(K)
|
|
3968
|
+
if(J&&J.all&&J.all.length>0){s.info(`Found ${J.all.length} commits for ${F} using git log`)
|
|
3969
|
+
const Y=J.all.map((e=>({filePath:F,recordId:"git-"+e.hash.substring(0,8),type:"git-commit",timestamp:new Date(e.date).toISOString(),commitHash:e.hash,status:"completed",record:{id:"git-"+e.hash.substring(0,8),type:"git-commit",content:e.message,createdAt:new Date(e.date).toISOString(),metadata:{commitHash:e.hash}}})))
|
|
3927
3970
|
if(Y.length>0){const Z=Y.length>1?Y[Y.length-1]:Y[0],X=Y[0],ee=1===Y.length
|
|
3928
3971
|
s.info(ee?`Using single git commit for ${F}: ${X.commitHash?X.commitHash.substring(0,8):"unknown"}`:`Using git commits for ${F}: ${Z.commitHash?Z.commitHash.substring(0,8):"unknown"} to ${X.commitHash?X.commitHash.substring(0,8):"unknown"}`)
|
|
3929
3972
|
let te=""
|
|
@@ -3934,34 +3977,34 @@ continue}const H=L[0],B=L[L.length-1]
|
|
|
3934
3977
|
s.info(`First commit: ${H.commitHash?H.commitHash:"unknown"}, Last commit: ${B.commitHash?B.commitHash:"unknown"}`)
|
|
3935
3978
|
let U=null,W=!1
|
|
3936
3979
|
if(t.git&&H.commitHash)try{U=await(0,c.findPreviousCommit)(t.git,F,H.commitHash),U?(W=!0,s.info(`Found previous commit: ${U} for ${F}`)):s.info(`No previous commit found for ${F}, likely a new file`)}catch(ce){s.warn("Error finding previous commit for "+F,{error:(0,u.getErrorMessage)(ce)})}const G=W&&U?{...H,commitHash:U,status:"pre-task"}:H
|
|
3937
|
-
if(s.info(`Using ${W?"pre-task":"first task"} commit as baseline for ${F}: ${G.commitHash}`),s.info(`Last commit for ${F}: ${B.commitHash}`),s.info("Commits are "+(G.commitHash===B.commitHash?"identical":"different")),H.commitHash===B.commitHash&&!W){if(
|
|
3980
|
+
if(s.info(`Using ${W?"pre-task":"first task"} commit as baseline for ${F}: ${G.commitHash}`),s.info(`Last commit for ${F}: ${B.commitHash}`),s.info("Commits are "+(G.commitHash===B.commitHash?"identical":"different")),H.commitHash===B.commitHash&&!W){if(g&&!W&&t.git&&B.commitHash)try{const le=[`${B.commitHash}:${F}`]
|
|
3938
3981
|
s.info(`Getting new file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${F}`)
|
|
3939
3982
|
const de=await t.git.show(le)
|
|
3940
3983
|
if(de&&de.trim().length>0){let ue=""
|
|
3941
3984
|
const he=de.split("\n")
|
|
3942
3985
|
for(const pe of he)ue+=`+${pe}\n`
|
|
3943
3986
|
E.set(F,{firstChange:G,lastChange:B,hasDiff:!0,diffText:ue}),s.info(`Formatted new file content as diff, ${he.length} lines`)
|
|
3944
|
-
continue}}catch(
|
|
3987
|
+
continue}}catch(me){s.warn("Error getting new file content for "+F,{error:(0,u.getErrorMessage)(me)})}E.set(F,{firstChange:G,lastChange:B,hasDiff:!1,diffText:"Only one commit available for this file"})
|
|
3945
3988
|
continue}if(H.commitHash===B.commitHash&&W){if(U===H.commitHash){E.set(F,{firstChange:G,lastChange:B,hasDiff:!1,diffText:"No changes detected"})
|
|
3946
|
-
continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let V="",
|
|
3947
|
-
if(
|
|
3948
|
-
continue}let
|
|
3949
|
-
if("pre-task"===G.status?(
|
|
3989
|
+
continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let V="",Q=!1
|
|
3990
|
+
if(g||"pre-task"!==G.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",Q=!0,E.set(F,{firstChange:G,lastChange:B,hasDiff:Q,diffText:V})
|
|
3991
|
+
continue}let ge
|
|
3992
|
+
if("pre-task"===G.status?(ge=[`${G.commitHash}..${B.commitHash}`,"--",F],s.info(`Comparing pre-task commit with final commit: ${G.commitHash?G.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${F}`)):(ge=["4b825dc642cb6eb9a060e54bf8d69288fbee4904.."+B.commitHash,"--",F],s.info(`File created during task, showing full file diff using empty tree object: ${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${F}`)),V=await t.git.diff(ge),Q=!!V&&V.trim().length>0,!Q&&G.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
|
|
3950
3993
|
try{const ye=await t.git.show([`${G.commitHash}:${F}`]),we=await t.git.show([`${B.commitHash}:${F}`])
|
|
3951
|
-
if(ye!==we&&(
|
|
3952
|
-
Math.abs(Ie.length-be.length)>0&&(V+=`\n\nLine count changed: ${Ie.length} \u2192 ${be.length}`),ye.includes("\0")||we.includes("\0")?V+="\n\nBinary content detected - changes not displayed":ye.replace(/\s+/g,"")===we.replace(/\s+/g,"")&&(V+="\n\nWhitespace-only changes detected")}}catch(ke){s.warn("Error in direct file comparison: "+(ke instanceof Error?ke.message:ke+""))}}s.info(`Diff generation result for ${F}: hasDiff=${
|
|
3994
|
+
if(ye!==we&&(Q=!0,V="Changes detected through direct content comparison (not visible in standard diff)",g)){const Ie=ye.split("\n"),be=we.split("\n")
|
|
3995
|
+
Math.abs(Ie.length-be.length)>0&&(V+=`\n\nLine count changed: ${Ie.length} \u2192 ${be.length}`),ye.includes("\0")||we.includes("\0")?V+="\n\nBinary content detected - changes not displayed":ye.replace(/\s+/g,"")===we.replace(/\s+/g,"")&&(V+="\n\nWhitespace-only changes detected")}}catch(ke){s.warn("Error in direct file comparison: "+(ke instanceof Error?ke.message:ke+""))}}s.info(`Diff generation result for ${F}: hasDiff=${Q}, length=${V.length}`)}}catch(ve){if(s.warn("Error getting diff for "+F,{error:(0,u.getErrorMessage)(ve),firstCommit:H.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),V="Error getting diff: "+(0,u.getErrorMessage)(ve),"pre-task"!==H.status&&t.git)try{const Ce=[`${B.commitHash}:${F}`]
|
|
3953
3996
|
s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${F}`)
|
|
3954
3997
|
const _e=await t.git.show(Ce)
|
|
3955
|
-
if(_e&&_e.trim().length>0){if(
|
|
3998
|
+
if(_e&&_e.trim().length>0){if(g){let Ee=""
|
|
3956
3999
|
const Se=_e.split("\n")
|
|
3957
4000
|
for(const qe of Se)Ee+=`+${qe}\n`
|
|
3958
4001
|
V=Ee}else V="File created during this task. Content:\n"+_e
|
|
3959
|
-
|
|
4002
|
+
Q=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(Te){s.warn("Fallback also failed for "+F,{error:Te instanceof Error?Te.message:Te+""})}}E.set(F,{firstChange:G,lastChange:B,hasDiff:Q,diffText:V||"No changes detected between commits"})}else Q=G.commitHash!==B.commitHash,V=Q?"File has changes":"No changes detected between commits",E.set(F,{firstChange:G,lastChange:B,hasDiff:Q,diffText:V})}let S=`# File Changes for Task: ${m}\n\n`
|
|
3960
4003
|
I&&"object"==typeof I&&(S+="## Task Information\n",S+=`- **Title**: ${I.title||"Unknown"}\n`,S+=`- **Status**: ${I.status||"Unknown"}\n`,S+=`- **Description**: ${I.description||"No description"}\n\n`)
|
|
3961
4004
|
const q=3e3
|
|
3962
4005
|
let T=0,P=!1
|
|
3963
|
-
if(
|
|
3964
|
-
P=T>q,s.info(`Total diff size: ${T} lines (limit: ${q} lines)`),s.info(`Diffs ${P?"will be limited":"will be shown"} based on size`)}if(S+="## Summary\n",S+=`- **Files Modified**: ${_.size}\n`,S+=`- **Total File Operations**: ${C.length}\n`,S+="- **What's Shown**: For existing files, comparing state before task started with final state.\n",S+=" For files created during task, showing the entire file as created.\n",P?(S+=`- **Diff Display**: Limited (total diff size of ${T} lines exceeds limit of ${q} lines)\n`,S+=" Use file-history tool with individual files to see detailed changes\n\n"):S+=`- **Diff Display**: ${
|
|
4006
|
+
if(g){for(const Pe of E.values())Pe.hasDiff&&Pe.diffText&&(T+=Pe.diffText.split("\n").length)
|
|
4007
|
+
P=T>q,s.info(`Total diff size: ${T} lines (limit: ${q} lines)`),s.info(`Diffs ${P?"will be limited":"will be shown"} based on size`)}if(S+="## Summary\n",S+=`- **Files Modified**: ${_.size}\n`,S+=`- **Total File Operations**: ${C.length}\n`,S+="- **What's Shown**: For existing files, comparing state before task started with final state.\n",S+=" For files created during task, showing the entire file as created.\n",P?(S+=`- **Diff Display**: Limited (total diff size of ${T} lines exceeds limit of ${q} lines)\n`,S+=" Use file-history tool with individual files to see detailed changes\n\n"):S+=`- **Diff Display**: ${g?"Enabled":"Disabled"} (use showDiff=${!g} to ${g?"hide":"show"} diffs)\n\n`,v.allMoves.length>0){S+="## Move Operations\n\n",S+=`Detected ${v.allMoves.length} file move operation(s):\n\n`
|
|
3965
4008
|
for(const xe of v.allMoves)S+=`- **${xe.source}** \u2192 **${xe.destination}**\n`,S+=` - Operation: ${xe.type}\n`,S+=` - Timestamp: ${new Date(xe.timestamp).toLocaleString()}\n`,S+=` - Record ID: ${xe.recordId}\n\n`}S+="## Modified Files\n\n"
|
|
3966
4009
|
for(const[je,Re]of E.entries()){const{normalizedPath:Me,fullPath:$e}=d.validateAndNormalizePath(je,t)
|
|
3967
4010
|
let Oe=!1
|
|
@@ -3969,7 +4012,7 @@ try{await a.access($e),Oe=!0}catch{}S+=`### ${je} ${Oe?"":"(Deleted)"}\n\n`
|
|
|
3969
4012
|
const De=new Date(Re.firstChange.timestamp).toLocaleString(),Ae=new Date(Re.lastChange.timestamp).toLocaleString()
|
|
3970
4013
|
S+=`**First Change**: ${De}\n`,S+=`**Last Change**: ${Ae}\n`,"pre-task"===Re.firstChange.status&&Re.firstChange.commitHash?S+=`**Pre-Task Commit**: ${Re.firstChange.commitHash.substring(0,8)}\n`:Re.firstChange.commitHash&&(S+=`**File Created During Task**: ${Re.firstChange.commitHash.substring(0,8)}\n`),Re.lastChange.commitHash&&(S+=`**Final Commit**: ${Re.lastChange.commitHash.substring(0,8)}\n`)
|
|
3971
4014
|
const Fe=v.sourceToMove.get(je),Ne=v.destToMove.get(je)
|
|
3972
|
-
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`),
|
|
4015
|
+
Fe?S+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Fe.destination}**\n`:Ne&&(S+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Ne.source}**\n`),g&&!P?Re.hasDiff?(S+="\n**Changes**:\n",S+="```diff\n",S+=Re.diffText,S+="\n```\n\n"):S+=`\n**Note**: ${Re.diffText}\n\n`:P&&Re.hasDiff?(S+=`\n**Note**: File has changes (${Re.diffText?Re.diffText.split("\n").length:0} lines). `,S+=`Compare ${Re.firstChange.commitHash?Re.firstChange.commitHash.substring(0,8):"unknown"}..${Re.lastChange.commitHash?Re.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):Re.hasDiff?S+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":S+=`\n**Note**: ${Re.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}}}
|
|
3973
4016
|
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"
|
|
3974
4017
|
module.exports=require("path")},6975(e,exports,t){"use strict"
|
|
3975
4018
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
|
|
@@ -4105,39 +4148,40 @@ i.appendFileSync(o,`[${s}] ${e} | ${t}${l}\n`)}catch(e){}}
|
|
|
4105
4148
|
const i=s(t(9896)),a=s(t(6928)),c=s(t(857))},7334(e,exports,t){"use strict"
|
|
4106
4149
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateRequest=async function(e,t,c,l,d,u,h){const p=l.child({tool:"create_request"})
|
|
4107
4150
|
p.info("Creating new request",{args:e})
|
|
4108
|
-
const
|
|
4151
|
+
const m=d.startTimer("tool_handler_duration")
|
|
4109
4152
|
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)
|
|
4110
4153
|
throw new r.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
|
|
4111
4154
|
d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
|
|
4112
|
-
const
|
|
4113
|
-
if(!
|
|
4114
|
-
c.setProjectId(
|
|
4155
|
+
const g=t.projectId
|
|
4156
|
+
if(!g)throw new r.ValidationError("Project ID is required for creating requests.")
|
|
4157
|
+
c.setProjectId(g)
|
|
4115
4158
|
const f=c.getRequestClient()
|
|
4116
4159
|
let y=(0,a.getApprovalMode)()
|
|
4117
4160
|
try{const e=h?.sessionId
|
|
4118
4161
|
if(e){const t=c.getCLISessionClient()
|
|
4119
4162
|
if(t){const r=await t.getByExternalId(e)
|
|
4120
4163
|
if(r?.workflowId){const e=await c.proxyGet("/api/workflows/"+r.workflowId),t=e?.data||e
|
|
4121
|
-
t?.approvalMode&&(y=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===y)try{const e=await c.proxyGet("/api/projects/"+
|
|
4164
|
+
t?.approvalMode&&(y=(0,a.getApprovalMode)(t.approvalMode))}}}if("none"===y)try{const e=await c.proxyGet("/api/projects/"+g),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
|
|
4122
4165
|
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"
|
|
4123
4166
|
let I=h
|
|
4124
4167
|
if(h?.sessionId)try{const e=c.getCLISessionClient()
|
|
4125
4168
|
if(e){const t=await e.getByExternalId(h.sessionId)
|
|
4126
4169
|
"planner"!==t?.agentType&&"auto-planner"!==t?.agentType||(I=void 0,p.info("Skipping cliOrigin for planner-created request",{agentType:t.agentType}))}}catch{}const b={title:l.title,description:l.description,type:l.type,acceptanceCriteria:l.acceptanceCriteria,status:w,...l.planDocumentId&&{planDocumentId:l.planDocumentId},...l.questDocumentId&&{questDocumentId:l.questDocumentId},...I&&{cliOrigin:I}}
|
|
4127
|
-
p.info("Creating request via request client",{projectId:
|
|
4170
|
+
p.info("Creating request via request client",{projectId:g,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
|
|
4128
4171
|
const k=await f.createRequest(b)
|
|
4129
4172
|
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"})
|
|
4130
4173
|
const v=(0,o.extractDataFromResponse)(k,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
|
|
4131
4174
|
let _,E={created:!1}
|
|
4132
4175
|
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})
|
|
4133
|
-
p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4176
|
+
if(p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName}),l.questDocumentId)try{const e=c.getDocumentClient(),t=await e.getDocument(l.questDocumentId)
|
|
4177
|
+
if(t&&"Quest"===t.type){const r={...t.metadata||{},consecutiveDoneAudits:0}
|
|
4178
|
+
await e.updateDocument(l.questDocumentId,{metadata:r}),p.info("Reset quest consecutiveDoneAudits after spawning request",{questDocumentId:l.questDocumentId,requestId:C.id})}}catch(e){p.warn("Failed to reset quest consecutiveDoneAudits after request creation",{questDocumentId:l.questDocumentId,requestId:C.id,error:(0,i.getErrorMessage)(e)})}try{const e=c.getToolRecordClient()
|
|
4179
|
+
if(e){const t=await e.createToolRecord({requestId:C.id,projectId:g,type:"create-request",metadata:{status:"completed",timestamp:(new Date).toISOString(),requestType:C.type,requestTitle:C.title,requestDescription:C.description,criteriaCount:C.acceptanceCriteria.length,branchCreated:E.created,branchName:E.created?E.branchName:null},note:`Created request "${C.title}" of type ${C.type}${E.created?" with branch "+E.branchName:" - branch will be created on first file operation"}`})
|
|
4180
|
+
_=t?.id}}catch(e){p.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:C.id})}m({success:!0,type:l.type,hasProjectId:!0}),p.info("Request created successfully",{requestId:C.id,title:C.title,type:C.type,projectId:g})
|
|
4137
4181
|
const S=C.localId||C.id
|
|
4138
4182
|
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})
|
|
4139
4183
|
else{const n=c.getToolRecordClient()
|
|
4140
|
-
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(
|
|
4184
|
+
n&&await n.createToolRecord({projectId:t.projectId,type:"create-request",metadata:{status:"failed",timestamp:(new Date).toISOString(),requestTitle:e.title,requestType:e.type,requestDescription:e.description?.substring(0,100)+(e.description?.length>100?"...":""),criteriaCount:e.acceptanceCriteria?e.acceptanceCriteria.length:0,branchCreated:!1,branchName:null,error:(0,i.getErrorMessage)(r),errorDetails:r instanceof Error?r.stack:r+""},note:"Failed to create request: "+e.title})}}catch(e){p.error("Failed to create failure record for request creation",{error:e instanceof Error?e.message:e+""})}if(m({success:!1,error:r instanceof Error?r.name:"unknown"}),r instanceof s.ZodError&&r.errors.length>0){const e=r.errors[0]
|
|
4141
4185
|
let t=e.message
|
|
4142
4186
|
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."
|
|
4143
4187
|
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}}}
|
|
@@ -4158,12 +4202,12 @@ const h=i[c]
|
|
|
4158
4202
|
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}}}
|
|
4159
4203
|
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"
|
|
4160
4204
|
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"})
|
|
4161
|
-
try{const s=e,{operations:
|
|
4205
|
+
try{const s=e,{operations:m,comment:g}=s,{enforceActiveTask:f}=await Promise.resolve().then(t.bind(t,3451)),y=await f(i,a,d,e.taskId)
|
|
4162
4206
|
if("errorResult"in y)return y.errorResult
|
|
4163
4207
|
const{taskId:w}=y
|
|
4164
|
-
p.info("Processing modify-file operations",{taskId:w,operationCount:
|
|
4208
|
+
p.info("Processing modify-file operations",{taskId:w,operationCount:m.length,comment:g})
|
|
4165
4209
|
const I=[],b=[],k=[],v=[],C=[]
|
|
4166
|
-
for(const e of
|
|
4210
|
+
for(const e of m){const t={path:e.path,documentId:e.documentId}
|
|
4167
4211
|
switch(e.operationType){case"replace-string":I.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
|
|
4168
4212
|
break
|
|
4169
4213
|
case"insert-lines":b.push({...t,insertions:e.insertLines.insertions})
|
|
@@ -4174,15 +4218,15 @@ case"delete-string":v.push({...t,replacements:e.deleteString.patterns.map((e=>({
|
|
|
4174
4218
|
break
|
|
4175
4219
|
case"delete-lines":C.push({...t,lines:e.deleteLines.lines})}}const _=[]
|
|
4176
4220
|
if(I.length>0){p.info("Routing to replace-strings handler",{operationCount:I.length})
|
|
4177
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:I,comment:
|
|
4221
|
+
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:I,comment:g+" [via modify-file: replace-string]"},i,a,c,l,p,u,h)
|
|
4178
4222
|
_.push({type:"replace-string",result:e})}if(b.length>0){p.info("Routing to insert-lines handler",{operationCount:b.length})
|
|
4179
|
-
const e=await(0,n.handleInsertLines)({taskId:w,operations:b,comment:
|
|
4223
|
+
const e=await(0,n.handleInsertLines)({taskId:w,operations:b,comment:g+" [via modify-file: insert-lines]"},i,a,c,l,p,u,h)
|
|
4180
4224
|
_.push({type:"insert-lines",result:e})}if(k.length>0){p.info("Routing to replace-lines handler",{operationCount:k.length})
|
|
4181
|
-
const e=await(0,o.handleReplaceLines)({taskId:w,operations:k,comment:
|
|
4225
|
+
const e=await(0,o.handleReplaceLines)({taskId:w,operations:k,comment:g+" [via modify-file: replace-lines]"},i,a,c,l,p,u,h)
|
|
4182
4226
|
_.push({type:"replace-lines",result:e})}if(v.length>0){p.info("Routing delete-string to replace-strings handler",{operationCount:v.length})
|
|
4183
|
-
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:v,comment:
|
|
4227
|
+
const e=await(0,r.handleReplaceStrings)({taskId:w,operations:v,comment:g+" [via modify-file: delete-string]"},i,a,c,l,p,u,h)
|
|
4184
4228
|
_.push({type:"delete-string",result:e})}if(C.length>0){p.info("Processing delete-lines operations",{operationCount:C.length})
|
|
4185
|
-
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:
|
|
4229
|
+
const e=C.map((e=>({path:e.path,documentId:e.documentId,replacements:[{lines:e.lines,content:[]}]}))),t=await(0,o.handleReplaceLines)({taskId:w,operations:e,comment:g+" [via modify-file: delete-lines]"},i,a,c,l,p,u,h)
|
|
4186
4230
|
_.push({type:"delete-lines",result:t})}const E=_.some((e=>e.result.isError)),S=_.filter((e=>!e.result.isError)).length,q=_.filter((e=>e.result.isError)).length
|
|
4187
4231
|
let T="## Modify File Results\n\n"
|
|
4188
4232
|
T+="**Summary:**\n",T+=`- **Total operation types:** ${_.length}\n`,T+=`- **Successful:** ${S}\n`,T+=`- **Failed:** ${q}\n\n`
|
|
@@ -4192,22 +4236,22 @@ const r=t(3306),n=t(6486),o=t(6651),s=t(8824)},7478(e,exports,t){"use strict"
|
|
|
4192
4236
|
async function r(e,t,r){const n=r.startTimer("git_get_current_branch_duration")
|
|
4193
4237
|
try{const o=(await e.status()).current
|
|
4194
4238
|
if(!o)throw new p.ValidationError("Repository is in detached HEAD state or branch detection failed")
|
|
4195
|
-
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,
|
|
4239
|
+
return t.debug("Retrieved current branch",{branch:o}),r.incrementCounter("git_get_current_branch_success",1),n({success:!0}),o}catch(e){const o=(0,g.getErrorMessage)(e)
|
|
4196
4240
|
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")
|
|
4197
4241
|
try{const s=(await e.branch(["-l"])).all.includes(t)
|
|
4198
|
-
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,
|
|
4242
|
+
return r.debug("Checked branch existence",{branchName:t,exists:s}),n.incrementCounter("git_branch_exists_check",1,{exists:s.toString()}),o({success:!0}),s}catch(e){const s=(0,g.getErrorMessage)(e)
|
|
4199
4243
|
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")
|
|
4200
4244
|
try{const a=await r(e,o,s)
|
|
4201
4245
|
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}'`}
|
|
4202
4246
|
if(!await n(e,t,o,s)){const e=`Branch '${t}' does not exist`
|
|
4203
4247
|
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)
|
|
4204
4248
|
const c=await e.revparse(["HEAD"])
|
|
4205
|
-
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,
|
|
4249
|
+
return o.info("Switched to branch",{branchName:t,previousBranch:a,commitHash:c.substring(0,8)}),s.incrementCounter("git_switch_branch_success",1),i({success:!0}),{success:!0,branchName:t,previousBranch:a,commitHash:c,message:`Switched from '${a}' to '${t}'`}}catch(e){const r=(0,g.getErrorMessage)(e)
|
|
4206
4250
|
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")
|
|
4207
4251
|
try{let o,s=!0
|
|
4208
4252
|
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")
|
|
4209
4253
|
let p=""
|
|
4210
|
-
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,
|
|
4254
|
+
return u?p="main":h?p="master":d.length>0&&(p=d[0].name),t.debug("Retrieved repository status",{currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:p,branchCount:d.length,uncommittedCount:c.length}),r.incrementCounter("git_repository_status_success",1),n({success:!0}),{isGitRepository:s,currentBranch:i,isClean:a,hasMainBranch:u,hasMasterBranch:h,defaultBranch:p,uncommittedChanges:c,branches:d}}catch(e){const o=(0,g.getErrorMessage)(e)
|
|
4211
4255
|
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")
|
|
4212
4256
|
try{t.debug("Starting uncommitted changes check"),t.debug("Checking for uncommitted changes before merge"),Date.now()
|
|
4213
4257
|
const o=await e.status()
|
|
@@ -4219,7 +4263,7 @@ t.debug("Uncommitted changes summary",{hasChanges:l,totalFiles:c,staged:s.length
|
|
|
4219
4263
|
let d=""
|
|
4220
4264
|
if(l){const e=[]
|
|
4221
4265
|
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"
|
|
4222
|
-
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,
|
|
4266
|
+
return(0,h.isDebugToolsEnabled)()&&t.debug("Summary",{summary:d}),t.debug("Uncommitted changes check completed",{hasChanges:l,staged:s.length,unstaged:i.length,untracked:a.length,total:c,summary:d}),r.incrementCounter("git_uncommitted_changes_check_success",1),r.recordValue("git_uncommitted_changes_total_files",c),n({success:!0}),{hasChanges:l,stagedFiles:s,unstagedFiles:i,untrackedFiles:a,totalFiles:c,summary:d}}catch(e){const o=(0,g.getErrorMessage)(e)
|
|
4223
4267
|
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)
|
|
4224
4268
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
4225
4269
|
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=[]
|
|
@@ -4233,42 +4277,42 @@ try{if(await n(e,t,s,i)){const e=`Branch '${t}' already exists`
|
|
|
4233
4277
|
return s.warn(e),i.incrementCounter("git_create_branch_already_exists",1),c({success:!1,reason:"already_exists"}),{success:!1,branchName:t,message:e}}const l=await r(e,s,i)
|
|
4234
4278
|
await e.checkoutBranch(t,o)
|
|
4235
4279
|
const d=await e.revparse(["HEAD"]),u=a||l
|
|
4236
|
-
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,
|
|
4280
|
+
return await e.checkout(u),s.info("Created new branch",{branchName:t,fromBranch:o,currentBranch:l,returnedToBranch:u,commitHash:d.substring(0,8)}),i.incrementCounter("git_create_branch_success",1),c({success:!0}),{success:!0,branchName:t,previousBranch:l,commitHash:d,message:`Created branch '${t}' from '${o}'`}}catch(e){const r=(0,g.getErrorMessage)(e)
|
|
4237
4281
|
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")
|
|
4238
4282
|
try{const d=await r(e,i,a)
|
|
4239
4283
|
if(d!==s&&await o(e,s,i,a),!await n(e,t,i,a)){const e=`Source branch '${t}' does not exist`
|
|
4240
4284
|
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"]))
|
|
4241
|
-
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,
|
|
4285
|
+
return i.info("Successfully merged branch",{sourceBranch:t,targetBranch:s,commitHash:h.substring(0,8),mergeMessage:c||"default merge message"}),a.incrementCounter("git_merge_branch_success",1),l({success:!0}),{success:!0,branchName:s,previousBranch:d,commitHash:h,message:`Merged '${t}' into '${s}'`}}catch(e){const r=(0,g.getErrorMessage)(e)
|
|
4242
4286
|
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")
|
|
4243
4287
|
try{const c=await r(e,s,i)
|
|
4244
4288
|
if(c===t){const e=`Cannot delete current branch '${t}'`
|
|
4245
4289
|
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}'`
|
|
4246
4290
|
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`
|
|
4247
4291
|
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]
|
|
4248
|
-
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,
|
|
4292
|
+
return await e.branch(l),s.info("Deleted branch",{branchName:t,force:o,currentBranch:c}),i.incrementCounter("git_delete_branch_success",1),a({success:!0}),{success:!0,branchName:t,previousBranch:c,message:`Deleted branch '${t}'${o?" (forced)":""}`}}catch(e){const r=(0,g.getErrorMessage)(e)
|
|
4249
4293
|
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")
|
|
4250
4294
|
try{const o=await s(e,t,r)
|
|
4251
|
-
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,
|
|
4295
|
+
return o.isGitRepository?(o.currentBranch||(t.warn("Git repository in detached HEAD state"),r.incrementCounter("git_validate_repository_detached_head",1)),o.isClean||(t.warn("Git repository has uncommitted changes",{count:o.uncommittedChanges.length,files:o.uncommittedChanges.slice(0,5)}),r.incrementCounter("git_validate_repository_dirty",1)),o.defaultBranch||(t.warn("No default branch found in git repository"),r.incrementCounter("git_validate_repository_no_default_branch",1)),t.info("Git repository validation completed",{currentBranch:o.currentBranch,isClean:o.isClean,defaultBranch:o.defaultBranch,branchCount:o.branches.length}),r.incrementCounter("git_validate_repository_success",1),n({success:!0}),o):(t.warn("Git repository validation failed: not a git repository"),r.incrementCounter("git_validate_repository_not_git",1),n({success:!1,reason:"not_git_repo"}),o)}catch(e){const o=(0,g.getErrorMessage)(e)
|
|
4252
4296
|
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)
|
|
4253
4297
|
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})-/)
|
|
4254
4298
|
return t?t[1]:null},exports.switchToDefaultBranch=async function(e,t,r){const n=r.startTimer("git_switch_to_default_duration")
|
|
4255
4299
|
try{const i=await s(e,t,r)
|
|
4256
4300
|
if(!i.defaultBranch){const e="No default branch found"
|
|
4257
4301
|
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)
|
|
4258
|
-
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,
|
|
4302
|
+
return a.success?(t.info("Switched to default branch",{defaultBranch:i.defaultBranch,previousBranch:a.previousBranch}),r.incrementCounter("git_switch_to_default_success",1),n({success:!0})):(r.incrementCounter("git_switch_to_default_failed",1),n({success:!1,reason:"switch_failed"})),a}catch(e){const o=(0,g.getErrorMessage)(e)
|
|
4259
4303
|
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")
|
|
4260
4304
|
try{const o=await s(e,t,r),i=[]
|
|
4261
4305
|
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")
|
|
4262
4306
|
const a=0===i.length
|
|
4263
|
-
return t.debug("Repository readiness check completed",{ready:a,issueCount:i.length,issues:i}),r.incrementCounter("git_ensure_repository_ready_check",1,{ready:a.toString()}),n({success:!0,ready:a.toString()}),{ready:a,status:o,issues:i}}catch(e){const o=(0,
|
|
4307
|
+
return t.debug("Repository readiness check completed",{ready:a,issueCount:i.length,issues:i}),r.incrementCounter("git_ensure_repository_ready_check",1,{ready:a.toString()}),n({success:!0,ready:a.toString()}),{ready:a,status:o,issues:i}}catch(e){const o=(0,g.getErrorMessage)(e)
|
|
4264
4308
|
return t.error("Failed to check repository readiness",{error:o}),r.incrementCounter("git_ensure_repository_ready_failure",1),n({success:!1,error:e instanceof Error?e.name:"unknown"}),{ready:!1,status:{isGitRepository:!1,currentBranch:"",isClean:!1,hasMainBranch:!1,hasMasterBranch:!1,defaultBranch:"",uncommittedChanges:[],branches:[]},issues:["Repository check failed: "+o]}}},exports.hasMainChangedSinceRevert=async function(e,t,r,n){const o=n.startTimer("git_check_main_changed_since_revert")
|
|
4265
4309
|
try{r.debug("Starting main branch change detection",{providedRevertCommitHash:t.substring(0,8),fullRevertCommitHash:t})
|
|
4266
4310
|
const n=await e.revparse(["HEAD"])
|
|
4267
4311
|
r.debug("Git state captured",{currentMainHash:n.substring(0,8),fullCurrentMainHash:n,revertCommitHash:t.substring(0,8),fullRevertCommitHash:t,hashesMatch:n===t})
|
|
4268
4312
|
try{const t=await e.revparse(["--abbrev-ref","HEAD"]),n=await e.status(),o=await e.log(["--oneline","-5"])
|
|
4269
|
-
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,
|
|
4313
|
+
r.debug("Additional git context",{currentBranch:t,gitStatus:{ahead:n.ahead,behind:n.behind,current:n.current,tracking:n.tracking,staged:n.staged.length,modified:n.modified.length},recentCommits:o.all.map((e=>({hash:e.hash.substring(0,8),message:e.message})))})}catch(e){r.warn("Failed to gather additional git context",{error:e instanceof Error?e.message:e+""})}const s=await(0,m.validateCommitHash)(e,t,r,"hasMainChangedSinceRevert-revert-validation")
|
|
4270
4314
|
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}`)
|
|
4271
|
-
const i=await(0,
|
|
4315
|
+
const i=await(0,m.validateCommitHash)(e,n,r,"hasMainChangedSinceRevert-head-validation")
|
|
4272
4316
|
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}`)
|
|
4273
4317
|
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"}
|
|
4274
4318
|
r.debug("Hash comparison shows difference, checking ancestor relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),hashesEqual:!1})
|
|
@@ -4276,10 +4320,10 @@ let a=!1,c=0,l=null
|
|
|
4276
4320
|
for(let n=1;3>=n;n++)try{r.debug("Checking ancestor relationship with merge-base",{revertCommitHash:t.substring(0,8),currentHead:"HEAD",attempt:n}),n>1&&(await new Promise((e=>setTimeout(e,100))),r.debug("Retry attempt after delay",{attempt:n,delay:100})),await e.raw(["merge-base","--is-ancestor",t,"HEAD"]),r.debug("Revert commit is ancestor of HEAD, counting commits between them",{attempt:n})
|
|
4277
4321
|
const o=await e.raw(["rev-list","--count",t+"..HEAD"])
|
|
4278
4322
|
c=parseInt(o.trim(),10),a=!0
|
|
4279
|
-
break}catch(e){l=e,r.debug("Ancestor check attempt failed",{attempt:n,error:(0,
|
|
4323
|
+
break}catch(e){l=e,r.debug("Ancestor check attempt failed",{attempt:n,error:(0,g.getErrorMessage)(e)}),3===n&&r.debug("All ancestor check attempts failed, treating as non-ancestor")}if(a){try{const n=await e.raw(["rev-list","--oneline",t+"..HEAD"])
|
|
4280
4324
|
r.debug("Commits found between revert and HEAD",{count:c,commits:n.trim().split("\n").filter((e=>e.length>0))})}catch(e){r.warn("Could not list commits between revert and HEAD",{error:e instanceof Error?e.message:e+""})}return r.info("Main branch has changed since revert - ancestor relationship confirmed",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),commitsSinceRevert:c,isAncestor:!0}),o({success:!0,changed:"true"}),{hasChanged:!0,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:c,message:`Main branch has ${c} new commit${c>1?"s":""} since revert`}}r.warn("Revert commit is not an ancestor of current HEAD after retries - investigating relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),lastAncestorError:l instanceof Error?l.message:l+"",attempts:3})
|
|
4281
4325
|
try{const o=await e.raw(["merge-base",t,"HEAD"])
|
|
4282
|
-
r.debug("Merge base found between revert commit and HEAD",{mergeBase:o.trim().substring(0,8),revertCommitHash:t.substring(0,8),currentMainHash:n.substring(0,8)})}catch(e){r.warn("Could not find merge base",{error:e instanceof Error?e.message:e+""})}try{await e.raw(["merge-base","--is-ancestor","HEAD",t]),r.error("CRITICAL: Current HEAD is ancestor of revert commit - possible git state corruption or incorrect revert hash",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),implication:"This suggests the stored revert commit hash may be incorrect or from a different branch state"})}catch(e){r.debug("HEAD is not ancestor of revert commit either - commits may be on divergent paths",{error:e instanceof Error?e.message:e+""})}return o({success:!0,changed:"unknown"}),{hasChanged:!0,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:-1,message:"Cannot determine relationship between revert commit and current HEAD - assuming changed for safety. This may indicate a stored revert commit hash issue."}}catch(e){const n=(0,
|
|
4326
|
+
r.debug("Merge base found between revert commit and HEAD",{mergeBase:o.trim().substring(0,8),revertCommitHash:t.substring(0,8),currentMainHash:n.substring(0,8)})}catch(e){r.warn("Could not find merge base",{error:e instanceof Error?e.message:e+""})}try{await e.raw(["merge-base","--is-ancestor","HEAD",t]),r.error("CRITICAL: Current HEAD is ancestor of revert commit - possible git state corruption or incorrect revert hash",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),implication:"This suggests the stored revert commit hash may be incorrect or from a different branch state"})}catch(e){r.debug("HEAD is not ancestor of revert commit either - commits may be on divergent paths",{error:e instanceof Error?e.message:e+""})}return o({success:!0,changed:"unknown"}),{hasChanged:!0,currentMainHash:n,revertCommitHash:t,commitsSinceRevert:-1,message:"Cannot determine relationship between revert commit and current HEAD - assuming changed for safety. This may indicate a stored revert commit hash issue."}}catch(e){const n=(0,g.getErrorMessage)(e)
|
|
4283
4327
|
throw r.error("Failed to check if main changed since revert",{revertCommitHash:t.substring(0,8),error:n}),o({success:!1,error:e instanceof Error?e.name:"unknown"}),Error("Failed to check main branch changes: "+n)}},exports.findRevertCommitHash=async function(e,t,r){try{r.debug("Searching for revert commit hash in tool records",{requestId:e})
|
|
4284
4328
|
const n=await t.getToolRecordsByRequestId(e,"revert-request")
|
|
4285
4329
|
if(n.sort(((e,t)=>new Date(t.createdAt).getTime()-new Date(e.createdAt).getTime())),!n||0===n.length)return r.debug("No revert tool records found for request",{requestId:e}),{found:!1,message:"No revert operations found for this request"}
|
|
@@ -4288,7 +4332,7 @@ for(const t of n)if(r.debug("Examining tool record",{requestId:e,recordId:t.id,r
|
|
|
4288
4332
|
r.debug("Found potential revert commit hash, validating...",{requestId:e,revertCommitHash:o.substring(0,8),fullRevertCommitHash:o,revertType:n,recordId:t.id,revertedAt:t.createdAt})
|
|
4289
4333
|
try{if(!/^[a-f0-9]{40}$/i.test(o)){r.warn("Invalid commit hash format found in tool record",{requestId:e,invalidHash:o,recordId:t.id,format:"Expected 40-character hex string"})
|
|
4290
4334
|
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+""})
|
|
4291
|
-
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,
|
|
4335
|
+
continue}}return r.warn("Found revert tool records but none have completed status with commit hash",{requestId:e,recordCount:n.length,records:n.map((e=>({type:e.type,status:e.metadata?.status,hasCommitHash:!!e.metadata?.revertCommitHash})))}),{found:!1,message:"Found revert records but none were completed successfully"}}catch(t){const n=(0,g.getErrorMessage)(t)
|
|
4292
4336
|
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")
|
|
4293
4337
|
try{if(!r.hasChanges)throw new p.ValidationError("No uncommitted changes to commit")
|
|
4294
4338
|
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})
|
|
@@ -4297,7 +4341,7 @@ i.length>0?(n.debug("Staging files",{files:i.slice(0,10),total:i.length}),await
|
|
|
4297
4341
|
const a=`chore: commit user changes before merging request ${t}\n\n${r.summary}\n\nThis commit preserves user modifications made during the request lifecycle\nbefore proceeding with the branch merge operation.`
|
|
4298
4342
|
n.debug("Commit message",{message:a.split("\n")[0]}),n.debug("Creating commit"),await e.commit(a)
|
|
4299
4343
|
const c=await e.revparse(["HEAD"])
|
|
4300
|
-
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,
|
|
4344
|
+
return n.debug("Commit created successfully",{commitHash:c.substring(0,8),filesCommitted:r.totalFiles}),n.info("Successfully committed user changes",{requestId:t,commitHash:c.substring(0,8),filesCommitted:r.totalFiles,message:a.split("\n")[0]}),o.incrementCounter("git_commit_user_changes_success",1),o.recordValue("git_commit_user_changes_files",r.totalFiles),s({success:!0}),{commitHash:c,message:a,filesCommitted:r.totalFiles}}catch(e){const i=(0,g.getErrorMessage)(e)
|
|
4301
4345
|
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")
|
|
4302
4346
|
try{let c=Date.now()
|
|
4303
4347
|
o.debug("Checking for user changes before tool operation",{toolName:r})
|
|
@@ -4314,8 +4358,8 @@ const h=`${u}\n\n${{...d,summary:`User changes detected before ${r}: ${d.summary
|
|
|
4314
4358
|
o.debug("Committing user changes with message",{firstLine:h.split("\n")[0]})
|
|
4315
4359
|
const p=[...d.unstagedFiles,...d.untrackedFiles]
|
|
4316
4360
|
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()
|
|
4317
|
-
const
|
|
4318
|
-
return o.debug("User changes committed successfully before tool",{commitHash:
|
|
4361
|
+
const m=await l.revparse(["HEAD"])
|
|
4362
|
+
return o.debug("User changes committed successfully before tool",{commitHash:m.substring(0,8),filesCommitted:d.totalFiles,toolName:r}),o.info("Successfully committed user changes before tool operation",{toolName:r,requestId:n.requestId,taskId:n.taskId,commitHash:m.substring(0,8),filesCommitted:d.totalFiles}),s.incrementCounter("git_pre_tool_user_changes_committed",1),s.recordValue("git_pre_tool_user_changes_files",d.totalFiles),i({success:!0,reason:"changes_committed"}),{userChangesCommitted:!0,commitHash:m,filesCommitted:d.totalFiles}}catch(e){const t=(0,g.getErrorMessage)(e)
|
|
4319
4363
|
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=[]
|
|
4320
4364
|
try{const o=t(3807).simpleGit(e),s=(await o.status()).not_added||[]
|
|
4321
4365
|
for(const t of s)try{const o=y.join(e,t),s=f.statSync(o)
|
|
@@ -4324,27 +4368,31 @@ const t=e.reduce(((e,t)=>e+t.sizeMB),0)
|
|
|
4324
4368
|
let r=`\n\n\u26a0\ufe0f **Performance Warning**: Large untracked files detected (${Math.round(t)} MB total) that may slow git operations:\n`
|
|
4325
4369
|
for(const t of e.slice(0,5))r+=`- \`${t.path}\` (${t.sizeMB} MB)\n`
|
|
4326
4370
|
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}
|
|
4327
|
-
const h=t(3444),p=t(9860),
|
|
4371
|
+
const h=t(3444),p=t(9860),m=t(3922),g=t(8824),f=u(t(9896)),y=u(t(6928))
|
|
4328
4372
|
t(857)},7575(e,exports){"use strict"
|
|
4329
4373
|
var t
|
|
4330
4374
|
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"
|
|
4331
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleUpdatePlan=async function(e,t,
|
|
4332
|
-
try{const t=
|
|
4375
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleUpdatePlan=async function(e,t,o,s){const i=s.child({tool:"plan_operations",operation:"update"})
|
|
4376
|
+
try{const t=o.getDocumentClient(),r=await t.getDocument(e.planId)
|
|
4333
4377
|
if(!r)return{content:[{type:"text",text:"\u274c Plan not found: "+e.planId}],isError:!0}
|
|
4334
|
-
const
|
|
4335
|
-
if("Plan"!==r.type&&!
|
|
4336
|
-
const
|
|
4337
|
-
void 0!==e.content&&(
|
|
4338
|
-
const
|
|
4339
|
-
if(
|
|
4378
|
+
const s="Quest"===r.type
|
|
4379
|
+
if("Plan"!==r.type&&!s)return{content:[{type:"text",text:`\u274c Document ${e.planId} is not a plan or quest (type: ${r.type})`}],isError:!0}
|
|
4380
|
+
const a={}
|
|
4381
|
+
void 0!==e.content&&(a.content=e.content),e.name&&(a.filename=e.name.replace(/\.md$/i,"")+".md")
|
|
4382
|
+
const c=e.metadata||{},l=n.QUEST_METADATA_KEYS.filter((e=>void 0!==c[e]))
|
|
4383
|
+
if(l.length>0){if(!s)return{content:[{type:"text",text:`\u274c Metadata fields (${l.join(", ")}) are only valid on Quest documents. ${e.planId} is a Plan.`}],isError:!0}
|
|
4384
|
+
if(void 0!==c.status&&!n.QUEST_STATUSES.includes(c.status))return{content:[{type:"text",text:`\u274c Invalid quest status "${c.status}". Allowed: ${n.QUEST_STATUSES.join(", ")}.`}],isError:!0}
|
|
4385
|
+
if(void 0!==c.completionMode&&!n.QUEST_COMPLETION_MODES.includes(c.completionMode))return{content:[{type:"text",text:`\u274c Invalid completionMode "${c.completionMode}". Allowed: ${n.QUEST_COMPLETION_MODES.join(", ")}.`}],isError:!0}
|
|
4340
4386
|
const t={...r.metadata||{}}
|
|
4341
|
-
for(const e of
|
|
4342
|
-
|
|
4343
|
-
const
|
|
4344
|
-
|
|
4345
|
-
const u=
|
|
4346
|
-
|
|
4347
|
-
const
|
|
4387
|
+
for(const e of l)t[e]=c[e]
|
|
4388
|
+
a.metadata=t}if(void 0===a.content&&!a.filename&&!a.metadata)return{content:[{type:"text",text:"\u274c No changes supplied. Provide content, name, or quest metadata."}],isError:!0}
|
|
4389
|
+
const d=r.metadata||{}
|
|
4390
|
+
if(d.isStub){const e=a.metadata??{...d}
|
|
4391
|
+
delete e.isStub,a.metadata=e}const u=await t.updateDocument(e.planId,a),h=u.localId||u.id
|
|
4392
|
+
i.info("Plan/Quest updated",{planId:h,isQuest:s,changedMetadata:l})
|
|
4393
|
+
const p=s?"Quest":"Plan",m=[]
|
|
4394
|
+
return void 0!==a.content&&m.push("content"),a.filename&&m.push("filename="+u.filename),l.length>0&&m.push(`metadata(${l.join(", ")})`),{content:[{type:"text",text:`\u2705 **${p} Updated**\n\n**ID:** ${h}\n**Filename:** ${u.filename}\n**Changes:** ${m.join(", ")}\n**Updated:** `+new Date(u.updatedAt).toLocaleString()}]}}catch(e){return i.error("Failed to update plan/quest",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to update:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
4395
|
+
const r=t(8824),n=t(3416)},7613(e,exports,t){"use strict"
|
|
4348
4396
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4349
4397
|
const r=t(6183),n=t(9072)
|
|
4350
4398
|
exports.def={name:"session_message_operations",description:'Inter-session messaging (questions and reports).\n\nOperations:\n\u2022 send - Send a message (type: "question" or "report")\n\u2022 reply - Reply to a message (answer a question or acknowledge a report). Type inferred from code prefix (Q-/R-).\n\u2022 list - List messages (filter by messageType, direction, status)\n\u2022 get - Get a message by its code\n\u2022 offer-handoff - Present the user with a choice to start building or keep planning\n\nMessage codes: Q-{id}-{seq} for questions, R-{id}-{seq} for reports.',schema:r.SessionMessageOperationsSchema,annotations:{title:"Session Message Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleSessionMessageOperations)(e,t.context,t.logger,t.metrics,t.apiClient??void 0,t.cliOrigin)}}},7617(e,exports,t){"use strict"
|
|
@@ -4528,7 +4576,7 @@ const r=t(4055)
|
|
|
4528
4576
|
Object.defineProperty(exports,"ProjectID",{enumerable:!0,get(){return r.ProjectID}}),Object.defineProperty(exports,"ProjectIDFactory",{enumerable:!0,get(){return r.ProjectIDFactory}})
|
|
4529
4577
|
const n=t(1791)
|
|
4530
4578
|
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"
|
|
4531
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,c,l,d,u,h,p,g
|
|
4579
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleManageFiles=async function(e,c,l,d,u,h,p,m,g){const f=p.child({tool:"manage_files"})
|
|
4532
4580
|
try{const a=e,{operations:y,comment:w}=a,{enforceActiveTask:I}=await Promise.resolve().then(t.bind(t,3451)),b=await I(c,h,p,e.taskId)
|
|
4533
4581
|
if("errorResult"in b)return b.errorResult
|
|
4534
4582
|
const{taskId:k}=b
|
|
@@ -4542,18 +4590,18 @@ case"delete-files":_.push(...e.deleteFiles.targets)
|
|
|
4542
4590
|
break
|
|
4543
4591
|
case"get-file-info":E.push({path:e.getFileInfo.path})}const S=[]
|
|
4544
4592
|
for(const e of v){f.info("Routing to create-directory handler",{path:e.path})
|
|
4545
|
-
const t=await(0,r.handleCreateDirectory)({taskId:k,path:e.path,comment:w+" [via manage-files: create-directory]"},c,l,d,u,f,g
|
|
4593
|
+
const t=await(0,r.handleCreateDirectory)({taskId:k,path:e.path,comment:w+" [via manage-files: create-directory]"},c,l,d,u,f,m,g)
|
|
4546
4594
|
S.push({type:"create-directory",result:t})}if(C.length>0){f.info("Routing to move-files handler",{operationCount:C.length})
|
|
4547
|
-
const e=await(0,n.handleMoveFiles)({taskId:k,operations:C,comment:w+" [via manage-files: move-files]"},c,l,d,u,f,g
|
|
4595
|
+
const e=await(0,n.handleMoveFiles)({taskId:k,operations:C,comment:w+" [via manage-files: move-files]"},c,l,d,u,f,m,g)
|
|
4548
4596
|
S.push({type:"move-files",result:e})}if(_.length>0){f.info("Routing to delete-files handler",{operationCount:_.length})
|
|
4549
|
-
const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,g
|
|
4597
|
+
const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,m,g)
|
|
4550
4598
|
S.push({type:"delete-files",result:e})}for(const e of E){f.info("Routing to get-file-info handler",{path:e.path})
|
|
4551
|
-
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,
|
|
4599
|
+
const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,m)
|
|
4552
4600
|
S.push({type:"get-file-info",result:t})}const q=S.some((e=>e.result.isError)),T=S.filter((e=>!e.result.isError)).length,P=S.filter((e=>e.result.isError)).length
|
|
4553
4601
|
let x="## Manage Files Results\n\n"
|
|
4554
4602
|
x+="**Summary:**\n",x+=`- **Total operation types:** ${S.length}\n`,x+=`- **Successful:** ${T}\n`,x+=`- **Failed:** ${P}\n\n`
|
|
4555
4603
|
for(const{type:e,result:t}of S)x+=`### ${e} operations\n`,x+=t.content[0].text+"\n\n"
|
|
4556
|
-
return f.info("Manage-files operations completed",{totalOperationTypes:S.length,successCount:T,errorCount:P}),
|
|
4604
|
+
return f.info("Manage-files operations completed",{totalOperationTypes:S.length,successCount:T,errorCount:P}),m.incrementCounter("manage_files_total",1,{success:!q}),{content:[{type:"text",text:x}],...(0,s.alchemyMeta)({kind:"manage-files"}),isError:q}}catch(e){return f.error("Manage-files operation failed",{error:e instanceof Error?e.stack:e+""}),m.incrementCounter("manage_files_errors",1),{content:[{type:"text",text:"\u274c **Manage Files Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
|
|
4557
4605
|
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"
|
|
4558
4606
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4559
4607
|
const r=t(6183),n=t(5303)
|
|
@@ -4578,8 +4626,8 @@ const r=t(5806),n=t(5715)
|
|
|
4578
4626
|
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"
|
|
4579
4627
|
async function r(e,t,r,n,o,s,a,l,d,u){const h=Date.now()
|
|
4580
4628
|
if(!r||""===r.trim())throw new c.ValidationError("Project ID is required and cannot be empty for tool record creation")
|
|
4581
|
-
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,
|
|
4582
|
-
return l.info("Tool record created with IDs",{recordId:p,localRecordId:
|
|
4629
|
+
try{const c=await a.createToolRecord({taskId:e,requestId:t,projectId:r,type:n,metadata:{path:o,operation:n,status:"pending",timestamp:(new Date).toISOString(),fileExtension:i.default.extname(o).slice(1),fileOperationId:`${e}-${Date.now()}`,...s},note:`${"write-file"===n?"Writing":"Modifying"} file: ${o}`}),p=c.id,m=c.localId
|
|
4630
|
+
return l.info("Tool record created with IDs",{recordId:p,localRecordId:m,hasLocalId:!!c.localId,recordKeys:Object.keys(c),fullRecord:JSON.stringify(c)}),l.info("Created tool record for file operation: "+n,{taskId:e,projectId:r,path:o,recordId:p,localRecordId:m}),d.recordValue(u+"_tool_record_creation_time",Date.now()-h),d.incrementCounter(u+"_tool_record_creation_success",1),{recordId:p,localRecordId:m}}catch(t){d.incrementCounter(u+"_tool_record_creation_failure",1),d.recordValue(u+"_tool_record_creation_time",Date.now()-h)
|
|
4583
4631
|
const n=t instanceof Error?`${t.message} (${JSON.stringify(t)})`:t+""
|
|
4584
4632
|
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()
|
|
4585
4633
|
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
|
|
@@ -4592,35 +4640,35 @@ if(o.workspaceManager){const t=o.workspaceManager.getCurrentContext(o.currentSes
|
|
|
4592
4640
|
"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}
|
|
4593
4641
|
let p=null
|
|
4594
4642
|
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)
|
|
4595
|
-
const
|
|
4596
|
-
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:
|
|
4643
|
+
const m=1===n.length?`${s} in ${n[0]} (${i})`:`${s} in ${n.length} files (${i})`,g=(await d.commit(m)).commit
|
|
4644
|
+
return l.info("Changes committed to git via shared multi-file utility",{commitMessage:m,filesCommitted:n.length,commitHash:g?.substring(0,8),previousCommitHash:p?.substring(0,8),toolRecordId:i,operationType:s}),u.incrementCounter(h+"_git_commit_success",1),u.recordValue(h+"_files_committed",n.length),{commitHash:g,previousCommitHash:p,filesCommitted:n,success:!0}}catch(e){const t=(0,d.getErrorMessage)(e)
|
|
4597
4645
|
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}}
|
|
4598
4646
|
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()
|
|
4599
|
-
let g
|
|
4647
|
+
let m,g
|
|
4600
4648
|
l.debug("createFileOperationRecords called",{taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,operationType:o,path:s})
|
|
4601
4649
|
try{const a=await r(e,t,n,o,s,i,c,l,u,h)
|
|
4602
|
-
return
|
|
4650
|
+
return m=a.recordId,g=a.localRecordId,l.info("Created tool record for file operation: "+o,{taskId:e,path:s,toolRecordId:m,localToolRecordId:g}),{toolRecordId:m,localToolRecordId:g}}catch(r){throw l.error("Failed to create tool record for file operation: "+o,{error:(0,d.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0,taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,path:s}),u.recordValue(h+"_record_creation_time",Date.now()-p),u.incrementCounter(h+"_record_creation_error",1),r}},exports.updateFileOperationRecords=async function(e,t,r,o,s,i,a,c,l,u,h,p,m){try{t&&h.info("Task record update skipped (task records removed): "+t,{taskId:e,path:o}),r&&await n(r,o,s,a,c,u,h,p,m)}catch(t){h.warn("Error updating tool record for operation: "+s,{error:(0,d.getErrorMessage)(t),taskId:e,normalizedPath:o,toolRecordId:r})}},exports.checkAndCommitUserMods=async function(e,t,r,n,o){if(!t.git)return{hadUserMods:!1}
|
|
4603
4651
|
try{let s=t.git
|
|
4604
4652
|
if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
|
|
4605
4653
|
"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)
|
|
4606
4654
|
const t=await s.commit("[USER-MODS] Preserve user modifications before tool operation: "+e)
|
|
4607
4655
|
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()
|
|
4608
|
-
let p,
|
|
4609
|
-
try{let
|
|
4656
|
+
let p,m=null
|
|
4657
|
+
try{let g=s.git
|
|
4610
4658
|
if(s.workspaceManager){const t=s.workspaceManager.getCurrentContext(s.currentSessionId)
|
|
4611
4659
|
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.`)
|
|
4612
|
-
|
|
4660
|
+
g=(0,a.simpleGit)(t.basePath),i.debug("Using WorkspaceManager git instance for commit",{taskId:e,mode:t.mode,requestId:t.requestId,basePath:t.basePath,branchName:t.branchName,worktreeValidated:!0})}}if(g){i.info("commitToGit called with:",{taskId:e,recordId:r,localRecordId:n,hasLocalRecordId:!!n,localRecordIdType:typeof n,normalizedPath:t})
|
|
4613
4661
|
let a=!1,f=""
|
|
4614
|
-
try{if(f=(await
|
|
4662
|
+
try{if(f=(await g.raw(["rev-parse","--show-toplevel"])).trim(),a=f.includes("/worktrees/")||f.includes("\\worktrees\\"),i.info("Git context detection for commit operation:",{taskId:e,gitRepoPath:f,isWorktreeOperation:a,targetFile:t,expectedContext:"worktree"}),!a)throw i.error("CRITICAL: Multi-agent operation using main repo Git instead of worktree",{taskId:e,detectedPath:f,targetFile:t,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"unknown"}),Error(`Git context mismatch: Multi-agent operation attempted to commit ${t} using main repository Git instance at ${f}, but should use worktree Git instance. This will fail due to .gitignore rules.`)}catch(e){i.warn("Failed to get Git instance info:",{error:e instanceof Error?e.message:e+""})}try{const r=await g.revparse(["--abbrev-ref","HEAD"]),n=await g.revparse(["HEAD"]),o=await g.revparse(["--show-toplevel"])
|
|
4615
4663
|
i.info("Git repository status before commit:",{taskId:e,currentBranch:r.trim(),currentCommit:n.trim().substring(0,8),repoPath:o.trim(),targetFile:t,currentRequestId:s.getCurrentRequestId?s.getCurrentRequestId():"none"})
|
|
4616
4664
|
const a=r.trim(),c=s.getCurrentRequestId?s.getCurrentRequestId():null
|
|
4617
4665
|
if(c){const t="requests/"+c
|
|
4618
|
-
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(
|
|
4619
|
-
|
|
4620
|
-
await
|
|
4621
|
-
try{const r=await
|
|
4622
|
-
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(
|
|
4623
|
-
return{commitHash:p,previousCommitHash:
|
|
4666
|
+
a!=="requests/"+c?i.warn("Multi-agent file operation may be on wrong branch",{taskId:e,actualBranch:a,expectedPattern:t,requestId:c}):i.info("Multi-agent file operation on expected branch",{taskId:e,branchName:a,requestId:c})}}catch(e){i.warn("Failed to get Git status before commit:",{error:e instanceof Error?e.message:e+""})}try{if(g){const r=await g.revparse(["HEAD"])
|
|
4667
|
+
m=await(0,l.findPreviousCommit)(g,t,r),i.info(`Previous commit hash for ${t}: ${m||"none (new file)"}`,{taskId:e,gitInstancePath:f||"unknown",isWorktreeOperation:a,usingCorrectGitInstance:!0})}else i.warn("Git not available for previous commit detection: "+t,{taskId:e,reason:"no_git_instance"})}catch(e){i.warn(`Failed to find previous commit for ${t}:`,{error:(0,d.getErrorMessage)(e)})}const y=n?`[RECORD:${n}] ${o}`:o
|
|
4668
|
+
await g.add(t),p=(await g.commit(y)).commit
|
|
4669
|
+
try{const r=await g.revparse(["--abbrev-ref","HEAD"]),n=await g.revparse(["HEAD"])
|
|
4670
|
+
i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(m||""),targetFile:t}),p&&n.trim()!==p&&i.warn("Commit hash mismatch after commit",{taskId:e,expectedCommitHash:p,actualHeadHash:n.trim(),targetFile:t})}catch(e){i.warn("Failed to verify post-commit status:",{error:e instanceof Error?e.message:e+""})}i.info("Committed file changes to Git: "+t,{taskId:e,path:t,recordId:r,localRecordId:n,commitHash:p,previousCommitHash:m}),c.recordValue(u+"_git_commit_time",Date.now()-h),c.incrementCounter(u+"_git_commit_success",1)}else i.warn("No Git repository available, skipping commit",{taskId:e,path:t})
|
|
4671
|
+
return{commitHash:p,previousCommitHash:m}}catch(r){return c.incrementCounter(u+"_git_commit_failure",1),c.recordValue(u+"_git_commit_time",Date.now()-h),i.warn("Failed to commit file changes to Git: "+t,{taskId:e,path:t,error:r instanceof Error?r.stack:r+""}),{commitHash:void 0,previousCommitHash:m}}},exports.commitMultipleFilesToGit=o,exports.handleMultiFileGitCommit=async function(e,t,r,n,s,i){const{logger:a,metricsPrefix:c,metrics:l}=s
|
|
4624
4672
|
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))}
|
|
4625
4673
|
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"
|
|
4626
4674
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.addConnectionStatusInfo=function(e){return async(t,n,o)=>{try{const t=e.isInOfflineMode()
|
|
@@ -4642,10 +4690,10 @@ class o{static create(){return exports.ProjectIDFactory.create()}static fromStri
|
|
|
4642
4690
|
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
|
|
4643
4691
|
if(e.includes("_")){const t=e.split("_")
|
|
4644
4692
|
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"
|
|
4645
|
-
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:
|
|
4693
|
+
function r(e,t,r){try{const n=`[${(new Date).toISOString()}] [detached-subagent] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,i.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,s.appendFileSync)(o,n)}catch{}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=function(e){const{agent:t,prompt:d,cwd:u,sessionId:h,model:p,initialBranch:m,serverUrl:g,onSpawn:f}=e
|
|
4646
4694
|
try{const e=u||process.cwd(),o={...process.env,...(0,c.getOpencodeSpawnEnv)(e,(0,l.isDevMode)())}
|
|
4647
4695
|
let y
|
|
4648
|
-
if(
|
|
4696
|
+
if(m&&(o.ALCHEMY_INITIAL_BRANCH=m),r(u,"Spawn env setup",{agent:t,initialBranch:m||"none",sessionId:h||"new",attachMode:!!g}),y=g&&h&&d?["run","--attach",g,"--session",h,"--agent",t,d]:h&&d?["run","--session",h,"--agent",t,d]:d?["run","--agent",t,d]:["run","--agent",t],p){const e=y.findIndex((e=>e===d))
|
|
4649
4697
|
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})
|
|
4650
4698
|
const w=(0,i.join)(u||process.cwd(),".alchemy_lab"),I=(0,i.join)(w,"spawn-stderr.log")
|
|
4651
4699
|
let b
|
|
@@ -4666,18 +4714,18 @@ const u=s.getRequestClient(),h=await u.listRequests(d)
|
|
|
4666
4714
|
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"})
|
|
4667
4715
|
const p=(0,n.extractArrayFromResponse)(h,{logger:c,operationName:"listRequests",defaultValue:[]})
|
|
4668
4716
|
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."}]}
|
|
4669
|
-
const
|
|
4670
|
-
return l({success:!0,requestCount:p.length}),{content:[{type:"text",text:`${
|
|
4717
|
+
const m=p.map((e=>`**${e.title}** (${e.id}) [${e.type}]\nStatus: ${e.status}\nType: ${e.type}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}\n`)).join("\n---\n"),g=`Found ${p.length} request${1===p.length?"":"s"}:`
|
|
4718
|
+
return l({success:!0,requestCount:p.length}),{content:[{type:"text",text:`${g}\n\n${m}`}]}}catch(t){return c.error("Error listing requests",{args:e,error:t instanceof Error?t.stack:t+""}),l({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:"Error listing requests: "+(0,o.getErrorMessage)(t)}],isError:!0}}}
|
|
4671
4719
|
const r=t(9860),n=t(2960),o=t(8824)},8045(e,exports,t){"use strict"
|
|
4672
4720
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4673
4721
|
const r=t(6183),n=t(7456)
|
|
4674
4722
|
exports.def={name:"modify_file",description:'Make targeted edits to existing files and documents.\n\nOperations:\n\u2022 replace-string - Find and replace text\n - mode: \'unique\' (default, safer - fails if multiple matches)\n - mode: \'all\' (replaces all occurrences)\n\u2022 delete-string - Remove text patterns (same modes as replace-string)\n\u2022 insert-lines - Insert content before/after/between lines\n\u2022 replace-lines - Replace specific line numbers\n\u2022 delete-lines - Remove specific line numbers\n\nLine specification (string format for line-based operations):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "10-15"\n\nRead file first to know line numbers. Supports multiple files and operations in one call. Works with both filesystem files (path) and tracked documents (documentId).',schema:r.ModifyFileSchema,annotations:{title:"Modify File",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},hidden:!0,handler(e,t){return(0,n.handleModifyFile)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},8184(e,exports,t){"use strict"
|
|
4675
4723
|
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")
|
|
4676
|
-
try{const i=e,{requestId:c,format:d="summary",path:h}=i,p=s.getRequestClient(),
|
|
4677
|
-
if(!
|
|
4678
|
-
const
|
|
4724
|
+
try{const i=e,{requestId:c,format:d="summary",path:h}=i,p=s.getRequestClient(),m=await p.getRequest(c)
|
|
4725
|
+
if(!m)return u({success:!1,reason:"not_found"}),n("Request not found: "+c)
|
|
4726
|
+
const g=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,f=t.git??(0,o.simpleGit)({baseDir:g,binary:t.gitBinary}),y="completed"===m.status,w="requests/"+c
|
|
4679
4727
|
let I,b
|
|
4680
|
-
if(y){const e=
|
|
4728
|
+
if(y){const e=m.metadata?.mergeBaseSha,t=m.metadata?.mergeCommitSha
|
|
4681
4729
|
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.`)
|
|
4682
4730
|
I=e,b=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)
|
|
4683
4731
|
try{I=(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{b=(await f.raw(["rev-parse",w])).trim()}catch{return u({success:!1,reason:"no_branch"}),n(`Branch ${w} not found.`)}}const k=h?["--",h]:[]
|
|
@@ -4722,35 +4770,35 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4722
4770
|
var t={}
|
|
4723
4771
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
4724
4772
|
return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4725
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,r,n,o,s,i,p,
|
|
4773
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreateDirectory=async function(e,r,n,o,s,i,p,m){const g=i.child({tool:"create_directory"}),f=Date.now()
|
|
4726
4774
|
let y,w,I=l.FileOperationPhase.VALIDATION
|
|
4727
4775
|
const b={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}"}
|
|
4728
4776
|
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)
|
|
4729
4777
|
if("errorResult"in v)return v.errorResult
|
|
4730
4778
|
const{taskId:C}=v
|
|
4731
|
-
|
|
4779
|
+
g.info("Creating directory: "+u,{taskId:C,path:u,comment:h}),l.validateTaskIdFormat(C,g,p,b.metricsPrefix),r.getCurrentBranchContext&&await r.getCurrentBranchContext()
|
|
4732
4780
|
const{normalizedPath:_,fullPath:E}=l.validateAndNormalizePath(u,r)
|
|
4733
4781
|
I=l.FileOperationPhase.TASK_VALIDATION,p.incrementCounter("create_directory_phase",1,{phase:I})
|
|
4734
|
-
const S=await l.validateTaskId(C,_,n,
|
|
4735
|
-
P.taskPromoted&&
|
|
4736
|
-
const x=await l.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:q,context:r,operation:"create-directory",logger:
|
|
4782
|
+
const S=await l.validateTaskId(C,_,n,g,p,b.metricsPrefix),q=S?.requestId,T=await l.validateWorkItemStates(C,_,n,s,r,g,p,b.metricsPrefix),P=await l.autoPromoteTaskStatus(C,S.status,q,T.request?.status,_,n,s,g,p,b.metricsPrefix)
|
|
4783
|
+
P.taskPromoted&&g.info(`Auto-promoted task ${C} (${S.title||"Untitled"}) to in_progress for file operation`,{taskId:C,taskTitle:S.title,previousStatus:S.status,newStatus:P.newTaskStatus,path:_}),P.requestPromoted&&g.info(`Auto-promoted request ${q} to in_progress for file operation`,{requestId:q,previousStatus:T.request?.status,newStatus:P.newRequestStatus,triggeringTaskId:C})
|
|
4784
|
+
const x=await l.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:q,context:r,operation:"create-directory",logger:g,metrics:p,metricsPrefix:b.metricsPrefix})
|
|
4737
4785
|
if(!x.success)throw Error(x.error)
|
|
4738
4786
|
let j=!1
|
|
4739
4787
|
try{j=(await a.default.stat(E)).isDirectory()}catch{j=!1}I=l.FileOperationPhase.RECORD_CREATION,p.incrementCounter("create_directory_phase",1,{phase:I})
|
|
4740
|
-
const{toolRecordId:R,localToolRecordId:M}=await l.createFileOperationRecords(C,q,r.projectId,b.recordType,_,{directoryExists:j,userComment:h},n,o,
|
|
4788
|
+
const{toolRecordId:R,localToolRecordId:M}=await l.createFileOperationRecords(C,q,r.projectId,b.recordType,_,{directoryExists:j,userComment:h},n,o,g,p,b.metricsPrefix,m)
|
|
4741
4789
|
y=R,w=R,I=b.fileOperationPhase,p.incrementCounter("create_directory_phase",1,{phase:I})
|
|
4742
4790
|
let $=j
|
|
4743
|
-
if(!j){await a.default.mkdir(E,{recursive:!0}),
|
|
4791
|
+
if(!j){await a.default.mkdir(E,{recursive:!0}),g.info("Successfully created directory "+_)
|
|
4744
4792
|
try{const e=c.default.join(E,".gitkeep")
|
|
4745
|
-
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),$=!0,
|
|
4793
|
+
await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),$=!0,g.info("Created .gitkeep file for Git tracking")}catch(e){g.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),$=!1}}const O=Date.now()-f
|
|
4746
4794
|
p.recordValue("create_directory_time",O),p.incrementCounter("create_directory_success",1),I=l.FileOperationPhase.GIT_COMMIT,p.incrementCounter("create_directory_phase",1,{phase:I})
|
|
4747
|
-
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!j&&$?_+"/.gitkeep":_,F=await l.commitToGit(C,A,R,M,D,r,
|
|
4748
|
-
I=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,p.incrementCounter("create_directory_phase",1,{phase:I}),await l.updateFileOperationRecords(C,y,w,_,b.recordType,`Successfully ${j?"verified":"created"} directory: ${_}`,{status:"completed",commitHash:F.commitHash,previousCommitHash:F.previousCommitHash,directoryExists:j,isDirectory:!0,userComment:h},`Successfully ${j?"verified":"created"} directory: ${_}`,n,o,
|
|
4795
|
+
const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!j&&$?_+"/.gitkeep":_,F=await l.commitToGit(C,A,R,M,D,r,g,p,b.metricsPrefix)
|
|
4796
|
+
I=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,p.incrementCounter("create_directory_phase",1,{phase:I}),await l.updateFileOperationRecords(C,y,w,_,b.recordType,`Successfully ${j?"verified":"created"} directory: ${_}`,{status:"completed",commitHash:F.commitHash,previousCommitHash:F.previousCommitHash,directoryExists:j,isDirectory:!0,userComment:h},`Successfully ${j?"verified":"created"} directory: ${_}`,n,o,g,p,b.metricsPrefix)
|
|
4749
4797
|
const N=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
|
|
4750
4798
|
return{content:[{type:"text",text:j?"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
|
|
4751
|
-
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:I,attemptedTaskId:e.taskId,taskIdValidationFailed:n},note:`Failed to create directory ${e.path} - ${(0,h.getErrorMessage)(t)}`})}catch(t){
|
|
4752
|
-
if(p.recordValue("create_directory_time",s),p.incrementCounter("create_directory_errors",1),
|
|
4753
|
-
try{await l.updateFileOperationRecords(e.taskId,y,w,e.path,b.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,
|
|
4799
|
+
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:I,attemptedTaskId:e.taskId,taskIdValidationFailed:n},note:`Failed to create directory ${e.path} - ${(0,h.getErrorMessage)(t)}`})}catch(t){g.error("Failed to create failure record for create directory operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,path:e.path})}const s=Date.now()-f
|
|
4800
|
+
if(p.recordValue("create_directory_time",s),p.incrementCounter("create_directory_errors",1),g.error("Error creating directory:",{error:(0,h.getErrorMessage)(t),time:s}),(y||w)&&e.taskId){I=l.FileOperationPhase.RECORD_UPDATE_FAILURE
|
|
4801
|
+
try{await l.updateFileOperationRecords(e.taskId,y,w,e.path,b.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,h.getErrorMessage)(t),userComment:e.comment},"Failed to create directory "+e.path,n,o,g,p,b.metricsPrefix)}catch(t){g.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(t,I,g,p,e,b)}}
|
|
4754
4802
|
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"
|
|
4755
4803
|
function r(e){const t=[]
|
|
4756
4804
|
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"
|
|
@@ -4759,11 +4807,11 @@ case"move-files":return"\u{1f4cb} Move Files"
|
|
|
4759
4807
|
case"delete-files":return"\u{1f5d1}\ufe0f Delete Files"
|
|
4760
4808
|
case"manage-files":return"\u{1f4c1} Manage Files"
|
|
4761
4809
|
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")
|
|
4762
|
-
try{const{requestId:l,detailLevel:p="summary",taskId:
|
|
4810
|
+
try{const{requestId:l,detailLevel:p="summary",taskId:m,showDiff:g=!1,fileFilter:f}=e
|
|
4763
4811
|
if(!l)throw(0,o.createValidationError)("Request ID is required")
|
|
4764
4812
|
if(!/^req[_\d].+$/.test(l))throw(0,o.createValidationError)(`Invalid request ID format: ${l}. Expected format: req_[26 chars] or req######`)
|
|
4765
|
-
if(
|
|
4766
|
-
if(u.info("Getting file changes for request "+l,{detailLevel:p,taskId:
|
|
4813
|
+
if(m&&!(0,a.isTaskRef)(m))throw(0,o.createValidationError)(`Invalid task ID format: ${m}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
|
|
4814
|
+
if(u.info("Getting file changes for request "+l,{detailLevel:p,taskId:m,showDiff:g}),!t.git)throw Error("Git integration not available in this context")
|
|
4767
4815
|
const y=t.projectId
|
|
4768
4816
|
let w
|
|
4769
4817
|
c.setProjectId(y)
|
|
@@ -4772,7 +4820,7 @@ w={id:n.id||l,title:n.title||"Unknown Request",description:n.description||"No de
|
|
|
4772
4820
|
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}
|
|
4773
4821
|
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()
|
|
4774
4822
|
let o=[]
|
|
4775
|
-
try{
|
|
4823
|
+
try{m?(o=await e.getToolRecordsByTaskId(m),u.info(`Fetched ${o.length} records for task ${m}`)):(o=await e.getToolRecordsByRequestId(l),u.info(`Fetched ${o.length} records for request ${l}`))}catch(e){u.warn("Error fetching tool records: "+(0,i.getErrorMessage)(e)),o=[]}const s=await async function(e,t,o,s,a,c,l){let d="# File Operations - Detailed View\n\n"
|
|
4776
4824
|
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
|
|
4777
4825
|
let u=t.filter((e=>{const t=e.type
|
|
4778
4826
|
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()))
|
|
@@ -4786,10 +4834,10 @@ let r=0
|
|
|
4786
4834
|
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])
|
|
4787
4835
|
if(e&&e.trim()){const r=500,n=e.length
|
|
4788
4836
|
if(n>r){const o=e.substring(0,r),s=(n/1024).toFixed(1)
|
|
4789
|
-
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,
|
|
4837
|
+
d+=`\n**Changes preview** (first ${r} chars):\n\`\`\`diff\n${o}\n\`\`\`\n`,d+=`... (diff truncated, ${s}KB total)\n`,d+=`\u{1f4a1} Use \`file-history\` tool with commit \`${t.metadata.commitHash.substring(0,8)}\` to see full diff\n`}else d+=`\n**Changes:**\n\`\`\`diff\n${e}\n\`\`\`\n`}}catch(e){c.debug("Could not fetch diff for commit",{commit:t.metadata.commitHash,error:(0,i.getErrorMessage)(e)})}d+="\n---\n\n"}return d}(w,o,m,g,t.git,u,f)
|
|
4790
4838
|
return h({success:!0,recordCount:o.length}),{content:[{type:"text",text:s}]}}{const e=c.getToolRecordClient()
|
|
4791
4839
|
let n=[]
|
|
4792
|
-
try{
|
|
4840
|
+
try{m?(n=await e.getToolRecordsByTaskId(m),u.info(`Fetched ${n.length} records for task ${m}`)):(n=await e.getToolRecordsByRequestId(l),u.info(`Fetched ${n.length} records for request ${l}`))}catch(e){u.warn("Error fetching tool records: "+(0,i.getErrorMessage)(e)),n=[]}const o=await async function(e,t){const n=new Map
|
|
4793
4841
|
let o=0
|
|
4794
4842
|
for(const s of e){const e=s.type
|
|
4795
4843
|
if(!["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(e))continue
|
|
@@ -4871,16 +4919,16 @@ function r(e){const t=c[e]
|
|
|
4871
4919
|
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.`)
|
|
4872
4920
|
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)
|
|
4873
4921
|
if(!s(u.projectId)){const t=Error(`Invalid projectId format: ${u.projectId}. Cannot create failure record without valid projectId.`)
|
|
4874
|
-
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,"_"),
|
|
4922
|
+
throw l.error("Cannot create failure record due to invalid projectId",{toolName:e,projectId:u.projectId,error:t.message}),t}const h=Date.now(),p=e.replace(/-/g,"_"),m=(0,i.getErrorMessage)(t),g=t instanceof Error?t.stack:void 0
|
|
4875
4923
|
try{const t=r(e),s={}
|
|
4876
4924
|
let i,f
|
|
4877
4925
|
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})))
|
|
4878
|
-
let y=u.note||`Failed to execute ${e}: ${
|
|
4926
|
+
let y=u.note||`Failed to execute ${e}: ${m.substring(0,100)}${m.length>100?"...":""}`
|
|
4879
4927
|
Object.keys(s).length>0&&(y+=` (Warning: Invalid IDs provided: ${Object.entries(s).map((([e,t])=>`${e}: ${t}`)).join(", ")})`)
|
|
4880
|
-
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:
|
|
4881
|
-
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:
|
|
4928
|
+
const w={projectId:u.projectId,type:t,note:y,metadata:{status:"failed",error:m,errorStack:g,originalToolName:e,timestamp:(new Date).toISOString(),invalidIds:Object.keys(s).length>0?s:void 0,...a}}
|
|
4929
|
+
i&&(w.taskId=i),f&&(w.requestId=f),l.info("Creating failure tool record for "+e,{toolName:e,recordType:w.type,...i&&{taskId:i},...f&&{requestId:f},projectId:u.projectId,invalidIds:Object.keys(s).length>0?s:void 0,error:m})
|
|
4882
4930
|
const I=await c.createToolRecord(w)
|
|
4883
|
-
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:I.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:
|
|
4931
|
+
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:I.id})}catch(t){throw d.recordValue(p+"_failure_record_creation_time",Date.now()-h),d.incrementCounter(p+"_failure_record_creation_failure",1),l.error("Failed to create failure tool record for "+e,{error:t instanceof Error?t.stack:t+"",toolName:e,...u.taskId&&{originalTaskId:u.taskId},...u.requestId&&{originalRequestId:u.requestId},projectId:u.projectId,originalError:m}),t}}
|
|
4884
4932
|
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"
|
|
4885
4933
|
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)
|
|
4886
4934
|
else if(e&&"object"==typeof e)for(const t of Object.keys(e)){const n=e[t]
|
|
@@ -4905,13 +4953,13 @@ function r(e,t,r){const n=exports.ERROR_TYPE_PROPERTIES[e]||exports.ERROR_TYPE_P
|
|
|
4905
4953
|
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)
|
|
4906
4954
|
return{statusCode:e.statusCode,body:t}}if(e instanceof Error&&"ConnectionError"===e.name){const t=e
|
|
4907
4955
|
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")
|
|
4908
|
-
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
|
|
4956
|
+
return{statusCode:o.error.statusCode,body:o}}function s(e){return!n(e)||e.isRetryable()}Object.defineProperty(exports,"__esModule",{value:!0}),exports.UnauthorizedError=exports.McpProtocolError=exports.FileOperationError=exports.ServiceError=exports.DatabaseError=exports.AuthorizationError=exports.AuthenticationError=exports.ValidationError=exports.NotFoundError=exports.AppError=exports.ErrorUtils=exports.ERROR_TYPE_PROPERTIES=void 0,exports.createErrorResponse=r,exports.createAppError=function(e,t="INTERNAL_ERROR",r=500,n){return new a(e,t,r,n)},exports.createNotFoundError=function(e="Resource not found",t){return new c(e,t)},exports.createValidationError=function(e="Invalid input",t){return new l(e,t)},exports.createAuthenticationError=function(e="Authentication required",t){return new d(e,t)},exports.createAuthorizationError=function(e="Not authorized",t){return new u(e,t)},exports.createDatabaseError=function(e="Database error",t){return new h(e,t)},exports.createServiceError=function(e="Service unavailable",t){return new p(e,t)},exports.createFileOperationError=function(e="File operation error",t){return new m(e,t)},exports.createMcpProtocolError=function(e="MCP protocol error",t){return new g(e,t)},exports.isAppError=n,exports.errorToResponse=o,exports.isRetryableError=s
|
|
4909
4957
|
const i=t(7388)
|
|
4910
4958
|
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}
|
|
4911
4959
|
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)
|
|
4912
4960
|
const o=exports.ERROR_TYPE_PROPERTIES[this.code]
|
|
4913
4961
|
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
|
|
4914
|
-
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class
|
|
4962
|
+
e&&e.error&&"retryable"in e.error&&(this.details.retryable=!!e.error.retryable)}}}class m extends a{constructor(e="File operation error",t){super(e,"FILE_OPERATION_ERROR",500,t)}}class g extends a{constructor(e="MCP protocol error",t){super(e,i.MCP_PROTOCOL_ERROR,500,t)}}exports.AppError=a,exports.NotFoundError=c,exports.ValidationError=l,exports.AuthenticationError=d,exports.AuthorizationError=u,exports.DatabaseError=h,exports.ServiceError=p,exports.FileOperationError=m,exports.McpProtocolError=g,exports.UnauthorizedError=d},8712(e,exports){"use strict"
|
|
4915
4963
|
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}
|
|
4916
4964
|
const o=e.split("\n"),s=[],i=new Set
|
|
4917
4965
|
let a=!1,c=""
|
|
@@ -4954,7 +5002,7 @@ if("string"==typeof r&&r.length>0)return`${e}: ${r}`}return"Unknown error (no re
|
|
|
4954
5002
|
async function r(e,t,r,o,s,i,a,c,l,d){const u=a?function(e){const t=e.match(/^(\d+)([mhdw])$/)
|
|
4955
5003
|
return t?`${parseInt(t[1],10)}.${{m:"minutes",h:"hours",d:"days",w:"weeks"}[t[2]]}.ago`:e}(a):void 0
|
|
4956
5004
|
try{let a
|
|
4957
|
-
if(i===await
|
|
5005
|
+
if(i===await g(e,l,d))a=await e.log({file:t,maxCount:r,...u&&{"--since":u}})
|
|
4958
5006
|
else try{a=await e.log({from:i,file:t,maxCount:r,...u&&{"--since":u}})}catch(a){l.debug("git.log with 'from' failed, trying raw command",{fromError:a})
|
|
4959
5007
|
try{const a=await e.raw(["log","--max-count="+r,"--pretty=format:%H|%an|%ad|%s","--date=iso",...u?["--since="+u]:[],i,"--",t])
|
|
4960
5008
|
if(a&&a.trim()){const r=a.trim().split("\n").map((e=>{const[t,r,n,o]=e.split("|")
|
|
@@ -4977,26 +5025,26 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
|
|
|
4977
5025
|
var t={}
|
|
4978
5026
|
if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
|
|
4979
5027
|
return i(t,e),t})
|
|
4980
|
-
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"),
|
|
4981
|
-
try{const o=e,{path:a,limit:
|
|
5028
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileHistory=async function(e,t,n,o,s){const i=o.child({tool:"file_history"}),a=s.startTimer("tool_execution_time"),m=Date.now()
|
|
5029
|
+
try{const o=e,{path:a,limit:g,showDiff:f,showTraceability:y,branch:w,commit:I,since:b}=o
|
|
4982
5030
|
return I?(i.info("Getting diff for specific commit",{filePath:a,commit:I}),await async function(e,t,r,n){const o=r.git,s=c.normalize(e).replace(/\\/g,"/")
|
|
4983
5031
|
if(n.info("Getting full diff for commit",{filePath:e,commit:t}),!o)return{content:[{type:"text",text:"\u274c Git not initialized"}],isError:!0}
|
|
4984
5032
|
try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
|
|
4985
5033
|
if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
|
|
4986
5034
|
const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
|
|
4987
5035
|
let a="# File History - Commit Diff\n\n"
|
|
4988
|
-
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,I,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:
|
|
5036
|
+
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,I,t,i)):(i.info("Getting file history with branch support",{filePath:a,limit:g,showDiff:f,showTraceability:y,branch:w}),await async function(e,t,n,o,s,i,a,c,h,m,g){try{const{normalizedPath:f,fullPath:y}=p.validateAndNormalizePath(e,a)
|
|
4989
5037
|
try{await l.access(y)}catch(e){throw Error("File not found: "+f)}const w=a.git
|
|
4990
5038
|
if(!w)throw Error("Git is not available in this context")
|
|
4991
5039
|
let I={branch:null,requestId:null,isMain:!0}
|
|
4992
5040
|
if(a.getCurrentBranchContext)try{I=await a.getCurrentBranchContext(),h.info("Current branch context detected",{branch:I.branch,requestId:I.requestId,isMain:I.isMain})}catch(e){h.warn("Could not get current branch context",{error:e})}let b=[],k=""
|
|
4993
|
-
if(s)b=await r(w,f,t,n,o,s,i,c,h,
|
|
4994
|
-
else{if(I.isMain&&!o)return h.info("Showing request-level timeline on main branch"),{content:[{type:"text",text:await(0,u.getRequestTimelineForFile)(w,f,c,h,
|
|
4995
|
-
if(I.requestId)return h.info("Showing operation-level detail on request branch",{requestId:I.requestId}),{content:[{type:"text",text:await(0,u.getOperationDetailForFile)(f,I.requestId,c,h,
|
|
5041
|
+
if(s)b=await r(w,f,t,n,o,s,i,c,h,m),k=`## File History: ${f} (Branch: ${s})\n\n`
|
|
5042
|
+
else{if(I.isMain&&!o)return h.info("Showing request-level timeline on main branch"),{content:[{type:"text",text:await(0,u.getRequestTimelineForFile)(w,f,c,h,m)}]}
|
|
5043
|
+
if(I.requestId)return h.info("Showing operation-level detail on request branch",{requestId:I.requestId}),{content:[{type:"text",text:await(0,u.getOperationDetailForFile)(f,I.requestId,c,h,m)}]}
|
|
4996
5044
|
{const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
|
|
4997
5045
|
if(!i.isMain&&i.branch){const p=await r(e,t,n,o,s,i.branch,a,c,l,d)
|
|
4998
|
-
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),
|
|
4999
|
-
return u.push(...
|
|
5046
|
+
u.push(...p),p.length>0&&h.push(i.branch+" (current)")}const p=await r(e,t,n,o,s,"main",a,c,l,d),m=new Set(u.map((e=>e.hash))),g=p.filter((e=>!m.has(e.hash)))
|
|
5047
|
+
return u.push(...g),p.length>0&&h.push("main"),u.sort(((e,t)=>new Date(t.date).getTime()-new Date(e.date).getTime())),{versions:u.slice(0,n),sources:h}}(w,f,t,n,o,I,i,c,h,m)
|
|
5000
5048
|
b=e.versions,k=`## File History: ${f} (Combined View)\n\n`,k+=`**Current Context:** ${I.isMain?"main":`${I.branch} (${I.requestId})`}\n`,k+=`**History Sources:** ${e.sources.join(", ")}\n\n`}}if(0===b.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}]}
|
|
5001
5049
|
const v=b.length,C=Math.min(b.length,t)
|
|
5002
5050
|
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:** ${b.length}\n`,k+="**Current File Size:** "
|
|
@@ -5005,9 +5053,9 @@ for(let e=0;e<b.length;e++){const t=b[e]
|
|
|
5005
5053
|
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")
|
|
5006
5054
|
let r=0,n=0
|
|
5007
5055
|
for(const t of e)t.startsWith("+")&&!t.startsWith("+++")&&r++,t.startsWith("-")&&!t.startsWith("---")&&n++
|
|
5008
|
-
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:b.length,targetBranch:s,currentBranch:I.branch,duration:Date.now()-
|
|
5056
|
+
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:b.length,targetBranch:s,currentBranch:I.branch,duration:Date.now()-g}),m.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:k}]}}catch(e){throw e}}(a,g,f,y,w,b,t,n,i,s,m))}catch(e){const t=Date.now()-m
|
|
5009
5057
|
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}}}
|
|
5010
|
-
const c=a(t(6928)),l=a(t(1943)),d=t(1181),u=t(2085),h=t(8824),p=a(t(5967)),
|
|
5058
|
+
const c=a(t(6928)),l=a(t(1943)),d=t(1181),u=t(2085),h=t(8824),p=a(t(5967)),m=a(t(7478)),{getCurrentBranch:g}=m},8849(e,exports,t){"use strict"
|
|
5011
5059
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
5012
5060
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5013
5061
|
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=[]
|
|
@@ -5137,7 +5185,7 @@ let c
|
|
|
5137
5185
|
try{const e=await fetch(`http://localhost:${I}/api/project-settings`)
|
|
5138
5186
|
if(e.ok){const t=await e.json()
|
|
5139
5187
|
if(t.data?.defaultModel){const[e,...r]=t.data.defaultModel.split("/")
|
|
5140
|
-
c={providerID:e,modelID:r.join("/")}}}}catch{}const l=`${i.replace(/\/$/,"")}/session/${e}/prompt_async`,d={type:"text",text:t,metadata:s??(0,
|
|
5188
|
+
c={providerID:e,modelID:r.join("/")}}}}catch{}const l=`${i.replace(/\/$/,"")}/session/${e}/prompt_async`,d={type:"text",text:t,metadata:s??(0,m.partMeta)("inserted-prompt")},u=await fetch(l,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[d],...a?{agent:a}:{},...c?{model:c}:{}})})
|
|
5141
5189
|
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
|
|
5142
5190
|
if(!s)throw new u.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
|
|
5143
5191
|
return(0,w.logSessionIdentity)(""+r,"identity",{sessionId:s,fromCliOrigin:!!o?.sessionId}),s}function a(e){const t=[],r=e.content||{}
|
|
@@ -5149,42 +5197,42 @@ if(!I)throw new u.ValidationError("API client not available")
|
|
|
5149
5197
|
const{operation:v}=e
|
|
5150
5198
|
k.info("Session message operation",{operation:v}),p.incrementCounter("session_message_operations",1,{operation:v})
|
|
5151
5199
|
try{switch(v){case"send":if(!e.type)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
5152
|
-
return(0,
|
|
5200
|
+
return(0,m.withAlchemyKind)(await async function(e,t,r,c,d){const{type:h}=e
|
|
5153
5201
|
if(!h)throw new u.ValidationError('send operation requires type ("question" or "report")')
|
|
5154
5202
|
const p=c.getSessionMessageClient()
|
|
5155
5203
|
if(!p)throw new u.ValidationError("Session message client not available")
|
|
5156
|
-
if("question"===h)return await async function(e,t,r,c,l,d){const{toSessionId:h,questionType:p,questionContent:
|
|
5157
|
-
if(!p||!
|
|
5204
|
+
if("question"===h)return await async function(e,t,r,c,l,d){const{toSessionId:h,questionType:p,questionContent:m,priority:g,expiresInHours:f,relatesTo:w}=e
|
|
5205
|
+
if(!p||!m?.question)throw new u.ValidationError("Question requires questionType and questionContent.question")
|
|
5158
5206
|
const I=i(0,0,"session_message_operations",0,d),b=await async function(e,t,r,n){if("parent"===e){const e=await s(t,r,n)
|
|
5159
5207
|
if(!e)throw new u.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
|
|
5160
5208
|
return n.info('Resolved toSessionId "parent" to actual ID',{parentId:e}),e}return void 0===e?void 0:(0,y.asExternal)(e)}(h,I,c,r)
|
|
5161
|
-
if(!("alternatives"!==p||
|
|
5209
|
+
if(!("alternatives"!==p||m.options&&Array.isArray(m.options)))throw new u.ValidationError("Alternatives questions require options array")
|
|
5162
5210
|
r.info("Creating question",{fromSessionId:I,toSessionId:b,questionType:p})
|
|
5163
|
-
const k=await l.createQuestion({fromSessionId:I,toSessionId:b,questionType:p,question:
|
|
5211
|
+
const k=await l.createQuestion({fromSessionId:I,toSessionId:b,questionType:p,question:m.question,options:m.options,context:m.context,allowMultiple:m.allowMultiple,priority:g,expiresInHours:f,...w?{relatesTo:w}:{}})
|
|
5164
5212
|
let v=""
|
|
5165
|
-
if(b){const e=await n(I)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:
|
|
5213
|
+
if(b){const e=await n(I)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:m.question,questionType:p,options:m.options,context:m.context,allowMultiple:m.allowMultiple,fromAgent:e,fromSessionId:I,priority:k.priority,expiresAt:k.expiresAt,...w?{relatesTo:w}:{}}}}
|
|
5166
5214
|
v=await o(b,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]
|
|
5167
5215
|
if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&&t.options){r.push(""),r.push("**Options:**")
|
|
5168
5216
|
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)
|
|
5169
|
-
if("report"===h)return await async function(e,t,r,a,c,d){const{status:h,summary:p,details:
|
|
5217
|
+
if("report"===h)return await async function(e,t,r,a,c,d){const{status:h,summary:p,details:m,finish:f,relatesTo:w}=e
|
|
5170
5218
|
if(!h||!p)throw new u.ValidationError("Report requires status and summary")
|
|
5171
5219
|
const I=i(0,0,"session_message_operations",0,d),b=await(async()=>{if(e.toSessionId&&"parent"!==e.toSessionId)return r.info("Using explicit toSessionId for report",{parentSessionId:e.toSessionId}),(0,y.asExternal)(e.toSessionId)
|
|
5172
5220
|
const t=await s(I,a,r)
|
|
5173
5221
|
if(t)return r.info("Auto-resolved parent session",{parentSessionId:t}),t
|
|
5174
5222
|
throw new u.ValidationError("Could not find parent session. Ensure this session was created with a parent link, or provide an explicit toSessionId.")})()
|
|
5175
5223
|
r.info("Submitting report",{sessionId:I,parentSessionId:b,status:h})
|
|
5176
|
-
const k=await c.createReport({fromSessionId:I,toSessionId:b,status:h,summary:p,details:
|
|
5177
|
-
return(0,
|
|
5224
|
+
const k=await c.createReport({fromSessionId:I,toSessionId:b,status:h,summary:p,details:m,...w?{relatesTo:w}:{}}),v=await n(I)??"agent",C={alchemy:{kind:"worker-report",payload:{status:h,summary:p,details:m,fromAgent:v,fromSessionId:I,...w?{relatesTo:w}:{}}}},_=await o(b,function(e,t="agent"){const r=e.content||{}
|
|
5225
|
+
return(0,g.formatReportNotification)({messageCode:e.messageCode,status:r.reportStatus,summary:r.summary,details:r.details,fromSessionId:e.fromSessionId,senderAgent:t})}(k,v),t,r,C)
|
|
5178
5226
|
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)
|
|
5179
5227
|
throw new u.ValidationError(`Unknown message type: ${h}. Use "question" or "report".`)}(e,t,k,I,b),r("send",e))
|
|
5180
5228
|
case"reply":if(!e.messageCode)throw new u.ValidationError("reply operation requires messageCode")
|
|
5181
|
-
return(0,
|
|
5229
|
+
return(0,m.withAlchemyKind)(await async function(e,t,r,s,i){const{messageCode:c}=e
|
|
5182
5230
|
if(!c)throw new u.ValidationError("reply operation requires messageCode")
|
|
5183
5231
|
const d=s.getSessionMessageClient()
|
|
5184
5232
|
if(!d)throw new u.ValidationError("Session message client not available")
|
|
5185
5233
|
if(c.startsWith("Q-")){const{text:s,selectedOptions:l,notes:u}=e,h=e.respondedBySessionId??i?.sessionId
|
|
5186
5234
|
r.info("Answering question",{messageCode:c,respondedBySessionId:h,autoDerived:!e.respondedBySessionId})
|
|
5187
|
-
const p=await d.answerQuestion(c,{respondedBySessionId:h,text:s,selectedOptions:l,notes:u}),
|
|
5235
|
+
const p=await d.answerQuestion(c,{respondedBySessionId:h,text:s,selectedOptions:l,notes:u}),m=h?await n(h)??"agent":"agent",g=p.content||{},f=p.response||{},y={alchemy:{kind:"question-answered",payload:{messageCode:p.messageCode,question:g.question,answer:f.text,selectedOptions:f.selectedOptions,notes:f.notes,answeredByAgent:m,answeredBySessionId:h}}},w=await o(p.fromSessionId,function(e){const t=e.content||{},r=e.response||{},n=["\u{1f4ec} **Your question has been answered!**","","**Question Code:** "+e.messageCode,"**Question:** "+t.question,"","---","**Answered by:** "+e.respondedBySessionId]
|
|
5188
5236
|
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)
|
|
5189
5237
|
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})
|
|
5190
5238
|
const e=await d.acknowledgeReport(c)
|
|
@@ -5199,21 +5247,21 @@ let l
|
|
|
5199
5247
|
try{const e=I.getSessionMessageClient()
|
|
5200
5248
|
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"})
|
|
5201
5249
|
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=I.getSessionMessageClient()
|
|
5202
|
-
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,
|
|
5203
|
-
const
|
|
5204
|
-
if(!
|
|
5250
|
+
e&&(await e.answerQuestion(l,{respondedBySessionId:"system",selectedOptions:["build"]}),a=!0,k.info("offer-handoff: auto-confirmed for auto-planner",{fromSessionId:r,messageCode:l}))}catch(e){k.warn("offer-handoff: failed to auto-confirm for auto-planner",{error:(0,h.getErrorMessage)(e)})}return(0,m.withAlchemyKind)({content:[{type:"text",text:a?"Handoff auto-confirmed (auto-planner). Start-building has been queued \u2014 you can stop now.":'Handoff offered to user. STOP here and wait \u2014 the user will choose "Start Building" or "Keep Planning". You will receive their choice as a new message. Do NOT generate any further output until then.'}],isError:!1,...(0,m.alchemyMeta)({pendingAction:{kind:"plan-handoff",payload:{summary:t.summary,requestIds:t.requestIds,parentSessionId:o,fromSessionId:r,autoConfirmed:a}}})},"offer-handoff")}case"list":return(0,m.withAlchemyKind)(await async function(e,t,r,n,o){let{sessionId:s,messageType:i,direction:a,status:c,readStatus:l,reportStatus:h,limit:p,offset:m}=e
|
|
5251
|
+
const g=n.getSessionMessageClient()
|
|
5252
|
+
if(!g)throw new u.ValidationError("Session message client not available")
|
|
5205
5253
|
if(!s){const e=o?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
|
|
5206
5254
|
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."}]}
|
|
5207
5255
|
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})
|
|
5208
|
-
const y={sessionId:s,direction:a,limit:p,offset:
|
|
5256
|
+
const y={sessionId:s,direction:a,limit:p,offset:m}
|
|
5209
5257
|
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)
|
|
5210
|
-
const I=await
|
|
5258
|
+
const I=await g.listMessages(y)
|
|
5211
5259
|
if(0===I.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
|
|
5212
5260
|
const b=[`Found ${I.length} message(s):\n`]
|
|
5213
5261
|
for(const e of I)b.push("---\n"),b.push(d(e)),b.push("")
|
|
5214
5262
|
return{content:[{type:"text",text:b.join("\n")}]}}(e.list||{},0,k,I,b),"list-messages")
|
|
5215
5263
|
case"get":if(!e.messageCode)throw new u.ValidationError("get operation requires messageCode")
|
|
5216
|
-
return(0,
|
|
5264
|
+
return(0,m.withAlchemyKind)(await async function(e,t,r){const{messageCode:n}=e
|
|
5217
5265
|
if(!n)throw new u.ValidationError("get operation requires messageCode")
|
|
5218
5266
|
const o=r.getSessionMessageClient()
|
|
5219
5267
|
if(!o)throw new u.ValidationError("Session message client not available")
|
|
@@ -5221,7 +5269,7 @@ t.debug("Getting message",{messageCode:n})
|
|
|
5221
5269
|
const s=await o.getMessage(n)
|
|
5222
5270
|
return s?{content:[{type:"text",text:d(s)}]}:{content:[{type:"text",text:`\u274c Message with code ${n} not found.`}],isError:!0}}(e,k,I),"get-message")
|
|
5223
5271
|
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}}}
|
|
5224
|
-
const u=t(9860),h=t(8824),p=t(7617),
|
|
5272
|
+
const u=t(9860),h=t(8824),p=t(7617),m=t(2272),g=t(7904),f=t(6688),y=t(3545),w=t(7280),I=(0,t(9414).getActionServerPort)(),b=new Map},9080(e,exports,t){"use strict"
|
|
5225
5273
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
5226
5274
|
const r=t(6183),n=t(1281)
|
|
5227
5275
|
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"
|
|
@@ -5247,12 +5295,12 @@ let l,d
|
|
|
5247
5295
|
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)})
|
|
5248
5296
|
let u=0
|
|
5249
5297
|
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})
|
|
5250
|
-
let h=!1,p="",
|
|
5251
|
-
if(0!==u?(h=!0,p="merge-tree-exit-code"):d&&d.trim()?(
|
|
5252
|
-
!
|
|
5253
|
-
let
|
|
5254
|
-
if(
|
|
5255
|
-
else try{
|
|
5298
|
+
let h=!1,p="",m=null
|
|
5299
|
+
if(0!==u?(h=!0,p="merge-tree-exit-code"):d&&d.trim()?(m=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch),m.hasConflictMarkers?(h=!0,p="conflict-parser-detected-markers",r.warn("Git exit code 0 but conflict parser found conflict markers - treating as conflict")):(h=!1,p="clean-merge-with-changes",r.info("Git exit code 0 and conflict parser found no markers - treating as clean merge",{hasOutput:!0,outputLength:d.length}))):(h=!1,p="clean-merge-no-changes"),r.info("FINAL conflict detection result (trusting Git exit codes)",{hasConflicts:h,exitCode:u,hasOutput:!!d.trim(),outputLength:d?d.length:0,conflictReason:p,method:"git-exit-code-primary",trustedGitExitCode:0===u}),!h)return{hasConflicts:!1,conflictedFiles:[],summary:"No conflicts detected (merge-tree clean)",resolutionInstructions:"",detectionMethod:"merge-tree-analysis",rawOutput:d}
|
|
5300
|
+
!m&&d&&d.trim()&&(m=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch))
|
|
5301
|
+
let g=[]
|
|
5302
|
+
if(m&&m.filesParsed&&m.filesParsed.length>0)g=m.filesParsed.map((e=>({path:e,conflictType:"content",description:"Merge conflict detected"}))),r.debug("Successfully extracted conflict files from parsed content",{conflictedFilesCount:g.length,files:g.map((e=>e.path))})
|
|
5303
|
+
else try{g=this.parseMergeTreeOutput(d,r),r.debug("Used fallback merge-tree parsing",{conflictedFilesCount:g.length})}catch(e){r.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),g=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===g.length&&(r.warn("Git detected conflicts but no files could be determined - using fallback"),g=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:g,summary:g.length>0&&"<parsing failed>"!==g[0].path&&"<unknown files>"!==g[0].path?g.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateMultiAgentInstructions(g,e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:d,rawConflictContent:m?m.cleanContent:void 0}}catch(e){throw r.error("Pure multi-agent conflict detection failed",{error:e}),e}}parseMergeTreeOutput(e,t){const r=[]
|
|
5256
5304
|
if(!e||!e.trim())return t.debug("Empty merge-tree output - no conflicts to parse"),[]
|
|
5257
5305
|
let n
|
|
5258
5306
|
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
|
|
@@ -5309,23 +5357,23 @@ o+=`## Test 4: All commits containing "${n}" (not just merges)\n`,o+=`Found ${e?
|
|
|
5309
5357
|
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()
|
|
5310
5358
|
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}}}
|
|
5311
5359
|
const r=t(8824)},9442(e,exports,t){"use strict"
|
|
5312
|
-
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:
|
|
5360
|
+
function r(e){return{line:e.line,actually_matched:e.actuallyMatched,match_type:e.matchType}}async function n(e,t,n,o,s,i,a){const{path:c,documentId:d,replacements:p,fuzzy_match:m}=e,g=!!d,f=void 0!==m?m:t,y={type:g?"document":"file",path:c,documentId:d,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,externalEditDebugInfo:{detectionRan:!1,reason:g?"Skipped: Document operation":n.git?"Pending":"Skipped: No Git context"}}
|
|
5313
5361
|
try{let t,o
|
|
5314
|
-
if(
|
|
5362
|
+
if(g){t=await n.documentFileManager.getDocumentAsFile(d)
|
|
5315
5363
|
const e=n.documentFileManager.getCachedDocumentInfo(d)
|
|
5316
5364
|
y.filename=e?.filename,o="document:"+d}else{const e=u.validateAndNormalizePath(c,n)
|
|
5317
|
-
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),
|
|
5365
|
+
o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),m=[]
|
|
5318
5366
|
for(const t of p){const{old:n,new:o,match_mode:i="unique"}=t,a={old:n,new:o,success:!1}
|
|
5319
5367
|
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)
|
|
5320
5368
|
continue}const t=(0,h.findMatches)(s,n,f,100,e.path)
|
|
5321
5369
|
if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(f?" (tried fuzzy matching)":""),a.success=!1
|
|
5322
5370
|
const e=(0,h.findSimilarMatches)(s,n,5,.3)
|
|
5323
|
-
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++):
|
|
5371
|
+
e.length>0&&(a.similarMatches=e),y.failedReplacements++}else"unique"===i&&t.length>1?(a.error=`Multiple matches found (${t.length}) - expected unique match`,a.success=!1,a.details=t.map(r),y.failedReplacements++):m.push({matches:t,newText:o,matchMode:i,repResult:a})}catch(e){a.error=(0,I.getErrorMessage)(e),a.success=!1,y.failedReplacements++}y.replacements.push(a)}let w=s
|
|
5324
5372
|
const b=[]
|
|
5325
|
-
for(const e of
|
|
5373
|
+
for(const e of m)for(const t of e.matches)b.push({match:t,newText:e.newText,repResult:e.repResult})
|
|
5326
5374
|
b.sort(((e,t)=>t.match.startPos-e.match.startPos))
|
|
5327
5375
|
for(const{match:e,newText:t,repResult:n}of b)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++)
|
|
5328
|
-
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),
|
|
5376
|
+
y.successfulReplacements>0&&(await l.default.writeFile(t,w,"utf8"),g&&(n.documentFileManager.markForSync(d),await n.documentFileManager.syncDocument(d))),i&&(y.externalEditWarning=i),a&&(y.externalEditDebugInfo={detectionRan:!0,...a}),y.success=0===y.failedReplacements}catch(e){y.error=(0,I.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)
|
|
5329
5377
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
5330
5378
|
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=[]
|
|
5331
5379
|
for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
|
|
@@ -5355,7 +5403,7 @@ const t=await u.autoPromoteTaskStatus(T,D.status,A,e.request?.status,$,o,i,k,c,"
|
|
|
5355
5403
|
t.taskPromoted&&k.info("Auto-promoted task to in_progress",{taskId:T,requestId:A,previousStatus:D.status,newStatus:t.newTaskStatus}),Date.now(),O=Date.now()
|
|
5356
5404
|
const n=await u.ensureCorrectWorkspaceContext({taskPromoted:t.taskPromoted,requestId:A,context:r,operation:"replace_in_files",logger:k,metrics:c,metricsPrefix:"replace_in_files"})
|
|
5357
5405
|
if(!n.success)throw Error(n.error)
|
|
5358
|
-
Date.now(),N=!0}if(R.length>0&&A)try{await(0,
|
|
5406
|
+
Date.now(),N=!0}if(R.length>0&&A)try{await(0,m.validateRequestStatusForDocumentOperation)(A,i,k,c,"replace_in_files-documents")}catch(e){if(e instanceof p.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
|
|
5359
5407
|
throw e}O=Date.now()
|
|
5360
5408
|
const z=new Map
|
|
5361
5409
|
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:x,s=[]
|
|
@@ -5364,7 +5412,7 @@ s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,t.fullP
|
|
|
5364
5412
|
k.info("\u{1f50d} Checking for external edits",{path:t.normalizedPath,affectedLines:o.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),matchCount:s.length})
|
|
5365
5413
|
const i=await(0,w.detectExternalEdits)(r.git,o,k)
|
|
5366
5414
|
k.info("\u{1f50d} External edit detection result",{path:t.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(z.set(e.path,{message:i.message,debugInfo:i.debugInfo}),k.warn("\u26a0\ufe0f External edits detected before auto-commit",{path:t.normalizedPath,conflictingLines:i.conflictingLines})):(i.debugInfo&&z.set(e.path,{message:"",debugInfo:i.debugInfo}),k.info("\u2705 No external edit conflicts detected",{path:t.normalizedPath}))}else k.info("\u2139\ufe0f No matches found for external edit detection",{path:t.normalizedPath}),z.set(e.path,{message:"",debugInfo:{detectionRan:!1,reason:"No matches found - patterns not found in file",affectedRegion:"none",uncommittedChanges:"not checked",overlapDetected:!1}})}catch(t){k.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,I.getErrorMessage)(t)})}if(Date.now(),O=Date.now(),F&&r.git)try{k.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
|
|
5367
|
-
const e=await(0,
|
|
5415
|
+
const e=await(0,g.commitUserChangesBeforeToolOperation)(r.git,"replace_in_files",{requestId:A,taskId:T,workspaceManager:r.workspaceManager},k,c)
|
|
5368
5416
|
e.userChangesCommitted&&(k.debug("[REPLACE-IN-FILES] User changes committed",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),k.info("User changes committed before batch operation",{taskId:T,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){k.warn("Pre-tool user changes commit failed",{taskId:T,error:e instanceof Error?e.message:e+""})}Date.now(),O=Date.now(),_=u.FileOperationPhase.RECORD_CREATION,c.incrementCounter("replace_in_files_phase",1,{phase:_})
|
|
5369
5417
|
const{toolRecordId:L}=await u.createFileOperationRecords(T,A,r.projectId,"replace-in-files",$,{operationCount:P.length,totalReplacements:P.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:x,userComment:j},o,s,k,c,"replace_in_files",b)
|
|
5370
5418
|
C=L,Date.now(),O=Date.now(),_=u.FileOperationPhase.STRING_REPLACEMENT,c.incrementCounter("replace_in_files_phase",1,{phase:_})
|
|
@@ -5373,8 +5421,8 @@ for(const e of P){const t=e.path?z.get(e.path):void 0,o=await n(e,x,r,0,0,t?.mes
|
|
|
5373
5421
|
H.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&B.push(o.path)}Date.now(),O=Date.now()
|
|
5374
5422
|
const U=P.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),W=await u.handleMultiFileGitCommit(T,U,H,B.length,{operationType:"Replace in files",toolRecordId:L||C||"unknown",successField:"successfulReplacements",logger:k,metrics:c,metricsPrefix:"replace_in_files"},r),G=W.commitHash
|
|
5375
5423
|
Date.now(),Date.now()
|
|
5376
|
-
const V=H.filter((e=>e.success)).length,
|
|
5377
|
-
await s.updateToolRecord(C,{metadata:{path:$,status:0===
|
|
5424
|
+
const V=H.filter((e=>e.success)).length,Q=H.length-V,K=H.reduce(((e,t)=>e+t.successfulReplacements),0),J=H.reduce(((e,t)=>e+t.failedReplacements),0),Y=H.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,replacements:e.replacements.map((e=>({old_str:e.old,new_str:e.new,success:e.success,error:e.error,matchesFound:e.matchesFound,matchType:e.matchType,lines:e.lines})))}))),Z=H.filter((e=>e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements}))),X=H.filter((e=>!e.success)).map((e=>({path:e.path,documentId:e.documentId,filename:e.filename,error:e.error,successfulReplacements:e.successfulReplacements,failedReplacements:e.failedReplacements})))
|
|
5425
|
+
await s.updateToolRecord(C,{metadata:{path:$,status:0===Q?"completed":"partial",operationCount:P.length,operations:Y,successfulFiles:Z,failedFiles:X,successfulReplacements:K,failedReplacements:J,processingTime:Date.now()-v,userComment:j,...W.success&&W.commitHash&&{commitHash:W.commitHash,previousCommitHash:W.previousCommitHash||void 0}}})
|
|
5378
5426
|
const ee=await async function(e,t,r,n,o){const s=e.filter((e=>e.success)).length,i=e.length-s,a=e.filter((e=>!e.success&&!e.error&&e.successfulReplacements>0)).length
|
|
5379
5427
|
let c="## Replace In Files - Batch Results\n\n"
|
|
5380
5428
|
if(o.workspaceManager)try{const e=o.workspaceManager.getCurrentContext(o.currentSessionId)
|
|
@@ -5388,10 +5436,10 @@ if(s.length>0){c+="\n**Failed Replacement Details:**\n"
|
|
|
5388
5436
|
for(const e of s)c+=`- \u274c \`${e.old.substring(0,40)}${e.old.length>40?"...":""}\` \u2192 \`${e.new.substring(0,40)}${e.new.length>40?"...":""}\`: ${e.error}\n`,e.details&&e.details.length>0&&(c+=" **Candidates found:**\n",c+=e.details.slice(0,5).map((e=>` - Line ${e.line}: \`${e.actually_matched.substring(0,40)}${e.actually_matched.length>40?"...":""}\` (${e.match_type})`)).join("\n")+"\n",e.details.length>5&&(c+=` ... and ${e.details.length-5} more matches\n`)),e.similarMatches&&e.similarMatches.length>0&&(c+=" **Did you mean? (Similar matches found):**\n",c+=e.similarMatches.map((e=>` - Line ${e.line}: \`${e.text.substring(0,60)}${e.text.length>60?"...":""}\` (${e.reason}, similarity: ${(100*e.similarity).toFixed(0)}%)`)).join("\n")+"\n")}c+="\n"}const l=e.filter((e=>"document"===e.type&&(e.success||e.successfulReplacements>0)))
|
|
5389
5437
|
l.length>0&&(c+=`\n**Document Changes:** ${l.length} modified document(s) synced back to tracking system.\n`)
|
|
5390
5438
|
const d=o.workspaceManager?.consumeLargeFileWarning(o.currentSessionId)
|
|
5391
|
-
return d&&(c+=d),c}(H,G,J,
|
|
5392
|
-
return{content:[{type:"text",text:ee}],isError:0===
|
|
5439
|
+
return d&&(c+=d),c}(H,G,K,J,r)
|
|
5440
|
+
return{content:[{type:"text",text:ee}],isError:0===K,...(0,d.alchemyMeta)({kind:"replace-in-files",toolRecordId:C,failed:J>0})}}catch(e){const t=Date.now()-v
|
|
5393
5441
|
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,I.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,I.getErrorMessage)(e)}],isError:!0}}},c(t(857))
|
|
5394
|
-
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),
|
|
5442
|
+
const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(2272)),u=a(t(5967)),h=t(3626),p=t(9860),m=t(5003),g=t(7478),f=t(9949),y=t(9947),w=t(1318),I=t(8824)},9470(e,exports){"use strict"
|
|
5395
5443
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
|
|
5396
5444
|
const t=e.trim()
|
|
5397
5445
|
if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
|
|
@@ -5462,11 +5510,11 @@ if(!u)throw new r.ValidationError("Project ID is required for listing tasks with
|
|
|
5462
5510
|
a.incrementCounter("list_tasks_attempts",1,{hasRequestId:!!i,hasFilters:Object.keys(d).length>0}),s.setProjectId(u)
|
|
5463
5511
|
const h=s.getTaskClient(),p=d
|
|
5464
5512
|
i&&(p.requestId=i),c.info("Listing tasks with filters",{projectId:u,taskFilters:p})
|
|
5465
|
-
const
|
|
5466
|
-
c.info("Raw tasks response data",{responseData:JSON.stringify(
|
|
5467
|
-
let
|
|
5468
|
-
|
|
5469
|
-
const f=
|
|
5513
|
+
const m=await h.listTasks(p)
|
|
5514
|
+
c.info("Raw tasks response data",{responseData:JSON.stringify(m)}),c.info("Tasks response structure",{type:typeof m,isArray:Array.isArray(m),hasData:null!=m,properties:m?Object.keys(m):[],dataPreview:m?JSON.stringify(m).substring(0,200)+"...":"null"})
|
|
5515
|
+
let g=[]
|
|
5516
|
+
m&&"object"==typeof m?"success"in m&&"data"in m?Array.isArray(m.data)?(g=m.data,c.info("Extracted tasks from success/data wrapper",{count:g.length})):m.data&&"object"==typeof m.data&&(g=[m.data],c.info("Extracted single task from success/data wrapper")):"data"in m?Array.isArray(m.data)?(g=m.data,c.info("Extracted tasks from data wrapper",{count:g.length})):m.data&&"object"==typeof m.data&&(g=[m.data],c.info("Extracted single task from data wrapper")):Array.isArray(m)?(g=m,c.info("Tasks response is direct array",{count:g.length})):(g=[m],c.info("Tasks response is single object")):(c.warn("Unexpected response format, using empty array",{responseType:typeof m}),g=[])
|
|
5517
|
+
const f=g
|
|
5470
5518
|
if(c.info(`Retrieved ${f.length} tasks`,{count:f.length,requestId:i,projectId:u}),0===f.length){let e=""
|
|
5471
5519
|
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
|
|
5472
5520
|
return`**[${(0,o.formatTaskRefForAgent)(i?(0,o.formatTaskRef)(i,r):e.localId||e.id)}]** ${e.title}\nStatus: ${e.status}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}`})).join("\n\n")
|