alchemylab 1.0.10 → 1.0.11

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
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- (()=>{"use strict"
3
- function e(t){var s=n[t]
2
+ (()=>{function e(t){var s=n[t]
4
3
  if(void 0!==s)return s.exports
5
4
  var module=n[t]={exports:{}}
6
- return o[t].call(module.exports,module,module.exports,e),module.exports}var t,s,r,o={848(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFinalizeRequestAction=async function(e,t){const{requestId:o}=e,{logger:n,apiClient:i,projectPath:a,projectId:c}=t
5
+ return o[t].call(module.exports,module,module.exports,e),module.exports}var t,s,r,o={848(e,exports,t){"use strict"
6
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFinalizeRequestAction=async function(e,t){const{requestId:o}=e,{logger:n,apiClient:i,projectPath:a,projectId:c}=t
7
7
  if(!o)return{success:!1,message:"requestId is required",error:"Missing requestId in payload"}
8
8
  n.info("Starting finalize-request action",{requestId:o})
9
9
  try{const e=await i.post(`/api/projects/${c}/requests/${o}/validate-completion`,{source:"ui"})
@@ -20,7 +20,9 @@ m=t.latest?.hash,n.info("Git merge completed",{requestId:o,mergeCommit:m?.substr
20
20
  if(t.toLowerCase().includes("conflict")){try{await h.merge(["--abort"])}catch(e){n.error("CRITICAL: git merge --abort failed \u2014 repo may be in inconsistent state",{requestId:o,error:e instanceof Error?e.message:e+""})}return{success:!1,message:`Merge conflicts detected for request ${o}. Please resolve conflicts before finalizing.`,error:"Merge conflicts",data:{hasConflicts:!0}}}return{success:!1,message:"Merge failed: "+t,error:t}}try{await h.deleteLocalBranch(u,!0),y=!0}catch{}try{await i.post(`/api/projects/${c}/requests/${o}/finalize-completion`,{summary:"Finalized request "+o,acceptanceEvidence:[{evidence:"Finalized via GUI after review"}],mergeResult:{mergeCommitHash:m||"unknown",cleanedUp:y,method:"action-server-merge"}})}catch(e){const t=(0,r.getErrorMessage)(e)
21
21
  return n.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:o,mergeCommitHash:m,error:t}),{success:!1,message:`Code was merged (commit: ${m?.substring(0,8)}) but server finalization failed: ${t}`,error:t,data:{mergeCommitHash:m,partialSuccess:!0}}}return{success:!0,message:`Successfully finalized request ${o}: ${d?.title||o}`,data:{mergeCommitHash:m,branchDeleted:y}}}catch(e){const t=(0,r.getErrorMessage)(e)
22
22
  return n.error("finalize-request action failed",{requestId:o,error:t}),{success:!1,message:"Failed to finalize request: "+t,error:t}}}
23
- const s=t(3807),r=t(8824)},857(module){module.exports=require("os")},1152(e,exports){function t(e=!0){return new s(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.createMetricsCollector=t,exports.createNullMetricsCollector=function(){return t(!1)}
23
+ const s=t(3807),r=t(8824)},857(module){"use strict"
24
+ module.exports=require("os")},1152(e,exports){"use strict"
25
+ function t(e=!0){return new s(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.createMetricsCollector=t,exports.createNullMetricsCollector=function(){return t(!1)}
24
26
  class s{constructor(e=!0){this.enabled=e,this.counters=new Map,this.gauges=new Map,this.histograms=new Map}getKey(e,t){const s=Object.entries(t).map((([e,t])=>`${e}="${t+""}"`)).join(",")
25
27
  return s?`${e}{${s}}`:e}incrementCounter(e,t=1,s={}){if(!this.enabled)return
26
28
  const r=this.getKey(e,s),o=this.counters.get(r)||0
@@ -31,7 +33,8 @@ const r=this.getKey(e,s),o=this.histograms.get(r)||[]
31
33
  o.push(t),this.histograms.set(r,o)}recordValue(e,t,s={}){this.observeHistogram(e,t,s)}startTimer(e){if(!this.enabled)return()=>{}
32
34
  const t=Date.now()
33
35
  return(s={})=>{const r=Date.now()-t
34
- this.observeHistogram(e,r,s)}}getMetrics(){return{counters:Object.fromEntries(this.counters),gauges:Object.fromEntries(this.gauges),histograms:Object.fromEntries(this.histograms)}}reset(){this.counters.clear(),this.gauges.clear(),this.histograms.clear()}}},1187(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.UnifiedLauncher=void 0
36
+ this.observeHistogram(e,r,s)}}getMetrics(){return{counters:Object.fromEntries(this.counters),gauges:Object.fromEntries(this.gauges),histograms:Object.fromEntries(this.histograms)}}reset(){this.counters.clear(),this.gauges.clear(),this.histograms.clear()}}},1187(e,exports,t){"use strict"
37
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.UnifiedLauncher=void 0
35
38
  const s=t(5317),r=t(8824)
36
39
  exports.UnifiedLauncher=class{constructor(e,t,s){this.logger=e,this.installContext=t,this.configurer=s}async launch(e){const{projectPath:t,settings:s,multiAgent:o}=e,{installPath:n,nodePath:i}=this.installContext
37
40
  this.logger.info("UnifiedLauncher: Starting launch",{projectPath:t,installPath:n})
@@ -45,7 +48,8 @@ const l=s=>{i+=s
45
48
  const o=i.match(/listening on http:\/\/[^:]+:(\d+)/)
46
49
  if(o&&!c){const s=parseInt(o[1],10)
47
50
  c=!0,this.logger.info("UnifiedLauncher: Discovered opencode serve port",{pid:t.pid,port:s}),t.unref(),e({success:!0,pid:t.pid,port:s,configPath:r.configPath})}}
48
- t.stdout?.on("data",(e=>l(e.toString()))),t.stderr?.on("data",(e=>l(e.toString()))),setTimeout((()=>{c||(c=!0,this.logger.warn("UnifiedLauncher: Timeout waiting for opencode serve port",{outputBuffer:i.slice(0,500)}),t.unref(),e({success:!0,pid:t.pid,configPath:r.configPath,error:"Could not determine port from opencode serve output"}))}),1e4),t.on("error",(t=>{c||(c=!0,this.logger.error("UnifiedLauncher: opencode serve failed to start",{error:t.message}),e({success:!1,error:"Failed to start opencode serve: "+t.message}))})),t.on("exit",(t=>{c||(c=!0,this.logger.error("UnifiedLauncher: opencode serve exited early",{code:t,output:i.slice(0,500)}),e({success:!1,error:"opencode serve exited with code "+t}))}))}))}}},1253(e,exports,t){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
51
+ t.stdout?.on("data",(e=>l(e.toString()))),t.stderr?.on("data",(e=>l(e.toString()))),setTimeout((()=>{c||(c=!0,this.logger.warn("UnifiedLauncher: Timeout waiting for opencode serve port",{outputBuffer:i.slice(0,500)}),t.unref(),e({success:!0,pid:t.pid,configPath:r.configPath,error:"Could not determine port from opencode serve output"}))}),1e4),t.on("error",(t=>{c||(c=!0,this.logger.error("UnifiedLauncher: opencode serve failed to start",{error:t.message}),e({success:!1,error:"Failed to start opencode serve: "+t.message}))})),t.on("exit",(t=>{c||(c=!0,this.logger.error("UnifiedLauncher: opencode serve exited early",{code:t,output:i.slice(0,500)}),e({success:!1,error:"opencode serve exited with code "+t}))}))}))}}},1253(e,exports,t){"use strict"
52
+ var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
49
53
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.TokenManager=void 0
50
54
  const r=s(t(6928)),o=s(t(1943)),n=s(t(6982)),i=s(t(857)),a=t(9067),c=t(8824),l="alchemy-lab"
51
55
  exports.TokenManager=class{constructor(e,t,s={}){this.projectId=null,this.encryptionKey=null,this.pendingAuthCheck=!1,this.tempAuthCode=null,this.CACHE_TTL_MS=6e4,this.TOKEN_CACHE={manualToken:null,encryptedToken:null,hasValidToken:null},this.initPromise=null,this.initialized=!1,this.logger=e.child({component:"token-manager"}),this.remoteServerUrl=s.remoteServerUrl||"https://api.alchemylabcode.com",this.allowInteractiveAuth=!1!==s.allowInteractiveAuth,void 0!==s.cacheTtlMs&&s.cacheTtlMs>0&&(this.CACHE_TTL_MS=s.cacheTtlMs),this.serverInstallDir=this.getModuleDir(),this.tokenDirPath=this.serverInstallDir,this.authFlow=new a.ExternalAuthFlow(e,this.remoteServerUrl),this.logger.info("TokenManager initialized",{workingDir:t,serverInstallDir:this.serverInstallDir,tokenDirPath:this.tokenDirPath,allowInteractiveAuth:this.allowInteractiveAuth,cacheTtlMs:this.CACHE_TTL_MS}),this.generateEncryptionKey()}getModuleDir(){const e=__dirname||process.cwd(),t=i.default.homedir()
@@ -107,7 +111,9 @@ const t=this.remoteServerUrl+"/auth/validate"
107
111
  this.logger.debug("Making token validation request",{validationUrl:t})
108
112
  const s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer "+e.token,"Content-Type":"application/json"},signal:AbortSignal.timeout(1e4)})
109
113
  if(s.ok){const e=await s.json()
110
- return this.logger.info("Token validation successful",{status:e.status||"unknown",username:e.username||"unknown"}),!0}return this.logger.info("Token validation failed - token may be invalid or expired",{status:s.status,statusText:s.statusText}),this.invalidateCache(),!1}catch(e){return e instanceof Error&&"AbortError"===e.name?(this.logger.info("Token validation request timed out - assuming offline or server unavailable"),!0):(this.logger.info("Token validation request failed",{error:(0,c.getErrorMessage)(e)}),!0)}}async hasValidAndWorkingToken(){return!!await this.hasValidToken()&&await this.validateTokenWithRemoteServer()}async isGoogleOAuthAvailable(){return await this.authFlow.isGoogleOAuthAvailable()}async startGoogleOAuthFlow(){return await this.authFlow.startGoogleOAuthFlow()}async startGoogleOAuthPolling(e,t,s,r,o){return await this.authFlow.startGoogleOAuthPolling(e,t,s,r,o)}}},1943(module){module.exports=require("fs/promises")},2096(e,exports,t){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
114
+ return this.logger.info("Token validation successful",{status:e.status||"unknown",username:e.username||"unknown"}),!0}return this.logger.info("Token validation failed - token may be invalid or expired",{status:s.status,statusText:s.statusText}),this.invalidateCache(),!1}catch(e){return e instanceof Error&&"AbortError"===e.name?(this.logger.info("Token validation request timed out - assuming offline or server unavailable"),!0):(this.logger.info("Token validation request failed",{error:(0,c.getErrorMessage)(e)}),!0)}}async hasValidAndWorkingToken(){return!!await this.hasValidToken()&&await this.validateTokenWithRemoteServer()}async isGoogleOAuthAvailable(){return await this.authFlow.isGoogleOAuthAvailable()}async startGoogleOAuthFlow(){return await this.authFlow.startGoogleOAuthFlow()}async startGoogleOAuthPolling(e,t,s,r,o){return await this.authFlow.startGoogleOAuthPolling(e,t,s,r,o)}}},1943(module){"use strict"
115
+ module.exports=require("fs/promises")},2096(e,exports,t){"use strict"
116
+ var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
111
117
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectConfigService=void 0
112
118
  const r=s(t(1943)),o=s(t(6928)),n=s(t(857)),i=t(4139),a=t(8824)
113
119
  exports.ProjectConfigService=class{constructor(e){this.logger=e.child({component:"project-config"})}async readProjectId(e){try{const t=o.default.join(e,i.ALCHEMY_DIR_NAME,"project.json"),s=await r.default.readFile(t,"utf-8"),n=JSON.parse(s)
@@ -123,7 +129,8 @@ return e&&o[e]?o[e]:e?null:o}catch(t){return this.logger.debug("No user preferen
123
129
  this.logger.info("Saving user tool preferences",{clientType:e,preset:t,disabledToolsCount:s?.length||0,allowedToolsCount:n?.length||0}),await r.default.mkdir(a,{recursive:!0})
124
130
  let c={}
125
131
  try{const e=await r.default.readFile(i,"utf-8")
126
- c=JSON.parse(e)}catch(e){}c[e]={preset:t,disabledTools:s||[],allowedAlchemyTools:n||[],updatedAt:(new Date).toISOString()},await r.default.writeFile(i,JSON.stringify(c,null,2),"utf-8"),this.logger.info("User tool preferences saved",{clientType:e,prefsFile:i})}}},2366(e,exports,t){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
132
+ c=JSON.parse(e)}catch(e){}c[e]={preset:t,disabledTools:s||[],allowedAlchemyTools:n||[],updatedAt:(new Date).toISOString()},await r.default.writeFile(i,JSON.stringify(c,null,2),"utf-8"),this.logger.info("User tool preferences saved",{clientType:e,prefsFile:i})}}},2366(e,exports,t){"use strict"
133
+ var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
127
134
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.AlchemyActionServer=void 0
128
135
  const r=s(t(7252)),o=s(t(8577)),n=t(4192),i=t(1152),a=s(t(6928)),c=s(t(9896)),l=s(t(857)),d=t(5607),u=t(8984),h=t(8524),g=t(8824),p=t(2096),f=t(7210),m=t(2928),y=t(5317)
129
136
  class v{updateAuthToken(e){this.options.authToken=e,this.apiClient.authToken=e,this.configurer.authToken=e}constructor(e,t){this.directReportDedup=new Map,this.settingsSyncCounter=0,this.isPolling=!1,this.isProcessingAction=!1,this.openCodeUrlCache=null,this.openCodePort=null,this.proxyAbortControllers=new Map,this.trackedChildPids=new Set,this.sseEventBuffer=[],this.hasRemoteEventConsumers=!1,this.cachedProjectConfig=null,this.logger=e,this.options=t,this.port=t.port||3456,this.startTime=new Date
@@ -371,7 +378,8 @@ if(!this.stuckSessionWatchdog)return void t.status(503).json({success:!1,error:"
371
378
  const r=await this.stuckSessionWatchdog.retrySession(s)
372
379
  r.success?t.json({success:!0}):t.status(400).json({success:!1,error:r.error})}async stop(){this.logger.info("Stopping AlchemyActionServer...")
373
380
  for(const[e]of this.proxyAbortControllers)try{e.abort()}catch{}if(this.proxyAbortControllers.size>0&&await Promise.allSettled([...this.proxyAbortControllers.values()]),this.proxyAbortControllers.clear(),this.killTrackedProcesses(),this.stuckSessionWatchdog?.stop(),this.stopSSEEventForwarder(),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)
374
- this.server.close((()=>{clearTimeout(t),e()}))}else e()})),this.logger.info("AlchemyActionServer stopped")}getPort(){return this.port}isRunning(){return!!this.server}}exports.AlchemyActionServer=v,v.PROJECT_CONFIG_TTL=3e4},2424(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ensureRequestWorktree=async function(e,t,i){const a="requests/"+t,c=(0,r.join)(e,n.ALCHEMY_DIR_NAME,"worktrees"),l=(0,r.join)(c,t)
381
+ this.server.close((()=>{clearTimeout(t),e()}))}else e()})),this.logger.info("AlchemyActionServer stopped")}getPort(){return this.port}isRunning(){return!!this.server}}exports.AlchemyActionServer=v,v.PROJECT_CONFIG_TTL=3e4},2424(e,exports,t){"use strict"
382
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.ensureRequestWorktree=async function(e,t,i){const a="requests/"+t,c=(0,r.join)(e,n.ALCHEMY_DIR_NAME,"worktrees"),l=(0,r.join)(c,t)
375
383
  if((0,s.existsSync)(l))return void i.info("Worktree already exists on disk, skipping pre-spawn creation",{requestId:t,worktreePath:l})
376
384
  const d=(0,o.simpleGit)(e);(0,s.mkdirSync)(c,{recursive:!0})
377
385
  try{await d.raw(["worktree","prune"])}catch{}const u=await d.branch(),h=u.all.includes(a)
@@ -379,7 +387,8 @@ try{if(h)await d.raw(["worktree","add",l,a]),i.info("Pre-spawn: created worktree
379
387
  else{const e=u.all.includes("main")?"main":"master"
380
388
  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 s=e instanceof Error?e.message:e+""
381
389
  i.warn("Pre-spawn: failed to create worktree (MCP process will retry)",{requestId:t,error:s})}}
382
- const s=t(9896),r=t(6928),o=t(3807),n=t(4139)},2782(e,exports,t){function s(){return"true"===process.env.ENABLE_DEBUG_TOOLS?.toLowerCase()}function r(e={}){const t={...function(e){const t={}
390
+ const s=t(9896),r=t(6928),o=t(3807),n=t(4139)},2782(e,exports,t){"use strict"
391
+ function s(){return"true"===process.env.ENABLE_DEBUG_TOOLS?.toLowerCase()}function r(e={}){const t={...function(e){const t={}
383
392
  if(!s())return t.level=(0,l.isDevBuild)()?c.LogLevel.INFO:c.LogLevel.ERROR,t.logToFile=!1,t
384
393
  if("true"===process.env.DEBUG_LOGGING?.toLowerCase()){t.level=c.LogLevel.DEBUG,t.logToFile=!0
385
394
  const s=e||process.cwd()
@@ -396,7 +405,8 @@ const e=process.env.DEBUG_LEVEL?.toLowerCase()
396
405
  return e&&Object.values(c.LogLevel).includes(e)?e:c.LogLevel.INFO}
397
406
  const n=o(t(5124)),i=o(t(6928)),a=o(t(9896)),c=t(6540),l=t(7960),d=n.default.format.combine(n.default.format.timestamp(),n.default.format.colorize(),n.default.format.printf((({level:e,message:t,timestamp:s,...r})=>`${s} [${e}]: ${t}${Object.keys(r).length?" "+JSON.stringify(r,null,0):""}`))),u=n.default.format.combine(n.default.format.timestamp(),n.default.format.json()),h=n.default.format.combine(n.default.format.timestamp(),n.default.format.printf((({level:e,message:t,timestamp:s,service:r,component:o,...n})=>{const i=r?`[${r}]`:"",a=o?`[${o}]`:"",c=Object.keys(n).length?" "+JSON.stringify(n,null,2):""
398
407
  return`${s} ${i}${a} [${e.toUpperCase()}]: ${t}${c}`}))),g=r({logToFile:!1,console:!0,level:c.LogLevel.INFO})
399
- exports.default=g},2928(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.StuckSessionWatchdog=void 0
408
+ exports.default=g},2928(e,exports,t){"use strict"
409
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.StuckSessionWatchdog=void 0
400
410
  const s=t(8824)
401
411
  exports.StuckSessionWatchdog=class{constructor(e){this.stuckSessions=new Map,this.resolvedRecently=new Set,this.notifiedSessions=new Set,this.testInjectedIds=new Set,this.logger=e.logger,this.getOpenCodeUrl=e.getOpenCodeUrl,this.onStuckDetected=e.onStuckDetected,this.onStuckResolved=e.onStuckResolved,this.checkIntervalMs=e.checkIntervalMs??3e4,this.stuckThresholdMs=e.stuckThresholdMs??9e4,this.maxRetries=e.maxRetries??3}start(){this.intervalTimer||(this.logger.info("Stuck session watchdog starting",{checkInterval:this.checkIntervalMs,stuckThreshold:this.stuckThresholdMs,maxRetries:this.maxRetries}),setTimeout((()=>this.check().catch((()=>{}))),5e3),this.intervalTimer=setInterval((()=>{this.check().catch((()=>{}))}),this.checkIntervalMs))}stop(){this.intervalTimer&&(clearInterval(this.intervalTimer),this.intervalTimer=void 0),this.stuckSessions.clear(),this.notifiedSessions.clear(),this.resolvedRecently.clear(),this.logger.info("Stuck session watchdog stopped")}getStuckSessions(){return Array.from(this.stuckSessions.values())}isStuck(e){return this.stuckSessions.has(e)}injectTestStuck(e,t){const s=e||"test-stuck-"+Date.now(),r={sessionId:s,messageId:"test-msg-"+Date.now(),detectedAt:Date.now(),retryCount:0,lastMessageCreated:Date.now()-this.stuckThresholdMs-1e3,sessionTitle:t||"Test Stuck Session"}
402
412
  return this.stuckSessions.set(s,r),this.testInjectedIds.add(s),this.notifiedSessions.add(s),this.onStuckDetected?.(r),r}clearTestStuck(e){return!!this.testInjectedIds.has(e)&&(this.testInjectedIds.delete(e),this.stuckSessions.delete(e),this.notifiedSessions.delete(e),this.onStuckResolved?.(e),!0)}async check(){const e=this.getOpenCodeUrl()
@@ -428,7 +438,8 @@ const s=await fetch(`${t}/session/${e}/abort`,{method:"POST",signal:AbortSignal.
428
438
  s.ok||this.logger.warn("Abort returned non-OK (may already be idle)",{sessionId:e,status:s.status}),await new Promise((e=>setTimeout(e,1e3))),this.logger.info("Retrying stuck session: sending continue",{sessionId:e})
429
439
  const o=await fetch(`${t}/session/${e}/prompt_async`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:"Continue"}]}),signal:AbortSignal.timeout(1e4)})
430
440
  if(!o.ok){const e=await o.text().catch((()=>""))
431
- return{success:!1,error:`Failed to re-send prompt: ${o.status} ${e}`}}return r.retryCount++,this.stuckSessions.delete(e),this.notifiedSessions.delete(e),this.logger.info("Stuck session retry sent",{sessionId:e,retryCount:r.retryCount}),{success:!0}}catch(e){return{success:!1,error:(0,s.getErrorMessage)(e)}}}}},3077(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.HookExecutor=void 0
441
+ return{success:!1,error:`Failed to re-send prompt: ${o.status} ${e}`}}return r.retryCount++,this.stuckSessions.delete(e),this.notifiedSessions.delete(e),this.logger.info("Stuck session retry sent",{sessionId:e,retryCount:r.retryCount}),{success:!0}}catch(e){return{success:!1,error:(0,s.getErrorMessage)(e)}}}}},3077(e,exports,t){"use strict"
442
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.HookExecutor=void 0
432
443
  const s=t(8740),r=t(4627),o=t(4769)
433
444
  exports.HookExecutor=class{constructor(e,t,r,o,n){this.logger=e,this.cache=new s.HookCache(e,t,o),this.ctx={logger:e,projectId:t,projectPath:r,apiClient:o,cachedDefaultModel:n?.cachedDefaultModel,trackChildPid:n?.trackChildPid}}setDefaultModel(e){this.ctx.cachedDefaultModel=e}setProjectId(e){this.ctx.projectId=e,this.cache.setProjectId(e)}async processEvent(e){const{eventType:t,sessionId:s,variables:o,timing:n}=e,i={triggered:0,hooks:[]}
434
445
  if(!this.ctx.projectId)return this.logger.debug("No project ID, skipping hook event",{eventType:t}),i
@@ -455,14 +466,18 @@ if(this.logger.info("Executing custom event hook",{name:e.name,event:n,chainDept
455
466
  break
456
467
  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)
457
468
  const c=(0,r.determineEventToEmit)(e,a)
458
- c&&await this.processCustomEvent(c,a,s+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{}}}},3444(e,exports,t){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
469
+ c&&await this.processCustomEvent(c,a,s+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{}}}},3444(e,exports,t){"use strict"
470
+ var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
459
471
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=exports.defaultLogger=exports.isDebugToolsEnabled=exports.getDebugLevelFromEnv=exports.isDebugLoggingEnabled=exports.createEnvLogger=exports.createLogger=void 0
460
472
  const r=t(2782)
461
473
  Object.defineProperty(exports,"createLogger",{enumerable:!0,get(){return r.createLogger}}),Object.defineProperty(exports,"createEnvLogger",{enumerable:!0,get(){return r.createEnvLogger}}),Object.defineProperty(exports,"isDebugLoggingEnabled",{enumerable:!0,get(){return r.isDebugLoggingEnabled}}),Object.defineProperty(exports,"getDebugLevelFromEnv",{enumerable:!0,get(){return r.getDebugLevelFromEnv}}),Object.defineProperty(exports,"isDebugToolsEnabled",{enumerable:!0,get(){return r.isDebugToolsEnabled}})
462
474
  const o=s(t(2782))
463
475
  exports.defaultLogger=o.default
464
476
  const n=t(6540)
465
- Object.defineProperty(exports,"LogLevel",{enumerable:!0,get(){return n.LogLevel}}),exports.default=o.default},3785(module){module.exports=require("readline")},3807(module){module.exports=require("simple-git")},3962(e,exports,t){function s(){if(n)return n
477
+ Object.defineProperty(exports,"LogLevel",{enumerable:!0,get(){return n.LogLevel}}),exports.default=o.default},3785(module){"use strict"
478
+ module.exports=require("readline")},3807(module){"use strict"
479
+ module.exports=require("simple-git")},3962(e,exports,t){"use strict"
480
+ function s(){if(n)return n
466
481
  const e=process.argv[1]||""
467
482
  let s=e
468
483
  try{s=t(9896).realpathSync(e)}catch{}let r=""
@@ -475,7 +490,9 @@ r=e.includes("alchemy-local")||e.includes("alchemy")?o.default.join(e,"dist-dev"
475
490
  return n={installPath:r,scriptPath:a,nodePath:process.execPath,isDevMode:i,serverName:"alchemy",remoteServerUrl:c},n}var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
476
491
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.getInstallContext=s,exports.clearInstallContextCache=function(){n=null},exports.isDevMode=function(e){return e?e.includes("dist-dev")||process.env.REMOTE_SERVER_URL?.includes("localhost")||!1:s().isDevMode},exports.getServerName=function(e){return e??s().isDevMode,"alchemy"}
477
492
  const o=r(t(6928))
478
- let n=null},4139(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.ALCHEMY_DIR_NAME=exports.TOKEN_DIR_NAME=void 0,exports.TOKEN_DIR_NAME="alchemy-key",exports.ALCHEMY_DIR_NAME=".alchemy_lab"},4192(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.BaseApiClient=void 0
493
+ let n=null},4139(e,exports){"use strict"
494
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.ALCHEMY_DIR_NAME=exports.TOKEN_DIR_NAME=void 0,exports.TOKEN_DIR_NAME="alchemy-key",exports.ALCHEMY_DIR_NAME=".alchemy_lab"},4192(e,exports,t){"use strict"
495
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.BaseApiClient=void 0
479
496
  const s=t(7163)
480
497
  exports.BaseApiClient=class{constructor(e,t,r,o,n){this.failureCount=0,this.circuitState="closed",this.circuitResetTimeout=null,this.baseUrl=e,this.logger=t,this.metrics=r,this.authToken=o,this.options={retryAttempts:3,retryDelay:1e3,timeout:1e4,circuitBreakerThreshold:5,circuitBreakerResetTime:3e4,...n},this.logger.debug("BaseApiClient constructor options:",{providedOptions:n?JSON.stringify(n):"undefined",mergedOptions:JSON.stringify(this.options)})
481
498
  try{(0,s.debugTokenAccess)(this,"BaseApiClient constructor")}catch(e){}}setAuthToken(e){this.authToken=e||void 0,this.logger.debug("Auth token updated",{hasToken:!!e,tokenLength:e?e.length:0})}getAuthToken(){return this.authToken}async requestWithRetry(e,t,s,r,o){if("open"===this.circuitState)throw this.logger.warn(`Circuit breaker open - rejecting request to ${e} ${t}`),Error("Service unavailable - circuit breaker open")
@@ -517,7 +534,9 @@ const s=Math.min((this.options.retryDelay||1e3)*Math.pow(2,l-1),5e3)
517
534
  this.logger.warn(`API request failed, retrying in ${s}ms`,{method:e,url:i,error:t.message||t+"",attempt:l,maxAttempts:d}),await new Promise((e=>setTimeout(e,s)))}}throw Error("Unexpected end of requestWithRetry")}incrementFailureCount(){this.failureCount++,this.metrics.setGauge("api_failure_count",this.failureCount),"half-open"!==this.circuitState&&(this.failureCount<this.options.circuitBreakerThreshold||"closed"!==this.circuitState)||this.openCircuit()}resetFailureCount(){const e="closed"!==this.circuitState
518
535
  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)
519
536
  const e=this.options.circuitBreakerResetTime||5e3
520
- this.circuitResetTimeout=setTimeout((()=>{this.circuitState="half-open",this.logger.info("Circuit breaker half-open, next request will probe")}),e)}async get(e,t,s){return this.requestWithRetry("GET",e,void 0,s,t)}async post(e,t,s){return this.requestWithRetry("POST",e,t,s)}async put(e,t,s){return this.requestWithRetry("PUT",e,t,s)}async delete(e,t){return this.requestWithRetry("DELETE",e,void 0,t)}async patch(e,t,s){return this.requestWithRetry("PATCH",e,t,s)}}},4627(e,exports){function t(e,t){try{return function(e){const t=s.get(e)
537
+ this.circuitResetTimeout=setTimeout((()=>{this.circuitState="half-open",this.logger.info("Circuit breaker half-open, next request will probe")}),e)}async get(e,t,s){return this.requestWithRetry("GET",e,void 0,s,t)}async post(e,t,s){return this.requestWithRetry("POST",e,t,s)}async put(e,t,s){return this.requestWithRetry("PUT",e,t,s)}async delete(e,t){return this.requestWithRetry("DELETE",e,void 0,t)}async patch(e,t,s){return this.requestWithRetry("PATCH",e,t,s)}}},4245(module){function e(e){var t=Error("Cannot find module '"+e+"'")
538
+ throw t.code="MODULE_NOT_FOUND",t}e.keys=()=>[],e.resolve=e,e.id=4245,module.exports=e},4627(e,exports){"use strict"
539
+ function t(e,t){try{return function(e){const t=s.get(e)
521
540
  if(t)return t
522
541
  let r=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"{{GLOBSTAR}}").replace(/\*/g,"[^/]*").replace(/\?/g,".").replace(/\{\{GLOBSTAR\}\}/g,".*")
523
542
  const o=RegExp(`^${r}$`)
@@ -556,7 +575,8 @@ return o.set(e,t),!1},exports.tryMarkMessageProcessed=function(e,t){if(!t)return
556
575
  if(i.get(e)===t)return!1
557
576
  if(i.set(e,t),i.size>100){const e=i.keys().next().value
558
577
  e&&i.delete(e)}return!0}
559
- const s=new Map,r=new Map,o=new Map,n=2e3,i=new Map},4769(e,exports,t){function s(e){return(0,o.getOpenCodeServerUrl)(e.projectPath,e.logger)}async function r(e,t,r){const o=s(r)
578
+ const s=new Map,r=new Map,o=new Map,n=2e3,i=new Map},4769(e,exports,t){"use strict"
579
+ function s(e){return(0,o.getOpenCodeServerUrl)(e.projectPath,e.logger)}async function r(e,t,r){const o=s(r)
560
580
  if(!o||!t)return!1
561
581
  try{const s=await async function(e,t){try{const s=await t.apiClient.get(`/api/projects/${t.projectId}/cli-sessions/external/opencode/${encodeURIComponent(e)}`),r=s?.data||s
562
582
  return r?.agentType||""}catch{return""}}(t,r)||void 0
@@ -580,7 +600,11 @@ if(!i.success||!i.data)return void s.logger.warn("Direct report returned failure
580
600
  const{notifiedSessions:a,report:c,parentExternalSessionId:l}=i.data,d=a||(l?[{externalSessionId:l}]:[])
581
601
  for(const e of d){const t=c?.content?.reportStatus||"success",o=[`\x3c!-- inserted-prompt --\x3e${{success:"\u2705",partial:"\u26a0\ufe0f",failure:"\u274c",blocked:"\u{1f6ab}"}[t]||"\u{1f4cb}"} **Worker Report \u2014 ${t}**`,"",c?.content?.summary||"Task completed",...c?.content?.details?["",c.content.details]:[]].join("\n")
582
602
  await r(o,e.externalSessionId,s)}}catch(t){s.logger.warn("Error in direct report",{sessionId:e,error:t+""})}}
583
- const o=t(8148)},5086(module){module.exports=require("ws")},5124(module){module.exports=require("winston")},5317(module){module.exports=require("child_process")},5607(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.executeAction=async function(e,t,s){const r=u[e]
603
+ const o=t(8148)},5086(module){"use strict"
604
+ module.exports=require("ws")},5124(module){"use strict"
605
+ module.exports=require("winston")},5317(module){"use strict"
606
+ module.exports=require("child_process")},5607(e,exports,t){"use strict"
607
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.executeAction=async function(e,t,s){const r=u[e]
584
608
  if(!r)return{success:!1,message:"Unknown action type: "+e,error:"No handler registered for action type: "+e}
585
609
  try{return await r(t,s)}catch(t){const r=(0,d.getErrorMessage)(t)
586
610
  return s.logger.error("Action handler failed",{actionType:e,error:r}),{success:!1,message:"Action failed: "+r,error:r}}}
@@ -589,7 +613,8 @@ if(!r||!o)return{success:!1,message:"sessionId and message are required",error:"
589
613
  const n=await Promise.resolve().then(t.t.bind(t,9896,23)),i=(await Promise.resolve().then(t.t.bind(t,6928,23))).join(s.projectPath,".alchemy_lab","opencode.json")
590
614
  let a
591
615
  try{a="http://127.0.0.1:"+JSON.parse(n.readFileSync(i,"utf-8")).port}catch{return{success:!1,message:"Cannot read OpenCode config",error:"no_opencode"}}try{const e=await fetch(`${a}/session/${r}/prompt_async`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({parts:[{type:"text",text:o}]}),signal:AbortSignal.timeout(1e4)})
592
- return e.ok?{success:!0,message:"Prompt injected into session "+r}:{success:!1,message:"prompt_async failed: "+e.status,error:"prompt_failed"}}catch(e){return{success:!1,message:(0,d.getErrorMessage)(e),error:"prompt_error"}}}}},5700(e,exports,t){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
616
+ return e.ok?{success:!0,message:"Prompt injected into session "+r}:{success:!1,message:"prompt_async failed: "+e.status,error:"prompt_failed"}}catch(e){return{success:!1,message:(0,d.getErrorMessage)(e),error:"prompt_error"}}}}},5700(e,exports,t){"use strict"
617
+ var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
593
618
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRestartMcpAction=async function(e,t){const{logger:s,projectPath:n}=t,i=e.reason||"Manual restart requested"
594
619
  s.info("Executing restart-mcp action",{reason:i})
595
620
  try{const e=function(e){return o.default.join(e,".alchemy_lab","mcp-restart-trigger")}(n),t=o.default.dirname(e)
@@ -597,8 +622,10 @@ await r.default.mkdir(t,{recursive:!0})
597
622
  const a=JSON.stringify({timestamp:(new Date).toISOString(),reason:i},null,2)
598
623
  return await r.default.writeFile(e,a,"utf-8"),s.info("MCP restart triggered",{triggerPath:e,reason:i}),{success:!0,message:"MCP restart triggered: "+i,data:{triggerPath:e}}}catch(e){const t=e instanceof Error?e.message:e+""
599
624
  return s.error("Failed to trigger MCP restart",{error:t}),{success:!1,message:"Failed to trigger MCP restart: "+t,error:t}}}
600
- const r=s(t(1943)),o=s(t(6928))},6540(e,exports){var t
601
- 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){function s(e,process,t,s,r=!1){const o=process.config||{},n=(o.setup,o.commands||[])
625
+ const r=s(t(1943)),o=s(t(6928))},6540(e,exports){"use strict"
626
+ var t
627
+ 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"
628
+ function s(e,process,t,s,r=!1){const o=process.config||{},n=(o.setup,o.commands||[])
602
629
  let i=`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: ${s}\n\n## Test Commands\nExecute these in order:\n`
603
630
  for(let e=0;e<n.length;e++){const t=n[e]
604
631
  i+=`\n### ${e+1}. ${t.name}${!1!==t.required?" (REQUIRED)":" (optional)"}\n- **Command:** \`${t.command}\`\n- **Timeout:** ${t.timeout||300}s\n`}if(i+=r?`\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.`,o.verifyAcceptanceCriteria&&e.acceptanceCriteria?.length>0){i+="\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"
@@ -632,7 +659,8 @@ if(!e.success)throw Error(e.error||"Spawn failed")
632
659
  P.push(t.id),e.sessionId&&y.patch(`/api/projects/${v}/test-runs/${t.id}`,{testerSessionId:e.sessionId}).catch((e=>m.warn("Failed to set testerSessionId on test run",{error:(0,i.getErrorMessage)(e)}))),m.info("Spawned test-runner agent",{testRunId:t.id,processName:process.name,worktreePath:b,pid:e.pid,sessionId:e.sessionId})}catch(e){m.error("Failed to spawn test-runner agent",{testRunId:t.id,error:(0,i.getErrorMessage)(e)})
633
660
  try{await y.patch(`/api/projects/${v}/test-runs/${t.id}`,{status:"error",results:{steps:[],summary:"Failed to spawn test agent: "+(0,i.getErrorMessage)(e)}})}catch{}}}return 0===P.length?{success:!1,message:"Failed to spawn any test agents",error:"All agent spawns failed"}:{success:!0,message:`Started ${P.length} test run(s) for request ${u}`,data:{testRunIds:T,agentsSpawned:P.length,processCount:S.length,worktreePath:b}}}catch(e){const t=(0,i.getErrorMessage)(e)
634
661
  return m.error("run-tests action failed",{requestId:u,error:t}),{success:!1,message:"Failed to run tests: "+t,error:t}}}
635
- const r=t(9896),o=t(6928),n=t(3807),i=t(8824),a=t(8148),c=".alchemy_lab",l="test-worktrees"},6636(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRevertRequestAction=async function(e,t){const{requestId:o,reason:n}=e,{logger:i,apiClient:a,projectPath:c,projectId:l}=t
662
+ const r=t(9896),o=t(6928),n=t(3807),i=t(8824),a=t(8148),c=".alchemy_lab",l="test-worktrees"},6636(e,exports,t){"use strict"
663
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRevertRequestAction=async function(e,t){const{requestId:o,reason:n}=e,{logger:i,apiClient:a,projectPath:c,projectId:l}=t
636
664
  if(!o)return{success:!1,message:"requestId is required",error:"Missing requestId in payload"}
637
665
  if(!n)return{success:!1,message:"reason is required",error:"Missing reason in payload"}
638
666
  i.info("Starting revert_request action",{requestId:o,reason:n})
@@ -657,17 +685,25 @@ i.error("Git revert failed",{requestId:o,error:t})
657
685
  try{await u.raw(["revert","--abort"])}catch(e){i.error("CRITICAL: git revert --abort failed \u2014 repo may be in inconsistent state",{requestId:o,error:e instanceof Error?e.message:e+""})}return{success:!1,message:"Git revert failed: "+t,error:t}}const f=await a.post(`/api/projects/${l}/requests/${o}/finalize-revert`,{reason:n,operationType:"revert",revertCommitHash:p,originalMergeCommitHash:d})
658
686
  return f.success?{success:!0,message:"Successfully reverted request "+o,data:{operationType:"revert",originalMergeCommit:d,revertCommitHash:p,reason:n}}:(i.error("CRITICAL: Git revert succeeded but finalization failed",{requestId:o,revertCommitHash:p,error:f.error}),{success:!1,message:`CRITICAL: Git revert succeeded (commit: ${p.substring(0,8)}) but server finalization failed`,error:"Finalization failed"})}catch(e){const t=(0,r.getErrorMessage)(e)
659
687
  return i.error("Revert_request action failed",{requestId:o,error:t}),{success:!1,message:"Failed to revert request: "+t,error:t}}}
