blade-code 0.11.2 → 0.11.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-g0xtk1yy.js → chunk-1g7c3f82.js} +1 -1
- package/dist/chunk-1hknjamx.js +1 -0
- package/dist/{chunk-tx9tb485.js → chunk-3gbteqvh.js} +1 -1
- package/dist/{chunk-q6sr4979.js → chunk-3v9epq9s.js} +1 -1
- package/dist/{chunk-pjeks4cz.js → chunk-4077g2fm.js} +1 -1
- package/dist/{chunk-re8p2y22.js → chunk-49jbxty9.js} +1 -1
- package/dist/{chunk-xnys4bgs.js → chunk-5ce8ydjq.js} +1 -1
- package/dist/{chunk-ebvzp8tn.js → chunk-5kmxe14c.js} +1 -1
- package/dist/{chunk-s7x4x6xw.js → chunk-6m81sxfz.js} +1 -1
- package/dist/chunk-6p0hkf4f.js +1 -0
- package/dist/{chunk-yeandcre.js → chunk-77n1drhv.js} +1 -1
- package/dist/{chunk-vemyfx92.js → chunk-7m07qp5c.js} +1 -1
- package/dist/{chunk-6v23hdt8.js → chunk-870szc6v.js} +1 -1
- package/dist/{chunk-v0eanse2.js → chunk-8d8wsqam.js} +1 -1
- package/dist/{chunk-t3pkk95s.js → chunk-a1vvg4yf.js} +1 -1
- package/dist/{chunk-px45q235.js → chunk-asgmmaec.js} +2 -2
- package/dist/{chunk-n30najxq.js → chunk-b5cz00mt.js} +1 -1
- package/dist/{chunk-0kxya4ye.js → chunk-bw3920qg.js} +1 -1
- package/dist/chunk-c33wff11.js +2 -0
- package/dist/chunk-d7frbjn7.js +1 -0
- package/dist/{chunk-jbpasjg9.js → chunk-e0ft3vwg.js} +1 -1
- package/dist/{chunk-8q6zsznc.js → chunk-e4q0rcmz.js} +1 -1
- package/dist/chunk-eb10zapp.js +1 -0
- package/dist/{chunk-a95jmx2j.js → chunk-ed2hdrwe.js} +1 -1
- package/dist/{chunk-g2295k8s.js → chunk-eexs73bz.js} +1 -1
- package/dist/{chunk-k2rgg45h.js → chunk-egqep8py.js} +2 -2
- package/dist/chunk-g2kqz1mm.js +1 -0
- package/dist/{chunk-sdapqhj0.js → chunk-gmpsfkgg.js} +1 -1
- package/dist/chunk-gwf872nm.js +1 -0
- package/dist/{chunk-p36k2e96.js → chunk-hb680ebj.js} +1 -1
- package/dist/{chunk-7rz5dt79.js → chunk-hbkpavbp.js} +2 -2
- package/dist/chunk-hfbw50pk.js +357 -0
- package/dist/{chunk-enmn892r.js → chunk-hfwn38rm.js} +1 -1
- package/dist/{chunk-qhcd0ww0.js → chunk-js7fre4w.js} +1 -1
- package/dist/chunk-kj20ad32.js +1 -0
- package/dist/chunk-m61cx42n.js +1 -0
- package/dist/{chunk-g7pjgspy.js → chunk-myznexy5.js} +1 -1
- package/dist/chunk-n62b30d1.js +164 -0
- package/dist/{chunk-wnzr9h84.js → chunk-nad5spvc.js} +1 -1
- package/dist/{chunk-04qhtx2w.js → chunk-nfdtrn3t.js} +1 -1
- package/dist/{chunk-zf72e5w8.js → chunk-p4j7gxjk.js} +1 -1
- package/dist/{chunk-3ee357pw.js → chunk-phch3t6v.js} +78 -78
- package/dist/{chunk-kaj8jaj5.js → chunk-q534f3j5.js} +1 -1
- package/dist/{chunk-2fdghgmf.js → chunk-qzsmbk13.js} +2 -2
- package/dist/chunk-r8rvkas8.js +1 -0
- package/dist/{chunk-h4b4fn3t.js → chunk-r9egmztq.js} +1 -1
- package/dist/{chunk-xrgeakpy.js → chunk-rswfbvay.js} +1 -1
- package/dist/{chunk-qa86anwd.js → chunk-rwm2e0r4.js} +1 -1
- package/dist/{chunk-wan9q99y.js → chunk-s14zayxp.js} +1 -1
- package/dist/{chunk-4e4qtpca.js → chunk-saz6mwpq.js} +1 -1
- package/dist/{chunk-a3dz41pd.js → chunk-ty3gwnwq.js} +1 -1
- package/dist/{chunk-290p3r7a.js → chunk-v5t3kcac.js} +1 -1
- package/dist/{chunk-qyfbeg5h.js → chunk-vmhcc7f9.js} +1 -1
- package/dist/{chunk-er6zghgg.js → chunk-vsmnzhhz.js} +1 -1
- package/dist/{chunk-f9qrjd2f.js → chunk-vv6r417h.js} +1 -1
- package/dist/{chunk-zwe1a7xe.js → chunk-w8dxjbm8.js} +1 -1
- package/dist/{chunk-6x5f6she.js → chunk-whxkwaz1.js} +1 -1
- package/dist/{chunk-5s2x98rx.js → chunk-xhwdac1j.js} +1 -1
- package/dist/chunk-ydtsh19k.js +1 -0
- package/dist/{chunk-0wxnrjes.js → chunk-yjdyzb5z.js} +1 -1
- package/dist/web/assets/ChatView-CvuKp3Yl.js +17 -0
- package/dist/web/assets/{CodeBlockHighlighter-OvLyFs9U.js → CodeBlockHighlighter-CYiAdOLs.js} +1 -1
- package/dist/web/assets/FilePreview-DGolvoH6.js +8 -0
- package/dist/web/assets/KanbanBoard-DdwrLpvb.js +1 -0
- package/dist/web/assets/{MarkdownRenderer-BTxnqChi.js → MarkdownRenderer-fJny7W8J.js} +3 -3
- package/dist/web/assets/{ScrollArea-BdOqyQ3g.js → ScrollArea-CSCl8r35.js} +1 -1
- package/dist/web/assets/{SessionHistorySurface-DaKE2oKU.js → SessionHistorySurface-dttyHhtN.js} +1 -1
- package/dist/web/assets/SettingsModal-Bn9m-F-v.js +5 -0
- package/dist/web/assets/Sidebar-JYvLuHTi.js +1 -0
- package/dist/web/assets/{TaskSwitcher-DKelLFZm.js → TaskSwitcher-InE9ArQH.js} +1 -1
- package/dist/web/assets/{TerminalPanel-D5Rieq62.js → TerminalPanel-BLRAlQoa.js} +1 -1
- package/dist/web/assets/{archive-CsFSEMp9.js → archive-D3alcPOa.js} +1 -1
- package/dist/web/assets/{arrow-left-gaino9Tb.js → arrow-left-CNfcSdE2.js} +1 -1
- package/dist/web/assets/{calendar-clock-DfHUrEw9.js → calendar-clock-BoRTfsxW.js} +1 -1
- package/dist/web/assets/chevron-right-B8JH5N50.js +1 -0
- package/dist/web/assets/{clock-3-dWIDc9IF.js → clock-3-BGymk4sE.js} +1 -1
- package/dist/web/assets/{copy-BPfhyh47.js → copy-CLG3LQ2v.js} +1 -1
- package/dist/web/assets/{dist-RGayDvc-.js → dist-BtGkS2rG.js} +1 -1
- package/dist/web/assets/{download-BR2L5Wme.js → download-DxK6pukC.js} +1 -1
- package/dist/web/assets/{folder-8dmZJ2a6.js → folder-B0xRimYH.js} +1 -1
- package/dist/web/assets/index-BJdxoBtv.css +1 -0
- package/dist/web/assets/{index-DSa8Dzp7.js → index-DkwePtIh.js} +4 -4
- package/dist/web/assets/{pause-DLZIDFMB.js → pause-CKNq9DgJ.js} +1 -1
- package/dist/web/assets/{pencil-DkC0bPYD.js → pencil-CMjIwtk5.js} +1 -1
- package/dist/web/assets/{play-BVeNn6fv.js → play-BOz9Sqzf.js} +1 -1
- package/dist/web/assets/plus-BJIEQjD7.js +1 -0
- package/dist/web/assets/preload-helper-HI3NtP3B.js +1 -0
- package/dist/web/assets/{session-events-BuMTbIwu.js → session-events-B-hnDC4L.js} +3 -3
- package/dist/web/assets/{settings-msYyNDKx.js → settings-CP6ArjQ7.js} +1 -1
- package/dist/web/assets/team-BHlihaeV.js +1 -0
- package/dist/web/assets/{teamService-Bus5RDi1.js → teamService-DDfifLYm.js} +1 -1
- package/dist/web/assets/{terminal-Cp5WYo8w.js → terminal-BYHhWXe-.js} +1 -1
- package/dist/web/assets/tooltip-DJBQZhJD.js +1 -0
- package/dist/web/assets/triangle-alert-BCJaJaVj.js +1 -0
- package/dist/web/assets/{vendor-radix-L0yJCKJX.js → vendor-radix-BCAvgfOW.js} +1 -1
- package/dist/web/assets/{vendor-react-CHEIQMI-.js → vendor-react-DQwAdeyS.js} +1 -1
- package/dist/web/index.html +5 -5
- package/package.json +2 -2
- package/dist/chunk-21qsfewd.js +0 -1
- package/dist/chunk-3d4wgfkr.js +0 -1
- package/dist/chunk-634ymwg5.js +0 -1
- package/dist/chunk-65v1vjvg.js +0 -1
- package/dist/chunk-7p8r4q6f.js +0 -1
- package/dist/chunk-d4xsrx3z.js +0 -357
- package/dist/chunk-eg0s155w.js +0 -1
- package/dist/chunk-fb2x1026.js +0 -171
- package/dist/chunk-gff7a5q0.js +0 -1
- package/dist/chunk-gymecxcc.js +0 -1
- package/dist/chunk-p665f6pn.js +0 -1
- package/dist/chunk-sqsfztrv.js +0 -1
- package/dist/chunk-yjcp8jk1.js +0 -2
- package/dist/web/assets/ChatView-DysPZPwF.js +0 -17
- package/dist/web/assets/FilePreview-CkSPwPdW.js +0 -8
- package/dist/web/assets/KanbanBoard-DH1wApt6.js +0 -1
- package/dist/web/assets/SettingsModal-CWlSSO_E.js +0 -5
- package/dist/web/assets/Sidebar-Dirk-XAQ.js +0 -1
- package/dist/web/assets/chevron-right-Bvu2j6hB.js +0 -1
- package/dist/web/assets/index-B7RyuO2x.css +0 -1
- package/dist/web/assets/message-square-plus-BgC981WF.js +0 -1
- package/dist/web/assets/plus-kzdwas-3.js +0 -1
- package/dist/web/assets/preload-helper-DvgLbiBV.js +0 -1
- package/dist/web/assets/team-D3XOVbxL.js +0 -1
- package/dist/web/assets/triangle-alert-cGqHxFsZ.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Ae as O1,Be as n2,Ce as d2,De as J1,Ee as Q1,Fe as i2,Ge as Y1,He as V0,Ie as Z1,Je as G1,Le as r2,Se as o2,Te as Q0,_e as I_,af as V1,cf as a2,df as t2,ef as L1,ff as s2,ue as l2,ve as e,we as p2,xe as W1,ye as c2,ze as v}from"./chunk-
|
|
1
|
+
import{Ae as O1,Be as n2,Ce as d2,De as J1,Ee as Q1,Fe as i2,Ge as Y1,He as V0,Ie as Z1,Je as G1,Le as r2,Se as o2,Te as Q0,_e as I_,af as V1,cf as a2,df as t2,ef as L1,ff as s2,ue as l2,ve as e,we as p2,xe as W1,ye as c2,ze as v}from"./chunk-s14zayxp.js";import{xg as h_}from"./chunk-pm163dfm.js";import{sh as l_}from"./chunk-1cy4ab77.js";import{Zi as f1}from"./chunk-b22ab7yw.js";import{Aj as E_,wj as u2,xj as h2,yj as F_,zj as r_}from"./chunk-m2x6pb4f.js";import{Ej as $0}from"./chunk-saz6mwpq.js";import{Rj as P_,Uj as u_}from"./chunk-0eajnhrj.js";import{Xj as __}from"./chunk-c33wff11.js";import{Ak as P,Bk as m,Ck as E1,Dk as F1,Ek as N_,Fk as z1,Gk as k1,Hk as L_,dk as l,nk as r,ok as p,pk as m2,qk as c,rk as n,sk as v2,tk as Z0,uk as $1,vk as P2,wk as H_,xk as G0,yk as g_,zk as T}from"./chunk-ed2hdrwe.js";import{readdir as D_,readFile as Z_,rm as R_,stat as L0}from"node:fs/promises";import*as N from"node:path";import{nanoid as i}from"nanoid";import{createHash as G4,randomUUID as V4}from"node:crypto";import*as $_ from"node:fs/promises";import*as n_ from"node:path";import L4 from"proper-lockfile";function nX(_){return Object.freeze({kind:"local",root:_})}function dX(_,X){let $=r(X);if(p($.collisionIdentity)!==_)throw Error("ACP remote workspace durable state is invalid");return Object.freeze({kind:"acp-remote",root:_,descriptor:$})}function iX(_,X){return _.kind==="acp-remote"?`${_.kind}\x00${_.root}\x00${_.descriptor.exactIdentity}\x00${X}`:`${_.kind}\x00${_.root}\x00${X}`}async function G_(_,X){if(_.kind==="local")return X(H_(_.root));return c(_.root,($)=>X(String($),$))}async function rX(_,X,$){return G_(_,(W,J)=>$(J?{storageRoot:W,transcriptPath:m(J,X),inboxPath:F1(J,X),goalPath:z1(J,X),remoteScope:J}:{storageRoot:W,transcriptPath:P(_.root,X),inboxPath:E1(_.root,X),goalPath:N_(_.root,X)}))}import{execFileSync as W4}from"node:child_process";import{createHash as O4}from"node:crypto";import{readFileSync as J4}from"node:fs";var Q4=/^[a-f0-9]{64}$/;function D1(_){if(!_||typeof _!=="object")return!1;let X=_;return(X.platform==="linux"||X.platform==="darwin"||X.platform==="win32")&&typeof X.fingerprint==="string"&&Q4.test(X.fingerprint)}var R1={readFile:(_)=>J4(_,"utf8"),execFile:(_,X)=>W4(_,X,{encoding:"utf8",timeout:_==="powershell.exe"?3000:2000,windowsHide:!0})},Y4=(_)=>{try{return process.kill(_,0),!0}catch(X){return X instanceof Error&&"code"in X&&X.code==="EPERM"}};function F0(_,X){return{platform:_,fingerprint:O4("sha256").update(`${_}\x00${X}`).digest("hex")}}function Z4(_,X){let $=X.readFile(`/proc/${_}/stat`).trim(),W=$.lastIndexOf(")");if(W<0)throw Error("Invalid /proc process stat");let O=$.slice(W+2).split(/\s+/)[19];if(!O||!/^\d+$/.test(O))throw Error("Missing process start ticks");return O}function b_(_,X=process.platform,$=R1){if(!Number.isInteger(_)||_<=1)return;try{if(X==="linux")return F0(X,Z4(_,$));if(X==="darwin"){let W=$.execFile("ps",["-o","lstart=","-p",String(_)]).trim();return W?F0(X,W):void 0}if(X==="win32"){let W=`(Get-CimInstance Win32_Process -Filter "ProcessId = ${_}").CreationDate.ToUniversalTime().ToString('O')`,J=$.execFile("powershell.exe",["-NoProfile","-NonInteractive","-Command",W]).trim();return J?F0(X,J):void 0}}catch{return}return}function eX(_,X){return b_(_,X.platform)?.fingerprint===X.fingerprint}function _$(_,X,$=R1,W=Y4){if(!Number.isInteger(_)||_<=1)return!1;let J=b_(_,X.platform,$);if(J)return J.fingerprint===X.fingerprint;return!W(_)}var j1=1;function B4(_,X){let $=G4("sha256").update(X).digest("hex");return n_.join(H_(_),".locks",`${$}.lock`)}function A_(_,X){return _ instanceof Error&&"code"in _&&_.code===X}async function z0(_){try{let X=JSON.parse(await $_.readFile(_,"utf8"));if(X.version!==j1||typeof X.sessionId!=="string"||typeof X.ownerId!=="string"||!Number.isInteger(X.pid)||(X.pid??0)<=0||X.processIdentity!==void 0&&!D1(X.processIdentity)||typeof X.acquiredAt!=="string")return;return X}catch(X){if(A_(X,"ENOENT")||X instanceof SyntaxError)return;throw X}}async function w1(_){let X=await z0(_);if(X)return X;return await new Promise(($)=>setTimeout($,10)),z0(_)}function U4(_){try{return process.kill(_,0),!0}catch(X){return!A_(X,"ESRCH")}}async function x1(_,X){let $;try{return $=await $_.open(_,"wx",384),await $.writeFile(`${JSON.stringify(X)}
|
|
2
2
|
`,"utf8"),!0}catch(W){if(A_(W,"EEXIST"))return!1;if($)await $_.unlink(_).catch(()=>{return});throw W}finally{await $?.close().catch(()=>{return})}}class X_ extends Error{code="BLADE_SESSION_IN_USE";constructor(_){super(_?`Session is already active in another Blade process (PID ${_}). Stop that process or choose a different session.`:"Session is already active in another Blade process. Stop that process or choose a different session.");this.name="SessionInUseError"}}async function b1(_,X,$=!1){let W,J;try{J=await L4.lock(_,{realpath:!1,retries:$?{retries:50,minTimeout:10,maxTimeout:100,factor:1.2}:0,onCompromised:(Q)=>{W=Q}})}catch(Q){if(A_(Q,"ELOCKED"))throw new X_;throw Q}let O=()=>{if(W)throw W};try{O();let Q=await X(O);return O(),Q}finally{await J()}}class h{filePath;record;stateStorage;released=!1;constructor(_,X,$){this.filePath=_;this.record=X;this.stateStorage=$}static async acquireForStorage(_,X){if(X.kind==="local")return h.acquire(_,X.root);return G_(X,($,W)=>{if(!W||$!==X.root)throw Error("ACP remote session lease scope is invalid");return h.acquireRemote(_,W,X)})}static async acquire(_,X=f1()){return h.acquireAtPath(_,B4(X,_))}static async acquireRemote(_,X,$){let W=k1(X,_);try{await n(X,W)}catch(O){if(O.code!=="ENOENT")throw O}let J=await h.acquireAtPath(_,W);try{return await n(X,W),new h(W,J.record,$)}catch(O){throw await J.release(),O}}static async acquireAtPath(_,X){return await $_.mkdir(n_.dirname(X),{recursive:!0,mode:448}),b1(X,async($)=>{let W={version:j1,sessionId:_,ownerId:V4(),pid:process.pid,processIdentity:b_(process.pid),acquiredAt:new Date().toISOString()};if($(),await x1(X,W))return new h(X,W);let J=await w1(X);if(!J||J.sessionId!==_)throw new X_;if(U4(J.pid)){let O=J.processIdentity?b_(J.pid,J.processIdentity.platform):void 0;if(!O||O.fingerprint===J.processIdentity?.fingerprint)throw new X_(J.pid)}if($(),await $_.unlink(X).catch((O)=>{if(!A_(O,"ENOENT"))throw O}),$(),await x1(X,W))return new h(X,W);throw new X_((await w1(X))?.pid)})}async release(){if(this.released)return;let _=()=>b1(this.filePath,async(X)=>{if((await z0(this.filePath))?.ownerId!==this.record.ownerId)return;X(),await $_.unlink(this.filePath).catch((W)=>{if(!A_(W,"ENOENT"))throw W})},!0);if(this.stateStorage?.kind==="acp-remote")await G_(this.stateStorage,_);else await _();this.released=!0}}import{createHash as d_}from"node:crypto";import{constants as C_,promises as W_}from"node:fs";import Y_ from"node:path";import{Mutex as H4}from"async-mutex";var y1=128,S1=67108864,N4=24576,g1=65536,R0=1,h1=/^[a-f0-9]{64}$/,C4=/^[a-f0-9]{64}\.txt$/,l1=64,q4=new Set(["EBUSY","EAGAIN","EMFILE","ENFILE"]),o_=`
|
|
3
3
|
|
|
4
4
|
...[middle omitted; read the private prompt artifact for the complete request]...
|
|
@@ -90,5 +90,5 @@ ${[...t,...k].join(`
|
|
|
90
90
|
ORDER BY s.last_message_time DESC,
|
|
91
91
|
s.project_sort_key ASC,
|
|
92
92
|
s.session_sort_key ASC
|
|
93
|
-
LIMIT ?`).all(...J,_.limit+1),Q=await Promise.all(O.map(async(Z)=>{let V=JSON.parse(Z.metadata_json);if(V.remoteWorkspace)throw Error("Local projection contains remote session metadata");if(Z.archive_root_id&&Z.effective_archived_at)return this.reconcileInterruptedTask({...V,archivedAt:Z.effective_archived_at,archivedBySessionId:Z.archive_root_id});let{archivedAt:L,archivedBySessionId:G,...B}=V;return this.reconcileInterruptedTask(B)})),Y=Z1(Q,_);return{sessions:Y.sessions.map((Z)=>this.toPublicMetadata(Z)),nextCursor:Y.nextCursor}}catch{return null}}static async listRemoteSessionPageFromProjection(_){d2(_);try{let X=await this.scanRemoteStoredSessionsFromProjection(_);if(!X)return null;let $=G1(this.toRemoteCatalogEntries(X).sort(V0),_);return{sessions:$.sessions.map((W)=>this.toPublicMetadata(W)),nextCursor:$.nextCursor}}catch(X){throw F(X)}}static async listSessions(_={}){let X=J1(_),$=i2(_),W=await this.scanStoredSessions(X.cwd??void 0,X.includeSubagents,0,X.archived,$),J=new Set;return W.sort(Y1).flatMap((O)=>{let Q=`${O.projectPath}\x00${O.sessionId}`;if(J.has(Q))return[];return J.add(Q),[this.toPublicMetadata(O)]})}static async listRemoteSessions(_={}){let X=Q1(_.descriptor!==void 0?{..._,descriptor:y2(_.descriptor)}:_),$=await this.scanRemoteStoredSessions(X),W=new Set;return this.toRemoteCatalogEntries($).sort(V0).flatMap((J)=>{let O=`${J.projectPath}\x00${J.sessionId}`;if(W.has(O))return[];return W.add(O),[this.toPublicMetadata(J)]})}static async collectStaleEmptySessions(_={}){let X=_.now??Date.now(),$=_.olderThanMs??TX;if(!Number.isFinite($)||$<0)throw Error("Stale empty session age must be a non-negative number");let W=_.projectPath?[{storagePath:H_(this.resolveCatalogWorkspace(_.projectPath)),projectPath:this.resolveCatalogWorkspace(_.projectPath)}]:await this.listAllProjectStorageDirectories(),J=0;for(let O of W){let Q;try{Q=await D_(O.storagePath)}catch(Y){if(Y.code==="ENOENT")continue;throw Y}for(let Y of Q){if(!Y.endsWith(".jsonl"))continue;let Z=Y.slice(0,-6);if(!g_(Z))continue;let V=N.join(O.storagePath,Y);try{let G=await L0(V);if(X-G.mtimeMs<$)continue;if(await Promise.all([L0(N.join(O.storagePath,`${Z}.inbox.json`)).then(()=>!0).catch(()=>!1),L0(N_(O.projectPath,Z)).then(()=>!0).catch(()=>!1)]).then((U)=>U.some(Boolean)))continue}catch(G){if(G.code==="ENOENT")continue;throw G}let L;try{L=await h.acquire(Z,O.projectPath)}catch(G){if(G instanceof X_)continue;throw G}try{if(!await new v(V).deleteValidated((B)=>B.length===1&&B[0]?.type==="session_created"&&B[0].data.relationType!=="subagent"))continue;J++,await R_(N.join(O.storagePath,`${Z}.inbox.json`),{force:!0}),await R_(N_(O.projectPath,Z),{force:!0}),await this.removeFromProjection(Z,O.projectPath)}catch(G){S_.warn(`[SessionService] Skipping stale empty session cleanup: ${Z}`,G)}finally{await L.release()}}}return J}static async findSessionMetadata(_,X){if(T(_),X!==void 0){let W=this.resolveCatalogWorkspace(X),J=this.getSessionFilePath(W,_);try{let O=await this.readStoredSessionMetadata(J,_,W);if(O.projectPath!==W)return;if(!O.parentId||O.archivedAt)return this.toPublicMetadata(X1([O],null)[0]??O);let Q=await this.scanStoredSessions(W,!0,0,null);return this.toPublicMetadata(Q.find((Y)=>Y.sessionId===_)??O)}catch(O){if(O.code==="ENOENT")return;throw O}}let $=(await this.scanStoredSessions(void 0,!0,0,null)).filter((W)=>W.sessionId===_);if($.length===0)return;if($.length>1)throw Error(`Ambiguous session ID: ${_}`);return this.toPublicMetadata($[0])}static async loadSession(_,X,$={}){try{if(X){let J=this.resolveCatalogWorkspace(X),O=this.getSessionFilePath(J,_);try{return await this.loadSessionFromFile(O,_,J,$)}catch(Q){if(Q.code==="ENOENT")throw Error(`未找到会话: ${_}`);throw Q}}let W=(await this.scanStoredSessions(void 0,!0,0,null)).find((J)=>J.sessionId===_);if(!W)throw Error(`未找到会话: ${_}`);return await this.loadSessionFromFile(W.filePath,_,void 0,$)}catch(W){throw S_.error(`[SessionService] 加载会话失败 (${_}):`,W),W}}static async loadSessionModelContext(_,X){try{if(X){let W=this.resolveCatalogWorkspace(X),J=this.getSessionFilePath(W,_);try{return await this.loadSessionModelContextFromFile(J,_,W)}catch(O){if(O.code==="ENOENT")throw Error(`未找到会话: ${_}`);throw O}}let $=(await this.scanStoredSessions(void 0,!0,0,null)).find((W)=>W.sessionId===_);if(!$)throw Error(`未找到会话: ${_}`);return await this.loadSessionModelContextFromFile($.filePath,_)}catch($){throw S_.error(`[SessionService] 加载模型上下文失败 (${_}):`,$),$}}static async loadRemoteSession(_,X,$){let W=await this.readValidatedRemoteSessionSnapshot(_,X,$);return this.convertJSONLToMessages(W)}static async loadRemoteSessionModelContext(_,X,$){let W=await this.readValidatedRemoteSessionSnapshot(_,X,$);return this.convertJSONLToModelContext(W)}static async readValidatedLocalSurfaceSnapshot(_,X,$){T(_);let W=this.resolveCatalogWorkspace(X),J=P(W,_),O=await this.readStableSessionSnapshot(J,_,3,$);this.validateSessionWorkspace(O,_,W);let Q=this.projectMetadataFromEntries(O,_,W,J);if(Q.remoteWorkspace)throw new w;return{entries:O,summary:V1(Q)}}static async readValidatedRemoteSurfaceSnapshot(_,X){let $=await this.readValidatedRemoteSessionSnapshot(_.sessionId,_.hostStateRoot,_.descriptor,X);return c(_.hostStateRoot,async(W)=>{X?.throwIfAborted();let J=m(W,_.sessionId),O=j(this.projectMetadataFromEntries($,_.sessionId,_.hostStateRoot,J),_.descriptor);return{entries:$,summary:V1(O,_.workspaceRef)}})}static async listValidatedRemoteSurfaceCandidates(_){let X=[];for(let $ of await $1())_?.throwIfAborted(),await c(String($),async(W)=>{for(let J of await D_(String(W))){if(_?.throwIfAborted(),!J.endsWith(".jsonl"))continue;let O=J.slice(0,-6);if(!g_(O))continue;let Q=m(W,O);await n(W,Q);let Y=await this.readStableSessionSnapshot(Q,O,3,_),Z=j(this.projectMetadataFromEntries(Y,O,String(W),Q));await this.reconcileInterruptedTask(Z,"acp-remote",W);let V=await l2(W,Z.remoteWorkspace);_?.throwIfAborted(),X.push({descriptor:Z.remoteWorkspace,hostStateRoot:String(W),sessionId:O,workspaceRef:V})}});return X}static async listValidatedLocalSurfaceCandidates(_){let X=new Map;for(let $ of await this.listAllProjectStorageDirectories()){_?.throwIfAborted();let W;try{W=await D_($.storagePath)}catch(J){if(J.code==="ENOENT")continue;throw J}for(let J of W){if(_?.throwIfAborted(),!J.endsWith(".jsonl"))continue;let O=J.slice(0,-6);if(!g_(O))continue;let Q=N.join($.storagePath,J);try{let Y=await this.readStableSessionSnapshot(Q,O,3,_),Z=this.getSessionCreatedEntry(Y,O);if(Z.data.sessionId!==O||!N.isAbsolute(Z.cwd)||Object.hasOwn(Z.data,"remoteWorkspace"))continue;let V;try{V=G0(Z.cwd)}catch{continue}if(P(V,O)!==Q)continue;await this.reconcileInterruptedTask(this.projectMetadataFromEntries(Y,O,V,Q)),X.set(`${V}\x00${O}`,{projectPath:V,sessionId:O})}catch(Y){if(_?.aborted)throw Y;if(Y.code==="ENOENT")continue;if(Y instanceof w)throw Y}}}return[...X.values()]}static async exportSessionMarkdown(_,X,$={}){T(_);let W=this.resolveCatalogWorkspace(X),J=P(W,_),O;try{O=await this.readStableSessionSnapshot(J,_)}catch(Z){throw this.sanitizeStoredSessionError(Z,_)}let Q=this.projectMetadataFromEntries(O,_,W,J);if(Q.projectPath!==W)throw Error(`Session export workspace mismatch: ${_}`);let Y=Q.archivedAt;if(!Y&&Q.parentId)Y=(await this.findArchivedAncestor(Q.parentId,W))?.archivedAt;return N2(O,{...Q,archivedAt:Y},$)}static async listRewindCheckpoints(_,X){T(_);let $=this.resolveCatalogWorkspace(X),W=P($,_),J=await this.readStableSessionSnapshot(W,_);this.validateSessionWorkspace(J,_,$);let O=new W0({sessionId:_,workspaceRoot:$});await O.initialize();let Q=p2(J),Y=[];for(let Z of Q){let V=W1(J,Z.messageId),L=await O.previewRewind(V.snapshotMessageIds);Y.push({...Z,fileCount:L.files.length})}return Y}static async rewindSession(_,X,$){T(_);let W=this.resolveCatalogWorkspace(X);await this.assertSessionWritable(_,W);let J=P(W,_),O=new v(J),Q;try{await O.appendValidatedAsync(async(Y)=>{this.validateSessionWorkspace(Y,_,W);let Z=W1(Y,$.targetMessageId),V=new W0({sessionId:_,workspaceRoot:W});await V.initialize();let L=await V.previewRewind(Z.snapshotMessageIds),G=$.mode==="conversation"?await V.commitSnapshots(Z.snapshotMessageIds):await V.rewindSnapshots(Z.snapshotMessageIds),B=new Date().toISOString(),U={id:i(),sessionId:_,timestamp:B,type:"session_rewound",cwd:W,gitBranch:L_(W),version:__(),data:{rewindId:i(),targetMessageId:$.targetMessageId,mode:$.mode,restoredFiles:$.mode==="conversation"?[]:G.files,createdAt:B}},H=e([...Y,U]);return Q={checkpoint:{...Z.checkpoint,fileCount:L.files.length},mode:$.mode,removedTurns:Z.removedTurns,restoredFiles:U.data.restoredFiles,messages:this.convertJSONLToMessages(H)},U})}catch(Y){throw this.sanitizeStoredSessionError(Y,_)}if(!Q)throw Error(`Session rewind did not produce a result: ${_}`);for(let Y of Q.restoredFiles)V_.getInstance().clearFileRecord(Y);return Q}static async forkSession(_,X){T(_);let $=X.newSessionId??`fork-${Date.now()}-${i(8)}`;T($);let W=X.remote;if(W)return this.forkRemoteSession(_,$,X.sourceProjectPath,X.targetProjectPath,W.expectedDescriptor);let J=this.resolveForkWorkspace(X.sourceProjectPath),O=this.resolveForkWorkspace(X.targetProjectPath);if(J!==O)throw Error("Session forks must stay in the source workspace");let Q=P(J,_),Y=await this.readStableSessionSnapshot(Q,_),Z=this.getSessionCreatedEntry(Y,_);if(Z.data.sessionId!==_)throw Error("Fork source session_created.data.sessionId must match the requested session ID");if(!N.isAbsolute(Z.cwd)||N.resolve(Z.cwd)!==J)throw Error("Fork source session_created.cwd must resolve to the requested source workspace");let V=this.projectMetadataFromEntries(Y,_,J,Q);if(V.archivedAt)throw new a(_,_);if(V.parentId){let k=await this.findArchivedAncestor(V.parentId,J);if(k)throw new a(_,k.sessionId)}let L=e(Y),G=new Date().toISOString(),B=Z.data.rootId||_,U=L_(O),H=__(),A=this.buildForkChildEntries({sourceEntries:L,sourceCreated:Z,sourceSessionId:_,targetSessionId:$,targetProjectPath:O,rootId:B,version:H,now:G,target:{kind:"local",gitBranch:U}}),z=P(O,$),D=!1;try{await new v(z).createExclusive(A),D=!0;let k=b0(L.flatMap((y)=>y.type==="message_created"?[y.data.metadata]:[]));if(k.length>0){let y=new O_(J,_,{storageRoot:l()}),u=new O_(O,$,{storageRoot:l()});await y.copyReferencedTo(k,u)}}catch(k){if(D)await new v(z).delete().catch(()=>{return}),await new O_(O,$,{storageRoot:l()}).removeAll().catch(()=>{return});if(k.code==="EEXIST")throw Error(`Fork session already exists: ${$}`,{cause:k});throw k}let t=this.projectMetadataFromEntries(A,$,O,z);return{sessionId:$,parentSessionId:_,projectPath:O,messages:this.convertJSONLToMessages(A),metadata:this.toPublicMetadata(t)}}static async forkRemoteSession(_,X,$,W,J){let O;try{O=r(J)}catch(Y){throw F(Y)}let Q=p(O.collisionIdentity);if($!==Q||W!==Q)throw new w;return c(Q,async(Y)=>{let Z=m(Y,_);try{await n(Y,Z)}catch(I){throw F(I)}let V;try{V=await this.readStableSessionSnapshot(Z,_)}catch(I){throw j2(I)}let L=Z0(V,_,Q),G=j(this.projectMetadataFromEntries(V,_,Q,Z),O);if(G.archivedAt)throw new a(_,_);if(G.parentId){let I=await this.findRemoteArchivedAncestor(G.parentId,Y,G.remoteWorkspace);if(I)throw new a(_,I.sessionId)}let B=e(V),U=new Date().toISOString(),H=__(),A=G.rootId||_,z=this.buildForkChildEntries({sourceEntries:B,sourceCreated:L,sourceSessionId:_,targetSessionId:X,targetProjectPath:Q,rootId:A,version:H,now:U,target:{kind:"remote",descriptor:G.remoteWorkspace}}),D=m(Y,X),t=!1;try{await new v(D).createExclusive(z),t=!0,await n(Y,D);let I=b0(B.flatMap((U_)=>U_.type==="message_created"?[U_.data.metadata]:[]));if(I.length>0){let U_=new O_(Q,_,{storageRoot:Q}),p_=new O_(Q,X,{storageRoot:Q});await U_.copyReferencedTo(I,p_)}}catch(I){if(t)await new v(D).delete().catch(()=>{return}),await new O_(Q,X,{storageRoot:Q}).removeAll().catch(()=>{return});if(I.code==="EEXIST")throw Error(`Fork session already exists: ${X}`,{cause:I});throw F(I)}let k=j(this.projectMetadataFromEntries(z,X,Q,D),G.remoteWorkspace),{gitBranch:y,taskIsolation:u,taskSourceProjectPath:R,taskWorktreePath:x,taskWorktreeBranch:f,taskBaseCommit:q,taskDiffStat:B_,...S}=this.toPublicMetadata(k);return{sessionId:X,parentSessionId:_,projectPath:Q,messages:this.convertJSONLToMessages(z),metadata:S}})}static async findRemoteArchivedAncestor(_,X,$){let W=new Set,J=_;while(J){if(W.has(J))throw new w;W.add(J),T(J);let O=m(X,J);try{await n(X,O)}catch(Z){if(Z.code==="ENOENT")return;throw F(Z)}let Q;try{Q=await this.readStableSessionSnapshot(O,J)}catch(Z){throw j2(Z)}Z0(Q,J,String(X));let Y=j(this.projectMetadataFromEntries(Q,J,String(X),O));if(!w_(Y.remoteWorkspace,$))return;if(Y.archivedAt)return{sessionId:Y.sessionId,archivedAt:Y.archivedAt};J=Y.parentId}return}static buildForkChildEntries(_){let{sourceEntries:X,sourceCreated:$,sourceSessionId:W,targetSessionId:J,targetProjectPath:O,rootId:Q,version:Y,now:Z,target:V}=_,L=V.kind==="remote"?{projectPath:O}:{gitBranch:V.gitBranch},G=V.kind==="remote"?{remoteWorkspace:V.descriptor}:{taskIsolation:"local",taskSourceProjectPath:O},B=V.kind==="remote"?{}:{taskIsolation:"local",taskSourceProjectPath:O,taskWorktree:null,taskDiffStat:null},{status:U,taskStatus:H,taskStatusReason:A,taskFailure:z,taskStartedAt:D,taskCompletedAt:t,taskOwnerPid:k,taskPromptSummary:y,taskPriority:u,taskKind:R,taskDueAt:x,taskDispatch:f,taskModelId:q,taskRetriedFrom:B_,taskDelivery:S,taskIsolation:I,taskSourceProjectPath:U_,taskWorktree:p_,taskDiffStat:N0,taskQueuePosition:C1,taskQueueDepth:q1,taskConcurrencyLimit:K1,pendingInteraction:M1,remoteWorkspace:T1,...c_}=$.data,C0={id:i(),sessionId:J,...L,timestamp:Z,type:"session_created",cwd:O,version:Y,data:{...c_,sessionId:J,rootId:Q,parentId:W,relationType:"fork",taskStatus:"completed",taskCompletedAt:Z,...G,createdAt:Z,updatedAt:Z}},q0=X.filter((g)=>g.type!=="session_created"&&g.type!=="token_budget_handoff_recorded"&&g.type!=="inbox_acknowledged"&&g.type!=="interaction_requested"&&g.type!=="interaction_responded"&&g.type!=="interaction_recovered"&&g.type!=="review_started"&&g.type!=="review_completed").map((g)=>{let{gitBranch:A1,...M0}=g,x_={...V.kind==="remote"?M0:g,id:i(),sessionId:J,...L,cwd:O,version:Y};if(g.type==="session_updated"){let{status:T0,taskStatus:T_,taskStatusReason:A0,taskFailure:b,taskStartedAt:E0,taskCompletedAt:zX,taskOwnerPid:DX,taskPromptSummary:RX,taskPriority:wX,taskKind:xX,taskDueAt:bX,taskDispatch:kX,taskModelId:fX,taskRetriedFrom:jX,taskDelivery:yX,taskIsolation:SX,taskSourceProjectPath:gX,taskWorktree:IX,taskDiffStat:mX,taskQueuePosition:vX,taskQueueDepth:PX,taskConcurrencyLimit:uX,pendingInteraction:hX,remoteWorkspace:lX,...$4}=g.data;return{...x_,type:"session_updated",data:{...$4,sessionId:J,rootId:Q,parentId:W,relationType:"fork"}}}if(g.type==="message_created"){let{inboxMessageId:T0,...T_}=g.data;return{...x_,type:"message_created",data:T_}}return x_}),K0={id:i(),sessionId:J,...L,timestamp:Z,type:"session_updated",cwd:O,version:Y,data:{sessionId:J,rootId:Q,parentId:W,relationType:"fork",taskStatus:"completed",taskStatusReason:null,taskFailure:null,taskStartedAt:null,taskCompletedAt:Z,taskOwnerPid:null,...B,taskDelivery:null,taskQueuePosition:null,taskQueueDepth:null,taskConcurrencyLimit:null,updatedAt:Z}};return[C0,...q0,K0]}static async deleteSession(_,X){if(T(_),X){if(!N.isAbsolute(X))throw Error("Session catalog cwd must be absolute");let W=N.resolve(X),J=this.getSessionFilePath(W,_),O=new v(J),Q;try{Q=await O.deleteValidated((Y)=>{return this.projectMetadataFromEntries(Y,_,W,J).projectPath===W})}catch(Y){if(!this.isCorruptSessionJSONLError(Y))throw Y;Q=await O.delete()}if(!Q)return 0;return await R_(N.join(N.dirname(J),`${_}.inbox.json`),{force:!0}),await R_(N_(W,_),{force:!0}),await new O_(W,_,{storageRoot:l()}).removeAll(),await S0(W,_,l()),await this.removeFromProjection(_,W),1}let $=(await this.scanStoredSessions(void 0,!0)).filter((W)=>W.sessionId===_);if($.length===0)return 0;return await Promise.all($.map(async(W)=>{await new v(W.filePath).delete(),await R_(N.join(N.dirname(W.filePath),`${W.sessionId}.inbox.json`),{force:!0}),await R_(N_(W.projectPath,W.sessionId),{force:!0}),await new O_(W.projectPath,W.sessionId,{storageRoot:l()}).removeAll(),await S0(W.projectPath,W.sessionId,l()),await this.removeFromProjection(W.sessionId,W.projectPath)})),$.length}static async removeFromProjection(_,X){try{let $=await I_();if($)s2($,_,X)}catch{}}static validateTaskMetadataUpdate(_,X){if(_.taskStatus!==void 0&&!D2.has(_.taskStatus))throw Error(`Invalid session task status: ${String(_.taskStatus)}`);if(_.taskOwnerPid!==void 0&&_.taskOwnerPid!==null&&(!Number.isInteger(_.taskOwnerPid)||_.taskOwnerPid<=0))throw Error("Session task owner PID must be a positive integer");if(_.taskPromptSummary!==void 0&&_.taskPromptSummary!==null&&(!_.taskPromptSummary.trim()||_.taskPromptSummary.length>1000))throw Error("Session task prompt summary must contain 1-1000 characters");if(_.taskPriority!==void 0&&_.taskPriority!==null&&!U0.has(_.taskPriority))throw Error("Invalid session task priority");if(_.taskKind!==void 0&&_.taskKind!==null&&!H0.has(_.taskKind))throw Error("Invalid session task kind");if(_.taskDueAt!==void 0&&_.taskDueAt!==null&&!Number.isFinite(Date.parse(_.taskDueAt)))throw Error("Invalid session task due date");if(_.taskFailure!==void 0&&_.taskFailure!==null&&!c0(_.taskFailure))throw Error("Invalid session task failure");if(_.taskDispatch!==void 0&&_.taskDispatch!==null&&!b2(_.taskDispatch))throw Error("Invalid durable task dispatch");if(_.taskModelId!==void 0&&_.taskModelId!==null&&(!_.taskModelId.trim()||_.taskModelId.length>500))throw Error("Invalid session task model ID");if(_.selectedModelId!==void 0&&_.selectedModelId!==null&&(!_.selectedModelId.trim()||_.selectedModelId.length>500))throw Error("Invalid selected session model ID");if(_.permissionMode!==void 0&&_.permissionMode!==null&&!B0(_.permissionMode))throw Error("Invalid session permission mode");if(_.reasoningEffort!==void 0&&_.reasoningEffort!==null&&!h_(_.reasoningEffort))throw Error("Invalid session reasoning effort");if(_.serviceTier!==void 0&&_.serviceTier!==null&&!u_(_.serviceTier))throw Error("Invalid session service tier");if(_.responseVerbosity!==void 0&&_.responseVerbosity!==null&&!P_(_.responseVerbosity))throw Error("Invalid session response verbosity");if(_.communicationStyle!==void 0&&_.communicationStyle!==null&&!l_(_.communicationStyle))throw Error("Invalid session communication style");if(_.communicationStyleDigest!==void 0&&_.communicationStyleDigest!==null&&!/^[a-f0-9]{64}$/.test(_.communicationStyleDigest))throw Error("Invalid session communication style digest");if(_.projectInstructionsDigest!==void 0&&_.projectInstructionsDigest!==null&&!/^[a-f0-9]{64}$/.test(_.projectInstructionsDigest))throw Error("Invalid session project instructions digest");if(_.taskRetriedFrom!==void 0&&_.taskRetriedFrom!==null&&!k2(_.taskRetriedFrom))throw Error("Invalid session task retry source");if(_.taskDelivery!==void 0&&_.taskDelivery!==null&&!w2(_.taskDelivery))throw Error("Invalid session task delivery");if(_.taskIsolation!==void 0&&_.taskIsolation!==null&&!B1.has(_.taskIsolation))throw Error(`Invalid session task isolation: ${String(_.taskIsolation)}`);if(_.taskSourceProjectPath!==void 0&&_.taskSourceProjectPath!==null&&!N.isAbsolute(_.taskSourceProjectPath))throw Error("Session task source project path must be absolute");if(_.taskWorktree!==void 0&&_.taskWorktree!==null){let $=R2(_.taskWorktree);if(!$||$.sessionId!==X||![$.repositoryRoot,$.originalWorkspaceRoot,$.worktreeRoot,$.workspaceRoot].every((W)=>N.isAbsolute(W)))throw Error("Invalid session task worktree metadata")}if(_.taskDiffStat!==void 0&&_.taskDiffStat!==null&&!x2(_.taskDiffStat))throw Error("Invalid session task diff stat");if(_.taskQueuePosition!==void 0&&_.taskQueuePosition!==null&&(!Number.isInteger(_.taskQueuePosition)||_.taskQueuePosition<1))throw Error("Invalid session task queue position");if(_.taskQueueDepth!==void 0&&_.taskQueueDepth!==null&&(!Number.isInteger(_.taskQueueDepth)||_.taskQueueDepth<0))throw Error("Invalid session task queue depth");if(_.taskConcurrencyLimit!==void 0&&_.taskConcurrencyLimit!==null&&(!Number.isInteger(_.taskConcurrencyLimit)||_.taskConcurrencyLimit<1))throw Error("Invalid session task concurrency limit");if(typeof _.taskQueuePosition==="number"&&typeof _.taskQueueDepth==="number"&&_.taskQueuePosition>_.taskQueueDepth)throw Error("Session task queue position exceeds queue depth")}static async createSessionMetadata(_,X,$={}){T(_),C.validateTaskMetadataUpdate($,_);let W=C.resolveCatalogWorkspace(X);if($.taskWorktree&&N.resolve($.taskWorktree.workspaceRoot)!==W)throw Error("Session task worktree must match the catalog workspace");let J=new Date().toISOString(),O={id:i(),sessionId:_,timestamp:J,type:"session_created",cwd:W,gitBranch:L_(W),version:__(),data:{...Y0(_,$,J,!0),sessionId:_,rootId:_,taskStatus:$.taskStatus??"queued",createdAt:J,updatedAt:J}},Q=C.getSessionFilePath(W,_);return await new v(Q).createExclusive([O]),C.toPublicMetadata(C.projectMetadataFromEntries([O],_,W,Q))}static async createRemoteSessionMetadata(_,X,$,W={}){T(_),C.validateTaskMetadataUpdate(W,_);let J;try{J=r($)}catch(Y){throw F(Y)}if(p(J.collisionIdentity)!==X)throw new w;await m2(X);let Q=new Date().toISOString();return c(X,async(Y)=>{let Z=m(Y,_),V={id:i(),sessionId:_,projectPath:X,timestamp:Q,type:"session_created",cwd:X,version:__(),data:{...Y0(_,W,Q,!1),sessionId:_,rootId:_,remoteWorkspace:J,taskStatus:W.taskStatus??"queued",createdAt:Q,updatedAt:Q}};try{await new v(Z).createExclusive([V])}catch(L){if(L.code!=="EEXIST")throw L;return this.assertRemoteSessionWritableInScope(_,X,J,Y)}return C.toPublicMetadata(C.projectMetadataFromEntries([V],_,X,Z))})}static async assertSessionWritable(_,X){let $=await this.findSessionMetadata(_,X);if(!$)throw Error(`Session not found: ${_}`);if($.archivedAt)throw new a(_,$.archivedBySessionId??_);return $}static async assertRemoteSessionWritable(_,X,$){T(_);let W;try{W=r($)}catch(O){throw F(O)}if(p(W.collisionIdentity)!==X)throw new w;return c(X,async(O)=>{return this.assertRemoteSessionWritableInScope(_,X,W,O)})}static async findArchivedAncestor(_,X){let $=new Set,W=_;while(W){if($.has(W))throw Error("Session lineage contains a cycle");$.add(W),T(W);let J=P(X,W),O;try{O=await Z_(J,"utf8")}catch(Y){if(Y.code==="ENOENT")return;throw Y}let Q=this.projectMetadataFromEntries(this.parseStoredSession(O,W),W,X,J);if(Q.projectPath!==X)throw Error("Session lineage escapes the requested workspace");if(Q.archivedAt)return{sessionId:Q.sessionId,archivedAt:Q.archivedAt};W=Q.parentId}return}static async listSessionArchiveMembers(_,X){T(_);let $=this.resolveCatalogWorkspace(X),W=await this.scanStoredSessions($,!0,0,null);if(!W.some((Q)=>Q.sessionId===_))throw Error(`Session not found: ${_}`);let J=new Set([_]),O=!0;while(O){O=!1;for(let Q of W)if(Q.parentId&&J.has(Q.parentId)&&!J.has(Q.sessionId))J.add(Q.sessionId),O=!0}return W.filter((Q)=>J.has(Q.sessionId)).sort((Q,Y)=>Q.sessionId.localeCompare(Y.sessionId)).map((Q)=>this.toPublicMetadata(Q))}static async archiveSession(_,X){T(_);let $=this.resolveCatalogWorkspace(X),W=await this.findSessionMetadata(_,$);if(!W)throw Error(`Session not found: ${_}`);if(W.archivedAt)return W;let J=await this.listSessionArchiveMembers(_,$),O=J.find((Y)=>Y.taskStatus==="queued"||Y.taskStatus==="running");if(O)throw new Q_(`Stop session ${O.sessionId} before archiving this session tree`);let Q=[];try{for(let L of J)Q.push(await h.acquire(L.sessionId,$));let Y=P($,_),Z=new v(Y),V=[];return await Z.appendValidated((L)=>{let G=this.projectMetadataFromEntries(L,_,$,Y);if(G.archivedAt)throw new Q_(`Session archive state changed concurrently: ${_}`);if(G.taskStatus==="queued"||G.taskStatus==="running")throw new Q_(`Stop session ${_} before archiving it`);let B=new Date().toISOString(),U={id:i(),sessionId:_,timestamp:B,type:"session_updated",cwd:$,gitBranch:L_($),version:__(),data:{sessionId:_,archivedAt:B,updatedAt:B}};return V=[...L,U],U}),this.toPublicMetadata({...this.projectMetadataFromEntries(V,_,$,Y),archivedBySessionId:_})}catch(Y){if(Y instanceof Q_)throw Y;if(Y instanceof X_)throw new Q_(Y.message);throw this.sanitizeStoredSessionError(Y,_)}finally{for(let Y of Q.reverse())await Y.release()}}static async unarchiveSession(_,X){T(_);let $=this.resolveCatalogWorkspace(X),W=await this.findSessionMetadata(_,$);if(!W)throw Error(`Session not found: ${_}`);if(!W.archivedAt)return W;if(W.archivedBySessionId&&W.archivedBySessionId!==_)throw new Q_(`Unarchive ancestor ${W.archivedBySessionId} to restore session ${_}`);let J;try{J=await h.acquire(_,$);let O=P($,_),Q=new v(O),Y=[];return await Q.appendValidated((Z)=>{if(!this.projectMetadataFromEntries(Z,_,$,O).archivedAt)throw new Q_(`Session archive state changed concurrently: ${_}`);let L=new Date().toISOString(),G={id:i(),sessionId:_,timestamp:L,type:"session_updated",cwd:$,gitBranch:L_($),version:__(),data:{sessionId:_,archivedAt:null,updatedAt:L}};return Y=[...Z,G],G}),this.toPublicMetadata(this.projectMetadataFromEntries(Y,_,$,O))}catch(O){if(O instanceof Q_)throw O;if(O instanceof X_)throw new Q_(O.message);throw this.sanitizeStoredSessionError(O,_)}finally{await J?.release()}}static async updateSessionMetadata(_,X,$){T(_),C.validateTaskMetadataUpdate($,_);let W=C.resolveCatalogWorkspace(X);if($.taskWorktree&&N.resolve($.taskWorktree.workspaceRoot)!==W)throw Error("Session task worktree must match the catalog workspace");let J=C.getSessionFilePath(W,_),O=new v(J),Q=[];try{await O.appendValidatedAsync(async(Y)=>{let Z=C.getSessionCreatedEntry(Y,_);if(Z.data.sessionId!==_)throw Error(`Session metadata creation record sessionId mismatch: ${_}`);if(!N.isAbsolute(Z.cwd)||N.resolve(Z.cwd)!==W)throw Error(`Session metadata creation record cwd mismatch: ${_}`);let V=C.projectMetadataFromEntries(Y,_,W,J);if(V.archivedAt)throw new a(_,_);if(V.parentId){let B=await C.findArchivedAncestor(V.parentId,W);if(B)throw new a(_,B.sessionId)}let L=new Date().toISOString(),G={id:i(),sessionId:_,timestamp:L,type:"session_updated",cwd:W,gitBranch:L_(W),version:__(),data:Y0(_,$,L,!0)};return Q=[...Y,G],G})}catch(Y){throw C.sanitizeStoredSessionError(Y,_)}return C.toPublicMetadata(C.projectMetadataFromEntries(Q,_,W,J))}static async updateRemoteSessionMetadata(_,X,$,W){T(_),C.validateTaskMetadataUpdate(W,_);let J;try{if(J=r($),p(J.collisionIdentity)!==X)throw new w}catch(O){throw F(O)}try{return await c(X,async(O)=>{let Q=m(O,_);await n(O,Q);let Y=new v(Q),Z=[];return await Y.appendValidatedAsync(async(V)=>{let L=j(C.projectMetadataFromEntries(V,_,X,Q),J);if(L.archivedAt)throw new a(_,_);if(L.parentId){let U=await C.findRemoteArchivedAncestor(L.parentId,O,L.remoteWorkspace);if(U)throw new a(_,U.sessionId)}let G=new Date().toISOString(),B={id:i(),sessionId:_,projectPath:X,timestamp:G,type:"session_updated",cwd:X,version:__(),data:Y0(_,W,G,!1)};return Z=[...V,B],B},{noFollow:!0,validateHandle:(V)=>v2(O,Q,V)}),C.toPublicMetadata(j(C.projectMetadataFromEntries(Z,_,X,Q),J))})}catch(O){if(O instanceof v_||O instanceof a)throw O;throw F(O)}}static async setSessionPermissionMode(_,X,$){if(T(_),!B0($))throw Error("Invalid session permission mode");let W=C.resolveCatalogWorkspace(X),J=await C.findSessionMetadata(_,W);if(J?.permissionMode===$)return J;if(J)return C.updateSessionMetadata(_,W,{permissionMode:$});try{return await C.createSessionMetadata(_,W,{taskStatus:"completed",permissionMode:$})}catch(O){if(O.code!=="EEXIST")throw O;return C.updateSessionMetadata(_,W,{permissionMode:$})}}static async findSessionTaskWorktree(_,X){T(_);let $=C.resolveCatalogWorkspace(X),W=C.getSessionFilePath($,_);try{return(await C.readStoredSessionMetadata(W,_,$)).taskWorktree}catch(J){if(J.code==="ENOENT")return;throw C.sanitizeStoredSessionError(J,_)}}static async findSessionTaskDispatch(_,X){T(_);let $=C.resolveCatalogWorkspace(X),W=C.getSessionFilePath($,_);try{return(await C.readStoredSessionMetadata(W,_,$)).taskDispatch}catch(J){if(J.code==="ENOENT")return;throw C.sanitizeStoredSessionError(J,_)}}static async loadSessionFromFile(_,X,$,W={}){let J=await Z_(_,"utf-8"),O=this.parseStoredSession(J,X);if($!==void 0){if(this.projectMetadataFromEntries(O,X,$,_).projectPath!==$)throw Error(`未找到会话: ${X}`)}return this.convertJSONLToMessages(O,W)}static async loadSessionModelContextFromFile(_,X,$){let W=await Z_(_,"utf-8"),J=this.parseStoredSession(W,X);if($!==void 0){if(this.projectMetadataFromEntries(J,X,$,_).projectPath!==$)throw Error(`未找到会话: ${X}`)}return this.convertJSONLToModelContext(J)}static convertJSONLToModelContext(_){let X=e(_),$=-1,W;for(let O=0;O<X.length;O++){let Q=X[O];if(Q?.type!=="part_created"||Q.data.partType!=="summary")continue;let Y=Q.data.payload;if($=O,W=s_(Y.replacementMessages),!W)W=[{role:"user",content:Y.text??"",metadata:Q.data.payload}]}if($<0||!W)return this.convertJSONLToMessages(X,{includeTokenBudgetHandoffs:!0}).filter((O)=>!o0(O));let J=this.convertJSONLToMessages(X.slice($+1),{includeTokenBudgetHandoffs:!0});return[...W,...J].filter((O)=>!o0(O))}static convertJSONLToMessages(_,X={}){let $=[],W=new Map,J=new Map,O=new Map,Q=new Map,Y=new Map,Z=e(_),V=X.includeTokenBudgetHandoffs?O2(Z):{kind:"none"},L=new Set;for(let G of Z){if(G.type==="token_budget_handoff_recorded"){if(V.kind==="valid"&&V.event.id===G.id){let B=J2(G);if(B)$.push(B)}continue}if(G.type==="message_created"){let B=G.data.metadata&&typeof G.data.metadata==="object"&&!Array.isArray(G.data.metadata)?G.data.metadata:void 0,U=B?.codeReview&&typeof B.codeReview==="object"&&!Array.isArray(B.codeReview)?B.codeReview:void 0;if(U?.phase==="completed"&&typeof U.reviewId==="string")L.add(U.reviewId);let H=G.data.role==="assistant"&&G.data.parentMessageId?O.get(G.data.parentMessageId):void 0,A=H??{...X.includeMessageIds?{id:G.data.messageId}:{},role:G.data.role,content:"",...G.data.metadata||G.data.inboxMessageId?{metadata:{...G.data.metadata&&typeof G.data.metadata==="object"&&!Array.isArray(G.data.metadata)?G.data.metadata:{},...G.data.inboxMessageId?{inboxMessageId:G.data.inboxMessageId}:{}}}:{}};if(X.includeMessageIds)A.id??=G.data.messageId;if(W.set(G.data.messageId,A),J.set(G.data.messageId,[]),!H)$.push(A)}if(G.type==="part_created"){if(G.data.partType==="reasoning"){let B=W.get(G.data.messageId);if(B){let U=G.data.payload;B.reasoningContent=(B.reasoningContent??"")+(U.text??"")}}if(G.data.partType==="text"){let B=W.get(G.data.messageId);if(B){let U=G.data.payload,H=J.get(G.data.messageId);if(H)H.push({type:"text",text:U.text??""}),B.content=I2(H);else B.content=U.text??""}}if(G.data.partType==="image"){let B=W.get(G.data.messageId);if(B){let U=G.data.payload,H=J.get(G.data.messageId);if(H&&U.dataUrl)H.push({type:"image_url",image_url:{url:U.dataUrl}}),B.content=I2(H)}}if(G.data.partType==="tool_call"){let B=W.get(G.data.messageId);if(B?.role!=="assistant"){if(B=O.get(G.data.messageId),!B)B={role:"assistant",content:"",tool_calls:[]},O.set(G.data.messageId,B),$.push(B)}if(B.role==="assistant"){let U=G.data.payload,H=U.toolCallId??G.data.partId;Q.set(G.data.partId,H),Y.set(H,B),B.tool_calls??=[],B.tool_calls.push({id:H,type:"function",function:{name:U.toolName??"unknown",arguments:JSON.stringify(U.input??{})}})}}if(G.data.partType==="tool_result"){let B=G.data.payload,U=L2(B),H=U.error?`Error: ${U.error.message}`:typeof U.llmContent==="string"?U.llmContent:JSON.stringify(U.llmContent),A=B;$.push({role:"tool",content:H,tool_call_id:Q.get(G.data.messageId)??B.toolCallId,name:B.toolName,metadata:A})}if(G.data.partType==="summary"){let B=G.data.payload,U=G.data.payload;$.push({role:"system",content:B.text??"",metadata:U})}if(G.data.partType==="subtask_ref"){let B=W.get(G.data.messageId)??Y.get(G.data.messageId);if(B){let U=G.data.payload,H=B.metadata??{};B.metadata={...H,subtaskRef:U}}}}}for(let G of e_(Z)){if(G.completion===void 0||L.has(G.start.reviewId))continue;$.push({role:"assistant",content:e1(G.start,G.completion),metadata:{codeReview:{..._2(G.start,G.completion),synthetic:!0}}})}return $}static projectionDeriver(){return(_,X,$,W,J)=>{try{let O=J??P($,X),Q=this.projectMetadataFromEntries(_,X,$,O);if(W==="acp-remote")return j(Q);return Q}catch(O){if(W==="acp-remote")throw F(O);return null}}}static projectionDeriverForSearch(){return this.projectionDeriver()}static async scanStoredSessionsFromProjection(_,X,$=0,W=!1,J={}){try{let O=await I_();if(!O)return null;await L1(O,this.projectionDeriver(),$);let Q=[];Q.push("source_kind = 'local'");let Y=[];if(_!==void 0)Q.push("project_path=?"),Y.push(_);CX(J,"",Q,Y);let Z=Q.length>0?` WHERE ${Q.join(" AND ")}`:"",V=O.prepare(`SELECT metadata_json, is_subagent FROM sessions${Z}`).all(...Y),L=[];for(let B of V){if(!X&&B.is_subagent===1)continue;try{let U=JSON.parse(B.metadata_json);if(U.remoteWorkspace)continue;if(_!==void 0&&U.projectPath!==_)continue;L.push(U)}catch{}}let G=await Promise.all(L.map((B)=>this.reconcileInterruptedTask(B)));return X1(G.filter((B)=>e2(B,J)),W)}catch{return null}}static async scanStoredSessions(_,X=!1,$=0,W=!1,J={}){let O=_?N.resolve(_):void 0,Q=await this.scanStoredSessionsFromProjection(O,X,$,W,J);if(Q)return Q;let Y=O?[{storagePath:H_(O),projectPath:O}]:await this.listAllProjectStorageDirectories(),Z=[];for(let V of Y){let L;try{L=await D_(V.storagePath)}catch(G){if(G.code==="ENOENT")continue;throw G}for(let G of L){if(!G.endsWith(".jsonl"))continue;let B=G.slice(0,-6),U=N.join(V.storagePath,G);try{let H=await this.readLocalCatalogSessionMetadata(U,B,V.projectPath);if(!H)continue;if(O!==void 0&&H.projectPath!==O){S_.warn(`[SessionService] Skipping out-of-scope session transcript: ${B}`);continue}if(!X&&H.relationType==="subagent")continue;if(!qX(H,J))continue;Z.push(await this.reconcileInterruptedTask(H))}catch(H){let A=H.code;if(A==="ENOENT")continue;if(A)throw H;if(H instanceof w)throw H;S_.warn(`[SessionService] Skipping invalid session transcript: ${B}`)}}}return X1(Z,W)}static async listAllProjectStorageDirectories(){let _=N.join(l(),"projects"),X;try{X=await D_(_,{withFileTypes:!0,encoding:"utf8"})}catch($){if($.code==="ENOENT")return[];throw $}return X.filter(($)=>$.isDirectory()).map(($)=>({storagePath:N.join(_,$.name),projectPath:P2($.name)}))}static async listRemoteSessionScopes(_){if(_.descriptor){let $=p(_.descriptor.collisionIdentity);try{return await c($,async()=>[{hostStateRoot:$,descriptor:_.descriptor}])}catch(W){if(W.code==="ENOENT")return[];throw F(W)}}return(await $1()).map(($)=>({hostStateRoot:String($)}))}static async scanRemoteStoredSessions(_){let X=await this.scanRemoteStoredSessionsFromProjection(_);if(X)return X;let $=await this.listRemoteSessionScopes(_),W=[];for(let J of $)await c(J.hostStateRoot,async(O)=>{let Q;try{Q=await D_(String(O))}catch(Y){if(Y.code==="ENOENT")return;throw F(Y)}for(let Y of Q){if(!Y.endsWith(".jsonl"))continue;let Z=Y.slice(0,-6);if(!g_(Z))continue;let V=m(O,Z),L;try{L=await this.readRemoteStoredSessionMetadata(V,Z,J.hostStateRoot,O,_.descriptor)}catch(G){if(G.code==="ENOENT")continue;if(G instanceof Error&&G.message)throw F(G);throw G}if(!L)continue;if(!_.includeSubagents&&L.relationType==="subagent")continue;W.push(L)}});return g2(W,_.archived)}static async scanRemoteStoredSessionsFromProjection(_){try{let X=await I_();if(!X)return null;if(_.descriptor)await a2(X,this.projectionDeriver(),p(_.descriptor.collisionIdentity));else await t2(X,this.projectionDeriver());let $=["source_kind = 'acp-remote'"],W=[];if(_.descriptor)$.push("project_path=?"),W.push(p(_.descriptor.collisionIdentity));let J=$.length>0?` WHERE ${$.join(" AND ")}`:"",O=X.prepare(`SELECT metadata_json, is_subagent FROM sessions${J}`).all(...W),Q=[];for(let L of O){if(!_.includeSubagents&&L.is_subagent===1)continue;let G=j(JSON.parse(L.metadata_json),void 0);if(_.descriptor&&!w_(G.remoteWorkspace,_.descriptor))continue;Q.push(G)}let Y=_.descriptor,Z=Y?Q.filter((L)=>w_(L.remoteWorkspace,Y)):Q,V=await Promise.all(Z.map((L)=>this.reconcileInterruptedTask(L,"acp-remote")));return g2(V.map((L)=>j(L)),_.archived)}catch(X){throw F(X)}}static toRemoteCatalogEntries(_){return _.flatMap((X)=>{if(!X.remoteWorkspace)return[];return[{...X,workspaceIdentity:X.remoteWorkspace.exactIdentity}]})}static async readStoredSessionMetadata(_,X,$,W="local",J){if(W==="acp-remote"){if(!J||String(J)!==$)throw new w;let Q=m(J,X);if(_!==Q)throw new w}let O=await this.readStoredSessionMetadataWithoutReconciliation(_,X,$);if(W==="acp-remote")j(O);else if(O.projectPath!==$||O.remoteWorkspace)return O;return this.reconcileInterruptedTask(O,W,J)}static async readStoredSessionMetadataWithoutReconciliation(_,X,$){let W=await Z_(_,"utf-8"),J=this.parseStoredSession(W,X);return this.projectMetadataFromEntries(J,X,$,_)}static async readLocalCatalogSessionMetadata(_,X,$){let W=await Z_(_,"utf-8"),J=this.parseStoredSession(W,X),O=this.getSessionCreatedEntry(J,X);if(Object.hasOwn(O.data,"remoteWorkspace")){try{r(O.data.remoteWorkspace)}catch(Q){throw F(Q)}return}return this.projectMetadataFromEntries(J,X,$,_)}static async readRemoteStoredSessionMetadata(_,X,$,W,J){if(String(W)!==$||_!==m(W,X))throw new w;await n(W,_);let O=await Z_(_,"utf-8"),Q=this.parseStoredSession(O,X);this.validateSessionWorkspace(Q,X,$);let Y=j(this.projectMetadataFromEntries(Q,X,$,_));if(J&&!w_(Y.remoteWorkspace,J))return;return j(await this.reconcileInterruptedTask(Y,"acp-remote",W),Y.remoteWorkspace)}static async reconcileInterruptedTask(_,X="local",$){let W=_.taskOwnerPid;if(_.taskStatus!=="running"||W===void 0)return _;if(X==="acp-remote"){if($)return this.reconcileInterruptedTaskInScope(_,W,$);return c(_.projectPath,async(J)=>this.reconcileInterruptedTaskInScope(_,W,J))}return this.reconcileInterruptedTaskInScope(_,W)}static async reconcileInterruptedTaskInScope(_,X,$){let W=$?j(_).remoteWorkspace:void 0;if($){let Y=m($,_.sessionId);if(_.projectPath!==String($)||_.filePath!==Y)throw new w;await n($,_.filePath)}let J;try{J=$?await h.acquireRemote(_.sessionId,$):await h.acquire(_.sessionId,_.projectPath)}catch(Y){if(!(Y instanceof X_))throw Y;let Z=await Z_(_.filePath,"utf-8"),V=this.projectMetadataFromEntries(this.parseStoredSession(Z,_.sessionId),_.sessionId,_.projectPath,_.filePath);return W?j(V,W):V}let O=new v(_.filePath),Q;try{try{await O.appendValidated((Z)=>{let V=this.projectMetadataFromEntries(Z,_.sessionId,_.projectPath,_.filePath);if(W)j(V,W);if(V.taskStatus!=="running"||V.taskOwnerPid!==X)throw new U1;let L=new Date().toISOString(),G={id:i(),sessionId:_.sessionId,timestamp:L,type:"session_updated",cwd:_.projectPath,...$?{projectPath:_.projectPath}:{},...$?{}:{gitBranch:L_(_.projectPath)},version:__(),data:{sessionId:_.sessionId,taskStatus:"interrupted",taskStatusReason:"Task owner process exited before completion",taskCompletedAt:L,taskOwnerPid:null,taskQueuePosition:null,taskQueueDepth:null,updatedAt:L}};return Q=[...Z,G],G})}catch(Z){if(!(Z instanceof U1))throw Z}if(!Q){let Z=await Z_(_.filePath,"utf-8");Q=this.parseStoredSession(Z,_.sessionId)}let Y=this.projectMetadataFromEntries(Q,_.sessionId,_.projectPath,_.filePath);return W?j(Y,W):Y}finally{await J.release()}}static projectMetadataFromEntries(_,X,$,W){if(_.length===0)throw Error(`Empty session transcript: ${X}`);let J=this.getSessionCreatedEntry(_,X);if(Object.hasOwn(J.data,"remoteWorkspace"))this.validateRemoteSessionCreationRecord(_,J,X,$);let O=_.reduce((b,E0)=>E0.type==="session_updated"?{...b,...E0.data}:b,{...J.data}),Q=e(_),Y=s1(t1(Q)),V=e_(Q).at(-1),L=Q.findLastIndex((b)=>b.type==="review_started"&&b.data.reviewId===V?.start.reviewId||b.type==="review_completed"&&b.data.reviewId===V?.start.reviewId),G=Q.findLastIndex((b)=>(b.type==="session_created"||b.type==="session_updated")&&Object.hasOwn(b.data,"taskStatus")),B=V!==void 0&&L>G,U=B?V.completion===void 0?"running":V.completion.status==="completed"||V.completion.status==="stale"?"completed":V.completion.status==="aborted"?"cancelled":V.completion.status==="interrupted"?"interrupted":"failed":void 0,H=Q.filter((b)=>b.type==="message_created"&&["user","assistant"].includes(b.data.role)).length,A=Q.some((b)=>b.type==="part_created"&&b.data.partType==="tool_result"&&typeof b.data.payload.error==="string"),z=D2.has(O.taskStatus)?O.taskStatus:void 0,D=U??z??(A?"failed":"completed"),t=typeof O.taskOwnerPid==="number"&&Number.isInteger(O.taskOwnerPid)&&O.taskOwnerPid>0?O.taskOwnerPid:void 0,k=B1.has(O.taskIsolation)?O.taskIsolation:void 0,y=typeof O.taskSourceProjectPath==="string"&&N.isAbsolute(O.taskSourceProjectPath)?N.resolve(O.taskSourceProjectPath):void 0,u=J.cwd;if(u!==void 0&&!N.isAbsolute(u))throw Error(`Session catalog cwd must be absolute: ${X}`);let R=u===void 0?$:N.resolve(u),x=this.parseRemoteWorkspaceFromCreated(J,R),f=R2(O.taskWorktree),q=f?.sessionId===X&&N.resolve(f.workspaceRoot)===R?f:void 0,B_=x2(O.taskDiffStat),S=b2(O.taskDispatch),I=U0.has(O.taskPriority)?O.taskPriority:S?.taskPriority,U_=H0.has(O.taskKind)?O.taskKind:S?.taskKind,p_=typeof O.taskDueAt==="string"&&Number.isFinite(Date.parse(O.taskDueAt))?new Date(O.taskDueAt).toISOString():S?.taskDueAt,N0=typeof O.taskModelId==="string"&&O.taskModelId.trim()?O.taskModelId:S?.modelId,C1=typeof O.selectedModelId==="string"&&O.selectedModelId.trim()?O.selectedModelId:N0,q1=B0(O.permissionMode)?O.permissionMode:S?.permissionMode,K1=h_(O.reasoningEffort)?O.reasoningEffort:S?.reasoningEffort,M1=u_(O.serviceTier)?O.serviceTier:S?.serviceTier,T1=P_(O.responseVerbosity)?O.responseVerbosity:S?.responseVerbosity,c_=l_(O.communicationStyle)?O.communicationStyle:S?.communicationStyle,C0=Object.hasOwn(O,"communicationStyleDigest")?typeof O.communicationStyleDigest==="string"&&/^[a-f0-9]{64}$/.test(O.communicationStyleDigest)?O.communicationStyleDigest:void 0:c_===S?.communicationStyle?S?.communicationStyleDigest:void 0,q0=Object.hasOwn(O,"projectInstructionsDigest")?typeof O.projectInstructionsDigest==="string"&&/^[a-f0-9]{64}$/.test(O.projectInstructionsDigest)?O.projectInstructionsDigest:void 0:S?.projectInstructionsDigest,K0=N1(O.archivedAt)?O.archivedAt:void 0,g=k2(O.taskRetriedFrom),A1=w2(O.taskDelivery),M0=typeof O.taskQueuePosition==="number"&&Number.isInteger(O.taskQueuePosition)&&O.taskQueuePosition>0?O.taskQueuePosition:void 0,x_=typeof O.taskQueueDepth==="number"&&Number.isInteger(O.taskQueueDepth)&&O.taskQueueDepth>=0?O.taskQueueDepth:void 0,T0=typeof O.taskConcurrencyLimit==="number"&&Number.isInteger(O.taskConcurrencyLimit)&&O.taskConcurrencyLimit>0?O.taskConcurrencyLimit:void 0,T_=B?V?.completion?V.completion.status==="completed"?void 0:`Code review ${I0(V.completion.status)}`:`Reviewing ${V?.start.target.label??"changes"}`:void 0,A0=B?D==="failed"&&T_?p0(T_):void 0:c0(O.taskFailure)?O.taskFailure:D==="failed"&&typeof O.taskStatusReason==="string"?p0(O.taskStatusReason):void 0;return{sessionId:X,projectPath:R,remoteWorkspace:x,...J.gitBranch!==void 0?{gitBranch:J.gitBranch}:{},rootId:O.rootId||X,parentId:O.parentId,relationType:O.relationType,resumedFrom:O.resumedFrom,rootAgentId:O.rootAgentId,resumeDepth:O.resumeDepth,title:O.title,agentType:O.agentType,model:O.model,selectedModelId:C1,permissionMode:q1,reasoningEffort:K1,serviceTier:M1,responseVerbosity:T1,communicationStyle:c_,communicationStyleDigest:C0,projectInstructionsDigest:q0,pendingInteraction:Y,taskStatus:D,taskStatusReason:A0?.message??T_??(typeof O.taskStatusReason==="string"?O.taskStatusReason:void 0),taskFailure:A0,taskStartedAt:B?V?.start.startedAt:typeof O.taskStartedAt==="string"?O.taskStartedAt:void 0,taskCompletedAt:B?V?.completion?.completedAt:typeof O.taskCompletedAt==="string"?O.taskCompletedAt:void 0,taskPromptSummary:B?V?EX(V.start.target):"/review uncommitted":typeof O.taskPromptSummary==="string"?O.taskPromptSummary:void 0,taskPriority:I,taskKind:U_,taskDueAt:p_,taskModelId:N0,taskRetryAvailable:S!==void 0,taskRetriedFrom:g,taskDelivery:A1,taskIsolation:k,taskSourceProjectPath:y,taskWorktreePath:q?.worktreeRoot,taskWorktreeBranch:q?.branch,taskBaseCommit:q?.baseCommit,taskDiffStat:B_,taskQueuePosition:M0,taskQueueDepth:x_,taskConcurrencyLimit:T0,archivedAt:K0,taskOwnerPid:B?void 0:t,taskWorktree:q,taskDispatch:S,messageCount:H,firstMessageTime:_[0].timestamp,lastMessageTime:_.at(-1).timestamp,hasErrors:A||D==="failed",filePath:W}}static parseRemoteWorkspaceFromCreated(_,X){if(!Object.hasOwn(_.data,"remoteWorkspace"))return;let $;try{$=r(_.data.remoteWorkspace)}catch(J){throw F(J)}if(p($.collisionIdentity)!==X)throw new w;return $}static async assertRemoteSessionWritableInScope(_,X,$,W){let J=m(W,_),O;try{await n(W,J),O=await this.readStableSessionSnapshot(J,_)}catch(Y){throw F(Y)}let Q;try{Q=this.projectMetadataFromEntries(O,_,X,J)}catch(Y){throw F(Y)}if(Q.archivedAt)throw new a(_,Q.archivedBySessionId??_);if(!Q.remoteWorkspace)throw new w;if(!w_(Q.remoteWorkspace,$))throw new v_;return this.toPublicMetadata(Q)}static async readValidatedRemoteSessionSnapshot(_,X,$,W){W?.throwIfAborted();let J;try{if(T(_),J=r($),p(J.collisionIdentity)!==X)throw new w}catch(O){throw F(O)}try{return await c(X,async(O)=>{W?.throwIfAborted();let Q=m(O,_);await n(O,Q);let Y=await this.readStableSessionSnapshot(Q,_,3,W),Z=this.projectMetadataFromEntries(Y,_,X,Q);return j(Z,J),Y})}catch(O){if(W?.aborted)throw O;if(O instanceof v_)throw O;throw F(O)}}static toPublicMetadata(_){let{filePath:X,taskOwnerPid:$,taskWorktree:W,taskDispatch:J,...O}=_;return O}static getSessionFilePath(_,X){return P(_,X)}static getSessionCreatedEntry(_,X){let $=_.find((W)=>W.type==="session_created");if(!$)throw new X4(X);return $}static validateRemoteSessionCreationRecord(_,X,$,W){if(Z0(_,$,W)!==X)throw new w}static resolveCatalogWorkspace(_){if(!N.isAbsolute(_))throw Error("Session catalog cwd must be absolute");return G0(_)}static validateSessionWorkspace(_,X,$){let W=this.getSessionCreatedEntry(_,X);if(W.data.sessionId!==X)throw Error(`Session creation record sessionId mismatch: ${X}`);if(!N.isAbsolute(W.cwd)||N.resolve(W.cwd)!==$)throw Error(`Session creation record cwd mismatch: ${X}`)}static resolveForkWorkspace(_){if(!N.isAbsolute(_))throw Error("Fork workspace paths must be absolute");return G0(_)}static parseStoredSession(_,X){return c2(_,`session ${X}`)}static isCorruptSessionJSONLError(_){return _ instanceof Error&&_.message.startsWith("Invalid session JSONL ")}static sanitizeStoredSessionError(_,X){if(!this.isCorruptSessionJSONLError(_)||!(_ instanceof Error))return _;let $=_.message.match(/ at line (\d+)$/)?.[1];return Error(`Invalid session JSONL in session ${X}${$?` at line ${$}`:""}`,{cause:_.cause})}static async readStableSessionSnapshot(_,X,$=3,W){for(let J=0;J<$;J+=1){W?.throwIfAborted();let O=await m_.stat(_,W),Q=await m_.readFile(_,W),Y=this.parseStoredSession(Q,X),Z=await m_.stat(_,W);if(W?.throwIfAborted(),O.size===Z.size&&O.mtimeNs===Z.mtimeNs&&O.dev===Z.dev&&O.ino===Z.ino)return Y}throw new H1}}function I2(_){if(_.length===1&&_[0]?.type==="text")return _[0].text;return[..._]}
|
|
93
|
+
LIMIT ?`).all(...J,_.limit+1),Q=await Promise.all(O.map(async(Z)=>{let V=JSON.parse(Z.metadata_json);if(V.remoteWorkspace)throw Error("Local projection contains remote session metadata");if(Z.archive_root_id&&Z.effective_archived_at)return this.reconcileInterruptedTask({...V,archivedAt:Z.effective_archived_at,archivedBySessionId:Z.archive_root_id});let{archivedAt:L,archivedBySessionId:G,...B}=V;return this.reconcileInterruptedTask(B)})),Y=Z1(Q,_);return{sessions:Y.sessions.map((Z)=>this.toPublicMetadata(Z)),nextCursor:Y.nextCursor}}catch{return null}}static async listRemoteSessionPageFromProjection(_){d2(_);try{let X=await this.scanRemoteStoredSessionsFromProjection(_);if(!X)return null;let $=G1(this.toRemoteCatalogEntries(X).sort(V0),_);return{sessions:$.sessions.map((W)=>this.toPublicMetadata(W)),nextCursor:$.nextCursor}}catch(X){throw F(X)}}static async listSessions(_={}){let X=J1(_),$=i2(_),W=await this.scanStoredSessions(X.cwd??void 0,X.includeSubagents,0,X.archived,$),J=new Set;return W.sort(Y1).flatMap((O)=>{let Q=`${O.projectPath}\x00${O.sessionId}`;if(J.has(Q))return[];return J.add(Q),[this.toPublicMetadata(O)]})}static async listRemoteSessions(_={}){let X=Q1(_.descriptor!==void 0?{..._,descriptor:y2(_.descriptor)}:_),$=await this.scanRemoteStoredSessions(X),W=new Set;return this.toRemoteCatalogEntries($).sort(V0).flatMap((J)=>{let O=`${J.projectPath}\x00${J.sessionId}`;if(W.has(O))return[];return W.add(O),[this.toPublicMetadata(J)]})}static async collectStaleEmptySessions(_={}){let X=_.now??Date.now(),$=_.olderThanMs??TX;if(!Number.isFinite($)||$<0)throw Error("Stale empty session age must be a non-negative number");let W=_.projectPath?[{storagePath:H_(this.resolveCatalogWorkspace(_.projectPath)),projectPath:this.resolveCatalogWorkspace(_.projectPath)}]:await this.listAllProjectStorageDirectories(),J=0;for(let O of W){let Q;try{Q=await D_(O.storagePath)}catch(Y){if(Y.code==="ENOENT")continue;throw Y}for(let Y of Q){if(!Y.endsWith(".jsonl"))continue;let Z=Y.slice(0,-6);if(!g_(Z))continue;let V=N.join(O.storagePath,Y);try{let G=await L0(V);if(X-G.mtimeMs<$)continue;if(await Promise.all([L0(N.join(O.storagePath,`${Z}.inbox.json`)).then(()=>!0).catch(()=>!1),L0(N_(O.projectPath,Z)).then(()=>!0).catch(()=>!1)]).then((U)=>U.some(Boolean)))continue}catch(G){if(G.code==="ENOENT")continue;throw G}let L;try{L=await h.acquire(Z,O.projectPath)}catch(G){if(G instanceof X_)continue;throw G}try{if(!await new v(V).deleteValidated((B)=>B.length===1&&B[0]?.type==="session_created"&&B[0].data.relationType!=="subagent"))continue;J++,await R_(N.join(O.storagePath,`${Z}.inbox.json`),{force:!0}),await R_(N_(O.projectPath,Z),{force:!0}),await this.removeFromProjection(Z,O.projectPath)}catch(G){S_.warn(`[SessionService] Skipping stale empty session cleanup: ${Z}`,G)}finally{await L.release()}}}return J}static async findSessionMetadata(_,X){if(T(_),X!==void 0){let W=this.resolveCatalogWorkspace(X),J=this.getSessionFilePath(W,_);try{let O=await this.readStoredSessionMetadata(J,_,W);if(O.projectPath!==W)return;if(!O.parentId||O.archivedAt)return this.toPublicMetadata(X1([O],null)[0]??O);let Q=await this.scanStoredSessions(W,!0,0,null);return this.toPublicMetadata(Q.find((Y)=>Y.sessionId===_)??O)}catch(O){if(O.code==="ENOENT")return;throw O}}let $=(await this.scanStoredSessions(void 0,!0,0,null)).filter((W)=>W.sessionId===_);if($.length===0)return;if($.length>1)throw Error(`Ambiguous session ID: ${_}`);return this.toPublicMetadata($[0])}static async loadSession(_,X,$={}){try{if(X){let J=this.resolveCatalogWorkspace(X),O=this.getSessionFilePath(J,_);try{return await this.loadSessionFromFile(O,_,J,$)}catch(Q){if(Q.code==="ENOENT")throw Error(`未找到会话: ${_}`);throw Q}}let W=(await this.scanStoredSessions(void 0,!0,0,null)).find((J)=>J.sessionId===_);if(!W)throw Error(`未找到会话: ${_}`);return await this.loadSessionFromFile(W.filePath,_,void 0,$)}catch(W){throw S_.error(`[SessionService] 加载会话失败 (${_}):`,W),W}}static async loadSessionModelContext(_,X){try{if(X){let W=this.resolveCatalogWorkspace(X),J=this.getSessionFilePath(W,_);try{return await this.loadSessionModelContextFromFile(J,_,W)}catch(O){if(O.code==="ENOENT")throw Error(`未找到会话: ${_}`);throw O}}let $=(await this.scanStoredSessions(void 0,!0,0,null)).find((W)=>W.sessionId===_);if(!$)throw Error(`未找到会话: ${_}`);return await this.loadSessionModelContextFromFile($.filePath,_)}catch($){throw S_.error(`[SessionService] 加载模型上下文失败 (${_}):`,$),$}}static async loadRemoteSession(_,X,$){let W=await this.readValidatedRemoteSessionSnapshot(_,X,$);return this.convertJSONLToMessages(W)}static async loadRemoteSessionModelContext(_,X,$){let W=await this.readValidatedRemoteSessionSnapshot(_,X,$);return this.convertJSONLToModelContext(W)}static async readValidatedLocalSurfaceSnapshot(_,X,$){T(_);let W=this.resolveCatalogWorkspace(X),J=P(W,_),O=await this.readStableSessionSnapshot(J,_,3,$);this.validateSessionWorkspace(O,_,W);let Q=this.projectMetadataFromEntries(O,_,W,J);if(Q.remoteWorkspace)throw new w;return{entries:O,summary:V1(Q)}}static async readValidatedRemoteSurfaceSnapshot(_,X){let $=await this.readValidatedRemoteSessionSnapshot(_.sessionId,_.hostStateRoot,_.descriptor,X);return c(_.hostStateRoot,async(W)=>{X?.throwIfAborted();let J=m(W,_.sessionId),O=j(this.projectMetadataFromEntries($,_.sessionId,_.hostStateRoot,J),_.descriptor);return{entries:$,summary:V1(O,_.workspaceRef)}})}static async listValidatedRemoteSurfaceCandidates(_){let X=[];for(let $ of await $1())_?.throwIfAborted(),await c(String($),async(W)=>{for(let J of await D_(String(W))){if(_?.throwIfAborted(),!J.endsWith(".jsonl"))continue;let O=J.slice(0,-6);if(!g_(O))continue;let Q=m(W,O);await n(W,Q);let Y=await this.readStableSessionSnapshot(Q,O,3,_),Z=j(this.projectMetadataFromEntries(Y,O,String(W),Q));await this.reconcileInterruptedTask(Z,"acp-remote",W);let V=await l2(W,Z.remoteWorkspace);_?.throwIfAborted(),X.push({descriptor:Z.remoteWorkspace,hostStateRoot:String(W),sessionId:O,workspaceRef:V})}});return X}static async listValidatedLocalSurfaceCandidates(_){let X=new Map;for(let $ of await this.listAllProjectStorageDirectories()){_?.throwIfAborted();let W;try{W=await D_($.storagePath)}catch(J){if(J.code==="ENOENT")continue;throw J}for(let J of W){if(_?.throwIfAborted(),!J.endsWith(".jsonl"))continue;let O=J.slice(0,-6);if(!g_(O))continue;let Q=N.join($.storagePath,J);try{let Y=await this.readStableSessionSnapshot(Q,O,3,_),Z=this.getSessionCreatedEntry(Y,O);if(Z.data.sessionId!==O||!N.isAbsolute(Z.cwd)||Object.hasOwn(Z.data,"remoteWorkspace"))continue;let V;try{V=G0(Z.cwd)}catch{continue}if(P(V,O)!==Q)continue;await this.reconcileInterruptedTask(this.projectMetadataFromEntries(Y,O,V,Q)),X.set(`${V}\x00${O}`,{projectPath:V,sessionId:O})}catch(Y){if(_?.aborted)throw Y;if(Y.code==="ENOENT")continue;if(Y instanceof w)throw Y}}}return[...X.values()]}static async exportSessionMarkdown(_,X,$={}){T(_);let W=this.resolveCatalogWorkspace(X),J=P(W,_),O;try{O=await this.readStableSessionSnapshot(J,_)}catch(Z){throw this.sanitizeStoredSessionError(Z,_)}let Q=this.projectMetadataFromEntries(O,_,W,J);if(Q.projectPath!==W)throw Error(`Session export workspace mismatch: ${_}`);let Y=Q.archivedAt;if(!Y&&Q.parentId)Y=(await this.findArchivedAncestor(Q.parentId,W))?.archivedAt;return N2(O,{...Q,archivedAt:Y},$)}static async listRewindCheckpoints(_,X){T(_);let $=this.resolveCatalogWorkspace(X),W=P($,_),J=await this.readStableSessionSnapshot(W,_);this.validateSessionWorkspace(J,_,$);let O=new W0({sessionId:_,workspaceRoot:$});await O.initialize();let Q=p2(J),Y=[];for(let Z of Q){let V=W1(J,Z.messageId),L=await O.previewRewind(V.snapshotMessageIds);Y.push({...Z,fileCount:L.files.length})}return Y}static async rewindSession(_,X,$){T(_);let W=this.resolveCatalogWorkspace(X);await this.assertSessionWritable(_,W);let J=P(W,_),O=new v(J),Q;try{await O.appendValidatedAsync(async(Y)=>{this.validateSessionWorkspace(Y,_,W);let Z=W1(Y,$.targetMessageId),V=new W0({sessionId:_,workspaceRoot:W});await V.initialize();let L=await V.previewRewind(Z.snapshotMessageIds),G=$.mode==="conversation"?await V.commitSnapshots(Z.snapshotMessageIds):await V.rewindSnapshots(Z.snapshotMessageIds),B=new Date().toISOString(),U={id:i(),sessionId:_,timestamp:B,type:"session_rewound",cwd:W,gitBranch:L_(W),version:__(),data:{rewindId:i(),targetMessageId:$.targetMessageId,mode:$.mode,restoredFiles:$.mode==="conversation"?[]:G.files,createdAt:B}},H=e([...Y,U]);return Q={checkpoint:{...Z.checkpoint,fileCount:L.files.length},mode:$.mode,removedTurns:Z.removedTurns,restoredFiles:U.data.restoredFiles,messages:this.convertJSONLToMessages(H)},U})}catch(Y){throw this.sanitizeStoredSessionError(Y,_)}if(!Q)throw Error(`Session rewind did not produce a result: ${_}`);for(let Y of Q.restoredFiles)V_.getInstance().clearFileRecord(Y);return Q}static async forkSession(_,X){T(_);let $=X.newSessionId??`fork-${Date.now()}-${i(8)}`;T($);let W=X.remote;if(W)return this.forkRemoteSession(_,$,X.sourceProjectPath,X.targetProjectPath,W.expectedDescriptor);let J=this.resolveForkWorkspace(X.sourceProjectPath),O=this.resolveForkWorkspace(X.targetProjectPath);if(J!==O)throw Error("Session forks must stay in the source workspace");let Q=P(J,_),Y=await this.readStableSessionSnapshot(Q,_),Z=this.getSessionCreatedEntry(Y,_);if(Z.data.sessionId!==_)throw Error("Fork source session_created.data.sessionId must match the requested session ID");if(!N.isAbsolute(Z.cwd)||N.resolve(Z.cwd)!==J)throw Error("Fork source session_created.cwd must resolve to the requested source workspace");let V=this.projectMetadataFromEntries(Y,_,J,Q);if(V.archivedAt)throw new a(_,_);if(V.parentId){let k=await this.findArchivedAncestor(V.parentId,J);if(k)throw new a(_,k.sessionId)}let L=e(Y),G=new Date().toISOString(),B=Z.data.rootId||_,U=L_(O),H=__(),A=this.buildForkChildEntries({sourceEntries:L,sourceCreated:Z,sourceSessionId:_,targetSessionId:$,targetProjectPath:O,rootId:B,version:H,now:G,target:{kind:"local",gitBranch:U}}),z=P(O,$),D=!1;try{await new v(z).createExclusive(A),D=!0;let k=b0(L.flatMap((y)=>y.type==="message_created"?[y.data.metadata]:[]));if(k.length>0){let y=new O_(J,_,{storageRoot:l()}),u=new O_(O,$,{storageRoot:l()});await y.copyReferencedTo(k,u)}}catch(k){if(D)await new v(z).delete().catch(()=>{return}),await new O_(O,$,{storageRoot:l()}).removeAll().catch(()=>{return});if(k.code==="EEXIST")throw Error(`Fork session already exists: ${$}`,{cause:k});throw k}let t=this.projectMetadataFromEntries(A,$,O,z);return{sessionId:$,parentSessionId:_,projectPath:O,messages:this.convertJSONLToMessages(A),metadata:this.toPublicMetadata(t)}}static async forkRemoteSession(_,X,$,W,J){let O;try{O=r(J)}catch(Y){throw F(Y)}let Q=p(O.collisionIdentity);if($!==Q||W!==Q)throw new w;return c(Q,async(Y)=>{let Z=m(Y,_);try{await n(Y,Z)}catch(I){throw F(I)}let V;try{V=await this.readStableSessionSnapshot(Z,_)}catch(I){throw j2(I)}let L=Z0(V,_,Q),G=j(this.projectMetadataFromEntries(V,_,Q,Z),O);if(G.archivedAt)throw new a(_,_);if(G.parentId){let I=await this.findRemoteArchivedAncestor(G.parentId,Y,G.remoteWorkspace);if(I)throw new a(_,I.sessionId)}let B=e(V),U=new Date().toISOString(),H=__(),A=G.rootId||_,z=this.buildForkChildEntries({sourceEntries:B,sourceCreated:L,sourceSessionId:_,targetSessionId:X,targetProjectPath:Q,rootId:A,version:H,now:U,target:{kind:"remote",descriptor:G.remoteWorkspace}}),D=m(Y,X),t=!1;try{await new v(D).createExclusive(z),t=!0,await n(Y,D);let I=b0(B.flatMap((U_)=>U_.type==="message_created"?[U_.data.metadata]:[]));if(I.length>0){let U_=new O_(Q,_,{storageRoot:Q}),p_=new O_(Q,X,{storageRoot:Q});await U_.copyReferencedTo(I,p_)}}catch(I){if(t)await new v(D).delete().catch(()=>{return}),await new O_(Q,X,{storageRoot:Q}).removeAll().catch(()=>{return});if(I.code==="EEXIST")throw Error(`Fork session already exists: ${X}`,{cause:I});throw F(I)}let k=j(this.projectMetadataFromEntries(z,X,Q,D),G.remoteWorkspace),{gitBranch:y,taskIsolation:u,taskSourceProjectPath:R,taskWorktreePath:x,taskWorktreeBranch:f,taskBaseCommit:q,taskDiffStat:B_,...S}=this.toPublicMetadata(k);return{sessionId:X,parentSessionId:_,projectPath:Q,messages:this.convertJSONLToMessages(z),metadata:S}})}static async findRemoteArchivedAncestor(_,X,$){let W=new Set,J=_;while(J){if(W.has(J))throw new w;W.add(J),T(J);let O=m(X,J);try{await n(X,O)}catch(Z){if(Z.code==="ENOENT")return;throw F(Z)}let Q;try{Q=await this.readStableSessionSnapshot(O,J)}catch(Z){throw j2(Z)}Z0(Q,J,String(X));let Y=j(this.projectMetadataFromEntries(Q,J,String(X),O));if(!w_(Y.remoteWorkspace,$))return;if(Y.archivedAt)return{sessionId:Y.sessionId,archivedAt:Y.archivedAt};J=Y.parentId}return}static buildForkChildEntries(_){let{sourceEntries:X,sourceCreated:$,sourceSessionId:W,targetSessionId:J,targetProjectPath:O,rootId:Q,version:Y,now:Z,target:V}=_,L=V.kind==="remote"?{projectPath:O}:{gitBranch:V.gitBranch},G=V.kind==="remote"?{remoteWorkspace:V.descriptor}:{taskIsolation:"local",taskSourceProjectPath:O},B=V.kind==="remote"?{}:{taskIsolation:"local",taskSourceProjectPath:O,taskWorktree:null,taskDiffStat:null},{status:U,taskStatus:H,taskStatusReason:A,taskFailure:z,taskStartedAt:D,taskCompletedAt:t,taskOwnerPid:k,taskPromptSummary:y,taskPriority:u,taskKind:R,taskDueAt:x,taskDispatch:f,taskModelId:q,taskRetriedFrom:B_,taskDelivery:S,taskIsolation:I,taskSourceProjectPath:U_,taskWorktree:p_,taskDiffStat:N0,taskQueuePosition:C1,taskQueueDepth:q1,taskConcurrencyLimit:K1,pendingInteraction:M1,remoteWorkspace:T1,...c_}=$.data,C0={id:i(),sessionId:J,...L,timestamp:Z,type:"session_created",cwd:O,version:Y,data:{...c_,sessionId:J,rootId:Q,parentId:W,relationType:"fork",taskStatus:"completed",taskCompletedAt:Z,...G,createdAt:Z,updatedAt:Z}},q0=X.filter((g)=>g.type!=="session_created"&&g.type!=="token_budget_handoff_recorded"&&g.type!=="inbox_acknowledged"&&g.type!=="interaction_requested"&&g.type!=="interaction_responded"&&g.type!=="interaction_recovered"&&g.type!=="review_started"&&g.type!=="review_completed").map((g)=>{let{gitBranch:A1,...M0}=g,x_={...V.kind==="remote"?M0:g,id:i(),sessionId:J,...L,cwd:O,version:Y};if(g.type==="session_updated"){let{status:T0,taskStatus:T_,taskStatusReason:A0,taskFailure:b,taskStartedAt:E0,taskCompletedAt:zX,taskOwnerPid:DX,taskPromptSummary:RX,taskPriority:wX,taskKind:xX,taskDueAt:bX,taskDispatch:kX,taskModelId:fX,taskRetriedFrom:jX,taskDelivery:yX,taskIsolation:SX,taskSourceProjectPath:gX,taskWorktree:IX,taskDiffStat:mX,taskQueuePosition:vX,taskQueueDepth:PX,taskConcurrencyLimit:uX,pendingInteraction:hX,remoteWorkspace:lX,...$4}=g.data;return{...x_,type:"session_updated",data:{...$4,sessionId:J,rootId:Q,parentId:W,relationType:"fork"}}}if(g.type==="message_created"){let{inboxMessageId:T0,...T_}=g.data;return{...x_,type:"message_created",data:T_}}return x_}),K0={id:i(),sessionId:J,...L,timestamp:Z,type:"session_updated",cwd:O,version:Y,data:{sessionId:J,rootId:Q,parentId:W,relationType:"fork",taskStatus:"completed",taskStatusReason:null,taskFailure:null,taskStartedAt:null,taskCompletedAt:Z,taskOwnerPid:null,...B,taskDelivery:null,taskQueuePosition:null,taskQueueDepth:null,taskConcurrencyLimit:null,updatedAt:Z}};return[C0,...q0,K0]}static async deleteSession(_,X){if(T(_),X){if(!N.isAbsolute(X))throw Error("Session catalog cwd must be absolute");let W=N.resolve(X),J=this.getSessionFilePath(W,_),O=new v(J),Q;try{Q=await O.deleteValidated((Y)=>{return this.projectMetadataFromEntries(Y,_,W,J).projectPath===W})}catch(Y){if(!this.isCorruptSessionJSONLError(Y))throw Y;Q=await O.delete()}if(!Q)return 0;return await R_(N.join(N.dirname(J),`${_}.inbox.json`),{force:!0}),await R_(N_(W,_),{force:!0}),await new O_(W,_,{storageRoot:l()}).removeAll(),await S0(W,_,l()),await this.removeFromProjection(_,W),1}let $=(await this.scanStoredSessions(void 0,!0)).filter((W)=>W.sessionId===_);if($.length===0)return 0;return await Promise.all($.map(async(W)=>{await new v(W.filePath).delete(),await R_(N.join(N.dirname(W.filePath),`${W.sessionId}.inbox.json`),{force:!0}),await R_(N_(W.projectPath,W.sessionId),{force:!0}),await new O_(W.projectPath,W.sessionId,{storageRoot:l()}).removeAll(),await S0(W.projectPath,W.sessionId,l()),await this.removeFromProjection(W.sessionId,W.projectPath)})),$.length}static async removeFromProjection(_,X){try{let $=await I_();if($)s2($,_,X)}catch{}}static validateTaskMetadataUpdate(_,X){if(_.taskStatus!==void 0&&!D2.has(_.taskStatus))throw Error(`Invalid session task status: ${String(_.taskStatus)}`);if(_.taskOwnerPid!==void 0&&_.taskOwnerPid!==null&&(!Number.isInteger(_.taskOwnerPid)||_.taskOwnerPid<=0))throw Error("Session task owner PID must be a positive integer");if(_.taskPromptSummary!==void 0&&_.taskPromptSummary!==null&&(!_.taskPromptSummary.trim()||_.taskPromptSummary.length>1000))throw Error("Session task prompt summary must contain 1-1000 characters");if(_.taskPriority!==void 0&&_.taskPriority!==null&&!U0.has(_.taskPriority))throw Error("Invalid session task priority");if(_.taskKind!==void 0&&_.taskKind!==null&&!H0.has(_.taskKind))throw Error("Invalid session task kind");if(_.taskDueAt!==void 0&&_.taskDueAt!==null&&!Number.isFinite(Date.parse(_.taskDueAt)))throw Error("Invalid session task due date");if(_.taskFailure!==void 0&&_.taskFailure!==null&&!c0(_.taskFailure))throw Error("Invalid session task failure");if(_.taskDispatch!==void 0&&_.taskDispatch!==null&&!b2(_.taskDispatch))throw Error("Invalid durable task dispatch");if(_.taskModelId!==void 0&&_.taskModelId!==null&&(!_.taskModelId.trim()||_.taskModelId.length>500))throw Error("Invalid session task model ID");if(_.selectedModelId!==void 0&&_.selectedModelId!==null&&(!_.selectedModelId.trim()||_.selectedModelId.length>500))throw Error("Invalid selected session model ID");if(_.permissionMode!==void 0&&_.permissionMode!==null&&!B0(_.permissionMode))throw Error("Invalid session permission mode");if(_.reasoningEffort!==void 0&&_.reasoningEffort!==null&&!h_(_.reasoningEffort))throw Error("Invalid session reasoning effort");if(_.serviceTier!==void 0&&_.serviceTier!==null&&!u_(_.serviceTier))throw Error("Invalid session service tier");if(_.responseVerbosity!==void 0&&_.responseVerbosity!==null&&!P_(_.responseVerbosity))throw Error("Invalid session response verbosity");if(_.communicationStyle!==void 0&&_.communicationStyle!==null&&!l_(_.communicationStyle))throw Error("Invalid session communication style");if(_.communicationStyleDigest!==void 0&&_.communicationStyleDigest!==null&&!/^[a-f0-9]{64}$/.test(_.communicationStyleDigest))throw Error("Invalid session communication style digest");if(_.projectInstructionsDigest!==void 0&&_.projectInstructionsDigest!==null&&!/^[a-f0-9]{64}$/.test(_.projectInstructionsDigest))throw Error("Invalid session project instructions digest");if(_.taskRetriedFrom!==void 0&&_.taskRetriedFrom!==null&&!k2(_.taskRetriedFrom))throw Error("Invalid session task retry source");if(_.taskDelivery!==void 0&&_.taskDelivery!==null&&!w2(_.taskDelivery))throw Error("Invalid session task delivery");if(_.taskIsolation!==void 0&&_.taskIsolation!==null&&!B1.has(_.taskIsolation))throw Error(`Invalid session task isolation: ${String(_.taskIsolation)}`);if(_.taskSourceProjectPath!==void 0&&_.taskSourceProjectPath!==null&&!N.isAbsolute(_.taskSourceProjectPath))throw Error("Session task source project path must be absolute");if(_.taskWorktree!==void 0&&_.taskWorktree!==null){let $=R2(_.taskWorktree);if(!$||$.sessionId!==X||![$.repositoryRoot,$.originalWorkspaceRoot,$.worktreeRoot,$.workspaceRoot].every((W)=>N.isAbsolute(W)))throw Error("Invalid session task worktree metadata")}if(_.taskDiffStat!==void 0&&_.taskDiffStat!==null&&!x2(_.taskDiffStat))throw Error("Invalid session task diff stat");if(_.taskQueuePosition!==void 0&&_.taskQueuePosition!==null&&(!Number.isInteger(_.taskQueuePosition)||_.taskQueuePosition<1))throw Error("Invalid session task queue position");if(_.taskQueueDepth!==void 0&&_.taskQueueDepth!==null&&(!Number.isInteger(_.taskQueueDepth)||_.taskQueueDepth<0))throw Error("Invalid session task queue depth");if(_.taskConcurrencyLimit!==void 0&&_.taskConcurrencyLimit!==null&&(!Number.isInteger(_.taskConcurrencyLimit)||_.taskConcurrencyLimit<1))throw Error("Invalid session task concurrency limit");if(typeof _.taskQueuePosition==="number"&&typeof _.taskQueueDepth==="number"&&_.taskQueuePosition>_.taskQueueDepth)throw Error("Session task queue position exceeds queue depth")}static async createSessionMetadata(_,X,$={}){T(_),C.validateTaskMetadataUpdate($,_);let W=C.resolveCatalogWorkspace(X);if($.taskWorktree&&N.resolve($.taskWorktree.workspaceRoot)!==W)throw Error("Session task worktree must match the catalog workspace");let J=new Date().toISOString(),O={id:i(),sessionId:_,timestamp:J,type:"session_created",cwd:W,gitBranch:L_(W),version:__(),data:{...Y0(_,$,J,!0),sessionId:_,rootId:_,taskStatus:$.taskStatus??"queued",createdAt:J,updatedAt:J}},Q=C.getSessionFilePath(W,_);return await new v(Q).createExclusive([O]),C.toPublicMetadata(C.projectMetadataFromEntries([O],_,W,Q))}static async createRemoteSessionMetadata(_,X,$,W={}){T(_),C.validateTaskMetadataUpdate(W,_);let J;try{J=r($)}catch(Y){throw F(Y)}if(p(J.collisionIdentity)!==X)throw new w;await m2(X);let Q=new Date().toISOString();return c(X,async(Y)=>{let Z=m(Y,_),V={id:i(),sessionId:_,projectPath:X,timestamp:Q,type:"session_created",cwd:X,version:__(),data:{...Y0(_,W,Q,!1),sessionId:_,rootId:_,remoteWorkspace:J,taskStatus:W.taskStatus??"queued",createdAt:Q,updatedAt:Q}};try{await new v(Z).createExclusive([V])}catch(L){if(L.code!=="EEXIST")throw L;return this.assertRemoteSessionWritableInScope(_,X,J,Y)}return C.toPublicMetadata(C.projectMetadataFromEntries([V],_,X,Z))})}static async assertSessionWritable(_,X){let $=await this.findSessionMetadata(_,X);if(!$)throw Error(`Session not found: ${_}`);if($.archivedAt)throw new a(_,$.archivedBySessionId??_);return $}static async assertRemoteSessionWritable(_,X,$){T(_);let W;try{W=r($)}catch(O){throw F(O)}if(p(W.collisionIdentity)!==X)throw new w;return c(X,async(O)=>{return this.assertRemoteSessionWritableInScope(_,X,W,O)})}static async findArchivedAncestor(_,X){let $=new Set,W=_;while(W){if($.has(W))throw Error("Session lineage contains a cycle");$.add(W),T(W);let J=P(X,W),O;try{O=await Z_(J,"utf8")}catch(Y){if(Y.code==="ENOENT")return;throw Y}let Q=this.projectMetadataFromEntries(this.parseStoredSession(O,W),W,X,J);if(Q.projectPath!==X)throw Error("Session lineage escapes the requested workspace");if(Q.archivedAt)return{sessionId:Q.sessionId,archivedAt:Q.archivedAt};W=Q.parentId}return}static async listSessionArchiveMembers(_,X){T(_);let $=this.resolveCatalogWorkspace(X),W=await this.scanStoredSessions($,!0,0,null);if(!W.some((Q)=>Q.sessionId===_))throw Error(`Session not found: ${_}`);let J=new Set([_]),O=!0;while(O){O=!1;for(let Q of W)if(Q.parentId&&J.has(Q.parentId)&&!J.has(Q.sessionId))J.add(Q.sessionId),O=!0}return W.filter((Q)=>J.has(Q.sessionId)).sort((Q,Y)=>Q.sessionId.localeCompare(Y.sessionId)).map((Q)=>this.toPublicMetadata(Q))}static async archiveSession(_,X){T(_);let $=this.resolveCatalogWorkspace(X),W=await this.findSessionMetadata(_,$);if(!W)throw Error(`Session not found: ${_}`);if(W.archivedAt)return W;let J=await this.listSessionArchiveMembers(_,$),O=J.find((Y)=>Y.taskStatus==="queued"||Y.taskStatus==="running");if(O)throw new Q_(`Stop session ${O.sessionId} before archiving this session tree`);let Q=[];try{for(let L of J)Q.push(await h.acquire(L.sessionId,$));let Y=P($,_),Z=new v(Y),V=[];return await Z.appendValidated((L)=>{let G=this.projectMetadataFromEntries(L,_,$,Y);if(G.archivedAt)throw new Q_(`Session archive state changed concurrently: ${_}`);if(G.taskStatus==="queued"||G.taskStatus==="running")throw new Q_(`Stop session ${_} before archiving it`);let B=new Date().toISOString(),U={id:i(),sessionId:_,timestamp:B,type:"session_updated",cwd:$,gitBranch:L_($),version:__(),data:{sessionId:_,archivedAt:B,updatedAt:B}};return V=[...L,U],U}),this.toPublicMetadata({...this.projectMetadataFromEntries(V,_,$,Y),archivedBySessionId:_})}catch(Y){if(Y instanceof Q_)throw Y;if(Y instanceof X_)throw new Q_(Y.message);throw this.sanitizeStoredSessionError(Y,_)}finally{for(let Y of Q.reverse())await Y.release()}}static async unarchiveSession(_,X){T(_);let $=this.resolveCatalogWorkspace(X),W=await this.findSessionMetadata(_,$);if(!W)throw Error(`Session not found: ${_}`);if(!W.archivedAt)return W;if(W.archivedBySessionId&&W.archivedBySessionId!==_)throw new Q_(`Unarchive ancestor ${W.archivedBySessionId} to restore session ${_}`);let J;try{J=await h.acquire(_,$);let O=P($,_),Q=new v(O),Y=[];return await Q.appendValidated((Z)=>{if(!this.projectMetadataFromEntries(Z,_,$,O).archivedAt)throw new Q_(`Session archive state changed concurrently: ${_}`);let L=new Date().toISOString(),G={id:i(),sessionId:_,timestamp:L,type:"session_updated",cwd:$,gitBranch:L_($),version:__(),data:{sessionId:_,archivedAt:null,updatedAt:L}};return Y=[...Z,G],G}),this.toPublicMetadata(this.projectMetadataFromEntries(Y,_,$,O))}catch(O){if(O instanceof Q_)throw O;if(O instanceof X_)throw new Q_(O.message);throw this.sanitizeStoredSessionError(O,_)}finally{await J?.release()}}static async updateSessionMetadata(_,X,$){T(_),C.validateTaskMetadataUpdate($,_);let W=C.resolveCatalogWorkspace(X);if($.taskWorktree&&N.resolve($.taskWorktree.workspaceRoot)!==W)throw Error("Session task worktree must match the catalog workspace");let J=C.getSessionFilePath(W,_),O=new v(J),Q=[];try{await O.appendValidatedAsync(async(Y)=>{let Z=C.getSessionCreatedEntry(Y,_);if(Z.data.sessionId!==_)throw Error(`Session metadata creation record sessionId mismatch: ${_}`);if(!N.isAbsolute(Z.cwd)||N.resolve(Z.cwd)!==W)throw Error(`Session metadata creation record cwd mismatch: ${_}`);let V=C.projectMetadataFromEntries(Y,_,W,J);if(V.archivedAt)throw new a(_,_);if(V.parentId){let B=await C.findArchivedAncestor(V.parentId,W);if(B)throw new a(_,B.sessionId)}let L=new Date().toISOString(),G={id:i(),sessionId:_,timestamp:L,type:"session_updated",cwd:W,gitBranch:L_(W),version:__(),data:Y0(_,$,L,!0)};return Q=[...Y,G],G})}catch(Y){throw C.sanitizeStoredSessionError(Y,_)}return C.toPublicMetadata(C.projectMetadataFromEntries(Q,_,W,J))}static async updateRemoteSessionMetadata(_,X,$,W){T(_),C.validateTaskMetadataUpdate(W,_);let J;try{if(J=r($),p(J.collisionIdentity)!==X)throw new w}catch(O){throw F(O)}try{return await c(X,async(O)=>{let Q=m(O,_);await n(O,Q);let Y=new v(Q),Z=[];return await Y.appendValidatedAsync(async(V)=>{let L=j(C.projectMetadataFromEntries(V,_,X,Q),J);if(L.archivedAt)throw new a(_,_);if(L.parentId){let U=await C.findRemoteArchivedAncestor(L.parentId,O,L.remoteWorkspace);if(U)throw new a(_,U.sessionId)}let G=new Date().toISOString(),B={id:i(),sessionId:_,projectPath:X,timestamp:G,type:"session_updated",cwd:X,version:__(),data:Y0(_,W,G,!1)};return Z=[...V,B],B},{noFollow:!0,validateHandle:(V)=>v2(O,Q,V)}),C.toPublicMetadata(j(C.projectMetadataFromEntries(Z,_,X,Q),J))})}catch(O){if(O instanceof v_||O instanceof a)throw O;throw F(O)}}static async setSessionPermissionMode(_,X,$){if(T(_),!B0($))throw Error("Invalid session permission mode");let W=C.resolveCatalogWorkspace(X),J=await C.findSessionMetadata(_,W);if(J?.permissionMode===$)return J;if(J)return C.updateSessionMetadata(_,W,{permissionMode:$});try{return await C.createSessionMetadata(_,W,{taskStatus:"completed",permissionMode:$})}catch(O){if(O.code!=="EEXIST")throw O;return C.updateSessionMetadata(_,W,{permissionMode:$})}}static async findSessionTaskWorktree(_,X){T(_);let $=C.resolveCatalogWorkspace(X),W=C.getSessionFilePath($,_);try{return(await C.readStoredSessionMetadata(W,_,$)).taskWorktree}catch(J){if(J.code==="ENOENT")return;throw C.sanitizeStoredSessionError(J,_)}}static async findSessionTaskDispatch(_,X){T(_);let $=C.resolveCatalogWorkspace(X),W=C.getSessionFilePath($,_);try{return(await C.readStoredSessionMetadata(W,_,$)).taskDispatch}catch(J){if(J.code==="ENOENT")return;throw C.sanitizeStoredSessionError(J,_)}}static async loadSessionFromFile(_,X,$,W={}){let J=await Z_(_,"utf-8"),O=this.parseStoredSession(J,X);if($!==void 0){if(this.projectMetadataFromEntries(O,X,$,_).projectPath!==$)throw Error(`未找到会话: ${X}`)}return this.convertJSONLToMessages(O,W)}static async loadSessionModelContextFromFile(_,X,$){let W=await Z_(_,"utf-8"),J=this.parseStoredSession(W,X);if($!==void 0){if(this.projectMetadataFromEntries(J,X,$,_).projectPath!==$)throw Error(`未找到会话: ${X}`)}return this.convertJSONLToModelContext(J)}static convertJSONLToModelContext(_){let X=e(_),$=-1,W;for(let O=0;O<X.length;O++){let Q=X[O];if(Q?.type!=="part_created"||Q.data.partType!=="summary")continue;let Y=Q.data.payload;if($=O,W=s_(Y.replacementMessages),!W)W=[{role:"user",content:Y.text??"",metadata:Q.data.payload}]}if($<0||!W)return this.convertJSONLToMessages(X,{includeTokenBudgetHandoffs:!0}).filter((O)=>!o0(O));let J=this.convertJSONLToMessages(X.slice($+1),{includeTokenBudgetHandoffs:!0});return[...W,...J].filter((O)=>!o0(O))}static convertJSONLToMessages(_,X={}){let $=[],W=new Map,J=new Map,O=new Map,Q=new Map,Y=new Map,Z=e(_),V=X.includeTokenBudgetHandoffs?O2(Z):{kind:"none"},L=new Set;for(let G of Z){if(G.type==="token_budget_handoff_recorded"){if(V.kind==="valid"&&V.event.id===G.id){let B=J2(G);if(B)$.push(B)}continue}if(G.type==="message_created"){let B=G.data.metadata&&typeof G.data.metadata==="object"&&!Array.isArray(G.data.metadata)?G.data.metadata:void 0,U=B?.codeReview&&typeof B.codeReview==="object"&&!Array.isArray(B.codeReview)?B.codeReview:void 0;if(U?.phase==="completed"&&typeof U.reviewId==="string")L.add(U.reviewId);let H=G.data.role==="assistant"&&G.data.parentMessageId?O.get(G.data.parentMessageId):void 0,A=H??{...X.includeMessageIds?{id:G.data.messageId,timestamp:Date.parse(G.data.createdAt)}:{},role:G.data.role,content:"",...G.data.metadata||G.data.inboxMessageId?{metadata:{...G.data.metadata&&typeof G.data.metadata==="object"&&!Array.isArray(G.data.metadata)?G.data.metadata:{},...G.data.inboxMessageId?{inboxMessageId:G.data.inboxMessageId}:{}}}:{}};if(X.includeMessageIds)A.id??=G.data.messageId;if(W.set(G.data.messageId,A),J.set(G.data.messageId,[]),!H)$.push(A)}if(G.type==="part_created"){if(G.data.partType==="reasoning"){let B=W.get(G.data.messageId);if(B){let U=G.data.payload;B.reasoningContent=(B.reasoningContent??"")+(U.text??"")}}if(G.data.partType==="text"){let B=W.get(G.data.messageId);if(B){let U=G.data.payload,H=J.get(G.data.messageId);if(H)H.push({type:"text",text:U.text??""}),B.content=I2(H);else B.content=U.text??""}}if(G.data.partType==="image"){let B=W.get(G.data.messageId);if(B){let U=G.data.payload,H=J.get(G.data.messageId);if(H&&U.dataUrl)H.push({type:"image_url",image_url:{url:U.dataUrl}}),B.content=I2(H)}}if(G.data.partType==="tool_call"){let B=W.get(G.data.messageId);if(B?.role!=="assistant"){if(B=O.get(G.data.messageId),!B)B={role:"assistant",content:"",tool_calls:[]},O.set(G.data.messageId,B),$.push(B)}if(B.role==="assistant"){let U=G.data.payload,H=U.toolCallId??G.data.partId;Q.set(G.data.partId,H),Y.set(H,B),B.tool_calls??=[],B.tool_calls.push({id:H,type:"function",function:{name:U.toolName??"unknown",arguments:JSON.stringify(U.input??{})}})}}if(G.data.partType==="tool_result"){let B=G.data.payload,U=L2(B),H=U.error?`Error: ${U.error.message}`:typeof U.llmContent==="string"?U.llmContent:JSON.stringify(U.llmContent),A=B;$.push({role:"tool",content:H,tool_call_id:Q.get(G.data.messageId)??B.toolCallId,name:B.toolName,metadata:A})}if(G.data.partType==="summary"){let B=G.data.payload,U=G.data.payload;$.push({role:"system",content:B.text??"",metadata:U})}if(G.data.partType==="subtask_ref"){let B=W.get(G.data.messageId)??Y.get(G.data.messageId);if(B){let U=G.data.payload,H=B.metadata??{};B.metadata={...H,subtaskRef:U}}}}}for(let G of e_(Z)){if(G.completion===void 0||L.has(G.start.reviewId))continue;$.push({role:"assistant",content:e1(G.start,G.completion),metadata:{codeReview:{..._2(G.start,G.completion),synthetic:!0}}})}return $}static projectionDeriver(){return(_,X,$,W,J)=>{try{let O=J??P($,X),Q=this.projectMetadataFromEntries(_,X,$,O);if(W==="acp-remote")return j(Q);return Q}catch(O){if(W==="acp-remote")throw F(O);return null}}}static projectionDeriverForSearch(){return this.projectionDeriver()}static async scanStoredSessionsFromProjection(_,X,$=0,W=!1,J={}){try{let O=await I_();if(!O)return null;await L1(O,this.projectionDeriver(),$);let Q=[];Q.push("source_kind = 'local'");let Y=[];if(_!==void 0)Q.push("project_path=?"),Y.push(_);CX(J,"",Q,Y);let Z=Q.length>0?` WHERE ${Q.join(" AND ")}`:"",V=O.prepare(`SELECT metadata_json, is_subagent FROM sessions${Z}`).all(...Y),L=[];for(let B of V){if(!X&&B.is_subagent===1)continue;try{let U=JSON.parse(B.metadata_json);if(U.remoteWorkspace)continue;if(_!==void 0&&U.projectPath!==_)continue;L.push(U)}catch{}}let G=await Promise.all(L.map((B)=>this.reconcileInterruptedTask(B)));return X1(G.filter((B)=>e2(B,J)),W)}catch{return null}}static async scanStoredSessions(_,X=!1,$=0,W=!1,J={}){let O=_?N.resolve(_):void 0,Q=await this.scanStoredSessionsFromProjection(O,X,$,W,J);if(Q)return Q;let Y=O?[{storagePath:H_(O),projectPath:O}]:await this.listAllProjectStorageDirectories(),Z=[];for(let V of Y){let L;try{L=await D_(V.storagePath)}catch(G){if(G.code==="ENOENT")continue;throw G}for(let G of L){if(!G.endsWith(".jsonl"))continue;let B=G.slice(0,-6),U=N.join(V.storagePath,G);try{let H=await this.readLocalCatalogSessionMetadata(U,B,V.projectPath);if(!H)continue;if(O!==void 0&&H.projectPath!==O){S_.warn(`[SessionService] Skipping out-of-scope session transcript: ${B}`);continue}if(!X&&H.relationType==="subagent")continue;if(!qX(H,J))continue;Z.push(await this.reconcileInterruptedTask(H))}catch(H){let A=H.code;if(A==="ENOENT")continue;if(A)throw H;if(H instanceof w)throw H;S_.warn(`[SessionService] Skipping invalid session transcript: ${B}`)}}}return X1(Z,W)}static async listAllProjectStorageDirectories(){let _=N.join(l(),"projects"),X;try{X=await D_(_,{withFileTypes:!0,encoding:"utf8"})}catch($){if($.code==="ENOENT")return[];throw $}return X.filter(($)=>$.isDirectory()).map(($)=>({storagePath:N.join(_,$.name),projectPath:P2($.name)}))}static async listRemoteSessionScopes(_){if(_.descriptor){let $=p(_.descriptor.collisionIdentity);try{return await c($,async()=>[{hostStateRoot:$,descriptor:_.descriptor}])}catch(W){if(W.code==="ENOENT")return[];throw F(W)}}return(await $1()).map(($)=>({hostStateRoot:String($)}))}static async scanRemoteStoredSessions(_){let X=await this.scanRemoteStoredSessionsFromProjection(_);if(X)return X;let $=await this.listRemoteSessionScopes(_),W=[];for(let J of $)await c(J.hostStateRoot,async(O)=>{let Q;try{Q=await D_(String(O))}catch(Y){if(Y.code==="ENOENT")return;throw F(Y)}for(let Y of Q){if(!Y.endsWith(".jsonl"))continue;let Z=Y.slice(0,-6);if(!g_(Z))continue;let V=m(O,Z),L;try{L=await this.readRemoteStoredSessionMetadata(V,Z,J.hostStateRoot,O,_.descriptor)}catch(G){if(G.code==="ENOENT")continue;if(G instanceof Error&&G.message)throw F(G);throw G}if(!L)continue;if(!_.includeSubagents&&L.relationType==="subagent")continue;W.push(L)}});return g2(W,_.archived)}static async scanRemoteStoredSessionsFromProjection(_){try{let X=await I_();if(!X)return null;if(_.descriptor)await a2(X,this.projectionDeriver(),p(_.descriptor.collisionIdentity));else await t2(X,this.projectionDeriver());let $=["source_kind = 'acp-remote'"],W=[];if(_.descriptor)$.push("project_path=?"),W.push(p(_.descriptor.collisionIdentity));let J=$.length>0?` WHERE ${$.join(" AND ")}`:"",O=X.prepare(`SELECT metadata_json, is_subagent FROM sessions${J}`).all(...W),Q=[];for(let L of O){if(!_.includeSubagents&&L.is_subagent===1)continue;let G=j(JSON.parse(L.metadata_json),void 0);if(_.descriptor&&!w_(G.remoteWorkspace,_.descriptor))continue;Q.push(G)}let Y=_.descriptor,Z=Y?Q.filter((L)=>w_(L.remoteWorkspace,Y)):Q,V=await Promise.all(Z.map((L)=>this.reconcileInterruptedTask(L,"acp-remote")));return g2(V.map((L)=>j(L)),_.archived)}catch(X){throw F(X)}}static toRemoteCatalogEntries(_){return _.flatMap((X)=>{if(!X.remoteWorkspace)return[];return[{...X,workspaceIdentity:X.remoteWorkspace.exactIdentity}]})}static async readStoredSessionMetadata(_,X,$,W="local",J){if(W==="acp-remote"){if(!J||String(J)!==$)throw new w;let Q=m(J,X);if(_!==Q)throw new w}let O=await this.readStoredSessionMetadataWithoutReconciliation(_,X,$);if(W==="acp-remote")j(O);else if(O.projectPath!==$||O.remoteWorkspace)return O;return this.reconcileInterruptedTask(O,W,J)}static async readStoredSessionMetadataWithoutReconciliation(_,X,$){let W=await Z_(_,"utf-8"),J=this.parseStoredSession(W,X);return this.projectMetadataFromEntries(J,X,$,_)}static async readLocalCatalogSessionMetadata(_,X,$){let W=await Z_(_,"utf-8"),J=this.parseStoredSession(W,X),O=this.getSessionCreatedEntry(J,X);if(Object.hasOwn(O.data,"remoteWorkspace")){try{r(O.data.remoteWorkspace)}catch(Q){throw F(Q)}return}return this.projectMetadataFromEntries(J,X,$,_)}static async readRemoteStoredSessionMetadata(_,X,$,W,J){if(String(W)!==$||_!==m(W,X))throw new w;await n(W,_);let O=await Z_(_,"utf-8"),Q=this.parseStoredSession(O,X);this.validateSessionWorkspace(Q,X,$);let Y=j(this.projectMetadataFromEntries(Q,X,$,_));if(J&&!w_(Y.remoteWorkspace,J))return;return j(await this.reconcileInterruptedTask(Y,"acp-remote",W),Y.remoteWorkspace)}static async reconcileInterruptedTask(_,X="local",$){let W=_.taskOwnerPid;if(_.taskStatus!=="running"||W===void 0)return _;if(X==="acp-remote"){if($)return this.reconcileInterruptedTaskInScope(_,W,$);return c(_.projectPath,async(J)=>this.reconcileInterruptedTaskInScope(_,W,J))}return this.reconcileInterruptedTaskInScope(_,W)}static async reconcileInterruptedTaskInScope(_,X,$){let W=$?j(_).remoteWorkspace:void 0;if($){let Y=m($,_.sessionId);if(_.projectPath!==String($)||_.filePath!==Y)throw new w;await n($,_.filePath)}let J;try{J=$?await h.acquireRemote(_.sessionId,$):await h.acquire(_.sessionId,_.projectPath)}catch(Y){if(!(Y instanceof X_))throw Y;let Z=await Z_(_.filePath,"utf-8"),V=this.projectMetadataFromEntries(this.parseStoredSession(Z,_.sessionId),_.sessionId,_.projectPath,_.filePath);return W?j(V,W):V}let O=new v(_.filePath),Q;try{try{await O.appendValidated((Z)=>{let V=this.projectMetadataFromEntries(Z,_.sessionId,_.projectPath,_.filePath);if(W)j(V,W);if(V.taskStatus!=="running"||V.taskOwnerPid!==X)throw new U1;let L=new Date().toISOString(),G={id:i(),sessionId:_.sessionId,timestamp:L,type:"session_updated",cwd:_.projectPath,...$?{projectPath:_.projectPath}:{},...$?{}:{gitBranch:L_(_.projectPath)},version:__(),data:{sessionId:_.sessionId,taskStatus:"interrupted",taskStatusReason:"Task owner process exited before completion",taskCompletedAt:L,taskOwnerPid:null,taskQueuePosition:null,taskQueueDepth:null,updatedAt:L}};return Q=[...Z,G],G})}catch(Z){if(!(Z instanceof U1))throw Z}if(!Q){let Z=await Z_(_.filePath,"utf-8");Q=this.parseStoredSession(Z,_.sessionId)}let Y=this.projectMetadataFromEntries(Q,_.sessionId,_.projectPath,_.filePath);return W?j(Y,W):Y}finally{await J.release()}}static projectMetadataFromEntries(_,X,$,W){if(_.length===0)throw Error(`Empty session transcript: ${X}`);let J=this.getSessionCreatedEntry(_,X);if(Object.hasOwn(J.data,"remoteWorkspace"))this.validateRemoteSessionCreationRecord(_,J,X,$);let O=_.reduce((b,E0)=>E0.type==="session_updated"?{...b,...E0.data}:b,{...J.data}),Q=e(_),Y=s1(t1(Q)),V=e_(Q).at(-1),L=Q.findLastIndex((b)=>b.type==="review_started"&&b.data.reviewId===V?.start.reviewId||b.type==="review_completed"&&b.data.reviewId===V?.start.reviewId),G=Q.findLastIndex((b)=>(b.type==="session_created"||b.type==="session_updated")&&Object.hasOwn(b.data,"taskStatus")),B=V!==void 0&&L>G,U=B?V.completion===void 0?"running":V.completion.status==="completed"||V.completion.status==="stale"?"completed":V.completion.status==="aborted"?"cancelled":V.completion.status==="interrupted"?"interrupted":"failed":void 0,H=Q.filter((b)=>b.type==="message_created"&&["user","assistant"].includes(b.data.role)).length,A=Q.some((b)=>b.type==="part_created"&&b.data.partType==="tool_result"&&typeof b.data.payload.error==="string"),z=D2.has(O.taskStatus)?O.taskStatus:void 0,D=U??z??(A?"failed":"completed"),t=typeof O.taskOwnerPid==="number"&&Number.isInteger(O.taskOwnerPid)&&O.taskOwnerPid>0?O.taskOwnerPid:void 0,k=B1.has(O.taskIsolation)?O.taskIsolation:void 0,y=typeof O.taskSourceProjectPath==="string"&&N.isAbsolute(O.taskSourceProjectPath)?N.resolve(O.taskSourceProjectPath):void 0,u=J.cwd;if(u!==void 0&&!N.isAbsolute(u))throw Error(`Session catalog cwd must be absolute: ${X}`);let R=u===void 0?$:N.resolve(u),x=this.parseRemoteWorkspaceFromCreated(J,R),f=R2(O.taskWorktree),q=f?.sessionId===X&&N.resolve(f.workspaceRoot)===R?f:void 0,B_=x2(O.taskDiffStat),S=b2(O.taskDispatch),I=U0.has(O.taskPriority)?O.taskPriority:S?.taskPriority,U_=H0.has(O.taskKind)?O.taskKind:S?.taskKind,p_=typeof O.taskDueAt==="string"&&Number.isFinite(Date.parse(O.taskDueAt))?new Date(O.taskDueAt).toISOString():S?.taskDueAt,N0=typeof O.taskModelId==="string"&&O.taskModelId.trim()?O.taskModelId:S?.modelId,C1=typeof O.selectedModelId==="string"&&O.selectedModelId.trim()?O.selectedModelId:N0,q1=B0(O.permissionMode)?O.permissionMode:S?.permissionMode,K1=h_(O.reasoningEffort)?O.reasoningEffort:S?.reasoningEffort,M1=u_(O.serviceTier)?O.serviceTier:S?.serviceTier,T1=P_(O.responseVerbosity)?O.responseVerbosity:S?.responseVerbosity,c_=l_(O.communicationStyle)?O.communicationStyle:S?.communicationStyle,C0=Object.hasOwn(O,"communicationStyleDigest")?typeof O.communicationStyleDigest==="string"&&/^[a-f0-9]{64}$/.test(O.communicationStyleDigest)?O.communicationStyleDigest:void 0:c_===S?.communicationStyle?S?.communicationStyleDigest:void 0,q0=Object.hasOwn(O,"projectInstructionsDigest")?typeof O.projectInstructionsDigest==="string"&&/^[a-f0-9]{64}$/.test(O.projectInstructionsDigest)?O.projectInstructionsDigest:void 0:S?.projectInstructionsDigest,K0=N1(O.archivedAt)?O.archivedAt:void 0,g=k2(O.taskRetriedFrom),A1=w2(O.taskDelivery),M0=typeof O.taskQueuePosition==="number"&&Number.isInteger(O.taskQueuePosition)&&O.taskQueuePosition>0?O.taskQueuePosition:void 0,x_=typeof O.taskQueueDepth==="number"&&Number.isInteger(O.taskQueueDepth)&&O.taskQueueDepth>=0?O.taskQueueDepth:void 0,T0=typeof O.taskConcurrencyLimit==="number"&&Number.isInteger(O.taskConcurrencyLimit)&&O.taskConcurrencyLimit>0?O.taskConcurrencyLimit:void 0,T_=B?V?.completion?V.completion.status==="completed"?void 0:`Code review ${I0(V.completion.status)}`:`Reviewing ${V?.start.target.label??"changes"}`:void 0,A0=B?D==="failed"&&T_?p0(T_):void 0:c0(O.taskFailure)?O.taskFailure:D==="failed"&&typeof O.taskStatusReason==="string"?p0(O.taskStatusReason):void 0;return{sessionId:X,projectPath:R,remoteWorkspace:x,...J.gitBranch!==void 0?{gitBranch:J.gitBranch}:{},rootId:O.rootId||X,parentId:O.parentId,relationType:O.relationType,resumedFrom:O.resumedFrom,rootAgentId:O.rootAgentId,resumeDepth:O.resumeDepth,title:O.title,agentType:O.agentType,model:O.model,selectedModelId:C1,permissionMode:q1,reasoningEffort:K1,serviceTier:M1,responseVerbosity:T1,communicationStyle:c_,communicationStyleDigest:C0,projectInstructionsDigest:q0,pendingInteraction:Y,taskStatus:D,taskStatusReason:A0?.message??T_??(typeof O.taskStatusReason==="string"?O.taskStatusReason:void 0),taskFailure:A0,taskStartedAt:B?V?.start.startedAt:typeof O.taskStartedAt==="string"?O.taskStartedAt:void 0,taskCompletedAt:B?V?.completion?.completedAt:typeof O.taskCompletedAt==="string"?O.taskCompletedAt:void 0,taskPromptSummary:B?V?EX(V.start.target):"/review uncommitted":typeof O.taskPromptSummary==="string"?O.taskPromptSummary:void 0,taskPriority:I,taskKind:U_,taskDueAt:p_,taskModelId:N0,taskRetryAvailable:S!==void 0,taskRetriedFrom:g,taskDelivery:A1,taskIsolation:k,taskSourceProjectPath:y,taskWorktreePath:q?.worktreeRoot,taskWorktreeBranch:q?.branch,taskBaseCommit:q?.baseCommit,taskDiffStat:B_,taskQueuePosition:M0,taskQueueDepth:x_,taskConcurrencyLimit:T0,archivedAt:K0,taskOwnerPid:B?void 0:t,taskWorktree:q,taskDispatch:S,messageCount:H,firstMessageTime:_[0].timestamp,lastMessageTime:_.at(-1).timestamp,hasErrors:A||D==="failed",filePath:W}}static parseRemoteWorkspaceFromCreated(_,X){if(!Object.hasOwn(_.data,"remoteWorkspace"))return;let $;try{$=r(_.data.remoteWorkspace)}catch(J){throw F(J)}if(p($.collisionIdentity)!==X)throw new w;return $}static async assertRemoteSessionWritableInScope(_,X,$,W){let J=m(W,_),O;try{await n(W,J),O=await this.readStableSessionSnapshot(J,_)}catch(Y){throw F(Y)}let Q;try{Q=this.projectMetadataFromEntries(O,_,X,J)}catch(Y){throw F(Y)}if(Q.archivedAt)throw new a(_,Q.archivedBySessionId??_);if(!Q.remoteWorkspace)throw new w;if(!w_(Q.remoteWorkspace,$))throw new v_;return this.toPublicMetadata(Q)}static async readValidatedRemoteSessionSnapshot(_,X,$,W){W?.throwIfAborted();let J;try{if(T(_),J=r($),p(J.collisionIdentity)!==X)throw new w}catch(O){throw F(O)}try{return await c(X,async(O)=>{W?.throwIfAborted();let Q=m(O,_);await n(O,Q);let Y=await this.readStableSessionSnapshot(Q,_,3,W),Z=this.projectMetadataFromEntries(Y,_,X,Q);return j(Z,J),Y})}catch(O){if(W?.aborted)throw O;if(O instanceof v_)throw O;throw F(O)}}static toPublicMetadata(_){let{filePath:X,taskOwnerPid:$,taskWorktree:W,taskDispatch:J,...O}=_;return O}static getSessionFilePath(_,X){return P(_,X)}static getSessionCreatedEntry(_,X){let $=_.find((W)=>W.type==="session_created");if(!$)throw new X4(X);return $}static validateRemoteSessionCreationRecord(_,X,$,W){if(Z0(_,$,W)!==X)throw new w}static resolveCatalogWorkspace(_){if(!N.isAbsolute(_))throw Error("Session catalog cwd must be absolute");return G0(_)}static validateSessionWorkspace(_,X,$){let W=this.getSessionCreatedEntry(_,X);if(W.data.sessionId!==X)throw Error(`Session creation record sessionId mismatch: ${X}`);if(!N.isAbsolute(W.cwd)||N.resolve(W.cwd)!==$)throw Error(`Session creation record cwd mismatch: ${X}`)}static resolveForkWorkspace(_){if(!N.isAbsolute(_))throw Error("Fork workspace paths must be absolute");return G0(_)}static parseStoredSession(_,X){return c2(_,`session ${X}`)}static isCorruptSessionJSONLError(_){return _ instanceof Error&&_.message.startsWith("Invalid session JSONL ")}static sanitizeStoredSessionError(_,X){if(!this.isCorruptSessionJSONLError(_)||!(_ instanceof Error))return _;let $=_.message.match(/ at line (\d+)$/)?.[1];return Error(`Invalid session JSONL in session ${X}${$?` at line ${$}`:""}`,{cause:_.cause})}static async readStableSessionSnapshot(_,X,$=3,W){for(let J=0;J<$;J+=1){W?.throwIfAborted();let O=await m_.stat(_,W),Q=await m_.readFile(_,W),Y=this.parseStoredSession(Q,X),Z=await m_.stat(_,W);if(W?.throwIfAborted(),O.size===Z.size&&O.mtimeNs===Z.mtimeNs&&O.dev===Z.dev&&O.ino===Z.ino)return Y}throw new H1}}function I2(_){if(_.length===1&&_[0]?.type==="text")return _[0].text;return[..._]}
|
|
94
94
|
export{nX as Cc,dX as Dc,iX as Ec,G_ as Fc,rX as Gc,j0 as Hc,n0 as Ic,D1 as Jc,b_ as Kc,eX as Lc,_$ as Mc,X_ as Nc,h as Oc,N4 as Pc,g1 as Qc,O_ as Rc,z$ as Sc,D$ as Tc,R$ as Uc,w$ as Vc,x$ as Wc,b$ as Xc,k$ as Yc,f$ as Zc,j$ as _c,y$ as $c,S$ as ad,g$ as bd,I$ as cd,m$ as dd,v$ as ed,P$ as fd,u$ as gd,h$ as hd,l$ as id,p$ as jd,c$ as kd,n$ as ld,d$ as md,i$ as nd,r$ as od,o$ as pd,a$ as qd,t$ as rd,s$ as sd,e$ as td,_W as ud,XW as vd,n1 as wd,w4 as xd,S0 as yd,r1 as zd,YW as Ad,ZW as Bd,t1 as Cd,LW as Dd,e_ as Ed,UW as Fd,I0 as Gd,e1 as Hd,_2 as Id,CW as Jd,qW as Kd,KW as Ld,P4 as Md,O2 as Nd,J2 as Od,u4 as Pd,MW as Qd,z_ as Rd,p0 as Sd,c0 as Td,V_ as Ud,W0 as Vd,SW as Wd,gW as Xd,IW as Yd,mW as Zd,L2 as _d,vW as $d,o0 as ae,nW as be,F2 as ce,C2 as de,oW as ee,z2 as fe,aW as ge,TX as he,kO as ie,fO as je,X4 as ke,a as le,Q_ as me,C as ne};
|