alchemylab 1.0.5 → 1.0.7

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.
@@ -823,20 +823,21 @@ let I=Date.now()
823
823
  const b=r(a)
824
824
  if(Date.now(),I=Date.now(),y){const e=await w()
825
825
  if(Date.now(),!e)return m.warn("Unauthenticated tool call attempt",{tool:i}),{content:[{type:"text",text:"Authentication required. Please run 'alchemylab setup' to authenticate and configure your project."}],isError:!0}}const C=(0,f.getToolByName)(i)
826
- if(I=Date.now(),n?(n.setOptions({createRecords:C?.createsRecords??!1}),m.info(`Setting record creation for tool ${i}: ${C?.createsRecords??!1}`)):m.debug(`No API client available for tool ${i} (minimal mode)`),Date.now(),I=Date.now(),t?.workspaceManager&&!t.workspaceManager.readonlyBranchCheckDone)try{const e=await(0,d.getServerUrl)(t,m)
827
- e&&n&&await t.workspaceManager.ensureReadonlyBranchIfNeeded(e,i,n,c?.sessionId)}catch(e){m.debug("Error during readonly branch check",{error:(0,l.getErrorMessage)(e)})}let _,E
828
- if(Date.now(),Date.now(),I=Date.now(),C&&!C.readOnly)if(c?.sessionId){const e=c.sessionId,r=c.messageId,n=u.sessionIdentity.getIdentity()
829
- if(n)n.sessionId!==e&&((0,p.logSessionIdentity)(i,"_meta-session-switch",{prevSessionId:n.sessionId,prevAgentType:n.agentType,newSessionId:e}),u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:n.serverUrl}))
826
+ let _,E
827
+ if(I=Date.now(),n?(n.setOptions({createRecords:C?.createsRecords??!1}),m.info(`Setting record creation for tool ${i}: ${C?.createsRecords??!1}`)):m.debug(`No API client available for tool ${i} (minimal mode)`),Date.now(),Date.now(),I=Date.now(),C&&!C.readOnly)if(c?.sessionId){const e=c.sessionId,r=c.messageId,n=u.sessionIdentity.getIdentity()
828
+ if(n)n.sessionId!==e&&((0,p.logSessionIdentity)(i,"_meta-session-switch",{prevSessionId:n.sessionId,prevAgentType:n.agentType,newSessionId:e}),u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:n.serverUrl}),t?.workspaceManager?.resetCurrentContext?.())
830
829
  else{const r=await(0,d.getServerUrl)(t,m)
831
830
  u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r||""}),u.sessionIdentity.markDiscoveryAttempted()}_={providerId:"opencode",sessionId:e,messageId:r,createdAt:(new Date).toISOString()},(0,p.logSessionIdentity)(i,"_meta",{sessionId:e,messageId:r})}else{const e=u.sessionIdentity.getIdentity()
832
- if(e){let t,r=!1
833
- try{t=await(0,d.findMessageIdForTool)(e.serverUrl,e.sessionId,i)}catch{r=!0}if(t)_=u.sessionIdentity.buildCliOrigin(t)
834
- else if(r)_=u.sessionIdentity.buildCliOrigin()
835
- else{m.info("Session identity mismatch: tool call not found in cached session, re-discovering",{prevSessionId:e.sessionId,prevAgentType:e.agentType,tool:i}),u.sessionIdentity.reset()
831
+ if(e){let r,n=!1
832
+ try{r=await(0,d.findMessageIdForTool)(e.serverUrl,e.sessionId,i)}catch{n=!0}if(r)_=u.sessionIdentity.buildCliOrigin(r)
833
+ else if(n)_=u.sessionIdentity.buildCliOrigin()
834
+ else{m.info("Session identity mismatch: tool call not found in cached session, re-discovering",{prevSessionId:e.sessionId,prevAgentType:e.agentType,tool:i}),u.sessionIdentity.reset(),t?.workspaceManager?.resetCurrentContext?.()
836
835
  try{const t=await(0,d.getAndStoreSessionId)(e.serverUrl,m,i)
837
836
  t?(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e.serverUrl}),(0,p.logSessionIdentity)(i,"re-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId)):(u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),m.info("Re-discovery found no other session, keeping current identity",{sessionId:e.sessionId})),u.sessionIdentity.markDiscoveryAttempted()}catch(t){u.sessionIdentity.setIdentity(e),_=u.sessionIdentity.buildCliOrigin(),u.sessionIdentity.markDiscoveryAttempted(),m.warn("Re-discovery failed, keeping current identity (may be stale)",{error:(0,l.getErrorMessage)(t),tool:i,sessionId:e.sessionId})}}}else if(!u.sessionIdentity.hasDiscoveryBeenAttempted())try{const e=await(0,d.getServerUrl)(t,m)
838
837
  if(e){const t=await(0,d.getAndStoreSessionId)(e,m,i)
839
- t&&(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e}),(0,p.logSessionIdentity)(i,"http-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId))}u.sessionIdentity.markDiscoveryAttempted()}catch(e){u.sessionIdentity.markDiscoveryAttempted(),(0,p.logSessionIdentity)(i,"discovery-failed",{error:(0,l.getErrorMessage)(e)}),m.debug("cliOrigin discovery failed",{error:(0,l.getErrorMessage)(e),tool:i})}}if(u.sessionIdentity.setCurrentCallOrigin(_),!v&&n){const e=u.sessionIdentity.getIdentity(),t=process.env.ALCHEMY_INITIAL_BRANCH
838
+ t&&(u.sessionIdentity.setIdentity({providerId:"opencode",sessionId:t.sessionId,serverUrl:e}),(0,p.logSessionIdentity)(i,"http-discovery",{sessionId:t.sessionId,messageId:t.messageId}),_=u.sessionIdentity.buildCliOrigin(t.messageId))}u.sessionIdentity.markDiscoveryAttempted()}catch(e){u.sessionIdentity.markDiscoveryAttempted(),(0,p.logSessionIdentity)(i,"discovery-failed",{error:(0,l.getErrorMessage)(e)}),m.debug("cliOrigin discovery failed",{error:(0,l.getErrorMessage)(e),tool:i})}}if(u.sessionIdentity.setCurrentCallOrigin(_),t?.workspaceManager&&!t.workspaceManager.readonlyBranchCheckDone){I=Date.now()
839
+ try{const e=await(0,d.getServerUrl)(t,m)
840
+ e&&n&&await t.workspaceManager.ensureReadonlyBranchIfNeeded(e,i,n,c?.sessionId)}catch(e){m.debug("Error during workspace check",{error:(0,l.getErrorMessage)(e)})}Date.now()}if(!v&&n){const e=u.sessionIdentity.getIdentity(),t=process.env.ALCHEMY_INITIAL_BRANCH
840
841
  if(e?.sessionId&&t){const r=t.match(/^requests\/(.+)$/),o="1"===process.env.ALCHEMY_ALLOW_PARALLEL
841
842
  if(r&&!o){const t=r[1]
842
843
  v=!0
@@ -1180,94 +1181,93 @@ const e=this.online,t=await this.performHealthCheck()
1180
1181
  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
1181
1182
  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}}}},1722(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
1182
1183
  const r=t(6183),n=t(355)
1183
- exports.def={name:"complete_task",description:"Mark a task as completed with a summary of work done.",schema:r.CompleteTaskSchema,annotations:{title:"Complete Task",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},handler(e,t){return(0,n.handleCompleteTask)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},1725(e,exports,t){function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,S.join)(e.basePath||process.cwd(),".alchemy_lab","spawn-debug.log");(0,q.appendFileSync)(o,n)}catch{}}async function n(e){try{const t=`http://localhost:${M}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
1184
+ exports.def={name:"complete_task",description:"Mark a task as completed with a summary of work done.",schema:r.CompleteTaskSchema,annotations:{title:"Complete Task",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0},handler(e,t){return(0,n.handleCompleteTask)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},1725(e,exports,t){function r(e,t,r){try{const n=`[${(new Date).toISOString()}] ${t}${r?" "+JSON.stringify(r):""}\n`,o=(0,T.join)(e.basePath||process.cwd(),".alchemy_lab","spawn-debug.log");(0,S.appendFileSync)(o,n)}catch{}}async function n(e){try{const t=`http://localhost:${R}/api/agents/by-name/${encodeURIComponent(e)}`,r=await fetch(t)
1184
1185
  if(!r.ok)return null
1185
1186
  const n=await r.json()
1186
1187
  return n.success?n.data??null:null}catch{return null}}async function o(e,t,o,s,i){const{agent:a="work",prompt:c,requestId:l,allowParallel:d=!1,useExistingSession:u}=e
1187
- if(r(t,"handleSpawn called",{agent:a,promptLength:c.length,requestId:l,useExistingSession:u,cliOriginSessionId:i?.sessionId||null}),!(0,T.isValidAgent)(a)){const e=(0,T.getAgentNames)()
1188
- return{content:[{type:"text",text:`\u274c Unknown agent '${a}'.\n\n**Available agents:** ${e.join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}}try{const e=(0,b.getCachedSession)(),n=i?.sessionId||e?.sessionId
1188
+ if(r(t,"handleSpawn called",{agent:a,promptLength:c.length,requestId:l,useExistingSession:u,cliOriginSessionId:i?.sessionId||null}),!(0,P.isValidAgent)(a)){const e=(0,P.getAgentNames)()
1189
+ return{content:[{type:"text",text:`\u274c Unknown agent '${a}'.\n\n**Available agents:** ${e.join(", ")}\n\nChoose one of the available agents listed above to see detailed descriptions of each agent.`}],isError:!0}}try{const e=(0,v.getCachedSession)(),n=i?.sessionId||e?.sessionId
1189
1190
  let o=e?.agentType
1190
- if(r(t,"Spawn agent type check",{cliOriginSessionId:i?.sessionId||null,cachedSessionId:e?.sessionId||null,cachedAgentType:e?.agentType||null,pid:process.pid,envSessionTag:process.env.ALCHEMY_SESSION_TAG||null,envInitialBranch:process.env.ALCHEMY_INITIAL_BRANCH||null}),!o&&n)try{const e=`http://localhost:${M}/api/sessions/${encodeURIComponent(n)}/agent-type`
1191
+ if(r(t,"Spawn agent type check",{cliOriginSessionId:i?.sessionId||null,cachedSessionId:e?.sessionId||null,cachedAgentType:e?.agentType||null,pid:process.pid,envSessionTag:process.env.ALCHEMY_SESSION_TAG||null,envInitialBranch:process.env.ALCHEMY_INITIAL_BRANCH||null}),!o&&n)try{const e=`http://localhost:${R}/api/sessions/${encodeURIComponent(n)}/agent-type`
1191
1192
  r(t,"Looking up agent type from action server",{sessionId:n,url:e})
1192
1193
  const s=await fetch(e)
1193
1194
  if(s.ok){const e=await s.json()
1194
- r(t,"Agent type response from action server",{sessionId:n,agentType:e.agentType||null,source:e.source||null,success:e.success}),e.success&&e.agentType&&(o=e.agentType,(0,b.updateCachedSession)({agentType:o}))}else r(t,"Agent type lookup failed",{sessionId:n,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e?.sessionId,error:(0,E.getErrorMessage)(n)})}if(o){const e=(0,T.getAllowedSubagents)(o)
1195
- if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${o}' cannot spawn '${a}'.\n\n**Allowed subagents for ${o}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,E.getErrorMessage)(e)})}let h
1195
+ r(t,"Agent type response from action server",{sessionId:n,agentType:e.agentType||null,source:e.source||null,success:e.success}),e.success&&e.agentType&&(o=e.agentType,(0,v.updateCachedSession)({agentType:o}))}else r(t,"Agent type lookup failed",{sessionId:n,status:s.status})}catch(n){r(t,"Agent type lookup error",{sessionId:e?.sessionId,error:(0,q.getErrorMessage)(n)})}if(o){const e=(0,P.getAllowedSubagents)(o)
1196
+ if(e&&!e.includes(a))return{content:[{type:"text",text:`\u274c Agent type '${o}' cannot spawn '${a}'.\n\n**Allowed subagents for ${o}:** ${e.join(", ")}\n\nUse one of the allowed agent types instead.`}],isError:!0}}}catch(e){r(t,"allowedSubagents check failed",{error:(0,q.getErrorMessage)(e)})}let h
1196
1197
  try{const e=await n(a)
1197
- if(h=e?.requestContextMode,!h){const e=(0,T.getBuiltInAgentConfig)(a)
1198
+ if(h=e?.requestContextMode,!h){const e=(0,P.getBuiltInAgentConfig)(a)
1198
1199
  h=e?.requestContextMode}}catch{}if(h&&"none"!==h&&!l)return{content:[{type:"text",text:`\u274c Agent '${a}' requires a requestId to be provided.\n\nThis agent has requestContextMode: '${h}' which means it needs to work in the context of a specific request.\n\nPlease provide a requestId when spawning this agent.`}],isError:!0}
1199
- const g=await(0,I.getServerUrl)(t,o)
1200
+ const g=await(0,b.getServerUrl)(t,o)
1200
1201
  r(t,"serverUrl resolved",{serverUrl:g})
1201
1202
  const p=t.basePath
1202
1203
  if(!p)throw new w.ValidationError("Working directory not available in context")
1203
- const f=(0,b.getCachedSession)()
1204
+ const f=(0,v.getCachedSession)()
1204
1205
  let m
1205
- if(g)try{m=i?.sessionId||f?.sessionId||await(0,I.discoverParentSessionId)(g,o)}catch{}let y=""
1206
+ if(g)try{m=i?.sessionId||f?.sessionId||await(0,b.discoverParentSessionId)(g,o)}catch{}let y=""
1206
1207
  if(s&&l)try{const e=s.getSessionRequestAssociationClient()
1207
1208
  if(e){const t=await e.getSessionsForRequest(l,!0),r=m?t.filter((e=>e.opencodeSessionId!==m)):t
1208
1209
  if(r.length>0){const e=r.map((e=>e.opencodeSessionId)).join(", ")
1209
1210
  if(!d)return o.warn("Blocked spawn: request already has active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId))}),{content:[{type:"text",text:`\u274c Cannot spawn: Request ${l} 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}
1210
- y=`\u26a0\ufe0f Warning: Request ${l} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,o.warn("Spawning parallel subagent for request with existing active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){o.debug("Failed to check for existing workers",{error:(0,E.getErrorMessage)(e)})}let C,_,q=c
1211
- l&&(C="requests/"+l,r(t,"Setting initialBranch for agent",{agent:a,requestId:l,initialBranch:C,agentRequestContextMode:h||"undefined"}),q="readonly"===h?`Working on request ${l} (READONLY mode - you cannot modify files, only explore and report).\n\n${c}`:`Working on request ${l}.\n\n${c}`)
1212
- let S=!1
1213
- if(u){if(_=u,o.info("Using existing session for spawn",{sessionId:_,requestId:l}),!g)throw new w.ValidationError("Could not determine OpenCode server URL")
1211
+ y=`\u26a0\ufe0f Warning: Request ${l} already has ${r.length} active worker(s): ${e}. Proceeding anyway (allowParallel=true).\n\n`,o.warn("Spawning parallel subagent for request with existing active workers",{requestId:l,existingWorkerCount:r.length,existingSessionIds:r.map((e=>e.opencodeSessionId)),allowParallel:!0})}}}catch(e){o.debug("Failed to check for existing workers",{error:(0,q.getErrorMessage)(e)})}let _,E,S=c
1212
+ l&&(_="requests/"+l,r(t,"Setting initialBranch for agent",{agent:a,requestId:l,initialBranch:_,agentRequestContextMode:h||"undefined"}),S="readonly"===h?`Working on request ${l} (READONLY mode - you cannot modify files, only explore and report).\n\n${c}`:`Working on request ${l}.\n\n${c}`)
1213
+ let T=!1
1214
+ if(u){if(E=u,o.info("Using existing session for spawn",{sessionId:E,requestId:l}),!g)throw new w.ValidationError("Could not determine OpenCode server URL")
1214
1215
  try{let e
1215
- try{const t=await fetch(`http://localhost:${M}/api/project-settings`)
1216
+ try{const t=await fetch(`http://localhost:${R}/api/project-settings`)
1216
1217
  if(t.ok){const r=await t.json()
1217
1218
  if(r.data?.defaultModel){const[t,...n]=r.data.defaultModel.split("/")
1218
- e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${_}/message`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:q}],...a?{agent:a}:{},...e?{model:e}:{}})})
1219
+ e={providerID:t,modelID:n.join("/")}}}}catch{}const t=`${g.replace(/\/$/,"")}/session/${E}/prompt_async`,r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:S}],...a?{agent:a}:{},...e?{model:e}:{}}),signal:AbortSignal.timeout(1e4)})
1219
1220
  if(!r.ok){const e=await r.text().catch((()=>"Unknown error"))
1220
- throw Error(`Failed to send to existing session: ${r.status} ${e}`)}o.info("Prompt sent to existing session",{sessionId:_,agent:a})}catch(e){throw Error("Failed to use existing session: "+(0,E.getErrorMessage)(e))}}else{if(S=!0,r(t,"Creating session via HTTP and spawning CLI"),!g)throw Error("Cannot spawn subagent: no server URL available")
1221
- const i=m||f?.sessionId||await(0,I.discoverParentSessionId)(g,o);(0,v.logSessionIdentity)("subagent_operations.spawn",m?"early-discovery":f?"_meta":"http-discovery",{parentSessionId:i}),r(t,"Parent session discovered",{parentSessionId:i})
1221
+ throw Error(`Failed to send to existing session: ${r.status} ${e}`)}o.info("Prompt sent to existing session",{sessionId:E,agent:a})}catch(e){throw Error("Failed to use existing session: "+(0,q.getErrorMessage)(e))}}else{if(T=!0,r(t,"Creating session via HTTP and spawning CLI"),!g)throw Error("Cannot spawn subagent: no server URL available")
1222
+ const i=m||f?.sessionId||await(0,b.discoverParentSessionId)(g,o);(0,C.logSessionIdentity)("subagent_operations.spawn",m?"early-discovery":f?"_meta":"http-discovery",{parentSessionId:i}),r(t,"Parent session discovered",{parentSessionId:i})
1222
1223
  const u=g.replace(/\/$/,"")+"/session",h=e.title?e.title:l?`[${l}] ${c.slice(0,40)}${c.length>40?"...":""}`:`${c.slice(0,50)}${c.length>50?"...":""}`,y=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parentID:i,title:h})})
1223
1224
  if(!y.ok)throw Error("Failed to create session: "+y.status)
1224
1225
  const w=await y.json()
1225
1226
  if(!w.id)throw Error("Session created but no ID returned")
1226
- const R=w.id
1227
- r(t,"Pre-created session with parentID",{preCreatedSessionId:R,parentSessionId:i}),o.info("Pre-created session with parentID",{preCreatedSessionId:R,parentSessionId:i})
1228
- const j=(async()=>{if(s)try{const n=s.getCLISessionClient()
1227
+ const j=w.id
1228
+ r(t,"Pre-created session with parentID",{preCreatedSessionId:j,parentSessionId:i}),o.info("Pre-created session with parentID",{preCreatedSessionId:j,parentSessionId:i})
1229
+ const x=(async()=>{if(s)try{const n=s.getCLISessionClient()
1229
1230
  if(!n)return
1230
1231
  let o,c
1231
- if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:(0,b.getCachedSession)()?.agentType||void 0})
1232
- o=e.id,c=e.workflowId,r(t,"Registered parent session in DB",{parentSessionId:i,parentDbId:o,parentWorkflowId:c})}const l=await n.createOrUpdateSession({externalSessionId:R,providerId:"opencode",parentSessionId:o||null,title:h,status:"active",agentType:a,specialization:e.specialization,workflowId:c||void 0})
1233
- r(t,"Registered child session in DB",{childSessionId:R,childDbId:l.id,parentDbId:o})}catch(e){r(t,"Failed to register sessions in DB",{error:(0,E.getErrorMessage)(e)}),o.warn("Failed to register sessions in alchemy DB",{error:(0,E.getErrorMessage)(e)})}})()
1234
- let x
1232
+ if(i){const e=await n.createOrUpdateSession({externalSessionId:i,providerId:"opencode",status:"active",agentType:(0,v.getCachedSession)()?.agentType||void 0})
1233
+ o=e.id,c=e.workflowId,r(t,"Registered parent session in DB",{parentSessionId:i,parentDbId:o,parentWorkflowId:c})}const l=await n.createOrUpdateSession({externalSessionId:j,providerId:"opencode",parentSessionId:o||null,title:h,status:"active",agentType:a,specialization:e.specialization,workflowId:c||void 0})
1234
+ r(t,"Registered child session in DB",{childSessionId:j,childDbId:l.id,parentDbId:o})}catch(e){r(t,"Failed to register sessions in DB",{error:(0,q.getErrorMessage)(e)}),o.warn("Failed to register sessions in alchemy DB",{error:(0,q.getErrorMessage)(e)})}})()
1235
+ let O
1235
1236
  r(t,"Starting model resolution",{agent:a,cwd:p})
1236
- try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${M}/api/agents/by-name/${a}`})
1237
+ try{r(t,"Fetching agent config from action server",{agent:a,url:`http://localhost:${R}/api/agents/by-name/${a}`})
1237
1238
  const e=await n(a)
1238
1239
  if(r(t,"Agent config result",{agent:a,agentConfig:e||"null",hasConfig:!!e}),e){const n=e.preferredProvider||"inherit",o=e.preferredModelTier||"same"
1239
1240
  r(t,"Agent preferences",{agent:a,preferredProvider:n,preferredTier:o,rawProvider:e.preferredProvider,rawTier:e.preferredModelTier})
1240
- const s=(0,P.resolveAgentModel)(p,n,o)
1241
- r(t,"Model resolution result",{agent:a,result:s}),s.resolved?(x=s.fullModel,r(t,"Resolved agent model",{agent:a,model:x,preferredProvider:n,preferredTier:o})):r(t,"Model resolution fallback",{agent:a,reason:s.reason})}else{const e=(0,T.getBuiltInAgentConfig)(a)
1241
+ const s=(0,M.resolveAgentModel)(p,n,o)
1242
+ r(t,"Model resolution result",{agent:a,result:s}),s.resolved?(O=s.fullModel,r(t,"Resolved agent model",{agent:a,model:O,preferredProvider:n,preferredTier:o})):r(t,"Model resolution fallback",{agent:a,reason:s.reason})}else{const e=(0,P.getBuiltInAgentConfig)(a)
1242
1243
  if(r(t,"No API agent config, checking built-in defaults",{agent:a,builtInConfig:e||"null"}),e){const n=e.preferredProvider||"inherit",o=e.preferredModelTier||"same"
1243
1244
  r(t,"Using built-in agent preferences",{agent:a,preferredProvider:n,preferredTier:o})
1244
- const s=(0,P.resolveAgentModel)(p,n,o)
1245
- r(t,"Built-in model resolution result",{agent:a,result:s}),s.resolved&&(x=s.fullModel,r(t,"Resolved built-in agent model",{agent:a,model:x,preferredProvider:n,preferredTier:o}))}else r(t,"No built-in config found - using default model",{agent:a})}}catch(e){r(t,"Error resolving agent model",{agent:a,error:(0,E.getErrorMessage)(e)})}try{const e=await async function(){try{const e=`http://localhost:${M}/api/project-settings`,t=await fetch(e)
1245
+ const s=(0,M.resolveAgentModel)(p,n,o)
1246
+ r(t,"Built-in model resolution result",{agent:a,result:s}),s.resolved&&(O=s.fullModel,r(t,"Resolved built-in agent model",{agent:a,model:O,preferredProvider:n,preferredTier:o}))}else r(t,"No built-in config found - using default model",{agent:a})}}catch(e){r(t,"Error resolving agent model",{agent:a,error:(0,q.getErrorMessage)(e)})}try{const e=await async function(){try{const e=`http://localhost:${R}/api/project-settings`,t=await fetch(e)
1246
1247
  if(t.ok){const e=await t.json()
1247
1248
  return e?.data?.defaultModel||null}}catch{}return null}()
1248
- if(e)if(x){const o=await n(a)
1249
- "same"===(o?.preferredModelTier||"same")&&(x=e,r(t,"Applied user default model (same tier)",{agent:a,userDefaultModel:e}))}else x=e,r(t,"Using user default model (no agent resolution)",{agent:a,userDefaultModel:e})}catch(e){r(t,"Failed to fetch user default model",{error:(0,E.getErrorMessage)(e)})}r(t,"Final resolved model before spawn",{agent:a,resolvedModel:x||"undefined (will use default)"}),await j
1250
- const O=(0,k.spawnDetachedSubagent)({agent:a,prompt:q,cwd:p,sessionId:R,model:x,initialBranch:C,allowParallel:d,serverUrl:g})
1251
- if(!O.success)throw Error("Failed to spawn subagent: "+O.error)
1252
- _=R,r(t,"CLI spawn successful with pre-created session",{sessionId:R,pid:O.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:R,pid:O.pid,parentSessionId:i})}if(s&&l&&_&&"unknown"!==_&&"spawning"!==_)try{const e=s.getSessionRequestAssociationClient()
1253
- if(e&&(e.createAssociation(_,l).then((()=>o.info("Created session-request association",{sessionId:_,requestId:l}))).catch((e=>o.warn("Failed to create session-request association",{error:(0,E.getErrorMessage)(e),sessionId:_,requestId:l}))),"coder"===a)){const e=s.getRequestClient()
1254
- e&&e.updateRequest(l,{cliOrigin:{providerId:"opencode",sessionId:_,createdAt:(new Date).toISOString()}}).catch((e=>o.debug("Failed to update request cliOrigin",{error:(0,E.getErrorMessage)(e)})))}}catch(e){o.warn("Failed to create session-request association",{error:(0,E.getErrorMessage)(e),sessionId:_,requestId:l})}let R=y
1255
- return u?R+=`Prompt sent to existing session ${_}.`:(R+=`Background ${a} subagent spawned successfully.`,_&&"unknown"!==_&&"spawning"!==_&&(R+=`\n[SESSION:${_}]`)),l&&(R+="\nWorking on: "+l),R+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:R}]}}async function s(e,t,r,n,o,s,i){const a=await(0,I.getServerUrl)(r,n)
1249
+ if(e)if(O){const o=await n(a)
1250
+ "same"===(o?.preferredModelTier||"same")&&(O=e,r(t,"Applied user default model (same tier)",{agent:a,userDefaultModel:e}))}else O=e,r(t,"Using user default model (no agent resolution)",{agent:a,userDefaultModel:e})}catch(e){r(t,"Failed to fetch user default model",{error:(0,q.getErrorMessage)(e)})}if(r(t,"Final resolved model before spawn",{agent:a,resolvedModel:O||"undefined (will use default)"}),await x,l&&_)try{await(0,I.ensureRequestWorktree)(p,l,o)}catch(e){r(t,"Pre-spawn worktree creation failed (non-fatal)",{requestId:l,error:(0,q.getErrorMessage)(e)})}const A=(0,k.spawnDetachedSubagent)({agent:a,prompt:S,cwd:p,sessionId:j,model:O,initialBranch:_,allowParallel:d,serverUrl:g})
1251
+ if(!A.success)throw Error("Failed to spawn subagent: "+A.error)
1252
+ E=j,r(t,"CLI spawn successful with pre-created session",{sessionId:j,pid:A.pid,parentSessionId:i}),o.info("Background subagent spawned via CLI with pre-created session",{agent:a,requestId:l,sessionId:j,pid:A.pid,parentSessionId:i})}if(s&&l&&E&&"unknown"!==E&&"spawning"!==E)try{const e=s.getSessionRequestAssociationClient()
1253
+ if(e&&(e.createAssociation(E,l).then((()=>o.info("Created session-request association",{sessionId:E,requestId:l}))).catch((e=>o.warn("Failed to create session-request association",{error:(0,q.getErrorMessage)(e),sessionId:E,requestId:l}))),"coder"===a)){const e=s.getRequestClient()
1254
+ e&&e.updateRequest(l,{cliOrigin:{providerId:"opencode",sessionId:E,createdAt:(new Date).toISOString()}}).catch((e=>o.debug("Failed to update request cliOrigin",{error:(0,q.getErrorMessage)(e)})))}}catch(e){o.warn("Failed to create session-request association",{error:(0,q.getErrorMessage)(e),sessionId:E,requestId:l})}let j=y
1255
+ return u?j+=`Prompt sent to existing session ${E}.`:(j+=`Background ${a} subagent spawned successfully.`,E&&"unknown"!==E&&"spawning"!==E&&(j+=`\n[SESSION:${E}]`)),l&&(j+="\nWorking on: "+l),j+="\n\nThe subagent is now working independently. You can continue with other tasks.",{content:[{type:"text",text:j}]}}async function s(e,t,r,n,o,s,i){const a=await(0,b.getServerUrl)(r,n)
1256
1256
  if(!a)throw new w.ValidationError("Could not determine OpenCode server URL")
1257
- if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId||(0,b.getCachedSession)()?.sessionId||await(0,I.discoverParentSessionId)(a,n)
1257
+ if(n.info("Sending message to subagent session",{sessionId:e,promptLength:t.length}),o)try{const t=i?.sessionId||(0,v.getCachedSession)()?.sessionId||await(0,b.discoverParentSessionId)(a,n)
1258
1258
  if(t){const r=o.getCLISessionClient()
1259
1259
  if(r){let o=await r.getByExternalId(t)
1260
- o||(o=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),n.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:o?.id})),o&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:o.id,status:"active"}),n.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){n.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,E.getErrorMessage)(e)})}let c=s
1261
- if(!c)try{const t=`http://localhost:${M}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
1260
+ o||(o=await r.createOrUpdateSession({externalSessionId:t,providerId:"opencode",status:"active"}),n.info("Created caller session in DB for re-parenting",{callerSessionId:t,dbId:o?.id})),o&&(await r.createOrUpdateSession({externalSessionId:e,providerId:"opencode",parentSessionId:o.id,status:"active"}),n.info("Updated parent session for reused agent",{sessionId:e,newParentSessionId:t}))}}}catch(e){n.warn("Failed to update parent session - reports may go to wrong parent",{error:(0,q.getErrorMessage)(e)})}let c=s
1261
+ if(!c)try{const t=`http://localhost:${R}/api/sessions/${encodeURIComponent(e)}/agent-type`,r=await fetch(t)
1262
1262
  if(r.ok){const e=await r.json()
1263
1263
  e.success&&e.agentType&&(c=e.agentType)}}catch{n.warn("Agent type lookup failed for session",{sessionId:e})}if(!c)throw new w.ValidationError(`Cannot continue session ${e}: unable to determine agent type. The session's agent type could not be looked up from the action server.`)
