@code-yeongyu/senpi 2026.11.10-1 → 2026.11.10-2

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 (129) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/bundle/chunks/{chunk-GPXZTSEX.js → chunk-2M54EAAY.js} +3 -3
  3. package/dist/bundle/chunks/{chunk-YPAQXRP3.js → chunk-47T6YMI2.js} +2 -2
  4. package/dist/bundle/chunks/{chunk-I5ASHSLZ.js → chunk-4JMGWVRH.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-HI5JSLG5.js → chunk-74IB3JPP.js} +2 -2
  6. package/dist/bundle/chunks/{chunk-NH7SYIGN.js → chunk-DLPV4B3R.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-Y7Z7XPUF.js → chunk-DZQA5LVN.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-2CNSCMYC.js → chunk-E5O4SP5I.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-3IYWH6RO.js → chunk-IKJCA5SH.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-H33A33M4.js → chunk-M2VJVJMK.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-L6NRDUWJ.js → chunk-OF3XVGG4.js} +1 -1
  12. package/dist/bundle/chunks/{chunk-THYEZBUG.js → chunk-Q4G5DECT.js} +2 -2
  13. package/dist/bundle/chunks/{chunk-ARUV3US4.js → chunk-QATU6BBC.js} +1 -1
  14. package/dist/bundle/chunks/{chunk-FAFIGBUD.js → chunk-TUEZNIBK.js} +1 -1
  15. package/dist/bundle/chunks/{chunk-BELNOPAI.js → chunk-UOZDDYBN.js} +2 -2
  16. package/dist/bundle/chunks/{chunk-DBQBJTMF.js → chunk-VUY4BZDI.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-TGW4R7SI.js → chunk-XH24X5B2.js} +1 -1
  18. package/dist/bundle/chunks/chunk-XI6THO4F.js +2 -0
  19. package/dist/bundle/chunks/{chunk-X4XWAB3J.js → chunk-YCPURLPU.js} +38 -38
  20. package/dist/bundle/chunks/{chunk-LHEP3ACI.js → chunk-YNGEZBTP.js} +1 -1
  21. package/dist/bundle/chunks/{cli-main-VG3C2EXI.js → cli-main-Y6ALA5OI.js} +1 -1
  22. package/dist/bundle/chunks/{hand-entry-3LQKUTYS.js → hand-entry-IPDAIOGI.js} +1 -1
  23. package/dist/bundle/chunks/{host-command-CCASS7W4.js → host-command-2326GCUP.js} +1 -1
  24. package/dist/bundle/chunks/{host-lifecycle-WWC7HXQ6.js → host-lifecycle-TNHASSFJ.js} +1 -1
  25. package/dist/bundle/chunks/host-lifecycle.js +1 -1
  26. package/dist/bundle/chunks/{host-session-command-YJB2FLKU.js → host-session-command-BZYBDOIE.js} +1 -1
  27. package/dist/bundle/chunks/{host-socket-request-DMYXC56U.js → host-socket-request-QN4Q2P5E.js} +1 -1
  28. package/dist/bundle/chunks/{interactive-mode-CUN3WMUF.js → interactive-mode-LBQB7DDR.js} +1 -1
  29. package/dist/bundle/chunks/{main-P7XRC2OI.js → main-FFRFP34W.js} +1 -1
  30. package/dist/bundle/chunks/{multi-session-host-244X3P6L.js → multi-session-host-NDIHHJ2L.js} +11 -8
  31. package/dist/bundle/chunks/{package-manager-cli-UVWJOQA3.js → package-manager-cli-XCPAMOYI.js} +1 -1
  32. package/dist/bundle/chunks/{rpc-mode-G4I3HHPB.js → rpc-mode-TKNZM4PZ.js} +1 -1
  33. package/dist/bundle/chunks/{rpc-monitor-source-C6VQ3BC4.js → rpc-monitor-source-PGTDSGWP.js} +1 -1
  34. package/dist/bundle/chunks/{run-attached-tui-R3RB5P7G.js → run-attached-tui-JDUKXDI2.js} +1 -1
  35. package/dist/bundle/chunks/{schedule-command-5FG2OKSR.js → schedule-command-HF2DHABB.js} +1 -1
  36. package/dist/bundle/chunks/{session-control-endpoint-XWCFLJYC.js → session-control-endpoint-A6R6W2JQ.js} +1 -1
  37. package/dist/bundle/chunks/{session-picker-2FZSNFS7.js → session-picker-GWA4S2PO.js} +1 -1
  38. package/dist/bundle/chunks/session-worker.js +119 -116
  39. package/dist/bundle/cli.js +2 -2
  40. package/dist/bundle/host-supervisor.js +1 -1
  41. package/dist/bundle/index.js +1 -1
  42. package/dist/bundle/rpc-entry.js +1 -1
  43. package/dist/bundle/runtime-manifest.json +1 -1
  44. package/dist/core/agent-session-runtime.d.ts +2 -0
  45. package/dist/core/agent-session-runtime.js +5 -0
  46. package/dist/core/agent-session.d.ts +1 -1
  47. package/dist/core/agent-session.js +30 -10
  48. package/dist/core/extensions/builtin/config-reload/change-groups.js +6 -2
  49. package/dist/core/extensions/builtin/mcp/auth/catalog-identity.js +32 -8
  50. package/dist/core/extensions/builtin/mcp/auth/oauth-grant.d.ts +43 -0
  51. package/dist/core/extensions/builtin/mcp/auth/oauth-grant.js +196 -0
  52. package/dist/core/extensions/builtin/mcp/auth/oauth-provider.d.ts +4 -17
  53. package/dist/core/extensions/builtin/mcp/auth/oauth-provider.js +64 -75
  54. package/dist/core/extensions/builtin/mcp/auth/oauth-refresh.d.ts +1 -1
  55. package/dist/core/extensions/builtin/mcp/auth/oauth-refresh.js +25 -4
  56. package/dist/core/extensions/builtin/mcp/auth/oauth.js +10 -7
  57. package/dist/core/extensions/builtin/mcp/auth/token-store.d.ts +18 -0
  58. package/dist/core/extensions/builtin/mcp/auth/token-store.js +3 -0
  59. package/dist/core/extensions/builtin/mcp/catalog-cache.js +7 -6
  60. package/dist/core/extensions/builtin/mcp/catalog.js +3 -2
  61. package/dist/core/extensions/builtin/mcp/invocation.js +6 -0
  62. package/dist/core/extensions/builtin/mcp/service-register.js +16 -2
  63. package/dist/core/extensions/builtin/mcp/service-tools-changed.js +61 -54
  64. package/dist/core/extensions/builtin/mcp/startup-race.d.ts +2 -0
  65. package/dist/core/extensions/builtin/mcp/startup-race.js +25 -7
  66. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-2.js +6 -6
  67. package/dist/core/open-timing.d.ts +2 -0
  68. package/dist/core/open-timing.js +7 -1
  69. package/dist/core/session-manager.d.ts +2 -0
  70. package/dist/core/session-manager.js +15 -1
  71. package/dist/modes/interactive/session-control-rpc-commands.d.ts +1 -1
  72. package/dist/modes/interactive/session-control-rpc-commands.js +5 -0
  73. package/dist/modes/rpc/compact-admission-validation.js +4 -1
  74. package/dist/modes/rpc/connection-handler.d.ts +2 -0
  75. package/dist/modes/rpc/connection-handler.js +10 -2
  76. package/dist/modes/rpc/custom-capability.d.ts +2 -0
  77. package/dist/modes/rpc/custom-capability.js +2 -0
  78. package/dist/modes/rpc/effect-commands.d.ts +21 -0
  79. package/dist/modes/rpc/host-capabilities.d.ts +1 -0
  80. package/dist/modes/rpc/host-capabilities.js +3 -1
  81. package/dist/modes/rpc/host-observe-request.d.ts +2 -0
  82. package/dist/modes/rpc/host-observe-request.js +6 -1
  83. package/dist/modes/rpc/host-park-ledger.d.ts +19 -0
  84. package/dist/modes/rpc/host-park-ledger.js +110 -0
  85. package/dist/modes/rpc/lifecycle-delivery.js +4 -1
  86. package/dist/modes/rpc/media-placeholders.js +1 -0
  87. package/dist/modes/rpc/method-classes-schema-host.d.ts +42 -1
  88. package/dist/modes/rpc/method-classes-schema-host.js +24 -21
  89. package/dist/modes/rpc/method-classes-schema.d.ts +42 -1
  90. package/dist/modes/rpc/method-classes-schema.js +5 -2
  91. package/dist/modes/rpc/method-classes.d.ts +2 -0
  92. package/dist/modes/rpc/method-classes.js +3 -0
  93. package/dist/modes/rpc/multi-session-host.js +1 -1
  94. package/dist/modes/rpc/rpc-host-command-types.d.ts +14 -1
  95. package/dist/modes/rpc/rpc-host-response-types.d.ts +21 -0
  96. package/dist/modes/rpc/session-attachment-gate.js +2 -0
  97. package/dist/modes/rpc/session-binding.d.ts +1 -0
  98. package/dist/modes/rpc/session-binding.js +6 -1
  99. package/dist/modes/rpc/session-connection-context.d.ts +2 -0
  100. package/dist/modes/rpc/session-connection-context.js +4 -0
  101. package/dist/modes/rpc/session-registry-attach.d.ts +2 -0
  102. package/dist/modes/rpc/session-registry-attach.js +15 -11
  103. package/dist/modes/rpc/session-registry-claims.js +2 -0
  104. package/dist/modes/rpc/session-registry-open.js +13 -7
  105. package/dist/modes/rpc/session-registry-opening.js +2 -1
  106. package/dist/modes/rpc/session-registry-types.d.ts +4 -0
  107. package/dist/modes/rpc/session-registry.d.ts +3 -0
  108. package/dist/modes/rpc/session-registry.js +27 -3
  109. package/dist/modes/rpc/session-router-close.js +1 -0
  110. package/dist/modes/rpc/session-router-context.d.ts +4 -2
  111. package/dist/modes/rpc/session-router-context.js +3 -0
  112. package/dist/modes/rpc/session-router-host-reads.js +1 -0
  113. package/dist/modes/rpc/session-router-occupancy.js +10 -1
  114. package/dist/modes/rpc/session-router-open-result.d.ts +12 -0
  115. package/dist/modes/rpc/session-router-open-result.js +63 -0
  116. package/dist/modes/rpc/session-router-open.d.ts +3 -0
  117. package/dist/modes/rpc/session-router-open.js +15 -63
  118. package/dist/modes/rpc/session-router-park.d.ts +15 -0
  119. package/dist/modes/rpc/session-router-park.js +176 -0
  120. package/dist/modes/rpc/session-router-routing.d.ts +1 -1
  121. package/dist/modes/rpc/session-router-routing.js +7 -0
  122. package/dist/modes/rpc/session-status-source.js +2 -2
  123. package/docs/engine-socket/fixtures/admission-routes/h-legacy.json +1 -1
  124. package/docs/engine-socket/fixtures/rpc-inbound-samples.json +22 -2
  125. package/docs/rpc.md +50 -0
  126. package/native/socket-secret/prebuilds/win32-arm64/senpi_socket_secret.win32-arm64.node +0 -0
  127. package/native/socket-secret/prebuilds/win32-x64/senpi_socket_secret.win32-x64.node +0 -0
  128. package/package.json +6 -6
  129. package/dist/bundle/chunks/chunk-436DNN4Z.js +0 -2
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{hostChildStartupHandOff,relayHostStartupEvents,reportStartupMilestone,startupHandOff}from"./chunk-R2Z7CX77.js";import{CHILD_KILL_EXIT_TIMEOUT_MS,CHILD_STALLED_STOP_MAX_MS_ENV,CHILD_STOP_TIMEOUT_MS,DEFAULT_HANDOFF_GRACE_MS,HANDOFF_GRACE_MS_ENV,IdleExitDecider,STOP_STALL_EVIDENCE_MAX_AGE_MS,childStalledStopMaxMs,classifyChildExit,clearStopProgress,errorMessage,hostEnsureLockOptions,hostEnsureLockTarget,hostLoopStalled,layeredSupervisorIntent,noteChildExit,parseIdleExitMs,readStopIntent,recordHostCrash,releaseGeneration,resolveHostPolicy,supervisorLog,watchDrainRequest,writeDrainRequest,writeDrainWatch,writeHostReady,writeStderrLine,writeStopIntent,writeStopProgress}from"./chunk-UCXBDE6R.js";import{HOST_DAEMON_DIR_ENV,HostDaemonStateError,createGenerationDirectory,createHostDaemonPaths,generationPaths,hostOwnerGone,readHostOwner,sameHostOwner,writeJsonAtomic}from"./chunk-YI6KRJDC.js";import{OBSERVE_REQUEST_FIELD,RPC_AUTH_CAPABILITY,RPC_AUTH_HEX,RPC_LAUNCH_PROOF_RECORD,RpcPublicEndpoint,authRecord,isObservingRequest,launchProofRecordRefusal,observingHoldChange,requestOriginHostInstance,rpcAuthProof,rpcProofMatches}from"./chunk-DBQBJTMF.js";import{MAX_RPC_LINE_CHARACTERS,attachJsonlLineReader,serializeJsonLine}from"./chunk-SF4MQDKZ.js";import{runtimeExecArgv,spawnWithPrivateFds}from"./chunk-E266ORGA.js";import{ADOPTION_GRANT_FILE,STARTUP_ATTEMPT_FILE,releaseStartupFillers,startupGrantLine,withStartupPipe}from"./chunk-T2SMQPRE.js";import{HOST_INSTANCE_ID_ENV,HOST_STARTUP_EVENTS_ENV,INTERNAL_KEY_STDIN_ENV}from"./chunk-RUGTHELO.js";import{BIND_SCRATCH_INFIX,BIND_SCRATCH_SOCKET,MAX_SOCKET_PATH_BYTES,PUBLIC_SOCKET_IDENTITY_FILE,adoptPublicSocket,classifyEndpointOwnership,parseSocketIdentity,shieldSocketDuringClose,socketEntryListenerState,statSocketIdentity,unlinkOwnedSocket,writeSocketIdentityFile}from"./chunk-5XHOHZIR.js";import{SOCKET_HANDSHAKE_TIMEOUT_MS,SOCKET_SECRET_FILE_ENV,acquireOwnershipSafeLock,authenticateSocket,createSocketSecret,ensureSocketSecret,isBusy,resolveSocketTransportAddress,sendSocketHandshake,socketSecretPath}from"./chunk-HW6AAS3R.js";import{VERSION,brandEnvNames,envValue,getAgentDir,isBunBinary,isBundledNode}from"./chunk-SODMQEHO.js";import{processStartTimeMs,readProcessIdentity,readProcessStartTime,sameProcessStartMs,waitForStartTime}from"./chunk-O5RYI3IW.js";import{randomUUID as randomUUID3}from"node:crypto";import{mkdir as mkdir5,rm as rm4}from"node:fs/promises";import{join as join6}from"node:path";var HostAdmission=class{constructor(info){this.stopped=!1,this.listeners=new Set,this.replies=Promise.resolve(),this.info=info}get stopping(){return this.stopped}protocol(){return{...this.info,lifecycle:this.stopped?"stopping":"ready"}}observe(info){this.info=info}stop(){this.stopped||(this.stopped=!0,this.replies=Promise.all([...this.listeners].map(listener=>listener())).then(()=>{}))}async flush(){let timer;try{await Promise.race([this.replies,new Promise(resolve2=>{timer=setTimeout(resolve2,2e3)})])}finally{clearTimeout(timer)}}onStop(listener){return this.listeners.add(listener),()=>this.listeners.delete(listener)}};function hostStoppingResponse(id,command,admission){return{...typeof id=="string"?{id}:{},type:"response",command,success:!1,error:"host_stopping",errorCode:"host_stopping",errorData:{instanceId:admission.protocol().instanceId}}}function hostCrashCleanupPaths(targets){let publicEntry=targets.platform==="win32"?[targets.publicSocket]:[];return targets.successor?publicEntry:[targets.generationPidFile,targets.settingsFile,...publicEntry,targets.pointerFile]}import{existsSync,readFileSync,realpathSync}from"node:fs";import{access,readFile}from"node:fs/promises";import{dirname,resolve}from"node:path";import{fileURLToPath}from"node:url";function isCliModuleEntry(moduleUrl){let entry=process.argv[1];if(!entry)return!1;try{return fileURLToPath(moduleUrl)===realpathSync(entry)}catch{return!1}}function resolveCliMainPath(modulePath=fileURLToPath(import.meta.url),bundled=isBundledNode){let declared=bundled?resolveDeclaredCliEntry(modulePath):void 0;if(declared!==void 0)return declared;let extension=modulePath.endsWith(".ts")?".ts":".js",unbundled=resolve(dirname(modulePath),"..","..",`cli-main${extension}`);return existsSync(unbundled)?unbundled:resolveDeclaredCliEntry(modulePath)??unbundled}function resolveDeclaredCliEntry(modulePath){let dir=dirname(modulePath);for(let depth=0;depth<8;depth+=1){let manifestPath=resolve(dir,"package.json");if(existsSync(manifestPath)){try{let declared=JSON.parse(readFileSync(manifestPath,"utf8")).bin,candidates=typeof declared=="string"?[declared]:Object.values(declared??{});for(let candidate of candidates){let entry=resolve(dir,candidate);if(existsSync(entry))return entry}}catch{}return}let parent=dirname(dir);if(parent===dir)return;dir=parent}}var existsAsync=path=>access(path).then(()=>!0,()=>!1);async function resolveCliMainPathAsync(modulePath=fileURLToPath(import.meta.url),bundled=isBundledNode){let declared=bundled?await resolveDeclaredCliEntryAsync(modulePath):void 0;if(declared!==void 0)return declared;let extension=modulePath.endsWith(".ts")?".ts":".js",unbundled=resolve(dirname(modulePath),"..","..",`cli-main${extension}`);return await existsAsync(unbundled)?unbundled:await resolveDeclaredCliEntryAsync(modulePath)??unbundled}async function resolveDeclaredCliEntryAsync(modulePath){let dir=dirname(modulePath);for(let depth=0;depth<8;depth+=1){let manifestPath=resolve(dir,"package.json");if(await existsAsync(manifestPath)){try{let declaredBin=JSON.parse(await readFile(manifestPath,"utf8")).bin,candidates=typeof declaredBin=="string"?[declaredBin]:Object.values(declaredBin??{});for(let candidate of candidates){let entry=resolve(dir,candidate);if(await existsAsync(entry))return entry}}catch{}return}let parent=dirname(dir);if(parent===dir)return;dir=parent}}import{watch}from"node:fs";import{createConnection,Socket}from"node:net";var MAX_CLASSIFIED_LINE_BYTES=64*1024,NEWLINE=10,ClientOccupancy=class{constructor(onAttach,ownInstance){this.clients=new Set,this.observers=new Set,this.attached=new Set,this.held=new Set,this.dependents=new Set,this.closed=!1,this.onAttach=onAttach,this.ownInstance=ownInstance}get attachedCount(){return this.attached.size+this.held.size}get unclassifiedCount(){return this.clients.size-this.observers.size-this.attached.size-this.dependents.size}admit(client){if(this.closed)return client.destroy(),!1;this.clients.add(client);let pending=Buffer.alloc(0),attach=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.held.delete(client),this.attached.add(client),this.onAttach()},depend=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.held.delete(client),this.dependents.add(client)},classify=chunk=>{pending=Buffer.concat([pending,chunk]);for(let newline=pending.indexOf(NEWLINE);newline!==-1;newline=pending.indexOf(NEWLINE)){let line=pending.subarray(0,newline).toString("utf8");if(pending=pending.subarray(newline+1),!isObservingRequest(line)){this.ownInstance!==void 0&&requestOriginHostInstance(line)===this.ownInstance?depend():attach();return}this.observers.add(client);let hold=observingHoldChange(line);hold===!0&&!this.held.has(client)?(this.held.add(client),this.onAttach()):hold===!1&&this.held.delete(client)}pending.length>MAX_CLASSIFIED_LINE_BYTES&&attach()};return client.on("data",classify),!0}release(client){let unclassified=this.clients.has(client)&&!this.observers.has(client)&&!this.attached.has(client)&&!this.dependents.has(client);return this.clients.delete(client),this.observers.delete(client),this.attached.delete(client),this.held.delete(client),this.dependents.delete(client),unclassified}destroyAll(){this.closed=!0;for(let client of this.clients)client.destroy()}};var SessionRunActivity=class{#running=new Set;#settling=new Map;#settleHoldMs;#now;#onSettleHoldExpired;constructor(options={}){this.#settleHoldMs=options.settleHoldMs??Number.POSITIVE_INFINITY,this.#now=options.now??Date.now,this.#onSettleHoldExpired=options.onSettleHoldExpired}observe(line){let event=parseHostEvent(line);if(event===void 0)return!1;if(event.type==="agent_start")this.#running.add(event.sessionId),this.#settling.delete(event.sessionId);else if(event.type==="agent_settled"&&event.reason!=="session_closed")this.#running.delete(event.sessionId),this.#settling.set(event.sessionId,this.#now());else if(event.type==="agent_settled"||event.type==="agent_idle"||event.type==="session_closed")this.#running.delete(event.sessionId),this.#settling.delete(event.sessionId);else return!1;return!0}get busySessions(){return this.#running.size}get settlingSessions(){let now=this.#now();for(let[sessionId,settledAt]of this.#settling){let heldMs=now-settledAt;heldMs<this.#settleHoldMs||(this.#settling.delete(sessionId),this.#onSettleHoldExpired?.(sessionId,heldMs))}return this.#settling.size}};function holdIdleExitForSettling(decision,runs){return decision==="exit"&&runs.settlingSessions>0?"idle":decision}function parseHostEvent(line){let event;try{event=JSON.parse(line)}catch{return}if(typeof event!="object"||event===null)return;let{type,sessionId,reason}=event;return typeof sessionId=="string"?{type,sessionId,reason}:void 0}import{randomBytes}from"node:crypto";import{hkdfSync}from"node:crypto";import{Duplex}from"node:stream";import{createCipheriv,createDecipheriv}from"node:crypto";var INTERNAL_RECORD_MAX=64*1024,RECORD_LIMIT=1n<<32n,InternalRecordCipher=class{constructor(key,direction,counter=0n){this.key=key,this.direction=direction,this.counter=counter}parameters(){if(this.counter<0n||this.counter>=RECORD_LIMIT)throw new Error("internal_record_counter_exhausted");let count=Buffer.alloc(8);return count.writeBigUInt64BE(this.counter),{nonce:Buffer.concat([Buffer.alloc(4),count]),aad:Buffer.concat([Buffer.from(this.direction),count])}}seal(plaintext){if(plaintext.length<1||plaintext.length>INTERNAL_RECORD_MAX)throw new Error("internal_record_length");let{nonce:nonce2,aad}=this.parameters(),cipher=createCipheriv("aes-256-gcm",this.key,nonce2);cipher.setAAD(aad);let body=Buffer.concat([cipher.update(plaintext),cipher.final(),cipher.getAuthTag()]),length=Buffer.alloc(4);return length.writeUInt32BE(body.length),this.counter++,Buffer.concat([length,body])}open(body){if(body.length<17||body.length>INTERNAL_RECORD_MAX+16)throw new Error("internal_record_length");let{nonce:nonce2,aad}=this.parameters(),decipher=createDecipheriv("aes-256-gcm",this.key,nonce2);decipher.setAAD(aad),decipher.setAuthTag(body.subarray(-16));let plaintext=decipher.update(body.subarray(0,-16)),final=decipher.final();return this.counter++,Buffer.concat([plaintext,final])}};function createInternalRecordStream(wire,key,clientNonce,serverNonce,role){let salt=Buffer.concat([clientNonce,serverNonce]),cipher=direction=>new InternalRecordCipher(Buffer.from(hkdfSync("sha256",key,salt,`senpi-rpc-internal ${direction}`,32)),direction);return new InternalRecordStream(wire,cipher(role==="client"?"c2s":"s2c"),cipher(role==="client"?"s2c":"c2s"))}var InternalRecordStream=class extends Duplex{constructor(wire,sender,receiver){super(),this.header=Buffer.alloc(4),this.headerUsed=0,this.bodyUsed=0,this.offset=0,this.wireDone=!1,this.wireClosed=!1,this.ended=!1,this.wire=wire,this.sender=sender,this.receiver=receiver,this.once("error",error=>{error.message.startsWith("internal_record")&&process.stderr.write(`senpi rpc: internal hop closed: ${error.message}
2
+ import{hostChildStartupHandOff,relayHostStartupEvents,reportStartupMilestone,startupHandOff}from"./chunk-R2Z7CX77.js";import{CHILD_KILL_EXIT_TIMEOUT_MS,CHILD_STALLED_STOP_MAX_MS_ENV,CHILD_STOP_TIMEOUT_MS,DEFAULT_HANDOFF_GRACE_MS,HANDOFF_GRACE_MS_ENV,IdleExitDecider,STOP_STALL_EVIDENCE_MAX_AGE_MS,childStalledStopMaxMs,classifyChildExit,clearStopProgress,errorMessage,hostEnsureLockOptions,hostEnsureLockTarget,hostLoopStalled,layeredSupervisorIntent,noteChildExit,parseIdleExitMs,readStopIntent,recordHostCrash,releaseGeneration,resolveHostPolicy,supervisorLog,watchDrainRequest,writeDrainRequest,writeDrainWatch,writeHostReady,writeStderrLine,writeStopIntent,writeStopProgress}from"./chunk-UCXBDE6R.js";import{HOST_DAEMON_DIR_ENV,HostDaemonStateError,createGenerationDirectory,createHostDaemonPaths,generationPaths,hostOwnerGone,readHostOwner,sameHostOwner,writeJsonAtomic}from"./chunk-YI6KRJDC.js";import{OBSERVE_REQUEST_FIELD,RPC_AUTH_CAPABILITY,RPC_AUTH_HEX,RPC_LAUNCH_PROOF_RECORD,RpcPublicEndpoint,authRecord,isObservingRequest,launchProofRecordRefusal,observingHoldChange,requestOriginHostInstance,rpcAuthProof,rpcProofMatches}from"./chunk-VUY4BZDI.js";import{MAX_RPC_LINE_CHARACTERS,attachJsonlLineReader,serializeJsonLine}from"./chunk-SF4MQDKZ.js";import{runtimeExecArgv,spawnWithPrivateFds}from"./chunk-E266ORGA.js";import{ADOPTION_GRANT_FILE,STARTUP_ATTEMPT_FILE,releaseStartupFillers,startupGrantLine,withStartupPipe}from"./chunk-T2SMQPRE.js";import{HOST_INSTANCE_ID_ENV,HOST_STARTUP_EVENTS_ENV,INTERNAL_KEY_STDIN_ENV}from"./chunk-RUGTHELO.js";import{BIND_SCRATCH_INFIX,BIND_SCRATCH_SOCKET,MAX_SOCKET_PATH_BYTES,PUBLIC_SOCKET_IDENTITY_FILE,adoptPublicSocket,classifyEndpointOwnership,parseSocketIdentity,shieldSocketDuringClose,socketEntryListenerState,statSocketIdentity,unlinkOwnedSocket,writeSocketIdentityFile}from"./chunk-5XHOHZIR.js";import{SOCKET_HANDSHAKE_TIMEOUT_MS,SOCKET_SECRET_FILE_ENV,acquireOwnershipSafeLock,authenticateSocket,createSocketSecret,ensureSocketSecret,isBusy,resolveSocketTransportAddress,sendSocketHandshake,socketSecretPath}from"./chunk-HW6AAS3R.js";import{VERSION,brandEnvNames,envValue,getAgentDir,isBunBinary,isBundledNode}from"./chunk-SODMQEHO.js";import{processStartTimeMs,readProcessIdentity,readProcessStartTime,sameProcessStartMs,waitForStartTime}from"./chunk-O5RYI3IW.js";import{randomUUID as randomUUID3}from"node:crypto";import{mkdir as mkdir5,rm as rm4}from"node:fs/promises";import{join as join6}from"node:path";var HostAdmission=class{constructor(info){this.stopped=!1,this.listeners=new Set,this.replies=Promise.resolve(),this.info=info}get stopping(){return this.stopped}protocol(){return{...this.info,lifecycle:this.stopped?"stopping":"ready"}}observe(info){this.info=info}stop(){this.stopped||(this.stopped=!0,this.replies=Promise.all([...this.listeners].map(listener=>listener())).then(()=>{}))}async flush(){let timer;try{await Promise.race([this.replies,new Promise(resolve2=>{timer=setTimeout(resolve2,2e3)})])}finally{clearTimeout(timer)}}onStop(listener){return this.listeners.add(listener),()=>this.listeners.delete(listener)}};function hostStoppingResponse(id,command,admission){return{...typeof id=="string"?{id}:{},type:"response",command,success:!1,error:"host_stopping",errorCode:"host_stopping",errorData:{instanceId:admission.protocol().instanceId}}}function hostCrashCleanupPaths(targets){let publicEntry=targets.platform==="win32"?[targets.publicSocket]:[];return targets.successor?publicEntry:[targets.generationPidFile,targets.settingsFile,...publicEntry,targets.pointerFile]}import{existsSync,readFileSync,realpathSync}from"node:fs";import{access,readFile}from"node:fs/promises";import{dirname,resolve}from"node:path";import{fileURLToPath}from"node:url";function isCliModuleEntry(moduleUrl){let entry=process.argv[1];if(!entry)return!1;try{return fileURLToPath(moduleUrl)===realpathSync(entry)}catch{return!1}}function resolveCliMainPath(modulePath=fileURLToPath(import.meta.url),bundled=isBundledNode){let declared=bundled?resolveDeclaredCliEntry(modulePath):void 0;if(declared!==void 0)return declared;let extension=modulePath.endsWith(".ts")?".ts":".js",unbundled=resolve(dirname(modulePath),"..","..",`cli-main${extension}`);return existsSync(unbundled)?unbundled:resolveDeclaredCliEntry(modulePath)??unbundled}function resolveDeclaredCliEntry(modulePath){let dir=dirname(modulePath);for(let depth=0;depth<8;depth+=1){let manifestPath=resolve(dir,"package.json");if(existsSync(manifestPath)){try{let declared=JSON.parse(readFileSync(manifestPath,"utf8")).bin,candidates=typeof declared=="string"?[declared]:Object.values(declared??{});for(let candidate of candidates){let entry=resolve(dir,candidate);if(existsSync(entry))return entry}}catch{}return}let parent=dirname(dir);if(parent===dir)return;dir=parent}}var existsAsync=path=>access(path).then(()=>!0,()=>!1);async function resolveCliMainPathAsync(modulePath=fileURLToPath(import.meta.url),bundled=isBundledNode){let declared=bundled?await resolveDeclaredCliEntryAsync(modulePath):void 0;if(declared!==void 0)return declared;let extension=modulePath.endsWith(".ts")?".ts":".js",unbundled=resolve(dirname(modulePath),"..","..",`cli-main${extension}`);return await existsAsync(unbundled)?unbundled:await resolveDeclaredCliEntryAsync(modulePath)??unbundled}async function resolveDeclaredCliEntryAsync(modulePath){let dir=dirname(modulePath);for(let depth=0;depth<8;depth+=1){let manifestPath=resolve(dir,"package.json");if(await existsAsync(manifestPath)){try{let declaredBin=JSON.parse(await readFile(manifestPath,"utf8")).bin,candidates=typeof declaredBin=="string"?[declaredBin]:Object.values(declaredBin??{});for(let candidate of candidates){let entry=resolve(dir,candidate);if(await existsAsync(entry))return entry}}catch{}return}let parent=dirname(dir);if(parent===dir)return;dir=parent}}import{watch}from"node:fs";import{createConnection,Socket}from"node:net";var MAX_CLASSIFIED_LINE_BYTES=64*1024,NEWLINE=10,ClientOccupancy=class{constructor(onAttach,ownInstance){this.clients=new Set,this.observers=new Set,this.attached=new Set,this.held=new Set,this.dependents=new Set,this.closed=!1,this.onAttach=onAttach,this.ownInstance=ownInstance}get attachedCount(){return this.attached.size+this.held.size}get unclassifiedCount(){return this.clients.size-this.observers.size-this.attached.size-this.dependents.size}admit(client){if(this.closed)return client.destroy(),!1;this.clients.add(client);let pending=Buffer.alloc(0),attach=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.held.delete(client),this.attached.add(client),this.onAttach()},depend=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.held.delete(client),this.dependents.add(client)},classify=chunk=>{pending=Buffer.concat([pending,chunk]);for(let newline=pending.indexOf(NEWLINE);newline!==-1;newline=pending.indexOf(NEWLINE)){let line=pending.subarray(0,newline).toString("utf8");if(pending=pending.subarray(newline+1),!isObservingRequest(line)){this.ownInstance!==void 0&&requestOriginHostInstance(line)===this.ownInstance?depend():attach();return}this.observers.add(client);let hold=observingHoldChange(line);hold===!0&&!this.held.has(client)?(this.held.add(client),this.onAttach()):hold===!1&&this.held.delete(client)}pending.length>MAX_CLASSIFIED_LINE_BYTES&&attach()};return client.on("data",classify),!0}release(client){let unclassified=this.clients.has(client)&&!this.observers.has(client)&&!this.attached.has(client)&&!this.dependents.has(client);return this.clients.delete(client),this.observers.delete(client),this.attached.delete(client),this.held.delete(client),this.dependents.delete(client),unclassified}destroyAll(){this.closed=!0;for(let client of this.clients)client.destroy()}};var SessionRunActivity=class{#running=new Set;#settling=new Map;#settleHoldMs;#now;#onSettleHoldExpired;constructor(options={}){this.#settleHoldMs=options.settleHoldMs??Number.POSITIVE_INFINITY,this.#now=options.now??Date.now,this.#onSettleHoldExpired=options.onSettleHoldExpired}observe(line){let event=parseHostEvent(line);if(event===void 0)return!1;if(event.type==="agent_start")this.#running.add(event.sessionId),this.#settling.delete(event.sessionId);else if(event.type==="agent_settled"&&event.reason!=="session_closed")this.#running.delete(event.sessionId),this.#settling.set(event.sessionId,this.#now());else if(event.type==="agent_settled"||event.type==="agent_idle"||event.type==="session_closed")this.#running.delete(event.sessionId),this.#settling.delete(event.sessionId);else return!1;return!0}get busySessions(){return this.#running.size}get settlingSessions(){let now=this.#now();for(let[sessionId,settledAt]of this.#settling){let heldMs=now-settledAt;heldMs<this.#settleHoldMs||(this.#settling.delete(sessionId),this.#onSettleHoldExpired?.(sessionId,heldMs))}return this.#settling.size}};function holdIdleExitForSettling(decision,runs){return decision==="exit"&&runs.settlingSessions>0?"idle":decision}function parseHostEvent(line){let event;try{event=JSON.parse(line)}catch{return}if(typeof event!="object"||event===null)return;let{type,sessionId,reason}=event;return typeof sessionId=="string"?{type,sessionId,reason}:void 0}import{randomBytes}from"node:crypto";import{hkdfSync}from"node:crypto";import{Duplex}from"node:stream";import{createCipheriv,createDecipheriv}from"node:crypto";var INTERNAL_RECORD_MAX=64*1024,RECORD_LIMIT=1n<<32n,InternalRecordCipher=class{constructor(key,direction,counter=0n){this.key=key,this.direction=direction,this.counter=counter}parameters(){if(this.counter<0n||this.counter>=RECORD_LIMIT)throw new Error("internal_record_counter_exhausted");let count=Buffer.alloc(8);return count.writeBigUInt64BE(this.counter),{nonce:Buffer.concat([Buffer.alloc(4),count]),aad:Buffer.concat([Buffer.from(this.direction),count])}}seal(plaintext){if(plaintext.length<1||plaintext.length>INTERNAL_RECORD_MAX)throw new Error("internal_record_length");let{nonce:nonce2,aad}=this.parameters(),cipher=createCipheriv("aes-256-gcm",this.key,nonce2);cipher.setAAD(aad);let body=Buffer.concat([cipher.update(plaintext),cipher.final(),cipher.getAuthTag()]),length=Buffer.alloc(4);return length.writeUInt32BE(body.length),this.counter++,Buffer.concat([length,body])}open(body){if(body.length<17||body.length>INTERNAL_RECORD_MAX+16)throw new Error("internal_record_length");let{nonce:nonce2,aad}=this.parameters(),decipher=createDecipheriv("aes-256-gcm",this.key,nonce2);decipher.setAAD(aad),decipher.setAuthTag(body.subarray(-16));let plaintext=decipher.update(body.subarray(0,-16)),final=decipher.final();return this.counter++,Buffer.concat([plaintext,final])}};function createInternalRecordStream(wire,key,clientNonce,serverNonce,role){let salt=Buffer.concat([clientNonce,serverNonce]),cipher=direction=>new InternalRecordCipher(Buffer.from(hkdfSync("sha256",key,salt,`senpi-rpc-internal ${direction}`,32)),direction);return new InternalRecordStream(wire,cipher(role==="client"?"c2s":"s2c"),cipher(role==="client"?"s2c":"c2s"))}var InternalRecordStream=class extends Duplex{constructor(wire,sender,receiver){super(),this.header=Buffer.alloc(4),this.headerUsed=0,this.bodyUsed=0,this.offset=0,this.wireDone=!1,this.wireClosed=!1,this.ended=!1,this.wire=wire,this.sender=sender,this.receiver=receiver,this.once("error",error=>{error.message.startsWith("internal_record")&&process.stderr.write(`senpi rpc: internal hop closed: ${error.message}
3
3
  `)}),this.on("error",()=>{}),wire.on("data",chunk=>{wire.pause(),this.pending=chunk,this.offset=0,this.consume()}),wire.once("end",()=>{this.wireDone=!0,this.pending===void 0&&this.finish()}),wire.once("error",error=>this.destroy(error)),wire.once("close",()=>{this.wireDone=!0,this.wireClosed=!0,this.ended&&this.readableEnded?this.destroy():this.pending===void 0&&this.finish()}),this.once("end",()=>{this.wireClosed&&this.destroy()})}finish(){this.ended||(this.ended=!0,this.headerUsed!==0||this.body!==void 0?this.destroy(new Error("internal_record_truncated")):this.push(null))}consume(){try{let chunk=this.pending;if(!chunk)return;for(;this.offset<chunk.length;){if(!this.body){let n2=Math.min(4-this.headerUsed,chunk.length-this.offset);if(chunk.copy(this.header,this.headerUsed,this.offset,this.offset+n2),this.headerUsed+=n2,this.offset+=n2,this.headerUsed!==4)break;let length=this.header.readUInt32BE();if(length<17||length>INTERNAL_RECORD_MAX+16)throw new Error("internal_record_length");this.headerUsed=0,this.body=Buffer.alloc(length)}let n=Math.min(this.body.length-this.bodyUsed,chunk.length-this.offset);if(chunk.copy(this.body,this.bodyUsed,this.offset,this.offset+n),this.bodyUsed+=n,this.offset+=n,this.bodyUsed===this.body.length){let plaintext=this.receiver.open(this.body);if(this.body=void 0,this.bodyUsed=0,!this.push(plaintext)){this.offset===chunk.length&&(this.pending=void 0,this.wireDone&&this.finish());return}}}this.pending=void 0,this.wireDone?this.finish():this.wire.resume()}catch(cause){this.destroy(cause instanceof Error&&cause.message.startsWith("internal_record")?cause:new Error("internal_record_unverified",{cause}))}}_read(){this.pending?this.consume():this.wire.resume()}_write(chunk,_encoding,callback){let offset=0,next=error=>{if(error){callback(error);return}if(this.destroyed){callback(new Error("internal_hop_lost"));return}if(offset===chunk.length){callback();return}try{let end=Math.min(chunk.length,offset+INTERNAL_RECORD_MAX),record2=this.sender.seal(chunk.subarray(offset,end));offset=end,this.wire.write(record2,next)}catch(cause){callback(cause instanceof Error?cause:new Error("internal_record_invalid"))}};next()}_final(callback){this.wire.end(callback)}_destroy(error,callback){this.wire.destroy(),callback(error)}};var INTERNAL_LAUNCH_ID="internal";function proof(key,label,first,second){return rpcAuthProof(key,label,INTERNAL_LAUNCH_ID,first,second)}function matches(actual,expected){return rpcProofMatches(expected,actual)}function object(value){if(!isObject(value))throw new Error("auth_failed");return value}function isObject(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function nonce(value){if(typeof value!="string"||!RPC_AUTH_HEX.test(value))throw new Error("auth_failed");return value}var HOST_PRE_AUTH_BUDGET={maxBytes:8192,timeoutMs:2e3};async function handshake(socket,budget,run){let readBytes=0,ended=!1,rejectPending,fail=error=>{ended=!0,rejectPending?.(error),socket.destroy()},timer=budget.timeoutMs===void 0?void 0:setTimeout(()=>fail(new Error("internal_auth_timeout")),budget.timeoutMs);timer?.unref();let onError=error=>fail(error),onClose=()=>fail(new Error("internal_hop_lost"));socket.on("error",onError),socket.once("close",onClose);let read2=()=>new Promise((resolve2,reject)=>{if(ended)return reject(new Error("internal_hop_lost"));let buffer=Buffer.alloc(0);rejectPending=cause=>{socket.off("data",data),reject(cause)};let data=chunk=>{let newline=chunk.indexOf(10),used=newline===-1?chunk.length:newline+1;if(readBytes+=used,readBytes>budget.maxBytes)return fail(new Error("internal_auth_oversized"));if(buffer=Buffer.concat([buffer,chunk.subarray(0,used)]),newline!==-1){socket.pause(),socket.off("data",data),rejectPending=void 0,used<chunk.length&&socket.unshift(chunk.subarray(used));try{resolve2(object(JSON.parse(buffer.toString("utf8"))))}catch{reject(new Error("auth_failed"))}}};socket.on("data",data),socket.resume()});try{return await run(read2,frame=>new Promise((resolve2,reject)=>{socket.write(`${JSON.stringify(frame)}
4
- `,error=>error?reject(error):resolve2())}))}catch(cause){throw socket.destroy(),cause}finally{timer&&clearTimeout(timer),socket.off("error",onError),socket.off("close",onClose)}}function connectInternalConnection(socket,key,options={}){return handshake(socket,{maxBytes:MAX_RPC_LINE_CHARACTERS,timeoutMs:options.timeoutMs},async(read2,send)=>{let clientNonce=randomBytes(32).toString("hex"),[response]=await Promise.all([read2(),send({id:"internal-protocol",type:"get_protocol_info",observe:!0,auth:{client_nonce:clientNonce}})]),data=response.data;if(!isObject(data)||!isObject(data.auth))throw new Error("host_identity_unproven");let auth=data.auth,serverNonce=nonce(auth.server_nonce);if(response.id!=="internal-protocol"||response.success!==!0||auth.launch_id!==INTERNAL_LAUNCH_ID||!matches(auth.server_proof,proof(key,"server",clientNonce,serverNonce)))throw new Error("host_identity_unproven");let[result]=await Promise.all([read2(),send({id:"internal-auth",type:"authenticate",client_proof:proof(key,"client",serverNonce,clientNonce)})]);if(result.id!=="internal-auth"||result.command!=="authenticate"||result.success!==!0)throw new Error("auth_failed");return createInternalRecordStream(socket,key,Buffer.from(clientNonce,"hex"),Buffer.from(serverNonce,"hex"),"client")})}function acceptInternalConnection(socket,key,protocol={}){return handshake(socket,HOST_PRE_AUTH_BUDGET,async(read2,send)=>{let refuse=async frame2=>{throw await send({id:frame2.id,type:"response",command:frame2.type,success:!1,error:"auth_required",errorCode:"auth_required"}),new Error("auth_required")},first=await read2(),offered=isObject(first.auth)?first.auth.client_nonce:void 0;if(first.type!=="get_protocol_info"||typeof offered!="string"||!RPC_AUTH_HEX.test(offered))return refuse(first);let clientNonce=offered,serverNonce=randomBytes(32).toString("hex"),[frame]=await Promise.all([read2(),send({id:first.id,type:"response",command:first.type,success:!0,data:{...protocol,capabilities:[...Array.isArray(protocol.capabilities)?protocol.capabilities:[],"socket_auth"],auth:{launch_id:INTERNAL_LAUNCH_ID,server_nonce:serverNonce,server_proof:proof(key,"server",clientNonce,serverNonce)}}})]);if(frame.type!=="authenticate")return refuse(frame);let valid=matches(frame.client_proof,proof(key,"client",serverNonce,clientNonce));if(await send({id:frame.id,type:"response",command:"authenticate",success:valid,...valid?{}:{error:"auth_failed",errorCode:"auth_failed"}}),!valid)throw new Error("auth_failed");return createInternalRecordStream(socket,key,Buffer.from(clientNonce,"hex"),Buffer.from(serverNonce,"hex"),"server")})}function activeTurnsForIdleDecision(input){return input.healthy?input.observedBusy:input.unhealthySince===void 0||input.now-input.unhealthySince<input.unknownGraceMs?1:0}function createObserverLink(options){let current,healthy=!1,unhealthySince,retry,armRetry=()=>{retry!==void 0||options.settled()||(retry=options.setTimer(()=>{retry=void 0,open().catch(armRetry)},options.retryDelayMs))};async function open(){let socket=await options.open();current=socket,healthy=!0,unhealthySince=void 0,socket.onLost(()=>{current!==socket||options.settled()||(healthy=!1,unhealthySince??=options.now(),current=void 0,armRetry())})}return{open,healthy:()=>healthy,unhealthySince:()=>unhealthySince,stop:()=>{retry?.cancel(),retry=void 0,current=void 0}}}var INTERNAL_OBSERVER_HANDSHAKE_MS=5e3,SupervisorActivity=class{constructor(options){this.options=options,this.decider=new IdleExitDecider(options.idleExitMs,Date.now,startupHandOff()?.budgetMs),this.runs=new SessionRunActivity({settleHoldMs:options.idleExitMs,onSettleHoldExpired:(sessionId,heldMs)=>supervisorLog(`session ${sessionId} settled ${heldMs} ms ago and its agent_settled extension handlers have not finished; idle exit no longer waits for them`)}),this.clients=new ClientOccupancy(()=>this.refresh(),options.instanceId),this.observerLink=createObserverLink({open:()=>this.connectObserver(),settled:options.settled,retryDelayMs:250,now:Date.now,setTimer:(run,ms)=>{let timer=setTimeout(run,ms);return timer.unref?.(),{cancel:()=>clearTimeout(timer)}}})}current(){return{connections:this.clients.attachedCount,activeTurns:activeTurnsForIdleDecision({healthy:this.observerLink.healthy(),unhealthySince:this.observerLink.unhealthySince(),now:Date.now(),unknownGraceMs:this.decider.idleExitMs,observedBusy:this.runs.busySessions})}}refresh(){let current=this.current();return(current.connections>0||current.activeTurns>0||this.clients.unclassifiedCount>0)&&this.options.onActivity?.(),holdIdleExitForSettling(this.decider.update(current),this.runs)}quiescent(){return this.observerLink.healthy()&&this.runs.busySessions===0&&this.runs.settlingSessions===0&&this.clients.attachedCount===0&&this.clients.unclassifiedCount===0}openObserver(){return this.observerLink.open()}stopObserver(){this.observerLink.stop(),this.observerSocket?.destroy()}async connectObserver(){let secret=this.options.internalSecret,next=createConnection(resolveSocketTransportAddress(this.options.internalSocket,process.platform,secret));secret&&sendSocketHandshake(next,secret);let stream;try{this.options.internalKey?stream=await connectInternalConnection(next,this.options.internalKey,{timeoutMs:INTERNAL_OBSERVER_HANDSHAKE_MS}):(await waitForConnect(next,5e3),stream=next)}catch(cause){throw next.destroy(),cause}return this.observerSocket=stream,attachJsonlLineReader(stream,line=>this.observeHostEvent(line),{maxLineLength:MAX_RPC_LINE_CHARACTERS}),{onLost:handler=>{let lost=()=>{handler(),this.options.onActivity?.()};stream.once("close",lost),stream.once("error",lost)}}}observeHostEvent(line){this.runs.observe(line)&&this.refresh()}},OWNER_EXIT_GRACE_MS=2e3,OWNER_PROBE_MAX_INTERVAL_MS=5e3,SupervisorOwner=class{constructor(generationDir){this.watchFailed=!1,this.nextProbeAt=0,this.probeIntervalMs=1e3,this.gone=!1,this.revision=0,this.stopped=!1,this.idle=new IdleExitDecider(OWNER_EXIT_GRACE_MS,()=>performance.now()),this.generationDir=generationDir}async start(fd){if(await this.reload(),!(fd===void 0||this.owner==null))try{let pipe=new Socket({fd,readable:!0,writable:!1});this.pipe=pipe;let bound=this.owner,failed=!1,eof=()=>{!failed&&!this.stopped&&sameHostOwner(this.owner,bound)&&(this.gone=!0)};pipe.once("end",eof),process.platform==="win32"&&pipe.once("close",eof),pipe.once("error",()=>{failed=!0,this.pipe===pipe&&(this.pipe=void 0),pipe.destroy()}),pipe.resume()}catch{this.pipe=void 0}}async reload(){let revision=++this.revision,next=await readHostOwner(this.generationDir);if(!(this.stopped||revision!==this.revision)){if(sameHostOwner(this.owner,next)||(this.pipe?.destroy(),this.pipe=void 0,this.gone=!1,this.nextProbeAt=0,this.probeIntervalMs=1e3,this.activity()),this.owner=next,next==null)this.watcher?.close(),this.watcher=void 0;else if(!this.watcher&&!this.watchFailed)try{this.watcher=watch(this.generationDir,(_event,filename)=>{filename?.toString()==="owner.json"&&this.reload()}),this.watcher.once("error",()=>{this.watchFailed=!0,this.watcher?.close(),this.watcher=void 0})}catch{this.watchFailed=!0}}}activity(){this.idle.update({connections:1,activeTurns:0})}async shouldExit(activity){this.watcher||await this.reload();let owner=this.owner,revision=this.revision;if(owner!=null&&(!this.pipe||process.ppid!==owner.pid)&&!this.gone&&performance.now()>=this.nextProbeAt){let gone=await hostOwnerGone(owner);if(this.stopped||revision!==this.revision)return!1;this.gone=gone,this.nextProbeAt=performance.now()+this.probeIntervalMs,this.probeIntervalMs=Math.min(OWNER_PROBE_MAX_INTERVAL_MS,this.probeIntervalMs*2)}let quiet=this.gone&&owner!=null&&activity.quiescent();if(this.idle.update({connections:quiet?0:1,activeTurns:0})!=="exit")return!1;let current=await readHostOwner(this.generationDir);return this.stopped||revision!==this.revision?!1:sameHostOwner(owner,current)?activity.quiescent():(await this.reload(),!1)}stop(){this.stopped=!0,this.watcher?.close(),this.pipe?.destroy()}};function waitForConnect(socket,timeoutMs){return new Promise((resolve2,reject)=>{let timer=setTimeout(()=>{cleanup(),reject(new Error(`observer connection to internal host timed out after ${timeoutMs}ms`))},timeoutMs),onConnect=()=>{cleanup(),resolve2()},onError=cause=>{cleanup(),reject(cause)},cleanup=()=>{clearTimeout(timer),socket.off("connect",onConnect),socket.off("error",onError)};socket.once("connect",onConnect),socket.once("error",onError)})}import{readFile as readFile2}from"node:fs/promises";var SUPERSESSION_POLL_MS=1e3,ABSENT_CONFIRMATIONS=3,REPLACED_CONFIRMATIONS=3,IDENTITY_PROBE_TIMEOUT_MS=2e3;function watchForSupersession(endpoint,onLost){if(endpoint.identity===void 0)return endpoint.pointer===void 0?()=>{}:watchPointerSupersession(endpoint,endpoint.pointer,onLost);let absentPolls=0,lost=!1,lose=loss=>{lost||(lost=!0,stop(),onLost(loss))},timer=setInterval(()=>{endpoint.settled?.()!==!0&&classifyEndpointOwnership(endpoint.path,endpoint.identity).then(ownership=>{if(endpoint.settled?.()!==!0)switch(ownership){case"replaced":lose("replaced");return;case"absent":if(absentPolls+=1,absentPolls<ABSENT_CONFIRMATIONS)return;lose("absent");return;case"held":case"unknown":absentPolls=0;return}},ignore)},SUPERSESSION_POLL_MS);timer.unref?.();let stop=()=>clearInterval(timer);return stop}function watchPointerSupersession(endpoint,pointer,onLost){let probe=endpoint.probeInstanceId??probeAnsweringInstance,readPointer=endpoint.readPointerInstanceId??pointerInstanceId,agreeingPolls=0,observing=!1,lost=!1,observe=async()=>{let named=await readPointer(pointer.file);return named===void 0||named===pointer.instanceId?!1:await probe(endpoint.path)===named},timer=setInterval(()=>{lost||observing||endpoint.settled?.()===!0||(observing=!0,observe().then(replaced=>{lost||endpoint.settled?.()===!0||(agreeingPolls=replaced?agreeingPolls+1:0,!(agreeingPolls<REPLACED_CONFIRMATIONS)&&(lost=!0,clearInterval(timer),onLost("replaced")))},()=>{agreeingPolls=0}).finally(()=>{observing=!1}))},SUPERSESSION_POLL_MS);return timer.unref?.(),()=>clearInterval(timer)}async function pointerInstanceId(file){try{let parsed=JSON.parse(await readFile2(file,"utf8")),instanceId=typeof parsed=="object"&&parsed!==null?Reflect.get(parsed,"instance_id"):void 0;return typeof instanceId=="string"&&instanceId!==""?instanceId:void 0}catch{return}}async function probeAnsweringInstance(path){let{isRecord:isRecord2,requestOnSocket}=await import("./host-socket-request-DMYXC56U.js"),answer=await requestOnSocket(path,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},IDENTITY_PROBE_TIMEOUT_MS).catch(()=>{});return isRecord2(answer)&&typeof answer.instanceId=="string"?answer.instanceId:void 0}function ignore(){}var SupervisorDrain=class{constructor(child,shuttingDown,beginStopping=()=>{},relay){this.draining=!1,this.child=child,this.shuttingDown=shuttingDown,this.beginStopping=beginStopping,this.relay=relay}get active(){return this.draining}drain(){if(this.draining||this.shuttingDown())return;this.draining=!0,this.beginStopping(),supervisorLog("draining into the next generation");let graceMs=parseIdleExitMs(process.env[HANDOFF_GRACE_MS_ENV])??6e5;this.graceTimer=setTimeout(()=>{supervisorLog(JSON.stringify({event:"handoff_grace_expired",graceMs})),this.requestChildDrain()},graceMs),this.graceTimer.unref(),this.requestChildDrain()}stop(){this.graceTimer&&clearTimeout(this.graceTimer)}async acceptRequests(generation){let stop=watchDrainRequest(generation.drainRequestFile,request=>{supervisorLog(`drain requested (${request.reason})`),this.drain()});return await writeDrainWatch(generation.drainWatchFile,{pid:process.pid}).catch(cause=>{supervisorLog(`cannot advertise the drain request: ${errorMessage(cause)}`)}),stop}requestChildDrain(){let{child,relay}=this;if(!(child.pid===void 0||child.exitCode!==null||child.signalCode!==null)&&(relay&&writeDrainRequest(relay.file,{sender:relay.sender,reason:"supervisor_drain"}).catch(cause=>{supervisorLog(`could not relay the drain to the host: ${errorMessage(cause)}`)}),process.platform!=="win32"))try{process.kill(child.pid,"SIGUSR1")}catch(cause){supervisorLog(`could not ask the host to drain: ${errorMessage(cause)}`)}}};function drainOnPublicSocketLoss(path,identity,settled,drain,onReplaced,pointer){return watchForSupersession({path,identity,settled,...pointer&&{pointer}},loss=>{loss==="replaced"&&onReplaced(),supervisorLog(loss==="absent"?"the public socket entry is gone; nothing can reach this generation; draining":"another generation owns the public socket; draining this one"),drain.drain()})}var CHILD_IDENTITY_TICK_MS=500,CHILD_IDENTITY_READ_GAP_TICKS=10,CHILD_IDENTITY_READ_GAP_MAX_TICKS=120;function childLiveness(pid){try{return process.kill(pid,0),"alive"}catch(cause){return cause instanceof Error&&"code"in cause&&cause.code==="ESRCH"?"dead":"unknown"}}async function watchWin32ChildIdentity(child,shuttingDown,onGone){let pid=child.pid;if(pid===void 0)return()=>{};let readStartTime=()=>readProcessStartTime(pid,process.platform,1e3),baseline=await readStartTime().catch(()=>{}),adoptable=!0,suspect=!1,deadTicks=0,reading=!1,ended=!1,ticksUntilRead=0,readGapTicks=CHILD_IDENTITY_READ_GAP_TICKS,backOff=()=>{ticksUntilRead=readGapTicks,readGapTicks=Math.min(readGapTicks*2,CHILD_IDENTITY_READ_GAP_MAX_TICKS)},end=()=>{ended=!0,onGone()},settle=current=>{if(!ended){if(baseline===void 0){current!==void 0&&adoptable&&childLiveness(pid)==="alive"?baseline=current:backOff();return}if(current!==void 0&&current!==baseline)return end();current===baseline&&(suspect=!1),backOff()}},timer=setInterval(()=>{if(ended||shuttingDown()||child.exitCode!==null||child.signalCode!==null)return;ticksUntilRead>0&&ticksUntilRead--;let liveness=childLiveness(pid);if(liveness==="dead"){if(deadTicks++,deadTicks>=2)return end();suspect=!0,adoptable=!1;return}(deadTicks>0||liveness==="unknown")&&(suspect=!0,adoptable=!1),deadTicks=0,!(!(baseline===void 0?adoptable:suspect)||reading||ticksUntilRead>0)&&(reading=!0,readStartTime().then(settle,()=>{ended||backOff()}).finally(()=>{reading=!1}))},CHILD_IDENTITY_TICK_MS);return timer.unref?.(),()=>{ended=!0,clearInterval(timer)}}import{randomBytes as randomBytes2}from"node:crypto";import{readFile as readFile4}from"node:fs/promises";import{join as join3}from"node:path";import{readFileSync as readFileSync2}from"node:fs";function readProcessStartTicks(pid,platform=process.platform){if(platform==="linux")try{let stat2=readFileSync2(`/proc/${pid}/stat`,"utf8"),ticks=stat2.slice(stat2.lastIndexOf(")")+2).split(" ")[19];return ticks!==void 0&&/^\d+$/.test(ticks)?ticks:void 0}catch{return}}async function compareRecordedStart(pid,recorded,platform,probe){if(platform==="linux"){if(recorded.ticks===void 0)return"unknown";let observed2=probe.ticks(pid);return observed2===void 0?"unknown":observed2===recorded.ticks?"same":"changed"}if(recorded.time===void 0)return"unknown";let observed=await probe.time(pid),recordedMs=processStartTimeMs(recorded.time),observedMs=observed===void 0?void 0:processStartTimeMs(observed);return recordedMs===void 0||observedMs===void 0?"unknown":sameProcessStartMs(recordedMs,observedMs)?"same":"changed"}import{randomUUID}from"node:crypto";import{realpathSync as realpathSync2}from"node:fs";import{mkdir,readFile as readFile3,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{join}from"node:path";var INTERNAL_HOST_DIR_PREFIX="senpi-rpc-host-internal-",SHORT_TEMP_ROOT="/tmp";function internalHostDirRoots(){let primary=tmpdir();return canonicalPath(primary)!==canonicalPath(SHORT_TEMP_ROOT)?[primary,SHORT_TEMP_ROOT]:[Buffer.byteLength(primary)<Buffer.byteLength(SHORT_TEMP_ROOT)?primary:SHORT_TEMP_ROOT]}function canonicalPath(path){try{return realpathSync2(path)}catch{return path}}function internalHostDirRoot(name){for(let root of internalHostDirRoots())if(Buffer.byteLength(join(root,name,"host.sock"))<=MAX_SOCKET_PATH_BYTES)return root;let tried=internalHostDirRoots().map(root=>join(root,name,"host.sock"));throw new Error(`internal_socket_path_too_long: every candidate exceeds ${MAX_SOCKET_PATH_BYTES} bytes (${tried.join(", ")}); set TMPDIR to a shorter directory`)}async function createInternalSocketPath(baseDir=tmpdir(),platform=process.platform){if(platform==="win32"){let dir2=join(baseDir,`internal-${randomUUID()}`);return await mkdir(dir2,{recursive:!0,mode:448}),{socket:`\\\\.\\pipe\\senpi-rpc-internal-${randomUUID()}`,dir:dir2,secretPath:join(dir2,"secret")}}let name=`${INTERNAL_HOST_DIR_PREFIX}${randomUUID().slice(0,8)}`,dir=join(internalHostDirRoot(name),name);return await mkdir(dir,{recursive:!1,mode:448}),await writeFile(join(dir,".owner"),JSON.stringify({pid:process.pid,processStartTime:await readProcessStartTime(process.pid),createdAt:Date.now()}),{mode:384}),{socket:join(dir,"host.sock"),dir,secretPath:join(dir,".secret")}}var CHILD_START_TIME_WAIT_MS=1e4,CHILD_START_TIME_UNHURRIED_MS=15e3;async function readChildStartTime(pid,timeoutMs){let identity=await readProcessIdentity(pid,process.platform,timeoutMs,void 0,"UTC");if(identity.kind==="error")throw identity.error;return identity.kind==="present"?identity.identity:void 0}async function recordChildPid(file,pid,running){try{await writeJsonAtomic(file,{pid,processStartTime:null});let processStartTime=await waitForStartTime(pid,CHILD_START_TIME_WAIT_MS,p=>readChildStartTime(p,1e3)).catch(()=>{})??await readChildStartTime(pid,CHILD_START_TIME_UNHURRIED_MS).catch(()=>{});if(processStartTime===void 0){supervisorLog(`host child pid ${pid} start time unreadable at recording`);return}if(!running())return;await writeJsonAtomic(file,{pid,processStartTime})}catch(cause){supervisorLog(`could not record the host child pid: ${errorMessage(cause)}`)}}async function readSettingsFile(settingsFile){try{return JSON.parse(await readFile3(settingsFile,"utf8"))}catch{return}}import{execFileSync}from"node:child_process";import{closeSync as closeSync2,constants,fstatSync,openSync,rmSync}from"node:fs";import{join as join2}from"node:path";import{closeSync}from"node:fs";import{Socket as Socket2}from"node:net";function watchHostLifetime(fd,gone,unavailable){let stopped=!1,bun=Reflect.get(globalThis,"Bun");if(typeof bun=="object"&&bun!==null&&typeof Reflect.get(bun,"file")=="function"){let reader=Reflect.get(bun,"file")(fd).stream().getReader();return(async()=>{try{for(;!stopped;){let{done}=await reader.read();if(done){stopped||gone();return}}}catch{stopped||unavailable()}})(),()=>{stopped||(stopped=!0,reader.cancel().catch(()=>{}).finally(()=>closeSync(fd)))}}let socket=new Socket2({fd,readable:!0,writable:!1});return socket.once("end",()=>{stopped||gone()}),socket.once("error",()=>{stopped||unavailable()}),socket.unref(),socket.resume(),()=>{stopped=!0,socket.destroy()}}var HOST_WATCH_LIFETIME_FIFO_ENV="SENPI_RPC_HOST_LIFETIME_FIFO";function prepareLifetimeBinding(hopDir,platform=process.platform){if(platform!=="linux")return{};let path=join2(hopDir,"lifetime.fifo");try{return rmSync(path,{force:!0}),execFileSync("mkfifo",["-m","600",path],{stdio:"ignore"}),openSync(path,constants.O_RDWR),{lifetimeFifo:path}}catch{return{}}}function armLifetimeBinding(binding,gone,unavailable,platform=process.platform){if(platform==="win32")return;let fifo=platform==="linux"?openFifoReadEnd(binding.lifetimeFifo):void 0;if(fifo!==void 0)return binding.lifetimeFd!==void 0&&closeSync2(binding.lifetimeFd),watchHostLifetime(fifo,()=>gone("supervisor lifetime FIFO closed"),unavailable);if(binding.lifetimeFd!==void 0)return watchHostLifetime(binding.lifetimeFd,()=>gone("supervisor stdin lifetime closed"),unavailable)}function openFifoReadEnd(path){if(path===void 0)return;let fd;try{fd=openSync(path,constants.O_RDONLY|constants.O_NONBLOCK|constants.O_NOFOLLOW)}catch{return}let stat2=fstatSync(fd),owned=typeof process.getuid!="function"||stat2.uid===process.getuid();if(stat2.isFIFO()&&owned&&(stat2.mode&511)===384)return fd;closeSync2(fd)}async function recordedOwnerStartTime(dir){if(dir!==void 0)try{let owner=JSON.parse(await readFile4(join3(dir,".owner"),"utf8")),start=owner!==null&&typeof owner=="object"?Reflect.get(owner,"processStartTime"):void 0;return typeof start=="string"?start:void 0}catch{return}}async function prepareInternalHop(daemonDir){let created=await createInternalSocketPath(daemonDir),internal={...created,secretPath:created.secretPath??socketSecretPath(created.socket)},internalSecret=process.platform==="win32"?await createSocketSecret(internal.secretPath):void 0,internalKey=process.platform==="win32"?void 0:randomBytes2(32);return{internal,internalSocket:internal.socket,internalSecret,internalKey,...internalKey&&internal.dir!==void 0?prepareLifetimeBinding(internal.dir):{},supervisorStart:internalKey?{time:await recordedOwnerStartTime(internal.dir),ticks:readProcessStartTicks(process.pid)}:void 0,transport:{...internalSecret?{internalSecret}:{},...internalKey?{internalKey}:{}}}}import childProcess from"node:child_process";import{Socket as Socket4}from"node:net";import{extname}from"node:path";import{read}from"node:fs";import{readFile as readFile6}from"node:fs/promises";import{join as join5}from"node:path";import{Readable}from"node:stream";import{randomUUID as randomUUID2}from"node:crypto";import{mkdir as mkdir2,readFile as readFile5,rename,rm,writeFile as writeFile2}from"node:fs/promises";import{dirname as dirname2}from"node:path";var ENDPOINT_FENCE_WAIT_MS=15e3;function endpointOwnerToken(endpoint,instanceId,generation){return{v:1,endpoint,instanceId,generation,pid:process.pid,nonce:randomUUID2()}}var ownerFile=socket=>`${hostEnsureLockTarget(socket)}.owner.json`;async function withEndpointFence(socket,run,hooks){let fence=`${hostEnsureLockTarget(socket)}.fence.lock`;await mkdir2(dirname2(fence),{recursive:!0});let release;try{release=await acquireOwnershipSafeLock(fence,{retries:{retries:0,minTimeout:1,maxTimeout:1}})}catch(cause){if(!isBusy(cause))throw cause;hooks?.onFenceBusy?.(),release=await acquireOwnershipSafeLock(fence,hostEnsureLockOptions(ENDPOINT_FENCE_WAIT_MS))}try{return await run()}finally{await release()}}async function readEndpointOwner(socket){let parsed;try{parsed=JSON.parse(await readFile5(ownerFile(socket),"utf8"))}catch{return}if(typeof parsed!="object"||parsed===null)return;let token=parsed;return token.v===1&&typeof token.instanceId=="string"&&typeof token.nonce=="string"?parsed:void 0}async function writeEndpointOwner(socket,token){let path=ownerFile(socket),staged=`${path}.${process.pid}.tmp`;await writeFile2(staged,`${JSON.stringify(token)}
4
+ `,error=>error?reject(error):resolve2())}))}catch(cause){throw socket.destroy(),cause}finally{timer&&clearTimeout(timer),socket.off("error",onError),socket.off("close",onClose)}}function connectInternalConnection(socket,key,options={}){return handshake(socket,{maxBytes:MAX_RPC_LINE_CHARACTERS,timeoutMs:options.timeoutMs},async(read2,send)=>{let clientNonce=randomBytes(32).toString("hex"),[response]=await Promise.all([read2(),send({id:"internal-protocol",type:"get_protocol_info",observe:!0,auth:{client_nonce:clientNonce}})]),data=response.data;if(!isObject(data)||!isObject(data.auth))throw new Error("host_identity_unproven");let auth=data.auth,serverNonce=nonce(auth.server_nonce);if(response.id!=="internal-protocol"||response.success!==!0||auth.launch_id!==INTERNAL_LAUNCH_ID||!matches(auth.server_proof,proof(key,"server",clientNonce,serverNonce)))throw new Error("host_identity_unproven");let[result]=await Promise.all([read2(),send({id:"internal-auth",type:"authenticate",client_proof:proof(key,"client",serverNonce,clientNonce)})]);if(result.id!=="internal-auth"||result.command!=="authenticate"||result.success!==!0)throw new Error("auth_failed");return createInternalRecordStream(socket,key,Buffer.from(clientNonce,"hex"),Buffer.from(serverNonce,"hex"),"client")})}function acceptInternalConnection(socket,key,protocol={}){return handshake(socket,HOST_PRE_AUTH_BUDGET,async(read2,send)=>{let refuse=async frame2=>{throw await send({id:frame2.id,type:"response",command:frame2.type,success:!1,error:"auth_required",errorCode:"auth_required"}),new Error("auth_required")},first=await read2(),offered=isObject(first.auth)?first.auth.client_nonce:void 0;if(first.type!=="get_protocol_info"||typeof offered!="string"||!RPC_AUTH_HEX.test(offered))return refuse(first);let clientNonce=offered,serverNonce=randomBytes(32).toString("hex"),[frame]=await Promise.all([read2(),send({id:first.id,type:"response",command:first.type,success:!0,data:{...protocol,capabilities:[...Array.isArray(protocol.capabilities)?protocol.capabilities:[],"socket_auth"],auth:{launch_id:INTERNAL_LAUNCH_ID,server_nonce:serverNonce,server_proof:proof(key,"server",clientNonce,serverNonce)}}})]);if(frame.type!=="authenticate")return refuse(frame);let valid=matches(frame.client_proof,proof(key,"client",serverNonce,clientNonce));if(await send({id:frame.id,type:"response",command:"authenticate",success:valid,...valid?{}:{error:"auth_failed",errorCode:"auth_failed"}}),!valid)throw new Error("auth_failed");return createInternalRecordStream(socket,key,Buffer.from(clientNonce,"hex"),Buffer.from(serverNonce,"hex"),"server")})}function activeTurnsForIdleDecision(input){return input.healthy?input.observedBusy:input.unhealthySince===void 0||input.now-input.unhealthySince<input.unknownGraceMs?1:0}function createObserverLink(options){let current,healthy=!1,unhealthySince,retry,armRetry=()=>{retry!==void 0||options.settled()||(retry=options.setTimer(()=>{retry=void 0,open().catch(armRetry)},options.retryDelayMs))};async function open(){let socket=await options.open();current=socket,healthy=!0,unhealthySince=void 0,socket.onLost(()=>{current!==socket||options.settled()||(healthy=!1,unhealthySince??=options.now(),current=void 0,armRetry())})}return{open,healthy:()=>healthy,unhealthySince:()=>unhealthySince,stop:()=>{retry?.cancel(),retry=void 0,current=void 0}}}var INTERNAL_OBSERVER_HANDSHAKE_MS=5e3,SupervisorActivity=class{constructor(options){this.options=options,this.decider=new IdleExitDecider(options.idleExitMs,Date.now,startupHandOff()?.budgetMs),this.runs=new SessionRunActivity({settleHoldMs:options.idleExitMs,onSettleHoldExpired:(sessionId,heldMs)=>supervisorLog(`session ${sessionId} settled ${heldMs} ms ago and its agent_settled extension handlers have not finished; idle exit no longer waits for them`)}),this.clients=new ClientOccupancy(()=>this.refresh(),options.instanceId),this.observerLink=createObserverLink({open:()=>this.connectObserver(),settled:options.settled,retryDelayMs:250,now:Date.now,setTimer:(run,ms)=>{let timer=setTimeout(run,ms);return timer.unref?.(),{cancel:()=>clearTimeout(timer)}}})}current(){return{connections:this.clients.attachedCount,activeTurns:activeTurnsForIdleDecision({healthy:this.observerLink.healthy(),unhealthySince:this.observerLink.unhealthySince(),now:Date.now(),unknownGraceMs:this.decider.idleExitMs,observedBusy:this.runs.busySessions})}}refresh(){let current=this.current();return(current.connections>0||current.activeTurns>0||this.clients.unclassifiedCount>0)&&this.options.onActivity?.(),holdIdleExitForSettling(this.decider.update(current),this.runs)}quiescent(){return this.observerLink.healthy()&&this.runs.busySessions===0&&this.runs.settlingSessions===0&&this.clients.attachedCount===0&&this.clients.unclassifiedCount===0}openObserver(){return this.observerLink.open()}stopObserver(){this.observerLink.stop(),this.observerSocket?.destroy()}async connectObserver(){let secret=this.options.internalSecret,next=createConnection(resolveSocketTransportAddress(this.options.internalSocket,process.platform,secret));secret&&sendSocketHandshake(next,secret);let stream;try{this.options.internalKey?stream=await connectInternalConnection(next,this.options.internalKey,{timeoutMs:INTERNAL_OBSERVER_HANDSHAKE_MS}):(await waitForConnect(next,5e3),stream=next)}catch(cause){throw next.destroy(),cause}return this.observerSocket=stream,attachJsonlLineReader(stream,line=>this.observeHostEvent(line),{maxLineLength:MAX_RPC_LINE_CHARACTERS}),{onLost:handler=>{let lost=()=>{handler(),this.options.onActivity?.()};stream.once("close",lost),stream.once("error",lost)}}}observeHostEvent(line){this.runs.observe(line)&&this.refresh()}},OWNER_EXIT_GRACE_MS=2e3,OWNER_PROBE_MAX_INTERVAL_MS=5e3,SupervisorOwner=class{constructor(generationDir){this.watchFailed=!1,this.nextProbeAt=0,this.probeIntervalMs=1e3,this.gone=!1,this.revision=0,this.stopped=!1,this.idle=new IdleExitDecider(OWNER_EXIT_GRACE_MS,()=>performance.now()),this.generationDir=generationDir}async start(fd){if(await this.reload(),!(fd===void 0||this.owner==null))try{let pipe=new Socket({fd,readable:!0,writable:!1});this.pipe=pipe;let bound=this.owner,failed=!1,eof=()=>{!failed&&!this.stopped&&sameHostOwner(this.owner,bound)&&(this.gone=!0)};pipe.once("end",eof),process.platform==="win32"&&pipe.once("close",eof),pipe.once("error",()=>{failed=!0,this.pipe===pipe&&(this.pipe=void 0),pipe.destroy()}),pipe.resume()}catch{this.pipe=void 0}}async reload(){let revision=++this.revision,next=await readHostOwner(this.generationDir);if(!(this.stopped||revision!==this.revision)){if(sameHostOwner(this.owner,next)||(this.pipe?.destroy(),this.pipe=void 0,this.gone=!1,this.nextProbeAt=0,this.probeIntervalMs=1e3,this.activity()),this.owner=next,next==null)this.watcher?.close(),this.watcher=void 0;else if(!this.watcher&&!this.watchFailed)try{this.watcher=watch(this.generationDir,(_event,filename)=>{filename?.toString()==="owner.json"&&this.reload()}),this.watcher.once("error",()=>{this.watchFailed=!0,this.watcher?.close(),this.watcher=void 0})}catch{this.watchFailed=!0}}}activity(){this.idle.update({connections:1,activeTurns:0})}async shouldExit(activity){this.watcher||await this.reload();let owner=this.owner,revision=this.revision;if(owner!=null&&(!this.pipe||process.ppid!==owner.pid)&&!this.gone&&performance.now()>=this.nextProbeAt){let gone=await hostOwnerGone(owner);if(this.stopped||revision!==this.revision)return!1;this.gone=gone,this.nextProbeAt=performance.now()+this.probeIntervalMs,this.probeIntervalMs=Math.min(OWNER_PROBE_MAX_INTERVAL_MS,this.probeIntervalMs*2)}let quiet=this.gone&&owner!=null&&activity.quiescent();if(this.idle.update({connections:quiet?0:1,activeTurns:0})!=="exit")return!1;let current=await readHostOwner(this.generationDir);return this.stopped||revision!==this.revision?!1:sameHostOwner(owner,current)?activity.quiescent():(await this.reload(),!1)}stop(){this.stopped=!0,this.watcher?.close(),this.pipe?.destroy()}};function waitForConnect(socket,timeoutMs){return new Promise((resolve2,reject)=>{let timer=setTimeout(()=>{cleanup(),reject(new Error(`observer connection to internal host timed out after ${timeoutMs}ms`))},timeoutMs),onConnect=()=>{cleanup(),resolve2()},onError=cause=>{cleanup(),reject(cause)},cleanup=()=>{clearTimeout(timer),socket.off("connect",onConnect),socket.off("error",onError)};socket.once("connect",onConnect),socket.once("error",onError)})}import{readFile as readFile2}from"node:fs/promises";var SUPERSESSION_POLL_MS=1e3,ABSENT_CONFIRMATIONS=3,REPLACED_CONFIRMATIONS=3,IDENTITY_PROBE_TIMEOUT_MS=2e3;function watchForSupersession(endpoint,onLost){if(endpoint.identity===void 0)return endpoint.pointer===void 0?()=>{}:watchPointerSupersession(endpoint,endpoint.pointer,onLost);let absentPolls=0,lost=!1,lose=loss=>{lost||(lost=!0,stop(),onLost(loss))},timer=setInterval(()=>{endpoint.settled?.()!==!0&&classifyEndpointOwnership(endpoint.path,endpoint.identity).then(ownership=>{if(endpoint.settled?.()!==!0)switch(ownership){case"replaced":lose("replaced");return;case"absent":if(absentPolls+=1,absentPolls<ABSENT_CONFIRMATIONS)return;lose("absent");return;case"held":case"unknown":absentPolls=0;return}},ignore)},SUPERSESSION_POLL_MS);timer.unref?.();let stop=()=>clearInterval(timer);return stop}function watchPointerSupersession(endpoint,pointer,onLost){let probe=endpoint.probeInstanceId??probeAnsweringInstance,readPointer=endpoint.readPointerInstanceId??pointerInstanceId,agreeingPolls=0,observing=!1,lost=!1,observe=async()=>{let named=await readPointer(pointer.file);return named===void 0||named===pointer.instanceId?!1:await probe(endpoint.path)===named},timer=setInterval(()=>{lost||observing||endpoint.settled?.()===!0||(observing=!0,observe().then(replaced=>{lost||endpoint.settled?.()===!0||(agreeingPolls=replaced?agreeingPolls+1:0,!(agreeingPolls<REPLACED_CONFIRMATIONS)&&(lost=!0,clearInterval(timer),onLost("replaced")))},()=>{agreeingPolls=0}).finally(()=>{observing=!1}))},SUPERSESSION_POLL_MS);return timer.unref?.(),()=>clearInterval(timer)}async function pointerInstanceId(file){try{let parsed=JSON.parse(await readFile2(file,"utf8")),instanceId=typeof parsed=="object"&&parsed!==null?Reflect.get(parsed,"instance_id"):void 0;return typeof instanceId=="string"&&instanceId!==""?instanceId:void 0}catch{return}}async function probeAnsweringInstance(path){let{isRecord:isRecord2,requestOnSocket}=await import("./host-socket-request-QN4Q2P5E.js"),answer=await requestOnSocket(path,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},IDENTITY_PROBE_TIMEOUT_MS).catch(()=>{});return isRecord2(answer)&&typeof answer.instanceId=="string"?answer.instanceId:void 0}function ignore(){}var SupervisorDrain=class{constructor(child,shuttingDown,beginStopping=()=>{},relay){this.draining=!1,this.child=child,this.shuttingDown=shuttingDown,this.beginStopping=beginStopping,this.relay=relay}get active(){return this.draining}drain(){if(this.draining||this.shuttingDown())return;this.draining=!0,this.beginStopping(),supervisorLog("draining into the next generation");let graceMs=parseIdleExitMs(process.env[HANDOFF_GRACE_MS_ENV])??6e5;this.graceTimer=setTimeout(()=>{supervisorLog(JSON.stringify({event:"handoff_grace_expired",graceMs})),this.requestChildDrain()},graceMs),this.graceTimer.unref(),this.requestChildDrain()}stop(){this.graceTimer&&clearTimeout(this.graceTimer)}async acceptRequests(generation){let stop=watchDrainRequest(generation.drainRequestFile,request=>{supervisorLog(`drain requested (${request.reason})`),this.drain()});return await writeDrainWatch(generation.drainWatchFile,{pid:process.pid}).catch(cause=>{supervisorLog(`cannot advertise the drain request: ${errorMessage(cause)}`)}),stop}requestChildDrain(){let{child,relay}=this;if(!(child.pid===void 0||child.exitCode!==null||child.signalCode!==null)&&(relay&&writeDrainRequest(relay.file,{sender:relay.sender,reason:"supervisor_drain"}).catch(cause=>{supervisorLog(`could not relay the drain to the host: ${errorMessage(cause)}`)}),process.platform!=="win32"))try{process.kill(child.pid,"SIGUSR1")}catch(cause){supervisorLog(`could not ask the host to drain: ${errorMessage(cause)}`)}}};function drainOnPublicSocketLoss(path,identity,settled,drain,onReplaced,pointer){return watchForSupersession({path,identity,settled,...pointer&&{pointer}},loss=>{loss==="replaced"&&onReplaced(),supervisorLog(loss==="absent"?"the public socket entry is gone; nothing can reach this generation; draining":"another generation owns the public socket; draining this one"),drain.drain()})}var CHILD_IDENTITY_TICK_MS=500,CHILD_IDENTITY_READ_GAP_TICKS=10,CHILD_IDENTITY_READ_GAP_MAX_TICKS=120;function childLiveness(pid){try{return process.kill(pid,0),"alive"}catch(cause){return cause instanceof Error&&"code"in cause&&cause.code==="ESRCH"?"dead":"unknown"}}async function watchWin32ChildIdentity(child,shuttingDown,onGone){let pid=child.pid;if(pid===void 0)return()=>{};let readStartTime=()=>readProcessStartTime(pid,process.platform,1e3),baseline=await readStartTime().catch(()=>{}),adoptable=!0,suspect=!1,deadTicks=0,reading=!1,ended=!1,ticksUntilRead=0,readGapTicks=CHILD_IDENTITY_READ_GAP_TICKS,backOff=()=>{ticksUntilRead=readGapTicks,readGapTicks=Math.min(readGapTicks*2,CHILD_IDENTITY_READ_GAP_MAX_TICKS)},end=()=>{ended=!0,onGone()},settle=current=>{if(!ended){if(baseline===void 0){current!==void 0&&adoptable&&childLiveness(pid)==="alive"?baseline=current:backOff();return}if(current!==void 0&&current!==baseline)return end();current===baseline&&(suspect=!1),backOff()}},timer=setInterval(()=>{if(ended||shuttingDown()||child.exitCode!==null||child.signalCode!==null)return;ticksUntilRead>0&&ticksUntilRead--;let liveness=childLiveness(pid);if(liveness==="dead"){if(deadTicks++,deadTicks>=2)return end();suspect=!0,adoptable=!1;return}(deadTicks>0||liveness==="unknown")&&(suspect=!0,adoptable=!1),deadTicks=0,!(!(baseline===void 0?adoptable:suspect)||reading||ticksUntilRead>0)&&(reading=!0,readStartTime().then(settle,()=>{ended||backOff()}).finally(()=>{reading=!1}))},CHILD_IDENTITY_TICK_MS);return timer.unref?.(),()=>{ended=!0,clearInterval(timer)}}import{randomBytes as randomBytes2}from"node:crypto";import{readFile as readFile4}from"node:fs/promises";import{join as join3}from"node:path";import{readFileSync as readFileSync2}from"node:fs";function readProcessStartTicks(pid,platform=process.platform){if(platform==="linux")try{let stat2=readFileSync2(`/proc/${pid}/stat`,"utf8"),ticks=stat2.slice(stat2.lastIndexOf(")")+2).split(" ")[19];return ticks!==void 0&&/^\d+$/.test(ticks)?ticks:void 0}catch{return}}async function compareRecordedStart(pid,recorded,platform,probe){if(platform==="linux"){if(recorded.ticks===void 0)return"unknown";let observed2=probe.ticks(pid);return observed2===void 0?"unknown":observed2===recorded.ticks?"same":"changed"}if(recorded.time===void 0)return"unknown";let observed=await probe.time(pid),recordedMs=processStartTimeMs(recorded.time),observedMs=observed===void 0?void 0:processStartTimeMs(observed);return recordedMs===void 0||observedMs===void 0?"unknown":sameProcessStartMs(recordedMs,observedMs)?"same":"changed"}import{randomUUID}from"node:crypto";import{realpathSync as realpathSync2}from"node:fs";import{mkdir,readFile as readFile3,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{join}from"node:path";var INTERNAL_HOST_DIR_PREFIX="senpi-rpc-host-internal-",SHORT_TEMP_ROOT="/tmp";function internalHostDirRoots(){let primary=tmpdir();return canonicalPath(primary)!==canonicalPath(SHORT_TEMP_ROOT)?[primary,SHORT_TEMP_ROOT]:[Buffer.byteLength(primary)<Buffer.byteLength(SHORT_TEMP_ROOT)?primary:SHORT_TEMP_ROOT]}function canonicalPath(path){try{return realpathSync2(path)}catch{return path}}function internalHostDirRoot(name){for(let root of internalHostDirRoots())if(Buffer.byteLength(join(root,name,"host.sock"))<=MAX_SOCKET_PATH_BYTES)return root;let tried=internalHostDirRoots().map(root=>join(root,name,"host.sock"));throw new Error(`internal_socket_path_too_long: every candidate exceeds ${MAX_SOCKET_PATH_BYTES} bytes (${tried.join(", ")}); set TMPDIR to a shorter directory`)}async function createInternalSocketPath(baseDir=tmpdir(),platform=process.platform){if(platform==="win32"){let dir2=join(baseDir,`internal-${randomUUID()}`);return await mkdir(dir2,{recursive:!0,mode:448}),{socket:`\\\\.\\pipe\\senpi-rpc-internal-${randomUUID()}`,dir:dir2,secretPath:join(dir2,"secret")}}let name=`${INTERNAL_HOST_DIR_PREFIX}${randomUUID().slice(0,8)}`,dir=join(internalHostDirRoot(name),name);return await mkdir(dir,{recursive:!1,mode:448}),await writeFile(join(dir,".owner"),JSON.stringify({pid:process.pid,processStartTime:await readProcessStartTime(process.pid),createdAt:Date.now()}),{mode:384}),{socket:join(dir,"host.sock"),dir,secretPath:join(dir,".secret")}}var CHILD_START_TIME_WAIT_MS=1e4,CHILD_START_TIME_UNHURRIED_MS=15e3;async function readChildStartTime(pid,timeoutMs){let identity=await readProcessIdentity(pid,process.platform,timeoutMs,void 0,"UTC");if(identity.kind==="error")throw identity.error;return identity.kind==="present"?identity.identity:void 0}async function recordChildPid(file,pid,running){try{await writeJsonAtomic(file,{pid,processStartTime:null});let processStartTime=await waitForStartTime(pid,CHILD_START_TIME_WAIT_MS,p=>readChildStartTime(p,1e3)).catch(()=>{})??await readChildStartTime(pid,CHILD_START_TIME_UNHURRIED_MS).catch(()=>{});if(processStartTime===void 0){supervisorLog(`host child pid ${pid} start time unreadable at recording`);return}if(!running())return;await writeJsonAtomic(file,{pid,processStartTime})}catch(cause){supervisorLog(`could not record the host child pid: ${errorMessage(cause)}`)}}async function readSettingsFile(settingsFile){try{return JSON.parse(await readFile3(settingsFile,"utf8"))}catch{return}}import{execFileSync}from"node:child_process";import{closeSync as closeSync2,constants,fstatSync,openSync,rmSync}from"node:fs";import{join as join2}from"node:path";import{closeSync}from"node:fs";import{Socket as Socket2}from"node:net";function watchHostLifetime(fd,gone,unavailable){let stopped=!1,bun=Reflect.get(globalThis,"Bun");if(typeof bun=="object"&&bun!==null&&typeof Reflect.get(bun,"file")=="function"){let reader=Reflect.get(bun,"file")(fd).stream().getReader();return(async()=>{try{for(;!stopped;){let{done}=await reader.read();if(done){stopped||gone();return}}}catch{stopped||unavailable()}})(),()=>{stopped||(stopped=!0,reader.cancel().catch(()=>{}).finally(()=>closeSync(fd)))}}let socket=new Socket2({fd,readable:!0,writable:!1});return socket.once("end",()=>{stopped||gone()}),socket.once("error",()=>{stopped||unavailable()}),socket.unref(),socket.resume(),()=>{stopped=!0,socket.destroy()}}var HOST_WATCH_LIFETIME_FIFO_ENV="SENPI_RPC_HOST_LIFETIME_FIFO";function prepareLifetimeBinding(hopDir,platform=process.platform){if(platform!=="linux")return{};let path=join2(hopDir,"lifetime.fifo");try{return rmSync(path,{force:!0}),execFileSync("mkfifo",["-m","600",path],{stdio:"ignore"}),openSync(path,constants.O_RDWR),{lifetimeFifo:path}}catch{return{}}}function armLifetimeBinding(binding,gone,unavailable,platform=process.platform){if(platform==="win32")return;let fifo=platform==="linux"?openFifoReadEnd(binding.lifetimeFifo):void 0;if(fifo!==void 0)return binding.lifetimeFd!==void 0&&closeSync2(binding.lifetimeFd),watchHostLifetime(fifo,()=>gone("supervisor lifetime FIFO closed"),unavailable);if(binding.lifetimeFd!==void 0)return watchHostLifetime(binding.lifetimeFd,()=>gone("supervisor stdin lifetime closed"),unavailable)}function openFifoReadEnd(path){if(path===void 0)return;let fd;try{fd=openSync(path,constants.O_RDONLY|constants.O_NONBLOCK|constants.O_NOFOLLOW)}catch{return}let stat2=fstatSync(fd),owned=typeof process.getuid!="function"||stat2.uid===process.getuid();if(stat2.isFIFO()&&owned&&(stat2.mode&511)===384)return fd;closeSync2(fd)}async function recordedOwnerStartTime(dir){if(dir!==void 0)try{let owner=JSON.parse(await readFile4(join3(dir,".owner"),"utf8")),start=owner!==null&&typeof owner=="object"?Reflect.get(owner,"processStartTime"):void 0;return typeof start=="string"?start:void 0}catch{return}}async function prepareInternalHop(daemonDir){let created=await createInternalSocketPath(daemonDir),internal={...created,secretPath:created.secretPath??socketSecretPath(created.socket)},internalSecret=process.platform==="win32"?await createSocketSecret(internal.secretPath):void 0,internalKey=process.platform==="win32"?void 0:randomBytes2(32);return{internal,internalSocket:internal.socket,internalSecret,internalKey,...internalKey&&internal.dir!==void 0?prepareLifetimeBinding(internal.dir):{},supervisorStart:internalKey?{time:await recordedOwnerStartTime(internal.dir),ticks:readProcessStartTicks(process.pid)}:void 0,transport:{...internalSecret?{internalSecret}:{},...internalKey?{internalKey}:{}}}}import childProcess from"node:child_process";import{Socket as Socket4}from"node:net";import{extname}from"node:path";import{read}from"node:fs";import{readFile as readFile6}from"node:fs/promises";import{join as join5}from"node:path";import{Readable}from"node:stream";import{randomUUID as randomUUID2}from"node:crypto";import{mkdir as mkdir2,readFile as readFile5,rename,rm,writeFile as writeFile2}from"node:fs/promises";import{dirname as dirname2}from"node:path";var ENDPOINT_FENCE_WAIT_MS=15e3;function endpointOwnerToken(endpoint,instanceId,generation){return{v:1,endpoint,instanceId,generation,pid:process.pid,nonce:randomUUID2()}}var ownerFile=socket=>`${hostEnsureLockTarget(socket)}.owner.json`;async function withEndpointFence(socket,run,hooks){let fence=`${hostEnsureLockTarget(socket)}.fence.lock`;await mkdir2(dirname2(fence),{recursive:!0});let release;try{release=await acquireOwnershipSafeLock(fence,{retries:{retries:0,minTimeout:1,maxTimeout:1}})}catch(cause){if(!isBusy(cause))throw cause;hooks?.onFenceBusy?.(),release=await acquireOwnershipSafeLock(fence,hostEnsureLockOptions(ENDPOINT_FENCE_WAIT_MS))}try{return await run()}finally{await release()}}async function readEndpointOwner(socket){let parsed;try{parsed=JSON.parse(await readFile5(ownerFile(socket),"utf8"))}catch{return}if(typeof parsed!="object"||parsed===null)return;let token=parsed;return token.v===1&&typeof token.instanceId=="string"&&typeof token.nonce=="string"?parsed:void 0}async function writeEndpointOwner(socket,token){let path=ownerFile(socket),staged=`${path}.${process.pid}.tmp`;await writeFile2(staged,`${JSON.stringify(token)}
5
5
  `,{mode:384}),await rename(staged,path)}async function claimEndpoint(socket,token,bind){let claim=async()=>{await bind?.(),await writeEndpointOwner(socket,token)};if(await readEndpointOwner(socket)){await withEndpointFence(socket,claim);return}await mkdir2(dirname2(ownerFile(socket)),{recursive:!0}),await claim()}async function adoptEndpoint(options){let{publicSocket}=options;await withEndpointFence(publicSocket,async()=>{if(options.granted&&!await options.granted())throw new Error(`${publicSocket}: the launcher revoked this generation's adoption grant`);let current=await readEndpointOwner(publicSocket);if(options.expectedOwner!==void 0&&current&&current.instanceId!==options.expectedOwner)throw new Error(`${publicSocket}: owner token names ${current.instanceId}, not ${options.expectedOwner}; refusing to replace it`);await adoptPublicSocket(options.bindSocket,publicSocket,options.expected),await writeEndpointOwner(publicSocket,options.token)},options.hooks)}async function unlinkOwnedEndpoint(socket,identity,instanceId,log,hooks){await withEndpointFence(socket,async()=>{let current=await readEndpointOwner(socket);if(current&&current.instanceId!==instanceId){log(`socket path ${socket} is owned by generation ${current.instanceId} now; leaving it`);return}await hooks?.afterValidate?.(),await unlinkOwnedSocket(socket,identity,log),current&&await rm(ownerFile(socket),{force:!0})})}async function closeShieldedEndpoint(socket,close){await withEndpointFence(socket,()=>shieldSocketDuringClose(socket,close))}async function settleCandidateAdoption(socket,candidate,revoke){return withEndpointFence(socket,async()=>(await revoke(),(await readEndpointOwner(socket))?.instanceId===candidate?"completed":"not_adopted"))}import{lstat as lstat2,mkdir as mkdir4,unlink}from"node:fs/promises";import{createConnection as createConnection2,createServer}from"node:net";import{dirname as dirname3}from"node:path";import{StringDecoder}from"node:string_decoder";function proxyWithAdmission(client,internal,admission,auth,launchProven=!1){let reply=chunk=>write(client,auth?auth.response(chunk.toString()):chunk),pending=[],refused=new Set,protocols=0,refusals=Promise.resolve(),unsubscribe=admission.onStop(()=>(refusals=refusePending(),refusals));async function refusePending(){let ids=pending.splice(0);for(let id of ids)refused.add(id);try{for(let id of ids)await reply(serializeJsonLine(hostStoppingResponse(id,"open_session",admission)))}catch{fail()}}client.once("close",()=>{unsubscribe(),internal?.destroy()});let fail=()=>{internal?.destroy(),client.destroy()};client.once("error",fail),internal?.once("error",()=>{admission.stopping||fail()}),requests().catch(()=>{admission.stopping||fail()}),internal&&responses(internal).catch(()=>{admission.stopping||fail()});async function requests(){internal&&launchProven&&internal.write(`${JSON.stringify({type:RPC_LAUNCH_PROOF_RECORD})}
6
6
  `);for await(let line of lines(auth?.input??client,MAX_RPC_LINE_CHARACTERS)){if(line===void 0){await reply(serializeJsonLine({type:"response",command:"parse",success:!1,error:`RPC input line exceeds ${MAX_RPC_LINE_CHARACTERS} characters.`}));continue}let request=record(line);if(!auth&&request?.type===RPC_LAUNCH_PROOF_RECORD){await reply(serializeJsonLine(launchProofRecordRefusal(request.id)));continue}admission.stopping&&request?.type==="get_protocol_info"?await reply(serializeJsonLine({id:request.id,type:"response",command:request.type,success:!0,data:admission.protocol()})):admission.stopping&&(request?.type==="open_session"||!internal)?await reply(serializeJsonLine(hostStoppingResponse(request?.id,String(request?.type??"parse"),admission))):internal&&(request?.type==="open_session"&&pending.push(request.id),request?.type==="get_protocol_info"&&protocols++,await write(internal,`${line}
7
7
  `))}internal?.end()}async function responses(source){let fragments=[];for await(let chunk of source){let newline=chunk.lastIndexOf(10);if(newline===-1){fragments.push(chunk);continue}let complete=chunk.subarray(0,newline+1);if(!auth&&pending.length===0&&protocols===0&&refused.size===0){client.cork();let written;try{for(let fragment of fragments)client.write(fragment);written=write(client,complete)}finally{client.uncork()}await written}else{let batch=fragments.length>0?Buffer.concat([...fragments,complete]):complete;await reply(filterReplies(batch))}fragments=newline+1<chunk.length?[chunk.subarray(newline+1)]:[]}fragments.length>0&&await reply(filterReplies(Buffer.concat(fragments))),await refusals,client.end(()=>client.destroy())}function filterReplies(batch){if(pending.length===0&&protocols===0&&refused.size===0)return batch;let output=[],changed=!1;for(let start=0;start<batch.length;){let newline=batch.indexOf(10,start),end=newline===-1?batch.length:newline+1,line=batch.subarray(start,end);start=end;let response=line.includes('"open_session"')||line.includes('"get_protocol_info"')?record(line.toString("utf8")):void 0;if(response?.type==="response"&&response.command==="open_session"){if(refused.has(response.id)){changed=!0;continue}let index=pending.indexOf(response.id);index!==-1&&pending.splice(index,1)}if(response?.type==="response"&&response.command==="get_protocol_info"&&(protocols=Math.max(0,protocols-1),response.success===!0)){isRecord(response.data)&&admission.observe(response.data),output.push(Buffer.from(serializeJsonLine({...response,data:admission.protocol()}))),changed=!0;continue}output.push(line)}return changed?Buffer.concat(output):batch}}async function write(socket,line){await new Promise((resolve2,reject)=>{socket.write(line,error=>error?reject(error):resolve2())})}async function*lines(socket,limit){let decoder=new StringDecoder("utf8"),buffer="",discarding=!1;for await(let chunk of socket){let text=typeof chunk=="string"?chunk:decoder.write(chunk),offset=0;for(;offset<text.length;){let newline=text.indexOf(`
@@ -1,4 +1,4 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{connectAuthenticatedRpcSocket,socketNeedsHandshake}from"./chunk-2CNSCMYC.js";import{RpcEndpointAuthError}from"./chunk-DBQBJTMF.js";import{readSocketSecret,resolveSocketTransportAddress,sendSocketHandshake,socketSecretPath}from"./chunk-HW6AAS3R.js";import{createConnection}from"node:net";var PROBE_REQUEST_ID="ensure-host-probe";async function requestOnSocket(socketPath,command,timeoutMs,options={}){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,...command},timeoutMs,!1,options)).answer}async function connectAndAsk(socketPath,request,timeoutMs,keep=!1,options={}){let secret;if(socketNeedsHandshake(socketPath))try{secret=await readSocketSecret(socketSecretPath(socketPath))}catch{return{connected:!1,answer:void 0}}let authenticated,deadline=Date.now()+timeoutMs;if(!socketNeedsHandshake(socketPath)){try{authenticated=await connectAuthenticatedRpcSocket(socketPath,request.type==="get_protocol_info"?request:void 0,options,timeoutMs)}catch(cause){if(cause instanceof RpcEndpointAuthError)throw cause;return{connected:cause instanceof Error&&"rpcSocketConnected"in cause&&cause.rpcSocketConnected===!0,answer:void 0}}if(request.type==="get_protocol_info"){let answer=authenticated.protocol.data??{};return keep?{connected:!0,answer,kept:authenticated.socket}:(authenticated.socket.destroy(),{connected:!0,answer})}}return new Promise((resolveProbe,rejectProbe)=>{let socket=authenticated?.socket??createConnection(resolveSocketTransportAddress(socketPath,process.platform,secret)),buffer="",settled=!1,connected=authenticated!==void 0,finish=value=>{if(!settled){if(settled=!0,clearTimeout(timeout),socket.removeAllListeners("data"),keep&&value!==void 0&&!socket.destroyed){resolveProbe({connected,answer:value,kept:socket});return}socket.destroy(),resolveProbe({connected,answer:value})}},timeout=setTimeout(()=>finish(),Math.max(0,deadline-Date.now())),send=()=>{connected=!0,socket.write(`${JSON.stringify(request)}
2
+ import{connectAuthenticatedRpcSocket,socketNeedsHandshake}from"./chunk-E5O4SP5I.js";import{RpcEndpointAuthError}from"./chunk-VUY4BZDI.js";import{readSocketSecret,resolveSocketTransportAddress,sendSocketHandshake,socketSecretPath}from"./chunk-HW6AAS3R.js";import{createConnection}from"node:net";var PROBE_REQUEST_ID="ensure-host-probe";async function requestOnSocket(socketPath,command,timeoutMs,options={}){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,...command},timeoutMs,!1,options)).answer}async function connectAndAsk(socketPath,request,timeoutMs,keep=!1,options={}){let secret;if(socketNeedsHandshake(socketPath))try{secret=await readSocketSecret(socketSecretPath(socketPath))}catch{return{connected:!1,answer:void 0}}let authenticated,deadline=Date.now()+timeoutMs;if(!socketNeedsHandshake(socketPath)){try{authenticated=await connectAuthenticatedRpcSocket(socketPath,request.type==="get_protocol_info"?request:void 0,options,timeoutMs)}catch(cause){if(cause instanceof RpcEndpointAuthError)throw cause;return{connected:cause instanceof Error&&"rpcSocketConnected"in cause&&cause.rpcSocketConnected===!0,answer:void 0}}if(request.type==="get_protocol_info"){let answer=authenticated.protocol.data??{};return keep?{connected:!0,answer,kept:authenticated.socket}:(authenticated.socket.destroy(),{connected:!0,answer})}}return new Promise((resolveProbe,rejectProbe)=>{let socket=authenticated?.socket??createConnection(resolveSocketTransportAddress(socketPath,process.platform,secret)),buffer="",settled=!1,connected=authenticated!==void 0,finish=value=>{if(!settled){if(settled=!0,clearTimeout(timeout),socket.removeAllListeners("data"),keep&&value!==void 0&&!socket.destroyed){resolveProbe({connected,answer:value,kept:socket});return}socket.destroy(),resolveProbe({connected,answer:value})}},timeout=setTimeout(()=>finish(),Math.max(0,deadline-Date.now())),send=()=>{connected=!0,socket.write(`${JSON.stringify(request)}
3
3
  `)};socket.on("data",chunk=>{for(buffer+=chunk.toString("utf8");;){let newline=buffer.indexOf(`
4
4
  `);if(newline===-1)return;let line=buffer.slice(0,newline);buffer=buffer.slice(newline+1);let value;try{value=JSON.parse(line)}catch{continue}if(isRecord(value)&&value.id===request.id&&(value.errorCode==="auth_required"||value.errorCode==="auth_failed")){clearTimeout(timeout),settled=!0,socket.destroy(),rejectProbe(new RpcEndpointAuthError(value.errorCode,`${socketPath}; set SENPI_RPC_KEY_ROOT to the host's agent dir`));return}let answer=readAnswer(line,typeof request.id=="string"?request.id:PROBE_REQUEST_ID);if(answer!==void 0)return finish(answer)}}),socket.once("error",()=>finish()),socket.once("close",()=>finish()),secret&&sendSocketHandshake(socket,secret),authenticated?send():socket.once("connect",send)})}function readAnswer(text,id=PROBE_REQUEST_ID){let parsed;try{parsed=JSON.parse(text)}catch{return}if(!(!isRecord(parsed)||parsed.id!==id||parsed.success!==!0))return parsed.data??{}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}export{PROBE_REQUEST_ID,requestOnSocket,connectAndAsk,readAnswer,isRecord};