blade-code 0.7.2 → 0.7.4
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-1vngdr7p.js +1 -0
- package/dist/{chunk-275gt6q1.js → chunk-373pmz70.js} +1 -1
- package/dist/{chunk-1w719wd9.js → chunk-38h3yh6z.js} +1 -1
- package/dist/{chunk-zcreym5g.js → chunk-3mhbped9.js} +33 -33
- package/dist/{chunk-k18bq4mn.js → chunk-4e2fzyf2.js} +2 -2
- package/dist/{chunk-p9pthxkm.js → chunk-501my8nh.js} +1 -1
- package/dist/{chunk-wc2xb6ge.js → chunk-5smacbk0.js} +2 -2
- package/dist/{chunk-cadngkwr.js → chunk-63dzf6hr.js} +1 -1
- package/dist/{chunk-t6y57501.js → chunk-6rszb7xd.js} +363 -362
- package/dist/{chunk-t3pyakvc.js → chunk-7mnefph6.js} +2 -2
- package/dist/{chunk-m4a480k7.js → chunk-98jpdmgc.js} +2 -2
- package/dist/chunk-aevyre2t.js +1 -0
- package/dist/{chunk-qw2wy4jc.js → chunk-b1d49byc.js} +1 -1
- package/dist/chunk-b4hmtjec.js +1 -0
- package/dist/{chunk-xa8szzc6.js → chunk-bmcc85nj.js} +1 -1
- package/dist/{chunk-67zx7ymj.js → chunk-by93yn92.js} +1 -1
- package/dist/{chunk-8xdqtspw.js → chunk-byxazdwv.js} +1 -1
- package/dist/chunk-cqrg2pp7.js +1 -0
- package/dist/{chunk-ztpseq3n.js → chunk-ctbhcw8h.js} +1 -1
- package/dist/{chunk-m2k4h3bs.js → chunk-cw125vv3.js} +1 -1
- package/dist/{chunk-wcm0nc84.js → chunk-cyxb6fxe.js} +1 -1
- package/dist/chunk-dftaxwg9.js +1 -0
- package/dist/{chunk-z0qxaky4.js → chunk-e21htmg4.js} +1 -1
- package/dist/{chunk-g0h3rans.js → chunk-egavbybx.js} +2 -2
- package/dist/{chunk-rmtcqc8q.js → chunk-erpgkabk.js} +1 -1
- package/dist/{chunk-9zwf87ne.js → chunk-gjf2d2yg.js} +1 -1
- package/dist/chunk-gzc9n5d6.js +2 -0
- package/dist/{chunk-p6d7k1x6.js → chunk-jf48kahn.js} +3 -3
- package/dist/{chunk-1mge0pzv.js → chunk-jpry8h07.js} +1 -1
- package/dist/{chunk-cqrkeq20.js → chunk-k4behavv.js} +1 -1
- package/dist/{chunk-cfrbsnfb.js → chunk-kfg3vx5z.js} +1 -1
- package/dist/chunk-n5rg9dbv.js +151 -0
- package/dist/chunk-pa364yr9.js +1 -0
- package/dist/{chunk-rr62k3ar.js → chunk-pvxp2gzr.js} +1 -1
- package/dist/{chunk-f9b8h03c.js → chunk-qxvp127d.js} +1 -1
- package/dist/{chunk-b6mxeey0.js → chunk-rkhhzc4r.js} +2 -2
- package/dist/{chunk-22gxb9qs.js → chunk-rtn0rb16.js} +2 -2
- package/dist/chunk-w1zb8zac.js +3 -0
- package/dist/chunk-z7x21493.js +7 -0
- package/dist/web/assets/{FilePreview-DXDzoFFc.js → FilePreview-evNzCuVx.js} +1 -1
- package/dist/web/assets/{MarkdownRenderer-BVPOLK1b.js → MarkdownRenderer-BQoiQTDd.js} +1 -1
- package/dist/web/assets/{McpModal-DeTf34Fw.js → McpModal-BT9OivhK.js} +1 -1
- package/dist/web/assets/{SettingsModal-CDLkPyL-.js → SettingsModal-CDRcorCS.js} +1 -1
- package/dist/web/assets/{SettingsStore-DYKvNeV_.js → SettingsStore-CfDjhOkS.js} +1 -1
- package/dist/web/assets/{SkillsModal-D784AUrt.js → SkillsModal-DCPaqoOe.js} +1 -1
- package/dist/web/assets/{TerminalPanel-BosJuIct.js → TerminalPanel-Cs16_6ew.js} +1 -1
- package/dist/web/assets/{dialog-CgyS_4Eo.js → dialog-C8VDk-ma.js} +1 -1
- package/dist/web/assets/index-9t-WxRrl.js +10 -0
- package/dist/web/assets/index-Bu13aXyE.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/chunk-108p1xw7.js +0 -1
- package/dist/chunk-42q476bq.js +0 -1
- package/dist/chunk-4hk7wfat.js +0 -3
- package/dist/chunk-7d1pn8a1.js +0 -2
- package/dist/chunk-abpvdaq2.js +0 -6
- package/dist/chunk-hv0bzn31.js +0 -1
- package/dist/chunk-j3k2c6tm.js +0 -1
- package/dist/chunk-je6r01h4.js +0 -1
- package/dist/chunk-nh37erd3.js +0 -1
- package/dist/chunk-z72cp8f5.js +0 -150
- package/dist/web/assets/index-Abieffcr.js +0 -10
- package/dist/web/assets/index-CQ3JnuUf.css +0 -1
package/dist/web/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>BladeCode</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-9t-WxRrl.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Bu13aXyE.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/package.json
CHANGED
package/dist/chunk-108p1xw7.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Ga as a,Ha as b,Ia as c,Ja as d,Ka as e,La as f}from"./chunk-k18bq4mn.js";import"./chunk-cfrbsnfb.js";export{b as getVersion,c as getPackageName,a as getPackageInfo,e as getFormattedVersion,d as getDescription,f as getCopyright};
|
package/dist/chunk-42q476bq.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Aa as l,Ba as m,pa as a,qa as b,ra as c,sa as d,ta as e,ua as f,va as g,wa as h,xa as i,ya as j,za as k}from"./chunk-wc2xb6ge.js";import"./chunk-b6mxeey0.js";import"./chunk-cadngkwr.js";import"./chunk-4hk7wfat.js";import"./chunk-cfrbsnfb.js";export{a as vanillaStore,c as sessionActions,l as getThinkingModeEnabled,b as getState,j as getModelById,e as getMessages,k as getMcpServers,i as getCurrentModel,f as getConfig,h as getAllModels,g as ensureStoreInitialized,m as configActions,d as appActions};
|
package/dist/chunk-4hk7wfat.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{Pb as w}from"./chunk-cfrbsnfb.js";import{appendFileSync as B,existsSync as N,mkdirSync as R,readdirSync as x,statSync as k,unlinkSync as j}from"node:fs";import Y from"node:path";import{execSync as z}from"node:child_process";import*as O from"node:os";import*as Q from"node:path";function F(q){return Q.resolve(q).replace(/[/\\]/g,"-").replace(/:/g,"_")}function S(q){let G=q.replace(/_/g,":");if(G.startsWith("-"))G="/"+G.slice(1);return G.replace(/-/g,"/")}function A(q){let G=F(q);return Q.join(W(),"projects",G)}function D(q,G){return Q.join(A(q),`${G}.jsonl`)}function P(q){try{return z("git rev-parse --abbrev-ref HEAD",{cwd:q,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function W(){return process.env.BLADE_STORAGE_ROOT||Q.join(O.homedir(),".blade")}async function v(){let{readdir:q}=await import("node:fs/promises");try{let G=Q.join(W(),"projects");return(await q(G,{withFileTypes:!0})).filter((H)=>H.isDirectory()).map((H)=>H.name)}catch{return[]}}var Z;((J)=>{J[J.DEBUG=0]="DEBUG";J[J.INFO=1]="INFO";J[J.WARN=2]="WARN";J[J.ERROR=3]="ERROR"})(Z||={});var X=null,U=null,_=!1;function y(q){if(X!==q)X=q}async function c(){}function V(){if(_)return U;_=!0;try{let q=Y.join(W(),"logs");if(!N(q))R(q,{recursive:!0,mode:493});if(k(q).uid===0&&process.getuid&&process.getuid()!==0)return console.error(""),console.error("[FAIL] 权限错误:~/.blade/logs 目录属于 root 用户"),console.error(""),console.error("这通常是因为您曾经使用 sudo 运行过 blade。"),console.error(""),console.error("解决方法:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("然后重新运行 blade(不要使用 sudo)"),console.error(""),null;return m(q,30),U=q,q}catch(q){return console.error("[Logger] 无法创建日志目录:",q),null}}function m(q,G){try{let K=x(q),H=Date.now(),J=G*24*60*60*1000;for(let T of K){if(!T.startsWith("blade-")||!T.endsWith(".log")&&!T.endsWith(".jsonl"))continue;let $=Y.join(q,T);try{let E=k($);if(H-E.mtimeMs>J)j($)}catch(E){}}}catch(K){}}function I(){let q=V();if(!q)return null;let G=X||"default";return Y.join(q,`blade-${G}.jsonl`)}function C(q,G,K){let H=I();if(!H)return;try{let J={timestamp:new Date().toISOString(),level:Z[G],category:q,message:K};B(H,JSON.stringify(J)+`
|
|
2
|
-
`)}catch(J){}}class M{static globalDebugConfig=null;enabled;minLevel;category;constructor(q={}){if(q.enabled!==void 0)this.enabled=q.enabled;else if(M.globalDebugConfig!==null)this.enabled=Boolean(M.globalDebugConfig);else this.enabled=!1;this.minLevel=q.minLevel??0,this.category=q.category??"General"}static setGlobalDebug(q){M.globalDebugConfig=q}static clearGlobalDebug(){M.globalDebugConfig=null}setEnabled(q){this.enabled=q}parseDebugFilter(q){if(!q)return{enabled:!1};if(q===!0||q==="true"||q==="1")return{enabled:!0};let G=String(q).trim();if(!G)return{enabled:!0};if(G.startsWith("!"))return{enabled:!0,filter:{mode:"exclude",categories:G.split(",").map((J)=>J.trim().replace(/^!/,"")).filter(Boolean)}};return{enabled:!0,filter:{mode:"include",categories:G.split(",").map((H)=>H.trim()).filter(Boolean)}}}shouldLogCategory(q){if(!q)return!0;let G=this.category.toLowerCase();if(q.mode==="include")return q.categories.some((K)=>G.includes(K.toLowerCase()));return!q.categories.some((K)=>G.includes(K.toLowerCase()))}shouldLogToConsole(q){if(M.globalDebugConfig!==null){let{enabled:G,filter:K}=this.parseDebugFilter(M.globalDebugConfig);if(!G)return!1;if(q<this.minLevel)return!1;return this.shouldLogCategory(K)}return this.enabled&&q>=this.minLevel}log(q,...G){let K=G.map((H)=>typeof H==="object"?JSON.stringify(H):String(H)).join(" ");if(C(this.category,q,K),this.shouldLogToConsole(q)){let H=Z[q],J=`[${this.category}] [${H}]`;console.error(J,...G)}}debug(...q){this.log(0,...q)}info(...q){this.log(1,...q)}warn(...q){this.log(2,...q)}error(...q){this.log(3,...q)}}function d(q,G){return new M({...G,category:q})}var L=new M({category:"General"});
|
|
3
|
-
export{S as Eb,A as Fb,D as Gb,P as Hb,W as Ib,v as Jb,y as Kb,c as Lb,M as Mb,d as Nb,L as Ob};
|
package/dist/chunk-7d1pn8a1.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as Df,k as Lf}from"./chunk-rr62k3ar.js";import{A as If,C as $f,D as Mf,H as mf,I as Rf,J as Yf,K as Hf,L,N as zf,O as Af,Q as yf,T as p,_ as uf}from"./chunk-t6y57501.js";import{ba as _}from"./chunk-t3pyakvc.js";import{Ba as T,ua as u,wa as Ef,xa as qf}from"./chunk-wc2xb6ge.js";import{Ha as v}from"./chunk-k18bq4mn.js";import{Na as kf,Pa as s,Ya as Wf}from"./chunk-zcreym5g.js";import{wb as U}from"./chunk-cadngkwr.js";import{Nb as F}from"./chunk-4hk7wfat.js";import{Pb as jf}from"./chunk-cfrbsnfb.js";var g0={port:{type:"number",describe:"Port to listen on (0 for auto)",default:0},hostname:{type:"string",describe:"Hostname to listen on",default:"127.0.0.1"},cors:{type:"array",describe:"Additional domains to allow for CORS",default:[]}};function o0(V){return{port:V.port??0,hostname:V.hostname??"127.0.0.1",cors:V.cors??[]}}import{Hono as w0}from"hono";import{cors as b0}from"hono/cors";import{existsSync as tf,readFileSync as Vf}from"node:fs";import{createServer as D0}from"node:http";import{networkInterfaces as L0}from"node:os";import{dirname as P0,extname as k0,join as k}from"node:path";import{fileURLToPath as S0}from"node:url";import{WebSocketServer as h0}from"ws";import{z as n}from"zod";class r extends Error{code;statusCode;constructor(V,$,f=500){super($);this.code=V;this.statusCode=f;this.name="BladeServerError"}toObject(){return{error:{code:this.code,message:this.message}}}}class h extends r{constructor(V,$){super("NOT_FOUND",$?`${V} not found: ${$}`:`${V} not found`,404)}}class H extends r{constructor(V){super("BAD_REQUEST",V,400)}}var r0=n.object({error:n.object({code:n.string(),message:n.string()})});import{Hono as sf}from"hono";import{z as I}from"zod";var Qf=F("Service"),ef=I.object({updates:I.record(I.any()),options:I.object({scope:I.enum(["local","project","global"]).optional(),immediate:I.boolean().optional()}).optional()}),Xf=()=>{let V=new sf;return V.get("/",async($)=>{try{let f=u();return $.json(f||{})}catch(f){return Qf.error("[ConfigRoutes] Failed to get config:",f),$.json({})}}),V.put("/",async($)=>{try{let f=await $.req.json(),O=ef.safeParse(f);if(!O.success)throw new H("Invalid config update format");let{updates:J,options:Y}=O.data;return await T().updateConfig(J,Y),$.json({success:!0,updates:J})}catch(f){throw Qf.error("[ConfigRoutes] Failed to update config:",f),f}}),V.get("/permissions",async($)=>{try{let f=u();return $.json(f?.permissions||{})}catch(f){return Qf.error("[ConfigRoutes] Failed to get permissions:",f),$.json({})}}),V};import{Hono as f0}from"hono";var Ff=()=>{let V=new f0;return V.get("/health",($)=>{return $.json({healthy:!0,version:v()})}),V.get("/info",($)=>{return $.json({version:v(),platform:process.platform,arch:process.arch,nodeVersion:process.version,cwd:U()})}),V};import{Hono as $0}from"hono";var c=F("Service"),Uf=()=>{let V=new $0;return V.get("/",async($)=>{try{let O=_.getInstance().getAllServers(),J=Array.from(O.entries()).map(([Y,Q])=>({id:Y,name:Y,status:Q.status==="connected"?"connected":Q.status==="connecting"?"connecting":Q.lastError?"error":"offline",endpoint:Q.config.command?`${Q.config.command} ${(Q.config.args||[]).join(" ")}`.trim():Q.config.url||"Unknown",description:`MCP server: ${Y}`,tools:Q.tools.map((K)=>K.name),connectedAt:Q.connectedAt?.toISOString(),error:Q.lastError?.message}));return $.json(J)}catch(f){return c.error("[McpRoutes] Failed to get MCP servers:",f),$.json([])}}),V.post("/:name/connect",async($)=>{try{let f=$.req.param("name");return await _.getInstance().connectServer(f),$.json({success:!0})}catch(f){return c.error("[McpRoutes] Failed to connect MCP server:",f),$.json({success:!1,error:f.message},500)}}),V.post("/:name/disconnect",async($)=>{try{let f=$.req.param("name");return await _.getInstance().disconnectServer(f),$.json({success:!0})}catch(f){return c.error("[McpRoutes] Failed to disconnect MCP server:",f),$.json({success:!1,error:f.message},500)}}),V.delete("/:name",async($)=>{try{let f=$.req.param("name");await _.getInstance().unregisterServer(f);let J=u();if(J?.mcpServers){let{[f]:Y,...Q}=J.mcpServers;await T().updateConfig({mcpServers:Q})}return $.json({success:!0})}catch(f){return c.error("[McpRoutes] Failed to delete MCP server:",f),$.json({success:!1,error:f.message},500)}}),V.post("/",async($)=>{try{let f=await $.req.json(),{name:O,config:J}=f;if(!O||!J)return $.json({success:!1,error:"Missing name or config"},400);await _.getInstance().registerServer(O,J);let Q=u();return await T().updateConfig({mcpServers:{...Q?.mcpServers,[O]:J}}),$.json({success:!0})}catch(f){return c.error("[McpRoutes] Failed to add MCP server:",f),$.json({success:!1,error:f.message},500)}}),V};import{Hono as V0}from"hono";var i=F("Service"),Bf=()=>{let V=new V0;return V.get("/",async($)=>{try{let f=Ef(),O=qf();return $.json({configured:f,current:O})}catch(f){return i.error("[ModelsRoutes] Failed to get models:",f),$.json({configured:[],current:null})}}),V.post("/",async($)=>{try{let f=await $.req.json(),{provider:O,name:J,model:Y,baseUrl:Q,apiKey:K}=f;if(!Y)throw new H("model is required");let G=await T().addModel({provider:O||"openai-compatible",name:J||Y,model:Y,baseUrl:Q||void 0,apiKey:K||void 0});return $.json({success:!0,model:G})}catch(f){throw i.error("[ModelsRoutes] Failed to add model:",f),f}}),V.put("/:modelId",async($)=>{try{let f=$.req.param("modelId"),O=await $.req.json(),{baseUrl:J,apiKey:Y,model:Q}=O;return await T().updateModel(f,{baseUrl:J||void 0,apiKey:Y||void 0,model:Q||void 0}),$.json({success:!0})}catch(f){throw i.error("[ModelsRoutes] Failed to update model:",f),f}}),V.delete("/:modelId",async($)=>{try{let f=$.req.param("modelId");return await T().removeModel(f),$.json({success:!0})}catch(f){throw i.error("[ModelsRoutes] Failed to delete model:",f),f}}),V};import{Hono as x0}from"hono";import{z}from"zod";import{Hono as O0}from"hono";import{streamSSE as J0}from"hono/streaming";import{LRUCache as Q0}from"lru-cache";import{nanoid as g}from"nanoid";import{z as B}from"zod";var q=F("Service"),Y0=B.object({title:B.string().optional(),projectPath:B.string().optional()}),Z0=B.object({content:B.string(),attachments:B.array(B.object({type:B.enum(["file","image","url"]),path:B.string().optional(),url:B.string().optional(),content:B.string().optional(),mimeType:B.string().optional(),name:B.string().optional()})).optional(),permissionMode:B.enum(["default","autoEdit","plan","yolo"]).optional()}),K0=B.object({title:B.string().optional()}),m=new Map,w=new Q0({max:100,ttl:1800000,dispose:(V,$)=>{if(V.status==="running"||V.status==="waiting_permission")V.abortController.abort(),q.debug(`[SessionRoutes] Run ${$} disposed due to cache eviction`)}}),M0=(V)=>{if(!V||typeof V!=="object")return V;let $={...V},f=200000;if(typeof $.oldContent==="string"&&$.oldContent.length>f)delete $.oldContent;if(typeof $.newContent==="string"&&$.newContent.length>f)delete $.newContent;return $};function Tf(V){if(typeof V==="string")return V;return V.filter(($)=>$.type==="text").map(($)=>$.text).join(`
|
|
2
|
-
`)}function j0(V,$){let f=($??[]).filter((J)=>J.type==="image"&&typeof J.content==="string").map((J)=>({type:"image_url",image_url:{url:J.content}}));if(f.length===0)return V;let O=[];if(V.trim())O.push({type:"text",text:V});return O.push(...f),O}var Cf=()=>{let V=new O0,$=new Map;return V.get("/",async(f)=>{try{let O=await p.listSessions(),J=new Set(O.filter((j)=>j.relationType==="subagent").map((j)=>j.sessionId)),Y=Array.from(m.values()).filter((j)=>!J.has(j.id)&&j.relationType!=="subagent").map((j)=>({sessionId:j.id,projectPath:j.projectPath,title:j.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:j.messages.length,firstMessageTime:j.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0})),Q=new Set(Y.map((j)=>j.sessionId)),K=O.filter((j)=>!m.has(j.sessionId)&&!Q.has(j.sessionId)&&j.relationType!=="subagent"),G=new Set(Q),Z=K.filter((j)=>{if(G.has(j.sessionId))return!1;return G.add(j.sessionId),!0}),M=[...Y,...Z];return f.json(M)}catch(O){return q.error("[SessionRoutes] Failed to list sessions:",O),f.json([])}}),V.post("/",async(f)=>{try{let O=await f.req.json(),J=Y0.safeParse(O);if(!J.success)throw new H("Invalid request body");let{title:Y,projectPath:Q}=J.data,K=g(12),G=Q||f.get("directory")||U(),Z={id:K,projectPath:G,title:Y||`Session ${K.slice(0,6)}`,createdAt:new Date,messages:[]};return m.set(K,Z),f.json({sessionId:K,projectPath:G,title:Z.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:0,firstMessageTime:Z.createdAt.toISOString(),lastMessageTime:Z.createdAt.toISOString(),hasErrors:!1})}catch(O){throw q.error("[SessionRoutes] Failed to create session:",O),O}}),V.get("/:sessionId",async(f)=>{let O=f.req.param("sessionId"),J=m.get(O);if(J)return f.json({sessionId:J.id,projectPath:J.projectPath,title:J.title,messageCount:J.messages.length,firstMessageTime:J.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0});try{let Q=(await p.listSessions()).find((K)=>K.sessionId===O);if(!Q)throw new h("Session",O);return f.json(Q)}catch(Y){if(Y instanceof h)throw Y;throw q.error("[SessionRoutes] Failed to get session:",Y),Y}}),V.patch("/:sessionId",async(f)=>{let O=f.req.param("sessionId");try{let J=await f.req.json(),Y=K0.safeParse(J);if(!Y.success)throw new H("Invalid request body");let{title:Q}=Y.data,K=m.get(O);if(K&&Q)K.title=Q;return f.json({success:!0,title:Q})}catch(J){throw q.error("[SessionRoutes] Failed to update session:",J),J}}),V.delete("/:sessionId",async(f)=>{let O=f.req.param("sessionId"),J=m.get(O);if(J?.currentRunId){let Q=w.get(J.currentRunId);if(Q)Q.abortController.abort(),L.publish(O,"run.cancelled",{runId:Q.id}),w.delete(J.currentRunId)}try{await p.deleteSession(O)}catch(Q){q.warn("[SessionRoutes] Failed to delete session file:",Q)}m.delete(O);let Y=$.get(O);if(Y){if(await Y.dispose(),$.delete(O),$.size===0)await _.getInstance().disconnectAll()}return f.json({success:!0})}),V.get("/:sessionId/message",async(f)=>{let O=f.req.param("sessionId");try{let J=await p.loadSession(O);return f.json(J)}catch(J){return q.error("[SessionRoutes] Failed to get messages:",J),f.json([])}}),V.get("/:sessionId/events",async(f)=>{let O=f.req.param("sessionId"),J=m.get(O);if(!J){let Y=f.get("directory")||U();J={id:O,projectPath:Y,title:`Session ${O.slice(0,6)}`,createdAt:new Date,messages:[]},m.set(O,J)}return J0(f,async(Y)=>{await Y.writeSSE({data:JSON.stringify({type:"connected",properties:{sessionId:O,timestamp:Date.now()}})});let K=L.subscribe((Z)=>{if(Z.sessionId!==O)return;Y.writeSSE({data:JSON.stringify({type:Z.type,properties:{sessionId:Z.sessionId,...Z.properties}})}).catch(()=>{})}),G=setInterval(()=>{if(!Y.aborted)Y.writeSSE({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})}).catch(()=>{})},15000);Y.onAbort(()=>{clearInterval(G),K()});while(!0)if(await new Promise((Z)=>setTimeout(Z,1000)),Y.aborted)break})}),V.post("/:sessionId/message",async(f)=>{let O=f.req.param("sessionId"),J=await f.req.json(),Y=Z0.safeParse(J);if(!Y.success)throw new H("Invalid message format");let{content:Q,attachments:K,permissionMode:G}=Y.data,Z=G||"default",M=f.get("directory")||U(),j=j0(Q,K),N=m.get(O);if(!N){let X=await p.loadSession(O).catch(()=>[]);N={id:O,projectPath:M,title:`Session ${O.slice(0,6)}`,createdAt:new Date,messages:X},m.set(O,N)}let E=N.currentRunId?w.get(N.currentRunId):void 0;if(E&&(E.status==="running"||E.status==="waiting_permission")){let X=$.get(O),C=X?.enqueueSteering(j,{allowBeforeTurn:!0});if(!X){let t=E.steeringBacklog.reduce((Of,Jf)=>Of+Yf(Jf),0);if(E.steeringBacklog.length>=mf||t+Yf(j)>Rf)return f.json({status:"rejected",reason:"queue_full"},409);E.steeringBacklog.push(j)}else if(!C?.accepted)return f.json({status:"rejected",reason:C?.reason??"turn_unavailable"},409);let S=g(12),l=C?.queued??E.steeringBacklog.length;return L.publish(O,"message.created",{messageId:S,role:"user",content:Tf(j)}),L.publish(O,"steering.queued",{runId:E.id,messageId:S,queued:l}),f.json({runId:E.id,status:"steering_queued",queued:l},202)}let A=g(12),W=new AbortController,x={id:A,sessionId:O,status:"running",abortController:W,steeringBacklog:[],createdAt:new Date};return w.set(A,x),N.currentRunId=A,G0(x,N,j,Z,$).catch((X)=>{q.error(`[SessionRoutes] Run ${A} failed:`,X)}),f.json({runId:A,status:"running"},202)}),V.post("/:sessionId/abort",async(f)=>{let O=f.req.param("sessionId"),J=m.get(O);if(J?.currentRunId){let Y=w.get(J.currentRunId);if(Y)Y.abortController.abort(),Y.status="cancelled",L.publish(O,"run.cancelled",{runId:Y.id})}return f.json({success:!0})}),V.get("/:sessionId/status",async(f)=>{let O=f.req.param("sessionId"),J=m.get(O);if(!J?.currentRunId)return f.json({sessionId:O,status:"idle"});let Y=w.get(J.currentRunId);return f.json({sessionId:O,runId:J.currentRunId,status:Y?.status||"idle"})}),V};async function G0(V,$,f,O,J){let{abortController:Y,sessionId:Q,id:K}=V,G=g(12),Z=g(12),M=(j,N)=>{L.publish(Q,j,N)};try{M("message.created",{messageId:G,role:"user",content:Tf(f)}),M("session.status",{status:"running"}),M("message.created",{messageId:Z,role:"assistant",content:""});let j=J.get(Q);if(!j)j=await Hf.create({sessionId:Q,workspaceRoot:$.projectPath}),J.set(Q,j);let N=await yf.createWithRuntime(j,{sessionId:Q});for(let x of V.steeringBacklog.splice(0))j.enqueueSteering(x,{allowBeforeTurn:!0});let E=async(x)=>{let X=g(12),C=300000;V.status="waiting_permission";let S=new Promise((t)=>{let Of=setTimeout(()=>{q.warn(`[SessionRoutes] Permission ${X} timed out after 300000ms`),M("permission.timeout",{requestId:X}),t({approved:!1,reason:"timeout"})},300000);V.pendingPermission={permissionId:X,resolve:(Jf)=>{clearTimeout(Of),t(Jf)},details:x}});M("permission.asked",{requestId:X,toolName:x.toolName,description:x.message,args:x.args,details:x}),q.info(`[SessionRoutes] Permission request created: ${X}, runId: ${K}`);let l=await S;return q.info(`[SessionRoutes] Permission response received: ${X}, approved: ${l.approved}`),V.status="running",V.pendingPermission=void 0,l},A={messages:[...$.messages],userId:"web-user",sessionId:Q,workspaceRoot:$.projectPath,signal:Y.signal,permissionMode:O,confirmationHandler:{requestConfirmation:E}},W=await Wf(N.chatStream(f,A,{stream:!0}),async(x)=>{switch(x.kind){case"content_delta":M("message.delta",{messageId:Z,delta:x.delta});break;case"thinking_delta":M("thinking.delta",{delta:x.delta});break;case"tool_start":if("function"in x.toolCall)M("tool.start",{messageId:Z,toolName:x.toolCall.function.name,toolCallId:x.toolCall.id,arguments:x.toolCall.function.arguments,toolKind:x.toolKind});break;case"tool_result":if("function"in x.toolCall)M("tool.result",{messageId:Z,toolName:x.toolCall.function.name,toolCallId:x.toolCall.id,success:x.result.success,summary:x.result.metadata?.summary,output:Af(zf(x.toolCall.function.name,x.result)),metadata:M0(x.result.metadata)});break;case"token_usage":M("token.usage",{...x.usage});break;case"turn_start":M("turn.started",{turn:x.turn,maxTurns:x.maxTurns});break;case"steering_applied":M("steering.applied",{runId:K,messageIds:x.messageIds,count:x.count,queued:j.getPendingSteeringCount()});break;case"compaction":M(x.phase==="start"?"compaction.started":"compaction.completed",{});break;case"model_fallback":M("model.fallback",{});break;case"task_update":M("task.updated",{tasks:x.tasks});break;default:break}});$.messages=[...A.messages],M("message.complete",{messageId:Z}),M("thinking.completed",{}),V.status="completed",M("session.completed",{runId:K,outputTruncated:W.metadata?.outputTruncated??!1}),M("session.status",{status:"idle"})}catch(j){q.error("[SessionRoutes] Agent execution error:",j),V.status="failed",M("session.error",{error:j instanceof Error?j.message:"Unknown error"}),M("session.status",{status:"error"})}}function _f(V,$,f){q.info(`[SessionRoutes] Looking for permission ${$} in session ${V}`),q.info(`[SessionRoutes] Active runs: ${w.size}`);for(let[O,J]of w.entries())if(q.info(`[SessionRoutes] Checking run ${O}: sessionId=${J.sessionId}, pendingPermission=${J.pendingPermission?.permissionId}`),J.sessionId===V&&J.pendingPermission?.permissionId===$)return J.pendingPermission.resolve(f),q.info(`[SessionRoutes] Permission ${$} responded, runId: ${J.id}`),!0;return q.error(`[SessionRoutes] Permission not found: ${$}`),!1}var Zf=F("Service"),N0=z.object({approved:z.boolean(),remember:z.boolean().optional(),scope:z.enum(["once","session"]).optional(),targetMode:z.enum(["default","autoEdit","plan","yolo"]).optional(),feedback:z.string().optional(),answers:z.record(z.union([z.string(),z.array(z.string())])).optional()}),wf=()=>{let V=new x0;return V.post("/:permissionId",async($)=>{let f=$.req.param("permissionId"),O=$.req.query("sessionId");Zf.info(`[PermissionRoutes] Received permission response: permissionId=${f}, sessionId=${O}`);try{let J=await $.req.json(),Y=N0.safeParse(J);if(!Y.success)throw new H("Invalid permission response format");let{approved:Q,remember:K,scope:G,targetMode:Z,feedback:M,answers:j}=Y.data;if(!O)throw new H("sessionId query parameter is required");if(!_f(O,f,{approved:Q,reason:M,scope:G,targetMode:Z,feedback:M,answers:j}))throw new h("Permission request",f);return Zf.info(`[PermissionRoutes] Permission ${f} ${Q?"approved":"denied"}`),$.json({success:!0,approved:Q,remember:K})}catch(J){throw Zf.error("[PermissionRoutes] Failed to respond to permission:",J),J}}),V};import{Hono as X0}from"hono";var bf=F("Service"),Pf=()=>{let V=new X0;return V.get("/",async($)=>{try{let f=await Df();return $.json(f)}catch(f){return bf.error("[ProviderRoutes] Failed to list providers:",f),$.json([])}}),V.get("/:provider/models",async($)=>{let f=$.req.param("provider");try{let O=await Lf(f);return $.json(O)}catch(O){return bf.error("[ProviderRoutes] Failed to list models:",O),$.json([])}}),V};import{Hono as F0}from"hono";import*as b from"node:fs/promises";import{homedir as U0}from"node:os";import*as e from"node:path";var P=F("Service"),Kf=e.join(U0(),".blade","skills-config.json");async function Sf(){try{let V=await b.readFile(Kf,"utf-8");return JSON.parse(V)}catch{return{disabled:[]}}}async function E0(V){await b.mkdir(e.dirname(Kf),{recursive:!0}),await b.writeFile(Kf,JSON.stringify(V,null,2))}async function q0(V,$){let f=await Sf();if($)f.disabled=f.disabled.filter((O)=>O!==V);else if(!f.disabled.includes(V))f.disabled.push(V);await E0(f)}var o=null,B0=300000;async function W0(){if(o&&Date.now()-o.timestamp<B0)return o.data;try{let V=await fetch("https://api.github.com/repos/anthropics/skills/contents/skills",{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"Blade-Skills-Catalog"}});if(!V.ok)return P.warn(`GitHub API returned ${V.status}`),o?.data||[];let $=await V.json(),f=[];for(let O of $){if(O.type!=="dir")continue;let J=`Official ${O.name} skill`;try{let Y=await fetch(`https://raw.githubusercontent.com/anthropics/skills/main/skills/${O.name}/SKILL.md`,{headers:{"User-Agent":"Blade-Skills-Catalog"}});if(Y.ok){let K=(await Y.text()).match(/^#[^\n]*\n+([^\n#]+)/);if(K)J=K[1].trim().slice(0,100)}}catch{}f.push({name:O.name,description:J,tag:"Official",author:"Anthropic"})}return o={data:f,timestamp:Date.now()},f}catch(V){return P.warn("Failed to fetch skills catalog from GitHub:",V),o?.data||[]}}var hf=()=>{let V=new F0;return V.get("/",async($)=>{try{let f=s();await f.initialize();let O=f.getAll(),J=await Sf(),Y=O.map((Q)=>({id:Q.name,name:Q.name,enabled:!J.disabled.includes(Q.name),description:Q.description||"",version:Q.version||"1.0.0",provider:"Local",location:Q.source==="builtin"?"Built-in":Q.basePath,capabilities:["prompts"],allowedTools:Q.allowedTools||[]}));return $.json(Y)}catch(f){return P.error("[SkillsRoutes] Failed to get skills:",f),$.json([])}}),V.post("/:name/toggle",async($)=>{try{let f=$.req.param("name"),O=await $.req.json();return await q0(f,O.enabled),$.json({success:!0,enabled:O.enabled})}catch(f){return P.error("[SkillsRoutes] Failed to toggle skill:",f),$.json({success:!1,error:f.message},500)}}),V.delete("/:name",async($)=>{try{let f=$.req.param("name"),O=`${process.env.HOME}/.blade/skills/${f}`;return await b.rm(O,{recursive:!0,force:!0}),await s().refresh(),$.json({success:!0})}catch(f){return P.error("[SkillsRoutes] Failed to uninstall skill:",f),$.json({success:!1,error:f.message},500)}}),V.post("/install",async($)=>{try{let f=await $.req.json(),O=kf(),J=s(),Y=!1;if(f.source==="catalog"&&f.name){if(Y=await O.installOfficialSkill(f.name),!Y)return $.json({success:!1,error:"Failed to install skill from catalog"},500)}else if(f.source==="repo"&&f.url){if(Y=await O.installFromRepo(f.url,f.name),!Y)return $.json({success:!1,error:"Failed to install skill from repository. Make sure the repo contains a SKILL.md file."},500)}else if(f.source==="local"&&f.path){if(Y=await O.installFromLocal(f.path,f.name),!Y)return $.json({success:!1,error:"Failed to install skill from local path. Make sure the path exists and contains a SKILL.md file."},500)}else return $.json({success:!1,error:"Invalid install parameters. Required: source with corresponding url/path/name"},400);return await J.refresh(),$.json({success:!0})}catch(f){return P.error("[SkillsRoutes] Failed to install skill:",f),$.json({success:!1,error:f.message},500)}}),V.get("/catalog",async($)=>{try{let f=await W0();return $.json(f)}catch(f){return P.error("[SkillsRoutes] Failed to get catalog:",f),$.json([])}}),V};import m0 from"fast-glob";import{Hono as R0}from"hono";import{execSync as H0}from"node:child_process";import{readdir as z0}from"node:fs/promises";import ff from"node:path";var a=F("Service"),A0=(V)=>{try{return H0("git rev-parse --abbrev-ref HEAD",{cwd:V,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}},y0=[...$f.map((V)=>`${V}/**`),...$f,...Mf.map((V)=>`**/${V}`)],T0=new Set(["/theme","/model","/permissions","/mcp","/skills","/exit","/resume","/ide","/login","/logout"]),vf=()=>{let V=new R0;return V.get("/commands",async($)=>{try{let f=$.req.query("q")||"",O=uf(f).filter((J)=>!T0.has(J.command));return $.json(O)}catch(f){return a.error("[SuggestionsRoutes] Failed to get command suggestions:",f),$.json([])}}),V.get("/files",async($)=>{try{let f=$.req.query("q")||"",O=$.get("directory")||U(),J=Math.min(Number($.req.query("limit"))||100,1000),Q=(await m0("**/*",{cwd:O,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:y0})).map((Z)=>Z.replace(/\\/g,"/"));if(!f)return $.json(Q.slice(0,J));let K=f.toLowerCase(),G=Q.filter((Z)=>Z.toLowerCase().includes(K)).slice(0,J);return $.json(G)}catch(f){return a.error("[SuggestionsRoutes] Failed to get file suggestions:",f),$.json([])}}),V.get("/files/tree",async($)=>{try{let f=$.get("directory")||U(),O=$.req.query("path")||"",J=O?ff.join(f,O):f,Q=(await z0(J,{withFileTypes:!0})).map((Z)=>({name:Z.name,path:O?`${O}/${Z.name}`:Z.name,type:Z.isDirectory()?"dir":"file"}));Q.sort((Z,M)=>{if(Z.type!==M.type)return Z.type==="dir"?-1:1;return Z.name.localeCompare(M.name)});let K=new Set($f),G=Q.filter((Z)=>{let M=Z.name;if(M.startsWith("."))return!1;if(K.has(M))return!1;for(let j of Mf)if(M.match(new RegExp(j.replace("*",".*"))))return!1;return!0});return $.json(G)}catch(f){return a.error("[SuggestionsRoutes] Failed to get file tree:",f),$.json([])}}),V.get("/files/content",async($)=>{try{let f=$.req.query("path");if(!f)return $.json({error:"Missing file path"},400);let O=$.get("directory")||U(),J=ff.resolve(O,f),Y=ff.relative(O,J);if(Y.startsWith("..")||ff.isAbsolute(Y))return $.json({error:"Invalid file path"},400);let Q=If(),K=await Q.stat(J);if(!K?.isFile)return $.json({error:"File not found"},404);let G=200000,Z=await Q.readTextFile(J),M=Z.length>G;return $.json({path:f,content:M?Z.slice(0,G):Z,truncated:M,size:K.size})}catch(f){return a.error("[SuggestionsRoutes] Failed to get file content:",f),$.json({error:"Failed to read file"},500)}}),V.get("/git-info",async($)=>{try{let f=$.get("directory")||U(),O=A0(f);return $.json({branch:O})}catch(f){return a.error("[SuggestionsRoutes] Failed to get git info:",f),$.json({branch:null})}}),V};import{Hono as C0}from"hono";var D=F("Service"),d=new Map,pf=2097152,gf=65536;function of(){return typeof globalThis.Bun<"u"}async function _0(V,$,f){if(of()){let{spawn:Y}=await import("bun-pty"),Q=Y(V,$,{name:"xterm-256color",cwd:f.cwd,env:f.env});return{pid:Q.pid,write:(K)=>Q.write(K),resize:(K,G)=>Q.resize(K,G),kill:()=>Q.kill(),onData:(K)=>Q.onData(K),onExit:(K)=>Q.onExit(K)}}let J=(await import("node-pty")).spawn(V,$,{name:"xterm-256color",cwd:f.cwd,env:f.env,cols:80,rows:24});return{pid:J.pid,write:(Y)=>J.write(Y),resize:(Y,Q)=>J.resize(Y,Q),kill:()=>J.kill(),onData:(Y)=>{J.onData(Y)},onExit:(Y)=>{J.onExit(Y)}}}var xf=void 0,Gf;if(of())try{let{createBunWebSocket:V}=await import("hono/bun"),$=V();Gf=$.upgradeWebSocket,xf=$.websocket}catch(V){D.warn("[Terminal] Failed to initialize Bun WebSocket support:",V)}async function df(V,$){let f=`term-${Date.now()}`;D.info(`[Terminal] New connection: ${f}, cwd: ${V}`);let O=process.platform==="win32"?"powershell.exe":process.env.SHELL||"/bin/zsh",J=O.endsWith("sh")?["-l"]:[],Y=await _0(O,J,{cwd:V,env:{...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"}}),Q={id:f,process:Y,cwd:V,buffer:"",subscribers:new Set};if(d.set(f,Q),Q.subscribers.add($),Y.onData((K)=>{let G=!1;for(let Z of Q.subscribers)try{Z.send(K),G=!0}catch{Q.subscribers.delete(Z)}if(G)return;if(Q.buffer+=K,Q.buffer.length>pf)Q.buffer=Q.buffer.slice(-pf)}),Y.onExit(({exitCode:K})=>{D.info(`[Terminal] Process exited: ${f}, code: ${K}`);for(let G of Q.subscribers)try{G.close()}catch{}d.delete(f)}),Q.buffer){let K=Q.buffer;Q.buffer="";for(let G=0;G<K.length;G+=gf)$.send(K.slice(G,G+gf))}return{session:Q,cleanup:()=>{if(D.info(`[Terminal] Connection closed: ${f}`),Q.subscribers.delete($),Q.subscribers.size===0){try{Q.process.kill()}catch{}d.delete(f)}}}}function lf(V,$){V.on("connection",async(f,O)=>{let J=new URL(O.url||"/",`http://${O.headers.host}`);if(!J.pathname.endsWith("/terminal/ws")){f.close();return}let Y=J.searchParams.get("cwd")||$()||U();try{let{session:Q,cleanup:K}=await df(Y,{send:(G)=>f.send(G),close:()=>f.close()});f.on("message",(G)=>{try{Q.process.write(String(G))}catch(Z){D.error("[Terminal] Failed to write to PTY:",Z)}}),f.on("close",K),f.on("error",K)}catch(Q){D.error("[Terminal] Failed to spawn PTY:",Q),f.close()}})}var rf=()=>{let V=new C0;if(V.get("/status",($)=>{let f=Array.from(d.values()).map((O)=>({id:O.id,cwd:O.cwd}));return $.json({active:f.length,terminals:f})}),V.post("/kill/:terminalId",($)=>{let f=$.req.param("terminalId"),O=d.get(f);if(O){try{O.process.kill()}catch{}for(let J of O.subscribers)J.close();return d.delete(f),$.json({success:!0})}return $.json({success:!1,error:"Terminal not found"},404)}),Gf)V.get("/ws",Gf(($)=>{let f=$.req.query("cwd")||$.get("directory")||U(),O;return{async onOpen(J,Y){try{O=await df(f,{send:(Q)=>Y.send(Q),close:()=>Y.close()})}catch(Q){D.error("[Terminal] Failed to spawn PTY:",Q),Y.close()}},onMessage(J){if(!O)return;try{O.session.process.write(String(J.data))}catch(Y){D.error("[Terminal] Failed to write to PTY:",Y)}},onClose(){O?.cleanup()}}}));else V.get("/ws",($)=>{return $.json({message:"WebSocket endpoint - connect via ws:// protocol",hint:"Use WebSocket client to connect to this endpoint"})});return V};var R=F("Service"),Nf=[];function I0(){let V=P0(S0(import.meta.url)),$=[k(V,"web"),k(U(),"dist/web"),k(U(),"packages/cli/dist/web")];for(let f of $){let O=k(f,"index.html");if(tf(O)){if(Vf(O,"utf-8").includes("/assets/"))return R.debug(`[Server] Found web dist at: ${f}`),f}}return null}function u0(){let V=new w0;V.onError((f,O)=>{if(R.error("[Server] Request error:",f),f instanceof r)return O.json(f.toObject(),f.statusCode);let J=f instanceof Error?f.message:String(f);return O.json({error:{code:"INTERNAL_ERROR",message:J}},500)}),V.use(async(f,O)=>{let J=process.env.BLADE_SERVER_PASSWORD;if(!J)return O();let Y=f.req.path;if(Y==="/"||Y.startsWith("/assets/")||Y.endsWith(".html")||Y.endsWith(".js")||Y.endsWith(".css"))return O();let Q=f.req.header("Authorization");if(!Q?.startsWith("Basic "))return f.header("WWW-Authenticate",'Basic realm="Blade Server"'),f.json({error:{code:"UNAUTHORIZED",message:"Authentication required"}},401);let K=Buffer.from(Q.slice(6),"base64").toString(),[G,Z]=K.split(":"),M=process.env.BLADE_SERVER_USERNAME??"blade";if(G!==M||Z!==J)return f.json({error:{code:"UNAUTHORIZED",message:"Invalid credentials"}},401);return O()}),V.use(async(f,O)=>{let J=f.req.path==="/health"||f.req.path==="/global/health"||f.req.path.startsWith("/assets/");if(!J)R.debug(`[Server] ${f.req.method} ${f.req.path}`);let Y=Date.now();if(await O(),!J){let Q=Date.now()-Y;R.debug(`[Server] ${f.req.method} ${f.req.path} - ${f.res.status} (${Q}ms)`)}}),V.use(b0({origin(f){if(!f)return;if(f.startsWith("http://localhost:"))return f;if(f.startsWith("http://127.0.0.1:"))return f;if(f==="tauri://localhost"||f==="http://tauri.localhost")return f;if(Nf.includes(f))return f;return}})),V.use(async(f,O)=>{let J=f.req.query("directory")||f.req.header("x-blade-directory")||U();try{J=decodeURIComponent(J)}catch{}return f.set("directory",J),O()}),V.route("/global",Ff()),V.route("/sessions",Cf()),V.route("/configs",Xf()),V.route("/permissions",wf()),V.route("/providers",Pf()),V.route("/models",Bf()),V.route("/suggestions",vf()),V.route("/terminal",rf()),V.route("/mcp",Uf()),V.route("/skills",hf()),V.get("/health",(f)=>{return f.json({healthy:!0,version:v()})});let $=I0();if($)R.info(`[Server] Serving static files from ${$}`),V.get("/assets/*",(f)=>{let O=k($,f.req.path);if(!tf(O))return f.json({error:{code:"NOT_FOUND",message:`File not found: ${f.req.path}`}},404);let J=Vf(O),Y=k0(O).toLowerCase(),K={".js":"application/javascript",".css":"text/css",".html":"text/html",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"}[Y]||"application/octet-stream";return new Response(J,{headers:{"Content-Type":K,"Cache-Control":"public, max-age=31536000, immutable"}})}),V.get("/",(f)=>{let O=k($,"index.html"),J=Vf(O,"utf-8");return f.html(J)}),V.get("*",(f)=>{let O=f.req.path;if(O.includes("."))return f.json({error:{code:"NOT_FOUND",message:`File not found: ${O}`}},404);let J=k($,"index.html"),Y=Vf(J,"utf-8");return f.html(Y)});else R.warn('[Server] Web UI not found. Run "cd packages/cli/web && bun run build" to enable web interface.'),V.get("/",(f)=>{return f.json({message:"Blade API Server",version:v(),webUI:!1,hint:'Web UI not built. Run "cd packages/cli/web && bun run build" to enable.',endpoints:{health:"/health",sessions:"/sessions",configs:"/configs",permissions:"/permissions",providers:"/providers"}})}),V.all("*",(f)=>{return f.json({error:{code:"NOT_FOUND",message:`Route not found: ${f.req.path}`}},404)});return V}function v0(){let V=L0(),$=[];for(let f of Object.keys(V)){let O=V[f];if(!O)continue;for(let J of O){if(J.internal||J.family!=="IPv4")continue;if(J.address.startsWith("172."))continue;$.push(J.address)}}return $}function cf(){return typeof globalThis.Bun<"u"}function af(V,$){let f=globalThis.Bun,O=(Y)=>{try{return f.serve({hostname:$.hostname,port:Y,fetch:V.fetch,idleTimeout:0,websocket:xf})}catch(Q){R.error("Failed to start Bun server:",Q);return}},J=$.port===0?O(4096)??O(0):O($.port);if(!J)throw Error(`Failed to start Bun server on port ${$.port}`);return{url:J.url,port:J.port,hostname:J.hostname,stop:async()=>{J.stop(!0)}}}function p0(V,$){return new Promise((f,O)=>{let J=D0(async(Z,M)=>{let j=new URL(Z.url||"/",`http://${Z.headers.host}`),N=new Headers;for(let[W,x]of Object.entries(Z.headers))if(x)if(Array.isArray(x))for(let X of x)N.append(W,X);else N.set(W,x);let E;if(Z.method!=="GET"&&Z.method!=="HEAD")E=(await new Promise((x)=>{let X=[];Z.on("data",(C)=>X.push(C)),Z.on("end",()=>x(Buffer.concat(X)))})).toString();let A=new Request(j.toString(),{method:Z.method,headers:N,body:E});try{let W=await V.fetch(A);if(M.statusCode=W.status,W.headers.forEach((x,X)=>{M.setHeader(X,x)}),W.body){let x=W.body.getReader(),X=async()=>{let{done:C,value:S}=await x.read();if(C){M.end();return}return M.write(S),X()};await X()}else{let x=await W.text();M.end(x)}}catch(W){R.error("[Server] Node request error:",W),M.statusCode=500,M.end(JSON.stringify({error:{code:"INTERNAL_ERROR",message:"Internal server error"}}))}}),Y=new h0({noServer:!0}),Q=U();lf(Y,()=>Q),J.on("upgrade",(Z,M,j)=>{if(new URL(Z.url||"/",`http://${Z.headers.host}`).pathname==="/terminal/ws")Y.handleUpgrade(Z,M,j,(E)=>{Y.emit("connection",E,Z)});else M.destroy()});let K=(Z)=>{return new Promise((M,j)=>{J.once("error",(N)=>{if(N.code==="EADDRINUSE")j(N);else j(N)}),J.listen(Z,$.hostname,()=>{let N=J.address();if(N&&typeof N==="object")M(N.port);else M(Z)})})};(async()=>{let Z;if($.port===0)try{Z=await K(4096)}catch{Z=await K(0)}else Z=await K($.port);let M=new URL(`http://${$.hostname==="0.0.0.0"?"localhost":$.hostname}:${Z}`);f({url:M,port:Z,hostname:$.hostname,stop:async()=>{return new Promise((j)=>{Y.close(()=>{J.close(()=>j())})})}})})().catch(O)})}var nf;((PV)=>{let V,$;function f(){if(!$)$=u0();return $}PV.getApp=f;function O(Q){Nf=Q.cors??[];let K=f();if(cf())V=af(K,Q),R.info(`[Server] Blade server listening on ${V.url} (Bun runtime)`);else throw Error("Blade web server requires Bun runtime. Please run with Bun: `bun run blade web` or install Bun from https://bun.sh");let G=V;return{url:G.url,port:G.port,hostname:G.hostname,stop:async()=>{if(V)await V.stop(),V=void 0,$=void 0,R.info("[Server] Blade server stopped")}}}PV.listen=O;async function J(Q){Nf=Q.cors??[];let K=f();if(cf())V=af(K,Q),R.info(`[Server] Blade server listening on ${V.url} (Bun runtime)`);else V=await p0(K,Q),R.info(`[Server] Blade server listening on ${V.url} (Node.js runtime)`);let G=V;return{url:G.url,port:G.port,hostname:G.hostname,stop:async()=>{if(V)await V.stop(),V=void 0,$=void 0,R.info("[Server] Blade server stopped")}}}PV.listenAsync=J;function Y(){return V!==void 0}PV.isRunning=Y})(nf||={});export{g0 as f,o0 as g,v0 as h,nf as i};
|
package/dist/chunk-abpvdaq2.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import{B as W,K as L,N as P,O as T,Q as R,T as U,W as M,Y as h,Z as j}from"./chunk-t6y57501.js";import"./chunk-z0qxaky4.js";import{ba as y}from"./chunk-t3pyakvc.js";import"./chunk-22gxb9qs.js";import{ua as A}from"./chunk-wc2xb6ge.js";import"./chunk-b6mxeey0.js";import"./chunk-k18bq4mn.js";import{Ya as f}from"./chunk-zcreym5g.js";import"./chunk-wcm0nc84.js";import"./chunk-p6d7k1x6.js";import{wb as B}from"./chunk-cadngkwr.js";import"./chunk-m4a480k7.js";import{Nb as _}from"./chunk-4hk7wfat.js";import"./chunk-cfrbsnfb.js";import{Readable as v,Writable as c}from"node:stream";import*as w from"@agentclientprotocol/sdk";import{PROTOCOL_VERSION as u}from"@agentclientprotocol/sdk";import{nanoid as C}from"nanoid";import{nanoid as K}from"nanoid";var Y=_("Agent");function N(z){return Object.fromEntries(z.map((G)=>[G.name,G.value]))}function b(z){if("command"in z)return{type:"stdio",command:z.command,args:z.args,env:N(z.env)};return{type:z.type,url:z.url,headers:N(z.headers)}}function k(z){return Object.fromEntries(z.map((G)=>[G.name,b(G)]))}function S(z){if(typeof z==="string")return z?[{type:"text",text:z}]:[];return z.flatMap((G)=>{if(G.type==="text")return G.text?[{type:"text",text:G.text}]:[];let H=G.image_url.url,J=/^data:([^;,]+);base64,(.+)$/s.exec(H);if(!J)return[{type:"text",text:"[Image]"}];return[{type:"image",mimeType:J[1]??"image/png",data:J[2]??""}]})}class D{id;cwd;connection;clientCapabilities;options;agent=null;runtime=null;pendingPrompt=null;messages;mode="default";sessionApprovals=new Set;constructor(z,G,H,J,Q={}){this.id=z;this.cwd=G;this.connection=H;this.clientCapabilities=J;this.options=Q;this.messages=[...Q.initialMessages??[]]}async initialize(){Y.debug(`[AcpSession ${this.id}] Initializing...`),W.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),Y.debug(`[AcpSession ${this.id}] ACP service context initialized`);let z=this.options.mcpServers?k(this.options.mcpServers):void 0;this.runtime=await L.create({sessionId:this.id,workspaceRoot:this.cwd,...z?{mcpServers:z}:{}}),this.agent=await R.createWithRuntime(this.runtime,{sessionId:this.id}),Y.debug(`[AcpSession ${this.id}] Agent created successfully`)}async replayHistory(){for(let z of this.messages){let G=z.role==="user"?"user_message_chunk":z.role==="assistant"?"agent_message_chunk":void 0;if(!G)continue;for(let H of S(z.content))await this.connection.sessionUpdate({sessionId:this.id,update:{sessionUpdate:G,content:H}})}}sendAvailableCommandsDelayed(){Y.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand(z,G){try{Y.debug(`[AcpSession ${this.id}] Executing slash command: ${z}`);let H={cwd:this.cwd,signal:G,acp:{sendMessage:(X)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:X}})},sendToolStart:(X,Z,E)=>{let $=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,F=this.mapToolKind(E);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:$,status:"in_progress",title:`${X}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(Z,null,2)}}],kind:F})},sendToolResult:(X,Z)=>{if(Z.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Z.summary}})}}},J=await h(z,H),Q=J.content||J.message;if(Q)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q}});if(J.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] ${J.error}`}});return{stopReason:J.success?"end_turn":"cancelled"}}catch(H){return Y.error(`[AcpSession ${this.id}] Slash command error:`,H),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] 命令执行失败: ${H instanceof Error?H.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let z=j(),G=["model","permissions","theme","config","exit","ide"],J=z.filter((Q)=>!G.includes(Q.name)).map((Q)=>{let X;if(Q.usage){let Z=Q.usage.replace(/^\/\w+\s*/,"").trim();if(Z)X=Z}if(Q.aliases?.length){let Z=`Aliases: ${Q.aliases.join(", ")}`;X=X?`${X} | ${Z}`:Z}return{name:Q.name,description:Q.description,input:X?{hint:X}:void 0}});Y.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(J.map((Q)=>Q.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:J}),Y.info(`[AcpSession ${this.id}] Sent ${J.length} available commands`)}catch(z){Y.error(`[AcpSession ${this.id}] Failed to send available commands:`,z)}}async prompt(z){if(W.setCurrentSession(this.id),!this.agent||!this.runtime)throw Error("Session not initialized");let G=this.resolvePrompt(z.prompt);if(this.pendingPrompt){let J=this.runtime.enqueueSteering(G,{allowBeforeTurn:!0});if(!J.accepted)throw Error(J.reason==="queue_full"?"Active turn steering queue is full":"Active turn is no longer steerable");return Y.debug(`[AcpSession ${this.id}] Queued steering for active turn (${J.queued})`),{stopReason:"end_turn"}}let H=new AbortController;this.pendingPrompt=H;try{if(Y.debug(`[AcpSession ${this.id}] Received prompt: ${G.slice(0,100)}...`),M(G))return await this.handleSlashCommand(G,H.signal);let J={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:H.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(Q)=>{return this.requestPermission(Q)}}};if(await f(this.agent.chatStream(G,J),async(Q)=>{switch(Q.kind){case"content_delta":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q.delta}});break;case"thinking_delta":this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:Q.delta}});break;case"tool_start":{let X=Q.toolCall,Z="function"in X?X.function.name:X.type,E=this.mapToolKind(Q.toolKind);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:X.id,status:"in_progress",title:`Executing ${Z}`,content:[],kind:E});break}case"tool_result":{let{toolCall:X,result:Z}=Q,E=[],$=Z.metadata;if($?.kind==="edit"&&typeof $.file_path==="string"&&typeof $.oldContent==="string"&&(typeof $.newContent==="string"||$.newContent===void 0))E.push({type:"diff",path:$.file_path,oldText:$.oldContent,newText:$.newContent??null});else{let V="function"in X?X.function.name:X.type,x=T(P(V,Z));E.push({type:"content",content:{type:"text",text:x}})}let F=Z.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:X.id,status:F,content:E});break}case"task_update":this.sendPlanUpdate(Q.tasks);break;default:break}}),this.messages=[...J.messages],H.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(J){if(H.signal.aborted||J instanceof Error&&J.name==="AbortError")return{stopReason:"cancelled"};throw Y.error(`[AcpSession ${this.id}] Prompt error:`,J),J}finally{if(this.pendingPrompt===H)this.pendingPrompt=null}}cancel(){if(Y.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,Y.info(`[AcpSession ${this.id}] Cancelled successfully`);else Y.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode(z){let G=["default","auto-edit","yolo","plan"];this.mode=G.includes(z)?z:"default",Y.info(`[AcpSession ${this.id}] Mode set to: ${this.mode}`),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})}mapModeToPermissionMode(){switch(this.mode){case"yolo":return"yolo";case"auto-edit":return"autoEdit";case"plan":return"plan";case"default":default:return"default"}}shouldAutoApprove(z){switch(this.mode){case"yolo":return!0;case"auto-edit":return z==="readonly"||z==="write";case"plan":return z==="readonly";case"default":default:return!1}}async setModel(z){if(Y.info(`[AcpSession ${this.id}] Model set to: ${z}`),this.pendingPrompt)throw Error("Cannot switch models while a prompt is active");if(!this.agent)throw Error("Session not initialized");await this.agent.switchModel(z)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;if(this.runtime)await this.runtime.dispose(),this.runtime=null;W.destroySession(this.id),Y.debug(`[AcpSession ${this.id}] Destroyed`)}resolvePrompt(z){let G=[];for(let H of z)if(H.type==="text")G.push(H.text);else if(H.type==="image")G.push(`[Image: ${H.mimeType}]`);else if(H.type==="resource"){let J=H.resource;if("text"in J)G.push(`<file path="${J.uri}">
|
|
2
|
-
${J.text}
|
|
3
|
-
</file>`)}else if(H.type==="resource_link")G.push(`[Resource: ${H.uri}]`);return G.join(`
|
|
4
|
-
`)}sendUpdate(z){let G={sessionId:this.id,update:z};this.connection.sessionUpdate(G).catch((H)=>{Y.warn(`[AcpSession ${this.id}] Failed to send update:`,H)})}sendPlanUpdate(z){let G=z.map((H)=>({content:H.subject,priority:H.priority,status:H.status}));Y.debug(`[AcpSession ${this.id}] Sending plan update with ${G.length} entries`),this.sendUpdate({sessionUpdate:"plan",entries:G})}async requestPermission(z){let G=z.kind?.toLowerCase()||"execute";if(this.shouldAutoApprove(G))return Y.debug(`[AcpSession ${this.id}] Auto-approving ${G} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(G==="write"||G==="execute"))return Y.debug(`[AcpSession ${this.id}] Rejecting ${G} in plan mode`),{approved:!1,reason:"Write and execute operations are not allowed in Plan mode"};let H=`${G}:${z.title||"unknown"}`;if(this.sessionApprovals.has(H))return Y.debug(`[AcpSession ${this.id}] Using cached approval for: ${H}`),{approved:!0};try{let J=K(),Q=[];if(z.message)Q.push({type:"content",content:{type:"text",text:z.message}});if(z.risks&&z.risks.length>0)Q.push({type:"content",content:{type:"text",text:`Risks:
|
|
5
|
-
- ${z.risks.join(`
|
|
6
|
-
- `)}`}});let X=this.mapToolKind(G),Z={sessionId:this.id,options:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},{optionId:"allow_always",name:"Always allow",kind:"allow_always"},{optionId:"reject_once",name:"Deny once",kind:"reject_once"},{optionId:"reject_always",name:"Always deny",kind:"reject_always"}],toolCall:{toolCallId:J,status:"pending",title:z.title||"Permission Required",content:Q,kind:X}},$=(await this.connection.requestPermission(Z)).outcome;if($.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let F=$.optionId,V=F==="allow_once"||F==="allow_always";if(F==="allow_always")this.sessionApprovals.add(H),Y.debug(`[AcpSession ${this.id}] Cached approval for: ${H}`);return{approved:V,reason:V?void 0:"User denied the operation"}}catch(J){return Y.warn(`[AcpSession ${this.id}] Permission request failed:`,J),{approved:!1,reason:"Permission request failed"}}}mapToolKind(z){return{readonly:"read",write:"edit",execute:"execute",read:"read",edit:"edit",delete:"delete",move:"move",search:"search",think:"think",fetch:"fetch"}[z||""]||"other"}}var q=_("Agent");class O{connection;sessions=new Map;clientCapabilities;constructor(z){this.connection=z}async initialize(z){return q.info("[BladeAgent] Initializing ACP connection"),q.debug(`[BladeAgent] Client capabilities: ${JSON.stringify(z.clientCapabilities)}`),this.clientCapabilities=z.clientCapabilities,{protocolVersion:u,agentCapabilities:{loadSession:!0,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate(z){return}async newSession(z){let G=C();q.info(`[BladeAgent] Creating new session: ${G}`),q.debug(`[BladeAgent] Session cwd: ${z.cwd||B()}`);let H=new D(G,z.cwd||B(),this.connection,this.clientCapabilities,{mcpServers:z.mcpServers});try{await H.initialize()}catch(J){throw await H.destroy().catch(()=>{return}),J}return this.sessions.set(G,H),q.info(`[BladeAgent] Session ${G} created, scheduling available commands update`),H.sendAvailableCommandsDelayed(),{sessionId:G,...this.buildSessionState()}}async loadSession(z){q.info(`[BladeAgent] Loading session: ${z.sessionId}`);let G=await U.loadSession(z.sessionId,z.cwd),H=this.sessions.get(z.sessionId);if(H)await H.destroy(),this.sessions.delete(z.sessionId),G=await U.loadSession(z.sessionId,z.cwd);let J=new D(z.sessionId,z.cwd,this.connection,this.clientCapabilities,{initialMessages:G,mcpServers:z.mcpServers});try{await J.initialize(),await J.replayHistory()}catch(Q){throw await J.destroy().catch(()=>{return}),Q}return this.sessions.set(z.sessionId,J),J.sendAvailableCommandsDelayed(),this.buildSessionState()}buildSessionState(){let z=A(),G=z?.models||[],H=z?.currentModelId||G[0]?.id,J=G.map((X)=>({modelId:X.id,name:X.name||X.id,description:X.provider?`Provider: ${X.provider}`:void 0}));return{modes:{availableModes:[{id:"default",name:"Default",description:"Ask for confirmation before all file edits and commands"},{id:"auto-edit",name:"Auto Edit",description:"Auto-approve file edits, ask for shell commands"},{id:"yolo",name:"Full Auto",description:"Auto-approve everything without confirmation"},{id:"plan",name:"Plan Only",description:"Read-only mode, no file changes or commands"}],currentModeId:"default"},models:J.length>0?{availableModels:J,currentModelId:H}:void 0}}async prompt(z){let G=this.sessions.get(z.sessionId);if(!G)throw Error(`Session not found: ${z.sessionId}`);return G.prompt(z)}async cancel(z){q.info(`[BladeAgent] Cancel notification received for session: ${z.sessionId}`);let G=this.sessions.get(z.sessionId);if(G)q.info("[BladeAgent] Found session, calling session.cancel()"),G.cancel();else q.warn(`[BladeAgent] Session not found for cancel: ${z.sessionId}`)}async setSessionMode(z){q.info(`[BladeAgent] Setting session mode: ${z.modeId}`);let G=this.sessions.get(z.sessionId);if(G)await G.setMode(z.modeId);return{}}async unstable_setSessionModel(z){q.info(`[BladeAgent] Setting session model: ${z.modelId}`);let G=this.sessions.get(z.sessionId);if(!G)throw Error(`Session not found: ${z.sessionId}`);return await G.setModel(z.modelId),{}}async destroy(){for(let z of this.sessions.values())await z.destroy();this.sessions.clear(),await y.getInstance().disconnectAll()}}async function qz(){let z=c.toWeb(process.stdout),G=v.toWeb(process.stdin),H=w.ndJsonStream(z,G);await new w.AgentSideConnection((Q)=>new O(Q),H).closed}export{qz as runAcpIntegration};
|
package/dist/chunk-hv0bzn31.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Db as a}from"./chunk-m4a480k7.js";import"./chunk-4hk7wfat.js";import"./chunk-cfrbsnfb.js";export{a as createChatServiceAsync};
|
package/dist/chunk-j3k2c6tm.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a,b,c,d,e}from"./chunk-9zwf87ne.js";import"./chunk-cfrbsnfb.js";export{b as setSkipUntilVersion,d as performUpgrade,c as getUpgradeCommand,e as checkVersionOnStartup,a as checkVersion};
|
package/dist/chunk-je6r01h4.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as a,u as b}from"./chunk-qw2wy4jc.js";import"./chunk-k18bq4mn.js";import"./chunk-cfrbsnfb.js";export{a as globalOptions,b as cliConfig};
|
package/dist/chunk-nh37erd3.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{v as a,w as b,x as c}from"./chunk-m2k4h3bs.js";import"./chunk-cqrkeq20.js";import"./chunk-z0qxaky4.js";import"./chunk-wc2xb6ge.js";import"./chunk-b6mxeey0.js";import"./chunk-cadngkwr.js";import"./chunk-4hk7wfat.js";import"./chunk-cfrbsnfb.js";export{a as validatePermissions,c as validateOutput,b as loadConfiguration};
|