1264
1264
  try{let r
1265
- try{const e=await fetch(`http://localhost:${M}/api/project-settings`)
1265
+ try{const e=await fetch(`http://localhost:${R}/api/project-settings`)
1266
1266
  if(e.ok){const t=await e.json()
1267
1267
  if(t.data?.defaultModel){const[e,...n]=t.data.defaultModel.split("/")
1268
- r={providerID:e,modelID:n.join("/")}}}}catch{}const o=`${a.replace(/\/$/,"")}/session/${e}/message`,s=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:t}],...c?{agent:c}:{},...r?{model:r}:{}})})
1268
+ r={providerID:e,modelID:n.join("/")}}}}catch{}const o=`${a.replace(/\/$/,"")}/session/${e}/prompt_async`,s=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:t}],...c?{agent:c}:{},...r?{model:r}:{}}),signal:AbortSignal.timeout(1e4)})
1269
1269
  if(!s.ok){const e=await s.text().catch((()=>"Unknown error"))
1270
- throw Error(`Failed to send message: ${s.status} ${e}`)}return n.info("Message sent to subagent session",{sessionId:e,agent:c}),{content:[{type:"text",text:`Message sent to session ${e}.\nThe subagent will process it in the background.`}]}}catch(e){throw Error("Failed to continue session: "+(0,E.getErrorMessage)(e))}}function i(e){const t=Math.floor(e/1e3)
1270
+ throw Error(`Failed to send message: ${s.status} ${e}`)}return n.info("Message sent to subagent session",{sessionId:e,agent:c}),{content:[{type:"text",text:`Message sent to session ${e}.\nThe subagent will process it in the background.`}]}}catch(e){throw Error("Failed to continue session: "+(0,q.getErrorMessage)(e))}}function i(e){const t=Math.floor(e/1e3)
1271
1271
  if(60>t)return t+"s"
1272
1272
  const r=Math.floor(t/60)
1273
1273
  return 60>r?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function a(e){const t=[]
@@ -1277,10 +1277,10 @@ const s=n.path||n.file||n.directory,i=n.needle||n.query||n.pattern
1277
1277
  "string"==typeof s?o+=" "+(s.split("/").pop()||s):"string"==typeof i&&(o+=` "${i.length>30?i.slice(0,27)+"...":i}"`),t.push({name:o,state:e.state.status,time:r.info.time.created})}t.sort(((e,t)=>t.time-e.time))
1278
1278
  const r=t.find((e=>"pending"===e.state||"running"===e.state)),n=t.filter((e=>"completed"===e.state||"error"===e.state)).slice(0,3),o=t.length>0?t[0].time:null
1279
1279
  return{current:r?.name??null,recent:n.map((e=>e.name)),lastActivityTime:o}}function c(e){return 1e3>e?"<1s ago":6e4>e?Math.floor(e/1e3)+"s ago":36e5>e?Math.floor(e/6e4)+"m ago":Math.floor(e/36e5)+"h ago"}function l(e,t){const r=e||t,n=Date.now()-r
1280
- return e&&R>n?{status:"working",detail:"last action "+c(n),isReady:!1}:n>j&&e?{status:"stalled",detail:"no activity for "+c(n),isReady:!0}:e?{status:"idle",detail:"no activity for "+c(n),isReady:!0}:{status:"idle",detail:"no tool activity",isReady:!0}}function d(e){let t=0,r=0,n=0
1280
+ return e&&j>n?{status:"working",detail:"last action "+c(n),isReady:!1}:n>x&&e?{status:"stalled",detail:"no activity for "+c(n),isReady:!0}:e?{status:"idle",detail:"no activity for "+c(n),isReady:!0}:{status:"idle",detail:"no tool activity",isReady:!0}}function d(e){let t=0,r=0,n=0
1281
1281
  for(const o of e.trim().split("\n")){if(!o)continue
1282
1282
  const[e,s]=o.split("\t")
1283
- "-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function u(e,r,n,o){const s=await(0,I.getServerUrl)(r,n)
1283
+ "-"!==e&&(t+=parseInt(e,10)||0),"-"!==s&&(r+=parseInt(s,10)||0),n++}return{additions:t,deletions:r,files:n}}async function u(e,r,n,o){const s=await(0,b.getServerUrl)(r,n)
1284
1284
  if(!s)throw new w.ValidationError("Could not determine OpenCode server URL")
1285
1285
  n.info("Checking status of subagent session",{sessionId:e})
1286
1286
  try{const c=`${s.replace(/\/$/,"")}/session/${e}`,u=await fetch(c)
@@ -1305,12 +1305,12 @@ if(e.trim())return d(e)}try{const t=n(`git log main --merges --oneline -n 50 --g
1305
1305
  if(t){const e=t.split("\n")[0].split(" ")[0],o=n(`git diff ${e}^1...${e} --numstat`,{cwd:r,encoding:"utf8"})
1306
1306
  if(o.trim())return{...d(o),merged:!0}}}catch{}return null}catch{return null}}(_,r.basePath)
1307
1307
  if(e){const t=e.additions+e.deletions,r=e.merged?" (merged)":""
1308
- v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${k} (${y.detail})\nReady for input: ${I?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${b.toLocaleString()} (in: ${f.input.toLocaleString()}, out: ${f.output.toLocaleString()}${f.reasoning>0?", reasoning: "+f.reasoning.toLocaleString():""})${m}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,E.getErrorMessage)(e))}}async function h(e,t,r){const n=await(0,I.getServerUrl)(t,r)
1308
+ v=`\nDiff vs main (${_}): +${e.additions}/-${e.deletions} lines (${t} total) in ${e.files} file${1!==e.files?"s":""}${r}`}}return{content:[{type:"text",text:`Session ${e}\nTitle: ${h.title||"Untitled"}\nStatus: ${k} (${y.detail})\nReady for input: ${I?"Yes":"No"}\nAge: ${i(w)}\nTokens: ${b.toLocaleString()} (in: ${f.input.toLocaleString()}, out: ${f.output.toLocaleString()}${f.reasoning>0?", reasoning: "+f.reasoning.toLocaleString():""})${m}${C}${v}`}]}}catch(e){throw Error("Failed to check session status: "+(0,q.getErrorMessage)(e))}}async function h(e,t,r){const n=await(0,b.getServerUrl)(t,r)
1309
1309
  if(!n)throw new w.ValidationError("Could not determine OpenCode server URL")
1310
1310
  r.info("Aborting subagent session",{sessionId:e})
1311
1311
  try{const t=`${n.replace(/\/$/,"")}/session/${e}/abort`,o=await fetch(t,{method:"POST"})
1312
1312
  if(!o.ok){const e=await o.text().catch((()=>"Unknown error"))
1313
- throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,E.getErrorMessage)(e))}}async function g(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:c,minTokens:d,maxTokens:u,maxAgeHours:h}=n,g=await(0,I.getServerUrl)(e,t)
1313
+ throw Error(`Failed to abort session: ${o.status} ${e}`)}return r.info("Session aborted",{sessionId:e}),{content:[{type:"text",text:`Session ${e} has been aborted.`}]}}catch(e){throw Error("Failed to abort session: "+(0,q.getErrorMessage)(e))}}async function g(e,t,r,n={}){const{activeOnly:o=!1,requestId:s,limit:c,minTokens:d,maxTokens:u,maxAgeHours:h}=n,g=await(0,b.getServerUrl)(e,t)
1314
1314
  if(!g)throw new w.ValidationError("Could not determine OpenCode server URL")
1315
1315
  t.info("Listing sessions",{filters:n})
1316
1316
  try{const e=g.replace(/\/$/,"")+"/session",t=await fetch(e)
@@ -1346,7 +1346,7 @@ const C=t.title||"Untitled",_=C.length>50?C.slice(0,47)+"...":C
1346
1346
  v.push({id:t.id,title:_,status:f,age:r,totalTokens:o,requestsInfo:y,allRequestIds:I,statusDetail:h.detail,specialization:m?.specialization??null,currentAction:i,recentActions:c})}if(0===v.length)return{content:[{type:"text",text:"No sessions match the specified filters."}]}
1347
1347
  const C=c?v.slice(0,c):v,_=C.map((e=>{const t=e.specialization?"\n Specialization: "+e.specialization:"",r=e.currentAction?"\n Current: "+e.currentAction:"",n=e.recentActions.length>0?"\n Recent: "+e.recentActions.join(", "):""
1348
1348
  return`\u2022 ${e.id}\n ${e.title}${t}\n Status: ${e.status} (${e.statusDetail}) | Age: ${i(e.age)} | ${e.totalTokens.toLocaleString()} tokens${e.requestsInfo}${r}${n}`})),E=c&&v.length>c?` (showing ${c} of ${v.length})`:""
1349
- return{content:[{type:"text",text:`Found ${C.length} session${1!==C.length?"s":""}${E}:\n\n${_.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,E.getErrorMessage)(e))}}var p,f=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
1349
+ return{content:[{type:"text",text:`Found ${C.length} session${1!==C.length?"s":""}${E}:\n\n${_.join("\n\n")}`}]}}catch(e){throw Error("Failed to list sessions: "+(0,q.getErrorMessage)(e))}}var p,f=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
1350
1350
  var o=Object.getOwnPropertyDescriptor(t,r)
