alchemylab 3.0.5 → 3.0.6
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 +153 -134
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -3801,10 +3801,11 @@ if(!r||r.startsWith("..")||M.default.isAbsolute(r)||".alchemy_lab"===r.split(M.d
|
|
|
3801
3801
|
const s=await te.note({sessionId:n,requestId:c.requestId,worktree:c.worktree,relPath:r.split(M.default.sep).join("/"),tool:i,..."read"===i&&e.lines?{readRange:e.lines}:{}},l)
|
|
3802
3802
|
s&&d.push(a.length>1?`${r}:\n${s}`:s)}t.json({success:!0,data:{note:d.length>0?d.join("\n\n"):null}})}catch(e){o.logger.debug("parallel-note failed (the tool result stays as it is)",{error:(0,P.getErrorMessage)(e)}),t.json({success:!0,data:{note:null}})}}),e.get("/api/sibling-overlap",async(e,t)=>{try{const r="string"==typeof e.query.requestId?e.query.requestId:void 0
|
|
3803
3803
|
if(!r||!/^req\d+$/.test(r))return void t.status(400).json({success:!1,error:"requestId required"})
|
|
3804
|
-
const s=o.getProjectId(),n=(0,L.simpleGit)(o.projectPath),i=(await n.raw(["for-each-ref","--format=%(refname:short)","refs/heads/requests/"])).split("\n").map(e=>e.trim().replace(/^requests\//,"")).filter(e=>/^req\d+$/.test(e)&&e!==r),a=new Set(["open","in_progress","ready_for_review","completing","resolving_conflicts"]),c=[]
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3804
|
+
const s=o.getProjectId(),n=(0,L.simpleGit)(o.projectPath),i=(await n.raw(["for-each-ref","--format=%(refname:short)","refs/heads/requests/"])).split("\n").map(e=>e.trim().replace(/^requests\//,"")).filter(e=>/^req\d+$/.test(e)&&e!==r),a=new Set(["open","in_progress","ready_for_review","completing","resolving_conflicts"]),c=new Set(i),l=[]
|
|
3805
|
+
if(s&&c.size>0){const e=await o.apiClient.get(`/api/projects/${s}/requests?inFlight=true&limit=100`),t=Array.isArray(e?.data)?e.data:[]
|
|
3806
|
+
for(const e of t){const t=String(e?.localId??"")
|
|
3807
|
+
c.has(t)&&a.has(String(e.status))&&l.push({id:t,title:String(e.title??""),status:String(e.status)})}}const d=await(0,Y.resolveDefaultBranch)(o.projectPath),u=await(0,_.siblingOverlap)({projectPath:o.projectPath,requestId:r,siblingIds:l.map(e=>e.id),defaultBranch:d,git:n}),h=new Map(l.map(e=>[e.id,e]))
|
|
3808
|
+
t.json({success:!0,data:u.map(e=>({...e,siblingTitle:h.get(e.sibling)?.title??"",siblingStatus:h.get(e.sibling)?.status??""}))})}catch(e){o.logger.debug("sibling-overlap lookup failed",{error:(0,P.getErrorMessage)(e)}),t.json({success:!0,data:[]})}}),e.get("/api/request-diff-stats",async(e,t)=>{try{const r="string"==typeof e.query.requestId?e.query.requestId:void 0
|
|
3808
3809
|
if(!r)return void t.status(400).json({success:!1,error:"requestId required"})
|
|
3809
3810
|
const s=(0,L.simpleGit)(o.projectPath),n=await(0,F.resolveRequestDiffRange)(s,r,{status:"in_progress"}),i=n.headSha,a="string"==typeof e.query.since&&/^[0-9a-f]{7,40}$/.test(e.query.since)?e.query.since:"",c=a&&i&&await s.raw(["merge-base","--is-ancestor",a,i]).then(()=>!0,()=>!1)?a:n.baseSha,l=c&&i?await(0,F.computeDiffStats)(s,c,i):void 0,d=await(0,Y.resolveDefaultBranch)(o.projectPath).catch(()=>{})
|
|
3810
3811
|
t.json({success:!0,data:l?{...l,baseSha:c,headSha:i,...d?{branch:d}:{}}:null})}catch(e){o.logger.debug("request-diff-stats lookup failed",{error:(0,P.getErrorMessage)(e)}),t.json({success:!0,data:null})}}),e.post("/api/verify-preflight",async(e,t)=>{try{const{requestId:r,commands:s}=e.body??{},n=Array.isArray(s)?s.filter(e=>"string"==typeof e&&!!e.trim()):[]
|
|
@@ -4968,7 +4969,10 @@ try{const t=Date.now()-this.pendingConfigReloadSince
|
|
|
4968
4969
|
if(t<ht.RELOAD_DEFER_CAP_MS){if(this.activeMcpCalls.size>0)return
|
|
4969
4970
|
if(await this.anySessionBusy())return}else this.logger.warn("Config reload deferred past cap; firing despite activity (staleness beats permanent deferral)",{trigger:e,waitedMs:t})
|
|
4970
4971
|
this.pendingConfigReload=!1,this.stopPendingReloadRecheck(),this.logger.info("Firing deferred OpenCode config reload",{trigger:e,waitedMs:t}),await this.reloadOpenCodeConfigNow(`deferred-${e}`)}finally{this.deferredReloadCheckInFlight=!1}}}else this.stopPendingReloadRecheck()}async applyClaudeThinking(e){const t=this.claudeThinkingSeen
|
|
4971
|
-
this.claudeThinkingSeen=e,void 0!==t&&t!==e&&this.projectId&&(this.logger.info("Claude thinking setting changed; re-syncing agents",{from:t,to:e}),await this.resyncAgentMarkdowns().catch(e=>this.logger.debug("Agent re-sync after the Claude thinking change failed",{error:(0,H.getErrorMessage)(e)})))}async
|
|
4972
|
+
this.claudeThinkingSeen=e,void 0!==t&&t!==e&&this.projectId&&(this.logger.info("Claude thinking setting changed; re-syncing agents",{from:t,to:e}),await this.resyncAgentMarkdowns().catch(e=>this.logger.debug("Agent re-sync after the Claude thinking change failed",{error:(0,H.getErrorMessage)(e)})))}async applyAnthropicCompaction(e){const t=(0,je.generatedOpencodeConfigPath)(this.options.projectPath)
|
|
4973
|
+
try{const r=JSON.parse(await D.default.promises.readFile(t,"utf8"))
|
|
4974
|
+
if(!r||"object"!=typeof r||!(0,B.withAnthropicCompaction)(r,e))return
|
|
4975
|
+
await D.default.promises.writeFile(t,JSON.stringify(r,null,2),"utf8"),this.logger.info("Claude's own compaction setting changed; reloading the serve's config",{on:e}),await this.requestConfigReload("anthropic-compaction")}catch(e){this.logger.debug("Claude's own compaction setting not applied yet",{error:(0,H.getErrorMessage)(e)})}}async applyPause(e){const t=this.getOpenCodeUrl()?.replace(/\/$/,"")
|
|
4972
4976
|
if(t&&(this.pauseApplied?.url!==t||this.pauseApplied.paused!==e))try{const r=await fetch(`${t}/config/pause`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({paused:e}),signal:AbortSignal.timeout(15e3)})
|
|
4973
4977
|
if(!r.ok)return void this.logger.warn("The serve did not take the pause",{paused:e,status:r.status})
|
|
4974
4978
|
const s=await r.json().catch(()=>({}))
|
|
@@ -5303,8 +5307,8 @@ r&&(t["X-Main-Sha"]=r)
|
|
|
5303
5307
|
const s=await fetch(e,{headers:t,signal:AbortSignal.timeout(35e3)})
|
|
5304
5308
|
if(!s.ok)throw new Error(`Poll failed with status ${s.status}`)
|
|
5305
5309
|
const n=await s.json(),o={success:!0,data:n.data||n}
|
|
5306
|
-
if(o.success&&o.data&&void 0!==o.data.hasRemoteEventConsumers&&(this.hasRemoteEventConsumers=o.data.hasRemoteEventConsumers,this.hasRemoteEventConsumers&&this.parkController?.noteActivity()),o.success&&o.data?.settings){const{defaultModel:e,paused:t,claudeThinking:r,defaultModelUnchosen:
|
|
5307
|
-
"boolean"==typeof
|
|
5310
|
+
if(o.success&&o.data&&void 0!==o.data.hasRemoteEventConsumers&&(this.hasRemoteEventConsumers=o.data.hasRemoteEventConsumers,this.hasRemoteEventConsumers&&this.parkController?.noteActivity()),o.success&&o.data?.settings){const{defaultModel:e,paused:t,claudeThinking:r,anthropicCompaction:s,defaultModelUnchosen:n}=o.data.settings
|
|
5311
|
+
"boolean"==typeof n&&(this.defaultModelUnchosen=n),void 0!==e&&await this.updateDefaultModel(e),await this.followUnchosenDefault(),"boolean"==typeof t&&await this.applyPause(t),"string"==typeof r&&await this.applyClaudeThinking(r),"boolean"==typeof s&&await this.applyAnthropicCompaction(s)}if(o.success&&!0===o.data?.previewTunnel&&this.projectId&&(this.previewTunnel||(this.previewTunnel=new T.PreviewTunnelClient({remoteServerUrl:this.options.remoteServerUrl,projectId:this.projectId,projectPath:this.options.projectPath,headers:()=>({...this.apiClient.authToken?{Authorization:`Bearer ${this.apiClient.authToken}`}:{},...(0,st.machineCallerHeaders)(this.options.remoteServerUrl)}),ports:()=>({ownPort:this.port,blocked:[...this.openCodePort?[this.openCodePort]:[],...(0,_.listLive)().map(e=>e.port).filter(e=>e!==this.port)]}),logger:this.logger})),this.previewTunnel.want()),o.success&&Array.isArray(o.data?.invalidations)&&o.data.invalidations.length>0){const e=o.data.invalidations
|
|
5308
5312
|
this.logger.info("Received cache invalidations from remote",{invalidations:e}),(e.includes("quests")||e.includes("documents")||e.includes("plans"))&&this.scheduleRunner?.invalidateCache(),e.includes("alchemist")&&this.scheduleRunner?.invalidateAlchemistCache(),e.includes("owner-guidance")&&(this.ownerGuidanceStale||this.logger.info("Your guidance changed; it reaches this project's agents at the next moment that costs nothing"),this.ownerGuidanceStale=!0),e.includes("agents")&&(this.logger.info("Agent definitions changed on the remote; re-syncing markdowns"),this.resyncAgentMarkdowns().catch(e=>this.logger.warn("Agent markdown re-sync after invalidation failed",{error:(0,H.getErrorMessage)(e)})))}const i=o.success?o.data?.scheduleNudges??o.data?.questNudges:void 0,a=Array.isArray(i)?i:[],c=o.success&&Array.isArray(o.data?.actions)?o.data.actions.length:0,l=a.length
|
|
5309
5313
|
if((c>0||l>0)&&await this.ensureServeAlive("poll-work"),a.length>0){const e=a
|
|
5310
5314
|
this.logger.info("Received goal nudges from remote",{scheduleNudges:e})
|
|
@@ -5802,30 +5806,30 @@ if("number"!=typeof t?.context)continue
|
|
|
5802
5806
|
const o={context:t.context,..."number"==typeof t.input?{input:t.input}:{},..."number"==typeof t.output?{output:t.output}:{}}
|
|
5803
5807
|
n.set(`${e.id}/${r}`,o),s?.id&&s.id!==r&&n.set(`${e.id}/${s.id}`,o)}}r.set(e,{at:Date.now(),value:n})}catch{}return n}
|
|
5804
5808
|
const t=new Map,r=new Map},58836(e,exports,t){"use strict"
|
|
5805
|
-
function r(e){
|
|
5806
|
-
|
|
5807
|
-
const
|
|
5808
|
-
|
|
5809
|
+
function r(e,t){const r=e?.info??e??{}
|
|
5810
|
+
if((0,n.isCompactionSummary)(r))return{compact:!1,why:"already compacted"}
|
|
5811
|
+
const s=(0,n.contextTokensOf)(r)
|
|
5812
|
+
return s<("alchemist"===t.agentType?1e5:6e4)?{compact:!1,why:"small"}:r.time&&!r.time.completed?{compact:!1,why:"mid-turn"}:r.providerID&&r.modelID?t.idleMs<(0,n.cacheRetentionMsFor)(r.providerID)?{compact:!1,why:"cache plausibly still warm"}:{compact:!0,ctx:s}:{compact:!1,why:"no model"}}exports.startSessionCompactor=function(e){let t,n,i=0
|
|
5813
|
+
const a=r=>e.apiClient.post("/api/liveness/report",{name:"session-compactor",project:e.projectName,description:`Compacts the hub session idle past its provider's cache window (~60-90 min, per-provider heuristic) with >${Math.round(60)}k context -> summarize so reuse is cheap`,intervalMs:6e5,lastRunAt:(new Date).toISOString(),runs:i,lastAction:t,lastActionAt:n,...r}).catch(()=>{}),c=async()=>{if((0,o.isProjectPaused)())return
|
|
5814
|
+
const c=Date.now()
|
|
5815
|
+
i++
|
|
5809
5816
|
try{const o=e.getOpenCodeUrl()
|
|
5810
|
-
if(!o||!e.projectId)return void await
|
|
5811
|
-
const
|
|
5812
|
-
for(const e of
|
|
5813
|
-
t&&"alchemist"===r&&"active"===(e.status??"active")&&
|
|
5814
|
-
const
|
|
5815
|
-
for(const s of Array.isArray(
|
|
5816
|
-
if(!
|
|
5817
|
-
const
|
|
5818
|
-
if(
|
|
5819
|
-
let
|
|
5817
|
+
if(!o||!e.projectId)return void await a({lastDurationMs:Date.now()-c})
|
|
5818
|
+
const i=await(0,s.readAllPages)(e.apiClient,t=>`/api/projects/${e.projectId}/cli-sessions?status=active&limit=100&offset=${t}`),l=new Map
|
|
5819
|
+
for(const e of i){const t=e.externalSessionId||e.external_session_id,r=e.agentType||e.agent_type
|
|
5820
|
+
t&&"alchemist"===r&&"active"===(e.status??"active")&&l.set(t,{title:e.title||t,agentType:r})}if(0===l.size)return void await a({lastDurationMs:Date.now()-c})
|
|
5821
|
+
const d=await fetch(`${o}/session?limit=1000`,{signal:AbortSignal.timeout(1e4)}),u=await d.json().catch(()=>[]),h=Date.now()
|
|
5822
|
+
for(const s of Array.isArray(u)?u:[]){const i=l.get(s.id)
|
|
5823
|
+
if(!i)continue
|
|
5824
|
+
const a=i.title,c=s.time?.updated??s.time?.created??0
|
|
5825
|
+
if(h-c<27e5)continue
|
|
5826
|
+
let d
|
|
5820
5827
|
try{const e=await fetch(`${o}/session/${s.id}/message?limit=1`,{signal:AbortSignal.timeout(1e4)}),t=await e.json()
|
|
5821
|
-
|
|
5822
|
-
if(
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
const m=await fetch(`${o}/session/${s.id}/summarize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({providerID:h.providerID,modelID:h.modelID}),signal:AbortSignal.timeout(12e4)})
|
|
5827
|
-
m.ok?(t=`compacted ${a.agentType} ${c} (${Math.round(f/1e3)}k ctx, idle ${Math.round((p-l)/6e4)}m)`,i=(new Date).toISOString(),e.logger.info("Session compactor: compacted an idle session",{sessionId:s.id,title:c,ctx:f})):e.logger.warn("Session compactor: summarize failed",{sessionId:s.id,status:m.status})}await c({lastDurationMs:Date.now()-l})}catch(e){await c({lastError:String(e).slice(0,200),lastDurationMs:Date.now()-l})}}
|
|
5828
|
-
setInterval(l,6e5),l()}
|
|
5828
|
+
d=Array.isArray(t)?t[t.length-1]:void 0}catch{continue}const u=d?.info??d??{},p=r(d,{agentType:i.agentType,idleMs:h-c})
|
|
5829
|
+
if(!p.compact)continue
|
|
5830
|
+
const f=p.ctx,m=await fetch(`${o}/session/${s.id}/summarize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({providerID:u.providerID,modelID:u.modelID}),signal:AbortSignal.timeout(12e4)})
|
|
5831
|
+
m.ok?(t=`compacted ${i.agentType} ${a} (${Math.round(f/1e3)}k ctx, idle ${Math.round((h-c)/6e4)}m)`,n=(new Date).toISOString(),e.logger.info("Session compactor: compacted an idle session",{sessionId:s.id,title:a,ctx:f})):e.logger.warn("Session compactor: summarize failed",{sessionId:s.id,status:m.status})}await a({lastDurationMs:Date.now()-c})}catch(e){await a({lastError:String(e).slice(0,200),lastDurationMs:Date.now()-c})}}
|
|
5832
|
+
setInterval(c,6e5),c()}
|
|
5829
5833
|
const s=t(5641),n=t(89063),o=t(36799)},67078(e,exports){"use strict"
|
|
5830
5834
|
function t(e,t){let s=r.get(e)
|
|
5831
5835
|
return s||(s=new Set,r.set(e,s)),s.add(t),()=>{const s=r.get(e)
|
|
@@ -6745,23 +6749,35 @@ else{const r=await(0,i.resolveDefaultBranch)(e)
|
|
|
6745
6749
|
await u.raw(["worktree","add","-b",c,d,r]),a.info("Pre-spawn: created worktree with new branch from latest main",{requestId:t,branchName:c,mainBranch:r,worktreePath:d})}}catch(e){const r=e instanceof Error?e.message:String(e)
|
|
6746
6750
|
a.warn("Pre-spawn: failed to create worktree (MCP process will retry)",{requestId:t,error:r})}}
|
|
6747
6751
|
const r=t(79896),s=t(16928),n=t(83807),o=t(7202),i=t(52232)},35419(e,exports,t){"use strict"
|
|
6748
|
-
function r(e){return(0,o.join)(e,i.ALCHEMY_DIR_NAME,"opencode-config.json")}function s(e){return(0,o.join)((0,n.homedir)(),i.ALCHEMY_DIR_NAME,e?"opencode-dev":"opencode")}exports.t=void 0,exports.generatedOpencodeConfigPath=r,exports.getGlobalConfigDir=s,exports.getOpencodeSpawnEnv=function(e,t){
|
|
6752
|
+
function r(e){return(0,o.join)(e,i.ALCHEMY_DIR_NAME,"opencode-config.json")}function s(e){return(0,o.join)((0,n.homedir)(),i.ALCHEMY_DIR_NAME,e?"opencode-dev":"opencode")}exports.t=void 0,exports.generatedOpencodeConfigPath=r,exports.getGlobalConfigDir=s,exports.getOpencodeSpawnEnv=function(e,t){const n=process.env.ALCHEMYLAB_ANTHROPIC_COMPACTION
|
|
6753
|
+
return{...void 0===n?{}:{ALCHEMYLAB_ANTHROPIC_COMPACTION:n},ANTHROPIC_CLI_VERSION:process.env.ANTHROPIC_CLI_VERSION??exports.t,OPENCODE_CLIENT:"cli",ALCHEMYLAB:"1",OPENCODE_ENABLE_EXA:"1",OPENCODE_DATA_DIR:(0,o.join)(e,i.ALCHEMY_DIR_NAME,"opencode"),OPENCODE_CONFIG_DIR:s(t),ALCHEMY_PROTECTED_ROOT:e,OPENCODE_CONFIG:r(e),OPENCODE_DISABLE_PROJECT_CONFIG:"1",OPENCODE_DISABLE_CLAUDE_CODE:"1",OPENCODE_DISABLE_EXTERNAL_SKILLS:"1"}}
|
|
6749
6754
|
const n=t(70857),o=t(16928),i=t(14139)
|
|
6750
6755
|
exports.t="2.1.280"},39068(e,exports,t){"use strict"
|
|
6751
6756
|
function r(){const e=process.env.ALCHEMY_OPENCODE_DIR
|
|
6752
6757
|
if(e)return e
|
|
6753
6758
|
try{const e=("undefined"!=typeof require?require:t(54245)).resolve("alchemylab-opencode/package.json")
|
|
6754
|
-
return(0,
|
|
6755
|
-
try{const e=(0,
|
|
6756
|
-
if((0,
|
|
6757
|
-
if((0,
|
|
6759
|
+
return(0,a.dirname)(e)}catch{}}function s(){if(u)return u
|
|
6760
|
+
try{const e=(0,l.execFileSync)("node",["--version"],{encoding:"utf8"}).trim()
|
|
6761
|
+
if((0,d.isSupportedNode)(e))return u="node",u}catch{}const e=process.env.NVM_DIR||(0,a.join)(process.env.HOME||"",".nvm"),t=(0,a.join)(e,"versions","node")
|
|
6762
|
+
if((0,c.existsSync)(t))try{const e=(0,c.readdirSync)(t).filter(e=>(0,d.isSupportedNode)(e)).sort((e,t)=>{const r=e.replace("v","").split(".").map(Number),s=t.replace("v","").split(".").map(Number)
|
|
6758
6763
|
return s[0]-r[0]||s[1]-r[1]||s[2]-r[2]})
|
|
6759
|
-
if(e.length>0){const r=(0,
|
|
6760
|
-
if((0,
|
|
6761
|
-
|
|
6762
|
-
return e
|
|
6763
|
-
|
|
6764
|
-
|
|
6764
|
+
if(e.length>0){const r=(0,a.join)(t,e[0],"bin","node")
|
|
6765
|
+
if((0,c.existsSync)(r))return u=r,u}}catch{}throw new Error((0,d.unsupportedNodeMessage)(process.version))}function n(e,t){return{command:s(),prependArgs:["--no-warnings",(0,a.join)(e,t)]}}function o(e,t,r){const s=(0,l.spawnSync)(e,[t],{cwd:r,encoding:"utf8",stdio:["ignore","pipe","pipe"],timeout:12e4}),n=`${s.stdout??""}${s.stderr??""}`
|
|
6766
|
+
if(s.error||0!==s.status)throw Object.assign(new Error(s.error?.message??`exit ${s.status}`),{stderr:n})
|
|
6767
|
+
return n}function i(e,t=o){if(!e||process.env.ALCHEMY_OPENCODE_DIR)return"not-needed"
|
|
6768
|
+
if(h?.dir===e)return h.state
|
|
6769
|
+
const r=(0,a.join)(e,"postinstall.cjs"),n=(t,r="")=>(h={dir:e,state:t,detail:r},t)
|
|
6770
|
+
if(!(0,c.existsSync)(r)||!(0,c.existsSync)((0,a.join)(e,"patches")))return n("not-needed")
|
|
6771
|
+
let i=""
|
|
6772
|
+
try{i=String(JSON.parse((0,c.readFileSync)((0,a.join)(e,"package.json"),"utf8")).version??"")}catch{}const l=(0,a.join)(e,exports.BY)
|
|
6773
|
+
try{if(i&&(0,c.readFileSync)(l,"utf8")===i)return n("done")}catch{}try{const o=t(s(),r,e)
|
|
6774
|
+
return i&&(0,c.writeFileSync)(l,i),n("applied",String(o??"").trim())}catch(t){const r=String(t?.stderr||t?.message||t).trim().split("\n").slice(-3).join(" ")
|
|
6775
|
+
return process.stderr.write(`AlchemyLab could not apply its engine's dependency patches in ${e} (${r}); the engine starts without them.\n`),n("failed",r)}}exports.BY=void 0,exports.findOpencodeDir=r,exports.lastEnginePatchState=function(){return h},exports.resolveServeCommand=function(){const e=r()
|
|
6776
|
+
return e?(i(e),n((0,a.join)(e,"dist"),"serve.js")):{command:"opencode",prependArgs:["serve"]}},exports.resolveRunCommand=function(){const e=r()
|
|
6777
|
+
return e?(i(e),n((0,a.join)(e,"dist"),"run.js")):{command:"opencode",prependArgs:[]}}
|
|
6778
|
+
const a=t(16928),c=t(79896),l=t(35317),d=t(84973)
|
|
6779
|
+
let u,h
|
|
6780
|
+
exports.BY=".alchemylab-patches-applied"},69706(e,exports,t){"use strict"
|
|
6765
6781
|
function r(e){try{const t=JSON.parse(a.default.readFileSync(c.default.join(e,l),"utf8"))
|
|
6766
6782
|
return"string"==typeof t.password&&t.password?t.password:null}catch{return null}}function s(e){const t=process.env.OPENCODE_SERVER_USERNAME||exports.SERVE_USERNAME
|
|
6767
6783
|
return`Basic ${Buffer.from(`${t}:${e}`).toString("base64")}`}function n(e){if(!d.port)return!1
|
|
@@ -7781,17 +7797,20 @@ const d=Number(s.prepare("SELECT v FROM meta WHERE k = 'generation'").get()?.v??
|
|
|
7781
7797
|
i.prepare("UPDATE meta SET v = max(v, ?) WHERE k = 'generation'").run(d),i.exec("COMMIT")}finally{s.close()}}}finally{i.close()}if(t===p.items+e)return{projectId:s,restored:!1,unchanged:!0,items:t,keptFromLive:e}
|
|
7782
7798
|
if(n.default.chmodSync(u,384),n.default.existsSync(d)){n.default.renameSync(d,`${d}.before-restore-${a}`)
|
|
7783
7799
|
for(const e of["-wal","-shm"])n.default.existsSync(d+e)&&n.default.renameSync(d+e,`${d}.before-restore-${a}${e}`)}return n.default.renameSync(u,d),{projectId:s,restored:!0,items:p.items+e,keptFromLive:e}}finally{o.unhold(s),n.default.rmSync(u,{force:!0})}}}},18984(e,exports,t){"use strict"
|
|
7784
|
-
function r(e){return"summary"===e?.claudeThinking?"summary":"omitted"}
|
|
7785
|
-
|
|
7800
|
+
function r(e){return"summary"===e?.claudeThinking?"summary":"omitted"}function s(e,t){const r=void 0!==e.compaction?.anthropic
|
|
7801
|
+
if(t?!0===e.compaction?.anthropic:!r)return!1
|
|
7802
|
+
const{anthropic:s,...n}=e.compaction??{}
|
|
7803
|
+
return t?e.compaction={...n,anthropic:!0}:Object.keys(n).length>0?e.compaction=n:delete e.compaction,!0}exports.MCPClientConfigurer=exports.Vr=exports.Es=exports.R1=exports.NK=void 0,exports.claudeThinkingOf=r,exports.withAnthropicCompaction=s
|
|
7804
|
+
const n=t(75632),o=t(58824),i=t(89796),a=t(95671),c=t(43218),l=t(49779),d=t(11773),u=t(79896),h=t(16928),p=t(35317),f=t(91943),m=t(39023),g=t(35419)
|
|
7786
7805
|
exports.NK="medium"
|
|
7787
|
-
const
|
|
7788
|
-
let
|
|
7806
|
+
const w=new Set(["low","medium","high","xhigh","max"])
|
|
7807
|
+
let y=exports.NK,v=[]
|
|
7789
7808
|
exports.R1=new Set(["$schema","model","mcp","agent","mode","permission","plugin","tools","small_model","share","autoshare"]),exports.Es=new Set(["theme","keybinds","tui","layout","username","watcher","instructions"]),exports.Vr=new Set(["reviewer","acceptance-judge","command-judge","guidance-judge","intake-reviewer"])
|
|
7790
|
-
class
|
|
7809
|
+
class b{constructor(e,t,r){this.logger=e,this.agentMarkdowns=new Map,this.pinnedAgents=new Set,this.connectedProviders=null,this.remoteServerUrl=t||process.env.REMOTE_SERVER_URL,this.authToken=r}async seedAgentsFromRemote(e){const t=this.remoteServerUrl
|
|
7791
7810
|
if(!t)return this.logger.debug("No REMOTE_SERVER_URL set, cannot initialize agents"),!1
|
|
7792
7811
|
try{const r=`${t}/api/agents/seed`
|
|
7793
7812
|
this.logger.info("Ensuring built-in agents exist",{url:r})
|
|
7794
|
-
const s={"Content-Type":"application/json","X-Client-Type":"alchemy-local-service",...(0,
|
|
7813
|
+
const s={"Content-Type":"application/json","X-Client-Type":"alchemy-local-service",...(0,d.machineCallerHeaders)(t)}
|
|
7795
7814
|
this.authToken&&(s.Authorization=`Bearer ${this.authToken}`)
|
|
7796
7815
|
const n=await fetch(r,{method:"POST",headers:s})
|
|
7797
7816
|
n.ok||this.logger.warn("Failed to seed global agents",{status:n.status,statusText:n.statusText})
|
|
@@ -7800,16 +7819,16 @@ this.logger.info("Initializing project agent activations",{url:o})
|
|
|
7800
7819
|
const i=await fetch(o,{method:"POST",headers:s})
|
|
7801
7820
|
if(!i.ok)return this.logger.warn("Failed to initialize project agents",{status:i.status,statusText:i.statusText}),!1
|
|
7802
7821
|
const a=await i.json()
|
|
7803
|
-
return this.logger.info("Initialized project agent activations",{initialized:a.data?.initialized||0}),!0}catch(e){return this.logger.warn("Error initializing agents from remote",{error:(0,
|
|
7822
|
+
return this.logger.info("Initialized project agent activations",{initialized:a.data?.initialized||0}),!0}catch(e){return this.logger.warn("Error initializing agents from remote",{error:(0,o.getErrorMessage)(e)}),!1}}async fetchPluginManifest(){const e={"opencode-claude-auth":"1.5.3"},t=this.remoteServerUrl
|
|
7804
7823
|
if(!t)return this.logger.debug("No REMOTE_SERVER_URL set, using baseline plugin manifest"),{...e}
|
|
7805
7824
|
const r=`${t}/api/distribution/plugin-versions`
|
|
7806
|
-
try{const s={"Content-Type":"application/json","X-Client-Type":"alchemy-local-service",...(0,
|
|
7825
|
+
try{const s={"Content-Type":"application/json","X-Client-Type":"alchemy-local-service",...(0,d.machineCallerHeaders)(t)}
|
|
7807
7826
|
this.authToken&&(s.Authorization=`Bearer ${this.authToken}`)
|
|
7808
7827
|
const n=await fetch(r,{method:"GET",headers:s})
|
|
7809
7828
|
if(!n.ok)return this.logger.warn("Plugin manifest fetch returned non-OK; using baseline",{status:n.status}),{...e}
|
|
7810
7829
|
const o=await n.json(),i=o?.data?.plugins??o?.plugins??{},a={...e}
|
|
7811
7830
|
for(const[e,t]of Object.entries(i)){const r=t?.version
|
|
7812
|
-
"string"==typeof r&&r.trim()&&(a[e]=r.trim())}return this.logger.info("Fetched plugin manifest",{manifest:a}),a}catch(t){return this.logger.warn("Plugin manifest fetch failed; using baseline",{error:(0,
|
|
7831
|
+
"string"==typeof r&&r.trim()&&(a[e]=r.trim())}return this.logger.info("Fetched plugin manifest",{manifest:a}),a}catch(t){return this.logger.warn("Plugin manifest fetch failed; using baseline",{error:(0,o.getErrorMessage)(t)}),{...e}}}async sweepLegacyAuthPluginFiles(e){const r=await Promise.resolve().then(()=>t.t(91943,23)),s=await Promise.resolve().then(()=>t.t(16928,23)),n=(await Promise.resolve().then(()=>t.t(70857,23))).homedir(),o=new Set
|
|
7813
7832
|
let i=e
|
|
7814
7833
|
for(let e=0;e<6;e++){o.add(s.join(i,".opencode","plugin","anthropic-auth.js"))
|
|
7815
7834
|
const e=s.dirname(i)
|
|
@@ -7832,17 +7851,17 @@ this.authToken&&(s.Authorization=`Bearer ${this.authToken}`)
|
|
|
7832
7851
|
const n=await fetch(r,{method:"GET",headers:s})
|
|
7833
7852
|
if(!n.ok)return this.logger.warn("Failed to fetch agents from remote",{status:n.status,statusText:n.statusText}),null
|
|
7834
7853
|
const o=await n.json(),i=o.data||o
|
|
7835
|
-
return this.logger.info("Fetched agents from remote",{count:i.length}),i}catch(e){return this.logger.warn("Error fetching agents from remote",{error:(0,
|
|
7854
|
+
return this.logger.info("Fetched agents from remote",{count:i.length}),i}catch(e){return this.logger.warn("Error fetching agents from remote",{error:(0,o.getErrorMessage)(e)}),null}}async fetchDefaultWorkflowFromRemote(e){const t=this.remoteServerUrl
|
|
7836
7855
|
if(!t)return null
|
|
7837
7856
|
try{const r=await fetch(`${t}/api/projects/${e}/default-workflow`,{headers:{"Content-Type":"application/json",...this.authToken?{Authorization:`Bearer ${this.authToken}`}:{}}})
|
|
7838
7857
|
if(!r.ok)return this.logger.warn("Failed to fetch default workflow from remote",{projectId:e,status:r.status}),null
|
|
7839
7858
|
const s=await r.json()
|
|
7840
7859
|
return s.data||s||null}catch(t){return this.logger.warn("Error fetching default workflow from remote",{projectId:e,error:t instanceof Error?t.message:String(t)}),null}}async fetchMcpServersFromRemote(e){const t=this.remoteServerUrl
|
|
7841
|
-
if(!t)return
|
|
7860
|
+
if(!t)return v
|
|
7842
7861
|
try{const r=await fetch(`${t}/api/projects/${e}/mcp-servers`,{headers:{"Content-Type":"application/json",...this.authToken?{Authorization:`Bearer ${this.authToken}`}:{}}})
|
|
7843
|
-
if(!r.ok)return this.logger.warn("Failed to fetch MCP connections; keeping the last known denies",{projectId:e,status:r.status,known:
|
|
7862
|
+
if(!r.ok)return this.logger.warn("Failed to fetch MCP connections; keeping the last known denies",{projectId:e,status:r.status,known:v.length}),v
|
|
7844
7863
|
const s=await r.json(),n=s.data||s||[]
|
|
7845
|
-
return Array.isArray(n)?(
|
|
7864
|
+
return Array.isArray(n)?(v=n,n):v}catch(t){return this.logger.warn("Error fetching MCP connections; keeping the last known denies",{projectId:e,error:t instanceof Error?t.message:String(t),known:v.length}),v}}async fetchOwnerGuidanceFromRemote(e){const t=this.remoteServerUrl
|
|
7846
7865
|
if(!t)return[]
|
|
7847
7866
|
try{const r=await fetch(`${t}/api/projects/${e}/owner-guidance`,{headers:{"Content-Type":"application/json",...this.authToken?{Authorization:`Bearer ${this.authToken}`}:{}}})
|
|
7848
7867
|
if(!r.ok)return[]
|
|
@@ -7854,97 +7873,97 @@ if(!t)return this.logger.debug("No REMOTE_SERVER_URL set, cannot fetch project f
|
|
|
7854
7873
|
try{const r=await fetch(`${t}/api/projects/${e}`,{headers:{"Content-Type":"application/json",...this.authToken?{Authorization:`Bearer ${this.authToken}`}:{}}})
|
|
7855
7874
|
if(!r.ok)return this.logger.warn("Failed to fetch project from remote",{projectId:e,status:r.status,statusText:r.statusText}),null
|
|
7856
7875
|
const s=await r.json()
|
|
7857
|
-
return s.data||s}catch(t){return this.logger.error("Error fetching project from remote",{projectId:e,error:(0,
|
|
7876
|
+
return s.data||s}catch(t){return this.logger.error("Error fetching project from remote",{projectId:e,error:(0,o.getErrorMessage)(t)}),null}}getAgentMarkdowns(){return[...this.agentMarkdowns].map(([e,t])=>({name:e,markdown:t}))}setAgentMarkdown(e,t){this.agentMarkdowns.set(e,t)}agentModelOf(e){const t=this.agentMarkdowns.get(e),r=t?/^model:\s*"([^"\n]+)"\s*$/m.exec(t):null
|
|
7858
7877
|
return r&&r[1].includes("/")?r[1]:null}agentPinnedOf(e){return this.pinnedAgents.has(e)}clearAgentMarkdowns(){this.agentMarkdowns.clear()}async removeOnDiskAgentFiles(e,r=[]){const s=await Promise.resolve().then(()=>t.t(91943,23)),n=await Promise.resolve().then(()=>t.t(16928,23)),o=new Set(r.map(e=>`${e}.md`)),i=(new Date).toISOString().slice(0,10)
|
|
7859
7878
|
try{for(const t of await s.readdir(e)){if(!t.endsWith(".md"))continue
|
|
7860
7879
|
const r=n.join(e,t)
|
|
7861
7880
|
let a=""
|
|
7862
7881
|
try{a=(await s.readFile(r,"utf8")).slice(0,400)}catch{}if(o.has(t)&&/^---[\s\S]*\bmode:\s*(primary|subagent|all)\b/m.test(a)){await s.unlink(r)
|
|
7863
7882
|
continue}const c=`${r}.removed-by-alchemy-${i}`
|
|
7864
|
-
try{await s.rename(r,c),this.logger.warn("Moved an agent file AlchemyLab did not write out of the way (agent prompts are served from memory now)",{from:r,movedTo:c})}catch(e){this.logger.warn("Could not move an unrecognised agent file aside; leaving it",{path:r,error:e instanceof Error?e.message:String(e)})}}}catch{}}buildExploreMarkdown(e){return`---\ndescription: Fast codebase exploration and research subagent\nmode: subagent\n---\n\n${e?e.trim()+"\n\n":""}You are a codebase exploration agent. Your job is to find specific information and return concise, targeted answers.\n\n## Response Guidelines\n\n- **Be concise.** Return only what was asked for. A typical answer is 100-500 words.\n- **Lead with the answer.** State findings first, then supporting details.\n- **Reference specific files and lines.** Use \`file_path:line_number\` format.\n- **Don't exhaustively document everything you find.** Focus on what's relevant to the question.\n- **Use structured output** when listing multiple items (bullet points, not prose).\n\n## Strategy\n\n1. Start with \`search\` to find relevant files by name or content patterns\n2. Use \`read_files\` to read specific sections (use line ranges, don't read entire large files)\n3. Use \`query_history\` for understanding why code changed or tracing decisions\n\n## Anti-patterns to Avoid\n\n- Don't produce multi-thousand-word reports for simple questions\n- Don't read every file in a directory when a targeted search would suffice\n- Don't explain how tools work \u2014 just use them and report findings\n`}async resolveWorkflowEffort(e){try{const t=await this.fetchDefaultWorkflowFromRemote(e),r="string"==typeof t?.effort&&
|
|
7865
|
-
r!==
|
|
7883
|
+
try{await s.rename(r,c),this.logger.warn("Moved an agent file AlchemyLab did not write out of the way (agent prompts are served from memory now)",{from:r,movedTo:c})}catch(e){this.logger.warn("Could not move an unrecognised agent file aside; leaving it",{path:r,error:e instanceof Error?e.message:String(e)})}}}catch{}}buildExploreMarkdown(e){return`---\ndescription: Fast codebase exploration and research subagent\nmode: subagent\n---\n\n${e?e.trim()+"\n\n":""}You are a codebase exploration agent. Your job is to find specific information and return concise, targeted answers.\n\n## Response Guidelines\n\n- **Be concise.** Return only what was asked for. A typical answer is 100-500 words.\n- **Lead with the answer.** State findings first, then supporting details.\n- **Reference specific files and lines.** Use \`file_path:line_number\` format.\n- **Don't exhaustively document everything you find.** Focus on what's relevant to the question.\n- **Use structured output** when listing multiple items (bullet points, not prose).\n\n## Strategy\n\n1. Start with \`search\` to find relevant files by name or content patterns\n2. Use \`read_files\` to read specific sections (use line ranges, don't read entire large files)\n3. Use \`query_history\` for understanding why code changed or tracing decisions\n\n## Anti-patterns to Avoid\n\n- Don't produce multi-thousand-word reports for simple questions\n- Don't read every file in a directory when a targeted search would suffice\n- Don't explain how tools work \u2014 just use them and report findings\n`}async resolveWorkflowEffort(e){try{const t=await this.fetchDefaultWorkflowFromRemote(e),r="string"==typeof t?.effort&&w.has(t.effort)?t.effort:exports.NK
|
|
7884
|
+
r!==y&&this.logger.info("Effort dial read from the workflow",{effort:r,was:y}),y=r}catch{}return y}hasConnectedProviders(){return null!==this.connectedProviders}getConnectedProviders(){return this.connectedProviders}async refreshConnectedProviders(e){const t=await(0,c.fetchConnectedProviders)(e)
|
|
7866
7885
|
if(!t)return!1
|
|
7867
7886
|
const r=JSON.stringify(t)!==JSON.stringify(this.connectedProviders)
|
|
7868
|
-
return this.connectedProviders=t,r}generateAgentMarkdown(e,t,r,
|
|
7869
|
-
if(e.model?.providerId&&e.model?.modelId?this.pinnedAgents.add(e.name):this.pinnedAgents.delete(e.name),e.model?.providerId&&e.model?.modelId)
|
|
7870
|
-
else if(e.preferredModelTier&&"same"!==e.preferredModelTier){const t=(0,
|
|
7871
|
-
t.resolved&&(
|
|
7872
|
-
if(l&&l!==
|
|
7873
|
-
|
|
7874
|
-
return` ${
|
|
7875
|
-
let u=`---\ndescription: "${e.description||e.name}"\nmode: "${"utility"===e.mode?"primary":e.mode||"primary"}"\nmodel: "${
|
|
7876
|
-
u+=`variant: "${e.variant||o.effort||
|
|
7887
|
+
return this.connectedProviders=t,r}generateAgentMarkdown(e,t,r,s,o={}){let i=r
|
|
7888
|
+
if(e.model?.providerId&&e.model?.modelId?this.pinnedAgents.add(e.name):this.pinnedAgents.delete(e.name),e.model?.providerId&&e.model?.modelId)i=`${e.model.providerId}/${e.model.modelId}`
|
|
7889
|
+
else if(e.preferredModelTier&&"same"!==e.preferredModelTier){const t=(0,a.resolveModelTier)(r,e.preferredProvider||"inherit",e.preferredModelTier,{anthropic:!0,openai:!0},o.limits)
|
|
7890
|
+
t.resolved&&(i=t.fullModel)}const l=(0,c.runnableModel)(i,this.connectedProviders)
|
|
7891
|
+
if(l&&l!==i){const t=`${e.name}:${i}->${l}`
|
|
7892
|
+
b.rerouteLogged.has(t)||(b.rerouteLogged.add(t),this.logger.warn("agent model provider not connected; the agent runs on a connected provider's default until it is",{agent:e.name,configured:i,running:l})),i=l}const d=[...Object.entries(e.tools||{}).map(([e,r])=>{const s=e.replace(/-/g,"_")
|
|
7893
|
+
return` ${b.OPENCODE_BUILTIN_TOOLS.has(e)?e:`${t}_${s}`}: ${r}`}),...Object.entries(o.extraTools||{}).map(([e,t])=>` ${e}: ${t}`)].join("\n")
|
|
7894
|
+
let u=`---\ndescription: "${e.description||e.name}"\nmode: "${"utility"===e.mode?"primary":e.mode||"primary"}"\nmodel: "${i}"\n`
|
|
7895
|
+
u+=`variant: "${e.variant||o.effort||y}"\n`
|
|
7877
7896
|
const h=[]
|
|
7878
|
-
"summary"===o.claudeThinking&&
|
|
7879
|
-
const p=(0,
|
|
7897
|
+
"summary"===o.claudeThinking&&i.startsWith("anthropic/")&&h.push(' thinking:\n display: "summarized"'),exports.Vr.has(e.name)&&i.startsWith("anthropic/")&&h.push(' cacheTtl: "5m"')
|
|
7898
|
+
const p=(0,n.toolScopesFor)(e.name,t,e.tools||{})
|
|
7880
7899
|
if(Object.keys(p).length>0&&h.push(` toolScopes: ${JSON.stringify(p)}`),h.length>0&&(u+=`options:\n${h.join("\n")}\n`),e.color&&(u+=`color: "${e.color}"\n`),u+=`tools:\n${d}\n`,e.opencodePermission&&Object.keys(e.opencodePermission).length>0){u+="permission:\n"
|
|
7881
7900
|
for(const[t,r]of Object.entries(e.opencodePermission))if("object"==typeof r&&null!==r){u+=` ${t}:\n`
|
|
7882
|
-
for(const[e,t]of Object.entries(r))u+=` "${e}": ${t}\n`}else u+=` ${t}: ${r}\n`}return void 0!==e.temperature&&(u+=`temperature: ${e.temperature}\n`),"number"==typeof e.maxSteps&&Number.isInteger(e.maxSteps)&&e.maxSteps>0&&(u+=`steps: ${e.maxSteps}\n`),u+="---\n\n",
|
|
7883
|
-
this.logger.info("Configuring OpenCode",{isDevMode:
|
|
7884
|
-
const
|
|
7885
|
-
let
|
|
7886
|
-
const
|
|
7887
|
-
let
|
|
7888
|
-
const
|
|
7889
|
-
if(!
|
|
7890
|
-
t?.openCodeTools?(
|
|
7891
|
-
try{e=JSON.parse(await
|
|
7901
|
+
for(const[e,t]of Object.entries(r))u+=` "${e}": ${t}\n`}else u+=` ${t}: ${r}\n`}return void 0!==e.temperature&&(u+=`temperature: ${e.temperature}\n`),"number"==typeof e.maxSteps&&Number.isInteger(e.maxSteps)&&e.maxSteps>0&&(u+=`steps: ${e.maxSteps}\n`),u+="---\n\n",s&&(u+=s.trim()+"\n\n"),e.prompt&&(u+=e.prompt),e.promptAddition&&(u+="\n\n"+e.promptAddition),u}async configureOpenCode(e,n,c="node",d,w){try{const v=await Promise.resolve().then(()=>t.t(91943,23)),k=await Promise.resolve().then(()=>t.t(16928,23)),S=e.includes("dist-dev")||process.env.REMOTE_SERVER_URL?.includes("localhost"),I="alchemy",$=k.join(e,"mcp-direct.js")
|
|
7902
|
+
this.logger.info("Configuring OpenCode",{isDevMode:S,serverName:I,scriptPath:$,projectPath:n}),await(0,i.ensureAlchemyIgnoreEntries)(n,this.logger),await this.sweepLegacyAuthPluginFiles(n)
|
|
7903
|
+
const j=(0,g.generatedOpencodeConfigPath)(n),E=k.join(n,"opencode.json")
|
|
7904
|
+
let A=null,C=null,_=null
|
|
7905
|
+
const T={}
|
|
7906
|
+
let x=null,M=!1
|
|
7907
|
+
const R=k.join(n,".alchemy_lab","config.json")
|
|
7908
|
+
if(!d)try{const e=await v.readFile(R,"utf-8"),t=JSON.parse(e)
|
|
7909
|
+
t?.openCodeTools?(A=t.openCodeTools,this.logger.info("Found tool settings in project config",{projectConfigTools:A})):M=!0,t?.openCodeModel&&(C=t.openCodeModel)}catch(e){this.logger.debug("No project config found, will create with defaults"),M=!0}{let e=null
|
|
7910
|
+
try{e=JSON.parse(await v.readFile(j,"utf-8"))}catch{}const t=await async function(e,t){const r=(0,h.join)(e,"opencode.json")
|
|
7892
7911
|
let s
|
|
7893
|
-
try{s=JSON.parse(await(0,
|
|
7894
|
-
try{return await(0,
|
|
7895
|
-
try{0===Object.keys(
|
|
7896
|
-
e=e??t,!
|
|
7897
|
-
try{const e=JSON.parse(await
|
|
7912
|
+
try{s=JSON.parse(await(0,f.readFile)(r,"utf8"))}catch{return null}if(!s||"object"!=typeof s||Array.isArray(s)||!s.mcp||"object"!=typeof s.mcp||!("alchemy"in s.mcp))return null
|
|
7913
|
+
try{return await(0,m.promisify)(p.execFile)("git",["ls-files","--error-unmatch","--","opencode.json"],{cwd:e}),null}catch{}const n=Object.fromEntries(Object.entries(s).filter(([e])=>!exports.R1.has(e)&&"instructions"!==e&&"skills"!==e))
|
|
7914
|
+
try{0===Object.keys(n).length?await(0,f.unlink)(r):await(0,f.writeFile)(r,JSON.stringify(n,null,2),"utf8"),t?.info("Moved the generated OpenCode config out of the project folder",{removed:0===Object.keys(n).length,keptUserKeys:Object.keys(n)})}catch(e){t?.warn("Could not clear the old generated opencode.json from the project folder",{error:(0,o.getErrorMessage)(e)})}return s}(n,this.logger)
|
|
7915
|
+
e=e??t,!d&&e?.mode?.alchemy?.tools&&(_=e.mode.alchemy.tools,this.logger.info("Found existing tool settings in the generated OpenCode config",{existingTools:_})),!d&&e?.model&&(x=e.model)
|
|
7916
|
+
try{const e=JSON.parse(await v.readFile(E,"utf-8")),{kept:t,setAside:r}=function(e){const t={},r={}
|
|
7898
7917
|
if(!e||"object"!=typeof e||Array.isArray(e))return{kept:t,setAside:r}
|
|
7899
7918
|
for(const[s,n]of Object.entries(e))if(!exports.R1.has(s))if(exports.Es.has(s)){if("instructions"===s&&Array.isArray(n)){const e=n.filter(e=>"string"==typeof e&&!/^[a-z][a-z0-9+.-]*:\/\//i.test(e)),o=n.filter(t=>!e.includes(t))
|
|
7900
7919
|
e.length>0&&(t[s]=e),o.length>0&&(r[s]=o)
|
|
7901
7920
|
continue}t[s]=n}else r[s]=n
|
|
7902
7921
|
return{kept:t,setAside:r}}(e)
|
|
7903
|
-
Object.assign(
|
|
7904
|
-
let
|
|
7905
|
-
if(
|
|
7906
|
-
const e=
|
|
7907
|
-
"string"==typeof e&&e.includes("/")&&(
|
|
7908
|
-
|
|
7909
|
-
const
|
|
7910
|
-
await
|
|
7911
|
-
const N
|
|
7912
|
-
let
|
|
7913
|
-
if(
|
|
7914
|
-
const e=await this.resolveWorkflowEffort(
|
|
7922
|
+
Object.assign(T,t),Object.keys(t).length>0&&this.logger.info("Keeping opencode.json keys AlchemyLab does not manage",{keys:Object.keys(t)}),Object.keys(r).length>0&&this.logger.warn("Not loading opencode.json keys: they run commands, change the runtime or send data elsewhere (providers are connected in Settings); the file is left as it is",{keys:Object.keys(r)})}catch{this.logger.info("No opencode.json of the user's in the project folder")}}const P=d?.openCodeTools||A||_||{glob:!1,grep:!1,ls:!1,list:!1,view:!1,read:!1,write:!1,edit:!1,patch:!1,diagnostics:!0,bash:!0===d?.enableBash,fetch:!1,sourcegraph:!0,agent:!1!==w,todoread:!1,todowrite:!1},O={tools:P}
|
|
7923
|
+
let D=null,q=null
|
|
7924
|
+
if(d?.projectId&&!d?.openCodeModel)try{q=await this.fetchProjectFromRemote(d.projectId)
|
|
7925
|
+
const e=q?.metadata?.defaultModel
|
|
7926
|
+
"string"==typeof e&&e.includes("/")&&(D=e)}catch(e){this.logger.warn("Could not fetch project default model; falling back",{error:e instanceof Error?e.message:String(e)})}const N=d?.openCodeModel||D||C||x||a.FLEET_DEFAULT_MODEL
|
|
7927
|
+
N!==a.FLEET_DEFAULT_MODEL||d?.openCodeModel||D||C||x||this.logger.warn("No default model configured anywhere for this project; agent files fall back to the fleet default model",{projectId:d?.projectId??null}),d?.openCodeModel?O.model=d.openCodeModel:D?O.model=D:C?O.model=C:x&&(O.model=x)
|
|
7928
|
+
const F=k.join(n,".opencode","agent")
|
|
7929
|
+
await v.mkdir(F,{recursive:!0})
|
|
7930
|
+
const L=N||a.FLEET_DEFAULT_MODEL
|
|
7931
|
+
let U,B=null,H=null,W=[],G=null
|
|
7932
|
+
if(d?.projectId)if(await this.seedAgentsFromRemote(d.projectId),H=q??await this.fetchProjectFromRemote(d.projectId),U=H?.metadata?.globalSystemPrompt,U&&this.logger.info("Using global system prompt from project metadata",{projectId:d.projectId,promptLength:U.length}),U=await this.agentPreambleFor(d.projectId,U),W=await this.fetchMcpServersFromRemote(d.projectId),G=(await this.fetchDefaultWorkflowFromRemote(d.projectId))?.connectionPermissions??null,B=await this.fetchAgentsFromRemote(d.projectId),B&&B.length>0){this.logger.info("Using agents from remote database",{count:B.length})
|
|
7933
|
+
const e=await this.resolveWorkflowEffort(d.projectId)
|
|
7915
7934
|
this.clearAgentMarkdowns()
|
|
7916
|
-
for(const t of
|
|
7917
|
-
await this.removeOnDiskAgentFiles(
|
|
7918
|
-
try{const e=new Set([...
|
|
7919
|
-
for(const t of await
|
|
7920
|
-
try{await
|
|
7935
|
+
for(const t of B)t.enabled&&this.setAgentMarkdown(t.name,this.generateAgentMarkdown(t,I,L,U,{effort:e,extraTools:(0,l.agentToolGrants)(W,t.name,G),limits:(0,a.modelLimitsOf)(H?.metadata),claudeThinking:r(H?.metadata)}))
|
|
7936
|
+
await this.removeOnDiskAgentFiles(F,[...B.filter(e=>e.enabled).map(e=>e.name),"explore"]),this.logger.info("Agent prompts held in memory (served to OpenCode over the action server)",{count:this.agentMarkdowns.size})
|
|
7937
|
+
try{const e=new Set([...B.filter(e=>e.enabled).map(e=>`${e.name}.md`),"explore.md"])
|
|
7938
|
+
for(const t of await v.readdir(F))if(t.endsWith(".md")&&!e.has(t)){const e=k.join(F,t),r=`${e}.removed-by-alchemy-${(new Date).toISOString().slice(0,10)}`
|
|
7939
|
+
try{await v.rename(e,r),this.logger.info(`Moved agent file ${t} aside (no agent by that name)`,{movedTo:r})}catch(e){this.logger.warn(`Could not move agent file ${t} aside; leaving it`,{error:e instanceof Error?e.message:String(e)})}}}catch(e){this.logger.warn("Orphaned agent-file cleanup failed",{error:e instanceof Error?e.message:String(e)})}}else this.logger.warn("No agents found - check remote server or enable agents via UI")
|
|
7921
7940
|
else this.logger.warn("No projectId provided - agents must be configured via database")
|
|
7922
|
-
const
|
|
7923
|
-
|
|
7924
|
-
const
|
|
7925
|
-
if(
|
|
7926
|
-
for(const e of
|
|
7941
|
+
const K={$schema:"https://opencode.ai/config.json",share:"disabled",model:N,mcp:{[I]:{type:"local",command:[c,$,n],enabled:!0,timeout:6e5}}}
|
|
7942
|
+
S&&process.env.REMOTE_SERVER_URL&&(K.mcp[I].environment={REMOTE_SERVER_URL:process.env.REMOTE_SERVER_URL})
|
|
7943
|
+
const z=d?.projectId?await this.fetchDefaultWorkflowFromRemote(d.projectId):null,V=!1!==z?.webAccess
|
|
7944
|
+
if(K.permission={...K.permission??{},bash:"deny"},Object.assign(K.permission,(0,l.globalDenyRules)(W)),B&&B.length>0){K.agent={}
|
|
7945
|
+
for(const e of B){if(!e.enabled)continue
|
|
7927
7946
|
const t={}
|
|
7928
7947
|
for(const[r,s]of Object.entries(e.tools||{})){const e=s,n=r.replace(/-/g,"_")
|
|
7929
|
-
t[
|
|
7930
|
-
Object.assign(t,(0,
|
|
7931
|
-
const e=this.buildExploreMarkdown(
|
|
7932
|
-
this.setAgentMarkdown("explore",e),this.logger.info("Explore agent override held in memory"),this.logger.info("Added agent tools to opencode.json",{agentCount:Object.keys(
|
|
7933
|
-
|
|
7934
|
-
try{const e=["opencode.jsonc",".opencode/opencode.json",".opencode/opencode.jsonc",".opencode/plugin",".opencode/tool",".opencode/command"].filter(e=>(0,
|
|
7935
|
-
e.length>0&&this.logger.warn("This repository carries OpenCode config the AlchemyLab runtime does not load (only the generated config is read)",{ignored:e})}catch{}
|
|
7936
|
-
return[...new Set([r,...s])]}(
|
|
7937
|
-
const
|
|
7938
|
-
|
|
7939
|
-
const
|
|
7940
|
-
await
|
|
7941
|
-
try{const e=await Promise.resolve().then(()=>t.t(70857,23)),r=
|
|
7948
|
+
t[b.OPENCODE_BUILTIN_TOOLS.has(r)?r:`${I}_${n}`]=e}if(!V)for(const e of b.WEB_TOOLS)t[b.OPENCODE_BUILTIN_TOOLS.has(e)?e:`${I}_${e}`]=!1
|
|
7949
|
+
Object.assign(t,(0,l.agentToolGrants)(W,e.name,G)),t.skill=!1,("subagent"===e.mode||"tester"===e.name||"auto-tester"===e.name||"reviewer"===e.name||"criteria-reviewer"===e.name)&&void 0===t.task&&(t.task=!1),K.agent[e.name]={tools:t,...e.description?{description:e.description}:{},mode:"utility"===e.mode?"primary":e.mode||"primary",...e.color?{color:e.color}:{}}}K.agent.general={...K.agent.general,disable:!0},K.agent.explore={...K.agent.explore,tools:{grep:!1,glob:!1,list:!1,read:!1,bash:!1,[`${I}_search`]:!0,[`${I}_read_files`]:!0,[`${I}_view_asset`]:!0,[`${I}_query_history`]:!0,webfetch:!0,websearch:!0,codesearch:!0}}
|
|
7950
|
+
const e=this.buildExploreMarkdown(U)
|
|
7951
|
+
this.setAgentMarkdown("explore",e),this.logger.info("Explore agent override held in memory"),this.logger.info("Added agent tools to opencode.json",{agentCount:Object.keys(K.agent).length})}const Y=e=>"string"==typeof e&&e.includes(".opencode/plugin/"),J=(await this.fetchPluginManifest())["opencode-claude-auth"],X=K.plugin,Q=Array.isArray(X)?X.filter(e=>!Y(e)):[]
|
|
7952
|
+
J&&this.applyAuthPluginPin(Q,J),Q.length>0?K.plugin=Q:delete K.plugin
|
|
7953
|
+
try{const e=["opencode.jsonc",".opencode/opencode.json",".opencode/opencode.jsonc",".opencode/plugin",".opencode/tool",".opencode/command"].filter(e=>(0,u.existsSync)(k.join(n,e)))
|
|
7954
|
+
e.length>0&&this.logger.warn("This repository carries OpenCode config the AlchemyLab runtime does not load (only the generated config is read)",{ignored:e})}catch{}K.instructions=function(e,t){const r=["AGENTS.md","CLAUDE.md","CONTEXT.md"].map(t=>(0,h.join)(e,t)).find(e=>(0,u.existsSync)(e))??(0,h.join)(e,"AGENTS.md"),s=(Array.isArray(t)?t:[]).filter(e=>"string"==typeof e&&e.trim().length>0).map(t=>t.startsWith("~/")||(0,h.isAbsolute)(t)?t:(0,h.join)(e,t))
|
|
7955
|
+
return[...new Set([r,...s])]}(n,T.instructions)
|
|
7956
|
+
const Z=[".opencode/skill",".opencode/skills",".claude/skills",".agents/skills"].map(e=>k.join(n,e)).filter(e=>(0,u.existsSync)(e))
|
|
7957
|
+
Z.length>0&&(K.skills={paths:Z})
|
|
7958
|
+
const ee={...T,...K}
|
|
7959
|
+
s(ee,(y=H?.metadata,!0===y?.anthropicCompaction)),await v.mkdir(k.dirname(j),{recursive:!0}),await v.writeFile(j,JSON.stringify(ee,null,2),"utf8"),this.logger.info("OpenCode configured successfully",{configPath:j})
|
|
7960
|
+
try{const e=await Promise.resolve().then(()=>t.t(70857,23)),r=k.join(e.homedir(),".alchemy_lab","opencode","config"),s=k.join(r,"opencode.json")
|
|
7942
7961
|
let n=null
|
|
7943
|
-
try{n=JSON.parse(await
|
|
7944
|
-
|
|
7945
|
-
try{const t=await
|
|
7946
|
-
e=JSON.parse(t)}catch{}e.openCodeTools||(e.openCodeTools=
|
|
7947
|
-
o.errors.length>0&&this.logger.warn("Some plugins failed to sync",{errors:o.errors}),await n
|
|
7962
|
+
try{n=JSON.parse(await v.readFile(s,"utf-8"))}catch{}const o=n??{},i=Array.isArray(o.plugin)?o.plugin.slice():[],a=i.filter(e=>!Y(e))
|
|
7963
|
+
J&&this.applyAuthPluginPin(a,J),i.length===a.length&&!i.some((e,t)=>e!==a[t])&&n||(o.plugin=a,await v.mkdir(r,{recursive:!0}),await v.writeFile(s,JSON.stringify(o,null,2),"utf8"),this.logger.info("Updated global opencode config plugin list",{globalConfigPath:s,plugins:a}))}catch(e){this.logger.warn("Failed to update global alchemy opencode config",{error:e instanceof Error?e.message:"Unknown error"})}if(M&&!d)try{let e={}
|
|
7964
|
+
try{const t=await v.readFile(R,"utf-8")
|
|
7965
|
+
e=JSON.parse(t)}catch{}e.openCodeTools||(e.openCodeTools=P,await v.writeFile(R,JSON.stringify(e,null,2),"utf8"),this.logger.info("Created project config with default tool settings",{projectConfigPath:R}))}catch(e){this.logger.warn("Failed to create project config",{error:e instanceof Error?e.message:"Unknown error"})}try{const{syncPluginsGlobal:r,cleanupLegacyProjectPlugins:s}=await t.e(939).then(()=>t.t(49939,23)),o=await r(S??!1,this.logger,e)
|
|
7966
|
+
o.errors.length>0&&this.logger.warn("Some plugins failed to sync",{errors:o.errors}),await s(n,this.logger)}catch(e){this.logger.warn("Plugin sync failed during OpenCode config",{error:e instanceof Error?e.message:"Unknown error"})}return{success:!0,configPath:j}}catch(e){return this.logger.error("Failed to configure OpenCode",{error:(0,o.getErrorMessage)(e)}),{success:!1,error:(0,o.getErrorMessage)(e)}}var y}}exports.MCPClientConfigurer=b,b.WEB_TOOLS=["webfetch","websearch","codesearch","capture_site","read_site","fetch_asset"],b.OPENCODE_BUILTIN_TOOLS=new Set(["glob","grep","ls","list","view","read","write","edit","patch","diagnostics","sourcegraph","bash","webfetch","websearch","codesearch","agent","task","question","todoread","todowrite"]),b.rerouteLogged=new Set},6688(e,exports,t){"use strict"
|
|
7948
7967
|
exports.sessionIdentity=void 0
|
|
7949
7968
|
const r=t(16698),s=t(79896),n=t(16928),o=t(43545),i=t(79414),a=t(87280)
|
|
7950
7969
|
class c{constructor(){this.parentCache=new Map,this.sessionRequestCache=new Map,this.endedUnderSession=new Map,this.callScope=new r.AsyncLocalStorage,this.agentTypeCache=new Map}setIdentity(e){const t=this.identity
|
|
@@ -8019,10 +8038,10 @@ t.info("UnifiedLauncher: reaping stale serve from a previous action-server life"
|
|
|
8019
8038
|
try{process.kill(-n,"SIGTERM")}catch{try{process.kill(n,"SIGTERM")}catch{}}await new Promise(e=>setTimeout(e,1500))
|
|
8020
8039
|
try{process.kill(n,0)
|
|
8021
8040
|
try{process.kill(-n,"SIGKILL")}catch{try{process.kill(n,"SIGKILL")}catch{}}t.warn("UnifiedLauncher: stale serve needed SIGKILL",{pid:n})}catch{}}catch(e){t.warn("UnifiedLauncher: stale-serve reap failed (continuing with launch)",{error:(0,m.getErrorMessage)(e)})}}(w,this.logger)
|
|
8022
|
-
const{resolveServeCommand:v,findOpencodeDir:k}=await Promise.resolve().then(()=>t(39068))
|
|
8041
|
+
const{resolveServeCommand:v,findOpencodeDir:k,lastEnginePatchState:S}=await Promise.resolve().then(()=>t(39068))
|
|
8023
8042
|
if(!k())try{(0,f.execFileSync)("win32"===process.platform?"where":"which",["opencode"],{stdio:"pipe"})}catch{return{success:!1,error:"alchemylab-opencode package not installed and no system `opencode` on PATH."}}this.logger.info("UnifiedLauncher: Launching opencode serve in background",{command:"opencode serve",cwd:w})
|
|
8024
|
-
const
|
|
8025
|
-
return new Promise(t=>{const v=l.default.join(w,".alchemy_lab","opencode"),k=process.env.XDG_DATA_HOME||l.default.join(d.default.homedir(),".local","share")
|
|
8043
|
+
const I=v(),$=S()
|
|
8044
|
+
return"applied"===$?.state?this.logger.info("UnifiedLauncher: applied the engine's dependency patches (its install script had not run)",{dir:$.dir,output:$.detail}):"failed"===$?.state&&this.logger.warn("UnifiedLauncher: the engine's dependency patches could not be applied; it starts without them",{dir:$.dir,error:$.detail}),new Promise(t=>{const v=l.default.join(w,".alchemy_lab","opencode"),k=process.env.XDG_DATA_HOME||l.default.join(d.default.homedir(),".local","share")
|
|
8026
8045
|
try{u.default.mkdirSync(l.default.join(k,"opencode"),{recursive:!0})}catch(e){this.logger.warn("UnifiedLauncher: Could not pre-create opencode globalData dir",{error:(0,m.getErrorMessage)(e)})}try{!function(e){const t=function(){const e=l.default.join(d.default.homedir(),".alchemy_lab","opencode","config","opencode.json")
|
|
8027
8046
|
try{const t=JSON.parse(u.default.readFileSync(e,"utf-8"))
|
|
8028
8047
|
if(Array.isArray(t.plugin)){const e=t.plugin.find(e=>"string"==typeof e&&/^opencode-claude-auth@/.test(e))
|
|
@@ -8031,15 +8050,15 @@ if(-1!==t)return e.slice(t+1)}}}catch{}return"1.5.3"}(),i=l.default.join(d.defau
|
|
|
8031
8050
|
if(!u.default.existsSync(c))try{u.default.mkdirSync(a,{recursive:!0}),u.default.writeFileSync(l.default.join(a,"package.json"),JSON.stringify({name:"alchemylab-claude-auth-wrapper",private:!0,version:"0.0.0"},null,2)),e.info("UnifiedLauncher: Pre-installing opencode-claude-auth plugin",{version:t,targetDir:a}),(0,f.execFileSync)("npm",["install",`opencode-claude-auth@${t}`,"--no-audit","--no-fund","--silent","--ignore-scripts"],{cwd:a,stdio:"pipe",timeout:12e4}),e.info("UnifiedLauncher: Pre-installed opencode-claude-auth plugin",{version:t})}catch(t){e.warn("UnifiedLauncher: claude-auth pre-install failed; opencode will install lazily and first OAuth click may crash",{error:(0,m.getErrorMessage)(t)})}if(u.default.existsSync(c)&&(r(c,e,`opencode-claude-auth@${t}`),s(l.default.join(l.default.dirname(c),"credentials.js"),e,`opencode-claude-auth@${t}`),n(c,e,`opencode-claude-auth@${t}`),o(c,e,`opencode-claude-auth@${t}`)),u.default.existsSync(i)){let t
|
|
8032
8051
|
try{t=u.default.readdirSync(i)}catch{return}for(const a of t){if(!a.startsWith("opencode-claude-auth@"))continue
|
|
8033
8052
|
const t=l.default.join(i,a,"node_modules","opencode-claude-auth","dist","index.js")
|
|
8034
|
-
t!==c&&(r(t,e,a),s(l.default.join(l.default.dirname(t),"credentials.js"),e,a),n(t,e,a),o(t,e,a))}}}(this.logger)}catch(e){this.logger.warn("UnifiedLauncher: claude-auth ensure-patched failed",{error:(0,m.getErrorMessage)(e)})}const
|
|
8053
|
+
t!==c&&(r(t,e,a),s(l.default.join(l.default.dirname(t),"credentials.js"),e,a),n(t,e,a),o(t,e,a))}}}(this.logger)}catch(e){this.logger.warn("UnifiedLauncher: claude-auth ensure-patched failed",{error:(0,m.getErrorMessage)(e)})}const S=l.default.join(v,"log"),$=l.default.join(S,"opencode-serve.log")
|
|
8035
8054
|
let j=null,E=0
|
|
8036
8055
|
const A=e=>{if(!j)return
|
|
8037
8056
|
const t=j
|
|
8038
8057
|
j=null,t.end(e)},C=e=>{u.default.writeFileSync($,e),j=u.default.createWriteStream($,{flags:"a"}),E=e.length},_=e=>{if(j&&(E+=e.length,j.write(e),E>=20971520))try{const e=j
|
|
8039
8058
|
j=null,e.end(),u.default.renameSync($,`${$}.1`),C(`# opencode-serve.log \u2014 rotated ${(new Date).toISOString()} (previous in opencode-serve.log.1)\n`)}catch(e){this.logger.warn("UnifiedLauncher: opencode log rotation failed; logging stops for this launch",{error:(0,m.getErrorMessage)(e)})}}
|
|
8040
|
-
try{u.default.mkdirSync(
|
|
8059
|
+
try{u.default.mkdirSync(S,{recursive:!0}),C(`# opencode-serve.log \u2014 launched ${(new Date).toISOString()}\n`)}catch(e){this.logger.warn("UnifiedLauncher: Could not open opencode log file",{error:(0,m.getErrorMessage)(e)})}const T=process.env.ALCHEMY_OPENCODE_LOG_LEVEL||"WARN",x=(0,g.newServePassword)()
|
|
8041
8060
|
try{(0,g.writeServeAuth)(w,x)}catch(e){this.logger.warn("UnifiedLauncher: could not record the serve password on disk; only this process can reach the serve",{error:(0,m.getErrorMessage)(e)})}(0,g.noteServe)(null,x),(0,c.noteServeLoadedLogins)()
|
|
8042
|
-
const M=(0,f.spawn)(
|
|
8061
|
+
const M=(0,f.spawn)(I.command,[...I.prependArgs,"--port","0","--data-dir",v,"--log-level",T],{stdio:["ignore","pipe","pipe"],cwd:w,detached:!0,env:{...process.env,...(0,p.getOpencodeSpawnEnv)(w,(0,h.isDevMode)()),...y,OPENCODE_SERVER_PASSWORD:x}})
|
|
8043
8062
|
let R="",P=!1
|
|
8044
8063
|
if(M.pid)try{const e=l.default.join(w,b,"opencode.json")
|
|
8045
8064
|
u.default.mkdirSync(l.default.dirname(e),{recursive:!0}),u.default.writeFileSync(e,JSON.stringify({pid:M.pid,port:null,startedAt:(new Date).toISOString()},null,2))}catch(e){this.logger.warn("UnifiedLauncher: could not record the serve pid (an orphan would survive a crash)",{error:(0,m.getErrorMessage)(e)})}const O=e=>{if(P)return
|
|
@@ -8165,16 +8184,16 @@ return e.ok?e.version??"":a(3e4)}():await async function(){if(console.log(" In
|
|
|
8165
8184
|
const e=await o()
|
|
8166
8185
|
return e.ok?e.version??"":e.permissionDenied?(c(),null):a(15e3)}()}return null!==h?(console.log("\u2705 Docker ready"+(h?` (server v${h})`:"")),{status:"ready",version:h}):{status:"unavailable",reason:"setup did not complete"}}
|
|
8167
8186
|
const d=t(35317),u=t(79896),h=t(23785)},89063(e,exports){"use strict"
|
|
8168
|
-
function t(e){return exports.lS[String(e??"").toLowerCase()]??exports.Ey}function
|
|
8169
|
-
return
|
|
8187
|
+
function t(e){return"assistant"===e?.role&&!0===e?.summary}function r(e){return exports.lS[String(e??"").toLowerCase()]??exports.Ey}function s(e){const t=r(e).atLeast
|
|
8188
|
+
return t-Math.min(5*n,t/10)}exports.Ey=exports.lS=void 0,exports.tokensOfMessage=function(e){const t={input:0,output:0,reasoning:0,cacheRead:0,cacheWrite:0,cost:0,hasUsage:!1}
|
|
8170
8189
|
for(const r of e?.parts||[])if("step-finish"===r?.type&&r?.tokens){t.hasUsage=!0
|
|
8171
8190
|
const e=r.tokens
|
|
8172
8191
|
t.input+=e.input||0,t.output+=e.output||0,t.reasoning+=e.reasoning||0,t.cacheRead+=e.cache?.read||0,t.cacheWrite+=e.cache?.write||0,t.cost+=r.cost||0}const r=e?.info
|
|
8173
8192
|
if(!t.hasUsage&&r?.tokens){const e=r.tokens
|
|
8174
|
-
t.input=e.input||0,t.output=e.output||0,t.reasoning=e.reasoning||0,t.cacheRead=e.cache?.read||0,t.cacheWrite=e.cache?.write||0,t.cost=r.cost||0,t.hasUsage=t.input>0||t.output>0||t.cacheRead>0||t.cacheWrite>0||t.cost>0}return t},exports.contextTokensOf=function(e){const
|
|
8175
|
-
return(
|
|
8176
|
-
const
|
|
8177
|
-
exports.lS={anthropic:{atLeast:60*
|
|
8193
|
+
t.input=e.input||0,t.output=e.output||0,t.reasoning=e.reasoning||0,t.cacheRead=e.cache?.read||0,t.cacheWrite=e.cache?.write||0,t.cost=r.cost||0,t.hasUsage=t.input>0||t.output>0||t.cacheRead>0||t.cacheWrite>0||t.cost>0}return t},exports.contextTokensOf=function(e){const r=e?.tokens||{}
|
|
8194
|
+
return t(e)?r.output??0:(r.input??0)+(r.cache?.read??0)},exports.isCompactionSummary=t,exports.cacheRetentionMsFor=function(e){return r(e).atMost},exports.cacheWarmForMs=s,exports.longestCacheWarmMs=function(){return Math.max(s(null),...Object.keys(exports.lS).map(s))}
|
|
8195
|
+
const n=6e4
|
|
8196
|
+
exports.lS={anthropic:{atLeast:60*n,atMost:65*n},openai:{atLeast:60*n,atMost:90*n}},exports.Ey={atLeast:5*n,atMost:60*n}},75632(e,exports){"use strict"
|
|
8178
8197
|
exports.REGISTER_BY_SETUP_RUN=exports.b=void 0,exports.toolScopesFor=function(e,t,r){const s=exports.b[e]
|
|
8179
8198
|
if(!s)return{}
|
|
8180
8199
|
const n={}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alchemylab",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "AlchemyLab: the agentic workbench. Work is a request, with criteria, gates and a receipt.",
|
|
6
6
|
"author": "Testfire Software",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
50
|
-
"alchemylab-opencode": "^
|
|
50
|
+
"alchemylab-opencode": "^2.0.0",
|
|
51
51
|
"chalk": "^4.1.2",
|
|
52
52
|
"compression": "^1.8.2",
|
|
53
53
|
"cors": "^2.8.6",
|