@code-yeongyu/senpi 2026.10.26-2 → 2026.10.27-1

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 (61) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/bundle/chunks/{chunk-PPECSSWX.js → chunk-6CJC6JY4.js} +1 -1
  3. package/dist/bundle/chunks/chunk-NXQFBAUI.js +2 -0
  4. package/dist/bundle/chunks/{chunk-ESNSRUW4.js → chunk-P5E4EVQF.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-I2WFLKZ2.js → chunk-Q2A2V6NT.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-JPGT64RV.js → chunk-TV3UI63P.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-TQ67PB7U.js → chunk-TWHF52G6.js} +3 -3
  8. package/dist/bundle/chunks/chunk-ZAS4NBVK.js +410 -0
  9. package/dist/bundle/chunks/{chunk-RPW3XQW3.js → chunk-ZXIAVLJV.js} +75 -75
  10. package/dist/bundle/chunks/{cli-main-Q2GA53XM.js → cli-main-36FRZ7ZB.js} +1 -1
  11. package/dist/bundle/chunks/client-CBDPMWZJ.js +2 -0
  12. package/dist/bundle/chunks/{dispatch-5R3TYAYB.js → dispatch-W5PENPZM.js} +1 -1
  13. package/dist/bundle/chunks/{interactive-mode-5DEKY3YW.js → interactive-mode-5S7NNV2Z.js} +1 -1
  14. package/dist/bundle/chunks/{multi-session-host-OPR5VBFO.js → multi-session-host-E3OPE6HJ.js} +1 -1
  15. package/dist/bundle/chunks/{package-manager-cli-W55E3LHP.js → package-manager-cli-3XO456VE.js} +1 -1
  16. package/dist/bundle/chunks/protocol-GLNWYI5G.js +2 -0
  17. package/dist/bundle/chunks/{rpc-mode-IDUJTSYS.js → rpc-mode-GLWKLTMA.js} +1 -1
  18. package/dist/bundle/chunks/{session-control-endpoint-LMZH5JLH.js → session-control-endpoint-KLE2X4RR.js} +1 -1
  19. package/dist/bundle/chunks/session-worker.js +102 -102
  20. package/dist/bundle/cli.js +2 -2
  21. package/dist/bundle/index.js +1 -1
  22. package/dist/bundle/rpc-entry.js +1 -1
  23. package/dist/bundle/runtime-manifest.json +1 -1
  24. package/dist/core/extensions/builtin/anthropic-subscription/account-context.d.ts +15 -0
  25. package/dist/core/extensions/builtin/anthropic-subscription/account-context.js +53 -0
  26. package/dist/core/extensions/builtin/anthropic-subscription/auth-attempt.d.ts +3 -0
  27. package/dist/core/extensions/builtin/anthropic-subscription/auth-attempt.js +26 -9
  28. package/dist/core/extensions/builtin/anthropic-subscription/auth-lane-boundary.d.ts +16 -0
  29. package/dist/core/extensions/builtin/anthropic-subscription/auth-lane-boundary.js +27 -0
  30. package/dist/core/extensions/builtin/anthropic-subscription/auth-lane.d.ts +2 -13
  31. package/dist/core/extensions/builtin/anthropic-subscription/auth-lane.js +3 -26
  32. package/dist/core/extensions/builtin/anthropic-subscription/errors.js +3 -2
  33. package/dist/core/extensions/builtin/anthropic-subscription/guidance.d.ts +6 -1
  34. package/dist/core/extensions/builtin/anthropic-subscription/guidance.js +1 -1
  35. package/dist/core/extensions/builtin/anthropic-subscription/stream-guidance.js +13 -2
  36. package/dist/core/extensions/builtin/mcp/modern/consent-queue.js +1 -0
  37. package/dist/core/extensions/builtin/mcp/modern/request.js +3 -2
  38. package/dist/core/extensions/builtin/mcp/sdk.lazy.d.ts +2 -0
  39. package/dist/core/extensions/builtin/mcp/sdk.lazy.js +2 -0
  40. package/dist/core/extensions/builtin/mcp/transport-sdk.js +12 -1
  41. package/dist/modes/interactive/interactive-mode.d.ts +2 -1
  42. package/dist/modes/interactive/interactive-mode.js +2 -1
  43. package/dist/modes/rpc/compact-commit-dependencies.d.ts +13 -0
  44. package/dist/modes/rpc/compact-commit-dependencies.js +48 -0
  45. package/dist/modes/rpc/compact-content-index.d.ts +1 -2
  46. package/dist/modes/rpc/compact-content-index.js +12 -23
  47. package/dist/modes/rpc/compact-content-store.d.ts +6 -2
  48. package/dist/modes/rpc/compact-content-store.js +40 -7
  49. package/dist/modes/rpc/compact-read-lease.d.ts +15 -0
  50. package/dist/modes/rpc/compact-read-lease.js +40 -0
  51. package/dist/modes/rpc/compact-session-state.d.ts +7 -28
  52. package/dist/modes/rpc/compact-session-state.js +58 -31
  53. package/dist/modes/rpc/compact-spool-storage.d.ts +5 -0
  54. package/dist/modes/rpc/compact-spool-storage.js +33 -0
  55. package/dist/modes/rpc/compact-text-roots.d.ts +22 -0
  56. package/dist/modes/rpc/compact-text-roots.js +138 -0
  57. package/dist/modes/rpc/compact-text-view.d.ts +22 -0
  58. package/dist/modes/rpc/compact-text-view.js +16 -0
  59. package/package.json +6 -6
  60. package/dist/bundle/chunks/chunk-2XF6W6F6.js +0 -410
  61. package/dist/bundle/chunks/client-LOS6GSEW.js +0 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [2026.10.27-1] - 2026-10-26
