@code-yeongyu/senpi 2026.11.3-1 → 2026.11.3-2
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 +27 -0
- package/dist/bundle/chunks/anthropic-messages-LJAKRKMX.js +11 -0
- package/dist/bundle/chunks/{args-O3WS4WCO.js → args-GQTXDYS3.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-YLBBQXI7.js → azure-openai-responses-HDEKTPMZ.js} +1 -1
- package/dist/bundle/chunks/chatgpt-subscription.js +10 -2
- package/dist/bundle/chunks/{chunk-ED7VJGL4.js → chunk-2PGSRQBF.js} +1 -1
- package/dist/bundle/chunks/{chunk-4BF4FLT6.js → chunk-3LDASCJN.js} +1 -1
- package/dist/bundle/chunks/{chunk-PIAY636U.js → chunk-3QPE75AR.js} +1 -1
- package/dist/bundle/chunks/{chunk-FQZZGSYH.js → chunk-4ZGQUOBV.js} +1 -1
- package/dist/bundle/chunks/{chunk-S2M5D5GS.js → chunk-5BMIET5O.js} +2 -2
- package/dist/bundle/chunks/{chunk-XLLQJALL.js → chunk-67M7HKXO.js} +1 -1
- package/dist/bundle/chunks/chunk-6ISOXWH2.js +2 -0
- package/dist/bundle/chunks/{chunk-7KLEFHSU.js → chunk-6NPK2O3C.js} +2 -2
- package/dist/bundle/chunks/{chunk-BNIZP4OS.js → chunk-7C4W5HMU.js} +1 -1
- package/dist/bundle/chunks/chunk-7KIHKE2T.js +2 -0
- package/dist/bundle/chunks/{chunk-WCRNJYHO.js → chunk-A4KOQUHT.js} +1 -1
- package/dist/bundle/chunks/{chunk-TOOB6OLG.js → chunk-A5PZGQCP.js} +1 -1
- package/dist/bundle/chunks/{chunk-TBARMJ75.js → chunk-AVP6DDBF.js} +1 -1
- package/dist/bundle/chunks/{chunk-FLM6GZPT.js → chunk-B3GTID4P.js} +1 -1
- package/dist/bundle/chunks/{chunk-2XBKE2BZ.js → chunk-BIWFWGUA.js} +1 -1
- package/dist/bundle/chunks/{chunk-6LDUM5CL.js → chunk-DCI4QOUX.js} +1 -1
- package/dist/bundle/chunks/{chunk-2YFPDNNP.js → chunk-DNZKKG4V.js} +1 -1
- package/dist/bundle/chunks/{chunk-W2V7RIBF.js → chunk-E7SA75PP.js} +1 -1
- package/dist/bundle/chunks/{chunk-YWD54RHU.js → chunk-EBZ6IP4V.js} +1 -1
- package/dist/bundle/chunks/{chunk-J2OBN7TI.js → chunk-G5XUGK4B.js} +1 -1
- package/dist/bundle/chunks/{chunk-PX7FF5LE.js → chunk-GKP34H3C.js} +2 -2
- package/dist/bundle/chunks/{chunk-PP52OWBB.js → chunk-GLTOBXZY.js} +1 -1
- package/dist/bundle/chunks/{chunk-ZNLCKKF6.js → chunk-IJGXAACA.js} +117 -35
- package/dist/bundle/chunks/{chunk-LGO25HPL.js → chunk-JCTODLUP.js} +1 -1
- package/dist/bundle/chunks/{chunk-3ESZE3DG.js → chunk-KHBCZ6TR.js} +1 -1
- package/dist/bundle/chunks/chunk-KJR3XXMI.js +2 -0
- package/dist/bundle/chunks/{chunk-FJ2UCBOA.js → chunk-KY4V3TSO.js} +2 -2
- package/dist/bundle/chunks/{chunk-4SENPCEA.js → chunk-MCXOJHN2.js} +1 -1
- package/dist/bundle/chunks/{chunk-DPBPO5OU.js → chunk-NKI7L5UM.js} +3 -3
- package/dist/bundle/chunks/{chunk-CJWSQ6CK.js → chunk-OD7RT7G7.js} +1 -1
- package/dist/bundle/chunks/{chunk-F4OHTL2K.js → chunk-OOU3BRUY.js} +1 -1
- package/dist/bundle/chunks/{chunk-LPHUMR6R.js → chunk-OT6ALXSJ.js} +1 -1
- package/dist/bundle/chunks/{chunk-XGBRBCIQ.js → chunk-Q5CKFBQT.js} +1 -1
- package/dist/bundle/chunks/{chunk-F7GBSQRV.js → chunk-QPYDQ4QK.js} +1 -1
- package/dist/bundle/chunks/{chunk-MOOFLKLI.js → chunk-QSMT5KVJ.js} +1 -1
- package/dist/bundle/chunks/{chunk-SAZ6E74O.js → chunk-RUOTFZQR.js} +1 -1
- package/dist/bundle/chunks/{chunk-5DZD623T.js → chunk-RWF6IJQL.js} +2 -2
- package/dist/bundle/chunks/{chunk-HBCNDC53.js → chunk-S5Y7NEHB.js} +1 -1
- package/dist/bundle/chunks/{chunk-DAPBNRN5.js → chunk-SCBTASM4.js} +1 -1
- package/dist/bundle/chunks/chunk-SJWTZ3Z2.js +2 -0
- package/dist/bundle/chunks/{chunk-ISZ4EWIS.js → chunk-SODMQEHO.js} +1 -1
- package/dist/bundle/chunks/{chunk-WEGTCUO3.js → chunk-SQAQEITV.js} +1 -1
- package/dist/bundle/chunks/{chunk-UFVZTQKN.js → chunk-TQQG5L4D.js} +1 -1
- package/dist/bundle/chunks/{chunk-VPDQ6MOL.js → chunk-U6A4X3FV.js} +1 -1
- package/dist/bundle/chunks/{chunk-ACIFXWJ6.js → chunk-UHUM55TR.js} +1 -1
- package/dist/bundle/chunks/{chunk-L5OFGHDA.js → chunk-USKWGPA6.js} +1 -1
- package/dist/bundle/chunks/{chunk-7ORS33CE.js → chunk-VDDJADPV.js} +1 -1
- package/dist/bundle/chunks/{chunk-R65P6LAT.js → chunk-VIHXG53S.js} +1 -1
- package/dist/bundle/chunks/{chunk-SGS76663.js → chunk-VPVD5G32.js} +1 -1
- package/dist/bundle/chunks/chunk-WO6I5PRF.js +3 -0
- package/dist/bundle/chunks/{chunk-ETCYVVVO.js → chunk-WVEIJ437.js} +1 -1
- package/dist/bundle/chunks/{chunk-7565XQAU.js → chunk-XKFG4N3Z.js} +1 -1
- package/dist/bundle/chunks/{chunk-57MRFI6E.js → chunk-XMWPCJU6.js} +1 -1
- package/dist/bundle/chunks/{chunk-GDPWQJDQ.js → chunk-XPSXUKSD.js} +1 -1
- package/dist/bundle/chunks/{chunk-FNBEICAA.js → chunk-YI6KRJDC.js} +1 -1
- package/dist/bundle/chunks/{chunk-UURGXV5B.js → chunk-YP47G4YP.js} +1 -1
- package/dist/bundle/chunks/{chunk-6BSMXZKQ.js → chunk-YRYDCKUI.js} +1 -1
- package/dist/bundle/chunks/{chunk-QTQ3ES2S.js → chunk-YTKZSGMQ.js} +1 -1
- package/dist/bundle/chunks/{chunk-V36CXIIB.js → chunk-YXL3PNTL.js} +1 -1
- package/dist/bundle/chunks/chunk-Z7HTHT6K.js +2 -0
- package/dist/bundle/chunks/{chunk-27XEDYQA.js → chunk-ZTPG27EJ.js} +1 -1
- package/dist/bundle/chunks/{cli-main-XM5FWY3Z.js → cli-main-RN7YB427.js} +1 -1
- package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-FC7QLRU2.js → cloudflare-workers-ai-system-one-N5KFNKK4.js} +1 -1
- package/dist/bundle/chunks/credential-accounts-BJX55MTT.js +2 -0
- package/dist/bundle/chunks/devin.js +10 -2
- package/dist/bundle/chunks/{dispatch-UY6LBJJE.js → dispatch-M7UAPGVY.js} +1 -1
- package/dist/bundle/chunks/{google-generative-ai-7PQ4QRHJ.js → google-generative-ai-2TZSCSIS.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-DY7EO4EJ.js → google-vertex-7NJJOI7V.js} +1 -1
- package/dist/bundle/chunks/{health-write-45CX64T2.js → health-write-YUSPVH7U.js} +1 -1
- package/dist/bundle/chunks/{help-fast-path-3EDGRKQM.js → help-fast-path-DWCA77QP.js} +1 -1
- package/dist/bundle/chunks/host-command-KJXUTSQ7.js +2 -0
- package/dist/bundle/chunks/{host-lifecycle-TGG7KGQH.js → host-lifecycle-QHIJ4G2K.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle.js +1 -1
- package/dist/bundle/chunks/{host-session-command-OJFARE5Q.js → host-session-command-IPH3WXSG.js} +1 -1
- package/dist/bundle/chunks/{host-socket-request-F2R5P34M.js → host-socket-request-XPXJV3CS.js} +1 -1
- package/dist/bundle/chunks/interactive-mode-XUXMDYLA.js +2 -0
- package/dist/bundle/chunks/{list-tips-3D3A6GFK.js → list-tips-XJY7EL5S.js} +1 -1
- package/dist/bundle/chunks/{login-health-YOPTYRTU.js → login-health-226NO44U.js} +1 -1
- package/dist/bundle/chunks/main-P7PKMJUG.js +2 -0
- package/dist/bundle/chunks/{mistral-conversations-6F2RAIB2.js → mistral-conversations-QMHMHSUF.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-N2RQ7JSZ.js → multi-session-host-ZQY4AN46.js} +1 -1
- package/dist/bundle/chunks/{native-loader-NMDTMHMA.js → native-loader-A6DNMGCK.js} +1 -1
- package/dist/bundle/chunks/openai-chatgpt.js +11 -3
- package/dist/bundle/chunks/{openai-codex-responses-YTWLG4OL.js → openai-codex-responses-GUAHKQE2.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-TIFDYHZL.js → openai-completions-UPRTFM54.js} +1 -1
- package/dist/bundle/chunks/{openai-images-OAEMY4RG.js → openai-images-IKWNS6VB.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-L35NIG5Y.js → openai-responses-AXN5NUHH.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +10 -2
- package/dist/bundle/chunks/{package-manager-cli-JPNA27E5.js → package-manager-cli-PP7L2Q5M.js} +1 -1
- package/dist/bundle/chunks/radius.js +10 -2
- package/dist/bundle/chunks/{rg-engine-JDUYBM6L.js → rg-engine-VRSXT6HG.js} +1 -1
- package/dist/bundle/chunks/{role-45Y7PQFC.js → role-L5J7ZPCF.js} +1 -1
- package/dist/bundle/chunks/rotation-stream-6INZXQFC.js +2 -0
- package/dist/bundle/chunks/rpc-mode-W4UATRAT.js +2 -0
- package/dist/bundle/chunks/{rpc-monitor-source-5TUR27NY.js → rpc-monitor-source-RMMUPBMS.js} +1 -1
- package/dist/bundle/chunks/{run-attached-tui-TI6MELEI.js → run-attached-tui-RLXFGCEP.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-OZ5ESMIT.js → schedule-command-ZNFEJNTT.js} +1 -1
- package/dist/bundle/chunks/{session-control-endpoint-5YKBYJOO.js → session-control-endpoint-TWTONJWF.js} +1 -1
- package/dist/bundle/chunks/{session-picker-CMRV72VA.js → session-picker-KRUVCHOV.js} +1 -1
- package/dist/bundle/chunks/session-slot-NJOZCOHQ.js +2 -0
- package/dist/bundle/chunks/session-worker.js +218 -135
- package/dist/bundle/chunks/{state-store-Q47AYMRI.js → state-store-ZAFZ4JOM.js} +1 -1
- package/dist/bundle/chunks/{typesafe-system-one-5JYDJK6S.js → typesafe-system-one-CICIRAYN.js} +1 -1
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/host-supervisor.js +1 -1
- 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/core/agent-session.js +5 -3
- package/dist/core/auth-storage.d.ts +19 -0
- package/dist/core/auth-storage.js +99 -24
- package/dist/core/auth-store-load-error.d.ts +29 -0
- package/dist/core/auth-store-load-error.js +74 -0
- package/dist/core/brand.d.ts +2 -0
- package/dist/core/brand.js +1 -0
- package/dist/core/credential-pool/failover.d.ts +8 -0
- package/dist/core/credential-pool/failover.js +18 -5
- package/dist/core/credential-pool/rotation-stream.d.ts +1 -1
- package/dist/core/credential-pool/rotation-stream.js +2 -7
- package/dist/core/credential-pool/session-slot.d.ts +20 -0
- package/dist/core/credential-pool/session-slot.js +26 -0
- package/dist/core/credential-recovery-revision.d.ts +10 -0
- package/dist/core/credential-recovery-revision.js +19 -0
- package/dist/core/execution/executor-body.d.ts +22 -0
- package/dist/core/execution/executor-body.js +73 -0
- package/dist/core/execution/executor-freeze.d.ts +17 -0
- package/dist/core/execution/executor-freeze.js +53 -0
- package/dist/core/execution/executor-pipeline.d.ts +9 -0
- package/dist/core/execution/executor-pipeline.js +25 -0
- package/dist/core/execution/executor-types.d.ts +82 -0
- package/dist/core/execution/executor-types.js +2 -0
- package/dist/core/execution/executor.d.ts +8 -0
- package/dist/core/execution/executor.js +216 -0
- package/dist/core/extensions/builtin/anthropic-subscription/account-block-log.d.ts +15 -0
- package/dist/core/extensions/builtin/anthropic-subscription/account-block-log.js +18 -0
- package/dist/core/extensions/builtin/anthropic-subscription/affinity.d.ts +9 -1
- package/dist/core/extensions/builtin/anthropic-subscription/affinity.js +15 -4
- package/dist/core/extensions/builtin/anthropic-subscription/failover.d.ts +7 -1
- package/dist/core/extensions/builtin/anthropic-subscription/failover.js +19 -2
- package/dist/core/extensions/builtin/anthropic-subscription/guidance.d.ts +8 -2
- package/dist/core/extensions/builtin/anthropic-subscription/guidance.js +25 -1
- package/dist/core/extensions/builtin/anthropic-subscription/provider-diagnostic.d.ts +9 -0
- package/dist/core/extensions/builtin/anthropic-subscription/provider-diagnostic.js +59 -0
- package/dist/core/extensions/builtin/anthropic-subscription/session-registry-wiring.js +7 -0
- package/dist/core/extensions/builtin/anthropic-subscription/stream-guidance.js +5 -3
- package/dist/core/extensions/builtin/anthropic-subscription/stream.js +4 -0
- package/dist/core/extensions/builtin/btw/index.js +3 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.js +3 -1
- package/dist/core/extensions/builtin/compaction/index.js +1 -1
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -1
- package/dist/core/extensions/builtin/compaction/openai-remote.js +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +3 -2
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js +3 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/native-bootstrap.js +3 -1
- package/dist/core/extensions/builtin/look-at/runner.js +3 -1
- package/dist/core/extensions/builtin/mcp/auth/callback.js +3 -4
- package/dist/core/extensions/builtin/mcp/auth/oauth-provider.js +2 -1
- package/dist/core/model-registry.d.ts +10 -2
- package/dist/core/model-registry.js +12 -4
- package/dist/core/model-runtime.d.ts +8 -0
- package/dist/core/model-runtime.js +38 -0
- package/dist/core/retry-fallback/controller-types.d.ts +7 -0
- package/dist/core/retry-fallback/controller.d.ts +2 -0
- package/dist/core/retry-fallback/controller.js +13 -4
- package/dist/core/retry-fallback/credential-recovery.d.ts +18 -0
- package/dist/core/retry-fallback/credential-recovery.js +32 -0
- package/dist/core/retry-fallback/settings.d.ts +8 -1
- package/dist/core/retry-fallback/settings.js +12 -6
- package/dist/core/session-log.js +1 -1
- package/dist/core/settings-manager.js +4 -1
- package/dist/modes/rpc/connection-handler.js +3 -1
- package/dist/modes/rpc/effect-commands.d.ts +1 -0
- package/dist/modes/rpc/loopless-execute-grant.d.ts +20 -0
- package/dist/modes/rpc/loopless-execute-grant.js +26 -0
- package/dist/modes/rpc/loopless-runtime-settings.d.ts +30 -0
- package/dist/modes/rpc/loopless-runtime-settings.js +69 -0
- package/dist/modes/rpc/loopless-tool-call.d.ts +12 -0
- package/dist/modes/rpc/loopless-tool-call.js +22 -0
- package/dist/modes/rpc/rpc-read-response-types.d.ts +2 -1
- package/dist/modes/rpc/rpc-session-state-types.d.ts +10 -0
- package/dist/modes/rpc/rpc-types.d.ts +1 -1
- package/dist/modes/rpc/runtime-factory-loopless.d.ts +57 -0
- package/dist/modes/rpc/runtime-factory-loopless.js +131 -0
- package/docs/development.md +1 -1
- package/docs/rpc.md +2 -0
- package/package.json +6 -6
- package/dist/bundle/chunks/anthropic-messages-AFWQB3KN.js +0 -10
- package/dist/bundle/chunks/chunk-3WJ2DE2G.js +0 -3
- package/dist/bundle/chunks/chunk-ESQBKTNG.js +0 -2
- package/dist/bundle/chunks/chunk-MOH5HOHX.js +0 -2
- package/dist/bundle/chunks/credential-accounts-YZYSKA7X.js +0 -2
- package/dist/bundle/chunks/host-command-PZ4VYQIW.js +0 -2
- package/dist/bundle/chunks/interactive-mode-7JSJVVIS.js +0 -2
- package/dist/bundle/chunks/main-3YGJ2O4I.js +0 -2
- package/dist/bundle/chunks/rotation-stream-WXWJKJZN.js +0 -2
- package/dist/bundle/chunks/rpc-mode-Z7MN2ZWA.js +0 -2
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
-
import{GrepEngineError}from"./chunk-H4QOEVS5.js";import{signalSpawnedChild}from"./chunk-KLAX467B.js";import{fetchWithRetry}from"./chunk-2SOVDETB.js";import{APP_NAME,envValue,getBinDir}from"./chunk-ISZ4EWIS.js";import{spawn}from"node:child_process";import{spawnSync}from"child_process";import{chmodSync,createWriteStream,existsSync,mkdirSync,readdirSync,renameSync,rmSync,statSync}from"fs";import{arch,platform}from"os";import{join}from"path";import{Readable}from"stream";import{pipeline}from"stream/promises";var TOOLS_DIR=getBinDir(),NETWORK_TIMEOUT_MS=1e4,DOWNLOAD_TIMEOUT_MS=12e4;function isOfflineModeEnabled(){let value=envValue("OFFLINE");return value?value==="1"||value.toLowerCase()==="true"||value.toLowerCase()==="yes":!1}var TOOLS={fd:{name:"fd",repo:"sharkdp/fd",binaryName:"fd",systemBinaryNames:["fd","fdfind"],tagPrefix:"v",getAssetName:(version,plat,architecture)=>plat==="darwin"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null},rg:{name:"ripgrep",repo:"BurntSushi/ripgrep",binaryName:"rg",tagPrefix:"",getAssetName:(version,plat,architecture)=>plat==="darwin"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null}};function executableCandidates(cmd){if(platform()!=="win32")return[cmd];let extensions=(process.env.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").filter(value=>value.length>0);return[cmd,...extensions.map(extension=>`${cmd}${extension.toLowerCase()}`)]}function commandExists(cmd){let pathValue=process.env.PATH;if(pathValue===void 0||pathValue.length===0)return!1;let separator=platform()==="win32"?";":":";for(let directory of pathValue.split(separator))if(directory.length!==0)for(let candidate of executableCandidates(cmd))try{let stats=statSync(join(directory,candidate));if(!stats.isFile())continue;if(platform()==="win32"||(stats.mode&73)!==0)return!0}catch{}return!1}function getToolPath(tool){let config=TOOLS[tool];if(!config)return null;let localPath=join(TOOLS_DIR,config.binaryName+(platform()==="win32"?".exe":""));if(existsSync(localPath))return localPath;let systemBinaryNames=config.systemBinaryNames??[config.binaryName];for(let systemBinaryName of systemBinaryNames)if(commandExists(systemBinaryName))return systemBinaryName;return null}async function getLatestVersion(repo){let response=await fetchWithRetry(`https://github.com/${repo}/releases/latest`,{headers:{"User-Agent":`${APP_NAME}-coding-agent`},redirect:"manual"},{timeoutMs:NETWORK_TIMEOUT_MS});try{await response.body?.cancel()}catch{}let location=response.status>=300&&response.status<400?response.headers.get("location"):null;if(!location)throw new Error(`Failed to resolve latest ${repo} release: HTTP ${response.status} without redirect`);let tag=new URL(location,"https://github.com").pathname.split("/").pop();if(!tag||!location.includes("/releases/tag/"))throw new Error(`Failed to resolve latest ${repo} release: unexpected redirect to ${location}`);return decodeURIComponent(tag).replace(/^v/,"")}async function downloadFile(url,dest){let response=await fetchWithRetry(url,void 0,{timeoutMs:DOWNLOAD_TIMEOUT_MS});if(!response.ok)throw new Error(`Download failed with HTTP ${response.status}: ${url}`);if(!response.body)throw new Error("No response body");let fileStream=createWriteStream(dest);await pipeline(Readable.fromWeb(response.body),fileStream)}function findBinaryRecursively(rootDir,binaryFileName){let stack=[rootDir];for(;stack.length>0;){let currentDir=stack.pop();if(!currentDir)continue;let entries=readdirSync(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join(currentDir,entry.name);if(entry.isFile()&&entry.name===binaryFileName)return fullPath;entry.isDirectory()&&stack.push(fullPath)}}return null}function formatSpawnFailure(result){if(result.error?.message)return result.error.message;let stderr=result.stderr?.toString().trim();if(stderr)return stderr;let stdout=result.stdout?.toString().trim();return stdout||`exit status ${result.status??"unknown"}`}function runExtractionCommand(command,args){let result=spawnSync(command,args,{stdio:"pipe"});return!result.error&&result.status===0?null:`${command}: ${formatSpawnFailure(result)}`}function extractTarGzArchive(archivePath,extractDir,assetName){let failure=runExtractionCommand("tar",["xzf",archivePath,"-C",extractDir]);if(failure)throw new Error(`Failed to extract ${assetName}: ${failure}`)}function getWindowsTarCommand(){let systemRoot=process.env.SystemRoot??process.env.WINDIR;if(systemRoot){let systemTar=join(systemRoot,"System32","tar.exe");if(existsSync(systemTar))return systemTar}return"tar.exe"}function extractZipArchive(archivePath,extractDir,assetName){let failures=[];if(platform()==="win32"){let tarFailure=runExtractionCommand(getWindowsTarCommand(),["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure);let powershellFailure=runExtractionCommand("powershell.exe",["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command","& { param($archive, $destination) $ErrorActionPreference = 'Stop'; Expand-Archive -LiteralPath $archive -DestinationPath $destination -Force }",archivePath,extractDir]);if(!powershellFailure)return;failures.push(powershellFailure)}else{let unzipFailure=runExtractionCommand("unzip",["-q",archivePath,"-d",extractDir]);if(!unzipFailure)return;failures.push(unzipFailure);let tarFailure=runExtractionCommand("tar",["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure)}throw new Error(`Failed to extract ${assetName}: ${failures.join("; ")}`)}async function downloadTool(tool){let config=TOOLS[tool];if(!config)throw new Error(`Unknown tool: ${tool}`);let plat=platform(),architecture=arch(),version=tool==="fd"&&plat==="darwin"&&architecture==="x64"?"10.3.0":await getLatestVersion(config.repo),assetName=config.getAssetName(version,plat,architecture);if(!assetName)throw new Error(`Unsupported platform: ${plat}/${architecture}`);mkdirSync(TOOLS_DIR,{recursive:!0});let downloadUrl=`https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`,archivePath=join(TOOLS_DIR,assetName),binaryExt=plat==="win32"?".exe":"",binaryPath=join(TOOLS_DIR,config.binaryName+binaryExt);await downloadFile(downloadUrl,archivePath);let extractDir=join(TOOLS_DIR,`extract_tmp_${config.binaryName}_${process.pid}_${Date.now()}_${Math.random().toString(36).slice(2,10)}`);mkdirSync(extractDir,{recursive:!0});try{if(assetName.endsWith(".tar.gz"))extractTarGzArchive(archivePath,extractDir,assetName);else if(assetName.endsWith(".zip"))extractZipArchive(archivePath,extractDir,assetName);else throw new Error(`Unsupported archive format: ${assetName}`);let binaryFileName=config.binaryName+binaryExt,extractedDir=join(extractDir,assetName.replace(/\.(tar\.gz|zip)$/,"")),extractedBinary=[join(extractedDir,binaryFileName),join(extractDir,binaryFileName)].find(candidate=>existsSync(candidate));if(extractedBinary||(extractedBinary=findBinaryRecursively(extractDir,binaryFileName)??void 0),extractedBinary)renameSync(extractedBinary,binaryPath);else throw new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);plat!=="win32"&&chmodSync(binaryPath,493)}finally{rmSync(archivePath,{force:!0}),rmSync(extractDir,{recursive:!0,force:!0})}return binaryPath}var TERMUX_PACKAGES={fd:"fd",rg:"ripgrep"};async function ensureTool(tool,onStatus){let existingPath=getToolPath(tool);if(existingPath)return existingPath;let config=TOOLS[tool];if(config){if(isOfflineModeEnabled()){onStatus?.({type:"warning",message:`${config.name} not found. Offline mode enabled, skipping download.`});return}if(platform()==="android"){let pkgName=TERMUX_PACKAGES[tool]??tool;onStatus?.({type:"warning",message:`${config.name} not found. Install with: pkg install ${pkgName}`});return}onStatus?.({type:"info",message:`${config.name} not found. Downloading...`});try{let path=await downloadTool(tool);return onStatus?.({type:"info",message:`${config.name} installed to ${path}`}),path}catch(e){let messages=[];for(let current=e,depth=0;current instanceof Error&&depth<5;current=current.cause,depth++)messages.includes(current.message)||messages.push(current.message);onStatus?.({type:"warning",message:`Failed to download ${config.name}: ${messages.length>0?messages.join(": "):String(e)}`});return}}}import{relative}from"node:path";function argvBudget(platform2=process.platform){return platform2==="win32"?32e3:256*1024}var EXECUTABLE_RESERVE=4096;function argvCost(argument,platform2=process.platform){if(platform2!=="win32")return argument.length+1;let quotes=argument.match(/"/g)?.length??0,doubled=argument.match(/\\+(?="|$)/g)?.join("").length??0;return argument.length+3+quotes+doubled}var LINUX_MAX_ARG_STRLEN=131072;function commandLineOverflow(args,platform2=process.platform){let budget=argvBudget(platform2),length=EXECUTABLE_RESERVE+args.reduce((sum,argument)=>sum+argvCost(argument,platform2),0);if(length>budget)return`the ripgrep command line would be ${length} characters, over the ${budget}-character limit on ${platform2}`;if(platform2!=="linux")return;let longest=Math.max(0,...args.map(argument=>Buffer.byteLength(argument)));if(longest>=LINUX_MAX_ARG_STRLEN)return`one ripgrep argument is ${longest} bytes, over Linux's ${LINUX_MAX_ARG_STRLEN-1}-byte per-argument limit`}function roomAfter(fixed,budget,platform2=process.platform){return budget-EXECUTABLE_RESERVE-fixed.reduce((sum,argument)=>sum+argvCost(argument,platform2),0)}function packArgv(items,costOf,room){let batches=[],used=0;for(let item of items){let cost=costOf(item),batch=batches.at(-1);batch&&used+cost<=room?(batch.push(item),used+=cost):(batches.push([item]),used=cost)}return batches}import{sep}from"node:path";var pathOrder=(a,b)=>Buffer.compare(Buffer.from(a),Buffer.from(b)),slashPath=path=>path.split(sep).join("/");import{open}from"node:fs/promises";import{createInterface}from"node:readline";import{resolve}from"node:path";function parseRgEvent(line){let event=JSON.parse(line);if(!event||!["begin","match","context","end","summary"].includes(event.type)||!event.data)throw new Error("Invalid ripgrep JSON event");return event}function decode(value){if(typeof value?.text=="string")return value.text;if(typeof value?.bytes=="string")return Buffer.from(value.bytes,"base64").toString("utf8");throw new GrepEngineError("ENGINE_UNAVAILABLE","Invalid ripgrep JSON text/bytes field")}function collectSegmentRows(segment,request,oversized){let first=segment[0],files=new Map,byPath=new Map(segment.map(candidate=>[candidate.absolute,candidate])),segmentBinary=new Set;return{files,segmentBinary,onEvent:event=>{if(event.type==="summary")return;let candidate=oversized?first:byPath.get(resolve(first.root.cwd,decode(event.data.path)));if(!candidate)throw new Error("ripgrep searched a file outside the ordered segment");if(event.type==="begin"){files.set(candidate.display,{candidate,rows:new Map});return}if(event.type==="end"){event.data.binary_offset!=null&&(files.delete(candidate.display),segmentBinary.add(candidate.display));return}let file=files.get(candidate.display);if(!file||typeof event.data.line_number!="number")throw new Error("ripgrep match/context without a begin or line number");let text=decode(event.data.lines).replace(/\n$/,"").split(`
|
|
2
|
+
import{GrepEngineError}from"./chunk-H4QOEVS5.js";import{signalSpawnedChild}from"./chunk-KLAX467B.js";import{fetchWithRetry}from"./chunk-2SOVDETB.js";import{APP_NAME,envValue,getBinDir}from"./chunk-SODMQEHO.js";import{spawn}from"node:child_process";import{spawnSync}from"child_process";import{chmodSync,createWriteStream,existsSync,mkdirSync,readdirSync,renameSync,rmSync,statSync}from"fs";import{arch,platform}from"os";import{join}from"path";import{Readable}from"stream";import{pipeline}from"stream/promises";var TOOLS_DIR=getBinDir(),NETWORK_TIMEOUT_MS=1e4,DOWNLOAD_TIMEOUT_MS=12e4;function isOfflineModeEnabled(){let value=envValue("OFFLINE");return value?value==="1"||value.toLowerCase()==="true"||value.toLowerCase()==="yes":!1}var TOOLS={fd:{name:"fd",repo:"sharkdp/fd",binaryName:"fd",systemBinaryNames:["fd","fdfind"],tagPrefix:"v",getAssetName:(version,plat,architecture)=>plat==="darwin"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null},rg:{name:"ripgrep",repo:"BurntSushi/ripgrep",binaryName:"rg",tagPrefix:"",getAssetName:(version,plat,architecture)=>plat==="darwin"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null}};function executableCandidates(cmd){if(platform()!=="win32")return[cmd];let extensions=(process.env.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").filter(value=>value.length>0);return[cmd,...extensions.map(extension=>`${cmd}${extension.toLowerCase()}`)]}function commandExists(cmd){let pathValue=process.env.PATH;if(pathValue===void 0||pathValue.length===0)return!1;let separator=platform()==="win32"?";":":";for(let directory of pathValue.split(separator))if(directory.length!==0)for(let candidate of executableCandidates(cmd))try{let stats=statSync(join(directory,candidate));if(!stats.isFile())continue;if(platform()==="win32"||(stats.mode&73)!==0)return!0}catch{}return!1}function getToolPath(tool){let config=TOOLS[tool];if(!config)return null;let localPath=join(TOOLS_DIR,config.binaryName+(platform()==="win32"?".exe":""));if(existsSync(localPath))return localPath;let systemBinaryNames=config.systemBinaryNames??[config.binaryName];for(let systemBinaryName of systemBinaryNames)if(commandExists(systemBinaryName))return systemBinaryName;return null}async function getLatestVersion(repo){let response=await fetchWithRetry(`https://github.com/${repo}/releases/latest`,{headers:{"User-Agent":`${APP_NAME}-coding-agent`},redirect:"manual"},{timeoutMs:NETWORK_TIMEOUT_MS});try{await response.body?.cancel()}catch{}let location=response.status>=300&&response.status<400?response.headers.get("location"):null;if(!location)throw new Error(`Failed to resolve latest ${repo} release: HTTP ${response.status} without redirect`);let tag=new URL(location,"https://github.com").pathname.split("/").pop();if(!tag||!location.includes("/releases/tag/"))throw new Error(`Failed to resolve latest ${repo} release: unexpected redirect to ${location}`);return decodeURIComponent(tag).replace(/^v/,"")}async function downloadFile(url,dest){let response=await fetchWithRetry(url,void 0,{timeoutMs:DOWNLOAD_TIMEOUT_MS});if(!response.ok)throw new Error(`Download failed with HTTP ${response.status}: ${url}`);if(!response.body)throw new Error("No response body");let fileStream=createWriteStream(dest);await pipeline(Readable.fromWeb(response.body),fileStream)}function findBinaryRecursively(rootDir,binaryFileName){let stack=[rootDir];for(;stack.length>0;){let currentDir=stack.pop();if(!currentDir)continue;let entries=readdirSync(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join(currentDir,entry.name);if(entry.isFile()&&entry.name===binaryFileName)return fullPath;entry.isDirectory()&&stack.push(fullPath)}}return null}function formatSpawnFailure(result){if(result.error?.message)return result.error.message;let stderr=result.stderr?.toString().trim();if(stderr)return stderr;let stdout=result.stdout?.toString().trim();return stdout||`exit status ${result.status??"unknown"}`}function runExtractionCommand(command,args){let result=spawnSync(command,args,{stdio:"pipe"});return!result.error&&result.status===0?null:`${command}: ${formatSpawnFailure(result)}`}function extractTarGzArchive(archivePath,extractDir,assetName){let failure=runExtractionCommand("tar",["xzf",archivePath,"-C",extractDir]);if(failure)throw new Error(`Failed to extract ${assetName}: ${failure}`)}function getWindowsTarCommand(){let systemRoot=process.env.SystemRoot??process.env.WINDIR;if(systemRoot){let systemTar=join(systemRoot,"System32","tar.exe");if(existsSync(systemTar))return systemTar}return"tar.exe"}function extractZipArchive(archivePath,extractDir,assetName){let failures=[];if(platform()==="win32"){let tarFailure=runExtractionCommand(getWindowsTarCommand(),["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure);let powershellFailure=runExtractionCommand("powershell.exe",["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command","& { param($archive, $destination) $ErrorActionPreference = 'Stop'; Expand-Archive -LiteralPath $archive -DestinationPath $destination -Force }",archivePath,extractDir]);if(!powershellFailure)return;failures.push(powershellFailure)}else{let unzipFailure=runExtractionCommand("unzip",["-q",archivePath,"-d",extractDir]);if(!unzipFailure)return;failures.push(unzipFailure);let tarFailure=runExtractionCommand("tar",["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure)}throw new Error(`Failed to extract ${assetName}: ${failures.join("; ")}`)}async function downloadTool(tool){let config=TOOLS[tool];if(!config)throw new Error(`Unknown tool: ${tool}`);let plat=platform(),architecture=arch(),version=tool==="fd"&&plat==="darwin"&&architecture==="x64"?"10.3.0":await getLatestVersion(config.repo),assetName=config.getAssetName(version,plat,architecture);if(!assetName)throw new Error(`Unsupported platform: ${plat}/${architecture}`);mkdirSync(TOOLS_DIR,{recursive:!0});let downloadUrl=`https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`,archivePath=join(TOOLS_DIR,assetName),binaryExt=plat==="win32"?".exe":"",binaryPath=join(TOOLS_DIR,config.binaryName+binaryExt);await downloadFile(downloadUrl,archivePath);let extractDir=join(TOOLS_DIR,`extract_tmp_${config.binaryName}_${process.pid}_${Date.now()}_${Math.random().toString(36).slice(2,10)}`);mkdirSync(extractDir,{recursive:!0});try{if(assetName.endsWith(".tar.gz"))extractTarGzArchive(archivePath,extractDir,assetName);else if(assetName.endsWith(".zip"))extractZipArchive(archivePath,extractDir,assetName);else throw new Error(`Unsupported archive format: ${assetName}`);let binaryFileName=config.binaryName+binaryExt,extractedDir=join(extractDir,assetName.replace(/\.(tar\.gz|zip)$/,"")),extractedBinary=[join(extractedDir,binaryFileName),join(extractDir,binaryFileName)].find(candidate=>existsSync(candidate));if(extractedBinary||(extractedBinary=findBinaryRecursively(extractDir,binaryFileName)??void 0),extractedBinary)renameSync(extractedBinary,binaryPath);else throw new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);plat!=="win32"&&chmodSync(binaryPath,493)}finally{rmSync(archivePath,{force:!0}),rmSync(extractDir,{recursive:!0,force:!0})}return binaryPath}var TERMUX_PACKAGES={fd:"fd",rg:"ripgrep"};async function ensureTool(tool,onStatus){let existingPath=getToolPath(tool);if(existingPath)return existingPath;let config=TOOLS[tool];if(config){if(isOfflineModeEnabled()){onStatus?.({type:"warning",message:`${config.name} not found. Offline mode enabled, skipping download.`});return}if(platform()==="android"){let pkgName=TERMUX_PACKAGES[tool]??tool;onStatus?.({type:"warning",message:`${config.name} not found. Install with: pkg install ${pkgName}`});return}onStatus?.({type:"info",message:`${config.name} not found. Downloading...`});try{let path=await downloadTool(tool);return onStatus?.({type:"info",message:`${config.name} installed to ${path}`}),path}catch(e){let messages=[];for(let current=e,depth=0;current instanceof Error&&depth<5;current=current.cause,depth++)messages.includes(current.message)||messages.push(current.message);onStatus?.({type:"warning",message:`Failed to download ${config.name}: ${messages.length>0?messages.join(": "):String(e)}`});return}}}import{relative}from"node:path";function argvBudget(platform2=process.platform){return platform2==="win32"?32e3:256*1024}var EXECUTABLE_RESERVE=4096;function argvCost(argument,platform2=process.platform){if(platform2!=="win32")return argument.length+1;let quotes=argument.match(/"/g)?.length??0,doubled=argument.match(/\\+(?="|$)/g)?.join("").length??0;return argument.length+3+quotes+doubled}var LINUX_MAX_ARG_STRLEN=131072;function commandLineOverflow(args,platform2=process.platform){let budget=argvBudget(platform2),length=EXECUTABLE_RESERVE+args.reduce((sum,argument)=>sum+argvCost(argument,platform2),0);if(length>budget)return`the ripgrep command line would be ${length} characters, over the ${budget}-character limit on ${platform2}`;if(platform2!=="linux")return;let longest=Math.max(0,...args.map(argument=>Buffer.byteLength(argument)));if(longest>=LINUX_MAX_ARG_STRLEN)return`one ripgrep argument is ${longest} bytes, over Linux's ${LINUX_MAX_ARG_STRLEN-1}-byte per-argument limit`}function roomAfter(fixed,budget,platform2=process.platform){return budget-EXECUTABLE_RESERVE-fixed.reduce((sum,argument)=>sum+argvCost(argument,platform2),0)}function packArgv(items,costOf,room){let batches=[],used=0;for(let item of items){let cost=costOf(item),batch=batches.at(-1);batch&&used+cost<=room?(batch.push(item),used+=cost):(batches.push([item]),used=cost)}return batches}import{sep}from"node:path";var pathOrder=(a,b)=>Buffer.compare(Buffer.from(a),Buffer.from(b)),slashPath=path=>path.split(sep).join("/");import{open}from"node:fs/promises";import{createInterface}from"node:readline";import{resolve}from"node:path";function parseRgEvent(line){let event=JSON.parse(line);if(!event||!["begin","match","context","end","summary"].includes(event.type)||!event.data)throw new Error("Invalid ripgrep JSON event");return event}function decode(value){if(typeof value?.text=="string")return value.text;if(typeof value?.bytes=="string")return Buffer.from(value.bytes,"base64").toString("utf8");throw new GrepEngineError("ENGINE_UNAVAILABLE","Invalid ripgrep JSON text/bytes field")}function collectSegmentRows(segment,request,oversized){let first=segment[0],files=new Map,byPath=new Map(segment.map(candidate=>[candidate.absolute,candidate])),segmentBinary=new Set;return{files,segmentBinary,onEvent:event=>{if(event.type==="summary")return;let candidate=oversized?first:byPath.get(resolve(first.root.cwd,decode(event.data.path)));if(!candidate)throw new Error("ripgrep searched a file outside the ordered segment");if(event.type==="begin"){files.set(candidate.display,{candidate,rows:new Map});return}if(event.type==="end"){event.data.binary_offset!=null&&(files.delete(candidate.display),segmentBinary.add(candidate.display));return}let file=files.get(candidate.display);if(!file||typeof event.data.line_number!="number")throw new Error("ripgrep match/context without a begin or line number");let text=decode(event.data.lines).replace(/\n$/,"").split(`
|
|
3
3
|
`);for(let[index,physical]of text.entries()){let line=event.data.line_number+index;if(line<(request.lineStart??1)||line>(request.lineEnd??1/0))continue;let isContext=event.type==="context",existing=file.rows.get(line);if(existing&&(!existing.isContext||isContext))continue;let column=!isContext&&index===0&&event.data.submatches?.[0]?event.data.submatches[0].start+1:void 0,content=physical.replace(/\r$/,""),truncated=!1;if(request.maxColumns!==void 0){let scalars=Array.from(content);scalars.length>request.maxColumns&&(content=`${scalars.slice(0,request.maxColumns).join("")}...`,truncated=!0)}file.rows.set(line,{path:candidate.display,line,column,text:content,isContext,truncated})}}}}var SearchTimeout=class extends Error{};function rgError(message){return/look-around|backreference/i.test(message)?new GrepEngineError("UNSUPPORTED_REGEX",message):/regex parse error|PCRE2: error compiling pattern|the literal .* is not allowed in a regex/i.test(message)?new GrepEngineError("INVALID_PATTERN",message):/error parsing glob/i.test(message)?new GrepEngineError("INVALID_GLOB",message):/unrecognized file type|unknown file type/i.test(message)?new GrepEngineError("UNKNOWN_TYPE",message):new GrepEngineError("ENGINE_UNAVAILABLE",message)}function onlyNoFilesWarnings(stderr){let lines=stderr.trim().split(/\r?\n/);return lines.some(line=>line.startsWith("No files were searched"))&&lines.every(line=>line.startsWith("No files were searched")||line==="Running with --debug will show why files are being skipped.")}function createRgRunner({executable,launch,now,deadline,signal,check}){return async(args,cwd,onEvent,input)=>{check();let overflow=commandLineOverflow(args);if(overflow)throw new GrepEngineError("ENGINE_UNAVAILABLE",`Cannot run ripgrep: ${overflow}. Search fewer paths at once.`);return new Promise((resolveRun,reject)=>{let child=launch(executable,args,{cwd,stdio:"pipe"}),chunks=[],stderr="",failure,timedOut=!1,stop=()=>{child.exitCode===null&&child.signalCode===null&&signalSpawnedChild(child,"SIGTERM")},onAbort=()=>{stop()},timer=setTimeout(()=>{timedOut=!0,stop()},Math.max(0,deadline-now()));signal?.addEventListener("abort",onAbort,{once:!0});let lines=onEvent?createInterface({input:child.stdout}):void 0;lines?.on("line",line=>{if(!failure)try{onEvent?.(parseRgEvent(line))}catch(error){failure=new GrepEngineError("ENGINE_UNAVAILABLE",`Malformed ripgrep JSON: ${String(error)}`),stop()}}),onEvent||child.stdout.on("data",chunk=>chunks.push(chunk)),child.stderr.setEncoding("utf8").on("data",chunk=>{stderr+=chunk}),child.on("error",error=>{failure=new GrepEngineError("ENGINE_UNAVAILABLE",`Failed to run ripgrep: ${error.message}`)}),child.stdin.on("error",error=>{error.code!=="EPIPE"&&(failure=new GrepEngineError("ENGINE_UNAVAILABLE",`Failed to write ripgrep input: ${error.message}`),stop())}),child.on("close",code=>{clearTimeout(timer),lines?.close(),signal?.removeEventListener("abort",onAbort),signal?.aborted?reject(new GrepEngineError("ABORTED","Grep search aborted")):timedOut||now()>=deadline?reject(new SearchTimeout):failure?reject(failure):code!==0&&code!==1&&!(code===2&&onlyNoFilesWarnings(stderr))?reject(rgError(stderr.trim()||`ripgrep exited with code ${code}`)):resolveRun(Buffer.concat(chunks))}),input!==void 0&&child.stdin.end(input),signal?.aborted&&onAbort()})}}var MAX_FILE_BYTES=4194304;async function readSearchablePrefix(candidate,result,check){let prefix;try{let file=await open(candidate.absolute,"r");try{let buffer=Buffer.alloc(MAX_FILE_BYTES),length=0;for(;length<buffer.length;){check();let{bytesRead}=await file.read(buffer,length,buffer.length-length,length);if(bytesRead===0)break;length+=bytesRead}prefix=buffer.subarray(0,length)}finally{await file.close()}}catch(error){if(error instanceof SearchTimeout||error instanceof GrepEngineError)throw error;check(),result.skippedOversized++,result.warnings.push({path:candidate.display,code:"SKIPPED_OVERSIZED",message:String(error)});return}if(check(),prefix.indexOf(0)!==-1){result.skippedBinary++;return}let newline=prefix.lastIndexOf(10);if(newline===-1){result.skippedOversized++;return}return prefix.subarray(0,newline+1)}function walkerFlags(request){let args=[];(request.hidden??!0)&&args.push("--hidden"),request.gitignore??!0?args.push("--no-require-git"):args.push("--no-ignore");for(let glob of request.glob?.filter(glob2=>!glob2.startsWith("!"))??[])args.push("-g",glob);for(let glob of request.glob?.filter(glob2=>glob2.startsWith("!"))??[])args.push("-g",glob);return request.type&&args.push("--type",request.type),(request.hidden??!0)&&args.push("-g","!.git"),args}function matcherFlags(request){let args=["--json","--line-number","--color=never","--encoding","none"];return request.ignoreCase&&args.push("-i"),request.literal&&args.push("-F"),request.multiline&&args.push("-U"),request.contextBefore!==void 0&&args.push("-B",String(request.contextBefore)),request.contextAfter!==void 0&&args.push("-A",String(request.contextAfter)),request.pcre2&&args.push("--pcre2"),request.mode==="files"?args.push("-m","1"):(request.mode??"content")==="content"&&request.maxCountPerFile!==void 0&&request.lineStart===void 0&&request.lineEnd===void 0&&args.push("-m",String(request.maxCountPerFile+1)),args}function candidateArgument(candidate){return candidate.root.file?candidate.root.path:`/${slashPath(relative(candidate.root.cwd,candidate.absolute)).replace(/[\\*?[\]{}!]/g,"\\$&")}`}function argumentCost(candidate,platform2=process.platform){let argument=argvCost(candidateArgument(candidate),platform2);return candidate.root.file?argument:argument+argvCost("-g",platform2)}function segmentFlags(segment,pattern,walk,matcher){let first=segment[0],limits=["--sort","path","--max-filesize",String(MAX_FILE_BYTES),...walk];if(first.root.file)return[...matcher,...limits,"--",pattern,...segment.map(candidateArgument)];let includes=["-g","!**/*","-g","**/"];for(let candidate of segment)includes.push("-g",candidateArgument(candidate));return[...matcher,...limits,...includes,"--",pattern,first.root.path]}import{realpath,stat}from"node:fs/promises";import{basename,dirname,relative as relative2,resolve as resolve2}from"node:path";async function resolveRoots(request,result){let roots=[];for(let path of new Set(request.paths))try{let[info,canonical]=await Promise.all([stat(path),realpath(path)]);roots.push({path:canonical,alias:path,cwd:info.isDirectory()?canonical:dirname(canonical),file:info.isFile()})}catch(error){if(error.code!=="ENOENT")throw error;result.missingPaths.push(path)}if(roots.length===0)throw new GrepEngineError("PATH_NOT_FOUND",`No search paths exist: ${request.paths.join(", ")}`);return roots}async function enumerateCandidates({roots,cwd,walk,run,check,result,budget=argvBudget()}){let candidates=new Map;for(let root of roots){let listed=root.file?[root.path]:(await run(["--files","--null","--sort","path",...walk,"--",root.path],root.cwd)).toString("utf8").split("\0").filter(Boolean);for(let path of listed){check();let absolute=resolve2(root.cwd,path),[canonical,info]=await Promise.all([realpath(absolute),stat(absolute)]).catch(error=>{throw root.file&&error.code==="ENOENT"?new GrepEngineError("ENGINE_UNAVAILABLE",`${root.path}: No such file or directory`):error}),alias=resolve2(root.alias,relative2(root.path,absolute)),display=slashPath(relative2(cwd,alias))||basename(alias),existing=candidates.get(canonical);(!existing||pathOrder(display,existing.display)<0)&&candidates.set(canonical,{absolute,canonical,display,root,size:info.size})}}let binaryPaths=new Set,scanned=roots.filter(root=>(candidates.get(root.path)?.size??0)<=MAX_FILE_BYTES),files=scanned.filter(root=>root.file),nulScan=["-a","-l","--null","--sort","path","--encoding","none","--max-filesize",String(MAX_FILE_BYTES),...walk,"-e","\\x00","--"],room=roomAfter(nulScan,budget),scans=[...packArgv(files,root=>argvCost(root.path),room).map(batch=>({cwd:batch[0].cwd,paths:batch.map(root=>root.path)})),...scanned.filter(root=>!root.file).map(root=>({cwd:root.cwd,paths:[root.path]}))];for(let scan of scans){let output=await run([...nulScan,...scan.paths],scan.cwd);for(let path of output.toString("utf8").split("\0").filter(Boolean))binaryPaths.add(await realpath(resolve2(scan.cwd,path)))}return result.skippedBinary=[...binaryPaths].filter(path=>candidates.has(path)).length,[...candidates.values()].sort((a,b)=>pathOrder(a.display,b.display)).map((candidate,index)=>({...candidate,ordinal:index+1,binary:binaryPaths.has(candidate.canonical)}))}var CAPPED_BATCH_SIZE=200,MAX_CAPPED_BATCH_SIZE=1600;function cappedLimit(head){return Math.min(MAX_CAPPED_BATCH_SIZE,Math.max(CAPPED_BATCH_SIZE,head.ordinal-1))}function joins(previous,candidate,request){let head=previous[0];return head.size>MAX_FILE_BYTES||candidate.size>MAX_FILE_BYTES?!1:(head.root.file&&candidate.root.file||!head.binary&&!candidate.binary&&head.root===candidate.root)&&(request.maxCount===void 0||previous.length<cappedLimit(head))}function planSegments(ordered,request,plan){let platform2=plan.platform??process.platform,budget=plan.budget??argvBudget(platform2),segments=[],room=0;for(let candidate of ordered){let previous=segments.at(-1),cost=candidate.binary?0:argumentCost(candidate,platform2);previous&&joins(previous,candidate,request)&&cost<=room?(previous.push(candidate),room-=cost):(segments.push([candidate]),room=roomAfter(segmentFlags([candidate],request.pattern,plan.walk,plan.matcher),budget,platform2))}return segments}function admitFiles(files,request,result){let lastCommitted,segmentFiles=[...files.values()].sort((a,b)=>pathOrder(a.candidate.display,b.candidate.display));for(let file of segmentFiles){let rows=[...file.rows.values()].sort((a,b)=>a.line-b.line||(a.column??0)-(b.column??0)),matching=rows.filter(row=>!row.isContext);if(matching.length===0)continue;let perFileCap=request.maxCountPerFile??1/0,perFileLimited=request.mode!=="files"&&matching.length>perFileCap;result.perFileLimitReached||=perFileLimited;let remaining=Math.max(0,(request.maxCount??1/0)-(request.mode==="files"?result.counts.files:result.counts.matches??0)),admitted=matching.slice(0,request.mode==="files"?remaining>0?1:0:Math.min(perFileCap,remaining)),available=request.mode==="files"?1:Math.min(matching.length,perFileCap);if(admitted.length<available&&(result.limitReached=!0),admitted.length!==0)if(lastCommitted=file.candidate,result.counts.files++,result.counts.matches!==null&&(result.counts.matches+=admitted.length),request.mode==="count"||request.mode==="files")result.fileCounts.push({path:file.candidate.display,count:request.mode==="files"?null:admitted.length,limitReached:perFileLimited});else{let lines=new Set(admitted.map(row=>row.line));for(let row of rows)(lines.has(row.line)||row.isContext&&admitted.some(match=>row.line>=match.line-(request.contextBefore??0)&&row.line<=match.line+(request.contextAfter??0)))&&result.matches.push(row)}}return lastCommitted}async function searchSegments({candidates,request,walk,matcher,run,check,result,budget}){let segments=planSegments(candidates,request,{walk,matcher,budget}),matcherRan=!1;for(let[segmentIndex,segment]of segments.entries()){check();let searchable=segment.filter(candidate=>!candidate.binary);if(searchable.length===0){result.filesSearched=segment[segment.length-1].ordinal;continue}let first=searchable[0],oversized=first.size>MAX_FILE_BYTES,prefix=oversized?await readSearchablePrefix(first,result,check):void 0;if(oversized&&prefix===void 0){result.filesSearched=first.ordinal;continue}let{files,segmentBinary,onEvent}=collectSegmentRows(searchable,request,oversized);matcherRan=!0,oversized?await run([...matcher,"--",request.pattern],request.cwd,onEvent,prefix):await run(segmentFlags(searchable,request.pattern,walk,matcher),first.root.cwd,onEvent),check(),oversized&&result.prefixSearched++,result.skippedBinary+=segmentBinary.size;let lastCommitted=admitFiles(files,request,result);result.filesSearched=segment[segment.length-1].ordinal;let admittedCount=request.mode==="files"?result.counts.files:result.counts.matches??0;if(request.maxCount!==void 0&&admittedCount>=request.maxCount){lastCommitted&&(result.filesSearched=lastCommitted.ordinal),segmentIndex<segments.length-1&&(result.limitReached=!0);break}}matcherRan||await run([...matcher,"--",request.pattern],request.cwd,()=>{},Buffer.alloc(0))}var RgGrepEngine=class{constructor(options={}){this.name="rg",this.launch=options.spawn??spawn,this.now=options.now??Date.now,this.batchBudget=options.batchBudget}async search(request,signal){let started=this.now(),deadline=started+(request.timeoutMs??3e4),result={matches:[],fileCounts:[],counts:{matches:request.mode==="files"?null:0,files:0,exact:!0},filesSearched:0,limitReached:!1,perFileLimitReached:!1,skippedOversized:0,prefixSearched:0,skippedBinary:0,missingPaths:[],warnings:[],timedOut:!1,elapsedMs:0,effectivePattern:request.pattern,patternKind:request.literal?"literal":"regex",regexEngine:request.pcre2?"pcre2":"rust"},check=()=>{if(signal?.aborted)throw new GrepEngineError("ABORTED","Grep search aborted");if(this.now()>=deadline)throw new SearchTimeout},overflow=commandLineOverflow([request.pattern]);if(overflow)throw new GrepEngineError("INVALID_PATTERN",`Pattern is too long to pass to ripgrep: ${overflow}. Shorten it.`);try{check();let roots=await resolveRoots(request,result);check();let executable=await ensureTool("rg");if(!executable)throw new GrepEngineError("ENGINE_UNAVAILABLE","ripgrep is unavailable and could not be downloaded");let walk=walkerFlags(request),matcher=matcherFlags(request),run=createRgRunner({executable,launch:(command,args,options)=>this.launch(command,args,options),now:()=>this.now(),deadline,signal,check}),candidates=await enumerateCandidates({roots,cwd:request.cwd,walk,run,check,result,budget:this.batchBudget});await searchSegments({candidates,request,walk,matcher,run,check,result,budget:this.batchBudget})}catch(error){if(!(error instanceof SearchTimeout))throw error;result.timedOut=!0,result.warnings.push({code:"TIMED_OUT",message:`Timed out after ${request.timeoutMs??3e4} ms; showing the completed ordered prefix.`})}return result.counts.exact=!result.limitReached&&!result.perFileLimitReached&&!result.timedOut,result.elapsedMs=Math.max(0,this.now()-started),result}};function createRgEngine(options={}){return new RgGrepEngine(options)}export{ensureTool,RgGrepEngine,createRgEngine};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
+
import{emitProviderAccountsChanged,slotsOfOwnKind}from"./chunk-SJWTZ3Z2.js";import{discoverEnvSlots}from"./chunk-VDDJADPV.js";import{signalSpawnedChild}from"./chunk-KLAX467B.js";import{CredentialSlotRepository,applicableStoredState}from"./chunk-RUOTFZQR.js";import{applyAccountOrder,isAvailable,isSlotBlocked,withoutOrderedAccount}from"./chunk-6ISOXWH2.js";import{activeModelBlockUntil,pruneModelBlocks}from"./chunk-6VWIMHMH.js";import{accountDisplayName,listSlots,normalizeProviderId,pinSlot,removeSlot,renameSlotDisplayName}from"./chunk-AVP6DDBF.js";import{getAgentDir}from"./chunk-SODMQEHO.js";import{lstat as lstat2}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";function isEnvSlot(slot){return slot.store===void 0}var SENTINEL_OAUTH_FIELDS={access:"claude-sdk-oauth-managed",refresh:"claude-sdk-oauth-managed",expires:41024448e5};function emptyCredential(){return{type:"oauth",...SENTINEL_OAUTH_FIELDS,accounts:[]}}function storedSlots(credential){return credential.accounts??[]}function isListedStoredSlot(slot){return"store"in slot&&slot.store==="claude-cli"}function listAccounts(credential,env){let slots=storedSlots(credential).filter(isListedStoredSlot);if(env){let state=credential.slotState??{};for(let slot of envSlots(env)){let persisted=state[slot.name];slots.push(persisted?{...slot,...persisted}:slot)}}return slots}var ACCOUNT_NAME_PATTERN=/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;function assertValidAccountName(name){if(!ACCOUNT_NAME_PATTERN.test(name))throw new Error(`Invalid account name '${name}': use letters, digits, '-' or '_', starting with a letter or digit`)}function pinAccount(credential,name){return{...credential,pinned:name}}function envSlots(env){let slots=[],read=suffix=>env(suffix===void 0?"CLAUDE_CODE_OAUTH_TOKEN":`CLAUDE_CODE_OAUTH_TOKEN_${suffix}`),names=[{slot:"env"}];for(let index=2;index<=16;index++)names.push({suffix:String(index),slot:`env-${index}`});for(let{suffix,slot}of names)read(suffix)&&slots.push({name:slot,refresh:"",access:"",expires:0,source:"env"});return slots}function envSlotToken(env,slotName){let match=/^env(?:-(\d+))?$/.exec(slotName);if(!match)return;let suffix=match[1];return env(suffix===void 0?"CLAUDE_CODE_OAUTH_TOKEN":`CLAUDE_CODE_OAUTH_TOKEN_${suffix}`)}import{createHash}from"node:crypto";var DEFAULT_AFFINITY_KEY="claude-sdk-oauth-default";function describeAccountState(state){let until=state.until===void 0?"re-login":new Date(state.until).toISOString(),login=state.reason==="auth_error"?` (run /login anthropic-subscription for ${state.name})`:"";return`${state.name}: ${state.reason} until ${until}${login}`}var AllAccountsBlockedError=class extends Error{constructor(soonestUnblockAt2,blockReason,limitedModel2,unavailableAccount,accounts=[]){let until=soonestUnblockAt2===void 0?void 0:new Date(soonestUnblockAt2).toISOString(),summary=limitedModel2!==void 0&&until!==void 0?`All Anthropic Subscription accounts have hit the usage limit for model ${limitedModel2} until ${until}.`:until===void 0?"All Anthropic Subscription accounts are blocked until re-login.":`All Anthropic Subscription accounts are blocked until ${until}.`;super(accounts.length===0?summary:`${summary} Accounts: ${accounts.map(describeAccountState).join("; ")}.`),this.accounts=accounts,this.limitedModel=limitedModel2,this.name="AllAccountsBlockedError",this.soonestUnblockAt=soonestUnblockAt2,this.blockReason=blockReason,this.unavailableAccount=unavailableAccount}};function getAffinityKey(options){return options.affinityKey??options.sessionId??DEFAULT_AFFINITY_KEY}function score(key,accountName){return createHash("sha256").update(`${key}\0${accountName}`).digest().readBigUInt64BE(0)}function rendezvousOrder(key,accounts){return[...accounts].map(account=>({account,score:score(key,account.name)})).sort((left,right)=>right.score>left.score?1:right.score<left.score?-1:0).map(({account})=>account)}function isAccountBlocked(account,now){return account.blockedUntil!==void 0&&account.blockedUntil>now}function isBlockedFor(account,now,model){return isAccountBlocked(account,now)||activeModelBlockUntil(account.modelBlocks,model,now)!==void 0}function clearExpiredBlocks(accounts,now=Date.now()){return accounts.map(account=>{let available=account;if(account.blockReason!==void 0&&(account.blockedUntil===void 0||account.blockedUntil<=now)){let{blockedUntil:_blockedUntil,blockReason:_blockReason,blockedAt:_blockedAt,...rest2}=account;available=rest2}if(available.modelBlocks===void 0)return available;let{modelBlocks,...rest}=available,live=pruneModelBlocks(modelBlocks,now);return live===void 0?rest:{...rest,modelBlocks:live}})}function selectUnblocked(accounts,options,now){let pinned=options.pinnedAccount===void 0?void 0:accounts.find(account=>account.name===options.pinnedAccount);if(pinned&&!isBlockedFor(pinned,now,options.model))return pinned;let preferred=options.preferredAccount===void 0?void 0:accounts.find(account=>account.name===options.preferredAccount);return preferred&&!isBlockedFor(preferred,now,options.model)?preferred:applyAccountOrder(options.accountOrder,rendezvousOrder(getAffinityKey(options),accounts)).find(account=>!isBlockedFor(account,now,options.model))}function unblockAt(account,now,model){let accountUntil=account.blockedUntil!==void 0&&account.blockedUntil>now?account.blockedUntil:void 0,modelUntil=activeModelBlockUntil(account.modelBlocks,model,now);return accountUntil===void 0?modelUntil:modelUntil===void 0?accountUntil:Math.max(accountUntil,modelUntil)}function soonestUnblockAt(accounts,now,model){let candidates=accounts.map(account=>unblockAt(account,now,model)).filter(value=>value!==void 0);return candidates.length===0?void 0:Math.min(...candidates)}function limitedModel(accounts,now,model){return accounts.some(account=>!isAccountBlocked(account,now)&&activeModelBlockUntil(account.modelBlocks,model,now)!==void 0)?model:void 0}function selectAccount(accounts,options={}){let now=options.now??Date.now(),candidates=accounts,unavailableAccount;if(options.accountFallback===!1){let name=options.pinnedAccount??options.preferredAccount??applyAccountOrder(options.accountOrder,rendezvousOrder(getAffinityKey(options),accounts))[0]?.name;candidates=accounts.filter(account=>account.name===name);let pinnedBy=options.pinnedAccount!==void 0?options.pinSource:void 0;name!==void 0&&(unavailableAccount={name,configured:candidates.length>0,...pinnedBy===void 0?{}:{pinnedBy}})}let selected=selectUnblocked(candidates,options,now);if(selected)return selected;let cleared=clearExpiredBlocks(candidates,now),afterClear=selectUnblocked(cleared,options,now);if(afterClear)return afterClear;throw new AllAccountsBlockedError(soonestUnblockAt(candidates,now,options.model),candidates.length>0&&candidates.every(account=>account.blockReason==="auth_error")?"auth_error":void 0,limitedModel(candidates,now,options.model),unavailableAccount,candidates.map(account=>({name:account.name,reason:account.blockReason??(isAccountBlocked(account,now)?"blocked":"model_limit"),until:unblockAt(account,now,options.model)})))}import{randomBytes}from"node:crypto";import{chmodSync,lstatSync,mkdirSync,readlinkSync,symlinkSync,unlinkSync}from"node:fs";import{lstat,mkdir,rm,unlink}from"node:fs/promises";import{homedir}from"node:os";import{join,resolve}from"node:path";import{spawn}from"node:child_process";function isClaudeOauthTokenName(name){return name==="CLAUDE_CODE_OAUTH_TOKEN"||/^CLAUDE_CODE_OAUTH_TOKEN_\d+$/.test(name)}function hasRequestOauthToken(requestEnvironment){return Object.entries(requestEnvironment??{}).some(([name,value])=>isClaudeOauthTokenName(name)&&!!value)}function mergeRequestAuthEnvironment(hostEnvironment,requestEnvironment){let environment={...hostEnvironment},requestTokens=Object.entries(requestEnvironment??{}).filter(([name])=>isClaudeOauthTokenName(name));if(requestTokens.length===0)return environment;for(let name of Object.keys(environment))isClaudeOauthTokenName(name)&&delete environment[name];for(let[name,value]of requestTokens)environment[name]=value;return environment}function stripManagedAuthEnvironment(parent){let{ANTHROPIC_API_KEY:_apiKey,ANTHROPIC_AUTH_TOKEN:_authToken,ANTHROPIC_BASE_URL:_gateway,ANTHROPIC_CUSTOM_HEADERS:_customHeaders,CLAUDE_CODE_OAUTH_TOKEN:_oauthToken,CLAUDE_CODE_USE_BEDROCK:_bedrock,CLAUDE_CODE_USE_FOUNDRY:_foundry,CLAUDE_CODE_USE_GATEWAY:_gatewayMode,CLAUDE_CODE_USE_VERTEX:_vertex,...environment}=parent;for(let name of Object.keys(environment))/^CLAUDE_CODE_OAUTH_TOKEN_\d+$/.test(name)&&delete environment[name],name.startsWith("SENPI_")&&delete environment[name];return environment}var HOST_REDIRECT_NAMES=["CLAUDE_SECURESTORAGE_CONFIG_DIR","CLAUDE_CONFIG_DIR","BROWSER"],INHERITED_CREDENTIAL_DESCRIPTORS=["CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR","CLAUDE_CODE_API_KEY_FILE_DESCRIPTOR"];function buildClaudeCliEnvironment(parent,options){let environment=stripManagedAuthEnvironment(parent);for(let name of[...HOST_REDIRECT_NAMES,...INHERITED_CREDENTIAL_DESCRIPTORS])delete environment[name];return environment.CLAUDE_CONFIG_DIR=options.configDir,environment.NO_COLOR="1",options.browser!==void 0&&(environment.BROWSER=options.browser),environment}function spawnClaudeCli(run,args,browser){return spawn(run.executable,[...args],{cwd:run.configDir,env:buildClaudeCliEnvironment(run.parentEnv??process.env,{configDir:run.configDir,...browser===void 0?{}:{browser}}),stdio:["pipe","pipe","pipe"],windowsHide:!0})}function stopClaudeCli(child,graceMs){if(child.exitCode!==null||child.signalCode!==null)return;signalSpawnedChild(child,"SIGTERM");let escalate=setTimeout(()=>signalSpawnedChild(child,"SIGKILL"),graceMs);escalate.unref?.(),child.once("close",()=>clearTimeout(escalate))}var DEFAULT_SHORT_COMMAND_TIMEOUT_MS=1e4;function runClaudeCliToExit(run,args,timeoutMs=DEFAULT_SHORT_COMMAND_TIMEOUT_MS,signal){return signal?.aborted?Promise.resolve(void 0):new Promise(resolve2=>{let child=spawnClaudeCli(run,args);child.stdin?.end();let stdout="";child.stdout?.setEncoding("utf8"),child.stdout?.on("data",chunk=>{stdout+=chunk}),child.stderr?.resume();let deadline=setTimeout(()=>{signalSpawnedChild(child,"SIGKILL"),resolve2(void 0)},timeoutMs);deadline.unref?.();let onAbort=()=>{clearTimeout(deadline),signalSpawnedChild(child,"SIGKILL"),resolve2(void 0)};signal?.addEventListener("abort",onAbort,{once:!0}),child.once("error",()=>{clearTimeout(deadline),signal?.removeEventListener("abort",onAbort),resolve2(void 0)}),child.once("close",exitCode=>{clearTimeout(deadline),signal?.removeEventListener("abort",onAbort),resolve2({exitCode,stdout})})})}function stringField(record,name){let value=record[name];return typeof value=="string"&&value.length>0?value:void 0}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function parseClaudeCliAuthStatus(stdout,exitCode){let parsed;try{parsed=JSON.parse(stdout)}catch{return{state:"unreadable"}}if(!isRecord(parsed)||typeof parsed.loggedIn!="boolean")return{state:"unreadable"};if(!parsed.loggedIn)return exitCode===0?{state:"unreadable"}:{state:"signed_out"};if(exitCode!==0)return{state:"unreadable"};if(parsed.authMethod!=="claude.ai")return{state:"rejected",reason:"auth_method"};if(parsed.apiProvider!=="firstParty")return{state:"rejected",reason:"api_provider"};let email=stringField(parsed,"email"),orgName=stringField(parsed,"orgName"),subscriptionType=stringField(parsed,"subscriptionType");return{state:"signed_in",profile:{...email===void 0?{}:{email},...orgName===void 0?{}:{orgName},...subscriptionType===void 0?{}:{subscriptionType}}}}async function readClaudeCliAuthStatus(run,timeoutMs){let exit=await runClaudeCliToExit(run,["auth","status","--json"],timeoutMs);return exit===void 0?{state:"unreadable"}:parseClaudeCliAuthStatus(exit.stdout,exit.exitCode)}async function logoutClaudeCli(run,timeoutMs,signal){return(await runClaudeCliToExit(run,["auth","logout"],timeoutMs,signal))?.exitCode===0}var CLAUDE_CLI_SHARED_LINKS=["projects","settings.json","CLAUDE.md","agents","commands","skills","output-styles"],SHARED_FILES=new Set(["settings.json","CLAUDE.md"]),DIR_ID_PATTERN=/^[0-9a-f]{32}$/;function newAccountDirId(){return randomBytes(16).toString("hex")}function isValidAccountDirId(dirId){return DIR_ID_PATTERN.test(dirId)}function accountDirFor(agentDir,dirId){if(!isValidAccountDirId(dirId))throw new Error("Invalid Claude account dir id");return join(agentDir,"anthropic-subscription-claude",dirId)}function claudeCliSharedRoot(env){let inherited=env.CLAUDE_CONFIG_DIR;return inherited?resolve(inherited):join(homedir(),".claude")}function isLink(path){try{return lstatSync(path).isSymbolicLink()}catch{return!1}}function exists(path){try{return lstatSync(path),!0}catch{return!1}}async function lstatOrUndefined(path){try{return await lstat(path)}catch(error){if(error.code==="ENOENT")return;throw error}}function linkEntry(entry,target,path){if(!SHARED_FILES.has(entry)){mkdirSync(target,{recursive:!0}),symlinkSync(target,path,process.platform==="win32"?"junction":"dir");return}if(exists(target))try{symlinkSync(target,path,"file")}catch(error){if(process.platform!=="win32")throw error}}function ensureAccountDir(options){let accountDir=accountDirFor(options.agentDir,options.dirId);mkdirSync(accountDir,{recursive:!0,mode:448}),process.platform!=="win32"&&chmodSync(accountDir,448);for(let entry of CLAUDE_CLI_SHARED_LINKS){let path=join(accountDir,entry),target=join(options.sharedRoot,entry);if(isLink(path)){if(resolve(accountDir,readlinkSync(path))===resolve(target))continue;unlinkSync(path)}else if(exists(path))continue;linkEntry(entry,target,path)}return accountDir}async function removeAccountDir(options){let accountDir=accountDirFor(options.agentDir,options.dirId);if(options.signal?.throwIfAborted(),await lstatOrUndefined(accountDir)===void 0&&await mkdir(accountDir,{recursive:!0,mode:448}),!(await lstatOrUndefined(accountDir))?.isDirectory())return"not_an_account_dir";let signedOut=options.executable!==void 0&&await logoutClaudeCli({executable:options.executable,configDir:accountDir,...options.parentEnv===void 0?{}:{parentEnv:options.parentEnv}},void 0,options.signal).catch(()=>!1);options.signal?.throwIfAborted();for(let entry of CLAUDE_CLI_SHARED_LINKS){let path=join(accountDir,entry);(await lstatOrUndefined(path))?.isSymbolicLink()&&await unlink(path)}return await rm(accountDir,{recursive:!0,force:!0}),signedOut?"removed":"removed_without_sign_out"}import{readFileSync as readFileSync3,statSync}from"node:fs";import{createRequire}from"node:module";import{dirname as dirname2,posix as posix2,win32 as win322}from"node:path";import{createHash as createHash2}from"crypto";import{chmodSync as chmodSync2,existsSync,lstatSync as lstatSync2,mkdirSync as mkdirSync2,readFileSync,renameSync,unlinkSync as unlinkSync2,writeFileSync}from"fs";import{tmpdir as osTmpdir}from"os";import{basename,join as join2}from"path";function tmpdir(){return process.env.CLAUDE_CODE_TMPDIR?process.env.CLAUDE_CODE_TMPDIR:process.platform==="darwin"?"/tmp":osTmpdir()}function safeTempBase(){let dir=join2(tmpdir(),process.platform==="win32"?"claude":`claude-${process.getuid?.()??0}`);if(typeof process.getuid=="function"){mkdirSync2(dir,{recursive:!0,mode:448});let uid=process.getuid(),st=lstatSync2(dir);if(!st.isDirectory())throw new Error(`Temp directory ${dir} is not a directory (may be an attacker-planted symlink). Refusing to use it.`);if(st.uid!==uid)throw new Error(`Temp directory ${dir} is owned by uid ${st.uid}, expected ${uid}. Refusing to use it \u2014 another user may have pre-created it.`);(st.mode&511)!==448&&chmodSync2(dir,448)}else try{mkdirSync2(dir,{recursive:!0,mode:448})}catch{}return dir}function extractFromBunfs(embeddedPath){if(!embeddedPath.includes("$bunfs")&&!embeddedPath.includes("~BUN"))return embeddedPath;try{let content=readFileSync(embeddedPath),hash=createHash2("sha256").update(content).digest("hex").slice(0,16),tmpDir=join2(safeTempBase(),`claude-agent-sdk-${hash}`),fileName=basename(embeddedPath),tmpPath=join2(tmpDir,fileName);if(mkdirSync2(tmpDir,{recursive:!0,mode:448}),existsSync(tmpPath))return tmpPath;let tmpFile=join2(tmpDir,`${fileName}.tmp.${process.pid}`);writeFileSync(tmpFile,content),chmodSync2(tmpFile,493);try{renameSync(tmpFile,tmpPath)}catch(e){if((e.code==="EPERM"||e.code==="EBUSY")&&existsSync(tmpPath)){try{unlinkSync2(tmpFile)}catch{}return tmpPath}throw e}return tmpPath}catch(err){return console.warn(`[claude-agent-sdk] Failed to extract CLI from $bunfs: ${err.message}. Child processes cannot access $bunfs paths \u2014 the CLI will likely fail to start.`),embeddedPath}}import{posix,win32}from"node:path";var WIN32_BATCH_EXTENSIONS=new Set([".bat",".cmd"]),CMD_SHIM_NATIVE_TARGET=/"%~?dp0%?\\([^"%]+?\.exe)"/i;function nativeTargetOfBatchFile(batchPath,deps){let text=deps.readText?.(batchPath),match=text===void 0?null:CMD_SHIM_NATIVE_TARGET.exec(text);if(!match?.[1])return;let target=win32.join(win32.dirname(batchPath),match[1]);return deps.isFile(target)?target:void 0}var WIN32_DEFAULT_PATHEXT=".COM;.EXE;.BAT;.CMD";function namesToProbe(name,platform,pathext){return platform!=="win32"?[name]:(pathext??WIN32_DEFAULT_PATHEXT).split(";").filter(extension=>extension.length>0).map(extension=>extension.toLowerCase()).map(extension=>`${name}${extension}`)}function pathDirectories(platform,path){if(path===void 0)return[];let delimiter=platform==="win32"?";":":";return path.split(delimiter).map(entry=>platform==="win32"?entry.replace(/^"(.*)"$/,"$1"):entry).filter(entry=>entry.length>0)}function findExecutableOnPath(name,deps){let join5=deps.platform==="win32"?win32.join:posix.join,names=namesToProbe(name,deps.platform,deps.env("PATHEXT"));for(let directory of pathDirectories(deps.platform,deps.env("PATH")))for(let candidate of names){let path=join5(directory,candidate);if(!deps.isFile(path))continue;if(deps.platform!=="win32"||!WIN32_BATCH_EXTENSIONS.has(win32.extname(path).toLowerCase()))return path;let target=nativeTargetOfBatchFile(path,deps);if(target!==void 0)return target;deps.onSkip?.(path)}}import{execFileSync}from"node:child_process";import{readFileSync as readFileSync2}from"node:fs";import{dirname,join as join3}from"node:path";import{fileURLToPath}from"node:url";var VERSION_PATTERN=/(\d+)\.(\d+)\.(\d+)/,VERSION_PROBE_TIMEOUT_MS=5e3;function parseClaudeCodeVersion(text){let match=text===void 0?null:VERSION_PATTERN.exec(text);if(match)return[Number(match[1]),Number(match[2]),Number(match[3])]}function isNewerClaudeCodeVersion(candidate,baseline){let left=parseClaudeCodeVersion(candidate),right=parseClaudeCodeVersion(baseline);if(left===void 0||right===void 0)return!1;for(let index=0;index<3;index++)if(left[index]!==right[index])return left[index]>right[index];return!1}var probedVersions=new Map;function probeClaudeCodeVersion(executable){if(probedVersions.has(executable))return probedVersions.get(executable);let version;try{let output=execFileSync(executable,["--version"],{encoding:"utf8",timeout:VERSION_PROBE_TIMEOUT_MS,windowsHide:!0,stdio:["ignore","pipe","ignore"]});version=VERSION_PATTERN.exec(output)?.[0]}catch{version=void 0}return probedVersions.set(executable,version),version}function bundledClaudeCodeVersion(){try{let entry=fileURLToPath(import.meta.resolve("@anthropic-ai/claude-agent-sdk")),manifest=JSON.parse(readFileSync2(join3(dirname(entry),"package.json"),"utf8"));return typeof manifest!="object"||manifest===null||!("claudeCodeVersion"in manifest)?void 0:typeof manifest.claudeCodeVersion=="string"?manifest.claudeCodeVersion:void 0}catch{return}}function claudeCodeExecutableCandidates(platform,arch,preferMusl=!1){let ext=platform==="win32"?".exe":"";if(platform==="linux"){let glibc=`@anthropic-ai/claude-agent-sdk-linux-${arch}/claude${ext}`,musl=`@anthropic-ai/claude-agent-sdk-linux-${arch}-musl/claude${ext}`;return preferMusl?[musl,glibc]:[glibc,musl]}return[`@anthropic-ai/claude-agent-sdk-${platform}-${arch}/claude${ext}`]}function spawnableSpelling(platform,candidate){return platform==="win32"?win322.toNamespacedPath(win322.resolve(candidate)):posix2.resolve(candidate)}function describeClaudeCodeExecutable(deps){let tried=[],accept=candidate=>{let spelled=spawnableSpelling(deps.platform,candidate);return tried.push(spelled),deps.isFile(spelled)?spelled:void 0},done=(executable,source)=>({executable,source,tried}),override=deps.env("CLAUDE_CODE_EXECUTABLE");if(override){let accepted=accept(override);if(accepted!==void 0)return done(accepted,"override")}let candidates=claudeCodeExecutableCandidates(deps.platform,deps.arch,deps.platform==="linux"&&deps.isMusl?.()===!0),bundled=acceptBundled(deps,candidates,accept,tried);if(bundled!==void 0){let newer=newerClaudeOnPath(deps,bundled);return newer===void 0?done(bundled,"bundled"):(tried.push(newer),done(newer,"path"))}let onPath=findExecutableOnPath("claude",{...deps,onSkip:batchFile=>tried.push(`${batchFile} (batch file wrapping no native binary)`)});if(onPath!==void 0){let accepted=accept(onPath);if(accepted!==void 0)return done(accepted,"path")}else tried.push(deps.env("PATH")?"claude on PATH":"claude on PATH (PATH is unset)");return{executable:void 0,source:void 0,tried}}function acceptBundled(deps,candidates,accept,tried){if(deps.isCompiledBun?.()&&deps.extractFromBunfs)for(let candidate of candidates){let extracted;try{extracted=deps.extractFromBunfs(deps.resolve(candidate))}catch{continue}let accepted=accept(extracted);if(accepted!==void 0)return accepted}for(let candidate of candidates){let resolved;try{resolved=deps.resolve(candidate)}catch{tried.push(candidate);continue}let accepted=accept(resolved);if(accepted!==void 0)return accepted}let executableDir=deps.isCompiledBun?.()?deps.executableDir?.():void 0;if(executableDir!==void 0){let path=deps.platform==="win32"?win322:posix2;for(let candidate of candidates){let accepted=accept(path.join(executableDir,"node_modules",...candidate.split("/")));if(accepted!==void 0)return accepted}}}function newerClaudeOnPath(deps,bundled){let versionOf=deps.versionOf;if(versionOf===void 0)return;let onPath=findExecutableOnPath("claude",deps);if(onPath===void 0)return;let spelled=spawnableSpelling(deps.platform,onPath);if(spelled===bundled||!deps.isFile(spelled))return;let pathVersion=versionOf(spelled);if(pathVersion===void 0)return;let bundledVersion=deps.bundledVersion?.()??versionOf(bundled);return isNewerClaudeCodeVersion(pathVersion,bundledVersion)?spelled:void 0}function resolveClaudeCodeExecutable(deps){return resolveClaudeCodeRun(deps).executable}function resolveClaudeCodeRun(deps){let resolution=describeClaudeCodeExecutable(deps);if(resolution.executable!==void 0&&resolution.source!==void 0)return{executable:resolution.executable,source:resolution.source};throw new Error([`Claude Code executable not found for ${deps.platform}-${deps.arch}. Tried:`,...resolution.tried.map(candidate=>` - ${candidate}`),"Reinstall @anthropic-ai/claude-agent-sdk without --omit=optional, install Claude Code so `claude` is on PATH, or set CLAUDE_CODE_EXECUTABLE to the binary."].join(`
|
|
3
|
+
`))}var defaultRequire=null,isCompiledBunBinary=import.meta.url.includes("$bunfs")||import.meta.url.includes("~BUN")||import.meta.url.includes("%7EBUN");function isMuslLinuxRuntime(){if(process.platform!=="linux"||typeof process.report?.getReport!="function")return!1;let report=process.report.getReport();return report===null||!("header"in report)||typeof report.header!="object"||report.header===null?!1:!("glibcVersionRuntime"in report.header)||report.header.glibcVersionRuntime===void 0}function readBatchFileText(path){try{return readFileSync3(path,"utf8")}catch{return}}function isRegularFile(path){try{return statSync(path).isFile()}catch{return!1}}var defaultDeps={platform:process.platform,arch:process.arch,env:name=>process.env[name],isFile:isRegularFile,readText:readBatchFileText,isMusl:isMuslLinuxRuntime,isCompiledBun:()=>isCompiledBunBinary,extractFromBunfs,bundledVersion:bundledClaudeCodeVersion,versionOf:probeClaudeCodeVersion,executableDir:()=>dirname2(process.execPath),resolve:spec=>(defaultRequire||(defaultRequire=createRequire(import.meta.resolve("@anthropic-ai/claude-agent-sdk"))),defaultRequire.resolve(spec))},activeDeps=defaultDeps;function defaultExecutableDeps(){return activeDeps}function objectField(value,key){let found=Object.entries(value).find(([candidate])=>candidate===key)?.[1];return typeof found=="object"&&found!==null&&!Array.isArray(found)?found:void 0}function storedCheck(slot){let check=objectField(slot,"check");if(check===void 0)return;let model=stringField2(check,"model"),outcome=stringField2(check,"outcome"),at=numberField(check,"at");if(model===void 0||at===void 0||outcome!=="ok"&&outcome!=="failed")return;let reason=stringField2(check,"reason");return{model,outcome,...reason===void 0?{}:{reason},at}}function claudeCliSlotFields(slot){if(stringField2(slot,"store")!=="claude-cli")return{};let profile=objectField(slot,"profile")??{},signedInAt=numberField(slot,"signedInAt"),email=stringField2(profile,"email"),orgName=stringField2(profile,"orgName"),subscriptionType=stringField2(profile,"subscriptionType"),check=storedCheck(slot);return{store:"claude-cli",...signedInAt===void 0?{}:{signedInAt},...email===void 0?{}:{email},...orgName===void 0?{}:{orgName},...subscriptionType===void 0?{}:{subscriptionType},...check===void 0?{}:{check},signIn:stringField2(slot,"signInRequired")===void 0?"signed_in":"needs_sign_in"}}var ACCOUNT_NAME_PATTERN2=/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;function assertValidAccountName2(name){if(!ACCOUNT_NAME_PATTERN2.test(name))throw new Error(`Invalid account name '${name}': use letters, digits, '-' or '_', starting with a letter or digit`)}function pooledFrom(credential){return credential===void 0?void 0:credential}function pinnedName(credential){return credential?.pinned}function numberField(value,key){let found=Object.entries(value).find(([candidate])=>candidate===key)?.[1];return typeof found=="number"?found:void 0}function credentialPoolRepository(storage){let authPath=storage.getStoragePath();return new CredentialSlotRepository(authPath?join4(dirname3(authPath),"credential-pool-state.json"):void 0)}function stringField2(value,key){let found=Object.entries(value).find(([candidate])=>candidate===key)?.[1];return typeof found=="string"?found:void 0}var UNBLOCKED={blocked:!1};function accountBlockedReason(reason){switch(reason){case"auth_error":case"rate_limit":return reason;case"account_disabled":return"disabled";default:return}}function liveBlock(reason,blockedUntil,now){let blockedReason=accountBlockedReason(reason);return blockedReason==="disabled"?{blocked:!0,blockedReason}:blockedUntil===void 0||blockedUntil<=now?UNBLOCKED:{blocked:!0,...blockedReason===void 0?{}:{blockedReason},blockedUntil}}function sidecarBlock(sidecar,now){return sidecar===void 0||isAvailable(sidecar,now)?UNBLOCKED:liveBlock(sidecar?.blockReason,sidecar?.blockedUntil,now)}function storedSlotBlock(provider,slot,now){let blockReason=stringField2(slot,"blockReason"),blockedUntil=numberField(slot,"blockedUntil"),blockedReason=accountBlockedReason(blockReason);return blockedReason==="disabled"?{blocked:!0,blockedReason}:(normalizeProviderId(provider)==="anthropic-subscription"?isAccountBlocked({blockedUntil},now):isSlotBlocked({blockReason,blockedUntil},now))?{blocked:!0,...blockedReason===void 0?{}:{blockedReason},...blockedUntil===void 0||blockedUntil<=now?{}:{blockedUntil}}:UNBLOCKED}function slotBlocked(provider,slot,sidecar,now){let fromSidecar=sidecarBlock(sidecar,now),lane=normalizeProviderId(provider);if(lane!=="cursor-cli-oauth"&&lane!=="anthropic-subscription")return fromSidecar;let fromSlot=storedSlotBlock(provider,slot,now);if(fromSlot.blockedReason==="disabled")return fromSlot;if(fromSidecar.blockedReason==="disabled"||!fromSlot.blocked)return fromSidecar;if(!fromSidecar.blocked||fromSlot.blockedUntil===void 0)return fromSlot;let later=(fromSlot.blockedUntil??0)>(fromSidecar.blockedUntil??0)?fromSlot:fromSidecar;return[fromSidecar,fromSlot].some(block=>block.blockedReason==="auth_error")?{...later,blockedReason:"auth_error"}:later}function storedModelBlocks(slot){let found=Object.entries(slot).find(([candidate])=>candidate==="modelBlocks")?.[1];if(found===null||typeof found!="object")return;let entries=Object.entries(found).flatMap(([model,block])=>{let until=block!==null&&typeof block=="object"?numberField(block,"blockedUntil"):void 0;return until===void 0?[]:[[model,{blockedUntil:until}]]});return entries.length===0?void 0:Object.fromEntries(entries)}function blockedModels(now,...sources){let until=new Map;for(let blocks of sources)for(let[model,block]of Object.entries(pruneModelBlocks(blocks,now)??{}))until.set(model,Math.max(until.get(model)??0,block.blockedUntil));return until.size===0?{}:{blockedModels:[...until].map(([model,at])=>({model,until:at}))}}async function getCredentialAccounts(storage,provider,env=process.env,repository){return summarizeCredentialAccounts(provider,storage.get(provider),env,repository??credentialPoolRepository(storage))}async function summarizeCredentialAccounts(provider,stored,env=process.env,repository=new CredentialSlotRepository){let credential=pooledFrom(stored);return applyAccountOrder(credential?.order,await summarizeInStoredOrder(provider,credential,env,repository))}async function summarizeInStoredOrder(provider,credential,env,repository){let now=Date.now(),pinned=pinnedName(credential),summaries=[];if(credential){let state2=await repository.listSlots(provider,"stored"),isClaudeSubscription=normalizeProviderId(provider)==="anthropic-subscription",storedAccounts=isClaudeSubscription?Array.isArray(credential.accounts)?listSlots(credential).filter(isListedStoredSlot):[]:listSlots(credential),usable=new Set(slotsOfOwnKind(credential).map(slot=>slot.name));for(let slot of storedAccounts){let displayName=accountDisplayName(slot.displayName),persisted=state2[slot.name],revisions=await repository.storedSlotRevisions(provider,slot.name,{key:slot.key,access:slot.access,refresh:slot.refresh}),applicable=applicableStoredState(persisted,revisions);summaries.push({name:slot.name,...displayName===void 0?{}:{displayName},source:slot.source??"login",...slotBlocked(provider,slot,applicable,now),pinned:pinned===slot.name,...blockedModels(now,applicable?.modelBlocks,storedModelBlocks(slot)),...usable.has(slot.name)?{}:{unused:!0},...isClaudeSubscription?claudeCliSlotFields(slot):{}})}if(normalizeProviderId(provider)!=="anthropic-subscription")return summaries}let state=await repository.listSlots(provider,"env");for(let slot of discoverEnvSlots(provider,name=>env[name])){let persisted=state[slot.name],revision=await repository.envCredentialRevision(slot.envVarName,slot.key),applicable=persisted?.credentialRevision===revision?persisted:void 0;summaries.push({name:slot.name,source:"env",...sidecarBlock(applicable,now),pinned:pinned===slot.name,...blockedModels(now,applicable?.modelBlocks)})}return summaries}async function renameCredentialAccount(storage,provider,name,displayName){await storage.modify(provider,async current=>{if(!current)throw new Error(`No stored credential for provider: ${provider}`);if(current.type==="oauth"&&!Array.isArray(current.accounts)&¤t.access===current.refresh&¤t.access.endsWith("-managed"))throw new Error(`Stored provider account not found: ${name}`);return renameSlotDisplayName(current,name,displayName)}),emitProviderAccountsChanged(provider)}async function pinCredentialAccount(storage,provider,name,env=process.env,repository){let repo=repository??credentialPoolRepository(storage);if(name!==null){assertValidAccountName2(name);let account=(await getCredentialAccounts(storage,provider,env,repo)).find(candidate=>candidate.name===name);if(!account)throw new Error(`Provider account not found: ${name}`);if(account.unused)throw new Error(`Account ${name} holds a login of the other kind and is never used, so it cannot be pinned. To switch ${provider} to it, save it again with /login.`)}await storage.modify(provider,async current=>{if(current===void 0){if(normalizeProviderId(provider)!=="anthropic-subscription"||name===null)throw new Error(`No stored credential for provider: ${provider}`);return pinSlot({type:"oauth",...SENTINEL_OAUTH_FIELDS,accounts:[]},name)}if(name===null){if(pinnedName(current)===void 0)return current;let{pinned:_pinned,...unpinned}={...current,pinned:void 0};return unpinned}return pinSlot(current,name)}),emitProviderAccountsChanged(provider)}async function removeCredentialAccount(storage,provider,name,env=process.env,repository){let repo=repository??credentialPoolRepository(storage),account=(await getCredentialAccounts(storage,provider,env,repo)).find(candidate=>candidate.name===name);if(!account)throw new Error(`Provider account not found: ${name}`);if(account.source==="env")throw new Error(`Environment provider account cannot be removed: ${name}`);let notice=await signOutAndDropSlot(storage,provider,name,env,repo);return emitProviderAccountsChanged(provider),notice===void 0?{}:{notice}}async function dropStoredSlot(storage,provider,name,repo){let removed=removeSlot(await storage.read(provider),name),remaining=removed===void 0?void 0:withoutOrderedAccount(removed,name);remaining===void 0?await storage.delete(provider):await storage.modify(provider,async()=>remaining),await repo.mutateSlotState(provider,"stored",name,()=>{})}async function pathExists(path){try{return await lstat2(path),!0}catch{return!1}}async function signOutAndDropSlot(storage,provider,name,env,repo,signal){let credential=await storage.read(provider);if(credential===void 0)throw new Error(`No stored credential for provider: ${provider}`);let notice;if(normalizeProviderId(provider)==="anthropic-subscription"){let accountDir=claudeCliAccountDir(storage,credential,name),dirExisted=accountDir!==void 0&&await pathExists(accountDir);try{notice=await signOutClaudeCliSlot(storage,credential,name,env,signal)}catch(error){throw dirExisted&&!await pathExists(accountDir)&&await dropStoredSlot(storage,provider,name,repo),error}}return await dropStoredSlot(storage,provider,name,repo),notice}async function signOutClaudeCliSlotsForLogout(storage,provider,env=process.env,signal){if(normalizeProviderId(provider)!=="anthropic-subscription")return[];let credential=await storage.read(provider);if(credential===void 0)return[];let repo=credentialPoolRepository(storage),notices=[],dropped=!1;try{for(let slot of listSlots(credential)){if(stringField2(slot,"store")!=="claude-cli")continue;signal?.throwIfAborted();let notice=await signOutAndDropSlot(storage,provider,slot.name,env,repo,signal);dropped=!0,notice!==void 0&¬ices.push(notice)}}finally{dropped&&emitProviderAccountsChanged(provider)}return notices}function claudeCliAgentDir(storage){let authPath=storage.getStoragePath();return authPath?dirname3(authPath):getAgentDir()}function claudeCliAccountDir(storage,credential,name){let slot=listSlots(credential).find(candidate=>candidate.name===name);if(slot===void 0||stringField2(slot,"store")!=="claude-cli")return;let dirId=stringField2(slot,"dirId");return dirId!==void 0&&isValidAccountDirId(dirId)?accountDirFor(claudeCliAgentDir(storage),dirId):void 0}async function signOutClaudeCliSlot(storage,credential,name,env,signal){let slot=listSlots(credential).find(candidate=>candidate.name===name);if(slot===void 0||stringField2(slot,"store")!=="claude-cli")return;let dirId=stringField2(slot,"dirId"),agentDir=claudeCliAgentDir(storage);if(dirId===void 0||!isValidAccountDirId(dirId))return`Removed Claude account ${name} without a Claude sign-out: it names no valid account dir.`;let executable;try{executable=resolveClaudeCodeExecutable({...defaultExecutableDeps(),env:key=>env[key]})}catch{executable=void 0}let outcome=await removeAccountDir({agentDir,dirId,executable,parentEnv:env,...signal===void 0?{}:{signal}});if(outcome!=="removed")return outcome==="removed_without_sign_out"?`Removed Claude account ${name}, but the Claude CLI sign-out could not run; its stored sign-in may remain in the Claude CLI's credential store.`:`Removed Claude account ${name} without a Claude sign-out: its account dir is a link or a file, left untouched at ${accountDirFor(agentDir,dirId)}.`}export{isEnvSlot,SENTINEL_OAUTH_FIELDS,emptyCredential,isListedStoredSlot,listAccounts,assertValidAccountName,pinAccount,envSlotToken,hasRequestOauthToken,mergeRequestAuthEnvironment,stripManagedAuthEnvironment,buildClaudeCliEnvironment,spawnClaudeCli,stopClaudeCli,readClaudeCliAuthStatus,logoutClaudeCli,CLAUDE_CLI_SHARED_LINKS,newAccountDirId,accountDirFor,claudeCliSharedRoot,ensureAccountDir,removeAccountDir,AllAccountsBlockedError,isBlockedFor,clearExpiredBlocks,selectAccount,resolveClaudeCodeExecutable,resolveClaudeCodeRun,defaultExecutableDeps,assertValidAccountName2,credentialPoolRepository,getCredentialAccounts,summarizeCredentialAccounts,renameCredentialAccount,pinCredentialAccount,removeCredentialAccount,signOutClaudeCliSlotsForLogout};
|
|
@@ -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{McpMrtrError,bindMcpFormPresented,enums,isRecord,privateMcpForms,queuedForm,validValue,validateMrtrForm}from"./chunk-7ICGN62G.js";import{redactResolvedReferenceValues}from"./chunk-DLAY7CIU.js";import{getAgentDir}from"./chunk-ISZ4EWIS.js";var McpError=class extends Error{constructor(kind,name,message,options={}){super(message),this.name=name,this.kind=kind,this.phase=options.phase,this.retriable=options.retriable,this.serverName=options.serverName,options.cause!==void 0&&Object.defineProperty(this,"cause",{configurable:!0,value:options.cause,writable:!1}),Object.setPrototypeOf(this,new.target.prototype)}},ConnectError=class extends McpError{constructor(message,options={}){super("connect","ConnectError",message,options)}};var ToolExecError=class extends McpError{constructor(message,options={}){super("tool_exec","ToolExecError",message,options)}},AuthError=class extends McpError{constructor(message,options={}){super("auth","AuthError",message,options)}},TimeoutError=class extends McpError{constructor(message,options={}){super("timeout","TimeoutError",message,options)}},SessionExpiredError=class extends McpError{constructor(message,options={}){super("session_expired","SessionExpiredError",message,options)}},RETRIABLE_STATUS_CODES=new Set([404,502,503]),RETRIABLE_NUMERIC_CODES=new Set([-32001]),RETRIABLE_TEXT=["econnrefused","connection refused","transport closed"];function isRetriableMcpError(error){if(error instanceof McpError&&error.retriable===!0||isMcpSessionExpiredError(error)||hasRetriableNumericSignal(error,new Set))return!0;let text=collectText(error,new Set).join(" ").toLowerCase();return RETRIABLE_TEXT.some(needle=>text.includes(needle))?!0:/\b(?:404|502|503)\b/.test(text)}function isMcpSessionExpiredError(error){if(hasSessionExpiredNumericSignal(error,new Set))return!0;let text=collectText(error,new Set).join(" ").toLowerCase();return/\b404\b/.test(text)||text.includes("-32000")&&text.includes("session")||text.includes("session expired")||text.includes("session not found")||text.includes("mcp-session-id")}function hasRetriableNumericSignal(value,seen){if(typeof value!="object"||value===null||seen.has(value))return!1;seen.add(value);let code=numberFromUnknown(getProperty(value,"code"));if(code!==void 0&&RETRIABLE_NUMERIC_CODES.has(code))return!0;let status=numberFromUnknown(getProperty(value,"status"));if(status!==void 0&&RETRIABLE_STATUS_CODES.has(status))return!0;let statusCode=numberFromUnknown(getProperty(value,"statusCode"));return statusCode!==void 0&&RETRIABLE_STATUS_CODES.has(statusCode)?!0:hasRetriableNumericSignal(getProperty(value,"response"),seen)||hasRetriableNumericSignal(getProperty(value,"cause"),seen)}function hasSessionExpiredNumericSignal(value,seen){if(typeof value!="object"||value===null||seen.has(value))return!1;seen.add(value);let code=numberFromUnknown(getProperty(value,"code"));if(code===-32001)return!0;if(code===-32e3){let message=getProperty(value,"message");if(typeof message=="string"&&message.toLowerCase().includes("session"))return!0}return numberFromUnknown(getProperty(value,"status"))===404||numberFromUnknown(getProperty(value,"statusCode"))===404?!0:hasSessionExpiredNumericSignal(getProperty(value,"response"),seen)||hasSessionExpiredNumericSignal(getProperty(value,"cause"),seen)}function collectText(value,seen){if(typeof value=="string")return[value];if(typeof value=="number")return[String(value)];if(typeof value!="object"||value===null)return[];if(seen.has(value))return[];seen.add(value);let parts=[];value instanceof Error&&parts.push(value.message,value.name);for(let key of["message","code","status","statusCode"]){let property=getProperty(value,key);(typeof property=="string"||typeof property=="number")&&parts.push(String(property))}return parts.push(...collectText(getProperty(value,"response"),seen)),parts.push(...collectText(getProperty(value,"cause"),seen)),parts}function numberFromUnknown(value){if(typeof value=="number")return value;if(typeof value!="string"||value.trim()==="")return;let parsed=Number(value);return Number.isFinite(parsed)?parsed:void 0}function getProperty(value,key){if(!(typeof value!="object"||value===null))return value[key]}import{chmodSync,closeSync,openSync,renameSync,rmSync,statSync}from"node:fs";var LOG_SINK_RETRY_MS=5e3,ROTATION_LOCK_STALE_MS=1e4;function errorCode(error){return typeof error=="object"&&error!==null&&"code"in error&&typeof error.code=="string"?error.code:void 0}function exceedsCap(filePath,incomingBytes,maxBytes){try{return statSync(filePath).size+incomingBytes>maxBytes}catch(error){if(errorCode(error)==="ENOENT")return!1;throw error}}function clearStaleLock(lockPath){try{Date.now()-statSync(lockPath).mtimeMs>ROTATION_LOCK_STALE_MS&&rmSync(lockPath,{force:!0})}catch(error){if(errorCode(error)!=="ENOENT")throw error}}function rotateLogIfNeeded(filePath,incomingBytes,maxBytes){if(!exceedsCap(filePath,incomingBytes,maxBytes))return;let lockPath=`${filePath}.rotate-lock`,lock;try{lock=openSync(lockPath,"wx",384)}catch(error){if(errorCode(error)!=="EEXIST")throw error;clearStaleLock(lockPath);return}try{if(!exceedsCap(filePath,incomingBytes,maxBytes))return;try{renameSync(filePath,`${filePath}.1`)}catch(error){if(errorCode(error)==="ENOENT")return;throw error}chmodSync(`${filePath}.1`,384)}finally{closeSync(lock),rmSync(lockPath,{force:!0})}}import{closeSync as closeSync3,fchmodSync,mkdirSync as mkdirSync2,openSync as openSync3,writeSync as writeSync2}from"node:fs";import{dirname,join as join2}from"node:path";import{createHmac,randomBytes,randomUUID}from"node:crypto";import{closeSync as closeSync2,constants,fstatSync,fsyncSync,linkSync,mkdirSync,openSync as openSync2,readSync,rmSync as rmSync2,writeSync}from"node:fs";import{join}from"node:path";var KEY_FILE="config-identity.key",KEY_BYTES=32,EPHEMERAL_PREFIX="ephemeral:",processKey=randomBytes(KEY_BYTES),installationKeys=new Map,warnedPaths=new Set;function keyedIdentity(agentDir,payload){let key=installationKey(agentDir??getAgentDir());return key===void 0?`${EPHEMERAL_PREFIX}${hmac(processKey,payload)}`:hmac(key,payload)}function isEphemeralIdentity(identity){return identity?.startsWith(EPHEMERAL_PREFIX)===!0}function keyedFingerprint(value){return hmac(installationKey(getAgentDir())??processKey,value).slice(0,8)}function hmac(key,payload){return createHmac("sha256",key).update(payload).digest("hex")}function installationKey(agentDir){return installationKeys.has(agentDir)||installationKeys.set(agentDir,loadOrPublishKey(agentDir)),installationKeys.get(agentDir)}function loadOrPublishKey(agentDir){let path=join(agentDir,KEY_FILE),existing=readKey(path);return existing.kind==="valid"?existing.key:existing.kind==="missing"?publishKey(agentDir,path):void 0}function readKey(path){let fd;try{fd=openSync2(path,constants.O_RDONLY|(constants.O_NOFOLLOW??0))}catch(error){return isErrno(error,"ENOENT")?{kind:"missing"}:invalidKey(path,"cannot open safely","repair access and ensure it is a regular file, not a symlink")}try{let stat=fstatSync(fd);if(!stat.isFile())return invalidKey(path,"not a regular file","restore the original private key file");if(stat.size!==KEY_BYTES)return invalidKey(path,`wrong size (${stat.size} bytes)`,"restore the original 32-byte key from backup");if(process.platform!=="win32"){if(stat.uid!==process.getuid?.())return invalidKey(path,"wrong owner","chown the key file to your current user");if((stat.mode&511)!==384)return invalidKey(path,"wrong mode","chmod 600 the key file")}let key=Buffer.alloc(KEY_BYTES);return readSync(fd,key,0,KEY_BYTES,0)===KEY_BYTES?{kind:"valid",key}:invalidKey(path,"incomplete read","restore the original 32-byte key from backup")}finally{closeSync2(fd)}}function invalidKey(path,problem,repair){return warnedPaths.has(path)||(warnedPaths.add(path),console.warn(`MCP identity key ${path}: ${problem}; persistent catalog cache is disabled. To fix: ${repair}, then restart senpi. The file was left unchanged.`)),{kind:"invalid"}}function publishKey(agentDir,path){let temporary=`${path}.${process.pid}.${randomUUID()}.tmp`;try{mkdirSync(agentDir,{recursive:!0,mode:448});let key=randomBytes(KEY_BYTES),fd=openSync2(temporary,constants.O_CREAT|constants.O_EXCL|constants.O_WRONLY,384);try{writeSync(fd,key),fsyncSync(fd)}finally{closeSync2(fd)}return linkSync(temporary,path),syncDirectory(agentDir),key}catch(error){if(!isErrno(error,"EEXIST"))return;let published=readKey(path);return published.kind==="valid"?published.key:void 0}finally{rmSync2(temporary,{force:!0})}}function syncDirectory(directory){if(process.platform==="win32")return;let fd=openSync2(directory,constants.O_RDONLY);try{fsyncSync(fd)}finally{closeSync2(fd)}}function isErrno(error,code){return error instanceof Error&&"code"in error&&error.code===code}var DEFAULT_MAX_FILE_BYTES=1024*1024,MAX_RING_LINES=200,SENSITIVE_KEY_PATTERN=/(?:^|[_-])(?:api[_-]?key|key|token|secret|password|client_secret|auth|authorization)(?:$|[_-])/i,QUERY_SECRET_PATTERN=/([?&][^=\s&"'<>]*(?:key|token|secret|password|client_secret|auth)[^=\s&"'<>]*=)([^&\s"'<>]+)/gi,AUTHORIZATION_VALUE_PATTERN=/((?:"|')?\bAuthorization(?:"|')?\s*[:=]\s*(?:"|')?(?:[A-Za-z][A-Za-z0-9+.-]*\s+)?)(?!<redacted:)([^"',\s}\]&]+)/gi,BEARER_VALUE_PATTERN=/(\bBearer\s+)(?!<redacted:)([A-Za-z0-9._~+/=-]+)/gi,KEY_VALUE_PATTERN=/((?:"|')?[^"'\s:=,{}]*(?:api[_-]?key|key|token|secret|password|client_secret|auth)[^"'\s:=,{}]*(?:"|')?\s*[:=]\s*(?:"|')?)([^"',\s}\]&]+)/gi,MCP_LOG_LEVELS={emergency:{level:"emergency",severity:0},alert:{level:"alert",severity:1},critical:{level:"critical",severity:2},crit:{level:"critical",severity:2},error:{level:"error",severity:3},err:{level:"error",severity:3},warning:{level:"warning",severity:4},warn:{level:"warning",severity:4},notice:{level:"notice",severity:5},informational:{level:"info",severity:6},info:{level:"info",severity:6},debug:{level:"debug",severity:7}};function createMcpLogger(server,options={}){return new FileMcpLogger(server,options)}function getMcpLogDir(){return join2(getAgentDir(),"logs","mcp")}function fingerprintSecret(secret){return keyedFingerprint(secret)}function redactMcpLogText(text){return redactMcpLogTextWithContext(text,{seen:new WeakSet,secrets:new Set})}function redactMcpLogTextWithContext(text,context){return text.replace(AUTHORIZATION_VALUE_PATTERN,(_match,prefix,secret)=>`${prefix}${redactionForSecret(secret,context)}`).replace(BEARER_VALUE_PATTERN,(_match,prefix,secret)=>`${prefix}${redactionForSecret(secret,context)}`).replace(QUERY_SECRET_PATTERN,(_match,prefix,secret)=>`${prefix}${redactionForSecret(secret,context)}`).replace(KEY_VALUE_PATTERN,(match,prefix,secret)=>secret.startsWith("<redacted:")||/\bAuthorization\b/i.test(prefix)?match:`${prefix}${redactionForSecret(secret,context)}`)}function mapMcpLogLevel(level){return{...MCP_LOG_LEVELS[level]??MCP_LOG_LEVELS.info}}var FileMcpLogger=class{#server;#maxFileBytes;#ring=[];#fileSinkRetryAt=0;constructor(server,options){this.#server=server,this.#maxFileBytes=options.maxFileBytes??DEFAULT_MAX_FILE_BYTES,this.filePath=join2(options.logDir??getMcpLogDir(),`${sanitizeServerName(server)}.log`)}debug(message,data){this.log("debug",message,data)}info(message,data){this.log("info",message,data)}warn(message,data){this.log("warning",message,data)}error(message,data){this.log("error",message,data)}stderr(message,data){this.log("info",message,data,"stderr")}log(level,message,data,channel="server"){let line=this.#formatLine(level,message,data,channel);this.#pushRing(line),this.#writeFile(line)}getRingBuffer(){return[...this.#ring]}#formatLine(level,message,data,channel){let context={seen:new WeakSet,secrets:new Set},mapped=mapMcpLogLevel(level),redactedData=data===void 0?void 0:redactMcpLogData(data,context),entry={timestamp:new Date().toISOString(),server:this.#server,level:mapped.level,severity:mapped.severity,channel,message:redactMcpLogTextWithContext(message,context),data:redactedData};return redactResolvedReferenceValues(redactKnownSecrets(JSON.stringify(entry),context))}#pushRing(line){this.#ring.push(line),this.#ring.length>MAX_RING_LINES&&this.#ring.splice(0,this.#ring.length-MAX_RING_LINES)}#writeFile(line){if(!(Date.now()<this.#fileSinkRetryAt))try{mkdirSync2(dirname(this.filePath),{recursive:!0,mode:448});let bytes=Buffer.byteLength(`${line}
|
|
2
|
+
import{McpMrtrError,bindMcpFormPresented,enums,isRecord,privateMcpForms,queuedForm,validValue,validateMrtrForm}from"./chunk-7ICGN62G.js";import{redactResolvedReferenceValues}from"./chunk-DLAY7CIU.js";import{getAgentDir}from"./chunk-SODMQEHO.js";var McpError=class extends Error{constructor(kind,name,message,options={}){super(message),this.name=name,this.kind=kind,this.phase=options.phase,this.retriable=options.retriable,this.serverName=options.serverName,options.cause!==void 0&&Object.defineProperty(this,"cause",{configurable:!0,value:options.cause,writable:!1}),Object.setPrototypeOf(this,new.target.prototype)}},ConnectError=class extends McpError{constructor(message,options={}){super("connect","ConnectError",message,options)}};var ToolExecError=class extends McpError{constructor(message,options={}){super("tool_exec","ToolExecError",message,options)}},AuthError=class extends McpError{constructor(message,options={}){super("auth","AuthError",message,options)}},TimeoutError=class extends McpError{constructor(message,options={}){super("timeout","TimeoutError",message,options)}},SessionExpiredError=class extends McpError{constructor(message,options={}){super("session_expired","SessionExpiredError",message,options)}},RETRIABLE_STATUS_CODES=new Set([404,502,503]),RETRIABLE_NUMERIC_CODES=new Set([-32001]),RETRIABLE_TEXT=["econnrefused","connection refused","transport closed"];function isRetriableMcpError(error){if(error instanceof McpError&&error.retriable===!0||isMcpSessionExpiredError(error)||hasRetriableNumericSignal(error,new Set))return!0;let text=collectText(error,new Set).join(" ").toLowerCase();return RETRIABLE_TEXT.some(needle=>text.includes(needle))?!0:/\b(?:404|502|503)\b/.test(text)}function isMcpSessionExpiredError(error){if(hasSessionExpiredNumericSignal(error,new Set))return!0;let text=collectText(error,new Set).join(" ").toLowerCase();return/\b404\b/.test(text)||text.includes("-32000")&&text.includes("session")||text.includes("session expired")||text.includes("session not found")||text.includes("mcp-session-id")}function hasRetriableNumericSignal(value,seen){if(typeof value!="object"||value===null||seen.has(value))return!1;seen.add(value);let code=numberFromUnknown(getProperty(value,"code"));if(code!==void 0&&RETRIABLE_NUMERIC_CODES.has(code))return!0;let status=numberFromUnknown(getProperty(value,"status"));if(status!==void 0&&RETRIABLE_STATUS_CODES.has(status))return!0;let statusCode=numberFromUnknown(getProperty(value,"statusCode"));return statusCode!==void 0&&RETRIABLE_STATUS_CODES.has(statusCode)?!0:hasRetriableNumericSignal(getProperty(value,"response"),seen)||hasRetriableNumericSignal(getProperty(value,"cause"),seen)}function hasSessionExpiredNumericSignal(value,seen){if(typeof value!="object"||value===null||seen.has(value))return!1;seen.add(value);let code=numberFromUnknown(getProperty(value,"code"));if(code===-32001)return!0;if(code===-32e3){let message=getProperty(value,"message");if(typeof message=="string"&&message.toLowerCase().includes("session"))return!0}return numberFromUnknown(getProperty(value,"status"))===404||numberFromUnknown(getProperty(value,"statusCode"))===404?!0:hasSessionExpiredNumericSignal(getProperty(value,"response"),seen)||hasSessionExpiredNumericSignal(getProperty(value,"cause"),seen)}function collectText(value,seen){if(typeof value=="string")return[value];if(typeof value=="number")return[String(value)];if(typeof value!="object"||value===null)return[];if(seen.has(value))return[];seen.add(value);let parts=[];value instanceof Error&&parts.push(value.message,value.name);for(let key of["message","code","status","statusCode"]){let property=getProperty(value,key);(typeof property=="string"||typeof property=="number")&&parts.push(String(property))}return parts.push(...collectText(getProperty(value,"response"),seen)),parts.push(...collectText(getProperty(value,"cause"),seen)),parts}function numberFromUnknown(value){if(typeof value=="number")return value;if(typeof value!="string"||value.trim()==="")return;let parsed=Number(value);return Number.isFinite(parsed)?parsed:void 0}function getProperty(value,key){if(!(typeof value!="object"||value===null))return value[key]}import{chmodSync,closeSync,openSync,renameSync,rmSync,statSync}from"node:fs";var LOG_SINK_RETRY_MS=5e3,ROTATION_LOCK_STALE_MS=1e4;function errorCode(error){return typeof error=="object"&&error!==null&&"code"in error&&typeof error.code=="string"?error.code:void 0}function exceedsCap(filePath,incomingBytes,maxBytes){try{return statSync(filePath).size+incomingBytes>maxBytes}catch(error){if(errorCode(error)==="ENOENT")return!1;throw error}}function clearStaleLock(lockPath){try{Date.now()-statSync(lockPath).mtimeMs>ROTATION_LOCK_STALE_MS&&rmSync(lockPath,{force:!0})}catch(error){if(errorCode(error)!=="ENOENT")throw error}}function rotateLogIfNeeded(filePath,incomingBytes,maxBytes){if(!exceedsCap(filePath,incomingBytes,maxBytes))return;let lockPath=`${filePath}.rotate-lock`,lock;try{lock=openSync(lockPath,"wx",384)}catch(error){if(errorCode(error)!=="EEXIST")throw error;clearStaleLock(lockPath);return}try{if(!exceedsCap(filePath,incomingBytes,maxBytes))return;try{renameSync(filePath,`${filePath}.1`)}catch(error){if(errorCode(error)==="ENOENT")return;throw error}chmodSync(`${filePath}.1`,384)}finally{closeSync(lock),rmSync(lockPath,{force:!0})}}import{closeSync as closeSync3,fchmodSync,mkdirSync as mkdirSync2,openSync as openSync3,writeSync as writeSync2}from"node:fs";import{dirname,join as join2}from"node:path";import{createHmac,randomBytes,randomUUID}from"node:crypto";import{closeSync as closeSync2,constants,fstatSync,fsyncSync,linkSync,mkdirSync,openSync as openSync2,readSync,rmSync as rmSync2,writeSync}from"node:fs";import{join}from"node:path";var KEY_FILE="config-identity.key",KEY_BYTES=32,EPHEMERAL_PREFIX="ephemeral:",processKey=randomBytes(KEY_BYTES),installationKeys=new Map,warnedPaths=new Set;function keyedIdentity(agentDir,payload){let key=installationKey(agentDir??getAgentDir());return key===void 0?`${EPHEMERAL_PREFIX}${hmac(processKey,payload)}`:hmac(key,payload)}function isEphemeralIdentity(identity){return identity?.startsWith(EPHEMERAL_PREFIX)===!0}function keyedFingerprint(value){return hmac(installationKey(getAgentDir())??processKey,value).slice(0,8)}function hmac(key,payload){return createHmac("sha256",key).update(payload).digest("hex")}function installationKey(agentDir){return installationKeys.has(agentDir)||installationKeys.set(agentDir,loadOrPublishKey(agentDir)),installationKeys.get(agentDir)}function loadOrPublishKey(agentDir){let path=join(agentDir,KEY_FILE),existing=readKey(path);return existing.kind==="valid"?existing.key:existing.kind==="missing"?publishKey(agentDir,path):void 0}function readKey(path){let fd;try{fd=openSync2(path,constants.O_RDONLY|(constants.O_NOFOLLOW??0))}catch(error){return isErrno(error,"ENOENT")?{kind:"missing"}:invalidKey(path,"cannot open safely","repair access and ensure it is a regular file, not a symlink")}try{let stat=fstatSync(fd);if(!stat.isFile())return invalidKey(path,"not a regular file","restore the original private key file");if(stat.size!==KEY_BYTES)return invalidKey(path,`wrong size (${stat.size} bytes)`,"restore the original 32-byte key from backup");if(process.platform!=="win32"){if(stat.uid!==process.getuid?.())return invalidKey(path,"wrong owner","chown the key file to your current user");if((stat.mode&511)!==384)return invalidKey(path,"wrong mode","chmod 600 the key file")}let key=Buffer.alloc(KEY_BYTES);return readSync(fd,key,0,KEY_BYTES,0)===KEY_BYTES?{kind:"valid",key}:invalidKey(path,"incomplete read","restore the original 32-byte key from backup")}finally{closeSync2(fd)}}function invalidKey(path,problem,repair){return warnedPaths.has(path)||(warnedPaths.add(path),console.warn(`MCP identity key ${path}: ${problem}; persistent catalog cache is disabled. To fix: ${repair}, then restart senpi. The file was left unchanged.`)),{kind:"invalid"}}function publishKey(agentDir,path){let temporary=`${path}.${process.pid}.${randomUUID()}.tmp`;try{mkdirSync(agentDir,{recursive:!0,mode:448});let key=randomBytes(KEY_BYTES),fd=openSync2(temporary,constants.O_CREAT|constants.O_EXCL|constants.O_WRONLY,384);try{writeSync(fd,key),fsyncSync(fd)}finally{closeSync2(fd)}return linkSync(temporary,path),syncDirectory(agentDir),key}catch(error){if(!isErrno(error,"EEXIST"))return;let published=readKey(path);return published.kind==="valid"?published.key:void 0}finally{rmSync2(temporary,{force:!0})}}function syncDirectory(directory){if(process.platform==="win32")return;let fd=openSync2(directory,constants.O_RDONLY);try{fsyncSync(fd)}finally{closeSync2(fd)}}function isErrno(error,code){return error instanceof Error&&"code"in error&&error.code===code}var DEFAULT_MAX_FILE_BYTES=1024*1024,MAX_RING_LINES=200,SENSITIVE_KEY_PATTERN=/(?:^|[_-])(?:api[_-]?key|key|token|secret|password|client_secret|auth|authorization)(?:$|[_-])/i,QUERY_SECRET_PATTERN=/([?&][^=\s&"'<>]*(?:key|token|secret|password|client_secret|auth)[^=\s&"'<>]*=)([^&\s"'<>]+)/gi,AUTHORIZATION_VALUE_PATTERN=/((?:"|')?\bAuthorization(?:"|')?\s*[:=]\s*(?:"|')?(?:[A-Za-z][A-Za-z0-9+.-]*\s+)?)(?!<redacted:)([^"',\s}\]&]+)/gi,BEARER_VALUE_PATTERN=/(\bBearer\s+)(?!<redacted:)([A-Za-z0-9._~+/=-]+)/gi,KEY_VALUE_PATTERN=/((?:"|')?[^"'\s:=,{}]*(?:api[_-]?key|key|token|secret|password|client_secret|auth)[^"'\s:=,{}]*(?:"|')?\s*[:=]\s*(?:"|')?)([^"',\s}\]&]+)/gi,MCP_LOG_LEVELS={emergency:{level:"emergency",severity:0},alert:{level:"alert",severity:1},critical:{level:"critical",severity:2},crit:{level:"critical",severity:2},error:{level:"error",severity:3},err:{level:"error",severity:3},warning:{level:"warning",severity:4},warn:{level:"warning",severity:4},notice:{level:"notice",severity:5},informational:{level:"info",severity:6},info:{level:"info",severity:6},debug:{level:"debug",severity:7}};function createMcpLogger(server,options={}){return new FileMcpLogger(server,options)}function getMcpLogDir(){return join2(getAgentDir(),"logs","mcp")}function fingerprintSecret(secret){return keyedFingerprint(secret)}function redactMcpLogText(text){return redactMcpLogTextWithContext(text,{seen:new WeakSet,secrets:new Set})}function redactMcpLogTextWithContext(text,context){return text.replace(AUTHORIZATION_VALUE_PATTERN,(_match,prefix,secret)=>`${prefix}${redactionForSecret(secret,context)}`).replace(BEARER_VALUE_PATTERN,(_match,prefix,secret)=>`${prefix}${redactionForSecret(secret,context)}`).replace(QUERY_SECRET_PATTERN,(_match,prefix,secret)=>`${prefix}${redactionForSecret(secret,context)}`).replace(KEY_VALUE_PATTERN,(match,prefix,secret)=>secret.startsWith("<redacted:")||/\bAuthorization\b/i.test(prefix)?match:`${prefix}${redactionForSecret(secret,context)}`)}function mapMcpLogLevel(level){return{...MCP_LOG_LEVELS[level]??MCP_LOG_LEVELS.info}}var FileMcpLogger=class{#server;#maxFileBytes;#ring=[];#fileSinkRetryAt=0;constructor(server,options){this.#server=server,this.#maxFileBytes=options.maxFileBytes??DEFAULT_MAX_FILE_BYTES,this.filePath=join2(options.logDir??getMcpLogDir(),`${sanitizeServerName(server)}.log`)}debug(message,data){this.log("debug",message,data)}info(message,data){this.log("info",message,data)}warn(message,data){this.log("warning",message,data)}error(message,data){this.log("error",message,data)}stderr(message,data){this.log("info",message,data,"stderr")}log(level,message,data,channel="server"){let line=this.#formatLine(level,message,data,channel);this.#pushRing(line),this.#writeFile(line)}getRingBuffer(){return[...this.#ring]}#formatLine(level,message,data,channel){let context={seen:new WeakSet,secrets:new Set},mapped=mapMcpLogLevel(level),redactedData=data===void 0?void 0:redactMcpLogData(data,context),entry={timestamp:new Date().toISOString(),server:this.#server,level:mapped.level,severity:mapped.severity,channel,message:redactMcpLogTextWithContext(message,context),data:redactedData};return redactResolvedReferenceValues(redactKnownSecrets(JSON.stringify(entry),context))}#pushRing(line){this.#ring.push(line),this.#ring.length>MAX_RING_LINES&&this.#ring.splice(0,this.#ring.length-MAX_RING_LINES)}#writeFile(line){if(!(Date.now()<this.#fileSinkRetryAt))try{mkdirSync2(dirname(this.filePath),{recursive:!0,mode:448});let bytes=Buffer.byteLength(`${line}
|
|
3
3
|
`);this.#maxFileBytes>0&&rotateLogIfNeeded(this.filePath,bytes,this.#maxFileBytes);let fd=openSync3(this.filePath,"a",384);try{writeSync2(fd,`${line}
|
|
4
4
|
`),fchmodSync(fd,384)}finally{closeSync3(fd)}}catch{this.#fileSinkRetryAt=Date.now()+LOG_SINK_RETRY_MS,this.#pushRing(this.#formatLine("warning","file sink disabled after write failure",void 0,"file"))}}};function redactMcpLogData(value,context){return typeof value=="string"?redactMcpLogTextWithContext(value,context):typeof value=="bigint"?value.toString():typeof value!="object"||value===null?value:context.seen.has(value)?"[Circular]":(context.seen.add(value),value instanceof Error?redactMcpLogError(value,context):Array.isArray(value)?value.map(item=>redactMcpLogData(item,context)):redactMcpLogEntries(value,context))}function redactMcpLogError(error,context){let redacted=redactMcpLogEntries(error,context);return redacted.name=redactMcpLogTextWithContext(error.name,context),redacted.message=redactKnownSecrets(redactMcpLogTextWithContext(error.message,context),context),error.stack!==void 0&&(redacted.stack=redactKnownSecrets(redactMcpLogTextWithContext(error.stack,context),context)),redacted}function redactMcpLogEntries(value,context){let redacted={};for(let[key,item]of Object.entries(value))SENSITIVE_KEY_PATTERN.test(key)?redacted[key]=redactionForSecret(stringifySecretValue(item),context):redacted[key]=redactMcpLogData(item,context);return redacted}function stringifySecretValue(value){if(typeof value=="string")return value;if(typeof value=="number"||typeof value=="boolean"||typeof value=="bigint")return String(value);let seen=new WeakSet;return JSON.stringify(value,(_key,item)=>typeof item=="bigint"?item.toString():typeof item!="object"||item===null?item:seen.has(item)?"[Circular]":(seen.add(item),item))??String(value)}function redactionForSecret(secret,context){return secret.length>0&&!secret.startsWith("<redacted:")&&context.secrets.add(secret),redactionFor(secret)}function redactKnownSecrets(text,context){for(let secret of[...context.secrets].sort((left,right)=>right.length-left.length))text=text.split(secret).join(redactionFor(secret));return text}function redactionFor(secret){return`<redacted:${fingerprintSecret(secret)}>`}function sanitizeServerName(server){return server.replace(/[^A-Za-z0-9._-]+/g,"_")||"server"}var mcpElapsedClock={now:()=>performance.now(),schedule:(callback,ms)=>setTimeout(callback,ms),cancel:timer=>clearTimeout(timer)};function mcpAbortableDelay(clock,ms,signal){return new Promise((resolve,reject)=>{let finish=()=>{clock.cancel(timer),signal.removeEventListener("abort",abort),resolve()},abort=()=>{clock.cancel(timer),signal.removeEventListener("abort",abort),reject(signal.reason)},timer=clock.schedule(finish,ms);signal.addEventListener("abort",abort,{once:!0}),signal.aborted&&abort()})}var clientCloseObservers=new WeakMap;function onMcpClientClose(client,listener){let state=clientCloseObservers.get(client);if(!state){let listeners=new Set,prior=client.onclose,close=()=>{for(let callback of listeners)callback();prior?.()};state={listeners,prior,close},clientCloseObservers.set(client,state),client.onclose=close}state.listeners.add(listener);let current=state;return()=>{current.listeners.delete(listener),current.listeners.size===0&&(client.onclose===current.close&&(client.onclose=current.prior),clientCloseObservers.delete(client))}}function mcpInterrupted(work,signal){return new Promise((resolve,reject)=>{let abort=()=>{signal.removeEventListener("abort",abort),reject(signal.reason)};signal.addEventListener("abort",abort,{once:!0}),signal.aborted&&abort(),work.then(value=>{signal.removeEventListener("abort",abort),resolve(value)},error=>{signal.removeEventListener("abort",abort),reject(error)})})}function wrapAsync(scope,fn,sink){return async(...args)=>{try{await fn(...args)}catch(error){let caughtError=error instanceof Error?error:normalizeCaughtError(error);await reportMcpAsyncError(scope,caughtError,sink)}}}function safeTimer(scope,delayMs,fn,sink){let wrapped=wrapAsync(scope,fn,sink),timer=setTimeout(()=>{wrapped()},delayMs);return timer.unref(),timer}function safeInterval(scope,delayMs,fn,sink){let wrapped=wrapAsync(scope,fn,sink),timer=setInterval(()=>{wrapped()},delayMs);return timer.unref(),timer}function safeDelay(delayMs){return new Promise(resolve=>{setTimeout(resolve,delayMs)})}function safeOn(emitter,eventName,scope,listener,sink){let wrapped=wrapAsync(scope,listener,sink);return emitter.on(eventName,wrapped),()=>{emitter.off(eventName,wrapped)}}function safeEventBusOn(bus,channel,handler){return bus.on(channel,handler)}async function reportMcpAsyncError(scope,error,sink){let normalized=normalizeError(error);if(logError(scope,normalized,sink.logger),!!sink.notify)try{await sink.notify(`MCP ${scope} failed: ${normalized.message}`,normalized)}catch(notifyError){let caughtNotifyError=notifyError instanceof Error?notifyError:normalizeCaughtError(notifyError);logError(`${scope}.notify`,caughtNotifyError,sink.logger)}}function logError(scope,error,logger){try{logger.error(scope,serializeError(error))}catch{let redactedScope=redactMcpLogText(scope);console.error(`MCP ${redactedScope} logger failed; suppressed async error details`)}}function serializeError(error){let serialized={name:error.name,message:error.message};return error.stack&&(serialized.stack=error.stack),serialized}function normalizeError(error){return error instanceof Error?error:normalizeCaughtError(error)}function normalizeCaughtError(error){return typeof error=="string"?new Error(error):new Error(safeStringify(error))}function safeStringify(value){try{return JSON.stringify(value)??String(value)}catch{return String(value)}}function memoizeLoader(load){let loaded,loading;return()=>loaded!==void 0?Promise.resolve(loaded):(loading??=load().then(module=>(loaded=module,module)).finally(()=>{loading=void 0}),loading)}var loadMcpSdkClient=memoizeLoader(()=>import("./client-CBDPMWZJ.js")),loadMcpSdkZodCompat=memoizeLoader(()=>import("./zod-compat-RJDXCU7S.js")),loadMcpSdkStdioTransport=memoizeLoader(()=>import("./stdio-YXDKKKQZ.js")),loadMcpSdkTypes=memoizeLoader(()=>import("./types-BJUEQ4II.js")),loadMcpSdkProtocol=memoizeLoader(()=>import("./protocol-GLNWYI5G.js")),authModule,loadMcpSdkAuth=memoizeLoader(async()=>{let module=await import("./auth-C77UQA55.js");return authModule=module,module}),loadMcpSdkStreamableHttpTransport=memoizeLoader(async()=>{let[module]=await Promise.all([import("./streamableHttp-DKIBUWVY.js"),loadMcpSdkAuth()]);return module});function isMcpSdkUnauthorizedError(error){return authModule!==void 0&&error instanceof authModule.UnauthorizedError}import{stripVTControlCharacters}from"node:util";var own=(value,key)=>Object.hasOwn(value,key),inert=value=>stripVTControlCharacters(value).replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g,"");async function collectMrtrForm(presentation,serverLabel,params,signal){if(!validateMrtrForm(params.requestedSchema))throw new McpMrtrError("MCP_MRTR_INVALID_INPUT");let schema=params.requestedSchema,abort=new AbortController,combined=AbortSignal.any([signal,presentation.signal,abort.signal]),opts={signal:combined,ephemeral:!0};bindMcpFormPresented(opts,presentation.presented);let heading=`MCP server: ${inert(serverLabel)}
|
|
5
5
|
${inert(params.message)}`,select=async(title,choices)=>{if(combined.aborted)return;let result=await presentation.ui.select(title,choices,opts);return combined.aborted?void 0:result},content=Object.create(null),finish=result=>(combined.aborted||presentation.admit?.(),result),required=new Set(schema.required??[]),entries=Object.entries(schema.properties),field=async(name,property)=>{let title=`${heading}
|
|
@@ -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{buildProviderDiagnostic,categoryForTransportCode,classifyProviderFailure}from"./chunk-
|
|
2
|
+
import{buildProviderDiagnostic,categoryForTransportCode,classifyProviderFailure}from"./chunk-Z7HTHT6K.js";import{attachProviderDiagnostic}from"./chunk-3SASTB6Y.js";var SSE_ERROR_ENVELOPE_MAX_BYTES=8192;function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function optionalString(value){if(value!=null)return typeof value=="string"?value:null}function anthropicProviderDiagnosticFromError(error){try{if(!(error instanceof Error))return;let status=Reflect.get(error,"status"),direct=optionalString(Reflect.get(error,"type")),body=Reflect.get(error,"error"),nested=isRecord(body)&&isRecord(body.error)?optionalString(body.error.type):void 0;if(direct===null||nested===null||direct!==void 0&&nested!==void 0&&direct!==nested)return;let code=direct??nested;if(code===void 0&&status==null)return;let diagnostic=classifyProviderFailure({status,code});if(diagnostic?.category!=="quota"&&diagnostic?.category!=="rate_limit")return diagnostic;let headers=Reflect.get(error,"headers");if(!(headers instanceof Headers))return diagnostic;let resets=["5h","7d"].flatMap(window=>{let utilization=Number(headers.get(`anthropic-ratelimit-unified-${window}-utilization`)),reset=Number(headers.get(`anthropic-ratelimit-unified-${window}-reset`))*1e3;return utilization>=1&&Number.isFinite(reset)&&reset>Date.now()?[reset]:[]});return resets.length===0?diagnostic:{...diagnostic,resetsAt:Math.max(...resets)}}catch{return}}function anthropicProviderDiagnosticFromSseData(data){try{if(new TextEncoder().encode(data).length>SSE_ERROR_ENVELOPE_MAX_BYTES)return;let parsed=JSON.parse(data);if(!isRecord(parsed)||parsed.type!=="error"||!isRecord(parsed.error))return;let code=parsed.error.type;return typeof code!="string"?void 0:classifyProviderFailure({status:void 0,code})}catch{return}}var OPENAI_COMPATIBLE_PRECISE_TYPES=new Set(["exceeded_current_quota_error","insufficient_quota"]);function openAICompatibleProviderDiagnosticFromError(error){try{if(!(error instanceof Error))return;let status=Reflect.get(error,"status"),code=optionalString(Reflect.get(error,"code"));if(code===null)return;let type=code===void 0?optionalString(Reflect.get(error,"type")):void 0,token=code??(typeof type=="string"&&OPENAI_COMPATIBLE_PRECISE_TYPES.has(type)?type:void 0);return token===void 0&&status==null?void 0:classifyProviderFailure({status,code:token})}catch{return}}function siwcProviderDiagnosticFromError(error){let diagnostic=openAICompatibleProviderDiagnosticFromError(error);return diagnostic===void 0?void 0:{...diagnostic,route:"siwc"}}var TRANSPORT_CAUSE_DEPTH=4;function transportProviderDiagnosticFromError(error){try{if(!(error instanceof Error))return;let current=error,sdkConnectionError;for(let depth=0;depth<TRANSPORT_CAUSE_DEPTH&&(isRecord(current)||current instanceof Error);depth++){let code=Reflect.get(current,"code");if(typeof code=="string"&&categoryForTransportCode(code)!==void 0)return buildProviderDiagnostic({category:"network",code,evidence:"structured_transport"});for(let name of current instanceof Error?[current.name,current.constructor.name]:[])sdkConnectionError===void 0&&categoryForTransportCode(name)!==void 0&&(sdkConnectionError=name);current=Reflect.get(current,"cause")}return sdkConnectionError===void 0?void 0:buildProviderDiagnostic({category:"network",code:sdkConnectionError,evidence:"structured_transport"})}catch{return}}function classifyWithTransport(classify,error){return classify(error)??transportProviderDiagnosticFromError(error)}async function awaitProviderTransport(request,classify){try{return await request()}catch(error){throw typeof error=="object"&&error!==null&&attachProviderDiagnostic(error,classifyWithTransport(classify,error)),error}}async function*iterateProviderTransport(source,classify){try{yield*source}catch(error){throw typeof error=="object"&&error!==null&&attachProviderDiagnostic(error,classifyWithTransport(classify,error)),error}}export{anthropicProviderDiagnosticFromError,anthropicProviderDiagnosticFromSseData,openAICompatibleProviderDiagnosticFromError,siwcProviderDiagnosticFromError,transportProviderDiagnosticFromError,awaitProviderTransport,iterateProviderTransport};
|
|
@@ -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{CONTEXT_PROVENANCE_FIELD,contextProvenanceFingerprint,getContextProvenance}from"./chunk-
|
|
2
|
+
import{CONTEXT_PROVENANCE_FIELD,contextProvenanceFingerprint,getContextProvenance}from"./chunk-YXL3PNTL.js";function isUserWord(value){return typeof value=="object"&&value!==null&&"label"in value&&typeof value.label=="string"&&"text"in value&&typeof value.text=="string"}function toolResultUserWords(message){let details=message.details;return typeof details!="object"||details===null||!("userWords"in details)?[]:Array.isArray(details.userWords)?details.userWords.filter(isUserWord):[]}function userWordBlocks(words){return words.flatMap(word=>[{type:"text",text:`[${word.label}]`},{type:"text",text:word.text}])}function appendToolResultUserWords(messages){if(!messages.some(message=>message.role==="toolResult"&&toolResultUserWords(message).length>0))return messages;let result=[],pending=[],source,flush=next=>{source&&!startsWithBlocks(next,pending)&&result.push(wordMessage(pending,source)),pending=[],source=void 0};for(let message of messages){if(message.role!=="toolResult"&&flush(message),result.push(message),message.role!=="toolResult")continue;let blocks=userWordBlocks(toolResultUserWords(message));blocks.length!==0&&(pending.push(...blocks),source=message)}return flush(void 0),result}function wordMessage(content,source){let message={role:"user",content,timestamp:source.timestamp},provenance=getContextProvenance(source);if(!provenance)return message;let{integrity,...owned}=provenance;if(!(integrity===void 0||integrity===contextProvenanceFingerprint(source)))return message;let sealed=integrity===void 0?owned:{...owned,integrity:contextProvenanceFingerprint(message)};return Object.assign(message,{[CONTEXT_PROVENANCE_FIELD]:sealed})}function startsWithBlocks(message,blocks){if(message?.role!=="user"||typeof message.content=="string")return!1;let content=message.content;return blocks.every((block,index)=>{let candidate=content[index];return candidate?.type==="text"&&candidate.text===block.text})}export{toolResultUserWords,userWordBlocks,appendToolResultUserWords};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
-
import{ORIGIN_HOST_INSTANCE_FIELD,RPC_AUTH_HEX,RPC_LAUNCH_ID,RpcEndpointAuthError,authRecord,originHostInstance,readRpcKeyRecord,rpcAuthProof,rpcProofMatches}from"./chunk-E6UCZ7E5.js";import{attachJsonlLineReader,serializeJsonLine}from"./chunk-H52J72VA.js";import{SOCKET_HANDSHAKE_TIMEOUT_MS}from"./chunk-QEESHRTS.js";import{getAgentDir}from"./chunk-
|
|
2
|
+
import{ORIGIN_HOST_INSTANCE_FIELD,RPC_AUTH_HEX,RPC_LAUNCH_ID,RpcEndpointAuthError,authRecord,originHostInstance,readRpcKeyRecord,rpcAuthProof,rpcProofMatches}from"./chunk-E6UCZ7E5.js";import{attachJsonlLineReader,serializeJsonLine}from"./chunk-H52J72VA.js";import{SOCKET_HANDSHAKE_TIMEOUT_MS}from"./chunk-QEESHRTS.js";import{getAgentDir}from"./chunk-SODMQEHO.js";import{createHash}from"node:crypto";import{basename}from"node:path";var TUI_SOCKET_NAME=/^t-[0-9a-f]{16}\.sock$/;function tuiSocketName(instanceId){return`t-${createHash("sha256").update(instanceId,"utf8").digest("hex").slice(0,16)}.sock`}function isTuiControlSocket(socket){return TUI_SOCKET_NAME.test(basename(socket))}function socketNeedsHandshake(socket,platform=process.platform){return platform==="win32"||isTuiControlSocket(socket)}import{AsyncLocalStorage}from"node:async_hooks";import{randomBytes}from"node:crypto";import{createConnection}from"node:net";var keyRoots=new AsyncLocalStorage;function withRpcKeyRoot(root,operation){return keyRoots.run(root,operation)}function rpcKeyRoot(options={},defaultRoot){return options.keyRoot??keyRoots.getStore()??process.env.SENPI_RPC_KEY_ROOT??defaultRoot??getAgentDir()}async function connectAuthenticatedRpcSocket(path,first={type:"get_protocol_info",id:"rpc-auth-protocol",observe:!0,[ORIGIN_HOST_INSTANCE_FIELD]:originHostInstance()},options={},timeoutMs=SOCKET_HANDSHAKE_TIMEOUT_MS){let deadline=Date.now()+timeoutMs;for(let attempt=0;;attempt++){let socket=createConnection(path),earlyError,ignoreLateError=error=>{earlyError??=error};socket.on("error",ignoreLateError);let connected=!1;socket.once("connect",()=>{connected=!0});try{let protocol=await authenticate(socket,path,first,rpcKeyRoot(options),Math.max(1,deadline-Date.now()));return socket.off("error",ignoreLateError),{socket,protocol}}catch(cause){if(socket.destroy(),attempt===0&&cause instanceof RpcEndpointAuthError&&cause.code==="auth_failed")continue;let failure=!(cause instanceof RpcEndpointAuthError)&&earlyError!==void 0?earlyError:cause;throw failure instanceof Error&&Object.assign(failure,{rpcSocketConnected:connected}),failure}}}async function authenticate(socket,path,first,root,timeoutMs){let pending,reject=error=>pending?.reject(error),socketError,onClose=()=>setImmediate(()=>reject(socketError??new Error(`RPC socket closed during authentication: ${path}`))),onError=error=>{socketError??=error,reject(error)};socket.on("error",onError),socket.on("close",onClose);let detach=attachJsonlLineReader(socket,line=>{let response;try{response=authRecord(JSON.parse(line))}catch{return}if(!(response===void 0||pending===void 0||response.id!==pending.id))if(response.success===!0)pending?.resolve(response);else{let code=response.errorCode;reject(code==="auth_failed"||code==="auth_required"?new RpcEndpointAuthError(code,`${path}; set SENPI_RPC_KEY_ROOT to the host's agent dir (${root})`):new Error(`RPC authentication probe refused on ${path}: ${String(response.error)}`))}},{maxLineLength:1024*1024,onOversizedLine:()=>socket.destroy()}),exchange=request=>new Promise((resolve,reject2)=>{if(socket.destroyed){setImmediate(()=>reject2(socketError??new Error(`RPC socket closed during authentication: ${path}`)));return}pending={id:request.id,resolve,reject:reject2},socket.write(serializeJsonLine(request))}),timer=setTimeout(()=>{reject(new Error(`RPC authentication timed out on ${path}`)),socket.destroy()},timeoutMs);try{let nonce=randomBytes(32).toString("hex"),response=await exchange({...first,auth:{client_nonce:nonce}}),data=authRecord(response.data);if(data?.auth===void 0)return response;let auth=authRecord(data.auth);if(typeof auth?.launch_id!="string"||!RPC_LAUNCH_ID.test(auth.launch_id)||typeof auth.server_nonce!="string"||!RPC_AUTH_HEX.test(auth.server_nonce))throw new RpcEndpointAuthError("host_identity_unproven",path);let record=await readRpcKeyRecord(root,auth.launch_id);if(socket.destroyed)throw new Error(`RPC authentication timed out on ${path}`);if(record===void 0)return process.stderr.write(`senpi rpc client: no key record for launch ${auth.launch_id} under ${root}; continuing unauthenticated (refused from the next release; set SENPI_RPC_KEY_ROOT to the host's agent dir)
|
|
3
3
|
`),response;if(typeof record.key!="string")throw new RpcEndpointAuthError("unsafe_key_record",root);let key=Buffer.from(record.key,"hex");if(!rpcProofMatches(rpcAuthProof(key,"server",auth.launch_id,nonce,auth.server_nonce),auth.server_proof))throw new RpcEndpointAuthError("host_identity_unproven",path);return await exchange({id:"rpc-authenticate",type:"authenticate",client_proof:rpcAuthProof(key,"client",auth.launch_id,auth.server_nonce,nonce)}),response}finally{clearTimeout(timer),detach(),socket.off("error",onError),socket.off("close",onClose)}}export{tuiSocketName,isTuiControlSocket,socketNeedsHandshake,withRpcKeyRoot,rpcKeyRoot,connectAuthenticatedRpcSocket};
|
|
@@ -1,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{getAgentDir}from"./chunk-
|
|
2
|
+
import{getAgentDir}from"./chunk-SODMQEHO.js";import{processStartTimeMs,readProcessIdentity,sameProcessStartMs}from"./chunk-O5RYI3IW.js";import{existsSync,realpathSync}from"node:fs";import{basename,dirname,join,resolve}from"node:path";function canonicalSessionPath(path){let absolutePath=resolve(path),missing=[],existing=absolutePath;for(;!existsSync(existing);){let parent=dirname(existing);if(parent===existing)return absolutePath;missing.unshift(basename(existing)),existing=parent}try{return join(realpathSync(existing),...missing)}catch{return absolutePath}}function sessionDirectoryRemoved(sessionFile){return!existsSync(dirname(sessionFile))}import{createHash}from"node:crypto";import{basename as basename2,dirname as dirname2,join as join2,win32}from"node:path";function canonicalEndpointPath(socket,platform=process.platform){return platform==="win32"?win32.normalize(socket).toLowerCase():socket.startsWith("\0")?socket:join2(canonicalSessionPath(dirname2(socket)),basename2(socket))}function daemonDirectoryName(socket,platform=process.platform){return directoryNameOf(canonicalEndpointPath(socket,platform))}function sameEndpoint(socket,other){return socket===other||canonicalEndpointPath(socket)===canonicalEndpointPath(other)}function socketNamesDirectory(socket,name){return daemonDirectoryName(socket)===name||process.platform!=="win32"&&directoryNameOf(socket)===name}function directoryNameOf(endpoint){return createHash("sha256").update(endpoint,"utf8").digest("hex").slice(0,16)}function shardKey(kind,ownerId){return createHash("sha256").update(`${kind}:${ownerId}`,"utf8").digest("hex").slice(0,16)}function shardSocketPathForKey(root,kind,key){return join2(root,`${kind}-${key}.sock`)}function shardSocketPath(root,kind,ownerId){return shardSocketPathForKey(root,kind,shardKey(kind,ownerId))}var SHARD_SOCKET_NAME=/^(p|i)-([0-9a-f]{16})\.sock$/;function parseShardSocket(socket){let match=SHARD_SOCKET_NAME.exec(basename2(socket)),key=match?.[2];return key===void 0?null:{kind:match?.[1]==="i"?"i":"p",key}}import{chmod,mkdir}from"node:fs/promises";import{join as join3}from"node:path";var DIRECTORY_MODE=448;function generationPaths(paths,instanceId){let dir=join3(paths.generationsDir,instanceId);return{dir,relativeDir:`generations/${instanceId}`,pidFile:join3(dir,"host.pid"),settingsFile:join3(dir,"settings.json"),scratchDir:join3(dir,"scratch"),childPidFile:join3(dir,"host-child.pid"),stopIntentFile:join3(dir,"stop-intent.json"),drainRequestFile:join3(dir,"drain-request.json"),childDrainRequestFile:join3(dir,"host-drain-request.json"),drainWatchFile:join3(dir,"drain-watch.json"),stalledFile:join3(dir,"host-stalled.json"),aliveFile:join3(dir,"host-alive.json"),stopProgressFile:join3(dir,"stop-progress.json")}}var HostDaemonStateError=class extends Error{constructor(path,cause){super(`RPC daemon state directory ${path} is not usable: ${cause instanceof Error?cause.message:cause}`,{cause}),this.name="HostDaemonStateError",this.path=path}};async function createGenerationDirectory(generation){try{await mkdir(generation.scratchDir,{recursive:!0,mode:DIRECTORY_MODE}),await chmod(generation.dir,DIRECTORY_MODE)}catch(cause){throw new HostDaemonStateError(generation.dir,cause)}}import{randomUUID}from"node:crypto";import{chmod as chmod2,link,mkdir as mkdir2,readFile,rename,rm,writeFile}from"node:fs/promises";import{basename as basename3,join as join4}from"node:path";var HOST_DAEMON_LAYOUT=2,HOST_DAEMON_DIR_ENV="SENPI_RPC_HOST_DAEMON_DIR",ENDPOINT_REGISTRY_VERSION=1,DIRECTORY_MODE2=448,HOST_STATE_FILE_MODE=384;function createHostDaemonPaths(target){let flatDir=join4(target.agentDir??getAgentDir(),"rpc-host-daemon");return{socket:target.socket,flatDir,layoutMarker:join4(flatDir,"layout.json"),legacyPidFile:join4(flatDir,"host.pid"),...hostDaemonDirectoryPaths(join4(flatDir,daemonDirectoryName(target.socket)))}}function hostDaemonDirectoryPaths(dir){return{dir,endpointFile:join4(dir,"endpoint.json"),pointerFile:join4(dir,"host.pid"),lockFile:join4(dir,"daemon.lock"),settingsFile:join4(dir,"settings.json"),stderrLog:join4(dir,"stderr.log"),generationsDir:join4(dir,"generations"),reservationsDir:join4(dir,"reservations")}}async function createDaemonDirectories(paths,identity={}){try{await mkdir2(paths.flatDir,{recursive:!0,mode:DIRECTORY_MODE2}),await makePrivateDirectory(paths.dir),await Promise.all([makePrivateDirectory(paths.generationsDir),makePrivateDirectory(paths.reservationsDir),writeFile(paths.layoutMarker,`${JSON.stringify({layout:HOST_DAEMON_LAYOUT,dir:basename3(paths.dir)})}
|
|
3
3
|
`,{mode:HOST_STATE_FILE_MODE})])}catch(cause){throw new HostDaemonStateError(paths.dir,cause)}await ensureEndpointIdentity(paths,paths.socket,identity)}async function makePrivateDirectory(directory){await mkdir2(directory,{recursive:!0,mode:DIRECTORY_MODE2})===void 0&&await chmod2(directory,DIRECTORY_MODE2)}async function ensureEndpointIdentity(paths,socket,options={}){let temporary=`${paths.endpointFile}.${process.pid}-${randomUUID()}.tmp`;try{await mkdir2(paths.dir,{recursive:!0,mode:DIRECTORY_MODE2});let record=`${JSON.stringify({layout:HOST_DAEMON_LAYOUT,registry_version:ENDPOINT_REGISTRY_VERSION,endpoint_kind:options.kind??"rpc_host",socket,created_at:new Date().toISOString()})}
|
|
4
4
|
`;await writeFile(temporary,record,{mode:HOST_STATE_FILE_MODE,flag:"wx"}),!await link(temporary,paths.endpointFile).then(()=>!0,cause=>isErrorCode(cause,"EEXIST")?!1:createExclusively(paths.endpointFile,record))&&options.repair===!0&&!await namesThisDirectory(paths)&&await rename(temporary,paths.endpointFile)}catch(cause){throw new HostDaemonStateError(paths.endpointFile,cause)}finally{await rm(temporary,{force:!0})}}async function createExclusively(path,content){try{return await writeFile(path,content,{mode:HOST_STATE_FILE_MODE,flag:"wx"}),!0}catch(cause){if(isErrorCode(cause,"EEXIST"))return!1;throw cause}}function isErrorCode(cause,code){return cause instanceof Error&&"code"in cause&&cause.code===code}async function namesThisDirectory(paths){let record;try{record=JSON.parse(await readFile(paths.endpointFile,"utf8"))}catch{return!1}return typeof record!="object"||record===null||!("socket"in record)?!1:typeof record.socket=="string"&&record.socket!==""&&socketNamesDirectory(record.socket,basename3(paths.dir))}import{randomUUID as randomUUID2}from"node:crypto";import{readFile as readFile2,rename as rename2,rm as rm2,writeFile as writeFile2}from"node:fs/promises";async function writeJsonAtomic(path,content){let temporary=`${path}.${process.pid}.${randomUUID2().slice(0,8)}.tmp`;try{await writeFile2(temporary,`${JSON.stringify(content)}
|
|
5
5
|
`,{mode:384}),await rename2(temporary,path)}catch(cause){throw await rm2(temporary,{force:!0}).catch(()=>{}),cause}}async function readJsonObject(path){try{let value=JSON.parse(await readFile2(path,"utf8"));return typeof value=="object"&&value!==null&&!Array.isArray(value)?{...value}:void 0}catch{return}}function ageOf(at,now){if(typeof at!="string")return;let parsed=Date.parse(at);return Number.isNaN(parsed)?void 0:now-parsed}import{readFile as readFile3,writeFile as writeFile3}from"node:fs/promises";import{join as join5}from"node:path";async function readHostOwner(generationDir){let record=await readJsonObject(join5(generationDir,"owner.json"));if(record?.owner===null)return null;if(!isRecord(record?.owner))return;let{pid,startTime}=record.owner;return typeof pid=="number"&&Number.isSafeInteger(pid)&&pid>0&&typeof startTime=="string"&&startTime.length>0?{pid,startTime}:void 0}function writeHostOwner(generationDir,owner){return writeJsonAtomic(join5(generationDir,"owner.json"),{owner})}function sameHostOwner(a,b){if(a==null||b==null||a.pid!==b.pid)return!1;let started=processStartTimeMs(a.startTime);return started!==void 0&&started===processStartTimeMs(b.startTime)}async function callerHostOwner(){let observed=await readProcessIdentity(process.pid,process.platform,void 0,void 0,"UTC");if(observed.kind!=="present"||processStartTimeMs(observed.identity)===void 0)throw new Error("cannot establish RPC host owner OS start identity");return{pid:process.pid,startTime:observed.identity}}async function hostOwnerGone(owner){let observed=await readProcessIdentity(owner.pid,process.platform,1e3,void 0,"UTC");return observed.kind==="absent"||observed.kind==="present"&&processStartTimeMs(observed.identity)!==void 0&&processStartTimeMs(owner.startTime)!==void 0&&!sameProcessStartMs(processStartTimeMs(observed.identity),processStartTimeMs(owner.startTime))}async function claimHostOwner(generationDir){let previous=await readHostOwner(generationDir);if(previous===void 0)throw new Error("RPC host does not support owner lifetime registration");let next=await callerHostOwner();if(!sameHostOwner(previous,next)){if(previous!==null&&!await hostOwnerGone(previous))throw new Error("RPC host lifetime owner is still alive or its identity is unknown");await writeHostOwner(generationDir,next)}}async function writeHostSettings(paths,settings){let generation=generationPaths(paths,settings.instanceId);await createGenerationDirectory(generation),await writeStateFile(paths.settingsFile,settings),await writeStateFile(generation.settingsFile,settings)}async function readHostSettings(paths){let parsed=parseJson(await readFileOrUndefined(paths.settingsFile));if(parsed)return{...typeof parsed.coldStart=="string"&&{coldStart:parsed.coldStart},...typeof parsed.idleExitMs=="number"&&{idleExitMs:parsed.idleExitMs}}}async function writeStateFile(path,content){try{await writeFile3(path,`${JSON.stringify(content)}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
-
import{require_proper_lockfile}from"./chunk-GZVCRV7I.js";import{CONFIG_DIR_NAME,canonicalizePath,canonicalizePathStrict,findNodePackageDir,getDocsPath,getExamplesPath,getExportTemplateDir,getInstallPackageDir,getInteractiveAssetsDir,getPackageDir,getThemesDir,isBunBinary,resolvePath,stripBom}from"./chunk-
|
|
2
|
+
import{require_proper_lockfile}from"./chunk-GZVCRV7I.js";import{CONFIG_DIR_NAME,canonicalizePath,canonicalizePathStrict,findNodePackageDir,getDocsPath,getExamplesPath,getExportTemplateDir,getInstallPackageDir,getInteractiveAssetsDir,getPackageDir,getThemesDir,isBunBinary,resolvePath,stripBom}from"./chunk-SODMQEHO.js";import{__toESM}from"./chunk-IKOFCODM.js";var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import{existsSync as existsSync2,mkdirSync,readFileSync,writeFileSync}from"node:fs";import{readFile,realpath,stat}from"node:fs/promises";import{homedir}from"node:os";import{basename,dirname as dirname3,join as join3,relative,resolve as resolve2,sep as sep2}from"node:path";import{existsSync}from"node:fs";import{createRequire}from"node:module";import{dirname as dirname2,join as join2,resolve,sep}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";import{dirname,join}from"node:path";import{fileURLToPath}from"node:url";function imagegenSkillPath(baseDir=dirname(fileURLToPath(import.meta.url))){return join(baseDir,"skill","SKILL.md")}var moduleRequire=createRequire(import.meta.url),runningFromSource=fileURLToPath2(import.meta.url).includes(`${sep}src${sep}core${sep}`),bundledBuiltinExtensions=[{id:"codemode",resolvePackage:()=>resolveBundledPackageJson("@code-yeongyu/senpi-codemode/package.json","senpi-codemode/package.json",join2("node_modules","@code-yeongyu","senpi-codemode","package.json"))}];function resolveBundledPackageJson(packageSpecifier,workspaceRelativePath,binaryRelativePath){let packageRoot=getPackageDir(),workspacePath=resolve(packageRoot,"..",workspaceRelativePath);if(runningFromSource&&existsSync(workspacePath))return workspacePath;let binaryPath=resolve(packageRoot,binaryRelativePath);if(isBunBinary&&existsSync(binaryPath))return binaryPath;try{return moduleRequire.resolve(packageSpecifier)}catch(error){if(existsSync(workspacePath))return workspacePath;throw error}}function getBundledResourceRoots(){let roots=[getThemesDir(),getExportTemplateDir(),getInteractiveAssetsDir(),getDocsPath(),getExamplesPath(),dirname2(imagegenSkillPath())];!isBunBinary&&!runningFromSource?roots.push(getPackageDir(),getInstallPackageDir(),findNodePackageDir(dirname2(fileURLToPath2(import.meta.url)))):isBunBinary&&roots.push(dirname2(fileURLToPath2(import.meta.url)));for(let extension of bundledBuiltinExtensions)try{roots.push(dirname2(extension.resolvePackage()))}catch(error){if(!(error instanceof Error&&"code"in error&&error.code==="MODULE_NOT_FOUND"))throw error}return roots}var TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES=["settings.json","mcp.json","extensions","skills","prompts","themes","SYSTEM.md","APPEND_SYSTEM.md"],LEGACY_PROJECT_CONFIG_DIR_NAME=".pi";function projectCodemodeNamesExecutable(configDir){let path=join3(configDir,"codemode.json");if(!existsSync2(path))return!1;let executableSettings=codemodeExecutableSettings();if(executableSettings===void 0)return!0;let parsed;try{parsed=JSON.parse(stripBom(readFileSync(path,"utf8")))}catch{return!0}return executableSettings.some(settingPath=>valueAtPath(parsed,settingPath)!==void 0)}function codemodeExecutableSettings(){let codemode=bundledBuiltinExtensions.find(extension=>extension.id==="codemode");try{let packageJson=codemode?.resolvePackage();if(packageJson===void 0)return;let list=JSON.parse(readFileSync(join3(dirname3(packageJson),"src","config","executable-settings.json"),"utf8"));if(typeof list!="object"||list===null)return;let paths=Reflect.get(list,"projectExecutableSettings");return Array.isArray(paths)&&paths.every(entry=>typeof entry=="string")?paths:void 0}catch{return}}function valueAtPath(value,path){let current=value;for(let key of path.split(".")){if(typeof current!="object"||current===null)return;current=Reflect.get(current,key)}return current}function normalizeCwd(cwd){let resolved=resolvePath(cwd);try{return canonicalizePathStrict(resolved)}catch{return resolved}}function findNearestTrustEntry(data,cwd){let currentDir=normalizeCwd(cwd);for(;;){let value=data[currentDir];if(value===!0||value===!1)return{path:currentDir,decision:value};let parentDir=dirname3(currentDir);if(parentDir===currentDir)return null;currentDir=parentDir}}function getProjectTrustParentPath(cwd){let trustPath=normalizeCwd(cwd),parentDir=dirname3(trustPath);return parentDir===trustPath?void 0:parentDir}function getProjectTrustOptions(cwd,options){let trustPath=normalizeCwd(cwd),trustOptions=[{label:"Trust",trusted:!0,updates:[{path:trustPath,decision:!0}],savedPath:trustPath}],parentPath=getProjectTrustParentPath(cwd);return parentPath!==void 0&&trustOptions.push({label:`Trust parent folder (${parentPath})`,trusted:!0,updates:[{path:parentPath,decision:!0},{path:trustPath,decision:null}],savedPath:parentPath}),options?.includeSessionOnly&&trustOptions.push({label:"Trust (this session only)",trusted:!0,updates:[]}),trustOptions.push({label:"Do not trust",trusted:!1,updates:[{path:trustPath,decision:!1}],savedPath:trustPath}),options?.includeSessionOnly&&trustOptions.push({label:"Do not trust (this session only)",trusted:!1,updates:[]}),trustOptions}function readTrustFile(path){if(!existsSync2(path))return{};let parsed;try{parsed=JSON.parse(stripBom(readFileSync(path,"utf-8")))}catch(error){let message=error instanceof Error?error.message:String(error);throw new Error(`Failed to read trust store ${path}: ${message}`)}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))throw new Error(`Invalid trust store ${path}: expected an object`);let data={};for(let[key,value]of Object.entries(parsed)){if(value!==!0&&value!==!1&&value!==null)throw new Error(`Invalid trust store ${path}: value for ${JSON.stringify(key)} must be true, false, or null`);data[key]=value}return data}function writeTrustFile(path,data){let sorted={};for(let key of Object.keys(data).sort()){let value=data[key];(value===!0||value===!1||value===null)&&(sorted[key]=value)}mkdirSync(dirname3(path),{recursive:!0}),writeFileSync(path,`${JSON.stringify(sorted,null,2)}
|
|
3
3
|
`,"utf-8")}function acquireTrustLockSync(path){let trustDir=dirname3(path);mkdirSync(trustDir,{recursive:!0});let maxAttempts=10,delayMs=20,lastError;for(let attempt=1;attempt<=maxAttempts;attempt++)try{return import_proper_lockfile.default.lockSync(trustDir,{realpath:!1,lockfilePath:`${path}.lock`})}catch(error){if((typeof error=="object"&&error!==null&&"code"in error?String(error.code):void 0)!=="ELOCKED"||attempt===maxAttempts)throw error;lastError=error;let start=Date.now();for(;Date.now()-start<delayMs;);}throw lastError instanceof Error?lastError:new Error("Failed to acquire trust store lock")}function withTrustFileLock(path,fn){let release=acquireTrustLockSync(path);try{return fn()}finally{release()}}function isHomeOrAboveDir(dir,homeDir){return dir===homeDir||homeDir.startsWith(dir.endsWith(sep2)?dir:`${dir}${sep2}`)}function findGitRepoRoot(dir){let currentDir=dir;for(;!existsSync2(join3(currentDir,".git"));){let parentDir=dirname3(currentDir);if(parentDir===currentDir)return;currentDir=parentDir}return currentDir}function projectAgentsSkillDirs(cwd){let homeDir=canonicalizePath(resolvePath(process.env.HOME||homedir())),startDir=resolvePath(cwd),gitRepoRoot=findGitRepoRoot(startDir),dirs=[],currentDir=startDir;for(;!isHomeOrAboveDir(canonicalizePath(currentDir),homeDir)&&(dirs.push(join3(currentDir,".agents","skills")),currentDir!==gitRepoRoot);){let parentDir=dirname3(currentDir);if(parentDir===currentDir)break;currentDir=parentDir}return dirs}function hasTrustRequiringProjectResources(cwd){let homeDir=canonicalizePath(resolvePath(process.env.HOME||homedir())),currentDir=canonicalizePath(resolvePath(cwd));return!isHomeOrAboveDir(currentDir,homeDir)&&([join3(currentDir,CONFIG_DIR_NAME),join3(currentDir,LEGACY_PROJECT_CONFIG_DIR_NAME)].some(configDir=>TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES.some(entry=>existsSync2(join3(configDir,entry))))||projectCodemodeNamesExecutable(join3(currentDir,CONFIG_DIR_NAME)))?!0:projectAgentsSkillDirs(cwd).some(dir=>existsSync2(dir))}var ProjectTrustStore=class{constructor(agentDir){this.trustPath=join3(resolvePath(agentDir),"trust.json")}get(cwd){return this.getEntry(cwd)?.decision??null}getEntry(cwd){return withTrustFileLock(this.trustPath,()=>{let data=readTrustFile(this.trustPath);return findNearestTrustEntry(data,cwd)})}set(cwd,decision){this.setMany([{path:cwd,decision}])}setMany(decisions){withTrustFileLock(this.trustPath,()=>{let data=readTrustFile(this.trustPath);for(let{path,decision}of decisions){let key=normalizeCwd(path);decision===null?delete data[key]:data[key]=decision}writeTrustFile(this.trustPath,data)})}},GITDIR_POINTER=/^gitdir:\s*(.+)$/;async function readFirstLine(path){try{return(await readFile(path,"utf-8")).split(/\r?\n/,1)[0]?.trim()||void 0}catch{return}}async function realPathOf(path){try{return await realpath(path)}catch{return}}async function entryKind(path){try{let stats=await stat(path);return stats.isDirectory()?"directory":stats.isFile()?"file":void 0}catch{return}}async function linkedWorktreeMainCheckoutDir(cwd){let dir=await realPathOf(resolvePath(cwd))??resolvePath(cwd),checkoutRoot=dir,markerKind=await entryKind(join3(checkoutRoot,".git"));for(;markerKind===void 0;){let parentDir=dirname3(checkoutRoot);if(parentDir===checkoutRoot)return;checkoutRoot=parentDir,markerKind=await entryKind(join3(checkoutRoot,".git"))}if(markerKind!=="file")return;let marker=join3(checkoutRoot,".git"),adminTarget=GITDIR_POINTER.exec(await readFirstLine(marker)??"")?.[1]?.trim();if(!adminTarget)return;let adminDir=await realPathOf(resolve2(checkoutRoot,adminTarget));if(adminDir===void 0)return;let commonDirPointer=await readFirstLine(join3(adminDir,"commondir")),backPointer=await readFirstLine(join3(adminDir,"gitdir"));if(commonDirPointer===void 0||backPointer===void 0)return;let markerRealPath=await realPathOf(marker);if(markerRealPath===void 0||await realPathOf(resolve2(adminDir,backPointer))!==markerRealPath)return;let commonDir=await realPathOf(resolve2(adminDir,commonDirPointer));if(commonDir===void 0||basename(commonDir)!==".git"||dirname3(adminDir)!==join3(commonDir,"worktrees"))return;let mainCheckout=dirname3(commonDir),mainMarker=join3(mainCheckout,".git");if(!(await entryKind(mainMarker)!=="directory"||await realPathOf(mainMarker)!==commonDir))return join3(mainCheckout,relative(checkoutRoot,dir))}async function getSavedProjectTrust(store,cwd){let own=store.get(cwd);if(own!==null)return own;let mainCheckoutDir=await linkedWorktreeMainCheckoutDir(cwd);return mainCheckoutDir===void 0?null:store.get(mainCheckoutDir)}export{imagegenSkillPath,bundledBuiltinExtensions,getBundledResourceRoots,getProjectTrustOptions,projectAgentsSkillDirs,hasTrustRequiringProjectResources,ProjectTrustStore,getSavedProjectTrust};
|
|
@@ -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{resolveMovedPath}from"./chunk-
|
|
2
|
+
import{resolveMovedPath}from"./chunk-USKWGPA6.js";import{advanceSessionFence}from"./chunk-SOMFLLPD.js";import{killWindowsProcessTree}from"./chunk-MCXOJHN2.js";import{APP_NAME}from"./chunk-SODMQEHO.js";import{ownProcessStartedAtMs,processBootAtMs,sameBoot}from"./chunk-QN2BHP3M.js";import{processStartTimeMs,sameProcessStartMs}from"./chunk-O5RYI3IW.js";import{randomUUID}from"node:crypto";import{mkdir,readdir,readFile,rename,rm,stat,writeFile}from"node:fs/promises";import{dirname,join}from"node:path";var InvalidScheduledJobError=class extends Error{constructor(message){super(message),this.name="InvalidScheduledJobError"}};function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function requireString(raw,key){let value=raw[key];if(typeof value!="string"||value.length===0)throw new InvalidScheduledJobError(`scheduled job field "${key}" must be a non-empty string`);return value}function requireCount(raw,key){let value=raw[key];if(typeof value!="number"||!Number.isSafeInteger(value)||value<0)throw new InvalidScheduledJobError(`scheduled job field "${key}" must be a non-negative integer`);return value}function nullableCount(raw,key){return raw[key]===null||raw[key]===void 0?null:requireCount(raw,key)}function nullableString(raw,key){let value=raw[key];if(value==null)return null;if(typeof value!="string")throw new InvalidScheduledJobError(`scheduled job field "${key}" must be a string`);return value}function parseScheduledJob(raw){if(!isRecord(raw))throw new InvalidScheduledJobError("scheduled job must be a JSON object");if(raw.version!==1)throw new InvalidScheduledJobError(`unsupported scheduled job version: ${JSON.stringify(raw.version)}`);let id=requireString(raw,"id");if(!/^sch_[a-z0-9]{12}$/.test(id))throw new InvalidScheduledJobError(`invalid scheduled job id: ${id}`);let everyMs=nullableCount(raw,"everyMs");if(everyMs!==null&&everyMs<60*1e3)throw new InvalidScheduledJobError("scheduled job recurrence must be at least 60s");if(everyMs!==null&&everyMs>316224e5)throw new InvalidScheduledJobError("scheduled job recurrence must be at most 366 days");let prompt=requireString(raw,"prompt");if(Buffer.byteLength(prompt,"utf8")>16384)throw new InvalidScheduledJobError("scheduled job prompt exceeds 16384 bytes");let createdAt=requireCount(raw,"createdAt"),dueAt=requireCount(raw,"dueAt");return{version:1,id,sessionId:requireString(raw,"sessionId"),sessionFile:nullableString(raw,"sessionFile"),cwd:requireString(raw,"cwd"),prompt,createdAt,dueAt,everyMs,fireCount:requireCount(raw,"fireCount"),lastFiredAt:nullableCount(raw,"lastFiredAt"),lastError:nullableString(raw,"lastError")}}function nextRecurringDueAt(dueAt,everyMs,now){if(dueAt>now)return dueAt;let missed=Math.floor((now-dueAt)/everyMs)+1;return dueAt+missed*everyMs}function formatScheduledMessage(job,firedAt){let recurrence=job.everyMs===null?"":`, repeats every ${Math.round(job.everyMs/1e3)}s`;return`[Scheduled prompt ${job.id}: created ${new Date(job.createdAt).toISOString()}, due ${new Date(job.dueAt).toISOString()}, fired ${new Date(firedAt).toISOString()}${recurrence}]
|
|
3
3
|
${job.prompt}`}var STATE_DIRS=["pending","firing","failed"],JOB_ID=/^sch_[a-z0-9]{12}$/,RECORD_FILE=/^(sch_[a-z0-9]{12})(?:@(\d+)(?:~(\d+)-(\d+))?)?\.json$/;function scheduleDir(agentDir){return join(agentDir,"schedule")}function isScheduledJobId(id){return JOB_ID.test(id)}function isFileSystemError(error,code){return error instanceof Error&&"code"in error&&error.code===code}async function ensureDir(dir){await mkdir(dir,{recursive:!0,mode:448})}async function writeAtomic(filePath,contents){await ensureDir(dirname(filePath));let tempPath=join(dirname(filePath),`.schedule-${randomUUID()}.tmp`);try{await writeFile(tempPath,contents,{encoding:"utf8",mode:384}),await rename(tempPath,filePath)}catch(error){throw await rm(tempPath,{force:!0}),error}}function serialize(job){return`${JSON.stringify(job,null,2)}
|
|
4
4
|
`}async function readJobFile(path,expectedId){if((await stat(path)).size>65536)throw new InvalidScheduledJobError(`scheduled job file exceeds ${65536} bytes`);let parsed;try{parsed=JSON.parse(await readFile(path,"utf8"))}catch(error){throw isFileSystemError(error,"ENOENT")?error:new InvalidScheduledJobError("scheduled job file is not valid JSON")}let job=parseScheduledJob(parsed);if(job.id!==expectedId)throw new InvalidScheduledJobError(`scheduled job id ${job.id} does not match its file`);return job}async function listScheduledJobs(dir){let jobs=[],invalid=[];for(let state of STATE_DIRS){let names;try{names=await readdir(join(dir,state))}catch(error){if(isFileSystemError(error,"ENOENT"))continue;throw error}for(let name of names.sort()){let match=RECORD_FILE.exec(name);if(match===null)continue;let[,id,occurrence,pid,startedAt]=match,file=join(state,name);if(!(state==="pending"?occurrence===void 0:state==="firing"?pid!==void 0:occurrence!==void 0&&pid===void 0)||id===void 0){invalid.push({state,file,error:`unexpected record name for ${state}/`});continue}try{let job=await readJobFile(join(dir,file),id);jobs.push({state,job,file,...occurrence===void 0?{}:{occurrence:Number(occurrence)},...pid===void 0||startedAt===void 0?{}:{owner:{pid:Number(pid),processStartedAtMs:Number(startedAt)}}})}catch(error){if(isFileSystemError(error,"ENOENT"))continue;invalid.push({state,file,error:error instanceof Error?error.message:String(error)})}}}return jobs.sort((a,b)=>a.job.dueAt-b.job.dueAt),{jobs,invalid}}async function createScheduledJob(dir,input,now){let job=parseScheduledJob({version:1,id:`sch_${randomUUID().replace(/-/g,"").slice(0,12)}`,...input,createdAt:now,fireCount:0,lastFiredAt:null});return await writeAtomic(join(dir,"pending",`${job.id}.json`),serialize(job)),job}function tombstonePath(dir,id){return join(dir,"cancelled",id)}async function isCancelled(dir,id){try{return await stat(tombstonePath(dir,id)),!0}catch(error){if(isFileSystemError(error,"ENOENT"))return!1;throw error}}function runnersDir(dir){return join(dir,"runners")}import{randomUUID as randomUUID2}from"node:crypto";import{link,readdir as readdir2,rename as rename2,rm as rm2,stat as stat2,writeFile as writeFile2}from"node:fs/promises";import{join as join2}from"node:path";var TOMBSTONE_RETENTION_MS=1440*60*1e3;async function cancelScheduledJob(dir,id,options={}){if(!isScheduledJobId(id))return;let records=(await listScheduledJobs(dir)).jobs.filter(record=>record.job.id===id),representative=records.find(record=>record.state==="pending")??records[0];if(representative===void 0||options.sessionId!==void 0&&representative.job.sessionId!==options.sessionId)return;await writeAtomic(tombstonePath(dir,id),`${new Date().toISOString()}
|
|
5
5
|
`);let inFlight=(await occurrenceNumbers(dir,"firing",id)).length>0;await rm2(join2(dir,"pending",`${id}.json`),{force:!0});let failed=records.filter(record=>record.state==="failed");for(let record of failed)await rm2(join2(dir,record.file),{force:!0});return{job:representative.job,inFlight,removedFailed:failed.length}}function occurrenceFile(id,occurrence,owner){return join2("firing",`${id}@${occurrence}~${owner.pid}-${owner.processStartedAtMs}.json`)}async function restorePending(dir,record,id){let pending=join2(dir,"pending",`${id}.json`);try{await link(join2(dir,record),pending)}catch(error){if(!isFileSystemError(error,"EEXIST"))throw error}await rm2(join2(dir,record),{force:!0}),await isCancelled(dir,id)&&await rm2(pending,{force:!0})}async function claimOccurrence(dir,job,owner){let record=occurrenceFile(job.id,job.fireCount+1,owner);await ensureDir(join2(dir,"firing"));try{await rename2(join2(dir,"pending",`${job.id}.json`),join2(dir,record))}catch(error){if(isFileSystemError(error,"ENOENT"))return;throw error}if(await isCancelled(dir,job.id)){await rm2(join2(dir,record),{force:!0});return}if((await readJobFile(join2(dir,record),job.id)).fireCount!==job.fireCount){await restorePending(dir,record,job.id);return}return record}async function rearmRecurringJob(dir,next){if(await isCancelled(dir,next.id))return;let path=join2(dir,"pending",`${next.id}.json`);await writeAtomic(path,serialize(next)),await isCancelled(dir,next.id)&&await rm2(path,{force:!0})}async function occurrenceNumbers(dir,state,id){let names;try{names=await readdir2(join2(dir,state))}catch(error){if(isFileSystemError(error,"ENOENT"))return[];throw error}let prefix=`${id}@`;return names.filter(name=>name.startsWith(prefix)).map(name=>Number.parseInt(name.slice(prefix.length),10)).filter(occurrence=>Number.isSafeInteger(occurrence))}async function restoreAbandonedSchedule(dir,job,occurrence,now){if(job.everyMs===null||await isCancelled(dir,job.id))return;let pending=join2(dir,"pending",`${job.id}.json`);if(await stat2(pending).then(()=>!0,()=>!1)||[...await occurrenceNumbers(dir,"firing",job.id),...await occurrenceNumbers(dir,"failed",job.id)].some(n=>n>occurrence))return;let next={...job,fireCount:occurrence,dueAt:nextRecurringDueAt(job.dueAt,job.everyMs,now),lastError:null};await ensureDir(join2(dir,"pending"));let temp=join2(dir,"pending",`.schedule-${randomUUID2()}.tmp`);try{await writeFile2(temp,serialize(next),{encoding:"utf8",mode:384}),await link(temp,pending)}catch(error){if(!isFileSystemError(error,"EEXIST"))throw error;return}finally{await rm2(temp,{force:!0})}if(await isCancelled(dir,job.id)){await rm2(pending,{force:!0});return}return next}async function settleOccurrence(dir,record,job,occurrence,outcome){if(!outcome.ok&&!await isCancelled(dir,job.id)){let failed=join2(dir,"failed",`${job.id}@${occurrence}.json`);await writeAtomic(failed,serialize({...job,lastError:outcome.error})),await isCancelled(dir,job.id)&&await rm2(failed,{force:!0});let older=(await occurrenceNumbers(dir,"failed",job.id)).sort((a,b)=>b-a);for(let stale of older.slice(10))await rm2(join2(dir,"failed",`${job.id}@${stale}.json`),{force:!0})}await rm2(join2(dir,record),{force:!0})}async function pruneTombstones(dir,listing,now){let names;try{names=await readdir2(join2(dir,"cancelled"))}catch(error){if(isFileSystemError(error,"ENOENT"))return;throw error}let live=new Set(listing.jobs.filter(record=>record.state!=="failed").map(record=>record.job.id));for(let id of names){if(!isScheduledJobId(id)||live.has(id))continue;let info=await stat2(tombstonePath(dir,id)).catch(()=>{});info!==void 0&&now-info.mtimeMs>TOMBSTONE_RETENTION_MS&&await rm2(tombstonePath(dir,id),{force:!0})}}import{mkdir as mkdir2,readdir as readdir3,stat as stat4}from"node:fs/promises";import{join as join3}from"node:path";import{randomUUID as randomUUID3}from"node:crypto";import{link as link2,open,readFile as readFile3,rename as rename3,stat as stat3,unlink}from"node:fs/promises";import{execFile}from"node:child_process";import{readFile as readFile2}from"node:fs/promises";var LINUX_CLOCK_TICKS_PER_SECOND=100;async function linuxProcessStartMs(pid){let[stat5,systemStat]=await Promise.all([readFile2(`/proc/${pid}/stat`,"utf8"),readFile2("/proc/stat","utf8")]),afterComm=stat5.slice(stat5.lastIndexOf(")")+2).split(" "),startTicks=Number(afterComm[19]),bootSeconds=Number(/^btime (\d+)/m.exec(systemStat)?.[1]);if(!(!Number.isFinite(startTicks)||!Number.isFinite(bootSeconds)))return Math.round((bootSeconds+startTicks/LINUX_CLOCK_TICKS_PER_SECOND)*1e3)}function execText(command,args,env){return new Promise((resolve,reject)=>{execFile(command,[...args],{encoding:"utf8",timeout:5e3,windowsHide:!0,...env===void 0?{}:{env}},(error,stdout)=>{error?reject(error):resolve(stdout)})})}async function darwinProcessStartMs(pid){let text=(await execText("ps",["-o","lstart=","-p",String(pid)],{...process.env,LC_ALL:"C",LANG:"C"})).trim();if(text.length!==0)return processStartTimeMs(text)}async function windowsProcessStartMs(pid){let script=`(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.ToUniversalTime().ToString('o')`,text=(await execText("powershell",["-NoProfile","-NonInteractive","-Command",script])).trim();return processStartTimeMs(text)}async function readProcessStartMs(pid){try{switch(process.platform){case"linux":return await linuxProcessStartMs(pid);case"darwin":return await darwinProcessStartMs(pid);case"win32":return await windowsProcessStartMs(pid);default:return}}catch{return}}function errorCode(error){if(typeof error=="object"&&error!==null&&"code"in error&&typeof error.code=="string")return error.code}async function unlinkIfPresent(path){try{await unlink(path)}catch(error){if(errorCode(error)!=="ENOENT")throw error}}async function readLeaseText(path){try{return await readFile3(path,"utf8")}catch(error){if(errorCode(error)==="ENOENT")return;throw error}}async function writeTemp(path,content,mode){let temp=`${path}.${process.pid}.${randomUUID3().slice(0,8)}.tmp`,file=await open(temp,"wx",mode);try{await file.writeFile(content,"utf8")}finally{await file.close()}return temp}async function publishExclusive(path,content,options={}){let temp=await writeTemp(path,content,options.mode);try{await link2(temp,path)}catch(error){let code=errorCode(error);if(code!=="ENOTSUP"&&code!=="EOPNOTSUPP"&&code!=="EPERM")throw error;let file=await open(path,"wx",options.mode);try{await file.writeFile(content,"utf8")}finally{await file.close()}}finally{await unlinkIfPresent(temp)}}async function publishReplace(path,content,options={}){let temp=await writeTemp(path,content,options.mode);try{await rename3(temp,path)}catch(error){throw await unlinkIfPresent(temp),error}}function pidAlive(pid){try{return process.kill(pid,0),!0}catch(error){return errorCode(error)==="EPERM"}}var UNREADABLE_LOCK_STALE_MS=3e4;function readLockHolder(raw){try{let parsed=JSON.parse(raw);if(typeof parsed!="object"||parsed===null||!("pid"in parsed)||!("bootAtMs"in parsed)||!("processStartedAtMs"in parsed))return;let{pid,bootAtMs,processStartedAtMs}=parsed;return typeof pid!="number"||typeof bootAtMs!="number"||typeof processStartedAtMs!="number"?void 0:{pid,bootAtMs,processStartedAtMs}}catch{return}}async function reclaimLockState(lock,probes={}){let raw=await readLeaseText(lock);if(raw===void 0)return{state:"free"};let holder=readLockHolder(raw);if(holder===void 0)return await stat3(lock).then(info=>Date.now()-info.mtimeMs,()=>0)>UNREADABLE_LOCK_STALE_MS?{state:"stale",raw}:{state:"held"};if(!sameBoot(holder.bootAtMs,processBootAtMs()))return{state:"stale",raw};if(holder.pid===process.pid)return sameProcessStartMs(holder.processStartedAtMs,ownProcessStartedAtMs())?{state:"held",holder}:{state:"stale",raw};if(!(probes.isProcessAlive??pidAlive)(holder.pid))return{state:"stale",raw};let observed=await(probes.readProcessStartMs??readProcessStartMs)(holder.pid).catch(()=>{});return observed===void 0?{state:"held",holder,unproven:!0}:sameProcessStartMs(holder.processStartedAtMs,observed)?{state:"held",holder}:{state:"stale",raw}}async function breakStaleLock(lock,raw){let aside=`${lock}.${process.pid}.${randomUUID3().slice(0,8)}.broken`;try{await rename3(lock,aside)}catch(error){if(errorCode(error)==="ENOENT")return;throw error}let moved=await readFile3(aside,"utf8");if(moved!==raw)try{await publishExclusive(lock,moved)}catch(error){if(errorCode(error)!=="EEXIST")throw error}await unlinkIfPresent(aside)}async function takeReclaimLock(lock,probes){let mine=JSON.stringify({pid:process.pid,bootAtMs:processBootAtMs(),processStartedAtMs:ownProcessStartedAtMs()});for(let attempt=0;attempt<3;attempt+=1){try{return await publishExclusive(lock,mine),mine}catch(error){if(errorCode(error)!=="EEXIST")throw error}let seen=await reclaimLockState(lock,probes);if(seen.state==="held")return{holder:seen.holder};seen.state==="stale"&&await breakStaleLock(lock,seen.raw)}return{}}async function reclaimInspected(path,inspected,probes={}){let lock=`${path}.lock`,taken=await takeReclaimLock(lock,probes);if(typeof taken!="string")return{outcome:"busy",...taken.holder?{holder:taken.holder}:{}};try{return await readLeaseText(path)!==inspected?{outcome:"changed"}:(await unlinkIfPresent(path),{outcome:"removed"})}finally{await readLeaseText(lock)===taken&&await unlinkIfPresent(lock)}}var RUNNER_HEARTBEAT_STALE_MS=12e4,RUNNER_HEARTBEAT_INTERVAL_MS=3e4,DEFAULT_MAX_DELIVERY_MS=9e5,PRIVATE={mode:384};function ownRunnerIdentity(){return{pid:process.pid,processStartedAtMs:ownProcessStartedAtMs()}}function leasePath(dir,pid){return join3(runnersDir(dir),`${pid}.json`)}async function writeRunnerLease(dir,lease,now){await mkdir2(runnersDir(dir),{recursive:!0,mode:448});let identity=ownRunnerIdentity();await publishReplace(leasePath(dir,identity.pid),JSON.stringify({...identity,bootAtMs:processBootAtMs(),beatAt:now,...lease}),PRIVATE)}async function removeRunnerLease(dir){await unlinkIfPresent(leasePath(dir,process.pid))}function parseLease(raw){try{let parsed=JSON.parse(raw);if(typeof parsed!="object"||parsed===null)return;let beatAt="beatAt"in parsed?parsed.beatAt:void 0;if(typeof beatAt!="number")return;let watch="watch"in parsed&&parsed.watch===!0,exec="exec"in parsed&&typeof parsed.exec=="string"?parsed.exec:null;return{beatAt,watch,exec}}catch{return}}async function liveRunners(dir){let names;try{names=await readdir3(runnersDir(dir))}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ENOENT")return[];throw error}let runners=[];for(let name of names){if(!/^\d+\.json$/.test(name))continue;let path=join3(runnersDir(dir),name),state=await reclaimLockState(path);if(state.state==="stale"&&await breakStaleLock(path,state.raw),state.state!=="held"||state.holder===void 0)continue;let raw=await readLeaseText(path),lease=raw===void 0?void 0:parseLease(raw);lease!==void 0&&runners.push({pid:state.holder.pid,processStartedAtMs:state.holder.processStartedAtMs,...lease})}return runners}async function isWatchRunnerAvailable(dir,now){return(await liveRunners(dir)).some(runner=>runner.watch&&now-runner.beatAt<=RUNNER_HEARTBEAT_STALE_MS)}function isOwnerAmong(owner,runners){return runners.some(runner=>runner.pid===owner.pid&&sameProcessStartMs(runner.processStartedAtMs,owner.processStartedAtMs))}function sessionLockPath(dir,sessionId){return join3(dir,"sessions",`${encodeURIComponent(sessionId)}.lock`)}function isDeliveryGroupAlive(pid){try{return process.kill(process.platform==="win32"?pid:-pid,0),!0}catch(error){return errorCode(error)==="EPERM"}}function isPidAlive(pid){try{return process.kill(pid,0),!0}catch(error){return errorCode(error)==="EPERM"}}async function orphanedDelivery(raw,lockAgeMs,probes){let parsed;try{parsed=JSON.parse(raw)}catch{return}if(typeof parsed!="object"||parsed===null)return;let field=key=>key in parsed?Reflect.get(parsed,key):void 0,boot=field("bootAtMs");if(typeof boot!="number"||!sameBoot(boot,processBootAtMs()))return;let pid=field("deliveryPid"),startedAt=field("deliveryStartedAtMs");if(typeof pid!="number"||typeof startedAt!="number"){let maxDeliveryMs=field("maxDeliveryMs"),runner=field("pid");return field("gated")===!1&&typeof maxDeliveryMs=="number"&&lockAgeMs<=maxDeliveryMs&&typeof runner=="number"?runner:void 0}if(!isDeliveryGroupAlive(pid))return;if(!isPidAlive(pid))return pid;let leaderStart=await(probes.readProcessStartMs??readProcessStartMs)(pid).catch(()=>{});return leaderStart!==void 0&&sameProcessStartMs(startedAt,leaderStart)?pid:void 0}async function acquireSessionDeliveryLock(dir,sessionId,options={}){let probes=options,path=sessionLockPath(dir,sessionId),identity={pid:process.pid,bootAtMs:processBootAtMs(),processStartedAtMs:ownProcessStartedAtMs(),gated:options.gated??process.platform!=="win32",maxDeliveryMs:options.maxDeliveryMs??DEFAULT_MAX_DELIVERY_MS},mine=JSON.stringify(identity);for(let attempt=0;attempt<3;attempt+=1){try{await publishExclusive(path,mine,PRIVATE);let tail=Promise.resolve(),serialized=operation=>{let run=tail.then(operation);return tail=run.catch(()=>{}),run};return{acquired:!0,attachDelivery:pid=>serialized(async()=>{let startedAt=Math.floor(Date.now()/1e3)*1e3;if(await readLeaseText(path)!==mine)throw new Error("session delivery lock was lost");let next=JSON.stringify({...identity,deliveryPid:pid,deliveryStartedAtMs:startedAt});await publishReplace(path,next,PRIVATE),mine=next}),release:()=>serialized(async()=>{await readLeaseText(path)===mine&&await unlinkIfPresent(path)})}}catch(error){let code=errorCode(error);if(code==="ENOENT"){await mkdir2(join3(dir,"sessions"),{recursive:!0,mode:448});continue}if(code!=="EEXIST")throw error}let state=await reclaimLockState(path);if(state.state==="held")return{acquired:!1,heldByPid:state.holder?.pid};if(state.state==="stale"){let lockAgeMs=await stat4(path).then(info=>Date.now()-info.mtimeMs,()=>0),delivering=await orphanedDelivery(state.raw,lockAgeMs,probes);if(delivering!==void 0)return{acquired:!1,heldByPid:delivering};await breakStaleLock(path,state.raw)}}return{acquired:!1,heldByPid:void 0}}import{randomUUID as randomUUID4}from"node:crypto";import{mkdir as mkdir3,readFile as readFile4,rename as rename4,rm as rm3,writeFile as writeFile3}from"node:fs/promises";import{dirname as dirname2,join as join4}from"node:path";var InvalidSidecarStoreError=class extends Error{constructor(message,options){super(message,options),this.name="InvalidSidecarStoreError"}},UnsupportedSidecarStoreVersionError=class extends Error{constructor(message){super(message),this.name="UnsupportedSidecarStoreVersionError"}},mutationTails=new Map,snapshots=new Map;function encodedSessionId(sessionId){return encodeURIComponent(sessionId)}function sidecarFilePath(ref){return join4(ref.baseDir,`${encodedSessionId(ref.sessionId)}.json`)}function createSidecarStore(options){let ref={baseDir:options.baseDir,sessionId:options.sessionId},filePath=sidecarFilePath(ref);async function read(){let raw;try{raw=await readFile4(filePath,"utf8")}catch(error){if(isFileSystemError2(error,"ENOENT"))return null;throw error}let state=parsePayload(raw,options,ref);return snapshots.set(filePath,state),state}async function write(state){await mkdir3(dirname2(filePath),{recursive:!0}),await writeAtomic2(filePath,`${JSON.stringify(state,null,2)}
|