alchemylab 1.4.5 → 1.4.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.
package/dist/cli.js CHANGED
@@ -204,11 +204,11 @@ if(!y.id)throw Error("Session created in OpenCode but no ID returned")
204
204
  const v=y.id
205
205
  u.info("Pre-created OpenCode session",{sessionId:v,title:p,agent:t})
206
206
  const w=this.registerSession({sessionId:v,parentSessionId:a,projectId:h,agent:t,title:p,specialization:c,specializationHeadline:l,callerAgentType:d,requestId:i}),I=this.resolveModel(t,n),b=i?(0,r.ensureRequestWorktree)(n,i,u).catch((e=>{u.warn("Pre-spawn worktree creation failed (non-fatal)",{requestId:i,error:(0,o.getErrorMessage)(e)})})):Promise.resolve(),[,E]=await Promise.all([w,I,b])
207
- return{sessionId:v,model:E,serverUrl:g,initialBranch:i?"requests/"+i:void 0}}async registerSession(e){const{sessionId:t,parentSessionId:r,projectId:s,agent:n,title:i,specialization:a,specializationHeadline:c,callerAgentType:l,requestId:d}=e,{apiClient:u,logger:h}=this.deps
208
- try{let e,g
209
- if(r)try{const t=await u.post(`/api/projects/${s}/cli-sessions`,{externalSessionId:r,providerId:"opencode",status:"active",agentType:l||void 0}),o=t?.data||t
210
- e=o?.id,g=o?.workflowId,h.info("Parent session upsert result",{parentExternalId:r,parentDbId:e??null,parentWorkflowId:g??null,responseHasSuccess:void 0!==t?.success,responseDataKeys:o?Object.keys(o):[]})}catch(e){h.warn("Failed to register parent session",{parentSessionId:r,error:(0,o.getErrorMessage)(e)})}const p={externalSessionId:t,providerId:"opencode",parentSessionId:e||null,title:i,status:"active",agentType:n,specialization:a,specializationHeadline:c,workflowId:g||void 0}
211
- if(h.info("Child session upsert payload",{sessionId:t,agent:n,parentExternalId:r??null,parentDbIdSent:p.parentSessionId,workflowIdSent:p.workflowId??null}),await u.post(`/api/projects/${s}/cli-sessions`,p),h.info("Registered session in alchemy DB",{sessionId:t,agent:n,parentSessionId:r}),d){try{await u.post(`/api/projects/${s}/session-request-associations`,{opencodeSessionId:t,requestLocalId:d}),h.info("Created session-request association",{sessionId:t,requestId:d})}catch(e){h.warn("Failed to create session-request association",{error:(0,o.getErrorMessage)(e)})}if("coder"===n)try{await u.patch(`/api/projects/${s}/requests/${d}`,{cliOrigin:{providerId:"opencode",sessionId:t,createdAt:(new Date).toISOString()}}),h.debug("Updated request cliOrigin",{sessionId:t,requestId:d})}catch(e){h.warn("Failed to update request cliOrigin",{error:(0,o.getErrorMessage)(e)})}}}catch(e){h.warn("Failed to register session in alchemy DB",{error:(0,o.getErrorMessage)(e)})}}async resolveModel(e,t){const{logger:r}=this.deps,s=this.fetchProjectDefaultModel()||void 0
207
+ return{sessionId:v,model:E,serverUrl:g,initialBranch:i?"requests/"+i:void 0}}async registerSession(e){const{sessionId:t,parentSessionId:r,projectId:s,agent:n,title:a,specialization:c,specializationHeadline:l,callerAgentType:d,requestId:u}=e,{apiClient:h,logger:g}=this.deps
208
+ try{let e,p
209
+ if(r)try{const t=await h.post(`/api/projects/${s}/cli-sessions`,{externalSessionId:r,providerId:"opencode",status:"active",agentType:d||void 0}),o=t?.data||t
210
+ e=o?.id,p=o?.workflowId,g.info("Parent session upsert result",{parentExternalId:r,parentDbId:e??null,parentWorkflowId:p??null,responseHasSuccess:void 0!==t?.success,responseDataKeys:o?Object.keys(o):[]})}catch(e){g.warn("Failed to register parent session",{parentSessionId:r,error:(0,o.getErrorMessage)(e)})}const m={externalSessionId:t,providerId:"opencode",parentSessionId:e||null,title:a,status:"active",agentType:n,specialization:c,specializationHeadline:l,workflowId:p||void 0,persistent:i.PERSISTENT_ORCHESTRATOR_AGENTS.includes(n)||void 0}
211
+ if(g.info("Child session upsert payload",{sessionId:t,agent:n,parentExternalId:r??null,parentDbIdSent:m.parentSessionId,workflowIdSent:m.workflowId??null}),await h.post(`/api/projects/${s}/cli-sessions`,m),g.info("Registered session in alchemy DB",{sessionId:t,agent:n,parentSessionId:r}),u){try{await h.post(`/api/projects/${s}/session-request-associations`,{opencodeSessionId:t,requestLocalId:u}),g.info("Created session-request association",{sessionId:t,requestId:u})}catch(e){g.warn("Failed to create session-request association",{error:(0,o.getErrorMessage)(e)})}if("coder"===n)try{await h.patch(`/api/projects/${s}/requests/${u}`,{cliOrigin:{providerId:"opencode",sessionId:t,createdAt:(new Date).toISOString()}}),g.debug("Updated request cliOrigin",{sessionId:t,requestId:u})}catch(e){g.warn("Failed to update request cliOrigin",{error:(0,o.getErrorMessage)(e)})}}}catch(e){g.warn("Failed to register session in alchemy DB",{error:(0,o.getErrorMessage)(e)})}}async resolveModel(e,t){const{logger:r}=this.deps,s=this.fetchProjectDefaultModel()||void 0
212
212
  let a
213
213
  try{const r=await this.fetchAgentConfig(e)
214
214
  if(r){const e=r.preferredProvider||"inherit",o=r.preferredModelTier||"same",i=(0,n.resolveAgentModel)(t,e,o,s)
@@ -297,8 +297,8 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.partMeta=function
297
297
  return{...e,_meta:{...s,alchemy:{...o,...r,kind:t}}}},exports.readAlchemyMeta=function(e){return e?._meta?.alchemy}},2366(e,exports,t){"use strict"
298
298
  var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
299
299
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.AlchemyActionServer=void 0
300
- const s=r(t(7252)),o=r(t(8577)),n=t(9896),i=t(5959),a=t(2640),c=t(4192),l=t(1152),d=r(t(6928)),u=r(t(9896)),h=r(t(857)),g=t(5607),p=t(8984),m=t(8524),f=t(8824),y=t(2096),v=t(7210),w=t(7227),I=t(5419),b=t(3962),E=t(2928),S=t(6563),C=t(1401),k=t(1292),T=t(8148),_=t(9068),j=t(8463),A=t(489),P=t(3807),M=t(7478),O=t(5317),R=t(355),D=t(833)
301
- class x{updateAuthToken(e){this.options.authToken=e,this.apiClient.authToken=e,this.configurer.authToken=e}constructor(e,t){this.directReportDedup=new Map,this.activeMcpCalls=new Map,this.pendingAgentResync=!1,this.settingsSyncCounter=0,this.versionWarnings=[],this.updateBlocked=!1,this._pendingUpdateBlock=!1,this.isPolling=!1,this.isProcessingAction=!1,this.openCodeUrlCache=null,this.openCodePort=null,this.proxyAbortControllers=new Map,this.trackedChildPids=new Set,this.sseEventBuffer=[],this.droppedEventCount=0,this.firstDropAt=0,this.hasRemoteEventConsumers=!1,this.cachedProjectConfig=null,this.logger=e,this.options=t,this.port=t.port||3456,this.startTime=new Date
300
+ const s=r(t(7252)),o=r(t(8577)),n=t(9896),i=t(5959),a=t(2640),c=t(4192),l=t(1152),d=r(t(6928)),u=r(t(9896)),h=r(t(857)),g=t(5607),p=t(8984),m=t(8524),f=t(8824),y=t(2096),v=t(7210),w=t(7227),I=t(5419),b=t(3962),E=t(2928),S=t(6563),C=t(1401),k=t(1292),T=t(8649),_=t(4306),j=t(9068),A=t(3435),P=t(8463),M=t(489),O=t(3807),R=t(7478),D=t(5317),x=t(355),$=t(833)
301
+ class F{updateAuthToken(e){this.options.authToken=e,this.apiClient.authToken=e,this.configurer.authToken=e}constructor(e,t){this.directReportDedup=new Map,this.activeMcpCalls=new Map,this.pendingAgentResync=!1,this.settingsSyncCounter=0,this.versionWarnings=[],this.updateBlocked=!1,this._pendingUpdateBlock=!1,this.isPolling=!1,this.isProcessingAction=!1,this.openCodeUrlCache=null,this.openCodePort=null,this.proxyAbortControllers=new Map,this.trackedChildPids=new Set,this.sseEventBuffer=[],this.droppedEventCount=0,this.firstDropAt=0,this.hasRemoteEventConsumers=!1,this.cachedProjectConfig=null,this.logger=e,this.options=t,this.port=t.port||3456,this.startTime=new Date
302
302
  const r=(0,l.createMetricsCollector)(!1)
303
303
  this.apiClient=new c.BaseApiClient(t.remoteServerUrl,e,r,t.authToken,{timeout:35e3}),this.configurer=new p.MCPClientConfigurer(e,t.remoteServerUrl,t.authToken),this.cliBridge=new m.CLIBridgeWebSocket(e),(0,m.setCLIBridge)(this.cliBridge),this.hookExecutor=new v.HookExecutor(e,"",t.projectPath,this.apiClient,{cachedDefaultModel:this.cachedDefaultModel,trackChildPid:e=>this.trackedChildPids.add(e)}),this.app=this.createApp()}createApp(){const e=(0,s.default)()
304
304
  return e.use(((e,t,r)=>{t.setHeader("Access-Control-Allow-Private-Network","true"),r()})),e.use((0,o.default)()),e.use(s.default.json({limit:"10mb"})),e.get("/health",this.handleHealth.bind(this)),e.get("/api/commands/running",(async(e,t)=>{try{const e=16384,r=await Promise.all((0,i.listEntries)().map((async t=>{let r,s="",o=0,i=t.finishedAt??t.startedAt
@@ -308,7 +308,7 @@ const c=Math.max(0,o-e),l=Buffer.alloc(o-c)
308
308
  await r.read(l,0,l.length,c),s=l.toString("utf-8").split("\n").slice(-50).join("\n")}catch{}finally{await(r?.close().catch((()=>{})))}return{...t,tail:s,sizeBytes:o,modifiedAt:i}})))
309
309
  t.json({success:!0,data:r})}catch(e){t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}})),e.post("/api/commands/start",(async(e,t)=>{try{const{id:r,name:s,command:o,cwd:n,sessionId:a,startedAt:c,logPath:l}=e.body??{}
310
310
  if(!(r&&s&&o&&n&&c&&l))return void t.status(400).json({success:!1,error:"missing required fields"});(0,i.addStart)({id:r,name:s,command:o,cwd:n,sessionId:a,startedAt:c,logPath:l}),t.json({success:!0})}catch(e){t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}})),e.post("/api/commands/end",(async(e,t)=>{try{const{id:r,exitCode:s,timedOut:o,finishedAt:n}=e.body??{}
311
- if(!r||"number"!=typeof s||!n)return void t.status(400).json({success:!1,error:"missing required fields"});(0,i.markEnd)({id:r,exitCode:s,timedOut:!!o,finishedAt:n}),t.json({success:!0})}catch(e){t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}})),e.get("/api/auth-status",this.handleAuthStatus.bind(this)),e.get("/status",this.handleStatus.bind(this)),e.get("/opencode",this.handleOpenCodeConfig.bind(this)),e.post("/sync-agents",this.handleSyncAgents.bind(this)),e.post("/api/generate-journal",this.handleGenerateJournal.bind(this)),(0,R.registerHooksRoutes)(e,{apiClient:this.apiClient,logger:this.logger,getProjectId:()=>this.projectId}),e.get("/api/project-settings",((e,t)=>{t.json({success:!0,data:{defaultModel:this.cachedDefaultModel||null}})})),e.post("/api/sync-settings",(async(e,t)=>{await this.syncProjectSettings(),t.json({success:!0,data:{defaultModel:this.cachedDefaultModel||null}})})),e.get("/api/agents/by-name/:agentName",this.handleGetAgentByName.bind(this)),e.get("/api/sessions/:sessionId/agent-type",this.handleGetSessionAgentType.bind(this)),e.get("/api/sessions/:sessionId/parent",this.handleGetSessionParent.bind(this)),e.get("/api/sessions/:sessionId/ancestors",(async(e,t)=>{try{const{sessionId:r}=e.params,s=this.projectId
311
+ if(!r||"number"!=typeof s||!n)return void t.status(400).json({success:!1,error:"missing required fields"});(0,i.markEnd)({id:r,exitCode:s,timedOut:!!o,finishedAt:n}),t.json({success:!0})}catch(e){t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}})),e.get("/api/auth-status",this.handleAuthStatus.bind(this)),e.get("/status",this.handleStatus.bind(this)),e.get("/opencode",this.handleOpenCodeConfig.bind(this)),e.post("/sync-agents",this.handleSyncAgents.bind(this)),e.post("/api/generate-journal",this.handleGenerateJournal.bind(this)),(0,x.registerHooksRoutes)(e,{apiClient:this.apiClient,logger:this.logger,getProjectId:()=>this.projectId}),e.get("/api/project-settings",((e,t)=>{t.json({success:!0,data:{defaultModel:this.cachedDefaultModel||null}})})),e.post("/api/sync-settings",(async(e,t)=>{await this.syncProjectSettings(),t.json({success:!0,data:{defaultModel:this.cachedDefaultModel||null}})})),e.get("/api/agents/by-name/:agentName",this.handleGetAgentByName.bind(this)),e.get("/api/sessions/:sessionId/agent-type",this.handleGetSessionAgentType.bind(this)),e.get("/api/sessions/:sessionId/parent",this.handleGetSessionParent.bind(this)),e.get("/api/sessions/:sessionId/ancestors",(async(e,t)=>{try{const{sessionId:r}=e.params,s=this.projectId
312
312
  if(!s)return void t.status(400).json({success:!1,error:"No project"})
313
313
  const o=await this.apiClient.get(`/api/projects/${s}/cli-sessions/external/opencode/${encodeURIComponent(r)}/ancestors`),n=(o?.data||o||[]).map((e=>({externalSessionId:e.externalSessionId,agentType:e.agentType,title:e.title})))
314
314
  t.json({success:!0,ancestors:n})}catch(e){t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}})),e.get("/api/registry/projects",(async(e,r)=>{try{const{listLive:e}=await Promise.resolve().then(t.bind(t,2640))
@@ -321,11 +321,11 @@ if(!r||"before"!==i&&"after"!==i)return void t.status(400).json({success:!1,erro
321
321
  const a=(0,w.parseToolEvents)({toolName:r,sessionId:s||"",input:o,output:n,timing:i})
322
322
  let c=0
323
323
  for(const e of a)c+=(await this.hookExecutor.processEvent({eventType:e.eventType,sessionId:s||"",variables:e.variables,timing:e.timing})).triggered
324
- this.logger.info("tool-event received",{toolName:r,timing:i,sessionId:s||"",events:a.length,triggered:c}),t.json({success:!0,data:{events:a.length,triggered:c}})}catch(e){this.logger.error("tool-event processing failed",{error:(0,f.getErrorMessage)(e)}),t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}})),e.post("/api/direct-report",this.handleDirectReport.bind(this)),e.post("/api/cli-bridge/command",this.handleCLIBridgeCommand.bind(this)),e.get("/api/cli-bridge/status",this.handleCLIBridgeStatus.bind(this)),e.post("/api/spawn-session",this.handleSpawnSession.bind(this)),e.post("/api/spawn-planner",this.handleSpawnPlanner.bind(this)),e.post("/api/setup-tests",this.handleSetupTests.bind(this)),e.post("/api/setup-commands",this.handleSetupCommands.bind(this)),e.post("/api/run-tests-now",this.handleRunTestsNow.bind(this)),e.get("/api/branch-head",(async(e,t)=>{try{const r="string"==typeof e.query.requestId?e.query.requestId:void 0,s=("string"==typeof e.query.branch?e.query.branch:void 0)||(r?(0,M.generateRequestBranchName)(r,""):void 0)
324
+ this.logger.info("tool-event received",{toolName:r,timing:i,sessionId:s||"",events:a.length,triggered:c}),t.json({success:!0,data:{events:a.length,triggered:c}})}catch(e){this.logger.error("tool-event processing failed",{error:(0,f.getErrorMessage)(e)}),t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}})),e.post("/api/direct-report",this.handleDirectReport.bind(this)),e.post("/api/cli-bridge/command",this.handleCLIBridgeCommand.bind(this)),e.get("/api/cli-bridge/status",this.handleCLIBridgeStatus.bind(this)),e.post("/api/spawn-session",this.handleSpawnSession.bind(this)),e.post("/api/spawn-planner",this.handleSpawnPlanner.bind(this)),e.post("/api/setup-tests",this.handleSetupTests.bind(this)),e.post("/api/setup-commands",this.handleSetupCommands.bind(this)),e.post("/api/run-tests-now",this.handleRunTestsNow.bind(this)),e.get("/api/branch-head",(async(e,t)=>{try{const r="string"==typeof e.query.requestId?e.query.requestId:void 0,s=("string"==typeof e.query.branch?e.query.branch:void 0)||(r?(0,R.generateRequestBranchName)(r,""):void 0)
325
325
  if(!s)return void t.status(400).json({success:!1,error:"requestId or branch required"})
326
- const o=(await(0,P.simpleGit)(this.options.projectPath).revparse([s])).trim()
326
+ const o=(await(0,O.simpleGit)(this.options.projectPath).revparse([s])).trim()
327
327
  t.json({success:!0,data:{branch:s,sha:o}})}catch(e){this.logger.debug("branch-head lookup failed",{error:(0,f.getErrorMessage)(e)}),t.json({success:!0,data:{branch:null,sha:null}})}})),e.post("/api/release-pool-slot",(async(e,t)=>{try{const{worktreePath:r}=e.body||{}
328
- if(!r||"string"!=typeof r)return void t.status(400).json({success:!1,error:"worktreePath required"});(0,A.releaseSlot)(r),this.logger.info("Released pool slot via report-back",{worktreePath:r}),t.json({success:!0})}catch(e){this.logger.warn("release-pool-slot failed (non-fatal)",{error:(0,f.getErrorMessage)(e)}),t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}})),e.get("/api/timer-hooks/status",((e,t)=>{const r=this.timerHookScheduler?.getStatus()??{running:!1,trackedHooks:0,inFlight:[],hooks:[]}
328
+ if(!r||"string"!=typeof r)return void t.status(400).json({success:!1,error:"worktreePath required"});(0,M.releaseSlot)(r),this.logger.info("Released pool slot via report-back",{worktreePath:r}),t.json({success:!0})}catch(e){this.logger.warn("release-pool-slot failed (non-fatal)",{error:(0,f.getErrorMessage)(e)}),t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}})),e.get("/api/timer-hooks/status",((e,t)=>{const r=this.timerHookScheduler?.getStatus()??{running:!1,trackedHooks:0,inFlight:[],hooks:[]}
329
329
  t.json({success:!0,data:r})})),e.post("/api/timer-hooks/:hookId/pause",((e,t)=>{if(!this.timerHookScheduler)return void t.status(503).json({success:!1,error:"Scheduler not running"})
330
330
  const r=this.timerHookScheduler.pauseHook(e.params.hookId)
331
331
  t.json({success:r})})),e.post("/api/timer-hooks/:hookId/resume",((e,t)=>{if(!this.timerHookScheduler)return void t.status(503).json({success:!1,error:"Scheduler not running"})
@@ -376,7 +376,7 @@ e&&(await fetch(e+"/config/reload",{method:"POST",signal:AbortSignal.timeout(5e3
376
376
  if(!s)return void r.status(400).json({success:!1,error:"requestId is required"})
377
377
  if(!/^req\d+$/.test(s))return void r.status(400).json({success:!1,error:"Invalid requestId format"})
378
378
  this.logger.info("Generating journal for request",{requestId:s})
379
- const o=`Generate a journal entry for request ${s}.\n\nSteps:\n1. Use the generate_request_journal tool with requestId: ${s}\n2. Write a concise narrative journal entry based on the returned data covering:\n - What was implemented and why\n - Key decisions and trade-offs made\n - Challenges encountered and solutions\n - Files modified and their purposes\n - How acceptance criteria were met\n3. Save as JOURNAL-${s}.md using document_operations (operation: create, type: Report)\n\nKeep it story-focused and informative.`,{resolveRunCommand:n}=await Promise.resolve().then(t.bind(t,9068)),i=n(),a=(0,O.spawn)(i.command,[...i.prependArgs,"run","--agent","journal",o],{detached:!0,stdio:"ignore",cwd:this.options.projectPath,env:{...process.env,...(0,I.getOpencodeSpawnEnv)(this.options.projectPath,(0,b.isDevMode)())}})
379
+ const o=`Generate a journal entry for request ${s}.\n\nSteps:\n1. Use the generate_request_journal tool with requestId: ${s}\n2. Write a concise narrative journal entry based on the returned data covering:\n - What was implemented and why\n - Key decisions and trade-offs made\n - Challenges encountered and solutions\n - Files modified and their purposes\n - How acceptance criteria were met\n3. Save as JOURNAL-${s}.md using document_operations (operation: create, type: Report)\n\nKeep it story-focused and informative.`,{resolveRunCommand:n}=await Promise.resolve().then(t.bind(t,9068)),i=n(),a=(0,D.spawn)(i.command,[...i.prependArgs,"run","--agent","journal",o],{detached:!0,stdio:"ignore",cwd:this.options.projectPath,env:{...process.env,...(0,I.getOpencodeSpawnEnv)(this.options.projectPath,(0,b.isDevMode)())}})
380
380
  a.pid&&this.trackChildPid(a.pid),a.unref(),r.json({success:!0,message:"Journal generation started for "+s})}catch(e){this.logger.error("Failed to generate journal",{error:(0,f.getErrorMessage)(e)}),r.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}}async handleDirectReport(e,t){try{const r=this.projectId
381
381
  if(!r)return void t.status(400).json({success:!1,error:"Project not registered"})
382
382
  const{sessionId:s,requestId:o,summary:n,status:i}=e.body
@@ -424,43 +424,27 @@ if(!t||t===r)throw e
424
424
  d=`${t}/${s}${o}`,this.logger.info("OpenCode proxy: retrying with fresh port",{oldUrl:r,newUrl:t}),l=await fetch(d,c)}if(204===l.status||"0"===l.headers.get("content-length"))return void t.status(l.status).end()
425
425
  const u=l.headers.get("content-type")||""
426
426
  let h
427
- try{h=u.includes("application/json")?await l.json():await l.text()}catch{return void t.status(l.status).end()}t.status(l.status),u&&t.setHeader("Content-Type",u),"string"==typeof h?t.send(h):t.json(h)}catch(r){this.openCodePort=null,this.openCodeUrlCache=null,this.logger.error("OpenCode proxy error",{error:(0,f.getErrorMessage)(r),path:e.params[0]}),t.status(502).json({error:"OpenCode proxy error",message:(0,f.getErrorMessage)(r)})}}async handleSpawnPlanner(e,r){try{const{agent:s,planId:o,prompt:n,title:i,parentSessionId:a}=e.body||{}
428
- if(!o||!n)return void r.status(400).json({success:!1,error:"planId and prompt are required"})
429
- const c=new Set(["planner","auto-planner","quest-planner"])
430
- if(s&&!c.has(s))return void r.status(400).json({success:!1,error:"agent must be one of: "+[...c].join(", ")})
431
- if(!this.projectId)return void r.status(400).json({success:!1,error:"No project configured"})
432
- const{spawnPlannerWithDoc:l}=await Promise.resolve().then(t.bind(t,8649)),d=await l({agent:s||"planner",planId:o,prompt:n,title:i||"Planner",parentSessionId:a,apiClient:this.apiClient,logger:this.logger,projectId:this.projectId,projectPath:this.options.projectPath,trackChildPid:e=>this.trackedChildPids.add(e)})
433
- if(!d.success||!d.sessionId)return void r.status(500).json({success:!1,error:d.error||"spawn failed"})
434
- r.json({success:!0,data:{sessionId:d.sessionId,planId:d.planId,pid:d.pid}})}catch(e){this.logger.error("Spawn planner failed",{error:(0,f.getErrorMessage)(e)}),r.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}}async handleSpawnSession(e,t){try{const{agent:r,prompt:s,requestId:o,parentSessionId:n,title:i,specialization:a,specializationHeadline:c,allowParallel:l,callerAgentType:d}=e.body
435
- if(!r||!s)return void t.status(400).json({success:!1,error:"agent and prompt are required"})
436
- if(!this.projectId)return void t.status(400).json({success:!1,error:"No project configured"})
437
- const u=this.projectId,h=new k.SessionSpawnService({apiClient:this.apiClient,logger:this.logger,projectId:u,getDefaultModel:()=>this.cachedDefaultModel||void 0}),g=await h.prepareSession({agent:r,prompt:s,projectPath:this.options.projectPath,requestId:o,parentSessionId:n,title:i,specialization:a,specializationHeadline:c,allowParallel:l,callerAgentType:d})
438
- t.json({success:!0,data:g})}catch(e){this.logger.error("Spawn session failed",{error:(0,f.getErrorMessage)(e)}),t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}}async handleRunTestsNow(e,r){try{const{requestId:s,parentSessionId:o,testProcessIds:n,commandNames:i}=e.body||{}
439
- if(!this.projectId)return void r.status(400).json({success:!1,error:"No project configured"})
440
- if(!s)return void r.status(400).json({success:!1,error:"requestId is required"})
441
- const{handleRunTestsAction:a}=await Promise.resolve().then(t.bind(t,6555)),c={projectId:this.projectId,projectPath:this.options.projectPath,logger:this.logger,apiClient:this.apiClient,trackChildPid:e=>this.trackedChildPids.add(e),cachedDefaultModel:this.cachedDefaultModel??null},l=await a({requestId:s,parentSessionId:o,testProcessIds:n,commandNames:i,mode:"auto"},c)
427
+ try{h=u.includes("application/json")?await l.json():await l.text()}catch{return void t.status(l.status).end()}t.status(l.status),u&&t.setHeader("Content-Type",u),"string"==typeof h?t.send(h):t.json(h)}catch(r){this.openCodePort=null,this.openCodeUrlCache=null,this.logger.error("OpenCode proxy error",{error:(0,f.getErrorMessage)(r),path:e.params[0]}),t.status(502).json({error:"OpenCode proxy error",message:(0,f.getErrorMessage)(r)})}}async handleSpawnPlanner(e,t){try{if(!(0,A.validateRequest)(e,t,this.projectId,["planId","prompt"]))return
428
+ const{agent:r,planId:s,prompt:o,title:n,parentSessionId:i}=e.body||{},a=new Set(["planner","auto-planner","quest-planner"])
429
+ if(r&&!a.has(r))return void t.status(400).json({success:!1,error:"agent must be one of: "+[...a].join(", ")})
430
+ const c=await(0,T.spawnPlannerWithDoc)({agent:r||"planner",planId:s,prompt:o,title:n||"Planner",parentSessionId:i,apiClient:this.apiClient,logger:this.logger,projectId:this.projectId,projectPath:this.options.projectPath,trackChildPid:e=>this.trackedChildPids.add(e)})
431
+ if(!c.success||!c.sessionId)return void t.status(500).json({success:!1,error:c.error||"spawn failed"})
432
+ t.json({success:!0,data:{sessionId:c.sessionId,planId:c.planId,pid:c.pid}})}catch(e){(0,A.respondWithError)(t,this.logger,"Spawn planner",e)}}async handleSpawnSession(e,t){try{if(!(0,A.validateRequest)(e,t,this.projectId,["agent","prompt"]))return
433
+ const{agent:r,prompt:s,requestId:o,parentSessionId:n,title:i,specialization:a,specializationHeadline:c,allowParallel:l,callerAgentType:d}=e.body,u=this.projectId,h=new k.SessionSpawnService({apiClient:this.apiClient,logger:this.logger,projectId:u,getDefaultModel:()=>this.cachedDefaultModel||void 0}),g=await h.prepareSession({agent:r,prompt:s,projectPath:this.options.projectPath,requestId:o,parentSessionId:n,title:i,specialization:a,specializationHeadline:c,allowParallel:l,callerAgentType:d})
434
+ t.json({success:!0,data:g})}catch(e){(0,A.respondWithError)(t,this.logger,"Spawn session",e)}}async handleRunTestsNow(e,r){try{if(!(0,A.validateRequest)(e,r,this.projectId,["requestId"]))return
435
+ const{requestId:s,parentSessionId:o,testProcessIds:n,commandNames:i}=e.body||{},{handleRunTestsAction:a}=await Promise.resolve().then(t.bind(t,6555)),c={projectId:this.projectId,projectPath:this.options.projectPath,logger:this.logger,apiClient:this.apiClient,trackChildPid:e=>this.trackedChildPids.add(e),cachedDefaultModel:this.cachedDefaultModel??null},l=await a({requestId:s,parentSessionId:o,testProcessIds:n,commandNames:i,mode:"auto"},c)
442
436
  if(!l.success)return void r.status(500).json({success:!1,error:l.error||l.message})
443
- r.json({success:!0,data:l.data})}catch(e){this.logger.error("Run tests now failed",{error:(0,f.getErrorMessage)(e)}),r.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}}async handleSetupTests(e,t){try{const{requestId:r,parentSessionId:s,branchName:o}=e.body||{}
444
- if(!this.projectId)return void t.status(400).json({success:!1,error:"No project configured"})
445
- const n=this.projectId,i=this.options.projectPath
446
- await(0,j.sweepStaleSetupWorktrees)(i,this.logger)
447
- const a=await(0,j.resolveSetupBranch)(this.apiClient,n,o,r,this.logger,i),c=(0,j.generateSetupId)(),l=d.default.join((0,j.getSetupWorktreesBase)(i),c)
448
- try{await(0,j.createSetupWorktree)(i,l,a,this.logger)}catch(e){const r=(0,f.getErrorMessage)(e)
449
- return this.logger.error("Failed to create setup worktree",{branch:a,error:r}),void t.status(500).json({success:!1,error:"Failed to create setup worktree: "+r})}const u=(0,j.buildSetupPrompt)(i,r),h=await(0,T.spawnActionAgent)({agent:"test-architect",prompt:u,cwd:l,projectPath:i,projectId:n,title:r?`[${r}] Test setup`:"Test setup",requestId:r,parentSessionId:s,allowParallel:!0,apiClient:this.apiClient,logger:this.logger,trackChildPid:e=>this.trackedChildPids.add(e),getDefaultModel:()=>this.cachedDefaultModel||void 0})
450
- if(!h.success)return void t.status(500).json({success:!1,error:h.error||"Spawn failed"})
451
- t.json({success:!0,data:{sessionId:h.sessionId,worktreePath:l,branch:a}})}catch(e){this.logger.error("Setup tests failed",{error:(0,f.getErrorMessage)(e)}),t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}}async handleSetupCommands(e,t){try{const{requestId:r,parentSessionId:s,branchName:o,context:n}=e.body||{}
452
- if(!this.projectId)return void t.status(400).json({success:!1,error:"No project configured"})
453
- const i=this.projectId,a=this.options.projectPath
454
- await(0,j.sweepStaleSetupWorktrees)(a,this.logger)
455
- const c=await(0,j.resolveSetupBranch)(this.apiClient,i,o,r,this.logger,a),l=(0,j.generateSetupId)(),u=d.default.join((0,j.getSetupWorktreesBase)(a),l)
456
- try{await(0,j.createSetupWorktree)(a,u,c,this.logger)}catch(e){const r=(0,f.getErrorMessage)(e)
457
- return this.logger.error("Failed to create setup worktree (commands)",{branch:c,error:r}),void t.status(500).json({success:!1,error:"Failed to create setup worktree: "+r})}const h=(0,j.buildCommandSetupPrompt)(a,r,n),g=await(0,T.spawnActionAgent)({agent:"command-architect",prompt:h,cwd:u,projectPath:a,projectId:i,title:r?`[${r}] Commands setup`:"Commands setup",requestId:r,parentSessionId:s,allowParallel:!0,apiClient:this.apiClient,logger:this.logger,trackChildPid:e=>this.trackedChildPids.add(e),getDefaultModel:()=>this.cachedDefaultModel||void 0})
458
- if(!g.success)return void t.status(500).json({success:!1,error:g.error||"Spawn failed"})
459
- t.json({success:!0,data:{sessionId:g.sessionId,worktreePath:u,branch:c}})}catch(e){this.logger.error("Setup commands failed",{error:(0,f.getErrorMessage)(e)}),t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}}async handleGetAgentByName(e,t){try{const r=this.projectId
437
+ r.json({success:!0,data:l.data})}catch(e){(0,A.respondWithError)(r,this.logger,"Run tests now",e)}}async handleSetupTests(e,t){try{if(!(0,A.validateRequest)(e,t,this.projectId))return
438
+ const{requestId:r,parentSessionId:s,branchName:o,context:n}=e.body||{},i=await(0,_.setupAgentInWorktree)({agent:"test-architect",promptBuilder(e,t,r){return(0,P.buildSetupPrompt)(e,t,r)},titleBuilder(e){return e?`[${e}] Test setup`:"Test setup"},worktreeErrorLabel:"Failed to create setup worktree",callerContext:n,requestId:r,parentSessionId:s,branchName:o,apiClient:this.apiClient,logger:this.logger,projectId:this.projectId,projectPath:this.options.projectPath,trackChildPid:e=>this.trackedChildPids.add(e),getDefaultModel:()=>this.cachedDefaultModel||void 0})
439
+ if(!i.success)return void t.status(i.statusCode||500).json({success:!1,error:i.error})
440
+ t.json({success:!0,data:{sessionId:i.sessionId,worktreePath:i.worktreePath,branch:i.branch}})}catch(e){(0,A.respondWithError)(t,this.logger,"Setup tests",e)}}async handleSetupCommands(e,t){try{if(!(0,A.validateRequest)(e,t,this.projectId))return
441
+ const{requestId:r,parentSessionId:s,branchName:o,context:n}=e.body||{},i=await(0,_.setupAgentInWorktree)({agent:"command-architect",promptBuilder(e,t,r){return(0,P.buildCommandSetupPrompt)(e,t,r)},titleBuilder(e){return e?`[${e}] Commands setup`:"Commands setup"},worktreeErrorLabel:"Failed to create setup worktree (commands)",callerContext:n,requestId:r,parentSessionId:s,branchName:o,apiClient:this.apiClient,logger:this.logger,projectId:this.projectId,projectPath:this.options.projectPath,trackChildPid:e=>this.trackedChildPids.add(e),getDefaultModel:()=>this.cachedDefaultModel||void 0})
442
+ if(!i.success)return void t.status(i.statusCode||500).json({success:!1,error:i.error})
443
+ t.json({success:!0,data:{sessionId:i.sessionId,worktreePath:i.worktreePath,branch:i.branch}})}catch(e){(0,A.respondWithError)(t,this.logger,"Setup commands",e)}}async handleGetAgentByName(e,t){try{const r=this.projectId
460
444
  if(!r)return void t.status(400).json({success:!1,error:"Project not registered"})
461
445
  const{agentName:s}=e.params,o=await this.apiClient.get(`/api/projects/${r}/agents`),n=(o?.data||o||[]).find((e=>e.name===s))
462
446
  if(!n)return void t.status(404).json({success:!1,error:`Agent '${s}' not found`})
463
- t.json({success:!0,data:n})}catch(e){this.logger.debug("Failed to get agent by name",{error:(0,f.getErrorMessage)(e)}),t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}}readProjectConfig(){if(this.cachedProjectConfig&&Date.now()-this.cachedProjectConfig.timestamp<x.PROJECT_CONFIG_TTL)return this.cachedProjectConfig.config
447
+ t.json({success:!0,data:n})}catch(e){this.logger.debug("Failed to get agent by name",{error:(0,f.getErrorMessage)(e)}),t.status(500).json({success:!1,error:(0,f.getErrorMessage)(e)})}}readProjectConfig(){if(this.cachedProjectConfig&&Date.now()-this.cachedProjectConfig.timestamp<F.PROJECT_CONFIG_TTL)return this.cachedProjectConfig.config
464
448
  const e=d.default.join(this.options.projectPath,".alchemy_lab","project.json")
465
449
  try{if(!u.default.existsSync(e))return this.cachedProjectConfig={config:null,timestamp:Date.now()},null
466
450
  const t=u.default.readFileSync(e,"utf-8"),r=JSON.parse(t)
@@ -473,7 +457,7 @@ if(!o||!n)return
473
457
  const i=`${o}/${n}`
474
458
  this.updateDefaultModel(i),this.logger.info("Seeded defaultModel from OpenCode zen default",{defaultModel:i}),this.apiClient.post("/api/user/preferences",{defaultModel:i}).catch((e=>this.logger.debug("Failed to seed user preference",{error:(0,f.getErrorMessage)(e)})))}getOpenCodeUrl(){if(this.openCodePort)return"http://127.0.0.1:"+this.openCodePort
475
459
  if(this.openCodeUrlCache&&3e4>Date.now()-this.openCodeUrlCache.timestamp)return this.openCodeUrlCache.url
476
- const e=(0,D.getOpenCodeUrlFromConfig)(this.options.projectPath)
460
+ const e=(0,$.getOpenCodeUrlFromConfig)(this.options.projectPath)
477
461
  return e&&(this.openCodeUrlCache={url:e,timestamp:Date.now()}),e}async handleSessionCommand(e,t){const r=this.getOpenCodeUrl()
478
462
  if(!r)return{success:!1,error:"OpenCode server not available. Is 'opencode serve' running?"}
479
463
  try{switch(e){case"list-sessions":{const[e,s]=await Promise.all([fetch(r+"/session"),fetch(r+"/session/status")])
@@ -508,7 +492,7 @@ r?.agentType&&(a=r.agentType)}catch{}return{success:!0,data:{id:e,title:i||"(unt
508
492
  if(!e?.id)throw Error("No project configuration found")
509
493
  this.projectId=e.id,this.hookExecutor.setProjectId(this.projectId),this.timerHookScheduler?.setProjectId(this.projectId)
510
494
  try{const e=d.default.resolve(__dirname,"../../package.json"),t=JSON.parse(u.default.readFileSync(e,"utf8"))
511
- this.clientVersion=t.version}catch{}try{const e=(0,_.findOpencodeDir)()
495
+ this.clientVersion=t.version}catch{}try{const e=(0,j.findOpencodeDir)()
512
496
  if(e){const t=JSON.parse(u.default.readFileSync(d.default.join(e,"package.json"),"utf8"))
513
497
  this.opencodeVersion=t.version}}catch{}const t={projectId:this.projectId,projectPath:this.options.projectPath,serverPort:this.port,hostname:h.default.hostname(),platform:process.platform,clientVersion:this.clientVersion,opencodeVersion:this.opencodeVersion}
514
498
  this.logger.info("Registering with remote",{projectId:this.projectId})
@@ -569,9 +553,9 @@ if(void 0!==r&&this.updateDefaultModel(r),void 0!==t&&t!==this.cachedAutoJournal
569
553
  const e=new y.ProjectConfigService(this.logger)
570
554
  await e.saveProjectConfig(this.options.projectPath,t),this.cachedAutoJournal=t}}}catch(e){this.logger.debug("Settings sync failed",{error:(0,f.getErrorMessage)(e)})}}async processAction(e){this.logger.info("Processing action",{actionId:e.id,type:e.type})
571
555
  const t=Date.now()
572
- try{const r={projectPath:this.options.projectPath,projectId:this.projectId,logger:this.logger,apiClient:this.apiClient,trackChildPid:e=>this.trackChildPid(e),cachedDefaultModel:this.cachedDefaultModel},s=await(0,g.executeAction)(e.type,e.payload||{},r)
573
- await this.apiClient.post(`/api/actions/${e.id}/result`,{success:s.success,result:s.data,error:s.message||s.error,duration:Date.now()-t}),this.logger.info("Action processed",{actionId:e.id,type:e.type,success:s.success,duration:Date.now()-t})}catch(r){const s=(0,f.getErrorMessage)(r)
574
- await this.apiClient.post(`/api/actions/${e.id}/result`,{success:!1,error:s,duration:Date.now()-t}),this.logger.error("Action failed",{actionId:e.id,type:e.type,error:s})}}async handleCLIBridgeCommand(e,t){try{const{action:r,params:s,timeout:o}=e.body
556
+ let r
557
+ try{const s={projectPath:this.options.projectPath,projectId:this.projectId,logger:this.logger,apiClient:this.apiClient,trackChildPid:e=>this.trackChildPid(e),cachedDefaultModel:this.cachedDefaultModel},o=await(0,g.executeAction)(e.type,e.payload||{},s)
558
+ r={success:o.success,result:o.data,error:o.message||o.error,duration:Date.now()-t}}catch(e){r={success:!1,error:(0,f.getErrorMessage)(e),duration:Date.now()-t}}try{await this.apiClient.post(`/api/actions/${e.id}/result`,r),r.success?this.logger.info("Action processed",{actionId:e.id,type:e.type,success:!0,duration:r.duration}):this.logger.error("Action failed",{actionId:e.id,type:e.type,error:r.error})}catch(t){this.logger.error("Failed to POST action result after retries; relying on stale-action sweep",{actionId:e.id,type:e.type,workSucceeded:r.success,postError:(0,f.getErrorMessage)(t)})}}async handleCLIBridgeCommand(e,t){try{const{action:r,params:s,timeout:o}=e.body
575
559
  if(!r)return void t.status(400).json({success:!1,error:"action is required"})
576
560
  if(["list-notifications","get-notification","respond-to-notification"].includes(r)){const e=await this.handleNotificationCommand(r,s||{})
577
561
  return void t.json(e)}if(["list-sessions","get-messages","send-message","create-session","get-session-status"].includes(r)){const e=await this.handleSessionCommand(r,s||{})
@@ -618,7 +602,7 @@ for(const[e]of this.proxyAbortControllers)try{e.abort()}catch{}this.proxyAbortCo
618
602
  try{const e=d.default.join(this.options.projectPath,".alchemy_lab","action-server.json")
619
603
  u.default.existsSync(e)&&u.default.unlinkSync(e)}catch{}if(this.projectId)try{const{removeEntry:e}=await Promise.resolve().then(t.bind(t,2640))
620
604
  e(this.projectId)}catch{}if(this.isPolling=!1,this.pollAbortController&&this.pollAbortController.abort(),this.pollingInterval&&clearInterval(this.pollingInterval),this.heartbeatInterval&&clearInterval(this.heartbeatInterval),this.serverId)try{await this.apiClient.post(`/api/servers/${this.serverId}/disconnect`)}catch{}this.cliBridge.close(),await new Promise((e=>{if(this.server){const t=setTimeout((()=>{this.logger.warn("Graceful shutdown timed out after 10s, forcing close"),e()}),1e4)
621
- this.server.close((()=>{clearTimeout(t),e()}))}else e()})),this.logger.info("AlchemyActionServer stopped")}getPort(){return this.port}isRunning(){return!!this.server}}exports.AlchemyActionServer=x,x.PROJECT_CONFIG_TTL=3e4},2424(e,exports,t){"use strict"
605
+ this.server.close((()=>{clearTimeout(t),e()}))}else e()})),this.logger.info("AlchemyActionServer stopped")}getPort(){return this.port}isRunning(){return!!this.server}}exports.AlchemyActionServer=F,F.PROJECT_CONFIG_TTL=3e4},2424(e,exports,t){"use strict"
622
606
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ensureRequestWorktree=async function(e,t,i){const a="requests/"+t,c=(0,s.join)(e,n.ALCHEMY_DIR_NAME,"worktrees"),l=(0,s.join)(c,t)
623
607
  if((0,r.existsSync)(l))return void i.info("Worktree already exists on disk, skipping pre-spawn creation",{requestId:t,worktreePath:l})
624
608
  const d=(0,o.simpleGit)(e);(0,r.mkdirSync)(c,{recursive:!0})
@@ -723,7 +707,13 @@ break
723
707
  case"parent_session":case"ancestor_chain":await(0,o.executeInjectPrompt)(e,e.promptTemplate,i,a,this.ctx)}else await(0,o.executeBackground)(e,t,i,a.requestId,this.ctx)
724
708
  const c=(0,s.determineEventToEmit)(e,a)
725
709
  c&&await this.processCustomEvent(c,a,r+1)}}async notifyHookTrigger(e){try{await this.ctx.apiClient.post(`/api/projects/${this.ctx.projectId}/hook-triggers`,{hookId:e.id,hookName:e.name,eventType:e.eventType,action:e.action,target:e.target,agent:e.agent})}catch{}}}},3416(e,exports){"use strict"
726
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.KIND_META=exports.QUEST_STATUS_DRAFT=exports.QUEST_STATUS_CLOSED=exports.QUEST_STATUS_OPEN=exports.QUEST_DEFAULTS=exports.PLAN_KINDS=void 0,exports.PLAN_KINDS=["plan","quest"],exports.QUEST_DEFAULTS={tickIntervalSeconds:1800,maxInFlight:1,maxPerDay:24,minIterations:3},exports.QUEST_STATUS_OPEN="open",exports.QUEST_STATUS_CLOSED="closed",exports.QUEST_STATUS_DRAFT="draft",exports.KIND_META={plan:{docType:"Plan",filenamePrefix:"PLAN-",label:"plan",idLabel:"Plan ID",headingCreated:"Plan Created",errorVerb:"create plan",alchemyKind:"plan-create",canBeActivePlan:!0},quest:{docType:"Quest",filenamePrefix:"QUEST-",label:"quest",idLabel:"Quest ID",headingCreated:"Quest Created",errorVerb:"create quest",alchemyKind:"quest-create",canBeActivePlan:!1}}},3444(e,exports,t){"use strict"
710
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.KIND_META=exports.QUEST_STATUS_DRAFT=exports.QUEST_STATUS_CLOSED=exports.QUEST_STATUS_OPEN=exports.QUEST_DEFAULTS=exports.PLAN_KINDS=void 0,exports.PLAN_KINDS=["plan","quest"],exports.QUEST_DEFAULTS={tickIntervalSeconds:1800,maxInFlight:1,maxPerDay:24,minIterations:3},exports.QUEST_STATUS_OPEN="open",exports.QUEST_STATUS_CLOSED="closed",exports.QUEST_STATUS_DRAFT="draft",exports.KIND_META={plan:{docType:"Plan",filenamePrefix:"PLAN-",label:"plan",idLabel:"Plan ID",headingCreated:"Plan Created",errorVerb:"create plan",alchemyKind:"plan-create",canBeActivePlan:!0},quest:{docType:"Quest",filenamePrefix:"QUEST-",label:"quest",idLabel:"Quest ID",headingCreated:"Quest Created",errorVerb:"create quest",alchemyKind:"quest-create",canBeActivePlan:!1}}},3435(e,exports,t){"use strict"
711
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.validateRequest=function(e,t,r,s=[]){if(!r)return t.status(400).json({success:!1,error:"No project configured"}),!1
712
+ const o=e.body??{},n=s.filter((e=>void 0===o[e]||null===o[e]||""===o[e]))
713
+ if(n.length>0){const e=1===n.length?"is":"are"
714
+ return t.status(400).json({success:!1,error:`${n.join(", ")} ${e} required`}),!1}return!0},exports.respondWithError=function(e,t,s,o){const n=(0,r.getErrorMessage)(o)
715
+ t.error(s+" failed",{error:n}),e.status(500).json({success:!1,error:n})}
716
+ const r=t(8824)},3444(e,exports,t){"use strict"
727
717
  var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
728
718
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=exports.defaultLogger=exports.isDebugToolsEnabled=exports.getDebugLevelFromEnv=exports.isDebugLoggingEnabled=exports.createEnvLogger=exports.createLogger=void 0
729
719
  const s=t(2782)
@@ -828,7 +818,15 @@ this.logger.warn(`API request failed, retrying in ${r}ms`,{method:e,url:i,error:
828
818
  this.failureCount=0,this.circuitState="closed",this.metrics.setGauge("api_failure_count",0),this.metrics.setGauge("circuit_breaker_open",0),this.circuitResetTimeout&&(clearTimeout(this.circuitResetTimeout),this.circuitResetTimeout=null),e&&this.logger.info("Circuit breaker closed after successful request")}openCircuit(){this.circuitState="open",this.metrics.setGauge("circuit_breaker_open",1),this.logger.warn(`Circuit breaker opened after ${this.failureCount} failures`),this.circuitResetTimeout&&clearTimeout(this.circuitResetTimeout)
829
819
  const e=this.options.circuitBreakerResetTime||5e3
830
820
  this.circuitResetTimeout=setTimeout((()=>{this.circuitState="half-open",this.logger.info("Circuit breaker half-open, next request will probe")}),e)}async get(e,t,r){return this.requestWithRetry("GET",e,void 0,r,t)}async post(e,t,r){return this.requestWithRetry("POST",e,t,r)}async put(e,t,r){return this.requestWithRetry("PUT",e,t,r)}async delete(e,t){return this.requestWithRetry("DELETE",e,void 0,t)}async patch(e,t,r){return this.requestWithRetry("PATCH",e,t,r)}}},4245(module){function e(e){var t=Error("Cannot find module '"+e+"'")
831
- throw t.code="MODULE_NOT_FOUND",t}e.keys=()=>[],e.resolve=e,e.id=4245,module.exports=e},4627(e,exports){"use strict"
821
+ throw t.code="MODULE_NOT_FOUND",t}e.keys=()=>[],e.resolve=e,e.id=4245,module.exports=e},4306(e,exports,t){"use strict"
822
+ var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
823
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.setupAgentInWorktree=async function(e){const{projectPath:t,projectId:r,apiClient:a,logger:c,trackChildPid:l}=e
824
+ await(0,o.sweepStaleSetupWorktrees)(t,c)
825
+ const d=await(0,o.resolveSetupBranch)(a,r,e.branchName,e.requestId,c,t),u=(0,o.generateSetupId)(),h=s.default.join((0,o.getSetupWorktreesBase)(t),u)
826
+ try{await(0,o.createSetupWorktree)(t,h,d,c)}catch(t){const r=(0,i.getErrorMessage)(t)
827
+ return c.error(e.worktreeErrorLabel,{branch:d,error:r}),{success:!1,error:"Failed to create setup worktree: "+r,statusCode:500}}const g=e.promptBuilder(t,e.requestId,e.callerContext),p=e.titleBuilder(e.requestId),m=await(0,n.spawnActionAgent)({agent:e.agent,prompt:g,cwd:h,projectPath:t,projectId:r,title:p,requestId:e.requestId,parentSessionId:e.parentSessionId,allowParallel:!0,apiClient:a,logger:c,trackChildPid:l,getDefaultModel:e.getDefaultModel})
828
+ return m.success&&m.sessionId?{success:!0,sessionId:m.sessionId,worktreePath:h,branch:d}:{success:!1,error:m.error||"Spawn failed",statusCode:500}}
829
+ const s=r(t(6928)),o=t(8463),n=t(8148),i=t(8824)},4627(e,exports){"use strict"
832
830
  function t(e,t){try{return function(e){const t=r.get(e)
833
831
  if(t)return t
834
832
  let s=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"{{GLOBSTAR}}").replace(/\*/g,"[^/]*").replace(/\?/g,".").replace(/\{\{GLOBSTAR\}\}/g,".*")
@@ -1016,12 +1014,12 @@ return"idle"===t||"completed"===t}))
1016
1014
  return{sessions:s,statusMap:o,running:n,idle:i}}catch(e){return this.logger.debug("Failed to fetch OpenCode session state",{error:e+""}),null}}}},6540(e,exports){"use strict"
1017
1015
  var t
1018
1016
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},6555(e,exports,t){"use strict"
1019
- function r(e,process,t,r,s=!1,o){const n=process.config||{},i=(n.setup,n.commands||[]),a=o&&o.length>0?o.map((e=>i.find((t=>t.name===e)))).filter((e=>e)):i,c=o&&o.length>0&&a.length<i.length
1020
- let l=`You are a test runner agent. Your job is to verify that request ${e.localId||e.id} ("${e.title}") passes all required tests.\n\n## Test Process: ${process.name}\n${process.description?`\n${process.description}\n`:""}\n${process.scope?`**Scope:** Files under \`${process.scope}\`\n`:""}\n## Project ID: ${r}\n\n## Test Commands${c?" (partial run \u2014 only the commands listed below)":""}\nExecute these in order:\n`
1021
- for(let e=0;e<a.length;e++){const t=a[e]
1022
- l+=`\n### ${e+1}. ${t.name}${!1!==t.required?" (REQUIRED)":" (optional)"}\n- **Command:** \`${t.command}\`\n- **Timeout:** ${t.timeout||300}s\n`}if(l+=s?`\n## Instructions\n\nYou are in interactive mode. Present the test plan to the user and **wait for their direction** before running anything.\n\n1. Greet the user and list the test commands available for this process.\n2. Wait for the user to tell you to proceed (they may want to run specific commands, skip some, or run all).\n3. Use \`execute_test_command\` with processId="${process.id}" and the command name to run each command.\n4. After each command, explain the result and wait for the user before continuing.\n5. When the user is satisfied, call \`report_test_results\` with the overall status.\n\nYou are read-only \u2014 do NOT modify any source code. Your job is to verify, not fix.`:`\n## Instructions\n\nSetup commands have already been executed. Use the \`execute_test_command\` tool to run each test command:\n\n1. For each command above, call \`execute_test_command\` with processId="${process.id}" and the command name.\n2. Check if it passed or failed.\n3. If it fails: try to determine why \u2014 is it a real bug, a flaky test, or an environment issue? Retry once if it looks flaky.\n4. When all commands are done, call \`report_test_results\` with the overall status and per-command results.\n - If all REQUIRED commands passed \u2192 status "passed"\n - If any REQUIRED command failed \u2192 status "failed" with diagnosis of each failure\n\nYou are read-only \u2014 do NOT modify any source code. Your job is to verify, not fix.`,n.verifyAcceptanceCriteria&&e.acceptanceCriteria?.length>0){l+="\n\n## Acceptance Criteria Verification\n\nAfter running all commands, verify each acceptance criterion by reading code changes and running ad-hoc commands as needed. This is **advisory only** \u2014 it does not affect the overall pass/fail status.\n\nCriteria to verify:\n"
1023
- for(const t of e.acceptanceCriteria)l+=`- ${t}\n`
1024
- l+='\nFor each criterion, report in the `acceptanceCriteria` array of your results:\n- **criterion**: The criterion text\n- **status**: "verified" (confirmed in code), "unverified" (not found/not implemented), or "unclear" (ambiguous)\n- **evidence**: How you verified it, or why you couldn\'t\n'}return l}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRunTestsAction=async function(e,l){const{requestId:d,testProcessIds:u,parentSessionId:h,mode:g}=e,p="interactive"===g,{logger:m,apiClient:f,projectId:y,projectPath:v,trackChildPid:w}=l
1017
+ function r(e,process,t,r,s=!1,o,n){const i=process.config||{},a=(i.setup,i.commands||[]),c=o&&o.length>0?o.map((e=>a.find((t=>t.name===e)))).filter((e=>e)):a,l=new Set(n||[]),d=l.size>0?c.filter((e=>!l.has(e.name))):c,u=o&&o.length>0&&d.length<a.length||l.size>0,h=l.size>0?a.filter((e=>l.has(e.name))).map((e=>e.name)):[]
1018
+ let g=`You are a test runner agent. Your job is to verify that request ${e.localId||e.id} ("${e.title}") passes all required tests.\n\n## Test Process: ${process.name}\n${process.description?`\n${process.description}\n`:""}\n${process.scope?`**Scope:** Files under \`${process.scope}\`\n`:""}\n## Project ID: ${r}\n${h.length>0?`\n_The coder opted out of these command(s) for this completion: **${h.join(", ")}**. Do NOT run them. They've been excluded from the list below._\n`:""}\n## Test Commands${u?" (partial run \u2014 only the commands listed below)":""}\nExecute these in order:\n`
1019
+ for(let e=0;e<d.length;e++){const t=d[e]
1020
+ g+=`\n### ${e+1}. ${t.name}${!1!==t.required?" (REQUIRED)":" (optional)"}\n- **Command:** \`${t.command}\`\n- **Timeout:** ${t.timeout||300}s\n`}if(g+=s?`\n## Instructions\n\nYou are in interactive mode. Present the test plan to the user and **wait for their direction** before running anything.\n\n1. Greet the user and list the test commands available for this process.\n2. Wait for the user to tell you to proceed (they may want to run specific commands, skip some, or run all).\n3. Use \`execute_test_command\` with processId="${process.id}" and the command name to run each command.\n4. After each command, explain the result and wait for the user before continuing.\n5. When the user is satisfied, call \`report_test_results\` with the overall status.\n\nYou are read-only \u2014 do NOT modify any source code. Your job is to verify, not fix.`:`\n## Instructions\n\nSetup commands have already been executed. Use the \`execute_test_command\` tool to run each test command:\n\n1. For each command above, call \`execute_test_command\` with processId="${process.id}" and the command name.\n2. Check if it passed or failed.\n3. If it fails: try to determine why \u2014 is it a real bug, a flaky test, or an environment issue? Retry once if it looks flaky.\n4. When all commands are done, call \`report_test_results\` with the overall status and per-command results.\n - If all REQUIRED commands passed \u2192 status "passed"\n - If any REQUIRED command failed \u2192 status "failed" with diagnosis of each failure\n\nYou are read-only \u2014 do NOT modify any source code. Your job is to verify, not fix.`,i.verifyAcceptanceCriteria&&e.acceptanceCriteria?.length>0){g+="\n\n## Acceptance Criteria Verification\n\nAfter running all commands, verify each acceptance criterion by reading code changes and running ad-hoc commands as needed. This is **advisory only** \u2014 it does not affect the overall pass/fail status.\n\nCriteria to verify:\n"
1021
+ for(const t of e.acceptanceCriteria)g+=`- ${t}\n`
1022
+ g+='\nFor each criterion, report in the `acceptanceCriteria` array of your results:\n- **criterion**: The criterion text\n- **status**: "verified" (confirmed in code), "unverified" (not found/not implemented), or "unclear" (ambiguous)\n- **evidence**: How you verified it, or why you couldn\'t\n'}return g}Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRunTestsAction=async function(e,l){const{requestId:d,testProcessIds:u,parentSessionId:h,mode:g}=e,p="interactive"===g,{logger:m,apiClient:f,projectId:y,projectPath:v,trackChildPid:w}=l
1025
1023
  if(!d)return{success:!1,message:"requestId is required",error:"Missing requestId in payload"}
1026
1024
  m.info("Starting run-tests action",{requestId:d,testProcessIds:u})
1027
1025
  try{const l=await f.get(`/api/projects/${y}/requests/${d}`)
@@ -1053,7 +1051,7 @@ const $={worktreePath:k,commitSha:M,fingerprintHit:A}
1053
1051
  for(const process of b){let t
1054
1052
  const s=e.testRunIds?.[O.length]
1055
1053
  try{s?(await f.patch(`/api/projects/${y}/test-runs/${s}`,$),t=(await f.get(`/api/projects/${y}/test-runs/${s}`)).data,O.push(t.id)):(t=(await f.post(`/api/projects/${y}/test-runs`,{requestId:d,testProcessId:process.id,parentSessionId:h,...$})).data,O.push(t.id))}catch(e){m.error("Failed to get/create test run record",{requestId:d,processId:process.id,preCreatedId:s,error:(0,i.getErrorMessage)(e)})
1056
- continue}const o=r(g,process,0,y,p,e.commandNames),n=p?"tester":"auto-tester"
1054
+ continue}const o=r(g,process,0,y,p,e.commandNames,e.skipCommandNames),n=p?"tester":"auto-tester"
1057
1055
  try{const e=await(0,a.spawnActionAgent)({agent:n,prompt:o,cwd:k,projectPath:v,projectId:y,title:`[${d}] Test: ${process.name}`,requestId:d,parentSessionId:h,allowParallel:!0,apiClient:f,logger:m,trackChildPid:w})
1058
1056
  if(!e.success)throw Error(e.error||"Spawn failed")
1059
1057
  R.push(t.id),e.sessionId&&D.push(e.sessionId),e.pid&&(x=e.pid),e.sessionId&&(f.patch(`/api/projects/${y}/test-runs/${t.id}`,{testerSessionId:e.sessionId}).catch((e=>m.warn("Failed to set testerSessionId on test run",{error:(0,i.getErrorMessage)(e)}))),f.post(`/api/projects/${y}/session-test-process-associations`,{opencodeSessionId:e.sessionId,testProcessId:process.id}).catch((t=>m.warn("Failed to create session\u2194test-process association",{sessionId:e.sessionId,testProcessId:process.id,error:(0,i.getErrorMessage)(t)})))),m.info("Spawned test-runner agent",{testRunId:t.id,processName:process.name,worktreePath:k,pid:e.pid,sessionId:e.sessionId})}catch(e){m.error("Failed to spawn test-runner agent",{testRunId:t.id,error:(0,i.getErrorMessage)(e)})
@@ -1181,7 +1179,7 @@ return t?t[1]:null}(d)
1181
1179
  e&&l.push({eventType:"task_completed",timing:"after",variables:{...u,taskId:e}})}else if(p){const e=d.match(/(?:Created|Updated|Wrote)\s+(?:file\s+)?([^\s\n]+)/i)
1182
1180
  l.push({eventType:"write_file",timing:"after",variables:{...u,path:e?.[1]||""}})}else if(m){const e=t(i?.operations)||[],r=(Array.isArray(e)?e:[]).map((e=>e.path||e.documentId)).filter(Boolean)
1183
1181
  l.push({eventType:"replace_in_files",timing:"after",variables:{...u,paths:r.join(", "),fileCount:r.length+""}})}else if(f){const e={...u,path:i?.operationArgs?.path||"",title:i?.title||""},t=d.match(/\*\*Request:\*\*\s*(req\d+)/i)
1184
- t&&(e.requestId=t[1]),l.push({eventType:"quick_edit",timing:"after",variables:e}),e.requestId&&l.push({eventType:"request_completed",timing:"after",variables:{...u,requestId:e.requestId}})}else if(y){const e=t(i?.paths)||[],r=(Array.isArray(e)?e:[]).map((e=>e.path||e.documentId)).filter(Boolean)
1182
+ t&&(e.requestId=t[1]),l.push({eventType:"quick_edit",timing:"after",variables:e})}else if(y){const e=t(i?.paths)||[],r=(Array.isArray(e)?e:[]).map((e=>e.path||e.documentId)).filter(Boolean)
1185
1183
  l.push({eventType:"read_files",timing:"after",variables:{...u,paths:r.join(", "),fileCount:r.length+""}})}else if(v)l.push({eventType:"search",timing:"after",variables:{...u,query:i?.needle||"",directory:i?.directory||"",fileExtension:i?.options?.fileExtension||"*"}})
1186
1184
  else if(w){const e=t(i?.operations)||[],r=(Array.isArray(e)?e:[]).map((e=>e.operationType)).filter(Boolean)
1187
1185
  l.push({eventType:"manage_files",timing:"after",variables:{...u,operationTypes:[...new Set(r)].join(", ")}})}else I?l.push({eventType:"document_operations",timing:"after",variables:u}):b&&l.push({eventType:"query_history",timing:"after",variables:u})
@@ -1409,8 +1407,8 @@ if(r?.success&&r?.data?.branchName)return r.data.branchName
1409
1407
  if(r?.success&&r?.data)return"requests/"+s}catch(e){o.debug("resolveSetupBranch: request lookup failed, falling back to repo HEAD",{requestId:s,error:(0,a.getErrorMessage)(e)})}if(i)try{const e=(0,n.simpleGit)(i),t=(await e.revparse(["--abbrev-ref","HEAD"])).trim()
1410
1408
  if(t&&"HEAD"!==t)return t}catch(e){o.debug("resolveSetupBranch: revparse HEAD failed, falling back to main",{error:(0,a.getErrorMessage)(e)})}return"main"},exports.createSetupWorktree=async function(e,t,o,i){(0,s.mkdirSync)(r(e),{recursive:!0})
1411
1409
  const a=(0,n.simpleGit)(e)
1412
- await a.raw(["worktree","add","--detach",t,o]),i.info("Created setup worktree",{worktreePath:t,branch:o})},exports.buildSetupPrompt=function(e,t){const r=["You are configuring the first test process for this project.","","Project path: "+e]
1413
- return t&&r.push("Triggered from request: "+t),r.push(""),r.push("1. Inspect manifests (package.json, pyproject.toml, Cargo.toml, go.mod, Makefile, CI configs) to identify build/test/lint commands."),r.push("2. Use `testing_reference` for per-language patterns."),r.push("3. Propose a draft to the user (name, setup commands, test commands with timeouts) as a single message."),r.push("4. Iterate until the user confirms."),r.push("5. Call `testing_process_create` with the agreed configuration."),r.push("6. Send a brief report back to your parent via `session_message_operations` (type: report) summarizing what you registered, then end your session."),r.push(""),r.push("You are read-only with respect to project files. Do not modify source code or run tests."),r.join("\n")},exports.buildCommandSetupPrompt=function(e,t,r){const s=["You are configuring fast project commands (typecheck, lint, build, format, dev server) for this project.","","Project path: "+e]
1410
+ await a.raw(["worktree","add","--detach",t,o]),i.info("Created setup worktree",{worktreePath:t,branch:o})},exports.buildSetupPrompt=function(e,t,r){const s=!(!r||!r.trim()),o=[s?"You are configuring an ADDITIONAL test process for this project (others already exist).":"You are configuring the first test process for this project.","","Project path: "+e]
1411
+ return t&&o.push("Triggered from request: "+t),s&&(o.push(""),o.push(r.trim())),o.push(""),o.push("1. Inspect manifests (package.json, pyproject.toml, Cargo.toml, go.mod, Makefile, CI configs) to identify build/test/lint commands."),o.push("2. Use `testing_reference` for per-language patterns."),o.push("3. Propose a draft to the user (name, setup commands, test commands with timeouts) as a single message."),o.push("4. Iterate until the user confirms."),o.push("5. Call `testing_process_create` with the agreed configuration."),o.push("6. Send a brief report back to your parent via `session_message_operations` (type: report) summarizing what you registered, then end your session."),o.push(""),o.push("You are read-only with respect to project files. Do not modify source code or run tests."),o.join("\n")},exports.buildCommandSetupPrompt=function(e,t,r){const s=["You are configuring fast project commands (typecheck, lint, build, format, dev server) for this project.","","Project path: "+e]
1414
1412
  return t&&s.push("Triggered from request: "+t),r&&r.trim()&&(s.push(""),s.push("Caller hint: "+r.trim()),s.push("Treat the caller hint as guidance about what the user likely wants \u2014 still do your full discovery and confirm with the user before registering. Do not blindly register only what was hinted.")),s.push(""),s.push('1. Call `commands({ operation: "list" })` to see what is already registered.'),s.push("2. Inspect manifests at any depth (package.json, pyproject.toml, Cargo.toml, go.mod, Makefile, deno.json, CI configs)."),s.push("3. For monorepos: ask the user which contexts they want commands for. Propose one command per (context x kind) with the right cwd."),s.push("4. Propose a draft to the user (name, command, description, cwd, timeout) in a single message."),s.push("5. Iterate until the user confirms."),s.push('6. Call `commands({ operation: "register", commands: [...] })` to submit the agreed batch \u2014 each item creates a per-command approval notification the user must click through.'),s.push("7. Send a brief report back to your parent via `session_message_operations` (type: report) summarizing what you registered, then end your session."),s.push(""),s.push("You are read-only with respect to project files. Do not modify source code or run the commands."),s.join("\n")}
