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.
package/dist/index.js CHANGED
@@ -3,9 +3,9 @@ if(void 0!==r)return r.exports
3
3
  var module=s[t]={exports:{}}
4
4
  return o[t].call(module.exports,module,module.exports,e),module.exports}var t,r,n,o={184(e,exports,t){"use strict"
5
5
  function r(e,t,r,n,o={}){const s=d.default.resolve(e)
6
- if(x.has(s))return t.child({component:"mcp-server-registry"}).debug("Using existing server for path",{path:s}),x.get(s)
7
- const i=new R(s,t,r,n,o)
8
- return x.set(s,i),i}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
6
+ if(R.has(s))return t.child({component:"mcp-server-registry"}).debug("Using existing server for path",{path:s}),R.get(s)
7
+ const i=new x(s,t,r,n,o)
8
+ return R.set(s,i),i}var n,o=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
9
9
  var o=Object.getOwnPropertyDescriptor(t,r)
10
10
  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=[]
11
11
  for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
@@ -16,7 +16,7 @@ return s(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModu
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
17
  const c=t(3807),l=t(8909),d=a(t(6928)),u=a(t(9896)),h=a(t(1943)),p=t(9567),g=t(3444),m=t(7660),f=t(1253),y=i(t(7478)),w=t(4139),b=new Set,I=t(9860),k=t(1472),v=t(3328),C=t(8955),_=t(3217),E=t(5278),S=t(9060),T=t(8824),q=(0,g.createLogger)({serviceName:"stdout-capture",console:!1,logToFile:!1}),P=process.stdout.write,j=process.argv.includes("--stdio")||"true"===process.env.MCP_DIRECT_MODE
18
18
  !(0,g.isDebugToolsEnabled)()||j&&"true"!==process.env.DEBUG_STDOUT_CAPTURE||(process.stdout.write=function(e){try{return(0,g.isDebugToolsEnabled)()&&"true"===process.env.DEBUG_LOGGING?.toLowerCase()&&"string"==typeof e&&!e.trim().startsWith('{"jsonrpc":"2.0"')&&e.trim().length>0&&q.debug("Stdout output",{content:e.substring(0,100),length:e.length}),P.call(process.stdout,e)}catch(e){return q.error("Error in safeStdoutWrite",{error:e+""}),!0}})
19
- class R{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,w.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new m.ProjectContext(e,t),this.tokenManager=new f.TokenManager(t,e,{remoteServerUrl:n}),this.configManager=new S.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new p.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{listChanged:!0}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
19
+ class x{constructor(e,t,r,n,o={}){this.git=null,this.currentSSEConnection=null,this.stdioTransport=null,this.isInitializing=!1,this.isInitialized=!1,this.logger=t.child({component:"mcp-server"}),this.logger.info("Creating McpServer instance",{basePath:e,remoteServerUrl:n,hasExistingProjectId:!!o.existingProjectId}),this.basePath=e,this.alchemyPath=d.default.join(e,w.ALCHEMY_DIR_NAME),this.metrics=r,this.remoteServerUrl=n,this.existingProjectId=o.existingProjectId,this.gitBinary=(0,l.detectGitBinary)(),this.logger.info("Detected git binary",{gitBinary:this.gitBinary,version:(0,l.getGitVersion)()}),this.projectContext=new m.ProjectContext(e,t),this.tokenManager=new f.TokenManager(t,e,{remoteServerUrl:n}),this.configManager=new S.ConfigManager(t),this.logger.debug("Server paths initialized",{basePath:this.basePath,alchemyPath:this.alchemyPath}),this.server=new p.Server({name:"alchemy",version:"1.0.0"},{capabilities:{tools:{listChanged:!0}}}),this.metrics.incrementCounter("mcp_server_init_started",1),this.logger.info("Starting initialization for server instance"),this.initializationPromise=this.initialize()}get branchState(){if(!this.workspaceManager)return{currentBranch:null,activeRequestId:null,isOnMainBranch:!0}
20
20
  const e=this.workspaceManager.getCurrentContext("__server__")
21
21
  return{currentBranch:e.branchName,activeRequestId:e.requestId,isOnMainBranch:e.isMainBranch}}async updateBranchState(e,t){this.logger.debug("updateBranchState called - managed by WorkspaceManager",{branch:e,requestId:t})}async getCurrentBranchContext(){if(!this.workspaceManager)return{branch:null,requestId:null,isMain:!0}
22
22
  const e=this.workspaceManager.getCurrentContext("__server__")
@@ -93,8 +93,8 @@ const r=await y.switchToBranch(this.git,n.branchName,this.logger,this.metrics)
93
93
  r.success?this.logger.info("Successfully switched workspace to correct branch",{requestId:e,branchName:n.branchName}):this.logger.error("Failed to switch workspace to correct branch",{requestId:e,expectedBranch:n.branchName,error:r.message})}}catch(t){this.logger.error("Failed to verify workspace branch status",{requestId:e,workspacePath:n.basePath,error:t instanceof Error?t.message:t+""})}return this.logger.info("Switched to request context",{requestId:e,workspacePath:n.basePath,branchName:n.branchName}),{success:!0,message:"Switched to workspace for request "+e,worktreePath:n.basePath}}catch(t){const r=(0,T.getErrorMessage)(t)
94
94
  return this.logger.error("Failed to switch to request context",{requestId:e,error:r}),{success:!1,message:"Failed to switch context: "+r}}}async getEffectiveBasePath(e){if(!this.workspaceManager||!e)return this.basePath
95
95
  const t=await this.workspaceManager.getWorkspaceInfo(e)
96
- return t?.path||this.basePath}}exports.McpServer=R
97
- const x=new Map},213(e,exports,t){"use strict"
96
+ return t?.path||this.basePath}}exports.McpServer=x
97
+ const R=new Map},213(e,exports,t){"use strict"
98
98
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
99
99
  const r=t(6183),n=t(3707)
100
100
  exports.def={name:"quick_write",description:"WHEN TO USE: trivial single-file edits only. For multi-file or feature work, spawn a coder via subagent_operations.\n\nCreate or update a file or document. Wraps the change in a request/task workflow that auto-completes.\n\nUse 'path' for filesystem files or 'documentId' for tracked documents.\nSet append:true to add content to existing content.\n\n`content` accepts a single string OR an array of lines (joined with \\n). PREFER the array form for files containing brackets, quotes, or code-like syntax (TOML, JSON, Python, YAML) \u2014 sidesteps the JSON-escaping foot-gun where multi-line content with `[` or `{` confuses the parser.\n\nRequires: title, description, path/documentId, content.",schema:r.QuickWriteSchema,annotations:{title:"Quick Write",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler(e,t){return(0,n.handleQuickChange)(e,"write",t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},233(e,exports,t){"use strict"
@@ -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:g}=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:g,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:g,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:g,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(g,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:** ${g}\n**Version:** ${n.versionNumber}\n**Label:** ${e||"None"}\n**Summary:** ${t||"None"}\n**Created:** `+new Date(n.createdAt).toLocaleString()}]},"plan-snapshot")}case"restore":{const{versionNumber:e}=i,t=c.getDocumentClient(),r=await t.restoreToVersion(g,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:** ${g}\n**Restored to Version:** ${e}\n**Filename:** ${r.filename}\n\nThe plan has been successfully restored to version ${e}.`}]},"plan-restore")}case"set-active":{const e=t.projectId
179
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)
181
- if(!n)return{content:[{type:"text",text:"\u274c Plan not found: "+m}],isError:!0}
182
- 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})
178
+ const r=c.getDocumentClient(),n=await r.getDocument(g)
179
+ if(!n)return{content:[{type:"text",text:"\u274c Plan not found: "+g}],isError:!0}
180
+ if("Plan"!==n.type)return{content:[{type:"text",text:`\u274c Document ${g} is not a Plan (type: ${n.type}).`}],isError:!0}
181
+ const o=c.getProjectClient()
182
+ await o.updateProject(e,{activePlanId:g}),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"
@@ -326,21 +327,21 @@ return t},r(e)},function(e){if(e&&e.__esModule)return e
326
327
  var t={}
327
328
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
328
329
  return o(t,e),t}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
329
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerApiRoutes=async function(e,r,n,o){const s=n.child({component:"api"}),i=r.getTokenManager(),q=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com",P=new f.AuthenticationManager(i,n.child({component:"auth-manager"})),j=P.getTokenSynchronizer(),R=await P.getTokenString()||void 0
330
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerApiRoutes=async function(e,r,n,o){const s=n.child({component:"api"}),i=r.getTokenManager(),q=process.env.REMOTE_SERVER_URL||"https://api.alchemylabcode.com",P=new f.AuthenticationManager(i,n.child({component:"auth-manager"})),j=P.getTokenSynchronizer(),x=await P.getTokenString()||void 0
330
331
  n.debug("Token retrieved from authentication manager")
331
- const x=new b.ConnectionStatusManager(q,n.child({component:"connection-status-manager"}),o,{checkIntervalMs:3e4,timeoutMs:5e3}),M=new w.ProjectClient(q,n.child({component:"project-client"}),o,x,R)
332
+ const R=new b.ConnectionStatusManager(q,n.child({component:"connection-status-manager"}),o,{checkIntervalMs:3e4,timeoutMs:5e3}),M=new w.ProjectClient(q,n.child({component:"project-client"}),o,R,x)
332
333
  j.registerClient(M)
333
- const O=new k.TaskClient(q,n.child({component:"task-client"}),o,M,x,R)
334
+ const O=new k.TaskClient(q,n.child({component:"task-client"}),o,M,R,x)
334
335
  j.registerClient(O)
335
- const $=new v.FileOperationsClient(q,n.child({component:"file-client"}),o,M,R,x)
336
+ const $=new v.FileOperationsClient(q,n.child({component:"file-client"}),o,M,x,R)
336
337
  j.registerClient($)
337
- const D=new C.ProxyClient(q,n.child({component:"proxy-client"}),o,M,R,x)
338
+ const D=new C.ProxyClient(q,n.child({component:"proxy-client"}),o,M,x,R)
338
339
  j.registerClient(D)
339
- const A=new _.RequestClient(q,n.child({component:"request-client"}),o,M,R,x)
340
- A.setAuthToken(R),(0,d.isDebugToolsEnabled)()&&n.debug("Explicitly set token on RequestClient",{tokenPresent:!!R}),j.registerClient(A)
341
- const F=new E.DocumentClient(q,n.child({component:"document-client"}),o,M,R,x)
340
+ const A=new _.RequestClient(q,n.child({component:"request-client"}),o,M,x,R)
341
+ A.setAuthToken(x),(0,d.isDebugToolsEnabled)()&&n.debug("Explicitly set token on RequestClient",{tokenPresent:!!x}),j.registerClient(A)
342
+ const F=new E.DocumentClient(q,n.child({component:"document-client"}),o,M,x,R)
342
343
  j.registerClient(F)
343
- const N=new S.ToolRecordClient(q,n.child({component:"tool-record-client"}),o,M,R,x)
344
+ const N=new S.ToolRecordClient(q,n.child({component:"tool-record-client"}),o,M,x,R)
344
345
  j.registerClient(N)
345
346
  const z=new T.ApiClient(P,M,O,$,A,F,N,D,n.child({component:"api-client"})),L=a.default.Router();(0,h.registerAuthRoutes)(L,{projectClient:M,taskClient:O,fileClient:$,authManager:P,apiClient:z},i,n)
346
347
  const H=r.getContext();(0,p.registerConfigRoutes)(L,n,H.basePath),e.use("/api",L)
@@ -546,13 +547,13 @@ v.resolvedPath=_
546
547
  let E=!1
547
548
  try{E=(await p.default.stat(_)).isFile()}catch(e){const t=`Cannot access path ${_}: ${(0,I.getErrorMessage)(e)}`
548
549
  throw v.errors.push(t),Error(t)}const S=C.maxResults||50,T=C.caseSensitive||!1,q=C.useRegex||!1,P=C.fileExtension,j=C.searchIn||"content"
549
- let R=void 0!==C.contextLines?C.contextLines:0
550
- if(0>R?R=0:R>10&&(l.warn(`contextLines ${R} exceeds maximum of 10, clamping to 10`),R=10),!E&&!P)throw v.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,m.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
551
- let x,M=""
550
+ let x=void 0!==C.contextLines?C.contextLines:0
551
+ if(0>x?x=0:x>10&&(l.warn(`contextLines ${x} exceeds maximum of 10, clamping to 10`),x=10),!E&&!P)throw v.errors.push('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")'),(0,m.createValidationError)('File extension is required for directory search (use "*" for any extension, or formats like "ts", ".ts", "*.ts")')
552
+ let R,M=""
552
553
  if(E)M="*"
553
554
  else if("*"===P)M="*"
554
- else if(P){let e=P;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),M=e.startsWith(".")?e:"."+e}try{x=q?T?RegExp(n):RegExp(n,"i"):T?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${q?"regex":"search"} pattern: ${(0,I.getErrorMessage)(e)}`
555
- throw v.errors.push(t),(0,m.createValidationError)(t)}if(v.patternInfo={needle:n,regex:x.toString(),caseSensitive:T,fileExtension:P,normalizedExtension:M},!E)try{const e=Date.now(),t=await p.default.readdir(_,{withFileTypes:!0}),r=[],n=[]
555
+ else if(P){let e=P;(e.startsWith("*.")||e.startsWith("*"))&&(e=e.substring(1)),M=e.startsWith(".")?e:"."+e}try{R=q?T?RegExp(n):RegExp(n,"i"):T?RegExp(o(n)):RegExp(o(n),"i")}catch(e){const t=`Invalid ${q?"regex":"search"} pattern: ${(0,I.getErrorMessage)(e)}`
556
+ throw v.errors.push(t),(0,m.createValidationError)(t)}if(v.patternInfo={needle:n,regex:R.toString(),caseSensitive:T,fileExtension:P,normalizedExtension:M},!E)try{const e=Date.now(),t=await p.default.readdir(_,{withFileTypes:!0}),r=[],n=[]
556
557
  for(const e of t)e.isDirectory()?r.push(e.name):e.isFile()&&n.push(e.name)
557
558
  v.initialScan={totalEntries:t.length,directories:r,files:n,firstFewFiles:n.slice(0,10),scanTime:Date.now()-e},v.phases.directoryListingTime=v.initialScan.scanTime}catch(e){const t="Failed to scan directory contents: "+(0,I.getErrorMessage)(e)
558
559
  v.errors.push(t),l.error(t)}const O=E?"file":"directory"
@@ -574,7 +575,7 @@ o.errors.push(r),n.error(r)}return{matches:i,totalFiles:1}}(e,t,l,s,i,u)
574
575
  const m={path:e,filesProcessed:0,filesMatched:0,subdirectories:0,errors:[]}
575
576
  try{const{filesCount:n,fileMatchesCount:c,subdirCount:d,subdirStats:h}=await r(e,t,g,a,o,s,0,m,l,u)
576
577
  return m.filesProcessed=n,m.filesMatched=c,m.subdirectories=d,i.directoryStats.push(m),h&&h.length>0&&i.directoryStats.push(...h),s.info("performLocalSearch completed",{totalFiles:n,matchesFound:g.length,directories:d+1}),{matches:g,totalFiles:n}}catch(t){const r="Error in performLocalSearch: "+(0,I.getErrorMessage)(t)
577
- return m.errors.push(r),i.directoryStats.push(m),i.errors.push(r),s.error(r,{error:t instanceof Error?t.stack:t+"",searchPath:e}),{matches:g,totalFiles:m.filesProcessed}}}(_,x,{maxResults:S,fileExtension:M,searchIn:j,isFile:E,contextLines:R},M,l,v)
578
+ 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:j,isFile:E,contextLines:x},M,l,v)
578
579
  D=e.matches,A=e.totalFiles
579
580
  const t=1e3
580
581
  D.length>0&&D.length<=t?(D.sort(((e,t)=>void 0!==e.modifiedTime&&void 0!==t.modifiedTime?t.modifiedTime-e.modifiedTime:void 0!==e.modifiedTime&&void 0===t.modifiedTime?-1:void 0===e.modifiedTime&&void 0!==t.modifiedTime?1:0)),l.info(`Sorted ${D.length} matches by modification time (newest first)`)):D.length>t&&l.info(`Skipped sorting ${D.length} matches (exceeds hard cap of ${t} for performance)`),F=D.length,D.length>S&&(D=D.slice(0,S),l.info(`Limited results to ${S} (from ${F} total matches)`)),D.forEach((e=>{e.relativePath=function(e,t){const r=h.default.relative(e,t)
@@ -584,7 +585,7 @@ let N,z=""
584
585
  try{if(t.workspaceManager){const e=t.workspaceManager.getCurrentContext(t.currentSessionId)
585
586
  e.branchName&&!e.permanentBranch&&(z=e.isMainBranch?` (searched on main branch: ${e.branchName})`:` (searched on request branch: ${e.branchName}${e.requestId?" for "+e.requestId:""})`)}}catch(e){l.debug("Could not get branch context",{error:e}),z=" (branch context unavailable)"}l.debug("Search diagnostic information",{diagnostic:v})
586
587
  const L="content"===j?"content":"filename"===j?"filenames":"content and filenames"
587
- if(F>D.length?(N=`Found ${F} results for "${n}" (searching ${L})`,g&&(N+=" in "+g),P&&(N+=" with extension "+P),N+=`${z}. Showing first ${D.length}:\n\n`):(N=`Found ${D.length} results for "${n}" (searching ${L})`,g&&(N+=" in "+g),P&&(N+=" with extension "+P),N+=z+":\n\n"),D.length>0)if(R>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
588
+ 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(x>0){const{filenameMatches:e,mergedGroups:t}=function(e,t){const r=e.filter((e=>"filename"===e.matchType)),n=e.filter((e=>"content"===e.matchType))
588
589
  if(0===n.length)return{filenameMatches:r,mergedGroups:[]}
589
590
  const o=new Map
590
591
  for(const e of n){const t=o.get(e.file)||[]
@@ -592,7 +593,7 @@ t.push(e),o.set(e.file,t)}const i=[]
592
593
  for(const[e,r]of o.entries()){r.sort(((e,t)=>e.line-t.line))
593
594
  let e=[r[0]]
594
595
  for(let n=1;n<r.length;n++){const o=e[e.length-1],a=r[n],c=o.line+t
595
- a.line-t>c+1?(i.push(s(e,t)),e=[a]):e.push(a)}e.length>0&&i.push(s(e,t))}return{filenameMatches:r,mergedGroups:i}}(D,R),r=[]
596
+ a.line-t>c+1?(i.push(s(e,t)),e=[a]):e.push(a)}e.length>0&&i.push(s(e,t))}return{filenameMatches:r,mergedGroups:i}}(D,x),r=[]
596
597
  e.forEach((e=>{r.push(e.relativePath+" [filename match]")})),t.forEach((e=>{const t=[]
597
598
  e.lines.forEach((e=>{e.isMatch?t.push(`> ${e.lineNumber}: ${e.content}`):t.push(` ${e.lineNumber}: ${e.content}`)})),r.push(`${e.relativePath}:\n${t.join("\n")}`)})),N+=r.join("\n\n")}else N+=await async function(e){const t=e.filter((e=>"filename"===e.matchType)),r=e.filter((e=>"content"===e.matchType)),n=[]
598
599
  t.length>0&&t.forEach((e=>{n.push(e.relativePath+" [filename match]")}))
@@ -723,15 +724,15 @@ if(r)r.sessionId!==e&&((0,m.logSessionIdentity)(n,"_meta-session-switch",{prevSe
723
724
  else{const t=await(0,u.getServerUrl)(o,k)
724
725
  h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}j={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})
725
726
  h.sessionIdentity.setCurrentCallOrigin(j)
726
- const R=j?.sessionId||S?.sessionId
727
+ const x=j?.sessionId||S?.sessionId
727
728
  if(o?.workspaceManager){q=Date.now()
728
729
  try{const e=await(0,u.getServerUrl)(o,k)
729
- e&&s&&await o.workspaceManager.ensureReadonlyBranchIfNeeded(e,n,s,R)}catch(e){k.debug("Error during workspace check",{error:(0,d.getErrorMessage)(e)})}Date.now()}const x=o?{...o,currentSessionId:R??"__server__"}:null,M=`${Date.now()}-${Math.random().toString(36).slice(2,10)}`,O=e=>{const{getActionServerBaseUrl:r}=t(9414)
730
+ e&&s&&await o.workspaceManager.ensureReadonlyBranchIfNeeded(e,n,s,x)}catch(e){k.debug("Error during workspace check",{error:(0,d.getErrorMessage)(e)})}Date.now()}const R=o?{...o,currentSessionId:x??"__server__"}:null,M=`${Date.now()}-${Math.random().toString(36).slice(2,10)}`,O=e=>{const{getActionServerBaseUrl:r}=t(9414)
730
731
  fetch(r()+"/api/mcp/tool-call-event",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:e,callId:M}),signal:AbortSignal.timeout(500)}).catch((()=>{}))}
731
732
  let $
732
733
  O("start")
733
734
  try{if(P){(0,y.preNormalize)(n,l),await(0,w.expandTaskRefsInArgs)(l,s,j?.sessionId,k),l=(0,f.resolveSchema)(P).parse(l)
734
- const t=e.params?._meta?.progressToken,r=c?.sendNotification,o={context:x,apiClient:s,logger:i,metrics:a,mcpServer:I,cliOrigin:j,progressToken:t,sendNotification:r}
735
+ const t=e.params?._meta?.progressToken,r=c?.sendNotification,o={context:R,apiClient:s,logger:i,metrics:a,mcpServer:I,cliOrigin:j,progressToken:t,sendNotification:r}
735
736
  $=await P.handler(l,o)}else k.info(`Tool ${n} not found, returning negative response`),$={content:[{type:"text",text:`The tool '${n}' does not exist.`}]}}finally{O("end")}return Date.now(),Date.now(),T({tool:n,success:!0}),$}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"})
736
737
  let r="Unknown error"
737
738
  return r=t instanceof b.ZodError?function(e,t){return 1===e.issues.length?n(e.issues[0],t):e.issues.map((e=>n(e,t))).join("; ")}(t,l):(0,d.getStructuredErrorMessage)(t),{content:[{type:"text",text:"Error: "+r}],isError:!0}}var g,E})),k.info("Tools registration complete")}
@@ -1044,7 +1045,27 @@ const n=this.isOffline()
1044
1045
  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
1045
1046
  const e=this.online,t=await this.performHealthCheck()
1046
1047
  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
1047
- 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"
1048
+ 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"
1049
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuestSetCriteriaStatuses=async function(e,t,o,s,i){const a=s.child({tool:"quest_set_criteria_statuses"})
1050
+ try{if(!t.projectId)return{content:[{type:"text",text:"\u274c No project context available."}],isError:!0}
1051
+ const r=o.getDocumentClient(),s=await r.getDocument(e.questId)
1052
+ if(!s)return{content:[{type:"text",text:"\u274c Quest not found: "+e.questId}],isError:!0}
1053
+ if("Quest"!==s.type)return{content:[{type:"text",text:`\u274c Document ${e.questId} is not a quest (type: ${s.type}).`}],isError:!0}
1054
+ const c=s.metadata||{},l=c.status||n.QUEST_STATUS_OPEN
1055
+ 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}
1056
+ const d=Array.isArray(c.criteria)?c.criteria:[]
1057
+ 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}
1058
+ const u=new Map(d.map((e=>[e.id,e]))),h=e.updates.map((e=>e.id)).filter((e=>!u.has(e)))
1059
+ if(h.length>0){const e=d.map((e=>`"${e.id}"`)).join(", ")
1060
+ 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]))),g=d.map((e=>{const t=p.get(e.id)
1061
+ if(!t)return e
1062
+ const r={...e,status:t.status}
1063
+ return void 0!==t.evidence&&(r.evidence=t.evidence),r})),m={...c,criteria:g}
1064
+ await r.updateDocument(e.questId,{metadata:m}),i.incrementCounter("quest_set_criteria_statuses_total",1,{updatedCount:e.updates.length+""})
1065
+ const f=s.localId||s.id,y=g.filter((e=>"verified"===e.status)).length,w=e.updates.map((e=>{const t=u.get(e.id)
1066
+ return`- ${e.id}: ${e.status}${e.evidence?` (evidence: ${e.evidence})`:""}${t?.description?" \u2014 "+t.description:""}`}))
1067
+ return a.info("quest_set_criteria_statuses processed",{questId:f,updatedCount:e.updates.length,verifiedAfter:y,totalCriteria:g.length}),{content:[{type:"text",text:`\u2705 **Criteria updated (${y}/${g.length} verified)**\n\nQuest **${f}**:\n`+w.join("\n")+(y===g.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}}}
1068
+ const r=t(8824),n=t(3416)},1725(e,exports,t){"use strict"
1048
1069
  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
1049
1070
  if(!t||!r)return
1050
1071
  const a=t.getSessionMessageClient()
@@ -1077,7 +1098,7 @@ if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
1077
1098
  if(!u)return s.warn("Blocked spawn: request already has active workers",{requestId:d,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId))}),{content:[{type:"text",text:`\u274c Cannot spawn: Request ${d} already has ${r.length} active worker(s): ${e}\n\nOptions:\n\u2022 Use \`useExistingSession: "${r[0].opencodeSessionId}"\` to send work to the existing session\n\u2022 Use \`allowParallel: true\` if you really need multiple workers on the same request`}],isError:!0}
