alchemylab 1.4.7 → 1.4.8

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.
@@ -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),g=t(3444),m=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,g.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,g.isDebugToolsEnabled)()||x&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,g.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&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 m.ProjectContext(e,t),this.tokenManager=new f.TokenManager(t,e,{remoteServerUrl:n}),this.configManager=new S.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new p.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{listChanged:!0}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
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 g=t.projectId
118
- if(!g)throw new i.ValidationError("Project ID is required for searching requests")
119
- u.info("Searching requests",{query:a,searchIn:l,filters:p,projectId:g})
120
- const m={limit:p.limit||100,offset:p.offset||0,sortBy:"updated_at",sortDirection:"desc"}
121
- p.status&&(m.status=p.status),p.type&&(m.type=p.type),p.dateFrom&&(m.dateFrom=p.dateFrom),p.dateTo&&(m.dateTo=p.dateTo),c.setProjectId(g)
122
- const f=c.getRequestClient(),y=await f.listRequests(m)
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,p){const g=d.child({tool:"plan_write"})
169
- try{const a=e,{operation:d,planId:m}=a
170
- switch(g.info("Processing plan_write",{operation:d}),d){case"create":{const e=await(0,s.handleCreatePlan)({name:a.name,content:a.content??"",kind:a.kind||"plan",criteria:a.criteria,tickIntervalSeconds:a.tickIntervalSeconds,maxInFlight:a.maxInFlight,maxPerDay:a.maxPerDay},t,l,g,u,h,p)
171
- u.incrementCounter("plan_write_total",1,{operation:"create",success:!e.isError})
172
- const r=a.kind||"plan"
173
- return(0,c.withAlchemyKind)(e,i.KIND_META[r].alchemyKind)}case"update":{const e=await(0,r.handleUpdatePlan)({planId:m,content:a.content,name:a.name,metadata:{criteria:a.criteria,tickIntervalSeconds:a.tickIntervalSeconds,maxInFlight:a.maxInFlight,maxPerDay:a.maxPerDay,minIterations:a.minIterations,status:a.status}},t,l,g,u)
174
- return u.incrementCounter("plan_write_total",1,{operation:"update",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-update")}case"append":{const e=await(0,n.handleAppendPlan)({planId:m,content:a.content,name:a.name},l,g,u)
175
- return u.incrementCounter("plan_write_total",1,{operation:"append",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-append")}case"replace":{const e=await(0,o.handleReplacePlan)({planId:m,old:a.old,new:a.new,name:a.name},l,g,u)
176
- return u.incrementCounter("plan_write_total",1,{operation:"replace",success:!e.isError}),(0,c.withAlchemyKind)(e,"plan-replace")}case"create-snapshot":{const{versionLabel:e,changeSummary:t}=a,r=l.getDocumentClient(),n=await r.createVersionSnapshot(m,e,t)
177
- 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=l.getDocumentClient(),n=await r.getDocument(m)
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=l.getProjectClient()
184
- await o.updateProject(e,{activePlanId:m}),u.incrementCounter("plan_write_total",1,{operation:"set-active",success:!0})
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,c.withAlchemyKind)({content:[{type:"text",text:`\u2705 **Active Plan Updated**\n\n**Plan:** ${s}\n**Filename:** ${n.filename}\n**Project:** ${e}\n\nThis plan is now the active project plan.`}]},"plan-set-active")}default:throw Error("Unknown plan_write operation: "+d)}}catch(e){return g.error("plan_write failed",{error:e instanceof Error?e.stack:e+""}),u.incrementCounter("plan_write_errors",1),{content:[{type:"text",text:"\u274c **Plan Write Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
187
- const r=t(7609),n=t(4419),o=t(2352),s=t(6656),i=t(3416),a=t(8824),c=t(2272)},441(e,exports){"use strict"
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)}}]},700(e,exports,t){"use strict"
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:g}=a
255
- let m
256
- switch(p.info("Processing query_history request",{queryType:g}),g){case"file-history":p.info("Routing to file-history handler",{path:a.fileHistory.path}),m=await(0,r.handleFileHistory)({path:a.fileHistory.path,limit:a.fileHistory.limit,showDiff:a.fileHistory.showDiff,showTraceability:a.fileHistory.showTraceability,branch:a.fileHistory.branch,since:a.fileHistory.since},c,l,p,u)
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}),m=await(0,n.handleRequestFileHistory)({requestId:a.requestHistory.requestId,showDiff:a.requestHistory.showDiff,detailLevel:a.requestHistory.detailLevel,taskId:a.requestHistory.taskId,fileFilter:a.requestHistory.fileFilter},c,l,p,u)
259
+ 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}}}m=await(0,o.handleFileRecover)({taskId:e.recover?.taskId||await(async()=>{const{resolveActiveTaskId:e}=await Promise.resolve().then(t.bind(t,3451))
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}),m=await(0,i.handleFileBlame)({path:a.blame.path,lines:a.blame.lines,branch:a.blame.branch},c,l,p,u)
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: "+g)}return p.info("query_history request completed",{queryType:g,success:!m.isError}),u.incrementCounter("query_history_total",1,{success:!m.isError,queryType:g}),(0,s.withAlchemyKind)(m,"query-history")}catch(e){return p.error("query_history request failed",{error:e instanceof Error?e.stack:e+""}),u.incrementCounter("query_history_errors",1),{content:[{type:"text",text:"\u274c **Query History Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
271
+ 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,m.handleWriteFile)({taskId:a,path:e.relativePath,content:i,format:c},r.getContext(),O,$,N,A,n,o)
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,g.handleReplaceStrings)({taskId:c,operations:[{path:e.relativePath,replacements:i,mode:a}],comment:"String replacement via API"},r.getContext(),$,N,A,n,o)
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),g=t(3306),m=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
+ 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 g=0,m=0,f=0
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:g,fileMatchesCount:m,subdirCount:f,subdirStats:y}
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){g++,t.hasMatches&&m++
496
- for(const e of t.matches){if(o.length>=v)return{filesCount:g,fileMatchesCount:m,subdirCount:f,subdirStats:y}
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
- g+=l.filesCount,m+=l.fileMatchesCount,e.filesProcessed=l.filesCount,e.filesMatched=l.fileMatchesCount,e.subdirectories=l.subdirCount,y.push(e),l.subdirStats&&l.subdirStats.length>0&&y.push(...l.subdirStats)}catch(t){const r=`Error processing subdirectory ${n}: ${(0,b.getErrorMessage)(t)}`
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:g,fileMatchesCount:m,subdirCount:f,subdirStats:y}}async function n(e,t,r,n,o,s,i,a=0){const c=[]
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:g.default.hostname(),username:g.default.userInfo().username,workingDirectory:process.cwd(),contextBasePath:t?.basePath||"unknown"},startTime:u,endTime:0,phases:{initializationTime:0,searchTime:0,directoryListingTime:0},totalFiles:0,totalMatches:0,directoryStats:[],errors:[]}
537
- try{const{needle:n,directory:g,options:C={}}=e
538
- if(!n||""===n.trim())return l.info("Empty needle detected, switching to list-all mode"),await(0,I.handleListDirectory)({path:g||".",levels:C.levels||1,sortBy:C.sortBy||"name"},t,a,c)
539
- if("string"!=typeof n)throw v.errors.push("Search term (needle) must be a string"),(0,m.createValidationError)("Search term (needle) must be a string")
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=g||".",g){const{normalizedPath:e,fullPath:r}=f.validateAndNormalizePath(g,t)
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,m.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
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,m.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
+ 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,g=[]
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 m={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
573
- try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,g,a,o,s,0,m,l,u)
574
- return m.filesProcessed=n,m.filesMatched=c,m.subdirectories=d,i.directoryStats.push(m),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:g.length,directories:d+1}),{matches:g,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,b.getErrorMessage)(t)
575
- return m.errors.push(r),i.directoryStats.push(m),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:g,totalFiles:m.filesProcessed}}}(_,R,{maxResults:S,fileExtension:M,searchIn:x,isFile:E,contextLines:j},M,l,v)
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})`,g&&(N+=" in "+g),P&&(N+=" with extension "+P),N+=`${z}. Showing first ${D.length}:\n\n`):(N=`Found ${D.length} results for "${n}" (searching ${L})`,g&&(N+=" in "+g),P&&(N+=" with extension "+P),N+=z+":\n\n"),D.length>0)if(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
+ 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)),g=u(t(857)),m=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
+ 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),g=t.lineRanges.map((e=>`${e.start}-${e.end}`)).join(", "),m=d.map((e=>`${e.start}-${e.end}`)).join(", ")||"none",f=u?u.substring(0,300):"no diff"
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 ${g} were last modified by external commits (not alchemy).`,"","Commit details: "+e,"\nThese changes may have been made manually or by another tool.\nReview recent commits before proceeding."].join("\n")
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:g,uncommittedChanges:"none",lastCommit:r[0].commit.message,wasLastCommitAlchemy:!1,diffPreview:e,overlapDetected:!0}}}return{hasExternalEdits:!1,conflictingLines:[],debugInfo:{detectionRan:!0,affectedRegion:g,uncommittedChanges:"none",lastCommit:h,wasLastCommitAlchemy:p,diffPreview:"no uncommitted changes, last commits from alchemy",overlapDetected:!1}}}const y={path:t.path,lineRanges:d,totalLines:d.reduce(((e,t)=>e+(t.end-t.start+1)),0),operationType:"modification"},w=(0,a.getOverlappingLines)(t,y)
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:g,uncommittedChanges:m,lastCommit:h,wasLastCommitAlchemy:p,diffPreview:f,overlapDetected:!1}}:{hasExternalEdits:!0,conflictingLines:w,message:["\u26a0\ufe0f Warning: File has uncommitted changes in lines you're about to modify.\n","Affected lines: "+g,"Conflicting lines: "+s(w),"",p?"Last commit was by alchemy, but file has been edited since.":"Last commit was NOT from alchemy - these may be manual edits.","\nReview the changes before proceeding."].join("\n"),details:{totalExternalChanges:y.totalLines,overlappingChanges:w.length,changedLineRanges:d},debugInfo:{detectionRan:!0,affectedRegion:g,uncommittedChanges:m,lastCommit:h,wasLastCommitAlchemy:p,diffPreview:f,overlapDetected:!0}}}catch(e){return i.error("Failed to detect external edits",{path:t.path,error:(0,l.getErrorMessage)(e)}),{hasExternalEdits:!1,conflictingLines:[],message:"Unable to check for external edits (Git error). Proceeding with caution."}}},exports.hasUncommittedChanges=async function(e,t){try{return(await e.status([t])).files.some((e=>e.path===t))}catch(e){return!1}}
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,g,b){const k=i.child({component:"tools"})
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=!!g,_=async()=>{if(!C)return!0
706
- try{return await g.hasValidToken()}catch(e){return k.error("Error checking authentication status",{error:(0,d.getErrorMessage)(e)}),!1}},E=async()=>{const e=(0,l.areTestsRequiredForCompletion)(),t=await _()
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,m.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
+ 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,m.logSessionIdentity)(n,"_meta-session-switch",{prevSessionId:r.sessionId,prevAgentType:r.agentType,newSessionId:e}),h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r.serverUrl}),o?.workspaceManager?.resetCurrentContext?.(e))
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,m.logSessionIdentity)(n,"_meta",{sessionId:e,messageId:t})}else if(g=n,E=S,v||(v=!0,k.warn("No _meta.sessionId on tool call \u2014 caller not on alchemylab-opencode fork.",{tool:g,metaKeys:E?Object.keys(E):null})),!1!==P?.requiresSession)throw(0,p.createMcpProtocolError)(`_meta.sessionId required for tool '${n}'`,{tool:n})
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 g,E})),k.info("Tools registration complete")}
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 g=t(7280)
739
- Object.defineProperty(exports,"logSessionIdentity",{enumerable:!0,get(){return g.logSessionIdentity}})
740
- const m=t(7280)
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 g=t.projectId
747
- if(!g){const e="Project ID is required. Make sure you are in a project context."
748
- return i.warn("No project context"),{content:[{type:"text",text:"\u274c "+e}],isError:!0}}n.setProjectId(g)
749
- const m=n.getDocumentClient()
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 m.listDocuments(e)
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}}}},1725(e,exports,t){"use strict"
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 g=await(0,y.getServerUrl)(t,s)
1067
- r(t,"serverUrl resolved",{serverUrl:g})
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 m.ValidationError("Working directory not available in context")
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}),!g)throw new m.ValidationError("Could not determine OpenCode server URL")
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=`${g.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)})
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`,g=await fetch(p,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent:c,prompt:l,requestId:d,parentSessionId:h,title:e.title,specialization:e.specialization,specializationHeadline:e.specializationHeadline,allowParallel:u,callerAgentType:w.sessionIdentity.getIdentity()?.agentType}),signal:AbortSignal.timeout(15e3)})
1090
- if(!g.ok){const e=await g.text().catch((()=>"Unknown error"))
1091
- throw Error(`Spawn session endpoint failed: ${g.status} ${e}`)}const m=await g.json()
1092
- if(!m.success||!m.data)throw Error(m.error||"Spawn session returned unsuccessful")
1093
- const{sessionId:y,model:I,serverUrl:b,initialBranch:v}=m.data
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 m.ValidationError("Could not determine OpenCode server URL")
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 m.ValidationError(`Cannot continue session ${e}: unable to determine agent type. The session's agent type could not be looked up from the action server.`)
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}:{}}}},g=await fetch(h,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:u,metadata:p}],...d?{agent:d}:{},...r?{model:r}:{}}),signal:AbortSignal.timeout(1e4)})
1122
- if(!g.ok){const e=await g.text().catch((()=>"Unknown error"))
1123
- throw Error(`Failed to send message: ${g.status} ${e}`)}return s.info("Message sent to subagent session",{sessionId:e,agent:d,instructionCode:a}),{content:[{type:"text",text:a?`Message sent to session ${e} (${a}).\nThe subagent will process it in the background.`:`Message sent to session ${e}.\nThe subagent will process it in the background.`}],...a?{_meta:{alchemy:{kind:"continue-subagent",instructionCode:a}},instructionCode:a}:{}}}catch(e){throw Error("Failed to continue session: "+(0,b.getErrorMessage)(e))}}function a(e){const t=Math.floor(e/1e3)
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 m.ValidationError("Could not determine OpenCode server URL")
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`,g=await fetch(p)
1142
- let m={input:0,output:0,reasoning:0},f="",y=d(null,h.time.updated)
1143
- if(g.ok){const e=await g.json()
1144
- for(const t of e)"assistant"===t.info.role&&t.info.tokens&&(m.input+=t.info.tokens.input||0,m.output+=t.info.tokens.output||0,m.reasoning+=t.info.tokens.reasoning||0)
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=m.input+m.output+m.reasoning
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: ${m.input.toLocaleString()}, out: ${m.output.toLocaleString()}${m.reasoning>0?", reasoning: "+m.reasoning.toLocaleString():""})${f}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,b.getErrorMessage)(e))}}async function p(e,t,r){const n=await(0,y.getServerUrl)(t,r)
1162
- if(!n)throw new m.ValidationError("Could not determine OpenCode server URL")
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 g(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:i,minTokens:l,maxTokens:u,maxAgeHours:h}=n,p=await(0,y.getServerUrl)(e,t)
1167
- if(!p)throw new m.ValidationError("Could not determine OpenCode server URL")
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 g=await t.json()
1172
- if(0===g.length)return{content:[{type:"text",text:"No sessions found."}]}
1173
- const m=g
1174
- n.parentSessionId&&(g=g.filter((e=>(e.parentId||e.parentID)===n.parentSessionId))),g.sort(((e,t)=>t.time.created-e.time.created))
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=g
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 m){const r=t.parentId||t.parentID
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],g="fulfilled"===p.status?p.value:[]
1190
- for(const e of g)"assistant"===e.info.role&&e.info.tokens&&(o+=(e.info.tokens.input||0)+(e.info.tokens.output||0)+(e.info.tokens.reasoning||0))
1191
- if(g.length>0){const e=c(g)
1192
- h=d(e.lastActivityTime,t.time.updated),i=e.current||null,a=e.recent}const m=h.status
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:m,age:r,totalTokens:o,requestsInfo:y,allRequestIds:k,statusDetail:h.detail,specialization:f?.specialization??null,currentAction:i,recentActions:a})}if(0===S.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
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=g,exports.handleSubagentOperations=async function(e,t,r,n,o,a){const c=r.child({tool:"subagent_operations"}),l=n.startTimer("tool_execution_time")
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 m.ValidationError("Could not determine OpenCode server URL")
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 g(t,c,o,n)
1260
+ f=await m(t,c,o,n)
1240
1261
  break
1241
- default:throw new m.ValidationError("Unknown operation: "+u)}l({success:!0}),n.incrementCounter(`subagent_operations_${u}_success`,1)
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 m=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"
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,g
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 m="workspace-manager"
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}),g=await t.workspaceManager.completeRequest(h,y,{skipConflictDetection:!0}),m="retry-theirs"):(g=await t.workspaceManager.completeRequest(h,y),m=g.autoMergeInfo?.strategy||"workspace-manager"),d.info("Merge completed",{requestId:h,mergeCommitHash:g.mergeCommitHash,mergeMethod:m})}catch(r){if(r.conflictInfo){const n=r.conflictInfo,s=n.workingDirectory||t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||process.cwd(),c=(0,o.createConflictResolutionManager)(d,a,s,t.git),l=await c.handleConflicts(n)
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:g.mergeCommitHash,mergeBaseSha:l,mergedFiles:g.mergedFiles,cleanedUp:g.cleanedUp,method:m}})}catch(e){const t=(0,i.getErrorMessage)(e)
1337
- return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:g.mergeCommitHash,error:t}),u({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${g.mergeCommitHash.substring(0,8)}) but failed to update server: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:`Request ${h} merged successfully.\nCommit: ${g.mergeCommitHash.substring(0,8)}`}]}}catch(e){const r=(0,i.getErrorMessage)(e)
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 g=null
1385
- const m=[]
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(m.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
1388
- if(m.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
1389
- m.push(`runs: ${Array.isArray(r)?r.length:0}, withWorktree: ${s?.id||"NONE"}, path: ${s?.worktreePath||s?.worktree_path||"NONE"}`),s&&(g=s.worktreePath||s.worktree_path,u.info("Using test worktree from request test run",{worktreePath:g,reqId:t}))}}}catch(e){u.warn("Failed to resolve test worktree",{error:(0,r.getErrorMessage)(e)})}if(!g)return d({success:!1,error:"no_worktree"}),{content:[{type:"text",text:`No test worktree found.\n\nDiagnostics:\n${m.length>0?m.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}
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(g,I,"command-logs")
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:g})
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: ${g}\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:g,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)
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,g=await i.proxyGet(`/api/projects/${s.projectId}/requests/${p}/test-runs`),m=g?.data||g||[],f=Array.isArray(m)?m:[],y=f.find((e=>"pending"===e.status||"running"===e.status))||f[0]
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:g}=await Promise.resolve().then(t.bind(t,9032)),m=await g(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.")
1423
- if(!m.ok)return d({success:!1,error:"no_request"}),m.errorResult
1424
- const f=m.requestId,y=e.name?[e.name]:void 0
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 g
1498
- try{g=function(e){for(let t=e.length-1;t>=0;t--){const r=e[t]
1499
- if("assistant"===r.info?.role&&r.info.agent)return r.info.agent}}(await r(u,p)),g||t.warn("commit_to_viewed_session: no agent resolvable for viewed session; omitting agent",{viewedId:p})}catch(e){t.warn("commit_to_viewed_session: could not fetch viewed messages; omitting agent",{viewedId:p,error:(0,n.getErrorMessage)(e)})}const m={parts:[{type:"text",text:c,metadata:(0,s.partMeta)("via-herald")}]}
1500
- g&&(m.agent=g),t.info("commit_to_viewed_session:posting",{callId:i,viewedId:p,heraldId:d,agent:g})
1501
- try{const e=await fetch(`${u}/session/${p}/prompt_async`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(m),signal:AbortSignal.timeout(1e4)})
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:g,messageLength:c.length,preview:c.slice(0,120),durationMs:Date.now()-a}),{content:[{type:"text",text:"Committed."}]}}
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,m){const f=i.child({tool:"move_files"}),y=Date.now()
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,g,k.metricsPrefix)
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,g.incrementCounter("move_files_phase",1,{phase:b})
1592
- const T=await l.validateTaskId(E,q[0].source,n,f,g,k.metricsPrefix),P=T?.requestId,x=await l.validateWorkItemStates(E,q[0].source,n,s,r,f,g,k.metricsPrefix),j=await l.autoPromoteTaskStatus(E,T.status,P,x.request?.status,q[0].source,n,s,f,g,k.metricsPrefix)
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:g,metricsPrefix:k.metricsPrefix})
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,g)
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,g.incrementCounter("move_files_phase",1,{phase:b})
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,g,k.metricsPrefix,m)
1601
- w=$,I=$,b=k.fileOperationPhase,g.incrementCounter("move_files_phase",1,{phase:b})
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
- g.recordValue("move_files_time",F),g.incrementCounter("move_files_operations_total",u.length),g.incrementCounter("move_files_operations_success",A),g.incrementCounter("move_files_operations_failed",u.length-A),A===u.length?g.incrementCounter("move_files_success",1):A>0?g.incrementCounter("move_files_partial_success",1):g.incrementCounter("move_files_total_failure",1)
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,g.incrementCounter("move_files_phase",1,{phase:b})
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,g,k.metricsPrefix)}b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,g.incrementCounter("move_files_phase",1,{phase:b})
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,g,k.metricsPrefix)
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(g.recordValue("move_files_time",s),g.incrementCounter("move_files_errors",1),f.error("Error in move-files operation:",{error:(0,p.getErrorMessage)(t),time:s}),(w||I)&&e.taskId){b=l.FileOperationPhase.RECORD_UPDATE_FAILURE
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,g,k.metricsPrefix)}catch(t){f.error("Failed to update record with failure status",{taskId:e.taskId,recordId:w,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(t,b,f,g,e,k)}}
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),g=t(4805),m=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(213),D=t(7250),A=t(2425),F=t(1540),N=t(5767),z=t(4973),L=t(509),H=t(7613),B=t(8456),U=t(3322),W=t(5247),G=t(8849),V=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(p.def),(0,r.registerTool)(g.def),(0,r.registerTool)(m.def),(0,r.registerTool)(f.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(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.registerTools)(U.metaDefs),(0,r.registerTools)(W.testingDefs),(0,r.registerTools)(G.checkingDefs),(0,r.registerTools)(V.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
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),g=await y.default.stat(h),m=d.isFile()?w.default.extname(d.name).toLowerCase():""
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,g.size,m))
1661
- const b={name:d.name,isDirectory:d.isDirectory(),depth:n,size:g.size,modified:g.mtime,extension:m,lineCount:f}
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]}),g=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),m=this&&this.__importStar||(h=function(e){return h=Object.getOwnPropertyNames||function(e){var t=[]
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 g(t,e),t}),f=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
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 g=e,{path:m,levels:f=1,sortBy:b="name"}=g
1697
- i.info("Listing directory: "+m)
1698
- const{normalizedPath:v,fullPath:C}=I.validateAndNormalizePath(m,t)
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: "+m}],isError:!0}
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: "+m}],isError:!0}:e instanceof Error&&"EACCES"===e.code?{content:[{type:"text",text:"Directory not accessible: "+m}],isError:!0}:{content:[{type:"text",text:"Cannot access directory: "+m}],isError:!0}}let _,E
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=m(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"
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 g=h.startTimer("tool_handler_duration")
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 m=o.summary;(0,c.isTaskRef)(u)&&(u=await(0,c.resolveTaskRef)(u,d,p))
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}: ${m}`)).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
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:m,lastCommit:b,completedAt:(new Date).toISOString()},note:`Completed task: ${m.substring(0,100)}${m.length>100?"...":""}`})).id})}catch(e){p.error("Failed to create tool record for task completion, but continuing",{error:e instanceof Error?e.stack:e+"",taskId:u,requestId:w.requestId})}try{const e=w.metadata||{},t=(new Date).toISOString(),r={status:"completed",metadata:{...e,lastCommit:b,completionSummary:m,completionRecordId:k?.id,completedAt:t}},o=await y.updateTask(u,r)
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 g({success:!0}),{content:[{type:"text",text:d}],...(0,n.alchemyMeta)({kind:"complete-task",toolRecordId:k?.id})}}catch(e){throw p.error("Failed to complete task",{error:e instanceof Error?e.stack:e+"",taskId:u}),Error("Failed to complete task: "+(0,a.getErrorMessage)(e))}}catch(t){if(p.error("Failed to complete task",{error:t instanceof Error?t.stack:t+"",args:e}),l.projectId)try{const n=d.getToolRecordClient()
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+""})}g({success:!1,error:t instanceof Error?t.name:"unknown"})
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:g=!1,logFilePath:m="./logs/app.log",console=!0}=t,f=[]
1868
- if(console&&f.push(new s.default.transports.Console({format:d,stderrLevels:["error","warn","info","debug"]})),g){!function(e){const t=i.default.dirname(e)
1869
- a.default.existsSync(t)||a.default.mkdirSync(t,{recursive:!0})}(m)
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:m,format:e?h:u}))}const y=s.default.createLogger({level:o,defaultMeta:{service:p},transports:f})
1872
- return o===c.LogLevel.DEBUG&&g&&r()&&y.info("Enhanced logging initialized",{level:o,serviceName:p,logToFile:g,logFilePath:m,debugLogging:process.env.DEBUG_LOGGING}),{error(e,t){y.error(e,t)},warn(e,t){y.warn(e,t)},info(e,t){y.info(e,t)},debug(e,t){y.debug(e,t)},child(e){const r=y.child(e)
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 g=await Promise.all(h)
1931
- let m=""
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&&(m=`**Current Branch:** ${e.branchName}\n`)}catch(e){i.debug("Could not get branch context",{error:e})}const f=g.filter((e=>e.success)).length,y=g.filter((e=>!e.success)).length,w=g.length
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
- m&&(I+=m),I+=`**Total Requests:** ${w} - **Successful:** ${f} - **Failed:** ${y}\n\n`
1936
- for(let e=0;e<g.length;e++){const t=g[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,g=!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
- g=t.promoted,h=t.newStatus}return{taskPromoted:p,newTaskStatus:s,requestPromoted:g,newRequestStatus:h}}catch(r){const n=(0,s.getErrorMessage)(r)
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(),g=o.getToolRecordClient(),[m,f,y]=await Promise.all([h.getRequest(a),p.listTasks({requestId:a}),g.getToolRecordsByRequestId(a).catch((e=>(l.warn("Failed to fetch tool records",{error:e+""}),[])))]),w=(0,s.extractDataFromResponse)(m,{logger:l,operationName:"getRequest",throwOnNoData:!0}),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})))
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 g=u.child({tool:"tasks"}),{operation:m}=e
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(m){case"create":{const{title:t,description:r}=e
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){g.debug("Could not auto-start task",{taskId:u,error:(0,i.getErrorMessage)(e)})}const m=a.sequenceNumber??null
2086
- let y=m?`Created #${m}: ${t}`:`Created ${(0,l.formatTaskRefForAgent)(u)}: ${t}`
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){g.debug("Could not auto-start next task",{taskId:n.taskId,error:(0,i.getErrorMessage)(e)})}else h+="\nAll tasks completed."
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: "+m}],isError:!0}}}catch(e){return g.error("tasks operation failed",{operation:m,error:(0,i.getErrorMessage)(e)}),{content:[{type:"text",text:"Error: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
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,m.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)
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,g.ensureDocumentsNotLocked)(e,r.apiClient,y,c,"replace-strings-documents")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
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,m.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}
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,m.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))
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:K,overallSuccess:J,successfulFiles:Q,failedFiles:Y}=W
2217
- 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:V+" operations failed",totalOperations:L.length,successfulFiles:Q,failedFiles:Y,operations:N,totalSuccessfulReplacements:K,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:J?`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:K,overallSuccess:J,successfulFiles:Q,failedFiles:Y},U,F)
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:** ${K} 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]
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:** ${K} successful, ${H} failed\n\n`,Z+="**Detailed Results:**\n\n"
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:J,totalOperations:L.length,successfulOperations:G,failedOperations:V}),c.incrementCounter("replace_strings_total",1,{success:J}),{content:[{type:"text",text:Z}],isError:!J}}catch(t){const r=Date.now()-w
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,m.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return c.incrementCounter("replace_strings_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
2228
- const l=c(t(1943)),d=a(t(5967)),u=t(9860),h=t(5003),p=t(7478),g=t(9949),m=t(8824)},3322(e,exports,t){"use strict"
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 g=t(5187)
2265
- Object.defineProperty(exports,"CLISessionClient",{enumerable:!0,get(){return g.CLISessionClient}})
2266
- var m=t(6539)
2267
- Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return m.ClientFactory}})
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.KIND_META=exports.QUEST_STATUS_DRAFT=exports.QUEST_STATUS_CLOSED=exports.QUEST_STATUS_OPEN=exports.QUEST_DEFAULTS=exports.PLAN_KINDS=void 0,exports.PLAN_KINDS=["plan","quest"],exports.QUEST_DEFAULTS={tickIntervalSeconds:1800,maxInFlight:1,maxPerDay:24,minIterations:3},exports.QUEST_STATUS_OPEN="open",exports.QUEST_STATUS_CLOSED="closed",exports.QUEST_STATUS_DRAFT="draft",exports.KIND_META={plan:{docType:"Plan",filenamePrefix:"PLAN-",label:"plan",idLabel:"Plan ID",headingCreated:"Plan Created",errorVerb:"create plan",alchemyKind:"plan-create",canBeActivePlan:!0},quest:{docType:"Quest",filenamePrefix:"QUEST-",label:"quest",idLabel:"Quest ID",headingCreated:"Quest Created",errorVerb:"create quest",alchemyKind:"quest-create",canBeActivePlan:!1}}},3420(e,exports,t){"use strict"
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 g=e=>{if(!e)return"Unknown date"
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=g(h.createdAt),f=g(h.updatedAt),y=h.requestId||h.requestLocalId,w=h.sequenceNumber&&y?(0,s.formatTaskRef)(y,h.sequenceNumber):r,I=(0,s.formatTaskRefForAgent)(w)
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**: ${m}\n`,b+=`**Updated**: ${f}\n`,h.requestId&&(b+="**Parent Request**: "+h.requestId,b+=p?` (${p.title})\n`:"\n"),h.metadata){const e=h.metadata
2298
- b+="\n## Metadata\n\n",e.lastCommit&&(b+=`**Last Commit**: ${e.lastCommit}\n`),e.completedAt&&(b+=`**Completed At**: ${g(e.completedAt)}\n`),e.completionSummary&&(b+=`**Completion Summary**: ${e.completionSummary}\n`)
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),g=t(7888),m=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:_})
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,m.ALCHEMY_DIR_NAME)
2342
- E.info(`Checking ${m.ALCHEMY_DIR_NAME} directory`,{alchemyPath:c}),await r.ensureDirectoryExists(c)
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,g.addConnectionStatusInfo)(t.connectionManager))):E.warn("Unable to add connection status middleware - connection manager not available")
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 g=0,m=0
2396
- for(;;){if(m%100==0&&Date.now()-d>o){const r=Date.now()-d
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`)}m++
2398
- const r=e.indexOf(p,g)
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}),g=t,y=!0
2406
- break}}y||(g=r+1)}return c}(e,t,c,u),h.length>0)return h}catch(e){if(e instanceof Error&&e.message.includes("timed out"))throw e}return h=function(e,t,n=100,a){if(r(a))return[]
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,g=0
2412
- for(;;){if(g%100==0&&Date.now()-d>n){const r=Date.now()-d
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`)}g++
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),m=Math.min(r+h+a,e.length)
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;m>=t;t++){const n=e.substring(r,t),i=o(n)
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:g,fullPath:m}=d.validateAndNormalizePath(u,t)
2467
+ const{normalizedPath:m,fullPath:g}=d.validateAndNormalizePath(u,t)
2447
2468
  i=d.FileOperationPhase.FILE_WRITE
2448
- try{await c.default.access(m)}catch(e){throw Error("Path not accessible: "+u)}const f=await c.default.stat(m),y=f.isFile()?l.default.extname(m).slice(1):"",w={path:g,type:f.isDirectory()?"directory":"file",size:f.size,sizeFormatted:(p=f.size,d.formatFileSize(p)),created:r(f.birthtime),modified:r(f.mtime),accessed:r(f.atime),permissions:(h=f.mode,(511&h).toString(8)),isDirectory:f.isDirectory(),isFile:f.isFile(),isSymbolicLink:f.isSymbolicLink(),extension:y},I=["File Information for: "+g,"Type: "+w.type,`Size: ${w.sizeFormatted} (${w.size} bytes)`,"Created: "+w.created,"Modified: "+w.modified,"Accessed: "+w.accessed,"Permissions: "+w.permissions,"Is Directory: "+w.isDirectory,"Is File: "+w.isFile,"Is Symbolic Link: "+w.isSymbolicLink]
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: "+g,{type:w.type,size:w.size,time:b}),{content:[{type:"text",text:I.join("\n")}]}}catch(t){const r=Date.now()-s
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,m){const f=p.child({tool:"quick_edit"}),y=Date.now()
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,g)
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,m)
2472
- else if("replace"===t)C=await(0,s.handleReplaceInFiles)({taskId:P,..._,comment:E},u,I,k,w,p,g,m)
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,m)}if(C.isError){f.error("File operation failed, cleaning up request and task",{requestId:T,taskId:P})
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,g),f.info("Task completed successfully",{taskId:P})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:P,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
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,m)
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:m,documentId:S,content:q,format:T,append:P,comment:x}=n
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=!!m
2580
- I.info("Writing content to "+($?"document":"file"),{taskId:M,filePath:O?m:void 0,documentId:$?S:void 0,contentLength:"string"==typeof q?q.length:JSON.stringify(q).length,format:T,append:P,comment:x})
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?m:void 0
2583
- if($){if(r.apiClient)try{await(0,g.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}
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 K=await d.ensureCorrectWorkspaceContext({taskPromoted:V.taskPromoted,requestId:W,context:r,operation:"write_file",logger:I,metrics:y,metricsPrefix:E.metricsPrefix,requireRequestContext:O})
2594
- if(!K.success)throw Error(K.error)
2595
- if(K.switched&&I.info("Workspace context successfully established",{requestId:W,branchName:K.branchName,operation:"write_file"}),O&&H){const e=d.validateAndNormalizePath(H,r)
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:J}=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)
2600
- let Q
2601
- if(v=J,C=J,_=E.fileOperationPhase,y.incrementCounter("write_file_phase",1,{phase:_}),"json"===T)if("string"==typeof q)try{JSON.parse(q),Q=q}catch(e){throw new u.ValidationError("Content is not valid JSON")}else Q=JSON.stringify(q,null,2)
2602
- else Q="string"==typeof q?q:JSON.stringify(q,null,2)
2603
- let Y=Q
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")+Q}catch(e){I.warn("Failed to read existing content for append",{error:e})}const Z=a.default.dirname(N)
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,m.getErrorMessage)(t),phase:_,duration:r,userComment:e?.comment},note:"Write operation failed: "+(0,m.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,m.getErrorMessage)(t)}],isError:!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),g=t(9949),m=t(8824)},4139(e,exports){"use strict"
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)}}},4221(e,exports,t){"use strict"
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),g=p.toString("base64")
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:g,mimeType:h}]}}catch(e){return o.error("Failed to view asset",{error:(0,c.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to view asset:** "+(0,c.getErrorMessage)(e)}],isError:!0}}}
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,m,f){const y=p.startTimer("tool_execution_time"),w=e.operation||"run"
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=m?.sessionId,n=t?await d.sessionIdentity.getSessionRequestId(r,h,t):void 0
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}(m)
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:m?.sessionId,isActive:!1}),o=n?.data?.id||n?.id
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 g=[`## Submitted ${p.length} command${1===p.length?"":"s"} for approval${i.length?`, ${i.length} skipped`:""}`]
2731
- return p.length>0&&(g.push("","### Pending approval"),g.push(...p.map((e=>`- **${e}**`))),g.push("","The user will see one approval notification per command. Approved commands become runnable; denied ones are removed.")),i.length>0&&(g.push("",`### Skipped (${i.length})`),g.push(...i.map((e=>`- **${e.name}** \u2014 ${e.reason}`)))),g.push("",'Use `commands({ operation: "list" })` to see status.'),{content:[{type:"text",text:g.join("\n")}],...(0,c.alchemyMeta)({kind:"register-commands"})}}if("remove"===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}
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:m?.sessionId,logPath:T},f)
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(g)try{const e=await g.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()}})
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:g,sessionId:m}=c
2795
+ try{const c=e,{operation:m,sessionId:g}=c
2772
2796
  let f
2773
- switch(h.info("Processing planner_ops",{operation:g,sessionId:m}),g){case"request":{const e=await async function(e,t,r){if(!e)return"ask"
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)(m,t,h,d)
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: "+g)}p({success:!0}),l.incrementCounter(`planner_ops_${g}_success`,1)
2799
- const y=a[g]??"planner-request"
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"}),g=u.startTimer("tool_execution_time"),m=Date.now()
2828
- try{const g=e,{path:f,commitHash:y,createBackup:w}=g,{resolveActiveTaskId:I}=await Promise.resolve().then(t.bind(t,3451)),b=e.taskId||await I(r,n,s)||"untracked"
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,m){let f
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",m)
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()-g,...E.commitHash&&{commitHash:E.commitHash,previousCommitHash:E.previousCommitHash||void 0}},note:"File recovered successfully from "+r.substring(0,8)})}catch(e){h.warn("Failed to update tool record",{recordError:e})}const S=v?"recovered":"created from recovery"
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()-g}),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,m,h)}catch(e){const t=Date.now()-m
2845
- return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),g({tool:"file_recover",success:!1}),u.incrementCounter("file_recover_errors",1),{content:[{type:"text",text:"\u274c **Recovery Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
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,m,f){const y=g.child({tool:"request_operations"})
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,m,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,g,m,f),h.merge)
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,m,f),h.approve)}case"revert":{y.info("Routing to revert-request handler")
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,m),h.revert)}case"get-info":{y.info("Routing to get-request-information handler")
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,m),h["get-info"])}case"list":{y.info("Routing to list-requests handler")
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,m),h.list)}case"search":{y.info("Routing to search-requests handler")
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,m),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}
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+""}),m.incrementCounter("request_operations_errors",1),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
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:g,branch:m}=e
2987
- c.info("Processing blame request",{filePath:i,lines:g,branch:m})
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}(g),b=["blame","--porcelain"]
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}`),m&&b.push(m),b.push("--",w),c.debug("Executing git blame",{args:b})
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 g=(0,o.extractArrayFromResponse)(l,{logger:d,operationName:"listTasksForRequest",defaultValue:[]})
3196
- d.info(`Successfully extracted ${g.length} tasks using data extraction utility`)
3197
- const m={pending:0,in_progress:0,blocked:0,ready_for_review:0,completed:0,reverted:0,total:g.length}
3198
- g.forEach((e=>{const t=e.status
3199
- t in m&&m[t]++}))
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: ${m.completed}/${m.total} completed (${Math.round(m.completed/m.total*100)||0}%)\n- Acceptance Criteria: ${y.verified}/${y.total} verified (${Math.round(y.verified/y.total*100)||0}%)\n`
3206
- return k+=`\n## Task Status\n- Pending: ${m.pending}\n- In Progress: ${m.in_progress}\n- Blocked: ${m.blocked}\n- Ready for Review: ${m.ready_for_review}\n- Completed: ${m.completed}\n- Reverted: ${m.reverted}\n`,k+="\n## Tasks\n",0===g.length?k+="No tasks found for this request.\n":g.forEach((e=>{k+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`})),d.info(`Added task listing with ${g.length} tasks`),k+="\n## Acceptance Criteria\n",k+=(0,i.formatCriteriaWithHashes)(f)+"\n","ready_for_review"===p.status&&f.some((e=>"verified"!==e.status))&&(k+="\n> **Status: ready_for_review** \u2014 Use the merge operation to verify criteria and merge to main.\n"),w&&(k+=`\n## Test Coverage\n- Test Cases: ${w.totalTestCases||0}\n- Criteria Tested: ${w.criteriaTestedCount||0}/${y.total}\n`,w.criterionCoverage&&Array.isArray(w.criterionCoverage)&&(k+="\n### Detailed Test Coverage:\n",w.criterionCoverage.forEach((e=>{k+=`- Criterion ${e.criterionId}: ${e.coverage} coverage\n`})))),p.recentActivity&&Array.isArray(p.recentActivity)&&(k+="\n## Recent Activity\n",p.recentActivity.slice(0,5).forEach((e=>{const t=new Date(e.timestamp).toLocaleString()
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,g=d?.sessionId,m=await l.createAnnotation(h,{selectedText:e,prefixContext:r,suffixContext:n,lineHint:a,body:t,createdByAgent:p,createdBySessionId:g})
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:** ${m.id}\n**Document:** ${h}\n**Selected text:** "${e.substring(0,60)}"\n**Comment:** `+t}]},"create-annotation")}case"reply-to-annotation":{u.info("Replying to annotation")
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)},5674(e,exports,t){"use strict"
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,36 @@ 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"}),g=d.startTimer("tool_execution_time")
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 m
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
- m=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
3285
- return p.error("Server validation failed",{requestId:n,error:t}),g({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate completion: "+t}],isError:!0}}if(!m.canComplete){let e=`Cannot complete request ${n}: ${m.reason}\n`
3286
- return m.blockedByTasks&&m.blockedByTasks.length>0&&(e+="\n**Tasks that must be completed or canceled first:**\n",m.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (Status: ${t.status})\n`}))),m.lifoViolation&&(e+="\n**Requests that must be re-completed first (LIFO order):**\n",m.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (Status: ${t.status})\n`}))),g({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(m.testsSkipped&&(l||d&&d.length>0))try{const e=c.getToolRecordClient()
3287
- e&&await e.createToolRecord({projectId:t.projectId,requestId:n,type:"tests-skipped",metadata:{...l?{reason:l}:{},...d&&d.length>0?{skipTests:d}:{},completionMode:m.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()
3288
- let y="auto-merge"!==m.completionMode&&!m.testsSkipped
3289
- const w="manual-review"===m.reviewMode
3290
- let I,b=null
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()
3328
+ let y="auto-merge"!==g.completionMode&&!g.testsSkipped
3329
+ const w="manual-review"===g.reviewMode,I=y&&!1===g.hasActiveTestProcesses&&("test-by-default"===g.completionMode||"always-test"===g.completionMode)
3330
+ I&&(y=!1)
3331
+ let b,k=null
3291
3332
  if(y)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
3333
  if(i&&"passed"===i.status&&i.commitSha){let e=null
3293
3334
  if(r&&r.ok){const t=await r.json()
3294
- e=t?.data?.sha??null}e&&e===i.commitSha&&(y=!1,b=`latest test run ${i.id} passed against current branch HEAD ${e.slice(0,7)}`,I=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 k=y||w?"ready_for_review":"ready_for_merge"
3295
- try{await f.updateRequest(n,{status:k,completionSummary:o,...I?{skippedTestRunId:I}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
3296
- return g({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let v
3297
- try{v=await f.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
3298
- return g({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const C=v?.acceptanceCriteria||[]
3299
- if(g({success:!0}),y)return{content:[{type:"text",text:`Request ${n} moved to ready_for_review. Testing is active \u2014 a notification has been created for the user to choose testing mode. Do NOT call merge or any other tool. Your work is done. Stop here and wait.`}]}
3300
- if(w)return{content:[{type:"text",text:`Request ${n} submitted for human review.${m.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.`}]}
3301
- const _=b?`\n\n_Skipped re-running tests: ${b}._\n`:""
3302
- return 0===C.length?{content:[{type:"text",text:`Request ${n} is ready. ${_}No acceptance criteria defined \u2014 call merge directly.`}]}:{content:[{type:"text",text:`Request ${n} completion started (${k}).${_}\n\n## Next Step: Verify & Merge\n\n${(0,i.formatVerifyInstructions)(C)}\n\nUse the merge operation with your verification evidence to merge to main.`}]}}catch(r){let s="An unexpected error occurred",i=""
3335
+ e=t?.data?.sha??null}e&&e===i.commitSha&&(y=!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=y||w?"ready_for_review":"ready_for_merge"
3336
+ try{await f.updateRequest(n,{status:v,completionSummary:o,...b?{skippedTestRunId:b}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
3337
+ return m({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let C
3338
+ try{C=await f.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
3339
+ return m({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const _=C?.acceptanceCriteria||[]
3340
+ if(m({success:!0}),y){const e=g.completionMode
3341
+ let t
3342
+ return t="ask-me"===e?"A notification has been created asking the user to choose how to handle testing (auto-test, interactive-test, or skip).":"always-test"===e?"Tests are running automatically in the background (always-test 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.":"Tests are running automatically in the background (test-by-default 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.",{content:[{type:"text",text:`Request ${n} moved to ready_for_review. ${t} Do NOT call merge or any other tool. Your work is done. Stop here and wait.`}]}}if(w)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.`}]}
3343
+ const E=k?`\n\n_Skipped re-running tests: ${k}._\n`:"",S=I?`\n\n_No test processes are configured for this project; ${g.completionMode} mode is being treated as auto-merge._\n`:""
3344
+ 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
3345
  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
3346
  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
3347
  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 +3370,7 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
3328
3370
  var t={}
3329
3371
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
3330
3372
  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 m=o.child({tool:"delete_files"}),f=Date.now()
3373
+ 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
3374
  let y,w,I=c.FileOperationPhase.VALIDATION
3333
3375
  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
3376
  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 +3383,54 @@ x=E.map((e=>{if(e.path)return{type:"file",target:e.path}
3341
3383
  if(e.documentId)return{type:"document",target:e.documentId}
3342
3384
  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
3385
  const j=x.filter((e=>"file"===e.type)),R=x.filter((e=>"document"===e.type)),M=x.length
3344
- m.info("Starting mixed file and document deletion operation",{taskId:P,totalOperations:x.length,fileOperations:j.length,documentOperations:R.length,comment:S}),c.validateTaskIdFormat(P,m,s,b.metricsPrefix)
3386
+ 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
3387
  const $=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3346
- m.info("Initial branch context",{initialBranch:$.branch,initialRequestId:$.requestId,isMain:$.isMain})
3388
+ g.info("Initial branch context",{initialBranch:$.branch,initialRequestId:$.requestId,isMain:$.isMain})
3347
3389
  const O=[]
3348
3390
  for(const e of j){const{normalizedPath:t,fullPath:n}=c.validateAndNormalizePath(e.target,r)
3349
3391
  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,m,s,b.metricsPrefix),F=A?.requestId,N=await c.validateWorkItemStates(P,D,d,v,r,m,s,b.metricsPrefix),z=await c.autoPromoteTaskStatus(P,A.status,F,N.request?.status,D,d,v,m,s,b.metricsPrefix)
3351
- z.taskPromoted&&m.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&&m.info(`Auto-promoted request ${F} to in_progress for file operations`,{requestId:F,previousStatus:N.request?.status,newStatus:z.newRequestStatus,triggeringTaskId:P})
3352
- const L=await c.ensureCorrectWorkspaceContext({taskPromoted:z.taskPromoted,requestId:F,context:r,operation:"delete-files",logger:m,metrics:s,metricsPrefix:b.metricsPrefix})
3392
+ 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)
3393
+ 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})
3394
+ const L=await c.ensureCorrectWorkspaceContext({taskPromoted:z.taskPromoted,requestId:F,context:r,operation:"delete-files",logger:g,metrics:s,metricsPrefix:b.metricsPrefix})
3353
3395
  if(!L.success)throw Error(L.error)
3354
3396
  let H={hadUserMods:!1,userModsCommitHash:void 0}
3355
- if(r.git)try{m.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
3356
- const e=await(0,u.commitUserChangesBeforeToolOperation)(r.git,"delete-files",{requestId:F,taskId:P,workspaceManager:r.workspaceManager},m,s)
3357
- e.userChangesCommitted&&(m.debug("[DELETE-FILES] User changes committed before mixed delete operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),m.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){m.debug("[DELETE-FILES] Pre-tool commit failed, continuing with mixed delete operations",{error:e instanceof Error?e.message:e+""}),m.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+""})}m.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})
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,m,s,b.metricsPrefix,i)
3397
+ if(r.git)try{g.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
3398
+ const e=await(0,u.commitUserChangesBeforeToolOperation)(r.git,"delete-files",{requestId:F,taskId:P,workspaceManager:r.workspaceManager},g,s)
3399
+ 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})
3400
+ 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
3401
  y=B,w=B,I=b.fileOperationPhase,s.incrementCounter("delete_files_phase",1,{phase:I})
3360
3402
  const W=[]
3361
3403
  let G=0
3362
3404
  R.length>0&&n.setProjectId(r.projectId)
3363
3405
  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
3406
  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++,m.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,g.getErrorMessage)(e),m.warn("Failed to delete file "+t.normalized,{error:r.error})}W.push(r)}const V=R.length>0?n.getDocumentClient():null
3407
+ 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
3408
  for(const e of R){const t=e.target,r={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3367
3409
  try{let e
3368
- try{if(e=await V.getDocument(t),r.filename=e.filename,m.info("Document found for archival",{documentId:e.id,filename:e.filename,type:e.type,requestId:e.requestId}),e.requestId)try{await(0,h.validateRequestStatusForDocumentOperation)(e.requestId,v,m,s,"delete-document")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
3369
- throw e}try{await(0,p.ensureDocumentNotLocked)(t,n,m,s,"delete-document-archive")}catch(e){if(e instanceof l.ValidationError)throw Error(e.message)
3370
- throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,g.getErrorMessage)(e)}`)}const o=await V.archiveDocument(t)
3371
- r.success=!0,r.filename=o.filename,G++,m.info("Document archived successfully",{documentId:o.id,filename:o.filename,archivedAt:o.archived_at})}catch(e){r.error=(0,g.getErrorMessage)(e),m.warn("Failed to delete document "+t,{error:r.error})}W.push(r)}const K=Date.now()-f
3372
- s.recordValue("delete_files_time",K),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)
3373
- let J=null
3410
+ 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)
3411
+ 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)
3412
+ throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,m.getErrorMessage)(e)}`)}const o=await V.archiveDocument(t)
3413
+ 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
3414
+ 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)
3415
+ let K=null
3374
3416
  if(G>0){I=c.FileOperationPhase.GIT_COMMIT,s.incrementCounter("delete_files_phase",1,{phase:I})
3375
3417
  const e=W.filter((e=>e.success)),t=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
3376
3418
  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}`,J=await c.commitToGit(P,D,B,U,o,r,m,s,b.metricsPrefix)}I=c.FileOperationPhase.RECORD_UPDATE_SUCCESS,s.incrementCounter("delete_files_phase",1,{phase:I})
