@ai-agent-forge/agent-forge 0.85.9 → 0.85.11

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.
@@ -505,7 +505,7 @@ File: ${path15}`)}let config=parsed,providers=new Map;for(let[providerId,provide
505
505
  `)}if(typeof data.profileId=="string"){let selected=Array.isArray(data.selectedPluginIds)?` selected=${data.selectedPluginIds.join(",")}`:"",disabled=Array.isArray(data.disabledPluginIds)?` disabled=${data.disabledPluginIds.join(",")}`:"";return`${status2}: ${command} profile:${data.profileId}${selected}${disabled}`}return`${status2}: ${command}`}function safeError(code){return Object.freeze({code,message:{invalid_command:"The plugin ecosystem command is invalid",unsupported_dependencies:"The plugin ecosystem operation is unavailable on this host",not_found:"The requested plugin was not found",not_installed:"The requested plugin is not installed",registry_failed:"The plugin registry operation failed",acquisition_failed:"The plugin package acquisition failed",distribution_failed:"The plugin distribution operation failed",incompatible:"The requested plugin is incompatible with this host",already_installed:"This plugin version is already installed in the requested scope",installer_failed:"The plugin installer operation failed",uninstall_failed:"The host plugin uninstall operation failed",state_failed:"The plugin state operation failed",selection_failed:"The plugin selection operation failed",cancelled:"Plugin ecosystem operation was cancelled"}[code]})}function invalidCommandError(argv,cause){let genericCauses=new Set(["ecosystem command is invalid","ecosystem command has unsupported arguments"]),causeMessage=cause instanceof Error?cause.message:void 0,reason=causeMessage!==void 0&&!genericCauses.has(causeMessage)?` (${causeMessage})`:"";return Object.freeze({code:"invalid_command",message:`The plugin ecosystem command is invalid: received argv [${argv.join(" ")}]${reason}; valid commands: ${PLUGIN_ECOSYSTEM_CLI_COMMAND_USAGE_V1}`})}function isCancelled(signal){return signal?.aborted===!0}function stateStoreOf(options,scope){return scope==="project"?options.projectStateStore:options.stateStore??options.stateHost}function operationScope(scope){return scope??"global"}function scopeRefOf(options,scope){return scope==="global"?DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1:options.projectScopeRef}function installerSupportsScope(installer,scope){return installer?.supportedScopes?.includes(scope)===!0}function selectionStoreOf(options,scope){return scope==="project"?options.projectSelectionStore:options.selectionStore??options.selectionHost}function stateEntry(record){return Object.freeze({pluginId:record.pluginId,pluginVersion:record.pluginVersion,manifestDigest:record.manifestDigest,scope:record.state.scope,scopeRef:record.state.scopeRef,enabled:record.state.enabled,lifecycle:record.state.lifecycle,...record.source===void 0?{}:{source:record.source}})}function selectionEntry(selection){return Object.freeze({profileId:selection.profileId,selectedPluginIds:Object.freeze([...selection.selectedPluginIds]),disabledPluginIds:Object.freeze([...selection.disabledPluginIds])})}function catalogEntry(entry){return Object.freeze({pluginId:entry.pluginId,pluginVersion:entry.pluginVersion,manifestDigest:entry.manifestDigest,status:entry.resolution.status,diagnosticCodes:Object.freeze(entry.resolution.diagnostics.map(item=>item.code).slice(0,16))})}function findStateRecord(records,pluginId,pluginVersion,scope,scopeRef){return records.find(record=>record.pluginId===pluginId&&(pluginVersion===void 0||record.pluginVersion===pluginVersion)&&(scope===void 0||record.state.scope===scope)&&(scopeRef===void 0||record.state.scopeRef===scopeRef))}function findCurrentStateRecord(records,pluginId,scope,scopeRef){return records.find(record=>record.pluginId===pluginId&&(scope===void 0||record.state.scope===scope)&&(scopeRef===void 0||record.state.scopeRef===scopeRef)&&record.state.lifecycle==="active")??findStateRecord(records,pluginId,void 0,scope,scopeRef)}function requireDependencies(options,scope,scopeRef){let requestedScope=operationScope(scope);if(!options.registry||!options.installer||scopeRef===void 0||!installerSupportsScope(options.installer,requestedScope)||!stateStoreOf(options,requestedScope)||!options.host)throw new Error("unsupported dependencies")}async function listManifests(options,signal){if(options.registry?.list)return await options.registry.list({signal});if(options.manifests)return options.manifests;throw new Error("unsupported dependencies")}function checkSignal(signal){if(isCancelled(signal))throw new Error("cancelled")}function createPluginEcosystemCliV1(options){let installTransactionTail=Promise.resolve();async function acquireInstallTransaction(){let release,turn=new Promise(resolve25=>{release=resolve25}),previous=installTransactionTail;return installTransactionTail=previous.then(()=>turn,()=>turn),await previous,release}async function execute(input){let parsed;try{parsed=parsePluginEcosystemCliCommandV1(input.argv,input.format??"text")}catch(error2){return response("invalid",input.format==="json"?"json":"text","failed",invalidCommandError(input.argv,error2))}let releaseInstallTransaction=parsed.command==="install"||parsed.command==="update"?await acquireInstallTransaction():void 0;try{let signal=input.signal,requestedScope=operationScope(parsed.scope),scopeRef=scopeRefOf(options,requestedScope);if(isCancelled(signal))return response(parsed.command,parsed.format,"cancelled",safeError("cancelled"));if(scopeRef===void 0)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));let phase="registry";try{if(parsed.command==="catalog-list"){if(!options.host)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));let manifests2=await listManifests(options,signal);checkSignal(signal);let snapshot2=buildPluginCatalogV1({manifests:manifests2,host:options.host,maxEntries:MAX_PLUGIN_ECOSYSTEM_CLI_LIST_ENTRIES_V1});return response(parsed.command,parsed.format,"succeeded",void 0,{version:snapshot2.version,entries:snapshot2.entries.map(catalogEntry),truncated:snapshot2.truncated})}if(parsed.command==="selection-list"){phase="selection";let selectionStore=selectionStoreOf(options,parsed.scope);if(!selectionStore)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));let result=await selectionStore.read({signal});return result.status==="cancelled"?response(parsed.command,parsed.format,"cancelled",safeError("cancelled")):result.status==="invalid"?response(parsed.command,parsed.format,"failed",safeError("selection_failed")):response(parsed.command,parsed.format,"succeeded",void 0,{version:result.snapshot.version,scope:parsed.scope??"global",entries:result.snapshot.selections.map(selectionEntry),truncated:!1})}if(parsed.command==="selection-set"){phase="selection";let selectionStore=selectionStoreOf(options,parsed.scope);if(!selectionStore)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));let selection;try{selection=createPluginSelectionV1({profileId:parsed.profileId,selectedPluginIds:parsed.selectedPluginIds??[],disabledPluginIds:[]})}catch{return response(parsed.command,parsed.format,"failed",safeError("selection_failed"))}let result=await selectionStore.set({selection,signal});return result.status==="cancelled"?response(parsed.command,parsed.format,"cancelled",safeError("cancelled")):result.status!=="ok"?response(parsed.command,parsed.format,"failed",safeError("selection_failed")):response(parsed.command,parsed.format,"succeeded",void 0,{profileId:selection.profileId,scope:parsed.scope??"global",selectedPluginIds:selection.selectedPluginIds,disabledPluginIds:selection.disabledPluginIds,changed:result.changed})}if(parsed.command==="selection-clear"){phase="selection";let selectionStore=selectionStoreOf(options,parsed.scope);if(!selectionStore)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));let result=await selectionStore.clear({profileId:parsed.profileId,signal});return result.status==="cancelled"?response(parsed.command,parsed.format,"cancelled",safeError("cancelled")):result.status!=="ok"?response(parsed.command,parsed.format,"failed",safeError("selection_failed")):response(parsed.command,parsed.format,"succeeded",void 0,{profileId:parsed.profileId,scope:parsed.scope??"global",changed:result.changed})}if(parsed.command==="state-list"){phase="state";let stateStore2=stateStoreOf(options,requestedScope);if(!stateStore2)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));let result=await stateStore2.read({signal});if(result.status==="cancelled")return response(parsed.command,parsed.format,"cancelled",safeError("cancelled"));if(result.status==="invalid")return response(parsed.command,parsed.format,"failed",safeError("state_failed"));let records=result.snapshot.records.filter(record=>record.state.scope===requestedScope&&record.state.scopeRef===scopeRef);return response(parsed.command,parsed.format,"succeeded",void 0,{version:result.snapshot.version,entries:records.map(stateEntry),truncated:!1})}if(parsed.command==="enable"||parsed.command==="disable"||parsed.command==="remove"){if(phase="state",parsed.command==="remove"&&requestedScope==="project"&&!installerSupportsScope(options.installer,requestedScope))return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));let stateStore2=stateStoreOf(options,requestedScope);if(!stateStore2)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));let current=await stateStore2.read({signal});if(current.status==="cancelled")return response(parsed.command,parsed.format,"cancelled",safeError("cancelled"));if(current.status==="invalid")return response(parsed.command,parsed.format,"failed",safeError("state_failed"));let record=parsed.pluginVersion===void 0?findCurrentStateRecord(current.snapshot.records,parsed.pluginId,requestedScope,scopeRef):findStateRecord(current.snapshot.records,parsed.pluginId,parsed.pluginVersion,requestedScope,scopeRef);if(!record)return response(parsed.command,parsed.format,"failed",safeError("not_installed"));if(parsed.command==="remove"){if(options.installer!==void 0){let removedFromHost;try{removedFromHost=await options.installer.remove({installation:{version:1,pluginId:record.pluginId,pluginVersion:record.pluginVersion,manifestDigest:record.manifestDigest,scope:record.state.scope,scopeRef:record.state.scopeRef,installationRef:record.installationRef,state:record.state.lifecycle},scope:requestedScope,scopeRef,signal})}catch{return response(parsed.command,parsed.format,"failed",safeError("uninstall_failed"))}if(removedFromHost.status!=="succeeded")return response(parsed.command,parsed.format,removedFromHost.status==="cancelled"?"cancelled":"failed",safeError(removedFromHost.status==="cancelled"?"cancelled":"uninstall_failed"))}let removed=await stateStore2.remove({pluginId:record.pluginId,pluginVersion:record.pluginVersion,scope:requestedScope,scopeRef,signal});return removed.status==="cancelled"?response(parsed.command,parsed.format,"cancelled",safeError("cancelled")):removed.status!=="ok"?response(parsed.command,parsed.format,"failed",safeError("state_failed")):response(parsed.command,parsed.format,"succeeded",void 0,{pluginId:record.pluginId,pluginVersion:record.pluginVersion,...options.installer===void 0?{}:{hostRemoved:!0},changed:removed.changed})}let enabled=parsed.command==="enable",updated=await stateStore2.upsert({installation:{version:1,pluginId:record.pluginId,pluginVersion:record.pluginVersion,manifestDigest:record.manifestDigest,scope:record.state.scope,scopeRef:record.state.scopeRef,installationRef:record.installationRef,state:record.state.lifecycle},scope:requestedScope,enabled,...record.source===void 0?{}:{source:record.source},signal});return updated.status==="cancelled"?response(parsed.command,parsed.format,"cancelled",safeError("cancelled")):updated.status!=="ok"?response(parsed.command,parsed.format,"failed",safeError("state_failed")):response(parsed.command,parsed.format,"succeeded",void 0,{pluginId:record.pluginId,pluginVersion:record.pluginVersion,enabled,changed:updated.changed})}let stateStore=stateStoreOf(options,requestedScope),installer=options.installer,host=options.host,acquisitionTarget=parsed.command==="install"&&parsed.target!==void 0&&isPluginAcquisitionRefTargetV1(parsed.target)?parsed.target:void 0;if(!stateStore||!installer||!host||!installerSupportsScope(installer,requestedScope)||acquisitionTarget===void 0&&!options.registry)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));let runInstallFlow=async resolved=>{phase="state";let current=await stateStore.read({signal});if(current.status==="cancelled")return response(parsed.command,parsed.format,"cancelled",safeError("cancelled"));if(current.status==="invalid")return response(parsed.command,parsed.format,"failed",safeError("state_failed"));let previous=findCurrentStateRecord(current.snapshot.records,resolved.manifest.id,requestedScope,scopeRef);if(findStateRecord(current.snapshot.records,resolved.manifest.id,resolved.manifest.pluginVersion,requestedScope,scopeRef)!==void 0)return response(parsed.command,parsed.format,"failed",safeError("already_installed"));if(parsed.command==="update"&&(!previous||previous.state.lifecycle!=="active"))return response(parsed.command,parsed.format,"failed",safeError("not_installed"));phase="installer";let verified=installer.prepare({manifest:resolved.manifest,source:resolved.source,host,...resolved.expectedDigest===void 0?{}:{expectedDigest:resolved.expectedDigest}});if(verified.status!=="verified")return response(parsed.command,parsed.format,"failed",safeError("incompatible"));let artifact=resolved.acquired?.artifact;if(resolved.distribution!==void 0){if(options.distribution===void 0)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));phase="distribution";let descriptor=options.distribution.validateDescriptor(resolved.distribution);if(descriptor.pluginId!==verified.record.pluginId||descriptor.pluginVersion!==verified.record.pluginVersion||descriptor.manifestDigest!==verified.record.manifestDigest)return response(parsed.command,parsed.format,"failed",safeError("incompatible"));artifact=await options.distribution.acquireArtifact({descriptor,signal})}let artifactReleased=!1,releaseArtifact=async()=>{if(artifact===void 0||artifactReleased)return!0;let previousPhase=phase;phase="distribution";try{return resolved.acquired!==void 0?await resolved.acquired.release()?(artifactReleased=!0,phase=previousPhase,!0):!1:options.distribution===void 0?!1:(await options.distribution.releaseArtifact({artifact}),artifactReleased=!0,phase=previousPhase,!0)}catch{return!1}},transactionResponse,transactionError,artifactCleanupFailed=!1;try{transactionResponse=await(async()=>{checkSignal(signal),phase="installer";let installed=await installer.install({record:verified.record,scope:requestedScope,scopeRef,...artifact===void 0?{}:{artifact},signal});if(installed.status!=="succeeded")return await releaseArtifact()?response(parsed.command,parsed.format,installed.status==="cancelled"?"cancelled":"failed",safeError(installed.status==="cancelled"?"cancelled":"installer_failed")):response(parsed.command,parsed.format,isCancelled(signal)?"cancelled":"failed",safeError(isCancelled(signal)?"cancelled":"distribution_failed"));let activated=await installer.activate({installation:installed.installation,record:verified.record,scope:requestedScope,scopeRef,signal});if(activated.status!=="succeeded")return previous&&previous.state.lifecycle==="active"&&(await installer.rollback({failed:installed.installation,previous:{version:1,pluginId:previous.pluginId,pluginVersion:previous.pluginVersion,manifestDigest:previous.manifestDigest,scope:previous.state.scope,scopeRef:previous.state.scopeRef,installationRef:previous.installationRef,state:"active"},scope:requestedScope,scopeRef,signal:void 0})).status!=="succeeded"||(await installer.remove({installation:installed.installation,scope:requestedScope,scopeRef})).status!=="succeeded"?response(parsed.command,parsed.format,"failed",safeError("installer_failed")):await releaseArtifact()?response(parsed.command,parsed.format,activated.status==="cancelled"?"cancelled":"failed",safeError(activated.status==="cancelled"?"cancelled":"installer_failed")):response(parsed.command,parsed.format,isCancelled(signal)?"cancelled":"failed",safeError(isCancelled(signal)?"cancelled":"distribution_failed"));let restoreActivatedInstallation=async()=>{let replacesPrevious=previous!==void 0&&`${previous.pluginId}@${previous.pluginVersion}`!=`${activated.installation.pluginId}@${activated.installation.pluginVersion}`;return replacesPrevious&&previous.state.lifecycle==="active"&&(await installer.rollback({failed:activated.installation,previous:{version:1,pluginId:previous.pluginId,pluginVersion:previous.pluginVersion,manifestDigest:previous.manifestDigest,scope:previous.state.scope,scopeRef:previous.state.scopeRef,installationRef:previous.installationRef,state:"active"},scope:requestedScope,scopeRef})).status!=="succeeded"?!1:previous!==void 0&&!replacesPrevious?!0:(await installer.remove({installation:activated.installation,scope:requestedScope,scopeRef})).status==="succeeded"},restoreState=async()=>{let replacesPrevious=previous!==void 0&&`${previous.pluginId}@${previous.pluginVersion}`!=`${activated.installation.pluginId}@${activated.installation.pluginVersion}`,restored=!0;if((previous===void 0||replacesPrevious)&&(restored=(await stateStore.remove({pluginId:activated.installation.pluginId,pluginVersion:activated.installation.pluginVersion,scope:requestedScope,scopeRef}).catch(()=>{}))?.status==="ok"),previous!==void 0){let restoredPrevious=await stateStore.upsert({installation:{version:1,pluginId:previous.pluginId,pluginVersion:previous.pluginVersion,manifestDigest:previous.manifestDigest,scope:previous.state.scope,scopeRef:previous.state.scopeRef,installationRef:previous.installationRef,state:"active"},scope:requestedScope,enabled:previous.state.enabled,...previous.source===void 0?{}:{source:previous.source}}).catch(()=>{});restored=restored&&restoredPrevious?.status==="ok"}return restored},stateFailure=async status2=>{let[hostRestored,stateRestored]=await Promise.all([restoreActivatedInstallation().catch(()=>!1),restoreState().catch(()=>!1)]);return response(parsed.command,parsed.format,hostRestored&&stateRestored?status2:"failed",safeError(hostRestored&&stateRestored?status2==="cancelled"?"cancelled":"state_failed":"installer_failed"))};if(!await releaseArtifact()){phase="installer";let restored=await restoreActivatedInstallation().catch(()=>!1);return response(parsed.command,parsed.format,"failed",safeError(restored?"distribution_failed":"installer_failed"))}if(phase="state",previous&&`${previous.pluginId}@${previous.pluginVersion}`!=`${installed.installation.pluginId}@${installed.installation.pluginVersion}`&&(await stateStore.upsert({installation:{version:1,pluginId:previous.pluginId,pluginVersion:previous.pluginVersion,manifestDigest:previous.manifestDigest,scope:previous.state.scope,scopeRef:previous.state.scopeRef,installationRef:previous.installationRef,state:"retained"},scope:requestedScope,enabled:previous.state.enabled,...previous.source===void 0?{}:{source:previous.source},signal:void 0})).status!=="ok")return await stateFailure("failed");let persisted=await stateStore.upsert({installation:activated.installation,scope:requestedScope,enabled:previous?.state.enabled??!0,...resolved.acquired===void 0?{}:{source:resolved.source},signal});return persisted.status==="cancelled"?await stateFailure("cancelled"):persisted.status!=="ok"?await stateFailure("failed"):response(parsed.command,parsed.format,"succeeded",void 0,{pluginId:activated.installation.pluginId,pluginVersion:activated.installation.pluginVersion,lifecycle:"active",changed:persisted.changed,...resolved.acquired===void 0?{}:{source:resolved.source}})})()}catch(error2){transactionError=error2}finally{artifactCleanupFailed=!await releaseArtifact()}if(artifactCleanupFailed)return response(parsed.command,parsed.format,"failed",safeError("distribution_failed"));if(transactionError!==void 0)throw transactionError;if(transactionResponse===void 0)throw new Error("plugin installation transaction did not complete");return transactionResponse};if(acquisitionTarget!==void 0){if(options.acquisition===void 0)return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"));phase="distribution";let acquired;try{acquired=await options.acquisition.resolvePackage({ref:acquisitionTarget,signal})}catch(error2){if(isCancelled(signal)||error2 instanceof PluginAcquisitionErrorV1&&error2.code==="cancelled")return response(parsed.command,parsed.format,"cancelled",safeError("cancelled"));if(error2 instanceof PluginAcquisitionErrorV1)return response(parsed.command,parsed.format,"failed",{code:"acquisition_failed",message:error2.message});throw error2}return checkSignal(signal),await runInstallFlow({manifest:acquired.manifest,source:acquired.source,acquired})}try{requireDependencies(options,requestedScope,scopeRef)}catch{return response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies"))}let identity=parsed.pluginId,packageValue=await options.registry.resolve({pluginId:identity,pluginVersion:parsed.pluginVersion,signal});return checkSignal(signal),!packageValue||packageValue.manifest.id!==identity||parsed.pluginVersion!==void 0&&packageValue.manifest.pluginVersion!==parsed.pluginVersion?response(parsed.command,parsed.format,"failed",safeError("not_found")):await runInstallFlow({manifest:packageValue.manifest,source:packageValue.source,...packageValue.expectedDigest===void 0?{}:{expectedDigest:packageValue.expectedDigest},...packageValue.distribution===void 0?{}:{distribution:packageValue.distribution}})}catch(error2){return isCancelled(signal)||error2 instanceof Error&&error2.message==="cancelled"?response(parsed.command,parsed.format,"cancelled",safeError("cancelled")):error2 instanceof Error&&error2.message==="unsupported dependencies"?response(parsed.command,parsed.format,"unsupported",safeError("unsupported_dependencies")):response(parsed.command,parsed.format,"failed",safeError(phase==="registry"?"registry_failed":phase==="distribution"?"distribution_failed":phase==="state"?"state_failed":phase==="selection"?"selection_failed":"installer_failed"))}}finally{releaseInstallTransaction?.()}}return{execute}}async function runPluginEcosystemCliV1(options,input){return await createPluginEcosystemCliV1(options).execute(input)}import{createHash}from"node:crypto";import{join as join13,resolve as resolve4}from"node:path";import{open as open2}from"node:fs/promises";import{isAbsolute as isAbsolute2,join as join11,relative as relative2}from"node:path";var NODE_DISK_REGISTRY_SOURCE_VERSION_V1=1,MAX_NODE_DISK_REGISTRY_INDEX_BYTES_V1=1024*1024,MAX_NODE_DISK_REGISTRY_MANIFEST_BYTES_V1=64*1024,MAX_NODE_DISK_REGISTRY_RECORDS_V1=256,INDEX_FILE_V1="index.v1.json",ECOSYSTEM_MANIFEST_FILE_V1="agent-forge.json",CAPABILITY_MANIFEST_FILE_V1="plugin.json",NODE_PACKAGE_FORMAT_VERSION_V1=1,NodeDiskRegistrySourceErrorV1=class extends Error{code;constructor(code,message){super(message),this.name="NodeDiskRegistrySourceErrorV1",this.code=code}},INDEX_KEYS_V1=["installationRef","directory","pluginId","pluginVersion","manifestDigest","scope","scopeRef","state"];function opaqueField(value,max){return typeof value=="string"&&value.length>0&&value.length<=max&&!/[\u0000-\u001f\u007f]/u.test(value)&&!/\s/u.test(value)&&!/^(?:file:|[a-z]:[\\/]|[\\/]{1,2}|\\\\)/iu.test(value)}function boundedField(value,max){return typeof value=="string"&&value.length>0&&value.length<=max&&!/[\u0000-\u001f\u007f]/u.test(value)}function withinRoot(root,value){if(!isAbsolute2(value))return!1;let relativePath=relative2(root,value);return relativePath!==""&&!relativePath.startsWith("..")&&!isAbsolute2(relativePath)}function validateRecord(root,value,index3){if(value===null||typeof value!="object"||Array.isArray(value))throw new NodeDiskRegistrySourceErrorV1("invalid_index",`Index record ${index3} is not an object`);let record=value,keys=INDEX_KEYS_V1;if(Object.keys(record).length!==keys.length||keys.some(key=>!(key in record)))throw new NodeDiskRegistrySourceErrorV1("invalid_index",`Index record ${index3} has an invalid schema`);if(!opaqueField(record.installationRef,2048)||!boundedField(record.directory,2048)||!boundedField(record.pluginId,256)||!boundedField(record.pluginVersion,256)||!boundedField(record.manifestDigest,512)||!opaqueField(record.scopeRef,2048)||record.scope!=="global"&&record.scope!=="project"||record.state!=="installed"&&record.state!=="active"&&record.state!=="retained"||!withinRoot(root,record.directory))throw new NodeDiskRegistrySourceErrorV1("invalid_index",`Index record ${index3} is invalid`);return{installationRef:record.installationRef,directory:record.directory,pluginId:record.pluginId,pluginVersion:record.pluginVersion,manifestDigest:record.manifestDigest,scope:record.scope,scopeRef:record.scopeRef,state:record.state}}function parseIndex(root,raw){let parsed;try{parsed=JSON.parse(raw)}catch{throw new NodeDiskRegistrySourceErrorV1("invalid_index","Install store index JSON is invalid")}if(parsed===null||typeof parsed!="object"||Array.isArray(parsed))throw new NodeDiskRegistrySourceErrorV1("invalid_index","Install store index is not an object");let value=parsed;if(Object.keys(value).length!==2||value.version!==NODE_DISK_REGISTRY_SOURCE_VERSION_V1||!Array.isArray(value.records))throw new NodeDiskRegistrySourceErrorV1("invalid_index","Install store index schema is unsupported");if(value.records.length>MAX_NODE_DISK_REGISTRY_RECORDS_V1)throw new NodeDiskRegistrySourceErrorV1("too_many_records","Install store index exceeds the record limit");return value.records.map((record,index3)=>validateRecord(root,record,index3))}async function readBoundedFile(path15,maxBytes,label){let handle=await open2(path15,"r");try{let stat5=await handle.stat();if(!stat5.isFile()||stat5.size>maxBytes)throw new NodeDiskRegistrySourceErrorV1(label==="index"?"invalid_index":"invalid_manifest",`${label} exceeds the size limit`);return await handle.readFile("utf8")}finally{await handle.close().catch(()=>{})}}function parseManifest(record,raw){let parsed;try{parsed=JSON.parse(raw)}catch{throw new NodeDiskRegistrySourceErrorV1("invalid_manifest","Installed plugin manifest JSON is invalid")}if(parsed===null||typeof parsed!="object"||Array.isArray(parsed))throw new NodeDiskRegistrySourceErrorV1("invalid_manifest","Installed plugin manifest is not an object");let value={...parsed};if(value.packageFormatVersion!==void 0&&value.packageFormatVersion!==NODE_PACKAGE_FORMAT_VERSION_V1)throw new NodeDiskRegistrySourceErrorV1("invalid_manifest","Installed plugin package format is unsupported");if(delete value.packageFormatVersion,value.id!==record.pluginId||value.pluginVersion!==record.pluginVersion)throw new NodeDiskRegistrySourceErrorV1("identity_mismatch",`Installed plugin manifest identity does not match index record for ${record.pluginId}@${record.pluginVersion}`);return value}async function readIndexRecords(rootDirectory,signal){if(signal?.aborted)throw new NodeDiskRegistrySourceErrorV1("cancelled","Disk registry source read was cancelled");let rawIndex;try{rawIndex=await readBoundedFile(join11(rootDirectory,INDEX_FILE_V1),MAX_NODE_DISK_REGISTRY_INDEX_BYTES_V1,"index")}catch(error2){if(error2 instanceof NodeDiskRegistrySourceErrorV1)throw error2;if(error2 instanceof Error&&"code"in error2&&error2.code==="ENOENT")return;throw new NodeDiskRegistrySourceErrorV1("io_failed","Install store index could not be read")}return parseIndex(rootDirectory,rawIndex)}function createNodeDiskPluginRegistrySourceV1(options){let rootDirectory=options.rootDirectory;if(typeof rootDirectory!="string"||!isAbsolute2(rootDirectory)||rootDirectory.trim()==="")throw new NodeDiskRegistrySourceErrorV1("invalid_configuration","Install store root directory must be absolute");return{version:NODE_DISK_REGISTRY_SOURCE_VERSION_V1,list:async({signal}={})=>{let records=await readIndexRecords(rootDirectory,signal);if(records===void 0)return Object.freeze([]);let envelopes=[];for(let record of records){if(signal?.aborted)throw new NodeDiskRegistrySourceErrorV1("cancelled","Disk registry source read was cancelled");let rawManifest;try{rawManifest=await readBoundedFile(join11(record.directory,ECOSYSTEM_MANIFEST_FILE_V1),MAX_NODE_DISK_REGISTRY_MANIFEST_BYTES_V1,"manifest")}catch(error2){throw error2 instanceof NodeDiskRegistrySourceErrorV1?error2:new NodeDiskRegistrySourceErrorV1("io_failed","Installed plugin manifest could not be read")}let manifest=parseManifest(record,rawManifest);envelopes.push({manifest,source:record.installationRef,manifestDigest:record.manifestDigest})}return Object.freeze(envelopes)},resolveCapabilityManifestPath:async({pluginId,pluginVersion,signal})=>{let records=await readIndexRecords(rootDirectory,signal);if(records===void 0)return;let record=records.find(candidate=>candidate.pluginId===pluginId&&candidate.pluginVersion===pluginVersion);if(record===void 0)return;let manifestPath=join11(record.directory,CAPABILITY_MANIFEST_FILE_V1);try{await(await open2(manifestPath,"r")).close().catch(()=>{})}catch{return}return manifestPath}}}var PLUGIN_DISTRIBUTION_CONTRACT_VERSION_V1=1,MAX_PLUGIN_DISTRIBUTION_DESCRIPTOR_BYTES_V1=16*1024,MAX_PLUGIN_DISTRIBUTION_FIELD_CHARS_V1=2048,MAX_PLUGIN_DISTRIBUTION_METADATA_BYTES_V1=16*1024,MAX_PLUGIN_DISTRIBUTION_ARTIFACT_REF_CHARS_V1=2048,MAX_PLUGIN_DISTRIBUTION_ARTIFACT_BYTES_V1=512*1024*1024,ERROR_MESSAGES={unsupported:"Plugin distribution is unsupported on this host",cancelled:"Plugin distribution operation was cancelled",invalid_descriptor:"Plugin distribution descriptor is invalid",invalid_metadata:"Plugin distribution metadata is invalid",invalid_artifact:"Plugin distribution artifact handle is invalid",source_mismatch:"Plugin distribution source does not match the descriptor",identity_mismatch:"Plugin distribution plugin identity does not match the descriptor",digest_mismatch:"Plugin distribution digest does not match the descriptor",signature_invalid:"Plugin distribution signature was rejected",expired:"Plugin distribution descriptor has expired",size_mismatch:"Plugin distribution size does not match the descriptor",media_type_mismatch:"Plugin distribution media type does not match the descriptor",host_failed:"Plugin distribution host operation failed",release_failed:"Plugin distribution artifact release failed"},PluginDistributionErrorV1=class extends Error{code;constructor(code){super(ERROR_MESSAGES[code]),this.name="PluginDistributionErrorV1",this.code=code}},DESCRIPTOR_KEYS=["version","source","pluginId","pluginVersion","manifestDigest","artifactDigest","signature","expiresAt","sizeBytes","mediaType"],METADATA_KEYS=["version","source","pluginId","pluginVersion","manifestDigest","artifactDigest","expiresAt","sizeBytes","mediaType"],ARTIFACT_KEYS=["artifactRef","artifactDigest","sizeBytes","mediaType"];function reject(code){throw new PluginDistributionErrorV1(code)}function hasExactKeys(value,keys){let expected=new Set(keys);return Object.keys(value).every(key=>expected.has(key)&&expected.size===keys.length)&&keys.every(key=>key in value)}function boundedString(value,code){return(typeof value!="string"||value.trim().length===0||value.length>MAX_PLUGIN_DISTRIBUTION_FIELD_CHARS_V1||/[\u0000-\u001f\u007f]/u.test(value))&&reject(code),value}function identityString(value,code){let result=boundedString(value,code);return/\s/u.test(result)&&reject(code),result}function sourceString(value,code){let source=boundedString(value,code);if((/\s/u.test(source)||/^(?:file:|[a-zA-Z]:[\\/]|[\\/]{1,2}|\\\\)/iu.test(source))&&reject(code),/^https?:\/\//iu.test(source))try{let parsed=new URL(source);(parsed.username!==""||parsed.password!=="")&&(parsed.username="",parsed.password=""),parsed.search="",parsed.hash="";let pathname=parsed.pathname.length>512?`${parsed.pathname.slice(0,509)}...`:parsed.pathname;return`${parsed.origin}${pathname||"/"}`}catch{reject(code)}return source}function digestString(value,code){let digest=identityString(value,code);return/^(?:[a-z][a-z0-9+.-]{0,15}:[A-Za-z0-9._~-]{1,128}|[0-9a-f]{16,128})$/u.test(digest)||reject(code),digest}function signatureString(value){let signature=boundedString(value,"invalid_descriptor");return(signature.length>512||/\s/u.test(signature))&&reject("invalid_descriptor"),signature}function expiryString(value,code){let expiry=boundedString(value,code);/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/u.test(expiry)||reject(code);let timestamp=Date.parse(expiry);return(!Number.isFinite(timestamp)||new Date(timestamp).toISOString()!==expiry)&&reject(code),expiry}function positiveSize(value,code){return(typeof value!="number"||!Number.isSafeInteger(value)||value<1||value>MAX_PLUGIN_DISTRIBUTION_ARTIFACT_BYTES_V1)&&reject(code),value}function mediaTypeString(value,code){let mediaType=boundedString(value,code).toLowerCase();return(mediaType.length>256||!/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+(?:\s*;\s*[a-z0-9!#$&^_.+-]+=[a-z0-9!#$&^_.+-]+)*$/u.test(mediaType))&&reject(code),mediaType}function serializedBytes(value,code){try{let serialized=JSON.stringify(value);return serialized===void 0&&reject(code),new TextEncoder().encode(serialized).byteLength}catch{reject(code)}}function descriptorValue(value){(!isPlainRecord(value)||!hasExactKeys(value,DESCRIPTOR_KEYS))&&reject("invalid_descriptor"),value.version!==PLUGIN_DISTRIBUTION_CONTRACT_VERSION_V1&&reject("invalid_descriptor");let descriptor={version:PLUGIN_DISTRIBUTION_CONTRACT_VERSION_V1,source:sourceString(value.source,"invalid_descriptor"),pluginId:identityString(value.pluginId,"invalid_descriptor"),pluginVersion:identityString(value.pluginVersion,"invalid_descriptor"),manifestDigest:digestString(value.manifestDigest,"invalid_descriptor"),artifactDigest:digestString(value.artifactDigest,"invalid_descriptor"),signature:signatureString(value.signature),expiresAt:expiryString(value.expiresAt,"invalid_descriptor"),sizeBytes:positiveSize(value.sizeBytes,"invalid_descriptor"),mediaType:mediaTypeString(value.mediaType,"invalid_descriptor")};return serializedBytes(descriptor,"invalid_descriptor")>MAX_PLUGIN_DISTRIBUTION_DESCRIPTOR_BYTES_V1&&reject("invalid_descriptor"),detachedFreeze(descriptor)}function metadataValue(value){(!isPlainRecord(value)||!hasExactKeys(value,METADATA_KEYS))&&reject("invalid_metadata"),value.version!==PLUGIN_DISTRIBUTION_CONTRACT_VERSION_V1&&reject("invalid_metadata");let metadata={version:PLUGIN_DISTRIBUTION_CONTRACT_VERSION_V1,source:sourceString(value.source,"invalid_metadata"),pluginId:identityString(value.pluginId,"invalid_metadata"),pluginVersion:identityString(value.pluginVersion,"invalid_metadata"),manifestDigest:digestString(value.manifestDigest,"invalid_metadata"),artifactDigest:digestString(value.artifactDigest,"invalid_metadata"),expiresAt:expiryString(value.expiresAt,"invalid_metadata"),sizeBytes:positiveSize(value.sizeBytes,"invalid_metadata"),mediaType:mediaTypeString(value.mediaType,"invalid_metadata")};return serializedBytes(metadata,"invalid_metadata")>MAX_PLUGIN_DISTRIBUTION_METADATA_BYTES_V1&&reject("invalid_metadata"),detachedFreeze(metadata)}function artifactHandleValue(value){(!isPlainRecord(value)||!hasExactKeys(value,ARTIFACT_KEYS))&&reject("invalid_artifact");let artifact={artifactRef:boundedString(value.artifactRef,"invalid_artifact"),artifactDigest:digestString(value.artifactDigest,"invalid_artifact"),sizeBytes:positiveSize(value.sizeBytes,"invalid_artifact"),mediaType:mediaTypeString(value.mediaType,"invalid_artifact")};return(/[\s\u0000-\u001f\u007f]/u.test(artifact.artifactRef)||/^(?:file:|[a-zA-Z]:[\\/]|[\\/]{1,2}|\\\\)/iu.test(artifact.artifactRef)||artifact.artifactRef.length>MAX_PLUGIN_DISTRIBUTION_ARTIFACT_REF_CHARS_V1)&&reject("invalid_artifact"),detachedFreeze(artifact)}function assertDescriptorMetadataMatch(descriptor,metadata){metadata.source!==descriptor.source&&reject("source_mismatch"),(metadata.pluginId!==descriptor.pluginId||metadata.pluginVersion!==descriptor.pluginVersion)&&reject("identity_mismatch"),(metadata.manifestDigest!==descriptor.manifestDigest||metadata.artifactDigest!==descriptor.artifactDigest)&&reject("digest_mismatch"),metadata.expiresAt!==descriptor.expiresAt&&reject("expired"),metadata.sizeBytes!==descriptor.sizeBytes&&reject("size_mismatch"),metadata.mediaType!==descriptor.mediaType&&reject("media_type_mismatch")}function assertArtifactMatch(descriptor,artifact){artifact.artifactDigest!==descriptor.artifactDigest&&reject("digest_mismatch"),artifact.sizeBytes!==descriptor.sizeBytes&&reject("size_mismatch"),artifact.mediaType!==descriptor.mediaType&&reject("media_type_mismatch")}function isCancelled2(error2,signal){return signal?.aborted===!0||error2 instanceof Error&&(error2.name==="AbortError"||error2.name==="AbortSignalError")}function assertNotExpired(descriptor,now){let current;try{current=now()}catch{reject("expired")}Number.isFinite(current)||reject("expired"),Date.parse(descriptor.expiresAt)<=current&&reject("expired")}async function verifyDescriptor(descriptor,verifySignature,now,signal){signal?.aborted&&reject("cancelled"),assertNotExpired(descriptor,now),verifySignature===void 0&&reject("unsupported");let verification;try{verification=await verifySignature({descriptor})}catch{reject("signature_invalid")}signal?.aborted&&reject("cancelled"),(!isPlainRecord(verification)||verification.status!=="accepted")&&reject("signature_invalid")}function createPluginDistributionV1(options={}){let verifySignature=options.verifySignature??options.verify,now=options.now??(()=>Date.now()),resolveMetadataForDescriptor=async(descriptor,signal)=>{signal?.aborted&&reject("cancelled"),options.host?.resolveMetadata===void 0&&reject("unsupported");let result;try{result=await options.host.resolveMetadata({descriptor,signal})}catch(error2){isCancelled2(error2,signal)&&reject("cancelled"),reject("host_failed")}signal?.aborted&&reject("cancelled");let metadata=metadataValue(result);return assertDescriptorMetadataMatch(descriptor,metadata),assertNotExpired(descriptor,now),metadata};return{validateDescriptor(input){return descriptorValue(input)},resolveMetadata:async input=>{let descriptor=descriptorValue(input.descriptor);return await verifyDescriptor(descriptor,verifySignature,now,input.signal),resolveMetadataForDescriptor(descriptor,input.signal)},acquireArtifact:async input=>{let descriptor=descriptorValue(input.descriptor);await verifyDescriptor(descriptor,verifySignature,now,input.signal),options.host?.acquireArtifact===void 0&&reject("unsupported");let metadata=input.metadata===void 0?await resolveMetadataForDescriptor(descriptor,input.signal):metadataValue(input.metadata);assertDescriptorMetadataMatch(descriptor,metadata),assertNotExpired(descriptor,now);let result,acquired;try{result=await options.host.acquireArtifact({descriptor,metadata,signal:input.signal});let handle=artifactHandleValue(result);return acquired=detachedFreeze({...metadata,artifactRef:handle.artifactRef}),assertArtifactMatch(descriptor,handle),assertNotExpired(descriptor,now),input.signal?.aborted&&reject("cancelled"),acquired}catch(error2){if(acquired!==void 0&&options.host.releaseArtifact!==void 0&&await options.host.releaseArtifact({artifact:acquired}).catch(()=>{}),error2 instanceof PluginDistributionErrorV1)throw error2;isCancelled2(error2,input.signal)&&reject("cancelled"),reject("host_failed")}},releaseArtifact:async input=>{input.signal?.aborted&&reject("cancelled"),options.host?.releaseArtifact===void 0&&reject("unsupported");let value=input.artifact;(!isPlainRecord(value)||!hasExactKeys(value,[...METADATA_KEYS,"artifactRef"]))&&reject("invalid_artifact");let metadataInput=Object.fromEntries(METADATA_KEYS.map(key=>[key,value[key]])),artifact={...metadataValue(metadataInput),artifactRef:artifactHandleValue({artifactRef:value.artifactRef,artifactDigest:value.artifactDigest,sizeBytes:value.sizeBytes,mediaType:value.mediaType}).artifactRef};try{await options.host.releaseArtifact({artifact:detachedFreeze(artifact),signal:input.signal})}catch(error2){isCancelled2(error2,input.signal)&&reject("cancelled"),reject("release_failed")}input.signal?.aborted&&reject("cancelled")}}}var MAX_PLUGIN_REGISTRY_MANIFEST_BYTES_V1=64*1024,MAX_PLUGIN_REGISTRY_MANIFESTS_V1=256,MAX_PLUGIN_REGISTRY_PAYLOAD_BYTES_V1=4*1024*1024,MAX_PLUGIN_REGISTRY_SOURCE_CHARS_V1=2048,MAX_PLUGIN_REGISTRY_PROOF_CHARS_V1=512,PluginRegistryErrorV1=class extends Error{code;cause;constructor(code,message,cause){super(message,cause===void 0?void 0:{cause}),this.name="PluginRegistryErrorV1",this.code=code,this.cause=cause}};function isAbortLike(error2,signal){return signal?.aborted===!0||error2 instanceof Error&&(error2.name==="AbortError"||error2.name==="AbortSignalError")}function boundedString2(value,label,max,code="invalid_source"){if(typeof value!="string"||value.trim()===""||value.length>max||/[\u0000-\u001f]/u.test(value))throw new PluginRegistryErrorV1(code,`${label} must be a non-empty bounded string`);return value}function assertAllowedKeys2(value,allowed,label){let expected=new Set(allowed);if(Object.keys(value).some(key=>!expected.has(key)))throw new PluginRegistryErrorV1("invalid_manifest",`${label} contains an unsupported field`)}function validateSource(source){let value=boundedString2(source,"source",MAX_PLUGIN_REGISTRY_SOURCE_CHARS_V1);if(/^(?:file:|[a-zA-Z]:[\\/]|[\\/]{1,2}|\\\\)/iu.test(value)||/\s/u.test(value))throw new PluginRegistryErrorV1("invalid_source","Plugin registry source must be an opaque URI, not a local path");if(/^https?:\/\//iu.test(value))try{let parsed=new URL(value),pathname=parsed.pathname.length>512?`${parsed.pathname.slice(0,511)}\u2026`:parsed.pathname;return`${parsed.origin}${pathname||"/"}`}catch(error2){throw new PluginRegistryErrorV1("invalid_source","Plugin registry source URL is invalid",error2)}return value}function validateManifest(manifest){if(typeof manifest!="object"||manifest===null||Array.isArray(manifest))throw new PluginRegistryErrorV1("invalid_manifest","Registry manifest must be an object");let value=manifest;if(assertAllowedKeys2(value,["id","pluginVersion","apiVersion","minHostVersion","maxHostVersion","capabilityRefs","requires","platform","testOnly"],"Registry manifest"),typeof value.id!="string"||value.id.trim()===""||value.id.length>256)throw new PluginRegistryErrorV1("invalid_manifest","Registry manifest id is invalid");if(typeof value.pluginVersion!="string"||value.pluginVersion.trim()===""||value.pluginVersion.length>256)throw new PluginRegistryErrorV1("invalid_manifest","Registry manifest pluginVersion is invalid");if(typeof value.apiVersion!="string"||value.apiVersion.trim()===""||value.apiVersion.length>256)throw new PluginRegistryErrorV1("invalid_manifest","Registry manifest apiVersion is invalid");if(value.minHostVersion===void 0&&value.maxHostVersion===void 0)throw new PluginRegistryErrorV1("invalid_manifest","Published plugins must declare host version compatibility range: set minHostVersion and/or maxHostVersion");let bytes;try{bytes=new TextEncoder().encode(JSON.stringify(manifest)).byteLength}catch(error2){throw new PluginRegistryErrorV1("invalid_manifest","Registry manifest cannot be serialized",error2)}if(bytes>MAX_PLUGIN_REGISTRY_MANIFEST_BYTES_V1)throw new PluginRegistryErrorV1("payload_too_large","Registry manifest exceeds the size limit");return Object.freeze({...value})}function validateEnvelope2(value){if(typeof value!="object"||value===null||Array.isArray(value))throw new PluginRegistryErrorV1("invalid_manifest","Registry response entry must be an object");let entry=value;assertAllowedKeys2(entry,["manifest","source","manifestDigest","signature","distribution"],"Registry response entry");let manifest=validateManifest(entry.manifest),source=validateSource(entry.source),manifestDigest=boundedString2(entry.manifestDigest,"manifestDigest",MAX_PLUGIN_REGISTRY_PROOF_CHARS_V1);entry.signature!==void 0&&boundedString2(entry.signature,"signature",MAX_PLUGIN_REGISTRY_PROOF_CHARS_V1);let distribution;if(entry.distribution!==void 0){try{distribution=createPluginDistributionV1().validateDescriptor(entry.distribution)}catch(error2){throw new PluginRegistryErrorV1("invalid_manifest","Registry distribution descriptor is invalid",error2)}if(distribution.pluginId!==manifest.id||distribution.pluginVersion!==manifest.pluginVersion||distribution.manifestDigest!==manifestDigest)throw new PluginRegistryErrorV1("invalid_manifest","Registry distribution descriptor does not match the manifest identity")}return Object.freeze({manifest,source,manifestDigest,...entry.signature===void 0?{}:{signature:entry.signature},...distribution===void 0?{}:{distribution}})}function validateMax(value){let max=value??MAX_PLUGIN_REGISTRY_MANIFESTS_V1;if(!Number.isSafeInteger(max)||max<1||max>MAX_PLUGIN_REGISTRY_MANIFESTS_V1)throw new PluginRegistryErrorV1("invalid_limit",`maxManifests must be an integer between 1 and ${MAX_PLUGIN_REGISTRY_MANIFESTS_V1}`);return max}async function validateSourceProof(entry,verifier,sourceVerifier){let actualDigest=pluginManifestDigestV1(entry.manifest);if(entry.manifestDigest!==actualDigest)throw new PluginRegistryErrorV1("invalid_digest",`Manifest digest mismatch for ${entry.manifest.id}@${entry.manifest.pluginVersion}`);try{let result2=await verifier.verify({manifest:entry.manifest,source:entry.source,manifestDigest:actualDigest,expectedDigest:entry.manifestDigest,signature:entry.signature});if(result2.status!=="accepted")throw new PluginRegistryErrorV1("source_rejected",result2.reason??"Registry source proof was rejected")}catch(error2){throw error2 instanceof PluginRegistryErrorV1?error2:new PluginRegistryErrorV1("source_rejected","Registry source proof was rejected",error2)}let result;try{result=sourceVerifier({pluginId:entry.manifest.id,pluginVersion:entry.manifest.pluginVersion,source:entry.source,manifestDigest:actualDigest})}catch(error2){throw new PluginRegistryErrorV1("source_rejected","Plugin source verifier failed",error2)}if(result.status!=="accepted")throw new PluginRegistryErrorV1("source_rejected",result.reason??"Plugin source was rejected")}function sourceIdentity(entries){return[...new Set(entries.map(entry=>entry.source))].sort((left,right)=>left.localeCompare(right)).join(",")}function createPluginRegistryV1(options){let maxManifests=validateMax(options.maxManifests);if(options.source===void 0||typeof options.source.list!="function")throw new PluginRegistryErrorV1("invalid_source","Registry source must provide list()");if(options.source.source!==void 0&&validateSource(options.source.source),options.verify===void 0||typeof options.verify.verify!="function")throw new PluginRegistryErrorV1("source_rejected","Registry source/digest verifier is required");if(options.sourceVerifier===void 0||typeof options.sourceVerifier!="function")throw new PluginRegistryErrorV1("source_rejected","Registry source verifier is required");let load=async(input={})=>{if(input.signal?.aborted)throw new PluginRegistryErrorV1("cancelled","Plugin registry operation was cancelled");let raw;try{raw=await options.source.list({signal:input.signal})}catch(error2){throw isAbortLike(error2,input.signal)?new PluginRegistryErrorV1("cancelled","Plugin registry operation was cancelled",error2):new PluginRegistryErrorV1("source_rejected","Plugin registry source failed",error2)}if(input.signal?.aborted)throw new PluginRegistryErrorV1("cancelled","Plugin registry operation was cancelled");if(!Array.isArray(raw))throw new PluginRegistryErrorV1("invalid_manifest","Registry source must return an array");if(raw.length>maxManifests)throw new PluginRegistryErrorV1("too_many_manifests","Registry response contains too many manifests");let entries=raw.map(validateEnvelope2);if(entries.reduce((total,entry)=>{let manifestBytes=new TextEncoder().encode(JSON.stringify(entry.manifest)).byteLength,distributionBytes=entry.distribution===void 0?0:new TextEncoder().encode(JSON.stringify(entry.distribution)).byteLength;return total+manifestBytes+distributionBytes+new TextEncoder().encode(entry.source).byteLength+new TextEncoder().encode(entry.manifestDigest).byteLength+(entry.signature===void 0?0:new TextEncoder().encode(entry.signature).byteLength)},0)>MAX_PLUGIN_REGISTRY_PAYLOAD_BYTES_V1)throw new PluginRegistryErrorV1("payload_too_large","Registry response exceeds the aggregate size limit");let seen=new Set,accepted=[],rejected=[];for(let entry of entries){let identity=`${entry.manifest.id}@${entry.manifest.pluginVersion}`;if(seen.has(identity))throw new PluginRegistryErrorV1("invalid_manifest",`Duplicate registry manifest: ${identity}`);seen.add(identity);try{await validateSourceProof(entry,options.verify,options.sourceVerifier)}catch(error2){if(!(error2 instanceof PluginRegistryErrorV1)||error2.cause!==void 0||error2.code!=="source_rejected"&&error2.code!=="invalid_digest")throw error2;rejected.push({pluginId:entry.manifest.id,pluginVersion:entry.manifest.pluginVersion,code:error2.code==="invalid_digest"?"digest_rejected":"source_rejected",reason:error2.code==="invalid_digest"?"Manifest digest mismatch":"Registry source proof was rejected"});continue}if(input.signal?.aborted)throw new PluginRegistryErrorV1("cancelled","Plugin registry operation was cancelled");accepted.push(entry)}let manifests2=accepted.map(entry=>entry.manifest),catalog=buildPluginCatalogV1({manifests:manifests2,host:options.host,availableCapabilities:options.availableCapabilities,maxEntries:maxManifests}),publicEntries=Object.freeze([...accepted].sort((left,right)=>{let idOrder=left.manifest.id.localeCompare(right.manifest.id);return idOrder===0?comparePluginVersionsV1(right.manifest.pluginVersion,left.manifest.pluginVersion):idOrder}).map(entry=>Object.freeze({pluginId:entry.manifest.id,pluginVersion:entry.manifest.pluginVersion,source:entry.source,manifestDigest:entry.manifestDigest,signed:entry.signature!==void 0}))),catalogByIdentity=new Map(catalog.entries.map(entry=>[`${entry.pluginId}@${entry.pluginVersion}`,entry])),verified=Object.freeze(publicEntries.flatMap(entry=>{let catalogEntry2=catalogByIdentity.get(`${entry.pluginId}@${entry.pluginVersion}`);if(catalogEntry2?.resolution.status==="installed-ready")return[{...entry,resolutionStatus:"installed-ready"}];let reason=catalogEntry2?.resolution.diagnostics[0]?.message??"Plugin is incompatible with this host";return rejected.push({pluginId:entry.pluginId,pluginVersion:entry.pluginVersion,code:"incompatible",reason}),[]}));return{accepted:Object.freeze(accepted),snapshot:Object.freeze({version:1,source:options.source.source===void 0?sourceIdentity(accepted):validateSource(options.source.source),entries:publicEntries,catalog,verified,rejected:Object.freeze(rejected)})}};return{list:async(input={})=>(await load(input)).snapshot,listManifests:async(input={})=>{let loaded=await load(input);return Object.freeze(loaded.snapshot.catalog.entries.flatMap(catalogEntry2=>loaded.accepted.filter(entry=>entry.manifest.id===catalogEntry2.pluginId&&entry.manifest.pluginVersion===catalogEntry2.pluginVersion).map(entry=>entry.manifest)))},resolve:async input=>{let loaded=await load({signal:input.signal}),verified=new Set(loaded.snapshot.verified.map(entry2=>`${entry2.pluginId}@${entry2.pluginVersion}`)),identity=input.pluginVersion===void 0?loaded.snapshot.catalog.entries.find(candidate=>candidate.pluginId===input.pluginId&&candidate.resolution.status==="installed-ready"&&verified.has(`${candidate.pluginId}@${candidate.pluginVersion}`)):loaded.snapshot.catalog.entries.find(candidate=>candidate.pluginId===input.pluginId&&candidate.pluginVersion===input.pluginVersion&&candidate.resolution.status==="installed-ready"&&verified.has(`${candidate.pluginId}@${candidate.pluginVersion}`)),entry=identity===void 0?void 0:loaded.accepted.find(candidate=>candidate.manifest.id===identity.pluginId&&candidate.manifest.pluginVersion===identity.pluginVersion);if(entry!==void 0)return Object.freeze({manifest:entry.manifest,source:entry.source,expectedDigest:entry.manifestDigest,...entry.distribution===void 0?{}:{distribution:entry.distribution}})}}}import{randomUUID as randomUUID3}from"node:crypto";import{mkdir,readFile as readFile3,rename,unlink,writeFile}from"node:fs/promises";import{basename as basename2,dirname as dirname6,isAbsolute as isAbsolute3,join as join12,resolve as resolve3}from"node:path";var PLUGIN_STATE_SNAPSHOT_VERSION_V1=1,MAX_PLUGIN_STATE_RECORDS_V1=256,MAX_PLUGIN_STATE_STRING_CHARS_V1=4096,MAX_PLUGIN_STATE_ID_CHARS_V1=256,MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1=2048,MAX_PLUGIN_STATE_SOURCE_CHARS_V1=128,EMPTY_SNAPSHOT=Object.freeze({version:PLUGIN_STATE_SNAPSHOT_VERSION_V1,records:Object.freeze([])});function diagnostic3(code,message,identity){return Object.freeze(identity===void 0?{code,message}:{code,message,identity})}function isAbortError(error2){return error2 instanceof Error&&(error2.name==="AbortError"||error2.name==="AbortSignalError")}function isMissingError(error2){return typeof error2!="object"||error2===null?!1:"code"in error2&&error2.code==="ENOENT"}function validateFilePath(value){if(typeof value!="string"||value.trim()===""||value.length>MAX_PLUGIN_STATE_STRING_CHARS_V1)throw new Error("invalid plugin state file path");if(value.includes("\0")||/[\u0000-\u001f]/u.test(value))throw new Error("invalid plugin state file path");if(/^file:/iu.test(value)||/^[a-z][a-z\d+.-]*:/iu.test(value)&&!/^[a-z]:[\\/]/iu.test(value))throw new Error("invalid plugin state file path");let normalized=isAbsolute3(value)?value:resolve3(value);if(basename2(normalized).length===0||basename2(normalized)==="."||basename2(normalized)==="..")throw new Error("invalid plugin state file path");return normalized}function validateOpaqueInstallationRef(value){if(typeof value!="string"||value.trim()===""||value.length>MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1)throw new Error("invalid installation reference");if(/^(?:file:|[a-zA-Z]:[\\/]|[\\/]{1,2}|\\\\)/u.test(value)||/\s/u.test(value))throw new Error("invalid installation reference");if(value.includes("\0")||/[\u0000-\u001f]/u.test(value))throw new Error("invalid installation reference");return value}function validateScopeRef(scope,value){if(typeof value!="string"||value.trim()===""||value.length>MAX_PLUGIN_SCOPE_REF_CHARS_V1)throw new Error("invalid plugin scope reference");if(/^(?:file:|[a-zA-Z]:[\\/]|[\\/]{1,2}|\\\\)/u.test(value)||/\s/u.test(value))throw new Error("invalid plugin scope reference");if(value.includes("\0")||/[\u0000-\u001f]/u.test(value))throw new Error("invalid plugin scope reference");if(scope==="global"&&value!==DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)throw new Error("invalid plugin scope reference");return value}function validateString(value,label,max=MAX_PLUGIN_STATE_STRING_CHARS_V1){if(typeof value!="string"||value.trim().length===0||value.length>max||/[\u0000-\u001f]/u.test(value))throw new Error(`${label} is invalid`);return value}function validateSourceLabel(value){if(typeof value!="string"||value.length===0||value.length>MAX_PLUGIN_STATE_SOURCE_CHARS_V1||!/^[a-z][a-z0-9.:[\]_/@-]*$/u.test(value))throw new Error("record source label is invalid");return value}function identityOf(record){return`${record.state.scope}:${record.state.scopeRef}:${record.pluginId}@${record.pluginVersion}`}function isObject2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function hasExactKeys2(value,keys){let expected=new Set(keys);return Object.keys(value).length===expected.size&&Object.keys(value).every(key=>expected.has(key))}function validateRecord2(value){let requiredKeys=["pluginId","pluginVersion","manifestDigest","installationRef","state"],allowedKeys=new Set([...requiredKeys,"source"]);if(!isObject2(value)||Object.keys(value).some(key=>!allowedKeys.has(key)))throw new Error("record schema is invalid");for(let key of requiredKeys)if(!(key in value))throw new Error("record schema is invalid");let pluginId=validateString(value.pluginId,"pluginId",MAX_PLUGIN_STATE_ID_CHARS_V1),pluginVersion=validateString(value.pluginVersion,"pluginVersion",MAX_PLUGIN_STATE_ID_CHARS_V1),manifestDigest=validateString(value.manifestDigest,"manifestDigest"),installationRef=validateOpaqueInstallationRef(value.installationRef),source=value.source===void 0?void 0:validateSourceLabel(value.source);if(!isObject2(value.state)||!hasExactKeys2(value.state,["scope","scopeRef","enabled","lifecycle"]))throw new Error("state schema is invalid");if(value.state.scope!=="global"&&value.state.scope!=="project")throw new Error("state scope is invalid");let scopeRef=validateScopeRef(value.state.scope,value.state.scopeRef);if(typeof value.state.enabled!="boolean")throw new Error("state enabled flag is invalid");if(value.state.lifecycle!=="installed"&&value.state.lifecycle!=="active"&&value.state.lifecycle!=="retained")throw new Error("state lifecycle is invalid");return Object.freeze({pluginId,pluginVersion,manifestDigest,installationRef,...source===void 0?{}:{source},state:Object.freeze({scope:value.state.scope,scopeRef,enabled:value.state.enabled,lifecycle:value.state.lifecycle})})}function validateSnapshot(value){if(!isObject2(value)||!hasExactKeys2(value,["version","records"]))throw new Error("snapshot schema is invalid");if(value.version!==PLUGIN_STATE_SNAPSHOT_VERSION_V1)throw new Error("snapshot version is unsupported");if(!Array.isArray(value.records))throw new Error("records must be an array");if(value.records.length>MAX_PLUGIN_STATE_RECORDS_V1)throw new Error("too many plugin state records");let records=value.records.map(validateRecord2),identities=new Set;for(let record of records){let identity=identityOf(record);if(identities.has(identity))throw new Error(`duplicate identity: ${identity}`);identities.add(identity)}return records.sort((left,right)=>identityOf(left).localeCompare(identityOf(right))),Object.freeze({version:PLUGIN_STATE_SNAPSHOT_VERSION_V1,records:Object.freeze(records)})}function invalidFromError(error2){let message=error2 instanceof Error?error2.message:"plugin state schema is invalid",duplicatePrefix="duplicate identity: ";return message.startsWith(duplicatePrefix)?diagnostic3("duplicate_identity",message,message.slice(duplicatePrefix.length)):diagnostic3(message==="too many plugin state records"?"too_many_records":message==="invalid installation reference"?"invalid_installation_ref":"invalid_schema",message)}function defaultFileSystem(){return{readFile:async path15=>await readFile3(path15,"utf8"),mkdir:async path15=>{await mkdir(path15,{recursive:!0})},writeFile:async(path15,data)=>{await writeFile(path15,data,"utf8")},rename,unlink}}function cancelledResult(){return Object.freeze({status:"cancelled",diagnostics:Object.freeze([diagnostic3("cancelled","Plugin state operation was cancelled")])})}function sortRecords(records){return Object.freeze([...records].sort((left,right)=>identityOf(left).localeCompare(identityOf(right))))}function makeRecord(installation,scope,enabled,source){if(installation.version!==1)throw new Error("plugin installation handle is invalid");let pluginId=validateString(installation.pluginId,"pluginId",MAX_PLUGIN_STATE_ID_CHARS_V1),pluginVersion=validateString(installation.pluginVersion,"pluginVersion",MAX_PLUGIN_STATE_ID_CHARS_V1),manifestDigest=validateString(installation.manifestDigest,"manifestDigest"),installationRef=validateOpaqueInstallationRef(installation.installationRef);if(scope!=="global"&&scope!=="project")throw new Error("state scope is invalid");if(installation.scope!==scope)throw new Error("installation scope does not match state scope");let scopeRef=validateScopeRef(scope,scope==="global"?installation.scopeRef??DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1:installation.scopeRef);if(typeof enabled!="boolean")throw new Error("state enabled flag is invalid");let sourceLabel=source===void 0?void 0:validateSourceLabel(source);return Object.freeze({pluginId,pluginVersion,manifestDigest,installationRef,...sourceLabel===void 0?{}:{source:sourceLabel},state:Object.freeze({scope,scopeRef,enabled,lifecycle:installation.state})})}function createPluginStateStoreV1(options){let filePath=validateFilePath(options.filePath),fileSystem=options.fileSystem??defaultFileSystem();async function read(signal){if(signal?.aborted)return cancelledResult();let content;try{content=await fileSystem.readFile(filePath)}catch(error2){if(isMissingError(error2))return Object.freeze({status:"missing",snapshot:EMPTY_SNAPSHOT});if(isAbortError(error2)||signal?.aborted)return cancelledResult();throw error2}if(signal?.aborted)return cancelledResult();let parsed;try{parsed=JSON.parse(content)}catch{return Object.freeze({status:"invalid",diagnostics:Object.freeze([diagnostic3("invalid_json","plugin state JSON is invalid")])})}try{return Object.freeze({status:"ok",snapshot:validateSnapshot(parsed)})}catch(error2){return Object.freeze({status:"invalid",diagnostics:Object.freeze([invalidFromError(error2)])})}}async function write(snapshot2,signal){if(signal?.aborted)return cancelledResult();let parent=dirname6(filePath),temporaryPath=join12(parent,`.${basename2(filePath)}.${randomUUID3()}.tmp`);try{return await fileSystem.mkdir(parent),signal?.aborted||(await fileSystem.writeFile(temporaryPath,`${JSON.stringify(snapshot2)}
506
506
  `),signal?.aborted)?cancelledResult():(await fileSystem.rename(temporaryPath,filePath),Object.freeze({status:"ok",snapshot:snapshot2,changed:!0}))}finally{try{await fileSystem.unlink(temporaryPath)}catch{}}}let mutationTail=Promise.resolve();function enqueueMutation(operation){let result=mutationTail.then(operation,operation);return mutationTail=result.then(()=>{},()=>{}),result}return{read:async({signal}={})=>await read(signal),upsert:input=>enqueueMutation(async()=>{let record;try{record=makeRecord(input.installation,input.scope,input.enabled,input.source)}catch(error2){return Object.freeze({status:"invalid",diagnostics:Object.freeze([invalidFromError(error2)])})}let current=await read(input.signal);if(current.status!=="ok"&&current.status!=="missing")return current;if(input.signal?.aborted)return cancelledResult();let records=current.snapshot.records.filter(candidate=>identityOf(candidate)!==identityOf(record));if(records.length>=MAX_PLUGIN_STATE_RECORDS_V1&&!current.snapshot.records.some(candidate=>identityOf(candidate)===identityOf(record)))return Object.freeze({status:"invalid",diagnostics:Object.freeze([diagnostic3("too_many_records","too many plugin state records")])});let snapshot2=Object.freeze({version:PLUGIN_STATE_SNAPSHOT_VERSION_V1,records:sortRecords([...records,record])});return await write(snapshot2,input.signal)}),remove:input=>enqueueMutation(async()=>{let pluginId,pluginVersion,scope,scopeRef;try{if(pluginId=validateString(input.pluginId,"pluginId",MAX_PLUGIN_STATE_ID_CHARS_V1),pluginVersion=validateString(input.pluginVersion,"pluginVersion",MAX_PLUGIN_STATE_ID_CHARS_V1),input.scope!=="global"&&input.scope!=="project")throw new Error("state scope is invalid");scope=input.scope,scopeRef=validateScopeRef(scope,input.scopeRef)}catch(error2){return Object.freeze({status:"invalid",diagnostics:Object.freeze([invalidFromError(error2)])})}let current=await read(input.signal);if(current.status!=="ok"&&current.status!=="missing")return current;if(input.signal?.aborted)return cancelledResult();let identity=`${scope}:${scopeRef}:${pluginId}@${pluginVersion}`,records=current.snapshot.records.filter(candidate=>identityOf(candidate)!==identity);if(records.length===current.snapshot.records.length)return Object.freeze({status:"ok",snapshot:current.snapshot,changed:!1});let snapshot2=Object.freeze({version:PLUGIN_STATE_SNAPSHOT_VERSION_V1,records:sortRecords(records)});return await write(snapshot2,input.signal)})}}var DEFAULT_PLUGIN_INSTALL_STORE_DIR_V1="plugin-install-store-v1",DEFAULT_PLUGIN_STATE_FILE_V1="plugin-state.json";function projectPluginScopeRefV1(cwd){let canonicalPath=resolve4(cwd),identityPath=process.platform==="win32"?canonicalPath.toLowerCase():canonicalPath;return`project:sha256:${createHash("sha256").update(identityPath).digest("hex")}`}function defaultPluginInstallStoreDirectoryV1(agentDir){return join13(agentDir,DEFAULT_PLUGIN_INSTALL_STORE_DIR_V1)}function defaultPluginInstallStoreInstanceRootV1(agentDir){return join13(defaultPluginInstallStoreDirectoryV1(agentDir),"agent-forge-plugin-install-store-v1")}function defaultPluginHostFactsV1(){return{os:process.platform==="win32"?"windows":process.platform==="darwin"?"macos":process.platform,arch:process.arch,runtime:[{name:"node",version:process.versions.node}],apiVersion:"1",hostFeatures:[]}}function digestOnlyVerifierV1(){return{verify:({manifestDigest,expectedDigest:expectedDigest2})=>expectedDigest2===void 0||expectedDigest2===manifestDigest?{status:"accepted"}:{status:"rejected",reason:"Manifest digest does not match the expected digest"}}}function installStoreSourceVerifierV1(){return()=>({status:"accepted"})}function createDefaultActivePluginBindingsResolverV1(){return async input=>{let registrySource=createNodeDiskPluginRegistrySourceV1({rootDirectory:defaultPluginInstallStoreInstanceRootV1(input.agentDir)}),registry=createPluginRegistryV1({source:registrySource,host:defaultPluginHostFactsV1(),verify:digestOnlyVerifierV1(),sourceVerifier:installStoreSourceVerifierV1()});return await resolveActivePluginBindingsForScopesV1({registry,...registrySource.resolveCapabilityManifestPath===void 0?{}:{resolveInstallationManifestPath:registrySource.resolveCapabilityManifestPath},project:{stateStore:createPluginStateStoreV1({filePath:join13(input.cwd,CONFIG_DIR_NAME,DEFAULT_PLUGIN_STATE_FILE_V1)}),scope:"project",scopeRef:projectPluginScopeRefV1(input.cwd)},global:{stateStore:createPluginStateStoreV1({filePath:join13(input.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)}),scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1}})}}import{join as join18}from"node:path";import{createHash as createHash2,randomUUID as randomUUID4}from"node:crypto";import{createReadStream}from"node:fs";import{mkdir as mkdir2,mkdtemp,open as open3,rename as rename2,rm}from"node:fs/promises";import{tmpdir}from"node:os";import{isAbsolute as isAbsolute4,join as join14}from"node:path";import{createPublicKey,verify}from"node:crypto";var NODE_PLUGIN_TRUST_ROOT_VERSION_V1=1,MAX_KEY_ID_CHARS_V1=128,MAX_KEYS_V1=256,SIGNATURE_PREFIX_V1="ed25519-v1";function validKeyId(value){return value.length>0&&value.length<=MAX_KEY_ID_CHARS_V1&&/^[A-Za-z0-9_-]+$/u.test(value)}function parseValidity(value,label){if(value===void 0)return;if(!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/u.test(value))throw new Error(`${label} must be an ISO-8601 UTC timestamp`);let timestamp=Date.parse(value);if(!Number.isFinite(timestamp)||new Date(timestamp).toISOString()!==value)throw new Error(`${label} must be a valid ISO-8601 UTC timestamp`);return timestamp}function parsePublicKey(value){if(value.length===0||value.length>16*1024||/\u0000/u.test(value))throw new Error("publicKeyPem is invalid");let key;try{key=createPublicKey(value)}catch{throw new Error("publicKeyPem is invalid")}if(key.type!=="public"||key.asymmetricKeyType!=="ed25519")throw new Error("publicKeyPem must be an Ed25519 public key");return key}function payload(input){return Buffer.from(`agent-forge-plugin-distribution-v${NODE_PLUGIN_TRUST_ROOT_VERSION_V1}
507
507
  ${JSON.stringify([input.version,input.source,input.pluginId,input.pluginVersion,input.manifestDigest,input.artifactDigest,input.expiresAt,input.sizeBytes,input.mediaType])}`,"utf8")}function buildNodePluginDistributionSignaturePayloadV1(input){return new Uint8Array(payload(input))}function parseSignature(value){let parts=value.split(".");if(parts.length!==3||parts[0]!==SIGNATURE_PREFIX_V1||!validKeyId(parts[1]??""))return;let encoded=parts[2]??"";if(!/^[A-Za-z0-9_-]+$/u.test(encoded))return;let bytes=Buffer.from(encoded,"base64url");if(bytes.byteLength===64)return{keyId:parts[1],bytes}}function validAt(key,current){return(key.notBefore===void 0||current>=key.notBefore)&&(key.notAfter===void 0||current<key.notAfter)}function createNodePluginTrustRootV1(options){if(!Array.isArray(options.keys)||options.keys.length===0||options.keys.length>MAX_KEYS_V1)throw new Error(`keys must contain between 1 and ${MAX_KEYS_V1} entries`);let revokedKeyIds=new Set(options.revokedKeyIds??[]);if([...revokedKeyIds].some(keyId=>!validKeyId(keyId))||options.revokedKeyIds!==void 0&&revokedKeyIds.size!==options.revokedKeyIds.length)throw new Error("revokedKeyIds is invalid or duplicated");let keys=new Map;for(let input of options.keys){if(!validKeyId(input.keyId)||keys.has(input.keyId))throw new Error("keyId is invalid or duplicated");let notBefore=parseValidity(input.notBefore,"notBefore"),notAfter=parseValidity(input.notAfter,"notAfter");if(notBefore!==void 0&&notAfter!==void 0&&notBefore>=notAfter)throw new Error("notBefore must be earlier than notAfter");keys.set(input.keyId,{keyId:input.keyId,publicKey:parsePublicKey(input.publicKeyPem),...notBefore===void 0?{}:{notBefore},...notAfter===void 0?{}:{notAfter}})}let now=options.now??(()=>Date.now());return({descriptor})=>{let signature=parseSignature(descriptor.signature);if(signature===void 0)return{status:"rejected"};let key=keys.get(signature.keyId);if(key===void 0||revokedKeyIds.has(signature.keyId))return{status:"rejected"};let current;try{current=now()}catch{return{status:"rejected"}}if(!Number.isFinite(current)||!validAt(key,current))return{status:"rejected"};try{return verify(null,payload(descriptor),key.publicKey,signature.bytes)?{status:"accepted"}:{status:"rejected"}}catch{return{status:"rejected"}}}}var NODE_DISTRIBUTION_HOST_VERSION_V1=1,DEFAULT_TIMEOUT_MS_V1=3e4,MAX_TIMEOUT_MS_V1=12e4,DEFAULT_REDIRECTS_V1=3,MAX_REDIRECTS_V1=5,REDIRECT_STATUS=new Set([301,302,303,307,308]);function cancelledRequestError(){let error2=new Error("plugin request was cancelled");return error2.name="AbortError",error2}function throwIfRequestCancelled(request){if(request.timedOut())throw new Error("plugin request timed out");if(request.signal.aborted)throw cancelledRequestError()}function boundedPositive(value,fallback,maximum,label){let result=value??fallback;if(!Number.isSafeInteger(result)||result<=0||result>maximum)throw new Error(`${label} must be a positive integer at most ${maximum}`);return result}function allowedOrigin(value){let parsed;try{parsed=new URL(value)}catch{throw new Error("allowed origin is invalid")}if(parsed.protocol!=="http:"&&parsed.protocol!=="https:"||parsed.username||parsed.password)throw new Error("allowed origin must be an http(s) origin");if(parsed.pathname!=="/"||parsed.search!==""||parsed.hash!=="")throw new Error("allowed origin must not include a path or query");return parsed.origin}function requestUrl(value,origins){let parsed;try{parsed=new URL(value)}catch{throw new Error("plugin source URL is invalid")}if(parsed.protocol!=="http:"&&parsed.protocol!=="https:"||parsed.username||parsed.password)throw new Error("plugin source URL must use http(s) without credentials");if(!origins.has(parsed.origin))throw new Error("plugin source origin is not allowed");return parsed}function requestSignal(parent,timeoutMs){let controller=new AbortController,didTimeout=!1,abort=()=>controller.abort(parent?.reason);parent?.aborted===!0?abort():parent?.addEventListener("abort",abort,{once:!0});let timeout=setTimeout(()=>{didTimeout=!0,controller.abort()},timeoutMs);return{signal:controller.signal,timedOut:()=>didTimeout,cleanup:()=>{clearTimeout(timeout),parent?.removeEventListener("abort",abort)}}}function contentLength(response2){let value=response2.headers.get("content-length");if(value===null)return;if(!/^\d+$/u.test(value))throw new Error("plugin response content length is invalid");let result=Number(value);if(!Number.isSafeInteger(result))throw new Error("plugin response content length is invalid");return result}function contentType(response2){let value=response2.headers.get("content-type");if(value!==null)return value.split(";",1)[0]?.trim().toLowerCase()||void 0}function assertResponseMetadata(response2,descriptor){if(contentLength(response2)!==descriptor.sizeBytes)throw new Error("plugin response size mismatch");if(contentType(response2)!==descriptor.mediaType.toLowerCase())throw new Error("plugin response media type mismatch")}async function cancelBody(response2){response2.body!==null&&await response2.body.cancel().catch(()=>{})}function expectedDigest(value){let prefixed=/^(sha256|sha512):([0-9a-f]+)$/iu.exec(value);if(prefixed!==null){let algorithm=prefixed[1]?.toLowerCase(),hex=prefixed[2]?.toLowerCase();if(algorithm==="sha256"&&hex?.length===64||algorithm==="sha512"&&hex?.length===128)return{algorithm,hex}}if(/^[0-9a-f]{64}$/iu.test(value))return{algorithm:"sha256",hex:value.toLowerCase()};if(/^[0-9a-f]{128}$/iu.test(value))return{algorithm:"sha512",hex:value.toLowerCase()};throw new Error("plugin artifact digest algorithm is unsupported")}function metadataFromDescriptor(descriptor){return{version:1,source:descriptor.source,pluginId:descriptor.pluginId,pluginVersion:descriptor.pluginVersion,manifestDigest:descriptor.manifestDigest,artifactDigest:descriptor.artifactDigest,expiresAt:descriptor.expiresAt,sizeBytes:descriptor.sizeBytes,mediaType:descriptor.mediaType}}function artifactMatchesDescriptor(artifact,descriptor){return artifact.version===1&&artifact.pluginId===descriptor.pluginId&&artifact.pluginVersion===descriptor.pluginVersion&&artifact.manifestDigest===descriptor.manifestDigest&&artifact.artifactDigest===descriptor.artifactDigest&&artifact.sizeBytes===descriptor.sizeBytes&&artifact.mediaType===descriptor.mediaType&&artifact.source===descriptor.source&&artifact.expiresAt===descriptor.expiresAt}async function writeFully(file,chunk){let offset=0;for(;offset<chunk.byteLength;){let result=await file.write(chunk,offset,chunk.byteLength-offset,null);if(result.bytesWritten<=0)throw new Error("plugin artifact file write failed");offset+=result.bytesWritten}}async function createNodeHttpPluginDistributionHostV1(options){let transport=options.fetch??globalThis.fetch;if(typeof transport!="function")throw new Error("Node fetch is unavailable");if(!Array.isArray(options.allowedOrigins)||options.allowedOrigins.length===0)throw new Error("at least one allowed origin is required");let origins=new Set(options.allowedOrigins.map(allowedOrigin)),timeoutMs=boundedPositive(options.requestTimeoutMs,DEFAULT_TIMEOUT_MS_V1,MAX_TIMEOUT_MS_V1,"requestTimeoutMs"),maxRedirects=options.maxRedirects??DEFAULT_REDIRECTS_V1;if(!Number.isSafeInteger(maxRedirects)||maxRedirects<0||maxRedirects>MAX_REDIRECTS_V1)throw new Error(`maxRedirects must be an integer between 0 and ${MAX_REDIRECTS_V1}`);let userAgent=options.userAgent??"agent-forge-plugin-distribution/1";if(userAgent.length===0||userAgent.length>256||/[\r\n]/u.test(userAgent))throw new Error("userAgent is invalid");let configuredDirectory=options.artifactDirectory;if(configuredDirectory!==void 0&&!isAbsolute4(configuredDirectory))throw new Error("artifactDirectory must be absolute");let baseDirectoryPromise=configuredDirectory===void 0?mkdtemp(join14(tmpdir(),"agent-forge-plugin-distribution-")):(async()=>(await mkdir2(configuredDirectory,{recursive:!0}),await mkdtemp(join14(configuredDirectory,"agent-forge-plugin-distribution-"))))(),artifacts=new Map,activeOperations=new Set,operationsDrained,closePromise,closed=!1,assertOpen=()=>{if(closed)throw new Error("plugin distribution host is closed")},beginOperation=()=>{assertOpen();let controller=new AbortController;return activeOperations.add(controller),controller},endOperation=controller=>{activeOperations.delete(controller),activeOperations.size===0&&(operationsDrained?.(),operationsDrained=void 0)},waitForOperations=async()=>{activeOperations.size!==0&&await new Promise(resolve25=>{operationsDrained=resolve25})},fetchResponse=async(value,method,parentSignal,operationSignal2)=>{let current=requestUrl(value,origins);for(let redirect=0;;redirect+=1){if(operationSignal2.aborted)throw cancelledRequestError();assertOpen();let request=requestSignal(AbortSignal.any([parentSignal,operationSignal2].filter(Boolean)),timeoutMs),response2;try{response2=await transport(current.toString(),{method,headers:{accept:"*/*","user-agent":userAgent},redirect:"manual",signal:request.signal})}catch(error2){throw request.cleanup(),throwIfRequestCancelled(request),error2}if(!REDIRECT_STATUS.has(response2.status))return{response:response2,request};let location=response2.headers.get("location");if(await cancelBody(response2),request.cleanup(),location===null||redirect>=maxRedirects)throw new Error("plugin redirect limit exceeded");current=requestUrl(new URL(location,current).toString(),origins)}};return{version:NODE_DISTRIBUTION_HOST_VERSION_V1,host:{resolveMetadata:async input=>{let operation=beginOperation();try{let{response:response2,request}=await fetchResponse(input.descriptor.source,"HEAD",input.signal,operation.signal);try{if(response2.status<200||response2.status>=300)throw new Error("plugin metadata request failed");return assertResponseMetadata(response2,input.descriptor),metadataFromDescriptor(input.descriptor)}finally{await cancelBody(response2),request.cleanup()}}finally{endOperation(operation)}},acquireArtifact:async input=>{let operation=beginOperation(),temporaryPath,finalPath,published=!1;try{let digest=expectedDigest(input.descriptor.artifactDigest),{response:response2,request}=await fetchResponse(input.descriptor.source,"GET",input.signal,operation.signal),file;try{if(response2.status<200||response2.status>=300)throw new Error("plugin artifact request failed");if(assertResponseMetadata(response2,input.descriptor),response2.body===null)throw new Error("plugin artifact response has no body");let directory=await baseDirectoryPromise;temporaryPath=join14(directory,`.partial-${randomUUID4()}`),finalPath=join14(directory,`artifact-${randomUUID4()}`),file=await open3(temporaryPath,"wx");let reader=response2.body.getReader(),hash=createHash2(digest.algorithm),total=0;try{for(;;){throwIfRequestCancelled(request);let item=await reader.read();if(item.done)break;let chunk=item.value;if(total+=chunk.byteLength,total>input.descriptor.sizeBytes)throw new Error("plugin artifact exceeds its size limit");hash.update(chunk),await writeFully(file,chunk)}}finally{reader.releaseLock()}if(throwIfRequestCancelled(request),total!==input.descriptor.sizeBytes)throw new Error("plugin artifact size mismatch");if(hash.digest("hex")!==digest.hex)throw new Error("plugin artifact digest mismatch");await file.close(),file=void 0,await rename2(temporaryPath,finalPath),assertOpen();let artifactRef=`artifact://node-http/${randomUUID4()}`;return artifacts.set(artifactRef,{path:finalPath,descriptor:input.descriptor,readers:0}),published=!0,{artifactRef,artifactDigest:input.descriptor.artifactDigest,sizeBytes:input.descriptor.sizeBytes,mediaType:input.descriptor.mediaType}}catch(error2){throw throwIfRequestCancelled(request),error2}finally{file!==void 0&&await file.close().catch(()=>{}),await cancelBody(response2),request.cleanup()}}finally{temporaryPath!==void 0&&await rm(temporaryPath,{force:!0}).catch(()=>{}),!published&&finalPath!==void 0&&await rm(finalPath,{force:!0}).catch(()=>{}),endOperation(operation)}},releaseArtifact:async input=>{if(assertOpen(),input.signal?.aborted)throw new Error("plugin artifact release was cancelled");let record=artifacts.get(input.artifact.artifactRef);if(record===void 0)throw new Error("plugin artifact reference is unknown");if(record.readers>0)throw new Error("plugin artifact is still being read");await rm(record.path,{force:!1}),artifacts.delete(input.artifact.artifactRef)}},openArtifact:input=>(async function*(){let operation=beginOperation(),stream,acquiredRecord,abort=()=>stream?.destroy(new Error("plugin artifact read was cancelled"));try{if(input.signal?.aborted)throw new Error("plugin artifact read was cancelled");let record=artifacts.get(input.artifact.artifactRef);if(record===void 0||!artifactMatchesDescriptor(input.artifact,record.descriptor))throw new Error("plugin artifact reference is unknown");record.readers+=1,acquiredRecord=record,stream=createReadStream(record.path,{highWaterMark:64*1024}),input.signal?.addEventListener("abort",abort,{once:!0}),operation.signal.addEventListener("abort",abort,{once:!0});for await(let chunk of stream){if(input.signal?.aborted||operation.signal.aborted)throw new Error("plugin artifact read was cancelled");yield new Uint8Array(chunk)}}finally{input.signal?.removeEventListener("abort",abort),operation.signal.removeEventListener("abort",abort),stream?.destroy(),acquiredRecord!==void 0&&acquiredRecord.readers>0&&(acquiredRecord.readers-=1),endOperation(operation)}})(),close:async()=>{if(closePromise!==void 0)return await closePromise;closed=!0;for(let operation of activeOperations)operation.abort();return closePromise=(async()=>{await waitForOperations();let directory=await baseDirectoryPromise;await Promise.all([...artifacts.values()].map(record=>rm(record.path,{force:!0}))),artifacts.clear(),await rm(directory,{recursive:!0,force:!0})})(),await closePromise}}}async function createNodeHttpPluginDistributionStackV1(options){let{trustRoot,now:configuredNow,...hostOptions}=options,host=await createNodeHttpPluginDistributionHostV1(hostOptions);try{let now=configuredNow??trustRoot.now??(()=>Date.now()),verifySignature=createNodePluginTrustRootV1({...trustRoot,now}),distribution=createPluginDistributionV1({host:host.host,verifySignature,now});return Object.freeze({...host,distribution})}catch(error2){throw await host.close().catch(()=>{}),error2}}import{createHash as createHash3,randomUUID as randomUUID6}from"node:crypto";import{mkdir as mkdir4,mkdtemp as mkdtemp2,rename as rename4,rm as rm3,writeFile as writeFile3}from"node:fs/promises";import{tmpdir as tmpdir2}from"node:os";import{isAbsolute as isAbsolute6,join as join16}from"node:path";import{inflateRawSync}from"node:zlib";import{randomUUID as randomUUID5}from"node:crypto";import{mkdir as mkdir3,open as open4,readFile as readFile4,rename as rename3,rm as rm2,writeFile as writeFile2}from"node:fs/promises";import{isAbsolute as isAbsolute5,join as join15,relative as relative3}from"node:path";var PERSISTENCE_VERSION_V1=1,DEFAULT_LOCK_TIMEOUT_MS_V1=5e3,MAX_LOCK_TIMEOUT_MS_V1=6e4,MAX_RECORDS_V1=8192,MAX_FIELD_CHARS_V1=2048,NodePackageInstallPersistenceErrorV1=class extends Error{code;constructor(code){super(`Node package install persistence failed: ${code}`),this.name="NodePackageInstallPersistenceErrorV1",this.code=code}},INDEX_FILE_V12="index.v1.json",LOCK_FILE_V1="index.v1.lock";function positiveLockTimeout(value){let result=value??DEFAULT_LOCK_TIMEOUT_MS_V1;if(!Number.isSafeInteger(result)||result<1||result>MAX_LOCK_TIMEOUT_MS_V1)throw new Error(`lockTimeoutMs must be a positive integer at most ${MAX_LOCK_TIMEOUT_MS_V1}`);return result}function field(value){return typeof value=="string"&&value.length>0&&value.length<=MAX_FIELD_CHARS_V1&&!/[\u0000-\u001f\u007f]/u.test(value)}function opaque(value){return field(value)&&!/\s/u.test(value)&&!/^(?:file:|[a-z]:[\\/]|[\\/]{1,2}|\\\\)/iu.test(value)}function withinRoot2(root,value){if(!isAbsolute5(value))return!1;let relativePath=relative3(root,value);return relativePath!==""&&!relativePath.startsWith("..")&&!isAbsolute5(relativePath)}function recordKey(record){return`${record.scope}\0${record.scopeRef}\0${record.pluginId}`}function validateRecord3(root,value){if(value===null||typeof value!="object"||Array.isArray(value))throw new NodePackageInstallPersistenceErrorV1("invalid_state");let record=value,keys=["installationRef","directory","pluginId","pluginVersion","manifestDigest","scope","scopeRef","state"];if(Object.keys(record).length!==keys.length||keys.some(key=>!(key in record)))throw new NodePackageInstallPersistenceErrorV1("invalid_state");if(!opaque(record.installationRef)||!field(record.directory)||!field(record.pluginId)||!field(record.pluginVersion)||!field(record.manifestDigest)||!opaque(record.scopeRef)||record.scope!=="global"&&record.scope!=="project"||record.state!=="installed"&&record.state!=="active"&&record.state!=="retained"||!withinRoot2(root,record.directory))throw new NodePackageInstallPersistenceErrorV1("invalid_state");return Object.freeze({installationRef:record.installationRef,directory:record.directory,pluginId:record.pluginId,pluginVersion:record.pluginVersion,manifestDigest:record.manifestDigest,scope:record.scope,scopeRef:record.scopeRef,state:record.state})}function snapshot(root,values){if(values.length>MAX_RECORDS_V1)throw new NodePackageInstallPersistenceErrorV1("invalid_state");let byRef=new Set,active=new Set,result=values.map(value=>validateRecord3(root,value));for(let record of result){if(byRef.has(record.installationRef))throw new NodePackageInstallPersistenceErrorV1("invalid_state");if(byRef.add(record.installationRef),record.state==="active"){let key=recordKey(record);if(active.has(key))throw new NodePackageInstallPersistenceErrorV1("invalid_state");active.add(key)}}return Object.freeze(result)}function parseIndex2(root,raw){let parsed;try{parsed=JSON.parse(raw)}catch{throw new NodePackageInstallPersistenceErrorV1("invalid_state")}if(parsed===null||typeof parsed!="object"||Array.isArray(parsed))throw new NodePackageInstallPersistenceErrorV1("invalid_state");let value=parsed;if(Object.keys(value).length!==2||value.version!==PERSISTENCE_VERSION_V1||!Array.isArray(value.records))throw new NodePackageInstallPersistenceErrorV1("invalid_state");return snapshot(root,value.records)}function serialize(root,records){return JSON.stringify({version:PERSISTENCE_VERSION_V1,records:snapshot(root,records)})}function delay(milliseconds,signal){return new Promise((resolve25,reject2)=>{let timer=setTimeout(resolve25,milliseconds);if(signal===void 0)return;let abort=()=>{clearTimeout(timer),reject2(new NodePackageInstallPersistenceErrorV1("cancelled"))};signal.aborted?abort():signal.addEventListener("abort",abort,{once:!0})})}async function createNodePackageInstallPersistenceV1(options){if(!isAbsolute5(options.rootDirectory))throw new Error("rootDirectory must be absolute");let lockTimeoutMs=positiveLockTimeout(options.lockTimeoutMs),rootDirectory=options.rootDirectory,indexPath=join15(rootDirectory,INDEX_FILE_V12),lockPath=join15(rootDirectory,LOCK_FILE_V1);await mkdir3(rootDirectory,{recursive:!0,mode:448});let closed=!1,closePromise,read=async()=>{try{return parseIndex2(rootDirectory,await readFile4(indexPath,"utf8"))}catch(error2){if(error2 instanceof NodePackageInstallPersistenceErrorV1)throw error2;if(error2 instanceof Error&&"code"in error2&&error2.code==="ENOENT")return Object.freeze([]);throw new NodePackageInstallPersistenceErrorV1("io_failed")}},acquire=async signal=>{let deadline=Date.now()+lockTimeoutMs;for(;;){if(signal?.aborted)throw new NodePackageInstallPersistenceErrorV1("cancelled");try{return await open4(lockPath,"wx",384)}catch(error2){if(!(error2 instanceof Error&&"code"in error2&&error2.code==="EEXIST"))throw new NodePackageInstallPersistenceErrorV1("io_failed");if(Date.now()>=deadline)throw new NodePackageInstallPersistenceErrorV1("busy");await delay(10,signal)}}},release=async handle=>{await handle.close().catch(()=>{}),await rm2(lockPath,{force:!0}).catch(()=>{})},write=async records=>{let temporary=`${indexPath}.${randomUUID5()}.tmp`;try{await writeFile2(temporary,serialize(rootDirectory,records),{flag:"wx",mode:384}),await rename3(temporary,indexPath)}catch{throw await rm2(temporary,{force:!0}).catch(()=>{}),new NodePackageInstallPersistenceErrorV1("io_failed")}};return{rootDirectory,load:async(input={})=>{if(closed)throw new NodePackageInstallPersistenceErrorV1("closed");if(input.signal?.aborted)throw new NodePackageInstallPersistenceErrorV1("cancelled");return await read()},mutate:async input=>{if(closed)throw new NodePackageInstallPersistenceErrorV1("closed");if(typeof input.update!="function")throw new NodePackageInstallPersistenceErrorV1("invalid_state");let handle=await acquire(input.signal);try{let current=await read(),records=new Map(current.map(record=>[record.installationRef,record]));await input.update(records);let result=snapshot(rootDirectory,[...records.values()]);return await write(result),result}finally{await release(handle)}},close:async()=>closePromise!==void 0?await closePromise:(closed=!0,closePromise=Promise.resolve(),await closePromise)}}import{createGunzip}from"node:zlib";var TAR_BLOCK_BYTES_V1=512,TAR_NAME_LENGTH_V1=100,TAR_SIZE_OFFSET_V1=124,TAR_SIZE_LENGTH_V1=12,TAR_CHECKSUM_OFFSET_V1=148,TAR_CHECKSUM_LENGTH_V1=8,TAR_TYPEFLAG_OFFSET_V1=156,TAR_MAGIC_OFFSET_V1=257,TAR_PREFIX_OFFSET_V1=345,TAR_PREFIX_LENGTH_V1=155,USTAR_MAGIC_V1=[117,115,116,97,114];function readHeaderString(bytes,offset,length){let end=offset+length,stop=offset;for(;stop<end&&bytes[stop]!==0;)stop+=1;try{return new TextDecoder("utf-8",{fatal:!0}).decode(bytes.subarray(offset,stop))}catch{throw new NodePackageInstallErrorV1("archive_invalid")}}function readOctalHeaderField(header,offset,length){let end=offset+length,start=offset;for(;start<end&&header[start]===32;)start+=1;let stop=end;for(;stop>start&&(header[stop-1]===0||header[stop-1]===32);)stop-=1;let value=0;for(let index3=start;index3<stop;index3+=1){let byte=header[index3];if(byte<48||byte>55)throw new NodePackageInstallErrorV1("archive_invalid");if(value=value*8+(byte-48),value>Number.MAX_SAFE_INTEGER)throw new NodePackageInstallErrorV1("archive_invalid")}return value}function verifyHeaderChecksum(header){let sum=0;for(let index3=0;index3<TAR_BLOCK_BYTES_V1;index3+=1)sum+=index3>=TAR_CHECKSUM_OFFSET_V1&&index3<TAR_CHECKSUM_OFFSET_V1+TAR_CHECKSUM_LENGTH_V1?32:header[index3];if(readOctalHeaderField(header,TAR_CHECKSUM_OFFSET_V1,TAR_CHECKSUM_LENGTH_V1)!==sum)throw new NodePackageInstallErrorV1("archive_invalid")}function headerEntryName(header){for(let index3=0;index3<USTAR_MAGIC_V1.length;index3+=1)if(header[TAR_MAGIC_OFFSET_V1+index3]!==USTAR_MAGIC_V1[index3])throw new NodePackageInstallErrorV1("archive_invalid");let name=readHeaderString(header,0,TAR_NAME_LENGTH_V1),prefix=readHeaderString(header,TAR_PREFIX_OFFSET_V1,TAR_PREFIX_LENGTH_V1);return prefix===""?name:`${prefix}/${name}`}function isZeroBlock(tar,offset){for(let index3=0;index3<TAR_BLOCK_BYTES_V1;index3+=1)if(tar[offset+index3]!==0)return!1;return!0}function verifyZeroPadding(tar,dataEnd,paddedEnd){for(let index3=dataEnd;index3<paddedEnd;index3+=1)if(tar[index3]!==0)throw new NodePackageInstallErrorV1("archive_invalid")}function parsePaxPath(data){let offset=0,path15;for(;offset<data.byteLength;){let space=offset;for(;space<data.byteLength&&data[space]!==32;)space+=1;if(space>=data.byteLength)throw new NodePackageInstallErrorV1("archive_invalid");let recordLength=0;for(let index3=offset;index3<space;index3+=1){let byte=data[index3];if(byte<48||byte>57)throw new NodePackageInstallErrorV1("archive_invalid");if(recordLength=recordLength*10+(byte-48),recordLength>data.byteLength)throw new NodePackageInstallErrorV1("archive_invalid")}if(recordLength<=space-offset+1)throw new NodePackageInstallErrorV1("archive_invalid");let end=offset+recordLength;if(end>data.byteLength||data[end-1]!==10)throw new NodePackageInstallErrorV1("archive_invalid");let equals=space+1;for(;equals<end-1&&data[equals]!==61;)equals+=1;if(equals>=end-1)throw new NodePackageInstallErrorV1("archive_invalid");readHeaderString(data,space+1,equals-space-1)==="path"&&(path15=readHeaderString(data,equals+1,end-1-equals-1)),offset=end}return path15}function readGnuLongName(data){let end=data.byteLength;if(end>0&&data[end-1]===0&&(end-=1),end===0)throw new NodePackageInstallErrorV1("archive_invalid");try{return new TextDecoder("utf-8",{fatal:!0}).decode(data.subarray(0,end))}catch{throw new NodePackageInstallErrorV1("archive_invalid")}}function gunzipBounded(input,maxBytes){return new Promise((resolve25,reject2)=>{let gunzip=createGunzip(),chunks=[],total=0,settled=!1,fail=error2=>{settled||(settled=!0,gunzip.destroy(),reject2(error2))};gunzip.on("data",chunk=>{if(!settled){if(total+=chunk.byteLength,total>maxBytes){fail(new NodePackageInstallErrorV1("archive_budget_exceeded"));return}chunks.push(chunk)}}),gunzip.on("end",()=>{if(settled)return;settled=!0;let result=new Uint8Array(total),offset=0;for(let chunk of chunks)result.set(chunk,offset),offset+=chunk.byteLength;resolve25(result)}),gunzip.on("error",()=>{fail(new NodePackageInstallErrorV1("archive_invalid"))}),gunzip.end(input)})}function parseTarEntries(tar,limits){let entries=[],names2=new Set,extractedBytes=0,offset=0,pendingPath;for(;offset+TAR_BLOCK_BYTES_V1<=tar.byteLength;){let header=tar.subarray(offset,offset+TAR_BLOCK_BYTES_V1);if(isZeroBlock(tar,offset)){if(offset+2*TAR_BLOCK_BYTES_V1>tar.byteLength||!isZeroBlock(tar,offset+TAR_BLOCK_BYTES_V1))throw new NodePackageInstallErrorV1("archive_invalid");if(pendingPath!==void 0)throw new NodePackageInstallErrorV1("archive_invalid");for(let index3=offset+2*TAR_BLOCK_BYTES_V1;index3<tar.byteLength;index3+=1)if(tar[index3]!==0)throw new NodePackageInstallErrorV1("archive_invalid");return Object.freeze(entries)}verifyHeaderChecksum(header);let typeflag=String.fromCharCode(header[TAR_TYPEFLAG_OFFSET_V1]),size=readOctalHeaderField(header,TAR_SIZE_OFFSET_V1,TAR_SIZE_LENGTH_V1);if(size>limits.maxEntryBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");let dataStart=offset+TAR_BLOCK_BYTES_V1,dataEnd=dataStart+size;if(dataEnd>tar.byteLength)throw new NodePackageInstallErrorV1("archive_invalid");let paddedEnd=Math.ceil(dataEnd/TAR_BLOCK_BYTES_V1)*TAR_BLOCK_BYTES_V1;verifyZeroPadding(tar,dataEnd,paddedEnd);let data=tar.subarray(dataStart,dataEnd);if(typeflag==="L"){pendingPath=readGnuLongName(data),offset=paddedEnd;continue}if(typeflag==="x"){let paxPath=parsePaxPath(data);paxPath!==void 0&&(pendingPath=paxPath),offset=paddedEnd;continue}if(typeflag==="g"){offset=paddedEnd;continue}if(typeflag==="1"||typeflag==="2")throw new NodePackageInstallErrorV1("archive_invalid");if(typeflag!=="\0"&&typeflag!=="0"&&typeflag!=="5")throw new NodePackageInstallErrorV1("archive_invalid");let rawName=pendingPath??headerEntryName(header);pendingPath=void 0,typeflag==="5"&&!rawName.endsWith("/")&&(rawName+="/");let normalized=normalizedEntryName(rawName);if(normalized.directory&&size!==0)throw new NodePackageInstallErrorV1("archive_invalid");if(names2.has(normalized.name))throw new NodePackageInstallErrorV1("archive_invalid");if(names2.add(normalized.name),entries.length+1>limits.maxEntries)throw new NodePackageInstallErrorV1("archive_budget_exceeded");let bytes=normalized.directory?new Uint8Array:new Uint8Array(data);if(extractedBytes+=bytes.byteLength,extractedBytes>limits.maxExtractedBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");entries.push(Object.freeze({name:normalized.name,directory:normalized.directory,bytes})),offset=paddedEnd}throw new NodePackageInstallErrorV1("archive_invalid")}function stripNpmPackageRoot(entries){if(entries.length===0)return entries;let rootSegment=entries[0].name.split("/")[0];if(rootSegment!=="package")return entries;let sharesRoot=entry=>{if(entry.name===rootSegment)return entry.directory;let parts=entry.name.split("/");return parts.length>=2&&parts[0]===rootSegment};if(!entries.every(sharesRoot))return entries;let stripped=[];for(let entry of entries)entry.name!==rootSegment&&stripped.push(Object.freeze({...entry,name:entry.name.slice(rootSegment.length+1)}));return Object.freeze(stripped)}async function parseNodeTarGzPackageV1(input,limitsInput={}){if(!(input instanceof Uint8Array))throw new NodePackageInstallErrorV1("archive_invalid");let limits=resolveNodePackageLimitsV1(limitsInput);if(input.byteLength>limits.maxArchiveBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");let tar=await gunzipBounded(input,limits.maxExtractedBytes);return stripNpmPackageRoot(parseTarEntries(tar,limits))}var NODE_PACKAGE_INSTALL_HOST_VERSION_V1=1,NODE_PACKAGE_FORMAT_VERSION_V12=1,DEFAULT_MAX_ARCHIVE_BYTES_V1=128*1024*1024,MAX_ARCHIVE_BYTES_V1=512*1024*1024,DEFAULT_MAX_EXTRACTED_BYTES_V1=256*1024*1024,MAX_EXTRACTED_BYTES_V1=1024*1024*1024,DEFAULT_MAX_ENTRY_BYTES_V1=64*1024*1024,MAX_ENTRY_BYTES_V1=256*1024*1024,DEFAULT_MAX_ENTRIES_V1=2048,MAX_ENTRIES_V1=8192,MAX_PACKAGE_MANIFEST_BYTES_V1=64*1024,ECOSYSTEM_MANIFEST_FILE_V12="agent-forge.json",CAPABILITY_MANIFEST_FILE_V12="plugin.json",LOCAL_FILE_HEADER_V1=67324752,CENTRAL_FILE_HEADER_V1=33639248,END_OF_CENTRAL_DIRECTORY_V1=101010256,ZIP64_END_OF_CENTRAL_DIRECTORY_V1=101075792,ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_V1=117853008,NodePackageInstallErrorV1=class extends Error{code;constructor(code){super(`Node package installation failed: ${code}`),this.name="NodePackageInstallErrorV1",this.code=code}};function createNodePackageInstallSessionLoaderV1(session){return async({manifestPath})=>({dispose:(await session.loadCapabilityPluginManifest(manifestPath)).dispose})}async function createNodePackageInstallHostForSessionV1(options,session){if(options.loadPlugin!==void 0)throw new Error("loadPlugin must be omitted when binding a session");return await createNodePackageInstallHostV1({...options,loadPlugin:createNodePackageInstallSessionLoaderV1(session)})}function positiveLimit(value,fallback,maximum,label){let result=value??fallback;if(!Number.isSafeInteger(result)||result<1||result>maximum)throw new Error(`${label} must be a positive integer at most ${maximum}`);return result}function resolveNodePackageLimitsV1(limitsInput){return{maxArchiveBytes:positiveLimit(limitsInput.maxArchiveBytes,DEFAULT_MAX_ARCHIVE_BYTES_V1,MAX_ARCHIVE_BYTES_V1,"maxArchiveBytes"),maxExtractedBytes:positiveLimit(limitsInput.maxExtractedBytes,DEFAULT_MAX_EXTRACTED_BYTES_V1,MAX_EXTRACTED_BYTES_V1,"maxExtractedBytes"),maxEntryBytes:positiveLimit(limitsInput.maxEntryBytes,DEFAULT_MAX_ENTRY_BYTES_V1,MAX_ENTRY_BYTES_V1,"maxEntryBytes"),maxEntries:positiveLimit(limitsInput.maxEntries,DEFAULT_MAX_ENTRIES_V1,MAX_ENTRIES_V1,"maxEntries")}}function readU16(bytes,offset){if(offset<0||offset+2>bytes.byteLength)throw new NodePackageInstallErrorV1("archive_invalid");return bytes[offset]|bytes[offset+1]<<8}function readU32(bytes,offset){if(offset<0||offset+4>bytes.byteLength)throw new NodePackageInstallErrorV1("archive_invalid");return(bytes[offset]|bytes[offset+1]<<8|bytes[offset+2]<<16|bytes[offset+3]<<24)>>>0}function decodeName(bytes,utf8){try{let value=new TextDecoder("utf-8",{fatal:!0}).decode(bytes);if(!utf8&&/[^\x00-\x7f]/u.test(value))throw new Error("non-ascii zip name");return value}catch{throw new NodePackageInstallErrorV1("archive_invalid")}}function normalizedEntryName(value){if(value.length===0||value.includes("\\")||/[\u0000-\u001f\u007f]/u.test(value))throw new NodePackageInstallErrorV1("archive_invalid");let directory=value.endsWith("/");if(value.startsWith("/")||/^[a-z]:/iu.test(value))throw new NodePackageInstallErrorV1("archive_invalid");let parts=value.split("/");if(directory&&parts.pop(),parts.length===0||parts.some(part=>part===""||part==="."||part===".."||part.includes(":")||/[ .]$/u.test(part)||/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/iu.test(part)))throw new NodePackageInstallErrorV1("archive_invalid");return{name:parts.join("/"),directory}}function crcTable(){let table=new Uint32Array(256);for(let index3=0;index3<table.length;index3+=1){let value=index3;for(let bit=0;bit<8;bit+=1)value=(value&1)===0?value>>>1:value>>>1^3988292384;table[index3]=value>>>0}return table}var CRC_TABLE_V1=crcTable();function crc32(bytes){let value=4294967295;for(let byte of bytes)value=value>>>8^CRC_TABLE_V1[(value^byte)&255];return(value^4294967295)>>>0}function findEndOfCentralDirectory(bytes){let minimum=Math.max(0,bytes.byteLength-65535-22);for(let offset=bytes.byteLength-22;offset>=minimum;offset-=1){if(readU32(bytes,offset)!==END_OF_CENTRAL_DIRECTORY_V1)continue;let disk=readU16(bytes,offset+4),centralDisk=readU16(bytes,offset+6),entries=readU16(bytes,offset+10),centralEntries=readU16(bytes,offset+8),size=readU32(bytes,offset+12),start=readU32(bytes,offset+16),commentLength=readU16(bytes,offset+20);if(disk!==0||centralDisk!==0||entries!==centralEntries||offset+22+commentLength!==bytes.byteLength)throw new NodePackageInstallErrorV1("archive_invalid");if(entries===65535||size===4294967295||start===4294967295)throw new NodePackageInstallErrorV1("archive_invalid");if(start+size>offset)throw new NodePackageInstallErrorV1("archive_invalid");return{offset,entries,size,start}}for(let offset=Math.max(0,bytes.byteLength-64);offset<bytes.byteLength-3;offset+=1){let signature=readU32(bytes,offset);if(signature===ZIP64_END_OF_CENTRAL_DIRECTORY_V1||signature===ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_V1)throw new NodePackageInstallErrorV1("archive_invalid")}throw new NodePackageInstallErrorV1("archive_invalid")}function parseCentralDirectory(bytes,limits){let end=findEndOfCentralDirectory(bytes);if(end.entries>limits.maxEntries||end.size>bytes.byteLength||end.start+end.size>end.offset)throw new NodePackageInstallErrorV1("archive_budget_exceeded");let entries=[],names2=new Set,offset=end.start;for(let index3=0;index3<end.entries;index3+=1){if(readU32(bytes,offset)!==CENTRAL_FILE_HEADER_V1)throw new NodePackageInstallErrorV1("archive_invalid");let madeBy=readU16(bytes,offset+4)>>>8,flags=readU16(bytes,offset+8),method=readU16(bytes,offset+10),crc=readU32(bytes,offset+16),compressedSize=readU32(bytes,offset+20),uncompressedSize=readU32(bytes,offset+24),nameLength=readU16(bytes,offset+28),extraLength=readU16(bytes,offset+30),commentLength=readU16(bytes,offset+32),disk=readU16(bytes,offset+34),externalAttributes=readU32(bytes,offset+38),localOffset=readU32(bytes,offset+42),nameStart=offset+46,recordEnd=nameStart+nameLength+extraLength+commentLength;if(recordEnd>end.start+end.size||disk!==0||(flags&-2057)!==0||(flags&1)!==0||(flags&64)!==0)throw new NodePackageInstallErrorV1("archive_invalid");if(method!==0&&method!==8)throw new NodePackageInstallErrorV1("archive_invalid");if(uncompressedSize>limits.maxEntryBytes||compressedSize>limits.maxArchiveBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");let name=normalizedEntryName(decodeName(bytes.subarray(nameStart,nameStart+nameLength),(flags&2048)!==0));if(names2.has(name.name))throw new NodePackageInstallErrorV1("archive_invalid");if(names2.add(name.name),((madeBy===3?externalAttributes>>>16&65535:0)&61440)===40960)throw new NodePackageInstallErrorV1("archive_invalid");entries.push({name:name.name,directory:name.directory,flags,method,compressedSize,uncompressedSize,crc32:crc,localOffset}),offset=recordEnd}if(offset!==end.start+end.size)throw new NodePackageInstallErrorV1("archive_invalid");let spans=[];for(let entry of entries){if(entry.localOffset<0||entry.localOffset+30>end.start)throw new NodePackageInstallErrorV1("archive_invalid");if(readU32(bytes,entry.localOffset)!==LOCAL_FILE_HEADER_V1)throw new NodePackageInstallErrorV1("archive_invalid");let localNameLength=readU16(bytes,entry.localOffset+26),localExtraLength=readU16(bytes,entry.localOffset+28),dataStart=entry.localOffset+30+localNameLength+localExtraLength,dataEnd=dataStart+entry.compressedSize;if(dataStart<entry.localOffset+30||dataEnd<dataStart||dataEnd>end.start)throw new NodePackageInstallErrorV1("archive_invalid");spans.push({start:entry.localOffset,end:dataEnd})}spans.sort((left,right)=>left.start-right.start||left.end-right.end);for(let index3=1;index3<spans.length;index3+=1)if(spans[index3-1].end>spans[index3].start)throw new NodePackageInstallErrorV1("archive_invalid");return entries}function extractEntry(bytes,entry,maxEntryBytes){if(entry.directory){if(entry.compressedSize!==0||entry.uncompressedSize!==0)throw new NodePackageInstallErrorV1("archive_invalid");return new Uint8Array}if(entry.localOffset+30>bytes.byteLength)throw new NodePackageInstallErrorV1("archive_invalid");if(readU32(bytes,entry.localOffset)!==LOCAL_FILE_HEADER_V1)throw new NodePackageInstallErrorV1("archive_invalid");let localFlags=readU16(bytes,entry.localOffset+6),localMethod=readU16(bytes,entry.localOffset+8),nameLength=readU16(bytes,entry.localOffset+26),extraLength=readU16(bytes,entry.localOffset+28),localName=decodeName(bytes.subarray(entry.localOffset+30,entry.localOffset+30+nameLength),(entry.flags&2048)!==0);if(normalizedEntryName(localName).name!==entry.name||localFlags!==entry.flags||localMethod!==entry.method)throw new NodePackageInstallErrorV1("archive_invalid");let localCompressedSize=readU32(bytes,entry.localOffset+18),localUncompressedSize=readU32(bytes,entry.localOffset+22);if((entry.flags&8)===0&&(localCompressedSize!==entry.compressedSize||localUncompressedSize!==entry.uncompressedSize))throw new NodePackageInstallErrorV1("archive_invalid");let dataStart=entry.localOffset+30+nameLength+extraLength,dataEnd=dataStart+entry.compressedSize;if(dataStart>bytes.byteLength||dataEnd>bytes.byteLength)throw new NodePackageInstallErrorV1("archive_invalid");let compressed=bytes.subarray(dataStart,dataEnd),output;try{output=entry.method===0?new Uint8Array(compressed):inflateRawSync(compressed,{maxOutputLength:maxEntryBytes})}catch{throw new NodePackageInstallErrorV1("archive_invalid")}if(output.byteLength!==entry.uncompressedSize||output.byteLength>maxEntryBytes||crc32(output)!==entry.crc32)throw new NodePackageInstallErrorV1("archive_invalid");return output}function parseNodeZipPackageV1(input,limitsInput={}){if(!(input instanceof Uint8Array))throw new NodePackageInstallErrorV1("archive_invalid");let limits=resolveNodePackageLimitsV1(limitsInput);if(input.byteLength>limits.maxArchiveBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");let descriptors=parseCentralDirectory(input,limits),extractedBytes=0;return Object.freeze(descriptors.map(descriptor=>{let bytes=extractEntry(input,descriptor,limits.maxEntryBytes);if(extractedBytes+=bytes.byteLength,extractedBytes>limits.maxExtractedBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");return Object.freeze({name:descriptor.name,directory:descriptor.directory,bytes})}))}function manifestKeys(value){let allowed=new Set(["packageFormatVersion","id","pluginVersion","apiVersion","minHostVersion","maxHostVersion","capabilityRefs","requires","platform","testOnly"]);return Object.keys(value).every(key=>allowed.has(key))}function packageManifest(value,record){if(value===null||typeof value!="object"||Array.isArray(value))throw new NodePackageInstallErrorV1("package_manifest_invalid");let manifest=value;if(!manifestKeys(manifest)||manifest.packageFormatVersion!==NODE_PACKAGE_FORMAT_VERSION_V12||manifest.id!==record.pluginId||manifest.pluginVersion!==record.pluginVersion)throw new NodePackageInstallErrorV1("package_manifest_mismatch");if(typeof manifest.apiVersion!="string"||manifest.apiVersion!==record.manifest.apiVersion)throw new NodePackageInstallErrorV1("package_manifest_mismatch");try{if(pluginManifestDigestV1(manifest)!==record.manifestDigest)throw new NodePackageInstallErrorV1("package_manifest_mismatch")}catch(error2){throw error2 instanceof NodePackageInstallErrorV1?error2:new NodePackageInstallErrorV1("package_manifest_invalid")}}function capabilityManifest(value,record,entries){let manifest;try{manifest=parseCapabilityPluginManifest(value,"<installed plugin.json>")}catch{throw new NodePackageInstallErrorV1("package_manifest_invalid")}if(manifest.id!==record.pluginId||manifest.version!==record.pluginVersion)throw new NodePackageInstallErrorV1("package_manifest_mismatch");let entryValue=manifest.entry.startsWith("./")?manifest.entry.slice(2):manifest.entry,entry=normalizedEntryName(entryValue);if(entry.directory||!entries.some(candidate=>candidate.name===entry.name&&!candidate.directory))throw new NodePackageInstallErrorV1("package_manifest_mismatch")}function opaqueScope(value){if(typeof value!="string"||value.trim()===""||value.length>2048||/\s|[\u0000-\u001f\u007f]/u.test(value))throw new NodePackageInstallErrorV1("installation_identity_mismatch");return value}function installationKey(scope,scopeRef,pluginId){return`${scope}\0${scopeRef}\0${pluginId}`}function identityMatches(record,input){return record.pluginId===input.pluginId&&record.pluginVersion===input.pluginVersion&&record.manifestDigest===input.manifestDigest&&record.scope===input.scope&&record.scopeRef===input.scopeRef}function artifactIdentityMatchesRecord(artifact,record){return artifact.version===1&&artifact.pluginId===record.pluginId&&artifact.pluginVersion===record.pluginVersion&&artifact.manifestDigest===record.manifestDigest}function expectedArtifactDigest(value){let prefixed=/^(sha256|sha512):([0-9a-f]+)$/iu.exec(value);if(prefixed!==null){let algorithm=prefixed[1].toLowerCase(),hex=prefixed[2].toLowerCase();if(algorithm==="sha256"&&hex.length===64||algorithm==="sha512"&&hex.length===128)return{algorithm,hex}}if(/^[0-9a-f]{64}$/iu.test(value))return{algorithm:"sha256",hex:value.toLowerCase()};if(/^[0-9a-f]{128}$/iu.test(value))return{algorithm:"sha512",hex:value.toLowerCase()};throw new NodePackageInstallErrorV1("invalid_artifact")}async function collectArtifact(openArtifact,artifact,maxBytes,signal){let chunks=[],total=0;for await(let chunk of openArtifact({artifact,signal})){if(signal.aborted)throw new NodePackageInstallErrorV1("cancelled");if(!(chunk instanceof Uint8Array))throw new NodePackageInstallErrorV1("invalid_artifact");if(chunk.byteLength>maxBytes-total)throw new NodePackageInstallErrorV1("archive_budget_exceeded");chunks.push(new Uint8Array(chunk)),total+=chunk.byteLength}let result=new Uint8Array(total),offset=0;for(let chunk of chunks)result.set(chunk,offset),offset+=chunk.byteLength;return result}function packagePath(root,key){return join16(root,createHash3("sha256").update(key).digest("hex"))}async function writeEntries(root,entries,signal){await mkdir4(root,{recursive:!0,mode:448});for(let entry of entries){if(signal.aborted)throw new NodePackageInstallErrorV1("cancelled");let target=join16(root,...entry.name.split("/"));if(entry.directory){await mkdir4(target,{recursive:!0,mode:448});continue}let parent=join16(root,...entry.name.split("/").slice(0,-1));await mkdir4(parent,{recursive:!0,mode:448}),await writeFile3(target,entry.bytes,{flag:"wx",mode:384})}}async function createNodePackageInstallHostV1(options){if(typeof options.openArtifact!="function")throw new Error("openArtifact is required");let limits=resolveNodePackageLimitsV1(options),parent=options.installationDirectory??tmpdir2();if(!isAbsolute6(parent))throw new Error("installationDirectory must be absolute");if(options.persistence!==void 0&&options.persistence!=="ephemeral"&&options.persistence!=="persistent")throw new Error("persistence mode is invalid");let supportedScopes=options.supportedScopes??["global","project"];if(!Array.isArray(supportedScopes)||supportedScopes.length===0||new Set(supportedScopes).size!==supportedScopes.length||supportedScopes.some(scope=>scope!=="global"&&scope!=="project"))throw new Error("supportedScopes is invalid");await mkdir4(parent,{recursive:!0,mode:448});let persistent=options.persistence==="persistent",instanceRoot=persistent?join16(parent,"agent-forge-plugin-install-store-v1"):await mkdtemp2(join16(parent,"agent-forge-plugin-install-")),persistence=persistent?await createNodePackageInstallPersistenceV1({rootDirectory:instanceRoot,lockTimeoutMs:options.persistenceLockTimeoutMs}):void 0,records=new Map,activeByKey=new Map;if(persistence!==void 0)for(let record of await persistence.load())records.set(record.installationRef,{...record});for(let record of records.values())record.state==="active"&&activeByKey.set(installationKey(record.scope,record.scopeRef,record.pluginId),record.installationRef);let closed=!1,activeOperations=new Set,runtimeHandles=new Map,applyPersistentSnapshot=snapshot2=>{records.clear(),activeByKey.clear();for(let value of snapshot2)records.set(value.installationRef,{...value});for(let value of records.values())value.state==="active"&&activeByKey.set(installationKey(value.scope,value.scopeRef,value.pluginId),value.installationRef)},commitRecords=async update=>{if(persistence===void 0){await update(records);return}applyPersistentSnapshot(await persistence.mutate({update}))},drained,closePromise,begin=parentSignal=>{if(closed)throw new NodePackageInstallErrorV1("host_closed");let controller=new AbortController;return parentSignal?.aborted?controller.abort(parentSignal.reason):parentSignal?.addEventListener("abort",()=>controller.abort(parentSignal.reason),{once:!0}),activeOperations.add(controller),{controller,signal:controller.signal}},end=controller=>{activeOperations.delete(controller),activeOperations.size===0&&(drained?.(),drained=void 0)},waitDrained=async()=>{activeOperations.size!==0&&await new Promise(resolve25=>{drained=resolve25})},getRecord=(installation,record,scope,scopeRef)=>{let value=records.get(installation.installationRef);if(value===void 0||installation.pluginId!==record.pluginId||installation.pluginVersion!==record.pluginVersion||installation.manifestDigest!==record.manifestDigest||installation.scope!==scope||installation.scopeRef!==scopeRef||!identityMatches(value,{pluginId:record.pluginId,pluginVersion:record.pluginVersion,manifestDigest:record.manifestDigest,scope,scopeRef}))throw new NodePackageInstallErrorV1("installation_identity_mismatch");return value},disposeRuntime=async installationRef=>{let handle=runtimeHandles.get(installationRef);handle!==void 0&&(handle.dispose!==void 0&&await Promise.resolve(handle.dispose()),runtimeHandles.delete(installationRef))},loadRuntime=async(installation,record,directory,signal)=>{if(options.loadPlugin!==void 0)try{return await options.loadPlugin({installation,record,directory,manifestPath:join16(directory,CAPABILITY_MANIFEST_FILE_V12),signal})??void 0}catch(error2){throw error2 instanceof NodePackageInstallErrorV1?error2:new NodePackageInstallErrorV1("installation_io_failed")}},host={version:NODE_PACKAGE_INSTALL_HOST_VERSION_V1,supportedScopes:Object.freeze([...supportedScopes]),getInstallationDirectory(input){let record=records.get(input.installation.installationRef);if(record===void 0||record.pluginId!==input.installation.pluginId||record.pluginVersion!==input.installation.pluginVersion||record.manifestDigest!==input.installation.manifestDigest||record.scope!==input.installation.scope||record.scopeRef!==input.installation.scopeRef)throw new NodePackageInstallErrorV1("installation_unknown");return record.directory},async install(input){let operation=begin(input.signal),staging;try{if(input.artifact===void 0)throw new NodePackageInstallErrorV1("invalid_artifact");if(!artifactIdentityMatchesRecord(input.artifact,input.record))throw new NodePackageInstallErrorV1("invalid_artifact");let mediaType=input.artifact.mediaType.toLowerCase();if(mediaType!=="application/zip"&&mediaType!=="application/gzip")throw new NodePackageInstallErrorV1("unsupported_media_type");let scopeRef=opaqueScope(input.scopeRef),bytes=await collectArtifact(options.openArtifact,input.artifact,limits.maxArchiveBytes,operation.signal);if(input.artifact.sizeBytes!==bytes.byteLength)throw new NodePackageInstallErrorV1("invalid_artifact");let digest=expectedArtifactDigest(input.artifact.artifactDigest);if(createHash3(digest.algorithm).update(bytes).digest("hex")!==digest.hex)throw new NodePackageInstallErrorV1("invalid_artifact");let entries=mediaType==="application/gzip"?await parseNodeTarGzPackageV1(bytes,limits):parseNodeZipPackageV1(bytes,limits),manifestEntry=entries.find(entry=>entry.name===ECOSYSTEM_MANIFEST_FILE_V12&&!entry.directory);if(manifestEntry===void 0)throw new NodePackageInstallErrorV1("package_manifest_missing");if(manifestEntry.bytes.byteLength>MAX_PACKAGE_MANIFEST_BYTES_V1)throw new NodePackageInstallErrorV1("package_manifest_invalid");let manifest;try{manifest=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(manifestEntry.bytes))}catch{throw new NodePackageInstallErrorV1("package_manifest_invalid")}packageManifest(manifest,input.record);let capabilityEntry=entries.find(entry=>entry.name===CAPABILITY_MANIFEST_FILE_V12&&!entry.directory);if(capabilityEntry===void 0)throw new NodePackageInstallErrorV1("package_manifest_missing");if(capabilityEntry.bytes.byteLength>MAX_PACKAGE_MANIFEST_BYTES_V1)throw new NodePackageInstallErrorV1("package_manifest_invalid");let capability;try{capability=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(capabilityEntry.bytes))}catch{throw new NodePackageInstallErrorV1("package_manifest_invalid")}capabilityManifest(capability,input.record,entries);let key=installationKey(input.scope,scopeRef,input.record.pluginId);staging=join16(instanceRoot,`.staging-${randomUUID6()}`),await writeEntries(staging,entries,operation.signal);let installRef=`plugin-install://node-zip/${randomUUID6()}`,destination=packagePath(instanceRoot,`${key}\0${installRef}`);await rename4(staging,destination),staging=void 0;let installedRecord={installationRef:installRef,directory:destination,pluginId:input.record.pluginId,pluginVersion:input.record.pluginVersion,manifestDigest:input.record.manifestDigest,scope:input.scope,scopeRef,state:"installed"};try{await commitRecords(values=>{values.set(installRef,installedRecord)})}catch(error2){throw await rm3(destination,{recursive:!0,force:!0}).catch(()=>{}),error2}return{installationRef:installRef,scope:input.scope,scopeRef}}catch(error2){throw operation.signal.aborted||input.signal?.aborted?new NodePackageInstallErrorV1("cancelled"):error2 instanceof NodePackageInstallErrorV1?error2:new NodePackageInstallErrorV1("installation_io_failed")}finally{staging!==void 0&&await rm3(staging,{recursive:!0,force:!0}).catch(()=>{}),end(operation.controller)}},async activate(input){let operation=begin(input.signal),candidate;try{let scopeRef=opaqueScope(input.scopeRef),record=getRecord(input.installation,input.record,input.scope,scopeRef);if(record.state!=="installed")throw new NodePackageInstallErrorV1("installation_identity_mismatch");candidate=await loadRuntime(input.installation,input.record,record.directory,operation.signal);let key=installationKey(input.scope,scopeRef,input.record.pluginId),previousRef=activeByKey.get(key);previousRef!==void 0&&records.get(previousRef)!==void 0&&await disposeRuntime(previousRef),await commitRecords(values=>{let candidateRecord=values.get(input.installation.installationRef);if(candidateRecord===void 0)throw new NodePackageInstallErrorV1("installation_identity_mismatch");if(previousRef!==void 0){let previousRecord=values.get(previousRef);previousRecord!==void 0&&values.set(previousRef,{...previousRecord,state:"retained"})}values.set(input.installation.installationRef,{...candidateRecord,state:"active"})}),activeByKey.set(key,input.installation.installationRef),candidate!==void 0&&runtimeHandles.set(input.installation.installationRef,candidate),candidate=void 0}catch(error2){throw candidate?.dispose!==void 0&&await Promise.resolve(candidate.dispose()).catch(()=>{}),error2 instanceof NodePackageInstallErrorV1?error2:new NodePackageInstallErrorV1("installation_io_failed")}finally{end(operation.controller)}},async rollback(input){let operation=begin(input.signal),candidate;try{let scopeRef=opaqueScope(input.scopeRef),failed=records.get(input.failed.installationRef);if(failed===void 0||!identityMatches(failed,{pluginId:input.failed.pluginId,pluginVersion:input.failed.pluginVersion,manifestDigest:input.failed.manifestDigest,scope:input.scope,scopeRef}))throw new NodePackageInstallErrorV1("installation_identity_mismatch");let previous=records.get(input.previous.installationRef);if(previous===void 0||!identityMatches(previous,{pluginId:input.previous.pluginId,pluginVersion:input.previous.pluginVersion,manifestDigest:input.previous.manifestDigest,scope:input.scope,scopeRef})||previous.state!=="active"&&previous.state!=="retained"||failed.pluginId!==previous.pluginId)throw new NodePackageInstallErrorV1("installation_identity_mismatch");let previousInstallation={version:1,pluginId:previous.pluginId,pluginVersion:previous.pluginVersion,manifestDigest:previous.manifestDigest,scope:previous.scope,scopeRef:previous.scopeRef,installationRef:input.previous.installationRef,state:"active"};candidate=await loadRuntime(previousInstallation,void 0,previous.directory,operation.signal),await disposeRuntime(input.failed.installationRef),await rm3(failed.directory,{recursive:!0,force:!0}),await commitRecords(values=>{values.delete(input.failed.installationRef);let previousRecord=values.get(input.previous.installationRef);previousRecord!==void 0&&values.set(input.previous.installationRef,{...previousRecord,state:"active"})}),activeByKey.set(installationKey(input.scope,scopeRef,failed.pluginId),input.previous.installationRef),candidate!==void 0&&runtimeHandles.set(input.previous.installationRef,candidate),candidate=void 0}catch(error2){throw candidate?.dispose!==void 0&&await Promise.resolve(candidate.dispose()).catch(()=>{}),error2 instanceof NodePackageInstallErrorV1?error2:new NodePackageInstallErrorV1("installation_io_failed")}finally{end(operation.controller)}},async uninstall(input){let operation=begin(input.signal);try{let scopeRef=opaqueScope(input.scopeRef),record=records.get(input.installation.installationRef);if(record===void 0||!identityMatches(record,{pluginId:input.installation.pluginId,pluginVersion:input.installation.pluginVersion,manifestDigest:input.installation.manifestDigest,scope:input.scope,scopeRef}))throw new NodePackageInstallErrorV1("installation_unknown");await disposeRuntime(input.installation.installationRef),await rm3(record.directory,{recursive:!0,force:!1}),await commitRecords(values=>{values.delete(input.installation.installationRef)});let key=installationKey(input.scope,scopeRef,record.pluginId);activeByKey.get(key)===input.installation.installationRef&&activeByKey.delete(key)}finally{end(operation.controller)}},async close(){if(closePromise!==void 0)return await closePromise;closed=!0;for(let operation of activeOperations)operation.abort();return closePromise=(async()=>{await waitDrained();let disposeError=!1;for(let installationRef of runtimeHandles.keys())try{await disposeRuntime(installationRef)}catch{disposeError=!0}if(persistence===void 0?await rm3(instanceRoot,{recursive:!0,force:!0}):await persistence.close(),records.clear(),activeByKey.clear(),disposeError)throw new NodePackageInstallErrorV1("installation_io_failed")})(),await closePromise}};if(options.loadPlugin!==void 0)try{for(let record of records.values()){if(record.state!=="active")continue;let installation={version:1,pluginId:record.pluginId,pluginVersion:record.pluginVersion,manifestDigest:record.manifestDigest,scope:record.scope,scopeRef:record.scopeRef,installationRef:record.installationRef,state:"active"},runtime=await loadRuntime(installation,void 0,record.directory,new AbortController().signal);runtime!==void 0&&runtimeHandles.set(record.installationRef,runtime)}}catch(error2){throw await host.close().catch(()=>{}),error2 instanceof NodePackageInstallErrorV1?error2:new NodePackageInstallErrorV1("installation_io_failed")}return host}import{createHash as createHash5,randomUUID as randomUUID7}from"node:crypto";import{lstatSync as lstatSync2}from"node:fs";import{lstat,readdir,readFile as readFile5}from"node:fs/promises";import{join as join17}from"node:path";function isMissingError2(error2){return typeof error2!="object"||error2===null?!1:"code"in error2&&error2.code==="ENOENT"}async function collectDirectory(root,relative14,limits,entries,budget,signal){if(signal?.aborted)throw new NodePackageInstallErrorV1("cancelled");let dirents=await readdir(relative14.length===0?root:join17(root,...relative14.split("/")),{withFileTypes:!0});dirents.sort((left,right)=>left.name<right.name?-1:left.name>right.name?1:0);for(let dirent of dirents){if(signal?.aborted)throw new NodePackageInstallErrorV1("cancelled");let childRelative=relative14.length===0?dirent.name:`${relative14}/${dirent.name}`;if(normalizedEntryName(childRelative),dirent.isSymbolicLink())throw new NodePackageInstallErrorV1("archive_invalid");let childPath=join17(root,...childRelative.split("/")),stats=await lstat(childPath);if(stats.isSymbolicLink())throw new NodePackageInstallErrorV1("archive_invalid");if(stats.isDirectory()){await collectDirectory(root,childRelative,limits,entries,budget,signal);continue}if(!stats.isFile())throw new NodePackageInstallErrorV1("archive_invalid");if(entries.length+1>limits.maxEntries)throw new NodePackageInstallErrorV1("archive_budget_exceeded");let bytes=await readFile5(childPath);if(bytes.byteLength>limits.maxEntryBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");if(budget.totalBytes+=bytes.byteLength,budget.totalBytes>limits.maxExtractedBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");entries.push(Object.freeze({name:childRelative,directory:!1,bytes:new Uint8Array(bytes)}))}}async function collectLocalDirectoryPackageEntriesV1(rootDirectory,limitsInput={},signal){if(typeof rootDirectory!="string"||rootDirectory.trim().length===0)throw new NodePackageInstallErrorV1("archive_invalid");let stats=await lstat(rootDirectory).catch(error2=>{throw isMissingError2(error2)?new NodePackageInstallErrorV1("archive_invalid"):error2});if(!stats.isDirectory()||stats.isSymbolicLink())throw new NodePackageInstallErrorV1("archive_invalid");let limits=resolveNodePackageLimitsV1(limitsInput),entries=[];return await collectDirectory(rootDirectory,"",limits,entries,{totalBytes:0},signal),Object.freeze(entries)}async function readLocalPackageFileV1(path15,limitsInput={},signal){if(signal?.aborted)throw new NodePackageInstallErrorV1("cancelled");if(typeof path15!="string"||path15.trim().length===0)throw new NodePackageInstallErrorV1("archive_invalid");let stats=await lstat(path15).catch(error2=>{throw isMissingError2(error2)?new NodePackageInstallErrorV1("archive_invalid"):error2});if(stats.isSymbolicLink()||!stats.isFile())throw new NodePackageInstallErrorV1("archive_invalid");let limits=resolveNodePackageLimitsV1(limitsInput);if(stats.size>limits.maxArchiveBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");let bytes=await readFile5(path15);if(bytes.byteLength!==stats.size||bytes.byteLength>limits.maxArchiveBytes)throw new NodePackageInstallErrorV1("archive_budget_exceeded");return new Uint8Array(bytes)}var DEFAULT_NPM_REGISTRY_V1="https://registry.npmjs.org",DEFAULT_TIMEOUT_MS_V12=15e3,MAX_TIMEOUT_MS_V12=12e4,DEFAULT_MAX_RESPONSE_BYTES_V1=8*1024*1024,MAX_RESPONSE_BYTES_V1=16*1024*1024,DEFAULT_MAX_TARBALL_BYTES_V1=128*1024*1024,MAX_TARBALL_BYTES_V1=512*1024*1024,DEFAULT_REDIRECTS_V12=3,MAX_REDIRECTS_V12=5,REDIRECT_STATUS2=new Set([301,302,303,307,308]),NodeNpmRegistrySourceErrorV1=class extends Error{code;constructor(code,message){super(message),this.name="NodeNpmRegistrySourceErrorV1",this.code=code}};function sriToIntegrityV1(sri){let match2=/^(sha512|sha256)-([A-Za-z0-9+/]+={0,2})$/u.exec(sri.trim());if(match2===null)throw new NodeNpmRegistrySourceErrorV1("integrity_unsupported","npm integrity algorithm is unsupported");let algorithm=match2[1],raw;try{raw=Buffer.from(match2[2],"base64")}catch{throw new NodeNpmRegistrySourceErrorV1("integrity_unsupported","npm integrity encoding is invalid")}if(algorithm==="sha256"&&raw.byteLength!==32||algorithm==="sha512"&&raw.byteLength!==64)throw new NodeNpmRegistrySourceErrorV1("integrity_unsupported","npm integrity length is invalid");let hex=raw.toString("hex").toLowerCase();if(hex.length===0)throw new NodeNpmRegistrySourceErrorV1("integrity_unsupported","npm integrity is invalid");return{algorithm,hex}}function parseVersionTriple(value){let match2=/^(\d+)\.(\d+)\.(\d+)/u.exec(value.replace(/^[vV]/u,""));if(match2===null)return;let major=Number.parseInt(match2[1],10),minor=Number.parseInt(match2[2],10),patch=Number.parseInt(match2[3],10);if(!(!Number.isSafeInteger(major)||!Number.isSafeInteger(minor)||!Number.isSafeInteger(patch)))return[major,minor,patch]}function plainVersion(value){return value.replace(/^[vV]/u,"")}function selectNpmPackageVersionV1(versions,range2){if(!Array.isArray(versions))return;let candidates=versions.filter(value=>typeof value=="string"&&parseVersionTriple(value)!==void 0);if(candidates.length===0)return;if(range2===void 0||range2==="latest")return candidates.reduce((left,right)=>comparePluginVersionsV1(right,left)>0?right:left);let exact=plainVersion(range2.replace(/^[=~^]/u,""));if(!range2.startsWith("^")&&!range2.startsWith("~"))return candidates.find(value=>plainVersion(value)===exact);let bound=parseVersionTriple(exact);if(bound===void 0)return;let[major,minor]=bound,upper=range2.startsWith("^")?`${major+1}.0.0`:`${major}.${minor+1}.0`;if(candidates=candidates.filter(value=>comparePluginVersionsV1(value,exact)>=0&&comparePluginVersionsV1(value,upper)<0),candidates.length!==0)return candidates.reduce((left,right)=>comparePluginVersionsV1(right,left)>0?right:left)}function boundedPositive2(value,fallback,maximum,label){let result=value??fallback;if(!Number.isSafeInteger(result)||result<=0||result>maximum)throw new NodeNpmRegistrySourceErrorV1("invalid_configuration",`${label} must be a positive integer at most ${maximum}`);return result}function registryOrigin(value){let parsed;try{parsed=new URL(value)}catch{throw new NodeNpmRegistrySourceErrorV1("invalid_configuration","npm registry origin is invalid")}if(parsed.protocol!=="http:"&&parsed.protocol!=="https:"||parsed.username!==""||parsed.password!=="")throw new NodeNpmRegistrySourceErrorV1("invalid_configuration","npm registry origin must be http(s) without credentials");if(parsed.pathname!=="/"||parsed.search!==""||parsed.hash!=="")throw new NodeNpmRegistrySourceErrorV1("invalid_configuration","npm registry origin must not include a path, query, or fragment");return parsed.origin}function packumentUrl(registryOriginValue,name){let scopeAt=name.indexOf("/");if(name.startsWith("@")&&scopeAt>0){let scope=name.slice(0,scopeAt),packageName=name.slice(scopeAt+1);return new URL(`${registryOriginValue}/${scope}%2F${encodeURIComponent(packageName)}`)}if(scopeAt>=0)throw new NodeNpmRegistrySourceErrorV1("invalid_configuration","npm package name is invalid");return new URL(`${registryOriginValue}/${encodeURIComponent(name)}`)}function tarballUrl(value){let parsed;try{parsed=new URL(value)}catch{throw new NodeNpmRegistrySourceErrorV1("invalid_response","npm tarball URL is invalid")}if(parsed.protocol!=="http:"&&parsed.protocol!=="https:"||parsed.username!==""||parsed.password!=="")throw new NodeNpmRegistrySourceErrorV1("invalid_response","npm tarball URL must use http(s) without credentials");if(parsed.hash!=="")throw new NodeNpmRegistrySourceErrorV1("invalid_response","npm tarball URL must not include a fragment");return parsed}function isAbortLike2(error2){return error2 instanceof Error&&(error2.name==="AbortError"||error2.name==="AbortSignalError")}function requestSignal2(parent,timeoutMs){let controller=new AbortController,timedOut=!1,abort=()=>controller.abort(parent?.reason);parent?.aborted===!0?abort():parent?.addEventListener("abort",abort,{once:!0});let timeout=setTimeout(()=>{timedOut=!0,controller.abort()},timeoutMs);return{signal:controller.signal,timedOut:()=>timedOut,cleanup:()=>{clearTimeout(timeout),parent?.removeEventListener("abort",abort)}}}function isJsonResponse(response2){let contentType2=response2.headers.get("content-type");if(contentType2===null)return!1;let mediaType=contentType2.split(";",1)[0]?.trim().toLowerCase();return mediaType==="application/json"||mediaType==="application/vnd.npm.install-v1+json"}async function readBody(response2,maxBytes,signal){if(response2.body===null)throw new NodeNpmRegistrySourceErrorV1("invalid_response","npm registry response has no body");let reader=response2.body.getReader(),chunks=[],total=0;try{for(;;){if(signal.aborted)throw new DOMException("aborted","AbortError");let item=await reader.read();if(item.done)break;if(total+=item.value.byteLength,total>maxBytes)throw new NodeNpmRegistrySourceErrorV1("response_too_large","npm registry response exceeds the configured size limit");chunks.push(item.value)}}finally{reader.releaseLock()}let bytes=new Uint8Array(total),offset=0;for(let chunk of chunks)bytes.set(chunk,offset),offset+=chunk.byteLength;return bytes}function parsePackument(bytes){let value;try{value=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(bytes))}catch{throw new NodeNpmRegistrySourceErrorV1("invalid_response","npm registry response is not valid JSON")}if(typeof value!="object"||value===null||Array.isArray(value))throw new NodeNpmRegistrySourceErrorV1("invalid_response","npm packument is invalid");let packument=value;if(typeof packument.versions!="object"||packument.versions===null||Array.isArray(packument.versions))throw new NodeNpmRegistrySourceErrorV1("invalid_response","npm packument has no version table");return packument.versions}function createNodeNpmRegistrySourceV1(options={}){let transport=options.fetch??globalThis.fetch;if(typeof transport!="function")throw new NodeNpmRegistrySourceErrorV1("invalid_configuration","Node fetch is unavailable");let registry=registryOrigin(options.registry??DEFAULT_NPM_REGISTRY_V1);if(options.token!==void 0&&(options.token.length===0||options.token.length>4096||/[\r\n\s]/u.test(options.token)))throw new NodeNpmRegistrySourceErrorV1("invalid_configuration","npm registry token is invalid");let token=options.token,timeoutMs=boundedPositive2(options.requestTimeoutMs,DEFAULT_TIMEOUT_MS_V12,MAX_TIMEOUT_MS_V12,"requestTimeoutMs"),maxResponseBytes=boundedPositive2(options.maxResponseBytes,DEFAULT_MAX_RESPONSE_BYTES_V1,MAX_RESPONSE_BYTES_V1,"maxResponseBytes"),maxTarballBytes=boundedPositive2(options.maxTarballBytes,DEFAULT_MAX_TARBALL_BYTES_V1,MAX_TARBALL_BYTES_V1,"maxTarballBytes"),maxRedirects=options.maxRedirects??DEFAULT_REDIRECTS_V12;if(!Number.isSafeInteger(maxRedirects)||maxRedirects<0||maxRedirects>MAX_REDIRECTS_V12)throw new NodeNpmRegistrySourceErrorV1("invalid_configuration",`maxRedirects must be an integer between 0 and ${MAX_REDIRECTS_V12}`);let userAgent=options.userAgent??"agent-forge-plugin-npm/1";if(userAgent.length===0||userAgent.length>256||/[\r\n]/u.test(userAgent))throw new NodeNpmRegistrySourceErrorV1("invalid_configuration","userAgent is invalid");let fetchFollowingRedirects=async(url,headers,parentSignal)=>{let current=url;for(let redirect=0;;redirect+=1){let request=requestSignal2(parentSignal,timeoutMs),response2;try{response2=await transport(current.toString(),{method:"GET",headers:{accept:"*/*","user-agent":userAgent,...headers},redirect:"manual",signal:request.signal})}catch(error2){throw request.cleanup(),request.timedOut()?new NodeNpmRegistrySourceErrorV1("request_timed_out","npm registry request timed out"):isAbortLike2(error2)?new NodeNpmRegistrySourceErrorV1("cancelled","npm registry request was cancelled"):new NodeNpmRegistrySourceErrorV1("request_failed","npm registry request failed")}if(!REDIRECT_STATUS2.has(response2.status))return{response:response2,request};let location=response2.headers.get("location");if(await response2.body?.cancel().catch(()=>{}),request.cleanup(),location===null||redirect>=maxRedirects)throw new NodeNpmRegistrySourceErrorV1("request_failed","npm registry redirect limit exceeded");current=tarballUrl(new URL(location,current).toString())}};return{version:1,registry,resolveNpmPackage:async input=>{if(input.signal?.aborted===!0)throw new NodeNpmRegistrySourceErrorV1("cancelled","npm registry request was cancelled");let endpoint=packumentUrl(registry,input.name),authorization=token===void 0?{}:{authorization:`Bearer ${token}`},{response:response2,request}=await fetchFollowingRedirects(endpoint,authorization,input.signal);try{if(response2.status===404||response2.status===403)throw new NodeNpmRegistrySourceErrorV1("package_not_found","npm package was not found on the registry");if(response2.status<200||response2.status>=300)throw new NodeNpmRegistrySourceErrorV1("request_failed","npm registry request did not succeed");if(!isJsonResponse(response2))throw new NodeNpmRegistrySourceErrorV1("invalid_response","npm registry response must be JSON");let versions=parsePackument(await readBody(response2,maxResponseBytes,request.signal)),version=selectNpmPackageVersionV1(Object.keys(versions),input.range),dist=version===void 0?void 0:versions[version]?.dist;if(version===void 0||dist===void 0||typeof dist.tarball!="string"||dist.tarball.length===0)throw new NodeNpmRegistrySourceErrorV1("version_not_found","No npm package version matches the requested range");let integrityValue=dist.integrity,integrity=typeof integrityValue=="string"&&integrityValue.length>0?sriToIntegrityV1(integrityValue):void 0;if(integrity===void 0)throw new NodeNpmRegistrySourceErrorV1("invalid_response","npm package version has no integrity field");return{version,tarballUrl:tarballUrl(dist.tarball).toString(),integrity,distInfo:dist}}finally{await response2.body?.cancel().catch(()=>{}),request.cleanup()}},fetchTarball:async input=>{if(input.signal?.aborted===!0)throw new NodeNpmRegistrySourceErrorV1("cancelled","npm tarball download was cancelled");let endpoint=tarballUrl(input.url),authorization=token===void 0?{}:{authorization:`Bearer ${token}`},{response:response2,request}=await fetchFollowingRedirects(endpoint,authorization,input.signal);try{if(response2.status<200||response2.status>=300)throw new NodeNpmRegistrySourceErrorV1("request_failed","npm tarball download did not succeed");return await readBody(response2,maxTarballBytes,request.signal)}finally{await response2.body?.cancel().catch(()=>{}),request.cleanup()}}}}function sniffMagic(bytes){if(bytes.byteLength>=4&&bytes[0]===80&&bytes[1]===75&&(bytes[2]===3||bytes[2]===5||bytes[2]===7))return"application/zip";if(bytes.byteLength>=2&&bytes[0]===31&&bytes[1]===139)return"application/gzip"}function extensionMediaType(fileName){let value=fileName.toLowerCase();if(value.endsWith(".zip"))return"application/zip";if(value.endsWith(".tgz")||value.endsWith(".tar.gz"))return"application/gzip"}function detectPluginPackageMediaTypeV1(bytes,fileName){if(!(bytes instanceof Uint8Array))throw new NodePackageInstallErrorV1("archive_invalid");let magic=sniffMagic(bytes),extension=fileName===void 0?void 0:extensionMediaType(fileName);if(magic===void 0)throw new NodePackageInstallErrorV1("unsupported_media_type");if(extension!==void 0&&extension!==magic)throw new NodePackageInstallErrorV1("unsupported_media_type");return magic}import{createHash as createHash4}from"node:crypto";var DEFAULT_TIMEOUT_MS_V13=3e4,MAX_TIMEOUT_MS_V13=12e4,DEFAULT_MAX_PACKAGE_BYTES_V1=128*1024*1024,MAX_PACKAGE_BYTES_V1=512*1024*1024,DEFAULT_REDIRECTS_V13=3,MAX_REDIRECTS_V13=5,REDIRECT_STATUS3=new Set([301,302,303,307,308]),NodeUrlPackageSourceErrorV1=class extends Error{code;constructor(code,message){super(message),this.name="NodeUrlPackageSourceErrorV1",this.code=code}};function boundedPositive3(value,fallback,maximum,label){let result=value??fallback;if(!Number.isSafeInteger(result)||result<=0||result>maximum)throw new NodeUrlPackageSourceErrorV1("invalid_configuration",`${label} must be a positive integer at most ${maximum}`);return result}function packageUrl(value){let parsed;try{parsed=new URL(value)}catch{throw new NodeUrlPackageSourceErrorV1("invalid_url","plugin package URL is invalid")}if(parsed.protocol!=="http:"&&parsed.protocol!=="https:"||parsed.username!==""||parsed.password!=="")throw new NodeUrlPackageSourceErrorV1("invalid_url","plugin package URL must use http(s) without credentials");if(parsed.hash!=="")throw new NodeUrlPackageSourceErrorV1("invalid_url","plugin package URL must not include a fragment");return parsed}function isAbortLike3(error2){return error2 instanceof Error&&(error2.name==="AbortError"||error2.name==="AbortSignalError")}async function downloadNodeUrlPackageV1(options,input){let transport=options.fetch??globalThis.fetch;if(typeof transport!="function")throw new NodeUrlPackageSourceErrorV1("invalid_configuration","Node fetch is unavailable");let timeoutMs=boundedPositive3(options.requestTimeoutMs,DEFAULT_TIMEOUT_MS_V13,MAX_TIMEOUT_MS_V13,"requestTimeoutMs"),maxPackageBytes=boundedPositive3(options.maxPackageBytes,DEFAULT_MAX_PACKAGE_BYTES_V1,MAX_PACKAGE_BYTES_V1,"maxPackageBytes"),maxRedirects=options.maxRedirects??DEFAULT_REDIRECTS_V13;if(!Number.isSafeInteger(maxRedirects)||maxRedirects<0||maxRedirects>MAX_REDIRECTS_V13)throw new NodeUrlPackageSourceErrorV1("invalid_configuration",`maxRedirects must be an integer between 0 and ${MAX_REDIRECTS_V13}`);let userAgent=options.userAgent??"agent-forge-plugin-url/1";if(userAgent.length===0||userAgent.length>256||/[\r\n]/u.test(userAgent))throw new NodeUrlPackageSourceErrorV1("invalid_configuration","userAgent is invalid");if(input.expectedDigestHex!==void 0&&!/^[0-9a-f]{64}$/u.test(input.expectedDigestHex))throw new NodeUrlPackageSourceErrorV1("invalid_url","expected sha256 digest is invalid");let current=packageUrl(input.url),response2,controller=new AbortController,timedOut=!1,abort=()=>controller.abort(input.signal?.reason);input.signal?.aborted===!0?abort():input.signal?.addEventListener("abort",abort,{once:!0});let timeout=setTimeout(()=>{timedOut=!0,controller.abort()},timeoutMs);try{for(let redirect=0;;redirect+=1){if(controller.signal.aborted)throw new NodeUrlPackageSourceErrorV1("cancelled","plugin package download was cancelled");let hop;try{hop=await transport(current.toString(),{method:"GET",headers:{accept:"*/*","user-agent":userAgent},redirect:"manual",signal:controller.signal})}catch(error2){throw timedOut?new NodeUrlPackageSourceErrorV1("request_timed_out","plugin package download timed out"):isAbortLike3(error2)||input.signal?.aborted===!0?new NodeUrlPackageSourceErrorV1("cancelled","plugin package download was cancelled"):new NodeUrlPackageSourceErrorV1("request_failed","plugin package download failed")}if(!REDIRECT_STATUS3.has(hop.status)){response2=hop;break}let location=hop.headers.get("location");if(await hop.body?.cancel().catch(()=>{}),location===null||redirect>=maxRedirects)throw new NodeUrlPackageSourceErrorV1("request_failed","plugin package redirect limit exceeded");current=packageUrl(new URL(location,current).toString())}if(response2===void 0)throw new NodeUrlPackageSourceErrorV1("request_failed","plugin package download failed");if(response2.status<200||response2.status>=300)throw new NodeUrlPackageSourceErrorV1("request_failed","plugin package download did not succeed");if(response2.body===null)throw new NodeUrlPackageSourceErrorV1("request_failed","plugin package response has no body");let reader=response2.body.getReader(),chunks=[],hash=createHash4("sha256"),total=0;try{for(;;){if(controller.signal.aborted)throw new NodeUrlPackageSourceErrorV1("cancelled","plugin package download was cancelled");let item=await reader.read();if(item.done)break;if(total+=item.value.byteLength,total>maxPackageBytes)throw new NodeUrlPackageSourceErrorV1("response_too_large","plugin package exceeds the configured size limit");hash.update(item.value),chunks.push(item.value)}}finally{reader.releaseLock()}if(controller.signal.aborted)throw new NodeUrlPackageSourceErrorV1("cancelled","plugin package download was cancelled");let bytes=new Uint8Array(total),offset=0;for(let chunk of chunks)bytes.set(chunk,offset),offset+=chunk.byteLength;let digestHex=hash.digest("hex");if(input.expectedDigestHex!==void 0&&digestHex!==input.expectedDigestHex)throw new NodeUrlPackageSourceErrorV1("digest_mismatch","plugin package bytes do not match the expected sha256 digest");let fileName=current.pathname.split("/").pop(),mediaType=detectPluginPackageMediaTypeV1(bytes,fileName===void 0||fileName.length===0?void 0:fileName);return{bytes,mediaType,digestHex}}finally{clearTimeout(timeout),input.signal?.removeEventListener("abort",abort),await response2?.body?.cancel().catch(()=>{})}}var DEFAULT_GITHUB_API_ORIGIN_V1="https://api.github.com",DEFAULT_GITEE_API_ORIGIN_V1="https://gitee.com/api/v5",DEFAULT_TIMEOUT_MS_V14=15e3,MAX_TIMEOUT_MS_V14=12e4,DEFAULT_MAX_RESPONSE_BYTES_V12=8*1024*1024,MAX_RESPONSE_BYTES_V12=16*1024*1024,DEFAULT_MAX_ASSET_BYTES_V1=128*1024*1024,MAX_ASSET_BYTES_V1=512*1024*1024,DEFAULT_REDIRECTS_V14=3,MAX_REDIRECTS_V14=5,REDIRECT_STATUS4=new Set([301,302,303,307,308]),NodeReleasePackageSourceErrorV1=class extends Error{code;resetEpochSeconds;constructor(code,message,options){super(message),this.name="NodeReleasePackageSourceErrorV1",this.code=code,options?.resetEpochSeconds!==void 0&&(this.resetEpochSeconds=options.resetEpochSeconds)}};function boundedPositive4(value,fallback,maximum,label){let result=value??fallback;if(!Number.isSafeInteger(result)||result<=0||result>maximum)throw new NodeReleasePackageSourceErrorV1("invalid_configuration",`${label} must be a positive integer at most ${maximum}`);return result}function boundedToken(value,label){if(value!==void 0){if(value.length===0||value.length>4096||/[\r\n\s]/u.test(value))throw new NodeReleasePackageSourceErrorV1("invalid_configuration",`${label} is invalid`);return value}}function apiOrigin(value,label){let parsed;try{parsed=new URL(value)}catch{throw new NodeReleasePackageSourceErrorV1("invalid_configuration",`${label} is invalid`)}if(parsed.protocol!=="http:"&&parsed.protocol!=="https:"||parsed.username!==""||parsed.password!=="")throw new NodeReleasePackageSourceErrorV1("invalid_configuration",`${label} must be http(s) without credentials`);if(parsed.search!==""||parsed.hash!=="")throw new NodeReleasePackageSourceErrorV1("invalid_configuration",`${label} must not include a query or fragment`);let trimmed=parsed.pathname.replace(/\/+$/u,"");return{origin:parsed.origin,pathPrefix:trimmed===""||trimmed==="/"?"":trimmed.replace(/^\//u,"")}}function jsonBytes(value){try{return JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(value))}catch{throw new NodeReleasePackageSourceErrorV1("invalid_response","release API response is not valid JSON")}}function parseReleaseList(bytes){let value=jsonBytes(bytes);if(!Array.isArray(value))throw new NodeReleasePackageSourceErrorV1("invalid_response","release API response is not a release list");return value}function parseReleaseObject(bytes){let value=jsonBytes(bytes);if(typeof value!="object"||value===null||Array.isArray(value))throw new NodeReleasePackageSourceErrorV1("invalid_response","release API response is not a release object");return value}function firstPublishedRelease(releases){let published=releases.find(release=>release.draft!==!0);if(published===void 0)throw new NodeReleasePackageSourceErrorV1("release_not_found","repo has no published release");return published}function namedAssets(release){if(release.assets===void 0)return[];if(!Array.isArray(release.assets))throw new NodeReleasePackageSourceErrorV1("invalid_response","release assets are invalid");let entries=[];for(let asset of release.assets){if(typeof asset!="object"||asset===null)continue;let shape=asset;typeof shape.name!="string"||shape.name.length===0||entries.push({name:shape.name,url:shape.browser_download_url})}return entries}function isPackageAssetName(name){let value=name.toLowerCase();return value.endsWith(".zip")||value.endsWith(".tgz")}function selectPackageAssetUrl(release){let assets=namedAssets(release),candidates=assets.filter(asset=>isPackageAssetName(asset.name)),assetNames=assets.map(asset=>asset.name).join(", ");if(candidates.length===0)throw new NodeReleasePackageSourceErrorV1("release_asset_not_found",assetNames.length===0?"release has no assets":`assets: ${assetNames}`);if(candidates.length>1)throw new NodeReleasePackageSourceErrorV1("release_asset_ambiguous",`candidates: ${candidates.map(asset=>asset.name).join(", ")}`);let chosen=candidates[0];if(typeof chosen.url!="string"||chosen.url.length===0)throw new NodeReleasePackageSourceErrorV1("invalid_response","release asset has no download URL");return chosen.url}function isAbortLike4(error2){return error2 instanceof Error&&(error2.name==="AbortError"||error2.name==="AbortSignalError")}function requestSignal3(parent,timeoutMs){let controller=new AbortController,timedOut=!1,abort=()=>controller.abort(parent?.reason);parent?.aborted===!0?abort():parent?.addEventListener("abort",abort,{once:!0});let timeout=setTimeout(()=>{timedOut=!0,controller.abort()},timeoutMs);return{signal:controller.signal,timedOut:()=>timedOut,cleanup:()=>{clearTimeout(timeout),parent?.removeEventListener("abort",abort)}}}function isJsonResponse2(response2){let contentType2=response2.headers.get("content-type");if(contentType2===null)return!1;let mediaType=contentType2.split(";",1)[0]?.trim().toLowerCase();return mediaType==="application/json"||mediaType==="application/vnd.github+json"}function rateLimitState(response2){if(!(response2.status===429||response2.status===403&&response2.headers.get("x-ratelimit-remaining")==="0"))return{limited:!1};let reset=response2.headers.get("x-ratelimit-reset"),resetValue=reset===null?Number.NaN:Number.parseInt(reset,10);return!Number.isSafeInteger(resetValue)||resetValue<0?{limited:!0}:{limited:!0,resetEpochSeconds:resetValue}}async function readBody2(response2,maxBytes,signal){if(response2.body===null)throw new NodeReleasePackageSourceErrorV1("invalid_response","release API response has no body");let reader=response2.body.getReader(),chunks=[],total=0;try{for(;;){if(signal.aborted)throw new DOMException("aborted","AbortError");let item=await reader.read();if(item.done)break;if(total+=item.value.byteLength,total>maxBytes)throw new NodeReleasePackageSourceErrorV1("response_too_large","release API response exceeds the configured size limit");chunks.push(item.value)}}finally{reader.releaseLock()}let bytes=new Uint8Array(total),offset=0;for(let chunk of chunks)bytes.set(chunk,offset),offset+=chunk.byteLength;return bytes}function createNodeReleasePackageSourceV1(options={}){let transport=options.fetch??globalThis.fetch;if(typeof transport!="function")throw new NodeReleasePackageSourceErrorV1("invalid_configuration","Node fetch is unavailable");let githubOrigin=apiOrigin(options.githubApiOrigin??DEFAULT_GITHUB_API_ORIGIN_V1,"githubApiOrigin"),giteeOrigin=apiOrigin(options.giteeApiOrigin??DEFAULT_GITEE_API_ORIGIN_V1,"giteeApiOrigin"),githubToken=boundedToken(options.githubToken,"githubToken"),giteeToken=boundedToken(options.giteeToken,"giteeToken"),timeoutMs=boundedPositive4(options.requestTimeoutMs,DEFAULT_TIMEOUT_MS_V14,MAX_TIMEOUT_MS_V14,"requestTimeoutMs"),maxResponseBytes=boundedPositive4(options.maxResponseBytes,DEFAULT_MAX_RESPONSE_BYTES_V12,MAX_RESPONSE_BYTES_V12,"maxResponseBytes"),maxAssetBytes=boundedPositive4(options.maxAssetBytes,DEFAULT_MAX_ASSET_BYTES_V1,MAX_ASSET_BYTES_V1,"maxAssetBytes"),maxRedirects=options.maxRedirects??DEFAULT_REDIRECTS_V14;if(!Number.isSafeInteger(maxRedirects)||maxRedirects<0||maxRedirects>MAX_REDIRECTS_V14)throw new NodeReleasePackageSourceErrorV1("invalid_configuration",`maxRedirects must be an integer between 0 and ${MAX_REDIRECTS_V14}`);let userAgent=options.userAgent??"agent-forge-plugin-release/1";if(userAgent.length===0||userAgent.length>256||/[\r\n]/u.test(userAgent))throw new NodeReleasePackageSourceErrorV1("invalid_configuration","userAgent is invalid");let fetchReleaseJson=async(url,headers,parentSignal)=>{let current=url;for(let redirect=0;;redirect+=1){let request=requestSignal3(parentSignal,timeoutMs),response2;try{response2=await transport(current.toString(),{method:"GET",headers:{accept:"application/json","user-agent":userAgent,...headers},redirect:"manual",signal:request.signal})}catch(error2){throw request.cleanup(),request.timedOut()?new NodeReleasePackageSourceErrorV1("request_timed_out","release API request timed out"):isAbortLike4(error2)?new NodeReleasePackageSourceErrorV1("cancelled","release API request was cancelled"):new NodeReleasePackageSourceErrorV1("request_failed","release API request failed")}if(!REDIRECT_STATUS4.has(response2.status))try{if(response2.status===404)throw new NodeReleasePackageSourceErrorV1("release_not_found","repo or release was not found");let limit=rateLimitState(response2);if(limit.limited){let message=limit.resetEpochSeconds===void 0?"rate limit was exceeded":`rate limit resets at ${new Date(limit.resetEpochSeconds*1e3).toISOString()}`;throw new NodeReleasePackageSourceErrorV1("rate_limited",message,{...limit.resetEpochSeconds===void 0?{}:{resetEpochSeconds:limit.resetEpochSeconds}})}if(response2.status<200||response2.status>=300)throw new NodeReleasePackageSourceErrorV1("request_failed","release API request did not succeed");if(!isJsonResponse2(response2))throw new NodeReleasePackageSourceErrorV1("invalid_response","release API response must be JSON");return await readBody2(response2,maxResponseBytes,request.signal)}finally{await response2.body?.cancel().catch(()=>{}),request.cleanup()}let location=response2.headers.get("location");if(await response2.body?.cancel().catch(()=>{}),request.cleanup(),location===null||redirect>=maxRedirects)throw new NodeReleasePackageSourceErrorV1("request_failed","release API redirect limit exceeded");let next;try{next=new URL(location,current)}catch{throw new NodeReleasePackageSourceErrorV1("invalid_response","release API redirect target is invalid")}if(next.protocol!=="http:"&&next.protocol!=="https:"||next.username!==""||next.password!=="")throw new NodeReleasePackageSourceErrorV1("invalid_response","release API redirect must stay http(s)");current=next}};return{version:1,downloadReleaseAsset:async input=>{if(input.signal?.aborted===!0)throw new NodeReleasePackageSourceErrorV1("cancelled","release asset download was cancelled");let sourceLabel=`${input.kind}:${input.owner}/${input.repo}@${input.tag??"latest"}`,base=input.kind==="github"?githubOrigin:giteeOrigin,segments=[base.pathPrefix===""?void 0:base.pathPrefix,"repos",encodeURIComponent(input.owner),encodeURIComponent(input.repo),"releases",...input.tag===void 0?[]:["tags",encodeURIComponent(input.tag)]].filter(segment2=>segment2!==void 0),endpoint=new URL(`${base.origin}/${segments.join("/")}`),headers=input.kind==="github"?{"x-github-api-version":"2022-11-28",...githubToken===void 0?{}:{authorization:`Bearer ${githubToken}`}}:{};input.kind==="gitee"&&giteeToken!==void 0&&endpoint.searchParams.set("access_token",giteeToken);let payload2=await fetchReleaseJson(endpoint,headers,input.signal),release=input.tag===void 0?firstPublishedRelease(parseReleaseList(payload2)):parseReleaseObject(payload2),assetUrl=selectPackageAssetUrl(release),download=await downloadNodeUrlPackageV1({...options.fetch===void 0?{}:{fetch:options.fetch},requestTimeoutMs:timeoutMs,maxPackageBytes:maxAssetBytes,userAgent},{url:assetUrl,...input.expectedDigestHex===void 0?{}:{expectedDigestHex:input.expectedDigestHex},signal:input.signal});return{bytes:download.bytes,mediaType:download.mediaType,sha256Hex:download.digestHex,sourceLabel}}}}import{gzipSync}from"node:zlib";var TAR_BLOCK_BYTES_V12=512,TAR_NAME_LENGTH_V12=100,TAR_MODE_LENGTH_V1=8,TAR_SIZE_LENGTH_V12=12,TAR_CHECKSUM_LENGTH_V12=8,TAR_PREFIX_LENGTH_V12=155,NodeTarWriterErrorV1=class extends Error{code;constructor(code,message){super(message),this.name="NodeTarWriterErrorV1",this.code=code}};function octalField(value,length){let digits=length-1,octal=value.toString(8);if(octal.length>digits)throw new NodeTarWriterErrorV1("invalid_entry","tar header field overflows");return`${octal.padStart(digits,"0")}\0`}function writeHeader(header,entry,nameField,prefixField){header.fill(0);let encode=(value,offset,length)=>{let bytes=new TextEncoder().encode(value);if(bytes.byteLength>length)throw new NodeTarWriterErrorV1("entry_name_too_long","tar header name field overflows");header.set(bytes,offset)};encode(nameField,0,TAR_NAME_LENGTH_V12-1);let contentBytes=entry.directory?0:entry.bytes?.byteLength??0,mode=octalField(entry.directory?493:420,TAR_MODE_LENGTH_V1),encodedMode=new TextEncoder().encode(mode);header.set(encodedMode,100),header.set(new TextEncoder().encode(octalField(0,TAR_MODE_LENGTH_V1)),108),header.set(new TextEncoder().encode(octalField(0,TAR_MODE_LENGTH_V1)),116),header.set(new TextEncoder().encode(octalField(contentBytes,TAR_SIZE_LENGTH_V12)),124),header.set(new TextEncoder().encode(octalField(0,TAR_SIZE_LENGTH_V12)),136),header[156]=entry.directory?53:48;let magic=new TextEncoder().encode("ustar\0");header.set(magic,257),header.set(new TextEncoder().encode("00"),263),prefixField.length>0&&encode(prefixField,345,TAR_PREFIX_LENGTH_V12-1);let checksum=0;for(let index3=148;index3<148+TAR_CHECKSUM_LENGTH_V12;index3+=1)header[index3]=32;for(let byte of header)checksum+=byte;let checksumText=`${checksum.toString(8).padStart(6,"0")}\0 `;header.set(new TextEncoder().encode(checksumText),148)}function entryFields(name){let bytes=new TextEncoder().encode(name);if(bytes.byteLength<=TAR_NAME_LENGTH_V12-1)return{name,prefix:""};let split=-1;for(let index3=Math.min(bytes.byteLength,TAR_PREFIX_LENGTH_V12)-1;index3>=0;index3-=1)if(bytes[index3]===47){split=index3;break}if(split<=0)throw new NodeTarWriterErrorV1("entry_name_too_long","tar entry name cannot be split into ustar fields");let prefix=name.slice(0,split),rest=name.slice(split+1);if(new TextEncoder().encode(rest).byteLength>TAR_NAME_LENGTH_V12-1||new TextEncoder().encode(prefix).byteLength>TAR_PREFIX_LENGTH_V12-1)throw new NodeTarWriterErrorV1("entry_name_too_long","tar entry name cannot be split into ustar fields");return{name:rest,prefix}}function headerBlock(entry){if(typeof entry.name!="string"||entry.name.length===0)throw new NodeTarWriterErrorV1("invalid_entry","tar entry name is invalid");if(normalizedEntryName(entry.directory?`${entry.name}/`:entry.name).name!==entry.name)throw new NodeTarWriterErrorV1("invalid_entry","tar entry name is not normalized");if(entry.directory&&entry.bytes!==void 0&&entry.bytes.byteLength>0)throw new NodeTarWriterErrorV1("invalid_entry","tar directory entry must be empty");if(!entry.directory&&!(entry.bytes instanceof Uint8Array))throw new NodeTarWriterErrorV1("invalid_entry","tar file entry requires bytes");let header=new Uint8Array(TAR_BLOCK_BYTES_V12),fields=entryFields(entry.name);return writeHeader(header,entry,fields.name,fields.prefix),header}function buildNodeTarBytesV1(entries){if(!Array.isArray(entries))throw new NodeTarWriterErrorV1("invalid_entry","tar entries must be an array");let names2=new Set,blocks=[];for(let entry of entries){if(names2.has(entry.name))throw new NodeTarWriterErrorV1("invalid_entry",`duplicate tar entry name: ${entry.name}`);if(names2.add(entry.name),blocks.push(headerBlock(entry)),!entry.directory){let bytes=entry.bytes??new Uint8Array,padding=(TAR_BLOCK_BYTES_V12-bytes.byteLength%TAR_BLOCK_BYTES_V12)%TAR_BLOCK_BYTES_V12;blocks.push(bytes,new Uint8Array(padding))}}blocks.push(new Uint8Array(TAR_BLOCK_BYTES_V12),new Uint8Array(TAR_BLOCK_BYTES_V12));let total=0;for(let block of blocks)total+=block.byteLength;let output=new Uint8Array(total),offset=0;for(let block of blocks)output.set(block,offset),offset+=block.byteLength;return output}function buildNodeTarGzBytesV1(entries){return gzipSync(buildNodeTarBytesV1(entries))}var NODE_PLUGIN_ACQUISITION_HOST_VERSION_V1=1,MAX_PACKAGE_MANIFEST_BYTES_V12=64*1024,ECOSYSTEM_MANIFEST_FILE_V13="agent-forge.json",ACQUISITION_ARTIFACT_EXPIRES_AT_V1="2099-01-01T00:00:00.000Z",ARTIFACT_CHUNK_BYTES_V1=64*1024,AGENT_FORGE_NPM_REGISTRY_ENV_V1="AGENT_FORGE_NPM_REGISTRY",AGENT_FORGE_NPM_TOKEN_ENV_V1="AGENT_FORGE_NPM_TOKEN",AGENT_FORGE_GITHUB_API_ENV_V1="AGENT_FORGE_GITHUB_API",AGENT_FORGE_GITEE_API_ENV_V1="AGENT_FORGE_GITEE_API",GITHUB_TOKEN_ENV_V1="GITHUB_TOKEN",GITEE_TOKEN_ENV_V1="GITEE_TOKEN",LOCAL_PROBE_V1={statLocalRef:path15=>{let stats=lstatSync2(path15,{throwIfNoEntry:!1});return stats===void 0?"missing":stats.isSymbolicLink()?"other":stats.isDirectory()?"directory":stats.isFile()?"file":"other"}};function mapInstallError(error2){return error2 instanceof PluginAcquisitionErrorV1?error2:error2 instanceof NodePackageInstallErrorV1?error2.code==="cancelled"?new PluginAcquisitionErrorV1("cancelled"):error2.code==="archive_budget_exceeded"?new PluginAcquisitionErrorV1("budget_exceeded"):error2.code==="unsupported_media_type"?new PluginAcquisitionErrorV1("unsupported_media_type"):new PluginAcquisitionErrorV1("package_invalid"):new PluginAcquisitionErrorV1("download_failed")}function mapNpmError(error2){return error2 instanceof PluginAcquisitionErrorV1?error2:error2 instanceof NodeNpmRegistrySourceErrorV1?error2.code==="package_not_found"?new PluginAcquisitionErrorV1("package_not_found"):error2.code==="version_not_found"?new PluginAcquisitionErrorV1("version_not_found"):error2.code==="cancelled"?new PluginAcquisitionErrorV1("cancelled"):error2.code==="invalid_response"||error2.code==="integrity_unsupported"?new PluginAcquisitionErrorV1("package_invalid"):new PluginAcquisitionErrorV1("download_failed"):mapInstallError(error2)}function mapUrlError(error2){return error2 instanceof PluginAcquisitionErrorV1?error2:error2 instanceof NodeUrlPackageSourceErrorV1?error2.code==="digest_mismatch"?new PluginAcquisitionErrorV1("digest_mismatch"):error2.code==="cancelled"?new PluginAcquisitionErrorV1("cancelled"):error2.code==="invalid_url"||error2.code==="invalid_configuration"?new PluginAcquisitionErrorV1("invalid_ref"):error2.code==="response_too_large"?new PluginAcquisitionErrorV1("budget_exceeded"):new PluginAcquisitionErrorV1("download_failed"):mapInstallError(error2)}function mapReleaseError(error2){return error2 instanceof PluginAcquisitionErrorV1?error2:error2 instanceof NodeReleasePackageSourceErrorV1?error2.code==="cancelled"?new PluginAcquisitionErrorV1("cancelled"):error2.code==="invalid_configuration"?new PluginAcquisitionErrorV1("invalid_ref"):error2.code==="response_too_large"?new PluginAcquisitionErrorV1("budget_exceeded"):error2.code==="invalid_response"?new PluginAcquisitionErrorV1("package_invalid"):error2.code==="rate_limited"?new PluginAcquisitionErrorV1("rate_limited",error2.resetEpochSeconds===void 0?void 0:`rate limit resets at ${new Date(error2.resetEpochSeconds*1e3).toISOString()}`):error2.code==="release_not_found"||error2.code==="release_asset_not_found"||error2.code==="release_asset_ambiguous"?new PluginAcquisitionErrorV1(error2.code,error2.message):new PluginAcquisitionErrorV1("download_failed"):mapUrlError(error2)}function shaHex(algorithm,bytes){return createHash5(algorithm).update(bytes).digest("hex")}function signalAborted(signal){return signal?.aborted===!0}function pluginAcquisitionManifestFromEntriesV1(entries){let manifestEntry=entries.find(entry=>entry.name===ECOSYSTEM_MANIFEST_FILE_V13&&!entry.directory);if(manifestEntry===void 0||manifestEntry.bytes.byteLength>MAX_PACKAGE_MANIFEST_BYTES_V12)throw new PluginAcquisitionErrorV1("package_invalid");let value;try{value=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(manifestEntry.bytes))}catch{throw new PluginAcquisitionErrorV1("package_invalid")}if(typeof value!="object"||value===null||Array.isArray(value))throw new PluginAcquisitionErrorV1("package_invalid");let record=value,manifestKeys2=new Set(["id","pluginVersion","apiVersion","minHostVersion","maxHostVersion","capabilityRefs","requires","platform","testOnly"]);if(record.packageFormatVersion!==1||Object.keys(record).some(key=>key!=="packageFormatVersion"&&!manifestKeys2.has(key)))throw new PluginAcquisitionErrorV1("package_invalid");let id=record.id,pluginVersion=record.pluginVersion,apiVersion=record.apiVersion;if(typeof id!="string"||id.trim().length===0||id.length>256||typeof pluginVersion!="string"||pluginVersion.trim().length===0||pluginVersion.length>256||typeof apiVersion!="string"||apiVersion.trim().length===0||apiVersion.length>256)throw new PluginAcquisitionErrorV1("package_invalid");if(record.minHostVersion===void 0&&record.maxHostVersion===void 0)throw new PluginAcquisitionErrorV1("package_invalid");let manifest=Object.freeze({id,pluginVersion,apiVersion,...record.minHostVersion===void 0?{}:{minHostVersion:record.minHostVersion},...record.maxHostVersion===void 0?{}:{maxHostVersion:record.maxHostVersion},...record.capabilityRefs===void 0?{}:{capabilityRefs:record.capabilityRefs},...record.requires===void 0?{}:{requires:record.requires},...record.platform===void 0?{}:{platform:record.platform},...record.testOnly===void 0?{}:{testOnly:record.testOnly}});return{manifest,manifestDigest:pluginManifestDigestV1(manifest)}}function createNodePluginAcquisitionHostV1(options={}){let limits=options.limits??{},npmRegistryOption=options.npmRegistry??process.env[AGENT_FORGE_NPM_REGISTRY_ENV_V1]?.trim(),npmTokenOption=options.npmToken??process.env[AGENT_FORGE_NPM_TOKEN_ENV_V1]?.trim(),githubApiOriginOption=options.githubApiOrigin??process.env[AGENT_FORGE_GITHUB_API_ENV_V1]?.trim(),giteeApiOriginOption=options.giteeApiOrigin??process.env[AGENT_FORGE_GITEE_API_ENV_V1]?.trim(),githubTokenOption=options.githubToken??process.env[GITHUB_TOKEN_ENV_V1]?.trim(),giteeTokenOption=options.giteeToken??process.env[GITEE_TOKEN_ENV_V1]?.trim(),npmSource=createNodeNpmRegistrySourceV1({...npmRegistryOption===void 0||npmRegistryOption===""?{}:{registry:npmRegistryOption},...npmTokenOption===void 0||npmTokenOption===""?{}:{token:npmTokenOption},...options.fetch===void 0?{}:{fetch:options.fetch},...options.requestTimeoutMs===void 0?{}:{requestTimeoutMs:options.requestTimeoutMs},...options.maxResponseBytes===void 0?{}:{maxResponseBytes:options.maxResponseBytes},...options.maxTarballBytes===void 0?{}:{maxTarballBytes:options.maxTarballBytes},...options.userAgent===void 0?{}:{userAgent:options.userAgent}}),releaseSource=createNodeReleasePackageSourceV1({...githubApiOriginOption===void 0||githubApiOriginOption===""?{}:{githubApiOrigin:githubApiOriginOption},...giteeApiOriginOption===void 0||giteeApiOriginOption===""?{}:{giteeApiOrigin:giteeApiOriginOption},...githubTokenOption===void 0||githubTokenOption===""?{}:{githubToken:githubTokenOption},...giteeTokenOption===void 0||giteeTokenOption===""?{}:{giteeToken:giteeTokenOption},...options.fetch===void 0?{}:{fetch:options.fetch},...options.requestTimeoutMs===void 0?{}:{requestTimeoutMs:options.requestTimeoutMs},...options.maxResponseBytes===void 0?{}:{maxResponseBytes:options.maxResponseBytes},...options.maxTarballBytes===void 0?{}:{maxAssetBytes:options.maxTarballBytes},...options.userAgent===void 0?{}:{userAgent:options.userAgent}}),artifacts=new Map,closed=!1,acquireBytes=async(ref,signal)=>{if(ref.kind==="github"||ref.kind==="gitee")try{let download=await releaseSource.downloadReleaseAsset({kind:ref.kind,owner:ref.owner,repo:ref.repo,...ref.tag===void 0?{}:{tag:ref.tag},...ref.expectedDigestHex===void 0?{}:{expectedDigestHex:ref.expectedDigestHex},signal});return{bytes:download.bytes,mediaType:download.mediaType,digest:{algorithm:"sha256",hex:download.sha256Hex},source:download.sourceLabel}}catch(error2){throw mapReleaseError(error2)}if(ref.kind==="npm")try{let resolved=await npmSource.resolveNpmPackage({name:ref.name,...ref.range===void 0?{}:{range:ref.range},signal}),bytes=await npmSource.fetchTarball({url:resolved.tarballUrl,signal});if(shaHex(resolved.integrity.algorithm,bytes)!==resolved.integrity.hex)throw new PluginAcquisitionErrorV1("digest_mismatch");return{bytes,mediaType:"application/gzip",digest:resolved.integrity,source:`npm:${new URL(resolved.tarballUrl).host}`}}catch(error2){throw mapNpmError(error2)}if(ref.kind==="url")try{let download=await downloadNodeUrlPackageV1({...options.fetch===void 0?{}:{fetch:options.fetch},...options.requestTimeoutMs===void 0?{}:{requestTimeoutMs:options.requestTimeoutMs},...options.maxTarballBytes===void 0?{}:{maxPackageBytes:options.maxTarballBytes},...options.userAgent===void 0?{}:{userAgent:options.userAgent}},{url:ref.url,...ref.expectedDigestHex===void 0?{}:{expectedDigestHex:ref.expectedDigestHex},signal});return{bytes:download.bytes,mediaType:download.mediaType,digest:{algorithm:"sha256",hex:download.digestHex},source:`url:${new URL(ref.url).host}`}}catch(error2){throw mapUrlError(error2)}if(ref.kind==="local-file")try{let bytes=await readLocalPackageFileV1(ref.path,limits,signal),fileName=ref.path.split(/[\\/]/u).pop(),mediaType=detectPluginPackageMediaTypeV1(bytes,fileName===void 0||fileName.length===0?void 0:fileName);return{bytes,mediaType,digest:{algorithm:"sha256",hex:shaHex("sha256",bytes)},source:"local:file"}}catch(error2){throw mapInstallError(error2)}if(ref.kind==="local-path")try{let entries=await collectLocalDirectoryPackageEntriesV1(ref.path,limits,signal),bytes=buildNodeTarGzBytesV1(entries.map(entry=>({name:entry.name,directory:entry.directory,bytes:entry.bytes})));return{bytes,mediaType:"application/gzip",digest:{algorithm:"sha256",hex:shaHex("sha256",bytes)},source:"local:dir"}}catch(error2){throw mapInstallError(error2)}throw new PluginAcquisitionErrorV1("invalid_ref")},releaseArtifact=async input=>{if(!artifacts.delete(input.artifact.artifactRef))throw new NodePackageInstallErrorV1("invalid_artifact")};return{version:NODE_PLUGIN_ACQUISITION_HOST_VERSION_V1,resolvePackage:async input=>{if(closed||signalAborted(input.signal))throw new PluginAcquisitionErrorV1("cancelled");let ref;try{ref=parsePluginAcquisitionRefV1(input.ref,LOCAL_PROBE_V1)}catch(error2){throw error2 instanceof PluginAcquisitionErrorV1?error2:new PluginAcquisitionErrorV1("invalid_ref")}let acquired=await acquireBytes(ref,input.signal);if(signalAborted(input.signal))throw new PluginAcquisitionErrorV1("cancelled");let entries;try{entries=acquired.mediaType==="application/gzip"?await parseNodeTarGzPackageV1(acquired.bytes,limits):parseNodeZipPackageV1(acquired.bytes,limits)}catch(error2){throw mapInstallError(error2)}let identity=pluginAcquisitionManifestFromEntriesV1(entries);if(closed)throw new PluginAcquisitionErrorV1("cancelled");let artifactRef=`plugin-acquisition://node/${randomUUID7()}`,artifact=Object.freeze({version:1,source:acquired.source,pluginId:identity.manifest.id,pluginVersion:identity.manifest.pluginVersion,manifestDigest:identity.manifestDigest,artifactDigest:acquired.digest.algorithm==="sha512"?`sha512:${acquired.digest.hex}`:`sha256:${acquired.digest.hex}`,expiresAt:ACQUISITION_ARTIFACT_EXPIRES_AT_V1,sizeBytes:acquired.bytes.byteLength,mediaType:acquired.mediaType,artifactRef});return artifacts.set(artifactRef,{bytes:acquired.bytes,artifact}),Object.freeze({manifest:identity.manifest,manifestDigest:identity.manifestDigest,source:acquired.source,artifact,release:async()=>{try{return await releaseArtifact({artifact:{artifactRef}}),!0}catch{return!1}}})},openArtifact(input){return(async function*(){let record=artifacts.get(input.artifact.artifactRef);if(record===void 0)throw new NodePackageInstallErrorV1("invalid_artifact");if(record.artifact.pluginId!==input.artifact.pluginId||record.artifact.pluginVersion!==input.artifact.pluginVersion||record.artifact.manifestDigest!==input.artifact.manifestDigest||record.artifact.artifactDigest!==input.artifact.artifactDigest||record.artifact.sizeBytes!==input.artifact.sizeBytes)throw new NodePackageInstallErrorV1("invalid_artifact");for(let offset=0;offset<record.bytes.byteLength;offset+=ARTIFACT_CHUNK_BYTES_V1){if(input.signal?.aborted===!0)throw new NodePackageInstallErrorV1("cancelled");yield new Uint8Array(record.bytes.subarray(offset,Math.min(offset+ARTIFACT_CHUNK_BYTES_V1,record.bytes.byteLength)))}})()},releaseArtifact,ownsArtifact:input=>artifacts.has(input.artifactRef),async close(){closed=!0,artifacts.clear()}}}var NodeHttpPluginRegistrySourceErrorV1=class extends Error{code;constructor(code,message){super(message),this.name="NodeHttpPluginRegistrySourceErrorV1",this.code=code}};function boundedPositive5(value,fallback,maximum,label){let result=value??fallback;if(!Number.isSafeInteger(result)||result<=0||result>maximum)throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration",`${label} must be a positive integer at most ${maximum}`);return result}function allowedOrigin2(value){let parsed;try{parsed=new URL(value)}catch{throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","Allowed registry origin is invalid")}if(parsed.protocol!=="http:"&&parsed.protocol!=="https:"||parsed.username||parsed.password)throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","Allowed registry origin must be an http(s) origin without credentials");if(parsed.pathname!=="/"||parsed.search!==""||parsed.hash!=="")throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","Allowed registry origin must not include a path, query, or fragment");return parsed.origin}function endpointUrl(value,origins){let parsed;try{parsed=new URL(value)}catch{throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","Plugin registry URL is invalid")}if(parsed.protocol!=="http:"&&parsed.protocol!=="https:"||parsed.username||parsed.password)throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","Plugin registry URL must use http(s) without credentials");if(parsed.search!==""||parsed.hash!=="")throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","Plugin registry URL must not include a query or fragment");if(!origins.has(parsed.origin))throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","Plugin registry origin is not allowed");return parsed}function responseLength(response2){let raw=response2.headers.get("content-length");if(raw===null)return;if(!/^\d+$/u.test(raw))throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response","Plugin registry response length is invalid");let value=Number(raw);if(!Number.isSafeInteger(value))throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response","Plugin registry response length is invalid");return value}function isJsonResponse3(response2){let contentType2=response2.headers.get("content-type");if(contentType2===null)return!1;let mediaType=contentType2.split(";",1)[0]?.trim().toLowerCase();return mediaType==="application/json"||mediaType==="application/vnd.agent-forge.plugin-registry+json"}function requestController(parent,timeoutMs){let controller=new AbortController,timedOut=!1,abort=()=>controller.abort(parent?.reason);parent?.aborted===!0?abort():parent?.addEventListener("abort",abort,{once:!0});let timeout=setTimeout(()=>{timedOut=!0,controller.abort()},timeoutMs);return{signal:controller.signal,timedOut:()=>timedOut,cleanup:()=>{clearTimeout(timeout),parent?.removeEventListener("abort",abort)}}}function abortPromise(signal){let rejectAbort;return{promise:new Promise((_resolve,reject2)=>{rejectAbort=()=>reject2(new DOMException("aborted","AbortError")),signal.aborted?rejectAbort():signal.addEventListener("abort",rejectAbort,{once:!0})}),cleanup:()=>{rejectAbort!==void 0&&signal.removeEventListener("abort",rejectAbort)}}}async function awaitBeforeAbort(operation,signal){let abort=abortPromise(signal);try{return await Promise.race([operation,abort.promise])}finally{abort.cleanup()}}function discardResponseBody(response2){let responseBody=response2?.body;responseBody?.cancel().catch(()=>{})}async function readBody3(response2,maxBytes,signal){if(response2.body===null)throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response","Plugin registry response has no body");let reader=response2.body.getReader(),chunks=[],total=0;try{for(;;){if(signal.aborted)throw new DOMException("aborted","AbortError");let item=await awaitBeforeAbort(reader.read(),signal);if(item.done)break;if(total+=item.value.byteLength,total>maxBytes)throw new NodeHttpPluginRegistrySourceErrorV1("response_too_large","Plugin registry response exceeds the configured size limit");chunks.push(item.value)}}finally{reader.releaseLock()}let bytes=new Uint8Array(total),offset=0;for(let chunk of chunks)bytes.set(chunk,offset),offset+=chunk.byteLength;return bytes}function parseDocument(bytes){let value;try{value=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(bytes))}catch{throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response","Plugin registry response is not valid JSON")}if(typeof value!="object"||value===null||Array.isArray(value))throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response","Plugin registry document is invalid");let document=value;if(Object.keys(document).some(key=>key!=="version"&&key!=="entries")||document.version!==1||!Array.isArray(document.entries))throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response","Plugin registry document is invalid");return document.entries}function isAbortLike5(error2){return error2 instanceof DOMException&&error2.name==="AbortError"}function isCallerCancelled(signal){return signal?.aborted===!0}function sanitizedSourceError(error2){let code=error2.code;return code!=="cancelled"&&code!=="invalid_configuration"&&code!=="request_failed"&&code!=="request_timed_out"&&code!=="invalid_response"&&code!=="response_too_large"?new NodeHttpPluginRegistrySourceErrorV1("request_failed","Plugin registry request failed"):new NodeHttpPluginRegistrySourceErrorV1(code,"Plugin registry request failed")}function createNodeHttpPluginRegistrySourceV1(options){let transport=options.fetch??globalThis.fetch;if(typeof transport!="function")throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","Node fetch is unavailable");if(!Array.isArray(options.allowedOrigins)||options.allowedOrigins.length===0)throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","At least one allowed registry origin is required");let origins=new Set(options.allowedOrigins.map(allowedOrigin2)),endpoint=endpointUrl(options.url,origins),timeoutMs=boundedPositive5(options.requestTimeoutMs,15e3,12e4,"requestTimeoutMs"),maxResponseBytes=boundedPositive5(options.maxResponseBytes,4194304,8388608,"maxResponseBytes"),userAgent=options.userAgent??"agent-forge-plugin-registry/1";if(userAgent.length===0||userAgent.length>256||/[\r\n]/u.test(userAgent))throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration","userAgent is invalid");return{version:1,source:endpoint.origin+endpoint.pathname,list:async({signal}={})=>{if(isCallerCancelled(signal))throw new NodeHttpPluginRegistrySourceErrorV1("cancelled","Plugin registry request was cancelled");let request=requestController(signal,timeoutMs),response2;try{let transportResponse=Promise.resolve().then(()=>{if(request.signal.aborted)throw new DOMException("aborted","AbortError");return transport(endpoint.toString(),{method:"GET",headers:{accept:"application/vnd.agent-forge.plugin-registry+json, application/json","user-agent":userAgent},redirect:"error",signal:request.signal})});transportResponse.then(lateResponse=>{request.signal.aborted&&discardResponseBody(lateResponse)},()=>{});let receivedResponse=await awaitBeforeAbort(transportResponse,request.signal);if(response2=receivedResponse,receivedResponse.status<200||receivedResponse.status>=300)throw new NodeHttpPluginRegistrySourceErrorV1("request_failed","Plugin registry request did not succeed");if(!isJsonResponse3(receivedResponse))throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response","Plugin registry response must be JSON");let length=responseLength(receivedResponse);if(length!==void 0&&length>maxResponseBytes)throw new NodeHttpPluginRegistrySourceErrorV1("response_too_large","Plugin registry response exceeds the configured size limit");return parseDocument(await readBody3(receivedResponse,maxResponseBytes,request.signal))}catch(error2){throw isCallerCancelled(signal)?new NodeHttpPluginRegistrySourceErrorV1("cancelled","Plugin registry request was cancelled"):request.timedOut()?new NodeHttpPluginRegistrySourceErrorV1("request_timed_out","Plugin registry request timed out"):error2 instanceof NodeHttpPluginRegistrySourceErrorV1?sanitizedSourceError(error2):isAbortLike5(error2)?new NodeHttpPluginRegistrySourceErrorV1("cancelled","Plugin registry request was cancelled"):new NodeHttpPluginRegistrySourceErrorV1("request_failed","Plugin registry request failed")}finally{request.cleanup(),discardResponseBody(response2)}}}}function createPluginEcosystemRegistryAdapterV1(registry){if(registry.resolve===void 0)throw new PluginRegistryErrorV1("invalid_source","Registry does not expose a host-side package resolver");let resolve25=registry.resolve,list=registry.listManifests;return{...list===void 0?{}:{list},resolve:resolve25}}var DEFAULT_PLUGIN_REGISTRY_ORIGIN_ENV_V1="AGENT_FORGE_PLUGIN_REGISTRY_ORIGIN",DEFAULT_PLUGIN_TRUST_KEYS_ENV_V1="AGENT_FORGE_PLUGIN_TRUST_KEYS",DEFAULT_PLUGIN_REGISTRY_PATH_V1="/v1/plugin-registry.json";async function createDefaultPluginMarketWiringV1(options){let origin=(options.registryOrigin??process.env[DEFAULT_PLUGIN_REGISTRY_ORIGIN_ENV_V1])?.trim(),effectiveOrigin=origin===""?void 0:origin,storeParent=defaultPluginInstallStoreDirectoryV1(options.agentDir),instanceRoot=defaultPluginInstallStoreInstanceRootV1(options.agentDir),diskSource=createNodeDiskPluginRegistrySourceV1({rootDirectory:instanceRoot}),httpSource=effectiveOrigin===void 0?void 0:createNodeHttpPluginRegistrySourceV1({url:new URL(effectiveOrigin+DEFAULT_PLUGIN_REGISTRY_PATH_V1),allowedOrigins:[effectiveOrigin],...options.fetch===void 0?{}:{fetch:options.fetch}}),source={...httpSource===void 0?{}:{source:httpSource.source},list:async({signal}={})=>{let disk=await diskSource.list({signal});if(httpSource===void 0)return disk;let remote=await httpSource.list({signal});return Object.freeze([...remote,...disk])}},distributionHost=effectiveOrigin===void 0?void 0:await createNodeHttpPluginDistributionHostV1({allowedOrigins:[effectiveOrigin],artifactDirectory:join18(storeParent,"distribution-cache-v1"),...options.fetch===void 0?{}:{fetch:options.fetch}}),trustKeys=options.trustKeys;if(trustKeys===void 0&&effectiveOrigin!==void 0){let raw=process.env[DEFAULT_PLUGIN_TRUST_KEYS_ENV_V1];if(raw!==void 0&&raw.trim()!==""){let parsed;try{parsed=JSON.parse(raw)}catch{throw new Error(`${DEFAULT_PLUGIN_TRUST_KEYS_ENV_V1} must be a JSON array of {keyId, publicKeyPem}`)}if(!Array.isArray(parsed))throw new Error(`${DEFAULT_PLUGIN_TRUST_KEYS_ENV_V1} must be a JSON array`);trustKeys=parsed}}let trustRoot=trustKeys===void 0||distributionHost===void 0?void 0:createNodePluginTrustRootV1({keys:trustKeys}),acquisitionHost=options.acquisition??createNodePluginAcquisitionHostV1({...options.limits===void 0?{}:{limits:options.limits},...options.fetch===void 0?{}:{fetch:options.fetch}}),installHost=await createNodePackageInstallHostV1({openArtifact:input=>{if(acquisitionHost.ownsArtifact(input.artifact))return acquisitionHost.openArtifact(input);let reader=distributionHost?.openArtifact;if(reader===void 0)throw new NodePackageInstallErrorV1("invalid_artifact");return reader(input)},installationDirectory:storeParent,persistence:"persistent",supportedScopes:["global","project"],...options.limits===void 0?{}:{...options.limits}}),registry=createPluginRegistryV1({source,host:defaultPluginHostFactsV1(),verify:{verify:({manifestDigest,expectedDigest:expectedDigest2})=>expectedDigest2===void 0||expectedDigest2===manifestDigest?{status:"accepted"}:{status:"rejected",reason:"Manifest digest does not match the expected digest"}},sourceVerifier:()=>({status:"accepted"})});return{registry,cliRegistry:createPluginEcosystemRegistryAdapterV1(registry),acquisition:acquisitionHost,installer:createPluginInstallerV1({host:installHost}),...distributionHost===void 0||trustRoot===void 0?{}:{distribution:createPluginDistributionV1({host:distributionHost.host,verifySignature:trustRoot})},stateStore:createPluginStateStoreV1({filePath:join18(options.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)}),projectStateStore:createPluginStateStoreV1({filePath:join18(options.cwd,CONFIG_DIR_NAME,DEFAULT_PLUGIN_STATE_FILE_V1)}),close:async()=>{await installHost.close(),await acquisitionHost.close(),await distributionHost?.close()}}}async function createNodePluginPackageInstallStackV1(options){let distributionHost=await createNodeHttpPluginDistributionStackV1(options.distribution);try{let packageOptions={...options.packageHost,openArtifact:distributionHost.openArtifact},packageHost=options.session===void 0?await createNodePackageInstallHostV1(packageOptions):await createNodePackageInstallHostForSessionV1(packageOptions,options.session);try{let installer=createPluginInstallerV1({host:packageHost,...options.verifier===void 0?{}:{verifier:options.verifier}}),closePromise,close=()=>(closePromise!==void 0||(closePromise=(async()=>{let failure2;try{await packageHost.close()}catch(error2){failure2=error2}try{await distributionHost.close()}catch(error2){failure2===void 0&&(failure2=error2)}if(failure2!==void 0)throw failure2})()),closePromise);return Object.freeze({distributionHost,distribution:distributionHost.distribution,packageHost,installer,close})}catch(error2){throw await packageHost.close().catch(()=>{}),error2}}catch(error2){throw await distributionHost.close().catch(()=>{}),error2}}import{randomUUID as randomUUID8}from"node:crypto";import{mkdir as mkdir5,readFile as readFile6,rename as rename5,unlink as unlink2,writeFile as writeFile4}from"node:fs/promises";import{basename as basename3,dirname as dirname7,isAbsolute as isAbsolute7,join as join19,resolve as resolve5}from"node:path";var PLUGIN_SELECTION_STORE_VERSION_V1=1,MAX_PLUGIN_SELECTION_PROFILES_V1=256,MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1=4096,EMPTY_SNAPSHOT2=Object.freeze({version:PLUGIN_SELECTION_STORE_VERSION_V1,selections:Object.freeze([])});function diagnostic4(code,message,profileId){return Object.freeze(profileId===void 0?{code,message}:{code,message,profileId})}function isAbortError2(error2){return error2 instanceof Error&&(error2.name==="AbortError"||error2.name==="AbortSignalError")}function isMissingError3(error2){return typeof error2=="object"&&error2!==null&&"code"in error2&&error2.code==="ENOENT"}function validateFilePath2(value){if(typeof value!="string"||value.trim()===""||value.length>MAX_PLUGIN_SELECTION_STORE_PATH_CHARS_V1)throw new Error("invalid plugin selection file path");if(value.includes("\0")||/[\u0000-\u001f]/u.test(value))throw new Error("invalid plugin selection file path");if(/^file:/iu.test(value)||/^[a-z][a-z\d+.-]*:/iu.test(value)&&!/^[a-z]:[\\/]/iu.test(value))throw new Error("invalid plugin selection file path");let normalized=isAbsolute7(value)?value:resolve5(value);if(basename3(normalized).length===0||basename3(normalized)==="."||basename3(normalized)==="..")throw new Error("invalid plugin selection file path");return normalized}function isObject3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function hasExactKeys3(value,keys){let expected=new Set(keys);return Object.keys(value).length===expected.size&&Object.keys(value).every(key=>expected.has(key))}function validateProfile(value){if(!isObject3(value)||!hasExactKeys3(value,["profileId","selectedPluginIds","disabledPluginIds"]))throw new Error("selection schema is invalid");if(!Array.isArray(value.selectedPluginIds)||!Array.isArray(value.disabledPluginIds))throw new Error("selection IDs must be arrays");if(value.selectedPluginIds.length>MAX_PLUGIN_SELECTION_IDS_V1||value.disabledPluginIds.length>MAX_PLUGIN_SELECTION_IDS_V1)throw new Error("too many plugin IDs");return createPluginSelectionV1({profileId:value.profileId,selectedPluginIds:value.selectedPluginIds,disabledPluginIds:value.disabledPluginIds})}function validateSnapshot2(value){if(!isObject3(value)||!hasExactKeys3(value,["version","selections"]))throw new Error("snapshot schema is invalid");if(value.version!==PLUGIN_SELECTION_STORE_VERSION_V1)throw new Error("snapshot version is unsupported");if(!Array.isArray(value.selections))throw new Error("selections must be an array");if(value.selections.length>MAX_PLUGIN_SELECTION_PROFILES_V1)throw new Error("too many selection profiles");let selections=value.selections.map(validateProfile),profiles2=new Set;for(let selection of selections){if(profiles2.has(selection.profileId))throw new Error(`duplicate profile: ${selection.profileId}`);profiles2.add(selection.profileId)}return selections.sort((left,right)=>left.profileId.localeCompare(right.profileId)),Object.freeze({version:PLUGIN_SELECTION_STORE_VERSION_V1,selections:Object.freeze(selections)})}function invalidFromError2(error2){let message=error2 instanceof Error?error2.message:"plugin selection schema is invalid";if(message==="too many selection profiles")return diagnostic4("too_many_profiles",message);let duplicatePrefix="duplicate profile: ";if(message.startsWith(duplicatePrefix)){let profileId=message.slice(duplicatePrefix.length);return diagnostic4("duplicate_profile",message,profileId)}return diagnostic4("invalid_schema",message)}function defaultFileSystem2(){return{readFile:async path15=>await readFile6(path15,"utf8"),mkdir:async path15=>{await mkdir5(path15,{recursive:!0})},writeFile:async(path15,data)=>{await writeFile4(path15,data,"utf8")},rename:rename5,unlink:unlink2}}function cancelledResult2(){return Object.freeze({status:"cancelled",diagnostics:Object.freeze([diagnostic4("cancelled","Plugin selection operation was cancelled")])})}function sortSelections(selections){return Object.freeze([...selections].sort((left,right)=>left.profileId.localeCompare(right.profileId)))}function persistedSelection(selection){return Object.freeze({profileId:selection.profileId,selectedPluginIds:selection.selectedPluginIds,disabledPluginIds:selection.disabledPluginIds})}function createPluginSelectionStoreV1(options){let filePath=validateFilePath2(options.filePath),fileSystem=options.fileSystem??defaultFileSystem2();async function read(signal){if(signal?.aborted)return cancelledResult2();let content;try{content=await fileSystem.readFile(filePath)}catch(error2){if(isMissingError3(error2))return Object.freeze({status:"missing",snapshot:EMPTY_SNAPSHOT2});if(isAbortError2(error2)||signal?.aborted)return cancelledResult2();throw error2}if(signal?.aborted)return cancelledResult2();let parsed;try{parsed=JSON.parse(content)}catch{return Object.freeze({status:"invalid",diagnostics:Object.freeze([diagnostic4("invalid_json","plugin selection JSON is invalid")])})}try{return Object.freeze({status:"ok",snapshot:validateSnapshot2(parsed)})}catch(error2){return Object.freeze({status:"invalid",diagnostics:Object.freeze([invalidFromError2(error2)])})}}async function write(snapshot2,signal){if(signal?.aborted)return cancelledResult2();let temporaryPath=join19(dirname7(filePath),`.${basename3(filePath)}.${randomUUID8()}.tmp`);try{return await fileSystem.mkdir(dirname7(filePath)),signal?.aborted||(await fileSystem.writeFile(temporaryPath,`${JSON.stringify({version:snapshot2.version,selections:snapshot2.selections.map(persistedSelection)})}
508
- `),signal?.aborted)?cancelledResult2():(await fileSystem.rename(temporaryPath,filePath),Object.freeze({status:"ok",snapshot:snapshot2,changed:!0}))}finally{try{await fileSystem.unlink(temporaryPath)}catch{}}}let mutationTail=Promise.resolve();function enqueueMutation(operation){let result=mutationTail.then(operation,operation);return mutationTail=result.then(()=>{},()=>{}),result}return{read:async({signal}={})=>await read(signal),set:input=>enqueueMutation(async()=>{let selection;try{selection=createPluginSelectionV1(input.selection)}catch(error2){return Object.freeze({status:"invalid",diagnostics:Object.freeze([invalidFromError2(error2)])})}let current=await read(input.signal);if(current.status!=="ok"&&current.status!=="missing")return current;if(input.signal?.aborted)return cancelledResult2();let existing=current.snapshot.selections.find(item=>item.profileId===selection.profileId);if(existing!==void 0&&JSON.stringify(existing)===JSON.stringify(selection))return Object.freeze({status:"ok",snapshot:current.snapshot,changed:!1});if(current.snapshot.selections.length>=MAX_PLUGIN_SELECTION_PROFILES_V1&&existing===void 0)return Object.freeze({status:"invalid",diagnostics:Object.freeze([diagnostic4("too_many_profiles","too many selection profiles")])});let snapshot2=Object.freeze({version:PLUGIN_SELECTION_STORE_VERSION_V1,selections:sortSelections([...current.snapshot.selections.filter(item=>item.profileId!==selection.profileId),selection])});return await write(snapshot2,input.signal)}),clear:input=>enqueueMutation(async()=>{let selection;try{selection=createPluginSelectionV1({profileId:input.profileId,selectedPluginIds:[],disabledPluginIds:[]})}catch(error2){return Object.freeze({status:"invalid",diagnostics:Object.freeze([invalidFromError2(error2)])})}let current=await read(input.signal);if(current.status!=="ok"&&current.status!=="missing")return current;if(input.signal?.aborted)return cancelledResult2();let selections=current.snapshot.selections.filter(item=>item.profileId!==selection.profileId);return selections.length===current.snapshot.selections.length?Object.freeze({status:"ok",snapshot:current.snapshot,changed:!1}):await write(Object.freeze({version:PLUGIN_SELECTION_STORE_VERSION_V1,selections:sortSelections(selections)}),input.signal)})}}function freezeAssembly(assembly){return Object.freeze({...assembly,plugins:Object.freeze(assembly.plugins.map(plugin=>Object.freeze({...plugin,capabilityRefs:Object.freeze(plugin.capabilityRefs.map(ref=>Object.freeze({...ref}))),...plugin.selectedAdapter===void 0?{}:{selectedAdapter:Object.freeze({...plugin.selectedAdapter})}})))})}function assembleIdentity(input){let identity=buildProfileIdentityV1({profileId:input.profileId,profileVersion:input.profileVersion,resolvedPlugins:input.plugins,capabilityVersions:[...new Set(input.plugins.flatMap(plugin=>plugin.capabilityRefs))].sort((a,b2)=>a.id.localeCompare(b2.id)||a.version-b2.version)});return freezeAssembly({profileId:input.profileId,profileVersion:input.profileVersion,identity,plugins:[...input.plugins]})}function assembleProfile(input){let verified=new Map(input.verifiedPlugins.map(entry=>[`${entry.pluginId}@${entry.version}`,!0])),unverified=input.resolvedPlugins.filter(plugin=>!verified.has(`${plugin.pluginId}@${plugin.pluginVersion}`)).map(plugin=>({pluginId:plugin.pluginId,pluginVersion:plugin.pluginVersion}));return unverified.length>0?{status:"unverified",unverified}:{status:"assembled",assembly:assembleIdentity({profileId:input.profileId,profileVersion:input.profileVersion,plugins:input.resolvedPlugins})}}function replaceProfilePlugin(assembly,input){let fromPlugin=assembly.plugins.find(plugin=>plugin.pluginId===input.fromPluginId);if(!fromPlugin)return{status:"absent",pluginId:input.fromPluginId};if(!new Map(input.verifiedPlugins.map(entry=>[`${entry.pluginId}@${entry.version}`,!0])).has(`${input.replacement.pluginId}@${input.replacement.pluginVersion}`))return{status:"unverified",unverified:[{pluginId:input.replacement.pluginId,pluginVersion:input.replacement.pluginVersion}]};let nextPlugins=assembly.plugins.filter(plugin=>plugin.pluginId!==input.fromPluginId).concat([input.replacement]);return{status:"replaced",assembly:assembleIdentity({profileId:assembly.profileId,profileVersion:assembly.profileVersion,plugins:nextPlugins}),replacement:{from:{pluginId:fromPlugin.pluginId,pluginVersion:fromPlugin.pluginVersion},to:{pluginId:input.replacement.pluginId,pluginVersion:input.replacement.pluginVersion},reason:input.reason}}}var manifests=Object.freeze({}),profiles=Object.freeze([{id:"coding-core",version:"1",pluginIds:[]},{id:"desktop-qa",version:"1",pluginIds:["agent-forge.plugin.desktop-windows-observe","agent-forge.plugin.desktop-windows-input"]},{id:"desktop-observe",version:"1",pluginIds:["agent-forge.plugin.desktop-windows-observe"]},{id:"desktop-control",version:"1",pluginIds:["agent-forge.plugin.desktop-windows-observe","agent-forge.plugin.desktop-windows-input"]},{id:"lsp-diagnostics",version:"1",pluginIds:["agent-forge.plugin.lsp-diagnostics"]},{id:"process-exec",version:"1",pluginIds:["agent-forge.plugin.process-exec"]},{id:"test-runner",version:"1",pluginIds:["agent-forge.plugin.test-runner"]},{id:"workspace-files",version:"1",pluginIds:["agent-forge.plugin.workspace-files"]},{id:"workspace-files-write",version:"1",pluginIds:["agent-forge.plugin.workspace-files-write"]},{id:"formatter-linter",version:"1",pluginIds:["agent-forge.plugin.formatter-linter"]},{id:"git-repository",version:"1",pluginIds:["agent-forge.plugin.git-repository"]}]);function listBuiltinPluginProfilesV1(){return profiles}function listBuiltinPluginManifestsV1(){return Object.freeze(Object.values(manifests).sort((left,right)=>{let idOrder=`${left.id}@${left.pluginVersion}`.localeCompare(`${right.id}@${right.pluginVersion}`);return idOrder===0?comparePluginVersionsV1(left.pluginVersion,right.pluginVersion):idOrder}))}function defaultBuiltinVerifiedPluginsV1(profileId){let profile=profiles.find(candidate=>candidate.id===profileId);return profile===void 0?[]:profile.pluginIds.flatMap(pluginId=>{let manifest=manifests[pluginId];return manifest===void 0?[]:[{pluginId:manifest.id,version:manifest.pluginVersion}]})}function resolveBuiltinPluginProfileV1(input){let profile=profiles.find(candidate=>candidate.id===input.profileId);if(profile===void 0)return{status:"not_found",profileId:input.profileId};let requestedPluginIds=input.selectedPluginIds,requestedDisabledPluginIds=input.disabledPluginIds;if(requestedPluginIds!==void 0||requestedDisabledPluginIds!==void 0){let availablePluginIds=new Set(profile.pluginIds),duplicatePluginIds=[],unknownPluginIds=[];for(let requestedIds of[requestedPluginIds??[],requestedDisabledPluginIds??[]]){let seen=new Set;for(let pluginId of requestedIds)!availablePluginIds.has(pluginId)&&!unknownPluginIds.includes(pluginId)&&unknownPluginIds.push(pluginId),seen.has(pluginId)&&!duplicatePluginIds.includes(pluginId)&&duplicatePluginIds.push(pluginId),seen.add(pluginId)}if(unknownPluginIds.length>0||duplicatePluginIds.length>0)return{status:"invalid_selection",profileId:input.profileId,unknownPluginIds:Object.freeze([...new Set(unknownPluginIds)]),duplicatePluginIds:Object.freeze(duplicatePluginIds)}}let selected=requestedPluginIds===void 0?profile.pluginIds:profile.pluginIds.filter(pluginId=>requestedPluginIds.includes(pluginId)),selectedProfile=requestedPluginIds===void 0?profile:Object.freeze({...profile,pluginIds:Object.freeze([...selected])}),disabled=new Set(input.disabledPluginIds??[]),manifestByPluginId=new Map(selectedProfile.pluginIds.map(pluginId=>[pluginId,manifestFor(pluginId,input.manifestOverrides)])),missingPluginIds=selectedProfile.pluginIds.filter(pluginId=>manifestByPluginId.get(pluginId)===void 0),resolution=resolvePluginProfileV1({profileId:selectedProfile.id,profileVersion:selectedProfile.version,plugins:selectedProfile.pluginIds.flatMap(pluginId=>{let manifest=manifestByPluginId.get(pluginId);return manifest===void 0?[]:[{manifest,required:!disabled.has(pluginId),disabled:disabled.has(pluginId)}]}),host:input.host,hostVersion:VERSION}),merged=mergeMissingPluginResolutionsV1(resolution,missingPluginIds,disabled);if(merged.status!=="ready")return{status:"resolved",profile:selectedProfile,resolution:merged};let resolvedPlugins=merged.resolvedManifest.plugins.map(plugin=>({pluginId:plugin.pluginId,pluginVersion:plugin.pluginVersion,capabilityRefs:plugin.capabilityRefs,...plugin.selectedAdapter===void 0?{}:{selectedAdapter:plugin.selectedAdapter}})),verifiedPlugins=input.verifiedPlugins??[],assembly=assembleProfile({profileId:selectedProfile.id,profileVersion:selectedProfile.version,resolvedPlugins,verifiedPlugins});return{status:"resolved",profile:selectedProfile,resolution:merged,assembly}}function manifestFor(pluginId,overrides){let manifest=overrides?.[pluginId]??manifests[pluginId];if(manifest!==void 0&&manifest.id!==pluginId)throw new Error(`builtin manifest override does not match plugin ${pluginId}`);return manifest}function mergeMissingPluginResolutionsV1(resolution,missingPluginIds,disabled){if(missingPluginIds.length===0)return resolution;let missing=missingPluginIds.map(pluginId=>({pluginId,pluginVersion:"",required:!disabled.has(pluginId),status:"manifest-missing",diagnostics:[{code:"manifest_missing",message:`Plugin ${pluginId} has no builtin manifest and no installed active override; the plugin is omitted from this profile (install it with agent-forge plugin install)`}]})),plugins=[...resolution.plugins,...missing].sort((left,right)=>left.pluginId.localeCompare(right.pluginId));return Object.freeze({...resolution,plugins:Object.freeze(plugins),diagnostics:Object.freeze(plugins.flatMap(plugin=>plugin.diagnostics))})}var plugin_manager_controller_exports={};__export(plugin_manager_controller_exports,{createPluginManagerControllerV1:()=>createPluginManagerControllerV1});var MAX_MANAGER_ENTRIES_V1=128,MAX_MANAGER_DIAGNOSTICS_V1=8,MAX_MANAGER_ID_CHARS_V1=256;function boundedId(value,label){if(typeof value!="string"||value.trim()===""||value.length>MAX_MANAGER_ID_CHARS_V1||/[\u0000-\u001f\s]/u.test(value))throw new Error(`${label} is invalid`);return value}function signalAborted2(signal){return signal?.aborted===!0}function rejectionCodes(registry,pluginId,pluginVersion){return Object.freeze(registry.rejected.filter(entry=>entry.pluginId===pluginId&&entry.pluginVersion===pluginVersion).slice(0,MAX_MANAGER_DIAGNOSTICS_V1).map(entry=>entry.code))}function activeRecord(state2,pluginId){return state2.records.filter(record=>record.pluginId===pluginId&&record.state.lifecycle==="active").sort((left,right)=>comparePluginVersionsV1(right.pluginVersion,left.pluginVersion))[0]}function makeSnapshot(registry,stateStatus,state2){let identities=new Map;for(let entry of registry.entries)identities.set(`${entry.pluginId}@${entry.pluginVersion}`,entry);for(let rejection of registry.rejected){let identity=`${rejection.pluginId}@${rejection.pluginVersion}`;identities.has(identity)||identities.set(identity,{pluginId:rejection.pluginId,pluginVersion:rejection.pluginVersion,signed:!1})}let entries=[...identities.values()].map(entry=>{let installed=activeRecord(state2,entry.pluginId),diagnostics=rejectionCodes(registry,entry.pluginId,entry.pluginVersion),unavailable2=diagnostics.length>0||!registry.verified.some(candidate=>candidate.pluginId===entry.pluginId&&candidate.pluginVersion===entry.pluginVersion),isInstalled=installed?.pluginVersion===entry.pluginVersion;return Object.freeze({pluginId:entry.pluginId,pluginVersion:entry.pluginVersion,status:unavailable2?"unavailable":isInstalled?"installed":installed===void 0?"available":"update-available",signed:entry.signed,...installed===void 0?{}:{installedVersion:installed.pluginVersion,lifecycle:installed.state.lifecycle},diagnosticCodes:diagnostics})}).sort((left,right)=>{let idOrder=left.pluginId.localeCompare(right.pluginId);return idOrder===0?comparePluginVersionsV1(right.pluginVersion,left.pluginVersion):idOrder}),boundedEntries=Object.freeze(entries.slice(0,MAX_MANAGER_ENTRIES_V1));return Object.freeze({version:1,registrySource:registry.source,stateStatus,entries:boundedEntries,truncated:entries.length>boundedEntries.length})}function stateResult(result){if(result.status==="ok"||result.status==="missing")return{status:result.status,snapshot:result.snapshot}}function responseCode(response2){return response2.status==="unsupported"?"manager-operation-unsupported":response2.status==="cancelled"?"manager-operation-cancelled":"manager-operation-failed"}function createPluginManagerControllerV1(options){let getSnapshot=async(input={})=>{if(signalAborted2(input.signal))return{status:"error",code:"cancelled"};let registry;try{registry=await options.registry.list({signal:input.signal})}catch{return signalAborted2(input.signal)?{status:"error",code:"cancelled"}:{status:"error",code:"registry-unavailable"}}if(signalAborted2(input.signal))return{status:"error",code:"cancelled"};let state2;try{state2=await options.stateStore.read({signal:input.signal})}catch{return signalAborted2(input.signal)?{status:"error",code:"cancelled"}:{status:"error",code:"state-unavailable"}}if(signalAborted2(input.signal))return{status:"error",code:"cancelled"};let checkedState=stateResult(state2);return checkedState===void 0?{status:"error",code:state2.status==="cancelled"?"cancelled":"state-invalid"}:{status:"ok",snapshot:makeSnapshot(registry,checkedState.status,checkedState.snapshot)}},run=async input=>{try{boundedId(input.pluginId,"plugin ID"),input.pluginVersion!==void 0&&boundedId(input.pluginVersion,"plugin version")}catch{return{status:"failed",code:"manager-operation-failed"}}if(!input.confirmed)return{status:"needs_confirmation",code:"confirmation-required"};if(signalAborted2(input.signal))return{status:"cancelled",code:"cancelled"};let response2;try{let identity=input.pluginVersion===void 0?input.pluginId:`${input.pluginId}@${input.pluginVersion}`;response2=await options.cli.execute({argv:[input.command,identity,"--json"],signal:input.signal})}catch{return{status:"failed",code:"manager-operation-failed"}}if(response2.status!=="succeeded")return{status:response2.status==="unsupported"?"unsupported":response2.status==="cancelled"?"cancelled":"failed",code:responseCode(response2)};let refreshed=await getSnapshot({signal:input.signal});return refreshed.status==="ok"?{status:"succeeded",snapshot:refreshed.snapshot}:{status:"succeeded"}};return Object.freeze({getSnapshot,install:input=>run({...input,command:"install"}),update:input=>run({...input,command:"update"}),remove:input=>run({...input,command:"remove"})})}import{closeSync as closeSync2,fsyncSync,mkdirSync as mkdirSync3,openSync as openSync2,readFileSync as readFileSync4,statSync as statSync5,unlinkSync,writeFileSync as writeFileSync3,writeSync}from"node:fs";import{dirname as dirname8,join as join20}from"node:path";var lockSleepBuffer=new Int32Array(new SharedArrayBuffer(4));function sleepSync(ms){Atomics.wait(lockSleepBuffer,0,0,ms)}var DurableServiceErrorV1=class extends Error{code;constructor(code,message){super(message),this.name="DurableServiceErrorV1",this.code=code}};function durableLogPath(agentDir,sessionId){return join20(agentDir,"durable",`${sessionId}.jsonl`)}function assertNonEmptyString3(value,label){if(typeof value!="string"||value.trim().length===0)throw new Error(`${label} must be a non-empty string`)}var writeAllSync=(fd,data)=>{let buffer=Buffer.from(data,"utf8"),written=0;for(;written<buffer.length;)written+=writeSync(fd,buffer,written,buffer.length-written)},LOCK_FILE_SUFFIX=".lock",LEASE_FILE_SUFFIX=".lease",LOCK_POLL_INTERVAL_MS=25,DEFAULT_LOCK_TIMEOUT_MS=5e3,DEFAULT_STALE_LOCK_MS=6e4,DEFAULT_LEASE_TTL_MS=3e4;function acquirePersistLock(lockPath,lockTimeoutMs,staleLockMs){let deadline=Date.now()+lockTimeoutMs;for(;;){mkdirSync3(dirname8(lockPath),{recursive:!0});let token=`${process.pid}:${Date.now()}`;try{let fd=openSync2(lockPath,"wx");try{writeFileSync3(fd,token)}finally{closeSync2(fd)}return token}catch(error2){let code=error2.code;if(code==="EPERM"){let vanished=!1;try{statSync5(lockPath)}catch(statError){if(statError.code!=="ENOENT")throw error2;vanished=!0}if(vanished){if(Date.now()>=deadline)throw error2;sleepSync(LOCK_POLL_INTERVAL_MS);continue}}else if(code!=="EEXIST")throw error2;let stale=!1;try{stale=Date.now()-statSync5(lockPath).mtimeMs>staleLockMs}catch{}if(stale){try{unlinkSync(lockPath)}catch{}continue}if(Date.now()>=deadline)throw new Error(`durable store persist lock timeout after ${lockTimeoutMs} ms: ${lockPath} is held by another writer`);sleepSync(LOCK_POLL_INTERVAL_MS)}}}function releasePersistLock(lockPath,token){try{readFileSync4(lockPath,"utf8")===token&&unlinkSync(lockPath)}catch{}}function createFileDurableStoreBackend(options){if(assertNonEmptyString3(options.path,"Durable store path"),options.lockTimeoutMs!==void 0&&(!Number.isFinite(options.lockTimeoutMs)||options.lockTimeoutMs<=0))throw new Error("Durable store lockTimeoutMs must be a positive number");if(options.staleLockMs!==void 0&&(!Number.isFinite(options.staleLockMs)||options.staleLockMs<=0))throw new Error("Durable store staleLockMs must be a positive number");if(options.leaseTtlMs!==void 0&&(!Number.isFinite(options.leaseTtlMs)||options.leaseTtlMs<=0))throw new Error("Durable store leaseTtlMs must be a positive number");let path15=options.path,lockTimeoutMs=options.lockTimeoutMs??DEFAULT_LOCK_TIMEOUT_MS,staleLockMs=options.staleLockMs??DEFAULT_STALE_LOCK_MS,leaseTtlMs=options.leaseTtlMs??DEFAULT_LEASE_TTL_MS,lockPath=`${path15}${LOCK_FILE_SUFFIX}`,leasePath=`${path15}${LEASE_FILE_SUFFIX}`,readLease=()=>{try{let value=JSON.parse(readFileSync4(leasePath,"utf8"));if(typeof value!="object"||value===null||Array.isArray(value))return;let writerId=value.writerId,expiresAt=value.expiresAt;return typeof writerId!="string"||writerId.length===0||typeof expiresAt!="number"||!Number.isFinite(expiresAt)?void 0:{writerId,expiresAt}}catch{return}},writeLease=(writerId,expiresAt)=>{let fd=openSync2(leasePath,"w");try{writeAllSync(fd,JSON.stringify({writerId,expiresAt}))}finally{closeSync2(fd)}},liveForeign=(current,writerId)=>current.writerId!==writerId&&Date.now()<=current.expiresAt;return{persist(operations){if(operations.length===0)return;let lines=operations.map(operation=>`${JSON.stringify(storeOperationEnvelope(operation))}
508
+ `),signal?.aborted)?cancelledResult2():(await fileSystem.rename(temporaryPath,filePath),Object.freeze({status:"ok",snapshot:snapshot2,changed:!0}))}finally{try{await fileSystem.unlink(temporaryPath)}catch{}}}let mutationTail=Promise.resolve();function enqueueMutation(operation){let result=mutationTail.then(operation,operation);return mutationTail=result.then(()=>{},()=>{}),result}return{read:async({signal}={})=>await read(signal),set:input=>enqueueMutation(async()=>{let selection;try{selection=createPluginSelectionV1(input.selection)}catch(error2){return Object.freeze({status:"invalid",diagnostics:Object.freeze([invalidFromError2(error2)])})}let current=await read(input.signal);if(current.status!=="ok"&&current.status!=="missing")return current;if(input.signal?.aborted)return cancelledResult2();let existing=current.snapshot.selections.find(item=>item.profileId===selection.profileId);if(existing!==void 0&&JSON.stringify(existing)===JSON.stringify(selection))return Object.freeze({status:"ok",snapshot:current.snapshot,changed:!1});if(current.snapshot.selections.length>=MAX_PLUGIN_SELECTION_PROFILES_V1&&existing===void 0)return Object.freeze({status:"invalid",diagnostics:Object.freeze([diagnostic4("too_many_profiles","too many selection profiles")])});let snapshot2=Object.freeze({version:PLUGIN_SELECTION_STORE_VERSION_V1,selections:sortSelections([...current.snapshot.selections.filter(item=>item.profileId!==selection.profileId),selection])});return await write(snapshot2,input.signal)}),clear:input=>enqueueMutation(async()=>{let selection;try{selection=createPluginSelectionV1({profileId:input.profileId,selectedPluginIds:[],disabledPluginIds:[]})}catch(error2){return Object.freeze({status:"invalid",diagnostics:Object.freeze([invalidFromError2(error2)])})}let current=await read(input.signal);if(current.status!=="ok"&&current.status!=="missing")return current;if(input.signal?.aborted)return cancelledResult2();let selections=current.snapshot.selections.filter(item=>item.profileId!==selection.profileId);return selections.length===current.snapshot.selections.length?Object.freeze({status:"ok",snapshot:current.snapshot,changed:!1}):await write(Object.freeze({version:PLUGIN_SELECTION_STORE_VERSION_V1,selections:sortSelections(selections)}),input.signal)})}}function freezeAssembly(assembly){return Object.freeze({...assembly,plugins:Object.freeze(assembly.plugins.map(plugin=>Object.freeze({...plugin,capabilityRefs:Object.freeze(plugin.capabilityRefs.map(ref=>Object.freeze({...ref}))),...plugin.selectedAdapter===void 0?{}:{selectedAdapter:Object.freeze({...plugin.selectedAdapter})}})))})}function assembleIdentity(input){let identity=buildProfileIdentityV1({profileId:input.profileId,profileVersion:input.profileVersion,resolvedPlugins:input.plugins,capabilityVersions:[...new Set(input.plugins.flatMap(plugin=>plugin.capabilityRefs))].sort((a,b2)=>a.id.localeCompare(b2.id)||a.version-b2.version)});return freezeAssembly({profileId:input.profileId,profileVersion:input.profileVersion,identity,plugins:[...input.plugins]})}function assembleProfile(input){let verified=new Map(input.verifiedPlugins.map(entry=>[`${entry.pluginId}@${entry.version}`,!0])),unverified=input.resolvedPlugins.filter(plugin=>!verified.has(`${plugin.pluginId}@${plugin.pluginVersion}`)).map(plugin=>({pluginId:plugin.pluginId,pluginVersion:plugin.pluginVersion}));return unverified.length>0?{status:"unverified",unverified}:{status:"assembled",assembly:assembleIdentity({profileId:input.profileId,profileVersion:input.profileVersion,plugins:input.resolvedPlugins})}}function replaceProfilePlugin(assembly,input){let fromPlugin=assembly.plugins.find(plugin=>plugin.pluginId===input.fromPluginId);if(!fromPlugin)return{status:"absent",pluginId:input.fromPluginId};if(!new Map(input.verifiedPlugins.map(entry=>[`${entry.pluginId}@${entry.version}`,!0])).has(`${input.replacement.pluginId}@${input.replacement.pluginVersion}`))return{status:"unverified",unverified:[{pluginId:input.replacement.pluginId,pluginVersion:input.replacement.pluginVersion}]};let nextPlugins=assembly.plugins.filter(plugin=>plugin.pluginId!==input.fromPluginId).concat([input.replacement]);return{status:"replaced",assembly:assembleIdentity({profileId:assembly.profileId,profileVersion:assembly.profileVersion,plugins:nextPlugins}),replacement:{from:{pluginId:fromPlugin.pluginId,pluginVersion:fromPlugin.pluginVersion},to:{pluginId:input.replacement.pluginId,pluginVersion:input.replacement.pluginVersion},reason:input.reason}}}var manifests=Object.freeze({}),profiles=Object.freeze([{id:"coding-core",version:"1",pluginIds:[]},{id:"desktop-qa",version:"1",pluginIds:["agent-forge.plugin.desktop-windows-observe","agent-forge.plugin.desktop-windows-input"]},{id:"desktop-observe",version:"1",pluginIds:["agent-forge.plugin.desktop-windows-observe"]},{id:"desktop-control",version:"1",pluginIds:["agent-forge.plugin.desktop-windows-observe","agent-forge.plugin.desktop-windows-input"]},{id:"lsp-diagnostics",version:"1",pluginIds:["agent-forge.plugin.lsp-diagnostics"]},{id:"image-generation",version:"1",pluginIds:["agent-forge.plugin.image-generation"]},{id:"process-exec",version:"1",pluginIds:["agent-forge.plugin.process-exec"]},{id:"test-runner",version:"1",pluginIds:["agent-forge.plugin.test-runner"]},{id:"workspace-files",version:"1",pluginIds:["agent-forge.plugin.workspace-files"]},{id:"workspace-files-write",version:"1",pluginIds:["agent-forge.plugin.workspace-files-write"]},{id:"formatter-linter",version:"1",pluginIds:["agent-forge.plugin.formatter-linter"]},{id:"git-repository",version:"1",pluginIds:["agent-forge.plugin.git-repository"]}]);function listBuiltinPluginProfilesV1(){return profiles}function listBuiltinPluginManifestsV1(){return Object.freeze(Object.values(manifests).sort((left,right)=>{let idOrder=`${left.id}@${left.pluginVersion}`.localeCompare(`${right.id}@${right.pluginVersion}`);return idOrder===0?comparePluginVersionsV1(left.pluginVersion,right.pluginVersion):idOrder}))}function defaultBuiltinVerifiedPluginsV1(profileId){let profile=profiles.find(candidate=>candidate.id===profileId);return profile===void 0?[]:profile.pluginIds.flatMap(pluginId=>{let manifest=manifests[pluginId];return manifest===void 0?[]:[{pluginId:manifest.id,version:manifest.pluginVersion}]})}function resolveBuiltinPluginProfileV1(input){let profile=profiles.find(candidate=>candidate.id===input.profileId);if(profile===void 0)return{status:"not_found",profileId:input.profileId};let requestedPluginIds=input.selectedPluginIds,requestedDisabledPluginIds=input.disabledPluginIds;if(requestedPluginIds!==void 0||requestedDisabledPluginIds!==void 0){let availablePluginIds=new Set(profile.pluginIds),duplicatePluginIds=[],unknownPluginIds=[];for(let requestedIds of[requestedPluginIds??[],requestedDisabledPluginIds??[]]){let seen=new Set;for(let pluginId of requestedIds)!availablePluginIds.has(pluginId)&&!unknownPluginIds.includes(pluginId)&&unknownPluginIds.push(pluginId),seen.has(pluginId)&&!duplicatePluginIds.includes(pluginId)&&duplicatePluginIds.push(pluginId),seen.add(pluginId)}if(unknownPluginIds.length>0||duplicatePluginIds.length>0)return{status:"invalid_selection",profileId:input.profileId,unknownPluginIds:Object.freeze([...new Set(unknownPluginIds)]),duplicatePluginIds:Object.freeze(duplicatePluginIds)}}let selected=requestedPluginIds===void 0?profile.pluginIds:profile.pluginIds.filter(pluginId=>requestedPluginIds.includes(pluginId)),selectedProfile=requestedPluginIds===void 0?profile:Object.freeze({...profile,pluginIds:Object.freeze([...selected])}),disabled=new Set(input.disabledPluginIds??[]),manifestByPluginId=new Map(selectedProfile.pluginIds.map(pluginId=>[pluginId,manifestFor(pluginId,input.manifestOverrides)])),missingPluginIds=selectedProfile.pluginIds.filter(pluginId=>manifestByPluginId.get(pluginId)===void 0),resolution=resolvePluginProfileV1({profileId:selectedProfile.id,profileVersion:selectedProfile.version,plugins:selectedProfile.pluginIds.flatMap(pluginId=>{let manifest=manifestByPluginId.get(pluginId);return manifest===void 0?[]:[{manifest,required:!disabled.has(pluginId),disabled:disabled.has(pluginId)}]}),host:input.host,hostVersion:VERSION}),merged=mergeMissingPluginResolutionsV1(resolution,missingPluginIds,disabled);if(merged.status!=="ready")return{status:"resolved",profile:selectedProfile,resolution:merged};let resolvedPlugins=merged.resolvedManifest.plugins.map(plugin=>({pluginId:plugin.pluginId,pluginVersion:plugin.pluginVersion,capabilityRefs:plugin.capabilityRefs,...plugin.selectedAdapter===void 0?{}:{selectedAdapter:plugin.selectedAdapter}})),verifiedPlugins=input.verifiedPlugins??[],assembly=assembleProfile({profileId:selectedProfile.id,profileVersion:selectedProfile.version,resolvedPlugins,verifiedPlugins});return{status:"resolved",profile:selectedProfile,resolution:merged,assembly}}function manifestFor(pluginId,overrides){let manifest=overrides?.[pluginId]??manifests[pluginId];if(manifest!==void 0&&manifest.id!==pluginId)throw new Error(`builtin manifest override does not match plugin ${pluginId}`);return manifest}function mergeMissingPluginResolutionsV1(resolution,missingPluginIds,disabled){if(missingPluginIds.length===0)return resolution;let missing=missingPluginIds.map(pluginId=>({pluginId,pluginVersion:"",required:!disabled.has(pluginId),status:"manifest-missing",diagnostics:[{code:"manifest_missing",message:`Plugin ${pluginId} has no builtin manifest and no installed active override; the plugin is omitted from this profile (install it with agent-forge plugin install)`}]})),plugins=[...resolution.plugins,...missing].sort((left,right)=>left.pluginId.localeCompare(right.pluginId));return Object.freeze({...resolution,plugins:Object.freeze(plugins),diagnostics:Object.freeze(plugins.flatMap(plugin=>plugin.diagnostics))})}var plugin_manager_controller_exports={};__export(plugin_manager_controller_exports,{createPluginManagerControllerV1:()=>createPluginManagerControllerV1});var MAX_MANAGER_ENTRIES_V1=128,MAX_MANAGER_DIAGNOSTICS_V1=8,MAX_MANAGER_ID_CHARS_V1=256;function boundedId(value,label){if(typeof value!="string"||value.trim()===""||value.length>MAX_MANAGER_ID_CHARS_V1||/[\u0000-\u001f\s]/u.test(value))throw new Error(`${label} is invalid`);return value}function signalAborted2(signal){return signal?.aborted===!0}function rejectionCodes(registry,pluginId,pluginVersion){return Object.freeze(registry.rejected.filter(entry=>entry.pluginId===pluginId&&entry.pluginVersion===pluginVersion).slice(0,MAX_MANAGER_DIAGNOSTICS_V1).map(entry=>entry.code))}function activeRecord(state2,pluginId){return state2.records.filter(record=>record.pluginId===pluginId&&record.state.lifecycle==="active").sort((left,right)=>comparePluginVersionsV1(right.pluginVersion,left.pluginVersion))[0]}function makeSnapshot(registry,stateStatus,state2){let identities=new Map;for(let entry of registry.entries)identities.set(`${entry.pluginId}@${entry.pluginVersion}`,entry);for(let rejection of registry.rejected){let identity=`${rejection.pluginId}@${rejection.pluginVersion}`;identities.has(identity)||identities.set(identity,{pluginId:rejection.pluginId,pluginVersion:rejection.pluginVersion,signed:!1})}let entries=[...identities.values()].map(entry=>{let installed=activeRecord(state2,entry.pluginId),diagnostics=rejectionCodes(registry,entry.pluginId,entry.pluginVersion),unavailable2=diagnostics.length>0||!registry.verified.some(candidate=>candidate.pluginId===entry.pluginId&&candidate.pluginVersion===entry.pluginVersion),isInstalled=installed?.pluginVersion===entry.pluginVersion;return Object.freeze({pluginId:entry.pluginId,pluginVersion:entry.pluginVersion,status:unavailable2?"unavailable":isInstalled?"installed":installed===void 0?"available":"update-available",signed:entry.signed,...installed===void 0?{}:{installedVersion:installed.pluginVersion,lifecycle:installed.state.lifecycle},diagnosticCodes:diagnostics})}).sort((left,right)=>{let idOrder=left.pluginId.localeCompare(right.pluginId);return idOrder===0?comparePluginVersionsV1(right.pluginVersion,left.pluginVersion):idOrder}),boundedEntries=Object.freeze(entries.slice(0,MAX_MANAGER_ENTRIES_V1));return Object.freeze({version:1,registrySource:registry.source,stateStatus,entries:boundedEntries,truncated:entries.length>boundedEntries.length})}function stateResult(result){if(result.status==="ok"||result.status==="missing")return{status:result.status,snapshot:result.snapshot}}function responseCode(response2){return response2.status==="unsupported"?"manager-operation-unsupported":response2.status==="cancelled"?"manager-operation-cancelled":"manager-operation-failed"}function createPluginManagerControllerV1(options){let getSnapshot=async(input={})=>{if(signalAborted2(input.signal))return{status:"error",code:"cancelled"};let registry;try{registry=await options.registry.list({signal:input.signal})}catch{return signalAborted2(input.signal)?{status:"error",code:"cancelled"}:{status:"error",code:"registry-unavailable"}}if(signalAborted2(input.signal))return{status:"error",code:"cancelled"};let state2;try{state2=await options.stateStore.read({signal:input.signal})}catch{return signalAborted2(input.signal)?{status:"error",code:"cancelled"}:{status:"error",code:"state-unavailable"}}if(signalAborted2(input.signal))return{status:"error",code:"cancelled"};let checkedState=stateResult(state2);return checkedState===void 0?{status:"error",code:state2.status==="cancelled"?"cancelled":"state-invalid"}:{status:"ok",snapshot:makeSnapshot(registry,checkedState.status,checkedState.snapshot)}},run=async input=>{try{boundedId(input.pluginId,"plugin ID"),input.pluginVersion!==void 0&&boundedId(input.pluginVersion,"plugin version")}catch{return{status:"failed",code:"manager-operation-failed"}}if(!input.confirmed)return{status:"needs_confirmation",code:"confirmation-required"};if(signalAborted2(input.signal))return{status:"cancelled",code:"cancelled"};let response2;try{let identity=input.pluginVersion===void 0?input.pluginId:`${input.pluginId}@${input.pluginVersion}`;response2=await options.cli.execute({argv:[input.command,identity,"--json"],signal:input.signal})}catch{return{status:"failed",code:"manager-operation-failed"}}if(response2.status!=="succeeded")return{status:response2.status==="unsupported"?"unsupported":response2.status==="cancelled"?"cancelled":"failed",code:responseCode(response2)};let refreshed=await getSnapshot({signal:input.signal});return refreshed.status==="ok"?{status:"succeeded",snapshot:refreshed.snapshot}:{status:"succeeded"}};return Object.freeze({getSnapshot,install:input=>run({...input,command:"install"}),update:input=>run({...input,command:"update"}),remove:input=>run({...input,command:"remove"})})}import{closeSync as closeSync2,fsyncSync,mkdirSync as mkdirSync3,openSync as openSync2,readFileSync as readFileSync4,statSync as statSync5,unlinkSync,writeFileSync as writeFileSync3,writeSync}from"node:fs";import{dirname as dirname8,join as join20}from"node:path";var lockSleepBuffer=new Int32Array(new SharedArrayBuffer(4));function sleepSync(ms){Atomics.wait(lockSleepBuffer,0,0,ms)}var DurableServiceErrorV1=class extends Error{code;constructor(code,message){super(message),this.name="DurableServiceErrorV1",this.code=code}};function durableLogPath(agentDir,sessionId){return join20(agentDir,"durable",`${sessionId}.jsonl`)}function assertNonEmptyString3(value,label){if(typeof value!="string"||value.trim().length===0)throw new Error(`${label} must be a non-empty string`)}var writeAllSync=(fd,data)=>{let buffer=Buffer.from(data,"utf8"),written=0;for(;written<buffer.length;)written+=writeSync(fd,buffer,written,buffer.length-written)},LOCK_FILE_SUFFIX=".lock",LEASE_FILE_SUFFIX=".lease",LOCK_POLL_INTERVAL_MS=25,DEFAULT_LOCK_TIMEOUT_MS=5e3,DEFAULT_STALE_LOCK_MS=6e4,DEFAULT_LEASE_TTL_MS=3e4;function acquirePersistLock(lockPath,lockTimeoutMs,staleLockMs){let deadline=Date.now()+lockTimeoutMs;for(;;){mkdirSync3(dirname8(lockPath),{recursive:!0});let token=`${process.pid}:${Date.now()}`;try{let fd=openSync2(lockPath,"wx");try{writeFileSync3(fd,token)}finally{closeSync2(fd)}return token}catch(error2){let code=error2.code;if(code==="EPERM"){let vanished=!1;try{statSync5(lockPath)}catch(statError){if(statError.code!=="ENOENT")throw error2;vanished=!0}if(vanished){if(Date.now()>=deadline)throw error2;sleepSync(LOCK_POLL_INTERVAL_MS);continue}}else if(code!=="EEXIST")throw error2;let stale=!1;try{stale=Date.now()-statSync5(lockPath).mtimeMs>staleLockMs}catch{}if(stale){try{unlinkSync(lockPath)}catch{}continue}if(Date.now()>=deadline)throw new Error(`durable store persist lock timeout after ${lockTimeoutMs} ms: ${lockPath} is held by another writer`);sleepSync(LOCK_POLL_INTERVAL_MS)}}}function releasePersistLock(lockPath,token){try{readFileSync4(lockPath,"utf8")===token&&unlinkSync(lockPath)}catch{}}function createFileDurableStoreBackend(options){if(assertNonEmptyString3(options.path,"Durable store path"),options.lockTimeoutMs!==void 0&&(!Number.isFinite(options.lockTimeoutMs)||options.lockTimeoutMs<=0))throw new Error("Durable store lockTimeoutMs must be a positive number");if(options.staleLockMs!==void 0&&(!Number.isFinite(options.staleLockMs)||options.staleLockMs<=0))throw new Error("Durable store staleLockMs must be a positive number");if(options.leaseTtlMs!==void 0&&(!Number.isFinite(options.leaseTtlMs)||options.leaseTtlMs<=0))throw new Error("Durable store leaseTtlMs must be a positive number");let path15=options.path,lockTimeoutMs=options.lockTimeoutMs??DEFAULT_LOCK_TIMEOUT_MS,staleLockMs=options.staleLockMs??DEFAULT_STALE_LOCK_MS,leaseTtlMs=options.leaseTtlMs??DEFAULT_LEASE_TTL_MS,lockPath=`${path15}${LOCK_FILE_SUFFIX}`,leasePath=`${path15}${LEASE_FILE_SUFFIX}`,readLease=()=>{try{let value=JSON.parse(readFileSync4(leasePath,"utf8"));if(typeof value!="object"||value===null||Array.isArray(value))return;let writerId=value.writerId,expiresAt=value.expiresAt;return typeof writerId!="string"||writerId.length===0||typeof expiresAt!="number"||!Number.isFinite(expiresAt)?void 0:{writerId,expiresAt}}catch{return}},writeLease=(writerId,expiresAt)=>{let fd=openSync2(leasePath,"w");try{writeAllSync(fd,JSON.stringify({writerId,expiresAt}))}finally{closeSync2(fd)}},liveForeign=(current,writerId)=>current.writerId!==writerId&&Date.now()<=current.expiresAt;return{persist(operations){if(operations.length===0)return;let lines=operations.map(operation=>`${JSON.stringify(storeOperationEnvelope(operation))}
509
509
  `),token=acquirePersistLock(lockPath,lockTimeoutMs,staleLockMs);try{let fd=openSync2(path15,"a");try{writeAllSync(fd,lines.join("")),fsyncSync(fd)}finally{closeSync2(fd)}}finally{releasePersistLock(lockPath,token)}},load(){let raw;try{raw=readFileSync4(path15,"utf8")}catch(error2){return error2.code==="ENOENT"?{operations:[],corruptedLines:0,unreadable:!1}:{operations:[],corruptedLines:0,unreadable:!0}}let operations=[],corruptedLines=0;for(let line of raw.split(`
510
510
  `)){if(line.trim()==="")continue;let operation=parseStoreOperationLine(line);if(operation===void 0){corruptedLines+=1;continue}operations.push(operation)}return{operations,corruptedLines,unreadable:!1}},close(){},lease:{claim(writerId){let token=acquirePersistLock(lockPath,lockTimeoutMs,staleLockMs);try{let current=readLease();return current!==void 0&&liveForeign(current,writerId)?{status:"held",by:current.writerId}:(writeLease(writerId,Date.now()+leaseTtlMs),{status:"claimed"})}finally{releasePersistLock(lockPath,token)}},release(writerId){let token=acquirePersistLock(lockPath,lockTimeoutMs,staleLockMs);try{let current=readLease();if(current===void 0||current.writerId===writerId){try{unlinkSync(leasePath)}catch{}return{status:"released"}}throw new DurableServiceErrorV1("not_writer",`Writer ${writerId} does not hold the store lease (held by ${current.writerId})`)}finally{releasePersistLock(lockPath,token)}},recover(writerId){let token=acquirePersistLock(lockPath,lockTimeoutMs,staleLockMs);try{let current=readLease();if(current!==void 0&&liveForeign(current,writerId))return{status:"held"};let previousWriter=current!==void 0&&current.writerId!==writerId?current.writerId:void 0;return writeLease(writerId,Date.now()+leaseTtlMs),previousWriter===void 0?{status:"recovered"}:{status:"recovered",previousWriter}}finally{releasePersistLock(lockPath,token)}},renew(writerId){let token=acquirePersistLock(lockPath,lockTimeoutMs,staleLockMs);try{let current=readLease();if(current===void 0||current.writerId!==writerId||Date.now()>current.expiresAt)throw new DurableServiceErrorV1("not_writer",`Writer ${writerId} lost the store lease (expired or recovered by another writer)`);writeLease(writerId,Date.now()+leaseTtlMs)}finally{releasePersistLock(lockPath,token)}}}}}function storeOperationEnvelope(operation){return{kind:operation.kind,...operation.record}}function parseStoreOperationLine(line){try{let value=JSON.parse(line);if(typeof value!="object"||value===null||Array.isArray(value))return;let record=value;switch(record.kind){case"session":{let base=importRecordBase(record,"sessionId","Durable store session record");return{kind:"session",record:{sessionId:base.id,data:base.data,persistedAt:base.persistedAt}}}case"operation":{let base=importRecordBase(record,"operationId","Durable store operation record");return{kind:"operation",record:{operationId:base.id,sessionId:importOwningSessionId(record,"Durable store operation record"),data:base.data,persistedAt:base.persistedAt}}}case"artifact":{let base=importRecordBase(record,"artifactId","Durable store artifact record");return{kind:"artifact",record:{artifactId:base.id,sessionId:importOwningSessionId(record,"Durable store artifact record"),data:base.data,persistedAt:base.persistedAt}}}default:return}}catch{return}}function assertObject(value,label){if(typeof value!="object"||value===null||Array.isArray(value))throw new Error(`${label} must be an object`)}function importRecordBase(value,idField,label){let id=value[idField];if(typeof id!="string"||id.length===0)throw new Error(`${label} ${idField} must be a non-empty string`);let persistedAt=value.persistedAt;if(typeof persistedAt!="number"||!Number.isFinite(persistedAt))throw new Error(`${label} persistedAt must be a finite number`);return{id,data:value.data,persistedAt}}function importOwningSessionId(value,label){let sessionId=value.sessionId;if(typeof sessionId!="string"||sessionId.length===0)throw new Error(`${label} sessionId must be a non-empty string`);return sessionId}function createDurableService(options={}){let now=options.now??(()=>Date.now()),sessions=new Map,operations=new Map,artifacts=new Map,holder=null,crashPending=null,backend=options.backend,backendLease=backend?.lease,replay={corruptedLines:0,unreadable:!1};if(backend){let loaded=backend.load();for(let operation of loaded.operations)switch(operation.kind){case"session":sessions.set(operation.record.sessionId,operation.record);break;case"operation":operations.set(operation.record.operationId,operation.record);break;case"artifact":artifacts.set(operation.record.artifactId,operation.record);break}replay={corruptedLines:loaded.corruptedLines,unreadable:loaded.unreadable}}let logOperation=operation=>{backend&&backend.persist([operation])};function requireWriter(writerId){if(holder!==writerId)throw new DurableServiceErrorV1("not_writer",`Writer ${writerId} does not hold the writer lease`);backendLease?.renew(writerId)}return{persistSession(input){requireWriter(input.writerId);let record={sessionId:input.sessionId,data:input.data,persistedAt:now()};return logOperation({kind:"session",record}),sessions.set(input.sessionId,record),record},loadSession(input){return sessions.get(input.sessionId)},persistOperation(input){requireWriter(input.writerId);let record={operationId:input.operationId,sessionId:input.sessionId,data:input.data,persistedAt:now()};return logOperation({kind:"operation",record}),operations.set(input.operationId,record),record},loadOperation(input){return operations.get(input.operationId)},persistArtifact(input){requireWriter(input.writerId);let record={artifactId:input.artifactId,sessionId:input.sessionId,data:input.data,persistedAt:now()};return logOperation({kind:"artifact",record}),artifacts.set(input.artifactId,record),record},loadArtifact(input){return artifacts.get(input.artifactId)},listSessions(){return[...sessions.values()].sort((a,b2)=>a.sessionId<b2.sessionId?-1:a.sessionId>b2.sessionId?1:0)},claimWriter(writerId){if(crashPending!==null)return{status:"held",by:crashPending};if(backendLease===void 0)return holder!==null&&holder!==writerId?{status:"held",by:holder}:(holder=writerId,{status:"claimed"});let result=backendLease.claim(writerId);return result.status==="claimed"?(holder=writerId,{status:"claimed"}):{status:"held",by:result.by}},releaseWriter(writerId){if(crashPending!==null)throw new DurableServiceErrorV1("not_writer",`Writer ${writerId} cannot release a crashed lease; recover it instead`);if(backendLease===void 0){if(holder!==null&&holder!==writerId)throw new DurableServiceErrorV1("not_writer",`Writer ${writerId} does not hold the writer lease (held by ${holder})`);return holder=null,{status:"released"}}let result=backendLease.release(writerId);return holder=null,result},recoverWriter(writerId){if(crashPending!==null){let previousWriter=crashPending;return crashPending=null,holder=writerId,{status:"recovered",previousWriter}}if(backendLease===void 0)return holder!==null&&holder!==writerId?{status:"held"}:(holder=writerId,{status:"recovered"});let result=backendLease.recover(writerId);return result.status==="recovered"?(holder=writerId,result.previousWriter===void 0?{status:"recovered"}:{status:"recovered",previousWriter:result.previousWriter}):{status:"held"}},readiness(){return crashPending!==null?{ready:!1,reason:`writer crash is pending recovery: ${crashPending}`}:holder===null?{ready:!1,reason:"no writer has claimed the lease"}:{ready:!0}},exportState(){return{version:1,exportedAt:now(),sessions:[...sessions.values()],operations:[...operations.values()],artifacts:[...artifacts.values()],writer:{holder,crashPending}}},importState(snapshot2){if(assertObject(snapshot2,"Durable snapshot"),snapshot2.version!==1)throw new Error(`Unsupported durable snapshot version: ${String(snapshot2.version)}`);for(let field2 of["sessions","operations","artifacts"])if(!Array.isArray(snapshot2[field2]))throw new Error(`Durable snapshot ${field2} must be an array`);let writer=snapshot2.writer;assertObject(writer,"Durable snapshot writer");let snapshotHolder=writer.holder,snapshotCrashPending=writer.crashPending;if(snapshotHolder!==null&&typeof snapshotHolder!="string")throw new Error("Durable snapshot writer holder must be a string or null");if(snapshotCrashPending!==null&&typeof snapshotCrashPending!="string")throw new Error("Durable snapshot writer crashPending must be a string or null");let importedSessions=new Map;for(let raw of snapshot2.sessions){assertObject(raw,"Durable snapshot session");let record=importRecordBase(raw,"sessionId","Durable snapshot session");importedSessions.set(record.id,{sessionId:record.id,data:record.data,persistedAt:record.persistedAt})}let importedOperations=new Map;for(let raw of snapshot2.operations){assertObject(raw,"Durable snapshot operation");let record=importRecordBase(raw,"operationId","Durable snapshot operation");importedOperations.set(record.id,{operationId:record.id,sessionId:importOwningSessionId(raw,"Durable snapshot operation"),data:record.data,persistedAt:record.persistedAt})}let importedArtifacts=new Map;for(let raw of snapshot2.artifacts){assertObject(raw,"Durable snapshot artifact");let record=importRecordBase(raw,"artifactId","Durable snapshot artifact");importedArtifacts.set(record.id,{artifactId:record.id,sessionId:importOwningSessionId(raw,"Durable snapshot artifact"),data:record.data,persistedAt:record.persistedAt})}sessions.clear();for(let[id,record]of importedSessions)sessions.set(id,record);operations.clear();for(let[id,record]of importedOperations)operations.set(id,record);artifacts.clear();for(let[id,record]of importedArtifacts)artifacts.set(id,record);holder=null,crashPending=snapshotHolder??snapshotCrashPending},replayDiagnostics(){return replay}}}import{Buffer as Buffer5}from"node:buffer";import{randomUUID as randomUUID12}from"node:crypto";var INTERNAL_SERVER_ERROR_MESSAGE="Internal server error",NOT_IMPLEMENTED_MESSAGE="Operation is not implemented",PiServerError=class extends Error{code;details;constructor(code,message,details){super(message),this.name="PiServerError",this.code=code,this.details=details}};var UnauthorizedError=class extends PiServerError{constructor(message="Authentication or authorization failed",details){super("unauthorized",message,details),this.name="UnauthorizedError"}},InternalServerError=class extends Error{constructor(cause){super(INTERNAL_SERVER_ERROR_MESSAGE,{cause}),this.name="InternalServerError"}};import{appendFile,mkdir as mkdir6,readFile as readFile7}from"node:fs/promises";import{dirname as dirname9}from"node:path";function assertCursor(value,label){if(!Number.isSafeInteger(value)||value<0)throw new TypeError(`${label} must be a non-negative integer`)}function assertLimit(value){if(!Number.isSafeInteger(value)||value<1||value>1e3)throw new TypeError("Replay limit must be between 1 and 1000")}var FileDurableSessionEventJournal=class{path;maxEntries;records=new Map;nextCursors=new Map;writeQueue=Promise.resolve();ready;constructor(path15,options={}){if(this.path=path15,this.maxEntries=options.maxEntries??1e4,!Number.isSafeInteger(this.maxEntries)||this.maxEntries<1)throw new TypeError("Journal maxEntries must be a positive safe integer");this.ready=this.load()}async append(sessionId,event){if(sessionId.trim()==="")throw new TypeError("Journal sessionId must be non-empty");let append=this.writeQueue.then(async()=>{await this.ready;let cursor=this.nextCursors.get(sessionId)??1,record={sessionId,cursor,event:structuredClone(event)};await mkdir6(dirname9(this.path),{recursive:!0}),await appendFile(this.path,`${JSON.stringify(record)}
511
511
  `,"utf8");let entries=this.records.get(sessionId)??[];for(entries.push(record);entries.length>this.maxEntries;)entries.shift();return this.records.set(sessionId,entries),this.nextCursors.set(sessionId,cursor+1),cursor});return this.writeQueue=append.then(()=>{},()=>{}),append}async replay(sessionId,afterCursor,limit){assertCursor(afterCursor,"Replay afterCursor"),assertLimit(limit),await this.ready,await this.writeQueue;let entries=this.records.get(sessionId)??[],firstCursor=entries[0]?.cursor,gap=firstCursor===void 0?afterCursor>0:afterCursor<firstCursor-1,selected=entries.filter(entry=>entry.cursor>afterCursor).slice(0,limit),nextCursor=selected.at(-1)?.cursor??afterCursor,latestCursor=(this.nextCursors.get(sessionId)??1)-1;return{events:selected.map(({cursor,event})=>({cursor,event:structuredClone(event)})),nextCursor,complete:!gap&&nextCursor>=latestCursor,gap}}async close(){await this.ready,await this.writeQueue}async load(){let contents;try{contents=await readFile7(this.path,"utf8")}catch(error2){if(error2.code==="ENOENT")return;throw error2}let lines=contents.split(/\r?\n/);for(;lines.length>0&&lines.at(-1).trim()==="";)lines.pop();for(let[index3,line]of lines.entries()){if(line.trim()==="")continue;let isTail=index3===lines.length-1,record;try{record=JSON.parse(line)}catch{if(isTail)break;throw new Error("Invalid durable session journal record")}if(!record||typeof record.sessionId!="string"||!Number.isSafeInteger(record.cursor)){if(isTail)break;throw new Error("Invalid durable session journal record")}let entries=this.records.get(record.sessionId)??[];for(entries.push(record);entries.length>this.maxEntries;)entries.shift();this.records.set(record.sessionId,entries),this.nextCursors.set(record.sessionId,Math.max(this.nextCursors.get(record.sessionId)??1,record.cursor+1))}}};function nonNegativeNumber(value){return Number.isFinite(value)?Math.max(0,value):0}function identifier(value,label){if(typeof value!="string"||value.length===0)throw new TypeError(`${label} must be a non-empty string`);return value}function toProtocolModelMetadata(model,authenticated){return{provider:identifier(model.provider,"Model provider"),id:identifier(model.id,"Model id"),name:identifier(model.name,"Model name"),api:identifier(model.api,"Model API"),reasoning:model.reasoning,input:[...model.input],contextWindow:Math.max(1,Math.floor(model.contextWindow)),maxTokens:Math.max(1,Math.floor(model.maxTokens)),cost:{input:nonNegativeNumber(model.cost.input),output:nonNegativeNumber(model.cost.output),cacheRead:nonNegativeNumber(model.cost.cacheRead),cacheWrite:nonNegativeNumber(model.cost.cacheWrite)},supportedThinkingLevels:getSupportedThinkingLevels(model),authenticated}}import{randomUUID as randomUUID9}from"node:crypto";var DEFAULT_READ_TOKEN_TTL_MS=6e4,ReadTokenStore=class{ttlMs;now;tokens=new Map;constructor(options){let ttlMs=options?.ttlMs??DEFAULT_READ_TOKEN_TTL_MS;if(!Number.isSafeInteger(ttlMs)||ttlMs<=0)throw new TypeError("Read token TTL must be a positive safe integer");this.ttlMs=ttlMs,this.now=options?.now??(()=>Date.now())}issue(sessionId,artifactId){this.sweepExpired();let token=randomUUID9(),expiresAt=this.now()+this.ttlMs;return this.tokens.set(token,{sessionId,artifactId,expiresAt}),{token,expiresAt}}consume(token,expected){let entry=this.tokens.get(token);return entry?(this.tokens.delete(token),entry.expiresAt<=this.now()?{ok:!1,reason:"expired"}:entry.sessionId!==expected.sessionId||entry.artifactId!==expected.artifactId?{ok:!1,reason:"binding_mismatch"}:{ok:!0,sessionId:entry.sessionId,artifactId:entry.artifactId}):{ok:!1,reason:"unknown"}}revokeSession(sessionId){let revoked=0;for(let[token,entry]of this.tokens)entry.sessionId===sessionId&&(this.tokens.delete(token),revoked+=1);return revoked}sweepExpired(){let now=this.now();for(let[token,entry]of this.tokens)entry.expiresAt<=now&&this.tokens.delete(token)}};import{randomUUID as randomUUID11}from"node:crypto";var PROTOCOL_VERSION=1,IdSchema=build_default.String({minLength:1}),TimestampSchema=build_default.Integer({minimum:0}),Base64Schema=build_default.String({pattern:"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"}),StrictObject=properties=>build_default.Object(properties,{additionalProperties:!1}),JsonValueRecursiveSchema=build_default.Cyclic({JsonValue:build_default.Union([build_default.Null(),build_default.Boolean(),build_default.Number(),build_default.String(),build_default.Array(build_default.Ref("JsonValue")),build_default.Record(build_default.String(),build_default.Ref("JsonValue"))])},"JsonValue"),JsonValueSchema=build_default.Unsafe(JsonValueRecursiveSchema),ThinkingLevelSchema=build_default.Union([build_default.Literal("off"),build_default.Literal("minimal"),build_default.Literal("low"),build_default.Literal("medium"),build_default.Literal("high"),build_default.Literal("xhigh"),build_default.Literal("max")]),SessionPhaseSchema=build_default.Union([build_default.Literal("idle"),build_default.Literal("turn"),build_default.Literal("compaction"),build_default.Literal("branch_summary"),build_default.Literal("retry")]),ModelRefSchema=StrictObject({provider:IdSchema,id:IdSchema}),ModelCostSchema2=StrictObject({input:build_default.Number({minimum:0}),output:build_default.Number({minimum:0}),cacheRead:build_default.Number({minimum:0}),cacheWrite:build_default.Number({minimum:0})}),ModelMetadataSchema=StrictObject({provider:IdSchema,id:IdSchema,name:build_default.String({minLength:1}),api:IdSchema,reasoning:build_default.Boolean(),input:build_default.Array(build_default.Union([build_default.Literal("text"),build_default.Literal("image")])),contextWindow:build_default.Integer({minimum:1}),maxTokens:build_default.Integer({minimum:1}),cost:ModelCostSchema2,supportedThinkingLevels:build_default.Array(ThinkingLevelSchema,{minItems:1}),authenticated:build_default.Boolean()}),TextContentSchema=StrictObject({type:build_default.Literal("text"),text:build_default.String()}),ThinkingContentSchema=StrictObject({type:build_default.Literal("thinking"),thinking:build_default.String(),redacted:build_default.Optional(build_default.Boolean())}),ImageContentSchema=StrictObject({type:build_default.Literal("image"),data:build_default.String(),mimeType:build_default.String({minLength:1})}),ToolCallContentSchema=StrictObject({type:build_default.Literal("toolCall"),toolCallId:IdSchema,toolName:IdSchema,input:JsonValueSchema}),UserContentSchema=build_default.Union([TextContentSchema,ImageContentSchema]),AssistantContentSchema=build_default.Union([TextContentSchema,ThinkingContentSchema,ToolCallContentSchema]),ToolContentSchema=build_default.Union([TextContentSchema,ImageContentSchema]),UsageSchema=StrictObject({input:build_default.Integer({minimum:0}),output:build_default.Integer({minimum:0}),cacheRead:build_default.Integer({minimum:0}),cacheWrite:build_default.Integer({minimum:0}),reasoning:build_default.Optional(build_default.Integer({minimum:0})),totalTokens:build_default.Integer({minimum:0}),cost:StrictObject({input:build_default.Number({minimum:0}),output:build_default.Number({minimum:0}),cacheRead:build_default.Number({minimum:0}),cacheWrite:build_default.Number({minimum:0}),total:build_default.Number({minimum:0})})}),UserTranscriptItemSchema=StrictObject({id:IdSchema,role:build_default.Literal("user"),content:build_default.Array(UserContentSchema),timestamp:TimestampSchema}),AssistantTranscriptItemProperties={id:IdSchema,role:build_default.Literal("assistant"),content:build_default.Array(AssistantContentSchema),model:ModelRefSchema,responseModel:build_default.Optional(build_default.String({minLength:1})),usage:build_default.Optional(UsageSchema),timestamp:TimestampSchema},StreamingAssistantTranscriptItemSchema=StrictObject({...AssistantTranscriptItemProperties,status:build_default.Literal("streaming")}),CompleteAssistantTranscriptItemSchema=StrictObject({...AssistantTranscriptItemProperties,status:build_default.Literal("complete"),stopReason:build_default.Union([build_default.Literal("stop"),build_default.Literal("length"),build_default.Literal("toolUse")])}),ErrorAssistantTranscriptItemSchema=StrictObject({...AssistantTranscriptItemProperties,status:build_default.Literal("error"),stopReason:build_default.Literal("error"),errorMessage:build_default.Optional(build_default.String({minLength:1}))}),AbortedAssistantTranscriptItemSchema=StrictObject({...AssistantTranscriptItemProperties,status:build_default.Literal("aborted"),stopReason:build_default.Literal("aborted"),errorMessage:build_default.Optional(build_default.String())}),AssistantTranscriptItemSchema=build_default.Union([StreamingAssistantTranscriptItemSchema,CompleteAssistantTranscriptItemSchema,ErrorAssistantTranscriptItemSchema,AbortedAssistantTranscriptItemSchema]),ToolTranscriptItemProperties={id:IdSchema,role:build_default.Literal("tool"),toolCallId:IdSchema,toolName:IdSchema,input:JsonValueSchema,content:build_default.Array(ToolContentSchema),details:build_default.Optional(JsonValueSchema),usage:build_default.Optional(UsageSchema),timestamp:TimestampSchema},RunningToolTranscriptItemSchema=StrictObject({...ToolTranscriptItemProperties,status:build_default.Literal("running"),isError:build_default.Literal(!1)}),CompleteToolTranscriptItemSchema=StrictObject({...ToolTranscriptItemProperties,status:build_default.Literal("complete"),isError:build_default.Literal(!1)}),ErrorToolTranscriptItemSchema=StrictObject({...ToolTranscriptItemProperties,status:build_default.Literal("error"),isError:build_default.Literal(!0)}),ToolTranscriptItemSchema=build_default.Union([RunningToolTranscriptItemSchema,CompleteToolTranscriptItemSchema,ErrorToolTranscriptItemSchema]),NoteTranscriptItemSchema=StrictObject({id:IdSchema,role:build_default.Literal("note"),kind:build_default.Union([build_default.Literal("branchSummary"),build_default.Literal("compactionSummary"),build_default.Literal("custom")]),text:build_default.String(),fromId:build_default.Optional(build_default.String()),tokensBefore:build_default.Optional(build_default.Integer({minimum:0})),customType:build_default.Optional(build_default.String()),display:build_default.Optional(build_default.Boolean()),timestamp:TimestampSchema}),TranscriptItemSchema=build_default.Union([UserTranscriptItemSchema,AssistantTranscriptItemSchema,ToolTranscriptItemSchema,NoteTranscriptItemSchema]),TranscriptProgressSchema=build_default.Union([StrictObject({type:build_default.Literal("item_started"),item:TranscriptItemSchema}),StrictObject({type:build_default.Literal("assistant_delta"),messageId:IdSchema,contentIndex:build_default.Integer({minimum:0}),kind:build_default.Union([build_default.Literal("text"),build_default.Literal("thinking"),build_default.Literal("toolCall")]),delta:build_default.String()}),StrictObject({type:build_default.Literal("item_updated"),item:build_default.Union([AssistantTranscriptItemSchema,ToolTranscriptItemSchema])}),StrictObject({type:build_default.Literal("item_finished"),item:build_default.Union([CompleteAssistantTranscriptItemSchema,ErrorAssistantTranscriptItemSchema,AbortedAssistantTranscriptItemSchema,CompleteToolTranscriptItemSchema,ErrorToolTranscriptItemSchema])})]),SessionMetadataSchema=StrictObject({id:IdSchema,createdAt:TimestampSchema,updatedAt:build_default.Optional(TimestampSchema),parentSessionId:build_default.Optional(IdSchema),sessionName:build_default.Optional(build_default.String()),cwd:build_default.Optional(build_default.String({minLength:1}))}),SessionSnapshotSchema=StrictObject({id:IdSchema,name:build_default.Optional(build_default.String()),cwd:build_default.String({minLength:1}),createdAt:TimestampSchema,updatedAt:TimestampSchema,phase:SessionPhaseSchema,model:ModelRefSchema,thinkingLevel:ThinkingLevelSchema,profileId:build_default.Optional(IdSchema),profileVersion:build_default.Optional(IdSchema),attached:build_default.Boolean(),locked:build_default.Boolean(),revision:build_default.Integer({minimum:0}),transcript:build_default.Array(TranscriptItemSchema),queuedSteer:build_default.Array(UserTranscriptItemSchema),queuedSteerCount:build_default.Integer({minimum:0})}),ServerSnapshotSchema=StrictObject({serverId:IdSchema,protocolVersion:build_default.Literal(PROTOCOL_VERSION),revision:build_default.Integer({minimum:0}),sessions:build_default.Array(SessionMetadataSchema),models:build_default.Array(ModelMetadataSchema)}),ProtocolErrorCodeSchema=build_default.Union([build_default.Literal("version"),build_default.Literal("busy"),build_default.Literal("session_locked"),build_default.Literal("not_found"),build_default.Literal("invalid_request"),build_default.Literal("unauthorized"),build_default.Literal("not_implemented"),build_default.Literal("internal_error"),build_default.Literal("operation_conflict"),build_default.Literal("operation_not_found"),build_default.Literal("durable_unavailable"),build_default.Literal("operation_cancelled")]),ProtocolErrorSchema=StrictObject({code:ProtocolErrorCodeSchema,message:build_default.String(),details:build_default.Optional(JsonValueSchema)}),PromptPayloadProperties={sessionId:IdSchema,text:build_default.String()},OperationIdProperty={operationId:build_default.Optional(IdSchema)},ListCommandSchema=StrictObject({command:build_default.Literal("list")}),CreateCommandSchema=StrictObject({command:build_default.Literal("create"),cwd:build_default.Optional(build_default.String({minLength:1})),name:build_default.Optional(build_default.String()),model:build_default.Optional(ModelRefSchema),thinkingLevel:build_default.Optional(ThinkingLevelSchema),profileId:build_default.Optional(IdSchema),profileVersion:build_default.Optional(IdSchema)}),SessionLeaseModeSchema=build_default.Union([build_default.Literal("shared"),build_default.Literal("exclusive")]),AttachCommandSchema=StrictObject({command:build_default.Literal("attach"),sessionId:IdSchema,mode:build_default.Optional(SessionLeaseModeSchema)}),DetachCommandSchema=StrictObject({command:build_default.Literal("detach"),sessionId:IdSchema}),PromptCommandSchema=StrictObject({command:build_default.Literal("prompt"),...PromptPayloadProperties,...OperationIdProperty}),SteerCommandSchema=StrictObject({command:build_default.Literal("steer"),...PromptPayloadProperties,...OperationIdProperty}),AbortCommandSchema=StrictObject({command:build_default.Literal("abort"),sessionId:IdSchema,...OperationIdProperty}),SetModelCommandSchema=StrictObject({command:build_default.Literal("set_model"),sessionId:IdSchema,model:ModelRefSchema,...OperationIdProperty}),SetThinkingCommandSchema=StrictObject({command:build_default.Literal("set_thinking"),sessionId:IdSchema,thinkingLevel:ThinkingLevelSchema,...OperationIdProperty}),ReplayCommandSchema=StrictObject({command:build_default.Literal("replay"),sessionId:IdSchema,afterCursor:build_default.Integer({minimum:0}),limit:build_default.Integer({minimum:1,maximum:1e3})}),ArtifactStatCommandSchema=StrictObject({command:build_default.Literal("artifact_stat"),sessionId:IdSchema,artifactId:IdSchema}),ArtifactReadCommandSchema=StrictObject({command:build_default.Literal("artifact_read"),sessionId:IdSchema,artifactId:IdSchema,offset:build_default.Integer({minimum:0}),maxBytes:build_default.Integer({minimum:1,maximum:1048576})}),ArtifactTokenIssueCommandSchema=StrictObject({command:build_default.Literal("artifact_token_issue"),sessionId:IdSchema,artifactId:IdSchema}),LeaseRenewCommandSchema=StrictObject({command:build_default.Literal("lease_renew"),sessionId:IdSchema}),LeaseRenewResultSchema=StrictObject({command:build_default.Literal("lease_renew"),sessionId:IdSchema,leaseId:IdSchema,expiresAt:TimestampSchema}),OperationSubmitCommandSchema=StrictObject({command:build_default.Literal("operation_submit"),sessionId:IdSchema,operationType:build_default.String(),input:build_default.Optional(JsonValueSchema),idempotencyKey:build_default.Optional(build_default.String()),expectedRevision:build_default.Optional(build_default.Integer({minimum:0}))}),OperationCancelCommandSchema=StrictObject({command:build_default.Literal("operation_cancel"),sessionId:IdSchema,operationId:build_default.String()}),OperationResultCommandSchema=StrictObject({command:build_default.Literal("operation_result"),sessionId:IdSchema,operationId:build_default.String()}),CommandSchema=build_default.Union([ListCommandSchema,CreateCommandSchema,AttachCommandSchema,DetachCommandSchema,PromptCommandSchema,SteerCommandSchema,AbortCommandSchema,SetModelCommandSchema,SetThinkingCommandSchema,ReplayCommandSchema,ArtifactStatCommandSchema,ArtifactReadCommandSchema,ArtifactTokenIssueCommandSchema,LeaseRenewCommandSchema,OperationSubmitCommandSchema,OperationCancelCommandSchema,OperationResultCommandSchema]),CreateResultSchema=StrictObject({command:build_default.Literal("create"),session:SessionSnapshotSchema,leaseId:build_default.Optional(IdSchema),leaseExpiresAt:build_default.Optional(TimestampSchema)}),AttachResultSchema=StrictObject({command:build_default.Literal("attach"),session:SessionSnapshotSchema,leaseId:build_default.Optional(IdSchema),leaseExpiresAt:build_default.Optional(TimestampSchema)}),PromptResultSchema=StrictObject({command:build_default.Literal("prompt"),session:SessionSnapshotSchema}),SteerResultSchema=StrictObject({command:build_default.Literal("steer"),session:SessionSnapshotSchema}),AbortResultSchema=StrictObject({command:build_default.Literal("abort"),session:SessionSnapshotSchema}),SetModelResultSchema=StrictObject({command:build_default.Literal("set_model"),session:SessionSnapshotSchema}),SetThinkingResultSchema=StrictObject({command:build_default.Literal("set_thinking"),session:SessionSnapshotSchema}),ArtifactRefSchema=StrictObject({sessionId:IdSchema,operationId:IdSchema,artifactId:IdSchema,kind:IdSchema,mediaType:IdSchema,sizeBytes:build_default.Optional(build_default.Integer({minimum:0})),truncated:build_default.Boolean(),createdAt:TimestampSchema}),ArtifactStatResultSchema=StrictObject({command:build_default.Literal("artifact_stat"),artifact:ArtifactRefSchema}),ArtifactReadResultSchema=StrictObject({command:build_default.Literal("artifact_read"),artifact:ArtifactRefSchema,encoding:build_default.Literal("base64"),data:Base64Schema,nextOffset:build_default.Optional(build_default.Integer({minimum:0})),eof:build_default.Boolean()}),ArtifactTokenIssueResultSchema=StrictObject({command:build_default.Literal("artifact_token_issue"),token:IdSchema,expiresAt:TimestampSchema,sessionId:IdSchema,artifactId:IdSchema}),ReplayEventSchema=StrictObject({cursor:build_default.Integer({minimum:1}),event:build_default.Union([StrictObject({type:build_default.Literal("server_snapshot"),snapshot:ServerSnapshotSchema}),StrictObject({type:build_default.Literal("session_snapshot"),snapshot:SessionSnapshotSchema}),StrictObject({type:build_default.Literal("session_progress"),sessionId:IdSchema,progress:TranscriptProgressSchema}),StrictObject({type:build_default.Literal("session_removed"),sessionId:IdSchema})])}),ReplayResultSchema=StrictObject({command:build_default.Literal("replay"),sessionId:IdSchema,afterCursor:build_default.Integer({minimum:0}),nextCursor:build_default.Integer({minimum:0}),complete:build_default.Boolean(),gap:build_default.Boolean(),events:build_default.Array(ReplayEventSchema)}),ListResultSchema=StrictObject({command:build_default.Literal("list"),sessions:build_default.Array(SessionMetadataSchema)}),DetachResultSchema=StrictObject({command:build_default.Literal("detach"),sessionId:IdSchema}),OperationAckResultSchema=StrictObject({command:build_default.Literal("operation_ack"),operationId:IdSchema,status:build_default.Union([build_default.Literal("accepted"),build_default.Literal("completed"),build_default.Literal("rejected")]),result:build_default.Optional(JsonValueSchema),error:build_default.Optional(ProtocolErrorSchema)}),CommandResultSchema=build_default.Union([ListResultSchema,CreateResultSchema,AttachResultSchema,DetachResultSchema,PromptResultSchema,SteerResultSchema,AbortResultSchema,SetModelResultSchema,SetThinkingResultSchema,ReplayResultSchema,LeaseRenewResultSchema,ArtifactStatResultSchema,ArtifactReadResultSchema,ArtifactTokenIssueResultSchema,OperationAckResultSchema]),ClientHelloSchema=StrictObject({type:build_default.Literal("hello"),version:build_default.Integer({minimum:0}),auth:build_default.Optional(JsonValueSchema)}),RequestEnvelopeSchema=StrictObject({type:build_default.Literal("request"),id:IdSchema,request:CommandSchema}),ClientMessageSchema=build_default.Union([ClientHelloSchema,RequestEnvelopeSchema]),ServerEventSchema=build_default.Union([StrictObject({type:build_default.Literal("server_snapshot"),snapshot:ServerSnapshotSchema}),StrictObject({type:build_default.Literal("session_snapshot"),snapshot:SessionSnapshotSchema}),StrictObject({type:build_default.Literal("session_progress"),sessionId:IdSchema,progress:TranscriptProgressSchema}),StrictObject({type:build_default.Literal("session_removed"),sessionId:IdSchema})]),ServerHelloSchema=StrictObject({type:build_default.Literal("hello"),version:build_default.Literal(PROTOCOL_VERSION),connectionId:IdSchema,snapshot:ServerSnapshotSchema}),ServerHelloErrorSchema=StrictObject({type:build_default.Literal("hello_error"),error:ProtocolErrorSchema}),ResponseEnvelopeSchema=build_default.Union([StrictObject({type:build_default.Literal("response"),id:IdSchema,ok:build_default.Literal(!0),result:CommandResultSchema}),StrictObject({type:build_default.Literal("response"),id:IdSchema,ok:build_default.Literal(!1),error:ProtocolErrorSchema})]),EventEnvelopeSchema=StrictObject({type:build_default.Literal("event"),event:ServerEventSchema}),ServerMessageSchema=build_default.Union([ServerHelloSchema,ServerHelloErrorSchema,ResponseEnvelopeSchema,EventEnvelopeSchema]);var ProtocolValidationError=class extends Error{constructor(message,_value){super(message),this.name="ProtocolValidationError"}};function isProtocolValue(value,optionalProperty=!1,ancestors=new Set){if(value===void 0)return optionalProperty;if(value===null||typeof value=="boolean"||typeof value=="number"||typeof value=="string")return!0;if(typeof value!="object"||ancestors.has(value))return!1;ancestors.add(value);try{return Array.isArray(value)?value.every(item=>isProtocolValue(item,!1,ancestors)):Object.getPrototypeOf(value)!==Object.prototype?!1:Object.values(value).every(item=>isProtocolValue(item,!0,ancestors))}finally{ancestors.delete(value)}}function parseClientMessage(value){if(!isProtocolValue(value)||!Check2(ClientMessageSchema,value))throw new ProtocolValidationError("Invalid client protocol message");return value}function parseServerMessage(value){if(!isProtocolValue(value)||!Check2(ServerMessageSchema,value))throw new ProtocolValidationError("Invalid server protocol message");return value}function boundedErrorMessage(error2){return error2 instanceof Error?error2.message.length<=500?error2.message:`${error2.message.slice(0,497)}...`:"Unknown codec error"}function encodeProtocolMessage(value,parse5,kind,options){let validated=parse5(value);try{let maxFrameLength=options?.maxFrameLength??16777216;return encodeFrame(encodeCbor(validated,{maxByteLength:maxFrameLength}))}catch(error2){throw error2 instanceof ProtocolValidationError?error2:new ProtocolValidationError(`Unable to encode ${kind} protocol message: ${boundedErrorMessage(error2)}`)}}function encodeServerMessage(message,options){return encodeProtocolMessage(message,parseServerMessage,"server",options)}var ValidatedMessageDecoder=class{failed=!1;frames;kind;maxFrameLength;parse;constructor(kind,parse5,options){this.frames=new FrameDecoder(options),this.kind=kind,this.maxFrameLength=options?.maxFrameLength??16777216,this.parse=parse5}push(chunk){if(this.failed)throw new ProtocolValidationError(`${this.kind} message decoder has failed`);try{let messages=[];for(let frame of this.frames.push(chunk))messages.push(this.parse(decodeCbor(frame,{maxByteLength:this.maxFrameLength})));return messages}catch(error2){throw this.failed=!0,error2 instanceof ProtocolValidationError?error2:new ProtocolValidationError(`Invalid ${this.kind} protocol frame: ${boundedErrorMessage(error2)}`)}}end(){if(this.failed)throw new ProtocolValidationError(`${this.kind} message decoder has failed`);try{this.frames.end()}catch(error2){throw this.failed=!0,new ProtocolValidationError(`Invalid ${this.kind} protocol framing: ${boundedErrorMessage(error2)}`)}}},ClientMessageDecoder=class{decoder;constructor(options){this.decoder=new ValidatedMessageDecoder("client",parseClientMessage,options)}push(chunk){return this.decoder.push(chunk)}end(){this.decoder.end()}};function isSupportedProtocolVersion(version){return Number.isInteger(version)&&version===PROTOCOL_VERSION}import{Buffer as Buffer4}from"node:buffer";import{Buffer as Buffer3}from"node:buffer";var MISMATCH_MESSAGE="Artifact store returned a mismatched artifact reference",BYTE_LIMIT_MESSAGE="Artifact store exceeded the requested byte limit";async function statValidatedArtifact(artifacts,sessionId,artifactId){let artifact=await artifacts.stat(sessionId,artifactId);if(artifact.sessionId!==sessionId||artifact.artifactId!==artifactId)throw new PiServerError("invalid_request",MISMATCH_MESSAGE);return artifact}async function readValidatedArtifact(artifacts,sessionId,artifactId,options){let chunk=await artifacts.read(sessionId,artifactId,options);if(chunk.artifact.sessionId!==sessionId||chunk.artifact.artifactId!==artifactId)throw new PiServerError("invalid_request",MISMATCH_MESSAGE);if(chunk.data.byteLength>options.maxBytes)throw new PiServerError("invalid_request",BYTE_LIMIT_MESSAGE);return chunk}function toArtifactStatResult(artifact){return{command:"artifact_stat",artifact}}function toArtifactReadResult(chunk){return{command:"artifact_read",artifact:chunk.artifact,encoding:"base64",data:Buffer3.from(chunk.data).toString("base64"),...chunk.nextOffset===void 0?{}:{nextOffset:chunk.nextOffset},eof:chunk.eof}}var MAX_ARTIFACT_READ_BYTES=1048576,MAX_HTTP_BODY_BYTES=65536;function handleArtifactHttpRoutes(dependencies,request,response2){return request.method!=="POST"?!1:request.url==="/artifact/stat"?(serveArtifactStat(dependencies,request,response2),!0):request.url==="/artifact/read"?(serveArtifactRead(dependencies,request,response2),!0):!1}async function serveArtifactStat(dependencies,request,response2){try{let body=await parseArtifactRequestBody(request,!1),consumed=consumeReadToken(dependencies.readTokens,body);if(!consumed.ok){respondTokenRejection(response2,consumed.reason);return}let artifacts=requireArtifacts(dependencies),artifact=await statValidatedArtifact(artifacts,consumed.sessionId,consumed.artifactId);respondJson(response2,200,toArtifactStatResult(artifact))}catch(error2){respondServerError(response2,error2)}}async function serveArtifactRead(dependencies,request,response2){try{let body=await parseArtifactRequestBody(request,!0),consumed=consumeReadToken(dependencies.readTokens,body);if(!consumed.ok){respondTokenRejection(response2,consumed.reason);return}let artifacts=requireArtifacts(dependencies),chunk=await readValidatedArtifact(artifacts,consumed.sessionId,consumed.artifactId,{offset:body.paging.offset,maxBytes:body.paging.maxBytes});respondJson(response2,200,toArtifactReadResult(chunk))}catch(error2){respondServerError(response2,error2)}}async function parseArtifactRequestBody(request,withPaging){let parsed;try{parsed=JSON.parse(await readJsonBody(request))}catch{throw new PiServerError("invalid_request","Artifact request body must be valid JSON")}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))throw new PiServerError("invalid_request","Artifact request body must be a JSON object");let record=parsed,token=record.token;if(typeof token!="string"||token==="")throw new PiServerError("invalid_request","Artifact request requires a token");let sessionId=record.sessionId,artifactId=record.artifactId;if(typeof sessionId!="string"||sessionId===""||typeof artifactId!="string"||artifactId==="")throw new PiServerError("invalid_request","Artifact request requires sessionId and artifactId");if(!withPaging)return{token,sessionId,artifactId,paging:{offset:0,maxBytes:MAX_ARTIFACT_READ_BYTES}};let rawOffset=record.offset??0;if(typeof rawOffset!="number"||!Number.isSafeInteger(rawOffset)||rawOffset<0)throw new PiServerError("invalid_request","Artifact read offset must be a non-negative safe integer");let rawMaxBytes=record.maxBytes??MAX_ARTIFACT_READ_BYTES;if(typeof rawMaxBytes!="number"||!Number.isSafeInteger(rawMaxBytes)||rawMaxBytes<1||rawMaxBytes>MAX_ARTIFACT_READ_BYTES)throw new PiServerError("invalid_request",`Artifact read maxBytes must be an integer between 1 and ${MAX_ARTIFACT_READ_BYTES}`);return{token,sessionId,artifactId,paging:{offset:rawOffset,maxBytes:rawMaxBytes}}}async function readJsonBody(request){let chunks=[],total=0;for await(let chunk of request){let part=Buffer4.isBuffer(chunk)?chunk:Buffer4.from(chunk);if(total+=part.byteLength,total>MAX_HTTP_BODY_BYTES)throw new PiServerError("invalid_request","Artifact request body exceeds the size limit");chunks.push(part)}return Buffer4.concat(chunks).toString("utf8")}function consumeReadToken(readTokens,body){return readTokens.consume(body.token,{sessionId:body.sessionId,artifactId:body.artifactId})}function requireArtifacts(dependencies){if(!dependencies.artifacts)throw new PiServerError("not_found","Artifact access is not configured");return dependencies.artifacts}function respondTokenRejection(response2,reason){if(reason==="binding_mismatch"){respondError(response2,403,"invalid_request","Read token is not bound to the requested artifact");return}respondError(response2,401,"unauthorized",`Read token rejected: ${reason}`)}function respondServerError(response2,error2){if(error2 instanceof PiServerError){let status2=error2.code==="not_found"?404:error2.code==="invalid_request"?400:500;respondError(response2,status2,error2.code,error2.message);return}respondError(response2,500,"internal_error","Internal server error")}function respondJson(response2,status2,body){let payload2=JSON.stringify(body);response2.writeHead(status2,{"Content-Type":"application/json; charset=utf-8","Content-Length":Buffer4.byteLength(payload2)}),response2.end(payload2)}function respondError(response2,status2,code,message){respondJson(response2,status2,{error:{code,message}})}function isTerminalConnection(state2){return state2.disconnected||state2.stage==="closing"||state2.stage==="closed"}import{randomUUID as randomUUID10}from"node:crypto";function toMetadata(snapshot2){return{id:snapshot2.id,createdAt:snapshot2.createdAt,updatedAt:snapshot2.updatedAt,sessionName:snapshot2.name,cwd:snapshot2.cwd}}var DEFAULT_LEASE_TTL_MS2=3e5,IDEMPOTENT_OPERATION_LIMIT=128;function toOperationAckResult(ack){return{command:"operation_ack",operationId:ack.operationId,status:ack.status,...ack.result===void 0?{}:{result:ack.result},...ack.error===void 0?{}:{error:ack.error}}}var LiveSessionManager=class{options;leaseTtlMs;now;liveSessions=new Map;openingSessions=new Map;constructor(options){this.options=options,this.leaseTtlMs=options.leaseTtlMs??DEFAULT_LEASE_TTL_MS2,this.now=options.now??(()=>Date.now())}async executeCommand(connection,command){try{await this.options.authorize?.({context:connection.principalContext,command})}catch(error2){throw error2 instanceof PiServerError?error2:new UnauthorizedError(error2 instanceof Error?error2.message:"Authorization failed")}switch(command.command){case"list":{let sessions=await this.listMetadata();return{command:"list",sessions:this.options.filterSessions?await this.options.filterSessions({context:connection.principalContext,sessions}):sessions}}case"create":{let id=randomUUID10(),options={id,cwd:command.cwd,name:command.name,model:command.model,thinkingLevel:command.thinkingLevel,profileId:command.profileId,profileVersion:command.profileVersion},live=await this.acquire(id,()=>this.options.service.createSession(options));await this.attach(connection,live,"exclusive");let session=this.forConnection(await this.broadcastSnapshot(live),connection);this.options.broadcastServerSnapshot();let lease=connection.sessionLeases.get(live.id);return{command:"create",session,...lease===void 0?{}:{leaseId:lease.leaseId,leaseExpiresAt:lease.expiresAt}}}case"attach":{let live=await this.acquire(command.sessionId,()=>this.options.service.openSession(command.sessionId));await this.attach(connection,live,command.mode??"shared");let session=this.forConnection(await this.broadcastSnapshot(live),connection);this.options.broadcastServerSnapshot();let lease=connection.sessionLeases.get(live.id);return{command:"attach",session,...lease===void 0?{}:{leaseId:lease.leaseId,leaseExpiresAt:lease.expiresAt}}}case"lease_renew":{let live=this.requireAttached(connection,command.sessionId),lease=connection.sessionLeases.get(command.sessionId);if(!lease)throw new PiServerError("session_locked",`No lease to renew: ${command.sessionId}`);return lease.expiresAt=this.now()+this.leaseTtlMs,{command:"lease_renew",sessionId:live.id,leaseId:lease.leaseId,expiresAt:lease.expiresAt}}case"detach":{let live=this.liveSessions.get(command.sessionId);return connection.sessionIds.has(command.sessionId)&&(connection.sessionIds.delete(command.sessionId),connection.sessionLeaseModes.delete(command.sessionId),connection.sessionLeases.delete(command.sessionId),this.options.readTokens?.revokeSession(command.sessionId),live&&(live.connections.delete(connection),live.connections.size>0&&!live.terminal&&!live.disposing&&await this.broadcastSnapshot(live),await this.maybeDispose(live)),this.options.broadcastServerSnapshot()),{command:"detach",sessionId:command.sessionId}}case"prompt":{let live=this.requireAttached(connection,command.sessionId);return{command:"prompt",session:await this.runIdempotent(live,command.operationId,()=>this.runOperation(connection,live,()=>live.runtime.prompt({text:command.text})))}}case"steer":{let live=this.requireAttached(connection,command.sessionId);return{command:"steer",session:await this.runIdempotent(live,command.operationId,()=>this.runOperation(connection,live,()=>live.runtime.steer({text:command.text})))}}case"abort":{let live=this.requireAttached(connection,command.sessionId);return{command:"abort",session:await this.runIdempotent(live,command.operationId,()=>this.runOperation(connection,live,()=>live.runtime.abort()))}}case"set_model":{let live=this.requireAttached(connection,command.sessionId);return{command:"set_model",session:await this.runIdempotent(live,command.operationId,()=>this.runOperation(connection,live,()=>live.runtime.setModel(command.model)))}}case"set_thinking":{let live=this.requireAttached(connection,command.sessionId);return{command:"set_thinking",session:await this.runIdempotent(live,command.operationId,()=>this.runOperation(connection,live,()=>live.runtime.setThinking(command.thinkingLevel)))}}case"replay":{let live=this.requireAttached(connection,command.sessionId);if(!this.options.journal)throw new PiServerError("not_implemented","Durable replay is not configured");let replay=await this.options.journal.replay(command.sessionId,command.afterCursor,command.limit);return{command:"replay",sessionId:live.id,afterCursor:command.afterCursor,nextCursor:replay.nextCursor,complete:replay.complete,gap:replay.gap,events:[...replay.events]}}case"artifact_stat":{this.requireAttached(connection,command.sessionId);let artifacts=this.options.service.artifacts;if(!artifacts)throw new PiServerError("not_implemented","Artifact access is not configured");return toArtifactStatResult(await statValidatedArtifact(artifacts,command.sessionId,command.artifactId))}case"artifact_read":{this.requireAttached(connection,command.sessionId);let artifacts=this.options.service.artifacts;if(!artifacts)throw new PiServerError("not_implemented","Artifact access is not configured");let chunk=await readValidatedArtifact(artifacts,command.sessionId,command.artifactId,{offset:command.offset,maxBytes:command.maxBytes});return toArtifactReadResult(chunk)}case"artifact_token_issue":{this.requireAttached(connection,command.sessionId);let readTokens=this.options.readTokens;if(!readTokens)throw new PiServerError("not_implemented","Read token issuing is not configured");let issued=readTokens.issue(command.sessionId,command.artifactId);return{command:"artifact_token_issue",token:issued.token,expiresAt:issued.expiresAt,sessionId:command.sessionId,artifactId:command.artifactId}}case"operation_submit":{let live=this.requireAttached(connection,command.sessionId),ack=await this.requireOperations().submit({sessionId:live.id,operationType:command.operationType,...command.input===void 0?{}:{input:command.input},...command.idempotencyKey===void 0?{}:{idempotencyKey:command.idempotencyKey},...command.expectedRevision===void 0?{}:{expectedRevision:command.expectedRevision}});return toOperationAckResult(ack)}case"operation_cancel":{let live=this.requireAttached(connection,command.sessionId),ack=await this.requireOperations().cancel({sessionId:live.id,operationId:command.operationId});return toOperationAckResult(ack)}case"operation_result":{let live=this.requireAttached(connection,command.sessionId),ack=await this.requireOperations().result({sessionId:live.id,operationId:command.operationId});return toOperationAckResult(ack)}}}async disconnect(connection){let sessions=[...connection.sessionIds].map(id=>this.liveSessions.get(id)).filter(live=>live!==void 0);connection.sessionIds.clear(),connection.sessionLeaseModes.clear();for(let live of sessions)live.connections.delete(connection);for(let live of sessions)this.options.readTokens?.revokeSession(live.id);let results=await Promise.allSettled(sessions.map(live=>this.maybeDispose(live)));for(let result of results)result.status==="rejected"&&this.options.reportError(result.reason)}async listMetadata(){let stored=await this.options.service.listSessions(),liveSnapshots=await Promise.all([...this.liveSessions.values()].filter(live=>!live.disposing).map(async live=>[live.id,await this.normalizedSnapshot(live)])),liveById=new Map(liveSnapshots),metadata=stored.map(item=>{let snapshot2=liveById.get(item.id);return snapshot2?(liveById.delete(item.id),{...item,...toMetadata(snapshot2)}):item});for(let snapshot2 of liveById.values())metadata.push(toMetadata(snapshot2));return metadata}async close(){let openingResults=await Promise.allSettled([...this.openingSessions.values()]);for(let result of openingResults)result.status==="rejected"&&this.options.reportError(result.reason);let sessions=[...this.liveSessions.values()];this.liveSessions.clear(),await Promise.all(sessions.map(async live=>{if(live.disposing){await live.disposing;return}live.unsubscribe(),await live.runtime.dispose()}))}async runOperation(connection,live,operation){live.operationCount+=1;try{return await operation(),this.forConnection(await this.broadcastSnapshot(live),connection)}finally{live.operationCount-=1,this.scheduleMaybeDispose(live)}}async runIdempotent(live,operationId,execute){if(operationId===void 0)return execute();let cache=live.idempotentOperations,recorded=cache.get(operationId);if(recorded)return cache.delete(operationId),cache.set(operationId,recorded),recorded;let pending=this.executeRecorded(live.id,operationId,execute);for(cache.set(operationId,pending);cache.size>IDEMPOTENT_OPERATION_LIMIT;){let oldest=cache.keys().next();if(oldest.done)break;cache.delete(oldest.value)}try{return await pending}catch(error2){throw cache.get(operationId)===pending&&cache.delete(operationId),error2}}async executeRecorded(sessionId,operationId,execute){let store=this.options.service.mutationResponses;if(store){let stored;try{stored=await store.load(sessionId,operationId)}catch(error2){this.options.reportError(error2)}if(stored)return stored}let snapshot2=await execute();return store&&store.record(sessionId,operationId,snapshot2).catch(error2=>this.options.reportError(error2)),snapshot2}async acquire(id,acquireRuntime){for(;;){let existing=this.liveSessions.get(id);if(existing){if(existing.terminal)throw new PiServerError("session_locked",`Session runtime is terminating: ${id}`);if(existing.disposing){await existing.disposing;continue}return existing}let opening=this.openingSessions.get(id);if(opening)return opening;let pending=this.create(id,acquireRuntime);this.openingSessions.set(id,pending);try{return await pending}finally{this.openingSessions.get(id)===pending&&this.openingSessions.delete(id)}}}async create(id,acquireRuntime){let runtime=await acquireRuntime();if(this.options.isClosing())throw await runtime.dispose(),new Error("PiServer closed while acquiring a session runtime");let live;try{let snapshot2=await runtime.snapshot();if(snapshot2.id!==id)throw new PiServerError("invalid_request",`Service returned session ${snapshot2.id} for server-assigned session ${id}`);return live={id,runtime,connections:new Set,unsubscribe:()=>{},operationCount:0,ready:!1,terminal:!1,idempotentOperations:new Map},live.unsubscribe=runtime.subscribe(event=>{this.handleRuntimeEvent(live,event).catch(error2=>this.options.reportError(error2))}),this.liveSessions.set(id,live),live.ready=!0,live}catch(error2){live&&live.unsubscribe();try{await runtime.dispose()}catch(disposeError){this.options.reportError(disposeError)}throw error2}}async handleRuntimeEvent(live,event){if(event.type==="error"){this.terminate(live,event.error).catch(error2=>this.options.reportError(error2));return}if(event.type==="progress"){let progressEvent={type:"session_progress",sessionId:live.id,progress:event.progress};await this.options.journal?.append(live.id,progressEvent);let envelope={type:"event",event:progressEvent};for(let connection of live.connections)this.options.sendMessage(connection,envelope)}else this.broadcastSnapshot(live).catch(error2=>this.options.reportError(error2));this.scheduleMaybeDispose(live)}async terminate(live,error2){if(live.terminal)return;live.terminal=!0,this.options.readTokens?.revokeSession(live.id),this.options.reportError(error2);try{await this.options.journal?.append(live.id,{type:"session_removed",sessionId:live.id})}catch(appendError){this.options.reportError(appendError)}live.unsubscribe();let connections=[...live.connections];await Promise.all(connections.map(connection=>this.options.closeConnection(connection.connection))),await Promise.all(connections.map(connection=>this.options.disconnect(connection))),await this.maybeDispose(live)}async normalizedSnapshot(live){let snapshot2=await live.runtime.snapshot();if(snapshot2.id!==live.id)throw new PiServerError("invalid_request",`Runtime session ID changed from ${live.id} to ${snapshot2.id}`);return{...snapshot2,phase:live.runtime.getPhase(),attached:live.connections.size>0,locked:!0}}forConnection(snapshot2,connection){return{...snapshot2,attached:connection.sessionIds.has(snapshot2.id)}}async broadcastSnapshot(live){let snapshot2=await this.normalizedSnapshot(live),event={type:"session_snapshot",snapshot:snapshot2};await this.options.journal?.append(live.id,event);let envelope={type:"event",event};for(let connection of live.connections)this.options.sendMessage(connection,envelope);return snapshot2}async attach(connection,live,mode){if(live.disposing||live.terminal)throw new PiServerError("session_locked",`Session runtime is terminating: ${live.id}`);if(connection.disconnected||connection.stage!=="ready"||connection.connection.closed)throw await this.maybeDispose(live),new PiServerError("invalid_request","Connection closed while attaching to a session");let existingMode=connection.sessionLeaseModes.get(live.id);if(existingMode!==void 0&&existingMode!==mode)throw new PiServerError("session_locked",`Connection already holds a ${existingMode} lease: ${live.id}`);for(let attached of live.connections){let attachedMode=attached.sessionLeaseModes.get(live.id);if(attached===connection)continue;let attachedLease=attached.sessionLeases.get(live.id);if(attachedLease&&attachedLease.expiresAt<=this.now()){this.options.readTokens?.revokeSession(live.id),attached.sessionLeaseModes.delete(live.id),attached.sessionLeases.delete(live.id),attached.sessionIds.delete(live.id),live.connections.delete(attached);continue}if(mode==="exclusive"||attachedMode==="exclusive")throw new PiServerError("session_locked",`Session lease conflict: ${live.id}`)}connection.sessionIds.add(live.id),connection.sessionLeaseModes.set(live.id,mode),connection.sessionLeases.set(live.id,{leaseId:randomUUID10(),expiresAt:this.now()+this.leaseTtlMs}),live.connections.add(connection)}requireAttached(connection,sessionId){if(!connection.sessionIds.has(sessionId))throw new PiServerError("invalid_request",`Connection is not attached to session ${sessionId}`);let lease=connection.sessionLeases.get(sessionId);if(lease&&lease.expiresAt<=this.now()){this.options.readTokens?.revokeSession(sessionId),connection.sessionIds.delete(sessionId),connection.sessionLeaseModes.delete(sessionId),connection.sessionLeases.delete(sessionId);let live2=this.liveSessions.get(sessionId);throw live2&&(live2.connections.delete(connection),this.scheduleMaybeDispose(live2)),new PiServerError("session_locked",`Session lease expired: ${sessionId}`)}let live=this.liveSessions.get(sessionId);if(!live||live.terminal||live.disposing)throw new PiServerError("not_found",`Session is not live: ${sessionId}`);return live}requireOperations(){let operations=this.options.service.operations;if(!operations)throw new PiServerError("durable_unavailable","Durable operation store is not configured");return operations}scheduleMaybeDispose(live){this.maybeDispose(live).catch(error2=>this.options.reportError(error2))}async maybeDispose(live){if(this.options.isClosing()||!live.ready||live.disposing||live.connections.size>0||live.operationCount>0||!live.terminal&&live.runtime.getPhase()!=="idle")return live.disposing;live.unsubscribe(),this.options.readTokens?.revokeSession(live.id),live.disposing=(async()=>{try{await live.runtime.dispose()}finally{this.liveSessions.get(live.id)===live&&this.liveSessions.delete(live.id)}})(),await live.disposing,this.options.isClosing()||this.options.broadcastServerSnapshot()}};var ServerSnapshotPublisher=class{options;revision=0;broadcastQueue=Promise.resolve();constructor(options){this.options=options}get currentRevision(){return this.revision}async get(models,applyFilter){let sessions=applyFilter?await applyFilter(await this.options.listSessions()):await this.options.listSessions();return{serverId:this.options.serverId,protocolVersion:PROTOCOL_VERSION,revision:this.revision,sessions,models:models??await this.options.service.listModels()}}broadcast(){let broadcast=this.broadcastQueue.then(()=>this.performBroadcast());return this.broadcastQueue=broadcast.catch(error2=>this.options.reportError(error2)),broadcast}async performBroadcast(){let readyConnections=[...this.options.connections].filter(connection=>connection.stage==="ready"&&!connection.disconnected);if(readyConnections.length===0||this.options.isClosing())return;let revision=++this.revision,models=await this.options.service.listModels(),filter2=this.options.filterSessions;for(let connection of readyConnections){let sessions=filter2?await filter2({context:connection.principalContext,sessions:await this.options.listSessions()}):await this.options.listSessions(),envelope={type:"event",event:{type:"server_snapshot",snapshot:{serverId:this.options.serverId,protocolVersion:PROTOCOL_VERSION,revision,sessions,models}}};await this.options.sendMessage(connection,envelope)}}};var DEFAULT_HANDSHAKE_TIMEOUT_MS=5e3,DEFAULT_LEASE_TTL_MS3=3e5,MAX_UINT322=4294967295,MAX_TIMER_DELAY_MS=2147483647,PiServer=class{id;listeners;maxFrameLength;handshakeTimeoutMs;onError;journal;authenticate;filterSessions;connections=new Set;service;sessions;readTokens;snapshots;closing=!1;closePromise;startPromise;started=!1;constructor(service,options){let resolved=resolveOptions2(options);this.listeners=options.listeners,this.id=options.serverId??randomUUID11(),this.maxFrameLength=resolved.maxFrameLength,this.handshakeTimeoutMs=resolved.handshakeTimeoutMs,this.onError=options.onError,this.journal=options.journal,this.authenticate=options.authenticate,this.service=service,this.readTokens=new ReadTokenStore({now:options.now}),this.sessions=new LiveSessionManager({service,isClosing:()=>this.closing,sendMessage:(connection,message)=>this.sendMessage(connection,message),closeConnection:connection=>this.closeConnection(connection),disconnect:connection=>this.disconnect(connection),broadcastServerSnapshot:()=>this.scheduleSnapshotBroadcast(),reportError:error2=>this.reportError(error2),journal:options.journal,authorize:options.authorize,filterSessions:options.filterSessions,leaseTtlMs:resolved.leaseTtlMs,readTokens:this.readTokens,now:options.now}),this.filterSessions=options.filterSessions,this.snapshots=new ServerSnapshotPublisher({serverId:this.id,service,connections:this.connections,isClosing:()=>this.closing,listSessions:()=>this.sessions.listMetadata(),filterSessions:options.filterSessions,sendMessage:(connection,message)=>this.sendMessage(connection,message),reportError:error2=>this.reportError(error2)})}get addresses(){return this.listeners.flatMap(listener=>listener.address===void 0?[]:[listener.address])}start(){return this.started?Promise.reject(new Error("PiServer is already started")):this.startPromise?Promise.reject(new Error("PiServer is already starting")):this.closing?Promise.reject(new Error("PiServer is closing or closed")):(this.startPromise=this.startInternal(),this.startPromise)}async startInternal(){let started=[];try{for(let listener of this.listeners)await listener.start(connection=>this.accept(connection)),started.push(listener);return this.started=!0,this}catch(error2){throw this.closing=!0,await Promise.allSettled(started.map(listener=>listener.close())),await this.closeServerState(),error2}finally{this.startPromise=void 0}}handleArtifactHttpRequest(request,response2){return handleArtifactHttpRoutes({readTokens:this.readTokens,artifacts:this.service.artifacts},request,response2)}accept(connection){if(this.closing)return this.closeConnection(connection),{onData:()=>{},onClose:()=>{},onError:error2=>this.reportError(error2)};let state2,handshakeTimeout=setTimeout(()=>{this.failProtocol(state2,{code:"invalid_request",message:"Handshake timeout"})},this.handshakeTimeoutMs);return handshakeTimeout.unref(),state2={id:randomUUID11(),connection,decoder:new ClientMessageDecoder({maxFrameLength:this.maxFrameLength}),sessionIds:new Set,sessionLeaseModes:new Map,sessionLeases:new Map,principalContext:{principalId:"anonymous"},stage:"awaitingHello",disconnected:!1,handshakeComplete:!1,handshakeTimeout},this.connections.add(state2),{onData:chunk=>this.receive(state2,chunk),onClose:()=>this.transportClosed(state2),onError:error2=>{this.reportError(error2),this.closeConnection(connection).then(()=>this.disconnect(state2))}}}async close(){return this.closePromise?this.closePromise:(this.closing=!0,this.closePromise=this.closeInternal(),this.closePromise)}async closeInternal(){let starting=this.startPromise;starting&&await starting.catch(()=>{});try{await Promise.all(this.listeners.map(listener=>listener.close()))}finally{await this.closeServerState(),this.started=!1}}receive(state2,chunk){if(isTerminalConnection(state2))return;let messages;try{messages=state2.decoder.push(chunk)}catch(error2){this.failProtocol(state2,this.toProtocolError(error2));return}for(let message of messages){if(isTerminalConnection(state2))return;this.dispatchMessage(state2,message)}}dispatchMessage(state2,message){if(state2.stage==="awaitingHello"){if(message.type!=="hello"){this.failProtocol(state2,{code:"invalid_request",message:"The first client message must be hello"});return}state2.stage="handshaking",state2.handshake=this.finishHandshake(state2,message).catch(error2=>this.failProtocol(state2,this.toProtocolError(error2)));return}if(message.type==="hello"){this.failProtocol(state2,{code:"invalid_request",message:"hello may only be sent as the first message"});return}if(state2.stage==="ready"){this.handleRequest(state2,message);return}if(state2.stage!=="handshaking")return;let handshake=state2.handshake;handshake&&handshake.then(()=>{state2.stage==="ready"&&!state2.disconnected&&this.handleRequest(state2,message)})}async finishHandshake(state2,hello){if(!isSupportedProtocolVersion(hello.version)){await this.failProtocol(state2,{code:"version",message:`Unsupported protocol version ${hello.version}; expected ${PROTOCOL_VERSION}`});return}try{let principal=this.authenticate?await this.authenticate({connectionId:state2.id,...hello.auth===void 0?{}:{auth:hello.auth}}):{principalId:"anonymous"};if(!principal||principal.principalId.trim()==="")throw new Error("Authenticated principalId is required");state2.principalContext=Object.freeze({...principal})}catch(error2){await this.failProtocol(state2,{code:"unauthorized",message:error2 instanceof Error?error2.message:"Authentication failed"});return}let snapshot2=await this.snapshots.get(void 0,sessions=>this.filterSessions?this.filterSessions({context:state2.principalContext,sessions}):sessions);if(this.closing||state2.disconnected||state2.stage!=="handshaking"||state2.connection.closed)return;if(await this.sendMessage(state2,{type:"hello",version:PROTOCOL_VERSION,connectionId:state2.id,snapshot:snapshot2})&&!state2.disconnected&&state2.stage==="handshaking"&&(state2.handshakeComplete=!0,state2.stage="ready",clearTimeout(state2.handshakeTimeout),snapshot2.revision!==this.snapshots.currentRevision)){let current=await this.snapshots.get();await this.sendMessage(state2,{type:"event",event:{type:"server_snapshot",snapshot:current}})}}async handleRequest(state2,envelope){let response2;try{let result=await this.sessions.executeCommand(state2,envelope.request);response2={type:"response",id:envelope.id,ok:!0,result}}catch(error2){response2={type:"response",id:envelope.id,ok:!1,error:this.toProtocolError(error2)}}let outcome=await this.transmitMessage(state2,response2);outcome!=="sent"&&(outcome==="oversize"&&!state2.disconnected&&await this.transmitMessage(state2,{type:"response",id:envelope.id,ok:!1,error:{code:"invalid_request",message:`Response frame exceeds the configured limit of ${this.maxFrameLength} bytes`}}),outcome!=="closed"&&await this.abandonConnection(state2))}transportClosed(connection){if(!connection.disconnected&&connection.stage!=="closing")try{connection.decoder.end()}catch(error2){this.reportError(error2)}this.disconnect(connection)}async disconnect(connection){if(connection.disconnected)return;let handshakeComplete=connection.handshakeComplete;connection.disconnected=!0,connection.stage="closed",clearTimeout(connection.handshakeTimeout),this.connections.delete(connection),await this.sessions.disconnect(connection),!this.closing&&handshakeComplete&&this.scheduleSnapshotBroadcast()}scheduleSnapshotBroadcast(){this.snapshots.broadcast().catch(()=>{})}async sendMessage(connection,message){let outcome=await this.transmitMessage(connection,message);return outcome==="sent"?!0:(outcome!=="closed"&&await this.abandonConnection(connection),!1)}async transmitMessage(connection,message){if(connection.disconnected||connection.connection.closed)return"closed";let frame;try{frame=encodeServerMessage(message,{maxFrameLength:this.maxFrameLength})}catch(error2){return this.reportError(error2),"oversize"}try{return await connection.connection.send(frame),"sent"}catch(error2){return this.reportError(error2),"failed"}}async abandonConnection(connection){await this.closeConnection(connection.connection),await this.disconnect(connection)}async failProtocol(connection,error2){if(connection.disconnected||connection.stage==="closing"||connection.stage==="closed")return;connection.stage="closing",clearTimeout(connection.handshakeTimeout);let message={type:"hello_error",error:error2},finalFrame;try{finalFrame=encodeServerMessage(message,{maxFrameLength:this.maxFrameLength})}catch(encodeError){this.reportError(encodeError)}await this.closeConnection(connection.connection,finalFrame),await this.disconnect(connection)}async closeServerState(){let connections=[...this.connections];for(let connection of connections)connection.stage="closing",clearTimeout(connection.handshakeTimeout);await Promise.all(connections.map(connection=>this.closeConnection(connection.connection))),await Promise.all(connections.map(connection=>this.disconnect(connection))),await this.sessions.close(),await this.journal?.close(),this.connections.clear()}async closeConnection(connection,finalChunk){try{await connection.close(finalChunk)}catch(error2){this.reportError(error2)}}toProtocolError(error2){return error2 instanceof InternalServerError?(this.reportError(error2.cause),{code:"internal_error",message:INTERNAL_SERVER_ERROR_MESSAGE}):error2 instanceof PiServerError?error2.code==="not_implemented"?{code:"not_implemented",message:NOT_IMPLEMENTED_MESSAGE}:error2.details===void 0?{code:error2.code,message:error2.message}:{code:error2.code,message:error2.message,details:error2.details}:error2 instanceof ProtocolValidationError?{code:"invalid_request",message:error2.message}:(this.reportError(error2),{code:"internal_error",message:INTERNAL_SERVER_ERROR_MESSAGE})}reportError(error2){try{this.onError?.(error2 instanceof Error?error2:new Error(String(error2)))}catch{}}};function resolveOptions2(options){if(!Array.isArray(options.listeners))throw new TypeError("PiServer listeners must be an array");if(options.serverId==="")throw new TypeError("PiServer serverId must not be empty");let maxFrameLength=options.maxFrameLength??16777216;if(!Number.isSafeInteger(maxFrameLength)||maxFrameLength<=0||maxFrameLength>MAX_UINT322)throw new TypeError(`PiServer maxFrameLength must be an integer between 1 and ${MAX_UINT322}`);let leaseTtlMs=options.leaseTtlMs??DEFAULT_LEASE_TTL_MS3;if(!Number.isSafeInteger(leaseTtlMs)||leaseTtlMs<=0||leaseTtlMs>MAX_TIMER_DELAY_MS)throw new TypeError(`PiServer leaseTtlMs must be an integer between 1 and ${MAX_TIMER_DELAY_MS}`);let handshakeTimeoutMs=options.handshakeTimeoutMs??DEFAULT_HANDSHAKE_TIMEOUT_MS;if(!Number.isSafeInteger(handshakeTimeoutMs)||handshakeTimeoutMs<=0||handshakeTimeoutMs>MAX_TIMER_DELAY_MS)throw new TypeError(`PiServer handshakeTimeoutMs must be an integer between 1 and ${MAX_TIMER_DELAY_MS}`);return{maxFrameLength,handshakeTimeoutMs,leaseTtlMs}}var MAX_UNIX_SOCKET_PATH_BYTES=process.platform==="linux"?107:103;function closeNetServer(server,reportError){return server.listening?new Promise(resolve25=>{server.close(error2=>{error2&&reportError(error2),resolve25()})}):Promise.resolve()}function validateTcpPort(port,description="TCP port"){if(!Number.isInteger(port)||port<0||port>65535)throw new TypeError(`${description} must be an integer between 0 and 65535`)}import{createServer as createHttpServer}from"node:http";var DEFAULT_GRACEFUL_CLOSE_TIMEOUT_MS=5e3,DEFAULT_WS_HOST="127.0.0.1",MAX_UINT323=4294967295,MAX_TIMER_DELAY_MS2=2147483647,WsListener=class{options;connections=new Set;httpServer;gateway;boundAddress;closing=!1;closePromise;accept;constructor(options){this.options=resolveWsListenerOptions(options)}get address(){return this.boundAddress}async start(accept){if(this.httpServer)throw new Error("WS listener is already started");if(this.closing)throw new Error("WS listener is closing or closed");this.accept=accept;let httpServer=createHttpServer((request,response2)=>{this.options.httpRequestHandler?.(request,response2)||handleHealthRequest(request,response2,this.boundAddress)||(response2.writeHead(426,{Upgrade:"websocket"}),response2.end("upgrade required"))});httpServer.on("error",error2=>this.reportError(error2));let gateway=new import_websocket_server.default({server:httpServer,maxPayload:this.options.maxPayloadBytes});gateway.on("connection",socket=>this.acceptSocket(socket)),this.httpServer=httpServer,this.gateway=gateway;try{await new Promise((resolve25,reject2)=>{let onError=error2=>{httpServer.off("listening",onListening),reject2(error2)},onListening=()=>{httpServer.off("error",onError),resolve25()};httpServer.once("error",onError),httpServer.once("listening",onListening),httpServer.listen(this.options.port,this.options.host)}),this.boundAddress=formatBindAddress(httpServer.address())}catch(error2){throw gateway.close(),await closeNetServer(httpServer,reportError=>this.reportError(reportError)),this.httpServer=void 0,this.gateway=void 0,error2}}async close(){return this.closePromise?this.closePromise:(this.closing=!0,this.closePromise=this.closeInternal(),this.closePromise)}acceptSocket(socket){if(this.closing){socket.terminate();return}let connection=new WsByteConnection(socket,this.options.gracefulCloseTimeoutMs,this.options.maxPendingBytes);this.connections.add(connection);let accept=this.accept;if(!accept){socket.terminate();return}let handler=accept(connection),onCloseDelivered=!1,deliverClose=()=>{onCloseDelivered||(onCloseDelivered=!0,handler.onClose())};socket.on("message",(data,isBinary)=>{if(!isBinary){connection.markClosed(),socket.close(1003,"binary protocol frames only"),deliverClose();return}handler.onData(toUint8Array(data))}),socket.on("error",error2=>{isWsSizeRejection(error2)||handler.onError(error2)}),socket.once("close",()=>{connection.markClosed(),this.connections.delete(connection),deliverClose()})}async closeInternal(){this.boundAddress=void 0;let connectionsClosed=Promise.all([...this.connections].map(connection=>connection.close())),gateway=this.gateway,httpServer=this.httpServer;this.gateway=void 0,this.httpServer=void 0,await connectionsClosed,gateway?.close(),httpServer&&await closeNetServer(httpServer,error2=>this.reportError(error2)),this.connections.clear()}reportError(error2){try{this.options.onError?.(error2 instanceof Error?error2:new Error(String(error2)))}catch{}}},WsByteConnection=class{socket;gracefulCloseTimeoutMs;maxPendingBytes;pendingBytes=0;closedValue=!1;closing=!1;writeTail=Promise.resolve();closePromise;resolveClose;constructor(socket,gracefulCloseTimeoutMs,maxPendingBytes){this.socket=socket,this.gracefulCloseTimeoutMs=gracefulCloseTimeoutMs,this.maxPendingBytes=maxPendingBytes}get closed(){return this.closedValue||this.socket.readyState!==import_websocket.default.OPEN}send(chunk){if(!(chunk instanceof Uint8Array))return Promise.reject(new TypeError("WS connection chunks must be Uint8Array"));if(this.closedValue||this.closing)return Promise.reject(new Error("WS connection is closed"));if(this.pendingBytes+chunk.byteLength>this.maxPendingBytes)return Promise.reject(new Error("WS connection exceeded its pending byte limit"));this.pendingBytes+=chunk.byteLength;let bytes=chunk.slice(),tracked=this.writeTail.then(()=>this.write(bytes)).finally(()=>{this.pendingBytes-=bytes.byteLength});return this.writeTail=tracked.catch(()=>{}),tracked}close(finalChunk){if(this.closedValue||this.socket.readyState===import_websocket.default.CLOSED)return this.markClosed(),Promise.resolve();if(this.closePromise)return this.closePromise;this.closing=!0;let finalBytes=finalChunk?.slice();return this.closePromise=new Promise(resolve25=>{this.resolveClose=resolve25;let timer=setTimeout(()=>{this.socket.readyState!==import_websocket.default.CLOSED&&this.socket.terminate()},this.gracefulCloseTimeoutMs);timer.unref(),this.socket.once("close",()=>{clearTimeout(timer),this.markClosed(),resolve25()}),this.writeTail.then(()=>{if(!this.closedValue)try{finalBytes&&this.socket.send(finalBytes),this.socket.readyState===import_websocket.default.OPEN&&this.socket.close(1e3,"protocol close")}catch{this.socket.terminate()}})}),this.closePromise}markClosed(){this.closedValue||(this.closedValue=!0,this.closing=!0,this.resolveClose?.(),this.resolveClose=void 0)}write(chunk){return this.closedValue||this.closing||this.socket.readyState!==import_websocket.default.OPEN?Promise.reject(new Error("WS connection is closed")):new Promise((resolve25,reject2)=>{try{this.socket.send(chunk,error2=>{error2?reject2(error2):resolve25()})}catch(error2){reject2(error2 instanceof Error?error2:new Error(String(error2)))}})}};function toUint8Array(data){if(data instanceof ArrayBuffer)return new Uint8Array(data);if(Array.isArray(data)){let joined=Buffer.concat(data);return new Uint8Array(joined.buffer,joined.byteOffset,joined.byteLength)}return new Uint8Array(data.buffer,data.byteOffset,data.byteLength)}function isWsSizeRejection(error2){return error2 instanceof Error&&"code"in error2&&error2.code==="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"}function handleHealthRequest(request,response2,boundAddress){if(request.method!=="GET"||request.url!=="/healthz")return!1;let body=JSON.stringify({status:"ok",transport:"ws",address:boundAddress});return response2.writeHead(200,{"Content-Type":"application/json; charset=utf-8","Content-Length":Buffer.byteLength(body)}),response2.end(body),!0}function formatBindAddress(address){return address===null?"unknown":typeof address=="string"?address:`${address.address}:${address.port}`}function resolveWsListenerOptions(options){validateTcpPort(options.port,"PiServer WS port");let maxPayloadBytes=options.maxPayloadBytes??16777216;if(!Number.isSafeInteger(maxPayloadBytes)||maxPayloadBytes<=0)throw new TypeError("PiServer WS maxPayloadBytes must be a positive safe integer");let maxFrameLength=options.maxFrameLength??16777216;if(!Number.isSafeInteger(maxFrameLength)||maxFrameLength<=0||maxFrameLength>MAX_UINT323)throw new TypeError(`PiServer maxFrameLength must be an integer between 1 and ${MAX_UINT323}`);let maxPendingBytes=options.maxPendingBytes??maxFrameLength*4;if(!Number.isSafeInteger(maxPendingBytes)||maxPendingBytes<maxFrameLength+4)throw new TypeError("PiServer maxPendingBytes must be a safe integer at least maxFrameLength + 4");let gracefulCloseTimeoutMs=options.gracefulCloseTimeoutMs??DEFAULT_GRACEFUL_CLOSE_TIMEOUT_MS;if(!Number.isSafeInteger(gracefulCloseTimeoutMs)||gracefulCloseTimeoutMs<=0||gracefulCloseTimeoutMs>MAX_TIMER_DELAY_MS2)throw new TypeError(`PiServer gracefulCloseTimeoutMs must be an integer between 1 and ${MAX_TIMER_DELAY_MS2}`);return{port:options.port,host:options.host??DEFAULT_WS_HOST,maxPayloadBytes,maxPendingBytes,gracefulCloseTimeoutMs,httpRequestHandler:options.httpRequestHandler,onError:options.onError}}function createWsServerListener(options){return new WsListener(options)}function requireIdle(session,action){if(!session.isIdle)throw new PiServerError("busy",`Cannot ${action} while the session is busy`)}function toError(error2){if(error2 instanceof PiServerError)return error2;let message=error2 instanceof Error?error2.message:String(error2);return/reload in progress/i.test(message)?new PiServerError("busy",message):/compaction is in progress/i.test(message)?new PiServerError("busy",message):/already processing/i.test(message)?new PiServerError("busy",message):new PiServerError("invalid_request",message)}function jsonSafe(value){return value===null||typeof value=="string"||typeof value=="boolean"?!0:typeof value=="number"?Number.isFinite(value):Array.isArray(value)?value.every(jsonSafe):typeof value!="object"||Object.getPrototypeOf(value)!==Object.prototype?!1:Object.values(value).every(jsonSafe)}function parseOperationPayload(value){if(typeof value!="object"||value===null||Array.isArray(value))return;let record=value;if(record.status!=="pending"&&record.status!=="completed"&&record.status!=="rejected"||typeof record.sessionId!="string"||record.sessionId===""||typeof record.operationType!="string"||typeof record.submittedAt!="number"||!Number.isFinite(record.submittedAt))return;let error2;if(record.error!==void 0){if(typeof record.error!="object"||record.error===null||Array.isArray(record.error))return;let entry=record.error;if(typeof entry.code!="string"||typeof entry.message!="string")return;error2={code:entry.code,message:entry.message}}return{status:record.status,sessionId:record.sessionId,operationType:record.operationType,...typeof record.idempotencyKey=="string"?{idempotencyKey:record.idempotencyKey}:{},...record.result===void 0?{}:{result:record.result},...error2===void 0?{}:{error:error2},submittedAt:record.submittedAt,...typeof record.terminalAt=="number"?{terminalAt:record.terminalAt}:{}}}function parseArtifactPayload(value){if(typeof value!="object"||value===null||Array.isArray(value))return;let record=value,ref=record.ref;if(typeof ref!="object"||ref===null||Array.isArray(ref))return;let entry=ref;if(!(typeof entry.sessionId!="string"||typeof entry.operationId!="string"||typeof entry.artifactId!="string"||typeof entry.kind!="string"||typeof entry.mediaType!="string"||typeof entry.truncated!="boolean"||typeof entry.createdAt!="number"||typeof record.bytes!="string"))return{ref:{sessionId:entry.sessionId,operationId:entry.operationId,artifactId:entry.artifactId,kind:entry.kind,mediaType:entry.mediaType,...typeof entry.sizeBytes=="number"?{sizeBytes:entry.sizeBytes}:{},truncated:entry.truncated,createdAt:entry.createdAt},bytes:record.bytes}}function parseMutationResponsePayload(value,sessionId){if(typeof value!="object"||value===null||Array.isArray(value))return;let record=value;if(!(record.id!==sessionId||typeof record.cwd!="string"||record.cwd===""||typeof record.revision!="number"||!Number.isInteger(record.revision)||record.revision<0||!Array.isArray(record.transcript)))return value}function toProtocolArtifactRef(ref){return{sessionId:ref.sessionId,operationId:ref.operationId,artifactId:ref.artifactId,kind:ref.kind,mediaType:ref.mediaType,...ref.sizeBytes===void 0?{}:{sizeBytes:ref.sizeBytes},truncated:ref.truncated,createdAt:ref.createdAt}}function projectUsage(usage){if(!usage||typeof usage!="object"||Array.isArray(usage))return;let record=usage,readCount=key=>{let value=record[key];return typeof value=="number"&&Number.isFinite(value)?Math.max(0,Math.trunc(value)):void 0},input=readCount("input"),output=readCount("output"),cacheRead=readCount("cacheRead"),cacheWrite=readCount("cacheWrite"),totalTokens=readCount("totalTokens");if(input===void 0||output===void 0||cacheRead===void 0||cacheWrite===void 0||totalTokens===void 0)return;let cost=record.cost;if(!cost||typeof cost!="object"||Array.isArray(cost))return;let costRecord=cost,readCost=key=>{let value=costRecord[key];return typeof value=="number"&&Number.isFinite(value)?value:void 0},costInput=readCost("input"),costOutput=readCost("output"),costCacheRead=readCost("cacheRead"),costCacheWrite=readCost("cacheWrite"),costTotal=readCost("total");if(costInput===void 0||costOutput===void 0||costCacheRead===void 0||costCacheWrite===void 0||costTotal===void 0)return;let reasoning=readCount("reasoning");return{input,output,cacheRead,cacheWrite,...reasoning===void 0?{}:{reasoning},totalTokens,cost:{input:costInput,output:costOutput,cacheRead:costCacheRead,cacheWrite:costCacheWrite,total:costTotal}}}function projectUserContent(content){if(typeof content=="string")return[{type:"text",text:content}];let projected=[];for(let part of content){if(!part||typeof part!="object")continue;let record=part;record.type==="text"&&typeof record.text=="string"?projected.push({type:"text",text:record.text}):record.type==="image"&&typeof record.data=="string"&&typeof record.mimeType=="string"&&projected.push({type:"image",data:record.data,mimeType:record.mimeType})}return projected}function projectToolResultContent(content){return projectUserContent(content)}function projectSessionTranscript(session){let messages=session.messages,toolInputs=new Map;for(let message of messages)if(message.role==="assistant")for(let part of message.content)part.type==="toolCall"&&toolInputs.set(part.id,part.arguments);let items=[];for(let message of messages){let id=`t-${items.length}`,timestamp=Math.max(0,Math.trunc(message.timestamp));if(message.role==="user"){items.push({id,role:"user",content:projectUserContent(message.content),timestamp});continue}if(message.role==="toolResult"){let input=toolInputs.get(message.toolCallId),usage2=projectUsage(message.usage),details=jsonSafe(message.details)?message.details:void 0,base={id,role:"tool",toolCallId:message.toolCallId,toolName:message.toolName,input:input!==void 0&&jsonSafe(input)?input:null,content:projectToolResultContent(message.content),...details===void 0?{}:{details},...usage2===void 0?{}:{usage:usage2},timestamp};if(message.isError){let item={...base,status:"error",isError:!0};items.push(item)}else{let item={...base,status:"complete",isError:!1};items.push(item)}continue}if(message.role==="bashExecution"){let failed=message.cancelled||message.exitCode!==void 0&&message.exitCode!==0,base={id,role:"tool",toolCallId:`bash-${id}`,toolName:"bash",input:{command:message.command},content:[{type:"text",text:message.output}],details:{exitCode:message.exitCode??null,cancelled:message.cancelled,truncated:message.truncated},timestamp};if(failed){let item={...base,status:"error",isError:!0};items.push(item)}else{let item={...base,status:"complete",isError:!1};items.push(item)}continue}if(message.role==="branchSummary"){items.push({id,role:"note",kind:"branchSummary",text:message.summary,fromId:message.fromId,timestamp});continue}if(message.role==="compactionSummary"){items.push({id,role:"note",kind:"compactionSummary",text:message.summary,tokensBefore:Math.max(0,Math.trunc(message.tokensBefore)),timestamp});continue}if(message.role==="custom"){let text=typeof message.content=="string"?message.content:message.content.filter(part=>part.type==="text").map(part=>part.text).join(`
@@ -1052,7 +1052,7 @@ ${body}
1052
1052
  </skill>`;return args?`${skillBlock}
1053
1053
 
1054
1054
  ${args}`:skillBlock}catch(err2){return this._hostLogger?.error("session","skill expansion failed",{...this.sessionId===void 0?{}:{sessionId:this.sessionId},fields:{skill:skill.name,path:skill.filePath},cause:err2}),text}}async _queueUserInput(text,images,behavior,source){let processedInput=await this._runInputHandlers(text,images,source),expandedText=this._expandSkillCommand(processedInput.text);expandedText=expandPromptTemplate(expandedText,[...this.promptTemplates]),behavior==="steer"?await this._queueSteer(expandedText,processedInput.images):await this._queueFollowUp(expandedText,processedInput.images)}async steer(text,images,options){await this._queueUserInput(text,images,"steer",options?.source??"interactive")}async followUp(text,images,options){await this._queueUserInput(text,images,"followUp",options?.source??"interactive")}async _queueSteer(text,images){this._steeringMessages.push(text),this._emitQueueUpdate();let content=[{type:"text",text}];images&&content.push(...images),this.agent.steer({role:"user",content,timestamp:Date.now()})}async _queueFollowUp(text,images){this._followUpMessages.push(text),this._emitQueueUpdate();let content=[{type:"text",text}];images&&content.push(...images),this.agent.followUp({role:"user",content,timestamp:Date.now()})}async sendCustomMessage(message,options){let appMessage={role:"custom",customType:message.customType,content:message.content??[],display:message.display,details:message.details,timestamp:Date.now()};options?.deliverAs==="nextTurn"?this._pendingNextTurnMessages.push(appMessage):this.isStreaming&&options?.triggerTurn!==!1?options?.deliverAs==="followUp"?this.agent.followUp(appMessage):this.agent.steer(appMessage):options?.triggerTurn?await this._runAgentPrompt(appMessage):this.isStreaming?this._pendingCustomMessages.push(appMessage):this._appendCustomMessage(appMessage)}_appendCustomMessage(appMessage){this.agent.state.messages.push(appMessage),this.sessionManager.appendCustomMessageEntry(appMessage.customType,appMessage.content,appMessage.display,appMessage.details),this._emit({type:"message_start",message:appMessage}),this._emit({type:"message_end",message:appMessage})}_flushPendingCustomMessages(){if(this._pendingCustomMessages.length===0)return;let pending=this._pendingCustomMessages;this._pendingCustomMessages=[];for(let appMessage of pending)this._appendCustomMessage(appMessage)}async sendUserMessage(content,options){let text,images;if(typeof content=="string")text=content;else{let textParts=[];images=[];for(let part of content)part.type==="text"?textParts.push(part.text):images.push(part);text=textParts.join(`
1055
- `),images.length===0&&(images=void 0)}await this.prompt(text,{expandPromptTemplates:options?.expandPromptTemplates??!1,streamingBehavior:options?.deliverAs,images,source:"extension"})}clearQueue(){let steering=[...this._steeringMessages],followUp=[...this._followUpMessages];return this._steeringMessages=[],this._followUpMessages=[],this.agent.clearAllQueues(),this._emitQueueUpdate(),{steering,followUp}}get pendingMessageCount(){return this._steeringMessages.length+this._followUpMessages.length}getSteeringMessages(){return this._steeringMessages}getFollowUpMessages(){return this._followUpMessages}get resourceLoader(){return this._resourceLoader}async abort(reason){this._pendingAbortReason=reason??"interrupted",this._lastAbortReason=this._pendingAbortReason,this._agentTaskScopeAbortController.abort(reason??"interrupted");try{await this._abortInternal(),this._appendTurnInterruptedMarker()}finally{this._pendingAbortReason=void 0,this._agentTaskScopeAbortController=new AbortController}}async _abortInternal(){this.abortRetry(),this._policyDecisionAbortController?.abort("session aborted"),this._commandAbortController?.abort("session aborted"),this.abortCompaction(),this.abortBranchSummary(),this.abortBash(),this.agent.abort(),await this.waitForIdle()}_appendTurnInterruptedMarker(){let messages=this.agent.state.messages,last=messages[messages.length-1];if(last?.role==="custom"&&last.customType==="turn-interrupted")return;let lastAssistantAborted=!1;for(let i=messages.length-1;i>=0;i--){let message=messages[i];if(message.role==="assistant"){lastAssistantAborted=message.stopReason==="aborted";break}}lastAssistantAborted&&this._appendCustomMessage({role:"custom",customType:"turn-interrupted",content:"The previous turn was interrupted by the user before it completed.",display:!1,details:this._pendingAbortReason===void 0?void 0:{reason:this._pendingAbortReason},timestamp:Date.now()})}async _abortActiveCapabilityCommand(reason){this._commandAbortController?.abort(reason),await this._activeCapabilityCommand}async _cancelAndDrainForReload(){this.abortRetry(),this._policyDecisionAbortController?.abort("session reloaded"),this._commandAbortController?.abort("session reloaded"),this.abortCompaction(),this.abortBranchSummary(),this.abortBash(),this.agent.abort(),await Promise.allSettled([this._activeCapabilityCommand,this._activeCompactionPromise,this._branchSummaryPromise,this._activeContextTransition,...this._activeBashPromises,this.waitForIdle()].filter(operation=>operation!==void 0)),await this._compactionQueue.catch(()=>{})}async waitForIdle(){this.isIdle||await this._getIdleWaitPromise()}async _emitModelSelect(nextModel,previousModel,source){return emitModelSelect(this._internal,nextModel,previousModel,source)}async setModel(model,options={}){return setModel(this._internal,model,options)}_addPersistedDefaultToNonEmptyScope(model){addPersistedDefaultToNonEmptyScope(this._internal,model)}async cycleModel(direction="forward",options={}){return cycleModel(this._internal,direction,options)}async _cycleScopedModel(direction,options){return cycleScopedModel(this._internal,direction,options)}async _cycleAvailableModel(direction,options){return cycleAvailableModel(this._internal,direction,options)}setThinkingLevel(level,options={}){let availableLevels=this.getAvailableThinkingLevels(),effectiveLevel=availableLevels.includes(level)?level:this._clampThinkingLevel(level,availableLevels),previousLevel=this.agent.state.thinkingLevel,isChanging=effectiveLevel!==previousLevel;this.agent.state.thinkingLevel=effectiveLevel,options.persist&&this.settingsManager.setDefaultThinkingLevel(level),isChanging&&(this.sessionManager.appendThinkingLevelChange(effectiveLevel),this._emit({type:"thinking_level_changed",level:effectiveLevel}),dispatchThinkingLevelSelectLifecycle(this._internal,effectiveLevel,previousLevel))}cycleThinkingLevel(options={}){if(!this.supportsThinking())return;let levels=this.getAvailableThinkingLevels(),nextIndex=(levels.indexOf(this.thinkingLevel)+1)%levels.length,nextLevel=levels[nextIndex];return this.setThinkingLevel(nextLevel,options),nextLevel}getAvailableThinkingLevels(){return this.model?getSupportedThinkingLevels(this.model):[...THINKING_LEVEL_OPTIONS]}supportsThinking(){return!!this.model?.reasoning}_getThinkingLevelForModelSwitch(targetModel,explicitLevel){return getThinkingLevelForModelSwitch(this._internal,targetModel,explicitLevel)}_clampThinkingLevel(level,_availableLevels){return this.model?clampThinkingLevel(this.model,level):"off"}syncQueueModesFromSettings(){this.agent.steeringMode=this.settingsManager.getSteeringMode(),this.agent.followUpMode=this.settingsManager.getFollowUpMode()}setSteeringMode(mode){this.agent.steeringMode=mode,this.settingsManager.setSteeringMode(mode)}setFollowUpMode(mode){this.agent.followUpMode=mode,this.settingsManager.setFollowUpMode(mode)}_enqueueCompaction(operation){return enqueueCompaction(this._internal,operation)}_observeLifecycleDeliveryError(error2,extensionPath,event){observeLifecycleDeliveryError(this._internal,error2,extensionPath,event)}async compact(customInstructions){if(this._reloadInProgress)throw new Error("Session reload in progress; compaction is unavailable");return this._enqueueCompaction(()=>this._compactInternal(customInstructions))}_compactInternal(customInstructions){return compactInternal(this._internal,customInstructions)}abortCompaction(){this._compactionAbortController?.abort(),this._autoCompactionAbortController?.abort()}abortBranchSummary(){this._branchSummaryAbortController?.abort()}_checkCompaction(assistantMessage,skipAbortedCheck=!0,signal){return checkCompaction(this._internal,assistantMessage,skipAbortedCheck,signal)}_runAutoCompaction(reason,willRetry){return runAutoCompaction(this._internal,reason,willRetry)}setAutoCompactionEnabled(enabled){this.settingsManager.setCompactionEnabled(enabled)}get autoCompactionEnabled(){return this.settingsManager.getCompactionEnabled()}async startSession(){await dispatchSessionStartLifecycle(this._internal,this._sessionStartEvent.reason,this._sessionStartEvent.previousSessionFile),await this.extendResourcesFromExtensions(this._sessionStartEvent.reason==="reload"?"reload":"startup")}async extendResourcesFromExtensions(reason){return extendResourcesFromExtensions(this._internal,reason)}buildExtensionResourcePaths(entries){return buildExtensionResourcePaths(this._internal,entries)}getExtensionSourceLabel(extensionPath){return getExtensionSourceLabel(extensionPath)}_refreshToolRegistry(options){refreshToolRegistry(this._internal,options)}_syncCapabilityTools(){syncCapabilityTools(this._internal)}_getCapabilitySkills(){return getCapabilitySkills(this._internal)}_getAvailableSkills(){let capabilitySkills=this._getCapabilitySkills();return capabilitySkills.length>0?capabilitySkills:this._resourceLoader.getSkills().skills}_validateCapabilitySkillConflicts(){validateCapabilitySkillConflicts(this._internal)}_refreshBootstrapSkills(){return refreshBootstrapSkills(this._internal)}async _disposeCapabilityPlugins(){let handles=Array.from(this._capabilityPlugins.values());this._isDisposingCapabilityPlugins=!0;let errors=[];try{for(let handle of handles)try{await handle.dispose()}catch(error2){errors.push(error2)}}finally{this._isDisposingCapabilityPlugins=!1}if(errors.length===1)throw errors[0];if(errors.length>1)throw new AggregateError(errors,"Capability plugin disposal failed")}_forwardLogRecordToHost(record){let hostLogger=this._hostLogger;if(!hostLogger)return;let context={...record.sessionId===void 0?{}:{sessionId:record.sessionId},...record.fields===void 0?{}:{fields:record.fields},...record.cause===void 0?{}:{cause:record.cause}};switch(record.level){case"debug":hostLogger.debug(record.pluginId,record.message,context);break;case"info":hostLogger.info(record.pluginId,record.message,context);break;case"warn":hostLogger.warn(record.pluginId,record.message,context);break;case"error":hostLogger.error(record.pluginId,record.message,context);break}}_buildRuntime(options){this._agentTaskScopeAbortController=new AbortController;let autoResizeImages=this.settingsManager.getImageAutoResize(),shellCommandPrefix=this.settingsManager.getShellCommandPrefix(),shellPath=this.settingsManager.getShellPath();this._capabilityRuntime=createCapabilityRuntime({apiVersion:EXPERIMENTAL_PUBLIC_API_VERSION,mode:this._capabilityMode,...this._agentDir===void 0?{}:{agentDir:this._agentDir},...this._communication===void 0?{}:{communication:this._communication},...this._turnContext===void 0?{}:{turnContext:this._turnContext},...this._roleAssociations===void 0?{}:{roleAssociations:this._roleAssociations},...this._memoryStorage===void 0?{}:{memoryStorage:this._memoryStorage},workspaceDirectory:this._cwd,features:["tools","skills","logger-v1","diagnostics-v1","plugin-state-v1","runtime-inspector-v1","retry-policy","compaction-policy","overflow-policy","events","operations","rpc","context","provider-headers","credentials","commands","session","session-revision-v1","session-export","output-artifacts",...this._agentTaskAdapter||this._agentSessionReader||this._agentSessionLister?["agents"]:[],...this._agentTaskResults?["agent-result-replay-v1"]:[],...this._agentComposition?["agent-composition-v1"]:[],...this._interactionHost?["interaction"]:[]],transports:["in-process"]},{...this._agentTaskAdapter?{agents:this._agentTaskAdapter}:{},...this._agentTaskResults?{agentResults:this._agentTaskResults}:{},...this._agentSessionReader?{agentSessionReader:this._agentSessionReader}:{},...this._agentSessionLister?{agentSessionLister:this._agentSessionLister}:{},...this._agentComposition?{composition:this._agentComposition}:{},...this._interactionHost?{interaction:this._interactionHost}:{},parentSignal:()=>this._agentTaskScopeAbortController.signal,...this._traceService===void 0?{}:{trace:this._traceService},...this._modelRuntime?{modelRuntime:{getModelFacts:()=>{let model=this.agent.state.model;if(model)return{provider:model.provider,id:model.id,contextWindow:model.contextWindow??0,maxTokens:model.maxTokens??0,reasoning:model.reasoning??!1}},invoke:async(input,options2)=>{let model=this.agent.state.model;if(!model)throw new Error("No model is set on this session's agent");let authResult=await this._modelRuntime.getAuth(model,{...options2?.signal===void 0?{}:{signal:options2.signal}}),requestModel=authResult?.auth.baseUrl?{...model,baseUrl:authResult.auth.baseUrl}:model,context={...input.systemPrompt===void 0?{}:{systemPrompt:input.systemPrompt},messages:[{role:"user",content:[{type:"text",text:input.prompt}],timestamp:Date.now()}]},requestOptions={...input.maxTokens===void 0?{}:{maxTokens:input.maxTokens},...input.thinkingLevel&&input.thinkingLevel!=="off"&&model.reasoning?{reasoning:input.thinkingLevel}:{},...authResult?.auth.apiKey===void 0?{}:{apiKey:authResult.auth.apiKey},...authResult?.auth.headers===void 0?{}:{headers:authResult.auth.headers},...authResult?.env===void 0?{}:{env:authResult.env},...options2?.signal===void 0?{}:{signal:options2.signal}},response2=await(await this.agent.streamFunction(requestModel,context,requestOptions)).result();return response2.stopReason==="aborted"?{version:1,status:"aborted"}:response2.stopReason==="error"?{version:1,status:"failed",error:{code:"summary_provider_error",message:response2.errorMessage??"Unknown error"}}:response2.stopReason==="length"?{version:1,status:"failed",error:{code:"summary_length_cap",message:"generation hit the token cap"}}:{version:1,status:"completed",text:response2.content.filter(block=>block.type==="text").map(block=>block.text).join(""),usage:response2.usage}}}}:{},onOutputArtifactCommit:this._dispatchOutputArtifactCommit,onToolRegistryChange:()=>{this._suspendToolRegistryHookRefresh||!this._toolRegistryHookReady||(this._syncCapabilityTools(),this._refreshToolRegistry({activeToolNames:this.getActiveToolNames()}))},toolExecutionContext:{cwd:this._cwd},...this._hostLogger===void 0&&this._logRecordMirrorRef===void 0?{}:{onLogRecord:record=>{this._logRecordMirrorRef?.current?.(record),this._forwardLogRecordToHost(record)}},credentials:{resolve:async({providerId,minValidityMs,signal})=>{let result=await this._modelRuntime.getAuth(providerId,{signal,...minValidityMs===void 0?{}:{minOAuthValidityMs:minValidityMs}});if(result)return{...result.auth.apiKey===void 0?{}:{apiKey:result.auth.apiKey},headers:{...result.auth.headers??{}},...result.auth.baseUrl===void 0?{}:{baseUrl:result.auth.baseUrl},...result.source===void 0?{}:{source:result.source}}}},session:this.getSessionAPI()});let disabledBootstrap=this._disabledBootstrapPlugins,capabilityRuntime=this._capabilityRuntime,installBootstrap=(pluginId,install2)=>{if(!disabledBootstrap?.includes(pluginId))try{install2()}catch(error2){this._hostLogger?.error("session","bootstrap plugin load failed",{fields:{pluginId},cause:error2}),capabilityRuntime.recordPluginRejection(Object.freeze({code:"plugin_load_failed",manifestPath:"<embedded>",pluginId,message:error2 instanceof Error?error2.message:String(error2)})).catch(()=>{})}};installBootstrap(BOOTSTRAP_LIFECYCLE_PLUGIN_ID,()=>installBootstrapLifecycle(capabilityRuntime)),installBootstrap(BOOTSTRAP_AGENT_LOOP_PLUGIN_ID,()=>installBootstrapAgentLoop(capabilityRuntime,this._createLoopWiring())),installBootstrap(BOOTSTRAP_TOOLS_PLUGIN_ID,()=>installSessionBootstrapTools(capabilityRuntime,this._cwd,{read:{autoResizeImages},bash:{commandPrefix:shellCommandPrefix,shellPath},mode:this._capabilityMode},this._baseToolsOverride)),this._syncCapabilityTools(),installBootstrap(BOOTSTRAP_SKILLS_PLUGIN_ID,()=>(this._bootstrapSkillsHandle=installSessionBootstrapSkills(capabilityRuntime,this._resourceLoader.getSkills().skills),this._bootstrapSkillsHandle)),installBootstrap(BOOTSTRAP_RETRY_PLUGIN_ID,()=>installBootstrapRetryPolicy(capabilityRuntime)),installBootstrap(BOOTSTRAP_OVERFLOW_PLUGIN_ID,()=>installBootstrapOverflowPolicy(capabilityRuntime)),installBootstrap(BOOTSTRAP_COMPACTION_PLUGIN_ID,()=>installBootstrapCompactionPolicy(capabilityRuntime)),installBootstrap(BOOTSTRAP_BRANCH_SUMMARY_PLUGIN_ID,()=>installBootstrapBranchSummaryPolicy(capabilityRuntime)),this._syncCapabilityTools();let builtinToolNames=this._capabilityRuntime.listTools().filter(tool=>this._capabilityMode!=="readonly"||!tool.source.startsWith("agent-forge.builtin.")||tool.readonlySafe===!0).filter(tool=>this._capabilityMode!=="readonly"||!tool.source.startsWith("agent-forge.plugin.")||tool.readonlySafe===!0).map(tool=>tool.name),defaultActiveToolNames=this._baseToolsOverride?Object.keys(this._baseToolsOverride):this._capabilityMode==="readonly"?this._capabilityRuntime.listTools().filter(tool=>tool.readonlySafe).map(tool=>tool.name):["read","bash","edit","write"],baseActiveToolNames=[...options.activeToolNames??defaultActiveToolNames,...builtinToolNames];this._refreshToolRegistry({activeToolNames:baseActiveToolNames,includeAllExtensionTools:options.includeAllExtensionTools}),this._toolRegistryHookReady=!0}async reload(options){if(this._reloadInProgress)throw new Error("Session reload is already in progress");this._reloadInProgress=!0,this._beginContextTransitionFence(),this._bashEpoch+=1;let committedGeneration;try{await this._cancelAndDrainForReload();let oldCapabilityRuntime=this._capabilityRuntime,contextStrategyName=this._contextStrategyName,contextSnapshot,hasContextSnapshot=!1;if(contextStrategyName){if(!oldCapabilityRuntime?.hasContextStrategy(contextStrategyName))throw new Error(`Configured context strategy is not registered: ${contextStrategyName}`);contextSnapshot=await oldCapabilityRuntime.snapshotContext(contextStrategyName,this._copyContextMessages(this.agent.state.messages,contextStrategyName,"input"),{reason:"reload",sessionId:this.sessionId}),hasContextSnapshot=!0}let capabilityPluginPaths=Array.from(this._capabilityPlugins.keys()).filter(key=>!this._inlineCapabilityPlugins.has(key)),inlineCapabilityPlugins=Array.from(this._inlineCapabilityPlugins.values());await this._disposeCapabilityPlugins(),oldCapabilityRuntime?.revokeAllAPIs(),await oldCapabilityRuntime?.disposeAll(),await this._agentTaskAdapter?.dispose?.(),await this._interactionHost?.dispose?.(),await this._bootstrapToolsHandle?.dispose(),this._bootstrapToolsHandle=void 0,await this._bootstrapSkillsHandle?.dispose(),this._bootstrapSkillsHandle=void 0,await this._bootstrapRetryHandle?.dispose(),this._bootstrapRetryHandle=void 0,await this._bootstrapOverflowHandle?.dispose(),this._bootstrapOverflowHandle=void 0,await this._bootstrapCompactionHandle?.dispose(),this._bootstrapCompactionHandle=void 0,await this._bootstrapBranchSummaryHandle?.dispose(),this._bootstrapBranchSummaryHandle=void 0,await this._bootstrapAgentLoopHandle?.dispose(),this._bootstrapAgentLoopHandle=void 0,await this._bootstrapLifecycleHandle?.dispose(),this._bootstrapLifecycleHandle=void 0,await this.settingsManager.reload(),this.syncQueueModesFromSettings(),await this._resourceLoader.reload(),this._buildRuntime({activeToolNames:this.getActiveToolNames(),includeAllExtensionTools:!0});for(let manifestPath of capabilityPluginPaths)await this.loadCapabilityPluginManifest(manifestPath);for(let{manifest,factory}of inlineCapabilityPlugins)await this.loadCapabilityPlugin(manifest,factory);if(contextStrategyName&&hasContextSnapshot){if(!this._capabilityRuntime?.hasContextStrategy(contextStrategyName))throw new Error(`Configured context strategy is not registered after reload: ${contextStrategyName}`);await this._restoreContextTransition(contextSnapshot,"reload",{allowReload:!0})}await options?.beforeSessionStart?.(),await dispatchSessionStartLifecycle(this._internal,"reload"),await this.extendResourcesFromExtensions("reload"),committedGeneration=this._reloadGeneration+1,this._reloadGeneration=committedGeneration}finally{this._reloadInProgress=!1}if(committedGeneration===void 0)throw new Error("Session reload did not commit a generation");await this._dispatchSessionReloadLifecycle(committedGeneration)}_isRetryableError(message,execution,signal){return isRetryableError(this._internal,message,execution,signal)}_prepareRetry(message,precomputedDecision){return prepareRetry(this._internal,message,precomputedDecision)}abortRetry(){this._retryAbortController?.abort()}get isRetrying(){return this._retryAbortController!==void 0}get autoRetryEnabled(){return this.settingsManager.getRetryEnabled()}setAutoRetryEnabled(enabled){this.settingsManager.setRetryEnabled(enabled)}captureBashEpoch(){return captureBashEpoch(this._internal)}isBashEpochCurrent(epoch){return isBashEpochCurrent(this._internal,epoch)}emitUserBash(excludeFromContext){emitUserBash(this._internal,excludeFromContext)}async executeBash(command,onChunk,options){return executeBash(this._internal,command,onChunk,options)}recordBashResult(command,result,options){recordBashResult(this._internal,command,result,options)}abortBash(){abortBash(this._internal)}get isBashRunning(){return this._bashAbortControllers.size>0}get hasPendingBashMessages(){return this._pendingBashMessages.length>0}_flushPendingBashMessages(){flushPendingBashMessages(this._internal)}setSessionName(name){this.sessionManager.appendSessionInfo(name);let event={type:"session_info_changed",name:this.sessionManager.getSessionName()};this._emit(event),dispatchSessionInfoChangedLifecycle(this._internal,event.name)}recordSuiteMismatch(originalSuiteId,currentSuiteId){this.sessionManager.appendCustomEntry(SUITE_MISMATCH_SESSION_ENTRY_TYPE,{originalSuiteId,currentSuiteId})}async navigateTree(targetId,options={}){return navigateTree(this._internal,targetId,options)}getUserMessagesForForking(){return getUserMessagesForForking(this._internal)}getSessionStats(){return getSessionStats(this._internal)}getContextUsage(){return getContextUsage(this._internal)}async exportToHtml(outputPath,options={}){return await exportToHtml(this._internal,outputPath,options)}exportToJsonl(outputPath){return exportToJsonl(this._internal,outputPath)}getLastAssistantText(){return getLastAssistantText(this._internal)}createReplacedSessionContext(){return{sendMessage:(message,options)=>this.sendCustomMessage(message,options),sendUserMessage:(content,options)=>this.sendUserMessage(content,options)}}get host(){let agent=this.agent,sessionManager=this.sessionManager;return{get abortSignal(){return agent.signal},get cwd(){return sessionManager.getCwd()},get sessionName(){return sessionManager.getSessionName()},get entries(){return sessionManager.getEntries()},setTransport:transport=>{agent.transport=transport},abortAgent:()=>{agent.abort()}}}};var import_semver4=__toESM(require_semver2(),1);import{existsSync as existsSync16,mkdirSync as mkdirSync11,rmSync as rmSync4,statSync as statSync13,writeFileSync as writeFileSync10}from"node:fs";import{dirname as dirname23,join as join42}from"node:path";var stdoutTakeoverState;var rawStdoutWriteTail=Promise.resolve();function getRawStdoutWrite(){return stdoutTakeoverState?stdoutTakeoverState.rawStdoutWrite:process.stdout.write.bind(process.stdout)}async function writeRawStdoutChunk(text){for(;;)try{await new Promise((resolve25,reject2)=>{try{getRawStdoutWrite()(text,error2=>{error2?reject2(error2):resolve25()})}catch(error2){reject2(error2 instanceof Error?error2:new Error(String(error2)))}});return}catch(error2){let writeError=error2 instanceof Error?error2:new Error(String(error2)),code=writeError.code;if(code!=="ENOBUFS"&&code!=="EAGAIN"&&code!=="EWOULDBLOCK")throw writeError;await new Promise(resolve25=>setTimeout(resolve25,10))}}function takeOverStdout(){if(stdoutTakeoverState)return;let rawStdoutWrite=process.stdout.write.bind(process.stdout),rawStderrWrite=process.stderr.write.bind(process.stderr),originalStdoutWrite=process.stdout.write;process.stdout.write=((chunk,encodingOrCallback,callback)=>typeof encodingOrCallback=="function"?rawStderrWrite(String(chunk),encodingOrCallback):rawStderrWrite(String(chunk),callback)),stdoutTakeoverState={rawStdoutWrite,rawStderrWrite,originalStdoutWrite}}function restoreStdout(){stdoutTakeoverState&&(process.stdout.write=stdoutTakeoverState.originalStdoutWrite,stdoutTakeoverState=void 0)}function isStdoutTakenOver(){return stdoutTakeoverState!==void 0}function writeRawStdout(text){text.length!==0&&(rawStdoutWriteTail=rawStdoutWriteTail.then(()=>writeRawStdoutChunk(text)),rawStdoutWriteTail.catch(()=>{process.exit(1)}))}async function waitForRawStdoutBackpressure(){for(;;){let tail=rawStdoutWriteTail;if(await tail,tail===rawStdoutWriteTail)return}}async function flushRawStdout(){await waitForRawStdoutBackpressure(),await writeRawStdoutChunk("")}var import_semver2=__toESM(require_semver2(),1);import{createHash as createHash8}from"node:crypto";import{chmodSync as chmodSync2,existsSync as existsSync13,mkdirSync as mkdirSync10,readdirSync as readdirSync11,readFileSync as readFileSync12,rmSync as rmSync3,writeFileSync as writeFileSync9}from"node:fs";import{basename as basename10,dirname as dirname20,join as join38,resolve as resolve12,sep as sep8}from"node:path";function getPackageTempFolder(agentDir){let tempFolder=join38(agentDir,"tmp","packages");return mkdirSync10(tempFolder,{recursive:!0,mode:448}),chmodSync2(tempFolder,448),tempFolder}function getNpmCommand(ctx){let configuredCommand=ctx.settingsManager.getNpmCommand();if(!configuredCommand||configuredCommand.length===0)return{command:"npm",args:[]};let[command,...args]=configuredCommand;if(!command)throw new Error("Invalid npmCommand: first array entry must be a non-empty command");return{command,args}}function getPackageManagerName(ctx){let npmCommand=getNpmCommand(ctx),commandParts=[npmCommand.command,...npmCommand.args],separatorIndex=commandParts.lastIndexOf("--"),packageManagerCommand=separatorIndex>=0?commandParts[separatorIndex+1]:npmCommand.command;return packageManagerCommand?basename10(packageManagerCommand).replace(/\.(cmd|exe)$/i,""):""}function getGitDependencyInstallArgs(ctx){let configuredCommand=ctx.settingsManager.getNpmCommand();return configuredCommand&&configuredCommand.length>0?["install"]:["install","--omit=dev"]}function getNpmInstallArgs(ctx,specs,installRoot){let packageManagerName=getPackageManagerName(ctx);return packageManagerName==="bun"?["install",...specs,"--cwd",installRoot,"--omit=peer"]:packageManagerName==="pnpm"?["install",...specs,"--prefix",installRoot,"--config.auto-install-peers=false","--config.strict-peer-dependencies=false","--config.strict-dep-builds=false"]:["install",...specs,"--prefix",installRoot,"--legacy-peer-deps"]}function getNpmInstallRoot(ctx,scope,temporary){return temporary?getTemporaryDir(ctx,"npm"):scope==="project"?join38(ctx.cwd,CONFIG_DIR_NAME,"npm"):join38(ctx.agentDir,"npm")}function getGitInstallRoot(ctx,scope){if(scope!=="temporary")return scope==="project"?join38(ctx.cwd,CONFIG_DIR_NAME,"git"):join38(ctx.agentDir,"git")}function getManagedNpmInstallPath(ctx,source,scope){return scope==="temporary"?join38(getTemporaryDir(ctx,"npm"),"node_modules",source.name):scope==="project"?join38(ctx.cwd,CONFIG_DIR_NAME,"npm","node_modules",source.name):join38(ctx.agentDir,"npm","node_modules",source.name)}function getGitInstallPath(ctx,source,scope){if(scope==="temporary")return getTemporaryDir(ctx,`git-${source.host}`,source.path);let installRoot=getGitInstallRoot(ctx,scope);if(!installRoot)throw new Error("Missing git install root");return resolveManagedPath(installRoot,source.host,source.path)}function getTemporaryDir(ctx,prefix,suffix){let root=resolveManagedPath(getPackageTempFolder(ctx.agentDir),prefix),hash=createHash8("sha256").update(`${prefix}-${suffix??""}`).digest("hex").slice(0,8);return resolveManagedPath(root,hash,suffix??"")}function resolveManagedPath(root,...parts){let resolvedRoot=resolve12(root),resolvedPath=resolve12(resolvedRoot,...parts);if(resolvedPath!==resolvedRoot&&!resolvedPath.startsWith(`${resolvedRoot}${sep8}`))throw new Error(`Refusing to use path outside package install root: ${resolvedPath}`);return resolvedPath}function ensureNpmProject(installRoot){existsSync13(installRoot)||mkdirSync10(installRoot,{recursive:!0}),markPathIgnoredByCloudSync(installRoot),ensureGitIgnore(installRoot);let packageJsonPath=join38(installRoot,"package.json");existsSync13(packageJsonPath)||writeFileSync9(packageJsonPath,JSON.stringify({name:"agent-forge-extensions",private:!0},null,2),"utf-8")}function ensureGitIgnore(dir){existsSync13(dir)||mkdirSync10(dir,{recursive:!0});let ignorePath=join38(dir,".gitignore");existsSync13(ignorePath)||writeFileSync9(ignorePath,`*
1055
+ `),images.length===0&&(images=void 0)}await this.prompt(text,{expandPromptTemplates:options?.expandPromptTemplates??!1,streamingBehavior:options?.deliverAs,images,source:"extension"})}clearQueue(){let steering=[...this._steeringMessages],followUp=[...this._followUpMessages];return this._steeringMessages=[],this._followUpMessages=[],this.agent.clearAllQueues(),this._emitQueueUpdate(),{steering,followUp}}get pendingMessageCount(){return this._steeringMessages.length+this._followUpMessages.length}getSteeringMessages(){return this._steeringMessages}getFollowUpMessages(){return this._followUpMessages}get resourceLoader(){return this._resourceLoader}async abort(reason){this._pendingAbortReason=reason??"interrupted",this._lastAbortReason=this._pendingAbortReason,this._agentTaskScopeAbortController.abort(reason??"interrupted");try{await this._abortInternal(),this._appendTurnInterruptedMarker()}finally{this._pendingAbortReason=void 0,this._agentTaskScopeAbortController=new AbortController}}async _abortInternal(){this.abortRetry(),this._policyDecisionAbortController?.abort("session aborted"),this._commandAbortController?.abort("session aborted"),this.abortCompaction(),this.abortBranchSummary(),this.abortBash(),this.agent.abort(),await this.waitForIdle()}_appendTurnInterruptedMarker(){let messages=this.agent.state.messages,last=messages[messages.length-1];if(last?.role==="custom"&&last.customType==="turn-interrupted")return;let lastAssistantAborted=!1;for(let i=messages.length-1;i>=0;i--){let message=messages[i];if(message.role==="assistant"){lastAssistantAborted=message.stopReason==="aborted";break}}lastAssistantAborted&&this._appendCustomMessage({role:"custom",customType:"turn-interrupted",content:"The previous turn was interrupted by the user before it completed.",display:!1,details:this._pendingAbortReason===void 0?void 0:{reason:this._pendingAbortReason},timestamp:Date.now()})}async _abortActiveCapabilityCommand(reason){this._commandAbortController?.abort(reason),await this._activeCapabilityCommand}async _cancelAndDrainForReload(){this.abortRetry(),this._policyDecisionAbortController?.abort("session reloaded"),this._commandAbortController?.abort("session reloaded"),this.abortCompaction(),this.abortBranchSummary(),this.abortBash(),this.agent.abort(),await Promise.allSettled([this._activeCapabilityCommand,this._activeCompactionPromise,this._branchSummaryPromise,this._activeContextTransition,...this._activeBashPromises,this.waitForIdle()].filter(operation=>operation!==void 0)),await this._compactionQueue.catch(()=>{})}async waitForIdle(){this.isIdle||await this._getIdleWaitPromise()}async _emitModelSelect(nextModel,previousModel,source){return emitModelSelect(this._internal,nextModel,previousModel,source)}async setModel(model,options={}){return setModel(this._internal,model,options)}_addPersistedDefaultToNonEmptyScope(model){addPersistedDefaultToNonEmptyScope(this._internal,model)}async cycleModel(direction="forward",options={}){return cycleModel(this._internal,direction,options)}async _cycleScopedModel(direction,options){return cycleScopedModel(this._internal,direction,options)}async _cycleAvailableModel(direction,options){return cycleAvailableModel(this._internal,direction,options)}setThinkingLevel(level,options={}){let availableLevels=this.getAvailableThinkingLevels(),effectiveLevel=availableLevels.includes(level)?level:this._clampThinkingLevel(level,availableLevels),previousLevel=this.agent.state.thinkingLevel,isChanging=effectiveLevel!==previousLevel;this.agent.state.thinkingLevel=effectiveLevel,options.persist&&this.settingsManager.setDefaultThinkingLevel(level),isChanging&&(this.sessionManager.appendThinkingLevelChange(effectiveLevel),this._emit({type:"thinking_level_changed",level:effectiveLevel}),dispatchThinkingLevelSelectLifecycle(this._internal,effectiveLevel,previousLevel))}cycleThinkingLevel(options={}){if(!this.supportsThinking())return;let levels=this.getAvailableThinkingLevels(),nextIndex=(levels.indexOf(this.thinkingLevel)+1)%levels.length,nextLevel=levels[nextIndex];return this.setThinkingLevel(nextLevel,options),nextLevel}getAvailableThinkingLevels(){return this.model?getSupportedThinkingLevels(this.model):[...THINKING_LEVEL_OPTIONS]}supportsThinking(){return!!this.model?.reasoning}_getThinkingLevelForModelSwitch(targetModel,explicitLevel){return getThinkingLevelForModelSwitch(this._internal,targetModel,explicitLevel)}_clampThinkingLevel(level,_availableLevels){return this.model?clampThinkingLevel(this.model,level):"off"}syncQueueModesFromSettings(){this.agent.steeringMode=this.settingsManager.getSteeringMode(),this.agent.followUpMode=this.settingsManager.getFollowUpMode()}setSteeringMode(mode){this.agent.steeringMode=mode,this.settingsManager.setSteeringMode(mode)}setFollowUpMode(mode){this.agent.followUpMode=mode,this.settingsManager.setFollowUpMode(mode)}_enqueueCompaction(operation){return enqueueCompaction(this._internal,operation)}_observeLifecycleDeliveryError(error2,extensionPath,event){observeLifecycleDeliveryError(this._internal,error2,extensionPath,event)}async compact(customInstructions){if(this._reloadInProgress)throw new Error("Session reload in progress; compaction is unavailable");return this._enqueueCompaction(()=>this._compactInternal(customInstructions))}_compactInternal(customInstructions){return compactInternal(this._internal,customInstructions)}abortCompaction(){this._compactionAbortController?.abort(),this._autoCompactionAbortController?.abort()}abortBranchSummary(){this._branchSummaryAbortController?.abort()}_checkCompaction(assistantMessage,skipAbortedCheck=!0,signal){return checkCompaction(this._internal,assistantMessage,skipAbortedCheck,signal)}_runAutoCompaction(reason,willRetry){return runAutoCompaction(this._internal,reason,willRetry)}setAutoCompactionEnabled(enabled){this.settingsManager.setCompactionEnabled(enabled)}get autoCompactionEnabled(){return this.settingsManager.getCompactionEnabled()}async startSession(){await dispatchSessionStartLifecycle(this._internal,this._sessionStartEvent.reason,this._sessionStartEvent.previousSessionFile),await this.extendResourcesFromExtensions(this._sessionStartEvent.reason==="reload"?"reload":"startup")}async extendResourcesFromExtensions(reason){return extendResourcesFromExtensions(this._internal,reason)}buildExtensionResourcePaths(entries){return buildExtensionResourcePaths(this._internal,entries)}getExtensionSourceLabel(extensionPath){return getExtensionSourceLabel(extensionPath)}_refreshToolRegistry(options){refreshToolRegistry(this._internal,options)}_syncCapabilityTools(){syncCapabilityTools(this._internal)}_getCapabilitySkills(){return getCapabilitySkills(this._internal)}_getAvailableSkills(){let capabilitySkills=this._getCapabilitySkills();return capabilitySkills.length>0?capabilitySkills:this._resourceLoader.getSkills().skills}_validateCapabilitySkillConflicts(){validateCapabilitySkillConflicts(this._internal)}_refreshBootstrapSkills(){return refreshBootstrapSkills(this._internal)}async _disposeCapabilityPlugins(){let handles=Array.from(this._capabilityPlugins.values());this._isDisposingCapabilityPlugins=!0;let errors=[];try{for(let handle of handles)try{await handle.dispose()}catch(error2){errors.push(error2)}}finally{this._isDisposingCapabilityPlugins=!1}if(errors.length===1)throw errors[0];if(errors.length>1)throw new AggregateError(errors,"Capability plugin disposal failed")}_forwardLogRecordToHost(record){let hostLogger=this._hostLogger;if(!hostLogger)return;let context={...record.sessionId===void 0?{}:{sessionId:record.sessionId},...record.fields===void 0?{}:{fields:record.fields},...record.cause===void 0?{}:{cause:record.cause}};switch(record.level){case"debug":hostLogger.debug(record.pluginId,record.message,context);break;case"info":hostLogger.info(record.pluginId,record.message,context);break;case"warn":hostLogger.warn(record.pluginId,record.message,context);break;case"error":hostLogger.error(record.pluginId,record.message,context);break}}_buildRuntime(options){this._agentTaskScopeAbortController=new AbortController;let autoResizeImages=this.settingsManager.getImageAutoResize(),shellCommandPrefix=this.settingsManager.getShellCommandPrefix(),shellPath=this.settingsManager.getShellPath();this._capabilityRuntime=createCapabilityRuntime({apiVersion:EXPERIMENTAL_PUBLIC_API_VERSION,mode:this._capabilityMode,...this._agentDir===void 0?{}:{agentDir:this._agentDir},...this._communication===void 0?{}:{communication:this._communication},...this._turnContext===void 0?{}:{turnContext:this._turnContext},...this._roleAssociations===void 0?{}:{roleAssociations:this._roleAssociations},...this._memoryStorage===void 0?{}:{memoryStorage:this._memoryStorage},workspaceDirectory:this._cwd,features:["tools","skills","logger-v1","diagnostics-v1","plugin-state-v1","runtime-inspector-v1","retry-policy","compaction-policy","overflow-policy","events","operations","rpc","context","provider-headers","credentials","commands","session","session-revision-v1","session-export","output-artifacts",...this._agentTaskAdapter||this._agentSessionReader||this._agentSessionLister?["agents"]:[],...this._agentTaskResults?["agent-result-replay-v1"]:[],...this._agentComposition?["agent-composition-v1"]:[],...this._interactionHost?["interaction"]:[]],transports:["in-process"]},{...this._agentTaskAdapter?{agents:this._agentTaskAdapter}:{},...this._agentTaskResults?{agentResults:this._agentTaskResults}:{},...this._agentSessionReader?{agentSessionReader:this._agentSessionReader}:{},...this._agentSessionLister?{agentSessionLister:this._agentSessionLister}:{},...this._agentComposition?{composition:this._agentComposition}:{},...this._interactionHost?{interaction:this._interactionHost}:{},parentSignal:()=>this._agentTaskScopeAbortController.signal,...this._traceService===void 0?{}:{trace:this._traceService},...this._modelRuntime?{modelRuntime:{getModelFacts:()=>{let model=this.agent.state.model;if(model)return{provider:model.provider,id:model.id,contextWindow:model.contextWindow??0,maxTokens:model.maxTokens??0,reasoning:model.reasoning??!1}},invoke:async(input,options2)=>{let model=this.agent.state.model;if(!model)throw new Error("No model is set on this session's agent");let authResult=await this._modelRuntime.getAuth(model,{...options2?.signal===void 0?{}:{signal:options2.signal}}),requestModel=authResult?.auth.baseUrl?{...model,baseUrl:authResult.auth.baseUrl}:model,context={...input.systemPrompt===void 0?{}:{systemPrompt:input.systemPrompt},messages:[{role:"user",content:[{type:"text",text:input.prompt}],timestamp:Date.now()}]},requestOptions={...input.maxTokens===void 0?{}:{maxTokens:input.maxTokens},...input.thinkingLevel&&input.thinkingLevel!=="off"&&model.reasoning?{reasoning:input.thinkingLevel}:{},...authResult?.auth.apiKey===void 0?{}:{apiKey:authResult.auth.apiKey},...authResult?.auth.headers===void 0?{}:{headers:authResult.auth.headers},...authResult?.env===void 0?{}:{env:authResult.env},...options2?.signal===void 0?{}:{signal:options2.signal}},response2=await(await this.agent.streamFunction(requestModel,context,requestOptions)).result();return response2.stopReason==="aborted"?{version:1,status:"aborted"}:response2.stopReason==="error"?{version:1,status:"failed",error:{code:"summary_provider_error",message:response2.errorMessage??"Unknown error"}}:response2.stopReason==="length"?{version:1,status:"failed",error:{code:"summary_length_cap",message:"generation hit the token cap"}}:{version:1,status:"completed",text:response2.content.filter(block=>block.type==="text").map(block=>block.text).join(""),usage:response2.usage}}}}:{},onOutputArtifactCommit:this._dispatchOutputArtifactCommit,onToolRegistryChange:()=>{this._suspendToolRegistryHookRefresh||!this._toolRegistryHookReady||(this._syncCapabilityTools(),this._refreshToolRegistry({activeToolNames:this.getActiveToolNames()}))},toolExecutionContext:{cwd:this._cwd},...this._hostLogger===void 0&&this._logRecordMirrorRef===void 0?{}:{onLogRecord:record=>{this._logRecordMirrorRef?.current?.(record),this._forwardLogRecordToHost(record)}},credentials:{resolve:async({providerId,minValidityMs,signal})=>{let result=await this._modelRuntime.getAuth(providerId,{signal,...minValidityMs===void 0?{}:{minOAuthValidityMs:minValidityMs}});if(!result)return;let providerBaseUrl=result.auth.baseUrl??this._modelRuntime.getProvider(providerId)?.baseUrl;return{...result.auth.apiKey===void 0?{}:{apiKey:result.auth.apiKey},headers:{...result.auth.headers??{}},...providerBaseUrl===void 0?{}:{baseUrl:providerBaseUrl},...result.source===void 0?{}:{source:result.source}}}},session:this.getSessionAPI()});let disabledBootstrap=this._disabledBootstrapPlugins,capabilityRuntime=this._capabilityRuntime,installBootstrap=(pluginId,install2)=>{if(!disabledBootstrap?.includes(pluginId))try{install2()}catch(error2){this._hostLogger?.error("session","bootstrap plugin load failed",{fields:{pluginId},cause:error2}),capabilityRuntime.recordPluginRejection(Object.freeze({code:"plugin_load_failed",manifestPath:"<embedded>",pluginId,message:error2 instanceof Error?error2.message:String(error2)})).catch(()=>{})}};installBootstrap(BOOTSTRAP_LIFECYCLE_PLUGIN_ID,()=>installBootstrapLifecycle(capabilityRuntime)),installBootstrap(BOOTSTRAP_AGENT_LOOP_PLUGIN_ID,()=>installBootstrapAgentLoop(capabilityRuntime,this._createLoopWiring())),installBootstrap(BOOTSTRAP_TOOLS_PLUGIN_ID,()=>installSessionBootstrapTools(capabilityRuntime,this._cwd,{read:{autoResizeImages},bash:{commandPrefix:shellCommandPrefix,shellPath},mode:this._capabilityMode},this._baseToolsOverride)),this._syncCapabilityTools(),installBootstrap(BOOTSTRAP_SKILLS_PLUGIN_ID,()=>(this._bootstrapSkillsHandle=installSessionBootstrapSkills(capabilityRuntime,this._resourceLoader.getSkills().skills),this._bootstrapSkillsHandle)),installBootstrap(BOOTSTRAP_RETRY_PLUGIN_ID,()=>installBootstrapRetryPolicy(capabilityRuntime)),installBootstrap(BOOTSTRAP_OVERFLOW_PLUGIN_ID,()=>installBootstrapOverflowPolicy(capabilityRuntime)),installBootstrap(BOOTSTRAP_COMPACTION_PLUGIN_ID,()=>installBootstrapCompactionPolicy(capabilityRuntime)),installBootstrap(BOOTSTRAP_BRANCH_SUMMARY_PLUGIN_ID,()=>installBootstrapBranchSummaryPolicy(capabilityRuntime)),this._syncCapabilityTools();let builtinToolNames=this._capabilityRuntime.listTools().filter(tool=>this._capabilityMode!=="readonly"||!tool.source.startsWith("agent-forge.builtin.")||tool.readonlySafe===!0).filter(tool=>this._capabilityMode!=="readonly"||!tool.source.startsWith("agent-forge.plugin.")||tool.readonlySafe===!0).map(tool=>tool.name),defaultActiveToolNames=this._baseToolsOverride?Object.keys(this._baseToolsOverride):this._capabilityMode==="readonly"?this._capabilityRuntime.listTools().filter(tool=>tool.readonlySafe).map(tool=>tool.name):["read","bash","edit","write"],baseActiveToolNames=[...options.activeToolNames??defaultActiveToolNames,...builtinToolNames];this._refreshToolRegistry({activeToolNames:baseActiveToolNames,includeAllExtensionTools:options.includeAllExtensionTools}),this._toolRegistryHookReady=!0}async reload(options){if(this._reloadInProgress)throw new Error("Session reload is already in progress");this._reloadInProgress=!0,this._beginContextTransitionFence(),this._bashEpoch+=1;let committedGeneration;try{await this._cancelAndDrainForReload();let oldCapabilityRuntime=this._capabilityRuntime,contextStrategyName=this._contextStrategyName,contextSnapshot,hasContextSnapshot=!1;if(contextStrategyName){if(!oldCapabilityRuntime?.hasContextStrategy(contextStrategyName))throw new Error(`Configured context strategy is not registered: ${contextStrategyName}`);contextSnapshot=await oldCapabilityRuntime.snapshotContext(contextStrategyName,this._copyContextMessages(this.agent.state.messages,contextStrategyName,"input"),{reason:"reload",sessionId:this.sessionId}),hasContextSnapshot=!0}let capabilityPluginPaths=Array.from(this._capabilityPlugins.keys()).filter(key=>!this._inlineCapabilityPlugins.has(key)),inlineCapabilityPlugins=Array.from(this._inlineCapabilityPlugins.values());await this._disposeCapabilityPlugins(),oldCapabilityRuntime?.revokeAllAPIs(),await oldCapabilityRuntime?.disposeAll(),await this._agentTaskAdapter?.dispose?.(),await this._interactionHost?.dispose?.(),await this._bootstrapToolsHandle?.dispose(),this._bootstrapToolsHandle=void 0,await this._bootstrapSkillsHandle?.dispose(),this._bootstrapSkillsHandle=void 0,await this._bootstrapRetryHandle?.dispose(),this._bootstrapRetryHandle=void 0,await this._bootstrapOverflowHandle?.dispose(),this._bootstrapOverflowHandle=void 0,await this._bootstrapCompactionHandle?.dispose(),this._bootstrapCompactionHandle=void 0,await this._bootstrapBranchSummaryHandle?.dispose(),this._bootstrapBranchSummaryHandle=void 0,await this._bootstrapAgentLoopHandle?.dispose(),this._bootstrapAgentLoopHandle=void 0,await this._bootstrapLifecycleHandle?.dispose(),this._bootstrapLifecycleHandle=void 0,await this.settingsManager.reload(),this.syncQueueModesFromSettings(),await this._resourceLoader.reload(),this._buildRuntime({activeToolNames:this.getActiveToolNames(),includeAllExtensionTools:!0});for(let manifestPath of capabilityPluginPaths)await this.loadCapabilityPluginManifest(manifestPath);for(let{manifest,factory}of inlineCapabilityPlugins)await this.loadCapabilityPlugin(manifest,factory);if(contextStrategyName&&hasContextSnapshot){if(!this._capabilityRuntime?.hasContextStrategy(contextStrategyName))throw new Error(`Configured context strategy is not registered after reload: ${contextStrategyName}`);await this._restoreContextTransition(contextSnapshot,"reload",{allowReload:!0})}await options?.beforeSessionStart?.(),await dispatchSessionStartLifecycle(this._internal,"reload"),await this.extendResourcesFromExtensions("reload"),committedGeneration=this._reloadGeneration+1,this._reloadGeneration=committedGeneration}finally{this._reloadInProgress=!1}if(committedGeneration===void 0)throw new Error("Session reload did not commit a generation");await this._dispatchSessionReloadLifecycle(committedGeneration)}_isRetryableError(message,execution,signal){return isRetryableError(this._internal,message,execution,signal)}_prepareRetry(message,precomputedDecision){return prepareRetry(this._internal,message,precomputedDecision)}abortRetry(){this._retryAbortController?.abort()}get isRetrying(){return this._retryAbortController!==void 0}get autoRetryEnabled(){return this.settingsManager.getRetryEnabled()}setAutoRetryEnabled(enabled){this.settingsManager.setRetryEnabled(enabled)}captureBashEpoch(){return captureBashEpoch(this._internal)}isBashEpochCurrent(epoch){return isBashEpochCurrent(this._internal,epoch)}emitUserBash(excludeFromContext){emitUserBash(this._internal,excludeFromContext)}async executeBash(command,onChunk,options){return executeBash(this._internal,command,onChunk,options)}recordBashResult(command,result,options){recordBashResult(this._internal,command,result,options)}abortBash(){abortBash(this._internal)}get isBashRunning(){return this._bashAbortControllers.size>0}get hasPendingBashMessages(){return this._pendingBashMessages.length>0}_flushPendingBashMessages(){flushPendingBashMessages(this._internal)}setSessionName(name){this.sessionManager.appendSessionInfo(name);let event={type:"session_info_changed",name:this.sessionManager.getSessionName()};this._emit(event),dispatchSessionInfoChangedLifecycle(this._internal,event.name)}recordSuiteMismatch(originalSuiteId,currentSuiteId){this.sessionManager.appendCustomEntry(SUITE_MISMATCH_SESSION_ENTRY_TYPE,{originalSuiteId,currentSuiteId})}async navigateTree(targetId,options={}){return navigateTree(this._internal,targetId,options)}getUserMessagesForForking(){return getUserMessagesForForking(this._internal)}getSessionStats(){return getSessionStats(this._internal)}getContextUsage(){return getContextUsage(this._internal)}async exportToHtml(outputPath,options={}){return await exportToHtml(this._internal,outputPath,options)}exportToJsonl(outputPath){return exportToJsonl(this._internal,outputPath)}getLastAssistantText(){return getLastAssistantText(this._internal)}createReplacedSessionContext(){return{sendMessage:(message,options)=>this.sendCustomMessage(message,options),sendUserMessage:(content,options)=>this.sendUserMessage(content,options)}}get host(){let agent=this.agent,sessionManager=this.sessionManager;return{get abortSignal(){return agent.signal},get cwd(){return sessionManager.getCwd()},get sessionName(){return sessionManager.getSessionName()},get entries(){return sessionManager.getEntries()},setTransport:transport=>{agent.transport=transport},abortAgent:()=>{agent.abort()}}}};var import_semver4=__toESM(require_semver2(),1);import{existsSync as existsSync16,mkdirSync as mkdirSync11,rmSync as rmSync4,statSync as statSync13,writeFileSync as writeFileSync10}from"node:fs";import{dirname as dirname23,join as join42}from"node:path";var stdoutTakeoverState;var rawStdoutWriteTail=Promise.resolve();function getRawStdoutWrite(){return stdoutTakeoverState?stdoutTakeoverState.rawStdoutWrite:process.stdout.write.bind(process.stdout)}async function writeRawStdoutChunk(text){for(;;)try{await new Promise((resolve25,reject2)=>{try{getRawStdoutWrite()(text,error2=>{error2?reject2(error2):resolve25()})}catch(error2){reject2(error2 instanceof Error?error2:new Error(String(error2)))}});return}catch(error2){let writeError=error2 instanceof Error?error2:new Error(String(error2)),code=writeError.code;if(code!=="ENOBUFS"&&code!=="EAGAIN"&&code!=="EWOULDBLOCK")throw writeError;await new Promise(resolve25=>setTimeout(resolve25,10))}}function takeOverStdout(){if(stdoutTakeoverState)return;let rawStdoutWrite=process.stdout.write.bind(process.stdout),rawStderrWrite=process.stderr.write.bind(process.stderr),originalStdoutWrite=process.stdout.write;process.stdout.write=((chunk,encodingOrCallback,callback)=>typeof encodingOrCallback=="function"?rawStderrWrite(String(chunk),encodingOrCallback):rawStderrWrite(String(chunk),callback)),stdoutTakeoverState={rawStdoutWrite,rawStderrWrite,originalStdoutWrite}}function restoreStdout(){stdoutTakeoverState&&(process.stdout.write=stdoutTakeoverState.originalStdoutWrite,stdoutTakeoverState=void 0)}function isStdoutTakenOver(){return stdoutTakeoverState!==void 0}function writeRawStdout(text){text.length!==0&&(rawStdoutWriteTail=rawStdoutWriteTail.then(()=>writeRawStdoutChunk(text)),rawStdoutWriteTail.catch(()=>{process.exit(1)}))}async function waitForRawStdoutBackpressure(){for(;;){let tail=rawStdoutWriteTail;if(await tail,tail===rawStdoutWriteTail)return}}async function flushRawStdout(){await waitForRawStdoutBackpressure(),await writeRawStdoutChunk("")}var import_semver2=__toESM(require_semver2(),1);import{createHash as createHash8}from"node:crypto";import{chmodSync as chmodSync2,existsSync as existsSync13,mkdirSync as mkdirSync10,readdirSync as readdirSync11,readFileSync as readFileSync12,rmSync as rmSync3,writeFileSync as writeFileSync9}from"node:fs";import{basename as basename10,dirname as dirname20,join as join38,resolve as resolve12,sep as sep8}from"node:path";function getPackageTempFolder(agentDir){let tempFolder=join38(agentDir,"tmp","packages");return mkdirSync10(tempFolder,{recursive:!0,mode:448}),chmodSync2(tempFolder,448),tempFolder}function getNpmCommand(ctx){let configuredCommand=ctx.settingsManager.getNpmCommand();if(!configuredCommand||configuredCommand.length===0)return{command:"npm",args:[]};let[command,...args]=configuredCommand;if(!command)throw new Error("Invalid npmCommand: first array entry must be a non-empty command");return{command,args}}function getPackageManagerName(ctx){let npmCommand=getNpmCommand(ctx),commandParts=[npmCommand.command,...npmCommand.args],separatorIndex=commandParts.lastIndexOf("--"),packageManagerCommand=separatorIndex>=0?commandParts[separatorIndex+1]:npmCommand.command;return packageManagerCommand?basename10(packageManagerCommand).replace(/\.(cmd|exe)$/i,""):""}function getGitDependencyInstallArgs(ctx){let configuredCommand=ctx.settingsManager.getNpmCommand();return configuredCommand&&configuredCommand.length>0?["install"]:["install","--omit=dev"]}function getNpmInstallArgs(ctx,specs,installRoot){let packageManagerName=getPackageManagerName(ctx);return packageManagerName==="bun"?["install",...specs,"--cwd",installRoot,"--omit=peer"]:packageManagerName==="pnpm"?["install",...specs,"--prefix",installRoot,"--config.auto-install-peers=false","--config.strict-peer-dependencies=false","--config.strict-dep-builds=false"]:["install",...specs,"--prefix",installRoot,"--legacy-peer-deps"]}function getNpmInstallRoot(ctx,scope,temporary){return temporary?getTemporaryDir(ctx,"npm"):scope==="project"?join38(ctx.cwd,CONFIG_DIR_NAME,"npm"):join38(ctx.agentDir,"npm")}function getGitInstallRoot(ctx,scope){if(scope!=="temporary")return scope==="project"?join38(ctx.cwd,CONFIG_DIR_NAME,"git"):join38(ctx.agentDir,"git")}function getManagedNpmInstallPath(ctx,source,scope){return scope==="temporary"?join38(getTemporaryDir(ctx,"npm"),"node_modules",source.name):scope==="project"?join38(ctx.cwd,CONFIG_DIR_NAME,"npm","node_modules",source.name):join38(ctx.agentDir,"npm","node_modules",source.name)}function getGitInstallPath(ctx,source,scope){if(scope==="temporary")return getTemporaryDir(ctx,`git-${source.host}`,source.path);let installRoot=getGitInstallRoot(ctx,scope);if(!installRoot)throw new Error("Missing git install root");return resolveManagedPath(installRoot,source.host,source.path)}function getTemporaryDir(ctx,prefix,suffix){let root=resolveManagedPath(getPackageTempFolder(ctx.agentDir),prefix),hash=createHash8("sha256").update(`${prefix}-${suffix??""}`).digest("hex").slice(0,8);return resolveManagedPath(root,hash,suffix??"")}function resolveManagedPath(root,...parts){let resolvedRoot=resolve12(root),resolvedPath=resolve12(resolvedRoot,...parts);if(resolvedPath!==resolvedRoot&&!resolvedPath.startsWith(`${resolvedRoot}${sep8}`))throw new Error(`Refusing to use path outside package install root: ${resolvedPath}`);return resolvedPath}function ensureNpmProject(installRoot){existsSync13(installRoot)||mkdirSync10(installRoot,{recursive:!0}),markPathIgnoredByCloudSync(installRoot),ensureGitIgnore(installRoot);let packageJsonPath=join38(installRoot,"package.json");existsSync13(packageJsonPath)||writeFileSync9(packageJsonPath,JSON.stringify({name:"agent-forge-extensions",private:!0},null,2),"utf-8")}function ensureGitIgnore(dir){existsSync13(dir)||mkdirSync10(dir,{recursive:!0});let ignorePath=join38(dir,".gitignore");existsSync13(ignorePath)||writeFileSync9(ignorePath,`*
1056
1056
  !.gitignore
1057
1057
  `,"utf-8")}function getInstalledNpmVersion(installedPath){let packageJsonPath=join38(installedPath,"package.json");if(existsSync13(packageJsonPath))try{let content=readFileSync12(packageJsonPath,"utf-8");return JSON.parse(stripBom(content)).version}catch{return}}function installedNpmMatchesConfiguredVersion(source,installedPath){let installedVersion=getInstalledNpmVersion(installedPath);return installedVersion?source.range?(0,import_semver2.satisfies)(installedVersion,source.range):!0:!1}function hasMissingGitDependencies(targetDir){let packageJsonPath=join38(targetDir,"package.json");if(!existsSync13(packageJsonPath))return!1;try{let manifest=JSON.parse(stripBom(readFileSync12(packageJsonPath,"utf-8")));if(!manifest.dependencies||typeof manifest.dependencies!="object"||Array.isArray(manifest.dependencies))return!1;let nodeModulesDir=resolve12(targetDir,"node_modules");return Object.keys(manifest.dependencies).some(name=>{let dependencyPath=resolve12(nodeModulesDir,name);return dependencyPath.startsWith(`${nodeModulesDir}${sep8}`)?!existsSync13(dependencyPath):!1})}catch{return!1}}function getGitUpdateMarkerPath(targetDir){return join38(dirname20(targetDir),`.${basename10(targetDir)}.agent-forge-update-incomplete`)}function pruneEmptyGitParents(targetDir,installRoot){if(!installRoot)return;let resolvedRoot=resolve12(installRoot),current=dirname20(targetDir);for(;current.startsWith(resolvedRoot)&&current!==resolvedRoot;){if(!existsSync13(current)){current=dirname20(current);continue}if(readdirSync11(current).length>0)break;try{rmSync3(current,{recursive:!0,force:!0})}catch{break}current=dirname20(current)}}import{readFileSync as readFileSync13}from"node:fs";function getEnv(){if(process.platform!=="linux"||Object.keys(process.env).length>0)return process.env;try{let data=readFileSync13("/proc/self/environ","utf-8"),env2={};for(let entry of data.split("\0")){let idx=entry.indexOf("=");idx>0&&(env2[entry.slice(0,idx)]=entry.slice(idx+1))}return env2}catch{return process.env}}function isOfflineModeEnabled2(){let value=process.env.AGENT_FORGE_OFFLINE;return value?value==="1"||value.toLowerCase()==="true"||value.toLowerCase()==="yes":!1}async function runWithConcurrency(tasks,limit){if(tasks.length===0)return[];let results=new Array(tasks.length),nextIndex=0,workerCount=Math.max(1,Math.min(limit,tasks.length)),worker=async()=>{for(;;){let index3=nextIndex;if(nextIndex+=1,index3>=tasks.length)return;results[index3]=await tasks[index3]()}};return await Promise.all(Array.from({length:workerCount},()=>worker())),results}import{existsSync as existsSync15,statSync as statSync12}from"node:fs";import{dirname as dirname22,join as join41,resolve as resolve14}from"node:path";var import_ignore3=__toESM(require_ignore(),1);import{existsSync as existsSync14,globSync,readdirSync as readdirSync12,readFileSync as readFileSync14,statSync as statSync11}from"node:fs";import{basename as basename11,dirname as dirname21,join as join39,relative as relative6,resolve as resolve13,sep as sep9}from"node:path";var RESOURCE_TYPES=["skills","prompts","themes"],FILE_PATTERNS={skills:/\.md$/,prompts:/\.md$/,themes:/\.json$/},IGNORE_FILE_NAMES2=[".gitignore",".ignore",".fdignore"];function toPosixPath3(p){return p.split(sep9).join("/")}function prefixIgnorePattern2(line,prefix){let trimmed=line.trim();if(!trimmed||trimmed.startsWith("#")&&!trimmed.startsWith("\\#"))return null;let pattern=line,negated=!1;pattern.startsWith("!")?(negated=!0,pattern=pattern.slice(1)):pattern.startsWith("\\!")&&(pattern=pattern.slice(1)),pattern.startsWith("/")&&(pattern=pattern.slice(1));let prefixed=prefix?`${prefix}${pattern}`:pattern;return negated?`!${prefixed}`:prefixed}function addIgnoreRules2(ig,dir,rootDir){let relativeDir=relative6(rootDir,dir),prefix=relativeDir?`${toPosixPath3(relativeDir)}/`:"";for(let filename of IGNORE_FILE_NAMES2){let ignorePath=join39(dir,filename);if(existsSync14(ignorePath))try{let patterns=readFileSync14(ignorePath,"utf-8").split(/\r?\n/).map(line=>prefixIgnorePattern2(line,prefix)).filter(line=>!!line);patterns.length>0&&ig.add(patterns)}catch{}}}function isPattern(s){return s.startsWith("!")||s.startsWith("+")||s.startsWith("-")||s.includes("*")||s.includes("?")}function isOverridePattern(s){return s.startsWith("!")||s.startsWith("+")||s.startsWith("-")}function hasGlobPattern(s){return s.includes("*")||s.includes("?")}function expandPackageGlob(pattern,root){return globSync(pattern,{cwd:root}).map(match2=>resolve13(root,match2)).filter(path15=>relative6(root,path15).split(sep9).every(segment2=>segment2===".."||!segment2.startsWith("."))).sort((a,b2)=>a<b2?-1:a>b2?1:0)}function splitPatterns(entries){let plain=[],patterns=[];for(let entry of entries)isPattern(entry)?patterns.push(entry):plain.push(entry);return{plain,patterns}}function collectFiles(dir,filePattern,skipNodeModules=!0,ignoreMatcher,rootDir){let files=[];if(!existsSync14(dir))return files;let root=rootDir??dir,ig=ignoreMatcher??(0,import_ignore3.default)();addIgnoreRules2(ig,dir,root);try{let entries=readdirSync12(dir,{withFileTypes:!0});for(let entry of entries){if(entry.name.startsWith(".")||skipNodeModules&&entry.name==="node_modules")continue;let fullPath=join39(dir,entry.name),isDir=entry.isDirectory(),isFile=entry.isFile();if(entry.isSymbolicLink())try{let stats=statSync11(fullPath);isDir=stats.isDirectory(),isFile=stats.isFile()}catch{continue}let relPath=toPosixPath3(relative6(root,fullPath)),ignorePath=isDir?`${relPath}/`:relPath;ig.ignores(ignorePath)||(isDir?files.push(...collectFiles(fullPath,filePattern,skipNodeModules,ig,root)):isFile&&filePattern.test(entry.name)&&files.push(fullPath))}}catch{}return files}function collectSkillEntries(dir,mode,ignoreMatcher,rootDir){let entries=[];if(!existsSync14(dir))return entries;let root=rootDir??dir,ig=ignoreMatcher??(0,import_ignore3.default)();addIgnoreRules2(ig,dir,root);try{let dirEntries=readdirSync12(dir,{withFileTypes:!0});for(let entry of dirEntries){if(entry.name!=="SKILL.md")continue;let fullPath=join39(dir,entry.name),isFile=entry.isFile();if(entry.isSymbolicLink())try{isFile=statSync11(fullPath).isFile()}catch{continue}let relPath=toPosixPath3(relative6(root,fullPath));if(isFile&&!ig.ignores(relPath))return entries.push(fullPath),entries}for(let entry of dirEntries){if(entry.name.startsWith(".")||entry.name==="node_modules")continue;let fullPath=join39(dir,entry.name),isDir=entry.isDirectory(),isFile=entry.isFile();if(entry.isSymbolicLink())try{let stats=statSync11(fullPath);isDir=stats.isDirectory(),isFile=stats.isFile()}catch{continue}let relPath=toPosixPath3(relative6(root,fullPath));if(isFile&&entry.name.endsWith(".md")&&!ig.ignores(relPath)&&(mode==="project"&&dir===root||mode==="agents"&&dir!==root)){entries.push(fullPath);continue}isDir&&(ig.ignores(`${relPath}/`)||entries.push(...collectSkillEntries(fullPath,mode,ig,root)))}}catch{}return entries}function collectAutoSkillEntries(dir,mode){return collectSkillEntries(dir,mode)}function findGitRepoRoot(startDir){let dir=resolve13(startDir);for(;;){if(existsSync14(join39(dir,".git")))return dir;let parent=dirname21(dir);if(parent===dir)return null;dir=parent}}function collectAncestorAgentsSkillDirs(startDir){let skillDirs=[],resolvedStartDir=resolve13(startDir),gitRepoRoot=findGitRepoRoot(resolvedStartDir),dir=resolvedStartDir;for(;skillDirs.push(join39(dir,".agents","skills")),!(gitRepoRoot&&dir===gitRepoRoot);){let parent=dirname21(dir);if(parent===dir)break;dir=parent}return skillDirs}function collectAutoPromptEntries(dir){let entries=[];if(!existsSync14(dir))return entries;let ig=(0,import_ignore3.default)();addIgnoreRules2(ig,dir,dir);try{let dirEntries=readdirSync12(dir,{withFileTypes:!0});for(let entry of dirEntries){if(entry.name.startsWith(".")||entry.name==="node_modules")continue;let fullPath=join39(dir,entry.name),isFile=entry.isFile();if(entry.isSymbolicLink())try{isFile=statSync11(fullPath).isFile()}catch{continue}let relPath=toPosixPath3(relative6(dir,fullPath));ig.ignores(relPath)||isFile&&entry.name.endsWith(".md")&&entries.push(fullPath)}}catch{}return entries}function collectAutoThemeEntries(dir){let entries=[];if(!existsSync14(dir))return entries;let ig=(0,import_ignore3.default)();addIgnoreRules2(ig,dir,dir);try{let dirEntries=readdirSync12(dir,{withFileTypes:!0});for(let entry of dirEntries){if(entry.name.startsWith(".")||entry.name==="node_modules")continue;let fullPath=join39(dir,entry.name),isFile=entry.isFile();if(entry.isSymbolicLink())try{isFile=statSync11(fullPath).isFile()}catch{continue}let relPath=toPosixPath3(relative6(dir,fullPath));ig.ignores(relPath)||isFile&&entry.name.endsWith(".json")&&entries.push(fullPath)}}catch{}return entries}function collectResourceFiles(dir,resourceType){return resourceType==="skills"?collectSkillEntries(dir,"project"):collectFiles(dir,FILE_PATTERNS[resourceType])}function matchesAnyPattern(filePath,patterns,baseDir){let rel=toPosixPath3(relative6(baseDir,filePath)),name=basename11(filePath),filePathPosix=toPosixPath3(filePath),isSkillFile=name==="SKILL.md",parentDir=isSkillFile?dirname21(filePath):void 0,parentRel=isSkillFile?toPosixPath3(relative6(baseDir,parentDir)):void 0,parentName=isSkillFile?basename11(parentDir):void 0,parentDirPosix=isSkillFile?toPosixPath3(parentDir):void 0;return patterns.some(pattern=>{let normalizedPattern=toPosixPath3(pattern);return minimatch(rel,normalizedPattern)||minimatch(name,normalizedPattern)||minimatch(filePathPosix,normalizedPattern)?!0:isSkillFile?minimatch(parentRel,normalizedPattern)||minimatch(parentName,normalizedPattern)||minimatch(parentDirPosix,normalizedPattern):!1})}function normalizeExactPattern(pattern){let normalized=pattern.startsWith("./")||pattern.startsWith(".\\")?pattern.slice(2):pattern;return toPosixPath3(normalized)}function matchesAnyExactPattern(filePath,patterns,baseDir){if(patterns.length===0)return!1;let rel=toPosixPath3(relative6(baseDir,filePath)),name=basename11(filePath),filePathPosix=toPosixPath3(filePath),isSkillFile=name==="SKILL.md",parentDir=isSkillFile?dirname21(filePath):void 0,parentRel=isSkillFile?toPosixPath3(relative6(baseDir,parentDir)):void 0,parentDirPosix=isSkillFile?toPosixPath3(parentDir):void 0;return patterns.some(pattern=>{let normalized=normalizeExactPattern(pattern);return normalized===rel||normalized===filePathPosix?!0:isSkillFile?normalized===parentRel||normalized===parentDirPosix:!1})}function getOverridePatterns(entries){return entries.filter(pattern=>pattern.startsWith("!")||pattern.startsWith("+")||pattern.startsWith("-"))}function isEnabledByOverrides(filePath,patterns,baseDir){let overrides=getOverridePatterns(patterns),excludes=overrides.filter(pattern=>pattern.startsWith("!")).map(pattern=>pattern.slice(1)),forceIncludes=overrides.filter(pattern=>pattern.startsWith("+")).map(pattern=>pattern.slice(1)),forceExcludes=overrides.filter(pattern=>pattern.startsWith("-")).map(pattern=>pattern.slice(1)),enabled=!0;return excludes.length>0&&matchesAnyPattern(filePath,excludes,baseDir)&&(enabled=!1),forceIncludes.length>0&&matchesAnyExactPattern(filePath,forceIncludes,baseDir)&&(enabled=!0),forceExcludes.length>0&&matchesAnyExactPattern(filePath,forceExcludes,baseDir)&&(enabled=!1),enabled}function applyPatterns(allPaths,patterns,baseDir){let includes=[],excludes=[],forceIncludes=[],forceExcludes=[];for(let p of patterns)p.startsWith("+")?forceIncludes.push(p.slice(1)):p.startsWith("-")?forceExcludes.push(p.slice(1)):p.startsWith("!")?excludes.push(p.slice(1)):includes.push(p);let result;if(includes.length===0?result=[...allPaths]:result=allPaths.filter(filePath=>matchesAnyPattern(filePath,includes,baseDir)),excludes.length>0&&(result=result.filter(filePath=>!matchesAnyPattern(filePath,excludes,baseDir))),forceIncludes.length>0)for(let filePath of allPaths)!result.includes(filePath)&&matchesAnyExactPattern(filePath,forceIncludes,baseDir)&&result.push(filePath);return forceExcludes.length>0&&(result=result.filter(filePath=>!matchesAnyExactPattern(filePath,forceExcludes,baseDir))),new Set(result)}function applyAutoloadDisabledPatterns(allPaths,patterns,baseDir){let result=new Map;for(let pattern of patterns){let target=pattern.slice(pattern.startsWith("+")||pattern.startsWith("-")||pattern.startsWith("!")?1:0),enabled=!pattern.startsWith("-")&&!pattern.startsWith("!"),exact=pattern.startsWith("+")||pattern.startsWith("-");for(let filePath of allPaths)(exact?matchesAnyExactPattern(filePath,[target],baseDir):matchesAnyPattern(filePath,[target],baseDir))&&result.set(filePath,enabled)}return result}var import_semver3=__toESM(require_semver2(),1);import{homedir as homedir7}from"node:os";import{join as join40,relative as relative7}from"node:path";var import_hosted_git_info=__toESM(require_lib(),1);function splitRef(url){let scpLikeMatch=url.match(/^git@([^:]+):(.+)$/);if(scpLikeMatch){let pathWithMaybeRef2=scpLikeMatch[2]??"",refSeparator2=pathWithMaybeRef2.indexOf("@");if(refSeparator2<0)return{repo:url};let repoPath2=pathWithMaybeRef2.slice(0,refSeparator2),ref2=pathWithMaybeRef2.slice(refSeparator2+1);return!repoPath2||!ref2?{repo:url}:{repo:`git@${scpLikeMatch[1]??""}:${repoPath2}`,ref:ref2}}if(url.includes("://"))try{let parsed=new URL(url),pathWithMaybeRef2=parsed.pathname.replace(/^\/+/,""),refSeparator2=pathWithMaybeRef2.indexOf("@");if(refSeparator2<0)return{repo:url};let repoPath2=pathWithMaybeRef2.slice(0,refSeparator2),ref2=pathWithMaybeRef2.slice(refSeparator2+1);return!repoPath2||!ref2?{repo:url}:(parsed.pathname=`/${repoPath2}`,{repo:parsed.toString().replace(/\/$/,""),ref:ref2})}catch{return{repo:url}}let slashIndex=url.indexOf("/");if(slashIndex<0)return{repo:url};let host=url.slice(0,slashIndex),pathWithMaybeRef=url.slice(slashIndex+1),refSeparator=pathWithMaybeRef.indexOf("@");if(refSeparator<0)return{repo:url};let repoPath=pathWithMaybeRef.slice(0,refSeparator),ref=pathWithMaybeRef.slice(refSeparator+1);return!repoPath||!ref?{repo:url}:{repo:`${host}/${repoPath}`,ref}}function decodeForValidation(value){try{return decodeURIComponent(value)}catch{return null}}function hasUnsafeGitInstallPart(value,allowSlash){let decoded=decodeForValidation(value);if(decoded===null)return!0;let candidates=[value,decoded];for(let candidate of candidates)if(candidate.includes("\0")||candidate.includes("\\")||candidate.startsWith("/")||!allowSlash&&candidate.includes("/")||candidate.split("/").includes(".."))return!0;return!1}function buildGitSource(args){if(args.path.startsWith("/"))return null;let normalizedPath=args.path.replace(/\.git$/,"").replace(/^\/+/,"");return!args.host||!normalizedPath||normalizedPath.split("/").length<2||hasUnsafeGitInstallPart(args.host,!1)||hasUnsafeGitInstallPart(normalizedPath,!0)?null:{type:"git",repo:args.repo,host:args.host,path:normalizedPath,ref:args.ref,pinned:!!args.ref}}function parseGenericGitUrl(url){let{repo:repoWithoutRef,ref}=splitRef(url),repo=repoWithoutRef,host="",path15="",scpLikeMatch=repoWithoutRef.match(/^git@([^:]+):(.+)$/);if(scpLikeMatch)host=scpLikeMatch[1]??"",path15=scpLikeMatch[2]??"";else if(repoWithoutRef.startsWith("https://")||repoWithoutRef.startsWith("http://")||repoWithoutRef.startsWith("ssh://")||repoWithoutRef.startsWith("git://"))try{let parsed=new URL(repoWithoutRef);host=parsed.hostname,path15=parsed.pathname.replace(/^\/+/,"")}catch{return null}else{let slashIndex=repoWithoutRef.indexOf("/");if(slashIndex<0||(host=repoWithoutRef.slice(0,slashIndex),path15=repoWithoutRef.slice(slashIndex+1),!host.includes(".")&&host!=="localhost"))return null;repo=`https://${repoWithoutRef}`}return buildGitSource({repo,host,path:path15,ref})}function parseGitUrl(source){let trimmed=source.trim(),hasGitPrefix=trimmed.startsWith("git:"),url=hasGitPrefix?trimmed.slice(4).trim():trimmed;if(!hasGitPrefix&&!/^(https?|ssh|git):\/\//i.test(url))return null;let split=splitRef(url),hostedCandidates=[split.ref?`${split.repo}#${split.ref}`:void 0,url].filter(value=>!!value);for(let candidate of hostedCandidates){let info=import_hosted_git_info.default.fromUrl(candidate);if(info){if(split.ref&&info.project?.includes("@"))continue;let useHttpsPrefix=!split.repo.startsWith("http://")&&!split.repo.startsWith("https://")&&!split.repo.startsWith("ssh://")&&!split.repo.startsWith("git://")&&!split.repo.startsWith("git@");return buildGitSource({repo:useHttpsPrefix?`https://${split.repo}`:split.repo,host:info.domain||"",path:`${info.user}/${info.project}`,ref:info.committish||split.ref||void 0})}}let httpsCandidates=[split.ref?`https://${split.repo}#${split.ref}`:void 0,`https://${url}`].filter(value=>!!value);for(let candidate of httpsCandidates){let info=import_hosted_git_info.default.fromUrl(candidate);if(info){if(split.ref&&info.project?.includes("@"))continue;return buildGitSource({repo:`https://${split.repo}`,host:info.domain||"",path:`${info.user}/${info.project}`,ref:info.committish||split.ref||void 0})}}return parseGenericGitUrl(url)}function isExactNpmVersion(version){return(0,import_semver3.valid)(version??"")!==null}function getNpmVersionRange(version){return version?(0,import_semver3.validRange)(version)??void 0:void 0}function getHomeDir(){return process.env.HOME||homedir7()}function getBaseDirForScope(ctx,scope){return scope==="project"?join40(ctx.cwd,CONFIG_DIR_NAME):scope==="user"?ctx.agentDir:ctx.cwd}function resolvePath3(ctx,input){return resolvePath(input,ctx.cwd,{homeDir:getHomeDir(),trim:!0})}function resolvePathFromBase(input,baseDir){return resolvePath(input,baseDir,{homeDir:getHomeDir(),trim:!0})}function parseNpmSpec(spec){let match2=spec.match(/^(@?[^@]+(?:\/[^@]+)?)(?:@(.+))?$/);if(!match2)return{name:spec};let name=match2[1]??spec,version=match2[2];return{name,version}}function parseSource(source){if(source.startsWith("npm:")){let spec=source.slice(4).trim(),{name,version}=parseNpmSpec(spec);return{type:"npm",spec,name,version,range:getNpmVersionRange(version),pinned:isExactNpmVersion(version)}}if(isLocalPath(source))return{type:"local",path:source};let gitParsed=parseGitUrl(source);return gitParsed||{type:"local",path:source}}function getPackageSourceString(pkg2){return typeof pkg2=="string"?pkg2:pkg2.source}function getSourceMatchKeyForInput(ctx,source){let parsed=parseSource(source);return parsed.type==="npm"?`npm:${parsed.name}`:parsed.type==="git"?`git:${parsed.host}/${parsed.path}`:`local:${resolvePath3(ctx,parsed.path)}`}function getSourceMatchKeyForSettings(ctx,source,scope){let parsed=parseSource(source);if(parsed.type==="npm")return`npm:${parsed.name}`;if(parsed.type==="git")return`git:${parsed.host}/${parsed.path}`;let baseDir=getBaseDirForScope(ctx,scope);return`local:${resolvePathFromBase(parsed.path,baseDir)}`}function buildNoMatchingPackageMessage(source,configuredPackages){let suggestion=findSuggestedConfiguredSource(source,configuredPackages);return suggestion?`No matching package found for ${source}. Did you mean ${suggestion}?`:`No matching package found for ${source}`}function findSuggestedConfiguredSource(source,configuredPackages){let trimmedSource=source.trim(),suggestions=new Set;for(let pkg2 of configuredPackages){let sourceStr=getPackageSourceString(pkg2),parsed=parseSource(sourceStr);if(parsed.type==="npm"){(trimmedSource===parsed.name||trimmedSource===parsed.spec)&&suggestions.add(sourceStr);continue}if(parsed.type==="git"){let shorthand=`${parsed.host}/${parsed.path}`,shorthandWithRef=parsed.ref?`${shorthand}@${parsed.ref}`:void 0;(trimmedSource===shorthand||shorthandWithRef&&trimmedSource===shorthandWithRef)&&suggestions.add(sourceStr)}}return suggestions.values().next().value}function normalizePackageSourceForSettings(ctx,source,scope){let parsed=parseSource(source);if(parsed.type!=="local")return source;let baseDir=getBaseDirForScope(ctx,scope),resolved=resolvePath3(ctx,parsed.path);return relative7(baseDir,resolved)||"."}function getPackageIdentity(ctx,source,scope){let parsed=parseSource(source);if(parsed.type==="npm")return`npm:${parsed.name}`;if(parsed.type==="git")return`git:${parsed.host}/${parsed.path}`;if(scope){let baseDir=getBaseDirForScope(ctx,scope);return`local:${resolvePathFromBase(parsed.path,baseDir)}`}return`local:${resolvePath3(ctx,parsed.path)}`}function dedupePackages(ctx,packages){let result=[],seen=new Map;for(let entry of packages){let identity=getPackageIdentity(ctx,getPackageSourceString(entry.pkg),entry.scope),index3=seen.get(identity);if(index3===void 0){seen.set(identity,result.length),result.push(entry);continue}let existing=result[index3];existing?.scope==="project"&&entry.scope==="user"?typeof existing.pkg=="object"&&existing.pkg.autoload===!1&&result.push(entry):entry.scope==="project"&&(result[index3]=entry)}return result}import{readFileSync as readFileSync15}from"node:fs";var RESOURCE_FIELDS=["skills","prompts","themes"];function isObject4(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function readPiManifest(packageJsonPath){try{let pkg2=JSON.parse(stripBom(readFileSync15(packageJsonPath,"utf-8")));if(!isObject4(pkg2)||!isObject4(pkg2.pi))return null;let manifest={};for(let field2 of RESOURCE_FIELDS){let entries=pkg2.pi[field2];Array.isArray(entries)&&entries.every(entry=>typeof entry=="string")&&(manifest[field2]=entries)}return manifest}catch{return null}}function resourcePrecedenceRank(m2){return m2.origin==="package"?4:(m2.scope==="project"?0:2)+(m2.source==="local"?0:1)}function collectPackageResources(packageRoot,accumulator,filter2,metadata){if(filter2){for(let resourceType of RESOURCE_TYPES){let patterns=filter2[resourceType],target=getTargetMap(accumulator,resourceType);filter2.autoload===!1?applyPackageDeltaFilter(packageRoot,patterns??[],resourceType,target,metadata):patterns!==void 0?applyPackageFilter(packageRoot,patterns,resourceType,target,metadata):collectDefaultResources(packageRoot,resourceType,target,metadata)}return!0}let manifest=readPiManifest(join41(packageRoot,"package.json"));if(manifest){for(let resourceType of RESOURCE_TYPES){let entries=manifest[resourceType];addManifestEntries(entries,packageRoot,resourceType,getTargetMap(accumulator,resourceType),metadata)}return!0}let hasAnyDir=!1;for(let resourceType of RESOURCE_TYPES){let dir=join41(packageRoot,resourceType);if(existsSync15(dir)){let files=collectResourceFiles(dir,resourceType);for(let f of files)addResource(getTargetMap(accumulator,resourceType),f,metadata,!0);hasAnyDir=!0}}return hasAnyDir}function collectDefaultResources(packageRoot,resourceType,target,metadata){let entries=readPiManifest(join41(packageRoot,"package.json"))?.[resourceType];if(entries){addManifestEntries(entries,packageRoot,resourceType,target,metadata);return}let dir=join41(packageRoot,resourceType);if(existsSync15(dir)){let files=collectResourceFiles(dir,resourceType);for(let f of files)addResource(target,f,metadata,!0)}}function applyPackageFilter(packageRoot,userPatterns,resourceType,target,metadata){let{allFiles}=collectManifestFiles(packageRoot,resourceType);if(userPatterns.length===0){for(let f of allFiles)addResource(target,f,metadata,!1);return}let enabledByUser=applyPatterns(allFiles,userPatterns,packageRoot);for(let f of allFiles){let enabled=enabledByUser.has(f);addResource(target,f,metadata,enabled)}}function applyPackageDeltaFilter(packageRoot,userPatterns,resourceType,target,metadata){if(userPatterns.length===0)return;let{allFiles}=collectManifestFiles(packageRoot,resourceType),enabledByUser=applyAutoloadDisabledPatterns(allFiles,userPatterns,packageRoot);for(let[filePath,enabled]of enabledByUser)addResource(target,filePath,metadata,enabled)}function collectManifestFiles(packageRoot,resourceType){let entries=readPiManifest(join41(packageRoot,"package.json"))?.[resourceType];if(entries&&entries.length>0){let allFiles2=collectFilesFromManifestEntries(entries,packageRoot,resourceType),manifestPatterns=entries.filter(isOverridePattern),enabledByManifest=manifestPatterns.length>0?applyPatterns(allFiles2,manifestPatterns,packageRoot):new Set(allFiles2);return{allFiles:Array.from(enabledByManifest),enabledByManifest}}let conventionDir=join41(packageRoot,resourceType);if(!existsSync15(conventionDir))return{allFiles:[],enabledByManifest:new Set};let allFiles=collectResourceFiles(conventionDir,resourceType);return{allFiles,enabledByManifest:new Set(allFiles)}}function addManifestEntries(entries,root,resourceType,target,metadata){if(!entries)return;let allFiles=collectFilesFromManifestEntries(entries,root,resourceType),patterns=entries.filter(isOverridePattern),enabledPaths=applyPatterns(allFiles,patterns,root);for(let f of allFiles)enabledPaths.has(f)&&addResource(target,f,metadata,!0)}function collectFilesFromManifestEntries(entries,root,resourceType){let resolved=entries.filter(entry=>!isOverridePattern(entry)).flatMap(entry=>hasGlobPattern(entry)?expandPackageGlob(entry,root):[resolve14(root,entry)]);return collectFilesFromPaths(resolved,resourceType)}function resolveLocalEntries(entries,resourceType,target,metadata,baseDir){if(entries.length===0)return;let{plain,patterns}=splitPatterns(entries),resolvedPlain=plain.map(p=>resolvePathFromBase(p,baseDir)),allFiles=collectFilesFromPaths(resolvedPlain,resourceType),enabledPaths=applyPatterns(allFiles,patterns,baseDir);for(let f of allFiles)addResource(target,f,metadata,enabledPaths.has(f))}function addAutoDiscoveredResources(cwd,accumulator,globalSettings,projectSettings,globalBaseDir,projectBaseDir){let userMetadata={source:"auto",scope:"user",origin:"top-level",baseDir:globalBaseDir},projectMetadata={source:"auto",scope:"project",origin:"top-level",baseDir:projectBaseDir},userOverrides={skills:globalSettings.skills??[],prompts:globalSettings.prompts??[],themes:globalSettings.themes??[]},projectOverrides={skills:projectSettings.skills??[],prompts:projectSettings.prompts??[],themes:projectSettings.themes??[]},userDirs={skills:join41(globalBaseDir,"skills"),prompts:join41(globalBaseDir,"prompts"),themes:join41(globalBaseDir,"themes")},projectDirs={skills:join41(projectBaseDir,"skills"),prompts:join41(projectBaseDir,"prompts"),themes:join41(projectBaseDir,"themes")},userAgentsSkillsDir=join41(getHomeDir(),".agents","skills"),projectAgentsSkillDirs=collectAncestorAgentsSkillDirs(cwd).filter(dir=>resolve14(dir)!==resolve14(userAgentsSkillsDir)),addResources=(resourceType,paths,metadata,overrides,baseDir)=>{let target=getTargetMap(accumulator,resourceType);for(let path15 of paths){let enabled=isEnabledByOverrides(path15,overrides,baseDir);addResource(target,path15,metadata,enabled)}};addResources("skills",collectAutoSkillEntries(projectDirs.skills,"project"),projectMetadata,projectOverrides.skills,projectBaseDir);for(let agentsSkillsDir of projectAgentsSkillDirs){let agentsBaseDir=dirname22(agentsSkillsDir),agentsMetadata={...projectMetadata,baseDir:agentsBaseDir};addResources("skills",collectAutoSkillEntries(agentsSkillsDir,"agents"),agentsMetadata,projectOverrides.skills,agentsBaseDir)}addResources("prompts",collectAutoPromptEntries(projectDirs.prompts),projectMetadata,projectOverrides.prompts,projectBaseDir),addResources("themes",collectAutoThemeEntries(projectDirs.themes),projectMetadata,projectOverrides.themes,projectBaseDir),addResources("skills",collectAutoSkillEntries(userDirs.skills,"project"),userMetadata,userOverrides.skills,globalBaseDir);let userAgentsBaseDir=dirname22(userAgentsSkillsDir),userAgentsMetadata={...userMetadata,baseDir:userAgentsBaseDir};addResources("skills",collectAutoSkillEntries(userAgentsSkillsDir,"agents"),userAgentsMetadata,userOverrides.skills,userAgentsBaseDir),addResources("prompts",collectAutoPromptEntries(userDirs.prompts),userMetadata,userOverrides.prompts,globalBaseDir),addResources("themes",collectAutoThemeEntries(userDirs.themes),userMetadata,userOverrides.themes,globalBaseDir)}function collectFilesFromPaths(paths,resourceType){let files=[];for(let p of paths)if(existsSync15(p))try{let stats=statSync12(p);stats.isFile()?files.push(p):stats.isDirectory()&&files.push(...collectResourceFiles(p,resourceType))}catch{}return files}function getTargetMap(accumulator,resourceType){switch(resourceType){case"skills":return accumulator.skills;case"prompts":return accumulator.prompts;case"themes":return accumulator.themes;default:throw new Error(`Unknown resource type: ${resourceType}`)}}function addResource(map,path15,metadata,enabled){path15&&(map.has(path15)||map.set(path15,{metadata,enabled}))}function createAccumulator(){return{skills:new Map,prompts:new Map,themes:new Map}}function toResolvedPaths(accumulator){let mapToResolved=entries=>{let resolved=Array.from(entries.entries()).map(([path15,{metadata,enabled}])=>({path:path15,enabled,metadata}));resolved.sort((a,b2)=>resourcePrecedenceRank(a.metadata)-resourcePrecedenceRank(b2.metadata));let seen=new Set;return resolved.filter(entry=>{let canonicalPath=canonicalizePath(entry.path);return seen.has(canonicalPath)?!1:(seen.add(canonicalPath),!0)})};return{skills:mapToResolved(accumulator.skills),prompts:mapToResolved(accumulator.prompts),themes:mapToResolved(accumulator.themes)}}var NETWORK_TIMEOUT_MS2=1e4,UPDATE_CHECK_CONCURRENCY=4,GIT_UPDATE_CONCURRENCY=4,DefaultPackageManager=class{cwd;agentDir;settingsManager;globalNpmRoot;globalNpmRootCommandKey;progressCallback;constructor(options){this.cwd=resolvePath(options.cwd),this.agentDir=resolvePath(options.agentDir),this.settingsManager=options.settingsManager}get context(){return{cwd:this.cwd,agentDir:this.agentDir,settingsManager:this.settingsManager}}setProgressCallback(callback){this.progressCallback=callback}addSourceToSettings(source,options){let scope=options?.local?"project":"user",currentPackages=(scope==="project"?this.settingsManager.getProjectSettings():this.settingsManager.getGlobalSettings()).packages??[],normalizedSource=this.normalizePackageSourceForSettings(source,scope),matchIndex=currentPackages.findIndex(existing=>this.packageSourcesMatch(existing,source,scope));if(matchIndex!==-1){let existing=currentPackages[matchIndex];if(this.getPackageSourceString(existing)===normalizedSource)return!1;let nextPackages2=[...currentPackages];return nextPackages2[matchIndex]=typeof existing=="string"?normalizedSource:{...existing,source:normalizedSource},scope==="project"?this.settingsManager.setProjectPackages(nextPackages2):this.settingsManager.setPackages(nextPackages2),!0}let nextPackages=[...currentPackages,normalizedSource];return scope==="project"?this.settingsManager.setProjectPackages(nextPackages):this.settingsManager.setPackages(nextPackages),!0}removeSourceFromSettings(source,options){let scope=options?.local?"project":"user",currentPackages=(scope==="project"?this.settingsManager.getProjectSettings():this.settingsManager.getGlobalSettings()).packages??[],nextPackages=currentPackages.filter(existing=>!this.packageSourcesMatch(existing,source,scope));return nextPackages.length!==currentPackages.length?(scope==="project"?this.settingsManager.setProjectPackages(nextPackages):this.settingsManager.setPackages(nextPackages),!0):!1}getInstalledPath(source,scope){let parsed=this.parseSource(source);if(parsed.type==="npm"){let path15=this.getNpmInstallPath(parsed,scope);return existsSync16(path15)?path15:void 0}if(parsed.type==="git"){let path15=this.getGitInstallPath(parsed,scope);return existsSync16(path15)?path15:void 0}if(parsed.type==="local"){let baseDir=this.getBaseDirForScope(scope),path15=this.resolvePathFromBase(parsed.path,baseDir);return existsSync16(path15)?path15:void 0}}emitProgress(event){this.progressCallback?.(event)}async withProgress(action,source,message,operation){this.emitProgress({type:"start",action,source,message});try{await operation(),this.emitProgress({type:"complete",action,source})}catch(error2){let errorMessage2=error2 instanceof Error?error2.message:String(error2);throw this.emitProgress({type:"error",action,source,message:errorMessage2}),error2}}async resolve(onMissing){let accumulator=createAccumulator(),globalSettings=this.settingsManager.getGlobalSettings(),projectSettings=this.settingsManager.getProjectSettings(),allPackages=[];for(let pkg2 of projectSettings.packages??[])allPackages.push({pkg:pkg2,scope:"project"});for(let pkg2 of globalSettings.packages??[])allPackages.push({pkg:pkg2,scope:"user"});let packageSources=this.dedupePackages(allPackages);await this.resolvePackageSources(packageSources,accumulator,onMissing);let globalBaseDir=this.agentDir,projectBaseDir=join42(this.cwd,CONFIG_DIR_NAME);for(let resourceType of RESOURCE_TYPES){let target=getTargetMap(accumulator,resourceType),globalEntries=globalSettings[resourceType]??[],projectEntries=projectSettings[resourceType]??[];resolveLocalEntries(projectEntries,resourceType,target,{source:"local",scope:"project",origin:"top-level"},projectBaseDir),resolveLocalEntries(globalEntries,resourceType,target,{source:"local",scope:"user",origin:"top-level"},globalBaseDir)}return addAutoDiscoveredResources(this.cwd,accumulator,globalSettings,projectSettings,globalBaseDir,projectBaseDir),toResolvedPaths(accumulator)}async resolveSourceResources(sources,options){let accumulator=createAccumulator(),scope=options?.temporary?"temporary":options?.local?"project":"user",packageSources=sources.map(source=>({pkg:source,scope}));return await this.resolvePackageSources(packageSources,accumulator),toResolvedPaths(accumulator)}listConfiguredPackages(){let globalSettings=this.settingsManager.getGlobalSettings(),projectSettings=this.settingsManager.getProjectSettings(),configuredPackages=[];for(let pkg2 of globalSettings.packages??[]){let source=typeof pkg2=="string"?pkg2:pkg2.source;configuredPackages.push({source,scope:"user",filtered:typeof pkg2=="object",installedPath:this.getInstalledPath(source,"user")})}for(let pkg2 of projectSettings.packages??[]){let source=typeof pkg2=="string"?pkg2:pkg2.source;configuredPackages.push({source,scope:"project",filtered:typeof pkg2=="object",installedPath:this.getInstalledPath(source,"project")})}return configuredPackages}async install(source,options){let parsed=this.parseSource(source),scope=options?.local?"project":"user";await this.withProgress("install",source,`Installing ${source}...`,async()=>{if(parsed.type==="npm"){await this.installNpm(parsed,scope,!1);return}if(parsed.type==="git"){await this.installGit(parsed,scope);return}if(parsed.type==="local"){let resolved=this.resolvePath(parsed.path);if(!existsSync16(resolved))throw new Error(`Path does not exist: ${resolved}`);return}throw new Error(`Unsupported install source: ${source}`)})}async installAndPersist(source,options){await this.install(source,options),this.addSourceToSettings(source,options)}async remove(source,options){let parsed=this.parseSource(source),scope=options?.local?"project":"user";await this.withProgress("remove",source,`Removing ${source}...`,async()=>{if(parsed.type==="npm"){await this.uninstallNpm(parsed,scope);return}if(parsed.type==="git"){await this.removeGit(parsed,scope);return}if(parsed.type!=="local")throw new Error(`Unsupported remove source: ${source}`)})}async removeAndPersist(source,options){return await this.remove(source,options),this.removeSourceFromSettings(source,options)}async update(source){let globalSettings=this.settingsManager.getGlobalSettings(),projectSettings=this.settingsManager.getProjectSettings(),identity=source?this.getPackageIdentity(source):void 0,matched=!1,updateSources=[];for(let pkg2 of globalSettings.packages??[]){let sourceStr=typeof pkg2=="string"?pkg2:pkg2.source;identity&&this.getPackageIdentity(sourceStr,"user")!==identity||(matched=!0,updateSources.push({source:sourceStr,scope:"user"}))}for(let pkg2 of projectSettings.packages??[]){let sourceStr=typeof pkg2=="string"?pkg2:pkg2.source;identity&&this.getPackageIdentity(sourceStr,"project")!==identity||(matched=!0,updateSources.push({source:sourceStr,scope:"project"}))}if(source&&!matched)throw new Error(this.buildNoMatchingPackageMessage(source,[...globalSettings.packages??[],...projectSettings.packages??[]]));await this.updateConfiguredSources(updateSources)}async updateConfiguredSources(sources){if(isOfflineModeEnabled2()||sources.length===0)return;let npmCandidates=[],gitCandidates=[];for(let entry of sources){let parsed=this.parseSource(entry.source);parsed.type==="npm"?parsed.pinned||npmCandidates.push({...entry,parsed}):parsed.type==="git"&&gitCandidates.push({...entry,parsed})}let npmCheckTasks=npmCandidates.map(entry=>async()=>({entry,shouldUpdate:await this.shouldUpdateNpmSource(entry.parsed,entry.scope)})),npmCheckResults=await runWithConcurrency(npmCheckTasks,UPDATE_CHECK_CONCURRENCY),userNpmUpdates=[],projectNpmUpdates=[];for(let result of npmCheckResults)result.shouldUpdate&&(result.entry.scope==="user"?userNpmUpdates.push(result.entry):projectNpmUpdates.push(result.entry));let tasks=[];if(userNpmUpdates.length>0&&tasks.push(this.updateNpmBatch(userNpmUpdates,"user")),projectNpmUpdates.length>0&&tasks.push(this.updateNpmBatch(projectNpmUpdates,"project")),gitCandidates.length>0){let gitTasks=gitCandidates.map(entry=>async()=>this.withProgress("update",entry.source,`Updating ${entry.source}...`,async()=>{await this.updateGit(entry.parsed,entry.scope)}));tasks.push(runWithConcurrency(gitTasks,GIT_UPDATE_CONCURRENCY).then(()=>{}))}await Promise.all(tasks)}async shouldUpdateNpmSource(source,scope){let installedPath=getManagedNpmInstallPath(this.context,source,scope),installedVersion=existsSync16(installedPath)?this.getInstalledNpmVersion(installedPath):void 0;if(!installedVersion)return!0;let targetVersion=await this.getLatestNpmVersion(source.version?source.spec:source.name,source.range);return(0,import_semver4.gt)(targetVersion,installedVersion)}async updateNpmBatch(sources,scope){if(sources.length===0)return;let sourceLabel=sources.length===1?sources[0].source:`${scope} npm packages`,message=sources.length===1?`Updating ${sources[0].source}...`:`Updating ${scope} npm packages...`,specs=sources.map(entry=>entry.parsed.version?entry.parsed.spec:`${entry.parsed.name}@latest`);await this.withProgress("update",sourceLabel,message,async()=>{await this.installNpmBatch(specs,scope)})}async installNpmBatch(specs,scope){let installRoot=getNpmInstallRoot(this.context,scope,!1);ensureNpmProject(installRoot),await this.runNpmCommand(getNpmInstallArgs(this.context,specs,installRoot))}async checkForAvailableUpdates(){if(isOfflineModeEnabled2())return[];let globalSettings=this.settingsManager.getGlobalSettings(),projectSettings=this.settingsManager.getProjectSettings(),allPackages=[];for(let pkg2 of projectSettings.packages??[])allPackages.push({pkg:pkg2,scope:"project"});for(let pkg2 of globalSettings.packages??[])allPackages.push({pkg:pkg2,scope:"user"});let checks=this.dedupePackages(allPackages).filter(entry=>entry.scope!=="temporary").map(entry=>async()=>{let source=typeof entry.pkg=="string"?entry.pkg:entry.pkg.source,parsed=this.parseSource(source);if(parsed.type==="local"||parsed.pinned)return;if(parsed.type==="npm"){let installedPath2=this.getNpmInstallPath(parsed,entry.scope);return!existsSync16(installedPath2)||!await this.npmHasAvailableUpdate(parsed,installedPath2)?void 0:{source,displayName:parsed.name,type:"npm",scope:entry.scope}}let installedPath=this.getGitInstallPath(parsed,entry.scope);if(!(!existsSync16(installedPath)||!await this.gitHasAvailableUpdate(installedPath)))return{source,displayName:`${parsed.host}/${parsed.path}`,type:"git",scope:entry.scope}});return(await runWithConcurrency(checks,UPDATE_CHECK_CONCURRENCY)).filter(result=>result!==void 0)}async resolvePackageSources(sources,accumulator,onMissing){for(let{pkg:pkg2,scope}of sources){let sourceStr=typeof pkg2=="string"?pkg2:pkg2.source,filter2=typeof pkg2=="object"?pkg2:void 0,deltaBase=this.findAutoloadDeltaBase(pkg2,scope,sources),resolvedSource=deltaBase?.source??sourceStr,resolvedScope=deltaBase?.scope??scope,parsed=this.parseSource(resolvedSource),metadata={source:sourceStr,scope,origin:"package"};if(parsed.type==="local"){let baseDir=this.getBaseDirForScope(resolvedScope),resolvedLocal=this.resolvePathFromBase(parsed.path,baseDir);if(existsSync16(resolvedLocal))try{statSync13(resolvedLocal).isDirectory()&&(metadata.baseDir=resolvedLocal,collectPackageResources(resolvedLocal,accumulator,filter2,metadata))}catch{}continue}let installMissing=async()=>{if(isOfflineModeEnabled2())return!1;if(!onMissing)return await this.installParsedSource(parsed,resolvedScope),!0;let action=await onMissing(resolvedSource);if(action==="skip")return!1;if(action==="error")throw new Error(`Missing source: ${resolvedSource}`);return await this.installParsedSource(parsed,resolvedScope),!0};if(parsed.type==="npm"){let installedPath=this.getNpmInstallPath(parsed,resolvedScope);if(!existsSync16(installedPath)||!await installedNpmMatchesConfiguredVersion(parsed,installedPath)){if(!await installMissing())continue;installedPath=this.getNpmInstallPath(parsed,resolvedScope)}metadata.baseDir=installedPath,collectPackageResources(installedPath,accumulator,filter2,metadata);continue}if(parsed.type==="git"){let installedPath=this.getGitInstallPath(parsed,resolvedScope);if(existsSync16(installedPath))resolvedScope==="temporary"&&!parsed.pinned&&!isOfflineModeEnabled2()&&await this.refreshTemporaryGitSource(parsed,resolvedSource);else if(!await installMissing())continue;metadata.baseDir=installedPath,collectPackageResources(installedPath,accumulator,filter2,metadata)}}}findAutoloadDeltaBase(pkg2,scope,sources){if(scope!=="project"||typeof pkg2!="object"||pkg2.autoload!==!1)return;let identity=this.getPackageIdentity(pkg2.source,scope),userEntry=sources.find(entry=>entry.scope==="user"&&this.getPackageIdentity(this.getPackageSourceString(entry.pkg),"user")===identity);return userEntry?{source:this.getPackageSourceString(userEntry.pkg),scope:"user"}:void 0}async installParsedSource(parsed,scope){if(parsed.type==="npm"){await this.installNpm(parsed,scope,scope==="temporary");return}if(parsed.type==="git"){await this.installGit(parsed,scope);return}}parseSource(source){return parseSource(source)}getBaseDirForScope(scope){return getBaseDirForScope(this.context,scope)}resolvePath(input){return resolvePath3(this.context,input)}resolvePathFromBase(input,baseDir){return resolvePathFromBase(input,baseDir)}getPackageSourceString(pkg2){return getPackageSourceString(pkg2)}getSourceMatchKeyForInput(source){return getSourceMatchKeyForInput(this.context,source)}getSourceMatchKeyForSettings(source,scope){return getSourceMatchKeyForSettings(this.context,source,scope)}packageSourcesMatch(existing,inputSource,scope){let left=this.getSourceMatchKeyForSettings(this.getPackageSourceString(existing),scope),right=this.getSourceMatchKeyForInput(inputSource);return left===right}normalizePackageSourceForSettings(source,scope){return normalizePackageSourceForSettings(this.context,source,scope)}getPackageIdentity(source,scope){return getPackageIdentity(this.context,source,scope)}dedupePackages(packages){return dedupePackages(this.context,packages)}buildNoMatchingPackageMessage(source,configuredPackages){return buildNoMatchingPackageMessage(source,configuredPackages)}getNpmCommand(){return getNpmCommand(this.context)}getInstalledNpmVersion(installedPath){return getInstalledNpmVersion(installedPath)}getGitInstallPath(source,scope){return getGitInstallPath(this.context,source,scope)}async npmHasAvailableUpdate(source,installedPath){if(isOfflineModeEnabled2())return!1;let installedVersion=this.getInstalledNpmVersion(installedPath);if(!installedVersion)return!1;try{let targetVersion=await this.getLatestNpmVersion(source.version?source.spec:source.name,source.range);return(0,import_semver4.gt)(targetVersion,installedVersion)}catch{return!1}}async getLatestNpmVersion(packageSpec,range2){let npmCommand=this.getNpmCommand(),raw=(await this.runCommandCapture(npmCommand.command,[...npmCommand.args,"view",packageSpec,"version","--json"],{cwd:this.cwd,timeoutMs:NETWORK_TIMEOUT_MS2})).trim();if(!raw)throw new Error("Empty response from npm view");let parsed=JSON.parse(raw);if(typeof parsed=="string")return parsed;if(Array.isArray(parsed)){let versions=parsed.filter(value=>typeof value=="string"&&value.length>0),latest=range2?(0,import_semver4.maxSatisfying)(versions,range2):[...versions].sort(import_semver4.rcompare)[0];if(latest)return latest}throw new Error("Unexpected response from npm view")}async gitHasAvailableUpdate(installedPath){if(isOfflineModeEnabled2())return!1;try{let localHead=await this.runCommandCapture("git",["rev-parse","HEAD"],{cwd:installedPath,timeoutMs:NETWORK_TIMEOUT_MS2}),remoteHead=await this.getRemoteGitHead(installedPath);return localHead.trim()!==remoteHead.trim()}catch{return!1}}async getRemoteGitHead(installedPath){let upstreamRef=await this.getGitUpstreamRef(installedPath);if(upstreamRef){let match3=(await this.runGitRemoteCommand(installedPath,["ls-remote","origin",upstreamRef])).match(/^([0-9a-f]{40})\s+/m);if(match3?.[1])return match3[1]}let match2=(await this.runGitRemoteCommand(installedPath,["ls-remote","origin","HEAD"])).match(/^([0-9a-f]{40})\s+HEAD$/m);if(!match2?.[1])throw new Error("Failed to determine remote HEAD");return match2[1]}async getLocalGitUpdateTarget(installedPath){try{let trimmedUpstream=(await this.runCommandCapture("git",["rev-parse","--abbrev-ref","@{upstream}"],{cwd:installedPath,timeoutMs:NETWORK_TIMEOUT_MS2})).trim();if(!trimmedUpstream.startsWith("origin/"))throw new Error(`Unsupported upstream remote: ${trimmedUpstream}`);let branch=trimmedUpstream.slice(7);if(!branch)throw new Error("Missing upstream branch name");return{ref:"@{upstream}",head:await this.runCommandCapture("git",["rev-parse","@{upstream}"],{cwd:installedPath,timeoutMs:NETWORK_TIMEOUT_MS2}),fetchArgs:["fetch","--prune","--no-tags","origin",`+refs/heads/${branch}:refs/remotes/origin/${branch}`]}}catch{await this.runCommand("git",["remote","set-head","origin","-a"],{cwd:installedPath}).catch(()=>{});let head=await this.runCommandCapture("git",["rev-parse","origin/HEAD"],{cwd:installedPath,timeoutMs:NETWORK_TIMEOUT_MS2}),branch=(await this.runCommandCapture("git",["symbolic-ref","refs/remotes/origin/HEAD"],{cwd:installedPath,timeoutMs:NETWORK_TIMEOUT_MS2}).catch(()=>"")).trim().replace(/^refs\/remotes\/origin\//,"");return branch?{ref:"origin/HEAD",head,fetchArgs:["fetch","--prune","--no-tags","origin",`+refs/heads/${branch}:refs/remotes/origin/${branch}`]}:{ref:"origin/HEAD",head,fetchArgs:["fetch","--prune","--no-tags","origin","+HEAD:refs/remotes/origin/HEAD"]}}}async getGitUpstreamRef(installedPath){try{let trimmed=(await this.runCommandCapture("git",["rev-parse","--abbrev-ref","@{upstream}"],{cwd:installedPath,timeoutMs:NETWORK_TIMEOUT_MS2})).trim();if(!trimmed.startsWith("origin/"))return;let branch=trimmed.slice(7);return branch?`refs/heads/${branch}`:void 0}catch{return}}runGitRemoteCommand(installedPath,args){return this.runCommandCapture("git",args,{cwd:installedPath,timeoutMs:NETWORK_TIMEOUT_MS2,env:{GIT_TERMINAL_PROMPT:"0"}})}getGlobalNpmRoot(){let npmCommand=this.getNpmCommand(),commandKey=[npmCommand.command,...npmCommand.args].join("\0");if(this.globalNpmRoot&&this.globalNpmRootCommandKey===commandKey)return this.globalNpmRoot;if(getPackageManagerName(this.context)==="bun"){let binDir=this.runNpmCommandSync(["pm","bin","-g"]).trim();this.globalNpmRoot=join42(dirname23(binDir),"install","global","node_modules")}else this.globalNpmRoot=this.runNpmCommandSync(["root","-g"]).trim();return this.globalNpmRootCommandKey=commandKey,this.globalNpmRoot}getPnpmGlobalPackagePath(packageName){if(getPackageManagerName(this.context)!=="pnpm")return;let output=this.runNpmCommandSync(["list","-g","--depth","0","--json"]),entries=JSON.parse(output);for(let entry of entries){let path15=entry.dependencies?.[packageName]?.path;if(path15)return path15}}getLegacyGlobalNpmInstallPath(source){try{return this.getPnpmGlobalPackagePath(source.name)??join42(this.getGlobalNpmRoot(),source.name)}catch{return}}getNpmInstallPath(source,scope){let managedPath=getManagedNpmInstallPath(this.context,source,scope);if(scope!=="user"||existsSync16(managedPath))return managedPath;let legacyPath=this.getLegacyGlobalNpmInstallPath(source);return legacyPath&&existsSync16(legacyPath)?legacyPath:managedPath}async installNpm(source,scope,temporary){let installRoot=getNpmInstallRoot(this.context,scope,temporary);ensureNpmProject(installRoot),await this.runNpmCommand(getNpmInstallArgs(this.context,[source.spec],installRoot))}async uninstallNpm(source,scope){let installRoot=getNpmInstallRoot(this.context,scope,!1);if(!existsSync16(installRoot))return;let packageManagerName=getPackageManagerName(this.context);if(packageManagerName==="bun"){await this.runNpmCommand(["uninstall",source.name,"--cwd",installRoot]);return}let args=["uninstall",source.name,"--prefix",installRoot];packageManagerName!=="pnpm"&&args.push("--legacy-peer-deps"),await this.runNpmCommand(args)}async installGit(source,scope){let targetDir=this.getGitInstallPath(source,scope);if(existsSync16(targetDir)){if(source.ref){await this.ensureGitRef(targetDir,["fetch","origin",source.ref],"FETCH_HEAD");return}let target=await this.getLocalGitUpdateTarget(targetDir);await this.ensureGitRef(targetDir,target.fetchArgs,target.ref);return}let gitRoot=getGitInstallRoot(this.context,scope);gitRoot&&ensureGitIgnore(gitRoot),mkdirSync11(dirname23(targetDir),{recursive:!0}),rmSync4(getGitUpdateMarkerPath(targetDir),{force:!0});try{await this.runCommand("git",["clone",source.repo,targetDir]),source.ref&&await this.runCommand("git",["checkout",source.ref],{cwd:targetDir});let packageJsonPath=join42(targetDir,"package.json");existsSync16(packageJsonPath)&&await this.runNpmCommand(getGitDependencyInstallArgs(this.context),{cwd:targetDir})}catch(error2){throw rmSync4(targetDir,{recursive:!0,force:!0}),pruneEmptyGitParents(targetDir,gitRoot),error2}}async updateGit(source,scope){let targetDir=this.getGitInstallPath(source,scope);if(!existsSync16(targetDir)){await this.installGit(source,scope);return}if(source.ref){await this.ensureGitRef(targetDir,["fetch","origin",source.ref],"FETCH_HEAD");return}let target=await this.getLocalGitUpdateTarget(targetDir);await this.ensureGitRef(targetDir,target.fetchArgs,target.ref)}async repairMissingGitDependencies(targetDir){hasMissingGitDependencies(targetDir)&&await this.runNpmCommand(getGitDependencyInstallArgs(this.context),{cwd:targetDir})}async cleanAndInstallGitDependencies(targetDir,markerPath){try{await this.runCommand("git",["clean","-fdx"],{cwd:targetDir})}catch(error2){throw await this.repairMissingGitDependencies(targetDir).catch(()=>{}),error2}let packageJsonPath=join42(targetDir,"package.json");existsSync16(packageJsonPath)&&await this.runNpmCommand(getGitDependencyInstallArgs(this.context),{cwd:targetDir}),rmSync4(markerPath,{force:!0})}async ensureGitRef(targetDir,fetchArgs,ref){await this.runCommand("git",fetchArgs,{cwd:targetDir});let localHead=await this.runCommandCapture("git",["rev-parse","HEAD"],{cwd:targetDir,timeoutMs:NETWORK_TIMEOUT_MS2}),commitRef=`${ref}^{commit}`,targetHead=await this.runCommandCapture("git",["rev-parse",commitRef],{cwd:targetDir,timeoutMs:NETWORK_TIMEOUT_MS2}),markerPath=getGitUpdateMarkerPath(targetDir);if(localHead.trim()===targetHead.trim()){existsSync16(markerPath)?await this.cleanAndInstallGitDependencies(targetDir,markerPath):await this.repairMissingGitDependencies(targetDir);return}writeFileSync10(markerPath,"","utf-8"),await this.runCommand("git",["reset","--hard",commitRef],{cwd:targetDir}),await this.cleanAndInstallGitDependencies(targetDir,markerPath)}async refreshTemporaryGitSource(source,sourceStr){if(!isOfflineModeEnabled2())try{await this.withProgress("pull",sourceStr,`Refreshing ${sourceStr}...`,async()=>{await this.updateGit(source,"temporary")})}catch{}}async removeGit(source,scope){let targetDir=this.getGitInstallPath(source,scope);rmSync4(targetDir,{recursive:!0,force:!0}),rmSync4(getGitUpdateMarkerPath(targetDir),{force:!0}),pruneEmptyGitParents(targetDir,getGitInstallRoot(this.context,scope))}async runNpmCommand(args,options){let npmCommand=this.getNpmCommand();await this.runCommand(npmCommand.command,[...npmCommand.args,...args],options)}runNpmCommandSync(args){let npmCommand=this.getNpmCommand();return this.runCommandSync(npmCommand.command,[...npmCommand.args,...args])}spawnCommand(command,args,options){let env2=getEnv();return spawnProcess(command,args,{cwd:options?.cwd,stdio:isStdoutTakenOver()?["ignore",2,2]:"inherit",env:env2})}spawnCaptureCommand(command,args,options){let baseEnv=getEnv(),env2=options?.env?{...baseEnv,...options.env}:baseEnv;return spawnProcess(command,args,{cwd:options?.cwd,stdio:["ignore","pipe","pipe"],env:env2})}runCommandCapture(command,args,options){return new Promise((resolvePromise,reject2)=>{let child=this.spawnCaptureCommand(command,args,options),stdout="",stderr="",timedOut=!1,timeout=typeof options?.timeoutMs=="number"?setTimeout(()=>{timedOut=!0,child.kill()},options.timeoutMs):void 0;child.stdout?.on("data",data=>{stdout+=data.toString()}),child.stderr?.on("data",data=>{stderr+=data.toString()}),child.once("error",error2=>{timeout&&clearTimeout(timeout),reject2(error2)}),child.once("close",(code,signal)=>{if(timeout&&clearTimeout(timeout),timedOut){reject2(new Error(`${command} ${args.join(" ")} timed out after ${options?.timeoutMs}ms`));return}if(code===0){resolvePromise(stdout.trim());return}let exitStatus=code===null?`signal ${signal??"unknown"}`:`code ${code}`;reject2(new Error(`${command} ${args.join(" ")} failed with ${exitStatus}: ${stderr||stdout}`))})})}runCommand(command,args,options){return new Promise((resolvePromise,reject2)=>{let child=this.spawnCommand(command,args,options);child.on("error",reject2),child.on("exit",code=>{code===0?resolvePromise():reject2(new Error(`${command} ${args.join(" ")} failed with code ${code}`))})})}runCommandSync(command,args){let env2=getEnv(),result=spawnProcessSync(command,args,{stdio:["ignore","pipe","pipe"],encoding:"utf-8",env:env2});if(result.error||result.status!==0)throw new Error(`Failed to run ${command} ${args.join(" ")}: ${result.error?.message||result.stderr||result.stdout}`);return(result.stdout||result.stderr||"").trim()}};var import_proper_lockfile2=__toESM(require_proper_lockfile(),1);import{randomUUID as randomUUID15}from"crypto";import{existsSync as existsSync17,mkdirSync as mkdirSync12,readFileSync as readFileSync16,writeFileSync as writeFileSync11}from"fs";import{dirname as dirname24,join as join43}from"path";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}function deepMergeSettings(base,overrides){return deepMergeObjects(base,overrides)}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)}`)}function toSettingsError(scope,error2,path15){return{scope,...path15?{path:path15}:{},error:error2 instanceof Error?error2:new Error(String(error2))}}var FileSettingsStorage=class{globalSettingsPath;projectSettingsPath;constructor(cwd,agentDir){let resolvedCwd=resolvePath(cwd),resolvedAgentDir=resolvePath(agentDir);this.globalSettingsPath=join43(resolvedAgentDir,"settings.json"),this.projectSettingsPath=join43(resolvedCwd,CONFIG_DIR_NAME,"settings.json")}acquireLockSyncWithRetry(path15){let lastError;for(let attempt2=1;attempt2<=10;attempt2++)try{return import_proper_lockfile2.default.lockSync(path15,{realpath:!1})}catch(error2){if((typeof error2=="object"&&error2!==null&&"code"in error2?String(error2.code):void 0)!=="ELOCKED"||attempt2===10)throw error2;lastError=error2;let start=Date.now();for(;Date.now()-start<20;);}throw lastError??new Error("Failed to acquire settings lock")}withLock(scope,fn){let path15=scope==="global"?this.globalSettingsPath:this.projectSettingsPath,dir=dirname24(path15),release;try{let fileExists2=existsSync17(path15);fileExists2&&(release=this.acquireLockSyncWithRetry(path15));let current=fileExists2?readFileSync16(path15,"utf-8"):void 0,next=fn(current);next!==void 0&&(existsSync17(dir)||mkdirSync12(dir,{recursive:!0}),release||(release=this.acquireLockSyncWithRetry(path15)),writeFileSync11(path15,next,"utf-8"))}finally{release&&release()}}},InMemorySettingsStorage=class{global;project;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)}},SettingsManager=class _SettingsManager{storage;globalSettings;projectSettings;settings;modifiedFields=new Set;modifiedNestedFields=new Map;modifiedProjectFields=new Set;modifiedProjectNestedFields=new Map;globalSettingsLoadError=null;projectSettingsLoadError=null;writeQueue=Promise.resolve();errors;settingsPaths;constructor(storage,initialGlobal,initialProject,globalLoadError=null,projectLoadError=null,initialErrors=[],settingsPaths={}){this.storage=storage,this.globalSettings=initialGlobal,this.projectSettings=initialProject,this.globalSettingsLoadError=globalLoadError,this.projectSettingsLoadError=projectLoadError,this.errors=[...initialErrors],this.settingsPaths=settingsPaths,this.settings=deepMergeSettings(this.globalSettings,this.projectSettings)}static create(cwd,agentDir=getAgentDir(),options={}){let resolvedCwd=resolvePath(cwd),resolvedAgentDir=resolvePath(agentDir),storage=new FileSettingsStorage(resolvedCwd,resolvedAgentDir);return _SettingsManager.fromStorageWithPaths(storage,options,{global:join43(resolvedAgentDir,"settings.json"),project:join43(resolvedCwd,CONFIG_DIR_NAME,"settings.json")})}static fromStorage(storage,options={}){return _SettingsManager.fromStorageWithPaths(storage,options)}static fromStorageWithPaths(storage,options,settingsPaths={}){let globalLoad=_SettingsManager.tryLoadFromStorage(storage,"global"),projectLoad=_SettingsManager.tryLoadFromStorage(storage,"project"),initialErrors=[];return globalLoad.error&&initialErrors.push(toSettingsError("global",globalLoad.error,settingsPaths.global)),projectLoad.error&&initialErrors.push(toSettingsError("project",projectLoad.error,settingsPaths.project)),new _SettingsManager(storage,globalLoad.settings,projectLoad.settings,globalLoad.error,projectLoad.error,initialErrors,settingsPaths)}static inMemory(settings2={},options={}){let storage=new InMemorySettingsStorage,initialSettings=_SettingsManager.migrateSettings(structuredClone(settings2));return storage.withLock("global",()=>JSON.stringify(initialSettings,null,2)),_SettingsManager.fromStorage(storage,options)}static loadFromStorage(storage,scope){let content;if(storage.withLock(scope,current=>{content=current}),!content)return{};let settings2=JSON.parse(stripBom(content));return _SettingsManager.migrateSettings(settings2)}static tryLoadFromStorage(storage,scope){try{return{settings:_SettingsManager.loadFromStorage(storage,scope),error:null}}catch(error2){return{settings:{},error:error2}}}static migrateSettings(settings2){if("queueMode"in settings2&&!("steeringMode"in settings2)&&(settings2.steeringMode=settings2.queueMode,delete settings2.queueMode),!("transport"in settings2)&&typeof settings2.websockets=="boolean"&&(settings2.transport=settings2.websockets?"websocket":"sse",delete settings2.websockets),"skills"in settings2&&typeof settings2.skills=="object"&&settings2.skills!==null&&!Array.isArray(settings2.skills)){let skillsSettings=settings2.skills;skillsSettings.enableSkillCommands!==void 0&&settings2.enableSkillCommands===void 0&&(settings2.enableSkillCommands=skillsSettings.enableSkillCommands),Array.isArray(skillsSettings.customDirectories)&&skillsSettings.customDirectories.length>0?settings2.skills=skillsSettings.customDirectories:delete settings2.skills}if("retry"in settings2&&typeof settings2.retry=="object"&&settings2.retry!==null&&!Array.isArray(settings2.retry)){let retrySettings=settings2.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 settings2}getGlobalSettings(){return structuredClone(this.globalSettings)}getProjectSettings(){return structuredClone(this.projectSettings)}async reload(){await this.writeQueue;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();let projectLoad=_SettingsManager.tryLoadFromStorage(this.storage,"project");projectLoad.error?(this.projectSettingsLoadError=projectLoad.error,this.recordError("project",projectLoad.error)):(this.projectSettings=projectLoad.settings,this.projectSettingsLoadError=null),this.settings=deepMergeSettings(this.globalSettings,this.projectSettings)}applyOverrides(overrides){this.settings=deepMergeSettings(this.settings,overrides)}markModified(field2,nestedKey){this.modifiedFields.add(field2),nestedKey&&(this.modifiedNestedFields.has(field2)||this.modifiedNestedFields.set(field2,new Set),this.modifiedNestedFields.get(field2).add(nestedKey))}markProjectModified(field2,nestedKey){this.modifiedProjectFields.add(field2),nestedKey&&(this.modifiedProjectNestedFields.has(field2)||this.modifiedProjectNestedFields.set(field2,new Set),this.modifiedProjectNestedFields.get(field2).add(nestedKey))}recordError(scope,error2){this.errors.push(toSettingsError(scope,error2,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(()=>{task(),this.clearModifiedScope(scope)}).catch(error2=>{this.recordError(scope,error2)})}cloneModifiedNestedFields(source){let snapshot2=new Map;for(let[key,value]of source.entries())snapshot2.set(key,new Set(value));return snapshot2}persistScopedSettings(scope,snapshotSettings,modifiedFields,modifiedNestedFields){this.storage.withLock(scope,current=>{let currentFileSettings=current?_SettingsManager.migrateSettings(JSON.parse(stripBom(current))):{},mergedSettings={...currentFileSettings};for(let field2 of modifiedFields){let value=snapshotSettings[field2];if(modifiedNestedFields.has(field2)&&typeof value=="object"&&value!==null){let nestedModified=modifiedNestedFields.get(field2),baseNested=currentFileSettings[field2]??{},inMemoryNested=value,mergedNested={...baseNested};for(let nestedKey of nestedModified)mergedNested[nestedKey]=inMemoryNested[nestedKey];mergedSettings[field2]=mergedNested}else mergedSettings[field2]=value}return JSON.stringify(mergedSettings,null,2)})}save(){if(this.settings=deepMergeSettings(this.globalSettings,this.projectSettings),this.globalSettingsLoadError)return;let snapshotGlobalSettings=structuredClone(this.globalSettings),modifiedFields=new Set(this.modifiedFields),modifiedNestedFields=this.cloneModifiedNestedFields(this.modifiedNestedFields);this.enqueueWrite("global",()=>{this.persistScopedSettings("global",snapshotGlobalSettings,modifiedFields,modifiedNestedFields)})}saveProjectSettings(settings2){if(this.projectSettings=structuredClone(settings2),this.settings=deepMergeSettings(this.globalSettings,this.projectSettings),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(field2,update){let projectSettings=structuredClone(this.projectSettings);update(projectSettings),this.markProjectModified(field2),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()}getSuiteNoticeAcknowledgement(suiteId){return this.settings.suiteNoticesAcknowledged?.[suiteId]}setSuiteNoticeAcknowledgement(suiteId,ack){let next={...this.globalSettings.suiteNoticesAcknowledged??{},...this.settings.suiteNoticesAcknowledged??{}},existing=next[suiteId];next[suiteId]={...typeof existing=="object"&&existing!==null?existing:{},...ack.driftDigest===void 0?{}:{driftDigest:ack.driftDigest},...ack.upgradeRevision===void 0?{}:{upgradeRevision:ack.upgradeRevision}},this.globalSettings.suiteNoticesAcknowledged=next,this.settings.suiteNoticesAcknowledged=next,this.markModified("suiteNoticesAcknowledged"),this.save()}getSessionDir(){let sessionDir=this.settings.sessionDir;return sessionDir&&normalizePath(sessionDir)}getDefaultProvider(){return this.settings.defaultProvider}getDefaultModel(){return this.settings.defaultModel}getMemoryModeSetting(){return this.settings.memory?.mode}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||"one-at-a-time"}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()}getModelThinkingLevel(provider,modelId){return this.settings.modelThinkingLevels?.[`${provider}/${modelId}`]}getAllModelThinkingLevels(){return{...this.settings.modelThinkingLevels??{}}}setModelThinkingLevel(provider,modelId,level){this.globalSettings.modelThinkingLevels||(this.globalSettings.modelThinkingLevels={}),this.globalSettings.modelThinkingLevels[`${provider}/${modelId}`]=level,this.markModified("modelThinkingLevels"),this.save()}removeModelThinkingLevel(provider,modelId){this.globalSettings.modelThinkingLevels&&(delete this.globalSettings.modelThinkingLevels[`${provider}/${modelId}`],Object.keys(this.globalSettings.modelThinkingLevels).length===0&&delete this.globalSettings.modelThinkingLevels,this.markModified("modelThinkingLevels"),this.save())}getTransport(){return this.settings.transport??"auto"}setTransport(transport){this.globalSettings.transport=transport,this.markModified("transport"),this.save()}getCompactionEnabled(){return this.settings.compaction?.enabled??!0}setCompactionEnabled(enabled){this.globalSettings.compaction||(this.globalSettings.compaction={}),this.globalSettings.compaction.enabled=enabled,this.markModified("compaction","enabled"),this.save()}getCompactionReserveTokens(){return this.settings.compaction?.reserveTokens??16384}getCompactionKeepRecentTokens(){return this.settings.compaction?.keepRecentTokens??2e4}getCompactionSettings(){return{enabled:this.getCompactionEnabled(),reserveTokens:this.getCompactionReserveTokens(),keepRecentTokens:this.getCompactionKeepRecentTokens()}}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()}getRetrySettings(){return{enabled:this.getRetryEnabled(),maxRetries:this.settings.retry?.maxRetries??5,baseDelayMs:this.settings.retry?.baseDelayMs??2e3,maxAgentDelayMs:this.settings.retry?.maxAgentDelayMs??DEFAULT_MAX_AGENT_RETRY_DELAY_MS}}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()}getProviderRetrySettings(){return{timeoutMs:this.settings.retry?.provider?.timeoutMs,maxRetries:this.settings.retry?.provider?.maxRetries,maxRetryDelayMs:this.settings.retry?.provider?.maxRetryDelayMs??6e4}}getWebSocketConnectTimeoutMs(){return parseTimeoutSetting(this.settings.websocketConnectTimeoutMs,"websocketConnectTimeoutMs")}getHideThinkingBlock(){return this.settings.hideThinkingBlock??!1}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()}setShowCacheMissNotices(show){this.globalSettings.showCacheMissNotices=show,this.markModified("showCacheMissNotices"),this.save()}getShellPath(){let shellPath=this.settings.shellPath;return shellPath&&normalizePath(shellPath)}setShellPath(path15){this.globalSettings.shellPath=path15,this.markModified("shellPath"),this.save()}getQuietStartup(){return this.settings.quietStartup??!1}setQuietStartup(quiet){this.globalSettings.quietStartup=quiet,this.markModified("quietStartup"),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()}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=randomUUID15(),this.markModified("trackingId")),this.save()}getPackages(){return[...this.settings.packages??[]]}setPackages(packages){this.globalSettings.packages=packages,this.markModified("packages"),this.save()}setProjectPackages(packages){this.updateProjectSettings("packages",settings2=>{settings2.packages=packages})}getSkillPaths(){return[...this.settings.skills??[]]}setSkillPaths(paths){this.globalSettings.skills=paths,this.markModified("skills"),this.save()}setProjectSkillPaths(paths){this.updateProjectSettings("skills",settings2=>{settings2.skills=paths})}getPromptTemplatePaths(){return[...this.settings.prompts??[]]}setPromptTemplatePaths(paths){this.globalSettings.prompts=paths,this.markModified("prompts"),this.save()}setProjectPromptTemplatePaths(paths){this.updateProjectSettings("prompts",settings2=>{settings2.prompts=paths})}getThemePaths(){return[...this.settings.themes??[]]}setThemePaths(paths){this.globalSettings.themes=paths,this.markModified("themes"),this.save()}setProjectThemePaths(paths){this.updateProjectSettings("themes",settings2=>{settings2.themes=paths})}setProjectSuite(id){this.updateProjectSettings("suite",settings2=>{if(id===void 0){delete settings2.suite;return}settings2.suite=id})}setSuite(id){id===void 0?delete this.globalSettings.suite:this.globalSettings.suite=id,this.markModified("suite"),this.save()}getEnableSkillCommands(){return this.settings.enableSkillCommands??!0}setEnableSkillCommands(enabled){this.globalSettings.enableSkillCommands=enabled,this.markModified("enableSkillCommands"),this.save()}getThinkingBudgets(){return this.settings.thinkingBudgets}getTerminalCapabilityOverrides(){let terminal=this.settings.terminal,images=terminal?.images;return{...images==="kitty"||images==="iterm2"?{images}:images===!1?{images:null}:{},...typeof terminal?.trueColor=="boolean"?{trueColor:terminal.trueColor}:{},...typeof terminal?.hyperlinks=="boolean"?{hyperlinks:terminal.hyperlinks}:{}}}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()}getClearOnShrink(){if(this.settings.terminal?.clearOnShrink!==void 0)return this.settings.terminal.clearOnShrink;let configuredValue=process.env.AGENT_FORGE_CLEAR_ON_SHRINK;return configuredValue===void 0?process.env.PI_CLEAR_ON_SHRINK==="1":configuredValue==="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()}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}setBlockImages(blocked){this.globalSettings.images||(this.globalSettings.images={}),this.globalSettings.images.blockImages=blocked,this.markModified("images","blockImages"),this.save()}getEnabledModels(){return this.settings.enabledModels}getDefaultTools(){let tools=this.settings.defaultTools;return tools?[...tools]:void 0}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(){if(this.settings.showHardwareCursor!==void 0)return this.settings.showHardwareCursor;let configuredValue=process.env.AGENT_FORGE_HARDWARE_CURSOR;return configuredValue===void 0?process.env.PI_HARDWARE_CURSOR==="1":configuredValue==="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()}};import{existsSync as existsSync19,readdirSync as readdirSync13,readFileSync as readFileSync18,statSync as statSync15}from"node:fs";import{basename as basename12,dirname as dirname26,join as join45,resolve as resolve16,sep as sep10}from"node:path";import{execFile,spawnSync as spawnSync4}from"child_process";import{existsSync as existsSync18,readFileSync as readFileSync17,statSync as statSync14,unwatchFile,watchFile}from"fs";import{dirname as dirname25,join as join44,resolve as resolve15}from"path";function findGitPaths(cwd){let dir=cwd;for(;;){let gitPath=join44(dir,".git");if(existsSync18(gitPath))try{let stat5=statSync14(gitPath);if(stat5.isFile()){let content=readFileSync17(gitPath,"utf8").trim();if(content.startsWith("gitdir: ")){let gitDir=resolve15(dir,content.slice(8).trim()),headPath=join44(gitDir,"HEAD");if(!existsSync18(headPath))return null;let commonDirPath=join44(gitDir,"commondir"),commonGitDir=existsSync18(commonDirPath)?resolve15(gitDir,readFileSync17(commonDirPath,"utf8").trim()):gitDir;return{repoDir:dir,commonGitDir,headPath}}}else if(stat5.isDirectory()){let headPath=join44(gitPath,"HEAD");return existsSync18(headPath)?{repoDir:dir,commonGitDir:gitPath,headPath}:null}}catch{return null}let parent=dirname25(dir);if(parent===dir)return null;dir=parent}}function resolveBranchWithGitSync(repoDir){let result=spawnSync4("git",["--no-optional-locks","symbolic-ref","--quiet","--short","HEAD"],{cwd:repoDir,encoding:"utf8",stdio:["ignore","pipe","ignore"]});return(result.status===0?result.stdout.trim():"")||null}function resolveBranchWithGitAsync(repoDir){return new Promise(resolvePromise=>{execFile("git",["--no-optional-locks","symbolic-ref","--quiet","--short","HEAD"],{cwd:repoDir,encoding:"utf8"},(error2,stdout)=>{if(error2){resolvePromise(null);return}let branch=stdout.trim();resolvePromise(branch||null)})})}function isWslEnvironment(){return process.platform==="linux"&&!!(process.env.WSL_DISTRO_NAME||process.env.WSL_INTEROP)}function isWindowsMountedRepoPath(repoDir){return/^\/mnt\/[a-z](?:\/|$)/i.test(repoDir)}function shouldPollGitHead(repoDir){return isWslEnvironment()&&isWindowsMountedRepoPath(repoDir)}var FooterDataProvider=class _FooterDataProvider{cwd;static WATCH_DEBOUNCE_MS=500;cachedBranch=void 0;gitPaths=void 0;headWatcher=null;headWatchFilePath=null;headWatchFileListener=null;reftableWatcher=null;reftableTablesListWatcher=null;reftableTablesListPath=null;branchChangeCallbacks=new Set;availableProviderCount=0;refreshTimer=null;gitWatcherRetryTimer=null;refreshInFlight=!1;refreshPending=!1;disposed=!1;constructor(cwd){this.cwd=cwd,this.gitPaths=findGitPaths(cwd),this.setupGitWatcher()}getGitBranch(){return this.cachedBranch===void 0&&(this.cachedBranch=this.resolveGitBranchSync()),this.cachedBranch}onBranchChange(callback){return this.branchChangeCallbacks.add(callback),()=>this.branchChangeCallbacks.delete(callback)}getAvailableProviderCount(){return this.availableProviderCount}setAvailableProviderCount(count){this.availableProviderCount=count}setCwd(cwd){this.cwd!==cwd&&(this.cwd=cwd,this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null),this.clearGitWatchers(),this.cachedBranch=void 0,this.gitPaths=findGitPaths(cwd),this.setupGitWatcher(),this.notifyBranchChange())}dispose(){this.disposed=!0,this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null),this.clearGitWatchers(),this.branchChangeCallbacks.clear()}notifyBranchChange(){for(let cb of this.branchChangeCallbacks)cb()}scheduleRefresh(){if(!(this.disposed||this.refreshTimer)){if(this.refreshInFlight){this.refreshPending=!0;return}this.refreshTimer=setTimeout(()=>{this.refreshTimer=null,this.refreshGitBranchAsync()},_FooterDataProvider.WATCH_DEBOUNCE_MS)}}async refreshGitBranchAsync(){if(!this.disposed){if(this.refreshInFlight){this.refreshPending=!0;return}this.refreshInFlight=!0;try{let nextBranch=await this.resolveGitBranchAsync();if(this.disposed)return;if(this.cachedBranch!==void 0&&this.cachedBranch!==nextBranch){this.cachedBranch=nextBranch,this.notifyBranchChange();return}this.cachedBranch=nextBranch}finally{this.refreshInFlight=!1,this.refreshPending&&!this.disposed&&(this.refreshPending=!1,this.scheduleRefresh())}}}resolveGitBranchSync(){try{if(!this.gitPaths)return null;let content=readFileSync17(this.gitPaths.headPath,"utf8").trim();if(content.startsWith("ref: refs/heads/")){let branch=content.slice(16);return branch===".invalid"?resolveBranchWithGitSync(this.gitPaths.repoDir)??"detached":branch}return"detached"}catch{return null}}async resolveGitBranchAsync(){try{if(!this.gitPaths)return null;let content=readFileSync17(this.gitPaths.headPath,"utf8").trim();if(content.startsWith("ref: refs/heads/")){let branch=content.slice(16);return branch===".invalid"?await resolveBranchWithGitAsync(this.gitPaths.repoDir)??"detached":branch}return"detached"}catch{return null}}clearGitWatchers(){closeWatcher(this.headWatcher),this.headWatcher=null,this.headWatchFilePath&&this.headWatchFileListener&&(unwatchFile(this.headWatchFilePath,this.headWatchFileListener),this.headWatchFilePath=null,this.headWatchFileListener=null),closeWatcher(this.reftableWatcher),this.reftableWatcher=null,closeWatcher(this.reftableTablesListWatcher),this.reftableTablesListWatcher=null,this.reftableTablesListPath&&(unwatchFile(this.reftableTablesListPath),this.reftableTablesListPath=null),this.gitWatcherRetryTimer&&(clearTimeout(this.gitWatcherRetryTimer),this.gitWatcherRetryTimer=null)}scheduleGitWatcherRetry(){this.disposed||this.gitWatcherRetryTimer||(this.gitWatcherRetryTimer=setTimeout(()=>{this.gitWatcherRetryTimer=null,this.setupGitWatcher()},FS_WATCH_RETRY_DELAY_MS))}handleGitWatcherError(){this.clearGitWatchers(),this.scheduleGitWatcherRetry()}setupGitWatcher(){if(this.clearGitWatchers(),!this.gitPaths)return;let pollGitHead=shouldPollGitHead(this.gitPaths.repoDir);if(this.headWatcher=watchWithErrorHandler(dirname25(this.gitPaths.headPath),(_eventType,filename)=>{(!filename||filename==="HEAD")&&this.scheduleRefresh()},()=>this.handleGitWatcherError()),pollGitHead&&(this.headWatchFilePath=this.gitPaths.headPath,this.headWatchFileListener=(current,previous)=>{(current.mtimeMs!==previous.mtimeMs||current.ctimeMs!==previous.ctimeMs||current.size!==previous.size)&&this.scheduleRefresh()},watchFile(this.headWatchFilePath,{interval:1e3},this.headWatchFileListener)),!this.headWatcher&&!pollGitHead)return;let reftableDir=join44(this.gitPaths.commonGitDir,"reftable");if(existsSync18(reftableDir)){if(this.reftableWatcher=watchWithErrorHandler(reftableDir,()=>{this.scheduleRefresh()},()=>this.handleGitWatcherError()),!this.reftableWatcher)return;let tablesListPath=join44(reftableDir,"tables.list");if(existsSync18(tablesListPath)){if(this.reftableTablesListPath=tablesListPath,this.reftableTablesListWatcher=watchWithErrorHandler(tablesListPath,()=>{this.scheduleRefresh()},()=>this.handleGitWatcherError()),!this.reftableTablesListWatcher)return;watchFile(tablesListPath,{interval:250},(current,previous)=>{(current.mtimeMs!==previous.mtimeMs||current.ctimeMs!==previous.ctimeMs||current.size!==previous.size)&&this.scheduleRefresh()})}}}};function resolvePromptInput(input,description){if(input){if(existsSync19(input))try{return stripBom(readFileSync18(input,"utf-8"))}catch(error2){return console.error(source_default.yellow(`Warning: Could not read ${description} file ${input}: ${error2}`)),input}return input}}function loadContextFileFromDir(dir){let candidates=["AGENTS.override.md","AGENTS.md","AGENTS.MD","CLAUDE.md","CLAUDE.MD"];for(let filename of candidates){let filePath=join45(dir,filename);if(existsSync19(filePath))try{if(!statSync15(filePath).isFile())continue;return{path:filePath,content:stripBom(readFileSync18(filePath,"utf-8"))}}catch(error2){console.error(source_default.yellow(`Warning: Could not read ${filePath}: ${error2}`))}}return null}function findShadowedContextFile(cwd){let gitPaths=findGitPaths(cwd);if(!gitPaths)return;let commonGitDir=canonicalizePath(gitPaths.commonGitDir),worktreeRoot=canonicalizePath(gitPaths.repoDir),mainRepoRoot=dirname26(commonGitDir);if(!worktreeRoot.startsWith(`${mainRepoRoot}${sep10}`)||canonicalizePath(join45(mainRepoRoot,".git"))!==commonGitDir)return;let worktreeContextFile=loadContextFileFromDir(worktreeRoot);return worktreeContextFile?join45(mainRepoRoot,basename12(worktreeContextFile.path)):void 0}function loadProjectContextFiles(options){let resolvedCwd=resolvePath(options.cwd),resolvedAgentDir=resolvePath(options.agentDir),contextFiles=[],seenPaths=new Set,globalContext=loadContextFileFromDir(resolvedAgentDir);globalContext&&(contextFiles.push(globalContext),seenPaths.add(globalContext.path));let ancestorContextFiles=[],shadowedContextFile=findShadowedContextFile(resolvedCwd),currentDir=resolvedCwd;for(;;){let contextFile=loadContextFileFromDir(currentDir),isShadowed=shadowedContextFile!==void 0&&canonicalizePath(contextFile?.path??"")===shadowedContextFile;contextFile&&!isShadowed&&!seenPaths.has(contextFile.path)&&(ancestorContextFiles.unshift(contextFile),seenPaths.add(contextFile.path));let parentDir=dirname26(currentDir);if(parentDir===currentDir)break;currentDir=parentDir}return contextFiles.push(...ancestorContextFiles),contextFiles}var DefaultResourceLoader=class{cwd;agentDir;settingsManager;packageManager;additionalSkillPaths;additionalPromptTemplatePaths;additionalThemePaths;noSkills;noPromptTemplates;noThemes;noContextFiles;systemPromptSource;appendSystemPromptSource;skillsOverride;promptsOverride;themesOverride;agentsFilesOverride;systemPromptOverride;appendSystemPromptOverride;skills;skillDiagnostics;prompts;promptDiagnostics;themes;themeDiagnostics;agentsFiles;systemPrompt;systemPromptSourcePath;appendSystemPrompt;appendSystemPromptSourcePaths;lastSkillPaths;extensionSkillSourceInfos;extensionPromptSourceInfos;extensionThemeSourceInfos;resourceMetadataByPath;lastPromptPaths;lastThemePaths;constructor(options){this.cwd=resolvePath(options.cwd),this.agentDir=resolvePath(options.agentDir),this.settingsManager=options.settingsManager??SettingsManager.create(this.cwd,this.agentDir),this.packageManager=new DefaultPackageManager({cwd:this.cwd,agentDir:this.agentDir,settingsManager:this.settingsManager}),this.additionalSkillPaths=options.additionalSkillPaths??[],this.additionalPromptTemplatePaths=options.additionalPromptTemplatePaths??[],this.additionalThemePaths=options.additionalThemePaths??[],this.noSkills=options.noSkills??!1,this.noPromptTemplates=options.noPromptTemplates??!1,this.noThemes=options.noThemes??!1,this.noContextFiles=options.noContextFiles??!1,this.systemPromptSource=options.systemPrompt,this.appendSystemPromptSource=options.appendSystemPrompt,this.skillsOverride=options.skillsOverride,this.promptsOverride=options.promptsOverride,this.themesOverride=options.themesOverride,this.agentsFilesOverride=options.agentsFilesOverride,this.systemPromptOverride=options.systemPromptOverride,this.appendSystemPromptOverride=options.appendSystemPromptOverride,this.skills=[],this.skillDiagnostics=[],this.prompts=[],this.promptDiagnostics=[],this.themes=[],this.themeDiagnostics=[],this.agentsFiles=[],this.appendSystemPrompt=[],this.appendSystemPromptSourcePaths=[],this.lastSkillPaths=[],this.extensionSkillSourceInfos=new Map,this.extensionPromptSourceInfos=new Map,this.extensionThemeSourceInfos=new Map,this.resourceMetadataByPath=new Map,this.lastPromptPaths=[],this.lastThemePaths=[]}getSkills(){return{skills:this.skills.slice(),diagnostics:this.skillDiagnostics.slice()}}getPrompts(){return{prompts:this.prompts.slice(),diagnostics:this.promptDiagnostics.slice()}}getThemes(){return{themes:this.themes.slice(),diagnostics:this.themeDiagnostics.slice()}}getAgentsFiles(){return{agentsFiles:this.agentsFiles.slice()}}getSystemPrompt(){return this.systemPrompt}getSystemPromptSource(){return this.systemPromptSourcePath?{path:this.systemPromptSourcePath}:void 0}getAppendSystemPrompt(){return this.appendSystemPrompt}getAppendSystemPromptSources(){return this.appendSystemPromptSourcePaths.map(path15=>({path:path15}))}extendResources(paths){let skillPaths=this.normalizeExtensionPaths(paths.skillPaths??[]),promptPaths=this.normalizeExtensionPaths(paths.promptPaths??[]),themePaths=this.normalizeExtensionPaths(paths.themePaths??[]);for(let entry of skillPaths)this.extensionSkillSourceInfos.set(entry.path,createSourceInfo(entry.path,entry.metadata));for(let entry of promptPaths)this.extensionPromptSourceInfos.set(entry.path,createSourceInfo(entry.path,entry.metadata));for(let entry of themePaths)this.extensionThemeSourceInfos.set(entry.path,createSourceInfo(entry.path,entry.metadata));skillPaths.length>0&&(this.lastSkillPaths=this.mergePaths(this.lastSkillPaths,skillPaths.map(entry=>entry.path)),this.updateSkillsFromPaths(this.lastSkillPaths,this.resourceMetadataByPath)),promptPaths.length>0&&(this.lastPromptPaths=this.mergePaths(this.lastPromptPaths,promptPaths.map(entry=>entry.path)),this.updatePromptsFromPaths(this.lastPromptPaths,this.resourceMetadataByPath)),themePaths.length>0&&(this.lastThemePaths=this.mergePaths(this.lastThemePaths,themePaths.map(entry=>entry.path)),this.updateThemesFromPaths(this.lastThemePaths,this.resourceMetadataByPath))}async reload(_options){await this.settingsManager.reload();let resolvedPaths=await this.packageManager.resolve();this.resourceMetadataByPath=new Map;let metadataByPath=this.resourceMetadataByPath;this.extensionSkillSourceInfos=new Map,this.extensionPromptSourceInfos=new Map,this.extensionThemeSourceInfos=new Map;let getEnabledResources=resources=>{for(let r of resources)metadataByPath.has(r.path)||metadataByPath.set(r.path,r.metadata);return resources.filter(r=>r.enabled)},getEnabledPaths=resources=>getEnabledResources(resources).map(r=>r.path),enabledSkillResources=getEnabledResources(resolvedPaths.skills),enabledPrompts=getEnabledPaths(resolvedPaths.prompts),enabledThemes=getEnabledPaths(resolvedPaths.themes),enabledSkills=enabledSkillResources.map(resource=>this.mapSkillPath(resource,metadataByPath)),skillPaths=this.noSkills?[...this.additionalSkillPaths]:this.mergePaths(enabledSkills,this.additionalSkillPaths);this.lastSkillPaths=skillPaths,this.updateSkillsFromPaths(skillPaths,metadataByPath);for(let p of this.additionalSkillPaths)if(isLocalPath(p)){let resolved=this.resolveResourcePath(p);!existsSync19(resolved)&&!this.skillDiagnostics.some(d2=>d2.path===resolved)&&this.skillDiagnostics.push({type:"error",message:"Skill path does not exist",path:resolved})}let promptPaths=this.noPromptTemplates?[...this.additionalPromptTemplatePaths]:this.mergePaths(enabledPrompts,this.additionalPromptTemplatePaths);this.lastPromptPaths=promptPaths,this.updatePromptsFromPaths(promptPaths,metadataByPath);for(let p of this.additionalPromptTemplatePaths)if(isLocalPath(p)){let resolved=this.resolveResourcePath(p);!existsSync19(resolved)&&!this.promptDiagnostics.some(d2=>d2.path===resolved)&&this.promptDiagnostics.push({type:"error",message:"Prompt template path does not exist",path:resolved})}let themePaths=this.noThemes?[...this.additionalThemePaths]:this.mergePaths(enabledThemes,this.additionalThemePaths);this.lastThemePaths=themePaths,this.updateThemesFromPaths(themePaths,metadataByPath);for(let p of this.additionalThemePaths){let resolved=this.resolveResourcePath(p);!existsSync19(resolved)&&!this.themeDiagnostics.some(d2=>d2.path===resolved)&&this.themeDiagnostics.push({type:"error",message:"Theme path does not exist",path:resolved})}let agentsFiles={agentsFiles:this.noContextFiles?[]:loadProjectContextFiles({cwd:this.cwd,agentDir:this.agentDir})},resolvedAgentsFiles=this.agentsFilesOverride?this.agentsFilesOverride(agentsFiles):agentsFiles;this.agentsFiles=resolvedAgentsFiles.agentsFiles;let systemPromptSource=this.systemPromptSource??this.discoverSystemPromptFile(),baseSystemPrompt=resolvePromptInput(systemPromptSource,"system prompt");this.systemPrompt=this.systemPromptOverride?this.systemPromptOverride(baseSystemPrompt):baseSystemPrompt,this.systemPromptSourcePath=systemPromptSource&&existsSync19(systemPromptSource)?resolvePath(systemPromptSource):void 0;let appendSources=this.appendSystemPromptSource;if(!appendSources){let discoveredAppendSystemPromptFile=this.discoverAppendSystemPromptFile();appendSources=discoveredAppendSystemPromptFile?[discoveredAppendSystemPromptFile]:[]}let baseAppend=appendSources.map(s=>resolvePromptInput(s,"append system prompt")).filter(s=>s!==void 0);this.appendSystemPrompt=this.appendSystemPromptOverride?this.appendSystemPromptOverride(baseAppend):baseAppend,this.appendSystemPromptSourcePaths=appendSources.filter(source=>existsSync19(source)).map(source=>resolvePath(source))}mapSkillPath(resource,metadataByPath){if(resource.metadata.source!=="auto"&&resource.metadata.origin!=="package")return resource.path;try{if(!statSync15(resource.path).isDirectory())return resource.path}catch{return resource.path}let skillFile=join45(resource.path,"SKILL.md");return existsSync19(skillFile)?(metadataByPath.has(skillFile)||metadataByPath.set(skillFile,resource.metadata),skillFile):resource.path}normalizeExtensionPaths(entries){return entries.map(entry=>{let metadata=entry.metadata.baseDir?{...entry.metadata,baseDir:this.resolveResourcePath(entry.metadata.baseDir)}:entry.metadata;return{path:this.resolveResourcePath(entry.path),metadata}})}updateSkillsFromPaths(skillPaths,metadataByPath){let skillsResult;this.noSkills&&skillPaths.length===0?skillsResult={skills:[],diagnostics:[]}:skillsResult=loadSkills({cwd:this.cwd,agentDir:this.agentDir,skillPaths,includeDefaults:!1});let applySourceInfo=skill=>({...skill,sourceInfo:this.findSourceInfoForPath(skill.filePath,this.extensionSkillSourceInfos,metadataByPath)??skill.sourceInfo??this.getDefaultSourceInfoForPath(skill.filePath)});skillsResult={skills:skillsResult.skills.map(applySourceInfo),diagnostics:skillsResult.diagnostics};let resolvedSkills=this.skillsOverride?this.skillsOverride(skillsResult):skillsResult;this.skills=resolvedSkills.skills.map(applySourceInfo),this.skillDiagnostics=resolvedSkills.diagnostics}updatePromptsFromPaths(promptPaths,metadataByPath){let promptsResult;if(this.noPromptTemplates&&promptPaths.length===0)promptsResult={prompts:[],diagnostics:[]};else{let allPrompts=loadPromptTemplates({cwd:this.cwd,agentDir:this.agentDir,promptPaths,includeDefaults:!1});promptsResult=this.dedupePrompts(allPrompts)}let resolvedPrompts=this.promptsOverride?this.promptsOverride(promptsResult):promptsResult;this.prompts=resolvedPrompts.prompts.map(prompt=>({...prompt,sourceInfo:this.findSourceInfoForPath(prompt.filePath,this.extensionPromptSourceInfos,metadataByPath)??prompt.sourceInfo??this.getDefaultSourceInfoForPath(prompt.filePath)})),this.promptDiagnostics=resolvedPrompts.diagnostics}updateThemesFromPaths(themePaths,metadataByPath){let loadedThemes,themeDiagnostics;if(this.noThemes&&themePaths.length===0)loadedThemes=[],themeDiagnostics=[];else{let loaded=this.loadThemes(themePaths,!1),deduped=this.dedupeThemes(loaded.themes);loadedThemes=deduped.themes,themeDiagnostics=[...loaded.diagnostics,...deduped.diagnostics]}let themesResult={themes:loadedThemes.map(theme2=>this.buildThemeMeta(theme2,metadataByPath)),diagnostics:themeDiagnostics},resolvedThemes=this.themesOverride?this.themesOverride(themesResult):themesResult;this.themes=resolvedThemes.themes.map(meta=>this.buildThemeMeta(meta,metadataByPath)),this.themeDiagnostics=resolvedThemes.diagnostics}buildThemeMeta(source,metadataByPath){let sourcePath=source.sourcePath??"";return{name:source.name,sourcePath,sourceInfo:sourcePath?this.findSourceInfoForPath(sourcePath,this.extensionThemeSourceInfos,metadataByPath)??source.sourceInfo??this.getDefaultSourceInfoForPath(sourcePath):source.sourceInfo}}findSourceInfoForPath(resourcePath,extraSourceInfos,metadataByPath){if(!resourcePath)return;if(resourcePath.startsWith("<"))return this.getDefaultSourceInfoForPath(resourcePath);let normalizedResourcePath=resolve16(resourcePath);if(extraSourceInfos)for(let[sourcePath,sourceInfo]of extraSourceInfos.entries()){let normalizedSourcePath=resolve16(sourcePath);if(normalizedResourcePath===normalizedSourcePath||normalizedResourcePath.startsWith(`${normalizedSourcePath}${sep10}`))return{...sourceInfo,path:resourcePath}}if(metadataByPath){let exact=metadataByPath.get(normalizedResourcePath)??metadataByPath.get(resourcePath);if(exact)return createSourceInfo(resourcePath,exact);for(let[sourcePath,metadata]of metadataByPath.entries()){let normalizedSourcePath=resolve16(sourcePath);if(normalizedResourcePath===normalizedSourcePath||normalizedResourcePath.startsWith(`${normalizedSourcePath}${sep10}`))return createSourceInfo(resourcePath,metadata)}}}getDefaultSourceInfoForPath(filePath){if(filePath.startsWith("<")&&filePath.endsWith(">"))return{path:filePath,source:filePath.slice(1,-1).split(":")[0]||"temporary",scope:"temporary",origin:"top-level"};let normalizedPath=resolve16(filePath),agentRoots=[join45(this.agentDir,"skills"),join45(this.agentDir,"prompts"),join45(this.agentDir,"themes")],projectRoots=[join45(this.cwd,CONFIG_DIR_NAME,"skills"),join45(this.cwd,CONFIG_DIR_NAME,"prompts"),join45(this.cwd,CONFIG_DIR_NAME,"themes")];for(let root of agentRoots)if(this.isUnderPath(normalizedPath,root))return{path:filePath,source:"local",scope:"user",origin:"top-level",baseDir:root};for(let root of projectRoots)if(this.isUnderPath(normalizedPath,root))return{path:filePath,source:"local",scope:"project",origin:"top-level",baseDir:root};return{path:filePath,source:"local",scope:"temporary",origin:"top-level",baseDir:statSync15(normalizedPath).isDirectory()?normalizedPath:resolve16(normalizedPath,"..")}}mergePaths(primary,additional){let merged=[],seen=new Set;for(let p of[...primary,...additional]){let resolved=this.resolveResourcePath(p),canonicalPath=canonicalizePath(resolved);seen.has(canonicalPath)||(seen.add(canonicalPath),merged.push(resolved))}return merged}resolveResourcePath(p){return resolvePath(p,this.cwd,{trim:!0})}loadThemes(paths,includeDefaults=!0){let themes=[],diagnostics=[];if(includeDefaults){let defaultDirs=[join45(this.agentDir,"themes"),join45(this.cwd,CONFIG_DIR_NAME,"themes")];for(let dir of defaultDirs)this.loadThemesFromDir(dir,themes,diagnostics)}for(let p of paths){let resolved=this.resolveResourcePath(p);if(!existsSync19(resolved)){diagnostics.push({type:"warning",message:"theme path does not exist",path:resolved});continue}try{let stats=statSync15(resolved);stats.isDirectory()?this.loadThemesFromDir(resolved,themes,diagnostics):stats.isFile()&&resolved.endsWith(".json")?this.loadThemeFromFile(resolved,themes,diagnostics):diagnostics.push({type:"warning",message:"theme path is not a json file",path:resolved})}catch(error2){let message=error2 instanceof Error?error2.message:"failed to read theme path";diagnostics.push({type:"warning",message,path:resolved})}}return{themes,diagnostics}}loadThemesFromDir(dir,themes,diagnostics){if(existsSync19(dir))try{let entries=readdirSync13(dir,{withFileTypes:!0});for(let entry of entries){let isFile=entry.isFile();if(entry.isSymbolicLink())try{isFile=statSync15(join45(dir,entry.name)).isFile()}catch{continue}isFile&&entry.name.endsWith(".json")&&this.loadThemeFromFile(join45(dir,entry.name),themes,diagnostics)}}catch(error2){let message=error2 instanceof Error?error2.message:"failed to read theme directory";diagnostics.push({type:"warning",message,path:dir})}}loadThemeFromFile(filePath,themes,diagnostics){try{themes.push(loadThemeFromPath(filePath))}catch(error2){let message=error2 instanceof Error?error2.message:"failed to load theme";diagnostics.push({type:"warning",message,path:filePath})}}dedupePrompts(prompts){let seen=new Map,diagnostics=[];for(let prompt of prompts){let existing=seen.get(prompt.name);existing?diagnostics.push({type:"collision",message:`name "/${prompt.name}" collision`,path:prompt.filePath,collision:{resourceType:"prompt",name:prompt.name,winnerPath:existing.filePath,loserPath:prompt.filePath}}):seen.set(prompt.name,prompt)}return{prompts:Array.from(seen.values()),diagnostics}}dedupeThemes(themes){let seen=new Map,diagnostics=[];for(let t of themes){let name=t.name??"unnamed",existing=seen.get(name);existing?diagnostics.push({type:"collision",message:`name "${name}" collision`,path:t.sourcePath,collision:{resourceType:"theme",name,winnerPath:existing.sourcePath??"<builtin>",loserPath:t.sourcePath??"<builtin>"}}):seen.set(name,t)}return{themes:Array.from(seen.values()),diagnostics}}discoverSystemPromptFile(){let projectPath=join45(this.cwd,CONFIG_DIR_NAME,"SYSTEM.md");if(existsSync19(projectPath))return projectPath;let globalPath=join45(this.agentDir,"SYSTEM.md");if(existsSync19(globalPath))return globalPath}discoverAppendSystemPromptFile(){let projectPath=join45(this.cwd,CONFIG_DIR_NAME,"APPEND_SYSTEM.md");if(existsSync19(projectPath))return projectPath;let globalPath=join45(this.agentDir,"APPEND_SYSTEM.md");if(existsSync19(globalPath))return globalPath}isUnderPath(target,root){let normalizedRoot=resolve16(root);if(target===normalizedRoot)return!0;let prefix=normalizedRoot.endsWith(sep10)?normalizedRoot:`${normalizedRoot}${sep10}`;return target.startsWith(prefix)}};import{existsSync as existsSync23,mkdirSync as mkdirSync15,readFileSync as readFileSync20,writeFileSync as writeFileSync12}from"node:fs";import{isAbsolute as isAbsolute10,join as join50,relative as relative8,sep as sep11}from"node:path";import{fileURLToPath as fileURLToPath5}from"node:url";import{existsSync as existsSync22,realpathSync as realpathSync4}from"node:fs";import{readFile as readFile9}from"node:fs/promises";import{join as join49,resolve as resolve18}from"node:path";var import_semver5=__toESM(require_semver2(),1);var BUILTIN_CAPABILITY_PACKAGE_IDS=Object.freeze({"builtin.goal":"agent-forge.plugin.goal","builtin.plan":"agent-forge.plugin.plan","builtin.todo-set":"agent-forge.plugin.todo-set","builtin.session-share":"agent-forge.plugin.session-share","builtin.subagent-delegate":"agent-forge.plugin.subagent-delegate","builtin.memory":"agent-forge.plugin.memory"});import{constants as constants7,copyFileSync,existsSync as existsSync21,mkdirSync as mkdirSync13}from"node:fs";import{basename as basename13,join as join46,parse as parse4,resolve as resolve17}from"node:path";import{existsSync as existsSync20}from"node:fs";function getMissingSessionCwdIssue(sessionManager,fallbackCwd){let sessionFile=sessionManager.getSessionFile();if(!sessionFile)return;let sessionCwd=sessionManager.getCwd();if(!(!sessionCwd||existsSync20(sessionCwd)))return{sessionFile,sessionCwd,fallbackCwd}}function formatMissingSessionCwdError(issue){let sessionFile=issue.sessionFile?`
1058
1058
  Session file: ${issue.sessionFile}`:"";return`Stored session working directory does not exist: ${issue.sessionCwd}${sessionFile}
@@ -1487,7 +1487,7 @@ Auth commands require at least one of --provider or --model. Checks refresh expi
1487
1487
  ${content}
1488
1488
  </file>
1489
1489
  `}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(source_default.red(`Error: Could not read file ${absolutePath}: ${message}`)),process.exit(1)}}return{text,images}}function buildInitialMessage({parsed,fileText,fileImages,stdinContent}){let parts=[];return stdinContent!==void 0&&parts.push(stdinContent),fileText&&parts.push(fileText),parsed.messages.length>0&&(parts.push(parsed.messages[0]),parsed.messages.shift()),{initialMessage:parts.length>0?parts.join(""):void 0,initialImages:fileImages&&fileImages.length>0?fileImages:void 0}}function formatTokenCount(count){if(count>=1e6){let millions=count/1e6;return millions%1===0?`${millions}M`:`${millions.toFixed(1)}M`}if(count>=1e3){let thousands=count/1e3;return thousands%1===0?`${thousands}K`:`${thousands.toFixed(1)}K`}return count.toString()}async function listModels(modelRuntime,searchPattern,signal){let loadError=modelRuntime.getError();loadError&&console.error(source_default.yellow(`Warning: errors loading models.json:
1490
- ${loadError}`));let models=[...await modelRuntime.getAvailable(void 0,{signal})];if(models.length===0){console.log(formatNoModelsAvailableMessage());return}let filteredModels=models;if(searchPattern&&(filteredModels=fuzzyFilter(models,searchPattern,m2=>`${m2.provider} ${m2.id}`)),filteredModels.length===0){console.log(`No models matching "${searchPattern}"`);return}filteredModels.sort((a,b2)=>{let providerCmp=a.provider.localeCompare(b2.provider);return providerCmp!==0?providerCmp:a.id.localeCompare(b2.id)});let rows=filteredModels.map(m2=>({provider:m2.provider,model:m2.id,context:formatTokenCount(m2.contextWindow),maxOut:formatTokenCount(m2.maxTokens),thinking:m2.reasoning?"yes":"no",images:m2.input.includes("image")?"yes":"no"})),headers={provider:"provider",model:"model",context:"context",maxOut:"max-out",thinking:"thinking",images:"images"},widths={provider:Math.max(headers.provider.length,...rows.map(r=>r.provider.length)),model:Math.max(headers.model.length,...rows.map(r=>r.model.length)),context:Math.max(headers.context.length,...rows.map(r=>r.context.length)),maxOut:Math.max(headers.maxOut.length,...rows.map(r=>r.maxOut.length)),thinking:Math.max(headers.thinking.length,...rows.map(r=>r.thinking.length)),images:Math.max(headers.images.length,...rows.map(r=>r.images.length))},headerLine=[headers.provider.padEnd(widths.provider),headers.model.padEnd(widths.model),headers.context.padEnd(widths.context),headers.maxOut.padEnd(widths.maxOut),headers.thinking.padEnd(widths.thinking),headers.images.padEnd(widths.images)].join(" ");console.log(headerLine);for(let row of rows){let line=[row.provider.padEnd(widths.provider),row.model.padEnd(widths.model),row.context.padEnd(widths.context),row.maxOut.padEnd(widths.maxOut),row.thinking.padEnd(widths.thinking),row.images.padEnd(widths.images)].join(" ");console.log(line)}}import{join as join59}from"node:path";var FACTORY_PLUGIN_RANGE=`^${VERSION}`,BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1=Object.freeze([{pluginId:"agent-forge.plugin.goal",npmName:"@ai-agent-forge/plugin-goal",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.plan",npmName:"@ai-agent-forge/plugin-plan",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.todo-set",npmName:"@ai-agent-forge/plugin-todo-set",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.session-share",npmName:"@ai-agent-forge/plugin-session-share",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.observability",npmName:"@ai-agent-forge/plugin-observability",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.subagent-delegate",npmName:"@ai-agent-forge/plugin-subagent-delegate",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.memory",npmName:"@ai-agent-forge/plugin-memory",range:FACTORY_PLUGIN_RANGE}]);function printResponse(response2,write){write(response2.text),response2.status!=="succeeded"&&(process.exitCode=1)}function buildMarketCli(options){let{market,overrides}=options;return createPluginEcosystemCliV1({host:overrides?.host??defaultPluginHostFactsV1(),manifests:listBuiltinPluginManifestsV1(),registry:overrides?.registry??market?.cliRegistry,...overrides?.acquisition===void 0&&market?.acquisition===void 0?{}:{acquisition:overrides?.acquisition??market?.acquisition},installer:overrides?.installer??market?.installer,...overrides?.distribution!==void 0||market?.distribution!==void 0?{distribution:overrides?.distribution??market.distribution}:{},stateStore:overrides?.stateStore??market?.stateStore??createPluginStateStoreV1({filePath:join59(options.agentDir,"plugin-state.json")}),projectStateStore:overrides?.projectStateStore??market?.projectStateStore??createPluginStateStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,"plugin-state.json")}),projectScopeRef:projectPluginScopeRefV1(options.cwd),selectionStore:overrides?.selectionStore??createPluginSelectionStoreV1({filePath:join59(options.agentDir,".plugin-selection.json")}),projectSelectionStore:overrides?.projectSelectionStore??createPluginSelectionStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,".plugin-selection.json")})})}async function createDefaultPluginManagerControllerV1(options){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=await createDefaultPluginMarketWiringV1({agentDir,cwd}),cli=buildMarketCli({agentDir,cwd,market});return{controller:createPluginManagerControllerV1({registry:market.registry,stateStore:options.scope==="project"?market.projectStateStore:market.stateStore,cli}),close:market.close}}async function handlePluginEcosystemCommand(args,options={}){if(args[0]!=="plugin")return!1;let write=options.write??(line=>console.log(line));if(args[1]==="update"&&args[2]==="--all")return await runBatchUpdate(args.slice(3),options,write),!0;let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let response2=await buildMarketCli({agentDir,cwd,market,overrides:options}).execute({argv:args.slice(1)});return printResponse(response2,write),!0}finally{await market?.close()}}async function runBatchUpdate(restArgs,options,write){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),scopeIndex=restArgs.indexOf("--scope"),scope=scopeIndex!==-1&&restArgs[scopeIndex+1]==="project"?"project":"global",market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let cli=buildMarketCli({agentDir,cwd,market,overrides:options}),listResponse=await cli.execute({argv:["state","list","--scope",scope]});if(listResponse.status!=="succeeded"){printResponse(listResponse,write);return}let entries=(listResponse.data?.entries??[]).filter(entry=>entry.lifecycle==="active"&&entry.scope===scope);if(entries.length===0){write("No active plugins to update.");return}let updated=[],current=[],failed=[];for(let entry of entries){let factoryEntry=BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1.find(item=>item.pluginId===entry.pluginId),argv=factoryEntry?["install",`${factoryEntry.npmName}@${factoryEntry.range??"latest"}`,"--scope",scope]:["update",entry.pluginId,"--scope",scope],response2=await cli.execute({argv});response2.status==="succeeded"?(updated.push(entry.pluginId),write(response2.text)):response2.error?.code==="already_installed"?current.push(entry.pluginId):(failed.push(entry.pluginId),write(response2.text))}let summary=[`updated ${updated.length}${updated.length>0?` (${updated.join(", ")})`:""}`,`already up to date ${current.length}${current.length>0?` (${current.join(", ")})`:""}`,`failed ${failed.length}${failed.length>0?` (${failed.join(", ")})`:""}`].join("; ");write(`plugin update --all [${scope}]: ${summary}`),failed.length>0&&(process.exitCode=1)}finally{await market?.close()}}import{join as join60}from"node:path";var DEFAULT_DURABLE_LOG_RELATIVE_PATH=join60("durable","remote-server-ops.jsonl");function isAddrInUse(error2){return typeof error2=="object"&&error2!==null&&error2.code==="EADDRINUSE"}async function runServeMode(port,options){let handle,createListener=options?.createListener??(()=>createWsServerListener({port,httpRequestHandler:(request,response2)=>handle?.server.handleArtifactHttpRequest(request,response2)??!1,onError:error2=>{console.error(`remote-server error: ${error2.message}`)}})),startServer=options?.startServer??startCodingAgentRemoteServer,workspaceRoots=options?.workspaceRoots,sessionDir=options?.sessionDir,durable=options?.durable??createDurableService({backend:createFileDurableStoreBackend({path:join60(getAgentDir(),DEFAULT_DURABLE_LOG_RELATIVE_PATH)})}),writerId=readOrCreateWriterId(getAgentDir());try{handle=await startServer({sessionSourceOptions:{sessionsDir:sessionDir??getSessionsDir(),cwd:process.cwd(),agentDir:getAgentDir(),...workspaceRoots===void 0||workspaceRoots.length===0?{}:{workspaceRoots},agentTaskResults:{store:durable,writerId},subagentPoolFromSelfInvocation:!0,...options?.hostLogger===void 0?{}:{hostLogger:options.hostLogger}},listeners:[createListener()],onError:error2=>{console.error(`remote-server error: ${error2.message}`)},durable,writerId})}catch(error2){throw isAddrInUse(error2)&&(console.error(`Port ${port} is already in use`),process.exit(1)),error2}let closing=!1,shutdown=()=>{closing||(closing=!0,handle.close().then(()=>{process.exit(0)}).catch(error2=>{console.error(`Remote server shutdown failed: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}))};process.on("SIGINT",shutdown),process.on("SIGTERM",shutdown),console.log(`Remote server listening on ${handle.addresses.join(", ")}`)}import{existsSync as existsSync29}from"fs";var THEME_OPTIONS=[{value:"dark",label:"Dark"},{value:"light",label:"Light"}],ANALYTICS_OPTIONS=[{value:!0,label:"Share anonymous usage data"},{value:!1,label:"Don't share"}],SETUP_LOGO_LINES=["\u2588\u2588\u2588\u2588\u2588\u2588","\u2588\u2588 \u2588\u2588","\u2588\u2588\u2588\u2588 \u2588\u2588","\u2588\u2588 \u2588\u2588"],FirstTimeSetupComponent=class extends Container{step="theme";themeIndex;analyticsIndex=0;options;constructor(options){super(),this.options=options,this.themeIndex=Math.max(0,THEME_OPTIONS.findIndex(option=>option.value===options.detectedTheme)),this.update()}update(){this.clear(),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",SETUP_LOGO_LINES.join(`
1490
+ ${loadError}`));let models=[...await modelRuntime.getAvailable(void 0,{signal})];if(models.length===0){console.log(formatNoModelsAvailableMessage());return}let filteredModels=models;if(searchPattern&&(filteredModels=fuzzyFilter(models,searchPattern,m2=>`${m2.provider} ${m2.id}`)),filteredModels.length===0){console.log(`No models matching "${searchPattern}"`);return}filteredModels.sort((a,b2)=>{let providerCmp=a.provider.localeCompare(b2.provider);return providerCmp!==0?providerCmp:a.id.localeCompare(b2.id)});let rows=filteredModels.map(m2=>({provider:m2.provider,model:m2.id,context:formatTokenCount(m2.contextWindow),maxOut:formatTokenCount(m2.maxTokens),thinking:m2.reasoning?"yes":"no",images:m2.input.includes("image")?"yes":"no"})),headers={provider:"provider",model:"model",context:"context",maxOut:"max-out",thinking:"thinking",images:"images"},widths={provider:Math.max(headers.provider.length,...rows.map(r=>r.provider.length)),model:Math.max(headers.model.length,...rows.map(r=>r.model.length)),context:Math.max(headers.context.length,...rows.map(r=>r.context.length)),maxOut:Math.max(headers.maxOut.length,...rows.map(r=>r.maxOut.length)),thinking:Math.max(headers.thinking.length,...rows.map(r=>r.thinking.length)),images:Math.max(headers.images.length,...rows.map(r=>r.images.length))},headerLine=[headers.provider.padEnd(widths.provider),headers.model.padEnd(widths.model),headers.context.padEnd(widths.context),headers.maxOut.padEnd(widths.maxOut),headers.thinking.padEnd(widths.thinking),headers.images.padEnd(widths.images)].join(" ");console.log(headerLine);for(let row of rows){let line=[row.provider.padEnd(widths.provider),row.model.padEnd(widths.model),row.context.padEnd(widths.context),row.maxOut.padEnd(widths.maxOut),row.thinking.padEnd(widths.thinking),row.images.padEnd(widths.images)].join(" ");console.log(line)}}import{join as join59}from"node:path";var FACTORY_PLUGIN_RANGE=`^${VERSION}`,BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1=Object.freeze([{pluginId:"agent-forge.plugin.goal",npmName:"@ai-agent-forge/plugin-goal",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.plan",npmName:"@ai-agent-forge/plugin-plan",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.todo-set",npmName:"@ai-agent-forge/plugin-todo-set",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.session-share",npmName:"@ai-agent-forge/plugin-session-share",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.observability",npmName:"@ai-agent-forge/plugin-observability",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.subagent-delegate",npmName:"@ai-agent-forge/plugin-subagent-delegate",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.memory",npmName:"@ai-agent-forge/plugin-memory",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.image-generation",npmName:"@ai-agent-forge/plugin-image-generation",range:FACTORY_PLUGIN_RANGE}]);function printResponse(response2,write){write(response2.text),response2.status!=="succeeded"&&(process.exitCode=1)}function buildMarketCli(options){let{market,overrides}=options;return createPluginEcosystemCliV1({host:overrides?.host??defaultPluginHostFactsV1(),manifests:listBuiltinPluginManifestsV1(),registry:overrides?.registry??market?.cliRegistry,...overrides?.acquisition===void 0&&market?.acquisition===void 0?{}:{acquisition:overrides?.acquisition??market?.acquisition},installer:overrides?.installer??market?.installer,...overrides?.distribution!==void 0||market?.distribution!==void 0?{distribution:overrides?.distribution??market.distribution}:{},stateStore:overrides?.stateStore??market?.stateStore??createPluginStateStoreV1({filePath:join59(options.agentDir,"plugin-state.json")}),projectStateStore:overrides?.projectStateStore??market?.projectStateStore??createPluginStateStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,"plugin-state.json")}),projectScopeRef:projectPluginScopeRefV1(options.cwd),selectionStore:overrides?.selectionStore??createPluginSelectionStoreV1({filePath:join59(options.agentDir,".plugin-selection.json")}),projectSelectionStore:overrides?.projectSelectionStore??createPluginSelectionStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,".plugin-selection.json")})})}async function createDefaultPluginManagerControllerV1(options){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=await createDefaultPluginMarketWiringV1({agentDir,cwd}),cli=buildMarketCli({agentDir,cwd,market});return{controller:createPluginManagerControllerV1({registry:market.registry,stateStore:options.scope==="project"?market.projectStateStore:market.stateStore,cli}),close:market.close}}async function handlePluginEcosystemCommand(args,options={}){if(args[0]!=="plugin")return!1;let write=options.write??(line=>console.log(line));if(args[1]==="update"&&args[2]==="--all")return await runBatchUpdate(args.slice(3),options,write),!0;let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let response2=await buildMarketCli({agentDir,cwd,market,overrides:options}).execute({argv:args.slice(1)});return printResponse(response2,write),!0}finally{await market?.close()}}async function runBatchUpdate(restArgs,options,write){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),scopeIndex=restArgs.indexOf("--scope"),scope=scopeIndex!==-1&&restArgs[scopeIndex+1]==="project"?"project":"global",market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let cli=buildMarketCli({agentDir,cwd,market,overrides:options}),listResponse=await cli.execute({argv:["state","list","--scope",scope]});if(listResponse.status!=="succeeded"){printResponse(listResponse,write);return}let entries=(listResponse.data?.entries??[]).filter(entry=>entry.lifecycle==="active"&&entry.scope===scope);if(entries.length===0){write("No active plugins to update.");return}let updated=[],current=[],failed=[];for(let entry of entries){let factoryEntry=BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1.find(item=>item.pluginId===entry.pluginId),argv=factoryEntry?["install",`${factoryEntry.npmName}@${factoryEntry.range??"latest"}`,"--scope",scope]:["update",entry.pluginId,"--scope",scope],response2=await cli.execute({argv});response2.status==="succeeded"?(updated.push(entry.pluginId),write(response2.text)):response2.error?.code==="already_installed"?current.push(entry.pluginId):(failed.push(entry.pluginId),write(response2.text))}let summary=[`updated ${updated.length}${updated.length>0?` (${updated.join(", ")})`:""}`,`already up to date ${current.length}${current.length>0?` (${current.join(", ")})`:""}`,`failed ${failed.length}${failed.length>0?` (${failed.join(", ")})`:""}`].join("; ");write(`plugin update --all [${scope}]: ${summary}`),failed.length>0&&(process.exitCode=1)}finally{await market?.close()}}import{join as join60}from"node:path";var DEFAULT_DURABLE_LOG_RELATIVE_PATH=join60("durable","remote-server-ops.jsonl");function isAddrInUse(error2){return typeof error2=="object"&&error2!==null&&error2.code==="EADDRINUSE"}async function runServeMode(port,options){let handle,createListener=options?.createListener??(()=>createWsServerListener({port,httpRequestHandler:(request,response2)=>handle?.server.handleArtifactHttpRequest(request,response2)??!1,onError:error2=>{console.error(`remote-server error: ${error2.message}`)}})),startServer=options?.startServer??startCodingAgentRemoteServer,workspaceRoots=options?.workspaceRoots,sessionDir=options?.sessionDir,durable=options?.durable??createDurableService({backend:createFileDurableStoreBackend({path:join60(getAgentDir(),DEFAULT_DURABLE_LOG_RELATIVE_PATH)})}),writerId=readOrCreateWriterId(getAgentDir());try{handle=await startServer({sessionSourceOptions:{sessionsDir:sessionDir??getSessionsDir(),cwd:process.cwd(),agentDir:getAgentDir(),...workspaceRoots===void 0||workspaceRoots.length===0?{}:{workspaceRoots},agentTaskResults:{store:durable,writerId},subagentPoolFromSelfInvocation:!0,...options?.hostLogger===void 0?{}:{hostLogger:options.hostLogger}},listeners:[createListener()],onError:error2=>{console.error(`remote-server error: ${error2.message}`)},durable,writerId})}catch(error2){throw isAddrInUse(error2)&&(console.error(`Port ${port} is already in use`),process.exit(1)),error2}let closing=!1,shutdown=()=>{closing||(closing=!0,handle.close().then(()=>{process.exit(0)}).catch(error2=>{console.error(`Remote server shutdown failed: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}))};process.on("SIGINT",shutdown),process.on("SIGTERM",shutdown),console.log(`Remote server listening on ${handle.addresses.join(", ")}`)}import{existsSync as existsSync29}from"fs";var THEME_OPTIONS=[{value:"dark",label:"Dark"},{value:"light",label:"Light"}],ANALYTICS_OPTIONS=[{value:!0,label:"Share anonymous usage data"},{value:!1,label:"Don't share"}],SETUP_LOGO_LINES=["\u2588\u2588\u2588\u2588\u2588\u2588","\u2588\u2588 \u2588\u2588","\u2588\u2588\u2588\u2588 \u2588\u2588","\u2588\u2588 \u2588\u2588"],FirstTimeSetupComponent=class extends Container{step="theme";themeIndex;analyticsIndex=0;options;constructor(options){super(),this.options=options,this.themeIndex=Math.max(0,THEME_OPTIONS.findIndex(option=>option.value===options.detectedTheme)),this.update()}update(){this.clear(),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",SETUP_LOGO_LINES.join(`
1491
1491
  `)),1,0)),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",theme.bold(`Welcome to ${APP_NAME}, the minimal coding agent.`)),1,0)),this.addChild(new Spacer(1)),this.step==="theme"?(this.addChild(new Text(theme.fg("text","Pick a theme."),1,0)),this.addChild(new Text(theme.fg("muted",`Detected system appearance: ${this.options.detectedTheme}`),1,0)),this.addChild(new Spacer(1)),this.addOptionList(THEME_OPTIONS.map(option=>option.label),this.themeIndex)):(this.addChild(new Text(theme.fg("text","Opt-in to anonymous usage data sharing?"),1,0)),this.addChild(new Text(theme.fg("muted",`Opting in stores a tracking identifier in settings.json and enables anonymous
1492
1492
  usage analytics. This helps us to better debug, reproduce, and resolve issues
1493
1493
  and bugs within Agent Forge. You can observe what is shared using /privacy and make