blade-code 0.10.100 → 0.10.102
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-fvfc95g3.js → chunk-00rps629.js} +2 -2
- package/dist/{chunk-gcnke6s4.js → chunk-19xfer55.js} +1 -1
- package/dist/{chunk-sgzqcr55.js → chunk-1wgese5c.js} +1 -1
- package/dist/chunk-4t3h306m.js +6 -0
- package/dist/{chunk-c3yd59qh.js → chunk-6kb69vkx.js} +1 -1
- package/dist/{chunk-hx55j0d0.js → chunk-6r6yzw44.js} +401 -399
- package/dist/{chunk-6hr7mv7f.js → chunk-6yezrqe7.js} +1 -1
- package/dist/{chunk-gr6e2vsy.js → chunk-9018357g.js} +1 -1
- package/dist/chunk-9b0896bm.js +12 -0
- package/dist/chunk-9n5ystr6.js +171 -0
- package/dist/{chunk-jac8cc04.js → chunk-a5jv8pn9.js} +1 -1
- package/dist/{chunk-axycs651.js → chunk-a8mgzsh7.js} +1 -1
- package/dist/chunk-anez8ekm.js +169 -0
- package/dist/{chunk-v9pcf4w4.js → chunk-b8n5mx53.js} +1 -1
- package/dist/{chunk-pzp42zf0.js → chunk-c3zcqqb7.js} +1 -1
- package/dist/{chunk-gkdynynx.js → chunk-cpk84yrx.js} +1 -1
- package/dist/chunk-cwnaydst.js +1 -0
- package/dist/{chunk-s15phq98.js → chunk-d7rg6t0n.js} +1 -1
- package/dist/chunk-enwtex3j.js +23 -0
- package/dist/{chunk-ara0zd89.js → chunk-ffp2rn7f.js} +1 -1
- package/dist/{chunk-1nwc2wt6.js → chunk-fn9cse83.js} +1 -1
- package/dist/{chunk-rmhgyrgh.js → chunk-fpx3462x.js} +1 -1
- package/dist/chunk-gdp02sqp.js +1 -0
- package/dist/{chunk-q1cc7kwn.js → chunk-hexj26gw.js} +1 -1
- package/dist/{chunk-h8qjkxee.js → chunk-hpjnk87v.js} +18 -18
- package/dist/{chunk-3ktsyk2g.js → chunk-kfmh3t1r.js} +1 -1
- package/dist/{chunk-cc74b8qp.js → chunk-kt5jqaxp.js} +1 -1
- package/dist/{chunk-b4d43ap3.js → chunk-kwkkcs4y.js} +1 -1
- package/dist/chunk-m4wnqx0e.js +8 -0
- package/dist/{chunk-6jhndjnq.js → chunk-na3jmz7f.js} +1 -1
- package/dist/{chunk-ttg3xrsc.js → chunk-pdqczfn3.js} +1 -1
- package/dist/{chunk-5dkzqgxa.js → chunk-qjeadpj2.js} +1 -1
- package/dist/{chunk-tagtjbw9.js → chunk-qw57eqns.js} +1 -1
- package/dist/{chunk-6p9p71qm.js → chunk-rkk39efr.js} +1 -1
- package/dist/{chunk-x677fstt.js → chunk-ryemn19e.js} +1 -1
- package/dist/{chunk-y7bsjbsa.js → chunk-v6hffjwc.js} +2 -2
- package/dist/{chunk-qc4fe1j6.js → chunk-vw328ehw.js} +1 -1
- package/dist/{chunk-njctfzqw.js → chunk-xy5fmskp.js} +1 -1
- package/dist/{chunk-6rd8x9j0.js → chunk-y3anmree.js} +1 -1
- package/dist/chunk-yx4802a0.js +2 -0
- package/dist/{chunk-8zm5r6g8.js → chunk-zxhv8xfp.js} +1 -1
- package/dist/{chunk-dfxfcsm1.js → chunk-zy6vm5jm.js} +1 -1
- package/dist/web/assets/ChatView-C5kVDWL0.js +58 -0
- package/dist/web/assets/{CodeBlockHighlighter-IGDocZUy.js → CodeBlockHighlighter-BxJu15oF.js} +1 -1
- package/dist/web/assets/{FilePreview-EWE-k9VN.js → FilePreview-BDNq89O6.js} +1 -1
- package/dist/web/assets/{KanbanBoard-FiiVQgTQ.js → KanbanBoard-CCn0j1Ow.js} +1 -1
- package/dist/web/assets/{MarkdownRenderer-DjhWmikM.js → MarkdownRenderer-15FrKNPV.js} +3 -3
- package/dist/web/assets/{SettingsModal-bHPx0fVG.js → SettingsModal-DCL04xT_.js} +1 -1
- package/dist/web/assets/{TaskSwitcher-CclOfJEl.js → TaskSwitcher-Gyn_K98p.js} +1 -1
- package/dist/web/assets/{TerminalPanel-Bnep8jE2.js → TerminalPanel-Cbh0NmHM.js} +1 -1
- package/dist/web/assets/{arrow-left-CiX0E9Mt.js → arrow-left-wfNAFD9Y.js} +1 -1
- package/dist/web/assets/{calendar-clock-Bgfr-twh.js → calendar-clock-BbbqqtLj.js} +1 -1
- package/dist/web/assets/{chevrons-up-down-B4T5fHUs.js → chevrons-up-down-uCUY_a67.js} +1 -1
- package/dist/web/assets/{clock-3-CGIhJjon.js → clock-3-DfiIeEEf.js} +1 -1
- package/dist/web/assets/{external-link-DnQv1VYE.js → external-link-CilEshFB.js} +1 -1
- package/dist/web/assets/{folder-C5f8TpGj.js → folder-D9K0ykgI.js} +1 -1
- package/dist/web/assets/index-BKBXGV6s.js +275 -0
- package/dist/web/assets/{pause-Cb0ijwnO.js → pause-D4a4_iHl.js} +1 -1
- package/dist/web/assets/{play-Dsw1qmpk.js → play-D9guMjPv.js} +1 -1
- package/dist/web/assets/{session-events-B4Cq2TwN.js → session-events-DelJesUm.js} +19 -19
- package/dist/web/assets/{teamService-C69fFhny.js → teamService-CAVeS_dL.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/chunk-2s86w4yb.js +0 -171
- package/dist/chunk-73t5j9dn.js +0 -160
- package/dist/chunk-8wzn2p00.js +0 -6
- package/dist/chunk-hx3c0qn6.js +0 -9
- package/dist/chunk-hz5rsfxv.js +0 -2
- package/dist/chunk-p4h3p1at.js +0 -23
- package/dist/chunk-t29x8420.js +0 -1
- package/dist/chunk-tsthz2ex.js +0 -8
- package/dist/chunk-vgevdm8b.js +0 -1
- package/dist/web/assets/ChatView-Cwc3fRAC.js +0 -58
- package/dist/web/assets/index-DNoVz0u1.js +0 -275
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import{ni as r}from"./chunk-d8wzc602.js";import{Li as d,Ni as x,Pi as j,Ti as u,Ui as i}from"./chunk-q3vza5gt.js";import{Vi as
|
|
1
|
+
import{ni as r}from"./chunk-d8wzc602.js";import{Li as d,Ni as x,Pi as j,Ti as u,Ui as i}from"./chunk-q3vza5gt.js";import{Vi as I}from"./chunk-w9xfks7f.js";import{stat as a}from"node:fs/promises";import B from"node:path";import*as U from"node:path";var e=50,__=100,E_=new Set(["queued","running","completed","failed","cancelled","interrupted"]),R_=new Set(["high","medium","low"]),W_=/^[A-Za-z0-9_-]+$/,$_=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}:\d{2})$/;function H_(_){return typeof _==="string"&&$_.test(_)&&Number.isFinite(Date.parse(_))}function v(_){return typeof _==="string"&&U.isAbsolute(_)}function M_(_){return Buffer.from(JSON.stringify(_),"utf8").toString("base64url")}function Q_(_){try{if(!W_.test(_))throw Error("invalid");let E=Buffer.from(_,"base64url").toString("utf8");if(Buffer.from(E,"utf8").toString("base64url")!==_)throw Error("invalid");let R=JSON.parse(E);if(R.version!==1||typeof R.includeSubagents!=="boolean"||R.archived!==void 0&&typeof R.archived!=="boolean"||!(R.cwd===null||v(R.cwd))||!H_(R.lastMessageTime)||!v(R.projectPath)||!x(R.sessionId))throw Error("invalid");return{version:1,cwd:R.cwd===null?null:U.resolve(R.cwd),includeSubagents:R.includeSubagents,archived:R.archived??!1,lastMessageTime:R.lastMessageTime,projectPath:U.resolve(R.projectPath),sessionId:R.sessionId}}catch{throw Error("Invalid session cursor")}}function J(_){let E="";for(let R=0;R<_.length;R+=1)E+=_.charCodeAt(R).toString(16).padStart(4,"0");return E}function V_(_){if(!_.cursor)return;let E=Q_(_.cursor);if(E.cwd!==_.cwd||E.includeSubagents!==_.includeSubagents||(E.archived??!1)!==_.archived)throw Error("Session cursor scope does not match this query");return E}function O_(_={}){let{cwd:E,cursor:R,limit:W,includeSubagents:$=!1,archived:M=!1}=_;if(E!==void 0&&!U.isAbsolute(E))throw Error("Session catalog cwd must be absolute");let H=W===void 0?e:W;if(!Number.isInteger(H)||H<1||H>__)throw Error("Session catalog limit must be an integer from 1 to 100");return{cwd:E===void 0?null:U.resolve(E),cursor:R??void 0,limit:H,includeSubagents:$,archived:M}}function N_(_={}){let E=c(_.taskStatus,E_,"task status"),R=c(_.taskPriority,R_,"task priority"),W=S(_.taskDueAfter,"taskDueAfter"),$=S(_.taskDueBefore,"taskDueBefore");return X_(W,$),{...E?{taskStatuses:E}:{},...R?{taskPriorities:R}:{},...W?{taskDueAfter:W}:{},...$?{taskDueBefore:$}:{}}}function c(_,E,R){if(_===void 0)return;let W=Array.isArray(_)?_:[_];if(W.length===0)return;let $=new Set;for(let M of W){if(typeof M!=="string"||!E.has(M))throw Error(`Invalid session ${R} filter`);$.add(M)}return[...$].sort()}function S(_,E){if(_===void 0)return;if(typeof _!=="string"||!Number.isFinite(Date.parse(_)))throw Error(`Invalid session ${E} filter`);return new Date(_).toISOString()}function X_(_,E){if(_!==void 0&&E!==void 0&&_>E)throw Error("Session task due range is inverted")}function Y_(_,E){if(_.lastMessageTime>E.lastMessageTime)return-1;if(_.lastMessageTime<E.lastMessageTime)return 1;if(_.projectPath<E.projectPath)return-1;if(_.projectPath>E.projectPath)return 1;if(_.sessionId<E.sessionId)return-1;if(_.sessionId>E.sessionId)return 1;return 0}function f_(_,E){let R=[..._],W=V_(E);if(W)R=R.filter((H)=>Y_(H,{sessionId:W.sessionId,projectPath:W.projectPath,lastMessageTime:W.lastMessageTime})>0);let $=R.slice(0,E.limit);if($.length===0||R.length<=$.length)return{sessions:$};let M=$[$.length-1];return{sessions:$,nextCursor:M_({version:1,cwd:E.cwd,includeSubagents:E.includeSubagents,archived:E.archived,lastMessageTime:M.lastMessageTime,projectPath:M.projectPath,sessionId:M.sessionId})}}function G_(_){return _.type==="message_created"||_.type==="token_budget_handoff_recorded"||_.type==="part_created"||_.type==="part_updated"||_.type==="turn_started"||_.type==="turn_completed"||_.type==="turn_aborted"||_.type==="turn_recovery_acknowledged"||_.type==="interaction_requested"||_.type==="interaction_responded"||_.type==="interaction_recovered"||_.type==="review_started"||_.type==="review_completed"}function O(_){return _.type==="message_created"&&_.data.role==="user"&&(_.data.inboxMessageId!==void 0||_.data.parentMessageId===void 0)}function N(_,E){let R=_.find((W)=>O(W)&&W.data.messageId===E);if(!R)throw Error(`Rewind checkpoint not found: ${E}`);return{messageId:E,preview:m(_,E),createdAt:R.data.createdAt}}function m(_,E){let R=_.flatMap((W)=>{if(W.type!=="part_created"||W.data.messageId!==E)return[];if(W.data.partType==="text"){let $=W.data.payload;return typeof $.text==="string"?[$.text]:[]}if(W.data.partType==="image")return["[Image]"];return[]}).join("").trim();if(R.length<=160)return R;return`${R.slice(0,160)}...`}function h(_,E){N(_,E);let R=_.findIndex((H)=>H.type==="message_created"&&H.data.messageId===E),W=_[R],$=W?.type==="message_created"?W.data.inboxMessageId:void 0,M=new Set(_.flatMap((H)=>H.type==="turn_started"&&$&&H.data.inputMessageIds?.includes($)?[H.data.turnId]:[]));return _.filter((H,Q)=>{if((H.type==="turn_started"||H.type==="turn_completed"||H.type==="turn_aborted"||H.type==="turn_recovery_acknowledged")&&M.has(H.data.turnId))return!1;return Q<R||!G_(H)})}function w(_){let E=[];for(let R of _){if(R.type!=="session_rewound"){E.push(R);continue}if(N(E,R.data.targetMessageId),R.data.mode!=="code")E=h(E,R.data.targetMessageId)}return E}function j_(_){let E=w(_);return E.filter(O).map((R)=>({messageId:R.data.messageId,preview:m(E,R.data.messageId),createdAt:R.data.createdAt})).reverse()}function u_(_,E){let R=w(_),W=N(R,E),$=R.findIndex((H)=>H.type==="message_created"&&H.data.messageId===E),M=R.slice($);return{checkpoint:W,projectedEntries:h(R,E),removedTurns:M.filter(O).length,snapshotMessageIds:M.flatMap((H)=>H.type==="part_created"&&H.data.partType==="tool_call"?[H.data.partId]:[])}}import*as z from"node:fs";import{createReadStream as g_}from"node:fs";import*as X from"node:fs/promises";import*as f from"node:path";import{createInterface as T_}from"node:readline";var b=65536;function D(_){let E=_.data;if(E===null||typeof E!=="object"||Array.isArray(E))throw Error("Session event data must be a JSON object");return JSON.stringify(_)}function Z_(_,E,R){let W=_.trim();if(!W)return;try{return JSON.parse(W)}catch($){throw Error(`Invalid session JSONL in ${R} at line ${E}`,{cause:$})}}function y(_,E="session transcript"){let R=_.split(`
|
|
2
2
|
`),W=!_.endsWith(`
|
|
3
|
-
`),$=[];for(let[H
|
|
3
|
+
`),$=[];for(let[M,H]of R.entries())try{let Q=Z_(H,M+1,E);if(Q){if(typeof Q.seq!=="number")Q.seq=$.length+1;$.push(Q)}}catch(Q){if(W&&M===R.length-1)break;throw Q}return $}class G{static appendQueues=new Map;filePath;constructor(_){this.filePath=_}static maxSeq(_){let E=0;for(let R of _)if(typeof R.seq==="number"&&R.seq>E)E=R.seq;return E}static stampSeqFrom(_,E){let R=E;return _.map((W)=>{if(typeof W.seq==="number"){if(W.seq>R)R=W.seq;return W}return R+=1,{...W,seq:R}})}static stampSeq(_,E){return G.stampSeqFrom(_,G.maxSeq(E))}async append(_){try{let[E]=await this.appendEntries([_]);return E}catch(E){throw console.error(`[JSONLStore] 追加写入失败: ${this.filePath}`,E),E}}async appendBatch(_){try{return await this.appendEntries(_)}catch(E){throw console.error(`[JSONLStore] 批量追加写入失败: ${this.filePath}`,E),E}}async appendEntries(_){if(_.length===0)return[];return this.enqueue(async()=>{await X.mkdir(f.dirname(this.filePath),{recursive:!0,mode:493});let E=await X.open(this.filePath,"a+",384);try{let R=await this.repairIncompleteTail(E),W=await this.readTailSeq(E),$=G.stampSeqFrom(_,W),M=`${$.map(D).join(`
|
|
4
4
|
`)}
|
|
5
|
-
`;return await E.appendFile(R+
|
|
5
|
+
`;return await E.appendFile(R+M,"utf8"),await E.sync(),$}finally{await E.close()}})}async createExclusive(_){if(_.length===0)throw Error("Cannot create an empty session transcript");await X.mkdir(f.dirname(this.filePath),{recursive:!0,mode:493});let E;try{E=await X.open(this.filePath,"wx",384);let W=`${G.stampSeq(_,[]).map(D).join(`
|
|
6
6
|
`)}
|
|
7
|
-
`;await E.writeFile(W,"utf-8"),await E.sync()}catch(R){if(E)await E.close(),E=void 0,await X.unlink(this.filePath).catch(()=>{return});throw R}finally{await E?.close()}}async readAll(){if(!
|
|
8
|
-
`).filter((W)=>W.trim().length>0).length;return{exists:!0,size:_.size,lineCount:R}}catch(_){return console.error(`[JSONLStore] 获取统计信息失败: ${this.filePath}`,_),{exists:!1,size:0,lineCount:0}}}async exists(){try{return await X.access(this.filePath),!0}catch{return!1}}async delete(){try{return await this.enqueue(async()=>{try{return await X.unlink(this.filePath),!0}catch(_){if(_.code==="ENOENT")return!1;throw _}})}catch(_){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,_),_}}async deleteValidated(_){return this.enqueue(async()=>{let E;try{E=await X.open(this.filePath,"r")}catch(W){if(W.code==="ENOENT")return!1;throw W}let R;try{R=
|
|
7
|
+
`;await E.writeFile(W,"utf-8"),await E.sync()}catch(R){if(E)await E.close(),E=void 0,await X.unlink(this.filePath).catch(()=>{return});throw R}finally{await E?.close()}}async readAll(){if(!z.existsSync(this.filePath))return[];let _=await X.readFile(this.filePath,"utf-8");return y(_,this.filePath)}async readStream(_){return new Promise((E,R)=>{if(!z.existsSync(this.filePath)){E();return}let W=g_(this.filePath,"utf-8"),$=T_({input:W,crlfDelay:Number.POSITIVE_INFINITY}),M=0;$.on("line",async(H)=>{let Q=H.trim();if(Q.length===0)return;try{let Y=JSON.parse(Q);if(M+=1,typeof Y.seq!=="number")Y.seq=M;await _(Y)}catch(Y){console.warn(`[JSONLStore] 解析 JSON 行失败: ${Q}`,Y)}}),$.on("close",()=>E()),$.on("error",R),W.on("error",R)})}async filter(_){let E=[];return await this.readStream((R)=>{if(_(R))E.push(R)}),E}async readLast(_){return(await this.readAll()).slice(-_)}async readFromSeq(_){return(await this.readAll()).filter((R)=>(R.seq??0)>=_)}async getStats(){try{if(!z.existsSync(this.filePath))return{exists:!1,size:0,lineCount:0};let _=await X.stat(this.filePath),R=(await X.readFile(this.filePath,"utf-8")).split(`
|
|
8
|
+
`).filter((W)=>W.trim().length>0).length;return{exists:!0,size:_.size,lineCount:R}}catch(_){return console.error(`[JSONLStore] 获取统计信息失败: ${this.filePath}`,_),{exists:!1,size:0,lineCount:0}}}async exists(){try{return await X.access(this.filePath),!0}catch{return!1}}async delete(){try{return await this.enqueue(async()=>{try{return await X.unlink(this.filePath),!0}catch(_){if(_.code==="ENOENT")return!1;throw _}})}catch(_){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,_),_}}async deleteValidated(_){return this.enqueue(async()=>{let E;try{E=await X.open(this.filePath,"r")}catch(W){if(W.code==="ENOENT")return!1;throw W}let R;try{R=y(await E.readFile("utf8"),"session transcript")}finally{await E.close()}if(!_(R))return!1;try{return await X.unlink(this.filePath),!0}catch(W){if(W.code==="ENOENT")return!1;throw W}})}async appendValidated(_){return this.appendValidatedAsync(async(E)=>_(E))}async appendValidatedBatch(_){return this.appendValidatedBatchAsync(async(E)=>_(E))}async appendValidatedBatchAsync(_){return this.enqueue(async()=>{let E=await X.open(this.filePath,"r+");try{let{entries:R,separator:W,size:$}=await this.readCommittedState(E,"session transcript"),M=await _(R);if(M.length===0)return[];let H=G.stampSeq(M,R),Q=`${H.map(D).join(`
|
|
9
9
|
`)}
|
|
10
|
-
`;return await E.write(W+Q,$,"utf8"),await E.sync(),
|
|
11
|
-
`;return await E.write(Q,$,"utf8"),await E.sync(),
|
|
12
|
-
`);for(let
|
|
13
|
-
`}catch{return await _.truncate(W),""}}async findTailStart(_,E){let R=E;while(R>0){let W=Math.max(0,R-b),$=Buffer.allocUnsafe(R-W);await _.read($,0,$.length,W);let
|
|
14
|
-
`);async function l(_){try{let E;if(K_()){let{Database:W}=await import("bun:sqlite");E=F_(new W(_))}else{let $=(await import("better-sqlite3")).default;E=U_(new $(_))}return E.exec(C_),E}catch{return null}}function
|
|
10
|
+
`;return await E.write(W+Q,$,"utf8"),await E.sync(),H}finally{await E.close()}})}async appendValidatedAsync(_){return this.enqueue(async()=>{let E=await X.open(this.filePath,"r+");try{let{entries:R,separator:W,size:$}=await this.readCommittedState(E,"session transcript"),M=await _(R),[H]=G.stampSeq([M],R),Q=`${W}${D(H)}
|
|
11
|
+
`;return await E.write(Q,$,"utf8"),await E.sync(),H}finally{await E.close()}})}getFilePath(){return this.filePath}async enqueue(_){let R=(G.appendQueues.get(this.filePath)??Promise.resolve()).catch(()=>{return}).then(_),W=R.then(()=>{return},()=>{return});G.appendQueues.set(this.filePath,W);try{return await R}finally{if(G.appendQueues.get(this.filePath)===W)G.appendQueues.delete(this.filePath)}}async readCommittedState(_,E=this.filePath){let R=await this.repairIncompleteTail(_),W=await _.readFile("utf8"),$=y(W,E),{size:M}=await _.stat();return{entries:$,separator:R,size:M}}async readTailSeq(_){let{size:E}=await _.stat();if(E===0)return 0;let R=Math.max(0,E-b),W=Buffer.allocUnsafe(E-R);await _.read(W,0,W.length,R);let $=W.toString("utf8").split(`
|
|
12
|
+
`);for(let H=$.length-1;H>=0;H--){let Q=$[H].trim();if(!Q)continue;if(H===0&&R>0)break;try{let Y=JSON.parse(Q).seq;if(typeof Y==="number")return Y}catch{}break}let M=await _.readFile("utf8");return G.maxSeq(y(M,this.filePath))}async repairIncompleteTail(_){let{size:E}=await _.stat();if(E===0)return"";let R=Buffer.allocUnsafe(1);if(await _.read(R,0,1,E-1),R[0]===10)return"";let W=await this.findTailStart(_,E),$=Buffer.allocUnsafe(E-W);await _.read($,0,$.length,W);try{return JSON.parse($.toString("utf8").trim()),`
|
|
13
|
+
`}catch{return await _.truncate(W),""}}async findTailStart(_,E){let R=E;while(R>0){let W=Math.max(0,R-b),$=Buffer.allocUnsafe(R-W);await _.read($,0,$.length,W);let M=$.lastIndexOf(10);if(M>=0)return W+M+1;R=W}return 0}}function K_(){return typeof globalThis.Bun<"u"}function U_(_){return{exec:(E)=>_.exec(E),prepare:(E)=>{let R=_.prepare(E);return{run:(...W)=>{R.run(...W)},get:(...W)=>R.get(...W),all:(...W)=>R.all(...W)}},transaction:(E)=>_.transaction(E)(),pragma:(E)=>_.pragma(E,{simple:!0}),close:()=>_.close()}}function F_(_){return{exec:(E)=>_.exec(E),prepare:(E)=>{let R=_.query(E);return{run:(...W)=>{R.run(...W)},get:(...W)=>R.get(...W),all:(...W)=>R.all(...W)}},transaction:(E)=>_.transaction(E)(),pragma:(E)=>{let R=_.query(`PRAGMA ${E}`).get();if(!R)return;let W=Object.values(R);return W.length===1?W[0]:R},close:()=>_.close()}}var C_=["PRAGMA journal_mode=WAL;","PRAGMA busy_timeout=5000;","PRAGMA synchronous=NORMAL;","PRAGMA foreign_keys=ON;"].join(`
|
|
14
|
+
`);async function l(_){try{let E;if(K_()){let{Database:W}=await import("bun:sqlite");E=F_(new W(_))}else{let $=(await import("better-sqlite3")).default;E=U_(new $(_))}return E.exec(C_),E}catch{return null}}function o(_){let E=Number(_.pragma("user_version")??0);if(E===5)return;if(E>0&&E!==5)_.exec(`
|
|
15
15
|
DROP TABLE IF EXISTS parts_fts;
|
|
16
16
|
DROP TABLE IF EXISTS parts;
|
|
17
17
|
DROP TABLE IF EXISTS sessions;
|
|
@@ -104,10 +104,10 @@ CREATE VIRTUAL TABLE IF NOT EXISTS parts_fts USING fts5(
|
|
|
104
104
|
seq UNINDEXED,
|
|
105
105
|
tokenize = 'unicode61'
|
|
106
106
|
);
|
|
107
|
-
`),_.exec("PRAGMA user_version=5;")}var
|
|
107
|
+
`),_.exec("PRAGMA user_version=5;")}var k_=r("Service"),k;function s(){return B.join(u(),"index.db")}async function B_(){let _=s();if(k&&k.path===_)return k.db;let E=(async()=>{let R=await l(_);if(!R)return null;try{return o(R),R}catch{return null}})();return k={path:_,db:E},E}function A_(){k=void 0}function x_(_){if(_&&typeof _==="object"){let E=_.text;if(typeof E==="string")return E}return null}function w_(_,E,R,W){_.prepare("DELETE FROM parts WHERE project_path=? AND session_id=?").run(E,R),_.prepare("DELETE FROM parts_fts WHERE project_path=? AND session_id=?").run(E,R);let $=new Map;for(let Q of W)if(Q.type==="message_created")$.set(Q.data.messageId,Q.data.role);let M=_.prepare(`INSERT OR REPLACE INTO parts
|
|
108
108
|
(project_path, session_id, part_id, message_id, part_type, role, seq, timestamp, text)
|
|
109
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`),
|
|
110
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`);for(let Q of W){if(Q.type!=="part_created"&&Q.type!=="part_updated")continue;if(Q.data.partType!=="text")continue;let Y=x_(Q.data.payload);if(Y===null)continue;let
|
|
109
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`),H=_.prepare(`INSERT INTO parts_fts (text, project_path, session_id, part_id, role, timestamp, seq)
|
|
110
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`);for(let Q of W){if(Q.type!=="part_created"&&Q.type!=="part_updated")continue;if(Q.data.partType!=="text")continue;let Y=x_(Q.data.payload);if(Y===null)continue;let g=$.get(Q.data.messageId)??"assistant",F=Q.seq??0;if(M.run(E,R,Q.data.partId,Q.data.messageId,Q.data.partType,g,F,Q.timestamp,Y),g==="user"||g==="assistant")H.run(Y,E,R,Q.data.partId,g,Q.timestamp,F)}}function D_(_,E){_.prepare(`INSERT INTO sessions
|
|
111
111
|
(project_path, session_id, root_id, parent_id, relation_type, title,
|
|
112
112
|
agent_type, model, task_status, task_priority, task_kind, task_due_at,
|
|
113
113
|
archived_at, last_message_time, project_sort_key,
|
|
@@ -126,15 +126,15 @@ CREATE VIRTUAL TABLE IF NOT EXISTS parts_fts USING fts5(
|
|
|
126
126
|
session_sort_key=excluded.session_sort_key,
|
|
127
127
|
first_message_time=excluded.first_message_time, message_count=excluded.message_count,
|
|
128
128
|
has_errors=excluded.has_errors, is_subagent=excluded.is_subagent,
|
|
129
|
-
metadata_json=excluded.metadata_json`).run(E.projectPath,E.sessionId,E.rootId,E.parentId??null,E.relationType??null,E.title??null,E.agentType??null,E.model??null,E.taskStatus,E.taskPriority??null,E.taskKind??null,E.taskDueAt??null,E.archivedAt??null,E.lastMessageTime,J(E.projectPath),J(E.sessionId),E.firstMessageTime,E.messageCount,E.hasErrors?1:0,E.relationType==="subagent"?1:0,JSON.stringify(E))}function t(_,E,R){for(let W of["sessions","parts","parts_fts"])_.prepare(`DELETE FROM ${W} WHERE project_path=? AND session_id=?`).run(E,R)}function p(_,E,R){t(_,E,R),_.prepare("DELETE FROM projection_state WHERE project_path=? AND session_id=?").run(E,R)}function L(_,E,R,W,$,
|
|
129
|
+
metadata_json=excluded.metadata_json`).run(E.projectPath,E.sessionId,E.rootId,E.parentId??null,E.relationType??null,E.title??null,E.agentType??null,E.model??null,E.taskStatus,E.taskPriority??null,E.taskKind??null,E.taskDueAt??null,E.archivedAt??null,E.lastMessageTime,J(E.projectPath),J(E.sessionId),E.firstMessageTime,E.messageCount,E.hasErrors?1:0,E.relationType==="subagent"?1:0,JSON.stringify(E))}function t(_,E,R){for(let W of["sessions","parts","parts_fts"])_.prepare(`DELETE FROM ${W} WHERE project_path=? AND session_id=?`).run(E,R)}function p(_,E,R){t(_,E,R),_.prepare("DELETE FROM projection_state WHERE project_path=? AND session_id=?").run(E,R)}function L(_,E,R,W,$,M){_.prepare(`INSERT INTO projection_state
|
|
130
130
|
(project_path, session_id, last_seq, file_size, mtime_ms)
|
|
131
131
|
VALUES (?, ?, ?, ?, ?)
|
|
132
132
|
ON CONFLICT(project_path, session_id) DO UPDATE SET
|
|
133
133
|
last_seq=excluded.last_seq, file_size=excluded.file_size,
|
|
134
|
-
mtime_ms=excluded.mtime_ms`).run(E,R,W,$,
|
|
135
|
-
FROM projection_state`).all(),Y=new Map(Q.map((V)=>[`${V.project_path}\x00${V.session_id}`,V])),
|
|
134
|
+
mtime_ms=excluded.mtime_ms`).run(E,R,W,$,M)}async function y_(_,E,R,W,$=j(R,E)){let M;try{let V=await a($);M={size:V.size,mtimeMs:V.mtimeMs}}catch{return _.transaction(()=>p(_,R,E)),!0}let H=_.prepare("SELECT last_seq, file_size, mtime_ms FROM projection_state WHERE project_path=? AND session_id=?").get(R,E);if(H&&H.file_size===M.size&&H.mtime_ms===Math.floor(M.mtimeMs))return!1;let Y=await new G($).readAll(),g=Y.reduce((V,Z)=>typeof Z.seq==="number"&&Z.seq>V?Z.seq:V,0),F=w(Y),T=W(Y,E,R);if(Y.length===0||!T)return _.transaction(()=>{t(_,R,E),L(_,R,E,g,M.size,Math.floor(M.mtimeMs))}),!0;let C=_.prepare("SELECT last_message_time FROM sessions WHERE project_path=? AND session_id=?").get(T.projectPath,T.sessionId),A=B.resolve($)===B.resolve(j(T.projectPath,T.sessionId));if(C&&!A&&typeof C.last_message_time==="string"&&C.last_message_time>T.lastMessageTime)return L(_,R,E,g,M.size,Math.floor(M.mtimeMs)),!0;return _.transaction(()=>{D_(_,T),w_(_,T.projectPath,T.sessionId,F),L(_,R,E,g,M.size,Math.floor(M.mtimeMs))}),!0}var n=new WeakMap;async function z_(_,E,R=0){let W=n.get(_)??{};if(n.set(_,W),W.inFlight)return W.inFlight;if(R>0&&W.lastCompletedAt!==void 0&&Date.now()-W.lastCompletedAt<=R)return;let $=I_(_,E);W.inFlight=$;try{await $,W.lastCompletedAt=Date.now()}finally{if(W.inFlight===$)W.inFlight=void 0}}async function I_(_,E){let{readdir:R}=await import("node:fs/promises"),W=await i(),$=new Set,H=(await Promise.all(W.map(async(V)=>{let Z=d(V),K=B.join(u(),"projects",V);try{return(await R(K)).flatMap((q)=>{if(!q.endsWith(".jsonl"))return[];let P=q.slice(0,-6);if(!x(P))return[];return[{filePath:B.join(K,q),projectPath:Z,sessionId:P}]})}catch{return[]}}))).flat();for(let V of H)$.add(`${V.projectPath}\x00${V.sessionId}`);let Q=_.prepare(`SELECT project_path, session_id, last_seq, file_size, mtime_ms
|
|
135
|
+
FROM projection_state`).all(),Y=new Map(Q.map((V)=>[`${V.project_path}\x00${V.session_id}`,V])),g=[],F=Math.min(128,H.length),T=0;await Promise.all(Array.from({length:F},async()=>{while(T<H.length){let V=H[T++];if(!V)continue;try{let Z=await a(V.filePath),K=Y.get(`${V.projectPath}\x00${V.sessionId}`);if(K&&K.file_size===Z.size&&K.mtime_ms===Math.floor(Z.mtimeMs))continue}catch{}g.push(V)}}));let C=Math.min(32,g.length),A=0;await Promise.all(Array.from({length:C},async()=>{while(A<g.length){let V=g[A++];if(!V)continue;try{await y_(_,V.sessionId,V.projectPath,E,V.filePath)}catch(Z){if(Z.code!=="ENOENT")k_.warn(`[SessionService] Skipping invalid session transcript: ${V.sessionId}`)}}}));for(let V of Q)if(!$.has(`${V.project_path}\x00${V.session_id}`))_.transaction(()=>p(_,V.project_path,V.session_id))}function t_(_,E,R){_.transaction(()=>p(_,R,E))}async function e_(_){let{rm:E}=await import("node:fs/promises");A_();let R=s();for(let M of["","-wal","-shm"])await E(`${R}${M}`,{force:!0}).catch(()=>{return});let W=await B_();if(!W)return null;return await z_(W,_),W.prepare("SELECT COUNT(*) c FROM sessions").get()?.c??0}function _E(_,E,R,W){let $=E.replace(/["*]/g," ").trim().split(/\s+/)[0];if(!$)return[];let M=`"${$}"*`,H=R?`SELECT session_id, role, timestamp, text FROM parts_fts
|
|
136
136
|
WHERE parts_fts MATCH ? AND project_path = ?
|
|
137
137
|
ORDER BY timestamp DESC LIMIT ?`:`SELECT session_id, role, timestamp, text FROM parts_fts
|
|
138
138
|
WHERE parts_fts MATCH ?
|
|
139
|
-
ORDER BY timestamp DESC LIMIT ?`,Q=_.prepare(
|
|
140
|
-
export{
|
|
139
|
+
ORDER BY timestamp DESC LIMIT ?`,Q=_.prepare(H);return R?Q.all(M,R,W):Q.all(M,W)}
|
|
140
|
+
export{w as Xd,j_ as Yd,u_ as Zd,y as _d,G as $d,J as ae,V_ as be,O_ as ce,N_ as de,Y_ as ee,f_ as fe,s as ge,B_ as he,A_ as ie,y_ as je,z_ as ke,t_ as le,e_ as me,_E as ne};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Kd as a,Ld as b,Md as c,Nd as d,Od as e,Pd as f,Qd as g}from"./chunk-
|
|
1
|
+
import{Kd as a,Ld as b,Md as c,Nd as d,Od as e,Pd as f,Qd as g}from"./chunk-6yezrqe7.js";import"./chunk-s0tq8gyx.js";import"./chunk-hpjnk87v.js";import"./chunk-2hb222re.js";import"./chunk-qcy79mva.js";import"./chunk-c6tq09mt.js";import"./chunk-maebpz1j.js";import"./chunk-9sx3vsyj.js";import"./chunk-d8wzc602.js";import"./chunk-k7vv9vne.js";import"./chunk-qw57eqns.js";import"./chunk-q3vza5gt.js";import"./chunk-w9xfks7f.js";export{b as __setSessionSnapshotIOForTesting,c as __resetSessionSnapshotIOForTesting,g as SessionService,d as SessionMissingCreationError,e as SessionArchivedError,f as SessionArchiveConflictError,a as STALE_EMPTY_SESSION_AGE_MS};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Xf as b1,Yf as L0,Zf as z1,cg as N0}from"./chunk-
|
|
1
|
+
import{Xf as b1,Yf as L0,Zf as z1,cg as N0}from"./chunk-00rps629.js";import{hg as jO,ig as wO}from"./chunk-qcy79mva.js";import{lg as A1}from"./chunk-p0rvgzpx.js";import{mg as b0,og as J0}from"./chunk-6kb69vkx.js";import{qh as S0,rh as GO,vh as I0}from"./chunk-19xfer55.js";import{Bh as L,Eh as c1,zh as u}from"./chunk-czcxx8tb.js";import{Nh as M}from"./chunk-9sx3vsyj.js";import{ni as k,oi as S}from"./chunk-d8wzc602.js";import{Bi as u0}from"./chunk-qw57eqns.js";import{Ii as N}from"./chunk-cp7xsjj2.js";import H1 from"node:path";import LO from"node:path";import v0 from"node:fs";import W0 from"node:os";import E from"node:path";import dO from"yaml";var U1=2000,V1=50,j1=1000,Y4={type:"object",properties:{verdict:{type:"string",enum:["pass","fail","partial"]},summary:{type:"string",minLength:1,maxLength:U1},findings:{type:"array",maxItems:V1,items:{type:"string",minLength:1,maxLength:j1}}},required:["verdict","summary","findings"],additionalProperties:!1};function F1(O,$){let Q=O.trim().replaceAll(/\s+/g," ");if($)Q=Q.replaceAll($,".");return Q.replace(/\bBearer\s+[^\s"'`]+/gi,"Bearer [redacted]").replace(/\bsk-[A-Za-z0-9_-]{8,}\b/g,"[redacted-key]").replace(/\b(api(?:[_-]?|\s+)key|access(?:[_-]?|\s+)token|authorization|cookie|password|passwd|refresh(?:[_-]?|\s+)token|secret|session(?:[_-]?|\s+)token)\b(\s*[:=]\s*)([^\s,;]+)/gi,"$1$2[redacted]")}function hO(O){if(O.length<=N0)return O;let $=" [verification feedback truncated]",Q=O.slice(0,N0-$.length);if(/[\uD800-\uDBFF]$/.test(Q))Q=Q.slice(0,-1);return Q.trimEnd()+$}function B1(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let $=O;if($.verdict!=="pass"&&$.verdict!=="fail"&&$.verdict!=="partial"||typeof $.summary!=="string"||!$.summary.trim()||$.summary.length>U1||!Array.isArray($.findings)||$.findings.length>V1||!$.findings.every((Q)=>typeof Q==="string"&&Q.trim().length>0&&Q.length<=j1))return;return{verdict:$.verdict,summary:$.summary.trim(),findings:$.findings.map((Q)=>Q.trim())}}function X4(O,$){let Q=B1(O);if(!Q)return;let Z=F1(Q.summary,$),J=Q.findings.map((K)=>F1(K,$));return hO([Z,J.length>0?`Findings:
|
|
2
2
|
${J.map((K)=>`- ${K}`).join(`
|
|
3
3
|
`)}`:""].filter(Boolean).join(`
|
|
4
4
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Ka as V,Ma as W,Na as O,db as J}from"./chunk-
|
|
1
|
+
import{Ka as V,Ma as W,Na as O,db as J}from"./chunk-yx4802a0.js";import"./chunk-czcxx8tb.js";import"./chunk-maebpz1j.js";import{Nh as Q}from"./chunk-9sx3vsyj.js";import"./chunk-d8wzc602.js";import"./chunk-q3vza5gt.js";import"./chunk-w9xfks7f.js";import F from"chalk";var K=(f)=>typeof f==="string"&&f.length>0?f:void 0;function X(f){let z=K(f.cron),G=K(f.every),H=K(f.at);if([z,G,H].filter(Boolean).length!==1)throw Error("Provide exactly one of --cron, --every, or --at");if(z)return{kind:"cron",cron:z};if(G){let P=V(G);if(!P)throw Error(`Invalid --every value "${G}" (use e.g. 30m, 2h, 1d)`);return{kind:"interval",intervalMs:P}}let N=new Date(H);if(Number.isNaN(N.getTime()))throw Error(`Invalid --at value "${H}" (use an ISO timestamp)`);return{kind:"once",runAt:N.toISOString()}}var Y={command:"create <prompt>",describe:"创建定时任务",builder:(f)=>f.positional("prompt",{type:"string",describe:"定时任务运行时发送给 Agent 的提示词",demandOption:!0}).option("cron",{type:"string",describe:"5 段 cron 表达式(本地时区)"}).option("every",{type:"string",describe:"间隔(如 30m、2h、1d)"}).option("at",{type:"string",describe:"一次性运行的 ISO 时间点"}).option("project-path",{alias:["projectPath","project"],type:"string",describe:"目标项目路径(默认当前目录)"}).option("title",{type:"string",describe:"定时任务标题"}).option("model",{alias:"m",type:"string",describe:"模型 ID"}).option("permission-mode",{type:"string",choices:["default","autoEdit","yolo","plan"],default:"default",describe:"权限模式"}).option("isolation",{type:"string",choices:["local","worktree"],default:"worktree",describe:"执行隔离方式"}).example([['$0 schedule create "跑测试并汇报失败" --every 1h',"每小时运行一次"],['$0 schedule create "生成每日站会摘要" --cron "0 9 * * 1-5"',"工作日 9 点运行"]]),handler:async(f)=>{try{let z=X(f),G=W(z);if(G)throw Error(G);let H={prompt:f.prompt,projectPath:K(f.projectPath)??Q(),title:K(f.title),trigger:z,modelId:K(f.model),isolation:K(f.isolation)??"worktree",permissionMode:K(f.permissionMode)??"default",enabled:!0},B=await J.create(H);console.log(F.green(`✓ 已创建定时任务 ${B.id}`)),console.log(` ${O(B.trigger)}`),console.log(` 项目: ${B.projectPath}`),console.log(` 下次运行: ${B.nextRunAt?new Date(B.nextRunAt).toLocaleString():"(无)"}`),process.exit(0)}catch(z){console.error(F.red(`创建定时任务失败: ${z instanceof Error?z.message:z}`)),process.exit(1)}}},Z={command:"list",aliases:["ls"],describe:"列出所有定时任务",handler:async()=>{let f=await J.list();if(f.length===0)console.log(F.dim("尚无定时任务。使用 `blade schedule create` 创建。")),process.exit(0);for(let z of f){let G=z.enabled?F.green("启用"):F.dim("停用"),H=z.nextRunAt?new Date(z.nextRunAt).toLocaleString():"—",B=z.lastRunAt?`${new Date(z.lastRunAt).toLocaleString()} (${z.lastStatus??"?"})`:"从未";console.log(`${F.cyan(z.id)} [${G}] ${z.title??z.prompt.slice(0,40)}`),console.log(` ${O(z.trigger)} · 下次: ${H} · 上次: ${B} · 运行 ${z.runCount} 次`),console.log(F.dim(` 项目: ${z.projectPath}`))}process.exit(0)}},_={command:"show <id>",describe:"查看定时任务详情",builder:(f)=>f.positional("id",{type:"string",describe:"定时任务 ID",demandOption:!0}),handler:async(f)=>{let z=await J.get(f.id);if(!z)console.error(F.red(`未找到定时任务 ${f.id}`)),process.exit(1);console.log(JSON.stringify(z,null,2)),process.exit(0)}},$={command:"remove <id>",aliases:["rm"],describe:"删除定时任务",builder:(f)=>f.positional("id",{type:"string",describe:"定时任务 ID",demandOption:!0}),handler:async(f)=>{if(!await J.remove(f.id))console.error(F.red(`未找到定时任务 ${f.id}`)),process.exit(1);console.log(F.green(`✓ 已删除定时任务 ${f.id}`)),process.exit(0)}},q={command:"enable <id>",describe:"启用定时任务",builder:(f)=>f.positional("id",{type:"string",describe:"定时任务 ID",demandOption:!0}),handler:async(f)=>{if(!await J.setEnabled(f.id,!0))console.error(F.red(`未找到定时任务 ${f.id}`)),process.exit(1);console.log(F.green(`✓ 已启用定时任务 ${f.id}`)),process.exit(0)}},x={command:"disable <id>",describe:"停用定时任务",builder:(f)=>f.positional("id",{type:"string",describe:"定时任务 ID",demandOption:!0}),handler:async(f)=>{if(!await J.setEnabled(f.id,!1))console.error(F.red(`未找到定时任务 ${f.id}`)),process.exit(1);console.log(F.green(`✓ 已停用定时任务 ${f.id}`)),process.exit(0)}},D={command:"run <id>",describe:"立即运行定时任务(需要 blade serve)",builder:(f)=>f.positional("id",{type:"string",describe:"定时任务 ID",demandOption:!0}).option("server",{type:"string",default:process.env.BLADE_SERVER_URL??"http://127.0.0.1:4097",describe:"Blade server 地址"}),handler:async(f)=>{let z=f.id,G=(K(f.server)??"http://127.0.0.1:4097").replace(/\/$/,""),H={};if(process.env.BLADE_SERVER_PASSWORD){let B=process.env.BLADE_SERVER_USERNAME??"blade";H.Authorization=`Basic ${Buffer.from(`${B}:${process.env.BLADE_SERVER_PASSWORD}`).toString("base64")}`}try{let B=await fetch(`${G}/schedules/${encodeURIComponent(z)}/run`,{method:"POST",headers:H});if(!B.ok){let N=await B.json().catch(()=>{return});throw Error(N?.error?.message??`Schedule run failed (${B.status})`)}console.log(F.green(`✓ 已触发定时任务 ${z}`)),process.exit(0)}catch(B){console.error(F.red(`运行定时任务失败: ${B instanceof Error?B.message:B}`)),process.exit(1)}}},R={command:"schedule",describe:"管理定时任务",builder:(f)=>f.command(Y).command(Z).command(_).command($).command(q).command(x).command(D).demandCommand(1,"请提供子命令:create | list | show | remove | enable | disable | run"),handler:()=>{}};export{R as scheduleCommands};
|