thinkpool-pair 0.7.435 → 0.7.436

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.
@@ -0,0 +1 @@
1
+ import{claimTurnReceipt as e}from"./turn-receipt.mjs";const t=4194304,n=new Set(["received","prepared","dispatching","dispatched","completed","recovery_required"]),r=e=>Buffer.byteLength(JSON.stringify(e)),o=()=>new Error("Command journal capacity is full; pending commands must be resolved first.");export function restoreCommandJournal(e){const a=(Array.isArray(e)?e:[]).filter(e=>e&&"string"==typeof e.cid&&n.has(e.state));if(a.length>128||a.reduce((e,t)=>e+r(t.payload),0)>t)throw o();return a}export function recordCommand(e,n){const a="string"==typeof n?.cid?n.cid:"";if(!a)return null;const i=e.commandJournal||(e.commandJournal=[]),d=i.find(e=>e.cid===a);if(d)return d;const s=JSON.stringify(n),c=Buffer.byteLength(s);if(c>1048576)throw new Error("Command is too large to persist safely.");let m=i.reduce((e,t)=>e+r(t.payload),0);for(;i.length>=128||m+c>t;){const e=i.findIndex(e=>"completed"===e.state);if(e<0)throw o();m-=r(i[e].payload),i.splice(e,1)}const u={cid:a,state:"received",payload:JSON.parse(s),createdAt:Date.now(),updatedAt:Date.now()};return i.push(u),u}export function transitionCommand(e,t,r){if(!n.has(r))throw new TypeError(`invalid command journal state: ${r}`);const o=e?.commandJournal?.find(e=>e.cid===t);return o?("completed"===o.state&&"dispatched"===r||(o.state=r,o.updatedAt=Date.now()),o):null}export function acceptDurableCommand(t,n){if(t.receivedTurnCids?.has(n.cid))return{duplicate:!0,claimed:!1};const r=[...t.commandJournal||[]],o=new Set(t.receivedTurnCids||[]);try{recordCommand(t,n);const r=e(t,n.cid);if(!0!==t.flush?.())throw new Error("Command persistence failed; no receipt was issued.");return r}catch(e){throw t.commandJournal=r,t.receivedTurnCids=o,e}}export function beginCommandDispatch(e,t){if(!t)return;const n=e.commandJournal?.find(e=>e.cid===t);if(!n)throw new Error("Command has no durable receipt.");const r=n.state;if(transitionCommand(e,t,"dispatching"),!0!==e.flush?.())throw n.state=r,new Error("Command dispatch persistence failed; agent was not called.");const o=e._dispatchingCommandCids||(e._dispatchingCommandCids=[]);o.includes(t)||o.push(t)}export function takeCommandResult(e){return e._dispatchingCommandCids?.shift()||null}export function completeCommand(e,t){if(!t)return!1;const n=e.commandJournal?.find(e=>e.cid===t);if(!n)return!1;const r=n.state;return transitionCommand(e,t,"completed"),!0!==e.flush?.()?(n.state=r,!1):(e._dispatchingCommandCids&&(e._dispatchingCommandCids=e._dispatchingCommandCids.filter(e=>e!==t)),!0)}export function recoverableCommands(e){const t=[];for(const n of e?.commandJournal||[])"received"===n.state||"prepared"===n.state?t.push({...n,recovery:"safe_redelivery"}):"completed"!==n.state&&(n.state="recovery_required",n.updatedAt=Date.now(),t.push({...n,recovery:"dispatch_uncertain"}));return t}
@@ -1 +1 @@
1
- const e=e=>new Promise(t=>setTimeout(t,e));export const acceptedRealtimeDelivery=e=>"ok"===e||!0===e?.success;export function createEventDeliveryQueue({send:t,wait:n=e,retryDelay:r=e=>Math.min(1e4,250*2**Math.min(e,6))}={}){if("function"!=typeof t)throw new TypeError("event delivery queue requires send(frame)");const l=[];let a=!1,c=!1,o=Promise.resolve(),s=null;const i=async()=>{if(!a&&!c){a=!0;try{for(;!c&&l.length;){const e=l[0];let a=null;try{a=await t(e.frame)}catch{a=null}acceptedRealtimeDelivery(a)||!1===e.retry?l.shift():(e.attempt+=1,await n(r(e.attempt)))}}finally{a=!1,!l.length&&s&&(s(),s=null),!c&&l.length&&i()}}};return{enqueue(e,{coalesceKey:t=null,retry:n=!0}={}){if(c)return!1;l.length||a||(o=new Promise(e=>{s=e}));const r=l.length-1;return t&&r>=(a?1:0)&&l[r]?.coalesceKey===t?l[r]={frame:e,attempt:0,coalesceKey:t,retry:n}:l.push({frame:e,attempt:0,coalesceKey:t,retry:n}),i(),!0},pending:()=>l.length,whenIdle:()=>o,close(){c=!0,l.length=0,s&&(s(),s=null)}}}
1
+ const e=e=>new Promise(t=>setTimeout(t,e)),t=e=>{try{return Buffer.byteLength(JSON.stringify(e))}catch{return 1/0}};export const acceptedRealtimeDelivery=e=>"ok"===e||!0===e?.success;export function createEventDeliveryQueue({send:r,wait:n=e,retryDelay:l=e=>Math.min(1e4,250*2**Math.min(e,6)),maxFrames:c=4096,maxBytes:a=8388608,sizeOf:s=t,onDrained:i=null}={}){if("function"!=typeof r)throw new TypeError("event delivery queue requires send(frame)");const o=[];let u=0,y=!1,f=!1,h=Promise.resolve(),p=null;const m=e=>{const[t]=o.splice(e,1);return t&&(u-=t.bytes),t},d=async()=>{if(!y&&!f){y=!0;try{for(;!f&&o.length;){const e=o[0];let t=null;try{t=await r(e.frame)}catch{t=null}acceptedRealtimeDelivery(t)||!1===e.retry?m(0):(e.attempt+=1,await n(l(e.attempt)))}}finally{if(y=!1,!o.length){p&&(p(),p=null);try{i?.()}catch{}}!f&&o.length&&d()}}};return{enqueue(e,{coalesceKey:t=null,retry:r=!0}={}){if(f)return{accepted:!1,reason:"closed"};let n=1/0;try{n=s(e)}catch{n=1/0}if(!Number.isFinite(n)||n>a)return{accepted:!1,reason:"frame_too_large"};if(o.length||y||(h=new Promise(e=>{p=e})),t){const e=(e=>{for(let t=o.length-1;t>=(y?1:0)&&!o[t].barrier;t--)if(o[t].coalesceKey===e)return t;return-1})(t);e>=0&&m(e)}for(;o.length>=c||u+n>a;){const e=o.findIndex((e,t)=>t>=(y?1:0)&&e.coalesceKey);if(e<0)return{accepted:!1,reason:"backpressure",pending:o.length,bytes:u};m(e)}return o.push({frame:e,bytes:n,attempt:0,coalesceKey:t,retry:r,barrier:!t}),u+=n,d(),{accepted:!0,pending:o.length,bytes:u}},pending:()=>o.length,pendingBytes:()=>u,whenIdle:()=>h,close(){f=!0,o.length=0,u=0,p&&(p(),p=null)}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thinkpool-pair",
3
- "version": "0.7.435",
3
+ "version": "0.7.436",
4
4
  "description": "Connect Claude Code, Codex, or Hermes on your computer to a thinkpool Code room.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -96,6 +96,9 @@
96
96
  "event-bounds.mjs",
97
97
  "replay-transport.mjs",
98
98
  "event-delivery-queue.mjs",
99
+ "transport-frame.mjs",
100
+ "turn-admission.mjs",
101
+ "durable-command-journal.mjs",
99
102
  "mcp-flight-recorder.mjs",
100
103
  "plan-meters.mjs",
101
104
  "recap.mjs",
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "format": 1,
3
3
  "package": "thinkpool-pair",
4
- "version": "0.7.435",
4
+ "version": "0.7.436",
5
5
  "kind": "minified",
6
- "minifiedModules": 144,
7
- "sourceModuleBytes": 1924502,
8
- "artifactModuleBytes": 883780,
6
+ "minifiedModules": 147,
7
+ "sourceModuleBytes": 1962774,
8
+ "artifactModuleBytes": 901772,
9
9
  "files": {
10
- "package.json": "e1de365d7934d253931e2b15dbc8dd2b922ad1e078e1e834878e975ae9f99d43",
10
+ "package.json": "5833ab9ac6e1d72990fb74a057b182e70ce11ce5f213b5b0b6b7c8cf252473b6",
11
11
  "LICENSE": "8a030197ca1cad9669909ca14c9ad15cf48d9fe551da526ccaf1fca993eddb23",
12
- "bridge.mjs": "769f36a59ccc9fcb54cac95e52b6e662603e01809aef55083ebf4fae9a302540",
12
+ "bridge.mjs": "da36ec2fb269640e7b391f46a69b2d1e9f4649ba94201cc1e95e2503d22b45c4",
13
13
  "bridge-service.sh": "b64f27c473ca8f3a49190fd08c23947ab14ca9958d70b6fa53c7bddc2be91403",
14
14
  "command-guidance.mjs": "b9b967b59ff4e77c9613abb0f28858bf3ac5b106a509e471039777b53bec3e29",
15
15
  "abort-turn-barrier.mjs": "3734a5b7e2e940ec6d7fa8b5b04935e1429a23d1bd9e92b2ac2a2ecd9f77c75e",
@@ -94,15 +94,18 @@
94
94
  "scheduled-run-admission.mjs": "3a2098d904c3aff571bf314e0182d5636d25d242cef52207e70f9dc1618c94f5",
95
95
  "event-id.mjs": "09c75e7fc8da282fc00651add58e5d2f82d3020e0c4dddb9921250cf9a6fa8c0",
96
96
  "event-bounds.mjs": "aa8eb8517c4aa81b3378f71401ed39c550cdc80e28e3a57ab46d0a5ef5c7c9c1",
97
- "replay-transport.mjs": "f4ed49dc023e3bb2d9534814bc2684121caafe4d24151b87688407eda47c6c7a",
98
- "event-delivery-queue.mjs": "9fd955766e5b6ff3209c59bf916f469784061cfee75b50ae519208d135603fff",
97
+ "replay-transport.mjs": "f17bd7ac0aaaaf096d7969ea8c54ee9d084e366b62a561bf5f656ed30c010465",
98
+ "event-delivery-queue.mjs": "0ed00938cca30627896a944fbdf8da21f91341e6d96a3ca190777843b302025f",
99
+ "transport-frame.mjs": "05ea57f34699d17131c0a2917d8e43c77e60186c1c2105bc89520d2e889e8aea",
100
+ "turn-admission.mjs": "d327a8a1226dfde72c71a2585f9e69230cb8cdfc978e78556241c3403156d06e",
101
+ "durable-command-journal.mjs": "787142debc5472299155b32d0684d594e9c577b669e50554b9b3b38619355e2c",
99
102
  "mcp-flight-recorder.mjs": "30bf77f4d567f0449856d6da09f7a0a9c8d7e12c5dcaf200dc9e511a331425be",
100
103
  "plan-meters.mjs": "f7f5aeb3d6a3462b754d3724367bbb331643ba58108e29e91b2aca2f613ab499",
101
104
  "recap.mjs": "10e67aa933fa8bac4059878167d578f87db3184d7affd168c46c5134c6e97c8b",
102
105
  "transcript-sanitize.mjs": "c7f4718f25f97c05bc7b4ad8e09f18cbda152c53ad6593af1ab99f0c132dbf01",
103
106
  "agent-output-hygiene.mjs": "914b04daa5b60342b5e44737cfba99f2c8ac292826db1fe501f653814454c835",
104
107
  "session-search.mjs": "d606fbab5c47357071e4919107aa00ad090f6e7d7e6dc929e0ac5a4d0cb2c538",
105
- "session-store.mjs": "fa3f7a27a8a7c49bb89364fb28c9c2680f7f487d4b4125329ab4a0ba9362bd8c",
108
+ "session-store.mjs": "b4b07ead290a74014b8669e2b86d79d781f34ee890265bc6b9476481f575e1a4",
106
109
  "side-lane.mjs": "6a6bc6d8041872ba4472d70fd1cece62607417982a72b8721f4fbed77655cc6d",
107
110
  "worker-completion.mjs": "3eab6abf9cde32e62b8bef676023bd59759836f88887d578d2db2e9fa092a151",
108
111
  "cross-terminal.mjs": "08d3889516f0b7edd7628dccb61b32731ab1e033efcc19f597a3d29a053fe020",
@@ -1 +1 @@
1
- export function requestedReplayIds(n,e,r){const t=Array.isArray(e)?new Set(e.filter(Boolean)):null;return[...n].filter(([n])=>!t||t.has(n)).sort(([n],[e])=>n===r?-1:e===r?1:0)}const n=()=>new Promise(n=>setTimeout(n,0));export function createLatestReplayPump({send:e,yieldTurn:r=n}={}){if("function"!=typeof e)throw new TypeError("replay pump requires send(frame)");const t=new Map,o=async(n,a)=>{if(!a.running){a.running=!0;try{for(;a.frames.length;){a.generation;const n=a.frames.shift();await e(n),await r(),a.generation}const n=a.onDone;a.onDone=null,n&&await n()}finally{a.running=!1,a.frames.length?o(n,a):t.get(n)===a&&t.delete(n)}}};return{enqueue(n,e,r=null){const a=String(n||"*"),i=t.get(a)||{generation:0,frames:[],onDone:null,running:!1};return i.generation+=1,i.frames=Array.isArray(e)?[...e]:[],i.onDone="function"==typeof r?r:null,t.set(a,i),o(a,i),i.generation},cancel(n){const e=t.get(String(n||"*"));return!!e&&(e.generation+=1,e.frames=[],e.onDone=null,!0)},pending:n=>t.get(String(n||"*"))?.frames.length||0}}
1
+ export function requestedReplayIds(e,r,t){const n=Array.isArray(r)?new Set(r.filter(Boolean)):null;return[...e].filter(([e])=>!n||n.has(e)).sort(([e],[r])=>e===t?-1:r===t?1:0)}export function replayChunkRanges(e,{budget:t=15e4,maxChunks:n=14,sizeOf:o=r}={}){if(!Array.isArray(e)||!e.length)return[];const a=[];let i=e.length,l=i,s=0;for(let r=e.length-1;r>=0;r--){let u=1/0;try{u=o(e[r])}catch{u=1/0}if(!Number.isFinite(u))return[];if(l<i&&s+u>t){if(a.push([l,i]),a.length>=n)break;i=r+1,l=i,s=0}l=r,s+=u}return l<i&&a.length<n&&a.push([l,i]),a.reverse()}const e=()=>new Promise(e=>setTimeout(e,0)),r=e=>{try{return Buffer.byteLength(JSON.stringify(e))}catch{return 1/0}},t=e=>"ok"===e||!0===e?.success;export function createLatestReplayPump({send:n,yieldTurn:o=e,maxViewers:a=32,maxQueuedBytes:i=4194304,maxConcurrent:l=2,maxFrameBytes:s=262144,maxRetries:u=2,operationTimeoutMs:c=1e4,identifyViewer:d=e=>"symbol"==typeof e?e:String(e||"*"),onError:f=null}={}){if("function"!=typeof n)throw new TypeError("replay pump requires send(frame)");const g=new Map;let y=0,m=0,h=0;const p=Math.min(s,i),w=(e,r)=>new Promise((t,n)=>{const o=new AbortController;let a;const i=(e,o)=>{clearTimeout(a),r.removeEventListener("abort",l),e?n(e):t(o)},l=()=>{o.abort(),i(new Error("replay_cancelled"))};r.aborted?l():(r.addEventListener("abort",l,{once:!0}),a=setTimeout(()=>{o.abort(),i(new Error("replay_deadline"))},Math.max(1,c)),Promise.resolve().then(()=>{if(o.signal.aborted)throw new Error("replay_cancelled");return e(o.signal)}).then(e=>i(null,e),e=>i(e)))}),b=async(e,r,t,n=null)=>{if(g.get(e)===r){g.delete(e);try{await(f?.({viewer:e,reason:t,error:n}))}catch{}}},v=()=>{if(!(m>=l||h+p>i))for(const[e,r]of g)r.running||r.scheduled||!r.source||(r.scheduled=!0,Promise.resolve().then(()=>x(e,r)))},x=async(e,a)=>{if(a.scheduled=!1,g.get(e)!==a||!a.source||a.running||m>=l||h+p>i)return;a.running=!0,m+=1,h+=p;let s=0;const c=a.generation,d=a.controller.signal;try{const i=a.source,l=await w(()=>i.next(),d);if(c!==a.generation||g.get(e)!==a)return;if(l.done){const r=a.onDone;return a.source=null,a.onDone=null,r&&await w(()=>r(),d),void(g.get(e)===a&&c===a.generation&&g.delete(e))}const f=l.value,m=r(f);if(!Number.isFinite(m)||m>p)return void await b(e,a,"frame_too_large");s=m,y+=s;let h=!1,v=null;for(let e=0;e<=u&&c===a.generation;e++){try{h=t(await w(e=>n(f,{signal:e}),d))}catch(e){v=e}if(h)break;await o()}if(c!==a.generation||g.get(e)!==a)return;if(!h)return void await b(e,a,"send_failed",v);await o()}catch(r){c===a.generation&&await b(e,a,"source_failed",r)}finally{y-=s,h-=p,a.running=!1,m-=1,g.get(e)!==a||a.source||g.delete(e),v()}};return{canAccept(e){const r=d(e);return!!r&&(g.has(r)||g.size<a)},enqueue(e,r,t=null){const n=d(e);if(!n)return{accepted:!1,reason:"invalid_viewer"};let o,i=g.get(n);if(!i&&g.size>=a)return{accepted:!1,reason:"viewer_limit"};try{o=(e=>{const r="function"==typeof e?e():e;return r?.[Symbol.asyncIterator]?r[Symbol.asyncIterator]():r?.[Symbol.iterator]?r[Symbol.iterator]():[][Symbol.iterator]()})(r)}catch{return{accepted:!1,reason:"invalid_source"}}return i||(i={generation:0,source:null,onDone:null,running:!1,scheduled:!1},g.set(n,i)),i.controller?.abort(),i.controller=new AbortController,i.generation+=1,i.source=o,i.onDone="function"==typeof t?t:null,v(),{accepted:!0,generation:i.generation}},cancel(e){const r=d(e),t=g.get(r);return!!t&&(t.generation+=1,t.controller?.abort(),t.source=null,t.onDone=null,t.running||g.delete(r),!0)},pending:e=>g.has(d(e))?1:0,stats:()=>({viewers:g.size,queuedBytes:y,active:m,reservedBytes:h})}}
package/session-store.mjs CHANGED
@@ -1 +1 @@
1
- import e from"node:os";import t from"node:fs";import n from"node:path";import{matchSessionEvents as r}from"./session-search.mjs";import{SPAWN as o}from"./cross-terminal.mjs";import{boundStructuredLog as c}from"./event-bounds.mjs";const s=t=>{const r=n.resolve(process.env.TP_PAIR_ROOT||n.join(e.homedir(),".thinkpool-pair")),o=n.resolve(r,t||"default");if(o!==r&&!o.startsWith(r+n.sep))throw new Error(`refused: room path escapes sandbox: ${JSON.stringify(t)}`);return o},i=e=>n.join(s(e),".archive");export const LIVE_SESSION_MAX=o.machineMax;function a(e){t.mkdirSync(s(e),{recursive:!0})}let u=0,l=null;function d(e,r){const o=n.join(n.dirname(e),`.${n.basename(e)}.tmp.${process.pid}.${Date.now()}.${u++}`);let c=null;try{c=t.openSync(o,"wx",384);const n=Buffer.from(r);for(let r=0;r<n.length;){const o=t.writeSync(c,n,r,n.length-r);if(o<=0)throw new Error(`short write while committing ${e}`);r+=o}return t.fsyncSync(c),t.closeSync(c),c=null,l?.({file:e,tmp:o}),t.renameSync(o,e),!0}catch(e){try{null!=c&&t.closeSync(c)}catch{}try{t.rmSync(o,{force:!0})}catch{}throw e}}export function setAtomicCommitHookForTest(e){l="function"==typeof e?e:null}function f(e,t,n){console.error(`[thinkpool-pair session-store] ${e} failed for ${t}: ${n?.message||n}`)}function m(e,r){try{t.mkdirSync(i(e),{recursive:!0});const o=n.basename(r),c=n.join(i(e),`${o}.${Date.now()}`);return t.renameSync(r,c),!0}catch(e){return f("archive session snapshot",r,e),!1}}function h(e){try{return t.readdirSync(s(e)).filter(e=>e.endsWith(".json")).map(r=>{const o=n.join(s(e),r);try{const e=JSON.parse(t.readFileSync(o,"utf8"));try{const n=t.statSync(o);e._bt=n.birthtimeMs||n.mtimeMs||0}catch{e._bt=0}return e}catch(e){return f("parse session snapshot",o,e),null}}).filter(Boolean)}catch{return[]}}const y=(e,t)=>n.join(s(e),`${t}.events.jsonl`);export function appendDurableEvents(e,n,r){if(e&&n&&Array.isArray(r)&&r.length)try{a(e),t.appendFileSync(y(e,n),r.map(e=>JSON.stringify(e)).join("\n")+"\n")}catch{}}export function seedDurableEvents(e,n,r){if(e&&n&&Array.isArray(r)&&r.length)try{a(e);const o=y(e,n);if(t.existsSync(o))return;t.writeFileSync(o,r.map(e=>JSON.stringify(e)).join("\n")+"\n")}catch{}}export function hasDurableArchive(e,n){try{return!!e&&!!n&&t.existsSync(y(e,n))}catch{return!1}}export function servesHistoryPage({payloadHost:e,bridgeName:t,hasSession:n,hasArchive:r}){return!(e&&e!==t||!n&&!r)}function p(e){let t=0,n=-1/0;for(let r=0;r<e.length;r++){const o=e[r]?.seq;"number"==typeof o&&(o<=n?(t=r,n=o):n=o)}return t}function S(e,n){const r=y(e,n);if(!t.existsSync(r))return null;const o=[];for(const e of t.readFileSync(r,"utf8").split("\n"))if(e)try{o.push(JSON.parse(e))}catch{}return o}export function readDurableOldestSeq(e,t){try{const n=S(e,t);if(!n)return null;for(let e=p(n);e<n.length;e++)if(n[e]&&null!=n[e].seq)return n[e].seq;return null}catch{return null}}export function readDurablePage(e,t,n,r=200){try{const o=S(e,t);if(!o)return{events:[],hasMore:!1};const c=p(o);let s=o.length;if(null!=n){const e=o.findIndex((e,t)=>t>=c&&e&&null!=e.seq&&e.seq>=n);e>=0&&(s=e)}const i=Math.max(c,s-r);return{events:o.slice(i,Math.max(i,s)),hasMore:i>c}}catch{return{events:[],hasMore:!1}}}export function searchDurableSessionEvents(e,t,n,{limit:o=200}={}){try{const c=[];for(const n of t||[]){const t=String(n?.term||"");if(!t)continue;const r=S(e,t);r&&c.push({term:t,termName:n.termName||"terminal",events:r.slice(p(r))})}return r(c,n,{limit:o})}catch{return{results:[],truncated:!1}}}const g=new Map;function x(e,r,o){const i=n.join(s(e),`${r}.json`);try{a(e);const u=Array.isArray(o?.log)?c(o.log):o?.log;return d(i,JSON.stringify({...o,...u?{log:u}:{},id:r,savedAt:Date.now()})),function(e){try{const r=loadNames(e),o=e=>{try{return JSON.parse(t.readFileSync(e,"utf8")).id}catch{return null}};t.readdirSync(s(e)).filter(e=>e.endsWith(".json")).map(r=>{const o=n.join(s(e),r);let c=0;try{c=JSON.parse(t.readFileSync(o,"utf8")).savedAt||0}catch{}return{p:o,f:r,m:c}}).sort((e,t)=>t.m-e.m).filter(e=>{const t=o(e.p);return!t||!r[t]}).slice(LIVE_SESSION_MAX).forEach(t=>m(e,t.p))}catch(t){f("prune live session snapshots",s(e),t)}}(e),!0}catch(e){return f("write session snapshot",i,e),!1}}export function saveSession(e,t,n){clearTimeout(g.get(t)),g.set(t,setTimeout(()=>x(e,t,n),1500))}export function flushSession(e,t,n){return clearTimeout(g.get(t)),x(e,t,n)}export function deleteSession(e,r){clearTimeout(g.get(r)),g.delete(r);const o=n.join(s(e),`${r}.json`);try{return!t.existsSync(o)||m(e,o)}catch(e){return f("archive closed session snapshot",o,e),!1}}const A=e=>n.join(s(e),".scheduled-outcomes"),v=e=>"string"==typeof e&&/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,159}$/.test(e),O=e=>"string"==typeof e&&/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,159}$/.test(e),w=e=>{try{const n=JSON.parse(t.readFileSync(A(e),"utf8"));return n&&"object"==typeof n&&!Array.isArray(n)?n:{}}catch{return{}}},b=e=>{if(!e||"object"!=typeof e||Array.isArray(e))return null;if(1===e.v&&"acknowledged"===e.state){const t=e.intent;return t&&"object"==typeof t&&!Array.isArray(t)&&O(t.runId)&&e.runId===t.runId?{intent:t,acknowledged:!0}:null}return O(e.runId)?{intent:e,acknowledged:!1}:null};export function savePendingScheduledOutcome(e,t,n){if(!v(t)||!n||"object"!=typeof n||Array.isArray(n)||!O(n.runId))return!1;try{a(e);const r=w(e);return r[t]=n,d(A(e),JSON.stringify(r)),!0}catch(t){return f("write scheduled outcome outbox",A(e),t),!1}}export function loadPendingScheduledOutcomes(e){return Object.entries(w(e)).map(([e,t])=>({terminalId:e,record:b(t)})).filter(({terminalId:e,record:t})=>v(e)&&t).map(({terminalId:e,record:t})=>({terminalId:e,intent:t.intent,...t.acknowledged?{acknowledged:!0}:{}})).slice(0,LIVE_SESSION_MAX)}export function loadPendingScheduledOutcome(e,t){return v(t)&&b(w(e)[t])?.intent||null}export function acknowledgePendingScheduledOutcome(e,t,n){if(!v(t)||!O(n))return!1;try{const r=w(e),o=b(r[t]);return!(!o||o.intent.runId!==n||(o.acknowledged||(r[t]={v:1,state:"acknowledged",runId:n,intent:o.intent},d(A(e),JSON.stringify(r))),0))}catch(t){return f("acknowledge scheduled outcome outbox",A(e),t),!1}}export function deletePendingScheduledOutcome(e,n){if(!v(n))return!1;try{const r=w(e);return!(n in r)||(delete r[n],Object.keys(r).length?d(A(e),JSON.stringify(r)):t.rmSync(A(e),{force:!0}),!0)}catch(t){return f("delete scheduled outcome outbox",A(e),t),!1}}export function commitRecordedScheduledOutcome(e,t,r){let o=!1;try{o="function"==typeof r&&!0===r()}catch(r){f("record scheduled outcome in session snapshot",n.join(s(e),`${t}.json`),r)}if(!o)return{ok:!1,snapshotRecorded:!1,outboxAcknowledged:!1,outboxDeleted:!1};const c=loadPendingScheduledOutcome(e,t);if(!acknowledgePendingScheduledOutcome(e,t,c?.runId))return{ok:!1,snapshotRecorded:!0,outboxAcknowledged:!1,outboxDeleted:!1};const i=deletePendingScheduledOutcome(e,t);return{ok:i,snapshotRecorded:!0,outboxAcknowledged:!0,outboxDeleted:i}}export function loadLatest(e){return h(e).sort((e,t)=>(t.savedAt||0)-(e.savedAt||0))[0]||null}export function canResume(e){return!!(e&&e.sessionId&&e.savedAt&&Date.now()-e.savedAt<432e5)}export function loadAll(e){return h(e).sort((e,t)=>(e.savedAt||0)-(t.savedAt||0))}export function loadArchived(e,r=40){try{return t.readdirSync(i(e)).map(r=>{const o=n.join(i(e),r);try{const e=t.statSync(o);if(!e.isFile())return null;const n=JSON.parse(t.readFileSync(o,"utf8"));return n&&Array.isArray(n.log)?{...n,_archivedAt:e.mtimeMs||0}:null}catch{return null}}).filter(Boolean).sort((e,t)=>(t._archivedAt||t.savedAt||0)-(e._archivedAt||e.savedAt||0)).slice(0,Math.max(1,Math.min(100,Number(r)||40)))}catch{return[]}}const j=e=>n.join(s(e),".pty-id");export function loadPtyId(e){try{return t.readFileSync(j(e),"utf8").trim()||null}catch{return null}}export function savePtyId(e,t){const n=j(e);try{return a(e),d(n,String(t)),!0}catch(e){return f("write PTY id",n,e),!1}}const N=e=>n.join(s(e),".names");export function loadNames(e){const n=N(e);try{return JSON.parse(t.readFileSync(n,"utf8"))||{}}catch(e){return"ENOENT"!==e?.code&&f("parse terminal names",n,e),{}}}export function saveNames(e,t){const n=N(e);try{return a(e),d(n,JSON.stringify(t||{})),!0}catch(e){return f("write terminal names",n,e),!1}}
1
+ import e from"node:os";import t from"node:fs";import n from"node:path";import{searchableSessionEventText as r}from"./session-search.mjs";import{SPAWN as s}from"./cross-terminal.mjs";import{boundStructuredLog as o}from"./event-bounds.mjs";const i=t=>{const r=n.resolve(process.env.TP_PAIR_ROOT||n.join(e.homedir(),".thinkpool-pair")),s=n.resolve(r,t||"default");if(s!==r&&!s.startsWith(r+n.sep))throw new Error(`refused: room path escapes sandbox: ${JSON.stringify(t)}`);return s},a=e=>n.join(i(e),".archive");export const LIVE_SESSION_MAX=s.machineMax;function c(e){t.mkdirSync(i(e),{recursive:!0})}let l=0,u=null;function f(e,r){const s=n.join(n.dirname(e),`.${n.basename(e)}.tmp.${process.pid}.${Date.now()}.${l++}`);let o=null;try{o=t.openSync(s,"wx",384);const n=Buffer.from(r);for(let r=0;r<n.length;){const s=t.writeSync(o,n,r,n.length-r);if(s<=0)throw new Error(`short write while committing ${e}`);r+=s}return t.fsyncSync(o),t.closeSync(o),o=null,u?.({file:e,tmp:s}),t.renameSync(s,e),!0}catch(e){try{null!=o&&t.closeSync(o)}catch{}try{t.rmSync(s,{force:!0})}catch{}throw e}}export function setAtomicCommitHookForTest(e){u="function"==typeof e?e:null}function d(e,t,n){console.error(`[thinkpool-pair session-store] ${e} failed for ${t}: ${n?.message||n}`)}function m(e,r){try{t.mkdirSync(a(e),{recursive:!0});const s=n.basename(r),o=n.join(a(e),`${s}.${Date.now()}`);return t.renameSync(r,o),!0}catch(e){return d("archive session snapshot",r,e),!1}}function y(e){try{return t.readdirSync(i(e)).filter(e=>e.endsWith(".json")&&!e.endsWith(".events.index.json")).map(r=>{const s=n.join(i(e),r);try{const e=JSON.parse(t.readFileSync(s,"utf8"));try{const n=t.statSync(s);e._bt=n.birthtimeMs||n.mtimeMs||0}catch{e._bt=0}return e}catch(e){return d("parse session snapshot",s,e),null}}).filter(Boolean)}catch{return[]}}const h=(e,t)=>n.join(i(e),`${t}.events.jsonl`),p=(e,t)=>n.join(i(e),`${t}.events.index.json`),S=1048576,g=8388608,b=262144,v=131072,x=new Map;function N(e,n,r,s){try{const o=p(e,n);let i=null;try{i=JSON.parse(t.readFileSync(o,"utf8"))}catch{}if(0!==s&&(!i||3!==i.v||i.size!==s))return;let a=s,c=Number.isFinite(i?.lastSeq)?i.lastSeq:null,l=Number.isFinite(i?.epochStart)?i.epochStart:s,u=Number.isFinite(i?.oldestSeq)?i.oldestSeq:null,d=Array.isArray(i?.points)?i.points.filter(e=>Number.isFinite(e?.seq)&&Number.isFinite(e?.offset)):[];for(const e of r){const t=Buffer.byteLength(JSON.stringify(e))+1,n=e?.seq;if("number"==typeof n){null!=c&&n<=c?(l=a,u=n,d=[]):null==u&&(u=n);const e=d.at(-1);(!e||n-e.seq>=64||a-e.offset>=v)&&d.push({seq:n,offset:a}),c=n}a+=t}const m=t.statSync(h(e,n));if(m.size!==a)return;f(o,JSON.stringify({v:3,size:a,epochStart:l,oldestSeq:u,lastSeq:c,points:d,dev:m.dev,ino:m.ino,mtimeMs:m.mtimeMs,ctimeMs:m.ctimeMs}))}catch{}}export function appendDurableEvents(e,n,r){if(e&&n&&Array.isArray(r)&&r.length)try{c(e);const s=h(e,n),o=t.existsSync(s)?t.statSync(s).size:0;t.appendFileSync(s,r.map(e=>JSON.stringify(e)).join("\n")+"\n"),N(e,n,r,o)}catch{}}export function seedDurableEvents(e,n,r){if(e&&n&&Array.isArray(r)&&r.length)try{c(e);const s=h(e,n);if(t.existsSync(s))return;t.writeFileSync(s,r.map(e=>JSON.stringify(e)).join("\n")+"\n"),N(e,n,r,0)}catch{}}export function hasDurableArchive(e,n){try{return!!e&&!!n&&t.existsSync(h(e,n))}catch{return!1}}export function servesHistoryPage({payloadHost:e,bridgeName:t,hasSession:n,hasArchive:r}){return!(e&&e!==t||!n&&!r)}function O(e,n){try{const r=h(e,n),s=JSON.parse(t.readFileSync(p(e,n),"utf8")),o=t.statSync(r);return 3!==s?.v||s.size!==o.size||s.dev!==o.dev||s.ino!==o.ino||s.mtimeMs!==o.mtimeMs||s.ctimeMs!==o.ctimeMs||!Number.isFinite(s.epochStart)||s.epochStart<0||s.epochStart>o.size||!Array.isArray(s.points)?null:s}catch{return null}}const w=e=>`${e.dev}:${e.ino}:${e.size}:${e.mtimeMs}:${e.ctimeMs}`;function A(e,t,n,r){let s=t,o=n;if(e.discarding){const t=s.indexOf(10);if(t<0)return;s=s.subarray(t+1),o+=t+1,e.discarding=!1}e.carry.length&&(s=Buffer.concat([e.carry,s]),o=e.carryOffset,e.carry=Buffer.alloc(0));let i=0;for(;;){const e=s.indexOf(10,i);if(e<0)break;const t=s.subarray(i,e);t.length<=b&&r(t,o+i),i=e+1}const a=s.subarray(i);a.length>b?(e.carry=Buffer.alloc(0),e.discarding=!0):(e.carry=Buffer.from(a),e.carryOffset=o+i)}function q(e,n){let r;try{r=t.statSync(h(e,n))}catch{return}const s=w(r),o=`${e}\0${n}`,i=x.get(o);if(i?.signature===s&&(i.active||i.attempts>=2))return;const a=i?.signature===s?i.attempts+1:1;x.set(o,{signature:s,attempts:a,active:!0}),j().then(async()=>{const r=await async function(e,n,r){const s=h(e,n);let o;try{const i=await t.promises.stat(s);if(w(i)!==r)return;o=await t.promises.open(s,"r");const a={carry:Buffer.alloc(0),carryOffset:0,discarding:!1};let c=0,l=0,u=null,d=null,m=[];const y=(e,t)=>{let n;try{n=JSON.parse(e.toString("utf8"))}catch{return}if("number"!=typeof n?.seq)return;null!=d&&n.seq<=d?(l=t,u=n.seq,m=[]):null==u&&(u=n.seq);const r=m.at(-1);(!r||n.seq-r.seq>=64||t-r.offset>=v)&&m.push({seq:n.seq,offset:t}),d=n.seq};for(;c<i.size;){const e=Math.min(65536,i.size-c),t=Buffer.allocUnsafe(e),{bytesRead:n}=await o.read(t,0,e,c);if(!n)break;A(a,t.subarray(0,n),c,y),c+=n,await j()}!a.discarding&&a.carry.length&&y(a.carry,a.carryOffset);const h=await t.promises.stat(s);if(w(h)!==r)return;return f(p(e,n),JSON.stringify({v:3,size:h.size,epochStart:l,oldestSeq:u,lastSeq:d,points:m,dev:h.dev,ino:h.ino,mtimeMs:h.mtimeMs,ctimeMs:h.ctimeMs})),!0}catch{}finally{try{await(o?.close())}catch{}}}(e,n,s),i=x.get(o);i?.signature===s&&(r?x.delete(o):x.set(o,{...i,active:!1}))})}function M(e,t,n=!1){if(n){const t=e.lastIndexOf(10);return t<0?{carry:Buffer.alloc(0),lines:[],discarding:!0}:M(e.subarray(0,t+1),Buffer.alloc(0))}const r=t.length?Buffer.concat([e,t]):e,s=r.indexOf(10);if(s<0)return r.length>b?{carry:Buffer.alloc(0),lines:[],discarding:!0}:{carry:Buffer.from(r),lines:[],discarding:!1};const o=Buffer.from(r.subarray(0,s)),i=[];let a=s+1;for(;;){const e=r.indexOf(10,a);if(e<0)break;i.push(r.subarray(a,e)),a=e+1}return i.push(r.subarray(a)),{carry:o.length>b?Buffer.alloc(0):o,lines:i,discarding:o.length>b}}export function readDurableOldestSeq(e,n){try{const r=O(e,n);return r?r.oldestSeq??null:(t.existsSync(h(e,n))&&q(e,n),null)}catch{return null}}export function readDurablePage(e,n,r,s=200){try{const o=O(e,n);return t.existsSync(h(e,n))?(o||q(e,n),function(e,n,r,s,o){const i=(e=>Math.max(1,Math.min(200,Number(e)||200)))(s),a=h(e,n),c=t.statSync(a).size,l=o?.epochStart||0,u=null==r?null:o?.points.find(e=>e.seq>r);let f=u?.offset??c,d=Buffer.alloc(0),m=!1,y=0,p=0,g=[],v=null,x=!1,N=!1;const O=t.openSync(a,"r");try{for(;f>l&&y<S&&p<5e3&&g.length<=i;){const e=Math.max(l,f-Math.min(65536,S-y)),n=Buffer.alloc(f-e);t.readSync(O,n,0,n.length,e),y+=n.length;const s=M(n,d,m);d=s.carry,m=s.discarding;for(let e=s.lines.length-1;e>=0;e--){const t=s.lines[e];if(t.length){try{if(t.length>b){N=!0;continue}const e=JSON.parse(t.toString("utf8"));if(p++,"number"==typeof e?.seq){if(null!=v&&e.seq>=v){x=!0;break}v=e.seq}(null==r||null==e?.seq||e.seq<r)&&g.push(e)}catch{}if(g.length>i)break}}if(x||g.length>i)break;f=e}if(f===l&&m&&(N=!0),f===l&&d.length&&!x&&g.length<=i)try{if(d.length>b)N=!0;else{const e=JSON.parse(d.toString("utf8"));p++,"number"==typeof e?.seq&&null!=v&&e.seq>=v?x=!0:(null==r||null==e?.seq||e.seq<r)&&g.push(e)}}catch{}}finally{t.closeSync(O)}f>l&&(y>=S||p>=5e3)&&(N=!0);const w=N||g.length>i||!x&&f>l;return{events:g.slice(0,i).reverse(),hasMore:w,...N?{partial:!0,bytesRead:y,eventsRead:p}:{}}}(e,n,r,s,o)):{events:[],hasMore:!1}}catch{return{events:[],hasMore:!1}}}const k=(e,t)=>(Number(e.ts)||0)-(Number(t.ts)||0)||String(e.termName||"").localeCompare(String(t.termName||""))||(Number(e.seq)||0)-(Number(t.seq)||0),j=()=>new Promise(e=>setImmediate(e));export async function searchDurableSessionEventsAsync(e,n,s,o={}){const i=String(s||"").trim().toLocaleLowerCase();if(!i)return{results:[],truncated:!1,partial:!1,bytesRead:0,eventsRead:0};const a=Math.max(1,Math.min(200,Number(o.limit)||200)),c=Math.max(16384,Math.min(g,Number(o.maxBytes)||g)),l=Math.max(1,Math.min(5e4,Number(o.maxEvents)||5e4)),u=Math.max(1,Math.min(5e3,Number(o.deadlineMs)||100)),f=Date.now()+u,d={bytes:0,events:0,partial:!1,truncated:!1},m=[],y=new Set;let p=2;const S=(e,t,n)=>{const s=r(e);if(!s||!s.toLocaleLowerCase().includes(i))return;const o=e.cid||(Number.isSafeInteger(e.seq)?`seq:${e.epoch||0}:${e.seq}`:`row:${n}`),c=`${t.term}:${o}`;if(y.has(c))return;y.add(c);const l=s.toLocaleLowerCase().indexOf(i),u=s.slice(Math.max(0,l-240),Math.min(s.length,l+i.length+560)),f={key:c,term:t.term,termName:t.termName||"terminal",cid:e.cid||null,seq:Number.isSafeInteger(e.seq)?e.seq:null,epoch:Number.isSafeInteger(e.epoch)?e.epoch:0,ts:Number(e.ts)||0,kind:e.kind,by:e.by||null,text:u},h=Buffer.byteLength(JSON.stringify(f))+1;if(p+h>12e4)return d.truncated=!0,void(d.partial=!0);p+=h,m.push(f),m.sort(k),m.length>a&&(p-=Buffer.byteLength(JSON.stringify(m.pop()))+1,d.truncated=!0)};try{for(const r of n||[]){const n=String(r?.term||"");if(!n||d.partial)continue;const s={term:n,termName:r.termName||"terminal"},o=h(e,n);let i;try{i=await t.promises.stat(o)}catch{continue}const a=O(e,n);a||q(e,n);const u=a?.epochStart||0;let m,y=i.size,p=Buffer.alloc(0),g=!1,v=null,x=!1,N=0;try{for(m=await t.promises.open(o,"r");y>u&&!x;){if(d.bytes>=c||d.events>=l||Date.now()>=f){d.partial=!0;break}const e=Math.min(16384,y-u,c-d.bytes);if(e<=0){d.partial=!0;break}const t=y-e,n=Buffer.allocUnsafe(e),{bytesRead:r}=await m.read(n,0,e,t);d.bytes+=r;const o=M(n.subarray(0,r),p,g);p=o.carry,g=o.discarding;for(let e=o.lines.length-1;e>=0;e--){const t=o.lines[e];if(!t.length)continue;if(t.length>b){d.partial=!0;continue}let n;try{n=JSON.parse(t.toString("utf8"))}catch{continue}if(d.events++,N++,"number"==typeof n?.seq){if(null!=v&&n.seq>=v){x=!0;break}v=n.seq}if(S(n,s,N),d.events>=l){d.partial=!0;break}}y=t,await j()}if(g&&(d.partial=!0),!d.partial&&!x&&y===u&&p.length)if(p.length>b)d.partial=!0;else try{const e=JSON.parse(p.toString("utf8"));d.events++,N++,"number"==typeof e?.seq&&null!=v&&e.seq>=v?x=!0:S(e,s,N)}catch{}}finally{await(m?.close())}!x&&y>u&&(d.partial=!0)}}catch{d.partial=!0}return d.partial&&(d.truncated=!0),{results:m,truncated:d.truncated,partial:d.partial,bytesRead:d.bytes,eventsRead:d.events,deadlineMs:u}}export function searchDurableSessionEvents(){return{results:[],truncated:!0,partial:!0,bytesRead:0,eventsRead:0}}const $=new Map;function I(e,r,s){const a=n.join(i(e),`${r}.json`);try{c(e);const l=Array.isArray(s?.log)?o(s.log):s?.log;return f(a,JSON.stringify({...s,...l?{log:l}:{},id:r,savedAt:Date.now()})),function(e){try{const r=loadNames(e),s=e=>{try{return JSON.parse(t.readFileSync(e,"utf8")).id}catch{return null}};t.readdirSync(i(e)).filter(e=>e.endsWith(".json")).map(r=>{const s=n.join(i(e),r);let o=0;try{o=JSON.parse(t.readFileSync(s,"utf8")).savedAt||0}catch{}return{p:s,f:r,m:o}}).sort((e,t)=>t.m-e.m).filter(e=>{const t=s(e.p);return!t||!r[t]}).slice(LIVE_SESSION_MAX).forEach(t=>m(e,t.p))}catch(t){d("prune live session snapshots",i(e),t)}}(e),!0}catch(e){return d("write session snapshot",a,e),!1}}export function saveSession(e,t,n){clearTimeout($.get(t)),$.set(t,setTimeout(()=>I(e,t,n),1500))}export function flushSession(e,t,n){return clearTimeout($.get(t)),I(e,t,n)}export function deleteSession(e,r){clearTimeout($.get(r)),$.delete(r);const s=n.join(i(e),`${r}.json`);try{return!t.existsSync(s)||m(e,s)}catch(e){return d("archive closed session snapshot",s,e),!1}}const J=e=>n.join(i(e),".scheduled-outcomes"),B=e=>"string"==typeof e&&/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,159}$/.test(e),F=e=>"string"==typeof e&&/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,159}$/.test(e),z=e=>{try{const n=JSON.parse(t.readFileSync(J(e),"utf8"));return n&&"object"==typeof n&&!Array.isArray(n)?n:{}}catch{return{}}},R=e=>{if(!e||"object"!=typeof e||Array.isArray(e))return null;if(1===e.v&&"acknowledged"===e.state){const t=e.intent;return t&&"object"==typeof t&&!Array.isArray(t)&&F(t.runId)&&e.runId===t.runId?{intent:t,acknowledged:!0}:null}return F(e.runId)?{intent:e,acknowledged:!1}:null};export function savePendingScheduledOutcome(e,t,n){if(!B(t)||!n||"object"!=typeof n||Array.isArray(n)||!F(n.runId))return!1;try{c(e);const r=z(e);return r[t]=n,f(J(e),JSON.stringify(r)),!0}catch(t){return d("write scheduled outcome outbox",J(e),t),!1}}export function loadPendingScheduledOutcomes(e){return Object.entries(z(e)).map(([e,t])=>({terminalId:e,record:R(t)})).filter(({terminalId:e,record:t})=>B(e)&&t).map(({terminalId:e,record:t})=>({terminalId:e,intent:t.intent,...t.acknowledged?{acknowledged:!0}:{}})).slice(0,LIVE_SESSION_MAX)}export function loadPendingScheduledOutcome(e,t){return B(t)&&R(z(e)[t])?.intent||null}export function acknowledgePendingScheduledOutcome(e,t,n){if(!B(t)||!F(n))return!1;try{const r=z(e),s=R(r[t]);return!(!s||s.intent.runId!==n||(s.acknowledged||(r[t]={v:1,state:"acknowledged",runId:n,intent:s.intent},f(J(e),JSON.stringify(r))),0))}catch(t){return d("acknowledge scheduled outcome outbox",J(e),t),!1}}export function deletePendingScheduledOutcome(e,n){if(!B(n))return!1;try{const r=z(e);return!(n in r)||(delete r[n],Object.keys(r).length?f(J(e),JSON.stringify(r)):t.rmSync(J(e),{force:!0}),!0)}catch(t){return d("delete scheduled outcome outbox",J(e),t),!1}}export function commitRecordedScheduledOutcome(e,t,r){let s=!1;try{s="function"==typeof r&&!0===r()}catch(r){d("record scheduled outcome in session snapshot",n.join(i(e),`${t}.json`),r)}if(!s)return{ok:!1,snapshotRecorded:!1,outboxAcknowledged:!1,outboxDeleted:!1};const o=loadPendingScheduledOutcome(e,t);if(!acknowledgePendingScheduledOutcome(e,t,o?.runId))return{ok:!1,snapshotRecorded:!0,outboxAcknowledged:!1,outboxDeleted:!1};const a=deletePendingScheduledOutcome(e,t);return{ok:a,snapshotRecorded:!0,outboxAcknowledged:!0,outboxDeleted:a}}export function loadLatest(e){return y(e).sort((e,t)=>(t.savedAt||0)-(e.savedAt||0))[0]||null}export function canResume(e){return!!(e&&e.sessionId&&e.savedAt&&Date.now()-e.savedAt<432e5)}export function loadAll(e){return y(e).sort((e,t)=>(e.savedAt||0)-(t.savedAt||0))}export function loadArchived(e,r=40){try{return t.readdirSync(a(e)).map(r=>{const s=n.join(a(e),r);try{const e=t.statSync(s);if(!e.isFile())return null;const n=JSON.parse(t.readFileSync(s,"utf8"));return n&&Array.isArray(n.log)?{...n,_archivedAt:e.mtimeMs||0}:null}catch{return null}}).filter(Boolean).sort((e,t)=>(t._archivedAt||t.savedAt||0)-(e._archivedAt||e.savedAt||0)).slice(0,Math.max(1,Math.min(100,Number(r)||40)))}catch{return[]}}const D=e=>n.join(i(e),".pty-id");export function loadPtyId(e){try{return t.readFileSync(D(e),"utf8").trim()||null}catch{return null}}export function savePtyId(e,t){const n=D(e);try{return c(e),f(n,String(t)),!0}catch(e){return d("write PTY id",n,e),!1}}const E=e=>n.join(i(e),".names");export function loadNames(e){const n=E(e);try{return JSON.parse(t.readFileSync(n,"utf8"))||{}}catch(e){return"ENOENT"!==e?.code&&d("parse terminal names",n,e),{}}}export function saveNames(e,t){const n=E(e);try{return c(e),f(n,JSON.stringify(t||{})),!0}catch(e){return d("write terminal names",n,e),!1}}
@@ -0,0 +1 @@
1
+ export const makeRoutedRealtimeFrame=(e,t,a)=>({event:e,payload:t,channel:a});export const realtimeWireBytes=({event:e,payload:t})=>{try{return Buffer.byteLength(JSON.stringify({event:e,payload:t}))}catch{return 1/0}};export async function sendAbortableReplayFrame(e,{event:t,payload:a},{signal:o,fetchImpl:n=fetch}={}){const r=new URL(e.broadcastEndpointURL),c={apikey:e.socket.apiKey||"","Content-Type":"application/json"};e.socket.accessTokenValue&&(c.Authorization=`Bearer ${e.socket.accessTokenValue}`);const s=await n(r,{method:"POST",headers:c,body:JSON.stringify({messages:[{topic:e.subTopic,event:t,payload:a,private:e.private}]}),signal:o});try{await(s.body?.cancel())}catch{}return s.ok?"ok":"error"}
@@ -0,0 +1 @@
1
+ export function createTurnAdmissionQueue({maxPending:e=128}={}){const t=new WeakMap;return(n,r)=>{if(!n||"function"!=typeof r)return Promise.resolve();let o=t.get(n);if(o||(o={tail:Promise.resolve(),count:0},t.set(n,o)),o.count>=e)return Promise.reject(new Error("Too many pending turns; wait for this lane to finish preparing."));o.count++;const i=o.tail.then(r),u=()=>{o.count--,o.count||t.get(n)!==o||t.delete(n)};return o.tail=i.then(u,u),i}}