@code-yeongyu/senpi 2026.10.10-10 → 2026.10.10-12

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 (187) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/dist/bundle/chunks/{anthropic-messages-2B35OVB7.js → anthropic-messages-I4Z6VKS3.js} +1 -1
  3. package/dist/bundle/chunks/{app-server-command-CV6N7JDD.js → app-server-command-EGTBOL5W.js} +2 -2
  4. package/dist/bundle/chunks/bun-extension-importer-QSQHKXVG.js +20 -0
  5. package/dist/bundle/chunks/{chunk-4WZF7G6N.js → chunk-2AYAOU6W.js} +12 -10
  6. package/dist/bundle/chunks/chunk-2ZGQRUGM.js +2506 -0
  7. package/dist/bundle/chunks/{chunk-ZPJHS64R.js → chunk-5BRVRFJI.js} +1 -1
  8. package/dist/bundle/chunks/chunk-6SBY4ZWC.js +2 -0
  9. package/dist/bundle/chunks/chunk-DRVT7RIO.js +2 -0
  10. package/dist/bundle/chunks/chunk-E75RO54O.js +14 -0
  11. package/dist/bundle/chunks/{chunk-ZCYTYHDN.js → chunk-IAYFQEXI.js} +1 -1
  12. package/dist/bundle/chunks/chunk-M4C6Z7UT.js +288 -0
  13. package/dist/bundle/chunks/chunk-N6HU6BEY.js +9 -0
  14. package/dist/bundle/chunks/chunk-NEFNNQSV.js +9 -0
  15. package/dist/bundle/chunks/{chunk-YI7SPFDN.js → chunk-Q3R44CGT.js} +2 -2
  16. package/dist/bundle/chunks/chunk-QKU6JOA4.js +2 -0
  17. package/dist/bundle/chunks/{chunk-JRGNL6WM.js → chunk-QXREUA5F.js} +1 -1
  18. package/dist/bundle/chunks/chunk-SIIACSBE.js +30 -0
  19. package/dist/bundle/chunks/{chunk-QQZREV6B.js → chunk-SSH4CLHJ.js} +1 -1
  20. package/dist/bundle/chunks/chunk-TOZBUPZP.js +3 -0
  21. package/dist/bundle/chunks/chunk-WASCMT6Y.js +2 -0
  22. package/dist/bundle/chunks/chunk-YU4AYH4C.js +2 -0
  23. package/dist/bundle/chunks/chunk-ZGCPUGLT.js +6 -0
  24. package/dist/bundle/chunks/{chunk-NTH33AXY.js → chunk-ZJOYLQXK.js} +1 -1
  25. package/dist/bundle/chunks/chunk-ZRWOLP4E.js +2 -0
  26. package/dist/bundle/chunks/cli-main-PANLBILV.js +3 -0
  27. package/dist/bundle/chunks/{help-fast-path-5P73752B.js → help-fast-path-IQAJFO2G.js} +1 -1
  28. package/dist/bundle/chunks/{host-command-MWQNTWFA.js → host-command-MWSVX37K.js} +1 -1
  29. package/dist/bundle/chunks/host-lifecycle-X2J5FTJL.js +3 -0
  30. package/dist/bundle/chunks/host-lifecycle.js +8 -8
  31. package/dist/bundle/chunks/interactive-mode-TQJU6K27.js +2 -0
  32. package/dist/bundle/chunks/multi-session-host-GBSMDUMG.js +26 -0
  33. package/dist/bundle/chunks/{package-manager-cli-PXP63ZPT.js → package-manager-cli-IBPABDGR.js} +1 -1
  34. package/dist/bundle/chunks/rotation-stream-JXT3JYW5.js +2 -0
  35. package/dist/bundle/chunks/rpc-mode-PFIAS2E5.js +2 -0
  36. package/dist/bundle/chunks/runtime-session-I4NDNGC5.js +2 -0
  37. package/dist/bundle/chunks/{schedule-command-MGZLHARF.js → schedule-command-Q4W37FAP.js} +1 -1
  38. package/dist/bundle/chunks/session-control-endpoint-YYFCJZXZ.js +3 -0
  39. package/dist/bundle/chunks/session-picker-YLDBGXTR.js +2 -0
  40. package/dist/bundle/chunks/session-worker.js +455 -448
  41. package/dist/bundle/cli.js +1 -1
  42. package/dist/bundle/index.js +1 -1
  43. package/dist/bundle/rpc-entry.js +1 -1
  44. package/dist/bundle/runtime-manifest.json +1 -1
  45. package/dist/cli/session-opening.d.ts +5 -0
  46. package/dist/cli/session-opening.js +11 -0
  47. package/dist/core/agent-session.d.ts +5 -0
  48. package/dist/core/agent-session.js +56 -33
  49. package/dist/core/engine-paused.d.ts +6 -0
  50. package/dist/core/engine-paused.js +50 -0
  51. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +9 -2
  52. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +22 -45
  53. package/dist/core/extensions/builtin/compaction/index.js +55 -9
  54. package/dist/core/extensions/builtin/compaction/rejected-recovery.d.ts +11 -0
  55. package/dist/core/extensions/builtin/compaction/rejected-recovery.js +73 -0
  56. package/dist/core/extensions/builtin/compaction/retained-message-projection.d.ts +10 -0
  57. package/dist/core/extensions/builtin/compaction/retained-message-projection.js +102 -0
  58. package/dist/core/extensions/builtin/goal/continuation.js +2 -0
  59. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +3 -1
  60. package/dist/core/extensions/builtin/goal/elapsed-ticker.js +2 -0
  61. package/dist/core/extensions/builtin/goal/format.d.ts +1 -1
  62. package/dist/core/extensions/builtin/goal/format.js +19 -4
  63. package/dist/core/extensions/builtin/goal/index.js +16 -9
  64. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +1 -0
  65. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +57 -13
  66. package/dist/core/extensions/builtin/goal/monitor-continuation.js +2 -1
  67. package/dist/core/extensions/builtin/goal/persistence.js +2 -0
  68. package/dist/core/extensions/builtin/goal/renderers.js +9 -4
  69. package/dist/core/extensions/builtin/goal/store.d.ts +5 -0
  70. package/dist/core/extensions/builtin/goal/store.js +44 -0
  71. package/dist/core/extensions/builtin/goal/types.d.ts +10 -0
  72. package/dist/core/extensions/builtin/goal/types.js +4 -0
  73. package/dist/core/extensions/builtin/goal/ui.js +6 -3
  74. package/dist/core/extensions/builtin/mcp/index.js +4 -2
  75. package/dist/core/extensions/builtin/mcp/service-connection.js +1 -0
  76. package/dist/core/extensions/builtin/mcp/service-types.d.ts +2 -0
  77. package/dist/core/extensions/builtin/mcp/service.js +257 -74
  78. package/dist/core/extensions/builtin/terminal/process-identity.d.ts +1 -3
  79. package/dist/core/extensions/builtin/terminal/process-identity.js +1 -7
  80. package/dist/core/extensions/builtin/terminal/process-start-probe.js +11 -7
  81. package/dist/core/extensions/builtin/ttsr/index.js +19 -0
  82. package/dist/core/extensions/bun-extension-importer.d.ts +1 -1
  83. package/dist/core/extensions/bun-extension-importer.js +7 -3
  84. package/dist/core/extensions/extension-module-cache.d.ts +4 -3
  85. package/dist/core/extensions/extension-module-cache.js +8 -22
  86. package/dist/core/foreign-session-holders.d.ts +7 -0
  87. package/dist/core/foreign-session-holders.js +63 -0
  88. package/dist/core/moved-session-cwd.d.ts +7 -0
  89. package/dist/core/moved-session-cwd.js +23 -0
  90. package/dist/core/moved-sessions.d.ts +6 -0
  91. package/dist/core/moved-sessions.js +83 -24
  92. package/dist/core/resource-loader.js +5 -6
  93. package/dist/core/resume-target.js +3 -1
  94. package/dist/core/session-holders.d.ts +2 -1
  95. package/dist/core/session-holders.js +4 -4
  96. package/dist/core/session-manager.js +29 -10
  97. package/dist/core/webview/webview-readiness.d.ts +2 -0
  98. package/dist/core/webview/webview-readiness.js +9 -0
  99. package/dist/core/webview/webview-service.d.ts +4 -0
  100. package/dist/core/webview/webview-service.js +30 -5
  101. package/dist/main.js +14 -3
  102. package/dist/modes/app-server/daemon/process.d.ts +7 -1
  103. package/dist/modes/app-server/daemon/process.js +58 -6
  104. package/dist/modes/app-server/threads/goal-wire.js +2 -1
  105. package/dist/modes/interactive/interactive-mode.js +7 -0
  106. package/dist/modes/rpc/connection-handler.js +3 -2
  107. package/dist/modes/rpc/custom-capability.d.ts +2 -0
  108. package/dist/modes/rpc/custom-capability.js +2 -0
  109. package/dist/modes/rpc/host-capabilities.js +3 -1
  110. package/dist/modes/rpc/host-client-occupancy.d.ts +2 -1
  111. package/dist/modes/rpc/host-client-occupancy.js +3 -0
  112. package/dist/modes/rpc/host-daemon-registration.js +20 -6
  113. package/dist/modes/rpc/host-daemon-state.d.ts +17 -0
  114. package/dist/modes/rpc/host-daemon-state.js +60 -0
  115. package/dist/modes/rpc/host-ensure-start.js +13 -3
  116. package/dist/modes/rpc/host-ensure-stop.d.ts +1 -1
  117. package/dist/modes/rpc/host-ensure-stop.js +17 -4
  118. package/dist/modes/rpc/host-ensure-types.d.ts +2 -0
  119. package/dist/modes/rpc/host-ensure.js +20 -2
  120. package/dist/modes/rpc/host-gc-evidence.js +3 -0
  121. package/dist/modes/rpc/host-generations.js +4 -1
  122. package/dist/modes/rpc/host-legacy.d.ts +1 -1
  123. package/dist/modes/rpc/host-legacy.js +11 -2
  124. package/dist/modes/rpc/host-lifecycle-activity.d.ts +30 -0
  125. package/dist/modes/rpc/host-lifecycle-activity.js +136 -4
  126. package/dist/modes/rpc/host-lifecycle-launch.d.ts +4 -0
  127. package/dist/modes/rpc/host-lifecycle-launch.js +24 -1
  128. package/dist/modes/rpc/host-lifecycle-proxy.d.ts +2 -0
  129. package/dist/modes/rpc/host-lifecycle-proxy.js +4 -1
  130. package/dist/modes/rpc/host-lifecycle-scratch.js +5 -2
  131. package/dist/modes/rpc/host-lifecycle-shutdown.d.ts +1 -1
  132. package/dist/modes/rpc/host-lifecycle-shutdown.js +81 -37
  133. package/dist/modes/rpc/host-lifecycle.js +23 -1
  134. package/dist/modes/rpc/host-reservations.d.ts +2 -0
  135. package/dist/modes/rpc/host-reservations.js +61 -3
  136. package/dist/modes/rpc/host-stalled-evidence.js +17 -3
  137. package/dist/modes/rpc/host-stop-intent.d.ts +3 -0
  138. package/dist/modes/rpc/host-stop-intent.js +3 -0
  139. package/dist/modes/rpc/host-stop.js +4 -9
  140. package/dist/modes/rpc/host-successor.js +10 -3
  141. package/dist/modes/rpc/host-supervisor-log.d.ts +1 -0
  142. package/dist/modes/rpc/host-supervisor-log.js +9 -0
  143. package/dist/modes/rpc/multi-session-host.js +8 -6
  144. package/dist/modes/rpc/rpc-mode.d.ts +3 -1
  145. package/dist/modes/rpc/rpc-mode.js +3 -1
  146. package/dist/modes/rpc/rpc-types.d.ts +3 -1
  147. package/dist/modes/rpc/rpc-types.js +2 -0
  148. package/dist/modes/rpc/session-command-router.d.ts +1 -1
  149. package/dist/modes/rpc/session-command-router.js +18 -14
  150. package/dist/modes/rpc/session-held.d.ts +8 -0
  151. package/dist/modes/rpc/session-held.js +127 -0
  152. package/dist/modes/rpc/session-registry-types.d.ts +1 -1
  153. package/dist/modes/rpc/session-registry.d.ts +2 -0
  154. package/dist/modes/rpc/session-registry.js +4 -0
  155. package/dist/modes/rpc/session-worker-client.d.ts +3 -3
  156. package/dist/modes/rpc/session-worker-client.js +24 -12
  157. package/dist/modes/rpc/worker-session-claims.d.ts +15 -0
  158. package/dist/modes/rpc/worker-session-claims.js +61 -0
  159. package/dist/modes/rpc/worker-session-registry.d.ts +4 -0
  160. package/dist/modes/rpc/worker-session-registry.js +51 -8
  161. package/dist/utils/shell.d.ts +6 -2
  162. package/dist/utils/shell.js +20 -6
  163. package/docs/app-server.md +1 -1
  164. package/docs/rpc.md +75 -2
  165. package/docs/session-format.md +19 -0
  166. package/package.json +6 -6
  167. package/dist/bundle/chunks/bun-extension-importer-3TEDTSKJ.js +0 -20
  168. package/dist/bundle/chunks/chunk-5AKP2VFB.js +0 -16
  169. package/dist/bundle/chunks/chunk-6Y7VGPJB.js +0 -9
  170. package/dist/bundle/chunks/chunk-CIRZTP7W.js +0 -2
  171. package/dist/bundle/chunks/chunk-HKRW6HT5.js +0 -30
  172. package/dist/bundle/chunks/chunk-JEZWV7JW.js +0 -17
  173. package/dist/bundle/chunks/chunk-LR5EN45D.js +0 -7
  174. package/dist/bundle/chunks/chunk-MYVBK47X.js +0 -2
  175. package/dist/bundle/chunks/chunk-O6YOQUVX.js +0 -2773
  176. package/dist/bundle/chunks/chunk-TJPMB4VH.js +0 -2
  177. package/dist/bundle/chunks/chunk-U5KVIAHJ.js +0 -2
  178. package/dist/bundle/chunks/chunk-XMHO4QQN.js +0 -7
  179. package/dist/bundle/chunks/cli-main-TM4UFZVC.js +0 -3
  180. package/dist/bundle/chunks/host-lifecycle-B24G65GD.js +0 -3
  181. package/dist/bundle/chunks/interactive-mode-CBQW7WRK.js +0 -2
  182. package/dist/bundle/chunks/multi-session-host-4KXWGRNS.js +0 -25
  183. package/dist/bundle/chunks/rotation-stream-FQH63DMY.js +0 -2
  184. package/dist/bundle/chunks/rpc-mode-7WHJHMUP.js +0 -2
  185. package/dist/bundle/chunks/runtime-session-CWJNFRHY.js +0 -2
  186. package/dist/bundle/chunks/session-control-endpoint-OH7XV2FN.js +0 -3
  187. package/dist/bundle/chunks/session-picker-UUSW6YSU.js +0 -2