1078
1099
  E=`\u26a0\ufe0f Warning: Request ${d} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,s.warn("Spawning parallel subagent for request with existing active workers",{requestId:d,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){s.debug("Failed to check for existing workers",{error:(0,I.getErrorMessage)(e)})}let T,q,P=l
1079
1100
  d&&(T="requests/"+d,r(t,"Setting initialBranch for agent",{agent:c,requestId:d,initialBranch:T,agentRequestContextMode:p||"undefined"}),P="readonly"===p?`Working on request ${d} (READONLY mode - you cannot modify files, only explore and report).\n\n${l}`:`Working on request ${d}.\n\n${l}`)
1080
- let j,R=!1
1101
+ let j,x=!1
1081
1102
  if(h){if(q=h,s.info("Using existing session for spawn",{sessionId:q,requestId:d}),!g)throw new m.ValidationError("Could not determine OpenCode server URL")
1082
1103
  try{let e
1083
1104
  try{const t=await fetch(`http://localhost:${S}/api/project-settings`)
@@ -1086,7 +1107,7 @@ if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
1086
1107
  e={providerID:t,modelID:n.join("/")}}}}catch{}j=await o({apiClient:i,fromSessionId:a?.sessionId,toSessionId:q,body:P,requestId:d,logger:s})
1087
1108
  const t=n(P,j),r=`${g.replace(/\/$/,"")}/session/${q}/prompt_async`,l={alchemy:{kind:"agent-delegation",payload:{body:P,fromSessionId:a?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...d?{requestId:d}:{},...j?{instructionCode:j}:{}}}},u=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:t,metadata:l}],...c?{agent:c}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
1088
1109
  if(!u.ok){const e=await u.text().catch((()=>"Unknown error"))
1089
- throw Error(`Failed to send to existing session: ${u.status} ${e}`)}s.info("Prompt sent to existing session",{sessionId:q,agent:c})}catch(e){throw Error("Failed to use existing session: "+(0,I.getErrorMessage)(e))}}else{R=!0,r(t,"Creating session via spawn-session endpoint")
1110
+ throw Error(`Failed to send to existing session: ${u.status} ${e}`)}s.info("Prompt sent to existing session",{sessionId:q,agent:c})}catch(e){throw Error("Failed to use existing session: "+(0,I.getErrorMessage)(e))}}else{x=!0,r(t,"Creating session via spawn-session endpoint")
1090
1111
  const h=v;(0,b.logSessionIdentity)("subagent_operations.spawn","_meta",{parentSessionId:h})
1091
1112
  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)})
