@code-yeongyu/senpi 2026.11.13 → 2026.11.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/bundle/chunks/{args-H56W53X6.js → args-JWBI5LNO.js} +1 -1
  3. package/dist/bundle/chunks/{azure-openai-responses-MNN2TINI.js → azure-openai-responses-PEMLRPJ5.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-HZQHA4PA.js → chunk-3RILB2OD.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-Y4PFEXFN.js → chunk-5IXYN6DK.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-BKDXY6EM.js → chunk-5NECOJNK.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-NI2AOYP6.js → chunk-6MRUNB3Z.js} +1 -1
  8. package/dist/bundle/chunks/chunk-6QQL3SKM.js +2 -0
  9. package/dist/bundle/chunks/{chunk-I4N2OIY4.js → chunk-6QXAYNO7.js} +17 -17
  10. package/dist/bundle/chunks/{chunk-7T2LAWZ4.js → chunk-73HGQTJN.js} +1 -1
  11. package/dist/bundle/chunks/chunk-75O3CWR5.js +2 -0
  12. package/dist/bundle/chunks/{chunk-AZ27TE3H.js → chunk-7BX3JQ7F.js} +1 -1
  13. package/dist/bundle/chunks/{chunk-NDI6N4NJ.js → chunk-7CXLNKEH.js} +1 -1
  14. package/dist/bundle/chunks/{chunk-E6ZBTSC6.js → chunk-A3LGSX7Z.js} +1 -1
  15. package/dist/bundle/chunks/{chunk-7GD2EO6T.js → chunk-FYVQEZYN.js} +1 -1
  16. package/dist/bundle/chunks/{chunk-U4FAWC6C.js → chunk-GXPH7RN6.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-SFACYIB6.js → chunk-IK3S2NDB.js} +1 -1
  18. package/dist/bundle/chunks/{chunk-V4VDIV3U.js → chunk-PWA75RQU.js} +1 -1
  19. package/dist/bundle/chunks/{chunk-IREUIMFE.js → chunk-PWTXZXHH.js} +1 -1
  20. package/dist/bundle/chunks/{chunk-KKB3K5CV.js → chunk-Q4RJ4WLE.js} +1 -1
  21. package/dist/bundle/chunks/chunk-QVG5SUSV.js +2 -0
  22. package/dist/bundle/chunks/chunk-RLIY3AUC.js +2 -0
  23. package/dist/bundle/chunks/{chunk-EQT4WNCW.js → chunk-TACOXP5H.js} +1 -1
  24. package/dist/bundle/chunks/{chunk-NXGSYUMV.js → chunk-TB6LIKVR.js} +2 -2
  25. package/dist/bundle/chunks/{chunk-JLCZIEBC.js → chunk-THYIV26N.js} +1 -1
  26. package/dist/bundle/chunks/{chunk-6FE42M54.js → chunk-VGHGM5PR.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-CU6HUYL7.js → chunk-WAGFTIT4.js} +1 -1
  28. package/dist/bundle/chunks/{chunk-UYPH6RHY.js → chunk-Z4PN2MDA.js} +2 -2
  29. package/dist/bundle/chunks/{chunk-JJYN347Z.js → chunk-ZJUL5ODW.js} +1 -1
  30. package/dist/bundle/chunks/{cli-main-MY53RXU3.js → cli-main-MM2XCVYE.js} +1 -1
  31. package/dist/bundle/chunks/credential-accounts-RXZIUKFM.js +2 -0
  32. package/dist/bundle/chunks/github-copilot.js +1 -1
  33. package/dist/bundle/chunks/{hand-entry-AXTVMVJK.js → hand-entry-MBOPYO6I.js} +1 -1
  34. package/dist/bundle/chunks/{headless-host-SU5O2KZ2.js → headless-host-OEK6W65T.js} +1 -1
  35. package/dist/bundle/chunks/{health-write-TN7EXGLI.js → health-write-44JERGEJ.js} +1 -1
  36. package/dist/bundle/chunks/{help-fast-path-TFQ4HJNO.js → help-fast-path-JWHUCE4E.js} +1 -1
  37. package/dist/bundle/chunks/{host-command-FG56Y53E.js → host-command-O2K2WIPO.js} +1 -1
  38. package/dist/bundle/chunks/{host-session-command-UFEOW7EP.js → host-session-command-EWA6N4JJ.js} +1 -1
  39. package/dist/bundle/chunks/interactive-mode-VSZYRVYY.js +2 -0
  40. package/dist/bundle/chunks/{login-health-XBTIORM4.js → login-health-V4B6LSCP.js} +1 -1
  41. package/dist/bundle/chunks/main-VEWKRBTD.js +2 -0
  42. package/dist/bundle/chunks/{multi-session-host-Q6SHI22A.js → multi-session-host-HC6NR5N2.js} +1 -1
  43. package/dist/bundle/chunks/{openai-codex-responses-VRGOAFEG.js → openai-codex-responses-IFPWK7NG.js} +1 -1
  44. package/dist/bundle/chunks/openai-responses-2BTL5MA2.js +5 -0
  45. package/dist/bundle/chunks/{package-manager-cli-LILAWI3Q.js → package-manager-cli-OZ6DK6GI.js} +3 -3
  46. package/dist/bundle/chunks/{role-KODRTWH5.js → role-BTH5PVME.js} +1 -1
  47. package/dist/bundle/chunks/{rotation-stream-2KNROTYB.js → rotation-stream-ZGPXLY62.js} +1 -1
  48. package/dist/bundle/chunks/rpc-mode-WPF3NVBL.js +2 -0
  49. package/dist/bundle/chunks/{run-attached-tui-OEFHV5CZ.js → run-attached-tui-RVVYEINN.js} +1 -1
  50. package/dist/bundle/chunks/{schedule-command-VO4RP2KX.js → schedule-command-6TAAG2KU.js} +1 -1
  51. package/dist/bundle/chunks/{session-control-endpoint-CCVRJHSC.js → session-control-endpoint-3FNVOKKT.js} +1 -1
  52. package/dist/bundle/chunks/{session-picker-VN5I2ZDI.js → session-picker-YDXDCBRL.js} +1 -1
  53. package/dist/bundle/chunks/session-slot-N4E4OSCX.js +2 -0
  54. package/dist/bundle/chunks/session-worker.js +22 -21
  55. package/dist/bundle/chunks/{state-store-7RVODZJU.js → state-store-I6MUHET3.js} +1 -1
  56. package/dist/bundle/cli.js +2 -2
  57. package/dist/bundle/index.js +1 -1
  58. package/dist/bundle/rpc-entry.js +1 -1
  59. package/dist/bundle/runtime-manifest.json +1 -1
  60. package/dist/core/agent-session.d.ts +5 -3
  61. package/dist/core/agent-session.js +16 -6
  62. package/dist/core/credential-accounts.d.ts +5 -3
  63. package/dist/core/credential-accounts.js +8 -6
  64. package/dist/core/credential-pool/classify.js +5 -1
  65. package/dist/core/extensions/builtin/anthropic-subscription/content-blocks.d.ts +6 -0
  66. package/dist/core/extensions/builtin/anthropic-subscription/content-blocks.js +14 -0
  67. package/dist/core/extensions/builtin/anthropic-subscription/prompt-bridge.js +3 -1
  68. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.js +4 -1
  69. package/dist/core/extensions/builtin/permission-system/index.js +5 -1
  70. package/dist/core/reasoning-baseline.d.ts +8 -1
  71. package/dist/core/reasoning-baseline.js +24 -0
  72. package/dist/modes/rpc/connection-handler.js +4 -0
  73. package/dist/modes/rpc/method-classes-schema-session.d.ts +3 -0
  74. package/dist/modes/rpc/method-classes-schema-session.js +6 -2
  75. package/dist/modes/rpc/method-classes-schema.d.ts +3 -0
  76. package/dist/modes/rpc/project-expected-cwd.d.ts +29 -0
  77. package/dist/modes/rpc/project-expected-cwd.js +45 -0
  78. package/dist/modes/rpc/rpc-error-types.d.ts +7 -1
  79. package/dist/modes/rpc/rpc-error-types.js +6 -0
  80. package/dist/modes/rpc/rpc-session-command-types.d.ts +3 -0
  81. package/dist/package-manager-cli.d.ts +14 -0
  82. package/dist/package-manager-cli.js +20 -4
  83. package/dist/utils/version-check.d.ts +10 -7
  84. package/dist/utils/version-check.js +24 -5
  85. package/docs/rpc.md +20 -7
  86. package/package.json +7 -7
  87. package/dist/bundle/chunks/chunk-GLTOBXZY.js +0 -2
  88. package/dist/bundle/chunks/chunk-PBUV2Z3R.js +0 -2
  89. package/dist/bundle/chunks/chunk-WRBOKYPS.js +0 -2
  90. package/dist/bundle/chunks/credential-accounts-ZB5IXHIG.js +0 -2
  91. package/dist/bundle/chunks/interactive-mode-PHES47E3.js +0 -2
  92. package/dist/bundle/chunks/main-PR4FI6HQ.js +0 -2
  93. package/dist/bundle/chunks/openai-responses-I7PXRWCM.js +0 -4
  94. package/dist/bundle/chunks/rpc-mode-CGVK4SSA.js +0 -2
  95. package/dist/bundle/chunks/session-slot-GHJVOSG7.js +0 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [2026.11.15] - 2026-11-15