@@ -0,0 +1,9 @@
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{HOST_INSTANCE_ID_ENV}from"./chunk-Q3R44CGT.js";import{ProcessIdentityUnreadableError,parseDaemonPidFile,processIsLive,processMatchesPidFile,processStartTimeMs,readProcessIdentity,readProcessStartTime,sameProcessStartMs}from"./chunk-ZRWOLP4E.js";import{getAgentDir}from"./chunk-463OK2Y4.js";import{existsSync,realpathSync}from"node:fs";import{basename,dirname,join,resolve}from"node:path";function canonicalSessionPath(path){let absolutePath=resolve(path),missing=[],existing=absolutePath;for(;!existsSync(existing);){let parent=dirname(existing);if(parent===existing)return absolutePath;missing.unshift(basename(existing)),existing=parent}try{return join(realpathSync(existing),...missing)}catch{return absolutePath}}function sessionDirectoryRemoved(sessionFile){return!existsSync(dirname(sessionFile))}import{createHash}from"node:crypto";import{basename as basename2,dirname as dirname2,join as join2,win32}from"node:path";function canonicalEndpointPath(socket,platform=process.platform){return platform==="win32"?win32.normalize(socket).toLowerCase():socket.startsWith("\0")?socket:join2(canonicalSessionPath(dirname2(socket)),basename2(socket))}function daemonDirectoryName(socket,platform=process.platform){return directoryNameOf(canonicalEndpointPath(socket,platform))}function sameEndpoint(socket,other){return socket===other||canonicalEndpointPath(socket)===canonicalEndpointPath(other)}function socketNamesDirectory(socket,name){return daemonDirectoryName(socket)===name||process.platform!=="win32"&&directoryNameOf(socket)===name}function directoryNameOf(endpoint){return createHash("sha256").update(endpoint,"utf8").digest("hex").slice(0,16)}function shardKey(kind,ownerId){return createHash("sha256").update(`${kind}:${ownerId}`,"utf8").digest("hex").slice(0,16)}function shardSocketPathForKey(root,kind,key){return join2(root,`${kind}-${key}.sock`)}function shardSocketPath(root,kind,ownerId){return shardSocketPathForKey(root,kind,shardKey(kind,ownerId))}var SHARD_SOCKET_NAME=/^(p|i)-([0-9a-f]{16})\.sock$/;function parseShardSocket(socket){let match=SHARD_SOCKET_NAME.exec(basename2(socket)),key=match?.[2];return key===void 0?null:{kind:match?.[1]==="i"?"i":"p",key}}import{chmod,mkdir}from"node:fs/promises";import{join as join3}from"node:path";var DIRECTORY_MODE=448;function generationPaths(paths,instanceId){let dir=join3(paths.generationsDir,instanceId);return{dir,relativeDir:`generations/${instanceId}`,pidFile:join3(dir,"host.pid"),settingsFile:join3(dir,"settings.json"),scratchDir:join3(dir,"scratch"),childPidFile:join3(dir,"host-child.pid"),stopIntentFile:join3(dir,"stop-intent.json"),stalledFile:join3(dir,"host-stalled.json"),aliveFile:join3(dir,"host-alive.json"),stopProgressFile:join3(dir,"stop-progress.json")}}var HostDaemonStateError=class extends Error{constructor(path,cause){super(`RPC daemon state directory ${path} is not usable: ${cause instanceof Error?cause.message:cause}`,{cause}),this.name="HostDaemonStateError",this.path=path}};async function createGenerationDirectory(generation){try{await mkdir(generation.scratchDir,{recursive:!0,mode:DIRECTORY_MODE}),await chmod(generation.dir,DIRECTORY_MODE)}catch(cause){throw new HostDaemonStateError(generation.dir,cause)}}import{randomUUID}from"node:crypto";import{chmod as chmod2,link,mkdir as mkdir2,readFile,rename,rm,writeFile}from"node:fs/promises";import{basename as basename3,join as join4}from"node:path";var HOST_DAEMON_LAYOUT=2,HOST_DAEMON_DIR_ENV="SENPI_RPC_HOST_DAEMON_DIR",ENDPOINT_REGISTRY_VERSION=1,DIRECTORY_MODE2=448,HOST_STATE_FILE_MODE=384;function createHostDaemonPaths(target){let flatDir=join4(target.agentDir??getAgentDir(),"rpc-host-daemon");return{socket:target.socket,flatDir,layoutMarker:join4(flatDir,"layout.json"),legacyPidFile:join4(flatDir,"host.pid"),...hostDaemonDirectoryPaths(join4(flatDir,daemonDirectoryName(target.socket)))}}function hostDaemonDirectoryPaths(dir){return{dir,endpointFile:join4(dir,"endpoint.json"),pointerFile:join4(dir,"host.pid"),lockFile:join4(dir,"daemon.lock"),settingsFile:join4(dir,"settings.json"),stderrLog:join4(dir,"stderr.log"),generationsDir:join4(dir,"generations"),reservationsDir:join4(dir,"reservations")}}async function createDaemonDirectories(paths,identity={}){try{await mkdir2(paths.flatDir,{recursive:!0,mode:DIRECTORY_MODE2}),await makePrivateDirectory(paths.dir),await Promise.all([makePrivateDirectory(paths.generationsDir),makePrivateDirectory(paths.reservationsDir),writeFile(paths.layoutMarker,`${JSON.stringify({layout:HOST_DAEMON_LAYOUT,dir:basename3(paths.dir)})}
3
+ `,{mode:HOST_STATE_FILE_MODE})])}catch(cause){throw new HostDaemonStateError(paths.dir,cause)}await ensureEndpointIdentity(paths,paths.socket,identity)}async function makePrivateDirectory(directory){await mkdir2(directory,{recursive:!0,mode:DIRECTORY_MODE2})===void 0&&await chmod2(directory,DIRECTORY_MODE2)}async function ensureEndpointIdentity(paths,socket,options={}){let temporary=`${paths.endpointFile}.${process.pid}-${randomUUID()}.tmp`;try{await mkdir2(paths.dir,{recursive:!0,mode:DIRECTORY_MODE2});let record=`${JSON.stringify({layout:HOST_DAEMON_LAYOUT,registry_version:ENDPOINT_REGISTRY_VERSION,endpoint_kind:options.kind??"rpc_host",socket,created_at:new Date().toISOString()})}
4
+ `;await writeFile(temporary,record,{mode:HOST_STATE_FILE_MODE,flag:"wx"}),!await link(temporary,paths.endpointFile).then(()=>!0,cause=>isErrorCode(cause,"EEXIST")?!1:createExclusively(paths.endpointFile,record))&&options.repair===!0&&!await namesThisDirectory(paths)&&await rename(temporary,paths.endpointFile)}catch(cause){throw new HostDaemonStateError(paths.endpointFile,cause)}finally{await rm(temporary,{force:!0})}}async function createExclusively(path,content){try{return await writeFile(path,content,{mode:HOST_STATE_FILE_MODE,flag:"wx"}),!0}catch(cause){if(isErrorCode(cause,"EEXIST"))return!1;throw cause}}function isErrorCode(cause,code){return cause instanceof Error&&"code"in cause&&cause.code===code}async function namesThisDirectory(paths){let record;try{record=JSON.parse(await readFile(paths.endpointFile,"utf8"))}catch{return!1}return typeof record!="object"||record===null||!("socket"in record)?!1:typeof record.socket=="string"&&record.socket!==""&&socketNamesDirectory(record.socket,basename3(paths.dir))}import{writeSync}from"node:fs";function writeStderrLine(text){try{writeSync(2,`${text}
5
+ `)}catch{}}function supervisorLog(message){writeStderrLine(`senpi rpc host supervisor: ${message}`)}var loggedUnknownIdentities=new Set;function logUnknownHostIdentity(record,pid){let key=`${record}:${pid}`;loggedUnknownIdentities.has(key)||(loggedUnknownIdentities.add(key),writeStderrLine(JSON.stringify({event:"legacy_host_identity_unknown",record,pid})))}function errorMessage(cause){return cause instanceof Error?cause.message:String(cause)}import{createHash as createHash2}from"node:crypto";import{mkdir as mkdir3,readdir,readFile as readFile4,rename as rename3,rm as rm3,writeFile as writeFile4}from"node:fs/promises";import{join as join6}from"node:path";import{readFile as readFile3,writeFile as writeFile3}from"node:fs/promises";import{join as join5}from"node:path";import{randomUUID as randomUUID2}from"node:crypto";import{readFile as readFile2,rename as rename2,rm as rm2,writeFile as writeFile2}from"node:fs/promises";async function writeJsonAtomic(path,content){let temporary=`${path}.${process.pid}.${randomUUID2().slice(0,8)}.tmp`;try{await writeFile2(temporary,`${JSON.stringify(content)}
6
+ `,{mode:384}),await rename2(temporary,path)}catch(cause){throw await rm2(temporary,{force:!0}).catch(()=>{}),cause}}async function readJsonObject(path){try{let value=JSON.parse(await readFile2(path,"utf8"));return typeof value=="object"&&value!==null&&!Array.isArray(value)?{...value}:void 0}catch{return}}function ageOf(at,now){if(typeof at!="string")return;let parsed=Date.parse(at);return Number.isNaN(parsed)?void 0:now-parsed}async function readHostOwner(generationDir){let record=await readJsonObject(join5(generationDir,"owner.json"));if(record?.owner===null)return null;if(!isRecord(record?.owner))return;let{pid,startTime}=record.owner;return typeof pid=="number"&&Number.isSafeInteger(pid)&&pid>0&&typeof startTime=="string"&&startTime.length>0?{pid,startTime}:void 0}function writeHostOwner(generationDir,owner){return writeJsonAtomic(join5(generationDir,"owner.json"),{owner})}function sameHostOwner(a,b){if(a==null||b==null||a.pid!==b.pid)return!1;let started=processStartTimeMs(a.startTime);return started!==void 0&&started===processStartTimeMs(b.startTime)}async function callerHostOwner(){let observed=await readProcessIdentity(process.pid,process.platform,void 0,void 0,"UTC");if(observed.kind!=="present"||processStartTimeMs(observed.identity)===void 0)throw new Error("cannot establish RPC host owner OS start identity");return{pid:process.pid,startTime:observed.identity}}async function hostOwnerGone(owner){let observed=await readProcessIdentity(owner.pid,process.platform,1e3,void 0,"UTC");return observed.kind==="absent"||observed.kind==="present"&&processStartTimeMs(observed.identity)!==void 0&&processStartTimeMs(owner.startTime)!==void 0&&!sameProcessStartMs(processStartTimeMs(observed.identity),processStartTimeMs(owner.startTime))}async function claimHostOwner(generationDir){let previous=await readHostOwner(generationDir);if(previous===void 0)throw new Error("RPC host does not support owner lifetime registration");let next=await callerHostOwner();if(!sameHostOwner(previous,next)){if(previous!==null&&!await hostOwnerGone(previous))throw new Error("RPC host lifetime owner is still alive or its identity is unknown");await writeHostOwner(generationDir,next)}}async function writeHostSettings(paths,settings){let generation=generationPaths(paths,settings.instanceId);await createGenerationDirectory(generation),await writeStateFile(paths.settingsFile,settings),await writeStateFile(generation.settingsFile,settings)}async function readHostSettings(paths){let parsed=parseJson(await readFileOrUndefined(paths.settingsFile));if(parsed)return{...typeof parsed.coldStart=="string"&&{coldStart:parsed.coldStart},...typeof parsed.idleExitMs=="number"&&{idleExitMs:parsed.idleExitMs}}}async function writeStateFile(path,content){try{await writeFile3(path,`${JSON.stringify(content)}
7
+ `,{mode:HOST_STATE_FILE_MODE})}catch(cause){throw new HostDaemonStateError(path,cause)}}async function readFileOrUndefined(path){try{return await readFile3(path,"utf8")}catch(error){if(isNodeErrorCode(error,"ENOENT")||isNodeErrorCode(error,"ENOTDIR"))return;throw error}}function parseJson(text){if(text!==void 0)try{let parsed=JSON.parse(text);return isRecord(parsed)?parsed:void 0}catch{return}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNodeErrorCode(error,code){return error instanceof Error&&"code"in error&&error.code===code}var SESSION_PATH_RETRY_AFTER_MS=2e3;function reservationFile(dir,sessionPath){return join6(dir,`${createHash2("sha256").update(sessionPath,"utf8").digest("hex").slice(0,16)}.json`)}function createEndpointReservations(host){let told=process.env[HOST_DAEMON_DIR_ENV],dir=told!==void 0&&told.trim()!==""?told:host.socket===void 0?void 0:createHostDaemonPaths({socket:host.socket,agentDir:host.agentDir}).dir;if(dir!==void 0)return createSessionPathReservations({daemonDir:dir,instanceId:host.instanceId,...host.onFailure?{onFailure:host.onFailure}:{}})}function createSessionPathReservations(options){let paths=hostDaemonDirectoryPaths(options.daemonDir),dir=paths.reservationsDir,pid=options.pid??process.pid,startTime=readProcessStartTime(pid).then(value=>value??null,()=>null),held=new Set,updates=new Map,report=message=>options.onFailure?.(message),publish=async(sessionPath,attached,stillHeld)=>{let owner={instanceId:options.instanceId,pid,processStartTime:await startTime,sessionPath,attached},file=reservationFile(dir,sessionPath);await mkdir3(dir,{recursive:!0,mode:448});let staging=`${file}.${pid}.tmp`;if(await writeFile4(staging,`${JSON.stringify(owner)}
8
+ `,{mode:384}),stillHeld?.()===!1){await rm3(staging,{force:!0});return}await rename3(staging,file)};return{async holderPids(observedStarts){let candidates=(await readSessionPathClaims(dir)).map(({owner})=>owner),generations=await readdir(paths.generationsDir,{withFileTypes:!0}).catch(()=>[]);for(let generation of generations){if(!generation.isDirectory())continue;let record=parseJson(await readFileOrUndefined(join6(paths.generationsDir,generation.name,"host-child.pid")));typeof record?.pid=="number"&&candidates.push({pid:record.pid,processStartTime:typeof record.processStartTime=="string"?record.processStartTime:null,instanceId:generation.name,sessionPath:""})}let byPid=new Map;for(let owner of candidates){if(owner.pid===process.pid)continue;let owners=byPid.get(owner.pid)??[];owners.push(owner),byPid.set(owner.pid,owners)}let live=await Promise.all([...byPid].map(async([pid2,owners])=>{if(!processIsLive(pid2))return;if(observedStarts){if(!observedStarts.has(pid2))return;let observed2=observedStarts.get(pid2);return owners.some(owner=>owner.processStartTime===null?!1:sameProcessStartMs(processStartTimeMs(owner.processStartTime),observed2))?pid2:void 0}let current=await readProcessStartTime(pid2,process.platform,1e3).catch(()=>{}),observed=current===void 0?void 0:processStartTimeMs(current);return observed!==void 0&&owners.some(owner=>owner.processStartTime!==null&&sameProcessStartMs(processStartTimeMs(owner.processStartTime),observed))?pid2:void 0}));return[...new Set(live.filter(value=>value!==void 0))]},async claim(sessionPath,attached=!0){let existing=await readOwner(reservationFile(dir,sessionPath));if(existing&&existing.pid!==pid){let standing=await standingOwner(existing,paths.pointerFile);if(standing)return standing}try{await publish(sessionPath,attached),held.add(sessionPath)}catch(cause){report(`session path reservation for ${sessionPath} could not be written (${errorMessage2(cause)})`)}},async release(sessionPath){held.delete(sessionPath)&&(await updates.get(sessionPath),updates.delete(sessionPath),await rm3(reservationFile(dir,sessionPath),{force:!0}).catch(cause=>{report(`session path reservation for ${sessionPath} could not be removed (${errorMessage2(cause)})`)}))},setAttached(sessionPath,attached){if(!held.has(sessionPath))return;let update=(updates.get(sessionPath)??Promise.resolve()).then(()=>publish(sessionPath,attached,()=>held.has(sessionPath))).catch(cause=>{report(`session path reservation for ${sessionPath} could not be updated (${errorMessage2(cause)})`)});updates.set(sessionPath,update)}}}async function readSessionPathClaims(dir){let entries=await readdir(dir).catch(()=>[]),claims=[];for(let entry of entries){if(!entry.endsWith(".json"))continue;let file=join6(dir,entry),owner=await readOwner(file);owner&&claims.push({file,owner})}return claims}async function standingOwner(owner,pointerFile){if(!await claimOwnerIsLive(owner))return;let current=await currentInstanceId(pointerFile)===owner.instanceId;return current||owner.attached!==!1?{...owner,current}:void 0}async function currentInstanceId(pointerFile){let pointer=parseJson(await readFileOrUndefined(pointerFile).catch(()=>{}));return typeof pointer?.instance_id=="string"?pointer.instance_id:void 0}async function readOwner(file){let parsed;try{parsed=JSON.parse(await readFile4(file,"utf8"))}catch{return}if(typeof parsed!="object"||parsed===null)return;let{instanceId,pid,processStartTime,sessionPath,attached}=parsed;if(!(typeof instanceId!="string"||typeof pid!="number"||typeof sessionPath!="string"))return{instanceId,pid,processStartTime:typeof processStartTime=="string"?processStartTime:null,sessionPath,...typeof attached=="boolean"?{attached}:{}}}async function claimOwnerIsLive(owner){if(!processIsLive(owner.pid))return!1;let recorded=owner.processStartTime===null?void 0:processStartTimeMs(owner.processStartTime);if(recorded===void 0)return logUnknownHostIdentity("session-path-claim",owner.pid),!0;let current=await readProcessStartTime(owner.pid).catch(()=>{}),observed=current===void 0?void 0:processStartTimeMs(current);return observed===void 0||sameProcessStartMs(recorded,observed)}function errorMessage2(cause){return cause instanceof Error?cause.message:String(cause)}var HOST_COLD_START_ENV="SENPI_RPC_HOST_COLD_START",HOST_IDLE_EXIT_MS_ENV="SENPI_RPC_HOST_IDLE_EXIT_MS",DEFAULT_HOST_IDLE_EXIT_MS=9e5,HANDOFF_GRACE_MS_ENV="SENPI_RPC_HANDOFF_GRACE_MS",DEFAULT_HANDOFF_GRACE_MS=6e5;function parseColdStart(value){return value==="transient"||value==="persistent"?value:void 0}function parseIdleExitMs(value){if(value===void 0||!/^\d+$/.test(value.trim()))return;let parsed=Number(value.trim());return Number.isFinite(parsed)&&parsed>0?parsed:void 0}function resolveHostPolicy(settings,env){let record=isRecord2(settings)?settings:{},coldStart=parseColdStart(env[HOST_COLD_START_ENV])??parseColdStart(asOptionalString(record.coldStart))??"transient",idleExitMs=parseIdleExitMs(env[HOST_IDLE_EXIT_MS_ENV])??parseIdleExitMs(asOptionalString(record.idleExitMs))??9e5;return{coldStart,idleExitMs}}var IdleExitDecider=class{constructor(idleExitMs,now=Date.now){this.idleExitMs=idleExitMs,this.now=now}update(activity){return activity.connections>0||activity.activeTurns>0?(this.idleSince=void 0,"active"):this.idleExitMs===Number.POSITIVE_INFINITY?"idle":this.idleSince===void 0?(this.idleSince=this.now(),"idle"):this.now()-this.idleSince>=this.idleExitMs?"exit":"idle"}};function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function asOptionalString(value){return typeof value=="string"?value:typeof value=="number"?String(value):void 0}import{rename as rename4,rm as rm6}from"node:fs/promises";import{readdir as readdir3,rm as rm5}from"node:fs/promises";import{readdir as readdir2}from"node:fs/promises";import{readdirSync,readFileSync}from"node:fs";function supportedPlatform(platform){return platform==="darwin"||platform==="linux"?platform:void 0}async function loadProcessTableReader(platform=process.platform,options={}){let supported=supportedPlatform(platform);return supported===void 0||typeof globalThis.Bun>"u"?void 0:supported==="darwin"?await darwinReader(options):linuxReader}var KINFO_PROC_STRIDE=648,KINFO_PID_OFFSET=40,KINFO_PPID_OFFSET=560,KINFO_STAT_OFFSET=36,SZOMB=5,PROC_PIDTASKINFO=4,TASKINFO_RESIDENT_OFFSET=8,TABLE_START_BYTES=1<<20,TABLE_MAX_BYTES=32<<20;function parseKernelProcessTable(table,rowCount,residentKb){if(rowCount<=0||table.byteLength<rowCount*KINFO_PROC_STRIDE)return;let view=new DataView(table.buffer,table.byteOffset,table.byteLength),rows=[],selfSeen=!1;for(let index=0;index<rowCount;index++){let base=index*KINFO_PROC_STRIDE,pid=view.getUint32(base+KINFO_PID_OFFSET,!0);if(!Number.isInteger(pid)||pid<=0)continue;let ppid=view.getUint32(base+KINFO_PPID_OFFSET,!0),zombie=table[base+KINFO_STAT_OFFSET]===SZOMB;if(pid===process.pid){if(ppid!==process.ppid||zombie)return;selfSeen=!0}rows.push({pid,ppid,state:zombie?"Z":"U",rssKb:residentKb(pid)})}return selfSeen?rows:void 0}async function darwinReader(options){let{dlopen,FFIType,ptr}=await import("bun:ffi"),library=dlopen("libSystem.B.dylib",{sysctl:{args:[FFIType.ptr,FFIType.u32,FFIType.ptr,FFIType.ptr,FFIType.ptr,FFIType.i32],returns:FFIType.i32},proc_pidinfo:{args:[FFIType.i32,FFIType.i32,FFIType.u32,FFIType.ptr,FFIType.i32],returns:FFIType.i32}}),mib=new Int32Array([1,14,0]),none=new Uint8Array(1),requested=options.initialTableBytes,table=new Uint8Array(Number.isFinite(requested)&&requested!==void 0&&requested>0?Math.min(Math.floor(requested),TABLE_MAX_BYTES):TABLE_START_BYTES),length=new Uint32Array(1),taskInfo=new Uint8Array(256),taskView=new DataView(taskInfo.buffer),residentKb=pid=>(taskInfo.fill(0),library.symbols.proc_pidinfo(pid,PROC_PIDTASKINFO,0,ptr(taskInfo),taskInfo.byteLength)>0?Math.round(Number(taskView.getBigUint64(TASKINFO_RESIDENT_OFFSET,!0))/1024):0);return()=>{for(;;){if(length[0]=table.byteLength,library.symbols.sysctl(ptr(mib),mib.length,ptr(table),ptr(length),ptr(none),0)!==0){if(table.byteLength>=TABLE_MAX_BYTES)return;let reported=length[0]>table.byteLength?length[0]:0;table=new Uint8Array(Math.min(TABLE_MAX_BYTES,Math.max(table.byteLength*2,reported)));continue}return parseKernelProcessTable(table,Math.floor(length[0]/KINFO_PROC_STRIDE),residentKb)}}}function linuxReader(){let rows=[];for(let entry of readdirSync("/proc")){let pid=Number(entry);if(!Number.isInteger(pid)||pid<=0)continue;let stat3;try{stat3=readFileSync(`/proc/${pid}/stat`,"utf8")}catch{continue}let tail=stat3.slice(stat3.lastIndexOf(")")+2).split(" "),state=tail[0],ppid=Number(tail[1]);if(state===void 0||!Number.isInteger(ppid))continue;let rssPages=Number(tail[21]);rows.push({pid,ppid,state,rssKb:Number.isFinite(rssPages)?Math.round(rssPages*4):0})}return rows}var UNOBSERVED={rss_mb:null,host_rss_mb:null,open_fds:null,zombies:null},readers=new Map;function tableReader(platform){let cached=readers.get(platform);if(cached!==void 0)return cached;let loading=loadProcessTableReader(platform);return readers.set(platform,loading),loading}async function readHostProcessMetrics(pid,platform=process.platform){if(platform==="win32")return UNOBSERVED;let read=await tableReader(platform);if(read===void 0)return UNOBSERVED;let rows=read();if(rows===void 0)return UNOBSERVED;let tree=descendants(rows,pid);return tree.length===0?UNOBSERVED:{rss_mb:residentMegabytes(tree),host_rss_mb:residentMegabytes(tree.filter(row=>row.pid===pid||row.ppid===pid)),open_fds:platform==="linux"?await openDescriptors(tree):null,zombies:tree.filter(row=>row.state.startsWith("Z")).length}}function residentMegabytes(rows){return Math.round(rows.reduce((total,row)=>total+row.rssKb,0)/KILOBYTES_PER_MEGABYTE)}function descendants(rows,root){let tree=rows.filter(row=>row.pid===root);if(tree.length===0)return tree;for(let index=0;index<tree.length;index++){let parent=tree[index].pid;for(let row of rows)row.ppid===parent&&!tree.includes(row)&&tree.push(row)}return tree}var KILOBYTES_PER_MEGABYTE=1024;async function openDescriptors(tree){let total=0,counted=!1;for(let row of tree){let entries=await readdir2(`/proc/${row.pid}/fd`).catch(()=>{});entries!==void 0&&(counted=!0,total+=entries.length)}return counted?total:null}import{rm as rm4}from"node:fs/promises";import{join as join7}from"node:path";var STALL_REFUSAL_WINDOW_MS_ENV="SENPI_RPC_STALL_REFUSAL_MS",DEFAULT_STALL_REFUSAL_WINDOW_MS=12e4,STOP_STALL_EVIDENCE_MAX_AGE_MS=6e4,CHILD_STALLED_STOP_MAX_MS_ENV="SENPI_RPC_CHILD_STALLED_STOP_MAX_MS",DEFAULT_CHILD_STALLED_STOP_MAX_MS=6e4;function childStalledStopMaxMs(env=process.env){return parseIdleExitMs(env[CHILD_STALLED_STOP_MAX_MS_ENV])??DEFAULT_CHILD_STALLED_STOP_MAX_MS}function ownGenerationDir(env){let daemonDir=env[HOST_DAEMON_DIR_ENV],instanceId=env[HOST_INSTANCE_ID_ENV];if(!(!daemonDir||!instanceId))return join7(daemonDir,"generations",instanceId)}function stallRefusalWindowMs(env=process.env){return parseIdleExitMs(env[STALL_REFUSAL_WINDOW_MS_ENV])??DEFAULT_STALL_REFUSAL_WINDOW_MS}function writeStallEvidence(generationDir,evidence){return writeJsonAtomic(join7(generationDir,"host-stalled.json"),evidence)}function writeHeartbeat(generationDir,at){return writeJsonAtomic(join7(generationDir,"host-alive.json"),{at})}async function readStallEvidence(generation){let raw=await readJsonObject(generation.stalledFile);if(!(raw===void 0||typeof raw.at!="string"||typeof raw.driftMs!="number"))return{at:raw.at,driftMs:raw.driftMs,processCpuMs:typeof raw.processCpuMs=="number"?raw.processCpuMs:0,heapDeltaMb:typeof raw.heapDeltaMb=="number"?raw.heapDeltaMb:0,...typeof raw.sessionId=="string"?{sessionId:raw.sessionId}:{},...typeof raw.tool=="string"?{tool:raw.tool}:{}}}async function recentStall(generation,now,maxAgeMs){let evidence=await readStallEvidence(generation),age=ageOf(evidence?.at,now);return evidence!==void 0&&age!==void 0&&age<=maxAgeMs?evidence:void 0}async function hostLoopStalled(generation,options){if(await recentStall(generation,options.now,options.windowMs)!==void 0)return!0;let heartbeatAge=ageOf((await readJsonObject(generation.aliveFile))?.at,options.now);return heartbeatAge!==void 0&&heartbeatAge>options.errorMs&&heartbeatAge<options.windowMs}async function hostChildAlive(generation){let record=await readJsonObject(generation.childPidFile),pid=record?.pid;if(typeof pid!="number"||!Number.isInteger(pid)||pid<=0)return;if(!processIsLive(pid))return!1;let observed=await readProcessIdentity(pid,process.platform,1e3,processIsLive,"UTC");if(!processIsLive(pid))return!1;let recordedMs=typeof record?.processStartTime=="string"?processStartTimeMs(record.processStartTime):void 0,observedMs=observed.kind==="present"?processStartTimeMs(observed.identity):void 0;return recordedMs!==void 0&&observedMs!==void 0?sameProcessStartMs(recordedMs,observedMs):(supervisorLog(`host child pid ${pid} start time unreadable; preserving generation`),!0)}function writeStopProgress(generation,progress){return writeJsonAtomic(generation.stopProgressFile,progress)}async function clearStopProgress(generation){await rm4(generation.stopProgressFile,{force:!0}).catch(()=>{})}async function activeStopProgress(generation,now,freshMs){let raw=await readJsonObject(generation.stopProgressFile),age=ageOf(raw?.at,now),untilAt=typeof raw?.untilAt=="string"?Date.parse(raw.untilAt):Number.NaN;if(!(age===void 0||age>freshMs||Number.isNaN(untilAt)||untilAt<=now))return untilAt}async function pruneDeadGenerations(paths){let pointer=parseJson(await readFileOrUndefined(paths.pointerFile).catch(()=>{})),pointedAt=typeof pointer?.instance_id=="string"?pointer.instance_id:void 0,generations=[];for(let instanceId of await readdir3(paths.generationsDir).catch(()=>[])){let record=parseJson(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));typeof record?.pid!="number"||processIsLive(record.pid)||await hostChildAlive(generationPaths(paths,instanceId))||(await rm5(generationPaths(paths,instanceId).dir,{recursive:!0,force:!0}).catch(()=>{}),generations.push(instanceId))}let pointerRemoved=pointedAt!==void 0&&generations.includes(pointedAt);pointerRemoved&&await rm5(paths.pointerFile,{force:!0}).catch(()=>{});let claims=[];for(let claim of await readSessionPathClaims(paths.reservationsDir))await claimOwnerIsLive(claim.owner)||(await rm5(claim.file,{force:!0}).catch(()=>{}),claims.push(claim.owner.sessionPath));return{generations,claims,pointer:pointerRemoved}}function memoryOf(metrics){return{rss_mb:metrics.rss_mb,host_rss_mb:metrics.host_rss_mb}}async function readGenerationRows(paths,options={}){let pointer=parseJson(await readFileOrUndefined(paths.pointerFile).catch(()=>{})),currentId=typeof pointer?.instance_id=="string"?pointer.instance_id:void 0,claims=await readSessionPathClaims(paths.reservationsDir),rows=[];for(let instanceId of await readdir3(paths.generationsDir).catch(()=>[])){let record=parseJson(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));if(typeof record?.pid!="number")continue;let alive=processIsLive(record.pid)||await hostChildAlive(generationPaths(paths,instanceId))===!0;!alive&&options.includeDead!==!0||rows.push({instanceId,generation:typeof record.generation=="number"?record.generation:0,pid:record.pid,engineVersion:typeof record.engineVersion=="string"?record.engineVersion:null,...alive?memoryOf(await readHostProcessMetrics(record.pid)):{rss_mb:null,host_rss_mb:null},sessions:claims.filter(claim=>claim.owner.instanceId===instanceId).length,current:instanceId===currentId,alive})}return rows.sort((left,right)=>left.generation-right.generation)}async function readHostRegistration(paths){let pointer=parseJson(await readFileOrUndefined(paths.pointerFile));if(!pointer||typeof pointer.instance_id!="string")return;let text=await readFileOrUndefined(generationPaths(paths,pointer.instance_id).pidFile),record=text===void 0?void 0:parseDaemonPidFile(text);if(record===void 0)return;let parsed=parseJson(text)??{},writer=parseWriter(parsed);return{record,...writer&&{writer},...typeof parsed.socket=="string"&&{socket:parsed.socket},instanceId:pointer.instance_id,generation:typeof parsed.generation=="number"?parsed.generation:0}}async function writeHostRegistration(paths,registration,options={}){options.fresh!==!0&&await pruneDeadGenerations(paths);let{generation,writer}=await writeGenerationRecord(paths,registration);await writeStateFile(`${paths.pointerFile}.${process.pid}.tmp`,{layout:HOST_DAEMON_LAYOUT,instance_id:registration.instanceId,generation_dir:generation.relativeDir,writer}),await rename4(`${paths.pointerFile}.${process.pid}.tmp`,paths.pointerFile)}async function writeGenerationRecord(paths,registration){let generation=generationPaths(paths,registration.instanceId),writer={pid:process.pid,startTime:await thisProcessStartTime()},{build}=registration;return await createGenerationDirectory(generation),await writeStateFile(generation.pidFile,{...registration.record,instance_id:registration.instanceId,generation:registration.generation,...build&&{engineVersion:build.text,engineOrdinal:build.ordinal},launchProfileId:registration.launchProfileId,socket:registration.socket,writer}),{generation,writer}}async function clearHostRegistration(paths){let pointer=parseJson(await readFileOrUndefined(paths.pointerFile));if(typeof pointer?.instance_id=="string"){if(await hostChildAlive(generationPaths(paths,pointer.instance_id)))throw new Error(`refusing to clear generation ${pointer.instance_id} with a live host child`);await rm6(generationPaths(paths,pointer.instance_id).dir,{recursive:!0,force:!0})}await rm6(paths.settingsFile,{force:!0}),await rm6(paths.pointerFile,{force:!0})}async function releaseGeneration(paths,owner){let generation=generationPaths(paths,owner.instanceId);if(await hostChildAlive(generation))return;let record=parseDaemonPidFile(await readFileOrUndefined(generation.pidFile)??"");if(record!==void 0&&record.pid!==owner.pid)return;if(owner.superseded===!0){await rm6(generation.dir,{recursive:!0,force:!0});return}let ownsPointer=parseJson(await readFileOrUndefined(paths.pointerFile))?.instance_id===owner.instanceId;ownsPointer&&await rm6(paths.settingsFile,{force:!0}),await rm6(generation.dir,{recursive:!0,force:!0}),ownsPointer&&await rm6(paths.pointerFile,{force:!0})}async function provenOwner(registered,socket){let record=registered?.record;if(!record||registered?.socket!==void 0&&!sameEndpoint(registered.socket,socket))return;if(record.processStartTime===null){processIsLive(record.pid)&&logUnknownHostIdentity("host.pid",record.pid);return}let identity={pid:record.pid,processStartTime:record.processStartTime};return await processMatchesPidFile(identity,readProcessStartTime).catch(error=>(error instanceof ProcessIdentityUnreadableError&&logUnknownHostIdentity("host.pid",identity.pid),!1))?{...identity,instanceId:registered.instanceId}:void 0}async function writtenByThisProcess(writer,readStartTime){if(writer===void 0||writer.pid!==process.pid||writer.startTime===null)return!1;let startTime=readStartTime?await readStartTime(process.pid).then(value=>value??null,()=>null):await thisProcessStartTime();return sameProcessStartMs(processStartTimeMs(writer.startTime),startTime===null?void 0:processStartTimeMs(startTime))}var selfStartTime;function thisProcessStartTime(){return selfStartTime??=readProcessStartTime(process.pid).then(value=>value??null,()=>null),selfStartTime}function parseWriter(parsed){if(!isRecord(parsed.writer)||typeof parsed.writer.pid!="number")return;let{pid,startTime}=parsed.writer;return{pid,startTime:typeof startTime=="string"?startTime:null}}import{createHash as createHash3,randomBytes,timingSafeEqual}from"node:crypto";import{chmod as chmod3,mkdir as mkdir4,readFile as readFile5,writeFile as writeFile5}from"node:fs/promises";import{dirname as dirname3,win32 as win322}from"node:path";var WINDOWS_PIPE_PREFIX="\\\\.\\pipe\\senpi-rpc-",SOCKET_SECRET_BYTES=32,SOCKET_SECRET_SUFFIX=".secret",SOCKET_SECRET_FILE_ENV="SENPI_RPC_SOCKET_SECRET_FILE",SOCKET_HANDSHAKE_TIMEOUT_MS=2e3;function socketSecretPath(logicalPath){if(logicalPath.toLowerCase().startsWith("\\\\.\\pipe\\"))throw new Error(`Windows RPC named-pipe addresses need a logical filesystem path for their secret: ${logicalPath}`);return`${logicalPath}${SOCKET_SECRET_SUFFIX}`}async function ensureSocketSecret(path){try{let existing=await readFile5(path);if(existing.length===SOCKET_SECRET_BYTES)return existing}catch(error){if(!isNodeErrorCode2(error,"ENOENT"))throw error}return createSocketSecret(path)}async function createSocketSecret(path){await mkdir4(dirname3(path),{recursive:!0});let secret=randomBytes(SOCKET_SECRET_BYTES);return await writeFile5(path,secret,{mode:384}),await chmod3(path,384),secret}async function readSocketSecret(path){let secret=await readFile5(path);if(secret.length!==SOCKET_SECRET_BYTES)throw new Error(`invalid RPC socket secret: ${path}`);return secret}function resolveSocketTransportAddress(socketPath,platform,secret){if(platform!=="win32"||socketPath.toLowerCase().startsWith("\\\\.\\pipe\\"))return socketPath;if(!/^[a-zA-Z]:[\\/]/.test(socketPath)&&!/^\\\\[^/]/.test(socketPath))throw new Error(`Windows RPC socket path must be drive-qualified or UNC: ${socketPath}`);let canonical=win322.normalize(socketPath).toLowerCase(),identity=Buffer.concat([Buffer.from(canonical,"utf8"),Buffer.from(secret??[])]),name=createHash3("sha256").update(identity).digest("hex").slice(0,32);return`${WINDOWS_PIPE_PREFIX}${name}`}function authenticateSocket(socket,secret,onAuthenticated){let received=Buffer.alloc(0),finish=()=>{clearTimeout(timer),socket.off("data",onData),socket.off("error",onError)},onError=()=>{finish(),socket.destroy()},timer=setTimeout(()=>{finish(),socket.destroy()},SOCKET_HANDSHAKE_TIMEOUT_MS),onData=chunk=>{if(received=Buffer.concat([received,chunk]),received.length<secret.length)return;if(finish(),!timingSafeEqual(received.subarray(0,secret.length),Buffer.from(secret))){socket.destroy();return}let remainder=received.subarray(secret.length);remainder.length>0&&socket.unshift(remainder),onAuthenticated()};socket.on("data",onData),socket.once("error",onError),socket.once("close",finish)}function sendSocketHandshake(socket,secret){socket.write(Buffer.from(secret))}function isNodeErrorCode2(error,code){return error instanceof Error&&"code"in error&&error.code===code}import{mkdir as mkdir5,readFile as readFile6,rename as rename5,stat,unlink,writeFile as writeFile6}from"node:fs/promises";import{dirname as dirname4}from"node:path";var PUBLIC_SOCKET_IDENTITY_FILE="public-socket.owner",SOCKET_IDENTITY_WAIT_MS=3e4,MAX_SOCKET_PATH_BYTES=103;function generationBindPath(publicSocket,generation){return`${publicSocket}.next-${generation}`}function sameSocketIdentity(a,b){return a.dev===b.dev&&a.ino===b.ino}async function statSocketIdentity(socketPath){try{let{dev,ino}=await stat(socketPath);return{dev,ino}}catch(cause){if(isNodeErrorCode3(cause,"ENOENT"))return;throw cause}}async function classifyEndpointOwnership(socketPath,identity){if(identity===void 0||process.platform==="win32"||socketPath.startsWith("\0"))return"unknown";let current;try{current=await statSocketIdentity(socketPath)}catch{return"unknown"}return current===void 0?"absent":sameSocketIdentity(current,identity)?"held":"replaced"}async function socketEntryReplaced(socketPath,identity){return await classifyEndpointOwnership(socketPath,identity)==="replaced"}async function writeSocketIdentityFile(path,identity){await mkdir5(dirname4(path),{recursive:!0,mode:448});let tmpPath=`${path}.${process.pid}.tmp`;await writeFile6(tmpPath,`${JSON.stringify(identity)}
9
+ `,{mode:384}),await rename5(tmpPath,path)}async function readSocketIdentityFile(path){let raw;try{raw=await readFile6(path,"utf8")}catch(cause){if(isNodeErrorCode3(cause,"ENOENT"))return;throw cause}let parsed;try{parsed=JSON.parse(raw)}catch{return}if(!(typeof parsed!="object"||parsed===null||typeof parsed.dev!="number"||typeof parsed.ino!="number"))return{dev:parsed.dev,ino:parsed.ino}}async function waitForSocketIdentityFile(path,timeoutMs=SOCKET_IDENTITY_WAIT_MS,intervalMs=25){let deadline=Date.now()+timeoutMs;for(;;){let identity=await readSocketIdentityFile(path);if(identity!==void 0)return identity;if(Date.now()>=deadline)return;await delayUnrefed(intervalMs)}}async function unlinkOwnedSocket(socketPath,identity,log){if(process.platform==="win32"||socketPath.startsWith("\0"))return;let current;try{current=await statSocketIdentity(socketPath)}catch(cause){log(`socket ${socketPath} ownership could not be verified (${errorMessage3(cause)}); leaving it`);return}if(current!==void 0){if(identity===void 0){log(`socket path ${socketPath} ownership unknown; leaving it`);return}if(!sameSocketIdentity(current,identity)){log(`socket path ${socketPath} now owned by another host; leaving it`);return}try{await unlink(socketPath)}catch(cause){isNodeErrorCode3(cause,"ENOENT")||log(`socket ${socketPath} removal failed (${errorMessage3(cause)})`)}}}async function shieldSocketDuringClose(socketPath,close){if(process.platform==="win32"||socketPath.startsWith("\0"))return close();let shieldPath=`${socketPath}.shield-${process.pid}`,shielded=!1;try{await statSocketIdentity(socketPath)!==void 0&&(await rename5(socketPath,shieldPath),shielded=!0)}catch{}try{await close()}finally{if(shielded)try{await rename5(shieldPath,socketPath)}catch{}}}function delayUnrefed(ms){return new Promise(resolve2=>{setTimeout(resolve2,ms).unref?.()})}function errorMessage3(cause){return cause instanceof Error?cause.message:String(cause)}function isNodeErrorCode3(cause,code){return cause instanceof Error&&"code"in cause&&cause.code===code}import{stat as stat2}from"node:fs/promises";var LegacyLockArtifactError=class extends Error{constructor(lockPath){super(`Legacy lock directory is present at ${lockPath}`),this.code="ELEGACY_LOCK_ARTIFACT",this.name="LegacyLockArtifactError",this.lockPath=lockPath}},DEFAULT_RETRIES={retries:100,minTimeout:20,maxTimeout:100};async function openLockDatabase(lockPath){if(typeof globalThis.Bun<"u"){let{Database}=await import("bun:sqlite"),database2=new Database(lockPath,{create:!0});return{exec:sql=>database2.exec(sql),close:()=>database2.close(!1)}}let{DatabaseSync}=await import("node:sqlite"),database=new DatabaseSync(lockPath);return{exec:sql=>database.exec(sql),close:()=>database.close()}}async function acquireOwnershipSafeLock(lockPath,options={}){let retries=options.retries??DEFAULT_RETRIES,deadline=Date.now()+retries.retries*retries.maxTimeout;for(;;){await rejectLegacyDirectory(lockPath);let busyMs=Math.max(1,Math.min(retries.maxTimeout,deadline-Date.now())),database;try{database=await openLockDatabase(lockPath),database.exec(`PRAGMA busy_timeout = ${busyMs}; BEGIN EXCLUSIVE;`);let released=!1,held=database;return async()=>{if(!released){released=!0;try{held.exec("COMMIT;")}finally{held.close()}}}}catch(error){try{database?.close()}catch{}if(await rejectLegacyDirectory(lockPath),isBusy(error)&&Date.now()<deadline){await new Promise(resolve2=>setTimeout(resolve2,Math.min(retries.minTimeout,Math.max(1,deadline-Date.now()))));continue}throw error}}}async function rejectLegacyDirectory(lockPath){try{if((await stat2(lockPath)).isDirectory())throw new LegacyLockArtifactError(lockPath)}catch(error){if(error instanceof LegacyLockArtifactError||error.code!=="ENOENT")throw error}}function isBusy(error){let message=error instanceof Error?error.message:String(error);return/busy|locked/i.test(message)||error?.code==="SQLITE_BUSY"}export{canonicalSessionPath,sessionDirectoryRemoved,canonicalEndpointPath,daemonDirectoryName,sameEndpoint,socketNamesDirectory,shardKey,shardSocketPathForKey,shardSocketPath,parseShardSocket,generationPaths,HOST_DAEMON_LAYOUT,HOST_DAEMON_DIR_ENV,ENDPOINT_REGISTRY_VERSION,HOST_STATE_FILE_MODE,createHostDaemonPaths,hostDaemonDirectoryPaths,createDaemonDirectories,ensureEndpointIdentity,writeJsonAtomic,readJsonObject,ageOf,readHostOwner,writeHostOwner,sameHostOwner,callerHostOwner,hostOwnerGone,claimHostOwner,writeHostSettings,readHostSettings,writeStateFile,readFileOrUndefined,parseJson,readHostProcessMetrics,writeStderrLine,supervisorLog,logUnknownHostIdentity,errorMessage,SESSION_PATH_RETRY_AFTER_MS,createEndpointReservations,readSessionPathClaims,claimOwnerIsLive,HOST_COLD_START_ENV,HOST_IDLE_EXIT_MS_ENV,DEFAULT_HOST_IDLE_EXIT_MS,HANDOFF_GRACE_MS_ENV,DEFAULT_HANDOFF_GRACE_MS,parseColdStart,parseIdleExitMs,resolveHostPolicy,IdleExitDecider,STOP_STALL_EVIDENCE_MAX_AGE_MS,CHILD_STALLED_STOP_MAX_MS_ENV,childStalledStopMaxMs,ownGenerationDir,stallRefusalWindowMs,writeStallEvidence,writeHeartbeat,recentStall,hostLoopStalled,hostChildAlive,writeStopProgress,clearStopProgress,activeStopProgress,pruneDeadGenerations,readGenerationRows,readHostRegistration,writeHostRegistration,writeGenerationRecord,clearHostRegistration,releaseGeneration,provenOwner,writtenByThisProcess,thisProcessStartTime,SOCKET_SECRET_FILE_ENV,socketSecretPath,ensureSocketSecret,createSocketSecret,readSocketSecret,resolveSocketTransportAddress,authenticateSocket,sendSocketHandshake,PUBLIC_SOCKET_IDENTITY_FILE,MAX_SOCKET_PATH_BYTES,generationBindPath,statSocketIdentity,classifyEndpointOwnership,socketEntryReplaced,writeSocketIdentityFile,readSocketIdentityFile,waitForSocketIdentityFile,unlinkOwnedSocket,shieldSocketDuringClose,acquireOwnershipSafeLock};
@@ -1,5 +1,5 @@
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{StringDecoder}from"node:string_decoder";function serializeJsonLine(value){return`${JSON.stringify(value)}
2
+ var HOST_GENERATION_ENV="SENPI_RPC_HOST_GENERATION",HOST_INSTANCE_ID_ENV="SENPI_RPC_HOST_INSTANCE_ID";import{StringDecoder}from"node:string_decoder";function serializeJsonLine(value){return`${JSON.stringify(value)}
3
3
  `}var MAX_RPC_LINE_CHARACTERS=16*1024*1024;function attachJsonlLineReader(stream,onLine,options={}){let decoder=new StringDecoder("utf8"),maxLineLength=options.maxLineLength??Number.POSITIVE_INFINITY;if(!(maxLineLength>0))throw new Error("maxLineLength must be greater than zero.");let buffer="",discardingOversizedLine=!1,consume=text=>{let offset=0;for(;offset<text.length;){if(discardingOversizedLine){let newlineIndex2=text.indexOf(`
4
4
  `,offset);if(newlineIndex2===-1)return;discardingOversizedLine=!1,offset=newlineIndex2+1;continue}let newlineIndex=text.indexOf(`
5
- `,offset);if(newlineIndex===-1){let remainder=text.slice(offset);buffer.length+remainder.length>maxLineLength?(buffer="",discardingOversizedLine=!0,options.onOversizedLine?.()):buffer+=remainder;return}let segment=text.slice(offset,newlineIndex);if(buffer.length+segment.length>maxLineLength)options.onOversizedLine?.();else{let line=buffer+segment;onLine(line.endsWith("\r")?line.slice(0,-1):line)}buffer="",offset=newlineIndex+1}},onData=chunk=>{consume(typeof chunk=="string"?chunk:decoder.write(chunk))},onEnd=()=>{consume(decoder.end()),!discardingOversizedLine&&buffer.length>0&&onLine(buffer.endsWith("\r")?buffer.slice(0,-1):buffer),buffer="",discardingOversizedLine=!1};return stream.on("data",onData),stream.on("end",onEnd),()=>{stream.off("data",onData),stream.off("end",onEnd)}}export{serializeJsonLine,MAX_RPC_LINE_CHARACTERS,attachJsonlLineReader};
5
+ `,offset);if(newlineIndex===-1){let remainder=text.slice(offset);buffer.length+remainder.length>maxLineLength?(buffer="",discardingOversizedLine=!0,options.onOversizedLine?.()):buffer+=remainder;return}let segment=text.slice(offset,newlineIndex);if(buffer.length+segment.length>maxLineLength)options.onOversizedLine?.();else{let line=buffer+segment;onLine(line.endsWith("\r")?line.slice(0,-1):line)}buffer="",offset=newlineIndex+1}},onData=chunk=>{consume(typeof chunk=="string"?chunk:decoder.write(chunk))},onEnd=()=>{consume(decoder.end()),!discardingOversizedLine&&buffer.length>0&&onLine(buffer.endsWith("\r")?buffer.slice(0,-1):buffer),buffer="",discardingOversizedLine=!1};return stream.on("data",onData),stream.on("end",onEnd),()=>{stream.off("data",onData),stream.off("end",onEnd)}}export{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV,serializeJsonLine,MAX_RPC_LINE_CHARACTERS,attachJsonlLineReader};
@@ -0,0 +1,2 @@
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{HOST_DAEMON_LAYOUT,acquireOwnershipSafeLock,canonicalEndpointPath,claimOwnerIsLive,createHostDaemonPaths,generationPaths,hostChildAlive,hostDaemonDirectoryPaths,parseJson,readFileOrUndefined,readSessionPathClaims,readSocketSecret,resolveSocketTransportAddress,socketNamesDirectory,socketSecretPath}from"./chunk-NEFNNQSV.js";import{ProcessIdentityUnreadableError,parseDaemonPidFile,processMatchesPidFile}from"./chunk-ZRWOLP4E.js";import{readdir}from"node:fs/promises";import{basename as basename2,join}from"node:path";import{createHash}from"node:crypto";import{basename}from"node:path";var TUI_SOCKET_NAME=/^t-[0-9a-f]{16}\.sock$/;function tuiSocketName(instanceId){return`t-${createHash("sha256").update(instanceId,"utf8").digest("hex").slice(0,16)}.sock`}function isTuiControlSocket(socket){return TUI_SOCKET_NAME.test(basename(socket))}function socketNeedsHandshake(socket,platform=process.platform){return platform==="win32"||isTuiControlSocket(socket)}var ENDPOINT_DIRECTORY_NAME=/^[0-9a-f]{16}$/;async function listHostEndpoints(agentDir){let flatDir=join(agentDir,"rpc-host-daemon");if(parseJson(await readFileOrUndefined(join(flatDir,"layout.json")).catch(()=>{}))?.layout!==HOST_DAEMON_LAYOUT)return[];let dirs=(await readdir(flatDir,{withFileTypes:!0}).catch(()=>[])).filter(entry=>entry.isDirectory()&&ENDPOINT_DIRECTORY_NAME.test(entry.name)).map(entry=>join(flatDir,entry.name)).sort(),endpoints=[];for(let dir of dirs)endpoints.push(await identifyEndpoint(dir));return endpoints}async function identifyEndpoint(dir){let paths=hostDaemonDirectoryPaths(dir),named=await recordNaming(paths.endpointFile,dir);if(named!==void 0)return{socket:named.socket,dir,identity:"endpoint",endpoint_kind:endpointKindOf(named.record)};let booted=await recordNaming(paths.settingsFile,dir);if(booted!==void 0)return{socket:booted.socket,dir,identity:"settings",endpoint_kind:"rpc_host"};let generations=await readdir(paths.generationsDir).catch(()=>[]);for(let instanceId of generations.sort()){let recorded=await recordNaming(join(paths.generationsDir,instanceId,"settings.json"),dir);if(recorded!==void 0)return{socket:recorded.socket,dir,identity:"generation-settings",endpoint_kind:"rpc_host"}}return{socket:null,dir,identity:"unknown",endpoint_kind:"rpc_host"}}async function endpointKindOfSocket(socket,agentDir){if(isTuiControlSocket(socket))return"tui";let paths=createHostDaemonPaths({socket,agentDir}),named=await recordNaming(paths.endpointFile,paths.dir);return named===void 0?"rpc_host":endpointKindOf(named.record)}function endpointKindOf(record){return record.endpoint_kind==="tui"?"tui":"rpc_host"}async function recordNaming(file,dir){let record=parseJson(await readFileOrUndefined(file).catch(()=>{})),socket=record?.socket;if(!(record===void 0||typeof socket!="string"||socket===""))return socketNamesDirectory(socket,basename2(dir))?{socket,record}:void 0}import{lstat as lstat2,rm}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";import{createHash as createHash2}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname,join as join2}from"node:path";var LOCK_BUSY_WAIT_MS=100;function hostEnsureLockTarget(socket){return join2(tmpdir(),"senpi-rpc-host-locks",createSocketLockName(socket))}async function acquireHostEnsureLock(socket,waitMs){let lockTarget=hostEnsureLockTarget(socket);return await mkdir(dirname(lockTarget),{recursive:!0}),await writeFile(lockTarget,"",{flag:"a",mode:384}),acquireOwnershipSafeLock(`${lockTarget}.lock`,hostEnsureLockOptions(waitMs))}function hostEnsureLockOptions(waitMs){return{retries:{retries:Math.ceil(waitMs/LOCK_BUSY_WAIT_MS),minTimeout:20,maxTimeout:LOCK_BUSY_WAIT_MS}}}function createSocketLockName(socket){return createHash2("sha256").update(socketLockAddress(socket),"utf8").digest("hex").slice(0,32)}function socketLockAddress(socket){return process.platform==="win32"||socket.startsWith("\0")?resolveSocketTransportAddress(socket,process.platform):canonicalEndpointPath(socket)}import{lstat,readdir as readdir2}from"node:fs/promises";import{createConnection}from"node:net";import{basename as basename3,dirname as dirname2,join as join3}from"node:path";var SOCKET_PROBE_TIMEOUT_MS=2e3;async function endpointInUse(paths,socket){if(await anyGenerationLive(paths))return{inUse:"live_generation"};for(let claim of await readSessionPathClaims(paths.reservationsDir))if(await claimOwnerIsLive(claim.owner))return{inUse:"live_claim"};let silence=await socketSilence(socket);if(silence===void 0)return{inUse:"reachable"};let successors=(await socketSiblings(socket)).filter(name=>name.startsWith(`${basename3(socket)}.next-`));for(let successor of successors)if(await socketSilence(join3(dirname2(socket),successor))===void 0)return{inUse:"reachable"};return{inUse:void 0,silence}}async function socketSiblings(socket){let name=basename3(socket);return(await readdir2(dirname2(socket)).catch(()=>[])).filter(entry=>entry.startsWith(`${name}.next-`)||entry.startsWith(`${name}.shield-`))}async function anyGenerationLive(paths){for(let instanceId of await readdir2(paths.generationsDir).catch(()=>[])){if(await hostChildAlive(generationPaths(paths,instanceId)))return!0;let record=generationRecord(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));if(record!==void 0&&await recordIsLive(record))return!0}return!1}function generationRecord(text){if(text===void 0)return;let record=parseDaemonPidFile(text);if(record!==void 0)return record;let pid=parseJson(text)?.pid;return typeof pid=="number"&&Number.isInteger(pid)&&pid>0?{pid,processStartTime:null}:void 0}async function recordIsLive(record){try{return await processMatchesPidFile(record)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}}async function socketSilence(socket){let secret;return process.platform==="win32"&&(secret=await readSocketSecret(socketSecretPath(socket)).catch(()=>{}),secret===void 0)?"socket_absent":new Promise(resolveProbe=>{let connection=createConnection(resolveSocketTransportAddress(socket,process.platform,secret)),finish=value=>{clearTimeout(timeout),connection.destroy(),resolveProbe(value)},timeout=setTimeout(()=>finish(void 0),SOCKET_PROBE_TIMEOUT_MS);connection.once("connect",()=>finish(void 0)),connection.once("error",error=>{error.code==="ECONNREFUSED"?refusedBySocket(socket).then(finish):error.code==="ENOENT"?finish("socket_absent"):finish(void 0)})})}async function refusedBySocket(socket){if(process.platform==="win32"||socket.startsWith("\0"))return"socket_refused";try{return(await lstat(socket)).isSocket()?"socket_refused":void 0}catch(error){return error instanceof Error&&"code"in error&&error.code==="ENOENT"?"socket_absent":void 0}}var GC_LOCK_WAIT_MS=2e3;async function gcHostEndpoints(agentDir,options={}){let removed=[],kept=[],wanted=kind=>options.kinds===void 0||options.kinds.includes(kind),legacy=wanted("rpc_host")?await legacyFlatDirectory(agentDir):void 0;legacy!==void 0&&kept.push({socket:null,dir:legacy,reason:"legacy_layout"});for(let endpoint of await listHostEndpoints(agentDir)){if(!wanted(endpoint.endpoint_kind))continue;if(endpoint.socket===null){kept.push({socket:null,dir:endpoint.dir,reason:"unknown_identity"});continue}let entry={socket:endpoint.socket,dir:endpoint.dir};try{let outcome=await gcEndpoint(endpoint.socket,endpoint.dir,options);outcome.removed?outcome.skipped.length===0?removed.push({...entry,reason:outcome.reason}):removed.push({...entry,reason:outcome.reason,skipped:outcome.skipped}):kept.push({...entry,reason:outcome.reason})}catch(error){kept.push({...entry,reason:"failed",error:error instanceof Error?error.message:String(error)})}}return{removed,kept}}async function gcEndpoint(socket,dir,options){let release=await acquireEnsureLock(socket);if(release===void 0)return{removed:!1,reason:"locked"};try{await options._test?.afterLockAcquired?.(socket);let evidence=await endpointInUse(hostDaemonDirectoryPaths(dir),socket);if(evidence.inUse!==void 0)return{removed:!1,reason:evidence.inUse};let skipped=await removeEndpoint(socket,dir);return{removed:!0,reason:evidence.silence,skipped}}finally{await release()}}async function removeEndpoint(socket,dir){let skipped=[];for(let sibling of await socketSiblings(socket)){let path=join4(dirname3(socket),sibling),entry=await lstat2(path).catch(error=>{if(!(error instanceof Error&&"code"in error&&error.code==="ENOENT"))throw error});entry?.isDirectory()?skipped.push({path,type:"directory"}):entry!==void 0&&await rm(path,{force:!0})}return await rm(socket,{force:!0}),await rm(dir,{recursive:!0,force:!0}),skipped}async function acquireEnsureLock(socket){return acquireHostEnsureLock(socket,GC_LOCK_WAIT_MS).catch(()=>{})}async function legacyFlatDirectory(agentDir){let flatDir=join4(agentDir,"rpc-host-daemon");return parseJson(await readFileOrUndefined(join4(flatDir,"layout.json")).catch(()=>{}))?.layout===HOST_DAEMON_LAYOUT?void 0:await readFileOrUndefined(join4(flatDir,"host.pid")).catch(()=>{})!==void 0?flatDir:void 0}export{tuiSocketName,socketNeedsHandshake,listHostEndpoints,endpointKindOfSocket,hostEnsureLockTarget,acquireHostEnsureLock,hostEnsureLockOptions,anyGenerationLive,gcHostEndpoints,gcEndpoint};
@@ -1,2 +1,2 @@
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{getProviderEnvValue}from"./chunk-5ROMKDLK.js";var CLAUDE_CODE_VERSION_PIN_ENV="PI_CLAUDE_CODE_VERSION",CLAUDE_RELEASE_CHANNEL_URL="https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases/latest",CLAUDE_NPM_DIST_TAG_URL="https://registry.npmjs.org/@anthropic-ai/claude-code/latest",REFRESH_INTERVAL_MS=360*60*1e3,FETCH_TIMEOUT_MS=5e3,EXACT_SEMVER=/^(\d+)\.(\d+)\.(\d+)$/,EMBEDDED_SEMVER=/(\d+\.\d+\.\d+)/,TOO_OLD_REJECTION=/claude_code_version_too_old|does not support this model; version (\d+\.\d+\.\d+) or newer/i;function compareClaudeCodeVersions(a,b){let left=a.split(".").map(Number),right=b.split(".").map(Number);for(let i=0;i<3;i++){let diff=(left[i]??0)-(right[i]??0);if(diff!==0)return diff}return 0}function isExactSemver(value){return typeof value=="string"&&EXACT_SEMVER.test(value)}function highest(candidates){let best;for(let candidate of candidates)isExactSemver(candidate)&&(best===void 0||compareClaudeCodeVersions(candidate,best)>0)&&(best=candidate);return best}async function fetchText(fetchImpl,url){try{let response=await fetchImpl(url,{signal:AbortSignal.timeout(FETCH_TIMEOUT_MS)});return response.ok?await response.text():void 0}catch{return}}async function fetchReleaseChannel(fetchImpl){let text=await fetchText(fetchImpl,CLAUDE_RELEASE_CHANNEL_URL);return text===void 0?void 0:EMBEDDED_SEMVER.exec(text.trim())?.[1]}async function fetchNpmDistTag(fetchImpl){let text=await fetchText(fetchImpl,CLAUDE_NPM_DIST_TAG_URL);if(text!==void 0)try{let data=JSON.parse(text),version=typeof data=="object"&&data!==null&&"version"in data?data.version:void 0;return typeof version=="string"?EMBEDDED_SEMVER.exec(version)?.[1]:void 0}catch{return}}async function fetchLatestClaudeCodeVersion(fetchImpl=fetch){return highest(await Promise.all([fetchReleaseChannel(fetchImpl),fetchNpmDistTag(fetchImpl)]))}function requiredClaudeCodeVersionFromError(message){let match=TOO_OLD_REJECTION.exec(message);if(match)return match[1]??/version (\d+\.\d+\.\d+) or newer/i.exec(message)?.[1]}function isClaudeCodeVersionTooOldError(error){return error instanceof Error&&"status"in error&&error.status===400&&TOO_OLD_REJECTION.test(error.message)}function createClaudeCodeVersionResolver(options){let{floor,store}=options,offline=options.offline===!0,fetchImpl=options.fetch??fetch,now=options.now??Date.now,refreshIntervalMs=options.refreshIntervalMs??REFRESH_INTERVAL_MS,pinned=isExactSemver(options.pinned)?options.pinned:void 0,loaded=!1,resolved,checkedAt=0,inflight,current=()=>resolved!==void 0&&compareClaudeCodeVersions(resolved,floor)>0?resolved:floor,loadCache=()=>{if(loaded||store===null)return;loaded=!0;let record=store.load();record&&isExactSemver(record.version)&&Number.isFinite(record.checkedAt)&&(resolved=record.version,checkedAt=record.checkedAt)},persist=()=>{store!==null&&resolved!==void 0&&store.save({version:resolved,checkedAt})},refresh=()=>pinned!==void 0||store===null?Promise.resolve(pinned??current()):(loadCache(),offline?Promise.resolve(current()):(inflight??=(async()=>{try{let latest=await fetchLatestClaudeCodeVersion(fetchImpl);checkedAt=now(),latest!==void 0&&(resolved===void 0||compareClaudeCodeVersions(latest,resolved)>0)&&(resolved=latest),persist()}finally{inflight=void 0}return current()})(),inflight));return{get(){return pinned!==void 0?pinned:(store===null||(loadCache(),!offline&&inflight===void 0&&now()-checkedAt>=refreshIntervalMs&&refresh()),current())},refresh,raise(version){return pinned!==void 0?pinned:(loadCache(),isExactSemver(version)&&compareClaudeCodeVersions(version,current())>0&&(resolved=version,persist()),current())}}}var installedStore=null,installedOffline=!1,defaultResolver,defaultFloor;function installClaudeCodeVersionStore(store,options={}){installedStore=store,installedOffline=options.offline===!0,defaultResolver=void 0}function resolver(floor){return(defaultResolver===void 0||defaultFloor!==floor)&&(defaultFloor=floor,defaultResolver=createClaudeCodeVersionResolver({floor,store:installedStore,offline:installedOffline})),defaultResolver}function pinnedClaudeCodeVersion(env){let pin=getProviderEnvValue(CLAUDE_CODE_VERSION_PIN_ENV,env)?.trim();return isExactSemver(pin)?pin:void 0}function getClaudeCodeVersion(floor,env){return pinnedClaudeCodeVersion(env)??resolver(floor).get()}async function recoverClaudeCodeVersion(error,floor,advertised,env){if(pinnedClaudeCodeVersion(env)!==void 0)return;let required=requiredClaudeCodeVersionFromError(error.message),next=required===void 0?await resolver(floor).refresh():resolver(floor).raise(required);return compareClaudeCodeVersions(next,advertised)>0?next:void 0}function claudeCodeVersionTooOldHint(advertised){return`senpi advertised claude-cli/${advertised}; Anthropic requires a newer Claude Code for this model. senpi refreshes the version automatically when online; set ${CLAUDE_CODE_VERSION_PIN_ENV}=X.Y.Z to advertise a specific one.`}var GATEWAY_NAMESPACE=/^mcp__(.+)$/i,GATEWAY_DELIMITER=/_{2,}/g,SERVER_NAMESPACE=/^mcp_([^_]+)_(.+)$/i;function foldToolName(name){return name.toLowerCase().replaceAll(/[-_]/g,"")}function toolNameForms(name){let forms=[name],gateway=GATEWAY_NAMESPACE.exec(name);if(gateway){let rest=gateway[1]??"";for(let run of rest.matchAll(GATEWAY_DELIMITER)){let suffix=rest.slice(run.index+run[0].length);run.index>0&&suffix.length>0&&forms.push(suffix)}return forms}let tool=SERVER_NAMESPACE.exec(name)?.[2];return tool!==void 0&&forms.push(tool),forms}function uniqueMatch(names,matches){let found=names.filter(matches);return found.length===1?found[0]:void 0}function resolveToolNameMatch(requested,available){let names=[...new Set(available)];for(let form of toolNameForms(requested)){if(names.includes(form))return form;let key=foldToolName(form),folded=uniqueMatch(names,name=>foldToolName(name)===key);if(folded!==void 0)return folded;let unprefixed=uniqueMatch(names,name=>toolNameForms(name).slice(1).some(registeredForm=>foldToolName(registeredForm)===key));if(unprefixed!==void 0)return unprefixed}}export{isClaudeCodeVersionTooOldError,installClaudeCodeVersionStore,getClaudeCodeVersion,recoverClaudeCodeVersion,claudeCodeVersionTooOldHint,resolveToolNameMatch};
2
+ import{getProviderEnvValue}from"./chunk-5ROMKDLK.js";var CLAUDE_CODE_VERSION_PIN_ENV="PI_CLAUDE_CODE_VERSION",CLAUDE_RELEASE_CHANNEL_URL="https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases/latest",CLAUDE_NPM_DIST_TAG_URL="https://registry.npmjs.org/@anthropic-ai/claude-code/latest",REFRESH_INTERVAL_MS=360*60*1e3,FETCH_TIMEOUT_MS=5e3,EXACT_SEMVER=/^(\d+)\.(\d+)\.(\d+)$/,EMBEDDED_SEMVER=/(\d+\.\d+\.\d+)/,TOO_OLD_REJECTION=/claude_code_version_too_old|does not support this model; version (\d+\.\d+\.\d+) or newer/i;function compareClaudeCodeVersions(a,b){let left=a.split(".").map(Number),right=b.split(".").map(Number);for(let i=0;i<3;i++){let diff=(left[i]??0)-(right[i]??0);if(diff!==0)return diff}return 0}function isExactSemver(value){return typeof value=="string"&&EXACT_SEMVER.test(value)}function highest(candidates){let best;for(let candidate of candidates)isExactSemver(candidate)&&(best===void 0||compareClaudeCodeVersions(candidate,best)>0)&&(best=candidate);return best}async function fetchText(fetchImpl,url){try{let response=await fetchImpl(url,{signal:AbortSignal.timeout(FETCH_TIMEOUT_MS)});return response.ok?await response.text():void 0}catch{return}}async function fetchReleaseChannel(fetchImpl){let text=await fetchText(fetchImpl,CLAUDE_RELEASE_CHANNEL_URL);return text===void 0?void 0:EMBEDDED_SEMVER.exec(text.trim())?.[1]}async function fetchNpmDistTag(fetchImpl){let text=await fetchText(fetchImpl,CLAUDE_NPM_DIST_TAG_URL);if(text!==void 0)try{let data=JSON.parse(text),version=typeof data=="object"&&data!==null&&"version"in data?data.version:void 0;return typeof version=="string"?EMBEDDED_SEMVER.exec(version)?.[1]:void 0}catch{return}}async function fetchLatestClaudeCodeVersion(fetchImpl=fetch){return highest(await Promise.all([fetchReleaseChannel(fetchImpl),fetchNpmDistTag(fetchImpl)]))}function requiredClaudeCodeVersionFromError(message){let match=TOO_OLD_REJECTION.exec(message);if(match)return match[1]??/version (\d+\.\d+\.\d+) or newer/i.exec(message)?.[1]}function isClaudeCodeVersionTooOldError(error){return error instanceof Error&&"status"in error&&error.status===400&&TOO_OLD_REJECTION.test(error.message)}function createClaudeCodeVersionResolver(options){let{floor,store}=options,offline=options.offline===!0,fetchImpl=options.fetch??fetch,now=options.now??Date.now,refreshIntervalMs=options.refreshIntervalMs??REFRESH_INTERVAL_MS,pinned=isExactSemver(options.pinned)?options.pinned:void 0,loaded=!1,resolved,checkedAt=0,inflight,current=()=>resolved!==void 0&&compareClaudeCodeVersions(resolved,floor)>0?resolved:floor,loadCache=()=>{if(loaded||store===null)return;loaded=!0;let record=store.load();record&&isExactSemver(record.version)&&Number.isFinite(record.checkedAt)&&(resolved=record.version,checkedAt=record.checkedAt)},persist=()=>{store!==null&&resolved!==void 0&&store.save({version:resolved,checkedAt})},refresh=()=>pinned!==void 0||store===null?Promise.resolve(pinned??current()):(loadCache(),offline?Promise.resolve(current()):(inflight??=(async()=>{try{let latest=await fetchLatestClaudeCodeVersion(fetchImpl);checkedAt=now(),latest!==void 0&&(resolved===void 0||compareClaudeCodeVersions(latest,resolved)>0)&&(resolved=latest),persist()}finally{inflight=void 0}return current()})(),inflight));return{get(){return pinned!==void 0?pinned:(store===null||(loadCache(),!offline&&inflight===void 0&&now()-checkedAt>=refreshIntervalMs&&refresh()),current())},refresh,raise(version){return pinned!==void 0?pinned:(loadCache(),isExactSemver(version)&&compareClaudeCodeVersions(version,current())>0&&(resolved=version,persist()),current())}}}var installedStore=null,installedOffline=!1,defaultResolver,defaultFloor;function installClaudeCodeVersionStore(store,options={}){installedStore=store,installedOffline=options.offline===!0,defaultResolver=void 0}function resolver(floor){return(defaultResolver===void 0||defaultFloor!==floor)&&(defaultFloor=floor,defaultResolver=createClaudeCodeVersionResolver({floor,store:installedStore,offline:installedOffline})),defaultResolver}function pinnedClaudeCodeVersion(env){let pin=getProviderEnvValue(CLAUDE_CODE_VERSION_PIN_ENV,env)?.trim();return isExactSemver(pin)?pin:void 0}function getClaudeCodeVersion(floor,env){return pinnedClaudeCodeVersion(env)??resolver(floor).get()}async function recoverClaudeCodeVersion(error,floor,advertised,env){if(pinnedClaudeCodeVersion(env)!==void 0)return;let required=requiredClaudeCodeVersionFromError(error.message),next=required===void 0?await resolver(floor).refresh():resolver(floor).raise(required);return compareClaudeCodeVersions(next,advertised)>0?next:void 0}function claudeCodeVersionTooOldHint(advertised){return`senpi advertised claude-cli/${advertised}; Anthropic requires a newer Claude Code for this model. senpi refreshes the version automatically when online; set ${CLAUDE_CODE_VERSION_PIN_ENV}=X.Y.Z to advertise a specific one.`}export{isClaudeCodeVersionTooOldError,installClaudeCodeVersionStore,getClaudeCodeVersion,recoverClaudeCodeVersion,claudeCodeVersionTooOldHint};
@@ -0,0 +1,30 @@
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{CUSTOM_UNSUPPORTED_CAPABILITY,EXTENSION_EVENTS_CAPABILITY,RPC_CLIENT_CAPABILITIES_ENV,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,hostLaunchProfile,socketHostLaunchProfile}from"./chunk-6SBY4ZWC.js";import{BUILTIN_PATH_PREFIX}from"./chunk-QMRJYMNH.js";import{acquireHostEnsureLock,anyGenerationLive,endpointKindOfSocket,gcEndpoint,gcHostEndpoints,hostEnsureLockOptions,hostEnsureLockTarget,listHostEndpoints,socketNeedsHandshake}from"./chunk-QKU6JOA4.js";import{compareEngineOrdinal,engineBuildIdentity}from"./chunk-ZJHRDQCH.js";import{external_exports}from"./chunk-KUPQO7MC.js";import{CHILD_KILL_EXIT_TIMEOUT_MS,CHILD_STOP_TIMEOUT_MS,INTERNAL_SUPERVISOR_FLAG,OBSERVE_REQUEST_FIELD,OWNER_WATCH_FD,isHostCrash,keepOwnerPipe,loopLagErrorMs,noteEscalatedStop,readHostCrashRecords,readStopIntent,resolveCliMainPath,runtimeExecArgv,writeStopIntent}from"./chunk-E75RO54O.js";import{DEFAULT_HOST_IDLE_EXIT_MS,HOST_DAEMON_DIR_ENV,HOST_STATE_FILE_MODE,MAX_SOCKET_PATH_BYTES,acquireOwnershipSafeLock,activeStopProgress,callerHostOwner,childStalledStopMaxMs,claimHostOwner,claimOwnerIsLive,clearHostRegistration,createDaemonDirectories,createHostDaemonPaths,createSocketSecret,ensureEndpointIdentity,generationBindPath,generationPaths,hostChildAlive,hostDaemonDirectoryPaths,hostLoopStalled,logUnknownHostIdentity,parseJson,parseShardSocket,provenOwner,pruneDeadGenerations,readFileOrUndefined,readGenerationRows,readHostOwner,readHostProcessMetrics,readHostRegistration,readHostSettings,readSessionPathClaims,readSocketSecret,releaseGeneration,resolveSocketTransportAddress,sameEndpoint,sameHostOwner,sendSocketHandshake,sessionDirectoryRemoved,shardKey,shardSocketPathForKey,socketSecretPath,stallRefusalWindowMs,statSocketIdentity,writeGenerationRecord,writeHostOwner,writeHostRegistration,writeHostSettings,writeStateFile,writtenByThisProcess}from"./chunk-NEFNNQSV.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV}from"./chunk-Q3R44CGT.js";import{ProcessIdentityUnreadableError,parseDaemonPidFile,processIsLive,processMatchesPidFile,readProcessStartTime,waitForStartTime}from"./chunk-ZRWOLP4E.js";import{isSessionRuntimeKind}from"./chunk-VE3D74HN.js";import{APP_NAME,ENV_AGENT_DIR,envValue,getAgentDir,isBunBinary}from"./chunk-463OK2Y4.js";import{writeSync}from"node:fs";import{join as join7,resolve as resolve3}from"node:path";import{readFile,realpath,stat}from"node:fs/promises";import{dirname,isAbsolute,relative,resolve}from"node:path";var SPEC_ENV_NAME=/^(SENPI|OMO|PI)_[A-Z0-9_]+$/u,HostLaunchSpecError=class extends Error{constructor(reason,detail){super(`${reason}: ${detail}`),this.name="HostLaunchSpecError",this.reason=reason,this.detail=detail}},DEFAULT_HOST_LAUNCH_SPEC={hostArgs:[],policy:{},env:{}};async function loadHostLaunchSpec(specPath,platform=process.platform){let absolute=resolve(specPath);await assertTrustedFile(absolute,platform);let spec=parseHostLaunchSpec(await readSpecText(absolute)),env=trustedEnv(spec.env),extensions=await resolveExtensions(spec.core.extensions,dirname(absolute));return{hostArgs:["--session-runtime",spec.core.session_runtime,...extensions.flatMap(path=>["--extension",path])],policy:{...spec.tunables?.idleExitMs!==void 0&&{idleExitMs:spec.tunables.idleExitMs},...spec.tunables?.coldStart!==void 0&&{coldStart:spec.tunables.coldStart}},env}}function parseHostLaunchSpec(text){let parsed;try{parsed=JSON.parse(text)}catch(error){throw new HostLaunchSpecError("launch_spec_invalid",error instanceof Error?error.message:"not JSON")}if(!isRecord(parsed))throw new HostLaunchSpecError("launch_spec_invalid","the spec is not a JSON object");if(parsed.spec_version!==1)throw new HostLaunchSpecError("launch_spec_invalid",`unsupported spec_version ${String(parsed.spec_version)}`);let core=parsed.core;if(!isRecord(core))throw new HostLaunchSpecError("launch_spec_invalid","core must be an object");if(typeof core.session_runtime!="string"||!isSessionRuntimeKind(core.session_runtime))throw new HostLaunchSpecError("launch_spec_invalid","core.session_runtime must be in-process or worker");if(core.multi_session!==!0)throw new HostLaunchSpecError("launch_spec_invalid","core.multi_session must be true");if(!Array.isArray(core.extensions)||!core.extensions.every(entry=>typeof entry=="string"))throw new HostLaunchSpecError("launch_spec_invalid","core.extensions must be an array of strings");let tunables=parsedTunables(parsed.tunables);return{spec_version:1,core:{session_runtime:core.session_runtime,multi_session:!0,extensions:core.extensions},...tunables&&{tunables},...isRecord(parsed.env)&&{env:parsedEnv(parsed.env)}}}async function readSpecText(absolute){try{return await readFile(absolute,"utf8")}catch(error){throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}}async function assertTrustedFile(absolute,platform){if(platform==="win32")return;let stats=await stat(absolute).catch(error=>{throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}),uid=process.getuid?.();if(uid!==void 0&&stats.uid!==uid)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is owned by uid ${stats.uid}, not ${uid}`);if((stats.mode&18)!==0)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is group/world writable (mode ${(stats.mode&511).toString(8)})`)}function trustedEnv(env){for(let name of Object.keys(env??{}))if(!SPEC_ENV_NAME.test(name))throw new HostLaunchSpecError("launch_spec_env_denied",`${name} is outside ${SPEC_ENV_NAME.source}`);return env??{}}async function resolveExtensions(extensions,specDir){let rootReal=await realpath(specDir).catch(()=>specDir),resolved=[];for(let entry of extensions){let target=resolve(specDir,entry);if(escapes(specDir,target))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} resolves outside ${specDir}`);let real=await realpath(target).catch(()=>{});if(real===void 0)throw new HostLaunchSpecError("launch_spec_missing_extension",`${target} does not exist`);if(escapes(rootReal,real))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} links outside ${specDir}`);resolved.push(real)}return resolved}function escapes(root,target){let step=relative(root,target);return step.startsWith("..")||isAbsolute(step)}function parsedTunables(value){if(!isRecord(value))return;let idleExitMs=value.idleExitMs,coldStart=value.coldStart;return{...typeof idleExitMs=="number"&&Number.isFinite(idleExitMs)&&idleExitMs>0&&{idleExitMs},...(coldStart==="transient"||coldStart==="persistent")&&{coldStart}}}function parsedEnv(value){let env={};for(let[name,entry]of Object.entries(value)){if(typeof entry!="string")throw new HostLaunchSpecError("launch_spec_invalid",`env.${name} must be a string`);env[name]=entry}return env}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{join}from"node:path";var ALLOWED_ENV_NAMES=[/^(PATH|HOME|USER|LOGNAME|SHELL|TMPDIR|TERM|LANG)$/u,/^(LC|XDG)_/u,/^(SENPI|OMO|PI)_/u,/^BSK_(HOME|BIN)$/u,/^(HTTPS?_PROXY|NO_PROXY)$/u,/^[A-Z0-9_]+_API_KEY$/u,/^(ANTHROPIC|OPENAI|GOOGLE|GEMINI|AZURE|AWS|OPENROUTER|XAI|MISTRAL|DEEPSEEK|GROQ|CEREBRAS|MINIMAX)_/u],WINDOWS_SYSTEM_ENV_NAMES=new Set(["SYSTEMROOT","SYSTEMDRIVE","WINDIR","COMSPEC","PATHEXT","TEMP","TMP","USERPROFILE","APPDATA","LOCALAPPDATA","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","HOMEDRIVE","HOMEPATH","NUMBER_OF_PROCESSORS","PROCESSOR_ARCHITECTURE","OS"]),TRANSIENT_ENV_NAMES=new Set(["PI_SESSION_ID","PI_SESSION_FILE","PI_SESSION_CWD","PI_GOAL_STORE_FILE","PI_PROVIDER","PI_MODEL","PI_REASONING_LEVEL","OMO_BROWSER_ENGINE","PI_PROMPT_CACHE_SAFE_WAIT_SECONDS","SENPI_PY_KERNEL_PARENT_PID","SENPI_RPC_HOST_WATCH_FD","SENPI_RPC_HOST_WATCH_PPID","SENPI_RPC_HOST_SCRATCH_DIR","SENPI_RPC_HOST_CLEANUP_PATHS","SENPI_RPC_HOST_PUBLIC_SOCKET","SENPI_RPC_HOST_INSTANCE_ID","SENPI_RPC_HOST_GENERATION","SENPI_RPC_HOST_DAEMON_DIR","SENPI_RPC_HOST_EXPECTED_RUNTIME_BUILD_ID"]);function daemonEnvIsAllowed(name,platform=process.platform){let upper=name.toUpperCase();return TRANSIENT_ENV_NAMES.has(platform==="win32"?upper:name)?!1:platform!=="win32"?ALLOWED_ENV_NAMES.some(pattern=>pattern.test(name)):WINDOWS_SYSTEM_ENV_NAMES.has(upper)||ALLOWED_ENV_NAMES.some(pattern=>pattern.test(upper))}function daemonEnvOverrides(processEnv,specEnv={},platform=process.platform){let overrides={};for(let name of Object.keys(processEnv))daemonEnvIsAllowed(name,platform)||(overrides[name]=null);for(let[name,value]of Object.entries(specEnv))daemonEnvIsAllowed(name,platform)&&(overrides[name]=value);return overrides}function daemonEnvironment(processEnv,overrides={},forced={},platform=process.platform){let env={};for(let[name,value]of Object.entries(processEnv))value!==void 0&&daemonEnvIsAllowed(name,platform)&&(env[name]=value);for(let[name,value]of Object.entries(overrides))daemonEnvIsAllowed(name,platform)&&(deleteEnvironmentName(env,name,platform),value!==null&&(env[name]=value));for(let[name,value]of Object.entries(forced))deleteEnvironmentName(env,name,platform),env[name]=value;return env}function daemonEnvKeys(processEnv,specEnv={},platform=process.platform){let kept=Object.keys(processEnv).filter(name=>daemonEnvIsAllowed(name,platform)),explicit=Object.keys(specEnv).filter(name=>daemonEnvIsAllowed(name,platform));return[...new Set([...kept,...explicit])].sort()}async function writeDaemonEnvKeys(paths,keys){await writeStateFile(daemonEnvKeysFile(paths),{env_keys:keys})}async function readDaemonEnvKeys(paths){let keys=parseJson(await readFileOrUndefined(daemonEnvKeysFile(paths)))?.env_keys;return Array.isArray(keys)?keys.filter(key=>typeof key=="string"):[]}function daemonEnvKeysFile(paths){return join(paths.dir,"env-keys.json")}function deleteEnvironmentName(env,name,platform){if(platform!=="win32"){delete env[name];return}let upper=name.toUpperCase();for(let existing of Object.keys(env))existing.toUpperCase()===upper&&delete env[existing]}import{createHash}from"node:crypto";import{existsSync}from"node:fs";import{readdir,readFile as readFile2,realpath as realpath2,stat as stat2}from"node:fs/promises";import{basename,dirname as dirname2,join as join2,relative as relative2,sep}from"node:path";import{fileURLToPath}from"node:url";var RUNTIME_IDENTITY_HANDOVER_CAPABILITY="runtime_identity_handover",RUNTIME_BUILD_ID=/^sha256:[0-9a-f]{64}$/,EXCLUDED_FILE=/\.(?:d\.[cm]?ts|map)$/,EXCLUDED_NAMES=new Set(["node_modules","runtime-manifest.json","runtime-snapshot.json"]),READ_CONCURRENCY=32;function parseRuntimeBuildId(value){return typeof value=="string"&&RUNTIME_BUILD_ID.test(value)?value:void 0}async function computeRuntimeBuildId(input){let source=input.source??loadedRuntimeSource(),plugins=await Promise.all(input.profile.extensions.map(path=>extensionDigest(path))),manifest={schema:1,flavour:source.flavour,platform:input.platform??process.platform,arch:input.arch??process.arch,engine:input.engine??engineBuildIdentity().text,runtime:await treeDigest(source.root),plugins:plugins.sort(),profile:{multi_session:input.profile.multi_session,session_runtime:input.profile.session_runtime}};return`sha256:${sha256(JSON.stringify(manifest))}`}function loadedRuntimeSource(){if(isBunBinary)return{flavour:"compiled",root:process.execPath};let moduleDir=dirname2(fileURLToPath(import.meta.url)),packageRoot=nearestPackageRoot(moduleDir),[top,next]=relative2(packageRoot,moduleDir).split(sep);return top==="dist"?{flavour:"packaged",root:join2(packageRoot,next==="bundle"?join2("dist","bundle"):"dist")}:{flavour:"dev",root:join2(packageRoot,top??"")}}function nearestPackageRoot(start){for(let dir=start;;dir=dirname2(dir)){if(existsSync(join2(dir,"package.json")))return dir;if(dirname2(dir)===dir)return start}}function extensionDigest(path){let name=basename(path);return name.startsWith(BUILTIN_PATH_PREFIX)?Promise.resolve(sha256(name)):treeDigest(path)}async function treeDigest(root){let files=[];(await stat2(root)).isFile()?files.push(["",root]):await collect(await realpath2(root),"",files,new Set);let digests=await mapLimited(files,READ_CONCURRENCY,async([path,file])=>[path,sha256(await readFile2(file))]);return digests.sort(([a],[b])=>a<b?-1:a>b?1:0),sha256(JSON.stringify(digests))}async function collect(dir,prefix,files,seen){if(seen.has(dir))return;seen.add(dir);let entries=(await readdir(dir,{withFileTypes:!0})).sort((a,b)=>a.name<b.name?-1:a.name>b.name?1:0);for(let entry of entries){if(entry.name.startsWith(".")||EXCLUDED_NAMES.has(entry.name))continue;let path=join2(dir,entry.name),name=prefix===""?entry.name:`${prefix}/${entry.name}`,kind=entry.isSymbolicLink()?await stat2(path).catch(()=>{}):entry;kind!==void 0&&(kind.isDirectory()?await collect(await realpath2(path),name,files,seen):kind.isFile()&&!EXCLUDED_FILE.test(entry.name)&&files.push([name,path]))}}async function mapLimited(items,limit,map){let results=new Array(items.length),next=0,worker=async()=>{for(let index=next++;index<items.length;index=next++)results[index]=await map(items[index])};return await Promise.all(Array.from({length:Math.min(limit,items.length)},worker)),results}function sha256(data){return createHash("sha256").update(data).digest("hex")}function parseHostProtocolInfo(data){if(!isRecord2(data)||typeof data.serverVersion!="string"||!Array.isArray(data.capabilities)||!data.capabilities.every(entry=>typeof entry=="string"))return;let ordinal=parseOrdinal(data.engineOrdinal),launchProfile=parseLaunchProfile(data.launch_profile),runtimeBuildId=parseRuntimeBuildId(data.runtimeBuildId);return{protocolVersion:typeof data.protocolVersion=="number"?data.protocolVersion:0,serverVersion:data.serverVersion,capabilities:data.capabilities,...typeof data.instanceId=="string"&&{instanceId:data.instanceId},...typeof data.generation=="number"&&Number.isSafeInteger(data.generation)&&{generation:data.generation},...typeof data.engineVersion=="string"&&{engineVersion:data.engineVersion},...ordinal&&{engineOrdinal:ordinal},...launchProfile&&{launch_profile:launchProfile},...typeof data.memory_pressure=="boolean"&&{memory_pressure:data.memory_pressure},...runtimeBuildId!==void 0&&{runtimeBuildId},...isRecord2(data.handover)&&{handover:data.handover}}}function parseOrdinal(value){if(!(!Array.isArray(value)||value.length!==5||!value.every(part=>typeof part=="number")))return[value[0],value[1],value[2],value[3],value[4]]}function parseLaunchProfile(value){if(!isRecord2(value)||typeof value.profile_id!="string"||!isRecord2(value.core))return;let{extensions,multi_session,session_runtime}=value.core;if(!(!Array.isArray(extensions)||!extensions.every(entry=>typeof entry=="string"))&&typeof multi_session=="boolean"&&!(session_runtime!=="in-process"&&session_runtime!=="worker"))return{profile_id:value.profile_id,core:{extensions,multi_session,session_runtime}}}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var HOST_PROTOCOL_VERSION=1,GENERATION_HANDOFF_CAPABILITY="generation_handoff",REQUIRED_HOST_CAPABILITIES=["multi_session",EXTENSION_EVENTS_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY],HostEnsureRefusedError=class extends Error{constructor(socket,reason,host,detail){super(`RPC socket ${socket} refused: ${reason} - ${refusalDetail(reason,host)}${detail?`: ${detail}`:""}`),this.name="HostEnsureRefusedError",this.socket=socket,this.reason=reason,this.detail=detail}};function refusalDetail(reason,host){switch(reason){case"protocol":return`the running host speaks protocol version ${host?.protocolVersion??"unknown"}, this build speaks ${HOST_PROTOCOL_VERSION}`;case"capability":{let missing=REQUIRED_HOST_CAPABILITIES.filter(capability=>!host?.capabilities.includes(capability));return`the running host is missing ${JSON.stringify(missing)}; it owns the socket, so no second host is started`}case"foreign_writer":return"its pidfile was written by another process, so this one may not signal it; stop that host explicitly instead";case"legacy_host":return"a host from before the per-socket daemon directory is still running; it is drained and replaced only while it holds no session, and no second host is started beside it";case"host_busy":return"its socket accepts connections but did not answer inside the probe budget: a live host under load, which is never ended to make room for a replacement";case"host_stalled":return"nothing reaches its socket, but its process is alive and its own loop-lag watchdog measured a recent stall: a stalled host is still serving its sessions, so it is neither stopped nor replaced";default:return assertNever(reason)}}function decideHostAction(client,host,policy){if(host===void 0)return{action:"start",reason:client.startedByUs?"restart_own_host":"no_host",upgradeable:!1};if(host.protocolVersion!==client.protocolVersion)return{action:"refuse",reason:"protocol",upgradeable:!1};if(!client.requiredCapabilities.every(capability=>host.capabilities.includes(capability)))return policy==="fallback"?{action:"fallback",reason:"capability",upgradeable:!1}:{action:"refuse",reason:"capability",upgradeable:!1};let upgradeable=client.platform!=="win32"&&host.capabilities.includes(GENERATION_HANDOFF_CAPABILITY);if(policy==="fallback"&&host.engineVersion!==client.identity.text)return{action:"fallback",reason:"engine_mismatch",upgradeable};let warning=profileWarning(client,host);return client.platform==="win32"?{action:"reuse",reason:"win32_attach_only",upgradeable:!1,...warning&&{warning}}:upgradeable?policy==="upgrade"&&client.launchProfile&&host.launch_profile&&supersedes(client,host)?{action:"handoff",reason:sameRelease(client.identity.ordinal,host.engineOrdinal)?"profile":"newer_engine",upgradeable:!0}:{action:"reuse",reason:"compatible",upgradeable,...warning&&{warning}}:{action:"reuse",reason:"handoff_unsupported",upgradeable:!1,...warning&&{warning}}}function supersedes(client,host){if(host.engineOrdinal===void 0)return!1;let hostIdentity={text:host.engineVersion??"",ordinal:host.engineOrdinal,scheme:host.engineOrdinal[4]>0?"epoch":"nodef"};return compareEngineOrdinal(client.identity,hostIdentity)<=0?!1:covers(client.launchProfile,host.launch_profile)}function profileWarning(client,host){if(client.launchProfile===void 0||host.launch_profile===void 0)return"profile_mismatch_attached";if(client.launchProfile.profile_id===host.launch_profile.profile_id)return;let clientCoversHost=covers(client.launchProfile,host.launch_profile);if(!(clientCoversHost&&covers(host.launch_profile,client.launchProfile)))return clientCoversHost?"profile_mismatch_attached":"profile_narrower_attached"}function extensionRole(extension){let segments=extension.split(/[\\/]+/),pluginAt=segments.lastIndexOf("plugin");return pluginAt<0?extension:segments.slice(pluginAt).join("/")}function covers(candidate,running){if(candidate===void 0||running===void 0)return!1;let candidateRoles=new Set(candidate.core.extensions.map(extensionRole));return running.core.extensions.every(extension=>candidateRoles.has(extensionRole(extension)))}function sameRelease(candidate,running){return running!==void 0&&candidate.slice(0,4).every((part,index)=>part===running[index])}function assertNever(value){throw new Error(`unreachable host decision: ${JSON.stringify(value)}`)}import{mkdir,writeFile as writeFile3}from"node:fs/promises";import{dirname as dirname5}from"node:path";function ensureClient(options,startedByUs){return{protocolVersion:HOST_PROTOCOL_VERSION,requiredCapabilities:REQUIRED_HOST_CAPABILITIES,identity:engineBuildIdentity(),...options.upgrade==="if-engine-differs"?{launchProfile:hostLaunchProfile(hostChildArgv(options.hostArgs??[]),process.cwd())}:{},startedByUs,platform:process.platform}}function hostChildArgv(hostArgs){return["--mode","rpc","--multi-session",...hostArgs]}function isCompatible(protocol){return decideHostAction(ensureClient({socket:""},!1),protocol,"never").action==="reuse"}import{createConnection}from"node:net";function holdAttachment(socket){return socket.removeAllListeners("data"),socket.resume(),socket.on("error",()=>socket.destroy()),socket.unref(),{release:()=>socket.destroy()}}var DEFAULT_PROBE_TIMEOUT_MS=1e4,PROBE_REQUEST_ID="ensure-host-probe";function probeHost(options){return probeProtocolInfo(options.socket,options.timeoutMs??DEFAULT_PROBE_TIMEOUT_MS)}async function probeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info"},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function observeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function holdProtocolInfo(socketPath,timeoutMs){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs,!0),info=outcome.answer===void 0?void 0:parseHostProtocolInfo(outcome.answer);if(outcome.kept===void 0)return;let hold=holdAttachment(outcome.kept);if(info!==void 0)return{info,hold};hold.release()}async function probeSocketReachable(socketPath,timeoutMs){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs)).connected}async function probeSessionCount(socketPath,timeoutMs){return sessionCountOf(await requestOnSocket(socketPath,{type:"list_sessions",include_workers:!0},timeoutMs))}async function holdSessionCount(socketPath,timeoutMs){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"list_sessions",include_workers:!0},timeoutMs,!0),kept=outcome.kept;if(kept===void 0)return;let sessions=sessionCountOf(outcome.answer);if(sessions===void 0){kept.destroy();return}let asked=0;return{sessions,recount:recountTimeoutMs=>askAgain(kept,`${PROBE_REQUEST_ID}-recount-${++asked}`,recountTimeoutMs),close:()=>kept.destroy()}}function askAgain(socket,id,timeoutMs){return new Promise(resolveCount=>{let buffer="",finish=count=>{clearTimeout(timeout),socket.off("data",onData),socket.off("close",onClose),resolveCount(count)},onClose=()=>finish(void 0),onData=chunk=>{buffer+=chunk.toString("utf8");for(let newline=buffer.indexOf(`
3
+ `);newline!==-1;newline=buffer.indexOf(`
4
+ `)){let answer2=readAnswer(buffer.slice(0,newline),id);if(buffer=buffer.slice(newline+1),answer2!==void 0){finish(sessionCountOf(answer2));return}}},timeout=setTimeout(()=>finish(void 0),timeoutMs);if(socket.destroyed){finish(void 0);return}socket.on("data",onData),socket.once("close",onClose),socket.write(`${JSON.stringify({id,type:"list_sessions",include_workers:!0})}
5
+ `)})}function sessionCountOf(reply){return isRecord3(reply)&&Array.isArray(reply.sessions)?reply.sessions.length:void 0}async function requestOnSocket(socketPath,command,timeoutMs){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,...command},timeoutMs)).answer}async function connectAndAsk(socketPath,request,timeoutMs,keep=!1){let secret;if(socketNeedsHandshake(socketPath))try{secret=await readSocketSecret(socketSecretPath(socketPath))}catch{return{connected:!1,answer:void 0}}return new Promise(resolveProbe=>{let socket=createConnection(resolveSocketTransportAddress(socketPath,process.platform,secret)),buffer="",settled=!1,connected=!1,finish=value=>{if(!settled){if(settled=!0,clearTimeout(timeout),keep&&value!==void 0&&!socket.destroyed){resolveProbe({connected,answer:value,kept:socket});return}socket.destroy(),resolveProbe({connected,answer:value})}},timeout=setTimeout(()=>finish(),timeoutMs);socket.once("connect",()=>{connected=!0,socket.write(`${JSON.stringify(request)}
6
+ `)}),socket.on("data",chunk=>{for(buffer+=chunk.toString("utf8");;){let newline=buffer.indexOf(`
7
+ `);if(newline===-1)return;let line=buffer.slice(0,newline);buffer=buffer.slice(newline+1);let answer2=readAnswer(line);if(answer2!==void 0)return finish(answer2)}}),socket.once("error",()=>finish()),socket.once("close",()=>finish()),secret&&sendSocketHandshake(socket,secret)})}function readAnswer(text,id=PROBE_REQUEST_ID){let parsed;try{parsed=JSON.parse(text)}catch{return}if(!(!isRecord3(parsed)||parsed.id!==id||parsed.success!==!0))return parsed.data??{}}function isRecord3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}async function refuseIfStalled(paths,instanceId,socket,protocol){let generation=generationPaths(paths,instanceId);if(await hostLoopStalled(generation,{now:Date.now(),errorMs:loopLagErrorMs(),windowMs:stallRefusalWindowMs()})&&await hostChildAlive(generation)!==!1)throw new HostEnsureRefusedError(socket,"host_stalled",protocol)}var FOREIGN_ENDPOINT_PROBE_TIMEOUT_MS=2e3;async function publicEndpointAccepts(socket){if(process.platform==="win32"||socket.startsWith("\0"))return!0;let entry=await statSocketIdentity(socket).then(identity=>identity===void 0?"absent":"present",()=>"unknown");return entry==="absent"?!1:entry==="unknown"?!0:probeSocketReachable(socket,FOREIGN_ENDPOINT_PROBE_TIMEOUT_MS)}import{spawn}from"node:child_process";import{randomUUID}from"node:crypto";import{open,readFile as readFile3}from"node:fs/promises";var DEFAULT_STOP_TIMEOUT_MS=Math.max(CHILD_STOP_TIMEOUT_MS,childStalledStopMaxMs())+CHILD_KILL_EXIT_TIMEOUT_MS+5e3,SIGKILL_GRACE_MS=2e3,STOP_PROGRESS_FRESH_MS=1e4,AFTER_STALL_WAIT_GRACE_MS=CHILD_KILL_EXIT_TIMEOUT_MS+5e3,STOP_WAIT_BUDGET_MS=Math.max(DEFAULT_STOP_TIMEOUT_MS,childStalledStopMaxMs()+AFTER_STALL_WAIT_GRACE_MS)+SIGKILL_GRACE_MS;function ensureSender(){return{pid:process.pid,kind:"ensure"}}async function announceStop(target,targetPid){let intent={sender:target.sender,targetPid,reason:target.reason,signal:"SIGTERM",at:new Date().toISOString()};return await writeStopIntent(target.generation,intent),intent}async function matchesPidFileOrUnknown(pidFile,probe){try{return await processMatchesPidFile(pidFile,probe)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!1;throw error}}async function recordEscalation(target,announced){let current=await readStopIntent(target.generation).catch(()=>{});await noteEscalatedStop(target.daemonDir,target.instanceId,current??announced)}async function stopSpawnedChild(child,childExit,termTimeoutMs,target){let exited=()=>child.exitCode!==null||child.signalCode!==null,pid=child.pid;if(exited()||pid===void 0)return;let waitFor=async ms=>{let timer;try{return await Promise.race([childExit.then(()=>!0),new Promise(resolve4=>{timer=setTimeout(()=>resolve4(exited()),ms)})])}finally{clearTimeout(timer)}},announced=await announceStop(target,pid);if(signalPid(pid,"SIGTERM"),!await waitWhileSupervisorReports(target,termTimeoutMs,waitFor)){if(signalPid(pid,"SIGKILL"),!await waitFor(SIGKILL_GRACE_MS))throw new Error(`RPC socket host pid ${pid} remained alive after SIGKILL`);await recordEscalation(target,announced)}}async function stopManagedHost(pidFile,termTimeoutMs,target,readStartTime=readProcessStartTime){let announced=await announceStop(target,pidFile.pid);if(await signalValidated(pidFile,"SIGTERM",readStartTime),!await waitWhileSupervisorReports(target,termTimeoutMs,ms=>waitForGone(pidFile,ms,readStartTime))){if(await signalValidated(pidFile,"SIGKILL",readStartTime),!await waitForGone(pidFile,SIGKILL_GRACE_MS,readStartTime))throw new Error(`RPC socket host pid ${pidFile.pid} remained alive after SIGKILL`);await recordEscalation(target,announced)}}async function waitWhileSupervisorReports(target,termTimeoutMs,waitFor){if(await waitFor(termTimeoutMs))return!0;let extended=!1;for(;;){let untilAt=await activeStopProgress(target.generation,Date.now(),STOP_PROGRESS_FRESH_MS);if(untilAt===void 0)return extended&&await waitFor(AFTER_STALL_WAIT_GRACE_MS);if(extended=!0,await waitFor(Math.min(STOP_PROGRESS_FRESH_MS,Math.max(1,untilAt-Date.now()))))return!0}}async function resolvePidFileOwnership(pidFile,readStartTime=readProcessStartTime){try{return await processMatchesPidFile(pidFile,readStartTime,processIsLive,{attempts:1})?"owns":"gone"}catch(error){if(error instanceof ProcessIdentityUnreadableError)return"unknown";throw error}}async function signalValidated(pidFile,signal,readStartTime=readProcessStartTime){await resolvePidFileOwnership(pidFile,readStartTime)==="owns"&&signalPid(pidFile.pid,signal)}async function waitForGone(pidFile,timeoutMs,readStartTime=readProcessStartTime){let deadline=Date.now()+timeoutMs;for(;Date.now()<=deadline;){if(await resolvePidFileOwnership(pidFile,readStartTime)==="gone")return!0;await delay(50)}return await resolvePidFileOwnership(pidFile,readStartTime)==="gone"}function signalPid(pid,signal){try{process.kill(pid,signal)}catch(error){if(!isNodeErrorCode(error,"ESRCH"))throw error}}function delay(ms){return new Promise(resolveDelay=>setTimeout(resolveDelay,ms))}function isNodeErrorCode(error,code){return error instanceof Error&&"code"in error&&error.code===code}import{existsSync as existsSync2}from"node:fs";import{basename as basename2,dirname as dirname3,resolve as resolve2}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";var PINNED_HOST_CLIENT_CAPABILITIES=[EXTENSION_EVENTS_CAPABILITY,CUSTOM_UNSUPPORTED_CAPABILITY];function defaultHostLaunch(supervisorArgs,compiled=isBunBinary,sibling=resolveHostLifecycleEntryPath()??null){return compiled?{command:process.execPath,args:[INTERNAL_SUPERVISOR_FLAG,...supervisorArgs]}:sibling!==null?{command:process.execPath,args:[...runtimeExecArgv(),sibling,...supervisorArgs]}:{command:process.execPath,args:[...runtimeExecArgv(),resolveCliMainPath(),INTERNAL_SUPERVISOR_FLAG,...supervisorArgs]}}function resolveHostLifecycleEntryPath(){let modulePath=fileURLToPath2(import.meta.url);if(basename2(dirname3(modulePath))==="chunks")return;let extension=modulePath.endsWith(".ts")?".ts":".js",sibling=resolve2(dirname3(modulePath),`host-lifecycle${extension}`);return existsSync2(sibling)?sibling:void 0}var SPAWNED_HOST_PROBE_TIMEOUT_MS=1e4;async function pollProtocolInfo(socket,timeoutMs,isCompatible2,childExit){let deadline=Date.now()+timeoutMs,lastProtocol;for(;Date.now()<=deadline;){let probe=holdProtocolInfo(socket,Math.min(SPAWNED_HOST_PROBE_TIMEOUT_MS,Math.max(1,deadline-Date.now()))),raced=childExit?await Promise.race([probe,childExit]):await probe;if(isChildExit(raced)){let held=await probe;if(!held)return{ready:!1,protocol:lastProtocol,exited:raced};if(lastProtocol=held.info,isCompatible2(held.info))return{ready:!0,protocol:held.info,hold:held.hold};held.hold.release()}else if(raced){if(lastProtocol=raced.info,isCompatible2(raced.info))return{ready:!0,protocol:raced.info,hold:raced.hold};raced.hold.release()}await delay2(50)}return{ready:!1,protocol:lastProtocol}}function isChildExit(value){return!!value&&"code"in value&&"signal"in value}function delay2(ms){return new Promise(resolveDelay=>setTimeout(resolveDelay,ms))}var EXPECTED_RUNTIME_BUILD_ID_ENV="SENPI_RPC_HOST_EXPECTED_RUNTIME_BUILD_ID",NEW_WORK_COMMANDS=new Set(["prompt","steer","follow_up","send_custom_message","continue_from_leaf","append_user_message","bash","compact","wake","edit_assistant_message","edit_user_message"]),DEFAULT_POLL_MS=200,HostIdleHandover=class{constructor(options){this.options=options}view(){return this.operation?.view}admits(commandType){let state=this.operation?.view.state;return state===void 0||state==="handover_blocked"||!NEW_WORK_COMMANDS.has(commandType)}async begin(request){let current=this.operation;if(current!==void 0&&current.view.operationId===request.operationId)return sameTerms(current.request,request)?answer(current):{kind:"refused",reason:"operation_conflict",detail:"this operation id names other terms"};if(current!==void 0&&current.view.state!=="handover_blocked")return current.request.targetRuntimeBuildId===request.targetRuntimeBuildId?answer(current):{kind:"refused",reason:"handover_in_progress",detail:current.view.operationId};let self=this.options.identity();if(self.instanceId!==request.ifInstanceId||self.generation!==request.ifGeneration)return{kind:"refused",reason:"stale_generation",detail:`this host is ${self.instanceId} generation ${self.generation}`};if(self.runtimeBuildId===request.targetRuntimeBuildId)return{kind:"refused",reason:"already_current",detail:self.runtimeBuildId};let operation={request,view:{operationId:request.operationId,state:"handover_pending",targetRuntimeBuildId:request.targetRuntimeBuildId}};return this.operation=operation,this.options.log?.(`handover ${request.operationId} pending: no new work is admitted`),this.idleNow()?(await this.switchOver(operation),answer(operation)):(this.timer=setInterval(()=>this.observe(),this.options.pollMs??DEFAULT_POLL_MS),this.timer.unref?.(),answer(operation))}observe(){let operation=this.operation;operation?.view.state==="handover_pending"&&this.idleNow()&&this.switchOver(operation)}dispose(){this.stopTimer()}idleNow(){try{return this.options.isIdle()}catch(cause){return this.options.log?.(`handover idle check failed, waiting: ${String(cause)}`),!1}}async switchOver(operation){if(operation.view.state!=="handover_pending")return;this.stopTimer(),operation.view={...operation.view,state:"handover_switching"};let outcome=await this.options.perform(operation.request).catch(cause=>({ok:!1,reason:`successor_unavailable: ${String(cause)}`}));operation.view=outcome.ok?{...operation.view,state:"handover_completed",successor:outcome.successor}:{...operation.view,state:"handover_blocked",reason:outcome.reason},this.options.log?.(`handover ${operation.view.operationId} ${operation.view.state}`)}stopTimer(){this.timer!==void 0&&clearInterval(this.timer),this.timer=void 0}};function sameTerms(a,b){return a.targetRuntimeBuildId===b.targetRuntimeBuildId&&a.ifInstanceId===b.ifInstanceId&&a.ifGeneration===b.ifGeneration}function answer(operation){return{kind:"operation",view:operation.view}}function initialHostEnvironment(options){return daemonEnvironment(process.env,options.env,{[ENV_AGENT_DIR]:options.agentDir??getAgentDir(),[RPC_CLIENT_CAPABILITIES_ENV]:PINNED_HOST_CLIENT_CAPABILITIES.join(","),[HOST_INSTANCE_ID_ENV]:options.instanceId,[HOST_GENERATION_ENV]:String(options.generation),[HOST_DAEMON_DIR_ENV]:options.paths.dir})}function successorHostEnvironment(options){return daemonEnvironment(process.env,options.env,{[RPC_CLIENT_CAPABILITIES_ENV]:PINNED_HOST_CLIENT_CAPABILITIES.join(","),...options.agentDir?{[ENV_AGENT_DIR]:options.agentDir}:{},[HOST_INSTANCE_ID_ENV]:options.instanceId,[HOST_GENERATION_ENV]:String(options.generation),[HOST_DAEMON_DIR_ENV]:options.paths.dir,...options.expectedRuntimeBuildId!==void 0&&{[EXPECTED_RUNTIME_BUILD_ID_ENV]:options.expectedRuntimeBuildId}})}var DEFAULT_READINESS_TIMEOUT_MS=1e4;async function startHost(paths,socket,options,generation=0){let testOptions=options._test,lifetimeOwner=options.owner?await callerHostOwner():null,instanceId=randomUUID(),stopTarget=reason=>({daemonDir:paths.dir,generation:generationPaths(paths,instanceId),instanceId,sender:ensureSender(),reason});process.platform==="win32"&&await createSocketSecret(socketSecretPath(socket)),await writeHostSettings(paths,{socket,capabilities:PINNED_HOST_CLIENT_CAPABILITIES,coldStart:options.policy?.coldStart??"transient",idleExitMs:options.policy?.idleExitMs??9e5,generation,instanceId}),await writeHostOwner(generationPaths(paths,instanceId).dir,lifetimeOwner);let stderr=await open(paths.stderrLog,generation===0?"w":"a",384),pidFile,child,exitedEarly,childExit;try{let supervisorArgs=["--socket",socket,...options.owner?["--owner-fd",String(OWNER_WATCH_FD)]:[],...options.hostArgs??[]],launch=testOptions?.spawn??testOptions?.launch?.(supervisorArgs)??defaultHostLaunch(supervisorArgs);if(child=spawn(launch.command,[...launch.args],{detached:!0,windowsHide:!0,env:initialHostEnvironment({agentDir:options.agentDir,env:options.env,paths,instanceId,generation}),stdio:options.owner?["ignore","ignore",stderr.fd,"pipe"]:["ignore","ignore",stderr.fd]}),childExit=new Promise(resolveExit=>{child.once("exit",(code,signal)=>{exitedEarly={code,signal},resolveExit(exitedEarly)})}),options.owner&&keepOwnerPipe(child),child.pid===void 0)throw new Error("failed to spawn RPC socket host");let probe=testOptions?.readProcessStartTime??readProcessStartTime,observedStartTime=await Promise.race([waitForStartTime(child.pid,1e4,probe),childExit.then(()=>{throw new Error("RPC socket host exited before its start time could be read")})]),unhurriedProbe=testOptions?.readProcessStartTime?testOptions.readProcessStartTime:pid=>readProcessStartTime(pid,process.platform,15e3),processStartTime=observedStartTime??await unhurriedProbe(child.pid).catch(()=>{});pidFile={pid:child.pid,processStartTime:processStartTime??null},await testOptions?.beforePidFileWrite?.(),await writeHostRegistration(paths,{record:pidFile,socket,instanceId,generation,launchProfileId:hostLaunchProfile(hostChildArgv(options.hostArgs??[]),process.cwd()).profile_id,build:engineBuildIdentity()}),child.unref()}catch(error){let exitedBeforeCleanup=exitedEarly;if(!exitedBeforeCleanup&&child?.pid!==void 0&&childExit&&await stopUnregisteredStart(child,childExit,stopTarget("start_failed")),!exitedBeforeCleanup)throw await clearHostRegistration(paths),error;let diagnostic2=await appendStderr(paths,`RPC socket host exited with code ${exitedBeforeCleanup.code??"null"}${exitedBeforeCleanup.signal?` (${exitedBeforeCleanup.signal})`:""} before answering get_protocol_info`);throw await clearHostRegistration(paths),new Error(diagnostic2)}finally{await stderr.close()}let readinessTimeoutMs=testOptions?.readinessTimeoutMs??DEFAULT_READINESS_TIMEOUT_MS,result=await pollProtocolInfo(socket,readinessTimeoutMs,isCompatible,childExit);if(result.ready)return{pid:pidFile.pid,socket,reused:!1,release:result.hold.release};await testOptions?.beforeReadinessTeardown?.();let stopFailure=await stopSpawnedChild(child,childExit,testOptions?.stopTimeoutMs??DEFAULT_STOP_TIMEOUT_MS,stopTarget("readiness_timeout")).then(()=>{},error=>error instanceof Error?error.message:String(error)),message=result.protocol?`RPC socket host answered get_protocol_info with protocolVersion ${result.protocol.protocolVersion}, serverVersion ${result.protocol.serverVersion} and capabilities ${JSON.stringify(result.protocol.capabilities)}, but is incompatible with protocol version ${HOST_PROTOCOL_VERSION} and required capabilities ${JSON.stringify(REQUIRED_HOST_CAPABILITIES)}`:result.exited?`RPC socket host exited with code ${result.exited.code??"null"}${result.exited.signal?` (${result.exited.signal})`:""} before answering get_protocol_info`:`spawned RPC socket host did not answer get_protocol_info within ${readinessTimeoutMs}ms`,diagnostic=await appendStderr(paths,stopFailure===void 0?message:`${message} (teardown also reported: ${stopFailure})`);throw await clearHostRegistration(paths),new Error(diagnostic)}async function stopUnregisteredStart(child,childExit,target){let pid=child.pid,running=()=>child.exitCode===null&&child.signalCode===null;if(pid===void 0||!running())return;let announced=await announceStop(target,pid);try{signalPid(pid,"SIGTERM")}catch{}if(await Promise.race([childExit,delay(2e3)]),!running())return;try{signalPid(pid,"SIGKILL")}catch{}await Promise.race([childExit.then(()=>!0),delay(SIGKILL_GRACE_MS).then(()=>!1)])&&await recordEscalation(target,announced)}async function appendStderr(paths,message){try{let stderr=(await readFile3(paths.stderrLog,"utf8")).trim();return stderr?`${message}
8
+ ${stderr}`:message}catch(error){if(isNodeErrorCode(error,"ENOENT"))return message;throw error}}import{appendFile}from"node:fs/promises";import{basename as basename3,join as join4}from"node:path";import{readFile as readFile4,rename,writeFile}from"node:fs/promises";import{join as join3}from"node:path";var GC_SKIP_INITIAL_BACKOFF_MS=10*6e4,GC_SKIP_MAX_BACKOFF_MS=1440*6e4,skipEntrySchema=external_exports.object({skipUntil:external_exports.number(),backoffMs:external_exports.number()}),markerSchema=external_exports.object({completedAt:external_exports.number(),cursor:external_exports.string().nullable(),examined:external_exports.number(),removed:external_exports.number(),stoppedBy:external_exports.enum(["time","count","exhausted"]),skip:external_exports.record(external_exports.string(),skipEntrySchema)});function hostGcPassMarkerPath(agentDir){return join3(agentDir,"rpc-host-daemon","gc-last-run.json")}function parseHostGcPassMarker(text){try{let parsed=markerSchema.safeParse(JSON.parse(text));return parsed.success?parsed.data:void 0}catch(error){if(error instanceof SyntaxError)return;throw error}}async function readHostGcPassMarker(agentDir){let text=await readFile4(hostGcPassMarkerPath(agentDir),"utf8").catch(error=>{if(!(error instanceof Error&&"code"in error&&error.code==="ENOENT"))throw error});return text===void 0?void 0:parseHostGcPassMarker(text)}async function writeHostGcPassMarker(agentDir,marker){let path=hostGcPassMarkerPath(agentDir),staged=`${path}.${process.pid}.tmp`;await writeFile(staged,`${JSON.stringify(marker)}
9
+ `,{mode:384}),await rename(staged,path)}function nextSkip(previous,now){let backoffMs=previous===void 0?GC_SKIP_INITIAL_BACKOFF_MS:Math.min(previous.backoffMs*2,GC_SKIP_MAX_BACKOFF_MS);return{skipUntil:now+backoffMs,backoffMs}}var OPPORTUNISTIC_GC_BUDGET={budgetMs:1500,maxEndpoints:32,minIntervalMs:3e5};async function gcHostEndpointsOpportunistically(options){let now=options.now??Date.now,budgetMs=options.budgetMs??OPPORTUNISTIC_GC_BUDGET.budgetMs,maxEndpoints=options.maxEndpoints??OPPORTUNISTIC_GC_BUDGET.maxEndpoints,minIntervalMs=options.minIntervalMs??OPPORTUNISTIC_GC_BUDGET.minIntervalMs,previous=await readHostGcPassMarker(options.agentDir),startedAt=now();if(previous!==void 0&&startedAt-previous.completedAt<minIntervalMs)return{ran:!1};let candidates=await gcCandidates(options),present=new Set(candidates.map(endpoint=>endpoint.name)),skip={};for(let[name,entry]of Object.entries(previous?.skip??{}))present.has(name)&&(skip[name]=entry);let cursor=previous?.cursor??null,examined=0,removed=0,stoppedBy="exhausted";for(let endpoint of rotateAfter(candidates,cursor)){if((skip[endpoint.name]?.skipUntil??0)>now())continue;if(examined>=maxEndpoints){stoppedBy="count";break}if(now()-startedAt>=budgetMs){stoppedBy="time";break}examined+=1,cursor=endpoint.name,(await gcEndpoint(endpoint.socket,endpoint.dir,{}).catch(()=>({removed:!1}))).removed?(removed+=1,delete skip[endpoint.name]):skip[endpoint.name]=nextSkip(skip[endpoint.name],now())}let marker={completedAt:now(),cursor,examined,removed,stoppedBy,skip};return await writeHostGcPassMarker(options.agentDir,marker),{ran:!0,marker}}var passesRunning=new Map;function scheduleOpportunisticHostGc(options){if(passesRunning.has(options.agentDir))return;let pass=new Promise(resolve4=>{setImmediate(()=>{gcHostEndpointsOpportunistically(options).then(()=>{},error=>recordPassFailure(options.agentDir,error)).finally(()=>{passesRunning.delete(options.agentDir),resolve4()})}).unref()});passesRunning.set(options.agentDir,pass)}async function gcCandidates(options){let targetName=basename3(createHostDaemonPaths({socket:options.exclude,agentDir:options.agentDir}).dir),candidates=[];for(let endpoint of await listHostEndpoints(options.agentDir)){let name=basename3(endpoint.dir);endpoint.socket===null||name===targetName||sameEndpoint(endpoint.socket,options.exclude)||candidates.push({...endpoint,socket:endpoint.socket,name})}return candidates}function rotateAfter(endpoints,cursor){if(cursor===null)return endpoints;let start=endpoints.findIndex(endpoint=>endpoint.name>cursor);return start<=0?endpoints:[...endpoints.slice(start),...endpoints.slice(0,start)]}async function recordPassFailure(agentDir,error){let line=`${new Date().toISOString()} gc pass failed: ${error instanceof Error?error.message:String(error)}
10
+ `;await appendFile(join4(agentDir,"rpc-host-daemon","gc-pass.log"),line,{mode:384}).catch(logError=>{logError instanceof Error&&"code"in logError&&logError.code==="ENOENT"||process.emitWarning(`host gc pass failed and could not be recorded: ${String(logError)}`)})}import{dirname as dirname4,join as join5}from"node:path";var LEGACY_PROBE_TIMEOUT_MS=1e4,DRAIN_POLL_MS=50;async function retireIdleLegacyHost(paths,probe,drainTimeoutMs=LEGACY_PROBE_TIMEOUT_MS){let judged=await judgeLegacyHost(paths,probe);if(judged.verdict==="absent")return;if(judged.verdict==="held")return judged.detail;let{record,socket}=judged.host;if(!await drainAndWait(record,probe,drainTimeoutMs))return`pid ${record.pid} (${socket}) was asked to drain and is still running after ${drainTimeoutMs}ms; retry once it exits`}async function readLegacyHost(paths){let text=await readFileOrUndefined(paths.legacyPidFile),record=text===void 0?void 0:parseDaemonPidFile(text);if(record===void 0)return;let stamped=parseJson(text)?.socket;return{record,socket:typeof stamped=="string"?stamped:join5(dirname4(paths.flatDir),"rpc","rpc.sock")}}async function provenLegacyOwner(paths,socket){let legacy=await readLegacyHost(paths),startTime=legacy?.record.processStartTime;if(!legacy||startTime===null||startTime===void 0||!sameEndpoint(legacy.socket,socket))return;let identity={pid:legacy.record.pid,processStartTime:startTime};return await processMatchesPidFile(identity,readProcessStartTime).catch(error=>(error instanceof ProcessIdentityUnreadableError&&logUnknownHostIdentity("legacy_host.pid",identity.pid),!1))?identity:void 0}async function judgeLegacyHost(paths,probe,platform=process.platform){let host=await readLegacyHost(paths);if(host===void 0)return{verdict:"absent"};let{pid}=host.record,identity=await processMatchesPidFile(host.record,probe).then(owns=>owns?"proven":"gone",error=>{if(error instanceof ProcessIdentityUnreadableError)return"unreadable";throw error});if(identity==="gone")return{verdict:"absent"};let where=`pid ${pid} (${host.socket})`;if(identity==="unreadable")return logUnknownHostIdentity("legacy_host.pid",pid),{verdict:"held",detail:`${where} cannot be proven to be the process its record names; stop it by hand`};if(platform==="win32")return{verdict:"held",detail:`${where} cannot be drained on win32; it exits once idle, then retry`};let protocol=await probeProtocolInfo(host.socket,LEGACY_PROBE_TIMEOUT_MS);if(!protocol?.capabilities.includes(GENERATION_HANDOFF_CAPABILITY))return{verdict:"held",detail:`${where} ${protocol?"cannot drain":"does not answer"}; it is never signalled - stop it by hand, then retry`};let sessions=await probeSessionCount(host.socket,LEGACY_PROBE_TIMEOUT_MS);return sessions===0?{verdict:"idle",host}:{verdict:"held",detail:busyLegacyHostDetail(pid,host.socket,sessions)}}function busyLegacyHostDetail(pid,socket,sessions){return`pid ${pid} (${socket}) holds ${describeSessions(sessions)}; run \`${APP_NAME} host stop --drain --socket ${socket}\` to let it finish that work and exit, then retry`}function describeSessions(sessions){return sessions===void 0?"an unknown number of sessions":`${sessions} open session${sessions===1?"":"s"}`}async function drainAndWait(record,probe,timeoutMs){try{process.kill(record.pid,"SIGUSR1")}catch(error){if(!(error instanceof Error&&"code"in error&&error.code==="ESRCH"))throw error}let stillRunning=()=>processMatchesPidFile(record,probe,processIsLive,{attempts:1}).catch(error=>{if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}),deadline=Date.now()+timeoutMs;for(;await stillRunning();){if(Date.now()>deadline)return!1;await new Promise(resolve4=>setTimeout(resolve4,DRAIN_POLL_MS))}return!0}import{spawn as spawn2}from"node:child_process";import{randomUUID as randomUUID2}from"node:crypto";import{open as open2,rm,writeFile as writeFile2}from"node:fs/promises";async function stopHost(options){let paths=createHostDaemonPaths({socket:options.socket,...options.agentDir?{agentDir:options.agentDir}:{}}),registered=await readHostRegistration(paths),owner=await provenOwner(registered,options.socket);if(options.drain===!0){let pid=owner?.pid??(await provenLegacyOwner(paths,options.socket))?.pid;return pid===void 0?{action:"refuse",reason:"unknown_owner"}:!(await probeProtocolInfo(options.socket,options.timeoutMs??1e4))?.capabilities.includes(GENERATION_HANDOFF_CAPABILITY)||process.platform==="win32"?{action:"refuse",reason:"drain_unsupported"}:(signalGeneration(pid,"SIGUSR1"),{action:"drained",pid})}if(!owner)return{action:"refuse",reason:"unknown_owner"};let host=await probeProtocolInfo(options.socket,options.timeoutMs??1e4),sessions=await probeSessionCount(options.socket,options.timeoutMs??1e4);return options.force!==!0&&host!==void 0&&sessions!==void 0&&sessions>0?{action:"refuse",reason:"sessions_live"}:(await writeStopIntent(generationPaths(paths,owner.instanceId),{sender:{pid:process.pid,kind:"stop"},targetPid:owner.pid,reason:"operator_stop",signal:"SIGTERM",at:new Date().toISOString()}),signalGeneration(owner.pid,"SIGTERM")||await releaseGeneration(paths,{instanceId:owner.instanceId,pid:owner.pid}),{action:"stopped",pid:owner.pid})}function signalGeneration(pid,signal){try{return process.kill(pid,signal),!0}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ESRCH")return!1;throw error}}var DEFAULT_HANDOFF_READINESS_MS=3e4,SUCCESSOR_EXIT_WAIT_MS=5e3,SUCCESSOR_START_BUDGET_MS=1e4+DEFAULT_HANDOFF_READINESS_MS+2e3+SUCCESSOR_EXIT_WAIT_MS;async function startSuccessor(context){let{options,paths,host,owner,drainGate}=context,generation=(host.generation??0)+1,instanceId=randomUUID2(),bindSocket=generationBindPath(options.socket,generation);if(Buffer.byteLength(bindSocket)>MAX_SOCKET_PATH_BYTES)return{action:"refuse",reason:"socket_path_too_long",upgradeable:!0,detail:bindSocket};let replaced=await statSocketIdentity(options.socket);if(!replaced)return{action:"refuse",reason:"socket_replaced",upgradeable:!0};let running=await readHostSettings(paths),lifetimeOwner=host.instanceId?await readHostOwner(generationPaths(paths,host.instanceId).dir):null,inheritOwnerPipe=lifetimeOwner?.pid===process.pid&&sameHostOwner(lifetimeOwner,await callerHostOwner()),bootSettings=await readFileOrUndefined(paths.settingsFile);await writeHostSettings(paths,{socket:options.socket,capabilities:PINNED_HOST_CLIENT_CAPABILITIES,coldStart:options.policy?.coldStart??running?.coldStart??"transient",idleExitMs:options.policy?.idleExitMs??running?.idleExitMs??9e5,generation,instanceId});let child,exited;try{await writeHostOwner(generationPaths(paths,instanceId).dir,lifetimeOwner??null),await options._test?.beforeSpawn?.();let argv=["--socket",options.socket,"--bind",bindSocket,"--replace",`${replaced.dev}:${replaced.ino}`,...inheritOwnerPipe?["--owner-fd",String(OWNER_WATCH_FD)]:[],...options.hostArgs??[]],launch=(options._test?.launch??options.launch)?.(argv)??defaultHostLaunch(argv),stderr=await open2(paths.stderrLog,"a",384),spawned=spawn2(launch.command,[...launch.args],{detached:!0,windowsHide:!0,env:successorHostEnvironment({agentDir:options.agentDir,env:options.env,expectedRuntimeBuildId:options.expectedRuntimeBuildId,paths,generation,instanceId}),stdio:inheritOwnerPipe?["ignore","ignore",stderr.fd,"pipe"]:["ignore","ignore",stderr.fd]});if(child=spawned,exited=new Promise(resolve4=>spawned.once("exit",()=>resolve4())),await stderr.close(),inheritOwnerPipe&&keepOwnerPipe(spawned),child.pid===void 0)throw new Error("failed to spawn the successor generation");let processStartTime=await waitForStartTime(child.pid,1e4).catch(()=>{})??null,registration={record:{pid:child.pid,processStartTime},socket:options.socket,instanceId,generation,launchProfileId:hostLaunchProfile(["--mode","rpc","--multi-session",...options.hostArgs??[]],process.cwd()).profile_id};await writeGenerationRecord(paths,registration),await options._test?.afterSpawn?.(child.pid);let answer2=await awaitSuccessor(options,host,exited);if(!answer2){let reason=await abortReason(options.socket,replaced),cleanupFailure=await abandonSuccessor({child,exited,paths,instanceId,bootSettings,reason:"successor_readiness_timeout"});return{action:"refuse",reason,upgradeable:!0,...cleanupFailure&&{detail:cleanupFailure}}}return await options._test?.beforeRegistration?.(),await writeHostRegistration(paths,{...registration,...successorBuild(answer2)}),child.unref(),owner!==void 0&&(drainGate===void 0||await drainGate())&&signalGeneration(owner.pid,"SIGUSR1"),{action:"handoff",pid:child.pid,socket:options.socket,generation:answer2.generation??generation,instanceId:answer2.instanceId??""}}catch(cause){let cleanupFailure=await abandonSuccessor({child,exited,paths,instanceId,bootSettings,reason:"successor_start_failed"}),detail=cause instanceof Error?cause.message:String(cause);return{action:"refuse",reason:"successor_unavailable",upgradeable:!0,detail:cleanupFailure?`${detail}; ${cleanupFailure}`:detail}}}async function abandonSuccessor(context){let{child,exited,paths,instanceId,bootSettings}=context,target={daemonDir:paths.dir,generation:generationPaths(paths,instanceId),instanceId,sender:{pid:process.pid,kind:"successor"},reason:context.reason},killed=child?.pid!==void 0&&child.exitCode===null&&child.signalCode===null?await announceStop(target,child.pid):void 0;killed!==void 0&&child?.pid!==void 0&&signalPid(child.pid,"SIGKILL");try{bootSettings===void 0?await rm(paths.settingsFile,{force:!0}):await writeFile2(paths.settingsFile,bootSettings,{mode:HOST_STATE_FILE_MODE}),child?.pid===void 0?await rm(generationPaths(paths,instanceId).dir,{recursive:!0,force:!0}):exited!==void 0&&await exitedWithin(exited,SUCCESSOR_EXIT_WAIT_MS)&&(killed!==void 0&&await recordEscalation(target,killed),await releaseGeneration(paths,{instanceId,pid:child.pid}));return}catch(cause){return`successor cleanup failed: ${cause instanceof Error?cause.message:String(cause)}`}}async function exitedWithin(exited,ms){let timer,timedOut=new Promise(resolve4=>{timer=setTimeout(()=>resolve4(!1),ms)});try{return await Promise.race([exited.then(()=>!0),timedOut])}finally{clearTimeout(timer)}}function successorBuild(answer2){return answer2.engineVersion===void 0||answer2.engineOrdinal===void 0?{}:{build:{text:answer2.engineVersion,ordinal:answer2.engineOrdinal}}}async function awaitSuccessor(options,previous,exited){let deadline=Date.now()+(options._test?.readinessTimeoutMs??DEFAULT_HANDOFF_READINESS_MS),childGone=!1;for(exited.then(()=>{childGone=!0});Date.now()<=deadline;){let answer2=await probeProtocolInfo(options.socket,2e3);if(answer2&&answer2.instanceId!==void 0&&answer2.instanceId!==previous.instanceId)return answer2;if(childGone)return;await delay3(50)}}async function abortReason(socket,replaced){let current=await statSocketIdentity(socket).catch(()=>{});return current===void 0||current.dev!==replaced.dev||current.ino!==replaced.ino?"socket_replaced":"successor_unavailable"}function delay3(ms){return new Promise(resolve4=>setTimeout(resolve4,ms))}var SESSION_COUNT_TIMEOUT_MS=1e4;async function handoffUnregisteredHost(options,paths,host){let counted=await holdSessionCount(options.socket,SESSION_COUNT_TIMEOUT_MS);try{let legacy=await provenLegacyOwner(paths,options.socket),sessions=counted?.sessions;if(sessions!==0)return legacy!==void 0?{action:"refuse",reason:"legacy_host",upgradeable:!0,detail:busyLegacyHostDetail(legacy.pid,options.socket,sessions)}:{action:"refuse",reason:"unknown_owner",upgradeable:!0,detail:`${options.socket} has no provable owner and holds ${describeSessions(sessions)}; it is never signalled - let that work finish, then retry`};let result=await startSuccessor({options,paths,host,owner:legacy,drainGate:async()=>await counted?.recount(SESSION_COUNT_TIMEOUT_MS)===0});return result.action==="handoff"&&legacy===void 0&&warnUnsignalledPredecessor(options.socket,host),result}finally{counted?.close()}}function warnUnsignalledPredecessor(socket,host){process.stderr.write(`generation handoff: no provable owner for ${socket}; the host it replaced (instance ${host.instanceId??"unknown"}, engine ${host.engineVersion??"unknown"}) listed 0 sessions and was not signalled; it drains itself on losing the public socket
11
+ `)}var HANDOFF_PROBE_TIMEOUT_MS=1e4,HANDOFF_LOCK_HOLD_MS=HANDOFF_PROBE_TIMEOUT_MS+2*SESSION_COUNT_TIMEOUT_MS+SUCCESSOR_START_BUDGET_MS,HANDOFF_LOCK_WAIT_MS=HANDOFF_PROBE_TIMEOUT_MS+Math.max(HANDOFF_LOCK_HOLD_MS,STOP_WAIT_BUDGET_MS+1e4)+1e4;async function handoffHost(options){if(handoffUnsupported(options))return{action:"refuse",reason:"upgrade_unsupported",upgradeable:!1};let release=await acquireHostEnsureLock(options.socket,HANDOFF_LOCK_WAIT_MS);try{return await handoffHostLocked(options)}finally{await release()}}async function handoffHostLocked(options){if(handoffUnsupported(options))return{action:"refuse",reason:"upgrade_unsupported",upgradeable:!1};let paths=createHostDaemonPaths({socket:options.socket,...options.agentDir?{agentDir:options.agentDir}:{}});await createDaemonDirectories(paths);let host=await probeProtocolInfo(options.socket,HANDOFF_PROBE_TIMEOUT_MS);if(!host)return{action:"refuse",reason:"no_host",upgradeable:!1};if(!host.capabilities.includes(GENERATION_HANDOFF_CAPABILITY))return{action:"refuse",reason:"handoff_unsupported",upgradeable:!1};let registered=await readHostRegistration(paths),owner=await provenOwner(registered,options.socket);return owner?startSuccessor({options,paths,host,owner}):handoffUnregisteredHost(options,paths,host)}function handoffUnsupported(options){return(options._test?.platform??process.platform)==="win32"}import{readdir as readdir2,readFile as readFile5,rm as rm2}from"node:fs/promises";import{tmpdir}from"node:os";import{join as join6}from"node:path";async function reapOrphanedInternalHostDirs(){try{let entries=await readdir2(tmpdir(),{withFileTypes:!0});await Promise.all(entries.filter(entry=>entry.isDirectory()&&entry.name.startsWith("senpi-rpc-host-internal-")).map(async entry=>{try{let owner=JSON.parse(await readFile5(join6(tmpdir(),entry.name,".owner"),"utf8"));typeof owner.pid=="number"&&typeof owner.processStartTime=="string"&&typeof owner.createdAt=="number"&&owner.processStartTime.length>0&&owner.createdAt<Date.now()-6e4&&(await readdir2(join6(tmpdir(),entry.name))).length===1&&!await processMatchesPidFile({pid:owner.pid,processStartTime:owner.processStartTime}).catch(error=>{if(error instanceof ProcessIdentityUnreadableError)return!0;throw error})&&await rm2(join6(tmpdir(),entry.name),{recursive:!0,force:!0})}catch{}}))}catch{}}var hostGenerationScopes=0;function isHostGenerationProcess(){return hostGenerationScopes>0}async function runAsHostGenerationProcess(action){hostGenerationScopes+=1;try{return await action()}finally{hostGenerationScopes-=1}}var EXISTING_HOST_PROBE_TIMEOUT_MS=1e4,ENSURE_LOCK_WAIT_MS=EXISTING_HOST_PROBE_TIMEOUT_MS+Math.max(STOP_WAIT_BUDGET_MS+DEFAULT_READINESS_TIMEOUT_MS,HANDOFF_LOCK_HOLD_MS)+1e4,lockOptions=hostEnsureLockOptions(ENSURE_LOCK_WAIT_MS);async function ensureHost(options){let socket=normalizeSocketPath(options.socket),paths=createHostDaemonPaths({socket,...options.agentDir?{agentDir:options.agentDir}:{}});await createDaemonDirectories(paths);let lockTarget=hostEnsureLockTarget(socket);await mkdir(dirname5(lockTarget),{recursive:!0}),await writeFile3(lockTarget,"",{flag:"a",mode:384}),await reapOrphanedInternalHostDirs();let release=await acquireOwnershipSafeLock(`${lockTarget}.lock`,lockOptions),ensured;try{await options._test?.afterLockAcquired?.(),ensured=await ensureHostLocked(paths,socket,options)}finally{await release()}return scheduleOpportunisticHostGc({agentDir:options.agentDir??getAgentDir(),exclude:socket}),ensured}async function ensureHostLocked(paths,socket,options){await ensureEndpointIdentity(paths,socket,{repair:!0});let testOptions=options._test,registered=await readHostRegistration(paths),registeredHere=registersSocket(registered,socket);if(registeredHere&&registered&&!processIsLive(registered.record.pid)&&await hostChildAlive(generationPaths(paths,registered.instanceId)))throw new HostEnsureRefusedError(socket,"host_stalled",void 0);let held=await holdProtocolInfo(socket,EXISTING_HOST_PROBE_TIMEOUT_MS),protocol=held?.info,startedByUs=registeredHere&&await writtenByThisProcess(registered?.writer,testOptions?.readProcessStartTime),attachedPid=registeredHere?registered?.record.pid??0:0,decision=decide(options,startedByUs,protocol);if(options.owner&&held&&(decision.action==="reuse"||decision.action==="handoff"))try{if(!registeredHere||!registered||registered.instanceId!==held.info.instanceId)throw new Error("RPC host has no matching registered owner-lifetime generation");await claimHostOwner(generationPaths(paths,registered.instanceId).dir)}catch(cause){throw held.hold.release(),cause}if(decision.action==="reuse"&&held)return{pid:attachedPid,socket,reused:!0,release:held.hold.release};switch(held?.hold.release(),decision.action){case"reuse":throw new Error(`host at ${socket} was reused without answering its probe`);case"refuse":throw new HostEnsureRefusedError(socket,decision.reason,protocol);case"handoff":return upgradeGeneration(paths,socket,options,attachedPid);case"start":break;default:return assertNever2(decision)}let probe=testOptions?.readProcessStartTime??readProcessStartTime,pidMatches=registeredHere&&registered?await matchesPidFileOrUnknown(registered.record,probe):!1,stranded;if(registered&&pidMatches)if(startedByUs){if(await probeSocketReachable(socket,EXISTING_HOST_PROBE_TIMEOUT_MS))throw new HostEnsureRefusedError(socket,"host_busy",protocol);await refuseIfStalled(paths,registered.instanceId,socket,protocol),await stopManagedHost(registered.record,testOptions?.stopTimeoutMs??DEFAULT_STOP_TIMEOUT_MS,{daemonDir:paths.dir,generation:generationPaths(paths,registered.instanceId),instanceId:registered.instanceId,sender:ensureSender(),reason:"replace_unreachable"},probe)}else{if(await publicEndpointAccepts(socket))throw new HostEnsureRefusedError(socket,"foreign_writer",protocol);await refuseIfStalled(paths,registered.instanceId,socket,protocol),stranded=registered}let legacyRefusal=await retireIdleLegacyHost(paths,probe,testOptions?.stopTimeoutMs);if(legacyRefusal!==void 0)throw new HostEnsureRefusedError(socket,"legacy_host",protocol,legacyRefusal);return stranded!==void 0?startHost(paths,socket,options,stranded.generation+1):(registeredHere&&await clearHostRegistration(paths),startHost(paths,socket,options))}function decide(options,startedByUs,protocol){if(options.upgrade!=="if-engine-differs"||isHostGenerationProcess())return decideHostAction(ensureClient(options,startedByUs),protocol,"never");let decision=decideHostAction(ensureClient(options,startedByUs),protocol,"upgrade");return decision.action==="fallback"?{action:"reuse",reason:"compatible",upgradeable:!1}:decision}async function upgradeGeneration(paths,socket,options,attachedPid){let result=await handoffHostLocked({socket,agentDir:options.agentDir??getAgentDir(),hostArgs:options.hostArgs??[],...options.env?{env:options.env}:{},...options.policy?{policy:options.policy}:{},_test:{...options._test?.launch?{launch:options._test.launch}:{},...options._test?.readinessTimeoutMs?{readinessTimeoutMs:options._test.readinessTimeoutMs}:{}}});return result.action==="handoff"?{pid:result.pid,socket,reused:!1,release:await holdEnsured(socket)}:(await appendStderr(paths,`generation handoff refused: ${result.reason}${result.detail?` (${result.detail})`:""}`),{pid:attachedPid,socket,reused:!0,release:await holdEnsured(socket)})}async function holdEnsured(socket){let held=await holdProtocolInfo(socket,EXISTING_HOST_PROBE_TIMEOUT_MS);if(!held)throw new Error(`RPC socket host at ${socket} stopped answering before this ensure could hold it`);return held.hold.release}function registersSocket(registered,socket){return registered===void 0?!1:registered.socket===void 0||sameEndpoint(registered.socket,socket)}function normalizeSocketPath(value){return value.startsWith("unix://")?value.slice(7):value}function assertNever2(value){throw new Error(`unreachable host decision: ${JSON.stringify(value)}`)}var WakeSourceTracker=class{constructor(){this.counts=new Map}observe(data){if(typeof data!="object"||data===null)return;let{source,activeCount}=data;typeof source!="string"||source.length===0||typeof activeCount!="number"||!Number.isFinite(activeCount)||(activeCount>0?this.counts.set(source,activeCount):this.counts.delete(source))}get hasActive(){return this.counts.size>0}get activeSources(){return[...this.counts.keys()]}};function isSessionBusySnapshot(snapshot){return snapshot.isStreaming||snapshot.isBashRunning||snapshot.isCompacting||snapshot.hasSessionWork||snapshot.hasActiveWakeSource}function isHandoffBusy(snapshot){return isSessionBusySnapshot({...snapshot,hasActiveWakeSource:!1})}function selectDrainVerdicts(registry,inFlight,unreadable){let park=[],gone=[];for(let{sessionId,status,sessionPath}of registry.list()){if(status!=="open"||inFlight(sessionId))continue;let entry=registry.peek(sessionId);!entry||handoffBusy(entry,sessionId,unreadable)||(sessionPath!==void 0&&sessionDirectoryRemoved(sessionPath)?gone.push(sessionId):park.push(sessionId))}return{park,gone}}function handoffBusy(entry,sessionId,unreadable){try{let snapshot=entry.runtime?.session.activitySnapshot;return entry.worker?.handoffBusy===!0||snapshot!==void 0&&isHandoffBusy(snapshot)}catch(cause){return unreadable(sessionId,cause),!1}}function readDrainVerdicts(registry,inFlight){try{return selectDrainVerdicts(registry,inFlight,(sessionId,cause)=>{process.stderr.write(`senpi rpc handoff activity of ${sessionId} unreadable, parking: ${String(cause)}
12
+ `)})}catch(cause){process.stderr.write(`senpi rpc handoff drain pass failed, retrying: ${String(cause)}
13
+ `);return}}var BEGIN_HANDOVER_COMMAND="begin_handover",SUCCESSOR_PROBE_TIMEOUT_MS=1e4;function parseBeginHandover(record){let{operation_id,if_instance_id,if_generation,target_runtime_build_id,launch,host_args,env}=record;if(typeof operation_id!="string"||operation_id==="")return"operation_id must be a non-empty string";if(typeof if_instance_id!="string")return"if_instance_id must be a string";if(typeof if_generation!="number"||!Number.isSafeInteger(if_generation))return"if_generation must be an integer";if(typeof target_runtime_build_id!="string")return"target_runtime_build_id must be a string";if(!isRecord4(launch)||typeof launch.command!="string"||!isStringArray(launch.args))return"launch must be { command, args }";if(!isStringArray(host_args))return"host_args must be an array of strings";if(!isRecord4(env)||!Object.values(env).every(value=>typeof value=="string"))return"env must map names to strings";let policy=isRecord4(record.policy)?record.policy:void 0;return{operationId:operation_id,ifInstanceId:if_instance_id,ifGeneration:if_generation,targetRuntimeBuildId:target_runtime_build_id,launch:{command:launch.command,args:launch.args},hostArgs:host_args,env,...policy!==void 0&&{policy}}}function beginHandoverResponse(id,answer2){let data=typeof answer2=="string"?{refused:"invalid_request",detail:answer2}:answer2.kind==="refused"?{refused:answer2.reason,...answer2.detail!==void 0&&{detail:answer2.detail}}:handoverWire(answer2.view);return{...typeof id=="string"&&{id},type:"response",command:BEGIN_HANDOVER_COMMAND,success:!0,data}}function handoverWire(view){return{operation_id:view.operationId,state:view.state,target_runtime_build_id:view.targetRuntimeBuildId,...view.reason!==void 0&&{reason:view.reason},...view.successor!==void 0&&{successor:view.successor}}}function handoverRefusal(command,view){return{...command.id!==void 0&&{id:command.id},type:"response",command:command.type,success:!1,error:`handover_pending: this host is handing over to runtime ${view.targetRuntimeBuildId} (operation ${view.operationId}); new work is admitted by its successor`}}function withHostIdentity(response,runtimeBuildId,handover){return response.command!=="get_protocol_info"||!response.success?response:{...response,data:{...response.data,...runtimeBuildId!==void 0&&{runtimeBuildId},...handover!==void 0&&{handover:handoverWire(handover)}}}}function isHostIdle(registry,inFlight){if((inFlight.get(void 0)??0)>0)return!1;let sessions=registry.list(),verdicts=selectDrainVerdicts(registry,sessionId=>(inFlight.get(sessionId)??0)>0,()=>{});return verdicts.park.length+verdicts.gone.length===sessions.length}async function performIdleHandover(context){let{request,socket,agentDir}=context,env={};for(let name of Object.keys(process.env))env[name]=null;Object.assign(env,request.env);let result=await handoffHost({socket,agentDir,hostArgs:request.hostArgs,env,expectedRuntimeBuildId:request.targetRuntimeBuildId,...request.policy!==void 0&&{policy:request.policy},launch:argv=>({command:request.launch.command,args:[...request.launch.args,...argv]})});if(result.action==="refuse")return{ok:!1,reason:result.detail===void 0?result.reason:`${result.reason}: ${result.detail}`};await writeDaemonEnvKeys(createHostDaemonPaths({socket,agentDir}),Object.keys(request.env).sort()).catch(cause=>{process.stderr.write(`senpi rpc handover: could not record the daemon environment: ${String(cause)}
14
+ `)});let successor=await probeProtocolInfo(socket,SUCCESSOR_PROBE_TIMEOUT_MS);return{ok:!0,successor:{pid:result.pid,instanceId:result.instanceId,generation:result.generation,runtimeBuildId:successor?.runtimeBuildId??null}}}function isRecord4(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isStringArray(value){return Array.isArray(value)&&value.every(entry=>typeof entry=="string")}var BYTES_PER_MB=1024*1024;function parseSessionRows(reply){return!isRecord5(reply)||!Array.isArray(reply.sessions)?[]:reply.sessions.flatMap(entry=>isRecord5(entry)?[{id:typeof entry.sessionId=="string"?entry.sessionId:"",kind:typeof entry.kind=="string"?entry.kind:"interactive",session_path:typeof entry.sessionPath=="string"?entry.sessionPath:null,cwd:typeof entry.cwd=="string"?entry.cwd:null,name:typeof entry.name=="string"?entry.name:null,attachments:typeof entry.attachments=="number"?entry.attachments:0,context:stringRecord(entry.context),memory:parseRowMemory(entry.memory)}]:[])}function parseRowMemory(value){if(!isRecord5(value))return{main_heap_mb:0,kernel_heap_mb:0,kernel_count:0};let toMb=bytes=>typeof bytes=="number"&&Number.isFinite(bytes)?Math.round(bytes/BYTES_PER_MB):0,count=value.kernel_count;return{main_heap_mb:toMb(value.main_heap_bytes),kernel_heap_mb:toMb(value.kernel_heap_bytes),kernel_count:typeof count=="number"&&Number.isFinite(count)?count:0}}async function readClaimRows(paths,generations){let rows=[];for(let claim of await readSessionPathClaims(paths.reservationsDir)){let owner=claim.owner;rows.push({session_path:owner.sessionPath,owner_pid:owner.pid,instance_id:owner.instanceId,generation:generations.find(row=>row.instanceId===owner.instanceId)?.generation??null,attached:owner.attached??null,live:await claimOwnerIsLive(owner)})}return rows.sort((left,right)=>left.session_path.localeCompare(right.session_path))}function stringRecord(value){return isRecord5(value)?Object.fromEntries(Object.entries(value).filter(entry=>typeof entry[1]=="string")):null}function isRecord5(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var STATUS_PROBE_TIMEOUT_MS=1e4;async function readHostStatus(options,read={}){return(await probeHostStatus(options,read)).report}async function probeHostStatus(options,read={}){let paths=createHostDaemonPaths({socket:options.socket,...options.agentDir?{agentDir:options.agentDir}:{}}),prune=read.prune!==!1,includeWorkers=options.includeWorkers===!0,timeoutMs=read.timeoutMs??STATUS_PROBE_TIMEOUT_MS,host=await observeProtocolInfo(options.socket,timeoutMs);prune&&await pruneDeadGenerations(paths);let generations=await readGenerationRows(paths,{includeDead:!prune}),current=generations.find(row=>row.current&&row.alive),metrics=current?await readHostProcessMetrics(current.pid):UNOBSERVED_METRICS,listing=host===void 0?[]:await readSessionListing(options.socket,includeWorkers,timeoutMs),claims=await readClaimRows(paths,generations);return{report:{reachable:host!==void 0,socket:options.socket,pid:current?.pid??null,instanceId:host?.instanceId??current?.instanceId??null,generation:host?.generation??current?.generation??null,engineVersion:host?.engineVersion??current?.engineVersion??null,capabilities:host?.capabilities??[],launchProfile:host?.launch_profile??null,runtimeBuildId:host?.runtimeBuildId??null,handover:host?.handover??null,sessions:countSessions(listing),zombies:metrics.zombies,rss_mb:metrics.rss_mb,host_rss_mb:metrics.host_rss_mb,open_fds:metrics.open_fds,memory_pressure:host?.memory_pressure??null,env_keys:await readDaemonEnvKeys(paths),generations,crashes:readHostCrashRecords(paths.dir).filter(isHostCrash).length,shard:parseShardSocket(options.socket),session_rows:includeWorkers?listing:[],claims_live:claims.filter(claim=>claim.live).length,claims:includeWorkers?claims:[]},answered:host,listing}}async function readSessionCounts(socket,includeWorkers){return countSessions(await readSessionListing(socket,includeWorkers))}async function readSessionListing(socket,includeWorkers,timeoutMs=STATUS_PROBE_TIMEOUT_MS){let reply=await requestOnSocket(socket,{type:"list_sessions",[OBSERVE_REQUEST_FIELD]:!0,...includeWorkers?{include_workers:!0}:{}},timeoutMs);return parseSessionRows(reply)}function countSessions(rows){let attached=rows.filter(row=>row.attachments>0).length,retained=rows.length-attached;return{total:rows.length,interactive:rows.filter(row=>row.kind!=="worker").length,worker:rows.filter(row=>row.kind==="worker").length,retained,foreign_attached:attached,foreign_retained:retained}}function hostSummary(host){return host===void 0?null:{protocolVersion:host.protocolVersion,serverVersion:host.serverVersion,capabilities:host.capabilities,instanceId:host.instanceId??null,generation:host.generation??null,engineVersion:host.engineVersion??null,launchProfileId:host.launch_profile?.profile_id??null}}var UNOBSERVED_METRICS={rss_mb:null,host_rss_mb:null,open_fds:null,zombies:null};var HOST_EXIT_OK=0,HOST_EXIT_ERROR=1,HOST_EXIT_USAGE=2,HOST_EXIT_REFUSED=3,HOST_EXIT_FALLBACK=4;function identityPayload(socket,pid,host){return{socket,pid,instanceId:host?.instanceId??null,generation:host?.generation??null,engineVersion:host?.engineVersion??null,engineOrdinal:host?.engineOrdinal??null,capabilities:host?.capabilities??[],launchProfileId:host?.launch_profile?.profile_id??null,runtimeBuildId:host?.runtimeBuildId??null,upgradeable:decideHostAction(decisionClient(),host,"upgrade").upgradeable}}async function clientRuntimeBuildId(spec){let profile=socketHostLaunchProfile(spec.hostArgs,process.cwd());return computeRuntimeBuildId({profile:profile.core}).catch(cause=>(process.stderr.write(`senpi host: runtime identity unreadable: ${String(cause)}
15
+ `),null))}function refusal(kind,host,body){return{exitCode:kind==="refuse"?HOST_EXIT_REFUSED:HOST_EXIT_FALLBACK,payload:{action:kind,...body,host:hostSummary(host)}}}function decisionClient(){return{protocolVersion:HOST_PROTOCOL_VERSION,requiredCapabilities:REQUIRED_HOST_CAPABILITIES,identity:engineBuildIdentity(),startedByUs:!1,platform:process.platform}}var PROBE_TIMEOUT_MS=1e4,BEGIN_HANDOVER_TIMEOUT_MS=2*HANDOFF_LOCK_HOLD_MS+2e4;async function idleHandoverOutcome(target,spec,terms){let{socket}=target;if(process.platform==="win32")return refusal("refuse",void 0,{reason:"upgrade_unsupported",socket,operationId:terms.operationId});let before=await probeProtocolInfo(socket,PROBE_TIMEOUT_MS),refuse=(reason,extra={})=>refusal("refuse",before,{reason,socket,operationId:terms.operationId,...extra}),client=await clientRuntimeBuildId(spec);if(client!==terms.targetRuntimeBuildId)return refuse("target_build_mismatch",{detail:`this CLI launches ${client??"a runtime it cannot read"}`,clientRuntimeBuildId:client});if(before===void 0)return refuse("no_host");if(before.runtimeBuildId===terms.targetRuntimeBuildId)return answered(target,"handover_completed",before,terms,null);if(before.instanceId!==terms.ifInstanceId||before.generation!==terms.ifGeneration)return refuse("stale_generation",{detail:`the socket is served by ${before.instanceId??"an unnamed host"} generation ${before.generation??"?"}`});if(!before.capabilities.includes(RUNTIME_IDENTITY_HANDOVER_CAPABILITY))return refuse("handover_unsupported");let reply=await requestOnSocket(socket,beginHandoverCommand(spec,terms),BEGIN_HANDOVER_TIMEOUT_MS);return isRecord6(reply)?typeof reply.refused=="string"?refuse(reply.refused,typeof reply.detail=="string"?{detail:reply.detail}:{}):reply.state==="handover_blocked"?refuse("handover_blocked",{detail:reply.reason??null,handover:reply}):reply.state==="handover_completed"?answered(target,"handover_completed",await probeProtocolInfo(socket,PROBE_TIMEOUT_MS),terms,reply):answered(target,"handover_pending",before,terms,reply):reconcileLostReply(target,terms,before)}function beginHandoverCommand(spec,terms){let env={};for(let[name,value]of Object.entries(daemonEnvironment(process.env,daemonEnvOverrides(process.env,spec.env))))value!==void 0&&(env[name]=value);let launch=defaultHostLaunch([]);return{type:BEGIN_HANDOVER_COMMAND,operation_id:terms.operationId,if_instance_id:terms.ifInstanceId,if_generation:terms.ifGeneration,target_runtime_build_id:terms.targetRuntimeBuildId,launch:{command:launch.command,args:launch.args},host_args:spec.hostArgs,env,...spec.policy!==void 0&&{policy:spec.policy}}}async function reconcileLostReply(target,terms,before){let now=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS);return now?.runtimeBuildId===terms.targetRuntimeBuildId?answered(target,"handover_completed",now,terms,null):{exitCode:HOST_EXIT_ERROR,payload:{action:"error",reason:"handover_reply_lost",operationId:terms.operationId,...identityPayload(target.socket,await servingPid(target),now??before)}}}async function answered(target,action,host,terms,handover){return{exitCode:HOST_EXIT_OK,payload:{action,...identityPayload(target.socket,await servingPid(target),host),operationId:typeof handover?.operation_id=="string"?handover.operation_id:terms.operationId,clientRuntimeBuildId:terms.targetRuntimeBuildId,handover}}}async function servingPid(target){return(await readHostRegistration(createHostDaemonPaths(target)))?.record.pid??0}function isRecord6(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{readdir as readdir3}from"node:fs/promises";var TUI_PROBE_TIMEOUT_MS=1500;function endpointProbeTimeoutMs(kind,requestedMs){return kind==="tui"?Math.min(requestedMs??TUI_PROBE_TIMEOUT_MS,TUI_PROBE_TIMEOUT_MS):requestedMs??DEFAULT_PROBE_TIMEOUT_MS}async function classifyEndpointLiveness(entry,options={}){let host=entry.socket===null?void 0:await observeProtocolInfo(entry.socket,endpointProbeTimeoutMs(entry.endpoint_kind,options.timeoutMs));return judgeEndpointLiveness(hostDaemonDirectoryPaths(entry.dir),host===void 0?void 0:host.instanceId??null)}async function judgeEndpointLiveness(paths,answered2){return typeof answered2=="string"&&await recordsInstance(paths,answered2)?"routable":answered2!==void 0||await anyGenerationLive(paths)?"live_unresponsive":"dead"}async function recordsInstance(paths,instanceId){return(await readdir3(paths.generationsDir).catch(()=>[])).includes(instanceId)?await readFileOrUndefined(generationPaths(paths,instanceId).pidFile).catch(()=>{})!==void 0:!1}var STATUS_ALL_MAX_IN_FLIGHT=64;async function readAllHostStatus(options){let endpoints=await listHostEndpoints(options.agentDir),read=options._test?.readEndpoint??(endpoint=>endpointStatus(endpoint,options)),rows=new Array(endpoints.length),next=0,worker=async()=>{for(let index=next++;index<endpoints.length;index=next++){let endpoint=endpoints[index];endpoint!==void 0&&(rows[index]=await read(endpoint))}};return await Promise.all(Array.from({length:Math.min(STATUS_ALL_MAX_IN_FLIGHT,endpoints.length)},worker)),rows}async function endpointStatus(endpoint,options){let located={dir:endpoint.dir,identity:endpoint.identity,endpoint_kind:endpoint.endpoint_kind},paths=hostDaemonDirectoryPaths(endpoint.dir);if(endpoint.socket===null){let verdict2=livenessFields(await judgeEndpointLiveness(paths,void 0)),status=await unaddressableStatus(endpoint.dir),owner2=endpoint.endpoint_kind==="tui"?tuiOwner(status,[]):null;return{...status,socket:null,...located,...verdict2,owner:owner2}}let{report,answered:answered2,listing}=await probeHostStatus({socket:endpoint.socket,agentDir:options.agentDir,includeWorkers:options.includeWorkers},{prune:!1,timeoutMs:endpointProbeTimeoutMs(endpoint.endpoint_kind,options.timeoutMs)}),verdict=await judgeEndpointLiveness(paths,answered2===void 0?void 0:answered2.instanceId??null),owner=endpoint.endpoint_kind==="tui"?tuiOwner(report,listing):null;return{...report,...located,...livenessFields(verdict),owner}}function tuiOwner(status,listing){let row=listing[0];return{pid:status.generations.find(generation=>generation.current)?.pid??null,cwd:row?.cwd??null,session:row===void 0?null:{id:row.id,path:row.session_path,name:row.name}}}function livenessFields(verdict){return verdict==="routable"?{alive:!0,reason:null}:{alive:!1,reason:verdict}}async function unaddressableStatus(dir){let paths=hostDaemonDirectoryPaths(dir),generations=await readGenerationRows(paths,{includeDead:!0}),claims=await readClaimRows(paths,generations);return{reachable:!1,pid:null,instanceId:null,generation:null,engineVersion:null,capabilities:[],launchProfile:null,runtimeBuildId:null,handover:null,sessions:{total:0,interactive:0,worker:0,retained:0,foreign_attached:0,foreign_retained:0},zombies:null,rss_mb:null,host_rss_mb:null,open_fds:null,memory_pressure:null,env_keys:[],generations,crashes:readHostCrashRecords(dir).filter(isHostCrash).length,shard:null,session_rows:[],claims_live:claims.filter(claim=>claim.live).length,claims:[]}}var PROBE_TIMEOUT_MS2=1e4;async function runHostRequest(request){if(request.action==="ensure"||request.action==="handoff"||request.action==="stop"){let{socket,agentDir}=request.target;if(await endpointKindOfSocket(socket,agentDir)==="tui")return refusal("refuse",void 0,{reason:"unsupported_endpoint_kind",socket,endpoint_kind:"tui"})}switch(request.action){case"ensure":return ensureOutcome(request.target,request.spec,request.policy);case"status":return request.all===!0?statusAllOutcome(request.target,request.includeWorkers):statusOutcome(request.target,request.includeWorkers);case"stop":return stopOutcome(request.target,request.drain,request.force);case"handoff":return request.handover===void 0?handoffOutcome(request.target,request.spec):idleHandoverOutcome(request.target,request.spec,request.handover);case"shard_path":return shardPathOutcome(request.kind,request.owner,request.root);case"gc":return{exitCode:HOST_EXIT_OK,payload:{...await gcHostEndpoints(request.agentDir)}};default:return assertNever3(request)}}async function ensureOutcome(target,spec,policy){let before=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS2);if(policy==="fallback"){let decision=decideHostAction(decisionClient(),before,"fallback");if(decision.action==="fallback")return refusal("fallback",before,{reason:decision.reason,socket:target.socket})}let ensured;try{ensured=await ensureHost({socket:target.socket,agentDir:target.agentDir,hostArgs:spec.hostArgs,env:daemonEnvOverrides(process.env,spec.env),policy:spec.policy,upgrade:policy==="upgrade"?"if-engine-differs":"never"})}catch(error){if(!(error instanceof HostEnsureRefusedError))throw error;return refusal("refuse",before,{reason:error.reason,socket:target.socket,...error.detail!==void 0&&{detail:error.detail}})}let host=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS2).finally(ensured.release);return ensured.reused||await recordEnvScope(target,spec),{exitCode:HOST_EXIT_OK,payload:{action:ensureAction(ensured.reused,before,host),...identityPayload(target.socket,ensured.pid,host),clientRuntimeBuildId:await clientRuntimeBuildId(spec),reused:ensured.reused}}}function ensureAction(reused,before,after){return reused?"reuse":before!==void 0&&before.instanceId!==after?.instanceId?"handoff":"start"}async function statusOutcome(target,includeWorkers){let status=await readHostStatus({socket:target.socket,agentDir:target.agentDir,includeWorkers});return{exitCode:status.reachable?HOST_EXIT_OK:HOST_EXIT_REFUSED,payload:{...status}}}async function statusAllOutcome(target,includeWorkers){let endpoints=await readAllHostStatus({agentDir:target.agentDir,includeWorkers});return{exitCode:endpoints.some(endpoint=>endpoint.reachable)?HOST_EXIT_OK:HOST_EXIT_REFUSED,payload:{endpoints}}}function shardPathOutcome(kind,owner,root){let key=shardKey(kind,owner);return{exitCode:HOST_EXIT_OK,payload:{kind,key,socket:shardSocketPathForKey(root,kind,key)}}}async function stopOutcome(target,drain,force){let host=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS2),sessions=await readSessionCounts(target.socket,!0),occupied=sessions.foreign_attached+sessions.foreign_retained>0;if(!drain&&!force&&occupied)return refusal("refuse",host,{reason:"sessions_live",socket:target.socket,sessions});let result=await stopHost({socket:target.socket,agentDir:target.agentDir,drain,force});return result.action==="refuse"?refusal("refuse",host,{reason:result.reason,socket:target.socket,sessions}):{exitCode:HOST_EXIT_OK,payload:{action:result.action,socket:target.socket,pid:result.pid,sessions}}}async function handoffOutcome(target,spec){let before=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS2),result=await handoffHost({socket:target.socket,agentDir:target.agentDir,hostArgs:spec.hostArgs,env:daemonEnvOverrides(process.env,spec.env),policy:spec.policy});if(result.action==="refuse")return refusal("refuse",before,{reason:upgradeRefusal(result.reason),socket:target.socket,detail:result.detail??result.reason,upgradeable:result.upgradeable});await recordEnvScope(target,spec);let host=await probeProtocolInfo(target.socket,PROBE_TIMEOUT_MS2);return{exitCode:HOST_EXIT_OK,payload:{action:"handoff",...identityPayload(target.socket,result.pid,host),clientRuntimeBuildId:await clientRuntimeBuildId(spec),reused:!1}}}function upgradeRefusal(reason){return reason==="handoff_unsupported"?"upgrade_unsupported":reason}async function recordEnvScope(target,spec){let paths=createHostDaemonPaths({socket:target.socket,agentDir:target.agentDir});await writeDaemonEnvKeys(paths,daemonEnvKeys(process.env,spec.env))}function assertNever3(value){throw new Error(`unreachable host request: ${JSON.stringify(value)}`)}var SUBCOMMANDS=["ensure","status","stop","handoff","shard-path","gc"],POLICIES=["upgrade","fallback","never"],USAGE=`usage: ${APP_NAME} host <ensure|status|stop|handoff|shard-path|gc> [options]
16
+
17
+ ensure [--launch-spec <file>] [--policy upgrade|fallback|never] [--socket <path>]
18
+ status [--include-workers] [--all] [--socket <path>] (--all: every endpoint, ignores --socket)
19
+ stop [--drain] [--force] [--socket <path>]
20
+ handoff [--launch-spec <file>] [--socket <path>]
21
+ [--when idle --operation <id> --if-instance <id> --if-generation <n> --target-build <sha256:...>]
22
+ (--when idle: the running host hands over to THIS runtime at its next safe idle point)
23
+ shard-path --kind <p|i> --owner <id> [--root <dir>] [--json] (no host contact)
24
+ gc [--agent-dir <dir>] [--json] (removes provably dead endpoints only; ignores --socket)
25
+
26
+ --json the answer is one JSON line on stdout (always, except shard-path's bare path)`;async function runHostCommand(args){let parsed=parseHostArgs(args);if(typeof parsed=="string")return process.stderr.write(`${parsed}
27
+ ${USAGE}
28
+ `),HOST_EXIT_USAGE;try{let outcome=await runHostRequest(await hostRequest(parsed));return parsed.subcommand==="shard-path"&&!parsed.json?writeSync(1,`${String(outcome.payload.socket)}
29
+ `):emit(outcome.payload),outcome.exitCode}catch(error){return error instanceof HostLaunchSpecError?(emit({action:"error",reason:error.reason,detail:error.detail}),HOST_EXIT_USAGE):(emit({action:"error",reason:"host_error",detail:error instanceof Error?error.message:String(error)}),HOST_EXIT_ERROR)}}async function hostRequest(parsed){let agentDir=getAgentDir(),target={socket:resolveHostSocket(parsed.socket,agentDir),agentDir};switch(parsed.subcommand){case"ensure":return{action:"ensure",target,spec:await launchSpec(parsed.specPath),policy:parsed.policy};case"status":return{action:"status",target,includeWorkers:parsed.includeWorkers,all:parsed.all};case"stop":return{action:"stop",target,drain:parsed.drain,force:parsed.force};case"handoff":return{action:"handoff",target,spec:await launchSpec(parsed.specPath),...parsed.handover!==void 0&&{handover:parsed.handover}};case"shard-path":return{action:"shard_path",kind:parsed.kind??"p",owner:parsed.owner??"",root:resolve3(parsed.root??join7(agentDir,"rpc","shards"))};case"gc":return{action:"gc",agentDir:resolve3(parsed.agentDir??agentDir)};default:return assertNever4(parsed.subcommand)}}function launchSpec(specPath){return specPath===void 0?DEFAULT_HOST_LAUNCH_SPEC:loadHostLaunchSpec(specPath)}function resolveHostSocket(explicit,agentDir){return explicit??envValue("RPC_SOCKET")??resolve3(agentDir,"rpc","rpc.sock")}function parseHostArgs(args){let[subcommand,...rest]=args;if(subcommand===void 0||!isSubcommand(subcommand))return`Error: unknown host command "${subcommand??""}".`;let specPath,policy="upgrade",socket,includeWorkers=!1,all=!1,drain=!1,force=!1,json=!1,kind,owner,root,agentDir,handover={};for(let index=0;index<rest.length;index++){let flag=rest[index],value=rest[index+1];if(flag==="--json")json=!0;else if(flag==="--include-workers")includeWorkers=!0;else if(flag==="--all"&&subcommand==="status")all=!0;else if(flag==="--kind"&&subcommand==="shard-path"&&(value==="p"||value==="i"))kind=value,index++;else if(flag==="--owner"&&subcommand==="shard-path"&&value!==void 0)owner=value,index++;else if(flag==="--root"&&subcommand==="shard-path"&&value!==void 0)root=value,index++;else if(flag==="--agent-dir"&&subcommand==="gc"&&value!==void 0)agentDir=value,index++;else if(subcommand==="handoff"&&value!==void 0&&HANDOVER_FLAGS.has(flag??""))handover[flag??""]=value,index++;else if(flag==="--drain")drain=!0;else if(flag==="--force")force=!0;else if(flag==="--launch-spec"&&value!==void 0)specPath=value,index++;else if(flag==="--socket"&&value!==void 0)socket=value,index++;else if(flag==="--policy"&&value!==void 0&&isPolicy(value))policy=value,index++;else return`Error: unknown option "${flag}" for "${APP_NAME} host ${subcommand}".`}if(subcommand==="shard-path"&&(kind===void 0||owner===void 0))return`Error: "${APP_NAME} host shard-path" needs --kind <p|i> and --owner <id>.`;let terms=Object.keys(handover).length===0?void 0:handoverTerms(handover);return typeof terms=="string"?terms:{subcommand,...specPath!==void 0&&{specPath},policy,...socket!==void 0&&{socket},includeWorkers,all,drain,force,json,...kind!==void 0&&{kind},...owner!==void 0&&{owner},...root!==void 0&&{root},...agentDir!==void 0&&{agentDir},...terms!==void 0&&{handover:terms}}}var HANDOVER_FLAGS=new Set(["--when","--operation","--if-instance","--if-generation","--target-build"]);function handoverTerms(flags){let when=flags["--when"],operationId=flags["--operation"],ifInstanceId=flags["--if-instance"],generation=flags["--if-generation"],targetRuntimeBuildId=flags["--target-build"];if(when!=="idle")return`Error: "${APP_NAME} host handoff" supports only --when idle.`;if(!operationId||!ifInstanceId||!generation||!targetRuntimeBuildId)return`Error: "${APP_NAME} host handoff --when idle" needs --operation, --if-instance, --if-generation and --target-build.`;let ifGeneration=Number(generation);return!/^\d+$/.test(generation)||!Number.isSafeInteger(ifGeneration)?"Error: --if-generation must be a non-negative integer.":{operationId,ifInstanceId,ifGeneration,targetRuntimeBuildId}}function emit(payload){writeSync(1,`${JSON.stringify(payload)}
30
+ `)}function isSubcommand(value){return SUBCOMMANDS.includes(value)}function isPolicy(value){return POLICIES.includes(value)}function assertNever4(value){throw new Error(`unreachable host subcommand: ${JSON.stringify(value)}`)}export{HostLaunchSpecError,DEFAULT_HOST_LAUNCH_SPEC,loadHostLaunchSpec,parseHostLaunchSpec,RUNTIME_IDENTITY_HANDOVER_CAPABILITY,computeRuntimeBuildId,parseHostProtocolInfo,HOST_PROTOCOL_VERSION,GENERATION_HANDOFF_CAPABILITY,REQUIRED_HOST_CAPABILITIES,HostEnsureRefusedError,decideHostAction,probeHost,PINNED_HOST_CLIENT_CAPABILITIES,EXPECTED_RUNTIME_BUILD_ID_ENV,HostIdleHandover,stopHost,handoffHost,runAsHostGenerationProcess,ensureHost,WakeSourceTracker,isSessionBusySnapshot,isHandoffBusy,readDrainVerdicts,BEGIN_HANDOVER_COMMAND,parseBeginHandover,beginHandoverResponse,handoverRefusal,withHostIdentity,isHostIdle,performIdleHandover,readHostStatus,HOST_EXIT_OK,HOST_EXIT_ERROR,HOST_EXIT_USAGE,HOST_EXIT_REFUSED,HOST_EXIT_FALLBACK,TUI_PROBE_TIMEOUT_MS,endpointProbeTimeoutMs,classifyEndpointLiveness,readAllHostStatus,runHostRequest,runHostCommand,parseHostArgs};
@@ -1,5 +1,5 @@
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{watchWithErrorHandler}from"./chunk-JABBHOD5.js";import{external_exports}from"./chunk-KUPQO7MC.js";import{ProjectTrustStore}from"./chunk-RRU5LXMS.js";import{modelSupportsAssistantPrefill}from"./chunk-ZPJHS64R.js";import{sanitizeProviderDiagnostic}from"./chunk-YOPVJDSU.js";import{getSupportedThinkingLevels,supportsMax,supportsXhigh}from"./chunk-L4HVJWIF.js";function supportsXhigh2(model){return supportsXhigh(model)}function supportsMax2(model){return supportsMax(model)}function getSupportedThinkingLevels2(model){let supportedLevels=getSupportedThinkingLevels(model);return supportedLevels.length>0?supportedLevels:["off"]}function clampThinkingSelection(selection,requested,level,model){if(selection===void 0)return;let{requested:_staleRequested,clampReason:_staleReason,...base}=selection;return requested===level||model===void 0?{...base,level}:{...base,level,requested,clampReason:model.reasoning?"level-unsupported":"model-not-reasoning"}}function getThinkingClampNotice(selection,model){let clamped=selection;if(!(model===void 0||clamped?.requested===void 0||clamped.clampReason===void 0))return{provider:model.provider,modelId:model.id,requestedLevel:clamped.requested,appliedLevel:clamped.level,reason:clamped.clampReason}}function formatThinkingClampWarning(notice){let model=`${notice.provider}/${notice.modelId}`;return notice.reason==="model-not-reasoning"?`Thinking level "${notice.requestedLevel}" was requested, but ${model} is not marked as a reasoning model, so thinking is "${notice.appliedLevel}". If the model supports reasoning, set "reasoning": true for it in models.json.`:`Thinking level "${notice.requestedLevel}" is not available on ${model}; using "${notice.appliedLevel}".`}function classifyReasoningCapability(model){if(!model.reasoning)return{kind:"none",levels:["off"],nonOffLevels:[]};let levels=getSupportedThinkingLevels2(model),nonOffLevels=levels.filter(level=>level!=="off");return levels.includes("off")?nonOffLevels.length===1?{kind:"on-off",levels,nonOffLevels}:nonOffLevels.length===0?{kind:"none",levels,nonOffLevels}:{kind:"graded",levels,nonOffLevels}:{kind:"always-on",levels,nonOffLevels}}var BROWSER_ENGINES=["connected","builtin","none"];function isBrowserEngine(value){return BROWSER_ENGINES.some(engine=>engine===value)}var clientMessageIdentitySchema=external_exports.object({clientMessageId:external_exports.string().min(1).max(256).optional(),clientTurnId:external_exports.string().min(1).max(256).optional()});function clientMessageIdentity(value={}){return{...value.clientMessageId===void 0?{}:{clientMessageId:value.clientMessageId},...value.clientTurnId===void 0?{}:{clientTurnId:value.clientTurnId}}}function readClientMessageIdentity(value){let parsed=clientMessageIdentitySchema.safeParse(value);return parsed.success?clientMessageIdentity(parsed.data):{}}var MAX_RPC_MESSAGE_CHARACTERS=1e6,SESSION_CONTEXT_LIMITS={keys:32,valueBytes:16*1024,totalBytes:32*1024},SESSION_CONTEXT_KEY_PATTERN=/^[a-z][a-z0-9_]*$/;function validContent(content){return typeof content=="string"?!0:Array.isArray(content)&&content.every(item=>{if(typeof item!="object"||item===null)return!1;let value=item;return value.type==="text"?typeof value.text=="string":value.type==="image"&&typeof value.data=="string"&&typeof value.mimeType=="string"})}function validBaseEntry(entry){return typeof entry.id=="string"&&(entry.parentId===null||typeof entry.parentId=="string")&&typeof entry.timestamp=="string"}function validSessionEntry(entry){if(typeof entry!="object"||entry===null||Array.isArray(entry))return!1;let value=entry;if(!validBaseEntry(value))return!1;switch(value.type){case"message":{let message=value.message;if(typeof message!="object"||message===null)return!1;let item=message;return["user","assistant","tool"].includes(item.role)&&validContent(item.content)}case"thinking_level_change":return typeof value.thinkingLevel=="string";case"model_change":return typeof value.provider=="string"&&typeof value.modelId=="string";case"model_change_rejected":return typeof value.provider=="string"&&typeof value.modelId=="string"&&typeof value.detail=="string";case"compaction":return typeof value.summary=="string"&&typeof value.firstKeptEntryId=="string"&&typeof value.tokensBefore=="number";case"branch_summary":return typeof value.fromId=="string"&&typeof value.summary=="string";case"custom":return typeof value.customType=="string";case"custom_message":return typeof value.customType=="string"&&validContent(value.content)&&typeof value.display=="boolean";case"label":return typeof value.targetId=="string"&&(value.label===void 0||typeof value.label=="string");case"session_info":return value.name===void 0||typeof value.name=="string";default:return!1}}function rpcCommandPayloadError(command){if(rpcCommandShapeError(command))return;let value=command;if((value.type==="prompt"||value.type==="steer"||value.type==="follow_up")&&!clientMessageIdentitySchema.safeParse(value).success)return"clientMessageId and clientTurnId must be non-empty strings of at most 256 characters.";if((value.type==="steer"||value.type==="follow_up")&&value.enqueueOrder!==void 0&&!(typeof value.enqueueOrder=="number"&&Number.isFinite(value.enqueueOrder)))return"enqueueOrder must be a finite number.";if(value.type==="append_user_message"&&!validContent(value.content))return"append_user_message content must be a string or text/image content array.";if(value.type==="append_session_entry"&&!validSessionEntry(value.entry))return"append_session_entry entry is malformed."}function sessionContextError(context){if(context===void 0)return;if(typeof context!="object"||context===null||Array.isArray(context))return"context must be an object of string values.";let entries=Object.entries(context);if(entries.length>SESSION_CONTEXT_LIMITS.keys)return`context has ${entries.length} keys, at most ${SESSION_CONTEXT_LIMITS.keys} are accepted.`;for(let[key,value]of entries){if(!SESSION_CONTEXT_KEY_PATTERN.test(key))return`context key "${key}" must match ${SESSION_CONTEXT_KEY_PATTERN.source}.`;if(typeof value!="string")return`context value for key "${key}" must be a string.`;let valueBytes=Buffer.byteLength(value);if(valueBytes>SESSION_CONTEXT_LIMITS.valueBytes)return`context value for key "${key}" is ${valueBytes} bytes, at most ${SESSION_CONTEXT_LIMITS.valueBytes} bytes are accepted.`}let totalBytes=Buffer.byteLength(JSON.stringify(context));if(totalBytes>SESSION_CONTEXT_LIMITS.totalBytes)return`context is ${totalBytes} bytes of JSON, at most ${SESSION_CONTEXT_LIMITS.totalBytes} bytes are accepted.`}function sessionKindError(kind){if(!(kind===void 0||kind==="interactive"||kind==="worker"))return'kind must be "interactive" or "worker".'}function sessionAutoTitleError(value){if(!(value===void 0||typeof value=="boolean"))return"auto_title must be a boolean."}function sessionPromptSurfaceError(value){if(!(value===void 0||value==="terminal"||value==="app"||value==="chat"))return'promptSurface must be "terminal", "app" or "chat".'}function sessionBrowserEngineError(value){if(!(value===void 0||isBrowserEngine(value)))return'browserEngine must be "connected", "builtin" or "none".'}var MAX_RETRY_FALLBACK_CHAINS=32,MAX_RETRY_FALLBACK_ENTRIES=32,MAX_RETRY_FALLBACK_SELECTOR_LENGTH=512;function sessionRetryFallbackError(value){if(value===void 0)return;let shape="retryFallback must be { modelFallback: boolean, fallbackChains: Record<string, string[]> }.";if(typeof value!="object"||value===null||Array.isArray(value))return shape;let record=value;if(typeof record.modelFallback!="boolean")return shape;let chains=record.fallbackChains;if(typeof chains!="object"||chains===null||Array.isArray(chains))return shape;let entries=Object.entries(chains);if(entries.length>MAX_RETRY_FALLBACK_CHAINS)return`retryFallback allows at most ${MAX_RETRY_FALLBACK_CHAINS} chains.`;for(let[key,selectors]of entries){if(!isSelector(key)||!Array.isArray(selectors)||!selectors.every(isSelector))return shape;if(selectors.length>MAX_RETRY_FALLBACK_ENTRIES)return`retryFallback allows at most ${MAX_RETRY_FALLBACK_ENTRIES} entries per chain.`}}function isSelector(value){return typeof value=="string"&&value.trim().length>0&&value.length<=MAX_RETRY_FALLBACK_SELECTOR_LENGTH}function rpcCommandShapeError(command){if(typeof command!="object"||command===null||Array.isArray(command))return"RPC command must be a JSON object."}function rpcMessageLengthError(command){if(rpcCommandShapeError(command))return;let input=command;if(!(input.type!=="prompt"&&input.type!=="steer"&&input.type!=="follow_up")&&!(typeof input.message!="string"||input.message.length<=MAX_RPC_MESSAGE_CHARACTERS))return`RPC ${input.type} message exceeds ${MAX_RPC_MESSAGE_CHARACTERS} characters.`}import{randomUUID}from"node:crypto";import{mkdir,rm,writeFile}from"node:fs/promises";import{join}from"node:path";import{setTimeout as delay}from"node:timers/promises";import{Worker}from"node:worker_threads";var RECURSIVE_WATCH_WORKER_SOURCE=`
2
+ import{watchWithErrorHandler}from"./chunk-JABBHOD5.js";import{external_exports}from"./chunk-KUPQO7MC.js";import{ProjectTrustStore}from"./chunk-RRU5LXMS.js";import{modelSupportsAssistantPrefill}from"./chunk-5BRVRFJI.js";import{sanitizeProviderDiagnostic}from"./chunk-YOPVJDSU.js";import{getSupportedThinkingLevels,supportsMax,supportsXhigh}from"./chunk-L4HVJWIF.js";function supportsXhigh2(model){return supportsXhigh(model)}function supportsMax2(model){return supportsMax(model)}function getSupportedThinkingLevels2(model){let supportedLevels=getSupportedThinkingLevels(model);return supportedLevels.length>0?supportedLevels:["off"]}function clampThinkingSelection(selection,requested,level,model){if(selection===void 0)return;let{requested:_staleRequested,clampReason:_staleReason,...base}=selection;return requested===level||model===void 0?{...base,level}:{...base,level,requested,clampReason:model.reasoning?"level-unsupported":"model-not-reasoning"}}function getThinkingClampNotice(selection,model){let clamped=selection;if(!(model===void 0||clamped?.requested===void 0||clamped.clampReason===void 0))return{provider:model.provider,modelId:model.id,requestedLevel:clamped.requested,appliedLevel:clamped.level,reason:clamped.clampReason}}function formatThinkingClampWarning(notice){let model=`${notice.provider}/${notice.modelId}`;return notice.reason==="model-not-reasoning"?`Thinking level "${notice.requestedLevel}" was requested, but ${model} is not marked as a reasoning model, so thinking is "${notice.appliedLevel}". If the model supports reasoning, set "reasoning": true for it in models.json.`:`Thinking level "${notice.requestedLevel}" is not available on ${model}; using "${notice.appliedLevel}".`}function classifyReasoningCapability(model){if(!model.reasoning)return{kind:"none",levels:["off"],nonOffLevels:[]};let levels=getSupportedThinkingLevels2(model),nonOffLevels=levels.filter(level=>level!=="off");return levels.includes("off")?nonOffLevels.length===1?{kind:"on-off",levels,nonOffLevels}:nonOffLevels.length===0?{kind:"none",levels,nonOffLevels}:{kind:"graded",levels,nonOffLevels}:{kind:"always-on",levels,nonOffLevels}}var BROWSER_ENGINES=["connected","builtin","none"];function isBrowserEngine(value){return BROWSER_ENGINES.some(engine=>engine===value)}var clientMessageIdentitySchema=external_exports.object({clientMessageId:external_exports.string().min(1).max(256).optional(),clientTurnId:external_exports.string().min(1).max(256).optional()});function clientMessageIdentity(value={}){return{...value.clientMessageId===void 0?{}:{clientMessageId:value.clientMessageId},...value.clientTurnId===void 0?{}:{clientTurnId:value.clientTurnId}}}function readClientMessageIdentity(value){let parsed=clientMessageIdentitySchema.safeParse(value);return parsed.success?clientMessageIdentity(parsed.data):{}}var MAX_RPC_MESSAGE_CHARACTERS=1e6,SESSION_CONTEXT_LIMITS={keys:32,valueBytes:16*1024,totalBytes:32*1024},SESSION_CONTEXT_KEY_PATTERN=/^[a-z][a-z0-9_]*$/;function validContent(content){return typeof content=="string"?!0:Array.isArray(content)&&content.every(item=>{if(typeof item!="object"||item===null)return!1;let value=item;return value.type==="text"?typeof value.text=="string":value.type==="image"&&typeof value.data=="string"&&typeof value.mimeType=="string"})}function validBaseEntry(entry){return typeof entry.id=="string"&&(entry.parentId===null||typeof entry.parentId=="string")&&typeof entry.timestamp=="string"}function validSessionEntry(entry){if(typeof entry!="object"||entry===null||Array.isArray(entry))return!1;let value=entry;if(!validBaseEntry(value))return!1;switch(value.type){case"message":{let message=value.message;if(typeof message!="object"||message===null)return!1;let item=message;return["user","assistant","tool"].includes(item.role)&&validContent(item.content)}case"thinking_level_change":return typeof value.thinkingLevel=="string";case"model_change":return typeof value.provider=="string"&&typeof value.modelId=="string";case"model_change_rejected":return typeof value.provider=="string"&&typeof value.modelId=="string"&&typeof value.detail=="string";case"compaction":return typeof value.summary=="string"&&typeof value.firstKeptEntryId=="string"&&typeof value.tokensBefore=="number";case"branch_summary":return typeof value.fromId=="string"&&typeof value.summary=="string";case"custom":return typeof value.customType=="string";case"custom_message":return typeof value.customType=="string"&&validContent(value.content)&&typeof value.display=="boolean";case"label":return typeof value.targetId=="string"&&(value.label===void 0||typeof value.label=="string");case"session_info":return value.name===void 0||typeof value.name=="string";default:return!1}}function rpcCommandPayloadError(command){if(rpcCommandShapeError(command))return;let value=command;if((value.type==="prompt"||value.type==="steer"||value.type==="follow_up")&&!clientMessageIdentitySchema.safeParse(value).success)return"clientMessageId and clientTurnId must be non-empty strings of at most 256 characters.";if((value.type==="steer"||value.type==="follow_up")&&value.enqueueOrder!==void 0&&!(typeof value.enqueueOrder=="number"&&Number.isFinite(value.enqueueOrder)))return"enqueueOrder must be a finite number.";if(value.type==="append_user_message"&&!validContent(value.content))return"append_user_message content must be a string or text/image content array.";if(value.type==="append_session_entry"&&!validSessionEntry(value.entry))return"append_session_entry entry is malformed."}function sessionContextError(context){if(context===void 0)return;if(typeof context!="object"||context===null||Array.isArray(context))return"context must be an object of string values.";let entries=Object.entries(context);if(entries.length>SESSION_CONTEXT_LIMITS.keys)return`context has ${entries.length} keys, at most ${SESSION_CONTEXT_LIMITS.keys} are accepted.`;for(let[key,value]of entries){if(!SESSION_CONTEXT_KEY_PATTERN.test(key))return`context key "${key}" must match ${SESSION_CONTEXT_KEY_PATTERN.source}.`;if(typeof value!="string")return`context value for key "${key}" must be a string.`;let valueBytes=Buffer.byteLength(value);if(valueBytes>SESSION_CONTEXT_LIMITS.valueBytes)return`context value for key "${key}" is ${valueBytes} bytes, at most ${SESSION_CONTEXT_LIMITS.valueBytes} bytes are accepted.`}let totalBytes=Buffer.byteLength(JSON.stringify(context));if(totalBytes>SESSION_CONTEXT_LIMITS.totalBytes)return`context is ${totalBytes} bytes of JSON, at most ${SESSION_CONTEXT_LIMITS.totalBytes} bytes are accepted.`}function sessionKindError(kind){if(!(kind===void 0||kind==="interactive"||kind==="worker"))return'kind must be "interactive" or "worker".'}function sessionAutoTitleError(value){if(!(value===void 0||typeof value=="boolean"))return"auto_title must be a boolean."}function sessionPromptSurfaceError(value){if(!(value===void 0||value==="terminal"||value==="app"||value==="chat"))return'promptSurface must be "terminal", "app" or "chat".'}function sessionBrowserEngineError(value){if(!(value===void 0||isBrowserEngine(value)))return'browserEngine must be "connected", "builtin" or "none".'}var MAX_RETRY_FALLBACK_CHAINS=32,MAX_RETRY_FALLBACK_ENTRIES=32,MAX_RETRY_FALLBACK_SELECTOR_LENGTH=512;function sessionRetryFallbackError(value){if(value===void 0)return;let shape="retryFallback must be { modelFallback: boolean, fallbackChains: Record<string, string[]> }.";if(typeof value!="object"||value===null||Array.isArray(value))return shape;let record=value;if(typeof record.modelFallback!="boolean")return shape;let chains=record.fallbackChains;if(typeof chains!="object"||chains===null||Array.isArray(chains))return shape;let entries=Object.entries(chains);if(entries.length>MAX_RETRY_FALLBACK_CHAINS)return`retryFallback allows at most ${MAX_RETRY_FALLBACK_CHAINS} chains.`;for(let[key,selectors]of entries){if(!isSelector(key)||!Array.isArray(selectors)||!selectors.every(isSelector))return shape;if(selectors.length>MAX_RETRY_FALLBACK_ENTRIES)return`retryFallback allows at most ${MAX_RETRY_FALLBACK_ENTRIES} entries per chain.`}}function isSelector(value){return typeof value=="string"&&value.trim().length>0&&value.length<=MAX_RETRY_FALLBACK_SELECTOR_LENGTH}function rpcCommandShapeError(command){if(typeof command!="object"||command===null||Array.isArray(command))return"RPC command must be a JSON object."}function rpcMessageLengthError(command){if(rpcCommandShapeError(command))return;let input=command;if(!(input.type!=="prompt"&&input.type!=="steer"&&input.type!=="follow_up")&&!(typeof input.message!="string"||input.message.length<=MAX_RPC_MESSAGE_CHARACTERS))return`RPC ${input.type} message exceeds ${MAX_RPC_MESSAGE_CHARACTERS} characters.`}import{randomUUID}from"node:crypto";import{mkdir,rm,writeFile}from"node:fs/promises";import{join}from"node:path";import{setTimeout as delay}from"node:timers/promises";import{Worker}from"node:worker_threads";var RECURSIVE_WATCH_WORKER_SOURCE=`
3
3
  const { watch } = require("node:fs");
4
4
  const { parentPort } = require("node:worker_threads");
5
5
 
@@ -0,0 +1,3 @@
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{getAgentDir}from"./chunk-463OK2Y4.js";import{accessSync,existsSync,lstatSync as lstatSync2,realpathSync,statSync}from"node:fs";import{homedir as homedir3}from"node:os";import{basename as basename3,dirname as dirname3,join as join4,resolve as resolve2}from"node:path";import{closeSync,constants,fstatSync,lstatSync,openSync,readSync}from"node:fs";import{lstat,open}from"node:fs/promises";import{join as join2}from"node:path";import path,{posix,win32}from"node:path";var MOVED_BREADCRUMB_FILE="omo-desktop-moved.json",MOVED_BREADCRUMB_KIND="omo-desktop-moved",MOVED_BREADCRUMB_SCHEMA_VERSION=1;function ignored(reason){return{kind:"ignored",reason}}function prefixSegments(prefix){if(typeof prefix!="string"||posix.isAbsolute(prefix)||win32.isAbsolute(prefix))return;let segments=prefix.split(/[\\/]/).filter(segment=>segment.length>0);if(!(segments.length===0||segments.some(segment=>segment==="."||segment==="..")))return segments}function isNormalizedAbsolute(value,host){return!host.isAbsolute(value)||host.normalize(value)!==value?!1:value===host.parse(value).root||!(value.endsWith("/")||value.endsWith(host.sep))}function parseMovedBreadcrumb(raw,host=path){if(typeof raw!="object"||raw===null)return ignored("not an object");let record=raw;if(record.kind!==MOVED_BREADCRUMB_KIND)return ignored("foreign kind");let version=record.schemaVersion;if(typeof version!="number"||!Number.isInteger(version)||version<1)return ignored("invalid schemaVersion");if(version>MOVED_BREADCRUMB_SCHEMA_VERSION)return ignored(`unsupported schemaVersion ${version}`);let movedTo=record.movedTo;if(typeof movedTo!="string"||!isNormalizedAbsolute(movedTo,host))return ignored("movedTo is not a normalized absolute path on this host");let homeId=record.homeId;if(typeof homeId!="string"||homeId.length===0)return ignored("homeId is missing");if(!Array.isArray(record.moved))return ignored("moved is not an array");let moved=[];for(let prefix of record.moved){let segments=prefixSegments(prefix);if(!segments)return ignored(`invalid moved prefix ${JSON.stringify(prefix)}`);moved.push(segments)}return{kind:"valid",breadcrumb:{movedTo,homeId,moved}}}import{appendFile,mkdir,rename,stat}from"node:fs/promises";import{dirname,join}from"node:path";var MAX_GUARD_LOG_BYTES=1024*1024,reported=new Set,pending=Promise.resolve();function guardLogPath(){return join(getAgentDir(),"logs","moved-path-guard.log")}async function append(line){let file=guardLogPath();await mkdir(dirname(file),{recursive:!0,mode:448}),await stat(file).then(stats=>stats.size,()=>0)+Buffer.byteLength(line)>MAX_GUARD_LOG_BYTES&&await rename(file,`${file}.1`),await appendFile(file,line,{mode:384})}function logGuardEvent(level,event,details){let{count:_count,...reason}=details,key=`${event}\0${JSON.stringify(reason)}`;if(reported.has(key))return;reported.add(key);let line=`${JSON.stringify({ts:new Date().toISOString(),level,event,...details})}
3
+ `;pending=pending.then(()=>append(line)).catch(()=>{})}var DESKTOP_HOME_MARKER_FILE="omo-desktop-home.json";function parseDesktopHomeMarker(raw){if(typeof raw!="object"||raw===null)return{kind:"invalid"};let record=raw;return record.kind!=="omo-desktop-data-home"||record.appId!=="com.omo.desktop"?{kind:"invalid"}:typeof record.schemaVersion=="number"&&record.schemaVersion>1?{kind:"newer",schemaVersion:record.schemaVersion}:record.schemaVersion!==1||typeof record.homeId!="string"||record.homeId.length===0?{kind:"invalid"}:{kind:"valid",homeId:record.homeId}}function currentPathPlatform(){return process.platform==="win32"?"win32":process.platform==="darwin"?"darwin":"posix"}function pathSegments(path2,platform){return platform!=="win32"?path2.split("/").filter(segment=>segment.length>0):(path2.startsWith("\\\\?\\UNC\\")?`\\\\${path2.slice(8)}`:path2.startsWith("\\\\?\\")?path2.slice(4):path2).split(/[\\/]/).filter(segment=>segment.length>0)}function sameSegment(a,b,platform){return platform==="posix"?a===b:a.toLowerCase()===b.toLowerCase()}function startsWithSegments(path2,prefix,platform){return prefix.length<=path2.length&&prefix.every((segment,index)=>sameSegment(path2[index]??"",segment,platform))}function matchMovedPrefix(path2,root,moved,platform){let pathParts=pathSegments(path2,platform),rootParts=pathSegments(root,platform);if(!startsWithSegments(pathParts,rootParts,platform))return;let remainder=pathParts.slice(rootParts.length),prefix=moved.find(candidate=>startsWithSegments(remainder,candidate,platform));return prefix?{prefix,remainder}:void 0}var MAX_HOPS=3,MAX_TRUST_FILE_BYTES=64*1024,jsonByFile=new Map;function parseJson(text){try{return JSON.parse(text)}catch{return}}function trustStamp(stats){if(!(!stats.isFile()||stats.size>MAX_TRUST_FILE_BYTES)&&!(process.platform!=="win32"&&(stats.uid!==process.getuid?.()||(stats.mode&18)!==0)))return`${stats.mtimeMs}:${stats.size}:${stats.ino}`}var OPEN_FLAGS=constants.O_RDONLY|(constants.O_NOFOLLOW??0)|(constants.O_NONBLOCK??0),NEEDS_LSTAT_FIRST=constants.O_NONBLOCK===void 0;function remembered(file,stamp,read){let cached=jsonByFile.get(file);if(cached?.stamp===stamp)return cached.value;let value=parseJson(read().toString("utf8"));return jsonByFile.set(file,{stamp,value}),value}function readJsonFileSync(file){let fd;try{if(NEEDS_LSTAT_FIRST&&!lstatSync(file).isFile())return;fd=openSync(file,OPEN_FLAGS)}catch{return}try{let stats=fstatSync(fd),stamp=trustStamp(stats);return stamp===void 0?void 0:remembered(file,stamp,()=>{let buffer=Buffer.alloc(stats.size);return buffer.subarray(0,readSync(fd,buffer,0,stats.size,0))})}finally{closeSync(fd)}}async function readJsonFileAsync(file){if(NEEDS_LSTAT_FIRST&&!await lstat(file).then(stats=>stats.isFile(),()=>!1))return;let handle=await open(file,OPEN_FLAGS).catch(()=>{});if(handle)try{let stats=await handle.stat(),stamp=trustStamp(stats);if(stamp===void 0)return;let cached=jsonByFile.get(file);if(cached?.stamp===stamp)return cached.value;let buffer=Buffer.alloc(stats.size),{bytesRead}=await handle.read(buffer,0,stats.size,0);return remembered(file,stamp,()=>buffer.subarray(0,bytesRead))}finally{await handle.close()}}var breadcrumbFile=dir=>join2(dir,MOVED_BREADCRUMB_FILE),homeMarkerFile=movedTo=>join2(movedTo,DESKTOP_HOME_MARKER_FILE);function ignoreBreadcrumb(file,reason){logGuardEvent("debug","breadcrumb_ignored",{file,reason})}function movedToInHome(dir,breadcrumb,homes,platform){return homes.some(home=>matchMovedPrefix(breadcrumb.movedTo,home,[[]],platform))?!0:(ignoreBreadcrumb(breadcrumbFile(dir),"movedTo is outside the user's home"),!1)}function trustedFolder(dir,stats){return stats===void 0?!1:process.platform==="win32"||stats.isDirectory()&&stats.uid===process.getuid?.()&&(stats.mode&18)===0?!0:(ignoreBreadcrumb(breadcrumbFile(dir),"its folder is shared or not the user's"),!1)}function parsedBreadcrumb(dir,raw){if(raw===void 0)return;let parsed=parseMovedBreadcrumb(raw);return parsed.kind==="valid"?parsed.breadcrumb:ignoreBreadcrumb(breadcrumbFile(dir),parsed.reason)}function trustedBreadcrumb(dir,breadcrumb,markerRaw,platform){if(matchMovedPrefix(breadcrumb.movedTo,dir,[[]],platform))return ignoreBreadcrumb(breadcrumbFile(dir),"movedTo is the breadcrumb's own folder or inside it");let marker=parseDesktopHomeMarker(markerRaw);if(marker.kind==="newer"){logGuardEvent("warn","marker_newer",{file:homeMarkerFile(breadcrumb.movedTo),schemaVersion:String(marker.schemaVersion)});return}return marker.kind!=="valid"||marker.homeId!==breadcrumb.homeId?ignoreBreadcrumb(breadcrumbFile(dir),"movedTo holds no desktop home marker with this homeId"):breadcrumb}function movedMatch(dir,breadcrumb,canonical,platform){let match=matchMovedPrefix(canonical,dir,breadcrumb.moved,platform);if(match)return{prefix:match.prefix,moved:{oldRoot:dir,movedTo:breadcrumb.movedTo,mappedPath:join2(breadcrumb.movedTo,...match.remainder)}}}var gitEntryOf=(oldRoot,prefix)=>prefix.includes("worktrees")?join2(oldRoot,...prefix,".git"):void 0;function movedPathReason(moved){return`This folder moved to ${moved.movedTo}. Use ${moved.mappedPath}.`}import{homedir as homedir2}from"node:os";import{basename as basename2,dirname as dirname2,resolve}from"node:path";import{homedir}from"node:os";import{basename,join as join3}from"node:path";var LEGACY_ROOT_NAMES=[".t3",".omo-app"],legacyRoots=()=>LEGACY_ROOT_NAMES.map(name=>join3(homedir(),name)),isLegacyRoot=(path2,homes,platform)=>homes.some(home=>LEGACY_ROOT_NAMES.some(name=>matchMovedPrefix(path2,join3(home,name),[[]],platform)?.remainder.length===0)),known=new Map,prefixKey=(oldRoot,breadcrumb,prefix)=>[basename(oldRoot).toLowerCase(),breadcrumb.homeId,breadcrumb.movedTo,prefix.join("/")].join("\0");function knownPrefixKeys(path2,platform=currentPathPlatform()){return[...known].flatMap(([spelling,{root,breadcrumb}])=>{let match=matchMovedPrefix(path2,spelling,breadcrumb.moved,platform);return match?[prefixKey(root,breadcrumb,match.prefix)]:[]})}var reusedDecisions=new Map;function rememberReused(key,reused){reusedDecisions.set(key,reused)}function rememberedReused(key){return reusedDecisions.get(key)}function rememberTrustedBreadcrumb(root,called,breadcrumb,homes,platform){let spellings=new Set(called===void 0?[root]:[root,called]);for(let spelling of[...spellings])for(let home of homes){let under=matchMovedPrefix(spelling,home,[[]],platform);if(under)for(let other of homes)spellings.add(join3(other,...under.remainder))}for(let spelling of spellings)known.set(spelling,{root,breadcrumb})}function looksMoved(path2,platform=currentPathPlatform()){return legacyRoots().some(root=>matchMovedPrefix(path2,root,[[]],platform))||[...known].some(([spelling,{breadcrumb}])=>matchMovedPrefix(path2,spelling,breadcrumb.moved,platform))}function knownMove(path2,platform=currentPathPlatform()){for(let[oldRoot,{root,breadcrumb}]of known){let match=matchMovedPrefix(path2,oldRoot,breadcrumb.moved,platform);if(match&&rememberedReused(prefixKey(root,breadcrumb,match.prefix))!==!0)return{oldRoot,movedTo:breadcrumb.movedTo,mappedPath:join3(breadcrumb.movedTo,...match.remainder)}}}function*homeSpellings(){let home=homedir2(),real=yield{op:"home"};return real!==void 0&&real!==home?[home,real]:[home]}function calledSpelling(path2,canonical,dir,homes,platform){let called=resolve(path2);for(let below=canonical;below!==dir;below=dirname2(below)){if(dirname2(called)===called||!sameSegment(basename2(called),basename2(below),platform))return;called=dirname2(called)}return isLegacyRoot(called,homes,platform)?called:void 0}function*movedOnce(path2,platform,onReused){let canonical=(yield{op:"canonical",path:path2})??resolve(path2),stop=dirname2(homedir2());for(let dir=dirname2(canonical);;dir=dirname2(dir)){let breadcrumb=parsedBreadcrumb(dir,yield{op:"json",file:breadcrumbFile(dir)}),match=breadcrumb&&movedMatch(dir,breadcrumb,canonical,platform),homes=match?yield*homeSpellings():[];if(match&&movedToInHome(dir,breadcrumb,homes,platform)&&trustedFolder(dir,yield{op:"folder",path:dir,follow:isLegacyRoot(dir,homes,platform)})&&trustedBreadcrumb(dir,breadcrumb,yield{op:"json",file:homeMarkerFile(breadcrumb.movedTo)},platform)){let gitEntry=gitEntryOf(dir,match.prefix),reused=!1;if(gitEntry!==void 0){let key=prefixKey(dir,breadcrumb,match.prefix),answer2=yield{op:"exists",path:gitEntry};typeof answer2=="boolean"&&rememberReused(key,answer2),reused=typeof answer2=="boolean"?answer2:rememberedReused(key)??!1}if(reused&&onReused?.(dir,breadcrumb,match.prefix),rememberTrustedBreadcrumb(dir,calledSpelling(path2,canonical,dir,homes,platform),breadcrumb,homes,platform),!reused)return match.moved}if(dir===stop||dirname2(dir)===dir)return}}function*movedPathWalk(path2,platform,onReused){let found;for(let hop=0;hop<MAX_HOPS;hop++){let next=yield*movedOnce(found?.mappedPath??path2,platform,onReused);if(!next)break;found=found?{...next,oldRoot:found.oldRoot}:next}return found}function canonicalPath(path2){let missing=[],existing=resolve2(path2);for(;!existsSync(existing);){let parent=dirname3(existing);if(parent===existing)return resolve2(path2);missing.unshift(basename3(existing)),existing=parent}return join4(realpathSync(existing),...missing)}function pathExistsSync(path2){try{return accessSync(path2),!0}catch(error){let code=error?.code;return code==="ENOENT"||code==="ENOTDIR"?!1:void 0}}function answer(step){try{return step.op==="canonical"?canonicalPath(step.path):step.op==="json"?readJsonFileSync(step.file):step.op==="home"?realpathSync(homedir3()):step.op==="folder"?(step.follow?statSync:lstatSync2)(step.path):pathExistsSync(step.path)}catch{return void 0}}function findMovedPath(path2,platform=currentPathPlatform()){let walk=movedPathWalk(path2,platform),step=walk.next();for(;!step.done;)step=walk.next(answer(step.value));return step.value}function resolveMovedPath(path2){return findMovedPath(path2)?.mappedPath??path2}export{logGuardEvent,currentPathPlatform,readJsonFileAsync,movedPathReason,prefixKey,knownPrefixKeys,looksMoved,knownMove,movedPathWalk,resolveMovedPath};
@@ -0,0 +1,2 @@
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
+ var GATEWAY_NAMESPACE=/^mcp__(.+)$/i,GATEWAY_DELIMITER=/_{2,}/g,SERVER_NAMESPACE=/^mcp_([^_]+)_(.+)$/i;function foldToolName(name){return name.toLowerCase().replaceAll(/[-_]/g,"")}function toolNameForms(name){let forms=[name],gateway=GATEWAY_NAMESPACE.exec(name);if(gateway){let rest=gateway[1]??"";for(let run of rest.matchAll(GATEWAY_DELIMITER)){let suffix=rest.slice(run.index+run[0].length);run.index>0&&suffix.length>0&&forms.push(suffix)}return forms}let tool=SERVER_NAMESPACE.exec(name)?.[2];return tool!==void 0&&forms.push(tool),forms}function uniqueMatch(names,matches){let found=names.filter(matches);return found.length===1?found[0]:void 0}function resolveToolNameMatch(requested,available){let names=[...new Set(available)];for(let form of toolNameForms(requested)){if(names.includes(form))return form;let key=foldToolName(form),folded=uniqueMatch(names,name=>foldToolName(name)===key);if(folded!==void 0)return folded;let unprefixed=uniqueMatch(names,name=>toolNameForms(name).slice(1).some(registeredForm=>foldToolName(registeredForm)===key));if(unprefixed!==void 0)return unprefixed}}export{resolveToolNameMatch};
@@ -0,0 +1,2 @@
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{__commonJS}from"./chunk-IKOFCODM.js";var require_ignore=__commonJS({"node_modules/ignore/index.js"(exports,module){function makeArray(subject){return Array.isArray(subject)?subject:[subject]}var UNDEFINED=void 0,EMPTY="",SPACE=" ",ESCAPE="\\",REGEX_LITERAL_SPECIAL=/[.*+?()[\]{}^$|\\/]/,REGEX_TEST_BLANK_LINE=/^\uFEFF? *$/,REGEX_INVALID_TRAILING_BACKSLASH=/(?:[^\\]|^)\\$/,REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION=/^\\!/,REGEX_REPLACE_LEADING_EXCAPED_HASH=/^\\#/,REGEX_SPLITALL_CRLF=/\r?\n/g,DOUBLE_SLASH="//",SLASH_CODE=47,DOT_CODE=46,SLASH="/",TMP_KEY_IGNORE="node-ignore";typeof Symbol<"u"&&(TMP_KEY_IGNORE=Symbol.for("node-ignore"));var KEY_IGNORE=TMP_KEY_IGNORE,define=(object,key,value)=>(Object.defineProperty(object,key,{value}),value),RETURN_FALSE=()=>!1,cleanRangeBackSlash=slashes=>{let{length}=slashes;return slashes.slice(0,length-length%2)},POSIX_CLASSES={alnum:"0-9A-Za-z",alpha:"A-Za-z",blank:" \\t",cntrl:"\\x00-\\x1f\\x7f",digit:"0-9",graph:"!-.0-~",lower:"a-z",print:" -.0-~",punct:"!-.:-@\\[-`{-~",space:" \\t\\n\\r",upper:"A-Z",xdigit:"0-9A-Fa-f"},CLASS_MEMBERS_TO_ESCAPE="\\]^-[",escapeMember=char=>CLASS_MEMBERS_TO_ESCAPE.indexOf(char)<0?char:ESCAPE+char,NON_SLASH="(?!\\/)",classSource=(negated,body)=>{if(negated)return`[^\\/${body}]`;let source=`[${body}]`;return new RegExp(source).test("/")?NON_SLASH+source:source},scanBracket=(pattern,start)=>{let{length}=pattern,index=start+1,negated=EMPTY,lead=pattern[index];(lead==="!"||lead==="^")&&(negated="^",index++);let body=EMPTY,prev=EMPTY;for(;;){let char=pattern[index];if(char===UNDEFINED)return null;if(char===ESCAPE){let escaped=pattern[index+1];if(escaped===UNDEFINED)return null;body+=escapeMember(escaped),prev=escaped,index++}else if(char==="-"&&prev&&index+1<length&&pattern[index+1]!=="]"){index++;let to=pattern[index];to===ESCAPE&&(to=pattern[index+=1]),prev<=to&&(body+=`-${escapeMember(to)}`),prev=EMPTY}else if(char==="["&&pattern[index+1]===":"){let nameStart=index+2,end=nameStart;for(;end<length&&pattern[end]!=="]";)end++;if(end===length)return null;if(end>nameStart&&pattern[end-1]===":"){let expanded=POSIX_CLASSES[pattern.slice(nameStart,end-1)];if(expanded===UNDEFINED)return null;body+=expanded,prev=EMPTY,index=end}else body+=escapeMember("["),prev="[",index=nameStart-2}else body+=escapeMember(char),prev=char;if(index++,pattern[index]==="]")return{end:index,source:classSource(negated,body)}}},NEVER_MATCH="[]",PLACEHOLDER="\0",REGEX_RESTORE_PLACEHOLDER=new RegExp(`${PLACEHOLDER}(\\d+)${PLACEHOLDER}`,"g"),TRAILING_WILDCARD="\uE000",extractBrackets=pattern=>{let sources=[],hold=source=>`${PLACEHOLDER}${sources.push(source)-1}${PLACEHOLDER}`,{length}=pattern,out=EMPTY,index=0;for(;index<length;){let char=pattern[index];if(char===ESCAPE){let escaped=pattern[index+1];escaped==="*"||escaped==="["||escaped===SPACE||escaped===ESCAPE?out+=pattern.slice(index,index+2):out+=hold(REGEX_LITERAL_SPECIAL.test(escaped)?ESCAPE+escaped:escaped),index+=2}else if(char===PLACEHOLDER)out+=hold(`[${PLACEHOLDER}]`),index++;else if(char==="["){let scanned=scanBracket(pattern,index);scanned===null?(out+=hold(NEVER_MATCH),index=length):(out+=hold(scanned.source),index=scanned.end+1)}else out+=char,index++}return{source:out,sources}},DIRECT=null,REGEX_INNER_SLASH=/\/(?!$)/,REPLACERS=[[/^\uFEFF/,()=>EMPTY,"\uFEFF"],[/[\r\n]+$/,()=>EMPTY],[/((?:\\\\)*?)(\\? +)$/,(_,m1,m2)=>m1+(m2.indexOf("\\")===0?SPACE:EMPTY)],[/(\\+?) /g,(_,m1)=>{let{length}=m1;return m1.slice(0,length-length%2)+SPACE}],[/[\\$.|*+(){^]/g,match=>`\\${match}`],[/(?!\\)\?/g,()=>"[^/]","?"],[/^\//,()=>"^",SLASH],[/\//g,()=>"\\/",SLASH],[/^\^*(?:\\\*\\\*\\\/)+/,()=>"^(?:.*\\/)?","*"],[DIRECT,(source,pattern)=>!source||source[0]==="^"?source:(REGEX_INNER_SLASH.test(pattern)?"^":"(?:^|\\/)")+source],[/\\\/\\\*\\\*(?=\\\/|$)/g,(_,index,str)=>index+6<str.length?str.slice(index+6)==="\\/"?"(?:\\/[^\\/]+)+":"(?:\\/[^\\/]+)*":"\\/.+","*"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(_,p1,p2)=>{let unescaped=p2.replace(/\\\*/g,"[^\\/]*");return p1+unescaped},"*"],[/(^|[^\\])((?:\\\\)*)\\\*$/,(match,p1,p2)=>p2.length/2%2===0?p1+p2+TRAILING_WILDCARD:match,"*"],[/\\\\\\(?=[$.|*+(){^])/g,()=>ESCAPE,ESCAPE+ESCAPE],[/\\\\/g,()=>ESCAPE,ESCAPE+ESCAPE],[/\\\[([^\]/]*?)(\\*)($|\])/g,(match,range,endEscape,close)=>`\\[${range}${cleanRangeBackSlash(endEscape)}${close}`,"["],[DIRECT,source=>{let last=source[source.length-1];return!last||last===TRAILING_WILDCARD?source:last===SLASH?`${source}$`:`${source}(?=$|\\/$)`}]],REGEX_REPLACE_TRAILING_WILDCARD=/(^|\\\/)?\uE000$/,MODE_IGNORE="regex",MODE_CHECK_IGNORE="checkRegex",UNDERSCORE="_",TRAILING_WILD_CARD_REPLACERS={[MODE_IGNORE](_,p1){return`${p1?`${p1}[^/]+`:"[^/]*"}(?=$|\\/$)`},[MODE_CHECK_IGNORE](_,p1){return`${p1?`${p1}[^/]*`:"[^/]*"}(?=$|\\/$)`}},WILDCARD="[^\\/]*",pinWildcards=source=>{if(source.indexOf(WILDCARD)<0)return source;let tokens=[],{length}=source,index=0;for(;index<length;){let char=source[index];if(source.startsWith(WILDCARD,index))tokens.push({wildcard:!0}),index+=WILDCARD.length;else if(char==="["){let end=index+1;for(source[end]==="^"&&end++,source[end]==="]"&&end++;end<length&&source[end]!=="]";)end+=source[end]===ESCAPE?2:1;end++,tokens.push({single:source.slice(index,end)}),index=end}else if(char===ESCAPE)tokens.push({single:source.slice(index,index+2)}),index+=2;else if(char==="("){let depth=0,end=index;do source[end]===ESCAPE?end++:source[end]==="("?depth++:source[end]===")"&&depth--,end++;while(end<length&&depth>0);"*+?".indexOf(source[end])>=0&&end++,tokens.push({boundary:source.slice(index,end)}),index=end}else char==="^"||char==="$"?(tokens.push({boundary:char}),index++):(tokens.push({single:char}),index++)}let out=EMPTY,run=[],flush=()=>{let lastWildcard;run.forEach((token,at)=>{token.wildcard&&(lastWildcard=at)}),run.forEach((token,at)=>{if(!token.wildcard){out+=token.single;return}out+=at===lastWildcard?WILDCARD:`(?:(?!${run[at+1].single})[^\\/])*`}),run=[]};return tokens.forEach(token=>{if(token.boundary===void 0){run.push(token);return}flush(),out+=token.boundary}),flush(),out},makeRegexPrefix=pattern=>{let{source,sources}=extractBrackets(pattern),replaced=REPLACERS.reduce((prev,[matcher,replacer,required])=>matcher===DIRECT?replacer(prev,pattern):required!==UNDEFINED&&prev.indexOf(required)<0?prev:matcher.test(prev)?prev.replace(matcher,replacer.bind(pattern)):prev,source);return sources.length?replaced.replace(REGEX_RESTORE_PLACEHOLDER,(match,index)=>sources[index]):replaced},matchesBasename=body=>{let index=body.indexOf(SLASH);return index<0||index===body.length-1},basenameOf=path=>{let end=path.length-1,index=path.lastIndexOf(SLASH,path[end]===SLASH?end-1:end);return index<0?path:path.slice(index+1)},parentOf=path=>{if(path.charCodeAt(0)===SLASH_CODE||path.indexOf(DOUBLE_SLASH)>=0){let slices=path.split(SLASH).filter(Boolean);return slices.pop(),slices.length?slices.join(SLASH)+SLASH:EMPTY}let end=path.length-1,cut=path.lastIndexOf(SLASH,path.charCodeAt(end)===SLASH_CODE?end-1:end);return cut<0?EMPTY:path.slice(0,cut+1)},isString=subject=>typeof subject=="string",checkPattern=pattern=>pattern&&isString(pattern)&&!REGEX_TEST_BLANK_LINE.test(pattern)&&!REGEX_INVALID_TRAILING_BACKSLASH.test(pattern)&&pattern.indexOf("#")!==0,splitPattern=pattern=>pattern.split(REGEX_SPLITALL_CRLF).filter(Boolean),IgnoreRule=class{constructor(pattern,mark,body,ignoreCase,negative,prefix){this.pattern=pattern,this.mark=mark,this.negative=negative,define(this,"body",body),define(this,"ignoreCase",ignoreCase),define(this,"regexPrefix",prefix)}get _basenameOnly(){return define(this,"_basenameOnly",matchesBasename(this.body))}get regex(){let key=UNDERSCORE+MODE_IGNORE;return this[key]?this[key]:this._make(MODE_IGNORE,key)}get checkRegex(){let key=UNDERSCORE+MODE_CHECK_IGNORE;return this[key]?this[key]:this._make(MODE_CHECK_IGNORE,key)}_make(mode,key){let str=pinWildcards(this.regexPrefix.replace(REGEX_REPLACE_TRAILING_WILDCARD,TRAILING_WILD_CARD_REPLACERS[mode])),regex=this.ignoreCase?new RegExp(str,"i"):new RegExp(str);return define(this,key,regex)}},createRule=({pattern,mark},ignoreCase)=>{let negative=!1,body=pattern;body.indexOf("!")===0&&(negative=!0,body=body.substr(1)),body=body.replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION,"!").replace(REGEX_REPLACE_LEADING_EXCAPED_HASH,"#");let regexPrefix=makeRegexPrefix(body);return new IgnoreRule(pattern,mark,body,ignoreCase,negative,regexPrefix)},RuleManager=class{constructor(ignoreCase){this._ignoreCase=ignoreCase,this._rules=[],this._basenameCount=0}_add(pattern){if(pattern&&pattern[KEY_IGNORE]){this._rules=this._rules.concat(pattern._rules._rules),this._basenameCount+=pattern._rules._basenameCount,this._added=!0;return}if(isString(pattern)&&(pattern={pattern}),checkPattern(pattern.pattern)){let rule=createRule(pattern,this._ignoreCase);this._added=!0,this._rules.push(rule),matchesBasename(rule.body)&&this._basenameCount++}}add(pattern){return this._added=!1,makeArray(isString(pattern)?splitPattern(pattern):pattern).forEach(this._add,this),this._added}test(path,checkUnignored,mode){let ignored=!1,unignored=!1,matchedRule,rules=this._rules,{length}=rules,shortcut=this._basenameCount*2>=length,basename=shortcut?basenameOf(path):path;for(let index=0;index<length;index++){let rule=rules[index],{negative}=rule;!(unignored===negative&&ignored!==unignored||negative&&!ignored&&!unignored&&!checkUnignored)&&rule[mode].test(shortcut&&rule._basenameOnly?basename:path)&&(ignored=!negative,unignored=negative,matchedRule=negative?UNDEFINED:rule)}let ret={ignored,unignored};return matchedRule&&(ret.rule=matchedRule),ret}},throwError=(message,Ctor)=>{throw new Ctor(message)},checkPath=(path,originalPath,doThrow)=>isString(path)?path?checkPath.isNotRelative(path)?doThrow(`path should be a \`path.relative()\`d string, but got "${originalPath}"`,RangeError):!0:doThrow("path must not be empty",TypeError):doThrow(`path must be a string, but got \`${originalPath}\``,TypeError),isNotRelative=path=>{let first=path.charCodeAt(0);if(first===SLASH_CODE)return!0;if(first!==DOT_CODE)return!1;if(path.length===1)return!0;let second=path.charCodeAt(1);return second===SLASH_CODE?!0:second!==DOT_CODE?!1:path.length===2||path.charCodeAt(2)===SLASH_CODE};checkPath.isNotRelative=isNotRelative;checkPath.convert=p=>p;var Ignore=class{constructor({ignorecase=!0,ignoreCase=ignorecase,allowRelativePaths=!1}={}){define(this,KEY_IGNORE,!0),this._rules=new RuleManager(ignoreCase),this._strictPathCheck=!allowRelativePaths,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}add(pattern){return this._rules.add(pattern)&&this._initCache(),this}addPattern(pattern){return this.add(pattern)}_test(originalPath,cache,checkUnignored){let path=originalPath&&checkPath.convert(originalPath);return checkPath(path,originalPath,this._strictPathCheck?throwError:RETURN_FALSE),this._t(path,cache,checkUnignored)}checkIgnore(path){if(path.charCodeAt(path.length-1)!==SLASH_CODE)return this.test(path);let parentPath=parentOf(path);if(parentPath){let parent=this._t(parentPath,this._testCache,!0);if(parent.ignored)return parent}return this._rules.test(path,!1,MODE_CHECK_IGNORE)}_t(path,cache,checkUnignored){if(path in cache)return cache[path];let parentPath=parentOf(path),parent=parentPath?this._t(parentPath,cache,checkUnignored):UNDEFINED;return cache[path]=parent&&parent.ignored?parent:this._rules.test(path,checkUnignored,MODE_IGNORE)}ignores(path){return this._test(path,this._ignoreCache,!1).ignored}createFilter(){return path=>!this.ignores(path)}filter(paths){return makeArray(paths).filter(this.createFilter())}test(path){return this._test(path,this._testCache,!0)}},factory=options=>new Ignore(options),isPathValid=path=>checkPath(path&&checkPath.convert(path),path,RETURN_FALSE),setupWindows=()=>{let makePosix=str=>/^\\\\\?\\/.test(str)||/["<>|\u0000-\u001F]+/u.test(str)?str:str.replace(/\\/g,"/");checkPath.convert=makePosix;let REGEX_TEST_WINDOWS_PATH_ABSOLUTE=/^[a-z]:\//i;checkPath.isNotRelative=path=>REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path)||isNotRelative(path)};typeof process<"u"&&process.platform==="win32"&&setupWindows();module.exports=factory;factory.default=factory;module.exports.isPathValid=isPathValid;define(module.exports,Symbol.for("setupWindows"),setupWindows)}});export{require_ignore};