1092
1113
  if(!g.ok){const e=await g.text().catch((()=>"Unknown error"))
@@ -1104,10 +1125,10 @@ if(e.ok){const t=(await e.json()).find((e=>"user"===e.info?.role)),i=t?.parts.fi
1104
1125
  if(t&&i){const e={...i,metadata:{...i.metadata||{},alchemy:{kind:"agent-delegation",payload:n}}},c=`${s}/session/${r}/message/${t.info.id}/part/${i.id}`,l=await fetch(c,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),signal:AbortSignal.timeout(5e3)})
1105
1126
  if(l.ok)return void o.info("Tagged initial delegation message",{sessionId:r,messageId:t.info.id,partId:i.id,attempt:a})
1106
1127
  const d=await l.text().catch((()=>"unknown"))
1107
- o.warn("PATCH initial delegation failed",{sessionId:r,status:l.status,body:d.slice(0,200)})}}}catch{}await new Promise((e=>setTimeout(e,500)))}o.warn("Timed out tagging initial delegation; message will appear as plain user bubble",{sessionId:r,attempts:a})}({serverUrl:I,sessionId:y,payload:{body:P,fromSessionId:a?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...d?{requestId:d}:{},...j?{instructionCode:j}:{}},logger:s})}catch(e){throw Error("Failed to spawn subagent: "+(0,I.getErrorMessage)(e))}}let x=E
1108
- x+=h?`Prompt sent to existing session ${q}.`:`Background ${c} subagent spawned successfully.`,d&&(x+="\nWorking on: "+d),j&&(x+=`\nInstruction code: ${j} (the specialist will cite this on their reports/questions via relatesTo)`),x+="\n\nThe subagent is now working independently. You can continue with other tasks.","coder"===c&&(x+="\n\nIf this work has shifted or expanded your area of expertise, update your specialization summary with `update_specialization`.")
1128
+ o.warn("PATCH initial delegation failed",{sessionId:r,status:l.status,body:d.slice(0,200)})}}}catch{}await new Promise((e=>setTimeout(e,500)))}o.warn("Timed out tagging initial delegation; message will appear as plain user bubble",{sessionId:r,attempts:a})}({serverUrl:I,sessionId:y,payload:{body:P,fromSessionId:a?.sessionId,fromAgent:w.sessionIdentity.getIdentity()?.agentType,...d?{requestId:d}:{},...j?{instructionCode:j}:{}},logger:s})}catch(e){throw Error("Failed to spawn subagent: "+(0,I.getErrorMessage)(e))}}let R=E
1129
+ R+=h?`Prompt sent to existing session ${q}.`:`Background ${c} subagent spawned successfully.`,d&&(R+="\nWorking on: "+d),j&&(R+=`\nInstruction code: ${j} (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`.")
1109
1130
  const M=!!q&&"unknown"!==q&&"spawning"!==q
1110
- return{content:[{type:"text",text:x}],...(0,_.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:M?q:void 0,agentType:c,requestId:d||void 0,description:e.title||l.slice(0,50)||c,...j?{instructionCode:j}:{}}),...j?{instructionCode:j}:{}}}async function i(e,t,r,s,i,a,c){const l=await(0,y.getServerUrl)(r,s)
1131
+ return{content:[{type:"text",text:R}],...(0,_.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:M?q:void 0,agentType:c,requestId:d||void 0,description:e.title||l.slice(0,50)||c,...j?{instructionCode:j}:{}}),...j?{instructionCode:j}:{}}}async function i(e,t,r,s,i,a,c){const l=await(0,y.getServerUrl)(r,s)
1111
1132
  if(!l)throw new m.ValidationError("Could not determine OpenCode server URL")
1112
1133
  if(s.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),i)try{const t=c?.sessionId
1113
1134
  if(t){const r=i.getCLISessionClient()
@@ -1591,10 +1612,10 @@ f.info("Initial branch context",{initialBranch:S.branch,initialRequestId:S.reque
1591
1612
  const T=[]
1592
1613
  for(const e of u){const{normalizedPath:t,fullPath:n}=l.validateAndNormalizePath(e.source,r),{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(e.destination,r)
1593
1614
  T.push({source:t,destination:o,fullSource:n,fullDestination:s})}I=l.FileOperationPhase.TASK_VALIDATION,g.incrementCounter("move_files_phase",1,{phase:I})
1594
- const q=await l.validateTaskId(E,T[0].source,n,f,g,k.metricsPrefix),P=q?.requestId,j=await l.validateWorkItemStates(E,T[0].source,n,s,r,f,g,k.metricsPrefix),R=await l.autoPromoteTaskStatus(E,q.status,P,j.request?.status,T[0].source,n,s,f,g,k.metricsPrefix)
1595
- R.taskPromoted&&f.info(`Auto-promoted task ${E} (${q.title||"Untitled"}) to in_progress for file operations`,{taskId:E,taskTitle:q.title,previousStatus:q.status,newStatus:R.newTaskStatus,operationCount:u.length}),R.requestPromoted&&f.info(`Auto-promoted request ${P} to in_progress for file operations`,{requestId:P,previousStatus:j.request?.status,newStatus:R.newRequestStatus,triggeringTaskId:E})
1596
- const x=await l.ensureCorrectWorkspaceContext({taskPromoted:R.taskPromoted,requestId:P,context:r,operation:"move-files",logger:f,metrics:g,metricsPrefix:k.metricsPrefix})
1597
- if(!x.success)throw Error(x.error)
1615
+ const q=await l.validateTaskId(E,T[0].source,n,f,g,k.metricsPrefix),P=q?.requestId,j=await l.validateWorkItemStates(E,T[0].source,n,s,r,f,g,k.metricsPrefix),x=await l.autoPromoteTaskStatus(E,q.status,P,j.request?.status,T[0].source,n,s,f,g,k.metricsPrefix)
1616
+ x.taskPromoted&&f.info(`Auto-promoted task ${E} (${q.title||"Untitled"}) to in_progress for file operations`,{taskId:E,taskTitle:q.title,previousStatus:q.status,newStatus:x.newTaskStatus,operationCount:u.length}),x.requestPromoted&&f.info(`Auto-promoted request ${P} to in_progress for file operations`,{requestId:P,previousStatus:j.request?.status,newStatus:x.newRequestStatus,triggeringTaskId:E})
1617
+ const R=await l.ensureCorrectWorkspaceContext({taskPromoted:x.taskPromoted,requestId:P,context:r,operation:"move-files",logger:f,metrics:g,metricsPrefix:k.metricsPrefix})
1618
+ if(!R.success)throw Error(R.error)
1598
1619
  let M={hadUserMods:!1,userModsCommitHash:void 0}
1599
1620
  if(r.git)try{f.debug("[MOVE-FILES] Checking for user changes before move operations")
1600
1621
  const e=await(0,h.commitUserChangesBeforeToolOperation)(r.git,"move-files",{requestId:P,taskId:E,workspaceManager:r.workspaceManager},f,g)
@@ -1632,7 +1653,7 @@ exports.def={name:"quick_manage",description:"WHEN TO USE: trivial single-file e
1632
1653
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildTaskEndpoint=function(e,t,r){const n=r?"/"+r.replace(/^\//,""):""
1633
1654
  return`/api/projects/${e}/tasks/${encodeURIComponent(t)}${n}`}},2462(e,exports,t){"use strict"
1634
1655
  Object.defineProperty(exports,"__esModule",{value:!0})
1635
- const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),p=t(5459),g=t(4805),m=t(260),f=t(2283),y=t(4165),w=t(7834),b=t(9373),I=t(6111),k=t(700),v=t(1535),C=t(7257),_=t(9230),E=t(4150),S=t(6473),T=t(6309),q=t(4921),P=t(8850),j=t(3556),R=t(1391),x=t(6315),M=t(7713),O=t(6252),$=t(213),D=t(7250),A=t(2425),F=t(1540),N=t(5767),z=t(4973),L=t(509),H=t(7613),B=t(8456),U=t(3322),G=t(5247),W=t(8849),V=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(p.def),(0,r.registerTool)(g.def),(0,r.registerTool)(m.def),(0,r.registerTool)(f.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(b.def),(0,r.registerTool)(I.def),(0,r.registerTool)(k.def),(0,r.registerTool)(v.def),(0,r.registerTool)(E.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(q.def),(0,r.registerTool)(P.def),(0,r.registerTool)(j.def),(0,r.registerTool)(R.def),(0,r.registerTool)(x.def),(0,r.registerTool)(M.def),(0,r.registerTool)(O.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(z.def),(0,r.registerTool)(L.def),(0,r.registerTool)(H.def),(0,r.registerTool)(B.def),(0,r.registerTools)(U.metaDefs),(0,r.registerTools)(G.testingDefs),(0,r.registerTools)(W.checkingDefs),(0,r.registerTools)(V.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
1656
+ const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),p=t(5459),g=t(4805),m=t(260),f=t(2283),y=t(4165),w=t(7834),b=t(9373),I=t(6111),k=t(700),v=t(1535),C=t(7257),_=t(9230),E=t(4150),S=t(6473),T=t(6309),q=t(4921),P=t(8850),j=t(3556),x=t(1391),R=t(6315),M=t(7713),O=t(6252),$=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),G=t(8456),W=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)(g.def),(0,r.registerTool)(m.def),(0,r.registerTool)(f.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(b.def),(0,r.registerTool)(I.def),(0,r.registerTool)(k.def),(0,r.registerTool)(v.def),(0,r.registerTool)(E.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(q.def),(0,r.registerTool)(P.def),(0,r.registerTool)(j.def),(0,r.registerTool)(x.def),(0,r.registerTool)(R.def),(0,r.registerTool)(M.def),(0,r.registerTool)(O.def),(0,r.registerTool)($.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(z.def),(0,r.registerTool)(L.def),(0,r.registerTool)(H.def),(0,r.registerTool)(B.def),(0,r.registerTool)(U.def),(0,r.registerTool)(G.def),(0,r.registerTools)(W.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"
1636
1657
  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"
1637
1658
  async function r(e,t,r){if(v.has(r)&&C>=t){if(0===t)return 0
1638
1659
  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]"
@@ -2186,50 +2207,50 @@ const{taskId:q}=T
2186
2207
  if(y.info("Replacing strings across files and documents",{taskId:q,operationCount:_.length,comment:E}),!_||0===_.length)throw new u.ValidationError("At least one operation is required")
2187
2208
  const P=_.filter((e=>e.path)),j=_.filter((e=>e.documentId))
2188
2209
  y.info("Operation breakdown",{fileOperations:P.length,documentOperations:j.length})
2189
- const R=[]
2210
+ const x=[]
2190
2211
  for(const e of P){const{normalizedPath:t,fullPath:n}=d.validateAndNormalizePath(e.path,r)
2191
- R.push({type:"file",path:t,fullPath:n,replacements:e.replacements,mode:e.mode||"unique"})}const x=[]
2212
+ x.push({type:"file",path:t,fullPath:n,replacements:e.replacements,mode:e.mode||"unique"})}const R=[]
2192
2213
  if(j.length>0&&!r.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
2193
- for(const e of j)x.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
2194
- if(x.length>0&&r.apiClient){const e=x.map((e=>e.documentId))
2214
+ for(const e of j)R.push({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode||"unique"})
2215
+ if(R.length>0&&r.apiClient){const e=R.map((e=>e.documentId))
2195
2216
  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}
2196
2217
  throw e}}k=d.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
2197
- const M=R.length>0?R[0].path:"document-operation",O=await d.validateTaskId(q,M,o,y,c,v.metricsPrefix),$=O?.requestId
2218
+ const M=x.length>0?x[0].path:"document-operation",O=await d.validateTaskId(q,M,o,y,c,v.metricsPrefix),$=O?.requestId
2198
2219
  let D=null
2199
- R.length>0&&$&&(D=await d.validateWorkItemStates(q,R[0].path,o,i,r,y,c,v.metricsPrefix))
2220
+ x.length>0&&$&&(D=await d.validateWorkItemStates(q,x[0].path,o,i,r,y,c,v.metricsPrefix))
2200
2221
  let A={taskPromoted:!1,requestPromoted:!1}
2201
- R.length>0&&$&&D&&(A=await d.autoPromoteTaskStatus(q,O.status,$,D.request?.status,R[0].path,o,i,y,c,v.metricsPrefix),A.taskPromoted&&y.info("Auto-promoted task to in_progress for replace-strings operation",{taskId:q,requestId:$,previousStatus:O.status,newStatus:A.newTaskStatus,triggeringOperation:"replace-strings"}))
2222
+ x.length>0&&$&&D&&(A=await d.autoPromoteTaskStatus(q,O.status,$,D.request?.status,x[0].path,o,i,y,c,v.metricsPrefix),A.taskPromoted&&y.info("Auto-promoted task to in_progress for replace-strings operation",{taskId:q,requestId:$,previousStatus:O.status,newStatus:A.newTaskStatus,triggeringOperation:"replace-strings"}))
2202
2223
  const F=await d.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:$,context:r,operation:"replace-strings",logger:y,metrics:c,metricsPrefix:v.metricsPrefix})
2203
2224
  if(!F.success)throw Error(F.error)
2204
- if(R.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:R.length,workspaceBasePath:r.workspaceManager?.getCurrentContext(r.currentSessionId).basePath})
2205
- for(let e=0;e<R.length;e++){const t=R[e],n=P[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,r)
2206
- R[e]={...t,path:o,fullPath:s}}}if(x.length>0&&$)try{await(0,h.validateRequestStatusForDocumentOperation)($,i,y,c,"replace-strings-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2225
+ if(x.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:x.length,workspaceBasePath:r.workspaceManager?.getCurrentContext(r.currentSessionId).basePath})
2226
+ for(let e=0;e<x.length;e++){const t=x[e],n=P[e],{normalizedPath:o,fullPath:s}=d.validateAndNormalizePath(n.path,r)
2227
+ x[e]={...t,path:o,fullPath:s}}}if(R.length>0&&$)try{await(0,h.validateRequestStatusForDocumentOperation)($,i,y,c,"replace-strings-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2207
2228
  throw e}k=d.FileOperationPhase.RECORD_CREATION,c.incrementCounter("replace_strings_phase",1,{phase:k})
2208
- const N=[...R.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...x.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:z}=await d.createFileOperationRecords(q,$,r.projectId,v.recordType,M,{operationCount:_.length,fileOperations:R.length,documentOperations:x.length,operations:N,userComment:E},o,s,y,c,v.metricsPrefix,f)
2209
- if(b=z,I=z,k=v.fileOperationPhase,c.incrementCounter("replace_strings_phase",1,{phase:k}),R.length>0&&r.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
2229
+ const N=[...x.map((e=>({type:"file",path:e.path,replacements:e.replacements,mode:e.mode}))),...R.map((e=>({type:"document",documentId:e.documentId,replacements:e.replacements,mode:e.mode})))],{toolRecordId:z}=await d.createFileOperationRecords(q,$,r.projectId,v.recordType,M,{operationCount:_.length,fileOperations:x.length,documentOperations:R.length,operations:N,userComment:E},o,s,y,c,v.metricsPrefix,f)
2230
+ if(b=z,I=z,k=v.fileOperationPhase,c.incrementCounter("replace_strings_phase",1,{phase:k}),x.length>0&&r.git)try{y.debug("[REPLACE-STRINGS] Checking for user changes before replace operations")
2210
2231
  const e=await(0,p.commitUserChangesBeforeToolOperation)(r.git,"replace-strings",{requestId:$,taskId:q,workspaceManager:r.workspaceManager},y,c)
2211
- e.userChangesCommitted&&(y.debug("[REPLACE-STRINGS] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),y.info("User changes committed before replace-strings operation",{taskId:q,fileOperationsCount:R.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){y.debug("[REPLACE-STRINGS] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),y.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:q,fileOperationsCount:R.length,error:e instanceof Error?e.message:e+""})}y.debug("[REPLACE-STRINGS] Proceeding with file operations",{fileCount:R.length})
2232
+ e.userChangesCommitted&&(y.debug("[REPLACE-STRINGS] User changes committed before replace operations",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),y.info("User changes committed before replace-strings operation",{taskId:q,fileOperationsCount:x.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){y.debug("[REPLACE-STRINGS] Pre-tool commit failed, continuing with replacements",{error:e instanceof Error?e.message:e+""}),y.warn("Pre-tool user changes commit failed, continuing with replace operation",{taskId:q,fileOperationsCount:x.length,error:e instanceof Error?e.message:e+""})}y.debug("[REPLACE-STRINGS] Proceeding with file operations",{fileCount:x.length})
2212
2233
  const L=[]
2213
2234
  let H=0,B=0
2214
- for(const e of R){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2235
+ for(const e of x){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2215
2236
  try{if(await l.default.access(e.fullPath),!(await l.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
2216
2237
  const r=await l.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await n(r,e.replacements,e.mode)
2217
- 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 x){const t={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
2238
+ 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}
2218
2239
  try{const o=await r.documentFileManager.getDocumentAsFile(e.documentId),s=r.documentFileManager.getCachedDocumentInfo(e.documentId)
2219
2240
  t.filename=s?.filename
2220
2241
  const i=await l.default.readFile(o,"utf8"),{newContent:a,results:c}=await n(i,e.replacements,e.mode)
2221
- 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(x.length>0)try{for(const e of x){const t=L.find((t=>t.documentId===e.documentId))
2222
- 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(q,R,L,B,{operationType:"Replace strings",toolRecordId:I,successField:"successfulReplacements",logger:y,metrics:c,metricsPrefix:"replace_strings"},r),G=d.processMultiFileOperationResults(L,"successfulReplacements"),{successfulOperations:W,failedOperations:V,totalSuccessfulChanges:K,overallSuccess:J,successfulFiles:Q,failedFiles:Y}=G
2223
- try{await s.updateToolRecord(I,{metadata:{path:R.length>0?R[0].path:"document:"+x[0]?.documentId,status:J?"completed":"failed",error:J?void 0:V+" operations failed",totalOperations:L.length,successfulFiles:Q,failedFiles:Y,operations:N,totalSuccessfulReplacements:K,totalFailedReplacements:H,operationsWithChanges:B,processingTime:Date.now()-w,userComment:E,...R.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:J?`String replacement completed: ${W}/${L.length} operations successful${R.length>0?" (committed to git)":""}`:`String replacement partially failed: ${V}/${L.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}d.formatMultiFileToolResponse("String Replacement",{successfulOperations:W,failedOperations:V,totalSuccessfulChanges:K,overallSuccess:J,successfulFiles:Q,failedFiles:Y},U,F)
2242
+ 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))
2243
+ 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(q,x,L,B,{operationType:"Replace strings",toolRecordId:I,successField:"successfulReplacements",logger:y,metrics:c,metricsPrefix:"replace_strings"},r),G=d.processMultiFileOperationResults(L,"successfulReplacements"),{successfulOperations:W,failedOperations:V,totalSuccessfulChanges:Q,overallSuccess:K,successfulFiles:J,failedFiles:Y}=G
2244
+ try{await s.updateToolRecord(I,{metadata:{path:x.length>0?x[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,...x.length>0&&U.success&&U.commitHash&&{commitHash:U.commitHash,previousCommitHash:U.previousCommitHash||void 0}},note:K?`String replacement completed: ${W}/${L.length} operations successful${x.length>0?" (committed to git)":""}`:`String replacement partially failed: ${V}/${L.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}d.formatMultiFileToolResponse("String Replacement",{successfulOperations:W,failedOperations:V,totalSuccessfulChanges:Q,overallSuccess:K,successfulFiles:J,failedFiles:Y},U,F)
2224
2245
  let Z="## String Replacement Results\n\n"
2225
2246
  if(r.workspaceManager){const e=r.workspaceManager.getCurrentContext(r.currentSessionId)
2226
- e.permanentBranch||(Z+=`**Branch:** \`${e.branchName}\`\n\n`)}if(Z+="**Summary:**\n",Z+=`- **Files processed:** ${W+V}\n`,Z+=`- **Successful operations:** ${W}\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]
2247
+ e.permanentBranch||(Z+=`**Branch:** \`${e.branchName}\`\n\n`)}if(Z+="**Summary:**\n",Z+=`- **Files processed:** ${W+V}\n`,Z+=`- **Successful operations:** ${W}\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]
2227
2248
  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"
2228
- 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:** ${W}\n`,Z+=`- **Failed:** ${V}\n`,Z+=`- **Total Replacements:** ${K} successful, ${H} failed\n\n`,Z+="**Detailed Results:**\n\n"
2249
+ 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:** ${W}\n`,Z+=`- **Failed:** ${V}\n`,Z+=`- **Total Replacements:** ${Q} successful, ${H} failed\n\n`,Z+="**Detailed Results:**\n\n"
2229
2250
  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"
2230
- for(const t of e.replacements.filter((e=>!e.success)))Z+=` - "${t.old_str}" \u2192 "${t.new_str}": ${t.error}\n`}Z+="\n"}}x.length>0&&(Z+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
2251
+ 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")
2231
2252
  const X=Date.now()-w
2232
- return y.info("Replace strings operation completed",{duration:X,success:J,totalOperations:L.length,successfulOperations:W,failedOperations:V}),c.incrementCounter("replace_strings_total",1,{success:J}),{content:[{type:"text",text:Z}],isError:!J}}catch(t){const r=Date.now()-w
2253
+ return y.info("Replace strings operation completed",{duration:X,success:K,totalOperations:L.length,successfulOperations:W,failedOperations:V}),c.incrementCounter("replace_strings_total",1,{success:K}),{content:[{type:"text",text:Z}],isError:!K}}catch(t){const r=Date.now()-w
2233
2254
  if(y.error("Replace strings operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await s.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,m.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"String replacement failed: "+(0,m.getErrorMessage)(t)})}catch(e){}return c.incrementCounter("replace_strings_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Replace Strings Failed:** "+(0,m.getErrorMessage)(t)}],isError:!0}}}
2234
2255
  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"
2235
2256
  var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
@@ -2273,7 +2294,7 @@ var m=t(6539)
2273
2294
  Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return m.ClientFactory}})
2274
2295
  const f=t(6539)
2275
2296
  exports.default={ClientFactory:f.ClientFactory}},3416(e,exports){"use strict"
2276
- 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"
2297
+ 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"
2277
2298
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleGetTaskInformation=async function(e,t,i,a,c){const l=a.child({tool:"get_task_information"})
2278
2299
  l.info("Getting task information",{args:e})
2279
2300
  const d=c.startTimer("tool_handler_duration")
@@ -2482,11 +2503,11 @@ try{await b.updateTaskStatus(P,"canceled"),f.info("Canceled task after operation
2482
2503
  j?f.warn("File operation completed with partial failures",{requestId:q}):f.info("File operation completed successfully"),f.debug("Completing task")
2483
2504
  try{await(0,a.handleCompleteTask)({taskId:P,summary:`Executed ${t} operation for quick fix: ${v}${j?" (partial success)":""}`},u,h,p,g),f.info("Task completed successfully",{taskId:P})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:P,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
2484
2505
  try{await b.updateTaskStatus(P,"completed"),f.info("Task completed via direct updateTaskStatus call",{taskId:P})}catch(e){return f.error("Direct task completion ALSO failed - task may be stuck in in_progress",{taskId:P,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0,operationType:t,isDocumentOperation:!!_.documentId}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but task completion failed.\n\n**Request:** ${q}\n**Task:** ${P}\n**Issue:** Could not mark task as completed - it remains in 'in_progress' state\n\nThe ${t} operation was successful, but we couldn't automatically complete the task. Please use the complete-task tool manually with taskId: ${P}\n\nError: `+(e instanceof Error?e.message:e+"")}],isError:!0}}}f.debug("Completing request")
2485
- const R=j?`Quick change completed with partial success: ${v}. Some replacements failed - see details below.`:"Quick change completed: "+v,x=j?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2506
+ const x=j?`Quick change completed with partial success: ${v}. Some replacements failed - see details below.`:"Quick change completed: "+v,R=j?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2486
2507
  let M=!1
2487
- try{const e=await(0,c.handleCompleteRequest)({requestId:q,summary:R,acceptanceEvidence:[{evidence:x}],testVerification:void 0},u,h,p,g,m)
2508
+ try{const e=await(0,c.handleCompleteRequest)({requestId:q,summary:x,acceptanceEvidence:[{evidence:R}],testVerification:void 0},u,h,p,g,m)
2488
2509
  if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:q,error:e.content[0].text})
2489
- else{try{await w.updateRequest(q,{status:"completed",completionSummary:R}),f.info("Request finalized to completed",{requestId:q})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:q,error:(0,d.getErrorMessage)(e)})}M=!0,f.info("Request completed successfully",{requestId:q})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:q,error:e instanceof Error?e.message:e+""})}if(!M)try{f.info("Attempting direct request completion via API",{requestId:q}),await w.updateRequest(q,{status:"completed",completionSummary:R}),M=!0,f.info("Request completed successfully via direct API call",{requestId:q})}catch(e){return f.error("Direct request completion also failed",{requestId:q,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${q}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const O=Date.now()-y
2510
+ else{try{await w.updateRequest(q,{status:"completed",completionSummary:x}),f.info("Request finalized to completed",{requestId:q})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:q,error:(0,d.getErrorMessage)(e)})}M=!0,f.info("Request completed successfully",{requestId:q})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:q,error:e instanceof Error?e.message:e+""})}if(!M)try{f.info("Attempting direct request completion via API",{requestId:q}),await w.updateRequest(q,{status:"completed",completionSummary:x}),M=!0,f.info("Request completed successfully via direct API call",{requestId:q})}catch(e){return f.error("Direct request completion also failed",{requestId:q,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${q}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const O=Date.now()-y
2490
2511
  f.info("Quick fix completed",{requestId:q,duration:O,hasPartialFailure:j})
2491
2512
  const $=(0,n.readAlchemyMeta)(C)?.toolRecordId
2492
2513
  let D
@@ -2580,9 +2601,9 @@ const E={toolName:"write_file",operationName:"write",fileOperationPhase:d.FileOp
2580
2601
  try{const n=e
2581
2602
  let{path:m,documentId:S,content:T,format:q,append:P,comment:j}=n
2582
2603
  Array.isArray(T)&&(T=T.join("\n"))
2583
- const{enforceActiveTask:R}=await Promise.resolve().then(t.bind(t,3451)),x=await R(r,o,f,e.taskId)
2584
- if("errorResult"in x)return x.errorResult
2585
- const{taskId:M}=x,O=!!S,$=!!m
2604
+ const{enforceActiveTask:x}=await Promise.resolve().then(t.bind(t,3451)),R=await x(r,o,f,e.taskId)
2605
+ if("errorResult"in R)return R.errorResult
2606
+ const{taskId:M}=R,O=!!S,$=!!m
2586
2607
  b.info("Writing content to "+(O?"document":"file"),{taskId:M,filePath:$?m:void 0,documentId:O?S:void 0,contentLength:"string"==typeof T?T.length:JSON.stringify(T).length,format:q,append:P,comment:j})
2587
2608
  let D,A,F,N="",z=!1,L=!1
2588
2609
  const H=$?m:void 0
@@ -2596,21 +2617,21 @@ let W=null
2596
2617
  $&&G&&(W=await d.validateWorkItemStates(M,B,o,i,r,b,y,E.metricsPrefix))
2597
2618
  let V={taskPromoted:!1,requestPromoted:!1}
2598
2619
  $&&G&&W&&(V=await d.autoPromoteTaskStatus(M,U.status,G,W.request?.status,B,o,i,b,y,E.metricsPrefix),V.taskPromoted&&b.info("Auto-promoted task to in_progress for file operation",{taskId:M,requestId:G,previousStatus:U.status,newStatus:V.newTaskStatus,triggeringOperation:"write_file"}))
2599
- const K=await d.ensureCorrectWorkspaceContext({taskPromoted:V.taskPromoted,requestId:G,context:r,operation:"write_file",logger:b,metrics:y,metricsPrefix:E.metricsPrefix,requireRequestContext:$})
2600
- if(!K.success)throw Error(K.error)
2601
- if(K.switched&&b.info("Workspace context successfully established",{requestId:G,branchName:K.branchName,operation:"write_file"}),$&&H){const e=d.validateAndNormalizePath(H,r)
2620
+ const Q=await d.ensureCorrectWorkspaceContext({taskPromoted:V.taskPromoted,requestId:G,context:r,operation:"write_file",logger:b,metrics:y,metricsPrefix:E.metricsPrefix,requireRequestContext:$})
2621
+ if(!Q.success)throw Error(Q.error)
2622
+ if(Q.switched&&b.info("Workspace context successfully established",{requestId:G,branchName:Q.branchName,operation:"write_file"}),$&&H){const e=d.validateAndNormalizePath(H,r)
2602
2623
  D=e.normalizedPath,A=e.fullPath,N=A
2603
2624
  try{await c.default.access(A),L=!0}catch{L=!1,z=!0}b.debug("Path validated with correct workspace context",{rawPath:H,normalizedPath:D,fullPath:A,workspaceBasePath:r.workspaceManager?.getCurrentContext(r.currentSessionId).basePath})}if(O&&G)try{await(0,h.validateRequestStatusForDocumentOperation)(G,i,b,y,"write_file-document")}catch(e){if(e instanceof u.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
2604
2625
  throw e}_=d.FileOperationPhase.RECORD_CREATION,y.incrementCounter("write_file_phase",1,{phase:_})
2605
- const{toolRecordId:J}=await d.createFileOperationRecords(M,G,r.projectId,E.recordType,B,{operationType:O?"document":"file",documentId:O?S:void 0,documentFilename:F,filePath:$?D:void 0,contentLength:"string"==typeof T?T.length:JSON.stringify(T).length,format:q||"text",append:P||!1,wasFileCreated:!L,userComment:j},o,s,b,y,E.metricsPrefix,w)
2606
- let Q
2607
- if(v=J,C=J,_=E.fileOperationPhase,y.incrementCounter("write_file_phase",1,{phase:_}),"json"===q)if("string"==typeof T)try{JSON.parse(T),Q=T}catch(e){throw new u.ValidationError("Content is not valid JSON")}else Q=JSON.stringify(T,null,2)
2608
- else Q="string"==typeof T?T:JSON.stringify(T,null,2)
2609
- let Y=Q
2626
+ const{toolRecordId:K}=await d.createFileOperationRecords(M,G,r.projectId,E.recordType,B,{operationType:O?"document":"file",documentId:O?S:void 0,documentFilename:F,filePath:$?D:void 0,contentLength:"string"==typeof T?T.length:JSON.stringify(T).length,format:q||"text",append:P||!1,wasFileCreated:!L,userComment:j},o,s,b,y,E.metricsPrefix,w)
2627
+ let J
2628
+ if(v=K,C=K,_=E.fileOperationPhase,y.incrementCounter("write_file_phase",1,{phase:_}),"json"===q)if("string"==typeof T)try{JSON.parse(T),J=T}catch(e){throw new u.ValidationError("Content is not valid JSON")}else J=JSON.stringify(T,null,2)
2629
+ else J="string"==typeof T?T:JSON.stringify(T,null,2)
2630
+ let Y=J
2610
2631
  if($&&r.git)try{b.debug("[WRITE-FILE] Checking for user changes before write operation")
2611
2632
  const e=await(0,p.commitUserChangesBeforeToolOperation)(r.git,"write_file",{requestId:r.workspaceManager?.getCurrentContext(r.currentSessionId)?.requestId,taskId:M},b,y)
2612
2633
  e.userChangesCommitted&&(b.debug("[WRITE-FILE] User changes committed before write operation",{commitHash:e.commitHash?.substring(0,8),filesCommitted:e.filesCommitted}),b.info("User changes committed before write-file operation",{taskId:M,path:D,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){b.debug("[WRITE-FILE] Pre-tool commit failed, continuing with write",{error:e instanceof Error?e.message:e+""}),b.warn("Pre-tool user changes commit failed, continuing with write operation",{taskId:M,path:D,error:e instanceof Error?e.message:e+""})}if(!N)throw Error("Target path not properly initialized")
2613
- if(b.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:N}),P&&L)try{Y=await c.default.readFile(N,"utf8")+Q}catch(e){b.warn("Failed to read existing content for append",{error:e})}const Z=a.default.dirname(N)
2634
+ if(b.debug("[WRITE-FILE] Proceeding with file write operation",{targetPath:N}),P&&L)try{Y=await c.default.readFile(N,"utf8")+J}catch(e){b.warn("Failed to read existing content for append",{error:e})}const Z=a.default.dirname(N)
2614
2635
  if(await c.default.mkdir(Z,{recursive:!0}),await c.default.writeFile(N,Y,"utf8"),b.info("Content written successfully",{path:$?D:"document:"+S,finalLength:Y.length,append:P,wasCreated:z}),O){r.documentFileManager.markForSync(S)
2615
2636
  try{await r.documentFileManager.syncDocument(S),b.info("Document synced successfully",{documentId:S})}catch(e){b.warn("Failed to sync document immediately",{documentId:S,error:e})}}let X,ee,te=null,re=!1
2616
2637
  if($){if(_=d.FileOperationPhase.GIT_COMMIT,y.incrementCounter("write_file_phase",1,{phase:_}),r.workspaceManager){const e=r.workspaceManager.getCurrentContext(r.currentSessionId)
@@ -2630,7 +2651,7 @@ const r=t(1569),n=t(3247)
2630
2651
  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"
2631
2652
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
2632
2653
  const r=t(6183),n=t(4648)
2633
- 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"
2654
+ 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"
2634
2655
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.BaseApiClient=void 0
2635
2656
  const r=t(7163)
2636
2657
  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)})
@@ -2673,7 +2694,10 @@ throw void 0!==r&&500>r||this.incrementFailureCount(),this.logger.error(`API req
2673
2694
  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
2674
2695
  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)
2675
2696
  const e=this.options.circuitBreakerResetTime||5e3
2676
- 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"
2697
+ 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"
2698
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
2699
+ const r=t(6183),n=t(1719)
2700
+ 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"
2677
2701
  var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
2678
2702
  var o=Object.getOwnPropertyDescriptor(t,r)
2679
2703
  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=[]
@@ -2748,7 +2772,7 @@ let P=null
2748
2772
  try{i.default.mkdirSync(S,{recursive:!0}),P=i.default.createWriteStream(q,{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:q,error:(0,l.getErrorMessage)(e)})}h.info("Running command",{name:v.name,command:C,cwd:E,configuredCwd:v.cwd,logPath:q})
2749
2773
  const j=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:T,name:v.name,sessionId:m?.sessionId,logPath:q},f)
2750
2774
  P&&(P.write(`\n# exit: ${j.exitCode}${j.timedOut?" (timed out)":""}\n`),P.end())
2751
- const{stdout:R,stderr:x,exitCode:M,timedOut:O}=j,{output:$,truncatedNote:D,logFooter:A}=(0,o.formatCommandOutput)(R,x,{invocationId:T}),F=O?"TIMEOUT":null
2775
+ const{stdout:x,stderr:R,exitCode:M,timedOut:O}=j,{output:$,truncatedNote:D,logFooter:A}=(0,o.formatCommandOutput)(x,R,{invocationId:T}),F=O?"TIMEOUT":null
2752
2776
  let N
2753
2777
  if(g)try{const e=await g.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:v.name,command:C,exitCode:M,timedOut:O,status:O?"timeout":0===M?"success":"failed",timestamp:(new Date).toISOString()}})
2754
2778
  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${$}\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}}}
@@ -3258,7 +3282,23 @@ const e=o.annotationId,t=o.body,r=i.getDocumentClient(),n=await r.replyToAnnotat
3258
3282
  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")
3259
3283
  const e=o.annotationId,t=i.getDocumentClient()
3260
3284
  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}}}
3261
- const r=t(1572),n=t(1483),o=t(8824),s=t(2272)},5674(e,exports,t){"use strict"
3285
+ const r=t(1572),n=t(1483),o=t(8824),s=t(2272)},5652(e,exports,t){"use strict"
3286
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleQuestAuditComplete=async function(e,t,o,s,i){const a=s.child({tool:"quest_audit_complete"})
3287
+ try{if(!t.projectId)return{content:[{type:"text",text:"\u274c No project context available."}],isError:!0}
3288
+ const r=o.getDocumentClient(),s=await r.getDocument(e.questId)
3289
+ if(!s)return{content:[{type:"text",text:"\u274c Quest not found: "+e.questId}],isError:!0}
3290
+ 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}
3291
+ const c=s.metadata||{},l=c.status||n.QUEST_STATUS_OPEN
3292
+ 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}
3293
+ 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:[]
3294
+ if(h.length>0){const e=h.filter((e=>"verified"!==e?.status))
3295
+ if(e.length>0){const t=e.map((e=>`- ${e?.id||"(no id)"}: ${e?.description||"(no description)"}`))
3296
+ 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),g=c.consecutiveDoneAudits??0,m=g+1,f=m>=p,y=f?"auto-close"===u?n.QUEST_STATUS_CLOSED:n.QUEST_STATUS_PENDING_REVIEW:l,w={...c,consecutiveDoneAudits:f?0:m,status:y}
3297
+ 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})
3298
+ const b=s.localId||s.id
3299
+ if(a.info("quest_audit_complete processed",{questId:b,previousCounter:g,nextCounter:m,willFlip:f,completionMode:u,nextStatus:y}),!f){const e=p-m
3300
+ return{content:[{type:"text",text:`\u{1f4dd} **Audit recorded (${m}/${p})**\n\nQuest **${b}** 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 (${m}/${p})**\n\nQuest **${b}**: ${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}}}
3301
+ const r=t(8824),n=t(3416)},5674(e,exports,t){"use strict"
3262
3302
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionError=void 0
3263
3303
  const r=t(441)
3264
3304
  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"]}
@@ -3295,20 +3335,22 @@ return p.error("Server validation failed",{requestId:n,error:t}),g({success:!1,e
3295
3335
  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()
3296
3336
  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()
3297
3337
  let y="auto-merge"!==m.completionMode&&!m.testsSkipped
3298
- const w="manual-review"===m.reviewMode
3299
- let b,I=null
3338
+ const w="manual-review"===m.reviewMode,b=y&&!1===m.hasActiveTestProcesses&&("test-by-default"===m.completionMode||"always-test"===m.completionMode)
3339
+ b&&(y=!1)
3340
+ let I,k=null
3300
3341
  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
3301
3342
  if(i&&"passed"===i.status&&i.commitSha){let e=null
3302
3343
  if(r&&r.ok){const t=await r.json()
3303
- e=t?.data?.sha??null}e&&e===i.commitSha&&(y=!1,I=`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 k=y||w?"ready_for_review":"ready_for_merge"
3304
- try{await f.updateRequest(n,{status:k,completionSummary:o,...b?{skippedTestRunId:b}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
3305
- return g({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let v
3306
- try{v=await f.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
3307
- return g({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const C=v?.acceptanceCriteria||[]
3308
- 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.`}]}
3309
- 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.`}]}
3310
- const _=I?`\n\n_Skipped re-running tests: ${I}._\n`:""
3311
- 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=""
3344
+ 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)}`,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 v=y||w?"ready_for_review":"ready_for_merge"
3345
+ try{await f.updateRequest(n,{status:v,completionSummary:o,...I?{skippedTestRunId:I}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
3346
+ return g({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let C
3347
+ try{C=await f.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
3348
+ return g({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const _=C?.acceptanceCriteria||[]
3349
+ if(g({success:!0}),y){const e=m.completionMode
3350
+ let t
3351
+ 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.${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.`}]}
3352
+ const E=k?`\n\n_Skipped re-running tests: ${k}._\n`:"",S=b?`\n\n_No test processes are configured for this project; ${m.completionMode} mode is being treated as auto-merge._\n`:""
3353
+ 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=""
3312
3354
  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})
3313
3355
  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}}}
3314
3356
  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"
@@ -3349,50 +3391,50 @@ else{if(!E)throw Error("Either paths or operations must be specified")
3349
3391
  j=E.map((e=>{if(e.path)return{type:"file",target:e.path}
3350
3392
  if(e.documentId)return{type:"document",target:e.documentId}
3351
3393
  throw Error("Invalid operation: neither path nor documentId specified")}))}if(0===j.length)throw Error("At least one file or document must be specified for deletion")
3352
- const R=j.filter((e=>"file"===e.type)),x=j.filter((e=>"document"===e.type)),M=j.length
3353
- m.info("Starting mixed file and document deletion operation",{taskId:P,totalOperations:j.length,fileOperations:R.length,documentOperations:x.length,comment:S}),c.validateTaskIdFormat(P,m,s,I.metricsPrefix)
3394
+ const x=j.filter((e=>"file"===e.type)),R=j.filter((e=>"document"===e.type)),M=j.length
3395
+ m.info("Starting mixed file and document deletion operation",{taskId:P,totalOperations:j.length,fileOperations:x.length,documentOperations:R.length,comment:S}),c.validateTaskIdFormat(P,m,s,I.metricsPrefix)
3354
3396
  const O=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3355
3397
  m.info("Initial branch context",{initialBranch:O.branch,initialRequestId:O.requestId,isMain:O.isMain})
3356
3398
  const $=[]
3357
- for(const e of R){const{normalizedPath:t,fullPath:n}=c.validateAndNormalizePath(e.target,r)
3399
+ for(const e of x){const{normalizedPath:t,fullPath:n}=c.validateAndNormalizePath(e.target,r)
3358
3400
  $.push({normalized:t,full:n})}b=c.FileOperationPhase.TASK_VALIDATION,s.incrementCounter("delete_files_phase",1,{phase:b})
3359
3401
  const D=$.length>0?$[0].normalized:"document_operations",A=await c.validateTaskId(P,D,d,m,s,I.metricsPrefix),F=A?.requestId,N=await c.validateWorkItemStates(P,D,d,v,r,m,s,I.metricsPrefix),z=await c.autoPromoteTaskStatus(P,A.status,F,N.request?.status,D,d,v,m,s,I.metricsPrefix)
3360
- 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:j.length,fileOperations:R.length,documentOperations:x.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})
3402
+ 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:j.length,fileOperations:x.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})
3361
3403
  const L=await c.ensureCorrectWorkspaceContext({taskPromoted:z.taskPromoted,requestId:F,context:r,operation:"delete-files",logger:m,metrics:s,metricsPrefix:I.metricsPrefix})
3362
3404
  if(!L.success)throw Error(L.error)
3363
3405
  let H={hadUserMods:!1,userModsCommitHash:void 0}
3364
3406
  if(r.git)try{m.debug("[DELETE-FILES] Checking for user changes before mixed delete operations")
3365
3407
  const e=await(0,u.commitUserChangesBeforeToolOperation)(r.git,"delete-files",{requestId:F,taskId:P,workspaceManager:r.workspaceManager},m,s)
3366
- 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:j.length,fileOperations:R.length,documentOperations:x.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:j.length,fileOperations:R.length,documentOperations:x.length,error:e instanceof Error?e.message:e+""})}m.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:j.length,fileDeletes:R.length,documentDeletes:x.length}),b=c.FileOperationPhase.RECORD_CREATION,s.incrementCounter("delete_files_phase",1,{phase:b})
3367
- const{toolRecordId:B,localToolRecordId:U}=await c.createFileOperationRecords(P,F,r.projectId,I.recordType,D,{totalOperations:j.length,fileOperations:R.length,documentOperations:x.length,filePaths:$.map((e=>e.normalized)),documentIds:x.map((e=>e.target)),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},d,k,m,s,I.metricsPrefix,i)
3408
+ 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:j.length,fileOperations:x.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:j.length,fileOperations:x.length,documentOperations:R.length,error:e instanceof Error?e.message:e+""})}m.debug("[DELETE-FILES] Proceeding with mixed delete operations",{totalOperations:j.length,fileDeletes:x.length,documentDeletes:R.length}),b=c.FileOperationPhase.RECORD_CREATION,s.incrementCounter("delete_files_phase",1,{phase:b})
3409
+ const{toolRecordId:B,localToolRecordId:U}=await c.createFileOperationRecords(P,F,r.projectId,I.recordType,D,{totalOperations:j.length,fileOperations:x.length,documentOperations:R.length,filePaths:$.map((e=>e.normalized)),documentIds:R.map((e=>e.target)),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},d,k,m,s,I.metricsPrefix,i)
3368
3410
  y=B,w=B,b=I.fileOperationPhase,s.incrementCounter("delete_files_phase",1,{phase:b})
3369
3411
  const G=[]
3370
3412
  let W=0
3371
- x.length>0&&n.setProjectId(r.projectId)
3413
+ R.length>0&&n.setProjectId(r.projectId)
3372
3414
  for(let e=0;e<$.length;e++){const t=$[e],r={type:"file",path:t.normalized,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3373
3415
  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)
3374
- await a.default.unlink(t.full),r.success=!0,W++,m.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,g.getErrorMessage)(e),m.warn("Failed to delete file "+t.normalized,{error:r.error})}G.push(r)}const V=x.length>0?n.getDocumentClient():null
3375
- for(const e of x){const t=e.target,r={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3416
+ await a.default.unlink(t.full),r.success=!0,W++,m.info("Successfully deleted file",{path:t.normalized})}catch(e){r.error=(0,g.getErrorMessage)(e),m.warn("Failed to delete file "+t.normalized,{error:r.error})}G.push(r)}const V=R.length>0?n.getDocumentClient():null
3417
+ for(const e of R){const t=e.target,r={type:"document",documentId:t,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0}
3376
3418
  try{let e
3377
3419
  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)
3378
3420
  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)
