@code-yeongyu/senpi 2026.10.25-4 → 2026.10.26-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.
- package/CHANGELOG.md +23 -0
- package/dist/bundle/chunks/{anthropic-messages-WBASBTIW.js → anthropic-messages-M235FJQV.js} +3 -3
- package/dist/bundle/chunks/{args-B444OQBK.js → args-FBNJOJSR.js} +1 -1
- package/dist/bundle/chunks/azure-openai-responses-YQRTQ7H6.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +3 -3
- package/dist/bundle/chunks/{chunk-4MOZXOJX.js → chunk-3A3XCLNH.js} +1 -1
- package/dist/bundle/chunks/{chunk-E6D4RIT7.js → chunk-3LPWILUZ.js} +2 -2
- package/dist/bundle/chunks/{chunk-3BTN337S.js → chunk-3WP5RFQR.js} +1 -1
- package/dist/bundle/chunks/{chunk-2RB5EL4X.js → chunk-5FQMNHXV.js} +1 -1
- package/dist/bundle/chunks/{chunk-STMXIBXF.js → chunk-5KZH6EYQ.js} +1 -1
- package/dist/bundle/chunks/{chunk-4P7WARQZ.js → chunk-5LWUUXMH.js} +1 -1
- package/dist/bundle/chunks/{chunk-5JJDR6XI.js → chunk-6U3TBFBA.js} +1 -1
- package/dist/bundle/chunks/{chunk-BWA4FVFW.js → chunk-7KOUQSBX.js} +2 -2
- package/dist/bundle/chunks/{chunk-7CNOCJCN.js → chunk-ADQAPDPV.js} +1 -1
- package/dist/bundle/chunks/{chunk-ITGYN22E.js → chunk-CDQPA4FP.js} +1 -1
- package/dist/bundle/chunks/{chunk-WDPQ6CZJ.js → chunk-DMFAVE5N.js} +1 -1
- package/dist/bundle/chunks/{chunk-XF3LJC3O.js → chunk-DYWIFF2Q.js} +1 -1
- package/dist/bundle/chunks/{chunk-C2MQ4QXN.js → chunk-EZP6AYW2.js} +35 -29
- package/dist/bundle/chunks/chunk-GQJYNFMO.js +2 -0
- package/dist/bundle/chunks/{chunk-SBGIXMX3.js → chunk-GWGNVYPB.js} +1 -1
- package/dist/bundle/chunks/{chunk-KKD4CYCI.js → chunk-H4WJ4LY3.js} +1 -1
- package/dist/bundle/chunks/{chunk-V2UYXTRR.js → chunk-HWTD4QF3.js} +1 -1
- package/dist/bundle/chunks/{chunk-WD6WBYC5.js → chunk-I7QWTWVZ.js} +1 -1
- package/dist/bundle/chunks/{chunk-BZ7726QO.js → chunk-J2YAYTB2.js} +1 -1
- package/dist/bundle/chunks/{chunk-TTU2RNVX.js → chunk-J5FCH7TI.js} +1 -1
- package/dist/bundle/chunks/chunk-JFQUWEN7.js +13 -0
- package/dist/bundle/chunks/{chunk-KNVNKDER.js → chunk-L2O6K3SJ.js} +1 -1
- package/dist/bundle/chunks/{chunk-4AOMNOGY.js → chunk-LO5MYLGF.js} +1 -1
- package/dist/bundle/chunks/{chunk-N7IN46Q5.js → chunk-MSHRIZGT.js} +8 -6
- package/dist/bundle/chunks/{chunk-T36LJ6MW.js → chunk-MY4ZD3EW.js} +1 -1
- package/dist/bundle/chunks/{chunk-UFJ2K7Q7.js → chunk-OQ3WDMB3.js} +1 -1
- package/dist/bundle/chunks/{chunk-7GZUFOM3.js → chunk-PH3JDRB2.js} +1 -1
- package/dist/bundle/chunks/{chunk-E6WYH3ZL.js → chunk-QREKAXKX.js} +7 -5
- package/dist/bundle/chunks/{chunk-3QCYBOKN.js → chunk-QYFOHFPS.js} +1 -1
- package/dist/bundle/chunks/{chunk-JMOUU75H.js → chunk-SOXQ42VS.js} +1 -1
- package/dist/bundle/chunks/{chunk-FHXR4ZAC.js → chunk-UDM7VO6O.js} +1 -1
- package/dist/bundle/chunks/{chunk-OLCDIITS.js → chunk-UW6M3EXY.js} +1 -1
- package/dist/bundle/chunks/chunk-VICDRG3J.js +410 -0
- package/dist/bundle/chunks/chunk-VL7O5PO4.js +5 -0
- package/dist/bundle/chunks/{chunk-PT6JJUN2.js → chunk-XMNPK472.js} +1 -1
- package/dist/bundle/chunks/{chunk-GSSD3R5X.js → chunk-XQ45JMGN.js} +1 -1
- package/dist/bundle/chunks/{client-WTYEICLH.js → chunk-Y3TMJV3J.js} +3 -3
- package/dist/bundle/chunks/{chunk-KXB5WIS5.js → chunk-Z6SAQ5O3.js} +1 -1
- package/dist/bundle/chunks/{chunk-LOIF6PHI.js → chunk-ZAUVY6ZC.js} +3 -3
- package/dist/bundle/chunks/{chunk-E4LBKOZG.js → chunk-ZLIVZQDY.js} +4 -4
- package/dist/bundle/chunks/{chunk-6AOVUTUR.js → chunk-ZXHLH4MW.js} +2 -2
- package/dist/bundle/chunks/cli-main-55EQA5PS.js +3 -0
- package/dist/bundle/chunks/client-LOS6GSEW.js +2 -0
- package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-K5H6BJP3.js → cloudflare-workers-ai-system-one-ZJQGIIRC.js} +1 -1
- package/dist/bundle/chunks/cursor-agent.js +3 -3
- package/dist/bundle/chunks/devin-agent.js +3 -3
- package/dist/bundle/chunks/dispatch-C2IBP5VV.js +9 -0
- package/dist/bundle/chunks/google-generative-ai-5G4RIQA6.js +2 -0
- package/dist/bundle/chunks/google-vertex-ALD4P27O.js +2 -0
- package/dist/bundle/chunks/{help-fast-path-3Z26DQSV.js → help-fast-path-PEIKGCKZ.js} +1 -1
- package/dist/bundle/chunks/host-command-657VCQ34.js +2 -0
- package/dist/bundle/chunks/{host-lifecycle-3VHHIGDL.js → host-lifecycle-HX3EGRRW.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle.js +2 -2
- package/dist/bundle/chunks/{host-session-command-56XF6ACS.js → host-session-command-OV5XDOJK.js} +1 -1
- package/dist/bundle/chunks/{host-socket-request-QL2WEZTN.js → host-socket-request-K4LCUOUD.js} +1 -1
- package/dist/bundle/chunks/interactive-mode-MLXSYK2H.js +2 -0
- package/dist/bundle/chunks/{mcp-presenter-bootstrap-XUSCQVRC.js → mcp-presenter-bootstrap-FOMKF4TU.js} +1 -1
- package/dist/bundle/chunks/{mistral-conversations-DH44NOYV.js → mistral-conversations-RAE4K2XY.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-Z2CW4SDM.js → multi-session-host-774MACJU.js} +5 -6
- package/dist/bundle/chunks/{openai-codex-responses-SERAFKAS.js → openai-codex-responses-3CW4R7TG.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-BZB5O45A.js → openai-completions-5UIJXQUF.js} +1 -1
- package/dist/bundle/chunks/openai-responses-2BO44MRW.js +3 -0
- package/dist/bundle/chunks/{package-manager-cli-N55U6PEO.js → package-manager-cli-MZHVCX2S.js} +1 -1
- package/dist/bundle/chunks/{pi-messages-VXATX45B.js → pi-messages-RF6GER4R.js} +2 -2
- package/dist/bundle/chunks/{role-JVSBNKGE.js → role-ETSFSDTS.js} +1 -1
- package/dist/bundle/chunks/{rotation-stream-CBGCBYHV.js → rotation-stream-ZMQB4GPO.js} +1 -1
- package/dist/bundle/chunks/rpc-mode-UJXOIZCW.js +2 -0
- package/dist/bundle/chunks/{rpc-monitor-source-AE3C6EQV.js → rpc-monitor-source-DRZXJHTL.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-VS7CZC2J.js → schedule-command-KA7LFFNK.js} +1 -1
- package/dist/bundle/chunks/session-control-endpoint-MFWXUR7Z.js +3 -0
- package/dist/bundle/chunks/{session-picker-E4KUJDLO.js → session-picker-BP33NRSL.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +199 -190
- package/dist/bundle/chunks/{typesafe-system-one-P75WJ767.js → typesafe-system-one-GNNZ5O5U.js} +1 -1
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/host-supervisor.js +2 -2
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/cli/host-command-args.d.ts +1 -0
- package/dist/cli/host-command-args.js +5 -0
- package/dist/cli/host-command.js +7 -1
- package/dist/cli.js +21 -3
- package/dist/core/extensions/builtin/mcp/catalog-cache.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/catalog-cache.js +19 -6
- package/dist/core/extensions/builtin/mcp/catalog.d.ts +3 -2
- package/dist/core/extensions/builtin/mcp/catalog.js +20 -3
- package/dist/core/extensions/builtin/mcp/expose/call.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/expose/call.js +2 -1
- package/dist/core/extensions/builtin/mcp/expose/register.js +1 -1
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.d.ts +2 -2
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.js +11 -1
- package/dist/core/extensions/builtin/mcp/invocation.js +16 -2
- package/dist/core/extensions/builtin/mcp/modern/request.d.ts +1 -1
- package/dist/core/extensions/builtin/mcp/modern/request.js +1 -1
- package/dist/core/extensions/builtin/mcp/modern/sdk-bridge.js +18 -3
- package/dist/core/extensions/builtin/mcp/modern/stdio-probe.js +23 -0
- package/dist/core/extensions/builtin/mcp/modern/subscriptions.d.ts +14 -0
- package/dist/core/extensions/builtin/mcp/modern/subscriptions.js +226 -0
- package/dist/core/extensions/builtin/mcp/modern/tool-schema.d.ts +13 -0
- package/dist/core/extensions/builtin/mcp/modern/tool-schema.js +75 -0
- package/dist/core/extensions/builtin/mcp/modern/tools.d.ts +107 -0
- package/dist/core/extensions/builtin/mcp/modern/tools.js +53 -0
- package/dist/core/extensions/builtin/mcp/resources.js +4 -0
- package/dist/core/extensions/builtin/mcp/tool-client.d.ts +13 -0
- package/dist/core/extensions/builtin/mcp/tool-client.js +17 -0
- package/dist/core/extensions/builtin/mcp/tool-contracts.d.ts +19 -0
- package/dist/core/extensions/builtin/mcp/tool-contracts.js +2 -0
- package/dist/core/extensions/builtin/mcp/wrap.js +2 -2
- package/dist/core/extensions/builtin/permission-system/bash-command-segments.d.ts +37 -0
- package/dist/core/extensions/builtin/permission-system/bash-command-segments.js +899 -0
- package/dist/core/extensions/builtin/permission-system/parsers.d.ts +2 -0
- package/dist/core/extensions/builtin/permission-system/parsers.js +44 -10
- package/dist/modes/interactive/session-control-commands.js +21 -4
- package/dist/modes/interactive/session-control-rpc-commands.d.ts +1 -1
- package/dist/modes/interactive/session-control-rpc-commands.js +19 -0
- package/dist/modes/rpc/compact-content-store.d.ts +96 -0
- package/dist/modes/rpc/compact-content-store.js +269 -0
- package/dist/modes/rpc/compact-session-state.d.ts +111 -0
- package/dist/modes/rpc/compact-session-state.js +206 -0
- package/dist/modes/rpc/compact-spool-dir.d.ts +5 -0
- package/dist/modes/rpc/compact-spool-dir.js +61 -0
- package/dist/modes/rpc/compact-storage-io.d.ts +27 -0
- package/dist/modes/rpc/compact-storage-io.js +19 -0
- package/dist/modes/rpc/connection-handler.d.ts +2 -0
- package/dist/modes/rpc/connection-handler.js +39 -7
- package/dist/modes/rpc/connection-question-bridge.d.ts +2 -1
- package/dist/modes/rpc/connection-question-bridge.js +6 -2
- package/dist/modes/rpc/extension-ui-response.d.ts +7 -2
- package/dist/modes/rpc/extension-ui-response.js +27 -7
- package/dist/modes/rpc/get-snapshot.d.ts +18 -0
- package/dist/modes/rpc/get-snapshot.js +43 -0
- package/dist/modes/rpc/host-capabilities.js +3 -0
- package/dist/modes/rpc/host-ensure-start.js +1 -0
- package/dist/modes/rpc/host-ensure-types.d.ts +2 -0
- package/dist/modes/rpc/host-ensure.js +1 -0
- package/dist/modes/rpc/host-handoff.d.ts +2 -0
- package/dist/modes/rpc/host-handover-request.d.ts +1 -1
- package/dist/modes/rpc/host-handover-request.js +4 -3
- package/dist/modes/rpc/host-handover-wire.js +6 -0
- package/dist/modes/rpc/host-idle-handover.d.ts +2 -0
- package/dist/modes/rpc/host-idle-handover.js +3 -1
- package/dist/modes/rpc/host-observe-request.js +1 -0
- package/dist/modes/rpc/host-runner.d.ts +1 -0
- package/dist/modes/rpc/host-runner.js +9 -7
- package/dist/modes/rpc/host-successor.js +4 -0
- package/dist/modes/rpc/json-normal-value.d.ts +6 -0
- package/dist/modes/rpc/json-normal-value.js +100 -0
- package/dist/modes/rpc/mcp-presenter-bootstrap.js +5 -0
- package/dist/modes/rpc/media-placeholders.d.ts +9 -3
- package/dist/modes/rpc/media-placeholders.js +12 -4
- package/dist/modes/rpc/rpc-host-command-types.d.ts +2 -0
- package/dist/modes/rpc/rpc-question-types.d.ts +1 -0
- package/dist/modes/rpc/rpc-read-response-types.d.ts +7 -0
- package/dist/modes/rpc/rpc-session-command-types.d.ts +6 -0
- package/dist/modes/rpc/rpc-session-state-types.d.ts +3 -0
- package/dist/modes/rpc/rpc-session-state.js +2 -0
- package/dist/modes/rpc/rpc-types.d.ts +1 -0
- package/dist/modes/rpc/session-attachment-gate.js +1 -0
- package/dist/modes/rpc/session-binding.js +21 -18
- package/dist/modes/rpc/session-command-activity.js +1 -0
- package/dist/modes/rpc/session-event-fanout.d.ts +1 -1
- package/dist/modes/rpc/session-event-fanout.js +17 -9
- package/dist/modes/rpc/session-event-writer.js +22 -5
- package/dist/modes/rpc/session-extension-ui-requests.d.ts +2 -1
- package/dist/modes/rpc/session-extension-ui-requests.js +15 -10
- package/dist/modes/rpc/session-held.js +1 -0
- package/dist/modes/rpc/session-status-stream.d.ts +2 -1
- package/dist/modes/rpc/session-status-stream.js +8 -2
- package/dist/modes/rpc/session-status-subscriptions.d.ts +2 -1
- package/dist/modes/rpc/session-status-subscriptions.js +4 -0
- package/dist/modes/rpc/session-worker.js +5 -2
- package/dist/modes/rpc/snapshot-types.d.ts +29 -0
- package/dist/modes/rpc/snapshot-types.js +2 -0
- package/dist/modes/rpc/ui-answer-ledger.d.ts +13 -0
- package/dist/modes/rpc/ui-answer-ledger.js +34 -0
- package/dist/senpi +21 -3
- package/docs/mcp.md +20 -0
- package/docs/rpc.md +44 -0
- package/package.json +7 -6
- package/dist/bundle/chunks/azure-openai-responses-7I45DI72.js +0 -2
- package/dist/bundle/chunks/chunk-DMI55M2N.js +0 -2
- package/dist/bundle/chunks/chunk-DODH3N6U.js +0 -410
- package/dist/bundle/chunks/chunk-J37GRED2.js +0 -5
- package/dist/bundle/chunks/chunk-TBU6VYHN.js +0 -13
- package/dist/bundle/chunks/cli-main-YYH3IBC6.js +0 -3
- package/dist/bundle/chunks/dispatch-MXG5YWLV.js +0 -9
- package/dist/bundle/chunks/google-generative-ai-UM5Y7T6B.js +0 -2
- package/dist/bundle/chunks/google-vertex-OKU2VQHL.js +0 -2
- package/dist/bundle/chunks/host-command-TDLLHXVI.js +0 -2
- package/dist/bundle/chunks/interactive-mode-OEPULLZK.js +0 -2
- package/dist/bundle/chunks/openai-responses-TNHQ6SJS.js +0 -3
- package/dist/bundle/chunks/rpc-mode-ETXQWEB2.js +0 -2
- package/dist/bundle/chunks/session-control-endpoint-4LEIDIVI.js +0 -3
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
+
var captures=new WeakMap,readers=new WeakMap,writers=new WeakMap,states=new WeakMap,demanded=new WeakSet,warned=new WeakSet,NO_CHANGE=Object.freeze({}),subscribers=0,capturedAny=!1;function subscribeAssistantCapture(){subscribers++;let held=!0;return()=>{held&&subscribers--,held=!1}}function setAssistantReader(owner,reader){readers.set(owner,reader)}function setAssistantProgressWriter(owner,writer){writers.set(owner,writer)}function enableAssistantCapture(owner){states.has(owner)||states.set(owner,void 0)}function activeState(owner){let state=states.get(owner);if(state!==void 0||!states.has(owner))return state??void 0;let decided=subscribers>0||demanded.has(owner)?{positions:new Map,metadata:new Map,insertCopies:new Map,failedBlocks:new Set}:null;return capturedAny||=decided!==null,states.set(owner,decided),decided??void 0}function dropCapture(owner,error,state,contentIndex){contentIndex!==void 0&&state?.failedBlocks.add(contentIndex),!warned.has(owner)&&(warned.add(owner),console.warn("[assistant-capture] could not build an internal capture record; that block's records are dropped",error))}function pushAssistantProgress(owner,progress){let writer=writers.get(owner);if(!writer)return;if(Object.isFrozen(progress)){writer(progress);return}let state=activeState(owner);if(!(!state||state.failedBlocks.has(progress.contentIndex)))try{writer(freezeProgress(state,progress))}catch(error){dropCapture(owner,error,state,progress.contentIndex)}}function freezeProgress(state,progress){if(progress.type==="message_tool_arguments_reset"&&state.positions.set(progress.contentIndex,{offset:progress.rawArgumentPrefix.length,parsedThrough:progress.parsedThrough}),progress.type!=="message_block_state")return Object.freeze({...progress});let previous=state.insertCopies.get(progress.contentIndex),current=publicBlock(progress.block),block=previous!==void 0&&sameValue(current,previous)?previous:freezeCapture(current);return progress.phase==="insert"?state.insertCopies.set(progress.contentIndex,block):state.insertCopies.delete(progress.contentIndex),Object.freeze({...progress,block})}function pushAssistantSignature(owner,contentIndex,block,signature){!signature||signature===(block.type==="text"?block.textSignature:block.thinkingSignature)||pushAssistantProgress(owner,{type:"message_block_metadata",contentIndex,...block.type==="text"?{textSignature:signature}:{thinkingSignature:signature}})}function pushAssistantCompleteBlock(owner,contentIndex,block){for(let phase of["insert","end"])pushAssistantProgress(owner,{type:"message_block_state",contentIndex,phase,block})}function assistantRecords(source){demanded.add(source);let read=readers.get(source);return{[Symbol.asyncIterator]:()=>read?.(entry=>({value:"event"in entry?entry.event:entry.progress,done:!1}))??source[Symbol.asyncIterator]()}}function assistantEvents(source,onProgress){let read=readers.get(source);return{[Symbol.asyncIterator]:()=>read?.(entry=>{if("event"in entry)return{value:entry.event,done:!1};onProgress(entry.progress)})??source[Symbol.asyncIterator]()}}function getAssistantCapture(event){return captures.get(event)}function isAssistantProgress(event){return event.type==="message_block_state"||event.type==="message_block_metadata"||event.type==="message_tool_arguments_reset"}function freezeCapture(value){let freeze=part=>{if(!(part===null||typeof part!="object"||Object.isFrozen(part))){for(let child of Object.values(part))freeze(child);Object.freeze(part)}},copy=structuredClone(value);return freeze(copy),copy}function publicBlock(block){return Object.fromEntries({text:["type","text","audience","textSignature"],thinking:["type","thinking","thinkingSignature","redacted","startedAt","endedAt"],toolCall:["type","id","name","arguments","incomplete","errorMessage","thoughtSignature","namespace"],providerNative:["type","subtype","raw"]}[block.type].filter(key=>key in block).map(key=>[key,Reflect.get(block,key)]))}function sameValue(left,right){if(left===right)return!0;if(!isPlainData(left)||!isPlainData(right)||Array.isArray(left)!==Array.isArray(right))return!1;let keys=Object.keys(left);return keys.length===Object.keys(right).length&&keys.every(key=>Object.hasOwn(right,key)&&sameValue(Reflect.get(left,key),Reflect.get(right,key)))}function isPlainData(value){if(typeof value!="object"||value===null)return!1;let prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===Array.prototype||prototype===null}function dropAssistantCapture(event){capturedAny&&captures.delete(event)}function carryAssistantCapture(source,target,terminal){let capture=captures.get(source);if(!capture)return target;try{captures.set(target,terminal?Object.freeze({...capture,message:freezeCapture({...terminal,content:terminal.content.map(publicBlock)})}):capture)}catch(error){dropCapture(source,error)}return target}function captureAssistantEvent(owner,event,hint={}){let state=activeState(owner);if(!state||captures.has(event))return;let contentIndex="contentIndex"in event?hint.contentIndex??event.contentIndex:void 0;if(!(contentIndex!==void 0&&state.failedBlocks.has(contentIndex)))try{captures.set(event,buildCapture(state,event,hint))}catch(error){dropCapture(owner,error,state,contentIndex)}}function buildCapture(state,event,hint){let message=event.type==="done"?event.message:event.type==="error"?event.error:event.partial,usage=usageCopy(state,message.usage);if(!("contentIndex"in event))return Object.freeze({usage,metadata:changedMetadata(state,message),message:freezeCapture({...message,content:message.content.map(publicBlock)})});let index=hint.contentIndex??event.contentIndex,own=index===event.contentIndex?{}:{contentIndex:index};if("delta"in event){let position=state.positions.get(index)??{offset:0,parsedThrough:0},offset=hint.offset??position.offset;return position.offset=offset+event.delta.length,event.type==="toolcall_delta"&&event.delta.length>0&&(position.parsedThrough=hint.parsedThrough??Math.max(position.parsedThrough,position.offset)),state.positions.set(index,position),Object.freeze({usage,offset,...own,...event.type==="toolcall_delta"?{parsedThrough:position.parsedThrough}:{}})}let metadata=changedMetadata(state,message),block=freezeCapture(publicBlock(event.type==="toolcall_end"?event.toolCall:message.content[index]));if(event.type!=="text_start"&&event.type!=="thinking_start"&&event.type!=="toolcall_start")return Object.freeze({usage,metadata,block,...own});let rawArgumentPrefix=hint.rawArgumentPrefix??"",coveredCodeUnits=block.type==="text"?block.text.length:block.type==="thinking"?block.thinking.length:rawArgumentPrefix.length,parsedThrough=hint.parsedThrough??0;return state.positions.set(index,{offset:hint.offset??coveredCodeUnits,parsedThrough}),Object.freeze({usage,metadata,block,coveredCodeUnits,...own,...block.type==="toolCall"?{rawArgumentPrefix,parsedThrough}:{}})}function usageCopy(state,usage){if(state.usage!==void 0&&sameValue(usage,state.usage))return state.usage;let copy=Object.freeze({...usage,cost:Object.freeze({...usage.cost}),...usage.contextUsage?{contextUsage:Object.freeze({...usage.contextUsage})}:{}});return state.usage=copy,copy}function changedMetadata(state,message){let changed={};for(let key of Object.keys(message)){if(key==="content"||key==="usage")continue;let value=Reflect.get(message,key);(!state.metadata.has(key)||state.metadata.get(key)!==value)&&(changed[key]=value)}for(let key of state.metadata.keys())key in message||(changed[key]=null);let frozen=Object.keys(changed).length===0?NO_CHANGE:freezeCapture(changed);for(let key of Object.keys(changed))key in message?state.metadata.set(key,Reflect.get(message,key)):state.metadata.delete(key);return frozen}var FifoQueue=class{constructor(){this.incoming=[],this.outgoing=[]}get length(){return this.incoming.length+this.outgoing.length}enqueue(value){this.incoming.push(value)}prepend(value){this.outgoing.push(value)}dequeue(){if(this.outgoing.length===0)for(;this.incoming.length>0;)this.outgoing.push(this.incoming.pop());return this.outgoing.pop()}},EventStream=class{#queue;#queueHead;#failed;#error;#localWorkDepth;constructor(isComplete,extractResult){this.#queue=[],this.#queueHead=0,this.waiting=new FifoQueue,this.done=!1,this.#failed=!1,this.#localWorkDepth=0,this.isComplete=isComplete,this.extractResult=extractResult,this.finalResultPromise=new Promise((resolve,reject)=>{this.resolveFinalResult=resolve,this.rejectFinalResult=reject}),this.finalResultPromise.catch(()=>{})}get queue(){return this.#queue.slice(this.#queueHead).flatMap(entry=>"event"in entry?[entry.event]:[])}#enqueue(event){this.#queue.push(event)}#dequeue(){let event=this.#queue[this.#queueHead];if(event===void 0)throw new Error("EventStream queue underflow");return this.#queueHead++,this.#queueHead>1024&&this.#queueHead*2>=this.#queue.length&&(this.#queue=this.#queue.slice(this.#queueHead),this.#queueHead=0),event}push(event){this.done||(this.isComplete(event)&&(this.done=!0,this.resolveFinalResult(this.extractResult(event))),this.#deliver({event}))}enqueueProgress(progress){this.done||this.#deliver({progress})}#deliver(entry){let waiter=this.waiting.dequeue();waiter?waiter.resolve({value:entry,done:!1}):this.#enqueue(entry)}end(result){for(this.done=!0,result!==void 0&&this.resolveFinalResult(result);this.waiting.length>0;){let waiter=this.waiting.dequeue();waiter&&waiter.resolve({value:void 0,done:!0})}}fail(error){if(!this.done)for(this.done=!0,this.#failed=!0,this.#error=error,this.rejectFinalResult(error);this.waiting.length>0;){let waiter=this.waiting.dequeue();waiter&&waiter.reject(error)}}[Symbol.asyncIterator](){return this.mapIterator(entry=>"event"in entry?{value:entry.event,done:!1}:void 0)}mapIterator(project){return{next:()=>{for(;this.#queueHead<this.#queue.length;){let result=project(this.#dequeue());if(result)return Promise.resolve(result)}return this.#failed?Promise.reject(this.#error):this.done?Promise.resolve({value:void 0,done:!0}):new Promise((resolve,reject)=>{let waiter={reject,resolve:next=>{let result=next.done?{value:void 0,done:!0}:project(next.value);result?resolve(result):this.waiting.prepend(waiter)}};this.waiting.enqueue(waiter)})}}}result(){return this.finalResultPromise}async trackLocalWork(work){this.#localWorkDepth++;try{return await work}finally{this.#localWorkDepth--}}hasPendingLocalWork(){return this.#localWorkDepth>0}},AssistantMessageEventStream=class _AssistantMessageEventStream extends EventStream{constructor(options={}){super(event=>event.type==="done"||event.type==="error",event=>{if(event.type==="done")return event.message;if(event.type==="error")return event.error;throw new Error("Unexpected event type for final result")}),options.captureBlocks&&enableAssistantCapture(this),setAssistantProgressWriter(this,progress=>this.enqueueProgress(progress)),new.target.prototype[Symbol.asyncIterator]===_AssistantMessageEventStream.prototype[Symbol.asyncIterator]&&setAssistantReader(this,project=>this.mapIterator(project))}push(event,hint){this.done||(captureAssistantEvent(this,event,hint),super.push(event))}[Symbol.asyncIterator](){return this.mapIterator(entry=>{if("event"in entry)return dropAssistantCapture(entry.event),{value:entry.event,done:!1}})}};function createAssistantMessageEventStream(){return new AssistantMessageEventStream}function formatThrownValue(value){return value instanceof Error?value.message||value.name:typeof value=="string"?value:String(value)}function extractDiagnosticError(error){if(!(error instanceof Error))return{name:"ThrownValue",message:formatThrownValue(error)};let code=error.code;return{name:error.name||void 0,message:error.message||error.name,stack:error.stack,code:typeof code=="string"||typeof code=="number"?code:void 0}}function createAssistantMessageDiagnostic(type,error,details){return{type,timestamp:Date.now(),error:extractDiagnosticError(error),details}}function appendAssistantMessageDiagnostic(message,diagnostic){message.diagnostics=[...message.diagnostics??[],diagnostic]}export{subscribeAssistantCapture,setAssistantReader,enableAssistantCapture,pushAssistantProgress,pushAssistantSignature,pushAssistantCompleteBlock,assistantRecords,assistantEvents,getAssistantCapture,isAssistantProgress,carryAssistantCapture,EventStream,AssistantMessageEventStream,createAssistantMessageEventStream,formatThrownValue,extractDiagnosticError,createAssistantMessageDiagnostic,appendAssistantMessageDiagnostic};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
2
|
import{ProcessIdentityUnreadableError,processMatchesPidFile,readProcessStartTime}from"./chunk-O5RYI3IW.js";var HOST_GENERATION_ENV="SENPI_RPC_HOST_GENERATION",HOST_INSTANCE_ID_ENV="SENPI_RPC_HOST_INSTANCE_ID";import{createHmac,timingSafeEqual}from"node:crypto";var RPC_AUTH_CAPABILITY="socket_auth",RPC_AUTH_HEX=/^[a-f0-9]{64}$/,RPC_LAUNCH_ID=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/;function rpcAuthProof(key,label,...parts){return createHmac("sha256",key).update([`senpi-rpc-${label}`,...parts].join(`
|
|
3
3
|
`),"utf8").digest("hex")}function rpcProofMatches(expected,received){return typeof received=="string"&&RPC_AUTH_HEX.test(received)&&timingSafeEqual(Buffer.from(expected,"hex"),Buffer.from(received,"hex"))}var RpcEndpointAuthError=class extends Error{constructor(code,detail,options){super(`${code}: ${detail}`,options),this.code=code,this.name="RpcEndpointAuthError"}};function authRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:void 0}import{randomBytes,randomUUID}from"node:crypto";import{constants,unlinkSync}from"node:fs";import*as fs from"node:fs/promises";import{join}from"node:path";var MAX_KEY_RECORD_BYTES=4096;async function checkRpcKeyDirectory(path,privateKeys=!1){let checked=privateKeys?path:await fs.realpath(path),problem=keyDirectoryProblem(await fs.lstat(checked),checked,privateKeys);if(problem!==void 0)throw new RpcEndpointAuthError("unsafe_key_record",`${checked} ${problem}`)}function keyDirectoryProblem(info,path,privateKeys){if(!info.isDirectory())return"is not a directory";if(info.uid!==process.getuid?.())return"is not owned by this user";let mode=info.mode&4095;return privateKeys?mode===448?void 0:`must be mode 0700 (is 0${mode.toString(8)}); run: chmod 700 ${path}`:(mode&18)===0?void 0:`is writable by group or others; run: chmod go-w ${path}`}async function checkRpcKeyParents(root){await checkRpcKeyDirectory(root),await checkRpcKeyDirectory(join(root,"rpc"))}async function readRpcKeyRecord(root,launchId){if(!RPC_LAUNCH_ID.test(launchId))throw new RpcEndpointAuthError("unsafe_key_record",`invalid launch id under ${root}`);let path=join(root,"rpc","keys",launchId);try{await checkRpcKeyParents(root),await checkRpcKeyDirectory(join(root,"rpc","keys"),!0);let handle=await fs.open(path,constants.O_RDONLY|constants.O_NOFOLLOW|constants.O_NONBLOCK);try{let info=await handle.stat();if(!info.isFile()||info.uid!==process.getuid?.()||(info.mode&4095)!==384||info.size>MAX_KEY_RECORD_BYTES)throw new RpcEndpointAuthError("unsafe_key_record",path);let record=authRecord(JSON.parse(await handle.readFile("utf8")));if(record?.version!==1||record.launch_id!==launchId||typeof record.key!="string"||!RPC_AUTH_HEX.test(record.key))throw new RpcEndpointAuthError("unsafe_key_record",path);return record}finally{await handle.close()}}catch(cause){if(cause instanceof Error&&"code"in cause&&cause.code==="ENOENT")return;throw cause instanceof RpcEndpointAuthError?cause:new RpcEndpointAuthError("unsafe_key_record",path,{cause})}}var RpcPublicEndpoint=class{constructor(agentDir,endpoint){this.key=randomBytes(32),this.launchId=randomUUID(),this.publication=Promise.withResolvers(),this.created=!1,this.exitCleanup=()=>{if(this.created)try{unlinkSync(this.recordPath)}catch(cause){cause instanceof Error&&"code"in cause&&cause.code==="ENOENT"||process.stderr.write(`senpi rpc host: could not remove own endpoint key record
|
|
4
|
-
`)}},this.agentDir=agentDir,this.endpoint=endpoint,this.recordPath=join(agentDir,"rpc","keys",this.launchId),this.ready=this.publication.promise,this.ready.catch(()=>{})}async publish(){try{await fs.mkdir(join(this.agentDir,"rpc"),{recursive:!0,mode:448}),await checkRpcKeyParents(this.agentDir);let keys=join(this.agentDir,"rpc","keys");await fs.mkdir(keys,{recursive:!0,mode:448});let directory=await fs.lstat(keys);if(!directory.isDirectory()||directory.uid!==process.getuid?.())throw new RpcEndpointAuthError("unsafe_key_record",keys);(directory.mode&4095)!==448&&await fs.chmod(keys,448),await checkRpcKeyDirectory(keys,!0);let handle=await fs.open(this.recordPath,constants.O_WRONLY|constants.O_CREAT|constants.O_EXCL|constants.O_NOFOLLOW,384);this.created=!0,process.once("exit",this.exitCleanup);try{await handle.writeFile(JSON.stringify({version:1,launch_id:this.launchId,key:this.key.toString("hex"),pid:process.pid,process_start:await readProcessStartTime(process.pid)??null,endpoint:this.endpoint,created_at:new Date().toISOString()})),await handle.sync();let info=await handle.stat();if(!info.isFile()||info.uid!==process.getuid?.()||(info.mode&4095)!==384)throw new RpcEndpointAuthError("unsafe_key_record",this.recordPath)}finally{await handle.close()}this.publication.resolve()}catch(cause){let error=new RpcEndpointAuthError("key_publication_failed",cause instanceof RpcEndpointAuthError?cause.message:this.recordPath,{cause});throw this.publication.reject(error),error}}async dispose(){process.off("exit",this.exitCleanup),this.created&&(this.created=!1,await fs.unlink(this.recordPath).catch(cause=>{if(!(cause instanceof Error&&"code"in cause&&cause.code==="ENOENT"))throw cause}))}};async function gcRpcPublicKeys(agentDir,budget={}){let keys=join(agentDir,"rpc","keys");try{await checkRpcKeyParents(agentDir),await checkRpcKeyDirectory(keys,!0)}catch(cause){if(cause instanceof RpcEndpointAuthError||cause instanceof Error&&"code"in cause&&cause.code==="ENOENT")return;throw cause}let names=await fs.readdir(keys).catch(cause=>{if(cause instanceof Error&&"code"in cause&&cause.code==="ENOENT")return[];throw cause}),examined=0;for(let name of names){if(Date.now()>=(budget.deadline??1/0)||examined>=(budget.maxRecords??1/0))break;if(RPC_LAUNCH_ID.test(name)){examined++;try{let record=await readRpcKeyRecord(agentDir,name);if(record===void 0||typeof record.pid!="number"||!Number.isSafeInteger(record.pid)||record.pid<=0||!(record.process_start===null||typeof record.process_start=="string")||await processMatchesPidFile({pid:record.pid,processStartTime:record.process_start}))continue;await fs.unlink(join(keys,name))}catch(cause){if(cause instanceof ProcessIdentityUnreadableError||cause instanceof RpcEndpointAuthError||cause instanceof Error&&"code"in cause&&cause.code==="ENOENT")continue;throw cause}}}}var OBSERVE_REQUEST_FIELD="observe",ORIGIN_HOST_INSTANCE_FIELD="origin_host_instance",OBSERVING_COMMANDS=new Set(["get_protocol_info","list_sessions","subscribe_sessions","unsubscribe_sessions","get_effect_status","get_pending_inputs","get_subscription_limits","get_state","get_entries"]);function isObservingRequest(line){let request;try{request=JSON.parse(line)}catch{return!1}if(typeof request!="object"||request===null||Array.isArray(request))return!1;let record=request;return record.type==="warm"||record.type==="authenticate"?!0:record[OBSERVE_REQUEST_FIELD]===!0&&OBSERVING_COMMANDS.has(record.type)}function originHostInstance(env=process.env){let instance=env[HOST_INSTANCE_ID_ENV]?.trim();return instance||void 0}function requestOriginHostInstance(line){let request;try{request=JSON.parse(line)}catch{return}if(typeof request!="object"||request===null||Array.isArray(request))return;let origin=Reflect.get(request,ORIGIN_HOST_INSTANCE_FIELD);return typeof origin=="string"&&origin.length>0?origin:void 0}export{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV,OBSERVE_REQUEST_FIELD,ORIGIN_HOST_INSTANCE_FIELD,isObservingRequest,originHostInstance,requestOriginHostInstance,RPC_AUTH_CAPABILITY,RPC_AUTH_HEX,RPC_LAUNCH_ID,rpcAuthProof,rpcProofMatches,RpcEndpointAuthError,authRecord,readRpcKeyRecord,RpcPublicEndpoint,gcRpcPublicKeys};
|
|
4
|
+
`)}},this.agentDir=agentDir,this.endpoint=endpoint,this.recordPath=join(agentDir,"rpc","keys",this.launchId),this.ready=this.publication.promise,this.ready.catch(()=>{})}async publish(){try{await fs.mkdir(join(this.agentDir,"rpc"),{recursive:!0,mode:448}),await checkRpcKeyParents(this.agentDir);let keys=join(this.agentDir,"rpc","keys");await fs.mkdir(keys,{recursive:!0,mode:448});let directory=await fs.lstat(keys);if(!directory.isDirectory()||directory.uid!==process.getuid?.())throw new RpcEndpointAuthError("unsafe_key_record",keys);(directory.mode&4095)!==448&&await fs.chmod(keys,448),await checkRpcKeyDirectory(keys,!0);let handle=await fs.open(this.recordPath,constants.O_WRONLY|constants.O_CREAT|constants.O_EXCL|constants.O_NOFOLLOW,384);this.created=!0,process.once("exit",this.exitCleanup);try{await handle.writeFile(JSON.stringify({version:1,launch_id:this.launchId,key:this.key.toString("hex"),pid:process.pid,process_start:await readProcessStartTime(process.pid)??null,endpoint:this.endpoint,created_at:new Date().toISOString()})),await handle.sync();let info=await handle.stat();if(!info.isFile()||info.uid!==process.getuid?.()||(info.mode&4095)!==384)throw new RpcEndpointAuthError("unsafe_key_record",this.recordPath)}finally{await handle.close()}this.publication.resolve()}catch(cause){let error=new RpcEndpointAuthError("key_publication_failed",cause instanceof RpcEndpointAuthError?cause.message:this.recordPath,{cause});throw this.publication.reject(error),error}}async dispose(){process.off("exit",this.exitCleanup),this.created&&(this.created=!1,await fs.unlink(this.recordPath).catch(cause=>{if(!(cause instanceof Error&&"code"in cause&&cause.code==="ENOENT"))throw cause}))}};async function gcRpcPublicKeys(agentDir,budget={}){let keys=join(agentDir,"rpc","keys");try{await checkRpcKeyParents(agentDir),await checkRpcKeyDirectory(keys,!0)}catch(cause){if(cause instanceof RpcEndpointAuthError||cause instanceof Error&&"code"in cause&&cause.code==="ENOENT")return;throw cause}let names=await fs.readdir(keys).catch(cause=>{if(cause instanceof Error&&"code"in cause&&cause.code==="ENOENT")return[];throw cause}),examined=0;for(let name of names){if(Date.now()>=(budget.deadline??1/0)||examined>=(budget.maxRecords??1/0))break;if(RPC_LAUNCH_ID.test(name)){examined++;try{let record=await readRpcKeyRecord(agentDir,name);if(record===void 0||typeof record.pid!="number"||!Number.isSafeInteger(record.pid)||record.pid<=0||!(record.process_start===null||typeof record.process_start=="string")||await processMatchesPidFile({pid:record.pid,processStartTime:record.process_start}))continue;await fs.unlink(join(keys,name))}catch(cause){if(cause instanceof ProcessIdentityUnreadableError||cause instanceof RpcEndpointAuthError||cause instanceof Error&&"code"in cause&&cause.code==="ENOENT")continue;throw cause}}}}var OBSERVE_REQUEST_FIELD="observe",ORIGIN_HOST_INSTANCE_FIELD="origin_host_instance",OBSERVING_COMMANDS=new Set(["get_protocol_info","get_snapshot","list_sessions","subscribe_sessions","unsubscribe_sessions","get_effect_status","get_pending_inputs","get_subscription_limits","get_state","get_entries"]);function isObservingRequest(line){let request;try{request=JSON.parse(line)}catch{return!1}if(typeof request!="object"||request===null||Array.isArray(request))return!1;let record=request;return record.type==="warm"||record.type==="authenticate"?!0:record[OBSERVE_REQUEST_FIELD]===!0&&OBSERVING_COMMANDS.has(record.type)}function originHostInstance(env=process.env){let instance=env[HOST_INSTANCE_ID_ENV]?.trim();return instance||void 0}function requestOriginHostInstance(line){let request;try{request=JSON.parse(line)}catch{return}if(typeof request!="object"||request===null||Array.isArray(request))return;let origin=Reflect.get(request,ORIGIN_HOST_INSTANCE_FIELD);return typeof origin=="string"&&origin.length>0?origin:void 0}export{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV,OBSERVE_REQUEST_FIELD,ORIGIN_HOST_INSTANCE_FIELD,isObservingRequest,originHostInstance,requestOriginHostInstance,RPC_AUTH_CAPABILITY,RPC_AUTH_HEX,RPC_LAUNCH_ID,rpcAuthProof,rpcProofMatches,RpcEndpointAuthError,authRecord,readRpcKeyRecord,RpcPublicEndpoint,gcRpcPublicKeys};
|
|
@@ -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
|
-
import{ORIGIN_HOST_INSTANCE_FIELD,RPC_AUTH_HEX,RPC_LAUNCH_ID,RpcEndpointAuthError,authRecord,originHostInstance,readRpcKeyRecord,rpcAuthProof,rpcProofMatches}from"./chunk-
|
|
2
|
+
import{ORIGIN_HOST_INSTANCE_FIELD,RPC_AUTH_HEX,RPC_LAUNCH_ID,RpcEndpointAuthError,authRecord,originHostInstance,readRpcKeyRecord,rpcAuthProof,rpcProofMatches}from"./chunk-GWGNVYPB.js";import{attachJsonlLineReader,serializeJsonLine}from"./chunk-YI7SPFDN.js";import{SOCKET_HANDSHAKE_TIMEOUT_MS}from"./chunk-ZGAB7WQA.js";import{getAgentDir}from"./chunk-7YO7VQZW.js";import{createHash}from"node:crypto";import{basename}from"node:path";var TUI_SOCKET_NAME=/^t-[0-9a-f]{16}\.sock$/;function tuiSocketName(instanceId){return`t-${createHash("sha256").update(instanceId,"utf8").digest("hex").slice(0,16)}.sock`}function isTuiControlSocket(socket){return TUI_SOCKET_NAME.test(basename(socket))}function socketNeedsHandshake(socket,platform=process.platform){return platform==="win32"||isTuiControlSocket(socket)}import{AsyncLocalStorage}from"node:async_hooks";import{randomBytes}from"node:crypto";import{createConnection}from"node:net";var keyRoots=new AsyncLocalStorage;function withRpcKeyRoot(root,operation){return keyRoots.run(root,operation)}function rpcKeyRoot(options={},defaultRoot){return options.keyRoot??keyRoots.getStore()??process.env.SENPI_RPC_KEY_ROOT??defaultRoot??getAgentDir()}async function connectAuthenticatedRpcSocket(path,first={type:"get_protocol_info",id:"rpc-auth-protocol",observe:!0,[ORIGIN_HOST_INSTANCE_FIELD]:originHostInstance()},options={},timeoutMs=SOCKET_HANDSHAKE_TIMEOUT_MS){let deadline=Date.now()+timeoutMs;for(let attempt=0;;attempt++){let socket=createConnection(path),earlyError,ignoreLateError=error=>{earlyError??=error};socket.on("error",ignoreLateError);let connected=!1;socket.once("connect",()=>{connected=!0});try{let protocol=await authenticate(socket,path,first,rpcKeyRoot(options),Math.max(1,deadline-Date.now()));return socket.off("error",ignoreLateError),{socket,protocol}}catch(cause){if(socket.destroy(),attempt===0&&cause instanceof RpcEndpointAuthError&&cause.code==="auth_failed")continue;let failure=!(cause instanceof RpcEndpointAuthError)&&earlyError!==void 0?earlyError:cause;throw failure instanceof Error&&Object.assign(failure,{rpcSocketConnected:connected}),failure}}}async function authenticate(socket,path,first,root,timeoutMs){let pending,reject=error=>pending?.reject(error),socketError,onClose=()=>setImmediate(()=>reject(socketError??new Error(`RPC socket closed during authentication: ${path}`))),onError=error=>{socketError??=error,reject(error)};socket.on("error",onError),socket.on("close",onClose);let detach=attachJsonlLineReader(socket,line=>{let response;try{response=authRecord(JSON.parse(line))}catch{return}if(!(response===void 0||pending===void 0||response.id!==pending.id))if(response.success===!0)pending?.resolve(response);else{let code=response.errorCode;reject(code==="auth_failed"||code==="auth_required"?new RpcEndpointAuthError(code,`${path}; set SENPI_RPC_KEY_ROOT to the host's agent dir (${root})`):new Error(`RPC authentication probe refused on ${path}: ${String(response.error)}`))}},{maxLineLength:1024*1024,onOversizedLine:()=>socket.destroy()}),exchange=request=>new Promise((resolve,reject2)=>{if(socket.destroyed){setImmediate(()=>reject2(socketError??new Error(`RPC socket closed during authentication: ${path}`)));return}pending={id:request.id,resolve,reject:reject2},socket.write(serializeJsonLine(request))}),timer=setTimeout(()=>{reject(new Error(`RPC authentication timed out on ${path}`)),socket.destroy()},timeoutMs);try{let nonce=randomBytes(32).toString("hex"),response=await exchange({...first,auth:{client_nonce:nonce}}),data=authRecord(response.data);if(data?.auth===void 0)return response;let auth=authRecord(data.auth);if(typeof auth?.launch_id!="string"||!RPC_LAUNCH_ID.test(auth.launch_id)||typeof auth.server_nonce!="string"||!RPC_AUTH_HEX.test(auth.server_nonce))throw new RpcEndpointAuthError("host_identity_unproven",path);let record=await readRpcKeyRecord(root,auth.launch_id);if(socket.destroyed)throw new Error(`RPC authentication timed out on ${path}`);if(record===void 0)return process.stderr.write(`senpi rpc client: no key record for launch ${auth.launch_id} under ${root}; continuing unauthenticated (refused from the next release; set SENPI_RPC_KEY_ROOT to the host's agent dir)
|
|
3
3
|
`),response;if(typeof record.key!="string")throw new RpcEndpointAuthError("unsafe_key_record",root);let key=Buffer.from(record.key,"hex");if(!rpcProofMatches(rpcAuthProof(key,"server",auth.launch_id,nonce,auth.server_nonce),auth.server_proof))throw new RpcEndpointAuthError("host_identity_unproven",path);return await exchange({id:"rpc-authenticate",type:"authenticate",client_proof:rpcAuthProof(key,"client",auth.launch_id,auth.server_nonce,nonce)}),response}finally{clearTimeout(timer),detach(),socket.off("error",onError),socket.off("close",onClose)}}export{tuiSocketName,isTuiControlSocket,socketNeedsHandshake,withRpcKeyRoot,rpcKeyRoot,connectAuthenticatedRpcSocket};
|
|
@@ -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{listHostEndpoints}from"./chunk-
|
|
2
|
+
import{listHostEndpoints}from"./chunk-XMNPK472.js";import{randomBytes}from"node:crypto";var MONITOR_ID_ALPHABET="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function allocateMonitorId(){let id="mon_",buffer=0,bits=0;for(let byte of randomBytes(10))for(buffer=buffer<<8|byte,bits+=8;bits>=5;)bits-=5,id+=MONITOR_ID_ALPHABET[buffer>>bits&31];return id}var STATUS_KINDS=new Set(["session_status","effect_status"]);function parseRpcTarget(target,selfDurableId){let trimmed=target.trim();return trimmed===""?{error:'target is empty; pass "children", "all" or a session id, path or st_ task id'}:trimmed==="children"?selfDurableId===void 0?{error:'target "children" needs a session with a durable id; save the session first, or watch "all"'}:{kind:"children",parent:selfDurableId}:trimmed==="all"?{kind:"all"}:trimmed.startsWith("st_")?{kind:"task",taskId:trimmed}:{kind:"id",id:trimmed}}function defaultEvents(target){return target.kind==="children"?["session_status","effect_status"]:["session_status"]}function subscriptionFor(target,events){let sessions=target.kind==="children"?{childrenOf:target.parent}:target.kind==="id"?{ids:[target.id]}:"all",content=events==="all"?"all":events.filter(kind=>!STATUS_KINDS.has(kind)),mirror=content==="all"?"all":content.length===0?void 0:content;return{sessions,include_workers:!0,include_context:target.kind==="children"||target.kind==="task",effects:events==="all"||events.includes("effect_status"),...mirror===void 0?{}:{mirror}}}function wantsRecord(events,exclude,type){return exclude.includes(type)?!1:events==="all"||events.includes(type)}function matchesTask(target,row){return target.kind!=="task"?!0:row.context?.task_id===target.taskId}async function endpointSockets(agentDir){return(await listHostEndpoints(agentDir)).map(endpoint=>endpoint.socket).filter(socket=>socket!==null)}export{allocateMonitorId,parseRpcTarget,defaultEvents,subscriptionFor,wantsRecord,matchesTask,endpointSockets};
|
|
@@ -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{source_default}from"./chunk-26UBFF6N.js";import{legacyProviderIdRejection}from"./chunk-6AOVUTUR.js";import{APP_NAME,CONFIG_DIR_NAME,ENV_AGENT_DIR,ENV_SESSION_DIR,brandEnvNames,envValue}from"./chunk-7YO7VQZW.js";function isSpawnedBy(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)&&"parentSessionId"in value&&typeof value.parentSessionId=="string"&&value.parentSessionId.length>0&&"rootSessionId"in value&&typeof value.rootSessionId=="string"&&value.rootSessionId.length>0&&"taskId"in value&&typeof value.taskId=="string"&&value.taskId.length>0}function isGrokNeoEnabled(env=process.env){let value=envValue("ENABLE_GROK_NEO",env);if(value===void 0)return!1;let normalized=value.trim().toLowerCase();return normalized==="1"||normalized==="true"||normalized==="yes"}var TOOL_RUNTIMES=["in-process","child"];function isToolRuntimeKind(value){return TOOL_RUNTIMES.some(kind=>kind===value)}var TOOL_RUNTIME_ENV_SUFFIX="TOOL_RUNTIME",TOOL_CHILD_PLACEMENTS=["launch-barrier","job-policy","hostcall","offload","terminal"],OFFLOAD_API_CAPABILITY="offload_api";function toolRuntimeCapabilities(runtime){return[toolRuntimeCapability(runtime),...runtime==="child"?TOOL_CHILD_PLACEMENTS.map(name=>`placement:${name}`):[],OFFLOAD_API_CAPABILITY]}function isHostOwnedToolRuntimeCapability(capability){return capability.startsWith("tool_runtime:")||capability.startsWith("placement:")||capability===OFFLOAD_API_CAPABILITY}function toolRuntimeCapability(runtime){return`tool_runtime:${runtime}`}var TOOL_RUNTIME_UNSUPPORTED_HOST="tool_runtime_unsupported_host";function toolRuntimeHostRefusal(runtime,platform=process.platform,hasFfi=()=>process.getBuiltinModule("bun:ffi")!==void 0){if(!(runtime!=="child"||platform!=="win32"||hasFfi()))return`${TOOL_RUNTIME_UNSUPPORTED_HOST}: --tool-runtime child on Windows needs the Bun runtime (bun:ffi holds the tool child in a Job Object); run senpi under Bun or use in-process`}var ToolRuntimeUnsupportedHostError=class extends Error{constructor(message){super(message),this.code=TOOL_RUNTIME_UNSUPPORTED_HOST,this.name="ToolRuntimeUnsupportedHostError"}};function resolveToolRuntime(parsed,env=process.env,platform=process.platform,hasFfi){let resolved=resolveRequestedToolRuntime(parsed,env);if(!resolved.ok)return resolved;let refusal=toolRuntimeHostRefusal(resolved.value,platform,hasFfi);return refusal===void 0?resolved:{ok:!1,message:refusal}}function resolveRequestedToolRuntime(parsed,env){if(parsed.toolRuntime!==void 0)return{ok:!0,value:parsed.toolRuntime};let fromEnv=envValue(TOOL_RUNTIME_ENV_SUFFIX,env);return fromEnv===void 0||fromEnv===""?{ok:!0,value:"in-process"}:isToolRuntimeKind(fromEnv)?{ok:!0,value:fromEnv}:{ok:!1,message:`${brandEnvNames(TOOL_RUNTIME_ENV_SUFFIX).find(candidate=>env[candidate]!==void 0)??TOOL_RUNTIME_ENV_SUFFIX} (--tool-runtime) must be in-process or child, got ${JSON.stringify(fromEnv)}`}}var SESSION_RUNTIMES=["in-process","worker"];function isSessionRuntimeKind(value){return SESSION_RUNTIMES.includes(value)}function resolveSessionRuntime(parsed){return parsed.sessionRuntime?parsed.sessionRuntime:parsed.listen!==void 0&&parsed.listen!=="stdio://"?"in-process":"worker"}var VALID_THINKING_LEVELS=["off","minimal","low","medium","high","xhigh","max"];function isValidThinkingLevel(level){return VALID_THINKING_LEVELS.includes(level)}function normalizeSessionName(value){let name=value.trim();return name.length>0?name:void 0}function parseArgs(args,options={}){let grokNeoEnabled=options.grokNeoEnabled??isGrokNeoEnabled(),result={messages:[],fileArgs:[],unknownFlags:new Map,diagnostics:[]};if(args[0]==="app-server")return result.diagnostics.push({type:"error",message:`The app-server command has been removed. Use "${APP_NAME} --mode rpc" for process integration.`}),result;let hasRetiredCommand=!1;for(let i=0;i<args.length;i++){let arg=args[i];if(arg==="--"){for(let positionalArg of args.slice(i+1))positionalArg.startsWith("@")?result.fileArgs.push(positionalArg.slice(1)):result.messages.push(positionalArg);break}else if(arg==="--help"||arg==="-h")result.help=!0;else if(arg==="--version"||arg==="-v")result.version=!0;else if(arg==="--mode"){let mode=args[i+1];if(mode===void 0||mode.startsWith("-")){result.diagnostics.push({type:"error",message:"--mode requires text, json, or rpc"});continue}if(i++,mode!=="text"&&mode!=="json"&&mode!=="rpc"){result.diagnostics.push({type:"error",message:`Invalid mode "${mode}". Valid values: text, json, rpc`});continue}result.mode=mode}else if(arg==="--continue"||arg==="-c")result.continue=!0;else if(arg==="--resume"||arg==="-r")result.resume=!0;else if(arg==="--provider"&&i+1<args.length){let typedProvider=args[++i],rejection=typedProvider===void 0?void 0:legacyProviderIdRejection(typedProvider);if(rejection)throw new Error(rejection);result.provider=typedProvider}else if(arg==="--model"&&i+1<args.length)result.model=args[++i];else if(arg==="--api-key"&&i+1<args.length)result.apiKey=args[++i];else if(arg==="--system-prompt"&&i+1<args.length)result.systemPrompt=args[++i];else if(arg==="--append-system-prompt"&&i+1<args.length)result.appendSystemPrompt=result.appendSystemPrompt??[],result.appendSystemPrompt.push(args[++i]);else if(arg==="--name"||arg==="-n")i+1<args.length?result.name=args[++i]:result.diagnostics.push({type:"error",message:"--name requires a value"});else if(arg==="--no-session")result.noSession=!0;else if(arg==="--session"&&i+1<args.length)result.session=args[++i];else if(arg==="--session-id"&&i+1<args.length)result.sessionId=args[++i];else if(arg==="--spawned-by"){let value=args[i+1];if(value===void 0||value.startsWith("-"))result.diagnostics.push({type:"error",message:"--spawned-by requires a JSON object"});else{i++;try{let ancestry=JSON.parse(value);isSpawnedBy(ancestry)?result.spawnedBy=ancestry:result.diagnostics.push({type:"error",message:"--spawned-by requires non-empty parentSessionId, rootSessionId, and taskId strings"})}catch(error){if(!(error instanceof SyntaxError))throw error;result.diagnostics.push({type:"error",message:"--spawned-by must be valid JSON"})}}}else if(arg==="--fork"&&i+1<args.length)result.fork=args[++i];else if(arg==="--rebind"&&i+1<args.length)result.rebind=args[++i];else if(arg==="--session-dir"&&i+1<args.length)result.sessionDir=args[++i];else if(arg==="--models"&&i+1<args.length)result.models=args[++i].split(",").map(s=>s.trim());else if(arg==="--no-tools"||arg==="-nt")result.noTools=!0;else if(arg==="--no-builtin-tools"||arg==="-nbt")result.noBuiltinTools=!0;else if((arg==="--tools"||arg==="-t")&&i+1<args.length)result.tools=args[++i].split(",").map(s=>s.trim()).filter(name=>name.length>0);else if((arg==="--exclude-tools"||arg==="-xt")&&i+1<args.length)result.excludeTools=args[++i].split(",").map(s=>s.trim()).filter(name=>name.length>0);else if(arg==="--thinking"&&i+1<args.length){let level=args[++i];isValidThinkingLevel(level)?result.thinking=level:result.diagnostics.push({type:"warning",message:`Invalid thinking level "${level}". Valid values: ${VALID_THINKING_LEVELS.join(", ")}`})}else if(arg==="--print"||arg==="-p"){result.print=!0;let next=args[i+1];next!==void 0&&!next.startsWith("@")&&(!next.startsWith("-")||next.startsWith("---"))&&(result.messages.push(next),i++)}else if(arg==="--export"&&i+1<args.length)result.export=args[++i];else if((arg==="--extension"||arg==="-e")&&i+1<args.length)result.extensions=result.extensions??[],result.extensions.push(args[++i]);else if(arg==="--no-extensions"||arg==="-ne")result.noExtensions=!0;else if(arg==="--skill"&&i+1<args.length)result.skills=result.skills??[],result.skills.push(args[++i]);else if(arg==="--prompt-template"&&i+1<args.length)result.promptTemplates=result.promptTemplates??[],result.promptTemplates.push(args[++i]);else if(arg==="--theme"&&i+1<args.length)result.themes=result.themes??[],result.themes.push(args[++i]);else if(arg==="--use-theme"){let themeName=args[i+1];themeName===void 0||themeName.startsWith("-")?result.diagnostics.push({type:"error",message:"--use-theme requires a theme name"}):(result.useTheme=themeName,i++)}else if(arg==="--no-skills"||arg==="-ns")result.noSkills=!0;else if(arg==="--no-prompt-templates"||arg==="-np")result.noPromptTemplates=!0;else if(arg==="--no-themes")result.noThemes=!0;else if(arg==="--no-context-files"||arg==="-nc")result.noContextFiles=!0;else if(arg==="--print-prompt-sizes")result.printPromptSizes=!0;else if(arg==="--list-models")i+1<args.length&&!args[i+1].startsWith("-")&&!args[i+1].startsWith("@")?result.listModels=args[++i]:result.listModels=!0;else if(arg==="--list-tips")result.listTips=!0;else if(arg==="--tui-mode"){let mode=args[i+1];mode==="regular"||mode==="fullscreen"?(result.tuiMode=mode,i++):mode===void 0||mode.startsWith("-")?result.diagnostics.push({type:"error",message:"--tui-mode requires regular or fullscreen"}):(i++,result.diagnostics.push({type:"error",message:`Invalid TUI mode "${mode}". Valid values: regular, fullscreen`}))}else if(arg==="--verbose")result.verbose=!0;else if(arg==="--approve"||arg==="-a")result.projectTrustOverride=!0;else if(arg==="--no-approve"||arg==="-na")result.projectTrustOverride=!1;else if(arg==="--offline")result.offline=!0;else if(grokNeoEnabled&&arg==="--grok-neo")result.grokNeo=!0;else if(arg==="--multi-session")result.multiSession=!0;else if(arg==="--mcp-presenter-fd")args[++i]==="4"?result.presenterBootstrapFd=4:result.diagnostics.push({type:"error",message:"Invalid presenter bootstrap descriptor"});else if(arg==="--mcp-presenter-enforcement")result.mcpPresenterEnforcement=!0;else if(arg==="--auto-title-sessions")result.autoTitleSessions=!0;else if(arg==="--session-runtime"){let value=args[i+1];value!==void 0&&!value.startsWith("--")&&i++,value!==void 0&&isSessionRuntimeKind(value)?result.sessionRuntime=value:result.diagnostics.push({type:"error",message:"--session-runtime must be in-process or worker"})}else if(arg==="--tool-runtime"){let value=args[i+1];value!==void 0&&!value.startsWith("--")&&i++,value!==void 0&&isToolRuntimeKind(value)?result.toolRuntime=value:result.diagnostics.push({type:"error",message:"--tool-runtime must be in-process or child"})}else if(arg==="--listen"&&result.mode==="rpc"){let value=args[i+1];value===void 0||value.startsWith("--")?result.diagnostics.push({type:"error",message:"--listen requires a value"}):(result.listen=value,result.multiSession=!0,i++)}else if(arg.startsWith("@"))result.fileArgs.push(arg.slice(1));else if(arg.startsWith("--")){let eqIndex=arg.indexOf("=");if(eqIndex!==-1)result.unknownFlags.set(arg.slice(2,eqIndex),arg.slice(eqIndex+1));else{let flagName=arg.slice(2),next=args[i+1];next!==void 0&&!next.startsWith("-")&&!next.startsWith("@")?(result.unknownFlags.set(flagName,next),i++):result.unknownFlags.set(flagName,!0)}}else arg==="-"?result.readStdin=!0:arg.startsWith("-")&&!arg.startsWith("--")?result.diagnostics.push({type:"error",message:`Unknown option: ${arg}`}):arg.startsWith("-")||(result.messages.length===0&&arg==="app-server"&&(hasRetiredCommand=!0),result.messages.push(arg))}return hasRetiredCommand&&result.mode===void 0&&!result.print&&(result.messages=[],result.diagnostics.push({type:"error",message:`The app-server command has been removed. Use "${APP_NAME} --mode rpc" for process integration.`})),result}function printHelp(extensionFlags,grokNeoEnabled=isGrokNeoEnabled()){let extensionFlagsText=extensionFlags&&extensionFlags.length>0?`
|
|
2
|
+
import{source_default}from"./chunk-26UBFF6N.js";import{legacyProviderIdRejection}from"./chunk-ZXHLH4MW.js";import{APP_NAME,CONFIG_DIR_NAME,ENV_AGENT_DIR,ENV_SESSION_DIR,brandEnvNames,envValue}from"./chunk-7YO7VQZW.js";function isSpawnedBy(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)&&"parentSessionId"in value&&typeof value.parentSessionId=="string"&&value.parentSessionId.length>0&&"rootSessionId"in value&&typeof value.rootSessionId=="string"&&value.rootSessionId.length>0&&"taskId"in value&&typeof value.taskId=="string"&&value.taskId.length>0}function isGrokNeoEnabled(env=process.env){let value=envValue("ENABLE_GROK_NEO",env);if(value===void 0)return!1;let normalized=value.trim().toLowerCase();return normalized==="1"||normalized==="true"||normalized==="yes"}var TOOL_RUNTIMES=["in-process","child"];function isToolRuntimeKind(value){return TOOL_RUNTIMES.some(kind=>kind===value)}var TOOL_RUNTIME_ENV_SUFFIX="TOOL_RUNTIME",TOOL_CHILD_PLACEMENTS=["launch-barrier","job-policy","hostcall","offload","terminal"],OFFLOAD_API_CAPABILITY="offload_api";function toolRuntimeCapabilities(runtime){return[toolRuntimeCapability(runtime),...runtime==="child"?TOOL_CHILD_PLACEMENTS.map(name=>`placement:${name}`):[],OFFLOAD_API_CAPABILITY]}function isHostOwnedToolRuntimeCapability(capability){return capability.startsWith("tool_runtime:")||capability.startsWith("placement:")||capability===OFFLOAD_API_CAPABILITY}function toolRuntimeCapability(runtime){return`tool_runtime:${runtime}`}var TOOL_RUNTIME_UNSUPPORTED_HOST="tool_runtime_unsupported_host";function toolRuntimeHostRefusal(runtime,platform=process.platform,hasFfi=()=>process.getBuiltinModule("bun:ffi")!==void 0){if(!(runtime!=="child"||platform!=="win32"||hasFfi()))return`${TOOL_RUNTIME_UNSUPPORTED_HOST}: --tool-runtime child on Windows needs the Bun runtime (bun:ffi holds the tool child in a Job Object); run senpi under Bun or use in-process`}var ToolRuntimeUnsupportedHostError=class extends Error{constructor(message){super(message),this.code=TOOL_RUNTIME_UNSUPPORTED_HOST,this.name="ToolRuntimeUnsupportedHostError"}};function resolveToolRuntime(parsed,env=process.env,platform=process.platform,hasFfi){let resolved=resolveRequestedToolRuntime(parsed,env);if(!resolved.ok)return resolved;let refusal=toolRuntimeHostRefusal(resolved.value,platform,hasFfi);return refusal===void 0?resolved:{ok:!1,message:refusal}}function resolveRequestedToolRuntime(parsed,env){if(parsed.toolRuntime!==void 0)return{ok:!0,value:parsed.toolRuntime};let fromEnv=envValue(TOOL_RUNTIME_ENV_SUFFIX,env);return fromEnv===void 0||fromEnv===""?{ok:!0,value:"in-process"}:isToolRuntimeKind(fromEnv)?{ok:!0,value:fromEnv}:{ok:!1,message:`${brandEnvNames(TOOL_RUNTIME_ENV_SUFFIX).find(candidate=>env[candidate]!==void 0)??TOOL_RUNTIME_ENV_SUFFIX} (--tool-runtime) must be in-process or child, got ${JSON.stringify(fromEnv)}`}}var SESSION_RUNTIMES=["in-process","worker"];function isSessionRuntimeKind(value){return SESSION_RUNTIMES.includes(value)}function resolveSessionRuntime(parsed){return parsed.sessionRuntime?parsed.sessionRuntime:parsed.listen!==void 0&&parsed.listen!=="stdio://"?"in-process":"worker"}var VALID_THINKING_LEVELS=["off","minimal","low","medium","high","xhigh","max"];function isValidThinkingLevel(level){return VALID_THINKING_LEVELS.includes(level)}function normalizeSessionName(value){let name=value.trim();return name.length>0?name:void 0}function parseArgs(args,options={}){let grokNeoEnabled=options.grokNeoEnabled??isGrokNeoEnabled(),result={messages:[],fileArgs:[],unknownFlags:new Map,diagnostics:[]};if(args[0]==="app-server")return result.diagnostics.push({type:"error",message:`The app-server command has been removed. Use "${APP_NAME} --mode rpc" for process integration.`}),result;let hasRetiredCommand=!1;for(let i=0;i<args.length;i++){let arg=args[i];if(arg==="--"){for(let positionalArg of args.slice(i+1))positionalArg.startsWith("@")?result.fileArgs.push(positionalArg.slice(1)):result.messages.push(positionalArg);break}else if(arg==="--help"||arg==="-h")result.help=!0;else if(arg==="--version"||arg==="-v")result.version=!0;else if(arg==="--mode"){let mode=args[i+1];if(mode===void 0||mode.startsWith("-")){result.diagnostics.push({type:"error",message:"--mode requires text, json, or rpc"});continue}if(i++,mode!=="text"&&mode!=="json"&&mode!=="rpc"){result.diagnostics.push({type:"error",message:`Invalid mode "${mode}". Valid values: text, json, rpc`});continue}result.mode=mode}else if(arg==="--continue"||arg==="-c")result.continue=!0;else if(arg==="--resume"||arg==="-r")result.resume=!0;else if(arg==="--provider"&&i+1<args.length){let typedProvider=args[++i],rejection=typedProvider===void 0?void 0:legacyProviderIdRejection(typedProvider);if(rejection)throw new Error(rejection);result.provider=typedProvider}else if(arg==="--model"&&i+1<args.length)result.model=args[++i];else if(arg==="--api-key"&&i+1<args.length)result.apiKey=args[++i];else if(arg==="--system-prompt"&&i+1<args.length)result.systemPrompt=args[++i];else if(arg==="--append-system-prompt"&&i+1<args.length)result.appendSystemPrompt=result.appendSystemPrompt??[],result.appendSystemPrompt.push(args[++i]);else if(arg==="--name"||arg==="-n")i+1<args.length?result.name=args[++i]:result.diagnostics.push({type:"error",message:"--name requires a value"});else if(arg==="--no-session")result.noSession=!0;else if(arg==="--session"&&i+1<args.length)result.session=args[++i];else if(arg==="--session-id"&&i+1<args.length)result.sessionId=args[++i];else if(arg==="--spawned-by"){let value=args[i+1];if(value===void 0||value.startsWith("-"))result.diagnostics.push({type:"error",message:"--spawned-by requires a JSON object"});else{i++;try{let ancestry=JSON.parse(value);isSpawnedBy(ancestry)?result.spawnedBy=ancestry:result.diagnostics.push({type:"error",message:"--spawned-by requires non-empty parentSessionId, rootSessionId, and taskId strings"})}catch(error){if(!(error instanceof SyntaxError))throw error;result.diagnostics.push({type:"error",message:"--spawned-by must be valid JSON"})}}}else if(arg==="--fork"&&i+1<args.length)result.fork=args[++i];else if(arg==="--rebind"&&i+1<args.length)result.rebind=args[++i];else if(arg==="--session-dir"&&i+1<args.length)result.sessionDir=args[++i];else if(arg==="--models"&&i+1<args.length)result.models=args[++i].split(",").map(s=>s.trim());else if(arg==="--no-tools"||arg==="-nt")result.noTools=!0;else if(arg==="--no-builtin-tools"||arg==="-nbt")result.noBuiltinTools=!0;else if((arg==="--tools"||arg==="-t")&&i+1<args.length)result.tools=args[++i].split(",").map(s=>s.trim()).filter(name=>name.length>0);else if((arg==="--exclude-tools"||arg==="-xt")&&i+1<args.length)result.excludeTools=args[++i].split(",").map(s=>s.trim()).filter(name=>name.length>0);else if(arg==="--thinking"&&i+1<args.length){let level=args[++i];isValidThinkingLevel(level)?result.thinking=level:result.diagnostics.push({type:"warning",message:`Invalid thinking level "${level}". Valid values: ${VALID_THINKING_LEVELS.join(", ")}`})}else if(arg==="--print"||arg==="-p"){result.print=!0;let next=args[i+1];next!==void 0&&!next.startsWith("@")&&(!next.startsWith("-")||next.startsWith("---"))&&(result.messages.push(next),i++)}else if(arg==="--export"&&i+1<args.length)result.export=args[++i];else if((arg==="--extension"||arg==="-e")&&i+1<args.length)result.extensions=result.extensions??[],result.extensions.push(args[++i]);else if(arg==="--no-extensions"||arg==="-ne")result.noExtensions=!0;else if(arg==="--skill"&&i+1<args.length)result.skills=result.skills??[],result.skills.push(args[++i]);else if(arg==="--prompt-template"&&i+1<args.length)result.promptTemplates=result.promptTemplates??[],result.promptTemplates.push(args[++i]);else if(arg==="--theme"&&i+1<args.length)result.themes=result.themes??[],result.themes.push(args[++i]);else if(arg==="--use-theme"){let themeName=args[i+1];themeName===void 0||themeName.startsWith("-")?result.diagnostics.push({type:"error",message:"--use-theme requires a theme name"}):(result.useTheme=themeName,i++)}else if(arg==="--no-skills"||arg==="-ns")result.noSkills=!0;else if(arg==="--no-prompt-templates"||arg==="-np")result.noPromptTemplates=!0;else if(arg==="--no-themes")result.noThemes=!0;else if(arg==="--no-context-files"||arg==="-nc")result.noContextFiles=!0;else if(arg==="--print-prompt-sizes")result.printPromptSizes=!0;else if(arg==="--list-models")i+1<args.length&&!args[i+1].startsWith("-")&&!args[i+1].startsWith("@")?result.listModels=args[++i]:result.listModels=!0;else if(arg==="--list-tips")result.listTips=!0;else if(arg==="--tui-mode"){let mode=args[i+1];mode==="regular"||mode==="fullscreen"?(result.tuiMode=mode,i++):mode===void 0||mode.startsWith("-")?result.diagnostics.push({type:"error",message:"--tui-mode requires regular or fullscreen"}):(i++,result.diagnostics.push({type:"error",message:`Invalid TUI mode "${mode}". Valid values: regular, fullscreen`}))}else if(arg==="--verbose")result.verbose=!0;else if(arg==="--approve"||arg==="-a")result.projectTrustOverride=!0;else if(arg==="--no-approve"||arg==="-na")result.projectTrustOverride=!1;else if(arg==="--offline")result.offline=!0;else if(grokNeoEnabled&&arg==="--grok-neo")result.grokNeo=!0;else if(arg==="--multi-session")result.multiSession=!0;else if(arg==="--mcp-presenter-fd")args[++i]==="4"?result.presenterBootstrapFd=4:result.diagnostics.push({type:"error",message:"Invalid presenter bootstrap descriptor"});else if(arg==="--mcp-presenter-enforcement")result.mcpPresenterEnforcement=!0;else if(arg==="--auto-title-sessions")result.autoTitleSessions=!0;else if(arg==="--session-runtime"){let value=args[i+1];value!==void 0&&!value.startsWith("--")&&i++,value!==void 0&&isSessionRuntimeKind(value)?result.sessionRuntime=value:result.diagnostics.push({type:"error",message:"--session-runtime must be in-process or worker"})}else if(arg==="--tool-runtime"){let value=args[i+1];value!==void 0&&!value.startsWith("--")&&i++,value!==void 0&&isToolRuntimeKind(value)?result.toolRuntime=value:result.diagnostics.push({type:"error",message:"--tool-runtime must be in-process or child"})}else if(arg==="--listen"&&result.mode==="rpc"){let value=args[i+1];value===void 0||value.startsWith("--")?result.diagnostics.push({type:"error",message:"--listen requires a value"}):(result.listen=value,result.multiSession=!0,i++)}else if(arg.startsWith("@"))result.fileArgs.push(arg.slice(1));else if(arg.startsWith("--")){let eqIndex=arg.indexOf("=");if(eqIndex!==-1)result.unknownFlags.set(arg.slice(2,eqIndex),arg.slice(eqIndex+1));else{let flagName=arg.slice(2),next=args[i+1];next!==void 0&&!next.startsWith("-")&&!next.startsWith("@")?(result.unknownFlags.set(flagName,next),i++):result.unknownFlags.set(flagName,!0)}}else arg==="-"?result.readStdin=!0:arg.startsWith("-")&&!arg.startsWith("--")?result.diagnostics.push({type:"error",message:`Unknown option: ${arg}`}):arg.startsWith("-")||(result.messages.length===0&&arg==="app-server"&&(hasRetiredCommand=!0),result.messages.push(arg))}return hasRetiredCommand&&result.mode===void 0&&!result.print&&(result.messages=[],result.diagnostics.push({type:"error",message:`The app-server command has been removed. Use "${APP_NAME} --mode rpc" for process integration.`})),result}function printHelp(extensionFlags,grokNeoEnabled=isGrokNeoEnabled()){let extensionFlagsText=extensionFlags&&extensionFlags.length>0?`
|
|
3
3
|
${source_default.bold("Extension CLI Flags:")}
|
|
4
4
|
${extensionFlags.map(flag=>{let value=flag.type==="string"?" <value>":"",description=flag.description??`Registered by ${flag.extensionPath}`;return` --${flag.name}${value}`.padEnd(30)+description}).join(`
|
|
5
5
|
`)}
|
|
@@ -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{HOST_DAEMON_DIR_ENV,HOST_DAEMON_LAYOUT,ageOf,createGenerationDirectory,createHostDaemonPaths,generationPaths,hostDaemonDirectoryPaths,isRecord,parseJson,readFileOrUndefined,readJsonObject,sameEndpoint,writeJsonAtomic,writeStateFile}from"./chunk-4WZRVZNX.js";import{HOST_INSTANCE_ID_ENV}from"./chunk-
|
|
2
|
+
import{HOST_DAEMON_DIR_ENV,HOST_DAEMON_LAYOUT,ageOf,createGenerationDirectory,createHostDaemonPaths,generationPaths,hostDaemonDirectoryPaths,isRecord,parseJson,readFileOrUndefined,readJsonObject,sameEndpoint,writeJsonAtomic,writeStateFile}from"./chunk-4WZRVZNX.js";import{HOST_INSTANCE_ID_ENV}from"./chunk-GWGNVYPB.js";import{ProcessIdentityUnreadableError,parseDaemonPidFile,processIsLive,processIsRunning,processMatchesPidFile,processStartTimeMs,readProcessIdentity,readProcessStartTime,sameProcessStartMs}from"./chunk-O5RYI3IW.js";var HOST_COLD_START_ENV="SENPI_RPC_HOST_COLD_START",HOST_IDLE_EXIT_MS_ENV="SENPI_RPC_HOST_IDLE_EXIT_MS",DEFAULT_HOST_IDLE_EXIT_MS=9e5,HANDOFF_GRACE_MS_ENV="SENPI_RPC_HANDOFF_GRACE_MS",DEFAULT_HANDOFF_GRACE_MS=6e5;function parseColdStart(value){return value==="transient"||value==="persistent"?value:void 0}function parseIdleExitMs(value){if(value===void 0||!/^\d+$/.test(value.trim()))return;let parsed=Number(value.trim());return Number.isFinite(parsed)&&parsed>0?parsed:void 0}function resolveHostPolicy(settings,env){let record=isRecord2(settings)?settings:{},coldStart=parseColdStart(env[HOST_COLD_START_ENV])??parseColdStart(asOptionalString(record.coldStart))??"transient",idleExitMs=parseIdleExitMs(env[HOST_IDLE_EXIT_MS_ENV])??parseIdleExitMs(asOptionalString(record.idleExitMs))??9e5;return{coldStart,idleExitMs}}var IdleExitDecider=class{constructor(idleExitMs,now=Date.now){this.idleExitMs=idleExitMs,this.now=now}update(activity){return activity.connections>0||activity.activeTurns>0?(this.idleSince=void 0,"active"):this.idleExitMs===Number.POSITIVE_INFINITY?"idle":this.idleSince===void 0?(this.idleSince=this.now(),"idle"):this.now()-this.idleSince>=this.idleExitMs?"exit":"idle"}};function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function asOptionalString(value){return typeof value=="string"?value:typeof value=="number"?String(value):void 0}import{writeSync}from"node:fs";function writeStderrLine(text){try{writeSync(2,`${text}
|
|
3
3
|
`)}catch{}}function supervisorLog(message){writeStderrLine(`senpi rpc host supervisor: ${message}`)}function writeHostReady(socket,coldStart,idleExitMs){writeStderrLine(`senpi rpc host ready on unix://${socket} (coldStart=${coldStart}, idleExitMs=${coldStart==="persistent"?"never":String(idleExitMs)})`)}var loggedUnknownIdentities=new Set;function logUnknownHostIdentity(record,pid){let key=`${record}:${pid}`;loggedUnknownIdentities.has(key)||(loggedUnknownIdentities.add(key),writeStderrLine(JSON.stringify({event:"legacy_host_identity_unknown",record,pid})))}function errorMessage(cause){return cause instanceof Error?cause.message:String(cause)}import{createHash}from"node:crypto";import{mkdir,readdir,readFile,rename,rm as rm2,writeFile}from"node:fs/promises";import{join as join2}from"node:path";import{rm,stat}from"node:fs/promises";import{isAbsolute,join}from"node:path";var STALL_REFUSAL_WINDOW_MS_ENV="SENPI_RPC_STALL_REFUSAL_MS",DEFAULT_STALL_REFUSAL_WINDOW_MS=12e4,STOP_STALL_EVIDENCE_MAX_AGE_MS=6e4,CHILD_STALLED_STOP_MAX_MS_ENV="SENPI_RPC_CHILD_STALLED_STOP_MAX_MS",DEFAULT_CHILD_STALLED_STOP_MAX_MS=6e4;function childStalledStopMaxMs(env=process.env){return parseIdleExitMs(env[CHILD_STALLED_STOP_MAX_MS_ENV])??DEFAULT_CHILD_STALLED_STOP_MAX_MS}function ownGenerationDir(env){let daemonDir=env[HOST_DAEMON_DIR_ENV],instanceId=env[HOST_INSTANCE_ID_ENV];if(!(!daemonDir||!instanceId))return join(daemonDir,"generations",instanceId)}function stallRefusalWindowMs(env=process.env){return parseIdleExitMs(env[STALL_REFUSAL_WINDOW_MS_ENV])??DEFAULT_STALL_REFUSAL_WINDOW_MS}function writeStallEvidence(generationDir,evidence){return writeJsonAtomic(join(generationDir,"host-stalled.json"),evidence)}function writeHeartbeat(generationDir,at){return writeJsonAtomic(join(generationDir,"host-alive.json"),{at})}async function readStallEvidence(generation){let raw=await readJsonObject(generation.stalledFile);if(!(raw===void 0||typeof raw.at!="string"||typeof raw.driftMs!="number"))return{at:raw.at,driftMs:raw.driftMs,processCpuMs:typeof raw.processCpuMs=="number"?raw.processCpuMs:0,heapDeltaMb:typeof raw.heapDeltaMb=="number"?raw.heapDeltaMb:0,...typeof raw.sessionId=="string"?{sessionId:raw.sessionId}:{},...typeof raw.tool=="string"?{tool:raw.tool}:{}}}async function recentStall(generation,now,maxAgeMs){let evidence=await readStallEvidence(generation),age=ageOf(evidence?.at,now);return evidence!==void 0&&age!==void 0&&age<=maxAgeMs?evidence:void 0}async function hostLoopStalled(generation,options){if(await recentStall(generation,options.now,options.windowMs)!==void 0)return!0;let heartbeatAge=ageOf((await readJsonObject(generation.aliveFile))?.at,options.now);return heartbeatAge!==void 0&&heartbeatAge>options.errorMs&&heartbeatAge<options.windowMs}async function generationHeartbeatStopped(generation,now=Date.now()){let age=ageOf((await readJsonObject(generation.aliveFile))?.at,now);return age!==void 0&&age>=stallRefusalWindowMs()}var SAFE_INSTANCE_ID=/^[A-Za-z0-9_-]+$/;async function exists(path){return stat(path).then(()=>!0,()=>!1)}async function holderGenerationEnded(holder,env=process.env){let instance=holder.host_instance;if(instance===void 0||!SAFE_INSTANCE_ID.test(instance)||instance===env[HOST_INSTANCE_ID_ENV])return!1;let daemonDir=holder.host_daemon_dir??env[HOST_DAEMON_DIR_ENV];if(daemonDir===void 0||!isAbsolute(daemonDir))return!1;let directory=hostDaemonDirectoryPaths(daemonDir),generation=generationPaths(directory,instance);return await generationHeartbeatStopped(generation)?!0:holder.host_daemon_dir!==void 0&&await exists(directory.endpointFile)&&!await exists(generation.dir)}async function hostChildAlive(generation){let record=await readJsonObject(generation.childPidFile),pid=record?.pid;if(typeof pid!="number"||!Number.isInteger(pid)||pid<=0)return;if(!processIsLive(pid))return!1;let observed=await readProcessIdentity(pid,process.platform,1e3,processIsLive,"UTC");if(observed.kind==="absent"||!processIsLive(pid))return!1;let recordedMs=typeof record?.processStartTime=="string"?processStartTimeMs(record.processStartTime):void 0,observedMs=observed.kind==="present"?processStartTimeMs(observed.identity):void 0;return recordedMs!==void 0&&observedMs!==void 0?sameProcessStartMs(recordedMs,observedMs):await generationHeartbeatStopped(generation)?(supervisorLog(`host child pid ${pid} start time unreadable and its heartbeat stopped; releasing generation`),!1):(supervisorLog(`host child pid ${pid} start time unreadable; preserving generation`),!0)}function writeStopProgress(generation,progress){return writeJsonAtomic(generation.stopProgressFile,progress)}async function clearStopProgress(generation){await rm(generation.stopProgressFile,{force:!0}).catch(()=>{})}async function activeStopProgress(generation,now,freshMs){let raw=await readJsonObject(generation.stopProgressFile),age=ageOf(raw?.at,now),untilAt=typeof raw?.untilAt=="string"?Date.parse(raw.untilAt):Number.NaN;if(!(age===void 0||age>freshMs||Number.isNaN(untilAt)||untilAt<=now))return untilAt}var SESSION_PATH_RETRY_AFTER_MS=2e3;function reservationFile(dir,sessionPath){return join2(dir,`${createHash("sha256").update(sessionPath,"utf8").digest("hex").slice(0,16)}.json`)}function createEndpointReservations(host){let told=process.env[HOST_DAEMON_DIR_ENV],dir=told!==void 0&&told.trim()!==""?told:host.socket===void 0?void 0:createHostDaemonPaths({socket:host.socket,agentDir:host.agentDir}).dir;if(dir!==void 0)return createSessionPathReservations({daemonDir:dir,instanceId:host.instanceId,...host.publicSocket===void 0?{}:{publicSocket:host.publicSocket},...host.onFailure?{onFailure:host.onFailure}:{}})}function createSessionPathReservations(options){let paths=hostDaemonDirectoryPaths(options.daemonDir),dir=paths.reservationsDir,pid=options.pid??process.pid,startTime=readProcessStartTime(pid).then(value=>value??null,()=>null),held=new Set,updates=new Map,report=message=>options.onFailure?.(message),publish=async(sessionPath,attached,stillHeld)=>{let owner={instanceId:options.instanceId,...options.publicSocket===void 0?{}:{host_socket:options.publicSocket},pid,processStartTime:await startTime,sessionPath,attached},file=reservationFile(dir,sessionPath);await mkdir(dir,{recursive:!0,mode:448});let staging=`${file}.${pid}.tmp`;if(await writeFile(staging,`${JSON.stringify(owner)}
|
|
4
4
|
`,{mode:384}),stillHeld?.()===!1){await rm2(staging,{force:!0});return}await rename(staging,file)};return{async holderPids(observedStarts){let candidates=(await readSessionPathClaims(dir)).map(({owner})=>owner),generations=await readdir(paths.generationsDir,{withFileTypes:!0}).catch(()=>[]);for(let generation of generations){if(!generation.isDirectory())continue;let record=parseJson(await readFileOrUndefined(join2(paths.generationsDir,generation.name,"host-child.pid")));typeof record?.pid=="number"&&candidates.push({pid:record.pid,processStartTime:typeof record.processStartTime=="string"?record.processStartTime:null,instanceId:generation.name,sessionPath:""})}let byPid=new Map;for(let owner of candidates){if(owner.pid===process.pid)continue;let owners=byPid.get(owner.pid)??[];owners.push(owner),byPid.set(owner.pid,owners)}let live=await Promise.all([...byPid].map(async([pid2,owners])=>{if(!processIsLive(pid2))return;if(observedStarts){if(!observedStarts.has(pid2))return;let observed2=observedStarts.get(pid2);return owners.some(owner=>owner.processStartTime===null?!1:sameProcessStartMs(processStartTimeMs(owner.processStartTime),observed2))?pid2:void 0}let current=await readProcessStartTime(pid2,process.platform,1e3).catch(()=>{}),observed=current===void 0?void 0:processStartTimeMs(current);return observed!==void 0&&owners.some(owner=>owner.processStartTime!==null&&sameProcessStartMs(processStartTimeMs(owner.processStartTime),observed))?pid2:void 0}));return[...new Set(live.filter(value=>value!==void 0))]},async claim(sessionPath,attached=!0){let existing=await readOwner(reservationFile(dir,sessionPath));if(existing&&existing.pid!==pid){let verdict=await standingOwner(existing,paths);if(verdict.kind==="stands")return verdict.owner;if(!(verdict.kind==="released"||await import("./session-write-fence-66EMOO4Y.js").then(({advanceSessionFence})=>advanceSessionFence(sessionPath)).then(()=>!0,cause=>(report(`session file ${sessionPath} could not be fenced for a takeover (${errorMessage2(cause)})`),!1))))return{...existing,current:!1}}try{await publish(sessionPath,attached),held.add(sessionPath)}catch(cause){report(`session path reservation for ${sessionPath} could not be written (${errorMessage2(cause)})`)}},async release(sessionPath){held.delete(sessionPath)&&(await updates.get(sessionPath),updates.delete(sessionPath),await rm2(reservationFile(dir,sessionPath),{force:!0}).catch(cause=>{report(`session path reservation for ${sessionPath} could not be removed (${errorMessage2(cause)})`)}))},setAttached(sessionPath,attached){if(!held.has(sessionPath))return;let update=(updates.get(sessionPath)??Promise.resolve()).then(()=>publish(sessionPath,attached,()=>held.has(sessionPath))).catch(cause=>{report(`session path reservation for ${sessionPath} could not be updated (${errorMessage2(cause)})`)});updates.set(sessionPath,update)}}}async function readSessionPathClaims(dir){let entries=await readdir(dir).catch(()=>[]),claims=[];for(let entry of entries){if(!entry.endsWith(".json"))continue;let file=join2(dir,entry),owner=await readOwner(file);owner&&claims.push({file,owner})}return claims}async function standingOwner(owner,paths){let identity=await claimOwnerIdentity(owner);if(identity==="gone")return{kind:"released"};let current=await currentInstanceId(paths.pointerFile)===owner.instanceId;return!current&&identity==="unproven"&&await heartbeatStopped(paths,owner.instanceId)?{kind:"presumed_done"}:current||owner.attached!==!1?{kind:"stands",owner:{...owner,current}}:{kind:"released"}}async function heartbeatStopped(paths,instanceId){return instanceId===""||instanceId==="."||instanceId===".."||/[\\/]/.test(instanceId)?!1:generationHeartbeatStopped(generationPaths(paths,instanceId))}async function currentInstanceId(pointerFile){let pointer=parseJson(await readFileOrUndefined(pointerFile).catch(()=>{}));return typeof pointer?.instance_id=="string"?pointer.instance_id:void 0}async function readOwner(file){let parsed;try{parsed=JSON.parse(await readFile(file,"utf8"))}catch{return}if(typeof parsed!="object"||parsed===null)return;let{instanceId,pid,processStartTime,sessionPath,attached,host_socket}=parsed;if(!(typeof instanceId!="string"||typeof pid!="number"||typeof sessionPath!="string"))return{instanceId,pid,processStartTime:typeof processStartTime=="string"?processStartTime:null,sessionPath,...typeof host_socket=="string"?{host_socket}:{},...typeof attached=="boolean"?{attached}:{}}}async function claimOwnerIsLive(owner){return await claimOwnerIdentity(owner)!=="gone"}async function claimOwnerIdentity(owner){if(!processIsRunning(owner.pid))return"gone";let recorded=owner.processStartTime===null?void 0:processStartTimeMs(owner.processStartTime);if(recorded===void 0)return logUnknownHostIdentity("session-path-claim",owner.pid),"unproven";let current=await readProcessStartTime(owner.pid).catch(()=>{}),observed=current===void 0?void 0:processStartTimeMs(current);return observed===void 0?"unproven":sameProcessStartMs(recorded,observed)?"proven":"gone"}function errorMessage2(cause){return cause instanceof Error?cause.message:String(cause)}import{rename as rename3,rm as rm4}from"node:fs/promises";import{randomUUID}from"node:crypto";import{link,readdir as readdir3,rename as rename2,rm as rm3}from"node:fs/promises";import{readdir as readdir2}from"node:fs/promises";import{readdirSync,readFileSync}from"node:fs";function supportedPlatform(platform){return platform==="darwin"||platform==="linux"?platform:void 0}async function loadProcessTableReader(platform=process.platform,options={}){let supported=supportedPlatform(platform);return supported===void 0||typeof globalThis.Bun>"u"?void 0:supported==="darwin"?await darwinReader(options):linuxReader}var KINFO_PROC_STRIDE=648,KINFO_PID_OFFSET=40,KINFO_PPID_OFFSET=560,KINFO_STAT_OFFSET=36,SZOMB=5,PROC_PIDTASKINFO=4,TASKINFO_RESIDENT_OFFSET=8,TABLE_START_BYTES=1<<20,TABLE_MAX_BYTES=32<<20;function parseKernelProcessTable(table,rowCount,residentKb){if(rowCount<=0||table.byteLength<rowCount*KINFO_PROC_STRIDE)return;let view=new DataView(table.buffer,table.byteOffset,table.byteLength),rows=[],selfSeen=!1;for(let index=0;index<rowCount;index++){let base=index*KINFO_PROC_STRIDE,pid=view.getUint32(base+KINFO_PID_OFFSET,!0);if(!Number.isInteger(pid)||pid<=0)continue;let ppid=view.getUint32(base+KINFO_PPID_OFFSET,!0),zombie=table[base+KINFO_STAT_OFFSET]===SZOMB;if(pid===process.pid){if(ppid!==process.ppid||zombie)return;selfSeen=!0}rows.push({pid,ppid,state:zombie?"Z":"U",rssKb:residentKb(pid)})}return selfSeen?rows:void 0}async function darwinReader(options){let{dlopen,FFIType,ptr}=await import("bun:ffi"),library=dlopen("libSystem.B.dylib",{sysctl:{args:[FFIType.ptr,FFIType.u32,FFIType.ptr,FFIType.ptr,FFIType.ptr,FFIType.i32],returns:FFIType.i32},proc_pidinfo:{args:[FFIType.i32,FFIType.i32,FFIType.u32,FFIType.ptr,FFIType.i32],returns:FFIType.i32}}),mib=new Int32Array([1,14,0]),none=new Uint8Array(1),requested=options.initialTableBytes,table=new Uint8Array(Number.isFinite(requested)&&requested!==void 0&&requested>0?Math.min(Math.floor(requested),TABLE_MAX_BYTES):TABLE_START_BYTES),length=new Uint32Array(1),taskInfo=new Uint8Array(256),taskView=new DataView(taskInfo.buffer),residentKb=pid=>(taskInfo.fill(0),library.symbols.proc_pidinfo(pid,PROC_PIDTASKINFO,0,ptr(taskInfo),taskInfo.byteLength)>0?Math.round(Number(taskView.getBigUint64(TASKINFO_RESIDENT_OFFSET,!0))/1024):0);return()=>{for(;;){if(length[0]=table.byteLength,library.symbols.sysctl(ptr(mib),mib.length,ptr(table),ptr(length),ptr(none),0)!==0){if(table.byteLength>=TABLE_MAX_BYTES)return;let reported=length[0]>table.byteLength?length[0]:0;table=new Uint8Array(Math.min(TABLE_MAX_BYTES,Math.max(table.byteLength*2,reported)));continue}return parseKernelProcessTable(table,Math.floor(length[0]/KINFO_PROC_STRIDE),residentKb)}}}function linuxReader(){let rows=[];for(let entry of readdirSync("/proc")){let pid=Number(entry);if(!Number.isInteger(pid)||pid<=0)continue;let stat3;try{stat3=readFileSync(`/proc/${pid}/stat`,"utf8")}catch{continue}let tail=stat3.slice(stat3.lastIndexOf(")")+2).split(" "),state=tail[0],ppid=Number(tail[1]);if(state===void 0||!Number.isInteger(ppid))continue;let rssPages=Number(tail[21]);rows.push({pid,ppid,state,rssKb:Number.isFinite(rssPages)?Math.round(rssPages*4):0})}return rows}var UNOBSERVED={rss_mb:null,host_rss_mb:null,host_footprint_mb:null,open_fds:null,zombies:null},readers=new Map,footprintReader;function loadFootprintReader(){return footprintReader??=import("./process-footprint-SOBYQLMN.js").then(module=>module.readProcessFootprint),footprintReader}function tableReader(platform){let cached=readers.get(platform);if(cached!==void 0)return cached;let loading=loadProcessTableReader(platform);return readers.set(platform,loading),loading}async function readHostProcessMetrics(pid,platform=process.platform){if(platform==="win32")return UNOBSERVED;let read=await tableReader(platform);if(read===void 0)return UNOBSERVED;let rows=read();if(rows===void 0)return UNOBSERVED;let tree=descendants(rows,pid);if(tree.length===0)return UNOBSERVED;let hostRows=tree.filter(row=>row.pid===pid||row.ppid===pid);return{rss_mb:residentMegabytes(tree),host_rss_mb:residentMegabytes(hostRows),host_footprint_mb:footprintMegabytes(hostRows,await loadFootprintReader()),open_fds:platform==="linux"?await openDescriptors(tree):null,zombies:tree.filter(row=>row.state.startsWith("Z")).length}}function residentMegabytes(rows){return Math.round(rows.reduce((total,row)=>total+row.rssKb,0)/KILOBYTES_PER_MEGABYTE)}function footprintMegabytes(rows,readProcessFootprint){let bytes=0;for(let row of rows){let reading=readProcessFootprint(row.pid);if(reading===void 0)return null;bytes+=reading.bytes}return Math.round(bytes/BYTES_PER_MEGABYTE)}var BYTES_PER_MEGABYTE=1024*1024;function descendants(rows,root){let tree=rows.filter(row=>row.pid===root);if(tree.length===0)return tree;for(let index=0;index<tree.length;index++){let parent=tree[index].pid;for(let row of rows)row.ppid===parent&&!tree.includes(row)&&tree.push(row)}return tree}var KILOBYTES_PER_MEGABYTE=1024;async function openDescriptors(tree){let total=0,counted=!1;for(let row of tree){let entries=await readdir2(`/proc/${row.pid}/fd`).catch(()=>{});entries!==void 0&&(counted=!0,total+=entries.length)}return counted?total:null}async function pruneDeadGenerations(paths,options={}){let pointerText=await readFileOrUndefined(paths.pointerFile).catch(()=>{}),pointer=parseJson(pointerText),pointedAt=typeof pointer?.instance_id=="string"?pointer.instance_id:void 0,generations=[];for(let instanceId of await readdir3(paths.generationsDir).catch(()=>[])){let record=parseJson(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));typeof record?.pid!="number"||processIsLive(record.pid)||await hostChildAlive(generationPaths(paths,instanceId))||generations.push(instanceId)}let claims=await endClaimsOfEndedGenerations(paths,new Set(generations));for(let instanceId of generations)await rm3(generationPaths(paths,instanceId).dir,{recursive:!0,force:!0}).catch(()=>{});let pointerNamesDead=pointerText!==void 0&&pointedAt!==void 0&&generations.includes(pointedAt);pointerNamesDead&&await options._test?.beforePointerRemoval?.();let pointerRemoved=pointerNamesDead&&await removePointerIfUnchanged(paths,pointerText);return{generations,claims,pointer:pointerRemoved}}async function removePointerIfUnchanged(paths,read){let parked=`${paths.pointerFile}.prune-${process.pid}-${randomUUID()}.tmp`;if(!await rename2(paths.pointerFile,parked).then(()=>!0,()=>!1))return!1;let unchanged=await readFileOrUndefined(parked).catch(()=>{})===read;return unchanged||await link(parked,paths.pointerFile).catch(()=>{}),await rm3(parked,{force:!0}).catch(()=>{}),unchanged}async function endClaimsOfEndedGenerations(paths,ended){let claims=[];for(let claim of await readSessionPathClaims(paths.reservationsDir))await claimEnded(claim.owner,ended)&&(await rm3(claim.file,{force:!0}).catch(()=>{}),claims.push(claim.owner.sessionPath));return claims}async function claimEnded(owner,ended){let identity=await claimOwnerIdentity(owner);return identity==="gone"?!0:identity==="proven"||!ended.has(owner.instanceId)?!1:import("./session-write-fence-66EMOO4Y.js").then(({advanceSessionFence})=>advanceSessionFence(owner.sessionPath)).then(()=>!0,()=>!1)}function memoryOf(metrics){return{rss_mb:metrics.rss_mb,host_rss_mb:metrics.host_rss_mb}}async function readGenerationRows(paths,options={}){let pointer=parseJson(await readFileOrUndefined(paths.pointerFile).catch(()=>{})),currentId=typeof pointer?.instance_id=="string"?pointer.instance_id:void 0,claims=await readSessionPathClaims(paths.reservationsDir),rows=[];for(let instanceId of await readdir3(paths.generationsDir).catch(()=>[])){let record=parseJson(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));if(typeof record?.pid!="number")continue;let alive=processIsLive(record.pid)||await hostChildAlive(generationPaths(paths,instanceId))===!0;!alive&&options.includeDead!==!0||rows.push({instanceId,generation:typeof record.generation=="number"?record.generation:0,pid:record.pid,engineVersion:typeof record.engineVersion=="string"?record.engineVersion:null,...alive?memoryOf(await readHostProcessMetrics(record.pid)):{rss_mb:null,host_rss_mb:null},sessions:claims.filter(claim=>claim.owner.instanceId===instanceId).length,current:instanceId===currentId,alive})}return rows.sort((left,right)=>left.generation-right.generation)}async function readHostRegistration(paths){let pointer=parseJson(await readFileOrUndefined(paths.pointerFile));if(!(!pointer||typeof pointer.instance_id!="string"))return readGenerationRegistration(paths,pointer.instance_id)}async function readGenerationRegistration(paths,instanceId){let text=await readFileOrUndefined(generationPaths(paths,instanceId).pidFile),record=text===void 0?void 0:parseDaemonPidFile(text);if(record===void 0)return;let parsed=parseJson(text)??{},writer=parseWriter(parsed);return{record,...writer&&{writer},...typeof parsed.socket=="string"&&{socket:parsed.socket},instanceId,generation:typeof parsed.generation=="number"?parsed.generation:0}}async function writeHostRegistration(paths,registration,options={}){options.fresh!==!0&&await pruneDeadGenerations(paths);let{generation,writer}=await writeGenerationRecord(paths,registration);await writeStateFile(`${paths.pointerFile}.${process.pid}.tmp`,{layout:HOST_DAEMON_LAYOUT,instance_id:registration.instanceId,generation_dir:generation.relativeDir,writer}),await rename3(`${paths.pointerFile}.${process.pid}.tmp`,paths.pointerFile)}async function writeGenerationRecord(paths,registration){let generation=generationPaths(paths,registration.instanceId),writer={pid:process.pid,startTime:await thisProcessStartTime()},{build}=registration;return await createGenerationDirectory(generation),await writeStateFile(generation.pidFile,{...registration.record,instance_id:registration.instanceId,generation:registration.generation,...build&&{engineVersion:build.text,engineOrdinal:build.ordinal},launchProfileId:registration.launchProfileId,socket:registration.socket,writer}),{generation,writer}}async function clearHostRegistration(paths){let pointer=parseJson(await readFileOrUndefined(paths.pointerFile));if(typeof pointer?.instance_id=="string"){if(await hostChildAlive(generationPaths(paths,pointer.instance_id)))throw new Error(`refusing to clear generation ${pointer.instance_id} with a live host child`);await endClaimsOfEndedGenerations(paths,new Set([pointer.instance_id])),await rm4(generationPaths(paths,pointer.instance_id).dir,{recursive:!0,force:!0})}await rm4(paths.settingsFile,{force:!0}),await rm4(paths.pointerFile,{force:!0})}async function releaseGeneration(paths,owner){let generation=generationPaths(paths,owner.instanceId);if(await hostChildAlive(generation))return;let record=parseDaemonPidFile(await readFileOrUndefined(generation.pidFile)??"");if(record!==void 0&&record.pid!==owner.pid)return;if(owner.superseded===!0){await rm4(generation.dir,{recursive:!0,force:!0});return}let ownsPointer=parseJson(await readFileOrUndefined(paths.pointerFile))?.instance_id===owner.instanceId;ownsPointer&&await rm4(paths.settingsFile,{force:!0}),await rm4(generation.dir,{recursive:!0,force:!0}),ownsPointer&&await rm4(paths.pointerFile,{force:!0})}async function provenOwner(registered,socket){let record=registered?.record;if(!record||registered?.socket!==void 0&&!sameEndpoint(registered.socket,socket))return;if(record.processStartTime===null){processIsLive(record.pid)&&logUnknownHostIdentity("host.pid",record.pid);return}let identity={pid:record.pid,processStartTime:record.processStartTime};return await processMatchesPidFile(identity,readProcessStartTime).catch(error=>(error instanceof ProcessIdentityUnreadableError&&logUnknownHostIdentity("host.pid",identity.pid),!1))?{...identity,instanceId:registered.instanceId}:void 0}async function writtenByThisProcess(writer,readStartTime){if(writer===void 0||writer.pid!==process.pid||writer.startTime===null)return!1;let startTime=readStartTime?await readStartTime(process.pid).then(value=>value??null,()=>null):await thisProcessStartTime();return sameProcessStartMs(processStartTimeMs(writer.startTime),startTime===null?void 0:processStartTimeMs(startTime))}var selfStartTime;function thisProcessStartTime(){return selfStartTime??=readProcessStartTime(process.pid).then(value=>value??null,()=>null),selfStartTime}function isGenerationId(instanceId){return/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(instanceId)&&!instanceId.includes("..")}function parseWriter(parsed){if(!isRecord(parsed.writer)||typeof parsed.writer.pid!="number")return;let{pid,startTime}=parsed.writer;return{pid,startTime:typeof startTime=="string"?startTime:null}}import{randomUUID as randomUUID2}from"node:crypto";import{watch}from"node:fs";import{readFile as readFile2,rm as rm5}from"node:fs/promises";import{basename,dirname}from"node:path";var STOP_INTENT_MAX_AGE_MS=12e4,CHILD_STOP_TIMEOUT_MS=5e3,CHILD_KILL_EXIT_TIMEOUT_MS=3e4,SENDER_KINDS=new Set(["ensure","supervisor","stop","successor","handoff"]);async function writeStopIntent(generation,intent,log=message=>{process.stderr.write(`${message}
|
|
5
5
|
`)}){try{await writeJsonAtomic(generation.stopIntentFile,intent)}catch(cause){log(`could not record the stop intent for ${generation.dir}: ${cause instanceof Error?cause.message:cause}`)}}async function readStopIntent(generation,options={}){let raw=await readJsonObject(generation.stopIntentFile);if(raw===void 0)return;let intent=parseStopIntent(raw),age=ageOf(raw.at,options.now??Date.now());if(intent!==void 0&&age!==void 0&&age<=(options.maxAgeMs??STOP_INTENT_MAX_AGE_MS))return intent;await clearStopIntent(generation)}async function consumeStopIntent(generation,now=Date.now()){let intent=await readStopIntent(generation,{now});return intent!==void 0&&await clearStopIntent(generation),intent}async function clearStopIntent(generation){await rm5(generation.stopIntentFile,{force:!0}).catch(()=>{})}function layeredSupervisorIntent(outer,supervisor,stop){return outer===void 0?{sender:supervisor,signal:"SIGTERM",...stop}:{sender:outer.sender,chain:[...outer.chain??[outer.sender],supervisor],targetPid:stop.targetPid,reason:`${outer.reason} -> ${stop.reason}`,signal:"SIGTERM",at:stop.at}}function parseStopIntent(raw){let sender=parseSender(raw.sender),chain=Array.isArray(raw.chain)?raw.chain.map(parseSender):void 0;if(!(sender===void 0||chain?.some(entry=>entry===void 0))&&!(typeof raw.reason!="string"||typeof raw.at!="string"))return{sender,...chain?{chain:chain.filter(entry=>entry!==void 0)}:{},targetPid:typeof raw.targetPid=="number"?raw.targetPid:0,reason:raw.reason,signal:typeof raw.signal=="string"?raw.signal:"SIGTERM",at:raw.at}}function parseSender(value){if(typeof value!="object"||value===null)return;let pid=Reflect.get(value,"pid"),kind=Reflect.get(value,"kind"),generation=Reflect.get(value,"generation");if(!(typeof pid!="number"||typeof kind!="string"||!isSenderKind(kind)))return{pid,kind,...typeof generation=="string"?{generation}:{}}}function isSenderKind(kind){return SENDER_KINDS.has(kind)}var DRAIN_REQUEST_POLL_MS=1e3,DRAIN_REQUEST_WATCHED_POLL_MS=5e3;async function writeDrainRequest(file,request){let record={...request,at:new Date().toISOString(),nonce:randomUUID2()};await writeJsonAtomic(file,record)}function watchDrainRequest(file,onRequest,options={}){let stopped=!1,timer,watcher,polling=!1,lastNonce,poll=()=>{stopped||polling||(polling=!0,readDrainRequest(file).then(request=>{stopped||request===void 0||request.nonce===lastNonce||(lastNonce=request.nonce,onRequest(request))},ignore).finally(()=>{polling=!1}))},schedule=intervalMs=>{timer!==void 0&&clearInterval(timer),timer=setInterval(poll,options.pollMs??intervalMs),timer.unref?.()},name=basename(file);try{watcher=watch(dirname(file),{persistent:!1},(_event,changed)=>{(changed===null||changed===name)&&poll()}),watcher.on("error",()=>{watcher?.close(),watcher=void 0,stopped||schedule(DRAIN_REQUEST_POLL_MS)})}catch{watcher=void 0}return schedule(watcher===void 0?DRAIN_REQUEST_POLL_MS:DRAIN_REQUEST_WATCHED_POLL_MS),poll(),()=>{stopped=!0,timer!==void 0&&clearInterval(timer),watcher?.close()}}async function readDrainRequest(file){let raw=await readJsonObject(file);if(raw===void 0)return;let sender=parseSender(raw.sender);if(sender!==void 0&&!(typeof raw.reason!="string"||typeof raw.at!="string"||typeof raw.nonce!="string"))return{sender,reason:raw.reason,at:raw.at,nonce:raw.nonce}}async function writeDrainWatch(file,watch2){await writeJsonAtomic(file,{...watch2,at:new Date().toISOString()})}async function readDrainWatch(file){let raw=await readFileOrUndefined2(file);if(raw!==void 0)try{let parsed=JSON.parse(raw),pid=typeof parsed=="object"&&parsed!==null?Reflect.get(parsed,"pid"):void 0;return typeof pid=="number"&&Number.isInteger(pid)&&pid>0?{pid}:void 0}catch{return}}function hostChildDrainRequestFile(env=process.env){let daemonDir=env[HOST_DAEMON_DIR_ENV],instanceId=env[HOST_INSTANCE_ID_ENV];if(!(!daemonDir||!instanceId))return generationPaths(hostDaemonDirectoryPaths(daemonDir),instanceId).childDrainRequestFile}async function readFileOrUndefined2(file){try{return await readFile2(file,"utf8")}catch{return}}function ignore(){}import{stat as stat2}from"node:fs/promises";var LegacyLockArtifactError=class extends Error{constructor(lockPath){super(`Legacy lock directory is present at ${lockPath}`),this.code="ELEGACY_LOCK_ARTIFACT",this.name="LegacyLockArtifactError",this.lockPath=lockPath}},DEFAULT_RETRIES={retries:100,minTimeout:20,maxTimeout:100};async function openLockDatabase(lockPath){if(typeof globalThis.Bun<"u"){let{Database}=await import("bun:sqlite"),database2=new Database(lockPath,{create:!0});return{exec:sql=>database2.exec(sql),close:()=>database2.close(!1)}}let{DatabaseSync}=await import("node:sqlite"),database=new DatabaseSync(lockPath);return{exec:sql=>database.exec(sql),close:()=>database.close()}}async function acquireOwnershipSafeLock(lockPath,options={}){let retries=options.retries??DEFAULT_RETRIES,deadline=Date.now()+retries.retries*retries.maxTimeout;for(;;){await rejectLegacyDirectory(lockPath);let busyMs=Math.max(1,Math.min(retries.maxTimeout,deadline-Date.now())),database;try{database=await openLockDatabase(lockPath),database.exec(`PRAGMA busy_timeout = ${busyMs}; BEGIN EXCLUSIVE;`);let released=!1,held=database;return async()=>{if(!released){released=!0;try{held.exec("COMMIT;")}finally{held.close()}}}}catch(error){try{database?.close()}catch{}if(await rejectLegacyDirectory(lockPath),isBusy(error)&&Date.now()<deadline){await new Promise(resolve=>setTimeout(resolve,Math.min(retries.minTimeout,Math.max(1,deadline-Date.now()))));continue}throw error}}}async function rejectLegacyDirectory(lockPath){try{if((await stat2(lockPath)).isDirectory())throw new LegacyLockArtifactError(lockPath)}catch(error){if(error instanceof LegacyLockArtifactError||error.code!=="ENOENT")throw error}}function isBusy(error){let message=error instanceof Error?error.message:String(error);return/busy|locked/i.test(message)||error?.code==="SQLITE_BUSY"}export{readHostProcessMetrics,HOST_COLD_START_ENV,HOST_IDLE_EXIT_MS_ENV,DEFAULT_HOST_IDLE_EXIT_MS,HANDOFF_GRACE_MS_ENV,DEFAULT_HANDOFF_GRACE_MS,parseColdStart,parseIdleExitMs,resolveHostPolicy,IdleExitDecider,writeStderrLine,supervisorLog,writeHostReady,logUnknownHostIdentity,errorMessage,STOP_STALL_EVIDENCE_MAX_AGE_MS,CHILD_STALLED_STOP_MAX_MS_ENV,childStalledStopMaxMs,ownGenerationDir,stallRefusalWindowMs,writeStallEvidence,writeHeartbeat,recentStall,hostLoopStalled,holderGenerationEnded,hostChildAlive,writeStopProgress,clearStopProgress,activeStopProgress,SESSION_PATH_RETRY_AFTER_MS,createEndpointReservations,readSessionPathClaims,claimOwnerIsLive,pruneDeadGenerations,readGenerationRows,readHostRegistration,readGenerationRegistration,writeHostRegistration,writeGenerationRecord,clearHostRegistration,releaseGeneration,provenOwner,writtenByThisProcess,thisProcessStartTime,isGenerationId,acquireOwnershipSafeLock,CHILD_STOP_TIMEOUT_MS,CHILD_KILL_EXIT_TIMEOUT_MS,writeStopIntent,readStopIntent,consumeStopIntent,layeredSupervisorIntent,writeDrainRequest,watchDrainRequest,writeDrainWatch,readDrainWatch,hostChildDrainRequestFile};
|
|
@@ -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{Text}from"./chunk-FDL4CF6F.js";import{getShellConfig}from"./chunk-BWA4FVFW.js";import{HOST_CALL_KINDS,TOOL_CHILD_LIMITS,connectChannel,isRefId}from"./chunk-V3CK2AVC.js";import{typebox_exports}from"./chunk-MIENF2YK.js";import{TOOL_CHILD_LEDGER_ENV,TOOL_CHILD_REENTRY_ENV,TOOL_CHILD_REFS_ROOT_ENV,rememberToolChildReentry,scrubToolChildEnv,toolChildReentry}from"./chunk-OXNWERO4.js";import{BACKGROUND_START_GRACE_MS,DEFAULT_COLS,DEFAULT_MAX_SESSIONS,DEFAULT_ROWS,FOREGROUND_ENV_OVERRIDES,KILLED_SESSION_EXIT_GRACE_MS,TERMINAL_BASH_TOOL,TERMINAL_INPUT_TOOL,TERMINAL_KILL_TOOL,TERMINAL_OUTPUT_TOOL,TERMINAL_RESIZE_TOOL,encodeKeys,loadPty,safeRegExp}from"./chunk-NTK2MHJ5.js";import{processIsRunning,processStartTimeMs,readProcessStartTime,sameProcessStartMs}from"./chunk-O5RYI3IW.js";var ToolChildJobError=class extends Error{constructor(code,message){super(message),this.code=code,this.name="ToolChildJobError"}};var WakeAdmissionError=class extends Error{constructor(bytes){super(`wake_too_large: ${bytes} bytes exceeds the ${TOOL_CHILD_LIMITS.wakePendingBytes}-byte pending budget`),this.code="wake_too_large",this.name="WakeAdmissionError"}},WakeAdmission=class{#pending=new Map;#blocked=[];#pendingBytes=0;get pending(){return this.#pending.size}get blocked(){return this.#blocked.length}send(wakeId,bytes){return bytes>TOOL_CHILD_LIMITS.wakePendingBytes?Promise.reject(new WakeAdmissionError(bytes)):this.#blocked.length===0&&this.#fits(bytes)?(this.#admit(wakeId,bytes),Promise.resolve()):new Promise(release=>{this.#blocked.push({wakeId,bytes,release})})}ack(wakeId){let bytes=this.#pending.get(wakeId);if(bytes!==void 0){this.#pending.delete(wakeId),this.#pendingBytes-=bytes;for(let next=this.#blocked[0];next!==void 0&&this.#fits(next.bytes);next=this.#blocked[0])this.#blocked.shift(),this.#admit(next.wakeId,next.bytes),next.release()}}#fits(bytes){return this.#pending.size<TOOL_CHILD_LIMITS.wakePending&&this.#pendingBytes+bytes<=TOOL_CHILD_LIMITS.wakePendingBytes}#admit(wakeId,bytes){this.#pending.set(wakeId,bytes),this.#pendingBytes+=bytes}};function hostCallCapacity(){return TOOL_CHILD_LIMITS.HOST_CALL_ACTIVE+TOOL_CHILD_LIMITS.HOST_CALL_WAITING}var HostCallAdmission=class{#active=new Set;#waiting=[];get active(){return this.#active.size}get waiting(){return this.#waiting.length}submit(callId){return this.#active.has(callId)||this.#waiting.includes(callId)?refuse(callId,"host_call_duplicate"):this.#active.size<TOOL_CHILD_LIMITS.HOST_CALL_ACTIVE&&this.#waiting.length===0?(this.#active.add(callId),{state:"active"}):this.#active.size+this.#waiting.length>=hostCallCapacity()?refuse(callId,"host_call_capacity"):(this.#waiting.push(callId),{state:"waiting"})}settle(callId){if(!this.#active.delete(callId)){let index=this.#waiting.indexOf(callId);index>=0&&this.#waiting.splice(index,1);return}let next=this.#waiting.shift();return next!==void 0&&this.#active.add(next),next}};function refuse(callId,code){return{state:"refused",frame:{type:"host_call_refused",callId,code}}}import{createHash,randomBytes}from"node:crypto";import{createReadStream}from"node:fs";import{mkdir,readFile,rm as rm2,stat,writeFile}from"node:fs/promises";import{dirname}from"node:path";import{readdir,rm}from"node:fs/promises";import{join}from"node:path";function refGenerationDir(root,generation){return join(root,`gen-${generation}`)}function refFilePath(root,ref){if(!isRefId(ref.refId))throw new Error(`invalid ref id: ${JSON.stringify(ref.refId)}`);return join(refGenerationDir(root,ref.generation),"refs",ref.refId)}async function teardownRefGeneration(root,generation){await rm(refGenerationDir(root,generation),{recursive:!0,force:!0})}var PayloadRefError=class extends Error{constructor(code,message,reason){super(`${code}: ${message}`),this.name="PayloadRefError",this.code=code,this.reason=reason}},PayloadRefWriter=class{#root;#now;#pending=new Map;#ownedBytes=0;constructor(options){this.generation=options.generation,this.budget=options.budget??TOOL_CHILD_LIMITS.refsBudget,this.#root=options.root,this.#now=options.now??Date.now}get ownedBytes(){return this.#ownedBytes}async create(payload){let size=payload.byteLength;if(this.#ownedBytes+size>this.budget)throw new PayloadRefError("ref_budget_exceeded",`${size} bytes on top of ${this.#ownedBytes} owned exceeds ${this.budget}`);this.#ownedBytes+=size;let ref={refId:randomBytes(12).toString("hex"),generation:this.generation,bytes:size,sha256:createHash("sha256").update(payload).digest("hex")},path=refFilePath(this.#root,ref);try{await mkdir(dirname(path),{recursive:!0,mode:448}),await writeFile(path,payload,{flag:"wx",mode:384})}catch(error){throw this.#ownedBytes-=size,await rm2(path,{force:!0}),error}return this.#pending.set(ref.refId,{bytes:size,createdAtMs:this.#now()}),ref}async handle(control){let pending=this.#pending.get(control.refId);pending!==void 0&&(this.#pending.delete(control.refId),this.#ownedBytes-=pending.bytes,control.type==="ref_nack"&&await rm2(refFilePath(this.#root,{refId:control.refId,generation:this.generation}),{force:!0}))}pendingIds(){return[...this.#pending.keys()]}overdue(){let deadline=this.#now()-TOOL_CHILD_LIMITS.refAckMs;return[...this.#pending].filter(([,ref])=>ref.createdAtMs<=deadline).map(([refId])=>refId)}async teardown(){this.#pending.clear(),this.#ownedBytes=0,await teardownRefGeneration(this.#root,this.generation)}},isMissingFile=error=>error instanceof Error&&"code"in error&&(error.code==="ENOENT"||error.code==="ENOTDIR");async function hashFile(path,signal){let hash=createHash("sha256");for await(let chunk of createReadStream(path)){if(signal?.aborted)return"cancelled";hash.update(chunk)}return hash.digest("hex")}var PayloadRefReader=class{#root;#generation;#budget;#send;#owned=new Map;#ownedBytes=0;constructor(options){this.#root=options.root,this.#generation=options.generation,this.#budget=options.budget??TOOL_CHILD_LIMITS.refsBudget,this.#send=options.send}async accept(ref,signal){let reason=await this.#verify(ref,signal);return reason!==void 0?(this.refuse(ref,reason),{ok:!1,reason}):(this.#owned.set(ref.refId,ref),this.#ownedBytes+=ref.bytes,this.#send({type:"ref_ack",refId:ref.refId}),{ok:!0})}refuse(ref,reason){this.#owned.has(ref.refId)||this.#send({type:"ref_nack",refId:ref.refId,reason})}async consume(refId){let ref=this.#owned.get(refId);if(ref===void 0)throw new PayloadRefError("ref_not_owned",`ref ${refId} is not owned by this side`);let path=refFilePath(this.#root,ref),bytes=await readFile(path);return await rm2(path,{force:!0}),this.#owned.delete(refId),this.#ownedBytes-=ref.bytes,bytes}ownedIds(){return[...this.#owned.keys()]}async#verify(ref,signal){if(signal?.aborted)return"cancelled";if(ref.generation!==this.#generation||!isRefId(ref.refId)||this.#owned.has(ref.refId))return"foreign";if(this.#ownedBytes+ref.bytes>this.#budget)return"budget";let path=refFilePath(this.#root,ref);try{if((await stat(path)).size!==ref.bytes)return"corrupt";let digest=await hashFile(path,signal);return digest==="cancelled"?"cancelled":digest===ref.sha256?void 0:"corrupt"}catch(error){if(isMissingFile(error))return"missing";throw error}}};async function packPayload(value,writer){let normalized=value===void 0?null:value,json=JSON.stringify(normalized);return json===void 0||Buffer.byteLength(json,"utf8")<=TOOL_CHILD_LIMITS.REF_THRESHOLD?{inline:!0,value:normalized}:{inline:!1,ref:await writer.create(Buffer.from(json,"utf8"))}}async function unpackPayload(ref,reader,signal){let acceptance=await reader.accept(ref,signal);if(!acceptance.ok)throw new PayloadRefError("ref_rejected",`ref ${ref.refId} was refused (${acceptance.reason})`,acceptance.reason);let bytes=await reader.consume(ref.refId);return JSON.parse(Buffer.from(bytes.buffer,bytes.byteOffset,bytes.byteLength).toString("utf8"))}var ChildHostCalls=class{#channel;#admissions=new Map;#pending=new Map;#refs;#next=0;constructor(channel,refs){this.#channel=channel,this.#refs=refs}load(jobId){let admission=this.#admissions.get(jobId);return{active:admission?.active??0,waiting:admission?.waiting??0}}async call(jobId,target,signal){let label=target.name??target.kind;if(signal.aborted)throw new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`);let callId=`h${++this.#next}`,packed=target.args===void 0||this.#refs===void 0?{inline:!0,value:target.args}:await packPayload(target.args,this.#refs.writer),frame={type:"host_call",callId,jobId,kind:target.kind,...target.name===void 0?{}:{name:target.name},...packed.inline?packed.value===void 0?{}:{args:packed.value}:{argsRef:packed.ref}};if(signal.aborted)throw this.#releaseUnsent(frame),new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`);return new Promise((resolve,reject)=>{let decision=this.#admission(jobId).submit(callId);if(decision.state==="refused"){this.#forgetIdle(jobId),this.#releaseUnsent(frame),reject(new ToolChildJobError(decision.frame.code,`${label}: host call ${callId} refused`));return}let pending={frame,resolve,reject,sent:!1};this.#pending.set(callId,pending),signal.addEventListener("abort",()=>this.#settle(callId,call=>{call.sent||this.#releaseUnsent(call.frame),call.reject(new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`))}),{once:!0}),decision.state==="active"&&this.#send(pending)})}handle(frame){if(frame.type==="host_reply"){let{valueRef}=frame;return this.#settle(frame.callId,call=>{frame.error!==void 0?call.reject(new ToolChildJobError("host_call_failed",frame.error)):valueRef===void 0?call.resolve(frame.value??null):this.#refs===void 0?call.reject(new ToolChildJobError("host_call_failed","a valueRef reply on a side that reads no refs")):unpackPayload(valueRef,this.#refs.reader).then(call.resolve,error=>call.reject(new ToolChildJobError("host_call_failed",error instanceof Error?error.message:String(error))))}),!0}return frame.type==="host_call_refused"?(this.#settle(frame.callId,call=>call.reject(new ToolChildJobError(frame.code,`host call ${frame.callId} refused by the server`))),!0):!1}close(){for(let callId of[...this.#pending.keys()])this.#settle(callId,call=>call.reject(new ToolChildJobError("tool_child_exited","the channel closed")))}#admission(jobId){let admission=this.#admissions.get(jobId);return admission===void 0&&(admission=new HostCallAdmission,this.#admissions.set(jobId,admission)),admission}#forgetIdle(jobId){let admission=this.#admissions.get(jobId);admission!==void 0&&admission.active===0&&admission.waiting===0&&this.#admissions.delete(jobId)}#send(call){call.sent=!0,this.#channel.send(call.frame)}#releaseUnsent(frame){frame.argsRef!==void 0&&this.#refs?.writer.handle({type:"ref_nack",refId:frame.argsRef.refId,reason:"cancelled"})}#settle(callId,apply){let call=this.#pending.get(callId);if(call===void 0)return;this.#pending.delete(callId);let{jobId}=call.frame,promoted=this.#admissions.get(jobId)?.settle(callId);if(this.#forgetIdle(jobId),apply(call),promoted!==void 0){let next=this.#pending.get(promoted);next!==void 0&&this.#send(next)}}};var JobUpdates=class{#jobId;#channel;#writer;#window;#nextSeq=0;#acked=0;#waiters=[];#ended=!1;#tail=Promise.resolve();constructor(options){this.#jobId=options.jobId,this.#channel=options.channel,this.#writer=options.writer,this.#window=options.window??TOOL_CHILD_LIMITS.updatesInFlight}update(value){let sent=this.#tail.then(()=>this.#send(value));return this.#tail=sent.catch(()=>{}),sent}async#send(value){for(;!this.#ended&&this.#nextSeq-this.#acked>=this.#window;)await new Promise(resolve=>this.#waiters.push(resolve));if(this.#ended)throw new Error(`update after job ${this.#jobId} ended`);let packed=this.#writer===void 0?{inline:!0,value}:await packPayload(value,this.#writer);if(this.#ended)throw new Error(`update after job ${this.#jobId} ended`);let seq=++this.#nextSeq;this.#channel.send(packed.inline?{type:"update",jobId:this.#jobId,seq,...packed.value===void 0?{}:{value:packed.value}}:{type:"update",jobId:this.#jobId,seq,valueRef:packed.ref})}acked(seq){seq<=this.#acked||(this.#acked=Math.min(seq,this.#nextSeq),this.#wake())}end(){this.#ended=!0,this.#wake()}#wake(){for(let resolve of this.#waiters.splice(0))resolve()}};var BarrierClock=class _BarrierClock{constructor(buffer){if(buffer.byteLength%Int32Array.BYTES_PER_ELEMENT!==0)throw new Error("barrier clock buffer is misaligned");let length=buffer.byteLength/Int32Array.BYTES_PER_ELEMENT;if(length<5||(length-1)%4!==0)throw new Error("barrier clock buffer has no slots");this.buffer=buffer,this.cells=new Int32Array(buffer),this.slots=(length-1)/4}static create(slots=256){if(!Number.isInteger(slots)||slots<1)throw new Error(`barrier clock needs at least one slot, got ${slots}`);return new _BarrierClock(new SharedArrayBuffer((1+slots*4)*Int32Array.BYTES_PER_ELEMENT))}tick(){return Atomics.add(this.cells,0,1)+1}claimSlot(){for(let slot=0;slot<this.slots;slot++)if(Atomics.compareExchange(this.cells,this.index(slot,3),0,1)===0)return Atomics.store(this.cells,this.index(slot,0),0),Atomics.store(this.cells,this.index(slot,1),0),Atomics.store(this.cells,this.index(slot,2),0),slot}releaseSlot(slot){Atomics.store(this.cells,this.index(slot,3),0)}recordAck(slot){let tick=this.tick();return Atomics.store(this.cells,this.index(slot,0),tick),Atomics.notify(this.cells,this.index(slot,0)),tick}recordInvoke(slot){let ackTick=Atomics.load(this.cells,this.index(slot,0)),invokeTick=this.tick();return Atomics.store(this.cells,this.index(slot,1),invokeTick),Atomics.add(this.cells,this.index(slot,2),1),{ackTick:ackTick===0?null:ackTick,invokeTick}}waitForAck(slot,timeoutMs=Number.POSITIVE_INFINITY){let at=this.index(slot,0);for(;Atomics.load(this.cells,at)===0;)if(Atomics.wait(this.cells,at,0,timeoutMs)==="timed-out")return"timed-out";return"acked"}read(slot){let ackTick=Atomics.load(this.cells,this.index(slot,0)),invokeTick=Atomics.load(this.cells,this.index(slot,1));return{ackTick:ackTick===0?null:ackTick,invokeTick:invokeTick===0?null:invokeTick,invocations:Atomics.load(this.cells,this.index(slot,2))}}index(slot,field){if(!Number.isInteger(slot)||slot<0||slot>=this.slots)throw new Error(`no barrier slot ${slot}`);return 1+slot*4+field}};function proofIsOrdered(proof){return proof.ackTick!==null&&proof.ackTick<proof.invokeTick}import{randomUUID}from"node:crypto";import{existsSync,readdirSync,rmSync,watch}from"node:fs";import{writeFile as writeFile2}from"node:fs/promises";import{join as join2}from"node:path";var PREFIX="SENPI_TOOL_CHILD_TEST_",TEST_CONTROL_DIR_ENV=`${PREFIX}CONTROL_DIR`;function readTestControls(env){let dir=env[TEST_CONTROL_DIR_ENV],value=name=>{let raw=env[`${PREFIX}${name}`];return raw===void 0||raw===""||raw==="0"?void 0:raw};return{enabled:name=>value(name)!==void 0,value,released:file=>dir===void 0?Promise.reject(new Error(`${TEST_CONTROL_DIR_ENV} is not set`)):waitForFile(dir,file),watchPrefix:(prefix,onFile)=>dir===void 0?{ready:Promise.reject(new Error(`${TEST_CONTROL_DIR_ENV} is not set`)),close:()=>{}}:watchPrefix(dir,prefix,onFile)}}function watchPrefix(dir,prefix,onFile){let seen=new Set,report=name=>{!name.startsWith(prefix)||seen.has(name)||(seen.add(name),onFile(name))},sentinel=`.watch-${process.pid}-${randomUUID()}`,resend,live=!1,markReady=()=>{},failReady=()=>{},ready=new Promise((resolve,reject)=>{markReady=resolve,failReady=reject}),watcher=watch(dir,(_event,name)=>{if(name!==null){if(name===sentinel){live=!0,clearTimeout(resend),rmSync(join2(dir,sentinel),{force:!0});for(let existing of readdirSync(dir))report(existing);markReady();return}existsSync(join2(dir,name))&&report(name)}}),touch=()=>{live||writeFile2(join2(dir,sentinel),String(Date.now())).then(()=>{live||(resend=setTimeout(touch,50))},error=>failReady(error))};return touch(),{ready,close:()=>{live=!0,clearTimeout(resend),watcher.close(),rmSync(join2(dir,sentinel),{force:!0})}}}function waitForFile(dir,file){let path=join2(dir,file),sentinel=join2(dir,`.watch-${process.pid}-${randomUUID()}`);return new Promise((resolve,reject)=>{let done=!1,resend,finish=()=>{done||(done=!0,clearTimeout(resend),watcher.close(),rmSync(sentinel,{force:!0}),resolve())},watcher=watch(dir,(_event,name)=>{if(existsSync(path)){finish();return}name!==null&&join2(dir,name)===sentinel&&clearTimeout(resend)}),touch=()=>{done||writeFile2(sentinel,String(Date.now())).then(()=>{done||(existsSync(path)?finish():resend=setTimeout(touch,50))},error=>{done||(done=!0,watcher.close(),reject(error))})};touch()})}var WindowsJobError=class extends Error{constructor(step,win32Error){super(`tool_child_job_assign_failed: ${step} failed (win32 error ${win32Error})`),this.code="tool_child_job_assign_failed",this.name="WindowsJobError",this.win32Error=win32Error}};function extendedLimitInformation(){let info=new Uint8Array(144);return new DataView(info.buffer).setUint32(16,10240,!0),info}var WindowsJob=class _WindowsJob{constructor(kernel,handle){this.closed=!1,this.kernel=kernel,this.handle=handle}static create(kernel){let handle=kernel.CreateJobObjectW(null,null);if(!handle)throw new WindowsJobError("CreateJobObjectW",kernel.GetLastError());let info=extendedLimitInformation();if(kernel.SetInformationJobObject(handle,9,info,info.byteLength)===0){let error=kernel.GetLastError();throw kernel.CloseHandle(handle),new WindowsJobError("SetInformationJobObject",error)}return new _WindowsJob(kernel,handle)}assign(pid){let process2=this.kernel.OpenProcess(4353,0,pid);if(!process2)throw new WindowsJobError("OpenProcess",this.kernel.GetLastError());try{if(this.kernel.AssignProcessToJobObject(this.handle,process2)===0)throw new WindowsJobError("AssignProcessToJobObject",this.kernel.GetLastError());let inJob=new Uint8Array(4);if(this.kernel.IsProcessInJob(process2,this.handle,inJob)===0||new DataView(inJob.buffer).getInt32(0,!0)===0)throw new WindowsJobError("IsProcessInJob",this.kernel.GetLastError())}finally{this.kernel.CloseHandle(process2)}}memberPids(){let list=new Uint8Array(8200);if(this.kernel.QueryInformationJobObject(this.handle,3,list,list.byteLength,null)===0)return[];let view=new DataView(list.buffer),count=Math.min(view.getUint32(4,!0),1024);return Array.from({length:count},(_,index)=>Number(view.getBigUint64(8+index*8,!0)))}terminate(exitCode=1){this.closed||this.kernel.TerminateJobObject(this.handle,exitCode)}close(){this.closed||(this.closed=!0,this.kernel.CloseHandle(this.handle))}};function loadKernel32Job(){if(process.platform!=="win32")return;let ffi=process.getBuiltinModule("bun:ffi");if(ffi===void 0)return;let lib=ffi.dlopen("kernel32.dll",{CreateJobObjectW:{args:["ptr","ptr"],returns:"ptr"},SetInformationJobObject:{args:["ptr","i32","ptr","u32"],returns:"i32"},QueryInformationJobObject:{args:["ptr","i32","ptr","u32","ptr"],returns:"i32"},OpenProcess:{args:["u32","i32","u32"],returns:"ptr"},AssignProcessToJobObject:{args:["ptr","ptr"],returns:"i32"},IsProcessInJob:{args:["ptr","ptr","ptr"],returns:"i32"},TerminateJobObject:{args:["ptr","u32"],returns:"i32"},CloseHandle:{args:["ptr"],returns:"i32"},GetLastError:{args:[],returns:"u32"},GetCurrentProcess:{args:[],returns:"ptr"}}),call=(name,...args)=>{let fn=lib.symbols[name];if(fn===void 0)throw new Error(`kernel32 has no ${name}`);return fn(...args.map(arg=>arg instanceof Uint8Array?ffi.ptr(arg):arg))};return{CreateJobObjectW:()=>call("CreateJobObjectW",null,null),SetInformationJobObject:(job,infoClass,info,length)=>Number(call("SetInformationJobObject",job,infoClass,info,length)),QueryInformationJobObject:(job,infoClass,info,length)=>Number(call("QueryInformationJobObject",job,infoClass,info,length,null)),OpenProcess:(access,inherit,pid)=>call("OpenProcess",access,inherit,pid),AssignProcessToJobObject:(job,process2)=>Number(call("AssignProcessToJobObject",job,process2)),IsProcessInJob:(process2,job,result)=>Number(call("IsProcessInJob",process2,job,result)),TerminateJobObject:(job,exitCode)=>Number(call("TerminateJobObject",job,exitCode)),CloseHandle:handle=>Number(call("CloseHandle",handle)),GetLastError:()=>Number(call("GetLastError")),GetCurrentProcess:()=>call("GetCurrentProcess")}}var defaultInJob;function currentProcessInJob(kernel){if(kernel!==void 0)return queryInJob(kernel);if(defaultInJob===void 0){let loaded=loadKernel32Job();defaultInJob=loaded===void 0?!1:queryInJob(loaded)}return defaultInJob}function queryInJob(kernel){let result=new Uint8Array(4);return kernel.IsProcessInJob(kernel.GetCurrentProcess(),null,result)!==0&&new DataView(result.buffer).getInt32(0,!0)!==0}var FINISHED_SLOT_STATES=256,LaunchGateError=class extends Error{constructor(code,message){super(`${code}: ${message}`),this.name="LaunchGateError",this.code=code}},LaunchGate=class{#channel;#slots=new Map;#finished=new Map;#controls;#next=0;constructor(channel,clock=BarrierClock.create(),env=process.env,creatorInJob=currentProcessInJob){this.#channel=channel,this.clock=clock,this.#controls=readTestControls(env),this.#creatorInJob=creatorInJob}#creatorInJob;started(launchId,pid,breakaway=!1){this.#slots.has(launchId)&&this.#channel.send({type:"command_started",launchId,pid,startedAtMs:Date.now(),creatorInJob:this.#creatorInJob(),breakaway})}get skipsAckWait(){return this.#controls.enabled("SKIP_ACK_WAIT")}request(request){let slot=this.clock.claimSlot();if(slot===void 0)throw new LaunchGateError("tool_child_launch_capacity",`${this.clock.slots} launches in flight`);let launchId=`L${process.pid}-${++this.#next}`,ack,acked=new Promise(resolve=>{ack=resolve});return this.#slots.set(launchId,{slot,ack,lifetime:request.lifetime,request}),this.#channel.send({type:"launch",launchId,...request}),this.#controls.enabled("STOP_AFTER_SPAWN")&&process.kill(process.pid,"SIGSTOP"),{launchId,slot,acked}}adopt(launchId,slot,request){this.#slots.set(launchId,{slot,ack:()=>{},lifetime:request.lifetime,request}),this.#channel.send({type:"launch",launchId,...request})}handleWorker(message){message.kind==="launch"?this.adopt(message.launchId,message.slot,message.request):message.kind==="invoking"?this.invoking(message.launchId):message.kind==="started"?this.started(message.launchId,message.pid,message.breakaway):this.done(message.launchId,{...message.exitCode===void 0?{}:{exitCode:message.exitCode},...message.signal===void 0?{}:{signal:message.signal}})}handle(message){if(message.type==="launch_ack"){let entry=this.#slots.get(message.launchId);return entry!==void 0&&(this.clock.recordAck(entry.slot),entry.ack()),!0}if(message.type==="slot_query"){let entry=this.#slots.get(message.launchId),state=entry===void 0?this.#finished.get(message.launchId)??{ackTick:null,invokeTick:null,invocations:0}:this.clock.read(entry.slot);return this.#channel.send({type:"slot_state",launchId:message.launchId,...state}),!0}return!1}invokeNow(launchId){let entry=this.#slots.get(launchId);if(entry===void 0)throw new LaunchGateError("tool_child_launch_unknown",launchId);this.clock.recordInvoke(entry.slot),this.invoking(launchId)}invoking(launchId){let entry=this.#slots.get(launchId);if(entry===void 0)return;let state=this.clock.read(entry.slot),invokeTick=state.invokeTick;if(invokeTick===null)return;let send=()=>this.#channel.send({type:"launch_proof",launchId,ackTick:state.ackTick,invokeTick}),hold=this.#controls.value("HOLD_LAUNCH_PROOF");if(hold!==void 0&&(hold!=="detached"||entry.lifetime==="detached")){this.#controls.released(`release-proof-${launchId}`).then(send);return}send()}endJobGroups(jobId){let ended=[];for(let[launchId,{request}]of this.#slots)if(!(request.jobId!==jobId||request.lifetime!=="owned"||request.containment!=="own-group")&&!(request.pgid===void 0||request.pgid<=1))try{process.kill(-request.pgid,"SIGKILL"),ended.push({launchId,pgid:request.pgid})}catch{}for(let{launchId}of ended)this.done(launchId,{signal:"SIGKILL"});return ended.map(({pgid})=>pgid)}done(launchId,outcome){let entry=this.#slots.get(launchId);entry!==void 0&&(this.#slots.delete(launchId),this.#finished.set(launchId,this.clock.read(entry.slot)),this.#finished.size>FINISHED_SLOT_STATES&&this.#finished.delete(this.#finished.keys().next().value??""),this.clock.releaseSlot(entry.slot),this.#channel.send({type:"launch_done",launchId,...outcome.exitCode===void 0?{}:{exitCode:outcome.exitCode},...outcome.signal===void 0?{}:{signal:outcome.signal}}))}};import{mkdir as mkdir3,readdir as readdir2,readFile as readFile3,rm as rm4,writeFile as writeFile3}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";import{appendFile,mkdir as mkdir2,open,readFile as readFile2,rm as rm3}from"node:fs/promises";import{dirname as dirname2,join as join3}from"node:path";function generationLedgerPath(dir,generation){return join3(dir,`g${generation}`,"descendants.ledger")}var DescendantsLedger=class{#path;#durableDir=!1;#entries=new Map;constructor(path){this.#path=path}get path(){return this.#path}entries(){return[...this.#entries.values()]}async append(entry){if(!this.#durableDir){let directory=dirname2(this.#path);await mkdir2(directory,{recursive:!0,mode:448}),await(await open(this.#path,"a",384)).close(),await syncDirectory(directory),await syncDirectory(dirname2(directory)),this.#durableDir=!0}let handle=await open(this.#path,"a",384);try{await handle.write(`${JSON.stringify(entry)}
|
|
2
|
+
import{Text}from"./chunk-FDL4CF6F.js";import{getShellConfig}from"./chunk-7KOUQSBX.js";import{HOST_CALL_KINDS,TOOL_CHILD_LIMITS,connectChannel,isRefId}from"./chunk-V3CK2AVC.js";import{typebox_exports}from"./chunk-MIENF2YK.js";import{TOOL_CHILD_LEDGER_ENV,TOOL_CHILD_REENTRY_ENV,TOOL_CHILD_REFS_ROOT_ENV,rememberToolChildReentry,scrubToolChildEnv,toolChildReentry}from"./chunk-OXNWERO4.js";import{BACKGROUND_START_GRACE_MS,DEFAULT_COLS,DEFAULT_MAX_SESSIONS,DEFAULT_ROWS,FOREGROUND_ENV_OVERRIDES,KILLED_SESSION_EXIT_GRACE_MS,TERMINAL_BASH_TOOL,TERMINAL_INPUT_TOOL,TERMINAL_KILL_TOOL,TERMINAL_OUTPUT_TOOL,TERMINAL_RESIZE_TOOL,encodeKeys,loadPty,safeRegExp}from"./chunk-NTK2MHJ5.js";import{processIsRunning,processStartTimeMs,readProcessStartTime,sameProcessStartMs}from"./chunk-O5RYI3IW.js";var ToolChildJobError=class extends Error{constructor(code,message){super(message),this.code=code,this.name="ToolChildJobError"}};var WakeAdmissionError=class extends Error{constructor(bytes){super(`wake_too_large: ${bytes} bytes exceeds the ${TOOL_CHILD_LIMITS.wakePendingBytes}-byte pending budget`),this.code="wake_too_large",this.name="WakeAdmissionError"}},WakeAdmission=class{#pending=new Map;#blocked=[];#pendingBytes=0;get pending(){return this.#pending.size}get blocked(){return this.#blocked.length}send(wakeId,bytes){return bytes>TOOL_CHILD_LIMITS.wakePendingBytes?Promise.reject(new WakeAdmissionError(bytes)):this.#blocked.length===0&&this.#fits(bytes)?(this.#admit(wakeId,bytes),Promise.resolve()):new Promise(release=>{this.#blocked.push({wakeId,bytes,release})})}ack(wakeId){let bytes=this.#pending.get(wakeId);if(bytes!==void 0){this.#pending.delete(wakeId),this.#pendingBytes-=bytes;for(let next=this.#blocked[0];next!==void 0&&this.#fits(next.bytes);next=this.#blocked[0])this.#blocked.shift(),this.#admit(next.wakeId,next.bytes),next.release()}}#fits(bytes){return this.#pending.size<TOOL_CHILD_LIMITS.wakePending&&this.#pendingBytes+bytes<=TOOL_CHILD_LIMITS.wakePendingBytes}#admit(wakeId,bytes){this.#pending.set(wakeId,bytes),this.#pendingBytes+=bytes}};function hostCallCapacity(){return TOOL_CHILD_LIMITS.HOST_CALL_ACTIVE+TOOL_CHILD_LIMITS.HOST_CALL_WAITING}var HostCallAdmission=class{#active=new Set;#waiting=[];get active(){return this.#active.size}get waiting(){return this.#waiting.length}submit(callId){return this.#active.has(callId)||this.#waiting.includes(callId)?refuse(callId,"host_call_duplicate"):this.#active.size<TOOL_CHILD_LIMITS.HOST_CALL_ACTIVE&&this.#waiting.length===0?(this.#active.add(callId),{state:"active"}):this.#active.size+this.#waiting.length>=hostCallCapacity()?refuse(callId,"host_call_capacity"):(this.#waiting.push(callId),{state:"waiting"})}settle(callId){if(!this.#active.delete(callId)){let index=this.#waiting.indexOf(callId);index>=0&&this.#waiting.splice(index,1);return}let next=this.#waiting.shift();return next!==void 0&&this.#active.add(next),next}};function refuse(callId,code){return{state:"refused",frame:{type:"host_call_refused",callId,code}}}import{createHash,randomBytes}from"node:crypto";import{createReadStream}from"node:fs";import{mkdir,readFile,rm as rm2,stat,writeFile}from"node:fs/promises";import{dirname}from"node:path";import{readdir,rm}from"node:fs/promises";import{join}from"node:path";function refGenerationDir(root,generation){return join(root,`gen-${generation}`)}function refFilePath(root,ref){if(!isRefId(ref.refId))throw new Error(`invalid ref id: ${JSON.stringify(ref.refId)}`);return join(refGenerationDir(root,ref.generation),"refs",ref.refId)}async function teardownRefGeneration(root,generation){await rm(refGenerationDir(root,generation),{recursive:!0,force:!0})}var PayloadRefError=class extends Error{constructor(code,message,reason){super(`${code}: ${message}`),this.name="PayloadRefError",this.code=code,this.reason=reason}},PayloadRefWriter=class{#root;#now;#pending=new Map;#ownedBytes=0;constructor(options){this.generation=options.generation,this.budget=options.budget??TOOL_CHILD_LIMITS.refsBudget,this.#root=options.root,this.#now=options.now??Date.now}get ownedBytes(){return this.#ownedBytes}async create(payload){let size=payload.byteLength;if(this.#ownedBytes+size>this.budget)throw new PayloadRefError("ref_budget_exceeded",`${size} bytes on top of ${this.#ownedBytes} owned exceeds ${this.budget}`);this.#ownedBytes+=size;let ref={refId:randomBytes(12).toString("hex"),generation:this.generation,bytes:size,sha256:createHash("sha256").update(payload).digest("hex")},path=refFilePath(this.#root,ref);try{await mkdir(dirname(path),{recursive:!0,mode:448}),await writeFile(path,payload,{flag:"wx",mode:384})}catch(error){throw this.#ownedBytes-=size,await rm2(path,{force:!0}),error}return this.#pending.set(ref.refId,{bytes:size,createdAtMs:this.#now()}),ref}async handle(control){let pending=this.#pending.get(control.refId);pending!==void 0&&(this.#pending.delete(control.refId),this.#ownedBytes-=pending.bytes,control.type==="ref_nack"&&await rm2(refFilePath(this.#root,{refId:control.refId,generation:this.generation}),{force:!0}))}pendingIds(){return[...this.#pending.keys()]}overdue(){let deadline=this.#now()-TOOL_CHILD_LIMITS.refAckMs;return[...this.#pending].filter(([,ref])=>ref.createdAtMs<=deadline).map(([refId])=>refId)}async teardown(){this.#pending.clear(),this.#ownedBytes=0,await teardownRefGeneration(this.#root,this.generation)}},isMissingFile=error=>error instanceof Error&&"code"in error&&(error.code==="ENOENT"||error.code==="ENOTDIR");async function hashFile(path,signal){let hash=createHash("sha256");for await(let chunk of createReadStream(path)){if(signal?.aborted)return"cancelled";hash.update(chunk)}return hash.digest("hex")}var PayloadRefReader=class{#root;#generation;#budget;#send;#owned=new Map;#ownedBytes=0;constructor(options){this.#root=options.root,this.#generation=options.generation,this.#budget=options.budget??TOOL_CHILD_LIMITS.refsBudget,this.#send=options.send}async accept(ref,signal){let reason=await this.#verify(ref,signal);return reason!==void 0?(this.refuse(ref,reason),{ok:!1,reason}):(this.#owned.set(ref.refId,ref),this.#ownedBytes+=ref.bytes,this.#send({type:"ref_ack",refId:ref.refId}),{ok:!0})}refuse(ref,reason){this.#owned.has(ref.refId)||this.#send({type:"ref_nack",refId:ref.refId,reason})}async consume(refId){let ref=this.#owned.get(refId);if(ref===void 0)throw new PayloadRefError("ref_not_owned",`ref ${refId} is not owned by this side`);let path=refFilePath(this.#root,ref),bytes=await readFile(path);return await rm2(path,{force:!0}),this.#owned.delete(refId),this.#ownedBytes-=ref.bytes,bytes}ownedIds(){return[...this.#owned.keys()]}async#verify(ref,signal){if(signal?.aborted)return"cancelled";if(ref.generation!==this.#generation||!isRefId(ref.refId)||this.#owned.has(ref.refId))return"foreign";if(this.#ownedBytes+ref.bytes>this.#budget)return"budget";let path=refFilePath(this.#root,ref);try{if((await stat(path)).size!==ref.bytes)return"corrupt";let digest=await hashFile(path,signal);return digest==="cancelled"?"cancelled":digest===ref.sha256?void 0:"corrupt"}catch(error){if(isMissingFile(error))return"missing";throw error}}};async function packPayload(value,writer){let normalized=value===void 0?null:value,json=JSON.stringify(normalized);return json===void 0||Buffer.byteLength(json,"utf8")<=TOOL_CHILD_LIMITS.REF_THRESHOLD?{inline:!0,value:normalized}:{inline:!1,ref:await writer.create(Buffer.from(json,"utf8"))}}async function unpackPayload(ref,reader,signal){let acceptance=await reader.accept(ref,signal);if(!acceptance.ok)throw new PayloadRefError("ref_rejected",`ref ${ref.refId} was refused (${acceptance.reason})`,acceptance.reason);let bytes=await reader.consume(ref.refId);return JSON.parse(Buffer.from(bytes.buffer,bytes.byteOffset,bytes.byteLength).toString("utf8"))}var ChildHostCalls=class{#channel;#admissions=new Map;#pending=new Map;#refs;#next=0;constructor(channel,refs){this.#channel=channel,this.#refs=refs}load(jobId){let admission=this.#admissions.get(jobId);return{active:admission?.active??0,waiting:admission?.waiting??0}}async call(jobId,target,signal){let label=target.name??target.kind;if(signal.aborted)throw new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`);let callId=`h${++this.#next}`,packed=target.args===void 0||this.#refs===void 0?{inline:!0,value:target.args}:await packPayload(target.args,this.#refs.writer),frame={type:"host_call",callId,jobId,kind:target.kind,...target.name===void 0?{}:{name:target.name},...packed.inline?packed.value===void 0?{}:{args:packed.value}:{argsRef:packed.ref}};if(signal.aborted)throw this.#releaseUnsent(frame),new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`);return new Promise((resolve,reject)=>{let decision=this.#admission(jobId).submit(callId);if(decision.state==="refused"){this.#forgetIdle(jobId),this.#releaseUnsent(frame),reject(new ToolChildJobError(decision.frame.code,`${label}: host call ${callId} refused`));return}let pending={frame,resolve,reject,sent:!1};this.#pending.set(callId,pending),signal.addEventListener("abort",()=>this.#settle(callId,call=>{call.sent||this.#releaseUnsent(call.frame),call.reject(new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`))}),{once:!0}),decision.state==="active"&&this.#send(pending)})}handle(frame){if(frame.type==="host_reply"){let{valueRef}=frame;return this.#settle(frame.callId,call=>{frame.error!==void 0?call.reject(new ToolChildJobError("host_call_failed",frame.error)):valueRef===void 0?call.resolve(frame.value??null):this.#refs===void 0?call.reject(new ToolChildJobError("host_call_failed","a valueRef reply on a side that reads no refs")):unpackPayload(valueRef,this.#refs.reader).then(call.resolve,error=>call.reject(new ToolChildJobError("host_call_failed",error instanceof Error?error.message:String(error))))}),!0}return frame.type==="host_call_refused"?(this.#settle(frame.callId,call=>call.reject(new ToolChildJobError(frame.code,`host call ${frame.callId} refused by the server`))),!0):!1}close(){for(let callId of[...this.#pending.keys()])this.#settle(callId,call=>call.reject(new ToolChildJobError("tool_child_exited","the channel closed")))}#admission(jobId){let admission=this.#admissions.get(jobId);return admission===void 0&&(admission=new HostCallAdmission,this.#admissions.set(jobId,admission)),admission}#forgetIdle(jobId){let admission=this.#admissions.get(jobId);admission!==void 0&&admission.active===0&&admission.waiting===0&&this.#admissions.delete(jobId)}#send(call){call.sent=!0,this.#channel.send(call.frame)}#releaseUnsent(frame){frame.argsRef!==void 0&&this.#refs?.writer.handle({type:"ref_nack",refId:frame.argsRef.refId,reason:"cancelled"})}#settle(callId,apply){let call=this.#pending.get(callId);if(call===void 0)return;this.#pending.delete(callId);let{jobId}=call.frame,promoted=this.#admissions.get(jobId)?.settle(callId);if(this.#forgetIdle(jobId),apply(call),promoted!==void 0){let next=this.#pending.get(promoted);next!==void 0&&this.#send(next)}}};var JobUpdates=class{#jobId;#channel;#writer;#window;#nextSeq=0;#acked=0;#waiters=[];#ended=!1;#tail=Promise.resolve();constructor(options){this.#jobId=options.jobId,this.#channel=options.channel,this.#writer=options.writer,this.#window=options.window??TOOL_CHILD_LIMITS.updatesInFlight}update(value){let sent=this.#tail.then(()=>this.#send(value));return this.#tail=sent.catch(()=>{}),sent}async#send(value){for(;!this.#ended&&this.#nextSeq-this.#acked>=this.#window;)await new Promise(resolve=>this.#waiters.push(resolve));if(this.#ended)throw new Error(`update after job ${this.#jobId} ended`);let packed=this.#writer===void 0?{inline:!0,value}:await packPayload(value,this.#writer);if(this.#ended)throw new Error(`update after job ${this.#jobId} ended`);let seq=++this.#nextSeq;this.#channel.send(packed.inline?{type:"update",jobId:this.#jobId,seq,...packed.value===void 0?{}:{value:packed.value}}:{type:"update",jobId:this.#jobId,seq,valueRef:packed.ref})}acked(seq){seq<=this.#acked||(this.#acked=Math.min(seq,this.#nextSeq),this.#wake())}end(){this.#ended=!0,this.#wake()}#wake(){for(let resolve of this.#waiters.splice(0))resolve()}};var BarrierClock=class _BarrierClock{constructor(buffer){if(buffer.byteLength%Int32Array.BYTES_PER_ELEMENT!==0)throw new Error("barrier clock buffer is misaligned");let length=buffer.byteLength/Int32Array.BYTES_PER_ELEMENT;if(length<5||(length-1)%4!==0)throw new Error("barrier clock buffer has no slots");this.buffer=buffer,this.cells=new Int32Array(buffer),this.slots=(length-1)/4}static create(slots=256){if(!Number.isInteger(slots)||slots<1)throw new Error(`barrier clock needs at least one slot, got ${slots}`);return new _BarrierClock(new SharedArrayBuffer((1+slots*4)*Int32Array.BYTES_PER_ELEMENT))}tick(){return Atomics.add(this.cells,0,1)+1}claimSlot(){for(let slot=0;slot<this.slots;slot++)if(Atomics.compareExchange(this.cells,this.index(slot,3),0,1)===0)return Atomics.store(this.cells,this.index(slot,0),0),Atomics.store(this.cells,this.index(slot,1),0),Atomics.store(this.cells,this.index(slot,2),0),slot}releaseSlot(slot){Atomics.store(this.cells,this.index(slot,3),0)}recordAck(slot){let tick=this.tick();return Atomics.store(this.cells,this.index(slot,0),tick),Atomics.notify(this.cells,this.index(slot,0)),tick}recordInvoke(slot){let ackTick=Atomics.load(this.cells,this.index(slot,0)),invokeTick=this.tick();return Atomics.store(this.cells,this.index(slot,1),invokeTick),Atomics.add(this.cells,this.index(slot,2),1),{ackTick:ackTick===0?null:ackTick,invokeTick}}waitForAck(slot,timeoutMs=Number.POSITIVE_INFINITY){let at=this.index(slot,0);for(;Atomics.load(this.cells,at)===0;)if(Atomics.wait(this.cells,at,0,timeoutMs)==="timed-out")return"timed-out";return"acked"}read(slot){let ackTick=Atomics.load(this.cells,this.index(slot,0)),invokeTick=Atomics.load(this.cells,this.index(slot,1));return{ackTick:ackTick===0?null:ackTick,invokeTick:invokeTick===0?null:invokeTick,invocations:Atomics.load(this.cells,this.index(slot,2))}}index(slot,field){if(!Number.isInteger(slot)||slot<0||slot>=this.slots)throw new Error(`no barrier slot ${slot}`);return 1+slot*4+field}};function proofIsOrdered(proof){return proof.ackTick!==null&&proof.ackTick<proof.invokeTick}import{randomUUID}from"node:crypto";import{existsSync,readdirSync,rmSync,watch}from"node:fs";import{writeFile as writeFile2}from"node:fs/promises";import{join as join2}from"node:path";var PREFIX="SENPI_TOOL_CHILD_TEST_",TEST_CONTROL_DIR_ENV=`${PREFIX}CONTROL_DIR`;function readTestControls(env){let dir=env[TEST_CONTROL_DIR_ENV],value=name=>{let raw=env[`${PREFIX}${name}`];return raw===void 0||raw===""||raw==="0"?void 0:raw};return{enabled:name=>value(name)!==void 0,value,released:file=>dir===void 0?Promise.reject(new Error(`${TEST_CONTROL_DIR_ENV} is not set`)):waitForFile(dir,file),watchPrefix:(prefix,onFile)=>dir===void 0?{ready:Promise.reject(new Error(`${TEST_CONTROL_DIR_ENV} is not set`)),close:()=>{}}:watchPrefix(dir,prefix,onFile)}}function watchPrefix(dir,prefix,onFile){let seen=new Set,report=name=>{!name.startsWith(prefix)||seen.has(name)||(seen.add(name),onFile(name))},sentinel=`.watch-${process.pid}-${randomUUID()}`,resend,live=!1,markReady=()=>{},failReady=()=>{},ready=new Promise((resolve,reject)=>{markReady=resolve,failReady=reject}),watcher=watch(dir,(_event,name)=>{if(name!==null){if(name===sentinel){live=!0,clearTimeout(resend),rmSync(join2(dir,sentinel),{force:!0});for(let existing of readdirSync(dir))report(existing);markReady();return}existsSync(join2(dir,name))&&report(name)}}),touch=()=>{live||writeFile2(join2(dir,sentinel),String(Date.now())).then(()=>{live||(resend=setTimeout(touch,50))},error=>failReady(error))};return touch(),{ready,close:()=>{live=!0,clearTimeout(resend),watcher.close(),rmSync(join2(dir,sentinel),{force:!0})}}}function waitForFile(dir,file){let path=join2(dir,file),sentinel=join2(dir,`.watch-${process.pid}-${randomUUID()}`);return new Promise((resolve,reject)=>{let done=!1,resend,finish=()=>{done||(done=!0,clearTimeout(resend),watcher.close(),rmSync(sentinel,{force:!0}),resolve())},watcher=watch(dir,(_event,name)=>{if(existsSync(path)){finish();return}name!==null&&join2(dir,name)===sentinel&&clearTimeout(resend)}),touch=()=>{done||writeFile2(sentinel,String(Date.now())).then(()=>{done||(existsSync(path)?finish():resend=setTimeout(touch,50))},error=>{done||(done=!0,watcher.close(),reject(error))})};touch()})}var WindowsJobError=class extends Error{constructor(step,win32Error){super(`tool_child_job_assign_failed: ${step} failed (win32 error ${win32Error})`),this.code="tool_child_job_assign_failed",this.name="WindowsJobError",this.win32Error=win32Error}};function extendedLimitInformation(){let info=new Uint8Array(144);return new DataView(info.buffer).setUint32(16,10240,!0),info}var WindowsJob=class _WindowsJob{constructor(kernel,handle){this.closed=!1,this.kernel=kernel,this.handle=handle}static create(kernel){let handle=kernel.CreateJobObjectW(null,null);if(!handle)throw new WindowsJobError("CreateJobObjectW",kernel.GetLastError());let info=extendedLimitInformation();if(kernel.SetInformationJobObject(handle,9,info,info.byteLength)===0){let error=kernel.GetLastError();throw kernel.CloseHandle(handle),new WindowsJobError("SetInformationJobObject",error)}return new _WindowsJob(kernel,handle)}assign(pid){let process2=this.kernel.OpenProcess(4353,0,pid);if(!process2)throw new WindowsJobError("OpenProcess",this.kernel.GetLastError());try{if(this.kernel.AssignProcessToJobObject(this.handle,process2)===0)throw new WindowsJobError("AssignProcessToJobObject",this.kernel.GetLastError());let inJob=new Uint8Array(4);if(this.kernel.IsProcessInJob(process2,this.handle,inJob)===0||new DataView(inJob.buffer).getInt32(0,!0)===0)throw new WindowsJobError("IsProcessInJob",this.kernel.GetLastError())}finally{this.kernel.CloseHandle(process2)}}memberPids(){let list=new Uint8Array(8200);if(this.kernel.QueryInformationJobObject(this.handle,3,list,list.byteLength,null)===0)return[];let view=new DataView(list.buffer),count=Math.min(view.getUint32(4,!0),1024);return Array.from({length:count},(_,index)=>Number(view.getBigUint64(8+index*8,!0)))}terminate(exitCode=1){this.closed||this.kernel.TerminateJobObject(this.handle,exitCode)}close(){this.closed||(this.closed=!0,this.kernel.CloseHandle(this.handle))}};function loadKernel32Job(){if(process.platform!=="win32")return;let ffi=process.getBuiltinModule("bun:ffi");if(ffi===void 0)return;let lib=ffi.dlopen("kernel32.dll",{CreateJobObjectW:{args:["ptr","ptr"],returns:"ptr"},SetInformationJobObject:{args:["ptr","i32","ptr","u32"],returns:"i32"},QueryInformationJobObject:{args:["ptr","i32","ptr","u32","ptr"],returns:"i32"},OpenProcess:{args:["u32","i32","u32"],returns:"ptr"},AssignProcessToJobObject:{args:["ptr","ptr"],returns:"i32"},IsProcessInJob:{args:["ptr","ptr","ptr"],returns:"i32"},TerminateJobObject:{args:["ptr","u32"],returns:"i32"},CloseHandle:{args:["ptr"],returns:"i32"},GetLastError:{args:[],returns:"u32"},GetCurrentProcess:{args:[],returns:"ptr"}}),call=(name,...args)=>{let fn=lib.symbols[name];if(fn===void 0)throw new Error(`kernel32 has no ${name}`);return fn(...args.map(arg=>arg instanceof Uint8Array?ffi.ptr(arg):arg))};return{CreateJobObjectW:()=>call("CreateJobObjectW",null,null),SetInformationJobObject:(job,infoClass,info,length)=>Number(call("SetInformationJobObject",job,infoClass,info,length)),QueryInformationJobObject:(job,infoClass,info,length)=>Number(call("QueryInformationJobObject",job,infoClass,info,length,null)),OpenProcess:(access,inherit,pid)=>call("OpenProcess",access,inherit,pid),AssignProcessToJobObject:(job,process2)=>Number(call("AssignProcessToJobObject",job,process2)),IsProcessInJob:(process2,job,result)=>Number(call("IsProcessInJob",process2,job,result)),TerminateJobObject:(job,exitCode)=>Number(call("TerminateJobObject",job,exitCode)),CloseHandle:handle=>Number(call("CloseHandle",handle)),GetLastError:()=>Number(call("GetLastError")),GetCurrentProcess:()=>call("GetCurrentProcess")}}var defaultInJob;function currentProcessInJob(kernel){if(kernel!==void 0)return queryInJob(kernel);if(defaultInJob===void 0){let loaded=loadKernel32Job();defaultInJob=loaded===void 0?!1:queryInJob(loaded)}return defaultInJob}function queryInJob(kernel){let result=new Uint8Array(4);return kernel.IsProcessInJob(kernel.GetCurrentProcess(),null,result)!==0&&new DataView(result.buffer).getInt32(0,!0)!==0}var FINISHED_SLOT_STATES=256,LaunchGateError=class extends Error{constructor(code,message){super(`${code}: ${message}`),this.name="LaunchGateError",this.code=code}},LaunchGate=class{#channel;#slots=new Map;#finished=new Map;#controls;#next=0;constructor(channel,clock=BarrierClock.create(),env=process.env,creatorInJob=currentProcessInJob){this.#channel=channel,this.clock=clock,this.#controls=readTestControls(env),this.#creatorInJob=creatorInJob}#creatorInJob;started(launchId,pid,breakaway=!1){this.#slots.has(launchId)&&this.#channel.send({type:"command_started",launchId,pid,startedAtMs:Date.now(),creatorInJob:this.#creatorInJob(),breakaway})}get skipsAckWait(){return this.#controls.enabled("SKIP_ACK_WAIT")}request(request){let slot=this.clock.claimSlot();if(slot===void 0)throw new LaunchGateError("tool_child_launch_capacity",`${this.clock.slots} launches in flight`);let launchId=`L${process.pid}-${++this.#next}`,ack,acked=new Promise(resolve=>{ack=resolve});return this.#slots.set(launchId,{slot,ack,lifetime:request.lifetime,request}),this.#channel.send({type:"launch",launchId,...request}),this.#controls.enabled("STOP_AFTER_SPAWN")&&process.kill(process.pid,"SIGSTOP"),{launchId,slot,acked}}adopt(launchId,slot,request){this.#slots.set(launchId,{slot,ack:()=>{},lifetime:request.lifetime,request}),this.#channel.send({type:"launch",launchId,...request})}handleWorker(message){message.kind==="launch"?this.adopt(message.launchId,message.slot,message.request):message.kind==="invoking"?this.invoking(message.launchId):message.kind==="started"?this.started(message.launchId,message.pid,message.breakaway):this.done(message.launchId,{...message.exitCode===void 0?{}:{exitCode:message.exitCode},...message.signal===void 0?{}:{signal:message.signal}})}handle(message){if(message.type==="launch_ack"){let entry=this.#slots.get(message.launchId);return entry!==void 0&&(this.clock.recordAck(entry.slot),entry.ack()),!0}if(message.type==="slot_query"){let entry=this.#slots.get(message.launchId),state=entry===void 0?this.#finished.get(message.launchId)??{ackTick:null,invokeTick:null,invocations:0}:this.clock.read(entry.slot);return this.#channel.send({type:"slot_state",launchId:message.launchId,...state}),!0}return!1}invokeNow(launchId){let entry=this.#slots.get(launchId);if(entry===void 0)throw new LaunchGateError("tool_child_launch_unknown",launchId);this.clock.recordInvoke(entry.slot),this.invoking(launchId)}invoking(launchId){let entry=this.#slots.get(launchId);if(entry===void 0)return;let state=this.clock.read(entry.slot),invokeTick=state.invokeTick;if(invokeTick===null)return;let send=()=>this.#channel.send({type:"launch_proof",launchId,ackTick:state.ackTick,invokeTick}),hold=this.#controls.value("HOLD_LAUNCH_PROOF");if(hold!==void 0&&(hold!=="detached"||entry.lifetime==="detached")){this.#controls.released(`release-proof-${launchId}`).then(send);return}send()}endJobGroups(jobId){let ended=[];for(let[launchId,{request}]of this.#slots)if(!(request.jobId!==jobId||request.lifetime!=="owned"||request.containment!=="own-group")&&!(request.pgid===void 0||request.pgid<=1))try{process.kill(-request.pgid,"SIGKILL"),ended.push({launchId,pgid:request.pgid})}catch{}for(let{launchId}of ended)this.done(launchId,{signal:"SIGKILL"});return ended.map(({pgid})=>pgid)}done(launchId,outcome){let entry=this.#slots.get(launchId);entry!==void 0&&(this.#slots.delete(launchId),this.#finished.set(launchId,this.clock.read(entry.slot)),this.#finished.size>FINISHED_SLOT_STATES&&this.#finished.delete(this.#finished.keys().next().value??""),this.clock.releaseSlot(entry.slot),this.#channel.send({type:"launch_done",launchId,...outcome.exitCode===void 0?{}:{exitCode:outcome.exitCode},...outcome.signal===void 0?{}:{signal:outcome.signal}}))}};import{mkdir as mkdir3,readdir as readdir2,readFile as readFile3,rm as rm4,writeFile as writeFile3}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";import{appendFile,mkdir as mkdir2,open,readFile as readFile2,rm as rm3}from"node:fs/promises";import{dirname as dirname2,join as join3}from"node:path";function generationLedgerPath(dir,generation){return join3(dir,`g${generation}`,"descendants.ledger")}var DescendantsLedger=class{#path;#durableDir=!1;#entries=new Map;constructor(path){this.#path=path}get path(){return this.#path}entries(){return[...this.#entries.values()]}async append(entry){if(!this.#durableDir){let directory=dirname2(this.#path);await mkdir2(directory,{recursive:!0,mode:448}),await(await open(this.#path,"a",384)).close(),await syncDirectory(directory),await syncDirectory(dirname2(directory)),this.#durableDir=!0}let handle=await open(this.#path,"a",384);try{await handle.write(`${JSON.stringify(entry)}
|
|
3
3
|
`),await handle.datasync()}finally{await handle.close()}this.#entries.set(entry.launchId,entry)}static async readPersisted(path){let text;try{text=await readFile2(path,"utf8")}catch{return[]}let entries=[];for(let line of text.split(`
|
|
4
4
|
`))if(line.trim()!=="")try{entries.push(JSON.parse(line))}catch{}return entries}async remove(){this.#entries.clear(),await rm3(this.#path,{force:!0})}};async function syncDirectory(directory){if(process.platform==="win32")return;let handle=await open(directory,"r");try{await handle.sync()}finally{await handle.close()}}var LaunchLog=class{#path;#chain=Promise.resolve();#failedWrites=0;constructor(path){this.#path=path}get path(){return this.#path}get failedWrites(){return this.#failedWrites}settled(){return this.#chain}record(record){let line=`${JSON.stringify({atMs:Date.now(),...record})}
|
|
5
5
|
`;return this.#chain=this.#chain.then(async()=>{try{await mkdir2(dirname2(this.#path),{recursive:!0,mode:448}),await appendFile(this.#path,line,{mode:384})}catch{this.#failedWrites+=1}}),this.#chain}};import{execFile}from"node:child_process";async function classifyGroup(group,ownGroup,probes){if(group.lifetime==="detached")return"detached";if(ownGroup===void 0||group.pgid===ownGroup||group.pgid<=1)return"own-group";if(!probes.groupHasMembers(group.pgid))return"empty";if(!probes.isAlive(group.pgid))return"sweep";let observed=await probes.startOf(group.pgid).catch(()=>{}),recorded=group.leaderStart===void 0?void 0:processStartTimeMs(group.leaderStart);return sameProcessStartMs(recorded,observed===void 0?void 0:processStartTimeMs(observed))?"sweep":"leader-reused"}async function sweepGroups(groups,options,probes=defaultGroupProbes){let ownGroup=await probes.ownGroup(),verdicts=await Promise.all(groups.map(async group=>({group,verdict:await classifyGroup(group,ownGroup,probes)}))),targets=verdicts.filter(entry=>entry.verdict==="sweep").map(entry=>entry.group.pgid);for(let pgid of targets)probes.signalGroup(pgid,"SIGTERM");let remaining=await drain(targets,options.graceMs,options.pollMs??25,probes);for(let pgid of remaining)probes.signalGroup(pgid,"SIGKILL");return remaining=await drain(remaining,options.killWaitMs,options.pollMs??25,probes),verdicts.map(({group,verdict})=>({launchId:group.launchId,pgid:group.pgid,verdict,...verdict==="sweep"?{survived:remaining.includes(group.pgid)}:{}}))}async function drain(pgids,budgetMs,pollMs,probes){let remaining=pgids.filter(pgid=>probes.groupHasMembers(pgid));for(let waited=0;remaining.length>0&&waited<budgetMs;waited+=pollMs)await probes.wait(pollMs),remaining=remaining.filter(pgid=>probes.groupHasMembers(pgid));return remaining}function processGroupOf(pid){return process.platform==="win32"?Promise.resolve(void 0):new Promise(resolve=>{execFile("ps",["-o","pgid=","-p",String(pid)],{timeout:2e3},(error,stdout)=>{let text=String(stdout).trim();resolve(error===null&&/^\d+$/u.test(text)?Number(text):void 0)})})}function groupHasMembers(pgid){try{return process.kill(-pgid,0),!0}catch(error){return error instanceof Error&&"code"in error&&error.code==="EPERM"}}var defaultGroupProbes={groupHasMembers,isAlive:processIsRunning,startOf:pid=>readProcessStartTime(pid),ownGroup:()=>processGroupOf(process.pid),signalGroup:(pgid,signal)=>{try{process.kill(-pgid,signal)}catch{}},wait:ms=>new Promise(resolve=>setTimeout(resolve,ms))};var SWEEP_TIMING={graceMs:500,killWaitMs:1e3};async function sweepLedger(path){let groups=(await DescendantsLedger.readPersisted(path)).flatMap(entry=>entry.pgid===void 0?[]:[{launchId:entry.launchId,pgid:entry.pgid,leaderStart:entry.leaderStart,lifetime:entry.lifetime}]);return groups.length===0?[]:sweepGroups(groups,SWEEP_TIMING)}var GENERATION_CHILD_FILE="child.pid";async function recordGenerationChild(dir,generation,pid){let generationDir=dirname3(generationLedgerPath(dir,generation));await mkdir3(generationDir,{recursive:!0,mode:448}),await writeFile3(join4(generationDir,GENERATION_CHILD_FILE),String(pid),{mode:384})}async function childAlive(file){let pid=Number(await readFile3(file,"utf8").catch(()=>""));if(!Number.isSafeInteger(pid)||pid<=1)return!1;try{return process.kill(pid,0),!0}catch(error){return Reflect.get(Object(error),"code")==="EPERM"}}async function sweepStaleGenerations(dir){let names=await readdir2(dir).catch(()=>[]),outcomes=[];for(let name of names){let generation=/^g(\d+)$/.exec(name)?.[1];generation!==void 0&&(await childAlive(join4(dir,name,GENERATION_CHILD_FILE))||(outcomes.push(...await sweepLedger(generationLedgerPath(dir,Number(generation)))),await rm4(join4(dir,name),{recursive:!0,force:!0})))}return outcomes}var TOOL_CHILD_GENERATION_ENV="SENPI_TOOL_CHILD_GENERATION",TOOL_CHILD_PROTOCOL_VERSION=2,NEVER_CANCELLED=new AbortController().signal;async function runToolChild(options){let env={...options.env??process.env},exit=options.exit??(code=>process.exit(code)),generation=Number(env[TOOL_CHILD_GENERATION_ENV]);(!Number.isSafeInteger(generation)||generation<0)&&(process.stderr.write(`tool-child: invalid generation
|
|
@@ -0,0 +1,13 @@
|
|
|
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{McpMrtrError,bindMcpFormPresented,enums,isRecord,privateMcpForms,queuedForm,validValue,validateMrtrForm}from"./chunk-JPGT64RV.js";import{redactResolvedReferenceValues}from"./chunk-DLAY7CIU.js";import{getAgentDir}from"./chunk-7YO7VQZW.js";var McpError=class extends Error{constructor(kind,name,message,options={}){super(message),this.name=name,this.kind=kind,this.phase=options.phase,this.retriable=options.retriable,this.serverName=options.serverName,options.cause!==void 0&&Object.defineProperty(this,"cause",{configurable:!0,value:options.cause,writable:!1}),Object.setPrototypeOf(this,new.target.prototype)}},ConnectError=class extends McpError{constructor(message,options={}){super("connect","ConnectError",message,options)}};var ToolExecError=class extends McpError{constructor(message,options={}){super("tool_exec","ToolExecError",message,options)}},AuthError=class extends McpError{constructor(message,options={}){super("auth","AuthError",message,options)}},TimeoutError=class extends McpError{constructor(message,options={}){super("timeout","TimeoutError",message,options)}},SessionExpiredError=class extends McpError{constructor(message,options={}){super("session_expired","SessionExpiredError",message,options)}},RETRIABLE_STATUS_CODES=new Set([404,502,503]),RETRIABLE_NUMERIC_CODES=new Set([-32001]),RETRIABLE_TEXT=["econnrefused","connection refused","transport closed"];function isRetriableMcpError(error){if(error instanceof McpError&&error.retriable===!0||isMcpSessionExpiredError(error)||hasRetriableNumericSignal(error,new Set))return!0;let text=collectText(error,new Set).join(" ").toLowerCase();return RETRIABLE_TEXT.some(needle=>text.includes(needle))?!0:/\b(?:404|502|503)\b/.test(text)}function isMcpSessionExpiredError(error){if(hasSessionExpiredNumericSignal(error,new Set))return!0;let text=collectText(error,new Set).join(" ").toLowerCase();return/\b404\b/.test(text)||text.includes("-32000")&&text.includes("session")||text.includes("session expired")||text.includes("session not found")||text.includes("mcp-session-id")}function hasRetriableNumericSignal(value,seen){if(typeof value!="object"||value===null||seen.has(value))return!1;seen.add(value);let code=numberFromUnknown(getProperty(value,"code"));if(code!==void 0&&RETRIABLE_NUMERIC_CODES.has(code))return!0;let status=numberFromUnknown(getProperty(value,"status"));if(status!==void 0&&RETRIABLE_STATUS_CODES.has(status))return!0;let statusCode=numberFromUnknown(getProperty(value,"statusCode"));return statusCode!==void 0&&RETRIABLE_STATUS_CODES.has(statusCode)?!0:hasRetriableNumericSignal(getProperty(value,"response"),seen)||hasRetriableNumericSignal(getProperty(value,"cause"),seen)}function hasSessionExpiredNumericSignal(value,seen){if(typeof value!="object"||value===null||seen.has(value))return!1;seen.add(value);let code=numberFromUnknown(getProperty(value,"code"));if(code===-32001)return!0;if(code===-32e3){let message=getProperty(value,"message");if(typeof message=="string"&&message.toLowerCase().includes("session"))return!0}return numberFromUnknown(getProperty(value,"status"))===404||numberFromUnknown(getProperty(value,"statusCode"))===404?!0:hasSessionExpiredNumericSignal(getProperty(value,"response"),seen)||hasSessionExpiredNumericSignal(getProperty(value,"cause"),seen)}function collectText(value,seen){if(typeof value=="string")return[value];if(typeof value=="number")return[String(value)];if(typeof value!="object"||value===null)return[];if(seen.has(value))return[];seen.add(value);let parts=[];value instanceof Error&&parts.push(value.message,value.name);for(let key of["message","code","status","statusCode"]){let property=getProperty(value,key);(typeof property=="string"||typeof property=="number")&&parts.push(String(property))}return parts.push(...collectText(getProperty(value,"response"),seen)),parts.push(...collectText(getProperty(value,"cause"),seen)),parts}function numberFromUnknown(value){if(typeof value=="number")return value;if(typeof value!="string"||value.trim()==="")return;let parsed=Number(value);return Number.isFinite(parsed)?parsed:void 0}function getProperty(value,key){if(!(typeof value!="object"||value===null))return value[key]}import{chmodSync,closeSync,openSync,renameSync,rmSync,statSync}from"node:fs";var LOG_SINK_RETRY_MS=5e3,ROTATION_LOCK_STALE_MS=1e4;function errorCode(error){return typeof error=="object"&&error!==null&&"code"in error&&typeof error.code=="string"?error.code:void 0}function exceedsCap(filePath,incomingBytes,maxBytes){try{return statSync(filePath).size+incomingBytes>maxBytes}catch(error){if(errorCode(error)==="ENOENT")return!1;throw error}}function clearStaleLock(lockPath){try{Date.now()-statSync(lockPath).mtimeMs>ROTATION_LOCK_STALE_MS&&rmSync(lockPath,{force:!0})}catch(error){if(errorCode(error)!=="ENOENT")throw error}}function rotateLogIfNeeded(filePath,incomingBytes,maxBytes){if(!exceedsCap(filePath,incomingBytes,maxBytes))return;let lockPath=`${filePath}.rotate-lock`,lock;try{lock=openSync(lockPath,"wx",384)}catch(error){if(errorCode(error)!=="EEXIST")throw error;clearStaleLock(lockPath);return}try{if(!exceedsCap(filePath,incomingBytes,maxBytes))return;try{renameSync(filePath,`${filePath}.1`)}catch(error){if(errorCode(error)==="ENOENT")return;throw error}chmodSync(`${filePath}.1`,384)}finally{closeSync(lock),rmSync(lockPath,{force:!0})}}import{closeSync as closeSync3,fchmodSync,mkdirSync as mkdirSync2,openSync as openSync3,writeSync as writeSync2}from"node:fs";import{dirname,join as join2}from"node:path";import{createHmac,randomBytes,randomUUID}from"node:crypto";import{closeSync as closeSync2,constants,fstatSync,fsyncSync,linkSync,mkdirSync,openSync as openSync2,readSync,rmSync as rmSync2,writeSync}from"node:fs";import{join}from"node:path";var KEY_FILE="config-identity.key",KEY_BYTES=32,EPHEMERAL_PREFIX="ephemeral:",processKey=randomBytes(KEY_BYTES),installationKeys=new Map,warnedPaths=new Set;function keyedIdentity(agentDir,payload){let key=installationKey(agentDir??getAgentDir());return key===void 0?`${EPHEMERAL_PREFIX}${hmac(processKey,payload)}`:hmac(key,payload)}function isEphemeralIdentity(identity){return identity?.startsWith(EPHEMERAL_PREFIX)===!0}function keyedFingerprint(value){return hmac(installationKey(getAgentDir())??processKey,value).slice(0,8)}function hmac(key,payload){return createHmac("sha256",key).update(payload).digest("hex")}function installationKey(agentDir){return installationKeys.has(agentDir)||installationKeys.set(agentDir,loadOrPublishKey(agentDir)),installationKeys.get(agentDir)}function loadOrPublishKey(agentDir){let path=join(agentDir,KEY_FILE),existing=readKey(path);return existing.kind==="valid"?existing.key:existing.kind==="missing"?publishKey(agentDir,path):void 0}function readKey(path){let fd;try{fd=openSync2(path,constants.O_RDONLY|(constants.O_NOFOLLOW??0))}catch(error){return isErrno(error,"ENOENT")?{kind:"missing"}:invalidKey(path,"cannot open safely","repair access and ensure it is a regular file, not a symlink")}try{let stat=fstatSync(fd);if(!stat.isFile())return invalidKey(path,"not a regular file","restore the original private key file");if(stat.size!==KEY_BYTES)return invalidKey(path,`wrong size (${stat.size} bytes)`,"restore the original 32-byte key from backup");if(process.platform!=="win32"){if(stat.uid!==process.getuid?.())return invalidKey(path,"wrong owner","chown the key file to your current user");if((stat.mode&511)!==384)return invalidKey(path,"wrong mode","chmod 600 the key file")}let key=Buffer.alloc(KEY_BYTES);return readSync(fd,key,0,KEY_BYTES,0)===KEY_BYTES?{kind:"valid",key}:invalidKey(path,"incomplete read","restore the original 32-byte key from backup")}finally{closeSync2(fd)}}function invalidKey(path,problem,repair){return warnedPaths.has(path)||(warnedPaths.add(path),console.warn(`MCP identity key ${path}: ${problem}; persistent catalog cache is disabled. To fix: ${repair}, then restart senpi. The file was left unchanged.`)),{kind:"invalid"}}function publishKey(agentDir,path){let temporary=`${path}.${process.pid}.${randomUUID()}.tmp`;try{mkdirSync(agentDir,{recursive:!0,mode:448});let key=randomBytes(KEY_BYTES),fd=openSync2(temporary,constants.O_CREAT|constants.O_EXCL|constants.O_WRONLY,384);try{writeSync(fd,key),fsyncSync(fd)}finally{closeSync2(fd)}return linkSync(temporary,path),syncDirectory(agentDir),key}catch(error){if(!isErrno(error,"EEXIST"))return;let published=readKey(path);return published.kind==="valid"?published.key:void 0}finally{rmSync2(temporary,{force:!0})}}function syncDirectory(directory){if(process.platform==="win32")return;let fd=openSync2(directory,constants.O_RDONLY);try{fsyncSync(fd)}finally{closeSync2(fd)}}function isErrno(error,code){return error instanceof Error&&"code"in error&&error.code===code}var DEFAULT_MAX_FILE_BYTES=1024*1024,MAX_RING_LINES=200,SENSITIVE_KEY_PATTERN=/(?:^|[_-])(?:api[_-]?key|key|token|secret|password|client_secret|auth|authorization)(?:$|[_-])/i,QUERY_SECRET_PATTERN=/([?&][^=\s&"'<>]*(?:key|token|secret|password|client_secret|auth)[^=\s&"'<>]*=)([^&\s"'<>]+)/gi,AUTHORIZATION_VALUE_PATTERN=/((?:"|')?\bAuthorization(?:"|')?\s*[:=]\s*(?:"|')?(?:[A-Za-z][A-Za-z0-9+.-]*\s+)?)(?!<redacted:)([^"',\s}\]&]+)/gi,BEARER_VALUE_PATTERN=/(\bBearer\s+)(?!<redacted:)([A-Za-z0-9._~+/=-]+)/gi,KEY_VALUE_PATTERN=/((?:"|')?[^"'\s:=,{}]*(?:api[_-]?key|key|token|secret|password|client_secret|auth)[^"'\s:=,{}]*(?:"|')?\s*[:=]\s*(?:"|')?)([^"',\s}\]&]+)/gi,MCP_LOG_LEVELS={emergency:{level:"emergency",severity:0},alert:{level:"alert",severity:1},critical:{level:"critical",severity:2},crit:{level:"critical",severity:2},error:{level:"error",severity:3},err:{level:"error",severity:3},warning:{level:"warning",severity:4},warn:{level:"warning",severity:4},notice:{level:"notice",severity:5},informational:{level:"info",severity:6},info:{level:"info",severity:6},debug:{level:"debug",severity:7}};function createMcpLogger(server,options={}){return new FileMcpLogger(server,options)}function getMcpLogDir(){return join2(getAgentDir(),"logs","mcp")}function fingerprintSecret(secret){return keyedFingerprint(secret)}function redactMcpLogText(text){return redactMcpLogTextWithContext(text,{seen:new WeakSet,secrets:new Set})}function redactMcpLogTextWithContext(text,context){return text.replace(AUTHORIZATION_VALUE_PATTERN,(_match,prefix,secret)=>`${prefix}${redactionForSecret(secret,context)}`).replace(BEARER_VALUE_PATTERN,(_match,prefix,secret)=>`${prefix}${redactionForSecret(secret,context)}`).replace(QUERY_SECRET_PATTERN,(_match,prefix,secret)=>`${prefix}${redactionForSecret(secret,context)}`).replace(KEY_VALUE_PATTERN,(match,prefix,secret)=>secret.startsWith("<redacted:")||/\bAuthorization\b/i.test(prefix)?match:`${prefix}${redactionForSecret(secret,context)}`)}function mapMcpLogLevel(level){return{...MCP_LOG_LEVELS[level]??MCP_LOG_LEVELS.info}}var FileMcpLogger=class{#server;#maxFileBytes;#ring=[];#fileSinkRetryAt=0;constructor(server,options){this.#server=server,this.#maxFileBytes=options.maxFileBytes??DEFAULT_MAX_FILE_BYTES,this.filePath=join2(options.logDir??getMcpLogDir(),`${sanitizeServerName(server)}.log`)}debug(message,data){this.log("debug",message,data)}info(message,data){this.log("info",message,data)}warn(message,data){this.log("warning",message,data)}error(message,data){this.log("error",message,data)}stderr(message,data){this.log("info",message,data,"stderr")}log(level,message,data,channel="server"){let line=this.#formatLine(level,message,data,channel);this.#pushRing(line),this.#writeFile(line)}getRingBuffer(){return[...this.#ring]}#formatLine(level,message,data,channel){let context={seen:new WeakSet,secrets:new Set},mapped=mapMcpLogLevel(level),redactedData=data===void 0?void 0:redactMcpLogData(data,context),entry={timestamp:new Date().toISOString(),server:this.#server,level:mapped.level,severity:mapped.severity,channel,message:redactMcpLogTextWithContext(message,context),data:redactedData};return redactResolvedReferenceValues(redactKnownSecrets(JSON.stringify(entry),context))}#pushRing(line){this.#ring.push(line),this.#ring.length>MAX_RING_LINES&&this.#ring.splice(0,this.#ring.length-MAX_RING_LINES)}#writeFile(line){if(!(Date.now()<this.#fileSinkRetryAt))try{mkdirSync2(dirname(this.filePath),{recursive:!0,mode:448});let bytes=Buffer.byteLength(`${line}
|
|
3
|
+
`);this.#maxFileBytes>0&&rotateLogIfNeeded(this.filePath,bytes,this.#maxFileBytes);let fd=openSync3(this.filePath,"a",384);try{writeSync2(fd,`${line}
|
|
4
|
+
`),fchmodSync(fd,384)}finally{closeSync3(fd)}}catch{this.#fileSinkRetryAt=Date.now()+LOG_SINK_RETRY_MS,this.#pushRing(this.#formatLine("warning","file sink disabled after write failure",void 0,"file"))}}};function redactMcpLogData(value,context){return typeof value=="string"?redactMcpLogTextWithContext(value,context):typeof value=="bigint"?value.toString():typeof value!="object"||value===null?value:context.seen.has(value)?"[Circular]":(context.seen.add(value),value instanceof Error?redactMcpLogError(value,context):Array.isArray(value)?value.map(item=>redactMcpLogData(item,context)):redactMcpLogEntries(value,context))}function redactMcpLogError(error,context){let redacted=redactMcpLogEntries(error,context);return redacted.name=redactMcpLogTextWithContext(error.name,context),redacted.message=redactKnownSecrets(redactMcpLogTextWithContext(error.message,context),context),error.stack!==void 0&&(redacted.stack=redactKnownSecrets(redactMcpLogTextWithContext(error.stack,context),context)),redacted}function redactMcpLogEntries(value,context){let redacted={};for(let[key,item]of Object.entries(value))SENSITIVE_KEY_PATTERN.test(key)?redacted[key]=redactionForSecret(stringifySecretValue(item),context):redacted[key]=redactMcpLogData(item,context);return redacted}function stringifySecretValue(value){if(typeof value=="string")return value;if(typeof value=="number"||typeof value=="boolean"||typeof value=="bigint")return String(value);let seen=new WeakSet;return JSON.stringify(value,(_key,item)=>typeof item=="bigint"?item.toString():typeof item!="object"||item===null?item:seen.has(item)?"[Circular]":(seen.add(item),item))??String(value)}function redactionForSecret(secret,context){return secret.length>0&&!secret.startsWith("<redacted:")&&context.secrets.add(secret),redactionFor(secret)}function redactKnownSecrets(text,context){for(let secret of[...context.secrets].sort((left,right)=>right.length-left.length))text=text.split(secret).join(redactionFor(secret));return text}function redactionFor(secret){return`<redacted:${fingerprintSecret(secret)}>`}function sanitizeServerName(server){return server.replace(/[^A-Za-z0-9._-]+/g,"_")||"server"}var mcpElapsedClock={now:()=>performance.now(),schedule:(callback,ms)=>setTimeout(callback,ms),cancel:timer=>clearTimeout(timer)};function wrapAsync(scope,fn,sink){return async(...args)=>{try{await fn(...args)}catch(error){let caughtError=error instanceof Error?error:normalizeCaughtError(error);await reportMcpAsyncError(scope,caughtError,sink)}}}function safeTimer(scope,delayMs,fn,sink){let wrapped=wrapAsync(scope,fn,sink),timer=setTimeout(()=>{wrapped()},delayMs);return timer.unref(),timer}function safeInterval(scope,delayMs,fn,sink){let wrapped=wrapAsync(scope,fn,sink),timer=setInterval(()=>{wrapped()},delayMs);return timer.unref(),timer}function safeDelay(delayMs){return new Promise(resolve=>{setTimeout(resolve,delayMs)})}function safeOn(emitter,eventName,scope,listener,sink){let wrapped=wrapAsync(scope,listener,sink);return emitter.on(eventName,wrapped),()=>{emitter.off(eventName,wrapped)}}function safeEventBusOn(bus,channel,handler){return bus.on(channel,handler)}async function reportMcpAsyncError(scope,error,sink){let normalized=normalizeError(error);if(logError(scope,normalized,sink.logger),!!sink.notify)try{await sink.notify(`MCP ${scope} failed: ${normalized.message}`,normalized)}catch(notifyError){let caughtNotifyError=notifyError instanceof Error?notifyError:normalizeCaughtError(notifyError);logError(`${scope}.notify`,caughtNotifyError,sink.logger)}}function logError(scope,error,logger){try{logger.error(scope,serializeError(error))}catch{let redactedScope=redactMcpLogText(scope);console.error(`MCP ${redactedScope} logger failed; suppressed async error details`)}}function serializeError(error){let serialized={name:error.name,message:error.message};return error.stack&&(serialized.stack=error.stack),serialized}function normalizeError(error){return error instanceof Error?error:normalizeCaughtError(error)}function normalizeCaughtError(error){return typeof error=="string"?new Error(error):new Error(safeStringify(error))}function safeStringify(value){try{return JSON.stringify(value)??String(value)}catch{return String(value)}}function memoizeLoader(load){let loaded,loading;return()=>loaded!==void 0?Promise.resolve(loaded):(loading??=load().then(module=>(loaded=module,module)).finally(()=>{loading=void 0}),loading)}var loadMcpSdkClient=memoizeLoader(()=>import("./client-LOS6GSEW.js")),loadMcpSdkZodCompat=memoizeLoader(()=>import("./zod-compat-RJDXCU7S.js")),loadMcpSdkStdioTransport=memoizeLoader(()=>import("./stdio-YXDKKKQZ.js")),loadMcpSdkTypes=memoizeLoader(()=>import("./types-BJUEQ4II.js")),authModule,loadMcpSdkAuth=memoizeLoader(async()=>{let module=await import("./auth-C77UQA55.js");return authModule=module,module}),loadMcpSdkStreamableHttpTransport=memoizeLoader(async()=>{let[module]=await Promise.all([import("./streamableHttp-DKIBUWVY.js"),loadMcpSdkAuth()]);return module});function isMcpSdkUnauthorizedError(error){return authModule!==void 0&&error instanceof authModule.UnauthorizedError}import{stripVTControlCharacters}from"node:util";var own=(value,key)=>Object.hasOwn(value,key),inert=value=>stripVTControlCharacters(value).replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g,"");async function collectMrtrForm(presentation,serverLabel,params,signal){if(!validateMrtrForm(params.requestedSchema))throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");let schema=params.requestedSchema,abort=new AbortController,combined=AbortSignal.any([signal,presentation.signal,abort.signal]),opts={signal:combined,ephemeral:!0};bindMcpFormPresented(opts,presentation.presented);let heading=`MCP server: ${inert(serverLabel)}
|
|
5
|
+
${inert(params.message)}`,select=async(title,choices)=>{if(combined.aborted)return;let result=await presentation.ui.select(title,choices,opts);return combined.aborted?void 0:result},content=Object.create(null),finish=result=>(combined.aborted||presentation.admit?.(),result),required=new Set(schema.required??[]),entries=Object.entries(schema.properties),field=async(name,property)=>{let title=`${heading}
|
|
6
|
+
${inert(String(property.title??name))}${typeof property.description=="string"?`
|
|
7
|
+
${inert(property.description)}`:""}`;for(;;){let actions=["Enter value"];required.has(name)||actions.push("Leave unset"),own(property,"default")&&actions.push("Use default");let action="Enter value";if(actions.length>1){let chosen=await select(title,actions);if(chosen===void 0)return!1;action=chosen}if(action==="Leave unset")return delete content[name],!0;if(action==="Use default")return content[name]=structuredClone(property.default),!0;let value;if(property.type==="boolean"){let chosen=await select(title,["true","false"]);if(chosen===void 0)return!1;value=chosen==="true"}else if(property.type==="array"||enums(property)){let choices=property.type==="array"&&isRecord(property.items)?enums(property.items):enums(property);if(choices===void 0)return!1;let values=[];for(;;){let labels=choices.map((choice2,index2)=>`${index2+1}. ${inert(choice2.label)}${values.includes(choice2.value)?" [selected]":""}`);property.type==="array"&&labels.push("Done");let chosen=await select(title,labels);if(chosen===void 0)return!1;if(chosen==="Done"){value=values;break}let index=labels.indexOf(chosen),choice=choices[index];if(!choice)continue;if(property.type!=="array"){value=choice.value;break}let existing=values.indexOf(choice.value);existing>=0?values.splice(existing,1):values.push(choice.value)}}else{if(combined.aborted)return!1;let text=await presentation.ui.input(title,void 0,opts);if(text===void 0||combined.aborted)return!1;value=property.type==="number"||property.type==="integer"?text.trim()===""?NaN:Number(text):text}if(validValue(property,value))return content[name]=value,!0;if(await select(`${title}
|
|
8
|
+
Value does not satisfy this field.`,["Try again","Cancel"])!=="Try again")return!1}};try{let begin=await select(heading,["Continue","Decline","Cancel"]);if(begin!=="Continue")return finish({action:begin==="Decline"?"decline":"cancel"});for(let[name,property]of entries)if(!await field(name,property))return finish({action:"cancel"});for(;;){let review=entries.map(([name])=>`${inert(name)}: ${own(content,name)?inert(JSON.stringify(content[name])):"(unset)"}`).join(`
|
|
9
|
+
`),action=await select(`${heading}
|
|
10
|
+
Review
|
|
11
|
+
${review}`,["Submit","Edit field","Decline","Cancel"]);if(action==="Submit"&&!combined.aborted)return finish({action:"accept",content:structuredClone(content)});if(action!=="Edit field")return finish({action:action==="Decline"?"decline":"cancel"});let labels=entries.map(([name],index)=>`${index+1}. ${inert(name)}`),chosen=await select(`${heading}
|
|
12
|
+
Edit field`,labels),entry=chosen===void 0?void 0:entries[labels.indexOf(chosen)];if(!entry||!await field(...entry))return finish({action:"cancel"})}}finally{bindMcpFormPresented(opts,void 0),abort.abort();for(let key of Object.keys(content))delete content[key]}}var originOption=Symbol("mcp-request-origin"),origins=new WeakSet,aliases=new WeakMap,physicalMcpClient=client=>aliases.get(client)??client;function registerMcpClientAlias(alias,physical){aliases.set(alias,physical)}var legacyOperations=new WeakMap;function beginLegacyMcpOperation(client,origin,caller){let lifetime=new AbortController,operation={origin,signal:AbortSignal.any([origin.signal,lifetime.signal,...caller?[caller]:[]])},operations=legacyOperations.get(client);return operations||(operations=new Set,legacyOperations.set(client,operations)),operations.add(operation),()=>{operations.delete(operation),lifetime.abort(),operations.size===0&&legacyOperations.delete(client)}}function legacyMcpOperation(client){let operations=legacyOperations.get(client);if(operations&&operations.size>1)return"ambiguous";if(operations?.size!==1)return;let operation=operations.values().next().value;return operation&&!operation.signal.aborted&&operation.origin.isCurrent()?operation:void 0}function createMcpRequestOrigin(origin){return origins.add(origin),origin}function mcpRequestOptions(origin,options={}){return origin===void 0?options:{...options,[originOption]:origin}}function takeMcpRequestOrigin(options,client){let supplied=options,origin=supplied?.[originOption],{[originOption]:_origin,...sdkOptions}=supplied??{};if(origin!==void 0){if(!origins.has(origin)||!origin.isCurrent())throw new McpMrtrError("MCP_MRTR_CONTEXT_CHANGED");let candidate=origin.connection.client;if(physicalMcpClient(candidate)!==client)throw new McpMrtrError("MCP_MRTR_CONTEXT_CHANGED")}return{origin,sdkOptions}}var own2=(value,key)=>Object.hasOwn(value,key),byteSize=value=>Buffer.byteLength(JSON.stringify(value),"utf8");function parseInputs(result){if(!own2(result,"requestState")&&!own2(result,"inputRequests"))throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");if(own2(result,"requestState")&&typeof result.requestState!="string")throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");if(byteSize(result)>512*1024||typeof result.requestState=="string"&&Buffer.byteLength(result.requestState)>64*1024)throw new McpMrtrError("MCP_MRTR_INPUT_LIMIT");if(!own2(result,"inputRequests"))return;if(!isRecord(result.inputRequests))throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");let entries=Object.entries(result.inputRequests);if(entries.length>32)throw new McpMrtrError("MCP_MRTR_INPUT_LIMIT");for(let[,input]of entries)if(isRecord(input)&&["roots/list","sampling/createMessage"].includes(String(input.method)))throw new McpMrtrError("MCP_MRTR_UNSUPPORTED_INPUT");let inputs=new Map,checkStrings=value=>{if(typeof value=="string"&&Buffer.byteLength(value)>16*1024)throw new McpMrtrError("MCP_MRTR_INPUT_LIMIT");if(Array.isArray(value))for(let entry of value)checkStrings(entry);else if(isRecord(value))for(let[key,entry]of Object.entries(value))checkStrings(key),checkStrings(entry)};for(let[key,input]of entries){if(checkStrings(key),!isRecord(input)||input.method!=="elicitation/create"||!isRecord(input.params)||typeof input.params.message!="string")throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");let params=input.params;if(checkStrings(params),params.mode==="url")throw typeof params.url!="string"||typeof params.elicitationId!="string"?new McpMrtrError("MCP_MRTR_INVALID_INPUT"):new McpMrtrError("MCP_MRTR_UNSUPPORTED_INPUT");if(params.mode!==void 0&¶ms.mode!=="form")throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");if(isRecord(params.requestedSchema)&&isRecord(params.requestedSchema.properties)&&Object.keys(params.requestedSchema.properties).length>64)throw new McpMrtrError("MCP_MRTR_INPUT_LIMIT");if(!validateMrtrForm(params.requestedSchema))throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");inputs.set(key,input)}return inputs}var MAX_MCP_MRTR_ROUNDS=8,capableMethods=new Set(["tools/call","resources/read","prompts/get"]),capabilitiesKey="io.modelcontextprotocol/clientCapabilities",modernDispatchGuard=Symbol("mcp-modern-dispatch"),states=new WeakMap,isModernMcpClient=client=>states.get(physicalMcpClient(client))?.version!==void 0,legacyMcpFormsAdvertised=client=>states.get(physicalMcpClient(client))?.legacyFormEligible,own3=(value,key)=>Object.hasOwn(value,key),byteSize2=value=>Buffer.byteLength(JSON.stringify(value),"utf8");function getModernDispatchGuard(params){return isRecord(params)?params[modernDispatchGuard]:void 0}function installModernRequestAdapter(client,protocol,clock=mcpElapsedClock,readCredential=()=>{}){let sdkRequest=client.request.bind(client);states.set(client,protocol);let requestWithMrtr=async(request,schema,options)=>{if(request.method==="initialize")return sdkRequest(request,schema,options);let{origin,sdkOptions}=takeMcpRequestOrigin(options,client);if(protocol.version===void 0){let end=request.method==="tools/call"&&origin?beginLegacyMcpOperation(client,origin,sdkOptions.signal):void 0;try{return await sdkRequest(request,schema,sdkOptions)}finally{end?.()}}if(own3(request.params??{},"requestState")||own3(request.params??{},"inputResponses")||options?.task)throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");let params=structuredClone(request.params??{}),start=clock.now(),timeout=sdkOptions.timeout??6e4,duration=Math.min(sdkOptions.maxTotalTimeout??1/0,9*timeout+3e5),deadline=start+duration,operation=new AbortController,credential=readCredential(),authority,authorityCaptured=!1,controller=origin?.connection,generation=controller?.generation,presentationLost=origin?.presentation===void 0||origin.presentation.signal.aborted,consentSpent=0,continuation={},failure,stop=code=>{failure??=new McpMrtrError(code),operation.abort(failure)},onCallerAbort=()=>stop("MCP_MRTR_CANCELLED"),onOwnerAbort=()=>stop("MCP_MRTR_CONTEXT_CHANGED"),onPresentationLost=()=>{presentationLost=!0},check=()=>{if(clock.now()>=deadline&&stop("MCP_MRTR_TIMEOUT"),origin&&(!origin.isCurrent()||origin.signal.aborted||controller?.generation!==generation||controller?.state!=="connected")&&stop("MCP_MRTR_CONTEXT_CHANGED"),failure)throw failure},resolveAuthority=async()=>{if(check(),origin){await origin.privateForm?.synchronize?.();let snapshot=JSON.stringify(await interrupted(origin.resolveAuthority(operation.signal),operation.signal));authorityCaptured?authority!==snapshot&&stop("MCP_MRTR_CONTEXT_CHANGED"):(authority=snapshot,authorityCaptured=!0)}check()},off=controller?.onStateChange(()=>{try{check()}catch{}});sdkOptions.signal?.addEventListener("abort",onCallerAbort,{once:!0}),origin?.signal.addEventListener("abort",onOwnerAbort,{once:!0}),origin?.presentation?.signal.addEventListener("abort",onPresentationLost,{once:!0});let timer=clock.schedule(()=>stop("MCP_MRTR_TIMEOUT"),Math.max(0,duration));sdkOptions.signal?.aborted&&onCallerAbort(),origin?.signal.aborted&&onOwnerAbort();try{let{safeParse}=await interrupted(loadMcpSdkZodCompat(),operation.signal),{ResultSchema}=await interrupted(loadMcpSdkTypes(),operation.signal);for(let round=0;;round++){await resolveAuthority();let remaining=deadline-clock.now(),attempt=new AbortController,forward=()=>attempt.abort("MCP request canceled");operation.signal.addEventListener("abort",forward,{once:!0});let metadata=isRecord(params._meta)?params._meta:{},capabilities=origin?.privateFormsEnforced?origin.privateForm?.ready()?{elicitation:{}}:{}:!presentationLost&&origin?.presentation?{elicitation:{}}:{},outgoing={...params,...continuation,_meta:{...metadata,[capabilitiesKey]:capabilities},[modernDispatchGuard]:snapshot=>{if(check(),(snapshot??readCredential())!==credential)throw new McpMrtrError("MCP_MRTR_CONTEXT_CHANGED")}},result;try{check(),result=await sdkRequest({method:request.method,params:outgoing},ResultSchema,{...sdkOptions,signal:attempt.signal,timeout:Math.min(timeout,remaining),maxTotalTimeout:remaining,onprogress:sdkOptions.onprogress?progress=>{check(),!(!Number.isFinite(progress.progress)||progress.total!==void 0&&!Number.isFinite(progress.total))&&sdkOptions.onprogress?.({progress:progress.progress,...progress.total===void 0?{}:{total:progress.total}})}:void 0})}finally{operation.signal.removeEventListener("abort",forward)}check();let type=own3(result,"resultType")?result.resultType:"complete";if(type==="complete"){if(["requestState","inputRequests","inputResponses"].some(key=>own3(result,key)))throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");let parsed=safeParse(schema,result);if(!parsed.success)throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");return parsed.data}if(type!=="input_required"||!capableMethods.has(request.method))throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");if(round>=MAX_MCP_MRTR_ROUNDS)throw new McpMrtrError("MCP_MRTR_ROUND_LIMIT");let inputs=parseInputs(result);if(continuation=own3(result,"requestState")?{requestState:result.requestState}:{},inputs){let responses=Object.create(null),cancelled=!1;for(let[key,input]of inputs){if(await resolveAuthority(),input.params.mode==="url")throw new McpMrtrError("MCP_MRTR_UNSUPPORTED_INPUT");if(cancelled)throw new McpMrtrError("MCP_MRTR_CANCELLED");if(consentSpent>=3e5)throw new McpMrtrError("MCP_MRTR_PROCESSING_UNAVAILABLE");if(origin?.privateFormsEnforced){let presenter=origin.privateForm,schema2=input.params.requestedSchema;if(!presenter?.ready()||!validateMrtrForm(schema2))throw new McpMrtrError("MCP_MRTR_PROCESSING_UNAVAILABLE");let began=clock.now(),outcome=await presenter.present({operationId:String(start),inputId:key,round,server:{label:origin.serverLabel,source:origin.serverSource??"user"},message:input.params.message,schema:schema2,operationSignal:operation.signal,presentationSignal:presenter.signal,deadlineMs:Math.max(0,3e5-consentSpent)});if(consentSpent+=clock.now()-began,check(),outcome.kind!=="result")throw new McpMrtrError(outcome.kind==="operation_aborted"?"MCP_MRTR_CANCELLED":"MCP_MRTR_PROCESSING_UNAVAILABLE");responses[key]=outcome.result,cancelled=outcome.result.action!=="accept"}else{if(presentationLost||!origin?.presentation)throw new McpMrtrError("MCP_MRTR_PROCESSING_UNAVAILABLE");{let consent=new AbortController,began=clock.now(),consentTimer=clock.schedule(()=>consent.abort(),Math.max(0,3e5-consentSpent)),signal=AbortSignal.any([operation.signal,origin.presentation.signal,consent.signal]),presented=!1;try{let answer=await interrupted(queuedForm(origin.binding,signal,()=>(presented=!0,collectMrtrForm(origin.presentation,origin.serverLabel,{message:input.params.message,requestedSchema:input.params.requestedSchema},signal))),operation.signal);if(check(),!presented)throw new McpMrtrError("MCP_MRTR_PROCESSING_UNAVAILABLE");responses[key]=answer,cancelled=answer.action!=="accept"}finally{consentSpent+=clock.now()-began,clock.cancel(consentTimer),consent.abort()}}}}if(byteSize2(responses)>512*1024)throw new McpMrtrError("MCP_MRTR_INPUT_LIMIT");continuation.inputResponses=responses}}}catch(error){if(check(),error instanceof McpMrtrError||error instanceof AuthError)throw error;let remoteCode=isRecord(error)&&typeof error.code=="number"?error.code:void 0;throw new McpMrtrError("MCP_MRTR_TRANSPORT_FAILED",remoteCode)}finally{continuation={},clock.cancel(timer),off?.(),sdkOptions.signal?.removeEventListener("abort",onCallerAbort),origin?.signal.removeEventListener("abort",onOwnerAbort),origin?.presentation?.signal.removeEventListener("abort",onPresentationLost)}};protocol.activateRequests=()=>{client.request=requestWithMrtr},(protocol.privateForms||protocol.version!==void 0)&&protocol.activateRequests()}function interrupted(work,signal){return new Promise((resolve,reject)=>{let onabort=()=>reject(signal.reason);signal.addEventListener("abort",onabort,{once:!0}),signal.aborted&&onabort(),work.then(resolve,reject).finally(()=>signal.removeEventListener("abort",onabort))})}var OAuthFlowError=class extends AuthError{constructor(oauthKind,message,options={}){super(message,options),this.name="OAuthFlowError",this.oauthKind=oauthKind,this.terminal=TERMINAL_KINDS.has(oauthKind)}},TERMINAL_KINDS=new Set(["s256_unsupported","needs_auth","invalid_grant","state_mismatch","expired_code","no_verifier","headless","missing_env"]),TERMINAL_OAUTH_CODES=new Set(["invalid_grant","invalid_token","invalid_client","unauthorized_client"]),TRANSIENT_OAUTH_CODES=new Set(["temporarily_unavailable","server_error","slow_down"]);function isInvalidGrant(error){let code=oauthErrorCode(error);if(code!==void 0)return TERMINAL_OAUTH_CODES.has(code);let text=errorText(error).toLowerCase();return text.includes("invalid_grant")||text.includes("invalid_token")}function isTransientTokenError(error){if(isInvalidGrant(error))return!1;let code=oauthErrorCode(error);if(code!==void 0&&TRANSIENT_OAUTH_CODES.has(code))return!0;let text=errorText(error).toLowerCase();return/\b(?:500|502|503|504)\b/.test(text)||text.includes("econnrefused")||text.includes("network")}function oauthErrorCode(error){if(typeof error!="object"||error===null)return;let code=error.errorCode;return typeof code=="string"?code:void 0}function errorText(error){return error instanceof Error?`${error.name} ${error.message}`:String(error)}var MAX_CAUSE_DEPTH=5;function isMcpNeedsAuthError(error,depth=0){return isMcpSdkUnauthorizedError(error)?!0:error instanceof OAuthFlowError?error.terminal:depth<MAX_CAUSE_DEPTH&&error!==null&&typeof error=="object"&&"cause"in error?isMcpNeedsAuthError(error.cause,depth+1):!1}var MCP_CLIENT_ELICITATION_CAPABILITY={elicitation:{}};function mcpClientCapabilities(elicitationEnabled=!0){return elicitationEnabled?MCP_CLIENT_ELICITATION_CAPABILITY:{}}var MCP_ELICITATION_TIMEOUT_MS=300*1e3,legacyUiProvider;async function rejectElicitation(){let{ErrorCode,McpError:McpError2}=await loadMcpSdkTypes();throw new McpError2(ErrorCode.InternalError,"Elicitation cannot be processed")}function legacyMcpFormEligible(provider,enabled){if(!enabled)return!1;if(provider?.eligible)return provider.eligible();let ui=provider?.(),binding=ui===void 0?void 0:privateMcpForms(ui);return binding===void 0||binding.capture()?.ready()===!0}async function rejectPrivateElicitation(){let{ErrorCode,McpError:McpError2}=await loadMcpSdkTypes();throw new McpError2(ErrorCode.InternalError,"Elicitation processing unavailable")}async function privateElicitation(client,params,signal,requestId,timeoutMs){let operation=legacyMcpOperation(client);if(operation==="ambiguous")return rejectPrivateElicitation();let presenter=operation?.origin.privateForm;if(!isRecord(params)||typeof params.message!="string"||params.mode!==void 0&¶ms.mode!=="form"||!operation||!presenter?.ready()||!validateMrtrForm(params.requestedSchema))return rejectPrivateElicitation();let outcome=await presenter.present({operationId:String(requestId),inputId:String(requestId),round:0,server:{label:operation.origin.serverLabel,source:operation.origin.serverSource??"user"},message:params.message,schema:params.requestedSchema,operationSignal:AbortSignal.any([operation.signal,signal]),presentationSignal:presenter.signal,deadlineMs:timeoutMs});return outcome.kind!=="result"||operation.signal.aborted||!operation.origin.isCurrent()?rejectPrivateElicitation():outcome.result}async function configureMcpElicitation(client,owner=legacyUiProvider,timeoutMs=MCP_ELICITATION_TIMEOUT_MS,elicitationEnabled=!0){if(!elicitationEnabled){let{ErrorCode,McpError:McpError2}=await loadMcpSdkTypes();client.fallbackRequestHandler=async request=>{if(request.method==="elicitation/create")return typeof owner=="function"&&owner.enforced?.()?rejectPrivateElicitation():rejectElicitation();throw new McpError2(ErrorCode.MethodNotFound,"Method not found")};return}let{ElicitRequestSchema}=await loadMcpSdkTypes();if(typeof owner=="function"&&owner.enforced?.()){client.setRequestHandler(ElicitRequestSchema.omit({params:!0}).passthrough(),(request,extra)=>privateElicitation(client,request.params,extra.signal,extra.requestId,timeoutMs));return}client.setRequestHandler(ElicitRequestSchema,async(request,extra)=>{let params=request.params;if(!("requestedSchema"in params))return rejectElicitation();let ui=typeof owner=="function"?owner():owner?.getMcpElicitationUi();return typeof owner=="function"&&owner.enforced?.()||ui!==void 0&&privateMcpForms(ui)!==void 0?privateElicitation(client,params,extra.signal,extra.requestId,timeoutMs):ui===void 0?rejectElicitation():await runElicitationForm(ui,params.message,params.requestedSchema,timeoutMs)})}async function runElicitationForm(ui,message,requestedSchema,timeoutMs=MCP_ELICITATION_TIMEOUT_MS){let timer,timeout=new Promise(resolve=>{timer=safeTimer("mcp.elicitation.timeout",timeoutMs,()=>resolve({action:"cancel"}),{logger:createMcpLogger("elicitation")})});try{return await Promise.race([collectForm(ui,message,requestedSchema),timeout])}finally{timer!==void 0&&clearTimeout(timer)}}async function collectForm(ui,message,requestedSchema){let content={},required=new Set(requestedSchema.required??[]);for(let[name,property]of Object.entries(requestedSchema.properties??{})){let title=`${message} - ${property.title??name}`;if(property.type==="boolean"){let picked=await ui.select(property.description?`${title}
|
|
13
|
+
${property.description}`:title,["Yes","No"]);if(picked===void 0)return{action:"cancel"};switch(picked.trim().toLowerCase()){case"yes":case"y":case"true":content[name]=!0;break;case"no":case"n":case"false":content[name]=!1;break;default:return rejectElicitation()}continue}if(Array.isArray(property.enum)&&property.enum.length>0){let picked=await ui.select(title,property.enum.map(String));if(picked===void 0)return{action:"cancel"};content[name]=picked;continue}let answer=await ui.input(title,property.description);if(answer===void 0)return{action:"cancel"};if(answer.length===0){if(required.has(name))return rejectElicitation();continue}if(property.type==="number"||property.type==="integer"){let parsed=Number(answer);if(!Number.isFinite(parsed))return rejectElicitation();content[name]=parsed;continue}content[name]=answer}return Object.keys(content).length===0&&await ui.select(message,["Submit"])!=="Submit"?{action:"cancel"}:{action:"accept",content}}import{execFile}from"node:child_process";import{promisify}from"node:util";var execFileAsync=promisify(execFile);async function collectProcessTree(rootPid){let seen=new Set,queue=[rootPid];for(let index=0;index<queue.length;index++){let pid=queue[index];if(!seen.has(pid)){seen.add(pid);for(let childPid of await childPids(pid))seen.has(childPid)||queue.push(childPid)}}return[...seen]}async function reapProcessTree(rootPid,options){let knownPids=new Set(await collectProcessTree(rootPid));if(someProcessAlive(knownPids)){killPids(knownPids,"SIGTERM"),await waitForDead(knownPids,options.termWaitMs);for(let pid of await collectProcessTree(rootPid))knownPids.add(pid);someProcessAlive(knownPids)&&(killPids(knownPids,"SIGKILL"),await waitForDead(knownPids,options.killWaitMs))}}function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch(error){return!1}}function delay(ms){return safeDelay(ms)}async function childPids(parentPid){if(!["darwin","linux"].includes(process.platform))return[];try{let{stdout}=await execFileAsync("pgrep",["-P",String(parentPid),"."],{timeout:1e3});return stdout.split(/\s+/).map(Number).filter(pid=>Number.isInteger(pid)&&pid>0)}catch(error){return[]}}function killPids(pids,signal){for(let pid of[...pids].reverse())if(!(!Number.isInteger(pid)||pid<=1))try{process.kill(pid,signal)}catch(error){}}async function waitForDead(pids,timeoutMs){let deadline=Date.now()+timeoutMs;for(;Date.now()<deadline;){if(!someProcessAlive(pids))return;await delay(25)}}function someProcessAlive(pids){for(let pid of pids)if(isProcessAlive(pid))return!0;return!1}export{LOG_SINK_RETRY_MS,rotateLogIfNeeded,keyedIdentity,isEphemeralIdentity,createMcpLogger,fingerprintSecret,redactMcpLogText,mcpElapsedClock,wrapAsync,safeTimer,safeInterval,safeDelay,safeOn,safeEventBusOn,reportMcpAsyncError,ConnectError,ToolExecError,AuthError,TimeoutError,SessionExpiredError,isRetriableMcpError,isMcpSessionExpiredError,OAuthFlowError,isInvalidGrant,isTransientTokenError,loadMcpSdkClient,loadMcpSdkStdioTransport,loadMcpSdkTypes,loadMcpSdkAuth,loadMcpSdkStreamableHttpTransport,registerMcpClientAlias,createMcpRequestOrigin,mcpRequestOptions,collectMrtrForm,modernDispatchGuard,isModernMcpClient,legacyMcpFormsAdvertised,getModernDispatchGuard,installModernRequestAdapter,isMcpNeedsAuthError,mcpClientCapabilities,legacyMcpFormEligible,configureMcpElicitation,reapProcessTree,delay};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
-
import{connectAuthenticatedRpcSocket,socketNeedsHandshake}from"./chunk-
|
|
2
|
+
import{connectAuthenticatedRpcSocket,socketNeedsHandshake}from"./chunk-H4WJ4LY3.js";import{RpcEndpointAuthError}from"./chunk-GWGNVYPB.js";import{readSocketSecret,resolveSocketTransportAddress,sendSocketHandshake,socketSecretPath}from"./chunk-ZGAB7WQA.js";import{createConnection}from"node:net";var PROBE_REQUEST_ID="ensure-host-probe";async function requestOnSocket(socketPath,command,timeoutMs,options={}){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,...command},timeoutMs,!1,options)).answer}async function connectAndAsk(socketPath,request,timeoutMs,keep=!1,options={}){let secret;if(socketNeedsHandshake(socketPath))try{secret=await readSocketSecret(socketSecretPath(socketPath))}catch{return{connected:!1,answer:void 0}}let authenticated,deadline=Date.now()+timeoutMs;if(!socketNeedsHandshake(socketPath)){try{authenticated=await connectAuthenticatedRpcSocket(socketPath,request.type==="get_protocol_info"?request:void 0,options,timeoutMs)}catch(cause){if(cause instanceof RpcEndpointAuthError)throw cause;return{connected:cause instanceof Error&&"rpcSocketConnected"in cause&&cause.rpcSocketConnected===!0,answer:void 0}}if(request.type==="get_protocol_info"){let answer=authenticated.protocol.data??{};return keep?{connected:!0,answer,kept:authenticated.socket}:(authenticated.socket.destroy(),{connected:!0,answer})}}return new Promise((resolveProbe,rejectProbe)=>{let socket=authenticated?.socket??createConnection(resolveSocketTransportAddress(socketPath,process.platform,secret)),buffer="",settled=!1,connected=authenticated!==void 0,finish=value=>{if(!settled){if(settled=!0,clearTimeout(timeout),socket.removeAllListeners("data"),keep&&value!==void 0&&!socket.destroyed){resolveProbe({connected,answer:value,kept:socket});return}socket.destroy(),resolveProbe({connected,answer:value})}},timeout=setTimeout(()=>finish(),Math.max(0,deadline-Date.now())),send=()=>{connected=!0,socket.write(`${JSON.stringify(request)}
|
|
3
3
|
`)};socket.on("data",chunk=>{for(buffer+=chunk.toString("utf8");;){let newline=buffer.indexOf(`
|
|
4
4
|
`);if(newline===-1)return;let line=buffer.slice(0,newline);buffer=buffer.slice(newline+1);let value;try{value=JSON.parse(line)}catch{continue}if(isRecord(value)&&value.id===request.id&&(value.errorCode==="auth_required"||value.errorCode==="auth_failed")){clearTimeout(timeout),settled=!0,socket.destroy(),rejectProbe(new RpcEndpointAuthError(value.errorCode,`${socketPath}; set SENPI_RPC_KEY_ROOT to the host's agent dir`));return}let answer=readAnswer(line,typeof request.id=="string"?request.id:PROBE_REQUEST_ID);if(answer!==void 0)return finish(answer)}}),socket.once("error",()=>finish()),socket.once("close",()=>finish()),secret&&sendSocketHandshake(socket,secret),authenticated?send():socket.once("connect",send)})}function readAnswer(text,id=PROBE_REQUEST_ID){let parsed;try{parsed=JSON.parse(text)}catch{return}if(!(!isRecord(parsed)||parsed.id!==id||parsed.success!==!0))return parsed.data??{}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}export{PROBE_REQUEST_ID,requestOnSocket,connectAndAsk,readAnswer,isRecord};
|
|
@@ -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{apiKeyEnvProviders,getApiKeyEnvVars}from"./chunk-
|
|
2
|
+
import{apiKeyEnvProviders,getApiKeyEnvVars}from"./chunk-MY4ZD3EW.js";import{normalizeProviderId}from"./chunk-ZXHLH4MW.js";var MAX_ENV_SLOT_INDEX=16;function primaryEnvVar(providerId){if(normalizeProviderId(providerId)==="anthropic-subscription")return"CLAUDE_CODE_OAUTH_TOKEN";let envVars=getApiKeyEnvVars(providerId);if(!(!envVars||envVars.length===0))return envVars.find(name=>name.endsWith("_API_KEY"))??envVars[0]}function envSlotVarNames(){let names=new Set;for(let provider of[...apiKeyEnvProviders(),"anthropic-subscription"]){let primary=primaryEnvVar(provider);if(primary){names.add(primary);for(let index=2;index<=MAX_ENV_SLOT_INDEX;index++)names.add(`${primary}_${index}`)}}return[...names]}function discoverEnvSlots(providerId,env){let primary=primaryEnvVar(providerId);if(!primary)return[];let slots=[],base=env(primary);base&&slots.push({name:"env",envVarName:primary,key:base,source:"env"});for(let index=2;index<=MAX_ENV_SLOT_INDEX;index++){let envVarName=`${primary}_${index}`,value=env(envVarName);value&&slots.push({name:`env-${index}`,envVarName,key:value,source:"env"})}return slots}export{envSlotVarNames,discoverEnvSlots};
|