alchemylab 1.4.2 → 1.4.3
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 +129 -102
- package/dist/http-server.js +62 -50
- package/dist/index.js +620 -608
- package/dist/mcp-direct.js +590 -578
- package/package.json +1 -1
- package/dist/640.js +0 -14
package/dist/http-server.js
CHANGED
|
@@ -1349,12 +1349,17 @@ try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.ge
|
|
|
1349
1349
|
if(p.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
|
|
1350
1350
|
if(p.push("reqId: "+(t||"NONE")),t){const e=await o.proxyGet(`/api/projects/${n.projectId}/requests/${t}/test-runs`),r=e?.data||e||[],s=Array.isArray(r)?r.find((e=>e.worktreePath||e.worktree_path)):null
|
|
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
|
-
const g=[]
|
|
1352
|
+
const g=[],{default:m}=await Promise.resolve().then(t.t.bind(t,6928,23)),{default:f}=await Promise.resolve().then(t.t.bind(t,9896,23)),{ALCHEMY_DIR_NAME:y}=await Promise.resolve().then(t.bind(t,4139)),w=m.join(h,y,"command-logs")
|
|
1353
|
+
try{f.mkdirSync(w,{recursive:!0})}catch{}const{runTrackedShellCommand:I}=await Promise.resolve().then(t.bind(t,4600)),{sessionIdentity:b}=await Promise.resolve().then(t.bind(t,6688)),k=b.getIdentity()?.sessionId
|
|
1353
1354
|
for(const t of l){c.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:h})
|
|
1354
|
-
const r
|
|
1355
|
-
|
|
1355
|
+
const r=`${t.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,n=m.join(w,r+".log")
|
|
1356
|
+
let o=null
|
|
1357
|
+
try{o=f.createWriteStream(n,{flags:"w"}),o.write(`# ${(new Date).toISOString()} starting: ${t.command}\n# cwd: ${h}\n# timeout: ${t.timeout}s\n\n`)}catch(e){c.warn("Failed to open command log file",{logPath:n,error:e+""})}const s=await I(t.command,{cwd:h,timeoutMs:1e3*t.timeout,env:{...u.env,FORCE_COLOR:"0"},onChunk:o?(e,t)=>{o?.write(t)}:void 0},{id:r,name:t.name,sessionId:k,logPath:n})
|
|
1358
|
+
o&&(o.write(`\n# exit: ${s.exitCode}${s.timedOut?" (timed out)":""}\n`),o.end())
|
|
1359
|
+
const i=(s.stdout+(s.stderr?"\n"+s.stderr:"")).trim().slice(-4e3)
|
|
1360
|
+
if(g.push({name:t.name,command:t.command,exitCode:s.exitCode,output:i,timedOut:s.timedOut}),"setup"===e.commandName&&0!==s.exitCode)break}const v=g.every((e=>0===e.exitCode)),C=g.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
|
|
1356
1361
|
return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\``})).join("\n\n")
|
|
1357
|
-
return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${
|
|
1362
|
+
return a({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${v?"PASSED":"FAILED"}\n\n${C}`}]}}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")
|
|
1358
1363
|
try{const{sessionIdentity:u}=await Promise.resolve().then(t.bind(t,6688)),h=await u.getSessionRequestId(i,a,l?.sessionId)
|
|
1359
1364
|
if(!h)return d({success:!1,error:"no_request_association"}),{content:[{type:"text",text:"Cannot report test results: this session is not associated with a request."}],isError:!0}
|
|
1360
1365
|
const p=await i.proxyGet(`/api/projects/${s.projectId}/requests/${h}/test-runs`),g=p?.data||p||[],m=Array.isArray(g)?g:[],f=m.find((e=>"pending"===e.status||"running"===e.status))||m[0]
|
|
@@ -2677,49 +2682,51 @@ const a=await r.updateDocument(e.planId,i),c=a.localId||a.id
|
|
|
2677
2682
|
return o.info("Plan appended",{planId:c,appendedLength:e.content.length}),{content:[{type:"text",text:`\u2705 **Plan Appended**\n\n**Plan ID:** ${c}\n**Appended:** ${e.content.length} characters\n**Total Length:** ${s.length} characters`}]}}catch(e){return o.error("Failed to append to plan",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to append to plan:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
2678
2683
|
const r=t(8824)},4425(e,exports,t){"use strict"
|
|
2679
2684
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2680
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,
|
|
2681
|
-
try{const
|
|
2682
|
-
if("list"===
|
|
2685
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,u,h,p,g){const m=h.startTimer("tool_execution_time"),f=e.operation||"run"
|
|
2686
|
+
try{const h=await r.proxyGet(`/api/projects/${t.projectId}/check-commands`),y=h?.data||h||[],w=y.filter((e=>e.isActive)),I=y.filter((e=>!e.isActive))
|
|
2687
|
+
if("list"===f){if(0===y.length)return m({success:!0}),{content:[{type:"text",text:'No commands configured for this project yet.\n\nUse `commands({ operation: "register", commands: [{ name: "typecheck", command: "tsc --noEmit", description: "..." }] })` to add one, or `commands({ operation: "setup" })` to spawn the architect for an interview.'}],...(0,a.alchemyMeta)({kind:"list-commands"})}
|
|
2683
2688
|
const e=[]
|
|
2684
|
-
return
|
|
2685
|
-
try{const r=await fetch((0,
|
|
2689
|
+
return w.length>0&&(e.push(`## Available Commands (${w.length})\n`),e.push(...w.map((e=>`- **${e.name}**: \`${e.command}\`${e.cwd?` (in \`${e.cwd}\`)`:""}${e.description?" \u2014 "+e.description:""}`)))),I.length>0&&(e.push(`\n## Pending Approval (${I.length})\n`),e.push(...I.map((e=>`- **${e.name}**: \`${e.command}\`${e.cwd?` (in \`${e.cwd}\`)`:""} \u2014 \u23f3 waiting for user approval`)))),e.push('\nRun: `commands({ name: "name" })`\nRegister: `commands({ operation: "register", commands: [{ name, command, description, cwd? }, ...] })` \u2014 submits 1+ commands for approval. Single-item arrays work for one command; multiples bundle into one batch notification.\nRemove: `commands({ operation: "remove", name: "..." })`\nSetup (interactive): `commands({ operation: "setup" })` \u2014 spawns the command-architect for guided setup'),m({success:!0}),{content:[{type:"text",text:e.join("\n")}],...(0,a.alchemyMeta)({kind:"list-commands"})}}if("setup"===f){const t=g?.sessionId,n=t?await l.sessionIdentity.getSessionRequestId(r,u,t):void 0
|
|
2690
|
+
try{const r=await fetch((0,d.getActionServerBaseUrl)()+"/api/setup-commands",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:n,parentSessionId:t,context:e.context}),signal:AbortSignal.timeout(15e3)})
|
|
2686
2691
|
if(!r.ok){const e=await r.text().catch((()=>""))
|
|
2687
|
-
return
|
|
2688
|
-
return o.success&&o.data?(
|
|
2689
|
-
const n=function(e){return e?.sessionId||
|
|
2690
|
-
if(!n)return
|
|
2691
|
-
const o=new Set(
|
|
2692
|
+
return m({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:`commands setup failed: action server returned ${r.status}: ${e.slice(0,300)}`}],isError:!0}}const o=await r.json()
|
|
2693
|
+
return o.success&&o.data?(m({success:!0}),{content:[{type:"text",text:`Commands setup session started.\nWorktree: ${o.data.worktreePath} (branch: ${o.data.branch})\n\nThe command-architect agent is now interviewing the user. You will receive a notification on your next turn when configuration completes \u2014 continue with other work in the meantime.`}],...(0,a.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:o.data.sessionId,agentType:"command-architect",description:"Commands setup"})}):(m({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(o.error||"unknown error")}],isError:!0})}catch(e){return m({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(0,c.getErrorMessage)(e)}],isError:!0}}}if("register"===f){if(!Array.isArray(e.commands)||0===e.commands.length)return m({success:!1,error:"missing_commands"}),{content:[{type:"text",text:"Error: `commands` array is required and must be non-empty for the register operation."}],isError:!0}
|
|
2694
|
+
const n=function(e){return e?.sessionId||l.sessionIdentity.getIdentity()?.sessionId||null}(g)
|
|
2695
|
+
if(!n)return m({success:!1,error:"no_session"}),{content:[{type:"text",text:"Error: no session context available to attribute approval notifications."}],isError:!0}
|
|
2696
|
+
const o=new Set(y.map((e=>e.name.toLowerCase()))),s=[],i=[]
|
|
2692
2697
|
for(const t of e.commands){const e=t.name?.trim(),r=t.command?.trim(),n=t.description?.trim()
|
|
2693
|
-
e&&r&&n?o.has(e.toLowerCase())?
|
|
2698
|
+
e&&r&&n?o.has(e.toLowerCase())?i.push({name:e,reason:"already exists"}):(o.add(e.toLowerCase()),s.push({name:e,command:r,description:n,cwd:t.cwd?.trim(),timeout:t.timeout})):i.push({name:e||"(unnamed)",reason:"missing required fields (name, command, description)"})}const d=await Promise.all(s.map((async e=>{try{const n=await r.proxyPost(`/api/projects/${t.projectId}/check-commands`,{name:e.name,command:e.command,description:e.description,timeout:e.timeout||60,cwd:e.cwd||void 0,addedBySessionId:g?.sessionId,isActive:!1}),o=n?.data?.id||n?.id
|
|
2694
2699
|
if(!o)throw Error("command create returned no id")
|
|
2695
|
-
return{ok:!0,proposal:e,commandId:o}}catch(t){return{ok:!1,proposal:e,error:(0,
|
|
2696
|
-
for(const e of
|
|
2697
|
-
const
|
|
2698
|
-
if(
|
|
2700
|
+
return{ok:!0,proposal:e,commandId:o}}catch(t){return{ok:!1,proposal:e,error:(0,c.getErrorMessage)(t)}}}))),h=d.filter((e=>e.ok))
|
|
2701
|
+
for(const e of d)e.ok||i.push({name:e.proposal.name,reason:e.error})
|
|
2702
|
+
const p=[]
|
|
2703
|
+
if(h.length>0)try{const e=r.getSessionMessageClient()
|
|
2699
2704
|
if(!e)throw Error("session message client unavailable")
|
|
2700
|
-
await e.createQuestion({fromSessionId:n,questionType:"alternatives",question:`Command batch approval: ${
|
|
2701
|
-
for(const e of
|
|
2702
|
-
for(const t of
|
|
2703
|
-
const
|
|
2704
|
-
return
|
|
2705
|
-
const n=
|
|
2706
|
-
if(!n)return
|
|
2707
|
-
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),
|
|
2708
|
-
return
|
|
2709
|
-
if(!
|
|
2710
|
-
return
|
|
2711
|
-
e.grep&&(
|
|
2712
|
-
const
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
const
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
const
|
|
2705
|
+
await e.createQuestion({fromSessionId:n,questionType:"alternatives",question:`Command batch approval: ${h.length} command${1===h.length?"":"s"}`,options:[{id:"approve-all",label:"Approve all",description:`Activate all ${h.length} commands`},{id:"deny-all",label:"Deny all",description:"Delete all proposed commands"},{id:"select",label:"Select\u2026",description:"Pick which to approve individually"}],context:JSON.stringify({type:"command-approval-batch",commands:h.map((e=>({commandId:e.commandId,name:e.proposal.name,command:e.proposal.command,description:e.proposal.description,cwd:e.proposal.cwd})))}),category:"action-required",priority:"high"})
|
|
2706
|
+
for(const e of h)p.push(e.proposal.name)}catch(e){await Promise.allSettled(h.map((e=>r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${e.commandId}`).catch((t=>u.warn("Rollback delete after batch question failure",{commandId:e.commandId,error:(0,c.getErrorMessage)(t)}))))))
|
|
2707
|
+
for(const t of h)i.push({name:t.proposal.name,reason:(0,c.getErrorMessage)(e)})}u.info("Register submitted commands for approval",{total:e.commands.length,submitted:p.length,skipped:i.length}),m({success:!0})
|
|
2708
|
+
const f=[`## Submitted ${p.length} command${1===p.length?"":"s"} for approval${i.length?`, ${i.length} skipped`:""}`]
|
|
2709
|
+
return p.length>0&&(f.push("","### Pending approval"),f.push(...p.map((e=>`- **${e}**`))),f.push("","The user will see one approval notification per command. Approved commands become runnable; denied ones are removed.")),i.length>0&&(f.push("",`### Skipped (${i.length})`),f.push(...i.map((e=>`- **${e.name}** \u2014 ${e.reason}`)))),f.push("",'Use `commands({ operation: "list" })` to see status.'),{content:[{type:"text",text:f.join("\n")}],...(0,a.alchemyMeta)({kind:"register-commands"})}}if("remove"===f){if(!e.name?.trim())return m({success:!1,error:"missing_name"}),{content:[{type:"text",text:"Error: `name` is required when removing a command."}],isError:!0}
|
|
2710
|
+
const n=y.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2711
|
+
if(!n)return m({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.`}],isError:!0}
|
|
2712
|
+
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),u.info("Removed command",{name:n.name,id:n.id}),m({success:!0}),{content:[{type:"text",text:`Removed command **${n.name}**.`}]}}catch(e){return m({success:!1,error:"remove_failed"}),{content:[{type:"text",text:"Failed to remove command: "+(0,c.getErrorMessage)(e)}],isError:!0}}}if(!e.name){const e=w.map((e=>e.name)).join(", ")
|
|
2713
|
+
return m({success:!1,error:"missing_name"}),{content:[{type:"text",text:"Error: `name` is required when running a command.\n\nAvailable commands: "+(e||"(none configured)")}],isError:!0}}const b=w.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2714
|
+
if(!b){const t=w.map((e=>e.name)).join(", ")
|
|
2715
|
+
return m({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.\n\nAvailable commands: ${t||"(none configured)"}`}],isError:!0}}let k=e.args?`${b.command} ${e.args}`:b.command
|
|
2716
|
+
e.grep&&(k=`${k} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
|
|
2717
|
+
const v=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,C=b.cwd?o.default.resolve(v,b.cwd):v,_=o.default.join(v,i.ALCHEMY_DIR_NAME,"command-logs"),E=`${b.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,S=o.default.join(_,E+".log")
|
|
2718
|
+
let q=null
|
|
2719
|
+
try{s.default.mkdirSync(_,{recursive:!0}),q=s.default.createWriteStream(S,{flags:"w"}),q.write(`# ${(new Date).toISOString()} starting: ${k}\n# cwd: ${C}\n# timeout: ${b.timeout||60}s\n\n`)}catch(e){u.warn("Failed to open command log file",{logPath:S,error:(0,c.getErrorMessage)(e)})}u.info("Running command",{name:b.name,command:k,cwd:C,configuredCwd:b.cwd,logPath:S})
|
|
2720
|
+
const T=await(0,n.runTrackedShellCommand)(k,{cwd:C,timeoutMs:1e3*(b.timeout||60),env:{...process.env,FORCE_COLOR:"0"},onChunk:q?(e,t)=>{q?.write(t)}:void 0},{id:E,name:b.name,sessionId:g?.sessionId,logPath:S})
|
|
2721
|
+
q&&(q.write(`\n# exit: ${T.exitCode}${T.timedOut?" (timed out)":""}\n`),q.end())
|
|
2722
|
+
let P=T.stdout,x=T.stderr
|
|
2723
|
+
const j=T.exitCode,R=T.timedOut,M=8e3,$=4e3
|
|
2724
|
+
P.length>M&&(P="\u2026"+P.slice(-M)),x.length>$&&(x="\u2026"+x.slice(-$))
|
|
2725
|
+
const O=R?"TIMEOUT":null,D=[P,x].filter(Boolean).join("\n")||"(no output)"
|
|
2726
|
+
let A
|
|
2727
|
+
if(p)try{const e=await p.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:b.name,command:k,exitCode:j,timedOut:R,status:R?"timeout":0===j?"success":"failed",timestamp:(new Date).toISOString()}})
|
|
2728
|
+
A=e?.id}catch(e){u.debug("Failed to create tool record for command run",{error:(0,c.getErrorMessage)(e)})}return m({success:!0}),{content:[{type:"text",text:`## ${b.name}${O?` \u2014 ${O} (killed after ${b.timeout}s)`:""}\n\`\`\`\n$ ${k}\n${D}\n\`\`\`\n\nExit code: ${j}\nFull log: ${S}`}],...(0,a.alchemyMeta)({kind:"run-command",toolRecordId:A})}}catch(e){return m({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,c.getErrorMessage)(e)}],isError:!0}}}
|
|
2729
|
+
const n=t(4600),o=r(t(6928)),s=r(t(9896)),i=t(4139),a=t(2272),c=t(8824),l=t(6688),d=t(9414)},4466(e,exports,t){"use strict"
|
|
2723
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
|
|
2724
2731
|
const i=e.match(exports.TASK_REF_SHORT_PATTERN)
|
|
2725
2732
|
if(!i)return e
|
|
@@ -2773,15 +2780,20 @@ default:throw new r.ValidationError("Unknown operation: "+g)}p({success:!0}),l.i
|
|
|
2773
2780
|
const y=a[g]??"planner-request"
|
|
2774
2781
|
return(0,i.withAlchemyKind)(f,y)}catch(e){return h.error("Planner ops failed",{error:e instanceof Error?e.stack:e+""}),p({success:!1}),l.incrementCounter("planner_ops_errors",1),{content:[{type:"text",text:"Planner operation failed: "+(0,n.getErrorMessage)(e)}],isError:!0}}}
|
|
2775
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"
|
|
2776
|
-
|
|
2783
|
+
async function r(e,r={}){const{spawn:n}=await Promise.resolve().then(t.t.bind(t,5317,23))
|
|
2784
|
+
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"],detached:!o}),i=[],a=[]
|
|
2785
|
+
let c=!1,l=!1
|
|
2786
|
+
const d=e=>{if(s.pid)try{o?s.kill(e):process.kill(-s.pid,e)}catch{}}
|
|
2787
|
+
let u,h
|
|
2788
|
+
r.timeoutMs&&r.timeoutMs>0&&(h=setTimeout((()=>{c=!0,d("SIGTERM"),u=setTimeout((()=>{l||d("SIGKILL")}),2e3)}),r.timeoutMs)),s.stdout?.on("data",(e=>{i.push(e),r.onChunk?.("stdout",e)})),s.stderr?.on("data",(e=>{a.push(e),r.onChunk?.("stderr",e)}))
|
|
2789
|
+
const p=e=>{l||(l=!0,h&&clearTimeout(h),u&&clearTimeout(u),t({stdout:Buffer.concat(i).toString("utf-8"),stderr:Buffer.concat(a).toString("utf-8"),exitCode:e,timedOut:c}))}
|
|
2790
|
+
s.on("close",(e=>p(e??(c?124:1)))),s.on("error",(()=>p(1)))}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.execAsync=async function(e,t={}){return new Promise(((r,o)=>{const[s,...i]=e.split(" "),a=(0,n.spawn)(s,i,{cwd:t.cwd||process.cwd(),stdio:["pipe","pipe","pipe"]})
|
|
2777
2791
|
let c="",l=""
|
|
2778
|
-
a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
const
|
|
2783
|
-
s.on("close",(e=>h(e??(d?124:1)))),s.on("error",(()=>h(1)))}))}
|
|
2784
|
-
const r=t(5317)},4607(e,exports,t){"use strict"
|
|
2792
|
+
a.stdout?.on("data",(e=>{c+=e.toString()})),a.stderr?.on("data",(e=>{l+=e.toString()})),a.on("close",(e=>{r({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=r,exports.runTrackedShellCommand=async function(e,n,o){const{getActionServerBaseUrl:s}=await Promise.resolve().then(t.bind(t,9414)),i=s(),a=(new Date).toISOString(),c=n.cwd??process.cwd()
|
|
2793
|
+
fetch(i+"/api/commands/start",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:o.id,name:o.name,command:e,cwd:c,sessionId:o.sessionId,startedAt:a,logPath:o.logPath}),signal:AbortSignal.timeout(2e3)}).catch((()=>{}))
|
|
2794
|
+
const l=await r(e,n)
|
|
2795
|
+
return fetch(i+"/api/commands/end",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:o.id,exitCode:l.exitCode,timedOut:l.timedOut,finishedAt:(new Date).toISOString()}),signal:AbortSignal.timeout(2e3)}).catch((()=>{})),l}
|
|
2796
|
+
const n=t(5317)},4607(e,exports,t){"use strict"
|
|
2785
2797
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
2786
2798
|
const r=t(6183),n=t(3306)
|
|
2787
2799
|
exports.def={name:"replace_strings",description:'Replace text strings across multiple files and documents in a single operation.\n\nMODES:\n\u2022 \'unique\' (default, safer) - Fails if string appears multiple times\n\u2022 \'all\' - Replaces all occurrences\n\nOPERATIONS:\nEach operation specifies:\n\u2022 Target: \'path\' (for files) or \'documentId\' (for documents)\n\u2022 Replacements: Array of {old_str, new_str} pairs\n\u2022 Mode: \'unique\' or \'all\'\n\nEXAMPLES:\n- Replace in file: {"path": "file.ts", "replacements": [{"old_str": "foo", "new_str": "bar"}], "mode": "unique"}\n- Replace in document: {"documentId": "doc123", "replacements": [{"old_str": "old", "new_str": "new"}]}\n\nSupports multiple files/documents and multiple replacements per operation. All changes are committed atomically to Git for files.',schema:r.ReplaceStringsSchema,annotations:{title:"Replace Strings in Files/Documents",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},hidden:!0,createsRecords:!0,handler(e,t){return(0,n.handleReplaceStrings)(e,t.context,t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},4640(e,exports,t){"use strict"
|