3379
3421
  throw e}}catch(e){throw Error(`Document not found or validation failed: ${t}. ${(0,g.getErrorMessage)(e)}`)}const o=await V.archiveDocument(t)
3380
- r.success=!0,r.filename=o.filename,W++,m.info("Document archived successfully",{documentId:o.id,filename:o.filename,archivedAt:o.archived_at})}catch(e){r.error=(0,g.getErrorMessage)(e),m.warn("Failed to delete document "+t,{error:r.error})}G.push(r)}const K=Date.now()-f
3381
- s.recordValue("delete_files_time",K),s.incrementCounter("delete_files_operations_total",M),s.incrementCounter("delete_files_operations_success",W),s.incrementCounter("delete_files_operations_failed",M-W),s.incrementCounter("delete_files_file_operations",R.length),s.incrementCounter("delete_files_document_operations",x.length),W===M?s.incrementCounter("delete_files_success",1):W>0?s.incrementCounter("delete_files_partial_success",1):s.incrementCounter("delete_files_total_failure",1)
3382
- let J=null
3422
+ r.success=!0,r.filename=o.filename,W++,m.info("Document archived successfully",{documentId:o.id,filename:o.filename,archivedAt:o.archived_at})}catch(e){r.error=(0,g.getErrorMessage)(e),m.warn("Failed to delete document "+t,{error:r.error})}G.push(r)}const Q=Date.now()-f
3423
+ s.recordValue("delete_files_time",Q),s.incrementCounter("delete_files_operations_total",M),s.incrementCounter("delete_files_operations_success",W),s.incrementCounter("delete_files_operations_failed",M-W),s.incrementCounter("delete_files_file_operations",x.length),s.incrementCounter("delete_files_document_operations",R.length),W===M?s.incrementCounter("delete_files_success",1):W>0?s.incrementCounter("delete_files_partial_success",1):s.incrementCounter("delete_files_total_failure",1)
3424
+ let K=null
3383
3425
  if(W>0){b=c.FileOperationPhase.GIT_COMMIT,s.incrementCounter("delete_files_phase",1,{phase:b})
3384
3426
  const e=G.filter((e=>e.success)),t=e.filter((e=>"file"===e.type)).length,n=e.filter((e=>"document"===e.type)).length
3385
3427
  let o
3386
- 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,I.metricsPrefix)}b=c.FileOperationPhase.RECORD_UPDATE_SUCCESS,s.incrementCounter("delete_files_phase",1,{phase:b})
3387
- const Q=G.filter((e=>e.success)),Y=G.filter((e=>!e.success))
3388
- await c.updateFileOperationRecords(P,y,w,D,I.recordType,W===M?`Successfully deleted all ${M} operations`:`Deleted ${W}/${M} operations successfully`,{status:W===M?"completed":"partial_success",commitHash:J?.commitHash,previousCommitHash:J?.previousCommitHash,totalOperations:M,fileOperations:R.length,documentOperations:x.length,successCount:W,failureCount:M-W,successfulOperations:Q.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename}))),failedOperations:Y.map((e=>({type:e.type,path:e.path,documentId:e.documentId,filename:e.filename,error:e.error}))),userComment:S,hadUserMods:H.hadUserMods,userModsCommitHash:H.userModsCommitHash},W===M?`Successfully deleted all ${M} operations`:`Deleted ${W}/${M} operations successfully`,d,k,m,s,I.metricsPrefix)
3428
+ 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,m,s,I.metricsPrefix)}b=c.FileOperationPhase.RECORD_UPDATE_SUCCESS,s.incrementCounter("delete_files_phase",1,{phase:b})
3429
+ const J=G.filter((e=>e.success)),Y=G.filter((e=>!e.success))
3430
+ await c.updateFileOperationRecords(P,y,w,D,I.recordType,W===M?`Successfully deleted all ${M} operations`:`Deleted ${W}/${M} operations successfully`,{status:W===M?"completed":"partial_success",commitHash:K?.commitHash,previousCommitHash:K?.previousCommitHash,totalOperations:M,fileOperations:x.length,documentOperations:R.length,successCount:W,failureCount:M-W,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},W===M?`Successfully deleted all ${M} operations`:`Deleted ${W}/${M} operations successfully`,d,k,m,s,I.metricsPrefix)
3389
3431
  const Z=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
