@code-yeongyu/senpi 2026.10.25-2 → 2026.10.25-4
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 +37 -0
- package/dist/bundle/chunks/{args-JXULI4EH.js → args-B444OQBK.js} +1 -1
- package/dist/bundle/chunks/{auth-4NUNUSTF.js → auth-C77UQA55.js} +1 -1
- package/dist/bundle/chunks/{chunk-XBUSVKWC.js → chunk-2RB5EL4X.js} +1 -1
- package/dist/bundle/chunks/{chunk-KUE4AQN6.js → chunk-3QCYBOKN.js} +1 -1
- package/dist/bundle/chunks/{chunk-2EFVQWXZ.js → chunk-4MOZXOJX.js} +5 -5
- package/dist/bundle/chunks/{chunk-MXZPAUFB.js → chunk-5JJDR6XI.js} +1 -1
- package/dist/bundle/chunks/chunk-6VWIMHMH.js +2 -0
- package/dist/bundle/chunks/{chunk-Y5OTHMXO.js → chunk-7CNOCJCN.js} +1 -1
- package/dist/bundle/chunks/chunk-AX72VNRS.js +27 -0
- package/dist/bundle/chunks/{chunk-VNN2V74Y.js → chunk-BZ7726QO.js} +1 -1
- package/dist/bundle/chunks/{chunk-J2U5VDG7.js → chunk-C2MQ4QXN.js} +30 -30
- package/dist/bundle/chunks/{chunk-JRXKLIEQ.js → chunk-DODH3N6U.js} +5 -5
- package/dist/bundle/chunks/{chunk-EHQXLHRB.js → chunk-E6D4RIT7.js} +2 -2
- package/dist/bundle/chunks/chunk-J37GRED2.js +5 -0
- package/dist/bundle/chunks/chunk-JMOUU75H.js +2 -0
- package/dist/bundle/chunks/chunk-JPGT64RV.js +2 -0
- package/dist/bundle/chunks/chunk-KKD4CYCI.js +3 -0
- package/dist/bundle/chunks/{chunk-YN7ELQ43.js → chunk-KNVNKDER.js} +1 -1
- package/dist/bundle/chunks/chunk-KXB5WIS5.js +4 -0
- package/dist/bundle/chunks/chunk-L73UYAH5.js +3 -0
- package/dist/bundle/chunks/{chunk-G2UETS2R.js → chunk-LOIF6PHI.js} +4 -4
- package/dist/bundle/chunks/chunk-LTU6UFEX.js +2 -0
- package/dist/bundle/chunks/chunk-N7IN46Q5.js +27 -0
- package/dist/bundle/chunks/{chunk-LYGAV6KU.js → chunk-PT6JJUN2.js} +1 -1
- package/dist/bundle/chunks/{chunk-WFXUCVIR.js → chunk-SBGIXMX3.js} +2 -5
- package/dist/bundle/chunks/{chunk-W2BKZBYJ.js → chunk-STMXIBXF.js} +2 -2
- package/dist/bundle/chunks/chunk-TBU6VYHN.js +13 -0
- package/dist/bundle/chunks/{chunk-RXKNOEQQ.js → chunk-V2UYXTRR.js} +1 -1
- package/dist/bundle/chunks/{chunk-U67ML6CQ.js → chunk-WD6WBYC5.js} +1 -1
- package/dist/bundle/chunks/chunk-WJOT3DFL.js +2 -0
- package/dist/bundle/chunks/chunk-XMJKZK5H.js +2 -0
- package/dist/bundle/chunks/chunk-YI7SPFDN.js +5 -0
- package/dist/bundle/chunks/cli-main-YYH3IBC6.js +3 -0
- package/dist/bundle/chunks/{client-KWTLTKVV.js → client-WTYEICLH.js} +3 -3
- package/dist/bundle/chunks/dispatch-MXG5YWLV.js +9 -0
- package/dist/bundle/chunks/{help-fast-path-ZHZGXAUG.js → help-fast-path-3Z26DQSV.js} +1 -1
- package/dist/bundle/chunks/host-command-TDLLHXVI.js +2 -0
- package/dist/bundle/chunks/host-lifecycle-3VHHIGDL.js +3 -0
- package/dist/bundle/chunks/host-lifecycle.js +8 -6
- package/dist/bundle/chunks/host-session-command-56XF6ACS.js +20 -0
- package/dist/bundle/chunks/{host-socket-request-AS2OCRLP.js → host-socket-request-QL2WEZTN.js} +1 -1
- package/dist/bundle/chunks/interactive-mode-OEPULLZK.js +2 -0
- package/dist/bundle/chunks/mcp-presenter-bootstrap-XUSCQVRC.js +2 -0
- package/dist/bundle/chunks/{multi-session-host-VTTY5MFT.js → multi-session-host-Z2CW4SDM.js} +12 -9
- package/dist/bundle/chunks/{package-manager-cli-DZFOC3MF.js → package-manager-cli-N55U6PEO.js} +1 -1
- package/dist/bundle/chunks/rotation-stream-CBGCBYHV.js +2 -0
- package/dist/bundle/chunks/rpc-mode-ETXQWEB2.js +2 -0
- package/dist/bundle/chunks/{rpc-monitor-source-B5NQ4ZVH.js → rpc-monitor-source-AE3C6EQV.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-SLISTG4V.js → schedule-command-VS7CZC2J.js} +1 -1
- package/dist/bundle/chunks/session-control-endpoint-4LEIDIVI.js +3 -0
- package/dist/bundle/chunks/session-picker-E4KUJDLO.js +2 -0
- package/dist/bundle/chunks/session-worker.js +292 -278
- package/dist/bundle/chunks/{stdio-IEC635SY.js → stdio-YXDKKKQZ.js} +1 -1
- package/dist/bundle/chunks/{streamableHttp-KJI5KE4K.js → streamableHttp-DKIBUWVY.js} +1 -1
- package/dist/bundle/chunks/{types-LLNV23LW.js → types-BJUEQ4II.js} +1 -1
- package/dist/bundle/chunks/zod-compat-RJDXCU7S.js +2 -0
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/host-supervisor.js +8 -6
- 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/args.d.ts +2 -0
- package/dist/cli/args.js +9 -0
- package/dist/cli/host-command-args.d.ts +1 -0
- package/dist/cli/host-command-args.js +7 -1
- package/dist/cli/host-command.js +3 -1
- package/dist/core/agent-session.js +22 -7
- package/dist/core/extensions/builtin/goal/index.js +1 -0
- package/dist/core/extensions/builtin/goal/lifecycle-facts.d.ts +3 -0
- package/dist/core/extensions/builtin/mcp/catalog.d.ts +3 -1
- package/dist/core/extensions/builtin/mcp/catalog.js +2 -0
- package/dist/core/extensions/builtin/mcp/connection.d.ts +1 -0
- package/dist/core/extensions/builtin/mcp/connection.js +46 -1
- package/dist/core/extensions/builtin/mcp/elicitation.d.ts +6 -1
- package/dist/core/extensions/builtin/mcp/elicitation.js +54 -2
- package/dist/core/extensions/builtin/mcp/expose/call.js +6 -2
- package/dist/core/extensions/builtin/mcp/expose/session.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/expose/session.js +7 -0
- package/dist/core/extensions/builtin/mcp/health.js +5 -0
- package/dist/core/extensions/builtin/mcp/host-registry.js +7 -1
- package/dist/core/extensions/builtin/mcp/index.js +2 -0
- package/dist/core/extensions/builtin/mcp/modern/client.d.ts +5 -0
- package/dist/core/extensions/builtin/mcp/modern/client.js +15 -0
- package/dist/core/extensions/builtin/mcp/modern/consent-queue.d.ts +2 -0
- package/dist/core/extensions/builtin/mcp/modern/consent-queue.js +59 -0
- package/dist/core/extensions/builtin/mcp/modern/diagnostics.d.ts +4 -0
- package/dist/core/extensions/builtin/mcp/modern/diagnostics.js +39 -0
- package/dist/core/extensions/builtin/mcp/modern/dispatch.js +21 -11
- package/dist/core/extensions/builtin/mcp/modern/elicitation.d.ts +14 -0
- package/dist/core/extensions/builtin/mcp/modern/elicitation.js +145 -0
- package/dist/core/extensions/builtin/mcp/modern/errors.d.ts +21 -0
- package/dist/core/extensions/builtin/mcp/modern/errors.js +23 -0
- package/dist/core/extensions/builtin/mcp/modern/form-schema.d.ts +20 -0
- package/dist/core/extensions/builtin/mcp/modern/form-schema.js +153 -0
- package/dist/core/extensions/builtin/mcp/modern/http-fetch.d.ts +3 -1
- package/dist/core/extensions/builtin/mcp/modern/http-fetch.js +8 -2
- package/dist/core/extensions/builtin/mcp/modern/inputs.d.ts +11 -0
- package/dist/core/extensions/builtin/mcp/modern/inputs.js +65 -0
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.d.ts +11 -0
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.js +109 -0
- package/dist/core/extensions/builtin/mcp/modern/request.d.ts +20 -0
- package/dist/core/extensions/builtin/mcp/modern/request.js +292 -0
- package/dist/core/extensions/builtin/mcp/modern/stdio-probe.d.ts +1 -1
- package/dist/core/extensions/builtin/mcp/modern/stdio-probe.js +54 -6
- package/dist/core/extensions/builtin/mcp/modern/transport.js +80 -14
- package/dist/core/extensions/builtin/mcp/modern/wire.js +11 -7
- package/dist/core/extensions/builtin/mcp/prompts.d.ts +5 -1
- package/dist/core/extensions/builtin/mcp/prompts.js +6 -1
- package/dist/core/extensions/builtin/mcp/request-origin.d.ts +47 -0
- package/dist/core/extensions/builtin/mcp/request-origin.js +59 -0
- package/dist/core/extensions/builtin/mcp/resources.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/resources.js +19 -4
- package/dist/core/extensions/builtin/mcp/sdk.lazy.d.ts +3 -1
- package/dist/core/extensions/builtin/mcp/sdk.lazy.js +3 -1
- package/dist/core/extensions/builtin/mcp/service-register.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/service-register.js +3 -0
- package/dist/core/extensions/builtin/mcp/service-types.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/service.d.ts +1 -0
- package/dist/core/extensions/builtin/mcp/service.js +79 -4
- package/dist/core/extensions/builtin/mcp/shared-connection.js +36 -2
- package/dist/core/extensions/builtin/mcp/shared-lease.d.ts +1 -0
- package/dist/core/extensions/builtin/mcp/shared-lease.js +9 -0
- package/dist/core/extensions/builtin/mcp/transport-sdk.d.ts +3 -2
- package/dist/core/extensions/builtin/mcp/transport-sdk.js +56 -25
- package/dist/core/extensions/builtin/mcp/wrap.d.ts +7 -0
- package/dist/core/extensions/builtin/mcp/wrap.js +6 -0
- package/dist/core/extensions/runner.js +3 -2
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/core/lifecycle-ledger.d.ts +1 -0
- package/dist/core/lifecycle-ledger.js +7 -2
- package/dist/core/lifecycle-record.js +3 -0
- package/dist/core/lifecycle-session-binding.d.ts +11 -1
- package/dist/core/lifecycle-session-binding.js +29 -2
- package/dist/core/lifecycle-stop.d.ts +41 -0
- package/dist/core/lifecycle-stop.js +92 -0
- package/dist/core/mcp-form-types.d.ts +89 -0
- package/dist/core/mcp-form-types.js +23 -0
- package/dist/core/mcp-mrtr-presentations.d.ts +15 -0
- package/dist/core/mcp-mrtr-presentations.js +17 -0
- package/dist/core/session-control-actions.js +0 -2
- package/dist/core/session-lifecycle-types.d.ts +15 -0
- package/dist/core/session-lifecycle.d.ts +17 -1
- package/dist/core/session-lifecycle.js +40 -2
- package/dist/main.js +5 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +1 -0
- package/dist/modes/interactive/components/extension-selector.js +4 -0
- package/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/dist/modes/interactive/interactive-mode.js +34 -8
- package/dist/modes/interactive/mcp-local-presenter.d.ts +5 -0
- package/dist/modes/interactive/mcp-local-presenter.js +109 -0
- package/dist/modes/interactive/session-control-attach.d.ts +20 -0
- package/dist/modes/interactive/session-control-attach.js +13 -0
- package/dist/modes/interactive/session-control-commands.js +16 -6
- package/dist/modes/interactive/session-control-registry.d.ts +2 -1
- package/dist/modes/interactive/session-control-registry.js +3 -2
- package/dist/modes/interactive/session-control-rpc-commands.d.ts +4 -2
- package/dist/modes/interactive/session-control-rpc-commands.js +114 -4
- package/dist/modes/interactive/session-control-server.js +9 -3
- package/dist/modes/rpc/connection-handler.d.ts +1 -0
- package/dist/modes/rpc/connection-handler.js +13 -41
- package/dist/modes/rpc/custom-capability.d.ts +6 -0
- package/dist/modes/rpc/custom-capability.js +6 -0
- package/dist/modes/rpc/get-entries-command.d.ts +13 -0
- package/dist/modes/rpc/get-entries-command.js +61 -0
- package/dist/modes/rpc/get-entries-page.d.ts +22 -0
- package/dist/modes/rpc/get-entries-page.js +41 -2
- package/dist/modes/rpc/host-capabilities.d.ts +1 -0
- package/dist/modes/rpc/host-capabilities.js +6 -2
- package/dist/modes/rpc/host-ensure-start.js +13 -2
- 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-wire.d.ts +2 -0
- package/dist/modes/rpc/host-handover-wire.js +1 -0
- package/dist/modes/rpc/host-lifecycle-launch.d.ts +1 -0
- package/dist/modes/rpc/host-lifecycle-launch.js +43 -2
- package/dist/modes/rpc/host-observe-request.d.ts +2 -1
- package/dist/modes/rpc/host-observe-request.js +4 -1
- package/dist/modes/rpc/host-runner.d.ts +2 -0
- package/dist/modes/rpc/host-runner.js +8 -6
- package/dist/modes/rpc/host-successor.js +11 -1
- package/dist/modes/rpc/mcp-form-dialog.d.ts +45 -0
- package/dist/modes/rpc/mcp-form-dialog.js +159 -0
- package/dist/modes/rpc/mcp-form-worker.d.ts +14 -0
- package/dist/modes/rpc/mcp-form-worker.js +167 -0
- package/dist/modes/rpc/mcp-presenter-authority.d.ts +53 -0
- package/dist/modes/rpc/mcp-presenter-authority.js +309 -0
- package/dist/modes/rpc/mcp-presenter-bootstrap.d.ts +8 -0
- package/dist/modes/rpc/mcp-presenter-bootstrap.js +111 -0
- package/dist/modes/rpc/mcp-presenter-control.d.ts +24 -0
- package/dist/modes/rpc/mcp-presenter-control.js +330 -0
- package/dist/modes/rpc/multi-session-host.d.ts +3 -0
- package/dist/modes/rpc/multi-session-host.js +36 -1
- package/dist/modes/rpc/rpc-read-response-types.d.ts +2 -0
- package/dist/modes/rpc/rpc-session-command-types.d.ts +8 -1
- package/dist/modes/rpc/session-binding.js +6 -1
- package/dist/modes/rpc/session-event-writer.d.ts +14 -0
- package/dist/modes/rpc/session-event-writer.js +128 -1
- package/dist/modes/rpc/session-router-routing.js +1 -0
- package/dist/modes/rpc/session-worker-client.d.ts +3 -0
- package/dist/modes/rpc/session-worker-client.js +89 -0
- package/dist/modes/rpc/session-worker-protocol.d.ts +41 -0
- package/dist/modes/rpc/session-worker.js +9 -0
- package/docs/extensions.md +5 -0
- package/docs/mcp.md +20 -3
- package/docs/rpc.md +151 -8
- package/package.json +6 -6
- package/dist/bundle/chunks/chunk-3LNSLJ7N.js +0 -2
- package/dist/bundle/chunks/chunk-B6TPQDBW.js +0 -5
- package/dist/bundle/chunks/chunk-CDRFFHLL.js +0 -4
- package/dist/bundle/chunks/chunk-HPCS4HM4.js +0 -27
- package/dist/bundle/chunks/chunk-KJZAY5YH.js +0 -27
- package/dist/bundle/chunks/chunk-MSQCTH6V.js +0 -2
- package/dist/bundle/chunks/chunk-OI4NMCKP.js +0 -3
- package/dist/bundle/chunks/chunk-SCVRKIFK.js +0 -2
- package/dist/bundle/chunks/cli-main-SWKFMTZQ.js +0 -3
- package/dist/bundle/chunks/dispatch-DEP4PEDZ.js +0 -10
- package/dist/bundle/chunks/host-command-BC6UWP33.js +0 -2
- package/dist/bundle/chunks/host-lifecycle-TN5NEGNF.js +0 -3
- package/dist/bundle/chunks/host-session-command-MGVBLBRV.js +0 -20
- package/dist/bundle/chunks/interactive-mode-SCSROHD5.js +0 -2
- package/dist/bundle/chunks/rotation-stream-U7YQMC7H.js +0 -2
- package/dist/bundle/chunks/rpc-mode-TOXYD4XA.js +0 -2
- package/dist/bundle/chunks/session-control-endpoint-HFFMBALG.js +0 -3
- package/dist/bundle/chunks/session-picker-465FVXQG.js +0 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
+
import{fetchWithinOrigin}from"./chunk-YP72RYUP.js";import{InitializeResultSchema,JSONRPCMessageSchema,LATEST_PROTOCOL_VERSION}from"./chunk-WJOT3DFL.js";import"./chunk-AX72VNRS.js";import{AuthError,ConnectError,configureMcpElicitation,getModernDispatchGuard,installModernRequestAdapter,isMcpNeedsAuthError,legacyMcpFormEligible,loadMcpSdkAuth,loadMcpSdkClient,loadMcpSdkStdioTransport,loadMcpSdkStreamableHttpTransport,mcpClientCapabilities,mcpElapsedClock,modernDispatchGuard,reapProcessTree,safeOn}from"./chunk-TBU6VYHN.js";import{McpMrtrError}from"./chunk-JPGT64RV.js";import{external_exports}from"./chunk-KUPQO7MC.js";import"./chunk-DLAY7CIU.js";import"./chunk-7YO7VQZW.js";import"./chunk-ATQFN5HI.js";import"./chunk-IKOFCODM.js";import{Buffer as Buffer2}from"node:buffer";var isRecord=value=>typeof value=="object"&&value!==null&&!Array.isArray(value);function encodeMcpHeaderValue(value){return/^[\x09\x20-\x7e]*$/.test(value)&&value.trim()===value&&!(value.startsWith("=?base64?")&&value.endsWith("?="))?value:`=?base64?${Buffer2.from(value,"utf8").toString("base64")}?=`}function clearMcpParameterHeaders(headers){for(let name of[...headers.keys()])name.toLowerCase().startsWith("mcp-param-")&&headers.delete(name)}function parseParameterHeaders(schema){let headers=[],names=new Set,visit=(node,path)=>{if(!isRecord(node))return!0;if(Object.hasOwn(node,"x-mcp-header")){let name=node["x-mcp-header"],type=node.type;if(!path?.length||typeof name!="string"||!/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(name)||names.has(name.toLowerCase())||type!=="string"&&type!=="integer"&&type!=="boolean")return!1;names.add(name.toLowerCase()),headers.push({name,path,type})}for(let[keyword,value]of Object.entries(node))if(["properties","patternProperties","$defs","definitions","dependentSchemas","dependencies"].includes(keyword)){if(!isRecord(value))continue;for(let[key,child]of Object.entries(value)){let childPath=keyword==="properties"&&path!==void 0?[...path,key]:void 0;if(!visit(child,childPath))return!1}}else if(["items","prefixItems","allOf","anyOf","oneOf","additionalItems","additionalProperties","unevaluatedItems","unevaluatedProperties","contains","propertyNames","not","if","then","else","contentSchema"].includes(keyword)){for(let child of Array.isArray(value)?value:[value])if(!visit(child,void 0))return!1}return!0};return visit(schema,[])?headers:void 0}var ModernParameterHeaders=class{#tools=new Map;filterTools(tools,firstPage){return firstPage&&this.#tools.clear(),tools.filter(tool=>{if(!isRecord(tool)||typeof tool.name!="string")return!0;let headers=parseParameterHeaders(tool.inputSchema);return headers===void 0?(this.#tools.delete(tool.name),!1):(this.#tools.set(tool.name,headers),!0)})}append(headers,name,args){if(typeof name=="string")for(let parameter of this.#tools.get(name)??[]){let value=args;for(let key of parameter.path)value=isRecord(value)&&Object.hasOwn(value,key)?value[key]:void 0;(parameter.type==="string"&&typeof value=="string"||parameter.type==="boolean"&&typeof value=="boolean"||parameter.type==="integer"&&typeof value=="number"&&Number.isSafeInteger(value))&&headers.set(`Mcp-Param-${parameter.name}`,encodeMcpHeaderValue(String(value)))}}};var modernCredentialSnapshot=tokens=>tokens===void 0?void 0:JSON.stringify([tokens.access_token,tokens.refresh_token]);function modernHttpFetch(spec,signal,authorizeResend=!0){let fetch=fetchWithinOrigin();return async(url,init)=>{let requestSignal=init?.signal?AbortSignal.any([signal,init.signal]):signal,send=()=>{let headers=new Headers,tokens=spec.authProvider?.tokens(),guard=init?.[modernDispatchGuard];guard?.(modernCredentialSnapshot(tokens)),tokens&&headers.set("Authorization",`Bearer ${tokens.access_token}`),new Headers(spec.requestInit?.headers).forEach((value,key)=>{headers.set(key,value)});for(let key of["Mcp-Session-Id","Mcp-Name","Mcp-Method","MCP-Protocol-Version"])headers.delete(key);return clearMcpParameterHeaders(headers),new Headers(init?.headers).forEach((value,key)=>{headers.set(key,value)}),headers.delete("Mcp-Session-Id"),fetch(url,{...spec.requestInit,...init,headers,signal:requestSignal})},response=await send();if(authorizeResend&&spec.authProvider&&(response.status===401||response.status===403)){let{auth,extractWWWAuthenticateParams,UnauthorizedError}=await loadMcpSdkAuth(),{resourceMetadataUrl,scope,error}=extractWWWAuthenticateParams(response);if(response.status===401||error==="insufficient_scope"){if(await response.body?.cancel(),await auth(spec.authProvider,{serverUrl:spec.url,resourceMetadataUrl,scope,fetchFn:(target,request2)=>fetch(target,{...request2,signal:request2?.signal?AbortSignal.any([requestSignal,request2.signal]):requestSignal})})!=="AUTHORIZED")throw new UnauthorizedError;if(response=await send(),response.status===401)throw await response.body?.cancel(),new UnauthorizedError("Server returned 401 after successful authentication")}}return response}}async function createMcpRequestClient(protocol,uiProvider,readCredential=()=>{},elicitationEnabled=!0){let{Client}=await loadMcpSdkClient();protocol.privateForms=uiProvider?.enforced?.()===!0;let legacyEligible=legacyMcpFormEligible(uiProvider,elicitationEnabled);protocol.legacyFormEligible=legacyEligible;let client=new Client({name:"senpi-mcp-client",version:"0.0.0"},{capabilities:mcpClientCapabilities(legacyEligible)});return await configureMcpElicitation(client,uiProvider,void 0,legacyEligible),installModernRequestAdapter(client,protocol,mcpElapsedClock,readCredential),client}import{PassThrough}from"node:stream";var ProjectStdioTransport=class{#resolve;#create;#current;#epoch;constructor(resolve,create){this.stderr=new PassThrough,this.#epoch=0,this.#resolve=resolve,this.#create=create}get pid(){return this.#current?.pid??null}async start(){let epoch=this.#epoch,spec=await this.#resolve();if(epoch!==this.#epoch)throw new ConnectError("Project MCP spawn was invalidated; retry",{phase:"create",retriable:!0});let transport=this.#create(spec);if(this.#current=transport,transport.onmessage=message=>this.onmessage?.(message),transport.onclose=()=>this.onclose?.(),transport.onerror=error=>this.onerror?.(error),transport.stderr?.pipe(this.stderr,{end:!1}),await transport.start(),epoch!==this.#epoch)throw await transport.close(),new ConnectError("Project MCP spawn was invalidated; retry",{phase:"create",retriable:!0})}async send(message,_options){if(this.#current===void 0)throw new ConnectError("Project MCP transport has not started",{phase:"send",retriable:!0});await this.#current.send(message)}async close(){this.#epoch++,await this.#current?.close()}};async function materializeMcpTransport(options,protocol={}){let client=await createMcpRequestClient(protocol,options.elicitationUiProvider,()=>modernCredentialSnapshot(options.spec.authProvider?.tokens()),options.elicitationEnabled);return options.spec.kind==="stdio"?materializeStdio(options.spec,options,client,protocol):materializeHttp(options.spec,client)}async function materializeStdio(spec,options,client,protocol){let{getDefaultEnvironment,StdioClientTransport}=await loadMcpSdkStdioTransport(),create=current=>new StdioClientTransport({args:current.args,command:current.command,cwd:current.cwd,env:{...current.projectPolicy?{}:getDefaultEnvironment(),...current.env,...oauthAccessTokenEnv(current.authProvider)},stderr:"pipe"}),transport=spec.projectPolicy&&spec.resolveBeforeStart!==void 0?new ProjectStdioTransport(spec.resolveBeforeStart,create):create(spec);return trackStdioStart(transport,options.onStart),pipeStderr(transport,options.logger,options.sink,protocol),dropNullNextCursor(transport),{client,close:()=>closeClientAndTransport(transport,client),readPid:()=>transport.pid,transport}}async function materializeHttp(spec,client){let{StreamableHTTPClientTransport}=await loadMcpSdkStreamableHttpTransport(),transport=new StreamableHTTPClientTransport(spec.url,{authProvider:spec.authProvider,requestInit:spec.requestInit});return dropNullNextCursor(transport),{client,close:()=>closeClientAndTransport(transport,client),readPid:()=>null,transport}}function oauthAccessTokenEnv(authProvider){let accessToken=authProvider?.tokens()?.access_token;return accessToken===void 0||accessToken.length===0?{}:{OAUTH_ACCESS_TOKEN:accessToken}}function dropNullNextCursor(transport){let originalStart=transport.start.bind(transport);transport.start=async()=>{let deliver=transport.onmessage;deliver!==void 0&&(transport.onmessage=(message,extra)=>{if("result"in message&&message.result!==null&&typeof message.result=="object"){let result=message.result;result.nextCursor===null&&delete result.nextCursor}deliver(message,extra)}),await originalStart()}}function trackStdioStart(transport,onStart){let start=transport.start.bind(transport);transport.start=async()=>{await start(),onStart()}}function pipeStderr(transport,logger,sink,protocol){let pending="",undecided="",stderrEnded=!1,stderr=transport.stderr;if(stderr==null)return;let logLine=line=>{let code=protocol.privateForms?line.match(/\b(?:EACCES|ENOENT|EPIPE|ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOSPC|ENOMEM|EMFILE)\b/)?.[0]:void 0;logger.stderr(protocol.privateForms?`[private MCP stderr redacted]${code?` ${code}`:""}`:line)},append=text=>{pending+=text;let lines=pending.split(/\r?\n/);pending=lines.pop()??"";for(let line of lines)line.length>0&&logLine(line)};protocol.resolveStdioDiagnostics=modern=>{(!modern||protocol.privateForms)&&(append(undecided),stderrEnded&&pending.length>0&&(logLine(pending),pending="")),undecided="",modern&&!protocol.privateForms&&(pending="")},safeOn(stderr,"data","transport.stderr.data",chunk=>{if(protocol.version!==void 0&&!protocol.privateForms){pending="",undecided="";return}if(!Buffer.isBuffer(chunk)&&typeof chunk!="string")return;let text=Buffer.isBuffer(chunk)?chunk.toString("utf8"):chunk;if(!protocol.legacy&&!protocol.privateForms){undecided+=text.slice(0,Math.max(0,512*1024-undecided.length));return}append(text)},sink),safeOn(stderr,"end","transport.stderr.end",()=>{stderrEnded=!0,(protocol.privateForms||protocol.legacy&&protocol.version===void 0)&&pending.length>0&&logLine(pending),pending="",(protocol.legacy||protocol.version!==void 0)&&(undecided="")},sink)}async function closeClientAndTransport(transport,client){isTerminableHttpTransport(transport)&&await transport.terminateSession().catch(()=>{}),await transport.close().catch(()=>{}),await client.close().catch(()=>{})}function isTerminableHttpTransport(transport){return"terminateSession"in transport&&typeof transport.terminateSession=="function"}var MODERN_PROTOCOL_VERSION="2026-07-28",MODERN_ERROR_CODES={HeaderMismatch:-32020,MissingRequiredClientCapabilityError:-32021,UnsupportedProtocolVersionError:-32022};function buildModernRequest(id,method,clientInfo2,clientCapabilities,params={}){return{jsonrpc:"2.0",id,method,params:{...params,_meta:{...params._meta,"io.modelcontextprotocol/protocolVersion":MODERN_PROTOCOL_VERSION,"io.modelcontextprotocol/clientInfo":clientInfo2,"io.modelcontextprotocol/clientCapabilities":clientCapabilities}}}}function modernizeRequest(id,method,clientInfo2,clientCapabilities,version,params){let built=buildModernRequest(id,method,clientInfo2,clientCapabilities,params),capabilities=params?._meta?.["io.modelcontextprotocol/clientCapabilities"];return{...built,params:{...built.params,_meta:{...built.params._meta,"io.modelcontextprotocol/clientCapabilities":isRecord2(capabilities)?capabilities:clientCapabilities,"io.modelcontextprotocol/protocolVersion":version}}}}function deriveModernHeaders(request2){let headers={"MCP-Protocol-Version":request2.params._meta["io.modelcontextprotocol/protocolVersion"],"Mcp-Method":request2.method},name=request2.method==="resources/read"?request2.params.uri:request2.method==="tools/call"||request2.method==="prompts/get"?request2.params.name:void 0;return typeof name=="string"&&(headers["Mcp-Name"]=encodeMcpHeaderValue(name)),headers}function classifyModernError(body2){let response=parseBody(body2);if(!isRecord2(response)||response.jsonrpc!=="2.0"||!isRecord2(response.error))return;let error=response.error;if(typeof error.message!="string")return;let common={message:error.message,..."data"in error?{data:error.data}:{}};switch(error.code){case MODERN_ERROR_CODES.HeaderMismatch:return{...common,kind:"HeaderMismatch",code:error.code};case MODERN_ERROR_CODES.MissingRequiredClientCapabilityError:return{...common,kind:"MissingRequiredClientCapabilityError",code:error.code};case MODERN_ERROR_CODES.UnsupportedProtocolVersionError:{let supported=isRecord2(error.data)?error.data.supported:void 0;return{...common,kind:"UnsupportedProtocolVersionError",code:error.code,...Array.isArray(supported)&&supported.every(version=>typeof version=="string")?{supportedVersions:supported}:{}}}default:return}}function parseBody(body2){if(typeof body2!="string")return body2;try{return JSON.parse(body2)}catch(error){if(error instanceof SyntaxError)return;throw error}}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var discoverySchema=external_exports.object({resultType:external_exports.literal("complete"),supportedVersions:external_exports.array(external_exports.string()),capabilities:external_exports.record(external_exports.string(),external_exports.unknown()),_meta:external_exports.object({"io.modelcontextprotocol/serverInfo":external_exports.object({name:external_exports.string(),version:external_exports.string()}).passthrough()}).passthrough(),instructions:external_exports.string().optional(),ttlMs:external_exports.number().nonnegative().optional(),cacheScope:external_exports.string().optional()}).passthrough(),modernError=classifyModernError,STDIO_PROBE_ID="senpi-era-probe",StdioProbeSilence=class extends Error{constructor(){super("MCP stdio server did not answer discovery in time"),this.name="StdioProbeSilence"}};function discoveryReply(value,id){return complete(value,id)}function request(options,version,id=1){let built=buildModernRequest(id,"server/discover",options.clientInfo,options.clientCapabilities);return{...built,params:{_meta:{...built.params._meta,"io.modelcontextprotocol/protocolVersion":version}}}}function complete(value,id=1){let parsed=external_exports.object({jsonrpc:external_exports.literal("2.0"),id:external_exports.literal(id),result:discoverySchema}).safeParse(value);return parsed.success?parsed.data.result:void 0}function errorReply(value,id){return external_exports.object({jsonrpc:external_exports.literal("2.0"),id:id===void 0?external_exports.union([external_exports.string(),external_exports.number(),external_exports.null()]):external_exports.literal(id),error:external_exports.object({code:external_exports.number(),message:external_exports.string()})}).safeParse(value).success}function mutualVersion(error,options){if(!(error.kind!=="UnsupportedProtocolVersionError"||!error.supportedVersions))return error.supportedVersions.filter(candidate=>options.supportedVersions.includes(candidate)).sort().at(-1)}function indeterminate(reason,action,details={}){return{kind:"indeterminate",reason,action,...details}}function parseJson(text){try{return JSON.parse(text)}catch(error){if(error instanceof SyntaxError)return;throw error}}async function body(response){let text=await response.text();if(!response.headers.get("Content-Type")?.includes("text/event-stream"))return parseJson(text);for(let event of text.replace(/\r\n/g,`
|
|
3
|
+
`).split(`
|
|
4
|
+
|
|
5
|
+
`)){let data=event.split(`
|
|
6
|
+
`).filter(line=>line.startsWith("data:")).map(line=>line.slice(5).replace(/^ /,"")).join(`
|
|
7
|
+
`),value=parseJson(data);if(complete(value)||modernError(value))return value}}async function probeHttpEra(url,fetch,options){let version=MODERN_PROTOCOL_VERSION;for(let attempt=0;attempt<2;attempt++){let response,value;try{let discoveryRequest=request(options,version);response=await fetch(url,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json, text/event-stream",...deriveModernHeaders(discoveryRequest)},body:JSON.stringify(discoveryRequest)}),value=await body(response)}catch(cause){if(isMcpNeedsAuthError(cause))throw cause;return indeterminate("transport","Check the MCP endpoint connection and retry discovery.",{cause})}let error=modernError(value);if(response.status===400){if(!error)return attempt===0?{kind:"legacy-fallback"}:indeterminate("version-retry-rejected","Check server version negotiation; the modern retry failed.",{era:"modern"});if(error.code!==-32022)return{kind:attempt?"modern-version-retry":"modern-OK",version,error};if(attempt===1)return indeterminate("version-retry-rejected","Update client or server; the single version retry was rejected.",{era:"modern"});let mutual=mutualVersion(error,options);if(!mutual)return indeterminate("no-mutual-version","Update client or server to share a supported protocol version.",{era:"modern"});version=mutual;continue}if(!error&&errorReply(value))return attempt===0?{kind:"legacy-fallback"}:indeterminate("version-retry-rejected","Check server version negotiation; the modern retry failed.",{era:"modern"});if(!response.ok)return indeterminate("http-status","Check endpoint, authentication, or server health before retrying.",{status:response.status});let discovery=complete(value);return discovery?{kind:attempt?"modern-version-retry":"modern-OK",version,discovery}:error?{kind:attempt?"modern-version-retry":"modern-OK",version,error}:indeterminate("invalid-discovery","Check that the server returns a complete server/discover envelope.")}return indeterminate("version-retry-rejected","Update client or server protocol versions.",{era:"modern"})}async function probeStdioEra(send,options){let version=MODERN_PROTOCOL_VERSION,retryRejected=()=>indeterminate("version-retry-rejected","Update client or server; the single version retry was rejected.",{era:"modern"});for(let attempt=0;attempt<2;attempt++){let id=attempt===0?STDIO_PROBE_ID:`${STDIO_PROBE_ID}-${attempt}`,value;try{value=await send(request(options,version,id))}catch(error2){return attempt>0?retryRejected():error2 instanceof StdioProbeSilence?{kind:"legacy-fallback",silent:!0}:{kind:"legacy-fallback",restart:!0}}let kind=attempt===0?"modern-OK":"modern-version-retry",discovery=complete(value,id);if(discovery)return{kind,version,discovery};if(!errorReply(value,id))return attempt>0?retryRejected():{kind:"legacy-fallback",restart:!0};let error=modernError(value);if(!error)return attempt>0?retryRejected():{kind:"legacy-fallback"};let mutual=attempt===0?mutualVersion(error,options):void 0;if(!mutual)return{kind,version,error};version=mutual}return retryRejected()}function sanitizeModernMessage(message){if("error"in message)return{jsonrpc:"2.0",id:message.id,error:{code:message.error.code,message:"MCP server request failed."}};if(!("method"in message))return message;if("id"in message)throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");if(message.method==="notifications/progress"){let params=message.params;return!params||typeof params.progress!="number"||!Number.isFinite(params.progress)||params.total!==void 0&&(typeof params.total!="number"||!Number.isFinite(params.total))?void 0:{jsonrpc:"2.0",method:message.method,params:{progressToken:params.progressToken,progress:params.progress,...params.total===void 0?{}:{total:params.total}}}}return message.method==="notifications/message"?{jsonrpc:"2.0",method:message.method,params:{level:"info",data:"MCP server diagnostic suppressed."}}:message}var ModernTransportError=class extends Error{constructor(message){super(message),this.name="ModernTransportError"}},ModernHttpTransport=class{#options;#abort=new AbortController;#attempts=new Map;#toolLists=new Map;#parameterHeaders=new ModernParameterHeaders;#started=!1;#closed=!1;constructor(options){this.#options=options}async start(){if(this.#started||this.#closed)throw new ModernTransportError("Modern MCP transport cannot be started twice");this.#started=!0}async close(){this.#closed||(this.#closed=!0,this.#abort.abort(),this.onclose?.())}async send(message){if(!this.#started||this.#closed)throw new ModernTransportError("Modern MCP transport is not open");if("method"in message&&message.method==="notifications/cancelled"){let id2=message.params?.requestId;(typeof id2=="string"||typeof id2=="number")&&this.#attempts.get(id2)?.abort();return}let id="method"in message&&"id"in message?message.id:void 0;id!==void 0&&"method"in message&&message.method==="tools/list"&&this.#toolLists.set(id,message.params?.cursor===void 0);let controller=new AbortController;id!==void 0&&this.#attempts.set(id,controller);let signal=AbortSignal.any([this.#abort.signal,controller.signal]);try{let version=this.#options.protocolVersion??MODERN_PROTOCOL_VERSION,headers=new Headers(this.#options.headers);clearMcpParameterHeaders(headers);for(let name of["Mcp-Session-Id","Mcp-Name","Mcp-Method","MCP-Protocol-Version"])headers.delete(name);headers.set("Content-Type","application/json"),headers.set("Accept","application/json, text/event-stream");let body2=message;if("method"in message){let request2=modernizeRequest("id"in message?message.id:0,message.method,this.#options.clientInfo,this.#options.clientCapabilities,version,message.params);for(let[name,value]of Object.entries(deriveModernHeaders(request2)))headers.set(name,value);if(request2.method==="tools/call"&&this.#parameterHeaders.append(headers,request2.params.name,request2.params.arguments),"id"in message)body2=request2;else{let{id:_id,...notification}=request2;body2=notification}}else headers.set("MCP-Protocol-Version",version);let guard="method"in message?getModernDispatchGuard(message.params):void 0;guard?.();let init={method:"POST",headers,body:JSON.stringify(body2),signal,[modernDispatchGuard]:guard},response=await this.#options.fetch(this.#options.url,init);if(signal.throwIfAborted(),response.status===401||response.status===403)throw await response.body?.cancel(),new AuthError("MCP server needs authentication; use /mcp auth-start.",{phase:"auth",retriable:!1});if(response.status===202||response.status===204)return;let mediaType=response.headers.get("Content-Type")?.split(";")[0].trim().toLowerCase();if(mediaType==="application/json"){let incoming=JSONRPCMessageSchema.parse(await response.json());if(!response.ok&&!("error"in incoming))throw new ModernTransportError(`Modern MCP POST failed with HTTP ${response.status}`);signal.throwIfAborted(),this.#deliver(incoming,id)}else if(response.ok&&mediaType==="text/event-stream"&&response.body)await this.#consumeSse(response.body,id,signal);else throw new ModernTransportError(`Modern MCP POST failed with HTTP ${response.status} (${mediaType??"no content type"})`)}catch(error){let failure=error instanceof McpMrtrError||error instanceof AuthError?error:new McpMrtrError("MCP_MRTR_TRANSPORT_FAILED");throw this.onerror?.(failure),failure}finally{id!==void 0&&this.#attempts.delete(id),id!==void 0&&this.#toolLists.delete(id)}}#deliver(incoming,expected){if("id"in incoming&&(expected===void 0||incoming.id!==expected))throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");if("id"in incoming&&"result"in incoming&&this.#toolLists.has(incoming.id)){let result=incoming.result;Array.isArray(result.tools)&&(incoming={...incoming,result:{...result,tools:this.#parameterHeaders.filterTools(result.tools,this.#toolLists.get(incoming.id)===!0)}})}let safe=sanitizeModernMessage(incoming);safe&&this.onmessage?.(safe)}async#consumeSse(stream,requestId,signal){let reader=stream.getReader(),decoder=new TextDecoder,aborted=Promise.withResolvers(),onabort=()=>aborted.reject(signal.reason);signal.addEventListener("abort",onabort,{once:!0}),signal.aborted&&onabort();let buffer="",data=[],event="";try{for(;;){let{value,done}=await Promise.race([reader.read(),aborted.promise]);for(signal.throwIfAborted(),buffer+=done?decoder.decode():decoder.decode(value,{stream:!0});;){let match=/[\r\n]/.exec(buffer);if(match===null)break;let end=match.index;if(!done&&buffer[end]==="\r"&&end+1===buffer.length)break;let line=buffer.slice(0,end);if(buffer=buffer.slice(end+(buffer.slice(end,end+2)===`\r
|
|
8
|
+
`?2:1)),line===""){if(data.length>0&&(event===""||event==="message")){let incoming=JSONRPCMessageSchema.parse(JSON.parse(data.join(`
|
|
9
|
+
`)));if(this.#deliver(incoming,requestId),"id"in incoming&&!("method"in incoming)&&incoming.id===requestId)return}data=[],event=""}else if(!line.startsWith(":")){let colon=line.indexOf(":"),field=colon===-1?line:line.slice(0,colon),text=colon===-1?"":line.slice(colon+1).replace(/^ /,"");field==="data"&&data.push(text),field==="event"&&(event=text)}}if(done){if(requestId!==void 0)throw new ModernTransportError("Modern MCP SSE ended before the request response");return}}}finally{signal.removeEventListener("abort",onabort),await reader.cancel(),reader.releaseLock()}}};function modernInitializeResult(discovery,wireVersion){if(!discovery.supportedVersions.includes(wireVersion))throw new ModernTransportError(`Discovery does not support negotiated MCP version ${wireVersion}`);return InitializeResultSchema.parse({protocolVersion:LATEST_PROTOCOL_VERSION,capabilities:discovery.capabilities,serverInfo:discovery._meta["io.modelcontextprotocol/serverInfo"],...discovery.instructions===void 0?{}:{instructions:discovery.instructions}})}function normalizeModernResult(message){return"result"in message&&message.result.nextCursor===null&&delete message.result.nextCursor,message}var ModernSdkBridge=class{#transport;#initializeResult;#initialized=!1;constructor(transport,discovery,wireVersion){this.#initializeResult=modernInitializeResult(discovery,wireVersion),this.#transport=transport}async start(){this.#transport.onmessage=(message,extra)=>{this.onmessage?.(normalizeModernResult(message),extra)},this.#transport.onclose=()=>this.onclose?.(),this.#transport.onerror=error=>this.onerror?.(error),await this.#transport.start()}async send(message,options){if("method"in message&&message.method==="initialize"){if(!("id"in message)||this.#initialized)throw new ModernTransportError("Modern MCP bridge has already initialized");this.#initialized=!0,this.onmessage?.({jsonrpc:"2.0",id:message.id,result:this.#initializeResult});return}"method"in message&&message.method==="notifications/initialized"&&!("id"in message)||await this.#transport.send(message,options)}close(){return this.#transport.close()}};var STDIO_PROBE_MS=2e3;function probeStdioTransport(transport,options,logger,timeoutMs,serverName,onModern,probeMs=STDIO_PROBE_MS,onLegacy){let start=transport.start.bind(transport),close=transport.close.bind(transport),send=transport.send.bind(transport),abort=new AbortController;transport.close=async()=>{abort.abort(),await close()},transport.start=async()=>{await start();let outcome=await probeStdioEra(exchange,options);if(abort.signal.throwIfAborted(),outcome.kind==="legacy-fallback"){outcome.restart?await restart():outcome.silent&&awaitLateDiscovery(),outcome.silent||onLegacy?.();return}if(outcome.kind==="indeterminate"||!outcome.discovery){let reason=outcome.kind==="indeterminate"?outcome.reason:outcome.error?.message,message=`MCP server ${serverName} modern discovery failed: ${reason}`;throw logger.error(message),new ConnectError(message,{phase:"modern-stdio",serverName})}speakModern(outcome.discovery,outcome.version),onModern?.(outcome.version)};async function exchange(request2){let reply=Promise.withResolvers(),signal=AbortSignal.any([abort.signal,AbortSignal.timeout(Math.min(probeMs,Math.floor(timeoutMs/4)))]),onabort=()=>reply.reject(abort.signal.aborted?abort.signal.reason:new StdioProbeSilence),{onmessage,onclose,onerror}=transport;signal.addEventListener("abort",onabort,{once:!0}),transport.onmessage=(message,extra)=>{"id"in message&&!("method"in message)&&message.id===request2.id?reply.resolve(message):onmessage?.(message,extra)},transport.onclose=()=>reply.reject(new ModernTransportError("MCP stdio closed during discovery")),transport.onerror=error=>reply.reject(error);try{return signal.throwIfAborted(),send(request2).catch(reply.reject),await reply.promise}finally{signal.removeEventListener("abort",onabort),transport.onmessage=onmessage,transport.onclose=onclose,transport.onerror=onerror}}async function restart(){logger.info(`MCP server ${serverName}: no clean discovery answer; restarting it for the legacy handshake`);let pid=transport.pid,stale=pid==null?0:1,onclose=transport.onclose;transport.onclose=()=>{stale>0?stale--:onclose?.()},pid!=null&&await reapProcessTree(pid,{termWaitMs:200,killWaitMs:200}),await close(),stale=0,abort.signal.throwIfAborted(),await start(),abort.signal.aborted&&(await close(),abort.signal.throwIfAborted())}function awaitLateDiscovery(){let{onmessage:deliver,onclose,onerror}=transport,late,initialize,initializeId,restarting,settle=()=>{transport.onmessage=deliver,transport.onclose=onclose,transport.onerror=onerror,transport.send=send},unclean=report=>{if(restarting)return report();let replay=initialize;restarting=(async()=>{try{await restart(),replay&&await send(replay)}catch(error){abort.signal.aborted||onerror?.(error instanceof Error?error:new Error(String(error))),onclose?.()}})()};transport.onclose=()=>unclean(()=>onclose?.()),transport.onerror=error=>unclean(()=>onerror?.(error)),transport.onmessage=(message,extra)=>{if("id"in message&&!("method"in message)&&typeof message.id=="string"&&message.id.startsWith(STDIO_PROBE_ID)){late??=discoveryReply(message,message.id);return}let isInitializeReply=initializeId!==void 0&&"id"in message&&message.id===initializeId;if(isInitializeReply&&late&&"error"in message&&late.supportedVersions.includes(MODERN_PROTOCOL_VERSION)){let discovery=late;logger.info(`MCP server ${serverName}: late discovery reply; switching to modern`),settle(),speakModern(discovery,MODERN_PROTOCOL_VERSION),onModern?.(MODERN_PROTOCOL_VERSION),deliver?.({jsonrpc:"2.0",id:initializeId,result:modernInitializeResult(discovery,MODERN_PROTOCOL_VERSION)},extra);return}isInitializeReply&&(settle(),onLegacy?.()),deliver?.(message,extra)},transport.send=async(message,sendOptions)=>("method"in message&&message.method==="initialize"&&"id"in message&&(initialize=message,initializeId=message.id),restarting&&await restarting,send(message,sendOptions))}function speakModern(discovery,version){let initializeResult=modernInitializeResult(discovery,version),deliver=transport.onmessage,live=new Set,initialized=!1;transport.onerror=()=>{let failure=new McpMrtrError("MCP_MRTR_TRANSPORT_FAILED");logger.warn(failure.message),transport.close()},transport.onmessage=(message,extra)=>{if("id"in message&&"method"in message){send({jsonrpc:"2.0",id:message.id,error:{code:-32601,message:"Unsupported MCP method."}}).catch(()=>{});return}if("id"in message&&message.id!==void 0&&!live.delete(message.id))return;if("method"in message&&message.method==="notifications/progress"){let token=message.params?.progressToken;if(typeof token!="string"&&typeof token!="number"||!live.has(token))return}let safe=sanitizeModernMessage(message);safe&&deliver?.(normalizeModernResult(safe),extra)},transport.send=async(message,sendOptions)=>{if(!("method"in message))return send(message,sendOptions);if(message.method==="initialize"){if(!("id"in message)||initialized)throw new ModernTransportError("Modern MCP stdio has already initialized");initialized=!0,deliver?.({jsonrpc:"2.0",id:message.id,result:initializeResult});return}if(message.method==="notifications/initialized"&&!("id"in message))return;if(message.method==="notifications/cancelled"&&!("id"in message)){let id=message.params?.requestId;return typeof id!="string"&&typeof id!="number"||!live.delete(id)?void 0:send({jsonrpc:"2.0",method:message.method,params:{requestId:id,reason:"MCP request canceled"}},sendOptions)}getModernDispatchGuard(message.params)?.();let request2=modernizeRequest("id"in message?message.id:0,message.method,options.clientInfo,options.clientCapabilities,version,message.params);if("id"in message){live.add(message.id);try{return await send(request2,sendOptions)}catch{throw live.delete(message.id),new McpMrtrError("MCP_MRTR_TRANSPORT_FAILED")}}let{id:_id,...notification}=request2;return send(notification,sendOptions)}}}var clientInfo={name:"senpi-mcp-client",version:"0.0.0"},probeOptions={clientInfo,clientCapabilities:{},supportedVersions:[MODERN_PROTOCOL_VERSION]};async function materializeNegotiatedTransport(options,serverName,timeoutMs,signal){signal.throwIfAborted();let{spec,logger}=options,protocol={},outcome={kind:"legacy-fallback"};if(spec.kind==="http"){let fetch=modernHttpFetch(spec,signal),timeout=AbortSignal.timeout(timeoutMs);if(outcome=await probeHttpEra(spec.url,(url,init)=>fetch(url,{...init,signal:timeout}),probeOptions),signal.throwIfAborted(),timeout.throwIfAborted(),outcome.kind==="modern-OK"||outcome.kind==="modern-version-retry"){if(!outcome.discovery)throw new ConnectError(`MCP server ${serverName} modern discovery failed: ${outcome.error?.message}`,{phase:"connect",serverName});protocol.version=outcome.version;let client=await createMcpRequestClient(protocol,options.elicitationUiProvider,()=>modernCredentialSnapshot(spec.authProvider?.tokens()),options.elicitationEnabled),transport=new ModernSdkBridge(new ModernHttpTransport({url:spec.url,fetch:modernHttpFetch(spec,signal,!1),clientInfo,clientCapabilities:{},protocolVersion:outcome.version}),outcome.discovery,outcome.version),version=outcome.version;return logVersion(transport,()=>version),{client,transport,readPid:()=>null,close:async()=>{await transport.close(),await client.close()}}}if(outcome.kind==="indeterminate"&&(outcome.era==="modern"||outcome.reason==="invalid-discovery"))throw new ConnectError(`MCP server ${serverName}: ${outcome.reason}. ${outcome.action}`,{phase:"connect",serverName,cause:outcome.cause})}spec.kind==="http"&&(protocol.legacy=!0);let legacy=await materializeMcpTransport(options,protocol),stdioModernVersion;return spec.kind==="stdio"&&probeStdioTransport(legacy.transport,probeOptions,logger,timeoutMs,serverName,version=>{stdioModernVersion=version,protocol.version=version,protocol.activateRequests?.(),protocol.resolveStdioDiagnostics?.(!0)},void 0,()=>{protocol.legacy=!0,protocol.resolveStdioDiagnostics?.(!1)}),logVersion(legacy.transport,()=>stdioModernVersion),legacy;function logVersion(transport,readModernVersion){let setVersion=transport.setProtocolVersion?.bind(transport);transport.setProtocolVersion=sdkVersion=>{setVersion?.(sdkVersion);let modernVersion=readModernVersion();logger.info(`MCP server ${serverName} negotiated: era=${modernVersion?"modern":"legacy"} version=${modernVersion??sdkVersion}`)}}}export{materializeNegotiatedTransport};
|
|
@@ -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{helpFlagsScope,isPlainHelpRequest,resolveHelpProjectTrust,tryPrintHelpWithoutEngine}from"./chunk-
|
|
2
|
+
import{helpFlagsScope,isPlainHelpRequest,resolveHelpProjectTrust,tryPrintHelpWithoutEngine}from"./chunk-7CNOCJCN.js";import"./chunk-MLVIYDHK.js";import"./chunk-GZVCRV7I.js";import"./chunk-WD6WBYC5.js";import"./chunk-26UBFF6N.js";import"./chunk-U3VOXCGP.js";import"./chunk-E6WYH3ZL.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-2VZJTDUX.js";import"./chunk-E4LBKOZG.js";import"./chunk-GVSBCJFI.js";import"./chunk-T36LJ6MW.js";import"./chunk-QGJLZ6BI.js";import"./chunk-WHPDEDCC.js";import"./chunk-AA2L2RHH.js";import"./chunk-HK46JMSC.js";import"./chunk-4P7WARQZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-6AOVUTUR.js";import"./chunk-45SZOLCU.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-7YO7VQZW.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-IKOFCODM.js";export{helpFlagsScope,isPlainHelpRequest,resolveHelpProjectTrust,tryPrintHelpWithoutEngine};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
+
import{parseHostArgs,resolveHostSocket,runHostCommand}from"./chunk-N7IN46Q5.js";import"./chunk-STMXIBXF.js";import"./chunk-QMRJYMNH.js";import"./chunk-PT6JJUN2.js";import"./chunk-4AOMNOGY.js";import"./chunk-KUPQO7MC.js";import"./chunk-WD6WBYC5.js";import"./chunk-26UBFF6N.js";import"./chunk-KNVNKDER.js";import"./chunk-KKD4CYCI.js";import"./chunk-KXB5WIS5.js";import"./chunk-LOIF6PHI.js";import"./chunk-BZ7726QO.js";import"./chunk-4WZRVZNX.js";import"./chunk-U3VOXCGP.js";import"./chunk-SBGIXMX3.js";import"./chunk-YI7SPFDN.js";import"./chunk-E6WYH3ZL.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-2VZJTDUX.js";import"./chunk-E4LBKOZG.js";import"./chunk-GVSBCJFI.js";import"./chunk-T36LJ6MW.js";import"./chunk-QGJLZ6BI.js";import"./chunk-WHPDEDCC.js";import"./chunk-AA2L2RHH.js";import"./chunk-HK46JMSC.js";import"./chunk-4P7WARQZ.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-6AOVUTUR.js";import"./chunk-45SZOLCU.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import"./chunk-VRDU425E.js";import"./chunk-ZGAB7WQA.js";import"./chunk-7YO7VQZW.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";export{parseHostArgs,resolveHostSocket,runHostCommand};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
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 = () => {}; } }
|
|
3
|
+
import{INTERNAL_SUPERVISOR_FLAG,classifyChildExit,createInternalSocketPath,findInternalSupervisorArgs,parseSupervisorArgs,resolveCliMainPath,resolveHostChildLaunch,runHostSupervisor,spawnableChildLaunch}from"./chunk-LOIF6PHI.js";import{DEFAULT_HANDOFF_GRACE_MS,DEFAULT_HOST_IDLE_EXIT_MS,HANDOFF_GRACE_MS_ENV,HOST_COLD_START_ENV,HOST_IDLE_EXIT_MS_ENV,IdleExitDecider,parseColdStart,parseIdleExitMs,resolveHostPolicy}from"./chunk-BZ7726QO.js";import"./chunk-4WZRVZNX.js";import"./chunk-U3VOXCGP.js";import"./chunk-SBGIXMX3.js";import"./chunk-YI7SPFDN.js";import"./chunk-VRDU425E.js";import"./chunk-ZGAB7WQA.js";import"./chunk-7YO7VQZW.js";import"./chunk-ATQFN5HI.js";import"./chunk-O5RYI3IW.js";import"./chunk-IKOFCODM.js";export{DEFAULT_HANDOFF_GRACE_MS,DEFAULT_HOST_IDLE_EXIT_MS,HANDOFF_GRACE_MS_ENV,HOST_COLD_START_ENV,HOST_IDLE_EXIT_MS_ENV,INTERNAL_SUPERVISOR_FLAG,IdleExitDecider,classifyChildExit,createInternalSocketPath,findInternalSupervisorArgs,parseColdStart,parseIdleExitMs,parseSupervisorArgs,resolveCliMainPath,resolveHostChildLaunch,resolveHostPolicy,runHostSupervisor,spawnableChildLaunch};
|
|
@@ -12,7 +12,7 @@ renameSync(temporary, launcher);
|
|
|
12
12
|
`);return}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed)){process.stderr.write(`warning: ignoring malformed ${BRAND_ENV_VAR} (expected a JSON object)
|
|
13
13
|
`);return}let source=parsed,name=readString(source,"name");if(!name){process.stderr.write(`warning: ignoring ${BRAND_ENV_VAR} without a "name"
|
|
14
14
|
`);return}let configDir=readString(source,"configDir")||`.${name}`;if(!isSafeConfigDirName(configDir)){process.stderr.write(`warning: ignoring ${BRAND_ENV_VAR} with an unsafe "configDir"
|
|
15
|
-
`);return}let changelog=readChangelog(source);return{name,command:readString(source,"command"),displayVersion:readString(source,"displayVersion"),configDir,flatLayout:source.flatLayout===!0,envPrefix:(readString(source,"envPrefix")||name).toUpperCase(),userAgent:readString(source,"userAgent")||name,originator:readString(source,"originator"),update:readUpdateChannel(source),...changelog?{changelog}:{}}}function consumeBrandProfile(env=process.env){return parseBrandProfile(env[BRAND_ENV_VAR])}function brandProfile(){return profileResolved||(cachedProfile=consumeBrandProfile(),profileResolved=!0),cachedProfile}function brandEnvNames(suffix,profile=brandProfile()){let prefixes=[profile?.envPrefix,...LEGACY_ENV_PREFIXES].filter(prefix=>typeof prefix=="string"&&prefix.length>0);return[...new Set(prefixes)].map(prefix=>`${prefix}_${suffix}`)}function envValue(suffix,env=process.env){for(let name of brandEnvNames(suffix)){let value=env[name];if(value!==void 0)return value}}var BRAND_ENV_VAR,LEGACY_ENV_PREFIXES,cachedProfile,profileResolved,init_brand=__esm({"packages/coding-agent/dist/core/brand.js"(){BRAND_ENV_VAR="SENPI_BRAND";LEGACY_ENV_PREFIXES=["SENPI","PI"],profileResolved=!1}});import{lstatSync}from"node:fs";import{dirname,join,normalize}from"node:path";function isDirectory(path){try{return lstatSync(path).isDirectory()}catch{return!1}}function isFile(path){try{return lstatSync(path).isFile()}catch{return!1}}function findNearestParentConfigDir(cwd,homeDir,configDirName,requiredChildDir,requiredChildFile){let normalizedHomeDir=normalize(homeDir),currentDir=normalize(cwd);for(let depth=0;depth<=MAX_PARENT_CONFIG_SEARCH_DEPTH;depth+=1){if(currentDir===normalizedHomeDir)return;let configDir=join(currentDir,configDirName),hasRequiredChild=requiredChildFile?isFile(join(configDir,requiredChildFile)):!requiredChildDir||isDirectory(join(configDir,requiredChildDir));if(isDirectory(configDir)&&hasRequiredChild)return configDir;let parentDir=dirname(currentDir);if(parentDir===currentDir)return;currentDir=parentDir}}var MAX_PARENT_CONFIG_SEARCH_DEPTH,init_nearest_parent_config=__esm({"packages/coding-agent/dist/nearest-parent-config.js"(){MAX_PARENT_CONFIG_SEARCH_DEPTH=100}});var init_marker=__esm({"packages/coding-agent/dist/runtime-snapshot/marker.js"(){}});var require_windows=__commonJS({"node_modules/isexe/windows.js"(exports,module){module.exports=isexe;isexe.sync=sync;var fs2=__require("fs");function checkPathExt(path,options){var pathext=options.pathExt!==void 0?options.pathExt:process.env.PATHEXT;if(!pathext||(pathext=pathext.split(";"),pathext.indexOf("")!==-1))return!0;for(var i=0;i<pathext.length;i++){var p=pathext[i].toLowerCase();if(p&&path.substr(-p.length).toLowerCase()===p)return!0}return!1}function checkStat(stat5,path,options){return!stat5.isSymbolicLink()&&!stat5.isFile()?!1:checkPathExt(path,options)}function isexe(path,options,cb){fs2.stat(path,function(er,stat5){cb(er,er?!1:checkStat(stat5,path,options))})}function sync(path,options){return checkStat(fs2.statSync(path),path,options)}}});var require_mode=__commonJS({"node_modules/isexe/mode.js"(exports,module){module.exports=isexe;isexe.sync=sync;var fs2=__require("fs");function isexe(path,options,cb){fs2.stat(path,function(er,stat5){cb(er,er?!1:checkStat(stat5,options))})}function sync(path,options){return checkStat(fs2.statSync(path),options)}function checkStat(stat5,options){return stat5.isFile()&&checkMode(stat5,options)}function checkMode(stat5,options){var mod=stat5.mode,uid=stat5.uid,gid=stat5.gid,myUid=options.uid!==void 0?options.uid:process.getuid&&process.getuid(),myGid=options.gid!==void 0?options.gid:process.getgid&&process.getgid(),u=parseInt("100",8),g=parseInt("010",8),o=parseInt("001",8),ug=u|g,ret=mod&o||mod&g&&gid===myGid||mod&u&&uid===myUid||mod&ug&&myUid===0;return ret}}});var require_isexe=__commonJS({"node_modules/isexe/index.js"(exports,module){var fs2=__require("fs"),core;process.platform==="win32"||global.TESTING_WINDOWS?core=require_windows():core=require_mode();module.exports=isexe;isexe.sync=sync;function isexe(path,options,cb){if(typeof options=="function"&&(cb=options,options={}),!cb){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(resolve4,reject){isexe(path,options||{},function(er,is){er?reject(er):resolve4(is)})})}core(path,options||{},function(er,is){er&&(er.code==="EACCES"||options&&options.ignoreErrors)&&(er=null,is=!1),cb(er,is)})}function sync(path,options){try{return core.sync(path,options||{})}catch(er){if(options&&options.ignoreErrors||er.code==="EACCES")return!1;throw er}}}});var require_which=__commonJS({"node_modules/which/which.js"(exports,module){var isWindows=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",path=__require("path"),COLON=isWindows?";":":",isexe=require_isexe(),getNotFoundError=cmd=>Object.assign(new Error(`not found: ${cmd}`),{code:"ENOENT"}),getPathInfo=(cmd,opt)=>{let colon=opt.colon||COLON,pathEnv=cmd.match(/\//)||isWindows&&cmd.match(/\\/)?[""]:[...isWindows?[process.cwd()]:[],...(opt.path||process.env.PATH||"").split(colon)],pathExtExe=isWindows?opt.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",pathExt=isWindows?pathExtExe.split(colon):[""];return isWindows&&cmd.indexOf(".")!==-1&&pathExt[0]!==""&&pathExt.unshift(""),{pathEnv,pathExt,pathExtExe}},which=(cmd,opt,cb)=>{typeof opt=="function"&&(cb=opt,opt={}),opt||(opt={});let{pathEnv,pathExt,pathExtExe}=getPathInfo(cmd,opt),found=[],step=i=>new Promise((resolve4,reject)=>{if(i===pathEnv.length)return opt.all&&found.length?resolve4(found):reject(getNotFoundError(cmd));let ppRaw=pathEnv[i],pathPart=/^".*"$/.test(ppRaw)?ppRaw.slice(1,-1):ppRaw,pCmd=path.join(pathPart,cmd),p=!pathPart&&/^\.[\\\/]/.test(cmd)?cmd.slice(0,2)+pCmd:pCmd;resolve4(subStep(p,i,0))}),subStep=(p,i,ii)=>new Promise((resolve4,reject)=>{if(ii===pathExt.length)return resolve4(step(i+1));let ext=pathExt[ii];isexe(p+ext,{pathExt:pathExtExe},(er,is)=>{if(!er&&is)if(opt.all)found.push(p+ext);else return resolve4(p+ext);return resolve4(subStep(p,i,ii+1))})});return cb?step(0).then(res=>cb(null,res),cb):step(0)},whichSync=(cmd,opt)=>{opt=opt||{};let{pathEnv,pathExt,pathExtExe}=getPathInfo(cmd,opt),found=[];for(let i=0;i<pathEnv.length;i++){let ppRaw=pathEnv[i],pathPart=/^".*"$/.test(ppRaw)?ppRaw.slice(1,-1):ppRaw,pCmd=path.join(pathPart,cmd),p=!pathPart&&/^\.[\\\/]/.test(cmd)?cmd.slice(0,2)+pCmd:pCmd;for(let j=0;j<pathExt.length;j++){let cur=p+pathExt[j];try{if(isexe.sync(cur,{pathExt:pathExtExe}))if(opt.all)found.push(cur);else return cur}catch{}}}if(opt.all&&found.length)return found;if(opt.nothrow)return null;throw getNotFoundError(cmd)};module.exports=which;which.sync=whichSync}});var require_path_key=__commonJS({"node_modules/path-key/index.js"(exports,module){"use strict";var pathKey=(options={})=>{let environment=options.env||process.env;return(options.platform||process.platform)!=="win32"?"PATH":Object.keys(environment).reverse().find(key=>key.toUpperCase()==="PATH")||"Path"};module.exports=pathKey;module.exports.default=pathKey}});var require_resolveCommand=__commonJS({"node_modules/cross-spawn/lib/util/resolveCommand.js"(exports,module){"use strict";var path=__require("path"),which=require_which(),getPathKey=require_path_key();function resolveCommandAttempt(parsed,withoutPathExt){let env=parsed.options.env||process.env,cwd=process.cwd(),hasCustomCwd=parsed.options.cwd!=null,shouldSwitchCwd=hasCustomCwd&&process.chdir!==void 0&&!process.chdir.disabled;if(shouldSwitchCwd)try{process.chdir(parsed.options.cwd)}catch{}let resolved;try{resolved=which.sync(parsed.command,{path:env[getPathKey({env})],pathExt:withoutPathExt?path.delimiter:void 0})}catch{}finally{shouldSwitchCwd&&process.chdir(cwd)}return resolved&&(resolved=path.resolve(hasCustomCwd?parsed.options.cwd:"",resolved)),resolved}function resolveCommand(parsed){return resolveCommandAttempt(parsed)||resolveCommandAttempt(parsed,!0)}module.exports=resolveCommand}});var require_escape=__commonJS({"node_modules/cross-spawn/lib/util/escape.js"(exports,module){"use strict";var metaCharsRegExp=/([()\][%!^"`<>&|;, *?])/g;function escapeCommand(arg){return arg=arg.replace(metaCharsRegExp,"^$1"),arg}function escapeArgument(arg,doubleEscapeMetaChars){return arg=`${arg}`,arg=arg.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),arg=arg.replace(/(?=(\\+?)?)\1$/,"$1$1"),arg=`"${arg}"`,arg=arg.replace(metaCharsRegExp,"^$1"),doubleEscapeMetaChars&&(arg=arg.replace(metaCharsRegExp,"^$1")),arg}module.exports.command=escapeCommand;module.exports.argument=escapeArgument}});var require_shebang_regex=__commonJS({"node_modules/shebang-regex/index.js"(exports,module){"use strict";module.exports=/^#!(.*)/}});var require_shebang_command=__commonJS({"node_modules/shebang-command/index.js"(exports,module){"use strict";var shebangRegex=require_shebang_regex();module.exports=(string="")=>{let match=string.match(shebangRegex);if(!match)return null;let[path,argument]=match[0].replace(/#! ?/,"").split(" "),binary=path.split("/").pop();return binary==="env"?argument:argument?`${binary} ${argument}`:binary}}});var require_readShebang=__commonJS({"node_modules/cross-spawn/lib/util/readShebang.js"(exports,module){"use strict";var fs2=__require("fs"),shebangCommand=require_shebang_command();function readShebang(command){let buffer=Buffer.alloc(150),fd;try{fd=fs2.openSync(command,"r"),fs2.readSync(fd,buffer,0,150,0),fs2.closeSync(fd)}catch{}return shebangCommand(buffer.toString())}module.exports=readShebang}});var require_parse=__commonJS({"node_modules/cross-spawn/lib/parse.js"(exports,module){"use strict";var path=__require("path"),resolveCommand=require_resolveCommand(),escape=require_escape(),readShebang=require_readShebang(),isWin=process.platform==="win32",isExecutableRegExp=/\.(?:com|exe)$/i,isCmdShimRegExp=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function detectShebang(parsed){parsed.file=resolveCommand(parsed);let shebang=parsed.file&&readShebang(parsed.file);return shebang?(parsed.args.unshift(parsed.file),parsed.command=shebang,resolveCommand(parsed)):parsed.file}function parseNonShell(parsed){if(!isWin)return parsed;let commandFile=detectShebang(parsed),needsShell=!isExecutableRegExp.test(commandFile);if(parsed.options.forceShell||needsShell){let needsDoubleEscapeMetaChars=isCmdShimRegExp.test(commandFile);parsed.command=path.normalize(parsed.command),parsed.command=escape.command(parsed.command),parsed.args=parsed.args.map(arg=>escape.argument(arg,needsDoubleEscapeMetaChars));let shellCommand=[parsed.command].concat(parsed.args).join(" ");parsed.args=["/d","/s","/c",`"${shellCommand}"`],parsed.command=process.env.comspec||"cmd.exe",parsed.options.windowsVerbatimArguments=!0}return parsed}function parse2(command,args,options){args&&!Array.isArray(args)&&(options=args,args=null),args=args?args.slice(0):[],options=Object.assign({},options);let parsed={command,args,options,file:void 0,original:{command,args}};return options.shell?parsed:parseNonShell(parsed)}module.exports=parse2}});var require_enoent=__commonJS({"node_modules/cross-spawn/lib/enoent.js"(exports,module){"use strict";var isWin=process.platform==="win32";function notFoundError(original,syscall){return Object.assign(new Error(`${syscall} ${original.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${syscall} ${original.command}`,path:original.command,spawnargs:original.args})}function hookChildProcess(cp,parsed){if(!isWin)return;let originalEmit=cp.emit;cp.emit=function(name,arg1){if(name==="exit"){let err=verifyENOENT(arg1,parsed);if(err)return originalEmit.call(cp,"error",err)}return originalEmit.apply(cp,arguments)}}function verifyENOENT(status,parsed){return isWin&&status===1&&!parsed.file?notFoundError(parsed.original,"spawn"):null}function verifyENOENTSync(status,parsed){return isWin&&status===1&&!parsed.file?notFoundError(parsed.original,"spawnSync"):null}module.exports={hookChildProcess,verifyENOENT,verifyENOENTSync,notFoundError}}});var require_cross_spawn=__commonJS({"node_modules/cross-spawn/index.js"(exports,module){"use strict";var cp=__require("child_process"),parse2=require_parse(),enoent=require_enoent();function spawn2(command,args,options){let parsed=parse2(command,args,options),spawned=cp.spawn(parsed.command,parsed.args,parsed.options);return enoent.hookChildProcess(spawned,parsed),spawned}function spawnSync(command,args,options){let parsed=parse2(command,args,options),result=cp.spawnSync(parsed.command,parsed.args,parsed.options);return result.error=result.error||enoent.verifyENOENTSync(result.status,parsed),result}module.exports=spawn2;module.exports.spawn=spawn2;module.exports.sync=spawnSync;module.exports._parse=parse2;module.exports._enoent=enoent}});var import_cross_spawn,init_child_process=__esm({"packages/coding-agent/dist/utils/child-process.js"(){import_cross_spawn=__toESM(require_cross_spawn(),1)}});import{homedir}from"node:os";import{isAbsolute,join as join2,resolve as nodeResolvePath,parse,relative,sep}from"node:path";import{fileURLToPath}from"node:url";function normalizeWindowsShellPath(filePath){if(!filePath.startsWith("/")||filePath.startsWith("//")||filePath.includes("\\"))return filePath;let match=filePath.match(/^\/(?:mnt\/|cygdrive\/)?([a-z])(?:\/(.*))?$/i);if(!match)return filePath;let suffix=match[2]?.replaceAll("/","\\");return`${match[1].toUpperCase()}:\\${suffix??""}`}function normalizePath(input,options={}){let normalized=options.trim?input.trim():input;if(options.normalizeUnicodeSpaces&&(normalized=normalized.replace(UNICODE_SPACES," ")),options.stripAtPrefix&&normalized.startsWith("@")&&(normalized=normalized.slice(1)),process.platform==="win32"&&(normalized=normalizeWindowsShellPath(normalized)),options.expandTilde??!0){let home=options.homeDir??homedir();if(normalized==="~")return home;if(normalized.startsWith("~/")||process.platform==="win32"&&normalized.startsWith("~\\"))return join2(home,normalized.slice(2))}return/^file:\/\//.test(normalized)?fileURLToPath(normalized):normalized}var UNICODE_SPACES,init_paths=__esm({"packages/coding-agent/dist/utils/paths.js"(){init_child_process();UNICODE_SPACES=/[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g}});function splitBom(content){return content.startsWith("\uFEFF")?{bom:"\uFEFF",text:content.slice(1)}:{bom:"",text:content}}function stripBom(content){return splitBom(content).text}var init_text=__esm({"packages/coding-agent/dist/utils/text.js"(){}});import{accessSync,constants,existsSync,readFileSync,realpathSync}from"fs";import{homedir as homedir2,userInfo}from"os";import{basename,dirname as dirname2,join as join3,resolve,sep as sep2,win32}from"path";import{fileURLToPath as fileURLToPath2}from"url";function findNodePackageDir(startDir){let dir=startDir;for(;dir!==dirname2(dir);){if(existsSync(join3(dir,"package.json"))){let parent=dirname2(dir);return basename(dir)==="dist"&&existsSync(join3(parent,"package.json"))?parent:dir}dir=dirname2(dir)}return startDir}function getPackageDir(){let envDir=envValue("PACKAGE_DIR");return envDir?normalizePath(envDir):isBunBinary?dirname2(process.execPath):(nodePackageDir??=findNodePackageDir(__dirname),nodePackageDir)}function getPackageJsonPath(){return join3(getPackageDir(),"package.json")}function resolveAgentDir(cwd,homeDir,envDir){if(envDir)return normalizePath(envDir,{homeDir});if(CONFIG_FLAT_LAYOUT)return findNearestParentConfigDir(cwd,homeDir,CONFIG_DIR_NAME,void 0,FLAT_LAYOUT_SENTINEL)??join3(homeDir,CONFIG_DIR_NAME);let projectConfigDir=findNearestParentConfigDir(cwd,homeDir,CONFIG_DIR_NAME,"agent");return projectConfigDir?join3(projectConfigDir,"agent"):join3(homeDir,CONFIG_DIR_NAME,"agent")}function isGuardedTestRun(env){return env.SENPI_TEST_AGENT_DIR_GUARD==="1"}function realHomeDir(){try{return userInfo().homedir}catch{return}}function assertAgentDirAllowedInTests(agentDir,activeConfigDirName,env=process.env){if(!isGuardedTestRun(env)||env.SENPI_TEST_USE_REAL_AGENT_DIR==="1")return;let home=realHomeDir();if(!home)return;let target=resolve(agentDir);for(let configDir of new Set([...KNOWN_BRAND_CONFIG_DIRS,activeConfigDirName])){let root=join3(home,configDir);if(target===root||target.startsWith(root+sep2))throw new RealAgentDirInTestError(target)}}function getAgentDir(){let agentDir=resolveAgentDir(process.cwd(),homedir2(),envValue("CODING_AGENT_DIR"));return assertAgentDirAllowedInTests(agentDir,CONFIG_DIR_NAME),agentDir}var __filename,__dirname,isBunBinary,isBunRuntime,isBundledNode,nodePackageDir,pkg,piConfigName,BRAND,PACKAGE_NAME,APP_NAME,APP_COMMAND,APP_TITLE,CONFIG_DIR_NAME,CONFIG_FLAT_LAYOUT,VERSION,DISPLAY_VERSION,ENV_PREFIX,ENV_AGENT_DIR,ENV_SESSION_DIR,FLAT_LAYOUT_SENTINEL,KNOWN_BRAND_CONFIG_DIRS,RealAgentDirInTestError,init_config=__esm({"packages/coding-agent/dist/config.js"(){init_bun_global_launcher();init_brand();init_nearest_parent_config();init_marker();init_child_process();init_paths();init_text();__filename=fileURLToPath2(import.meta.url),__dirname=dirname2(__filename),isBunBinary=import.meta.url.includes("$bunfs")||import.meta.url.includes("~BUN")||import.meta.url.includes("%7EBUN"),isBunRuntime=!!process.versions.bun,isBundledNode=!0;pkg={};try{pkg=JSON.parse(stripBom(readFileSync(getPackageJsonPath(),"utf-8")))}catch(e){if(e.code!=="ENOENT")throw e}piConfigName=pkg.piConfig?.name,BRAND=brandProfile(),PACKAGE_NAME=pkg.name||"@earendil-works/pi-coding-agent",APP_NAME=BRAND?.name||piConfigName||"pi",APP_COMMAND=BRAND?.command??APP_NAME,APP_TITLE=BRAND?.name||(piConfigName?APP_NAME:"\u03C0"),CONFIG_DIR_NAME=BRAND?.configDir||pkg.piConfig?.configDir||".pi",CONFIG_FLAT_LAYOUT=BRAND?.flatLayout===!0,VERSION=pkg.version||"0.0.0",DISPLAY_VERSION=BRAND?.displayVersion||VERSION,ENV_PREFIX=BRAND?.envPrefix||APP_NAME.toUpperCase(),ENV_AGENT_DIR=`${ENV_PREFIX}_CODING_AGENT_DIR`,ENV_SESSION_DIR=`${ENV_PREFIX}_CODING_AGENT_SESSION_DIR`,FLAT_LAYOUT_SENTINEL="settings.json";KNOWN_BRAND_CONFIG_DIRS=[".senpi",".omo",".pi"],RealAgentDirInTestError=class extends Error{constructor(agentDir){super(`Refusing to use the real agent directory ${agentDir} from a test run. Point <BRAND>_CODING_AGENT_DIR at a temp dir, or set SENPI_TEST_USE_REAL_AGENT_DIR=1 to opt in.`),this.name="RealAgentDirInTestError",this.agentDir=agentDir}}}});var require_signals=__commonJS({"node_modules/signal-exit/signals.js"(exports,module){module.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"];process.platform!=="win32"&&module.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&module.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")}});var require_signal_exit=__commonJS({"node_modules/signal-exit/index.js"(exports,module){var process2=global.process,processOk=function(process3){return process3&&typeof process3=="object"&&typeof process3.removeListener=="function"&&typeof process3.emit=="function"&&typeof process3.reallyExit=="function"&&typeof process3.listeners=="function"&&typeof process3.kill=="function"&&typeof process3.pid=="number"&&typeof process3.on=="function"};processOk(process2)?(assert=__require("assert"),signals=require_signals(),isWin=/^win/i.test(process2.platform),EE=__require("events"),typeof EE!="function"&&(EE=EE.EventEmitter),process2.__signal_exit_emitter__?emitter=process2.__signal_exit_emitter__:(emitter=process2.__signal_exit_emitter__=new EE,emitter.count=0,emitter.emitted={}),emitter.infinite||(emitter.setMaxListeners(1/0),emitter.infinite=!0),module.exports=function(cb,opts){if(!processOk(global.process))return function(){};assert.equal(typeof cb,"function","a callback must be provided for exit handler"),loaded===!1&&load();var ev="exit";opts&&opts.alwaysLast&&(ev="afterexit");var remove=function(){emitter.removeListener(ev,cb),emitter.listeners("exit").length===0&&emitter.listeners("afterexit").length===0&&unload()};return emitter.on(ev,cb),remove},unload=function(){!loaded||!processOk(global.process)||(loaded=!1,signals.forEach(function(sig){try{process2.removeListener(sig,sigListeners[sig])}catch{}}),process2.emit=originalProcessEmit,process2.reallyExit=originalProcessReallyExit,emitter.count-=1)},module.exports.unload=unload,emit=function(event,code,signal){emitter.emitted[event]||(emitter.emitted[event]=!0,emitter.emit(event,code,signal))},sigListeners={},signals.forEach(function(sig){sigListeners[sig]=function(){if(processOk(global.process)){var listeners=process2.listeners(sig);listeners.length===emitter.count&&(unload(),emit("exit",null,sig),emit("afterexit",null,sig),isWin&&sig==="SIGHUP"&&(sig="SIGINT"),process2.kill(process2.pid,sig))}}}),module.exports.signals=function(){return signals},loaded=!1,load=function(){loaded||!processOk(global.process)||(loaded=!0,emitter.count+=1,signals=signals.filter(function(sig){try{return process2.on(sig,sigListeners[sig]),!0}catch{return!1}}),process2.emit=processEmit,process2.reallyExit=processReallyExit)},module.exports.load=load,originalProcessReallyExit=process2.reallyExit,processReallyExit=function(code){processOk(global.process)&&(process2.exitCode=code||0,emit("exit",process2.exitCode,null),emit("afterexit",process2.exitCode,null),originalProcessReallyExit.call(process2,process2.exitCode))},originalProcessEmit=process2.emit,processEmit=function(ev,arg){if(ev==="exit"&&processOk(global.process)){arg!==void 0&&(process2.exitCode=arg);var ret=originalProcessEmit.apply(this,arguments);return emit("exit",process2.exitCode,null),emit("afterexit",process2.exitCode,null),ret}else return originalProcessEmit.apply(this,arguments)}):module.exports=function(){return function(){}};var assert,signals,isWin,EE,emitter,unload,emit,sigListeners,loaded,load,originalProcessReallyExit,processReallyExit,originalProcessEmit,processEmit}});import{execFile,execFileSync}from"node:child_process";function processStartTimeMs(identity){if(/^\d+$/.test(identity)){let parsed2=Number((BigInt(identity)-WINDOWS_FILETIME_EPOCH)/10000n);return Number.isFinite(parsed2)?parsed2:void 0}let localIdentity=identity.trim(),korean=/^(\d{4})\uB144\s+(\d{1,2})\uC6D4\s+(\d{1,2})\uC77C\s+[\uC6D4\uD654\uC218\uBAA9\uAE08\uD1A0\uC77C]\uC694\uC77C\s+(\d{1,2})\uC2DC\s+(\d{1,2})\uBD84\s+(\d{1,2})\uCD08$/.exec(localIdentity),japanese=/^[\u65E5\u6708\u706B\u6C34\u6728\u91D1\u571F](?:\u66DC\u65E5)?\s+(\d{1,2})\/\s*(\d{1,2})\s+(\d{2}):(\d{2}):(\d{2})\s+(\d{4})$/.exec(localIdentity),parts=korean?korean.slice(1):japanese?[japanese[6],japanese[1],japanese[2],japanese[3],japanese[4],japanese[5]]:void 0;if(parts===void 0){let parsed2=Date.parse(identity);return Number.isFinite(parsed2)?parsed2:void 0}let[year=NaN,month=NaN,day=NaN,hour=NaN,minute=NaN,second=NaN]=parts.map(Number),parsed=new Date(year,month-1,day,hour,minute,second,0);return parsed.getFullYear()===year&&parsed.getMonth()===month-1&&parsed.getDate()===day&&parsed.getHours()===hour&&parsed.getMinutes()===minute&&parsed.getSeconds()===second?parsed.getTime():void 0}function sameProcessStartMs(recorded,observed){return recorded!==void 0&&observed!==void 0&&Number.isFinite(recorded)&&Number.isFinite(observed)&&Math.abs(recorded-observed)<=PROCESS_START_TOLERANCE_MS}function parseDaemonPidFile(text){let parsed;try{parsed=JSON.parse(text)}catch(error){if(error instanceof SyntaxError)return;throw error}let unguarded=parsed!==null&&isRecord(parsed)&&parsed.processStartTime===null;if(!(!isRecord(parsed)||typeof parsed.pid!="number"||!unguarded&&typeof parsed.processStartTime!="string")&&!(!Number.isInteger(parsed.pid)||parsed.pid<=0)){if(unguarded)return{pid:parsed.pid,processStartTime:null};if(!(typeof parsed.processStartTime!="string"||parsed.processStartTime.trim()===""))return{pid:parsed.pid,processStartTime:parsed.processStartTime}}}async function readProcessIdentity(pid,platform=process.platform,timeoutMs,isLive=processIsLive,timeZone){let command=platform==="win32"?{executable:"powershell.exe",args:["-NoProfile","-NonInteractive","-Command",`$process = Get-CimInstance Win32_Process -Filter "ProcessId=${String(pid)}" -ErrorAction Stop; if ($null -eq $process) { Write-Output '__SENPI_ABSENT__'; exit 0 }; $process.CreationDate.ToFileTimeUtc().ToString("D", [Globalization.CultureInfo]::InvariantCulture)`]}:{executable:"ps",args:["-o","stat=,lstart=","-p",String(pid)]};return new Promise(resolve4=>{let effectiveTimeoutMs=timeoutMs??(platform==="win32"?1e3:void 0);execFile(command.executable,command.args,{windowsHide:!0,...effectiveTimeoutMs===void 0?{}:{timeout:effectiveTimeoutMs},...platform==="win32"&&timeZone===void 0?{}:{env:{...process.env,LC_ALL:"C",LANG:"C",...timeZone?{TZ:timeZone}:{}}}},(error,stdout)=>{if(error){let code="code"in error?error.code:void 0;if(platform!=="win32"&&code===1||!isLive(pid)){resolve4({kind:"absent"});return}resolve4({kind:"error",error});return}let snapshot=stdout.trim();if(snapshot==="__SENPI_ABSENT__")return resolve4({kind:"absent"});let state=platform==="win32"?"":snapshot.split(/\s+/,1)[0]??"";if(state.startsWith("Z"))return resolve4({kind:"absent"});let output=platform==="win32"?snapshot:snapshot.slice(state.length).trim();if(!output||platform==="win32"&&!/^\d+$/.test(output))return resolve4({kind:"error",error:new Error("invalid process identity output")});resolve4({kind:"present",identity:timeZone&&platform!=="win32"?`${output} UTC`:output})}).once("error",error=>resolve4({kind:"error",error}))})}async function readProcessStartTime(pid,platform=process.platform,timeoutMs){return readProcessIdentity(pid,platform,timeoutMs).then(result=>{if(result.kind==="error")throw result.error;return result.kind==="present"?result.identity:void 0})}function processIsLive(pid){try{return process.kill(pid,0),!0}catch(error){if(isNodeErrorCode(error,"ESRCH"))return!1;if(isNodeErrorCode(error,"EPERM"))return!0;throw error}}async function waitForStartTime(pid,timeoutMs,readStartTime=readProcessStartTime,isLive=processIsLive){let deadline=Date.now()+timeoutMs;for(;Date.now()<=deadline;){let startTime;try{startTime=await readStartTime(pid)}catch{}if(startTime)return startTime;await delay(20)}if(!isLive(pid))throw new Error(`spawned daemon pid ${pid} had no process start time`)}function delay(ms){return new Promise(resolveDelay=>setTimeout(resolveDelay,ms))}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNodeErrorCode(error,code){return error instanceof Error&&"code"in error&&error.code===code}var WINDOWS_FILETIME_EPOCH,PROCESS_START_TOLERANCE_MS,init_process_identity=__esm({"packages/coding-agent/dist/utils/process-identity.js"(){WINDOWS_FILETIME_EPOCH=116444736000000000n,PROCESS_START_TOLERANCE_MS=3e3}});var HOST_INSTANCE_ID_ENV,init_host_identity_env=__esm({"packages/coding-agent/dist/modes/rpc/host-identity-env.js"(){HOST_INSTANCE_ID_ENV="SENPI_RPC_HOST_INSTANCE_ID"}});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 record2=request;return record2.type==="warm"||record2.type==="authenticate"?!0:record2[OBSERVE_REQUEST_FIELD]===!0&&OBSERVING_COMMANDS.has(record2.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}var OBSERVE_REQUEST_FIELD,ORIGIN_HOST_INSTANCE_FIELD,OBSERVING_COMMANDS,init_host_observe_request=__esm({"packages/coding-agent/dist/modes/rpc/host-observe-request.js"(){init_host_identity_env();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"])}});import{StringDecoder}from"node:string_decoder";function serializeJsonLine(value){return`${JSON.stringify(value)}
|
|
15
|
+
`);return}let changelog=readChangelog(source);return{name,command:readString(source,"command"),displayVersion:readString(source,"displayVersion"),configDir,flatLayout:source.flatLayout===!0,envPrefix:(readString(source,"envPrefix")||name).toUpperCase(),userAgent:readString(source,"userAgent")||name,originator:readString(source,"originator"),update:readUpdateChannel(source),...changelog?{changelog}:{}}}function consumeBrandProfile(env=process.env){return parseBrandProfile(env[BRAND_ENV_VAR])}function brandProfile(){return profileResolved||(cachedProfile=consumeBrandProfile(),profileResolved=!0),cachedProfile}function brandEnvNames(suffix,profile=brandProfile()){let prefixes=[profile?.envPrefix,...LEGACY_ENV_PREFIXES].filter(prefix=>typeof prefix=="string"&&prefix.length>0);return[...new Set(prefixes)].map(prefix=>`${prefix}_${suffix}`)}function envValue(suffix,env=process.env){for(let name of brandEnvNames(suffix)){let value=env[name];if(value!==void 0)return value}}var BRAND_ENV_VAR,LEGACY_ENV_PREFIXES,cachedProfile,profileResolved,init_brand=__esm({"packages/coding-agent/dist/core/brand.js"(){BRAND_ENV_VAR="SENPI_BRAND";LEGACY_ENV_PREFIXES=["SENPI","PI"],profileResolved=!1}});import{lstatSync}from"node:fs";import{dirname,join,normalize}from"node:path";function isDirectory(path){try{return lstatSync(path).isDirectory()}catch{return!1}}function isFile(path){try{return lstatSync(path).isFile()}catch{return!1}}function findNearestParentConfigDir(cwd,homeDir,configDirName,requiredChildDir,requiredChildFile){let normalizedHomeDir=normalize(homeDir),currentDir=normalize(cwd);for(let depth=0;depth<=MAX_PARENT_CONFIG_SEARCH_DEPTH;depth+=1){if(currentDir===normalizedHomeDir)return;let configDir=join(currentDir,configDirName),hasRequiredChild=requiredChildFile?isFile(join(configDir,requiredChildFile)):!requiredChildDir||isDirectory(join(configDir,requiredChildDir));if(isDirectory(configDir)&&hasRequiredChild)return configDir;let parentDir=dirname(currentDir);if(parentDir===currentDir)return;currentDir=parentDir}}var MAX_PARENT_CONFIG_SEARCH_DEPTH,init_nearest_parent_config=__esm({"packages/coding-agent/dist/nearest-parent-config.js"(){MAX_PARENT_CONFIG_SEARCH_DEPTH=100}});var init_marker=__esm({"packages/coding-agent/dist/runtime-snapshot/marker.js"(){}});var require_windows=__commonJS({"node_modules/isexe/windows.js"(exports,module){module.exports=isexe;isexe.sync=sync;var fs2=__require("fs");function checkPathExt(path,options){var pathext=options.pathExt!==void 0?options.pathExt:process.env.PATHEXT;if(!pathext||(pathext=pathext.split(";"),pathext.indexOf("")!==-1))return!0;for(var i=0;i<pathext.length;i++){var p=pathext[i].toLowerCase();if(p&&path.substr(-p.length).toLowerCase()===p)return!0}return!1}function checkStat(stat5,path,options){return!stat5.isSymbolicLink()&&!stat5.isFile()?!1:checkPathExt(path,options)}function isexe(path,options,cb){fs2.stat(path,function(er,stat5){cb(er,er?!1:checkStat(stat5,path,options))})}function sync(path,options){return checkStat(fs2.statSync(path),path,options)}}});var require_mode=__commonJS({"node_modules/isexe/mode.js"(exports,module){module.exports=isexe;isexe.sync=sync;var fs2=__require("fs");function isexe(path,options,cb){fs2.stat(path,function(er,stat5){cb(er,er?!1:checkStat(stat5,options))})}function sync(path,options){return checkStat(fs2.statSync(path),options)}function checkStat(stat5,options){return stat5.isFile()&&checkMode(stat5,options)}function checkMode(stat5,options){var mod=stat5.mode,uid=stat5.uid,gid=stat5.gid,myUid=options.uid!==void 0?options.uid:process.getuid&&process.getuid(),myGid=options.gid!==void 0?options.gid:process.getgid&&process.getgid(),u=parseInt("100",8),g=parseInt("010",8),o=parseInt("001",8),ug=u|g,ret=mod&o||mod&g&&gid===myGid||mod&u&&uid===myUid||mod&ug&&myUid===0;return ret}}});var require_isexe=__commonJS({"node_modules/isexe/index.js"(exports,module){var fs2=__require("fs"),core;process.platform==="win32"||global.TESTING_WINDOWS?core=require_windows():core=require_mode();module.exports=isexe;isexe.sync=sync;function isexe(path,options,cb){if(typeof options=="function"&&(cb=options,options={}),!cb){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(resolve4,reject){isexe(path,options||{},function(er,is){er?reject(er):resolve4(is)})})}core(path,options||{},function(er,is){er&&(er.code==="EACCES"||options&&options.ignoreErrors)&&(er=null,is=!1),cb(er,is)})}function sync(path,options){try{return core.sync(path,options||{})}catch(er){if(options&&options.ignoreErrors||er.code==="EACCES")return!1;throw er}}}});var require_which=__commonJS({"node_modules/which/which.js"(exports,module){var isWindows=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",path=__require("path"),COLON=isWindows?";":":",isexe=require_isexe(),getNotFoundError=cmd=>Object.assign(new Error(`not found: ${cmd}`),{code:"ENOENT"}),getPathInfo=(cmd,opt)=>{let colon=opt.colon||COLON,pathEnv=cmd.match(/\//)||isWindows&&cmd.match(/\\/)?[""]:[...isWindows?[process.cwd()]:[],...(opt.path||process.env.PATH||"").split(colon)],pathExtExe=isWindows?opt.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",pathExt=isWindows?pathExtExe.split(colon):[""];return isWindows&&cmd.indexOf(".")!==-1&&pathExt[0]!==""&&pathExt.unshift(""),{pathEnv,pathExt,pathExtExe}},which=(cmd,opt,cb)=>{typeof opt=="function"&&(cb=opt,opt={}),opt||(opt={});let{pathEnv,pathExt,pathExtExe}=getPathInfo(cmd,opt),found=[],step=i=>new Promise((resolve4,reject)=>{if(i===pathEnv.length)return opt.all&&found.length?resolve4(found):reject(getNotFoundError(cmd));let ppRaw=pathEnv[i],pathPart=/^".*"$/.test(ppRaw)?ppRaw.slice(1,-1):ppRaw,pCmd=path.join(pathPart,cmd),p=!pathPart&&/^\.[\\\/]/.test(cmd)?cmd.slice(0,2)+pCmd:pCmd;resolve4(subStep(p,i,0))}),subStep=(p,i,ii)=>new Promise((resolve4,reject)=>{if(ii===pathExt.length)return resolve4(step(i+1));let ext=pathExt[ii];isexe(p+ext,{pathExt:pathExtExe},(er,is)=>{if(!er&&is)if(opt.all)found.push(p+ext);else return resolve4(p+ext);return resolve4(subStep(p,i,ii+1))})});return cb?step(0).then(res=>cb(null,res),cb):step(0)},whichSync=(cmd,opt)=>{opt=opt||{};let{pathEnv,pathExt,pathExtExe}=getPathInfo(cmd,opt),found=[];for(let i=0;i<pathEnv.length;i++){let ppRaw=pathEnv[i],pathPart=/^".*"$/.test(ppRaw)?ppRaw.slice(1,-1):ppRaw,pCmd=path.join(pathPart,cmd),p=!pathPart&&/^\.[\\\/]/.test(cmd)?cmd.slice(0,2)+pCmd:pCmd;for(let j=0;j<pathExt.length;j++){let cur=p+pathExt[j];try{if(isexe.sync(cur,{pathExt:pathExtExe}))if(opt.all)found.push(cur);else return cur}catch{}}}if(opt.all&&found.length)return found;if(opt.nothrow)return null;throw getNotFoundError(cmd)};module.exports=which;which.sync=whichSync}});var require_path_key=__commonJS({"node_modules/path-key/index.js"(exports,module){"use strict";var pathKey=(options={})=>{let environment=options.env||process.env;return(options.platform||process.platform)!=="win32"?"PATH":Object.keys(environment).reverse().find(key=>key.toUpperCase()==="PATH")||"Path"};module.exports=pathKey;module.exports.default=pathKey}});var require_resolveCommand=__commonJS({"node_modules/cross-spawn/lib/util/resolveCommand.js"(exports,module){"use strict";var path=__require("path"),which=require_which(),getPathKey=require_path_key();function resolveCommandAttempt(parsed,withoutPathExt){let env=parsed.options.env||process.env,cwd=process.cwd(),hasCustomCwd=parsed.options.cwd!=null,shouldSwitchCwd=hasCustomCwd&&process.chdir!==void 0&&!process.chdir.disabled;if(shouldSwitchCwd)try{process.chdir(parsed.options.cwd)}catch{}let resolved;try{resolved=which.sync(parsed.command,{path:env[getPathKey({env})],pathExt:withoutPathExt?path.delimiter:void 0})}catch{}finally{shouldSwitchCwd&&process.chdir(cwd)}return resolved&&(resolved=path.resolve(hasCustomCwd?parsed.options.cwd:"",resolved)),resolved}function resolveCommand(parsed){return resolveCommandAttempt(parsed)||resolveCommandAttempt(parsed,!0)}module.exports=resolveCommand}});var require_escape=__commonJS({"node_modules/cross-spawn/lib/util/escape.js"(exports,module){"use strict";var metaCharsRegExp=/([()\][%!^"`<>&|;, *?])/g;function escapeCommand(arg){return arg=arg.replace(metaCharsRegExp,"^$1"),arg}function escapeArgument(arg,doubleEscapeMetaChars){return arg=`${arg}`,arg=arg.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),arg=arg.replace(/(?=(\\+?)?)\1$/,"$1$1"),arg=`"${arg}"`,arg=arg.replace(metaCharsRegExp,"^$1"),doubleEscapeMetaChars&&(arg=arg.replace(metaCharsRegExp,"^$1")),arg}module.exports.command=escapeCommand;module.exports.argument=escapeArgument}});var require_shebang_regex=__commonJS({"node_modules/shebang-regex/index.js"(exports,module){"use strict";module.exports=/^#!(.*)/}});var require_shebang_command=__commonJS({"node_modules/shebang-command/index.js"(exports,module){"use strict";var shebangRegex=require_shebang_regex();module.exports=(string="")=>{let match=string.match(shebangRegex);if(!match)return null;let[path,argument]=match[0].replace(/#! ?/,"").split(" "),binary=path.split("/").pop();return binary==="env"?argument:argument?`${binary} ${argument}`:binary}}});var require_readShebang=__commonJS({"node_modules/cross-spawn/lib/util/readShebang.js"(exports,module){"use strict";var fs2=__require("fs"),shebangCommand=require_shebang_command();function readShebang(command){let buffer=Buffer.alloc(150),fd;try{fd=fs2.openSync(command,"r"),fs2.readSync(fd,buffer,0,150,0),fs2.closeSync(fd)}catch{}return shebangCommand(buffer.toString())}module.exports=readShebang}});var require_parse=__commonJS({"node_modules/cross-spawn/lib/parse.js"(exports,module){"use strict";var path=__require("path"),resolveCommand=require_resolveCommand(),escape=require_escape(),readShebang=require_readShebang(),isWin=process.platform==="win32",isExecutableRegExp=/\.(?:com|exe)$/i,isCmdShimRegExp=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function detectShebang(parsed){parsed.file=resolveCommand(parsed);let shebang=parsed.file&&readShebang(parsed.file);return shebang?(parsed.args.unshift(parsed.file),parsed.command=shebang,resolveCommand(parsed)):parsed.file}function parseNonShell(parsed){if(!isWin)return parsed;let commandFile=detectShebang(parsed),needsShell=!isExecutableRegExp.test(commandFile);if(parsed.options.forceShell||needsShell){let needsDoubleEscapeMetaChars=isCmdShimRegExp.test(commandFile);parsed.command=path.normalize(parsed.command),parsed.command=escape.command(parsed.command),parsed.args=parsed.args.map(arg=>escape.argument(arg,needsDoubleEscapeMetaChars));let shellCommand=[parsed.command].concat(parsed.args).join(" ");parsed.args=["/d","/s","/c",`"${shellCommand}"`],parsed.command=process.env.comspec||"cmd.exe",parsed.options.windowsVerbatimArguments=!0}return parsed}function parse2(command,args,options){args&&!Array.isArray(args)&&(options=args,args=null),args=args?args.slice(0):[],options=Object.assign({},options);let parsed={command,args,options,file:void 0,original:{command,args}};return options.shell?parsed:parseNonShell(parsed)}module.exports=parse2}});var require_enoent=__commonJS({"node_modules/cross-spawn/lib/enoent.js"(exports,module){"use strict";var isWin=process.platform==="win32";function notFoundError(original,syscall){return Object.assign(new Error(`${syscall} ${original.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${syscall} ${original.command}`,path:original.command,spawnargs:original.args})}function hookChildProcess(cp,parsed){if(!isWin)return;let originalEmit=cp.emit;cp.emit=function(name,arg1){if(name==="exit"){let err=verifyENOENT(arg1,parsed);if(err)return originalEmit.call(cp,"error",err)}return originalEmit.apply(cp,arguments)}}function verifyENOENT(status,parsed){return isWin&&status===1&&!parsed.file?notFoundError(parsed.original,"spawn"):null}function verifyENOENTSync(status,parsed){return isWin&&status===1&&!parsed.file?notFoundError(parsed.original,"spawnSync"):null}module.exports={hookChildProcess,verifyENOENT,verifyENOENTSync,notFoundError}}});var require_cross_spawn=__commonJS({"node_modules/cross-spawn/index.js"(exports,module){"use strict";var cp=__require("child_process"),parse2=require_parse(),enoent=require_enoent();function spawn2(command,args,options){let parsed=parse2(command,args,options),spawned=cp.spawn(parsed.command,parsed.args,parsed.options);return enoent.hookChildProcess(spawned,parsed),spawned}function spawnSync(command,args,options){let parsed=parse2(command,args,options),result=cp.spawnSync(parsed.command,parsed.args,parsed.options);return result.error=result.error||enoent.verifyENOENTSync(result.status,parsed),result}module.exports=spawn2;module.exports.spawn=spawn2;module.exports.sync=spawnSync;module.exports._parse=parse2;module.exports._enoent=enoent}});var import_cross_spawn,init_child_process=__esm({"packages/coding-agent/dist/utils/child-process.js"(){import_cross_spawn=__toESM(require_cross_spawn(),1)}});import{homedir}from"node:os";import{isAbsolute,join as join2,resolve as nodeResolvePath,parse,relative,sep}from"node:path";import{fileURLToPath}from"node:url";function normalizeWindowsShellPath(filePath){if(!filePath.startsWith("/")||filePath.startsWith("//")||filePath.includes("\\"))return filePath;let match=filePath.match(/^\/(?:mnt\/|cygdrive\/)?([a-z])(?:\/(.*))?$/i);if(!match)return filePath;let suffix=match[2]?.replaceAll("/","\\");return`${match[1].toUpperCase()}:\\${suffix??""}`}function normalizePath(input,options={}){let normalized=options.trim?input.trim():input;if(options.normalizeUnicodeSpaces&&(normalized=normalized.replace(UNICODE_SPACES," ")),options.stripAtPrefix&&normalized.startsWith("@")&&(normalized=normalized.slice(1)),process.platform==="win32"&&(normalized=normalizeWindowsShellPath(normalized)),options.expandTilde??!0){let home=options.homeDir??homedir();if(normalized==="~")return home;if(normalized.startsWith("~/")||process.platform==="win32"&&normalized.startsWith("~\\"))return join2(home,normalized.slice(2))}return/^file:\/\//.test(normalized)?fileURLToPath(normalized):normalized}var UNICODE_SPACES,init_paths=__esm({"packages/coding-agent/dist/utils/paths.js"(){init_child_process();UNICODE_SPACES=/[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g}});function splitBom(content){return content.startsWith("\uFEFF")?{bom:"\uFEFF",text:content.slice(1)}:{bom:"",text:content}}function stripBom(content){return splitBom(content).text}var init_text=__esm({"packages/coding-agent/dist/utils/text.js"(){}});import{accessSync,constants,existsSync,readFileSync,realpathSync}from"fs";import{homedir as homedir2,userInfo}from"os";import{basename,dirname as dirname2,join as join3,resolve,sep as sep2,win32}from"path";import{fileURLToPath as fileURLToPath2}from"url";function findNodePackageDir(startDir){let dir=startDir;for(;dir!==dirname2(dir);){if(existsSync(join3(dir,"package.json"))){let parent=dirname2(dir);return basename(dir)==="dist"&&existsSync(join3(parent,"package.json"))?parent:dir}dir=dirname2(dir)}return startDir}function getPackageDir(){let envDir=envValue("PACKAGE_DIR");return envDir?normalizePath(envDir):isBunBinary?dirname2(process.execPath):(nodePackageDir??=findNodePackageDir(__dirname),nodePackageDir)}function getPackageJsonPath(){return join3(getPackageDir(),"package.json")}function resolveAgentDir(cwd,homeDir,envDir){if(envDir)return normalizePath(envDir,{homeDir});if(CONFIG_FLAT_LAYOUT)return findNearestParentConfigDir(cwd,homeDir,CONFIG_DIR_NAME,void 0,FLAT_LAYOUT_SENTINEL)??join3(homeDir,CONFIG_DIR_NAME);let projectConfigDir=findNearestParentConfigDir(cwd,homeDir,CONFIG_DIR_NAME,"agent");return projectConfigDir?join3(projectConfigDir,"agent"):join3(homeDir,CONFIG_DIR_NAME,"agent")}function isGuardedTestRun(env){return env.SENPI_TEST_AGENT_DIR_GUARD==="1"}function realHomeDir(){try{return userInfo().homedir}catch{return}}function assertAgentDirAllowedInTests(agentDir,activeConfigDirName,env=process.env){if(!isGuardedTestRun(env)||env.SENPI_TEST_USE_REAL_AGENT_DIR==="1")return;let home=realHomeDir();if(!home)return;let target=resolve(agentDir);for(let configDir of new Set([...KNOWN_BRAND_CONFIG_DIRS,activeConfigDirName])){let root=join3(home,configDir);if(target===root||target.startsWith(root+sep2))throw new RealAgentDirInTestError(target)}}function getAgentDir(){let agentDir=resolveAgentDir(process.cwd(),homedir2(),envValue("CODING_AGENT_DIR"));return assertAgentDirAllowedInTests(agentDir,CONFIG_DIR_NAME),agentDir}var __filename,__dirname,isBunBinary,isBunRuntime,isBundledNode,nodePackageDir,pkg,piConfigName,BRAND,PACKAGE_NAME,APP_NAME,APP_COMMAND,APP_TITLE,CONFIG_DIR_NAME,CONFIG_FLAT_LAYOUT,VERSION,DISPLAY_VERSION,ENV_PREFIX,ENV_AGENT_DIR,ENV_SESSION_DIR,FLAT_LAYOUT_SENTINEL,KNOWN_BRAND_CONFIG_DIRS,RealAgentDirInTestError,init_config=__esm({"packages/coding-agent/dist/config.js"(){init_bun_global_launcher();init_brand();init_nearest_parent_config();init_marker();init_child_process();init_paths();init_text();__filename=fileURLToPath2(import.meta.url),__dirname=dirname2(__filename),isBunBinary=import.meta.url.includes("$bunfs")||import.meta.url.includes("~BUN")||import.meta.url.includes("%7EBUN"),isBunRuntime=!!process.versions.bun,isBundledNode=!0;pkg={};try{pkg=JSON.parse(stripBom(readFileSync(getPackageJsonPath(),"utf-8")))}catch(e){if(e.code!=="ENOENT")throw e}piConfigName=pkg.piConfig?.name,BRAND=brandProfile(),PACKAGE_NAME=pkg.name||"@earendil-works/pi-coding-agent",APP_NAME=BRAND?.name||piConfigName||"pi",APP_COMMAND=BRAND?.command??APP_NAME,APP_TITLE=BRAND?.name||(piConfigName?APP_NAME:"\u03C0"),CONFIG_DIR_NAME=BRAND?.configDir||pkg.piConfig?.configDir||".pi",CONFIG_FLAT_LAYOUT=BRAND?.flatLayout===!0,VERSION=pkg.version||"0.0.0",DISPLAY_VERSION=BRAND?.displayVersion||VERSION,ENV_PREFIX=BRAND?.envPrefix||APP_NAME.toUpperCase(),ENV_AGENT_DIR=`${ENV_PREFIX}_CODING_AGENT_DIR`,ENV_SESSION_DIR=`${ENV_PREFIX}_CODING_AGENT_SESSION_DIR`,FLAT_LAYOUT_SENTINEL="settings.json";KNOWN_BRAND_CONFIG_DIRS=[".senpi",".omo",".pi"],RealAgentDirInTestError=class extends Error{constructor(agentDir){super(`Refusing to use the real agent directory ${agentDir} from a test run. Point <BRAND>_CODING_AGENT_DIR at a temp dir, or set SENPI_TEST_USE_REAL_AGENT_DIR=1 to opt in.`),this.name="RealAgentDirInTestError",this.agentDir=agentDir}}}});var require_signals=__commonJS({"node_modules/signal-exit/signals.js"(exports,module){module.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"];process.platform!=="win32"&&module.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&module.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")}});var require_signal_exit=__commonJS({"node_modules/signal-exit/index.js"(exports,module){var process2=global.process,processOk=function(process3){return process3&&typeof process3=="object"&&typeof process3.removeListener=="function"&&typeof process3.emit=="function"&&typeof process3.reallyExit=="function"&&typeof process3.listeners=="function"&&typeof process3.kill=="function"&&typeof process3.pid=="number"&&typeof process3.on=="function"};processOk(process2)?(assert=__require("assert"),signals=require_signals(),isWin=/^win/i.test(process2.platform),EE=__require("events"),typeof EE!="function"&&(EE=EE.EventEmitter),process2.__signal_exit_emitter__?emitter=process2.__signal_exit_emitter__:(emitter=process2.__signal_exit_emitter__=new EE,emitter.count=0,emitter.emitted={}),emitter.infinite||(emitter.setMaxListeners(1/0),emitter.infinite=!0),module.exports=function(cb,opts){if(!processOk(global.process))return function(){};assert.equal(typeof cb,"function","a callback must be provided for exit handler"),loaded===!1&&load();var ev="exit";opts&&opts.alwaysLast&&(ev="afterexit");var remove=function(){emitter.removeListener(ev,cb),emitter.listeners("exit").length===0&&emitter.listeners("afterexit").length===0&&unload()};return emitter.on(ev,cb),remove},unload=function(){!loaded||!processOk(global.process)||(loaded=!1,signals.forEach(function(sig){try{process2.removeListener(sig,sigListeners[sig])}catch{}}),process2.emit=originalProcessEmit,process2.reallyExit=originalProcessReallyExit,emitter.count-=1)},module.exports.unload=unload,emit=function(event,code,signal){emitter.emitted[event]||(emitter.emitted[event]=!0,emitter.emit(event,code,signal))},sigListeners={},signals.forEach(function(sig){sigListeners[sig]=function(){if(processOk(global.process)){var listeners=process2.listeners(sig);listeners.length===emitter.count&&(unload(),emit("exit",null,sig),emit("afterexit",null,sig),isWin&&sig==="SIGHUP"&&(sig="SIGINT"),process2.kill(process2.pid,sig))}}}),module.exports.signals=function(){return signals},loaded=!1,load=function(){loaded||!processOk(global.process)||(loaded=!0,emitter.count+=1,signals=signals.filter(function(sig){try{return process2.on(sig,sigListeners[sig]),!0}catch{return!1}}),process2.emit=processEmit,process2.reallyExit=processReallyExit)},module.exports.load=load,originalProcessReallyExit=process2.reallyExit,processReallyExit=function(code){processOk(global.process)&&(process2.exitCode=code||0,emit("exit",process2.exitCode,null),emit("afterexit",process2.exitCode,null),originalProcessReallyExit.call(process2,process2.exitCode))},originalProcessEmit=process2.emit,processEmit=function(ev,arg){if(ev==="exit"&&processOk(global.process)){arg!==void 0&&(process2.exitCode=arg);var ret=originalProcessEmit.apply(this,arguments);return emit("exit",process2.exitCode,null),emit("afterexit",process2.exitCode,null),ret}else return originalProcessEmit.apply(this,arguments)}):module.exports=function(){return function(){}};var assert,signals,isWin,EE,emitter,unload,emit,sigListeners,loaded,load,originalProcessReallyExit,processReallyExit,originalProcessEmit,processEmit}});import{execFile,execFileSync}from"node:child_process";function processStartTimeMs(identity){if(/^\d+$/.test(identity)){let parsed2=Number((BigInt(identity)-WINDOWS_FILETIME_EPOCH)/10000n);return Number.isFinite(parsed2)?parsed2:void 0}let localIdentity=identity.trim(),korean=/^(\d{4})\uB144\s+(\d{1,2})\uC6D4\s+(\d{1,2})\uC77C\s+[\uC6D4\uD654\uC218\uBAA9\uAE08\uD1A0\uC77C]\uC694\uC77C\s+(\d{1,2})\uC2DC\s+(\d{1,2})\uBD84\s+(\d{1,2})\uCD08$/.exec(localIdentity),japanese=/^[\u65E5\u6708\u706B\u6C34\u6728\u91D1\u571F](?:\u66DC\u65E5)?\s+(\d{1,2})\/\s*(\d{1,2})\s+(\d{2}):(\d{2}):(\d{2})\s+(\d{4})$/.exec(localIdentity),parts=korean?korean.slice(1):japanese?[japanese[6],japanese[1],japanese[2],japanese[3],japanese[4],japanese[5]]:void 0;if(parts===void 0){let parsed2=Date.parse(identity);return Number.isFinite(parsed2)?parsed2:void 0}let[year=NaN,month=NaN,day=NaN,hour=NaN,minute=NaN,second=NaN]=parts.map(Number),parsed=new Date(year,month-1,day,hour,minute,second,0);return parsed.getFullYear()===year&&parsed.getMonth()===month-1&&parsed.getDate()===day&&parsed.getHours()===hour&&parsed.getMinutes()===minute&&parsed.getSeconds()===second?parsed.getTime():void 0}function sameProcessStartMs(recorded,observed){return recorded!==void 0&&observed!==void 0&&Number.isFinite(recorded)&&Number.isFinite(observed)&&Math.abs(recorded-observed)<=PROCESS_START_TOLERANCE_MS}function parseDaemonPidFile(text){let parsed;try{parsed=JSON.parse(text)}catch(error){if(error instanceof SyntaxError)return;throw error}let unguarded=parsed!==null&&isRecord(parsed)&&parsed.processStartTime===null;if(!(!isRecord(parsed)||typeof parsed.pid!="number"||!unguarded&&typeof parsed.processStartTime!="string")&&!(!Number.isInteger(parsed.pid)||parsed.pid<=0)){if(unguarded)return{pid:parsed.pid,processStartTime:null};if(!(typeof parsed.processStartTime!="string"||parsed.processStartTime.trim()===""))return{pid:parsed.pid,processStartTime:parsed.processStartTime}}}async function readProcessIdentity(pid,platform=process.platform,timeoutMs,isLive=processIsLive,timeZone){let command=platform==="win32"?{executable:"powershell.exe",args:["-NoProfile","-NonInteractive","-Command",`$process = Get-CimInstance Win32_Process -Filter "ProcessId=${String(pid)}" -ErrorAction Stop; if ($null -eq $process) { Write-Output '__SENPI_ABSENT__'; exit 0 }; $process.CreationDate.ToFileTimeUtc().ToString("D", [Globalization.CultureInfo]::InvariantCulture)`]}:{executable:"ps",args:["-o","stat=,lstart=","-p",String(pid)]};return new Promise(resolve4=>{let effectiveTimeoutMs=timeoutMs??(platform==="win32"?1e3:void 0);execFile(command.executable,command.args,{windowsHide:!0,...effectiveTimeoutMs===void 0?{}:{timeout:effectiveTimeoutMs},...platform==="win32"&&timeZone===void 0?{}:{env:{...process.env,LC_ALL:"C",LANG:"C",...timeZone?{TZ:timeZone}:{}}}},(error,stdout)=>{if(error){let code="code"in error?error.code:void 0;if(platform!=="win32"&&code===1||!isLive(pid)){resolve4({kind:"absent"});return}resolve4({kind:"error",error});return}let snapshot=stdout.trim();if(snapshot==="__SENPI_ABSENT__")return resolve4({kind:"absent"});let state=platform==="win32"?"":snapshot.split(/\s+/,1)[0]??"";if(state.startsWith("Z"))return resolve4({kind:"absent"});let output=platform==="win32"?snapshot:snapshot.slice(state.length).trim();if(!output||platform==="win32"&&!/^\d+$/.test(output))return resolve4({kind:"error",error:new Error("invalid process identity output")});resolve4({kind:"present",identity:timeZone&&platform!=="win32"?`${output} UTC`:output})}).once("error",error=>resolve4({kind:"error",error}))})}async function readProcessStartTime(pid,platform=process.platform,timeoutMs){return readProcessIdentity(pid,platform,timeoutMs).then(result=>{if(result.kind==="error")throw result.error;return result.kind==="present"?result.identity:void 0})}function processIsLive(pid){try{return process.kill(pid,0),!0}catch(error){if(isNodeErrorCode(error,"ESRCH"))return!1;if(isNodeErrorCode(error,"EPERM"))return!0;throw error}}async function waitForStartTime(pid,timeoutMs,readStartTime=readProcessStartTime,isLive=processIsLive){let deadline=Date.now()+timeoutMs;for(;Date.now()<=deadline;){let startTime;try{startTime=await readStartTime(pid)}catch{}if(startTime)return startTime;await delay(20)}if(!isLive(pid))throw new Error(`spawned daemon pid ${pid} had no process start time`)}function delay(ms){return new Promise(resolveDelay=>setTimeout(resolveDelay,ms))}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNodeErrorCode(error,code){return error instanceof Error&&"code"in error&&error.code===code}var WINDOWS_FILETIME_EPOCH,PROCESS_START_TOLERANCE_MS,init_process_identity=__esm({"packages/coding-agent/dist/utils/process-identity.js"(){WINDOWS_FILETIME_EPOCH=116444736000000000n,PROCESS_START_TOLERANCE_MS=3e3}});var HOST_INSTANCE_ID_ENV,init_host_identity_env=__esm({"packages/coding-agent/dist/modes/rpc/host-identity-env.js"(){HOST_INSTANCE_ID_ENV="SENPI_RPC_HOST_INSTANCE_ID"}});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 record2=request;return record2.type==="warm"||record2.type==="authenticate"?!0:record2[OBSERVE_REQUEST_FIELD]===!0&&OBSERVING_COMMANDS.has(record2.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}var OBSERVE_REQUEST_FIELD,ORIGIN_HOST_INSTANCE_FIELD,OBSERVING_COMMANDS,init_host_observe_request=__esm({"packages/coding-agent/dist/modes/rpc/host-observe-request.js"(){init_host_identity_env();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"])}});import{StringDecoder}from"node:string_decoder";function serializeJsonLine(value){return`${JSON.stringify(value)}
|
|
16
16
|
`}function attachJsonlLineReader(stream,onLine,options={}){let decoder=new StringDecoder("utf8"),maxLineLength=options.maxLineLength??Number.POSITIVE_INFINITY;if(!(maxLineLength>0))throw new Error("maxLineLength must be greater than zero.");let buffer="",discardingOversizedLine=!1,consume=text=>{let offset=0;for(;offset<text.length;){if(discardingOversizedLine){let newlineIndex2=text.indexOf(`
|
|
17
17
|
`,offset);if(newlineIndex2===-1)return;discardingOversizedLine=!1,offset=newlineIndex2+1;continue}let newlineIndex=text.indexOf(`
|
|
18
18
|
`,offset);if(newlineIndex===-1){let remainder=text.slice(offset);buffer.length+remainder.length>maxLineLength?(buffer="",discardingOversizedLine=!0,options.onOversizedLine?.()):buffer+=remainder;return}let segment=text.slice(offset,newlineIndex);if(buffer.length+segment.length>maxLineLength)options.onOversizedLine?.();else{let line=buffer+segment;onLine(line.endsWith("\r")?line.slice(0,-1):line)}buffer="",offset=newlineIndex+1}},onData=chunk=>{consume(typeof chunk=="string"?chunk:decoder.write(chunk))},onEnd=()=>{consume(decoder.end()),!discardingOversizedLine&&buffer.length>0&&onLine(buffer.endsWith("\r")?buffer.slice(0,-1):buffer),buffer="",discardingOversizedLine=!1};return stream.on("data",onData),stream.on("end",onEnd),()=>{stream.off("data",onData),stream.off("end",onEnd)}}var MAX_RPC_LINE_CHARACTERS,init_jsonl=__esm({"packages/coding-agent/dist/modes/rpc/jsonl.js"(){MAX_RPC_LINE_CHARACTERS=16*1024*1024}});import{createHmac,timingSafeEqual}from"node:crypto";function rpcAuthProof(key,label,...parts){return createHmac("sha256",key).update([`senpi-rpc-${label}`,...parts].join(`
|
|
@@ -20,7 +20,9 @@ renameSync(temporary, launcher);
|
|
|
20
20
|
`)}},this.agentDir=agentDir,this.endpoint=endpoint,this.recordPath=join10(agentDir,"rpc","keys",this.launchId),this.ready=this.publication.promise,this.ready.catch(()=>{})}async publish(){try{await fs.mkdir(join10(this.agentDir,"rpc"),{recursive:!0,mode:448}),await checkRpcKeyParents(this.agentDir);let keys=join10(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,constants2.O_WRONLY|constants2.O_CREAT|constants2.O_EXCL|constants2.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}))}}}});import{AsyncLocalStorage}from"node:async_hooks";import{randomBytes as randomBytes4}from"node:crypto";import{createConnection as createConnection3}from"node:net";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=createConnection3(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((resolve4,reject2)=>{if(socket.destroyed){setImmediate(()=>reject2(socketError??new Error(`RPC socket closed during authentication: ${path}`)));return}pending={id:request.id,resolve:resolve4,reject:reject2},socket.write(serializeJsonLine(request))}),timer=setTimeout(()=>{reject(new Error(`RPC authentication timed out on ${path}`)),socket.destroy()},timeoutMs);try{let nonce2=randomBytes4(32).toString("hex"),response=await exchange({...first,auth:{client_nonce:nonce2}}),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 record2=await readRpcKeyRecord(root,auth.launch_id);if(socket.destroyed)throw new Error(`RPC authentication timed out on ${path}`);if(record2===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)
|
|
21
21
|
`),response;if(typeof record2.key!="string")throw new RpcEndpointAuthError("unsafe_key_record",root);let key=Buffer.from(record2.key,"hex");if(!rpcProofMatches(rpcAuthProof(key,"server",auth.launch_id,nonce2,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,nonce2)}),response}finally{clearTimeout(timer),detach(),socket.off("error",onError),socket.off("close",onClose)}}var keyRoots,init_rpc_auth_client=__esm({"packages/coding-agent/dist/modes/rpc/rpc-auth-client.js"(){init_config();init_host_observe_request();init_jsonl();init_rpc_auth_proof();init_rpc_public_key();init_socket_transport();keyRoots=new AsyncLocalStorage}});import{basename as basename6}from"node:path";function isTuiControlSocket(socket){return TUI_SOCKET_NAME.test(basename6(socket))}function socketNeedsHandshake(socket,platform=process.platform){return platform==="win32"||isTuiControlSocket(socket)}var TUI_SOCKET_NAME,init_tui_socket=__esm({"packages/coding-agent/dist/modes/rpc/tui-socket.js"(){TUI_SOCKET_NAME=/^t-[0-9a-f]{16}\.sock$/}});var host_socket_request_exports={};__export(host_socket_request_exports,{PROBE_REQUEST_ID:()=>PROBE_REQUEST_ID,connectAndAsk:()=>connectAndAsk,isRecord:()=>isRecord4,readAnswer:()=>readAnswer,requestOnSocket:()=>requestOnSocket});import{createConnection as createConnection4}from"node:net";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??createConnection4(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)}
|
|
22
22
|
`)};socket.on("data",chunk=>{for(buffer+=chunk.toString("utf8");;){let newline=buffer.indexOf(`
|
|
23
|
-
`);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(isRecord4(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(!(!isRecord4(parsed)||parsed.id!==id||parsed.success!==!0))return parsed.data??{}}function isRecord4(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var PROBE_REQUEST_ID,init_host_socket_request=__esm({"packages/coding-agent/dist/modes/rpc/host-socket-request.js"(){init_rpc_auth_client();init_rpc_auth_proof();init_socket_transport();init_tui_socket();PROBE_REQUEST_ID="ensure-host-probe"}});
|
|
23
|
+
`);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(isRecord4(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(!(!isRecord4(parsed)||parsed.id!==id||parsed.success!==!0))return parsed.data??{}}function isRecord4(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var PROBE_REQUEST_ID,init_host_socket_request=__esm({"packages/coding-agent/dist/modes/rpc/host-socket-request.js"(){init_rpc_auth_client();init_rpc_auth_proof();init_socket_transport();init_tui_socket();PROBE_REQUEST_ID="ensure-host-probe"}});var mcp_presenter_bootstrap_exports={};__export(mcp_presenter_bootstrap_exports,{MCP_PRESENTER_BOOTSTRAP_FD:()=>MCP_PRESENTER_BOOTSTRAP_FD,presenterBootstrapStream:()=>presenterBootstrapStream,relayPresenterBootstrap:()=>relayPresenterBootstrap});import{createReadStream,fstatSync as fstatSync2,write}from"node:fs";import{Socket as Socket2}from"node:net";import{Duplex as Duplex2}from"node:stream";function presenterBootstrapStream(fd){if(fd!==MCP_PRESENTER_BOOTSTRAP_FD)return;try{let stat5=fstatSync2(fd);if(!stat5.isSocket()&&!stat5.isFIFO())return}catch{return}let input=createReadStream("",{fd,autoClose:!0}),stream=new Duplex2({read(){input.resume()},write(chunk,_encoding,done){if(chunk.length===0){done();return}let send=offset=>{write(fd,chunk,offset,chunk.length-offset,null,(error,count)=>{error?done(error):count===0?done(new Error("presenter_bootstrap_write_failed")):offset+count===chunk.length?done():send(offset+count)})};send(0)},destroy(error,done){input.closed?done(error):(input.once("close",()=>done(error)),input.destroy())}});return input.on("data",chunk=>{stream.push(chunk)||input.pause()}),input.on("end",()=>stream.push(null)),input.on("error",error=>stream.destroy(error)),stream}function relayPresenterBootstrap(upstream,child){let downstream=child.stdio[MCP_PRESENTER_BOOTSTRAP_FD];return downstream instanceof Socket2?new Promise(resolve4=>{let ended=!1,acknowledging=!1,finish=()=>{ended||(ended=!0,clearTimeout(timer),unreadUp(),unreadDown(),upstream.destroy(),downstream.destroy(),resolve4())},timer=setTimeout(finish,3e4),unreadUp=attachJsonlLineReader(upstream,line=>{downstream.write(`${line}
|
|
24
|
+
`)||finish()},{maxLineLength:16*1024,onOversizedLine:finish}),unreadDown=attachJsonlLineReader(downstream,line=>{try{let record2=JSON.parse(line);acknowledging=typeof record2=="object"&&record2!==null&&"type"in record2&&record2.type==="enrolled",upstream.write(`${line}
|
|
25
|
+
`,()=>{acknowledging&&finish()})}catch{finish()}},{maxLineLength:16*1024,onOversizedLine:finish});upstream.once("error",finish),downstream.once("error",finish),upstream.once("end",finish),downstream.once("end",()=>{acknowledging||finish()}),child.once("exit",finish)}):(upstream.destroy(),Promise.resolve())}var MCP_PRESENTER_BOOTSTRAP_FD,init_mcp_presenter_bootstrap=__esm({"packages/coding-agent/dist/modes/rpc/mcp-presenter-bootstrap.js"(){init_jsonl();MCP_PRESENTER_BOOTSTRAP_FD=4}});init_config();import{randomUUID as randomUUID5}from"node:crypto";import{join as join14}from"node:path";var HostAdmission=class{constructor(info){this.stopped=!1,this.listeners=new Set,this.replies=Promise.resolve(),this.info=info}get stopping(){return this.stopped}protocol(){return{...this.info,lifecycle:this.stopped?"stopping":"ready"}}observe(info){this.info=info}stop(){this.stopped||(this.stopped=!0,this.replies=Promise.all([...this.listeners].map(listener=>listener())).then(()=>{}))}async flush(){let timer;try{await Promise.race([this.replies,new Promise(resolve4=>{timer=setTimeout(resolve4,2e3)})])}finally{clearTimeout(timer)}}onStop(listener){return this.listeners.add(listener),()=>this.listeners.delete(listener)}};function hostStoppingResponse(id,command,admission){return{...typeof id=="string"?{id}:{},type:"response",command,success:!1,error:"host_stopping",errorCode:"host_stopping",errorData:{instanceId:admission.protocol().instanceId}}}var import_signal_exit=__toESM(require_signal_exit(),1);init_config();function crashingRuntimeVersions(){return{...process.versions.bun===void 0?{}:{bunVersion:process.versions.bun},senpiVersion:VERSION,...DISPLAY_VERSION===VERSION?{}:{productVersion:DISPLAY_VERSION}}}import{appendFileSync,mkdirSync,readFileSync as readFileSync2,writeFileSync}from"node:fs";import{join as join4}from"node:path";import{stat}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(resolve4=>setTimeout(resolve4,Math.min(retries.minTimeout,Math.max(1,deadline-Date.now()))));continue}throw error}}}async function rejectLegacyDirectory(lockPath){try{if((await stat(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"}var HOST_CRASH_RECORD_LIMIT=50,CRASH_RECORD_FILE_MODE=384,TERMINAL_RECORD_LOCK_WAIT_MS=500;function hostCrashRecordFile(daemonDir){return join4(daemonDir,"crashes.jsonl")}function recordHostCrash(daemonDir,record2){try{mkdirSync(daemonDir,{recursive:!0,mode:448}),appendFileSync(hostCrashRecordFile(daemonDir),`${JSON.stringify(record2)}
|
|
24
26
|
`,{mode:CRASH_RECORD_FILE_MODE}),pruneHostCrashRecords(daemonDir)}catch{}}async function recordTerminalHostRecord(daemonDir,record2){let release=await acquireRecordLock(daemonDir);try{(!(record2.generation!==void 0&&readHostCrashRecords(daemonDir).some(existing=>existing.kind==="rpc-host"&&existing.generation===record2.generation))||release===void 0)&&recordHostCrash(daemonDir,{...record2,kind:"rpc-host"})}finally{await release?.().catch(()=>{})}}async function acquireRecordLock(daemonDir){try{return mkdirSync(daemonDir,{recursive:!0,mode:448}),await acquireOwnershipSafeLock(join4(daemonDir,"crashes.lock"),{retries:{retries:Math.ceil(TERMINAL_RECORD_LOCK_WAIT_MS/50),minTimeout:20,maxTimeout:50}})}catch{return}}function readHostCrashRecords(daemonDir){let raw;try{raw=readFileSync2(hostCrashRecordFile(daemonDir),"utf8")}catch{return[]}let records=[];for(let line of raw.split(`
|
|
25
27
|
`))if(line.trim()!=="")try{let value=JSON.parse(line);typeof value=="object"&&value!==null&&typeof Reflect.get(value,"at")=="string"&&records.push(value)}catch{}return records}function pruneHostCrashRecords(daemonDir){let records=readHostCrashRecords(daemonDir);if(records.length<=HOST_CRASH_RECORD_LIMIT)return;let kept=records.slice(records.length-HOST_CRASH_RECORD_LIMIT);writeFileSync(hostCrashRecordFile(daemonDir),`${kept.map(r=>JSON.stringify(r)).join(`
|
|
26
28
|
`)}
|
|
@@ -30,10 +32,10 @@ renameSync(temporary, launcher);
|
|
|
30
32
|
`)}){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 rm3(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 record2={...request,at:new Date().toISOString(),nonce:randomUUID2()};await writeJsonAtomic(file,record2)}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=basename5(file);try{watcher=watch(dirname5(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,watch3){await writeJsonAtomic(file,{...watch3,at:new Date().toISOString()})}function ignore(){}function classifyChildExit(code,signal){return code===0&&signal===null?{reason:"rpc host exited on its own idle policy",exitCode:0}:{reason:`rpc host process exited unexpectedly (${code??signal})`,exitCode:1}}async function noteChildExit(context){let now=context.now??Date.now(),intent=await consumeStopIntent(context.generation,now).catch(()=>{}),outcome=describeExit(context,intent);if(outcome===void 0)return;let stall=await recentStall(context.generation,now,STOP_STALL_EVIDENCE_MAX_AGE_MS).catch(()=>{});await recordTerminalHostRecord(context.daemonDir,{at:new Date(now).toISOString(),...context.signal===null?{code:context.code??void 0}:{signal:context.signal},uptimeMs:Math.max(0,now-context.childStartedAt),kind:"rpc-host",generation:context.instanceId,...outcome,...stall?{stall:{driftMs:stall.driftMs,at:stall.at,attributedSessionId:stall.sessionId}}:{},...crashingRuntimeVersions()}).catch(()=>{})}function describeExit(context,intent){return intent!==void 0?{detection:"engine_stop",sender:intent.sender,...intent.chain?{chain:intent.chain}:{},reason:intent.reason,stopIntent:!0}:context.shutdown!==void 0?{detection:"engine_stop",sender:context.shutdown.supervisor,reason:context.shutdown.reason,stopIntent:!1}:classifyChildExit(context.code,context.signal).exitCode===0?void 0:{detection:context.signal===null||SELF_INFLICTED_SIGNALS.has(context.signal)?"supervisor":"external",stopIntent:!1}}var SELF_INFLICTED_SIGNALS=new Set(["SIGSEGV","SIGBUS","SIGABRT","SIGILL","SIGFPE","SIGTRAP","SIGSYS"]);function hostCrashCleanupPaths(targets){let publicEntry=targets.platform==="win32"?[targets.publicSocket]:[];return targets.successor?publicEntry:[targets.generationPidFile,targets.settingsFile,...publicEntry,targets.pointerFile]}import{existsSync as existsSync3,readFileSync as readFileSync3,realpathSync as realpathSync3}from"node:fs";init_config();import{dirname as dirname6,resolve as resolve3}from"node:path";import{fileURLToPath as fileURLToPath3}from"node:url";function isCliModuleEntry(moduleUrl){let entry=process.argv[1];if(!entry)return!1;try{return fileURLToPath3(moduleUrl)===realpathSync3(entry)}catch{return!1}}function resolveCliMainPath(modulePath=fileURLToPath3(import.meta.url),bundled=isBundledNode){let declared=bundled?resolveDeclaredCliEntry(modulePath):void 0;if(declared!==void 0)return declared;let extension=modulePath.endsWith(".ts")?".ts":".js",unbundled=resolve3(dirname6(modulePath),"..","..",`cli-main${extension}`);return existsSync3(unbundled)?unbundled:resolveDeclaredCliEntry(modulePath)??unbundled}function resolveDeclaredCliEntry(modulePath){let dir=dirname6(modulePath);for(let depth=0;depth<8;depth+=1){let manifestPath=resolve3(dir,"package.json");if(existsSync3(manifestPath)){try{let declared=JSON.parse(readFileSync3(manifestPath,"utf8")).bin,candidates=typeof declared=="string"?[declared]:Object.values(declared??{});for(let candidate of candidates){let entry=resolve3(dir,candidate);if(existsSync3(entry))return entry}}catch{}return}let parent=dirname6(dir);if(parent===dir)return;dir=parent}}init_host_identity_env();import{watch as watch2}from"node:fs";import{createConnection,Socket}from"node:net";init_host_observe_request();var MAX_CLASSIFIED_LINE_BYTES=64*1024,NEWLINE=10,ClientOccupancy=class{constructor(onAttach,ownInstance){this.clients=new Set,this.observers=new Set,this.attached=new Set,this.dependents=new Set,this.closed=!1,this.onAttach=onAttach,this.ownInstance=ownInstance}get attachedCount(){return this.attached.size}get unclassifiedCount(){return this.clients.size-this.observers.size-this.attached.size-this.dependents.size}admit(client){if(this.closed)return client.destroy(),!1;this.clients.add(client);let pending=Buffer.alloc(0),attach=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.attached.add(client),this.onAttach()},depend=()=>{client.off("data",classify),pending=Buffer.alloc(0),this.observers.delete(client),this.dependents.add(client)},classify=chunk=>{pending=Buffer.concat([pending,chunk]);for(let newline=pending.indexOf(NEWLINE);newline!==-1;newline=pending.indexOf(NEWLINE)){let line=pending.subarray(0,newline).toString("utf8");if(pending=pending.subarray(newline+1),!isObservingRequest(line)){this.ownInstance!==void 0&&requestOriginHostInstance(line)===this.ownInstance?depend():attach();return}this.observers.add(client)}pending.length>MAX_CLASSIFIED_LINE_BYTES&&attach()};return client.on("data",classify),!0}release(client){let unclassified=this.clients.has(client)&&!this.observers.has(client)&&!this.attached.has(client)&&!this.dependents.has(client);return this.clients.delete(client),this.observers.delete(client),this.attached.delete(client),this.dependents.delete(client),unclassified}destroyAll(){this.closed=!0;for(let client of this.clients)client.destroy()}};init_process_identity();import{readFile as readFile3,writeFile as writeFile2}from"node:fs/promises";import{join as join9}from"node:path";async function readHostOwner(generationDir){let record2=await readJsonObject(join9(generationDir,"owner.json"));if(record2?.owner===null)return null;if(!isRecord3(record2?.owner))return;let{pid,startTime}=record2.owner;return typeof pid=="number"&&Number.isSafeInteger(pid)&&pid>0&&typeof startTime=="string"&&startTime.length>0?{pid,startTime}:void 0}function sameHostOwner(a,b){if(a==null||b==null||a.pid!==b.pid)return!1;let started=processStartTimeMs(a.startTime);return started!==void 0&&started===processStartTimeMs(b.startTime)}async function hostOwnerGone(owner){let observed=await readProcessIdentity(owner.pid,process.platform,1e3,void 0,"UTC");return observed.kind==="absent"||observed.kind==="present"&&processStartTimeMs(observed.identity)!==void 0&&processStartTimeMs(owner.startTime)!==void 0&&!sameProcessStartMs(processStartTimeMs(observed.identity),processStartTimeMs(owner.startTime))}async function readFileOrUndefined(path){try{return await readFile3(path,"utf8")}catch(error){if(isNodeErrorCode2(error,"ENOENT")||isNodeErrorCode2(error,"ENOTDIR"))return;throw error}}function parseJson(text){if(text!==void 0)try{let parsed=JSON.parse(text);return isRecord3(parsed)?parsed:void 0}catch{return}}function isRecord3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNodeErrorCode2(error,code){return error instanceof Error&&"code"in error&&error.code===code}var SessionRunActivity=class{#running=new Set;observe(line){let event=parseHostEvent(line);if(event===void 0)return!1;if(event.type==="agent_start")this.#running.add(event.sessionId);else if(event.type==="agent_settled"||event.type==="session_closed")this.#running.delete(event.sessionId);else return!1;return!0}get busySessions(){return this.#running.size}};function parseHostEvent(line){let event;try{event=JSON.parse(line)}catch{return}if(typeof event!="object"||event===null)return;let{type,sessionId}=event;return typeof sessionId=="string"?{type,sessionId}:void 0}import{randomBytes}from"node:crypto";import{hkdfSync}from"node:crypto";import{Duplex}from"node:stream";import{createCipheriv,createDecipheriv}from"node:crypto";var INTERNAL_RECORD_MAX=64*1024,RECORD_LIMIT=1n<<32n,InternalRecordCipher=class{constructor(key,direction,counter=0n){this.key=key,this.direction=direction,this.counter=counter}parameters(){if(this.counter<0n||this.counter>=RECORD_LIMIT)throw new Error("internal_record_counter_exhausted");let count=Buffer.alloc(8);return count.writeBigUInt64BE(this.counter),{nonce:Buffer.concat([Buffer.alloc(4),count]),aad:Buffer.concat([Buffer.from(this.direction),count])}}seal(plaintext){if(plaintext.length<1||plaintext.length>INTERNAL_RECORD_MAX)throw new Error("internal_record_length");let{nonce:nonce2,aad}=this.parameters(),cipher=createCipheriv("aes-256-gcm",this.key,nonce2);cipher.setAAD(aad);let body=Buffer.concat([cipher.update(plaintext),cipher.final(),cipher.getAuthTag()]),length=Buffer.alloc(4);return length.writeUInt32BE(body.length),this.counter++,Buffer.concat([length,body])}open(body){if(body.length<17||body.length>INTERNAL_RECORD_MAX+16)throw new Error("internal_record_length");let{nonce:nonce2,aad}=this.parameters(),decipher=createDecipheriv("aes-256-gcm",this.key,nonce2);decipher.setAAD(aad),decipher.setAuthTag(body.subarray(-16));let plaintext=decipher.update(body.subarray(0,-16)),final=decipher.final();return this.counter++,Buffer.concat([plaintext,final])}};function createInternalRecordStream(wire,key,clientNonce,serverNonce,role){let salt=Buffer.concat([clientNonce,serverNonce]),cipher=direction=>new InternalRecordCipher(Buffer.from(hkdfSync("sha256",key,salt,`senpi-rpc-internal ${direction}`,32)),direction);return new InternalRecordStream(wire,cipher(role==="client"?"c2s":"s2c"),cipher(role==="client"?"s2c":"c2s"))}var InternalRecordStream=class extends Duplex{constructor(wire,sender,receiver){super(),this.header=Buffer.alloc(4),this.headerUsed=0,this.bodyUsed=0,this.offset=0,this.wireDone=!1,this.wireClosed=!1,this.ended=!1,this.wire=wire,this.sender=sender,this.receiver=receiver,this.once("error",error=>{error.message.startsWith("internal_record")&&process.stderr.write(`senpi rpc: internal hop closed: ${error.message}
|
|
31
33
|
`)}),this.on("error",()=>{}),wire.on("data",chunk=>{wire.pause(),this.pending=chunk,this.offset=0,this.consume()}),wire.once("end",()=>{this.wireDone=!0,this.pending===void 0&&this.finish()}),wire.once("error",error=>this.destroy(error)),wire.once("close",()=>{this.wireDone=!0,this.wireClosed=!0,this.ended&&this.readableEnded?this.destroy():this.pending===void 0&&this.finish()}),this.once("end",()=>{this.wireClosed&&this.destroy()})}finish(){this.ended||(this.ended=!0,this.headerUsed!==0||this.body!==void 0?this.destroy(new Error("internal_record_truncated")):this.push(null))}consume(){try{let chunk=this.pending;if(!chunk)return;for(;this.offset<chunk.length;){if(!this.body){let n2=Math.min(4-this.headerUsed,chunk.length-this.offset);if(chunk.copy(this.header,this.headerUsed,this.offset,this.offset+n2),this.headerUsed+=n2,this.offset+=n2,this.headerUsed!==4)break;let length=this.header.readUInt32BE();if(length<17||length>INTERNAL_RECORD_MAX+16)throw new Error("internal_record_length");this.headerUsed=0,this.body=Buffer.alloc(length)}let n=Math.min(this.body.length-this.bodyUsed,chunk.length-this.offset);if(chunk.copy(this.body,this.bodyUsed,this.offset,this.offset+n),this.bodyUsed+=n,this.offset+=n,this.bodyUsed===this.body.length){let plaintext=this.receiver.open(this.body);if(this.body=void 0,this.bodyUsed=0,!this.push(plaintext)){this.offset===chunk.length&&(this.pending=void 0,this.wireDone&&this.finish());return}}}this.pending=void 0,this.wireDone?this.finish():this.wire.resume()}catch(cause){this.destroy(cause instanceof Error&&cause.message.startsWith("internal_record")?cause:new Error("internal_record_unverified",{cause}))}}_read(){this.pending?this.consume():this.wire.resume()}_write(chunk,_encoding,callback){let offset=0,next=error=>{if(error){callback(error);return}if(this.destroyed){callback(new Error("internal_hop_lost"));return}if(offset===chunk.length){callback();return}try{let end=Math.min(chunk.length,offset+INTERNAL_RECORD_MAX),record2=this.sender.seal(chunk.subarray(offset,end));offset=end,this.wire.write(record2,next)}catch(cause){callback(cause instanceof Error?cause:new Error("internal_record_invalid"))}};next()}_final(callback){this.wire.end(callback)}_destroy(error,callback){this.wire.destroy(),callback(error)}};init_jsonl();init_rpc_auth_proof();var INTERNAL_LAUNCH_ID="internal";function proof(key,label,first,second){return rpcAuthProof(key,label,INTERNAL_LAUNCH_ID,first,second)}function matches(actual,expected){return rpcProofMatches(expected,actual)}function object(value){if(!isObject(value))throw new Error("auth_failed");return value}function isObject(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function nonce(value){if(typeof value!="string"||!RPC_AUTH_HEX.test(value))throw new Error("auth_failed");return value}async function handshake(socket,budget,run){let readBytes=0,ended=!1,rejectPending,fail=error=>{ended=!0,rejectPending?.(error),socket.destroy()},timer=budget.timeoutMs===void 0?void 0:setTimeout(()=>fail(new Error("internal_auth_timeout")),budget.timeoutMs);timer?.unref();let onError=error=>fail(error),onClose=()=>fail(new Error("internal_hop_lost"));socket.on("error",onError),socket.once("close",onClose);let read=()=>new Promise((resolve4,reject)=>{if(ended)return reject(new Error("internal_hop_lost"));let buffer=Buffer.alloc(0);rejectPending=cause=>{socket.off("data",data),reject(cause)};let data=chunk=>{let newline=chunk.indexOf(10),used=newline===-1?chunk.length:newline+1;if(readBytes+=used,readBytes>budget.maxBytes)return fail(new Error("internal_auth_oversized"));if(buffer=Buffer.concat([buffer,chunk.subarray(0,used)]),newline!==-1){socket.pause(),socket.off("data",data),rejectPending=void 0,used<chunk.length&&socket.unshift(chunk.subarray(used));try{resolve4(object(JSON.parse(buffer.toString("utf8"))))}catch{reject(new Error("auth_failed"))}}};socket.on("data",data),socket.resume()});try{return await run(read,frame=>new Promise((resolve4,reject)=>{socket.write(`${JSON.stringify(frame)}
|
|
32
34
|
`,error=>error?reject(error):resolve4())}))}catch(cause){throw socket.destroy(),cause}finally{timer&&clearTimeout(timer),socket.off("error",onError),socket.off("close",onClose)}}function connectInternalConnection(socket,key,options={}){return handshake(socket,{maxBytes:MAX_RPC_LINE_CHARACTERS,timeoutMs:options.timeoutMs},async(read,send)=>{let clientNonce=randomBytes(32).toString("hex"),[response]=await Promise.all([read(),send({id:"internal-protocol",type:"get_protocol_info",observe:!0,auth:{client_nonce:clientNonce}})]),data=response.data;if(!isObject(data)||!isObject(data.auth))throw new Error("host_identity_unproven");let auth=data.auth,serverNonce=nonce(auth.server_nonce);if(response.id!=="internal-protocol"||response.success!==!0||auth.launch_id!==INTERNAL_LAUNCH_ID||!matches(auth.server_proof,proof(key,"server",clientNonce,serverNonce)))throw new Error("host_identity_unproven");let[result]=await Promise.all([read(),send({id:"internal-auth",type:"authenticate",client_proof:proof(key,"client",serverNonce,clientNonce)})]);if(result.id!=="internal-auth"||result.command!=="authenticate"||result.success!==!0)throw new Error("auth_failed");return createInternalRecordStream(socket,key,Buffer.from(clientNonce,"hex"),Buffer.from(serverNonce,"hex"),"client")})}init_jsonl();function activeTurnsForIdleDecision(input){return input.healthy?input.observedBusy:input.unhealthySince===void 0||input.now-input.unhealthySince<input.unknownGraceMs?1:0}function createObserverLink(options){let current,healthy=!1,unhealthySince,retry,armRetry=()=>{retry!==void 0||options.settled()||(retry=options.setTimer(()=>{retry=void 0,open2().catch(armRetry)},options.retryDelayMs))};async function open2(){let socket=await options.open();current=socket,healthy=!0,unhealthySince=void 0,socket.onLost(()=>{current!==socket||options.settled()||(healthy=!1,unhealthySince??=options.now(),current=void 0,armRetry())})}return{open:open2,healthy:()=>healthy,unhealthySince:()=>unhealthySince,stop:()=>{retry?.cancel(),retry=void 0,current=void 0}}}init_socket_transport();var INTERNAL_OBSERVER_HANDSHAKE_MS=5e3,SupervisorActivity=class{constructor(options){this.runs=new SessionRunActivity,this.options=options,this.decider=new IdleExitDecider(options.idleExitMs),this.clients=new ClientOccupancy(()=>this.refresh(),options.instanceId),this.observerLink=createObserverLink({open:()=>this.connectObserver(),settled:options.settled,retryDelayMs:250,now:Date.now,setTimer:(run,ms)=>{let timer=setTimeout(run,ms);return timer.unref?.(),{cancel:()=>clearTimeout(timer)}}})}current(){return{connections:this.clients.attachedCount,activeTurns:activeTurnsForIdleDecision({healthy:this.observerLink.healthy(),unhealthySince:this.observerLink.unhealthySince(),now:Date.now(),unknownGraceMs:this.decider.idleExitMs,observedBusy:this.runs.busySessions})}}refresh(){let current=this.current();return(current.connections>0||current.activeTurns>0||this.clients.unclassifiedCount>0)&&this.options.onActivity?.(),this.decider.update(current)}quiescent(){return this.observerLink.healthy()&&this.runs.busySessions===0&&this.clients.attachedCount===0&&this.clients.unclassifiedCount===0}openObserver(){return this.observerLink.open()}stopObserver(){this.observerLink.stop(),this.observerSocket?.destroy()}async connectObserver(){let secret=this.options.internalSecret,next=createConnection(resolveSocketTransportAddress(this.options.internalSocket,process.platform,secret));secret&&sendSocketHandshake(next,secret);let stream;try{this.options.internalKey?stream=await connectInternalConnection(next,this.options.internalKey,{timeoutMs:INTERNAL_OBSERVER_HANDSHAKE_MS}):(await waitForConnect(next,5e3),stream=next)}catch(cause){throw next.destroy(),cause}return this.observerSocket=stream,attachJsonlLineReader(stream,line=>this.observeHostEvent(line),{maxLineLength:MAX_RPC_LINE_CHARACTERS}),{onLost:handler=>{let lost=()=>{handler(),this.options.onActivity?.()};stream.once("close",lost),stream.once("error",lost)}}}observeHostEvent(line){this.runs.observe(line)&&this.refresh()}},OWNER_EXIT_GRACE_MS=2e3,OWNER_PROBE_MAX_INTERVAL_MS=5e3,SupervisorOwner=class{constructor(generationDir){this.watchFailed=!1,this.nextProbeAt=0,this.probeIntervalMs=1e3,this.gone=!1,this.revision=0,this.stopped=!1,this.idle=new IdleExitDecider(OWNER_EXIT_GRACE_MS,()=>performance.now()),this.generationDir=generationDir}async start(fd){if(await this.reload(),!(fd===void 0||this.owner==null))try{let pipe=new Socket({fd,readable:!0,writable:!1});this.pipe=pipe;let bound=this.owner,failed=!1,eof=()=>{!failed&&!this.stopped&&sameHostOwner(this.owner,bound)&&(this.gone=!0)};pipe.once("end",eof),process.platform==="win32"&&pipe.once("close",eof),pipe.once("error",()=>{failed=!0,this.pipe===pipe&&(this.pipe=void 0),pipe.destroy()}),pipe.resume()}catch{this.pipe=void 0}}async reload(){let revision=++this.revision,next=await readHostOwner(this.generationDir);if(!(this.stopped||revision!==this.revision)){if(sameHostOwner(this.owner,next)||(this.pipe?.destroy(),this.pipe=void 0,this.gone=!1,this.nextProbeAt=0,this.probeIntervalMs=1e3,this.activity()),this.owner=next,next==null)this.watcher?.close(),this.watcher=void 0;else if(!this.watcher&&!this.watchFailed)try{this.watcher=watch2(this.generationDir,(_event,filename)=>{filename?.toString()==="owner.json"&&this.reload()}),this.watcher.once("error",()=>{this.watchFailed=!0,this.watcher?.close(),this.watcher=void 0})}catch{this.watchFailed=!0}}}activity(){this.idle.update({connections:1,activeTurns:0})}async shouldExit(activity){this.watcher||await this.reload();let owner=this.owner,revision=this.revision;if(owner!=null&&!this.pipe&&!this.gone&&performance.now()>=this.nextProbeAt){let gone=await hostOwnerGone(owner);if(this.stopped||revision!==this.revision)return!1;this.gone=gone,this.nextProbeAt=performance.now()+this.probeIntervalMs,this.probeIntervalMs=Math.min(OWNER_PROBE_MAX_INTERVAL_MS,this.probeIntervalMs*2)}let quiet=this.gone&&owner!=null&&activity.quiescent();if(this.idle.update({connections:quiet?0:1,activeTurns:0})!=="exit")return!1;let current=await readHostOwner(this.generationDir);return!this.stopped&&revision===this.revision&&sameHostOwner(owner,current)&&activity.quiescent()}stop(){this.stopped=!0,this.watcher?.close(),this.pipe?.destroy()}};function waitForConnect(socket,timeoutMs){return new Promise((resolve4,reject)=>{let timer=setTimeout(()=>{cleanup(),reject(new Error(`observer connection to internal host timed out after ${timeoutMs}ms`))},timeoutMs),onConnect=()=>{cleanup(),resolve4()},onError=cause=>{cleanup(),reject(cause)},cleanup=()=>{clearTimeout(timer),socket.off("connect",onConnect),socket.off("error",onError)};socket.once("connect",onConnect),socket.once("error",onError)})}init_process_identity();init_host_observe_request();import{readFile as readFile6}from"node:fs/promises";init_socket_transport();import{execFile as execFile2}from"node:child_process";import{mkdir as mkdir2,readFile as readFile5,rename as rename2,stat as stat3,unlink,writeFile as writeFile4}from"node:fs/promises";import{createConnection as createConnection2}from"node:net";import{dirname as dirname8}from"node:path";var PUBLIC_SOCKET_IDENTITY_FILE="public-socket.owner";var MAX_SOCKET_PATH_BYTES=103;function sameSocketIdentity(a,b){return a.dev===b.dev&&a.ino===b.ino}function classifyConnectError(code,platform){return code==="ENOENT"?"gone":code==="ECONNREFUSED"?platform==="linux"?"dead":"confirm-holder":"live"}var HOLDER_PROBE_TIMEOUT_MS=5e3,lsofSocketHolders=socketPath=>new Promise(resolve4=>{execFile2("lsof",["-t","--",socketPath],{timeout:HOLDER_PROBE_TIMEOUT_MS},(error,stdout)=>{let pids=String(stdout).split(/\s+/).filter(part=>/^\d+$/.test(part)).map(Number);if(pids.length>0)return resolve4(pids);let exitCode=error===null?void 0:Reflect.get(error,"code");resolve4(error===null||exitCode===1?[]:void 0)})}),CONNECT_PROBE_TIMEOUT_MS=2e3;function connectOnce(socketPath){return new Promise(resolve4=>{let socket=createConnection2(resolveSocketTransportAddress(socketPath,process.platform)),settle=value=>{socket.destroy(),resolve4(value)};socket.setTimeout(CONNECT_PROBE_TIMEOUT_MS,()=>settle({code:"timeout"})),socket.once("connect",()=>settle({connected:!0})),socket.once("error",cause=>settle({code:cause.code}))})}async function socketEntryListenerState(socketPath,platform=process.platform,holders=lsofSocketHolders){let attempt=await connectOnce(socketPath);if("connected"in attempt)return{verdict:"live",evidence:"accepting connections"};let verdict=classifyConnectError(attempt.code,platform);if(verdict!=="confirm-holder")return{verdict,evidence:`connect ${attempt.code??"failed"}`};let pids=await holders(socketPath);return pids===void 0?{verdict:"live",evidence:"connect ECONNREFUSED, holders unknown"}:pids.length>0?{verdict:"live",evidence:`connect ECONNREFUSED, held open by pid ${pids.join(",")}`}:{verdict:"dead",evidence:"connect ECONNREFUSED, held by nobody"}}async function statSocketIdentity(socketPath){try{let{dev,ino}=await stat3(socketPath);return{dev,ino}}catch(cause){if(isNodeErrorCode4(cause,"ENOENT"))return;throw cause}}async function classifyEndpointOwnership(socketPath,identity){if(identity===void 0||process.platform==="win32"||socketPath.startsWith("\0"))return"unknown";let current;try{current=await statSocketIdentity(socketPath)}catch{return"unknown"}return current===void 0?"absent":sameSocketIdentity(current,identity)?"held":"replaced"}async function writeSocketIdentityFile(path,identity){await mkdir2(dirname8(path),{recursive:!0,mode:448});let tmpPath=`${path}.${process.pid}.tmp`;await writeFile4(tmpPath,`${JSON.stringify(identity)}
|
|
33
|
-
`,{mode:384}),await rename2(tmpPath,path)}async function unlinkOwnedSocket(socketPath,identity,log){if(process.platform==="win32"||socketPath.startsWith("\0"))return;let current;try{current=await statSocketIdentity(socketPath)}catch(cause){log(`socket ${socketPath} ownership could not be verified (${errorMessage2(cause)}); leaving it`);return}if(current!==void 0){if(identity===void 0){log(`socket path ${socketPath} ownership unknown; leaving it`);return}if(!sameSocketIdentity(current,identity)){log(`socket path ${socketPath} now owned by another host; leaving it`);return}try{await unlink(socketPath)}catch(cause){isNodeErrorCode4(cause,"ENOENT")||log(`socket ${socketPath} removal failed (${errorMessage2(cause)})`)}}}async function shieldSocketDuringClose(socketPath,close){if(process.platform==="win32"||socketPath.startsWith("\0"))return close();let shieldPath=`${socketPath}.shield-${process.pid}`,shielded=!1;try{await statSocketIdentity(socketPath)!==void 0&&(await rename2(socketPath,shieldPath),shielded=!0)}catch{}try{await close()}finally{if(shielded)try{await rename2(shieldPath,socketPath)}catch{}}}function errorMessage2(cause){return cause instanceof Error?cause.message:String(cause)}function isNodeErrorCode4(cause,code){return cause instanceof Error&&"code"in cause&&cause.code===code}async function adoptPublicSocket(bindSocket,publicSocket,expected){if(expected===void 0)throw new Error(`${publicSocket}: a generation launch must name the entry it replaces`);let current=await statSocketIdentity(publicSocket);if(current===void 0||current.dev!==expected.dev||current.ino!==expected.ino)throw new Error(`${publicSocket}: owned by another socket entry now; refusing to replace it`);await rename2(bindSocket,publicSocket)}var SUPERSESSION_POLL_MS=1e3,ABSENT_CONFIRMATIONS=3,REPLACED_CONFIRMATIONS=3,IDENTITY_PROBE_TIMEOUT_MS=2e3;function watchForSupersession(endpoint,onLost){if(endpoint.identity===void 0)return endpoint.pointer===void 0?()=>{}:watchPointerSupersession(endpoint,endpoint.pointer,onLost);let absentPolls=0,lost=!1,lose=loss=>{lost||(lost=!0,stop(),onLost(loss))},timer=setInterval(()=>{endpoint.settled?.()!==!0&&classifyEndpointOwnership(endpoint.path,endpoint.identity).then(ownership=>{if(endpoint.settled?.()!==!0)switch(ownership){case"replaced":lose("replaced");return;case"absent":if(absentPolls+=1,absentPolls<ABSENT_CONFIRMATIONS)return;lose("absent");return;case"held":case"unknown":absentPolls=0;return}},ignore2)},SUPERSESSION_POLL_MS);timer.unref?.();let stop=()=>clearInterval(timer);return stop}function watchPointerSupersession(endpoint,pointer,onLost){let probe=endpoint.probeInstanceId??probeAnsweringInstance,readPointer=endpoint.readPointerInstanceId??pointerInstanceId,agreeingPolls=0,observing=!1,lost=!1,observe=async()=>{let named=await readPointer(pointer.file);return named===void 0||named===pointer.instanceId?!1:await probe(endpoint.path)===named},timer=setInterval(()=>{lost||observing||endpoint.settled?.()===!0||(observing=!0,observe().then(replaced=>{lost||endpoint.settled?.()===!0||(agreeingPolls=replaced?agreeingPolls+1:0,!(agreeingPolls<REPLACED_CONFIRMATIONS)&&(lost=!0,clearInterval(timer),onLost("replaced")))},()=>{agreeingPolls=0}).finally(()=>{observing=!1}))},SUPERSESSION_POLL_MS);return timer.unref?.(),()=>clearInterval(timer)}async function pointerInstanceId(file){try{let parsed=JSON.parse(await readFile6(file,"utf8")),instanceId=typeof parsed=="object"&&parsed!==null?Reflect.get(parsed,"instance_id"):void 0;return typeof instanceId=="string"&&instanceId!==""?instanceId:void 0}catch{return}}async function probeAnsweringInstance(path){let{isRecord:isRecord6,requestOnSocket:requestOnSocket2}=await Promise.resolve().then(()=>(init_host_socket_request(),host_socket_request_exports)),answer=await requestOnSocket2(path,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},IDENTITY_PROBE_TIMEOUT_MS).catch(()=>{});return isRecord6(answer)&&typeof answer.instanceId=="string"?answer.instanceId:void 0}function ignore2(){}var SupervisorDrain=class{constructor(child,shuttingDown,beginStopping=()=>{},relay){this.draining=!1,this.child=child,this.shuttingDown=shuttingDown,this.beginStopping=beginStopping,this.relay=relay}get active(){return this.draining}drain(){if(this.draining||this.shuttingDown())return;this.draining=!0,this.beginStopping(),supervisorLog("draining into the next generation");let graceMs=parseIdleExitMs(process.env[HANDOFF_GRACE_MS_ENV])??6e5;this.graceTimer=setTimeout(()=>{supervisorLog(JSON.stringify({event:"handoff_grace_expired",graceMs})),this.requestChildDrain()},graceMs),this.graceTimer.unref(),this.requestChildDrain()}stop(){this.graceTimer&&clearTimeout(this.graceTimer)}async acceptRequests(generation){let stop=watchDrainRequest(generation.drainRequestFile,request=>{supervisorLog(`drain requested (${request.reason})`),this.drain()});return await writeDrainWatch(generation.drainWatchFile,{pid:process.pid}).catch(cause=>{supervisorLog(`cannot advertise the drain request: ${errorMessage(cause)}`)}),stop}requestChildDrain(){let{child,relay}=this;if(!(child.pid===void 0||child.exitCode!==null||child.signalCode!==null)&&(relay&&writeDrainRequest(relay.file,{sender:relay.sender,reason:"supervisor_drain"}).catch(cause=>{supervisorLog(`could not relay the drain to the host: ${errorMessage(cause)}`)}),process.platform!=="win32"))try{process.kill(child.pid,"SIGUSR1")}catch(cause){supervisorLog(`could not ask the host to drain: ${errorMessage(cause)}`)}}};function drainOnPublicSocketLoss(path,identity,settled,drain,onReplaced,pointer){return watchForSupersession({path,identity,settled,...pointer&&{pointer}},loss=>{loss==="replaced"&&onReplaced(),supervisorLog(loss==="absent"?"the public socket entry is gone; nothing can reach this generation; draining":"another generation owns the public socket; draining this one"),drain.drain()})}async function watchWin32ChildIdentity(child,shuttingDown,onGone){let pid=child.pid;if(pid===void 0)return()=>{};let childStartTime=await readProcessStartTime(pid,process.platform,1e3).catch(()=>{}),missingIdentityChecks=0,checking=!1,timer=setInterval(()=>{shuttingDown()||checking||child.exitCode!==null||child.signalCode!==null||(checking=!0,readProcessStartTime(pid,process.platform,1e3).then(currentStartTime=>{currentStartTime===void 0&&!processIsLive(pid)?missingIdentityChecks++:currentStartTime!==void 0&&(missingIdentityChecks=0),(childStartTime!==void 0&¤tStartTime!==void 0&¤tStartTime!==childStartTime||missingIdentityChecks>=2)&&onGone()}).catch(()=>{}).finally(()=>{checking=!1}))},500);return timer.unref?.(),()=>clearInterval(timer)}import{randomBytes as randomBytes5}from"node:crypto";import{readFile as readFile8}from"node:fs/promises";import{join as join13}from"node:path";init_process_identity();import{readFileSync as readFileSync4}from"node:fs";function readProcessStartTicks(pid,platform=process.platform){if(platform==="linux")try{let stat5=readFileSync4(`/proc/${pid}/stat`,"utf8"),ticks=stat5.slice(stat5.lastIndexOf(")")+2).split(" ")[19];return ticks!==void 0&&/^\d+$/.test(ticks)?ticks:void 0}catch{return}}init_process_identity();import{randomUUID as randomUUID4}from"node:crypto";import{realpathSync as realpathSync4}from"node:fs";import{mkdir as mkdir4,readFile as readFile7,writeFile as writeFile5}from"node:fs/promises";import{tmpdir}from"node:os";import{join as join11}from"node:path";var INTERNAL_HOST_DIR_PREFIX="senpi-rpc-host-internal-",SHORT_TEMP_ROOT="/tmp";function internalHostDirRoots(){let primary=tmpdir();return canonicalPath(primary)!==canonicalPath(SHORT_TEMP_ROOT)?[primary,SHORT_TEMP_ROOT]:[Buffer.byteLength(primary)<Buffer.byteLength(SHORT_TEMP_ROOT)?primary:SHORT_TEMP_ROOT]}function canonicalPath(path){try{return realpathSync4(path)}catch{return path}}function internalHostDirRoot(name){for(let root of internalHostDirRoots())if(Buffer.byteLength(join11(root,name,"host.sock"))<=MAX_SOCKET_PATH_BYTES)return root;let tried=internalHostDirRoots().map(root=>join11(root,name,"host.sock"));throw new Error(`internal_socket_path_too_long: every candidate exceeds ${MAX_SOCKET_PATH_BYTES} bytes (${tried.join(", ")}); set TMPDIR to a shorter directory`)}async function createInternalSocketPath(baseDir=tmpdir(),platform=process.platform){if(platform==="win32"){let dir2=join11(baseDir,`internal-${randomUUID4()}`);return await mkdir4(dir2,{recursive:!0,mode:448}),{socket:`\\\\.\\pipe\\senpi-rpc-internal-${randomUUID4()}`,dir:dir2,secretPath:join11(dir2,"secret")}}let name=`${INTERNAL_HOST_DIR_PREFIX}${randomUUID4().slice(0,8)}`,dir=join11(internalHostDirRoot(name),name);return await mkdir4(dir,{recursive:!1,mode:448}),await writeFile5(join11(dir,".owner"),JSON.stringify({pid:process.pid,processStartTime:await readProcessStartTime(process.pid),createdAt:Date.now()}),{mode:384}),{socket:join11(dir,"host.sock"),dir,secretPath:join11(dir,".secret")}}var CHILD_START_TIME_WAIT_MS=1e4,CHILD_START_TIME_UNHURRIED_MS=15e3;async function readChildStartTime(pid,timeoutMs){let identity=await readProcessIdentity(pid,process.platform,timeoutMs,void 0,"UTC");if(identity.kind==="error")throw identity.error;return identity.kind==="present"?identity.identity:void 0}async function recordChildPid(file,pid,running){try{await writeJsonAtomic(file,{pid,processStartTime:null});let processStartTime=await waitForStartTime(pid,CHILD_START_TIME_WAIT_MS,p=>readChildStartTime(p,1e3)).catch(()=>{})??await readChildStartTime(pid,CHILD_START_TIME_UNHURRIED_MS).catch(()=>{});if(processStartTime===void 0){supervisorLog(`host child pid ${pid} start time unreadable at recording`);return}if(!running())return;await writeJsonAtomic(file,{pid,processStartTime})}catch(cause){supervisorLog(`could not record the host child pid: ${errorMessage(cause)}`)}}async function readSettingsFile(settingsFile){try{return JSON.parse(await readFile7(settingsFile,"utf8"))}catch{return}}import{execFileSync as execFileSync2}from"node:child_process";import{closeSync,constants as constants3,fstatSync,openSync,rmSync}from"node:fs";import{join as join12}from"node:path";var HOST_WATCH_LIFETIME_FIFO_ENV="SENPI_RPC_HOST_LIFETIME_FIFO";function prepareLifetimeBinding(hopDir,platform=process.platform){if(platform!=="linux")return{};let path=join12(hopDir,"lifetime.fifo");try{return rmSync(path,{force:!0}),execFileSync2("mkfifo",["-m","600",path],{stdio:"ignore"}),openSync(path,constants3.O_RDWR),{lifetimeFifo:path}}catch{return{}}}init_socket_transport();async function recordedOwnerStartTime(dir){if(dir!==void 0)try{let owner=JSON.parse(await readFile8(join13(dir,".owner"),"utf8")),start=owner!==null&&typeof owner=="object"?Reflect.get(owner,"processStartTime"):void 0;return typeof start=="string"?start:void 0}catch{return}}async function prepareInternalHop(daemonDir){let created=await createInternalSocketPath(daemonDir),internal={...created,secretPath:created.secretPath??socketSecretPath(created.socket)},internalSecret=process.platform==="win32"?await createSocketSecret(internal.secretPath):void 0,internalKey=process.platform==="win32"?void 0:randomBytes5(32);return{internal,internalSocket:internal.socket,internalSecret,internalKey,...internalKey&&internal.dir!==void 0?prepareLifetimeBinding(internal.dir):{},supervisorStart:internalKey?{time:await recordedOwnerStartTime(internal.dir),ticks:readProcessStartTicks(process.pid)}:void 0,transport:{...internalSecret?{internalSecret}:{},...internalKey?{internalKey}:{}}}}import{spawn}from"node:child_process";init_config();import{extname}from"node:path";function runtimeExecArgv(execArgv=process.execArgv,bun=process.versions.bun!==void 0){let args=[];for(let index=0;index<execArgv.length;index++){let arg=execArgv[index];if(bun){if(arg==="-e"||arg==="--eval"||arg==="-p"||arg==="--print"||arg==="-pe"){index++;continue}if(arg.startsWith("-e")||arg.startsWith("-p"))continue}if(arg==="-e"||arg==="--eval"||arg==="-pe"||arg==="--input-type"||arg==="--input_type"){index++;continue}if(arg==="-p"||arg==="--print"){execArgv[index+1]!==void 0&&!execArgv[index+1].startsWith("-")&&index++;continue}arg==="-i"||arg==="--interactive"||arg.startsWith("--interactive=")||arg.startsWith("--eval=")||arg.startsWith("--print=")||arg.startsWith("--input-type=")||arg.startsWith("--input_type=")||args.push(arg)}return args}init_host_identity_env();init_brand();init_host_identity_env();init_process_identity();var HOST_WATCH_FD_ENV="SENPI_RPC_HOST_WATCH_FD",HOST_SCRATCH_DIR_ENV="SENPI_RPC_HOST_SCRATCH_DIR",HOST_PUBLIC_SOCKET_ENV="SENPI_RPC_HOST_PUBLIC_SOCKET",HOST_WATCH_PPID_ENV="SENPI_RPC_HOST_WATCH_PPID",HOST_WATCH_PSTART_ENV="SENPI_RPC_HOST_WATCH_PSTART",HOST_WATCH_PSTART_TICKS_ENV="SENPI_RPC_HOST_WATCH_PSTART_TICKS",HOST_CLEANUP_PATHS_ENV="SENPI_RPC_HOST_CLEANUP_PATHS";init_socket_transport();var INTERNAL_SUPERVISOR_FLAG="--internal-rpc-host-supervisor",INJECTABLE_PREFIX_FLAGS=new Set(["--extension"]);function findInternalSupervisorArgs(argv){for(let index=0;index<argv.length;index++){let arg=argv[index];if(arg===INTERNAL_SUPERVISOR_FLAG)return argv.slice(index+1);if(!INJECTABLE_PREFIX_FLAGS.has(arg)||index+1>=argv.length)return;index++}}function parseSupervisorArgs(argv){let hostArgs=[],socket,childCommand,childArgs,agentDir,ownerFd,bindSocket,replaceIdentity;for(let index=0;index<argv.length;index++){let arg=argv[index];if(arg==="--owner-fd"&&index+1<argv.length){if(ownerFd=Number(argv[++index]),!Number.isSafeInteger(ownerFd)||ownerFd<3)return;continue}if(arg==="--socket"&&index+1<argv.length){socket=argv[++index];continue}if(arg==="--child-command"&&index+1<argv.length){childCommand=argv[++index];continue}if(arg==="--child-args"&&index+1<argv.length){try{let parsed=JSON.parse(argv[++index]);Array.isArray(parsed)&&parsed.every(value=>typeof value=="string")&&(childArgs=parsed)}catch{return}continue}if(arg==="--agent-dir"&&index+1<argv.length){agentDir=argv[++index];continue}if(arg==="--bind"&&index+1<argv.length){bindSocket=argv[++index];continue}if(arg==="--replace"&&index+1<argv.length){replaceIdentity=parseSocketIdentity(argv[++index]);continue}hostArgs.push(arg)}return socket===void 0?void 0:{socket,hostArgs,childCommand,childArgs,agentDir,ownerFd,bindSocket,replaceIdentity}}function parseSocketIdentity(value){let match=/^(\d+):(\d+)$/.exec(value);return match?{dev:Number(match[1]),ino:Number(match[2])}:void 0}function resolveHostChildLaunch(launch,internalSocket,compiled=isBunBinary){return launch.childCommand?{command:launch.childCommand,args:[...launch.childArgs??[],"--listen",`unix://${internalSocket}`]}:{command:process.execPath,args:[...compiled?[]:[...runtimeExecArgv(),resolveCliMainPath()],"--mode","rpc","--multi-session","--listen",`unix://${internalSocket}`,...launch.hostArgs]}}function quoteWindowsShellArg(value){return`"${value.replace(/(\\*)"/g,'$1$1\\"').replace(/(\\*)$/,"$1$1").replace(/([()%!^"<>&|;,])/g,"^$1")}"`}function spawnableChildLaunch(launch,platform=process.platform){let extension=extname(launch.command).toLowerCase();return platform!=="win32"||extension!==".cmd"&&extension!==".bat"?{...launch,shell:!1}:{command:quoteWindowsShellArg(launch.command),args:launch.args.map(quoteWindowsShellArg),shell:!0}}var HOST_CHILD_WATCH_FD=3;function spawnHostChild(options){let{launch,internalSocket,internal,internalSecret,publicSocket}=options,childLaunch=spawnableChildLaunch(resolveHostChildLaunch(launch,internalSocket)),child=spawn(childLaunch.command,childLaunch.args,{env:{...process.env,...launch.agentDir?{SENPI_CODING_AGENT_DIR:launch.agentDir}:{},[HOST_DAEMON_DIR_ENV]:options.daemonDir,[HOST_INSTANCE_ID_ENV]:options.instanceId,[HOST_WATCH_FD_ENV]:String(HOST_CHILD_WATCH_FD),[HOST_WATCH_PPID_ENV]:String(process.pid),[HOST_WATCH_PSTART_ENV]:options.supervisorStart?.time,[HOST_WATCH_PSTART_TICKS_ENV]:options.supervisorStart?.ticks,[HOST_WATCH_LIFETIME_FIFO_ENV]:options.lifetimeFifo,...internal.dir?{[HOST_SCRATCH_DIR_ENV]:internal.dir}:{},[SOCKET_SECRET_FILE_ENV]:process.platform==="win32"&&internalSecret?internal.secretPath:void 0,SENPI_RPC_INTERNAL_KEY_STDIN:options.internalKey?"1":void 0,[HOST_CLEANUP_PATHS_ENV]:options.cleanupPaths.join(`
|
|
34
|
-
`),...process.platform==="win32"?{}:{[HOST_PUBLIC_SOCKET_ENV]:publicSocket}},shell:childLaunch.shell,stdio:[process.platform==="win32"?"ignore":"pipe","ignore","inherit","pipe"],windowsHide:!0});return options.internalKey&&(child.stdin?.on("error",()=>{}),child.stdin?.write(options.internalKey)),child}import{chmod as chmod3,mkdir as mkdir5,stat as stat4,unlink as unlink3}from"node:fs/promises";import{createConnection as createConnection5,createServer}from"node:net";import{dirname as dirname9}from"node:path";import{StringDecoder as StringDecoder2}from"node:string_decoder";init_jsonl();function proxyWithAdmission(client,internal,admission,auth){let reply=chunk=>
|
|
35
|
-
`))}internal?.end()}async function responses(source){let fragments=[];for await(let chunk of source){let newline=chunk.lastIndexOf(10);if(newline===-1){fragments.push(chunk);continue}let complete=chunk.subarray(0,newline+1);if(!auth&&pending.length===0&&protocols===0&&refused.size===0){client.cork();let written;try{for(let fragment of fragments)client.write(fragment);written=
|
|
36
|
-
`,offset),end=newline===-1?text.length:newline;if(discarding||(buffer.length+end-offset>limit?(buffer="",discarding=!0,yield void 0):buffer+=text.slice(offset,end)),newline===-1)break;discarding||(yield buffer),buffer="",discarding=!1,offset=newline+1}}buffer+=decoder.end(),!discarding&&buffer.length>0&&(yield buffer)}function record(line){try{let value=JSON.parse(line);return isRecord5(value)?value:void 0}catch{return}}function isRecord5(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}init_jsonl();init_jsonl();init_rpc_auth_proof();init_socket_transport();import{randomBytes as randomBytes6}from"node:crypto";import{Duplex as
|
|
35
|
+
`,{mode:384}),await rename2(tmpPath,path)}async function unlinkOwnedSocket(socketPath,identity,log){if(process.platform==="win32"||socketPath.startsWith("\0"))return;let current;try{current=await statSocketIdentity(socketPath)}catch(cause){log(`socket ${socketPath} ownership could not be verified (${errorMessage2(cause)}); leaving it`);return}if(current!==void 0){if(identity===void 0){log(`socket path ${socketPath} ownership unknown; leaving it`);return}if(!sameSocketIdentity(current,identity)){log(`socket path ${socketPath} now owned by another host; leaving it`);return}try{await unlink(socketPath)}catch(cause){isNodeErrorCode4(cause,"ENOENT")||log(`socket ${socketPath} removal failed (${errorMessage2(cause)})`)}}}async function shieldSocketDuringClose(socketPath,close){if(process.platform==="win32"||socketPath.startsWith("\0"))return close();let shieldPath=`${socketPath}.shield-${process.pid}`,shielded=!1;try{await statSocketIdentity(socketPath)!==void 0&&(await rename2(socketPath,shieldPath),shielded=!0)}catch{}try{await close()}finally{if(shielded)try{await rename2(shieldPath,socketPath)}catch{}}}function errorMessage2(cause){return cause instanceof Error?cause.message:String(cause)}function isNodeErrorCode4(cause,code){return cause instanceof Error&&"code"in cause&&cause.code===code}async function adoptPublicSocket(bindSocket,publicSocket,expected){if(expected===void 0)throw new Error(`${publicSocket}: a generation launch must name the entry it replaces`);let current=await statSocketIdentity(publicSocket);if(current===void 0||current.dev!==expected.dev||current.ino!==expected.ino)throw new Error(`${publicSocket}: owned by another socket entry now; refusing to replace it`);await rename2(bindSocket,publicSocket)}var SUPERSESSION_POLL_MS=1e3,ABSENT_CONFIRMATIONS=3,REPLACED_CONFIRMATIONS=3,IDENTITY_PROBE_TIMEOUT_MS=2e3;function watchForSupersession(endpoint,onLost){if(endpoint.identity===void 0)return endpoint.pointer===void 0?()=>{}:watchPointerSupersession(endpoint,endpoint.pointer,onLost);let absentPolls=0,lost=!1,lose=loss=>{lost||(lost=!0,stop(),onLost(loss))},timer=setInterval(()=>{endpoint.settled?.()!==!0&&classifyEndpointOwnership(endpoint.path,endpoint.identity).then(ownership=>{if(endpoint.settled?.()!==!0)switch(ownership){case"replaced":lose("replaced");return;case"absent":if(absentPolls+=1,absentPolls<ABSENT_CONFIRMATIONS)return;lose("absent");return;case"held":case"unknown":absentPolls=0;return}},ignore2)},SUPERSESSION_POLL_MS);timer.unref?.();let stop=()=>clearInterval(timer);return stop}function watchPointerSupersession(endpoint,pointer,onLost){let probe=endpoint.probeInstanceId??probeAnsweringInstance,readPointer=endpoint.readPointerInstanceId??pointerInstanceId,agreeingPolls=0,observing=!1,lost=!1,observe=async()=>{let named=await readPointer(pointer.file);return named===void 0||named===pointer.instanceId?!1:await probe(endpoint.path)===named},timer=setInterval(()=>{lost||observing||endpoint.settled?.()===!0||(observing=!0,observe().then(replaced=>{lost||endpoint.settled?.()===!0||(agreeingPolls=replaced?agreeingPolls+1:0,!(agreeingPolls<REPLACED_CONFIRMATIONS)&&(lost=!0,clearInterval(timer),onLost("replaced")))},()=>{agreeingPolls=0}).finally(()=>{observing=!1}))},SUPERSESSION_POLL_MS);return timer.unref?.(),()=>clearInterval(timer)}async function pointerInstanceId(file){try{let parsed=JSON.parse(await readFile6(file,"utf8")),instanceId=typeof parsed=="object"&&parsed!==null?Reflect.get(parsed,"instance_id"):void 0;return typeof instanceId=="string"&&instanceId!==""?instanceId:void 0}catch{return}}async function probeAnsweringInstance(path){let{isRecord:isRecord6,requestOnSocket:requestOnSocket2}=await Promise.resolve().then(()=>(init_host_socket_request(),host_socket_request_exports)),answer=await requestOnSocket2(path,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},IDENTITY_PROBE_TIMEOUT_MS).catch(()=>{});return isRecord6(answer)&&typeof answer.instanceId=="string"?answer.instanceId:void 0}function ignore2(){}var SupervisorDrain=class{constructor(child,shuttingDown,beginStopping=()=>{},relay){this.draining=!1,this.child=child,this.shuttingDown=shuttingDown,this.beginStopping=beginStopping,this.relay=relay}get active(){return this.draining}drain(){if(this.draining||this.shuttingDown())return;this.draining=!0,this.beginStopping(),supervisorLog("draining into the next generation");let graceMs=parseIdleExitMs(process.env[HANDOFF_GRACE_MS_ENV])??6e5;this.graceTimer=setTimeout(()=>{supervisorLog(JSON.stringify({event:"handoff_grace_expired",graceMs})),this.requestChildDrain()},graceMs),this.graceTimer.unref(),this.requestChildDrain()}stop(){this.graceTimer&&clearTimeout(this.graceTimer)}async acceptRequests(generation){let stop=watchDrainRequest(generation.drainRequestFile,request=>{supervisorLog(`drain requested (${request.reason})`),this.drain()});return await writeDrainWatch(generation.drainWatchFile,{pid:process.pid}).catch(cause=>{supervisorLog(`cannot advertise the drain request: ${errorMessage(cause)}`)}),stop}requestChildDrain(){let{child,relay}=this;if(!(child.pid===void 0||child.exitCode!==null||child.signalCode!==null)&&(relay&&writeDrainRequest(relay.file,{sender:relay.sender,reason:"supervisor_drain"}).catch(cause=>{supervisorLog(`could not relay the drain to the host: ${errorMessage(cause)}`)}),process.platform!=="win32"))try{process.kill(child.pid,"SIGUSR1")}catch(cause){supervisorLog(`could not ask the host to drain: ${errorMessage(cause)}`)}}};function drainOnPublicSocketLoss(path,identity,settled,drain,onReplaced,pointer){return watchForSupersession({path,identity,settled,...pointer&&{pointer}},loss=>{loss==="replaced"&&onReplaced(),supervisorLog(loss==="absent"?"the public socket entry is gone; nothing can reach this generation; draining":"another generation owns the public socket; draining this one"),drain.drain()})}async function watchWin32ChildIdentity(child,shuttingDown,onGone){let pid=child.pid;if(pid===void 0)return()=>{};let childStartTime=await readProcessStartTime(pid,process.platform,1e3).catch(()=>{}),missingIdentityChecks=0,checking=!1,timer=setInterval(()=>{shuttingDown()||checking||child.exitCode!==null||child.signalCode!==null||(checking=!0,readProcessStartTime(pid,process.platform,1e3).then(currentStartTime=>{currentStartTime===void 0&&!processIsLive(pid)?missingIdentityChecks++:currentStartTime!==void 0&&(missingIdentityChecks=0),(childStartTime!==void 0&¤tStartTime!==void 0&¤tStartTime!==childStartTime||missingIdentityChecks>=2)&&onGone()}).catch(()=>{}).finally(()=>{checking=!1}))},500);return timer.unref?.(),()=>clearInterval(timer)}import{randomBytes as randomBytes5}from"node:crypto";import{readFile as readFile8}from"node:fs/promises";import{join as join13}from"node:path";init_process_identity();import{readFileSync as readFileSync4}from"node:fs";function readProcessStartTicks(pid,platform=process.platform){if(platform==="linux")try{let stat5=readFileSync4(`/proc/${pid}/stat`,"utf8"),ticks=stat5.slice(stat5.lastIndexOf(")")+2).split(" ")[19];return ticks!==void 0&&/^\d+$/.test(ticks)?ticks:void 0}catch{return}}init_process_identity();import{randomUUID as randomUUID4}from"node:crypto";import{realpathSync as realpathSync4}from"node:fs";import{mkdir as mkdir4,readFile as readFile7,writeFile as writeFile5}from"node:fs/promises";import{tmpdir}from"node:os";import{join as join11}from"node:path";var INTERNAL_HOST_DIR_PREFIX="senpi-rpc-host-internal-",SHORT_TEMP_ROOT="/tmp";function internalHostDirRoots(){let primary=tmpdir();return canonicalPath(primary)!==canonicalPath(SHORT_TEMP_ROOT)?[primary,SHORT_TEMP_ROOT]:[Buffer.byteLength(primary)<Buffer.byteLength(SHORT_TEMP_ROOT)?primary:SHORT_TEMP_ROOT]}function canonicalPath(path){try{return realpathSync4(path)}catch{return path}}function internalHostDirRoot(name){for(let root of internalHostDirRoots())if(Buffer.byteLength(join11(root,name,"host.sock"))<=MAX_SOCKET_PATH_BYTES)return root;let tried=internalHostDirRoots().map(root=>join11(root,name,"host.sock"));throw new Error(`internal_socket_path_too_long: every candidate exceeds ${MAX_SOCKET_PATH_BYTES} bytes (${tried.join(", ")}); set TMPDIR to a shorter directory`)}async function createInternalSocketPath(baseDir=tmpdir(),platform=process.platform){if(platform==="win32"){let dir2=join11(baseDir,`internal-${randomUUID4()}`);return await mkdir4(dir2,{recursive:!0,mode:448}),{socket:`\\\\.\\pipe\\senpi-rpc-internal-${randomUUID4()}`,dir:dir2,secretPath:join11(dir2,"secret")}}let name=`${INTERNAL_HOST_DIR_PREFIX}${randomUUID4().slice(0,8)}`,dir=join11(internalHostDirRoot(name),name);return await mkdir4(dir,{recursive:!1,mode:448}),await writeFile5(join11(dir,".owner"),JSON.stringify({pid:process.pid,processStartTime:await readProcessStartTime(process.pid),createdAt:Date.now()}),{mode:384}),{socket:join11(dir,"host.sock"),dir,secretPath:join11(dir,".secret")}}var CHILD_START_TIME_WAIT_MS=1e4,CHILD_START_TIME_UNHURRIED_MS=15e3;async function readChildStartTime(pid,timeoutMs){let identity=await readProcessIdentity(pid,process.platform,timeoutMs,void 0,"UTC");if(identity.kind==="error")throw identity.error;return identity.kind==="present"?identity.identity:void 0}async function recordChildPid(file,pid,running){try{await writeJsonAtomic(file,{pid,processStartTime:null});let processStartTime=await waitForStartTime(pid,CHILD_START_TIME_WAIT_MS,p=>readChildStartTime(p,1e3)).catch(()=>{})??await readChildStartTime(pid,CHILD_START_TIME_UNHURRIED_MS).catch(()=>{});if(processStartTime===void 0){supervisorLog(`host child pid ${pid} start time unreadable at recording`);return}if(!running())return;await writeJsonAtomic(file,{pid,processStartTime})}catch(cause){supervisorLog(`could not record the host child pid: ${errorMessage(cause)}`)}}async function readSettingsFile(settingsFile){try{return JSON.parse(await readFile7(settingsFile,"utf8"))}catch{return}}import{execFileSync as execFileSync2}from"node:child_process";import{closeSync,constants as constants3,fstatSync,openSync,rmSync}from"node:fs";import{join as join12}from"node:path";var HOST_WATCH_LIFETIME_FIFO_ENV="SENPI_RPC_HOST_LIFETIME_FIFO";function prepareLifetimeBinding(hopDir,platform=process.platform){if(platform!=="linux")return{};let path=join12(hopDir,"lifetime.fifo");try{return rmSync(path,{force:!0}),execFileSync2("mkfifo",["-m","600",path],{stdio:"ignore"}),openSync(path,constants3.O_RDWR),{lifetimeFifo:path}}catch{return{}}}init_socket_transport();async function recordedOwnerStartTime(dir){if(dir!==void 0)try{let owner=JSON.parse(await readFile8(join13(dir,".owner"),"utf8")),start=owner!==null&&typeof owner=="object"?Reflect.get(owner,"processStartTime"):void 0;return typeof start=="string"?start:void 0}catch{return}}async function prepareInternalHop(daemonDir){let created=await createInternalSocketPath(daemonDir),internal={...created,secretPath:created.secretPath??socketSecretPath(created.socket)},internalSecret=process.platform==="win32"?await createSocketSecret(internal.secretPath):void 0,internalKey=process.platform==="win32"?void 0:randomBytes5(32);return{internal,internalSocket:internal.socket,internalSecret,internalKey,...internalKey&&internal.dir!==void 0?prepareLifetimeBinding(internal.dir):{},supervisorStart:internalKey?{time:await recordedOwnerStartTime(internal.dir),ticks:readProcessStartTicks(process.pid)}:void 0,transport:{...internalSecret?{internalSecret}:{},...internalKey?{internalKey}:{}}}}import{spawn}from"node:child_process";init_config();import{extname}from"node:path";function runtimeExecArgv(execArgv=process.execArgv,bun=process.versions.bun!==void 0){let args=[];for(let index=0;index<execArgv.length;index++){let arg=execArgv[index];if(bun){if(arg==="-e"||arg==="--eval"||arg==="-p"||arg==="--print"||arg==="-pe"){index++;continue}if(arg.startsWith("-e")||arg.startsWith("-p"))continue}if(arg==="-e"||arg==="--eval"||arg==="-pe"||arg==="--input-type"||arg==="--input_type"){index++;continue}if(arg==="-p"||arg==="--print"){execArgv[index+1]!==void 0&&!execArgv[index+1].startsWith("-")&&index++;continue}arg==="-i"||arg==="--interactive"||arg.startsWith("--interactive=")||arg.startsWith("--eval=")||arg.startsWith("--print=")||arg.startsWith("--input-type=")||arg.startsWith("--input_type=")||args.push(arg)}return args}init_host_identity_env();init_brand();init_host_identity_env();init_process_identity();var HOST_WATCH_FD_ENV="SENPI_RPC_HOST_WATCH_FD",HOST_SCRATCH_DIR_ENV="SENPI_RPC_HOST_SCRATCH_DIR",HOST_PUBLIC_SOCKET_ENV="SENPI_RPC_HOST_PUBLIC_SOCKET",HOST_WATCH_PPID_ENV="SENPI_RPC_HOST_WATCH_PPID",HOST_WATCH_PSTART_ENV="SENPI_RPC_HOST_WATCH_PSTART",HOST_WATCH_PSTART_TICKS_ENV="SENPI_RPC_HOST_WATCH_PSTART_TICKS",HOST_CLEANUP_PATHS_ENV="SENPI_RPC_HOST_CLEANUP_PATHS";init_socket_transport();var INTERNAL_SUPERVISOR_FLAG="--internal-rpc-host-supervisor",INJECTABLE_PREFIX_FLAGS=new Set(["--extension"]);function findInternalSupervisorArgs(argv){for(let index=0;index<argv.length;index++){let arg=argv[index];if(arg===INTERNAL_SUPERVISOR_FLAG)return argv.slice(index+1);if(!INJECTABLE_PREFIX_FLAGS.has(arg)||index+1>=argv.length)return;index++}}function parseSupervisorArgs(argv){let hostArgs=[],socket,childCommand,childArgs,agentDir,ownerFd,presenterBootstrapFd,bindSocket,replaceIdentity;for(let index=0;index<argv.length;index++){let arg=argv[index];if(arg==="--mcp-presenter-fd"&&argv[index+1]==="4"){presenterBootstrapFd=4,index++;continue}if(arg==="--owner-fd"&&index+1<argv.length){if(ownerFd=Number(argv[++index]),!Number.isSafeInteger(ownerFd)||ownerFd<3)return;continue}if(arg==="--socket"&&index+1<argv.length){socket=argv[++index];continue}if(arg==="--child-command"&&index+1<argv.length){childCommand=argv[++index];continue}if(arg==="--child-args"&&index+1<argv.length){try{let parsed=JSON.parse(argv[++index]);Array.isArray(parsed)&&parsed.every(value=>typeof value=="string")&&(childArgs=parsed)}catch{return}continue}if(arg==="--agent-dir"&&index+1<argv.length){agentDir=argv[++index];continue}if(arg==="--bind"&&index+1<argv.length){bindSocket=argv[++index];continue}if(arg==="--replace"&&index+1<argv.length){replaceIdentity=parseSocketIdentity(argv[++index]);continue}hostArgs.push(arg)}return socket===void 0||ownerFd===presenterBootstrapFd&&ownerFd!==void 0?void 0:{socket,hostArgs,childCommand,childArgs,agentDir,ownerFd,bindSocket,replaceIdentity,presenterBootstrapFd}}function parseSocketIdentity(value){let match=/^(\d+):(\d+)$/.exec(value);return match?{dev:Number(match[1]),ino:Number(match[2])}:void 0}function resolveHostChildLaunch(launch,internalSocket,compiled=isBunBinary){return launch.childCommand?{command:launch.childCommand,args:[...launch.childArgs??[],"--listen",`unix://${internalSocket}`]}:{command:process.execPath,args:[...compiled?[]:[...runtimeExecArgv(),resolveCliMainPath()],"--mode","rpc","--multi-session","--listen",`unix://${internalSocket}`,...launch.hostArgs]}}function quoteWindowsShellArg(value){return`"${value.replace(/(\\*)"/g,'$1$1\\"').replace(/(\\*)$/,"$1$1").replace(/([()%!^"<>&|;,])/g,"^$1")}"`}function spawnableChildLaunch(launch,platform=process.platform){let extension=extname(launch.command).toLowerCase();return platform!=="win32"||extension!==".cmd"&&extension!==".bat"?{...launch,shell:!1}:{command:quoteWindowsShellArg(launch.command),args:launch.args.map(quoteWindowsShellArg),shell:!0}}var HOST_CHILD_WATCH_FD=3;function spawnHostChild(options){let{launch,internalSocket,internal,internalSecret,publicSocket}=options,childLaunch=spawnableChildLaunch(resolveHostChildLaunch(launch,internalSocket)),bootstrap=launch.presenterBootstrapFd!==void 0&&!childLaunch.shell;bootstrap&&childLaunch.args.push("--mcp-presenter-fd","4");let child=spawn(childLaunch.command,childLaunch.args,{env:{...process.env,...launch.agentDir?{SENPI_CODING_AGENT_DIR:launch.agentDir}:{},[HOST_DAEMON_DIR_ENV]:options.daemonDir,[HOST_INSTANCE_ID_ENV]:options.instanceId,[HOST_WATCH_FD_ENV]:String(HOST_CHILD_WATCH_FD),[HOST_WATCH_PPID_ENV]:String(process.pid),[HOST_WATCH_PSTART_ENV]:options.supervisorStart?.time,[HOST_WATCH_PSTART_TICKS_ENV]:options.supervisorStart?.ticks,[HOST_WATCH_LIFETIME_FIFO_ENV]:options.lifetimeFifo,...internal.dir?{[HOST_SCRATCH_DIR_ENV]:internal.dir}:{},[SOCKET_SECRET_FILE_ENV]:process.platform==="win32"&&internalSecret?internal.secretPath:void 0,SENPI_RPC_INTERNAL_KEY_STDIN:options.internalKey?"1":void 0,[HOST_CLEANUP_PATHS_ENV]:options.cleanupPaths.join(`
|
|
36
|
+
`),...process.platform==="win32"?{}:{[HOST_PUBLIC_SOCKET_ENV]:publicSocket}},shell:childLaunch.shell,stdio:[process.platform==="win32"?"ignore":"pipe","ignore","inherit","pipe",...bootstrap?["pipe"]:[]],windowsHide:!0});if(launch.presenterBootstrapFd!==void 0){let fd=launch.presenterBootstrapFd;Promise.resolve().then(()=>(init_mcp_presenter_bootstrap(),mcp_presenter_bootstrap_exports)).then(({presenterBootstrapStream:presenterBootstrapStream2,relayPresenterBootstrap:relayPresenterBootstrap2})=>{let upstream=presenterBootstrapStream2(fd);if(upstream&&bootstrap)return relayPresenterBootstrap2(upstream,child);upstream?.destroy(),child.stdio[4]?.destroy()}).catch(()=>child.stdio[4]?.destroy())}return options.internalKey&&(child.stdin?.on("error",()=>{}),child.stdin?.write(options.internalKey)),child}import{chmod as chmod3,mkdir as mkdir5,stat as stat4,unlink as unlink3}from"node:fs/promises";import{createConnection as createConnection5,createServer}from"node:net";import{dirname as dirname9}from"node:path";import{StringDecoder as StringDecoder2}from"node:string_decoder";init_jsonl();function proxyWithAdmission(client,internal,admission,auth){let reply=chunk=>write2(client,auth?auth.response(chunk.toString()):chunk),pending=[],refused=new Set,protocols=0,refusals=Promise.resolve(),unsubscribe=admission.onStop(()=>(refusals=refusePending(),refusals));async function refusePending(){let ids=pending.splice(0);for(let id of ids)refused.add(id);try{for(let id of ids)await reply(serializeJsonLine(hostStoppingResponse(id,"open_session",admission)))}catch{fail()}}client.once("close",()=>{unsubscribe(),internal?.destroy()});let fail=()=>{internal?.destroy(),client.destroy()};client.once("error",fail),internal?.once("error",()=>{admission.stopping||fail()}),requests().catch(()=>{admission.stopping||fail()}),internal&&responses(internal).catch(()=>{admission.stopping||fail()});async function requests(){for await(let line of lines(auth?.input??client,MAX_RPC_LINE_CHARACTERS)){if(line===void 0){await reply(serializeJsonLine({type:"response",command:"parse",success:!1,error:`RPC input line exceeds ${MAX_RPC_LINE_CHARACTERS} characters.`}));continue}let request=record(line);admission.stopping&&request?.type==="get_protocol_info"?await reply(serializeJsonLine({id:request.id,type:"response",command:request.type,success:!0,data:admission.protocol()})):admission.stopping&&(request?.type==="open_session"||!internal)?await reply(serializeJsonLine(hostStoppingResponse(request?.id,String(request?.type??"parse"),admission))):internal&&(request?.type==="open_session"&&pending.push(request.id),request?.type==="get_protocol_info"&&protocols++,await write2(internal,`${line}
|
|
37
|
+
`))}internal?.end()}async function responses(source){let fragments=[];for await(let chunk of source){let newline=chunk.lastIndexOf(10);if(newline===-1){fragments.push(chunk);continue}let complete=chunk.subarray(0,newline+1);if(!auth&&pending.length===0&&protocols===0&&refused.size===0){client.cork();let written;try{for(let fragment of fragments)client.write(fragment);written=write2(client,complete)}finally{client.uncork()}await written}else{let batch=fragments.length>0?Buffer.concat([...fragments,complete]):complete;await reply(filterReplies(batch))}fragments=newline+1<chunk.length?[chunk.subarray(newline+1)]:[]}fragments.length>0&&await reply(filterReplies(Buffer.concat(fragments))),await refusals,client.end(()=>client.destroy())}function filterReplies(batch){if(pending.length===0&&protocols===0&&refused.size===0)return batch;let output=[],changed=!1;for(let start=0;start<batch.length;){let newline=batch.indexOf(10,start),end=newline===-1?batch.length:newline+1,line=batch.subarray(start,end);start=end;let response=line.includes('"open_session"')||line.includes('"get_protocol_info"')?record(line.toString("utf8")):void 0;if(response?.type==="response"&&response.command==="open_session"){if(refused.has(response.id)){changed=!0;continue}let index=pending.indexOf(response.id);index!==-1&&pending.splice(index,1)}if(response?.type==="response"&&response.command==="get_protocol_info"&&(protocols=Math.max(0,protocols-1),response.success===!0)){isRecord5(response.data)&&admission.observe(response.data),output.push(Buffer.from(serializeJsonLine({...response,data:admission.protocol()}))),changed=!0;continue}output.push(line)}return changed?Buffer.concat(output):batch}}async function write2(socket,line){await new Promise((resolve4,reject)=>{socket.write(line,error=>error?reject(error):resolve4())})}async function*lines(socket,limit){let decoder=new StringDecoder2("utf8"),buffer="",discarding=!1;for await(let chunk of socket){let text=typeof chunk=="string"?chunk:decoder.write(chunk),offset=0;for(;offset<text.length;){let newline=text.indexOf(`
|
|
38
|
+
`,offset),end=newline===-1?text.length:newline;if(discarding||(buffer.length+end-offset>limit?(buffer="",discarding=!0,yield void 0):buffer+=text.slice(offset,end)),newline===-1)break;discarding||(yield buffer),buffer="",discarding=!1,offset=newline+1}}buffer+=decoder.end(),!discarding&&buffer.length>0&&(yield buffer)}function record(line){try{let value=JSON.parse(line);return isRecord5(value)?value:void 0}catch{return}}function isRecord5(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}init_jsonl();init_jsonl();init_rpc_auth_proof();init_socket_transport();import{randomBytes as randomBytes6}from"node:crypto";import{Duplex as Duplex3,PassThrough}from"node:stream";var PREAUTH_BYTES=8*1024,PublicRpcConnection=class{get stream(){return this.view??=this.duplex(),this.view}constructor(socket,endpoint,requireToken=process.env.SENPI_RPC_REQUIRE_TOKEN==="1"){this.input=new PassThrough,this.raw=new PassThrough,this.bytes=0,this.active=!1,this.failed=!1,this.first=!0,this.protocolPending=!1,this.socket=socket,this.endpoint=endpoint,this.requireToken=requireToken,socket.pause(),this.timer=setTimeout(()=>{this.requireToken?this.drop("pre-auth deadline"):!this.active&&!this.failed&&this.challenge===void 0&&this.grace()},SOCKET_HANDSHAKE_TIMEOUT_MS);let detach=attachJsonlLineReader(this.raw,line=>this.line(line),{maxLineLength:MAX_RPC_LINE_CHARACTERS,onOversizedLine:()=>this.active?socket.destroy():this.drop("first frame over the line limit")});socket.on("error",()=>socket.destroy()),socket.once("close",()=>{!this.active&&!this.failed&&!this.requireToken&&!this.first&&this.grace(),clearTimeout(this.timer),detach(),this.raw.destroy(),this.input.end()}),socket.once("end",()=>this.raw.end()),this.input.on("drain",()=>socket.resume()),socket.on("data",chunk=>{for(let offset=0;offset<chunk.length&&!this.failed;){let newline=chunk.indexOf(10,offset),end=newline===-1?chunk.length:newline+1,segment=chunk.subarray(offset,end);if(this.active||(this.bytes+=segment.length),!this.active&&this.requireToken&&this.bytes>PREAUTH_BYTES){this.drop("pre-auth budget exceeded");return}this.raw.write(segment),offset=end}}),endpoint.ready.then(()=>{socket.destroyed||socket.resume()},()=>this.drop("key publication failed"))}duplex(){let input=this.input,stream=new Duplex3({read:()=>input.resume(),write:(chunk,_encoding,callback)=>{let output=this.response(chunk.toString());output===""?callback():this.socket.write(output,callback)},final:callback=>this.socket.end(callback),destroy:(error,callback)=>{this.socket.destroy(),callback(error)}});return input.on("data",chunk=>{stream.push(chunk)||input.pause()}),input.once("end",()=>{stream.push(null),stream.destroy()}),input.readableEnded&&stream.destroy(),stream}line(line){if(this.failed||this.socket.destroyed)return;let request;try{request=authRecord(JSON.parse(line))}catch{}if(!this.active){if(this.first&&request?.type==="get_protocol_info"){this.first=!1,this.protocolPending=!0;let nonce2=authRecord(request.auth)?.client_nonce;if(nonce2!==void 0){if(typeof nonce2!="string"||!RPC_AUTH_HEX.test(nonce2)){this.refuse(request,"auth_failed");return}this.challenge={id:request.id,client:nonce2,server:randomBytes6(32).toString("hex")}}else if(this.requireToken){this.refuse(request,"auth_required");return}else this.grace();this.forward(line);return}if(this.first=!1,request?.type==="authenticate"){let c=this.challenge;if(!c||!rpcProofMatches(rpcAuthProof(this.endpoint.key,"client",this.endpoint.launchId,c.server,c.client),request.client_proof)){this.refuse(request,"auth_failed");return}this.active=!0,clearTimeout(this.timer),this.socket.write(serializeJsonLine({id:request.id,type:"response",command:"authenticate",success:!0}));return}if(this.requireToken){this.refuse(request,"auth_required");return}this.grace()}this.forward(line)}forward(line){this.input.write(`${line}
|
|
37
39
|
`)||this.socket.pause()}grace(){this.active=!0,clearTimeout(this.timer),process.stderr.write(`senpi rpc host: served a client that did not prove the endpoint key on ${this.endpoint.endpoint} (deprecated, refused from the next release; see docs/rpc.md#authentication)
|
|
38
40
|
`)}logDrop(reason){process.stderr.write(`senpi rpc host: dropped an unauthenticated connection on ${this.endpoint.endpoint}: ${reason}
|
|
39
41
|
`)}drop(reason){this.failed||(this.failed=!0,clearTimeout(this.timer),this.logDrop(reason),this.socket.destroy())}refuse(request,code){this.failed=!0,clearTimeout(this.timer),this.logDrop(code),this.socket.end(serializeJsonLine({id:request?.id,type:"response",command:request?.type??"parse",success:!1,error:code,errorCode:code}),()=>this.socket.destroy())}response(chunk){if(this.failed)return"";if(this.active&&!this.protocolPending)return chunk;let output="";for(let line of chunk.split(`
|