3378
- const Q=W.filter((e=>e.success)),Y=W.filter((e=>!e.success))
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:J?.commitHash,previousCommitHash:J?.previousCommitHash,totalOperations:M,fileOperations:j.length,documentOperations:R.length,successCount:G,failureCount:M-G,successfulOperations:Q.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:Y.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},G===M?`Successfully deleted all ${M} operations`:`Deleted ${G}/${M} operations successfully`,d,k,m,s,b.metricsPrefix)
3419
+ 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})
3420
+ const J=W.filter((e=>e.success)),Y=W.filter((e=>!e.success))
3421
+ 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
3422
  const Z=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3381
3423
  let X=""
3382
- if(G===M){const e=Q.filter((e=>"file"===e.type)).length,t=Q.filter((e=>"document"===e.type)).length
3424
+ if(G===M){const e=J.filter((e=>"file"===e.type)).length,t=J.filter((e=>"document"===e.type)).length
3383
3425
  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
3426
  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
3427
  return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
3386
- return J?.commitHash&&(X+="\nCommit: "+J.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
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,g.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:I,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,g.getErrorMessage)(t)})}catch(t){m.error("Failed to create failure record for delete-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0})}const o=Date.now()-f
3388
- if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),m.error("Error in delete-files operation:",{error:(0,g.getErrorMessage)(t),time:o}),(y||w)&&e.taskId){I=c.FileOperationPhase.RECORD_UPDATE_FAILURE
3428
+ 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
3429
+ 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
3430
+ 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
3431
  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,g.getErrorMessage)(t),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment},"Failed to delete operations",r,o,m,s,b.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return c.handleFileOperationError(t,I,m,s,e,b)}}
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),g=t(8824)},5997(e,exports,t){"use strict"
3432
+ 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)}}
3433
+ 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
3434
  var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