3390
3432
  let X=""
3391
- if(W===M){const e=Q.filter((e=>"file"===e.type)).length,t=Q.filter((e=>"document"===e.type)).length
3433
+ if(W===M){const e=J.filter((e=>"file"===e.type)).length,t=J.filter((e=>"document"===e.type)).length
3392
3434
  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=W>0?`Successfully deleted ${W}/${M} operations.\n\nFailed operations:\n`+G.filter((e=>!e.success)).map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
3393
3435
  return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n"):"All delete operations failed:\n"+G.map((e=>{const t="file"===e.type?e.path:`${e.filename||e.documentId} (${e.documentId})`
3394
3436
  return`\u2022 ${e.type}: ${t}: ${e.error}`})).join("\n")
3395
- return J?.commitHash&&(X+="\nCommit: "+J.commitHash.substring(0,8)),Z.requestId&&(X+="\nBranch: "+Z.requestId),{content:[{type:"text",text:X}],isError:0===W}}catch(t){if(e.taskId&&n)try{const o=n.getToolRecordClient(),s=t instanceof l.NotFoundError||t instanceof l.ValidationError||t instanceof d.ZodError
3437
+ return K?.commitHash&&(X+="\nCommit: "+K.commitHash.substring(0,8)),Z.requestId&&(X+="\nBranch: "+Z.requestId),{content:[{type:"text",text:X}],isError:0===W}}catch(t){if(e.taskId&&n)try{const o=n.getToolRecordClient(),s=t instanceof l.NotFoundError||t instanceof l.ValidationError||t instanceof d.ZodError
3396
3438
  await o.createToolRecord({...s?{}:{taskId:e.taskId},projectId:r.projectId,type:"delete-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0,paths:e.paths||e.operations?.filter((e=>e.path))?.map((e=>e.path))||[],documentIds:e.operations?.filter((e=>e.documentId))?.map((e=>e.documentId))||[],userComment:e.comment,error:(0,g.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:s},note:"Failed to delete files - "+(0,g.getErrorMessage)(t)})}catch(t){m.error("Failed to create failure record for delete-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,totalOperations:e.operations?.length||e.paths?.length||0,fileOperations:e.paths?.length||e.operations?.filter((e=>e.path))?.length||0,documentOperations:e.operations?.filter((e=>e.documentId))?.length||0})}const o=Date.now()-f
3397
3439
  if(s.recordValue("delete_files_time",o),s.incrementCounter("delete_files_errors",1),m.error("Error in delete-files operation:",{error:(0,g.getErrorMessage)(t),time:o}),(y||w)&&e.taskId){b=c.FileOperationPhase.RECORD_UPDATE_FAILURE
3398
3440
  try{const r=n.getTaskClient(),o=n.getToolRecordClient()
@@ -3459,22 +3501,25 @@ const n=await this.requestWithRetry("POST","/api/files/recover",t)
3459
3501
  if(!(0,i.safeGetResponseData)(n,null))throw new r.ServiceError("Empty response when recovering file")
3460
3502
  const o=(0,i.safeGetResponseData)(n,{success:!0,path:e.path,commitHash:e.commitHash,backupPath:void 0})
3461
3503
  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"
3462
- 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
3463
- 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
3464
- 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" }'})}))
3465
- const u=r.z.string().min(1).describe("OpenCode session ID")
3466
- 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"})}))
3467
- 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)")
3468
- 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
3469
- 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
3470
- 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
3504
+ 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
3505
+ 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
3506
+ 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" }'})}))
3507
+ const h=r.z.string().min(1).describe("OpenCode session ID")
3508
+ 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"})}))
3509
+ 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)")
3510
+ 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
3511
+ 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)."})
3512
+ const r=s.QUEST_METADATA_KEYS.filter((t=>void 0!==e[t]))
3513
+ 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}'.`})
3514
+ 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
3515
+ 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
3471
3516
  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]
3472
- 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")})
3473
- 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)")})
3474
- 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"
3517
+ 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")})
3518
+ const g=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)")})
3519
+ exports.TestingProcessCreateSchema=r.z.object({name:r.z.string().min(1).describe("Name for the test process"),description:r.z.string().optional().describe("Description of what this process verifies"),scope:r.z.string().optional().describe('Path prefix for monorepo scoping (e.g., "packages/api/"). Omit for global.'),setup:r.z.array(r.z.string()).optional().describe('Commands to prepare the environment (e.g., ["ln -s ../../node_modules node_modules"])'),commands:r.z.array(g).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe('Files whose content invalidates setup. Setup commands re-run only when these files change between runs (e.g. ["package-lock.json"], ["Cargo.lock"], ["uv.lock", "poetry.lock"]). Polyglot repos list multiple. Omit / empty list = always re-run setup (existing behavior).'),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool. Default 2. Set to 1 for languages with very large build artifacts (Rust target/, C++ build/). Higher values allow more parallel test runs at the cost of disk.")}),exports.TestingProcessDeleteSchema=r.z.object({processId:r.z.string().describe("Test process ID to delete")}),exports.TestingProcessUpdateSchema=r.z.object({processId:r.z.string().describe("Test process ID to update"),name:r.z.string().min(1).optional().describe("New name"),description:r.z.string().optional().describe("New description"),scope:r.z.string().optional().describe('New scope to limit when this process runs (e.g., "packages/api/"). Omit to leave unchanged.'),isActive:r.z.boolean().optional().describe("Enable or disable the process"),setup:r.z.array(r.z.string()).optional().describe("New setup commands (replaces existing)"),commands:r.z.array(g).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe("Files whose content invalidates setup (replaces existing list)."),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool (replaces existing).")}),exports.TestingReferenceSchema=r.z.object({}),exports.TestsSchema=r.z.object({operation:r.z.enum(["list","setup","run"]).describe('"list" to see registered test processes for this project. "setup" to spawn an interactive test-architect session that helps configure a process. "run" to fire an async test run 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"
3475
3520
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
3476
3521
  const r=t(6183),n=t(405)
3477
- 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"
3522
+ 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"
3478
3523
  module.exports=require("events")},6285(e,exports,t){"use strict"
3479
3524
  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")
3480
3525
  try{const u=e,{operation:y,sessionId:w}=u
@@ -3611,51 +3656,51 @@ const{taskId:q}=T
3611
3656
  if(y.info("Inserting lines into files and documents",{taskId:q,operationCount:_.length,comment:E}),!_||0===_.length)throw new d.ValidationError("At least one operation is required")
3612
3657
  const P=_.filter((e=>e.path)),j=_.filter((e=>e.documentId))
3613
3658
  y.info("Operation breakdown",{fileOperations:P.length,documentOperations:j.length})
3614
- const R=[]
3659
+ const x=[]
3615
3660
  for(const e of P){const{normalizedPath:t,fullPath:r}=l.validateAndNormalizePath(e.path,n)
3616
- R.push({type:"file",path:t,fullPath:r,insertions:e.insertions})}const x=[]
3661
+ x.push({type:"file",path:t,fullPath:r,insertions:e.insertions})}const R=[]
3617
3662
  if(j.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3618
- for(const e of j)x.push({type:"document",documentId:e.documentId,insertions:e.insertions})
3619
- if(x.length>0&&n.apiClient){const e=x.map((e=>e.documentId))
3663
+ for(const e of j)R.push({type:"document",documentId:e.documentId,insertions:e.insertions})
3664
+ if(R.length>0&&n.apiClient){const e=R.map((e=>e.documentId))
3620
3665
  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}
3621
3666
  throw e}}k=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("insert_lines_phase",1,{phase:k})
3622
- const M=R.length>0?R[0].path:"document-operation",O=await l.validateTaskId(q,M,o,y,m,v.metricsPrefix),$=O?.requestId
3667
+ const M=x.length>0?x[0].path:"document-operation",O=await l.validateTaskId(q,M,o,y,m,v.metricsPrefix),$=O?.requestId
3623
3668
  let D=null
3624
- R.length>0&&$&&(D=await l.validateWorkItemStates(q,R[0].path,o,i,n,y,m,v.metricsPrefix))
3669
+ x.length>0&&$&&(D=await l.validateWorkItemStates(q,x[0].path,o,i,n,y,m,v.metricsPrefix))
3625
3670
  let A={taskPromoted:!1,requestPromoted:!1}
3626
- R.length>0&&$&&D&&(A=await l.autoPromoteTaskStatus(q,O.status,$,D.request?.status,R[0].path,o,i,y,m,v.metricsPrefix),A.taskPromoted&&y.info("Auto-promoted task to in_progress for insert-lines operation",{taskId:q,requestId:$,previousStatus:O.status,newStatus:A.newTaskStatus,triggeringOperation:"insert-lines"}))
3671
+ x.length>0&&$&&D&&(A=await l.autoPromoteTaskStatus(q,O.status,$,D.request?.status,x[0].path,o,i,y,m,v.metricsPrefix),A.taskPromoted&&y.info("Auto-promoted task to in_progress for insert-lines operation",{taskId:q,requestId:$,previousStatus:O.status,newStatus:A.newTaskStatus,triggeringOperation:"insert-lines"}))
3627
3672
  const F=await l.ensureCorrectWorkspaceContext({taskPromoted:A.taskPromoted,requestId:$,context:n,operation:"insert-lines",logger:y,metrics:m,metricsPrefix:v.metricsPrefix})
3628
3673
  if(!F.success)throw Error(F.error)
3629
- if(R.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:R.length,workspaceBasePath:n.workspaceManager?.getCurrentContext(n.currentSessionId).basePath})
3630
- for(let e=0;e<R.length;e++){const t=R[e],r=P[e],{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(r.path,n)
3631
- R[e]={...t,path:o,fullPath:s}}}if(x.length>0&&$)try{await(0,u.validateRequestStatusForDocumentOperation)($,i,y,m,"insert-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3674
+ if(x.length>0){y.debug("Re-validating file paths with correct workspace context",{operationCount:x.length,workspaceBasePath:n.workspaceManager?.getCurrentContext(n.currentSessionId).basePath})
3675
+ for(let e=0;e<x.length;e++){const t=x[e],r=P[e],{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(r.path,n)
3676
+ x[e]={...t,path:o,fullPath:s}}}if(R.length>0&&$)try{await(0,u.validateRequestStatusForDocumentOperation)($,i,y,m,"insert-lines-document")}catch(e){if(e instanceof d.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
3632
3677
  throw e}k=l.FileOperationPhase.RECORD_CREATION,m.incrementCounter("insert_lines_phase",1,{phase:k})
3633
- const N=[...R.map((e=>({type:"file",path:e.path,insertions:e.insertions}))),...x.map((e=>({type:"document",documentId:e.documentId,insertions:e.insertions})))],{toolRecordId:z}=await l.createFileOperationRecords(q,$,n.projectId,v.recordType,M,{operationCount:_.length,fileOperations:R.length,documentOperations:x.length,operations:N,userComment:E},o,s,y,m,v.metricsPrefix,f)
3634
- if(b=z,I=z,k=v.fileOperationPhase,m.incrementCounter("insert_lines_phase",1,{phase:k}),R.length>0&&n.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
3678
+ const N=[...x.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(q,$,n.projectId,v.recordType,M,{operationCount:_.length,fileOperations:x.length,documentOperations:R.length,operations:N,userComment:E},o,s,y,m,v.metricsPrefix,f)
3679
+ if(b=z,I=z,k=v.fileOperationPhase,m.incrementCounter("insert_lines_phase",1,{phase:k}),x.length>0&&n.git)try{y.debug("[INSERT-LINES] Checking for user changes before insert operations")
3635
3680
  const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"insert-lines",{requestId:$,taskId:q,workspaceManager:n.workspaceManager},y,m)
3636
- 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:q,fileOperationsCount:R.length,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){y.debug("[INSERT-LINES] Pre-tool commit failed, continuing with insertions",{error:e instanceof Error?e.message:e+""}),y.warn("Pre-tool user changes commit failed, continuing with insert operation",{taskId:q,fileOperationsCount:R.length,error:e instanceof Error?e.message:e+""})}y.debug("[INSERT-LINES] Proceeding with file operations",{fileCount:R.length})
3681
+ 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:q,fileOperationsCount:x.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:q,fileOperationsCount:x.length,error:e instanceof Error?e.message:e+""})}y.debug("[INSERT-LINES] Proceeding with file operations",{fileCount:x.length})
3637
3682
  const L=[]
3638
3683
  let H=0,B=0,U=0
3639
- for(const e of R){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3684
+ for(const e of x){const t={type:"file",path:e.path,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3640
3685
  try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
3641
3686
  const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.insertions)
3642
- t.insertions=s,t.successfulInsertions=s.filter((e=>e.success)).length,t.failedInsertions=s.filter((e=>!e.success)).length,t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulInsertions>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,U++,y.info("File updated successfully",{path:e.path,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,g.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("File operation failed",{path:e.path,error:t.error})}L.push(t)}for(const e of x){const t={type:"document",documentId:e.documentId,success:!1,insertions:[],successfulInsertions:0,failedInsertions:0,totalLinesAdded:0}
3687
+ 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}
3643
3688
  try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.documentFileManager.getCachedDocumentInfo(e.documentId)
3644
3689
  t.filename=s?.filename
3645
3690
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.insertions)
3646
- t.insertions=l,t.successfulInsertions=l.filter((e=>e.success)).length,t.failedInsertions=l.filter((e=>!e.success)).length,t.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&t.successfulInsertions>0?(await c.default.writeFile(o,a,"utf8"),n.documentFileManager.markForSync(e.documentId),t.success=!0,U++,y.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulInsertions:t.successfulInsertions,failedInsertions:t.failedInsertions,linesAdded:t.totalLinesAdded})):0===t.failedInsertions&&(t.success=!0),H+=t.failedInsertions,B+=t.totalLinesAdded}catch(r){t.error=(0,g.getErrorMessage)(r),t.failedInsertions=e.insertions.length,H+=t.failedInsertions,y.error("Document operation failed",{documentId:e.documentId,error:t.error})}L.push(t)}if(x.length>0)try{for(const e of x){const t=L.find((t=>t.documentId===e.documentId))
3647
- t?.success&&await n.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const G=await l.handleMultiFileGitCommit(q,R,L,U,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:m,metricsPrefix:"insert_lines"},n),W=l.processMultiFileOperationResults(L,"successfulInsertions"),{successfulOperations:V,failedOperations:K,totalSuccessfulChanges:J,overallSuccess:Q,successfulFiles:Y,failedFiles:Z}=W
3648
- try{await s.updateToolRecord(I,{metadata:{path:R.length>0?R[0].path:"document:"+x[0]?.documentId,status:Q?"completed":"failed",error:Q?void 0:K+" operations failed",totalOperations:L.length,successfulFiles:Y,failedFiles:Z,operations:N,totalSuccessfulInsertions:J,totalFailedInsertions:H,totalLinesAdded:B,operationsWithChanges:U,processingTime:Date.now()-w,userComment:E,...R.length>0&&G.success&&G.commitHash&&{commitHash:G.commitHash,previousCommitHash:G.previousCommitHash||void 0}},note:Q?`Line insertion completed: ${V}/${L.length} operations successful${R.length>0?" (committed to git)":""}`:`Line insertion partially failed: ${K}/${L.length} operations failed`})}catch(e){y.warn("Failed to update tool record",{recordError:e})}let X="## Line Insertion Results\n\n"
3691
+ 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))
3692
+ t?.success&&await n.documentFileManager.syncDocument(e.documentId)}}catch(e){y.warn("Some documents may not have synced properly",{error:e})}const G=await l.handleMultiFileGitCommit(q,x,L,U,{operationType:"Insert lines",toolRecordId:I,successField:"successfulInsertions",logger:y,metrics:m,metricsPrefix:"insert_lines"},n),W=l.processMultiFileOperationResults(L,"successfulInsertions"),{successfulOperations:V,failedOperations:Q,totalSuccessfulChanges:K,overallSuccess:J,successfulFiles:Y,failedFiles:Z}=W
3693
+ try{await s.updateToolRecord(I,{metadata:{path:x.length>0?x[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,...x.length>0&&G.success&&G.commitHash&&{commitHash:G.commitHash,previousCommitHash:G.previousCommitHash||void 0}},note:J?`Line insertion completed: ${V}/${L.length} operations successful${x.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"
3649
3694
  if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
3650
- e.permanentBranch||(X+=`**Branch:** \`${e.branchName}\`\n\n`)}if(X+="**Summary:**\n",X+=`- **Files processed:** ${V+K}\n`,X+=`- **Successful operations:** ${V}\n`,X+=`- **Failed operations:** ${K}\n`,X+=`- **Total insertions:** ${J} successful, ${H} failed\n`,X+=`- **Total Lines Added:** ${B}\n`,X+="\n",G.success&&G.commitHash&&(X+="**Git Commit:**\n",X+=`- **Commit Hash:** ${G.commitHash.substring(0,8)}\n`,X+=`- **Files Committed:** ${G.filesCommitted.length}\n`,G.previousCommitHash&&(X+=`- **Previous Commit:** ${G.previousCommitHash.substring(0,8)}\n`),X+="\n"),1===L.length){const e=L[0]
3695
+ 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",G.success&&G.commitHash&&(X+="**Git Commit:**\n",X+=`- **Commit Hash:** ${G.commitHash.substring(0,8)}\n`,X+=`- **Files Committed:** ${G.filesCommitted.length}\n`,G.previousCommitHash&&(X+=`- **Previous Commit:** ${G.previousCommitHash.substring(0,8)}\n`),X+="\n"),1===L.length){const e=L[0]
3651
3696
  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"
3652
3697
  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}`
3653
- 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"
3698
+ 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"
3654
3699
  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"
3655
3700
  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}`
3656
- X+=` - ${t.type} insertion ${e}: ${t.error}\n`}}X+="\n"}}x.length>0&&(X+="\u{1f4c4} **Document Changes:** Modified documents have been automatically synced back to the tracking system.\n\n")
3701
+ 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")
3657
3702
  const ee=Date.now()-w
