@robota-sdk/agent-transport 3.0.0-beta.82 → 3.0.0-beta.84

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +795 -0
  2. package/README.md +80 -118
  3. package/dist/browser/client.d.ts +2 -2
  4. package/dist/browser/client.js +1 -1
  5. package/dist/browser/index.d.ts +87 -13
  6. package/dist/browser/index.d.ts.map +1 -1
  7. package/dist/browser/index.js +1 -1
  8. package/dist/browser/index.js.map +1 -1
  9. package/dist/browser/observer-messages-CEeisRaF.js +2 -0
  10. package/dist/browser/observer-messages-CEeisRaF.js.map +1 -0
  11. package/dist/browser/observer-messages-Dnff2Tdb.d.ts +471 -0
  12. package/dist/browser/observer-messages-Dnff2Tdb.d.ts.map +1 -0
  13. package/dist/node/index.cjs +1 -1
  14. package/dist/node/index.d.cts +308 -16
  15. package/dist/node/index.d.cts.map +1 -1
  16. package/dist/node/index.d.ts +308 -16
  17. package/dist/node/index.d.ts.map +1 -1
  18. package/dist/node/index.js +1 -1
  19. package/dist/node/index.js.map +1 -1
  20. package/dist/node/node.cjs +1 -1
  21. package/dist/node/node.d.cts +69 -1
  22. package/dist/node/node.d.cts.map +1 -1
  23. package/dist/node/node.d.ts +70 -2
  24. package/dist/node/node.d.ts.map +1 -1
  25. package/dist/node/node.js +1 -1
  26. package/dist/node/node.js.map +1 -1
  27. package/package.json +17 -14
  28. package/src/__tests__/bearer-resource-gate.test.ts +120 -0
  29. package/src/__tests__/history-attached-budget.test.ts +216 -0
  30. package/src/__tests__/message-decoders.test.ts +496 -6
  31. package/src/__tests__/project-read-messages.test.ts +118 -0
  32. package/src/__tests__/session-detail-loop-status.test.ts +169 -0
  33. package/src/__tests__/session-directory-messages.test.ts +322 -0
  34. package/src/__tests__/session-error-classification.test.ts +113 -0
  35. package/src/__tests__/session-history-wire.test.ts +342 -0
  36. package/src/__tests__/session-message-handler-observe.test.ts +217 -0
  37. package/src/__tests__/session-message-handler.test.ts +139 -4
  38. package/src/__tests__/settings-messages.test.ts +193 -0
  39. package/src/__tests__/ws-broadcast-events.test.ts +10 -0
  40. package/src/client.ts +9 -1
  41. package/src/index.ts +18 -2
  42. package/src/loop-control-messages.ts +34 -0
  43. package/src/message-decoders.ts +238 -6
  44. package/src/node/bearer-resource-gate.ts +291 -0
  45. package/src/node/index.ts +13 -0
  46. package/src/observer-messages.ts +47 -0
  47. package/src/open-prompts.ts +76 -0
  48. package/src/outbound-delivery.ts +11 -2
  49. package/src/project-read-messages.ts +74 -0
  50. package/src/protocol-session.ts +23 -1
  51. package/src/session-directory-messages.ts +162 -0
  52. package/src/session-error-classification.ts +91 -0
  53. package/src/session-events.ts +100 -19
  54. package/src/session-message-handler.ts +110 -15
  55. package/src/session-query-messages.ts +123 -5
  56. package/src/session-resume-bridge.ts +8 -0
  57. package/src/settings-messages.ts +103 -0
  58. package/src/wire-messages.ts +238 -11
  59. package/dist/browser/message-decoders-BB8n-H2X.d.ts +0 -252
  60. package/dist/browser/message-decoders-BB8n-H2X.d.ts.map +0 -1
  61. package/dist/browser/message-decoders-CDmDoZPR.js +0 -2
  62. package/dist/browser/message-decoders-CDmDoZPR.js.map +0 -1
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e,t,o){if(o.type===`get-background-tasks`){t({type:`background_tasks`,tasks:e.listBackgroundTasks(o.filter)});return}if(o.type===`get-background-task`){n(e,t,o);return}if(o.type===`get-background-job-groups`){t({type:`background_job_groups`,groups:e.listBackgroundJobGroups()});return}if(o.type===`get-background-job-group`){i(e,t,o);return}if(o.type===`wait-background-job-group`){a(e,t,o);return}r(e,t,o)}function t(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}if(n.type===`cancel-background-task`){s(t,`cancel`,n.taskId,e.cancelBackgroundTask(n.taskId,n.reason));return}if(n.type===`close-background-task`){s(t,`close`,n.taskId,e.closeBackgroundTask(n.taskId));return}o(e,t,n)}function n(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}t({type:`background_task`,taskId:n.taskId,task:e.getBackgroundTask(n.taskId)??null})}function r(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}e.readBackgroundTaskLog(n.taskId,n.cursor).then(e=>t({type:`background_task_log`,taskId:n.taskId,page:e}),e=>t({type:`protocol_error`,message:e.message}))}function i(e,t,n){if(!n.groupId){t({type:`protocol_error`,message:`groupId is required`});return}t({type:`background_job_group`,groupId:n.groupId,group:e.getBackgroundJobGroup(n.groupId)??null})}function a(e,t,n){if(!n.groupId){t({type:`protocol_error`,message:`groupId is required`});return}e.waitBackgroundJobGroup(n.groupId).then(e=>t({type:`background_job_group`,groupId:n.groupId,group:e}),e=>t({type:`protocol_error`,message:e.message}))}function o(e,t,n){if(!n.input){t({type:`protocol_error`,message:`input is required`});return}s(t,`send`,n.taskId,e.sendBackgroundTask(n.taskId,n.input))}function s(e,t,n,r){r.then(()=>e({type:`background_task_control_result`,action:t,taskId:n,success:!0}),r=>e({type:`background_task_control_result`,action:t,taskId:n,success:!1,message:r.message}))}function c(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const l=e=>typeof e==`string`,u=e=>typeof e==`string`&&e.length>0,d=e=>typeof e==`boolean`,f=e=>typeof e==`number`&&Number.isFinite(e),p=e=>t=>t===void 0||e(t),m=e=>Array.isArray(e)&&e.every(c),h=e=>e===null||c(e),g=e=>t=>typeof t==`string`&&e.includes(t),_=[`agent`,`process`,`scheduled`],v=[`foreground`,`background`],y=[`queued`,`running`,`waiting_permission`,`sleeping`,`paused`,`completed`,`failed`,`cancelled`],b=[`cancel`,`close`,`send`],x={submit:{prompt:u},command:{name:u,args:p(l)},abort:{},"cancel-queue":{},"get-messages":{},"get-context":{},"get-usage-report":{},"get-personal-usage-report":{requestId:u,period:g([`7d`,`30d`]),timezone:u},"get-stored-session-usage-report":{requestId:u,sessionId:u},"get-executing":{},"get-pending":{},"get-execution-workspace":{},"get-background-tasks":{filter:p(e=>c(e)&&p(g(_))(e.kind)&&p(g(y))(e.status)&&p(g(v))(e.mode)&&p(d)(e.includeClosed))},"get-background-task":{taskId:u},"get-background-job-groups":{},"get-background-job-group":{groupId:u},"wait-background-job-group":{groupId:u},"cancel-background-task":{taskId:u,reason:p(l)},"close-background-task":{taskId:u},"send-background-task":{taskId:u,input:e=>c(e)&&p(l)(e.prompt)&&p(l)(e.stdin)},"read-background-task-log":{taskId:u,cursor:p(e=>c(e)&&f(e.offset))},"permission-response":{id:u,result:e=>d(e)||e===`allow-session`||e===`allow-project`},"ask-response":{id:u,response:e=>c(e)&&(e.type===`answer`&&Array.isArray(e.values)&&e.values.every(l)&&p(l)(e.text)||e.type===`cancelled`&&e.values===void 0&&e.text===void 0)},resume:{lastSeq:f},ack:{seq:f}},S={driverId:p(l)},C={text_delta:{delta:l,...S},user_message:{content:l,...S},tool_start:{state:c,...S},tool_end:{state:c,...S},thinking:{isThinking:d,...S},complete:{result:c,...S},interrupted:{result:c,...S},error:{message:l,...S},command_result:{name:l,message:l,success:d},messages:{messages:m},context:{state:c},usage_report:{report:c},personal_usage_report:{requestId:u,report:c},personal_usage_report_error:{requestId:u,code:g([`not_available`,`report_failed`]),message:l},stored_session_usage_report:{requestId:u,sessionId:u,report:c},stored_session_usage_report_error:{requestId:u,sessionId:u,code:g([`not_available`,`report_failed`]),message:l},executing:{executing:d},pending:{pending:e=>e===null||l(e)},execution_workspace_event:{snapshot:c},background_task_event:{event:c},background_job_group_event:{event:c},plan_event:{event:c},context_file_refreshed:{event:c},branch_event:{event:c},background_tasks:{tasks:m},background_task:{taskId:l,task:h},background_job_groups:{groups:m},background_job_group:{groupId:l,group:h},background_task_log:{taskId:l,page:c},permission_request:{event:c},ask_request:{event:c},prompt_resolved:{event:c},ui_intent:{event:c},session_renamed:{event:c},history_cleared:{},background_task_control_result:{action:g(b),taskId:l,success:d,message:p(l)},protocol_error:{message:l},resume_gap:{}};function w(e,t,n){if(!c(e))return{ok:!1,reason:`message must be a JSON object`};let r=e.type;if(!l(r))return{ok:!1,reason:`message type must be a string`};let i=Object.prototype.hasOwnProperty.call(t,r)?t[r]:void 0;if(i===void 0)return{ok:!1,reason:`Unknown message type: ${r}`};for(let[t,r]of Object.entries(i))if(!r(e[t]))return{ok:!1,reason:n(t)};return{ok:!0,message:e}}function T(e){return w(e,x,e=>e===`prompt`?`prompt must be a non-empty string`:`${e} has an invalid shape`)}function E(e){return w(e,C,e=>`${e} has an invalid shape`)}function D(e,t){if(e.length>4194304)return{ok:!1,reason:`Frame too large`};let n;try{n=JSON.parse(e)}catch{return{ok:!1,reason:`Invalid JSON`}}return t(n)}function ee(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function O(e){return typeof e==`string`&&e.length>0?e:void 0}function te(e){if(!(new TextEncoder().encode(e).byteLength>4194304))try{let t=JSON.parse(e);if(!ee(t))return;let n=O(t.requestId);if(!n)return;if(t.type===`get-personal-usage-report`)return{type:`personal`,requestId:n};let r=O(t.sessionId);return t.type===`get-stored-session-usage-report`&&r?{type:`stored-session`,requestId:n,sessionId:r}:void 0}catch{return}}function ne(e,t,n,r){return n.type===`get-personal-usage-report`?(ae(t,n,r.personalUsageReporter),!0):n.type===`get-stored-session-usage-report`?(ie(t,n,r.storedSessionUsageReporter),!0):n.type===`get-usage-report`?(re(e,t,r.usageReporter),!0):!1}function re(e,t,n){if(!n){t({type:`protocol_error`,message:`Per-session usage reporting is not available on this host.`});return}try{Promise.resolve(n(e)).then(e=>t({type:`usage_report`,report:e}),e=>t({type:`protocol_error`,message:j(e)}))}catch(e){t({type:`protocol_error`,message:j(e instanceof Error?e:String(e))})}}function ie(e,t,n){if(!n){k(e,t,`not_available`,`Stored-session usage reporting is not available on this host.`);return}try{Promise.resolve(n(t.sessionId)).then(n=>e({type:`stored_session_usage_report`,requestId:t.requestId,sessionId:t.sessionId,report:n}),n=>k(e,t,`report_failed`,j(n)))}catch(n){k(e,t,`report_failed`,j(n instanceof Error?n:String(n)))}}function k(e,t,n,r){e({type:`stored_session_usage_report_error`,requestId:t.requestId,sessionId:t.sessionId,code:n,message:r})}function ae(e,t,n){if(!n){A(e,t.requestId,`not_available`,`Personal usage reporting is not available on this host.`);return}try{Promise.resolve(n({period:t.period,timezone:t.timezone})).then(n=>e({type:`personal_usage_report`,requestId:t.requestId,report:n}),n=>A(e,t.requestId,`report_failed`,j(n)))}catch(n){A(e,t.requestId,`report_failed`,j(n instanceof Error?n:String(n)))}}function A(e,t,n,r){e({type:`personal_usage_report_error`,requestId:t,code:n,message:r})}function j(e){return e instanceof Error?e.message:String(e)}function M(e,t){let n=D(e,T);if(n.ok)return n.message;let r=te(e);return r?.type===`personal`?(t({type:`personal_usage_report_error`,requestId:r.requestId,code:`report_failed`,message:`Invalid personal usage report request.`}),null):r?.type===`stored-session`?(t({type:`stored_session_usage_report_error`,requestId:r.requestId,sessionId:r.sessionId,code:`report_failed`,message:`Invalid stored-session usage report request.`}),null):(t({type:`protocol_error`,message:n.reason}),null)}const oe={text_delta:`forwarded`,tool_start:`forwarded`,tool_end:`forwarded`,thinking:`forwarded`,complete:`forwarded`,error:`forwarded`,context_update:`non-surface`,compact:`non-surface`,interrupted:`forwarded`,skill_activation:`non-surface`,background_task_event:`forwarded`,background_job_group_event:`forwarded`,execution_workspace_event:`forwarded`,user_message:`forwarded`,turn_source:`non-surface`,context_file_refreshed:`forwarded`,memory_event:`non-surface`,goal_event:`non-surface`,plan_event:`forwarded`,branch_event:`forwarded`,permission_request:`forwarded`,ask_request:`forwarded`,prompt_resolved:`forwarded`,ui_intent:`requester-routed`,session_renamed:`forwarded`,history_cleared:`forwarded`};function N(e,t,n={}){let r=()=>{let t=e.getActiveDriverId();return t?{driverId:t}:{}},i=e=>t({type:`user_message`,content:e,...r()}),a=e=>t({type:`text_delta`,delta:e,...r()}),o=e=>t({type:`tool_start`,state:e,...r()}),s=e=>t({type:`tool_end`,state:e,...r()}),c=e=>t({type:`thinking`,isThinking:e,...r()}),l=e=>t({type:`complete`,result:e,...r()}),u=e=>t({type:`interrupted`,result:e,...r()}),d=e=>t({type:`error`,message:e.message,...r()}),f=e=>t({type:`background_task_event`,event:e}),p=e=>t({type:`background_job_group_event`,event:e}),m=e=>t({type:`execution_workspace_event`,snapshot:e.snapshot}),h=e=>t({type:`plan_event`,event:e}),g=e=>t({type:`context_file_refreshed`,event:e}),_=e=>t({type:`branch_event`,event:e}),v=e=>t({type:`permission_request`,event:e}),y=e=>t({type:`ask_request`,event:e}),b=e=>t({type:`prompt_resolved`,event:e}),x=e=>{(e.requesterDriverId===void 0||e.requesterDriverId===n.getSurfaceDriverId?.())&&t({type:`ui_intent`,event:e})},S=e=>t({type:`session_renamed`,event:e}),C=()=>t({type:`history_cleared`});return e.on(`user_message`,i),e.on(`text_delta`,a),e.on(`tool_start`,o),e.on(`tool_end`,s),e.on(`thinking`,c),e.on(`complete`,l),e.on(`interrupted`,u),e.on(`error`,d),e.on(`background_task_event`,f),e.on(`background_job_group_event`,p),e.on(`execution_workspace_event`,m),e.on(`plan_event`,h),e.on(`context_file_refreshed`,g),e.on(`branch_event`,_),e.on(`permission_request`,v),e.on(`ask_request`,y),e.on(`prompt_resolved`,b),e.on(`ui_intent`,x),e.on(`session_renamed`,S),e.on(`history_cleared`,C),()=>{e.off(`user_message`,i),e.off(`text_delta`,a),e.off(`tool_start`,o),e.off(`tool_end`,s),e.off(`thinking`,c),e.off(`complete`,l),e.off(`interrupted`,u),e.off(`error`,d),e.off(`background_task_event`,f),e.off(`background_job_group_event`,p),e.off(`execution_workspace_event`,m),e.off(`plan_event`,h),e.off(`context_file_refreshed`,g),e.off(`branch_event`,_),e.off(`permission_request`,v),e.off(`ask_request`,y),e.off(`prompt_resolved`,b),e.off(`ui_intent`,x),e.off(`session_renamed`,S),e.off(`history_cleared`,C)}}function se(e){return e.type===`get-messages`||e.type===`get-context`||e.type===`get-executing`||e.type===`get-pending`||e.type===`get-execution-workspace`}function ce(e,t,n){n.type===`get-messages`?t({type:`messages`,messages:e.getMessages()}):n.type===`get-context`?t({type:`context`,state:e.getContextState()}):n.type===`get-executing`?t({type:`executing`,executing:e.isExecuting()}):n.type===`get-execution-workspace`?t({type:`execution_workspace_event`,snapshot:e.getExecutionWorkspaceSnapshot()}):t({type:`pending`,pending:e.getPendingPrompt()})}function le(e){let t=N(e.session,e.deliver,{getSurfaceDriverId:()=>e.driverId});return{onMessage:ue(e.session,e.deliver,e.driverId,{personalUsageReporter:e.personalUsageReporter,usageReporter:e.usageReporter,storedSessionUsageReporter:e.storedSessionUsageReporter},e.surface),cleanup:t}}function ue(e,t,n,r=P,i){return a=>{let o=M(a,t);o&&F(e,t,o,n,r,i)}}const P={personalUsageReporter:void 0,usageReporter:void 0,storedSessionUsageReporter:void 0};function F(n,r,i,a,o=P,s){if(ne(n,r,i,o))return;if(de(i)){R(n,r,i,a,s);return}if(se(i)){ce(n,r,i);return}if(fe(i)){e(n,r,i);return}if(pe(i)){t(n,r,i);return}if(I(i)){L(n,i,a);return}let c=i.type;r({type:`protocol_error`,message:`Unknown message type: ${c}`})}function de(e){return e.type===`submit`||e.type===`command`||e.type===`abort`||e.type===`cancel-queue`}function fe(e){return e.type===`get-background-tasks`||e.type===`get-background-task`||e.type===`read-background-task-log`||e.type===`get-background-job-groups`||e.type===`get-background-job-group`||e.type===`wait-background-job-group`}function pe(e){return e.type===`cancel-background-task`||e.type===`close-background-task`||e.type===`send-background-task`}function I(e){return e.type===`permission-response`||e.type===`ask-response`}function L(e,t,n){t.type===`permission-response`?e.resolvePermission(t.id,t.result,n):e.resolveAsk(t.id,t.response,n)}function R(e,t,n,r,i){if(n.type===`submit`){if(typeof n.prompt!=`string`||n.prompt.length===0){t({type:`protocol_error`,message:`prompt must be a non-empty string`});return}let a={...r?{driverId:r}:{},...i?{surface:i}:{}};e.submit(n.prompt,void 0,void 0,Object.keys(a).length>0?a:void 0).catch(e=>{t({type:`protocol_error`,message:e.message})})}else if(n.type===`command`){if(!n.name){t({type:`protocol_error`,message:`name is required`});return}e.executeCommand(n.name,n.args??``,`remote`,r).then(e=>{t({type:`command_result`,name:n.name,message:e?.message??`Unknown command: ${n.name}`,success:e?.success??!1,data:e?.data})},e=>{t({type:`protocol_error`,message:e.message})})}else n.type===`abort`?e.abort():e.cancelQueue()}const z=8*1048576;function B(e,t=z){return e!==void 0&&e>t}const V=120*1e3;function H(e=V,t=Date.now){let n;return{maxPendingMs:e,observe(r){if(r===void 0)return;if(r===0){n=void 0;return}let i=t();n??=i;let a=i-n;return a>e?a:void 0}}}function U(e,t,n,r=z,i=H()){let a=!1,o=t=>{if(a)return;let o=n?.();if(B(o,r)){a=!0,s(Error(`outbound backpressure budget exceeded: ${o} byte(s) pending, limit ${r}. The peer has accepted frames it is not reading.`),t.type);return}let c=i.observe(o);if(c!==void 0){a=!0,s(Error(`outbound drain budget exceeded: ${o} byte(s) pending for ${c} ms, limit ${i.maxPendingMs} ms. The peer is reading too slowly to ever drain what it accepted.`),t.type);return}try{e(t)}catch(e){a=!0,s(e instanceof Error?e:Error(String(e)),t.type)}};function s(e,n){try{t(e,n)}catch{}}return Object.assign(o,{pendingBytes:()=>n?.()})}var W=class{frames=[];sizes=[];nextSeq=1;bytes=0;maxFrames;maxBytes;sizeOf;constructor(e={}){this.maxFrames=e.maxFrames??512,this.maxBytes=e.maxBytes??4194304,this.sizeOf=e.sizeOf??(e=>JSON.stringify(e).length)}append(e){let t=this.nextSeq;this.nextSeq+=1;let n=this.sizeOf(e);return this.frames.push({seq:t,message:e}),this.sizes.push(n),this.bytes+=n,this.evict(),t}ackThrough(e){let t=0;for(;t<this.frames.length&&this.frames[t].seq<=e;)t+=1;this.removeOldest(t)}tailAfter(e){return this.frames.length===0?e>=this.nextSeq-1?{kind:`tail`,frames:[]}:{kind:`overrun`}:e<this.frames[0].seq-1?{kind:`overrun`}:{kind:`tail`,frames:this.frames.filter(t=>t.seq>e)}}get lastSeq(){return this.nextSeq-1}get size(){return this.frames.length}evict(){let e=0,t=this.bytes;for(;this.frames.length-e>this.maxFrames||t>this.maxBytes&&this.frames.length-e>1;)t-=this.sizes[e],e+=1;this.removeOldest(e)}removeOldest(e){if(!(e<=0)){for(let t=0;t<e;t+=1)this.bytes-=this.sizes[t]??0;this.frames.splice(0,e),this.sizes.splice(0,e),this.frames.length===0&&(this.bytes=0)}}};const G=new TextEncoder,K=new TextDecoder,q=G.encode(`RBF`),J=4294967295;function Y(e,t){let n=G.encode(e);if(n.byteLength===0||n.byteLength>255)throw Error(`channel name must be 1..255 UTF-8 bytes (got ${n.byteLength})`);if(!Number.isInteger(t)||t<0||t>J)throw Error(`seq must be an integer in 0..${J} (got ${t})`);return n}function X(e,t,n,r){e.set(q,0),e[3]=1,e[4]=t,e[5]=n.byteLength,e.set(n,6);let i=6+n.byteLength;return new DataView(e.buffer,e.byteOffset,e.byteLength).setUint32(i,r,!1),i+4}function me(e){let t=Y(e.channel,e.seq),n=new Uint8Array(6+t.byteLength+4+e.payload.byteLength),r=X(n,1,t,e.seq);return n.set(e.payload,r),n}function he(e){let t=Y(e.channel,e.seq),n=G.encode(JSON.stringify({event:e.event,payload:e.payload})),r=new Uint8Array(6+t.byteLength+4+n.byteLength),i=X(r,2,t,e.seq);return r.set(n,i),r}function Z(e){return e.byteLength<q.length?!1:q.every((t,n)=>e[n]===t)}function Q(e){let t=K.decode(e),n;try{n=JSON.parse(t)}catch{return{ok:!1,error:`channel frame: malformed JSON body`}}if(typeof n!=`object`||!n||Array.isArray(n))return{ok:!1,error:`channel frame: event body must be a JSON object`};let{event:r,payload:i}=n;return typeof r!=`string`||r.length===0?{ok:!1,error:"channel frame: event body is missing a non-empty `event` name"}:{ok:!0,event:r,payload:i??null}}function ge(e){if(!Z(e))return{ok:!1,error:`channel frame: bad magic (not a channel frame)`};if(e.byteLength<6)return{ok:!1,error:`channel frame: truncated header`};if(e[3]!==1)return{ok:!1,error:`channel frame: unsupported version ${String(e[3])}`};let t=e[4],n=e[5]??0;if(n===0)return{ok:!1,error:`channel frame: empty channel name`};let r=6+n,i=r+4;if(e.byteLength<i)return{ok:!1,error:`channel frame: truncated (header longer than the frame)`};let a=K.decode(e.subarray(6,r)),o=new DataView(e.buffer,e.byteOffset,e.byteLength).getUint32(r,!1),s=e.subarray(i);if(t===1)return{ok:!0,frame:{kind:`binary`,channel:a,seq:o,payload:Uint8Array.from(s)}};if(t===2){let e=Q(s);return e.ok?{ok:!0,frame:{kind:`event`,channel:a,seq:o,event:e.event,payload:e.payload}}:{ok:!1,error:e.error}}return{ok:!1,error:`channel frame: unknown kind ${String(t)}`}}var _e=class{session;buffer;driverId;reporters;surface;unsubscribe;onDeliveryError;outbound;emitBoundary;disposed=!1;holding=!1;constructor(e){this.session=e.session,this.buffer=new W(e.buffer),this.driverId=e.driverId,this.surface=e.surface,this.reporters={personalUsageReporter:e.personalUsageReporter,usageReporter:e.usageReporter,storedSessionUsageReporter:e.storedSessionUsageReporter},this.emitBoundary=U(e=>this.emit(e),(e,t)=>this.reportDeliveryError(e,t)),this.unsubscribe=N(this.session,this.emitBoundary,{getSurfaceDriverId:()=>this.driverId})}attach(e,t){this.disposed||(this.onDeliveryError=t.onDeliveryError,this.outbound=U(t=>e(JSON.stringify(t)),(e,t)=>this.reportDeliveryError(e,t),t.pendingBytes),this.holding=t.awaitResume===!0)}detach(){this.outbound=void 0,this.onDeliveryError=void 0}setDriverId(e){this.driverId=e}onClientMessage(e){if(this.disposed)return;let t=M(e,this.emitBoundary);if(t){if(t.type===`resume`){this.replay(t.lastSeq);return}if(t.type===`ack`){this.buffer.ackThrough(t.seq);return}F(this.session,this.emitBoundary,t,this.driverId,this.reporters,this.surface)}}dispose(){this.disposed||(this.disposed=!0,this.detach(),this.unsubscribe())}get lastSeq(){return this.buffer.lastSeq}emit(e){if(this.disposed)return;let t=this.buffer.append(e);this.holding||this.deliverFrame({...e,seq:t})}replay(e){let t=this.buffer.tailAfter(e);if(t.kind===`overrun`){this.deliverFrame({type:`resume_gap`}),this.holding=!1;return}for(let e of t.frames)this.deliverFrame({...e.message,seq:e.seq});this.holding=!1}deliverFrame(e){this.outbound?.(e)}reportDeliveryError(e,t){let n=this.onDeliveryError;this.detach();try{n?.(e,t)}catch{}}};function ve(){return{origins:new Map}}function ye(e,t,n){let r=t.origin.sessionId,i=e.origins.get(r);i===void 0&&(i={highestSequence:0,delivered:new Set,issued:new Map},e.origins.set(r,i));let a=i.issued.get(t.id);if(a!==void 0)return{ack:{...a,state:`duplicate`},deliver:!1};if(n!==void 0){let e={id:t.id,sequence:t.sequence,state:n.state,reason:n.reason};return i.issued.set(t.id,e),{ack:e,deliver:!1}}if(i.delivered.has(t.sequence)){let e={id:t.id,sequence:t.sequence,state:`refused`,reason:`sequence ${t.sequence} was already delivered by this origin under a different message id. A retry must repeat its id; a new id on a delivered sequence cannot be ordered against what the receiver already has.`};return i.issued.set(t.id,e),{ack:e,deliver:!1}}let o=i.highestSequence+1,s=t.sequence>o?o:void 0,c={id:t.id,sequence:t.sequence,state:`delivered`};return i.issued.set(t.id,c),i.delivered.add(t.sequence),i.highestSequence=Math.max(i.highestSequence,t.sequence),s===void 0?{ack:c,deliver:!0}:{ack:c,deliver:!0,gapBefore:s}}function be(e,t,n){let r=e.origins.get(t),i=r?.issued.get(n);if(r===void 0||i===void 0||i.state!==`delivered`)return;let a={...i,state:`acknowledged`};return r.issued.set(n,a),a}function xe(e,t){e.origins.delete(t)}const $=16*1024;function Se(e,t,n=$){if(!Number.isInteger(n)||n<1)throw Error(`handoff chunking: maxChunkBytes must be a positive integer, got ${n}. A zero or negative budget produces an infinite sequence of empty chunks, which presents as a hang rather than as the configuration error it is.`);let r=Buffer.from(t,`utf8`),i=Math.max(1,Math.ceil(r.byteLength/n)),a=[];for(let t=0;t<i;t+=1){let o=r.subarray(t*n,(t+1)*n);a.push({handoffId:e,index:t,total:i,data:o.toString(`base64`)})}return a}var Ce=class{handoffId;chunks=new Map;declaredTotal;constructor(e){this.handoffId=e}get received(){return this.chunks.size}get expected(){return this.declaredTotal}accept(e){let t=e=>({outcome:`refused`,rejection:e,received:this.chunks.size,...this.declaredTotal===void 0?{}:{expected:this.declaredTotal}});if(e.handoffId!==this.handoffId)return t(`wrong-handoff`);if(!Number.isInteger(e.total)||e.total<1||this.declaredTotal!==void 0&&e.total!==this.declaredTotal)return t(`inconsistent-total`);if(!Number.isInteger(e.index)||e.index<0||e.index>=e.total)return t(`out-of-range`);let n=Buffer.from(e.data,`base64`);if(n.toString(`base64`)!==e.data)return t(`undecodable`);this.declaredTotal=e.total;let r=this.chunks.get(e.index);return r===void 0?(this.chunks.set(e.index,n),this.chunks.size<e.total?{outcome:`accepted`,received:this.chunks.size,expected:e.total}:{outcome:`complete`,serialized:this.reassemble(e.total),received:this.chunks.size,expected:e.total}):r.equals(n)?{outcome:`duplicate`,received:this.chunks.size,expected:e.total}:t(`inconsistent-total`)}missing(){if(this.declaredTotal===void 0)return[];let e=[];for(let t=0;t<this.declaredTotal;t+=1)this.chunks.has(t)||e.push(t);return e}discard(){this.chunks.clear(),this.declaredTotal=void 0}reassemble(e){let t=[];for(let n=0;n<e;n+=1){let r=this.chunks.get(n);if(r===void 0)throw Error(`handoff chunking: chunk ${n} of ${e} is missing at reassembly.`);t.push(r)}return Buffer.concat(t).toString(`utf8`)}};function we(e,t=$){return Math.max(1,Math.ceil(e.byteLength/t))}exports.CHANNEL_FRAME_MAGIC=q,exports.CHANNEL_FRAME_VERSION=1,exports.DEFAULT_MAX_CHUNK_BYTES=$,exports.DEFAULT_MAX_PENDING_BYTES=z,exports.DEFAULT_MAX_PENDING_MS=V,exports.HandoffChunkAssembler=Ce,exports.MAX_INBOUND_FRAME_BYTES=4194304,exports.PROTOCOL_SESSION_EVENT_CLASSIFICATION=oe,exports.ResumeBuffer=W,exports.SessionResumeBridge=_e,exports.acknowledgePeerMessage=be,exports.admitPeerMessage=ye,exports.chunkCountFor=we,exports.chunkHandoffPayload=Se,exports.createOutboundDelivery=U,exports.createPeerMessageLedger=ve,exports.createPendingStallClock=H,exports.createSessionMessageHandler=le,exports.decodeChannelFrame=ge,exports.decodeClientMessage=T,exports.decodeFrame=D,exports.decodeServerMessage=E,exports.encodeBinaryFrame=me,exports.encodeChannelEventFrame=he,exports.forgetPeerOrigin=xe,exports.isChannelFrame=Z,exports.isOverPendingBudget=B;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@robota-sdk/agent-interface-session"),t=require("@robota-sdk/agent-core");function n(e,t,n){if(n.type===`get-background-tasks`){t({type:`background_tasks`,tasks:e.listBackgroundTasks(n.filter)});return}if(n.type===`get-background-task`){i(e,t,n);return}if(n.type===`get-background-job-groups`){t({type:`background_job_groups`,groups:e.listBackgroundJobGroups()});return}if(n.type===`get-background-job-group`){o(e,t,n);return}if(n.type===`wait-background-job-group`){s(e,t,n);return}a(e,t,n)}function r(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}if(n.type===`cancel-background-task`){l(t,`cancel`,n.taskId,e.cancelBackgroundTask(n.taskId,n.reason));return}if(n.type===`close-background-task`){l(t,`close`,n.taskId,e.closeBackgroundTask(n.taskId));return}c(e,t,n)}function i(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}t({type:`background_task`,taskId:n.taskId,task:e.getBackgroundTask(n.taskId)??null})}function a(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}e.readBackgroundTaskLog(n.taskId,n.cursor).then(e=>t({type:`background_task_log`,taskId:n.taskId,page:e}),e=>t({type:`protocol_error`,message:e.message}))}function o(e,t,n){if(!n.groupId){t({type:`protocol_error`,message:`groupId is required`});return}t({type:`background_job_group`,groupId:n.groupId,group:e.getBackgroundJobGroup(n.groupId)??null})}function s(e,t,n){if(!n.groupId){t({type:`protocol_error`,message:`groupId is required`});return}e.waitBackgroundJobGroup(n.groupId).then(e=>t({type:`background_job_group`,groupId:n.groupId,group:e}),e=>t({type:`protocol_error`,message:e.message}))}function c(e,t,n){if(!n.input){t({type:`protocol_error`,message:`input is required`});return}l(t,`send`,n.taskId,e.sendBackgroundTask(n.taskId,n.input))}function l(e,t,n,r){r.then(()=>e({type:`background_task_control_result`,action:t,taskId:n,success:!0}),r=>e({type:`background_task_control_result`,action:t,taskId:n,success:!1,message:r.message}))}function u(e){return e.type===`stop-waiting-loop`}function d(e,t,n){let{requestId:r}=n;e.stopWaitingSelfPacedLoop().then(e=>t({type:`waiting_loop_stop`,requestId:r,outcome:e}),e=>t({type:`waiting_loop_stop`,requestId:r,outcome:{kind:`failed`,message:f(e)}}))}function f(e){return e instanceof Error?e.message:String(e)}function p(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const m=e=>typeof e==`string`,h=e=>typeof e==`string`&&e.length>0,g=e=>typeof e==`boolean`,_=e=>typeof e==`number`&&Number.isFinite(e),v=e=>Number.isSafeInteger(e)&&e>=0,y=e=>t=>t===void 0||e(t),b=e=>Array.isArray(e)&&e.every(p),x=e=>e===null||p(e),S=e=>t=>typeof t==`string`&&e.includes(t),C={user:!0,"agent-wakeup":!0,peer:!0,external:!0},w=e=>p(e)&&m(e.id)&&m(e.timestamp)&&m(e.category)&&m(e.type),T=e=>Array.isArray(e)&&e.every(w),E=e=>p(e)&&m(e.name)&&m(e.description)&&m(e.definedIn),D=e=>Array.isArray(e)&&e.every(E),O=[`agent`,`process`,`scheduled`],k=[`foreground`,`background`],A=[`queued`,`running`,`waiting_permission`,`sleeping`,`paused`,`completed`,`failed`,`cancelled`],ee=[`cancel`,`close`,`send`],te=e=>p(e)&&y(S(O))(e.kind)&&y(S(A))(e.status)&&y(S(k))(e.mode)&&y(g)(e.includeClosed),ne=e=>p(e)&&y(m)(e.prompt)&&y(m)(e.stdin),re=e=>p(e)&&_(e.offset),ie=e=>p(e)&&v(e.offset),ae=e=>g(e)||e===`allow-session`||e===`allow-project`,oe=e=>p(e)&&(e.type===`answer`&&Array.isArray(e.values)&&e.values.every(m)&&y(m)(e.text)||e.type===`cancelled`&&e.values===void 0&&e.text===void 0),j={language:{language:h},outputStyle:{styleId:h},preset:{presetId:h},permissionMode:{mode:h},sandbox:{enabled:g},removePermissionRule:{scope:h,kind:S([`allow`,`deny`,`ask`]),pattern:h},mcpServerEnabled:{serverId:h,enabled:g},reloadMcpServers:{},pluginEnabled:{pluginId:h,enabled:g},reloadPlugins:{},installPlugin:{pluginId:h},uninstallPlugin:{pluginId:h},providerProfile:{profileName:h},providerModel:{profileName:h,modelId:h},deleteProviderProfile:{profileName:h}},se=e=>{if(!p(e)||!m(e.field))return!1;let t=e.field;if(!Object.prototype.hasOwnProperty.call(j,t))return!1;let n=j[t];return Object.entries(n).every(([t,n])=>n(e[t]))},ce={none:{},several:{message:m},stopped:{loopId:h,message:y(m)},failed:{loopId:y(h),message:m}},le=e=>{if(!p(e)||!m(e.kind))return!1;let t=e.kind;if(!Object.prototype.hasOwnProperty.call(ce,t))return!1;let n=ce[t];return Object.entries(n).every(([t,n])=>n(e[t]))};function M(e){return t=>{if(!p(t)||!m(t.kind))return!1;let n=Object.prototype.hasOwnProperty.call(e,t.kind)?e[t.kind]:void 0;return n!==void 0&&Object.entries(n).every(([e,n])=>n(t[e]))}}const ue=[`Added`,`Modified`,`Deleted`,`Renamed`,`Copied`,`Untracked`,`Conflicted`],de=e=>p(e)&&h(e.path)&&S(ue)(e.status)&&y(h)(e.renamedFrom)&&y(_)(e.added)&&y(_)(e.removed),fe=M({status:{branch:y(m),unborn:g,files:e=>Array.isArray(e)&&e.every(de),truncated:g},"not-a-repository":{},failed:{message:m}}),pe=[`add`,`remove`,`context`,`hunk`],me=e=>p(e)&&S(pe)(e.type)&&m(e.text)&&_(e.lineNumber),he=M({diff:{diffLines:e=>Array.isArray(e)&&e.every(me),truncated:g},"not-a-repository":{},"outside-workspace":{},failed:{message:m}}),ge=M({memory:{content:m,path:h,truncated:g},unavailable:{message:m}}),_e={submit:{prompt:h},command:{name:h,args:y(m),requestId:y(h)},abort:{},"cancel-queue":{},"get-messages":{},"get-history":{fromIndex:y(v)},"get-prompts":{},"get-context":{},"get-commands":{},"get-status":{},"list-models":{requestId:h},"get-agent-definitions":{requestId:h},"list-sessions":{requestId:h},"new-session":{requestId:y(h)},"switch-session":{sessionId:h,requestId:y(h)},"rename-session":{sessionId:h,name:h,requestId:h},"delete-session":{sessionId:h,requestId:h},"get-usage-report":{},"get-personal-usage-report":{requestId:h,period:S([`7d`,`30d`]),timezone:h},"get-stored-session-usage-report":{requestId:h,sessionId:h},"get-executing":{},"get-pending":{},"get-execution-workspace":{},"read-execution-detail":{requestId:h,entryId:h,cursor:y(ie)},"stop-waiting-loop":{requestId:h},"project-status":{requestId:h},"project-diff":{requestId:h,path:h},"project-memory":{requestId:h},"get-background-tasks":{filter:y(te)},"get-background-task":{taskId:h},"get-background-job-groups":{},"get-background-job-group":{groupId:h},"wait-background-job-group":{groupId:h},"cancel-background-task":{taskId:h,reason:y(m)},"close-background-task":{taskId:h},"send-background-task":{taskId:h,input:ne},"read-background-task-log":{taskId:h,cursor:y(re)},"permission-response":{id:h,result:ae},"ask-response":{id:h,response:oe},resume:{lastSeq:_},ack:{seq:_},"get-settings":{requestId:h},"update-settings":{requestId:h,patch:se}},N={driverId:y(m)},ve={text_delta:{delta:m,...N},user_message:{content:m,...N},tool_start:{state:p,...N},tool_end:{state:p,...N},thinking:{isThinking:g,...N},complete:{result:p,...N},interrupted:{result:p,...N},error:{message:m,code:y(S([`auth`,`rate_limit`,`model_unavailable`,`network`,`provider`])),provider:y(m),retryAfterSeconds:y(_),model:y(m),...N},command_result:{name:m,message:m,success:g,requestId:y(m)},messages:{messages:b,display:y(b),...N},history:{startIndex:v,total:v,entries:T},context:{state:p},history_changed:{},turn_source:{source:S(Object.keys(C))},commands:{commands:b,skills:b},session_status:{status:p},model_list:{requestId:h,groups:b,currentProfile:y(m),currentModel:m},agent_definitions:{requestId:h,agents:D,current:h},sessions:{requestId:h,listing:p},sessions_error:{requestId:h,code:S([`not_available`,`list_failed`]),message:m},session_switched:{event:p},session_change_failed:{code:S(e.SESSION_CHANGE_REFUSAL_CODES),message:m,requestId:y(m)},session_renamed_in_list:{requestId:h,sessionId:m,name:m},session_rename_failed:{requestId:h,message:m},session_deleted:{requestId:h,sessionId:m},session_delete_failed:{requestId:h,code:S(e.SESSION_DELETE_REFUSAL_CODES),message:m},usage_report:{report:p},personal_usage_report:{requestId:h,report:p},personal_usage_report_error:{requestId:h,code:S([`not_available`,`report_failed`]),message:m},stored_session_usage_report:{requestId:h,sessionId:h,report:p},stored_session_usage_report_error:{requestId:h,sessionId:h,code:S([`not_available`,`report_failed`]),message:m},executing:{executing:g},pending:{pending:e=>e===null||m(e),pendingCount:y(v)},execution_workspace_event:{snapshot:p},execution_detail:{requestId:h,page:p},execution_detail_error:{requestId:h,message:m},waiting_loop_stop:{requestId:h,outcome:le},project_status:{requestId:h,result:fe},project_diff:{requestId:h,result:he},project_memory:{requestId:h,result:ge},background_task_event:{event:p},background_job_group_event:{event:p},plan_event:{event:p},context_file_refreshed:{event:p},branch_event:{event:p},background_tasks:{tasks:b},background_task:{taskId:m,task:x},background_job_groups:{groups:b},background_job_group:{groupId:m,group:x},background_task_log:{taskId:m,page:p},permission_request:{event:p},ask_request:{event:p},prompt_resolved:{event:p},ui_intent:{event:p},session_renamed:{event:p},history_cleared:{},background_task_control_result:{action:S(ee),taskId:m,success:g,message:y(m)},protocol_error:{message:m,requestId:y(m)},resume_gap:{},settings:{requestId:h,settings:p},settings_error:{requestId:h,code:S([`not_available`,`invalid`,`refused`,`update_failed`]),message:m}};function P(e,t,n){if(!p(e))return{ok:!1,reason:`message must be a JSON object`};let r=e.type;if(!m(r))return{ok:!1,reason:`message type must be a string`};let i=Object.prototype.hasOwnProperty.call(t,r)?t[r]:void 0;if(i===void 0)return{ok:!1,reason:`Unknown message type: ${r}`};for(let[t,r]of Object.entries(i))if(!r(e[t]))return{ok:!1,reason:n(t)};return{ok:!0,message:e}}function F(e){return P(e,_e,e=>e===`prompt`?`prompt must be a non-empty string`:`${e} has an invalid shape`)}function ye(e){return P(e,ve,e=>`${e} has an invalid shape`)}function be(e,t){if(e.length>4194304)return{ok:!1,reason:`Frame too large`};let n;try{n=JSON.parse(e)}catch{return{ok:!1,reason:`Invalid JSON`}}return t(n)}function xe(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Se(e){return typeof e==`string`&&e.length>0?e:void 0}function Ce(e){if(!(new TextEncoder().encode(e).byteLength>4194304))try{let t=JSON.parse(e);if(!xe(t))return;let n=Se(t.requestId);if(!n)return;if(t.type===`get-personal-usage-report`)return{type:`personal`,requestId:n};let r=Se(t.sessionId);return t.type===`get-stored-session-usage-report`&&r?{type:`stored-session`,requestId:n,sessionId:r}:void 0}catch{return}}function we(e,t,n,r){return n.type===`get-personal-usage-report`?(De(t,n,r.personalUsageReporter),!0):n.type===`get-stored-session-usage-report`?(Ee(t,n,r.storedSessionUsageReporter),!0):n.type===`get-usage-report`?(Te(e,t,r.usageReporter),!0):!1}function Te(e,t,n){if(!n){t({type:`protocol_error`,message:`Per-session usage reporting is not available on this host.`});return}try{Promise.resolve(n(e)).then(e=>t({type:`usage_report`,report:e}),e=>t({type:`protocol_error`,message:R(e)}))}catch(e){t({type:`protocol_error`,message:R(e instanceof Error?e:String(e))})}}function Ee(e,t,n){if(!n){I(e,t,`not_available`,`Stored-session usage reporting is not available on this host.`);return}try{Promise.resolve(n(t.sessionId)).then(n=>e({type:`stored_session_usage_report`,requestId:t.requestId,sessionId:t.sessionId,report:n}),n=>I(e,t,`report_failed`,R(n)))}catch(n){I(e,t,`report_failed`,R(n instanceof Error?n:String(n)))}}function I(e,t,n,r){e({type:`stored_session_usage_report_error`,requestId:t.requestId,sessionId:t.sessionId,code:n,message:r})}function De(e,t,n){if(!n){L(e,t.requestId,`not_available`,`Personal usage reporting is not available on this host.`);return}try{Promise.resolve(n({period:t.period,timezone:t.timezone})).then(n=>e({type:`personal_usage_report`,requestId:t.requestId,report:n}),n=>L(e,t.requestId,`report_failed`,R(n)))}catch(n){L(e,t.requestId,`report_failed`,R(n instanceof Error?n:String(n)))}}function L(e,t,n,r){e({type:`personal_usage_report_error`,requestId:t,code:n,message:r})}function R(e){return e instanceof Error?e.message:String(e)}function Oe(e,t){let n=be(e,F);if(n.ok)return n.message;let r=Ce(e);return r?.type===`personal`?(t({type:`personal_usage_report_error`,requestId:r.requestId,code:`report_failed`,message:`Invalid personal usage report request.`}),null):r?.type===`stored-session`?(t({type:`stored_session_usage_report_error`,requestId:r.requestId,sessionId:r.sessionId,code:`report_failed`,message:`Invalid stored-session usage report request.`}),null):(t({type:`protocol_error`,message:n.reason}),null)}const ke=new Set([`get-messages`,`get-history`,`get-context`,`get-status`,`get-commands`,`list-models`,`get-executing`,`get-pending`,`get-execution-workspace`,`read-execution-detail`,`get-agent-definitions`,`get-usage-report`,`list-sessions`,`get-background-tasks`,`get-background-task`,`get-background-job-groups`,`get-background-job-group`,`wait-background-job-group`,`read-background-task-log`,`get-settings`,`project-status`,`project-diff`,`project-memory`]);function Ae(e){return ke.has(e)}function je(e){return e.type===`project-status`||e.type===`project-diff`||e.type===`project-memory`}function z(e,t){e({type:`protocol_error`,message:`This host does not support the Project panel.`,requestId:t})}function Me(e,t,n){let{requestId:r}=n;if(n.type===`project-status`){if(!e.readProjectStatus)return z(t,r);e.readProjectStatus().then(e=>t({type:`project_status`,requestId:r,result:e}),e=>t({type:`project_status`,requestId:r,result:{kind:`failed`,message:e instanceof Error?e.message:String(e)}}))}else if(n.type===`project-diff`){if(!e.readProjectDiff)return z(t,r);e.readProjectDiff(n.path).then(e=>t({type:`project_diff`,requestId:r,result:e}),e=>t({type:`project_diff`,requestId:r,result:{kind:`failed`,message:e instanceof Error?e.message:String(e)}}))}else{if(!e.readProjectMemory)return z(t,r);e.readProjectMemory().then(e=>t({type:`project_memory`,requestId:r,result:e}),e=>t({type:`project_memory`,requestId:r,result:{kind:`unavailable`,message:e instanceof Error?e.message:String(e)}}))}}function Ne(e){return e.type===`list-sessions`||e.type===`new-session`||e.type===`switch-session`}function Pe(e){return e.type===`rename-session`}function Fe(e){return e.type===`delete-session`}function Ie(t,n,r){if(n.type===`list-sessions`){Le(t,n.requestId,r);return}let i=n.requestId===void 0?{}:{requestId:n.requestId};if(!r){t({type:`session_change_failed`,code:`not_available`,message:`Sessions cannot be switched on this host.`,...i});return}Promise.resolve().then(()=>n.type===`new-session`?r.newSession():r.switchSession(n.sessionId)).catch(n=>t({type:`session_change_failed`,code:(0,e.isSessionChangeRefusal)(n)?n.code:`failed`,message:B(n),...i}))}function Le(e,t,n){if(!n){e({type:`sessions_error`,requestId:t,code:`not_available`,message:`Session listing is not available on this host.`});return}try{e({type:`sessions`,requestId:t,listing:n.listSessions()})}catch(n){e({type:`sessions_error`,requestId:t,code:`list_failed`,message:B(n instanceof Error?n:String(n))})}}function B(e){return e instanceof Error?e.message:String(e)}function Re(e,t,n){if(!n){e({type:`session_rename_failed`,requestId:t.requestId,message:`Sessions cannot be renamed on this host.`});return}n.renameSession(t.sessionId,t.name).then(()=>e({type:`session_renamed_in_list`,requestId:t.requestId,sessionId:t.sessionId,name:t.name}),n=>e({type:`session_rename_failed`,requestId:t.requestId,message:B(n)}))}function ze(t,n,r){if(!r){t({type:`session_delete_failed`,requestId:n.requestId,code:`not_available`,message:`Sessions cannot be deleted on this host.`});return}r.deleteSession(n.sessionId).then(()=>t({type:`session_deleted`,requestId:n.requestId,sessionId:n.sessionId}),r=>t({type:`session_delete_failed`,requestId:n.requestId,code:(0,e.isSessionDeleteRefusal)(r)?r.code:`failed`,message:B(r)}))}const V=new WeakMap;function Be(e){let t=V.get(e);t===void 0&&(t={frames:new Map,holders:0},V.set(e,t));let n=t;n.holders+=1;let r=!1;return{record:e=>{r||n.frames.set(e.event.id,e)},forget:e=>{n.frames.delete(e)},clear:()=>{n.frames.clear()},release:()=>{r||(r=!0,--n.holders,n.holders===0&&V.get(e)===n&&V.delete(e))}}}function Ve(e){return[...V.get(e)?.frames.values()??[]]}function He(e){let t=[],n=new Set,r=[e];for(let e=0;e<=8&&r.length>0;e++){let e=[];for(let i of r)if(!(i==null||n.has(i))&&(n.add(i),t.push(i),typeof i==`object`)){let t=i;e.push(t.originalError,t.cause)}r=e}return t}function Ue(e){let n;for(let r of He(e)){if(r instanceof t.AuthenticationError)return{code:`auth`,...r.provider!==void 0&&{provider:r.provider}};if(r instanceof t.RateLimitError)return{code:`rate_limit`,...r.provider!==void 0&&{provider:r.provider},...r.retryAfter!==void 0&&{retryAfterSeconds:r.retryAfter}};if(r instanceof t.ModelNotAvailableError)return{code:`model_unavailable`,provider:r.provider,...r.model!==void 0&&{model:r.model}};if(r instanceof t.NetworkError)return{code:`network`,...r.provider!==void 0&&{provider:r.provider}};n===void 0&&r instanceof t.ProviderError&&(n={code:`provider`,provider:r.provider})}return n??{}}const We={text_delta:`forwarded`,tool_start:`forwarded`,tool_end:`forwarded`,thinking:`forwarded`,complete:`forwarded`,error:`forwarded`,context_update:`forwarded`,compact:`forwarded`,interrupted:`forwarded`,skill_activation:`forwarded`,background_task_event:`forwarded`,background_job_group_event:`forwarded`,execution_workspace_event:`forwarded`,user_message:`forwarded`,turn_source:`forwarded`,context_file_refreshed:`forwarded`,memory_event:`forwarded`,goal_event:`non-surface`,plan_event:`forwarded`,branch_event:`forwarded`,permission_request:`forwarded`,ask_request:`forwarded`,prompt_resolved:`forwarded`,ui_intent:`requester-routed`,session_renamed:`forwarded`,history_cleared:`forwarded`,session_switched:`forwarded`,status_changed:`forwarded`};function H(e,t,n={}){let r=()=>{let t=e.getActiveDriverId();return t?{driverId:t}:{}},i=e=>t({type:`user_message`,content:e,...r()}),a=e=>t({type:`text_delta`,delta:e,...r()}),o=e=>t({type:`tool_start`,state:e,...r()}),s=e=>t({type:`tool_end`,state:e,...r()}),c=e=>t({type:`thinking`,isThinking:e,...r()}),l=e=>t({type:`complete`,result:U(e),...r()}),u=e=>t({type:`interrupted`,result:U(e),...r()}),d=e=>t({type:`error`,message:e.message,...Ue(e),...r()}),f=e=>t({type:`background_task_event`,event:e}),p=e=>t({type:`background_job_group_event`,event:e}),m=e=>t({type:`execution_workspace_event`,snapshot:e.snapshot}),h=e=>t({type:`plan_event`,event:e}),g=e=>t({type:`context_file_refreshed`,event:e}),_=e=>t({type:`branch_event`,event:e}),v=n.receivePrompts??!0,y=v?Be(e):void 0,b=e=>{let n={type:`permission_request`,event:e};y?.record(n),t(n)},x=e=>{let n={type:`ask_request`,event:e};y?.record(n),t(n)},S=e=>{y?.forget(e.id),t({type:`prompt_resolved`,event:e})},C=e=>{(e.requesterDriverId===void 0||e.requesterDriverId===n.getSurfaceDriverId?.())&&t({type:`ui_intent`,event:e})},w=e=>t({type:`session_renamed`,event:e}),T=()=>t({type:`history_cleared`}),E=e=>{y?.clear(),t({type:`session_switched`,event:e})},D=e=>t({type:`context`,state:e}),O=()=>t({type:`history_changed`}),k=e=>t({type:`turn_source`,source:e}),A=e=>t({type:`session_status`,status:e});return e.on(`user_message`,i),e.on(`text_delta`,a),e.on(`tool_start`,o),e.on(`tool_end`,s),e.on(`thinking`,c),e.on(`complete`,l),e.on(`interrupted`,u),e.on(`error`,d),e.on(`background_task_event`,f),e.on(`background_job_group_event`,p),e.on(`execution_workspace_event`,m),e.on(`plan_event`,h),e.on(`context_file_refreshed`,g),e.on(`branch_event`,_),v&&(e.on(`permission_request`,b),e.on(`ask_request`,x)),e.on(`prompt_resolved`,S),e.on(`ui_intent`,C),e.on(`session_renamed`,w),e.on(`history_cleared`,T),e.on(`session_switched`,E),e.on(`context_update`,D),e.on(`compact`,O),e.on(`skill_activation`,O),e.on(`memory_event`,O),e.on(`turn_source`,k),e.on(`status_changed`,A),()=>{e.off(`user_message`,i),e.off(`text_delta`,a),e.off(`tool_start`,o),e.off(`tool_end`,s),e.off(`thinking`,c),e.off(`complete`,l),e.off(`interrupted`,u),e.off(`error`,d),e.off(`background_task_event`,f),e.off(`background_job_group_event`,p),e.off(`execution_workspace_event`,m),e.off(`plan_event`,h),e.off(`context_file_refreshed`,g),e.off(`branch_event`,_),v&&(e.off(`permission_request`,b),e.off(`ask_request`,x)),e.off(`prompt_resolved`,S),e.off(`ui_intent`,C),e.off(`session_renamed`,w),e.off(`history_cleared`,T),e.off(`session_switched`,E),e.off(`context_update`,D),e.off(`compact`,O),e.off(`skill_activation`,O),e.off(`memory_event`,O),e.off(`turn_source`,k),e.off(`status_changed`,A),y?.release()}}function U(e){let{history:t,...n}=e;return n}const Ge=new TextEncoder;function Ke(e){return e.type===`get-messages`||e.type===`get-history`||e.type===`get-prompts`||e.type===`get-context`||e.type===`get-commands`||e.type===`get-status`||e.type===`list-models`||e.type===`get-agent-definitions`||e.type===`get-executing`||e.type===`get-pending`||e.type===`get-execution-workspace`||e.type===`read-execution-detail`}function qe(e,t,n){if(n.type===`get-messages`)t({type:`messages`,messages:e.getMessages(),display:e.getMessagesDisplay()});else if(n.type===`get-history`)t(Ye(e,n.fromIndex??0));else if(n.type===`get-prompts`)for(let n of Ve(e))t(n);else if(n.type===`get-context`)t({type:`context`,state:e.getContextState()});else if(n.type===`get-commands`)t({type:`commands`,commands:e.listCommands(),skills:e.listSkills()});else if(n.type===`get-status`)t({type:`session_status`,status:e.getStatusSnapshot()});else if(n.type===`list-models`){let r=e.listModels();t({type:`model_list`,requestId:n.requestId,...r})}else n.type===`get-agent-definitions`?t({type:`agent_definitions`,requestId:n.requestId,agents:e.listAgentDefinitions(),current:e.getDefaultAgentType()}):n.type===`get-executing`?t({type:`executing`,executing:e.isExecuting()}):n.type===`get-execution-workspace`?t({type:`execution_workspace_event`,snapshot:e.getExecutionWorkspaceSnapshot()}):n.type===`read-execution-detail`?Je(e,t,n):t(W(e))}function Je(e,t,n){let{requestId:r}=n;e.readExecutionWorkspaceDetail(n.entryId,n.cursor).then(e=>t({type:`execution_detail`,requestId:r,page:e}),e=>t({type:`execution_detail_error`,requestId:r,message:e instanceof Error?e.message:String(e)}))}function W(e){return{type:`pending`,pending:e.getPendingPrompt(),pendingCount:e.getPendingCount()}}function Ye(e,t){let n=e.getFullHistory(),r=n.length,i=Math.min(t,r),a=[],o=0;for(let e=i;e<r;e+=1){let t=Xe(n[e]),r=Ge.encode(JSON.stringify(t)).byteLength;if(a.length>0&&o+r>262144)break;a.push(t),o+=r}return{type:`history`,startIndex:i,total:r,entries:a}}function Xe(e){return{...e,timestamp:Ze(e.timestamp)}}function Ze(e){return typeof e==`string`?e:e.toISOString()}function G(e){return e.type===`get-settings`||e.type===`update-settings`}function K(e,t,n,r,i){if(!r){q(t,n.requestId,`not_available`,`Settings are not available on this host.`);return}try{if(n.type===`get-settings`){Promise.resolve(r.getSettings(e,i)).then(e=>t({type:`settings`,requestId:n.requestId,settings:e}),e=>q(t,n.requestId,`update_failed`,J(e)));return}Promise.resolve(r.updateSettings(e,n.patch,i)).then(e=>{e.ok?t({type:`settings`,requestId:n.requestId,settings:e.settings}):q(t,n.requestId,e.code,e.message)},e=>q(t,n.requestId,`update_failed`,J(e)))}catch(e){q(t,n.requestId,`update_failed`,J(e instanceof Error?e:String(e)))}}function q(e,t,n,r){e({type:`settings_error`,requestId:t,code:n,message:r})}function J(e){return e instanceof Error?e.message:String(e)}function Qe(e){let t=e.role??`drive`,n=H(e.session,e.deliver,{getSurfaceDriverId:()=>e.driverId,receivePrompts:t===`drive`});return{onMessage:$e(e.session,e.deliver,e.driverId,{personalUsageReporter:e.personalUsageReporter,usageReporter:e.usageReporter,storedSessionUsageReporter:e.storedSessionUsageReporter},e.surface,t,e.sessionDirectory,e.settingsReporter,e.commandSurfaceLocality),cleanup:n}}function $e(e,t,n,r=et,i,a=`drive`,o,s,c){return l=>{let u=Oe(l,t);if(u){if(a===`observe`&&!Ae(u.type)){t({type:`protocol_error`,message:`Not permitted for an observer: ${u.type}`});return}tt(e,t,u,n,r,i,o,s,c)}}}const et={personalUsageReporter:void 0,usageReporter:void 0,storedSessionUsageReporter:void 0};function tt(e,t,i,a,o=et,s,c,l,f){if(we(e,t,i,o))return;if(Ne(i)){Ie(t,i,c);return}if(G(i)){K(e,t,i,l,f);return}if(Pe(i)){Re(t,i,c);return}if(Fe(i)){ze(t,i,c);return}if(nt(i)){st(e,t,i,a,s,f);return}if(u(i)){d(e,t,i);return}if(Ke(i)){qe(e,t,i);return}if(je(i)){Me(e,t,i);return}if(rt(i)){n(e,t,i);return}if(it(i)){r(e,t,i);return}if(at(i)){ot(e,i,a);return}let p=i.type;t({type:`protocol_error`,message:`Unknown message type: ${p}`})}function nt(e){return e.type===`submit`||e.type===`command`||e.type===`abort`||e.type===`cancel-queue`}function rt(e){return e.type===`get-background-tasks`||e.type===`get-background-task`||e.type===`read-background-task-log`||e.type===`get-background-job-groups`||e.type===`get-background-job-group`||e.type===`wait-background-job-group`}function it(e){return e.type===`cancel-background-task`||e.type===`close-background-task`||e.type===`send-background-task`}function at(e){return e.type===`permission-response`||e.type===`ask-response`}function ot(e,t,n){t.type===`permission-response`?e.resolvePermission(t.id,t.result,n):e.resolveAsk(t.id,t.response,n)}function st(e,t,n,r,i,a){if(n.type===`submit`){if(typeof n.prompt!=`string`||n.prompt.length===0){t({type:`protocol_error`,message:`prompt must be a non-empty string`});return}let a={...r?{driverId:r}:{},...i?{surface:i}:{}};e.submit(n.prompt,void 0,void 0,Object.keys(a).length>0?a:void 0).then(()=>t(W(e)),e=>t({type:`protocol_error`,message:e.message}))}else if(n.type===`command`){let i=n.requestId===void 0?{}:{requestId:n.requestId};if(!n.name){t({type:`protocol_error`,message:`name is required`,...i});return}e.executeCommand(n.name,n.args??``,`remote`,r,a).then(e=>{t({type:`command_result`,name:n.name,message:e?.message??`Unknown command: ${n.name}`,success:e?.success??!1,data:e?.data,...i})},e=>{t({type:`protocol_error`,message:e.message,...i})})}else n.type===`abort`?e.abort():e.cancelQueue()}const Y=8*1048576;function ct(e,t=Y){return e!==void 0&&e>t}const lt=120*1e3;function ut(e=lt,t=Date.now){let n;return{maxPendingMs:e,observe(r){if(r===void 0)return;if(r===0){n=void 0;return}let i=t();n??=i;let a=i-n;return a>e?a:void 0}}}function X(e,t,n,r=Y,i=ut()){let a=!1,o=t=>{if(a)return;let o=n?.();if(ct(o,r)){a=!0,s(Error(`outbound backpressure budget exceeded: ${o} byte(s) pending, limit ${r}. The peer has accepted frames it is not reading.`),t.type);return}let c=i.observe(o);if(c!==void 0){a=!0,s(Error(`outbound drain budget exceeded: ${o} byte(s) pending for ${c} ms, limit ${i.maxPendingMs} ms. The peer is reading too slowly to ever drain what it accepted.`),t.type);return}try{e(t)}catch(e){a=!0,s(e instanceof Error?e:Error(String(e)),t.type)}};function s(e,n){try{t(e,n)}catch{}}return Object.assign(o,{pendingBytes:()=>n?.()})}var dt=class{frames=[];sizes=[];nextSeq=1;bytes=0;maxFrames;maxBytes;sizeOf;constructor(e={}){this.maxFrames=e.maxFrames??512,this.maxBytes=e.maxBytes??4194304,this.sizeOf=e.sizeOf??(e=>JSON.stringify(e).length)}append(e){let t=this.nextSeq;this.nextSeq+=1;let n=this.sizeOf(e);return this.frames.push({seq:t,message:e}),this.sizes.push(n),this.bytes+=n,this.evict(),t}ackThrough(e){let t=0;for(;t<this.frames.length&&this.frames[t].seq<=e;)t+=1;this.removeOldest(t)}tailAfter(e){return this.frames.length===0?e>=this.nextSeq-1?{kind:`tail`,frames:[]}:{kind:`overrun`}:e<this.frames[0].seq-1?{kind:`overrun`}:{kind:`tail`,frames:this.frames.filter(t=>t.seq>e)}}get lastSeq(){return this.nextSeq-1}get size(){return this.frames.length}evict(){let e=0,t=this.bytes;for(;this.frames.length-e>this.maxFrames||t>this.maxBytes&&this.frames.length-e>1;)t-=this.sizes[e],e+=1;this.removeOldest(e)}removeOldest(e){if(!(e<=0)){for(let t=0;t<e;t+=1)this.bytes-=this.sizes[t]??0;this.frames.splice(0,e),this.sizes.splice(0,e),this.frames.length===0&&(this.bytes=0)}}};const Z=new TextEncoder,ft=new TextDecoder,Q=Z.encode(`RBF`),pt=4294967295;function mt(e,t){let n=Z.encode(e);if(n.byteLength===0||n.byteLength>255)throw Error(`channel name must be 1..255 UTF-8 bytes (got ${n.byteLength})`);if(!Number.isInteger(t)||t<0||t>pt)throw Error(`seq must be an integer in 0..${pt} (got ${t})`);return n}function ht(e,t,n,r){e.set(Q,0),e[3]=1,e[4]=t,e[5]=n.byteLength,e.set(n,6);let i=6+n.byteLength;return new DataView(e.buffer,e.byteOffset,e.byteLength).setUint32(i,r,!1),i+4}function gt(e){let t=mt(e.channel,e.seq),n=new Uint8Array(6+t.byteLength+4+e.payload.byteLength),r=ht(n,1,t,e.seq);return n.set(e.payload,r),n}function _t(e){let t=mt(e.channel,e.seq),n=Z.encode(JSON.stringify({event:e.event,payload:e.payload})),r=new Uint8Array(6+t.byteLength+4+n.byteLength),i=ht(r,2,t,e.seq);return r.set(n,i),r}function vt(e){return e.byteLength<Q.length?!1:Q.every((t,n)=>e[n]===t)}function yt(e){let t=ft.decode(e),n;try{n=JSON.parse(t)}catch{return{ok:!1,error:`channel frame: malformed JSON body`}}if(typeof n!=`object`||!n||Array.isArray(n))return{ok:!1,error:`channel frame: event body must be a JSON object`};let{event:r,payload:i}=n;return typeof r!=`string`||r.length===0?{ok:!1,error:"channel frame: event body is missing a non-empty `event` name"}:{ok:!0,event:r,payload:i??null}}function bt(e){if(!vt(e))return{ok:!1,error:`channel frame: bad magic (not a channel frame)`};if(e.byteLength<6)return{ok:!1,error:`channel frame: truncated header`};if(e[3]!==1)return{ok:!1,error:`channel frame: unsupported version ${String(e[3])}`};let t=e[4],n=e[5]??0;if(n===0)return{ok:!1,error:`channel frame: empty channel name`};let r=6+n,i=r+4;if(e.byteLength<i)return{ok:!1,error:`channel frame: truncated (header longer than the frame)`};let a=ft.decode(e.subarray(6,r)),o=new DataView(e.buffer,e.byteOffset,e.byteLength).getUint32(r,!1),s=e.subarray(i);if(t===1)return{ok:!0,frame:{kind:`binary`,channel:a,seq:o,payload:Uint8Array.from(s)}};if(t===2){let e=yt(s);return e.ok?{ok:!0,frame:{kind:`event`,channel:a,seq:o,event:e.event,payload:e.payload}}:{ok:!1,error:e.error}}return{ok:!1,error:`channel frame: unknown kind ${String(t)}`}}var xt=class{session;buffer;driverId;reporters;surface;commandSurfaceLocality;unsubscribe;onDeliveryError;outbound;emitBoundary;disposed=!1;holding=!1;constructor(e){this.session=e.session,this.buffer=new dt(e.buffer),this.driverId=e.driverId,this.surface=e.surface,this.commandSurfaceLocality=e.commandSurfaceLocality,this.reporters={personalUsageReporter:e.personalUsageReporter,usageReporter:e.usageReporter,storedSessionUsageReporter:e.storedSessionUsageReporter},this.emitBoundary=X(e=>this.emit(e),(e,t)=>this.reportDeliveryError(e,t)),this.unsubscribe=H(this.session,this.emitBoundary,{getSurfaceDriverId:()=>this.driverId})}attach(e,t){this.disposed||(this.onDeliveryError=t.onDeliveryError,this.outbound=X(t=>e(JSON.stringify(t)),(e,t)=>this.reportDeliveryError(e,t),t.pendingBytes),this.holding=t.awaitResume===!0)}detach(){this.outbound=void 0,this.onDeliveryError=void 0}setDriverId(e){this.driverId=e}onClientMessage(e){if(this.disposed)return;let t=Oe(e,this.emitBoundary);if(t){if(t.type===`resume`){this.replay(t.lastSeq);return}if(t.type===`ack`){this.buffer.ackThrough(t.seq);return}tt(this.session,this.emitBoundary,t,this.driverId,this.reporters,this.surface,void 0,void 0,this.commandSurfaceLocality)}}dispose(){this.disposed||(this.disposed=!0,this.detach(),this.unsubscribe())}get lastSeq(){return this.buffer.lastSeq}emit(e){if(this.disposed)return;let t=this.buffer.append(e);this.holding||this.deliverFrame({...e,seq:t})}replay(e){let t=this.buffer.tailAfter(e);if(t.kind===`overrun`){this.deliverFrame({type:`resume_gap`}),this.holding=!1;return}for(let e of t.frames)this.deliverFrame({...e.message,seq:e.seq});this.holding=!1}deliverFrame(e){this.outbound?.(e)}reportDeliveryError(e,t){let n=this.onDeliveryError;this.detach();try{n?.(e,t)}catch{}}};function St(){return{origins:new Map}}function Ct(e,t,n){let r=t.origin.sessionId,i=e.origins.get(r);i===void 0&&(i={highestSequence:0,delivered:new Set,issued:new Map},e.origins.set(r,i));let a=i.issued.get(t.id);if(a!==void 0)return{ack:{...a,state:`duplicate`},deliver:!1};if(n!==void 0){let e={id:t.id,sequence:t.sequence,state:n.state,reason:n.reason};return i.issued.set(t.id,e),{ack:e,deliver:!1}}if(i.delivered.has(t.sequence)){let e={id:t.id,sequence:t.sequence,state:`refused`,reason:`sequence ${t.sequence} was already delivered by this origin under a different message id. A retry must repeat its id; a new id on a delivered sequence cannot be ordered against what the receiver already has.`};return i.issued.set(t.id,e),{ack:e,deliver:!1}}let o=i.highestSequence+1,s=t.sequence>o?o:void 0,c={id:t.id,sequence:t.sequence,state:`delivered`};return i.issued.set(t.id,c),i.delivered.add(t.sequence),i.highestSequence=Math.max(i.highestSequence,t.sequence),s===void 0?{ack:c,deliver:!0}:{ack:c,deliver:!0,gapBefore:s}}function wt(e,t,n){let r=e.origins.get(t),i=r?.issued.get(n);if(r===void 0||i===void 0||i.state!==`delivered`)return;let a={...i,state:`acknowledged`};return r.issued.set(n,a),a}function Tt(e,t){e.origins.delete(t)}const $=16*1024;function Et(e,t,n=$){if(!Number.isInteger(n)||n<1)throw Error(`handoff chunking: maxChunkBytes must be a positive integer, got ${n}. A zero or negative budget produces an infinite sequence of empty chunks, which presents as a hang rather than as the configuration error it is.`);let r=Buffer.from(t,`utf8`),i=Math.max(1,Math.ceil(r.byteLength/n)),a=[];for(let t=0;t<i;t+=1){let o=r.subarray(t*n,(t+1)*n);a.push({handoffId:e,index:t,total:i,data:o.toString(`base64`)})}return a}var Dt=class{handoffId;chunks=new Map;declaredTotal;constructor(e){this.handoffId=e}get received(){return this.chunks.size}get expected(){return this.declaredTotal}accept(e){let t=e=>({outcome:`refused`,rejection:e,received:this.chunks.size,...this.declaredTotal===void 0?{}:{expected:this.declaredTotal}});if(e.handoffId!==this.handoffId)return t(`wrong-handoff`);if(!Number.isInteger(e.total)||e.total<1||this.declaredTotal!==void 0&&e.total!==this.declaredTotal)return t(`inconsistent-total`);if(!Number.isInteger(e.index)||e.index<0||e.index>=e.total)return t(`out-of-range`);let n=Buffer.from(e.data,`base64`);if(n.toString(`base64`)!==e.data)return t(`undecodable`);this.declaredTotal=e.total;let r=this.chunks.get(e.index);return r===void 0?(this.chunks.set(e.index,n),this.chunks.size<e.total?{outcome:`accepted`,received:this.chunks.size,expected:e.total}:{outcome:`complete`,serialized:this.reassemble(e.total),received:this.chunks.size,expected:e.total}):r.equals(n)?{outcome:`duplicate`,received:this.chunks.size,expected:e.total}:t(`inconsistent-total`)}missing(){if(this.declaredTotal===void 0)return[];let e=[];for(let t=0;t<this.declaredTotal;t+=1)this.chunks.has(t)||e.push(t);return e}discard(){this.chunks.clear(),this.declaredTotal=void 0}reassemble(e){let t=[];for(let n=0;n<e;n+=1){let r=this.chunks.get(n);if(r===void 0)throw Error(`handoff chunking: chunk ${n} of ${e} is missing at reassembly.`);t.push(r)}return Buffer.concat(t).toString(`utf8`)}};function Ot(e,t=$){return Math.max(1,Math.ceil(e.byteLength/t))}exports.ATTACHED_SURFACE_MAX_PENDING_BYTES=1048576,exports.CHANNEL_FRAME_MAGIC=Q,exports.CHANNEL_FRAME_VERSION=1,exports.DEFAULT_MAX_CHUNK_BYTES=$,exports.DEFAULT_MAX_PENDING_BYTES=Y,exports.DEFAULT_MAX_PENDING_MS=lt,exports.HandoffChunkAssembler=Dt,exports.MAX_INBOUND_FRAME_BYTES=4194304,exports.PROTOCOL_SESSION_EVENT_CLASSIFICATION=We,exports.ResumeBuffer=dt,exports.SessionResumeBridge=xt,exports.acknowledgePeerMessage=wt,exports.admitPeerMessage=Ct,exports.chunkCountFor=Ot,exports.chunkHandoffPayload=Et,exports.createOutboundDelivery=X,exports.createPeerMessageLedger=St,exports.createPendingStallClock=ut,exports.createSessionMessageHandler=Qe,exports.decodeChannelFrame=bt,exports.decodeClientMessage=F,exports.decodeFrame=be,exports.decodeServerMessage=ye,exports.encodeBinaryFrame=gt,exports.encodeChannelEventFrame=_t,exports.forgetPeerOrigin=Tt,exports.handleSettingsMessage=K,exports.isChannelFrame=vt,exports.isObserverMessageType=Ae,exports.isOverPendingBudget=ct,exports.isSettingsMessage=G;
@@ -1,11 +1,35 @@
1
1
  import { IPersonalUsageReport, IPersonalUsageRequest, IUsageBySourceReport, TUsageSurface } from "@robota-sdk/agent-interface-analytics";
2
- import { ICommandResult } from "@robota-sdk/agent-interface-command";
3
- import { IBackgroundJobGroupState, IBackgroundTaskInput, IBackgroundTaskListFilter, IBackgroundTaskLogCursor, IBackgroundTaskLogPage, IBackgroundTaskState, IExecutionWorkspaceSnapshot, TBackgroundJobGroupEvent, TBackgroundTaskEvent } from "@robota-sdk/agent-interface-execution";
4
- import { IAskRequestEvent, IBranchEvent, IContextFileRefreshedEvent, IExecutionResult, IPermissionRequestEvent, IPlanApprovalEvent, IPromptResolvedEvent, ISessionBackgroundGroups, ISessionBackgroundTasks, ISessionCommands, ISessionConversationRead, ISessionDriverAttribution, ISessionEvents, ISessionExecutionState, ISessionExecutionWorkspace, ISessionPromptResolution, ISessionRenamedEvent, ISessionTurnControl, ISessionTurnSubmission, IToolState, IUiIntentEvent, TDriverId, TPermissionResultValue } from "@robota-sdk/agent-interface-session";
2
+ import { ICommandListEntry, ICommandResult, ICommandSkillListEntry, TCommandSurfaceLocality } from "@robota-sdk/agent-interface-command";
3
+ import { IBackgroundJobGroupState, IBackgroundTaskInput, IBackgroundTaskListFilter, IBackgroundTaskLogCursor, IBackgroundTaskLogPage, IBackgroundTaskState, IExecutionDetailCursor, IExecutionDetailPage, IExecutionWorkspaceSnapshot, TBackgroundJobGroupEvent, TBackgroundTaskEvent } from "@robota-sdk/agent-interface-execution";
4
+ import { IAskRequestEvent, IBranchEvent, IContextFileRefreshedEvent, IExecutionResult, IModelListGroup, IPermissionRequestEvent, IPlanApprovalEvent, IPromptResolvedEvent, ISessionAgentJobs, ISessionBackgroundGroups, ISessionBackgroundTasks, ISessionCommands, ISessionConversationRead, ISessionDirectory, ISessionDriverAttribution, ISessionEvents, ISessionExecutionDetail, ISessionExecutionState, ISessionExecutionWorkspace, ISessionListing, ISessionProjectRead, ISessionPromptResolution, ISessionRenamedEvent, ISessionSelfPacedLoopControl, ISessionStatusRead, ISessionStatusSnapshot, ISessionSwitchedEvent, ISessionTurnControl, ISessionTurnSubmission, ISettingsSnapshot, IToolState, IUiIntentEvent, TDriverId, TPermissionResultValue, TProjectDiffRead, TProjectMemoryRead, TProjectStatusRead, TSessionChangeRefusalCode, TSessionDeleteRefusalCode, TSettingsPatch, TTurnSource, TWaitingLoopStopOutcome } from "@robota-sdk/agent-interface-session";
5
5
  import { IBinaryFrame, IChannelEventFrame, TActionResponse, TChannelReceiveResult } from "@robota-sdk/agent-interface-transport";
6
6
  import { IHandoffIntegrity, IPeerMessage, IPeerMessageAck, TPeerDeliveryState } from "@robota-sdk/agent-interface-session-mobility";
7
7
  //#region src/wire-messages.d.ts
8
8
  type TBackgroundControlAction = 'cancel' | 'close' | 'send';
9
+ type THistoryEntry = ReturnType<ISessionConversationRead['getFullHistory']>[number];
10
+ /**
11
+ * #3282 §4: one agent the switcher can offer. `definedIn` is a plain-words location — a discovered
12
+ * file's path, or "Built-in" — never a raw internal id.
13
+ */
14
+ interface IWireAgentDefinitionSummary {
15
+ name: string;
16
+ description: string;
17
+ definedIn: string;
18
+ }
19
+ /**
20
+ * #3189: one entry of the session's full history as it crosses the wire. The same record the session
21
+ * keeps, except that `timestamp` is an ISO 8601 string: a `Date` does not survive JSON, and a
22
+ * declared `Date` that arrives as a string would let a client call `Date` methods on a string.
23
+ */
24
+ interface IWireHistoryEntry extends Omit<THistoryEntry, 'timestamp'> {
25
+ /** ISO 8601. */
26
+ timestamp: string;
27
+ }
28
+ /**
29
+ * #3189: a turn's result as it crosses the wire. The session's whole history stays behind: it only
30
+ * grows, so a client reads it in bounded pages with `get-history` instead.
31
+ */
32
+ type TWireExecutionResult = Omit<IExecutionResult, 'history'>;
9
33
  /** Inbound message from client to server. */
10
34
  type TClientMessage = {
11
35
  type: 'submit';
@@ -14,14 +38,49 @@ type TClientMessage = {
14
38
  type: 'command';
15
39
  name: string;
16
40
  args?: string;
41
+ requestId?: string;
17
42
  } | {
18
43
  type: 'abort';
19
44
  } | {
20
45
  type: 'cancel-queue';
21
46
  } | {
22
47
  type: 'get-messages';
48
+ } | {
49
+ type: 'get-history';
50
+ fromIndex?: number;
51
+ } | {
52
+ type: 'get-prompts';
23
53
  } | {
24
54
  type: 'get-context';
55
+ } | {
56
+ type: 'get-commands';
57
+ } | {
58
+ type: 'get-status';
59
+ } | {
60
+ type: 'list-models';
61
+ requestId: string;
62
+ } | {
63
+ type: 'get-agent-definitions';
64
+ requestId: string;
65
+ } | {
66
+ type: 'list-sessions';
67
+ requestId: string;
68
+ } | {
69
+ type: 'new-session';
70
+ requestId?: string;
71
+ } | {
72
+ type: 'switch-session';
73
+ sessionId: string;
74
+ requestId?: string;
75
+ } | {
76
+ type: 'rename-session';
77
+ sessionId: string;
78
+ name: string;
79
+ requestId: string;
80
+ } | {
81
+ type: 'delete-session';
82
+ sessionId: string;
83
+ requestId: string;
25
84
  } | {
26
85
  type: 'get-usage-report';
27
86
  } | {
@@ -39,6 +98,24 @@ type TClientMessage = {
39
98
  type: 'get-pending';
40
99
  } | {
41
100
  type: 'get-execution-workspace';
101
+ } | {
102
+ type: 'read-execution-detail';
103
+ requestId: string;
104
+ entryId: string;
105
+ cursor?: IExecutionDetailCursor;
106
+ } | {
107
+ type: 'stop-waiting-loop';
108
+ requestId: string;
109
+ } | {
110
+ type: 'project-status';
111
+ requestId: string;
112
+ } | {
113
+ type: 'project-diff';
114
+ requestId: string;
115
+ path: string;
116
+ } | {
117
+ type: 'project-memory';
118
+ requestId: string;
42
119
  } | {
43
120
  type: 'get-background-tasks';
44
121
  filter?: IBackgroundTaskListFilter;
@@ -82,6 +159,13 @@ type TClientMessage = {
82
159
  } | {
83
160
  type: 'ack';
84
161
  seq: number;
162
+ } | {
163
+ type: 'get-settings';
164
+ requestId: string;
165
+ } | {
166
+ type: 'update-settings';
167
+ requestId: string;
168
+ patch: TSettingsPatch;
85
169
  };
86
170
  /** Outbound message from server to client. */
87
171
  type TServerMessage = {
@@ -106,15 +190,32 @@ type TServerMessage = {
106
190
  driverId?: TDriverId;
107
191
  } | {
108
192
  type: 'complete';
109
- result: IExecutionResult;
193
+ result: TWireExecutionResult;
110
194
  driverId?: TDriverId;
111
195
  } | {
112
196
  type: 'interrupted';
113
- result: IExecutionResult;
197
+ result: TWireExecutionResult;
114
198
  driverId?: TDriverId;
115
199
  } | {
116
200
  type: 'error';
201
+ /** The raw failure text — kept for a "Details" disclosure; never the whole story on its own. */
117
202
  message: string;
203
+ /**
204
+ * What kind of failure this was, when it's known — so a renderer can say what happened and
205
+ * what to do next in plain words instead of showing `message` verbatim (#3289 §3). Additive:
206
+ * absent for a session error this classification does not recognize (unchanged behavior).
207
+ */
208
+ code?: 'auth' | 'rate_limit' | 'model_unavailable' | 'network' | 'provider';
209
+ /** The provider/profile name the failure came from, when `code` names one. */
210
+ provider?: string;
211
+ /** For `code: 'rate_limit'`, how long until a retry may succeed, when the provider said so. */
212
+ retryAfterSeconds?: number;
213
+ /**
214
+ * For `code: 'model_unavailable'`, the model the failed request tried — captured at the moment
215
+ * of failure so a renderer never has to fall back to whatever model is live by the time it
216
+ * draws this notice (which may already be a different one the person switched to).
217
+ */
218
+ model?: string;
118
219
  driverId?: TDriverId;
119
220
  } | {
120
221
  type: 'command_result';
@@ -122,12 +223,91 @@ type TServerMessage = {
122
223
  message: string;
123
224
  success: boolean;
124
225
  data?: ICommandResult['data'];
226
+ /** The `requestId` of the `command` this answers, when it carried one. */
227
+ requestId?: string;
125
228
  } | {
126
229
  type: 'messages';
127
230
  messages: ReturnType<ISessionConversationRead['getMessages']>;
231
+ /**
232
+ * #3288 §2: the SAME history, projected into display segments (text runs and finished tool
233
+ * calls, diffs included) — so a reload/reconnect/resume replay shows tool rows instead of bare
234
+ * text. Optional so an older host that has not grown `getMessagesDisplay()` yet still sends a
235
+ * valid frame; a client without this field falls back to `messages`-only (text bubbles), the
236
+ * same as before this existed.
237
+ */
238
+ display?: ReturnType<ISessionConversationRead['getMessagesDisplay']>;
239
+ /**
240
+ * #3289 §3: this connection's own server-assigned driver id, carried on the first frame every
241
+ * connection already gets — so a client can tell its OWN turns from a co-driver's instead of
242
+ * treating everything but the literal `'owner'` id as someone else (REMOTE-014 E5 display-only).
243
+ */
244
+ driverId?: TDriverId;
245
+ } | {
246
+ type: 'history';
247
+ startIndex: number;
248
+ total: number;
249
+ entries: IWireHistoryEntry[];
128
250
  } | {
129
251
  type: 'context';
130
252
  state: ReturnType<ISessionConversationRead['getContextState']>;
253
+ } | {
254
+ type: 'history_changed';
255
+ } | {
256
+ type: 'turn_source';
257
+ source: TTurnSource;
258
+ } | {
259
+ type: 'commands';
260
+ commands: ICommandListEntry[];
261
+ skills: ICommandSkillListEntry[];
262
+ } | {
263
+ type: 'session_status';
264
+ status: ISessionStatusSnapshot;
265
+ } | {
266
+ type: 'model_list';
267
+ requestId: string;
268
+ groups: readonly IModelListGroup[];
269
+ currentProfile?: string;
270
+ currentModel: string;
271
+ } | {
272
+ type: 'agent_definitions';
273
+ requestId: string;
274
+ agents: readonly IWireAgentDefinitionSummary[];
275
+ current: string;
276
+ } | {
277
+ type: 'sessions';
278
+ requestId: string;
279
+ listing: ISessionListing;
280
+ } | {
281
+ type: 'sessions_error';
282
+ requestId: string;
283
+ code: 'not_available' | 'list_failed';
284
+ message: string;
285
+ } | {
286
+ type: 'session_switched';
287
+ event: ISessionSwitchedEvent;
288
+ } | {
289
+ type: 'session_change_failed';
290
+ code: TSessionChangeRefusalCode;
291
+ message: string;
292
+ requestId?: string;
293
+ } | {
294
+ type: 'session_renamed_in_list';
295
+ requestId: string;
296
+ sessionId: string;
297
+ name: string;
298
+ } | {
299
+ type: 'session_rename_failed';
300
+ requestId: string;
301
+ message: string;
302
+ } | {
303
+ type: 'session_deleted';
304
+ requestId: string;
305
+ sessionId: string;
306
+ } | {
307
+ type: 'session_delete_failed';
308
+ requestId: string;
309
+ code: TSessionDeleteRefusalCode;
310
+ message: string;
131
311
  } | {
132
312
  type: 'usage_report';
133
313
  report: IUsageBySourceReport;
@@ -157,9 +337,34 @@ type TServerMessage = {
157
337
  } | {
158
338
  type: 'pending';
159
339
  pending: string | null;
340
+ pendingCount?: number;
160
341
  } | {
161
342
  type: 'execution_workspace_event';
162
343
  snapshot: IExecutionWorkspaceSnapshot;
344
+ } | {
345
+ type: 'execution_detail';
346
+ requestId: string;
347
+ page: IExecutionDetailPage;
348
+ } | {
349
+ type: 'execution_detail_error';
350
+ requestId: string;
351
+ message: string;
352
+ } | {
353
+ type: 'waiting_loop_stop';
354
+ requestId: string;
355
+ outcome: TWaitingLoopStopOutcome;
356
+ } | {
357
+ type: 'project_status';
358
+ requestId: string;
359
+ result: TProjectStatusRead;
360
+ } | {
361
+ type: 'project_diff';
362
+ requestId: string;
363
+ result: TProjectDiffRead;
364
+ } | {
365
+ type: 'project_memory';
366
+ requestId: string;
367
+ result: TProjectMemoryRead;
163
368
  } | {
164
369
  type: 'background_task_event';
165
370
  event: TBackgroundTaskEvent;
@@ -219,8 +424,18 @@ type TServerMessage = {
219
424
  } | {
220
425
  type: 'protocol_error';
221
426
  message: string;
427
+ requestId?: string;
222
428
  } | {
223
429
  type: 'resume_gap';
430
+ } | {
431
+ type: 'settings';
432
+ requestId: string;
433
+ settings: ISettingsSnapshot;
434
+ } | {
435
+ type: 'settings_error';
436
+ requestId: string;
437
+ code: 'not_available' | 'invalid' | 'refused' | 'update_failed';
438
+ message: string;
224
439
  };
225
440
  /**
226
441
  * REMOTE-013 E4: a server message stamped with its monotonic session sequence number (added by the
@@ -262,14 +477,22 @@ type TOutboundDeliver = ((message: TServerMessage) => void) & {
262
477
  };
263
478
  /**
264
479
  * Observe THIS connection's first outbound delivery failure. `event` is the `type` of the frame that
265
- * could not be delivered — a session event's own name for the fan-out (they are identical), and the
266
- * reply's type for a reply (`command_result`, `protocol_error`, …).
480
+ * could not be delivered — for the fan-out, the frame a session event was forwarded as (usually, not
481
+ * always, the event's own name), and the reply's type for a reply (`command_result`, `protocol_error`, …).
267
482
  *
268
483
  * Required, never optional: a carrier that could opt out of observing its own delivery failures is the
269
484
  * silent-failure shape this boundary exists to remove.
270
485
  */
271
486
  type TDeliveryErrorHandler = (error: Error, event: TServerMessage['type']) => void;
272
487
  declare const DEFAULT_MAX_PENDING_BYTES: number;
488
+ /**
489
+ * Backpressure budget for a terminal attached to a session on the same host, in either role.
490
+ *
491
+ * 1 MiB, tighter than the default: an attached terminal reads a local socket, so a backlog this large
492
+ * means it stopped reading rather than that a network is slow. Exceeding it closes that connection
493
+ * only; the session never waits for a reader, so other surfaces keep streaming.
494
+ */
495
+ declare const ATTACHED_SURFACE_MAX_PENDING_BYTES: number;
273
496
  /**
274
497
  * Is this carrier holding more than the budget allows?
275
498
  *
@@ -315,7 +538,48 @@ declare function createOutboundDelivery(send: (message: TServerMessage) => void,
315
538
  //#endregion
316
539
  //#region src/protocol-session.d.ts
317
540
  /** Session roles required by the shared WebSocket/WebRTC protocol. */
318
- interface IProtocolSession extends ISessionTurnSubmission, ISessionTurnControl, ISessionCommands, ISessionEvents, ISessionPromptResolution, ISessionConversationRead, ISessionExecutionState, ISessionDriverAttribution, ISessionBackgroundTasks, ISessionBackgroundGroups, ISessionExecutionWorkspace {}
541
+ interface IProtocolSession extends ISessionTurnSubmission, ISessionTurnControl, ISessionCommands, ISessionStatusRead, ISessionEvents, ISessionPromptResolution, ISessionConversationRead, ISessionExecutionState, ISessionDriverAttribution, ISessionBackgroundTasks, ISessionBackgroundGroups, ISessionExecutionWorkspace, ISessionExecutionDetail, ISessionSelfPacedLoopControl, ISessionAgentJobs {}
542
+ /**
543
+ * #3282 §4c: a protocol session that ALSO answers the Project panel's reads. `Partial` (not a fourth
544
+ * mandatory role on {@link IProtocolSession} itself) deliberately: every existing test double and
545
+ * every other host that builds an `IProtocolSession` keeps type-checking unchanged, and the panel's
546
+ * three methods are runtime-probed (`typeof session.readProjectStatus === 'function'`) rather than
547
+ * assumed — `InteractiveSession` (the one production implementation) provides all three, satisfying
548
+ * this type with no further wiring.
549
+ */
550
+ type TProjectReadCapableSession = IProtocolSession & Partial<ISessionProjectRead>;
551
+ //#endregion
552
+ //#region src/settings-messages.d.ts
553
+ type TSettingsMessage = Extract<TClientMessage, {
554
+ type: 'get-settings' | 'update-settings';
555
+ }>;
556
+ declare function isSettingsMessage(msg: TClientMessage): msg is TSettingsMessage;
557
+ /** What applying a patch did: the fresh snapshot, or why nothing was written. */
558
+ type TSettingsUpdateOutcome = {
559
+ readonly ok: true;
560
+ readonly settings: ISettingsSnapshot;
561
+ } | {
562
+ readonly ok: false;
563
+ readonly code: 'not_available' | 'invalid' | 'refused' | 'update_failed';
564
+ readonly message: string;
565
+ };
566
+ /**
567
+ * #3282 §4a: host-owned read/write for the Settings screen, supplied by the composition root the
568
+ * same way `IUsageQueryReporters` supplies usage reads — this package only correlates the request
569
+ * and carries the result. `updateSettings` applies through the SAME function the matching slash
570
+ * command uses (issue #3282 §4: "one code path, so the behavior matches the TUI"), so whatever a
571
+ * command would refuse on this surface is refused here too.
572
+ */
573
+ interface ISettingsReporter {
574
+ getSettings(session: IProtocolSession, locality?: TCommandSurfaceLocality): ISettingsSnapshot | Promise<ISettingsSnapshot>;
575
+ /**
576
+ * Applies through the SAME function the matching slash command uses. `locality` (#3282 §4 part
577
+ * b-2) is forwarded to that command exactly as the transport received it, so a command that
578
+ * refuses a remote surface (installing a plugin) refuses identically here.
579
+ */
580
+ updateSettings(session: IProtocolSession, patch: TSettingsPatch, locality?: TCommandSurfaceLocality): TSettingsUpdateOutcome | Promise<TSettingsUpdateOutcome>;
581
+ }
582
+ declare function handleSettingsMessage(session: IProtocolSession, deliver: TOutboundDeliver, msg: TSettingsMessage, reporter: ISettingsReporter | undefined, locality?: TCommandSurfaceLocality): void;
319
583
  //#endregion
320
584
  //#region src/usage-messages.d.ts
321
585
  interface IUsageQueryReporters {
@@ -334,17 +598,17 @@ declare const PROTOCOL_SESSION_EVENT_CLASSIFICATION: {
334
598
  readonly thinking: "forwarded";
335
599
  readonly complete: "forwarded";
336
600
  readonly error: "forwarded";
337
- readonly context_update: "non-surface";
338
- readonly compact: "non-surface";
601
+ readonly context_update: "forwarded";
602
+ readonly compact: "forwarded";
339
603
  readonly interrupted: "forwarded";
340
- readonly skill_activation: "non-surface";
604
+ readonly skill_activation: "forwarded";
341
605
  readonly background_task_event: "forwarded";
342
606
  readonly background_job_group_event: "forwarded";
343
607
  readonly execution_workspace_event: "forwarded";
344
608
  readonly user_message: "forwarded";
345
- readonly turn_source: "non-surface";
609
+ readonly turn_source: "forwarded";
346
610
  readonly context_file_refreshed: "forwarded";
347
- readonly memory_event: "non-surface";
611
+ readonly memory_event: "forwarded";
348
612
  readonly goal_event: "non-surface";
349
613
  readonly plan_event: "forwarded";
350
614
  readonly branch_event: "forwarded";
@@ -354,12 +618,20 @@ declare const PROTOCOL_SESSION_EVENT_CLASSIFICATION: {
354
618
  readonly ui_intent: "requester-routed";
355
619
  readonly session_renamed: "forwarded";
356
620
  readonly history_cleared: "forwarded";
621
+ readonly session_switched: "forwarded";
622
+ readonly status_changed: "forwarded";
357
623
  };
358
624
  //#endregion
359
625
  //#region src/session-message-handler.d.ts
626
+ /**
627
+ * What a connected surface may do. `drive` sends prompts, answers questions and controls the session.
628
+ * `observe` is read-only: it follows this session's conversation and state, but never submits, answers,
629
+ * controls, or reads another session's records, and it never counts as a surface that can answer.
630
+ */
631
+ type TSessionSurfaceRole = 'drive' | 'observe';
360
632
  interface ISessionMessageHandlerOptions {
361
- /** IProtocolSession to expose. */
362
- session: IProtocolSession;
633
+ /** IProtocolSession to expose — `Partial<ISessionProjectRead>` is probed, not assumed (#3282 §4c). */
634
+ session: TProjectReadCapableSession;
363
635
  /**
364
636
  * ARCH-030: the CARRIER's connection-scoped outbound delivery boundary — not a raw `send`, and not a
365
637
  * `send` plus an error callback for this handler to assemble into one. The carrier owns both the sink
@@ -376,12 +648,25 @@ interface ISessionMessageHandlerOptions {
376
648
  driverId?: TDriverId;
377
649
  /** Trusted carrier-owned product surface, kept separate from driver identity. */
378
650
  surface?: TUsageSurface;
651
+ /** Carrier-decided role of this connection; defaults to `drive`. The client never chooses it here. */
652
+ role?: TSessionSurfaceRole;
379
653
  /** Host-owned cross-session read model. The protocol only correlates and carries its result. */
380
654
  personalUsageReporter?: NonNullable<IUsageQueryReporters['personalUsageReporter']>;
381
655
  /** Host-owned current-session trace/cost producer for the pre-existing message family. */
382
656
  usageReporter?: NonNullable<IUsageQueryReporters['usageReporter']>;
383
657
  /** Host-owned stored-session producer used by cross-session drill-down. */
384
658
  storedSessionUsageReporter?: NonNullable<IUsageQueryReporters['storedSessionUsageReporter']>;
659
+ /** Host-owned session directory (#3189): list, start and switch the host's sessions. */
660
+ sessionDirectory?: ISessionDirectory;
661
+ /** #3282 §4a: host-owned read/write for the GUI Settings screen. */
662
+ settingsReporter?: ISettingsReporter;
663
+ /**
664
+ * #3282 §4 part b-2: carrier-decided, like `role` — whether THIS carrier's connections are
665
+ * provably on this machine. The loopback WS carrier is `'local'`; the device-mesh/WebRTC carrier
666
+ * sets `'remote'`. Absent → `'local'`, forwarded to `executeCommand` and the settings reporter so a
667
+ * command that runs code from outside the session (installing a plugin) can refuse a remote device.
668
+ */
669
+ commandSurfaceLocality?: TCommandSurfaceLocality;
385
670
  }
386
671
  /**
387
672
  * Create a carrier-neutral message handler for an IProtocolSession.
@@ -407,6 +692,10 @@ declare function createSessionMessageHandler(options: ISessionMessageHandlerOpti
407
692
  cleanup: () => void;
408
693
  };
409
694
  //#endregion
695
+ //#region src/observer-messages.d.ts
696
+ /** Whether an observer may send a message of this type. */
697
+ declare function isObserverMessageType(type: string): boolean;
698
+ //#endregion
410
699
  //#region src/message-decoders.d.ts
411
700
  type TMessageDecodeResult<TMessage> = {
412
701
  readonly ok: true;
@@ -528,6 +817,8 @@ interface ISessionResumeBridgeOptions {
528
817
  readonly personalUsageReporter?: IUsageQueryReporters['personalUsageReporter'];
529
818
  readonly usageReporter?: IUsageQueryReporters['usageReporter'];
530
819
  readonly storedSessionUsageReporter?: IUsageQueryReporters['storedSessionUsageReporter'];
820
+ /** #3282 §4 part b-2: this bridge is the reconnectable WebRTC path, so it is always `'remote'`. */
821
+ readonly commandSurfaceLocality?: TCommandSurfaceLocality;
531
822
  }
532
823
  declare class SessionResumeBridge {
533
824
  private readonly session;
@@ -535,6 +826,7 @@ declare class SessionResumeBridge {
535
826
  private driverId?;
536
827
  private readonly reporters;
537
828
  private readonly surface?;
829
+ private readonly commandSurfaceLocality?;
538
830
  private readonly unsubscribe;
539
831
  private onDeliveryError?;
540
832
  /**
@@ -762,5 +1054,5 @@ declare class HandoffChunkAssembler {
762
1054
  */
763
1055
  declare function chunkCountFor(integrity: IHandoffIntegrity, maxChunkBytes?: number): number;
764
1056
  //#endregion
765
- export { CHANNEL_FRAME_MAGIC, CHANNEL_FRAME_VERSION, DEFAULT_MAX_CHUNK_BYTES, DEFAULT_MAX_PENDING_BYTES, DEFAULT_MAX_PENDING_MS, HandoffChunkAssembler, type IAttachOptions, type IBufferedFrame, type IChunkResult, type IHandoffChunk, type IPeerMessageLedger, type IPeerMessageRejection, type IPeerMessageVerdict, type IPendingStallClock, type IProtocolSession, type IResumeBufferOptions, type ISessionMessageHandlerOptions, type ISessionResumeBridgeOptions, MAX_INBOUND_FRAME_BYTES, PROTOCOL_SESSION_EVENT_CLASSIFICATION, ResumeBuffer, SessionResumeBridge, type TChunkOutcome, type TChunkRejection, type TClientMessage, type TDeliveryErrorHandler, type TMessageDecodeResult, type TOutboundDeliver, type TProtocolSessionEventClassification, type TResumeSink, type TResumeTail, type TSeqServerMessage, type TServerMessage, acknowledgePeerMessage, admitPeerMessage, chunkCountFor, chunkHandoffPayload, createOutboundDelivery, createPeerMessageLedger, createPendingStallClock, createSessionMessageHandler, decodeChannelFrame, decodeClientMessage, decodeFrame, decodeServerMessage, encodeBinaryFrame, encodeChannelEventFrame, forgetPeerOrigin, isChannelFrame, isOverPendingBudget };
1057
+ export { ATTACHED_SURFACE_MAX_PENDING_BYTES, CHANNEL_FRAME_MAGIC, CHANNEL_FRAME_VERSION, DEFAULT_MAX_CHUNK_BYTES, DEFAULT_MAX_PENDING_BYTES, DEFAULT_MAX_PENDING_MS, HandoffChunkAssembler, type IAttachOptions, type IBufferedFrame, type IChunkResult, type IHandoffChunk, type IPeerMessageLedger, type IPeerMessageRejection, type IPeerMessageVerdict, type IPendingStallClock, type IProtocolSession, type IResumeBufferOptions, type ISessionMessageHandlerOptions, type ISessionResumeBridgeOptions, type ISettingsReporter, type IWireAgentDefinitionSummary, type IWireHistoryEntry, MAX_INBOUND_FRAME_BYTES, PROTOCOL_SESSION_EVENT_CLASSIFICATION, ResumeBuffer, SessionResumeBridge, type TChunkOutcome, type TChunkRejection, type TClientMessage, type TDeliveryErrorHandler, type TMessageDecodeResult, type TOutboundDeliver, type TProtocolSessionEventClassification, type TResumeSink, type TResumeTail, type TSeqServerMessage, type TServerMessage, type TSessionSurfaceRole, type TSettingsUpdateOutcome, type TWireExecutionResult, acknowledgePeerMessage, admitPeerMessage, chunkCountFor, chunkHandoffPayload, createOutboundDelivery, createPeerMessageLedger, createPendingStallClock, createSessionMessageHandler, decodeChannelFrame, decodeClientMessage, decodeFrame, decodeServerMessage, encodeBinaryFrame, encodeChannelEventFrame, forgetPeerOrigin, handleSettingsMessage, isChannelFrame, isObserverMessageType, isOverPendingBudget, isSettingsMessage };
766
1058
  //# sourceMappingURL=index.d.cts.map