1415
1413
  const s=t(9896),o=t(6928),n=t(3807),i=t(6982),a=t(8824),c=".alchemy_lab",l="setup-worktrees"},8524(e,exports,t){"use strict"
1416
1414
  var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
@@ -1472,11 +1470,11 @@ if("string"==typeof t.body){try{const e=JSON.parse(t.body)
1472
1470
  if(e.error?.message)return e.error.message
1473
1471
  if(e.message)return e.message}catch{}return t.body.substring(0,200)}for(const e of Object.keys(t)){const r=t[e]
1474
1472
  if("string"==typeof r&&r.length>0)return`${e}: ${r}`}return"Unknown error (no readable properties)"}},8955(e,exports){"use strict"
1475
- function t(){return n||s}function r(){return t().map((e=>e.name))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.REQUEST_SCOPED_AGENTS=void 0,exports.initializeAgentRegistry=async function(e,t){return a||(a=(async()=>{try{if(!e)return t.debug("No API client available, using default agents"),n=s,void(i=!0)
1473
+ function t(){return n||s}function r(){return t().map((e=>e.name))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.PERSISTENT_ORCHESTRATOR_AGENTS=exports.REQUEST_SCOPED_AGENTS=void 0,exports.initializeAgentRegistry=async function(e,t){return a||(a=(async()=>{try{if(!e)return t.debug("No API client available, using default agents"),n=s,void(i=!0)
1476
1474
  t.info("Fetching available agents from API")
1477
1475
  const r=await e.proxyGet("/api/agents/templates")
1478
1476
  r&&Array.isArray(r)&&r.length>0?(n=r.map((e=>({id:e.id||e.name,name:e.name,description:e.description,mode:e.mode,builtIn:e.builtIn}))),t.info("Agent registry initialized",{agentCount:n.length})):(t.warn("No agents returned from API, using defaults"),n=s),i=!0}catch(e){t.warn("Failed to fetch agents from API, using defaults",{error:e instanceof Error?e.message:e+""}),n=s,i=!0}})(),a)},exports.getAvailableAgents=t,exports.getAgentNames=r,exports.isValidAgent=function(e){return r().includes(e)},exports.getDefaultAgent=function(){return"work"},exports.formatAgentsForDescription=function(){return t().map((e=>`'${e.name}'${e.description?" - "+e.description:""}`)).join(", ")},exports.isAgentRegistryInitialized=function(){return i},exports.getBuiltInAgentConfig=function(e){const t=s.find((t=>t.name===e))
1479
- return t?{preferredProvider:t.preferredProvider||"inherit",preferredModelTier:t.preferredModelTier||"same",requestContextMode:t.requestContextMode}:null},exports.getAllowedSubagents=function(e){return o[e]||null},exports.resetAgentRegistry=function(){n=null,i=!1,a=null},exports.REQUEST_SCOPED_AGENTS=["coder","tester","test-architect"]
1477
+ return t?{preferredProvider:t.preferredProvider||"inherit",preferredModelTier:t.preferredModelTier||"same",requestContextMode:t.requestContextMode}:null},exports.getAllowedSubagents=function(e){return o[e]||null},exports.resetAgentRegistry=function(){n=null,i=!1,a=null},exports.REQUEST_SCOPED_AGENTS=["coder","tester","test-architect"],exports.PERSISTENT_ORCHESTRATOR_AGENTS=["alchemist","herald"]
1480
1478
  const s=[{id:"coder",name:"coder",description:"Development and implementation agent",builtIn:!0,preferredModelTier:"same",requestContextMode:"required"},{id:"research",name:"research",description:"Codebase research and exploration agent",builtIn:!0,preferredModelTier:"two_down",requestContextMode:"none"},{id:"journal",name:"journal",description:"Journal generation agent",builtIn:!0,preferredModelTier:"one_down"},{id:"planner",name:"planner",description:"Planning and architecture agent",builtIn:!0,preferredModelTier:"same"},{id:"specialist",name:"specialist",description:"Domain specialist for development tasks",builtIn:!0,preferredModelTier:"same"},{id:"auto-planner",name:"auto-planner",description:"Autonomous background planner",builtIn:!0,preferredModelTier:"same"},{id:"alchemist",name:"alchemist",description:"Persistent orchestrator",builtIn:!0,preferredModelTier:"same"}],o={alchemist:["specialist","research","planner"],specialist:["coder","research","auto-planner","planner"],tester:["research"],"auto-tester":["research"]}
1481
1479
  let n=null,i=!1,a=null},8984(e,exports,t){"use strict"
1482
1480
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.MCPClientConfigurer=void 0