3658
- 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
3703
+ return y.info("Insert lines operation completed",{duration:ee,success:J,totalOperations:L.length,successfulOperations:V,failedOperations:Q}),m.incrementCounter("insert_lines_total",1,{success:J}),{content:[{type:"text",text:X}],isError:!J}}catch(t){const r=Date.now()-w
3659
3704
  if(y.error("Insert lines operation failed",{error:t instanceof Error?t.stack:t+"",duration:r,phase:k}),I)try{await s.updateToolRecord(I,{metadata:{path:e?.operations?.[0]?.path||e?.operations?.[0]?.documentId,status:"failed",error:(0,g.getErrorMessage)(t),phase:k,duration:r,userComment:e?.comment},note:"Line insertion failed: "+(0,g.getErrorMessage)(t)})}catch(e){}return m.incrementCounter("insert_lines_errors",1,{phase:k}),{content:[{type:"text",text:"\u274c **Insert Lines Failed:** "+(0,g.getErrorMessage)(t)}],isError:!0}}}
3660
3705
  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"
3661
3706
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClientFactory=void 0
@@ -3680,12 +3725,12 @@ if(I.registerClient(j),!w.alchemyPath)throw Error("alchemyPath is required for P
3680
3725
  try{f.info("Creating ProjectSynchronizer components")
3681
3726
  const{ProjectRegistry,ProjectFileSystem,ProjectSynchronizer}=await t.e(478).then(t.bind(t,5478)),e=new ProjectRegistry(f),r=new ProjectFileSystem(f),n=new ProjectSynchronizer(f,e,new l.ProjectClientAdapter(_,f),r,{createRemoteProjects:!0})
3682
3727
  _.setProjectSynchronizer(n),f.info("ProjectSynchronizer created and connected to ProjectClient")}catch(e){const t="Failed to create required ProjectSynchronizer components: "+(0,h.getErrorMessage)(e)
3683
- throw f.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const R=new o.ApiClient(k,_,E,S,T,q,P,j,f)
3684
- f.info("API client initialized with specialized clients"),v?(R.setAuthToken(v),f.info("Auth token set on ApiClient during creation",{hasToken:!0,tokenLength:v.length})):f.warn("No auth token available during ApiClient creation",{info:"Client will need to authenticate before making requests"})
3685
- const x=I.verifyAllClients()
3686
- x.success?f.info("Token consistency verified across all clients"):f.error(`Token inconsistency detected in ${x.failedClients.length} clients: ${x.failedClients.join(", ")}`)
3687
- const M=R.getAuthToken()
3688
- return v&&!M?(f.error("CRITICAL: ApiClient token was not set properly!"),R.setAuthToken(v)):M&&f.info("ApiClient token verified",{tokenLength:M.length,matches:M===v}),f.info("API client creation completed successfully"),R}}},6540(e,exports){"use strict"
3728
+ throw f.error(t,{error:e instanceof Error?e.stack:e+""}),Error(t)}const x=new o.ApiClient(k,_,E,S,T,q,P,j,f)
3729
+ f.info("API client initialized with specialized clients"),v?(x.setAuthToken(v),f.info("Auth token set on ApiClient during creation",{hasToken:!0,tokenLength:v.length})):f.warn("No auth token available during ApiClient creation",{info:"Client will need to authenticate before making requests"})
3730
+ const R=I.verifyAllClients()
3731
+ R.success?f.info("Token consistency verified across all clients"):f.error(`Token inconsistency detected in ${R.failedClients.length} clients: ${R.failedClients.join(", ")}`)
3732
+ const M=x.getAuthToken()
3733
+ return v&&!M?(f.error("CRITICAL: ApiClient token was not set properly!"),x.setAuthToken(v)):M&&f.info("ApiClient token verified",{tokenLength:M.length,matches:M===v}),f.info("API client creation completed successfully"),x}}},6540(e,exports){"use strict"
3689
3734
  var t
3690
3735
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6552(e,exports,t){"use strict"
3691
3736
  async function r(){const e=new o.StdioServerTransport,t=(0,l.setupParentProcessDetection)((()=>{b.info("Parent process gone or orphan detected. Shutting down."),process.exit(0)}))
@@ -3763,34 +3808,34 @@ try{const _=e,{operations:E,comment:S}=_,{enforceActiveTask:T}=await Promise.res
3763
3808
  if("errorResult"in q)return q.errorResult
3764
3809
  const{taskId:P}=q
3765
3810
  if(w.info("Replacing lines in files and documents",{taskId:P,operationCount:E.length,comment:S}),!E||0===E.length)throw new d.ValidationError("At least one operation is required")
3766
- const j=E.filter((e=>e.path)),R=E.filter((e=>e.documentId))
3767
- w.info("Operation breakdown",{fileOperations:j.length,documentOperations:R.length})
3768
- const x=[]
3811
+ const j=E.filter((e=>e.path)),x=E.filter((e=>e.documentId))
3812
+ w.info("Operation breakdown",{fileOperations:j.length,documentOperations:x.length})
3813
+ const R=[]
3769
3814
  for(const e of j){const{normalizedPath:t,fullPath:r}=l.validateAndNormalizePath(e.path,n)
3770
- x.push({type:"file",path:t,fullPath:r,replacements:e.replacements.map((e=>({lines:(0,f.parseLineSpec)(e.lines),content:e.content})))})}const M=[]
3771
- if(R.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3772
- for(const e of R)M.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,f.parseLineSpec)(e.lines),content:e.content})))})
3815
+ R.push({type:"file",path:t,fullPath:r,replacements:e.replacements.map((e=>({lines:(0,f.parseLineSpec)(e.lines),content:e.content})))})}const M=[]
3816
+ if(x.length>0&&!n.documentFileManager)throw Error("Document file manager not available - cannot process document operations")
3817
+ for(const e of x)M.push({type:"document",documentId:e.documentId,replacements:e.replacements.map((e=>({lines:(0,f.parseLineSpec)(e.lines),content:e.content})))})
3773
3818
  if(M.length>0&&n.apiClient){const e=M.map((e=>e.documentId))
3774
3819
  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}
3775
3820
  throw e}}v=l.FileOperationPhase.TASK_VALIDATION,m.incrementCounter("replace_lines_phase",1,{phase:v})
3776
- const O=x.length>0?x[0].path:"document-operation",$=await l.validateTaskId(P,O,o,w,m,C.metricsPrefix),D=$?.requestId
3821
+ const O=R.length>0?R[0].path:"document-operation",$=await l.validateTaskId(P,O,o,w,m,C.metricsPrefix),D=$?.requestId
3777
3822
  let A=null
3778
- x.length>0&&D&&(A=await l.validateWorkItemStates(P,x[0].path,o,i,n,w,m,C.metricsPrefix))
3823
+ R.length>0&&D&&(A=await l.validateWorkItemStates(P,R[0].path,o,i,n,w,m,C.metricsPrefix))
3779
3824
  let F={taskPromoted:!1,requestPromoted:!1}
3780
- x.length>0&&D&&A&&(F=await l.autoPromoteTaskStatus(P,$.status,D,A.request?.status,x[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:$.status,newStatus:F.newTaskStatus,triggeringOperation:"replace-lines"}))
3825
+ R.length>0&&D&&A&&(F=await l.autoPromoteTaskStatus(P,$.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:$.status,newStatus:F.newTaskStatus,triggeringOperation:"replace-lines"}))
3781
3826
  const N=await l.ensureCorrectWorkspaceContext({taskPromoted:F.taskPromoted,requestId:D,context:n,operation:"replace-lines",logger:w,metrics:m,metricsPrefix:C.metricsPrefix})
3782
3827
  if(!N.success)throw Error(N.error)
3783
- if(x.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:x.length,workspaceBasePath:n.workspaceManager?.getCurrentContext(n.currentSessionId).basePath})
3784
- for(let e=0;e<x.length;e++){const t=x[e],r=j[e],{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(r.path,n)
3785
- x[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}
3828
+ if(R.length>0){w.debug("Re-validating file paths with correct workspace context",{operationCount:R.length,workspaceBasePath:n.workspaceManager?.getCurrentContext(n.currentSessionId).basePath})
3829
+ for(let e=0;e<R.length;e++){const t=R[e],r=j[e],{normalizedPath:o,fullPath:s}=l.validateAndNormalizePath(r.path,n)
3830
+ 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}
3786
3831
  throw e}v=l.FileOperationPhase.RECORD_CREATION,m.incrementCounter("replace_lines_phase",1,{phase:v})
3787
- const z=[...x.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,O,{operationCount:E.length,fileOperations:x.length,documentOperations:M.length,operations:z,userComment:S},o,s,w,m,C.metricsPrefix,y)
3788
- if(I=L,k=L,v=C.fileOperationPhase,m.incrementCounter("replace_lines_phase",1,{phase:v}),x.length>0&&n.git)try{w.debug("[REPLACE-LINES] Checking for user changes before replace operations")
3832
+ 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,O,{operationCount:E.length,fileOperations:R.length,documentOperations:M.length,operations:z,userComment:S},o,s,w,m,C.metricsPrefix,y)
3833
+ if(I=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")
3789
3834
  const e=await(0,h.commitUserChangesBeforeToolOperation)(n.git,"replace-lines",{requestId:D,taskId:P,workspaceManager:n.workspaceManager},w,m)
3790
- 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:x.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:x.length,error:e instanceof Error?e.message:e+""})}w.debug("[REPLACE-LINES] Proceeding with file operations",{fileCount:x.length})
3835
+ 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})
3791
3836
  const H=[]
3792
3837
  let B=0,U=0,G=0,W=0