3393
3435
  var o=Object.getOwnPropertyDescriptor(t,r)
3394
3436
  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 +3492,30 @@ const n=await this.requestWithRetry("POST","/api/files/recover",t)
3450
3492
  if(!(0,i.safeGetResponseData)(n,null))throw new r.ServiceError("Empty response when recovering file")
3451
3493
  const o=(0,i.safeGetResponseData)(n,{success:!0,path:e.path,commitHash:e.commitHash,backupPath:void 0})
3452
3494
  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=s([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)."),a=s([/^req\d{6}$/],"Request ID must match format: req###### (e.g. req000001)"),c=s([/^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}),l=e=>e.path&&e.documentId?{...e,documentId:void 0}:e,d=e=>!!e.path||!!e.documentId
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 u=r.z.string().min(1).describe("OpenCode session ID")
3457
- exports.SubagentOperationsSchema=r.z.object({sessionId:u.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:u.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:u.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:a}),exports.InsertLinesSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.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(l).refine(d,{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:c.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(l).refine(d,{message:"path or documentId required"})),comment:r.z.string()}),exports.CreateDocumentSchema=r.z.object({requestId:a.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:a.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:c.optional(),requestId:a.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"})}))
3458
- const h=s([/^doc_[0-9A-Z]{26}$/i,/^(plan|quest)\d{6}$/],"Plan ID must match format: doc_[26 alphanumeric] (ULID) or plan######/quest###### (local ID)")
3459
- exports.PlanReadSchema=r.z.object({operation:r.z.enum(["get","get-active","list","get-history","get-requests"]),planId:h.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:h.optional(),kind:r.z.enum(["plan","quest"]).default("plan").describe("Document kind to create. Defaults to plan; quest writes type=Quest with quest metadata."),criteria:r.z.string().optional().describe("Quest acceptance criteria. Free text. Settable on create or update (when planId is a Quest)."),tickIntervalSeconds:r.z.number().int().min(300).optional().describe("Quest evaluation interval (seconds). Default 1800 (30 min) at create time. Minimum 300 (5 min). Provide on update to change."),maxInFlight:r.z.number().int().min(1).optional().describe("Quest concurrent in-flight request cap. Default 1 at create time."),maxPerDay:r.z.number().int().min(1).optional().describe("Quest daily spawn cap. Default 24 at create time."),minIterations:r.z.number().int().min(1).optional().describe("Quest minimum tick count. Runner fires at least this many ticks. Default 3 at create time."),status:r.z.enum(["open","closed"]).optional().describe('Quest lifecycle status. Set to "closed" to pause the runner; "open" to resume.'),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
3460
- 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)."}),"quest"!==e.kind||e.criteria||t.addIssue({code:"custom",message:"criteria is required when kind='quest'."})):e.planId||t.addIssue({code:"custom",message:`planId is required for '${r}'.`}),"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
3461
- r||n||t.addIssue({code:"custom",message:"update requires either 'content' (plan or quest body) or at least one metadata field (criteria, tickIntervalSeconds, maxInFlight, maxPerDay, minIterations, status \u2014 quest only)."})}"replace"===r&&(e.old||t.addIssue({code:"custom",message:'old is required for replace. Example: { "operation": "replace", "planId": "plan000001", "old": "find this", "new": "replace with" }'}),void 0===e.new&&t.addIssue({code:"custom",message:"new is required for replace"})),"restore"!==r||e.versionNumber||t.addIssue({code:"custom",message:'versionNumber is required for restore. Example: { "operation": "restore", "planId": "plan000001", "versionNumber": 1 }'})})),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:a,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),operationType:r.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:r.z.object({replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).optional(),insertLines:r.z.object({insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).optional(),replaceLines:r.z.object({replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).optional(),deleteString:r.z.object({patterns:r.z.array(r.z.string()),mode:r.z.enum(["all","unique"]).optional()}).optional(),deleteLines:r.z.object({lines:r.z.string()}).optional()}).transform(l).refine(d,{message:"path or documentId required"}).refine((e=>"replace-string"===e.operationType?e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"insert-lines"===e.operationType?e.insertLines&&!e.replaceString&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"replace-lines"===e.operationType?e.replaceLines&&!e.replaceString&&!e.insertLines&&!e.deleteString&&!e.deleteLines:"delete-string"===e.operationType?e.deleteString&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteLines:"delete-lines"===e.operationType&&e.deleteLines&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString),{message:"Invalid operation data"})),comment:r.z.string()}),exports.ManageFilesSchema=r.z.object({operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"}))}).optional(),getFileInfo:r.z.object({path:r.z.string()}).optional()}).refine((e=>"create-directory"===e.operationType?e.createDirectory&&!e.moveFiles&&!e.deleteFiles&&!e.getFileInfo:"move-files"===e.operationType?e.moveFiles&&!e.createDirectory&&!e.deleteFiles&&!e.getFileInfo:"delete-files"===e.operationType?e.deleteFiles&&!e.createDirectory&&!e.moveFiles&&!e.getFileInfo:"get-file-info"===e.operationType&&e.getFileInfo&&!e.createDirectory&&!e.moveFiles&&!e.deleteFiles),{message:"Invalid operation data"})),comment:r.z.string()}),exports.RequestOperationsSchema=r.z.object({requestId:a.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search","delete-empty"]),complete:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({summary:r.z.string(),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(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),approve:r.z.object({}).optional()}).superRefine(((e,t)=>{e.requestId
3495
+ 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
3496
+ 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
3497
+ 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" }'})}))
3498
+ const h=r.z.string().min(1).describe("OpenCode session ID")
3499
+ 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"})}))
3500
+ 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)")
3501
+ 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
3502
+ 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)."})
3503
+ const r=s.QUEST_METADATA_KEYS.filter((t=>void 0!==e[t]))
3504
+ 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}'.`})
3505
+ 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
3506
+ 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
3507
  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:c.optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"}),exports.QuickReplaceSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"})).min(1),fuzzy_match:r.z.boolean().optional(),comment:r.z.string().min(1,"Comment describing the change is required")}),exports.QuickManageSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"}))}).optional()})).min(1)}),exports.GenerateRequestJournalSchema=r.z.object({requestId:r.z.string().regex(/^req[_\d].+$/,"Invalid request ID format. Expected format: req_[26 chars] or req######")}),exports.MetaWorkflowListSchema=r.z.object({}),exports.MetaWorkflowGetSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the workflow"),shortName:r.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:r.z.string().optional().describe("Description of what the workflow does"),documentation:r.z.string().optional().describe("Detailed documentation"),defaultAgent:r.z.string().optional().describe("Default agent template to use"),completionMode:r.z.enum(["auto-merge","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")})