1351
1351
  o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),m=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),y=this&&this.__importStar||(p=function(e){return p=Object.getOwnPropertyNames||function(e){var t=[]
1352
1352
  for(var r in e)({}).hasOwnProperty.call(e,r)&&(t[t.length]=r)
@@ -1355,8 +1355,8 @@ var t={}
1355
1355
  if(null!=e)for(var r=p(e),n=0;n<r.length;n++)"default"!==r[n]&&f(t,e,r[n])
1356
1356
  return m(t,e),t})
1357
1357
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpawn=o,exports.handleContinue=s,exports.handleCheckStatus=u,exports.handleAbort=h,exports.handleListSessions=g,exports.handleSubagentOperations=async function(e,t,r,n,i,a){const c=r.child({tool:"subagent_operations"}),l=n.startTimer("tool_execution_time")
1358
- try{e&&!e.operation&&(e.spawn?e.operation="spawn":e.continue?e.operation="continue":e.readMessages?e.operation="read-messages":e.listSessions?e.operation="list-sessions":e.prompt&&(e.agent||e.description)?e={operation:"spawn",spawn:{agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId,allowParallel:e.allowParallel,useExistingSession:e.useExistingSession}}:e.sessionId&&e.prompt&&!e.spawn?e={operation:"continue",sessionId:e.sessionId,continue:{prompt:e.prompt}}:e.sessionId&&(e={operation:"check-status",sessionId:e.sessionId})),"spawn"===e?.operation&&e?.prompt&&!e?.spawn&&(e.spawn={agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId},delete e.prompt,delete e.agent,delete e.description,delete e.requestId),"continue"===e?.operation&&e?.prompt&&!e?.continue&&(e.continue={prompt:e.prompt},delete e.prompt)
1359
- const r=_.validateArgs(e,C.SubagentOperationsSchema),{sessionId:d,operation:p}=r
1358
+ try{if(e&&!e.operation&&(e.spawn?e.operation="spawn":e.continue?e.operation="continue":e.readMessages?e.operation="read-messages":e.listSessions?e.operation="list-sessions":e.prompt&&(e.agent||e.description)?e={operation:"spawn",spawn:{agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId,allowParallel:e.allowParallel,useExistingSession:e.useExistingSession}}:e.sessionId&&e.prompt&&!e.spawn?e={operation:"continue",sessionId:e.sessionId,continue:{prompt:e.prompt}}:e.sessionId&&(e={operation:"check-status",sessionId:e.sessionId})),e?.spawn&&"string"==typeof e.spawn)try{e.spawn=JSON.parse(e.spawn)}catch{}if(e?.continue&&"string"==typeof e.continue)try{e.continue=JSON.parse(e.continue)}catch{}"spawn"===e?.operation&&e?.prompt&&!e?.spawn&&(e.spawn={agent:e.agent||"coder",prompt:e.prompt,description:e.description||e.prompt.slice(0,60),requestId:e.requestId},delete e.prompt,delete e.agent,delete e.description,delete e.requestId),"continue"===e?.operation&&e?.prompt&&!e?.continue&&(e.continue={prompt:e.prompt},delete e.prompt)
1359
+ const r=E.validateArgs(e,_.SubagentOperationsSchema),{sessionId:d,operation:p}=r
1360
1360
  let f
1361
1361
  switch(c.info("Processing subagent_operations",{operation:p,sessionId:d}),p){case"spawn":f=await o(r.spawn,t,c,i,a)
1362
1362
  break
@@ -1367,7 +1367,7 @@ break
1367
1367
  case"abort":f=await h(d,t,c)
1368
1368
  break
1369
1369
  case"read-messages":const e=r.readMessages?.limit??1
1370
- f=await async function(e,t,r,n){const o=await(0,I.getServerUrl)(r,n)
1370
+ f=await async function(e,t,r,n){const o=await(0,b.getServerUrl)(r,n)
1371
1371
  if(!o)throw new w.ValidationError("Could not determine OpenCode server URL")
1372
1372
  n.info("Reading messages from subagent session",{sessionId:e,limit:t})
1373
1373
  try{const r=`${o.replace(/\/$/,"")}/session/${e}/message?limit=${t}`,n=await fetch(r)
@@ -1376,13 +1376,13 @@ throw Error("Failed to fetch messages: "+n.status)}const s=await n.json()
1376
1376
  if(0===s.length)return{content:[{type:"text",text:`Session ${e} has no messages yet.`}]}
1377
1377
  const i=s.map(((e,t)=>{const r="user"===e.info.role?"USER":"ASSISTANT",n=e.parts.filter((e=>"text"===e.type&&e.text)).map((e=>e.text)).join("\n"),o=n.length>5e3?n.slice(0,5e3)+"...[truncated]":n
1378
1378
  return`[${t+1}] ${r} (${new Date(e.info.time.created).toLocaleTimeString()}):\n${o}`})).join("\n\n---\n\n")
1379
- return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,E.getErrorMessage)(e))}}(d,e,t,c)
1379
+ return{content:[{type:"text",text:`Session ${e} - Last ${s.length} messages:\n\n${i}`}]}}catch(e){throw Error("Failed to read messages: "+(0,q.getErrorMessage)(e))}}(d,e,t,c)
1380
1380
  break
1381
- case"list-sessions":const n={activeOnly:r.listSessions?.activeOnly,requestId:r.listSessions?.requestId,limit:r.listSessions?.limit,minTokens:r.listSessions?.minTokens,maxTokens:r.listSessions?.maxTokens,maxAgeHours:r.listSessions?.maxAgeHours,parentSessionId:a?.sessionId||(0,b.getCachedSession)()?.sessionId}
1381
+ case"list-sessions":const n={activeOnly:r.listSessions?.activeOnly,requestId:r.listSessions?.requestId,limit:r.listSessions?.limit,minTokens:r.listSessions?.minTokens,maxTokens:r.listSessions?.maxTokens,maxAgeHours:r.listSessions?.maxAgeHours,parentSessionId:a?.sessionId||(0,v.getCachedSession)()?.sessionId}
1382
1382
  f=await g(t,c,i,n)
1383
1383
  break
1384
- default:throw new w.ValidationError("Unknown operation: "+p)}return l({success:!0}),n.incrementCounter(`subagent_operations_${p}_success`,1),f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,E.getErrorMessage)(e)}],isError:!0}}}
1385
- const w=t(9860),k=t(8035),I=t(7617),b=t(715),v=t(7280),C=t(6183),_=y(t(5967)),E=t(8824),q=t(9896),S=t(6928),T=t(8955),P=t(5671),M=3456,R=6e4,j=3e5},1791(e,exports,t){function r(e,t){return t.info("Creating project context middleware",{projectId:e}),(t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
1384
+ default:throw new w.ValidationError("Unknown operation: "+p)}return l({success:!0}),n.incrementCounter(`subagent_operations_${p}_success`,1),f}catch(e){return c.error("Subagent operations failed",{error:e instanceof Error?e.stack:e+""}),l({success:!1}),n.incrementCounter("subagent_operations_errors",1),{content:[{type:"text",text:"Subagent operation failed: "+(0,q.getErrorMessage)(e)}],isError:!0}}}
1385
+ const w=t(9860),k=t(8035),I=t(2424),b=t(7617),v=t(715),C=t(7280),_=t(6183),E=y(t(5967)),q=t(8824),S=t(9896),T=t(6928),P=t(8955),M=t(5671),R=3456,j=6e4,x=3e5},1791(e,exports,t){function r(e,t){return t.info("Creating project context middleware",{projectId:e}),(t,r,n)=>{"GET"===t.method&&(t.query.projectId=e),["POST","PATCH","PUT"].includes(t.method)&&t.body&&(t.body.projectId=e),n()}}var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
1386
1386
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectContext=void 0,exports.projectContextMiddleware=r
1387
1387
  const o=n(t(9896)),s=n(t(6928)),i=t(4139),a=t(4055),c=t(8824)
1388
1388
  exports.ProjectContext=class{constructor(e,t){this.projectId=null,this.initialized=!1,this.initializationInProgress=!1,this.initializationPromise=null,this.basePath=e,this.alchemyPath=s.default.join(e,i.ALCHEMY_DIR_NAME),this.projectFilePath=s.default.join(this.alchemyPath,"project.json"),this.logger=t.child({component:"project-context"}),this.logger.debug("Project context constructed",{basePath:this.basePath,alchemyPath:this.alchemyPath,projectFilePath:this.projectFilePath})}initialize(){return this.initialized&&this.projectId?(this.logger.info("Project context already initialized",{projectId:this.projectId}),Promise.resolve(this.projectId)):this.initializationInProgress&&this.initializationPromise?(this.logger.info("Project context initialization already in progress, reusing promise"),this.initializationPromise):(this.initializationInProgress=!0,this.logger.debug("Starting initialization",{basePath:this.basePath}),this.initializationPromise=this.doInitialize(),this.initializationPromise)}async doInitialize(){try{if(o.default.existsSync(this.alchemyPath))this.logger.debug("alchemy_lab directory already exists")
@@ -1716,7 +1716,15 @@ return D?.commitHash&&(L+="\nCommit: "+D.commitHash.substring(0,8)),N.requestId&
1716
1716
  await n.createToolRecord({...r?{}:{taskId:e.taskId},projectId:t.projectId,type:"move-files",metadata:{status:"failed",timestamp:(new Date).toISOString(),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment,error:(0,p.getErrorMessage)(o),errorDetails:o instanceof Error?o.stack:o+"",phase:I,attemptedTaskId:e.taskId,taskIdValidationFailed:r},note:"Failed to move files - "+(0,p.getErrorMessage)(o)})}catch(t){m.error("Failed to create failure record for move-files operation",{error:t instanceof Error?t.message:t+"",taskId:e.taskId,operationCount:e.operations?.length||0})}const s=Date.now()-y
1717
1717
  if(i.recordValue("move_files_time",s),i.incrementCounter("move_files_errors",1),m.error("Error in move-files operation:",{error:(0,p.getErrorMessage)(o),time:s}),(w||k)&&e.taskId){I=d.FileOperationPhase.RECORD_UPDATE_FAILURE
1718
1718
  try{await d.updateFileOperationRecords(e.taskId,w,k,e.operations?.[0]?.source||"unknown",b.recordType,"Failed to move files",{status:"failed",error:(0,p.getErrorMessage)(o),operationCount:e.operations?.length||0,operations:e.operations||[],userComment:e.comment},"Failed to move files",r,n,m,i,b.metricsPrefix)}catch(t){m.error("Failed to update record with failure status",{taskId:e.taskId,recordId:w,error:t instanceof Error?t.message:t+""})}}return d.handleFileOperationError(o,I,m,i,e,b)}}
1719
- const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(7478),p=t(8824)},2422(module){module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2425(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
1719
+ const a=i(t(1943)),c=i(t(6928)),l=t(6183),d=s(t(5967)),u=t(9860),h=t(1569),g=t(7478),p=t(8824)},2422(module){module.exports=require("@modelcontextprotocol/sdk/server/sse.js")},2424(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ensureRequestWorktree=async function(e,t,i){const a="requests/"+t,c=(0,n.join)(e,s.ALCHEMY_DIR_NAME,"worktrees"),l=(0,n.join)(c,t)
1720
+ if((0,r.existsSync)(l))return void i.info("Worktree already exists on disk, skipping pre-spawn creation",{requestId:t,worktreePath:l})
1721
+ const d=(0,o.simpleGit)(e);(0,r.mkdirSync)(c,{recursive:!0})
1722
+ try{await d.raw(["worktree","prune"])}catch{}const u=await d.branch(),h=u.all.includes(a)
1723
+ try{if(h)await d.raw(["worktree","add",l,a]),i.info("Pre-spawn: created worktree for existing branch",{requestId:t,branchName:a,worktreePath:l})
1724
+ else{const e=u.all.includes("main")?"main":"master"
1725
+ await d.raw(["worktree","add","-b",a,l,e]),i.info("Pre-spawn: created worktree with new branch from latest main",{requestId:t,branchName:a,mainBranch:e,worktreePath:l})}}catch(e){const r=e instanceof Error?e.message:e+""
1726
+ i.warn("Pre-spawn: failed to create worktree (MCP process will retry)",{requestId:t,error:r})}}
1727
+ const r=t(9896),n=t(6928),o=t(3807),s=t(4139)},2425(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
1720
1728
  const r=t(6183),n=t(3707)
1721
1729
  exports.def={name:"quick_manage",description:"Move, delete, or create directories. Wraps the change in a request/task workflow that auto-completes.\n\nProvide an array of operations, each with operationType and corresponding data:\n\u2022 create-directory: { createDirectory: { path } }\n\u2022 move-files: { moveFiles: { moves: [{ source, destination }] } }\n\u2022 delete-files: { deleteFiles: { targets: [{ path }] } }\n\nFor read-only operations like get-file-info, use manage_files instead.\n\nRequires: title, description, operations.",schema:r.QuickManageSchema,annotations:{title:"Quick Manage",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},handler(e,t){return(0,n.handleQuickChange)(e,"manage",t.context,t.apiClient,t.logger,t.metrics,t.mcpServer)}}},2462(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0})
