@code-yeongyu/senpi 2026.10.25-1 → 2026.10.25-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/bundle/chunks/{chunk-BTNYLNWZ.js → chunk-2EFVQWXZ.js} +2 -2
- package/dist/bundle/chunks/{chunk-RHHBXIRN.js → chunk-4WZRVZNX.js} +1 -1
- package/dist/bundle/chunks/{chunk-J5P2VL3Y.js → chunk-B6TPQDBW.js} +1 -1
- package/dist/bundle/chunks/{chunk-VOBD6FQG.js → chunk-FHXR4ZAC.js} +1 -1
- package/dist/bundle/chunks/{chunk-7IRLFYNM.js → chunk-G2UETS2R.js} +2 -2
- package/dist/bundle/chunks/{chunk-URBJS24R.js → chunk-J2U5VDG7.js} +15 -15
- package/dist/bundle/chunks/{chunk-YDCRA5ES.js → chunk-JRXKLIEQ.js} +1 -1
- package/dist/bundle/chunks/{chunk-3VOG6WFU.js → chunk-KJZAY5YH.js} +1 -1
- package/dist/bundle/chunks/{chunk-EYBDBR7V.js → chunk-KUE4AQN6.js} +1 -1
- package/dist/bundle/chunks/{chunk-FWXMMMCV.js → chunk-LYGAV6KU.js} +1 -1
- package/dist/bundle/chunks/{chunk-SGDOZT6B.js → chunk-MXZPAUFB.js} +1 -1
- package/dist/bundle/chunks/chunk-O5RYI3IW.js +2 -0
- package/dist/bundle/chunks/{chunk-II22E3CV.js → chunk-OI4NMCKP.js} +1 -1
- package/dist/bundle/chunks/{chunk-7UUOGZKR.js → chunk-RXKNOEQQ.js} +1 -1
- package/dist/bundle/chunks/{chunk-QH2HSCMX.js → chunk-TTU2RNVX.js} +3 -3
- package/dist/bundle/chunks/{chunk-PXKF2RHD.js → chunk-UFJ2K7Q7.js} +1 -1
- package/dist/bundle/chunks/chunk-VNN2V74Y.js +5 -0
- package/dist/bundle/chunks/{chunk-BMYNMUVZ.js → chunk-W2BKZBYJ.js} +1 -1
- package/dist/bundle/chunks/{chunk-RVYSJBZ7.js → chunk-WFXUCVIR.js} +1 -1
- package/dist/bundle/chunks/{chunk-7WAJCESX.js → chunk-XBUSVKWC.js} +1 -1
- package/dist/bundle/chunks/{chunk-EWOEVVQT.js → chunk-YN7ELQ43.js} +1 -1
- package/dist/bundle/chunks/{cli-main-TABBP55A.js → cli-main-SWKFMTZQ.js} +1 -1
- package/dist/bundle/chunks/{host-command-OQR4RDTM.js → host-command-BC6UWP33.js} +1 -1
- package/dist/bundle/chunks/{host-lifecycle-U36U7JTE.js → host-lifecycle-TN5NEGNF.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle.js +3 -3
- package/dist/bundle/chunks/{host-session-command-IGB27ZPJ.js → host-session-command-MGVBLBRV.js} +1 -1
- package/dist/bundle/chunks/{host-socket-request-ZDJGSSZO.js → host-socket-request-AS2OCRLP.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-DGQNSXUA.js → interactive-mode-SCSROHD5.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-M7HVUMRH.js → multi-session-host-VTTY5MFT.js} +1 -1
- package/dist/bundle/chunks/{package-manager-cli-FSR5P6YL.js → package-manager-cli-DZFOC3MF.js} +1 -1
- package/dist/bundle/chunks/{role-M2MTVACJ.js → role-JVSBNKGE.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-SZAJNKKL.js → rpc-mode-TOXYD4XA.js} +1 -1
- package/dist/bundle/chunks/{rpc-monitor-source-OL5KU6NO.js → rpc-monitor-source-B5NQ4ZVH.js} +1 -1
- package/dist/bundle/chunks/{runtime-session-CLNODAYE.js → runtime-session-V5OO7ZRM.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-XBW4EOG5.js → schedule-command-SLISTG4V.js} +1 -1
- package/dist/bundle/chunks/{session-control-endpoint-WEF3XTJR.js → session-control-endpoint-HFFMBALG.js} +1 -1
- package/dist/bundle/chunks/{session-picker-KQUFWDQC.js → session-picker-465FVXQG.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +18 -18
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/host-supervisor.js +3 -3
- 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.d.ts +1 -0
- package/dist/core/agent-session.js +28 -9
- package/dist/core/engine-turn-limit.d.ts +2 -0
- package/dist/core/engine-turn-limit.js +7 -1
- package/dist/core/extensions/builtin/anthropic-subscription/auth-attempt.js +5 -0
- package/dist/core/extensions/builtin/goal/stop-pause.js +2 -1
- package/dist/core/extensions/builtin/loop/session-hold.js +2 -1
- package/dist/core/lifecycle-runtime-facts.js +3 -0
- package/dist/core/lifecycle-session-binding.js +6 -2
- package/dist/core/run-resume-turn.d.ts +1 -0
- package/dist/core/run-resume-turn.js +4 -3
- package/dist/core/stop-resume-directive.d.ts +1 -1
- package/dist/core/stop-resume-directive.js +10 -1
- package/dist/modes/interactive/interactive-mode.js +1 -0
- package/dist/modes/interactive/pause-footer.d.ts +5 -0
- package/dist/modes/interactive/pause-footer.js +2 -0
- package/dist/modes/rpc/host-reservations.js +3 -2
- package/dist/modes/rpc/host-stalled-evidence.js +2 -1
- package/dist/modes/rpc/tool-child/group-ownership.js +4 -2
- package/dist/utils/process-identity.d.ts +7 -0
- package/dist/utils/process-identity.js +32 -5
- package/package.json +6 -6
- package/dist/bundle/chunks/chunk-7ASLQ243.js +0 -2
- package/dist/bundle/chunks/chunk-XUFUKDKJ.js +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2026.10.25-2] - 2026-10-25
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- `senpi host gc` and the gc pass after an ensure no longer keep a dead endpoint (as `live_generation` or `live_claim`) while its SIGKILLed supervisor or host child is exited but not yet reaped, and a tool child's teardown still sweeps a process group whose leader is in that state: liveness now treats a process in state Z as gone ([#4119](https://github.com/code-yeongyu/senpi/issues/4119))
|
|
14
|
+
- Keep interrupted sessions open when automatic continuation is enabled, holding automatic work until explicit Resume or input ([#4206](https://github.com/code-yeongyu/senpi/pull/4206)).
|
|
15
|
+
- Keep Claude Code auto memory out of Anthropic subscription sessions, including when the inherited environment or SDK settings enable it ([#4222](https://github.com/code-yeongyu/senpi/pull/4222)).
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
|
|
3
19
|
## [2026.10.25-1] - 2026-10-25
|
|
4
20
|
|
|
5
21
|
### Breaking Changes
|
|
@@ -162,7 +162,7 @@ Continue from where the conversation ends.
|
|
|
162
162
|
|
|
163
163
|
Your last reply may have been edited by the user; treat its current text as your own words.
|
|
164
164
|
Carry on from it without repeating it, apologizing for it, or commenting on the edit.
|
|
165
|
-
</system-notice>`,CONTINUE_FROM_LEAF_MESSAGES={streaming:"Wait for the current response to finish before continuing.",nothing_to_continue:"There is nothing to continue: the session has no messages yet.",leaf_not_assistant:"There is no answer to continue: the conversation ends on a user message. Send it, or retry it, instead."},ContinueFromLeafError=class extends Error{constructor(code){super(CONTINUE_FROM_LEAF_MESSAGES[code]),this.name="ContinueFromLeafError",this.code=code}};function trackTurnAdmission(input){let resolveStarted,promise=new Promise(resolve6=>{resolveStarted=resolve6}),agentStartSeen=!1,startDispositionSeen=!1,maybeStarted=()=>{agentStartSeen&&startDispositionSeen&&resolveStarted?.()};input.disposition.then(disposition=>{if(disposition==="delegated"){resolveStarted?.();return}disposition==="started"&&(startDispositionSeen=!0,maybeStarted())});let unsubscribe=input.subscribe(event=>{event.type==="agent_start"&&(agentStartSeen=!0,maybeStarted())});return{promise,dispose:unsubscribe}}var STOP_RESUME_CUSTOM_TYPE="session-resumed",DIRECTIVE="<system-reminder>The user stopped the previous turn and has now resumed. Tool calls that the Stop interrupted show an aborted result; they were not re-run and their side effects may be partial. Check their effects before repeating any of them, then continue the work.</system-reminder>";function stopResumeDirective(){return{customType:STOP_RESUME_CUSTOM_TYPE,content:DIRECTIVE,display:!1}}var MAX_ENGINE_TURNS_PER_USER_INPUT=0,MAX_ENGINE_TURNS_PER_RESUME_WINDOW=8,MAX_TOOL_FREE_ENGINE_TURNS_PER_WINDOW=12,ENGINE_TURN_WINDOW_MS=6e4,ENGINE_TURN_START_ENTRY_TYPE="engine-turn-start",ENGINE_TURN_LIMIT_ENTRY_TYPE="engine-turn-limit",ENGINE_TURN_LIMIT_EVENT="engine:turn-limit";function engineTurnLimitNotice(stop){return stop.reason==="resume-window"?`Paused: the agent started ${stop.sinceUserInput} turns on its own in this resume window. Send any message to continue.`:stop.reason==="per-user-input"?`Paused: the agent started ${stop.sinceUserInput} turns on its own since your last message. Send any message to continue.`:`Paused: the agent started ${stop.toolFreeInWindow} turns on its own in the last minute without doing any work. Send any message to continue.`}function isUserDirectedTurn(customType){return customType===MANUAL_CONTINUE_CUSTOM_TYPE||customType===CONTINUE_FROM_LEAF_CUSTOM_TYPE||customType===STOP_RESUME_CUSTOM_TYPE}function isUserMessage(entry){return entry.type==="custom_message"?isUserDirectedTurn(entry.customType):entry.type==="message"&&entry.message.role==="user"}function isEngineTurnStart(entry){return entry.type==="custom"&&entry.customType===ENGINE_TURN_START_ENTRY_TYPE}function callsATool(entry){return entry.type==="message"&&entry.message.role==="assistant"&&entry.message.content.some(block=>block.type==="toolCall")}var engineTurnHistory={initial:()=>({starts:[]}),add:(history,entry)=>{if(isUserMessage(entry))return{starts:[]};if(isEngineTurnStart(entry))history.starts.push({at:Date.parse(entry.timestamp),toolUsed:!1});else if(callsATool(entry)){let latest=history.starts.at(-1);latest!==void 0&&(latest.toolUsed=!0)}return history}};function engineTurnStop(history,now,limits,inProcess=[]){let sinceUserInput=history.starts.length,toolFreeInWindow=0;for(let start of history.starts)now-start.at>=ENGINE_TURN_WINDOW_MS||start.toolUsed||(toolFreeInWindow+=1);sinceUserInput=Math.max(sinceUserInput,inProcess.length),toolFreeInWindow=Math.max(toolFreeInWindow,inProcess.filter(record=>!record.toolUsed&&now-record.at<ENGINE_TURN_WINDOW_MS).length);let resumeLimit=limits.maxPerResumeWindow??0;return resumeLimit>0&&sinceUserInput>=resumeLimit?{reason:"resume-window",sinceUserInput,toolFreeInWindow}:limits.maxPerUserInput>0&&sinceUserInput>=limits.maxPerUserInput?{reason:"per-user-input",sinceUserInput,toolFreeInWindow}:limits.maxToolFreePerMinute>0&&toolFreeInWindow>=limits.maxToolFreePerMinute?{reason:"tool-free-rate",sinceUserInput,toolFreeInWindow}:null}import{resolve as resolve4}from"node:path";function isHealthExhaustionFailure(errorMessage){return isBillingErrorMessage(errorMessage)||isQuotaExhaustionMessage(errorMessage)}var CircuitProbes=class{constructor(circuits){this.circuits=circuits}isOpen(selector){return this.circuits?.isOpen(selector)??!1}governs(selector){return this.circuits?.governs(selector)??!1}isExhausted(selector){return this.circuits?.isExhausted(selector)??!1}admit(selector){let admission=this.circuits?.admit(selector)??{kind:"closed"};return admission.kind==="probe"&&this.token?.selector!==selector&&(this.release(),this.token=admission.token),admission.kind}holds(selector){return this.token?.selector===selector}get probing(){return this.token?.selector}noteFailure(selector,failure){this.circuits?.noteFailure(selector,failure),this.token?.selector===selector&&(this.token=void 0)}accept(selector){this.circuits?.close(selector),this.token?.selector===selector&&(this.token=void 0)}release(){this.token&&this.circuits?.release(this.token),this.token=void 0}releaseAll(){this.token=void 0,this.circuits?.releaseAll()}};var DEFAULT_CIRCUIT_COOLDOWN_MS=6e4,DEFAULT_CIRCUIT_MAX_COOLDOWN_MS=30*6e4;function nonNegativeMs(value,fallback){return typeof value=="number"&&Number.isFinite(value)&&value>=0?value:fallback}function resolveFallbackCircuitSettings(settings){let cooldownMs=nonNegativeMs(settings?.circuitCooldownMs,DEFAULT_CIRCUIT_COOLDOWN_MS),maxCooldownMs=nonNegativeMs(settings?.circuitMaxCooldownMs,DEFAULT_CIRCUIT_MAX_COOLDOWN_MS);return{cooldownMs,maxCooldownMs:Math.max(cooldownMs,maxCooldownMs)}}var FallbackCircuitBreaker=class{constructor(){this.circuits=new Map,this.generations=0}get size(){return this.circuits.size}open(selector,request){let previous=this.circuits.get(selector),sameEpisode=previous!==void 0&&request.now<previous.openUntil,consecutiveOpens=(previous?.consecutiveOpens??0)+(sameEpisode?0:1),cooldownMs=sameEpisode?previous.cooldownMs:Math.min(request.cooldownMs*2**(consecutiveOpens-1),request.maxCooldownMs),retryAfterMs=request.retryAfterMs,hinted=retryAfterMs!==void 0&&Number.isFinite(retryAfterMs)&&retryAfterMs>0?request.now+retryAfterMs:0,retryFloorUntil=Math.max(hinted,previous&&previous.retryFloorUntil>request.now?previous.retryFloorUntil:0),resetWindowMs=request.resetWindowMs,hintedUntil=Math.min(retryFloorUntil,request.now+request.maxCooldownMs),openUntil=resetWindowMs!==void 0&&Number.isFinite(resetWindowMs)&&resetWindowMs>0?Math.max(request.now+Math.min(resetWindowMs,request.maxCooldownMs),hintedUntil):Math.max(sameEpisode?previous.openUntil:request.now+cooldownMs,hintedUntil);return this.circuits.set(selector,{openUntil,retryFloorUntil,consecutiveOpens,cooldownMs,maxCooldownMs:request.maxCooldownMs,probe:void 0,exhausted:request.exhausted===!0||sameEpisode&&previous.exhausted}),openUntil}isOpen(selector,now,owner){let circuit=this.circuits.get(selector);return circuit?now<circuit.openUntil?!0:circuit.probe!==void 0&&circuit.probe.owner!==owner:!1}admit(selector,now,owner){let circuit=this.circuits.get(selector);return circuit?now<circuit.openUntil?{kind:"open"}:circuit.probe&&circuit.probe.owner!==owner?{kind:"open"}:(circuit.probe??={owner,generation:++this.generations},{kind:"probe",token:{selector,owner,generation:circuit.probe.generation}}):{kind:"closed"}}release(token){let probe=this.circuits.get(token.selector)?.probe;if(probe&&probe.owner===token.owner&&probe.generation===token.generation){let circuit=this.circuits.get(token.selector);circuit&&(circuit.probe=void 0)}}releaseOwnersWithPrefix(prefix){for(let circuit of this.circuits.values())circuit.probe?.owner.startsWith(prefix)&&(circuit.probe=void 0)}close(selector){this.circuits.delete(selector)}has(selector){return this.circuits.has(selector)}isExhausted(selector){return this.circuits.get(selector)?.exhausted===!0}sweep(now){for(let[selector,circuit]of this.circuits)!circuit.probe&&now>=circuit.openUntil+circuit.maxCooldownMs&&this.circuits.delete(selector)}};function createFallbackCircuitAccess(deps){let enabled=()=>deps.settings().cooldownMs>0;return{noteFailure(selector,failure){if(!enabled())return;let{cooldownMs,maxCooldownMs}=deps.settings(),now=deps.now(),message=failure.errorMessage,retryAfterMs=failure.retryAfterMs??(message===void 0?void 0:parseRetryAfterMsMarker(message)),reset=message!==void 0&&usageLimitScope(message)!==void 0?usageLimitReset(message,(deps.wallNow??deps.now)()):void 0,resetWindowMs=reset!==void 0&&(reset.kind==="absolute"||reset.ms>=cooldownMs)?reset.ms:void 0;deps.breaker.sweep(now);let exhausted=message!==void 0&&(isHealthExhaustionFailure(message)||usageLimitScope(message)==="account"),openUntil=deps.breaker.open(selector,{now,cooldownMs,maxCooldownMs,retryAfterMs,resetWindowMs,exhausted});deps.logger.info("circuit_opened",{selector,durationMs:openUntil-now,retryAfterMs,resetWindowMs})},governs:selector=>enabled()&&deps.breaker.has(selector),isExhausted:selector=>enabled()&&deps.breaker.isExhausted(selector),isOpen:(selector,lane="turn")=>enabled()&&deps.breaker.isOpen(selector,deps.now(),laneOwner(deps.owner(),lane)),admit:(selector,lane="turn")=>enabled()?deps.breaker.admit(selector,deps.now(),laneOwner(deps.owner(),lane)):{kind:"closed"},release:token=>deps.breaker.release(token),releaseAll:()=>deps.breaker.releaseOwnersWithPrefix(`${deps.owner()}:`),close:selector=>deps.breaker.close(selector)}}function laneOwner(session,lane){return`${session}:${lane}`}var breakersByAgentDir=new Map;function evictUnheldEmptyBreakers(){for(let[key,entry]of breakersByAgentDir)entry.owners===0&&entry.breaker.size===0&&breakersByAgentDir.delete(key)}function entryFor(agentDir){let key=resolve4(agentDir),entry=breakersByAgentDir.get(key);return entry||(evictUnheldEmptyBreakers(),entry={breaker:new FallbackCircuitBreaker,owners:0},breakersByAgentDir.set(key,entry)),entry}function acquireFallbackCircuits(agentDir){let entry=entryFor(agentDir);entry.owners++;let released=!1;return{breaker:entry.breaker,release(){released||(released=!0,entry.owners--,evictUnheldEmptyBreakers())}}}function monotonicNow(){return performance.timeOrigin+performance.now()}function isPlainObject2(value){if(value===null||typeof value!="object"||Array.isArray(value))return!1;let prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===null}function describeValue(value){return value===null?"null":Array.isArray(value)?"an array":`a ${typeof value}`}function isNonNegativeSafeInteger2(value){return typeof value=="number"&&Number.isSafeInteger(value)&&value>=0}function isFiniteAtLeast(value,min){return typeof value=="number"&&Number.isFinite(value)&&value>=min}function isFiniteRatio(value){return typeof value=="number"&&Number.isFinite(value)&&value>=0&&value<=1}function validateStageKnobs(stage,providerId,stageName,warnings){if(stage===void 0)return;if(!isPlainObject2(stage)){warnings.push(`retry.providers.${providerId}.${stageName} must be a plain object, but got ${describeValue(stage)}.`);return}let out={},invalid=[];if(stage.enabled!==void 0&&(typeof stage.enabled=="boolean"?out.enabled=stage.enabled:invalid.push("enabled")),stage.maxRetries!==void 0&&(isNonNegativeSafeInteger2(stage.maxRetries)?out.maxRetries=stage.maxRetries:invalid.push("maxRetries")),stage.baseDelayMs!==void 0&&(isNonNegativeSafeInteger2(stage.baseDelayMs)?out.baseDelayMs=stage.baseDelayMs:invalid.push("baseDelayMs")),stage.growthFactor!==void 0&&(isFiniteAtLeast(stage.growthFactor,1)?out.growthFactor=stage.growthFactor:invalid.push("growthFactor")),stage.perAttemptCapMs!==void 0&&(stage.perAttemptCapMs===null?out.perAttemptCapMs=null:isNonNegativeSafeInteger2(stage.perAttemptCapMs)?out.perAttemptCapMs=stage.perAttemptCapMs:invalid.push("perAttemptCapMs")),stage.jitter!==void 0)if(isPlainObject2(stage.jitter)){let mode=stage.jitter.mode;mode==="none"?out.jitter={mode:"none"}:(mode==="additive"||mode==="subtractive")&&isFiniteRatio(stage.jitter.ratio)?out.jitter={mode,ratio:stage.jitter.ratio}:invalid.push("jitter")}else invalid.push("jitter");if(stage.serverHintMaxDelayMs!==void 0&&(stage.serverHintMaxDelayMs===null?out.serverHintMaxDelayMs=null:isNonNegativeSafeInteger2(stage.serverHintMaxDelayMs)?out.serverHintMaxDelayMs=stage.serverHintMaxDelayMs:invalid.push("serverHintMaxDelayMs")),invalid.length>0){warnings.push(`retry.providers.${providerId}.${stageName} has invalid knob(s): ${invalid.join(", ")}.`);return}return out}function validateRetryProviderOverrides(value,knownProviderIds,tieredProviderIds){if(value===void 0)return{overrides:{},warnings:[]};if(!isPlainObject2(value))return{overrides:{},warnings:[`retry.providers must be a plain object keyed by provider id, but got ${describeValue(value)}.`]};let overrides={},warnings=[];for(let[providerId,entry]of Object.entries(value)){if(!knownProviderIds.has(providerId)){warnings.push(`retry.providers.${providerId}: unknown provider id "${providerId}".`);continue}if(!isPlainObject2(entry)){warnings.push(`retry.providers.${providerId} must be a plain object, but got ${describeValue(entry)}.`);continue}let stageWarnings=[],providerRequest=validateStageKnobs(entry.providerRequest,providerId,"providerRequest",stageWarnings),turn=validateStageKnobs(entry.turn,providerId,"turn",stageWarnings);if(stageWarnings.length>0){warnings.push(...stageWarnings);continue}if(tieredProviderIds?.has(providerId)&&(providerRequest?.serverHintMaxDelayMs!==void 0||turn?.serverHintMaxDelayMs!==void 0)){warnings.push(`retry.providers.${providerId}: serverHintMaxDelayMs is invalid for a tiered stage (tier thresholds own that strategy).`);continue}let result={};if(providerRequest!==void 0&&(result.providerRequest=providerRequest),turn!==void 0&&(result.turn=turn),providerRequest===void 0&&turn===void 0){warnings.push(`retry.providers.${providerId} has no recognized knobs.`);continue}overrides[providerId]=result}return{overrides,warnings}}var FABLE55_LAUNCH={modelId:"claude-fable-5-5",mythosModelId:"claude-mythos-5-5",snapshotId:null,minimumClaudeCodeVersion:null,released:!1,promoteDefaults:!1,refusalFallbackModels:["claude-opus-4-8","claude-opus-5"],metadataSource:"models.dev"};function isFable55ModelId(modelId){let normalized=modelId.toLowerCase().replace(/\s+/g,"-");return[FABLE55_LAUNCH.modelId,FABLE55_LAUNCH.mythosModelId,FABLE55_LAUNCH.snapshotId].some(id=>{if(!id)return!1;let family=id.replace(/^claude-/,""),dotted=family.replace(/-(\d+)-(\d+)$/,"-$1.$2");return[family,dotted].some(marker=>{let at=normalized.indexOf(marker);if(at<0)return!1;let before=normalized[at-1],after=normalized[at+marker.length];return(!before||/[/@:._-]/.test(before))&&(!after||/[/@:._-]/.test(after))})})}var DEFAULT_FALLBACK_CHAINS={...FABLE55_LAUNCH.released?{[FABLE55_LAUNCH.modelId]:["claude-opus-5-5:max","claude-opus-5:max"]}:{},"claude-fable-5-1":["claude-opus-5-5:max","claude-opus-5:max"],"claude-fable-5":["claude-opus-5-5:max","claude-opus-5:max"],"claude-opus-5-5":["claude-opus-5:max"]};function cloneDefaultFallbackChains(){let chains={};for(let[key,entries]of Object.entries(DEFAULT_FALLBACK_CHAINS))chains[key]=[...entries];return chains}function isPlainObject3(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function isStringArray(value){return Array.isArray(value)&&value.every(entry=>typeof entry=="string")}function resolveFallbackChains(value){if(value===void 0||!isPlainObject3(value))return cloneDefaultFallbackChains();let chains=cloneDefaultFallbackChains();for(let[key,entries]of Object.entries(value)){if(!isStringArray(entries))return cloneDefaultFallbackChains();chains[key]=[...entries]}return chains}function resolveRetryFallbackSettings(settings){return{modelFallback:typeof settings?.modelFallback=="boolean"?settings.modelFallback:!0,chains:resolveFallbackChains(settings?.fallbackChains),revertPolicy:settings?.fallbackRevertPolicy==="never"?"never":"cooldown-expiry"}}function resolveAbortServerSideFallback(settings){return typeof settings?.abortServerSideFallback=="boolean"?settings.abortServerSideFallback:!0}var DEFAULT_HINTED_WAIT_CAP_MS=3e5,DEFAULT_PROBE_BACK_MAX_MS=36e5;function resolveHintPolicySettings(settings){let hintedWaitCapMs=typeof settings?.hintedWaitCapMs=="number"&&settings.hintedWaitCapMs>=0?settings.hintedWaitCapMs:DEFAULT_HINTED_WAIT_CAP_MS,probeBackMaxMs=typeof settings?.probeBackMaxMs=="number"&&settings.probeBackMaxMs>=0?settings.probeBackMaxMs:DEFAULT_PROBE_BACK_MAX_MS;return probeBackMaxMs<=hintedWaitCapMs?{hintedWaitCapMs:DEFAULT_HINTED_WAIT_CAP_MS,probeBackMaxMs:DEFAULT_PROBE_BACK_MAX_MS}:{hintedWaitCapMs,probeBackMaxMs}}function parseSettingsJson(content){content=stripBom(content);let withoutComments=[],inString=!1,escaped=!1;for(let index=0;index<content.length;index+=1){let char=content[index],next=content[index+1];if(inString){withoutComments.push(char),escaped?escaped=!1:char==="\\"?escaped=!0:char==='"'&&(inString=!1);continue}if(char==='"'){inString=!0,withoutComments.push(char);continue}if(char==="/"&&next==="/"){for(withoutComments.push(" "," "),index+=2;index<content.length&&content[index]!==`
|
|
165
|
+
</system-notice>`,CONTINUE_FROM_LEAF_MESSAGES={streaming:"Wait for the current response to finish before continuing.",nothing_to_continue:"There is nothing to continue: the session has no messages yet.",leaf_not_assistant:"There is no answer to continue: the conversation ends on a user message. Send it, or retry it, instead."},ContinueFromLeafError=class extends Error{constructor(code){super(CONTINUE_FROM_LEAF_MESSAGES[code]),this.name="ContinueFromLeafError",this.code=code}};function trackTurnAdmission(input){let resolveStarted,promise=new Promise(resolve6=>{resolveStarted=resolve6}),agentStartSeen=!1,startDispositionSeen=!1,maybeStarted=()=>{agentStartSeen&&startDispositionSeen&&resolveStarted?.()};input.disposition.then(disposition=>{if(disposition==="delegated"){resolveStarted?.();return}disposition==="started"&&(startDispositionSeen=!0,maybeStarted())});let unsubscribe=input.subscribe(event=>{event.type==="agent_start"&&(agentStartSeen=!0,maybeStarted())});return{promise,dispose:unsubscribe}}var STOP_RESUME_CUSTOM_TYPE="session-resumed",DIRECTIVE="<system-reminder>The user stopped the previous turn and has now resumed. Tool calls that the Stop interrupted show an aborted result; they were not re-run and their side effects may be partial. Check their effects before repeating any of them, then continue the work.</system-reminder>";function stopResumeDirective(cause="stop"){return cause==="interrupted"?{customType:STOP_RESUME_CUSTOM_TYPE,content:"<system-reminder>The previous run was interrupted and has now resumed. Interrupted tool calls may have partial side effects and were not re-run. Check their effects before repeating any of them, then continue the work.</system-reminder>",display:!1,details:{resumeCause:cause}}:{customType:STOP_RESUME_CUSTOM_TYPE,content:DIRECTIVE,display:!1}}var MAX_ENGINE_TURNS_PER_USER_INPUT=0,MAX_ENGINE_TURNS_PER_RESUME_WINDOW=8,MAX_TOOL_FREE_ENGINE_TURNS_PER_WINDOW=12,ENGINE_TURN_WINDOW_MS=6e4,ENGINE_TURN_START_ENTRY_TYPE="engine-turn-start",ENGINE_TURN_LIMIT_ENTRY_TYPE="engine-turn-limit",ENGINE_TURN_LIMIT_EVENT="engine:turn-limit";function engineTurnLimitNotice(stop){return stop.reason==="resume-window"?`Paused: the agent started ${stop.sinceUserInput} turns on its own in this resume window. Send any message to continue.`:stop.reason==="per-user-input"?`Paused: the agent started ${stop.sinceUserInput} turns on its own since your last message. Send any message to continue.`:`Paused: the agent started ${stop.toolFreeInWindow} turns on its own in the last minute without doing any work. Send any message to continue.`}function isUserDirectedTurn(customType){return customType===MANUAL_CONTINUE_CUSTOM_TYPE||customType===CONTINUE_FROM_LEAF_CUSTOM_TYPE||customType===STOP_RESUME_CUSTOM_TYPE}function resetsEngineTurnHistory(customType,details){return isUserDirectedTurn(customType)&&!(customType===STOP_RESUME_CUSTOM_TYPE&&details?.resumeCause==="interrupted")}function isUserMessage(entry){return entry.type==="custom_message"?resetsEngineTurnHistory(entry.customType,entry.details):entry.type==="message"&&entry.message.role==="user"}function isEngineTurnStart(entry){return entry.type==="custom"&&entry.customType===ENGINE_TURN_START_ENTRY_TYPE}function callsATool(entry){return entry.type==="message"&&entry.message.role==="assistant"&&entry.message.content.some(block=>block.type==="toolCall")}var engineTurnHistory={initial:()=>({starts:[]}),add:(history,entry)=>{if(isUserMessage(entry))return{starts:[]};if(isEngineTurnStart(entry))history.starts.push({at:Date.parse(entry.timestamp),toolUsed:!1});else if(callsATool(entry)){let latest=history.starts.at(-1);latest!==void 0&&(latest.toolUsed=!0)}return history}};function engineTurnStop(history,now,limits,inProcess=[]){let sinceUserInput=history.starts.length,toolFreeInWindow=0;for(let start of history.starts)now-start.at>=ENGINE_TURN_WINDOW_MS||start.toolUsed||(toolFreeInWindow+=1);sinceUserInput=Math.max(sinceUserInput,inProcess.length),toolFreeInWindow=Math.max(toolFreeInWindow,inProcess.filter(record=>!record.toolUsed&&now-record.at<ENGINE_TURN_WINDOW_MS).length);let resumeLimit=limits.maxPerResumeWindow??0;return resumeLimit>0&&sinceUserInput>=resumeLimit?{reason:"resume-window",sinceUserInput,toolFreeInWindow}:limits.maxPerUserInput>0&&sinceUserInput>=limits.maxPerUserInput?{reason:"per-user-input",sinceUserInput,toolFreeInWindow}:limits.maxToolFreePerMinute>0&&toolFreeInWindow>=limits.maxToolFreePerMinute?{reason:"tool-free-rate",sinceUserInput,toolFreeInWindow}:null}import{resolve as resolve4}from"node:path";function isHealthExhaustionFailure(errorMessage){return isBillingErrorMessage(errorMessage)||isQuotaExhaustionMessage(errorMessage)}var CircuitProbes=class{constructor(circuits){this.circuits=circuits}isOpen(selector){return this.circuits?.isOpen(selector)??!1}governs(selector){return this.circuits?.governs(selector)??!1}isExhausted(selector){return this.circuits?.isExhausted(selector)??!1}admit(selector){let admission=this.circuits?.admit(selector)??{kind:"closed"};return admission.kind==="probe"&&this.token?.selector!==selector&&(this.release(),this.token=admission.token),admission.kind}holds(selector){return this.token?.selector===selector}get probing(){return this.token?.selector}noteFailure(selector,failure){this.circuits?.noteFailure(selector,failure),this.token?.selector===selector&&(this.token=void 0)}accept(selector){this.circuits?.close(selector),this.token?.selector===selector&&(this.token=void 0)}release(){this.token&&this.circuits?.release(this.token),this.token=void 0}releaseAll(){this.token=void 0,this.circuits?.releaseAll()}};var DEFAULT_CIRCUIT_COOLDOWN_MS=6e4,DEFAULT_CIRCUIT_MAX_COOLDOWN_MS=30*6e4;function nonNegativeMs(value,fallback){return typeof value=="number"&&Number.isFinite(value)&&value>=0?value:fallback}function resolveFallbackCircuitSettings(settings){let cooldownMs=nonNegativeMs(settings?.circuitCooldownMs,DEFAULT_CIRCUIT_COOLDOWN_MS),maxCooldownMs=nonNegativeMs(settings?.circuitMaxCooldownMs,DEFAULT_CIRCUIT_MAX_COOLDOWN_MS);return{cooldownMs,maxCooldownMs:Math.max(cooldownMs,maxCooldownMs)}}var FallbackCircuitBreaker=class{constructor(){this.circuits=new Map,this.generations=0}get size(){return this.circuits.size}open(selector,request){let previous=this.circuits.get(selector),sameEpisode=previous!==void 0&&request.now<previous.openUntil,consecutiveOpens=(previous?.consecutiveOpens??0)+(sameEpisode?0:1),cooldownMs=sameEpisode?previous.cooldownMs:Math.min(request.cooldownMs*2**(consecutiveOpens-1),request.maxCooldownMs),retryAfterMs=request.retryAfterMs,hinted=retryAfterMs!==void 0&&Number.isFinite(retryAfterMs)&&retryAfterMs>0?request.now+retryAfterMs:0,retryFloorUntil=Math.max(hinted,previous&&previous.retryFloorUntil>request.now?previous.retryFloorUntil:0),resetWindowMs=request.resetWindowMs,hintedUntil=Math.min(retryFloorUntil,request.now+request.maxCooldownMs),openUntil=resetWindowMs!==void 0&&Number.isFinite(resetWindowMs)&&resetWindowMs>0?Math.max(request.now+Math.min(resetWindowMs,request.maxCooldownMs),hintedUntil):Math.max(sameEpisode?previous.openUntil:request.now+cooldownMs,hintedUntil);return this.circuits.set(selector,{openUntil,retryFloorUntil,consecutiveOpens,cooldownMs,maxCooldownMs:request.maxCooldownMs,probe:void 0,exhausted:request.exhausted===!0||sameEpisode&&previous.exhausted}),openUntil}isOpen(selector,now,owner){let circuit=this.circuits.get(selector);return circuit?now<circuit.openUntil?!0:circuit.probe!==void 0&&circuit.probe.owner!==owner:!1}admit(selector,now,owner){let circuit=this.circuits.get(selector);return circuit?now<circuit.openUntil?{kind:"open"}:circuit.probe&&circuit.probe.owner!==owner?{kind:"open"}:(circuit.probe??={owner,generation:++this.generations},{kind:"probe",token:{selector,owner,generation:circuit.probe.generation}}):{kind:"closed"}}release(token){let probe=this.circuits.get(token.selector)?.probe;if(probe&&probe.owner===token.owner&&probe.generation===token.generation){let circuit=this.circuits.get(token.selector);circuit&&(circuit.probe=void 0)}}releaseOwnersWithPrefix(prefix){for(let circuit of this.circuits.values())circuit.probe?.owner.startsWith(prefix)&&(circuit.probe=void 0)}close(selector){this.circuits.delete(selector)}has(selector){return this.circuits.has(selector)}isExhausted(selector){return this.circuits.get(selector)?.exhausted===!0}sweep(now){for(let[selector,circuit]of this.circuits)!circuit.probe&&now>=circuit.openUntil+circuit.maxCooldownMs&&this.circuits.delete(selector)}};function createFallbackCircuitAccess(deps){let enabled=()=>deps.settings().cooldownMs>0;return{noteFailure(selector,failure){if(!enabled())return;let{cooldownMs,maxCooldownMs}=deps.settings(),now=deps.now(),message=failure.errorMessage,retryAfterMs=failure.retryAfterMs??(message===void 0?void 0:parseRetryAfterMsMarker(message)),reset=message!==void 0&&usageLimitScope(message)!==void 0?usageLimitReset(message,(deps.wallNow??deps.now)()):void 0,resetWindowMs=reset!==void 0&&(reset.kind==="absolute"||reset.ms>=cooldownMs)?reset.ms:void 0;deps.breaker.sweep(now);let exhausted=message!==void 0&&(isHealthExhaustionFailure(message)||usageLimitScope(message)==="account"),openUntil=deps.breaker.open(selector,{now,cooldownMs,maxCooldownMs,retryAfterMs,resetWindowMs,exhausted});deps.logger.info("circuit_opened",{selector,durationMs:openUntil-now,retryAfterMs,resetWindowMs})},governs:selector=>enabled()&&deps.breaker.has(selector),isExhausted:selector=>enabled()&&deps.breaker.isExhausted(selector),isOpen:(selector,lane="turn")=>enabled()&&deps.breaker.isOpen(selector,deps.now(),laneOwner(deps.owner(),lane)),admit:(selector,lane="turn")=>enabled()?deps.breaker.admit(selector,deps.now(),laneOwner(deps.owner(),lane)):{kind:"closed"},release:token=>deps.breaker.release(token),releaseAll:()=>deps.breaker.releaseOwnersWithPrefix(`${deps.owner()}:`),close:selector=>deps.breaker.close(selector)}}function laneOwner(session,lane){return`${session}:${lane}`}var breakersByAgentDir=new Map;function evictUnheldEmptyBreakers(){for(let[key,entry]of breakersByAgentDir)entry.owners===0&&entry.breaker.size===0&&breakersByAgentDir.delete(key)}function entryFor(agentDir){let key=resolve4(agentDir),entry=breakersByAgentDir.get(key);return entry||(evictUnheldEmptyBreakers(),entry={breaker:new FallbackCircuitBreaker,owners:0},breakersByAgentDir.set(key,entry)),entry}function acquireFallbackCircuits(agentDir){let entry=entryFor(agentDir);entry.owners++;let released=!1;return{breaker:entry.breaker,release(){released||(released=!0,entry.owners--,evictUnheldEmptyBreakers())}}}function monotonicNow(){return performance.timeOrigin+performance.now()}function isPlainObject2(value){if(value===null||typeof value!="object"||Array.isArray(value))return!1;let prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===null}function describeValue(value){return value===null?"null":Array.isArray(value)?"an array":`a ${typeof value}`}function isNonNegativeSafeInteger2(value){return typeof value=="number"&&Number.isSafeInteger(value)&&value>=0}function isFiniteAtLeast(value,min){return typeof value=="number"&&Number.isFinite(value)&&value>=min}function isFiniteRatio(value){return typeof value=="number"&&Number.isFinite(value)&&value>=0&&value<=1}function validateStageKnobs(stage,providerId,stageName,warnings){if(stage===void 0)return;if(!isPlainObject2(stage)){warnings.push(`retry.providers.${providerId}.${stageName} must be a plain object, but got ${describeValue(stage)}.`);return}let out={},invalid=[];if(stage.enabled!==void 0&&(typeof stage.enabled=="boolean"?out.enabled=stage.enabled:invalid.push("enabled")),stage.maxRetries!==void 0&&(isNonNegativeSafeInteger2(stage.maxRetries)?out.maxRetries=stage.maxRetries:invalid.push("maxRetries")),stage.baseDelayMs!==void 0&&(isNonNegativeSafeInteger2(stage.baseDelayMs)?out.baseDelayMs=stage.baseDelayMs:invalid.push("baseDelayMs")),stage.growthFactor!==void 0&&(isFiniteAtLeast(stage.growthFactor,1)?out.growthFactor=stage.growthFactor:invalid.push("growthFactor")),stage.perAttemptCapMs!==void 0&&(stage.perAttemptCapMs===null?out.perAttemptCapMs=null:isNonNegativeSafeInteger2(stage.perAttemptCapMs)?out.perAttemptCapMs=stage.perAttemptCapMs:invalid.push("perAttemptCapMs")),stage.jitter!==void 0)if(isPlainObject2(stage.jitter)){let mode=stage.jitter.mode;mode==="none"?out.jitter={mode:"none"}:(mode==="additive"||mode==="subtractive")&&isFiniteRatio(stage.jitter.ratio)?out.jitter={mode,ratio:stage.jitter.ratio}:invalid.push("jitter")}else invalid.push("jitter");if(stage.serverHintMaxDelayMs!==void 0&&(stage.serverHintMaxDelayMs===null?out.serverHintMaxDelayMs=null:isNonNegativeSafeInteger2(stage.serverHintMaxDelayMs)?out.serverHintMaxDelayMs=stage.serverHintMaxDelayMs:invalid.push("serverHintMaxDelayMs")),invalid.length>0){warnings.push(`retry.providers.${providerId}.${stageName} has invalid knob(s): ${invalid.join(", ")}.`);return}return out}function validateRetryProviderOverrides(value,knownProviderIds,tieredProviderIds){if(value===void 0)return{overrides:{},warnings:[]};if(!isPlainObject2(value))return{overrides:{},warnings:[`retry.providers must be a plain object keyed by provider id, but got ${describeValue(value)}.`]};let overrides={},warnings=[];for(let[providerId,entry]of Object.entries(value)){if(!knownProviderIds.has(providerId)){warnings.push(`retry.providers.${providerId}: unknown provider id "${providerId}".`);continue}if(!isPlainObject2(entry)){warnings.push(`retry.providers.${providerId} must be a plain object, but got ${describeValue(entry)}.`);continue}let stageWarnings=[],providerRequest=validateStageKnobs(entry.providerRequest,providerId,"providerRequest",stageWarnings),turn=validateStageKnobs(entry.turn,providerId,"turn",stageWarnings);if(stageWarnings.length>0){warnings.push(...stageWarnings);continue}if(tieredProviderIds?.has(providerId)&&(providerRequest?.serverHintMaxDelayMs!==void 0||turn?.serverHintMaxDelayMs!==void 0)){warnings.push(`retry.providers.${providerId}: serverHintMaxDelayMs is invalid for a tiered stage (tier thresholds own that strategy).`);continue}let result={};if(providerRequest!==void 0&&(result.providerRequest=providerRequest),turn!==void 0&&(result.turn=turn),providerRequest===void 0&&turn===void 0){warnings.push(`retry.providers.${providerId} has no recognized knobs.`);continue}overrides[providerId]=result}return{overrides,warnings}}var FABLE55_LAUNCH={modelId:"claude-fable-5-5",mythosModelId:"claude-mythos-5-5",snapshotId:null,minimumClaudeCodeVersion:null,released:!1,promoteDefaults:!1,refusalFallbackModels:["claude-opus-4-8","claude-opus-5"],metadataSource:"models.dev"};function isFable55ModelId(modelId){let normalized=modelId.toLowerCase().replace(/\s+/g,"-");return[FABLE55_LAUNCH.modelId,FABLE55_LAUNCH.mythosModelId,FABLE55_LAUNCH.snapshotId].some(id=>{if(!id)return!1;let family=id.replace(/^claude-/,""),dotted=family.replace(/-(\d+)-(\d+)$/,"-$1.$2");return[family,dotted].some(marker=>{let at=normalized.indexOf(marker);if(at<0)return!1;let before=normalized[at-1],after=normalized[at+marker.length];return(!before||/[/@:._-]/.test(before))&&(!after||/[/@:._-]/.test(after))})})}var DEFAULT_FALLBACK_CHAINS={...FABLE55_LAUNCH.released?{[FABLE55_LAUNCH.modelId]:["claude-opus-5-5:max","claude-opus-5:max"]}:{},"claude-fable-5-1":["claude-opus-5-5:max","claude-opus-5:max"],"claude-fable-5":["claude-opus-5-5:max","claude-opus-5:max"],"claude-opus-5-5":["claude-opus-5:max"]};function cloneDefaultFallbackChains(){let chains={};for(let[key,entries]of Object.entries(DEFAULT_FALLBACK_CHAINS))chains[key]=[...entries];return chains}function isPlainObject3(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function isStringArray(value){return Array.isArray(value)&&value.every(entry=>typeof entry=="string")}function resolveFallbackChains(value){if(value===void 0||!isPlainObject3(value))return cloneDefaultFallbackChains();let chains=cloneDefaultFallbackChains();for(let[key,entries]of Object.entries(value)){if(!isStringArray(entries))return cloneDefaultFallbackChains();chains[key]=[...entries]}return chains}function resolveRetryFallbackSettings(settings){return{modelFallback:typeof settings?.modelFallback=="boolean"?settings.modelFallback:!0,chains:resolveFallbackChains(settings?.fallbackChains),revertPolicy:settings?.fallbackRevertPolicy==="never"?"never":"cooldown-expiry"}}function resolveAbortServerSideFallback(settings){return typeof settings?.abortServerSideFallback=="boolean"?settings.abortServerSideFallback:!0}var DEFAULT_HINTED_WAIT_CAP_MS=3e5,DEFAULT_PROBE_BACK_MAX_MS=36e5;function resolveHintPolicySettings(settings){let hintedWaitCapMs=typeof settings?.hintedWaitCapMs=="number"&&settings.hintedWaitCapMs>=0?settings.hintedWaitCapMs:DEFAULT_HINTED_WAIT_CAP_MS,probeBackMaxMs=typeof settings?.probeBackMaxMs=="number"&&settings.probeBackMaxMs>=0?settings.probeBackMaxMs:DEFAULT_PROBE_BACK_MAX_MS;return probeBackMaxMs<=hintedWaitCapMs?{hintedWaitCapMs:DEFAULT_HINTED_WAIT_CAP_MS,probeBackMaxMs:DEFAULT_PROBE_BACK_MAX_MS}:{hintedWaitCapMs,probeBackMaxMs}}function parseSettingsJson(content){content=stripBom(content);let withoutComments=[],inString=!1,escaped=!1;for(let index=0;index<content.length;index+=1){let char=content[index],next=content[index+1];if(inString){withoutComments.push(char),escaped?escaped=!1:char==="\\"?escaped=!0:char==='"'&&(inString=!1);continue}if(char==='"'){inString=!0,withoutComments.push(char);continue}if(char==="/"&&next==="/"){for(withoutComments.push(" "," "),index+=2;index<content.length&&content[index]!==`
|
|
166
166
|
`&&content[index]!=="\r";)withoutComments.push(" "),index+=1;index<content.length&&withoutComments.push(content[index]);continue}if(char==="/"&&next==="*"){withoutComments.push(" "," "),index+=2;let closed=!1;for(;index<content.length;index+=1){if(content[index]==="*"&&content[index+1]==="/"){withoutComments.push(" "," "),index+=1,closed=!0;break}withoutComments.push(content[index]===`
|
|
167
167
|
`||content[index]==="\r"?content[index]:" ")}if(!closed)throw new SyntaxError("Unterminated block comment in settings");continue}withoutComments.push(char)}let normalized=withoutComments;inString=!1,escaped=!1;for(let index=0;index<normalized.length;index+=1){let char=normalized[index];if(inString){escaped?escaped=!1:char==="\\"?escaped=!0:char==='"'&&(inString=!1);continue}if(char==='"'){inString=!0;continue}if(char!==",")continue;let nextIndex=index+1;for(;nextIndex<normalized.length&&/\s/.test(normalized[nextIndex]);)nextIndex+=1;(normalized[nextIndex]==="}"||normalized[nextIndex]==="]")&&(normalized[index]=" ")}let parsed=JSON.parse(normalized.join(""));if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))throw new TypeError("Settings must contain a JSON object");return parsed}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function withoutOverride(overrides,field,nestedKey){if(!(field in overrides))return overrides;let next={...overrides},current=next[field];if(nestedKey===void 0||!isRecord(current))return delete next[field],next;if(!(nestedKey in current))return overrides;let nested={...current};return delete nested[nestedKey],Object.keys(nested).length===0?delete next[field]:next[field]=nested,next}var RETIRED_NESTED_KEYS=[["experimental","sharedHost"]];function removeRetiredSettingsKeys(raw){let removed=!1;for(let[parent,key]of RETIRED_NESTED_KEYS){let container=raw[parent];if(typeof container!="object"||container===null||Array.isArray(container)||!(key in container))continue;let remaining={...container};delete remaining[key],Object.keys(remaining).length===0?delete raw[parent]:raw[parent]=remaining,removed=!0}return removed}var failedRewrites=new Set;function writeRawScopedSettings(storage,scope){let target=storage.selectSource?.(scope)?.path??storage;if(!failedRewrites.has(target))try{storage.withLock(scope,current=>{if(!current)return;let raw=parseSettingsJson(current);return removeRetiredSettingsKeys(raw)?JSON.stringify(raw,null,2):void 0})}catch(error){failedRewrites.add(target);let detail=error instanceof Error?`${error.name}: ${error.message}`:String(error);try{appendDebugLogEntry(`settings: could not remove retired ${scope} settings keys`,detail)}catch{}}}var STATE_KEYS=new Set(["tipsHistory","changelogSeen","lastChangelogVersion","modelThinkingLevels","modelLastOnThinkingLevels","modelServiceTiers"]),failedMigrations=new Set,reportedStateErrors=new Set;function logStateError(storage,error){let target=storage.selectSource?.("global")?.path??storage;if(reportedStateErrors.has(target))return;reportedStateErrors.add(target);let detail=error instanceof Error?`${error.name}: ${error.message}`:String(error);try{appendDebugLogEntry("settings: could not read or save state.json; using empty bookkeeping",detail)}catch{}}function parseStateSettings(storage,content){let raw;try{raw=content?parseSettingsJson(content):{}}catch(error){return logStateError(storage,error),{}}for(let field of["modelThinkingLevels","modelLastOnThinkingLevels","modelServiceTiers"]){let map=raw[field];if(typeof map!="object"||map===null||Array.isArray(map))continue;let normalized={};for(let[key,value]of Object.entries(map)){let canonical=normalizeModelRef(key);(key===canonical||!Object.hasOwn(map,canonical))&&(normalized[canonical]=value)}raw[field]=normalized}return raw}function migrateSettingsState(storage){let withStateLock=storage.withStateLock?.bind(storage);if(!withStateLock)return;let target=storage.selectSource?.("global")?.path??storage;if(!failedMigrations.has(target))try{storage.withLock("global",current=>{if(!current)return;let raw=parseSettingsJson(current);if([...STATE_KEYS].some(key=>Object.hasOwn(raw,key))){withStateLock(stateContent=>{let state=stateContent?parseSettingsJson(stateContent):{},changed=!1;for(let key of STATE_KEYS)Object.hasOwn(raw,key)&&!Object.hasOwn(state,key)&&(state[key]=raw[key],changed=!0);return changed?JSON.stringify(state,null,2):void 0});for(let key of STATE_KEYS)delete raw[key];return JSON.stringify(raw,null,2)}})}catch(error){failedMigrations.add(target);let detail=error instanceof Error?`${error.name}: ${error.message}`:String(error);try{appendDebugLogEntry("settings: could not migrate global state keys",detail)}catch{}}}function readSettingsState(storage){let state={};try{storage.withStateLock?.(current=>{let raw=parseStateSettings(storage,current);for(let key of STATE_KEYS)Object.hasOwn(raw,key)&&(state[key]=raw[key])})}catch(error){return logStateError(storage,error),{}}return state}var TERMINAL_MOUSE_MODES=["off","whilePending","always"];function isTerminalMouseMode(value){return value==="off"||value==="whilePending"||value==="always"}var DEFAULT_STREAM_START_TIMEOUT_MS=3e5,DEFAULT_PROVIDER_STREAM_RETRY_TIMEOUT_MS=3e4,DEFAULT_SESSION_SHUTDOWN_HANDLER_WARN_MS=2e3,DEFAULT_SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS=1e4,DEFAULT_SESSION_SHUTDOWN_QUIT_BUDGET_MS=2e3,DEFAULT_EXTENSION_EVENT_HANDLER_WARN_MS=6e4,DEFAULT_EXTENSION_EVENT_HANDLER_TIMEOUT_MS=12e5,THINKING_LEVEL_VALUES=new Set(["off","minimal","low","medium","high","xhigh","max"]),MODEL_SERVICE_TIER_VALUES=new Set(["auto","flex","priority"]);function modelMemoryKey(provider,modelId){return`${provider}/${modelId}`}function readModelMemoryEntry(map,key,allowed){if(typeof map!="object"||map===null||Array.isArray(map))return;let value=map[key];return typeof value=="string"&&allowed.has(value)?value:void 0}function isMergeableObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function deepMergeObjects(base,overrides){let result={...base};for(let key of Object.keys(overrides)){let overrideValue=overrides[key];if(overrideValue===void 0)continue;let baseValue=base[key];result[key]=isMergeableObject(baseValue)&&isMergeableObject(overrideValue)?deepMergeObjects(baseValue,overrideValue):overrideValue}return result}var DEFAULT_TOOL_NAMES=["read","bash","edit","write","grep"];function isToolModifier(entry){return typeof entry=="string"&&(entry.startsWith("+")||entry.startsWith("-"))}function mergeDefaultTools(base,overrides){return overrides===void 0?base:!Array.isArray(base)||!Array.isArray(overrides)||!overrides.every(isToolModifier)?overrides:[...base,...overrides]}function resolveDefaultTools(entries){let plain=entries.filter(entry=>!isToolModifier(entry)),tools=plain.length>0||entries.length===0?plain:[...DEFAULT_TOOL_NAMES];for(let entry of entries){if(!isToolModifier(entry))continue;let name=entry.slice(1),index=tools.indexOf(name);entry.startsWith("+")&&index===-1&&name?tools.push(name):entry.startsWith("-")&&index!==-1&&tools.splice(index,1)}return tools}function deepMergeSettings(base,overrides){let merged=deepMergeObjects(base,overrides);overrides.retry?.fallbackChains!==void 0&&(merged.retry={...merged.retry,fallbackChains:structuredClone(overrides.retry.fallbackChains)});let defaultTools=mergeDefaultTools(base.defaultTools,overrides.defaultTools);return defaultTools===void 0?merged:{...merged,defaultTools}}function resolveAskUserTimeoutMinutes(value){return typeof value!="number"||!Number.isFinite(value)?30:Math.min(120,Math.max(1,Math.floor(value)))}function parseTimeoutSetting(value,settingName){let timeoutMs=parseHttpIdleTimeoutMs(value);if(timeoutMs!==void 0)return timeoutMs;if(value!==void 0)throw new Error(`Invalid ${settingName} setting: ${String(value)}`)}var SELF_WRITE_TTL_MS=15e3,MAX_SELF_WRITES_PER_PATH=8,selfWritesByPath=new Map,selfWriteClock=Date.now;function recordSelfWrite(absPath,content){let now=selfWriteClock(),writes=selfWritesByPath.get(absPath)??new Map;for(let[hash2,recordedAt]of writes)now-recordedAt>SELF_WRITE_TTL_MS&&writes.delete(hash2);let hash=createHash3("sha256").update(content).digest("hex");for(writes.delete(hash),writes.set(hash,now);writes.size>MAX_SELF_WRITES_PER_PATH;){let oldestHash=writes.keys().next().value;if(oldestHash===void 0)break;writes.delete(oldestHash)}selfWritesByPath.set(absPath,writes)}function wasSelfWrite(absPath,hash){let writes=selfWritesByPath.get(absPath);if(!writes)return!1;let now=selfWriteClock();for(let[trackedHash,recordedAt]of writes)now-recordedAt>SELF_WRITE_TTL_MS&&writes.delete(trackedHash);return writes.delete(hash)?(writes.size===0&&selfWritesByPath.delete(absPath),!0):(writes.size===0&&selfWritesByPath.delete(absPath),!1)}function getSettingsDirectory(cwd,agentDir,scope,homeDir){if(scope==="global")return resolvePath(agentDir);let resolvedCwd=resolvePath(cwd);return findNearestParentConfigDir(resolvedCwd,homeDir,CONFIG_DIR_NAME)??join4(resolvedCwd,CONFIG_DIR_NAME)}function resolveSettingsSource(cwd,agentDir,scope,homeDir=homedir3()){let directory=getSettingsDirectory(cwd,agentDir,scope,homeDir),jsoncPath=join4(directory,"settings.jsonc");if(existsSync4(jsoncPath))return{path:jsoncPath,format:"jsonc",reason:"explicit-jsonc",scope};let jsonPath=join4(directory,"settings.json");if(existsSync4(jsonPath))return{path:jsonPath,format:"json",reason:"json-only",scope}}function getSettingsPath2(cwd,agentDir,scope,homeDir=homedir3()){return resolveSettingsSource(cwd,agentDir,scope,homeDir)?.path??join4(getSettingsDirectory(cwd,agentDir,scope,homeDir),"settings.json")}function getInMemorySettingsPath(scope){return scope==="global"?"/__senpi_in_memory__/settings.json":"/__senpi_in_memory__/.senpi/settings.json"}function toSettingsError(scope,error,path2){return{scope,...path2?{path:path2}:{},error:error instanceof Error?error:new Error(String(error))}}var SettingsLockBusy=class extends Error{},FileSettingsStorage=class{constructor(cwd,agentDir,homeDir=homedir3()){this.cwd=cwd,this.agentDir=agentDir,this.homeDir=homeDir,this.globalSettingsPath=getSettingsPath2(cwd,agentDir,"global",homeDir),this.projectSettingsPath=getSettingsPath2(cwd,agentDir,"project",homeDir)}selectSource(scope){let source=resolveSettingsSource(this.cwd,this.agentDir,scope,this.homeDir),path2=source?.path??join4(getSettingsDirectory(this.cwd,this.agentDir,scope,this.homeDir),"settings.json");return scope==="global"?this.globalSettingsPath=path2:this.projectSettingsPath=path2,source}tryAcquireLockSync(path2){try{return import_proper_lockfile.default.lockSync(path2,{...FILE_STORAGE_LOCK_OPTIONS,retries:0})}catch(error){throw isLockError(error)?new SettingsLockBusy:error}}acquireLockSyncWithRetry(path2){let startedAt=Date.now(),attempt=0;for(;;)try{return import_proper_lockfile.default.lockSync(path2,{...FILE_STORAGE_LOCK_OPTIONS,retries:0})}catch(error){if(!isLockError(error))throw error;let waitedMs=Date.now()-startedAt;if(waitedMs>=FILE_STORAGE_SYNC_LOCK_BUDGET_MS)throw new CredentialStoreBusyError(path2,waitedMs,error);let delayMs=Math.min(FILE_STORAGE_LOCK_RETRY_MIN_DELAY_MS*2**attempt,FILE_STORAGE_LOCK_RETRY_MAX_DELAY_MS,FILE_STORAGE_SYNC_LOCK_BUDGET_MS-waitedMs);attempt++;let sleeper=new Int32Array(new SharedArrayBuffer(4));Atomics.wait(sleeper,0,0,delayMs)}}async acquireLockWithRetry(path2){let startedAt=Date.now(),attempt=0;for(;;)try{return await lockWithLossHandling(path2,{...FILE_STORAGE_LOCK_OPTIONS,retries:0})}catch(error){if(!isLockError(error))throw error;let waitedMs=Date.now()-startedAt;if(waitedMs>=FILE_STORAGE_LOCK_RETRY_BUDGET_MS)throw new CredentialStoreBusyError(path2,waitedMs,error);let delayMs=Math.min(FILE_STORAGE_LOCK_RETRY_MIN_DELAY_MS*2**attempt,FILE_STORAGE_LOCK_RETRY_MAX_DELAY_MS,FILE_STORAGE_LOCK_RETRY_BUDGET_MS-waitedMs);attempt++,await new Promise(resolve6=>setTimeout(resolve6,delayMs))}}async withLockAsync(scope,fn,underLock){let path2=scope==="global"?this.globalSettingsPath:this.projectSettingsPath;return this.withPathLockAsync(path2,fn,underLock)}withStateLockAsync(fn){return this.withPathLockAsync(join4(resolvePath(this.agentDir),"state.json"),fn)}async withPathLockAsync(path2,fn,underLock){let readCurrent=async()=>{try{return await readFile2(path2,"utf-8")}catch(error){if(error.code==="ENOENT")return;throw error}},current=await readCurrent(),next=fn(current);if(next===void 0)return;await mkdir(dirname3(path2),{recursive:!0});let lock=await this.acquireLockWithRetry(path2);try{underLock?.();let lockedContent=await readCurrent();if(lockedContent!==current&&(next=fn(lockedContent)),next!==void 0){let tempPath=`${path2}.${process.pid}.${randomUUID()}.tmp`;try{await writeFile(tempPath,next,"utf-8"),lock.assertHeld(),await rename(tempPath,path2),recordSelfWrite(path2,next)}catch(error){throw await rm(tempPath,{force:!0}),error}}}finally{await lock.release()}}tryWithLock(scope,fn){try{return this.withLock(scope,fn,!1),!0}catch(error){if(error instanceof SettingsLockBusy)return!1;throw error}}withLock(scope,fn,waitForLock=!0){let path2=scope==="global"?this.globalSettingsPath:this.projectSettingsPath;this.withPathLock(path2,fn,waitForLock)}withStateLock(fn){this.withPathLock(join4(resolvePath(this.agentDir),"state.json"),fn)}tryWithStateLock(fn){try{return this.withPathLock(join4(resolvePath(this.agentDir),"state.json"),fn,!1),!0}catch(error){if(error instanceof SettingsLockBusy)return!1;throw error}}withPathLock(path2,fn,waitForLock=!0){let dir=dirname3(path2),current=existsSync4(path2)?readFileSync5(path2,"utf-8"):void 0,next=fn(current);if(next===void 0)return;existsSync4(dir)||mkdirSync2(dir,{recursive:!0});let release=waitForLock?this.acquireLockSyncWithRetry(path2):this.tryAcquireLockSync(path2);try{let underLock=existsSync4(path2)?readFileSync5(path2,"utf-8"):void 0;if(underLock!==current&&(next=fn(underLock)),next!==void 0){let tempPath=`${path2}.${process.pid}.${randomUUID()}.tmp`;try{writeFileSync2(tempPath,next,"utf-8"),recordSelfWrite(path2,next),renameSync(tempPath,path2)}catch(error){throw rmSync2(tempPath,{force:!0}),error}}}finally{release()}}},InMemorySettingsStorage=class{withStateLock(fn){let next=fn(this.state);next!==void 0&&(this.state=next)}withLock(scope,fn){let current=scope==="global"?this.global:this.project,next=fn(current);next!==void 0&&(scope==="global"?this.global=next:this.project=next,recordSelfWrite(getInMemorySettingsPath(scope),next))}},SettingsManager=class _SettingsManager{constructor(storage,initialGlobal,initialProject,globalLoadError=null,projectLoadError=null,initialErrors=[],projectTrusted=!0,initialSources=[],settingsPaths={}){this.runtimeOverrides={},this.modifiedFields=new Set,this.modifiedNestedFields=new Map,this.modifiedProjectFields=new Set,this.modifiedProjectNestedFields=new Map,this.globalSettingsLoadError=null,this.projectSettingsLoadError=null,this.writeQueue=Promise.resolve(),this.selectedSources=new Map,this.sourceListeners=[],this.providerSettingsListeners=new Set,this.trustFromFullAccess=!1,this.trustEpoch=0,this.storage=storage,this.globalSettings=initialGlobal,this.projectSettings=initialProject,this.projectTrusted=projectTrusted,this.globalSettingsLoadError=globalLoadError,this.projectSettingsLoadError=projectLoadError,this.errors=[...initialErrors],this.settingsPaths=settingsPaths;for(let source of initialSources)this.selectedSources.set(source.scope,source);this.settings=deepMergeSettings(this.globalSettings,this.projectSettings)}static create(cwd,agentDir=getAgentDir(),options={}){let storage=new FileSettingsStorage(cwd,agentDir);return _SettingsManager.fromStorage(storage,options)}static fromStorage(storage,options={}){let projectTrusted=options.projectTrusted??!0,initialSources=[],settingsPaths={},globalSource=storage.selectSource?.("global");globalSource&&(initialSources.push(globalSource),settingsPaths.global=globalSource.path);let globalLoad=_SettingsManager.tryLoadFromStorage(storage,"global"),projectSource=projectTrusted?storage.selectSource?.("project"):void 0;projectSource&&(initialSources.push(projectSource),settingsPaths.project=projectSource.path);let projectLoad=_SettingsManager.tryLoadFromStorage(storage,"project",projectTrusted),initialErrors=[];globalLoad.error&&initialErrors.push(toSettingsError("global",globalLoad.error,settingsPaths.global)),projectLoad.error&&initialErrors.push(toSettingsError("project",projectLoad.error,settingsPaths.project));let manager=new _SettingsManager(storage,globalLoad.settings,projectLoad.settings,globalLoad.error,projectLoad.error,initialErrors,projectTrusted,initialSources,settingsPaths);return manager.trustFromFullAccess=options.trustFromFullAccess===!0,manager}static inMemory(settings={},options={}){let storage=new InMemorySettingsStorage,initialSettings=_SettingsManager.migrateSettings(structuredClone(settings));return storage.withLock("global",()=>JSON.stringify(initialSettings,null,2)),_SettingsManager.fromStorage(storage,options)}static loadFromStorage(storage,scope,projectTrusted=!0){if(scope==="project"&&!projectTrusted)return{};let content;storage.withLock(scope,current=>{content=current});let raw=content?parseSettingsJson(content):{};return removeRetiredSettingsKeys(raw)&&scope==="global"&&writeRawScopedSettings(storage,scope),scope==="global"&&storage.withStateLock&&([...STATE_KEYS].some(key=>Object.hasOwn(raw,key))&&migrateSettingsState(storage),Object.assign(raw,readSettingsState(storage))),_SettingsManager.migrateSettings(raw)}static tryLoadFromStorage(storage,scope,projectTrusted=!0){try{return{settings:_SettingsManager.loadFromStorage(storage,scope,projectTrusted),error:null}}catch(error){return{settings:{},error}}}static migrateSettings(settings){if("queueMode"in settings&&!("steeringMode"in settings)&&(settings.steeringMode=settings.queueMode,delete settings.queueMode),!("transport"in settings)&&typeof settings.websockets=="boolean"&&(settings.transport=settings.websockets?"websocket":"sse",delete settings.websockets),"skills"in settings&&typeof settings.skills=="object"&&settings.skills!==null&&!Array.isArray(settings.skills)){let skillsSettings=settings.skills;skillsSettings.enableSkillCommands!==void 0&&settings.enableSkillCommands===void 0&&(settings.enableSkillCommands=skillsSettings.enableSkillCommands),Array.isArray(skillsSettings.customDirectories)&&skillsSettings.customDirectories.length>0?settings.skills=skillsSettings.customDirectories:delete settings.skills}if("retry"in settings&&typeof settings.retry=="object"&&settings.retry!==null&&!Array.isArray(settings.retry)){let retrySettings=settings.retry,providerSettings=typeof retrySettings.provider=="object"&&retrySettings.provider!==null?retrySettings.provider:void 0;typeof retrySettings.maxDelayMs=="number"&&(providerSettings?.maxRetryDelayMs===void 0||providerSettings?.maxRetryDelayMs===null)&&(retrySettings.provider={...providerSettings??{},maxRetryDelayMs:retrySettings.maxDelayMs}),delete retrySettings.maxDelayMs}return _SettingsManager.migrateRenamedProviderIds(settings),settings}static providerSettingsKey(providerId){return`${providerId.split("-").map((part,i)=>i===0?part:part.charAt(0).toUpperCase()+part.slice(1)).join("")}Provider`}static migrateRenamedProviderIds(settings){for(let[legacyId,canonicalId]of Object.entries(LEGACY_PROVIDER_IDS)){let legacyKey=_SettingsManager.providerSettingsKey(legacyId),canonicalKey=_SettingsManager.providerSettingsKey(canonicalId);legacyKey in settings&&!(canonicalKey in settings)&&(settings[canonicalKey]=settings[legacyKey],delete settings[legacyKey])}typeof settings.defaultProvider=="string"&&(settings.defaultProvider=normalizeProviderId(settings.defaultProvider)),typeof settings.defaultModel=="string"&&(settings.defaultModel=normalizeModelRef(settings.defaultModel)),Array.isArray(settings.favoriteModels)&&(settings.favoriteModels=settings.favoriteModels.map(entry=>typeof entry=="string"?normalizeModelRef(entry):entry));for(let field of["modelThinkingLevels","modelServiceTiers","modelLastOnThinkingLevels"]){let map=settings[field];typeof map=="object"&&map!==null&&!Array.isArray(map)&&(settings[field]=_SettingsManager.rekeyByModelRef(map))}if(typeof settings.retry=="object"&&settings.retry!==null&&!Array.isArray(settings.retry)){let retry=settings.retry,chains=retry.fallbackChains;if(typeof chains=="object"&&chains!==null&&!Array.isArray(chains)){let rekeyed={};for(let[key,rungs]of Object.entries(chains)){let nextRungs=Array.isArray(rungs)?rungs.map(rung=>typeof rung=="string"?normalizeModelRef(rung):rung):rungs;rekeyed[normalizeModelRef(key)]=nextRungs}retry.fallbackChains=rekeyed}}}static rekeyByModelRef(map){let out={};for(let[key,value]of Object.entries(map))out[normalizeModelRef(key)]=value;return out}getSettings(){return structuredClone(this.settings)}getGlobalSettings(){return structuredClone(this.globalSettings)}getProjectSettings(){return structuredClone(this.projectSettings)}getProviderSettings(){return structuredClone(this.settings.providers??{})}getProviderConcurrencyLimit(providerId){let value=readByProviderId(this.settings.providers,providerId)?.maxConcurrency;return typeof value=="number"&&Number.isInteger(value)&&value>0?value:1/0}subscribeToProviderSettings(listener){return this.providerSettingsListeners.add(listener),()=>this.providerSettingsListeners.delete(listener)}updateSettings(settings){this.settings=settings;for(let listener of this.providerSettingsListeners)listener()}getPromptCacheGoalBackstopMaxSeconds(){return this.projectSettings.promptCache?.goalBackstopMaxSeconds??this.globalSettings.promptCache?.goalBackstopMaxSeconds??270}getPromptCacheKeepAliveSettings(){let configured=this.settings.promptCache?.keepAlive;return{enabled:configured?.enabled??!1,maxRequestsPerSession:configured?.maxRequestsPerSession??3,maxCostUsdPerSession:configured?.maxCostUsdPerSession??.05,marginSeconds:configured?.marginSeconds??60}}getAskUserSettings(){let configured=this.settings.askUser;return{enabled:typeof configured?.enabled=="boolean"?configured.enabled:!0,timeoutMinutes:resolveAskUserTimeoutMinutes(configured?.timeoutMinutes),bell:typeof configured?.bell=="boolean"?configured.bell:!0}}getEngineTurnSettings(){let configured=this.settings.engineTurns,limit=(value,fallback)=>typeof value=="number"&&Number.isInteger(value)&&value>=0?value:fallback;return{maxPerUserInput:limit(configured?.maxPerUserInput,MAX_ENGINE_TURNS_PER_USER_INPUT),maxPerResumeWindow:limit(configured?.maxPerResumeWindow,MAX_ENGINE_TURNS_PER_RESUME_WINDOW),maxToolFreePerMinute:limit(configured?.maxToolFreePerMinute,MAX_TOOL_FREE_ENGINE_TURNS_PER_WINDOW)}}getTurnInactivityMs(){return this.settings.turn_inactivity_ms}getTurnMaxRuntimeMs(){return this.settings.turn_max_runtime_ms}getTodoFirstTurnPlan(){let configured=this.settings.todo?.firstTurnPlan;return configured==="remind"||configured==="off"?configured:"force"}getTodoTurnEndBackstop(){let configured=this.settings.todo?.turnEndBackstop;return typeof configured=="boolean"?configured:!0}isProjectTrusted(){return this.projectTrusted}isTrustFromFullAccess(){return this.trustFromFullAccess&&this.projectTrusted}canRestoreFullAccessTrust(){return this.trustFromFullAccess&&!this.projectTrusted}getTrustEpoch(){return this.trustEpoch}setProjectTrusted(trusted){if(this.projectTrusted===trusted)return;if(this.projectTrusted=trusted,this.trustEpoch+=1,this.modifiedProjectFields.clear(),this.modifiedProjectNestedFields.clear(),!trusted){this.projectSettings={},this.projectSettingsLoadError=null,this.updateSettings(this.mergedSettings());return}this.selectAndPublishSource("project");let projectLoad=_SettingsManager.tryLoadFromStorage(this.storage,"project",trusted);this.projectSettings=projectLoad.settings,this.projectSettingsLoadError=projectLoad.error,projectLoad.error&&this.recordError("project",projectLoad.error),this.updateSettings(this.mergedSettings())}async reload(){await this.writeQueue,this.selectAndPublishSource("global");let globalLoad=_SettingsManager.tryLoadFromStorage(this.storage,"global");globalLoad.error?(this.globalSettingsLoadError=globalLoad.error,this.recordError("global",globalLoad.error)):(this.globalSettings=globalLoad.settings,this.globalSettingsLoadError=null),this.modifiedFields.clear(),this.modifiedNestedFields.clear(),this.modifiedProjectFields.clear(),this.modifiedProjectNestedFields.clear(),this.projectTrusted&&this.selectAndPublishSource("project");let projectLoad=_SettingsManager.tryLoadFromStorage(this.storage,"project",this.projectTrusted);projectLoad.error?(this.projectSettingsLoadError=projectLoad.error,this.recordError("project",projectLoad.error)):(this.projectSettings=projectLoad.settings,this.projectSettingsLoadError=null),this.updateSettings(this.mergedSettings())}getSelectedSettingsSources(){return[...this.selectedSources.values()].map(source=>({...source}))}subscribeToSourceSelection(listener){return this.sourceListeners.push(listener),()=>{let index=this.sourceListeners.indexOf(listener);index!==-1&&this.sourceListeners.splice(index,1)}}selectAndPublishSource(scope){let source=this.storage.selectSource?.(scope);if(!source){this.selectedSources.delete(scope);return}this.selectedSources.set(scope,source);for(let listener of this.sourceListeners)listener({...source})}applyOverrides(overrides){this.runtimeOverrides=deepMergeSettings(this.runtimeOverrides,overrides),this.updateSettings(this.mergedSettings())}mergedSettings(){return deepMergeSettings(deepMergeSettings(this.globalSettings,this.projectSettings),this.runtimeOverrides)}markModified(field,nestedKey){this.runtimeOverrides=withoutOverride(this.runtimeOverrides,field,nestedKey),this.modifiedFields.add(field),nestedKey&&(this.modifiedNestedFields.has(field)||this.modifiedNestedFields.set(field,new Set),this.modifiedNestedFields.get(field).add(nestedKey))}markProjectModified(field,nestedKey){this.runtimeOverrides=withoutOverride(this.runtimeOverrides,field,nestedKey),this.modifiedProjectFields.add(field),nestedKey&&(this.modifiedProjectNestedFields.has(field)||this.modifiedProjectNestedFields.set(field,new Set),this.modifiedProjectNestedFields.get(field).add(nestedKey))}assertProjectTrustedForWrite(){if(!this.projectTrusted)throw new Error("Project is not trusted; refusing to write project settings")}recordError(scope,error){let normalizedError=error instanceof Error?error:new Error(String(error));this.errors.push(toSettingsError(scope,normalizedError,this.settingsPaths[scope]))}clearModifiedScope(scope){if(scope==="global"){this.modifiedFields.clear(),this.modifiedNestedFields.clear();return}this.modifiedProjectFields.clear(),this.modifiedProjectNestedFields.clear()}enqueueWrite(scope,task){this.writeQueue=this.writeQueue.then(async()=>{scope==="project"&&this.assertProjectTrustedForWrite(),await task(),this.clearModifiedScope(scope)}).catch(error=>{this.recordError(scope,error)})}cloneModifiedNestedFields(source){let snapshot=new Map;for(let[key,value]of source.entries())snapshot.set(key,new Set(value));return snapshot}persistScopedSettings(scope,snapshotSettings,modifiedFields,modifiedNestedFields,state=!1){let merge=current=>{let raw=state?parseStateSettings(this.storage,current):current?parseSettingsJson(current):{},currentFileSettings=_SettingsManager.migrateSettings(structuredClone(raw)),mergedSettings={...currentFileSettings};for(let field of modifiedFields){let value=snapshotSettings[field];if(modifiedNestedFields.has(field)&&typeof value=="object"&&value!==null){let nestedModified=modifiedNestedFields.get(field),baseNested=currentFileSettings[field]??{},inMemoryNested=value,mergedNested={...baseNested};for(let nestedKey of nestedModified)inMemoryNested[nestedKey]===void 0?delete mergedNested[nestedKey]:mergedNested[nestedKey]=inMemoryNested[nestedKey];mergedSettings[field]=mergedNested}else value===void 0?delete mergedSettings[field]:mergedSettings[field]=value}return isDeepStrictEqual(currentFileSettings,mergedSettings)?void 0:JSON.stringify(mergedSettings,null,2)},storage=this.storage;if(state&&storage.withStateLock){if(!storage.withStateLockAsync||!storage.tryWithStateLock){storage.withStateLock(merge);return}return storage.tryWithStateLock(merge)?void 0:storage.withStateLockAsync(merge)}if(!storage.withLockAsync||!storage.tryWithLock){storage.withLock(scope,merge);return}if(!storage.tryWithLock(scope,merge))return storage.withLockAsync(scope,merge,scope==="project"?()=>this.assertProjectTrustedForWrite():void 0)}save(){if(this.updateSettings(this.mergedSettings()),this.globalSettingsLoadError)return;let snapshotGlobalSettings=structuredClone(this.globalSettings),modifiedFields=new Set(this.modifiedFields),modifiedNestedFields=this.cloneModifiedNestedFields(this.modifiedNestedFields);this.enqueueWrite("global",async()=>{if(this.storage.withStateLock){let stateFields=new Set([...modifiedFields].filter(key=>STATE_KEYS.has(key)));if(stateFields.size>0)try{await this.persistScopedSettings("global",snapshotGlobalSettings,stateFields,modifiedNestedFields,!0)}catch(error){logStateError(this.storage,error)}for(let key of STATE_KEYS)modifiedFields.delete(key)}modifiedFields.size>0&&await this.persistScopedSettings("global",snapshotGlobalSettings,modifiedFields,modifiedNestedFields)})}saveProjectSettings(settings){if(this.assertProjectTrustedForWrite(),this.projectSettings=structuredClone(settings),this.updateSettings(this.mergedSettings()),this.projectSettingsLoadError)return;let snapshotProjectSettings=structuredClone(this.projectSettings),modifiedFields=new Set(this.modifiedProjectFields),modifiedNestedFields=this.cloneModifiedNestedFields(this.modifiedProjectNestedFields);this.enqueueWrite("project",()=>this.persistScopedSettings("project",snapshotProjectSettings,modifiedFields,modifiedNestedFields))}updateProjectSettings(field,update){this.assertProjectTrustedForWrite();let projectSettings=structuredClone(this.projectSettings);update(projectSettings),this.markProjectModified(field),this.saveProjectSettings(projectSettings)}async flush(){await this.writeQueue}drainErrors(){let drained=[...this.errors];return this.errors=[],drained}getLastChangelogVersion(){return this.settings.lastChangelogVersion}setLastChangelogVersion(version){this.globalSettings.lastChangelogVersion=version,this.markModified("lastChangelogVersion"),this.save()}getChangelogSeen(source="engine"){return this.settings.changelogSeen?.[source]??(source==="engine"?this.settings.lastChangelogVersion:void 0)}setChangelogSeen(source,version){!source||this.globalSettings.changelogSeen?.[source]===version||(this.globalSettings.changelogSeen={...this.globalSettings.changelogSeen??{},[source]:version},this.markModified("changelogSeen",source),this.save())}getSessionDir(){let sessionDir=this.settings.sessionDir;return sessionDir&&normalizePath(sessionDir)}getDefaultProvider(){return this.settings.defaultProvider}getDefaultModel(){return this.settings.defaultModel}setDefaultProvider(provider){this.globalSettings.defaultProvider=provider,this.markModified("defaultProvider"),this.save()}setDefaultModel(modelId){this.globalSettings.defaultModel=modelId,this.markModified("defaultModel"),this.save()}setDefaultModelAndProvider(provider,modelId){this.globalSettings.defaultProvider=provider,this.globalSettings.defaultModel=modelId,this.markModified("defaultProvider"),this.markModified("defaultModel"),this.save()}getSteeringMode(){return this.settings.steeringMode||"all"}setSteeringMode(mode){this.globalSettings.steeringMode=mode,this.markModified("steeringMode"),this.save()}getFollowUpMode(){return this.settings.followUpMode||"one-at-a-time"}setFollowUpMode(mode){this.globalSettings.followUpMode=mode,this.markModified("followUpMode"),this.save()}getThemeSetting(){let value=this.settings.theme;if(typeof value=="string")return value}getTheme(){let theme2=this.getThemeSetting();return theme2?.includes("/")?void 0:theme2}setTheme(theme2){this.globalSettings.theme=theme2,this.markModified("theme"),this.save()}getDefaultThinkingLevel(){return this.settings.defaultThinkingLevel}setDefaultThinkingLevel(level){this.globalSettings.defaultThinkingLevel=level,this.markModified("defaultThinkingLevel"),this.save()}getAllModelThinkingLevels(){return{...this.settings.modelThinkingLevels??{}}}getModelThinkingLevel(provider,modelId){return readModelMemoryEntry(this.settings.modelThinkingLevels,modelMemoryKey(provider,modelId),THINKING_LEVEL_VALUES)}setModelThinkingLevel(provider,modelId,level,options={}){let key=modelMemoryKey(provider,modelId),existing=this.globalSettings.modelThinkingLevels,map=typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?{...existing}:{};level===void 0?delete map[key]:map[key]=level,this.globalSettings.modelThinkingLevels=map,this.markModified("modelThinkingLevels",key),level!=="off"&&!options.preserveLastOn&&this.updateModelLastOnThinkingLevel(key,level),this.save()}getModelLastOnThinkingLevel(provider,modelId){let level=readModelMemoryEntry(this.settings.modelLastOnThinkingLevels,modelMemoryKey(provider,modelId),THINKING_LEVEL_VALUES);return level==="off"?void 0:level}setModelLastOnThinkingLevel(provider,modelId,level){this.updateModelLastOnThinkingLevel(modelMemoryKey(provider,modelId),level==="off"?void 0:level),this.save()}updateModelLastOnThinkingLevel(key,level){let existing=this.globalSettings.modelLastOnThinkingLevels,map=typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?{...existing}:{};level===void 0?delete map[key]:map[key]=level,this.globalSettings.modelLastOnThinkingLevels=map,this.markModified("modelLastOnThinkingLevels",key)}getModelServiceTier(provider,modelId){return readModelMemoryEntry(this.settings.modelServiceTiers,modelMemoryKey(provider,modelId),MODEL_SERVICE_TIER_VALUES)}setModelServiceTier(provider,modelId,tier){let key=modelMemoryKey(provider,modelId),existing=this.globalSettings.modelServiceTiers,map=typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?{...existing}:{};tier===void 0?delete map[key]:map[key]=tier,this.globalSettings.modelServiceTiers=map,this.markModified("modelServiceTiers",key),this.save()}getTransport(){return this.settings.transport??"auto"}getOpenAIServiceTier(){return this.settings.openai?.serviceTier}setTransport(transport){this.globalSettings.transport=transport,this.markModified("transport"),this.save()}getCompactionEnabled(){return compactionEnabled(this.settings.compaction)}setCompactionEnabled(enabled){this.globalSettings.compaction||(this.globalSettings.compaction={}),this.globalSettings.compaction.enabled=enabled,this.markModified("compaction","enabled"),this.save()}getCompactionReserveTokens(forModel){return compactionReserveTokens(this.settings.compaction,forModel)}getCompactionKeepRecentTokens(forModel){return compactionKeepRecentTokens(this.settings.compaction,forModel)}getCompactionSettings(forModel){return{...resolveCompactionSettings(this.settings.compaction,forModel),model:this.settings.compaction?.model}}getBranchSummarySettings(){return{reserveTokens:this.settings.branchSummary?.reserveTokens??16384,skipPrompt:this.settings.branchSummary?.skipPrompt??!1}}getBranchSummarySkipPrompt(){return this.settings.branchSummary?.skipPrompt??!1}getRetryEnabled(){return this.settings.retry?.enabled??!0}setRetryEnabled(enabled){this.globalSettings.retry||(this.globalSettings.retry={}),this.globalSettings.retry.enabled=enabled,this.markModified("retry","enabled"),this.save()}isRetryMaxAgentDelayMsConfigured(){return this.settings.retry?.maxAgentDelayMs!==void 0}getRetrySettings(){return{enabled:this.getRetryEnabled(),maxRetries:this.settings.retry?.maxRetries??SENPI_DEFAULT_RETRY_PROFILE.turn.maxRetries,baseDelayMs:this.settings.retry?.baseDelayMs??2e3,maxAgentDelayMs:this.settings.retry?.maxAgentDelayMs??DEFAULT_MAX_AGENT_RETRY_DELAY_MS}}getAbortServerSideFallback(){return resolveAbortServerSideFallback(this.settings.retry)}getRawFallbackChains(){return this.settings.retry?.fallbackChains}getFallbackChainsScope(){if(this.projectSettings.retry?.fallbackChains!==void 0)return"project";if(this.globalSettings.retry?.fallbackChains!==void 0)return"global"}getRetryFallbackSettings(){return resolveRetryFallbackSettings(this.settings.retry)}getFallbackCircuitSettings(){return resolveFallbackCircuitSettings(this.settings.fallback)}getHintPolicySettings(){return resolveHintPolicySettings(this.settings.retry)}setFallbackChain(key,entries){this.globalSettings.retry||(this.globalSettings.retry={});let chains=this.getGlobalFallbackChains();this.globalSettings.retry.fallbackChains={...chains,[key]:[...entries]},this.markModified("retry","fallbackChains"),this.save()}removeFallbackChain(key){let chains=this.getGlobalFallbackChains();key in chains&&(this.globalSettings.retry||(this.globalSettings.retry={}),delete chains[key],this.globalSettings.retry.fallbackChains=chains,this.markModified("retry","fallbackChains"),this.save())}setModelFallbackEnabled(enabled){this.globalSettings.retry||(this.globalSettings.retry={}),this.globalSettings.retry.modelFallback=enabled,this.markModified("retry","modelFallback"),this.save()}setFallbackRevertPolicy(policy){this.globalSettings.retry||(this.globalSettings.retry={}),this.globalSettings.retry.fallbackRevertPolicy=policy,this.markModified("retry","fallbackRevertPolicy"),this.save()}getGlobalFallbackChains(){let fallbackChains=this.globalSettings.retry?.fallbackChains;if(typeof fallbackChains!="object"||fallbackChains===null||Array.isArray(fallbackChains))return{};let chains={};for(let[key,entries]of Object.entries(fallbackChains))Array.isArray(entries)&&entries.every(entry=>typeof entry=="string")&&(chains[key]=[...entries]);return chains}getHttpIdleTimeoutMs(){return parseTimeoutSetting(this.settings.httpIdleTimeoutMs,"httpIdleTimeoutMs")??DEFAULT_HTTP_IDLE_TIMEOUT_MS}setHttpIdleTimeoutMs(timeoutMs){if(!Number.isFinite(timeoutMs)||timeoutMs<0)throw new Error(`Invalid httpIdleTimeoutMs setting: ${String(timeoutMs)}`);this.globalSettings.httpIdleTimeoutMs=Math.floor(timeoutMs),this.markModified("httpIdleTimeoutMs"),this.save()}getSessionShutdownHandlerWarnMs(){return parseTimeoutSetting(this.settings.sessionShutdownHandlerWarnMs,"sessionShutdownHandlerWarnMs")??DEFAULT_SESSION_SHUTDOWN_HANDLER_WARN_MS}setSessionShutdownHandlerWarnMs(warnMs){if(!Number.isFinite(warnMs)||warnMs<0)throw new Error(`Invalid sessionShutdownHandlerWarnMs setting: ${String(warnMs)}`);this.globalSettings.sessionShutdownHandlerWarnMs=Math.floor(warnMs),this.markModified("sessionShutdownHandlerWarnMs"),this.save()}getSessionShutdownHandlerTimeoutMs(){return parseTimeoutSetting(this.settings.sessionShutdownHandlerTimeoutMs,"sessionShutdownHandlerTimeoutMs")??DEFAULT_SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS}setSessionShutdownHandlerTimeoutMs(timeoutMs){if(!Number.isFinite(timeoutMs)||timeoutMs<0)throw new Error(`Invalid sessionShutdownHandlerTimeoutMs setting: ${String(timeoutMs)}`);this.globalSettings.sessionShutdownHandlerTimeoutMs=Math.floor(timeoutMs),this.markModified("sessionShutdownHandlerTimeoutMs"),this.save()}getSessionShutdownQuitBudgetMs(){return parseTimeoutSetting(this.settings.sessionShutdownQuitBudgetMs,"sessionShutdownQuitBudgetMs")??DEFAULT_SESSION_SHUTDOWN_QUIT_BUDGET_MS}setSessionShutdownQuitBudgetMs(budgetMs){if(!Number.isFinite(budgetMs)||budgetMs<0)throw new Error(`Invalid sessionShutdownQuitBudgetMs setting: ${String(budgetMs)}`);this.globalSettings.sessionShutdownQuitBudgetMs=Math.floor(budgetMs),this.markModified("sessionShutdownQuitBudgetMs"),this.save()}getExtensionEventHandlerWarnMs(){return parseTimeoutSetting(this.settings.extensionEventHandlerWarnMs,"extensionEventHandlerWarnMs")??DEFAULT_EXTENSION_EVENT_HANDLER_WARN_MS}getExtensionEventHandlerTimeoutMs(){return parseTimeoutSetting(this.settings.extensionEventHandlerTimeoutMs,"extensionEventHandlerTimeoutMs")??DEFAULT_EXTENSION_EVENT_HANDLER_TIMEOUT_MS}getProviderRetrySettings(){return{timeoutMs:this.settings.retry?.provider?.timeoutMs,maxRetries:this.settings.retry?.provider?.maxRetries,maxRetryDelayMs:this.settings.retry?.provider?.maxRetryDelayMs??6e4}}resolveRetryProfile(provider){let base=provider?.retryPolicy??SENPI_DEFAULT_RETRY_PROFILE,declared=provider?.retryPolicy!==void 0,turnBackoff={...base.turn.backoff};declared||this.settings.retry?.maxRetries!==void 0&&(turnBackoff.baseDelayMs=this.settings.retry.baseDelayMs??turnBackoff.baseDelayMs);let turnMaxRetries=base.turn.maxRetries,turnBaseDelayMs=turnBackoff.baseDelayMs;declared||(this.settings.retry?.maxRetries!==void 0&&(turnMaxRetries=this.settings.retry.maxRetries),this.settings.retry?.baseDelayMs!==void 0&&(turnBaseDelayMs=this.settings.retry.baseDelayMs));let providerOverride=this._resolveRetryProviderOverride(provider?.id);providerOverride?.turn?.maxRetries!==void 0&&(turnMaxRetries=providerOverride.turn.maxRetries),providerOverride?.turn?.baseDelayMs!==void 0&&(turnBaseDelayMs=providerOverride.turn.baseDelayMs);let turnEnabled=this.getRetryEnabled()?providerOverride?.turn?.enabled??base.turn.enabled:!1,tierStrategy=base.turn.serverHint.mode==="tiered"?base.turn.serverHint.strategy:()=>{throw new Error("not tiered")},turn={enabled:turnEnabled,maxRetries:turnMaxRetries,backoff:{...base.turn.backoff,baseDelayMs:turnBaseDelayMs},extractServerHint:base.turn.extractServerHint,serverHint:base.turn.serverHint.mode==="tiered"?{mode:"tiered",strategy:tierStrategy}:base.turn.serverHint,classify:base.turn.classify};return{id:base.id,providerRequest:base.providerRequest,turn,fallback:base.fallback}}_resolveRetryProviderOverride(providerId){if(providerId===void 0)return;let raw=this.settings.retry?.providers;if(raw===void 0)return;let{overrides}=validateRetryProviderOverrides(raw,new Set([providerId]));return overrides[providerId]}getProviderStreamRetryTimeoutMs(){let explicit=this.settings.retry?.provider?.streamRetryTimeoutMs;return explicit!==void 0?explicit>0?explicit:void 0:DEFAULT_PROVIDER_STREAM_RETRY_TIMEOUT_MS}getAgentStreamIdleTimeoutMs(){let providerTimeoutMs=this.settings.retry?.provider?.timeoutMs;if(providerTimeoutMs!==void 0)return providerTimeoutMs;let httpIdleTimeoutMs=this.getHttpIdleTimeoutMs();return httpIdleTimeoutMs===0?void 0:httpIdleTimeoutMs}getAgentStreamStartTimeoutMs(){let explicit=this.settings.retry?.provider?.streamStartTimeoutMs;if(explicit!==void 0)return explicit>0?explicit:void 0;let idleTimeoutMs=this.getAgentStreamIdleTimeoutMs();if(idleTimeoutMs!==void 0)return Math.min(DEFAULT_STREAM_START_TIMEOUT_MS,idleTimeoutMs)}getWebSocketConnectTimeoutMs(){return parseTimeoutSetting(this.settings.websocketConnectTimeoutMs,"websocketConnectTimeoutMs")}getHideThinkingBlock(){return this.settings.hideThinkingBlock??!1}getSmoothStreaming(){return this.settings.smoothStreaming??!0}getSmoothStreamingFps(){let fps=this.settings.smoothStreamingFps;return typeof fps!="number"||!Number.isFinite(fps)?60:Math.min(120,Math.max(30,fps))}getShowCacheMissNotices(){return this.settings.showCacheMissNotices??!1}getExternalEditorCommand(){let configuredEditor=this.settings.externalEditor;if(typeof configuredEditor=="string"&&configuredEditor.trim()!=="")return configuredEditor;let environmentEditor=process.env.VISUAL||process.env.EDITOR;return environmentEditor||(process.platform==="win32"?"notepad":"nano")}setHideThinkingBlock(hide){this.globalSettings.hideThinkingBlock=hide,this.markModified("hideThinkingBlock"),this.save()}setSmoothStreaming(enabled){this.globalSettings.smoothStreaming=enabled,this.markModified("smoothStreaming"),this.save()}setSmoothStreamingFps(fps){this.globalSettings.smoothStreamingFps=fps,this.markModified("smoothStreamingFps"),this.save()}setShowCacheMissNotices(show){this.globalSettings.showCacheMissNotices=show,this.markModified("showCacheMissNotices"),this.save()}getShellPath(){let shellPath=this.settings.shellPath;return shellPath&&normalizePath(shellPath)}setShellPath(path2){this.globalSettings.shellPath=path2,this.markModified("shellPath"),this.save()}getQuietStartup(){let value=this.settings.quietStartup;return value===!0||value==="header"?value:!1}setQuietStartup(quiet){this.globalSettings.quietStartup=quiet,this.markModified("quietStartup"),this.save()}getTipsEnabled(){return this.settings.tips??!0}getTipsHistory(){let history=this.settings.tipsHistory;return typeof history!="object"||history===null||Array.isArray(history)?{}:{...history}}setTipsHistory(history){this.globalSettings.tipsHistory=history,this.markModified("tipsHistory"),this.save()}setTipShown(tipId,timestamp){let history=this.getTipsHistory();history[tipId]=timestamp,this.globalSettings.tipsHistory=history,this.markModified("tipsHistory",tipId),this.save()}getDefaultProjectTrust(){let value=this.globalSettings.defaultProjectTrust;return value==="always"||value==="never"?value:"ask"}setDefaultProjectTrust(defaultProjectTrust){this.globalSettings.defaultProjectTrust=defaultProjectTrust,this.markModified("defaultProjectTrust"),this.save()}getShellCommandPrefix(){return this.settings.shellCommandPrefix}setShellCommandPrefix(prefix){this.globalSettings.shellCommandPrefix=prefix,this.markModified("shellCommandPrefix"),this.save()}getNpmCommand(){return this.settings.npmCommand?[...this.settings.npmCommand]:void 0}setNpmCommand(command){this.globalSettings.npmCommand=command?[...command]:void 0,this.markModified("npmCommand"),this.save()}getCollapseChangelog(){return this.settings.collapseChangelog??!1}setCollapseChangelog(collapse){this.globalSettings.collapseChangelog=collapse,this.markModified("collapseChangelog"),this.save()}getEnableInstallTelemetry(){return this.settings.enableInstallTelemetry??!0}setEnableInstallTelemetry(enabled){this.globalSettings.enableInstallTelemetry=enabled,this.markModified("enableInstallTelemetry"),this.save()}getEnableSessionShare(){return this.settings.enableSessionShare??!0}getEnableAnalytics(){return this.settings.enableAnalytics??!1}getTrackingId(){return this.settings.trackingId}setEnableAnalytics(enabled){this.globalSettings.enableAnalytics=enabled,this.markModified("enableAnalytics"),enabled&&!this.globalSettings.trackingId&&(this.globalSettings.trackingId=randomUUID(),this.markModified("trackingId")),this.save()}getOrCreateDeviceId(){return this.globalSettings.deviceId||(this.globalSettings.deviceId=randomUUID(),this.markModified("deviceId"),this.save()),this.globalSettings.deviceId}getPackages(){return[...this.settings.packages??[]]}getDisabledBuiltinExtensions(){return[...this.settings.disabledBuiltinExtensions??[]]}getEnabledBuiltinExtensions(){return this.settings.enabledBuiltinExtensions?[...this.settings.enabledBuiltinExtensions]:void 0}setPackages(packages){this.globalSettings.packages=packages,this.markModified("packages"),this.save()}setProjectPackages(packages){this.updateProjectSettings("packages",settings=>{settings.packages=packages})}getExtensionPaths(){return[...this.settings.extensions??[]]}setExtensionPaths(paths){this.globalSettings.extensions=paths,this.markModified("extensions"),this.save()}setProjectExtensionPaths(paths){this.updateProjectSettings("extensions",settings=>{settings.extensions=paths})}getSkillPaths(){return[...this.settings.skills??[]]}setSkillPaths(paths){this.globalSettings.skills=paths,this.markModified("skills"),this.save()}setProjectSkillPaths(paths){this.updateProjectSettings("skills",settings=>{settings.skills=paths})}getPromptTemplatePaths(){return[...this.settings.prompts??[]]}setPromptTemplatePaths(paths){this.globalSettings.prompts=paths,this.markModified("prompts"),this.save()}setProjectPromptTemplatePaths(paths){this.updateProjectSettings("prompts",settings=>{settings.prompts=paths})}getThemePaths(){return[...this.settings.themes??[]]}setThemePaths(paths){this.globalSettings.themes=paths,this.markModified("themes"),this.save()}setProjectThemePaths(paths){this.updateProjectSettings("themes",settings=>{settings.themes=paths})}getEnableSkillCommands(){return this.settings.enableSkillCommands??!0}getMaxSkillExpansionsPerPrompt(){let value=this.settings.maxSkillExpansionsPerPrompt;return typeof value=="number"&&Number.isInteger(value)&&value>0?value:MAX_SKILL_EXPANSIONS_PER_PROMPT}setEnableSkillCommands(enabled){this.globalSettings.enableSkillCommands=enabled,this.markModified("enableSkillCommands"),this.save()}getThinkingBudgets(){return this.settings.thinkingBudgets}getTerminalCapabilityOverrides(){let terminal=this.settings.terminal,imageSetting=terminal?.images,imageOverride=imageSetting!==void 0?imageSetting:envValue("IMAGE_PROTOCOL")?.toLowerCase(),trueColorSetting=terminal?.trueColor,trueColorOverride=trueColorSetting!==void 0?trueColorSetting:envValue("TRUE_COLOR"),hyperlinksSetting=terminal?.hyperlinks,hyperlinksOverride=hyperlinksSetting!==void 0?hyperlinksSetting:envValue("HYPERLINKS");return{...imageOverride==="kitty"||imageOverride==="iterm2"?{images:imageOverride}:imageOverride===!1||imageOverride==="none"||imageOverride==="0"?{images:null}:{},...typeof trueColorOverride=="boolean"?{trueColor:trueColorOverride}:trueColorOverride==="1"||trueColorOverride==="0"?{trueColor:trueColorOverride==="1"}:{},...typeof hyperlinksOverride=="boolean"?{hyperlinks:hyperlinksOverride}:hyperlinksOverride==="1"||hyperlinksOverride==="0"?{hyperlinks:hyperlinksOverride==="1"}:{}}}getShowImages(){return this.settings.terminal?.showImages??!0}setShowImages(show){this.globalSettings.terminal||(this.globalSettings.terminal={}),this.globalSettings.terminal.showImages=show,this.markModified("terminal","showImages"),this.save()}getImageWidthCells(){let width=this.settings.terminal?.imageWidthCells;return typeof width!="number"||!Number.isFinite(width)?60:Math.max(1,Math.floor(width))}setImageWidthCells(width){this.globalSettings.terminal||(this.globalSettings.terminal={}),this.globalSettings.terminal.imageWidthCells=Math.max(1,Math.floor(width)),this.markModified("terminal","imageWidthCells"),this.save()}getTerminalMouse(){let value=this.settings.terminal?.mouse;return isTerminalMouseMode(value)?value:"whilePending"}setTerminalMouse(mouse){if(!isTerminalMouseMode(mouse))throw new TypeError("Invalid terminal.mouse");this.globalSettings.terminal??={},this.globalSettings.terminal.mouse=mouse,this.markModified("terminal","mouse"),this.save()}getClearOnShrink(){return this.settings.terminal?.clearOnShrink!==void 0?this.settings.terminal.clearOnShrink:envValue("CLEAR_ON_SHRINK")==="1"}setClearOnShrink(enabled){this.globalSettings.terminal||(this.globalSettings.terminal={}),this.globalSettings.terminal.clearOnShrink=enabled,this.markModified("terminal","clearOnShrink"),this.save()}getShowTerminalProgress(){return this.settings.terminal?.showTerminalProgress??!1}setShowTerminalProgress(enabled){this.globalSettings.terminal||(this.globalSettings.terminal={}),this.globalSettings.terminal.showTerminalProgress=enabled,this.markModified("terminal","showTerminalProgress"),this.save()}getTuiMode(){return this.settings.tuiMode==="fullscreen"?"fullscreen":"regular"}setTuiMode(mode){this.globalSettings.tuiMode=mode,this.markModified("tuiMode"),this.save()}getFullscreenExitOutput(){return this.settings.fullscreenExitOutput==="resume-hint"?"resume-hint":"transcript"}setFullscreenExitOutput(output){this.globalSettings.fullscreenExitOutput=output,this.markModified("fullscreenExitOutput"),this.save()}getFullscreenScrollbar(){let mode=this.settings.fullscreenScrollbar;return mode==="always"||mode==="hidden"?mode:"auto"}setFullscreenScrollbar(mode){this.globalSettings.fullscreenScrollbar=mode,this.markModified("fullscreenScrollbar"),this.save()}getFullscreenCopyOnSelect(){return this.settings.fullscreenCopyOnSelect??!0}setFullscreenCopyOnSelect(enabled){this.globalSettings.fullscreenCopyOnSelect=enabled,this.markModified("fullscreenCopyOnSelect"),this.save()}getFullscreenWheelScrollLines(){let lines=this.settings.fullscreenWheelScrollLines;return typeof lines=="number"&&Number.isFinite(lines)?Math.max(1,Math.min(100,Math.floor(lines))):"auto"}setFullscreenWheelScrollLines(lines){this.globalSettings.fullscreenWheelScrollLines=lines==="auto"?lines:Math.max(1,Math.min(100,Math.floor(lines))),this.markModified("fullscreenWheelScrollLines"),this.save()}getImageAutoResize(){return this.settings.images?.autoResize??!0}setImageAutoResize(enabled){this.globalSettings.images||(this.globalSettings.images={}),this.globalSettings.images.autoResize=enabled,this.markModified("images","autoResize"),this.save()}getBlockImages(){return this.settings.images?.blockImages??!1}getMaxHistoricalImages(){let value=this.settings.images?.maxHistoricalImages;return Number.isInteger(value)&&value!==void 0&&value>=0?value:void 0}setBlockImages(blocked){this.globalSettings.images||(this.globalSettings.images={}),this.globalSettings.images.blockImages=blocked,this.markModified("images","blockImages"),this.save()}getEnabledModels(){return this.settings.enabledModels}getRecommendedModels(){return this.settings.recommendedModels?[...this.settings.recommendedModels]:void 0}getFavoriteModels(){return this.settings.favoriteModels}setFavoriteModels(patterns){this.globalSettings.favoriteModels=patterns,this.markModified("favoriteModels"),this.save()}getDefaultTools(){let tools=this.settings.defaultTools;if(tools!==void 0)return resolveDefaultTools(Array.isArray(tools)?tools.filter(tool=>typeof tool=="string"):[])}setEnabledModels(patterns){this.globalSettings.enabledModels=patterns,this.markModified("enabledModels"),this.save()}getDoubleEscapeAction(){return this.settings.doubleEscapeAction??"tree"}setDoubleEscapeAction(action){this.globalSettings.doubleEscapeAction=action,this.markModified("doubleEscapeAction"),this.save()}getTreeFilterMode(){let mode=this.settings.treeFilterMode;return mode&&["default","no-tools","user-only","labeled-only","all"].includes(mode)?mode:"default"}setTreeFilterMode(mode){this.globalSettings.treeFilterMode=mode,this.markModified("treeFilterMode"),this.save()}getShowHardwareCursor(){return this.settings.showHardwareCursor??envValue("HARDWARE_CURSOR")==="1"}setShowHardwareCursor(enabled){this.globalSettings.showHardwareCursor=enabled,this.markModified("showHardwareCursor"),this.save()}getEditorPaddingX(){return this.settings.editorPaddingX??0}setEditorPaddingX(padding){this.globalSettings.editorPaddingX=Math.max(0,Math.min(3,Math.floor(padding))),this.markModified("editorPaddingX"),this.save()}getOutputPad(){return this.settings.outputPad===0?0:1}setOutputPad(padding){this.globalSettings.outputPad=padding,this.markModified("outputPad"),this.save()}getAutocompleteMaxVisible(){return this.settings.autocompleteMaxVisible??5}setAutocompleteMaxVisible(maxVisible){this.globalSettings.autocompleteMaxVisible=Math.max(3,Math.min(20,Math.floor(maxVisible))),this.markModified("autocompleteMaxVisible"),this.save()}getCodeBlockIndent(){return this.settings.markdown?.codeBlockIndent??" "}getMermaidRenderingMode(){let mode=this.settings.markdown?.mermaid;return mode==="off"||mode==="final"?mode:"streaming"}setMermaidRenderingMode(mode){this.globalSettings.markdown??={},this.globalSettings.markdown.mermaid=mode,this.markModified("markdown","mermaid"),this.save()}getWarnings(){return{...this.settings.warnings??{}}}setWarnings(warnings){this.globalSettings.warnings={...warnings},this.markModified("warnings"),this.save()}};var CountdownTimer=class{constructor(timeoutMs,tui,onTick,onExpire){this.tui=tui,this.onTick=onTick,this.onExpire=onExpire,this.remainingSeconds=Math.ceil(timeoutMs/1e3),this.onTick(this.remainingSeconds),this.intervalId=setInterval(()=>{this.remainingSeconds--,this.onTick(this.remainingSeconds),this.tui?.requestRender(),this.remainingSeconds<=0&&(this.dispose(),this.onExpire())},1e3)}dispose(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0)}};var ExtensionInputComponent=class extends Container{get focused(){return this._focused}set focused(value){this._focused=value,this.input.focused=value}constructor(title,_placeholder,onSubmit,onCancel,opts){super(),this._focused=!1,this.onSubmitCallback=onSubmit,this.onCancelCallback=onCancel,this.baseTitle=title,this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.titleText=new Text(theme.fg("accent",title),1,0),this.addChild(this.titleText),opts?.description&&(this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("text",opts.description),1,0))),this.addChild(new Spacer(1)),opts?.timeout&&opts.timeout>0&&opts.tui&&(this.countdown=new CountdownTimer(opts.timeout,opts.tui,s=>this.titleText.setText(theme.fg("accent",`${this.baseTitle} (${s}s)`)),()=>this.onCancelCallback())),this.input=new Input,opts?.initialValue&&this.input.handleInput(opts.initialValue),this.addChild(this.input),this.addChild(new Spacer(1)),this.addChild(new Text(`${keyHint("tui.select.confirm","submit")} ${keyHint("tui.select.cancel","cancel")}`,1,0)),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder)}handleInput(keyData){let kb=getKeybindings();kb.matches(keyData,"tui.select.confirm")||keyData===`
|
|
168
168
|
`?this.onSubmitCallback(this.input.getValue()):kb.matches(keyData,"tui.select.cancel")?this.onCancelCallback():this.input.handleInput(keyData)}dispose(){this.countdown?.dispose()}};var ExtensionSelectorComponent=class _ExtensionSelectorComponent extends Container{static{this.DEFAULT_MAX_VISIBLE_OPTIONS=10}constructor(title,options,onSelect,onCancel,opts){super(),this.selectedIndex=0,this.options=options,this.onSelectCallback=onSelect,this.onCancelCallback=onCancel,this.onToggleToolsExpanded=opts?.onToggleToolsExpanded,this.baseTitle=title,this.maxVisibleOptions=opts?.tui?Math.max(5,Math.floor(opts.tui.terminal.rows/2)):_ExtensionSelectorComponent.DEFAULT_MAX_VISIBLE_OPTIONS,this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.titleText=new Text(theme.fg("accent",theme.bold(title)),1,0),this.addChild(this.titleText),opts?.description&&(this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("text",opts.description),1,0))),this.addChild(new Spacer(1)),opts?.timeout&&opts.timeout>0&&opts.tui&&(this.countdown=new CountdownTimer(opts.timeout,opts.tui,s=>this.titleText.setText(theme.fg("accent",theme.bold(`${this.baseTitle} (${s}s)`))),()=>this.onCancelCallback())),this.listContainer=new Container,this.addChild(this.listContainer),this.addChild(new Spacer(1)),this.addChild(new Text(rawKeyHint("\u2191\u2193","navigate")+" "+keyHint("tui.select.confirm","select")+" "+keyHint("tui.select.cancel","cancel"),1,0)),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder),this.updateList()}updateList(){this.listContainer.clear();let count=this.options.length,startIndex=Math.max(0,Math.min(this.selectedIndex-Math.floor(this.maxVisibleOptions/2),count-this.maxVisibleOptions)),endIndex=Math.min(startIndex+this.maxVisibleOptions,count);startIndex>0&&this.listContainer.addChild(new Text(theme.fg("muted",` \u2026 ${startIndex} more above`),1,0));for(let i=startIndex;i<endIndex;i++){let text=i===this.selectedIndex?theme.fg("accent","\u2192 ")+theme.fg("accent",this.options[i]):` ${theme.fg("text",this.options[i])}`;this.listContainer.addChild(new Text(text,1,0))}endIndex<count&&this.listContainer.addChild(new Text(theme.fg("muted",` \u2026 ${count-endIndex} more below`),1,0))}handleInput(keyData){let kb=getKeybindings();if(kb.matches(keyData,"app.tools.expand"))this.onToggleToolsExpanded?.();else if(kb.matches(keyData,"tui.select.up")||keyData==="k")this.selectedIndex=Math.max(0,this.selectedIndex-1),this.updateList();else if(kb.matches(keyData,"tui.select.down")||keyData==="j")this.selectedIndex=Math.min(this.options.length-1,this.selectedIndex+1),this.updateList();else if(kb.matches(keyData,"tui.select.confirm")||keyData===`
|
|
@@ -175,4 +175,4 @@ and bugs within Pi. You can observe what is shared using /privacy and make
|
|
|
175
175
|
changes anytime in settings.json.`),1,0)),this.addChild(new Spacer(1)),this.addOptionList(ANALYTICS_OPTIONS.map(option=>option.label),this.analyticsIndex)),this.addChild(new Spacer(1)),this.addChild(new Text(rawKeyHint("\u2191\u2193","navigate")+" "+keyHint("tui.select.confirm",this.step==="theme"?"continue":"finish")+" "+keyHint("tui.select.cancel","skip setup"),1,0)),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder)}addOptionList(labels,selectedIndex){for(let i=0;i<labels.length;i++){let isSelected=i===selectedIndex,prefix=isSelected?theme.fg("accent","\u2192 "):" ",label=isSelected?theme.fg("accent",labels[i]):theme.fg("text",labels[i]);this.addChild(new Text(`${prefix}${label}`,1,0))}}moveSelection(delta){if(this.step==="theme"){let next=Math.max(0,Math.min(THEME_OPTIONS.length-1,this.themeIndex+delta));next!==this.themeIndex&&(this.themeIndex=next,this.options.onThemePreview(THEME_OPTIONS[this.themeIndex].value))}else this.analyticsIndex=Math.max(0,Math.min(ANALYTICS_OPTIONS.length-1,this.analyticsIndex+delta));this.update()}handleInput(keyData){let kb=getKeybindings();kb.matches(keyData,"tui.select.up")||keyData==="k"?this.moveSelection(-1):kb.matches(keyData,"tui.select.down")||keyData==="j"?this.moveSelection(1):kb.matches(keyData,"tui.select.confirm")||keyData===`
|
|
176
176
|
`?this.step==="theme"?(this.step="analytics",this.update()):this.options.onSubmit({theme:THEME_OPTIONS[this.themeIndex].value,shareAnalytics:ANALYTICS_OPTIONS[this.analyticsIndex].value}):kb.matches(keyData,"tui.select.cancel")&&this.options.onCancel()}};var OFFICIAL_PACKAGE_NAME="@earendil-works/pi-coding-agent",OFFICIAL_APP_NAME="pi",OFFICIAL_CONFIG_DIR_NAME=".pi";function isOfficialDistribution({packageName,appName,configDirName}){return packageName===OFFICIAL_PACKAGE_NAME&&appName===OFFICIAL_APP_NAME&&configDirName===OFFICIAL_CONFIG_DIR_NAME}function loadThemes(resources){let themes=[],seen=new Set;for(let resource of resources)if(resource.enabled)try{let loadedTheme=loadThemeFromPath(resource.path);if(loadedTheme.name){if(seen.has(loadedTheme.name))continue;seen.add(loadedTheme.name)}themes.push(loadedTheme)}catch{}return themes}async function loadStartupThemes(settingsManager){let globalSettingsManager=SettingsManager.inMemory(settingsManager.getGlobalSettings(),{projectTrusted:!1}),resolvedPaths=await new DefaultPackageManager({cwd:process.cwd(),agentDir:getAgentDir(),settingsManager:globalSettingsManager}).resolve(async()=>"skip");return loadThemes(resolvedPaths.themes)}async function createStartupTui(settingsManager){setCapabilityOverrides(settingsManager.getTerminalCapabilityOverrides()),setRegisteredThemes(await loadStartupThemes(settingsManager)),markTerminalColorsPending(),initTheme(resolveThemeSetting(settingsManager.getThemeSetting(),getTerminalTheme())??SYSTEM_THEME_NAME),setKeybindings(KeybindingsManager.create());let ui=new TUI(new ProcessTerminal({onExternalStdoutWrite:appendHiddenTuiStdout}),settingsManager.getShowHardwareCursor());return ui.setClearOnShrink(settingsManager.getClearOnShrink()),ui}function startStartupTui(ui,settingsManager){ui.start();let themeSetting=settingsManager.getThemeSetting();queryStartupTerminalColors(ui,()=>{setTheme(resolveThemeSetting(themeSetting,getTerminalTheme())??SYSTEM_THEME_NAME)})}function queryStartupTerminalColors(ui,onColors){requestTerminalColors(ui,colors=>{setTerminalColors(colors),onColors(),ui.invalidate(),ui.requestRender()})}async function clearStartupTui(ui){ui.clear(),ui.requestRender(),await new Promise(resolve6=>setTimeout(resolve6,25))}function shouldRunFirstTimeSetup(settingsPath=getSettingsPath()){return!isOfficialDistribution({packageName:PACKAGE_NAME,appName:APP_NAME,configDirName:CONFIG_DIR_NAME})||!areExperimentalFeaturesEnabled()||process.env[ENV_AGENT_DIR]?!1:!existsSync5(settingsPath)}async function showStartupSelector(settingsManager,title,options){let ui=await createStartupTui(settingsManager);return new Promise(resolve6=>{let settled=!1,finish=async result=>{settled||(settled=!0,await clearStartupTui(ui),ui.stop(),resolve6(result))},selector=new ExtensionSelectorComponent(title,options.map(option=>option.label),option=>{finish(options.find(entry=>entry.label===option)?.value)},()=>{finish(void 0)},{tui:ui});ui.addChild(selector),ui.setFocus(selector),startStartupTui(ui,settingsManager)})}async function showFirstTimeSetup(settingsManager){let ui=await createStartupTui(settingsManager);return new Promise(resolve6=>{let settled=!1,finish=async result=>{settled||(settled=!0,result&&(settingsManager.setTheme(result.theme),settingsManager.setEnableAnalytics(result.shareAnalytics),await settingsManager.flush()),await clearStartupTui(ui),ui.stop(),resolve6())};ui.start();let previewTheme=SYSTEM_THEME_NAME;setTheme(previewTheme);let component=new FirstTimeSetupComponent({onThemePreview:themeName=>{previewTheme=themeName,setTheme(themeName),ui.requestRender()},onSubmit:result=>{finish(result)},onCancel:()=>{finish(void 0)}});ui.addChild(component),ui.setFocus(component),ui.requestRender(),queryStartupTerminalColors(ui,()=>setTheme(previewTheme))})}async function showStartupInput(settingsManager,title,placeholder){let ui=await createStartupTui(settingsManager);return new Promise(resolve6=>{let settled=!1,finish=async result=>{settled||(settled=!0,input.dispose(),await clearStartupTui(ui),ui.stop(),resolve6(result))},input=new ExtensionInputComponent(title,placeholder,value=>{finish(value)},()=>{finish(void 0)},{tui:ui});ui.addChild(input),ui.setFocus(input),startStartupTui(ui,settingsManager)})}import{spawnSync}from"node:child_process";import{existsSync as existsSync7}from"node:fs";import{unlink}from"node:fs/promises";import*as os from"node:os";import{createHash as createHash4,randomBytes}from"node:crypto";import{chmodSync as chmodSync2,existsSync as existsSync6,lstatSync as lstatSync2,mkdirSync as mkdirSync4,readdirSync as readdirSync3,renameSync as renameSync3,rmSync as rmSync3,statSync as statSync4,writeFileSync as writeFileSync4}from"node:fs";import{open as open2}from"node:fs/promises";import{dirname as dirname5,join as join6,resolve as resolve5}from"node:path";var MAX_TOOL_IMAGE_BYTES=20*1024*1024,MAX_SESSION_MEDIA_BYTES=256*1024*1024,DEFAULT_LIMITS={perImage:MAX_TOOL_IMAGE_BYTES,perSession:MAX_SESSION_MEDIA_BYTES},MEDIA_DIRECTORY="media",EXTENSIONS={"image/png":"png","image/jpeg":"jpg","image/gif":"gif","image/webp":"webp"},reserved=new Map,SIGNATURES={"image/png":bytes=>bytes.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])),"image/jpeg":bytes=>bytes.subarray(0,3).equals(Buffer.from([255,216,255])),"image/gif":bytes=>bytes.subarray(0,4).toString("latin1")==="GIF8","image/webp":bytes=>bytes.subarray(0,4).toString("latin1")==="RIFF"&&bytes.subarray(8,12).toString("latin1")==="WEBP"};function assertRealDirectoryChain(root,callDirectory){for(let path2 of[dirname5(root),root,callDirectory]){let stat;try{stat=lstatSync2(path2)}catch{continue}if(!stat.isDirectory())throw new Error(`not a real directory: ${path2}`)}}var outcomes=new WeakMap;function liveToolMediaScope(entry){let manager=entry.runtime?.session.sessionManager,sessionFile=manager?.getSessionFile()??entry.worker?.snapshot?.state.sessionFile,durableSessionId=manager?.getSessionId()??entry.worker?.snapshot?.state.sessionId;return sessionFile===void 0||durableSessionId===void 0?void 0:{sessionDir:dirname5(sessionFile),durableSessionId}}function toolMediaRoot(scope){return assertValidSessionId(scope.durableSessionId),join6(scope.sessionDir,MEDIA_DIRECTORY,scope.durableSessionId)}function directoryBytes(directory){let total=0;for(let entry of readdirSync3(directory,{withFileTypes:!0})){let path2=join6(directory,entry.name);total+=entry.isDirectory()?directoryBytes(path2):statSync4(path2).size}return total}function storedBytes(root){let known=reserved.get(root);if(known!==void 0)return known;let scanned=existsSync6(root)?directoryBytes(root):0;return reserved.set(root,scanned),scanned}var unavailable=reason=>({unavailableReason:reason});function writeImage(root,path2,bytes){let callDirectory=dirname5(path2);mkdirSync4(callDirectory,{recursive:!0,mode:448}),assertRealDirectoryChain(root,callDirectory);let staging=`${path2}.${randomBytes(6).toString("hex")}.tmp`;try{writeFileSync4(staging,bytes,{mode:384,flag:"wx"}),renameSync3(staging,path2),chmodSync2(path2,256)}catch(cause){throw rmSync3(staging,{force:!0}),cause}}function persistToolImage(scope,ref,block,limits=DEFAULT_LIMITS){let known=outcomes.get(block);if(known!==void 0)return known;let outcome=store(scope,ref,block,limits);return(!("unavailableReason"in outcome)||outcome.unavailableReason!=="storage_error")&&outcomes.set(block,outcome),outcome}function store(scope,ref,block,limits){let extension=EXTENSIONS[(block.mimeType??"").toLowerCase()];if(extension===void 0)return unavailable("storage_error");if(base64ByteLength(block.data)>limits.perImage)return unavailable("image_too_large");let bytes=Buffer.from(block.data,"base64");if(bytes.length>limits.perImage)return unavailable("image_too_large");if(SIGNATURES[(block.mimeType??"").toLowerCase()]?.(bytes)!==!0)return unavailable("storage_error");try{let root=toolMediaRoot(scope),callDirectory=createHash4("sha256").update(ref.toolCallId).digest("hex"),digest=createHash4("sha256").update(bytes).digest("hex"),path2=resolve5(root,callDirectory,`${ref.contentIndex}-${digest}.${extension}`);if(assertRealDirectoryChain(root,dirname5(path2)),existsSync6(path2))return{path:path2};let used=storedBytes(root);if(used+bytes.length>limits.perSession)return unavailable("session_limit");reserved.set(root,used+bytes.length);try{writeImage(root,path2,bytes)}catch(cause){throw reserved.set(root,storedBytes(root)-bytes.length),cause}return{path:path2}}catch{return unavailable("storage_error")}}function toolMediaPersister(scope){return(ref,block)=>{let current=scope();return current===void 0?void 0:persistToolImage(current,ref,block)}}function removeToolMedia(scope){let root=toolMediaRoot(scope);reserved.delete(root),makeTreeWritable(root),rmSync3(root,{recursive:!0,force:!0})}function makeTreeWritable(path2){let entries;try{if(!lstatSync2(path2).isDirectory())return;chmodSync2(path2,448),entries=readdirSync3(path2,{withFileTypes:!0})}catch{return}for(let entry of entries){let child=join6(path2,entry.name);if(entry.isDirectory())makeTreeWritable(child);else if(entry.isFile())try{chmodSync2(child,384)}catch{}}}async function toolMediaScopeOfSessionFile(sessionFile){try{let handle=await open2(sessionFile,"r");try{let{buffer,bytesRead}=await handle.read(Buffer.alloc(4096),0,4096,0),firstLine=buffer.subarray(0,bytesRead).toString("utf8").split(`
|
|
177
177
|
`,1)[0]??"",id=JSON.parse(firstLine).id;return typeof id=="string"?{sessionDir:dirname5(sessionFile),durableSessionId:id}:void 0}finally{await handle.close()}}catch{return}}function normalizeWhitespaceLower(text){return text.toLowerCase().replace(/\s+/g," ").trim()}var searchTextCache=new WeakMap;function getSessionSearchText(session){let cached=searchTextCache.get(session);if(cached)return cached;let fileNameId=sessionFileNameId(session.path),text=`${fileNameId===void 0||fileNameId===session.id?session.id:`${session.id} ${fileNameId}`} ${session.name??""} ${session.allMessagesText} ${session.cwd}`,entry={text,lower:text.toLowerCase()};return searchTextCache.set(session,entry),entry}function prepareTokens(parsed){return parsed.tokens.map(token=>token.kind==="phrase"?{kind:"phrase",normalized:normalizeWhitespaceLower(token.value)}:{kind:"fuzzy",lower:token.value.toLowerCase()})}function hasSessionName(session){return!!session.name?.trim()}function matchesNameFilter(session,filter2){return filter2==="all"?!0:hasSessionName(session)}function parseSearchQuery(query){let trimmed=query.trim();if(!trimmed)return{mode:"tokens",tokens:[],regex:null};if(trimmed.startsWith("re:")){let pattern=trimmed.slice(3).trim();if(!pattern)return{mode:"regex",tokens:[],regex:null,error:"Empty regex"};try{return{mode:"regex",tokens:[],regex:new RegExp(pattern,"i")}}catch(err){let msg=err instanceof Error?err.message:String(err);return{mode:"regex",tokens:[],regex:null,error:msg}}}let tokens=[],buf="",inQuote=!1,hadUnclosedQuote=!1,flush=kind=>{let v=buf.trim();buf="",v&&tokens.push({kind,value:v})};for(let i=0;i<trimmed.length;i++){let ch=trimmed[i];if(ch==='"'){inQuote?(flush("phrase"),inQuote=!1):(flush("fuzzy"),inQuote=!0);continue}if(!inQuote&&/\s/.test(ch)){flush("fuzzy");continue}buf+=ch}return inQuote&&(hadUnclosedQuote=!0),hadUnclosedQuote?{mode:"tokens",tokens:trimmed.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0).map(t=>({kind:"fuzzy",value:t})),regex:null}:(flush(inQuote?"phrase":"fuzzy"),{mode:"tokens",tokens,regex:null})}function matchPrepared(session,parsed,tokens){let searchText=getSessionSearchText(session);if(parsed.mode==="regex"){if(!parsed.regex)return{matches:!1,score:0};let idx=searchText.text.search(parsed.regex);return idx<0?{matches:!1,score:0}:{matches:!0,score:idx*.1}}if(tokens.length===0)return{matches:!0,score:0};let totalScore=0;for(let token of tokens){if(token.kind==="phrase"){if(searchText.normalized??=normalizeWhitespaceLower(searchText.text),!token.normalized)continue;let idx=searchText.normalized.indexOf(token.normalized);if(idx<0)return{matches:!1,score:0};totalScore+=idx*.1;continue}let m=fuzzyMatchLower(token.lower,searchText.lower);if(!m.matches)return{matches:!1,score:0};totalScore+=m.score}return{matches:!0,score:totalScore}}function filterAndSortSessions(sessions,query,sortMode,nameFilter="all"){let nameFiltered=nameFilter==="all"?sessions:sessions.filter(session=>matchesNameFilter(session,nameFilter));if(!query.trim())return nameFiltered;let parsed=parseSearchQuery(query);if(parsed.error)return[];let tokens=prepareTokens(parsed);if(sortMode==="recent"){let filtered=[];for(let s of nameFiltered)matchPrepared(s,parsed,tokens).matches&&filtered.push(s);return filtered}let scored=[];for(let s of nameFiltered){let res=matchPrepared(s,parsed,tokens);res.matches&&scored.push({session:s,score:res.score})}return scored.sort((a,b)=>a.score!==b.score?a.score-b.score:b.session.modified.getTime()-a.session.modified.getTime()),scored.map(r=>r.session)}function createCanonicalPathResolver(){let cache=new Map;return path2=>{if(!path2)return path2;let canonical=cache.get(path2);return canonical===void 0&&(canonical=canonicalizePath(path2),cache.set(path2,canonical)),canonical}}function buildSessionTree(sessions,canonicalize){let byPath=new Map;for(let session of sessions){let sessionPath=canonicalize(session.path)??session.path;byPath.set(sessionPath,{session,children:[],latestActivity:session.modified.getTime()})}let roots=[];for(let session of sessions){let sessionPath=canonicalize(session.path)??session.path,node=byPath.get(sessionPath),parentPath=canonicalize(session.parentSessionPath);parentPath&&byPath.has(parentPath)?byPath.get(parentPath).children.push(node):roots.push(node)}let updateLatestActivity=node=>{let latestActivity=node.session.modified.getTime();for(let child of node.children)latestActivity=Math.max(latestActivity,updateLatestActivity(child));return node.latestActivity=latestActivity,latestActivity};for(let root of roots)updateLatestActivity(root);let sortNodes=nodes=>{nodes.sort((a,b)=>b.latestActivity-a.latestActivity);for(let node of nodes)sortNodes(node.children)};return sortNodes(roots),roots}function flattenSessionTree(roots){let result=[],walk=(node,depth,ancestorContinues,isLast)=>{result.push({session:node.session,depth,isLast,ancestorContinues});for(let i=0;i<node.children.length;i++){let childIsLast=i===node.children.length-1,continues=depth>0?!isLast:!1;walk(node.children[i],depth+1,[...ancestorContinues,continues],childIsLast)}};for(let i=0;i<roots.length;i++)walk(roots[i],0,[],i===roots.length-1);return result}function shortenPath(path2){let home=os.homedir();return path2&&(path2.startsWith(home)?`~${path2.slice(home.length)}`:path2)}function formatSessionDate(date){let diffMs=new Date().getTime()-date.getTime(),diffMins=Math.floor(diffMs/6e4),diffHours=Math.floor(diffMs/36e5),diffDays=Math.floor(diffMs/864e5);return diffMins<1?"now":diffMins<60?`${diffMins}m`:diffHours<24?`${diffHours}h`:diffDays<7?`${diffDays}d`:diffDays<30?`${Math.floor(diffDays/7)}w`:diffDays<365?`${Math.floor(diffDays/30)}mo`:`${Math.floor(diffDays/365)}y`}var SessionSelectorHeader=class{constructor(scope,sortMode,nameFilter,requestRender){this.loading=!1,this.loadProgress=null,this.showPath=!1,this.confirmingDeletePath=null,this.statusMessage=null,this.statusTimeout=null,this.showRenameHint=!1,this.scope=scope,this.sortMode=sortMode,this.nameFilter=nameFilter,this.requestRender=requestRender}setScope(scope){this.scope=scope}setSortMode(sortMode){this.sortMode=sortMode}setNameFilter(nameFilter){this.nameFilter=nameFilter}setLoading(loading){this.loading=loading,this.loadProgress=null}setProgress(loaded,total){this.loadProgress={loaded,total}}setShowPath(showPath){this.showPath=showPath}setShowRenameHint(show){this.showRenameHint=show}setConfirmingDeletePath(path2){this.confirmingDeletePath=path2}clearStatusTimeout(){this.statusTimeout&&(clearTimeout(this.statusTimeout),this.statusTimeout=null)}setStatusMessage(msg,autoHideMs){this.clearStatusTimeout(),this.statusMessage=msg,!(!msg||!autoHideMs)&&(this.statusTimeout=setTimeout(()=>{this.statusMessage=null,this.statusTimeout=null,this.requestRender()},autoHideMs))}invalidate(){}render(width){let title=this.scope==="current"?"Resume Session (Current Folder)":"Resume Session (All)",leftText=theme.bold(title),sortLabel=this.sortMode==="threaded"?"Threaded":this.sortMode==="recent"?"Recent":"Fuzzy",sortText=theme.fg("muted","Sort: ")+theme.fg("accent",sortLabel),nameLabel=this.nameFilter==="all"?"All":"Named",nameText=theme.fg("muted","Name: ")+theme.fg("accent",nameLabel),scopeText;if(this.loading){let progressText=this.loadProgress?`${this.loadProgress.loaded}/${this.loadProgress.total}`:"...";scopeText=`${theme.fg("muted","\u25CB Current Folder | ")}${theme.fg("accent",`Loading ${progressText}`)}`}else this.scope==="current"?scopeText=`${theme.fg("accent","\u25C9 Current Folder")}${theme.fg("muted"," | \u25CB All")}`:scopeText=`${theme.fg("muted","\u25CB Current Folder | ")}${theme.fg("accent","\u25C9 All")}`;let rightText=truncateToWidth(`${scopeText} ${nameText} ${sortText}`,width,""),availableLeft=Math.max(0,width-visibleWidth(rightText)-1),left=truncateToWidth(leftText,availableLeft,""),spacing=Math.max(0,width-visibleWidth(left)-visibleWidth(rightText)),hintLine1,hintLine2;if(this.confirmingDeletePath!==null){let confirmHint=`Delete session? ${keyHint("tui.select.confirm","confirm")} \xB7 ${keyHint("tui.select.cancel","cancel")}`;hintLine1=theme.fg("error",truncateToWidth(confirmHint,width,"\u2026")),hintLine2=""}else if(this.statusMessage){let color=this.statusMessage.type==="error"?"error":"accent";hintLine1=theme.fg(color,truncateToWidth(this.statusMessage.message,width,"\u2026")),hintLine2=""}else{let pathState=this.showPath?"(on)":"(off)",sep5=theme.fg("muted"," \xB7 "),hint1=keyHint("tui.input.tab","scope")+sep5+theme.fg("muted",'re:<pattern> regex \xB7 "phrase" exact'),hint2Parts=[keyHint("app.session.toggleSort","sort"),keyHint("app.session.toggleNamedFilter","named"),keyHint("app.session.delete","delete"),keyHint("app.session.togglePath",`path ${pathState}`)];this.showRenameHint&&hint2Parts.push(keyHint("app.session.rename","rename"));let hint2=hint2Parts.join(sep5);hintLine1=truncateToWidth(hint1,width,"\u2026"),hintLine2=truncateToWidth(hint2,width,"\u2026")}return[`${left}${" ".repeat(spacing)}${rightText}`,hintLine1,hintLine2]}},SessionList=class{getSelectedSessionPath(){return this.filteredSessions[this.selectedIndex]?.session.path}get focused(){return this._focused}set focused(value){this._focused=value,this.searchInput.focused=value}constructor(sessions,showCwd,sortMode,nameFilter,keybindings,currentSessionFilePath){this.allSessions=[],this.filteredSessions=[],this.selectedIndex=0,this.selectionTouched=!1,this.showCwd=!1,this.sortMode="threaded",this.nameFilter="all",this.showPath=!1,this.confirmingDeletePath=null,this.canonicalPath=createCanonicalPathResolver(),this.onExit=()=>{},this.maxVisible=10,this._focused=!1,this.allSessions=sessions,this.filteredSessions=[],this.searchInput=new Input,this.showCwd=showCwd,this.sortMode=sortMode,this.nameFilter=nameFilter,this.keybindings=keybindings,this.currentSessionCanonicalPath=this.canonicalPath(currentSessionFilePath),this.filterSessions(""),this.searchInput.onSubmit=()=>{if(this.filteredSessions[this.selectedIndex]){let selected=this.filteredSessions[this.selectedIndex];this.onSelect&&this.onSelect(selected.session.path)}}}setSortMode(sortMode){this.sortMode=sortMode,this.filterSessions(this.searchInput.getValue())}setNameFilter(nameFilter){this.nameFilter=nameFilter,this.filterSessions(this.searchInput.getValue())}setSessions(sessions,showCwd){let selectedPath=this.selectionTouched?this.getSelectedSessionPath():void 0;if(this.allSessions=sessions,this.canonicalPath=createCanonicalPathResolver(),this.showCwd=showCwd,this.filterSessions(this.searchInput.getValue()),!this.selectionTouched)this.selectedIndex=0;else if(selectedPath){let selectedIndex=this.filteredSessions.findIndex(node=>node.session.path===selectedPath);selectedIndex>=0&&(this.selectedIndex=selectedIndex)}}filterSessions(query){let trimmed=query.trim(),nameFiltered=this.nameFilter==="all"?this.allSessions:this.allSessions.filter(session=>hasSessionName(session));if(this.sortMode==="threaded"&&!trimmed){let roots=buildSessionTree(nameFiltered,this.canonicalPath);this.filteredSessions=flattenSessionTree(roots)}else{let filtered=filterAndSortSessions(nameFiltered,query,this.sortMode,"all");this.filteredSessions=filtered.map(session=>({session,depth:0,isLast:!0,ancestorContinues:[]}))}this.selectedIndex=Math.min(this.selectedIndex,Math.max(0,this.filteredSessions.length-1))}setConfirmingDeletePath(path2){this.confirmingDeletePath=path2,this.onDeleteConfirmationChange?.(path2)}startDeleteConfirmationForSelectedSession(){let selected=this.filteredSessions[this.selectedIndex];if(selected){if(this.isCurrentSessionPath(selected.session.path)){this.onError?.("Cannot delete the currently active session");return}this.setConfirmingDeletePath(selected.session.path)}}isCurrentSessionPath(path2){return this.currentSessionCanonicalPath?(this.canonicalPath(path2)??path2)===this.currentSessionCanonicalPath:!1}invalidate(){}render(width){let lines=[];if(lines.push(...this.searchInput.render(width)),lines.push(""),this.filteredSessions.length===0){let emptyMessage;if(this.nameFilter==="named"){let toggleKey=keyText("app.session.toggleNamedFilter");this.showCwd?emptyMessage=` No named sessions found. Press ${toggleKey} to show all.`:emptyMessage=` No named sessions in current folder. Press ${toggleKey} to show all, or Tab to view all.`}else this.showCwd?emptyMessage=" No sessions found":emptyMessage=" No sessions in current folder. Press Tab to view all.";return lines.push(theme.fg("muted",truncateToWidth(emptyMessage,width,"\u2026"))),lines}let startIndex=Math.max(0,Math.min(this.selectedIndex-Math.floor(this.maxVisible/2),this.filteredSessions.length-this.maxVisible)),endIndex=Math.min(startIndex+this.maxVisible,this.filteredSessions.length);for(let i=startIndex;i<endIndex;i++){let node=this.filteredSessions[i],session=node.session,isSelected=i===this.selectedIndex,isConfirmingDelete=session.path===this.confirmingDeletePath,isCurrent=this.isCurrentSessionPath(session.path),prefix=this.buildTreePrefix(node),hasName=!!session.name,normalizedMessage=(session.name??session.firstMessage).replace(/[\x00-\x1f\x7f]/g," ").trim(),age=formatSessionDate(session.modified),rightPart=`${String(session.messageCount)} ${age}`;(this.showCwd||session.moved)&&session.cwd&&(rightPart=`${shortenPath(session.cwd)} ${rightPart}`);let movedBadge=session.moved?"moved from ":"";this.showPath&&(rightPart=`${shortenPath(session.path)} ${rightPart}`);let cursor=isSelected?theme.fg("accent","\u203A "):" ",prefixWidth=visibleWidth(prefix),rightWidth=visibleWidth(rightPart)+2,availableForMsg=width-2-prefixWidth-rightWidth,truncatedMsg=truncateToWidth(normalizedMessage,Math.max(10,availableForMsg),"\u2026"),messageColor=null;isConfirmingDelete?messageColor="error":isCurrent?messageColor="accent":hasName&&(messageColor="warning");let styledMsg=messageColor?theme.fg(messageColor,truncatedMsg):truncatedMsg;isSelected&&(styledMsg=theme.bold(styledMsg));let leftPart=cursor+theme.fg("dim",prefix)+styledMsg,leftWidth=visibleWidth(leftPart),spacing=Math.max(1,width-leftWidth-visibleWidth(movedBadge+rightPart)),styledRight=(movedBadge?theme.fg("warning",movedBadge):"")+theme.fg(isConfirmingDelete?"error":"dim",rightPart),line=leftPart+" ".repeat(spacing)+styledRight;isSelected&&(line=theme.bg("selectedBg",line)),lines.push(truncateToWidth(line,width))}if(startIndex>0||endIndex<this.filteredSessions.length){let scrollText=` (${this.selectedIndex+1}/${this.filteredSessions.length})`,scrollInfo=theme.fg("muted",truncateToWidth(scrollText,width,""));lines.push(scrollInfo)}return lines}buildTreePrefix(node){if(node.depth===0)return"";let parts=node.ancestorContinues.map(continues=>continues?"\u2502 ":" "),branch=node.isLast?"\u2514\u2500 ":"\u251C\u2500 ";return parts.join("")+branch}handleInput(keyData){let kb=getKeybindings();if(this.confirmingDeletePath!==null){if(kb.matches(keyData,"tui.select.confirm")){let pathToDelete=this.confirmingDeletePath;this.setConfirmingDeletePath(null),this.onDeleteSession?.(pathToDelete);return}if(kb.matches(keyData,"tui.select.cancel")){this.setConfirmingDeletePath(null);return}return}if(kb.matches(keyData,"tui.input.tab")){this.onToggleScope&&this.onToggleScope();return}if(kb.matches(keyData,"app.session.toggleSort")){this.onToggleSort?.();return}if(this.keybindings.matches(keyData,"app.session.toggleNamedFilter")){this.onToggleNameFilter?.();return}if(kb.matches(keyData,"app.session.togglePath")){this.showPath=!this.showPath,this.onTogglePath?.(this.showPath);return}if(kb.matches(keyData,"app.session.delete")){this.startDeleteConfirmationForSelectedSession();return}if(kb.matches(keyData,"app.session.rename")){let selected=this.filteredSessions[this.selectedIndex];selected&&this.onRenameSession?.(selected.session.path);return}if(kb.matches(keyData,"app.session.deleteNoninvasive")){if(this.searchInput.getValue().length>0){this.searchInput.handleInput(keyData),this.filterSessions(this.searchInput.getValue());return}this.startDeleteConfirmationForSelectedSession();return}if(this.selectionTouched=!0,kb.matches(keyData,"tui.select.up"))this.selectedIndex=Math.max(0,this.selectedIndex-1);else if(kb.matches(keyData,"tui.select.down"))this.selectedIndex=Math.min(this.filteredSessions.length-1,this.selectedIndex+1);else if(kb.matches(keyData,"tui.select.pageUp"))this.selectedIndex=Math.max(0,this.selectedIndex-this.maxVisible);else if(kb.matches(keyData,"tui.select.pageDown"))this.selectedIndex=Math.min(this.filteredSessions.length-1,this.selectedIndex+this.maxVisible);else if(kb.matches(keyData,"tui.select.confirm")){let selected=this.filteredSessions[this.selectedIndex];selected&&this.onSelect&&this.onSelect(selected.session.path)}else kb.matches(keyData,"tui.select.cancel")?this.onCancel&&this.onCancel():(this.searchInput.handleInput(keyData),this.filterSessions(this.searchInput.getValue()))}};function withMediaOutcome(result,mediaError){return mediaError===void 0?result:{...result,mediaError}}async function deleteSessionFile(sessionPath){let mediaScope=await toolMediaScopeOfSessionFile(sessionPath),removeMedia=()=>{if(mediaScope!==void 0)try{removeToolMedia(mediaScope);return}catch(cause){let reason=cause instanceof Error?cause.message:String(cause);return`${toolMediaRoot(mediaScope)}: ${reason}`}},trashArgs=sessionPath.startsWith("-")?["--",sessionPath]:[sessionPath],trashResult=spawnSync("trash",trashArgs,{encoding:"utf-8"}),getTrashErrorHint=()=>{let parts=[];trashResult.error&&parts.push(trashResult.error.message);let stderr=trashResult.stderr?.trim();return stderr&&parts.push(stderr.split(`
|
|
178
|
-
`)[0]??stderr),parts.length===0?null:`trash: ${parts.join(" \xB7 ").slice(0,200)}`};if(trashResult.status===0||!existsSync7(sessionPath))return withMediaOutcome({ok:!0,method:"trash"},removeMedia());try{return await unlink(sessionPath),withMediaOutcome({ok:!0,method:"unlink"},removeMedia())}catch(err){let unlinkError=err instanceof Error?err.message:String(err),trashErrorHint=getTrashErrorHint();return{ok:!1,method:"unlink",error:trashErrorHint?`${unlinkError} (${trashErrorHint})`:unlinkError}}}var SessionSelectorComponent=class extends Container{handleInput(data){if(this.mode==="rename"){if(getKeybindings().matches(data,"tui.select.cancel")){this.exitRenameMode();return}this.renameInput.handleInput(data);return}this.sessionList.handleInput(data)}get focused(){return this._focused}set focused(value){this._focused=value,this.sessionList.focused=value,this.renameInput.focused=value,value&&this.mode==="rename"&&(this.renameInput.focused=!0)}buildBaseLayout(content,options){this.clear(),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder(s=>theme.fg("accent",s))),this.addChild(new Spacer(1)),(options?.showHeader??!0)&&(this.addChild(this.header),this.addChild(new Spacer(1))),this.addChild(content),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder(s=>theme.fg("accent",s)))}constructor(currentSessionsLoader,allSessionsLoader,onSelect,onCancel,onExit,requestRender,options,currentSessionFilePath){super(),this.canRename=!0,this.scope="current",this.sortMode="threaded",this.nameFilter="all",this.currentSessions=null,this.allSessions=null,this.currentLoad=null,this.allLoad=null,this.mode="list",this.renameInput=new Input,this.renameTargetPath=null,this._focused=!1,this.keybindings=options?.keybindings??KeybindingsManager.create(),this.currentSessionsLoader=currentSessionsLoader,this.allSessionsLoader=allSessionsLoader,this.requestRender=requestRender,this.header=new SessionSelectorHeader(this.scope,this.sortMode,this.nameFilter,this.requestRender);let renameSession=options?.renameSession;this.renameSession=renameSession,this.canRename=!!renameSession,this.header.setShowRenameHint(options?.showRenameHint??this.canRename),this.sessionList=new SessionList([],!1,this.sortMode,this.nameFilter,this.keybindings,currentSessionFilePath),this.buildBaseLayout(this.sessionList),this.renameInput.onSubmit=value=>{this.confirmRename(value)};let clearStatusMessage=()=>this.header.setStatusMessage(null);this.sessionList.onSelect=sessionPath=>{clearStatusMessage(),this.cancelLoads(),onSelect(sessionPath)},this.sessionList.onCancel=()=>{clearStatusMessage(),this.cancelLoads(),onCancel()},this.sessionList.onExit=()=>{clearStatusMessage(),this.cancelLoads(),onExit()},this.sessionList.onToggleScope=()=>this.toggleScope(),this.sessionList.onToggleSort=()=>this.toggleSortMode(),this.sessionList.onToggleNameFilter=()=>this.toggleNameFilter(),this.sessionList.onRenameSession=sessionPath=>{if(!renameSession||(this.scope==="current"?this.currentLoad:this.allLoad))return;let session=(this.scope==="all"?this.allSessions??[]:this.currentSessions??[]).find(s=>s.path===sessionPath);this.enterRenameMode(sessionPath,session?.name)},this.sessionList.onTogglePath=showPath=>{this.header.setShowPath(showPath),this.requestRender()},this.sessionList.onDeleteConfirmationChange=path2=>{this.header.setConfirmingDeletePath(path2),this.requestRender()},this.sessionList.onError=msg=>{this.header.setStatusMessage({type:"error",message:msg},3e3),this.requestRender()},this.sessionList.onDeleteSession=async sessionPath=>{let result=await deleteSessionFile(sessionPath);if(result.ok){this.currentSessions&&(this.currentSessions=this.currentSessions.filter(s=>s.path!==sessionPath)),this.allSessions&&(this.allSessions=this.allSessions.filter(s=>s.path!==sessionPath));let sessions=this.scope==="all"?this.allSessions??[]:this.currentSessions??[],showCwd=this.scope==="all";this.sessionList.setSessions(sessions,showCwd);let msg=result.method==="trash"?"Session moved to trash":"Session deleted";result.mediaError?this.header.setStatusMessage({type:"error",message:`${msg}, but its images were not removed: ${result.mediaError}`},8e3):this.header.setStatusMessage({type:"info",message:msg},2e3),await this.refreshSessionsAfterMutation()}else{let errorMessage=result.error??"Unknown error";this.header.setStatusMessage({type:"error",message:`Failed to delete: ${errorMessage}`},3e3)}this.requestRender()},this.loadScope("current")}cancelLoads(){this.currentLoad&&(this.currentLoad.abort(),this.currentLoad=null,this.currentSessions=null),this.allLoad&&(this.allLoad.abort(),this.allLoad=null,this.allSessions=null)}enterRenameMode(sessionPath,currentName){this.mode="rename",this.renameTargetPath=sessionPath,this.renameInput.setValue(currentName??""),this.renameInput.focused=!0;let panel=new Container;panel.addChild(new Text(theme.bold("Rename Session"),1,0)),panel.addChild(new Spacer(1)),panel.addChild(this.renameInput),panel.addChild(new Spacer(1)),panel.addChild(new Text(theme.fg("muted",`${keyText("tui.select.confirm")} to save \xB7 ${keyText("tui.select.cancel")} to cancel`),1,0)),this.buildBaseLayout(panel,{showHeader:!1}),this.requestRender()}exitRenameMode(){this.mode="list",this.renameTargetPath=null,this.buildBaseLayout(this.sessionList),this.requestRender()}async confirmRename(value){let next=value.trim();if(!next)return;let target=this.renameTargetPath;if(!target){this.exitRenameMode();return}let renameSession=this.renameSession;if(!renameSession){this.exitRenameMode();return}try{await renameSession(target,next),await this.refreshSessionsAfterMutation()}finally{this.exitRenameMode()}}async loadScope(scope){if(scope==="current"?this.currentLoad:this.allLoad)return;let showCwd=scope==="all",controller=new AbortController;scope==="current"?this.currentLoad=controller:this.allLoad=controller,this.header.setScope(scope),this.header.setLoading(!0),this.requestRender();let isActive=()=>(scope==="current"?this.currentLoad:this.allLoad)===controller,onProgress=(loaded,total,partialSessions)=>{if(isActive()){if(partialSessions){let sessions=[...partialSessions];scope==="current"?this.currentSessions=sessions:this.allSessions=sessions,scope===this.scope&&this.sessionList.setSessions(sessions,showCwd)}scope===this.scope&&(this.header.setProgress(loaded,total),this.requestRender())}};try{let sessions=await(scope==="current"?this.currentSessionsLoader(onProgress,controller.signal):this.allSessionsLoader(onProgress,controller.signal));if(!isActive()||(scope==="current"?(this.currentSessions=sessions,this.currentLoad=null):(this.allSessions=sessions,this.allLoad=null),scope!==this.scope))return;this.header.setLoading(!1),this.sessionList.setSessions(sessions,showCwd),this.requestRender()}catch(err){if(!isActive()||(scope==="current"?(this.currentLoad=null,this.currentSessions=null):(this.allLoad=null,this.allSessions=null),scope!==this.scope))return;let message=err instanceof Error?err.message:String(err);this.header.setLoading(!1),this.header.setStatusMessage({type:"error",message:`Failed to load sessions: ${message}`},4e3),this.sessionList.setSessions([],showCwd),this.requestRender()}}toggleSortMode(){this.sortMode=this.sortMode==="threaded"?"recent":this.sortMode==="recent"?"relevance":"threaded",this.header.setSortMode(this.sortMode),this.sessionList.setSortMode(this.sortMode),this.requestRender()}toggleNameFilter(){this.nameFilter=this.nameFilter==="all"?"named":"all",this.header.setNameFilter(this.nameFilter),this.sessionList.setNameFilter(this.nameFilter),this.requestRender()}async refreshSessionsAfterMutation(){this.cancelLoads(),this.currentSessions=null,this.allSessions=null,await this.loadScope(this.scope)}toggleScope(){this.scope=this.scope==="current"?"all":"current";let sessions=this.scope==="current"?this.currentSessions:this.allSessions,loading=(this.scope==="current"?this.currentLoad:this.allLoad)!==null;this.header.setScope(this.scope),this.header.setLoading(loading),this.sessionList.setSessions(sessions??[],this.scope==="all"),this.requestRender(),sessions===null&&!loading&&this.loadScope(this.scope)}getSessionList(){return this.sessionList}};export{DynamicBorder,formatKeyText,keyText,keyDisplayText,keyHint,rawKeyHint,areExperimentalFeaturesEnabled,minimatch,parseGitUrl,takeOverStdout,restoreStdout,observeVisibleStderrWrites,takeOverStderr,restoreStderr,writeRawStdout,waitForRawStdoutBackpressure,flushRawStdout,readPiManifest,shouldSkipSkillWalkDirectoryName,readSkillMarkdownSource,skillProjectRoot,insideSkillRoot,buildSkillAllowedSet,BlockedSkillLinkError,authorizeSkillPath,readSkillFileCheckedSync,readSkillFileChecked,DefaultPackageManager,CONTINUE_FROM_LEAF_CUSTOM_TYPE,CONTINUE_FROM_LEAF_DIRECTIVE,ContinueFromLeafError,trackTurnAdmission,MANUAL_CONTINUE_CUSTOM_TYPE,isManualContinueSubmission,MANUAL_CONTINUE_DIRECTIVE,STOP_RESUME_CUSTOM_TYPE,stopResumeDirective,ENGINE_TURN_START_ENTRY_TYPE,ENGINE_TURN_LIMIT_ENTRY_TYPE,ENGINE_TURN_LIMIT_EVENT,engineTurnLimitNotice,isUserDirectedTurn,engineTurnHistory,engineTurnStop,require_undici,HTTP_IDLE_TIMEOUT_CHOICES,formatHttpIdleTimeoutMs,applyHttpProxySettings,configureHttpDispatcher,isBillingErrorMessage,isHealthExhaustionFailure,CircuitProbes,AccountUsageLimitError,usageLimitScope,describeUsageLimitMessage,describeUsageLimitEntry,usageLimitCause,createFallbackCircuitAccess,acquireFallbackCircuits,monotonicNow,FABLE55_LAUNCH,isFable55ModelId,parseSettingsJson,formatSkillInvocationPrompt,parseSkillBlock,parseSkillInvocationTokens,removeSkillInvocationTokens,TERMINAL_MOUSE_MODES,isTerminalMouseMode,DEFAULT_STREAM_START_TIMEOUT_MS,DEFAULT_SESSION_SHUTDOWN_HANDLER_WARN_MS,DEFAULT_SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS,DEFAULT_SESSION_SHUTDOWN_QUIT_BUDGET_MS,DEFAULT_EXTENSION_EVENT_HANDLER_WARN_MS,DEFAULT_EXTENSION_EVENT_HANDLER_TIMEOUT_MS,DEFAULT_TOOL_NAMES,wasSelfWrite,getSettingsPath2 as getSettingsPath,FileSettingsStorage,SettingsManager,CountdownTimer,ExtensionInputComponent,ExtensionSelectorComponent,InteractiveThemeController,createStartupTui,startStartupTui,shouldRunFirstTimeSetup,showStartupSelector,showFirstTimeSetup,showStartupInput,liveToolMediaScope,toolMediaPersister,SessionSelectorComponent};
|
|
178
|
+
`)[0]??stderr),parts.length===0?null:`trash: ${parts.join(" \xB7 ").slice(0,200)}`};if(trashResult.status===0||!existsSync7(sessionPath))return withMediaOutcome({ok:!0,method:"trash"},removeMedia());try{return await unlink(sessionPath),withMediaOutcome({ok:!0,method:"unlink"},removeMedia())}catch(err){let unlinkError=err instanceof Error?err.message:String(err),trashErrorHint=getTrashErrorHint();return{ok:!1,method:"unlink",error:trashErrorHint?`${unlinkError} (${trashErrorHint})`:unlinkError}}}var SessionSelectorComponent=class extends Container{handleInput(data){if(this.mode==="rename"){if(getKeybindings().matches(data,"tui.select.cancel")){this.exitRenameMode();return}this.renameInput.handleInput(data);return}this.sessionList.handleInput(data)}get focused(){return this._focused}set focused(value){this._focused=value,this.sessionList.focused=value,this.renameInput.focused=value,value&&this.mode==="rename"&&(this.renameInput.focused=!0)}buildBaseLayout(content,options){this.clear(),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder(s=>theme.fg("accent",s))),this.addChild(new Spacer(1)),(options?.showHeader??!0)&&(this.addChild(this.header),this.addChild(new Spacer(1))),this.addChild(content),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder(s=>theme.fg("accent",s)))}constructor(currentSessionsLoader,allSessionsLoader,onSelect,onCancel,onExit,requestRender,options,currentSessionFilePath){super(),this.canRename=!0,this.scope="current",this.sortMode="threaded",this.nameFilter="all",this.currentSessions=null,this.allSessions=null,this.currentLoad=null,this.allLoad=null,this.mode="list",this.renameInput=new Input,this.renameTargetPath=null,this._focused=!1,this.keybindings=options?.keybindings??KeybindingsManager.create(),this.currentSessionsLoader=currentSessionsLoader,this.allSessionsLoader=allSessionsLoader,this.requestRender=requestRender,this.header=new SessionSelectorHeader(this.scope,this.sortMode,this.nameFilter,this.requestRender);let renameSession=options?.renameSession;this.renameSession=renameSession,this.canRename=!!renameSession,this.header.setShowRenameHint(options?.showRenameHint??this.canRename),this.sessionList=new SessionList([],!1,this.sortMode,this.nameFilter,this.keybindings,currentSessionFilePath),this.buildBaseLayout(this.sessionList),this.renameInput.onSubmit=value=>{this.confirmRename(value)};let clearStatusMessage=()=>this.header.setStatusMessage(null);this.sessionList.onSelect=sessionPath=>{clearStatusMessage(),this.cancelLoads(),onSelect(sessionPath)},this.sessionList.onCancel=()=>{clearStatusMessage(),this.cancelLoads(),onCancel()},this.sessionList.onExit=()=>{clearStatusMessage(),this.cancelLoads(),onExit()},this.sessionList.onToggleScope=()=>this.toggleScope(),this.sessionList.onToggleSort=()=>this.toggleSortMode(),this.sessionList.onToggleNameFilter=()=>this.toggleNameFilter(),this.sessionList.onRenameSession=sessionPath=>{if(!renameSession||(this.scope==="current"?this.currentLoad:this.allLoad))return;let session=(this.scope==="all"?this.allSessions??[]:this.currentSessions??[]).find(s=>s.path===sessionPath);this.enterRenameMode(sessionPath,session?.name)},this.sessionList.onTogglePath=showPath=>{this.header.setShowPath(showPath),this.requestRender()},this.sessionList.onDeleteConfirmationChange=path2=>{this.header.setConfirmingDeletePath(path2),this.requestRender()},this.sessionList.onError=msg=>{this.header.setStatusMessage({type:"error",message:msg},3e3),this.requestRender()},this.sessionList.onDeleteSession=async sessionPath=>{let result=await deleteSessionFile(sessionPath);if(result.ok){this.currentSessions&&(this.currentSessions=this.currentSessions.filter(s=>s.path!==sessionPath)),this.allSessions&&(this.allSessions=this.allSessions.filter(s=>s.path!==sessionPath));let sessions=this.scope==="all"?this.allSessions??[]:this.currentSessions??[],showCwd=this.scope==="all";this.sessionList.setSessions(sessions,showCwd);let msg=result.method==="trash"?"Session moved to trash":"Session deleted";result.mediaError?this.header.setStatusMessage({type:"error",message:`${msg}, but its images were not removed: ${result.mediaError}`},8e3):this.header.setStatusMessage({type:"info",message:msg},2e3),await this.refreshSessionsAfterMutation()}else{let errorMessage=result.error??"Unknown error";this.header.setStatusMessage({type:"error",message:`Failed to delete: ${errorMessage}`},3e3)}this.requestRender()},this.loadScope("current")}cancelLoads(){this.currentLoad&&(this.currentLoad.abort(),this.currentLoad=null,this.currentSessions=null),this.allLoad&&(this.allLoad.abort(),this.allLoad=null,this.allSessions=null)}enterRenameMode(sessionPath,currentName){this.mode="rename",this.renameTargetPath=sessionPath,this.renameInput.setValue(currentName??""),this.renameInput.focused=!0;let panel=new Container;panel.addChild(new Text(theme.bold("Rename Session"),1,0)),panel.addChild(new Spacer(1)),panel.addChild(this.renameInput),panel.addChild(new Spacer(1)),panel.addChild(new Text(theme.fg("muted",`${keyText("tui.select.confirm")} to save \xB7 ${keyText("tui.select.cancel")} to cancel`),1,0)),this.buildBaseLayout(panel,{showHeader:!1}),this.requestRender()}exitRenameMode(){this.mode="list",this.renameTargetPath=null,this.buildBaseLayout(this.sessionList),this.requestRender()}async confirmRename(value){let next=value.trim();if(!next)return;let target=this.renameTargetPath;if(!target){this.exitRenameMode();return}let renameSession=this.renameSession;if(!renameSession){this.exitRenameMode();return}try{await renameSession(target,next),await this.refreshSessionsAfterMutation()}finally{this.exitRenameMode()}}async loadScope(scope){if(scope==="current"?this.currentLoad:this.allLoad)return;let showCwd=scope==="all",controller=new AbortController;scope==="current"?this.currentLoad=controller:this.allLoad=controller,this.header.setScope(scope),this.header.setLoading(!0),this.requestRender();let isActive=()=>(scope==="current"?this.currentLoad:this.allLoad)===controller,onProgress=(loaded,total,partialSessions)=>{if(isActive()){if(partialSessions){let sessions=[...partialSessions];scope==="current"?this.currentSessions=sessions:this.allSessions=sessions,scope===this.scope&&this.sessionList.setSessions(sessions,showCwd)}scope===this.scope&&(this.header.setProgress(loaded,total),this.requestRender())}};try{let sessions=await(scope==="current"?this.currentSessionsLoader(onProgress,controller.signal):this.allSessionsLoader(onProgress,controller.signal));if(!isActive()||(scope==="current"?(this.currentSessions=sessions,this.currentLoad=null):(this.allSessions=sessions,this.allLoad=null),scope!==this.scope))return;this.header.setLoading(!1),this.sessionList.setSessions(sessions,showCwd),this.requestRender()}catch(err){if(!isActive()||(scope==="current"?(this.currentLoad=null,this.currentSessions=null):(this.allLoad=null,this.allSessions=null),scope!==this.scope))return;let message=err instanceof Error?err.message:String(err);this.header.setLoading(!1),this.header.setStatusMessage({type:"error",message:`Failed to load sessions: ${message}`},4e3),this.sessionList.setSessions([],showCwd),this.requestRender()}}toggleSortMode(){this.sortMode=this.sortMode==="threaded"?"recent":this.sortMode==="recent"?"relevance":"threaded",this.header.setSortMode(this.sortMode),this.sessionList.setSortMode(this.sortMode),this.requestRender()}toggleNameFilter(){this.nameFilter=this.nameFilter==="all"?"named":"all",this.header.setNameFilter(this.nameFilter),this.sessionList.setNameFilter(this.nameFilter),this.requestRender()}async refreshSessionsAfterMutation(){this.cancelLoads(),this.currentSessions=null,this.allSessions=null,await this.loadScope(this.scope)}toggleScope(){this.scope=this.scope==="current"?"all":"current";let sessions=this.scope==="current"?this.currentSessions:this.allSessions,loading=(this.scope==="current"?this.currentLoad:this.allLoad)!==null;this.header.setScope(this.scope),this.header.setLoading(loading),this.sessionList.setSessions(sessions??[],this.scope==="all"),this.requestRender(),sessions===null&&!loading&&this.loadScope(this.scope)}getSessionList(){return this.sessionList}};export{DynamicBorder,formatKeyText,keyText,keyDisplayText,keyHint,rawKeyHint,areExperimentalFeaturesEnabled,minimatch,parseGitUrl,takeOverStdout,restoreStdout,observeVisibleStderrWrites,takeOverStderr,restoreStderr,writeRawStdout,waitForRawStdoutBackpressure,flushRawStdout,readPiManifest,shouldSkipSkillWalkDirectoryName,readSkillMarkdownSource,skillProjectRoot,insideSkillRoot,buildSkillAllowedSet,BlockedSkillLinkError,authorizeSkillPath,readSkillFileCheckedSync,readSkillFileChecked,DefaultPackageManager,CONTINUE_FROM_LEAF_CUSTOM_TYPE,CONTINUE_FROM_LEAF_DIRECTIVE,ContinueFromLeafError,trackTurnAdmission,MANUAL_CONTINUE_CUSTOM_TYPE,isManualContinueSubmission,MANUAL_CONTINUE_DIRECTIVE,stopResumeDirective,ENGINE_TURN_START_ENTRY_TYPE,ENGINE_TURN_LIMIT_ENTRY_TYPE,ENGINE_TURN_LIMIT_EVENT,engineTurnLimitNotice,isUserDirectedTurn,resetsEngineTurnHistory,engineTurnHistory,engineTurnStop,require_undici,HTTP_IDLE_TIMEOUT_CHOICES,formatHttpIdleTimeoutMs,applyHttpProxySettings,configureHttpDispatcher,isBillingErrorMessage,isHealthExhaustionFailure,CircuitProbes,AccountUsageLimitError,usageLimitScope,describeUsageLimitMessage,describeUsageLimitEntry,usageLimitCause,createFallbackCircuitAccess,acquireFallbackCircuits,monotonicNow,FABLE55_LAUNCH,isFable55ModelId,parseSettingsJson,formatSkillInvocationPrompt,parseSkillBlock,parseSkillInvocationTokens,removeSkillInvocationTokens,TERMINAL_MOUSE_MODES,isTerminalMouseMode,DEFAULT_STREAM_START_TIMEOUT_MS,DEFAULT_SESSION_SHUTDOWN_HANDLER_WARN_MS,DEFAULT_SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS,DEFAULT_SESSION_SHUTDOWN_QUIT_BUDGET_MS,DEFAULT_EXTENSION_EVENT_HANDLER_WARN_MS,DEFAULT_EXTENSION_EVENT_HANDLER_TIMEOUT_MS,DEFAULT_TOOL_NAMES,wasSelfWrite,getSettingsPath2 as getSettingsPath,FileSettingsStorage,SettingsManager,CountdownTimer,ExtensionInputComponent,ExtensionSelectorComponent,InteractiveThemeController,createStartupTui,startStartupTui,shouldRunFirstTimeSetup,showStartupSelector,showFirstTimeSetup,showStartupInput,liveToolMediaScope,toolMediaPersister,SessionSelectorComponent};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
-
import{getAgentDir}from"./chunk-7YO7VQZW.js";import{processStartTimeMs,readProcessIdentity,sameProcessStartMs}from"./chunk-
|
|
2
|
+
import{getAgentDir}from"./chunk-7YO7VQZW.js";import{processStartTimeMs,readProcessIdentity,sameProcessStartMs}from"./chunk-O5RYI3IW.js";import{existsSync,realpathSync}from"node:fs";import{basename,dirname,join,resolve}from"node:path";function canonicalSessionPath(path){let absolutePath=resolve(path),missing=[],existing=absolutePath;for(;!existsSync(existing);){let parent=dirname(existing);if(parent===existing)return absolutePath;missing.unshift(basename(existing)),existing=parent}try{return join(realpathSync(existing),...missing)}catch{return absolutePath}}function sessionDirectoryRemoved(sessionFile){return!existsSync(dirname(sessionFile))}import{createHash}from"node:crypto";import{basename as basename2,dirname as dirname2,join as join2,win32}from"node:path";function canonicalEndpointPath(socket,platform=process.platform){return platform==="win32"?win32.normalize(socket).toLowerCase():socket.startsWith("\0")?socket:join2(canonicalSessionPath(dirname2(socket)),basename2(socket))}function daemonDirectoryName(socket,platform=process.platform){return directoryNameOf(canonicalEndpointPath(socket,platform))}function sameEndpoint(socket,other){return socket===other||canonicalEndpointPath(socket)===canonicalEndpointPath(other)}function socketNamesDirectory(socket,name){return daemonDirectoryName(socket)===name||process.platform!=="win32"&&directoryNameOf(socket)===name}function directoryNameOf(endpoint){return createHash("sha256").update(endpoint,"utf8").digest("hex").slice(0,16)}function shardKey(kind,ownerId){return createHash("sha256").update(`${kind}:${ownerId}`,"utf8").digest("hex").slice(0,16)}function shardSocketPathForKey(root,kind,key){return join2(root,`${kind}-${key}.sock`)}function shardSocketPath(root,kind,ownerId){return shardSocketPathForKey(root,kind,shardKey(kind,ownerId))}var SHARD_SOCKET_NAME=/^(p|i)-([0-9a-f]{16})\.sock$/;function parseShardSocket(socket){let match=SHARD_SOCKET_NAME.exec(basename2(socket)),key=match?.[2];return key===void 0?null:{kind:match?.[1]==="i"?"i":"p",key}}import{chmod,mkdir}from"node:fs/promises";import{join as join3}from"node:path";var DIRECTORY_MODE=448;function generationPaths(paths,instanceId){let dir=join3(paths.generationsDir,instanceId);return{dir,relativeDir:`generations/${instanceId}`,pidFile:join3(dir,"host.pid"),settingsFile:join3(dir,"settings.json"),scratchDir:join3(dir,"scratch"),childPidFile:join3(dir,"host-child.pid"),stopIntentFile:join3(dir,"stop-intent.json"),drainRequestFile:join3(dir,"drain-request.json"),childDrainRequestFile:join3(dir,"host-drain-request.json"),drainWatchFile:join3(dir,"drain-watch.json"),stalledFile:join3(dir,"host-stalled.json"),aliveFile:join3(dir,"host-alive.json"),stopProgressFile:join3(dir,"stop-progress.json")}}var HostDaemonStateError=class extends Error{constructor(path,cause){super(`RPC daemon state directory ${path} is not usable: ${cause instanceof Error?cause.message:cause}`,{cause}),this.name="HostDaemonStateError",this.path=path}};async function createGenerationDirectory(generation){try{await mkdir(generation.scratchDir,{recursive:!0,mode:DIRECTORY_MODE}),await chmod(generation.dir,DIRECTORY_MODE)}catch(cause){throw new HostDaemonStateError(generation.dir,cause)}}import{randomUUID}from"node:crypto";import{chmod as chmod2,link,mkdir as mkdir2,readFile,rename,rm,writeFile}from"node:fs/promises";import{basename as basename3,join as join4}from"node:path";var HOST_DAEMON_LAYOUT=2,HOST_DAEMON_DIR_ENV="SENPI_RPC_HOST_DAEMON_DIR",ENDPOINT_REGISTRY_VERSION=1,DIRECTORY_MODE2=448,HOST_STATE_FILE_MODE=384;function createHostDaemonPaths(target){let flatDir=join4(target.agentDir??getAgentDir(),"rpc-host-daemon");return{socket:target.socket,flatDir,layoutMarker:join4(flatDir,"layout.json"),legacyPidFile:join4(flatDir,"host.pid"),...hostDaemonDirectoryPaths(join4(flatDir,daemonDirectoryName(target.socket)))}}function hostDaemonDirectoryPaths(dir){return{dir,endpointFile:join4(dir,"endpoint.json"),pointerFile:join4(dir,"host.pid"),lockFile:join4(dir,"daemon.lock"),settingsFile:join4(dir,"settings.json"),stderrLog:join4(dir,"stderr.log"),generationsDir:join4(dir,"generations"),reservationsDir:join4(dir,"reservations")}}async function createDaemonDirectories(paths,identity={}){try{await mkdir2(paths.flatDir,{recursive:!0,mode:DIRECTORY_MODE2}),await makePrivateDirectory(paths.dir),await Promise.all([makePrivateDirectory(paths.generationsDir),makePrivateDirectory(paths.reservationsDir),writeFile(paths.layoutMarker,`${JSON.stringify({layout:HOST_DAEMON_LAYOUT,dir:basename3(paths.dir)})}
|
|
3
3
|
`,{mode:HOST_STATE_FILE_MODE})])}catch(cause){throw new HostDaemonStateError(paths.dir,cause)}await ensureEndpointIdentity(paths,paths.socket,identity)}async function makePrivateDirectory(directory){await mkdir2(directory,{recursive:!0,mode:DIRECTORY_MODE2})===void 0&&await chmod2(directory,DIRECTORY_MODE2)}async function ensureEndpointIdentity(paths,socket,options={}){let temporary=`${paths.endpointFile}.${process.pid}-${randomUUID()}.tmp`;try{await mkdir2(paths.dir,{recursive:!0,mode:DIRECTORY_MODE2});let record=`${JSON.stringify({layout:HOST_DAEMON_LAYOUT,registry_version:ENDPOINT_REGISTRY_VERSION,endpoint_kind:options.kind??"rpc_host",socket,created_at:new Date().toISOString()})}
|
|
4
4
|
`;await writeFile(temporary,record,{mode:HOST_STATE_FILE_MODE,flag:"wx"}),!await link(temporary,paths.endpointFile).then(()=>!0,cause=>isErrorCode(cause,"EEXIST")?!1:createExclusively(paths.endpointFile,record))&&options.repair===!0&&!await namesThisDirectory(paths)&&await rename(temporary,paths.endpointFile)}catch(cause){throw new HostDaemonStateError(paths.endpointFile,cause)}finally{await rm(temporary,{force:!0})}}async function createExclusively(path,content){try{return await writeFile(path,content,{mode:HOST_STATE_FILE_MODE,flag:"wx"}),!0}catch(cause){if(isErrorCode(cause,"EEXIST"))return!1;throw cause}}function isErrorCode(cause,code){return cause instanceof Error&&"code"in cause&&cause.code===code}async function namesThisDirectory(paths){let record;try{record=JSON.parse(await readFile(paths.endpointFile,"utf8"))}catch{return!1}return typeof record!="object"||record===null||!("socket"in record)?!1:typeof record.socket=="string"&&record.socket!==""&&socketNamesDirectory(record.socket,basename3(paths.dir))}import{randomUUID as randomUUID2}from"node:crypto";import{readFile as readFile2,rename as rename2,rm as rm2,writeFile as writeFile2}from"node:fs/promises";async function writeJsonAtomic(path,content){let temporary=`${path}.${process.pid}.${randomUUID2().slice(0,8)}.tmp`;try{await writeFile2(temporary,`${JSON.stringify(content)}
|
|
5
5
|
`,{mode:384}),await rename2(temporary,path)}catch(cause){throw await rm2(temporary,{force:!0}).catch(()=>{}),cause}}async function readJsonObject(path){try{let value=JSON.parse(await readFile2(path,"utf8"));return typeof value=="object"&&value!==null&&!Array.isArray(value)?{...value}:void 0}catch{return}}function ageOf(at,now){if(typeof at!="string")return;let parsed=Date.parse(at);return Number.isNaN(parsed)?void 0:now-parsed}import{readFile as readFile3,writeFile as writeFile3}from"node:fs/promises";import{join as join5}from"node:path";async function readHostOwner(generationDir){let record=await readJsonObject(join5(generationDir,"owner.json"));if(record?.owner===null)return null;if(!isRecord(record?.owner))return;let{pid,startTime}=record.owner;return typeof pid=="number"&&Number.isSafeInteger(pid)&&pid>0&&typeof startTime=="string"&&startTime.length>0?{pid,startTime}:void 0}function writeHostOwner(generationDir,owner){return writeJsonAtomic(join5(generationDir,"owner.json"),{owner})}function sameHostOwner(a,b){if(a==null||b==null||a.pid!==b.pid)return!1;let started=processStartTimeMs(a.startTime);return started!==void 0&&started===processStartTimeMs(b.startTime)}async function callerHostOwner(){let observed=await readProcessIdentity(process.pid,process.platform,void 0,void 0,"UTC");if(observed.kind!=="present"||processStartTimeMs(observed.identity)===void 0)throw new Error("cannot establish RPC host owner OS start identity");return{pid:process.pid,startTime:observed.identity}}async function hostOwnerGone(owner){let observed=await readProcessIdentity(owner.pid,process.platform,1e3,void 0,"UTC");return observed.kind==="absent"||observed.kind==="present"&&processStartTimeMs(observed.identity)!==void 0&&processStartTimeMs(owner.startTime)!==void 0&&!sameProcessStartMs(processStartTimeMs(observed.identity),processStartTimeMs(owner.startTime))}async function claimHostOwner(generationDir){let previous=await readHostOwner(generationDir);if(previous===void 0)throw new Error("RPC host does not support owner lifetime registration");let next=await callerHostOwner();if(!sameHostOwner(previous,next)){if(previous!==null&&!await hostOwnerGone(previous))throw new Error("RPC host lifetime owner is still alive or its identity is unknown");await writeHostOwner(generationDir,next)}}async function writeHostSettings(paths,settings){let generation=generationPaths(paths,settings.instanceId);await createGenerationDirectory(generation),await writeStateFile(paths.settingsFile,settings),await writeStateFile(generation.settingsFile,settings)}async function readHostSettings(paths){let parsed=parseJson(await readFileOrUndefined(paths.settingsFile));if(parsed)return{...typeof parsed.coldStart=="string"&&{coldStart:parsed.coldStart},...typeof parsed.idleExitMs=="number"&&{idleExitMs:parsed.idleExitMs}}}async function writeStateFile(path,content){try{await writeFile3(path,`${JSON.stringify(content)}
|