3464
- const p=r.z.object({name:r.z.string().min(1).describe('Command name (e.g., "Build", "Unit Tests")'),command:r.z.string().min(1).describe('Shell command to run (e.g., "npm test")'),required:r.z.boolean().default(!0).describe("If true, failure blocks the request (default: true)"),timeout:r.z.number().int().min(10).max(3600).default(300).describe("Max execution time in seconds (default: 300)")})
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"
3508
+ 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")})
3509
+ 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)")})
3510
+ 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
3511
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3467
3512
  const r=t(6183),n=t(405)
3468
- exports.def={name:"plan_write",description:"Create and modify project plans (and quests).\n\nOperations:\n\u2022 create - Create a new plan or quest. Pass kind='quest' with criteria/tickIntervalSeconds/maxInFlight/maxPerDay to create a quest.\n\u2022 update - Update plan/quest content. For quests, also accepts criteria / tickIntervalSeconds / maxInFlight / maxPerDay / minIterations / status (open|closed). Provide at least content or one metadata field.\n\u2022 append - Append content to an existing plan\n\u2022 replace - Find and replace text within a plan\n\u2022 create-snapshot - Create a version snapshot\n\u2022 restore - Restore to a previous version\n\u2022 set-active - Set a plan as the project's active plan",schema:r.PlanWriteSchema,annotations:{title:"Plan Write",readOnlyHint:!1,destructiveHint:!1},handler(e,t){return(0,n.handlePlanWrite)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer,t.cliOrigin)}}},6261(module){"use strict"
3513
+ 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
3514
  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,g){const m=u.child({tool:"specialist_ops"}),f=h.startTimer("tool_execution_time")
3515
+ 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
3516
  try{const u=e,{operation:y,sessionId:w}=u
3472
3517
  let I
3473
- switch(m.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=g?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
3518
+ switch(g.info("Processing specialist_ops",{operation:y,sessionId:w}),y){case"delegate":{const e=10,r=m?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
3474
3519
  if(r&&p){const t=await async function(e,t,r,o,s){o.info("enforcePoolLimit called",{parentSessionId:e,maxPoolSize:t})
3475
3520
  const a=await(0,i.getServerUrl)(r,o)
3476
3521
  if(a)try{const r=await fetch(a.replace(/\/$/,"")+"/session")
@@ -3484,31 +3529,31 @@ return"specialist"===t?.agentType&&"archived"!==t?.status}))
3484
3529
  if(o.info("Pool check: specialist count",{specialistCount:h.length,maxPoolSize:t}),h.length<t)return
3485
3530
  const p=h.map((e=>{const t=l[e.id],r=u[e.id]?.type||"idle",n=t?.specialization||"(none)"
3486
3531
  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,m,p)
3532
+ 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
3533
  if(t){I=t
3489
3534
  break}}let c=u.description||u.prompt.slice(0,60)
3490
3535
  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,m)
3536
+ if(r)try{const e=await(0,i.getServerUrl)(d,g)
3492
3537
  if(h(`serverUrl=${e}, parentId=${r}`),e){const t=await fetch(e.replace(/\/$/,"")+"/session")
3493
3538
  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
3539
  h(`siblings=${e.length}: ${e.join(", ")}`)
3495
3540
  const n=(0,o.pickSpecialistName)(e)
3496
3541
  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,m,p,g)
3498
- break}case"follow-up":{const e=await(0,i.getServerUrl)(d,m)
3542
+ I=await(0,s.handleSpawn)({agent:"specialist",prompt:u.prompt,title:c,specialization:u.specialization,specializationHeadline:u.specializationHeadline},d,g,p,m)
3543
+ break}case"follow-up":{const e=await(0,i.getServerUrl)(d,g)
3499
3544
  if(e)try{const t=await fetch(e.replace(/\/$/,"")+"/session/status")
3500
3545
  if(t.ok){const e=await t.json(),r=e[w]?.type
3501
3546
  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,m,p,"specialist",g)
3503
- break}case"check-status":I=await(0,s.handleCheckStatus)(w,d,m,p)
3547
+ break}}}catch{}I=await(0,s.handleContinue)(w,u.prompt,d,g,p,"specialist",m)
3548
+ break}case"check-status":I=await(0,s.handleCheckStatus)(w,d,g,p)
3504
3549
  break
3505
- case"abort":if(I=await(0,s.handleAbort)(w,d,m),!I.isError&&p)try{const e=p.getCLISessionClient()
3550
+ case"abort":if(I=await(0,s.handleAbort)(w,d,g),!I.isError&&p)try{const e=p.getCLISessionClient()
3506
3551
  e&&await e.createOrUpdateSession({externalSessionId:w,status:"archived"})}catch{}break
3507
- case"list":{const e=g?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
3508
- I=await(0,s.handleListSessions)(d,m,p,{activeOnly:u.activeOnly,requestId:u.requestId,limit:u.limit,agentType:"specialist",parentSessionId:e})
3552
+ case"list":{const e=m?.sessionId||a.sessionIdentity.getIdentity()?.sessionId
3553
+ I=await(0,s.handleListSessions)(d,g,p,{activeOnly:u.activeOnly,requestId:u.requestId,limit:u.limit,agentType:"specialist",parentSessionId:e})
3509
3554
  break}default:throw new r.ValidationError("Unknown operation: "+y)}f({success:!0}),h.incrementCounter(`specialist_ops_${y}_success`,1)
3510
3555
  const b=l[y]??"specialist-delegate"
3511
- return(0,c.withAlchemyKind)(I,b)}catch(e){return m.error("Specialist ops failed",{error:e instanceof Error?e.stack:e+""}),f({success:!1}),h.incrementCounter("specialist_ops_errors",1),{content:[{type:"text",text:"Specialist operation failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}}
3556
+ 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
3557
  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
3558
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3514
3559
  const r=t(6183),n=t(8184)
@@ -3527,16 +3572,16 @@ return o(t,e),t})
3527
3572
  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
3573
  try{const n=e,{requestId:l,reason:h,confirmDestructive:p}=n
3529
3574
  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 g
3575
+ let m
3531
3576
  try{const e=await r.proxyPost(`/api/projects/${t.projectId}/requests/${l}/validate-revert`,{})
3532
- g=e?.data||e}catch(e){const t=(0,d.getErrorMessage)(e)
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:g.canRevert,operationType:g.operationType,mergeCommitHash:g.mergeCommitHash?.substring(0,8),reason:g.reason}),!g.canRevert){let e=`Cannot revert request ${l}: ${g.reason}\n`
3534
- return g.lifoViolation?.blockingRequests?.length&&(e+="\n**Requests that must be reverted first (in reverse order):**\n",g.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (${t.status})\n`})),e+="\n**Why:** Requests must be reverted in reverse order (LIFO) to maintain safe git history.\n",e+="Revert the above request(s) first, then retry this one."),u({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if("cancel"===g.operationType){s.info("Cancel operation \u2014 delegating to server",{requestId:l})
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: ${g.tasksToUpdate.length} task(s) marked as canceled\nReason: ${h}`}]}}catch(e){const t=(0,d.getErrorMessage)(e)
3577
+ m=e?.data||e}catch(e){const t=(0,d.getErrorMessage)(e)
3578
+ 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`
3579
+ 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})
3580
+ 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
3581
  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
3582
  t.syncBranchState&&await t.syncBranchState()
3538
- let m=g.mergeCommitHash
3539
- if(!m){s.info("No merge commit hash from server, searching git log",{requestId:l})
3583
+ let g=m.mergeCommitHash
3584
+ if(!g){s.info("No merge commit hash from server, searching git log",{requestId:l})
3540
3585
  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
3586
  return-1===t?{hash:e,message:""}:{hash:e.substring(0,t),message:e.substring(t+1)}})):[],s=a.generateMergeMessagePatterns(e)
3542
3587
  for(const e of s){let t
@@ -3544,14 +3589,14 @@ if(e.includes("\\")||e.includes(".*")){const r=RegExp(e,"i")
3544
3589
  t=o.find((e=>r.test(e.message)))}else t=o.find((t=>t.message.includes(e)))
3545
3590
  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
3591
  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
- m=e.commitHash}const f=t.workspaceManager.getMainGit(),y=await a.getRepositoryStatus(f,s,o)
3592
+ g=e.commitHash}const f=t.workspaceManager.getMainGit(),y=await a.getRepositoryStatus(f,s,o)
3548
3593
  if(y.currentBranch!==y.defaultBranch){const e=await a.switchToBranch(f,y.defaultBranch||"main",s,o)
3549
3594
  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:m.substring(0,8)}),await f.raw(["revert","-m","1","--no-edit",m]),w=await(0,c.captureCommitHashRobustly)(f,s,"revert-request-"+l,3,150)
3595
+ 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
3596
  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:m.substring(0,8),revertCommitHash:w.substring(0,8)})}catch(e){const t=(0,d.getErrorMessage)(e)
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:m})}catch(e){const t=(0,d.getErrorMessage)(e)
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: ${g.tasksToUpdate.length} task(s) marked as reverted\nReason: ${h}\n\nYou can re-complete the request if the revert was a mistake.`}]}}catch(n){if(n instanceof i.ValidationError||n instanceof i.NotFoundError)return s.warn("Revert validation failed",{error:n.message,requestId:e.requestId}),u({success:!1,error:"validation"}),{content:[{type:"text",text:"Error: "+n.message}],isError:!0}
3597
+ 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)
3598
+ 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)
3599
+ 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
3600
  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
3601
  if(t.projectId&&e.requestId)try{const o=r.getToolRecordClient()
3557
3602
  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 +3622,15 @@ const s=[...t].sort(((e,t)=>"between"===e.type&&"between"===t.type?(t.afterLine|
3577
3622
  for(const e of s){const t={type:e.type,line:e.line,afterLine:e.afterLine,beforeLine:e.beforeLine,success:!1}
3578
3623
  try{let n
3579
3624
  switch(e.type){case"before":if(void 0===e.line)throw Error("Line number is required for before insertion")
3580
- n=(0,m.insertBeforeLine)(r,e.line,e.content)
3625
+ n=(0,g.insertBeforeLine)(r,e.line,e.content)
3581
3626
  break
3582
3627
  case"after":if(void 0===e.line)throw Error("Line number is required for after insertion")
3583
- n=(0,m.insertAfterLine)(r,e.line,e.content)
3628
+ n=(0,g.insertAfterLine)(r,e.line,e.content)
3584
3629
  break
3585
3630
  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,m.insertBetweenLines)(r,e.afterLine,e.beforeLine,e.content)
3631
+ n=(0,g.insertBetweenLines)(r,e.afterLine,e.beforeLine,e.content)
3587
3632
  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,g.getErrorMessage)(e)}n.push(t)}return{newContent:r,results:n}}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
3633
+ 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
3634
  var o=Object.getOwnPropertyDescriptor(t,r)
3590
3635
  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
3636
  for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
@@ -3593,7 +3638,7 @@ return t},n(e)},function(e){if(e&&e.__esModule)return e
3593
3638
  var t={}
3594
3639
  if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
3595
3640
  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,m,f){const y=a.child({tool:"insert_lines"}),w=Date.now()
3641
+ 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
3642
  let I,b,k=l.FileOperationPhase.VALIDATION
3598
3643
  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
3644
  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 +3653,55 @@ j.push({type:"file",path:t,fullPath:r,insertions:e.insertions})}const R=[]
3608
3653
  if(x.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3609
3654
  for(const e of x)R.push({type:"document",documentId:e.documentId,insertions:e.insertions})
3610
3655
  if(R.length>0&&n.apiClient){const e=R.map((e=>e.documentId))
3611
- try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,y,m,"insert-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3612
- throw e}}k=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("insert_lines_phase",1,{phase:k})
3613
- const M=j.length>0?j[0].path:"document-operation",$=await l.validateTaskId(T,M,o,y,m,v.metricsPrefix),O=$?.requestId
3656
+ 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}
3657
+ throw e}}k=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("insert_lines_phase",1,{phase:k})
3658
+ const M=j.length>0?j[0].path:"document-operation",$=await l.validateTaskId(T,M,o,y,g,v.metricsPrefix),O=$?.requestId
3614
3659
  let D=null
3615
- j.length>0&&O&&(D=await l.validateWorkItemStates(T,j[0].path,o,i,n,y,m,v.metricsPrefix))
3660
+ j.length>0&&O&&(D=await l.validateWorkItemStates(T,j[0].path,o,i,n,y,g,v.metricsPrefix))
3616
3661
  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,m,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"}))
3618
- const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:O,context:n,operation:"insert-lines",logger:y,metrics:m,metricsPrefix:v.metricsPrefix})
3662
+ 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"}))
3663
+ const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:O,context:n,operation:"insert-lines",logger:y,metrics:g,metricsPrefix:v.metricsPrefix})
3619
3664
  if(!F.success)throw Error(F.error)
3620
3665
  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
3666
  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,m,"insert-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3623
- throw e}k=l.FileOperationPhase.RECORD_CREATION,m.incrementCounter("insert_lines_phase",1,{phase:k})
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,m,v.metricsPrefix,f)
3625
- if(I=z,b=z,k=v.fileOperationPhase,m.incrementCounter("insert_lines_phase",1,{phase:k}),j.length>0&&n.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
3626
- const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"insert-lines",{requestId:O,taskId:T,workspaceManager:n.workspaceManager},y,m)
3667
+ 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}
3668
+ throw e}k=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("insert_lines_phase",1,{phase:k})
3669
+ 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)
3670
+ 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")
3671
+ const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"insert-lines",{requestId:O,taskId:T,workspaceManager:n.workspaceManager},y,g)
3627
3672
  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
3673
  const L=[]
3629
3674
  let H=0,B=0,U=0