3793
- for(const e of x){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3838
+ for(const e of R){const t={type:"file",path:e.path,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
3794
3839
  try{if(await c.default.access(e.fullPath),!(await c.default.stat(e.fullPath)).isFile())throw Error("Path is not a file: "+e.path)
3795
3840
  const n=await c.default.readFile(e.fullPath,"utf8"),{newContent:o,results:s}=await r(n,e.replacements)
3796
3841
  t.replacements=s,t.successfulReplacements=s.filter((e=>e.success)).length,t.failedReplacements=s.filter((e=>!e.success)).length,t.totalLinesReplaced=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=s.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),o!==n&&t.successfulReplacements>0?(await c.default.writeFile(e.fullPath,o,"utf8"),t.success=!0,W++,w.info("File updated successfully",{path:e.path,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),B+=t.failedReplacements,U+=t.totalLinesReplaced,G+=t.totalLinesAdded}catch(r){t.error=(0,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("File operation failed",{path:e.path,error:t.error})}H.push(t)}for(const e of M){const t={type:"document",documentId:e.documentId,success:!1,replacements:[],successfulReplacements:0,failedReplacements:0,totalLinesReplaced:0,totalLinesAdded:0}
@@ -3798,28 +3843,28 @@ try{const o=await n.documentFileManager.getDocumentAsFile(e.documentId),s=n.docu
3798
3843
  t.filename=s?.filename
3799
3844
  const i=await c.default.readFile(o,"utf8"),{newContent:a,results:l}=await r(i,e.replacements)
3800
3845
  t.replacements=l,t.successfulReplacements=l.filter((e=>e.success)).length,t.failedReplacements=l.filter((e=>!e.success)).length,t.totalLinesReplaced=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesReplaced||0)),0),t.totalLinesAdded=l.filter((e=>e.success)).reduce(((e,t)=>e+(t.linesAdded||0)),0),a!==i&&t.successfulReplacements>0?(await c.default.writeFile(o,a,"utf8"),n.documentFileManager.markForSync(e.documentId),t.success=!0,W++,w.info("Document updated successfully",{documentId:e.documentId,filename:t.filename,successfulReplacements:t.successfulReplacements,failedReplacements:t.failedReplacements,linesReplaced:t.totalLinesReplaced,linesAdded:t.totalLinesAdded})):0===t.failedReplacements&&(t.success=!0),B+=t.failedReplacements,U+=t.totalLinesReplaced,G+=t.totalLinesAdded}catch(r){t.error=(0,g.getErrorMessage)(r),t.failedReplacements=e.replacements.length,B+=t.failedReplacements,w.error("Document operation failed",{documentId:e.documentId,error:t.error})}H.push(t)}if(M.length>0)try{for(const e of M){const t=H.find((t=>t.documentId===e.documentId))
3801
- t?.success&&await n.documentFileManager.syncDocument(e.documentId)}}catch(e){w.warn("Some documents may not have synced properly",{error:e})}const V=await l.handleMultiFileGitCommit(P,x,H,W,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:m,metricsPrefix:"replace_lines"},n),K=l.processMultiFileOperationResults(H,"successfulReplacements"),{successfulOperations:J,failedOperations:Q,totalSuccessfulChanges:Y,overallSuccess:Z,successfulFiles:X,failedFiles:ee}=K
3802
- try{await s.updateToolRecord(k,{metadata:{path:x.length>0?x[0].path:"document:"+M[0]?.documentId,status:Z?"completed":"failed",error:Z?void 0:Q+" operations failed",totalOperations:H.length,successfulFiles:X,failedFiles:ee,operations:z,totalSuccessfulReplacements:Y,totalFailedReplacements:B,totalLinesReplaced:U,totalLinesAdded:G,operationsWithChanges:W,processingTime:Date.now()-b,userComment:S,...x.length>0&&V.success&&V.commitHash&&{commitHash:V.commitHash,previousCommitHash:V.previousCommitHash||void 0}},note:Z?`Line replacement completed: ${J}/${H.length} operations successful${x.length>0?" (committed to git)":""}`:`Line replacement partially failed: ${Q}/${H.length} operations failed`})}catch(e){w.warn("Failed to update tool record",{recordError:e})}let te="## Line Replacement Results\n\n"
3846
+ 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,W,{operationType:"Replace lines",toolRecordId:k,successField:"successfulReplacements",logger:w,metrics:m,metricsPrefix:"replace_lines"},n),Q=l.processMultiFileOperationResults(H,"successfulReplacements"),{successfulOperations:K,failedOperations:J,totalSuccessfulChanges:Y,overallSuccess:Z,successfulFiles:X,failedFiles:ee}=Q
3847
+ 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:G,operationsWithChanges:W,processingTime:Date.now()-b,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"
3803
3848
  if(n.workspaceManager){const e=n.workspaceManager.getCurrentContext(n.currentSessionId)
3804
- e.permanentBranch||(te+=`**Branch:** \`${e.branchName}\`\n\n`)}if(te+="**Summary:**\n",te+=`- **Files processed:** ${J+Q}\n`,te+=`- **Successful operations:** ${J}\n`,te+=`- **Failed operations:** ${Q}\n`,te+=`- **Total replacements:** ${Y} successful, ${B} failed\n`,te+=`- **Total Lines Replaced:** ${U}\n`,G>0&&(te+=`- **Total Lines Added:** ${G}\n`),te+="\n",V.success&&V.commitHash&&(te+="**Git Commit:**\n",te+=`- **Commit Hash:** ${V.commitHash.substring(0,8)}\n`,te+=`- **Files Committed:** ${V.filesCommitted.length}\n`,V.previousCommitHash&&(te+=`- **Previous Commit:** ${V.previousCommitHash.substring(0,8)}\n`),te+="\n"),1===H.length){const e=H[0]
3849
+ 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`,G>0&&(te+=`- **Total Lines Added:** ${G}\n`),te+="\n",V.success&&V.commitHash&&(te+="**Git Commit:**\n",te+=`- **Commit Hash:** ${V.commitHash.substring(0,8)}\n`,te+=`- **Files Committed:** ${V.filesCommitted.length}\n`,V.previousCommitHash&&(te+=`- **Previous Commit:** ${V.previousCommitHash.substring(0,8)}\n`),te+="\n"),1===H.length){const e=H[0]
3805
3850
  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"
3806
- 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`,G>0&&(te+=`- **Total Lines Added:** ${G}\n`),te+="\n",te+="**Detailed Results:**\n\n"
3851
+ 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`,G>0&&(te+=`- **Total Lines Added:** ${G}\n`),te+="\n",te+="**Detailed Results:**\n\n"
3807
3852
  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"
3808
3853
  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")
3809
3854
  const re=Date.now()-b
3810
- return w.info("Replace lines operation completed",{duration:re,success:Z,totalOperations:H.length,successfulOperations:J,failedOperations:Q}),m.incrementCounter("replace_lines_total",1,{success:Z}),{content:[{type:"text",text:te}],isError:!Z}}catch(t){const r=Date.now()-b
3855
+ return w.info("Replace lines operation completed",{duration:re,success:Z,totalOperations:H.length,successfulOperations:K,failedOperations:J}),m.incrementCounter("replace_lines_total",1,{success:Z}),{content:[{type:"text",text:te}],isError:!Z}}catch(t){const r=Date.now()-b
3811
3856
  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}}}
3812
3857
  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"
3813
- 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"})
3814
- try{const s=t.projectId
3815
- if(!s)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
3816
- 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})
3817
- 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}
3818
- 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
3819
- 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
3820
- if(d.canBeActivePlan)try{const e=o.getProjectClient(),t=await e.getProject(s)
3821
- 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}}}
3822
- const r=t(8824),n=t(3416)},6688(e,exports,t){"use strict"
3858
+ 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"})
3859
+ try{const o=t.projectId
3860
+ if(!o)return{content:[{type:"text",text:"\u274c No project context available. Please ensure project is initialized."}],isError:!0}
3861
+ const s=`PLAN-${e.name.replace(/\.md$/i,"")}.md`,i=n.getDocumentClient(),l=await i.listDocuments({type:"Plan",filename:s,limit:1,offset:0})
3862
+ 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}
3863
+ 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
3864
+ 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
3865
+ try{const e=n.getProjectClient(),t=await e.getProject(o)
3866
+ 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}}}
3867
+ const r=t(8824)},6688(e,exports,t){"use strict"
3823
3868
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.sessionIdentity=void 0
3824
3869
  const r=t(9896),n=t(6928),o=t(3545)
3825
3870
  exports.sessionIdentity=new class{constructor(){this.parentCache=new Map,this.sessionRequestCache=new Map}setIdentity(e){const t=this.identity
@@ -3904,9 +3949,9 @@ const f=r.getTaskClient(),y=r.getToolRecordClient(),w=t.projectId
3904
3949
  let b
3905
3950
  r.setProjectId(w)
3906
3951
  try{const j=await f.getTask(g)
3907
- s.info("Raw task response data",{responseDataType:typeof j,isArray:Array.isArray(j),hasData:null!=j,properties:j&&"object"==typeof j?Object.keys(j):[]}),b=(0,l.extractDataFromResponse)(j,{logger:s,operationName:"getTask",defaultValue:{id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+b.title)}catch(R){s.warn("Could not fetch task information: "+(0,u.getErrorMessage)(R)),b={id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let I=[]
3908
- try{const x=await y.getToolRecordsByTaskId(g)
3909
- if(s.info("Raw records response data",{responseDataType:typeof x,isArray:Array.isArray(x),hasData:null!=x,properties:x&&"object"==typeof x?Object.keys(x):[]}),I=(0,l.extractArrayFromResponse)(x,{logger:s,operationName:"searchRecords",defaultValue:[]}),I.length>0&&s.info("First record summary:",{id:I[0].id,type:I[0].type,hasMetadata:!!I[0].metadata,hasCommitHash:!!I[0].metadata?.commitHash}),s.info(`Extracted ${I.length} records for task ${g}`),I.length>0){const M={}
3952
+ s.info("Raw task response data",{responseDataType:typeof j,isArray:Array.isArray(j),hasData:null!=j,properties:j&&"object"==typeof j?Object.keys(j):[]}),b=(0,l.extractDataFromResponse)(j,{logger:s,operationName:"getTask",defaultValue:{id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}),s.info("Found task: "+b.title)}catch(x){s.warn("Could not fetch task information: "+(0,u.getErrorMessage)(x)),b={id:g,title:"Unknown Task",status:"unknown",description:"No description available"}}let I=[]
3953
+ try{const R=await y.getToolRecordsByTaskId(g)
3954
+ 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):[]}),I=(0,l.extractArrayFromResponse)(R,{logger:s,operationName:"searchRecords",defaultValue:[]}),I.length>0&&s.info("First record summary:",{id:I[0].id,type:I[0].type,hasMetadata:!!I[0].metadata,hasCommitHash:!!I[0].metadata?.commitHash}),s.info(`Extracted ${I.length} records for task ${g}`),I.length>0){const M={}
3910
3955
  I.forEach((e=>{M[e.type]=(M[e.type]||0)+1})),s.info("Record type distribution:",M)}}catch(O){s.warn("Error fetching records for task "+g,{error:(0,u.getErrorMessage)(O)}),I=[]}if(0===I.length)return p({success:!0,recordCount:0}),{content:[{type:"text",text:`No records found for task ${g}.`}]}
3911
3956
  function k(e){const t=new Map,r=new Map,n=[]
3912
3957
  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
@@ -3962,9 +4007,9 @@ const z=new Map
3962
4007
  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(" -> ")}`)}))
3963
4008
  const L=N.filter((e=>e.commitHash))
3964
4009
  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`)
3965
- try{if(t.git){const J={file:F,n:10},Q=await t.git.log(J)
3966
- if(Q&&Q.all&&Q.all.length>0){s.info(`Found ${Q.all.length} commits for ${F} using git log`)
3967
- 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}}})))
4010
+ try{if(t.git){const K={file:F,n:10},J=await t.git.log(K)
4011
+ if(J&&J.all&&J.all.length>0){s.info(`Found ${J.all.length} commits for ${F} using git log`)
4012
+ 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}}})))
3968
4013
  if(Y.length>0){const Z=Y.length>1?Y[Y.length-1]:Y[0],X=Y[0],ee=1===Y.length
3969
4014
  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"}`)
3970
4015
  let te=""
@@ -3984,33 +4029,33 @@ for(const pe of he)ue+=`+${pe}\n`
3984
4029
  E.set(F,{firstChange:W,lastChange:B,hasDiff:!0,diffText:ue}),s.info(`Formatted new file content as diff, ${he.length} lines`)
3985
4030
  continue}}catch(ge){s.warn("Error getting new file content for "+F,{error:(0,u.getErrorMessage)(ge)})}E.set(F,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"Only one commit available for this file"})
3986
4031
  continue}if(H.commitHash===B.commitHash&&G){if(U===H.commitHash){E.set(F,{firstChange:W,lastChange:B,hasDiff:!1,diffText:"No changes detected"})
3987
- continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let V="",K=!1
3988
- if(m||"pre-task"!==W.status){try{if(t.git){try{await t.git.show([`${B.commitHash}:${F}`])}catch(fe){s.warn(`File ${F} does not exist in commit ${B.commitHash}, might be deleted or moved`),V="File was deleted or moved from this location during the task",K=!0,E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V})
4032
+ continue}s.info("Special case: First and last task commits are the same, but pre-task commit is different")}let V="",Q=!1
4033
+ if(m||"pre-task"!==W.status){try{if(t.git){try{await t.git.show([`${B.commitHash}:${F}`])}catch(fe){s.warn(`File ${F} does not exist in commit ${B.commitHash}, might be deleted or moved`),V="File was deleted or moved from this location during the task",Q=!0,E.set(F,{firstChange:W,lastChange:B,hasDiff:Q,diffText:V})
3989
4034
  continue}let me
3990
- if("pre-task"===W.status?(me=[`${W.commitHash}..${B.commitHash}`,"--",F],s.info(`Comparing pre-task commit with final commit: ${W.commitHash?W.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${F}`)):(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&&W.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
4035
+ if("pre-task"===W.status?(me=[`${W.commitHash}..${B.commitHash}`,"--",F],s.info(`Comparing pre-task commit with final commit: ${W.commitHash?W.commitHash.substring(0,8):"unknown"}..${B.commitHash?B.commitHash.substring(0,8):"unknown"} for ${F}`)):(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),Q=!!V&&V.trim().length>0,!Q&&W.commitHash!==B.commitHash){s.info("No diff found between commits but commits are different, trying direct file content comparison")
3991
4036
  try{const ye=await t.git.show([`${W.commitHash}:${F}`]),we=await t.git.show([`${B.commitHash}:${F}`])
3992
- if(ye!==we&&(K=!0,V="Changes detected through direct content comparison (not visible in standard diff)",m)){const be=ye.split("\n"),Ie=we.split("\n")
3993
- Math.abs(be.length-Ie.length)>0&&(V+=`\n\nLine count changed: ${be.length} \u2192 ${Ie.length}`),ye.includes("\0")||we.includes("\0")?V+="\n\nBinary content detected - changes not displayed":ye.replace(/\s+/g,"")===we.replace(/\s+/g,"")&&(V+="\n\nWhitespace-only changes detected")}}catch(ke){s.warn("Error in direct file comparison: "+(ke instanceof Error?ke.message:ke+""))}}s.info(`Diff generation result for ${F}: hasDiff=${K}, length=${V.length}`)}}catch(ve){if(s.warn("Error getting diff for "+F,{error:(0,u.getErrorMessage)(ve),firstCommit:H.commitHash||"unknown",lastCommit:B.commitHash||"unknown"}),V="Error getting diff: "+(0,u.getErrorMessage)(ve),"pre-task"!==H.status&&t.git)try{const Ce=[`${B.commitHash}:${F}`]
4037
+ if(ye!==we&&(Q=!0,V="Changes detected through direct content comparison (not visible in standard diff)",m)){const be=ye.split("\n"),Ie=we.split("\n")
4038
+ Math.abs(be.length-Ie.length)>0&&(V+=`\n\nLine count changed: ${be.length} \u2192 ${Ie.length}`),ye.includes("\0")||we.includes("\0")?V+="\n\nBinary content detected - changes not displayed":ye.replace(/\s+/g,"")===we.replace(/\s+/g,"")&&(V+="\n\nWhitespace-only changes detected")}}catch(ke){s.warn("Error in direct file comparison: "+(ke instanceof Error?ke.message:ke+""))}}s.info(`Diff generation result for ${F}: hasDiff=${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}`]
3994
4039
  s.info(`Trying fallback to show file content using git show: ${B.commitHash?B.commitHash.substring(0,8):"unknown"}:${F}`)
3995
4040
  const _e=await t.git.show(Ce)
3996
4041
  if(_e&&_e.trim().length>0){if(m){let Ee=""
3997
4042
  const Se=_e.split("\n")
3998
4043
  for(const Te of Se)Ee+=`+${Te}\n`
3999
4044
  V=Ee}else V="File created during this task. Content:\n"+_e
4000
- K=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(qe){s.warn("Fallback also failed for "+F,{error:qe instanceof Error?qe.message:qe+""})}}E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V||"No changes detected between commits"})}else K=W.commitHash!==B.commitHash,V=K?"File has changes":"No changes detected between commits",E.set(F,{firstChange:W,lastChange:B,hasDiff:K,diffText:V})}let S=`# File Changes for Task: ${g}\n\n`
4045
+ Q=!0,s.info("Fallback succeeded, got file content of length "+_e.length)}}catch(qe){s.warn("Fallback also failed for "+F,{error:qe instanceof Error?qe.message:qe+""})}}E.set(F,{firstChange:W,lastChange:B,hasDiff:Q,diffText:V||"No changes detected between commits"})}else Q=W.commitHash!==B.commitHash,V=Q?"File has changes":"No changes detected between commits",E.set(F,{firstChange:W,lastChange:B,hasDiff:Q,diffText:V})}let S=`# File Changes for Task: ${g}\n\n`
4001
4046
  b&&"object"==typeof b&&(S+="## Task Information\n",S+=`- **Title**: ${b.title||"Unknown"}\n`,S+=`- **Status**: ${b.status||"Unknown"}\n`,S+=`- **Description**: ${b.description||"No description"}\n\n`)
4002
4047
  const T=3e3
4003
4048
  let q=0,P=!1
4004
4049
  if(m){for(const Pe of E.values())Pe.hasDiff&&Pe.diffText&&(q+=Pe.diffText.split("\n").length)
4005
4050
  P=q>T,s.info(`Total diff size: ${q} lines (limit: ${T} 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 ${q} lines exceeds limit of ${T} 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`
4006
4051
  for(const je of v.allMoves)S+=`- **${je.source}** \u2192 **${je.destination}**\n`,S+=` - Operation: ${je.type}\n`,S+=` - Timestamp: ${new Date(je.timestamp).toLocaleString()}\n`,S+=` - Record ID: ${je.recordId}\n\n`}S+="## Modified Files\n\n"
4007
- for(const[Re,xe]of E.entries()){const{normalizedPath:Me,fullPath:Oe}=d.validateAndNormalizePath(Re,t)
4052
+ for(const[xe,Re]of E.entries()){const{normalizedPath:Me,fullPath:Oe}=d.validateAndNormalizePath(xe,t)
4008
4053
  let $e=!1
4009
- try{await a.access(Oe),$e=!0}catch{}S+=`### ${Re} ${$e?"":"(Deleted)"}\n\n`
4010
- const De=new Date(xe.firstChange.timestamp).toLocaleString(),Ae=new Date(xe.lastChange.timestamp).toLocaleString()
4011
- S+=`**First Change**: ${De}\n`,S+=`**Last Change**: ${Ae}\n`,"pre-task"===xe.firstChange.status&&xe.firstChange.commitHash?S+=`**Pre-Task Commit**: ${xe.firstChange.commitHash.substring(0,8)}\n`:xe.firstChange.commitHash&&(S+=`**File Created During Task**: ${xe.firstChange.commitHash.substring(0,8)}\n`),xe.lastChange.commitHash&&(S+=`**Final Commit**: ${xe.lastChange.commitHash.substring(0,8)}\n`)
4012
- const Fe=v.sourceToMove.get(Re),Ne=v.destToMove.get(Re)
4013
- Fe?S+=`**\u2139\ufe0f Move Operation**: This file was moved TO **${Fe.destination}**\n`:Ne&&(S+=`**\u2139\ufe0f Move Operation**: This file was moved FROM **${Ne.source}**\n`),m&&!P?xe.hasDiff?(S+="\n**Changes**:\n",S+="```diff\n",S+=xe.diffText,S+="\n```\n\n"):S+=`\n**Note**: ${xe.diffText}\n\n`:P&&xe.hasDiff?(S+=`\n**Note**: File has changes (${xe.diffText?xe.diffText.split("\n").length:0} lines). `,S+=`Compare ${xe.firstChange.commitHash?xe.firstChange.commitHash.substring(0,8):"unknown"}..${xe.lastChange.commitHash?xe.lastChange.commitHash.substring(0,8):"unknown"} to see changes.\n\n`):xe.hasDiff?S+="\n**Note**: File has changes. Use showDiff=true to see the diff.\n\n":S+=`\n**Note**: ${xe.diffText}\n\n`,S+="---\n\n"}return p({success:!0,fileCount:_.size}),{content:[{type:"text",text:S}]}}catch(ze){return s.error("Error in task file history tool",{error:ze instanceof Error?ze.stack:ze+""}),p({success:!1,error:ze instanceof Error?ze.name:"unknown"}),{content:[{type:"text",text:"Error: "+(0,u.getErrorMessage)(ze)}],isError:!0}}}
4054
+ try{await a.access(Oe),$e=!0}catch{}S+=`### ${xe} ${$e?"":"(Deleted)"}\n\n`
4055
+ const De=new Date(Re.firstChange.timestamp).toLocaleString(),Ae=new Date(Re.lastChange.timestamp).toLocaleString()
4056
+ 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`)
4057
+ const Fe=v.sourceToMove.get(xe),Ne=v.destToMove.get(xe)
4058
+ 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}}}
4014
4059
  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"
4015
4060
  module.exports=require("path")},6975(e,exports,t){"use strict"
4016
4061
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClientAdapter=void 0
@@ -4171,8 +4216,9 @@ p.debug("Create request response structure",{type:typeof k,isArray:Array.isArray
4171
4216
  const v=(0,o.extractDataFromResponse)(k,{logger:p,operationName:"createRequest",throwOnNoData:!0}),C="data"in v?v.data:v
4172
4217
  let _,E={created:!1}
4173
4218
  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})
4174
- p.info("Request created successfully",{requestId:C.id,title:C.title,branchCreated:E.created,branchName:E.branchName})
4175
- try{const e=c.getToolRecordClient()
4219
+ 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)
4220
+ if(t&&"Quest"===t.type){const r={...t.metadata||{},consecutiveDoneAudits:0}
4221
+ 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()
4176
4222
  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"}`})
4177
4223
  _=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
4224
  const S=C.localId||C.id