1722
1730
  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),g=t(5459),p=t(4805),f=t(260),m=t(2283),y=t(4165),w=t(7834),k=t(9373),I=t(6111),b=t(700),v=t(2783),C=t(2601),_=t(1722),E=t(7257),q=t(9230),S=t(5216),T=t(6473),P=t(4921),M=t(8850),R=t(3556),j=t(1391),x=t(6315),O=t(7713),A=t(6252),D=t(213),$=t(7250),F=t(2425),N=t(1540),L=t(5767),z=t(4973),B=t(7613),H=t(3322),W=t(5247),U=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)(g.def),(0,r.registerTool)(p.def),(0,r.registerTool)(f.def),(0,r.registerTool)(m.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(k.def),(0,r.registerTool)(I.def),(0,r.registerTool)(b.def),(0,r.registerTool)(v.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(E.def),(0,r.registerTool)(q.def),(0,r.registerTool)(S.def),(0,r.registerTool)(T.def),(0,r.registerTool)(P.def),(0,r.registerTool)(M.def),(0,r.registerTool)(R.def),(0,r.registerTool)(j.def),(0,r.registerTool)(x.def),(0,r.registerTool)(O.def),(0,r.registerTool)(A.def),(0,r.registerTool)(D.def),(0,r.registerTool)($.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(L.def),(0,r.registerTool)(z.def),(0,r.registerTool)(B.def),(0,r.registerTools)(H.metaDefs),(0,r.registerTools)(W.testingDefs),(0,r.registerTools)(U.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.requestConfig=void 0,exports.areTestsRequiredForCompletion=function(){return exports.requestConfig.requireTestsForCompletion},exports.setTestsRequiredForCompletion=function(e){exports.requestConfig.requireTestsForCompletion=e},exports.getCompletionMode=function(e){return e&&["auto-merge","auto-test-then-merge","manual-review"].includes(e)?e:"auto-merge"},exports.getApprovalMode=function(e){return e&&["none","require-approval"].includes(e)?e:"none"},exports.requestConfig={requireTestsForCompletion:!1}},2537(e,exports,t){async function r(e,t,r){if(C.has(r)&&_>=t){if(0===t)return 0
@@ -2482,21 +2490,22 @@ e.userChangesCommitted?f.info("Committed user changes to main before quick-edit
2482
2490
  f.debug("Creating task")
2483
2491
  const e=await w.createTask({requestId:S,projectId:d.projectId,title:`Execute ${t} operation`,description:"Quick change: "+b})
2484
2492
  if(!e||!e.id)throw Error("Failed to create task")
2485
- let l
2486
- if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{operationType:t}),"write"===t)l=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,k,w,I,y,h,g,p)
2487
- else if("replace"===t)l=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,I,y,h,g,p)
2493
+ let v
2494
+ if(T=e.id,f.info("Created task",{taskId:T}),f.debug("Executing file operation",{operationType:t}),"write"===t)v=await(0,n.handleWriteFile)({taskId:T,...C,comment:_},d,k,w,I,y,h,g,p)
2495
+ else if("replace"===t)v=await(0,o.handleReplaceInFiles)({taskId:T,...C,comment:_},d,w,I,y,h,g,p)
2488
2496
  else{if("manage"!==t)throw new r.ValidationError("Unsupported operation type: "+t)
2489
- l=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||b},d,w,I,y,u,h,g,p)}if(l.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
2490
- try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after operation failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after operation failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${l.content[0].text}\n\nThe request (${S}) and task have been canceled and cleaned up.`}],isError:!0}}const v=l.content[0].text,q=v.includes("\u26a0\ufe0f Partial Success")||v.includes("\u274c Failed")||v.includes("\u274c 0 successful")
2491
- q?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
2492
- try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${b}${q?" (partial success)":""}`},d,u,h,g),f.info("Task completed successfully",{taskId:T})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
2497
+ v=await(0,s.handleManageFiles)({taskId:T,...C,comment:_||b},d,w,I,y,u,h,g,p)}if(v.isError){f.error("File operation failed, cleaning up request and task",{requestId:S,taskId:T})
2498
+ try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after operation failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after operation failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after operation failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}return{content:[{type:"text",text:`\u274c Quick change failed during ${t} operation:\n\n${v.content[0].text}\n\nThe request (${S}) and task have been canceled and cleaned up.`}],isError:!0}}const q=v.content[0].text,P=q.includes("\u26a0\ufe0f Partial Success")||q.includes("\u274c Failed")||q.includes("\u274c 0 successful")
2499
+ P?f.warn("File operation completed with partial failures",{requestId:S}):f.info("File operation completed successfully"),f.debug("Completing task")
2500
+ try{await(0,i.handleCompleteTask)({taskId:T,summary:`Executed ${t} operation for quick fix: ${b}${P?" (partial success)":""}`},d,u,h,g),f.info("Task completed successfully",{taskId:T})}catch(e){f.error("Task completion via handleCompleteTask failed, attempting direct status update",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0})
2493
2501
  try{await w.updateTaskStatus(T,"completed"),f.info("Task completed via direct updateTaskStatus call",{taskId:T})}catch(e){return f.error("Direct task completion ALSO failed - task may be stuck in in_progress",{taskId:T,error:e instanceof Error?e.message:e+"",errorStack:e instanceof Error?e.stack:void 0,operationType:t,isDocumentOperation:!!C.documentId}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but task completion failed.\n\n**Request:** ${S}\n**Task:** ${T}\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: ${T}\n\nError: `+(e instanceof Error?e.message:e+"")}],isError:!0}}}f.debug("Completing request")
2494
- const P=q?`Quick change completed with partial success: ${b}. Some replacements failed - see details below.`:"Quick change completed: "+b,M=q?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2495
- let R=!1
2496
- try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:P,acceptanceEvidence:[{evidence:M}],testVerification:void 0},d,u,h,g,p)
2497
- e.isError?f.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text}):(R=!0,f.info("Request completed successfully via handleCompleteRequest",{requestId:S}))}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:S,error:e instanceof Error?e.message:e+""})}if(!R)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:P}),R=!0,f.info("Request completed successfully via direct API call",{requestId:S})}catch(e){return f.error("Direct request completion also failed",{requestId:S,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${S}\n**Status:** Still in 'in_progress' - please complete manually\n\nThe file operation was successful, but we couldn't automatically complete the request. Please use the complete-request tool manually.`}],isError:!0}}const j=Date.now()-m
2498
- let x
2499
- return f.info("Quick fix completed",{requestId:S,duration:j,hasPartialFailure:q}),x=q?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${j}ms\n**Status:** Some operations succeeded, some failed\n\nThe successful changes have been applied and automatically merged to main.\n**Active branch:** main\n\n**\u26a0\ufe0f Note:** This quick-fix had partial failures. See operation details below:\n\n`+v:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${j}ms\n\nThe change has been applied and automatically merged to main.\n**Active branch:** main`+(v.match(/\[RECORD:trec\d{6}\]/)?.[0]?"\n"+v.match(/\[RECORD:trec\d{6}\]/)?.[0]:""),E&&(x+="\n\n\u{1f4a1} **Recommendation:** You've created several quick-edits in a row. For better traceability and organization, consider creating a proper feature or bugfix request with multiple tasks for your next change."),{content:[{type:"text",text:x}]}}catch(e){if(f.error("Quick change workflow failed after request creation, cleaning up",{requestId:S,error:(0,l.getErrorMessage)(e)}),T)try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after workflow failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after workflow failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after workflow failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}throw e}}catch(e){const t=Date.now()-m
2502
+ const M=P?`Quick change completed with partial success: ${b}. Some replacements failed - see details below.`:"Quick change completed: "+b,R=P?t+" operation partially completed - some operations succeeded, some failed":t+" operation executed successfully"
2503
+ let j=!1
2504
+ try{const e=await(0,a.handleCompleteRequest)({requestId:S,summary:M,acceptanceEvidence:[{evidence:R}],testVerification:void 0},d,u,h,g,p)
2505
+ if(e.isError)f.error("Request completion failed, attempting direct completion",{requestId:S,error:e.content[0].text})
2506
+ else{try{await y.updateRequest(S,{status:"completed",completionSummary:M}),f.info("Request finalized to completed",{requestId:S})}catch(e){f.warn("Failed to finalize request to completed, may be stuck at ready_for_merge",{requestId:S,error:(0,l.getErrorMessage)(e)})}j=!0,f.info("Request completed successfully",{requestId:S})}}catch(e){f.error("Request completion threw exception, attempting direct completion",{requestId:S,error:e instanceof Error?e.message:e+""})}if(!j)try{f.info("Attempting direct request completion via API",{requestId:S}),await y.updateRequest(S,{status:"completed",completionSummary:M}),j=!0,f.info("Request completed successfully via direct API call",{requestId:S})}catch(e){return f.error("Direct request completion also failed",{requestId:S,error:e instanceof Error?e.message:e+""}),{content:[{type:"text",text:`\u26a0\ufe0f Quick change operation succeeded but request completion failed.\n\n**Request:** ${S}\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 x=Date.now()-m
2507
+ let O
2508
+ return f.info("Quick fix completed",{requestId:S,duration:x,hasPartialFailure:P}),O=P?`\u26a0\ufe0f Quick change completed with partial success\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${x}ms\n**Status:** Some operations succeeded, some failed\n\nThe successful changes have been applied and automatically merged to main.\n**Active branch:** main\n\n**\u26a0\ufe0f Note:** This quick-fix had partial failures. See operation details below:\n\n`+q:`\u2705 Quick change completed successfully!\n\n**Request:** ${S}\n**Title:** ${b}\n**Operation:** ${t}\n**Duration:** ${x}ms\n\nThe change has been applied and automatically merged to main.\n**Active branch:** main`+(q.match(/\[RECORD:trec\d{6}\]/)?.[0]?"\n"+q.match(/\[RECORD:trec\d{6}\]/)?.[0]:""),E&&(O+="\n\n\u{1f4a1} **Recommendation:** You've created several quick-edits in a row. For better traceability and organization, consider creating a proper feature or bugfix request with multiple tasks for your next change."),{content:[{type:"text",text:O}]}}catch(e){if(f.error("Quick change workflow failed after request creation, cleaning up",{requestId:S,error:(0,l.getErrorMessage)(e)}),T)try{await w.updateTaskStatus(T,"canceled"),f.info("Canceled task after workflow failure",{taskId:T})}catch(e){f.warn("Failed to cancel task during cleanup",{taskId:T,error:e instanceof Error?e.message:e+""})}try{await y.updateRequest(S,{status:"canceled"}),f.info("Canceled request after workflow failure",{requestId:S}),d.workspaceManager&&(await d.workspaceManager.cancelRequest(S),f.info("Cleaned up branch/worktree after workflow failure",{requestId:S}))}catch(e){f.warn("Failed to cancel request during cleanup",{requestId:S,error:e instanceof Error?e.message:e+""})}throw e}}catch(e){const t=Date.now()-m
2500
2509
  return f.error("Quick change failed",{error:(0,l.getErrorMessage)(e),duration:t}),e instanceof r.ValidationError?{content:[{type:"text",text:"\u274c "+e.message}],isError:!0}:{content:[{type:"text",text:"\u274c Quick change failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
2501
2510
  const r=t(9860),n=t(4079),o=t(9442),s=t(7684),i=t(355),a=t(5715),c=t(7478),l=t(8824)},3807(module){module.exports=require("simple-git")},3884(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.middleware=exports.validateRequest=exports.authenticate=exports.corsOptions=exports.errorHandler=exports.requestLogger=void 0
2502
2511
  const r=t(9860),n=t(5674)
@@ -2732,7 +2741,7 @@ var t={}
2732
2741
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
2733
2742
  return o(t,e),t})
2734
2743
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handlePlannerOps=async function(e,t,r,n,o,s){const h=r.child({tool:"planner_ops"}),g=n.startTimer("tool_execution_time")
2735
- try{"request"===e?.operation&&e?.prompt&&!e?.request&&(e.request={prompt:e.prompt,description:e.description||e.prompt.slice(0,60)},delete e.prompt,delete e.description)
2744
+ try{if(e?.request&&"string"==typeof e.request)try{e.request=JSON.parse(e.request)}catch{}"request"===e?.operation&&e?.prompt&&!e?.request&&(e.request={prompt:e.prompt,description:e.description||e.prompt.slice(0,60)},delete e.prompt,delete e.description)
2736
2745
  const r=c.validateArgs(e,a.PlannerOpsSchema),{operation:p,sessionId:f}=r
2737
2746
  let m
2738
2747
  switch(h.info("Processing planner_ops",{operation:p,sessionId:f}),p){case"request":{const e=await async function(e,t,r){if(!e)return"ask"
@@ -3447,7 +3456,7 @@ return"delegate"===e.operation?r&&!n&&!t:"follow-up"===e.operation?n&&!r&&t:"che
3447
3456
  return"request"===e.operation?t&&!r:"check-status"===e.operation?!t&&r:"list"===e.operation&&!t&&!r}),{message:"Invalid operation data: request requires request object, check-status requires sessionId"}),exports.SwitchToRequestBranchSchema=r.z.object({requestId:s}),exports.InsertLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.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"}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceLinesSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.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())])}))}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{message:"path or documentId required"})),comment:r.z.string()}),exports.CreateDocumentSchema=r.z.object({requestId:s.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:s.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:i.optional(),requestId:s.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"})}))
3448
3457
  const c=r.z.string().refine((e=>!!e&&(/^doc_[0-9A-Z]{26}$/i.test(e)||/^plan\d{6}$/.test(e))),{message:"Plan ID must match format: doc_[26 alphanumeric] (ULID) or plan###### (local ID)"})
3449
3458
  exports.PlanReadSchema=r.z.object({operation:r.z.enum(["get","get-active","list","get-history","get-requests"]),planId:c.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(["update","append","replace","create-snapshot","restore","set-active"]),planId:c,content:r.z.string().optional(),name:r.z.string().optional().describe("Optional new name for the plan"),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
3450
- "update"!==r&&"append"!==r||e.content||t.addIssue({code:"custom",message:`content is required for '${r}'. Example: { "operation": "${r}", "planId": "plan000001", "content": "..." }`}),"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(),password:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:s,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.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()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{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({taskId:o,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:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{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:s.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search"]),complete:r.z.object({summary:r.z.string()}).optional(),merge: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)=>{const r=!!e.requestId,n=e.operation
3459
+ "update"!==r&&"append"!==r||e.content||t.addIssue({code:"custom",message:`content is required for '${r}'. Example: { "operation": "${r}", "planId": "plan000001", "content": "..." }`}),"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(),password:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:s,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({taskId:o,operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:i.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()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{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({taskId:o,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:i.optional()}).refine((e=>e.path&&!e.documentId||!e.path&&e.documentId),{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:s.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search"]),complete:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({summary:r.z.string()})).optional(),merge:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({verifications:r.z.array(r.z.object({key:r.z.string().min(2).max(4),evidence:r.z.string().min(1)})).min(1)})).optional(),revert:r.z.object({reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}).optional(),list:r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),approve:r.z.object({}).optional()}).superRefine(((e,t)=>{const r=!!e.requestId,n=e.operation
3451
3460
  if(["complete","merge","approve","revert","get-info"].includes(n)&&!r)return void t.addIssue({code:"custom",message:`requestId is required for '${n}' operation`})
3452
3461
  const o={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: "..." } }'}}[n]
3453
3462
  o&&!e[o.field]&&t.addIssue({code:"custom",message:`'${n}' operation requires '${o.field}' data. ${o.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:i.optional(),content:r.z.union([r.z.string(),r.z.record(r.z.any()),r.z.array(r.z.unknown())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}),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:i.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()})).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:i.optional()}))}).optional()})).min(1)}),exports.GenerateRequestJournalSchema=r.z.object({requestId:r.z.string().regex(/^req[_\d].+$/,"Invalid request ID format. Expected format: req_[26 chars] or req######")}),exports.MetaWorkflowListSchema=r.z.object({}),exports.MetaWorkflowGetSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the workflow"),shortName:r.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:r.z.string().optional().describe("Description of what the workflow does"),documentation:r.z.string().optional().describe("Detailed documentation"),defaultAgent:r.z.string().optional().describe("Default agent template to use"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior: auto-merge (default), auto-test-then-merge, or manual-review"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaWorkflowUpdateSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to update"),name:r.z.string().min(1).optional().describe("New name"),shortName:r.z.string().max(10).optional().describe("New short name (max 10 chars)"),description:r.z.string().optional().describe("New description"),documentation:r.z.string().optional().describe("New documentation"),defaultAgent:r.z.string().optional().describe("New default agent"),completionMode:r.z.enum(["auto-merge","auto-test-then-merge","manual-review"]).optional().describe("Request completion behavior"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaRecipeListSchema=r.z.object({}),exports.MetaRecipeGetSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to retrieve")}),exports.MetaRecipeCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the recipe"),description:r.z.string().optional().describe("Description of what the recipe does"),documentation:r.z.string().optional().describe("Detailed documentation")}),exports.MetaRecipeAddHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to add the hook to"),hookId:r.z.string().describe("Hook template ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the recipe (0-based, appended if omitted)")}),exports.MetaRecipeRemoveHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to remove the hook from"),hookId:r.z.string().describe("Hook template ID to remove")}),exports.MetaHookListSchema=r.z.object({}),exports.MetaHookCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the hook"),description:r.z.string().optional().describe("Description of what the hook does"),eventType:r.z.string().describe("Event type that triggers this hook (e.g., session_idle, request_completed, custom:plan_ready)"),category:r.z.enum(["alchemy","session","message","editing","reading","file_management","documents","history","tool"]).default("session").describe("Hook category"),agent:r.z.string().describe("Agent template to execute when hook fires"),promptTemplate:r.z.string().describe("Prompt template with {{variable}} substitution"),condition:r.z.record(r.z.any()).optional().describe("Condition object for filtering when hook fires"),executionMode:r.z.enum(["same_session","sub_agent","background","notification","direct_report"]).default("background").describe("How to execute the hook"),timing:r.z.enum(["before","after"]).default("after").describe("When to fire relative to the event"),maxIterations:r.z.number().int().min(1).optional().describe("Maximum times to fire per session"),emitEvent:r.z.string().optional().describe("Custom event to emit on completion"),emitEventOnCondition:r.z.union([r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}),r.z.array(r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}))]).optional().describe("Conditional event emission based on output")}),exports.MetaWorkflowAddRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to add the recipe to"),recipeId:r.z.string().describe("Recipe ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the workflow (0-based, appended if omitted)")}),exports.MetaWorkflowRemoveRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to remove the recipe from"),recipeId:r.z.string().describe("Recipe ID to remove")}),exports.MetaAgentListSchema=r.z.object({}),exports.MetaReferenceSchema=r.z.object({}),exports.TestingProcessListSchema=r.z.object({}),exports.TestingProcessGetSchema=r.z.object({processId:r.z.string().describe("Test process ID to retrieve")})