3630
3675
  for(const e of j){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3631
3676
  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
3677
  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,g.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}L.push(t)}for(const e of R){const t={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3678
+ 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
3679
  try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
3635
3680
  t.filename=s?.filename
3636
3681
  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,g.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:t.error})}L.push(t)}if(R.length>0)try{for(const e of R){const t=L.find((t=>t.documentId===e.documentId))
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:m,metricsPrefix:"insert_lines"},n),G=l.processMultiFileOperationResults(L,"successfulInsertions"),{successfulOperations:V,failedOperations:K,totalSuccessfulChanges:J,overallSuccess:Q,successfulFiles:Y,failedFiles:Z}=G
3639
- try{await s.updateToolRecord(b,{metadata:{path:j.length>0?j[0].path:"document:"+R[0]?.documentId,status:Q?"completed":"failed",error:Q?void 0:K+" operations failed",totalOperations:L.length,successfulFiles:Y,failedFiles:Z,operations:N,totalSuccessfulInsertions:J,totalFailedInsertions:H,totalLinesAdded:B,operationsWithChanges:U,processingTime:Date.now()-w,userComment:E,...j.length>0&&W.success&&W.commitHash&&{commitHash:W.commitHash,previousCommitHash:W.previousCommitHash||void 0}},note:Q?`Line insertion completed: ${V}/${L.length} operations successful${j.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${K}/${L.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let X="## Line Insertion Results\n\n"
3682
+ 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))
3683
+ 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
3684
+ 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
3685
  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+K}\n`,X+=`- **Successful operations:** ${V}\n`,X+=`- **Failed operations:** ${K}\n`,X+=`- **Total insertions:** ${J} successful, ${H} failed\n`,X+=`- **Total Lines Added:** ${B}\n`,X+="\n",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]
3686
+ 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
3687
  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
3688
  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:** ${K}\n`,X+=`- **Total Insertions:** ${J} successful, ${H} failed\n`,X+=`- **Total Lines Added:** ${B}\n\n`,X+="**Detailed Results:**\n\n"
3689
+ 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
3690
  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
3691
  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
3692
  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
3693
  const ee=Date.now()-w
3649
- return y.info("Insert lines operation completed",{duration:ee,success:Q,totalOperations:L.length,successfulOperations:V,failedOperations:K}),m.incrementCounter("insert_lines_total",1,{success:Q}),{content:[{type:"text",text:X}],isError:!Q}}catch(t){const r=Date.now()-w
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,g.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,g.getErrorMessage)(t)})}catch(e){}return m.incrementCounter("insert_lines_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,g.getErrorMessage)(t)}],isError:!0}}}
3651
- const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),g=t(8824),m=t(3255)},6539(e,exports,t){"use strict"
3694
+ 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
3695
+ 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}}}
3696
+ 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
3697
  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),g=t(2968),m=t(922)
3698
+ 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
3699
  exports.ClientFactory=class{static async createClient(e,f,y,w={}){(f=f.child({component:"client-factory"})).info("Creating API client with components")
3655
3700
  const I=w.tokenManager||new r.TokenManager(f,w.workingDir||process.cwd())
3656
3701
  await I.initialize()
3657
3702
  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
3703
  b.registerClient(_),w.alchemyPath&&_.setAlchemyPath(w.alchemyPath)
3659
- const E=new g.TaskClient(e,f,y,_,C,v||void 0,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3704
+ 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
3705
  b.registerClient(E)
3661
3706
  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
3707
  b.registerClient(S),f.info("RequestClient constructor received token: "+(v?"present":"missing"))
@@ -3664,7 +3709,7 @@ const q=new u.RequestClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts
3664
3709
  b.registerClient(q),f.info("RequestClient post-constructor token: "+(q.getAuthToken()?"present":"missing"))
3665
3710
  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
3711
  b.registerClient(T)
3667
- const P=new m.ToolRecordClient(e,f,y,_,v||void 0,C,{timeout:w.timeout,retryAttempts:w.retryAttempts,retryDelay:w.retryDelay,circuitBreakerThreshold:w.circuitBreakerThreshold,circuitBreakerResetTime:w.circuitBreakerResetTime})
3712
+ 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
3713
  b.registerClient(P)
3669
3714
  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
3715
  if(b.registerClient(x),!w.alchemyPath)throw Error("alchemyPath is required for ProjectSynchronizer creation. Cannot create API client without project synchronization capabilities.")
@@ -3706,8 +3751,8 @@ async function r(e,t){let r=e
3706
3751
  const n=[],o=[...t].sort(((e,t)=>{const r=e=>"number"==typeof e?e:Array.isArray(e)?Math.max(...e):e.end
3707
3752
  return r(t.lines)-r(e.lines)}))
3708
3753
  for(const e of o){const t={lines:e.lines,success:!1}
3709
- try{const n=(0,m.replaceLines)(r,e.lines,e.content)
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,g.getErrorMessage)(e)}n.push(t)}return{newContent:r,results:n}}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
3754
+ try{const n=(0,g.replaceLines)(r,e.lines,e.content)
3755
+ 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
3756
  var o=Object.getOwnPropertyDescriptor(t,r)
3712
3757
  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
3758
  for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
@@ -3715,7 +3760,7 @@ return t},n(e)},function(e){if(e&&e.__esModule)return e
3715
3760
  var t={}
3716
3761
  if(null!=e)for(var r=n(e),i=0;i<r.length;i++)"default"!==r[i]&&o(t,e,r[i])
3717
3762
  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,m,y){const w=a.child({tool:"replace_lines"}),I=Date.now()
3763
+ 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
3764
  let b,k,v=l.FileOperationPhase.VALIDATION
3720
3765
  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
3766
  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 +3775,55 @@ R.push({type:"file",path:t,fullPath:r,replacements:e.replacements.map((e=>({line
3730
3775
  if(j.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3731
3776
  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
3777
  if(M.length>0&&n.apiClient){const e=M.map((e=>e.documentId))
3733
- try{await(0,p.ensureDocumentsNotLocked)(e,n.apiClient,w,m,"replace-lines-documents")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3734
- throw e}}v=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("replace_lines_phase",1,{phase:v})
3735
- const $=R.length>0?R[0].path:"document-operation",O=await l.validateTaskId(P,$,o,w,m,C.metricsPrefix),D=O?.requestId
3778
+ 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}
3779
+ throw e}}v=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("replace_lines_phase",1,{phase:v})
3780
+ const $=R.length>0?R[0].path:"document-operation",O=await l.validateTaskId(P,$,o,w,g,C.metricsPrefix),D=O?.requestId
3736
3781
  let A=null
3737
- R.length>0&&D&&(A=await l.validateWorkItemStates(P,R[0].path,o,i,n,w,m,C.metricsPrefix))
3782
+ R.length>0&&D&&(A=await l.validateWorkItemStates(P,R[0].path,o,i,n,w,g,C.metricsPrefix))
3738
3783
  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,m,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"}))
3740
- const N=await l.ensureCorrectWorkspaceContext({taskPromoted:F.taskPromoted,requestId:D,context:n,operation:"replace-lines",logger:w,metrics:m,metricsPrefix:C.metricsPrefix})
3784
+ 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"}))
3785
+ const N=await l.ensureCorrectWorkspaceContext({taskPromoted:F.taskPromoted,requestId:D,context:n,operation:"replace-lines",logger:w,metrics:g,metricsPrefix:C.metricsPrefix})
3741
3786
  if(!N.success)throw Error(N.error)
3742
3787
  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
3788
  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,m,"replace-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3745
- throw e}v=l.FileOperationPhase.RECORD_CREATION,m.incrementCounter("replace_lines_phase",1,{phase:v})
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,m,C.metricsPrefix,y)
3747
- if(b=L,k=L,v=C.fileOperationPhase,m.incrementCounter("replace_lines_phase",1,{phase:v}),R.length>0&&n.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
3748
- const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"replace-lines",{requestId:D,taskId:P,workspaceManager:n.workspaceManager},w,m)
3789
+ 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}
3790
+ throw e}v=l.FileOperationPhase.RECORD_CREATION,g.incrementCounter("replace_lines_phase",1,{phase:v})
3791
+ 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)
3792
+ 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")
3793
+ const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"replace-lines",{requestId:D,taskId:P,workspaceManager:n.workspaceManager},w,g)
3749
3794
  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
3795
  const H=[]
3751
3796
  let B=0,U=0,W=0,G=0
3752
3797
  for(const e of R){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3753
3798
  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
3799
  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,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("File operation failed",{path:e.path,error:t.error})}H.push(t)}for(const e of M){const t={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3800
+ 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
3801
  try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
3757
3802
  t.filename=s?.filename
3758
3803
  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,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:t.error})}H.push(t)}if(M.length>0)try{for(const e of M){const t=H.find((t=>t.documentId===e.documentId))
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:m,metricsPrefix:"replace_lines"},n),K=l.processMultiFileOperationResults(H,"successfulReplacements"),{successfulOperations:J,failedOperations:Q,totalSuccessfulChanges:Y,overallSuccess:Z,successfulFiles:X,failedFiles:ee}=K
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:Q+" 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: ${J}/${H.length} operations successful${R.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${Q}/${H.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let te="## Line Replacement Results\n\n"
3804
+ 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))
3805
+ 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
3806
+ 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
3807
  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+Q}\n`,te+=`- **Successful operations:** ${J}\n`,te+=`- **Failed operations:** ${Q}\n`,te+=`- **Total replacements:** ${Y} successful, ${B} failed\n`,te+=`- **Total Lines Replaced:** ${U}\n`,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]
3808
+ 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
3809
  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:** ${J}\n`,te+=`- **Failed:** ${Q}\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"
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`}}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
3811
  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
3812
  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
3813
  const re=Date.now()-I
3769
- return w.info("Replace lines operation completed",{duration:re,success:Z,totalOperations:H.length,successfulOperations:J,failedOperations:Q}),m.incrementCounter("replace_lines_total",1,{success:Z}),{content:[{type:"text",text:te}],isError:!Z}}catch(t){const r=Date.now()-I
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,g.getErrorMessage)(t),phase:v,duration:r,userComment:e?.comment},note:"Line replacement failed: "+(0,g.getErrorMessage)(t)})}catch(e){}return m.incrementCounter("replace_lines_errors",1,{phase:v}),{content:[{type:"text",text:"\u274c **Replace Lines Failed:** "+(0,g.getErrorMessage)(t)}],isError:!0}}}
3771
- const c=a(t(1943)),l=i(t(5967)),d=t(9860),u=t(5003),h=t(7478),p=t(9949),g=t(8824),m=t(3255),f=t(9470)},6656(e,exports,t){"use strict"
3772
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCreatePlan=async function(e,t,o,s,i,a,c){const l=e.kind??"plan",d=n.KIND_META[l],u="quest"===l,h=s.child({tool:"plan_operations",operation:u?"create-quest":"create"})
3773
- try{const s=t.projectId
3774
- if(!s)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
3775
- const i=e.name.replace(/\.md$/i,""),a=`${d.filenamePrefix}${i}.md`,l=o.getDocumentClient(),p=await l.listDocuments({type:d.docType,filename:a,limit:1,offset:0})
3776
- if(p&&p.length>0)return{content:[{type:"text",text:`\u274c A ${d.label} with filename "${a}" already exists (${p[0].localId||p[0].id}). Choose a different name.`}],isError:!0}
3777
- const g=u?{criteria:e.criteria||"",status:n.QUEST_STATUS_OPEN,tickIntervalSeconds:e.tickIntervalSeconds??n.QUEST_DEFAULTS.tickIntervalSeconds,maxInFlight:e.maxInFlight??n.QUEST_DEFAULTS.maxInFlight,maxPerDay:e.maxPerDay??n.QUEST_DEFAULTS.maxPerDay,minIterations:e.minIterations??n.QUEST_DEFAULTS.minIterations}:void 0,m=await l.createDocument(void 0,{filename:a,content:e.content,type:d.docType,...g&&{metadata:g},...c&&{cliOrigin:c}}),f=m.localId||m.id,y=m.id
3778
- if(c?.sessionId)try{await o.proxyPost(`/api/projects/${s}/session-plan-associations`,{opencodeSessionId:c.sessionId,documentId:y})}catch(e){h.warn("Failed to create session-plan association",{error:(0,r.getErrorMessage)(e)})}let w=!1
3779
- if(d.canBeActivePlan)try{const e=o.getProjectClient(),t=await e.getProject(s)
3780
- t&&!t.activePlanId&&(await e.updateProject(s,{activePlanId:y}),w=!0,h.info("Auto-set as active plan",{planId:f,projectId:s}))}catch(e){h.warn("Failed to auto-set active plan",{error:(0,r.getErrorMessage)(e)})}return h.info(""+d.headingCreated,{planId:f,filename:a}),{content:[{type:"text",text:`\u2705 **${d.headingCreated}**\n\n**${d.idLabel}:** ${f}\n**Filename:** ${a}\n**Created:** `+new Date(m.createdAt).toLocaleString()+(w?"\n\n\u{1f4cc} _Automatically set as the active project plan._":"")}]}}catch(e){return h.error("Failed to "+d.errorVerb,{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:`\u274c **Failed to ${d.errorVerb}:** ${(0,r.getErrorMessage)(e)}`}],isError:!0}}}
3781
- const r=t(8824),n=t(3416)},6688(e,exports,t){"use strict"
3814
+ 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
3815
+ 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}}}
3816
+ 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"
3817
+ 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"})
3818
+ try{const o=t.projectId
3819
+ if(!o)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
3820
+ const s=`PLAN-${e.name.replace(/\.md$/i,"")}.md`,i=n.getDocumentClient(),l=await i.listDocuments({type:"Plan",filename:s,limit:1,offset:0})
3821
+ 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}
3822
+ 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
3823
+ 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
3824
+ try{const e=n.getProjectClient(),t=await e.getProject(o)
3825
+ 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}}}
3826
+ const r=t(8824)},6688(e,exports,t){"use strict"
3782
3827
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
3783
3828
  const r=t(9896),n=t(6928),o=t(3545)
3784
3829
  exports.sessionIdentity=new class{constructor(){this.parentCache=new Map,this.sessionRequestCache=new Map}setIdentity(e){const t=this.identity
@@ -3855,18 +3900,18 @@ var t={}
3855
3900
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
3856
3901
  return o(t,e),t})
3857
3902
  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:g,showDiff:m=!1}=e
3859
- if(!g)throw(0,i.createValidationError)("Task ID is required")
3860
- if(!(0,h.isTaskRef)(g))throw(0,i.createValidationError)(`Invalid task ID format: ${g}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
3861
- s.info("Getting file changes for task "+g,{showDiff:m})
3903
+ try{const{taskId:m,showDiff:g=!1}=e
3904
+ if(!m)throw(0,i.createValidationError)("Task ID is required")
3905
+ 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.`)
3906
+ s.info("Getting file changes for task "+m,{showDiff:g})
3862
3907
  const f=r.getTaskClient(),y=r.getToolRecordClient(),w=t.projectId
3863
3908
  let I
3864
3909
  r.setProjectId(w)
3865
- try{const x=await f.getTask(g)
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:g,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:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let b=[]
3867
- try{const R=await y.getToolRecordsByTaskId(g)
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 ${g}`),b.length>0){const M={}
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 "+g,{error:(0,u.getErrorMessage)($)}),b=[]}if(0===b.length)return p({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
3910
+ try{const x=await f.getTask(m)
3911
+ 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=[]
3912
+ try{const R=await y.getToolRecordsByTaskId(m)
3913
+ 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={}
3914
+ 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
3915
  function k(e){const t=new Map,r=new Map,n=[]
3871
3916
  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
3917
  if(e&&s){const i={source:e,destination:s,recordId:o.id,timestamp:o.createdAt,type:"move-file"}
@@ -3887,7 +3932,7 @@ if(t&&(n=e.metadata.successfulOperations.some((e=>e&&e.source&&e.destination))),
3887
3932
  if(!Array.isArray(t)||0===t.length)return s.warn("Skipping delete-files record without valid paths array: "+e.id),!1
3888
3933
  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
3934
  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 ${g}.`}]}
3935
+ 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
3936
  const _=new Map
3892
3937
  C.forEach((e=>{let t=null
3893
3938
  if(e.metadata){if(!e.metadata.commitHash){const t=["gitCommitId","commitId","commit","gitCommit"]
@@ -3921,9 +3966,9 @@ const z=new Map
3921
3966
  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
3967
  const L=N.filter((e=>e.commitHash))
3923
3968
  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 J={file:F,n:10},Q=await t.git.log(J)
3925
- if(Q&&Q.all&&Q.all.length>0){s.info(`Found ${Q.all.length} commits for ${F} using git log`)
3926
- const Y=Q.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}}})))
3969
+ try{if(t.git){const K={file:F,n:10},J=await t.git.log(K)
3970
+ if(J&&J.all&&J.all.length>0){s.info(`Found ${J.all.length} commits for ${F} using git log`)
3971
+ 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
3972
  if(Y.length>0){const Z=Y.length>1?Y[Y.length-1]:Y[0],X=Y[0],ee=1===Y.length
3928
3973
  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
3974
  let te=""
@@ -3934,34 +3979,34 @@ continue}const H=L[0],B=L[L.length-1]
3934
3979
  s.info(`First commit: ${H.commitHash?H.commitHash:"unknown"}, Last commit: ${B.commitHash?B.commitHash:"unknown"}`)
3935
3980
  let U=null,W=!1
3936
3981
  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(m&&!W&&t.git&&B.commitHash)try{const le=[`${B.commitHash}:${F}`]
3982
+ 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
3983
  s.info(`Getting new file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${F}`)
3939
3984
  const de=await t.git.show(le)
3940
3985
  if(de&&de.trim().length>0){let ue=""
3941
3986
  const he=de.split("\n")
3942
3987
  for(const pe of he)ue+=`+${pe}\n`
3943
3988
  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(ge){s.warn("Error getting new file content for "+F,{error:(0,u.getErrorMessage)(ge)})}E.set(F,{firstChange:G,lastChange:B,hasDiff:!1,diffText:"Only one commit available for this file"})
3989
+ 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
3990
  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="",K=!1
3947
- if(m||"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",K=!0,E.set(F,{firstChange:G,lastChange:B,hasDiff:K,diffText:V})
3948
- continue}let me
3949
- if("pre-task"===G.status?(me=[`${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}`)):(me=["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(me),K=!!V&&V.trim().length>0,!K&&G.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
3991
+ continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let V="",Q=!1
3992
+ 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})
3993
+ continue}let ge
3994
+ 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
3995
  try{const ye=await t.git.show([`${G.commitHash}:${F}`]),we=await t.git.show([`${B.commitHash}:${F}`])
3951
- if(ye!==we&&(K=!0,V="Changes detected through direct content comparison (not visible in standard diff)",m)){const Ie=ye.split("\n"),be=we.split("\n")
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=${K}, length=${V.length}`)}}catch(ve){if(s.warn("Error getting diff for "+F,{error:(0,u.getErrorMessage)(ve),firstCommit:H.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),V="Error getting diff: "+(0,u.getErrorMessage)(ve),"pre-task"!==H.status&&t.git)try{const Ce=[`${B.commitHash}:${F}`]
3996
+ 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")
3997
+ 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
3998
  s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${F}`)
3954
3999
  const _e=await t.git.show(Ce)
3955
- if(_e&&_e.trim().length>0){if(m){let Ee=""
4000
+ if(_e&&_e.trim().length>0){if(g){let Ee=""
3956
4001
  const Se=_e.split("\n")
3957
4002
  for(const qe of Se)Ee+=`+${qe}\n`
3958
4003
  V=Ee}else V="File created during this task. Content:\n"+_e
3959
- K=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(Te){s.warn("Fallback also failed for "+F,{error:Te instanceof Error?Te.message:Te+""})}}E.set(F,{firstChange:G,lastChange:B,hasDiff:K,diffText:V||"No changes detected between commits"})}else K=G.commitHash!==B.commitHash,V=K?"File has changes":"No changes detected between commits",E.set(F,{firstChange:G,lastChange:B,hasDiff:K,diffText:V})}let S=`# File Changes for Task: ${g}\n\n`
4004
+ 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
4005
  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
4006
  const q=3e3
3962
4007
  let T=0,P=!1
3963
- if(m){for(const Pe of E.values())Pe.hasDiff&&Pe.diffText&&(T+=Pe.diffText.split("\n").length)
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**: ${m?"Enabled":"Disabled"} (use showDiff=${!m} to ${m?"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`
4008
+ if(g){for(const Pe of E.values())Pe.hasDiff&&Pe.diffText&&(T+=Pe.diffText.split("\n").length)
4009
+ 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
4010
  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
4011
  for(const[je,Re]of E.entries()){const{normalizedPath:Me,fullPath:$e}=d.validateAndNormalizePath(je,t)
3967
4012
  let Oe=!1
@@ -3969,7 +4014,7 @@ try{await a.access($e),Oe=!0}catch{}S+=`### ${je} ${Oe?"":"(Deleted)"}\n\n`
3969
4014
  const De=new Date(Re.firstChange.timestamp).toLocaleString(),Ae=new Date(Re.lastChange.timestamp).toLocaleString()
3970
4015
  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
4016
  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`),m&&!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}}}
4017
+ 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
4018
  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
4019
  module.exports=require("path")},6975(e,exports,t){"use strict"
3975
4020
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
@@ -4105,39 +4150,40 @@ i.appendFileSync(o,`[${s}] ${e} | ${t}${l}\n`)}catch(e){}}
4105
4150
  const i=s(t(9896)),a=s(t(6928)),c=s(t(857))},7334(e,exports,t){"use strict"
4106
4151
  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
4152
  p.info("Creating new request",{args:e})
4108
- const g=d.startTimer("tool_handler_duration")
4153
+ const m=d.startTimer("tool_handler_duration")
4109
4154
  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
4155
  throw new r.ValidationError("Invalid input: "+(0,i.getErrorMessage)(e))}}(e)
4111
4156
  d.incrementCounter("create_request_attempts",1,{type:l.type,criteriaCounts:l.acceptanceCriteria.length})
4112
- const m=t.projectId
4113
- if(!m)throw new r.ValidationError("Project ID is required for creating requests.")
4114
- c.setProjectId(m)
4157
+ const g=t.projectId
4158
+ if(!g)throw new r.ValidationError("Project ID is required for creating requests.")
4159
+ c.setProjectId(g)
4115
4160
  const f=c.getRequestClient()
4116
4161
  let y=(0,a.getApprovalMode)()
4117
4162
  try{const e=h?.sessionId
4118
4163
  if(e){const t=c.getCLISessionClient()
4119
4164
  if(t){const r=await t.getByExternalId(e)
4120
4165
  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/"+m),t=e?.data||e,r=t?.metadata?.defaultApprovalMode
4166
+ 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
4167
  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
4168
  let I=h
4124
4169
  if(h?.sessionId)try{const e=c.getCLISessionClient()
4125
4170
  if(e){const t=await e.getByExternalId(h.sessionId)
4126
4171
  "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:m,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
4172
+ p.info("Creating request via request client",{projectId:g,title:l.title,type:l.type,criteriaCount:l.acceptanceCriteria.length})
4128
4173
  const k=await f.createRequest(b)
4129
4174
  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
4175
  const v=(0,o.extractDataFromResponse)(k,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
4131
4176
  let _,E={created:!1}
4132
4177
  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
- try{const e=c.getToolRecordClient()
4135
- if(e){const t=await e.createToolRecord({requestId:C.id,projectId:m,type:"create-request",metadata:{status:"completed",timestamp:(new Date).toISOString(),requestType:C.type,requestTitle:C.title,requestDescription:C.description,criteriaCount:C.acceptanceCriteria.length,branchCreated:E.created,branchName:E.created?E.branchName:null},note:`Created request "${C.title}" of type ${C.type}${E.created?" with branch "+E.branchName:" - branch will be created on first file operation"}`})
4136
- _=t?.id}}catch(e){p.warn("Failed to create tool record for request creation",{error:(0,i.getErrorMessage)(e),requestId:C.id})}g({success:!0,type:l.type,hasProjectId:!0}),p.info("Request created successfully",{requestId:C.id,title:C.title,type:C.type,projectId:m})
4178
+ 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)
4179
+ if(t&&"Quest"===t.type){const r={...t.metadata||{},consecutiveDoneAudits:0}
4180
+ 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()
4181
+ 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"}`})
4182
+ _=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
4183
  const S=C.localId||C.id
4138
4184
  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
4185
  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(g({success:!1,error:r instanceof Error?r.name:"unknown"}),r instanceof s.ZodError&&r.errors.length>0){const e=r.errors[0]
4186
+ 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
4187
  let t=e.message
4142
4188
  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
4189
  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 +4204,12 @@ const h=i[c]
4158
4204
  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
4205
  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
4206
  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:g,comment:m}=s,{enforceActiveTask:f}=await Promise.resolve().then(t.bind(t,3451)),y=await f(i,a,d,e.taskId)
4207
+ 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
4208
  if("errorResult"in y)return y.errorResult
4163
4209
  const{taskId:w}=y
4164
- p.info("Processing modify-file operations",{taskId:w,operationCount:g.length,comment:m})
4210
+ p.info("Processing modify-file operations",{taskId:w,operationCount:m.length,comment:g})
4165
4211
  const I=[],b=[],k=[],v=[],C=[]
4166
- for(const e of g){const t={path:e.path,documentId:e.documentId}
4212
+ for(const e of m){const t={path:e.path,documentId:e.documentId}
4167
4213
  switch(e.operationType){case"replace-string":I.push({...t,replacements:e.replaceString.replacements,mode:e.replaceString.mode})
4168
4214
  break
4169
4215
  case"insert-lines":b.push({...t,insertions:e.insertLines.insertions})
@@ -4174,15 +4220,15 @@ case"delete-string":v.push({...t,replacements:e.deleteString.patterns.map((e=>({
4174
4220
  break
4175
4221
  case"delete-lines":C.push({...t,lines:e.deleteLines.lines})}}const _=[]
4176
4222
  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:m+" [via modify-file: replace-string]"},i,a,c,l,p,u,h)
4223
+ 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
4224
  _.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:m+" [via modify-file: insert-lines]"},i,a,c,l,p,u,h)
4225
+ 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
4226
  _.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:m+" [via modify-file: replace-lines]"},i,a,c,l,p,u,h)
4227
+ 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
4228
  _.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:m+" [via modify-file: delete-string]"},i,a,c,l,p,u,h)
4229
+ 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
4230
  _.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:m+" [via modify-file: delete-lines]"},i,a,c,l,p,u,h)
4231
+ 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
4232
  _.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
4233
  let T="## Modify File Results\n\n"
4188
4234
  T+="**Summary:**\n",T+=`- **Total operation types:** ${_.length}\n`,T+=`- **Successful:** ${S}\n`,T+=`- **Failed:** ${q}\n\n`
@@ -4192,22 +4238,22 @@ const r=t(3306),n=t(6486),o=t(6651),s=t(8824)},7478(e,exports,t){"use strict"
4192
4238
  async function r(e,t,r){const n=r.startTimer("git_get_current_branch_duration")
4193
4239
  try{const o=(await e.status()).current
4194
4240
  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,m.getErrorMessage)(e)
4241
+ 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
4242
  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
4243
  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,m.getErrorMessage)(e)
4244
+ 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
4245
  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
4246
  try{const a=await r(e,o,s)
4201
4247
  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
4248
  if(!await n(e,t,o,s)){const e=`Branch '${t}' does not exist`
4203
4249
  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
4250
  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,m.getErrorMessage)(e)
4251
+ 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
4252
  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
4253
  try{let o,s=!0
4208
4254
  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
4255
  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,m.getErrorMessage)(e)
4256
+ 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
4257
  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
4258
  try{t.debug("Starting uncommitted changes check"),t.debug("Checking for uncommitted changes before merge"),Date.now()
4213
4259
  const o=await e.status()
@@ -4219,7 +4265,7 @@ t.debug("Uncommitted changes summary",{hasChanges:l,totalFiles:c,staged:s.length
4219
4265
  let d=""
4220
4266
  if(l){const e=[]
4221
4267
  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,m.getErrorMessage)(e)
4268
+ 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
4269
  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
4270
  var o=Object.getOwnPropertyDescriptor(t,r)
4225
4271
  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 +4279,42 @@ try{if(await n(e,t,s,i)){const e=`Branch '${t}' already exists`
4233
4279
  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
4280
  await e.checkoutBranch(t,o)
4235
4281
  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,m.getErrorMessage)(e)
4282
+ 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
4283
  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
4284
  try{const d=await r(e,i,a)
4239
4285
  if(d!==s&&await o(e,s,i,a),!await n(e,t,i,a)){const e=`Source branch '${t}' does not exist`
4240
4286
  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,m.getErrorMessage)(e)
4287
+ 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
4288
  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
4289
  try{const c=await r(e,s,i)
4244
4290
  if(c===t){const e=`Cannot delete current branch '${t}'`
4245
4291
  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
4292
  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
4293
  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,m.getErrorMessage)(e)
4294
+ 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
4295
  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
4296
  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,m.getErrorMessage)(e)
4297
+ 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
4298
  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
4299
  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
4300
  return t?t[1]:null},exports.switchToDefaultBranch=async function(e,t,r){const n=r.startTimer("git_switch_to_default_duration")
4255
4301
  try{const i=await s(e,t,r)
4256
4302
  if(!i.defaultBranch){const e="No default branch found"
4257
4303
  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,m.getErrorMessage)(e)
4304
+ 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
4305
  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
4306
  try{const o=await s(e,t,r),i=[]
4261
4307
  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
4308
  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,m.getErrorMessage)(e)
4309
+ 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
4310
  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
4311
  try{r.debug("Starting main branch change detection",{providedRevertCommitHash:t.substring(0,8),fullRevertCommitHash:t})
4266
4312
  const n=await e.revparse(["HEAD"])
4267
4313
  r.debug("Git state captured",{currentMainHash:n.substring(0,8),fullCurrentMainHash:n,revertCommitHash:t.substring(0,8),fullRevertCommitHash:t,hashesMatch:n===t})
4268
4314
  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,g.validateCommitHash)(e,t,r,"hasMainChangedSinceRevert-revert-validation")
4315
+ 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
4316
  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,g.validateCommitHash)(e,n,r,"hasMainChangedSinceRevert-head-validation")
4317
+ const i=await(0,m.validateCommitHash)(e,n,r,"hasMainChangedSinceRevert-head-validation")
4272
4318
  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
4319
  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
4320
  r.debug("Hash comparison shows difference, checking ancestor relationship",{currentMainHash:n.substring(0,8),revertCommitHash:t.substring(0,8),hashesEqual:!1})
@@ -4276,10 +4322,10 @@ let a=!1,c=0,l=null
4276
4322
  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
4323
  const o=await e.raw(["rev-list","--count",t+"..HEAD"])
4278
4324
  c=parseInt(o.trim(),10),a=!0
4279
- break}catch(e){l=e,r.debug("Ancestor check attempt failed",{attempt:n,error:(0,m.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"])
4325
+ 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
4326
  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
4327
  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,m.getErrorMessage)(e)
4328
+ 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
4329
  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
4330
  const n=await t.getToolRecordsByRequestId(e,"revert-request")
4285
4331
  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 +4334,7 @@ for(const t of n)if(r.debug("Examining tool record",{requestId:e,recordId:t.id,r
4288
4334
  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
4335
  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
4336
  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,m.getErrorMessage)(t)
4337
+ 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
4338
  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
4339
  try{if(!r.hasChanges)throw new p.ValidationError("No uncommitted changes to commit")
4294
4340
  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 +4343,7 @@ i.length>0?(n.debug("Staging files",{files:i.slice(0,10),total:i.length}),await
4297
4343
  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
4344
  n.debug("Commit message",{message:a.split("\n")[0]}),n.debug("Creating commit"),await e.commit(a)
4299
4345
  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,m.getErrorMessage)(e)
4346
+ 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
4347
  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
4348
  try{let c=Date.now()
4303
4349
  o.debug("Checking for user changes before tool operation",{toolName:r})
@@ -4314,8 +4360,8 @@ const h=`${u}\n\n${{...d,summary:`User changes detected before ${r}: ${d.summary
4314
4360
  o.debug("Committing user changes with message",{firstLine:h.split("\n")[0]})
4315
4361
  const p=[...d.unstagedFiles,...d.untrackedFiles]
4316
4362
  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 g=await l.revparse(["HEAD"])
4318
- return o.debug("User changes committed successfully before tool",{commitHash:g.substring(0,8),filesCommitted:d.totalFiles,toolName:r}),o.info("Successfully committed user changes before tool operation",{toolName:r,requestId:n.requestId,taskId:n.taskId,commitHash:g.substring(0,8),filesCommitted:d.totalFiles}),s.incrementCounter("git_pre_tool_user_changes_committed",1),s.recordValue("git_pre_tool_user_changes_files",d.totalFiles),i({success:!0,reason:"changes_committed"}),{userChangesCommitted:!0,commitHash:g,filesCommitted:d.totalFiles}}catch(e){const t=(0,m.getErrorMessage)(e)
4363
+ const m=await l.revparse(["HEAD"])
4364
+ 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
4365
  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
4366
  try{const o=t(3807).simpleGit(e),s=(await o.status()).not_added||[]
4321
4367
  for(const t of s)try{const o=y.join(e,t),s=f.statSync(o)
@@ -4324,27 +4370,31 @@ const t=e.reduce(((e,t)=>e+t.sizeMB),0)
4324
4370
  let r=`\n\n\u26a0\ufe0f **Performance Warning**: Large untracked files detected (${Math.round(t)} MB total) that may slow git operations:\n`
4325
4371
  for(const t of e.slice(0,5))r+=`- \`${t.path}\` (${t.sizeMB} MB)\n`
4326
4372
  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),g=t(3922),m=t(8824),f=u(t(9896)),y=u(t(6928))
4373
+ const h=t(3444),p=t(9860),m=t(3922),g=t(8824),f=u(t(9896)),y=u(t(6928))
4328
4374
  t(857)},7575(e,exports){"use strict"
4329
4375
  var t
4330
4376
  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,n,o){const s=o.child({tool:"plan_operations",operation:"update"})
4332
- try{const t=n.getDocumentClient(),r=await t.getDocument(e.planId)
4377
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleUpdatePlan=async function(e,t,o,s){const i=s.child({tool:"plan_operations",operation:"update"})
4378
+ try{const t=o.getDocumentClient(),r=await t.getDocument(e.planId)
4333
4379
  if(!r)return{content:[{type:"text",text:"\u274c Plan not found: "+e.planId}],isError:!0}
4334
- const o="Quest"===r.type
4335
- if("Plan"!==r.type&&!o)return{content:[{type:"text",text:`\u274c Document ${e.planId} is not a plan or quest (type: ${r.type})`}],isError:!0}
4336
- const i={}
4337
- void 0!==e.content&&(i.content=e.content),e.name&&(i.filename=e.name.replace(/\.md$/i,"")+".md")
4338
- const a=e.metadata||{},c=["criteria","tickIntervalSeconds","maxInFlight","maxPerDay","minIterations","status"].filter((e=>void 0!==a[e]))
4339
- if(c.length>0){if(!o)return{content:[{type:"text",text:`\u274c Metadata fields (${c.join(", ")}) are only valid on Quest documents. ${e.planId} is a Plan.`}],isError:!0}
4380
+ const s="Quest"===r.type
4381
+ 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}
4382
+ const a={}
4383
+ void 0!==e.content&&(a.content=e.content),e.name&&(a.filename=e.name.replace(/\.md$/i,"")+".md")
4384
+ const c=e.metadata||{},l=n.QUEST_METADATA_KEYS.filter((e=>void 0!==c[e]))
4385
+ 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}
4386
+ 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}
4387
+ 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
4388
  const t={...r.metadata||{}}
4341
- for(const e of c)t[e]=a[e]
4342
- i.metadata=t}if(void 0===i.content&&!i.filename&&!i.metadata)return{content:[{type:"text",text:"\u274c No changes supplied. Provide content, name, or quest metadata."}],isError:!0}
4343
- const l=await t.updateDocument(e.planId,i),d=l.localId||l.id
4344
- s.info("Plan/Quest updated",{planId:d,isQuest:o,changedMetadata:c})
4345
- const u=o?"Quest":"Plan",h=[]
4346
- return void 0!==i.content&&h.push("content"),i.filename&&h.push("filename="+l.filename),c.length>0&&h.push(`metadata(${c.join(", ")})`),{content:[{type:"text",text:`\u2705 **${u} Updated**\n\n**ID:** ${d}\n**Filename:** ${l.filename}\n**Changes:** ${h.join(", ")}\n**Updated:** `+new Date(l.updatedAt).toLocaleString()}]}}catch(e){return s.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}}}
4347
- const r=t(8824)},7613(e,exports,t){"use strict"
4389
+ for(const e of l)t[e]=c[e]
4390
+ 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}
4391
+ const d=r.metadata||{}
4392
+ if(d.isStub){const e=a.metadata??{...d}
4393
+ delete e.isStub,a.metadata=e}const u=await t.updateDocument(e.planId,a),h=u.localId||u.id
4394
+ i.info("Plan/Quest updated",{planId:h,isQuest:s,changedMetadata:l})
4395
+ const p=s?"Quest":"Plan",m=[]
4396
+ 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}}}
4397
+ const r=t(8824),n=t(3416)},7613(e,exports,t){"use strict"
4348
4398
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
4349
4399
  const r=t(6183),n=t(9072)
4350
4400
  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 +4578,7 @@ const r=t(4055)
4528
4578
  Object.defineProperty(exports,"ProjectID",{enumerable:!0,get(){return r.ProjectID}}),Object.defineProperty(exports,"ProjectIDFactory",{enumerable:!0,get(){return r.ProjectIDFactory}})
4529
4579
  const n=t(1791)
4530
4580
  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,m){const f=p.child({tool:"manage_files"})
4581
+ 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
4582
  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
4583
  if("errorResult"in b)return b.errorResult
4534
4584
  const{taskId:k}=b
@@ -4542,18 +4592,18 @@ case"delete-files":_.push(...e.deleteFiles.targets)
4542
4592
  break
4543
4593
  case"get-file-info":E.push({path:e.getFileInfo.path})}const S=[]
4544
4594
  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,m)
4595
+ 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
4596
  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,m)
4597
+ 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
4598
  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,m)
4599
+ const e=await(0,i.handleDeleteFiles)({taskId:k,operations:_,comment:w+" [via manage-files: delete-files]"},c,h,f,m,g)
4550
4600
  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,g)
4601
+ const t=await(0,o.handleGetFileInfo)({path:e.path},c,f,m)
4552
4602
  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
4603
  let x="## Manage Files Results\n\n"
4554
4604
  x+="**Summary:**\n",x+=`- **Total operation types:** ${S.length}\n`,x+=`- **Successful:** ${T}\n`,x+=`- **Failed:** ${P}\n\n`
4555
4605
  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}),g.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+""}),g.incrementCounter("manage_files_errors",1),{content:[{type:"text",text:"\u274c **Manage Files Failed:** "+(0,a.getErrorMessage)(e)}],isError:!0}}}
4606
+ 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
4607
  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
4608
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
4559
4609
  const r=t(6183),n=t(5303)
@@ -4578,8 +4628,8 @@ const r=t(5806),n=t(5715)
4578
4628
  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
4629
  async function r(e,t,r,n,o,s,a,l,d,u){const h=Date.now()
4580
4630
  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,g=c.localId
4582
- return l.info("Tool record created with IDs",{recordId:p,localRecordId:g,hasLocalId:!!c.localId,recordKeys:Object.keys(c),fullRecord:JSON.stringify(c)}),l.info("Created tool record for file operation: "+n,{taskId:e,projectId:r,path:o,recordId:p,localRecordId:g}),d.recordValue(u+"_tool_record_creation_time",Date.now()-h),d.incrementCounter(u+"_tool_record_creation_success",1),{recordId:p,localRecordId:g}}catch(t){d.incrementCounter(u+"_tool_record_creation_failure",1),d.recordValue(u+"_tool_record_creation_time",Date.now()-h)
4631
+ 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
4632
+ 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
4633
  const n=t instanceof Error?`${t.message} (${JSON.stringify(t)})`:t+""
4584
4634
  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
4635
  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 +4642,35 @@ if(o.workspaceManager){const t=o.workspaceManager.getCurrentContext(o.currentSes
4592
4642
  "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
4643
  let p=null
4594
4644
  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 g=1===n.length?`${s} in ${n[0]} (${i})`:`${s} in ${n.length} files (${i})`,m=(await d.commit(g)).commit
4596
- return l.info("Changes committed to git via shared multi-file utility",{commitMessage:g,filesCommitted:n.length,commitHash:m?.substring(0,8),previousCommitHash:p?.substring(0,8),toolRecordId:i,operationType:s}),u.incrementCounter(h+"_git_commit_success",1),u.recordValue(h+"_files_committed",n.length),{commitHash:m,previousCommitHash:p,filesCommitted:n,success:!0}}catch(e){const t=(0,d.getErrorMessage)(e)
4645
+ const m=1===n.length?`${s} in ${n[0]} (${i})`:`${s} in ${n.length} files (${i})`,g=(await d.commit(m)).commit
4646
+ 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
4647
  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
4648
  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,m
4649
+ let m,g
4600
4650
  l.debug("createFileOperationRecords called",{taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,operationType:o,path:s})
4601
4651
  try{const a=await r(e,t,n,o,s,i,c,l,u,h)
4602
- return g=a.recordId,m=a.localRecordId,l.info("Created tool record for file operation: "+o,{taskId:e,path:s,toolRecordId:g,localToolRecordId:m}),{toolRecordId:g,localToolRecordId:m}}catch(r){throw l.error("Failed to create tool record for file operation: "+o,{error:(0,d.getErrorMessage)(r),errorStack:r instanceof Error?r.stack:void 0,taskId:e,requestId:t,projectId:n||"<empty>",projectIdType:typeof n,path:s}),u.recordValue(h+"_record_creation_time",Date.now()-p),u.incrementCounter(h+"_record_creation_error",1),r}},exports.updateFileOperationRecords=async function(e,t,r,o,s,i,a,c,l,u,h,p,g){try{t&&h.info("Task record update skipped (task records removed): "+t,{taskId:e,path:o}),r&&await n(r,o,s,a,c,u,h,p,g)}catch(t){h.warn("Error updating tool record for operation: "+s,{error:(0,d.getErrorMessage)(t),taskId:e,normalizedPath:o,toolRecordId:r})}},exports.checkAndCommitUserMods=async function(e,t,r,n,o){if(!t.git)return{hadUserMods:!1}
4652
+ 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
4653
  try{let s=t.git
4604
4654
  if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
4605
4655
  "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
4656
  const t=await s.commit("[USER-MODS] Preserve user modifications before tool operation: "+e)
4607
4657
  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,g=null
4609
- try{let m=s.git
4658
+ let p,m=null
4659
+ try{let g=s.git
4610
4660
  if(s.workspaceManager){const t=s.workspaceManager.getCurrentContext(s.currentSessionId)
4611
4661
  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
- m=(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(m){i.info("commitToGit called with:",{taskId:e,recordId:r,localRecordId:n,hasLocalRecordId:!!n,localRecordIdType:typeof n,normalizedPath:t})
4662
+ 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
4663
  let a=!1,f=""
4614
- try{if(f=(await m.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 m.revparse(["--abbrev-ref","HEAD"]),n=await m.revparse(["HEAD"]),o=await m.revparse(["--show-toplevel"])
4664
+ 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
4665
  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
4666
  const a=r.trim(),c=s.getCurrentRequestId?s.getCurrentRequestId():null
4617
4667
  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(m){const r=await m.revparse(["HEAD"])
4619
- g=await(0,l.findPreviousCommit)(m,t,r),i.info(`Previous commit hash for ${t}: ${g||"none (new file)"}`,{taskId:e,gitInstancePath:f||"unknown",isWorktreeOperation:a,usingCorrectGitInstance:!0})}else i.warn("Git not available for previous commit detection: "+t,{taskId:e,reason:"no_git_instance"})}catch(e){i.warn(`Failed to find previous commit for ${t}:`,{error:(0,d.getErrorMessage)(e)})}const y=n?`[RECORD:${n}] ${o}`:o
4620
- await m.add(t),p=(await m.commit(y)).commit
4621
- try{const r=await m.revparse(["--abbrev-ref","HEAD"]),n=await m.revparse(["HEAD"])
4622
- i.info("Git repository status after commit:",{taskId:e,postCommitBranch:r.trim(),postCommitHash:n.trim().substring(0,8),commitAdvanced:n.trim()!==(g||""),targetFile:t}),p&&n.trim()!==p&&i.warn("Commit hash mismatch after commit",{taskId:e,expectedCommitHash:p,actualHeadHash:n.trim(),targetFile:t})}catch(e){i.warn("Failed to verify post-commit status:",{error:e instanceof Error?e.message:e+""})}i.info("Committed file changes to Git: "+t,{taskId:e,path:t,recordId:r,localRecordId:n,commitHash:p,previousCommitHash:g}),c.recordValue(u+"_git_commit_time",Date.now()-h),c.incrementCounter(u+"_git_commit_success",1)}else i.warn("No Git repository available, skipping commit",{taskId:e,path:t})
4623
- return{commitHash:p,previousCommitHash:g}}catch(r){return c.incrementCounter(u+"_git_commit_failure",1),c.recordValue(u+"_git_commit_time",Date.now()-h),i.warn("Failed to commit file changes to Git: "+t,{taskId:e,path:t,error:r instanceof Error?r.stack:r+""}),{commitHash:void 0,previousCommitHash:g}}},exports.commitMultipleFilesToGit=o,exports.handleMultiFileGitCommit=async function(e,t,r,n,s,i){const{logger:a,metricsPrefix:c,metrics:l}=s
4668
+ 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"])
4669
+ 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
4670
+ await g.add(t),p=(await g.commit(y)).commit
4671
+ try{const r=await g.revparse(["--abbrev-ref","HEAD"]),n=await g.revparse(["HEAD"])
4672
+ 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})
4673
+ 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
4674
  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
4675
  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
4676
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.addConnectionStatusInfo=function(e){return async(t,n,o)=>{try{const t=e.isInOfflineMode()
@@ -4642,10 +4692,10 @@ class o{static create(){return exports.ProjectIDFactory.create()}static fromStri
4642
4692
  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
4693
  if(e.includes("_")){const t=e.split("_")
4644
4694
  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:g,serverUrl:m,onSpawn:f}=e
4695
+ 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
4696
  try{const e=u||process.cwd(),o={...process.env,...(0,c.getOpencodeSpawnEnv)(e,(0,l.isDevMode)())}
4647
4697
  let y
4648
- if(g&&(o.ALCHEMY_INITIAL_BRANCH=g),r(u,"Spawn env setup",{agent:t,initialBranch:g||"none",sessionId:h||"new",attachMode:!!m}),y=m&&h&&d?["run","--attach",m,"--session",h,"--agent",t,d]:h&&d?["run","--session",h,"--agent",t,d]:d?["run","--agent",t,d]:["run","--agent",t],p){const e=y.findIndex((e=>e===d))
4698
+ 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
4699
  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
4700
  const w=(0,i.join)(u||process.cwd(),".alchemy_lab"),I=(0,i.join)(w,"spawn-stderr.log")
4651
4701
  let b
@@ -4666,18 +4716,18 @@ const u=s.getRequestClient(),h=await u.listRequests(d)
4666
4716
  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
4717
  const p=(0,n.extractArrayFromResponse)(h,{logger:c,operationName:"listRequests",defaultValue:[]})
4668
4718
  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 g=p.map((e=>`**${e.title}** (${e.id}) [${e.type}]\nStatus: ${e.status}\nType: ${e.type}\nCreated: ${new Date(e.createdAt).toLocaleString()}\nUpdated: ${new Date(e.updatedAt).toLocaleString()}\n`)).join("\n---\n"),m=`Found ${p.length} request${1===p.length?"":"s"}:`
4670
- return l({success:!0,requestCount:p.length}),{content:[{type:"text",text:`${m}\n\n${g}`}]}}catch(t){return c.error("Error listing requests",{args:e,error:t instanceof Error?t.stack:t+""}),l({success:!1,error:t instanceof Error?t.name:"unknown"}),{content:[{type:"text",text:"Error listing requests: "+(0,o.getErrorMessage)(t)}],isError:!0}}}
4719
+ 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"}:`
4720
+ 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
4721
  const r=t(9860),n=t(2960),o=t(8824)},8045(e,exports,t){"use strict"
4672
4722
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
4673
4723
  const r=t(6183),n=t(7456)
4674
4724
  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
4725
  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(),g=await p.getRequest(c)
4677
- if(!g)return u({success:!1,reason:"not_found"}),n("Request not found: "+c)
4678
- const m=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,f=t.git??(0,o.simpleGit)({baseDir:m,binary:t.gitBinary}),y="completed"===g.status,w="requests/"+c
4726
+ try{const i=e,{requestId:c,format:d="summary",path:h}=i,p=s.getRequestClient(),m=await p.getRequest(c)
4727
+ if(!m)return u({success:!1,reason:"not_found"}),n("Request not found: "+c)
4728
+ 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
4729
  let I,b
4680
- if(y){const e=g.metadata?.mergeBaseSha,t=g.metadata?.mergeCommitSha
4730
+ if(y){const e=m.metadata?.mergeBaseSha,t=m.metadata?.mergeCommitSha
4681
4731
  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
4732
  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
4733
  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 +4772,35 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
4722
4772
  var t={}
4723
4773
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
4724
4774
  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,g){const m=i.child({tool:"create_directory"}),f=Date.now()
4775
+ 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
4776
  let y,w,I=l.FileOperationPhase.VALIDATION
4727
4777
  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
4778
  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
4779
  if("errorResult"in v)return v.errorResult
4730
4780
  const{taskId:C}=v
4731
- m.info("Creating directory: "+u,{taskId:C,path:u,comment:h}),l.validateTaskIdFormat(C,m,p,b.metricsPrefix),r.getCurrentBranchContext&&await r.getCurrentBranchContext()
4781
+ g.info("Creating directory: "+u,{taskId:C,path:u,comment:h}),l.validateTaskIdFormat(C,g,p,b.metricsPrefix),r.getCurrentBranchContext&&await r.getCurrentBranchContext()
4732
4782
  const{normalizedPath:_,fullPath:E}=l.validateAndNormalizePath(u,r)
4733
4783
  I=l.FileOperationPhase.TASK_VALIDATION,p.incrementCounter("create_directory_phase",1,{phase:I})
4734
- const S=await l.validateTaskId(C,_,n,m,p,b.metricsPrefix),q=S?.requestId,T=await l.validateWorkItemStates(C,_,n,s,r,m,p,b.metricsPrefix),P=await l.autoPromoteTaskStatus(C,S.status,q,T.request?.status,_,n,s,m,p,b.metricsPrefix)
4735
- P.taskPromoted&&m.info(`Auto-promoted task ${C} (${S.title||"Untitled"}) to in_progress for file operation`,{taskId:C,taskTitle:S.title,previousStatus:S.status,newStatus:P.newTaskStatus,path:_}),P.requestPromoted&&m.info(`Auto-promoted request ${q} to in_progress for file operation`,{requestId:q,previousStatus:T.request?.status,newStatus:P.newRequestStatus,triggeringTaskId:C})
4736
- const x=await l.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:q,context:r,operation:"create-directory",logger:m,metrics:p,metricsPrefix:b.metricsPrefix})
4784
+ 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)
4785
+ 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})
4786
+ const x=await l.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:q,context:r,operation:"create-directory",logger:g,metrics:p,metricsPrefix:b.metricsPrefix})
4737
4787
  if(!x.success)throw Error(x.error)
4738
4788
  let j=!1
4739
4789
  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,m,p,b.metricsPrefix,g)
4790
+ 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
4791
  y=R,w=R,I=b.fileOperationPhase,p.incrementCounter("create_directory_phase",1,{phase:I})
4742
4792
  let $=j
4743
- if(!j){await a.default.mkdir(E,{recursive:!0}),m.info("Successfully created directory "+_)
4793
+ if(!j){await a.default.mkdir(E,{recursive:!0}),g.info("Successfully created directory "+_)
4744
4794
  try{const e=c.default.join(E,".gitkeep")
4745
- await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),$=!0,m.info("Created .gitkeep file for Git tracking")}catch(e){m.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),$=!1}}const O=Date.now()-f
4795
+ 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
4796
  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,m,p,b.metricsPrefix)
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,m,p,b.metricsPrefix)
4797
+ const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!j&&$?_+"/.gitkeep":_,F=await l.commitToGit(C,A,R,M,D,r,g,p,b.metricsPrefix)
4798
+ 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
4799
  const N=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
4750
4800
  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){m.error("Failed to create failure record for create directory operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,path:e.path})}const s=Date.now()-f
4752
- if(p.recordValue("create_directory_time",s),p.incrementCounter("create_directory_errors",1),m.error("Error creating directory:",{error:(0,h.getErrorMessage)(t),time:s}),(y||w)&&e.taskId){I=l.FileOperationPhase.RECORD_UPDATE_FAILURE
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,m,p,b.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(t,I,m,p,e,b)}}
4801
+ 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
4802
+ 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
4803
+ 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
4804
  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
4805
  function r(e){const t=[]
4756
4806
  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 +4809,11 @@ case"move-files":return"\u{1f4cb} Move Files"
4759
4809
  case"delete-files":return"\u{1f5d1}\ufe0f Delete Files"
4760
4810
  case"manage-files":return"\u{1f4c1} Manage Files"
4761
4811
  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:g,showDiff:m=!1,fileFilter:f}=e
4812
+ try{const{requestId:l,detailLevel:p="summary",taskId:m,showDiff:g=!1,fileFilter:f}=e
4763
4813
  if(!l)throw(0,o.createValidationError)("Request ID is required")
4764
4814
  if(!/^req[_\d].+$/.test(l))throw(0,o.createValidationError)(`Invalid request ID format: ${l}. Expected format: req_[26 chars] or req######`)
4765
- if(g&&!(0,a.isTaskRef)(g))throw(0,o.createValidationError)(`Invalid task ID format: ${g}. Expected req######+#NN (e.g. req000005#03), or short forms #01/01/1 which are expanded against the active request before this handler runs.`)
4766
- if(u.info("Getting file changes for request "+l,{detailLevel:p,taskId:g,showDiff:m}),!t.git)throw Error("Git integration not available in this context")
4815
+ 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.`)
4816
+ 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
4817
  const y=t.projectId
4768
4818
  let w
4769
4819
  c.setProjectId(y)
@@ -4772,7 +4822,7 @@ w={id:n.id||l,title:n.title||"Unknown Request",description:n.description||"No de
4772
4822
  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
4823
  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
4824
  let o=[]
4775
- try{g?(o=await e.getToolRecordsByTaskId(g),u.info(`Fetched ${o.length} records for task ${g}`)):(o=await e.getToolRecordsByRequestId(l),u.info(`Fetched ${o.length} records for request ${l}`))}catch(e){u.warn("Error fetching tool records: "+(0,i.getErrorMessage)(e)),o=[]}const s=await async function(e,t,o,s,a,c,l){let d="# File Operations - Detailed View\n\n"
4825
+ 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
4826
  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
4827
  let u=t.filter((e=>{const t=e.type
4778
4828
  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 +4836,10 @@ let r=0
4786
4836
  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
4837
  if(e&&e.trim()){const r=500,n=e.length
4788
4838
  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,m,t.git,u,f)
4839
+ 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
4840
  return h({success:!0,recordCount:o.length}),{content:[{type:"text",text:s}]}}{const e=c.getToolRecordClient()
4791
4841
  let n=[]
4792
- try{g?(n=await e.getToolRecordsByTaskId(g),u.info(`Fetched ${n.length} records for task ${g}`)):(n=await e.getToolRecordsByRequestId(l),u.info(`Fetched ${n.length} records for request ${l}`))}catch(e){u.warn("Error fetching tool records: "+(0,i.getErrorMessage)(e)),n=[]}const o=await async function(e,t){const n=new Map
4842
+ 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
4843
  let o=0
4794
4844
  for(const s of e){const e=s.type
4795
4845
  if(!["write-file","replace-in-files","move-files","delete-files","manage-files"].includes(e))continue
@@ -4871,16 +4921,16 @@ function r(e){const t=c[e]
4871
4921
  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
4922
  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
4923
  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,"_"),g=(0,i.getErrorMessage)(t),m=t instanceof Error?t.stack:void 0
4924
+ 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
4925
  try{const t=r(e),s={}
4876
4926
  let i,f
4877
4927
  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}: ${g.substring(0,100)}${g.length>100?"...":""}`
4928
+ let y=u.note||`Failed to execute ${e}: ${m.substring(0,100)}${m.length>100?"...":""}`
4879
4929
  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:g,errorStack:m,originalToolName:e,timestamp:(new Date).toISOString(),invalidIds:Object.keys(s).length>0?s:void 0,...a}}
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:g})
4930
+ 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}}
4931
+ 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
4932
  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:g}),t}}
