@code-yeongyu/senpi 2026.10.8 → 2026.10.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/bundle/chunks/{app-server-command-MJOYE5ZS.js → app-server-command-SZWKEC36.js} +1 -1
- package/dist/bundle/chunks/{chunk-MJGHZT4N.js → chunk-3A3C5VVO.js} +1 -1
- package/dist/bundle/chunks/{chunk-4GUQVY4Z.js → chunk-3YXB7Z7O.js} +1 -1
- package/dist/bundle/chunks/{chunk-6EH7QXOG.js → chunk-6VVV27W2.js} +1 -1
- package/dist/bundle/chunks/{chunk-CB77NQMN.js → chunk-7GVD54RM.js} +1 -1
- package/dist/bundle/chunks/{chunk-CM5QTRC2.js → chunk-H67EVDWG.js} +1 -1
- package/dist/bundle/chunks/chunk-IZOTKUWG.js +2 -0
- package/dist/bundle/chunks/{chunk-K4AZKFRB.js → chunk-J5MUMVWB.js} +2 -2
- package/dist/bundle/chunks/{chunk-V2VQ4BHG.js → chunk-M2IHGL3M.js} +1 -1
- package/dist/bundle/chunks/chunk-N3QEG537.js +14 -0
- package/dist/bundle/chunks/{chunk-LUWWM7GA.js → chunk-RADHRQ4K.js} +3 -3
- package/dist/bundle/chunks/{chunk-BTYFICUC.js → chunk-SB22X6ZR.js} +1 -1
- package/dist/bundle/chunks/{chunk-5MG76BCM.js → chunk-WQ77WBQW.js} +60 -60
- package/dist/bundle/chunks/{cli-main-GWVLFOIP.js → cli-main-C3AS73Q4.js} +1 -1
- package/dist/bundle/chunks/{host-command-HTYYQBSG.js → host-command-X64D7PT3.js} +1 -1
- package/dist/bundle/chunks/{host-lifecycle-XZF6IKKO.js → host-lifecycle-GC3GIR2N.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-YLM2U7IX.js → interactive-mode-KUP43WXL.js} +1 -1
- package/dist/bundle/chunks/{list-tips-JQDZPB6C.js → list-tips-IIRFXBTO.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-KMCBBPTV.js → multi-session-host-EM24ZBGK.js} +1 -1
- package/dist/bundle/chunks/{package-manager-cli-3UIJ4RXY.js → package-manager-cli-MGFHGI5O.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-PUYBZG27.js → rpc-mode-2GT75YBZ.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-CVAPK2WQ.js → schedule-command-EQ4PQCRP.js} +1 -1
- package/dist/bundle/chunks/{session-control-endpoint-THEF3K7M.js → session-control-endpoint-DOIW7IBF.js} +2 -2
- package/dist/bundle/chunks/{session-picker-N463VCDI.js → session-picker-R5N2EKUS.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +73 -73
- package/dist/bundle/cli.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-runtime.d.ts +9 -0
- package/dist/core/agent-session-runtime.js +22 -0
- package/dist/core/agent-session.d.ts +12 -1
- package/dist/core/agent-session.js +36 -4
- package/dist/core/dynamic-prompt/handoff.js +3 -3
- package/dist/core/dynamic-prompt/intent-gate.js +1 -1
- package/dist/core/dynamic-prompt/style.js +1 -1
- package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts +5 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.js +1 -0
- package/dist/core/extensions/builtin/compaction/index.js +1 -0
- package/dist/core/extensions/builtin/compaction/lane-policy.d.ts +7 -0
- package/dist/core/extensions/builtin/compaction/lane-policy.js +28 -15
- package/dist/core/extensions/builtin/permission-system/index.js +4 -0
- package/dist/core/extensions/builtin/permission-system/prompt.js +10 -2
- package/dist/core/extensions/builtin/permission-system/types.d.ts +3 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +2 -2
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +2 -2
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5-5.js +2 -2
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js +2 -2
- package/dist/core/extensions/builtin/prompt-preset/claude-sonnet-5-5.js +2 -2
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js +3 -3
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +3 -3
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +2 -2
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +4 -4
- package/dist/core/extensions/builtin/prompt-preset/gpt-surface.js +2 -2
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.js +2 -2
- package/dist/core/extensions/builtin/prompt-preset/grok-4.6.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.7.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +2 -2
- package/dist/core/extensions/builtin/rules/rules/finder.js +8 -3
- package/dist/core/extensions/types.d.ts +4 -0
- package/dist/core/sdk.js +7 -3
- package/dist/core/thinking-levels.d.ts +23 -1
- package/dist/core/thinking-levels.js +37 -0
- package/dist/main.js +12 -13
- package/dist/modes/interactive/interactive-mode.js +8 -0
- package/dist/modes/interactive/session-control-endpoint.js +33 -8
- package/dist/modes/interactive/session-control-registry.js +3 -1
- package/dist/modes/interactive/session-control-wake.d.ts +11 -5
- package/dist/modes/interactive/session-control-wake.js +38 -16
- package/dist/modes/rpc/connection-handler.d.ts +5 -0
- package/dist/modes/rpc/connection-handler.js +40 -4
- package/dist/modes/rpc/custom-capability.d.ts +6 -0
- package/dist/modes/rpc/custom-capability.js +6 -0
- package/dist/modes/rpc/host-daemon-paths.d.ts +5 -4
- package/dist/modes/rpc/host-daemon-paths.js +17 -9
- package/dist/modes/rpc/host-daemon-registration.d.ts +6 -1
- package/dist/modes/rpc/host-daemon-registration.js +6 -2
- package/dist/modes/rpc/host-session-control.js +6 -4
- package/dist/modes/rpc/rpc-client.d.ts +5 -0
- package/dist/modes/rpc/rpc-client.js +7 -0
- package/dist/modes/rpc/rpc-mode.js +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +14 -0
- package/docs/json.md +3 -0
- package/docs/rpc.md +48 -0
- package/package.json +6 -6
- package/dist/bundle/chunks/chunk-VJJ53ORU.js +0 -2
- package/dist/bundle/chunks/chunk-X6UDRO7J.js +0 -14
|
@@ -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{CUSTOM_UNSUPPORTED_CAPABILITY,EXTENSION_EVENTS_CAPABILITY,RPC_CLIENT_CAPABILITIES_ENV,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,hostLaunchProfile,socketHostLaunchProfile}from"./chunk-VJJ53ORU.js";import{BUILTIN_PATH_PREFIX}from"./chunk-QMRJYMNH.js";import{acquireHostEnsureLock,acquireOwnershipSafeLock,anyGenerationLive,endpointKindOfSocket,gcEndpoint,gcHostEndpoints,hostEnsureLockOptions,hostEnsureLockTarget,listHostEndpoints,socketNeedsHandshake}from"./chunk-CM5QTRC2.js";import{compareEngineOrdinal,engineBuildIdentity}from"./chunk-ZJHRDQCH.js";import{external_exports}from"./chunk-KUPQO7MC.js";import{DEFAULT_HOST_IDLE_EXIT_MS,INTERNAL_SUPERVISOR_FLAG,OBSERVE_REQUEST_FIELD,readHostCrashRecords,resolveCliMainPath,rpcHostExecArgv}from"./chunk-MJGHZT4N.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV}from"./chunk-CIRZTP7W.js";import{HOST_DAEMON_DIR_ENV,HOST_STATE_FILE_MODE,MAX_SOCKET_PATH_BYTES,ProcessIdentityUnreadableError,claimOwnerIsLive,clearHostRegistration,createDaemonDirectories,createHostDaemonPaths,createSocketSecret,ensureEndpointIdentity,generationBindPath,generationPaths,hostDaemonDirectoryPaths,parseDaemonPidFile,parseJson,parseShardSocket,processIsLive,processMatchesPidFile,provenOwner,pruneDeadGenerations,readFileOrUndefined,readGenerationRows,readHostProcessMetrics,readHostRegistration,readHostSettings,readProcessStartTime,readSessionPathClaims,readSocketSecret,releaseGeneration,resolveSocketTransportAddress,sameEndpoint,sendSocketHandshake,sessionDirectoryRemoved,shardKey,shardSocketPathForKey,socketSecretPath,statSocketIdentity,waitForStartTime,writeGenerationRecord,writeHostRegistration,writeHostSettings,writeStateFile,writtenByThisProcess}from"./chunk-LUWWM7GA.js";import{isSessionRuntimeKind}from"./chunk-MH2BFYGN.js";import{APP_NAME,ENV_AGENT_DIR,envValue,getAgentDir,isBunBinary}from"./chunk-463OK2Y4.js";import{writeSync}from"node:fs";import{join as join7,resolve as resolve3}from"node:path";import{readFile,realpath,stat}from"node:fs/promises";import{dirname,isAbsolute,relative,resolve}from"node:path";var SPEC_ENV_NAME=/^(SENPI|OMO|PI)_[A-Z0-9_]+$/u,HostLaunchSpecError=class extends Error{constructor(reason,detail){super(`${reason}: ${detail}`),this.name="HostLaunchSpecError",this.reason=reason,this.detail=detail}},DEFAULT_HOST_LAUNCH_SPEC={hostArgs:[],policy:{},env:{}};async function loadHostLaunchSpec(specPath,platform=process.platform){let absolute=resolve(specPath);await assertTrustedFile(absolute,platform);let spec=parseHostLaunchSpec(await readSpecText(absolute)),env=trustedEnv(spec.env),extensions=await resolveExtensions(spec.core.extensions,dirname(absolute));return{hostArgs:["--session-runtime",spec.core.session_runtime,...extensions.flatMap(path=>["--extension",path])],policy:{...spec.tunables?.idleExitMs!==void 0&&{idleExitMs:spec.tunables.idleExitMs},...spec.tunables?.coldStart!==void 0&&{coldStart:spec.tunables.coldStart}},env}}function parseHostLaunchSpec(text){let parsed;try{parsed=JSON.parse(text)}catch(error){throw new HostLaunchSpecError("launch_spec_invalid",error instanceof Error?error.message:"not JSON")}if(!isRecord(parsed))throw new HostLaunchSpecError("launch_spec_invalid","the spec is not a JSON object");if(parsed.spec_version!==1)throw new HostLaunchSpecError("launch_spec_invalid",`unsupported spec_version ${String(parsed.spec_version)}`);let core=parsed.core;if(!isRecord(core))throw new HostLaunchSpecError("launch_spec_invalid","core must be an object");if(typeof core.session_runtime!="string"||!isSessionRuntimeKind(core.session_runtime))throw new HostLaunchSpecError("launch_spec_invalid","core.session_runtime must be in-process or worker");if(core.multi_session!==!0)throw new HostLaunchSpecError("launch_spec_invalid","core.multi_session must be true");if(!Array.isArray(core.extensions)||!core.extensions.every(entry=>typeof entry=="string"))throw new HostLaunchSpecError("launch_spec_invalid","core.extensions must be an array of strings");let tunables=parsedTunables(parsed.tunables);return{spec_version:1,core:{session_runtime:core.session_runtime,multi_session:!0,extensions:core.extensions},...tunables&&{tunables},...isRecord(parsed.env)&&{env:parsedEnv(parsed.env)}}}async function readSpecText(absolute){try{return await readFile(absolute,"utf8")}catch(error){throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}}async function assertTrustedFile(absolute,platform){if(platform==="win32")return;let stats=await stat(absolute).catch(error=>{throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}),uid=process.getuid?.();if(uid!==void 0&&stats.uid!==uid)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is owned by uid ${stats.uid}, not ${uid}`);if((stats.mode&18)!==0)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is group/world writable (mode ${(stats.mode&511).toString(8)})`)}function trustedEnv(env){for(let name of Object.keys(env??{}))if(!SPEC_ENV_NAME.test(name))throw new HostLaunchSpecError("launch_spec_env_denied",`${name} is outside ${SPEC_ENV_NAME.source}`);return env??{}}async function resolveExtensions(extensions,specDir){let rootReal=await realpath(specDir).catch(()=>specDir),resolved=[];for(let entry of extensions){let target=resolve(specDir,entry);if(escapes(specDir,target))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} resolves outside ${specDir}`);let real=await realpath(target).catch(()=>{});if(real===void 0)throw new HostLaunchSpecError("launch_spec_missing_extension",`${target} does not exist`);if(escapes(rootReal,real))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} links outside ${specDir}`);resolved.push(real)}return resolved}function escapes(root,target){let step=relative(root,target);return step.startsWith("..")||isAbsolute(step)}function parsedTunables(value){if(!isRecord(value))return;let idleExitMs=value.idleExitMs,coldStart=value.coldStart;return{...typeof idleExitMs=="number"&&Number.isFinite(idleExitMs)&&idleExitMs>0&&{idleExitMs},...(coldStart==="transient"||coldStart==="persistent")&&{coldStart}}}function parsedEnv(value){let env={};for(let[name,entry]of Object.entries(value)){if(typeof entry!="string")throw new HostLaunchSpecError("launch_spec_invalid",`env.${name} must be a string`);env[name]=entry}return env}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{join}from"node:path";var ALLOWED_ENV_NAMES=[/^(PATH|HOME|USER|LOGNAME|SHELL|TMPDIR|TERM|LANG)$/u,/^(LC|XDG)_/u,/^(SENPI|OMO|PI)_/u,/^BSK_(HOME|BIN)$/u,/^(HTTPS?_PROXY|NO_PROXY)$/u,/^[A-Z0-9_]+_API_KEY$/u,/^(ANTHROPIC|OPENAI|GOOGLE|GEMINI|AZURE|AWS|OPENROUTER|XAI|MISTRAL|DEEPSEEK|GROQ|CEREBRAS|MINIMAX)_/u],WINDOWS_SYSTEM_ENV_NAMES=new Set(["SYSTEMROOT","SYSTEMDRIVE","WINDIR","COMSPEC","PATHEXT","TEMP","TMP","USERPROFILE","APPDATA","LOCALAPPDATA","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","HOMEDRIVE","HOMEPATH","NUMBER_OF_PROCESSORS","PROCESSOR_ARCHITECTURE","OS"]),TRANSIENT_ENV_NAMES=new Set(["PI_SESSION_ID","PI_SESSION_FILE","PI_SESSION_CWD","PI_GOAL_STORE_FILE","PI_PROVIDER","PI_MODEL","PI_REASONING_LEVEL","OMO_BROWSER_ENGINE","PI_PROMPT_CACHE_SAFE_WAIT_SECONDS","SENPI_PY_KERNEL_PARENT_PID","SENPI_RPC_HOST_WATCH_FD","SENPI_RPC_HOST_WATCH_PPID","SENPI_RPC_HOST_SCRATCH_DIR","SENPI_RPC_HOST_CLEANUP_PATHS","SENPI_RPC_HOST_PUBLIC_SOCKET","SENPI_RPC_HOST_INSTANCE_ID","SENPI_RPC_HOST_GENERATION","SENPI_RPC_HOST_DAEMON_DIR","SENPI_RPC_HOST_EXPECTED_RUNTIME_BUILD_ID"]);function daemonEnvIsAllowed(name,platform=process.platform){let upper=name.toUpperCase();return TRANSIENT_ENV_NAMES.has(platform==="win32"?upper:name)?!1:platform!=="win32"?ALLOWED_ENV_NAMES.some(pattern=>pattern.test(name)):WINDOWS_SYSTEM_ENV_NAMES.has(upper)||ALLOWED_ENV_NAMES.some(pattern=>pattern.test(upper))}function daemonEnvOverrides(processEnv,specEnv={},platform=process.platform){let overrides={};for(let name of Object.keys(processEnv))daemonEnvIsAllowed(name,platform)||(overrides[name]=null);for(let[name,value]of Object.entries(specEnv))daemonEnvIsAllowed(name,platform)&&(overrides[name]=value);return overrides}function daemonEnvironment(processEnv,overrides={},forced={},platform=process.platform){let env={};for(let[name,value]of Object.entries(processEnv))value!==void 0&&daemonEnvIsAllowed(name,platform)&&(env[name]=value);for(let[name,value]of Object.entries(overrides))daemonEnvIsAllowed(name,platform)&&(deleteEnvironmentName(env,name,platform),value!==null&&(env[name]=value));for(let[name,value]of Object.entries(forced))deleteEnvironmentName(env,name,platform),env[name]=value;return env}function daemonEnvKeys(processEnv,specEnv={},platform=process.platform){let kept=Object.keys(processEnv).filter(name=>daemonEnvIsAllowed(name,platform)),explicit=Object.keys(specEnv).filter(name=>daemonEnvIsAllowed(name,platform));return[...new Set([...kept,...explicit])].sort()}async function writeDaemonEnvKeys(paths,keys){await writeStateFile(daemonEnvKeysFile(paths),{env_keys:keys})}async function readDaemonEnvKeys(paths){let keys=parseJson(await readFileOrUndefined(daemonEnvKeysFile(paths)))?.env_keys;return Array.isArray(keys)?keys.filter(key=>typeof key=="string"):[]}function daemonEnvKeysFile(paths){return join(paths.dir,"env-keys.json")}function deleteEnvironmentName(env,name,platform){if(platform!=="win32"){delete env[name];return}let upper=name.toUpperCase();for(let existing of Object.keys(env))existing.toUpperCase()===upper&&delete env[existing]}import{createHash}from"node:crypto";import{existsSync}from"node:fs";import{readdir,readFile as readFile2,realpath as realpath2,stat as stat2}from"node:fs/promises";import{basename,dirname as dirname2,join as join2,relative as relative2,sep}from"node:path";import{fileURLToPath}from"node:url";var RUNTIME_IDENTITY_HANDOVER_CAPABILITY="runtime_identity_handover",RUNTIME_BUILD_ID=/^sha256:[0-9a-f]{64}$/,EXCLUDED_FILE=/\.(?:d\.[cm]?ts|map)$/,EXCLUDED_NAMES=new Set(["node_modules","runtime-manifest.json","runtime-snapshot.json"]),READ_CONCURRENCY=32;function parseRuntimeBuildId(value){return typeof value=="string"&&RUNTIME_BUILD_ID.test(value)?value:void 0}async function computeRuntimeBuildId(input){let source=input.source??loadedRuntimeSource(),plugins=await Promise.all(input.profile.extensions.map(path=>extensionDigest(path))),manifest={schema:1,flavour:source.flavour,platform:input.platform??process.platform,arch:input.arch??process.arch,engine:input.engine??engineBuildIdentity().text,runtime:await treeDigest(source.root),plugins:plugins.sort(),profile:{multi_session:input.profile.multi_session,session_runtime:input.profile.session_runtime}};return`sha256:${sha256(JSON.stringify(manifest))}`}function loadedRuntimeSource(){if(isBunBinary)return{flavour:"compiled",root:process.execPath};let moduleDir=dirname2(fileURLToPath(import.meta.url)),packageRoot=nearestPackageRoot(moduleDir),[top,next]=relative2(packageRoot,moduleDir).split(sep);return top==="dist"?{flavour:"packaged",root:join2(packageRoot,next==="bundle"?join2("dist","bundle"):"dist")}:{flavour:"dev",root:join2(packageRoot,top??"")}}function nearestPackageRoot(start){for(let dir=start;;dir=dirname2(dir)){if(existsSync(join2(dir,"package.json")))return dir;if(dirname2(dir)===dir)return start}}function extensionDigest(path){let name=basename(path);return name.startsWith(BUILTIN_PATH_PREFIX)?Promise.resolve(sha256(name)):treeDigest(path)}async function treeDigest(root){let files=[];(await stat2(root)).isFile()?files.push(["",root]):await collect(await realpath2(root),"",files,new Set);let digests=await mapLimited(files,READ_CONCURRENCY,async([path,file])=>[path,sha256(await readFile2(file))]);return digests.sort(([a],[b])=>a<b?-1:a>b?1:0),sha256(JSON.stringify(digests))}async function collect(dir,prefix,files,seen){if(seen.has(dir))return;seen.add(dir);let entries=(await readdir(dir,{withFileTypes:!0})).sort((a,b)=>a.name<b.name?-1:a.name>b.name?1:0);for(let entry of entries){if(entry.name.startsWith(".")||EXCLUDED_NAMES.has(entry.name))continue;let path=join2(dir,entry.name),name=prefix===""?entry.name:`${prefix}/${entry.name}`,kind=entry.isSymbolicLink()?await stat2(path).catch(()=>{}):entry;kind!==void 0&&(kind.isDirectory()?await collect(await realpath2(path),name,files,seen):kind.isFile()&&!EXCLUDED_FILE.test(entry.name)&&files.push([name,path]))}}async function mapLimited(items,limit,map){let results=new Array(items.length),next=0,worker=async()=>{for(let index=next++;index<items.length;index=next++)results[index]=await map(items[index])};return await Promise.all(Array.from({length:Math.min(limit,items.length)},worker)),results}function sha256(data){return createHash("sha256").update(data).digest("hex")}function parseHostProtocolInfo(data){if(!isRecord2(data)||typeof data.serverVersion!="string"||!Array.isArray(data.capabilities)||!data.capabilities.every(entry=>typeof entry=="string"))return;let ordinal=parseOrdinal(data.engineOrdinal),launchProfile=parseLaunchProfile(data.launch_profile),runtimeBuildId=parseRuntimeBuildId(data.runtimeBuildId);return{protocolVersion:typeof data.protocolVersion=="number"?data.protocolVersion:0,serverVersion:data.serverVersion,capabilities:data.capabilities,...typeof data.instanceId=="string"&&{instanceId:data.instanceId},...typeof data.generation=="number"&&Number.isSafeInteger(data.generation)&&{generation:data.generation},...typeof data.engineVersion=="string"&&{engineVersion:data.engineVersion},...ordinal&&{engineOrdinal:ordinal},...launchProfile&&{launch_profile:launchProfile},...typeof data.memory_pressure=="boolean"&&{memory_pressure:data.memory_pressure},...runtimeBuildId!==void 0&&{runtimeBuildId},...isRecord2(data.handover)&&{handover:data.handover}}}function parseOrdinal(value){if(!(!Array.isArray(value)||value.length!==5||!value.every(part=>typeof part=="number")))return[value[0],value[1],value[2],value[3],value[4]]}function parseLaunchProfile(value){if(!isRecord2(value)||typeof value.profile_id!="string"||!isRecord2(value.core))return;let{extensions,multi_session,session_runtime}=value.core;if(!(!Array.isArray(extensions)||!extensions.every(entry=>typeof entry=="string"))&&typeof multi_session=="boolean"&&!(session_runtime!=="in-process"&&session_runtime!=="worker"))return{profile_id:value.profile_id,core:{extensions,multi_session,session_runtime}}}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var HOST_PROTOCOL_VERSION=1,GENERATION_HANDOFF_CAPABILITY="generation_handoff",REQUIRED_HOST_CAPABILITIES=["multi_session",EXTENSION_EVENTS_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY],HostEnsureRefusedError=class extends Error{constructor(socket,reason,host,detail){super(`RPC socket ${socket} refused: ${reason} - ${refusalDetail(reason,host)}${detail?`: ${detail}`:""}`),this.name="HostEnsureRefusedError",this.socket=socket,this.reason=reason,this.detail=detail}};function refusalDetail(reason,host){switch(reason){case"protocol":return`the running host speaks protocol version ${host?.protocolVersion??"unknown"}, this build speaks ${HOST_PROTOCOL_VERSION}`;case"capability":{let missing=REQUIRED_HOST_CAPABILITIES.filter(capability=>!host?.capabilities.includes(capability));return`the running host is missing ${JSON.stringify(missing)}; it owns the socket, so no second host is started`}case"foreign_writer":return"its pidfile was written by another process, so this one may not signal it; stop that host explicitly instead";case"legacy_host":return"a host from before the per-socket daemon directory is still running; it is drained and replaced only while it holds no session, and no second host is started beside it";case"host_busy":return"its socket accepts connections but did not answer inside the probe budget: a live host under load, which is never ended to make room for a replacement";default:return assertNever(reason)}}function decideHostAction(client,host,policy){if(host===void 0)return{action:"start",reason:client.startedByUs?"restart_own_host":"no_host",upgradeable:!1};if(host.protocolVersion!==client.protocolVersion)return{action:"refuse",reason:"protocol",upgradeable:!1};if(!client.requiredCapabilities.every(capability=>host.capabilities.includes(capability)))return policy==="fallback"?{action:"fallback",reason:"capability",upgradeable:!1}:{action:"refuse",reason:"capability",upgradeable:!1};let upgradeable=client.platform!=="win32"&&host.capabilities.includes(GENERATION_HANDOFF_CAPABILITY);if(policy==="fallback"&&host.engineVersion!==client.identity.text)return{action:"fallback",reason:"engine_mismatch",upgradeable};let warning=profileWarning(client,host);return client.platform==="win32"?{action:"reuse",reason:"win32_attach_only",upgradeable:!1,...warning&&{warning}}:upgradeable?policy==="upgrade"&&client.launchProfile&&host.launch_profile&&supersedes(client,host)?{action:"handoff",reason:sameRelease(client.identity.ordinal,host.engineOrdinal)?"profile":"newer_engine",upgradeable:!0}:{action:"reuse",reason:"compatible",upgradeable,...warning&&{warning}}:{action:"reuse",reason:"handoff_unsupported",upgradeable:!1,...warning&&{warning}}}function supersedes(client,host){if(host.engineOrdinal===void 0)return!1;let hostIdentity={text:host.engineVersion??"",ordinal:host.engineOrdinal,scheme:host.engineOrdinal[4]>0?"epoch":"nodef"};return compareEngineOrdinal(client.identity,hostIdentity)<=0?!1:covers(client.launchProfile,host.launch_profile)}function profileWarning(client,host){if(client.launchProfile===void 0||host.launch_profile===void 0)return"profile_mismatch_attached";if(client.launchProfile.profile_id===host.launch_profile.profile_id)return;let clientCoversHost=covers(client.launchProfile,host.launch_profile);if(!(clientCoversHost&&covers(host.launch_profile,client.launchProfile)))return clientCoversHost?"profile_mismatch_attached":"profile_narrower_attached"}function extensionRole(extension){let segments=extension.split(/[\\/]+/),pluginAt=segments.lastIndexOf("plugin");return pluginAt<0?extension:segments.slice(pluginAt).join("/")}function covers(candidate,running){if(candidate===void 0||running===void 0)return!1;let candidateRoles=new Set(candidate.core.extensions.map(extensionRole));return running.core.extensions.every(extension=>candidateRoles.has(extensionRole(extension)))}function sameRelease(candidate,running){return running!==void 0&&candidate.slice(0,4).every((part,index)=>part===running[index])}function assertNever(value){throw new Error(`unreachable host decision: ${JSON.stringify(value)}`)}import{mkdir,writeFile as writeFile3}from"node:fs/promises";import{dirname as dirname5}from"node:path";function ensureClient(options,startedByUs){return{protocolVersion:HOST_PROTOCOL_VERSION,requiredCapabilities:REQUIRED_HOST_CAPABILITIES,identity:engineBuildIdentity(),...options.upgrade==="if-engine-differs"?{launchProfile:hostLaunchProfile(hostChildArgv(options.hostArgs??[]),process.cwd())}:{},startedByUs,platform:process.platform}}function hostChildArgv(hostArgs){return["--mode","rpc","--multi-session",...hostArgs]}function isCompatible(protocol){return decideHostAction(ensureClient({socket:""},!1),protocol,"never").action==="reuse"}import{spawn}from"node:child_process";import{randomUUID}from"node:crypto";import{open,readFile as readFile3}from"node:fs/promises";var SIGKILL_GRACE_MS=2e3;async function matchesPidFileOrUnknown(pidFile,probe){try{return await processMatchesPidFile(pidFile,probe)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!1;throw error}}async function stopSpawnedChild(child,childExit,termTimeoutMs){let exited=()=>child.exitCode!==null||child.signalCode!==null;if(exited())return;let signal=name=>{try{child.kill(name)}catch(error){if(!isNodeErrorCode(error,"ESRCH"))throw error}},waitFor=ms=>Promise.race([childExit.then(()=>!0),delay(ms).then(()=>exited())]);if(signal("SIGTERM"),!await waitFor(termTimeoutMs)&&(signal("SIGKILL"),!await waitFor(SIGKILL_GRACE_MS)))throw new Error(`RPC socket host pid ${child.pid??"?"} remained alive after SIGKILL`)}async function stopManagedHost(pidFile,termTimeoutMs,readStartTime=readProcessStartTime){if(await signalValidated(pidFile,"SIGTERM",readStartTime),!await waitForGone(pidFile,termTimeoutMs,readStartTime)&&(await signalValidated(pidFile,"SIGKILL",readStartTime),!await waitForGone(pidFile,SIGKILL_GRACE_MS,readStartTime)))throw new Error(`RPC socket host pid ${pidFile.pid} remained alive after SIGKILL`)}async function resolvePidFileOwnership(pidFile,readStartTime){try{return await processMatchesPidFile(pidFile,readStartTime,processIsLive,{attempts:1})?"owns":"gone"}catch(error){if(error instanceof ProcessIdentityUnreadableError)return"unknown";throw error}}async function signalValidated(pidFile,signal,readStartTime=readProcessStartTime){if(await resolvePidFileOwnership(pidFile,readStartTime)==="owns")try{process.kill(pidFile.pid,signal)}catch(error){if(!isNodeErrorCode(error,"ESRCH"))throw error}}async function waitForGone(pidFile,timeoutMs,readStartTime=readProcessStartTime){let deadline=Date.now()+timeoutMs;for(;Date.now()<=deadline;){if(await resolvePidFileOwnership(pidFile,readStartTime)==="gone")return!0;await delay(50)}return await resolvePidFileOwnership(pidFile,readStartTime)==="gone"}function delay(ms){return new Promise(resolveDelay=>setTimeout(resolveDelay,ms))}function isNodeErrorCode(error,code){return error instanceof Error&&"code"in error&&error.code===code}import{existsSync as existsSync2}from"node:fs";import{basename as basename2,dirname as dirname3,resolve as resolve2}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";var PINNED_HOST_CLIENT_CAPABILITIES=[EXTENSION_EVENTS_CAPABILITY,CUSTOM_UNSUPPORTED_CAPABILITY];function defaultHostLaunch(supervisorArgs,compiled=isBunBinary,sibling=resolveHostLifecycleEntryPath()??null){return compiled?{command:process.execPath,args:[INTERNAL_SUPERVISOR_FLAG,...supervisorArgs]}:sibling!==null?{command:process.execPath,args:[...rpcHostExecArgv(),sibling,...supervisorArgs]}:{command:process.execPath,args:[...rpcHostExecArgv(),resolveCliMainPath(),INTERNAL_SUPERVISOR_FLAG,...supervisorArgs]}}function resolveHostLifecycleEntryPath(){let modulePath=fileURLToPath2(import.meta.url);if(basename2(dirname3(modulePath))==="chunks")return;let extension=modulePath.endsWith(".ts")?".ts":".js",sibling=resolve2(dirname3(modulePath),`host-lifecycle${extension}`);return existsSync2(sibling)?sibling:void 0}import{createConnection}from"node:net";function holdAttachment(socket){return socket.removeAllListeners("data"),socket.resume(),socket.on("error",()=>socket.destroy()),socket.unref(),{release:()=>socket.destroy()}}var DEFAULT_PROBE_TIMEOUT_MS=1e4,PROBE_REQUEST_ID="ensure-host-probe";function probeHost(options){return probeProtocolInfo(options.socket,options.timeoutMs??DEFAULT_PROBE_TIMEOUT_MS)}async function probeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info"},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function observeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function holdProtocolInfo(socketPath,timeoutMs){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs,!0),info=outcome.answer===void 0?void 0:parseHostProtocolInfo(outcome.answer);if(outcome.kept===void 0)return;let hold=holdAttachment(outcome.kept);if(info!==void 0)return{info,hold};hold.release()}async function probeSocketReachable(socketPath,timeoutMs){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs)).connected}async function probeSessionCount(socketPath,timeoutMs){return sessionCountOf(await requestOnSocket(socketPath,{type:"list_sessions",include_workers:!0},timeoutMs))}async function holdSessionCount(socketPath,timeoutMs){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"list_sessions",include_workers:!0},timeoutMs,!0),kept=outcome.kept;if(kept===void 0)return;let sessions=sessionCountOf(outcome.answer);if(sessions===void 0){kept.destroy();return}let asked=0;return{sessions,recount:recountTimeoutMs=>askAgain(kept,`${PROBE_REQUEST_ID}-recount-${++asked}`,recountTimeoutMs),close:()=>kept.destroy()}}function askAgain(socket,id,timeoutMs){return new Promise(resolveCount=>{let buffer="",finish=count=>{clearTimeout(timeout),socket.off("data",onData),socket.off("close",onClose),resolveCount(count)},onClose=()=>finish(void 0),onData=chunk=>{buffer+=chunk.toString("utf8");for(let newline=buffer.indexOf(`
|
|
2
|
+
import{CUSTOM_UNSUPPORTED_CAPABILITY,EXTENSION_EVENTS_CAPABILITY,RPC_CLIENT_CAPABILITIES_ENV,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,hostLaunchProfile,socketHostLaunchProfile}from"./chunk-IZOTKUWG.js";import{BUILTIN_PATH_PREFIX}from"./chunk-QMRJYMNH.js";import{acquireHostEnsureLock,acquireOwnershipSafeLock,anyGenerationLive,endpointKindOfSocket,gcEndpoint,gcHostEndpoints,hostEnsureLockOptions,hostEnsureLockTarget,listHostEndpoints,socketNeedsHandshake}from"./chunk-H67EVDWG.js";import{compareEngineOrdinal,engineBuildIdentity}from"./chunk-ZJHRDQCH.js";import{external_exports}from"./chunk-KUPQO7MC.js";import{DEFAULT_HOST_IDLE_EXIT_MS,INTERNAL_SUPERVISOR_FLAG,OBSERVE_REQUEST_FIELD,readHostCrashRecords,resolveCliMainPath,rpcHostExecArgv}from"./chunk-3A3C5VVO.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV}from"./chunk-CIRZTP7W.js";import{HOST_DAEMON_DIR_ENV,HOST_STATE_FILE_MODE,MAX_SOCKET_PATH_BYTES,ProcessIdentityUnreadableError,claimOwnerIsLive,clearHostRegistration,createDaemonDirectories,createHostDaemonPaths,createSocketSecret,ensureEndpointIdentity,generationBindPath,generationPaths,hostDaemonDirectoryPaths,parseDaemonPidFile,parseJson,parseShardSocket,processIsLive,processMatchesPidFile,provenOwner,pruneDeadGenerations,readFileOrUndefined,readGenerationRows,readHostProcessMetrics,readHostRegistration,readHostSettings,readProcessStartTime,readSessionPathClaims,readSocketSecret,releaseGeneration,resolveSocketTransportAddress,sameEndpoint,sendSocketHandshake,sessionDirectoryRemoved,shardKey,shardSocketPathForKey,socketSecretPath,statSocketIdentity,waitForStartTime,writeGenerationRecord,writeHostRegistration,writeHostSettings,writeStateFile,writtenByThisProcess}from"./chunk-RADHRQ4K.js";import{isSessionRuntimeKind}from"./chunk-MH2BFYGN.js";import{APP_NAME,ENV_AGENT_DIR,envValue,getAgentDir,isBunBinary}from"./chunk-463OK2Y4.js";import{writeSync}from"node:fs";import{join as join7,resolve as resolve3}from"node:path";import{readFile,realpath,stat}from"node:fs/promises";import{dirname,isAbsolute,relative,resolve}from"node:path";var SPEC_ENV_NAME=/^(SENPI|OMO|PI)_[A-Z0-9_]+$/u,HostLaunchSpecError=class extends Error{constructor(reason,detail){super(`${reason}: ${detail}`),this.name="HostLaunchSpecError",this.reason=reason,this.detail=detail}},DEFAULT_HOST_LAUNCH_SPEC={hostArgs:[],policy:{},env:{}};async function loadHostLaunchSpec(specPath,platform=process.platform){let absolute=resolve(specPath);await assertTrustedFile(absolute,platform);let spec=parseHostLaunchSpec(await readSpecText(absolute)),env=trustedEnv(spec.env),extensions=await resolveExtensions(spec.core.extensions,dirname(absolute));return{hostArgs:["--session-runtime",spec.core.session_runtime,...extensions.flatMap(path=>["--extension",path])],policy:{...spec.tunables?.idleExitMs!==void 0&&{idleExitMs:spec.tunables.idleExitMs},...spec.tunables?.coldStart!==void 0&&{coldStart:spec.tunables.coldStart}},env}}function parseHostLaunchSpec(text){let parsed;try{parsed=JSON.parse(text)}catch(error){throw new HostLaunchSpecError("launch_spec_invalid",error instanceof Error?error.message:"not JSON")}if(!isRecord(parsed))throw new HostLaunchSpecError("launch_spec_invalid","the spec is not a JSON object");if(parsed.spec_version!==1)throw new HostLaunchSpecError("launch_spec_invalid",`unsupported spec_version ${String(parsed.spec_version)}`);let core=parsed.core;if(!isRecord(core))throw new HostLaunchSpecError("launch_spec_invalid","core must be an object");if(typeof core.session_runtime!="string"||!isSessionRuntimeKind(core.session_runtime))throw new HostLaunchSpecError("launch_spec_invalid","core.session_runtime must be in-process or worker");if(core.multi_session!==!0)throw new HostLaunchSpecError("launch_spec_invalid","core.multi_session must be true");if(!Array.isArray(core.extensions)||!core.extensions.every(entry=>typeof entry=="string"))throw new HostLaunchSpecError("launch_spec_invalid","core.extensions must be an array of strings");let tunables=parsedTunables(parsed.tunables);return{spec_version:1,core:{session_runtime:core.session_runtime,multi_session:!0,extensions:core.extensions},...tunables&&{tunables},...isRecord(parsed.env)&&{env:parsedEnv(parsed.env)}}}async function readSpecText(absolute){try{return await readFile(absolute,"utf8")}catch(error){throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}}async function assertTrustedFile(absolute,platform){if(platform==="win32")return;let stats=await stat(absolute).catch(error=>{throw new HostLaunchSpecError("launch_spec_unreadable",error instanceof Error?error.message:absolute)}),uid=process.getuid?.();if(uid!==void 0&&stats.uid!==uid)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is owned by uid ${stats.uid}, not ${uid}`);if((stats.mode&18)!==0)throw new HostLaunchSpecError("launch_spec_insecure",`${absolute} is group/world writable (mode ${(stats.mode&511).toString(8)})`)}function trustedEnv(env){for(let name of Object.keys(env??{}))if(!SPEC_ENV_NAME.test(name))throw new HostLaunchSpecError("launch_spec_env_denied",`${name} is outside ${SPEC_ENV_NAME.source}`);return env??{}}async function resolveExtensions(extensions,specDir){let rootReal=await realpath(specDir).catch(()=>specDir),resolved=[];for(let entry of extensions){let target=resolve(specDir,entry);if(escapes(specDir,target))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} resolves outside ${specDir}`);let real=await realpath(target).catch(()=>{});if(real===void 0)throw new HostLaunchSpecError("launch_spec_missing_extension",`${target} does not exist`);if(escapes(rootReal,real))throw new HostLaunchSpecError("launch_spec_path_escape",`${entry} links outside ${specDir}`);resolved.push(real)}return resolved}function escapes(root,target){let step=relative(root,target);return step.startsWith("..")||isAbsolute(step)}function parsedTunables(value){if(!isRecord(value))return;let idleExitMs=value.idleExitMs,coldStart=value.coldStart;return{...typeof idleExitMs=="number"&&Number.isFinite(idleExitMs)&&idleExitMs>0&&{idleExitMs},...(coldStart==="transient"||coldStart==="persistent")&&{coldStart}}}function parsedEnv(value){let env={};for(let[name,entry]of Object.entries(value)){if(typeof entry!="string")throw new HostLaunchSpecError("launch_spec_invalid",`env.${name} must be a string`);env[name]=entry}return env}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{join}from"node:path";var ALLOWED_ENV_NAMES=[/^(PATH|HOME|USER|LOGNAME|SHELL|TMPDIR|TERM|LANG)$/u,/^(LC|XDG)_/u,/^(SENPI|OMO|PI)_/u,/^BSK_(HOME|BIN)$/u,/^(HTTPS?_PROXY|NO_PROXY)$/u,/^[A-Z0-9_]+_API_KEY$/u,/^(ANTHROPIC|OPENAI|GOOGLE|GEMINI|AZURE|AWS|OPENROUTER|XAI|MISTRAL|DEEPSEEK|GROQ|CEREBRAS|MINIMAX)_/u],WINDOWS_SYSTEM_ENV_NAMES=new Set(["SYSTEMROOT","SYSTEMDRIVE","WINDIR","COMSPEC","PATHEXT","TEMP","TMP","USERPROFILE","APPDATA","LOCALAPPDATA","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","HOMEDRIVE","HOMEPATH","NUMBER_OF_PROCESSORS","PROCESSOR_ARCHITECTURE","OS"]),TRANSIENT_ENV_NAMES=new Set(["PI_SESSION_ID","PI_SESSION_FILE","PI_SESSION_CWD","PI_GOAL_STORE_FILE","PI_PROVIDER","PI_MODEL","PI_REASONING_LEVEL","OMO_BROWSER_ENGINE","PI_PROMPT_CACHE_SAFE_WAIT_SECONDS","SENPI_PY_KERNEL_PARENT_PID","SENPI_RPC_HOST_WATCH_FD","SENPI_RPC_HOST_WATCH_PPID","SENPI_RPC_HOST_SCRATCH_DIR","SENPI_RPC_HOST_CLEANUP_PATHS","SENPI_RPC_HOST_PUBLIC_SOCKET","SENPI_RPC_HOST_INSTANCE_ID","SENPI_RPC_HOST_GENERATION","SENPI_RPC_HOST_DAEMON_DIR","SENPI_RPC_HOST_EXPECTED_RUNTIME_BUILD_ID"]);function daemonEnvIsAllowed(name,platform=process.platform){let upper=name.toUpperCase();return TRANSIENT_ENV_NAMES.has(platform==="win32"?upper:name)?!1:platform!=="win32"?ALLOWED_ENV_NAMES.some(pattern=>pattern.test(name)):WINDOWS_SYSTEM_ENV_NAMES.has(upper)||ALLOWED_ENV_NAMES.some(pattern=>pattern.test(upper))}function daemonEnvOverrides(processEnv,specEnv={},platform=process.platform){let overrides={};for(let name of Object.keys(processEnv))daemonEnvIsAllowed(name,platform)||(overrides[name]=null);for(let[name,value]of Object.entries(specEnv))daemonEnvIsAllowed(name,platform)&&(overrides[name]=value);return overrides}function daemonEnvironment(processEnv,overrides={},forced={},platform=process.platform){let env={};for(let[name,value]of Object.entries(processEnv))value!==void 0&&daemonEnvIsAllowed(name,platform)&&(env[name]=value);for(let[name,value]of Object.entries(overrides))daemonEnvIsAllowed(name,platform)&&(deleteEnvironmentName(env,name,platform),value!==null&&(env[name]=value));for(let[name,value]of Object.entries(forced))deleteEnvironmentName(env,name,platform),env[name]=value;return env}function daemonEnvKeys(processEnv,specEnv={},platform=process.platform){let kept=Object.keys(processEnv).filter(name=>daemonEnvIsAllowed(name,platform)),explicit=Object.keys(specEnv).filter(name=>daemonEnvIsAllowed(name,platform));return[...new Set([...kept,...explicit])].sort()}async function writeDaemonEnvKeys(paths,keys){await writeStateFile(daemonEnvKeysFile(paths),{env_keys:keys})}async function readDaemonEnvKeys(paths){let keys=parseJson(await readFileOrUndefined(daemonEnvKeysFile(paths)))?.env_keys;return Array.isArray(keys)?keys.filter(key=>typeof key=="string"):[]}function daemonEnvKeysFile(paths){return join(paths.dir,"env-keys.json")}function deleteEnvironmentName(env,name,platform){if(platform!=="win32"){delete env[name];return}let upper=name.toUpperCase();for(let existing of Object.keys(env))existing.toUpperCase()===upper&&delete env[existing]}import{createHash}from"node:crypto";import{existsSync}from"node:fs";import{readdir,readFile as readFile2,realpath as realpath2,stat as stat2}from"node:fs/promises";import{basename,dirname as dirname2,join as join2,relative as relative2,sep}from"node:path";import{fileURLToPath}from"node:url";var RUNTIME_IDENTITY_HANDOVER_CAPABILITY="runtime_identity_handover",RUNTIME_BUILD_ID=/^sha256:[0-9a-f]{64}$/,EXCLUDED_FILE=/\.(?:d\.[cm]?ts|map)$/,EXCLUDED_NAMES=new Set(["node_modules","runtime-manifest.json","runtime-snapshot.json"]),READ_CONCURRENCY=32;function parseRuntimeBuildId(value){return typeof value=="string"&&RUNTIME_BUILD_ID.test(value)?value:void 0}async function computeRuntimeBuildId(input){let source=input.source??loadedRuntimeSource(),plugins=await Promise.all(input.profile.extensions.map(path=>extensionDigest(path))),manifest={schema:1,flavour:source.flavour,platform:input.platform??process.platform,arch:input.arch??process.arch,engine:input.engine??engineBuildIdentity().text,runtime:await treeDigest(source.root),plugins:plugins.sort(),profile:{multi_session:input.profile.multi_session,session_runtime:input.profile.session_runtime}};return`sha256:${sha256(JSON.stringify(manifest))}`}function loadedRuntimeSource(){if(isBunBinary)return{flavour:"compiled",root:process.execPath};let moduleDir=dirname2(fileURLToPath(import.meta.url)),packageRoot=nearestPackageRoot(moduleDir),[top,next]=relative2(packageRoot,moduleDir).split(sep);return top==="dist"?{flavour:"packaged",root:join2(packageRoot,next==="bundle"?join2("dist","bundle"):"dist")}:{flavour:"dev",root:join2(packageRoot,top??"")}}function nearestPackageRoot(start){for(let dir=start;;dir=dirname2(dir)){if(existsSync(join2(dir,"package.json")))return dir;if(dirname2(dir)===dir)return start}}function extensionDigest(path){let name=basename(path);return name.startsWith(BUILTIN_PATH_PREFIX)?Promise.resolve(sha256(name)):treeDigest(path)}async function treeDigest(root){let files=[];(await stat2(root)).isFile()?files.push(["",root]):await collect(await realpath2(root),"",files,new Set);let digests=await mapLimited(files,READ_CONCURRENCY,async([path,file])=>[path,sha256(await readFile2(file))]);return digests.sort(([a],[b])=>a<b?-1:a>b?1:0),sha256(JSON.stringify(digests))}async function collect(dir,prefix,files,seen){if(seen.has(dir))return;seen.add(dir);let entries=(await readdir(dir,{withFileTypes:!0})).sort((a,b)=>a.name<b.name?-1:a.name>b.name?1:0);for(let entry of entries){if(entry.name.startsWith(".")||EXCLUDED_NAMES.has(entry.name))continue;let path=join2(dir,entry.name),name=prefix===""?entry.name:`${prefix}/${entry.name}`,kind=entry.isSymbolicLink()?await stat2(path).catch(()=>{}):entry;kind!==void 0&&(kind.isDirectory()?await collect(await realpath2(path),name,files,seen):kind.isFile()&&!EXCLUDED_FILE.test(entry.name)&&files.push([name,path]))}}async function mapLimited(items,limit,map){let results=new Array(items.length),next=0,worker=async()=>{for(let index=next++;index<items.length;index=next++)results[index]=await map(items[index])};return await Promise.all(Array.from({length:Math.min(limit,items.length)},worker)),results}function sha256(data){return createHash("sha256").update(data).digest("hex")}function parseHostProtocolInfo(data){if(!isRecord2(data)||typeof data.serverVersion!="string"||!Array.isArray(data.capabilities)||!data.capabilities.every(entry=>typeof entry=="string"))return;let ordinal=parseOrdinal(data.engineOrdinal),launchProfile=parseLaunchProfile(data.launch_profile),runtimeBuildId=parseRuntimeBuildId(data.runtimeBuildId);return{protocolVersion:typeof data.protocolVersion=="number"?data.protocolVersion:0,serverVersion:data.serverVersion,capabilities:data.capabilities,...typeof data.instanceId=="string"&&{instanceId:data.instanceId},...typeof data.generation=="number"&&Number.isSafeInteger(data.generation)&&{generation:data.generation},...typeof data.engineVersion=="string"&&{engineVersion:data.engineVersion},...ordinal&&{engineOrdinal:ordinal},...launchProfile&&{launch_profile:launchProfile},...typeof data.memory_pressure=="boolean"&&{memory_pressure:data.memory_pressure},...runtimeBuildId!==void 0&&{runtimeBuildId},...isRecord2(data.handover)&&{handover:data.handover}}}function parseOrdinal(value){if(!(!Array.isArray(value)||value.length!==5||!value.every(part=>typeof part=="number")))return[value[0],value[1],value[2],value[3],value[4]]}function parseLaunchProfile(value){if(!isRecord2(value)||typeof value.profile_id!="string"||!isRecord2(value.core))return;let{extensions,multi_session,session_runtime}=value.core;if(!(!Array.isArray(extensions)||!extensions.every(entry=>typeof entry=="string"))&&typeof multi_session=="boolean"&&!(session_runtime!=="in-process"&&session_runtime!=="worker"))return{profile_id:value.profile_id,core:{extensions,multi_session,session_runtime}}}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var HOST_PROTOCOL_VERSION=1,GENERATION_HANDOFF_CAPABILITY="generation_handoff",REQUIRED_HOST_CAPABILITIES=["multi_session",EXTENSION_EVENTS_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY],HostEnsureRefusedError=class extends Error{constructor(socket,reason,host,detail){super(`RPC socket ${socket} refused: ${reason} - ${refusalDetail(reason,host)}${detail?`: ${detail}`:""}`),this.name="HostEnsureRefusedError",this.socket=socket,this.reason=reason,this.detail=detail}};function refusalDetail(reason,host){switch(reason){case"protocol":return`the running host speaks protocol version ${host?.protocolVersion??"unknown"}, this build speaks ${HOST_PROTOCOL_VERSION}`;case"capability":{let missing=REQUIRED_HOST_CAPABILITIES.filter(capability=>!host?.capabilities.includes(capability));return`the running host is missing ${JSON.stringify(missing)}; it owns the socket, so no second host is started`}case"foreign_writer":return"its pidfile was written by another process, so this one may not signal it; stop that host explicitly instead";case"legacy_host":return"a host from before the per-socket daemon directory is still running; it is drained and replaced only while it holds no session, and no second host is started beside it";case"host_busy":return"its socket accepts connections but did not answer inside the probe budget: a live host under load, which is never ended to make room for a replacement";default:return assertNever(reason)}}function decideHostAction(client,host,policy){if(host===void 0)return{action:"start",reason:client.startedByUs?"restart_own_host":"no_host",upgradeable:!1};if(host.protocolVersion!==client.protocolVersion)return{action:"refuse",reason:"protocol",upgradeable:!1};if(!client.requiredCapabilities.every(capability=>host.capabilities.includes(capability)))return policy==="fallback"?{action:"fallback",reason:"capability",upgradeable:!1}:{action:"refuse",reason:"capability",upgradeable:!1};let upgradeable=client.platform!=="win32"&&host.capabilities.includes(GENERATION_HANDOFF_CAPABILITY);if(policy==="fallback"&&host.engineVersion!==client.identity.text)return{action:"fallback",reason:"engine_mismatch",upgradeable};let warning=profileWarning(client,host);return client.platform==="win32"?{action:"reuse",reason:"win32_attach_only",upgradeable:!1,...warning&&{warning}}:upgradeable?policy==="upgrade"&&client.launchProfile&&host.launch_profile&&supersedes(client,host)?{action:"handoff",reason:sameRelease(client.identity.ordinal,host.engineOrdinal)?"profile":"newer_engine",upgradeable:!0}:{action:"reuse",reason:"compatible",upgradeable,...warning&&{warning}}:{action:"reuse",reason:"handoff_unsupported",upgradeable:!1,...warning&&{warning}}}function supersedes(client,host){if(host.engineOrdinal===void 0)return!1;let hostIdentity={text:host.engineVersion??"",ordinal:host.engineOrdinal,scheme:host.engineOrdinal[4]>0?"epoch":"nodef"};return compareEngineOrdinal(client.identity,hostIdentity)<=0?!1:covers(client.launchProfile,host.launch_profile)}function profileWarning(client,host){if(client.launchProfile===void 0||host.launch_profile===void 0)return"profile_mismatch_attached";if(client.launchProfile.profile_id===host.launch_profile.profile_id)return;let clientCoversHost=covers(client.launchProfile,host.launch_profile);if(!(clientCoversHost&&covers(host.launch_profile,client.launchProfile)))return clientCoversHost?"profile_mismatch_attached":"profile_narrower_attached"}function extensionRole(extension){let segments=extension.split(/[\\/]+/),pluginAt=segments.lastIndexOf("plugin");return pluginAt<0?extension:segments.slice(pluginAt).join("/")}function covers(candidate,running){if(candidate===void 0||running===void 0)return!1;let candidateRoles=new Set(candidate.core.extensions.map(extensionRole));return running.core.extensions.every(extension=>candidateRoles.has(extensionRole(extension)))}function sameRelease(candidate,running){return running!==void 0&&candidate.slice(0,4).every((part,index)=>part===running[index])}function assertNever(value){throw new Error(`unreachable host decision: ${JSON.stringify(value)}`)}import{mkdir,writeFile as writeFile3}from"node:fs/promises";import{dirname as dirname5}from"node:path";function ensureClient(options,startedByUs){return{protocolVersion:HOST_PROTOCOL_VERSION,requiredCapabilities:REQUIRED_HOST_CAPABILITIES,identity:engineBuildIdentity(),...options.upgrade==="if-engine-differs"?{launchProfile:hostLaunchProfile(hostChildArgv(options.hostArgs??[]),process.cwd())}:{},startedByUs,platform:process.platform}}function hostChildArgv(hostArgs){return["--mode","rpc","--multi-session",...hostArgs]}function isCompatible(protocol){return decideHostAction(ensureClient({socket:""},!1),protocol,"never").action==="reuse"}import{spawn}from"node:child_process";import{randomUUID}from"node:crypto";import{open,readFile as readFile3}from"node:fs/promises";var SIGKILL_GRACE_MS=2e3;async function matchesPidFileOrUnknown(pidFile,probe){try{return await processMatchesPidFile(pidFile,probe)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!1;throw error}}async function stopSpawnedChild(child,childExit,termTimeoutMs){let exited=()=>child.exitCode!==null||child.signalCode!==null;if(exited())return;let signal=name=>{try{child.kill(name)}catch(error){if(!isNodeErrorCode(error,"ESRCH"))throw error}},waitFor=ms=>Promise.race([childExit.then(()=>!0),delay(ms).then(()=>exited())]);if(signal("SIGTERM"),!await waitFor(termTimeoutMs)&&(signal("SIGKILL"),!await waitFor(SIGKILL_GRACE_MS)))throw new Error(`RPC socket host pid ${child.pid??"?"} remained alive after SIGKILL`)}async function stopManagedHost(pidFile,termTimeoutMs,readStartTime=readProcessStartTime){if(await signalValidated(pidFile,"SIGTERM",readStartTime),!await waitForGone(pidFile,termTimeoutMs,readStartTime)&&(await signalValidated(pidFile,"SIGKILL",readStartTime),!await waitForGone(pidFile,SIGKILL_GRACE_MS,readStartTime)))throw new Error(`RPC socket host pid ${pidFile.pid} remained alive after SIGKILL`)}async function resolvePidFileOwnership(pidFile,readStartTime){try{return await processMatchesPidFile(pidFile,readStartTime,processIsLive,{attempts:1})?"owns":"gone"}catch(error){if(error instanceof ProcessIdentityUnreadableError)return"unknown";throw error}}async function signalValidated(pidFile,signal,readStartTime=readProcessStartTime){if(await resolvePidFileOwnership(pidFile,readStartTime)==="owns")try{process.kill(pidFile.pid,signal)}catch(error){if(!isNodeErrorCode(error,"ESRCH"))throw error}}async function waitForGone(pidFile,timeoutMs,readStartTime=readProcessStartTime){let deadline=Date.now()+timeoutMs;for(;Date.now()<=deadline;){if(await resolvePidFileOwnership(pidFile,readStartTime)==="gone")return!0;await delay(50)}return await resolvePidFileOwnership(pidFile,readStartTime)==="gone"}function delay(ms){return new Promise(resolveDelay=>setTimeout(resolveDelay,ms))}function isNodeErrorCode(error,code){return error instanceof Error&&"code"in error&&error.code===code}import{existsSync as existsSync2}from"node:fs";import{basename as basename2,dirname as dirname3,resolve as resolve2}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";var PINNED_HOST_CLIENT_CAPABILITIES=[EXTENSION_EVENTS_CAPABILITY,CUSTOM_UNSUPPORTED_CAPABILITY];function defaultHostLaunch(supervisorArgs,compiled=isBunBinary,sibling=resolveHostLifecycleEntryPath()??null){return compiled?{command:process.execPath,args:[INTERNAL_SUPERVISOR_FLAG,...supervisorArgs]}:sibling!==null?{command:process.execPath,args:[...rpcHostExecArgv(),sibling,...supervisorArgs]}:{command:process.execPath,args:[...rpcHostExecArgv(),resolveCliMainPath(),INTERNAL_SUPERVISOR_FLAG,...supervisorArgs]}}function resolveHostLifecycleEntryPath(){let modulePath=fileURLToPath2(import.meta.url);if(basename2(dirname3(modulePath))==="chunks")return;let extension=modulePath.endsWith(".ts")?".ts":".js",sibling=resolve2(dirname3(modulePath),`host-lifecycle${extension}`);return existsSync2(sibling)?sibling:void 0}import{createConnection}from"node:net";function holdAttachment(socket){return socket.removeAllListeners("data"),socket.resume(),socket.on("error",()=>socket.destroy()),socket.unref(),{release:()=>socket.destroy()}}var DEFAULT_PROBE_TIMEOUT_MS=1e4,PROBE_REQUEST_ID="ensure-host-probe";function probeHost(options){return probeProtocolInfo(options.socket,options.timeoutMs??DEFAULT_PROBE_TIMEOUT_MS)}async function probeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info"},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function observeProtocolInfo(socketPath,timeoutMs){let reply=await requestOnSocket(socketPath,{type:"get_protocol_info",[OBSERVE_REQUEST_FIELD]:!0},timeoutMs);return reply===void 0?void 0:parseHostProtocolInfo(reply)}async function holdProtocolInfo(socketPath,timeoutMs){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs,!0),info=outcome.answer===void 0?void 0:parseHostProtocolInfo(outcome.answer);if(outcome.kept===void 0)return;let hold=holdAttachment(outcome.kept);if(info!==void 0)return{info,hold};hold.release()}async function probeSocketReachable(socketPath,timeoutMs){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"get_protocol_info"},timeoutMs)).connected}async function probeSessionCount(socketPath,timeoutMs){return sessionCountOf(await requestOnSocket(socketPath,{type:"list_sessions",include_workers:!0},timeoutMs))}async function holdSessionCount(socketPath,timeoutMs){let outcome=await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,type:"list_sessions",include_workers:!0},timeoutMs,!0),kept=outcome.kept;if(kept===void 0)return;let sessions=sessionCountOf(outcome.answer);if(sessions===void 0){kept.destroy();return}let asked=0;return{sessions,recount:recountTimeoutMs=>askAgain(kept,`${PROBE_REQUEST_ID}-recount-${++asked}`,recountTimeoutMs),close:()=>kept.destroy()}}function askAgain(socket,id,timeoutMs){return new Promise(resolveCount=>{let buffer="",finish=count=>{clearTimeout(timeout),socket.off("data",onData),socket.off("close",onClose),resolveCount(count)},onClose=()=>finish(void 0),onData=chunk=>{buffer+=chunk.toString("utf8");for(let newline=buffer.indexOf(`
|
|
3
3
|
`);newline!==-1;newline=buffer.indexOf(`
|
|
4
4
|
`)){let answer2=readAnswer(buffer.slice(0,newline),id);if(buffer=buffer.slice(newline+1),answer2!==void 0){finish(sessionCountOf(answer2));return}}},timeout=setTimeout(()=>finish(void 0),timeoutMs);if(socket.destroyed){finish(void 0);return}socket.on("data",onData),socket.once("close",onClose),socket.write(`${JSON.stringify({id,type:"list_sessions",include_workers:!0})}
|
|
5
5
|
`)})}function sessionCountOf(reply){return isRecord3(reply)&&Array.isArray(reply.sessions)?reply.sessions.length:void 0}async function requestOnSocket(socketPath,command,timeoutMs){return(await connectAndAsk(socketPath,{id:PROBE_REQUEST_ID,...command},timeoutMs)).answer}async function connectAndAsk(socketPath,request,timeoutMs,keep=!1){let secret;if(socketNeedsHandshake(socketPath))try{secret=await readSocketSecret(socketSecretPath(socketPath))}catch{return{connected:!1,answer:void 0}}return new Promise(resolveProbe=>{let socket=createConnection(resolveSocketTransportAddress(socketPath,process.platform,secret)),buffer="",settled=!1,connected=!1,finish=value=>{if(!settled){if(settled=!0,clearTimeout(timeout),keep&&value!==void 0&&!socket.destroyed){resolveProbe({connected,answer:value,kept:socket});return}socket.destroy(),resolveProbe({connected,answer:value})}},timeout=setTimeout(()=>finish(),timeoutMs);socket.once("connect",()=>{connected=!0,socket.write(`${JSON.stringify(request)}
|
|
@@ -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{HOST_DAEMON_LAYOUT,ProcessIdentityUnreadableError,canonicalEndpointPath,claimOwnerIsLive,createHostDaemonPaths,generationPaths,hostDaemonDirectoryPaths,parseDaemonPidFile,parseJson,processMatchesPidFile,readFileOrUndefined,readSessionPathClaims,readSocketSecret,resolveSocketTransportAddress,socketNamesDirectory,socketSecretPath}from"./chunk-LUWWM7GA.js";import{readdir}from"node:fs/promises";import{basename as basename2,join}from"node:path";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)}var ENDPOINT_DIRECTORY_NAME=/^[0-9a-f]{16}$/;async function listHostEndpoints(agentDir){let flatDir=join(agentDir,"rpc-host-daemon");if(parseJson(await readFileOrUndefined(join(flatDir,"layout.json")).catch(()=>{}))?.layout!==HOST_DAEMON_LAYOUT)return[];let dirs=(await readdir(flatDir,{withFileTypes:!0}).catch(()=>[])).filter(entry=>entry.isDirectory()&&ENDPOINT_DIRECTORY_NAME.test(entry.name)).map(entry=>join(flatDir,entry.name)).sort(),endpoints=[];for(let dir of dirs)endpoints.push(await identifyEndpoint(dir));return endpoints}async function identifyEndpoint(dir){let paths=hostDaemonDirectoryPaths(dir),named=await recordNaming(paths.endpointFile,dir);if(named!==void 0)return{socket:named.socket,dir,identity:"endpoint",endpoint_kind:endpointKindOf(named.record)};let booted=await recordNaming(paths.settingsFile,dir);if(booted!==void 0)return{socket:booted.socket,dir,identity:"settings",endpoint_kind:"rpc_host"};let generations=await readdir(paths.generationsDir).catch(()=>[]);for(let instanceId of generations.sort()){let recorded=await recordNaming(join(paths.generationsDir,instanceId,"settings.json"),dir);if(recorded!==void 0)return{socket:recorded.socket,dir,identity:"generation-settings",endpoint_kind:"rpc_host"}}return{socket:null,dir,identity:"unknown",endpoint_kind:"rpc_host"}}async function endpointKindOfSocket(socket,agentDir){if(isTuiControlSocket(socket))return"tui";let paths=createHostDaemonPaths({socket,agentDir}),named=await recordNaming(paths.endpointFile,paths.dir);return named===void 0?"rpc_host":endpointKindOf(named.record)}function endpointKindOf(record){return record.endpoint_kind==="tui"?"tui":"rpc_host"}async function recordNaming(file,dir){let record=parseJson(await readFileOrUndefined(file).catch(()=>{})),socket=record?.socket;if(!(record===void 0||typeof socket!="string"||socket===""))return socketNamesDirectory(socket,basename2(dir))?{socket,record}:void 0}import{lstat as lstat2,rm}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";import{createHash as createHash2}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname,join as join2}from"node:path";import{stat}from"node:fs/promises";var LegacyLockArtifactError=class extends Error{constructor(lockPath){super(`Legacy lock directory is present at ${lockPath}`),this.code="ELEGACY_LOCK_ARTIFACT",this.name="LegacyLockArtifactError",this.lockPath=lockPath}},DEFAULT_RETRIES={retries:100,minTimeout:20,maxTimeout:100};async function openLockDatabase(lockPath){if(typeof globalThis.Bun<"u"){let{Database}=await import("bun:sqlite"),database2=new Database(lockPath,{create:!0});return{exec:sql=>database2.exec(sql),close:()=>database2.close(!1)}}let{DatabaseSync}=await import("node:sqlite"),database=new DatabaseSync(lockPath);return{exec:sql=>database.exec(sql),close:()=>database.close()}}async function acquireOwnershipSafeLock(lockPath,options={}){let retries=options.retries??DEFAULT_RETRIES,deadline=Date.now()+retries.retries*retries.maxTimeout;for(;;){await rejectLegacyDirectory(lockPath);let busyMs=Math.max(1,Math.min(retries.maxTimeout,deadline-Date.now())),database;try{database=await openLockDatabase(lockPath),database.exec(`PRAGMA busy_timeout = ${busyMs}; BEGIN EXCLUSIVE;`);let released=!1,held=database;return async()=>{if(!released){released=!0;try{held.exec("COMMIT;")}finally{held.close()}}}}catch(error){try{database?.close()}catch{}if(await rejectLegacyDirectory(lockPath),isBusy(error)&&Date.now()<deadline){await new Promise(resolve=>setTimeout(resolve,Math.min(retries.minTimeout,Math.max(1,deadline-Date.now()))));continue}throw error}}}async function rejectLegacyDirectory(lockPath){try{if((await stat(lockPath)).isDirectory())throw new LegacyLockArtifactError(lockPath)}catch(error){if(error instanceof LegacyLockArtifactError||error.code!=="ENOENT")throw error}}function isBusy(error){let message=error instanceof Error?error.message:String(error);return/busy|locked/i.test(message)||error?.code==="SQLITE_BUSY"}var LOCK_BUSY_WAIT_MS=100;function hostEnsureLockTarget(socket){return join2(tmpdir(),"senpi-rpc-host-locks",createSocketLockName(socket))}async function acquireHostEnsureLock(socket,waitMs){let lockTarget=hostEnsureLockTarget(socket);return await mkdir(dirname(lockTarget),{recursive:!0}),await writeFile(lockTarget,"",{flag:"a",mode:384}),acquireOwnershipSafeLock(`${lockTarget}.lock`,hostEnsureLockOptions(waitMs))}function hostEnsureLockOptions(waitMs){return{retries:{retries:Math.ceil(waitMs/LOCK_BUSY_WAIT_MS),minTimeout:20,maxTimeout:LOCK_BUSY_WAIT_MS}}}function createSocketLockName(socket){return createHash2("sha256").update(socketLockAddress(socket),"utf8").digest("hex").slice(0,32)}function socketLockAddress(socket){return process.platform==="win32"||socket.startsWith("\0")?resolveSocketTransportAddress(socket,process.platform):canonicalEndpointPath(socket)}import{lstat,readdir as readdir2}from"node:fs/promises";import{createConnection}from"node:net";import{basename as basename3,dirname as dirname2,join as join3}from"node:path";var SOCKET_PROBE_TIMEOUT_MS=2e3;async function endpointInUse(paths,socket){if(await anyGenerationLive(paths))return{inUse:"live_generation"};for(let claim of await readSessionPathClaims(paths.reservationsDir))if(await claimOwnerIsLive(claim.owner))return{inUse:"live_claim"};let silence=await socketSilence(socket);if(silence===void 0)return{inUse:"reachable"};let successors=(await socketSiblings(socket)).filter(name=>name.startsWith(`${basename3(socket)}.next-`));for(let successor of successors)if(await socketSilence(join3(dirname2(socket),successor))===void 0)return{inUse:"reachable"};return{inUse:void 0,silence}}async function socketSiblings(socket){let name=basename3(socket);return(await readdir2(dirname2(socket)).catch(()=>[])).filter(entry=>entry.startsWith(`${name}.next-`)||entry.startsWith(`${name}.shield-`))}async function anyGenerationLive(paths){for(let instanceId of await readdir2(paths.generationsDir).catch(()=>[])){let record=generationRecord(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));if(record!==void 0&&await recordIsLive(record))return!0}return!1}function generationRecord(text){if(text===void 0)return;let record=parseDaemonPidFile(text);if(record!==void 0)return record;let pid=parseJson(text)?.pid;return typeof pid=="number"&&Number.isInteger(pid)&&pid>0?{pid,processStartTime:null}:void 0}async function recordIsLive(record){try{return await processMatchesPidFile(record)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}}async function socketSilence(socket){let secret;return process.platform==="win32"&&(secret=await readSocketSecret(socketSecretPath(socket)).catch(()=>{}),secret===void 0)?"socket_absent":new Promise(resolveProbe=>{let connection=createConnection(resolveSocketTransportAddress(socket,process.platform,secret)),finish=value=>{clearTimeout(timeout),connection.destroy(),resolveProbe(value)},timeout=setTimeout(()=>finish(void 0),SOCKET_PROBE_TIMEOUT_MS);connection.once("connect",()=>finish(void 0)),connection.once("error",error=>{error.code==="ECONNREFUSED"?refusedBySocket(socket).then(finish):error.code==="ENOENT"?finish("socket_absent"):finish(void 0)})})}async function refusedBySocket(socket){if(process.platform==="win32"||socket.startsWith("\0"))return"socket_refused";try{return(await lstat(socket)).isSocket()?"socket_refused":void 0}catch(error){return error instanceof Error&&"code"in error&&error.code==="ENOENT"?"socket_absent":void 0}}var GC_LOCK_WAIT_MS=2e3;async function gcHostEndpoints(agentDir,options={}){let removed=[],kept=[],wanted=kind=>options.kinds===void 0||options.kinds.includes(kind),legacy=wanted("rpc_host")?await legacyFlatDirectory(agentDir):void 0;legacy!==void 0&&kept.push({socket:null,dir:legacy,reason:"legacy_layout"});for(let endpoint of await listHostEndpoints(agentDir)){if(!wanted(endpoint.endpoint_kind))continue;if(endpoint.socket===null){kept.push({socket:null,dir:endpoint.dir,reason:"unknown_identity"});continue}let entry={socket:endpoint.socket,dir:endpoint.dir};try{let outcome=await gcEndpoint(endpoint.socket,endpoint.dir,options);outcome.removed?outcome.skipped.length===0?removed.push({...entry,reason:outcome.reason}):removed.push({...entry,reason:outcome.reason,skipped:outcome.skipped}):kept.push({...entry,reason:outcome.reason})}catch(error){kept.push({...entry,reason:"failed",error:error instanceof Error?error.message:String(error)})}}return{removed,kept}}async function gcEndpoint(socket,dir,options){let release=await acquireEnsureLock(socket);if(release===void 0)return{removed:!1,reason:"locked"};try{await options._test?.afterLockAcquired?.(socket);let evidence=await endpointInUse(hostDaemonDirectoryPaths(dir),socket);if(evidence.inUse!==void 0)return{removed:!1,reason:evidence.inUse};let skipped=await removeEndpoint(socket,dir);return{removed:!0,reason:evidence.silence,skipped}}finally{await release()}}async function removeEndpoint(socket,dir){let skipped=[];for(let sibling of await socketSiblings(socket)){let path=join4(dirname3(socket),sibling),entry=await lstat2(path).catch(error=>{if(!(error instanceof Error&&"code"in error&&error.code==="ENOENT"))throw error});entry?.isDirectory()?skipped.push({path,type:"directory"}):entry!==void 0&&await rm(path,{force:!0})}return await rm(socket,{force:!0}),await rm(dir,{recursive:!0,force:!0}),skipped}async function acquireEnsureLock(socket){return acquireHostEnsureLock(socket,GC_LOCK_WAIT_MS).catch(()=>{})}async function legacyFlatDirectory(agentDir){let flatDir=join4(agentDir,"rpc-host-daemon");return parseJson(await readFileOrUndefined(join4(flatDir,"layout.json")).catch(()=>{}))?.layout===HOST_DAEMON_LAYOUT?void 0:await readFileOrUndefined(join4(flatDir,"host.pid")).catch(()=>{})!==void 0?flatDir:void 0}export{tuiSocketName,socketNeedsHandshake,listHostEndpoints,endpointKindOfSocket,acquireOwnershipSafeLock,hostEnsureLockTarget,acquireHostEnsureLock,hostEnsureLockOptions,anyGenerationLive,gcHostEndpoints,gcEndpoint};
|
|
2
|
+
import{HOST_DAEMON_LAYOUT,ProcessIdentityUnreadableError,canonicalEndpointPath,claimOwnerIsLive,createHostDaemonPaths,generationPaths,hostDaemonDirectoryPaths,parseDaemonPidFile,parseJson,processMatchesPidFile,readFileOrUndefined,readSessionPathClaims,readSocketSecret,resolveSocketTransportAddress,socketNamesDirectory,socketSecretPath}from"./chunk-RADHRQ4K.js";import{readdir}from"node:fs/promises";import{basename as basename2,join}from"node:path";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)}var ENDPOINT_DIRECTORY_NAME=/^[0-9a-f]{16}$/;async function listHostEndpoints(agentDir){let flatDir=join(agentDir,"rpc-host-daemon");if(parseJson(await readFileOrUndefined(join(flatDir,"layout.json")).catch(()=>{}))?.layout!==HOST_DAEMON_LAYOUT)return[];let dirs=(await readdir(flatDir,{withFileTypes:!0}).catch(()=>[])).filter(entry=>entry.isDirectory()&&ENDPOINT_DIRECTORY_NAME.test(entry.name)).map(entry=>join(flatDir,entry.name)).sort(),endpoints=[];for(let dir of dirs)endpoints.push(await identifyEndpoint(dir));return endpoints}async function identifyEndpoint(dir){let paths=hostDaemonDirectoryPaths(dir),named=await recordNaming(paths.endpointFile,dir);if(named!==void 0)return{socket:named.socket,dir,identity:"endpoint",endpoint_kind:endpointKindOf(named.record)};let booted=await recordNaming(paths.settingsFile,dir);if(booted!==void 0)return{socket:booted.socket,dir,identity:"settings",endpoint_kind:"rpc_host"};let generations=await readdir(paths.generationsDir).catch(()=>[]);for(let instanceId of generations.sort()){let recorded=await recordNaming(join(paths.generationsDir,instanceId,"settings.json"),dir);if(recorded!==void 0)return{socket:recorded.socket,dir,identity:"generation-settings",endpoint_kind:"rpc_host"}}return{socket:null,dir,identity:"unknown",endpoint_kind:"rpc_host"}}async function endpointKindOfSocket(socket,agentDir){if(isTuiControlSocket(socket))return"tui";let paths=createHostDaemonPaths({socket,agentDir}),named=await recordNaming(paths.endpointFile,paths.dir);return named===void 0?"rpc_host":endpointKindOf(named.record)}function endpointKindOf(record){return record.endpoint_kind==="tui"?"tui":"rpc_host"}async function recordNaming(file,dir){let record=parseJson(await readFileOrUndefined(file).catch(()=>{})),socket=record?.socket;if(!(record===void 0||typeof socket!="string"||socket===""))return socketNamesDirectory(socket,basename2(dir))?{socket,record}:void 0}import{lstat as lstat2,rm}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";import{createHash as createHash2}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname,join as join2}from"node:path";import{stat}from"node:fs/promises";var LegacyLockArtifactError=class extends Error{constructor(lockPath){super(`Legacy lock directory is present at ${lockPath}`),this.code="ELEGACY_LOCK_ARTIFACT",this.name="LegacyLockArtifactError",this.lockPath=lockPath}},DEFAULT_RETRIES={retries:100,minTimeout:20,maxTimeout:100};async function openLockDatabase(lockPath){if(typeof globalThis.Bun<"u"){let{Database}=await import("bun:sqlite"),database2=new Database(lockPath,{create:!0});return{exec:sql=>database2.exec(sql),close:()=>database2.close(!1)}}let{DatabaseSync}=await import("node:sqlite"),database=new DatabaseSync(lockPath);return{exec:sql=>database.exec(sql),close:()=>database.close()}}async function acquireOwnershipSafeLock(lockPath,options={}){let retries=options.retries??DEFAULT_RETRIES,deadline=Date.now()+retries.retries*retries.maxTimeout;for(;;){await rejectLegacyDirectory(lockPath);let busyMs=Math.max(1,Math.min(retries.maxTimeout,deadline-Date.now())),database;try{database=await openLockDatabase(lockPath),database.exec(`PRAGMA busy_timeout = ${busyMs}; BEGIN EXCLUSIVE;`);let released=!1,held=database;return async()=>{if(!released){released=!0;try{held.exec("COMMIT;")}finally{held.close()}}}}catch(error){try{database?.close()}catch{}if(await rejectLegacyDirectory(lockPath),isBusy(error)&&Date.now()<deadline){await new Promise(resolve=>setTimeout(resolve,Math.min(retries.minTimeout,Math.max(1,deadline-Date.now()))));continue}throw error}}}async function rejectLegacyDirectory(lockPath){try{if((await stat(lockPath)).isDirectory())throw new LegacyLockArtifactError(lockPath)}catch(error){if(error instanceof LegacyLockArtifactError||error.code!=="ENOENT")throw error}}function isBusy(error){let message=error instanceof Error?error.message:String(error);return/busy|locked/i.test(message)||error?.code==="SQLITE_BUSY"}var LOCK_BUSY_WAIT_MS=100;function hostEnsureLockTarget(socket){return join2(tmpdir(),"senpi-rpc-host-locks",createSocketLockName(socket))}async function acquireHostEnsureLock(socket,waitMs){let lockTarget=hostEnsureLockTarget(socket);return await mkdir(dirname(lockTarget),{recursive:!0}),await writeFile(lockTarget,"",{flag:"a",mode:384}),acquireOwnershipSafeLock(`${lockTarget}.lock`,hostEnsureLockOptions(waitMs))}function hostEnsureLockOptions(waitMs){return{retries:{retries:Math.ceil(waitMs/LOCK_BUSY_WAIT_MS),minTimeout:20,maxTimeout:LOCK_BUSY_WAIT_MS}}}function createSocketLockName(socket){return createHash2("sha256").update(socketLockAddress(socket),"utf8").digest("hex").slice(0,32)}function socketLockAddress(socket){return process.platform==="win32"||socket.startsWith("\0")?resolveSocketTransportAddress(socket,process.platform):canonicalEndpointPath(socket)}import{lstat,readdir as readdir2}from"node:fs/promises";import{createConnection}from"node:net";import{basename as basename3,dirname as dirname2,join as join3}from"node:path";var SOCKET_PROBE_TIMEOUT_MS=2e3;async function endpointInUse(paths,socket){if(await anyGenerationLive(paths))return{inUse:"live_generation"};for(let claim of await readSessionPathClaims(paths.reservationsDir))if(await claimOwnerIsLive(claim.owner))return{inUse:"live_claim"};let silence=await socketSilence(socket);if(silence===void 0)return{inUse:"reachable"};let successors=(await socketSiblings(socket)).filter(name=>name.startsWith(`${basename3(socket)}.next-`));for(let successor of successors)if(await socketSilence(join3(dirname2(socket),successor))===void 0)return{inUse:"reachable"};return{inUse:void 0,silence}}async function socketSiblings(socket){let name=basename3(socket);return(await readdir2(dirname2(socket)).catch(()=>[])).filter(entry=>entry.startsWith(`${name}.next-`)||entry.startsWith(`${name}.shield-`))}async function anyGenerationLive(paths){for(let instanceId of await readdir2(paths.generationsDir).catch(()=>[])){let record=generationRecord(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));if(record!==void 0&&await recordIsLive(record))return!0}return!1}function generationRecord(text){if(text===void 0)return;let record=parseDaemonPidFile(text);if(record!==void 0)return record;let pid=parseJson(text)?.pid;return typeof pid=="number"&&Number.isInteger(pid)&&pid>0?{pid,processStartTime:null}:void 0}async function recordIsLive(record){try{return await processMatchesPidFile(record)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}}async function socketSilence(socket){let secret;return process.platform==="win32"&&(secret=await readSocketSecret(socketSecretPath(socket)).catch(()=>{}),secret===void 0)?"socket_absent":new Promise(resolveProbe=>{let connection=createConnection(resolveSocketTransportAddress(socket,process.platform,secret)),finish=value=>{clearTimeout(timeout),connection.destroy(),resolveProbe(value)},timeout=setTimeout(()=>finish(void 0),SOCKET_PROBE_TIMEOUT_MS);connection.once("connect",()=>finish(void 0)),connection.once("error",error=>{error.code==="ECONNREFUSED"?refusedBySocket(socket).then(finish):error.code==="ENOENT"?finish("socket_absent"):finish(void 0)})})}async function refusedBySocket(socket){if(process.platform==="win32"||socket.startsWith("\0"))return"socket_refused";try{return(await lstat(socket)).isSocket()?"socket_refused":void 0}catch(error){return error instanceof Error&&"code"in error&&error.code==="ENOENT"?"socket_absent":void 0}}var GC_LOCK_WAIT_MS=2e3;async function gcHostEndpoints(agentDir,options={}){let removed=[],kept=[],wanted=kind=>options.kinds===void 0||options.kinds.includes(kind),legacy=wanted("rpc_host")?await legacyFlatDirectory(agentDir):void 0;legacy!==void 0&&kept.push({socket:null,dir:legacy,reason:"legacy_layout"});for(let endpoint of await listHostEndpoints(agentDir)){if(!wanted(endpoint.endpoint_kind))continue;if(endpoint.socket===null){kept.push({socket:null,dir:endpoint.dir,reason:"unknown_identity"});continue}let entry={socket:endpoint.socket,dir:endpoint.dir};try{let outcome=await gcEndpoint(endpoint.socket,endpoint.dir,options);outcome.removed?outcome.skipped.length===0?removed.push({...entry,reason:outcome.reason}):removed.push({...entry,reason:outcome.reason,skipped:outcome.skipped}):kept.push({...entry,reason:outcome.reason})}catch(error){kept.push({...entry,reason:"failed",error:error instanceof Error?error.message:String(error)})}}return{removed,kept}}async function gcEndpoint(socket,dir,options){let release=await acquireEnsureLock(socket);if(release===void 0)return{removed:!1,reason:"locked"};try{await options._test?.afterLockAcquired?.(socket);let evidence=await endpointInUse(hostDaemonDirectoryPaths(dir),socket);if(evidence.inUse!==void 0)return{removed:!1,reason:evidence.inUse};let skipped=await removeEndpoint(socket,dir);return{removed:!0,reason:evidence.silence,skipped}}finally{await release()}}async function removeEndpoint(socket,dir){let skipped=[];for(let sibling of await socketSiblings(socket)){let path=join4(dirname3(socket),sibling),entry=await lstat2(path).catch(error=>{if(!(error instanceof Error&&"code"in error&&error.code==="ENOENT"))throw error});entry?.isDirectory()?skipped.push({path,type:"directory"}):entry!==void 0&&await rm(path,{force:!0})}return await rm(socket,{force:!0}),await rm(dir,{recursive:!0,force:!0}),skipped}async function acquireEnsureLock(socket){return acquireHostEnsureLock(socket,GC_LOCK_WAIT_MS).catch(()=>{})}async function legacyFlatDirectory(agentDir){let flatDir=join4(agentDir,"rpc-host-daemon");return parseJson(await readFileOrUndefined(join4(flatDir,"layout.json")).catch(()=>{}))?.layout===HOST_DAEMON_LAYOUT?void 0:await readFileOrUndefined(join4(flatDir,"host.pid")).catch(()=>{})!==void 0?flatDir:void 0}export{tuiSocketName,socketNeedsHandshake,listHostEndpoints,endpointKindOfSocket,acquireOwnershipSafeLock,hostEnsureLockTarget,acquireHostEnsureLock,hostEnsureLockOptions,anyGenerationLive,gcHostEndpoints,gcEndpoint};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
+
import{engineBuildIdentity}from"./chunk-ZJHRDQCH.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV}from"./chunk-CIRZTP7W.js";import{parseArgs,resolveSessionRuntime}from"./chunk-MH2BFYGN.js";import*as crypto from"node:crypto";var CUSTOM_UNSUPPORTED_CAPABILITY="custom_unsupported",EXTENSION_EVENTS_CAPABILITY="extension_events",AUTO_TITLE_SESSIONS_CAPABILITY="auto_title_sessions",CONTINUE_FROM_LEAF_CAPABILITY="continue_from_leaf",MEDIA_PLACEHOLDERS_CAPABILITY="media_placeholders",QUESTION_CAPABILITY="question",RETAIN_ON_DISCONNECT_CAPABILITY="retain_on_disconnect",SESSION_CONTEXT_CAPABILITY="session_context",SESSION_KIND_CAPABILITY="session_kind",AUTO_TITLE_PER_SESSION_CAPABILITY="auto_title_per_session",WARM_CAPABILITY="warm",DURABLE_SESSION_ID_CAPABILITY="durable_session_id",PROMPT_SURFACE_CAPABILITY="prompt_surface",BROWSER_ENGINE_CAPABILITY="browser_engine",RETRY_FALLBACK_PROFILE_CAPABILITY="retry_fallback_profile",RETRY_FALLBACK_COMMAND_CAPABILITY="retry_fallback_command",PROMPT_SURFACE_CHAT_CAPABILITY="prompt_surface_chat",RPC_CLIENT_CAPABILITIES_ENV="SENPI_RPC_CLIENT_CAPABILITIES";function parseClientCapabilities(value){return value?value.split(",").map(part=>part.trim()).filter(part=>part.length>0):[]}var DEFAULT_CUSTOM_EXTENSION_LABEL="custom UI component";function buildCustomUnsupportedRequest(capabilities,extensionName){if(!capabilities?.includes(CUSTOM_UNSUPPORTED_CAPABILITY))return;let name=extensionName.trim()||DEFAULT_CUSTOM_EXTENSION_LABEL;return{type:"extension_ui_request",id:crypto.randomUUID(),method:"custom_unsupported",extensionName:name}}import{createHash,randomUUID as randomUUID2}from"node:crypto";import{resolve}from"node:path";var INSTANCE_ID=resolveInstanceId(process.env[HOST_INSTANCE_ID_ENV]);function resolveInstanceId(value){return value!==void 0&&value.trim()!==""?value:randomUUID2()}function hostInstanceId(){return INSTANCE_ID}var cachedProfile;function hostGeneration(env){let value=env[HOST_GENERATION_ENV];return value!==void 0&&/^\d+$/.test(value)?Number(value):0}function hostLaunchProfile(argv,cwd){let parsed=parseArgs([...argv],{grokNeoEnabled:!1}),core={extensions:[...new Set((parsed.extensions??[]).map(path=>resolve(cwd,path)))].sort(),multi_session:parsed.multiSession===!0,session_runtime:resolveSessionRuntime(parsed)},canonical=JSON.stringify({extensions:core.extensions,multi_session:core.multi_session,session_runtime:core.session_runtime});return{profile_id:createHash("sha256").update(canonical).digest("hex"),core}}function socketHostLaunchProfile(hostArgs,cwd){return hostLaunchProfile(["--mode","rpc","--multi-session","--listen","unix://",...hostArgs],cwd)}function protocolIdentity(){cachedProfile??=hostLaunchProfile(process.argv.slice(2),process.cwd());let build=engineBuildIdentity();return{instanceId:INSTANCE_ID,generation:hostGeneration(process.env),engineVersion:build.text,engineOrdinal:build.ordinal,launch_profile:cachedProfile}}export{CUSTOM_UNSUPPORTED_CAPABILITY,EXTENSION_EVENTS_CAPABILITY,AUTO_TITLE_SESSIONS_CAPABILITY,CONTINUE_FROM_LEAF_CAPABILITY,MEDIA_PLACEHOLDERS_CAPABILITY,QUESTION_CAPABILITY,RETAIN_ON_DISCONNECT_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,AUTO_TITLE_PER_SESSION_CAPABILITY,WARM_CAPABILITY,DURABLE_SESSION_ID_CAPABILITY,PROMPT_SURFACE_CAPABILITY,BROWSER_ENGINE_CAPABILITY,RETRY_FALLBACK_PROFILE_CAPABILITY,RETRY_FALLBACK_COMMAND_CAPABILITY,PROMPT_SURFACE_CHAT_CAPABILITY,RPC_CLIENT_CAPABILITIES_ENV,parseClientCapabilities,DEFAULT_CUSTOM_EXTENSION_LABEL,buildCustomUnsupportedRequest,hostInstanceId,hostGeneration,hostLaunchProfile,socketHostLaunchProfile,protocolIdentity};
|
|
@@ -108,7 +108,7 @@ Please report this to https://github.com/markedjs/marked.`,e){let i="<p>An error
|
|
|
108
108
|
`&&isWarpWslSession(env,platform,socketExists)?NATIVE_SHIFT_ENTER_SEQUENCE:data}function keyboardEnhancementEnabled(){let value=process.env.PI_TUI_KEYBOARD_PROTOCOL;return value===void 0?!0:!["0","false","no","off"].includes(value.toLowerCase())}function isDeadTerminalError(error){if(!(error instanceof Error))return!1;if("code"in error&&typeof error.code=="string")return DEAD_TERMINAL_ERROR_CODES.has(error.code);if("errno"in error&&error.errno===EIO_ERRNO)return!0;let messageErrno=ERRNO_IN_MESSAGE_PATTERN.exec(error.message);return messageErrno?DEAD_TERMINAL_ERRNOS.has(Number.parseInt(messageErrno[1],10)):!1}var STDIN_ERROR_HANDLER_GRACE_MS=250,stdinErrorSubscribers=new Set;function isTerminalDetachStdinError(err){if(err.code==="EIO")return!0;let errno=err.errno;return errno===EIO_ERRNO||errno===-EIO_ERRNO}var dispatchStdinError=err=>{if(!isTerminalDetachStdinError(err)){if(!process.stdin.listeners("error").some(listener=>listener!==dispatchStdinError))throw err;return}for(let subscriber of stdinErrorSubscribers)subscriber(err)};function subscribeToStdinErrors(subscriber){stdinErrorSubscribers.size===0&&process.stdin.on("error",dispatchStdinError),stdinErrorSubscribers.add(subscriber)}function unsubscribeFromStdinErrors(subscriber){stdinErrorSubscribers.delete(subscriber),stdinErrorSubscribers.size===0&&process.stdin.removeListener("error",dispatchStdinError)}var DEFAULT_ESCAPE_TIMEOUT_MS2=10,DEFAULT_SSH_ESCAPE_TIMEOUT_MS=100,DEFAULT_BURST_WINDOW_MS2=20,DEFAULT_SSH_BURST_WINDOW_MS=100;function resolveEscapeTimeoutMs(env=process.env){let configured=Number(env.PI_TUI_ESC_TIMEOUT);return Number.isFinite(configured)&&configured>0?configured:env.SSH_CONNECTION||env.SSH_TTY?DEFAULT_SSH_ESCAPE_TIMEOUT_MS:DEFAULT_ESCAPE_TIMEOUT_MS2}function resolveBurstWindowMs(env=process.env){let raw=env.PI_TUI_BURST_WINDOW_MS?.trim();if(raw!==void 0&&raw.length>0){let configured=Number(raw);if(Number.isFinite(configured)&&configured>=0)return configured}return env.SSH_CONNECTION||env.SSH_TTY?DEFAULT_SSH_BURST_WINDOW_MS:DEFAULT_BURST_WINDOW_MS2}var ProcessTerminal=class{constructor(options){this.wasRaw=!1,this.externalWriteObservers=new Set,this.keyboardNegotiationSettled=!1,this.cursorQueryTimedOut=!1,this.forwardingExternalWrite=!1,this._kittyProtocolActive=!1,this._modifyOtherKeysActive=!1,this.keyboardProtocolPushed=!1,this.pendingKeyboardProtocolDeviceAttributes=0,this.keyboardProtocolNegotiationBuffer="",this.discardingPrivateResponse=!1,this.writeLogPath=(()=>{let env=process.env.PI_TUI_WRITE_LOG||"";if(!env)return"";try{if(fs2.statSync(env).isDirectory()){let now=new Date,ts=`${now.getFullYear()}-${String(now.getMonth()+1).padStart(2,"0")}-${String(now.getDate()).padStart(2,"0")}_${String(now.getHours()).padStart(2,"0")}-${String(now.getMinutes()).padStart(2,"0")}-${String(now.getSeconds()).padStart(2,"0")}`;return path3.join(env,`tui-${ts}-${process.pid}.log`)}}catch{}return env})(),this.onExternalStdoutWrite=options?.onExternalStdoutWrite,this.observeExternalStderrWrites=options?.observeExternalStderrWrites??observeProcessStderrWrites,this.tmuxExecFile=options?.tmuxExecFile}get kittyProtocolActive(){return this._kittyProtocolActive}queryCursorPosition(){if(this.cursorQuery)return this.cursorQuery.promise;if(!this.inputHandler||this.cursorQueryTimedOut)return Promise.resolve(void 0);let resolve,promise=new Promise(settle=>{resolve=settle}),timer=setTimeout(()=>{this.cursorQueryTimedOut=!0,this.settleCursorQuery(void 0)},750);return this.cursorQuery={promise,resolve,timer,issued:!1,tmuxPane:process.env.TMUX_PANE,deadline:Date.now()+750},this.issueCursorQuery(),promise}issueCursorQuery(){if(!this.keyboardNegotiationSettled||!this.cursorQuery||this.cursorQuery.issued)return;this.cursorQuery.issued=!0,this.rawWrite("\x1B[?6n");let pending=this.cursorQuery;pending?.tmuxPane!==void 0&&queryTmuxCursorPosition(pending.tmuxPane,pending.deadline,this.tmuxExecFile).then(position=>{this.cursorQuery===pending&&(Date.now()>=pending.deadline&&(this.cursorQueryTimedOut=!0),this.settleCursorQuery(this.cursorQueryTimedOut?void 0:position))})}settleCursorQuery(position){let pending=this.cursorQuery;pending&&(this.cursorQuery=void 0,clearTimeout(pending.timer),pending.resolve(position))}observeExternalWrites(listener){return this.externalWriteObservers.add(listener),this.inputHandler&&(this.installExternalStdoutGuard(),this.installExternalStderrObserver()),()=>{this.externalWriteObservers.delete(listener)}}noteExternalWrite(){for(let listener of this.externalWriteObservers)listener()}installExternalStderrObserver(){this.stopExternalStderrObservation||this.externalWriteObservers.size===0||(this.stopExternalStderrObservation=this.observeExternalStderrWrites(()=>this.noteExternalWrite()))}rawWrite(data){if(this.rawStdoutWrite){this.rawStdoutWrite(data);return}process.stdout.write(data)}installExternalStdoutGuard(){let handler=this.onExternalStdoutWrite;if(!handler&&this.externalWriteObservers.size===0||this.originalStdoutWrite)return;this.originalStdoutWrite=process.stdout.write;let rawWrite=process.stdout.write.bind(process.stdout);this.rawStdoutWrite=rawWrite,process.stdout.write=((chunk,encodingOrCallback,callback)=>{let cb=typeof encodingOrCallback=="function"?encodingOrCallback:callback,encoding=typeof encodingOrCallback=="string"?encodingOrCallback:void 0,text=typeof chunk=="string"?chunk:Buffer.from(chunk).toString(encoding);if(!handler||this.forwardingExternalWrite)return this.noteExternalWrite(),rawWrite(text),cb?.(null),!0;this.forwardingExternalWrite=!0;try{handler(text)}catch{this.noteExternalWrite(),rawWrite(text)}finally{this.forwardingExternalWrite=!1}return cb?.(null),!0})}removeExternalStdoutGuard(){this.originalStdoutWrite&&(process.stdout.write=this.originalStdoutWrite,this.originalStdoutWrite=void 0,this.rawStdoutWrite=void 0)}get modifyOtherKeysActive(){return this._modifyOtherKeysActive}start(onInput,onResize){this.installExternalStdoutGuard(),this.installExternalStderrObserver(),this.keyboardNegotiationSettled=!keyboardEnhancementEnabled(),this.cursorQueryTimedOut=!1,this.discardingPrivateResponse=!1,this.inputHandler=onInput,this.resizeHandler=onResize,this.wasRaw=process.stdin.isRaw||!1,process.stdin.setRawMode&&process.stdin.setRawMode(!0),process.stdin.resume(),this.stdinErrorHandlerCleanupTimer&&(clearTimeout(this.stdinErrorHandlerCleanupTimer),this.stdinErrorHandlerCleanupTimer=void 0),this.stdinErrorHandler||(this.stdinErrorHandler=()=>{},subscribeToStdinErrors(this.stdinErrorHandler)),this.rawWrite("\x1B[?2004h"),process.stdout.on("resize",this.resizeHandler),refreshTerminalDimensions(),this.enableWindowsVTInput(),this.queryAndEnableKittyProtocol()}setupStdinBuffer(){this.stdinBuffer=new StdinBuffer({escapeTimeout:resolveEscapeTimeoutMs(),burstWindowMs:resolveBurstWindowMs()}),this.stdinBuffer.on("data",sequence=>{if(this.discardingPrivateResponse)if(sequence.startsWith("\x1B"))this.discardingPrivateResponse=!1;else{/[\x40-\x7e]/.test(sequence)&&(this.discardingPrivateResponse=!1);return}let negotiation=this.readKeyboardProtocolNegotiationSequence(sequence);if(negotiation==="pending"){this.scheduleKeyboardProtocolNegotiationBufferFlush();return}negotiation&&this.handleKeyboardProtocolNegotiationSequence(negotiation.parsed)||this.forwardInputSequence(negotiation?.sequence??sequence)}),this.stdinBuffer.on("paste",content=>{this.inputHandler&&this.inputHandler(`\x1B[200~${content}\x1B[201~`)}),this.stdinDataHandler=data=>{this.stdinBuffer.process(data)}}queryAndEnableKittyProtocol(){this.setupStdinBuffer(),process.stdin.on("data",this.stdinDataHandler),keyboardEnhancementEnabled()&&((process.env.TMUX!==void 0||process.env.TMUX_PANE!==void 0)&&this.enableModifyOtherKeys(),this.keyboardProtocolPushed=!0,this.pendingKeyboardProtocolDeviceAttributes+=1,this.clearKeyboardProtocolNegotiationBuffer(),this.rawWrite(KITTY_KEYBOARD_PROTOCOL_QUERY))}handleKeyboardProtocolNegotiationSequence(negotiationSequence){if(this.clearKeyboardProtocolNegotiationBuffer(),negotiationSequence.type==="cursor-position"){if(this.cursorQuery?.issued&&this.cursorQuery.tmuxPane===void 0){let{type:_type,...position}=negotiationSequence;this.settleCursorQuery(position)}return!0}if(negotiationSequence.type==="device-attributes"){if(this.pendingKeyboardProtocolDeviceAttributes===0)return!1;this.pendingKeyboardProtocolDeviceAttributes-=1}return this.keyboardNegotiationSettled=!0,this.issueCursorQuery(),negotiationSequence.type==="kitty-flags"?(negotiationSequence.flags!==0?(this.disableModifyOtherKeys(),this._kittyProtocolActive||(this._kittyProtocolActive=!0,setKittyProtocolActive(!0))):this.enableModifyOtherKeys(),!0):(this._kittyProtocolActive||this.enableModifyOtherKeys(),!0)}readKeyboardProtocolNegotiationSequence(sequence){if(this.keyboardProtocolNegotiationBuffer){let bufferedSequence=this.keyboardProtocolNegotiationBuffer+sequence,negotiationSequence2=parseKeyboardProtocolNegotiationSequence(bufferedSequence);if(negotiationSequence2)return this.clearKeyboardProtocolNegotiationBuffer(),{parsed:negotiationSequence2,sequence:bufferedSequence};if(isKeyboardProtocolNegotiationSequencePrefix(bufferedSequence))return this.setKeyboardProtocolNegotiationBuffer(bufferedSequence),"pending";this.flushKeyboardProtocolNegotiationBufferAsInput()}let negotiationSequence=parseKeyboardProtocolNegotiationSequence(sequence);if(negotiationSequence)return{parsed:negotiationSequence,sequence};if(isKeyboardProtocolNegotiationSequencePrefix(sequence))return this.setKeyboardProtocolNegotiationBuffer(sequence),"pending"}setKeyboardProtocolNegotiationBuffer(sequence){this.clearKeyboardProtocolNegotiationBufferFlushTimer(),this.keyboardProtocolNegotiationBuffer=sequence}clearKeyboardProtocolNegotiationBuffer(){this.clearKeyboardProtocolNegotiationBufferFlushTimer(),this.keyboardProtocolNegotiationBuffer=""}flushKeyboardProtocolNegotiationBufferAsInput(discardTail=!1){if(!this.keyboardProtocolNegotiationBuffer)return;let sequence=this.keyboardProtocolNegotiationBuffer;if(this.clearKeyboardProtocolNegotiationBuffer(),/^\x1b\[\?[\d;]*$/.test(sequence)){this.discardingPrivateResponse=discardTail;return}this.forwardInputSequence(sequence)}scheduleKeyboardProtocolNegotiationBufferFlush(){!this.keyboardProtocolNegotiationBuffer||this.keyboardProtocolBufferFlushTimer||(this.keyboardProtocolBufferFlushTimer=setTimeout(()=>{this.keyboardProtocolBufferFlushTimer=void 0,this.flushKeyboardProtocolNegotiationBufferAsInput(!0)},KEYBOARD_PROTOCOL_RESPONSE_FRAGMENT_TIMEOUT_MS))}clearKeyboardProtocolNegotiationBufferFlushTimer(){this.keyboardProtocolBufferFlushTimer&&(clearTimeout(this.keyboardProtocolBufferFlushTimer),this.keyboardProtocolBufferFlushTimer=void 0)}forwardInputSequence(sequence){if(!this.inputHandler)return;let shouldDetectNativeShiftEnter=sequence==="\r"&&(isAppleTerminalSession()||process.platform==="win32"),input=normalizeNativeShiftEnterInput(sequence,shouldDetectNativeShiftEnter,shouldDetectNativeShiftEnter&&isNativeModifierPressed("shift"));this.inputHandler(input)}enableModifyOtherKeys(){this._kittyProtocolActive||this._modifyOtherKeysActive||(this.rawWrite("\x1B[>4;2m"),this._modifyOtherKeysActive=!0)}disableModifyOtherKeys(){this._modifyOtherKeysActive&&(this.rawWrite("\x1B[>4;0m"),this._modifyOtherKeysActive=!1)}enableWindowsVTInput(){if(process.platform==="win32")try{getNativePlatformHelper()?.enableVirtualTerminalInput?.()}catch{}}async drainInput(maxMs=1e3,idleMs=50){let shouldDisableKittyProtocol=this.keyboardProtocolPushed||this._kittyProtocolActive;this.clearKeyboardProtocolNegotiationBuffer(),shouldDisableKittyProtocol&&(this.rawWrite("\x1B[<u"),this.keyboardProtocolPushed=!1,this._kittyProtocolActive=!1,setKittyProtocolActive(!1)),this.disableModifyOtherKeys();let previousHandler=this.inputHandler;this.inputHandler=void 0;let lastDataTime=Date.now(),onData=()=>{lastDataTime=Date.now()};process.stdin.on("data",onData);let endTime=Date.now()+maxMs;try{for(;;){let now=Date.now(),timeLeft=endTime-now;if(timeLeft<=0||now-lastDataTime>=idleMs)break;await new Promise(resolve=>setTimeout(resolve,Math.min(idleMs,timeLeft)))}}finally{process.stdin.removeListener("data",onData),this.inputHandler=previousHandler}}stop(){this.settleCursorQuery(void 0),this.stopExternalStderrObservation?.(),this.stopExternalStderrObservation=void 0,this.clearProgressInterval()&&this.rawWrite(TERMINAL_PROGRESS_CLEAR_SEQUENCE),this.rawWrite("\x1B[?2004l");let shouldDisableKittyProtocol=this.keyboardProtocolPushed||this._kittyProtocolActive;if(this.clearKeyboardProtocolNegotiationBuffer(),shouldDisableKittyProtocol&&(this.rawWrite("\x1B[<u"),this.keyboardProtocolPushed=!1,this._kittyProtocolActive=!1,setKittyProtocolActive(!1)),this.disableModifyOtherKeys(),this.stdinBuffer&&(this.stdinBuffer.destroy(),this.stdinBuffer=void 0),this.stdinDataHandler&&(process.stdin.removeListener("data",this.stdinDataHandler),this.stdinDataHandler=void 0),this.inputHandler=void 0,this.resizeHandler&&(process.stdout.removeListener("resize",this.resizeHandler),this.resizeHandler=void 0),process.stdin.pause(),process.stdin.setRawMode)try{process.stdin.setRawMode(this.wasRaw)}catch(error){if(!isDeadTerminalError(error))throw error}this.removeExternalStdoutGuard(),this.scheduleStdinErrorHandlerCleanup()}scheduleStdinErrorHandlerCleanup(){if(!this.stdinErrorHandler||this.stdinErrorHandlerCleanupTimer)return;let handler=this.stdinErrorHandler;this.stdinErrorHandlerCleanupTimer=setTimeout(()=>{this.stdinErrorHandlerCleanupTimer=void 0,this.stdinErrorHandler===handler&&(this.stdinErrorHandler=void 0,unsubscribeFromStdinErrors(handler))},STDIN_ERROR_HANDLER_GRACE_MS),this.stdinErrorHandlerCleanupTimer.unref()}write(data){if(this.rawWrite(data),this.writeLogPath)try{fs2.appendFileSync(this.writeLogPath,data,{encoding:"utf8"})}catch{}}get columns(){return process.stdout.columns||Number(process.env.COLUMNS)||80}get rows(){return process.stdout.rows||Number(process.env.LINES)||24}moveBy(lines){lines>0?this.rawWrite(`\x1B[${lines}B`):lines<0&&this.rawWrite(`\x1B[${-lines}A`)}hideCursor(){this.rawWrite("\x1B[?25l")}showCursor(){this.rawWrite("\x1B[?25h")}clearLine(){this.rawWrite("\x1B[K")}clearFromCursor(){this.rawWrite("\x1B[J")}clearScreen(){this.rawWrite("\x1B[2J\x1B[H")}setTitle(title){let sanitizedTitle=title.replace(/[\u0000-\u001f\u007f-\u009f]/g,"");this.rawWrite(`\x1B]0;${sanitizedTitle}\x07`)}setProgress(active){active?(this.rawWrite(TERMINAL_PROGRESS_ACTIVE_SEQUENCE),this.progressInterval||(this.progressInterval=setInterval(()=>{this.rawWrite(TERMINAL_PROGRESS_ACTIVE_SEQUENCE)},TERMINAL_PROGRESS_KEEPALIVE_MS))):(this.clearProgressInterval(),this.rawWrite(TERMINAL_PROGRESS_CLEAR_SEQUENCE))}clearProgressInterval(){return this.progressInterval?(clearInterval(this.progressInterval),this.progressInterval=void 0,!0):!1}};var FAKE_CURSOR_END2="\x1B[7m \x1B[0m";function clampMentions(mentions,length){return mentions.map(range=>({start:Math.max(0,range.start),end:Math.min(length,range.end)})).filter(range=>range.start<range.end)}function cutPoints(length,mentions,cursorGlyph){let cuts=new Set([0,length]);for(let range of mentions)cuts.add(range.start),cuts.add(range.end);return cursorGlyph&&(cuts.add(cursorGlyph.start),cuts.add(cursorGlyph.end)),[...cuts].sort((left,right)=>left-right)}function renderEditorLine(input){let{text,cursor}=input,mentions=clampMentions(input.mentions,text.length),cursorInText=cursor!==void 0&&cursor.pos<text.length,cursorGlyph=cursorInText&&cursor.drawFakeCursor?{start:cursor.pos,end:cursor.pos+input.firstGrapheme(text.slice(cursor.pos)).length}:void 0,points=cutPoints(text.length,mentions,cursorGlyph),out="";for(let index=0;index<points.length-1;index++){let from=points[index]??0,to=points[index+1]??from;cursorInText&&from===cursor.pos&&(out+=cursor.marker);let segment=text.slice(from,to);cursorGlyph&&from===cursorGlyph.start?out+=`\x1B[7m${segment}\x1B[0m`:mentions.some(range=>from>=range.start&&to<=range.end)?out+=input.mentionStyle(segment):out+=segment}return cursor!==void 0&&!cursorInText&&(out+=cursor.marker,cursor.drawFakeCursor)?{text:out+FAKE_CURSOR_END2,cursorAppended:!0}:{text:out,cursorAppended:!1}}var graphemeSegmenter2=getGraphemeSegmenter(),wordSegmenter4=getWordSegmenter();function isAtomicMarker(segment){return isPasteMarker(segment)||isImageMarker(segment)}function markerKind(segment){if(isPasteMarker(segment))return"paste";if(isImageMarker(segment))return"image"}function containsMarkerPrefix(text){return text.includes("[paste #")||text.includes("[Image #")}function isPrintableAsciiText(text){for(let i=0;i<text.length;i++){let code=text.charCodeAt(i);if(code<32||code>126)return!1}return!0}function wordWrapAsciiLine(line,maxWidth){if(line.length<=maxWidth)return[{text:line,startIndex:0,endIndex:line.length}];let chunks=[],chunkStart=0;for(;chunkStart<line.length;){let chunkEnd=Math.min(line.length,chunkStart+maxWidth);if(chunkEnd<line.length){let breakAt=-1;for(let i=chunkEnd;i>chunkStart;i--){let code=line.charCodeAt(i-1);if(code===32||code===9){breakAt=i-1;break}}breakAt>chunkStart&&(chunkEnd=breakAt)}let raw=line.slice(chunkStart,chunkEnd),text=raw.trimEnd();for((text||chunks.length===0)&&chunks.push({text,startIndex:chunkStart,endIndex:chunkStart+raw.length}),chunkStart=chunkEnd;chunkStart<line.length;){let code=line.charCodeAt(chunkStart);if(code!==32&&code!==9)break;chunkStart++}}return chunks.length>0?chunks:[{text:"",startIndex:0,endIndex:0}]}function wordWrapLine(line,maxWidth,preSegmented){if(!line||maxWidth<=0)return[{text:"",startIndex:0,endIndex:0}];if(preSegmented===void 0&&!/\s/.test(line)&&!containsMarkerPrefix(line)&&isPrintableAsciiText(line))return wordWrapAsciiLine(line,maxWidth);if(visibleWidth(line)<=maxWidth)return[{text:line,startIndex:0,endIndex:line.length}];let chunks=[],segments=preSegmented??[...graphemeSegmenter2.segment(line)],currentWidth=0,chunkStart=0,wrapOppIndex=-1,wrapOppWidth=0;for(let i=0;i<segments.length;i++){let seg=segments[i],grapheme=seg.segment,gWidth=visibleWidth(grapheme),charIndex=seg.index,isWs=!isAtomicMarker(grapheme)&&isWhitespaceChar(grapheme);if(currentWidth+gWidth>maxWidth&&(wrapOppIndex>=0&¤tWidth-wrapOppWidth+gWidth<=maxWidth?(chunks.push({text:line.slice(chunkStart,wrapOppIndex),startIndex:chunkStart,endIndex:wrapOppIndex}),chunkStart=wrapOppIndex,currentWidth-=wrapOppWidth):chunkStart<charIndex&&(chunks.push({text:line.slice(chunkStart,charIndex),startIndex:chunkStart,endIndex:charIndex}),chunkStart=charIndex,currentWidth=0),wrapOppIndex=-1),gWidth>maxWidth){let subChunks=wordWrapLine(grapheme,maxWidth);for(let j=0;j<subChunks.length-1;j++){let sc=subChunks[j];chunks.push({text:sc.text,startIndex:charIndex+sc.startIndex,endIndex:charIndex+sc.endIndex})}let last=subChunks[subChunks.length-1];chunkStart=charIndex+last.startIndex,currentWidth=visibleWidth(last.text),wrapOppIndex=-1;continue}currentWidth+=gWidth;let next=segments[i+1];if(isWs&&next&&(isAtomicMarker(next.segment)||!isWhitespaceChar(next.segment)))wrapOppIndex=next.index,wrapOppWidth=currentWidth;else if(!isWs&&next&&!isWhitespaceChar(next.segment)){let isCjk=!isAtomicMarker(grapheme)&&cjkBreakRegex.test(grapheme),nextIsCjk=!isAtomicMarker(next.segment)&&cjkBreakRegex.test(next.segment);(isCjk||nextIsCjk)&&(wrapOppIndex=next.index,wrapOppWidth=currentWidth)}}return chunks.push({text:line.slice(chunkStart),startIndex:chunkStart,endIndex:line.length}),chunks}var SLASH_COMMAND_SELECT_LIST_LAYOUT={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},ATTACHMENT_AUTOCOMPLETE_DEBOUNCE_MS=20,DEFAULT_AUTOCOMPLETE_TRIGGER_CHARACTERS=["@","#","$"],unquotedAutocompleteSuffixRegex=new RegExp(`(?:(?!${autocompleteSeparatorRegex.source}).)*`,"u"),autocompleteTokenStartSource=`${autocompleteBoundaryRegex.source}[([{<\`]*`;function escapeCharacterClass(value){return value.replace(/[\\^$.*+?()[\]{}|-]/g,"\\$&")}function buildTriggerPattern(triggerCharacters){return new RegExp(`${autocompleteTokenStartSource}(?:@"[^"]*|[${triggerCharacters.map(escapeCharacterClass).join("")}]${unquotedAutocompleteSuffixRegex.source})$`,"u")}function buildDebouncePattern(triggerCharacters){let escapedWithoutAt=triggerCharacters.filter(character=>character!=="@").map(escapeCharacterClass);return new RegExp(`${autocompleteTokenStartSource}(?:@(?:"[^"]*|${unquotedAutocompleteSuffixRegex.source})|[${escapedWithoutAt.join("")}]${unquotedAutocompleteSuffixRegex.source})$`,"u")}function createScrollBorder(direction,hiddenLineCount,width){let availableWidth=Math.max(0,width),label=` ${direction} ${hiddenLineCount} more `,labelWidth=visibleWidth(label);if(labelWidth+2<=availableWidth){let leftWidth=Math.floor((availableWidth-labelWidth)/2);return"\u2500".repeat(leftWidth)+label+"\u2500".repeat(availableWidth-leftWidth-labelWidth)}let indicator=`\u2500\u2500\u2500 ${direction} ${hiddenLineCount} more `,remaining=availableWidth-visibleWidth(indicator);if(remaining>=0)return indicator+"\u2500".repeat(remaining);let ellipsis="...".slice(0,availableWidth),indicatorWidth=availableWidth-visibleWidth(ellipsis);return sliceByColumn(indicator,0,indicatorWidth,!0)+ellipsis}var Editor=class{constructor(tui,theme,options={}){this.state={lines:[""],cursorLine:0,cursorCol:0},this.focused=!1,this.paddingX=0,this.lastWidth=80,this.renderedVisibleLineCount=1,this.renderedAutocompleteHeight=0,this.scrollOffset=0,this.autocompleteTriggerCharacters=[...DEFAULT_AUTOCOMPLETE_TRIGGER_CHARACTERS],this.autocompleteTriggerPattern=buildTriggerPattern(this.autocompleteTriggerCharacters),this.autocompleteDebouncePattern=buildDebouncePattern(this.autocompleteTriggerCharacters),this.autocompleteState=null,this.autocompletePrefix="",this.autocompleteItems=[],this.autocompleteMaxVisible=5,this.autocompleteRequestTask=Promise.resolve(),this.autocompleteStartToken=0,this.autocompleteRequestId=0,this.pasteMarkers=new PasteMarkerRegistry,this.imageMarkers=new ImageMarkerRegistry,this.pasteBuffer="",this.isInPaste=!1,this.history=[],this.historyIndex=-1,this.historyDraft=null,this.killRing=new KillRing,this.lastAction=null,this.jumpMode=null,this.preferredVisualCol=null,this.snappedFromCursorCol=null,this.undoStack=new UndoStack,this.wrappedLineCache=[],this.disableSubmit=!1,this.tui=tui,this.theme=theme,this.borderColor=theme.borderColor;let paddingX=options.paddingX??0;this.paddingX=Number.isFinite(paddingX)?Math.max(0,Math.floor(paddingX)):0,this.terminalEnvironment=options.terminalEnvironment,this.terminalPlatform=options.terminalPlatform,this.terminalSocketExists=options.terminalSocketExists;let maxVisible=options.autocompleteMaxVisible??5;this.autocompleteMaxVisible=Number.isFinite(maxVisible)?Math.max(3,Math.min(20,Math.floor(maxVisible))):5}segment(text,mode){return segmentWithMarkers(text,mode==="word"?wordSegmenter4:graphemeSegmenter2,this.authorizedMarkers(text))}authorizedMarkers(text){let imageMarkers=this.imageMarkers.authorizedMarkers(text);if(imageMarkers.size===0)return this.pasteMarkers.authorizedMarkers(text);let merged=new Set(this.pasteMarkers.authorizedMarkers(text));for(let marker of imageMarkers)merged.add(marker);return merged}removePasteMarker(id){let removal=this.pasteMarkers.remove(id,this.getText());return removal.removed?(this.state.lines=removal.text.split(`
|
|
109
109
|
`),!0):!1}removeImageMarker(id){let survivors=this.imageMarkers.ids(this.getText()).filter(entryId=>entryId!==id),removal=this.imageMarkers.remove(id,this.getText());return removal.removed?(this.state.lines=removal.text.split(`
|
|
110
110
|
`),this.onImageMarkersChanged?.(survivors),!0):!1}removeMarkerSegment(segment){switch(markerKind(segment)){case"paste":{let id=pasteMarkerId(segment);return id!==void 0&&this.removePasteMarker(id)}case"image":{let id=imageMarkerId(segment);return id!==void 0&&this.removeImageMarker(id)}default:return!1}}notifyImageMarkersChanged(){this.onImageMarkersChanged?.(this.imageMarkers.ids(this.getText()))}getPaddingX(){return this.paddingX}setPaddingX(padding){let newPadding=Number.isFinite(padding)?Math.max(0,Math.floor(padding)):0;this.paddingX!==newPadding&&(this.paddingX=newPadding,this.tui.requestRender())}getAutocompleteMaxVisible(){return this.autocompleteMaxVisible}setAutocompleteMaxVisible(maxVisible){let newMaxVisible=Number.isFinite(maxVisible)?Math.max(3,Math.min(20,Math.floor(maxVisible))):5;this.autocompleteMaxVisible!==newMaxVisible&&(this.autocompleteMaxVisible=newMaxVisible,this.tui.requestRender())}setAutocompleteProvider(provider){this.cancelAutocomplete(),this.autocompleteProvider=provider,this.setAutocompleteTriggerCharacters(provider.triggerCharacters??[])}addToHistory(text){let trimmed=text.trim();trimmed&&(this.history.length>0&&this.history[0]===trimmed||(this.history.unshift(trimmed),this.history.length>100&&this.history.pop()))}isEditorEmpty(){return this.state.lines.length===1&&this.state.lines[0]===""}isOnFirstVisualLine(){let visualLines=this.buildVisualLineMap(this.lastWidth);return this.findCurrentVisualLine(visualLines)===0}isOnLastVisualLine(){let visualLines=this.buildVisualLineMap(this.lastWidth);return this.findCurrentVisualLine(visualLines)===visualLines.length-1}navigateHistory(direction){if(this.lastAction=null,this.history.length===0)return;let newIndex=this.historyIndex-direction;if(!(newIndex<-1||newIndex>=this.history.length))if(this.historyIndex===-1&&newIndex>=0&&(this.pushUndoSnapshot(),this.historyDraft=structuredClone(this.state)),this.historyIndex=newIndex,this.historyIndex===-1){let draft=this.historyDraft;this.historyDraft=null,draft?(this.state=draft,this.preferredVisualCol=null,this.snappedFromCursorCol=null,this.scrollOffset=0,this.onChange&&this.onChange(this.getText())):this.setTextInternal("")}else this.setTextInternal(this.history[this.historyIndex]||"",direction===-1?"start":"end")}exitHistoryBrowsing(){this.historyIndex=-1,this.historyDraft=null}setTextInternal(text,cursorPlacement="end"){let lines=text.split(`
|
|
111
|
-
`);this.state.lines=lines.length===0?[""]:lines,this.state.cursorLine=cursorPlacement==="start"?0:this.state.lines.length-1,this.setCursorCol(cursorPlacement==="start"?0:this.state.lines[this.state.cursorLine]?.length||0),this.scrollOffset=0,this.onChange&&this.onChange(this.getText())}invalidate(){this.wrappedLineCache.length=0}getWrappedLine(lineIndex,contentWidth){let line=this.state.lines[lineIndex]||"",cached=this.wrappedLineCache[lineIndex];if(cached&&cached.lineRef===line&&cached.contentWidth===contentWidth)return cached;let width=isPrintableAsciiText(line)?line.length:visibleWidth(line);if(containsMarkerPrefix(line))return{width,chunks:width<=contentWidth?[{text:line,startIndex:0,endIndex:line.length}]:wordWrapLine(line,contentWidth,[...this.segment(line,"grapheme")])};let wrapped={lineRef:line,contentWidth,width,chunks:width<=contentWidth?[{text:line,startIndex:0,endIndex:line.length}]:wordWrapLine(line,contentWidth)};return this.wrappedLineCache[lineIndex]=wrapped,wrapped}renderTopBorder(width,hiddenLineCount){let border=hiddenLineCount>0?createScrollBorder("\u2191",hiddenLineCount,width):"\u2500".repeat(width);return this.borderColor(border)}renderBottomBorder(width,hiddenLineCount){let border=hiddenLineCount>0?createScrollBorder("\u2193",hiddenLineCount,width):"\u2500".repeat(width);return this.borderColor(border)}render(width){let maxPadding=Math.max(0,Math.floor((width-1)/2)),paddingX=Math.min(this.paddingX,maxPadding),contentWidth=Math.max(1,width-paddingX*2),layoutWidth=Math.max(1,contentWidth-(paddingX?0:1));this.lastWidth=layoutWidth;let layoutLines=this.layoutText(layoutWidth),terminalRows=this.tui.terminal.rows,maxVisibleLines=Math.max(5,Math.floor(terminalRows*.3)),cursorLineIndex=layoutLines.findIndex(line=>line.hasCursor);cursorLineIndex===-1&&(cursorLineIndex=0),cursorLineIndex<this.scrollOffset?this.scrollOffset=cursorLineIndex:cursorLineIndex>=this.scrollOffset+maxVisibleLines&&(this.scrollOffset=cursorLineIndex-maxVisibleLines+1);let maxScrollOffset=Math.max(0,layoutLines.length-maxVisibleLines);this.scrollOffset=Math.max(0,Math.min(this.scrollOffset,maxScrollOffset));let visibleLines=layoutLines.slice(this.scrollOffset,this.scrollOffset+maxVisibleLines);this.renderedVisibleLineCount=visibleLines.length;let result=[],leftPadding=" ".repeat(paddingX),rightPadding=leftPadding;result.push(this.renderTopBorder(width,this.scrollOffset));let emitCursorMarker=this.focused,drawFakeCursor=!this.tui.getShowHardwareCursor(),mentionStyle=this.theme.mention,mentionRangesByLine=new Map,mentionRangesFor=layoutLine=>{if(!mentionStyle||!this.autocompleteProvider?.getMentionRanges)return[];let ranges=mentionRangesByLine.get(layoutLine.logicalLine);return ranges===void 0&&(ranges=this.autocompleteProvider.getMentionRanges(this.state.lines[layoutLine.logicalLine]??""),mentionRangesByLine.set(layoutLine.logicalLine,ranges)),ranges.map(range=>({start:range.start-layoutLine.startIndex,end:range.end-layoutLine.startIndex}))};for(let layoutLine of visibleLines){let lineVisibleWidth=visibleWidth(layoutLine.text),cursorInPadding=!1,cursor=layoutLine.hasCursor&&layoutLine.cursorPos!==void 0?{pos:layoutLine.cursorPos,marker:emitCursorMarker?CURSOR_MARKER:"",drawFakeCursor}:void 0,rendered=renderEditorLine({text:layoutLine.text,mentions:mentionRangesFor(layoutLine),mentionStyle:mentionStyle??(text=>text),cursor,firstGrapheme:text=>[...this.segment(text,"grapheme")][0]?.segment??""}),displayText=rendered.text;rendered.cursorAppended&&(lineVisibleWidth=lineVisibleWidth+1,lineVisibleWidth>contentWidth&&paddingX>0&&(cursorInPadding=!0));let padding=" ".repeat(Math.max(0,contentWidth-lineVisibleWidth)),lineRightPadding=cursorInPadding?rightPadding.slice(1):rightPadding;result.push(`${leftPadding}${displayText}${padding}${lineRightPadding}`)}let linesBelow=layoutLines.length-(this.scrollOffset+visibleLines.length);if(result.push(this.renderBottomBorder(width,linesBelow)),this.renderedAutocompleteHeight=0,this.autocompleteState&&this.autocompleteList){let autocompleteResult=this.autocompleteList.render(contentWidth);this.renderedAutocompleteHeight=autocompleteResult.length;for(let line of autocompleteResult){let lineWidth=visibleWidth(line),linePadding=" ".repeat(Math.max(0,contentWidth-lineWidth));result.push(`${leftPadding}${line}${linePadding}${rightPadding}`)}}return result}handleMouse(event){let autocompleteStartRow=this.renderedVisibleLineCount+2;if(this.autocompleteState&&this.autocompleteList&&event.y>=autocompleteStartRow&&event.y<autocompleteStartRow+this.renderedAutocompleteHeight){let maxPadding2=Math.max(0,Math.floor((event.width-1)/2)),paddingX2=Math.min(this.paddingX,maxPadding2),contentWidth=Math.max(1,event.width-paddingX2*2),result=this.autocompleteList.handleMouse?.({...event,x:event.x-paddingX2,y:event.y-autocompleteStartRow,width:contentWidth,height:this.renderedAutocompleteHeight});return result?{...result,focus:!0}:void 0}if(event.type!=="click"||event.button!=="left")return;if(event.y<=0||event.y>this.renderedVisibleLineCount)return{handled:!0,focus:!0};let visualLines=this.buildVisualLineMap(this.lastWidth),visualLineIndex=this.scrollOffset+event.y-1,visualLine=visualLines[visualLineIndex];if(!visualLine)return{handled:!0,focus:!0};let logicalLine=this.state.lines[visualLine.logicalLine]??"",chunkEnd=visualLine.startCol+visualLine.length,chunk=logicalLine.slice(visualLine.startCol,chunkEnd),maxPadding=Math.max(0,Math.floor((event.width-1)/2)),paddingX=Math.min(this.paddingX,maxPadding),targetColumn=Math.max(0,event.x-paddingX),visibleColumn=0,targetIndex=chunk.length,lastGraphemeIndex=0;for(let grapheme of this.segment(chunk,"grapheme")){let nextColumn=visibleColumn+visibleWidth(grapheme.segment);if(lastGraphemeIndex=grapheme.index,targetColumn<nextColumn){targetIndex=grapheme.index;break}visibleColumn=nextColumn}return!(visualLineIndex===visualLines.length-1||visualLines[visualLineIndex+1]?.logicalLine!==visualLine.logicalLine)&&targetIndex===chunk.length&&chunk.length>0&&(targetIndex=lastGraphemeIndex),this.state.cursorLine=visualLine.logicalLine,this.setCursorCol(visualLine.startCol+targetIndex),this.lastAction=null,this.exitHistoryBrowsing(),this.autocompleteState&&this.updateAutocomplete(),{handled:!0,focus:!0}}handleInput(data){data=normalizeWarpWslShiftEnterInput(data,this.terminalEnvironment,this.terminalPlatform,this.terminalSocketExists);let kb=getKeybindings();if(this.jumpMode!==null){if(kb.matches(data,"tui.editor.jumpForward")||kb.matches(data,"tui.editor.jumpBackward")){this.jumpMode=null;return}let printable2=decodePrintableKey(data)??(data.charCodeAt(0)>=32?data:void 0);if(printable2!==void 0){let direction=this.jumpMode;this.jumpMode=null,this.jumpToChar(printable2,direction);return}this.jumpMode=null}if(data.includes("\x1B[200~")&&(this.isInPaste=!0,this.pasteBuffer="",data=data.replace("\x1B[200~","")),this.isInPaste){this.pasteBuffer+=data;let endIndex=this.pasteBuffer.indexOf("\x1B[201~");if(endIndex!==-1){let pasteContent=this.pasteBuffer.substring(0,endIndex);pasteContent.length>0&&this.handlePaste(pasteContent),this.isInPaste=!1;let remaining=this.pasteBuffer.substring(endIndex+6);this.pasteBuffer="",remaining.length>0&&this.handleInput(remaining);return}return}if(kb.matches(data,"tui.input.copy"))return;if(kb.matches(data,"tui.editor.undo")){this.undo();return}if(this.autocompleteState&&this.autocompleteList){if(kb.matches(data,"tui.select.cancel")){this.cancelAutocomplete();return}if(kb.matches(data,"tui.select.up")||kb.matches(data,"tui.select.down")){this.autocompleteList.handleInput(data);return}if(kb.matches(data,"tui.input.tab")){let selected=this.autocompleteList.getSelectedItem();if(selected&&this.autocompleteProvider){let drillsIntoNamespace=this.isSlashNamespaceSelection(selected.value);this.pushUndoSnapshot(),this.lastAction=null;let result=this.autocompleteProvider.applyCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol,selected,this.autocompletePrefix);this.state.lines=result.lines,this.state.cursorLine=result.cursorLine,this.setCursorCol(result.cursorCol),this.cancelAutocomplete(),this.onChange&&this.onChange(this.getText()),drillsIntoNamespace&&this.tryTriggerAutocomplete()}return}if(kb.matches(data,"tui.select.confirm")){let selected=this.autocompleteList.getSelectedItem();if(selected&&this.autocompleteProvider){let drillsIntoNamespace=this.isSlashNamespaceSelection(selected.value);this.pushUndoSnapshot(),this.lastAction=null;let result=this.autocompleteProvider.applyCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol,selected,this.autocompletePrefix);if(this.state.lines=result.lines,this.state.cursorLine=result.cursorLine,this.setCursorCol(result.cursorCol),drillsIntoNamespace){this.cancelAutocomplete(),this.onChange&&this.onChange(this.getText()),this.tryTriggerAutocomplete();return}if(this.autocompletePrefix.startsWith("/")){let awaitsArguments=this.autocompleteItems.some(item=>item===selected&&item.awaitsArguments===!0);if(this.cancelAutocomplete(),awaitsArguments){this.onChange&&this.onChange(this.getText());return}}else{this.cancelAutocomplete(),this.onChange&&this.onChange(this.getText());return}}}}if(kb.matches(data,"tui.input.tab")&&!this.autocompleteState){this.handleTabCompletion();return}if(kb.matches(data,"tui.editor.deleteToLineEnd")){this.deleteToEndOfLine();return}if(kb.matches(data,"tui.editor.deleteToLineStart")){this.deleteToStartOfLine();return}if(kb.matches(data,"tui.editor.deleteWordBackward")){this.deleteWordBackwards();return}if(kb.matches(data,"tui.editor.deleteWordForward")){this.deleteWordForward();return}if(kb.matches(data,"tui.editor.deleteCharBackward")||matchesKey(data,"shift+backspace")){this.handleBackspace();return}if(kb.matches(data,"tui.editor.deleteCharForward")||matchesKey(data,"shift+delete")){this.handleForwardDelete();return}if(kb.matches(data,"tui.editor.yank")){this.yank();return}if(kb.matches(data,"tui.editor.yankPop")){this.yankPop();return}if(kb.matches(data,"tui.editor.historyPrevious")){this.cancelAutocomplete(),this.navigateHistory(-1);return}if(kb.matches(data,"tui.editor.historyNext")){this.cancelAutocomplete(),this.navigateHistory(1);return}if(kb.matches(data,"tui.editor.cursorLineStart")){this.moveToLineStart();return}if(kb.matches(data,"tui.editor.cursorLineEnd")){this.moveToLineEnd();return}if(kb.matches(data,"tui.editor.cursorWordLeft")){this.moveWordBackwards();return}if(kb.matches(data,"tui.editor.cursorWordRight")){this.moveWordForwards();return}if(kb.matches(data,"tui.input.submit")){if(this.disableSubmit)return;let currentLine=this.state.lines[this.state.cursorLine]||"";if(this.state.cursorCol>0&¤tLine[this.state.cursorCol-1]==="\\"){this.handleBackspace(),this.addNewLine();return}this.submitValue();return}if(kb.matches(data,"tui.input.newLine")||data.charCodeAt(0)===10&&data.length>1||data==="\x1B\r"||data==="\x1B[13;2~"||data.length>1&&data.includes("\x1B")&&data.includes("\r")||data===`
|
|
111
|
+
`);this.state.lines=lines.length===0?[""]:lines,this.state.cursorLine=cursorPlacement==="start"?0:this.state.lines.length-1,this.setCursorCol(cursorPlacement==="start"?0:this.state.lines[this.state.cursorLine]?.length||0),this.scrollOffset=0,this.onChange&&this.onChange(this.getText())}invalidate(){this.wrappedLineCache.length=0}getWrappedLine(lineIndex,contentWidth){let line=this.state.lines[lineIndex]||"",cached=this.wrappedLineCache[lineIndex];if(cached&&cached.lineRef===line&&cached.contentWidth===contentWidth)return cached;let width=isPrintableAsciiText(line)?line.length:visibleWidth(line);if(containsMarkerPrefix(line))return{width,chunks:width<=contentWidth?[{text:line,startIndex:0,endIndex:line.length}]:wordWrapLine(line,contentWidth,[...this.segment(line,"grapheme")])};let wrapped={lineRef:line,contentWidth,width,chunks:width<=contentWidth?[{text:line,startIndex:0,endIndex:line.length}]:wordWrapLine(line,contentWidth)};return this.wrappedLineCache[lineIndex]=wrapped,wrapped}renderTopBorder(width,hiddenLineCount){let border=hiddenLineCount>0?createScrollBorder("\u2191",hiddenLineCount,width):"\u2500".repeat(width);return this.borderColor(border)}renderBottomBorder(width,hiddenLineCount){let border=hiddenLineCount>0?createScrollBorder("\u2193",hiddenLineCount,width):"\u2500".repeat(width);return this.borderColor(border)}render(width){let maxPadding=Math.max(0,Math.floor((width-1)/2)),paddingX=Math.min(this.paddingX,maxPadding),contentWidth=Math.max(1,width-paddingX*2),layoutWidth=Math.max(1,contentWidth-(paddingX?0:1));this.lastWidth=layoutWidth;let layoutLines=this.layoutText(layoutWidth),terminalRows=this.tui.terminal.rows,maxVisibleLines=Math.max(5,Math.floor(terminalRows*.3)),cursorLineIndex=layoutLines.findIndex(line=>line.hasCursor);cursorLineIndex===-1&&(cursorLineIndex=0),cursorLineIndex<this.scrollOffset?this.scrollOffset=cursorLineIndex:cursorLineIndex>=this.scrollOffset+maxVisibleLines&&(this.scrollOffset=cursorLineIndex-maxVisibleLines+1);let maxScrollOffset=Math.max(0,layoutLines.length-maxVisibleLines);this.scrollOffset=Math.max(0,Math.min(this.scrollOffset,maxScrollOffset));let visibleLines=layoutLines.slice(this.scrollOffset,this.scrollOffset+maxVisibleLines);this.renderedVisibleLineCount=visibleLines.length;let result=[],leftPadding=" ".repeat(paddingX),rightPadding=leftPadding;result.push(this.renderTopBorder(width,this.scrollOffset));let emitCursorMarker=this.focused,drawFakeCursor=!this.tui.getShowHardwareCursor(),mentionStyle=this.theme.mention,mentionRangesByLine=new Map,mentionRangesFor=layoutLine=>{if(!mentionStyle||!this.autocompleteProvider?.getMentionRanges)return[];let ranges=mentionRangesByLine.get(layoutLine.logicalLine);return ranges===void 0&&(ranges=this.autocompleteProvider.getMentionRanges(this.state.lines[layoutLine.logicalLine]??""),mentionRangesByLine.set(layoutLine.logicalLine,ranges)),ranges.map(range=>({start:range.start-layoutLine.startIndex,end:range.end-layoutLine.startIndex}))};for(let layoutLine of visibleLines){let lineVisibleWidth=visibleWidth(layoutLine.text),cursorInPadding=!1,cursor=layoutLine.hasCursor&&layoutLine.cursorPos!==void 0?{pos:layoutLine.cursorPos,marker:emitCursorMarker?CURSOR_MARKER:"",drawFakeCursor}:void 0,rendered=renderEditorLine({text:layoutLine.text,mentions:mentionRangesFor(layoutLine),mentionStyle:mentionStyle??(text=>text),cursor,firstGrapheme:text=>[...this.segment(text,"grapheme")][0]?.segment??""}),displayText=rendered.text;rendered.cursorAppended&&(lineVisibleWidth=lineVisibleWidth+1,lineVisibleWidth>contentWidth&&paddingX>0&&(cursorInPadding=!0));let padding=" ".repeat(Math.max(0,contentWidth-lineVisibleWidth)),lineRightPadding=cursorInPadding?rightPadding.slice(1):rightPadding;result.push(`${leftPadding}${displayText}${padding}${lineRightPadding}`)}let linesBelow=layoutLines.length-(this.scrollOffset+visibleLines.length);if(result.push(this.renderBottomBorder(width,linesBelow)),this.renderedAutocompleteHeight=0,this.autocompleteState&&this.autocompleteList){let autocompleteResult=this.autocompleteList.render(contentWidth);this.renderedAutocompleteHeight=autocompleteResult.length;for(let line of autocompleteResult){let lineWidth=visibleWidth(line),linePadding=" ".repeat(Math.max(0,contentWidth-lineWidth));result.push(`${leftPadding}${line}${linePadding}${rightPadding}`)}}return result}handleMouse(event){let autocompleteStartRow=this.renderedVisibleLineCount+2;if(this.autocompleteState&&this.autocompleteList&&event.y>=autocompleteStartRow&&event.y<autocompleteStartRow+this.renderedAutocompleteHeight){let maxPadding2=Math.max(0,Math.floor((event.width-1)/2)),paddingX2=Math.min(this.paddingX,maxPadding2),contentWidth=Math.max(1,event.width-paddingX2*2),result=this.autocompleteList.handleMouse?.({...event,x:event.x-paddingX2,y:event.y-autocompleteStartRow,width:contentWidth,height:this.renderedAutocompleteHeight});return result?{...result,focus:!0}:void 0}if(event.type!=="click"||event.button!=="left")return;if(event.y<=0||event.y>this.renderedVisibleLineCount)return{handled:!0,focus:!0};let visualLines=this.buildVisualLineMap(this.lastWidth),visualLineIndex=this.scrollOffset+event.y-1,visualLine=visualLines[visualLineIndex];if(!visualLine)return{handled:!0,focus:!0};let logicalLine=this.state.lines[visualLine.logicalLine]??"",chunkEnd=visualLine.startCol+visualLine.length,chunk=logicalLine.slice(visualLine.startCol,chunkEnd),maxPadding=Math.max(0,Math.floor((event.width-1)/2)),paddingX=Math.min(this.paddingX,maxPadding),targetColumn=Math.max(0,event.x-paddingX),visibleColumn=0,targetIndex=chunk.length,lastGraphemeIndex=0;for(let grapheme of this.segment(chunk,"grapheme")){let nextColumn=visibleColumn+visibleWidth(grapheme.segment);if(lastGraphemeIndex=grapheme.index,targetColumn<nextColumn){targetIndex=grapheme.index;break}visibleColumn=nextColumn}return!(visualLineIndex===visualLines.length-1||visualLines[visualLineIndex+1]?.logicalLine!==visualLine.logicalLine)&&targetIndex===chunk.length&&chunk.length>0&&(targetIndex=lastGraphemeIndex),this.state.cursorLine=visualLine.logicalLine,this.setCursorCol(visualLine.startCol+targetIndex),this.lastAction=null,this.exitHistoryBrowsing(),this.autocompleteState&&this.updateAutocomplete(),{handled:!0,focus:!0}}handleInput(data){data=normalizeWarpWslShiftEnterInput(data,this.terminalEnvironment,this.terminalPlatform,this.terminalSocketExists);let kb=getKeybindings();if(this.jumpMode!==null){if(kb.matches(data,"tui.editor.jumpForward")||kb.matches(data,"tui.editor.jumpBackward")){this.jumpMode=null;return}let printable2=decodePrintableKey(data)??(data.charCodeAt(0)>=32?data:void 0);if(printable2!==void 0){let direction=this.jumpMode;this.jumpMode=null,this.jumpToChar(printable2,direction);return}this.jumpMode=null}if(data.includes("\x1B[200~")&&(this.isInPaste=!0,this.pasteBuffer="",data=data.replace("\x1B[200~","")),this.isInPaste){this.pasteBuffer+=data;let endIndex=this.pasteBuffer.indexOf("\x1B[201~");if(endIndex!==-1){let pasteContent=this.pasteBuffer.substring(0,endIndex);pasteContent.length>0&&this.handlePaste(pasteContent),this.isInPaste=!1;let remaining=this.pasteBuffer.substring(endIndex+6);this.pasteBuffer="",remaining.length>0&&this.handleInput(remaining);return}return}if(kb.matches(data,"tui.input.copy"))return;if(kb.matches(data,"tui.editor.undo")){this.undo();return}if(this.autocompleteState&&this.autocompleteList){if(kb.matches(data,"tui.select.cancel")){this.cancelAutocomplete();return}if(kb.matches(data,"tui.select.up")||kb.matches(data,"tui.select.down")){this.autocompleteList.handleInput(data);return}if(kb.matches(data,"tui.input.tab")){if(this.isAutocompleteListStale()){this.acceptRefreshedAutocomplete();return}let selected=this.autocompleteList.getSelectedItem();if(selected&&this.autocompleteProvider){let drillsIntoNamespace=this.isSlashNamespaceSelection(selected.value);this.pushUndoSnapshot(),this.lastAction=null;let result=this.autocompleteProvider.applyCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol,selected,this.autocompletePrefix);this.state.lines=result.lines,this.state.cursorLine=result.cursorLine,this.setCursorCol(result.cursorCol),this.cancelAutocomplete(),this.onChange&&this.onChange(this.getText()),drillsIntoNamespace&&this.tryTriggerAutocomplete()}return}if(kb.matches(data,"tui.select.confirm")){if(!this.autocompletePrefix.startsWith("/")&&this.isAutocompleteListStale()){this.acceptRefreshedAutocomplete();return}let selected=this.autocompleteList.getSelectedItem();if(selected&&this.autocompleteProvider){let drillsIntoNamespace=this.isSlashNamespaceSelection(selected.value);this.pushUndoSnapshot(),this.lastAction=null;let result=this.autocompleteProvider.applyCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol,selected,this.autocompletePrefix);if(this.state.lines=result.lines,this.state.cursorLine=result.cursorLine,this.setCursorCol(result.cursorCol),drillsIntoNamespace){this.cancelAutocomplete(),this.onChange&&this.onChange(this.getText()),this.tryTriggerAutocomplete();return}if(this.autocompletePrefix.startsWith("/")){let awaitsArguments=this.autocompleteItems.some(item=>item===selected&&item.awaitsArguments===!0);if(this.cancelAutocomplete(),awaitsArguments){this.onChange&&this.onChange(this.getText());return}}else{this.cancelAutocomplete(),this.onChange&&this.onChange(this.getText());return}}}}if(kb.matches(data,"tui.input.tab")&&!this.autocompleteState){this.handleTabCompletion();return}if(kb.matches(data,"tui.editor.deleteToLineEnd")){this.deleteToEndOfLine();return}if(kb.matches(data,"tui.editor.deleteToLineStart")){this.deleteToStartOfLine();return}if(kb.matches(data,"tui.editor.deleteWordBackward")){this.deleteWordBackwards();return}if(kb.matches(data,"tui.editor.deleteWordForward")){this.deleteWordForward();return}if(kb.matches(data,"tui.editor.deleteCharBackward")||matchesKey(data,"shift+backspace")){this.handleBackspace();return}if(kb.matches(data,"tui.editor.deleteCharForward")||matchesKey(data,"shift+delete")){this.handleForwardDelete();return}if(kb.matches(data,"tui.editor.yank")){this.yank();return}if(kb.matches(data,"tui.editor.yankPop")){this.yankPop();return}if(kb.matches(data,"tui.editor.historyPrevious")){this.cancelAutocomplete(),this.navigateHistory(-1);return}if(kb.matches(data,"tui.editor.historyNext")){this.cancelAutocomplete(),this.navigateHistory(1);return}if(kb.matches(data,"tui.editor.cursorLineStart")){this.moveToLineStart();return}if(kb.matches(data,"tui.editor.cursorLineEnd")){this.moveToLineEnd();return}if(kb.matches(data,"tui.editor.cursorWordLeft")){this.moveWordBackwards();return}if(kb.matches(data,"tui.editor.cursorWordRight")){this.moveWordForwards();return}if(kb.matches(data,"tui.input.submit")){if(this.disableSubmit)return;let currentLine=this.state.lines[this.state.cursorLine]||"";if(this.state.cursorCol>0&¤tLine[this.state.cursorCol-1]==="\\"){this.handleBackspace(),this.addNewLine();return}this.submitValue();return}if(kb.matches(data,"tui.input.newLine")||data.charCodeAt(0)===10&&data.length>1||data==="\x1B\r"||data==="\x1B[13;2~"||data.length>1&&data.includes("\x1B")&&data.includes("\r")||data===`
|
|
112
112
|
`&&data.length===1){if(this.shouldSubmitOnBackslashEnter(data,kb)){this.handleBackspace(),this.submitValue();return}this.addNewLine();return}if(kb.matches(data,"tui.editor.cursorUp")){this.isOnFirstVisualLine()&&(this.isEditorEmpty()||this.historyIndex>-1||this.state.cursorCol===0)?this.navigateHistory(-1):this.isOnFirstVisualLine()?this.moveToLineStart():this.moveCursor(-1,0);return}if(kb.matches(data,"tui.editor.cursorDown")){this.historyIndex>-1&&this.isOnLastVisualLine()?this.navigateHistory(1):this.isOnLastVisualLine()?this.moveToLineEnd():this.moveCursor(1,0);return}if(kb.matches(data,"tui.editor.cursorRight")){this.moveCursor(0,1);return}if(kb.matches(data,"tui.editor.cursorLeft")){this.moveCursor(0,-1);return}if(kb.matches(data,"tui.editor.pageUp")){this.pageScroll(-1);return}if(kb.matches(data,"tui.editor.pageDown")){this.pageScroll(1);return}if(kb.matches(data,"tui.editor.jumpForward")){this.jumpMode="forward";return}if(kb.matches(data,"tui.editor.jumpBackward")){this.jumpMode="backward";return}if(matchesKey(data,"shift+space")){this.insertCharacter(" ");return}let printable=decodePrintableKey(data);if(printable!==void 0){this.insertCharacter(printable);return}data.charCodeAt(0)>=32&&this.insertCharacter(data)}layoutText(contentWidth){let layoutLines=[];if(this.state.lines.length===0||this.state.lines.length===1&&this.state.lines[0]==="")return this.wrappedLineCache.length=this.state.lines.length,layoutLines.push({text:"",hasCursor:!0,cursorPos:0,logicalLine:0,startIndex:0}),layoutLines;for(let i=0;i<this.state.lines.length;i++){let line=this.state.lines[i]||"",isCurrentLine=i===this.state.cursorLine,wrappedLine=this.getWrappedLine(i,contentWidth);if(wrappedLine.width<=contentWidth)isCurrentLine?layoutLines.push({text:line,hasCursor:!0,cursorPos:this.state.cursorCol,logicalLine:i,startIndex:0}):layoutLines.push({text:line,hasCursor:!1,logicalLine:i,startIndex:0});else{let chunks=wrappedLine.chunks;for(let chunkIndex=0;chunkIndex<chunks.length;chunkIndex++){let chunk=chunks[chunkIndex];if(!chunk)continue;let cursorPos=this.state.cursorCol,isLastChunk=chunkIndex===chunks.length-1,hasCursorInChunk=!1,adjustedCursorPos=0;isCurrentLine&&(isLastChunk?(hasCursorInChunk=cursorPos>=chunk.startIndex,adjustedCursorPos=cursorPos-chunk.startIndex):(hasCursorInChunk=cursorPos>=chunk.startIndex&&cursorPos<chunk.endIndex,hasCursorInChunk&&(adjustedCursorPos=cursorPos-chunk.startIndex,adjustedCursorPos>chunk.text.length&&(adjustedCursorPos=chunk.text.length)))),hasCursorInChunk?layoutLines.push({text:chunk.text,hasCursor:!0,cursorPos:adjustedCursorPos,logicalLine:i,startIndex:chunk.startIndex}):layoutLines.push({text:chunk.text,hasCursor:!1,logicalLine:i,startIndex:chunk.startIndex})}}}return this.wrappedLineCache.length=this.state.lines.length,layoutLines}getText(){return this.state.lines.join(`
|
|
113
113
|
`)}getExpandedText(){return this.pasteMarkers.expand(this.state.lines.join(`
|
|
114
114
|
`))}getLines(){return[...this.state.lines]}getCursor(){return{line:this.state.cursorLine,col:this.state.cursorCol}}setText(text){this.cancelAutocomplete(),this.lastAction=null,this.exitHistoryBrowsing();let normalized=this.normalizeText(text),previousText=this.getText();previousText!==normalized&&this.pushUndoSnapshot(),this.pasteMarkers.prune(normalized,previousText);let previousImageOrder=this.imageMarkers.ids(previousText);this.imageMarkers.prune(normalized,previousText),this.setTextInternal(normalized);let canonicalization=this.imageMarkers.canonicalize(normalized);this.applyCanonicalizedText(canonicalization);let imageOrder=canonicalization.order;(previousImageOrder.length!==imageOrder.length||previousImageOrder.some((id,i)=>id!==imageOrder[i]))&&this.onImageMarkersChanged?.(imageOrder)}getPasteState(){return this.pasteMarkers.snapshot()}setPasteState(state){this.pasteMarkers.install(state,this.getText())}getImageMarkerState(){return this.imageMarkers.snapshot()}setImageMarkerState(state){this.imageMarkers.install(state,this.getText())}insertImageMarker(){this.cancelAutocomplete(),this.pushUndoSnapshot(),this.lastAction=null,this.exitHistoryBrowsing();let marker=this.imageMarkers.add();this.insertTextAtCursorInternal(marker);let canonicalization=this.imageMarkers.canonicalize(this.getText());this.applyCanonicalizedText(canonicalization);let insertionId=imageMarkerId(marker),finalId=canonicalization.order.includes(insertionId)?canonicalization.order.indexOf(insertionId)+1:insertionId;return this.onImageMarkersChanged?.(canonicalization.order),finalId}applyCanonicalizedText(canonicalization){if(canonicalization.text===this.getText())return;let oldLine=this.state.lines[this.state.cursorLine]??"",cursorCol=this.state.cursorCol,renumbered=new Map;for(let[index,id]of canonicalization.order.entries())renumbered.set(id,index+1);let delta=0;for(let match of oldLine.matchAll(IMAGE_MARKER_REGEX)){if((match.index??0)+match[0].length>cursorCol)break;let newId=renumbered.get(Number.parseInt(match[1]??"0",10));newId!==void 0&&(delta+=formatImageMarker(newId).length-match[0].length)}this.state.lines=canonicalization.text.split(`
|
|
@@ -124,4 +124,4 @@ Please report this to https://github.com/markedjs/marked.`,e){let i="<p>An error
|
|
|
124
124
|
`,{prepend:!0,accumulate:this.lastAction==="kill"}),this.lastAction="kill";let previousLine=this.state.lines[this.state.cursorLine-1]||"";this.state.lines[this.state.cursorLine-1]=previousLine+currentLine,this.state.lines.splice(this.state.cursorLine,1),this.state.cursorLine--,this.setCursorCol(previousLine.length)}}else{this.pushUndoSnapshot();let wasKill=this.lastAction==="kill",oldCursorCol=this.state.cursorCol;this.moveWordBackwards();let deleteFrom=this.state.cursorCol;this.setCursorCol(oldCursorCol);let deletedText=currentLine.slice(deleteFrom,this.state.cursorCol);this.killRing.push(deletedText,{prepend:!0,accumulate:wasKill}),this.lastAction="kill",this.state.lines[this.state.cursorLine]=currentLine.slice(0,deleteFrom)+currentLine.slice(this.state.cursorCol),this.setCursorCol(deleteFrom)}this.onChange&&this.onChange(this.getText())}deleteWordForward(){this.exitHistoryBrowsing();let currentLine=this.state.lines[this.state.cursorLine]||"";if(this.state.cursorCol>=currentLine.length){if(this.state.cursorLine<this.state.lines.length-1){this.pushUndoSnapshot(),this.killRing.push(`
|
|
125
125
|
`,{prepend:!1,accumulate:this.lastAction==="kill"}),this.lastAction="kill";let nextLine=this.state.lines[this.state.cursorLine+1]||"";this.state.lines[this.state.cursorLine]=currentLine+nextLine,this.state.lines.splice(this.state.cursorLine+1,1)}}else{this.pushUndoSnapshot();let wasKill=this.lastAction==="kill",oldCursorCol=this.state.cursorCol;this.moveWordForwards();let deleteTo=this.state.cursorCol;this.setCursorCol(oldCursorCol);let deletedText=currentLine.slice(this.state.cursorCol,deleteTo);this.killRing.push(deletedText,{prepend:!1,accumulate:wasKill}),this.lastAction="kill",this.state.lines[this.state.cursorLine]=currentLine.slice(0,this.state.cursorCol)+currentLine.slice(deleteTo)}this.onChange&&this.onChange(this.getText())}handleForwardDelete(){this.exitHistoryBrowsing(),this.lastAction=null;let currentLine=this.state.lines[this.state.cursorLine]||"";if(this.state.cursorCol<currentLine.length){this.pushUndoSnapshot();let afterCursor=currentLine.slice(this.state.cursorCol),firstGrapheme=[...this.segment(afterCursor,"grapheme")][0];if(this.removeMarkerSegment(firstGrapheme?.segment??"")){this.onChange?.(this.getText());return}let graphemeLength=firstGrapheme?firstGrapheme.segment.length:1,before=currentLine.slice(0,this.state.cursorCol),after=currentLine.slice(this.state.cursorCol+graphemeLength);this.state.lines[this.state.cursorLine]=before+after}else if(this.state.cursorLine<this.state.lines.length-1){this.pushUndoSnapshot();let nextLine=this.state.lines[this.state.cursorLine+1]||"";this.state.lines[this.state.cursorLine]=currentLine+nextLine,this.state.lines.splice(this.state.cursorLine+1,1)}if(this.onChange&&this.onChange(this.getText()),this.autocompleteState)this.updateAutocomplete();else{let textBeforeCursor=(this.state.lines[this.state.cursorLine]||"").slice(0,this.state.cursorCol);this.isInSlashCommandContext(textBeforeCursor)?this.tryTriggerAutocomplete():this.autocompleteTriggerPattern.test(textBeforeCursor)&&this.tryTriggerAutocomplete()}}buildVisualLineMap(width){let visualLines=[];for(let i=0;i<this.state.lines.length;i++){let line=this.state.lines[i]||"",lineVisWidth=visibleWidth(line);if(line.length===0)visualLines.push({logicalLine:i,startCol:0,length:0});else if(lineVisWidth<=width)visualLines.push({logicalLine:i,startCol:0,length:line.length});else{let chunks=this.getWrappedLine(i,width).chunks;for(let chunk of chunks)visualLines.push({logicalLine:i,startCol:chunk.startIndex,length:chunk.endIndex-chunk.startIndex})}}return visualLines}findVisualLineAt(visualLines,line,col){for(let i=0;i<visualLines.length;i++){let vl=visualLines[i];if(!vl||vl.logicalLine!==line)continue;let offset=col-vl.startCol,isLastSegmentOfLine=i===visualLines.length-1||visualLines[i+1]?.logicalLine!==vl.logicalLine;if(offset>=0&&(offset<vl.length||isLastSegmentOfLine&&offset===vl.length))return i}return visualLines.length-1}findCurrentVisualLine(visualLines){return this.findVisualLineAt(visualLines,this.state.cursorLine,this.state.cursorCol)}moveCursor(deltaLine,deltaCol){this.lastAction=null;let visualLines=this.buildVisualLineMap(this.lastWidth),currentVisualLine=this.findCurrentVisualLine(visualLines);if(deltaLine!==0){let targetVisualLine=currentVisualLine+deltaLine;targetVisualLine>=0&&targetVisualLine<visualLines.length&&this.moveToVisualLine(visualLines,currentVisualLine,targetVisualLine)}if(deltaCol!==0){let currentLine=this.state.lines[this.state.cursorLine]||"";if(deltaCol>0)if(this.state.cursorCol<currentLine.length){let afterCursor=currentLine.slice(this.state.cursorCol),firstGrapheme=[...this.segment(afterCursor,"grapheme")][0];this.setCursorCol(this.state.cursorCol+(firstGrapheme?firstGrapheme.segment.length:1))}else if(this.state.cursorLine<this.state.lines.length-1)this.state.cursorLine++,this.setCursorCol(0);else{let currentVL=visualLines[currentVisualLine];currentVL&&(this.preferredVisualCol=this.state.cursorCol-currentVL.startCol)}else if(this.state.cursorCol>0){let beforeCursor=currentLine.slice(0,this.state.cursorCol),graphemes=[...this.segment(beforeCursor,"grapheme")],lastGrapheme=graphemes[graphemes.length-1];this.setCursorCol(this.state.cursorCol-(lastGrapheme?lastGrapheme.segment.length:1))}else if(this.state.cursorLine>0){this.state.cursorLine--;let prevLine=this.state.lines[this.state.cursorLine]||"";this.setCursorCol(prevLine.length)}}this.autocompleteState&&this.updateAutocomplete()}pageScroll(direction){this.lastAction=null;let terminalRows=this.tui.terminal.rows,pageSize=Math.max(5,Math.floor(terminalRows*.3)),visualLines=this.buildVisualLineMap(this.lastWidth),currentVisualLine=this.findCurrentVisualLine(visualLines),targetVisualLine=Math.max(0,Math.min(visualLines.length-1,currentVisualLine+direction*pageSize));this.moveToVisualLine(visualLines,currentVisualLine,targetVisualLine)}moveWordBackwards(){this.lastAction=null;let currentLine=this.state.lines[this.state.cursorLine]||"";if(this.state.cursorCol===0){if(this.state.cursorLine>0){this.state.cursorLine--;let prevLine=this.state.lines[this.state.cursorLine]||"";this.setCursorCol(prevLine.length)}return}this.setCursorCol(findWordBackward(currentLine,this.state.cursorCol,{segment:text=>this.segment(text,"word"),isAtomicSegment:isAtomicMarker}))}yank(){if(this.killRing.length===0)return;this.pushUndoSnapshot();let text=this.killRing.peek();this.insertYankedText(text),this.lastAction="yank"}yankPop(){if(this.lastAction!=="yank"||this.killRing.length<=1)return;this.pushUndoSnapshot(),this.deleteYankedText(),this.killRing.rotate();let text=this.killRing.peek();this.insertYankedText(text),this.lastAction="yank"}insertYankedText(text){this.exitHistoryBrowsing();let lines=text.split(`
|
|
126
126
|
`);if(lines.length===1){let currentLine=this.state.lines[this.state.cursorLine]||"",before=currentLine.slice(0,this.state.cursorCol),after=currentLine.slice(this.state.cursorCol);this.state.lines[this.state.cursorLine]=before+text+after,this.setCursorCol(this.state.cursorCol+text.length)}else{let currentLine=this.state.lines[this.state.cursorLine]||"",before=currentLine.slice(0,this.state.cursorCol),after=currentLine.slice(this.state.cursorCol);this.state.lines[this.state.cursorLine]=before+(lines[0]||"");for(let i=1;i<lines.length-1;i++)this.state.lines.splice(this.state.cursorLine+i,0,lines[i]||"");let lastLineIndex=this.state.cursorLine+lines.length-1;this.state.lines.splice(lastLineIndex,0,(lines[lines.length-1]||"")+after),this.state.cursorLine=lastLineIndex,this.setCursorCol((lines[lines.length-1]||"").length)}this.onChange&&this.onChange(this.getText())}deleteYankedText(){let yankedText=this.killRing.peek();if(!yankedText)return;let yankLines=yankedText.split(`
|
|
127
|
-
`);if(yankLines.length===1){let currentLine=this.state.lines[this.state.cursorLine]||"",deleteLen=yankedText.length,before=currentLine.slice(0,this.state.cursorCol-deleteLen),after=currentLine.slice(this.state.cursorCol);this.state.lines[this.state.cursorLine]=before+after,this.setCursorCol(this.state.cursorCol-deleteLen)}else{let startLine=this.state.cursorLine-(yankLines.length-1),startCol=(this.state.lines[startLine]||"").length-(yankLines[0]||"").length,afterCursor=(this.state.lines[this.state.cursorLine]||"").slice(this.state.cursorCol),beforeYank=(this.state.lines[startLine]||"").slice(0,startCol);this.state.lines.splice(startLine,yankLines.length,beforeYank+afterCursor),this.state.cursorLine=startLine,this.setCursorCol(startCol)}this.onChange&&this.onChange(this.getText())}pushUndoSnapshot(){this.undoStack.push({state:this.state,pasteState:this.pasteMarkers.snapshot(),imageState:this.imageMarkers.snapshot(),attachmentState:this.snapshotAttachmentState?.()})}undo(){this.exitHistoryBrowsing();let snapshot=this.undoStack.pop();snapshot&&(Object.assign(this.state,snapshot.state),this.pasteMarkers.restore(snapshot.pasteState),this.imageMarkers.restore(snapshot.imageState),snapshot.attachmentState!==void 0&&this.restoreAttachmentState?.(snapshot.attachmentState),this.lastAction=null,this.preferredVisualCol=null,this.onChange&&this.onChange(this.getText()),this.notifyImageMarkersChanged())}jumpToChar(char,direction){this.lastAction=null;let isForward=direction==="forward",lines=this.state.lines,end=isForward?lines.length:-1,step=isForward?1:-1;for(let lineIdx=this.state.cursorLine;lineIdx!==end;lineIdx+=step){let line=lines[lineIdx]||"",searchFrom=lineIdx===this.state.cursorLine?isForward?this.state.cursorCol+1:this.state.cursorCol-1:void 0,idx=isForward?line.indexOf(char,searchFrom):line.lastIndexOf(char,searchFrom);if(idx!==-1){this.state.cursorLine=lineIdx,this.setCursorCol(idx);return}}}moveWordForwards(){this.lastAction=null;let currentLine=this.state.lines[this.state.cursorLine]||"";if(this.state.cursorCol>=currentLine.length){this.state.cursorLine<this.state.lines.length-1&&(this.state.cursorLine++,this.setCursorCol(0));return}this.setCursorCol(findWordForward(currentLine,this.state.cursorCol,{segment:text=>this.segment(text,"word"),isAtomicSegment:isAtomicMarker}))}isSlashMenuAllowed(){return this.state.cursorLine===0}isAtStartOfMessage(){if(!this.isSlashMenuAllowed())return!1;let beforeCursor=(this.state.lines[this.state.cursorLine]||"").slice(0,this.state.cursorCol);return beforeCursor.trim()===""||beforeCursor.trim()==="/"}isInSlashCommandContext(textBeforeCursor){return this.isSlashMenuAllowed()&&textBeforeCursor.trimStart().startsWith("/")}getBestAutocompleteMatchIndex(items,prefix){if(!prefix)return-1;let firstPrefixIndex=-1;for(let i=0;i<items.length;i++){let value=items[i].value;if(value===prefix)return i;firstPrefixIndex===-1&&value.startsWith(prefix)&&(firstPrefixIndex=i)}return firstPrefixIndex}createAutocompleteList(prefix,items){let layout=prefix.startsWith("/")?SLASH_COMMAND_SELECT_LIST_LAYOUT:void 0,list=new SelectList(items,this.autocompleteMaxVisible,this.theme.selectList,layout);return list.onSelect=selected=>{if(!this.autocompleteProvider)return;this.pushUndoSnapshot(),this.lastAction=null;let result=this.autocompleteProvider.applyCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol,selected,this.autocompletePrefix);this.state.lines=result.lines,this.state.cursorLine=result.cursorLine,this.setCursorCol(result.cursorCol),this.cancelAutocomplete(),this.onChange?.(this.getText())},list}tryTriggerAutocomplete(explicitTab=!1){this.requestAutocomplete({force:!1,explicitTab})}openAutocomplete(){this.tryTriggerAutocomplete()}isSlashNamespaceSelection(value){return this.autocompletePrefix.startsWith("/")&&isSlashNamespaceItem(value)}handleTabCompletion(){if(!this.autocompleteProvider)return;let beforeCursor=(this.state.lines[this.state.cursorLine]||"").slice(0,this.state.cursorCol);this.isInSlashCommandContext(beforeCursor)&&!beforeCursor.trimStart().includes(" ")?this.handleSlashCommandCompletion():this.forceFileAutocomplete(!0)}handleSlashCommandCompletion(){this.requestAutocomplete({force:!1,explicitTab:!0})}forceFileAutocomplete(explicitTab=!1){this.requestAutocomplete({force:!0,explicitTab})}requestAutocomplete(options){if(!this.autocompleteProvider||options.force&&!(!this.autocompleteProvider.shouldTriggerFileCompletion||this.autocompleteProvider.shouldTriggerFileCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol)))return;this.cancelAutocompleteRequest();let startToken=++this.autocompleteStartToken,debounceMs=this.getAutocompleteDebounceMs(options);if(debounceMs>0){this.autocompleteDebounceTimer=setTimeout(()=>{this.autocompleteDebounceTimer=void 0,this.startAutocompleteRequest(startToken,options)},debounceMs);return}this.startAutocompleteRequest(startToken,options)}async startAutocompleteRequest(startToken,options){let previousTask=this.autocompleteRequestTask;this.autocompleteRequestTask=(async()=>{if(await previousTask,startToken!==this.autocompleteStartToken||!this.autocompleteProvider)return;let controller=new AbortController;this.autocompleteAbort=controller;let requestId=++this.autocompleteRequestId,snapshotText=this.getText(),snapshotLine=this.state.cursorLine,snapshotCol=this.state.cursorCol;await this.runAutocompleteRequest(requestId,controller,snapshotText,snapshotLine,snapshotCol,options)})(),await this.autocompleteRequestTask}setAutocompleteTriggerCharacters(triggerCharacters){let next=[...DEFAULT_AUTOCOMPLETE_TRIGGER_CHARACTERS];for(let character of triggerCharacters)character.length!==1||character==="/"||isWhitespaceChar(character)||next.includes(character)||next.push(character);this.autocompleteTriggerCharacters=next,this.autocompleteTriggerPattern=buildTriggerPattern(next),this.autocompleteDebouncePattern=buildDebouncePattern(next)}getAutocompleteDebounceMs(options){if(options.explicitTab||options.force)return 0;let textBeforeCursor=(this.state.lines[this.state.cursorLine]||"").slice(0,this.state.cursorCol);return this.autocompleteDebouncePattern.test(textBeforeCursor)?ATTACHMENT_AUTOCOMPLETE_DEBOUNCE_MS:0}async runAutocompleteRequest(requestId,controller,snapshotText,snapshotLine,snapshotCol,options){if(!this.autocompleteProvider)return;let suggestions=await this.autocompleteProvider.getSuggestions(this.state.lines,this.state.cursorLine,this.state.cursorCol,{signal:controller.signal,force:options.force});if(this.isAutocompleteRequestCurrent(requestId,controller,snapshotText,snapshotLine,snapshotCol)){if(this.autocompleteAbort=void 0,!suggestions||!Array.isArray(suggestions.items)||suggestions.items.length===0){this.cancelAutocomplete(),this.tui.requestRender();return}if(options.force&&options.explicitTab&&suggestions.items.length===1){let item=suggestions.items[0];this.pushUndoSnapshot(),this.lastAction=null;let result=this.autocompleteProvider.applyCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol,item,suggestions.prefix);this.state.lines=result.lines,this.state.cursorLine=result.cursorLine,this.setCursorCol(result.cursorCol),this.onChange&&this.onChange(this.getText()),this.tui.requestRender();return}this.applyAutocompleteSuggestions(suggestions,options.force?"force":"regular"),this.tui.requestRender()}}isAutocompleteRequestCurrent(requestId,controller,snapshotText,snapshotLine,snapshotCol){return!controller.signal.aborted&&requestId===this.autocompleteRequestId&&this.getText()===snapshotText&&this.state.cursorLine===snapshotLine&&this.state.cursorCol===snapshotCol}applyAutocompleteSuggestions(suggestions,state){this.autocompletePrefix=suggestions.prefix,this.autocompleteItems=suggestions.items,this.autocompleteList=this.createAutocompleteList(suggestions.prefix,suggestions.items);let bestMatchIndex=this.getBestAutocompleteMatchIndex(suggestions.items,suggestions.prefix);bestMatchIndex>=0&&this.autocompleteList.setSelectedIndex(bestMatchIndex),this.autocompleteState=state}cancelAutocompleteRequest(){this.autocompleteStartToken+=1,this.autocompleteDebounceTimer&&(clearTimeout(this.autocompleteDebounceTimer),this.autocompleteDebounceTimer=void 0),this.autocompleteAbort?.abort(),this.autocompleteAbort=void 0}clearAutocompleteUi(){this.autocompleteState=null,this.autocompleteList=void 0,this.autocompleteItems=[],this.autocompletePrefix=""}cancelAutocomplete(){this.cancelAutocompleteRequest(),this.clearAutocompleteUi()}isShowingAutocomplete(){return this.autocompleteState!==null}updateAutocomplete(){!this.autocompleteState||!this.autocompleteProvider||this.requestAutocomplete({force:this.autocompleteState==="force",explicitTab:!1})}};var HStack=class extends Stack{constructor(children=[],options={}){super(children,options),this.layoutType="hstack"}render(width){let safeWidth=Math.max(1,width),viewport={width:safeWidth,height:Number.MAX_SAFE_INTEGER},entries=visibleStackEntries(this.entries,viewport);if(entries.length===0)return[];let intrinsicWidths=entries.map(entry=>entry.component.render(safeWidth).reduce((max,line)=>Math.max(max,visibleWidth(line)),0)),widths=allocateStackSizes(entries,intrinsicWidths,safeWidth,this.gap),rendered=entries.map((entry,index)=>widths[index]===0?[]:entry.component.render(widths[index])),height=rendered.reduce((max,lines)=>Math.max(max,lines.length),0),result=Array.from({length:height},()=>""),x2=0;for(let index=0;index<rendered.length;index++){let lines=rendered[index],childWidth=widths[index],offset=0;this.align==="center"?offset=Math.floor((height-lines.length)/2):this.align==="end"&&(offset=height-lines.length);for(let row=0;row<lines.length;row++){let target=row+offset;target<0||target>=result.length||(result[target]=compositeTuiLine(result[target],lines[row],x2,childWidth,safeWidth))}x2+=childWidth+this.gap}return result}};var Image=class{constructor(base64Data,mimeType,theme,options={},dimensions){this.base64Data=base64Data,this.mimeType=mimeType,this.theme=theme,this.options=options,this.dimensions=dimensions||getImageDimensions(base64Data,mimeType)||{widthPx:800,heightPx:600},this.imageId=options.imageId}getImageId(){return this.imageId}invalidate(){this.cachedLines=void 0,this.cachedWidth=void 0}render(width){if(this.cachedLines&&this.cachedWidth===width)return this.cachedLines;let maxWidth=Math.max(1,Math.min(width-2,this.options.maxWidthCells??60)),cellDimensions2=getCellDimensions(),defaultMaxHeight=Math.max(1,Math.ceil(maxWidth*cellDimensions2.widthPx/cellDimensions2.heightPx)),maxHeight=this.options.maxHeightCells??defaultMaxHeight,caps=getCapabilities(),lines;if(caps.images){caps.images==="kitty"&&this.imageId===void 0&&(this.imageId=allocateImageId());let result=renderImage(this.base64Data,this.dimensions,{maxWidthCells:maxWidth,maxHeightCells:maxHeight,imageId:this.imageId,moveCursor:!1});if(result)if(result.imageId&&(this.imageId=result.imageId),caps.images==="kitty"&&result.lines)lines=result.lines;else if(caps.images==="kitty"){lines=[result.sequence];for(let i=0;i<result.rows-1;i++)lines.push("")}else{lines=[];for(let i=0;i<result.rows-1;i++)lines.push("");let rowOffset=result.rows-1,moveUp=rowOffset>0?`\x1B[${rowOffset}A`:"";lines.push(moveUp+result.sequence)}else{let fallback=imageFallback(this.mimeType,this.dimensions,this.options.filename);lines=[truncateToWidth(this.theme.fallbackColor(fallback),width)]}}else{let fallback=imageFallback(this.mimeType,this.dimensions,this.options.filename);lines=[truncateToWidth(this.theme.fallbackColor(fallback),width)]}return this.cachedLines=lines,this.cachedWidth=width,lines}};var MouseRegion=class _MouseRegion{constructor(child,onMouse){this.child=child,this.onMouse=onMouse}render(width){return this.child.render(width)}getRenderRevision(){return Object.getPrototypeOf(this)===_MouseRegion.prototype?this.child.getRenderRevision?.():void 0}handleMouse(event){return dispatchMouseEvent(this.child,event)??this.onMouse(event)}invalidate(){this.child.invalidate()}};var SettingsList=class{constructor(items,maxVisible,theme,onChange,onCancel,options={}){this.selectedIndex=0,this.submenuComponent=null,this.submenuItemIndex=null,this.navigateAfterClose=null,this.items=items,this.filteredItems=items,this.maxVisible=maxVisible,this.theme=theme,this.onChange=onChange,this.onCancel=onCancel,this.searchEnabled=options.enableSearch??!1,this.searchEnabled&&(this.searchInput=new Input)}updateValue(id,newValue){let item=this.items.find(i=>i.id===id);item&&(item.currentValue=newValue)}selectItem(id){let index=(this.searchEnabled?this.filteredItems:this.items).findIndex(i=>i.id===id);index!==-1&&(this.selectedIndex=index)}invalidate(){this.submenuComponent?.invalidate?.()}render(width){return this.submenuComponent?this.submenuComponent.render(width):this.renderMainList(width)}renderMainList(width){let lines=[];if(this.searchEnabled&&this.searchInput&&(lines.push(...this.searchInput.render(width)),lines.push("")),this.items.length===0)return lines.push(this.theme.hint(" No settings available")),this.searchEnabled&&this.addHintLine(lines,width),lines;let displayItems=this.getDisplayItems();if(displayItems.length===0)return lines.push(truncateToWidth(this.theme.hint(" No matching settings"),width)),this.addHintLine(lines,width),lines;let{startIndex,endIndex}=this.getVisibleRange(displayItems),maxLabelWidth=Math.min(36,Math.max(...this.items.map(item=>visibleWidth(item.label))));for(let i=startIndex;i<endIndex;i++){let item=displayItems[i];if(!item)continue;let isSelected=i===this.selectedIndex,prefix=isSelected?this.theme.cursor:" ",prefixWidth=visibleWidth(prefix),labelPadded=item.label+" ".repeat(Math.max(0,maxLabelWidth-visibleWidth(item.label))),labelText=this.theme.label(labelPadded,isSelected),separator=" ",usedWidth=prefixWidth+maxLabelWidth+visibleWidth(separator),valueMaxWidth=width-usedWidth-2,valueText=this.theme.value(truncateToWidth(item.currentValue,valueMaxWidth,""),isSelected);lines.push(truncateToWidth(prefix+labelText+separator+valueText,width))}if(startIndex>0||endIndex<displayItems.length){let scrollText=` (${this.selectedIndex+1}/${displayItems.length})`;lines.push(this.theme.hint(truncateToWidth(scrollText,width-2,"")))}let selectedItem=displayItems[this.selectedIndex];if(selectedItem?.description){lines.push("");let wrappedDesc=wrapTextWithAnsi(selectedItem.description,width-4);for(let line of wrappedDesc)lines.push(this.theme.description(` ${line}`))}return this.addHintLine(lines,width),lines}handleMouse(event){if(this.submenuComponent){let result=this.submenuComponent.handleMouse?.(event);return result?{...result,focus:!0}:void 0}if(this.searchEnabled&&this.searchInput){if(event.y===0){let result=this.searchInput.handleMouse?.(event);return result?{...result,focus:!0}:void 0}if(event.y===1)return}let displayItems=this.getDisplayItems();if(displayItems.length===0)return;if(event.type==="wheel"&&event.wheelDelta){let delta=event.wheelDelta<0?-1:1,previousIndex=this.selectedIndex;return this.selectedIndex=Math.max(0,Math.min(displayItems.length-1,this.selectedIndex+delta)),{handled:!0,render:this.selectedIndex!==previousIndex}}if(event.button!=="left"||event.type!=="press"&&event.type!=="click")return;let rowOffset=this.searchEnabled?2:0,{startIndex,endIndex}=this.getVisibleRange(displayItems),itemIndex=startIndex+event.y-rowOffset;if(!(itemIndex<startIndex||itemIndex>=endIndex)){if(event.type==="press")return this.mousePressedIndex=itemIndex,this.selectedIndex=itemIndex,{handled:!0,focus:!0};if(event.type==="click")return this.selectedIndex=this.mousePressedIndex??itemIndex,this.mousePressedIndex=void 0,this.activateItem(),{handled:!0}}}handleInput(data){if(this.submenuComponent){this.submenuComponent.handleInput?.(data);return}let kb=getKeybindings(),displayItems=this.getDisplayItems();if(kb.matches(data,"tui.select.up")){if(displayItems.length===0)return;this.selectedIndex=this.selectedIndex===0?displayItems.length-1:this.selectedIndex-1}else if(kb.matches(data,"tui.select.down")){if(displayItems.length===0)return;this.selectedIndex=this.selectedIndex===displayItems.length-1?0:this.selectedIndex+1}else kb.matches(data,"tui.select.confirm")||data===" "&&(!this.searchEnabled||this.searchInput?.getValue().length===0)?this.activateItem():kb.matches(data,"tui.select.cancel")?this.onCancel():this.searchEnabled&&this.searchInput&&(this.searchInput.handleInput(data),this.applyFilter(this.searchInput.getValue()))}getDisplayItems(){return this.searchEnabled?this.filteredItems:this.items}getVisibleRange(displayItems){let startIndex=Math.max(0,Math.min(this.selectedIndex-Math.floor(this.maxVisible/2),displayItems.length-this.maxVisible));return{startIndex,endIndex:Math.min(startIndex+this.maxVisible,displayItems.length)}}activateItem(){let item=this.getDisplayItems()[this.selectedIndex];if(item){if(item.submenu)this.submenuItemIndex=this.selectedIndex,this.submenuComponent=item.submenu(item.currentValue,(selectedValue,options)=>{selectedValue!==void 0&&(item.currentValue=selectedValue,this.onChange(item.id,selectedValue)),options?.navigateTo&&(this.navigateAfterClose=options.navigateTo),this.closeSubmenu()});else if(item.values&&item.values.length>0){let nextIndex=(item.values.indexOf(item.currentValue)+1)%item.values.length,newValue=item.values[nextIndex];item.currentValue=newValue,this.onChange(item.id,newValue)}}}closeSubmenu(){if(this.submenuComponent=null,this.navigateAfterClose!==null){let id=this.navigateAfterClose;this.navigateAfterClose=null,this.submenuItemIndex=null,this.selectItem(id),this.activateItem()}else this.submenuItemIndex!==null&&(this.selectedIndex=this.submenuItemIndex,this.submenuItemIndex=null)}applyFilter(query){this.filteredItems=fuzzyFilter(this.items,query,item=>item.label),this.selectedIndex=0}addHintLine(lines,width){lines.push(""),lines.push(truncateToWidth(this.theme.hint(this.searchEnabled?" Type to search \xB7 Enter/Space to change \xB7 Esc to cancel":" Enter/Space to change \xB7 Esc to cancel"),width))}};var VStack=class extends Stack{constructor(children=[],options={}){super(children,options),this.layoutType="vstack"}render(width){let viewport={width:Math.max(1,width),height:Number.MAX_SAFE_INTEGER},entries=visibleStackEntries(this.entries,viewport),rendered=entries.map(entry=>entry.component.render(viewport.width)),sizes=allocateStackSizes(entries,rendered.map(lines2=>lines2.length),void 0,this.gap),lines=[];for(let index=0;index<entries.length;index++){if(index>0)for(let gap=0;gap<this.gap;gap++)lines.push("");let childLines=rendered[index].slice(0,sizes[index]);lines.push(...childLines);for(let padding=childLines.length;padding<sizes[index];padding++)lines.push("")}return lines}};function calculateImageRows(imageDimensions,targetWidthCells,cellDimensions2={widthPx:9,heightPx:18}){return calculateImageCellSize(imageDimensions,targetWidthCells,void 0,cellDimensions2).rows}export{outerKittyGraphicsMode,sanitizeTerminalLabel,detectCapabilities,getCapabilities,getTerminalColorMode,setCapabilityOverrides,getImageDimensions,hyperlink,imageFallback,x,Q,Key,isKeyRelease,matchesKey,decodeKittyPrintable,TUI_KEYBINDINGS,KeybindingsManager,setKeybindings,getKeybindings,getGraphemeSegmenter,visibleWidth,stripTerminalSequences,wrapTextWithAnsi,truncateToWidth,sliceByColumn,dispatchMouseEvent,frameMode,mainScreenHistoryLines,frameScrollbackRows,claimFrameRow,renderAtFrameRow,nextRenderRevision,currentRenderRevision,Container,joinLineArrays,isViewportTUI,TUI,Input,fuzzyMatch,fuzzyMatchLower,fuzzyFilter,CombinedAutocompleteProvider,oklabToOkhslLightness,indexedColor,rgbColor,oklchColor,okhslColor,colorToOkhsl,parseColor,colorToRgb,colorToOklch,colorToHex,mixColors,foregroundAnsi,backgroundAnsi,styleTextWithAnsi,Box,Text,Loader,CancellableLoader,expandPasteMarkers,getNativeClipboard,isWarpWslSession,ProcessTerminal,SelectList,Editor,Image,Markdown,MouseRegion,ScrollView,SettingsList,Spacer,TruncatedText,VStack,TuiAltScreen,TuiMainScreen,dist_exports};
|
|
127
|
+
`);if(yankLines.length===1){let currentLine=this.state.lines[this.state.cursorLine]||"",deleteLen=yankedText.length,before=currentLine.slice(0,this.state.cursorCol-deleteLen),after=currentLine.slice(this.state.cursorCol);this.state.lines[this.state.cursorLine]=before+after,this.setCursorCol(this.state.cursorCol-deleteLen)}else{let startLine=this.state.cursorLine-(yankLines.length-1),startCol=(this.state.lines[startLine]||"").length-(yankLines[0]||"").length,afterCursor=(this.state.lines[this.state.cursorLine]||"").slice(this.state.cursorCol),beforeYank=(this.state.lines[startLine]||"").slice(0,startCol);this.state.lines.splice(startLine,yankLines.length,beforeYank+afterCursor),this.state.cursorLine=startLine,this.setCursorCol(startCol)}this.onChange&&this.onChange(this.getText())}pushUndoSnapshot(){this.undoStack.push({state:this.state,pasteState:this.pasteMarkers.snapshot(),imageState:this.imageMarkers.snapshot(),attachmentState:this.snapshotAttachmentState?.()})}undo(){this.exitHistoryBrowsing();let snapshot=this.undoStack.pop();snapshot&&(Object.assign(this.state,snapshot.state),this.pasteMarkers.restore(snapshot.pasteState),this.imageMarkers.restore(snapshot.imageState),snapshot.attachmentState!==void 0&&this.restoreAttachmentState?.(snapshot.attachmentState),this.lastAction=null,this.preferredVisualCol=null,this.onChange&&this.onChange(this.getText()),this.notifyImageMarkersChanged())}jumpToChar(char,direction){this.lastAction=null;let isForward=direction==="forward",lines=this.state.lines,end=isForward?lines.length:-1,step=isForward?1:-1;for(let lineIdx=this.state.cursorLine;lineIdx!==end;lineIdx+=step){let line=lines[lineIdx]||"",searchFrom=lineIdx===this.state.cursorLine?isForward?this.state.cursorCol+1:this.state.cursorCol-1:void 0,idx=isForward?line.indexOf(char,searchFrom):line.lastIndexOf(char,searchFrom);if(idx!==-1){this.state.cursorLine=lineIdx,this.setCursorCol(idx);return}}}moveWordForwards(){this.lastAction=null;let currentLine=this.state.lines[this.state.cursorLine]||"";if(this.state.cursorCol>=currentLine.length){this.state.cursorLine<this.state.lines.length-1&&(this.state.cursorLine++,this.setCursorCol(0));return}this.setCursorCol(findWordForward(currentLine,this.state.cursorCol,{segment:text=>this.segment(text,"word"),isAtomicSegment:isAtomicMarker}))}isSlashMenuAllowed(){return this.state.cursorLine===0}isAtStartOfMessage(){if(!this.isSlashMenuAllowed())return!1;let beforeCursor=(this.state.lines[this.state.cursorLine]||"").slice(0,this.state.cursorCol);return beforeCursor.trim()===""||beforeCursor.trim()==="/"}isInSlashCommandContext(textBeforeCursor){return this.isSlashMenuAllowed()&&textBeforeCursor.trimStart().startsWith("/")}getBestAutocompleteMatchIndex(items,prefix){if(!prefix)return-1;let firstPrefixIndex=-1;for(let i=0;i<items.length;i++){let value=items[i].value;if(value===prefix)return i;firstPrefixIndex===-1&&value.startsWith(prefix)&&(firstPrefixIndex=i)}return firstPrefixIndex}createAutocompleteList(prefix,items){let layout=prefix.startsWith("/")?SLASH_COMMAND_SELECT_LIST_LAYOUT:void 0,list=new SelectList(items,this.autocompleteMaxVisible,this.theme.selectList,layout);return list.onSelect=selected=>{if(!this.autocompleteProvider)return;this.pushUndoSnapshot(),this.lastAction=null;let result=this.autocompleteProvider.applyCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol,selected,this.autocompletePrefix);this.state.lines=result.lines,this.state.cursorLine=result.cursorLine,this.setCursorCol(result.cursorCol),this.cancelAutocomplete(),this.onChange?.(this.getText())},list}tryTriggerAutocomplete(explicitTab=!1){this.requestAutocomplete({force:!1,explicitTab})}openAutocomplete(){this.tryTriggerAutocomplete()}isSlashNamespaceSelection(value){return this.autocompletePrefix.startsWith("/")&&isSlashNamespaceItem(value)}handleTabCompletion(){if(!this.autocompleteProvider)return;let beforeCursor=(this.state.lines[this.state.cursorLine]||"").slice(0,this.state.cursorCol);this.isInSlashCommandContext(beforeCursor)&&!beforeCursor.trimStart().includes(" ")?this.handleSlashCommandCompletion():this.forceFileAutocomplete(!0)}handleSlashCommandCompletion(){this.requestAutocomplete({force:!1,explicitTab:!0})}forceFileAutocomplete(explicitTab=!1){this.requestAutocomplete({force:!0,explicitTab})}requestAutocomplete(options){if(!this.autocompleteProvider||options.force&&!(!this.autocompleteProvider.shouldTriggerFileCompletion||this.autocompleteProvider.shouldTriggerFileCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol)))return;this.cancelAutocompleteRequest();let startToken=++this.autocompleteStartToken,debounceMs=this.getAutocompleteDebounceMs(options);if(debounceMs>0){this.autocompleteDebounceTimer=setTimeout(()=>{this.autocompleteDebounceTimer=void 0,this.startAutocompleteRequest(startToken,options)},debounceMs);return}this.startAutocompleteRequest(startToken,options)}async startAutocompleteRequest(startToken,options){let previousTask=this.autocompleteRequestTask;this.autocompleteRequestTask=(async()=>{if(await previousTask,startToken!==this.autocompleteStartToken||!this.autocompleteProvider)return;let controller=new AbortController;this.autocompleteAbort=controller;let requestId=++this.autocompleteRequestId,snapshotText=this.getText(),snapshotLine=this.state.cursorLine,snapshotCol=this.state.cursorCol;await this.runAutocompleteRequest(requestId,controller,snapshotText,snapshotLine,snapshotCol,options)})(),await this.autocompleteRequestTask}setAutocompleteTriggerCharacters(triggerCharacters){let next=[...DEFAULT_AUTOCOMPLETE_TRIGGER_CHARACTERS];for(let character of triggerCharacters)character.length!==1||character==="/"||isWhitespaceChar(character)||next.includes(character)||next.push(character);this.autocompleteTriggerCharacters=next,this.autocompleteTriggerPattern=buildTriggerPattern(next),this.autocompleteDebouncePattern=buildDebouncePattern(next)}getAutocompleteDebounceMs(options){if(options.explicitTab||options.force)return 0;let textBeforeCursor=(this.state.lines[this.state.cursorLine]||"").slice(0,this.state.cursorCol);return this.autocompleteDebouncePattern.test(textBeforeCursor)?ATTACHMENT_AUTOCOMPLETE_DEBOUNCE_MS:0}async runAutocompleteRequest(requestId,controller,snapshotText,snapshotLine,snapshotCol,options){if(!this.autocompleteProvider)return;let suggestions=await this.autocompleteProvider.getSuggestions(this.state.lines,this.state.cursorLine,this.state.cursorCol,{signal:controller.signal,force:options.force});if(this.isAutocompleteRequestCurrent(requestId,controller,snapshotText,snapshotLine,snapshotCol)){if(this.autocompleteAbort=void 0,!suggestions||!Array.isArray(suggestions.items)||suggestions.items.length===0){this.cancelAutocomplete(),this.tui.requestRender();return}if(options.acceptSelection){let bestMatchIndex=this.getBestAutocompleteMatchIndex(suggestions.items,suggestions.prefix),item=suggestions.items[Math.max(bestMatchIndex,0)],drillsIntoNamespace=suggestions.prefix.startsWith("/")&&isSlashNamespaceItem(item.value);this.pushUndoSnapshot(),this.lastAction=null;let result=this.autocompleteProvider.applyCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol,item,suggestions.prefix);this.state.lines=result.lines,this.state.cursorLine=result.cursorLine,this.setCursorCol(result.cursorCol),this.clearAutocompleteUi(),this.onChange&&this.onChange(this.getText()),drillsIntoNamespace&&this.tryTriggerAutocomplete(),this.tui.requestRender();return}if(options.force&&options.explicitTab&&suggestions.items.length===1){let item=suggestions.items[0];this.pushUndoSnapshot(),this.lastAction=null;let result=this.autocompleteProvider.applyCompletion(this.state.lines,this.state.cursorLine,this.state.cursorCol,item,suggestions.prefix);this.state.lines=result.lines,this.state.cursorLine=result.cursorLine,this.setCursorCol(result.cursorCol),this.onChange&&this.onChange(this.getText()),this.tui.requestRender();return}this.applyAutocompleteSuggestions(suggestions,options.force?"force":"regular"),this.tui.requestRender()}}isAutocompleteRequestCurrent(requestId,controller,snapshotText,snapshotLine,snapshotCol){return!controller.signal.aborted&&requestId===this.autocompleteRequestId&&this.getText()===snapshotText&&this.state.cursorLine===snapshotLine&&this.state.cursorCol===snapshotCol}applyAutocompleteSuggestions(suggestions,state){this.autocompletePrefix=suggestions.prefix,this.autocompleteListSnapshot={text:this.getText(),line:this.state.cursorLine,col:this.state.cursorCol},this.autocompleteItems=suggestions.items,this.autocompleteList=this.createAutocompleteList(suggestions.prefix,suggestions.items);let bestMatchIndex=this.getBestAutocompleteMatchIndex(suggestions.items,suggestions.prefix);bestMatchIndex>=0&&this.autocompleteList.setSelectedIndex(bestMatchIndex),this.autocompleteState=state}cancelAutocompleteRequest(){this.autocompleteStartToken+=1,this.autocompleteDebounceTimer&&(clearTimeout(this.autocompleteDebounceTimer),this.autocompleteDebounceTimer=void 0),this.autocompleteAbort?.abort(),this.autocompleteAbort=void 0}clearAutocompleteUi(){this.autocompleteState=null,this.autocompleteList=void 0,this.autocompleteItems=[],this.autocompletePrefix="",this.autocompleteListSnapshot=void 0}isAutocompleteListStale(){let snapshot=this.autocompleteListSnapshot;return snapshot!==void 0&&(snapshot.text!==this.getText()||snapshot.line!==this.state.cursorLine||snapshot.col!==this.state.cursorCol)}acceptRefreshedAutocomplete(){this.requestAutocomplete({force:this.autocompleteState==="force",explicitTab:!0,acceptSelection:!0})}cancelAutocomplete(){this.cancelAutocompleteRequest(),this.clearAutocompleteUi()}isShowingAutocomplete(){return this.autocompleteState!==null}updateAutocomplete(){!this.autocompleteState||!this.autocompleteProvider||this.requestAutocomplete({force:this.autocompleteState==="force",explicitTab:!1})}};var HStack=class extends Stack{constructor(children=[],options={}){super(children,options),this.layoutType="hstack"}render(width){let safeWidth=Math.max(1,width),viewport={width:safeWidth,height:Number.MAX_SAFE_INTEGER},entries=visibleStackEntries(this.entries,viewport);if(entries.length===0)return[];let intrinsicWidths=entries.map(entry=>entry.component.render(safeWidth).reduce((max,line)=>Math.max(max,visibleWidth(line)),0)),widths=allocateStackSizes(entries,intrinsicWidths,safeWidth,this.gap),rendered=entries.map((entry,index)=>widths[index]===0?[]:entry.component.render(widths[index])),height=rendered.reduce((max,lines)=>Math.max(max,lines.length),0),result=Array.from({length:height},()=>""),x2=0;for(let index=0;index<rendered.length;index++){let lines=rendered[index],childWidth=widths[index],offset=0;this.align==="center"?offset=Math.floor((height-lines.length)/2):this.align==="end"&&(offset=height-lines.length);for(let row=0;row<lines.length;row++){let target=row+offset;target<0||target>=result.length||(result[target]=compositeTuiLine(result[target],lines[row],x2,childWidth,safeWidth))}x2+=childWidth+this.gap}return result}};var Image=class{constructor(base64Data,mimeType,theme,options={},dimensions){this.base64Data=base64Data,this.mimeType=mimeType,this.theme=theme,this.options=options,this.dimensions=dimensions||getImageDimensions(base64Data,mimeType)||{widthPx:800,heightPx:600},this.imageId=options.imageId}getImageId(){return this.imageId}invalidate(){this.cachedLines=void 0,this.cachedWidth=void 0}render(width){if(this.cachedLines&&this.cachedWidth===width)return this.cachedLines;let maxWidth=Math.max(1,Math.min(width-2,this.options.maxWidthCells??60)),cellDimensions2=getCellDimensions(),defaultMaxHeight=Math.max(1,Math.ceil(maxWidth*cellDimensions2.widthPx/cellDimensions2.heightPx)),maxHeight=this.options.maxHeightCells??defaultMaxHeight,caps=getCapabilities(),lines;if(caps.images){caps.images==="kitty"&&this.imageId===void 0&&(this.imageId=allocateImageId());let result=renderImage(this.base64Data,this.dimensions,{maxWidthCells:maxWidth,maxHeightCells:maxHeight,imageId:this.imageId,moveCursor:!1});if(result)if(result.imageId&&(this.imageId=result.imageId),caps.images==="kitty"&&result.lines)lines=result.lines;else if(caps.images==="kitty"){lines=[result.sequence];for(let i=0;i<result.rows-1;i++)lines.push("")}else{lines=[];for(let i=0;i<result.rows-1;i++)lines.push("");let rowOffset=result.rows-1,moveUp=rowOffset>0?`\x1B[${rowOffset}A`:"";lines.push(moveUp+result.sequence)}else{let fallback=imageFallback(this.mimeType,this.dimensions,this.options.filename);lines=[truncateToWidth(this.theme.fallbackColor(fallback),width)]}}else{let fallback=imageFallback(this.mimeType,this.dimensions,this.options.filename);lines=[truncateToWidth(this.theme.fallbackColor(fallback),width)]}return this.cachedLines=lines,this.cachedWidth=width,lines}};var MouseRegion=class _MouseRegion{constructor(child,onMouse){this.child=child,this.onMouse=onMouse}render(width){return this.child.render(width)}getRenderRevision(){return Object.getPrototypeOf(this)===_MouseRegion.prototype?this.child.getRenderRevision?.():void 0}handleMouse(event){return dispatchMouseEvent(this.child,event)??this.onMouse(event)}invalidate(){this.child.invalidate()}};var SettingsList=class{constructor(items,maxVisible,theme,onChange,onCancel,options={}){this.selectedIndex=0,this.submenuComponent=null,this.submenuItemIndex=null,this.navigateAfterClose=null,this.items=items,this.filteredItems=items,this.maxVisible=maxVisible,this.theme=theme,this.onChange=onChange,this.onCancel=onCancel,this.searchEnabled=options.enableSearch??!1,this.searchEnabled&&(this.searchInput=new Input)}updateValue(id,newValue){let item=this.items.find(i=>i.id===id);item&&(item.currentValue=newValue)}selectItem(id){let index=(this.searchEnabled?this.filteredItems:this.items).findIndex(i=>i.id===id);index!==-1&&(this.selectedIndex=index)}invalidate(){this.submenuComponent?.invalidate?.()}render(width){return this.submenuComponent?this.submenuComponent.render(width):this.renderMainList(width)}renderMainList(width){let lines=[];if(this.searchEnabled&&this.searchInput&&(lines.push(...this.searchInput.render(width)),lines.push("")),this.items.length===0)return lines.push(this.theme.hint(" No settings available")),this.searchEnabled&&this.addHintLine(lines,width),lines;let displayItems=this.getDisplayItems();if(displayItems.length===0)return lines.push(truncateToWidth(this.theme.hint(" No matching settings"),width)),this.addHintLine(lines,width),lines;let{startIndex,endIndex}=this.getVisibleRange(displayItems),maxLabelWidth=Math.min(36,Math.max(...this.items.map(item=>visibleWidth(item.label))));for(let i=startIndex;i<endIndex;i++){let item=displayItems[i];if(!item)continue;let isSelected=i===this.selectedIndex,prefix=isSelected?this.theme.cursor:" ",prefixWidth=visibleWidth(prefix),labelPadded=item.label+" ".repeat(Math.max(0,maxLabelWidth-visibleWidth(item.label))),labelText=this.theme.label(labelPadded,isSelected),separator=" ",usedWidth=prefixWidth+maxLabelWidth+visibleWidth(separator),valueMaxWidth=width-usedWidth-2,valueText=this.theme.value(truncateToWidth(item.currentValue,valueMaxWidth,""),isSelected);lines.push(truncateToWidth(prefix+labelText+separator+valueText,width))}if(startIndex>0||endIndex<displayItems.length){let scrollText=` (${this.selectedIndex+1}/${displayItems.length})`;lines.push(this.theme.hint(truncateToWidth(scrollText,width-2,"")))}let selectedItem=displayItems[this.selectedIndex];if(selectedItem?.description){lines.push("");let wrappedDesc=wrapTextWithAnsi(selectedItem.description,width-4);for(let line of wrappedDesc)lines.push(this.theme.description(` ${line}`))}return this.addHintLine(lines,width),lines}handleMouse(event){if(this.submenuComponent){let result=this.submenuComponent.handleMouse?.(event);return result?{...result,focus:!0}:void 0}if(this.searchEnabled&&this.searchInput){if(event.y===0){let result=this.searchInput.handleMouse?.(event);return result?{...result,focus:!0}:void 0}if(event.y===1)return}let displayItems=this.getDisplayItems();if(displayItems.length===0)return;if(event.type==="wheel"&&event.wheelDelta){let delta=event.wheelDelta<0?-1:1,previousIndex=this.selectedIndex;return this.selectedIndex=Math.max(0,Math.min(displayItems.length-1,this.selectedIndex+delta)),{handled:!0,render:this.selectedIndex!==previousIndex}}if(event.button!=="left"||event.type!=="press"&&event.type!=="click")return;let rowOffset=this.searchEnabled?2:0,{startIndex,endIndex}=this.getVisibleRange(displayItems),itemIndex=startIndex+event.y-rowOffset;if(!(itemIndex<startIndex||itemIndex>=endIndex)){if(event.type==="press")return this.mousePressedIndex=itemIndex,this.selectedIndex=itemIndex,{handled:!0,focus:!0};if(event.type==="click")return this.selectedIndex=this.mousePressedIndex??itemIndex,this.mousePressedIndex=void 0,this.activateItem(),{handled:!0}}}handleInput(data){if(this.submenuComponent){this.submenuComponent.handleInput?.(data);return}let kb=getKeybindings(),displayItems=this.getDisplayItems();if(kb.matches(data,"tui.select.up")){if(displayItems.length===0)return;this.selectedIndex=this.selectedIndex===0?displayItems.length-1:this.selectedIndex-1}else if(kb.matches(data,"tui.select.down")){if(displayItems.length===0)return;this.selectedIndex=this.selectedIndex===displayItems.length-1?0:this.selectedIndex+1}else kb.matches(data,"tui.select.confirm")||data===" "&&(!this.searchEnabled||this.searchInput?.getValue().length===0)?this.activateItem():kb.matches(data,"tui.select.cancel")?this.onCancel():this.searchEnabled&&this.searchInput&&(this.searchInput.handleInput(data),this.applyFilter(this.searchInput.getValue()))}getDisplayItems(){return this.searchEnabled?this.filteredItems:this.items}getVisibleRange(displayItems){let startIndex=Math.max(0,Math.min(this.selectedIndex-Math.floor(this.maxVisible/2),displayItems.length-this.maxVisible));return{startIndex,endIndex:Math.min(startIndex+this.maxVisible,displayItems.length)}}activateItem(){let item=this.getDisplayItems()[this.selectedIndex];if(item){if(item.submenu)this.submenuItemIndex=this.selectedIndex,this.submenuComponent=item.submenu(item.currentValue,(selectedValue,options)=>{selectedValue!==void 0&&(item.currentValue=selectedValue,this.onChange(item.id,selectedValue)),options?.navigateTo&&(this.navigateAfterClose=options.navigateTo),this.closeSubmenu()});else if(item.values&&item.values.length>0){let nextIndex=(item.values.indexOf(item.currentValue)+1)%item.values.length,newValue=item.values[nextIndex];item.currentValue=newValue,this.onChange(item.id,newValue)}}}closeSubmenu(){if(this.submenuComponent=null,this.navigateAfterClose!==null){let id=this.navigateAfterClose;this.navigateAfterClose=null,this.submenuItemIndex=null,this.selectItem(id),this.activateItem()}else this.submenuItemIndex!==null&&(this.selectedIndex=this.submenuItemIndex,this.submenuItemIndex=null)}applyFilter(query){this.filteredItems=fuzzyFilter(this.items,query,item=>item.label),this.selectedIndex=0}addHintLine(lines,width){lines.push(""),lines.push(truncateToWidth(this.theme.hint(this.searchEnabled?" Type to search \xB7 Enter/Space to change \xB7 Esc to cancel":" Enter/Space to change \xB7 Esc to cancel"),width))}};var VStack=class extends Stack{constructor(children=[],options={}){super(children,options),this.layoutType="vstack"}render(width){let viewport={width:Math.max(1,width),height:Number.MAX_SAFE_INTEGER},entries=visibleStackEntries(this.entries,viewport),rendered=entries.map(entry=>entry.component.render(viewport.width)),sizes=allocateStackSizes(entries,rendered.map(lines2=>lines2.length),void 0,this.gap),lines=[];for(let index=0;index<entries.length;index++){if(index>0)for(let gap=0;gap<this.gap;gap++)lines.push("");let childLines=rendered[index].slice(0,sizes[index]);lines.push(...childLines);for(let padding=childLines.length;padding<sizes[index];padding++)lines.push("")}return lines}};function calculateImageRows(imageDimensions,targetWidthCells,cellDimensions2={widthPx:9,heightPx:18}){return calculateImageCellSize(imageDimensions,targetWidthCells,void 0,cellDimensions2).rows}export{outerKittyGraphicsMode,sanitizeTerminalLabel,detectCapabilities,getCapabilities,getTerminalColorMode,setCapabilityOverrides,getImageDimensions,hyperlink,imageFallback,x,Q,Key,isKeyRelease,matchesKey,decodeKittyPrintable,TUI_KEYBINDINGS,KeybindingsManager,setKeybindings,getKeybindings,getGraphemeSegmenter,visibleWidth,stripTerminalSequences,wrapTextWithAnsi,truncateToWidth,sliceByColumn,dispatchMouseEvent,frameMode,mainScreenHistoryLines,frameScrollbackRows,claimFrameRow,renderAtFrameRow,nextRenderRevision,currentRenderRevision,Container,joinLineArrays,isViewportTUI,TUI,Input,fuzzyMatch,fuzzyMatchLower,fuzzyFilter,CombinedAutocompleteProvider,oklabToOkhslLightness,indexedColor,rgbColor,oklchColor,okhslColor,colorToOkhsl,parseColor,colorToRgb,colorToOklch,colorToHex,mixColors,foregroundAnsi,backgroundAnsi,styleTextWithAnsi,Box,Text,Loader,CancellableLoader,expandPasteMarkers,getNativeClipboard,isWarpWslSession,ProcessTerminal,SelectList,Editor,Image,Markdown,MouseRegion,ScrollView,SettingsList,Spacer,TruncatedText,VStack,TuiAltScreen,TuiMainScreen,dist_exports};
|
|
@@ -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{KeybindingsManager,TUI_KEYBINDINGS,isWarpWslSession}from"./chunk-
|
|
2
|
+
import{KeybindingsManager,TUI_KEYBINDINGS,isWarpWslSession}from"./chunk-J5MUMVWB.js";import{getAgentDir,stripBom}from"./chunk-463OK2Y4.js";import{existsSync,readFileSync}from"fs";import{join}from"path";function useWindowsKeybindings(platform=process.platform,env=process.env){return platform==="win32"||platform==="linux"&&!!(env.WSL_DISTRO_NAME||env.WSL_INTEROP)}var windowsKeybindings=useWindowsKeybindings(),QUESTION_ANSWER_PRIMARY_KEY="alt+up",QUESTION_ANSWER_FALLBACK_KEY="alt+a",KEYBINDINGS={...TUI_KEYBINDINGS,"tui.editor.undo":{...TUI_KEYBINDINGS["tui.editor.undo"],defaultKeys:process.platform==="win32"?"ctrl+z":windowsKeybindings?"alt+z":"ctrl+-"},"tui.altScreen.previousPrompt":{...TUI_KEYBINDINGS["tui.altScreen.previousPrompt"],defaultKeys:windowsKeybindings?"ctrl+up":["ctrl+shift+up","ctrl+up"]},"tui.altScreen.nextPrompt":{...TUI_KEYBINDINGS["tui.altScreen.nextPrompt"],defaultKeys:windowsKeybindings?"ctrl+down":["ctrl+shift+down","ctrl+down"]},"tui.altScreen.search":{...TUI_KEYBINDINGS["tui.altScreen.search"],defaultKeys:windowsKeybindings?"ctrl+f":"ctrl+shift+f"},"app.interrupt":{defaultKeys:"escape",description:"Cancel or abort"},"app.clear":{defaultKeys:"ctrl+c",description:"Clear editor"},"app.exit":{defaultKeys:"ctrl+d",description:"Exit when editor is empty"},"app.suspend":{defaultKeys:process.platform==="win32"?[]:"ctrl+z",description:"Suspend to background"},"app.thinking.cycle":{defaultKeys:"shift+tab",description:"Cycle thinking level"},"app.thinking.save":{defaultKeys:"ctrl+s",description:"Save thinking level"},"app.model.cycleForward":{defaultKeys:"ctrl+p",description:"Cycle to next model"},"app.model.cycleBackward":{defaultKeys:windowsKeybindings?"alt+p":"shift+ctrl+p",description:"Cycle to previous model"},"app.model.select":{defaultKeys:"ctrl+l",description:"Open model selector"},"app.history.search":{defaultKeys:"ctrl+r",description:"Search prompt history across sessions"},"app.tools.expand":{defaultKeys:"ctrl+o",description:"Toggle tool output"},"app.thinking.toggle":{defaultKeys:"ctrl+t",description:"Toggle thinking blocks"},"app.session.toggleNamedFilter":{defaultKeys:"ctrl+n",description:"Toggle named session filter"},"app.editor.external":{defaultKeys:"ctrl+g",description:"Open external editor"},"app.message.copy":{defaultKeys:"ctrl+x",description:"Copy selection or last assistant message"},"app.message.followUp":{defaultKeys:windowsKeybindings?"ctrl+q":"alt+enter",description:"Queue follow-up message"},"app.message.dequeue":{defaultKeys:windowsKeybindings?"alt+q":"alt+up",description:"Restore queued messages"},"app.question.answer":{defaultKeys:[QUESTION_ANSWER_PRIMARY_KEY,QUESTION_ANSWER_FALLBACK_KEY],description:"Open the pending question"},"app.question.next":{defaultKeys:"alt+down",description:"Show the next pending question"},"app.clipboard.pasteImage":{defaultKeys:isWarpWslSession()?["ctrl+v","alt+v"]:windowsKeybindings?"alt+v":"ctrl+v",description:"Paste files on macOS, images, or text from clipboard"},"app.session.new":{defaultKeys:[],description:"Start a new session"},"app.session.tree":{defaultKeys:[],description:"Open session tree"},"app.session.fork":{defaultKeys:[],description:"Fork current session"},"app.session.resume":{defaultKeys:[],description:"Resume a session"},"app.session.renameCurrent":{defaultKeys:[],description:"Rename the current session"},"app.tree.foldOrUp":{defaultKeys:process.platform==="darwin"?["alt+left","ctrl+left"]:["ctrl+left","alt+left"],description:"Fold tree branch or move up"},"app.tree.unfoldOrDown":{defaultKeys:process.platform==="darwin"?["alt+right","ctrl+right"]:["ctrl+right","alt+right"],description:"Unfold tree branch or move down"},"app.tree.editLabel":{defaultKeys:"shift+l",description:"Edit tree label"},"app.tree.editMessage":{defaultKeys:"ctrl+e",description:"Edit the selected assistant response, or reopen a user message in the editor"},"app.tree.toggleLabelTimestamp":{defaultKeys:"shift+t",description:"Toggle tree label timestamps"},"app.session.togglePath":{defaultKeys:"ctrl+p",description:"Toggle session path display"},"app.session.toggleSort":{defaultKeys:"ctrl+s",description:"Toggle session sort mode"},"app.session.rename":{defaultKeys:"ctrl+r",description:"Rename session"},"app.session.delete":{defaultKeys:"ctrl+d",description:"Delete session"},"app.session.deleteNoninvasive":{defaultKeys:"ctrl+backspace",description:"Delete session when query is empty"},"app.models.save":{defaultKeys:"ctrl+s",description:"Save model selection"},"app.models.toggleFavorite":{defaultKeys:"ctrl+f",description:"Toggle favorite model"},"app.models.enableAll":{defaultKeys:"ctrl+a",description:"Enable all models"},"app.models.clearAll":{defaultKeys:"ctrl+x",description:"Clear all models"},"app.models.toggleProvider":{defaultKeys:"ctrl+p",description:"Toggle all models for provider"},"app.models.reorderUp":{defaultKeys:"alt+up",description:"Move model up in order"},"app.models.reorderDown":{defaultKeys:"alt+down",description:"Move model down in order"},"app.tree.filter.default":{defaultKeys:"ctrl+d",description:"Tree filter: default view"},"app.tree.filter.noTools":{defaultKeys:"ctrl+t",description:"Tree filter: hide tool results"},"app.tree.filter.userOnly":{defaultKeys:"ctrl+u",description:"Tree filter: user messages only"},"app.tree.filter.labeledOnly":{defaultKeys:"ctrl+l",description:"Tree filter: labeled entries only"},"app.tree.filter.all":{defaultKeys:"ctrl+a",description:"Tree filter: show all entries"},"app.tree.filter.cycleForward":{defaultKeys:"ctrl+o",description:"Tree filter: cycle forward"},"app.tree.filter.cycleBackward":{defaultKeys:"shift+ctrl+o",description:"Tree filter: cycle backward"}},KEYBINDING_NAME_MIGRATIONS={cursorUp:"tui.editor.cursorUp",cursorDown:"tui.editor.cursorDown",cursorLeft:"tui.editor.cursorLeft",cursorRight:"tui.editor.cursorRight",cursorWordLeft:"tui.editor.cursorWordLeft",cursorWordRight:"tui.editor.cursorWordRight",cursorLineStart:"tui.editor.cursorLineStart",cursorLineEnd:"tui.editor.cursorLineEnd",jumpForward:"tui.editor.jumpForward",jumpBackward:"tui.editor.jumpBackward",pageUp:"tui.editor.pageUp",pageDown:"tui.editor.pageDown",deleteCharBackward:"tui.editor.deleteCharBackward",deleteCharForward:"tui.editor.deleteCharForward",deleteWordBackward:"tui.editor.deleteWordBackward",deleteWordForward:"tui.editor.deleteWordForward",deleteToLineStart:"tui.editor.deleteToLineStart",deleteToLineEnd:"tui.editor.deleteToLineEnd",yank:"tui.editor.yank",yankPop:"tui.editor.yankPop",undo:"tui.editor.undo",newLine:"tui.input.newLine",submit:"tui.input.submit",tab:"tui.input.tab",copy:"tui.input.copy",selectUp:"tui.select.up",selectDown:"tui.select.down",selectPageUp:"tui.select.pageUp",selectPageDown:"tui.select.pageDown",selectConfirm:"tui.select.confirm",selectCancel:"tui.select.cancel",interrupt:"app.interrupt",clear:"app.clear",exit:"app.exit",suspend:"app.suspend",cycleThinkingLevel:"app.thinking.cycle",cycleModelForward:"app.model.cycleForward",cycleModelBackward:"app.model.cycleBackward",selectModel:"app.model.select",expandTools:"app.tools.expand",toggleThinking:"app.thinking.toggle",toggleSessionNamedFilter:"app.session.toggleNamedFilter",externalEditor:"app.editor.external",followUp:"app.message.followUp",dequeue:"app.message.dequeue",pasteImage:"app.clipboard.pasteImage",newSession:"app.session.new",tree:"app.session.tree",fork:"app.session.fork",resume:"app.session.resume",treeFoldOrUp:"app.tree.foldOrUp",treeUnfoldOrDown:"app.tree.unfoldOrDown",treeEditLabel:"app.tree.editLabel",treeEditMessage:"app.tree.editMessage",treeToggleLabelTimestamp:"app.tree.toggleLabelTimestamp",toggleSessionPath:"app.session.togglePath",toggleSessionSort:"app.session.toggleSort",renameSession:"app.session.rename",deleteSession:"app.session.delete",deleteSessionNoninvasive:"app.session.deleteNoninvasive"};function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function hasOwn(value,key){return Object.hasOwn(value,key)}function isLegacyKeybindingName(key){return key in KEYBINDING_NAME_MIGRATIONS}function toKeybindingsConfig(value){let config={};for(let[key,binding]of Object.entries(value)){if(typeof binding=="string"){config[key]=binding;continue}Array.isArray(binding)&&binding.every(entry=>typeof entry=="string")&&(config[key]=binding)}return config}function migrateKeybindingsConfig(rawConfig){let config={},migrated=!1;for(let[key,value]of Object.entries(rawConfig)){let nextKey=isLegacyKeybindingName(key)?KEYBINDING_NAME_MIGRATIONS[key]:key;if(nextKey!==key&&(migrated=!0),key!==nextKey&&hasOwn(rawConfig,nextKey)){migrated=!0;continue}config[nextKey]=value}return{config:orderKeybindingsConfig(config),migrated}}function orderKeybindingsConfig(config){let ordered={};for(let keybinding of Object.keys(KEYBINDINGS))hasOwn(config,keybinding)&&(ordered[keybinding]=config[keybinding]);let extras=Object.keys(config).filter(key=>!hasOwn(ordered,key)).sort();for(let key of extras)ordered[key]=config[key];return ordered}function loadRawConfig(path){if(existsSync(path))try{let parsed=JSON.parse(stripBom(readFileSync(path,"utf-8")));return isRecord(parsed)?parsed:void 0}catch{return}}var KeybindingsManager2=class _KeybindingsManager extends KeybindingsManager{constructor(userBindings={},configPath){super(KEYBINDINGS,userBindings),this.configPath=configPath}static create(agentDir=getAgentDir()){let configPath=join(agentDir,"keybindings.json"),userBindings=_KeybindingsManager.loadFromFile(configPath);return new _KeybindingsManager(userBindings,configPath)}reload(){this.configPath&&this.setUserBindings(_KeybindingsManager.loadFromFile(this.configPath))}getEffectiveConfig(){return this.getResolvedBindings()}static loadFromFile(path){let rawConfig=loadRawConfig(path);return rawConfig?toKeybindingsConfig(migrateKeybindingsConfig(rawConfig).config):{}}};export{QUESTION_ANSWER_PRIMARY_KEY,QUESTION_ANSWER_FALLBACK_KEY,KEYBINDINGS,migrateKeybindingsConfig,KeybindingsManager2 as KeybindingsManager};
|