660
- const s=t(3807),r=t(8824)},6800(e,exports,t){function s(e){return new Promise((t=>{const s=o.default.createServer()
688
+ const s=t(3807),r=t(8824)},6800(e,exports,t){"use strict"
689
+ function s(e){return new Promise((t=>{const s=o.default.createServer()
661
690
  s.once("error",(e=>{e.code,t(!1)})),s.once("listening",(()=>{s.close((()=>{t(!0)}))})),s.listen(e)}))}var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
662
691
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.isPortAvailable=s,exports.findAvailablePort=async function(e,t=10){for(let r=0;t>r;r++){const t=e+r
663
692
  if(await s(t))return t}throw Error(`No available port found after ${t} attempts starting from port ${e}`)}
664
- const o=r(t(9278))},6895(module){module.exports=require("chalk")},6928(module){module.exports=require("path")},6982(module){module.exports=require("crypto")},7163(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.debugTokenAccess=function(){},exports.compareTokens=function(){},exports.debugTokenStorage=function(){},exports.disableTokenDebugging=function(){},exports.enableTokenDebugging=function(){},new WeakMap},7210(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.tryMarkMessageProcessed=exports.createToolCallHash=exports.isDuplicateToolCall=exports.determineEventToEmit=exports.interpolatePrompt=exports.evaluateCondition=exports.HookCache=exports.HookExecutor=void 0
693
+ const o=r(t(9278))},6895(module){"use strict"
694
+ module.exports=require("chalk")},6928(module){"use strict"
695
+ module.exports=require("path")},6982(module){"use strict"
696
+ module.exports=require("crypto")},7163(e,exports){"use strict"
697
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.debugTokenAccess=function(){},exports.compareTokens=function(){},exports.debugTokenStorage=function(){},exports.disableTokenDebugging=function(){},exports.enableTokenDebugging=function(){},new WeakMap},7210(e,exports,t){"use strict"
698
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.tryMarkMessageProcessed=exports.createToolCallHash=exports.isDuplicateToolCall=exports.determineEventToEmit=exports.interpolatePrompt=exports.evaluateCondition=exports.HookCache=exports.HookExecutor=void 0
665
699
  var s=t(3077)
666
700
  Object.defineProperty(exports,"HookExecutor",{enumerable:!0,get(){return s.HookExecutor}})
667
701
  var r=t(8740)
668
702
  Object.defineProperty(exports,"HookCache",{enumerable:!0,get(){return r.HookCache}})
669
703
  var o=t(4627)
670
- Object.defineProperty(exports,"evaluateCondition",{enumerable:!0,get(){return o.evaluateCondition}}),Object.defineProperty(exports,"interpolatePrompt",{enumerable:!0,get(){return o.interpolatePrompt}}),Object.defineProperty(exports,"determineEventToEmit",{enumerable:!0,get(){return o.determineEventToEmit}}),Object.defineProperty(exports,"isDuplicateToolCall",{enumerable:!0,get(){return o.isDuplicateToolCall}}),Object.defineProperty(exports,"createToolCallHash",{enumerable:!0,get(){return o.createToolCallHash}}),Object.defineProperty(exports,"tryMarkMessageProcessed",{enumerable:!0,get(){return o.tryMarkMessageProcessed}})},7252(module){module.exports=require("express")},7453(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequestAction=async function(e,t){const{requestId:o,reason:n}=e,{logger:i,apiClient:a,projectPath:c,projectId:l}=t
704
+ Object.defineProperty(exports,"evaluateCondition",{enumerable:!0,get(){return o.evaluateCondition}}),Object.defineProperty(exports,"interpolatePrompt",{enumerable:!0,get(){return o.interpolatePrompt}}),Object.defineProperty(exports,"determineEventToEmit",{enumerable:!0,get(){return o.determineEventToEmit}}),Object.defineProperty(exports,"isDuplicateToolCall",{enumerable:!0,get(){return o.isDuplicateToolCall}}),Object.defineProperty(exports,"createToolCallHash",{enumerable:!0,get(){return o.createToolCallHash}}),Object.defineProperty(exports,"tryMarkMessageProcessed",{enumerable:!0,get(){return o.tryMarkMessageProcessed}})},7252(module){"use strict"
705
+ module.exports=require("express")},7453(e,exports,t){"use strict"
706
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequestAction=async function(e,t){const{requestId:o,reason:n}=e,{logger:i,apiClient:a,projectPath:c,projectId:l}=t
671
707
  if(!o)return{success:!1,message:"requestId is required",error:"Missing requestId in payload"}
672
708
  i.info("Starting complete_request action",{requestId:o,reason:n})
673
709
  try{const e=await a.post(`/api/projects/${l}/requests/${o}/validate-completion`,{})
@@ -690,7 +726,8 @@ return n.error("Revert removal failed",{requestId:e,error:s}),{success:!1,messag
690
726
  if(!d.success)return d
691
727
  try{await a.post(`/api/projects/${l}/requests/${o}/finalize-completion`,{summary:n||"Re-completed from UI",acceptanceEvidence:[{evidence:"Re-completed reverted request via GUI action"}],mergeResult:{mergeCommitHash:d.data.restoredToCommit,method:"revert-removal"}})}catch(e){return i.error("Merge succeeded but finalization failed",{requestId:o,error:(0,r.getErrorMessage)(e)}),{success:!1,message:"Git revert removal succeeded but server finalization failed: "+(0,r.getErrorMessage)(e),error:"Finalization failed"}}return d}catch(e){const t=(0,r.getErrorMessage)(e)
692
728
  return i.error("Complete_request action failed",{requestId:o,error:t}),{success:!1,message:"Failed to complete request: "+t,error:t}}}
693
- const s=t(3807),r=t(8824)},7767(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleApproveAndWorkRequestAction=async function(e,t){const{requestId:o}=e,{logger:n,apiClient:i,projectId:a,projectPath:c,trackChildPid:l}=t
729
+ const s=t(3807),r=t(8824)},7767(e,exports,t){"use strict"
730
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleApproveAndWorkRequestAction=async function(e,t){const{requestId:o}=e,{logger:n,apiClient:i,projectId:a,projectPath:c,trackChildPid:l}=t
694
731
  if(!o)return{success:!1,message:"requestId is required",error:"Missing requestId in payload"}
695
732
  n.info("Starting approve-and-work-request action",{requestId:o})
696
733
  try{const e=await i.get(`/api/projects/${a}/requests/${o}`)
@@ -706,11 +743,13 @@ if(e){const s=`\u2705 [Request Approved]\n\nRequest ${o} "${t.title}" has been a
706
743
  i.ok?n.info("Pushed notification to CLI session",{sessionId:t.cliOrigin.sessionId}):n.warn("Failed to push notification to CLI session",{status:i.status})}}catch(e){n.warn("Could not push notification to CLI session (may be offline)",{error:(0,s.getErrorMessage)(e)})}}catch(e){n.warn("Failed to notify creating session, spawning work agent instead",{requestId:o,error:(0,s.getErrorMessage)(e)})}if(!h)try{const e=await(0,r.spawnActionAgent)({agent:"work",prompt:u,cwd:c,projectPath:c,projectId:a,title:`[${o}] ${t.title}`,requestId:o,apiClient:i,logger:n,trackChildPid:l})
707
744
  g=e.success,g?n.info("Spawned work agent for request",{requestId:o,sessionId:e.sessionId}):n.warn("Failed to spawn work agent",{requestId:o,error:e.error})}catch(e){n.warn("Failed to spawn work agent",{requestId:o,error:(0,s.getErrorMessage)(e)})}return n.info("Approve-and-work-request action completed",{requestId:o,notifiedSession:h,agentSpawned:g}),{success:!0,message:`Successfully approved request ${o}: ${t.title}${h?" \u2014 creating session notified":g?" \u2014 work agent spawned":""}`,data:{operationType:"approve-and-work",previousStatus:"pending_approval",newStatus:"open",notifiedSession:h,agentSpawned:g}}}catch(e){const t=(0,s.getErrorMessage)(e)
708
745
  return n.error("approve-and-work-request action failed",{requestId:o,error:t}),{success:!1,message:"Failed to approve request: "+t,error:t}}}
709
- const s=t(8824),r=t(8148)},7960(e,exports){function t(){const e=process.argv[1]||""
746
+ const s=t(8824),r=t(8148)},7960(e,exports){"use strict"
747
+ function t(){const e=process.argv[1]||""
710
748
  if(e.includes("/dist-dev/")||e.includes("\\dist-dev\\"))return!0
711
749
  if(e.includes("/dist/")||e.includes("\\dist\\"))return!1
712
750
  const t=process.cwd()
713
- return!(!t.includes("/dist-dev")&&!t.includes("\\dist-dev"))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.isDevBuild=t,exports.getBuildMode=function(){return t()?"development":"production"},exports.enableDebugMode=function(){return"true"===process.env.ENABLE_DEBUG_TOOLS&&(process.env.DEBUG_LOGGING="true",!0)}},8035(e,exports,t){function s(e,t,s){try{const r=`[${(new Date).toISOString()}] [detached-subagent] ${t}${s?" "+JSON.stringify(s):""}\n`,o=(0,a.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,i.appendFileSync)(o,r)}catch{}}function r(e){const{agent:t,prompt:r,cwd:l,parentServerUrl:d,parentSessionId:u,sessionId:h,model:g,initialBranch:p,serverUrl:f,onSpawn:m,onError:y}=e
751
+ return!(!t.includes("/dist-dev")&&!t.includes("\\dist-dev"))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.isDevBuild=t,exports.getBuildMode=function(){return t()?"development":"production"},exports.enableDebugMode=function(){return"true"===process.env.ENABLE_DEBUG_TOOLS&&(process.env.DEBUG_LOGGING="true",!0)}},8035(e,exports,t){"use strict"
752
+ function s(e,t,s){try{const r=`[${(new Date).toISOString()}] [detached-subagent] ${t}${s?" "+JSON.stringify(s):""}\n`,o=(0,a.join)(e||process.cwd(),".alchemy_lab","spawn-debug.log");(0,i.appendFileSync)(o,r)}catch{}}function r(e){const{agent:t,prompt:r,cwd:l,parentServerUrl:d,parentSessionId:u,sessionId:h,model:g,initialBranch:p,serverUrl:f,onSpawn:m,onError:y}=e
714
753
  try{const n={...process.env}
715
754
  d&&(n.OPENCODE_PARENT_SERVER=d),p&&(n.ALCHEMY_INITIAL_BRANCH=p),e.allowParallel&&(n.ALCHEMY_ALLOW_PARALLEL="1")
716
755
  const u=new Date,y=`${(u.getHours()+"").padStart(2,"0")}${(u.getMinutes()+"").padStart(2,"0")}${(u.getSeconds()+"").padStart(2,"0")}`,v=Math.random().toString(36).substring(2,7)
@@ -722,7 +761,8 @@ let S
722
761
  try{S=(0,i.openSync)(k,"a")}catch{}const I=(0,c.resolveRunCommand)(),b=(0,o.spawn)(I.command,[...I.prependArgs,...w],{detached:!0,stdio:["ignore","ignore",S??"ignore"],cwd:l||process.cwd(),env:n})
723
762
  return b.unref(),m&&m(b.pid),{success:!0,pid:b.pid}}catch(e){const t=(0,n.getErrorMessage)(e)
724
763
  return y&&e instanceof Error&&y(e),{success:!1,error:t}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.spawnDetachedSubagent=r,exports.spawnJournalSubagent=function(e,t,s,o){return r({agent:"journal",prompt:`Generate a journal entry for request ${e}.\n\nSteps:\n1. Use ${t}__generate_request_journal tool with requestId: ${e}\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-${e}.md using ${t}__document_operations (operation: create, type: Report)\n\nKeep it story-focused and informative.`,cwd:s,parentServerUrl:o})},exports.spawnWorkSubagent=function(e,t,s){return r({agent:"work",prompt:e,cwd:t,parentServerUrl:s})}
725
- const o=t(5317),n=t(8824),i=t(9896),a=t(6928),c=t(9068)},8148(e,exports,t){function s(e,t){try{const t=(0,o.join)(e,c,"opencode.json"),s=(0,r.readFileSync)(t,"utf8"),n=JSON.parse(s)
764
+ const o=t(5317),n=t(8824),i=t(9896),a=t(6928),c=t(9068)},8148(e,exports,t){"use strict"
765
+ function s(e,t){try{const t=(0,o.join)(e,c,"opencode.json"),s=(0,r.readFileSync)(t,"utf8"),n=JSON.parse(s)
726
766
  if(n.port)return"http://127.0.0.1:"+n.port}catch(e){t.debug("Could not read opencode.json for server URL",{error:(0,a.getErrorMessage)(e)})}return null}Object.defineProperty(exports,"__esModule",{value:!0}),exports.getOpenCodeServerUrl=s,exports.spawnActionAgent=async function(e){const{agent:t,prompt:r,cwd:o,projectPath:c,title:l,requestId:d,parentSessionId:u,allowParallel:h,apiClient:g,logger:p,trackChildPid:f}=e,m=s(c,p)
727
767
  let y,v=null
728
768
  m?v=await async function(e,t,s,r,o,n,i,c){try{const l=await fetch(e+"/session",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:t,...o?{parentID:o}:{}})})
@@ -736,7 +776,8 @@ try{const e=await fetch("http://localhost:3456/api/project-settings")
736
776
  if(e.ok){const s=await e.json()
737
777
  s.data?.defaultModel&&(y=s.data.defaultModel,p.info("Using user default model for agent spawn",{agent:t,model:y}))}}catch{}if(d)try{await(0,i.ensureRequestWorktree)(c,d,p)}catch(e){p.warn("Pre-spawn worktree creation failed (non-fatal)",{requestId:d,error:(0,a.getErrorMessage)(e)})}const w=(0,n.spawnDetachedSubagent)({agent:t,prompt:r,cwd:o,sessionId:v||void 0,serverUrl:m||void 0,model:y,allowParallel:h??!1,onSpawn(e){e&&f&&f(e)}})
738
778
  return w.success?(p.info("Spawned action agent",{agent:t,sessionId:v,pid:w.pid,requestId:d}),{success:!0,sessionId:v,pid:w.pid}):{success:!1,sessionId:v,error:w.error||"Spawn failed"}}
739
- const r=t(9896),o=t(6928),n=t(8035),i=t(2424),a=t(8824),c=".alchemy_lab"},8524(e,exports,t){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
779
+ const r=t(9896),o=t(6928),n=t(8035),i=t(2424),a=t(8824),c=".alchemy_lab"},8524(e,exports,t){"use strict"
780
+ var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
740
781
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.CLIBridgeWebSocket=void 0,exports.setCLIBridge=function(e){n=e},exports.getCLIBridge=function(){return n}
741
782
  const r=t(5086),o=s(t(6982))
742
783
  exports.CLIBridgeWebSocket=class{constructor(e,t=3e4){this.wss=null,this.uiClient=null,this.pendingCommands=new Map,this.heartbeatInterval=null,this.logger=e,this.defaultTimeout=t}attach(e){this.wss=new r.WebSocketServer({server:e,path:"/ws/cli-bridge"}),this.wss.on("connection",(e=>{this.logger.info("[CLIBridge] UI client connected"),this.uiClient&&(this.logger.warn("[CLIBridge] Replacing existing UI client connection"),this.uiClient.close(1e3,"Replaced by new connection")),this.uiClient=e,this.startHeartbeat(),e.on("message",(e=>{try{const t=JSON.parse(e.toString())
@@ -749,10 +790,14 @@ try{this.uiClient.send(JSON.stringify(n))}catch(e){clearTimeout(i),this.pendingC
749
790
  t?(clearTimeout(t.timer),this.pendingCommands.delete(e.id),t.resolve(e)):this.logger.warn("[CLIBridge] Received response for unknown command",{id:e.id})}startHeartbeat(){this.stopHeartbeat(),this.heartbeatInterval=setInterval((()=>{this.uiClient&&this.uiClient.readyState===r.WebSocket.OPEN&&this.uiClient.ping()}),3e4)}stopHeartbeat(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null)}close(){this.stopHeartbeat()
750
791
  for(const[e,t]of this.pendingCommands)clearTimeout(t.timer),t.reject(Error("Bridge shutting down")),this.pendingCommands.delete(e)
751
792
  this.uiClient&&(this.uiClient.close(1e3,"Server shutting down"),this.uiClient=null),this.wss&&(this.wss.close(),this.wss=null)}}
752
- let n=null},8577(module){module.exports=require("cors")},8740(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.HookCache=void 0,exports.HookCache=class{constructor(e,t,s){this.cache=new Map,this.logger=e,this.projectId=t,this.apiClient=s}setProjectId(e){this.projectId=e}getCacheKey(e,t){return t?`${e}:session:${t}`:e+":all"}async getHooksForEvent(e,t,s){const r=this.getCacheKey(e,t)
793
+ let n=null},8577(module){"use strict"
794
+ module.exports=require("cors")},8740(e,exports){"use strict"
795
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.HookCache=void 0,exports.HookCache=class{constructor(e,t,s){this.cache=new Map,this.logger=e,this.projectId=t,this.apiClient=s}setProjectId(e){this.projectId=e}getCacheKey(e,t){return t?`${e}:session:${t}`:e+":all"}async getHooksForEvent(e,t,s){const r=this.getCacheKey(e,t)
753
796
  if(!s){const e=this.cache.get(r)
754
797
  if(e&&6e4>Date.now()-e.time)return e.hooks.filter((e=>e.enabled))}try{const s=t?"?sessionId="+encodeURIComponent(t):"",o=await this.apiClient.get(`/api/projects/${this.projectId}/event-hooks/by-event/${e}${s}`),n=(o?.data||o||[]).map((e=>({id:e.id||e.hookId,name:e.name||e.hookName,eventType:e.eventType||e.hookEventType,agent:e.agent||e.hookAgent,promptTemplate:e.promptTemplate||e.hookPromptTemplate,condition:e.condition||e.hookCondition||{},enabled:!1!==e.enabled,action:e.action||e.hookAction||void 0,target:e.target||e.hookTarget||void 0,timing:e.timing||e.hookTiming||"after",maxIterations:e.maxIterations||e.hookMaxIterations||void 0,emitEvent:e.emitEvent||e.hookEmitEvent||void 0,emitEventOnCondition:e.emitEventOnCondition||e.hookEmitEventOnCondition||void 0})))
755
- return this.cache.set(r,{hooks:n,time:Date.now()}),n.filter((e=>e.enabled))}catch(t){return this.logger.warn("Failed to fetch hooks",{eventType:e,error:t+""}),[]}}preWarm(e,t){this.getHooksForEvent(e,t).catch((()=>{}))}clear(){this.cache.clear()}}},8824(e,exports){Object.defineProperty(exports,"__esModule",{value:!0}),exports.getErrorMessage=function(e){return e instanceof Error?e.message:"string"==typeof e?e:null===e?"null error":void 0===e?"undefined error":e+""},exports.getErrorStack=function(e){return e instanceof Error?e.stack||e.message:e+""},exports.formatErrorForLog=function(e){return e instanceof Error?{message:e.message,stack:e.stack}:{message:e+""}},exports.isError=function(e){return e instanceof Error}},8984(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.MCPClientConfigurer=void 0
798
+ return this.cache.set(r,{hooks:n,time:Date.now()}),n.filter((e=>e.enabled))}catch(t){return this.logger.warn("Failed to fetch hooks",{eventType:e,error:t+""}),[]}}preWarm(e,t){this.getHooksForEvent(e,t).catch((()=>{}))}clear(){this.cache.clear()}}},8824(e,exports){"use strict"
799
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.getErrorMessage=function(e){return e instanceof Error?e.message:"string"==typeof e?e:null===e?"null error":void 0===e?"undefined error":e+""},exports.getErrorStack=function(e){return e instanceof Error?e.stack||e.message:e+""},exports.formatErrorForLog=function(e){return e instanceof Error?{message:e.message,stack:e.stack}:{message:e+""}},exports.isError=function(e){return e instanceof Error}},8984(e,exports,t){"use strict"
800
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.MCPClientConfigurer=void 0
756
801
  const s=t(8824)
757
802
  class r{constructor(e,t,s){this.logger=e,this.remoteServerUrl=t||process.env.REMOTE_SERVER_URL,this.authToken=s}async seedAgentsFromRemote(e){const t=this.remoteServerUrl
758
803
  if(!t)return this.logger.debug("No REMOTE_SERVER_URL set, cannot initialize agents"),!1
@@ -824,7 +869,8 @@ try{n=JSON.parse(await s.readFile(o,"utf-8"))}catch{}const i=(n.plugin||[]).filt
824
869
  n.plugin=[...i,...A],n.$schema=n.$schema||"https://opencode.ai/config.json",await s.writeFile(o,JSON.stringify(n,null,2),"utf8"),this.logger.info("Updated global alchemy opencode config",{globalConfigPath:o,plugins:n.plugin})}catch(e){this.logger.warn("Failed to write global alchemy opencode config",{error:e instanceof Error?e.message:"Unknown error"})}if(v&&!i)try{let e={}
825
870
  try{const t=await s.readFile(w,"utf-8")
826
871
  e=JSON.parse(t)}catch{}e.openCodeTools||(e.openCodeTools=C,await s.writeFile(w,JSON.stringify(e,null,2),"utf8"),this.logger.info("Created project config with default tool settings",{projectConfigPath:w}))}catch(e){this.logger.warn("Failed to create project config",{error:e instanceof Error?e.message:"Unknown error"})}try{const{syncPlugins:s}=await t.e(939).then(t.t.bind(t,9939,23)),r=await s(o,l??!1,this.logger,e)
827
- r.synced.length>0&&this.logger.info("Synced plugins during OpenCode config",{synced:r.synced}),r.errors.length>0&&this.logger.warn("Some plugins failed to sync",{errors:r.errors})}catch(e){this.logger.warn("Plugin sync failed during OpenCode config",{error:e instanceof Error?e.message:"Unknown error"})}return{success:!0,configPath:h}}catch(e){return this.logger.error("Failed to configure OpenCode",{error:(0,s.getErrorMessage)(e)}),{success:!1,error:(0,s.getErrorMessage)(e)}}}}exports.MCPClientConfigurer=r,r.OPENCODE_BUILTIN_TOOLS=new Set(["glob","grep","ls","list","view","read","write","edit","patch","diagnostics","sourcegraph","bash","fetch","agent","task","question","todoread","todowrite"])},9067(e,exports,t){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
872
+ r.synced.length>0&&this.logger.info("Synced plugins during OpenCode config",{synced:r.synced}),r.errors.length>0&&this.logger.warn("Some plugins failed to sync",{errors:r.errors})}catch(e){this.logger.warn("Plugin sync failed during OpenCode config",{error:e instanceof Error?e.message:"Unknown error"})}return{success:!0,configPath:h}}catch(e){return this.logger.error("Failed to configure OpenCode",{error:(0,s.getErrorMessage)(e)}),{success:!1,error:(0,s.getErrorMessage)(e)}}}}exports.MCPClientConfigurer=r,r.OPENCODE_BUILTIN_TOOLS=new Set(["glob","grep","ls","list","view","read","write","edit","patch","diagnostics","sourcegraph","bash","fetch","agent","task","question","todoread","todowrite"])},9067(e,exports,t){"use strict"
873
+ var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
828
874
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.ExternalAuthFlow=exports.PollingStatus=void 0
829
875
  const r=s(t(6982)),o=t(8824)
830
876
  var n
@@ -870,14 +916,15 @@ if(!o.ok)return void this.logger.debug("Polling response not ok",{status:o.statu
870
916
  const i=await o.json()
871
917
  if(this.logger.debug("Google OAuth polling response",{data:i}),i.success&&i.data&&i.data.authenticated&&i.data.token){this.logger.info("Google OAuth authentication completed")
872
918
  const e=this.parseTokenResponse(i.data)
873
- e&&(this.pollingStatus=n.AUTHENTICATED,this.tokenResult=e,this.stopPolling(),s&&s(e))}else this.logger.debug("Not authenticated yet, continuing to poll",{hasSuccess:!!i.success,hasData:!!i.data,authenticated:i.data?.authenticated})}catch(e){this.logger.error("Error during Google OAuth polling",{error:(0,o.getErrorMessage)(e)}),this.pollingStatus=n.ERROR,this.pollingError=(0,o.getErrorMessage)(e),this.stopPolling(),i&&i(this.pollingError)}}),this.pollingIntervalMs),{authUrl:e,state:t}}}},9068(e,exports,t){function s(){const e=process.env.ALCHEMY_OPENCODE_DIR
919
+ e&&(this.pollingStatus=n.AUTHENTICATED,this.tokenResult=e,this.stopPolling(),s&&s(e))}else this.logger.debug("Not authenticated yet, continuing to poll",{hasSuccess:!!i.success,hasData:!!i.data,authenticated:i.data?.authenticated})}catch(e){this.logger.error("Error during Google OAuth polling",{error:(0,o.getErrorMessage)(e)}),this.pollingStatus=n.ERROR,this.pollingError=(0,o.getErrorMessage)(e),this.stopPolling(),i&&i(this.pollingError)}}),this.pollingIntervalMs),{authUrl:e,state:t}}}},9068(e,exports,t){"use strict"
920
+ function s(){const e=process.env.ALCHEMY_OPENCODE_DIR
874
921
  if(e)return e
875
- try{const e=Object(function(){var e=Error("Cannot find module 'alchemylab-opencode/package.json'")
876
- throw e.code="MODULE_NOT_FOUND",e}())
922
+ try{const e=("undefined"!=typeof require?require:t(4245)).resolve("alchemylab-opencode/package.json")
877
923
  return(0,o.dirname)(e)}catch{}}function r(e,t){return{command:"node",prependArgs:["--experimental-strip-types","--experimental-transform-types","--no-warnings","--import",(0,o.join)(e,"node-preload.mjs"),(0,o.join)(e,t)]}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.resolveServeCommand=function(){const e=s()
878
924
  return e?r((0,o.join)(e,"packages","opencode","src"),"serve.ts"):{command:"opencode",prependArgs:["serve"]}},exports.resolveRunCommand=function(){const e=s()
879
925
  return e?r((0,o.join)(e,"packages","opencode","src"),"run.ts"):{command:"opencode",prependArgs:[]}}
880
- const o=t(6928)},9266(e,exports,t){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
926
+ const o=t(6928)},9266(e,exports,t){"use strict"
927
+ var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
881
928
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleOpenCodeProxyAction=async function(e,t){const{method:s,path:i,body:a,headers:c}=e
882
929
  if(!s||!i)return{success:!1,message:"method and path are required in proxy payload"}
883
930
  const l=function(e){const t=r.default.join(e,".alchemy_lab","opencode.json")
@@ -892,7 +939,9 @@ e=s}r.body="string"==typeof e?e:JSON.stringify(e)}const o=await fetch(d,r),l=o.h
892
939
  let u
893
940
  if(u=l.includes("application/json")?await o.json():await o.text(),"POST"===s.toUpperCase()&&"/session"===i&&o.status>=200&&300>o.status&&u?.id)try{const e=u.id,s=a?.parentID
894
941
  await t.apiClient.post(`/api/projects/${t.projectId}/cli-sessions`,{externalSessionId:e,providerId:"opencode",...s?{parentExternalSessionId:s}:{},agentType:a?._alchemyAgentType||"unknown",status:"active"}),t.logger.info("Registered proxy-created session in DB",{sessionId:e,parentSessionId:s})}catch(e){t.logger.warn("Failed to register proxy-created session",{error:(0,n.getErrorMessage)(e)})}return{success:!0,message:"Proxy request completed",data:{status:o.status,contentType:l,body:u}}}catch(e){return{success:!1,message:"Proxy request failed: "+(0,n.getErrorMessage)(e),error:(0,n.getErrorMessage)(e)}}}
895
- const r=s(t(6928)),o=s(t(9896)),n=t(8824)},9278(module){module.exports=require("net")},9735(e,exports,t){Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleApproveRequestAction=async function(e,t){const{requestId:r}=e,{logger:o,apiClient:n,projectId:i}=t
942
+ const r=s(t(6928)),o=s(t(9896)),n=t(8824)},9278(module){"use strict"
943
+ module.exports=require("net")},9735(e,exports,t){"use strict"
944
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleApproveRequestAction=async function(e,t){const{requestId:r}=e,{logger:o,apiClient:n,projectId:i}=t
896
945
  if(!r)return{success:!1,message:"requestId is required",error:"Missing requestId in payload"}
897
946
  o.info("Starting approve-request action",{requestId:r})
898
947
  try{const e=await n.get(`/api/projects/${i}/requests/${r}`)
@@ -900,7 +949,8 @@ if(!e.success||!e.data)return{success:!1,message:`Request ${r} not found`,error:
900
949
  const t=e.data
901
950
  return"pending_approval"!==t.status?{success:!1,message:`Cannot approve request with status '${t.status}'. Only requests in 'pending_approval' status can be approved.`,error:"Invalid status: "+t.status}:(await n.patch(`/api/projects/${i}/requests/${r}`,{status:"open"})).success?(o.info("Approve-request action completed",{requestId:r}),{success:!0,message:`Successfully approved request ${r}: ${t.title}`,data:{operationType:"approve",previousStatus:"pending_approval",newStatus:"open"}}):{success:!1,message:"Failed to update request status",error:"Update failed"}}catch(e){const t=(0,s.getErrorMessage)(e)
902
951
  return o.error("approve-request action failed",{requestId:r,error:t}),{success:!1,message:"Failed to approve request: "+t,error:t}}}
903
- const s=t(8824)},9896(module){module.exports=require("fs")}},n={}
952
+ const s=t(8824)},9896(module){"use strict"
953
+ module.exports=require("fs")}},n={}
904
954
  e.m=o,s=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,e.t=function(r,o){if(1&o&&(r=this(r)),8&o)return r
905
955
  if("object"==typeof r&&r){if(4&o&&r.__esModule)return r
906
956
  if(16&o&&"function"==typeof r.then)return r}var n=Object.create(null)
@@ -912,7 +962,8 @@ return i.default=()=>r,e.d(n,i),n},e.d=(exports,t)=>{for(var s in t)e.o(t,s)&&!e
912
962
  for(var i in s)e.o(s,i)&&(e.m[i]=s[i])
913
963
  n&&n(e)
914
964
  for(var a=0;a<o.length;a++)r[o[a]]=1})(require("./"+e.u(t)))}
915
- var i={};(()=>{function t(){const e=[(0,h.join)(__dirname,"..","package.json"),(0,h.join)(__dirname,"..","..","package.json")]
965
+ var i={};(()=>{"use strict"
966
+ function t(){const e=[(0,h.join)(__dirname,"..","package.json"),(0,h.join)(__dirname,"..","..","package.json")]
916
967
  for(const t of e)try{const e=JSON.parse((0,d.readFileSync)(t,"utf-8"))
917
968
  if(e.version)return e.version}catch{}return"unknown"}function s(){const e=t()
918
969
  console.log(`\nAlchemyLab CLI v${e}\n\nUSAGE:\n alchemy [command] [options]\n\nCOMMANDS:\n (none) Start action server + launch OpenCode (default)\n serve Start the action server only (for GUI-triggered actions)\n logout Log out and remove stored auth token\n\nOPTIONS:\n --port <n> Action server port (default: auto)\n --help, -h Show this help message\n --version, -v Show version information\n\nEXAMPLES:\n alchemy # Start server + OpenCode (default)\n alchemy serve # Start action server only\n alchemy logout # Log out\nFor more information, visit: https://alchemylabcode.com/\n`)}function r(e){const t=(0,h.join)(e,S.ALCHEMY_DIR_NAME,"project.json")
@@ -957,9 +1008,9 @@ const r=(0,h.join)(process.env.HOME||"/usr/local/bin",".local","bin")
957
1008
  await(0,u.mkdir)(r,{recursive:!0})
958
1009
  const o=(0,h.join)(r,"opencode")
959
1010
  return(0,g.execFileSync)("curl",["-fsSL","-o",o,t],{stdio:"inherit",timeout:6e4}),(0,g.execFileSync)("chmod",["+x",o],{stdio:"pipe"}),(process.env.PATH||"").split(":").includes(r)||(console.log(` \u26a0\ufe0f Add ${r} to your PATH:`),console.log(` export PATH="${r}:$PATH"`),console.log(""),process.env.PATH=`${r}:${process.env.PATH}`),void console.log("\u2705 OpenCode installed successfully")}}catch(e){console.log("\u26a0\ufe0f Binary download failed: "+(0,C.getErrorMessage)(e))}console.log(""),console.log("\u26a0\ufe0f Could not auto-install OpenCode."),console.log(""),console.log(" Install manually:"),console.log(" go install github.com/sst/opencode@latest"),console.log(" Or download from:"),console.log(" https://github.com/sst/opencode/releases"),console.log("")}(i)
960
- const O=t()
961
- console.log(["\n .oo 8 8 o 8 \n .P 8 8 8 8 8 \n .P 8 8 .oPYo. 8oPYo. .oPYo. ooYoYo. o o 8 .oPYo. 8oPYo. \n oPooo8 8 8 ' 8 8 8oooo8 8' 8 8 8 8 8 .oooo8 8 8 \n .P 8 8 8 . 8 8 8. 8 8 8 8 8 8 8 8 8 8 \n.P 8 8 `YooP' 8 8 `Yooo' 8 8 8 `YooP8 8oooo `YooP8 `YooP' \n..:::::....:.....:..:::..:.....:..:..:..:....8 ......:.....::.....:","::::::::::::::::::::::::::::::::::::::::::ooP'.::::::::::::::::::: v"+O,"::::::::::::::::::::::::::::::::::::::::::...::::::::::::::::::::::\n"].join("\n")),console.log("\u{1f4c1} Project: "+i)
962
- const _=s.port||await(0,k.findAvailablePort)(3456),x=new y.AlchemyActionServer(b,{projectPath:i,remoteServerUrl:E,port:_,authToken:P})
1011
+ const _=t()
1012
+ console.log(["\n .oo 8 8 o 8 \n .P 8 8 8 8 8 \n .P 8 8 .oPYo. 8oPYo. .oPYo. ooYoYo. o o 8 .oPYo. 8oPYo. \n oPooo8 8 8 ' 8 8 8oooo8 8' 8 8 8 8 8 .oooo8 8 8 \n .P 8 8 8 . 8 8 8. 8 8 8 8 8 8 8 8 8 8 \n.P 8 8 `YooP' 8 8 `Yooo' 8 8 8 `YooP8 8oooo `YooP8 `YooP' \n..:::::....:.....:..:::..:.....:..:..:..:....8 ......:.....::.....:","::::::::::::::::::::::::::::::::::::::::::ooP'.::::::::::::::::::: v"+_,"::::::::::::::::::::::::::::::::::::::::::...::::::::::::::::::::::\n"].join("\n")),console.log("\u{1f4c1} Project: "+i)
1013
+ const O=s.port||await(0,k.findAvailablePort)(3456),x=new y.AlchemyActionServer(b,{projectPath:i,remoteServerUrl:E,port:O,authToken:P})
963
1014
  try{await x.start()
964
1015
  let t=process.env.FRONTEND_URL
965
1016
  if(!t)if(E.includes("api.alchemylabcode.com"))t="https://alchemylabcode.com"