4933
+ 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
4934
  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
4935
  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
4936
  else if(e&&"object"==typeof e)for(const t of Object.keys(e)){const n=e[t]
@@ -4905,13 +4955,13 @@ function r(e,t,r){const n=exports.ERROR_TYPE_PROPERTIES[e]||exports.ERROR_TYPE_P
4905
4955
  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
4956
  return{statusCode:e.statusCode,body:t}}if(e instanceof Error&&"ConnectionError"===e.name){const t=e
4907
4957
  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 g(e,t)},exports.createMcpProtocolError=function(e="MCP protocol error",t){return new m(e,t)},exports.isAppError=n,exports.errorToResponse=o,exports.isRetryableError=s
4958
+ 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
4959
  const i=t(7388)
4910
4960
  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
4961
  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
4962
  const o=exports.ERROR_TYPE_PROPERTIES[this.code]
4913
4963
  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 g extends a{constructor(e="File operation error",t){super(e,"FILE_OPERATION_ERROR",500,t)}}class m extends a{constructor(e="MCP protocol error",t){super(e,i.MCP_PROTOCOL_ERROR,500,t)}}exports.AppError=a,exports.NotFoundError=c,exports.ValidationError=l,exports.AuthenticationError=d,exports.AuthorizationError=u,exports.DatabaseError=h,exports.ServiceError=p,exports.FileOperationError=g,exports.McpProtocolError=m,exports.UnauthorizedError=d},8712(e,exports){"use strict"
4964
+ 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
4965
  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
4966
  const o=e.split("\n"),s=[],i=new Set
4917
4967
  let a=!1,c=""
@@ -4954,7 +5004,7 @@ if("string"==typeof r&&r.length>0)return`${e}: ${r}`}return"Unknown error (no re
4954
5004
  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
