blade-code 0.10.17 → 0.10.19
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/blade.js +2 -2
- package/dist/{chunk-cd087ckq.js → chunk-07mstszb.js} +2 -2
- package/dist/{chunk-kjet3e74.js → chunk-1wz10w2m.js} +1 -1
- package/dist/{chunk-z9mpf0t7.js → chunk-1ydqqzp1.js} +1 -1
- package/dist/{chunk-bpnyda6p.js → chunk-29axr7g4.js} +1 -1
- package/dist/chunk-2gj76ba1.js +1 -0
- package/dist/{chunk-ab3a9gdc.js → chunk-30e3v8cw.js} +1 -1
- package/dist/{chunk-bjzykvs1.js → chunk-36626eyr.js} +1 -1
- package/dist/{chunk-gjw014rv.js → chunk-3gra6n0k.js} +1 -1
- package/dist/{chunk-2675vkx5.js → chunk-5a8tqdrk.js} +1 -1
- package/dist/{chunk-wvh6entt.js → chunk-5ra89kse.js} +1 -1
- package/dist/{chunk-rn04c7hs.js → chunk-6r0nj7ay.js} +1 -1
- package/dist/{chunk-bqgd4db7.js → chunk-8mafna0v.js} +1 -1
- package/dist/{chunk-fm8vpym2.js → chunk-8zywzb9j.js} +1 -1
- package/dist/{chunk-a0hk9xrj.js → chunk-aem57a6n.js} +1 -1
- package/dist/{chunk-fneamw65.js → chunk-amzz0mk6.js} +1 -1
- package/dist/{chunk-hm3yme2m.js → chunk-c6rff43d.js} +1 -1
- package/dist/{chunk-6yjn2wj7.js → chunk-ctkxf0y7.js} +50 -50
- package/dist/{chunk-677ywzhs.js → chunk-cyda7gnb.js} +1 -1
- package/dist/{chunk-w320ev24.js → chunk-ddqwtw3z.js} +1 -1
- package/dist/{chunk-rgy886ad.js → chunk-et9k9pac.js} +1 -1
- package/dist/{chunk-nqj9c68w.js → chunk-hmvyreyx.js} +3 -3
- package/dist/{chunk-hxcd65h1.js → chunk-kgypdjdw.js} +1 -1
- package/dist/{chunk-6aw8vpf8.js → chunk-ks6by04t.js} +1 -1
- package/dist/{chunk-2x0marf0.js → chunk-mg421b17.js} +1 -1
- package/dist/{chunk-wzvy13p2.js → chunk-qwxqfb9z.js} +1 -1
- package/dist/{chunk-3d4cgnpw.js → chunk-t8g4288j.js} +1 -1
- package/dist/{chunk-amdw5728.js → chunk-tcnnh890.js} +1 -1
- package/dist/{chunk-c18qckn4.js → chunk-y5fk4fx5.js} +1 -1
- package/dist/{chunk-ncj12cv0.js → chunk-ycwrykxe.js} +1 -1
- package/dist/{chunk-8vd6q2wt.js → chunk-yp02wzek.js} +1 -1
- package/dist/{chunk-774jxdm3.js → chunk-yxmy7g38.js} +1 -1
- package/dist/{chunk-69ma931b.js → chunk-zek2ec3c.js} +1 -1
- package/dist/{chunk-w9zgpqjd.js → chunk-zgt1jpgg.js} +1 -1
- package/package.json +1 -1
- package/dist/chunk-wygpe92c.js +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={name:"blade-code",version:"0.10.
|
|
1
|
+
var e={name:"blade-code",version:"0.10.19",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","vendor/ripgrep/**","README.md"],scripts:{dev:"node scripts/run-bun.js --watch src/blade.tsx","dev:serve":"node scripts/run-bun.js --watch src/blade.tsx serve --port 4097",build:"rm -rf dist && node scripts/run-bun.js run scripts/build.ts",start:"node scripts/run-bun.js run dist/blade.js",test:"node scripts/test.js","test:all":"vitest run --config vitest.config.ts --project='!performance' && vitest run --config vitest.config.ts --project=performance","test:unit":"node scripts/test.js unit","test:integration":"node scripts/test.js integration","test:real-api":"node scripts/test.js realApi","test:real-api:qualification":"node scripts/test.js realApiQualification","test:cli":"node scripts/test.js cli","test:headless-core":"node scripts/test.js headlessCore","test:e2e":"node scripts/test.js e2e","test:performance":"node scripts/test.js performance","test:snapshot":"node scripts/test.js snapshot","test:security":"node scripts/test.js security","test:coverage":"node scripts/test.js all --coverage","test:watch":"vitest --watch --config vitest.config.ts","qualify:local":"node scripts/run-bun.js run scripts/qualify.ts local","qualify:production":"node scripts/run-bun.js run scripts/qualify.ts production","benchmark:repo":"node scripts/run-bun.js run scripts/run-real-repo-benchmark.ts","test:update-snapshots":"node scripts/test.js snapshot --update",lint:"biome lint src tests","lint:fix":"biome lint --write src tests","type-check":"tsc --noEmit","format:check":"biome format src tests",ready:"node scripts/run-bun.js run scripts/qualify.ts production","detect-unused":"node scripts/run-bun.js run scripts/detect-unused.ts",release:"node scripts/release.js","release:dry":"node scripts/release.js --dry-run","release:major":"node scripts/release.js --major","release:minor":"node scripts/release.js --minor","release:patch":"node scripts/release.js --patch"},keywords:["cli","blade","ai","assistant","agent","llm"],author:"echoVic",license:"MIT",engines:{node:">=22.19.0"},optionalDependencies:{"@vscode/ripgrep":"^1.18.0","better-sqlite3":"^11.8.1","bun-pty":"^0.4.8","node-pty":"1.1.0"},dependencies:{"@agentclientprotocol/sdk":"^1.3.0","@anthropic-ai/sandbox-runtime":"0.0.67","@earendil-works/pi-ai":"0.83.0","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.30.0",ahooks:"^3.9.7","ansi-escapes":"^7.3.0",ajv:"^8.17.1","async-mutex":"^0.5.0",axios:"^1.19.0",chalk:"^5.4.1",diff:"^8.0.2","fast-glob":"^3.3.3","fuse.js":"^7.5.0","gray-matter":"^4.0.3",hono:"^4.13.0",ink:"npm:@jrichman/ink@6.4.10","ink-big-text":"^2.0.0","ink-gradient":"^3.0.0","ink-select-input":"^6.2.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0","js-tiktoken":"^1.0.21","lodash-es":"^4.18.1",lowlight:"^3.3.0","lru-cache":"^11.5.2",nanoid:"^5.1.6",open:"^10.1.2",picomatch:"^4.0.5",react:"19.2.4","react-dom":"19.2.4",semver:"^7.8.5","string-width":"^8.2.2",typebox:"1.3.10",undici:"^7.16.0","vscode-jsonrpc":"8.2.1","vscode-languageserver-protocol":"3.17.5","vscode-languageserver-types":"3.17.5","write-file-atomic":"^7.0.0",ws:"^8.21.2",yaml:"^2.9.0",yargs:"^18.1.0",zustand:"^5.0.14"},devDependencies:{"@biomejs/biome":"^2.5.7","@types/bun":"^1.3.14","@types/json-schema":"^7.0.15","@types/lodash-es":"^4.17.12","@types/node":"^22.15.24","@types/picomatch":"^4.0.3","@types/react":"19.2.10","@types/react-dom":"19.2.3","@types/semver":"^7.8.0","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.18.1","@types/yargs":"^17.0.35","@vitest/coverage-v8":"^4.1.10",jsdom:"^26.0.0",typescript:"^5.9.2",vitest:"^4.1.10"}};function i(){return{name:e.name,version:e.version,description:e.description}}function n(){return e.version}function o(){return e.name}function c(){return e.description}function a(){return`v${e.version}`}function d(){return`v${e.version} © 2025 Blade Code`}
|
|
2
2
|
export{i as yf,n as zf,o as Af,c as Bf,a as Cf,d as Df};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ka as H}from"./chunk-
|
|
1
|
+
import{ka as H}from"./chunk-3gra6n0k.js";import"./chunk-095x2ykj.js";import{$c as $,fd as T}from"./chunk-8mafna0v.js";import"./chunk-6pa6c2n0.js";import"./chunk-yz2bsntj.js";import"./chunk-5ra89kse.js";import"./chunk-q3c07kb4.js";import"./chunk-6207mbmr.js";import"./chunk-et9k9pac.js";import"./chunk-y2g5a5bp.js";import"./chunk-96h588rd.js";import"./chunk-3qhqbj09.js";import{mf as k}from"./chunk-prgh321y.js";import"./chunk-jpwfq49n.js";import"./chunk-yqfqj7mh.js";import"./chunk-cyda7gnb.js";import"./chunk-1n60pgsq.js";import"./chunk-qkrssft1.js";import"./chunk-yvf4nmds.js";import"./chunk-6g5k5de1.js";import U from"os";import J from"path";function X(z){return typeof z==="string"?z:void 0}function N(z){if(!Array.isArray(z))return;let q=[];for(let K of z)if(typeof K==="string")q.push(K);else if(K!=null)q.push(String(K));return q}function b(){console.log(`
|
|
2
2
|
blade mcp
|
|
3
3
|
`),console.log(`管理 MCP 服务器
|
|
4
4
|
`),console.log("Commands:"),console.log(" blade mcp add <name> <commandOrUrl> [args...] 添加 MCP 服务器"),console.log(" blade mcp remove <name> 删除 MCP 服务器 [aliases: rm]"),console.log(" blade mcp list 列出所有 MCP 服务器并检查健康状态 [aliases: ls]"),console.log(" blade mcp get <name> 获取服务器详情"),console.log(" blade mcp login <name> 登录远程 MCP OAuth"),console.log(" blade mcp logout <name> 清除远程 MCP OAuth 凭证"),console.log(` blade mcp add-json <name> <json> 从 JSON 字符串添加服务器
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{$e as Jn,_e as Zn}from"./chunk-y2g5a5bp.js";import{af as rn,bf as D,cf as m}from"./chunk-96h588rd.js";import{gf as pn,hf as Nn}from"./chunk-3qhqbj09.js";import{mf as b}from"./chunk-prgh321y.js";import{of as Dn,rf as H}from"./chunk-jpwfq49n.js";import{Af as En,zf as fn}from"./chunk-
|
|
1
|
+
import{$e as Jn,_e as Zn}from"./chunk-y2g5a5bp.js";import{af as rn,bf as D,cf as m}from"./chunk-96h588rd.js";import{gf as pn,hf as Nn}from"./chunk-3qhqbj09.js";import{mf as b}from"./chunk-prgh321y.js";import{of as Dn,rf as H}from"./chunk-jpwfq49n.js";import{Af as En,zf as fn}from"./chunk-cyda7gnb.js";import{Ef as P}from"./chunk-1n60pgsq.js";import{Of as un}from"./chunk-yvf4nmds.js";var Qn=/^[\x21\x23-\x5b\x5d-\x7e]+$/;function Wn(n){return n==="127.0.0.1"||n==="[::1]"||n.toLowerCase()==="localhost"}function I(n,t="MCP OAuth URL"){let e=new URL(n);if(e.username||e.password)throw Error(`${t} must not contain credentials`);if(e.protocol!=="https:"&&!(e.protocol==="http:"&&Wn(e.hostname)))throw Error(`${t} requires HTTPS; HTTP is allowed only for loopback servers`);return e}var B=async(n,t)=>{I(n,"MCP OAuth request URL");let e=await fetch(n,{...t,redirect:"manual"});if(e.status>=300&&e.status<400)throw await e.body?.cancel(),Error("MCP OAuth network requests must not follow redirects");return e};function q(n){let t=n.oauth;if(!t)return;let e=t;for(let _ of["clientSecret","authorizationUrl","tokenUrl","redirectUri"])if(e[_]!==void 0)throw Error(`MCP OAuth "${_}" is not supported; use standards-based discovery`);if(t.enabled!==!0)return{enabled:!1};if(n.type!=="http"&&n.type!=="sse")throw Error("MCP OAuth is supported only for HTTP and SSE transports");if(!n.url)throw Error("MCP OAuth requires an MCP server URL");if(I(n.url,"MCP OAuth server URL"),Object.keys(n.headers??{}).find((_)=>_.toLowerCase()==="authorization"))throw Error("MCP OAuth cannot be combined with a configured Authorization header");let u=t.clientId?.trim();if(u&&u.length>4096)throw Error("MCP OAuth clientId exceeds 4096 characters");let M=t.scopes?.map((_)=>_.trim());if(M){if(M.length>32)throw Error("MCP OAuth supports at most 32 scopes");if(M.some((_)=>!_||_.length>128||!Qn.test(_)))throw Error("MCP OAuth scopes contain an invalid value");if(new Set(M).size!==M.length)throw Error("MCP OAuth scopes must not contain duplicates")}let o=t.callbackPort;if(o!==void 0&&(!Number.isInteger(o)||o<1024||o>65535))throw Error("MCP OAuth callbackPort must be between 1024 and 65535");return{enabled:!0,...u?{clientId:u}:{},...M?.length?{scopes:M}:{},...o!==void 0?{callbackPort:o}:{}}}import{randomUUID as J}from"node:crypto";import st from"node:http";import{auth as _n}from"@modelcontextprotocol/sdk/client/auth.js";import St from"open";import{createHash as jn,randomUUID as Fn}from"node:crypto";import{constants as O,promises as A}from"node:fs";import Y from"node:path";import{Mutex as vn}from"async-mutex";import nt from"write-file-atomic";var Mn=1,tt=1048576,et=5000,ut=50,rt=/^[a-f0-9]{64}$/,Mt=m.Object({client_id:m.String({minLength:1,maxLength:4096})},{additionalProperties:!0}),ot=m.Object({access_token:m.String({minLength:1,maxLength:65536}),token_type:m.String({minLength:1,maxLength:64}),expires_in:m.Optional(m.Number({minimum:0})),refresh_token:m.Optional(m.String({minLength:1,maxLength:65536})),scope:m.Optional(m.String({maxLength:16384})),id_token:m.Optional(m.String({minLength:1,maxLength:262144}))},{additionalProperties:!1}),_t=m.Unsafe({type:"object",properties:{authorizationServerUrl:m.String({format:"uri"}),resourceMetadataUrl:m.Optional(m.String({format:"uri"})),resourceMetadata:m.Optional(m.Unknown()),authorizationServerMetadata:m.Optional(m.Unknown())},required:["authorizationServerUrl"],additionalProperties:!1}),on=m.Object({serverUrl:m.String({format:"uri"}),clientId:m.Optional(m.String({minLength:1,maxLength:4096})),clientInformation:m.Optional(Mt),tokens:m.Optional(ot),tokenExpiresAt:m.Optional(m.Number({minimum:0})),discoveryState:m.Optional(_t),updatedAt:m.String({format:"date-time"})},{additionalProperties:!1}),tn=m.Object({version:m.Literal(Mn),credentials:m.Record(m.String(),on)},{additionalProperties:!1});function l(n,t){return n instanceof Error&&"code"in n&&n.code===t}function it(n){if(!Number.isInteger(n)||n<=0)return!1;try{return process.kill(n,0),!0}catch(t){return l(t,"EPERM")}}function V(n){return structuredClone(n)}function en(n){if(Object.keys(n.credentials).some((t)=>!rt.test(t)))throw Error("MCP OAuth credential store contains an invalid identity")}function y(n){let t=new URL(n);return t.hash="",t.toString()}function Z(n,t,e=[]){return jn("sha256").update(JSON.stringify({serverUrl:y(n),clientId:t?.trim()||null,scopes:[...e].sort()})).digest("hex")}class x{static mutexes=new Map;stateRoot;tokenFilePath;mutex;constructor(n=un()){this.stateRoot=Y.join(n,"mcp"),this.tokenFilePath=Y.join(this.stateRoot,"oauth-credentials.json");let t=x.mutexes.get(this.tokenFilePath);if(!t)t=new vn,x.mutexes.set(this.tokenFilePath,t);this.mutex=t}async getCredential(n){return this.mutex.runExclusive(async()=>{let e=(await this.readStore()).credentials[n];return e?V(e):null})}async updateCredential(n,t){return this.runMutation(async(e)=>{let r=e.credentials[n],u=await t(r?V(r):null);if(u)e.credentials[n]=D(on,u);else delete e.credentials[n];return u?V(e.credentials[n]):null})}async deleteCredential(n){await this.updateCredential(n,()=>null)}async listCredentialIds(){return this.mutex.runExclusive(async()=>Object.keys((await this.readStore()).credentials).sort())}async runMutation(n){return this.mutex.runExclusive(async()=>{let t=await this.acquireStoreLock();try{let e=await this.readStore(),r=await n(e);return await this.writeStore(e),r}finally{await t()}})}async ensureStateRoot(){await A.mkdir(this.stateRoot,{recursive:!0,mode:448});let n=await A.lstat(this.stateRoot);if(!n.isDirectory()||n.isSymbolicLink())throw Error("MCP OAuth credential root must be a regular directory");if(process.getuid&&n.uid!==process.getuid())throw Error("MCP OAuth credential root must be owned by the current user");if((n.mode&63)!==0)throw Error("MCP OAuth credential root permissions must not allow group access")}async readStore(){try{let n=await A.lstat(this.tokenFilePath);if(!n.isFile()||n.isSymbolicLink())throw Error("MCP OAuth credential store must be a regular file");if(process.getuid&&n.uid!==process.getuid())throw Error("MCP OAuth credential store must be owned by the current user");if((n.mode&511)!==384)throw Error("MCP OAuth credential store permissions must be 0600");if(n.size>tt)throw Error("MCP OAuth credential store exceeds the 1 MiB limit");let t=JSON.parse(await A.readFile(this.tokenFilePath,"utf8")),e=rn(tn,t);if(!e.success)throw Error("MCP OAuth credential store has an invalid schema");return en(e.data),e.data}catch(n){if(l(n,"ENOENT"))return{version:Mn,credentials:{}};throw n}}async writeStore(n){await this.ensureStateRoot();let t=D(tn,n);en(t),await nt(this.tokenFilePath,`${JSON.stringify(t,null,2)}
|
|
2
2
|
`,{mode:384,encoding:"utf8"}),await A.chmod(this.tokenFilePath,384)}async acquireStoreLock(){await this.ensureStateRoot();let n=Y.join(this.stateRoot,".oauth-credentials.lock"),t=Fn(),e=Date.now()+et;while(Date.now()<e)try{let r=await A.open(n,O.O_CREAT|O.O_EXCL|O.O_WRONLY,384);return await r.writeFile(`${JSON.stringify({version:1,pid:process.pid,token:t,createdAt:new Date().toISOString()})}
|
|
3
3
|
`,"utf8"),await r.close(),async()=>{try{if(JSON.parse(await A.readFile(n,"utf8")).token===t)await A.unlink(n)}catch(u){if(!l(u,"ENOENT"))throw u}}}catch(r){if(!l(r,"EEXIST"))throw r;await this.removeDeadLock(n),await new Promise((u)=>setTimeout(u,ut))}throw Error("MCP OAuth credential store is busy; retry the operation")}async removeDeadLock(n){let t=await A.lstat(n);if(!t.isFile()||t.isSymbolicLink())throw Error("MCP OAuth credential lock must be a regular file");if(process.getuid&&t.uid!==process.getuid()||(t.mode&511)!==384)throw Error("MCP OAuth credential lock ownership or permissions are invalid");let e=JSON.parse(await A.readFile(n,"utf8"));if(typeof e.pid!=="number"||!Number.isInteger(e.pid)||e.pid<=0)throw Error("MCP OAuth credential lock owner is invalid");if(!it(e.pid))await A.unlink(n)}}var sn="127.0.0.1",Sn=7777,mn="/oauth/callback",mt=300000;class Q extends Error{constructor(n){super(`MCP server "${n}" requires OAuth authorization; run "blade mcp login ${n}" or use the Web MCP panel`);this.name="McpOAuthAuthorizationRequiredError"}}class cn extends Error{constructor(n){super(`MCP OAuth credentials are unavailable in this runtime for server "${n}"`);this.name="McpOAuthUnavailableError"}}function ft(n){let t=n?"Authentication complete":"Authentication failed";return`<!doctype html>
|
|
4
4
|
<html lang="en">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ca as j,da as x0,ia as KJ,ja as O8,ka as P0}from"./chunk-
|
|
1
|
+
import{ca as j,da as x0,ia as KJ,ja as O8,ka as P0}from"./chunk-3gra6n0k.js";import{Ea as J7,la as $7,na as Z7,oa as r6}from"./chunk-qt114yth.js";import{Fa as _$,Ga as o1,Ha as eZ,Ia as E1,Ja as Z8,Ka as J8,La as U8,Oa as V2,Qa as $6,Ra as E2,Sa as _2,Va as r0,Ya as Q0,cb as M2,db as YJ,eb as M9,gb as G8,ob as M8}from"./chunk-ctkxf0y7.js";import{pb as g8,qb as p8,rb as J2}from"./chunk-095x2ykj.js";import{$b as l9,Jb as A2,Kb as V0,Lb as p0,Mb as p2,Nb as c$,Ob as p9,Pb as i9,Sb as VJ,Wb as f8,_b as c9,bc as c,xb as X0,yb as m9,zb as g9}from"./chunk-zek2ec3c.js";import{cc as Y7,fc as H7,nc as z7,tc as Q7}from"./chunk-8rzwyknk.js";import{Ec as g4,Fc as d4}from"./chunk-k3nkcaap.js";import{$c as M$,Rc as O2,Sc as z0,Tc as P,Wc as W0,Xc as X2,Yc as n$,Zc as F$,_c as B6,ad as T8,fd as p$}from"./chunk-8mafna0v.js";import{gd as k$}from"./chunk-6pa6c2n0.js";import{hd as Y$}from"./chunk-yz2bsntj.js";import{nd as t9,od as Y2}from"./chunk-xet98pc1.js";import{qd as A0,rd as j$}from"./chunk-kbpc97n3.js";import{sd as zJ}from"./chunk-5chec8rs.js";import{ud as y9,vd as x9,wd as h9}from"./chunk-y5fk4fx5.js";import{Ad as L$,Bd as r8,Dd as C0,Ed as q7,Fd as S0,Gd as h0,Hd as r2,Id as N2,Jd as $$,Kd as u$,Ld as d$,Md as d9,Nd as M6,Pd as $0,Qd as H2,Rd as r9,xd as W2,yd as B2}from"./chunk-yp02wzek.js";import{Td as a$,Vd as q$,Wd as s1}from"./chunk-r1jxbx1h.js";import{$d as p4,Xd as TJ,Zd as u9,_d as L2}from"./chunk-6sb7cg95.js";import{be as g6,de as K0}from"./chunk-5ra89kse.js";import{ee as u0}from"./chunk-q3c07kb4.js";import{ie as g}from"./chunk-6207mbmr.js";import{Be as C4,De as P9,Fe as oZ,Ge as tZ,Ne as K4,Oe as a9,Pe as v9,Qe as F8,Re as q8,Se as w8,Te as D8,Ue as b8,Ve as L8,We as e,le as f4,qe as M4,se as x6,xe as GJ}from"./chunk-et9k9pac.js";import{af as I1,bf as B4,cf as _,df as a8,ef as S,ff as m}from"./chunk-96h588rd.js";import{hf as T9,if as f9}from"./chunk-3qhqbj09.js";import{kf as u1,mf as A}from"./chunk-prgh321y.js";import{qf as I9,rf as k9}from"./chunk-jpwfq49n.js";import{sf as MJ,vf as NJ}from"./chunk-yqfqj7mh.js";import{zf as PJ}from"./chunk-cyda7gnb.js";import{Ef as f0}from"./chunk-1n60pgsq.js";import{Hf as X7,Jf as P$,Lf as S9,Mf as W4,Of as O0}from"./chunk-yvf4nmds.js";import{Qf as t0}from"./chunk-6g5k5de1.js";import{randomUUID as T7}from"crypto";import{mkdir as S1,realpath as m2}from"node:fs/promises";import D7 from"node:os";import W$ from"node:path";import{Mutex as b7}from"async-mutex";var o6=new b7,B$,u2;function L7(){return import("@anthropic-ai/sandbox-runtime")}async function X1(){if(B$)return B$;if(!u2)u2=L7();return B$=await u2,B$}var A7={isSupportedPlatform:async()=>(await X1()).SandboxManager.isSupportedPlatform(),checkDependencies:async()=>(await X1()).SandboxManager.checkDependencies(),getDefaultWritePaths:async()=>(await X1()).getDefaultWritePaths(),initialize:async($)=>(await X1()).SandboxManager.initialize($),updateConfig:($)=>{if(!B$)throw Error("Sandbox runtime is not initialized");B$.SandboxManager.updateConfig($)},wrapWithSandboxArgv:async($,Z,J,U,X)=>(await X1()).SandboxManager.wrapWithSandboxArgv($,Z,J,U,X),cleanupAfterCommand:()=>B$?.SandboxManager.cleanupAfterCommand(),reset:async()=>{await B$?.SandboxManager.reset()}};function d2($){return{network:{allowedDomains:$,deniedDomains:[],strictAllowlist:!0},filesystem:{denyRead:[],allowRead:[],allowWrite:[],denyWrite:[]},enableWeakerNestedSandbox:!0}}class T$ extends Error{constructor($){super($);this.name="WorkspaceSandboxUnavailableError"}}class m$ extends Error{constructor($){super($);this.name="WorkspaceSandboxBoundaryError"}}class t6{backend;constructor($){this.backend=$}async prepare($){let Z=W$.resolve($.workspaceRoot),J=W$.resolve($.cwd);if(!X0.isWithinWorkspace(J,Z))throw new m$(`Bash cwd is outside the workspace sandbox: ${$.cwd}`);let U,X;try{[U,X]=await Promise.all([m2(Z),m2(J)])}catch(Y){throw new m$(`Workspace sandbox path cannot be resolved: ${Y instanceof Error?Y.message:String(Y)}`)}if(!X0.isWithinWorkspace(X,U))throw new m$(`Bash cwd resolves outside the workspace sandbox: ${$.cwd}`);return this.backend.prepare({...$,cwd:X,workspaceRoot:U})}}class e6{runtime;tempRoot;defaultWritePaths;initialization;constructor($={}){this.runtime=$.runtime??A7,this.tempRoot=$.tempRoot??W$.join(O0(),"sandbox-tmp"),this.defaultWritePaths=$.defaultWritePaths}async prepare($){await this.ensureInitialized();let Z=await this.prepareTempRoot(),J=W$.join(Z,"tmp"),U=W$.join(Z,"cache"),X=W$.join(U,"npm"),Y=W$.join(U,"bun");await Promise.all([S1(J,{recursive:!0}),S1(X,{recursive:!0}),S1(Y,{recursive:!0})]);let z=(this.defaultWritePaths??await this.runtime.getDefaultWritePaths()).filter((F)=>!F.startsWith("/dev/")),Q=$.access==="workspace-read-only",W=Q?[D7.homedir(),O0(),process.env.BLADE_REAL_API_CREDENTIALS_FILE].filter((F)=>typeof F==="string"&&F.trim().length>0).map((F)=>W$.resolve(F)).filter((F,w,q)=>q.indexOf(F)===w):[],B=process.platform==="win32"?"bash":"/bin/bash",V,E,O=()=>{if(!E)return;let F=E;E=void 0;try{this.runtime.updateConfig(d2(["*"]))}finally{F()}},G=async()=>{let F=process.env.CLAUDE_CODE_TMPDIR;process.env.CLAUDE_CODE_TMPDIR=J;try{return await this.runtime.wrapWithSandboxArgv($.command,B,{network:Q?{allowedDomains:[],deniedDomains:[],strictAllowlist:!0}:{allowedDomains:["*"],deniedDomains:[],strictAllowlist:!0},filesystem:{denyRead:W,allowRead:Q?[$.workspaceRoot]:[],allowWrite:Q?[Z]:[$.workspaceRoot,Z],denyWrite:Q?[$.workspaceRoot,...z]:z},git:{safeDirectories:[$.workspaceRoot]}},$.signal,$.cwd)}finally{if(F===void 0)delete process.env.CLAUDE_CODE_TMPDIR;else process.env.CLAUDE_CODE_TMPDIR=F}};try{if(Q)E=await o6.acquire(),this.runtime.updateConfig(d2([])),V=await G();else V=await o6.runExclusive(G)}catch(F){if(O(),F instanceof Error&&F.name==="AbortError")throw F;throw new T$(`Workspace sandbox failed to prepare the command: ${F instanceof Error?F.message:String(F)}`)}let K=!1;return{executable:V.argv[0]??B,args:V.argv.slice(1),env:{...V.env,TMPDIR:J,TMP:J,TEMP:J,XDG_CACHE_HOME:U,npm_config_cache:X,BUN_INSTALL_CACHE_DIR:Y},sandboxed:!0,inheritProcessEnv:!Q,cleanup:()=>{if(K)return;K=!0;try{this.runtime.cleanupAfterCommand()}finally{O()}}}}async dispose(){this.initialization=void 0,await this.runtime.reset()}async ensureInitialized(){if(!this.initialization)this.initialization=this.initializeRuntime().catch(($)=>{throw this.initialization=void 0,$});return this.initialization}async initializeRuntime(){if(!await this.runtime.isSupportedPlatform())throw new T$(`Workspace sandbox is unsupported on ${process.platform}`);let $=await this.runtime.checkDependencies();if($.errors.length>0)throw new T$(`Workspace sandbox dependencies are unavailable: ${$.errors.join("; ")}`);try{await this.runtime.initialize(d2(["*"]))}catch(Z){throw new T$(`Workspace sandbox failed to initialize: ${Z instanceof Error?Z.message:String(Z)}`)}}async prepareTempRoot(){return await S1(this.tempRoot,{recursive:!0}),m2(this.tempRoot)}}function P1($,Z){let J=Z.toLowerCase();return $===71&&J.includes("sandbox-exec")||J.includes("sandbox_apply: operation not permitted")||J.includes("bwrap: creating new namespace failed")||J.includes("failed to create new user namespace")||J.includes("srt-win sandbox failed")}var N7=new e6,j7={prepare:($)=>N7.prepare($)},g2=new t6(j7);class t{static instance=null;processes=new Map;static getInstance(){if(!t.instance)t.instance=new t;return t.instance}startBackgroundProcess($){let Z=`bash_${T7()}`,J={};for(let[Q,W]of Object.entries({...process.env,...$.env,...$.sandboxedCommand?.env,BLADE_CLI:"1"}))if(W!==void 0)J[Q]=W;let U=$.sandboxedCommand?.executable??"bash",X=$.sandboxedCommand?.args??["-c",$.command],{child:Y,processTree:H}=u0(U,X,{cwd:$.cwd||A(),env:J,stdio:["pipe","pipe","pipe"]}),z={id:Z,command:$.command,sessionId:$.sessionId,cwd:$.cwd,env:$.env,process:Y,processTree:H,pid:Y.pid,status:"running",startTime:Date.now(),pendingStdout:new p2,pendingStderr:new p2,sandboxed:Boolean($.sandboxedCommand)};return Y.stdout?.setEncoding("utf8"),Y.stderr?.setEncoding("utf8"),Y.stdout?.on("data",(Q)=>{z.pendingStdout.append(Q)}),Y.stderr?.on("data",(Q)=>{z.pendingStderr.append(Q)}),Y.on("close",(Q,W)=>{$.sandboxedCommand?.cleanup();let B=z.sandboxed&&P1(Q,z.pendingStderr.peek().content);if(z.status=z.status==="killed"?"killed":B?"error":"exited",z.exitCode=Q,z.signal=W,B)z.errorMessage="Workspace sandbox failed to start; command was not executed";z.endTime=Date.now(),z.process=void 0}),Y.on("error",(Q)=>{$.sandboxedCommand?.cleanup(),z.status="error",z.errorMessage=Q.message,z.endTime=Date.now(),z.process=void 0,z.pendingStderr.append(`
|
|
2
2
|
[error] ${Q.message}`)}),this.processes.set(Z,z),z}consumeOutput($,Z){let J=this.getProcess($,Z);if(!J)return;let U=J.pendingStdout.consume(),X=J.pendingStderr.consume();return{id:J.id,command:J.command,status:J.status,stdout:U.content,stderr:X.content,stdoutOmittedBytes:U.omittedBytes,stderrOmittedBytes:X.omittedBytes,exitCode:J.exitCode,signal:J.signal,pid:J.pid,startedAt:J.startTime,endedAt:J.endTime,errorMessage:J.errorMessage,sandboxed:J.sandboxed}}getProcess($,Z){let J=this.processes.get($);return J?.sessionId===Z?J:void 0}listForSession($){return Array.from(this.processes.values()).filter((Z)=>Z.sessionId===$)}async writeInput($,Z,J,U=!1){let X=this.getProcess($,Z);if(!X)return;let Y=X.process?.stdin;if(X.status!=="running"||!Y||Y.destroyed||Y.writableEnded)return{success:!1,status:X.status,bytesWritten:0,stdinClosed:!Y||Y.destroyed||Y.writableEnded,errorMessage:"Shell stdin is not writable"};try{return await new Promise((H,z)=>{let Q=(B)=>{Y.off("error",Q),z(B)},W=(B)=>{if(Y.off("error",Q),B)z(B);else H()};if(Y.once("error",Q),U)Y.end(J,W);else Y.write(J,W)}),{success:!0,status:X.status,bytesWritten:Buffer.byteLength(J),stdinClosed:U}}catch(H){return{success:!1,status:X.status,bytesWritten:0,stdinClosed:Y.destroyed||Y.writableEnded,errorMessage:H instanceof Error?H.message:"Failed to write stdin"}}}async kill($,Z){let J=this.getProcess($,Z);if(!J)return;return this.terminateProcess(J)}async killSession($){let Z=this.listForSession($);await Promise.all(Z.map((J)=>this.terminateProcess(J)));for(let J of Z)this.processes.delete(J.id)}async terminateProcess($){if($.status!=="running"||!$.process)return{success:!1,alreadyExited:!0,status:$.status,pid:$.pid,exitCode:$.exitCode,signal:$.signal};$.status="killed",$.endTime=Date.now();let Z=await $.processTree?.terminate();if(!Z?.success)return $.status="error",$.errorMessage="Failed to terminate owned process tree",{success:!1,alreadyExited:Z?.alreadyExited??!1,status:$.status,pid:$.pid,exitCode:$.exitCode,signal:$.signal};return{success:!0,alreadyExited:Z.alreadyExited,status:$.status,pid:$.pid,exitCode:$.exitCode,signal:$.signal}}async killAll(){await Promise.all(Array.from(this.processes.values()).map(($)=>this.terminateProcess($))),this.processes.clear()}}import{stat as qH}from"node:fs/promises";import{Mutex as wH}from"async-mutex";import{nanoid as DH}from"nanoid";import*as n9 from"os";import*as U0 from"path";import*as k0 from"fs/promises";class f${async readTextFile($){return k0.readFile($,"utf-8")}async writeTextFile($,Z){await k0.writeFile($,Z,"utf-8")}async exists($){try{return await k0.access($),!0}catch{return!1}}async readBinaryFile($){return k0.readFile($)}async stat($){try{let Z=await k0.stat($);return{size:Z.size,isDirectory:Z.isDirectory(),isFile:Z.isFile(),mtime:Z.mtime}}catch{return null}}async mkdir($,Z){await k0.mkdir($,{recursive:Z?.recursive??!1,mode:Z?.mode??493})}}var f7=new f$;function V$(){return f7}var D0=g("Agent");class Y1{connection;sessionId;capabilities;fallback;constructor($,Z,J,U=new f$){this.connection=$;this.sessionId=Z;this.capabilities=J;this.fallback=U}async readTextFile($){if(!this.capabilities.readTextFile)return D0.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return D0.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Z){throw D0.warn(`[AcpFileSystem] readTextFile ACP failed: ${Z}`),Z}}async writeTextFile($,Z){if(!this.capabilities.writeTextFile)return D0.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Z);try{D0.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Z,sessionId:this.sessionId})}catch(J){throw D0.warn(`[AcpFileSystem] writeTextFile ACP failed: ${J}`),J}}async exists($){if(!this.capabilities.readTextFile)return D0.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),D0.debug(`[AcpFileSystem] exists(${$}): true (ACP read success)`),!0}catch(Z){let J=String(Z).toLowerCase();if(["not found","no such file","enoent","does not exist","file not found","path not found"].some((H)=>J.includes(H)))return D0.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let Y=M7(J);return D0.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${Y} error`,{error:String(Z),errorType:Y,filePath:$}),!0}}async readBinaryFile($){return D0.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return D0.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Z){return D0.debug(`[AcpFileSystem] mkdir fallback: ${$}`),this.fallback.mkdir($,Z)}getCapabilities(){return this.capabilities}canReadTextFile(){return this.capabilities.readTextFile??!1}canWriteTextFile(){return this.capabilities.writeTextFile??!1}usesRemoteFiles(){return this.canReadTextFile()||this.canWriteTextFile()}}function M7($){if($.includes("permission")||$.includes("access denied"))return"permission";if($.includes("timeout")||$.includes("timed out"))return"timeout";if($.includes("binary")||$.includes("encoding"))return"binary";if($.includes("too large")||$.includes("size"))return"size";if($.includes("connection")||$.includes("network"))return"network";return"unknown"}var d0=g("Agent");class i2{async execute($,Z){return new Promise((J)=>{let U=process.platform==="win32"?"cmd.exe":"/bin/bash",X=process.platform==="win32"?["/c",$]:["-c",$],{child:Y,processTree:H}=u0(U,X,{cwd:Z?.cwd||A(),env:{...process.env,...Z?.env},stdio:["pipe","pipe","pipe"]}),z,Q=()=>{return z??=H.terminate(),z},W="",B="",V=!1,E=Z?.timeout?setTimeout(()=>{V=!0,Q()},Z.timeout):null,O=null,G=()=>{if(E)clearTimeout(E);if(O&&Z?.signal)Z.signal.removeEventListener("abort",O),O=null};if(Z?.signal){if(O=()=>{V=!0,Q()},Z.signal.addEventListener("abort",O),Z.signal.aborted)O()}Y.stdout?.on("data",(K)=>{let F=K.toString();W+=F,Z?.onOutput?.(F)}),Y.stderr?.on("data",(K)=>{let F=K.toString();B+=F,Z?.onOutput?.(F)}),Y.on("close",async(K)=>{if(G(),V)await Q();J({success:K===0&&!V,stdout:W,stderr:B,exitCode:K,error:V?"Command was terminated":void 0})}),Y.on("error",(K)=>{G(),J({success:!1,stdout:W,stderr:B,exitCode:null,error:K.message})})})}isAvailable(){return!0}}class $4{connection;sessionId;fallback;constructor($,Z,J=new i2){this.connection=$;this.sessionId=Z;this.fallback=J}async execute($,Z){try{d0.debug(`[AcpTerminal] Executing command via ACP: ${$}`);let J=await this.connection.createTerminal({sessionId:this.sessionId,command:$,cwd:Z?.cwd,env:Z?.env?Object.entries(Z.env).map(([W,B])=>({name:W,value:B})):void 0}),U=0,X=null;if(Z?.onOutput)X=setInterval(async()=>{try{let B=(await J.currentOutput()).output||"";if(B.length>U){let V=B.slice(U);U=B.length,Z.onOutput?.(V)}}catch{}},100);let Y=(W=!1)=>{if(X)clearInterval(X),X=null;(W?J.kill().then(()=>d0.debug("[AcpTerminal] Killed remote command")).catch(()=>{}).then(()=>J.release()).catch(()=>{}):J.release().catch(()=>{})).catch(()=>{})},H=[];if(H.push(J.waitForExit().then((W)=>({type:"completed",exitCode:W.exitCode??null}))),Z?.timeout)H.push(new Promise((W)=>{setTimeout(()=>W({type:"timeout"}),Z.timeout)}));if(Z?.signal)H.push(new Promise((W)=>{if(Z.signal.aborted)W({type:"aborted"});else Z.signal.addEventListener("abort",()=>W({type:"aborted"}),{once:!0})}));let z=await Promise.race(H),Q="";try{if(Q=(await J.currentOutput()).output||"",Z?.onOutput&&Q.length>U)Z.onOutput(Q.slice(U))}catch{}switch(z.type){case"completed":return Y(!1),{success:z.exitCode===0,stdout:Q,stderr:"",exitCode:z.exitCode};case"timeout":return d0.debug(`[AcpTerminal] Command timed out, killing: ${$}`),Y(!0),{success:!1,stdout:Q,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return d0.debug(`[AcpTerminal] Command aborted, killing: ${$}`),Y(!0),{success:!1,stdout:Q,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(J){if(Z?.allowLocalFallback===!1)return{success:!1,stdout:"",stderr:"",exitCode:null,error:J instanceof Error?`ACP terminal unavailable: ${J.message}`:"ACP terminal unavailable"};return d0.warn("[AcpTerminal] ACP terminal failed, using fallback:",J),this.fallback.execute($,Z)}}isAvailable(){return!0}}class y{static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new y}static initializeSession($,Z,J,U){let X=J?.fs?new Y1($,Z,J.fs):new f$;if(J?.fs)d0.debug(`[AcpServiceContext:${Z}] Using ACP file system service`);let Y=new $4($,Z);d0.debug(`[AcpServiceContext:${Z}] Using ACP terminal service`),y.sessions.set(Z,{fileSystemService:X,terminalService:Y,connection:$,clientCapabilities:J||null,cwd:U}),y.currentSessionId=Z,d0.debug(`[AcpServiceContext:${Z}] Initialized with capabilities:`,{fs:!!J?.fs,readTextFile:J?.fs?.readTextFile,writeTextFile:J?.fs?.writeTextFile,cwd:U})}static destroySession($){if(y.sessions.delete($),y.currentSessionId===$){let Z=Array.from(y.sessions.keys());y.currentSessionId=Z[0]||null}d0.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return y.sessions.get($)||null}static setCurrentSession($){if(y.sessions.has($))y.currentSessionId=$}static getCurrentSessionId(){return y.currentSessionId}initialize($,Z,J,U){y.initializeSession($,Z,J,U||A())}reset(){if(y.currentSessionId)y.destroySession(y.currentSessionId)}isAcpMode(){return y.currentSessionId!==null}getFileSystemService($){let Z=$??y.currentSessionId;if(Z){let J=y.sessions.get(Z);if(J)return J.fileSystemService}return new f$}getTerminalService($){let Z=$??y.currentSessionId;if(Z){let J=y.sessions.get(Z);if(J)return J.terminalService}return new i2}getConnection(){if(y.currentSessionId){let $=y.sessions.get(y.currentSessionId);if($)return $.connection}return null}getSessionId(){return y.currentSessionId}getClientCapabilities(){if(y.currentSessionId){let $=y.sessions.get(y.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Z,J,U,X){let Y=y.currentSessionId;if(!Y)return;let H=y.sessions.get(Y);if(!H)return;try{await H.connection.sessionUpdate({sessionId:Y,update:{sessionUpdate:"tool_call",toolCallId:$,status:Z,title:J,content:U||[],kind:X||"other"}})}catch(z){d0.warn("[AcpServiceContext] Failed to send tool update:",z)}}}function E$($){return y.getInstance().getFileSystemService($)}function Z4($){return y.getInstance().getTerminalService($)}function a($){return $?y.getSessionServices($)!==null:y.getInstance().isAcpMode()}import*as m0 from"node:fs/promises";import*as V4 from"node:path";import{Mutex as C7}from"async-mutex";import{nanoid as R7}from"nanoid";import S7 from"write-file-atomic";var J4=["active","verifying","paused","blocked","usage_limited","budget_limited","complete"],U4=["pending","pass","fail","partial"];var X4=1048576,c2=1e5,E4=4000,P7=_.Object({attempt:_.Integer({minimum:1}),status:m(U4),requestedAt:_.String({format:"date-time"}),completedAt:_.Optional(_.String({format:"date-time"})),verifierSessionId:_.Optional(_.String({minLength:1})),summary:_.Optional(_.String({maxLength:E4})),evidenceSha256:_.Optional(_.String({pattern:"^[a-f0-9]{64}$"}))}),Y4=_.Object({version:_.Literal(1),sessionId:_.String({minLength:1}),goalId:_.String({minLength:1}),objective:_.String({minLength:1,maxLength:c2}),status:m(J4),tokenBudget:_.Optional(_.Integer({minimum:1})),tokensUsed:_.Integer({minimum:0}),timeUsedSeconds:_.Integer({minimum:0}),continuationCount:_.Integer({minimum:0}),statusReason:_.Optional(_.String()),completionVerification:_.Optional(P7),createdAt:_.String({format:"date-time"}),updatedAt:_.String({format:"date-time"})});function H4($,Z){return $ instanceof Error&&"code"in $&&$.code===Z}function z4($){let Z=$.trim();if(!Z)throw Error("Goal objective must not be empty");if(Z.length>c2)throw Error(`Goal objective exceeds ${c2} characters`);return Z}function I7($){if($===void 0)return;if(!Number.isInteger($)||$<=0)throw Error("Goal token budget must be a positive integer");return $}function Q4($){let Z=$?.trim();if(!Z)return;return Z.slice(0,E4)}class T0{workspaceRoot;sessionId;static mutexes=new Map;static listeners=new Set;filePath;mutex;constructor($,Z){this.workspaceRoot=$;this.sessionId=Z;this.filePath=W4($,Z);let J=T0.mutexes.get(this.filePath);if(!J)J=new C7,T0.mutexes.set(this.filePath,J);this.mutex=J}static subscribe($){return this.listeners.add($),()=>this.listeners.delete($)}static async hasActiveGoal($,Z){let J=(await new T0($,Z).get())?.status;return J==="active"||J==="verifying"}async get(){return this.mutex.runExclusive(()=>this.readUnlocked())}async create($){return this.mutex.runExclusive(async()=>{let Z=await this.readUnlocked();if(Z&&Z.status!=="complete")throw Error(`Session already has an unfinished goal (${Z.status}); clear or complete it first`);let J=new Date().toISOString(),U=I7($.tokenBudget),X={version:1,sessionId:this.sessionId,goalId:R7(12),objective:z4($.objective),status:"active",...U===void 0?{}:{tokenBudget:U},tokensUsed:0,timeUsedSeconds:0,continuationCount:0,createdAt:J,updatedAt:J};return await this.persistUnlocked(X),this.emit(X),X})}async edit($){return this.updateExisting((Z)=>{if(!["active","verifying","paused","blocked"].includes(Z.status))throw Error(`Cannot edit goal while status is ${Z.status}`);return{...Z,objective:z4($),completionVerification:void 0,status:Z.status==="verifying"?"active":Z.status,statusReason:Z.status==="verifying"?void 0:Z.statusReason,updatedAt:new Date().toISOString()}})}async pause($="paused by user"){return this.updateExisting((Z)=>{if(Z.status!=="active"&&Z.status!=="verifying"&&Z.status!=="blocked")throw Error(`Cannot pause goal while status is ${Z.status}`);return{...Z,status:"paused",statusReason:$,updatedAt:new Date().toISOString()}})}async pauseIfActive($){return this.mutex.runExclusive(async()=>{let Z=await this.readUnlocked();if(!Z||Z.status!=="active"&&Z.status!=="verifying")return Z;let J={...Z,status:"paused",statusReason:$,updatedAt:new Date().toISOString()};return await this.persistUnlocked(J),this.emit(J),J})}async resume(){return this.updateExisting(($)=>{if($.status!=="paused"&&$.status!=="blocked")throw Error(`Cannot resume goal while status is ${$.status}`);let Z=$.completionVerification?.status==="pending"||$.completionVerification?.status==="pass";return{...$,status:Z?"verifying":"active",statusReason:void 0,updatedAt:new Date().toISOString()}})}async requestCompletion(){return this.updateExisting(($)=>{if($.status!=="active"&&$.status!=="verifying")throw Error(`Cannot request goal completion while status is ${$.status}`);if($.status==="verifying"&&($.completionVerification?.status==="pending"||$.completionVerification?.status==="pass"))return $;let Z=new Date().toISOString();return{...$,status:"verifying",statusReason:"awaiting independent completion verification",completionVerification:{attempt:($.completionVerification?.attempt??0)+1,status:"pending",requestedAt:Z},updatedAt:Z}})}async recordCompletionVerification($){let Z=$.verifierSessionId?.trim();if(!Z)throw Error("Goal verification requires a verifier Session identity");if(!/^[a-f0-9]{64}$/.test($.evidenceSha256??""))throw Error("Goal verification requires a SHA-256 evidence digest");return this.updateExisting((J)=>{if(J.status!=="verifying"||!J.completionVerification)throw Error(`Cannot record goal verification while status is ${J.status}`);let U=new Date().toISOString();return{...J,statusReason:$.verdict==="pass"?"independent completion verification passed":`independent completion verification returned ${$.verdict}`,completionVerification:{...J.completionVerification,status:$.verdict,completedAt:U,verifierSessionId:Z,...Q4($.summary)?{summary:Q4($.summary)}:{},evidenceSha256:$.evidenceSha256},updatedAt:U}})}async invalidateCompletionVerification($){return this.updateExisting((Z)=>{if(Z.status!=="verifying"||!Z.completionVerification)return Z;let J=$.trim()||"goal completion evidence became stale";return{...Z,statusReason:J,completionVerification:{attempt:Z.completionVerification.attempt,status:"pending",requestedAt:Z.completionVerification.requestedAt},updatedAt:new Date().toISOString()}})}async finalizeVerifiedCompletion(){return this.updateExisting(($)=>{if($.status!=="verifying"||$.completionVerification?.status!=="pass"||!$.completionVerification.verifierSessionId||!$.completionVerification.evidenceSha256)throw Error("Goal completion requires a persisted independent PASS verdict");return{...$,status:"complete",statusReason:void 0,updatedAt:new Date().toISOString()}})}async block($){return this.updateExisting((Z)=>{if(Z.status!=="active"&&Z.status!=="verifying")throw Error(`Cannot block goal while status is ${Z.status}`);let J=$.trim();if(!J)throw Error("Blocked goal requires a reason");return{...Z,status:"blocked",statusReason:J,completionVerification:void 0,updatedAt:new Date().toISOString()}})}async recordProgress($){return this.mutex.runExclusive(async()=>{let Z=await this.readUnlocked();if(!Z||Z.status!=="active"&&Z.status!=="verifying")return Z;let J=Math.max(0,Math.round($.tokens)),U=Math.max(0,Math.round($.elapsedMs/1000)),X=Z.tokensUsed+J,Y=Z.tokenBudget!==void 0&&X>=Z.tokenBudget,H={...Z,tokensUsed:X,timeUsedSeconds:Z.timeUsedSeconds+U,status:Y?"budget_limited":Z.status,statusReason:Y?"token budget exhausted":Z.statusReason,updatedAt:new Date().toISOString()};return await this.persistUnlocked(H),this.emit(H),H})}async beginContinuation(){return this.updateExisting(($)=>{if($.status!=="active"&&$.status!=="verifying")throw Error(`Cannot continue goal while status is ${$.status}`);return{...$,continuationCount:$.continuationCount+1,updatedAt:new Date().toISOString()}})}async tryBeginContinuation(){return this.mutex.runExclusive(async()=>{let $=await this.readUnlocked();if(!$||$.status!=="active"&&$.status!=="verifying")return null;let Z={...$,continuationCount:$.continuationCount+1,updatedAt:new Date().toISOString()};return await this.persistUnlocked(Z),this.emit(Z),Z})}async clear(){return this.mutex.runExclusive(async()=>{try{await m0.unlink(this.filePath)}catch($){if(H4($,"ENOENT"))return!1;throw $}return this.emit(null),!0})}async updateExisting($){return this.mutex.runExclusive(async()=>{let Z=await this.readUnlocked();if(!Z)throw Error("Session has no goal");let J=B4(Y4,$(Z));return await this.persistUnlocked(J),this.emit(J),J})}async readUnlocked(){try{if((await m0.stat(this.filePath)).size>X4)throw Error(`Goal state exceeds ${X4} bytes`);await m0.chmod(this.filePath,384);let Z=I1(Y4,JSON.parse(await m0.readFile(this.filePath,"utf8")));if(!Z.success||Z.data.sessionId!==this.sessionId)throw Error(`Invalid goal state: ${this.filePath}`);return Z.data}catch($){if(H4($,"ENOENT"))return null;if($ instanceof SyntaxError)throw Error(`Invalid goal state JSON: ${this.filePath}`,{cause:$});throw $}}async persistUnlocked($){await m0.mkdir(V4.dirname(this.filePath),{recursive:!0,mode:448}),await S7(this.filePath,`${JSON.stringify($)}
|
|
3
3
|
`,{encoding:"utf8",mode:384,fsync:!0})}emit($){let Z={workspaceRoot:this.workspaceRoot,sessionId:this.sessionId,goal:$?{...$}:null};for(let J of T0.listeners)try{J(Z)}catch{}}}import{createHash as k7}from"node:crypto";import{promises as k1,realpathSync as v7}from"node:fs";import l from"node:path";import{fileURLToPath as y7,pathToFileURL as e0}from"node:url";var _4=g("Service"),O4=65536;class l2{name;onCrash;child;processTree;connection;closePromise;crashCleanup;capabilities;initialized=!1;stopping=!1;notificationHandlers=new Map;requestHandlers=new Map;constructor($,Z){this.name=$;this.onCrash=Z}get serverCapabilities(){return this.capabilities}get isInitialized(){return this.initialized}async start($){if(await this.crashCleanup,this.crashCleanup=void 0,this.connection)return;let Z=await import("vscode-jsonrpc/node.js"),{child:J,processTree:U}=u0($.command,[...$.args],{cwd:$.cwd,env:{...$.environment,PATH:$.environment.PATH??process.env.PATH??"",HOME:$.environment.HOME??process.env.HOME??"",USER:$.environment.USER??process.env.USER??"",SHELL:$.environment.SHELL??process.env.SHELL??"/bin/sh",BLADE_CLI:"1"},stdio:["pipe","pipe","pipe"]},{releaseOnExit:!1});this.child=J,this.processTree=U;try{if(await new Promise((H,z)=>{let Q=()=>{J.removeListener("spawn",W),J.removeListener("error",B)},W=()=>{Q(),H()},B=(V)=>{Q(),z(V)};J.once("spawn",W),J.once("error",B)}),!J.stdout||!J.stdin)throw Error("LSP server stdio is unavailable");let X="";J.stderr?.setEncoding("utf8"),J.stderr?.on("data",(H)=>{if(X.length<O4)X+=H.slice(0,O4-X.length)}),J.stdin.on("error",(H)=>{if(!this.stopping)_4.debug(`[LSP ${this.name}] stdin closed: ${H.message}`)}),this.closePromise=new Promise((H)=>{J.once("close",(z,Q)=>{this.initialized=!1;let W=!this.stopping;if(!this.stopping){let B=X.trim()?`: ${X.trim().slice(0,512)}`:Q?` (${Q})`:"";this.onCrash(Error(`LSP server "${this.name}" exited with code ${z}${B}`))}if(this.child===J){let B=this.processTree;try{this.connection?.dispose()}catch{}if(this.connection=void 0,this.child=void 0,this.closePromise=void 0,W&&B)this.crashCleanup=B.terminate().then(()=>{return}),this.processTree=void 0}H()})});let Y=Z.createMessageConnection(new Z.StreamMessageReader(J.stdout),new Z.StreamMessageWriter(J.stdin));this.connection=Y,Y.onError(([H])=>{if(!this.stopping)_4.warn(`[LSP ${this.name}] connection error: ${H.message}`)}),Y.onClose(()=>{this.initialized=!1});for(let[H,z]of this.notificationHandlers)for(let Q of z)Y.onNotification(H,Q);for(let[H,z]of this.requestHandlers)Y.onRequest(H,z);Y.listen()}catch(X){throw await this.disposeTransport(),X}}async initialize($,Z,J){let U=await this.request("initialize",$,Z,J,!1);return this.capabilities=U.capabilities,await this.notify("initialized",{}),this.initialized=!0,U}async request($,Z,J,U,X=!0){let Y=this.connection;if(!Y)throw Error(`LSP server "${this.name}" is not started`);if(X&&!this.initialized)throw Error(`LSP server "${this.name}" is not initialized`);let z=new(await import("vscode-jsonrpc/node.js")).CancellationTokenSource;return this.awaitRequest(Y.sendRequest($,Z,z.token),z,J,U,$)}async notify($,Z){if(!this.connection)throw Error(`LSP server "${this.name}" is not started`);await this.connection.sendNotification($,Z)}onNotification($,Z){let J=this.notificationHandlers.get($)??[];J.push(Z),this.notificationHandlers.set($,J),this.connection?.onNotification($,Z)}onRequest($,Z){this.requestHandlers.set($,Z),this.connection?.onRequest($,Z)}async stop($){if(!this.child&&!this.connection){await this.crashCleanup,this.crashCleanup=void 0;return}this.stopping=!0;let Z=this.connection;try{if(Z&&this.initialized){let U=new(await import("vscode-jsonrpc/node.js")).CancellationTokenSource;await this.awaitRequest(Z.sendRequest("shutdown",U.token),U,$,void 0,"shutdown").catch(()=>{return}),await Z.sendNotification("exit").catch(()=>{return})}await Promise.race([this.closePromise??Promise.resolve(),new Promise((J)=>setTimeout(J,Math.min($,500)))])}finally{await this.disposeTransport(),this.stopping=!1,this.initialized=!1,this.capabilities=void 0}}awaitRequest($,Z,J,U,X){return new Promise((Y,H)=>{let z=!1,Q=(V)=>{if(z)return;z=!0,clearTimeout(B),U?.removeEventListener("abort",W),V()},W=()=>{Z.cancel(),Q(()=>H(Error(`LSP request "${X}" was aborted`)))},B=setTimeout(()=>{Z.cancel(),Q(()=>H(Error(`LSP request "${X}" timed out after ${J}ms`)))},J);if(U?.addEventListener("abort",W,{once:!0}),U?.aborted)W();$.then((V)=>Q(()=>Y(V)),(V)=>Q(()=>H(V)))})}async disposeTransport(){let $=this.connection,Z=this.processTree;this.connection=void 0,this.processTree=void 0,this.child=void 0,this.closePromise=void 0;try{$?.dispose()}catch{}await Z?.terminate(),await this.crashCleanup,this.crashCleanup=void 0}}var x7=g("Service"),h7=10485760,u7=10,G4=30,d7=-32801;class n2{options;workspaceRoot;servers=new Map;diagnostics=new Map;delivered=new Map;waiters=new Map;disposeController=new AbortController;diagnosticSequence=0;disposed=!1;constructor($){this.options=$;let Z=l.resolve($.workspaceRoot);try{this.workspaceRoot=v7.native(Z)}catch{this.workspaceRoot=Z}for(let[J,U]of Object.entries($.servers)){if(U.enabled===!1)continue;let X={name:J,config:structuredClone(U),state:"stopped",restartCount:0,openedFiles:new Map,client:new l2(J,(Y)=>{X.state="error",X.lastError=Y.message,X.openedFiles.clear()})};X.client.onNotification("textDocument/publishDiagnostics",(Y)=>{this.captureDiagnostics(J,Y)}),X.client.onRequest("workspace/configuration",(Y)=>this.resolveWorkspaceConfiguration(U.settings,Y)),X.client.onRequest("workspace/workspaceFolders",()=>[{uri:e0(this.workspaceRoot).href,name:l.basename(this.workspaceRoot)}]),X.client.onRequest("window/workDoneProgress/create",()=>null),this.servers.set(J,X)}}get available(){return this.servers.size>0&&!this.isRemoteSession()&&!this.disposed}get workspacePath(){return this.workspaceRoot}getStatus(){return[...this.servers.values()].map(($)=>({name:$.name,state:$.state,restartCount:$.restartCount,extensions:Object.keys($.config.extensionToLanguage).sort(),...$.lastError?{lastError:$.lastError}:{}})).sort(($,Z)=>$.name.localeCompare(Z.name))}async afterToolUse($,Z,J,U){if(!this.available||this.disposed)return;let X;if(J.success&&($==="Write"||$==="Edit")&&typeof Z.file_path==="string")X=await this.syncAfterWrite(Z.file_path,U.signal);else if(J.success&&$==="ApplyPatch"){let Y=Array.isArray(J.metadata?.changes)?J.metadata.changes:[];for(let H of Y){if(!H||typeof H!=="object"||!("path"in H)||typeof H.path!=="string")continue;if("newContent"in H&&H.newContent===null)await this.syncAfterDelete(H.path);else X=await this.syncAfterWrite(H.path,U.signal)??X}}this.attachPendingDiagnostics(J,X)}async query($,Z){if(!this.available)throw Error(this.isRemoteSession()?"LSP is unavailable for ACP-owned remote files":"No LSP servers are configured for this Session");let J=await this.resolveFile($.filePath);if($.operation==="diagnostics")return{operation:$.operation,filePath:J,result:this.getCurrentDiagnostics(J)};let U=await this.ensureFileOpen(J,void 0,Z);if(!U)throw Error(`No LSP server handles ${l.extname(J)||"this file"}`);let X={line:Math.max(0,($.line??1)-1),character:Math.max(0,($.character??1)-1)},Y={uri:e0(J).href},H={goToDefinition:{method:"textDocument/definition",params:{textDocument:Y,position:X}},findReferences:{method:"textDocument/references",params:{textDocument:Y,position:X,context:{includeDeclaration:!0}}},hover:{method:"textDocument/hover",params:{textDocument:Y,position:X}},documentSymbol:{method:"textDocument/documentSymbol",params:{textDocument:Y}},workspaceSymbol:{method:"workspace/symbol",params:{query:$.query??""}},goToImplementation:{method:"textDocument/implementation",params:{textDocument:Y,position:X}},prepareCallHierarchy:{method:"textDocument/prepareCallHierarchy",params:{textDocument:Y,position:X}}},z;if($.operation==="incomingCalls"||$.operation==="outgoingCalls"){let W=(await this.requestWithRetry(U,"textDocument/prepareCallHierarchy",{textDocument:Y,position:X},Z))?.[0];z=W?await this.requestWithRetry(U,$.operation==="incomingCalls"?"callHierarchy/incomingCalls":"callHierarchy/outgoingCalls",{item:W},Z):[]}else{let Q=H[$.operation];z=await this.requestWithRetry(U,Q.method,Q.params,Z)}return{operation:$.operation,filePath:J,serverName:U.name,result:z}}async dispose(){if(this.disposed)return;this.disposed=!0,this.disposeController.abort();for(let $ of this.waiters.values())for(let Z of $)clearTimeout(Z.timer),Z.resolve();this.waiters.clear(),await Promise.allSettled([...this.servers.values()].map(async($)=>{$.state="stopping",await $.client.stop($.config.shutdownTimeout??2000),$.state="stopped",$.openedFiles.clear()})),this.diagnostics.clear(),this.delivered.clear()}isRemoteSession(){return this.options.isRemoteSession?.()??a(this.options.sessionId)}selectServer($){let Z=l.extname($).toLowerCase();return[...this.servers.values()].filter((J)=>(Z in J.config.extensionToLanguage)).sort((J,U)=>(U.config.priority??0)-(J.config.priority??0)||J.name.localeCompare(U.name))[0]}async ensureFileOpen($,Z,J){let U=this.selectServer($);if(!U)return;await this.ensureStarted(U,J);let X=e0($).href;if(U.openedFiles.has(X))return U;let Y=Z??await this.readBoundedFile($);return await U.client.notify("textDocument/didOpen",{textDocument:{uri:X,languageId:U.config.extensionToLanguage[l.extname($).toLowerCase()],version:1,text:Y}}),U.openedFiles.set(X,1),U}async syncAfterWrite($,Z){try{let J=await this.resolveFile($),U=await this.readBoundedFile(J),X=await this.ensureFileOpen(J,U,Z);if(!X)return;let Y=e0(J).href,H=this.diagnostics.get(Y)?.sequence??0;this.delivered.delete(Y);let z=X.openedFiles.get(Y)??0;if(z>0){let Q=z+1;await X.client.notify("textDocument/didChange",{textDocument:{uri:Y,version:Q},contentChanges:[{text:U}]}),X.openedFiles.set(Y,Q)}return await X.client.notify("textDocument/didSave",{textDocument:{uri:Y},text:U}),await this.waitForDiagnostics(Y,H,X.config.diagnosticWaitTimeout??750,Z),J}catch(J){if(!Z?.aborted&&!this.disposeController.signal.aborted)x7.debug(`[LSP] post-edit sync skipped: ${J instanceof Error?J.message:String(J)}`);return}}async syncAfterDelete($){let Z=await this.resolveMissingFile($).catch(()=>{return});if(!Z)return;if(!this.isInsideWorkspace(Z))return;let J=e0(Z).href;for(let U of this.servers.values()){if(!U.openedFiles.has(J))continue;await U.client.notify("textDocument/didClose",{textDocument:{uri:J}}).catch(()=>{return}),U.openedFiles.delete(J)}this.diagnostics.delete(J),this.delivered.delete(J)}async ensureStarted($,Z){if($.state==="running")return;if($.startPromise)return $.startPromise;if($.state==="error"){if($.restartCount>=($.config.maxRestarts??3))throw Error(`LSP server "${$.name}" exceeded its restart limit`);$.restartCount++}let J=this.startServer($,Z).finally(()=>{$.startPromise=void 0});return $.startPromise=J,J}async startServer($,Z){$.state="starting";try{await $.client.start({command:$.config.command,args:$.config.args??[],cwd:this.workspaceRoot,environment:{...this.options.environment,...$.config.env,BLADE_SESSION_ID:this.options.sessionId}});let J=e0(this.workspaceRoot).href,U={processId:process.pid,rootPath:this.workspaceRoot,rootUri:J,workspaceFolders:[{uri:J,name:l.basename(this.workspaceRoot)}],initializationOptions:$.config.initializationOptions??{},capabilities:{workspace:{configuration:!0,workspaceFolders:!0,symbol:{dynamicRegistration:!1}},textDocument:{synchronization:{dynamicRegistration:!1,willSave:!1,willSaveWaitUntil:!1,didSave:!0},publishDiagnostics:{relatedInformation:!0,versionSupport:!1},hover:{dynamicRegistration:!1,contentFormat:["markdown","plaintext"]},definition:{dynamicRegistration:!1,linkSupport:!0},references:{dynamicRegistration:!1},implementation:{dynamicRegistration:!1,linkSupport:!0},documentSymbol:{dynamicRegistration:!1,hierarchicalDocumentSymbolSupport:!0},callHierarchy:{dynamicRegistration:!1}},general:{positionEncodings:["utf-16"]}}};if(await $.client.initialize(U,$.config.startupTimeout??1e4,Z),$.config.settings!==void 0)await $.client.notify("workspace/didChangeConfiguration",{settings:$.config.settings});$.state="running",$.lastError=void 0}catch(J){throw $.state="error",$.lastError=J instanceof Error?J.message:String(J),await $.client.stop($.config.shutdownTimeout??2000).catch(()=>{return}),J}}async requestWithRetry($,Z,J,U){let X;for(let Y=0;Y<4;Y++)try{return await $.client.request(Z,J,$.config.requestTimeout??1e4,U)}catch(H){if(X=H,H.code!==d7||Y===3)break;await new Promise((z)=>setTimeout(z,100*2**Y))}throw X}captureDiagnostics($,Z){if(this.disposed||!Z||typeof Z!=="object"||!("uri"in Z)||!("diagnostics"in Z))return;let J=Z;if(!Array.isArray(J.diagnostics))return;let U;try{U=J.uri.startsWith("file:")?y7(J.uri):l.resolve(J.uri)}catch{return}if(!this.isInsideWorkspace(U))return;let X=e0(l.resolve(U)).href,Y={sequence:++this.diagnosticSequence,serverName:$,filePath:l.resolve(U),diagnostics:J.diagnostics.filter((Q)=>Q&&typeof Q.message==="string"&&Q.range!==void 0).slice(0,100).map((Q)=>structuredClone(Q))};this.diagnostics.set(X,Y);let H=this.waiters.get(X)??[],z=[];for(let Q of H)if(Y.sequence>Q.afterSequence)clearTimeout(Q.timer),Q.resolve();else z.push(Q);if(z.length>0)this.waiters.set(X,z);else this.waiters.delete(X)}waitForDiagnostics($,Z,J,U){if(J===0||(this.diagnostics.get($)?.sequence??0)>Z)return Promise.resolve();return new Promise((X)=>{let Y=!1,H,z=()=>{if(Y)return;Y=!0,clearTimeout(H.timer),U?.removeEventListener("abort",z);let B=(this.waiters.get($)??[]).filter((V)=>V!==H);if(B.length>0)this.waiters.set($,B);else this.waiters.delete($);X()},Q=setTimeout(z,J);H={afterSequence:Z,resolve:z,timer:Q};let W=this.waiters.get($)??[];if(W.push(H),this.waiters.set($,W),U?.addEventListener("abort",z,{once:!0}),U?.aborted)z()})}attachPendingDiagnostics($,Z){let J=[...this.diagnostics.values()].sort((z,Q)=>{if(Z){if(z.filePath===Z&&Q.filePath!==Z)return-1;if(Q.filePath===Z&&z.filePath!==Z)return 1}return Q.sequence-z.sequence}),U=[],X=[],Y=0;for(let z of J){let Q=e0(z.filePath).href,W=this.delivered.get(Q)??new Set,B=z.diagnostics.sort((E,O)=>(E.severity??4)-(O.severity??4)).filter((E)=>!W.has(this.diagnosticKey(E))).slice(0,Math.min(u7,G4-Y));if(B.length===0)continue;let V=l.relative(this.workspaceRoot,z.filePath);U.push(`${V}:`);for(let E of B){let O=E.range.start.line+1,G=E.range.start.character+1,K=["Error","Warning","Info","Hint"][(E.severity??1)-1],F=E.message.replace(/\s+/g," ").slice(0,500);U.push(` ${K??"Error"} ${O}:${G} ${F}`+(E.code!==void 0?` [${String(E.code)}]`:"")),W.add(this.diagnosticKey(E)),X.push({file:V,line:O,character:G,severity:K??"Error",message:F,server:z.serverName}),Y++}if(this.delivered.set(Q,W),Y>=G4)break}if(U.length===0)return;let H=typeof $.llmContent==="string"?$.llmContent:JSON.stringify($.llmContent);$.llmContent=`${H}
|
|
4
4
|
|
|
@@ -657,7 +657,7 @@ ${o}
|
|
|
657
657
|
</approved-plan>
|
|
658
658
|
|
|
659
659
|
IMPORTANT: Execute according to the approved plan above. Follow the steps exactly as specified.`;if(typeof E==="string")w0=E+H0;else w0=[...E,{type:"text",text:H0}]}M=yield*this.runLoop(w0,O,{...f,inputMessageId:void 0})}if(!this.sessionRuntime||!R)return M;if(M.success&&!O.signal?.aborted)await this.sessionRuntime.acknowledgeTurn(R);let h=await this.sessionRuntime.recordGoalProgress({tokens:M.metadata?.tokensUsed??0,elapsedMs:M.metadata?.duration??0});if(h)yield{kind:"goal_updated",goal:h};if(!M.success||O.signal?.aborted){if(h=await this.sessionRuntime.pauseActiveGoal(O.signal?.aborted?"goal paused after user cancellation":M.error?.message??"goal paused after turn failure"),h)yield{kind:"goal_updated",goal:h}}let p=M.success&&!O.signal?.aborted&&D<20;if(b=await this.sessionRuntime.finishTurn(R,{continuePending:p,outcome:M.success&&!O.signal?.aborted?{status:"completed",turnsCount:M.metadata?.turnsCount??0,toolCallsCount:M.metadata?.toolCallsCount??0,durationMs:M.metadata?.duration??0}:{status:"aborted",cause:O.signal?.aborted?"cancelled":"failed",turnsCount:M.metadata?.turnsCount??0,toolCallsCount:M.metadata?.toolCallsCount??0,durationMs:M.metadata?.duration??0}}),b){D++,G=!0,K=!1,w=null,E="",q=void 0,F=N(),yield{kind:"follow_up_started",queued:this.sessionRuntime.getPendingSteeringCount(),recovered:this.sessionRuntime.getRecoveredSteeringCount(),messages:L()};continue}if(!M.success||O.signal?.aborted)return M;if(h=await this.sessionRuntime.getGoal(),!h||h.status!=="active"&&h.status!=="verifying")return M;if(w=await this.sessionRuntime.beginGoalContinuation(),!w)return M;b=await this.sessionRuntime.beginTurn("goal"),G=!1,K=!0,E=w5(w),q=void 0,F=void 0,yield{kind:"goal_continuation_started",goal:w,continuation:w.continuationCount},yield{kind:"goal_updated",goal:w}}}finally{if(this.sessionRuntime&&b)await this.sessionRuntime.finishTurn(b)}}let W=typeof z==="string"?z:z.filter((E)=>E.type==="text").map((E)=>E.text).join(`
|
|
660
|
-
`),B={id:this.generateTaskId(),type:"simple",prompt:W};return{success:!0,finalMessage:(await this.executeTask(B)).content,metadata:{turnsCount:1,toolCallsCount:0,duration:0}}}async chat($,Z,J){let{drainLoop:U}=await import("./chunk-
|
|
660
|
+
`),B={id:this.generateTaskId(),type:"simple",prompt:W};return{success:!0,finalMessage:(await this.executeTask(B)).content,metadata:{turnsCount:1,toolCallsCount:0,duration:0}}}async chat($,Z,J){let{drainLoop:U}=await import("./chunk-c6rff43d.js");return U(this.chatStream($,Z,J))}async*runPlanLoop($,Z,J){x.debug("Processing Plan mode message...");let{prompt:U}=await C$({projectPath:Z.workspaceRoot||A(),mode:"plan",includeEnvironment:!0,language:this.config.language,availableSkills:this.agentResources?.skills.generateAvailableSkillsList(),communicationStyle:this.sessionRuntime?.getCommunicationStyleConfiguration().selection,communicationStyleCatalog:this.sessionRuntime?.getCommunicationStyleCatalog(),projectRuleCatalog:this.sessionRuntime?.getProjectRuleCatalog(),projectInstructionSourcePath:this.sessionRuntime?.projectRoot}),X;if(typeof $==="string")X=Q1($);else{let Y=$.filter((H)=>H.type==="text");if(Y.length>0){let H=Y[0];X=$.map((z)=>z===H?{type:"text",text:Q1(H.text)}:z)}else X=[{type:"text",text:Q1("")},...$]}return yield*this.executeLoop(X,Z,J,U)}async*runLoop($,Z,J){x.debug("Processing enhanced chat message...");let U=Z.systemPrompt??await this.buildSystemPromptOnDemand(Z.workspaceRoot||A());return yield*this.executeLoop($,Z,J,U)}async buildSystemPromptOnDemand($){let Z=this.runtimeOptions.systemPrompt,J=this.runtimeOptions.appendSystemPrompt;return(await C$({projectPath:$,replaceDefault:Z,append:J,includeEnvironment:!0,language:this.config.language,availableSkills:this.agentResources?.skills.generateAvailableSkillsList(),communicationStyle:this.sessionRuntime?.getCommunicationStyleConfiguration().selection,communicationStyleCatalog:this.sessionRuntime?.getCommunicationStyleCatalog(),projectRuleCatalog:this.sessionRuntime?.getProjectRuleCatalog(),projectInstructionSourcePath:this.sessionRuntime?.projectRoot})).prompt}executeLoop($,Z,J,U){if(!this.isInitialized)throw Error("Agent未初始化");let X=this.buildLoopDependencies();return M8(X,$,Z,J,U)}buildLoopDependencies(){return{chatService:this.chatService,toolExecutor:this.toolExecutor,executionEngine:this.executionEngine,config:this.config,runtimeOptions:this.runtimeOptions,currentModelMaxContextTokens:this.currentModelMaxContextTokens,activeSkillContext:this.activeSkillContext,onSkillActivated:($)=>{this.activeSkillContext=$,x.debug(`Skill "${$.skillName}" activated`+($.allowedTools?` with allowed tools: ${$.allowedTools.join(", ")}`:""))},onModelSwitch:($)=>this.switchModelIfNeeded($),applySkillToolRestrictions:($)=>this.applySkillToolRestrictions($),staticProjectRules:this.sessionRuntime?.getStaticProjectRules(),hydrateProjectRules:this.sessionRuntime?($)=>this.sessionRuntime.hydrateProjectRules($):void 0,resolveContextualProjectRules:this.sessionRuntime?($,Z,J,U)=>this.sessionRuntime.resolveContextualProjectRules($,Z,J,U):void 0}}async chatWithSystem($,Z){if(!this.isInitialized)throw Error("Agent未初始化");let J=[{role:"system",content:$},{role:"user",content:Z}];return(await this.chatService.chat(J)).content}getActiveTask(){return this.activeTask}getChatService(){return this.chatService}getContextManager(){return this.executionEngine?.getContextManager()}getStats(){return{initialized:this.isInitialized,activeTask:this.activeTask?.id,components:{chatService:this.chatService?"ready":"not_loaded",executionEngine:this.executionEngine?"ready":"not_loaded"}}}getAvailableTools(){return this.toolExecutor?this.toolExecutor.getRegistry().getAll():[]}getToolRegistry(){return this.toolExecutor.getRegistry()}applyToolWhitelist($){let Z=this.toolExecutor.getRegistry(),U=Z.getAll().filter((X)=>!$.includes(X.name));for(let X of U)Z.unregister(X.name);x.debug(`Applied tool whitelist: ${$.join(", ")} (removed ${U.length} tools)`)}applyToolBlacklist($){let Z=this.toolExecutor.getRegistry(),J=new Set($);for(let U of Z.getAll())if(J.has(U.name))Z.unregister(U.name);x.debug(`Applied tool blacklist: ${$.join(", ")}`)}getToolStats(){let $=this.getAvailableTools(),Z=new Map;return $.forEach((J)=>{let U=Z.get(J.kind)||0;Z.set(J.kind,U+1)}),{totalTools:$.length,toolsByKind:Object.fromEntries(Z),toolNames:$.map((J)=>J.name)}}async destroy(){this.log("销毁Agent...");try{await this.legacyMcpRegistry?.disconnectAll(),this.legacyMcpRegistry=void 0,this.log("Agent已销毁")}catch($){throw this.error("Agent销毁失败",$),$}finally{this.toolExecutor.dispose(),this.isInitialized=!1}}syncRuntimeState(){if(!this.sessionRuntime)return;this.chatService=this.sessionRuntime.getChatService(),this.executionEngine=this.sessionRuntime.getExecutionEngine(),this.attachmentCollector=this.sessionRuntime.getAttachmentCollector(),this.currentModelId=this.sessionRuntime.getCurrentModelId(),this.currentModelMaxContextTokens=this.sessionRuntime.getCurrentModelMaxContextTokens()}generateTaskId(){return`task_${Date.now()}_${Math.random().toString(36).substring(2,9)}`}log($,Z){x.debug(`[MainAgent] ${$}`,Z||"")}error($,Z){x.error(`[MainAgent] ${$}`,Z||"")}async initializeSystemPrompt(){try{let $=this.runtimeOptions.systemPrompt,Z=this.runtimeOptions.appendSystemPrompt,J=await C$({projectPath:this.sessionRuntime?.workspaceRoot??A(),replaceDefault:$,append:Z,includeEnvironment:!1,language:this.config.language,availableSkills:this.agentResources?.skills.generateAvailableSkillsList(),communicationStyle:this.sessionRuntime?.getCommunicationStyleConfiguration().selection,communicationStyleCatalog:this.sessionRuntime?.getCommunicationStyleCatalog(),projectRuleCatalog:this.sessionRuntime?.getProjectRuleCatalog(),projectInstructionSourcePath:this.sessionRuntime?.projectRoot});if(J.prompt)this.log("系统提示配置验证成功"),x.debug(`[SystemPrompt] 可用来源: ${J.sources.filter((U)=>U.loaded).map((U)=>U.name).join(", ")}`)}catch($){this.error("系统提示配置验证失败",$)}}async registerBuiltinTools(){try{let $=await z2({sessionId:"default",configDir:R8.join(C8.homedir(),".blade"),workspaceRoot:A(),resourceRoot:A(),agentResources:this.agentResources});x.debug(`Registering ${$.length} builtin tools...`),this.toolExecutor.getRegistry().registerAll($);let Z=this.toolExecutor.getRegistry().getAll().length;x.debug(`Builtin tools registered: ${Z} tools`),x.debug(`[Tools] ${this.toolExecutor.getRegistry().getAll().map((J)=>J.name).join(", ")}`),await this.registerMcpTools()}catch($){throw x.error("Failed to register builtin tools:",$),$}}async registerMcpTools(){try{let $=await d1({workspaceRoot:A(),storeServers:this.config.mcpServers??{},cliConfigs:this.runtimeOptions.mcpConfig,strictCliConfig:this.runtimeOptions.strictMcpConfig});if(Object.keys($).length===0){x.debug("No MCP servers configured");return}let Z=P0.createIsolated({artifactWriter:new z1(`legacy-${TX()}`)});this.legacyMcpRegistry=Z;for(let[Y,H]of Object.entries($))try{x.debug(`Connecting to MCP server: ${Y}`),await Z.registerServer(Y,H),x.debug(`MCP server "${Y}" connected`)}catch(z){x.warn(`Warning: MCP server "${Y}" connection failed:`,z)}let J=this.toolExecutor.getRegistry();J.setMcpCatalogBarrier(()=>Z.waitForCatalogIdle());let U=Z.getCatalogSnapshot();J.replaceMcpTools(U.tools),J.registerAll(O1(Z));let X=Z.getInstructionsSnapshot();if(J.queueMcpInstructionsChange({revision:X.revision,reason:"snapshot",replace:!0,instructions:X.instructions,removed:[]}),Z.on("catalogChanged",(Y)=>{J.replaceMcpTools(Y.tools,Y)}),Z.on("contentCatalogChanged",(Y)=>{J.queueMcpContentChange(Y)}),Z.on("resourceUpdated",(Y)=>{J.queueMcpResourceUpdated(Y)}),Z.on("connectionLifecycleChanged",(Y)=>{J.queueMcpConnectionChange(Y)}),Z.on("log",(Y)=>{J.queueMcpLog(Y)}),Z.on("instructionsChanged",(Y)=>{J.queueMcpInstructionsChange({revision:Y.revision,reason:Y.reason,replace:!1,instructions:Y.action==="added"&&Y.instruction?[{serverName:Y.serverName,...Y.instruction}]:[],removed:Y.action==="removed"?[Y.serverName]:[]})}),U.tools.length>0)x.debug(`Registered ${U.tools.length} MCP tools`),x.debug(`[MCP Tools] ${U.tools.map((Y)=>Y.name).join(", ")}`)}catch($){x.warn("Failed to register MCP tools:",$)}}async loadSubagents(){let $=await $0(A());if(this.agentResources=H2($),this.subagentRegistry=this.agentResources.subagents,this.runtimeOptions.agents?.length)this.subagentRegistry.applyOverrides(this.runtimeOptions.agents);let Z=this.subagentRegistry.getAllNames().length;if(Z>0)x.debug(`Loaded ${Z} subagents: ${this.subagentRegistry.getAllNames().join(", ")}`);else x.debug("No subagents configured")}applySkillToolRestrictions($){if(!this.activeSkillContext?.allowedTools)return $;let Z=this.activeSkillContext.allowedTools;x.debug(`Applying Skill tool restrictions: ${Z.join(", ")}`);let J=$.filter((U)=>{return Z.some((X)=>{if(X===U.name)return!0;let Y=X.match(/^(\w+)\(.*\)$/);if(Y&&Y[1]===U.name)return!0;return!1})});return x.debug(`Filtered tools: ${J.map((U)=>U.name).join(", ")} (${J.length}/${$.length})`),J}clearSkillContext(){if(this.activeSkillContext)x.debug(`Skill "${this.activeSkillContext.skillName}" deactivated`),this.activeSkillContext=void 0}async processAtMentionsForContent($){if(!this.attachmentCollector)return $;if(typeof $==="string")return this.processAtMentions($);let Z=[];for(let U of $)if(U.type==="text")Z.push(U.text);if(Z.length===0)return $;let J=Z.join(`
|
|
661
661
|
`);try{let U=await this.attachmentCollector.collect(J);if(U.length===0)return $;x.debug(`Processed ${U.length} @ file mentions in multimodal message`);let X=this.buildAttachmentText(U);if(!X)return $;return[...$,{type:"text",text:X}]}catch(U){return x.error("Failed to process @ mentions in multimodal message:",U),$}}buildAttachmentText($){let Z=[],J=[];for(let X of $)if(X.type==="file"){let Y=X.metadata?.lineRange?` (lines ${X.metadata.lineRange.start}${X.metadata.lineRange.end?`-${X.metadata.lineRange.end}`:""})`:"";Z.push(`<file path="${X.path}"${Y?` range="${Y}"`:""}>`,X.content,"</file>")}else if(X.type==="directory")Z.push(`<directory path="${X.path}">`,X.content,"</directory>");else if(X.type==="error")J.push(`- @${X.path}: ${X.error}`);let U="";if(Z.length>0)U+=`
|
|
662
662
|
|
|
663
663
|
<system-reminder>
|
|
@@ -1449,7 +1449,7 @@ ${J}
|
|
|
1449
1449
|
`)),{success:!0,message:"Schedules listed",content:Q.join(`
|
|
1450
1450
|
`)}}case"create":{let z=AQ(Y);if("error"in z)return U.sendMessage(`创建失败:${z.error}`),{success:!1,error:z.error};let Q={prompt:z.prompt,projectPath:H,trigger:z.trigger,isolation:"worktree",permissionMode:"default",enabled:!0};try{let W=await $.create(Q),B=W.nextRunAt?new Date(W.nextRunAt).toLocaleString():"(无)";return U.sendMessage(`[OK] 已创建定时任务 \`${W.id}\`
|
|
1451
1451
|
${r6(W.trigger)} · 下次运行: ${B}`),{success:!0,message:`Schedule ${W.id} created`}}catch(W){let B=W instanceof Error?W.message:String(W);return U.sendMessage(`创建失败:${B}`),{success:!1,error:B}}}case"remove":case"rm":{let z=Y[0];if(!z)return U.sendMessage("用法:/schedule remove <id>"),{success:!1,error:"Missing schedule id"};let Q=await $.remove(z);return U.sendMessage(Q?`[OK] 已删除 \`${z}\``:`未找到 \`${z}\``),{success:Q,message:Q?"Removed":"Not found"}}case"enable":case"disable":{let z=Y[0];if(!z)return U.sendMessage(`用法:/schedule ${X} <id>`),{success:!1,error:"Missing schedule id"};let Q=await $.setEnabled(z,X==="enable");return U.sendMessage(Q?`[OK] 已${X==="enable"?"启用":"停用"} \`${z}\``:`未找到 \`${z}\``),{success:Boolean(Q),message:Q?"Updated":"Not found"}}case"run":{let z=Y[0];if(!z)return U.sendMessage("用法:/schedule run <id>"),{success:!1,error:"Missing schedule id"};try{return await NQ(z),U.sendMessage(`[OK] 已触发 \`${z}\``),{success:!0,message:"Schedule triggered"}}catch(Q){let W=Q instanceof Error?Q.message:String(Q);return U.sendMessage(`运行失败:${W}`),{success:!1,error:W}}}default:return U.sendMessage(`未知子命令: ${X}
|
|
1452
|
-
使用 /schedule 查看帮助`),{success:!1,error:`Unknown subcommand: ${X}`}}}}}var U7=jQ();import*as J1 from"node:fs/promises";import*as U1 from"node:path";async function W7($,Z={}){let{maxResults:J=20,caseSensitive:U=!1,projectPath:X,storagePath:Y}=Z,H=Y??X7(X??A());if(!Y){let E=await TQ($,X??A(),J,U);if(E)return E}let z;try{z=(await J1.readdir(H)).filter((O)=>O.endsWith(".jsonl")&&!O.startsWith("agent_")).map((O)=>U1.join(H,O))}catch{return[]}let W=(await Promise.all(z.map(async(E)=>{try{let O=await J1.stat(E);return{path:E,mtime:O.mtimeMs}}catch{return null}}))).filter((E)=>E!==null).sort((E,O)=>O.mtime-E.mtime).map((E)=>E.path),B=[],V=U?$:$.toLowerCase();for(let E of W){if(B.length>=J)break;let O=U1.basename(E,".jsonl"),G=await fQ(E,V,U,O);if(B.push(...G),B.length>=J){B.length=J;break}}return B}async function TQ($,Z,J,U){try{let{syncAll:X}=await import("./chunk-y72p0x68.js"),Y=await z7();if(!Y)return null;let{SessionService:H}=await import("./chunk-
|
|
1452
|
+
使用 /schedule 查看帮助`),{success:!1,error:`Unknown subcommand: ${X}`}}}}}var U7=jQ();import*as J1 from"node:fs/promises";import*as U1 from"node:path";async function W7($,Z={}){let{maxResults:J=20,caseSensitive:U=!1,projectPath:X,storagePath:Y}=Z,H=Y??X7(X??A());if(!Y){let E=await TQ($,X??A(),J,U);if(E)return E}let z;try{z=(await J1.readdir(H)).filter((O)=>O.endsWith(".jsonl")&&!O.startsWith("agent_")).map((O)=>U1.join(H,O))}catch{return[]}let W=(await Promise.all(z.map(async(E)=>{try{let O=await J1.stat(E);return{path:E,mtime:O.mtimeMs}}catch{return null}}))).filter((E)=>E!==null).sort((E,O)=>O.mtime-E.mtime).map((E)=>E.path),B=[],V=U?$:$.toLowerCase();for(let E of W){if(B.length>=J)break;let O=U1.basename(E,".jsonl"),G=await fQ(E,V,U,O);if(B.push(...G),B.length>=J){B.length=J;break}}return B}async function TQ($,Z,J,U){try{let{syncAll:X}=await import("./chunk-y72p0x68.js"),Y=await z7();if(!Y)return null;let{SessionService:H}=await import("./chunk-1ydqqzp1.js");await X(Y,H.projectionDeriverForSearch());let z=U1.resolve(Z),Q=Q7(Y,$,z,J*4),W=U?$:$.toLowerCase(),B=[];for(let V of Q){if(V.role!=="user"&&V.role!=="assistant")continue;let E=a6(V.text,W,U,V.session_id,V.role,V.timestamp??void 0,0);if(E)B.push(E);if(B.length>=J)break}return B}catch{return null}}async function fQ($,Z,J,U){try{let X=await J1.readFile($,"utf8"),H=X.split(`
|
|
1453
1453
|
`).flatMap((V,E)=>{if(!V.trim())return[];try{return[{event:JSON.parse(V),index:E}]}catch{return[]}});if(!H.some(({event:V})=>V.type==="session_created"))return MQ(H,Z,J,U);let Q=new Map(H.flatMap(({event:V,index:E})=>typeof V.id==="string"?[[V.id,E+1]]:[])),W=Y7(H7(X,$)),B=new Map;for(let V of W){if(V.type==="message_created"&&(V.data.role==="user"||V.data.role==="assistant"))B.set(V.data.messageId,{role:V.data.role,content:[],timestamp:V.timestamp,lineNumber:Q.get(V.id)??0});if(V.type==="part_created"&&V.data.partType==="text"){let E=B.get(V.data.messageId),O=V.data.payload.text;if(E&&typeof O==="string")E.content.push(O)}}return[...B.values()].flatMap((V)=>{let E=a6(V.content.join(" "),Z,J,U,V.role,V.timestamp,V.lineNumber);return E?[E]:[]})}catch{return[]}}function MQ($,Z,J,U){return $.flatMap(({event:X,index:Y})=>{if(X.type!=="message")return[];let H=X.message;if(H?.role!=="user"&&H?.role!=="assistant"||!H.content)return[];let z=typeof H.content==="string"?H.content:Array.isArray(H.content)?H.content.filter((W)=>typeof W==="object"&&W!==null&&W.type==="text"&&typeof W.text==="string").map((W)=>W.text).join(" "):"",Q=a6(z,Z,J,U,H.role,typeof X.timestamp==="string"?X.timestamp:void 0,Y+1);return Q?[Q]:[]})}function a6($,Z,J,U,X,Y,H){if(!$)return;let z=J?$:$.toLowerCase();if(!z.includes(Z))return;let Q=z.indexOf(Z),W=Math.max(0,Q-80),B=Math.min($.length,Q+Z.length+80);return{sessionId:U,role:X,content:(W>0?"...":"")+$.slice(W,B).replace(/\n/g," ")+(B<$.length?"...":""),timestamp:Y,lineNumber:H}}function B7($){if($.length===0)return"没有找到匹配的历史记录";let Z=[`**找到 ${$.length} 条匹配:**
|
|
1454
1454
|
`];for(let J of $){let U=J.timestamp?new Date(J.timestamp).toLocaleString("zh-CN",{timeZone:"Asia/Shanghai"}):"?",X=J.role==="user"?"\uD83D\uDC64":"\uD83E\uDD16";Z.push(`${X} \`${J.sessionId.slice(0,8)}\` (${U})`),Z.push(` ${J.content}`),Z.push("")}return Z.join(`
|
|
1455
1455
|
`)}var CQ={name:"search",description:"Search past session transcripts",fullDescription:"搜索历史会话记录,查找过去的对话内容",usage:"/search <keyword>",aliases:["find","history"],category:"Session",examples:['/search 断路器 - 搜索包含"断路器"的历史对话',"/search edit tool - 搜索 edit tool 相关讨论"],async handler($,Z){let J=k(Z);if($.length===0)return J.sendMessage("**用法:** `/search <关键词>`\n\n在历史会话中搜索包含指定关键词的对话"),{success:!0,message:"显示帮助"};let U=$.join(" ");J.sendMessage(`正在搜索: "${U}" ...`);try{let X=await W7(U,{maxResults:15,projectPath:Z.cwd}),Y=B7(X);return J.sendMessage(Y),{success:!0,message:`found ${X.length} results`,data:{matches:X.length}}}catch(X){let Y=X instanceof Error?X.message:"未知错误";return J.sendMessage(`搜索失败: ${Y}`),{success:!1,error:Y}}}},V7=CQ;var RQ={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Z)=>{try{return await C0({cwd:Z.workspaceRoot??Z.cwd}).refresh(),d$(Z.workspaceRoot??Z.cwd),await u$(Z.workspaceRoot??Z.cwd),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(J){let U=`获取 Skills 失败: ${J instanceof Error?J.message:"未知错误"}`;return P().addAssistantMessage(U),{success:!1,error:U}}}},E7=RQ;import SQ from"node:path";function y2($){if($<1000)return`${$}ms`;let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let J=Math.floor(Z/60);if(J<60)return`${J}m ${Z%60}s`;return`${Math.floor(J/60)}h ${J%60}m`}function _7($){switch($){case"running":return"[RUNNING]";case"completed":case"exited":return"[OK]";case"failed":case"error":return"[FAIL]";case"killed":case"cancelled":return"[STOPPED]";default:return"[?]"}}function O7($,Z){if($.length<=Z)return $;return $.slice(0,Z-3)+"..."}async function PQ($,Z){let J=k(Z),U=$[0],X=t.getInstance(),Y=s.getInstance(),H=Z.sessionId??"",z=Z.sessionId?{sessionId:Z.sessionId,projectPath:SQ.resolve(Z.workspaceRoot??Z.cwd)}:void 0;if(U==="resume"){let O=$[1],G=$.slice(2).join(" ").trim();if(!O||!G)return{success:!1,error:"Usage: /tasks resume <agentId> <prompt>"};if(!Z.subagents)return{success:!1,error:"This surface does not own a subagent runtime"};let K=await Z.subagents.resume(O,G),F=`Resumed \`${O}\` as \`${K.session.id}\` (depth ${K.session.resumeDepth}).`;return J.sendMessage(F),{success:!0,message:F,data:{action:"subagent_resumed",sourceAgentId:O,subagent:K.session}}}if(U==="clean"){let O=Y.cleanupExpiredSessionsForParent(z??H,0);return J.sendMessage(`已清理 ${O} 个已完成的 Agent 会话`),{success:!0,message:`Cleaned ${O} agent sessions`}}let Q=[`**后台任务列表**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ud as a,vd as b,wd as c}from"./chunk-
|
|
1
|
+
import{ud as a,vd as b,wd as c}from"./chunk-y5fk4fx5.js";import"./chunk-et9k9pac.js";import"./chunk-y2g5a5bp.js";import"./chunk-96h588rd.js";import"./chunk-3qhqbj09.js";import"./chunk-prgh321y.js";import"./chunk-jpwfq49n.js";import"./chunk-yqfqj7mh.js";import"./chunk-cyda7gnb.js";import"./chunk-1n60pgsq.js";import"./chunk-qkrssft1.js";import"./chunk-yvf4nmds.js";import"./chunk-6g5k5de1.js";export{c as snapshotWorkspaceModelResources,b as resolveWorkspaceModelResources,a as cloneWorkspaceModelConfig};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as uJ,c as lJ,d as dJ}from"./chunk-d9k98jy2.js";import{j as e9,k as $J}from"./chunk-zdkc4kj1.js";import{r as p8}from"./chunk-
|
|
1
|
+
import{b as uJ,c as lJ,d as dJ}from"./chunk-d9k98jy2.js";import{j as e9,k as $J}from"./chunk-zdkc4kj1.js";import{r as p8}from"./chunk-t8g4288j.js";import{$ as g4,F as _$,H as C4,I as I4,L as J8,M as WJ,N as LJ,Q as BJ,R as wJ,W as w6,X as b6,Y as ZY,Z as E4,ba as U6,t as q6,w as s2,x as a2,y as e4,z as YY}from"./chunk-hmvyreyx.js";import{fa as I9,ga as T9,ha as f9,ka as JY}from"./chunk-3gra6n0k.js";import"./chunk-qt114yth.js";import{Va as l4,hb as u2}from"./chunk-ctkxf0y7.js";import{sb as X8}from"./chunk-095x2ykj.js";import{Hb as m4,Pb as k4,Qb as x2,Rb as v4,Tb as D8,_b as Q8,bc as P0}from"./chunk-zek2ec3c.js";import"./chunk-8rzwyknk.js";import{zc as cJ}from"./chunk-wt7gy9bm.js";import{Ac as G8,Bc as c8,Dc as T1}from"./chunk-6r0nj7ay.js";import"./chunk-k3nkcaap.js";import{Hc as C$,Ic as d0,Jc as s1,Kc as RQ,Lc as D$,Mc as V8,Nc as o6,Oc as uQ,Pc as d9,Qc as n6,Rc as k$,Sc as Q1,Tc as $Y,Uc as r0,Vc as pJ,Wc as b2,Xc as Y8,_c as j4,fd as g0}from"./chunk-8mafna0v.js";import"./chunk-6pa6c2n0.js";import"./chunk-yz2bsntj.js";import"./chunk-xet98pc1.js";import{rd as lQ}from"./chunk-kbpc97n3.js";import"./chunk-5chec8rs.js";import"./chunk-y5fk4fx5.js";import{Ad as W6,Dd as kJ,Jd as HJ,Pd as QY}from"./chunk-yp02wzek.js";import"./chunk-r1jxbx1h.js";import"./chunk-6sb7cg95.js";import"./chunk-2c3zavy2.js";import{be as IQ,de as U1}from"./chunk-5ra89kse.js";import"./chunk-q3c07kb4.js";import{fe as tJ,ie as n1}from"./chunk-6207mbmr.js";import{Me as sJ,We as FJ,Xe as eJ}from"./chunk-et9k9pac.js";import"./chunk-y2g5a5bp.js";import"./chunk-96h588rd.js";import{gf as V$,hf as j8,if as TQ}from"./chunk-3qhqbj09.js";import{mf as x0}from"./chunk-prgh321y.js";import{nf as n9,of as t9,rf as V1}from"./chunk-jpwfq49n.js";import"./chunk-yqfqj7mh.js";import{Df as g9}from"./chunk-cyda7gnb.js";import{Ef as sQ}from"./chunk-1n60pgsq.js";import"./chunk-qkrssft1.js";import"./chunk-yvf4nmds.js";import{Qf as CQ}from"./chunk-6g5k5de1.js";import{useMemoizedFn as k2}from"ahooks";import{useEffect as jX,useState as v2}from"react";import{useMemoizedFn as t0}from"ahooks";import{Box as q$}from"ink";import{useEffect as U$,useMemo as TX,useRef as I2}from"react";import{useShallow as GY}from"zustand/react/shallow";import{useStore as XY}from"zustand";function s($){return XY(k$,$)}var KY=[],v$=()=>s(($)=>$.session.sessionId),I1=()=>s(($)=>$.session.workspaceRoot),eQ=()=>s(($)=>$.session.messages),$4=()=>s(($)=>$.session.clearCount),Q4=()=>s(($)=>$.session.isCompacting),J4=()=>s(($)=>$.session.tokenUsage.estimatedCostUsd),Y4=()=>s(($)=>$.session.providerRetry),Z4=()=>s(($)=>$.session.providerStall),a1=()=>s(($)=>$.session.actions),X4=()=>s(($)=>{let{inputTokens:Q,maxContextTokens:Y}=$.session.tokenUsage;if(Y<=0)return 100;let J=Math.max(0,100-Q/Y*100);return Math.round(J)}),G4=()=>s(($)=>$.app.initializationStatus),K4=()=>s(($)=>$.app.initializationError),P8=()=>s(($)=>$.app.activeModal),q4=()=>s(($)=>$.app.tasks),U4=()=>s(($)=>$.app.modelEditorTarget),z4=()=>s(($)=>$.app.sessionSelectorData),O4=()=>s(($)=>$.app.awaitingSecondCtrlC),i1=()=>s(($)=>$.app.actions),y8=()=>s(($)=>$.app.initializationStatus==="ready"),_4=()=>s(($)=>$.app.tasks.length>0),S$=()=>s(($)=>$.config.config?.permissionMode||"default"),N4=()=>s(($)=>$.config.config?.models??KY),R8=()=>s(($)=>{let Q=$.config.config;if(!Q)return;let Y=Q.currentModelId;return Q.models.find((Z)=>Z.id===Y)??Q.models[0]}),M8=()=>s(($)=>$.config.config?.currentModelId),A0=()=>s(($)=>{return d0.getTheme()}),F4=()=>s(($)=>$.config.config?.theme??"default"),$1=()=>s(($)=>$.focus.currentFocus),H4=()=>s(($)=>$.focus.actions),o1=()=>s(($)=>$.command.isProcessing),W4=()=>s(($)=>$.command.actions),C8=()=>s(($)=>$.command.pendingCommands),L4=()=>s(($)=>$.command.recoveredSteeringCount),I8=()=>s(($)=>$.app.thinkingModeEnabled),T8=()=>s(($)=>$.app.reasoningEffort),f8=()=>s(($)=>$.app.serviceTier),k8=()=>s(($)=>$.app.responseVerbosity),v8=()=>s(($)=>$.app.communicationStyle),B4=()=>s(($)=>$.session.currentThinkingContent),w4=()=>s(($)=>$.session.thinkingExpanded),b4=()=>s(($)=>$.session.currentStreamingMessageId),A4=()=>s(GY(($)=>({lines:$.session.currentStreamingLines,tail:$.session.currentStreamingTail,lineCount:$.session.currentStreamingLineCount,version:$.session.currentStreamingVersion}))),P4=()=>s(($)=>$.session.finalizingStreamingMessageId),y4=()=>s(($)=>$.session.historyExpanded),R4=()=>s(($)=>$.session.expandedMessageCount);import{useMemoizedFn as h$}from"ahooks";import{useEffect as p2,useRef as u4}from"react";function qY($){if(!($ instanceof Error))return"未知错误";let J=$.lastError??$;if(J.responseBody)try{let G=JSON.parse(J.responseBody)?.error?.message;if(G){let q=J.statusCode?` (HTTP ${J.statusCode})`:"";return`${G}${q}`}}catch{}let Z=$.message.match(/Last error:\s*(.+)$/);if(Z)return Z[1];return $.message}function UY($){if(!($ instanceof Error))return!1;return $.name==="AbortError"||$.message.includes("aborted")}function zY($){if(!($ instanceof Error))return!1;let Q=$.message;return Q.includes("can only concatenate str")||Q.includes("image_url")||Q.includes("multimodal")||Q.includes("vision")||Q.includes("does not support images")}function S8($){let Q=UY($),Y=zY($),J;if(Y)J="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";else J=qY($);return{displayMessage:J,isAbort:Q,isVisionNotSupported:Y}}import{appendFileSync as OY,mkdirSync as _Y,writeFileSync as NY}from"node:fs";import FY from"node:os";import j2 from"node:path";var M4=null;function HY(){let $=process.env.BLADE_STORAGE_ROOT||j2.join(FY.homedir(),".blade");return j2.join($,"logs","stream-debug.log")}function WY($){if(M4===$)return;let Q=j2.dirname($);_Y(Q,{recursive:!0,mode:493}),NY($,`=== Stream Debug Log Started: ${new Date().toISOString()} ===
|
|
2
2
|
`),M4=$}function h2($,Q,Y){try{let J=HY();WY(J);let Z=new Date().toISOString(),X=Y?` | ${JSON.stringify(Y)}`:"",G=`[${Z}] [${$}] ${Q}${X}
|
|
3
3
|
`;OY(J,G)}catch{}}var $8=n1("UI");function T4($,Q){let Y=!1;return(J)=>{switch(J.kind){case"content_delta":if(Y||$.signal.aborted)break;Q.contentDeltaCount++,Q.contentDeltaTotalLen+=J.delta.length,h2("loopEventHandler","onContentDelta",{callCount:Q.contentDeltaCount,deltaLen:J.delta.length,totalLen:Q.contentDeltaTotalLen}),$.streamingBuffer.batchAppendContent(J.delta);break;case"thinking_delta":if(Y||$.signal.aborted)break;if($.thinkingModeEnabled)$.streamingBuffer.batchAppendThinking(J.delta);break;case"stream_end":{if($.sessionActions.setProviderRetry(null),$.sessionActions.setProviderStall(null),$8.debug("[loopEventHandler] stream_end",{contentDeltaCount:Q.contentDeltaCount,contentDeltaTotalLen:Q.contentDeltaTotalLen,streamFinalized:Y,signalAborted:$.signal.aborted}),h2("loopEventHandler","onStreamEnd",{contentDeltaCallCount:Q.contentDeltaCount,contentDeltaTotalLen:Q.contentDeltaTotalLen,streamFinalized:Y,signalAborted:$.signal.aborted}),Y||$.signal.aborted){Y=!0;break}let{extraContent:Z,extraThinking:X}=$.streamingBuffer.drainPendingBuffers(),G=$.getStreamingMessageId();if(G){if(Z)D$(G,Z);V8(G)}$.sessionActions.finalizeStreamingMessage(Z,X),Y=!0;break}case"model_fallback":Y=!0,$.sessionActions.setProviderRetry(null),$.sessionActions.setProviderStall(null),$.streamingBuffer.resetStreamingBuffers(),$.sessionActions.discardStreamingMessage(),$.sessionActions.setCurrentThinkingContent(null);break;case"provider_retry":{let{kind:Z,...X}=J;$.sessionActions.setProviderRetry(J.phase==="scheduled"||J.phase==="attempt"?X:null);break}case"provider_stall":{let{kind:Z,...X}=J;$.sessionActions.setProviderStall(J.phase==="detected"?X:null);break}case"tool_start":{let Z=J.toolCall;if(!("function"in Z))break;if(Z.function.name===D8)break;if($8.debug("[loopEventHandler] tool_start",{toolName:Z.function.name,toolKind:J.toolKind}),["TaskCreate","TaskUpdate","TaskList"].includes(Z.function.name))break;try{let X=JSON.parse(Z.function.arguments),G=C4(Z.function.name,X);$.sessionActions.addToolMessage(G,{toolCallId:Z.id,toolName:Z.function.name,phase:"start",summary:G,params:X})}catch(X){$8.error("[loopEventHandler] onToolStart error:",X)}break}case"tool_progress":{let Z=J.toolCall;if(!("function"in Z))break;if(Z.function.name===D8)break;let X=J.update.total!==void 0?` ${Math.max(0,Math.min(100,Math.round((J.update.progress??0)/J.update.total*100)))}%`:"",G=`${Z.function.name}${X}: ${J.update.message}`;$.sessionActions.addToolMessage(G,{toolCallId:Z.id,toolName:Z.function.name,phase:"progress",summary:G});break}case"tool_result":{let Z=J.toolCall;if(!("function"in Z))break;if(Z.function.name===D8)break;$8.debug("[loopEventHandler] tool_result",{toolName:Z.function.name,success:J.result.success});let X=I4(Z.function.name,J.result);$.sessionActions.addToolMessage(X.summary,{toolCallId:Z.id,toolName:Z.function.name,phase:"complete",summary:X.summary,detail:X.detail});break}case"structured_output":$.sessionActions.replaceLastAssistantMessage(JSON.stringify(J.output,null,2));break;case"token_usage":$.sessionActions.updateTokenUsage(J.usage);break;case"compaction":if($.sessionActions.setCompacting(J.phase==="start"),J.phase==="end"){if($.sessionActions.resetContextUsage(),J.outcome!=="failed")Q.compactionCount=(Q.compactionCount??0)+1}break;case"turn_start":$8.debug("[loopEventHandler] turn_start",{turn:J.turn,maxTurns:J.maxTurns}),$.sessionActions.updateTokenUsage({turnCount:J.turn}),$.sessionActions.setProviderRetry(null),$.sessionActions.setProviderStall(null),Y=!1;break;case"task_update":$.appActions.setTasks(J.tasks);break;case"mcp_catalog_changed":{let Z=`MCP catalog r${J.revision}: +${J.added.length} -${J.removed.length} ~${J.updated.length}`;$.sessionActions.addToolMessage(Z,{toolName:"MCP Catalog",phase:"complete",summary:Z,detail:[J.added.length>0?`Added: ${J.added.join(", ")}`:"",J.removed.length>0?`Removed: ${J.removed.join(", ")}`:"",J.updated.length>0?`Updated: ${J.updated.join(", ")}`:""].filter(Boolean).join(`
|
|
4
4
|
`)});break}case"mcp_content_changed":{let Z=`MCP ${J.contentKind} r${J.revision}: +${J.added.length} -${J.removed.length} ~${J.updated.length}`;$.sessionActions.addToolMessage(Z,{toolName:"MCP Content",phase:"complete",summary:Z,detail:[J.added.length>0?`Added: ${J.added.join(", ")}`:"",J.removed.length>0?`Removed: ${J.removed.join(", ")}`:"",J.updated.length>0?`Updated: ${J.updated.join(", ")}`:""].filter(Boolean).join(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as y,g as A,h as C,i as D}from"./chunk-
|
|
1
|
+
import{f as y,g as A,h as C,i as D}from"./chunk-5a8tqdrk.js";import"./chunk-zdkc4kj1.js";import"./chunk-fa6313dv.js";import"./chunk-t8g4288j.js";import"./chunk-qwxqfb9z.js";import"./chunk-hmvyreyx.js";import"./chunk-3gra6n0k.js";import"./chunk-qt114yth.js";import"./chunk-ctkxf0y7.js";import"./chunk-095x2ykj.js";import"./chunk-zek2ec3c.js";import"./chunk-8rzwyknk.js";import"./chunk-k3nkcaap.js";import{Xc as q}from"./chunk-8mafna0v.js";import"./chunk-6pa6c2n0.js";import"./chunk-yz2bsntj.js";import"./chunk-xet98pc1.js";import"./chunk-kbpc97n3.js";import"./chunk-5chec8rs.js";import"./chunk-y5fk4fx5.js";import"./chunk-yp02wzek.js";import"./chunk-r1jxbx1h.js";import"./chunk-6sb7cg95.js";import"./chunk-2c3zavy2.js";import"./chunk-5ra89kse.js";import"./chunk-q3c07kb4.js";import"./chunk-6207mbmr.js";import"./chunk-et9k9pac.js";import"./chunk-y2g5a5bp.js";import"./chunk-96h588rd.js";import"./chunk-3qhqbj09.js";import"./chunk-prgh321y.js";import"./chunk-jpwfq49n.js";import"./chunk-yqfqj7mh.js";import"./chunk-cyda7gnb.js";import"./chunk-1n60pgsq.js";import"./chunk-qkrssft1.js";import"./chunk-yvf4nmds.js";import"./chunk-6g5k5de1.js";import H from"chalk";var R={command:"serve",describe:"Start a headless Blade server (no browser)",builder:y,handler:async(E)=>{let f=A(E);if(await q(),!process.env.BLADE_SERVER_PASSWORD)console.log(H.yellow("Warning: BLADE_SERVER_PASSWORD is not set; server is unsecured."));let b=await D.listenAsync(f);if(console.log(`Blade server listening on http://${b.hostname}:${b.port}`),f.hostname==="0.0.0.0"){let F=C();for(let G of F)console.log(` Network: http://${G}:${b.port}`)}await new Promise(()=>{}),await b.stop()}};export{R as serveCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{C as o}from"./chunk-
|
|
1
|
+
import{C as o}from"./chunk-hmvyreyx.js";import{bc as i}from"./chunk-zek2ec3c.js";import a from"node:path";function n(e){let s=e.replace(/\s+/g," ").trim();return s.length<=72?s:`${s.slice(0,69)}...`}function c(e){let s=e.replace(/\s+/g," ").trim();return s.length<=500?s:`${s.slice(0,497)}...`}function d(e){return`task/${e.replace(/[^a-zA-Z0-9_-]/g,"-").slice(0,40)}`}class m{static async createSessionTask(e){if(!e.prompt.trim())throw Error("Task prompt must not be blank");if(!a.isAbsolute(e.sourceProjectPath))throw Error("Task source project path must be absolute");let s=a.resolve(e.sourceProjectPath),t;try{return t=e.isolation==="worktree"?await o.enter({sessionId:e.sessionId,workspaceRoot:s,name:d(e.sessionId)}):void 0,{metadata:await i.createSessionMetadata(e.sessionId,t?.workspaceRoot??s,{title:e.title?.trim()||n(e.prompt),taskPromptSummary:c(e.prompt),taskDispatch:e.dispatch,taskModelId:e.dispatch?.modelId,selectedModelId:e.dispatch?.modelId,permissionMode:e.dispatch?.permissionMode,reasoningEffort:e.dispatch?.reasoningEffort,serviceTier:e.dispatch?.serviceTier,responseVerbosity:e.dispatch?.responseVerbosity,communicationStyle:e.dispatch?.communicationStyle,communicationStyleDigest:e.dispatch?.communicationStyleDigest,projectInstructionsDigest:e.dispatch?.projectInstructionsDigest,taskRetriedFrom:e.retriedFrom,taskIsolation:e.isolation,taskSourceProjectPath:s,taskWorktree:t}),taskWorktree:t}}catch(r){if(t)await o.exit({sessionId:e.sessionId,action:"remove",discardChanges:!0}).catch(()=>{return});throw r}}}
|
|
2
2
|
export{m as s};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{G as P}from"./chunk-
|
|
1
|
+
import{G as P}from"./chunk-hmvyreyx.js";import{gb as K}from"./chunk-ctkxf0y7.js";import{Eb as G,Fb as N,Gb as S,Hb as O,Ib as s,bc as B}from"./chunk-zek2ec3c.js";import{gc as j}from"./chunk-8rzwyknk.js";import{hd as q}from"./chunk-yz2bsntj.js";import{zd as v}from"./chunk-yp02wzek.js";import{Kf as z}from"./chunk-yvf4nmds.js";import R from"node:path";import{nanoid as cf}from"nanoid";import{execFile as I}from"node:child_process";import{createHash as p}from"node:crypto";import{lstat as o,readFile as ff,realpath as V}from"node:fs/promises";import A from"node:path";import{promisify as af}from"node:util";var tf=af(I),L=8388608,U=500,Y=200;async function y(n,a){try{return(await tf("git",["-c","core.pager=cat",...a],{cwd:n,encoding:"utf8",timeout:30000,maxBuffer:L+1024,env:{...process.env,GIT_CONFIG_NOSYSTEM:"1",GIT_PAGER:"cat",GIT_OPTIONAL_LOCKS:"0"}})).stdout}catch(f){let t=f instanceof Error&&f.message.includes("maxBuffer")?`Review target exceeds the ${L} byte limit`:f instanceof Error?f.message:String(f);throw Error(`Git review target failed: ${t}`)}}function Q(n,a){let f=n?.trim();if(!f||f.length>Y||f.includes("\x00")||f.includes(`
|
|
2
2
|
`)||f.includes("\r"))throw Error(`${a} must contain 1-${Y} characters`);return f}function W(n){return n.split("\x00").filter(Boolean)}async function _(n,a){return(await y(n,["rev-parse","--verify",`${a}^{commit}`])).trim()}async function nf(n,a,f,t,g){let w=g,c=await V(n);for(let e of a){let $=A.resolve(c,e),l=A.relative(c,$);if(!l||l.startsWith("..")||A.isAbsolute(l))throw Error(`Untracked review path escapes the workspace: ${e}`);let i=await o($);if(!i.isFile()||i.isSymbolicLink())throw Error(`Untracked review target must be a regular file: ${e}`);if(w+=i.size,w>L)throw Error(`Review target exceeds ${L} bytes`);f.update("\x00untracked\x00"),f.update(l.replaceAll(A.sep,"/")),f.update("\x00");let b=await ff($);f.update(b);let m=Math.max(1,b.toString("utf8").split(`
|
|
3
3
|
`).length);t.set(l.replaceAll(A.sep,"/"),[{start:1,end:m}])}}function M(n,a){let f=new Map,t,g,w,c,e=!1,$=(l,i)=>{let b=f.get(l)??[],m=b.at(-1);if(m&&i<=m.end+1)m.end=Math.max(m.end,i);else b.push({start:i,end:i});f.set(l,b)};for(let l of n.split(`
|
|
4
4
|
`)){if(l.startsWith("--- ")){let i=l.slice(4).split("\t")[0]?.trim();t=i&&i!=="/dev/null"?i.replace(/^a\//,"").replaceAll("\\","/"):void 0;continue}if(l.startsWith("+++ ")){let i=l.slice(4).split("\t")[0]?.trim();e=i==="/dev/null",g=e?t:i?i.replace(/^b\//,"").replaceAll("\\","/"):void 0,w=void 0,c=void 0;continue}if(l.startsWith("@@ ")){let i=/-(\d+)(?:,\d+)? \+(\d+)(?:,\d+)?/.exec(l);w=i?Math.max(1,Number(i[1])):void 0,c=i?Math.max(1,Number(i[2])):void 0;continue}if(!g||w===void 0||c===void 0)continue;if(l.startsWith("+")&&!l.startsWith("+++"))$(g,c),c++;else if(l.startsWith("-")&&!l.startsWith("---"))$(g,e?w:c),w++;else if(!l.startsWith("\\"))w++,c++}for(let l of a)if(!f.has(l))f.set(l,[{start:1,end:1}]);return f}function D(n){if(n.length>U)throw Error(`Review target exceeds the ${U} file limit`)}class d{static async resolve(n,a){let f=await V(n);await y(f,["rev-parse","--is-inside-work-tree"]);let t=await _(f,"HEAD"),g=p("sha256");g.update(`kind\x00${a.kind}\x00head\x00${t}\x00`);let w="",c=[],e,$,l,i,b=new Map;switch(a.kind){case"uncommitted":{w=await y(f,["diff","--binary","--no-ext-diff","--relative","HEAD","--","."]);let m=W(await y(f,["diff","--name-only","-z","--relative","HEAD","--","."])),h=W(await y(f,["ls-files","--others","--exclude-standard","-z","--","."]));if(c=[...new Set([...m,...h])].sort(),D(c),c.length===0)throw Error("No uncommitted changes to review");g.update(w),b=M(w,m),await nf(f,h,g,b,Buffer.byteLength(w)),l="uncommitted changes",i=["Review the uncommitted working tree against HEAD.","Use git status --short, git diff --cached, and git diff, then inspect","every relevant untracked file listed by git status."].join(" ");break}case"base":{let m=Q(a.ref,"Base ref");e=await _(f,m);let h=(await y(f,["merge-base",e,t])).trim();if(w=await y(f,["diff","--binary","--no-ext-diff","--relative",`${h}..${t}`,"--","."]),c=W(await y(f,["diff","--name-only","-z","--relative",`${h}..${t}`,"--","."])),D(c),c.length===0)throw Error(`No changes between ${m} and HEAD`);g.update(w),g.update(`\x00merge-base\x00${h}`),b=M(w,c),l=`changes against ${m}`,i=`Review changes introduced by ${h}..${t}.`;break}case"commit":{let m=Q(a.ref,"Commit ref");if($=await _(f,m),w=await y(f,["show","--format=","--binary","--no-ext-diff","--relative",$,"--","."]),c=W(await y(f,["diff-tree","--root","--no-commit-id","--name-only","-r","-z",$,"--","."])),D(c),c.length===0)throw Error(`Commit has no changes in this workspace: ${m}`);g.update(w),g.update(`\x00commit\x00${$}`),b=M(w,c),l=`commit ${m}`,i=`Review only the changes introduced by commit ${$}.`;break}}if(Buffer.byteLength(w)>L)throw Error(`Review diff exceeds ${L} bytes`);return{info:{kind:a.kind,label:l,headSha:t,...e?{baseSha:e}:{},...$?{commitSha:$}:{},digest:g.digest("hex"),fileCount:c.length},instruction:i,changedLines:b}}}var wf=131072,X=50,E=new Set;function Z(n,a){return`${R.resolve(n)}\x00${a}`}function J(n){return`/review ${n.kind}${n.kind==="uncommitted"?"":` ${n.ref?.trim()??""}`}`}function C(n,a,f,t=!1){if(typeof n!=="string")throw Error(`${a} must be a string`);let g=n.trim();if(!t&&!g||g.length>f)throw Error(`${a} exceeds its allowed length`);return g}function lf(n,a,f){if(!n||typeof n!=="object"||Array.isArray(n))throw Error("Review finding must be an object");let t=n,g=typeof t.line==="number"&&Number.isInteger(t.line)?t.line:void 0,w=t.code_location??(typeof t.file==="string"&&g!==void 0?{path:t.file,line_start:g,line_end:g}:void 0);if(!w||typeof w!=="object"||Array.isArray(w))throw Error("Review finding has no code_location");let c=w,e=C(c.path,"Finding path",1000),$=R.posix.normalize(e.replaceAll("\\","/"));if(R.posix.isAbsolute($)||$===".."||$.startsWith("../"))throw Error("Review finding path must be workspace-relative");let l=R.resolve(a,$),i=R.relative(R.resolve(a),l);if(i.startsWith("..")||R.isAbsolute(i))throw Error("Review finding path escapes the workspace");let b=typeof t.severity==="string"?t.severity.toLowerCase():"",m=b==="critical"?0:b==="high"?1:b==="medium"?2:b==="low"?3:void 0,h=t.priority??m;if(h!==0&&h!==1&&h!==2&&h!==3)throw Error("Review finding priority must be 0-3");let x=t.confidence_score??t.confidence??0.8;if(typeof x!=="number"||!Number.isFinite(x)||x<0||x>1)throw Error("Review finding confidence_score must be between 0 and 1");let{line_start:r,line_end:u}=c;if(!Number.isInteger(r)||!Number.isInteger(u)||r<1||u<r||u-r>=10)throw Error("Review finding line range is invalid");let F=f.changedLines.get($);if(!F)throw Error("Review finding path is outside the review target");if(!F.some((T)=>r<=T.end&&u>=T.start))throw Error("Review finding line range does not overlap the changed lines");let k=C(t.title??`[P${h}] ${String(t.type??"Review finding").replaceAll("-"," ").replace(/\b\w/g,(T)=>T.toUpperCase())}`,"Finding title",120);if(!k.startsWith(`[P${h}] `))throw Error("Review finding title priority does not match priority");return{title:k,body:C(t.body??t.description,"Finding body",4000),priority:h,confidenceScore:x,codeLocation:{path:$,lineStart:r,lineEnd:u}}}function mf(n,a,f){if(Buffer.byteLength(n)>wf)throw Error("Review output exceeds the 128 KiB limit");let t=n.indexOf("{"),g=n.lastIndexOf("}");if(t<0||g<=t)throw Error("Reviewer did not return a JSON object");let w;try{w=JSON.parse(n.slice(t,g+1))}catch{throw Error("Reviewer returned invalid JSON")}if(!w||typeof w!=="object"||Array.isArray(w))throw Error("Reviewer output must be an object");let c=w;if(!Array.isArray(c.findings))throw Error("Reviewer output must contain findings");if(c.findings.length>X)throw Error(`Reviewer returned more than ${X} findings`);return{overallExplanation:C(c.overall_explanation??c.summary,"Review explanation",1e4,!0),findings:c.findings.map((e)=>lf(e,a,f))}}async function H(n,a){return new j(z(n,a)).readAll()}class gf{static async start(n){let{sessionId:a,projectPath:f,runtime:t,request:g,onEvent:w}=n;if(t.sessionId!==a||R.resolve(t.workspaceRoot)!==R.resolve(f))throw Error("Review runtime does not own the requested Session");if(t.hasTurnOwner())throw Error("Cannot start a review during an active turn");await B.assertSessionWritable(a,f);let c=Z(f,a);if(E.has(c))throw Error("Session already has an active review");let e=await H(f,a);if(N(e))throw Error("Session has an interrupted review that must be recovered");let $=g.instructions?.trim();if($&&$.length>4000)throw Error("Review instructions exceed 4,000 characters");let l=await d.resolve(f,g),i=cf(16),b=q("review"),m=new Date().toISOString(),h={reviewId:i,reviewerSessionId:b,target:l.info,startedAt:m},x=new K(f);await x.saveReviewStart(a,h),await x.saveMessage(a,"user",J(g),null,{codeReview:{reviewId:i,phase:"started",targetKind:l.info.kind,targetDigest:l.info.digest}}),await B.updateSessionMetadata(a,f,{taskStatus:"running",taskStatusReason:`Reviewing ${l.info.label}`,taskPromptSummary:J(g),taskStartedAt:m,taskCompletedAt:null,taskFailure:null}),E.add(c);let r=this.execute({...n,target:l,reviewId:i,reviewerSessionId:b,instructions:$,store:x,onEvent:w}).finally(()=>{E.delete(c)});return{reviewId:i,completion:r}}static async execute(n){let{sessionId:a,projectPath:f,runtime:t,request:g,signal:w,onEvent:c,target:e,reviewId:$,reviewerSessionId:l,instructions:i,store:b}=n,m;try{let x=[e.instruction,"Bash already starts in the review workspace. Never prefix a command with cd.",`Authoritative target digest: ${e.info.digest}`,`Changed file count: ${e.info.fileCount}`,i?`Additional review instructions:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{wc as a,xc as b,yc as c}from"./chunk-
|
|
1
|
+
import{wc as a,xc as b,yc as c}from"./chunk-zgt1jpgg.js";import"./chunk-wt7gy9bm.js";import"./chunk-8mafna0v.js";import"./chunk-6pa6c2n0.js";import"./chunk-yz2bsntj.js";import"./chunk-2c3zavy2.js";import"./chunk-6207mbmr.js";import"./chunk-et9k9pac.js";import"./chunk-y2g5a5bp.js";import"./chunk-96h588rd.js";import"./chunk-3qhqbj09.js";import"./chunk-prgh321y.js";import"./chunk-jpwfq49n.js";import"./chunk-yqfqj7mh.js";import"./chunk-cyda7gnb.js";import"./chunk-1n60pgsq.js";import"./chunk-qkrssft1.js";import"./chunk-yvf4nmds.js";import"./chunk-6g5k5de1.js";export{a as validatePermissions,c as validateOutput,b as loadConfiguration};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{We as F}from"./chunk-
|
|
1
|
+
import{We as F}from"./chunk-et9k9pac.js";import{qf as D,rf as E}from"./chunk-jpwfq49n.js";import G from"node:path";function A(b){if(Array.isArray(b))return b.map((q)=>A(q));if(b!==null&&typeof b==="object"&&Object.getPrototypeOf(b)===Object.prototype)return Object.fromEntries(Object.entries(b).map(([q,w])=>[q,A(w)]));return b}function H(b){return A(b)}function I(b,q){let w=new D(q?.credentials??E().credentials);return w.configureModelProviders(b.modelProviders,b.models),w}async function Q(b,q){let w=G.resolve(b),x=F.getInstance(),[J,K]=await Promise.all([x.loadWorkspaceModelConfig(w,q),x.loadWorkspaceRuntimeSettings(w,q)]),z={...H(q),...J,...K},B=I(z);return x.validateConfig(z,B),{projectRoot:w,config:z,catalog:B}}function T(b){let q=H(b.config);return{projectRoot:G.resolve(b.projectRoot),config:q,catalog:I(q,b.catalog)}}
|
|
2
2
|
export{H as ud,Q as vd,T as wd};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Nd as a,Od as b,Pd as c,Qd as d,Rd as e}from"./chunk-
|
|
1
|
+
import{Nd as a,Od as b,Pd as c,Qd as d,Rd as e}from"./chunk-yp02wzek.js";import"./chunk-r1jxbx1h.js";import"./chunk-6sb7cg95.js";import"./chunk-2c3zavy2.js";import"./chunk-5ra89kse.js";import"./chunk-q3c07kb4.js";import"./chunk-6207mbmr.js";import"./chunk-et9k9pac.js";import"./chunk-y2g5a5bp.js";import"./chunk-96h588rd.js";import"./chunk-3qhqbj09.js";import"./chunk-prgh321y.js";import"./chunk-jpwfq49n.js";import"./chunk-yqfqj7mh.js";import"./chunk-cyda7gnb.js";import"./chunk-1n60pgsq.js";import"./chunk-qkrssft1.js";import"./chunk-yvf4nmds.js";import"./chunk-6g5k5de1.js";export{d as snapshotWorkspaceAgentResources,c as resolveWorkspaceAgentResources,e as resetWorkspaceAgentResources,a as refreshWorkspaceCommunicationStyles,b as configureInvocationPluginDirs};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Sd as L1,Td as Z0,Ud as G1}from"./chunk-r1jxbx1h.js";import{Yd as $O,Zd as HO}from"./chunk-6sb7cg95.js";import{ae as Y1}from"./chunk-2c3zavy2.js";import{be as B0,de as M0}from"./chunk-
|
|
1
|
+
import{Sd as L1,Td as Z0,Ud as G1}from"./chunk-r1jxbx1h.js";import{Yd as $O,Zd as HO}from"./chunk-6sb7cg95.js";import{ae as Y1}from"./chunk-2c3zavy2.js";import{be as B0,de as M0}from"./chunk-5ra89kse.js";import{ie as h,je as z}from"./chunk-6207mbmr.js";import{Me as V0,Ne as o1,We as j0}from"./chunk-et9k9pac.js";import{af as u,cf as W,ff as R1}from"./chunk-96h588rd.js";import{mf as b}from"./chunk-prgh321y.js";import{zf as d0}from"./chunk-cyda7gnb.js";import{Ef as T}from"./chunk-1n60pgsq.js";import J1 from"node:path";import L$ from"node:path";import C0 from"node:fs";import J0 from"node:os";import R from"node:path";import jO from"yaml";var g$={type:"object",properties:{verdict:{type:"string",enum:["pass","fail","partial"]},summary:{type:"string",minLength:1,maxLength:2000},findings:{type:"array",maxItems:50,items:{type:"string",minLength:1,maxLength:1000}}},required:["verdict","summary","findings"],additionalProperties:!1};function u$(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let $=O.verdict;return $==="pass"||$==="fail"||$==="partial"?$:void 0}var UO=`# Goal Completion Verifier
|
|
2
2
|
|
|
3
3
|
You are a fresh, independent, adversarial verifier. The parent Agent has claimed
|
|
4
4
|
that a persisted goal is complete. Your job is to refute that claim unless the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as E}from"./chunk-
|
|
1
|
+
import{r as E}from"./chunk-t8g4288j.js";import{s as YJ}from"./chunk-qwxqfb9z.js";import{$ as o,F as m,I as d,J as l,L as i,Z as r,_ as a,aa as n,v as A}from"./chunk-hmvyreyx.js";import{ka as WJ}from"./chunk-3gra6n0k.js";import"./chunk-qt114yth.js";import{Va as c,Ya as p,hb as v}from"./chunk-ctkxf0y7.js";import{sb as T}from"./chunk-095x2ykj.js";import{Hb as f,Qb as M,Rb as u,Tb as R,Wb as g,_b as N,bc as D}from"./chunk-zek2ec3c.js";import"./chunk-8rzwyknk.js";import"./chunk-k3nkcaap.js";import"./chunk-8mafna0v.js";import"./chunk-6pa6c2n0.js";import{hd as ZJ}from"./chunk-yz2bsntj.js";import"./chunk-xet98pc1.js";import"./chunk-kbpc97n3.js";import{sd as $J}from"./chunk-5chec8rs.js";import"./chunk-y5fk4fx5.js";import"./chunk-yp02wzek.js";import"./chunk-r1jxbx1h.js";import{Xd as zJ}from"./chunk-6sb7cg95.js";import"./chunk-2c3zavy2.js";import"./chunk-5ra89kse.js";import"./chunk-q3c07kb4.js";import{ie as b}from"./chunk-6207mbmr.js";import"./chunk-et9k9pac.js";import"./chunk-y2g5a5bp.js";import"./chunk-96h588rd.js";import{gf as I,hf as S,if as y}from"./chunk-3qhqbj09.js";import{mf as e}from"./chunk-prgh321y.js";import"./chunk-jpwfq49n.js";import{sf as JJ,vf as QJ}from"./chunk-yqfqj7mh.js";import"./chunk-cyda7gnb.js";import"./chunk-1n60pgsq.js";import"./chunk-qkrssft1.js";import"./chunk-yvf4nmds.js";import"./chunk-6g5k5de1.js";import{Readable as VJ,Writable as wJ}from"node:stream";import*as x from"@agentclientprotocol/sdk";import{PROTOCOL_VERSION as BJ}from"@agentclientprotocol/sdk";import s from"node:path";import{RequestError as GJ}from"@agentclientprotocol/sdk";import{nanoid as h}from"nanoid";var j=b("Agent");function C(J){if(!J)return{};return Object.fromEntries(J.map((Z)=>[Z.name,Z.value]))}function XJ(J){if("command"in J)return{type:"stdio",command:J.command,args:J.args,env:C(J.env)};if("url"in J)return{type:J.type,url:J.url,headers:C("headers"in J?J.headers:void 0)};return null}function jJ(J){let Z={};for(let Q of J){let Y=XJ(Q);if(Y)Z[Q.name]=Y}return Z}function t(J){if(typeof J==="string")return J?[{type:"text",text:J}]:[];return J.flatMap((Z)=>{if(Z.type==="text")return Z.text?[{type:"text",text:Z.text}]:[];let Q=Z.image_url.url,Y=/^data:([^;,]+);base64,(.+)$/s.exec(Q);if(!Y)return[{type:"text",text:"[Image]"}];return[{type:"image",mimeType:Y[1]??"image/png",data:Y[2]??""}]})}function DJ(J){let Z=u(J.metadata);return Z?[{type:"text",text:M(Z)}]:t(J.content)}function LJ(J){return[`Status: ${J.status}`,`Exit code: ${J.exitCode??"null"}`,`Duration: ${(J.durationMs/1000).toFixed(3)} seconds`].join(`
|
|
2
2
|
`)}class O{id;cwd;connection;clientCapabilities;options;agent=null;runtime=null;pendingPrompt=null;pendingUserShell=null;pendingResumeRequested=!1;availableCommandsTimer=null;taskStatusUnsubscribe;destroyed=!1;messages;contextMessages;mode;constructor(J,Z,Q,Y,H={}){this.id=J;this.cwd=Z;this.connection=Q;this.clientCapabilities=Y;this.options=H;this.messages=[...H.initialMessages??[]],this.contextMessages=[...this.messages],this.mode=this.mapPermissionModeToMode(H.permissionMode)}async refreshPersistedMessages(){let[J,Z]=await Promise.all([D.loadSession(this.id,this.cwd),D.loadSessionModelContext(this.id,this.cwd)]);if(J.length>0)this.messages=J;if(Z.length>0)this.contextMessages=Z}async loadModelContextOr(J){let Z=await D.loadSessionModelContext(this.id,this.cwd);return Z.length>0?Z:[...J]}mapPermissionModeToMode(J){switch(J){case"yolo":return"yolo";case"autoEdit":return"auto-edit";case"plan":return"plan";case"default":default:return"default"}}createAgent(){if(!this.runtime)throw Error("Session runtime is unavailable");return i.createWithRuntime(this.runtime,{sessionId:this.id,...this.options.taskWorktree?{toolBlacklist:["EnterWorktree","ExitWorktree"]}:{}})}async initialize(){if(j.debug(`[AcpSession ${this.id}] Initializing...`),await D.setSessionPermissionMode(this.id,this.cwd,this.mapModeToPermissionMode()??"default"),A.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),j.debug(`[AcpSession ${this.id}] ACP service context initialized`),await v.resolvePendingWithHandler(this.cwd,this.id,{requestConfirmation:(z)=>this.requestPermission(z)}))await this.refreshPersistedMessages();else if((this.options.initialMessages?.length??0)>0)this.contextMessages=await this.loadModelContextOr(this.options.initialMessages??[]);let Z=this.options.mcpServers?jJ(this.options.mcpServers):void 0,Q=A.getInstance().getTerminalService(this.id);if(this.runtime=await m.create({sessionId:this.id,workspaceRoot:this.cwd,permissionMode:this.mapModeToPermissionMode(),...Z?{mcpServers:Z}:{},...this.options.taskWorktree?{taskWorktree:this.options.taskWorktree}:{},...this.options.taskIsolation?{taskIsolation:this.options.taskIsolation}:{},userShellExecutor:{execute:async(z,$)=>{let F=await Q.execute(z,{cwd:$.cwd,env:$.env,timeout:$.timeoutMs,signal:$.signal,allowLocalFallback:!1,onOutput:(G)=>$.onOutput?.("stdout",G)});return{exitCode:F.exitCode,stdout:F.stdout,stderr:F.stderr,...F.error?{error:F.error}:{},timedOut:F.error==="Command timed out",aborted:F.error==="Command was aborted"}}},...(this.options.initialMessages?.length??0)>0?{sessionStart:{isResume:!0,resumeSessionId:this.id}}:{}}),await E.recoverInterrupted(this.cwd,this.id,this.runtime))await this.refreshPersistedMessages();this.agent=await this.createAgent(),await a(this.cwd),j.debug(`[AcpSession ${this.id}] Agent created successfully`),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=p.subscribe((z)=>{if(z.sessionId!==this.id||z.projectPath!==this.cwd)return;if(z.type==="task.delivery"){if(!z.properties.taskDelivery||typeof z.properties.taskDelivery!=="object")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof z.properties.updatedAt==="string"?z.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskDelivery":z.properties.taskDelivery,...z.properties.taskWorktreeRemoved===!0?{"blade/taskWorktreeRemoved":!0}:{}}});return}if(z.type!=="task.status")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof z.properties.updatedAt==="string"?z.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskStatus":z.properties.taskStatus,...typeof z.properties.taskStatusReason==="string"?{"blade/taskStatusReason":z.properties.taskStatusReason}:{},...z.properties.taskFailure&&typeof z.properties.taskFailure==="object"?{"blade/taskFailure":z.properties.taskFailure}:{},...typeof z.properties.taskStartedAt==="string"?{"blade/taskStartedAt":z.properties.taskStartedAt}:{},...typeof z.properties.taskCompletedAt==="string"?{"blade/taskCompletedAt":z.properties.taskCompletedAt}:{},...z.properties.taskDiffStat&&typeof z.properties.taskDiffStat==="object"?{"blade/taskDiffStat":z.properties.taskDiffStat}:{},...typeof z.properties.taskQueuePosition==="number"?{"blade/taskQueuePosition":z.properties.taskQueuePosition}:{},...typeof z.properties.taskQueueDepth==="number"?{"blade/taskQueueDepth":z.properties.taskQueueDepth}:{},...typeof z.properties.taskConcurrencyLimit==="number"?{"blade/taskConcurrencyLimit":z.properties.taskConcurrencyLimit}:{},...typeof z.properties.taskInFlight==="number"?{"blade/taskInFlight":z.properties.taskInFlight}:{}}})});let H=await this.runtime.getGoal();if(this.runtime.getPendingSteeringCount()>0||H?.status==="active")if(this.options.initialMessages===void 0)this.schedulePendingResume();else this.pendingResumeRequested=!0}async replayHistory(){for(let J of this.messages){if(!this.canSendUpdates())return;let Z=J.role==="user"?"user_message_chunk":J.role==="assistant"?"agent_message_chunk":void 0;if(!Z)continue;for(let Q of DJ(J)){if(!this.canSendUpdates())return;if(!await this.sendUpdateAndWait({sessionUpdate:Z,content:Q}))return}}if(this.pendingResumeRequested)this.schedulePendingResume()}sendAvailableCommandsDelayed(){if(this.destroyed||this.connection.signal.aborted)return;if(this.availableCommandsTimer!==null)clearTimeout(this.availableCommandsTimer);j.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),this.availableCommandsTimer=setTimeout(()=>{if(this.availableCommandsTimer=null,this.destroyed||this.connection.signal.aborted)return;this.sendAvailableCommands()},500)}async handleSlashCommand(J,Z){try{j.debug(`[AcpSession ${this.id}] Executing slash command: ${J}`);let Q={cwd:this.cwd,surface:"acp",workspaceRoot:this.cwd,sessionId:this.id,messages:[...this.contextMessages],rewind:{listCheckpoints:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listRewindCheckpoints()},execute:async($)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let F=await this.runtime.rewindSession($);return this.messages=[...F.messages],this.contextMessages=await this.loadModelContextOr(F.messages),await this.agent?.destroy(),this.agent=await this.createAgent(),F}},reasoning:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getReasoningConfiguration()},set:async($)=>{if(await this.setReasoningEffort($),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getReasoningConfiguration()}},serviceTier:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getServiceTierConfiguration()},set:async($)=>{if(await this.setServiceTier($),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getServiceTierConfiguration()}},responseVerbosity:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getResponseVerbosityConfiguration()},set:async($)=>{if(await this.setResponseVerbosity($),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getResponseVerbosityConfiguration()}},communicationStyle:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getCommunicationStyleConfiguration()},set:async($)=>{if(await this.setCommunicationStyle($),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getCommunicationStyleConfiguration()}},subagents:{list:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listSubagents()},resume:async($,F)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let G=!1,X,L=(W)=>{this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:W.id,status:W.status==="completed"?"completed":"failed",content:[{type:"content",content:{type:"text",text:W.result?.message||W.result?.error||`Subagent ${W.status}`}}]})},B=this.runtime.resumeSubagent({agentId:$,prompt:F,onCompleted:(W)=>{if(G)L(W);else X=W}});if(this.sendUpdate({sessionUpdate:"tool_call",toolCallId:B.session.id,status:"in_progress",title:`Resuming ${B.session.subagentType} subagent`,content:[{type:"content",content:{type:"text",text:`Resumed from ${B.source.id} at depth ${B.session.resumeDepth}`}}],kind:this.mapToolKind("readonly")}),G=!0,X)L(X);return B}},mcp:{getCatalog:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpContentCatalog()},refresh:async($)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.refreshMcpContentCatalogs($)},getPrompt:async($,F,G)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpPrompt($,F,G)},complete:async($,F,G)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.completeMcpArgument($,F,G)},listTasks:async($)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listMcpTasks($)},getTask:async($)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpTask($)},cancelTask:async($,F)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.cancelMcpTask($,F)},getLogs:async($,F)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpLogs($,F)},setLoggingLevel:async($,F)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.setMcpLoggingLevel($,F)},getInstructions:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpInstructions()}},codeReview:{run:async($,F)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let G=await E.start({sessionId:this.id,projectPath:this.cwd,runtime:this.runtime,request:$,signal:F,onEvent:(B)=>{if(B.kind==="tool_start")this.sendUpdate({sessionUpdate:"tool_call",toolCallId:B.toolCall.id,status:"in_progress",title:`Review: ${B.toolCall.function.name}`,content:[],kind:this.mapToolKind(B.toolKind)});else if(B.kind==="tool_result")this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:B.toolCall.id,status:B.result.success?"completed":"failed",content:[]})}}),X=await G.completion,L=(await E.list(this.cwd,this.id)).find((B)=>B.start.reviewId===G.reviewId);if(!L)throw Error(`Review not found: ${G.reviewId}`);return await this.refreshPersistedMessages(),{reviewId:G.reviewId,status:X.status,findings:X.findings.length,content:f(L.start,X)}}},signal:Z,acp:{sendMessage:($)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:$}})},sendToolStart:($,F,G)=>{let X=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,L=this.mapToolKind(G);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:X,status:"in_progress",title:`${$}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(F,null,2)}}],kind:L})},sendToolResult:($,F)=>{if(F.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:F.summary}})}}},Y=await o(J,Q),H=Y.data?.action;if(H==="start_goal"||H==="resume_goal")this.schedulePendingResume();if(H==="rewind_session"&&Array.isArray(Y.data?.messages))this.messages=[...Y.data.messages],this.contextMessages=await this.loadModelContextOr(Y.data.messages);if((Y.message==="compact_completed"||Y.message==="compact_fallback")&&Y.data?.compactedMessages){this.contextMessages=[...Y.data.compactedMessages];let $=await D.loadSession(this.id,this.cwd);if($.length>0)this.messages=$}let z=Y.content||Y.message;if(z)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:z}});if(Y.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] ${Y.error}`}});return{stopReason:Y.success?"end_turn":"cancelled"}}catch(Q){return j.error(`[AcpSession ${this.id}] Slash command error:`,Q),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] 命令执行失败: ${Q instanceof Error?Q.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let J=n(this.cwd),Z=["model","permissions","theme","config","exit","ide"],Y=J.filter((H)=>!Z.includes(H.name)).map((H)=>{let z;if(H.usage){let $=H.usage.replace(/^\/\w+\s*/,"").trim();if($)z=$}if(H.aliases?.length){let $=`Aliases: ${H.aliases.join(", ")}`;z=z?`${z} | ${$}`:$}return{name:H.name,description:H.description,input:z?{hint:z}:void 0}});j.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Y.map((H)=>H.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Y}),j.info(`[AcpSession ${this.id}] Sent ${Y.length} available commands`)}catch(J){j.error(`[AcpSession ${this.id}] Failed to send available commands:`,J)}}async prompt(J,Z={}){if(A.setCurrentSession(this.id),!this.agent||!this.runtime)throw Error("Session not initialized");let Q=this.resolvePrompt(J.prompt),Y=Q.content,H=Q.displayText,z=J._meta?.outputSchema??(Z.pendingInputOnly?this.runtime.getPendingSteeringMessages().find((G)=>G.outputSchema)?.outputSchema:void 0),$;if(z!==void 0)$=g(z).schema;if(H.trimStart().startsWith("!")){if($)throw Error("Output schemas cannot be combined with user shell commands");return this.handleUserShellCommand(H)}if(this.pendingPrompt){if($)throw Error("Wait for the active turn to finish before setting an output schema");if(/^\/goal(?:\s|$)/i.test(H.trim()))return this.handleSlashCommand(H,this.pendingPrompt.signal);let G=await this.runtime.enqueueSteering(Y,{allowBeforeTurn:!0});if(!G.accepted)throw Error(G.reason==="queue_full"?"Active turn steering queue is full":"Active turn is no longer steerable");if(j.debug(`[AcpSession ${this.id}] Queued steering for active turn (${G.queued})`),G.delivery==="next_turn")this.schedulePendingResume();return{stopReason:"end_turn"}}let F=new AbortController;this.pendingPrompt=F;try{if(j.debug(`[AcpSession ${this.id}] Received prompt: ${H.slice(0,100)}...`),r(H)){if($)throw Error("Output schemas cannot be combined with slash commands");return await this.handleSlashCommand(H,F.signal)}let G={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.contextMessages],signal:F.signal,permissionMode:this.mapModeToPermissionMode(),onPermissionModeChange:async(W)=>{this.mode=this.mapPermissionModeToMode(W),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})},...this.options.taskWorktree?{worktreeActive:!0}:{},confirmationHandler:{requestConfirmation:async(W)=>{return this.requestPermission(W)}}},X=await c(this.agent.chatStream(Y,G,{pendingInputOnly:Z.pendingInputOnly,goalContinuationOnly:Z.goalContinuationOnly,outputSchema:$}),async(W)=>{switch(W.kind){case"content_delta":if($)break;this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:W.delta}});break;case"thinking_delta":this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:W.delta}});break;case"tool_start":{let w=W.toolCall,_=w.function.name;if(_===R)break;let q=this.mapToolKind(W.toolKind),V=`Executing ${_}`;if(_==="Task"&&"function"in w)try{let P=JSON.parse(w.function.arguments),K=P.resume_from??P.resume;if(typeof K==="string")V=`Resuming ${String(P.subagent_type||"subagent")} from ${K}`}catch{}this.sendUpdate({sessionUpdate:"tool_call",toolCallId:w.id,status:"in_progress",title:V,content:[],kind:q});break}case"tool_progress":{let w=W.toolCall;if(w.function.name===R)break;this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:w.id,status:"in_progress",content:[{type:"content",content:{type:"text",text:W.update.message}}]});break}case"tool_result":{let w=W.toolCall;if(w.function.name===R)break;let _=W.result,q=[],V=_.metadata;if(V?.kind==="patch"&&Array.isArray(V.changes))for(let K of V.changes){if(!K||typeof K!=="object"||!("path"in K)||typeof K.path!=="string")continue;q.push({type:"diff",path:K.path,oldText:"oldContent"in K&&typeof K.oldContent==="string"?K.oldContent:null,newText:"newContent"in K&&typeof K.newContent==="string"?K.newContent:null})}else if(V?.kind==="edit"&&typeof V.file_path==="string"&&typeof V.oldContent==="string"&&(typeof V.newContent==="string"||V.newContent===void 0))q.push({type:"diff",path:V.file_path,oldText:V.oldContent,newText:V.newContent??null});else{let K=w.function.name,HJ=l(d(K,_));q.push({type:"content",content:{type:"text",text:HJ}})}if(w.function.name==="Task"&&(V?.verificationVerdict==="pass"||V?.verificationVerdict==="fail"||V?.verificationVerdict==="partial"))q.unshift({type:"content",content:{type:"text",text:`Verification result: ${V.verificationVerdict.toUpperCase()}`}});let P=_.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:w.id,status:P,content:q});break}case"structured_output":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:JSON.stringify(W.output)}});break;case"mcp_catalog_changed":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP catalog r${W.revision} (${W.serverName}): +${W.added.length} -${W.removed.length} ~${W.updated.length}
|
|
3
3
|
`}});break;case"mcp_content_changed":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP ${W.contentKind} r${W.revision} (${W.serverName}): +${W.added.length} -${W.removed.length} ~${W.updated.length}
|
|
4
4
|
`}});break;case"mcp_resource_updated":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP resource updated r${W.revision} (${W.serverName}): ${W.uri}
|