4
+
5
+ ### Breaking Changes
6
+
7
+ ### Added
8
+
9
+ ### Changed
10
+
11
+ ### Fixed
12
+
13
+ - Preserve startup diagnostics when an MCP stdio child exits before protocol classification, and follow the SDK's default timeout for modern multi-round requests ([#4226](https://github.com/code-yeongyu/senpi/issues/4226)).
14
+ - Claude subscription billing errors identify the attempted account and source and offer effective account-switch or top-up actions. Attempt-open logs include store and account provenance as salted digests, without account names or absolute paths ([#4364](https://github.com/code-yeongyu/senpi/pull/4364)).
15
+
16
+ ### Removed
17
+
3
18
  ## [2026.10.26-2] - 2026-10-26
4
19
 
5
20
  ### Breaking Changes
@@ -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{CONFIG_COMMAND_ARGV,HOST_COMMAND_ARGV,SCHEDULE_COMMAND_ARGV,isPackageCommandArgv}from"./chunk-ESNSRUW4.js";import{homedir}from"node:os";try{process.cwd()}catch{let fallback=homedir();process.chdir(fallback),console.error(`the current working directory no longer exists; continuing from ${fallback}`)}import*as nodeModule from"node:module";async function enableStartupCompileCache(){let enable=nodeModule.enableCompileCache;if(typeof enable!="function")return;let args=process.argv.slice(2);if(!isPackageCommandArgv(args)&&args[0]!==CONFIG_COMMAND_ARGV&&(args.includes("--version")||args.includes("-v")))return;let scheduleWatch=!1;if(args[0]===SCHEDULE_COMMAND_ARGV&&args[1]==="run")for(let index=2;index<args.length;index++){let arg=args[index];arg==="--watch"?scheduleWatch=!0:["--exec","--poll-seconds","--timeout-seconds","--concurrency"].includes(arg??"")&&index++}if(!(isPackageCommandArgv(args)||args[0]===HOST_COMMAND_ARGV||args[0]===SCHEDULE_COMMAND_ARGV&&!scheduleWatch)){if(!scheduleWatch&&args.some(arg=>["--help","-h","--export","--list-models","--list-tips"].includes(arg)))try{let{parseArgs}=await import("./args-SWKJAYQD.js"),parsed=parseArgs(args);if(parsed.version||parsed.export||parsed.listModels!==void 0||parsed.listTips||parsed.help&&!(parsed.mode==="rpc"&&parsed.multiSession))return}catch{}try{let result=enable();result.directory!==void 0&&process.env.NODE_COMPILE_CACHE===void 0&&(process.env.NODE_COMPILE_CACHE=result.directory)}catch{}}}export{enableStartupCompileCache};
2
+ import{CONFIG_COMMAND_ARGV,HOST_COMMAND_ARGV,SCHEDULE_COMMAND_ARGV,isPackageCommandArgv}from"./chunk-P5E4EVQF.js";import{homedir}from"node:os";try{process.cwd()}catch{let fallback=homedir();process.chdir(fallback),console.error(`the current working directory no longer exists; continuing from ${fallback}`)}import*as nodeModule from"node:module";async function enableStartupCompileCache(){let enable=nodeModule.enableCompileCache;if(typeof enable!="function")return;let args=process.argv.slice(2);if(!isPackageCommandArgv(args)&&args[0]!==CONFIG_COMMAND_ARGV&&(args.includes("--version")||args.includes("-v")))return;let scheduleWatch=!1;if(args[0]===SCHEDULE_COMMAND_ARGV&&args[1]==="run")for(let index=2;index<args.length;index++){let arg=args[index];arg==="--watch"?scheduleWatch=!0:["--exec","--poll-seconds","--timeout-seconds","--concurrency"].includes(arg??"")&&index++}if(!(isPackageCommandArgv(args)||args[0]===HOST_COMMAND_ARGV||args[0]===SCHEDULE_COMMAND_ARGV&&!scheduleWatch)){if(!scheduleWatch&&args.some(arg=>["--help","-h","--export","--list-models","--list-tips"].includes(arg)))try{let{parseArgs}=await import("./args-SWKJAYQD.js"),parsed=parseArgs(args);if(parsed.version||parsed.export||parsed.listModels!==void 0||parsed.listTips||parsed.help&&!(parsed.mode==="rpc"&&parsed.multiSession))return}catch{}try{let result=enable();result.directory!==void 0&&process.env.NODE_COMPILE_CACHE===void 0&&(process.env.NODE_COMPILE_CACHE=result.directory)}catch{}}}export{enableStartupCompileCache};
@@ -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{getLiteralValue,getObjectShape,safeParse}from"./chunk-L73UYAH5.js";import{CancelTaskRequestSchema,CancelTaskResultSchema,CancelledNotificationSchema,CreateTaskResultSchema,ErrorCode,GetTaskPayloadRequestSchema,GetTaskRequestSchema,GetTaskResultSchema,ListTasksRequestSchema,ListTasksResultSchema,McpError,PingRequestSchema,ProgressNotificationSchema,RELATED_TASK_META_KEY,TaskStatusNotificationSchema,isJSONRPCErrorResponse,isJSONRPCNotification,isJSONRPCRequest,isJSONRPCResultResponse,isTaskAugmentedRequestParams}from"./chunk-WJOT3DFL.js";function isTerminal(status){return status==="completed"||status==="failed"||status==="cancelled"}var ALPHA_NUMERIC=new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");function getMethodLiteral(schema){let methodSchema=getObjectShape(schema)?.method;if(!methodSchema)throw new Error("Schema is missing a method literal");let value=getLiteralValue(methodSchema);if(typeof value!="string")throw new Error("Schema method literal must be a string");return value}function parseWithCompat(schema,data){let result=safeParse(schema,data);if(!result.success)throw result.error;return result.data}var DEFAULT_REQUEST_TIMEOUT_MSEC=6e4,Protocol=class{constructor(_options){this._options=_options,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this._timeoutInfo=new Map,this._pendingDebouncedNotifications=new Set,this._taskProgressTokens=new Map,this._requestResolvers=new Map,this.setNotificationHandler(CancelledNotificationSchema,notification=>{this._oncancel(notification)}),this.setNotificationHandler(ProgressNotificationSchema,notification=>{this._onprogress(notification)}),this.setRequestHandler(PingRequestSchema,_request=>({})),this._taskStore=_options?.taskStore,this._taskMessageQueue=_options?.taskMessageQueue,this._taskStore&&(this.setRequestHandler(GetTaskRequestSchema,async(request,extra)=>{let task=await this._taskStore.getTask(request.params.taskId,extra.sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,"Failed to retrieve task: Task not found");return{...task}}),this.setRequestHandler(GetTaskPayloadRequestSchema,async(request,extra)=>{let handleTaskResult=async()=>{let taskId=request.params.taskId;if(!await this._taskStore.getTask(taskId,extra.sessionId))throw new McpError(ErrorCode.InvalidParams,`Task not found: ${taskId}`);if(this._taskMessageQueue){let queuedMessage;for(;queuedMessage=await this._taskMessageQueue.dequeue(taskId,extra.sessionId);){if(queuedMessage.type==="response"||queuedMessage.type==="error"){let message=queuedMessage.message,requestId=message.id,resolver=this._requestResolvers.get(requestId);if(resolver)if(this._requestResolvers.delete(requestId),queuedMessage.type==="response")resolver(message);else{let errorMessage=message,error=new McpError(errorMessage.error.code,errorMessage.error.message,errorMessage.error.data);resolver(error)}else{let messageType=queuedMessage.type==="response"?"Response":"Error";this._onerror(new Error(`${messageType} handler missing for request ${requestId}`))}continue}await this._transport?.send(queuedMessage.message,{relatedRequestId:extra.requestId})}}let task=await this._taskStore.getTask(taskId,extra.sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,`Task not found: ${taskId}`);if(!isTerminal(task.status))return await this._waitForTaskUpdate(taskId,extra.signal,extra.sessionId),await handleTaskResult();if(isTerminal(task.status)){let result=await this._taskStore.getTaskResult(taskId,extra.sessionId);return this._clearTaskQueue(taskId,extra.sessionId),{...result,_meta:{...result._meta,[RELATED_TASK_META_KEY]:{taskId}}}}return await handleTaskResult()};return await handleTaskResult()}),this.setRequestHandler(ListTasksRequestSchema,async(request,extra)=>{try{let{tasks,nextCursor}=await this._taskStore.listTasks(request.params?.cursor,extra.sessionId);return{tasks,nextCursor,_meta:{}}}catch(error){throw new McpError(ErrorCode.InvalidParams,`Failed to list tasks: ${error instanceof Error?error.message:String(error)}`)}}),this.setRequestHandler(CancelTaskRequestSchema,async(request,extra)=>{try{let task=await this._taskStore.getTask(request.params.taskId,extra.sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,`Task not found: ${request.params.taskId}`);if(isTerminal(task.status))throw new McpError(ErrorCode.InvalidParams,`Cannot cancel task in terminal status: ${task.status}`);await this._taskStore.updateTaskStatus(request.params.taskId,"cancelled","Client cancelled task execution.",extra.sessionId),this._clearTaskQueue(request.params.taskId,extra.sessionId);let cancelledTask=await this._taskStore.getTask(request.params.taskId,extra.sessionId);if(!cancelledTask)throw new McpError(ErrorCode.InvalidParams,`Task not found after cancellation: ${request.params.taskId}`);return{_meta:{},...cancelledTask}}catch(error){throw error instanceof McpError?error:new McpError(ErrorCode.InvalidRequest,`Failed to cancel task: ${error instanceof Error?error.message:String(error)}`)}}))}async _oncancel(notification){if(!notification.params.requestId)return;this._requestHandlerAbortControllers.get(notification.params.requestId)?.abort(notification.params.reason)}_setupTimeout(messageId,timeout,maxTotalTimeout,onTimeout,resetTimeoutOnProgress=!1){this._timeoutInfo.set(messageId,{timeoutId:setTimeout(onTimeout,timeout),startTime:Date.now(),timeout,maxTotalTimeout,resetTimeoutOnProgress,onTimeout})}_resetTimeout(messageId){let info=this._timeoutInfo.get(messageId);if(!info)return!1;let totalElapsed=Date.now()-info.startTime;if(info.maxTotalTimeout&&totalElapsed>=info.maxTotalTimeout)throw this._timeoutInfo.delete(messageId),McpError.fromError(ErrorCode.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:info.maxTotalTimeout,totalElapsed});return clearTimeout(info.timeoutId),info.timeoutId=setTimeout(info.onTimeout,info.timeout),!0}_cleanupTimeout(messageId){let info=this._timeoutInfo.get(messageId);info&&(clearTimeout(info.timeoutId),this._timeoutInfo.delete(messageId))}async connect(transport){if(this._transport)throw new Error("Already connected to a transport. Call close() before connecting to a new transport, or use a separate Protocol instance per connection.");this._transport=transport;let _onclose=this.transport?.onclose;this._transport.onclose=()=>{_onclose?.(),this._onclose()};let _onerror=this.transport?.onerror;this._transport.onerror=error=>{_onerror?.(error),this._onerror(error)};let _onmessage=this._transport?.onmessage;this._transport.onmessage=(message,extra)=>{_onmessage?.(message,extra),isJSONRPCResultResponse(message)||isJSONRPCErrorResponse(message)?this._onresponse(message):isJSONRPCRequest(message)?this._onrequest(message,extra):isJSONRPCNotification(message)?this._onnotification(message):this._onerror(new Error(`Unknown message type: ${JSON.stringify(message)}`))},await this._transport.start()}_onclose(){let responseHandlers=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._taskProgressTokens.clear(),this._pendingDebouncedNotifications.clear();for(let info of this._timeoutInfo.values())clearTimeout(info.timeoutId);this._timeoutInfo.clear();for(let controller of this._requestHandlerAbortControllers.values())controller.abort();this._requestHandlerAbortControllers.clear();let error=McpError.fromError(ErrorCode.ConnectionClosed,"Connection closed");this._transport=void 0,this.onclose?.();for(let handler of responseHandlers.values())handler(error)}_onerror(error){this.onerror?.(error)}_onnotification(notification){let handler=this._notificationHandlers.get(notification.method)??this.fallbackNotificationHandler;handler!==void 0&&Promise.resolve().then(()=>handler(notification)).catch(error=>this._onerror(new Error(`Uncaught error in notification handler: ${error}`)))}_onrequest(request,extra){let handler=this._requestHandlers.get(request.method)??this.fallbackRequestHandler,capturedTransport=this._transport,relatedTaskId=request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId,sessionId=capturedTransport?.sessionId,store=this._taskStore,relatedTaskFound=!0,relatedTaskLookup;if(relatedTaskId&&store&&this._taskMessageQueue&&sessionId!==void 0&&(relatedTaskFound=!1,relatedTaskLookup=(async()=>{if(!await store.getTask(relatedTaskId,sessionId))throw new McpError(ErrorCode.InvalidParams,`Task not found: ${relatedTaskId}`);relatedTaskFound=!0})()),handler===void 0){let errorResponse={jsonrpc:"2.0",id:request.id,error:{code:ErrorCode.MethodNotFound,message:"Method not found"}};if(relatedTaskId&&relatedTaskLookup){let queuedError={type:"error",message:errorResponse,timestamp:Date.now()};relatedTaskLookup.then(()=>this._enqueueTaskMessage(relatedTaskId,queuedError,sessionId),()=>capturedTransport?.send(errorResponse)).catch(error=>this._onerror(new Error(`Failed to send an error response: ${error}`)))}else relatedTaskId&&this._taskMessageQueue?this._enqueueTaskMessage(relatedTaskId,{type:"error",message:errorResponse,timestamp:Date.now()},capturedTransport?.sessionId).catch(error=>this._onerror(new Error(`Failed to enqueue error response: ${error}`))):capturedTransport?.send(errorResponse).catch(error=>this._onerror(new Error(`Failed to send an error response: ${error}`)));return}let abortController=new AbortController;this._requestHandlerAbortControllers.set(request.id,abortController);let taskCreationParams=isTaskAugmentedRequestParams(request.params)?request.params.task:void 0,taskStore=this._taskStore?this.requestTaskStore(request,capturedTransport?.sessionId):void 0,fullExtra={signal:abortController.signal,sessionId:capturedTransport?.sessionId,_meta:request.params?._meta,sendNotification:async notification=>{if(abortController.signal.aborted)return;let notificationOptions={relatedRequestId:request.id};relatedTaskId&&(notificationOptions.relatedTask={taskId:relatedTaskId}),await this.notification(notification,notificationOptions)},sendRequest:async(r,resultSchema,options)=>{if(abortController.signal.aborted)throw new McpError(ErrorCode.ConnectionClosed,"Request was cancelled");let requestOptions={...options,relatedRequestId:request.id};relatedTaskId&&!requestOptions.relatedTask&&(requestOptions.relatedTask={taskId:relatedTaskId});let effectiveTaskId=requestOptions.relatedTask?.taskId??relatedTaskId;return effectiveTaskId&&taskStore&&await taskStore.updateTaskStatus(effectiveTaskId,"input_required"),await this.request(r,resultSchema,requestOptions)},authInfo:extra?.authInfo,requestId:request.id,requestInfo:extra?.requestInfo,taskId:relatedTaskId,taskStore,taskRequestedTtl:taskCreationParams?.ttl,closeSSEStream:extra?.closeSSEStream,closeStandaloneSSEStream:extra?.closeStandaloneSSEStream};(relatedTaskLookup??Promise.resolve()).then(()=>{if(relatedTaskLookup&&abortController.signal.aborted)throw new McpError(ErrorCode.ConnectionClosed,"Request was cancelled");taskCreationParams&&this.assertTaskHandlerCapability(request.method)}).then(()=>handler(request,fullExtra)).then(async result=>{if(abortController.signal.aborted)return;let response={result,jsonrpc:"2.0",id:request.id};relatedTaskId&&this._taskMessageQueue?await this._enqueueTaskMessage(relatedTaskId,{type:"response",message:response,timestamp:Date.now()},capturedTransport?.sessionId):await capturedTransport?.send(response)},async error=>{if(abortController.signal.aborted)return;let errorResponse={jsonrpc:"2.0",id:request.id,error:{code:Number.isSafeInteger(error.code)?error.code:ErrorCode.InternalError,message:error.message??"Internal error",...error.data!==void 0&&{data:error.data}}};relatedTaskId&&this._taskMessageQueue&&relatedTaskFound?await this._enqueueTaskMessage(relatedTaskId,{type:"error",message:errorResponse,timestamp:Date.now()},capturedTransport?.sessionId):await capturedTransport?.send(errorResponse)}).catch(error=>this._onerror(new Error(`Failed to send response: ${error}`))).finally(()=>{this._requestHandlerAbortControllers.get(request.id)===abortController&&this._requestHandlerAbortControllers.delete(request.id)})}_onprogress(notification){let{progressToken,...params}=notification.params,messageId=Number(progressToken),handler=this._progressHandlers.get(messageId);if(!handler){this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(notification)}`));return}let responseHandler=this._responseHandlers.get(messageId),timeoutInfo=this._timeoutInfo.get(messageId);if(timeoutInfo&&responseHandler&&timeoutInfo.resetTimeoutOnProgress)try{this._resetTimeout(messageId)}catch(error){this._responseHandlers.delete(messageId),this._progressHandlers.delete(messageId),this._cleanupTimeout(messageId),responseHandler(error);return}handler(params)}_onresponse(response){let messageId=Number(response.id),resolver=this._requestResolvers.get(messageId);if(resolver){if(this._requestResolvers.delete(messageId),isJSONRPCResultResponse(response))resolver(response);else{let error=new McpError(response.error.code,response.error.message,response.error.data);resolver(error)}return}let handler=this._responseHandlers.get(messageId);if(handler===void 0){this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(response)}`));return}this._responseHandlers.delete(messageId),this._cleanupTimeout(messageId);let isTaskResponse=!1;if(isJSONRPCResultResponse(response)&&response.result&&typeof response.result=="object"){let result=response.result;if(result.task&&typeof result.task=="object"){let task=result.task;typeof task.taskId=="string"&&(isTaskResponse=!0,this._taskProgressTokens.set(task.taskId,messageId))}}if(isTaskResponse||this._progressHandlers.delete(messageId),isJSONRPCResultResponse(response))handler(response);else{let error=McpError.fromError(response.error.code,response.error.message,response.error.data);handler(error)}}get transport(){return this._transport}async close(){await this._transport?.close()}async*requestStream(request,resultSchema,options){let{task}=options??{};if(!task){try{yield{type:"result",result:await this.request(request,resultSchema,options)}}catch(error){yield{type:"error",error:error instanceof McpError?error:new McpError(ErrorCode.InternalError,String(error))}}return}let taskId;try{let createResult=await this.request(request,CreateTaskResultSchema,options);if(createResult.task)taskId=createResult.task.taskId,yield{type:"taskCreated",task:createResult.task};else throw new McpError(ErrorCode.InternalError,"Task creation did not return a task");for(;;){let task2=await this.getTask({taskId},options);if(yield{type:"taskStatus",task:task2},isTerminal(task2.status)){task2.status==="completed"?yield{type:"result",result:await this.getTaskResult({taskId},resultSchema,options)}:task2.status==="failed"?yield{type:"error",error:new McpError(ErrorCode.InternalError,`Task ${taskId} failed`)}:task2.status==="cancelled"&&(yield{type:"error",error:new McpError(ErrorCode.InternalError,`Task ${taskId} was cancelled`)});return}if(task2.status==="input_required"){yield{type:"result",result:await this.getTaskResult({taskId},resultSchema,options)};return}let pollInterval=task2.pollInterval??this._options?.defaultTaskPollInterval??1e3;await new Promise(resolve=>setTimeout(resolve,pollInterval)),options?.signal?.throwIfAborted()}}catch(error){yield{type:"error",error:error instanceof McpError?error:new McpError(ErrorCode.InternalError,String(error))}}}request(request,resultSchema,options){let{relatedRequestId,resumptionToken,onresumptiontoken,task,relatedTask}=options??{};return new Promise((resolve,reject)=>{let earlyReject=error=>{reject(error)};if(!this._transport){earlyReject(new Error("Not connected"));return}if(this._options?.enforceStrictCapabilities===!0)try{this.assertCapabilityForMethod(request.method),task&&this.assertTaskCapability(request.method)}catch(e){earlyReject(e);return}options?.signal?.throwIfAborted();let messageId=this._requestMessageId++,jsonrpcRequest={...request,jsonrpc:"2.0",id:messageId};options?.onprogress&&(this._progressHandlers.set(messageId,options.onprogress),jsonrpcRequest.params={...request.params,_meta:{...request.params?._meta||{},progressToken:messageId}}),task&&(jsonrpcRequest.params={...jsonrpcRequest.params,task}),relatedTask&&(jsonrpcRequest.params={...jsonrpcRequest.params,_meta:{...jsonrpcRequest.params?._meta||{},[RELATED_TASK_META_KEY]:relatedTask}});let cancel=reason=>{this._responseHandlers.delete(messageId),this._progressHandlers.delete(messageId),this._cleanupTimeout(messageId),this._transport?.send({jsonrpc:"2.0",method:"notifications/cancelled",params:{requestId:messageId,reason:String(reason)}},{relatedRequestId,resumptionToken,onresumptiontoken}).catch(error2=>this._onerror(new Error(`Failed to send cancellation: ${error2}`)));let error=reason instanceof McpError?reason:new McpError(ErrorCode.RequestTimeout,String(reason));reject(error)};this._responseHandlers.set(messageId,response=>{if(!options?.signal?.aborted){if(response instanceof Error)return reject(response);try{let parseResult=safeParse(resultSchema,response.result);parseResult.success?resolve(parseResult.data):reject(parseResult.error)}catch(error){reject(error)}}}),options?.signal?.addEventListener("abort",()=>{cancel(options?.signal?.reason)});let timeout=options?.timeout??DEFAULT_REQUEST_TIMEOUT_MSEC,timeoutHandler=()=>cancel(McpError.fromError(ErrorCode.RequestTimeout,"Request timed out",{timeout}));this._setupTimeout(messageId,timeout,options?.maxTotalTimeout,timeoutHandler,options?.resetTimeoutOnProgress??!1);let relatedTaskId=relatedTask?.taskId;if(relatedTaskId){let responseResolver=response=>{let handler=this._responseHandlers.get(messageId);handler?handler(response):this._onerror(new Error(`Response handler missing for side-channeled request ${messageId}`))};this._requestResolvers.set(messageId,responseResolver),this._enqueueTaskMessage(relatedTaskId,{type:"request",message:jsonrpcRequest,timestamp:Date.now()}).catch(error=>{this._cleanupTimeout(messageId),reject(error)})}else this._transport.send(jsonrpcRequest,{relatedRequestId,resumptionToken,onresumptiontoken}).catch(error=>{this._cleanupTimeout(messageId),reject(error)})})}async getTask(params,options){return this.request({method:"tasks/get",params},GetTaskResultSchema,options)}async getTaskResult(params,resultSchema,options){return this.request({method:"tasks/result",params},resultSchema,options)}async listTasks(params,options){return this.request({method:"tasks/list",params},ListTasksResultSchema,options)}async cancelTask(params,options){return this.request({method:"tasks/cancel",params},CancelTaskResultSchema,options)}async notification(notification,options){if(!this._transport)throw new Error("Not connected");this.assertNotificationCapability(notification.method);let relatedTaskId=options?.relatedTask?.taskId;if(relatedTaskId){let jsonrpcNotification2={...notification,jsonrpc:"2.0",params:{...notification.params,_meta:{...notification.params?._meta||{},[RELATED_TASK_META_KEY]:options.relatedTask}}};await this._enqueueTaskMessage(relatedTaskId,{type:"notification",message:jsonrpcNotification2,timestamp:Date.now()});return}if((this._options?.debouncedNotificationMethods??[]).includes(notification.method)&&!notification.params&&!options?.relatedRequestId&&!options?.relatedTask){if(this._pendingDebouncedNotifications.has(notification.method))return;this._pendingDebouncedNotifications.add(notification.method),Promise.resolve().then(()=>{if(this._pendingDebouncedNotifications.delete(notification.method),!this._transport)return;let jsonrpcNotification2={...notification,jsonrpc:"2.0"};options?.relatedTask&&(jsonrpcNotification2={...jsonrpcNotification2,params:{...jsonrpcNotification2.params,_meta:{...jsonrpcNotification2.params?._meta||{},[RELATED_TASK_META_KEY]:options.relatedTask}}}),this._transport?.send(jsonrpcNotification2,options).catch(error=>this._onerror(error))});return}let jsonrpcNotification={...notification,jsonrpc:"2.0"};options?.relatedTask&&(jsonrpcNotification={...jsonrpcNotification,params:{...jsonrpcNotification.params,_meta:{...jsonrpcNotification.params?._meta||{},[RELATED_TASK_META_KEY]:options.relatedTask}}}),await this._transport.send(jsonrpcNotification,options)}setRequestHandler(requestSchema,handler){let method=getMethodLiteral(requestSchema);this.assertRequestHandlerCapability(method),this._requestHandlers.set(method,(request,extra)=>{let parsed=parseWithCompat(requestSchema,request);return Promise.resolve(handler(parsed,extra))})}removeRequestHandler(method){this._requestHandlers.delete(method)}assertCanSetRequestHandler(method){if(this._requestHandlers.has(method))throw new Error(`A request handler for ${method} already exists, which would be overridden`)}setNotificationHandler(notificationSchema,handler){let method=getMethodLiteral(notificationSchema);this._notificationHandlers.set(method,notification=>{let parsed=parseWithCompat(notificationSchema,notification);return Promise.resolve(handler(parsed))})}removeNotificationHandler(method){this._notificationHandlers.delete(method)}_cleanupTaskProgressHandler(taskId){let progressToken=this._taskProgressTokens.get(taskId);progressToken!==void 0&&(this._progressHandlers.delete(progressToken),this._taskProgressTokens.delete(taskId))}async _enqueueTaskMessage(taskId,message,sessionId){if(!this._taskStore||!this._taskMessageQueue)throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");let maxQueueSize=this._options?.maxTaskQueueSize;await this._taskMessageQueue.enqueue(taskId,message,sessionId??this._transport?.sessionId,maxQueueSize)}async _clearTaskQueue(taskId,sessionId){if(this._taskMessageQueue){let messages=await this._taskMessageQueue.dequeueAll(taskId,sessionId);for(let message of messages)if(message.type==="request"&&isJSONRPCRequest(message.message)){let requestId=message.message.id,resolver=this._requestResolvers.get(requestId);resolver?(resolver(new McpError(ErrorCode.InternalError,"Task cancelled or completed")),this._requestResolvers.delete(requestId)):this._onerror(new Error(`Resolver missing for request ${requestId} during task ${taskId} cleanup`))}}}async _waitForTaskUpdate(taskId,signal,sessionId){let interval=this._options?.defaultTaskPollInterval??1e3;try{let task=await this._taskStore?.getTask(taskId,sessionId);task?.pollInterval&&(interval=task.pollInterval)}catch{}return new Promise((resolve,reject)=>{if(signal.aborted){reject(new McpError(ErrorCode.InvalidRequest,"Request cancelled"));return}let timeoutId=setTimeout(resolve,interval);signal.addEventListener("abort",()=>{clearTimeout(timeoutId),reject(new McpError(ErrorCode.InvalidRequest,"Request cancelled"))},{once:!0})})}requestTaskStore(request,sessionId){let taskStore=this._taskStore;if(!taskStore)throw new Error("No task store configured");return{createTask:async taskParams=>{if(!request)throw new Error("No request provided");return await taskStore.createTask(taskParams,request.id,{method:request.method,params:request.params},sessionId)},getTask:async taskId=>{let task=await taskStore.getTask(taskId,sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,"Failed to retrieve task: Task not found");return task},storeTaskResult:async(taskId,status,result)=>{await taskStore.storeTaskResult(taskId,status,result,sessionId);let task=await taskStore.getTask(taskId,sessionId);if(task){let notification=TaskStatusNotificationSchema.parse({method:"notifications/tasks/status",params:task});await this.notification(notification),isTerminal(task.status)&&this._cleanupTaskProgressHandler(taskId)}},getTaskResult:taskId=>taskStore.getTaskResult(taskId,sessionId),updateTaskStatus:async(taskId,status,statusMessage)=>{let task=await taskStore.getTask(taskId,sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,`Task "${taskId}" not found - it may have been cleaned up`);if(isTerminal(task.status))throw new McpError(ErrorCode.InvalidParams,`Cannot update task "${taskId}" from terminal status "${task.status}" to "${status}". Terminal states (completed, failed, cancelled) cannot transition to other states.`);await taskStore.updateTaskStatus(taskId,status,statusMessage,sessionId);let updatedTask=await taskStore.getTask(taskId,sessionId);if(updatedTask){let notification=TaskStatusNotificationSchema.parse({method:"notifications/tasks/status",params:updatedTask});await this.notification(notification),isTerminal(updatedTask.status)&&this._cleanupTaskProgressHandler(taskId)}},listTasks:cursor=>taskStore.listTasks(cursor,sessionId)}}};function isPlainObject(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function mergeCapabilities(base,additional){let result={...base};for(let key in additional){let k=key,addValue=additional[k];if(addValue===void 0)continue;let baseValue=result[k];isPlainObject(baseValue)&&isPlainObject(addValue)?result[k]={...baseValue,...addValue}:result[k]=addValue}return result}export{DEFAULT_REQUEST_TIMEOUT_MSEC,Protocol,mergeCapabilities};
@@ -1,3 +1,3 @@
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
2
  import{require_semver}from"./chunk-ZOFZRJSL.js";import{fetchWithRetry}from"./chunk-2SOVDETB.js";import{APP_NAME,BRAND,DISPLAY_VERSION,PACKAGE_NAME,brandProfile,envValue}from"./chunk-7YO7VQZW.js";import{__toESM}from"./chunk-IKOFCODM.js";import{spawnSync}from"node:child_process";import{homedir as osHomedir}from"node:os";import{posix,win32}from"node:path";var RUNTIME_ENV_VAR="SENPI_RUNTIME",MIN_BUN_VERSION="1.4.0";function normalize(path){return path.replaceAll("\\","/")}function paths(options){return options.platform==="win32"?win32:posix}function bunRoot(options){let configured=options.env.BUN_INSTALL;return configured!==void 0&&configured.trim()!==""?configured:paths(options).join(options.homedir,".bun")}function resolveOrSelf(path,options){try{return options.realpath(path)}catch{return path}}function isUnderBunGlobalTree(scriptRealPath,options){let globalRoot=paths(options).join(bunRoot(options),"install","global"),script=normalize(scriptRealPath);for(let candidate of new Set([globalRoot,resolveOrSelf(globalRoot,options)]))if(script.startsWith(`${normalize(candidate)}/`))return!0;return!1}function isInstalledPackageScript(scriptRealPath){return normalize(scriptRealPath).includes("/node_modules/")}function bunVersionSatisfies(version){let actual=/^v?(\d+)\.(\d+)\.(\d+)/.exec(version?.trim()??""),minimum=/^(\d+)\.(\d+)\.(\d+)/.exec(MIN_BUN_VERSION);if(!actual||!minimum)return!1;for(let index=1;index<=3;index++){let difference=Number(actual[index])-Number(minimum[index]);if(difference!==0)return difference>0}return!0}function bunExecutableName(options){return options.platform==="win32"?"bun.exe":"bun"}function pathCandidateNames(options){if(options.platform!=="win32")return["bun"];let extensions=(options.env.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").map(extension=>extension.trim()).filter(extension=>extension.length>0);return extensions.length>0?extensions.map(extension=>`bun${extension}`):["bun.exe"]}function findBunBinary(options){let path=paths(options),executable=bunExecutableName(options),rootCandidates=[path.join(bunRoot(options),"bin",executable),path.join(options.homedir,".bun","bin",executable)];for(let candidate of rootCandidates)if(options.exists(candidate))return candidate;let pathValue=options.env.PATH??options.env.Path;if(pathValue===void 0||pathValue==="")return;let names=pathCandidateNames(options);for(let directory of pathValue.split(path.delimiter))if(directory!=="")for(let name of names){let candidate=path.join(directory,name);if(options.exists(candidate))return candidate}}function readRuntimePin(options){let value=options.env[RUNTIME_ENV_VAR];if(value==="node"||value==="bun")return value}function resolveBunReexec(input){if(input.versions.bun!==void 0)return{action:"stay",reason:"already-bun"};let pinned=readRuntimePin(input.options);if(pinned==="node")return{action:"stay",reason:"runtime-pinned-node"};if(input.hasInheritedInspectorOption)return{action:"stay",reason:"inspector"};let trustsInstalledBun=pinned==="bun"||isUnderBunGlobalTree(input.scriptRealPath,input.options);if(!trustsInstalledBun&&!isInstalledPackageScript(input.scriptRealPath))return{action:"stay",reason:"not-bun-install"};let bunPath=findBunBinary(input.options);return bunPath===void 0?{action:"stay",reason:"bun-not-found"}:!trustsInstalledBun&&!bunVersionSatisfies(input.options.bunVersion(bunPath))?{action:"stay",reason:"bun-too-old"}:{action:"reexec",bunPath}}function readBunVersion(bunPath){try{let result=spawnSync(bunPath,["--version"],{encoding:"utf8",timeout:5e3,windowsHide:!0});if(result.status!==0)return;let version=result.stdout.trim();return version===""?void 0:version}catch{return}}function processBunRuntimeOptions(exists,realpath){return{env:process.env,homedir:osHomedir(),platform:process.platform,exists,realpath,bunVersion:readBunVersion}}import{format}from"node:util";var OUTPUT_DELIVERY_LIMIT_MS=3e4,nativeLog=console.log,nativeStdoutWrite=process.stdout.write;async function captureStdout(print){if(console.log!==nativeLog||process.stdout.write!==nativeStdoutWrite)return{result:await print(),output:""};let chunks=[];console.log=(...args)=>{chunks.push(`${format(...args)}
3
- `)},process.stdout.write=((chunk,encodingOrCallback,callback)=>(chunks.push(typeof chunk=="string"?chunk:Buffer.from(chunk).toString()),(typeof encodingOrCallback=="function"?encodingOrCallback:callback)?.(),!0));let printed=!1;try{let result=await print();return printed=!0,{result,output:chunks.join("")}}finally{console.log=nativeLog,process.stdout.write=nativeStdoutWrite,!printed&&chunks.length>0&&process.stdout.write(chunks.join(""))}}function delivered(stream,text){return stream.destroyed||stream.writableEnded?Promise.resolve():new Promise(resolve=>{let timer=setTimeout(resolve,OUTPUT_DELIVERY_LIMIT_MS);timer.unref();let done=()=>{clearTimeout(timer),resolve()};stream.once("error",done);try{stream.write(text,done)}catch{done()}})}async function exitAfterOutput(output="",code){await Promise.all([delivered(process.stdout,output),delivered(process.stderr,"")]),process.exit(code)}async function printThenExit(print,code){let{output}=await captureStdout(print);return exitAfterOutput(output,code)}function getPiUserAgent(version=DISPLAY_VERSION){let runtime=process.versions.bun?`bun/${process.versions.bun}`:`node/${process.version}`;return`${BRAND?.userAgent??APP_NAME}/${version} (${process.platform}; ${runtime}; ${process.arch})`}var modeHandlers=new WeakSet;function markModeCrashHandler(listener){modeHandlers.add(listener)}function hasModeCrashHandler(event){return process.listeners(event).some(listener=>modeHandlers.has(listener))}import{close as closeInspector,url as inspectorUrl}from"node:inspector";var StaleExtensionContextError=class extends Error{constructor(){super(...arguments),this.name="StaleExtensionContextError"}};var STALE_EXTENSION_CONTEXT_ERROR_PREFIX="This extension ctx is stale after session replacement or reload.",STALE_EXTENSION_GENERATION_AFTER_RELOAD_MESSAGE="stale extension generation after reload";function isStaleExtensionContextError(error){return error instanceof StaleExtensionContextError?!0:error instanceof Error&&(error.message.startsWith(STALE_EXTENSION_CONTEXT_ERROR_PREFIX)||error.message===STALE_EXTENSION_GENERATION_AFTER_RELOAD_MESSAGE)}var VM_DYNAMIC_IMPORT_CALLBACK_MISSING="ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING",INSPECTOR_IMPORT_FRAME="at importModuleDynamicallyCallback (node:internal/modules/esm/",INSPECTOR_TIMEOUT_FRAME=/\bat Timeout\._onTimeout \(<anonymous>:\d+:\d+\)/,RECOVER_INSPECTOR_VM_IMPORT=envValue("RECOVER_INSPECTOR_VM_IMPORT")==="1",INSPECTOR_VM_IMPORT_WARNING="Node Inspector dynamic import is unsupported; use require() or a target-side loader. Senpi kept running.";function hasInheritedInspectorOption(){return process.execArgv.some(argument=>argument.startsWith("--inspect"))||process.env.NODE_OPTIONS?.includes("--inspect")===!0}function releaseInheritedInspectorForChild(){inspectorUrl()!==void 0&&hasInheritedInspectorOption()&&closeInspector()}function isRecoverableInspectorVmImportError(error,origin){if(!RECOVER_INSPECTOR_VM_IMPORT||origin!=="unhandledRejection")return!1;try{return inspectorUrl()===void 0||typeof error!="object"||error===null||!("code"in error)||!("stack"in error)?!1:error.code===VM_DYNAMIC_IMPORT_CALLBACK_MISSING&&typeof error.stack=="string"&&error.stack.includes(INSPECTOR_IMPORT_FRAME)&&INSPECTOR_TIMEOUT_FRAME.test(error.stack)}catch{return!1}}var earlyRecoveryCount=0,earlyRecoveryInstalled=!1;function installEarlyInspectorVmImportRecovery(){if(!RECOVER_INSPECTOR_VM_IMPORT||earlyRecoveryInstalled)return;earlyRecoveryInstalled=!0;let listener=(error,origin)=>{let otherHandlerActive=hasModeCrashHandler("uncaughtException");if(isRecoverableInspectorVmImportError(error,origin)){otherHandlerActive||earlyRecoveryCount++;return}otherHandlerActive||isStaleExtensionContextError(error)||(console.error(error),process.exit(1))};process.on("uncaughtException",listener)}function consumeEarlyInspectorVmImportRecoveries(){let count=earlyRecoveryCount;return earlyRecoveryCount=0,count}var import_semver=__toESM(require_semver(),1);var REGISTRY_BASE_URL="https://registry.npmjs.org",LATEST_VERSION_URL=`${REGISTRY_BASE_URL}/${encodeURIComponent(PACKAGE_NAME)}/latest`;function latestVersionUrl(channel){return channel?`${REGISTRY_BASE_URL}/-/package/${encodeURIComponent(channel.packageName)}/dist-tags`:LATEST_VERSION_URL}function readAvailableVersion(payload,channel){if(typeof payload!="object"||payload===null)return;let source=payload,raw=channel?source[channel.distTag]:source.version;return typeof raw=="string"&&raw.trim()?raw.trim():void 0}var DEFAULT_VERSION_CHECK_TIMEOUT_MS=1e4,RELEASE_CHANGELOG_BASE_URL="https://github.com/code-yeongyu/senpi/blob",RELEASE_CHANGELOG_PATH="packages/coding-agent/CHANGELOG.md",SENPI_CALVER_PATTERN=/^(\d{4})\.(\d{1,2})\.(\d{1,2})(?:-([2-9]\d*))?$/;function parseSenpiCalVer(version){let match=SENPI_CALVER_PATTERN.exec(version);if(match)return[Number(match[1]),Number(match[2]),Number(match[3]),Number(match[4]??1)]}function formatVersionCheckError(error){let rootMessage=error instanceof Error&&error.message?error.message:String(error),cause=error instanceof Error?error.cause:void 0,causes=cause instanceof AggregateError?cause.errors:cause===void 0?[]:[cause],codes=causes.map(value=>typeof value=="object"&&value!==null&&"code"in value&&typeof value.code=="string"?value.code:void 0).filter(code=>code!==void 0);if(codes.length>0)return`${rootMessage} (${[...new Set(codes)].join(", ")})`;let causeMessage=causes.find(value=>value instanceof Error&&!!value.message)?.message;return causeMessage?`${rootMessage} (cause: ${causeMessage})`:rootMessage}function comparePackageVersions(leftVersion,rightVersion){let leftTrimmed=leftVersion.trim(),rightTrimmed=rightVersion.trim(),leftCalVer=parseSenpiCalVer(leftTrimmed),rightCalVer=parseSenpiCalVer(rightTrimmed);if(leftCalVer&&rightCalVer){for(let index=0;index<leftCalVer.length;index++)if(leftCalVer[index]!==rightCalVer[index])return leftCalVer[index]<rightCalVer[index]?-1:1;return 0}let left=(0,import_semver.valid)(leftTrimmed),right=(0,import_semver.valid)(rightTrimmed);if(!(!left||!right))return(0,import_semver.compare)(left,right)}function isNewerPackageVersion(candidateVersion,currentVersion){let comparison=comparePackageVersions(candidateVersion,currentVersion);return comparison!==void 0&&comparison>0}function getReleaseChangelogUrl(version){let trimmedVersion=version.trim(),channel=brandProfile()?.update;if(channel?.changelogUrl)return channel.changelogUrl.replace("{version}",trimmedVersion);let tag=trimmedVersion.startsWith("v")?trimmedVersion:`v${trimmedVersion}`;return`${RELEASE_CHANGELOG_BASE_URL}/${tag}/${RELEASE_CHANGELOG_PATH}`}async function getLatestPiRelease(currentVersion,options={}){if(envValue("OFFLINE"))return;let brand=brandProfile(),channel=brand?.update;if(brand&&!channel)return;let response=await fetchWithRetry(latestVersionUrl(channel),{headers:{"User-Agent":getPiUserAgent(currentVersion),accept:"application/json"}},{maxRetries:options.retry?2:0,timeoutMs:options.timeoutMs??DEFAULT_VERSION_CHECK_TIMEOUT_MS});if(!response.ok)return;let data=await response.json(),availableVersion=readAvailableVersion(data,channel);if(!availableVersion)return;if(channel)return{version:availableVersion,packageName:channel.packageName};let packageName=typeof data.packageName=="string"&&data.packageName.trim()?data.packageName.trim():void 0,note=typeof data.note=="string"&&data.note.trim()?data.note.trim():void 0;return{version:availableVersion,packageName,note}}async function checkForNewPiVersion(currentVersion){if(!envValue("SKIP_VERSION_CHECK"))try{let latestRelease=await getLatestPiRelease(currentVersion);return latestRelease&&isNewerPackageVersion(latestRelease.version,currentVersion)?latestRelease:void 0}catch{return}}var PACKAGE_COMMAND_ARGV={install:!0,remove:!0,update:!0,list:!0},PACKAGE_COMMAND_ALIAS="uninstall",CONFIG_COMMAND_ARGV="config",HOST_COMMAND_ARGV="host",SCHEDULE_COMMAND_ARGV="schedule";function isPackageCommandArgv(args){let command=args[0]??"";return Object.hasOwn(PACKAGE_COMMAND_ARGV,command)||command===PACKAGE_COMMAND_ALIAS}async function dispatchPackageCommand(args,runtimeOptions={}){if(!isPackageCommandArgv(args))return!1;let{handlePackageCommand}=await import("./package-manager-cli-W55E3LHP.js");return await handlePackageCommand(args,runtimeOptions)}async function dispatchConfigCommand(args,runtimeOptions={}){if(args[0]!==CONFIG_COMMAND_ARGV)return!1;let{handleConfigCommand}=await import("./package-manager-cli-W55E3LHP.js");return await handleConfigCommand(args,runtimeOptions)}async function dispatchHostCommand(args){if(args[0]!==HOST_COMMAND_ARGV)return;if(args[1]==="session"){let{runHostSessionCommand}=await import("./host-session-command-FFN52LXJ.js");return await runHostSessionCommand(args.slice(2))}let{runHostCommand}=await import("./host-command-XEB7SHT3.js");return await runHostCommand(args.slice(1))}async function dispatchScheduleCommand(args){if(args[0]!==SCHEDULE_COMMAND_ARGV)return;let{runScheduleCommand}=await import("./schedule-command-B7RRSANU.js");return await runScheduleCommand(args.slice(1))}export{RUNTIME_ENV_VAR,MIN_BUN_VERSION,bunVersionSatisfies,findBunBinary,resolveBunReexec,processBunRuntimeOptions,captureStdout,exitAfterOutput,printThenExit,getPiUserAgent,StaleExtensionContextError,isStaleExtensionContextError,markModeCrashHandler,hasModeCrashHandler,INSPECTOR_VM_IMPORT_WARNING,hasInheritedInspectorOption,releaseInheritedInspectorForChild,isRecoverableInspectorVmImportError,installEarlyInspectorVmImportRecovery,consumeEarlyInspectorVmImportRecoveries,formatVersionCheckError,isNewerPackageVersion,getReleaseChangelogUrl,getLatestPiRelease,checkForNewPiVersion,CONFIG_COMMAND_ARGV,HOST_COMMAND_ARGV,SCHEDULE_COMMAND_ARGV,isPackageCommandArgv,dispatchPackageCommand,dispatchConfigCommand,dispatchHostCommand,dispatchScheduleCommand};
3
+ `)},process.stdout.write=((chunk,encodingOrCallback,callback)=>(chunks.push(typeof chunk=="string"?chunk:Buffer.from(chunk).toString()),(typeof encodingOrCallback=="function"?encodingOrCallback:callback)?.(),!0));let printed=!1;try{let result=await print();return printed=!0,{result,output:chunks.join("")}}finally{console.log=nativeLog,process.stdout.write=nativeStdoutWrite,!printed&&chunks.length>0&&process.stdout.write(chunks.join(""))}}function delivered(stream,text){return stream.destroyed||stream.writableEnded?Promise.resolve():new Promise(resolve=>{let timer=setTimeout(resolve,OUTPUT_DELIVERY_LIMIT_MS);timer.unref();let done=()=>{clearTimeout(timer),resolve()};stream.once("error",done);try{stream.write(text,done)}catch{done()}})}async function exitAfterOutput(output="",code){await Promise.all([delivered(process.stdout,output),delivered(process.stderr,"")]),process.exit(code)}async function printThenExit(print,code){let{output}=await captureStdout(print);return exitAfterOutput(output,code)}function getPiUserAgent(version=DISPLAY_VERSION){let runtime=process.versions.bun?`bun/${process.versions.bun}`:`node/${process.version}`;return`${BRAND?.userAgent??APP_NAME}/${version} (${process.platform}; ${runtime}; ${process.arch})`}var modeHandlers=new WeakSet;function markModeCrashHandler(listener){modeHandlers.add(listener)}function hasModeCrashHandler(event){return process.listeners(event).some(listener=>modeHandlers.has(listener))}import{close as closeInspector,url as inspectorUrl}from"node:inspector";var StaleExtensionContextError=class extends Error{constructor(){super(...arguments),this.name="StaleExtensionContextError"}};var STALE_EXTENSION_CONTEXT_ERROR_PREFIX="This extension ctx is stale after session replacement or reload.",STALE_EXTENSION_GENERATION_AFTER_RELOAD_MESSAGE="stale extension generation after reload";function isStaleExtensionContextError(error){return error instanceof StaleExtensionContextError?!0:error instanceof Error&&(error.message.startsWith(STALE_EXTENSION_CONTEXT_ERROR_PREFIX)||error.message===STALE_EXTENSION_GENERATION_AFTER_RELOAD_MESSAGE)}var VM_DYNAMIC_IMPORT_CALLBACK_MISSING="ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING",INSPECTOR_IMPORT_FRAME="at importModuleDynamicallyCallback (node:internal/modules/esm/",INSPECTOR_TIMEOUT_FRAME=/\bat Timeout\._onTimeout \(<anonymous>:\d+:\d+\)/,RECOVER_INSPECTOR_VM_IMPORT=envValue("RECOVER_INSPECTOR_VM_IMPORT")==="1",INSPECTOR_VM_IMPORT_WARNING="Node Inspector dynamic import is unsupported; use require() or a target-side loader. Senpi kept running.";function hasInheritedInspectorOption(){return process.execArgv.some(argument=>argument.startsWith("--inspect"))||process.env.NODE_OPTIONS?.includes("--inspect")===!0}function releaseInheritedInspectorForChild(){inspectorUrl()!==void 0&&hasInheritedInspectorOption()&&closeInspector()}function isRecoverableInspectorVmImportError(error,origin){if(!RECOVER_INSPECTOR_VM_IMPORT||origin!=="unhandledRejection")return!1;try{return inspectorUrl()===void 0||typeof error!="object"||error===null||!("code"in error)||!("stack"in error)?!1:error.code===VM_DYNAMIC_IMPORT_CALLBACK_MISSING&&typeof error.stack=="string"&&error.stack.includes(INSPECTOR_IMPORT_FRAME)&&INSPECTOR_TIMEOUT_FRAME.test(error.stack)}catch{return!1}}var earlyRecoveryCount=0,earlyRecoveryInstalled=!1;function installEarlyInspectorVmImportRecovery(){if(!RECOVER_INSPECTOR_VM_IMPORT||earlyRecoveryInstalled)return;earlyRecoveryInstalled=!0;let listener=(error,origin)=>{let otherHandlerActive=hasModeCrashHandler("uncaughtException");if(isRecoverableInspectorVmImportError(error,origin)){otherHandlerActive||earlyRecoveryCount++;return}otherHandlerActive||isStaleExtensionContextError(error)||(console.error(error),process.exit(1))};process.on("uncaughtException",listener)}function consumeEarlyInspectorVmImportRecoveries(){let count=earlyRecoveryCount;return earlyRecoveryCount=0,count}var import_semver=__toESM(require_semver(),1);var REGISTRY_BASE_URL="https://registry.npmjs.org",LATEST_VERSION_URL=`${REGISTRY_BASE_URL}/${encodeURIComponent(PACKAGE_NAME)}/latest`;function latestVersionUrl(channel){return channel?`${REGISTRY_BASE_URL}/-/package/${encodeURIComponent(channel.packageName)}/dist-tags`:LATEST_VERSION_URL}function readAvailableVersion(payload,channel){if(typeof payload!="object"||payload===null)return;let source=payload,raw=channel?source[channel.distTag]:source.version;return typeof raw=="string"&&raw.trim()?raw.trim():void 0}var DEFAULT_VERSION_CHECK_TIMEOUT_MS=1e4,RELEASE_CHANGELOG_BASE_URL="https://github.com/code-yeongyu/senpi/blob",RELEASE_CHANGELOG_PATH="packages/coding-agent/CHANGELOG.md",SENPI_CALVER_PATTERN=/^(\d{4})\.(\d{1,2})\.(\d{1,2})(?:-([2-9]\d*))?$/;function parseSenpiCalVer(version){let match=SENPI_CALVER_PATTERN.exec(version);if(match)return[Number(match[1]),Number(match[2]),Number(match[3]),Number(match[4]??1)]}function formatVersionCheckError(error){let rootMessage=error instanceof Error&&error.message?error.message:String(error),cause=error instanceof Error?error.cause:void 0,causes=cause instanceof AggregateError?cause.errors:cause===void 0?[]:[cause],codes=causes.map(value=>typeof value=="object"&&value!==null&&"code"in value&&typeof value.code=="string"?value.code:void 0).filter(code=>code!==void 0);if(codes.length>0)return`${rootMessage} (${[...new Set(codes)].join(", ")})`;let causeMessage=causes.find(value=>value instanceof Error&&!!value.message)?.message;return causeMessage?`${rootMessage} (cause: ${causeMessage})`:rootMessage}function comparePackageVersions(leftVersion,rightVersion){let leftTrimmed=leftVersion.trim(),rightTrimmed=rightVersion.trim(),leftCalVer=parseSenpiCalVer(leftTrimmed),rightCalVer=parseSenpiCalVer(rightTrimmed);if(leftCalVer&&rightCalVer){for(let index=0;index<leftCalVer.length;index++)if(leftCalVer[index]!==rightCalVer[index])return leftCalVer[index]<rightCalVer[index]?-1:1;return 0}let left=(0,import_semver.valid)(leftTrimmed),right=(0,import_semver.valid)(rightTrimmed);if(!(!left||!right))return(0,import_semver.compare)(left,right)}function isNewerPackageVersion(candidateVersion,currentVersion){let comparison=comparePackageVersions(candidateVersion,currentVersion);return comparison!==void 0&&comparison>0}function getReleaseChangelogUrl(version){let trimmedVersion=version.trim(),channel=brandProfile()?.update;if(channel?.changelogUrl)return channel.changelogUrl.replace("{version}",trimmedVersion);let tag=trimmedVersion.startsWith("v")?trimmedVersion:`v${trimmedVersion}`;return`${RELEASE_CHANGELOG_BASE_URL}/${tag}/${RELEASE_CHANGELOG_PATH}`}async function getLatestPiRelease(currentVersion,options={}){if(envValue("OFFLINE"))return;let brand=brandProfile(),channel=brand?.update;if(brand&&!channel)return;let response=await fetchWithRetry(latestVersionUrl(channel),{headers:{"User-Agent":getPiUserAgent(currentVersion),accept:"application/json"}},{maxRetries:options.retry?2:0,timeoutMs:options.timeoutMs??DEFAULT_VERSION_CHECK_TIMEOUT_MS});if(!response.ok)return;let data=await response.json(),availableVersion=readAvailableVersion(data,channel);if(!availableVersion)return;if(channel)return{version:availableVersion,packageName:channel.packageName};let packageName=typeof data.packageName=="string"&&data.packageName.trim()?data.packageName.trim():void 0,note=typeof data.note=="string"&&data.note.trim()?data.note.trim():void 0;return{version:availableVersion,packageName,note}}async function checkForNewPiVersion(currentVersion){if(!envValue("SKIP_VERSION_CHECK"))try{let latestRelease=await getLatestPiRelease(currentVersion);return latestRelease&&isNewerPackageVersion(latestRelease.version,currentVersion)?latestRelease:void 0}catch{return}}var PACKAGE_COMMAND_ARGV={install:!0,remove:!0,update:!0,list:!0},PACKAGE_COMMAND_ALIAS="uninstall",CONFIG_COMMAND_ARGV="config",HOST_COMMAND_ARGV="host",SCHEDULE_COMMAND_ARGV="schedule";function isPackageCommandArgv(args){let command=args[0]??"";return Object.hasOwn(PACKAGE_COMMAND_ARGV,command)||command===PACKAGE_COMMAND_ALIAS}async function dispatchPackageCommand(args,runtimeOptions={}){if(!isPackageCommandArgv(args))return!1;let{handlePackageCommand}=await import("./package-manager-cli-3XO456VE.js");return await handlePackageCommand(args,runtimeOptions)}async function dispatchConfigCommand(args,runtimeOptions={}){if(args[0]!==CONFIG_COMMAND_ARGV)return!1;let{handleConfigCommand}=await import("./package-manager-cli-3XO456VE.js");return await handleConfigCommand(args,runtimeOptions)}async function dispatchHostCommand(args){if(args[0]!==HOST_COMMAND_ARGV)return;if(args[1]==="session"){let{runHostSessionCommand}=await import("./host-session-command-FFN52LXJ.js");return await runHostSessionCommand(args.slice(2))}let{runHostCommand}=await import("./host-command-XEB7SHT3.js");return await runHostCommand(args.slice(1))}async function dispatchScheduleCommand(args){if(args[0]!==SCHEDULE_COMMAND_ARGV)return;let{runScheduleCommand}=await import("./schedule-command-B7RRSANU.js");return await runScheduleCommand(args.slice(1))}export{RUNTIME_ENV_VAR,MIN_BUN_VERSION,bunVersionSatisfies,findBunBinary,resolveBunReexec,processBunRuntimeOptions,captureStdout,exitAfterOutput,printThenExit,getPiUserAgent,StaleExtensionContextError,isStaleExtensionContextError,markModeCrashHandler,hasModeCrashHandler,INSPECTOR_VM_IMPORT_WARNING,hasInheritedInspectorOption,releaseInheritedInspectorForChild,isRecoverableInspectorVmImportError,installEarlyInspectorVmImportRecovery,consumeEarlyInspectorVmImportRecoveries,formatVersionCheckError,isNewerPackageVersion,getReleaseChangelogUrl,getLatestPiRelease,checkForNewPiVersion,CONFIG_COMMAND_ARGV,HOST_COMMAND_ARGV,SCHEDULE_COMMAND_ARGV,isPackageCommandArgv,dispatchPackageCommand,dispatchConfigCommand,dispatchHostCommand,dispatchScheduleCommand};
@@ -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{McpPresenterAuthority,attachMcpGrantPresentation,effectStatusRecord,sessionQuestionBridges}from"./chunk-2XF6W6F6.js";import{RPC_ERROR_INVALID_SESSION_CONTEXT,RPC_ERROR_INVALID_SUBSCRIPTION,RPC_ERROR_SESSION_NOT_ATTACHED,RPC_ERROR_SUBSCRIPTION_LIMIT,RPC_ERROR_UNKNOWN_SUBSCRIPTION,RPC_ERROR_UNSUPPORTED_TRANSPORT}from"./chunk-GY5MR5KR.js";import{carriesMedia,normalizeJsonValue,omitNormalInlineMedia}from"./chunk-DNDZPKIQ.js";import{bindPrivateMcpForms}from"./chunk-JPGT64RV.js";import{MEDIA_PLACEHOLDERS_CAPABILITY,hostGeneration,hostInstanceId}from"./chunk-CNDPCYNT.js";import{serializeJsonLine}from"./chunk-YI7SPFDN.js";import{AsyncLocalStorage}from"node:async_hooks";var SessionStructuredLanes=class{constructor(){this.receivers=new Map}observe(sessionId,receiver){let receivers=this.receivers.get(sessionId)??new Set;return receivers.add(receiver),this.receivers.set(sessionId,receivers),()=>{receivers.delete(receiver),receivers.size===0&&this.receivers.get(sessionId)===receivers&&this.receivers.delete(sessionId)}}accept(sessionId,record){for(let receiver of[...this.receivers.get(sessionId)??[]])receiver(record)}};var RpcSecurityPresentations=class{#sessions=new Map;#attachments=new Map;constructor(fanout,inConnection,flush){this.fanout=fanout,this.inConnection=inConnection,this.flush=flush}bind(sessionId,durableId,notices,select){let previous=this.#sessions.get(sessionId);this.#stop(previous);let state={durableId,select,snapshot:notices.snapshot,registrations:new Map,grants:new Map,replayed:previous?.durableId===durableId?previous.replayed:new Map};this.#sessions.set(sessionId,state),state.stop=notices.subscribe(snapshot=>this.acceptSnapshot(sessionId,snapshot));for(let id of this.fanout.attachedConnections(sessionId))this.#register(id,state);return()=>{this.#sessions.get(sessionId)===state&&(this.#stop(state),this.#sessions.delete(sessionId))}}acceptSnapshot(sessionId,snapshot){let state=this.#sessions.get(sessionId);state===void 0&&(state={snapshot,registrations:new Map,grants:new Map,replayed:new Map},this.#sessions.set(sessionId,state)),state.snapshot=snapshot;for(let id of this.fanout.attachedConnections(sessionId))this.#replay(sessionId,id,snapshot)}attach(id,sessionId){let attached=this.#attachments.get(id)??new Set;if(attached.has(sessionId))return;attached.add(sessionId),this.#attachments.set(id,attached);let state=this.#sessions.get(sessionId);state!==void 0&&(this.#register(id,state),this.#replay(sessionId,id,state.snapshot))}detach(id,sessionId){this.#attachments.get(id)?.delete(sessionId),this.#attachments.get(id)?.size===0&&this.#attachments.delete(id);let state=this.#sessions.get(sessionId);state?.registrations.get(id)?.(),state?.registrations.delete(id),state?.replayed.delete(id),state!==void 0&&this.#cancelFor(state,id)}dropConnection(id){for(let sessionId of[...this.#attachments.get(id)??[]])this.detach(id,sessionId)}capabilitiesChanged(id){for(let sessionId of this.#attachments.get(id)??[]){let state=this.#sessions.get(sessionId);state!==void 0&&(this.#register(id,state),this.fanout.connectionHas(id,"grant_select")||this.#cancelFor(state,id))}}routeWorkerGrant(sessionId,requestId,preferred,fallbackCapabilities,cancel){let attached=this.fanout.attachedConnections(sessionId),connection=attached.includes(preferred??"")&&this.fanout.connectionHas(preferred,"grant_select")?preferred:attached.find(id=>this.fanout.connectionHas(id,"grant_select"));if(!(connection!==void 0||this.fanout.isEmpty()&&fallbackCapabilities.includes("grant_select")))return cancel(),{accepted:!1};let state=this.#sessions.get(sessionId);return state===void 0&&(state={snapshot:{generation:0,notices:[]},registrations:new Map,grants:new Map,replayed:new Map},this.#sessions.set(sessionId,state)),state.grants.set(requestId,{connection,cancel}),{accepted:!0,connection}}acceptWorkerResponse(sessionId,requestId,connection){let pending=this.#sessions.get(sessionId)?.grants.get(requestId);if(pending!==void 0)return!(pending.connection!==connection||connection!==void 0&&!this.fanout.connectionHas(connection,"grant_select"))}settleGrant(sessionId,requestId){this.#sessions.get(sessionId)?.grants.delete(requestId)}dropSession(sessionId){this.#stop(this.#sessions.get(sessionId)),this.#sessions.delete(sessionId);for(let[id,sessions]of this.#attachments)sessions.delete(sessionId),sessions.size===0&&this.#attachments.delete(id)}#register(id,state){if(!this.fanout.connectionHas(id,"grant_select")){state.registrations.get(id)?.(),state.registrations.delete(id);return}if(state.registrations.has(id)||state.select===void 0||state.durableId===void 0)return;let select=state.select;state.registrations.set(id,attachMcpGrantPresentation(state.durableId,(title,choices,opts)=>this.inConnection(id,()=>select(title,choices,opts))))}#replay(sessionId,id,snapshot){let target=this.fanout.get(id);if(target===void 0)return;let state=this.#sessions.get(sessionId),revision=JSON.stringify(snapshot);if(state?.replayed.get(id)!==revision){state?.replayed.set(id,revision);for(let notice of snapshot.notices)target.actor.enqueue(serializeJsonLine({type:"extension_ui_request",id:crypto.randomUUID(),sessionId,method:"notify",notifyType:"warning",message:notice.message}));this.flush()}}#cancelFor(state,id){for(let[requestId,pending]of state.grants)pending.connection===id&&(state.grants.delete(requestId),pending.cancel())}#stop(state){state?.stop?.();for(let stop of state?.registrations.values()??[])stop();for(let pending of state?.grants.values()??[])pending.cancel()}};var blockedMsTotal=0;function recordLoopBlockedMs(driftMs){driftMs>0&&(blockedMsTotal+=driftMs)}function loopBlockedMark(){return blockedMsTotal}function loopBlockedMsSince(mark){return blockedMsTotal-mark}var EVENT_RESYNC_CAPABILITY="event_resync";function isCorrelatedReply(value){return typeof value=="object"&&value!==null&&"type"in value&&value.type==="response"&&"id"in value&&typeof value.id=="string"}var SocketPeerLivenessError=class extends Error{constructor(){super("socket peer missed its liveness ping"),this.name="SocketPeerLivenessError"}},SocketPeerRecovery=class{constructor(write,snapshot){this.awaitingPing=!1,this.pingBuffered=!1,this.replyLost=!1,this.write=write,this.snapshot=snapshot,this.pingBuffered=!0,this.write(serializeJsonLine({type:"rpc_ping"}))}get pending(){return this.reason!==void 0}shed(reason){this.reason===void 0&&(this.reason=reason,this.readSnapshot=this.snapshot(reason))}acknowledge(){this.awaitingPing=!1}loseReply(){this.replyLost=!0}ping(){if(this.awaitingPing)throw new SocketPeerLivenessError;this.awaitingPing=!0,this.pingBuffered||(this.pingBuffered=!0,this.write(serializeJsonLine({type:"rpc_ping"})))}takeSnapshot(){let reason=this.reason;this.reason=void 0,this.awaitingPing=!1,this.pingBuffered=!1;let snapshot=this.readSnapshot;this.readSnapshot=void 0;let gap=reason===void 0?[]:[{type:"resync_required",reason,replyLost:this.replyLost}];return this.replyLost=!1,[...gap,...snapshot?.()??[]]}};var DEFAULT_QUEUE_BYTES=64*1024*1024,DEFAULT_STALL_MS=3e4,SocketEventQueueStallError=class extends Error{constructor(pendingBytes,stallMs){super(`socket event queue stalled: peer did not drain ${pendingBytes} queued bytes within ${stallMs}ms`),this.name="SocketEventQueueStallError",this.pendingBytes=pendingBytes,this.stallMs=stallMs}},SocketEventQueueOverflowError=class extends Error{constructor(queuedBytes,incomingBytes,maxQueueBytes,incomingPreview){super(`socket event queue overflow: ${queuedBytes} queued + ${incomingBytes} incoming > ${maxQueueBytes} (incoming: ${incomingPreview})`),this.name="SocketEventQueueOverflowError",this.queuedBytes=queuedBytes,this.incomingBytes=incomingBytes,this.maxQueueBytes=maxQueueBytes,this.incomingPreview=incomingPreview}},SocketEventSinkActor=class{constructor(sink,onFailure,maxQueueBytes=DEFAULT_QUEUE_BYTES,stallMs=DEFAULT_STALL_MS){this.queue=[],this.queuedBytes=0,this.closed=!1,this.recoveryEnabled=!1,this.stopped=new AbortController,this.sink=sink,this.onFailure=onFailure,this.maxQueueBytes=maxQueueBytes,this.stallMs=stallMs}enableRecovery(snapshot){this.recoveryEnabled=!0,this.recovery??=new SocketPeerRecovery(line=>this.sink.writeRaw(line),snapshot),this.recovery.acknowledge()}disableRecovery(){this.recoveryEnabled=!1,this.recovery?.pending||(this.recovery=void 0)}enqueue(line,key,onWritten,demotedLine,reply=!1){if(this.closed)return;if(this.recovery?.pending&&!reply){onWritten?.();return}let bytes=Buffer.byteLength(line);if(this.recovery?.pending){this.queuedBytes+bytes<=this.maxQueueBytes?(this.queue.push({line,bytes,onWritten,reply}),this.queuedBytes+=bytes):(this.recovery.loseReply(),onWritten?.());return}if(key!==void 0){let existing=this.queue.find(entry=>entry.key===key);existing&&(existing.demotedLine!==void 0&&(this.queuedBytes-=existing.bytes,existing.line=existing.demotedLine,existing.bytes=Buffer.byteLength(existing.line),this.queuedBytes+=existing.bytes,existing.demotedLine=void 0),existing.key=void 0)}if(this.queuedBytes+bytes>this.maxQueueBytes){if(this.recovery&&this.recoveryEnabled){this.shed("overflow"),this.enqueue(line,void 0,onWritten,void 0,reply),this.drain();return}let overflow=new SocketEventQueueOverflowError(this.queuedBytes,bytes,this.maxQueueBytes,line.slice(0,120));this.closed=!0,this.queue.length=0,this.queuedBytes=0;try{this.sink.writeRaw(`${JSON.stringify({type:"overflow",error:"overflow, resync required"})}
2
+ import{McpPresenterAuthority,attachMcpGrantPresentation,effectStatusRecord,sessionQuestionBridges}from"./chunk-ZAS4NBVK.js";import{RPC_ERROR_INVALID_SESSION_CONTEXT,RPC_ERROR_INVALID_SUBSCRIPTION,RPC_ERROR_SESSION_NOT_ATTACHED,RPC_ERROR_SUBSCRIPTION_LIMIT,RPC_ERROR_UNKNOWN_SUBSCRIPTION,RPC_ERROR_UNSUPPORTED_TRANSPORT}from"./chunk-GY5MR5KR.js";import{carriesMedia,normalizeJsonValue,omitNormalInlineMedia}from"./chunk-DNDZPKIQ.js";import{bindPrivateMcpForms}from"./chunk-TV3UI63P.js";import{MEDIA_PLACEHOLDERS_CAPABILITY,hostGeneration,hostInstanceId}from"./chunk-CNDPCYNT.js";import{serializeJsonLine}from"./chunk-YI7SPFDN.js";import{AsyncLocalStorage}from"node:async_hooks";var SessionStructuredLanes=class{constructor(){this.receivers=new Map}observe(sessionId,receiver){let receivers=this.receivers.get(sessionId)??new Set;return receivers.add(receiver),this.receivers.set(sessionId,receivers),()=>{receivers.delete(receiver),receivers.size===0&&this.receivers.get(sessionId)===receivers&&this.receivers.delete(sessionId)}}accept(sessionId,record){for(let receiver of[...this.receivers.get(sessionId)??[]])receiver(record)}};var RpcSecurityPresentations=class{#sessions=new Map;#attachments=new Map;constructor(fanout,inConnection,flush){this.fanout=fanout,this.inConnection=inConnection,this.flush=flush}bind(sessionId,durableId,notices,select){let previous=this.#sessions.get(sessionId);this.#stop(previous);let state={durableId,select,snapshot:notices.snapshot,registrations:new Map,grants:new Map,replayed:previous?.durableId===durableId?previous.replayed:new Map};this.#sessions.set(sessionId,state),state.stop=notices.subscribe(snapshot=>this.acceptSnapshot(sessionId,snapshot));for(let id of this.fanout.attachedConnections(sessionId))this.#register(id,state);return()=>{this.#sessions.get(sessionId)===state&&(this.#stop(state),this.#sessions.delete(sessionId))}}acceptSnapshot(sessionId,snapshot){let state=this.#sessions.get(sessionId);state===void 0&&(state={snapshot,registrations:new Map,grants:new Map,replayed:new Map},this.#sessions.set(sessionId,state)),state.snapshot=snapshot;for(let id of this.fanout.attachedConnections(sessionId))this.#replay(sessionId,id,snapshot)}attach(id,sessionId){let attached=this.#attachments.get(id)??new Set;if(attached.has(sessionId))return;attached.add(sessionId),this.#attachments.set(id,attached);let state=this.#sessions.get(sessionId);state!==void 0&&(this.#register(id,state),this.#replay(sessionId,id,state.snapshot))}detach(id,sessionId){this.#attachments.get(id)?.delete(sessionId),this.#attachments.get(id)?.size===0&&this.#attachments.delete(id);let state=this.#sessions.get(sessionId);state?.registrations.get(id)?.(),state?.registrations.delete(id),state?.replayed.delete(id),state!==void 0&&this.#cancelFor(state,id)}dropConnection(id){for(let sessionId of[...this.#attachments.get(id)??[]])this.detach(id,sessionId)}capabilitiesChanged(id){for(let sessionId of this.#attachments.get(id)??[]){let state=this.#sessions.get(sessionId);state!==void 0&&(this.#register(id,state),this.fanout.connectionHas(id,"grant_select")||this.#cancelFor(state,id))}}routeWorkerGrant(sessionId,requestId,preferred,fallbackCapabilities,cancel){let attached=this.fanout.attachedConnections(sessionId),connection=attached.includes(preferred??"")&&this.fanout.connectionHas(preferred,"grant_select")?preferred:attached.find(id=>this.fanout.connectionHas(id,"grant_select"));if(!(connection!==void 0||this.fanout.isEmpty()&&fallbackCapabilities.includes("grant_select")))return cancel(),{accepted:!1};let state=this.#sessions.get(sessionId);return state===void 0&&(state={snapshot:{generation:0,notices:[]},registrations:new Map,grants:new Map,replayed:new Map},this.#sessions.set(sessionId,state)),state.grants.set(requestId,{connection,cancel}),{accepted:!0,connection}}acceptWorkerResponse(sessionId,requestId,connection){let pending=this.#sessions.get(sessionId)?.grants.get(requestId);if(pending!==void 0)return!(pending.connection!==connection||connection!==void 0&&!this.fanout.connectionHas(connection,"grant_select"))}settleGrant(sessionId,requestId){this.#sessions.get(sessionId)?.grants.delete(requestId)}dropSession(sessionId){this.#stop(this.#sessions.get(sessionId)),this.#sessions.delete(sessionId);for(let[id,sessions]of this.#attachments)sessions.delete(sessionId),sessions.size===0&&this.#attachments.delete(id)}#register(id,state){if(!this.fanout.connectionHas(id,"grant_select")){state.registrations.get(id)?.(),state.registrations.delete(id);return}if(state.registrations.has(id)||state.select===void 0||state.durableId===void 0)return;let select=state.select;state.registrations.set(id,attachMcpGrantPresentation(state.durableId,(title,choices,opts)=>this.inConnection(id,()=>select(title,choices,opts))))}#replay(sessionId,id,snapshot){let target=this.fanout.get(id);if(target===void 0)return;let state=this.#sessions.get(sessionId),revision=JSON.stringify(snapshot);if(state?.replayed.get(id)!==revision){state?.replayed.set(id,revision);for(let notice of snapshot.notices)target.actor.enqueue(serializeJsonLine({type:"extension_ui_request",id:crypto.randomUUID(),sessionId,method:"notify",notifyType:"warning",message:notice.message}));this.flush()}}#cancelFor(state,id){for(let[requestId,pending]of state.grants)pending.connection===id&&(state.grants.delete(requestId),pending.cancel())}#stop(state){state?.stop?.();for(let stop of state?.registrations.values()??[])stop();for(let pending of state?.grants.values()??[])pending.cancel()}};var blockedMsTotal=0;function recordLoopBlockedMs(driftMs){driftMs>0&&(blockedMsTotal+=driftMs)}function loopBlockedMark(){return blockedMsTotal}function loopBlockedMsSince(mark){return blockedMsTotal-mark}var EVENT_RESYNC_CAPABILITY="event_resync";function isCorrelatedReply(value){return typeof value=="object"&&value!==null&&"type"in value&&value.type==="response"&&"id"in value&&typeof value.id=="string"}var SocketPeerLivenessError=class extends Error{constructor(){super("socket peer missed its liveness ping"),this.name="SocketPeerLivenessError"}},SocketPeerRecovery=class{constructor(write,snapshot){this.awaitingPing=!1,this.pingBuffered=!1,this.replyLost=!1,this.write=write,this.snapshot=snapshot,this.pingBuffered=!0,this.write(serializeJsonLine({type:"rpc_ping"}))}get pending(){return this.reason!==void 0}shed(reason){this.reason===void 0&&(this.reason=reason,this.readSnapshot=this.snapshot(reason))}acknowledge(){this.awaitingPing=!1}loseReply(){this.replyLost=!0}ping(){if(this.awaitingPing)throw new SocketPeerLivenessError;this.awaitingPing=!0,this.pingBuffered||(this.pingBuffered=!0,this.write(serializeJsonLine({type:"rpc_ping"})))}takeSnapshot(){let reason=this.reason;this.reason=void 0,this.awaitingPing=!1,this.pingBuffered=!1;let snapshot=this.readSnapshot;this.readSnapshot=void 0;let gap=reason===void 0?[]:[{type:"resync_required",reason,replyLost:this.replyLost}];return this.replyLost=!1,[...gap,...snapshot?.()??[]]}};var DEFAULT_QUEUE_BYTES=64*1024*1024,DEFAULT_STALL_MS=3e4,SocketEventQueueStallError=class extends Error{constructor(pendingBytes,stallMs){super(`socket event queue stalled: peer did not drain ${pendingBytes} queued bytes within ${stallMs}ms`),this.name="SocketEventQueueStallError",this.pendingBytes=pendingBytes,this.stallMs=stallMs}},SocketEventQueueOverflowError=class extends Error{constructor(queuedBytes,incomingBytes,maxQueueBytes,incomingPreview){super(`socket event queue overflow: ${queuedBytes} queued + ${incomingBytes} incoming > ${maxQueueBytes} (incoming: ${incomingPreview})`),this.name="SocketEventQueueOverflowError",this.queuedBytes=queuedBytes,this.incomingBytes=incomingBytes,this.maxQueueBytes=maxQueueBytes,this.incomingPreview=incomingPreview}},SocketEventSinkActor=class{constructor(sink,onFailure,maxQueueBytes=DEFAULT_QUEUE_BYTES,stallMs=DEFAULT_STALL_MS){this.queue=[],this.queuedBytes=0,this.closed=!1,this.recoveryEnabled=!1,this.stopped=new AbortController,this.sink=sink,this.onFailure=onFailure,this.maxQueueBytes=maxQueueBytes,this.stallMs=stallMs}enableRecovery(snapshot){this.recoveryEnabled=!0,this.recovery??=new SocketPeerRecovery(line=>this.sink.writeRaw(line),snapshot),this.recovery.acknowledge()}disableRecovery(){this.recoveryEnabled=!1,this.recovery?.pending||(this.recovery=void 0)}enqueue(line,key,onWritten,demotedLine,reply=!1){if(this.closed)return;if(this.recovery?.pending&&!reply){onWritten?.();return}let bytes=Buffer.byteLength(line);if(this.recovery?.pending){this.queuedBytes+bytes<=this.maxQueueBytes?(this.queue.push({line,bytes,onWritten,reply}),this.queuedBytes+=bytes):(this.recovery.loseReply(),onWritten?.());return}if(key!==void 0){let existing=this.queue.find(entry=>entry.key===key);existing&&(existing.demotedLine!==void 0&&(this.queuedBytes-=existing.bytes,existing.line=existing.demotedLine,existing.bytes=Buffer.byteLength(existing.line),this.queuedBytes+=existing.bytes,existing.demotedLine=void 0),existing.key=void 0)}if(this.queuedBytes+bytes>this.maxQueueBytes){if(this.recovery&&this.recoveryEnabled){this.shed("overflow"),this.enqueue(line,void 0,onWritten,void 0,reply),this.drain();return}let overflow=new SocketEventQueueOverflowError(this.queuedBytes,bytes,this.maxQueueBytes,line.slice(0,120));this.closed=!0,this.queue.length=0,this.queuedBytes=0;try{this.sink.writeRaw(`${JSON.stringify({type:"overflow",error:"overflow, resync required"})}
3
3
  `)}catch(cause){this.onFailure(cause)}this.onFailure(overflow);return}this.queue.push({line,bytes,key,demotedLine,onWritten,reply}),this.queuedBytes+=bytes,this.drain()}async flush(){for(;this.draining;)await this.draining;if(this.failure!==void 0)throw this.failure}waitForAcceptance(){return Promise.resolve()}close(){this.closed=!0,this.queue.length=0,this.queuedBytes=0,this.stopped.abort()}shed(reason){if(this.recovery?.pending)return;let replies=[];for(let entry of this.queue)entry.reply?replies.push(entry):entry.onWritten?.();this.queue.length=0;for(let reply of replies)this.queue.push(reply);this.queuedBytes=replies.reduce((bytes,entry)=>bytes+entry.bytes,0),this.recovery?.shed(reason)}waitForDrainOrStall(writtenBytes){return new Promise((resolve,reject)=>{let timer,blockedMark=loopBlockedMark(),cleanup=()=>{clearTimeout(timer),this.stopped.signal.removeEventListener("abort",onStop)},onStop=()=>{cleanup(),resolve()},onDeadline=()=>{let blockedMs=loopBlockedMsSince(blockedMark);if(blockedMs>0){blockedMark=loopBlockedMark(),timer=setTimeout(onDeadline,Math.min(blockedMs,this.stallMs));return}if(this.recovery&&this.recoveryEnabled){try{this.shed("stall"),this.recovery.ping(),blockedMark=loopBlockedMark(),timer=setTimeout(onDeadline,this.stallMs)}catch(cause){cleanup(),reject(cause)}return}let stall=new SocketEventQueueStallError(this.queuedBytes+writtenBytes,this.stallMs);try{this.sink.writeRaw(`${JSON.stringify({type:"overflow",error:"stalled, resync required"})}
4
4
  `)}catch{}cleanup(),reject(stall)};timer=setTimeout(onDeadline,this.stallMs),this.stopped.signal.addEventListener("abort",onStop,{once:!0}),this.sink.waitForBackpressure().then(()=>{cleanup(),resolve()},cause=>{cleanup(),reject(cause)})})}drain(){return this.draining?this.draining:(this.draining=(async()=>{try{for(;!this.closed&&(this.queue.length>0||this.recovery?.pending);){if(this.recovery?.pending&&this.queue.length===0){if(await this.waitForDrainOrStall(0),this.closed)break;let snapshot=this.recovery.takeSnapshot();this.recoveryEnabled||(this.recovery=void 0);for(let record of snapshot){if(this.closed||this.recovery?.pending)break;let line=serializeJsonLine(record);this.sink.writeRaw(line),await this.waitForDrainOrStall(Buffer.byteLength(line))}continue}let entry=this.queue.shift();this.queuedBytes-=entry.bytes,this.sink.writeRaw(entry.line),await this.waitForDrainOrStall(entry.bytes),entry.onWritten?.()}}catch(cause){this.failure=cause,this.closed=!0,this.queue.length=0,this.queuedBytes=0,this.onFailure(cause)}})().finally(()=>{this.draining=void 0,!this.closed&&(this.queue.length>0||this.recovery?.pending)&&this.drain()}),this.draining)}};var BROADCAST_LIFECYCLE_RECORDS=new Set(["agent_start","agent_settled","agent_idle","session_opened","session_closed","session_lifecycle"]);function snapshotPlaceholderLine(record){if(record.placeholderLine!==void 0)return record.placeholderLine;if(!record.mayCarryMedia)return record.line;let source=JSON.parse(record.line),redacted=omitNormalInlineMedia(source);return record.placeholderLine=redacted===source?record.line:serializeJsonLine(redacted),record.placeholderLine}var SessionEventFanout=class{constructor(){this.connections=new Map,this.sessionSnapshots=new Map,this.lifecycleSnapshots=new Map,this.pendingQuestions=new Map,this.connectionCapabilities=new Map,this.connectionSessions=new Map,this.registeredCapabilityConnections=new Set}registerConnection(id,connection,options={}){let actor=new SocketEventSinkActor(connection,cause=>{this.connections.get(id)?.actor===actor&&(this.connections.delete(id),this.connectionCapabilities.delete(id),this.connectionSessions.delete(id),this.registeredCapabilityConnections.delete(id),this.onConnectionClosed?.(id)),process.stderr.write(`senpi rpc connection ${id} event queue failed; closing: ${cause instanceof Error?cause.message:String(cause)}
5
5
  `),connection.close?.()},options.maxQueueBytes,options.stallMs);this.connections.set(id,{connection,actor}),this.connectionCapabilities.set(id,new Set),this.connectionSessions.set(id,new Set)}unregisterConnection(id){let registered=this.connections.get(id);registered&&(registered.actor.close(),this.connections.delete(id),this.connectionCapabilities.delete(id),this.connectionSessions.delete(id),this.registeredCapabilityConnections.delete(id))}attachConnectionToSession(id,sessionId){if(!this.connections.has(id))return;let sessions=this.connectionSessions.get(id)??new Set;if(!sessions.has(sessionId)){sessions.add(sessionId),this.connectionSessions.set(id,sessions),this.replaySnapshot(id,sessionId);for(let frame of this.pendingQuestions.get(sessionId)?.values()??[])this.connections.get(id)?.actor.enqueue(serializeJsonLine({...frame,remainingMs:typeof frame.deadlineAtMs=="number"?Math.max(0,frame.deadlineAtMs-Date.now()):0}))}}detachConnectionFromSession(id,sessionId){this.connectionSessions.get(id)?.delete(sessionId)}setConnectionCapabilities(id,capabilities){let registered=this.connections.get(id);registered&&(this.connectionCapabilities.set(id,new Set(capabilities)),this.registeredCapabilityConnections.add(id),capabilities.includes(EVENT_RESYNC_CAPABILITY)?registered.actor.enableRecovery(reason=>{let attached=[...this.connectionSessions.get(id)??[]];return()=>this.resyncSnapshot(id,reason,attached)}):registered.actor.disableRecovery())}clearConnectionCapabilities(id){this.connections.has(id)&&(this.connectionCapabilities.set(id,new Set),this.registeredCapabilityConnections.delete(id))}hasRegisteredConnectionCapabilities(id){return this.registeredCapabilityConnections.has(id)}getConnectionCapabilities(id){if(this.registeredCapabilityConnections.has(id))return[...this.connectionCapabilities.get(id)??[]]}connectionHas(id,capability){return id===void 0?!1:this.connectionCapabilities.get(id)?.has(capability)??!1}targets(sessionId,targetId,isTargeted,recordType){return isTargeted?[targetId]:typeof recordType=="string"&&BROADCAST_LIFECYCLE_RECORDS.has(recordType)?this.connections.size>0?[...this.connections.keys()]:[void 0]:this.connections.size>0?[...this.connections.keys()].filter(id=>this.connectionSessions.get(id)?.has(sessionId)):[void 0]}get(id){return this.connections.get(id)}values(){return this.connections.values()}isEmpty(){return this.connections.size===0}broadcast(line){for(let{actor}of this.connections.values())actor.enqueue(line)}connectionIds(){return[...this.connections.keys()]}attachedConnections(sessionId){return[...this.connections.keys()].filter(id=>this.connectionSessions.get(id)?.has(sessionId))}pendingQuestionCount(sessionId){return this.pendingQuestions.get(sessionId)?.size??0}deliverToSession(sessionId,line){for(let[id,{actor}]of this.connections)this.connectionSessions.get(id)?.has(sessionId)&&actor.enqueue(line)}rememberSnapshot(sessionId,value,line,placeholderLine){let record={line,placeholderLine,hasMessage:value.message!=null,mayCarryMedia:carriesMedia(value)};if(value.type==="session_lifecycle"){this.lifecycleSnapshots.set(sessionId,record);return}if(value.type==="extension_ui_request"&&value.method==="question"&&typeof value.id=="string"){let pending=this.pendingQuestions.get(sessionId)??new Map;pending.set(value.id,{...value}),this.pendingQuestions.set(sessionId,pending);return}if(value.type==="question_resolved"&&typeof value.id=="string"){this.pendingQuestions.get(sessionId)?.delete(value.id);return}if(value.type==="question_updated"&&typeof value.id=="string"){let frame=this.pendingQuestions.get(sessionId)?.get(value.id);frame&&Object.assign(frame,{deadlineAtMs:value.deadlineAtMs,remainingMs:value.remainingMs});return}let event=value.assistantMessageEvent;value.type==="message_start"||value.type==="message_update"&&event?.type==="text_start"?this.sessionSnapshots.set(sessionId,[record]):this.sessionSnapshots.has(sessionId)&&this.sessionSnapshots.get(sessionId)?.push(record),value.type==="message_end"&&this.sessionSnapshots.delete(sessionId)}forgetSession(sessionId){this.pendingQuestions.delete(sessionId),this.sessionSnapshots.delete(sessionId),this.lifecycleSnapshots.delete(sessionId)}replaySnapshot(id,sessionId){let actor=this.connections.get(id)?.actor;if(!actor)return;let placeholders=this.connectionHas(id,MEDIA_PLACEHOLDERS_CAPABILITY),lifecycle=this.lifecycleSnapshots.get(sessionId);lifecycle&&actor.enqueue(placeholders?snapshotPlaceholderLine(lifecycle):lifecycle.line);for(let record of this.sessionSnapshots.get(sessionId)??[])actor.enqueue(placeholders?snapshotPlaceholderLine(record):record.line)}resyncSnapshot(id,reason,attached){let placeholders=this.connectionHas(id,MEDIA_PLACEHOLDERS_CAPABILITY),current=this.connectionSessions.get(id)??new Set;return[...new Set([...attached,...current])].map(sessionId=>{let latest=(this.sessionSnapshots.get(sessionId)??[]).findLast(record2=>record2.hasMessage),frozen=latest===void 0?void 0:JSON.parse(latest.line),record={type:"resync_required",sessionId,reason,message:typeof frozen=="object"&&frozen!==null&&"message"in frozen?frozen.message:null,...current.has(sessionId)?{}:{closed:!0}};return placeholders?omitNormalInlineMedia(record):record})}};var SessionOpenTurns=class{constructor(){this.open=new Map}note(sessionId,type){if(type==="agent_start")this.open.set(sessionId,(this.open.get(sessionId)??0)+1);else if(type==="agent_settled"){let left=(this.open.get(sessionId)??0)-1;left>0?this.open.set(sessionId,left):this.open.delete(sessionId)}}take(sessionId){let owed=this.open.get(sessionId)??0;return this.open.delete(sessionId),owed}};var SessionRecordAccounting=class{constructor(){this.count=0,this.bytes=0}append(queue,value,key,resolve,reject){let line=serializeJsonLine(value),byteLength=Buffer.byteLength(line),node={value,line,byteLength,key,previous:queue.tail,resolve,reject};return queue.tail?queue.tail.next=node:queue.head=node,queue.tail=node,this.count++,this.bytes+=byteLength,node}replace(node,value){let line=serializeJsonLine(value),byteLength=Buffer.byteLength(line);this.bytes+=byteLength-node.byteLength,node.value=value,node.line=line,node.byteLength=byteLength}unlink(queue,node){node.previous?node.previous.next=node.next:queue.head=node.next,node.next?node.next.previous=node.previous:queue.tail=node.previous,node.key&&queue.latestByKey.get(node.key)===node&&queue.latestByKey.delete(node.key),node.previous=void 0,node.next=void 0,this.count--,this.bytes-=node.byteLength}};function liveStatus(runtime,fanout){return fanout.pendingQuestions>0||runtime.pendingQuestions>0?"waiting_input":runtime.isCompacting?"compacting":runtime.isStreaming?"running":"idle"}function statusOf(entry,runtime,fanout,terminal){if(terminal!==void 0)return terminal.status;switch(entry.state){case"opening":return"opening";case"closing":case"quarantined":case"closed":return"closed";case"open":return runtime===void 0?"opening":liveStatus(runtime,fanout);default:{let exhaustive=entry.state;throw new Error(`unexpected session state ${String(exhaustive)}`)}}}function deriveSessionStatus(entry,runtime,fanout,terminal,cause){let status=statusOf(entry,runtime,fanout,terminal),reason=terminal?.reason??(status==="idle"&&cause==="abort"?"aborted":void 0);return{status,...reason!==void 0?{reason}:{},kind:entry.kind,cwd:entry.cwd,attachments:Math.max(0,entry.attachments),...entry.durableSessionId!==void 0?{durableSessionId:entry.durableSessionId}:{},...entry.sessionPath!==void 0?{sessionPath:entry.sessionPath}:{},...entry.name!==void 0?{name:entry.name}:{},...runtime?.model!==void 0?{model:{provider:runtime.model.provider,id:runtime.model.id}}:{},...runtime?.thinkingLevel!==void 0?{thinkingLevel:runtime.thinkingLevel}:{},pendingQueue:{steering:runtime?.steering??0,followUp:runtime?.followUp??0},context:entry.context}}function terminalOfLifecycle(record){let reason=typeof record.reason=="string"?record.reason:void 0;if(record.type==="session_parked")return{status:"unloaded",reason:reason==="unloaded"?"unload_session":"idle"};if(record.type==="session_closed")return reason==="handoff_parked"?{status:"unloaded",reason:"handoff"}:reason===void 0?{status:"closed"}:{status:"closed",reason}}function causeOfRecord(record){switch(record.type){case"agent_start":return"prompt";case"agent_end":return"agent_end";case"agent_idle":return"agent_idle";case"session_abort":return"abort";case"queue_update":return"queue";case"model_changed":case"thinking_level_changed":return"set_model";case"session_replaced":return"replace";case"session_parked":return"park";case"session_closed":return"close";case"question_resolved":return"question";case"extension_ui_request":return record.method==="question"?"question":void 0;case"compaction_start":case"compaction_end":return"compaction";default:return}}function sessionOpenedLines(record){let{context,...plain}=record;return{plain:serializeJsonLine(plain),withContext:serializeJsonLine(context===void 0?plain:{...plain,context})}}var RECORD_TYPE_PATTERN=/^[a-z][a-z0-9_]{0,63}$/;function refusal(reason,action){return{refusal:{reason,action}}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function parseSelector(value){if(value===void 0||value==="all")return{selector:{kind:"all"}};let action='send sessions: "all", { ids: [<sessionId | durableSessionId | sessionPath>] } or { childrenOf: <durableSessionId> }';if(!isRecord(value))return refusal('sessions must be "all" or an object',action);if("ids"in value&&!("childrenOf"in value)){let ids=value.ids;return!Array.isArray(ids)||ids.length===0||ids.length>1024?refusal("sessions.ids must be a non-empty array of at most 1024 strings",action):ids.every(id=>typeof id=="string"&&id.length>0)?{selector:{kind:"ids",ids:new Set(ids)}}:refusal("every sessions.ids entry must be a non-empty string",action)}if("childrenOf"in value&&!("ids"in value)){let parent=value.childrenOf;return typeof parent!="string"||parent.length===0?refusal("sessions.childrenOf must be a non-empty durable session id",action):{selector:{kind:"childrenOf",parent}}}return refusal("sessions must name exactly one of ids or childrenOf",action)}function parseMirror(value){if(value===void 0||value==="none")return{mirror:{kind:"none"}};if(value==="all")return{mirror:{kind:"all"}};let action='send mirror: "none", "all" or an array of record types such as ["message_update"]';return!Array.isArray(value)||value.length===0||value.length>64?refusal('mirror must be "none", "all" or a non-empty array of at most 64 record types',action):value.every(type=>typeof type=="string"&&RECORD_TYPE_PATTERN.test(type))?{mirror:{kind:"types",types:new Set(value)}}:refusal(`every mirror entry must be a record type matching ${RECORD_TYPE_PATTERN.source}`,action)}function optionalBoolean(value,field){return value===void 0||typeof value=="boolean"?value:{reason:`${field} must be a boolean`,action:`send ${field}: true or false, or omit it`}}function parseSubscription(request){let selector=parseSelector(request.sessions);if("refusal"in selector)return selector;let mirror=parseMirror(request.mirror);if("refusal"in mirror)return mirror;let includeWorkers=optionalBoolean(request.include_workers,"include_workers");if(typeof includeWorkers=="object")return{refusal:includeWorkers};let includeContext=optionalBoolean(request.include_context,"include_context");if(typeof includeContext=="object")return{refusal:includeContext};let dialogs=optionalBoolean(request.dialogs,"dialogs");if(typeof dialogs=="object")return{refusal:dialogs};let effects=optionalBoolean(request.effects,"effects");return typeof effects=="object"?{refusal:effects}:{options:{selector:selector.selector,dialogs:dialogs??!1,includeWorkers:includeWorkers??selector.selector.kind==="childrenOf",includeContext:includeContext??!1,mirror:mirror.mirror,effects:effects??selector.selector.kind==="childrenOf"}}}function subscriptionMatches(options,sessionId,entry){if(entry.kind==="worker"&&!options.includeWorkers)return!1;let selector=options.selector;switch(selector.kind){case"all":return!0;case"ids":return selector.ids.has(sessionId)||entry.durableSessionId!==void 0&&selector.ids.has(entry.durableSessionId)||entry.sessionPath!==void 0&&selector.ids.has(entry.sessionPath);case"childrenOf":{let lineage=entry.openContext??entry.context;return(lineage.parent_session_id??lineage.root_session_id)===selector.parent}default:{let exhaustive=selector;throw new Error(`unexpected selector ${String(exhaustive)}`)}}}function mirrorsRecord(mirror,recordType){switch(mirror.kind){case"none":return!1;case"all":return!0;case"types":return mirror.types.has(recordType);default:{let exhaustive=mirror;throw new Error(`unexpected mirror ${String(exhaustive)}`)}}}var MAX_SUBSCRIPTIONS_PER_CONNECTION=64,SessionStatusStream=class{constructor(delivery){this.subscriptions=new Map,this.pendings=new Map,this.terminals=new Map,this.lastViews=new Map,this.lastChanges=new Map,this.nextSubscription=0,this.delivery=delivery}setSource(source){this.source=source}setLastEffectProvider(provider){this.lastEffect=provider}get size(){return this.subscriptions.size}connectionSize(connectionId){let count=0;for(let pending of this.pendings.values())pending.connectionId===connectionId&&count++;for(let subscription of this.subscriptions.values())subscription.connectionId===connectionId&&count++;return count}subscribe(connectionId,options){let pending={id:`sub-${++this.nextSubscription}`,connectionId,options,seq:0,lines:[]};this.pendings.set(pending.id,pending);let snapshot=[];for(let sessionId of this.source?.sessionIds()??[]){let view=this.currentView(sessionId);if(view===void 0||!subscriptionMatches(options,sessionId,view.entry))continue;let derived=this.derive(sessionId,view);snapshot.push(this.recordFor(pending,sessionId,derived,this.lastChangeOf(sessionId)))}return{subscriptionId:pending.id,snapshot,seq:pending.seq}}activate(subscriptionId){let pending=this.pendings.get(subscriptionId);if(pending===void 0)return;this.pendings.delete(subscriptionId);let subscription={id:pending.id,connectionId:pending.connectionId,options:pending.options,seq:pending.seq};this.subscriptions.set(subscription.id,subscription);for(let line of pending.lines)this.delivery.enqueue(subscription.connectionId,line);pending.lines.length=0}unsubscribe(connectionId,subscriptionId){let pending=this.pendings.get(subscriptionId);return pending!==void 0?pending.connectionId!==connectionId?!1:(this.pendings.delete(subscriptionId),!0):this.subscriptions.get(subscriptionId)?.connectionId!==connectionId?!1:(this.subscriptions.delete(subscriptionId),!0)}dropConnection(connectionId){for(let[id,pending]of this.pendings)pending.connectionId===connectionId&&this.pendings.delete(id);for(let[id,subscription]of this.subscriptions)subscription.connectionId===connectionId&&this.subscriptions.delete(id)}publish(sessionId,cause,by,contextOnly=!1){let change={at:(this.delivery.now?.()??new Date).toISOString(),cause,by};if(this.lastChanges.set(sessionId,change),this.subscriptions.size===0&&this.pendings.size===0)return;let view=this.currentView(sessionId);if(view===void 0)return;let derived=this.derive(sessionId,view,cause);for(let pending of this.pendings.values())contextOnly&&!pending.options.includeContext||subscriptionMatches(pending.options,sessionId,view.entry)&&(pending.seq+=1,pending.lines.push(serializeJsonLine(this.recordFor(pending,sessionId,derived,change))));for(let subscription of this.subscriptions.values()){if(contextOnly&&!subscription.options.includeContext||!subscriptionMatches(subscription.options,sessionId,view.entry))continue;subscription.seq+=1;let record=this.recordFor(subscription,sessionId,derived,change);this.delivery.enqueue(subscription.connectionId,serializeJsonLine(record))||this.subscriptions.delete(subscription.id)}}publishEffect(sessionId,status){if(this.subscriptions.size===0&&this.pendings.size===0)return;let view=this.currentView(sessionId);if(view===void 0)return;let at=status.updatedAt??status.acceptedAt??(this.delivery.now?.()??new Date).toISOString();for(let pending of this.pendings.values())!pending.options.effects||!subscriptionMatches(pending.options,sessionId,view.entry)||(pending.seq+=1,pending.lines.push(serializeJsonLine(effectStatusRecord(pending,sessionId,status,at))));for(let subscription of this.subscriptions.values()){if(!subscription.options.effects||!subscriptionMatches(subscription.options,sessionId,view.entry))continue;subscription.seq+=1;let line=serializeJsonLine(effectStatusRecord(subscription,sessionId,status,at));this.delivery.enqueue(subscription.connectionId,line)||this.subscriptions.delete(subscription.id)}}seal(sessionId,terminal,cause,by){this.terminals.set(sessionId,terminal),this.publish(sessionId,cause,by)}forget(sessionId){this.terminals.delete(sessionId),this.lastViews.delete(sessionId),this.lastChanges.delete(sessionId)}dialogTargets(sessionId){return this.mirrorTargets(sessionId,"ui_request_pending",!0)}mirrorTargets(sessionId,recordType,dialogs=!1){let subscriptions=[...this.pendings.values(),...this.subscriptions.values()].filter(subscription=>(dialogs?subscription.options.dialogs===!0:!0)&&(recordType==="snapshot_marker"||dialogs?subscription.options.mirror.kind!=="none":mirrorsRecord(subscription.options.mirror,recordType)));if(subscriptions.length===0)return[];let entry=this.source?.entryView(sessionId)??this.lastViews.get(sessionId)?.entry;if(entry===void 0)return[];let targets=new Set;for(let subscription of subscriptions)subscriptionMatches(subscription.options,sessionId,entry)&&targets.add(subscription.connectionId);return[...targets]}matchingConnections(sessionId){let view=this.currentView(sessionId),matches=new Map;if(view===void 0)return matches;for(let subscription of this.subscriptions.values())subscriptionMatches(subscription.options,sessionId,view.entry)&&matches.set(subscription.connectionId,(matches.get(subscription.connectionId)??!1)||subscription.options.includeContext);return matches}currentView(sessionId){let live=this.source?.view(sessionId);return live!==void 0&&this.lastViews.set(sessionId,live),live??this.lastViews.get(sessionId)}derive(sessionId,view,cause){return deriveSessionStatus(view.entry,view.runtime,{pendingQuestions:this.delivery.pendingQuestions(sessionId)},this.terminals.get(sessionId),cause)}lastChangeOf(sessionId){return this.lastChanges.get(sessionId)??{at:(this.delivery.now?.()??new Date).toISOString(),cause:"open",by:"host"}}recordFor(subscription,sessionId,derived,lastChange){let{context,...rest}=derived,lastEffect=this.lastEffect?.(sessionId);return{type:"session_status",subscriptionId:subscription.id,seq:subscription.seq,sessionId,...rest,...subscription.options.includeContext?{context}:{},...lastEffect!==void 0?{lastEffect}:{},lastChange}}};var SurfaceDigestDedupe=class{constructor(){this.connections=new Map}announce(connectionId,sessionId,previous,digest){let sessions=this.connections.get(connectionId);if(sessions===void 0&&(sessions=new Map,this.connections.set(connectionId,sessions)),previous===digest)return!1;let tell=!0;for(let[other,announced]of sessions)if(!(other===sessionId||announced.last!==digest)&&announced.previous===previous){tell=!1;break}return sessions.set(sessionId,{last:digest,previous}),tell}dropConnection(connectionId){this.connections.delete(connectionId)}forgetSession(sessionId){for(let sessions of this.connections.values())sessions.delete(sessionId)}};var settleActors=actors=>Promise.all(actors.map(actor=>actor.flush().catch(()=>{}))).then(()=>{}),acceptActors=actors=>Promise.all(actors.map(actor=>actor.waitForAcceptance())).then(()=>{}),MAX_SHARED_STDIO_QUEUE_BYTES=64*1024*1024,MAX_SHARED_STDIO_QUEUE_RECORDS=4096,MESSAGE_KEY="message",COMPACT_DELTA_TYPES=new Set(["text_delta","thinking_delta","toolcall_delta"]);function compactDelta(value){if(value.type!=="message_update"||!Object.hasOwn(value,"message"))return;let event=value.assistantMessageEvent;if(typeof event!="object"||event===null)return;let typedEvent=event;if(!(typeof typedEvent.type!="string"||!COMPACT_DELTA_TYPES.has(typedEvent.type)||typeof typedEvent.contentIndex!="number"||typeof typedEvent.delta!="string"))return{type:typedEvent.type,contentIndex:typedEvent.contentIndex,delta:typedEvent.delta}}function demoteToDeltaOnly(value){let event=value.assistantMessageEvent;return{...value,message:null,assistantMessageEvent:{...event,partial:null}}}function toolUpdateKey(value){return value.type==="tool_execution_update"&&typeof value.toolCallId=="string"?`tool:${value.toolCallId}`:void 0}var SessionEventWriter=class{enableMcpPresenters(){return this.presenterAuthority??=new McpPresenterAuthority,this.presenterAuthority}get mcpPresenters(){return this.presenterAuthority}getMcpPresenterConnection(id){return this.presenterConnections.get(id)}findMcpPresenterConnection(nonce){return[...this.presenterConnections.values()].find(connection=>connection.nonce===nonce)}getMcpFormBinding(sessionId){return this.presenterBindings.get(sessionId)}bindMcpForms(sessionId,durableId,ui,admit){let authority=this.presenterAuthority;if(!authority)return;let binding=authority.bind(sessionId,durableId,admit);this.presenterBindings.set(sessionId,binding);for(let id of this.fanout.attachedConnections(sessionId)){let connection=this.presenterConnections.get(id);connection&&authority.attach(connection,binding)}return bindPrivateMcpForms(ui,binding),()=>{binding.dispose(),this.presenterBindings.get(sessionId)===binding&&this.presenterBindings.delete(sessionId)}}handleMcpForm(value){if(!this.presenterAuthority||typeof value!="object"||value===null||!("type"in value)||typeof value.type!="string"||!value.type.startsWith("mcp_form_")&&value.type!=="mcp_presenter_context")return!1;let id=this.currentConnection(),sender=id===void 0?void 0:this.presenterConnections.get(id),context=value.type==="mcp_presenter_context"&&"sessionId"in value&&typeof value.sessionId=="string"&&sender?this.presenterAuthority?.connectionContext(sender,value.sessionId):void 0,reply=value.type==="mcp_presenter_context"?context?{ok:!0,context}:{error:"presenter_not_authorized"}:sender&&this.presenterAuthority?this.presenterAuthority.receive(sender,value):{error:"presenter_not_authorized"},connection=id===void 0?void 0:this.fanout.get(id)?.connection;if(connection)try{connection.writeRaw(serializeJsonLine({type:"mcp_form_reply",..."id"in value&&typeof value.id=="string"?{id:value.id}:{},...reply}))}catch{sender&&this.presenterAuthority?.detach(sender)}return!0}get pendingCloseRecordCount(){return this.reservedCloseRecords}get pendingCloseByteLength(){return this.reservedCloseBytes}constructor(writeRaw,waitOrSchedule,scheduleFlush){this.structuredLanes=new SessionStructuredLanes,this.presenterConnections=new Map,this.presenterBindings=new Map,this.records=new SessionRecordAccounting,this.queues=new Map,this.fanout=new SessionEventFanout,this.connectionContext=new AsyncLocalStorage,this.securityPresentations=new RpcSecurityPresentations(this.fanout,(id,task)=>this.withConnection(id,task),()=>this.requestFlush()),this.workerSecurityBridge=!1,this.controlQueue={latestByKey:new Map,ready:!1},this.readyQueues=[],this.sealedSessions=new Set,this.workerSessions=new Set,this.openTurns=new SessionOpenTurns,this.status=new SessionStatusStream({enqueue:(connectionId,line)=>{let actor=this.fanout.get(connectionId)?.actor;return actor===void 0?!1:(actor.enqueue(line),this.requestFlush(),!0)},pendingQuestions:sessionId=>this.fanout.pendingQuestionCount(sessionId)}),this.surfaceDedupe=new SurfaceDigestDedupe,this.mediaPersisters=new Map,this.flushScheduled=!1,this.controlOverflowReported=!1,this.closeOverflowReported=!1,this.closeOverflowActors=new WeakSet,this.reservedCloseRecords=0,this.reservedCloseBytes=0,this.fanout.onConnectionClosed=id=>{this.securityPresentations.dropConnection(id);let sender=this.presenterConnections.get(id);sender&&this.presenterAuthority?.detach(sender),this.presenterConnections.delete(id)},this.writeRaw=writeRaw,waitOrSchedule&&scheduleFlush===void 0&&waitOrSchedule.length>0?this.scheduleFlush=waitOrSchedule:(this.waitForBackpressure=waitOrSchedule,this.scheduleFlush=scheduleFlush??(flush=>queueMicrotask(()=>{flush()})))}get bufferedRecordCount(){return this.records.count+(this.inFlight?1:0)}get bufferedByteLength(){return this.records.bytes+(this.inFlight?.node.byteLength??0)}isSessionSealed(sessionId){return this.sealedSessions.has(sessionId)}registerConnection(id,connection,options={}){let previousPresenter=this.presenterConnections.get(id);if(previousPresenter&&this.presenterAuthority?.detach(previousPresenter),this.fanout.registerConnection(id,connection,options),this.presenterAuthority){let sender=this.presenterAuthority.connect(id,frame=>{if(!this.fanout.get(id))return!1;try{return connection.writeRaw(serializeJsonLine(frame)),connection.waitForBackpressure().catch(()=>this.presenterAuthority?.detach(sender)),!0}catch{return this.presenterAuthority?.detach(sender),!1}});this.presenterConnections.set(id,sender)}}unregisterConnection(id){let sender=this.presenterConnections.get(id);sender&&this.presenterAuthority?.detach(sender),this.presenterConnections.delete(id),this.securityPresentations.dropConnection(id),this.fanout.unregisterConnection(id),this.status.dropConnection(id),this.surfaceDedupe.dropConnection(id)}attachConnectionToSession(id,sessionId){this.fanout.attachConnectionToSession(id,sessionId),this.hasConnection(id)&&this.securityPresentations.attach(id,sessionId);let sender=this.presenterConnections.get(id),binding=this.presenterBindings.get(sessionId);sender&&binding&&this.presenterAuthority?.attach(sender,binding)}detachConnectionFromSession(id,sessionId){let sender=this.presenterConnections.get(id),binding=this.presenterBindings.get(sessionId);sender&&binding&&this.presenterAuthority?.detach(sender,binding),this.fanout.detachConnectionFromSession(id,sessionId),this.securityPresentations.detach(id,sessionId)}hasConnection(id){return this.fanout.get(id)!==void 0}setConnectionCapabilities(id,capabilities){if(this.fanout.setConnectionCapabilities(id,capabilities),this.securityPresentations.capabilitiesChanged(id),!capabilities.includes("interactive_user")||!capabilities.includes("mcp_form_presenter_v1")){let sender=this.presenterConnections.get(id);sender&&this.presenterAuthority?.withdraw(sender)}}clearConnectionCapabilities(id){let sender=this.presenterConnections.get(id);sender&&this.presenterAuthority?.withdraw(sender),this.fanout.clearConnectionCapabilities(id),this.securityPresentations.capabilitiesChanged(id)}bindSecurityPresentations(sessionId,durableId,notices,ui){if(!this.fanout.isEmpty())return this.securityPresentations.bind(sessionId,durableId,notices,ui.select)}acceptWorkerSecuritySnapshot(sessionId,snapshot){this.securityPresentations.acceptSnapshot(sessionId,snapshot)}routeWorkerGrant(sessionId,requestId,preferred,capabilities,cancel){return this.securityPresentations.routeWorkerGrant(sessionId,requestId,preferred,capabilities,cancel)}acceptWorkerGrantResponse(sessionId,id,connection){return this.securityPresentations.acceptWorkerResponse(sessionId,id,connection)}settleGrantDialog(sessionId,id){this.securityPresentations.settleGrant(sessionId,id)}hasRegisteredConnectionCapabilities(id){return this.fanout.hasRegisteredConnectionCapabilities(id)}getConnectionCapabilities(id){return this.fanout.getConnectionCapabilities(id)}setSessionMedia(sessionId,persister){persister===void 0?this.mediaPersisters.delete(sessionId):this.mediaPersisters.set(sessionId,persister)}setSessionKind(sessionId,kind){kind==="worker"?this.workerSessions.add(sessionId):this.workerSessions.delete(sessionId)}async flushConnection(id){let target=this.fanout.get(id);target&&await settleActors([target.actor])}withConnection(id,task){return this.connectionContext.run(id,task)}currentConnection(){return this.connectionContext.getStore()}enqueue(sessionId,value){if(this.sealedSessions.has(sessionId))return!1;let targetId=this.connectionContext.getStore(),record=normalizeJsonValue(value).value,isTargeted=record.type==="response"||record.type==="bash_execution_update"||record.type==="host_request"||record.type==="relocation_due"||record.type==="extension_ui_request"&&["select","confirm","input","editor"].includes(String(record.method)),tagged={...record,sessionId},line=serializeJsonLine(tagged);if(record.type==="snapshot_marker"||record.type==="ui_request_pending"||record.type==="ui_request_settled"){let targets2=record.type==="snapshot_marker"?this.status.mirrorTargets(sessionId,"snapshot_marker").filter(id=>id===targetId):this.status.dialogTargets(sessionId);for(let target of targets2)this.fanout.get(target)?.actor.enqueue(line);return targets2.length>0&&this.requestFlush(),!0}if(this.fanout.isEmpty()&&this.exceedsStdioCapacity(line))return this.closeSession(sessionId,{type:"response",command:"close_session",success:!1,error:"session_output_overflow, resync required"},"error"),!1;this.openTurns.note(sessionId,record.type);let attached=this.fanout.targets(sessionId,targetId,isTargeted,record.type),mirrors=isTargeted?[]:this.status.mirrorTargets(sessionId,String(record.type)),targets=mirrors.length===0?attached:[...new Set([...attached,...mirrors])],redacted=targets.some(target=>this.fanout.connectionHas(target,MEDIA_PLACEHOLDERS_CAPABILITY))?omitNormalInlineMedia(tagged,this.mediaPersisters.get(sessionId)):tagged,placeholderLine=redacted===tagged?void 0:serializeJsonLine(redacted);isTargeted||this.fanout.rememberSnapshot(sessionId,tagged,line,placeholderLine);for(let target of targets){if(target!==void 0&&!this.fanout.get(target))continue;let registered=target===void 0?void 0:this.fanout.get(target),wants=placeholderLine!==void 0&&this.fanout.connectionHas(target,MEDIA_PLACEHOLDERS_CAPABILITY);if(registered){let keyed=compactDelta(tagged)!==void 0&&tagged.message!==null;registered.actor.enqueue(wants?placeholderLine:line,keyed?MESSAGE_KEY:void 0,void 0,keyed?serializeJsonLine(demoteToDeltaOnly(tagged)):void 0,isCorrelatedReply(tagged))}else this.appendSessionRecord(sessionId,wants?redacted:tagged,target)}let cause=isTargeted?void 0:causeOfRecord(record);return cause!==void 0&&this.status.publish(sessionId,cause,this.changeActor("agent")),this.afterRecord?.(sessionId),this.requestFlush(),!0}changeActor(fallback){return this.connectionContext.getStore()===void 0?fallback:"client"}publishSessionOpened(record){if(this.fanout.isEmpty()){let{context:_context,...wire}=record;this.appendSessionRecord(record.sessionId,{...wire}),this.requestFlush();return}let lines=sessionOpenedLines(record),subscribers=this.status.matchingConnections(record.sessionId),recipients=record.kind==="worker"?new Set([...this.fanout.attachedConnections(record.sessionId),...subscribers.keys()]):new Set(this.fanout.connectionIds());for(let id of recipients)this.fanout.get(id)?.actor.enqueue(subscribers.get(id)===!0?lines.withContext:lines.plain);this.requestFlush()}publishLoadedSurfacesChanged(sessionId,previous,digest){if(this.fanout.isEmpty()){this.enqueue(sessionId,{type:"loaded_surfaces_changed"});return}if(this.sealedSessions.has(sessionId))return;let line=serializeJsonLine({type:"loaded_surfaces_changed",sessionId});for(let id of this.fanout.attachedConnections(sessionId))this.surfaceDedupe.announce(id,sessionId,previous,digest)&&this.fanout.get(id)?.actor.enqueue(line);this.requestFlush()}waitForSessionBackpressure(sessionId){return this.fanout.isEmpty()?this.flush():acceptActors(this.sessionActors(sessionId))}sessionActors(sessionId){return[...new Set([...this.fanout.targets(sessionId,this.currentConnection(),!1,void 0),this.currentConnection()])].flatMap(target=>{let registered=target===void 0?void 0:this.fanout.get(target);return registered?[registered.actor]:[]})}enqueueControl(value,targetOverride){if(this.failure!==void 0)return Promise.reject(this.failure);let targetId=targetOverride??this.connectionContext.getStore(),registered=targetId===void 0?void 0:this.fanout.get(targetId);if(registered)return registered.actor.enqueue(serializeJsonLine(value),void 0,void 0,void 0,isCorrelatedReply(value)),this.requestFlush(),Promise.resolve();if(this.exceedsStdioCapacity(serializeJsonLine(value)))return this.controlOverflowReported||(this.controlOverflowReported=!0,this.records.append(this.controlQueue,{type:"overflow",error:"rpc_control_output_overflow, resync required"}),this.markReady(this.controlQueue),this.requestFlush()),Promise.reject(new Error("rpc_control_output_overflow, resync required"));let queue=targetId===void 0?this.controlQueue:this.connectionQueue(targetId),completion=new Promise((resolve,reject)=>{this.records.append(queue,{...value},void 0,resolve,reject)});return this.markReady(queue),this.requestFlush(),completion}sendOpenQueued(connection,record){let wire={type:"queued",for_request:record.for_request,position:record.position,in_flight:record.in_flight},target=this.fanout.get(connection);target!==void 0&&(target.actor.enqueue(serializeJsonLine(wire)),this.requestFlush())}broadcastHostRecord(record){let wire;switch(record.type){case"host_superseded":wire={type:"host_superseded",instanceId:record.instanceId,generation:record.generation,successor:record.successor};break;case"host_stalled":wire={type:"host_stalled",driftMs:record.driftMs,...record.sessionId!==void 0?{sessionId:record.sessionId}:{},...record.tool!==void 0?{tool:record.tool}:{}};break;case"host_memory_pressure":wire={type:"host_memory_pressure",rssMb:record.rssMb,...record.footprintMb!==void 0?{footprintMb:record.footprintMb}:{},...record.measure!==void 0?{measure:record.measure}:{},sessions:record.sessions,...record.main!==void 0?{main:record.main}:{},...record.kernels!==void 0?{kernels:record.kernels}:{}};break;case"host_trimmed":wire={type:"host_trimmed",footprintBeforeMb:record.footprintBeforeMb,footprintAfterMb:record.footprintAfterMb,measure:record.measure,collected:record.collected,sessions:record.sessions,pauseMs:record.pauseMs};break;case"subscription_limits":wire={type:"subscription_limits",provider:record.provider,account:record.account,windows:record.windows,reportedAt:record.reportedAt,...record.plan===void 0?{}:{plan:record.plan},...record.error===void 0?{}:{error:record.error}};break;default:{let exhaustive=record;throw new Error(`unexpected host record ${exhaustive}`)}}this.fanout.isEmpty()?(this.records.append(this.controlQueue,wire),this.markReady(this.controlQueue)):this.fanout.broadcast(serializeJsonLine(wire)),this.requestFlush()}closeSession(sessionId,response,reason,sessionPath){if(this.presenterBindings.get(sessionId)?.dispose(),this.presenterBindings.delete(sessionId),!this.settleBeforeSeal(sessionId))return;this.sealedSessions.add(sessionId),this.securityPresentations.dropSession(sessionId),this.fanout.forgetSession(sessionId),this.mediaPersisters.delete(sessionId);let targetId=this.connectionContext.getStore(),lifecycle={type:"session_closed",sessionId,...reason&&{reason},...sessionPath&&{sessionPath}};this.fanout.isEmpty()?this.appendSessionRecord(sessionId,lifecycle):this.workerSessions.has(sessionId)?this.fanout.deliverToSession(sessionId,serializeJsonLine(lifecycle)):this.fanout.broadcast(serializeJsonLine(lifecycle)),this.sealStatus(sessionId,lifecycle);let taggedResponse={...response,sessionId},registered=targetId===void 0?void 0:this.fanout.get(targetId);registered?registered.actor.enqueue(serializeJsonLine(taggedResponse),void 0,void 0,void 0,isCorrelatedReply(response)):this.appendSessionRecord(sessionId,taggedResponse,targetId),this.requestFlush()}parkSession(sessionId,sessionPath,reason){this.sealLifecycle(sessionId,{type:"session_parked",sessionId,sessionPath,reason})}releaseSession(sessionId,sessionPath){this.sealLifecycle(sessionId,{type:"session_closed",sessionId,reason:"released",sessionPath})}sealRolledBackOpen(sessionId,sessionPath){this.sealLifecycle(sessionId,{type:"session_closed",sessionId,reason:"error",...sessionPath!==void 0&&{sessionPath}})}sealLifecycle(sessionId,lifecycle,attachedOnly=!1){this.presenterBindings.get(sessionId)?.dispose(),this.presenterBindings.delete(sessionId),this.settleBeforeSeal(sessionId)&&(this.sealedSessions.add(sessionId),this.securityPresentations.dropSession(sessionId),this.fanout.forgetSession(sessionId),this.mediaPersisters.delete(sessionId),this.fanout.isEmpty()?this.appendSessionRecord(sessionId,lifecycle):attachedOnly||this.workerSessions.has(sessionId)?this.fanout.deliverToSession(sessionId,serializeJsonLine(lifecycle)):this.fanout.broadcast(serializeJsonLine(lifecycle)),this.sealStatus(sessionId,lifecycle),this.requestFlush())}sealStatus(sessionId,lifecycle){let terminal=terminalOfLifecycle(lifecycle),cause=causeOfRecord(lifecycle);terminal!==void 0&&cause!==void 0&&this.status.seal(sessionId,terminal,cause,this.changeActor("host"))}reserveCloseResponse(sessionId,response,records=2){let bytes=Buffer.byteLength(serializeJsonLine({...response,sessionId}))+(records===2?Buffer.byteLength(serializeJsonLine({type:"session_closed",sessionId,reason:"client_close"})):0);if(this.bufferedRecordCount+this.reservedCloseRecords+records>MAX_SHARED_STDIO_QUEUE_RECORDS||this.bufferedByteLength+this.reservedCloseBytes+bytes>MAX_SHARED_STDIO_QUEUE_BYTES){let overflow={type:"overflow",command:"close_session",error:"rpc_close_output_overflow, resync required"},targetId=this.currentConnection();if(targetId!==void 0){let actor=this.fanout.get(targetId)?.actor;actor&&!this.closeOverflowActors.has(actor)&&(this.closeOverflowActors.add(actor),actor.enqueue(serializeJsonLine(overflow),void 0,()=>this.closeOverflowActors.delete(actor)))}else this.closeOverflowReported||(this.closeOverflowReported=!0,this.records.append(this.controlQueue,overflow),this.markReady(this.controlQueue),this.requestFlush());return}this.reservedCloseRecords+=records,this.reservedCloseBytes+=bytes;let active=!0,release=()=>{active&&(active=!1,this.reservedCloseRecords-=records,this.reservedCloseBytes-=bytes)};return{release,complete:(terminal,reason)=>{active&&(release(),terminal&&!this.sealedSessions.has(sessionId)?this.closeSession(sessionId,response,reason):this.appendClosedResponse(sessionId,response))}}}enqueueClosedResponse(sessionId,response){this.reserveCloseResponse(sessionId,response,1)?.complete(!1)}appendClosedResponse(sessionId,response){let targetId=this.connectionContext.getStore(),taggedResponse={...response,sessionId},registered=targetId===void 0?void 0:this.fanout.get(targetId);registered?registered.actor.enqueue(serializeJsonLine(taggedResponse),void 0,void 0,void 0,isCorrelatedReply(response)):this.appendSessionRecord(sessionId,taggedResponse,targetId),this.requestFlush()}settleBeforeSeal(sessionId){if(this.sealedSessions.has(sessionId))return!1;for(let owed=this.openTurns.take(sessionId);owed>0;owed-=1)this.enqueue(sessionId,{type:"agent_settled",reason:"session_closed"});return!this.sealedSessions.has(sessionId)}forgetSession(sessionId){this.sealedSessions.delete(sessionId),this.openTurns.take(sessionId),this.workerSessions.delete(sessionId),this.fanout.forgetSession(sessionId),this.mediaPersisters.delete(sessionId),this.status.forget(sessionId),this.surfaceDedupe.forgetSession(sessionId)}flush(){if(this.failure!==void 0)return Promise.reject(this.failure);if(this.flushScheduled=!1,this.drainPromise)return this.drainPromise;if(this.readyQueues.length===0)return settleActors([...this.fanout.values()].map(({actor})=>actor));let resolveDrain,rejectDrain,drain=new Promise((resolve,reject)=>{resolveDrain=resolve,rejectDrain=reject});return this.drainPromise=drain,this.drainUntilEmpty().then(resolveDrain,rejectDrain),drain.then(()=>{this.drainPromise===drain&&(this.drainPromise=void 0),this.readyQueues.length>0&&this.requestFlush()},cause=>{this.drainPromise===drain&&(this.drainPromise=void 0),this.fail(cause)}),drain}async drainUntilEmpty(){do await this.drainReadyQueues();while(this.readyQueues.length>0);await settleActors([...this.fanout.values()].map(({actor})=>actor)),this.controlOverflowReported=!1,this.reservedCloseRecords===0&&(this.closeOverflowReported=!1)}async drainReadyQueues(){for(;this.readyQueues.length>0;){let queue=this.readyQueues.shift();queue.ready=!1;let node=queue.head;if(node){this.records.unlink(queue,node),this.inFlight={queue,node};try{let connection=queue.targetId?this.fanout.get(queue.targetId)?.connection:void 0,writeRaw=connection?.writeRaw??this.writeRaw,waitForBackpressure=connection?.waitForBackpressure??this.waitForBackpressure;!connection&&queue.targetId||(writeRaw(node.line),waitForBackpressure&&await waitForBackpressure()),node.resolve?.()}catch(cause){throw node.reject?.(cause),cause}finally{this.inFlight=void 0}if(queue.head)this.markReady(queue);else if(queue.sessionId||queue.targetId)for(let[key,candidate]of this.queues)candidate===queue&&this.queues.delete(key)}}}exceedsStdioCapacity(line){return this.bufferedRecordCount+this.reservedCloseRecords>=MAX_SHARED_STDIO_QUEUE_RECORDS||this.bufferedByteLength+this.reservedCloseBytes+Buffer.byteLength(line)>MAX_SHARED_STDIO_QUEUE_BYTES}connectionQueue(targetId){let key=`connection:${targetId}`,queue=this.queues.get(key);return queue||(queue={targetId,latestByKey:new Map,ready:!1},this.queues.set(key,queue)),queue}appendSessionRecord(sessionId,value,targetId){let key=`${targetId??"default"}:${sessionId}`,queue=this.queues.get(key);if(queue||(queue={sessionId,targetId,latestByKey:new Map,ready:!1},this.queues.set(key,queue)),compactDelta(value)){let previousFull=queue.latestByKey.get(MESSAGE_KEY);previousFull&&this.demoteAndMerge(queue,previousFull);let node=this.records.append(queue,value,MESSAGE_KEY);queue.latestByKey.set(MESSAGE_KEY,node),this.markReady(queue);return}let toolKey=toolUpdateKey(value);if(toolKey){let previous=queue.latestByKey.get(toolKey);previous&&this.records.unlink(queue,previous);let node=this.records.append(queue,value,toolKey);queue.latestByKey.set(toolKey,node),this.markReady(queue);return}queue.latestByKey.clear(),this.records.append(queue,value),this.markReady(queue)}demoteAndMerge(queue,node){this.records.replace(node,demoteToDeltaOnly(node.value));let current=compactDelta(node.value),preceding=node.previous,previous=preceding?compactDelta(preceding.value):void 0;if(preceding&&previous&&current&&preceding.value.message===null&&previous.type===current.type&&previous.contentIndex===current.contentIndex){let precedingEvent=preceding.value.assistantMessageEvent;this.records.replace(preceding,{...preceding.value,assistantMessageEvent:{...precedingEvent,delta:previous.delta+current.delta}}),this.records.unlink(queue,node)}}markReady(queue){queue.ready||this.inFlight?.queue===queue||!queue.head||(queue.ready=!0,this.readyQueues.push(queue))}requestFlush(){this.failure!==void 0||this.flushScheduled||this.drainPromise||(this.flushScheduled=!0,this.scheduleFlush(()=>this.flush()))}fail(cause){if(this.failure===void 0){this.failure=cause;for(let queue of this.allQueues())for(let node=queue.head;node;node=node.next)node.reject?.(cause)}}*allQueues(){yield*this.queues.values(),yield this.controlQueue}};function socketSink(socket){let needsDrain=!1,cut=!1;return{writeRaw(chunk){!cut&&!socket.destroyed&&(needsDrain=!socket.write(chunk))},close(){if(cut||(cut=!0,socket.destroyed))return;socket.end();let grace=setTimeout(()=>socket.destroy(),5e3);grace.unref(),socket.once("close",()=>clearTimeout(grace))},waitForBackpressure(){return socket.destroyed||!needsDrain?Promise.resolve():(needsDrain=!1,new Promise(resolve=>{let done=()=>{socket.off("drain",done),socket.off("close",done),resolve()};socket.once("drain",done),socket.once("close",done)}))}}}var SESSION_CONTEXT_PATCH_LIMITS={keyPattern:/^[a-z][a-z0-9_]{0,63}$/,valueChars:256,overlayBytes:4096},RESERVED_SESSION_CONTEXT_KEYS=new Set(["host_socket","host_instance","shard_key","tree_key","parent_session_id","root_session_id"]);function refuse(reason,action){return{refusal:{reason,action}}}function applyContextPatch(overlay,patch){let shape='send patch as an object of lowercase keys to string, number, boolean or null values, e.g. { "task_status": "running" }';if(typeof patch!="object"||patch===null||Array.isArray(patch))return refuse("patch must be an object",shape);let entries=Object.entries(patch);if(entries.length===0)return refuse("patch has no keys",shape);let merged={...overlay};for(let[key,value]of entries){if(!SESSION_CONTEXT_PATCH_LIMITS.keyPattern.test(key))return refuse(`key "${key}" must match ${SESSION_CONTEXT_PATCH_LIMITS.keyPattern.source}`,"rename the key to lowercase letters, digits and underscores");if(RESERVED_SESSION_CONTEXT_KEYS.has(key))return refuse(`key "${key}" is set by the host and cannot be patched`,"drop that key from the patch; the host keeps it current");if(typeof value=="string"&&value.length>SESSION_CONTEXT_PATCH_LIMITS.valueChars)return refuse(`value for "${key}" is ${value.length} characters, at most ${SESSION_CONTEXT_PATCH_LIMITS.valueChars} are accepted`,"shorten the value or store it elsewhere and publish a reference");if(typeof value=="number"&&!Number.isFinite(value))return refuse(`value for "${key}" must be a finite number`,shape);if(value!==null&&typeof value!="string"&&typeof value!="number"&&typeof value!="boolean")return refuse(`value for "${key}" must be a string, number, boolean or null`,shape);merged[key]=value}let bytes=Buffer.byteLength(JSON.stringify(merged));return bytes>SESSION_CONTEXT_PATCH_LIMITS.overlayBytes?refuse(`patched context would be ${bytes} bytes, at most ${SESSION_CONTEXT_PATCH_LIMITS.overlayBytes} are accepted`,"remove keys with null or shorten values before adding more"):{overlay:merged}}function publishedSessionContext(base,overlay){if(overlay===void 0)return base;let published={...base};for(let[key,value]of Object.entries(overlay))value===null?delete published[key]:published[key]=value;return published}function modelOf(model){return model===void 0?void 0:{provider:model.provider,id:model.id}}function sessionRuntimeView(session,pendingQuestions){let model=modelOf(session.model);return{isStreaming:session.isStreaming===!0,isCompacting:session.isCompacting===!0,...model!==void 0?{model}:{},...session.thinkingLevel!==void 0?{thinkingLevel:session.thinkingLevel}:{},steering:typeof session.getSteeringMessages=="function"?session.getSteeringMessages().length:0,followUp:typeof session.getFollowUpMessages=="function"?session.getFollowUpMessages().length:0,pendingQuestions:pendingQuestions??sessionQuestionBridges.get(session)?.pendingQuestions()?.length??0}}function runtimeView(entry){let session=entry.runtime?.session;if(session!==void 0)return sessionRuntimeView(session);let state=entry.worker?.snapshot?.state;if(state===void 0)return;let model=modelOf(state.model??void 0);return{isStreaming:state.isStreaming,isCompacting:state.isCompacting,...model!==void 0?{model}:{},...state.thinkingLevel!==void 0?{thinkingLevel:state.thinkingLevel}:{},steering:state.steering.length,followUp:state.followUp.length,pendingQuestions:state.pendingQuestions?.length??0}}function entryView(entry){let session=entry.runtime?.session,state=entry.worker?.snapshot?.state,durableSessionId=session?.sessionId??state?.sessionId??entry.durableSessionId,sessionPath=session?.sessionFile??state?.sessionFile??entry.sessionPath,name=session?.sessionManager.getSessionName()??state?.sessionName;return{state:entry.state,kind:entry.kind,cwd:entry.cwd,attachments:entry.attachments,...durableSessionId!==void 0?{durableSessionId}:{},...sessionPath!==void 0?{sessionPath}:{},...name!==void 0?{name}:{},context:publishedSessionContext(entry.context,entry.contextOverlay),openContext:entry.context}}function registryStatusSource(registry){return{sessionIds:()=>registry.list().map(row=>row.sessionId),entryView:sessionId=>{let entry=registry.peek(sessionId);return entry===void 0?void 0:entryView(entry)},view:sessionId=>{let entry=registry.peek(sessionId);if(entry===void 0)return;let runtime=runtimeView(entry);return runtime===void 0?{entry:entryView(entry)}:{entry:entryView(entry),runtime}}}}function refusal2(id,command,code,detail){return{id,type:"response",command,success:!1,error:`${code}: ${detail.reason}`,errorCode:code,errorData:{reason:detail.reason,action:detail.action}}}function answerSubscribeSessions(command,connectionId,stream){if(connectionId===void 0)return{answer:refusal2(command.id,command.type,RPC_ERROR_UNSUPPORTED_TRANSPORT,{reason:"stdio has no per-connection identity to deliver a subscription to",action:"connect to the host socket (senpi --mode rpc --listen) and subscribe there"})};if(stream.connectionSize(connectionId)>=MAX_SUBSCRIPTIONS_PER_CONNECTION)return{answer:refusal2(command.id,command.type,RPC_ERROR_SUBSCRIPTION_LIMIT,{reason:`this connection already holds ${MAX_SUBSCRIPTIONS_PER_CONNECTION} subscriptions`,action:"unsubscribe_sessions the ones you no longer read, then subscribe again"})};let parsed=parseSubscription(command);if("refusal"in parsed)return{answer:refusal2(command.id,command.type,RPC_ERROR_INVALID_SUBSCRIPTION,parsed.refusal)};let subscribed=stream.subscribe(connectionId,parsed.options);return{answer:{id:command.id,type:"response",command:"subscribe_sessions",success:!0,data:{subscriptionId:subscribed.subscriptionId,snapshot:subscribed.snapshot,seq:subscribed.seq,hostGeneration:String(hostGeneration(process.env)),hostInstanceId:hostInstanceId()}},activate:subscribed.subscriptionId}}function answerUnsubscribeSessions(command,connectionId,stream){return connectionId===void 0?refusal2(command.id,command.type,RPC_ERROR_UNSUPPORTED_TRANSPORT,{reason:"stdio has no per-connection identity holding any subscription",action:"connect to the host socket (senpi --mode rpc --listen) and manage subscriptions there"}):typeof command.subscriptionId=="string"&&stream.unsubscribe(connectionId,command.subscriptionId)?{id:command.id,type:"response",command:"unsubscribe_sessions",success:!0}:refusal2(command.id,command.type,RPC_ERROR_UNKNOWN_SUBSCRIPTION,{reason:"this connection holds no subscription with that id",action:"send the subscriptionId your subscribe_sessions answer returned, on the same connection"})}function notAttachedRefusal(command){return refusal2(command.id,command.type,RPC_ERROR_SESSION_NOT_ATTACHED,{reason:"this connection is not attached to that session",action:"attach first with open_session { sessionPath }, then patch its context"})}function answerSetSessionContext(command,entry,stream){let applied=applyContextPatch(entry.contextOverlay,command.patch);return"refusal"in applied?refusal2(command.id,command.type,RPC_ERROR_INVALID_SESSION_CONTEXT,applied.refusal):(entry.contextOverlay=applied.overlay,stream.publish(command.sessionId,"context","client",!0),{id:command.id,type:"response",command:"set_session_context",success:!0,data:{context:publishedSessionContext(entry.context,entry.contextOverlay)}})}export{applyContextPatch,publishedSessionContext,recordLoopBlockedMs,sessionRuntimeView,registryStatusSource,refusal2 as refusal,answerSubscribeSessions,answerUnsubscribeSessions,notAttachedRefusal,answerSetSessionContext,SessionEventWriter,socketSink};
@@ -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
- var presentations=new WeakMap;function registerMcpMrtrPresentation(ui,signal,admit,privateForms){return presentations.set(ui,{ui,signal,admit,privateForms}),ui}function getMcpMrtrPresentation(ui){let presentation=presentations.get(ui);return presentation?.signal.aborted?void 0:presentation}function inheritMcpMrtrPresentation(source,wrapper){let presentation=getMcpMrtrPresentation(source);return presentation&&presentations.set(wrapper,presentation),wrapper}var presentedCallbacks=new WeakMap;function bindMcpFormPresented(options,callback){callback?presentedCallbacks.set(options,callback):presentedCallbacks.delete(options)}function markMcpFormPresented(options){if(!options)return;let callback=presentedCallbacks.get(options);presentedCallbacks.delete(options),callback?.()}function bindPrivateMcpForms(ui,binding){registerMcpMrtrPresentation(ui,binding.signal,void 0,binding)}function privateMcpForms(ui){return getMcpMrtrPresentation(ui)?.privateForms}var messages={MCP_MRTR_ROUND_LIMIT:"Request stopped after 8 input rounds; start a new request to continue.",MCP_MRTR_INPUT_LIMIT:"Server input exceeds the client's supported limits.",MCP_MRTR_INVALID_INPUT:"Server returned an invalid input request or form schema.",MCP_MRTR_UNSUPPORTED_INPUT:"Server requested an undeclared client feature.",MCP_MRTR_PROCESSING_UNAVAILABLE:"Elicitation processing unavailable.",MCP_MRTR_INVALID_RESULT:"Server returned an unsupported or invalid result type/shape.",MCP_MRTR_CONTEXT_CHANGED:"Request stopped because its session or server authorization changed.",MCP_MRTR_CANCELLED:"Request was canceled before completion.",MCP_MRTR_TIMEOUT:"Request exceeded its operation deadline.",MCP_MRTR_TRANSPORT_FAILED:"Request could not complete; it was not automatically replayed."},McpMrtrError=class extends Error{constructor(code,remoteCode){super(remoteCode===void 0?messages[code]:`${messages[code]} (remote code ${remoteCode})`),this.source="local",this.retriable=!1,this.code=code,this.remoteCode=remoteCode,this.name="McpMrtrError"}};var isRecord=value=>typeof value=="object"&&value!==null&&!Array.isArray(value),own=(value,key)=>Object.hasOwn(value,key);function enums(property){if(Array.isArray(property.enum)&&property.enum.length>0&&property.enum.every(entry=>typeof entry=="string"))return property.enum.map(value=>({value,label:value}));let choices=property.oneOf??property.anyOf;if(Array.isArray(choices)&&choices.length>0&&choices.every(entry=>isRecord(entry)&&typeof entry.const=="string"&&typeof entry.title=="string"&&Object.keys(entry).every(key=>key==="const"||key==="title")))return choices.map(entry=>({value:entry.const,label:entry.title}))}function validValue(property,value){if(property.type==="boolean")return typeof value=="boolean";if(property.type==="integer"||property.type==="number")return typeof value=="number"&&Number.isFinite(value)&&(property.type!=="integer"||Number.isInteger(value))&&(typeof property.minimum!="number"||value>=property.minimum)&&(typeof property.maximum!="number"||value<=property.maximum);if(property.type==="array"){let choices2=isRecord(property.items)?enums(property.items):void 0;return Array.isArray(value)&&value.every(entry=>typeof entry=="string"&&choices2?.some(choice=>choice.value===entry))&&new Set(value).size===value.length&&(typeof property.minItems!="number"||value.length>=property.minItems)&&(typeof property.maxItems!="number"||value.length<=property.maxItems)}if(typeof value!="string")return!1;let choices=enums(property);if(choices&&!choices.some(choice=>choice.value===value)||typeof property.minLength=="number"&&[...value].length<property.minLength||typeof property.maxLength=="number"&&[...value].length>property.maxLength)return!1;switch(property.format){case"email":return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);case"uri":try{return new URL(value).protocol.length>1}catch{return!1}case"date":return/^\d{4}-\d{2}-\d{2}$/.test(value)&&Number.isFinite(Date.parse(value))&&new Date(value).toISOString().slice(0,10)===value;case"date-time":{let date=value.slice(0,10);return/^\d{4}-\d{2}-\d{2}T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(value)&&Number.isFinite(Date.parse(value))&&new Date(date).toISOString().slice(0,10)===date}default:return!0}}function validMcpFormContent(schema,content){return isRecord(content)&&(schema.required??[]).every(key=>own(content,key))&&Object.entries(content).every(([key,value])=>own(schema.properties,key)&&validValue(schema.properties[key],value))}function validateMrtrForm(schema){if(!isRecord(schema)||schema.type!=="object"||!isRecord(schema.properties))return!1;for(let key of["title","description"])if(own(schema,key)&&typeof schema[key]!="string")return!1;if(Object.keys(schema).some(key=>!["type","properties","required","title","description","$schema"].includes(key))||schema.required!==void 0&&(!Array.isArray(schema.required)||!schema.required.every(key=>typeof key=="string"&&own(schema.properties,key))))return!1;for(let property of Object.values(schema.properties)){if(!isRecord(property))return!1;let allowed=["type","title","description","default"];switch(property.type){case"string":if(allowed.push("minLength","maxLength","format","enum","oneOf"),property.format!==void 0&&!["email","uri","date","date-time"].includes(String(property.format))||(own(property,"enum")||own(property,"oneOf"))&&!enums(property)||own(property,"enum")&&own(property,"oneOf"))return!1;break;case"number":case"integer":allowed.push("minimum","maximum");break;case"boolean":break;case"array":if(allowed.push("items","minItems","maxItems"),!isRecord(property.items)||!enums(property.items)||Object.keys(property.items).some(key=>!["type","enum","anyOf"].includes(key))||property.items.type!==void 0&&property.items.type!=="string")return!1;break;default:return!1}if(Object.keys(property).some(key=>!allowed.includes(key)))return!1;for(let key of["title","description"])if(own(property,key)&&typeof property[key]!="string")return!1;for(let key of["minimum","maximum","minLength","maxLength","minItems","maxItems"]){let value=property[key];if(value!==void 0&&(typeof value!="number"||!Number.isFinite(value)||!["minimum","maximum"].includes(key)&&(!Number.isInteger(value)||value<0)))return!1}for(let[min,max]of[["minimum","maximum"],["minLength","maxLength"],["minItems","maxItems"]])if(min&&max&&typeof property[min]=="number"&&typeof property[max]=="number"&&property[min]>property[max])return!1;if(own(property,"default")&&!validValue(property,property.default))return!1}return!0}var queues=new WeakMap;function queuedForm(binding,signal,run){let queue=queues.get(binding);queue||(queue={busy:!1,jobs:[]},queues.set(binding,queue));let current=queue,pump=()=>{if(current.busy)return;let next=current.jobs.shift();if(!next){queues.delete(binding);return}if(next.signal.removeEventListener("abort",next.abort),next.signal.aborted){next.reject(new McpMrtrError("MCP_MRTR_PROCESSING_UNAVAILABLE")),pump();return}current.busy=!0,next.run().finally(()=>{current.busy=!1,pump()})};return new Promise((resolve,reject)=>{let job={signal,run:async()=>{try{resolve(await run())}catch(error){reject(error)}},reject,abort:()=>{}};job.abort=()=>{let index=current.jobs.indexOf(job);index>=0&&(current.jobs.splice(index,1),signal.removeEventListener("abort",job.abort),reject(new McpMrtrError("MCP_MRTR_PROCESSING_UNAVAILABLE")))},current.jobs.push(job),signal.addEventListener("abort",job.abort,{once:!0}),signal.aborted&&job.abort(),pump()})}export{registerMcpMrtrPresentation,getMcpMrtrPresentation,inheritMcpMrtrPresentation,McpMrtrError,bindMcpFormPresented,markMcpFormPresented,bindPrivateMcpForms,privateMcpForms,isRecord,enums,validValue,validMcpFormContent,validateMrtrForm,queuedForm};
2
+ var presentations=new WeakMap;function registerMcpMrtrPresentation(ui,signal,admit,privateForms){return presentations.set(ui,{ui,signal,admit,privateForms}),ui}function getMcpMrtrPresentation(ui){let presentation=presentations.get(ui);return presentation?.signal.aborted?void 0:presentation}function inheritMcpMrtrPresentation(source,wrapper){let presentation=getMcpMrtrPresentation(source);return presentation&&presentations.set(wrapper,presentation),wrapper}var presentedCallbacks=new WeakMap;function bindMcpFormPresented(options,callback){callback?presentedCallbacks.set(options,callback):presentedCallbacks.delete(options)}function markMcpFormPresented(options){if(!options)return;let callback=presentedCallbacks.get(options);presentedCallbacks.delete(options),callback?.()}function bindPrivateMcpForms(ui,binding){registerMcpMrtrPresentation(ui,binding.signal,void 0,binding)}function privateMcpForms(ui){return getMcpMrtrPresentation(ui)?.privateForms}var messages={MCP_MRTR_ROUND_LIMIT:"Request stopped after 8 input rounds; start a new request to continue.",MCP_MRTR_INPUT_LIMIT:"Server input exceeds the client's supported limits.",MCP_MRTR_INVALID_INPUT:"Server returned an invalid input request or form schema.",MCP_MRTR_UNSUPPORTED_INPUT:"Server requested an undeclared client feature.",MCP_MRTR_PROCESSING_UNAVAILABLE:"Elicitation processing unavailable.",MCP_MRTR_INVALID_RESULT:"Server returned an unsupported or invalid result type/shape.",MCP_MRTR_CONTEXT_CHANGED:"Request stopped because its session or server authorization changed.",MCP_MRTR_CANCELLED:"Request was canceled before completion.",MCP_MRTR_TIMEOUT:"Request exceeded its operation deadline.",MCP_MRTR_TRANSPORT_FAILED:"Request could not complete; it was not automatically replayed."},McpMrtrError=class extends Error{constructor(code,remoteCode){super(remoteCode===void 0?messages[code]:`${messages[code]} (remote code ${remoteCode})`),this.source="local",this.retriable=!1,this.code=code,this.remoteCode=remoteCode,this.name="McpMrtrError"}};var isRecord=value=>typeof value=="object"&&value!==null&&!Array.isArray(value),own=(value,key)=>Object.hasOwn(value,key);function enums(property){if(Array.isArray(property.enum)&&property.enum.length>0&&property.enum.every(entry=>typeof entry=="string"))return property.enum.map(value=>({value,label:value}));let choices=property.oneOf??property.anyOf;if(Array.isArray(choices)&&choices.length>0&&choices.every(entry=>isRecord(entry)&&typeof entry.const=="string"&&typeof entry.title=="string"&&Object.keys(entry).every(key=>key==="const"||key==="title")))return choices.map(entry=>({value:entry.const,label:entry.title}))}function validValue(property,value){if(property.type==="boolean")return typeof value=="boolean";if(property.type==="integer"||property.type==="number")return typeof value=="number"&&Number.isFinite(value)&&(property.type!=="integer"||Number.isInteger(value))&&(typeof property.minimum!="number"||value>=property.minimum)&&(typeof property.maximum!="number"||value<=property.maximum);if(property.type==="array"){let choices2=isRecord(property.items)?enums(property.items):void 0;return Array.isArray(value)&&value.every(entry=>typeof entry=="string"&&choices2?.some(choice=>choice.value===entry))&&new Set(value).size===value.length&&(typeof property.minItems!="number"||value.length>=property.minItems)&&(typeof property.maxItems!="number"||value.length<=property.maxItems)}if(typeof value!="string")return!1;let choices=enums(property);if(choices&&!choices.some(choice=>choice.value===value)||typeof property.minLength=="number"&&[...value].length<property.minLength||typeof property.maxLength=="number"&&[...value].length>property.maxLength)return!1;switch(property.format){case"email":return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);case"uri":try{return new URL(value).protocol.length>1}catch{return!1}case"date":return/^\d{4}-\d{2}-\d{2}$/.test(value)&&Number.isFinite(Date.parse(value))&&new Date(value).toISOString().slice(0,10)===value;case"date-time":{let date=value.slice(0,10);return/^\d{4}-\d{2}-\d{2}T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(value)&&Number.isFinite(Date.parse(value))&&new Date(date).toISOString().slice(0,10)===date}default:return!0}}function validMcpFormContent(schema,content){return isRecord(content)&&(schema.required??[]).every(key=>own(content,key))&&Object.entries(content).every(([key,value])=>own(schema.properties,key)&&validValue(schema.properties[key],value))}function validateMrtrForm(schema){if(!isRecord(schema)||schema.type!=="object"||!isRecord(schema.properties))return!1;for(let key of["title","description"])if(own(schema,key)&&typeof schema[key]!="string")return!1;if(Object.keys(schema).some(key=>!["type","properties","required","title","description","$schema"].includes(key))||schema.required!==void 0&&(!Array.isArray(schema.required)||!schema.required.every(key=>typeof key=="string"&&own(schema.properties,key))))return!1;for(let property of Object.values(schema.properties)){if(!isRecord(property))return!1;let allowed=["type","title","description","default"];switch(property.type){case"string":if(allowed.push("minLength","maxLength","format","enum","oneOf"),property.format!==void 0&&!["email","uri","date","date-time"].includes(String(property.format))||(own(property,"enum")||own(property,"oneOf"))&&!enums(property)||own(property,"enum")&&own(property,"oneOf"))return!1;break;case"number":case"integer":allowed.push("minimum","maximum");break;case"boolean":break;case"array":if(allowed.push("items","minItems","maxItems"),!isRecord(property.items)||!enums(property.items)||Object.keys(property.items).some(key=>!["type","enum","anyOf"].includes(key))||property.items.type!==void 0&&property.items.type!=="string")return!1;break;default:return!1}if(Object.keys(property).some(key=>!allowed.includes(key)))return!1;for(let key of["title","description"])if(own(property,key)&&typeof property[key]!="string")return!1;for(let key of["minimum","maximum","minLength","maxLength","minItems","maxItems"]){let value=property[key];if(value!==void 0&&(typeof value!="number"||!Number.isFinite(value)||!["minimum","maximum"].includes(key)&&(!Number.isInteger(value)||value<0)))return!1}for(let[min,max]of[["minimum","maximum"],["minLength","maxLength"],["minItems","maxItems"]])if(min&&max&&typeof property[min]=="number"&&typeof property[max]=="number"&&property[min]>property[max])return!1;if(own(property,"default")&&!validValue(property,property.default))return!1}return!0}var queues=new WeakMap;function queuedForm(binding,signal,run){let queue=queues.get(binding);queue||(queue={busy:!1,jobs:[]},queues.set(binding,queue));let current=queue,pump=()=>{if(current.busy)return;let next=current.jobs.shift();if(!next){queues.delete(binding);return}if(next.signal.removeEventListener("abort",next.abort),next.signal.aborted){next.reject(new McpMrtrError("MCP_MRTR_PROCESSING_UNAVAILABLE")),pump();return}current.busy=!0,next.run().finally(()=>{current.busy=!1,pump()})};return new Promise((resolve,reject)=>{let job={signal,run:async()=>{try{resolve(await run())}catch(error){reject(error)}},reject,abort:()=>{}};job.abort=()=>{let index=current.jobs.indexOf(job);index>=0&&(current.jobs.splice(index,1),signal.removeEventListener("abort",job.abort),reject(new McpMrtrError("MCP_MRTR_PROCESSING_UNAVAILABLE")),pump())},current.jobs.push(job),signal.addEventListener("abort",job.abort,{once:!0}),signal.aborted&&job.abort(),pump()})}export{registerMcpMrtrPresentation,getMcpMrtrPresentation,inheritMcpMrtrPresentation,McpMrtrError,bindMcpFormPresented,markMcpFormPresented,bindPrivateMcpForms,privateMcpForms,isRecord,enums,validValue,validMcpFormContent,validateMrtrForm,queuedForm};