5005
  return t?`${parseInt(t[1],10)}.${{m:"minutes",h:"hours",d:"days",w:"weeks"}[t[2]]}.ago`:e}(a):void 0
4956
5006
  try{let a
4957
- if(i===await m(e,l,d))a=await e.log({file:t,maxCount:r,...u&&{"--since":u}})
5007
+ if(i===await g(e,l,d))a=await e.log({file:t,maxCount:r,...u&&{"--since":u}})
4958
5008
  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
5009
  try{const a=await e.raw(["log","--max-count="+r,"--pretty=format:%H|%an|%ad|%s","--date=iso",...u?["--since="+u]:[],i,"--",t])
4960
5010
  if(a&&a.trim()){const r=a.trim().split("\n").map((e=>{const[t,r,n,o]=e.split("|")
@@ -4977,26 +5027,26 @@ return t},o(e)},function(e){if(e&&e.__esModule)return e
4977
5027
  var t={}
4978
5028
  if(null!=e)for(var r=o(e),n=0;n<r.length;n++)"default"!==r[n]&&s(t,e,r[n])
4979
5029
  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"),g=Date.now()
4981
- try{const o=e,{path:a,limit:m,showDiff:f,showTraceability:y,branch:w,commit:I,since:b}=o
5030
+ 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()
5031
+ try{const o=e,{path:a,limit:g,showDiff:f,showTraceability:y,branch:w,commit:I,since:b}=o
4982
5032
  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
5033
  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
5034
  try{const r=await o.log({from:t,to:t,file:s,maxCount:1})
4985
5035
  if(!r.all||0===r.all.length)return{content:[{type:"text",text:`No commit found with hash ${t} for file ${e}`}]}
4986
5036
  const n=r.all[0],i=await o.diff([t+"^",t,"--",s])
4987
5037
  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:m,showDiff:f,showTraceability:y,branch:w}),await async function(e,t,n,o,s,i,a,c,h,g,m){try{const{normalizedPath:f,fullPath:y}=p.validateAndNormalizePath(e,a)
5038
+ 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
5039
  try{await l.access(y)}catch(e){throw Error("File not found: "+f)}const w=a.git
4990
5040
  if(!w)throw Error("Git is not available in this context")
4991
5041
  let I={branch:null,requestId:null,isMain:!0}
4992
5042
  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,g),k=`## File History: ${f} (Branch: ${s})\n\n`
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,g)}]}
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,g)}]}
5043
+ if(s)b=await r(w,f,t,n,o,s,i,c,h,m),k=`## File History: ${f} (Branch: ${s})\n\n`
5044
+ 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)}]}
5045
+ 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
5046
  {const e=await async function(e,t,n,o,s,i,a,c,l,d){const u=[],h=[]
4997
5047
  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),g=new Set(u.map((e=>e.hash))),m=p.filter((e=>!g.has(e.hash)))
4999
- return u.push(...m),p.length>0&&h.push("main"),u.sort(((e,t)=>new Date(t.date).getTime()-new Date(e.date).getTime())),{versions:u.slice(0,n),sources:h}}(w,f,t,n,o,I,i,c,h,g)
5048
+ 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)))
5049
+ 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
5050
  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
5051
  const v=b.length,C=Math.min(b.length,t)