@@ -4369,23 +4415,27 @@ const h=t(3444),p=t(9860),g=t(3922),m=t(8824),f=u(t(9896)),y=u(t(6928))
4369
4415
  t(857)},7575(e,exports){"use strict"
4370
4416
  var t
4371
4417
  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"
4372
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleUpdatePlan=async function(e,t,n,o){const s=o.child({tool:"plan_operations",operation:"update"})
4373
- try{const t=n.getDocumentClient(),r=await t.getDocument(e.planId)
4418
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleUpdatePlan=async function(e,t,o,s){const i=s.child({tool:"plan_operations",operation:"update"})
4419
+ try{const t=o.getDocumentClient(),r=await t.getDocument(e.planId)
4374
4420
  if(!r)return{content:[{type:"text",text:"\u274c Plan not found: "+e.planId}],isError:!0}
4375
- const o="Quest"===r.type
4376
- 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}
4377
- const i={}
4378
- void 0!==e.content&&(i.content=e.content),e.name&&(i.filename=e.name.replace(/\.md$/i,"")+".md")
4379
- const a=e.metadata||{},c=["criteria","tickIntervalSeconds","maxInFlight","maxPerDay","minIterations","status"].filter((e=>void 0!==a[e]))
4380
- 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}
4421
+ const s="Quest"===r.type
4422
+ 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}
4423
+ const a={}
4424
+ void 0!==e.content&&(a.content=e.content),e.name&&(a.filename=e.name.replace(/\.md$/i,"")+".md")
4425
+ const c=e.metadata||{},l=n.QUEST_METADATA_KEYS.filter((e=>void 0!==c[e]))
4426
+ 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}
4427
+ 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}
4428
+ 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}
4381
4429
  const t={...r.metadata||{}}
4382
- for(const e of c)t[e]=a[e]
4383
- 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}
4384
- const l=await t.updateDocument(e.planId,i),d=l.localId||l.id
4385
- s.info("Plan/Quest updated",{planId:d,isQuest:o,changedMetadata:c})
4386
- const u=o?"Quest":"Plan",h=[]
4387
- 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}}}
4388
- const r=t(8824)},7613(e,exports,t){"use strict"
4430
+ for(const e of l)t[e]=c[e]
4431
+ 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}
4432
+ const d=r.metadata||{}
4433
+ if(d.isStub){const e=a.metadata??{...d}
4434
+ delete e.isStub,a.metadata=e}const u=await t.updateDocument(e.planId,a),h=u.localId||u.id
4435
+ i.info("Plan/Quest updated",{planId:h,isQuest:s,changedMetadata:l})
4436
+ const p=s?"Quest":"Plan",g=[]
4437
+ return void 0!==a.content&&g.push("content"),a.filename&&g.push("filename="+u.filename),l.length>0&&g.push(`metadata(${l.join(", ")})`),{content:[{type:"text",text:`\u2705 **${p} Updated**\n\n**ID:** ${h}\n**Filename:** ${u.filename}\n**Changes:** ${g.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}}}
4438
+ const r=t(8824),n=t(3416)},7613(e,exports,t){"use strict"
4389
4439
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
4390
4440
  const r=t(6183),n=t(9072)
4391
4441
  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"
@@ -4800,19 +4850,19 @@ const S=await l.validateTaskId(C,_,n,m,p,I.metricsPrefix),T=S?.requestId,q=await
4800
4850
  P.taskPromoted&&m.info(`Auto-promoted task ${C} (${S.title||"Untitled"}) to in_progress for file operation`,{taskId:C,taskTitle:S.title,previousStatus:S.status,newStatus:P.newTaskStatus,path:_}),P.requestPromoted&&m.info(`Auto-promoted request ${T} to in_progress for file operation`,{requestId:T,previousStatus:q.request?.status,newStatus:P.newRequestStatus,triggeringTaskId:C})
4801
4851
  const j=await l.ensureCorrectWorkspaceContext({taskPromoted:P.taskPromoted,requestId:T,context:r,operation:"create-directory",logger:m,metrics:p,metricsPrefix:I.metricsPrefix})
4802
4852
  if(!j.success)throw Error(j.error)
4803
- let R=!1
4804
- try{R=(await a.default.stat(E)).isDirectory()}catch{R=!1}b=l.FileOperationPhase.RECORD_CREATION,p.incrementCounter("create_directory_phase",1,{phase:b})
4805
- const{toolRecordId:x,localToolRecordId:M}=await l.createFileOperationRecords(C,T,r.projectId,I.recordType,_,{directoryExists:R,userComment:h},n,o,m,p,I.metricsPrefix,g)
4806
- y=x,w=x,b=I.fileOperationPhase,p.incrementCounter("create_directory_phase",1,{phase:b})
4807
- let O=R
4808
- if(!R){await a.default.mkdir(E,{recursive:!0}),m.info("Successfully created directory "+_)
4853
+ let x=!1
4854
+ try{x=(await a.default.stat(E)).isDirectory()}catch{x=!1}b=l.FileOperationPhase.RECORD_CREATION,p.incrementCounter("create_directory_phase",1,{phase:b})
4855
+ const{toolRecordId:R,localToolRecordId:M}=await l.createFileOperationRecords(C,T,r.projectId,I.recordType,_,{directoryExists:x,userComment:h},n,o,m,p,I.metricsPrefix,g)
4856
+ y=R,w=R,b=I.fileOperationPhase,p.incrementCounter("create_directory_phase",1,{phase:b})
4857
+ let O=x
4858
+ if(!x){await a.default.mkdir(E,{recursive:!0}),m.info("Successfully created directory "+_)
4809
4859
  try{const e=c.default.join(E,".gitkeep")
4810
4860
  await a.default.writeFile(e,"# This file makes the directory trackable by Git\n"),O=!0,m.info("Created .gitkeep file for Git tracking")}catch(e){m.warn("Failed to create .gitkeep file",{error:e instanceof Error?e.message:e+""}),O=!1}}const $=Date.now()-f
4811
4861
  p.recordValue("create_directory_time",$),p.incrementCounter("create_directory_success",1),b=l.FileOperationPhase.GIT_COMMIT,p.incrementCounter("create_directory_phase",1,{phase:b})
4812
- const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!R&&O?_+"/.gitkeep":_,F=await l.commitToGit(C,A,x,M,D,r,m,p,I.metricsPrefix)
4813
- b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,p.incrementCounter("create_directory_phase",1,{phase:b}),await l.updateFileOperationRecords(C,y,w,_,I.recordType,`Successfully ${R?"verified":"created"} directory: ${_}`,{status:"completed",commitHash:F.commitHash,previousCommitHash:F.previousCommitHash,directoryExists:R,isDirectory:!0,userComment:h},`Successfully ${R?"verified":"created"} directory: ${_}`,n,o,m,p,I.metricsPrefix)
4862
+ const D=`Create directory: ${_} - ${h||"Create directory"}`,A=!x&&O?_+"/.gitkeep":_,F=await l.commitToGit(C,A,R,M,D,r,m,p,I.metricsPrefix)
4863
+ b=l.FileOperationPhase.RECORD_UPDATE_SUCCESS,p.incrementCounter("create_directory_phase",1,{phase:b}),await l.updateFileOperationRecords(C,y,w,_,I.recordType,`Successfully ${x?"verified":"created"} directory: ${_}`,{status:"completed",commitHash:F.commitHash,previousCommitHash:F.previousCommitHash,directoryExists:x,isDirectory:!0,userComment:h},`Successfully ${x?"verified":"created"} directory: ${_}`,n,o,m,p,I.metricsPrefix)
4814
4864
  const N=r.getCurrentBranchContext?await r.getCurrentBranchContext():{branch:null,requestId:null,isMain:!0}
4815
- return{content:[{type:"text",text:R?"Directory already exists":`Successfully created directory${F.commitHash?"\nCommit: "+F.commitHash.substring(0,8):""}${N.requestId&&!N.permanentBranch?"\nBranch: "+N.requestId:""}`}]}}catch(t){if(e.taskId&&o)try{const n=t instanceof d.NotFoundError||t instanceof d.ValidationError||t instanceof u.ZodError
4865
+ return{content:[{type:"text",text:x?"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
4816
4866
  await o.createToolRecord({...n?{}:{taskId:e.taskId},projectId:r.projectId,type:"create-directory",metadata:{status:"failed",timestamp:(new Date).toISOString(),path:e.path,userComment:e.comment,error:(0,h.getErrorMessage)(t),errorDetails:t instanceof Error?t.stack:t+"",phase:b,attemptedTaskId:e.taskId,taskIdValidationFailed:n},note:`Failed to create directory ${e.path} - ${(0,h.getErrorMessage)(t)}`})}catch(t){m.error("Failed to create failure record for create directory operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,path:e.path})}const s=Date.now()-f
4817
4867
  if(p.recordValue("create_directory_time",s),p.incrementCounter("create_directory_errors",1),m.error("Error creating directory:",{error:(0,h.getErrorMessage)(t),time:s}),(y||w)&&e.taskId){b=l.FileOperationPhase.RECORD_UPDATE_FAILURE
4818
4868
  try{await l.updateFileOperationRecords(e.taskId,y,w,e.path,I.recordType,"Failed to create directory "+e.path,{status:"failed",error:(0,h.getErrorMessage)(t),userComment:e.comment},"Failed to create directory "+e.path,n,o,m,p,I.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:y,error:t instanceof Error?t.message:t+""})}}return l.handleFileOperationError(t,b,m,p,e,I)}}
@@ -5425,10 +5475,10 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleReplaceInFi
5425
5475
  let C,_=u.FileOperationPhase.VALIDATION
5426
5476
  try{const E=e,{enforceActiveTask:S}=await Promise.resolve().then(t.bind(t,3451)),T=await S(r,o,a,e.taskId)
5427
5477
  if("errorResult"in T)return T.errorResult
5428
- const{taskId:q}=T,{operations:P,fuzzy_match:j=!0,comment:R}=E
5429
- k.info("Replace in files batch operation",{taskId:q,operationCount:P.length,totalReplacements:P.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:j,comment:R})
5430
- const x=P.filter((e=>e.documentId)).map((e=>e.documentId))
5431
- if(x.length>0&&r.apiClient)try{await(0,f.ensureDocumentsNotLocked)(x,r.apiClient,k,c,"replace_in_files-documents")}catch(e){if(e instanceof p.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5478
+ const{taskId:q}=T,{operations:P,fuzzy_match:j=!0,comment:x}=E
5479
+ k.info("Replace in files batch operation",{taskId:q,operationCount:P.length,totalReplacements:P.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:j,comment:x})
5480
+ const R=P.filter((e=>e.documentId)).map((e=>e.documentId))
5481
+ if(R.length>0&&r.apiClient)try{await(0,f.ensureDocumentsNotLocked)(R,r.apiClient,k,c,"replace_in_files-documents")}catch(e){if(e instanceof p.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5432
5482
  throw e}_=u.FileOperationPhase.TASK_VALIDATION,c.incrementCounter("replace_in_files_phase",1,{phase:_})
5433
5483
  const M=P[0],O=M.documentId?"document:"+M.documentId:M.path
5434
5484
  let $=Date.now()
@@ -5443,7 +5493,7 @@ const t=await u.autoPromoteTaskStatus(q,D.status,A,e.request?.status,O,o,i,k,c,"
5443
5493
  t.taskPromoted&&k.info("Auto-promoted task to in_progress",{taskId:q,requestId:A,previousStatus:D.status,newStatus:t.newTaskStatus}),Date.now(),$=Date.now()
5444
5494
  const n=await u.ensureCorrectWorkspaceContext({taskPromoted:t.taskPromoted,requestId:A,context:r,operation:"replace_in_files",logger:k,metrics:c,metricsPrefix:"replace_in_files"})
5445
5495
  if(!n.success)throw Error(n.error)
5446
- Date.now(),N=!0}if(x.length>0&&A)try{await(0,g.validateRequestStatusForDocumentOperation)(A,i,k,c,"replace_in_files-documents")}catch(e){if(e instanceof p.ValidationError)return{content:[{type:"text",text:e.message}],isError:!0}
5496
+ 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}
5447
5497
  throw e}$=Date.now()
5448
5498
  const z=new Map
5449
5499
  if(k.info("\u{1f50d} Starting external edit detection",{hasFileOperations:F,hasGit:!!r.git,operationCount:P.length}),F&&r.git)for(const e of P)if(e.path&&!e.documentId)try{const t=u.validateAndNormalizePath(e.path,r),n=await l.default.readFile(t.fullPath,"utf8"),o=void 0!==e.fuzzy_match?e.fuzzy_match:j,s=[]
@@ -5454,15 +5504,15 @@ const i=await(0,w.detectExternalEdits)(r.git,o,k)
5454
5504
  k.info("\u{1f50d} External edit detection result",{path:t.normalizedPath,hasExternalEdits:i.hasExternalEdits,conflictingLines:i.conflictingLines,hasMessage:!!i.message}),i.hasExternalEdits&&i.message?(z.set(e.path,{message:i.message,debugInfo:i.debugInfo}),k.warn("\u26a0\ufe0f External edits detected before auto-commit",{path:t.normalizedPath,conflictingLines:i.conflictingLines})):(i.debugInfo&&z.set(e.path,{message:"",debugInfo:i.debugInfo}),k.info("\u2705 No external edit conflicts detected",{path:t.normalizedPath}))}else k.info("\u2139\ufe0f No matches found for external edit detection",{path:t.normalizedPath}),z.set(e.path,{message:"",debugInfo:{detectionRan:!1,reason:"No matches found - patterns not found in file",affectedRegion:"none",uncommittedChanges:"not checked",overlapDetected:!1}})}catch(t){k.warn("Failed to check for external edits before auto-commit",{path:e.path,error:(0,b.getErrorMessage)(t)})}if(Date.now(),$=Date.now(),F&&r.git)try{k.debug("[REPLACE-IN-FILES] Checking for user changes before batch operation")
5455
5505
  const e=await(0,m.commitUserChangesBeforeToolOperation)(r.git,"replace_in_files",{requestId:A,taskId:q,workspaceManager:r.workspaceManager},k,c)
5456
5506
  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:q,userCommitHash:e.commitHash?.substring(0,8),userFilesCommitted:e.filesCommitted}))}catch(e){k.warn("Pre-tool user changes commit failed",{taskId:q,error:e instanceof Error?e.message:e+""})}Date.now(),$=Date.now(),_=u.FileOperationPhase.RECORD_CREATION,c.incrementCounter("replace_in_files_phase",1,{phase:_})
5457
- const{toolRecordId:L}=await u.createFileOperationRecords(q,A,r.projectId,"replace-in-files",O,{operationCount:P.length,totalReplacements:P.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:j,userComment:R},o,s,k,c,"replace_in_files",I)
5507
+ const{toolRecordId:L}=await u.createFileOperationRecords(q,A,r.projectId,"replace-in-files",O,{operationCount:P.length,totalReplacements:P.reduce(((e,t)=>e+t.replacements.length),0),globalFuzzyMatch:j,userComment:x},o,s,k,c,"replace_in_files",I)
5458
5508
  C=L,Date.now(),$=Date.now(),_=u.FileOperationPhase.STRING_REPLACEMENT,c.incrementCounter("replace_in_files_phase",1,{phase:_})
5459
5509
  const H=[],B=[]
5460
5510
  for(const e of P){const t=e.path?z.get(e.path):void 0,o=await n(e,j,r,0,0,t?.message,t?.debugInfo)
5461
5511
  H.push(o),o.successfulReplacements>0&&"file"===o.type&&o.path&&B.push(o.path)}Date.now(),$=Date.now()
5462
5512
  const U=P.filter((e=>e.path&&!e.documentId)).map((e=>({path:e.path}))),G=await u.handleMultiFileGitCommit(q,U,H,B.length,{operationType:"Replace in files",toolRecordId:L||C||"unknown",successField:"successfulReplacements",logger:k,metrics:c,metricsPrefix:"replace_in_files"},r),W=G.commitHash
5463
5513
  Date.now(),Date.now()
5464
- 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})))
5465
- await s.updateToolRecord(C,{metadata:{path:O,status:0===K?"completed":"partial",operationCount:P.length,operations:Y,successfulFiles:Z,failedFiles:X,successfulReplacements:J,failedReplacements:Q,processingTime:Date.now()-v,userComment:R,...G.success&&G.commitHash&&{commitHash:G.commitHash,previousCommitHash:G.previousCommitHash||void 0}}})
5514
+ 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})))
5515
+ await s.updateToolRecord(C,{metadata:{path:O,status:0===Q?"completed":"partial",operationCount:P.length,operations:Y,successfulFiles:Z,failedFiles:X,successfulReplacements:K,failedReplacements:J,processingTime:Date.now()-v,userComment:x,...G.success&&G.commitHash&&{commitHash:G.commitHash,previousCommitHash:G.previousCommitHash||void 0}}})
5466
5516
  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
5467
5517
  let c="## Replace In Files - Batch Results\n\n"
5468
5518
  if(o.workspaceManager)try{const e=o.workspaceManager.getCurrentContext(o.currentSessionId)
@@ -5476,8 +5526,8 @@ if(s.length>0){c+="\n**Failed Replacement Details:**\n"
5476
5526
  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)))
5477
5527
  l.length>0&&(c+=`\n**Document Changes:** ${l.length} modified document(s) synced back to tracking system.\n`)
5478
5528
  const d=o.workspaceManager?.consumeLargeFileWarning(o.currentSessionId)
5479
- return d&&(c+=d),c}(H,W,J,Q,r)
5480
- 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
5529
+ return d&&(c+=d),c}(H,W,K,J,r)
5530
+ 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
5481
5531
  if(k.error("Replace in files batch operation failed",{error:e instanceof Error?e.stack:e+"",duration:t,phase:_}),C)try{await s.updateToolRecord(C,{metadata:{status:"failed",error:(0,b.getErrorMessage)(e),phase:_,duration:t}})}catch(e){}return c.incrementCounter("replace_in_files_errors",1,{phase:_}),{content:[{type:"text",text:"\u274c **Replace In Files Failed:** "+(0,b.getErrorMessage)(e)}],isError:!0}}},c(t(857))
5482
5532
  const l=c(t(1943)),d=(a(t(9896)),a(t(6928)),c(t(6982)),t(2272)),u=a(t(5967)),h=t(3626),p=t(9860),g=t(5003),m=t(7478),f=t(9949),y=t(9947),w=t(1318),b=t(8824)},9470(e,exports){"use strict"
5483
5533
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseLineSpec=function(e){if(!e||""===e.trim())throw Error("Line specification cannot be empty")