@@ -3463,7 +3472,7 @@ var t={}
3463
3472
  if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
3464
3473
  return o(t,e),t})
3465
3474
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleSpecialistOps=async function(e,r,n,o,s,f){const m=n.child({tool:"specialist_ops"}),y=o.startTimer("tool_execution_time")
3466
- try{if(!e?.operation&&e&&(e.prompt&&!e.sessionId?e.operation="delegate":e.prompt&&e.sessionId?e.operation="follow-up":e.sessionId&&(e.operation="check-status")),"string"==typeof e?.delegate){const t=e.delegate
3475
+ try{if(!e?.operation&&e&&(e.prompt&&!e.sessionId?e.operation="delegate":e.prompt&&e.sessionId?e.operation="follow-up":e.sessionId&&(e.operation="check-status")),e?.followUp&&"string"==typeof e.followUp)try{e.followUp=JSON.parse(e.followUp)}catch{}if(e?.delegate&&"string"==typeof e.delegate)try{e.delegate=JSON.parse(e.delegate)}catch{}if("string"==typeof e?.delegate){const t=e.delegate
3467
3476
  e.delegate={prompt:e.prompt||t,description:e.description||t.slice(0,60),specialization:e.specialization||"general",requestId:e.requestId},e.operation=e.operation||"delegate",delete e.prompt,delete e.description,delete e.specialization,delete e.requestId}"follow-up"===e?.operation&&e?.prompt&&!e?.followUp&&(e.followUp={prompt:e.prompt,specialization:e.specialization},delete e.prompt,e.specialization&&delete e.specialization),"delegate"===e?.operation&&e?.prompt&&!e?.delegate&&(e.delegate={prompt:e.prompt,description:e.description||e.prompt.slice(0,60),specialization:e.specialization||"general",requestId:e.requestId},delete e.prompt,delete e.description,delete e.specialization,delete e.requestId)
3468
3477
  const n=c.validateArgs(e,a.SpecialistOpsSchema),{operation:w,sessionId:k}=n
3469
3478
  let I
@@ -4429,12 +4438,9 @@ this.logger.info("ALCHEMY_INITIAL_BRANCH set, switching to worktree",{initialBra
4429
4438
  try{await this.ensureWorkspaceReady(r),this.readonlyBranchCheckDone=!0,this.logger.info("Successfully switched to worktree from ALCHEMY_INITIAL_BRANCH",{requestId:r,worktreePath:this.currentWorktreePath})}catch(t){this.logger.warn("Failed to switch to worktree from ALCHEMY_INITIAL_BRANCH",{initialBranch:e,requestId:r,error:(0,i.getErrorMessage)(t)})}}hasExactConflictMarkers(e){return!(!e||!e.trim())&&[/^\s*<{7}(?:\s|$)/m,/^\s*={7}(?:\s|$)/m,/^\s*>{7}(?:\s|$)/m].some((t=>t.test(e)))}async initializeWorktreeManager(){try{await this.worktreeManager.initialize(),this.logger.debug("Initialized multi-agent workspace manager with worktrees")}catch(e){throw this.logger.error("Failed to initialize worktree manager",{error:e}),e}}setTaskCreator(e){this.taskCreator=e}async initializeRequest(e,t){const r=Date.now(),n=a.WorkspaceValidation.validateRequestId(e)
4430
4439
  if(!n.isValid)throw Error("Invalid request ID: "+n.errors.join(", "))
4431
4440
  const o=n.sanitized
4432
- try{a.WorkspaceLogging.logOperation(this.logger,"info","Initializing request by creating branch (no worktree yet)",e,"multi-agent","initializeRequest",{requestTitle:t,architecture:"hybrid-creation"})
4433
- const n="requests/"+o,s=await this.mainGit.branch().then((e=>e.all.includes(n)||e.all.includes("remotes/origin/"+n)))
4434
- if(!s){const e=await this.mainGit.revparse(["--abbrev-ref","HEAD"]),t=(await this.mainGit.branch()).all.includes("main")?"main":"master"
4435
- await this.mainGit.checkout(["-b",n,t]),this.logger.info("Created branch for request",{requestId:o,branchName:n,fromBranch:t}),await this.mainGit.checkout(e),this.logger.info("Returned to original branch after creation",{returnedTo:e,createdBranch:n})}this.workspaceStates.set(o,"initialized")
4436
- const i=Date.now()-r
4437
- this.metrics.recordValue("workspace.initialize",i),a.WorkspaceLogging.logOperation(this.logger,"info","Successfully initialized request with branch (no worktree)",e,"multi-agent","initializeRequest",{branchName:n,branchExisted:s,duration:i,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
4441
+ try{this.workspaceStates.set(o,"initialized")
4442
+ const t=Date.now()-r
4443
+ this.metrics.recordValue("workspace.initialize",t),a.WorkspaceLogging.logOperation(this.logger,"info","Successfully initialized request (branch deferred)",e,"multi-agent","initializeRequest",{duration:t,architecture:"hybrid-creation"})}catch(t){const n=Date.now()-r
4438
4444
  throw this.metrics.recordValue("workspace.initialize",n),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to initialize request",e,"multi-agent","initializeRequest",{error:(0,i.getErrorMessage)(t),duration:n}),t}}async ensureWorkspaceReady(e){const t=Date.now(),r=a.WorkspaceValidation.validateRequestId(e)
4439
4445
  if(!r.isValid)throw Error("Invalid request ID: "+r.errors.join(", "))
4440
4446
  const n=r.sanitized
@@ -4447,8 +4453,9 @@ const e=this.worktreeManager.getWorktreeInfo(n)
4447
4453
  if(e&&e.worktreePath)return this.currentRequestId=n,this.currentWorktreePath=e.worktreePath,this.currentGit=(0,o.simpleGit)(e.worktreePath),void this.logger.info("Switched to existing ready workspace",{requestId:n,worktreePath:e.worktreePath})}try{a.WorkspaceLogging.logOperation(this.logger,"info","Ensuring workspace ready by creating/switching to worktree",e,"multi-agent","ensureWorkspaceReady",{currentState:this.workspaceStates.get(n)||"not-initialized",currentRequestId:this.currentRequestId,architecture:"hybrid-creation"})
4448
4454
  const r=await this.worktreeManager.ensureWorktreeExists(n,void 0,void 0)
4449
4455
  if(!r.success)throw Error("Failed to create worktree: "+r.message)
4450
- this.currentRequestId=n,this.currentWorktreePath=r.worktreePath,this.currentGit=(0,o.simpleGit)(r.worktreePath),this.workspaceStates.set(n,"ready"),r.created&&(this.workspaceKnownClean=!0,this.logger.debug("Fresh worktree created - marking workspace as known clean",{requestId:n,worktreePath:r.worktreePath}))
4451
- const s=Date.now()-t
4456
+ if(this.currentRequestId=n,this.currentWorktreePath=r.worktreePath,this.currentGit=(0,o.simpleGit)(r.worktreePath),this.workspaceStates.set(n,"ready"),r.created){this.workspaceKnownClean=!0
4457
+ try{const e=(0,o.simpleGit)(r.worktreePath),t=(await this.mainGit.branch()).all.includes("main")?"main":"master",s=await this.mainGit.revparse([t]),i=await e.revparse(["HEAD"])
4458
+ s!==i&&0===(await e.log({from:t,to:"HEAD"})).total&&(await e.rebase([t]),this.logger.info("Rebased fresh request branch onto latest main",{requestId:n,mainHead:s.substring(0,8),previousHead:i.substring(0,8)}))}catch(e){this.logger.warn("Failed to rebase onto main, proceeding with existing branch",{requestId:n,error:(0,i.getErrorMessage)(e)})}}const s=Date.now()-t
4452
4459
  this.metrics.recordValue("workspace.ensure_ready",s),a.WorkspaceLogging.logOperation(this.logger,"info","Workspace is ready with worktree",e,"multi-agent","ensureWorkspaceReady",{worktreePath:r.worktreePath,branchName:r.branchName,duration:s,architecture:"hybrid-creation"})}catch(r){const n=Date.now()-t
4453
4460
  throw this.metrics.recordValue("workspace.ensure_ready",n),a.WorkspaceLogging.logOperation(this.logger,"error","Failed to ensure workspace ready",e,"multi-agent","ensureWorkspaceReady",{error:(0,i.getErrorMessage)(r),duration:n}),r}}else this.logger.debug("Workspace already ready and in correct context",{requestId:n,worktreePath:this.currentWorktreePath})}async switchToRequest(e,t){this.logger.debug("switchToRequest called",{requestId:e,options:t})
4454
4461
  const r=Date.now(),n=this.getCurrentContext()
@@ -4481,17 +4488,19 @@ try{this.currentRequestId===r&&await this.switchToMain()
4481
4488
  const e=await this.worktreeManager.removeWorktree(r,!1)
4482
4489
  if(!e.success)throw Error(e.message||"Failed to remove worktree")
4483
4490
  this.logger.info("Successfully cancelled request",{requestId:r})}catch(e){throw this.logger.error("Failed to cancel request",{requestId:r,error:(0,i.getErrorMessage)(e)}),e}}getCurrentContext(){const e={requestId:this.currentRequestId,basePath:this.currentWorktreePath||this.basePath,branchName:this.currentRequestId?"requests/"+this.currentRequestId:"main",isMainBranch:!this.currentRequestId,mode:"multi-agent"}
4484
- return this.logger.debug("getCurrentContext returning",{context:e}),e}async getWorkspaceInfo(e){try{const t=a.WorkspaceValidation.validateRequestId(e)
4491
+ return this.logger.debug("getCurrentContext returning",{context:e}),e}resetCurrentContext(){this.currentRequestId&&this.logger.info("Resetting workspace context (session switch)",{prevRequestId:this.currentRequestId,prevWorktreePath:this.currentWorktreePath}),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit,this.readonlyBranchCheckDone=!1}async getWorkspaceInfo(e){try{const t=a.WorkspaceValidation.validateRequestId(e)
4485
4492
  if(!t.isValid)return null
4486
4493
  const r=t.sanitized,n=await this.getWorktreeInfo(r)
4487
4494
  return n?{requestId:r,path:n.worktreePath,branchName:n.branchName,isActive:this.currentRequestId===r,created:new Date,lastAccessed:new Date}:null}catch(t){return this.logger.error("Failed to get workspace info",{requestId:e,error:(0,i.getErrorMessage)(t)}),null}}async listActiveWorkspaces(){try{return(await this.worktreeManager.listActiveWorktrees()).map((e=>this.convertWorktreeInfoToWorkspaceInfo(e)))}catch(e){return this.logger.error("Failed to list active workspaces",{error:(0,i.getErrorMessage)(e)}),[]}}extractRequestIdFromBranch(e){const t=e.match(/^requests\/(.+)$/)
4488
4495
  return t?t[1]:null}convertWorktreeInfoToWorkspaceInfo(e){return{requestId:e.requestId,path:e.worktreePath,branchName:e.branchName,isActive:this.currentRequestId===e.requestId,created:e.created,lastAccessed:e.lastAccessed}}async getWorktreeInfo(e){try{const t=e.replace(/[^a-zA-Z0-9_-]/g,"_")
4489
- return this.worktreeManager.getWorktreeInfo(t)}catch(t){return void this.logger.warn("Failed to get worktree info",{requestId:e,error:(0,i.getErrorMessage)(t)})}}getMainGit(){return this.gitAdapter.getMainGit()}getCurrentGit(){return this.currentGit}async ensureReadonlyBranchIfNeeded(e,t,r,n){if(this.readonlyBranchCheckDone)return
4496
+ return this.worktreeManager.getWorktreeInfo(t)}catch(t){return void this.logger.warn("Failed to get worktree info",{requestId:e,error:(0,i.getErrorMessage)(t)})}}getMainGit(){return this.gitAdapter.getMainGit()}getCurrentGit(){return this.currentGit}async ensureReadonlyBranchIfNeeded(e,r,n,o){if(this.readonlyBranchCheckDone)return
4490
4497
  this.readonlyBranchCheckDone=!0
4491
- const o=process.env.ALCHEMY_INITIAL_BRANCH
4492
- if(o){const e=o.match(/^requests\/(.+)$/)
4498
+ try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
4499
+ if(r&&n){const t=await e.getSessionRequestId(n,this.logger)
4500
+ if(t)return await this.ensureWorkspaceReady(t),void this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready from session DB lookup",{requestId:t,sessionId:r.sessionId})}}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: session DB lookup failed, falling back to env var",{error:(0,i.getErrorMessage)(e)})}const s=process.env.ALCHEMY_INITIAL_BRANCH
4501
+ if(s){const e=s.match(/^requests\/(.+)$/)
4493
4502
  if(e){const t=e[1]
4494
- try{await this.ensureWorkspaceReady(t),this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready",{requestId:t})}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: failed to ensure workspace",{requestId:t,error:(0,i.getErrorMessage)(e)})}}}}async cleanup(){this.logger.info("Cleaning up multi-agent workspace manager"),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit}}},7645(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionAwareClient=void 0
4503
+ try{await this.ensureWorkspaceReady(t),this.logger.info("ensureReadonlyBranchIfNeeded: workspace ready from env var",{requestId:t})}catch(e){this.logger.warn("ensureReadonlyBranchIfNeeded: failed to ensure workspace",{requestId:t,error:(0,i.getErrorMessage)(e)})}}}}async cleanup(){this.logger.info("Cleaning up multi-agent workspace manager"),this.currentRequestId=null,this.currentWorktreePath=null,this.currentGit=this.mainGit}}},7645(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConnectionAwareClient=void 0
4495
4504
  const r=t(4192),n=t(7163)
4496
4505
  class o extends r.BaseApiClient{constructor(e,t,r,o,s,i){t.debug("ConnectionAwareClient constructor parameters:",{hasAuthToken:!!o,hasOptions:!!s,optionsType:s?typeof s:"undefined",options:s?JSON.stringify(s):"undefined",hasConnectionManager:!!i}),super(e,t,r,o,s),this.isGettingAuthToken=!1,this.connectionStatusManager=i||{isInOfflineMode(){return!1},isOffline(){return!1},setOfflineMode(){},async checkConnectivity(){return!0},getHealthCheckStats(){return{isOffline:!1,consecutiveFailures:0,currentBackoffMs:0,lastCheckTime:0}},cleanup(){}},o&&this.logger.debug("Client initialized with auth token",{clientType:this.constructor.name,tokenPrefix:o.substring(0,10)+"..."})
4497
4506
  try{(0,n.debugTokenAccess)(this,"ConnectionAwareClient constructor")}catch(e){this.logger.debug("Error accessing token details during init",{error:e instanceof Error?e.message:e+""})}}setConnectionStatusManager(e){this.logger.debug("Setting connection status manager in ConnectionAwareClient"),this.connectionStatusManager=e}}exports.ConnectionAwareClient=o},7660(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.projectContextMiddleware=exports.ProjectContext=exports.ProjectIDFactory=exports.ProjectID=void 0