5002
5052
  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 +5055,9 @@ for(let e=0;e<b.length;e++){const t=b[e]
5005
5055
  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
5056
  let r=0,n=0
5007
5057
  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()-m}),g.incrementCounter("file_history_total",1,{success:!0,type:"file",mode:s?"single-branch":"combined"}),{content:[{type:"text",text:k}]}}catch(e){throw e}}(a,m,f,y,w,b,t,n,i,s,g))}catch(e){const t=Date.now()-g
5058
+ 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
5059
  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)),g=a(t(7478)),{getCurrentBranch:m}=g},8849(e,exports,t){"use strict"
5060
+ 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
5061
  var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
5012
5062
  var o=Object.getOwnPropertyDescriptor(t,r)
5013
5063
  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 +5187,7 @@ let c
5137
5187
  try{const e=await fetch(`http://localhost:${I}/api/project-settings`)
5138
5188
  if(e.ok){const t=await e.json()
5139
5189
  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,g.partMeta)("inserted-prompt")},u=await fetch(l,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[d],...a?{agent:a}:{},...c?{model:c}:{}})})
5190
+ 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
5191
  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
5192
  if(!s)throw new u.ValidationError("No session identity available. Make sure you are running within an OpenCode session.")
5143
5193
  return(0,w.logSessionIdentity)(""+r,"identity",{sessionId:s,fromCliOrigin:!!o?.sessionId}),s}function a(e){const t=[],r=e.content||{}
@@ -5149,42 +5199,42 @@ if(!I)throw new u.ValidationError("API client not available")
5149
5199
  const{operation:v}=e
5150
5200
  k.info("Session message operation",{operation:v}),p.incrementCounter("session_message_operations",1,{operation:v})
5151
5201
  try{switch(v){case"send":if(!e.type)throw new u.ValidationError('send operation requires type ("question" or "report")')
5152
- return(0,g.withAlchemyKind)(await async function(e,t,r,c,d){const{type:h}=e
5202
+ return(0,m.withAlchemyKind)(await async function(e,t,r,c,d){const{type:h}=e
5153
5203
  if(!h)throw new u.ValidationError('send operation requires type ("question" or "report")')
5154
5204
  const p=c.getSessionMessageClient()
5155
5205
  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:g,priority:m,expiresInHours:f,relatesTo:w}=e
5157
- if(!p||!g?.question)throw new u.ValidationError("Question requires questionType and questionContent.question")
5206
+ 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
5207
+ if(!p||!m?.question)throw new u.ValidationError("Question requires questionType and questionContent.question")
5158
5208
  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
5209
  if(!e)throw new u.ValidationError("Could not find parent session. Make sure this session was spawned as a subagent.")
5160
5210
  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||g.options&&Array.isArray(g.options)))throw new u.ValidationError("Alternatives questions require options array")
5211
+ if(!("alternatives"!==p||m.options&&Array.isArray(m.options)))throw new u.ValidationError("Alternatives questions require options array")
5162
5212
  r.info("Creating question",{fromSessionId:I,toSessionId:b,questionType:p})
5163
- const k=await l.createQuestion({fromSessionId:I,toSessionId:b,questionType:p,question:g.question,options:g.options,context:g.context,allowMultiple:g.allowMultiple,priority:m,expiresInHours:f,...w?{relatesTo:w}:{}})
5213
+ 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
5214
  let v=""
5165
- if(b){const e=await n(I)??"agent",s={alchemy:{kind:"question-received",payload:{messageCode:k.messageCode,question:g.question,questionType:p,options:g.options,context:g.context,allowMultiple:g.allowMultiple,fromAgent:e,fromSessionId:I,priority:k.priority,expiresAt:k.expiresAt,...w?{relatesTo:w}:{}}}}
5215
+ 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
5216
  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
5217
  if(t.context&&r.push("**Context:** "+t.context),"alternatives"===t.questionType&&t.options){r.push(""),r.push("**Options:**")
5168
5218
  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:g,finish:f,relatesTo:w}=e
5219
+ 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
5220
  if(!h||!p)throw new u.ValidationError("Report requires status and summary")
5171
5221
  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
5222
  const t=await s(I,a,r)
5173
5223
  if(t)return r.info("Auto-resolved parent session",{parentSessionId:t}),t
5174
5224
  throw new u.ValidationError("Could not find parent session. Ensure this session was created with a parent link, or provide an explicit toSessionId.")})()
5175
5225
  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:g,...w?{relatesTo:w}:{}}),v=await n(I)??"agent",C={alchemy:{kind:"worker-report",payload:{status:h,summary:p,details:g,fromAgent:v,fromSessionId:I,...w?{relatesTo:w}:{}}}},_=await o(b,function(e,t="agent"){const r=e.content||{}
5177
- return(0,m.formatReportNotification)({messageCode:e.messageCode,status:r.reportStatus,summary:r.summary,details:r.details,fromSessionId:e.fromSessionId,senderAgent:t})}(k,v),t,r,C)
5226
+ 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||{}
5227
+ 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
5228
  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
5229
  throw new u.ValidationError(`Unknown message type: ${h}. Use "question" or "report".`)}(e,t,k,I,b),r("send",e))
5180
5230
  case"reply":if(!e.messageCode)throw new u.ValidationError("reply operation requires messageCode")
5181
- return(0,g.withAlchemyKind)(await async function(e,t,r,s,i){const{messageCode:c}=e
5231
+ return(0,m.withAlchemyKind)(await async function(e,t,r,s,i){const{messageCode:c}=e
5182
5232
  if(!c)throw new u.ValidationError("reply operation requires messageCode")
5183
5233
  const d=s.getSessionMessageClient()
5184
5234
  if(!d)throw new u.ValidationError("Session message client not available")
5185
5235
  if(c.startsWith("Q-")){const{text:s,selectedOptions:l,notes:u}=e,h=e.respondedBySessionId??i?.sessionId
5186
5236
  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}),g=h?await n(h)??"agent":"agent",m=p.content||{},f=p.response||{},y={alchemy:{kind:"question-answered",payload:{messageCode:p.messageCode,question:m.question,answer:f.text,selectedOptions:f.selectedOptions,notes:f.notes,answeredByAgent:g,answeredBySessionId:h}}},w=await o(p.fromSessionId,function(e){const t=e.content||{},r=e.response||{},n=["\u{1f4ec} **Your question has been answered!**","","**Question Code:** "+e.messageCode,"**Question:** "+t.question,"","---","**Answered by:** "+e.respondedBySessionId]
5237
+ 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
5238
  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
5239
  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
5240
  const e=await d.acknowledgeReport(c)
@@ -5199,21 +5249,21 @@ let l
5199
5249
  try{const e=I.getSessionMessageClient()
5200
5250
  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
5251
  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,g.withAlchemyKind)({content:[{type:"text",text:a?"Handoff auto-confirmed (auto-planner). Start-building has been queued \u2014 you can stop now.":'Handoff offered to user. STOP here and wait \u2014 the user will choose "Start Building" or "Keep Planning". You will receive their choice as a new message. Do NOT generate any further output until then.'}],isError:!1,...(0,g.alchemyMeta)({pendingAction:{kind:"plan-handoff",payload:{summary:t.summary,requestIds:t.requestIds,parentSessionId:o,fromSessionId:r,autoConfirmed:a}}})},"offer-handoff")}case"list":return(0,g.withAlchemyKind)(await async function(e,t,r,n,o){let{sessionId:s,messageType:i,direction:a,status:c,readStatus:l,reportStatus:h,limit:p,offset:g}=e
5203
- const m=n.getSessionMessageClient()
5204
- if(!m)throw new u.ValidationError("Session message client not available")
5252
+ 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
5253
+ const g=n.getSessionMessageClient()
5254
+ if(!g)throw new u.ValidationError("Session message client not available")
5205
5255
  if(!s){const e=o?.sessionId||f.sessionIdentity.getIdentity()?.sessionId
5206
5256
  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
5257
  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:g}
5258
+ const y={sessionId:s,direction:a,limit:p,offset:m}
5209
5259
  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 m.listMessages(y)
5260
+ const I=await g.listMessages(y)
5211
5261
  if(0===I.length)return{content:[{type:"text",text:"No messages found matching the criteria."}]}
5212
5262
  const b=[`Found ${I.length} message(s):\n`]
5213
5263
  for(const e of I)b.push("---\n"),b.push(d(e)),b.push("")
5214
5264
  return{content:[{type:"text",text:b.join("\n")}]}}(e.list||{},0,k,I,b),"list-messages")
5215
5265
  case"get":if(!e.messageCode)throw new u.ValidationError("get operation requires messageCode")
5216
- return(0,g.withAlchemyKind)(await async function(e,t,r){const{messageCode:n}=e
5266
+ return(0,m.withAlchemyKind)(await async function(e,t,r){const{messageCode:n}=e
5217
5267
  if(!n)throw new u.ValidationError("get operation requires messageCode")
5218
5268
  const o=r.getSessionMessageClient()
5219
5269
  if(!o)throw new u.ValidationError("Session message client not available")
@@ -5221,7 +5271,7 @@ t.debug("Getting message",{messageCode:n})
5221
5271
  const s=await o.getMessage(n)
5222
5272
  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
5273
  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),g=t(2272),m=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"
5274
+ 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
5275
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
5226
5276
  const r=t(6183),n=t(1281)
5227
5277
  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 +5297,12 @@ let l,d
5247
5297
  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
5298
  let u=0
5249
5299
  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="",g=null
5251
- if(0!==u?(h=!0,p="merge-tree-exit-code"):d&&d.trim()?(g=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch),g.hasConflictMarkers?(h=!0,p="conflict-parser-detected-markers",r.warn("Git exit code 0 but conflict parser found conflict markers - treating as conflict")):(h=!1,p="clean-merge-with-changes",r.info("Git exit code 0 and conflict parser found no markers - treating as clean merge",{hasOutput:!0,outputLength:d.length}))):(h=!1,p="clean-merge-no-changes"),r.info("FINAL conflict detection result (trusting Git exit codes)",{hasConflicts:h,exitCode:u,hasOutput:!!d.trim(),outputLength:d?d.length:0,conflictReason:p,method:"git-exit-code-primary",trustedGitExitCode:0===u}),!h)return{hasConflicts:!1,conflictedFiles:[],summary:"No conflicts detected (merge-tree clean)",resolutionInstructions:"",detectionMethod:"merge-tree-analysis",rawOutput:d}
5252
- !g&&d&&d.trim()&&(g=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch))
5253
- let m=[]
5254
- if(g&&g.filesParsed&&g.filesParsed.length>0)m=g.filesParsed.map((e=>({path:e,conflictType:"content",description:"Merge conflict detected"}))),r.debug("Successfully extracted conflict files from parsed content",{conflictedFilesCount:m.length,files:m.map((e=>e.path))})
5255
- else try{m=this.parseMergeTreeOutput(d,r),r.debug("Used fallback merge-tree parsing",{conflictedFilesCount:m.length})}catch(e){r.warn("Both conflict parsing methods failed",{parseError:e instanceof Error?e.message:e+""}),m=[{path:"<parsing failed>",conflictType:"content",description:"Git detected conflicts but parsing failed - manual inspection required"}]}return 0===m.length&&(r.warn("Git detected conflicts but no files could be determined - using fallback"),m=[{path:"<unknown files>",conflictType:"content",description:"Git detected conflicts but could not determine specific files"}]),{hasConflicts:!0,conflictedFiles:m,summary:m.length>0&&"<parsing failed>"!==m[0].path&&"<unknown files>"!==m[0].path?m.length+" file(s) have merge conflicts (detected by Git)":"Merge conflicts detected by Git (parsing details failed)",resolutionInstructions:this.generateMultiAgentInstructions(m,e.requestId,e.worktreePath,e.targetBranch),detectionMethod:"merge-tree-analysis",rawOutput:d,rawConflictContent:g?g.cleanContent:void 0}}catch(e){throw r.error("Pure multi-agent conflict detection failed",{error:e}),e}}parseMergeTreeOutput(e,t){const r=[]
5300
+ let h=!1,p="",m=null
5301
+ 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}
5302
+ !m&&d&&d.trim()&&(m=(0,o.parseConflictOutputWithContext)(d,e.requestId,e.sourceBranch,e.targetBranch))
5303
+ let g=[]
5304
+ 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))})
5305
+ 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
5306
  if(!e||!e.trim())return t.debug("Empty merge-tree output - no conflicts to parse"),[]
5257
5307
  let n
5258
5308
  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 +5359,23 @@ o+=`## Test 4: All commits containing "${n}" (not just merges)\n`,o+=`Found ${e?
5309
5359
  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
5360
  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
5361
  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:g}=e,m=!!d,f=void 0!==g?g:t,y={type:m?"document":"file",path:c,documentId:d,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,externalEditDebugInfo:{detectionRan:!1,reason:m?"Skipped: Document operation":n.git?"Pending":"Skipped: No Git context"}}
5362
+ 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
5363
  try{let t,o
5314
- if(m){t=await n.documentFileManager.getDocumentAsFile(d)
5364
+ if(g){t=await n.documentFileManager.getDocumentAsFile(d)
5315
5365
  const e=n.documentFileManager.getCachedDocumentInfo(d)
5316
5366
  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"),g=[]
5367
+ o=e.normalizedPath,t=e.fullPath,y.path=o}const s=await l.default.readFile(t,"utf8"),m=[]
5318
5368
  for(const t of p){const{old:n,new:o,match_mode:i="unique"}=t,a={old:n,new:o,success:!1}
5319
5369
  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
5370
  continue}const t=(0,h.findMatches)(s,n,f,100,e.path)
5321
5371
  if(a.matchesFound=t.length,0===t.length){a.error="No matches found"+(f?" (tried fuzzy matching)":""),a.success=!1
5322
5372
  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++):g.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
5373
+ 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
5374
  const b=[]
5325
- for(const e of g)for(const t of e.matches)b.push({match:t,newText:e.newText,repResult:e.repResult})
5375
+ for(const e of m)for(const t of e.matches)b.push({match:t,newText:e.newText,repResult:e.repResult})
5326
5376
  b.sort(((e,t)=>t.match.startPos-e.match.startPos))
5327
5377
  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"),m&&(n.documentFileManager.markForSync(d),await n.documentFileManager.syncDocument(d))),i&&(y.externalEditWarning=i),a&&(y.externalEditDebugInfo={detectionRan:!0,...a}),y.success=0===y.failedReplacements}catch(e){y.error=(0,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)
5378
+ 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
5379
  var o=Object.getOwnPropertyDescriptor(t,r)
5330
5380
  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
5381
  for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
@@ -5355,7 +5405,7 @@ const t=await u.autoPromoteTaskStatus(T,D.status,A,e.request?.status,$,o,i,k,c,"
5355
5405
  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
5406
  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
5407
  if(!n.success)throw Error(n.error)
5358
- Date.now(),N=!0}if(R.length>0&&A)try{await(0,g.validateRequestStatusForDocumentOperation)(A,i,k,c,"replace_in_files-documents")}catch(e){if(e instanceof p.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5408
+ 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
5409
  throw e}O=Date.now()
5360
5410
  const z=new Map
5361
5411
  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 +5414,7 @@ s.push(...r)}if(s.length>0){const o=(0,y.calculateReplacementRegion)(n,s,t.fullP
5364
5414
  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
5415
  const i=await(0,w.detectExternalEdits)(r.git,o,k)
5366
5416
  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,m.commitUserChangesBeforeToolOperation)(r.git,"replace_in_files",{requestId:A,taskId:T,workspaceManager:r.workspaceManager},k,c)
5417
+ const e=await(0,g.commitUserChangesBeforeToolOperation)(r.git,"replace_in_files",{requestId:A,taskId:T,workspaceManager:r.workspaceManager},k,c)
5368
5418
  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
5419
  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
5420
  C=L,Date.now(),O=Date.now(),_=u.FileOperationPhase.STRING_REPLACEMENT,c.incrementCounter("replace_in_files_phase",1,{phase:_})
@@ -5373,8 +5423,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
5423
  H.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&B.push(o.path)}Date.now(),O=Date.now()
5374
5424
  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
5425
  Date.now(),Date.now()
5376
- const V=H.filter((e=>e.success)).length,K=H.length-V,J=H.reduce(((e,t)=>e+t.successfulReplacements),0),Q=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})))
5377
- await s.updateToolRecord(C,{metadata:{path:$,status:0===K?"completed":"partial",operationCount:P.length,operations:Y,successfulFiles:Z,failedFiles:X,successfulReplacements:J,failedReplacements:Q,processingTime:Date.now()-v,userComment:j,...W.success&&W.commitHash&&{commitHash:W.commitHash,previousCommitHash:W.previousCommitHash||void 0}}})
5426
+ 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})))
5427
+ 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
5428
  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
5429
  let c="## Replace In Files - Batch Results\n\n"
5380
5430
  if(o.workspaceManager)try{const e=o.workspaceManager.getCurrentContext(o.currentSessionId)
@@ -5388,10 +5438,10 @@ if(s.length>0){c+="\n**Failed Replacement Details:**\n"
5388
5438
  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
5439
  l.length>0&&(c+=`\n**Document Changes:** ${l.length} modified document(s) synced back to tracking system.\n`)
5390
5440
  const d=o.workspaceManager?.consumeLargeFileWarning(o.currentSessionId)
5391
- return d&&(c+=d),c}(H,G,J,Q,r)
5392
- return{content:[{type:"text",text:ee}],isError:0===J,...(0,d.alchemyMeta)({kind:"replace-in-files",toolRecordId:C,failed:Q>0})}}catch(e){const t=Date.now()-v
5441
+ return d&&(c+=d),c}(H,G,K,J,r)
5442
+ 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
5443
  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),g=t(5003),m=t(7478),f=t(9949),y=t(9947),w=t(1318),I=t(8824)},9470(e,exports){"use strict"
5444
+ 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
5445
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")
5396
5446
  const t=e.trim()
5397
5447
  if(t.includes("-")){const r=t.split("-").map((e=>e.trim()))
@@ -5462,11 +5512,11 @@ if(!u)throw new r.ValidationError("Project ID is required for listing tasks with
5462
5512
  a.incrementCounter("list_tasks_attempts",1,{hasRequestId:!!i,hasFilters:Object.keys(d).length>0}),s.setProjectId(u)
5463
5513
  const h=s.getTaskClient(),p=d
5464
5514
  i&&(p.requestId=i),c.info("Listing tasks with filters",{projectId:u,taskFilters:p})
5465
- const g=await h.listTasks(p)
5466
- c.info("Raw tasks response data",{responseData:JSON.stringify(g)}),c.info("Tasks response structure",{type:typeof g,isArray:Array.isArray(g),hasData:null!=g,properties:g?Object.keys(g):[],dataPreview:g?JSON.stringify(g).substring(0,200)+"...":"null"})
5467
- let m=[]
5468
- g&&"object"==typeof g?"success"in g&&"data"in g?Array.isArray(g.data)?(m=g.data,c.info("Extracted tasks from success/data wrapper",{count:m.length})):g.data&&"object"==typeof g.data&&(m=[g.data],c.info("Extracted single task from success/data wrapper")):"data"in g?Array.isArray(g.data)?(m=g.data,c.info("Extracted tasks from data wrapper",{count:m.length})):g.data&&"object"==typeof g.data&&(m=[g.data],c.info("Extracted single task from data wrapper")):Array.isArray(g)?(m=g,c.info("Tasks response is direct array",{count:m.length})):(m=[g],c.info("Tasks response is single object")):(c.warn("Unexpected response format, using empty array",{responseType:typeof g}),m=[])
5469
- const f=m
5515
+ const m=await h.listTasks(p)
5516
+ 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"})
5517
+ let g=[]
5518
+ 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=[])
5519
+ const f=g
5470
5520
  if(c.info(`Retrieved ${f.length} tasks`,{count:f.length,requestId:i,projectId:u}),0===f.length){let e=""
5471
5521
  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
5522
  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")