alchemylab 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1502,7 +1502,7 @@ for(const e of T){if(!e.enabled)continue
1502
1502
  const t=this.generateAgentMarkdown(e,d,S,k),s=c.join(C,e.name+".md")
1503
1503
  await r.writeFile(s,t,"utf8"),this.logger.info(`Created ${e.name} agent file from remote config`,{agentPath:s,mode:e.mode})}}else this.logger.warn("No agents found - check remote server or enable agents via UI")
1504
1504
  else this.logger.warn("No projectId provided - agents must be configured via database")
1505
- const j={$schema:"https://opencode.ai/config.json",model:E,mcp:{[d]:{type:"local",command:[n,u,s],enabled:!0}}}
1505
+ const j={$schema:"https://opencode.ai/config.json",model:E,mcp:{[d]:{type:"local",command:[n,u,s],enabled:!0,timeout:6e5}}}
1506
1506
  if(l&&process.env.REMOTE_SERVER_URL&&(j.mcp[d].environment={REMOTE_SERVER_URL:process.env.REMOTE_SERVER_URL}),T&&T.length>0){j.agent={}
1507
1507
  for(const e of T){if(!e.enabled)continue
1508
1508
  const t={}
@@ -1342,7 +1342,7 @@ if("setup"===e.commandName){const e=process.config.setup||[]
1342
1342
  if(0===e.length)return a({success:!0}),{content:[{type:"text",text:"No setup commands configured for this test process."}]}
1343
1343
  l=e.map(((e,t)=>({name:"setup-"+(t+1),command:e,timeout:120})))}else{const t=process.config.commands||[],r=t.find((t=>t.name===e.commandName))
1344
1344
  if(!r){const r=t.map((e=>e.name)).join(", ")
1345
- return a({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}l=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{execSync:d}=await Promise.resolve().then(t.t.bind(t,5317,23)),u=globalThis.process
1345
+ return a({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}l=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{runShellCommand:d}=await Promise.resolve().then(t.bind(t,4600)),u=globalThis.process
1346
1346
  let h=null
1347
1347
  const p=[]
1348
1348
  try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
@@ -1351,9 +1351,8 @@ if(p.push("reqId: "+(t||"NONE")),t){const e=await o.proxyGet(`/api/projects/${n.
1351
1351
  p.push(`runs: ${Array.isArray(r)?r.length:0}, withWorktree: ${s?.id||"NONE"}, path: ${s?.worktreePath||s?.worktree_path||"NONE"}`),s&&(h=s.worktreePath||s.worktree_path,c.info("Using test worktree from request test run",{worktreePath:h,reqId:t}))}}}catch(e){c.warn("Failed to resolve test worktree",{error:(0,r.getErrorMessage)(e)})}if(!h)return a({success:!1,error:"no_worktree"}),{content:[{type:"text",text:`No test worktree found.\n\nDiagnostics:\n${p.length>0?p.map((e=>"\u2022 "+e)).join("\n"):"\u2022 No session identity found"}\n\nEnsure this session is linked to a test process and a test run has been created.`}],isError:!0}
1352
1352
  const g=[]
1353
1353
  for(const t of l){c.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:h})
1354
- try{const e=d(t.command,{cwd:h,timeout:1e3*t.timeout,encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:"win32"===process.platform?"cmd.exe":"/bin/sh",env:{...u.env,FORCE_COLOR:"0"}})
1355
- g.push({name:t.name,command:t.command,exitCode:0,output:e.slice(-4e3),timedOut:!1})}catch(r){const n=!0===r.killed,o=((r.stdout||"")+"\n"+(r.stderr||"")).trim().slice(-4e3),s=r.status??1
1356
- if(g.push({name:t.name,command:t.command,exitCode:s,output:o,timedOut:n}),"setup"===e.commandName)break}}const m=g.every((e=>0===e.exitCode)),f=g.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
1354
+ const r=await d(t.command,{cwd:h,timeoutMs:1e3*t.timeout,env:{...u.env,FORCE_COLOR:"0"}}),n=(r.stdout+(r.stderr?"\n"+r.stderr:"")).trim().slice(-4e3)
1355
+ if(g.push({name:t.name,command:t.command,exitCode:r.exitCode,output:n,timedOut:r.timedOut}),"setup"===e.commandName&&0!==r.exitCode)break}const m=g.every((e=>0===e.exitCode)),f=g.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
1357
1356
  return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\``})).join("\n\n")
1358
1357
  return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${m?"PASSED":"FAILED"}\n\n${f}`}]}}catch(e){return a({success:!1,error:"execution_error"}),{content:[{type:"text",text:"Failed to execute test command: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleReportTestResults=async function(e,s,i,a,c,l){const d=c.startTimer("tool_execution_time")
1359
1358
  try{const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=await u.getSessionRequestId(i,a,l?.sessionId)
@@ -2712,14 +2711,15 @@ return p({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "$
2712
2711
  e.grep&&(I=`${I} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
2713
2712
  const b=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,k=w.cwd?o.default.resolve(b,w.cwd):b
2714
2713
  l.info("Running command",{name:w.name,command:I,cwd:k,configuredCwd:w.cwd})
2715
- let v="",C="",_=0,E=!1
2716
- try{v=(0,n.execSync)(I,{cwd:k,timeout:1e3*(w.timeout||60),encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:"win32"===process.platform?"cmd.exe":"/bin/sh",env:{...process.env,FORCE_COLOR:"0"}})||""}catch(e){_=e.status??1,v=e.stdout||"",C=e.stderr||"",e.killed&&(E=!0)}const S=8e3,q=4e3
2717
- v.length>S&&(v="\u2026"+v.slice(-S)),C.length>q&&(C="\u2026"+C.slice(-q))
2718
- const T=E?"TIMEOUT":null,P=[v,C].filter(Boolean).join("\n")||"(no output)"
2719
- let x
2720
- if(u)try{const e=await u.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:w.name,command:I,exitCode:_,timedOut:E,status:E?"timeout":0===_?"success":"failed",timestamp:(new Date).toISOString()}})
2721
- x=e?.id}catch(e){l.debug("Failed to create tool record for command run",{error:(0,i.getErrorMessage)(e)})}return p({success:!0}),{content:[{type:"text",text:`## ${w.name}${T?` \u2014 ${T} (killed after ${w.timeout}s)`:""}\n\`\`\`\n$ ${I}\n${P}\n\`\`\`\n\nExit code: ${_}`}],...(0,s.alchemyMeta)({kind:"run-command",toolRecordId:x})}}catch(e){return p({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
2722
- const n=t(5317),o=r(t(6928)),s=t(2272),i=t(8824),a=t(6688),c=t(9414)},4466(e,exports,t){"use strict"
2714
+ const v=await(0,n.runShellCommand)(I,{cwd:k,timeoutMs:1e3*(w.timeout||60),env:{...process.env,FORCE_COLOR:"0"}})
2715
+ let C=v.stdout,_=v.stderr
2716
+ const E=v.exitCode,S=v.timedOut,q=8e3,T=4e3
2717
+ C.length>q&&(C="\u2026"+C.slice(-q)),_.length>T&&(_="\u2026"+_.slice(-T))
2718
+ const P=S?"TIMEOUT":null,x=[C,_].filter(Boolean).join("\n")||"(no output)"
2719
+ let j
2720
+ if(u)try{const e=await u.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:w.name,command:I,exitCode:E,timedOut:S,status:S?"timeout":0===E?"success":"failed",timestamp:(new Date).toISOString()}})
2721
+ j=e?.id}catch(e){l.debug("Failed to create tool record for command run",{error:(0,i.getErrorMessage)(e)})}return p({success:!0}),{content:[{type:"text",text:`## ${w.name}${P?` \u2014 ${P} (killed after ${w.timeout}s)`:""}\n\`\`\`\n$ ${I}\n${x}\n\`\`\`\n\nExit code: ${E}`}],...(0,s.alchemyMeta)({kind:"run-command",toolRecordId:j})}}catch(e){return p({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
2722
+ const n=t(4600),o=r(t(6928)),s=t(2272),i=t(8824),a=t(6688),c=t(9414)},4466(e,exports,t){"use strict"
2723
2723
  function r(e,t){return`${e}#${t.toString().padStart(2,"0")}`}async function n(e,t,n,s){if(exports.TASK_REF_PATTERN.test(e))return e
2724
2724
  const i=e.match(exports.TASK_REF_SHORT_PATTERN)
2725
2725
  if(!i)return e
@@ -2775,7 +2775,12 @@ return(0,i.withAlchemyKind)(f,y)}catch(e){return h.error("Planner ops failed",{e
2775
2775
  const r=t(9860),n=t(8824),o=t(6688),s=t(1725),i=t(2272),a={request:"planner-request","check-status":"planner-check-status",list:"planner-list"}},4600(e,exports,t){"use strict"
2776
2776
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.execAsync=async function(e,t={}){return new Promise(((n,o)=>{const[s,...i]=e.split(" "),a=(0,r.spawn)(s,i,{cwd:t.cwd||process.cwd(),stdio:["pipe","pipe","pipe"]})
2777
2777
  let c="",l=""
2778
- a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{n({stdout:c,stderr:l,exitCode:e||0})})),a.on("error",(t=>{o(Error(`Command failed: ${e}\nError: ${t.message}`))})),t.timeout&&setTimeout((()=>{a.kill(),o(Error("Command timed out: "+e))}),t.timeout)}))}
2778
+ a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{n({stdout:c,stderr:l,exitCode:e||0})})),a.on("error",(t=>{o(Error(`Command failed: ${e}\nError: ${t.message}`))})),t.timeout&&setTimeout((()=>{a.kill(),o(Error("Command timed out: "+e))}),t.timeout)}))},exports.runShellCommand=async function(e,r={}){const{spawn:n}=await Promise.resolve().then(t.t.bind(t,5317,23))
2779
+ return new Promise((t=>{const o="win32"===process.platform,s=n(e,{cwd:r.cwd??process.cwd(),env:r.env,shell:o?"cmd.exe":"/bin/sh",stdio:["pipe","pipe","pipe"]}),i=[],a=[]
2780
+ let c,l,d=!1,u=!1
2781
+ r.timeoutMs&&r.timeoutMs>0&&(l=setTimeout((()=>{d=!0,s.kill("SIGTERM"),c=setTimeout((()=>{u||s.kill("SIGKILL")}),2e3)}),r.timeoutMs)),s.stdout?.on("data",(e=>i.push(e))),s.stderr?.on("data",(e=>a.push(e)))
2782
+ const h=e=>{u||(u=!0,l&&clearTimeout(l),c&&clearTimeout(c),t({stdout:Buffer.concat(i).toString("utf-8"),stderr:Buffer.concat(a).toString("utf-8"),exitCode:e,timedOut:d}))}
2783
+ s.on("close",(e=>h(e??(d?124:1)))),s.on("error",(()=>h(1)))}))}
2779
2784
  const r=t(5317)},4607(e,exports,t){"use strict"
2780
2785
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
2781
2786
  const r=t(6183),n=t(3306)
package/dist/index.js CHANGED
@@ -1344,7 +1344,7 @@ if("setup"===e.commandName){const e=process.config.setup||[]
1344
1344
  if(0===e.length)return a({success:!0}),{content:[{type:"text",text:"No setup commands configured for this test process."}]}
1345
1345
  l=e.map(((e,t)=>({name:"setup-"+(t+1),command:e,timeout:120})))}else{const t=process.config.commands||[],r=t.find((t=>t.name===e.commandName))
1346
1346
  if(!r){const r=t.map((e=>e.name)).join(", ")
1347
- return a({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}l=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{execSync:d}=await Promise.resolve().then(t.t.bind(t,5317,23)),u=globalThis.process
1347
+ return a({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}l=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{runShellCommand:d}=await Promise.resolve().then(t.bind(t,4600)),u=globalThis.process
1348
1348
  let h=null
1349
1349
  const p=[]
1350
1350
  try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
@@ -1353,9 +1353,8 @@ if(p.push("reqId: "+(t||"NONE")),t){const e=await o.proxyGet(`/api/projects/${n.
1353
1353
  p.push(`runs: ${Array.isArray(r)?r.length:0}, withWorktree: ${s?.id||"NONE"}, path: ${s?.worktreePath||s?.worktree_path||"NONE"}`),s&&(h=s.worktreePath||s.worktree_path,c.info("Using test worktree from request test run",{worktreePath:h,reqId:t}))}}}catch(e){c.warn("Failed to resolve test worktree",{error:(0,r.getErrorMessage)(e)})}if(!h)return a({success:!1,error:"no_worktree"}),{content:[{type:"text",text:`No test worktree found.\n\nDiagnostics:\n${p.length>0?p.map((e=>"\u2022 "+e)).join("\n"):"\u2022 No session identity found"}\n\nEnsure this session is linked to a test process and a test run has been created.`}],isError:!0}
1354
1354
  const g=[]
1355
1355
  for(const t of l){c.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:h})
1356
- try{const e=d(t.command,{cwd:h,timeout:1e3*t.timeout,encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:"win32"===process.platform?"cmd.exe":"/bin/sh",env:{...u.env,FORCE_COLOR:"0"}})
1357
- g.push({name:t.name,command:t.command,exitCode:0,output:e.slice(-4e3),timedOut:!1})}catch(r){const n=!0===r.killed,o=((r.stdout||"")+"\n"+(r.stderr||"")).trim().slice(-4e3),s=r.status??1
1358
- if(g.push({name:t.name,command:t.command,exitCode:s,output:o,timedOut:n}),"setup"===e.commandName)break}}const m=g.every((e=>0===e.exitCode)),f=g.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
1356
+ const r=await d(t.command,{cwd:h,timeoutMs:1e3*t.timeout,env:{...u.env,FORCE_COLOR:"0"}}),n=(r.stdout+(r.stderr?"\n"+r.stderr:"")).trim().slice(-4e3)
1357
+ if(g.push({name:t.name,command:t.command,exitCode:r.exitCode,output:n,timedOut:r.timedOut}),"setup"===e.commandName&&0!==r.exitCode)break}const m=g.every((e=>0===e.exitCode)),f=g.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
1359
1358
  return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\``})).join("\n\n")
1360
1359
  return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${m?"PASSED":"FAILED"}\n\n${f}`}]}}catch(e){return a({success:!1,error:"execution_error"}),{content:[{type:"text",text:"Failed to execute test command: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleReportTestResults=async function(e,s,i,a,c,l){const d=c.startTimer("tool_execution_time")
1361
1360
  try{const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=await u.getSessionRequestId(i,a,l?.sessionId)
@@ -2719,14 +2718,15 @@ return p({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "$
2719
2718
  e.grep&&(b=`${b} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
2720
2719
  const I=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,k=w.cwd?o.default.resolve(I,w.cwd):I
2721
2720
  l.info("Running command",{name:w.name,command:b,cwd:k,configuredCwd:w.cwd})
2722
- let v="",C="",_=0,E=!1
2723
- try{v=(0,n.execSync)(b,{cwd:k,timeout:1e3*(w.timeout||60),encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:"win32"===process.platform?"cmd.exe":"/bin/sh",env:{...process.env,FORCE_COLOR:"0"}})||""}catch(e){_=e.status??1,v=e.stdout||"",C=e.stderr||"",e.killed&&(E=!0)}const S=8e3,T=4e3
2724
- v.length>S&&(v="\u2026"+v.slice(-S)),C.length>T&&(C="\u2026"+C.slice(-T))
2725
- const q=E?"TIMEOUT":null,P=[v,C].filter(Boolean).join("\n")||"(no output)"
2726
- let j
2727
- if(u)try{const e=await u.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:w.name,command:b,exitCode:_,timedOut:E,status:E?"timeout":0===_?"success":"failed",timestamp:(new Date).toISOString()}})
2728
- j=e?.id}catch(e){l.debug("Failed to create tool record for command run",{error:(0,i.getErrorMessage)(e)})}return p({success:!0}),{content:[{type:"text",text:`## ${w.name}${q?` \u2014 ${q} (killed after ${w.timeout}s)`:""}\n\`\`\`\n$ ${b}\n${P}\n\`\`\`\n\nExit code: ${_}`}],...(0,s.alchemyMeta)({kind:"run-command",toolRecordId:j})}}catch(e){return p({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
2729
- const n=t(5317),o=r(t(6928)),s=t(2272),i=t(8824),a=t(6688),c=t(9414)},4466(e,exports,t){"use strict"
2721
+ const v=await(0,n.runShellCommand)(b,{cwd:k,timeoutMs:1e3*(w.timeout||60),env:{...process.env,FORCE_COLOR:"0"}})
2722
+ let C=v.stdout,_=v.stderr
2723
+ const E=v.exitCode,S=v.timedOut,T=8e3,q=4e3
2724
+ C.length>T&&(C="\u2026"+C.slice(-T)),_.length>q&&(_="\u2026"+_.slice(-q))
2725
+ const P=S?"TIMEOUT":null,j=[C,_].filter(Boolean).join("\n")||"(no output)"
2726
+ let R
2727
+ if(u)try{const e=await u.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:w.name,command:b,exitCode:E,timedOut:S,status:S?"timeout":0===E?"success":"failed",timestamp:(new Date).toISOString()}})
2728
+ R=e?.id}catch(e){l.debug("Failed to create tool record for command run",{error:(0,i.getErrorMessage)(e)})}return p({success:!0}),{content:[{type:"text",text:`## ${w.name}${P?` \u2014 ${P} (killed after ${w.timeout}s)`:""}\n\`\`\`\n$ ${b}\n${j}\n\`\`\`\n\nExit code: ${E}`}],...(0,s.alchemyMeta)({kind:"run-command",toolRecordId:R})}}catch(e){return p({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
2729
+ const n=t(4600),o=r(t(6928)),s=t(2272),i=t(8824),a=t(6688),c=t(9414)},4466(e,exports,t){"use strict"
2730
2730
  function r(e,t){return`${e}#${t.toString().padStart(2,"0")}`}async function n(e,t,n,s){if(exports.TASK_REF_PATTERN.test(e))return e
2731
2731
  const i=e.match(exports.TASK_REF_SHORT_PATTERN)
2732
2732
  if(!i)return e
@@ -2782,7 +2782,12 @@ return(0,i.withAlchemyKind)(f,y)}catch(e){return h.error("Planner ops failed",{e
2782
2782
  const r=t(9860),n=t(8824),o=t(6688),s=t(1725),i=t(2272),a={request:"planner-request","check-status":"planner-check-status",list:"planner-list"}},4600(e,exports,t){"use strict"
2783
2783
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.execAsync=async function(e,t={}){return new Promise(((n,o)=>{const[s,...i]=e.split(" "),a=(0,r.spawn)(s,i,{cwd:t.cwd||process.cwd(),stdio:["pipe","pipe","pipe"]})
2784
2784
  let c="",l=""
2785
- a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{n({stdout:c,stderr:l,exitCode:e||0})})),a.on("error",(t=>{o(Error(`Command failed: ${e}\nError: ${t.message}`))})),t.timeout&&setTimeout((()=>{a.kill(),o(Error("Command timed out: "+e))}),t.timeout)}))}
2785
+ a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{n({stdout:c,stderr:l,exitCode:e||0})})),a.on("error",(t=>{o(Error(`Command failed: ${e}\nError: ${t.message}`))})),t.timeout&&setTimeout((()=>{a.kill(),o(Error("Command timed out: "+e))}),t.timeout)}))},exports.runShellCommand=async function(e,r={}){const{spawn:n}=await Promise.resolve().then(t.t.bind(t,5317,23))
2786
+ return new Promise((t=>{const o="win32"===process.platform,s=n(e,{cwd:r.cwd??process.cwd(),env:r.env,shell:o?"cmd.exe":"/bin/sh",stdio:["pipe","pipe","pipe"]}),i=[],a=[]
2787
+ let c,l,d=!1,u=!1
2788
+ r.timeoutMs&&r.timeoutMs>0&&(l=setTimeout((()=>{d=!0,s.kill("SIGTERM"),c=setTimeout((()=>{u||s.kill("SIGKILL")}),2e3)}),r.timeoutMs)),s.stdout?.on("data",(e=>i.push(e))),s.stderr?.on("data",(e=>a.push(e)))
2789
+ const h=e=>{u||(u=!0,l&&clearTimeout(l),c&&clearTimeout(c),t({stdout:Buffer.concat(i).toString("utf-8"),stderr:Buffer.concat(a).toString("utf-8"),exitCode:e,timedOut:d}))}
2790
+ s.on("close",(e=>h(e??(d?124:1)))),s.on("error",(()=>h(1)))}))}
2786
2791
  const r=t(5317)},4607(e,exports,t){"use strict"
2787
2792
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
2788
2793
  const r=t(6183),n=t(3306)
@@ -1241,7 +1241,7 @@ if("setup"===e.commandName){const e=process.config.setup||[]
1241
1241
  if(0===e.length)return a({success:!0}),{content:[{type:"text",text:"No setup commands configured for this test process."}]}
1242
1242
  l=e.map(((e,t)=>({name:"setup-"+(t+1),command:e,timeout:120})))}else{const t=process.config.commands||[],r=t.find((t=>t.name===e.commandName))
1243
1243
  if(!r){const r=t.map((e=>e.name)).join(", ")
1244
- return a({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}l=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{execSync:d}=await Promise.resolve().then(t.t.bind(t,5317,23)),u=globalThis.process
1244
+ return a({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}l=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{runShellCommand:d}=await Promise.resolve().then(t.bind(t,4600)),u=globalThis.process
1245
1245
  let h=null
1246
1246
  const p=[]
1247
1247
  try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
@@ -1250,9 +1250,8 @@ if(p.push("reqId: "+(t||"NONE")),t){const e=await o.proxyGet(`/api/projects/${n.
1250
1250
  p.push(`runs: ${Array.isArray(r)?r.length:0}, withWorktree: ${s?.id||"NONE"}, path: ${s?.worktreePath||s?.worktree_path||"NONE"}`),s&&(h=s.worktreePath||s.worktree_path,c.info("Using test worktree from request test run",{worktreePath:h,reqId:t}))}}}catch(e){c.warn("Failed to resolve test worktree",{error:(0,r.getErrorMessage)(e)})}if(!h)return a({success:!1,error:"no_worktree"}),{content:[{type:"text",text:`No test worktree found.\n\nDiagnostics:\n${p.length>0?p.map((e=>"\u2022 "+e)).join("\n"):"\u2022 No session identity found"}\n\nEnsure this session is linked to a test process and a test run has been created.`}],isError:!0}
1251
1251
  const g=[]
1252
1252
  for(const t of l){c.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:h})
1253
- try{const e=d(t.command,{cwd:h,timeout:1e3*t.timeout,encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:"win32"===process.platform?"cmd.exe":"/bin/sh",env:{...u.env,FORCE_COLOR:"0"}})
1254
- g.push({name:t.name,command:t.command,exitCode:0,output:e.slice(-4e3),timedOut:!1})}catch(r){const n=!0===r.killed,o=((r.stdout||"")+"\n"+(r.stderr||"")).trim().slice(-4e3),s=r.status??1
1255
- if(g.push({name:t.name,command:t.command,exitCode:s,output:o,timedOut:n}),"setup"===e.commandName)break}}const m=g.every((e=>0===e.exitCode)),f=g.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
1253
+ const r=await d(t.command,{cwd:h,timeoutMs:1e3*t.timeout,env:{...u.env,FORCE_COLOR:"0"}}),n=(r.stdout+(r.stderr?"\n"+r.stderr:"")).trim().slice(-4e3)
1254
+ if(g.push({name:t.name,command:t.command,exitCode:r.exitCode,output:n,timedOut:r.timedOut}),"setup"===e.commandName&&0!==r.exitCode)break}const m=g.every((e=>0===e.exitCode)),f=g.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
1256
1255
  return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\``})).join("\n\n")
1257
1256
  return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${m?"PASSED":"FAILED"}\n\n${f}`}]}}catch(e){return a({success:!1,error:"execution_error"}),{content:[{type:"text",text:"Failed to execute test command: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleReportTestResults=async function(e,s,i,a,c,l){const d=c.startTimer("tool_execution_time")
1258
1257
  try{const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=await u.getSessionRequestId(i,a,l?.sessionId)
@@ -2488,14 +2487,15 @@ return p({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "$
2488
2487
  e.grep&&(b=`${b} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
2489
2488
  const I=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,k=w.cwd?o.default.resolve(I,w.cwd):I
2490
2489
  l.info("Running command",{name:w.name,command:b,cwd:k,configuredCwd:w.cwd})
2491
- let v="",C="",_=0,E=!1
2492
- try{v=(0,n.execSync)(b,{cwd:k,timeout:1e3*(w.timeout||60),encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:"win32"===process.platform?"cmd.exe":"/bin/sh",env:{...process.env,FORCE_COLOR:"0"}})||""}catch(e){_=e.status??1,v=e.stdout||"",C=e.stderr||"",e.killed&&(E=!0)}const S=8e3,q=4e3
2493
- v.length>S&&(v="\u2026"+v.slice(-S)),C.length>q&&(C="\u2026"+C.slice(-q))
2494
- const T=E?"TIMEOUT":null,x=[v,C].filter(Boolean).join("\n")||"(no output)"
2495
- let P
2496
- if(u)try{const e=await u.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:w.name,command:b,exitCode:_,timedOut:E,status:E?"timeout":0===_?"success":"failed",timestamp:(new Date).toISOString()}})
2497
- P=e?.id}catch(e){l.debug("Failed to create tool record for command run",{error:(0,i.getErrorMessage)(e)})}return p({success:!0}),{content:[{type:"text",text:`## ${w.name}${T?` \u2014 ${T} (killed after ${w.timeout}s)`:""}\n\`\`\`\n$ ${b}\n${x}\n\`\`\`\n\nExit code: ${_}`}],...(0,s.alchemyMeta)({kind:"run-command",toolRecordId:P})}}catch(e){return p({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
2498
- const n=t(5317),o=r(t(6928)),s=t(2272),i=t(8824),a=t(6688),c=t(9414)},4466(e,exports,t){"use strict"
2490
+ const v=await(0,n.runShellCommand)(b,{cwd:k,timeoutMs:1e3*(w.timeout||60),env:{...process.env,FORCE_COLOR:"0"}})
2491
+ let C=v.stdout,_=v.stderr
2492
+ const E=v.exitCode,S=v.timedOut,q=8e3,T=4e3
2493
+ C.length>q&&(C="\u2026"+C.slice(-q)),_.length>T&&(_="\u2026"+_.slice(-T))
2494
+ const x=S?"TIMEOUT":null,P=[C,_].filter(Boolean).join("\n")||"(no output)"
2495
+ let R
2496
+ if(u)try{const e=await u.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:w.name,command:b,exitCode:E,timedOut:S,status:S?"timeout":0===E?"success":"failed",timestamp:(new Date).toISOString()}})
2497
+ R=e?.id}catch(e){l.debug("Failed to create tool record for command run",{error:(0,i.getErrorMessage)(e)})}return p({success:!0}),{content:[{type:"text",text:`## ${w.name}${x?` \u2014 ${x} (killed after ${w.timeout}s)`:""}\n\`\`\`\n$ ${b}\n${P}\n\`\`\`\n\nExit code: ${E}`}],...(0,s.alchemyMeta)({kind:"run-command",toolRecordId:R})}}catch(e){return p({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,i.getErrorMessage)(e)}],isError:!0}}}
2498
+ const n=t(4600),o=r(t(6928)),s=t(2272),i=t(8824),a=t(6688),c=t(9414)},4466(e,exports,t){"use strict"
2499
2499
  function r(e,t){return`${e}#${t.toString().padStart(2,"0")}`}async function n(e,t,n,s){if(exports.TASK_REF_PATTERN.test(e))return e
2500
2500
  const i=e.match(exports.TASK_REF_SHORT_PATTERN)
2501
2501
  if(!i)return e
@@ -2551,7 +2551,12 @@ return(0,i.withAlchemyKind)(f,y)}catch(e){return h.error("Planner ops failed",{e
2551
2551
  const r=t(9860),n=t(8824),o=t(6688),s=t(1725),i=t(2272),a={request:"planner-request","check-status":"planner-check-status",list:"planner-list"}},4600(e,exports,t){"use strict"
2552
2552
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.execAsync=async function(e,t={}){return new Promise(((n,o)=>{const[s,...i]=e.split(" "),a=(0,r.spawn)(s,i,{cwd:t.cwd||process.cwd(),stdio:["pipe","pipe","pipe"]})
2553
2553
  let c="",l=""
2554
- a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{n({stdout:c,stderr:l,exitCode:e||0})})),a.on("error",(t=>{o(Error(`Command failed: ${e}\nError: ${t.message}`))})),t.timeout&&setTimeout((()=>{a.kill(),o(Error("Command timed out: "+e))}),t.timeout)}))}
2554
+ a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{n({stdout:c,stderr:l,exitCode:e||0})})),a.on("error",(t=>{o(Error(`Command failed: ${e}\nError: ${t.message}`))})),t.timeout&&setTimeout((()=>{a.kill(),o(Error("Command timed out: "+e))}),t.timeout)}))},exports.runShellCommand=async function(e,r={}){const{spawn:n}=await Promise.resolve().then(t.t.bind(t,5317,23))
2555
+ return new Promise((t=>{const o="win32"===process.platform,s=n(e,{cwd:r.cwd??process.cwd(),env:r.env,shell:o?"cmd.exe":"/bin/sh",stdio:["pipe","pipe","pipe"]}),i=[],a=[]
2556
+ let c,l,d=!1,u=!1
2557
+ r.timeoutMs&&r.timeoutMs>0&&(l=setTimeout((()=>{d=!0,s.kill("SIGTERM"),c=setTimeout((()=>{u||s.kill("SIGKILL")}),2e3)}),r.timeoutMs)),s.stdout?.on("data",(e=>i.push(e))),s.stderr?.on("data",(e=>a.push(e)))
2558
+ const h=e=>{u||(u=!0,l&&clearTimeout(l),c&&clearTimeout(c),t({stdout:Buffer.concat(i).toString("utf-8"),stderr:Buffer.concat(a).toString("utf-8"),exitCode:e,timedOut:d}))}
2559
+ s.on("close",(e=>h(e??(d?124:1)))),s.on("error",(()=>h(1)))}))}
2555
2560
  const r=t(5317)},4607(e,exports,t){"use strict"
2556
2561
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
2557
2562
  const r=t(6183),n=t(3306)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alchemylab",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "private": false,
5
5
  "description": "AlchemyLab - agentic coding IDEm",
6
6
  "author": "Testfire Software",
@@ -31,7 +31,7 @@
31
31
  "build": "npm run build:dev",
32
32
  "build:dev": "tsc -p tsconfig.json && chmod +x dist-dev/*.js",
33
33
  "dev:watch": "tsc -p tsconfig.json --watch",
34
- "build:prod": "webpack --mode=production && chmod +x dist/*.js && npm run copy:plugins",
34
+ "build:prod": "npm run build:dev && webpack --mode=production && chmod +x dist/*.js && npm run copy:plugins",
35
35
  "copy:plugins": "mkdir -p dist/plugins/hooks/lib && cp dist-dev/plugins/hooks/plugin.js dist/plugins/hooks/ && cp dist-dev/plugins/hooks/lib/*.js dist/plugins/hooks/lib/ && cp dist-dev/plugins/inject-session.js dist/plugins/ && cp dist-dev/plugins/system-logger.js dist/plugins/",
36
36
  "build:analyze": "ANALYZE=true webpack --mode=production",
37
37
  "test": "npm run build:dev && mocha --require ts-node/register test/**/*.test.ts",