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 +94 -43
- package/dist/http-server.js +1263 -1014
- package/dist/index.js +1296 -1036
- package/dist/mcp-direct.js +1231 -994
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
(()=>{
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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)}}},
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
601
|
-
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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){
|
|
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=
|
|
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){
|
|
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){
|
|
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){
|
|
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={};(()=>{
|
|
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
|
|
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"+
|
|
962
|
-
const
|
|
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"
|