4
+
5
+ ### Breaking Changes
6
+
7
+ ### Added
8
+
9
+ - RPC project writes (`set_project_trust`, `set_project_setting`, `write_project_file`) accept an optional `expectedCwd`; when the session's working directory is another folder the write is refused with `project_cwd_mismatch` and nothing is written ([#6659](https://github.com/code-yeongyu/senpi/pull/6659))
10
+
11
+ ### Changed
12
+
13
+ ### Fixed
14
+
15
+ - A Claude subscription account that is out for billing or organization access no longer lets its usage reading release the session's usage-limit hold ([#6536](https://github.com/code-yeongyu/senpi/issues/6536))
16
+ - Standalone binary installs no longer announce an update that is published on npm but not yet available as a GitHub Release; they read the latest GitHub Release instead, and `update --self` on a binary points at the download page when that lookup fails ([#6634](https://github.com/code-yeongyu/senpi/pull/6634))
17
+ - ChatGPT subscription (Sign in with ChatGPT): an account without Responses API access is no longer parked as `auth_error`; the turn fails with a message that says signing in again will not help and what to check instead ([#6643](https://github.com/code-yeongyu/senpi/issues/6643))
18
+ - Models that take mid-session effort updates (GPT-6.1 Sol, GPT-6 Astra) now run a retry-fallback rung at the rung's own thinking level instead of the level of an earlier update ([#6655](https://github.com/code-yeongyu/senpi/issues/6655))
19
+ - ChatGPT subscription (Sign in with ChatGPT): a missing-scope refusal that lists other scopes before `api.responses.write` now gets the same guidance and leaves the account healthy ([#6643](https://github.com/code-yeongyu/senpi/issues/6643))
20
+ - Claude subscription (anthropic-subscription): tool output is always sent to Claude Code marked as tool output, so it can never be read as a Claude Code slash command ([#6667](https://github.com/code-yeongyu/senpi/issues/6667))
21
+ - A permission prompt that nobody answers no longer keeps a turn or a sub-agent waiting forever: aborting the turn now ends the prompt and refuses the call ([#6670](https://github.com/code-yeongyu/senpi/issues/6670))
22
+
23
+ ### Removed
24
+
3
25
  ## [2026.11.13] - 2026-11-13
4
26
 
5
27
  ### Breaking Changes
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{isSessionRuntimeKind,isValidThinkingLevel,normalizeSessionName,parseArgs,printHelp,resolveSessionRuntime}from"./chunk-IEY2SL46.js";import"./chunk-26UBFF6N.js";import"./chunk-SFACYIB6.js";import"./chunk-XDEZA6U6.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-IREUIMFE.js";import"./chunk-GVSBCJFI.js";import"./chunk-Z6TEQEZO.js";import"./chunk-ZG3MNTNX.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-UAOOH2V7.js";import"./chunk-WDTJ6JKE.js";import"./chunk-OH5TKHW7.js";import"./chunk-NDNQ23SK.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-PJ34QVL5.js";import"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-IKOFCODM.js";export{isSessionRuntimeKind,isValidThinkingLevel,normalizeSessionName,parseArgs,printHelp,resolveSessionRuntime};
2
+ import{isSessionRuntimeKind,isValidThinkingLevel,normalizeSessionName,parseArgs,printHelp,resolveSessionRuntime}from"./chunk-IEY2SL46.js";import"./chunk-26UBFF6N.js";import"./chunk-IK3S2NDB.js";import"./chunk-XDEZA6U6.js";import"./chunk-COH5F7QV.js";import"./chunk-RFB5CBW7.js";import"./chunk-Y7QPP7BG.js";import"./chunk-PWTXZXHH.js";import"./chunk-GVSBCJFI.js";import"./chunk-Z6TEQEZO.js";import"./chunk-ZG3MNTNX.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-UAOOH2V7.js";import"./chunk-WDTJ6JKE.js";import"./chunk-OH5TKHW7.js";import"./chunk-NDNQ23SK.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import"./chunk-PJ34QVL5.js";import"./chunk-SODMQEHO.js";import"./chunk-ATQFN5HI.js";import"./chunk-MIENF2YK.js";import"./chunk-IKOFCODM.js";export{isSessionRuntimeKind,isValidThinkingLevel,normalizeSessionName,parseArgs,printHelp,resolveSessionRuntime};
@@ -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{AzureOpenAI}from"./chunk-CD2HJK4C.js";import{getPiUserAgent}from"./chunk-QTG7MY2X.js";import{buildBaseOptions}from"./chunk-A7HSTZ5T.js";import{retryProviderRequest}from"./chunk-GIT63LXN.js";import{deriveOpenAIPromptCacheKey}from"./chunk-2IKL4F24.js";import{formatProviderError,normalizeProviderError}from"./chunk-AC72EWI5.js";import"./chunk-RQFD6LG2.js";import{convertResponsesMessages,convertResponsesTools,processResponsesStream}from"./chunk-IREUIMFE.js";import"./chunk-GVSBCJFI.js";import"./chunk-HK46JMSC.js";import{getProviderEnvValue}from"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import{createGrammarToolInputProperties}from"./chunk-UAOOH2V7.js";import"./chunk-WDTJ6JKE.js";import{clampThinkingLevel,getDeclaredTools,resolveTranscript,resolveTranscriptTools,supportsMax}from"./chunk-OH5TKHW7.js";import{AssistantMessageEventStream}from"./chunk-NDNQ23SK.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import{headersToRecord}from"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";var DEFAULT_AZURE_API_VERSION="v1",AZURE_TOOL_CALL_PROVIDERS=new Set(["openai","chatgpt-subscription","opencode","azure-openai-responses"]),OPENAI_RESPONSES_MIN_OUTPUT_TOKENS=16;function parseDeploymentNameMap(value){let map=new Map;if(!value)return map;for(let entry of value.split(",")){let trimmed=entry.trim();if(!trimmed)continue;let[modelId,deploymentName]=trimmed.split("=",2);!modelId||!deploymentName||map.set(modelId.trim(),deploymentName.trim())}return map}function resolveDeploymentName(model,options){return options?.azureDeploymentName?options.azureDeploymentName:parseDeploymentNameMap(getProviderEnvValue("AZURE_OPENAI_DEPLOYMENT_NAME_MAP",options?.env)).get(model.id)||model.id}function formatAzureOpenAIError(error){return formatProviderError(normalizeProviderError(error),"Azure OpenAI API error")}var stream=(model,context,options)=>{let stream2=new AssistantMessageEventStream({captureBlocks:!0}),normalizedContext=resolveTranscript(context,model.compat?.supportsMidConvoSystemMessages);return(async()=>{let deploymentName=resolveDeploymentName(model,options),output={role:"assistant",content:[],api:"azure-openai-responses",provider:model.provider,model:model.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};try{let apiKey=options?.apiKey;if(!apiKey)throw new Error(`No API key for provider: ${model.provider}`);let client=createClient(model,apiKey,options),grammarToolInputProperties=createGrammarToolInputProperties(getDeclaredTools(normalizedContext.messages),model.compat?.supportsOpenAIGrammarTools??!1),params=buildParams(model,normalizedContext,options,deploymentName,grammarToolInputProperties),nextParams=await options?.onPayload?.(params,model);nextParams!==void 0&&(params=nextParams);let requestOptions={...options?.signal?{signal:options.signal}:{},...options?.timeoutMs!==void 0?{timeout:options.timeoutMs}:{},maxRetries:0},{data:openaiStream,response}=await retryProviderRequest(()=>client.responses.create(params,requestOptions).withResponse(),{maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,signal:options?.signal});if(await options?.onResponse?.({status:response.status,headers:headersToRecord(response.headers)},model),stream2.push({type:"start",partial:output}),await processResponsesStream(openaiStream,output,stream2,model,{onProviderStreamEvent:options?.onProviderStreamEvent,grammarToolInputProperties}),options?.signal?.aborted)throw new Error("Request was aborted");if(output.stopReason==="pending")throw new Error("Azure OpenAI Responses stream ended without a stop reason");if(output.stopReason==="aborted"||output.stopReason==="error")throw new Error(output.errorMessage||"An unknown error occurred");stream2.push({type:"done",reason:output.stopReason,message:output}),stream2.end()}catch(error){for(let block of output.content)delete block.index,delete block.partialJson,delete block.customInput;output.stopReason=options?.signal?.aborted?"aborted":"error",output.errorMessage=formatAzureOpenAIError(error),stream2.push({type:"error",reason:output.stopReason,error:output}),stream2.end()}})(),stream2},streamSimple=(model,context,options)=>{let apiKey=options?.apiKey;if(!apiKey)throw new Error(`No API key for provider: ${model.provider}`);let base={...buildBaseOptions(model,context,options,apiKey),toolChoice:options?.toolChoice},clampedReasoning=options?.reasoning?clampThinkingLevel(model,options.reasoning):void 0,reasoningEffort=clampedReasoning==="off"?void 0:clampedReasoning==="max"&&supportsMax(model)?"max":clampedReasoning==="max"?"high":clampedReasoning;return stream(model,context,{...base,reasoningEffort})};function normalizeAzureBaseUrl(baseUrl){let trimmed=baseUrl.trim().replace(/\/+$/,""),url;try{url=new URL(trimmed)}catch{throw new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`)}let isAzureHost=url.hostname.endsWith(".openai.azure.com")||url.hostname.endsWith(".cognitiveservices.azure.com")||url.hostname.endsWith(".ai.azure.com"),normalizedPath=url.pathname.replace(/\/+$/,"");return isAzureHost&&(normalizedPath===""||normalizedPath==="/"||normalizedPath==="/openai"||normalizedPath==="/openai/v1/responses")&&(url.pathname="/openai/v1",url.search=""),url.toString().replace(/\/+$/,"")}function buildDefaultBaseUrl(resourceName){return`https://${resourceName}.openai.azure.com/openai/v1`}function resolveAzureConfig(model,options){let apiVersion=options?.azureApiVersion||getProviderEnvValue("AZURE_OPENAI_API_VERSION",options?.env)||DEFAULT_AZURE_API_VERSION,baseUrl=options?.azureBaseUrl?.trim()||getProviderEnvValue("AZURE_OPENAI_BASE_URL",options?.env)?.trim()||void 0,resourceName=options?.azureResourceName||getProviderEnvValue("AZURE_OPENAI_RESOURCE_NAME",options?.env),resolvedBaseUrl=baseUrl;if(!resolvedBaseUrl&&resourceName&&(resolvedBaseUrl=buildDefaultBaseUrl(resourceName)),!resolvedBaseUrl&&model.baseUrl&&(resolvedBaseUrl=model.baseUrl),!resolvedBaseUrl)throw new Error("Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.");return{baseUrl:normalizeAzureBaseUrl(resolvedBaseUrl),apiVersion}}function createClient(model,apiKey,options){let headers={"User-Agent":getPiUserAgent(),...model.headers};options?.headers&&Object.assign(headers,options.headers);let{baseUrl,apiVersion}=resolveAzureConfig(model,options);return new AzureOpenAI({apiKey,apiVersion,dangerouslyAllowBrowser:!0,fetch:options?.fetch,defaultHeaders:headers,baseURL:baseUrl})}function buildParams(model,context,options,deploymentName,grammarToolInputProperties=createGrammarToolInputProperties(getDeclaredTools(context.messages),model.compat?.supportsOpenAIGrammarTools??!1)){let requestedReasoningEffort=options?.reasoningEffort??(options?.reasoningSummary?"medium":void 0),mappedReasoningEffort=requestedReasoningEffort===void 0?void 0:model.thinkingLevelMap?.[requestedReasoningEffort],reasoningEffort=mappedReasoningEffort===void 0?requestedReasoningEffort:mappedReasoningEffort,reasoningRequested=reasoningEffort!=null,reasoningUnavailable=reasoningEffort===null,supportsAdditionalTools=model.compat?.supportsAdditionalTools??!1,supportsToolSearch=model.compat?.supportsToolSearch??!1,transcriptTools=resolveTranscriptTools(context.messages,supportsAdditionalTools||supportsToolSearch),messages=convertResponsesMessages(model,context,AZURE_TOOL_CALL_PROVIDERS,{grammarToolInputProperties,supportsMidConvoSystemMessages:model.compat?.supportsMidConvoSystemMessages??!1,supportsAdditionalTools,supportsToolSearch,toolOptions:{supportsStrictMode:model.compat?.supportsStrictMode??!0,supportsOpenAIGrammarTools:model.compat?.supportsOpenAIGrammarTools??!1}}),params={model:deploymentName,input:messages,stream:!0,...(options?.cacheRetention??model.cacheRetention)==="none"?{}:{prompt_cache_key:deriveOpenAIPromptCacheKey(model.id,context)},store:!1};return options?.maxTokens&&(params.max_output_tokens=Math.max(options.maxTokens,OPENAI_RESPONSES_MIN_OUTPUT_TOKENS)),options?.temperature!==void 0&&(params.temperature=options?.temperature),transcriptTools.requestTools.length>0&&(params.tools=convertResponsesTools(transcriptTools.requestTools,{supportsStrictMode:model.compat?.supportsStrictMode??!0,supportsOpenAIGrammarTools:model.compat?.supportsOpenAIGrammarTools??!1})),options?.toolChoice!==void 0&&(params.tool_choice=options.toolChoice),model.reasoning&&(reasoningRequested?(params.reasoning={effort:reasoningEffort,...options?.reasoningSummary===null?{}:{summary:options?.reasoningSummary||"auto"}},params.include=["reasoning.encrypted_content"]):!reasoningUnavailable&&model.thinkingLevelMap?.off!==null&&(params.reasoning={effort:model.thinkingLevelMap?.off??"none"})),Object.assign(params,model.samplingParams,options?.samplingParams),params}export{stream,streamSimple};
2
+ import{AzureOpenAI}from"./chunk-CD2HJK4C.js";import{getPiUserAgent}from"./chunk-QTG7MY2X.js";import{buildBaseOptions}from"./chunk-A7HSTZ5T.js";import{retryProviderRequest}from"./chunk-GIT63LXN.js";import{deriveOpenAIPromptCacheKey}from"./chunk-2IKL4F24.js";import{formatProviderError,normalizeProviderError}from"./chunk-AC72EWI5.js";import"./chunk-RQFD6LG2.js";import{convertResponsesMessages,convertResponsesTools,processResponsesStream}from"./chunk-PWTXZXHH.js";import"./chunk-GVSBCJFI.js";import"./chunk-HK46JMSC.js";import{getProviderEnvValue}from"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import{createGrammarToolInputProperties}from"./chunk-UAOOH2V7.js";import"./chunk-WDTJ6JKE.js";import{clampThinkingLevel,getDeclaredTools,resolveTranscript,resolveTranscriptTools,supportsMax}from"./chunk-OH5TKHW7.js";import{AssistantMessageEventStream}from"./chunk-NDNQ23SK.js";import"./chunk-JGKH3D6W.js";import"./chunk-3SASTB6Y.js";import{headersToRecord}from"./chunk-PJ34QVL5.js";import"./chunk-IKOFCODM.js";var DEFAULT_AZURE_API_VERSION="v1",AZURE_TOOL_CALL_PROVIDERS=new Set(["openai","chatgpt-subscription","opencode","azure-openai-responses"]),OPENAI_RESPONSES_MIN_OUTPUT_TOKENS=16;function parseDeploymentNameMap(value){let map=new Map;if(!value)return map;for(let entry of value.split(",")){let trimmed=entry.trim();if(!trimmed)continue;let[modelId,deploymentName]=trimmed.split("=",2);!modelId||!deploymentName||map.set(modelId.trim(),deploymentName.trim())}return map}function resolveDeploymentName(model,options){return options?.azureDeploymentName?options.azureDeploymentName:parseDeploymentNameMap(getProviderEnvValue("AZURE_OPENAI_DEPLOYMENT_NAME_MAP",options?.env)).get(model.id)||model.id}function formatAzureOpenAIError(error){return formatProviderError(normalizeProviderError(error),"Azure OpenAI API error")}var stream=(model,context,options)=>{let stream2=new AssistantMessageEventStream({captureBlocks:!0}),normalizedContext=resolveTranscript(context,model.compat?.supportsMidConvoSystemMessages);return(async()=>{let deploymentName=resolveDeploymentName(model,options),output={role:"assistant",content:[],api:"azure-openai-responses",provider:model.provider,model:model.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};try{let apiKey=options?.apiKey;if(!apiKey)throw new Error(`No API key for provider: ${model.provider}`);let client=createClient(model,apiKey,options),grammarToolInputProperties=createGrammarToolInputProperties(getDeclaredTools(normalizedContext.messages),model.compat?.supportsOpenAIGrammarTools??!1),params=buildParams(model,normalizedContext,options,deploymentName,grammarToolInputProperties),nextParams=await options?.onPayload?.(params,model);nextParams!==void 0&&(params=nextParams);let requestOptions={...options?.signal?{signal:options.signal}:{},...options?.timeoutMs!==void 0?{timeout:options.timeoutMs}:{},maxRetries:0},{data:openaiStream,response}=await retryProviderRequest(()=>client.responses.create(params,requestOptions).withResponse(),{maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,signal:options?.signal});if(await options?.onResponse?.({status:response.status,headers:headersToRecord(response.headers)},model),stream2.push({type:"start",partial:output}),await processResponsesStream(openaiStream,output,stream2,model,{onProviderStreamEvent:options?.onProviderStreamEvent,grammarToolInputProperties}),options?.signal?.aborted)throw new Error("Request was aborted");if(output.stopReason==="pending")throw new Error("Azure OpenAI Responses stream ended without a stop reason");if(output.stopReason==="aborted"||output.stopReason==="error")throw new Error(output.errorMessage||"An unknown error occurred");stream2.push({type:"done",reason:output.stopReason,message:output}),stream2.end()}catch(error){for(let block of output.content)delete block.index,delete block.partialJson,delete block.customInput;output.stopReason=options?.signal?.aborted?"aborted":"error",output.errorMessage=formatAzureOpenAIError(error),stream2.push({type:"error",reason:output.stopReason,error:output}),stream2.end()}})(),stream2},streamSimple=(model,context,options)=>{let apiKey=options?.apiKey;if(!apiKey)throw new Error(`No API key for provider: ${model.provider}`);let base={...buildBaseOptions(model,context,options,apiKey),toolChoice:options?.toolChoice},clampedReasoning=options?.reasoning?clampThinkingLevel(model,options.reasoning):void 0,reasoningEffort=clampedReasoning==="off"?void 0:clampedReasoning==="max"&&supportsMax(model)?"max":clampedReasoning==="max"?"high":clampedReasoning;return stream(model,context,{...base,reasoningEffort})};function normalizeAzureBaseUrl(baseUrl){let trimmed=baseUrl.trim().replace(/\/+$/,""),url;try{url=new URL(trimmed)}catch{throw new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`)}let isAzureHost=url.hostname.endsWith(".openai.azure.com")||url.hostname.endsWith(".cognitiveservices.azure.com")||url.hostname.endsWith(".ai.azure.com"),normalizedPath=url.pathname.replace(/\/+$/,"");return isAzureHost&&(normalizedPath===""||normalizedPath==="/"||normalizedPath==="/openai"||normalizedPath==="/openai/v1/responses")&&(url.pathname="/openai/v1",url.search=""),url.toString().replace(/\/+$/,"")}function buildDefaultBaseUrl(resourceName){return`https://${resourceName}.openai.azure.com/openai/v1`}function resolveAzureConfig(model,options){let apiVersion=options?.azureApiVersion||getProviderEnvValue("AZURE_OPENAI_API_VERSION",options?.env)||DEFAULT_AZURE_API_VERSION,baseUrl=options?.azureBaseUrl?.trim()||getProviderEnvValue("AZURE_OPENAI_BASE_URL",options?.env)?.trim()||void 0,resourceName=options?.azureResourceName||getProviderEnvValue("AZURE_OPENAI_RESOURCE_NAME",options?.env),resolvedBaseUrl=baseUrl;if(!resolvedBaseUrl&&resourceName&&(resolvedBaseUrl=buildDefaultBaseUrl(resourceName)),!resolvedBaseUrl&&model.baseUrl&&(resolvedBaseUrl=model.baseUrl),!resolvedBaseUrl)throw new Error("Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.");return{baseUrl:normalizeAzureBaseUrl(resolvedBaseUrl),apiVersion}}function createClient(model,apiKey,options){let headers={"User-Agent":getPiUserAgent(),...model.headers};options?.headers&&Object.assign(headers,options.headers);let{baseUrl,apiVersion}=resolveAzureConfig(model,options);return new AzureOpenAI({apiKey,apiVersion,dangerouslyAllowBrowser:!0,fetch:options?.fetch,defaultHeaders:headers,baseURL:baseUrl})}function buildParams(model,context,options,deploymentName,grammarToolInputProperties=createGrammarToolInputProperties(getDeclaredTools(context.messages),model.compat?.supportsOpenAIGrammarTools??!1)){let requestedReasoningEffort=options?.reasoningEffort??(options?.reasoningSummary?"medium":void 0),mappedReasoningEffort=requestedReasoningEffort===void 0?void 0:model.thinkingLevelMap?.[requestedReasoningEffort],reasoningEffort=mappedReasoningEffort===void 0?requestedReasoningEffort:mappedReasoningEffort,reasoningRequested=reasoningEffort!=null,reasoningUnavailable=reasoningEffort===null,supportsAdditionalTools=model.compat?.supportsAdditionalTools??!1,supportsToolSearch=model.compat?.supportsToolSearch??!1,transcriptTools=resolveTranscriptTools(context.messages,supportsAdditionalTools||supportsToolSearch),messages=convertResponsesMessages(model,context,AZURE_TOOL_CALL_PROVIDERS,{grammarToolInputProperties,supportsMidConvoSystemMessages:model.compat?.supportsMidConvoSystemMessages??!1,supportsAdditionalTools,supportsToolSearch,toolOptions:{supportsStrictMode:model.compat?.supportsStrictMode??!0,supportsOpenAIGrammarTools:model.compat?.supportsOpenAIGrammarTools??!1}}),params={model:deploymentName,input:messages,stream:!0,...(options?.cacheRetention??model.cacheRetention)==="none"?{}:{prompt_cache_key:deriveOpenAIPromptCacheKey(model.id,context)},store:!1};return options?.maxTokens&&(params.max_output_tokens=Math.max(options.maxTokens,OPENAI_RESPONSES_MIN_OUTPUT_TOKENS)),options?.temperature!==void 0&&(params.temperature=options?.temperature),transcriptTools.requestTools.length>0&&(params.tools=convertResponsesTools(transcriptTools.requestTools,{supportsStrictMode:model.compat?.supportsStrictMode??!0,supportsOpenAIGrammarTools:model.compat?.supportsOpenAIGrammarTools??!1})),options?.toolChoice!==void 0&&(params.tool_choice=options.toolChoice),model.reasoning&&(reasoningRequested?(params.reasoning={effort:reasoningEffort,...options?.reasoningSummary===null?{}:{summary:options?.reasoningSummary||"auto"}},params.include=["reasoning.encrypted_content"]):!reasoningUnavailable&&model.thinkingLevelMap?.off!==null&&(params.reasoning={effort:model.thinkingLevelMap?.off??"none"})),Object.assign(params,model.samplingParams,options?.samplingParams),params}export{stream,streamSimple};
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{Text,truncateToWidth,visibleWidth}from"./chunk-4PMRUR4L.js";import{rotateLogIfNeeded}from"./chunk-LPYBKMPT.js";import{getShellConfig}from"./chunk-JJYN347Z.js";import{engineTrustAction}from"./chunk-R7J5TEYK.js";import{redactSecrets}from"./chunk-62OVOJPI.js";import{HOST_CALL_KINDS,TOOL_CHILD_LIMITS,connectChannel,isRefId,isStaleExtensionContextError}from"./chunk-IHES3JES.js";import{APP_NAME,envValue,getAgentDir}from"./chunk-SODMQEHO.js";import{typebox_exports}from"./chunk-MIENF2YK.js";import{TOOL_CHILD_LEDGER_ENV,TOOL_CHILD_REENTRY_ENV,TOOL_CHILD_REFS_ROOT_ENV,rememberToolChildReentry,scrubToolChildEnv,toolChildReentry}from"./chunk-OXNWERO4.js";import{BACKGROUND_START_GRACE_MS,DEFAULT_COLS,DEFAULT_MAX_SESSIONS,DEFAULT_ROWS,FOREGROUND_ENV_OVERRIDES,KILLED_SESSION_EXIT_GRACE_MS,SecretOutputRedactor,TERMINAL_BASH_TOOL,TERMINAL_INPUT_TOOL,TERMINAL_KILL_TOOL,TERMINAL_OUTPUT_TOOL,TERMINAL_RESIZE_TOOL,encodeKeys,loadPty,safeRegExp}from"./chunk-AOTHPTMU.js";import{processIsRunning,processStartTimeMs,readProcessStartTime,sameProcessStartMs}from"./chunk-O5RYI3IW.js";import{adoptedEngineTrust}from"./chunk-RFFMEA4B.js";var ToolChildJobError=class extends Error{constructor(code,message){super(message),this.code=code,this.name="ToolChildJobError"}};var WakeAdmissionError=class extends Error{constructor(bytes){super(`wake_too_large: ${bytes} bytes exceeds the ${TOOL_CHILD_LIMITS.wakePendingBytes}-byte pending budget`),this.code="wake_too_large",this.name="WakeAdmissionError"}},WakeAdmission=class{#pending=new Map;#blocked=[];#pendingBytes=0;get pending(){return this.#pending.size}get blocked(){return this.#blocked.length}send(wakeId,bytes){return bytes>TOOL_CHILD_LIMITS.wakePendingBytes?Promise.reject(new WakeAdmissionError(bytes)):this.#blocked.length===0&&this.#fits(bytes)?(this.#admit(wakeId,bytes),Promise.resolve()):new Promise(release=>{this.#blocked.push({wakeId,bytes,release})})}ack(wakeId){let bytes=this.#pending.get(wakeId);if(bytes!==void 0){this.#pending.delete(wakeId),this.#pendingBytes-=bytes;for(let next=this.#blocked[0];next!==void 0&&this.#fits(next.bytes);next=this.#blocked[0])this.#blocked.shift(),this.#admit(next.wakeId,next.bytes),next.release()}}#fits(bytes){return this.#pending.size<TOOL_CHILD_LIMITS.wakePending&&this.#pendingBytes+bytes<=TOOL_CHILD_LIMITS.wakePendingBytes}#admit(wakeId,bytes){this.#pending.set(wakeId,bytes),this.#pendingBytes+=bytes}};function hostCallCapacity(){return TOOL_CHILD_LIMITS.HOST_CALL_ACTIVE+TOOL_CHILD_LIMITS.HOST_CALL_WAITING}var HostCallAdmission=class{#active=new Set;#waiting=[];get active(){return this.#active.size}get waiting(){return this.#waiting.length}submit(callId){return this.#active.has(callId)||this.#waiting.includes(callId)?refuse(callId,"host_call_duplicate"):this.#active.size<TOOL_CHILD_LIMITS.HOST_CALL_ACTIVE&&this.#waiting.length===0?(this.#active.add(callId),{state:"active"}):this.#active.size+this.#waiting.length>=hostCallCapacity()?refuse(callId,"host_call_capacity"):(this.#waiting.push(callId),{state:"waiting"})}settle(callId){if(!this.#active.delete(callId)){let index=this.#waiting.indexOf(callId);index>=0&&this.#waiting.splice(index,1);return}let next=this.#waiting.shift();return next!==void 0&&this.#active.add(next),next}};function refuse(callId,code){return{state:"refused",frame:{type:"host_call_refused",callId,code}}}import{createHash,randomBytes}from"node:crypto";import{createReadStream}from"node:fs";import{mkdir,readFile,rm as rm2,stat,writeFile}from"node:fs/promises";import{dirname}from"node:path";import{readdir,rm}from"node:fs/promises";import{join}from"node:path";function refGenerationDir(root,generation){return join(root,`gen-${generation}`)}function refFilePath(root,ref){if(!isRefId(ref.refId))throw new Error(`invalid ref id: ${JSON.stringify(ref.refId)}`);return join(refGenerationDir(root,ref.generation),"refs",ref.refId)}async function teardownRefGeneration(root,generation){await rm(refGenerationDir(root,generation),{recursive:!0,force:!0})}var PayloadRefError=class extends Error{constructor(code,message,reason){super(`${code}: ${message}`),this.name="PayloadRefError",this.code=code,this.reason=reason}},PayloadRefWriter=class{#root;#now;#pending=new Map;#ownedBytes=0;constructor(options){this.generation=options.generation,this.budget=options.budget??TOOL_CHILD_LIMITS.refsBudget,this.#root=options.root,this.#now=options.now??Date.now}get ownedBytes(){return this.#ownedBytes}async create(payload){let size=payload.byteLength;if(this.#ownedBytes+size>this.budget)throw new PayloadRefError("ref_budget_exceeded",`${size} bytes on top of ${this.#ownedBytes} owned exceeds ${this.budget}`);this.#ownedBytes+=size;let ref={refId:randomBytes(12).toString("hex"),generation:this.generation,bytes:size,sha256:createHash("sha256").update(payload).digest("hex")},path=refFilePath(this.#root,ref);try{await mkdir(dirname(path),{recursive:!0,mode:448}),await writeFile(path,payload,{flag:"wx",mode:384})}catch(error){throw this.#ownedBytes-=size,await rm2(path,{force:!0}),error}return this.#pending.set(ref.refId,{bytes:size,createdAtMs:this.#now()}),ref}async handle(control){let pending=this.#pending.get(control.refId);pending!==void 0&&(this.#pending.delete(control.refId),this.#ownedBytes-=pending.bytes,control.type==="ref_nack"&&await rm2(refFilePath(this.#root,{refId:control.refId,generation:this.generation}),{force:!0}))}pendingIds(){return[...this.#pending.keys()]}overdue(){let deadline=this.#now()-TOOL_CHILD_LIMITS.refAckMs;return[...this.#pending].filter(([,ref])=>ref.createdAtMs<=deadline).map(([refId])=>refId)}async teardown(){this.#pending.clear(),this.#ownedBytes=0,await teardownRefGeneration(this.#root,this.generation)}},isMissingFile=error=>error instanceof Error&&"code"in error&&(error.code==="ENOENT"||error.code==="ENOTDIR");async function hashFile(path,signal){let hash=createHash("sha256");for await(let chunk of createReadStream(path)){if(signal?.aborted)return"cancelled";hash.update(chunk)}return hash.digest("hex")}var PayloadRefReader=class{#root;#generation;#budget;#send;#owned=new Map;#ownedBytes=0;constructor(options){this.#root=options.root,this.#generation=options.generation,this.#budget=options.budget??TOOL_CHILD_LIMITS.refsBudget,this.#send=options.send}async accept(ref,signal){let reason=await this.#verify(ref,signal);return reason!==void 0?(this.refuse(ref,reason),{ok:!1,reason}):(this.#owned.set(ref.refId,ref),this.#ownedBytes+=ref.bytes,this.#send({type:"ref_ack",refId:ref.refId}),{ok:!0})}refuse(ref,reason){this.#owned.has(ref.refId)||this.#send({type:"ref_nack",refId:ref.refId,reason})}async consume(refId){let ref=this.#owned.get(refId);if(ref===void 0)throw new PayloadRefError("ref_not_owned",`ref ${refId} is not owned by this side`);let path=refFilePath(this.#root,ref),bytes=await readFile(path);return await rm2(path,{force:!0}),this.#owned.delete(refId),this.#ownedBytes-=ref.bytes,bytes}ownedIds(){return[...this.#owned.keys()]}async#verify(ref,signal){if(signal?.aborted)return"cancelled";if(ref.generation!==this.#generation||!isRefId(ref.refId)||this.#owned.has(ref.refId))return"foreign";if(this.#ownedBytes+ref.bytes>this.#budget)return"budget";let path=refFilePath(this.#root,ref);try{if((await stat(path)).size!==ref.bytes)return"corrupt";let digest=await hashFile(path,signal);return digest==="cancelled"?"cancelled":digest===ref.sha256?void 0:"corrupt"}catch(error){if(isMissingFile(error))return"missing";throw error}}};async function packPayload(value,writer){let normalized=value===void 0?null:value,json=JSON.stringify(normalized);return json===void 0||Buffer.byteLength(json,"utf8")<=TOOL_CHILD_LIMITS.REF_THRESHOLD?{inline:!0,value:normalized}:{inline:!1,ref:await writer.create(Buffer.from(json,"utf8"))}}async function unpackPayload(ref,reader,signal){let acceptance=await reader.accept(ref,signal);if(!acceptance.ok)throw new PayloadRefError("ref_rejected",`ref ${ref.refId} was refused (${acceptance.reason})`,acceptance.reason);let bytes=await reader.consume(ref.refId);return JSON.parse(Buffer.from(bytes.buffer,bytes.byteOffset,bytes.byteLength).toString("utf8"))}var ChildHostCalls=class{#channel;#admissions=new Map;#pending=new Map;#refs;#next=0;constructor(channel,refs){this.#channel=channel,this.#refs=refs}load(jobId){let admission=this.#admissions.get(jobId);return{active:admission?.active??0,waiting:admission?.waiting??0}}async call(jobId,target,signal){let label=target.name??target.kind;if(signal.aborted)throw new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`);let callId=`h${++this.#next}`,packed=target.args===void 0||this.#refs===void 0?{inline:!0,value:target.args}:await packPayload(target.args,this.#refs.writer),frame={type:"host_call",callId,jobId,kind:target.kind,...target.name===void 0?{}:{name:target.name},...packed.inline?packed.value===void 0?{}:{args:packed.value}:{argsRef:packed.ref}};if(signal.aborted)throw this.#releaseUnsent(frame),new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`);return new Promise((resolve,reject)=>{let decision=this.#admission(jobId).submit(callId);if(decision.state==="refused"){this.#forgetIdle(jobId),this.#releaseUnsent(frame),reject(new ToolChildJobError(decision.frame.code,`${label}: host call ${callId} refused`));return}let pending={frame,resolve,reject,sent:!1};this.#pending.set(callId,pending),signal.addEventListener("abort",()=>this.#settle(callId,call=>{call.sent||this.#releaseUnsent(call.frame),call.reject(new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`))}),{once:!0}),decision.state==="active"&&this.#send(pending)})}handle(frame){if(frame.type==="host_reply"){let{valueRef}=frame;return this.#settle(frame.callId,call=>{frame.error!==void 0?call.reject(new ToolChildJobError("host_call_failed",frame.error)):valueRef===void 0?call.resolve(frame.value??null):this.#refs===void 0?call.reject(new ToolChildJobError("host_call_failed","a valueRef reply on a side that reads no refs")):unpackPayload(valueRef,this.#refs.reader).then(call.resolve,error=>call.reject(new ToolChildJobError("host_call_failed",error instanceof Error?error.message:String(error))))}),!0}return frame.type==="host_call_refused"?(this.#settle(frame.callId,call=>call.reject(new ToolChildJobError(frame.code,`host call ${frame.callId} refused by the server`))),!0):!1}close(){for(let callId of[...this.#pending.keys()])this.#settle(callId,call=>call.reject(new ToolChildJobError("tool_child_exited","the channel closed")))}#admission(jobId){let admission=this.#admissions.get(jobId);return admission===void 0&&(admission=new HostCallAdmission,this.#admissions.set(jobId,admission)),admission}#forgetIdle(jobId){let admission=this.#admissions.get(jobId);admission!==void 0&&admission.active===0&&admission.waiting===0&&this.#admissions.delete(jobId)}#send(call){call.sent=!0,this.#channel.send(call.frame)}#releaseUnsent(frame){frame.argsRef!==void 0&&this.#refs?.writer.handle({type:"ref_nack",refId:frame.argsRef.refId,reason:"cancelled"})}#settle(callId,apply){let call=this.#pending.get(callId);if(call===void 0)return;this.#pending.delete(callId);let{jobId}=call.frame,promoted=this.#admissions.get(jobId)?.settle(callId);if(this.#forgetIdle(jobId),apply(call),promoted!==void 0){let next=this.#pending.get(promoted);next!==void 0&&this.#send(next)}}};var JobUpdates=class{#jobId;#channel;#writer;#window;#nextSeq=0;#acked=0;#waiters=[];#ended=!1;#tail=Promise.resolve();constructor(options){this.#jobId=options.jobId,this.#channel=options.channel,this.#writer=options.writer,this.#window=options.window??TOOL_CHILD_LIMITS.updatesInFlight}update(value){let sent=this.#tail.then(()=>this.#send(value));return this.#tail=sent.catch(()=>{}),sent}async#send(value){for(;!this.#ended&&this.#nextSeq-this.#acked>=this.#window;)await new Promise(resolve=>this.#waiters.push(resolve));if(this.#ended)throw new Error(`update after job ${this.#jobId} ended`);let packed=this.#writer===void 0?{inline:!0,value}:await packPayload(value,this.#writer);if(this.#ended)throw new Error(`update after job ${this.#jobId} ended`);let seq=++this.#nextSeq;this.#channel.send(packed.inline?{type:"update",jobId:this.#jobId,seq,...packed.value===void 0?{}:{value:packed.value}}:{type:"update",jobId:this.#jobId,seq,valueRef:packed.ref})}acked(seq){seq<=this.#acked||(this.#acked=Math.min(seq,this.#nextSeq),this.#wake())}end(){this.#ended=!0,this.#wake()}#wake(){for(let resolve of this.#waiters.splice(0))resolve()}};var BarrierClock=class _BarrierClock{constructor(buffer){if(buffer.byteLength%Int32Array.BYTES_PER_ELEMENT!==0)throw new Error("barrier clock buffer is misaligned");let length=buffer.byteLength/Int32Array.BYTES_PER_ELEMENT;if(length<5||(length-1)%4!==0)throw new Error("barrier clock buffer has no slots");this.buffer=buffer,this.cells=new Int32Array(buffer),this.slots=(length-1)/4}static create(slots=256){if(!Number.isInteger(slots)||slots<1)throw new Error(`barrier clock needs at least one slot, got ${slots}`);return new _BarrierClock(new SharedArrayBuffer((1+slots*4)*Int32Array.BYTES_PER_ELEMENT))}tick(){return Atomics.add(this.cells,0,1)+1}claimSlot(){for(let slot=0;slot<this.slots;slot++)if(Atomics.compareExchange(this.cells,this.index(slot,3),0,1)===0)return Atomics.store(this.cells,this.index(slot,0),0),Atomics.store(this.cells,this.index(slot,1),0),Atomics.store(this.cells,this.index(slot,2),0),slot}releaseSlot(slot){Atomics.store(this.cells,this.index(slot,3),0)}recordAck(slot){let tick=this.tick();return Atomics.store(this.cells,this.index(slot,0),tick),Atomics.notify(this.cells,this.index(slot,0)),tick}recordInvoke(slot){let ackTick=Atomics.load(this.cells,this.index(slot,0)),invokeTick=this.tick();return Atomics.store(this.cells,this.index(slot,1),invokeTick),Atomics.add(this.cells,this.index(slot,2),1),{ackTick:ackTick===0?null:ackTick,invokeTick}}waitForAck(slot,timeoutMs=Number.POSITIVE_INFINITY){let at=this.index(slot,0);for(;Atomics.load(this.cells,at)===0;)if(Atomics.wait(this.cells,at,0,timeoutMs)==="timed-out")return"timed-out";return"acked"}read(slot){let ackTick=Atomics.load(this.cells,this.index(slot,0)),invokeTick=Atomics.load(this.cells,this.index(slot,1));return{ackTick:ackTick===0?null:ackTick,invokeTick:invokeTick===0?null:invokeTick,invocations:Atomics.load(this.cells,this.index(slot,2))}}index(slot,field){if(!Number.isInteger(slot)||slot<0||slot>=this.slots)throw new Error(`no barrier slot ${slot}`);return 1+slot*4+field}};function proofIsOrdered(proof){return proof.ackTick!==null&&proof.ackTick<proof.invokeTick}import{randomUUID}from"node:crypto";import{existsSync,readdirSync,rmSync,watch}from"node:fs";import{writeFile as writeFile2}from"node:fs/promises";import{join as join2}from"node:path";var PREFIX="SENPI_TOOL_CHILD_TEST_",TEST_CONTROL_DIR_ENV=`${PREFIX}CONTROL_DIR`;function readTestControls(env){let dir=env[TEST_CONTROL_DIR_ENV],value=name=>{let raw=env[`${PREFIX}${name}`];return raw===void 0||raw===""||raw==="0"?void 0:raw};return{enabled:name=>value(name)!==void 0,value,released:file=>dir===void 0?Promise.reject(new Error(`${TEST_CONTROL_DIR_ENV} is not set`)):waitForFile(dir,file),watchPrefix:(prefix,onFile)=>dir===void 0?{ready:Promise.reject(new Error(`${TEST_CONTROL_DIR_ENV} is not set`)),close:()=>{}}:watchPrefix(dir,prefix,onFile)}}function watchPrefix(dir,prefix,onFile){let seen=new Set,report=name=>{!name.startsWith(prefix)||seen.has(name)||(seen.add(name),onFile(name))},sentinel=`.watch-${process.pid}-${randomUUID()}`,resend,live=!1,markReady=()=>{},failReady=()=>{},ready=new Promise((resolve,reject)=>{markReady=resolve,failReady=reject}),watcher=watch(dir,(_event,name)=>{if(name!==null){if(name===sentinel){live=!0,clearTimeout(resend),rmSync(join2(dir,sentinel),{force:!0});for(let existing of readdirSync(dir))report(existing);markReady();return}existsSync(join2(dir,name))&&report(name)}}),touch=()=>{live||writeFile2(join2(dir,sentinel),String(Date.now())).then(()=>{live||(resend=setTimeout(touch,50))},error=>failReady(error))};return touch(),{ready,close:()=>{live=!0,clearTimeout(resend),watcher.close(),rmSync(join2(dir,sentinel),{force:!0})}}}function waitForFile(dir,file){let path=join2(dir,file),sentinel=join2(dir,`.watch-${process.pid}-${randomUUID()}`);return new Promise((resolve,reject)=>{let done=!1,resend,finish=()=>{done||(done=!0,clearTimeout(resend),watcher.close(),rmSync(sentinel,{force:!0}),resolve())},watcher=watch(dir,(_event,name)=>{if(existsSync(path)){finish();return}name!==null&&join2(dir,name)===sentinel&&clearTimeout(resend)}),touch=()=>{done||writeFile2(sentinel,String(Date.now())).then(()=>{done||(existsSync(path)?finish():resend=setTimeout(touch,50))},error=>{done||(done=!0,watcher.close(),reject(error))})};touch()})}var WindowsJobError=class extends Error{constructor(step,win32Error){super(`tool_child_job_assign_failed: ${step} failed (win32 error ${win32Error})`),this.code="tool_child_job_assign_failed",this.name="WindowsJobError",this.win32Error=win32Error}};function extendedLimitInformation(){let info=new Uint8Array(144);return new DataView(info.buffer).setUint32(16,10240,!0),info}var WindowsJob=class _WindowsJob{constructor(kernel,handle){this.closed=!1,this.kernel=kernel,this.handle=handle}static create(kernel){let handle=kernel.CreateJobObjectW(null,null);if(!handle)throw new WindowsJobError("CreateJobObjectW",kernel.GetLastError());let info=extendedLimitInformation();if(kernel.SetInformationJobObject(handle,9,info,info.byteLength)===0){let error=kernel.GetLastError();throw kernel.CloseHandle(handle),new WindowsJobError("SetInformationJobObject",error)}return new _WindowsJob(kernel,handle)}assign(pid){let process2=this.kernel.OpenProcess(4353,0,pid);if(!process2)throw new WindowsJobError("OpenProcess",this.kernel.GetLastError());try{if(this.kernel.AssignProcessToJobObject(this.handle,process2)===0)throw new WindowsJobError("AssignProcessToJobObject",this.kernel.GetLastError());let inJob=new Uint8Array(4);if(this.kernel.IsProcessInJob(process2,this.handle,inJob)===0||new DataView(inJob.buffer).getInt32(0,!0)===0)throw new WindowsJobError("IsProcessInJob",this.kernel.GetLastError())}finally{this.kernel.CloseHandle(process2)}}memberPids(){let list=new Uint8Array(8200);if(this.kernel.QueryInformationJobObject(this.handle,3,list,list.byteLength,null)===0)return[];let view=new DataView(list.buffer),count=Math.min(view.getUint32(4,!0),1024);return Array.from({length:count},(_,index)=>Number(view.getBigUint64(8+index*8,!0)))}terminate(exitCode=1){this.closed||this.kernel.TerminateJobObject(this.handle,exitCode)}close(){this.closed||(this.closed=!0,this.kernel.CloseHandle(this.handle))}};function loadKernel32Job(){if(process.platform!=="win32")return;let ffi=process.getBuiltinModule("bun:ffi");if(ffi===void 0)return;let lib=ffi.dlopen("kernel32.dll",{CreateJobObjectW:{args:["ptr","ptr"],returns:"ptr"},SetInformationJobObject:{args:["ptr","i32","ptr","u32"],returns:"i32"},QueryInformationJobObject:{args:["ptr","i32","ptr","u32","ptr"],returns:"i32"},OpenProcess:{args:["u32","i32","u32"],returns:"ptr"},AssignProcessToJobObject:{args:["ptr","ptr"],returns:"i32"},IsProcessInJob:{args:["ptr","ptr","ptr"],returns:"i32"},TerminateJobObject:{args:["ptr","u32"],returns:"i32"},CloseHandle:{args:["ptr"],returns:"i32"},GetLastError:{args:[],returns:"u32"},GetCurrentProcess:{args:[],returns:"ptr"}}),call=(name,...args)=>{let fn=lib.symbols[name];if(fn===void 0)throw new Error(`kernel32 has no ${name}`);return fn(...args.map(arg=>arg instanceof Uint8Array?ffi.ptr(arg):arg))};return{CreateJobObjectW:()=>call("CreateJobObjectW",null,null),SetInformationJobObject:(job,infoClass,info,length)=>Number(call("SetInformationJobObject",job,infoClass,info,length)),QueryInformationJobObject:(job,infoClass,info,length)=>Number(call("QueryInformationJobObject",job,infoClass,info,length,null)),OpenProcess:(access,inherit,pid)=>call("OpenProcess",access,inherit,pid),AssignProcessToJobObject:(job,process2)=>Number(call("AssignProcessToJobObject",job,process2)),IsProcessInJob:(process2,job,result)=>Number(call("IsProcessInJob",process2,job,result)),TerminateJobObject:(job,exitCode)=>Number(call("TerminateJobObject",job,exitCode)),CloseHandle:handle=>Number(call("CloseHandle",handle)),GetLastError:()=>Number(call("GetLastError")),GetCurrentProcess:()=>call("GetCurrentProcess")}}var defaultInJob;function currentProcessInJob(kernel){if(kernel!==void 0)return queryInJob(kernel);if(defaultInJob===void 0){let loaded=loadKernel32Job();defaultInJob=loaded===void 0?!1:queryInJob(loaded)}return defaultInJob}function queryInJob(kernel){let result=new Uint8Array(4);return kernel.IsProcessInJob(kernel.GetCurrentProcess(),null,result)!==0&&new DataView(result.buffer).getInt32(0,!0)!==0}var FINISHED_SLOT_STATES=256,LaunchGateError=class extends Error{constructor(code,message){super(`${code}: ${message}`),this.name="LaunchGateError",this.code=code}},LaunchGate=class{#channel;#slots=new Map;#finished=new Map;#controls;#next=0;constructor(channel,clock=BarrierClock.create(),env=process.env,creatorInJob=currentProcessInJob){this.#channel=channel,this.clock=clock,this.#controls=readTestControls(env),this.#creatorInJob=creatorInJob}#creatorInJob;started(launchId,pid,breakaway=!1){this.#slots.has(launchId)&&this.#channel.send({type:"command_started",launchId,pid,startedAtMs:Date.now(),creatorInJob:this.#creatorInJob(),breakaway})}get skipsAckWait(){return this.#controls.enabled("SKIP_ACK_WAIT")}request(request){let slot=this.clock.claimSlot();if(slot===void 0)throw new LaunchGateError("tool_child_launch_capacity",`${this.clock.slots} launches in flight`);let launchId=`L${process.pid}-${++this.#next}`,ack,acked=new Promise(resolve=>{ack=resolve});return this.#slots.set(launchId,{slot,ack,lifetime:request.lifetime,request}),this.#channel.send({type:"launch",launchId,...request}),this.#controls.enabled("STOP_AFTER_SPAWN")&&process.kill(process.pid,"SIGSTOP"),{launchId,slot,acked}}adopt(launchId,slot,request){this.#slots.set(launchId,{slot,ack:()=>{},lifetime:request.lifetime,request}),this.#channel.send({type:"launch",launchId,...request})}handleWorker(message){message.kind==="launch"?this.adopt(message.launchId,message.slot,message.request):message.kind==="invoking"?this.invoking(message.launchId):message.kind==="started"?this.started(message.launchId,message.pid,message.breakaway):this.done(message.launchId,{...message.exitCode===void 0?{}:{exitCode:message.exitCode},...message.signal===void 0?{}:{signal:message.signal}})}handle(message){if(message.type==="launch_ack"){let entry=this.#slots.get(message.launchId);return entry!==void 0&&(this.clock.recordAck(entry.slot),entry.ack()),!0}if(message.type==="slot_query"){let entry=this.#slots.get(message.launchId),state=entry===void 0?this.#finished.get(message.launchId)??{ackTick:null,invokeTick:null,invocations:0}:this.clock.read(entry.slot);return this.#channel.send({type:"slot_state",launchId:message.launchId,...state}),!0}return!1}invokeNow(launchId){let entry=this.#slots.get(launchId);if(entry===void 0)throw new LaunchGateError("tool_child_launch_unknown",launchId);this.clock.recordInvoke(entry.slot),this.invoking(launchId)}invoking(launchId){let entry=this.#slots.get(launchId);if(entry===void 0)return;let state=this.clock.read(entry.slot),invokeTick=state.invokeTick;if(invokeTick===null)return;let send=()=>this.#channel.send({type:"launch_proof",launchId,ackTick:state.ackTick,invokeTick}),hold=this.#controls.value("HOLD_LAUNCH_PROOF");if(hold!==void 0&&(hold!=="detached"||entry.lifetime==="detached")){this.#controls.released(`release-proof-${launchId}`).then(send);return}send()}endJobGroups(jobId){let ended=[];for(let[launchId,{request}]of this.#slots)if(!(request.jobId!==jobId||request.lifetime!=="owned"||request.containment!=="own-group")&&!(request.pgid===void 0||request.pgid<=1))try{process.kill(-request.pgid,"SIGKILL"),ended.push({launchId,pgid:request.pgid})}catch{}for(let{launchId}of ended)this.done(launchId,{signal:"SIGKILL"});return ended.map(({pgid})=>pgid)}done(launchId,outcome){let entry=this.#slots.get(launchId);entry!==void 0&&(this.#slots.delete(launchId),this.#finished.set(launchId,this.clock.read(entry.slot)),this.#finished.size>FINISHED_SLOT_STATES&&this.#finished.delete(this.#finished.keys().next().value??""),this.clock.releaseSlot(entry.slot),this.#channel.send({type:"launch_done",launchId,...outcome.exitCode===void 0?{}:{exitCode:outcome.exitCode},...outcome.signal===void 0?{}:{signal:outcome.signal}}))}};import{mkdir as mkdir3,readdir as readdir2,readFile as readFile3,rm as rm4,writeFile as writeFile3}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";import{appendFile,mkdir as mkdir2,open,readFile as readFile2,rm as rm3}from"node:fs/promises";import{dirname as dirname2,join as join3}from"node:path";function generationLedgerPath(dir,generation){return join3(dir,`g${generation}`,"descendants.ledger")}var DescendantsLedger=class{#path;#durableDir=!1;#entries=new Map;constructor(path){this.#path=path}get path(){return this.#path}entries(){return[...this.#entries.values()]}async append(entry){if(!this.#durableDir){let directory=dirname2(this.#path);await mkdir2(directory,{recursive:!0,mode:448}),await(await open(this.#path,"a",384)).close(),await syncDirectory(directory),await syncDirectory(dirname2(directory)),this.#durableDir=!0}let handle=await open(this.#path,"a",384);try{await handle.write(`${JSON.stringify(entry)}
2
+ import{Text,truncateToWidth,visibleWidth}from"./chunk-4PMRUR4L.js";import{rotateLogIfNeeded}from"./chunk-LPYBKMPT.js";import{getShellConfig}from"./chunk-ZJUL5ODW.js";import{engineTrustAction}from"./chunk-R7J5TEYK.js";import{redactSecrets}from"./chunk-62OVOJPI.js";import{HOST_CALL_KINDS,TOOL_CHILD_LIMITS,connectChannel,isRefId,isStaleExtensionContextError}from"./chunk-IHES3JES.js";import{APP_NAME,envValue,getAgentDir}from"./chunk-SODMQEHO.js";import{typebox_exports}from"./chunk-MIENF2YK.js";import{TOOL_CHILD_LEDGER_ENV,TOOL_CHILD_REENTRY_ENV,TOOL_CHILD_REFS_ROOT_ENV,rememberToolChildReentry,scrubToolChildEnv,toolChildReentry}from"./chunk-OXNWERO4.js";import{BACKGROUND_START_GRACE_MS,DEFAULT_COLS,DEFAULT_MAX_SESSIONS,DEFAULT_ROWS,FOREGROUND_ENV_OVERRIDES,KILLED_SESSION_EXIT_GRACE_MS,SecretOutputRedactor,TERMINAL_BASH_TOOL,TERMINAL_INPUT_TOOL,TERMINAL_KILL_TOOL,TERMINAL_OUTPUT_TOOL,TERMINAL_RESIZE_TOOL,encodeKeys,loadPty,safeRegExp}from"./chunk-AOTHPTMU.js";import{processIsRunning,processStartTimeMs,readProcessStartTime,sameProcessStartMs}from"./chunk-O5RYI3IW.js";import{adoptedEngineTrust}from"./chunk-RFFMEA4B.js";var ToolChildJobError=class extends Error{constructor(code,message){super(message),this.code=code,this.name="ToolChildJobError"}};var WakeAdmissionError=class extends Error{constructor(bytes){super(`wake_too_large: ${bytes} bytes exceeds the ${TOOL_CHILD_LIMITS.wakePendingBytes}-byte pending budget`),this.code="wake_too_large",this.name="WakeAdmissionError"}},WakeAdmission=class{#pending=new Map;#blocked=[];#pendingBytes=0;get pending(){return this.#pending.size}get blocked(){return this.#blocked.length}send(wakeId,bytes){return bytes>TOOL_CHILD_LIMITS.wakePendingBytes?Promise.reject(new WakeAdmissionError(bytes)):this.#blocked.length===0&&this.#fits(bytes)?(this.#admit(wakeId,bytes),Promise.resolve()):new Promise(release=>{this.#blocked.push({wakeId,bytes,release})})}ack(wakeId){let bytes=this.#pending.get(wakeId);if(bytes!==void 0){this.#pending.delete(wakeId),this.#pendingBytes-=bytes;for(let next=this.#blocked[0];next!==void 0&&this.#fits(next.bytes);next=this.#blocked[0])this.#blocked.shift(),this.#admit(next.wakeId,next.bytes),next.release()}}#fits(bytes){return this.#pending.size<TOOL_CHILD_LIMITS.wakePending&&this.#pendingBytes+bytes<=TOOL_CHILD_LIMITS.wakePendingBytes}#admit(wakeId,bytes){this.#pending.set(wakeId,bytes),this.#pendingBytes+=bytes}};function hostCallCapacity(){return TOOL_CHILD_LIMITS.HOST_CALL_ACTIVE+TOOL_CHILD_LIMITS.HOST_CALL_WAITING}var HostCallAdmission=class{#active=new Set;#waiting=[];get active(){return this.#active.size}get waiting(){return this.#waiting.length}submit(callId){return this.#active.has(callId)||this.#waiting.includes(callId)?refuse(callId,"host_call_duplicate"):this.#active.size<TOOL_CHILD_LIMITS.HOST_CALL_ACTIVE&&this.#waiting.length===0?(this.#active.add(callId),{state:"active"}):this.#active.size+this.#waiting.length>=hostCallCapacity()?refuse(callId,"host_call_capacity"):(this.#waiting.push(callId),{state:"waiting"})}settle(callId){if(!this.#active.delete(callId)){let index=this.#waiting.indexOf(callId);index>=0&&this.#waiting.splice(index,1);return}let next=this.#waiting.shift();return next!==void 0&&this.#active.add(next),next}};function refuse(callId,code){return{state:"refused",frame:{type:"host_call_refused",callId,code}}}import{createHash,randomBytes}from"node:crypto";import{createReadStream}from"node:fs";import{mkdir,readFile,rm as rm2,stat,writeFile}from"node:fs/promises";import{dirname}from"node:path";import{readdir,rm}from"node:fs/promises";import{join}from"node:path";function refGenerationDir(root,generation){return join(root,`gen-${generation}`)}function refFilePath(root,ref){if(!isRefId(ref.refId))throw new Error(`invalid ref id: ${JSON.stringify(ref.refId)}`);return join(refGenerationDir(root,ref.generation),"refs",ref.refId)}async function teardownRefGeneration(root,generation){await rm(refGenerationDir(root,generation),{recursive:!0,force:!0})}var PayloadRefError=class extends Error{constructor(code,message,reason){super(`${code}: ${message}`),this.name="PayloadRefError",this.code=code,this.reason=reason}},PayloadRefWriter=class{#root;#now;#pending=new Map;#ownedBytes=0;constructor(options){this.generation=options.generation,this.budget=options.budget??TOOL_CHILD_LIMITS.refsBudget,this.#root=options.root,this.#now=options.now??Date.now}get ownedBytes(){return this.#ownedBytes}async create(payload){let size=payload.byteLength;if(this.#ownedBytes+size>this.budget)throw new PayloadRefError("ref_budget_exceeded",`${size} bytes on top of ${this.#ownedBytes} owned exceeds ${this.budget}`);this.#ownedBytes+=size;let ref={refId:randomBytes(12).toString("hex"),generation:this.generation,bytes:size,sha256:createHash("sha256").update(payload).digest("hex")},path=refFilePath(this.#root,ref);try{await mkdir(dirname(path),{recursive:!0,mode:448}),await writeFile(path,payload,{flag:"wx",mode:384})}catch(error){throw this.#ownedBytes-=size,await rm2(path,{force:!0}),error}return this.#pending.set(ref.refId,{bytes:size,createdAtMs:this.#now()}),ref}async handle(control){let pending=this.#pending.get(control.refId);pending!==void 0&&(this.#pending.delete(control.refId),this.#ownedBytes-=pending.bytes,control.type==="ref_nack"&&await rm2(refFilePath(this.#root,{refId:control.refId,generation:this.generation}),{force:!0}))}pendingIds(){return[...this.#pending.keys()]}overdue(){let deadline=this.#now()-TOOL_CHILD_LIMITS.refAckMs;return[...this.#pending].filter(([,ref])=>ref.createdAtMs<=deadline).map(([refId])=>refId)}async teardown(){this.#pending.clear(),this.#ownedBytes=0,await teardownRefGeneration(this.#root,this.generation)}},isMissingFile=error=>error instanceof Error&&"code"in error&&(error.code==="ENOENT"||error.code==="ENOTDIR");async function hashFile(path,signal){let hash=createHash("sha256");for await(let chunk of createReadStream(path)){if(signal?.aborted)return"cancelled";hash.update(chunk)}return hash.digest("hex")}var PayloadRefReader=class{#root;#generation;#budget;#send;#owned=new Map;#ownedBytes=0;constructor(options){this.#root=options.root,this.#generation=options.generation,this.#budget=options.budget??TOOL_CHILD_LIMITS.refsBudget,this.#send=options.send}async accept(ref,signal){let reason=await this.#verify(ref,signal);return reason!==void 0?(this.refuse(ref,reason),{ok:!1,reason}):(this.#owned.set(ref.refId,ref),this.#ownedBytes+=ref.bytes,this.#send({type:"ref_ack",refId:ref.refId}),{ok:!0})}refuse(ref,reason){this.#owned.has(ref.refId)||this.#send({type:"ref_nack",refId:ref.refId,reason})}async consume(refId){let ref=this.#owned.get(refId);if(ref===void 0)throw new PayloadRefError("ref_not_owned",`ref ${refId} is not owned by this side`);let path=refFilePath(this.#root,ref),bytes=await readFile(path);return await rm2(path,{force:!0}),this.#owned.delete(refId),this.#ownedBytes-=ref.bytes,bytes}ownedIds(){return[...this.#owned.keys()]}async#verify(ref,signal){if(signal?.aborted)return"cancelled";if(ref.generation!==this.#generation||!isRefId(ref.refId)||this.#owned.has(ref.refId))return"foreign";if(this.#ownedBytes+ref.bytes>this.#budget)return"budget";let path=refFilePath(this.#root,ref);try{if((await stat(path)).size!==ref.bytes)return"corrupt";let digest=await hashFile(path,signal);return digest==="cancelled"?"cancelled":digest===ref.sha256?void 0:"corrupt"}catch(error){if(isMissingFile(error))return"missing";throw error}}};async function packPayload(value,writer){let normalized=value===void 0?null:value,json=JSON.stringify(normalized);return json===void 0||Buffer.byteLength(json,"utf8")<=TOOL_CHILD_LIMITS.REF_THRESHOLD?{inline:!0,value:normalized}:{inline:!1,ref:await writer.create(Buffer.from(json,"utf8"))}}async function unpackPayload(ref,reader,signal){let acceptance=await reader.accept(ref,signal);if(!acceptance.ok)throw new PayloadRefError("ref_rejected",`ref ${ref.refId} was refused (${acceptance.reason})`,acceptance.reason);let bytes=await reader.consume(ref.refId);return JSON.parse(Buffer.from(bytes.buffer,bytes.byteOffset,bytes.byteLength).toString("utf8"))}var ChildHostCalls=class{#channel;#admissions=new Map;#pending=new Map;#refs;#next=0;constructor(channel,refs){this.#channel=channel,this.#refs=refs}load(jobId){let admission=this.#admissions.get(jobId);return{active:admission?.active??0,waiting:admission?.waiting??0}}async call(jobId,target,signal){let label=target.name??target.kind;if(signal.aborted)throw new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`);let callId=`h${++this.#next}`,packed=target.args===void 0||this.#refs===void 0?{inline:!0,value:target.args}:await packPayload(target.args,this.#refs.writer),frame={type:"host_call",callId,jobId,kind:target.kind,...target.name===void 0?{}:{name:target.name},...packed.inline?packed.value===void 0?{}:{args:packed.value}:{argsRef:packed.ref}};if(signal.aborted)throw this.#releaseUnsent(frame),new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`);return new Promise((resolve,reject)=>{let decision=this.#admission(jobId).submit(callId);if(decision.state==="refused"){this.#forgetIdle(jobId),this.#releaseUnsent(frame),reject(new ToolChildJobError(decision.frame.code,`${label}: host call ${callId} refused`));return}let pending={frame,resolve,reject,sent:!1};this.#pending.set(callId,pending),signal.addEventListener("abort",()=>this.#settle(callId,call=>{call.sent||this.#releaseUnsent(call.frame),call.reject(new ToolChildJobError("tool_child_cancelled",`${label}: job cancelled`))}),{once:!0}),decision.state==="active"&&this.#send(pending)})}handle(frame){if(frame.type==="host_reply"){let{valueRef}=frame;return this.#settle(frame.callId,call=>{frame.error!==void 0?call.reject(new ToolChildJobError("host_call_failed",frame.error)):valueRef===void 0?call.resolve(frame.value??null):this.#refs===void 0?call.reject(new ToolChildJobError("host_call_failed","a valueRef reply on a side that reads no refs")):unpackPayload(valueRef,this.#refs.reader).then(call.resolve,error=>call.reject(new ToolChildJobError("host_call_failed",error instanceof Error?error.message:String(error))))}),!0}return frame.type==="host_call_refused"?(this.#settle(frame.callId,call=>call.reject(new ToolChildJobError(frame.code,`host call ${frame.callId} refused by the server`))),!0):!1}close(){for(let callId of[...this.#pending.keys()])this.#settle(callId,call=>call.reject(new ToolChildJobError("tool_child_exited","the channel closed")))}#admission(jobId){let admission=this.#admissions.get(jobId);return admission===void 0&&(admission=new HostCallAdmission,this.#admissions.set(jobId,admission)),admission}#forgetIdle(jobId){let admission=this.#admissions.get(jobId);admission!==void 0&&admission.active===0&&admission.waiting===0&&this.#admissions.delete(jobId)}#send(call){call.sent=!0,this.#channel.send(call.frame)}#releaseUnsent(frame){frame.argsRef!==void 0&&this.#refs?.writer.handle({type:"ref_nack",refId:frame.argsRef.refId,reason:"cancelled"})}#settle(callId,apply){let call=this.#pending.get(callId);if(call===void 0)return;this.#pending.delete(callId);let{jobId}=call.frame,promoted=this.#admissions.get(jobId)?.settle(callId);if(this.#forgetIdle(jobId),apply(call),promoted!==void 0){let next=this.#pending.get(promoted);next!==void 0&&this.#send(next)}}};var JobUpdates=class{#jobId;#channel;#writer;#window;#nextSeq=0;#acked=0;#waiters=[];#ended=!1;#tail=Promise.resolve();constructor(options){this.#jobId=options.jobId,this.#channel=options.channel,this.#writer=options.writer,this.#window=options.window??TOOL_CHILD_LIMITS.updatesInFlight}update(value){let sent=this.#tail.then(()=>this.#send(value));return this.#tail=sent.catch(()=>{}),sent}async#send(value){for(;!this.#ended&&this.#nextSeq-this.#acked>=this.#window;)await new Promise(resolve=>this.#waiters.push(resolve));if(this.#ended)throw new Error(`update after job ${this.#jobId} ended`);let packed=this.#writer===void 0?{inline:!0,value}:await packPayload(value,this.#writer);if(this.#ended)throw new Error(`update after job ${this.#jobId} ended`);let seq=++this.#nextSeq;this.#channel.send(packed.inline?{type:"update",jobId:this.#jobId,seq,...packed.value===void 0?{}:{value:packed.value}}:{type:"update",jobId:this.#jobId,seq,valueRef:packed.ref})}acked(seq){seq<=this.#acked||(this.#acked=Math.min(seq,this.#nextSeq),this.#wake())}end(){this.#ended=!0,this.#wake()}#wake(){for(let resolve of this.#waiters.splice(0))resolve()}};var BarrierClock=class _BarrierClock{constructor(buffer){if(buffer.byteLength%Int32Array.BYTES_PER_ELEMENT!==0)throw new Error("barrier clock buffer is misaligned");let length=buffer.byteLength/Int32Array.BYTES_PER_ELEMENT;if(length<5||(length-1)%4!==0)throw new Error("barrier clock buffer has no slots");this.buffer=buffer,this.cells=new Int32Array(buffer),this.slots=(length-1)/4}static create(slots=256){if(!Number.isInteger(slots)||slots<1)throw new Error(`barrier clock needs at least one slot, got ${slots}`);return new _BarrierClock(new SharedArrayBuffer((1+slots*4)*Int32Array.BYTES_PER_ELEMENT))}tick(){return Atomics.add(this.cells,0,1)+1}claimSlot(){for(let slot=0;slot<this.slots;slot++)if(Atomics.compareExchange(this.cells,this.index(slot,3),0,1)===0)return Atomics.store(this.cells,this.index(slot,0),0),Atomics.store(this.cells,this.index(slot,1),0),Atomics.store(this.cells,this.index(slot,2),0),slot}releaseSlot(slot){Atomics.store(this.cells,this.index(slot,3),0)}recordAck(slot){let tick=this.tick();return Atomics.store(this.cells,this.index(slot,0),tick),Atomics.notify(this.cells,this.index(slot,0)),tick}recordInvoke(slot){let ackTick=Atomics.load(this.cells,this.index(slot,0)),invokeTick=this.tick();return Atomics.store(this.cells,this.index(slot,1),invokeTick),Atomics.add(this.cells,this.index(slot,2),1),{ackTick:ackTick===0?null:ackTick,invokeTick}}waitForAck(slot,timeoutMs=Number.POSITIVE_INFINITY){let at=this.index(slot,0);for(;Atomics.load(this.cells,at)===0;)if(Atomics.wait(this.cells,at,0,timeoutMs)==="timed-out")return"timed-out";return"acked"}read(slot){let ackTick=Atomics.load(this.cells,this.index(slot,0)),invokeTick=Atomics.load(this.cells,this.index(slot,1));return{ackTick:ackTick===0?null:ackTick,invokeTick:invokeTick===0?null:invokeTick,invocations:Atomics.load(this.cells,this.index(slot,2))}}index(slot,field){if(!Number.isInteger(slot)||slot<0||slot>=this.slots)throw new Error(`no barrier slot ${slot}`);return 1+slot*4+field}};function proofIsOrdered(proof){return proof.ackTick!==null&&proof.ackTick<proof.invokeTick}import{randomUUID}from"node:crypto";import{existsSync,readdirSync,rmSync,watch}from"node:fs";import{writeFile as writeFile2}from"node:fs/promises";import{join as join2}from"node:path";var PREFIX="SENPI_TOOL_CHILD_TEST_",TEST_CONTROL_DIR_ENV=`${PREFIX}CONTROL_DIR`;function readTestControls(env){let dir=env[TEST_CONTROL_DIR_ENV],value=name=>{let raw=env[`${PREFIX}${name}`];return raw===void 0||raw===""||raw==="0"?void 0:raw};return{enabled:name=>value(name)!==void 0,value,released:file=>dir===void 0?Promise.reject(new Error(`${TEST_CONTROL_DIR_ENV} is not set`)):waitForFile(dir,file),watchPrefix:(prefix,onFile)=>dir===void 0?{ready:Promise.reject(new Error(`${TEST_CONTROL_DIR_ENV} is not set`)),close:()=>{}}:watchPrefix(dir,prefix,onFile)}}function watchPrefix(dir,prefix,onFile){let seen=new Set,report=name=>{!name.startsWith(prefix)||seen.has(name)||(seen.add(name),onFile(name))},sentinel=`.watch-${process.pid}-${randomUUID()}`,resend,live=!1,markReady=()=>{},failReady=()=>{},ready=new Promise((resolve,reject)=>{markReady=resolve,failReady=reject}),watcher=watch(dir,(_event,name)=>{if(name!==null){if(name===sentinel){live=!0,clearTimeout(resend),rmSync(join2(dir,sentinel),{force:!0});for(let existing of readdirSync(dir))report(existing);markReady();return}existsSync(join2(dir,name))&&report(name)}}),touch=()=>{live||writeFile2(join2(dir,sentinel),String(Date.now())).then(()=>{live||(resend=setTimeout(touch,50))},error=>failReady(error))};return touch(),{ready,close:()=>{live=!0,clearTimeout(resend),watcher.close(),rmSync(join2(dir,sentinel),{force:!0})}}}function waitForFile(dir,file){let path=join2(dir,file),sentinel=join2(dir,`.watch-${process.pid}-${randomUUID()}`);return new Promise((resolve,reject)=>{let done=!1,resend,finish=()=>{done||(done=!0,clearTimeout(resend),watcher.close(),rmSync(sentinel,{force:!0}),resolve())},watcher=watch(dir,(_event,name)=>{if(existsSync(path)){finish();return}name!==null&&join2(dir,name)===sentinel&&clearTimeout(resend)}),touch=()=>{done||writeFile2(sentinel,String(Date.now())).then(()=>{done||(existsSync(path)?finish():resend=setTimeout(touch,50))},error=>{done||(done=!0,watcher.close(),reject(error))})};touch()})}var WindowsJobError=class extends Error{constructor(step,win32Error){super(`tool_child_job_assign_failed: ${step} failed (win32 error ${win32Error})`),this.code="tool_child_job_assign_failed",this.name="WindowsJobError",this.win32Error=win32Error}};function extendedLimitInformation(){let info=new Uint8Array(144);return new DataView(info.buffer).setUint32(16,10240,!0),info}var WindowsJob=class _WindowsJob{constructor(kernel,handle){this.closed=!1,this.kernel=kernel,this.handle=handle}static create(kernel){let handle=kernel.CreateJobObjectW(null,null);if(!handle)throw new WindowsJobError("CreateJobObjectW",kernel.GetLastError());let info=extendedLimitInformation();if(kernel.SetInformationJobObject(handle,9,info,info.byteLength)===0){let error=kernel.GetLastError();throw kernel.CloseHandle(handle),new WindowsJobError("SetInformationJobObject",error)}return new _WindowsJob(kernel,handle)}assign(pid){let process2=this.kernel.OpenProcess(4353,0,pid);if(!process2)throw new WindowsJobError("OpenProcess",this.kernel.GetLastError());try{if(this.kernel.AssignProcessToJobObject(this.handle,process2)===0)throw new WindowsJobError("AssignProcessToJobObject",this.kernel.GetLastError());let inJob=new Uint8Array(4);if(this.kernel.IsProcessInJob(process2,this.handle,inJob)===0||new DataView(inJob.buffer).getInt32(0,!0)===0)throw new WindowsJobError("IsProcessInJob",this.kernel.GetLastError())}finally{this.kernel.CloseHandle(process2)}}memberPids(){let list=new Uint8Array(8200);if(this.kernel.QueryInformationJobObject(this.handle,3,list,list.byteLength,null)===0)return[];let view=new DataView(list.buffer),count=Math.min(view.getUint32(4,!0),1024);return Array.from({length:count},(_,index)=>Number(view.getBigUint64(8+index*8,!0)))}terminate(exitCode=1){this.closed||this.kernel.TerminateJobObject(this.handle,exitCode)}close(){this.closed||(this.closed=!0,this.kernel.CloseHandle(this.handle))}};function loadKernel32Job(){if(process.platform!=="win32")return;let ffi=process.getBuiltinModule("bun:ffi");if(ffi===void 0)return;let lib=ffi.dlopen("kernel32.dll",{CreateJobObjectW:{args:["ptr","ptr"],returns:"ptr"},SetInformationJobObject:{args:["ptr","i32","ptr","u32"],returns:"i32"},QueryInformationJobObject:{args:["ptr","i32","ptr","u32","ptr"],returns:"i32"},OpenProcess:{args:["u32","i32","u32"],returns:"ptr"},AssignProcessToJobObject:{args:["ptr","ptr"],returns:"i32"},IsProcessInJob:{args:["ptr","ptr","ptr"],returns:"i32"},TerminateJobObject:{args:["ptr","u32"],returns:"i32"},CloseHandle:{args:["ptr"],returns:"i32"},GetLastError:{args:[],returns:"u32"},GetCurrentProcess:{args:[],returns:"ptr"}}),call=(name,...args)=>{let fn=lib.symbols[name];if(fn===void 0)throw new Error(`kernel32 has no ${name}`);return fn(...args.map(arg=>arg instanceof Uint8Array?ffi.ptr(arg):arg))};return{CreateJobObjectW:()=>call("CreateJobObjectW",null,null),SetInformationJobObject:(job,infoClass,info,length)=>Number(call("SetInformationJobObject",job,infoClass,info,length)),QueryInformationJobObject:(job,infoClass,info,length)=>Number(call("QueryInformationJobObject",job,infoClass,info,length,null)),OpenProcess:(access,inherit,pid)=>call("OpenProcess",access,inherit,pid),AssignProcessToJobObject:(job,process2)=>Number(call("AssignProcessToJobObject",job,process2)),IsProcessInJob:(process2,job,result)=>Number(call("IsProcessInJob",process2,job,result)),TerminateJobObject:(job,exitCode)=>Number(call("TerminateJobObject",job,exitCode)),CloseHandle:handle=>Number(call("CloseHandle",handle)),GetLastError:()=>Number(call("GetLastError")),GetCurrentProcess:()=>call("GetCurrentProcess")}}var defaultInJob;function currentProcessInJob(kernel){if(kernel!==void 0)return queryInJob(kernel);if(defaultInJob===void 0){let loaded=loadKernel32Job();defaultInJob=loaded===void 0?!1:queryInJob(loaded)}return defaultInJob}function queryInJob(kernel){let result=new Uint8Array(4);return kernel.IsProcessInJob(kernel.GetCurrentProcess(),null,result)!==0&&new DataView(result.buffer).getInt32(0,!0)!==0}var FINISHED_SLOT_STATES=256,LaunchGateError=class extends Error{constructor(code,message){super(`${code}: ${message}`),this.name="LaunchGateError",this.code=code}},LaunchGate=class{#channel;#slots=new Map;#finished=new Map;#controls;#next=0;constructor(channel,clock=BarrierClock.create(),env=process.env,creatorInJob=currentProcessInJob){this.#channel=channel,this.clock=clock,this.#controls=readTestControls(env),this.#creatorInJob=creatorInJob}#creatorInJob;started(launchId,pid,breakaway=!1){this.#slots.has(launchId)&&this.#channel.send({type:"command_started",launchId,pid,startedAtMs:Date.now(),creatorInJob:this.#creatorInJob(),breakaway})}get skipsAckWait(){return this.#controls.enabled("SKIP_ACK_WAIT")}request(request){let slot=this.clock.claimSlot();if(slot===void 0)throw new LaunchGateError("tool_child_launch_capacity",`${this.clock.slots} launches in flight`);let launchId=`L${process.pid}-${++this.#next}`,ack,acked=new Promise(resolve=>{ack=resolve});return this.#slots.set(launchId,{slot,ack,lifetime:request.lifetime,request}),this.#channel.send({type:"launch",launchId,...request}),this.#controls.enabled("STOP_AFTER_SPAWN")&&process.kill(process.pid,"SIGSTOP"),{launchId,slot,acked}}adopt(launchId,slot,request){this.#slots.set(launchId,{slot,ack:()=>{},lifetime:request.lifetime,request}),this.#channel.send({type:"launch",launchId,...request})}handleWorker(message){message.kind==="launch"?this.adopt(message.launchId,message.slot,message.request):message.kind==="invoking"?this.invoking(message.launchId):message.kind==="started"?this.started(message.launchId,message.pid,message.breakaway):this.done(message.launchId,{...message.exitCode===void 0?{}:{exitCode:message.exitCode},...message.signal===void 0?{}:{signal:message.signal}})}handle(message){if(message.type==="launch_ack"){let entry=this.#slots.get(message.launchId);return entry!==void 0&&(this.clock.recordAck(entry.slot),entry.ack()),!0}if(message.type==="slot_query"){let entry=this.#slots.get(message.launchId),state=entry===void 0?this.#finished.get(message.launchId)??{ackTick:null,invokeTick:null,invocations:0}:this.clock.read(entry.slot);return this.#channel.send({type:"slot_state",launchId:message.launchId,...state}),!0}return!1}invokeNow(launchId){let entry=this.#slots.get(launchId);if(entry===void 0)throw new LaunchGateError("tool_child_launch_unknown",launchId);this.clock.recordInvoke(entry.slot),this.invoking(launchId)}invoking(launchId){let entry=this.#slots.get(launchId);if(entry===void 0)return;let state=this.clock.read(entry.slot),invokeTick=state.invokeTick;if(invokeTick===null)return;let send=()=>this.#channel.send({type:"launch_proof",launchId,ackTick:state.ackTick,invokeTick}),hold=this.#controls.value("HOLD_LAUNCH_PROOF");if(hold!==void 0&&(hold!=="detached"||entry.lifetime==="detached")){this.#controls.released(`release-proof-${launchId}`).then(send);return}send()}endJobGroups(jobId){let ended=[];for(let[launchId,{request}]of this.#slots)if(!(request.jobId!==jobId||request.lifetime!=="owned"||request.containment!=="own-group")&&!(request.pgid===void 0||request.pgid<=1))try{process.kill(-request.pgid,"SIGKILL"),ended.push({launchId,pgid:request.pgid})}catch{}for(let{launchId}of ended)this.done(launchId,{signal:"SIGKILL"});return ended.map(({pgid})=>pgid)}done(launchId,outcome){let entry=this.#slots.get(launchId);entry!==void 0&&(this.#slots.delete(launchId),this.#finished.set(launchId,this.clock.read(entry.slot)),this.#finished.size>FINISHED_SLOT_STATES&&this.#finished.delete(this.#finished.keys().next().value??""),this.clock.releaseSlot(entry.slot),this.#channel.send({type:"launch_done",launchId,...outcome.exitCode===void 0?{}:{exitCode:outcome.exitCode},...outcome.signal===void 0?{}:{signal:outcome.signal}}))}};import{mkdir as mkdir3,readdir as readdir2,readFile as readFile3,rm as rm4,writeFile as writeFile3}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";import{appendFile,mkdir as mkdir2,open,readFile as readFile2,rm as rm3}from"node:fs/promises";import{dirname as dirname2,join as join3}from"node:path";function generationLedgerPath(dir,generation){return join3(dir,`g${generation}`,"descendants.ledger")}var DescendantsLedger=class{#path;#durableDir=!1;#entries=new Map;constructor(path){this.#path=path}get path(){return this.#path}entries(){return[...this.#entries.values()]}async append(entry){if(!this.#durableDir){let directory=dirname2(this.#path);await mkdir2(directory,{recursive:!0,mode:448}),await(await open(this.#path,"a",384)).close(),await syncDirectory(directory),await syncDirectory(dirname2(directory)),this.#durableDir=!0}let handle=await open(this.#path,"a",384);try{await handle.write(`${JSON.stringify(entry)}
3
3
  `),await handle.datasync()}finally{await handle.close()}this.#entries.set(entry.launchId,entry)}static async readPersisted(path){let text;try{text=await readFile2(path,"utf8")}catch{return[]}let entries=[];for(let line of text.split(`
4
4
  `))if(line.trim()!=="")try{entries.push(JSON.parse(line))}catch{}return entries}async remove(){this.#entries.clear(),await rm3(this.#path,{force:!0})}};async function syncDirectory(directory){if(process.platform==="win32")return;let handle=await open(directory,"r");try{await handle.sync()}finally{await handle.close()}}var LaunchLog=class{#path;#chain=Promise.resolve();#failedWrites=0;constructor(path){this.#path=path}get path(){return this.#path}get failedWrites(){return this.#failedWrites}settled(){return this.#chain}record(record){let line=`${JSON.stringify({atMs:Date.now(),...record})}
5
5
  `;return this.#chain=this.#chain.then(async()=>{try{await mkdir2(dirname2(this.#path),{recursive:!0,mode:448}),await appendFile(this.#path,line,{mode:384})}catch{this.#failedWrites+=1}}),this.#chain}};import{execFile}from"node:child_process";async function classifyGroup(group,ownGroup,probes){if(group.lifetime==="detached")return"detached";if(ownGroup===void 0||group.pgid===ownGroup||group.pgid<=1)return"own-group";if(!probes.groupHasMembers(group.pgid))return"empty";if(!probes.isAlive(group.pgid))return"sweep";let observed=await probes.startOf(group.pgid).catch(()=>{}),recorded=group.leaderStart===void 0?void 0:processStartTimeMs(group.leaderStart);return sameProcessStartMs(recorded,observed===void 0?void 0:processStartTimeMs(observed))?"sweep":"leader-reused"}async function sweepGroups(groups,options,probes=defaultGroupProbes){let ownGroup=await probes.ownGroup(),verdicts=await Promise.all(groups.map(async group=>({group,verdict:await classifyGroup(group,ownGroup,probes)}))),targets=verdicts.filter(entry=>entry.verdict==="sweep").map(entry=>entry.group.pgid);for(let pgid of targets)probes.signalGroup(pgid,"SIGTERM");let remaining=await drain(targets,options.graceMs,options.pollMs??25,probes);for(let pgid of remaining)probes.signalGroup(pgid,"SIGKILL");return remaining=await drain(remaining,options.killWaitMs,options.pollMs??25,probes),verdicts.map(({group,verdict})=>({launchId:group.launchId,pgid:group.pgid,verdict,...verdict==="sweep"?{survived:remaining.includes(group.pgid)}:{}}))}async function drain(pgids,budgetMs,pollMs,probes){let remaining=pgids.filter(pgid=>probes.groupHasMembers(pgid));for(let waited=0;remaining.length>0&&waited<budgetMs;waited+=pollMs)await probes.wait(pollMs),remaining=remaining.filter(pgid=>probes.groupHasMembers(pgid));return remaining}function processGroupOf(pid){return process.platform==="win32"?Promise.resolve(void 0):new Promise(resolve=>{execFile("ps",["-o","pgid=","-p",String(pid)],{timeout:2e3},(error,stdout)=>{let text=String(stdout).trim();resolve(error===null&&/^\d+$/u.test(text)?Number(text):void 0)})})}function groupHasMembers(pgid){try{return process.kill(-pgid,0),!0}catch(error){return error instanceof Error&&"code"in error&&error.code==="EPERM"}}var defaultGroupProbes={groupHasMembers,isAlive:processIsRunning,startOf:pid=>readProcessStartTime(pid),ownGroup:()=>processGroupOf(process.pid),signalGroup:(pgid,signal)=>{try{process.kill(-pgid,signal)}catch{}},wait:ms=>new Promise(resolve=>setTimeout(resolve,ms))};var SWEEP_TIMING={graceMs:500,killWaitMs:1e3};async function sweepLedger(path){let groups=(await DescendantsLedger.readPersisted(path)).flatMap(entry=>entry.pgid===void 0?[]:[{launchId:entry.launchId,pgid:entry.pgid,leaderStart:entry.leaderStart,lifetime:entry.lifetime}]);return groups.length===0?[]:sweepGroups(groups,SWEEP_TIMING)}var GENERATION_CHILD_FILE="child.pid";async function recordGenerationChild(dir,generation,pid){let generationDir=dirname3(generationLedgerPath(dir,generation));await mkdir3(generationDir,{recursive:!0,mode:448}),await writeFile3(join4(generationDir,GENERATION_CHILD_FILE),String(pid),{mode:384})}async function childAlive(file){let pid=Number(await readFile3(file,"utf8").catch(()=>""));if(!Number.isSafeInteger(pid)||pid<=1)return!1;try{return process.kill(pid,0),!0}catch(error){return Reflect.get(Object(error),"code")==="EPERM"}}async function sweepStaleGenerations(dir){let names=await readdir2(dir).catch(()=>[]),outcomes=[];for(let name of names){let generation=/^g(\d+)$/.exec(name)?.[1];generation!==void 0&&(await childAlive(join4(dir,name,GENERATION_CHILD_FILE))||(outcomes.push(...await sweepLedger(generationLedgerPath(dir,Number(generation)))),await rm4(join4(dir,name),{recursive:!0,force:!0})))}return outcomes}var TOOL_CHILD_GENERATION_ENV="SENPI_TOOL_CHILD_GENERATION",TOOL_CHILD_PROTOCOL_VERSION=2,NEVER_CANCELLED=new AbortController().signal;async function runToolChild(options){let env={...options.env??process.env},exit=options.exit??(code=>process.exit(code)),generation=Number(env[TOOL_CHILD_GENERATION_ENV]);(!Number.isSafeInteger(generation)||generation<0)&&(process.stderr.write(`tool-child: invalid generation
@@ -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{appendDebugLogEntry}from"./chunk-EUCZC2RF.js";import{isRecoverableInspectorVmImportError}from"./chunk-U4FAWC6C.js";import{hasModeCrashHandler}from"./chunk-ZFIC2DZV.js";import{isStaleExtensionContextError}from"./chunk-IHES3JES.js";function containStaleExtensionError(error,origin){if(!isStaleExtensionContextError(error))return!1;try{appendDebugLogEntry(`contained stale extension ctx (${origin})`,error.stack??error.message)}catch{}return!0}var installed=!1;function installStaleExtensionContainment(){installed||(installed=!0,process.on("uncaughtException",(error,origin)=>{containStaleExtensionError(error,origin??"uncaughtException")||hasModeCrashHandler("uncaughtException")||isRecoverableInspectorVmImportError(error,origin??"uncaughtException")||(console.error(error),process.exit(1))}))}export{containStaleExtensionError,installStaleExtensionContainment};
2
+ import{appendDebugLogEntry}from"./chunk-EUCZC2RF.js";import{isRecoverableInspectorVmImportError}from"./chunk-GXPH7RN6.js";import{hasModeCrashHandler}from"./chunk-ZFIC2DZV.js";import{isStaleExtensionContextError}from"./chunk-IHES3JES.js";function containStaleExtensionError(error,origin){if(!isStaleExtensionContextError(error))return!1;try{appendDebugLogEntry(`contained stale extension ctx (${origin})`,error.stack??error.message)}catch{}return!0}var installed=!1;function installStaleExtensionContainment(){installed||(installed=!0,process.on("uncaughtException",(error,origin)=>{containStaleExtensionError(error,origin??"uncaughtException")||hasModeCrashHandler("uncaughtException")||isRecoverableInspectorVmImportError(error,origin??"uncaughtException")||(console.error(error),process.exit(1))}))}export{containStaleExtensionError,installStaleExtensionContainment};