herm-tui 1.9.0-dev.23 → 1.9.0-dev.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +7 -6
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -4084,7 +4084,7 @@ Please report this to https://github.com/markedjs/marked.`,e){let r="<p>An error
4084
4084
  `,1)[0];if(!first)return null;if(row2(first,1).type==="header")return parseLaunchStream(text2).meta;return parse3(text2).meta}catch{return null}}import{existsSync as existsSync7}from"fs";import{join as join6,dirname as dirname4,basename as basename4}from"path";var NAME_RE=/^[a-z0-9-]{2,32}$/;function lint(raw){let e=parse3(raw),errs=[];if(!NAME_RE.test(e.meta.name))errs.push(`name "${e.meta.name}" must match ${NAME_RE}`);if(!e.meta.author)errs.push("header.author required");if(e.meta.width<8||e.meta.height<4)errs.push(`dims ${e.meta.width}\xD7${e.meta.height} too small`);for(let s of STATES)if(!e.clips.get(s)?.frames.length)errs.push(`state "${s}" missing or empty`);if(errs.length)throw Error(errs.join(`
4085
4085
  `));return e}function lintManifest(path6,raw){let man=JSON.parse(raw),dir=dirname4(path6),errs=[];if("license"in man||"provenance"in man)errs.push("manifest must not contain license or provenance");if(!NAME_RE.test(man.name))errs.push(`name "${man.name}" must match ${NAME_RE}`);if(basename4(dir)!==man.name)errs.push(`name "${man.name}" \u2260 folder "${basename4(dir)}"`);if(man.source&&!existsSync7(join6(dir,man.source)))errs.push(`source: ${man.source} missing`);if(!man.states||typeof man.states!=="object")errs.push("states: object required");else for(let[st,v2]of Object.entries(man.states))if(!STATES.includes(st))errs.push(`states.${st}: unknown state`);else if(!v2?.file)errs.push(`states.${st}.file required`);else if(!existsSync7(join6(dir,v2.file)))errs.push(`states.${st}.file: ${v2.file} missing`);if(errs.length)throw Error(`${path6}:
4086
4086
  ${errs.join(`
4087
- `)}`);return man}import{existsSync as existsSync8,mkdirSync as mkdirSync3,readFileSync as readFileSync3,writeFileSync as writeFileSync4,copyFileSync,renameSync as renameSync2,rmSync,statSync,readdirSync as readdirSync2,lstatSync}from"fs";import{join as join7,extname as extname2,basename as basename5,dirname as dirname5}from"path";import{mkdtempSync}from"fs";import{tmpdir}from"os";import{createHash as createHash2}from"crypto";var NAME_RE2=/^[a-z0-9][a-z0-9-]{1,63}$/,SAFE_PATH_RE=/^[a-zA-Z0-9._/-]+$/,problem=(path6,message)=>({code:"manifest",path:path6,message:`${path6}: ${message}`}),isObj2=(value)=>!!value&&typeof value==="object"&&!Array.isArray(value),isSafeText=(value)=>!/[<>\u0000-\u001f]/.test(value),isSha256=(value)=>typeof value==="string"&&/^sha256:[A-Za-z0-9._~+/=-]+$/.test(value),isEncoding=(value)=>typeof value==="string"&&RUNTIME_ENCODINGS.includes(value),isRuntimePath=(path6)=>path6.endsWith(LAUNCH_STREAM_EXTENSION)||/^blobs\/sha256\/[A-Fa-f0-9]{16,}(?:\.eikon)?$/.test(path6),STALE_DESCRIPTOR_ROLES=new Set(["stream","source"]);function isSafeRelativePath(path6){if(!path6||path6.startsWith("/")||path6.startsWith("./")||path6.includes("../")||path6==="..")return!1;if(/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(path6))return!1;if(!SAFE_PATH_RE.test(path6))return!1;return!path6.split("/").includes("..")}function supportsLaunch(range){let parts2=[...range.matchAll(/(>=|>|<=|<|==|=)?\s*(\d+)(?:\.\d+)?/g)];if(!parts2.length)return!0;return parts2.every(([,op="=",raw])=>{let n=Number(raw);if(op===">=")return LAUNCH_MAJOR_VERSION>=n;if(op===">")return LAUNCH_MAJOR_VERSION>n;if(op==="<=")return LAUNCH_MAJOR_VERSION<=n;if(op==="<")return LAUNCH_MAJOR_VERSION<n;return LAUNCH_MAJOR_VERSION===n})}function validateDescriptor(file,index,opts,errs){let base=`files.${index}`;if(!file||typeof file!=="object"){errs.push(problem(base,"descriptor object required"));return}if(typeof file.path!=="string"||!isSafeRelativePath(file.path))errs.push(problem(`${base}.path`,"safe relative path required"));if(typeof file.role!=="string"||!file.role)errs.push(problem(`${base}.role`,"role required"));else if(STALE_DESCRIPTOR_ROLES.has(file.role))errs.push(problem(`${base}.role`,`stale descriptor role "${file.role}"; use final runtime/source.base/source.clip roles`));if(typeof file.mediaType!=="string"||!file.mediaType)errs.push(problem(`${base}.mediaType`,"mediaType required"));if(file.role==="runtime"){if(!isRuntimePath(file.path))errs.push(problem(`${base}.path`,`runtime descriptor must point at launch ${LAUNCH_STREAM_EXTENSION} stream or content-addressed blob`));if(file.mediaType!==LAUNCH_MEDIA_TYPE)errs.push(problem(`${base}.mediaType`,`runtime descriptor must use ${LAUNCH_MEDIA_TYPE}`));if(file.encoding!=null&&!isEncoding(file.encoding))errs.push(problem(`${base}.encoding`,"runtime encoding must be identity or gzip"));let enc=file.encoding??"identity";if(file.decodedSize!=null&&(typeof file.decodedSize!=="number"||!Number.isFinite(file.decodedSize)||file.decodedSize<0))errs.push(problem(`${base}.decodedSize`,"non-negative number required"));if(file.decodedDigest!=null&&!isSha256(file.decodedDigest))errs.push(problem(`${base}.decodedDigest`,"sha256 digest required"));if(opts.registry&&enc==="gzip"){let missing=[];if(typeof file.size!=="number"||!Number.isFinite(file.size)||file.size<0)missing.push("size");if(!isSha256(file.digest))missing.push("digest");if(typeof file.decodedSize!=="number"||!Number.isFinite(file.decodedSize)||file.decodedSize<0)missing.push("decodedSize");if(!isSha256(file.decodedDigest))missing.push("decodedDigest");if(missing.length)errs.push(problem(base,`${missing.join(" ")} required for gzip registry runtime descriptors`))}}else if(file.encoding!=null||file.decodedSize!=null||file.decodedDigest!=null)errs.push(problem(base,"runtime encoding metadata is only valid on runtime descriptors"));if(opts.registry){let missing=[];if(typeof file.size!=="number"||!Number.isFinite(file.size)||file.size<0)missing.push("size");if(!isSha256(file.digest))missing.push("digest");if(missing.length)errs.push(problem(base,`${missing.join(" ")} required for registry descriptors`))}}function validatePackageManifest(value,opts={}){let errs=[];if(!isObj2(value))throw new EikonValidationError([problem("manifest","object required")]);let raw=value,man=value;if(man.kind!==PACKAGE_KIND)errs.push(problem("kind",`must be ${PACKAGE_KIND}`));if(man.schemaVersion!==PACKAGE_SCHEMA_VERSION)errs.push(problem("schemaVersion",`must be ${PACKAGE_SCHEMA_VERSION}`));if(!NAME_RE2.test(String(man.name??"")))errs.push(problem("name","safe package name required"));if(!man.id||typeof man.id!=="string"||!isSafeText(man.id))errs.push(problem("id","safe id required"));if(opts.registry&&(typeof man.version!=="string"||!man.version))errs.push(problem("version","version required for registry packages"));if(!isObj2(man.compatibility)||typeof man.compatibility.eikon!=="string"||!supportsLaunch(man.compatibility.eikon))errs.push(problem("compatibility.eikon","must support launch major version 1"));if(!isObj2(man.entrypoints)||typeof man.entrypoints.default!=="string"||!isSafeRelativePath(man.entrypoints.default))errs.push(problem("entrypoints.default","safe relative path required"));if(typeof man.entrypoints?.default==="string"&&!isRuntimePath(man.entrypoints.default))errs.push(problem("entrypoints.default",`must point at launch ${LAUNCH_STREAM_EXTENSION} runtime stream or content-addressed blob`));for(let[key2,path6]of Object.entries(man.entrypoints??{}))if(typeof path6!=="string"||!isSafeRelativePath(path6))errs.push(problem(`entrypoints.${key2}`,"safe relative path required"));if("signals"in raw)errs.push(problem("signals","runtime signal mappings belong in the .eikon header"));if(opts.registry&&!Array.isArray(man.files))errs.push(problem("files","files descriptors required for registry packages"));for(let[index,file]of(man.files??[]).entries())validateDescriptor(file,index,opts,errs);let runtime=(man.files??[]).find((file)=>file.role==="runtime"&&file.path===man.entrypoints.default);if(opts.registry&&!runtime)errs.push(problem("files","runtime descriptor for entrypoints.default required"));if(man.source?.base&&!isSafeRelativePath(man.source.base))errs.push(problem("source.base","safe relative path required"));for(let[key2,source]of Object.entries(man.source?.states??{}))if(!source||typeof source!=="object"||typeof source.file!=="string"||!isSafeRelativePath(source.file))errs.push(problem(`source.states.${key2}.file`,"safe relative path required"));for(let ext of man.extensions?.required??[])errs.push(problem("extensions.required",`unknown required Eikon extension ${ext}`));if(man.poster&&!isSafeRelativePath(man.poster))errs.push(problem("poster","safe relative path required"));for(let bundle of man.bundles??[])if(!bundle||typeof bundle!=="object"||typeof bundle.url!=="string")errs.push(problem("bundles.url","bundle URL required"));for(let[key2,value2]of Object.entries(man.display??{})){if(typeof value2==="string"&&!isSafeText(value2))errs.push(problem(`display.${key2}`,"unsafe text"));if(Array.isArray(value2)&&value2.some((item)=>typeof item!=="string"||!isSafeText(item)))errs.push(problem(`display.${key2}`,"unsafe text"))}for(let trigger of man.triggers??[])if(!trigger||typeof trigger.signal!=="string"||typeof trigger.when!=="string")errs.push(problem("triggers","signal and when required"));if(errs.length)throw new EikonValidationError(errs);return man}function buffer(bytes){return bytes.buffer.slice(bytes.byteOffset,bytes.byteOffset+bytes.byteLength)}async function sha256Bytes2(bytes){let out=await globalThis.crypto.subtle.digest("SHA-256",buffer(bytes));return`sha256:${[...new Uint8Array(out)].map((n)=>n.toString(16).padStart(2,"0")).join("")}`}async function assertDigest2(bytes,expected,label){if(expected&&await sha256Bytes2(bytes)!==expected)runtimeError(`runtime ${label} digest mismatch`)}async function decodeRuntimeBytes2(bytes,opts={}){assertBytes(bytes,opts),await assertDigest2(bytes,opts.descriptor?.digest,"stored");let decoded=runtimeEncoding(bytes,opts.descriptor)==="gzip"?await gunzip2(bytes,opts.maxDecodedBytes??DEFAULT_RUNTIME_MAX_DECODED_BYTES):bytes;return assertDecoded(decoded,opts),await assertDigest2(decoded,opts.descriptor?.decodedDigest,"decoded"),utf8(decoded)}async function gunzip2(bytes,max){let ctor=globalThis.DecompressionStream;if(!ctor)runtimeError("runtime gzip decode unsupported in this browser");try{let source=new ReadableStream({start(ctrl){ctrl.enqueue(new Uint8Array(buffer(bytes))),ctrl.close()}}),gzip=new ctor("gzip"),reader=source.pipeThrough(gzip).getReader(),chunks=[],size=0;for(;;){let item=await reader.read();if(item.done)break;if(size+=item.value.length,size>max)await reader.cancel(),runtimeError(`runtime decoded byte limit exceeded: ${size} > ${max}`);chunks.push(item.value)}let out=new Uint8Array(size),at=0;for(let chunk of chunks)out.set(chunk,at),at+=chunk.length;return out}catch(err){if(err instanceof Error&&err.message.includes("runtime decoded byte limit"))throw err;runtimeError(`runtime gzip decode failed: ${err instanceof Error?err.message:String(err)}`)}}var PRIVATE_HOSTS=new Set(["localhost","127.0.0.1","0.0.0.0","::1"]);function privateIpv4(a,b2){if(a===10||a===127)return!0;if(a===169&&b2===254)return!0;if(a===192&&b2===168)return!0;return a===172&&b2>=16&&b2<=31}function mappedIpv4Private(host){let dotted=host.match(/^::ffff:(\d+)\.(\d+)\.(\d+)\.(\d+)$/);if(dotted)return privateIpv4(Number(dotted[1]),Number(dotted[2]));let hex=host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);if(!hex)return!1;let n=Number.parseInt(hex[1],16)*65536+Number.parseInt(hex[2],16);return privateIpv4(Math.floor(n/16777216),Math.floor(n/65536)&255)}function privateHost(host){let h2=host.toLowerCase().replace(/^\[|\]$/g,"");if(PRIVATE_HOSTS.has(h2))return!0;if(h2.endsWith(".localhost"))return!0;let ip=h2.match(/^(\d+)\.(\d+)\./);if(ip&&privateIpv4(Number(ip[1]),Number(ip[2])))return!0;if(h2.startsWith("fe80:"))return!0;if(/^f[cd][0-9a-f]{2}:/.test(h2))return!0;return mappedIpv4Private(h2)}function pathParts(raw){let path6=raw.split(/[?#]/,1)[0]??raw,decoded=(()=>{try{return decodeURIComponent(path6)}catch{return path6}})();return[path6,decoded]}function pathEscape(raw){return pathParts(raw).some((value)=>/%5c/i.test(value)||value.split(/[\\/]/).some((part)=>part===".."))}var DEFAULT_PUBLIC_CATALOG=DEFAULT_CATALOG,NAME_RE3=/^[a-z0-9][a-z0-9-]{1,63}$/,text2=(value)=>typeof value==="string"&&!/[<>\u0000-\u001f]/.test(value),isObj3=(value)=>!!value&&typeof value==="object"&&!Array.isArray(value),problem2=(path6,message)=>({code:"catalog",path:path6,message:`${path6}: ${message}`}),digestRe=/^sha256:[A-Za-z0-9._~+/=-]+$/,encodings=new Set(["identity","gzip"]),trimSlash=(s)=>s.replace(/\/$/,""),slash=(s)=>s.replace(/\/?$/,"/"),clean=(value)=>typeof value==="string"?value.replace(/[\u0000-\u001f\u007f-\u009f]/g,""):void 0,cleanTextBlock=(value)=>typeof value==="string"?value.replace(/[\u0000-\u0009\u000b\u000c\u000e-\u001f\u007f-\u009f]/g,""):void 0;var blobDigest=(value)=>{let m2=new URL(value).pathname.match(/\/blobs\/sha256\/([A-Fa-f0-9]{64})(?:\.eikon)?$/);return m2?`sha256:${m2[1].toLowerCase()}`:void 0},isRuntimeUrl=(value)=>value.endsWith(".eikon")||/\/blobs\/sha256\/[A-Fa-f0-9]{16,}(?:\.eikon)?$/.test(new URL(value).pathname),goodSize=(value)=>typeof value==="number"&&Number.isFinite(value)&&value>=0;async function sha256(bytes){let copy=new Uint8Array(bytes),hash=await crypto.subtle.digest("SHA-256",copy.buffer);return`sha256:${[...new Uint8Array(hash)].map((byte)=>byte.toString(16).padStart(2,"0")).join("")}`}function publicCatalogUrl(raw=DEFAULT_PUBLIC_CATALOG,base,opts={}){let out;try{out=new URL(raw,base)}catch{throw Error("public catalog URL is invalid")}if(pathEscape(raw))throw Error(`public catalog URL path escape: ${out.origin}${out.pathname}`);if(opts.allowPrivate&&out.protocol==="file:")return out.href;if(out.protocol!=="https:"&&out.protocol!=="http:")throw Error(`public catalog URL must use http(s): ${out.href}`);if(out.username||out.password)throw Error(`public catalog URL cannot include credentials: ${out.protocol}//[redacted]@${out.host}${out.pathname}`);for(let key2 of out.searchParams.keys())if(/token|secret|key|credential|password/i.test(key2))throw Error(`public catalog URL cannot include credentials: ${out.origin}${out.pathname}`);if(!opts.allowPrivate&&privateHost(out.hostname))throw Error(`public catalog URL cannot use private host: ${out.hostname}`);if(out.protocol==="http:"&&!privateHost(out.hostname))throw Error(`public catalog URL must use https: ${out.href}`);if(out.pathname.split("/").some((p)=>p===".."))throw Error(`public catalog URL path escape: ${out.href}`);return out.href}function url(value,base){try{return publicCatalogUrl(value,base,{allowPrivate:!0})}catch{throw new EikonValidationError([problem2("packageUrl","http(s) URL required")])}}function joinUrl(base,path6){return new URL(path6,base.endsWith("/")?base:`${base}/`).toString()}function relativeUrl(base,path6){if(!path6)return;if(/^https?:\/\//.test(path6))return url(path6);if(!isSafeRelativePath(path6))throw new EikonValidationError([problem2("path","safe relative path required")]);return joinUrl(base,path6)}function assetUrl(raw,base,fallback,opts={}){let input=raw||fallback,out=publicCatalogUrl(input,input.includes("://")?void 0:slash(base),opts),root=new URL(slash(base)),parsed=new URL(out);if(parsed.host!==root.host)throw Error(`public catalog URL host must match catalog host: ${out}`);if(!parsed.pathname.startsWith(root.pathname))throw Error(`public catalog URL path escape: ${out}`);return out}function runtimeDescriptor(man){return man.files?.find((file)=>file.role==="runtime"&&file.path===runtimePath(man))}function digestFor(man,path6){return man.files?.find((file)=>file.path===path6)?.digest}function runtimePath(man){return man.entrypoints.default}function catalogEntry(entry,base=DEFAULT_PUBLIC_CATALOG,opts={}){return publicFromEntry(fromLegacy(entry,base,opts),entry)}function publicFromEntry(entry,raw=entry){return{...entry,trust:entry.trust??{},poster:entry.poster??"",w:0,h:0,width:0,height:0,identityKey:entry.sourceKey||entry.id,raw}}function runtimeDesc(entry){let trust=entry.trust,digest=trust?.runtimeDigest??blobDigest(entry.runtimeUrl);if(!digest&&!trust?.runtimeSize&&!trust?.runtimeEncoding&&!trust?.runtimeDecodedSize&&!trust?.runtimeDecodedDigest)return;return{digest,size:trust?.runtimeSize,encoding:trust?.runtimeEncoding,decodedSize:trust?.runtimeDecodedSize,decodedDigest:trust?.runtimeDecodedDigest}}function assertArtifactHeaders(res,entry){let enc=res.headers.get("content-encoding");if(enc&&enc.toLowerCase()!=="identity"&&(entry.trust?.runtimeDigest||blobDigest(entry.runtimeUrl)))throw Error(`catalog: runtime artifact must be served without Content-Encoding: ${enc}`)}async function loadRuntimeArtifact(entry,fetcher=fetch,opts={}){if(publicCatalogUrl(entry.runtimeUrl,void 0,{allowPrivate:opts.allowPrivate}),publicCatalogUrl(entry.packageUrl,void 0,{allowPrivate:opts.allowPrivate}),entry.trust?.manifestDigest){let pkg=await fetcher(entry.packageUrl,opts.signal?{signal:opts.signal}:void 0);if(pkg.url)publicCatalogUrl(pkg.url,void 0,{allowPrivate:opts.allowPrivate});if(!pkg.ok)throw Error(`catalog: package HTTP ${pkg.status}`);let body=new Uint8Array(await pkg.arrayBuffer());if(await sha256(body)!==entry.trust.manifestDigest)throw Error("catalog: package manifest digest mismatch")}let out=await fetcher(entry.runtimeUrl,opts.signal?{signal:opts.signal}:void 0);if(out.url)publicCatalogUrl(out.url,void 0,{allowPrivate:opts.allowPrivate});if(!out.ok)throw Error(`catalog: HTTP ${out.status}`);assertArtifactHeaders(out,entry);let bytes=new Uint8Array(await out.arrayBuffer());if(opts.maxBytes!=null&&bytes.length>opts.maxBytes)throw Error("catalog: size limit exceeded");return{bytes,text:await decodeRuntimeBytes2(bytes,{descriptor:runtimeDesc(entry),maxBytes:opts.maxBytes,maxDecodedBytes:opts.maxBytes})}}function fromPackage(input,root,opts={}){let man=validatePackageManifest(input.manifest),packageUrl=url(input.packageUrl,root),base=packageUrl.slice(0,packageUrl.lastIndexOf("/")+1),runtime=runtimePath(man),desc=runtimeDescriptor(man),runtimeUrl=relativeUrl(base,runtime);return validateCatalogEntry({kind:CATALOG_KIND,schemaVersion:CATALOG_SCHEMA_VERSION,id:man.id,version:man.version,sourceKey:input.sourceKey??`registry:${new URL(packageUrl).host}:${man.id}${man.version?`@${man.version}`:""}`,name:man.name,title:man.display?.title,author:man.display?.author,description:man.display?.description,glyph:man.display?.glyph,tags:man.display?.tags,poster:relativeUrl(base,man.poster),runtimeUrl,packageUrl,detailUrl:input.detailUrl?url(input.detailUrl,base):void 0,compatibility:{eikon:man.compatibility.eikon,hosts:man.compatibility.hosts,available:!0},trust:{manifestDigest:input.trust?.manifestDigest??digestFor(man,"manifest.json"),runtimeDigest:input.trust?.runtimeDigest??desc?.digest,runtimeSize:input.trust?.runtimeSize??desc?.size,runtimeEncoding:input.trust?.runtimeEncoding??desc?.encoding,runtimeDecodedSize:input.trust?.runtimeDecodedSize??desc?.decodedSize,runtimeDecodedDigest:input.trust?.runtimeDecodedDigest??desc?.decodedDigest}},opts)}function fromLegacy(input,base,opts={}){if(!NAME_RE3.test(input.name))throw new EikonValidationError([problem2("name","safe catalog name required")]);let source=input.source??`${input.name}/`;if(/^file:|^javascript:|^data:/i.test(source))throw new EikonValidationError([problem2("packageUrl","http(s) URL required")]);if(!/^https?:\/\//.test(source)&&!isSafeRelativePath(source))throw new EikonValidationError([problem2("path","path escape")]);let root=/^https?:\/\//.test(source)?publicCatalogUrl(source,void 0,opts):base?joinUrl(base,source):source,catalogRoot=base?slash(base):root,runtimeUrl=typeof input.runtimeUrl==="string"?assetUrl(input.runtimeUrl,catalogRoot,"",opts):typeof input.runtime_url==="string"?assetUrl(input.runtime_url,catalogRoot,"",opts):joinUrl(root,`${input.name}.eikon`),packageUrl=typeof input.packageUrl==="string"?url(input.packageUrl,catalogRoot):typeof input.package_url==="string"?url(input.package_url,catalogRoot):joinUrl(root,"manifest.json");return validateCatalogEntry({kind:CATALOG_KIND,schemaVersion:CATALOG_SCHEMA_VERSION,id:input.name,version:input.version,sourceKey:/^https?:\/\//.test(root)?root:input.name,name:input.name,title:clean(input.name),author:clean(input.author),glyph:clean(input.glyph),tags:Array.isArray(input.tags)?input.tags.filter(text2):void 0,poster:cleanTextBlock(input.poster),runtimeUrl,packageUrl,detailUrl:typeof input.detailUrl==="string"?url(input.detailUrl,root):typeof input.detail_url==="string"?url(input.detail_url,root):void 0,description:clean(input.description),compatibility:{eikon:">=1 <2",available:!0},trust:{}},opts)}function validateCatalogEntry(entry,opts={}){let errs=[];if(entry.kind!==CATALOG_KIND)errs.push(problem2("kind",`must be ${CATALOG_KIND}`));if(entry.schemaVersion!==CATALOG_SCHEMA_VERSION)errs.push(problem2("schemaVersion",`must be ${CATALOG_SCHEMA_VERSION}`));if(!NAME_RE3.test(entry.name))errs.push(problem2("name","safe catalog name required"));for(let[key2,value]of Object.entries({id:entry.id,sourceKey:entry.sourceKey,title:entry.title,author:entry.author,description:entry.description,glyph:entry.glyph}))if(value!=null&&!text2(value))errs.push(problem2(key2,"unsafe text"));try{publicCatalogUrl(entry.packageUrl,void 0,opts)}catch{errs.push(problem2("packageUrl","safe http(s) URL required"))}try{publicCatalogUrl(entry.runtimeUrl,void 0,opts)}catch{errs.push(problem2("runtimeUrl","safe http(s) URL required"))}if(entry.runtimeUrl&&!isRuntimeUrl(entry.runtimeUrl))errs.push(problem2("runtimeUrl","must point at launch .eikon stream or content-addressed blob"));let trust=entry.trust;if(trust?.manifestDigest!=null&&!digestRe.test(trust.manifestDigest))errs.push(problem2("trust.manifestDigest","sha256 digest required"));if(trust?.runtimeDigest!=null&&!digestRe.test(trust.runtimeDigest))errs.push(problem2("trust.runtimeDigest","sha256 digest required"));if(trust?.runtimeDecodedDigest!=null&&!digestRe.test(trust.runtimeDecodedDigest))errs.push(problem2("trust.runtimeDecodedDigest","sha256 digest required"));if(trust?.runtimeSize!=null&&!goodSize(trust.runtimeSize))errs.push(problem2("trust.runtimeSize","non-negative finite size required"));if(trust?.runtimeDecodedSize!=null&&!goodSize(trust.runtimeDecodedSize))errs.push(problem2("trust.runtimeDecodedSize","non-negative finite size required"));if(trust?.runtimeEncoding!=null&&!encodings.has(trust.runtimeEncoding))errs.push(problem2("trust.runtimeEncoding","unsupported runtime encoding"));if(trust?.runtimeEncoding==="gzip"){if(!trust.runtimeDigest)errs.push(problem2("trust.runtimeDigest","required for gzip runtime"));if(!goodSize(trust.runtimeSize))errs.push(problem2("trust.runtimeSize","required for gzip runtime"));if(!goodSize(trust.runtimeDecodedSize))errs.push(problem2("trust.runtimeDecodedSize","required for gzip runtime"));if(!trust.runtimeDecodedDigest)errs.push(problem2("trust.runtimeDecodedDigest","required for gzip runtime"))}for(let key2 of["poster","detailUrl"]){let value=entry[key2];if(value&&/^file:|^javascript:|^data:/i.test(value))errs.push(problem2(key2,"unsafe URL"))}if(!entry.compatibility?.eikon)errs.push(problem2("compatibility.eikon","required"));if(entry.compatibility?.eikon&&!/>=?\s*1/.test(entry.compatibility.eikon))errs.push(problem2("compatibility.eikon","must support launch major version 1"));if(errs.length)throw new EikonValidationError(errs);return entry}function normalizeCatalogEntry(input,base,opts={}){if(isObj3(input)&&"kind"in input&&input.kind===CATALOG_KIND)return validateCatalogEntry(input,opts);if(isObj3(input)&&"manifest"in input)return fromPackage(input,base,opts);return fromLegacy(input,base,opts)}function searchCatalogEntries(entries,query){let q2=query.trim().toLowerCase();if(!q2)return[...entries];return entries.filter((entry)=>[entry.name,entry.title,entry.author,entry.description,...entry.tags??[]].some((value)=>value?.toLowerCase().includes(q2)))}async function loadCatalogEntries(base,fetcher=fetch,opts={}){let root=trimSlash(publicCatalogUrl(base,void 0,opts)),res=await fetcher(`${root}/index.json`);if(res.url)publicCatalogUrl(res.url,void 0,opts);if(!res.ok)throw Error(`catalog: ${res.status} loading ${root}/index.json`);let items=await res.json();if(!Array.isArray(items))throw new EikonValidationError([problem2("catalog","index array required")]);return items.map((item)=>normalizeCatalogEntry(item,`${root}/`,opts))}function searchCatalog(entries,query){return searchCatalogEntries(entries,query)}async function loadCatalog(base=DEFAULT_PUBLIC_CATALOG,fetcher=fetch,opts={}){let root=trimSlash(publicCatalogUrl(base,void 0,opts)),res=await fetcher(`${root}/index.json`);if(res.url)publicCatalogUrl(res.url,void 0,opts);if(!res.ok)throw Error(`catalog: HTTP ${res.status}`);let items=await res.json();if(!Array.isArray(items))throw new EikonValidationError([problem2("catalog","index array required")]);let entries=items.map((item)=>{if(isObj3(item)&&"kind"in item&&item.kind===CATALOG_KIND)return publicFromEntry(normalizeCatalogEntry(item,void 0,opts),item);if(isObj3(item)&&"manifest"in item)return publicFromEntry(normalizeCatalogEntry(item,`${root}/`,opts),item);return catalogEntry(item,root,opts)});return{base:root,entries,async load(entry){let item=typeof entry==="string"?entries.find((e)=>e.identityKey===entry||e.sourceKey===entry||e.id===entry||e.name===entry):entry;if(!item)throw Error(`catalog: unknown eikon "${entry}"`);return(await loadRuntimeArtifact(item,fetcher,{allowPrivate:opts.allowPrivate})).text}}}var clean2=(value)=>value.trim(),safe=(value)=>/^[A-Za-z0-9._~:/?#[\]@!$&'()*+,;=%-]+$/.test(value)&&!/[\u0000-\u001f\u007f\\]/.test(value),esc=(value)=>value.replace(/[#?].*$/,"").split("/").some((part)=>part===".."),key2=(kind,value)=>`${kind}:${value}`;function cleanUrl(raw){try{let url2=new URL(raw);for(let key3 of[...url2.searchParams.keys()])if(/token|secret|key|credential|password/i.test(key3))url2.searchParams.set(key3,"[redacted]");return`${url2.origin}${url2.pathname}${url2.search}`}catch{return raw.replace(/([?&][^=]*(?:token|secret|key|credential|password)[^=]*=)[^&\s]+/ig,"$1[redacted]")}}function http(raw){try{let rawPath=raw.split(/[?#]/,1)[0]??raw,decoded=(()=>{try{return decodeURIComponent(rawPath)}catch{return rawPath}})(),url2=new URL(raw);if(url2.protocol!=="http:"&&url2.protocol!=="https:")return;if(!safe(raw)||esc(rawPath)||esc(decoded)||esc(url2.pathname)||/%5c/i.test(raw))throw Error(`unsafe source URL: ${cleanUrl(raw)}`);return url2.href}catch(err){if(err instanceof Error&&err.message.startsWith("unsafe"))throw err;return}}function github(raw){let spec2=raw.replace(/^github:/,""),input=spec2.replace(/^https:\/\/github\.com\//,"").replace(/^git@github\.com:/,"").replace(/^github\.com\//,"");if(input===spec2&&!raw.startsWith("github:"))return;let[path6,query=""]=input.split("?"),[head,hash]=path6.split("#"),parts2=head.replace(/\.git$/,"").split("/").filter(Boolean);if(parts2.length<2)return;let owner=parts2[0],repo=parts2[1].replace(/\.git$/,""),pathSelector=parts2.slice(2).join("/")||void 0,params=new URLSearchParams(query),ref=hash?decodeURIComponent(hash):void 0,selector=params.get("selector")?decodeURIComponent(params.get("selector")):pathSelector;for(let part of[owner,repo,ref,selector].filter(Boolean))if(!/^[A-Za-z0-9._/-]+$/.test(part)||part.split("/").some((x2)=>!x2||x2==="."||x2===".."||x2.startsWith("-")))throw Error(`unsafe GitHub source: ${raw}`);let suffix2=`${owner}/${repo}${ref?`#${ref}`:""}${selector?`?selector=${selector}`:""}`;return{kind:"github",spec:raw,sourceKey:key2("github",suffix2),owner,repo,...ref?{ref}:{},...selector?{selector}:{}}}function parseSourceSpec(raw){let spec2=clean2(raw);if(!spec2)throw Error("source spec required");if(!safe(spec2))throw Error(`unsafe source spec: ${spec2}`);if(/^(npm|registry):/.test(spec2)){let body=spec2.replace(/^(npm|registry):/,""),at=body.startsWith("@")?body.indexOf("@",1):body.lastIndexOf("@"),name=at>0?body.slice(0,at):body,range=at>0?body.slice(at+1):void 0;if(!name)throw Error(`registry source name required: ${spec2}`);return{kind:"registry",spec:spec2,sourceKey:key2("registry",body),name,...range?{range}:{},supported:!1}}if(spec2.startsWith("catalog+")){let[url3,name]=spec2.slice(8).split("#"),catalogUrl=http(url3)??(()=>{throw Error(`catalog URL must be http(s): ${spec2}`)})();return{kind:"catalog",spec:spec2,sourceKey:key2("catalog",`${catalogUrl}#${name??""}`),catalogUrl,...name?{name}:{}}}if(spec2.startsWith("catalog:")){let name=spec2.slice(8);if(!name)throw Error("catalog source name required");return{kind:"catalog",spec:spec2,sourceKey:key2("catalog",name),name}}if(spec2.startsWith("pkg:")){let url3=http(spec2.slice(4))??(()=>{throw Error(`package URL must be http(s): ${spec2}`)})();return{kind:"package-url",spec:spec2,sourceKey:key2("package",url3),url:url3}}let gh=github(spec2);if(gh)return gh;let url2=http(spec2);if(url2)return{kind:"package-url",spec:spec2,sourceKey:key2("package",url2),url:url2};if(spec2.startsWith("file://")||spec2.startsWith("/")||spec2.startsWith("./")||spec2.startsWith("../"))return{kind:"local",spec:spec2,sourceKey:key2("local",spec2),path:spec2.replace(/^file:\/\//,"")};if(!/[/:]/.test(spec2))return{kind:"catalog",spec:spec2,sourceKey:key2("catalog",spec2),name:spec2};throw Error(`unsupported source spec: ${spec2}`)}function assertWritableScope(scope="profile"){if(scope==="project-reserved")throw Error("project-reserved Eikon scope is deferred until project trust policy exists");return scope}var sha2562=(data2)=>`sha256:${createHash2("sha256").update(data2).digest("hex")}`,NAME_RE4=/^[a-z0-9][a-z0-9-]{0,63}$/,cleanUrl2=(raw)=>{try{let u3=new URL(raw);for(let key3 of[...u3.searchParams.keys()])if(/token|secret|key|credential|password/i.test(key3))u3.searchParams.set(key3,"[redacted]");if(u3.username||u3.password)return`${u3.protocol}//[redacted]@${u3.host}${u3.pathname}${u3.search}${u3.hash}`;return u3.href}catch{return raw.replace(/\/\/[^/@\s]+@/,"//[redacted]@").replace(/([?&][^=]*(?:token|secret|key|credential|password)[^=]*=)[^&\s]+/ig,"$1[redacted]")}};function assertDownloadUrl(raw,opts){if(/[\u0000-\u001f\u007f]/.test(raw)||raw.includes("\\")||/%5c/i.test(raw))throw Error(`download URL contains unsafe characters: ${cleanUrl2(raw)}`);if(pathParts(raw).some((path6)=>path6.split(/[\\/]/).some((part)=>part==="..")))throw Error(`download URL path escape: ${cleanUrl2(raw)}`);let url2=new URL(raw);if(pathParts(url2.pathname).some((path6)=>path6.split(/[\\/]/).some((part)=>part==="..")))throw Error(`download URL path escape: ${cleanUrl2(raw)}`);if(url2.protocol!=="https:"&&url2.protocol!=="http:")throw Error(`download URL must use https: ${cleanUrl2(raw)}`);if(url2.username||url2.password)throw Error(`download URL cannot include credentials: ${cleanUrl2(raw)}`);if(!opts.allowPrivate&&privateHost(url2.hostname))throw Error(`download URL cannot use private host: ${url2.hostname}`);if(url2.protocol==="http:"&&!privateHost(url2.hostname))throw Error(`download URL must use https: ${cleanUrl2(raw)}`);return url2}async function downloadBytes(raw,opts={}){let fetcher=opts.fetcher??fetch,maxBytes=opts.maxBytes??104857600,maxRedirects=opts.maxRedirects??5,url2=assertDownloadUrl(raw,opts);for(let i=0;i<=maxRedirects;i++){let res=await fetcher(url2.href,{redirect:"manual"});if(res.status>=300&&res.status<400&&res.headers.get("location")){url2=assertDownloadUrl(new URL(res.headers.get("location"),url2).href,opts);continue}if(!res.ok)throw Error(`download failed ${res.status}: ${cleanUrl2(url2.href)}`);let enc=res.headers.get("content-encoding");if(opts.rejectContentEncoding&&enc&&enc.toLowerCase()!=="identity")throw Error(`download content-encoding not allowed for artifact bytes: ${enc}`);if(Number(res.headers.get("content-length")??0)>maxBytes)throw Error(`download byte limit exceeded: ${cleanUrl2(url2.href)}`);let buf=new Uint8Array(await res.arrayBuffer());if(buf.length>maxBytes)throw Error(`download byte limit exceeded: ${cleanUrl2(url2.href)}`);return buf}throw Error(`download redirect limit exceeded: ${cleanUrl2(raw)}`)}function safeSelector(selector){if(!selector)return;if(/[\u0000-\u001f\u007f]|%|\\/.test(selector))throw Error("unsafe selector");if(selector.split("/").some((p)=>!p||p==="."||p===".."||p.startsWith("-")))throw Error("unsafe selector");let parts2=selector.split("/");if(parts2.length>2||parts2.some((p)=>!/^[A-Za-z0-9._-]+$/.test(p)))throw Error("unsafe selector");return selector}function resolveGithubSource(raw){if(/[\u0000\r\n]/.test(raw))throw Error("unsafe GitHub source");let owner,repo,rest="",m2=raw.match(/^github\.com\/([^/]+)\/([^/]+)(?:\/(.+))?$/);if(m2)owner=m2[1],repo=m2[2],rest=m2[3]??"";if(m2=raw.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/(.+))?$/),!owner&&m2)owner=m2[1],repo=m2[2],rest=m2[3]??"";if(m2=raw.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?(?:\/(.+))?$/),!owner&&m2)owner=m2[1],repo=m2[2],rest=m2[3]??"";if(!owner||!repo)throw Error("only github.com repository sources are supported");if(repo=repo.replace(/\.git$/,""),![owner,repo].every((p)=>/^[A-Za-z0-9._-]+$/.test(p))||owner.startsWith("-")||repo.startsWith("-"))throw Error("unsafe GitHub repository");let selector=safeSelector(rest.replace(/^\/+/,"")||void 0);return{owner,repo,selector,cloneUrl:`https://github.com/${owner}/${repo}.git`,display:`github.com/${owner}/${repo}${selector?`/${selector}`:""}`}}function entries(man){let pkg=validatePackageManifest(man),xs=[];if(pkg.source?.base)xs.push(["base",pkg.source.base]);for(let k2 of STATES){let f=pkg.source?.states?.[k2]?.file;if(f)xs.push([k2,f])}return xs}function manifest(value){return validatePackageManifest(value)}function installManifest(man,origin){let{license:_license,provenance:_provenance,...clean3}=man;return{...clean3,origin}}var gitish=(s)=>{if(/^(?:github\.com|https:\/\/github\.com|git@github\.com:)/.test(s))return!0;return/^git@|^ssh:\/\/|^git:\/\/|\.git$/.test(s)||/^(https?:\/\/)?(gitlab|bitbucket)\.com\/[\w.-]+\/[\w.-]+\/?$/.test(s)};async function defaultClone(url2,dst){let[raw,ref]=url2.split("#",2),source=resolveGithubSource(raw),args=["git","clone","--depth","1",...ref?["--branch",ref]:[],"--",source.cloneUrl,dst],p=Bun.spawn(args,{stdout:"pipe",stderr:"pipe"}),[code,err]=await Promise.all([p.exited,new Response(p.stderr).text()]);if(code!==0)throw Error(`git clone failed: ${err.trim()}`);let sha=await new Response(Bun.spawn(["git","-C",dst,"rev-parse","HEAD"],{stdout:"pipe"}).stdout).text();return rmSync(join7(dst,".git"),{recursive:!0,force:!0}),{dir:dst,sha:sha.trim()||void 0,cleanup:!0}}function readJson(path6){return JSON.parse(readFileSync3(path6,"utf8"))}function asPackageIndex(value){if(!value||typeof value!=="object"||Array.isArray(value))return;let raw=value;if(!Array.isArray(raw.versions))return;return raw}function latestPackageFromIndex(path6){let rel=asPackageIndex(readJson(path6))?.versions?.at(-1)?.manifest;if(!rel||!isSafeRelativePath(rel))throw Error(`${path6}: package index has no safe manifest path`);return join7(dirname5(path6),rel)}function catalogMatches(entry,selector){let slug=selector.split("/").at(-1);return[entry.id,entry.name,entry.sourceKey,entry.packageUrl.split("/packages/").at(-1)?.replace(/\/[^/]+\.json$/,"")].some((key3)=>key3===selector||key3===slug||key3?.endsWith(`/${selector}`)||key3?.endsWith(`/${slug}`))}function packageResolution(repo,selector){let parts2=selector.split("/");if(parts2.length===2){let idx=join7(repo,"packages",parts2[0],parts2[1],"index.json");if(!existsSync8(idx))return;let path7=latestPackageFromIndex(idx);return{manifest:manifest(readJson(path7)),staged:dirname5(path7),root:`packages/${parts2[0]}/${parts2[1]}/index.json`}}let matches=[],packages=join7(repo,"packages");if(existsSync8(packages))for(let ns2 of readdirSync2(packages,{withFileTypes:!0})){if(!ns2.isDirectory())continue;let idx=join7(packages,ns2.name,selector,"index.json");if(existsSync8(idx))matches.push(idx)}if(matches.length>1)throw Error(`ambiguous package selector "${selector}"; use namespace/name`);if(!matches.length)return;let path6=latestPackageFromIndex(matches[0]),ns=basename5(dirname5(dirname5(path6)));return{manifest:manifest(readJson(path6)),staged:dirname5(path6),root:`packages/${ns}/${selector}/index.json`}}function catalogResolution(repo,selector){for(let root of["eikons/index.json","registry.json","index.json"]){let path6=join7(repo,root);if(!existsSync8(path6))continue;let raw=readJson(path6);if(!Array.isArray(raw))continue;let matches=raw.map((item)=>{let any=item;if(any.packageUrl?.startsWith("../")||any.package_url?.startsWith("../")){let rel=any.packageUrl??any.package_url;return normalizeCatalogEntry({...item,packageUrl:`https://github.local/${rel.replace(/^\.\.\//,"")}`},"https://github.local/")}return normalizeCatalogEntry(item,"https://github.local/")}).filter((entry2)=>catalogMatches(entry2,selector));if(matches.length>1)throw Error(`ambiguous catalog selector "${selector}"`);if(!matches.length)continue;let entry=matches[0],pkgPath,url2=new URL(entry.packageUrl);if(pkgPath=join7(repo,url2.pathname.replace(/^\//,"")),!existsSync8(pkgPath))pkgPath=join7(dirname5(path6),entry.packageUrl);return{entry,manifest:manifest(readJson(pkgPath)),staged:dirname5(pkgPath),root}}return}function trustFor(man,staged,base){let pkg=validatePackageManifest(man),files=pkg.files??[];if(!files.length)return{state:"unverified",reason:"package descriptors missing"};if(files.filter((file)=>!file.digest||typeof file.size!=="number").length)return{state:"unverified",reason:"package descriptor digest or size missing"};if(base)return{state:"unverified",reason:"remote package files not downloaded yet"};return verifyPackageFiles(pkg,staged)}async function verifyRemotePackageFiles(pkg,base,opts){let files=pkg.files??[];if(!files.length)return{trust:{state:"unverified",reason:"package descriptors missing"}};if(files.filter((file)=>!file.digest||typeof file.size!=="number").length)return{trust:{state:"unverified",reason:"package descriptor digest or size missing"}};let verified=[],data2=new Map;for(let file of files){if(!isSafeRelativePath(file.path))throw Error(`mismatch: unsafe descriptor path ${file.path}`);let buf=await downloadBytes(new URL(file.path,base).href,{...opts,rejectContentEncoding:file.role==="runtime"&&!!file.digest});if(typeof file.size==="number"&&buf.length!==file.size)throw Error(`mismatch: size ${file.path}`);if(file.digest&&sha2562(buf)!==file.digest)throw Error(`mismatch: digest ${file.path}`);data2.set(file.path,buf),verified.push(file.path)}return{trust:{state:"verified",verified},files:data2}}function assertRemotePackageWriteCoverage(pkg,files){for(let rel of new Set([pkg.entrypoints.default,...entries(pkg).map(([,rel2])=>rel2)]))if(!files?.has(rel))throw Error(`missing verified descriptor for remote package write: ${rel}`)}function assertVerifiedPackageWriteCoverage(pkg,trust){if(trust.state!=="verified")return;let verified=new Set(trust.verified??[]);for(let rel of new Set([pkg.entrypoints.default,...entries(pkg).map(([,rel2])=>rel2)]))if(!verified.has(rel))throw Error(`missing verified descriptor for package write: ${rel}`)}function installName(name){if(!NAME_RE4.test(name))throw Error(`${name||"<empty>"}: invalid eikon name`);return name}function cleanupResolved(r){if(r.tmp)rmSync(r.cleanup??r.staged,{recursive:!0,force:!0})}function assertSafePackageFile(staged,rel){let parts2=rel.split("/"),current=staged;for(let part of parts2){current=join7(current,part);let stat=lstatSync(current);if(stat.isSymbolicLink())throw Error(`mismatch: symlink or special file ${rel}`);if(part!==parts2.at(-1)&&!stat.isDirectory())throw Error(`mismatch: symlink or special file ${rel}`);if(part===parts2.at(-1)&&!stat.isFile())throw Error(`mismatch: symlink or special file ${rel}`)}return current}function verifyPackageFiles(pkg,staged){let verified=[];for(let file of pkg.files??[]){if(!isSafeRelativePath(file.path))throw Error(`mismatch: unsafe descriptor path ${file.path}`);let path6=assertSafePackageFile(staged,file.path),data2=readFileSync3(path6);if(typeof file.size==="number"&&data2.length!==file.size)throw Error(`mismatch: size ${file.path}`);if(file.digest&&sha2562(data2)!==file.digest)throw Error(`mismatch: digest ${file.path}`);if(file.digest&&typeof file.size==="number")verified.push(file.path)}return verified.length?{state:"verified",verified}:{state:"unverified",reason:"package descriptor digest or size missing"}}function locate(dir){if(existsSync8(join7(dir,"manifest.json")))return dir;for(let e of readdirSync2(dir,{withFileTypes:!0}))if(e.isDirectory()&&existsSync8(join7(dir,e.name,"manifest.json")))return join7(dir,e.name);throw Error(`no manifest.json in ${dir} (or one level deep)`)}async function catalog(name,url2,opts={}){let base=url2.replace(/\/?$/,"/"),allow=opts.downloader?.allowPrivate||/^http:\/\/localhost[:/]/.test(base),dl=opts.downloader??(allow?{allowPrivate:!0}:{}),entry=(await loadCatalogEntries(base,async(input)=>{let raw=typeof input==="string"?input:input instanceof URL?input.href:input.url;return new Response(new TextDecoder().decode(await downloadBytes(raw,dl)))},{allowPrivate:allow})).find((e)=>e.name===name||e.id===name||e.sourceKey===name);if(!entry)throw Error(`catalog: no eikon named "${name}"`);return entry}async function resolvePackageUrl(entry,opts={},source){let at=new Date().toISOString(),bytes=await downloadBytes(entry.packageUrl,opts.downloader??(/^http:\/\/localhost[:/]/.test(entry.packageUrl)?{allowPrivate:!0}:void 0));if(entry.trust?.manifestDigest&&sha2562(bytes)!==entry.trust.manifestDigest)throw Error("mismatch: package manifest digest");let man=manifest(JSON.parse(new TextDecoder().decode(bytes))),base=new URL(".",entry.packageUrl).href,pkg=man,desc=pkg.files?.find((file)=>file.role==="runtime"&&file.path===pkg.entrypoints?.default),version=typeof man.version==="string"?man.version:man.version!=null?String(man.version):void 0;return{name:man.name,manifest:man,staged:"",base,origin:{source:source?.source??entry.packageUrl,sourceSpec:source?.spec??entry.packageUrl,at,kind:source?.kind??"default-catalog",sourceKey:entry.sourceKey,identityKey:entry.sourceKey||entry.id,packageUrl:entry.packageUrl,runtimeUrl:entry.runtimeUrl,contentDigest:desc?.digest,resolvedVersion:version},trust:trustFor(man,"",base)}}async function resolve6(src,opts={}){let at=new Date().toISOString(),local=src.replace(/^file:\/\//,"");if(!gitish(src)&&existsSync8(local)&&statSync(local).isDirectory()){let staged=locate(local),man=manifest(JSON.parse(readFileSync3(join7(staged,"manifest.json"),"utf8")));return{name:man.name,manifest:man,staged,origin:{source:src,sourceSpec:src,at,kind:"local",sourceKey:`local:${src}`},trust:trustFor(man,staged)}}let parsed=parseSourceSpec(src);if(parsed.kind==="registry")throw Error("registry Eikon sources are reserved for a future package backend");let sourceSpec=parsed.spec;if(parsed.kind==="catalog"){let base=opts.catalog??parsed.catalogUrl??DEFAULT_CATALOG;return resolvePackageUrl(await catalog(parsed.name??src,base,opts),opts,{spec:sourceSpec,source:parsed.name??src,kind:"default-catalog"})}if(parsed.kind==="package-url"){let raw=new URL(parsed.url),href=raw.pathname.endsWith(".json")?raw.href:new URL("manifest.json",parsed.url.replace(/\/?$/,"/")).href,base=new URL(".",href).href,bytes=await downloadBytes(href,opts.downloader??(/^http:\/\/localhost[:/]/.test(href)?{allowPrivate:!0}:void 0)),man=manifest(JSON.parse(new TextDecoder().decode(bytes))),version=typeof man.version==="string"?man.version:man.version!=null?String(man.version):void 0;return{name:man.name,manifest:man,staged:"",base,origin:{source:src,sourceSpec,at,kind:"catalog-package",sourceKey:parsed.sourceKey,packageUrl:href,resolvedVersion:version},trust:trustFor(man,"",base)}}if(parsed.kind==="github"||gitish(src)){let gh;if(parsed.kind==="github")gh={owner:parsed.owner,repo:parsed.repo,selector:parsed.selector,cloneUrl:`https://github.com/${parsed.owner}/${parsed.repo}.git`,display:`github.com/${parsed.owner}/${parsed.repo}${parsed.selector?`/${parsed.selector}`:""}`};else try{gh=resolveGithubSource(src)}catch{}let tmp=mkdtempSync(join7(tmpdir(),"eikon-"));if(!gh){let p=Bun.spawn(["git","clone","--depth","1","--",src,tmp],{stdout:"pipe",stderr:"pipe"}),[code,err]=await Promise.all([p.exited,new Response(p.stderr).text()]);if(code!==0)throw Error(`git clone failed: ${err.trim()}`);let sha=await new Response(Bun.spawn(["git","-C",tmp,"rev-parse","HEAD"],{stdout:"pipe"}).stdout).text();rmSync(join7(tmp,".git"),{recursive:!0,force:!0});let staged2=locate(tmp),man2=manifest(JSON.parse(readFileSync3(join7(staged2,"manifest.json"),"utf8")));return{name:man2.name,manifest:man2,staged:staged2,tmp:!0,cleanup:tmp,origin:{source:src,sourceSpec,at,kind:"github-package",sourceKey:parsed.sourceKey,sha:sha.trim()||void 0,resolvedRef:sha.trim()||void 0},trust:trustFor(man2,staged2)}}let cloneUrl=parsed.kind==="github"&&parsed.ref?`${gh.cloneUrl}#${parsed.ref}`:gh.cloneUrl,cloned=await(opts.clone??defaultClone)(cloneUrl,tmp),repo=cloned.dir;if(gh.selector){let selected=catalogResolution(repo,gh.selector);if(selected)return{name:selected.manifest.name,manifest:selected.manifest,staged:selected.staged,tmp:cloned.cleanup!==!1,cleanup:cloned.cleanup!==!1?repo:void 0,origin:{source:src,sourceSpec,at,kind:"github-catalog",sha:cloned.sha,resolvedRef:cloned.sha??(parsed.kind==="github"?parsed.ref:void 0),repo:gh.display,selector:gh.selector,catalogRoot:selected.root,sourceKey:selected.entry.sourceKey,identityKey:selected.entry.sourceKey||selected.entry.id,packageUrl:selected.entry.packageUrl,runtimeUrl:selected.entry.runtimeUrl},trust:trustFor(selected.manifest,selected.staged)};let indexed=packageResolution(repo,gh.selector);if(indexed)return{name:indexed.manifest.name,manifest:indexed.manifest,staged:indexed.staged,tmp:cloned.cleanup!==!1,cleanup:cloned.cleanup!==!1?repo:void 0,origin:{source:src,sourceSpec,at,kind:"github-catalog",sha:cloned.sha,resolvedRef:cloned.sha??(parsed.kind==="github"?parsed.ref:void 0),repo:gh.display,selector:gh.selector,catalogRoot:indexed.root,sourceKey:parsed.sourceKey},trust:trustFor(indexed.manifest,indexed.staged)};if(cloned.cleanup!==!1)rmSync(repo,{recursive:!0,force:!0});throw Error(`no eikon named "${gh.selector}" in GitHub catalog`)}let staged=locate(repo),man=manifest(JSON.parse(readFileSync3(join7(staged,"manifest.json"),"utf8")));return{name:man.name,manifest:man,staged,tmp:cloned.cleanup!==!1,cleanup:cloned.cleanup!==!1?repo:void 0,origin:{source:src,sourceSpec,at,kind:"github-package",sourceKey:parsed.sourceKey,sha:cloned.sha,resolvedRef:cloned.sha??(parsed.kind==="github"?parsed.ref:void 0),repo:gh.display},trust:trustFor(man,staged)}}throw Error(`cannot resolve "${src}": expected catalog name, git URL, local dir, or http(s) base`)}var peeked=new Map;function peek3(src,opts){let hit=peeked.get(src);if(hit)return hit;let p=resolve6(src,opts).then(async(r)=>{let xs=entries(r.manifest);if(r.base){let sizes=await Promise.all(xs.map(([,rel])=>fetch(new URL(rel,r.base).href,{method:"HEAD"}).then((h2)=>Number(h2.headers.get("content-length")??0)).catch(()=>0)));return{n:xs.length,bytes:sizes.reduce((a,b2)=>a+b2,0)}}let bytes=xs.reduce((a,[,rel])=>{let p2=join7(r.staged,rel);return a+(existsSync8(p2)?statSync(p2).size:0)},0);return{n:xs.length,bytes}}).catch(()=>{return});return peeked.set(src,p),p}async function install(src,root,opts={}){let scope=assertWritableScope(opts.scope??"profile"),r=await resolve6(src,opts);r.origin.scope=scope;let name=installName(opts.name??r.name);mkdirSync3(root,{recursive:!0});let dst=join7(root,name),tmp=mkdtempSync(join7(root,`.${name}-`)),srcd=join7(tmp,"source"),old=join7(root,`.${name}.old-${process.pid}-${Date.now()}`);try{let remote,launchBytes,man=validatePackageManifest(r.manifest),dl=opts.downloader??(/^http:\/\/localhost[:/]/.test(r.base??"")?{allowPrivate:!0}:{});if(r.base)remote=await verifyRemotePackageFiles(man,r.base,dl),assertRemotePackageWriteCoverage(man,remote.files),validatePackageManifest(man,{registry:!0}),r.trust=remote.trust;if(!r.base&&r.staged)r.trust=verifyPackageFiles(man,r.staged),assertVerifiedPackageWriteCoverage(man,r.trust);let rel=man.entrypoints.default,desc=man.files?.find((file)=>file.role==="runtime"&&file.path===rel);if(r.base)launchBytes=remote.files.get(rel);else launchBytes=readFileSync3(assertSafePackageFile(r.staged,rel));parseRuntimeBytes(launchBytes,{descriptor:desc}),mkdirSync3(srcd,{recursive:!0}),writeFileSync4(join7(tmp,`${name}.eikon`),launchBytes);let xs=entries(r.manifest),sources={},done=0,bytes=0,tick2=()=>opts.progress?.(++done,xs.length);if(opts.media!==!1)await Promise.all(xs.map(async([role,rel2])=>{let fname=`${role}${extname2(rel2).toLowerCase()}`,to=join7(srcd,fname);if(r.base){let dl2=opts.downloader??(/^http:\/\/localhost[:/]/.test(r.base)?{allowPrivate:!0}:{}),buf=remote?remote.files.get(rel2):await downloadBytes(new URL(rel2,r.base).href,dl2);await Bun.write(to,buf),bytes+=buf.length}else{let from2=assertSafePackageFile(r.staged,rel2);if(!existsSync8(from2))throw Error(`${rel2}: missing in ${r.staged}`);copyFileSync(from2,to),bytes+=statSync(to).size}sources[role]=fname,tick2()}));let out=installManifest(r.manifest,{...r.origin,trust:r.trust.state});if(writeFileSync4(join7(tmp,"manifest.json"),JSON.stringify(out,null,2)+`
4087
+ `)}`);return man}import{existsSync as existsSync8,mkdirSync as mkdirSync3,readFileSync as readFileSync3,writeFileSync as writeFileSync4,copyFileSync,renameSync as renameSync2,rmSync,statSync,readdirSync as readdirSync2,lstatSync}from"fs";import{join as join7,extname as extname2,basename as basename5,dirname as dirname5}from"path";import{mkdtempSync}from"fs";import{tmpdir}from"os";import{createHash as createHash2}from"crypto";var NAME_RE2=/^[a-z0-9][a-z0-9-]{1,63}$/,SAFE_PATH_RE=/^[a-zA-Z0-9._/-]+$/,problem=(path6,message)=>({code:"manifest",path:path6,message:`${path6}: ${message}`}),isObj2=(value)=>!!value&&typeof value==="object"&&!Array.isArray(value),isSafeText=(value)=>!/[<>\u0000-\u001f]/.test(value),isSha256=(value)=>typeof value==="string"&&/^sha256:[A-Za-z0-9._~+/=-]+$/.test(value),isEncoding=(value)=>typeof value==="string"&&RUNTIME_ENCODINGS.includes(value),isRuntimePath=(path6)=>path6.endsWith(LAUNCH_STREAM_EXTENSION)||/^blobs\/sha256\/[A-Fa-f0-9]{16,}(?:\.eikon)?$/.test(path6),STALE_DESCRIPTOR_ROLES=new Set(["stream","source"]);function isSafeRelativePath(path6){if(!path6||path6.startsWith("/")||path6.startsWith("./")||path6.includes("../")||path6==="..")return!1;if(/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(path6))return!1;if(!SAFE_PATH_RE.test(path6))return!1;return!path6.split("/").includes("..")}function supportsLaunch(range){let parts2=[...range.matchAll(/(>=|>|<=|<|==|=)?\s*(\d+)(?:\.\d+)?/g)];if(!parts2.length)return!0;return parts2.every(([,op="=",raw])=>{let n=Number(raw);if(op===">=")return LAUNCH_MAJOR_VERSION>=n;if(op===">")return LAUNCH_MAJOR_VERSION>n;if(op==="<=")return LAUNCH_MAJOR_VERSION<=n;if(op==="<")return LAUNCH_MAJOR_VERSION<n;return LAUNCH_MAJOR_VERSION===n})}function validateDescriptor(file,index,opts,errs){let base=`files.${index}`;if(!file||typeof file!=="object"){errs.push(problem(base,"descriptor object required"));return}if(typeof file.path!=="string"||!isSafeRelativePath(file.path))errs.push(problem(`${base}.path`,"safe relative path required"));if(typeof file.role!=="string"||!file.role)errs.push(problem(`${base}.role`,"role required"));else if(STALE_DESCRIPTOR_ROLES.has(file.role))errs.push(problem(`${base}.role`,`stale descriptor role "${file.role}"; use final runtime/source.base/source.clip roles`));if(typeof file.mediaType!=="string"||!file.mediaType)errs.push(problem(`${base}.mediaType`,"mediaType required"));if(file.role==="runtime"){if(!isRuntimePath(file.path))errs.push(problem(`${base}.path`,`runtime descriptor must point at launch ${LAUNCH_STREAM_EXTENSION} stream or content-addressed blob`));if(file.mediaType!==LAUNCH_MEDIA_TYPE)errs.push(problem(`${base}.mediaType`,`runtime descriptor must use ${LAUNCH_MEDIA_TYPE}`));if(file.encoding!=null&&!isEncoding(file.encoding))errs.push(problem(`${base}.encoding`,"runtime encoding must be identity or gzip"));let enc=file.encoding??"identity";if(file.decodedSize!=null&&(typeof file.decodedSize!=="number"||!Number.isFinite(file.decodedSize)||file.decodedSize<0))errs.push(problem(`${base}.decodedSize`,"non-negative number required"));if(file.decodedDigest!=null&&!isSha256(file.decodedDigest))errs.push(problem(`${base}.decodedDigest`,"sha256 digest required"));if(opts.registry&&enc==="gzip"){let missing=[];if(typeof file.size!=="number"||!Number.isFinite(file.size)||file.size<0)missing.push("size");if(!isSha256(file.digest))missing.push("digest");if(typeof file.decodedSize!=="number"||!Number.isFinite(file.decodedSize)||file.decodedSize<0)missing.push("decodedSize");if(!isSha256(file.decodedDigest))missing.push("decodedDigest");if(missing.length)errs.push(problem(base,`${missing.join(" ")} required for gzip registry runtime descriptors`))}}else if(file.encoding!=null||file.decodedSize!=null||file.decodedDigest!=null)errs.push(problem(base,"runtime encoding metadata is only valid on runtime descriptors"));if(opts.registry){let missing=[];if(typeof file.size!=="number"||!Number.isFinite(file.size)||file.size<0)missing.push("size");if(!isSha256(file.digest))missing.push("digest");if(missing.length)errs.push(problem(base,`${missing.join(" ")} required for registry descriptors`))}}function validatePackageManifest(value,opts={}){let errs=[];if(!isObj2(value))throw new EikonValidationError([problem("manifest","object required")]);let raw=value,man=value;if(man.kind!==PACKAGE_KIND)errs.push(problem("kind",`must be ${PACKAGE_KIND}`));if(man.schemaVersion!==PACKAGE_SCHEMA_VERSION)errs.push(problem("schemaVersion",`must be ${PACKAGE_SCHEMA_VERSION}`));if(!NAME_RE2.test(String(man.name??"")))errs.push(problem("name","safe package name required"));if(!man.id||typeof man.id!=="string"||!isSafeText(man.id))errs.push(problem("id","safe id required"));if(opts.registry&&(typeof man.version!=="string"||!man.version))errs.push(problem("version","version required for registry packages"));if(!isObj2(man.compatibility)||typeof man.compatibility.eikon!=="string"||!supportsLaunch(man.compatibility.eikon))errs.push(problem("compatibility.eikon","must support launch major version 1"));if(!isObj2(man.entrypoints)||typeof man.entrypoints.default!=="string"||!isSafeRelativePath(man.entrypoints.default))errs.push(problem("entrypoints.default","safe relative path required"));if(typeof man.entrypoints?.default==="string"&&!isRuntimePath(man.entrypoints.default))errs.push(problem("entrypoints.default",`must point at launch ${LAUNCH_STREAM_EXTENSION} runtime stream or content-addressed blob`));for(let[key2,path6]of Object.entries(man.entrypoints??{}))if(typeof path6!=="string"||!isSafeRelativePath(path6))errs.push(problem(`entrypoints.${key2}`,"safe relative path required"));if("signals"in raw)errs.push(problem("signals","runtime signal mappings belong in the .eikon header"));if(opts.registry&&!Array.isArray(man.files))errs.push(problem("files","files descriptors required for registry packages"));for(let[index,file]of(man.files??[]).entries())validateDescriptor(file,index,opts,errs);let runtime=(man.files??[]).find((file)=>file.role==="runtime"&&file.path===man.entrypoints.default);if(opts.registry&&!runtime)errs.push(problem("files","runtime descriptor for entrypoints.default required"));if(man.source?.base&&!isSafeRelativePath(man.source.base))errs.push(problem("source.base","safe relative path required"));for(let[key2,source]of Object.entries(man.source?.states??{}))if(!source||typeof source!=="object"||typeof source.file!=="string"||!isSafeRelativePath(source.file))errs.push(problem(`source.states.${key2}.file`,"safe relative path required"));for(let ext of man.extensions?.required??[])errs.push(problem("extensions.required",`unknown required Eikon extension ${ext}`));if(man.poster&&!isSafeRelativePath(man.poster))errs.push(problem("poster","safe relative path required"));for(let[key2,value2]of Object.entries(man.display??{})){if(typeof value2==="string"&&!isSafeText(value2))errs.push(problem(`display.${key2}`,"unsafe text"));if(Array.isArray(value2)&&value2.some((item)=>typeof item!=="string"||!isSafeText(item)))errs.push(problem(`display.${key2}`,"unsafe text"))}for(let trigger of man.triggers??[])if(!trigger||typeof trigger.signal!=="string"||typeof trigger.when!=="string")errs.push(problem("triggers","signal and when required"));if(errs.length)throw new EikonValidationError(errs);return man}function buffer(bytes){return bytes.buffer.slice(bytes.byteOffset,bytes.byteOffset+bytes.byteLength)}async function sha256Bytes2(bytes){let out=await globalThis.crypto.subtle.digest("SHA-256",buffer(bytes));return`sha256:${[...new Uint8Array(out)].map((n)=>n.toString(16).padStart(2,"0")).join("")}`}async function assertDigest2(bytes,expected,label){if(expected&&await sha256Bytes2(bytes)!==expected)runtimeError(`runtime ${label} digest mismatch`)}async function decodeRuntimeBytes2(bytes,opts={}){assertBytes(bytes,opts),await assertDigest2(bytes,opts.descriptor?.digest,"stored");let decoded=runtimeEncoding(bytes,opts.descriptor)==="gzip"?await gunzip2(bytes,opts.maxDecodedBytes??DEFAULT_RUNTIME_MAX_DECODED_BYTES):bytes;return assertDecoded(decoded,opts),await assertDigest2(decoded,opts.descriptor?.decodedDigest,"decoded"),utf8(decoded)}async function gunzip2(bytes,max){let ctor=globalThis.DecompressionStream;if(!ctor)runtimeError("runtime gzip decode unsupported in this browser");try{let source=new ReadableStream({start(ctrl){ctrl.enqueue(new Uint8Array(buffer(bytes))),ctrl.close()}}),gzip=new ctor("gzip"),reader=source.pipeThrough(gzip).getReader(),chunks=[],size=0;for(;;){let item=await reader.read();if(item.done)break;if(size+=item.value.length,size>max)await reader.cancel(),runtimeError(`runtime decoded byte limit exceeded: ${size} > ${max}`);chunks.push(item.value)}let out=new Uint8Array(size),at=0;for(let chunk of chunks)out.set(chunk,at),at+=chunk.length;return out}catch(err){if(err instanceof Error&&err.message.includes("runtime decoded byte limit"))throw err;runtimeError(`runtime gzip decode failed: ${err instanceof Error?err.message:String(err)}`)}}var PRIVATE_HOSTS=new Set(["localhost","127.0.0.1","0.0.0.0","::1"]);function privateIpv4(a,b2){if(a===10||a===127)return!0;if(a===169&&b2===254)return!0;if(a===192&&b2===168)return!0;return a===172&&b2>=16&&b2<=31}function mappedIpv4Private(host){let dotted=host.match(/^::ffff:(\d+)\.(\d+)\.(\d+)\.(\d+)$/);if(dotted)return privateIpv4(Number(dotted[1]),Number(dotted[2]));let hex=host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);if(!hex)return!1;let n=Number.parseInt(hex[1],16)*65536+Number.parseInt(hex[2],16);return privateIpv4(Math.floor(n/16777216),Math.floor(n/65536)&255)}function privateHost(host){let h2=host.toLowerCase().replace(/^\[|\]$/g,"");if(PRIVATE_HOSTS.has(h2))return!0;if(h2.endsWith(".localhost"))return!0;let ip=h2.match(/^(\d+)\.(\d+)\./);if(ip&&privateIpv4(Number(ip[1]),Number(ip[2])))return!0;if(h2.startsWith("fe80:"))return!0;if(/^f[cd][0-9a-f]{2}:/.test(h2))return!0;return mappedIpv4Private(h2)}function pathParts(raw){let path6=raw.split(/[?#]/,1)[0]??raw,decoded=(()=>{try{return decodeURIComponent(path6)}catch{return path6}})();return[path6,decoded]}function pathEscape(raw){return pathParts(raw).some((value)=>/%5c/i.test(value)||value.split(/[\\/]/).some((part)=>part===".."))}var DEFAULT_PUBLIC_CATALOG=DEFAULT_CATALOG,NAME_RE3=/^[a-z0-9][a-z0-9-]{1,63}$/,text2=(value)=>typeof value==="string"&&!/[<>\u0000-\u001f]/.test(value),isObj3=(value)=>!!value&&typeof value==="object"&&!Array.isArray(value),problem2=(path6,message)=>({code:"catalog",path:path6,message:`${path6}: ${message}`}),digestRe=/^sha256:[A-Za-z0-9._~+/=-]+$/,encodings=new Set(["identity","gzip"]),trimSlash=(s)=>s.replace(/\/$/,""),slash=(s)=>s.replace(/\/?$/,"/"),clean=(value)=>typeof value==="string"?value.replace(/[\u0000-\u001f\u007f-\u009f]/g,""):void 0,cleanTextBlock=(value)=>typeof value==="string"?value.replace(/[\u0000-\u0009\u000b\u000c\u000e-\u001f\u007f-\u009f]/g,""):void 0;var blobDigest=(value)=>{let m2=new URL(value).pathname.match(/\/blobs\/sha256\/([A-Fa-f0-9]{64})(?:\.eikon)?$/);return m2?`sha256:${m2[1].toLowerCase()}`:void 0},isRuntimeUrl=(value)=>value.endsWith(".eikon")||/\/blobs\/sha256\/[A-Fa-f0-9]{16,}(?:\.eikon)?$/.test(new URL(value).pathname),goodSize=(value)=>typeof value==="number"&&Number.isFinite(value)&&value>=0;async function sha256(bytes){let copy=new Uint8Array(bytes),hash=await crypto.subtle.digest("SHA-256",copy.buffer);return`sha256:${[...new Uint8Array(hash)].map((byte)=>byte.toString(16).padStart(2,"0")).join("")}`}function publicCatalogUrl(raw=DEFAULT_PUBLIC_CATALOG,base,opts={}){let out;try{out=new URL(raw,base)}catch{throw Error("public catalog URL is invalid")}if(pathEscape(raw))throw Error(`public catalog URL path escape: ${out.origin}${out.pathname}`);if(opts.allowPrivate&&out.protocol==="file:")return out.href;if(out.protocol!=="https:"&&out.protocol!=="http:")throw Error(`public catalog URL must use http(s): ${out.href}`);if(out.username||out.password)throw Error(`public catalog URL cannot include credentials: ${out.protocol}//[redacted]@${out.host}${out.pathname}`);for(let key2 of out.searchParams.keys())if(/token|secret|key|credential|password/i.test(key2))throw Error(`public catalog URL cannot include credentials: ${out.origin}${out.pathname}`);if(!opts.allowPrivate&&privateHost(out.hostname))throw Error(`public catalog URL cannot use private host: ${out.hostname}`);if(out.protocol==="http:"&&!privateHost(out.hostname))throw Error(`public catalog URL must use https: ${out.href}`);if(out.pathname.split("/").some((p)=>p===".."))throw Error(`public catalog URL path escape: ${out.href}`);return out.href}function url(value,base){try{return publicCatalogUrl(value,base,{allowPrivate:!0})}catch{throw new EikonValidationError([problem2("packageUrl","http(s) URL required")])}}function joinUrl(base,path6){return new URL(path6,base.endsWith("/")?base:`${base}/`).toString()}function relativeUrl(base,path6){if(!path6)return;if(/^https?:\/\//.test(path6))return url(path6);if(!isSafeRelativePath(path6))throw new EikonValidationError([problem2("path","safe relative path required")]);return joinUrl(base,path6)}function assetUrl(raw,base,fallback,opts={}){let input=raw||fallback,out=publicCatalogUrl(input,input.includes("://")?void 0:slash(base),opts),root=new URL(slash(base)),parsed=new URL(out);if(parsed.host!==root.host)throw Error(`public catalog URL host must match catalog host: ${out}`);if(!parsed.pathname.startsWith(root.pathname))throw Error(`public catalog URL path escape: ${out}`);return out}function runtimeDescriptor(man){return man.files?.find((file)=>file.role==="runtime"&&file.path===runtimePath(man))}function digestFor(man,path6){return man.files?.find((file)=>file.path===path6)?.digest}function runtimePath(man){return man.entrypoints.default}function catalogEntry(entry,base=DEFAULT_PUBLIC_CATALOG,opts={}){return publicFromEntry(fromLegacy(entry,base,opts),entry)}function publicFromEntry(entry,raw=entry){return{...entry,trust:entry.trust??{},poster:entry.poster??"",w:0,h:0,width:0,height:0,identityKey:entry.sourceKey||entry.id,raw}}function runtimeDesc(entry){let trust=entry.trust,digest=trust?.runtimeDigest??blobDigest(entry.runtimeUrl);if(!digest&&!trust?.runtimeSize&&!trust?.runtimeEncoding&&!trust?.runtimeDecodedSize&&!trust?.runtimeDecodedDigest)return;return{digest,size:trust?.runtimeSize,encoding:trust?.runtimeEncoding,decodedSize:trust?.runtimeDecodedSize,decodedDigest:trust?.runtimeDecodedDigest}}function assertArtifactHeaders(res,entry){let enc=res.headers.get("content-encoding");if(enc&&enc.toLowerCase()!=="identity"&&(entry.trust?.runtimeDigest||blobDigest(entry.runtimeUrl)))throw Error(`catalog: runtime artifact must be served without Content-Encoding: ${enc}`)}async function loadRuntimeArtifact(entry,fetcher=fetch,opts={}){if(publicCatalogUrl(entry.runtimeUrl,void 0,{allowPrivate:opts.allowPrivate}),publicCatalogUrl(entry.packageUrl,void 0,{allowPrivate:opts.allowPrivate}),entry.trust?.manifestDigest){let pkg=await fetcher(entry.packageUrl,opts.signal?{signal:opts.signal}:void 0);if(pkg.url)publicCatalogUrl(pkg.url,void 0,{allowPrivate:opts.allowPrivate});if(!pkg.ok)throw Error(`catalog: package HTTP ${pkg.status}`);let body=new Uint8Array(await pkg.arrayBuffer());if(await sha256(body)!==entry.trust.manifestDigest)throw Error("catalog: package manifest digest mismatch")}let out=await fetcher(entry.runtimeUrl,opts.signal?{signal:opts.signal}:void 0);if(out.url)publicCatalogUrl(out.url,void 0,{allowPrivate:opts.allowPrivate});if(!out.ok)throw Error(`catalog: HTTP ${out.status}`);assertArtifactHeaders(out,entry);let bytes=new Uint8Array(await out.arrayBuffer());if(opts.maxBytes!=null&&bytes.length>opts.maxBytes)throw Error("catalog: size limit exceeded");return{bytes,text:await decodeRuntimeBytes2(bytes,{descriptor:runtimeDesc(entry),maxBytes:opts.maxBytes,maxDecodedBytes:opts.maxBytes})}}function fromPackage(input,root,opts={}){let man=validatePackageManifest(input.manifest),packageUrl=url(input.packageUrl,root),base=packageUrl.slice(0,packageUrl.lastIndexOf("/")+1),runtime=runtimePath(man),desc=runtimeDescriptor(man),runtimeUrl=relativeUrl(base,runtime);return validateCatalogEntry({kind:CATALOG_KIND,schemaVersion:CATALOG_SCHEMA_VERSION,id:man.id,version:man.version,sourceKey:input.sourceKey??`registry:${new URL(packageUrl).host}:${man.id}${man.version?`@${man.version}`:""}`,name:man.name,title:man.display?.title,author:man.display?.author,description:man.display?.description,glyph:man.display?.glyph,tags:man.display?.tags,poster:relativeUrl(base,man.poster),runtimeUrl,packageUrl,detailUrl:input.detailUrl?url(input.detailUrl,base):void 0,compatibility:{eikon:man.compatibility.eikon,available:!0},trust:{manifestDigest:input.trust?.manifestDigest??digestFor(man,"manifest.json"),runtimeDigest:input.trust?.runtimeDigest??desc?.digest,runtimeSize:input.trust?.runtimeSize??desc?.size,runtimeEncoding:input.trust?.runtimeEncoding??desc?.encoding,runtimeDecodedSize:input.trust?.runtimeDecodedSize??desc?.decodedSize,runtimeDecodedDigest:input.trust?.runtimeDecodedDigest??desc?.decodedDigest}},opts)}function fromLegacy(input,base,opts={}){if(!NAME_RE3.test(input.name))throw new EikonValidationError([problem2("name","safe catalog name required")]);let source=input.source??`${input.name}/`;if(/^file:|^javascript:|^data:/i.test(source))throw new EikonValidationError([problem2("packageUrl","http(s) URL required")]);if(!/^https?:\/\//.test(source)&&!isSafeRelativePath(source))throw new EikonValidationError([problem2("path","path escape")]);let root=/^https?:\/\//.test(source)?publicCatalogUrl(source,void 0,opts):base?joinUrl(base,source):source,catalogRoot=base?slash(base):root,runtimeUrl=typeof input.runtimeUrl==="string"?assetUrl(input.runtimeUrl,catalogRoot,"",opts):typeof input.runtime_url==="string"?assetUrl(input.runtime_url,catalogRoot,"",opts):joinUrl(root,`${input.name}.eikon`),packageUrl=typeof input.packageUrl==="string"?url(input.packageUrl,catalogRoot):typeof input.package_url==="string"?url(input.package_url,catalogRoot):joinUrl(root,"manifest.json");return validateCatalogEntry({kind:CATALOG_KIND,schemaVersion:CATALOG_SCHEMA_VERSION,id:input.name,version:input.version,sourceKey:/^https?:\/\//.test(root)?root:input.name,name:input.name,title:clean(input.name),author:clean(input.author),glyph:clean(input.glyph),tags:Array.isArray(input.tags)?input.tags.filter(text2):void 0,poster:cleanTextBlock(input.poster),runtimeUrl,packageUrl,detailUrl:typeof input.detailUrl==="string"?url(input.detailUrl,root):typeof input.detail_url==="string"?url(input.detail_url,root):void 0,description:clean(input.description),compatibility:{eikon:">=1 <2",available:!0},trust:{}},opts)}function validateCatalogEntry(entry,opts={}){let errs=[];if(entry.kind!==CATALOG_KIND)errs.push(problem2("kind",`must be ${CATALOG_KIND}`));if(entry.schemaVersion!==CATALOG_SCHEMA_VERSION)errs.push(problem2("schemaVersion",`must be ${CATALOG_SCHEMA_VERSION}`));if(!NAME_RE3.test(entry.name))errs.push(problem2("name","safe catalog name required"));for(let[key2,value]of Object.entries({id:entry.id,sourceKey:entry.sourceKey,title:entry.title,author:entry.author,description:entry.description,glyph:entry.glyph}))if(value!=null&&!text2(value))errs.push(problem2(key2,"unsafe text"));try{publicCatalogUrl(entry.packageUrl,void 0,opts)}catch{errs.push(problem2("packageUrl","safe http(s) URL required"))}try{publicCatalogUrl(entry.runtimeUrl,void 0,opts)}catch{errs.push(problem2("runtimeUrl","safe http(s) URL required"))}if(entry.runtimeUrl&&!isRuntimeUrl(entry.runtimeUrl))errs.push(problem2("runtimeUrl","must point at launch .eikon stream or content-addressed blob"));let trust=entry.trust;if(trust?.manifestDigest!=null&&!digestRe.test(trust.manifestDigest))errs.push(problem2("trust.manifestDigest","sha256 digest required"));if(trust?.runtimeDigest!=null&&!digestRe.test(trust.runtimeDigest))errs.push(problem2("trust.runtimeDigest","sha256 digest required"));if(trust?.runtimeDecodedDigest!=null&&!digestRe.test(trust.runtimeDecodedDigest))errs.push(problem2("trust.runtimeDecodedDigest","sha256 digest required"));if(trust?.runtimeSize!=null&&!goodSize(trust.runtimeSize))errs.push(problem2("trust.runtimeSize","non-negative finite size required"));if(trust?.runtimeDecodedSize!=null&&!goodSize(trust.runtimeDecodedSize))errs.push(problem2("trust.runtimeDecodedSize","non-negative finite size required"));if(trust?.runtimeEncoding!=null&&!encodings.has(trust.runtimeEncoding))errs.push(problem2("trust.runtimeEncoding","unsupported runtime encoding"));if(trust?.runtimeEncoding==="gzip"){if(!trust.runtimeDigest)errs.push(problem2("trust.runtimeDigest","required for gzip runtime"));if(!goodSize(trust.runtimeSize))errs.push(problem2("trust.runtimeSize","required for gzip runtime"));if(!goodSize(trust.runtimeDecodedSize))errs.push(problem2("trust.runtimeDecodedSize","required for gzip runtime"));if(!trust.runtimeDecodedDigest)errs.push(problem2("trust.runtimeDecodedDigest","required for gzip runtime"))}for(let key2 of["poster","detailUrl"]){let value=entry[key2];if(value&&/^file:|^javascript:|^data:/i.test(value))errs.push(problem2(key2,"unsafe URL"))}if(!entry.compatibility?.eikon)errs.push(problem2("compatibility.eikon","required"));if(entry.compatibility?.eikon&&!/>=?\s*1/.test(entry.compatibility.eikon))errs.push(problem2("compatibility.eikon","must support launch major version 1"));if(errs.length)throw new EikonValidationError(errs);return entry}function normalizeCatalogEntry(input,base,opts={}){if(isObj3(input)&&"kind"in input&&input.kind===CATALOG_KIND)return validateCatalogEntry(input,opts);if(isObj3(input)&&"manifest"in input)return fromPackage(input,base,opts);return fromLegacy(input,base,opts)}function searchCatalogEntries(entries,query){let q2=query.trim().toLowerCase();if(!q2)return[...entries];return entries.filter((entry)=>[entry.name,entry.title,entry.author,entry.description,...entry.tags??[]].some((value)=>value?.toLowerCase().includes(q2)))}async function loadCatalogEntries(base,fetcher=fetch,opts={}){let root=trimSlash(publicCatalogUrl(base,void 0,opts)),res=await fetcher(`${root}/index.json`);if(res.url)publicCatalogUrl(res.url,void 0,opts);if(!res.ok)throw Error(`catalog: ${res.status} loading ${root}/index.json`);let items=await res.json();if(!Array.isArray(items))throw new EikonValidationError([problem2("catalog","index array required")]);return items.map((item)=>normalizeCatalogEntry(item,`${root}/`,opts))}function searchCatalog(entries,query){return searchCatalogEntries(entries,query)}async function loadCatalog(base=DEFAULT_PUBLIC_CATALOG,fetcher=fetch,opts={}){let root=trimSlash(publicCatalogUrl(base,void 0,opts)),res=await fetcher(`${root}/index.json`);if(res.url)publicCatalogUrl(res.url,void 0,opts);if(!res.ok)throw Error(`catalog: HTTP ${res.status}`);let items=await res.json();if(!Array.isArray(items))throw new EikonValidationError([problem2("catalog","index array required")]);let entries=items.map((item)=>{if(isObj3(item)&&"kind"in item&&item.kind===CATALOG_KIND)return publicFromEntry(normalizeCatalogEntry(item,void 0,opts),item);if(isObj3(item)&&"manifest"in item)return publicFromEntry(normalizeCatalogEntry(item,`${root}/`,opts),item);return catalogEntry(item,root,opts)});return{base:root,entries,async load(entry){let item=typeof entry==="string"?entries.find((e)=>e.identityKey===entry||e.sourceKey===entry||e.id===entry||e.name===entry):entry;if(!item)throw Error(`catalog: unknown eikon "${entry}"`);return(await loadRuntimeArtifact(item,fetcher,{allowPrivate:opts.allowPrivate})).text}}}var clean2=(value)=>value.trim(),safe=(value)=>/^[A-Za-z0-9._~:/?#[\]@!$&'()*+,;=%-]+$/.test(value)&&!/[\u0000-\u001f\u007f\\]/.test(value),esc=(value)=>value.replace(/[#?].*$/,"").split("/").some((part)=>part===".."),key2=(kind,value)=>`${kind}:${value}`;function cleanUrl(raw){try{let url2=new URL(raw);for(let key3 of[...url2.searchParams.keys()])if(/token|secret|key|credential|password/i.test(key3))url2.searchParams.set(key3,"[redacted]");return`${url2.origin}${url2.pathname}${url2.search}`}catch{return raw.replace(/([?&][^=]*(?:token|secret|key|credential|password)[^=]*=)[^&\s]+/ig,"$1[redacted]")}}function http(raw){try{let rawPath=raw.split(/[?#]/,1)[0]??raw,decoded=(()=>{try{return decodeURIComponent(rawPath)}catch{return rawPath}})(),url2=new URL(raw);if(url2.protocol!=="http:"&&url2.protocol!=="https:")return;if(!safe(raw)||esc(rawPath)||esc(decoded)||esc(url2.pathname)||/%5c/i.test(raw))throw Error(`unsafe source URL: ${cleanUrl(raw)}`);return url2.href}catch(err){if(err instanceof Error&&err.message.startsWith("unsafe"))throw err;return}}function github(raw){let spec2=raw.replace(/^github:/,""),input=spec2.replace(/^https:\/\/github\.com\//,"").replace(/^git@github\.com:/,"").replace(/^github\.com\//,"");if(input===spec2&&!raw.startsWith("github:"))return;let[path6,query=""]=input.split("?"),[head,hash]=path6.split("#"),parts2=head.replace(/\.git$/,"").split("/").filter(Boolean);if(parts2.length<2)return;let owner=parts2[0],repo=parts2[1].replace(/\.git$/,""),pathSelector=parts2.slice(2).join("/")||void 0,params=new URLSearchParams(query),ref=hash?decodeURIComponent(hash):void 0,selector=params.get("selector")?decodeURIComponent(params.get("selector")):pathSelector;for(let part of[owner,repo,ref,selector].filter(Boolean))if(!/^[A-Za-z0-9._/-]+$/.test(part)||part.split("/").some((x2)=>!x2||x2==="."||x2===".."||x2.startsWith("-")))throw Error(`unsafe GitHub source: ${raw}`);let suffix2=`${owner}/${repo}${ref?`#${ref}`:""}${selector?`?selector=${selector}`:""}`;return{kind:"github",spec:raw,sourceKey:key2("github",suffix2),owner,repo,...ref?{ref}:{},...selector?{selector}:{}}}function parseSourceSpec(raw){let spec2=clean2(raw);if(!spec2)throw Error("source spec required");if(!safe(spec2))throw Error(`unsafe source spec: ${spec2}`);if(/^(npm|registry):/.test(spec2)){let body=spec2.replace(/^(npm|registry):/,""),at=body.startsWith("@")?body.indexOf("@",1):body.lastIndexOf("@"),name=at>0?body.slice(0,at):body,range=at>0?body.slice(at+1):void 0;if(!name)throw Error(`registry source name required: ${spec2}`);return{kind:"registry",spec:spec2,sourceKey:key2("registry",body),name,...range?{range}:{},supported:!1}}if(spec2.startsWith("catalog+")){let[url3,name]=spec2.slice(8).split("#"),catalogUrl=http(url3)??(()=>{throw Error(`catalog URL must be http(s): ${spec2}`)})();return{kind:"catalog",spec:spec2,sourceKey:key2("catalog",`${catalogUrl}#${name??""}`),catalogUrl,...name?{name}:{}}}if(spec2.startsWith("catalog:")){let name=spec2.slice(8);if(!name)throw Error("catalog source name required");return{kind:"catalog",spec:spec2,sourceKey:key2("catalog",name),name}}if(spec2.startsWith("pkg:")){let url3=http(spec2.slice(4))??(()=>{throw Error(`package URL must be http(s): ${spec2}`)})();return{kind:"package-url",spec:spec2,sourceKey:key2("package",url3),url:url3}}let gh=github(spec2);if(gh)return gh;let url2=http(spec2);if(url2)return{kind:"package-url",spec:spec2,sourceKey:key2("package",url2),url:url2};if(spec2.startsWith("file://")||spec2.startsWith("/")||spec2.startsWith("./")||spec2.startsWith("../"))return{kind:"local",spec:spec2,sourceKey:key2("local",spec2),path:spec2.replace(/^file:\/\//,"")};if(!/[/:]/.test(spec2))return{kind:"catalog",spec:spec2,sourceKey:key2("catalog",spec2),name:spec2};throw Error(`unsupported source spec: ${spec2}`)}function assertWritableScope(scope="profile"){if(scope==="project-reserved")throw Error("project-reserved Eikon scope is deferred until project trust policy exists");return scope}var sha2562=(data2)=>`sha256:${createHash2("sha256").update(data2).digest("hex")}`,NAME_RE4=/^[a-z0-9][a-z0-9-]{0,63}$/,cleanUrl2=(raw)=>{try{let u3=new URL(raw);for(let key3 of[...u3.searchParams.keys()])if(/token|secret|key|credential|password/i.test(key3))u3.searchParams.set(key3,"[redacted]");if(u3.username||u3.password)return`${u3.protocol}//[redacted]@${u3.host}${u3.pathname}${u3.search}${u3.hash}`;return u3.href}catch{return raw.replace(/\/\/[^/@\s]+@/,"//[redacted]@").replace(/([?&][^=]*(?:token|secret|key|credential|password)[^=]*=)[^&\s]+/ig,"$1[redacted]")}};function assertDownloadUrl(raw,opts){if(/[\u0000-\u001f\u007f]/.test(raw)||raw.includes("\\")||/%5c/i.test(raw))throw Error(`download URL contains unsafe characters: ${cleanUrl2(raw)}`);if(pathParts(raw).some((path6)=>path6.split(/[\\/]/).some((part)=>part==="..")))throw Error(`download URL path escape: ${cleanUrl2(raw)}`);let url2=new URL(raw);if(pathParts(url2.pathname).some((path6)=>path6.split(/[\\/]/).some((part)=>part==="..")))throw Error(`download URL path escape: ${cleanUrl2(raw)}`);if(url2.protocol!=="https:"&&url2.protocol!=="http:")throw Error(`download URL must use https: ${cleanUrl2(raw)}`);if(url2.username||url2.password)throw Error(`download URL cannot include credentials: ${cleanUrl2(raw)}`);if(!opts.allowPrivate&&privateHost(url2.hostname))throw Error(`download URL cannot use private host: ${url2.hostname}`);if(url2.protocol==="http:"&&!privateHost(url2.hostname))throw Error(`download URL must use https: ${cleanUrl2(raw)}`);return url2}async function downloadBytes(raw,opts={}){let fetcher=opts.fetcher??fetch,maxBytes=opts.maxBytes??104857600,maxRedirects=opts.maxRedirects??5,url2=assertDownloadUrl(raw,opts);for(let i=0;i<=maxRedirects;i++){let res=await fetcher(url2.href,{redirect:"manual"});if(res.status>=300&&res.status<400&&res.headers.get("location")){url2=assertDownloadUrl(new URL(res.headers.get("location"),url2).href,opts);continue}if(!res.ok)throw Error(`download failed ${res.status}: ${cleanUrl2(url2.href)}`);let enc=res.headers.get("content-encoding");if(opts.rejectContentEncoding&&enc&&enc.toLowerCase()!=="identity")throw Error(`download content-encoding not allowed for artifact bytes: ${enc}`);if(Number(res.headers.get("content-length")??0)>maxBytes)throw Error(`download byte limit exceeded: ${cleanUrl2(url2.href)}`);let buf=new Uint8Array(await res.arrayBuffer());if(buf.length>maxBytes)throw Error(`download byte limit exceeded: ${cleanUrl2(url2.href)}`);return buf}throw Error(`download redirect limit exceeded: ${cleanUrl2(raw)}`)}function safeSelector(selector){if(!selector)return;if(/[\u0000-\u001f\u007f]|%|\\/.test(selector))throw Error("unsafe selector");if(selector.split("/").some((p)=>!p||p==="."||p===".."||p.startsWith("-")))throw Error("unsafe selector");let parts2=selector.split("/");if(parts2.length>2||parts2.some((p)=>!/^[A-Za-z0-9._-]+$/.test(p)))throw Error("unsafe selector");return selector}function resolveGithubSource(raw){if(/[\u0000\r\n]/.test(raw))throw Error("unsafe GitHub source");let owner,repo,rest="",m2=raw.match(/^github\.com\/([^/]+)\/([^/]+)(?:\/(.+))?$/);if(m2)owner=m2[1],repo=m2[2],rest=m2[3]??"";if(m2=raw.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/(.+))?$/),!owner&&m2)owner=m2[1],repo=m2[2],rest=m2[3]??"";if(m2=raw.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?(?:\/(.+))?$/),!owner&&m2)owner=m2[1],repo=m2[2],rest=m2[3]??"";if(!owner||!repo)throw Error("only github.com repository sources are supported");if(repo=repo.replace(/\.git$/,""),![owner,repo].every((p)=>/^[A-Za-z0-9._-]+$/.test(p))||owner.startsWith("-")||repo.startsWith("-"))throw Error("unsafe GitHub repository");let selector=safeSelector(rest.replace(/^\/+/,"")||void 0);return{owner,repo,selector,cloneUrl:`https://github.com/${owner}/${repo}.git`,display:`github.com/${owner}/${repo}${selector?`/${selector}`:""}`}}function entries(man){let pkg=validatePackageManifest(man),xs=[];if(pkg.source?.base)xs.push(["base",pkg.source.base]);for(let k2 of STATES){let f=pkg.source?.states?.[k2]?.file;if(f)xs.push([k2,f])}return xs}function manifest(value){return validatePackageManifest(value)}function installManifest(man,origin){let{license:_license,provenance:_provenance,...clean3}=man;return{...clean3,origin}}var gitish=(s)=>{if(/^(?:github\.com|https:\/\/github\.com|git@github\.com:)/.test(s))return!0;return/^git@|^ssh:\/\/|^git:\/\/|\.git$/.test(s)||/^(https?:\/\/)?(gitlab|bitbucket)\.com\/[\w.-]+\/[\w.-]+\/?$/.test(s)};async function defaultClone(url2,dst){let[raw,ref]=url2.split("#",2),source=resolveGithubSource(raw),args=["git","clone","--depth","1",...ref?["--branch",ref]:[],"--",source.cloneUrl,dst],p=Bun.spawn(args,{stdout:"pipe",stderr:"pipe"}),[code,err]=await Promise.all([p.exited,new Response(p.stderr).text()]);if(code!==0)throw Error(`git clone failed: ${err.trim()}`);let sha=await new Response(Bun.spawn(["git","-C",dst,"rev-parse","HEAD"],{stdout:"pipe"}).stdout).text();return rmSync(join7(dst,".git"),{recursive:!0,force:!0}),{dir:dst,sha:sha.trim()||void 0,cleanup:!0}}function readJson(path6){return JSON.parse(readFileSync3(path6,"utf8"))}function asPackageIndex(value){if(!value||typeof value!=="object"||Array.isArray(value))return;let raw=value;if(!Array.isArray(raw.versions))return;return raw}function latestPackageFromIndex(path6){let rel=asPackageIndex(readJson(path6))?.versions?.at(-1)?.manifest;if(!rel||!isSafeRelativePath(rel))throw Error(`${path6}: package index has no safe manifest path`);return join7(dirname5(path6),rel)}function catalogMatches(entry,selector){let slug=selector.split("/").at(-1);return[entry.id,entry.name,entry.sourceKey,entry.packageUrl.split("/packages/").at(-1)?.replace(/\/[^/]+\.json$/,"")].some((key3)=>key3===selector||key3===slug||key3?.endsWith(`/${selector}`)||key3?.endsWith(`/${slug}`))}function packageResolution(repo,selector){let parts2=selector.split("/");if(parts2.length===2){let idx=join7(repo,"packages",parts2[0],parts2[1],"index.json");if(!existsSync8(idx))return;let path7=latestPackageFromIndex(idx);return{manifest:manifest(readJson(path7)),staged:dirname5(path7),root:`packages/${parts2[0]}/${parts2[1]}/index.json`}}let matches=[],packages=join7(repo,"packages");if(existsSync8(packages))for(let ns2 of readdirSync2(packages,{withFileTypes:!0})){if(!ns2.isDirectory())continue;let idx=join7(packages,ns2.name,selector,"index.json");if(existsSync8(idx))matches.push(idx)}if(matches.length>1)throw Error(`ambiguous package selector "${selector}"; use namespace/name`);if(!matches.length)return;let path6=latestPackageFromIndex(matches[0]),ns=basename5(dirname5(dirname5(path6)));return{manifest:manifest(readJson(path6)),staged:dirname5(path6),root:`packages/${ns}/${selector}/index.json`}}function catalogResolution(repo,selector){for(let root of["eikons/index.json","registry.json","index.json"]){let path6=join7(repo,root);if(!existsSync8(path6))continue;let raw=readJson(path6);if(!Array.isArray(raw))continue;let matches=raw.map((item)=>{let any=item;if(any.packageUrl?.startsWith("../")||any.package_url?.startsWith("../")){let rel=any.packageUrl??any.package_url;return normalizeCatalogEntry({...item,packageUrl:`https://github.local/${rel.replace(/^\.\.\//,"")}`},"https://github.local/")}return normalizeCatalogEntry(item,"https://github.local/")}).filter((entry2)=>catalogMatches(entry2,selector));if(matches.length>1)throw Error(`ambiguous catalog selector "${selector}"`);if(!matches.length)continue;let entry=matches[0],pkgPath,url2=new URL(entry.packageUrl);if(pkgPath=join7(repo,url2.pathname.replace(/^\//,"")),!existsSync8(pkgPath))pkgPath=join7(dirname5(path6),entry.packageUrl);return{entry,manifest:manifest(readJson(pkgPath)),staged:dirname5(pkgPath),root}}return}function trustFor(man,staged,base){let pkg=validatePackageManifest(man),files=pkg.files??[];if(!files.length)return{state:"unverified",reason:"package descriptors missing"};if(files.filter((file)=>!file.digest||typeof file.size!=="number").length)return{state:"unverified",reason:"package descriptor digest or size missing"};if(base)return{state:"unverified",reason:"remote package files not downloaded yet"};return verifyPackageFiles(pkg,staged)}async function verifyRemotePackageFiles(pkg,base,opts){let files=pkg.files??[];if(!files.length)return{trust:{state:"unverified",reason:"package descriptors missing"}};if(files.filter((file)=>!file.digest||typeof file.size!=="number").length)return{trust:{state:"unverified",reason:"package descriptor digest or size missing"}};let verified=[],data2=new Map;for(let file of files){if(!isSafeRelativePath(file.path))throw Error(`mismatch: unsafe descriptor path ${file.path}`);let buf=await downloadBytes(new URL(file.path,base).href,{...opts,rejectContentEncoding:file.role==="runtime"&&!!file.digest});if(typeof file.size==="number"&&buf.length!==file.size)throw Error(`mismatch: size ${file.path}`);if(file.digest&&sha2562(buf)!==file.digest)throw Error(`mismatch: digest ${file.path}`);data2.set(file.path,buf),verified.push(file.path)}return{trust:{state:"verified",verified},files:data2}}function assertRemotePackageWriteCoverage(pkg,files){for(let rel of new Set([pkg.entrypoints.default,...entries(pkg).map(([,rel2])=>rel2)]))if(!files?.has(rel))throw Error(`missing verified descriptor for remote package write: ${rel}`)}function assertVerifiedPackageWriteCoverage(pkg,trust){if(trust.state!=="verified")return;let verified=new Set(trust.verified??[]);for(let rel of new Set([pkg.entrypoints.default,...entries(pkg).map(([,rel2])=>rel2)]))if(!verified.has(rel))throw Error(`missing verified descriptor for package write: ${rel}`)}function installName(name){if(!NAME_RE4.test(name))throw Error(`${name||"<empty>"}: invalid eikon name`);return name}function cleanupResolved(r){if(r.tmp)rmSync(r.cleanup??r.staged,{recursive:!0,force:!0})}function assertSafePackageFile(staged,rel){let parts2=rel.split("/"),current=staged;for(let part of parts2){current=join7(current,part);let stat=lstatSync(current);if(stat.isSymbolicLink())throw Error(`mismatch: symlink or special file ${rel}`);if(part!==parts2.at(-1)&&!stat.isDirectory())throw Error(`mismatch: symlink or special file ${rel}`);if(part===parts2.at(-1)&&!stat.isFile())throw Error(`mismatch: symlink or special file ${rel}`)}return current}function verifyPackageFiles(pkg,staged){let verified=[];for(let file of pkg.files??[]){if(!isSafeRelativePath(file.path))throw Error(`mismatch: unsafe descriptor path ${file.path}`);let path6=assertSafePackageFile(staged,file.path),data2=readFileSync3(path6);if(typeof file.size==="number"&&data2.length!==file.size)throw Error(`mismatch: size ${file.path}`);if(file.digest&&sha2562(data2)!==file.digest)throw Error(`mismatch: digest ${file.path}`);if(file.digest&&typeof file.size==="number")verified.push(file.path)}return verified.length?{state:"verified",verified}:{state:"unverified",reason:"package descriptor digest or size missing"}}function locate(dir){if(existsSync8(join7(dir,"manifest.json")))return dir;for(let e of readdirSync2(dir,{withFileTypes:!0}))if(e.isDirectory()&&existsSync8(join7(dir,e.name,"manifest.json")))return join7(dir,e.name);throw Error(`no manifest.json in ${dir} (or one level deep)`)}async function catalog(name,url2,opts={}){let base=url2.replace(/\/?$/,"/"),allow=opts.downloader?.allowPrivate||/^http:\/\/localhost[:/]/.test(base),dl=opts.downloader??(allow?{allowPrivate:!0}:{}),entry=(await loadCatalogEntries(base,async(input)=>{let raw=typeof input==="string"?input:input instanceof URL?input.href:input.url;return new Response(new TextDecoder().decode(await downloadBytes(raw,dl)))},{allowPrivate:allow})).find((e)=>e.name===name||e.id===name||e.sourceKey===name);if(!entry)throw Error(`catalog: no eikon named "${name}"`);return entry}async function resolvePackageUrl(entry,opts={},source){let at=new Date().toISOString(),bytes=await downloadBytes(entry.packageUrl,opts.downloader??(/^http:\/\/localhost[:/]/.test(entry.packageUrl)?{allowPrivate:!0}:void 0));if(entry.trust?.manifestDigest&&sha2562(bytes)!==entry.trust.manifestDigest)throw Error("mismatch: package manifest digest");let man=manifest(JSON.parse(new TextDecoder().decode(bytes))),base=new URL(".",entry.packageUrl).href,pkg=man,desc=pkg.files?.find((file)=>file.role==="runtime"&&file.path===pkg.entrypoints?.default),version=typeof man.version==="string"?man.version:man.version!=null?String(man.version):void 0;return{name:man.name,manifest:man,staged:"",base,origin:{source:source?.source??entry.packageUrl,sourceSpec:source?.spec??entry.packageUrl,at,kind:source?.kind??"default-catalog",sourceKey:entry.sourceKey,identityKey:entry.sourceKey||entry.id,packageUrl:entry.packageUrl,runtimeUrl:entry.runtimeUrl,contentDigest:desc?.digest,resolvedVersion:version},trust:trustFor(man,"",base)}}async function resolve6(src,opts={}){let at=new Date().toISOString(),local=src.replace(/^file:\/\//,"");if(!gitish(src)&&existsSync8(local)&&statSync(local).isDirectory()){let staged=locate(local),man=manifest(JSON.parse(readFileSync3(join7(staged,"manifest.json"),"utf8")));return{name:man.name,manifest:man,staged,origin:{source:src,sourceSpec:src,at,kind:"local",sourceKey:`local:${src}`},trust:trustFor(man,staged)}}let parsed=parseSourceSpec(src);if(parsed.kind==="registry")throw Error("registry Eikon sources are reserved for a future package backend");let sourceSpec=parsed.spec;if(parsed.kind==="catalog"){let base=opts.catalog??parsed.catalogUrl??DEFAULT_CATALOG;return resolvePackageUrl(await catalog(parsed.name??src,base,opts),opts,{spec:sourceSpec,source:parsed.name??src,kind:"default-catalog"})}if(parsed.kind==="package-url"){let raw=new URL(parsed.url),href=raw.pathname.endsWith(".json")?raw.href:new URL("manifest.json",parsed.url.replace(/\/?$/,"/")).href,base=new URL(".",href).href,bytes=await downloadBytes(href,opts.downloader??(/^http:\/\/localhost[:/]/.test(href)?{allowPrivate:!0}:void 0)),man=manifest(JSON.parse(new TextDecoder().decode(bytes))),version=typeof man.version==="string"?man.version:man.version!=null?String(man.version):void 0;return{name:man.name,manifest:man,staged:"",base,origin:{source:src,sourceSpec,at,kind:"catalog-package",sourceKey:parsed.sourceKey,packageUrl:href,resolvedVersion:version},trust:trustFor(man,"",base)}}if(parsed.kind==="github"||gitish(src)){let gh;if(parsed.kind==="github")gh={owner:parsed.owner,repo:parsed.repo,selector:parsed.selector,cloneUrl:`https://github.com/${parsed.owner}/${parsed.repo}.git`,display:`github.com/${parsed.owner}/${parsed.repo}${parsed.selector?`/${parsed.selector}`:""}`};else try{gh=resolveGithubSource(src)}catch{}let tmp=mkdtempSync(join7(tmpdir(),"eikon-"));if(!gh){let p=Bun.spawn(["git","clone","--depth","1","--",src,tmp],{stdout:"pipe",stderr:"pipe"}),[code,err]=await Promise.all([p.exited,new Response(p.stderr).text()]);if(code!==0)throw Error(`git clone failed: ${err.trim()}`);let sha=await new Response(Bun.spawn(["git","-C",tmp,"rev-parse","HEAD"],{stdout:"pipe"}).stdout).text();rmSync(join7(tmp,".git"),{recursive:!0,force:!0});let staged2=locate(tmp),man2=manifest(JSON.parse(readFileSync3(join7(staged2,"manifest.json"),"utf8")));return{name:man2.name,manifest:man2,staged:staged2,tmp:!0,cleanup:tmp,origin:{source:src,sourceSpec,at,kind:"github-package",sourceKey:parsed.sourceKey,sha:sha.trim()||void 0,resolvedRef:sha.trim()||void 0},trust:trustFor(man2,staged2)}}let cloneUrl=parsed.kind==="github"&&parsed.ref?`${gh.cloneUrl}#${parsed.ref}`:gh.cloneUrl,cloned=await(opts.clone??defaultClone)(cloneUrl,tmp),repo=cloned.dir;if(gh.selector){let selected=catalogResolution(repo,gh.selector);if(selected)return{name:selected.manifest.name,manifest:selected.manifest,staged:selected.staged,tmp:cloned.cleanup!==!1,cleanup:cloned.cleanup!==!1?repo:void 0,origin:{source:src,sourceSpec,at,kind:"github-catalog",sha:cloned.sha,resolvedRef:cloned.sha??(parsed.kind==="github"?parsed.ref:void 0),repo:gh.display,selector:gh.selector,catalogRoot:selected.root,sourceKey:selected.entry.sourceKey,identityKey:selected.entry.sourceKey||selected.entry.id,packageUrl:selected.entry.packageUrl,runtimeUrl:selected.entry.runtimeUrl},trust:trustFor(selected.manifest,selected.staged)};let indexed=packageResolution(repo,gh.selector);if(indexed)return{name:indexed.manifest.name,manifest:indexed.manifest,staged:indexed.staged,tmp:cloned.cleanup!==!1,cleanup:cloned.cleanup!==!1?repo:void 0,origin:{source:src,sourceSpec,at,kind:"github-catalog",sha:cloned.sha,resolvedRef:cloned.sha??(parsed.kind==="github"?parsed.ref:void 0),repo:gh.display,selector:gh.selector,catalogRoot:indexed.root,sourceKey:parsed.sourceKey},trust:trustFor(indexed.manifest,indexed.staged)};if(cloned.cleanup!==!1)rmSync(repo,{recursive:!0,force:!0});throw Error(`no eikon named "${gh.selector}" in GitHub catalog`)}let staged=locate(repo),man=manifest(JSON.parse(readFileSync3(join7(staged,"manifest.json"),"utf8")));return{name:man.name,manifest:man,staged,tmp:cloned.cleanup!==!1,cleanup:cloned.cleanup!==!1?repo:void 0,origin:{source:src,sourceSpec,at,kind:"github-package",sourceKey:parsed.sourceKey,sha:cloned.sha,resolvedRef:cloned.sha??(parsed.kind==="github"?parsed.ref:void 0),repo:gh.display},trust:trustFor(man,staged)}}throw Error(`cannot resolve "${src}": expected catalog name, git URL, local dir, or http(s) base`)}var peeked=new Map;function peek3(src,opts){let hit=peeked.get(src);if(hit)return hit;let p=resolve6(src,opts).then(async(r)=>{let xs=entries(r.manifest);if(r.base){let sizes=await Promise.all(xs.map(([,rel])=>fetch(new URL(rel,r.base).href,{method:"HEAD"}).then((h2)=>Number(h2.headers.get("content-length")??0)).catch(()=>0)));return{n:xs.length,bytes:sizes.reduce((a,b2)=>a+b2,0)}}let bytes=xs.reduce((a,[,rel])=>{let p2=join7(r.staged,rel);return a+(existsSync8(p2)?statSync(p2).size:0)},0);return{n:xs.length,bytes}}).catch(()=>{return});return peeked.set(src,p),p}async function install(src,root,opts={}){let scope=assertWritableScope(opts.scope??"profile"),r=await resolve6(src,opts);r.origin.scope=scope;let name=installName(opts.name??r.name);mkdirSync3(root,{recursive:!0});let dst=join7(root,name),tmp=mkdtempSync(join7(root,`.${name}-`)),srcd=join7(tmp,"source"),old=join7(root,`.${name}.old-${process.pid}-${Date.now()}`);try{let remote,launchBytes,man=validatePackageManifest(r.manifest),dl=opts.downloader??(/^http:\/\/localhost[:/]/.test(r.base??"")?{allowPrivate:!0}:{});if(r.base)remote=await verifyRemotePackageFiles(man,r.base,dl),assertRemotePackageWriteCoverage(man,remote.files),validatePackageManifest(man,{registry:!0}),r.trust=remote.trust;if(!r.base&&r.staged)r.trust=verifyPackageFiles(man,r.staged),assertVerifiedPackageWriteCoverage(man,r.trust);let rel=man.entrypoints.default,desc=man.files?.find((file)=>file.role==="runtime"&&file.path===rel);if(r.base)launchBytes=remote.files.get(rel);else launchBytes=readFileSync3(assertSafePackageFile(r.staged,rel));parseRuntimeBytes(launchBytes,{descriptor:desc}),mkdirSync3(srcd,{recursive:!0}),writeFileSync4(join7(tmp,`${name}.eikon`),launchBytes);let xs=entries(r.manifest),sources={},done=0,bytes=0,tick2=()=>opts.progress?.(++done,xs.length);if(opts.media!==!1)await Promise.all(xs.map(async([role,rel2])=>{let fname=`${role}${extname2(rel2).toLowerCase()}`,to=join7(srcd,fname);if(r.base){let dl2=opts.downloader??(/^http:\/\/localhost[:/]/.test(r.base)?{allowPrivate:!0}:{}),buf=remote?remote.files.get(rel2):await downloadBytes(new URL(rel2,r.base).href,dl2);await Bun.write(to,buf),bytes+=buf.length}else{let from2=assertSafePackageFile(r.staged,rel2);if(!existsSync8(from2))throw Error(`${rel2}: missing in ${r.staged}`);copyFileSync(from2,to),bytes+=statSync(to).size}sources[role]=fname,tick2()}));let out=installManifest(r.manifest,{...r.origin,trust:r.trust.state});if(writeFileSync4(join7(tmp,"manifest.json"),JSON.stringify(out,null,2)+`
4088
4088
  `),existsSync8(dst))renameSync2(dst,old);try{renameSync2(tmp,dst)}catch(err){if(existsSync8(old))renameSync2(old,dst);throw err}if(existsSync8(old))rmSync(old,{recursive:!0,force:!0});return cleanupResolved(r),{...r,name,dir:dst,sources,n:xs.length,bytes}}catch(err){throw rmSync(tmp,{recursive:!0,force:!0}),cleanupResolved(r),err}}function dirty(dir){let mf=join7(dir,"manifest.json");if(!existsSync8(mf))return!1;let man=JSON.parse(readFileSync3(mf,"utf8"));if(!man.origin?.at)return!1;let since=Date.parse(man.origin.at);for(let e of readdirSync2(dir,{withFileTypes:!0,recursive:!0}))if(statSync(join7(e.parentPath??dir,e.name)).mtimeMs>since+2000)return!0;return!1}import{existsSync as existsSync9,lstatSync as lstatSync2,readFileSync as readFileSync4}from"fs";import{basename as basename6,dirname as dirname6,join as join8,relative as relative2,resolve as resolve7,sep}from"path";var DEFAULT_SUBMIT_REPO=process.env.EIKON_REPO??"liftaris/eikon",DEFAULT_MAX_BUNDLE_BYTES=33554432,SECRET=/(\.env($|\.)|\.pem$|\.key$|\.p12$|\.pfx$|id_rsa$|id_ed25519$|token|secret|credential|password)/i,TOKEN=/(gh[pousr]_[A-Za-z0-9_]+|github_pat_[A-Za-z0-9_]+|Bearer\s+[A-Za-z0-9._~+/=-]+|token\s+[A-Za-z0-9._~+/=-]+)/gi,hidden=(rel)=>rel.split(/[\\/]/).some((p)=>p.startsWith(".")),secret=(rel)=>SECRET.test(rel),redact=(s)=>s.replace(TOKEN,"[redacted]"),posix=(s)=>s.split(sep).join("/");function contain(root,rel){if(rel.startsWith("/")||/^[A-Za-z]:[\\/]/.test(rel)||rel.split(/[\\/]/).some((p)=>p===".."))throw Error(`submission bundle path escape: ${rel}`);let abs=resolve7(root,rel),back=relative2(root,abs);if(back.startsWith("..")||back===""||resolve7(root,back)!==abs)throw Error(`submission bundle path escape: ${rel}`);return{abs,rel:posix(back)}}function add(root,rel,out,opts){let path6=contain(root,rel);if(!existsSync9(path6.abs))throw Error(`submission bundle missing source: ${path6.rel}`);if(!opts.allowHidden&&hidden(path6.rel))return;if(!opts.allowSecrets&&secret(path6.rel))return;let parts2=path6.rel.split("/"),cur=root;for(let part of parts2){cur=join8(cur,part);let st2=lstatSync2(cur);if(st2.isSymbolicLink())throw Error(`submission bundle symlink unsupported: ${path6.rel}`);if(part!==parts2.at(-1)&&!st2.isDirectory())return;if(part===parts2.at(-1)&&!st2.isFile())return}let bytes=lstatSync2(path6.abs).size;out.set(path6.rel,{path:path6.rel,abs:path6.abs,bytes})}function bundleFiles(root,packed,man,opts){let out=new Map;if(add(root,basename6(packed),out,opts),man){if(add(root,"manifest.json",out,opts),man.source)add(root,man.source,out,opts);for(let[st,v2]of Object.entries(man.states??{}))if(v2?.file)add(root,v2.file,out,opts);else throw Error(`manifest states.${st}.file required`)}for(let rel of opts.extraFiles??[])add(root,rel,out,opts);let files=[...out.values()].sort((a,b2)=>a.path.localeCompare(b2.path)),bytes=files.reduce((n,f)=>n+f.bytes,0),max=opts.maxBytes??DEFAULT_MAX_BUNDLE_BYTES;if(bytes>max)throw Error(`submission bundle too large: ${bytes} > ${max} bytes`);return files}async function previewSubmitBundle(opts){let packed=resolve7(opts.path),root=dirname6(packed),eikon;try{eikon=lint(decodeRuntimeFile(packed))}catch(err){throw Error(`invalid eikon: ${err instanceof Error?err.message:String(err)}`)}let mf=join8(root,"manifest.json"),manifest2=existsSync9(mf)?lintManifest(mf,readFileSync4(mf,"utf8")):void 0,files=bundleFiles(root,packed,manifest2,opts),catalog2=catalogEntry({name:eikon.meta.name,author:eikon.meta.author,glyph:eikon.meta.glyph,width:eikon.meta.width,height:eikon.meta.height,poster:poster(eikon),source:`${eikon.meta.name}/`,runtime_url:`${eikon.meta.name}/${eikon.meta.name}.eikon`,package_url:manifest2?`${eikon.meta.name}/manifest.json`:void 0},"https://eikon.liftaris.dev/eikons/",{allowPrivate:!0});return{root,packed,files,meta:eikon.meta,...manifest2?{manifest:manifest2}:{},catalog:catalog2}}async function submit(opts){let bundle;try{bundle=await previewSubmitBundle(opts)}catch(err){let message=err instanceof Error?err.message:String(err);return{kind:"validation-failed",failures:[{code:/missing source|\.file: .* missing/.test(message)?"missing-source":"invalid-eikon",message}]}}let backend3=opts.backend??githubSubmitBackend(),setup=await backend3.check();if(!setup.ok)return{kind:"setup-needed",failures:[{code:"missing-auth",message:redact(setup.reason)}]};let req=submission(bundle);try{return await backend3.create(req)}catch(err){return{kind:"backend-failed",failures:[{code:"backend-failed",message:redact(err instanceof Error?err.message:String(err))}]}}}function submission(bundle){let title=`eikons: submit ${bundle.meta.name}`,body=[`Submits \`${bundle.meta.name}\` by ${bundle.meta.author??"unknown"}.`,`${bundle.meta.width}\xD7${bundle.meta.height}; ${bundle.files.length} bundled files.`,"","Submission bundle:",...bundle.files.map((f)=>`- ${f.path} (${f.bytes} bytes)`)].join(`
4089
4089
  `);return{bundle,title,body}}async function gh(args,input){let p=Bun.spawn(["gh",...args],{stdin:input?new TextEncoder().encode(input):void 0,stdout:"pipe",stderr:"pipe"}),[out,err,code]=await Promise.all([new Response(p.stdout).text(),new Response(p.stderr).text(),p.exited]);if(code!==0)throw Error(`gh ${args[0]} failed: ${err.trim()||out.trim()}`);return out.trim()}async function existingSha(run,fork,branch,path6){try{let out=await run(["api","-X","GET",`repos/${fork}/contents/${path6}`,"-f",`ref=${branch}`]),json=JSON.parse(out);return typeof json.sha==="string"?json.sha:void 0}catch{return}}function githubSubmitBackend(repo=DEFAULT_SUBMIT_REPO,run=gh){return{async check(){try{return await run(["auth","status"]),{ok:!0}}catch(err){return{ok:!1,reason:err instanceof Error?err.message:String(err)}}},async create(req){let name=req.bundle.meta.name,branch=`submit/${name}`;await run(["repo","fork",repo,"--clone=false"]).catch(()=>"");let user=await run(["api","user","-q",".login"]),fork=`${user}/${repo.split("/")[1]}`,main2=await run(["api",`repos/${repo}/git/ref/heads/main`,"-q",".object.sha"]);await run(["api","-X","POST",`repos/${fork}/git/refs`,"-f",`ref=refs/heads/${branch}`,"-f",`sha=${main2}`]).catch(()=>"");for(let file of req.bundle.files){let dest=`eikons/${name}/${file.path}`,content=Buffer.from(await Bun.file(file.abs).arrayBuffer()).toString("base64"),sha=await existingSha(run,fork,branch,dest),args=["api","-X","PUT",`repos/${fork}/contents/${dest}`,"-f",`message=eikons: submit ${name}`,"-f",`branch=${branch}`,"-f",`content=${content}`];if(sha)args.push("-f",`sha=${sha}`);await run(args)}return{kind:"submitted",url:await run(["pr","create","-R",repo,"-H",`${user}:${branch}`,"-B","main","-t",req.title,"-b",req.body]),request:req}}}}var STREAM_EXT=/\.eikon$/;function readManifestEntrypoint(path6){try{let entrypoints=JSON.parse(readFileSync5(path6,"utf8")).entrypoints;if(!entrypoints||typeof entrypoints!=="object"||Array.isArray(entrypoints))return;let value=entrypoints.default;return typeof value==="string"&&STREAM_EXT.test(value)?value:void 0}catch{return}}function parseEikon(text3){let first=text3.split(`
4090
4090
  `,1)[0];if((first?JSON.parse(first):{}).type==="header"){let e2=parseLaunchStream(text3);return{meta:e2.meta,states:e2.clips,resolve:(signal)=>{try{return e2.clips.get(resolveSignal(e2,signal).clip)}catch{return}}}}let e=parse3(text3);return{meta:e.meta,states:e.clips,resolve:(signal)=>e.clips.get(signal.replace(/^state\./,""))}}function parseEikonFile(path6){return parseEikon(decodeRuntimeFile(path6))}function listEikons(dirs){return dirs.flatMap((dir)=>{let ents;try{ents=readdirSync3(dir,{recursive:!0})}catch{return[]}let paths=ents.map((e)=>join9(dir,e)),streamFiles=paths.filter((path6)=>STREAM_EXT.test(path6)),packageEntrypoints=new Map;for(let manifest2 of paths.filter((path6)=>path6.endsWith("manifest.json"))){let entrypoint=readManifestEntrypoint(manifest2);if(entrypoint){let root=dirname7(manifest2);packageEntrypoints.set(root,join9(root,entrypoint))}}let packageRootFor=(path6)=>{for(let root of packageEntrypoints.keys()){let rel=relative3(root,path6);if(rel&&!rel.startsWith("..")&&!isAbsolute2(rel))return root}return};return streamFiles.sort((a,b2)=>a.localeCompare(b2)).filter((path6)=>{let packageRoot=packageRootFor(path6);return packageRoot?path6===packageEntrypoints.get(packageRoot):!0}).map((path6)=>({path:path6,meta:peek2(resolve8(path6))})).filter((x2)=>x2.meta!==null)})}var BLANK2={fps:1,loopFrom:1,frames:[[""]]},DEFAULT_EIKON=(()=>{try{return parseEikon(default_default)}catch{return}})(),STATE_FRAMES={idle:DEFAULT_EIKON?.states.get("idle")??BLANK2,listening:DEFAULT_EIKON?.states.get("listening")??BLANK2,thinking:DEFAULT_EIKON?.states.get("thinking")??BLANK2,speaking:DEFAULT_EIKON?.states.get("speaking")??BLANK2,working:DEFAULT_EIKON?.states.get("working")??BLANK2,error:DEFAULT_EIKON?.states.get("error")??BLANK2};init_perf();var AnimatedAvatar=import_react29.memo(({state="idle",eikon,onHold})=>{let theme=useTheme().theme,[frame,setFrame]=import_react29.useState(0),timer2=import_react29.useRef(null),holdRef=import_react29.useRef(onHold);holdRef.current=onHold;let signal=`state.${state}`,clip=eikon?.resolve(signal)??eikon?.states.get(state)??STATE_FRAMES[state],{frames,fps,loopFrom}=clip,count2=frames.length,animate=usePref("animations")!==!1,targetFps=usePref("targetFps")??30,dt=1000/Math.max(1,Math.min(fps,targetFps));import_react29.useEffect(()=>{if(timer2.current)clearTimeout(timer2.current),timer2.current=null;if(setFrame(0),!animate||count2<2)return;if(count("avatar:timer:start"),process.env.HERM_TEST_PERF==="1")globalThis.__hermAvatarTimerStarts=(globalThis.__hermAvatarTimerStarts??0)+1;let idx=0,tick2=()=>{if(count("avatar:tick"),idx++,idx>=count2){if(loopFrom>=count2){setFrame(count2-1),holdRef.current?.(state);return}idx=loopFrom}setFrame(idx),timer2.current=setTimeout(tick2,dt)};return timer2.current=setTimeout(tick2,dt),()=>{if(timer2.current)clearTimeout(timer2.current),timer2.current=null,count("avatar:timer:stop")}},[state,count2,loopFrom,animate,dt]);let end=mark("avatar:render"),lines3=frames[Math.min(frame,count2-1)]??[],result=$jsx("box",{flexDirection:"column",children:lines3.map((line,i)=>$jsx("text",{children:$jsx("span",{fg:theme.hermAvatar,children:line})},i))});return end(),result});var import_react30=__toESM(require_react_production(),1);import{watch}from"fs";var TIMEOUT=500;async function git(cwd,...args){let p=Bun.spawn(["git","-C",cwd,...args],{stdout:"pipe",stderr:"ignore"}),t2=setTimeout(()=>p.kill(),TIMEOUT),out=await new Response(p.stdout).text();return clearTimeout(t2),await p.exited===0?out.trim():null}async function branch(cwd){let b2=await git(cwd,"rev-parse","--abbrev-ref","HEAD");return!b2||b2==="HEAD"?null:b2}async function gitdir(cwd){return git(cwd,"rev-parse","--absolute-git-dir")}function useGitBranch(cwd){let[val,set2]=import_react30.useState(null);return import_react30.useEffect(()=>{if(!cwd){set2(null);return}let dead=!1,w2,read=()=>branch(cwd).then((b2)=>{if(!dead)set2(b2)});return read(),gitdir(cwd).then((dir)=>{if(dead||!dir)return;try{w2=watch(dir,{persistent:!1},(_ev,f)=>{if(f==="HEAD")read()})}catch{}}),()=>{dead=!0,w2?.close()}},[cwd]),val}var rtrunc=(s,max)=>s.length<=max?s:"\u2026"+s.slice(-(max-1));var import_react31=__toESM(require_react_production(),1);var enc,load3=()=>{if(enc!==void 0)return enc;try{enc=require_main()}catch{enc=null}return enc},warmup=()=>{queueMicrotask(load3)},hash=(s)=>{let h2=5381;for(let i=0;i<s.length;i++)h2=(h2<<5)+h2+s.charCodeAt(i)|0;return String(h2)},cache2=new Map;var roughCount=(s)=>Math.ceil(s.length/4);function count2(s){if(!s)return 0;let k2=hash(s),hit=cache2.get(k2);if(hit!==void 0)return hit;let n;try{n=load3()?.countTokens(s)??roughCount(s)}catch{n=roughCount(s)}if(cache2.size>=1024){let first=cache2.keys().next().value;if(first!==void 0)cache2.delete(first)}return cache2.set(k2,n),n}function formatTokens(n){if(!Number.isFinite(n)||n<0)return"0";if(n>=1e6){let m2=n/1e6;return m2===Math.floor(m2)?`${m2}M`:`${m2.toFixed(1)}M`}if(n>=1e4)return`${Math.round(n/1000)}K`;if(n>=1000)return`${(n/1000).toFixed(1)}K`;return String(Math.round(n))}var FILL="\u2588",EMPTY="\u2591",ramp=(ratio)=>{if(ratio>=0.9)return"error";if(ratio>=0.75)return"warning";if(ratio>=0.5)return"primary";return"muted"},centered=(s,width)=>{let pad=Math.max(0,width-s.length),left=Math.ceil(pad/2),right=pad-left;return" ".repeat(left)+s+" ".repeat(right)},formatPct=(ratio)=>{let pct=ratio*100;if(pct<10)return`${pct.toFixed(1)}%`;return`${Math.round(pct)}%`},ContextGauge=import_react31.memo((props)=>{let theme=useTheme().theme,info=props.info,used=props.usage?.context_used??info?.usage?.context_used??info?.context_used,max=props.usage?.context_max??info?.usage?.context_max??info?.context_max;if(typeof max!=="number"||max<=0)return null;if(typeof used!=="number")return null;let ratio=Math.max(0,Math.min(1,used/max)),cells=Math.max(8,props.width-2),filled=Math.round(ratio*cells),bar=FILL.repeat(filled)+EMPTY.repeat(cells-filled),color=(()=>{switch(ramp(ratio)){case"error":return theme.error;case"warning":return theme.warning;case"primary":return theme.primary;default:return theme.textMuted}})(),top=`${formatTokens(used)} / ${formatTokens(max)}`,pct=formatPct(ratio);return $jsxs("box",{flexDirection:"column",marginTop:1,children:[$jsx("box",{height:1,children:$jsx("text",{children:$jsx("span",{fg:theme.textMuted,children:centered(top,props.width)})})}),$jsx("box",{height:1,children:$jsx("text",{children:$jsx("span",{fg:color,children:centered(`[${bar}]`,props.width)})})}),$jsx("box",{height:1,children:$jsx("text",{children:$jsx("span",{fg:theme.textMuted,children:centered(pct,props.width)})})})]})});var import_react32=__toESM(require_react_production(),1);var cycle=(t2)=>t2==="off"?"in":t2==="in"?"ex":"off",FilterChip=import_react32.memo((p)=>{let theme=useTheme().theme,color=p.color??theme.accent,text3=p.textColor??theme.text,bg2=p.state==="in"?color:p.state==="ex"?void 0:theme.backgroundElement,fg2=p.state==="in"?theme.background:p.state==="ex"?p.selected?color:theme.borderSubtle:p.selected?color:text3;return $jsx("box",{id:p.id,height:1,flexShrink:0,marginLeft:p.gap??1,paddingLeft:1,paddingRight:1,backgroundColor:bg2,onMouseDown:p.onMouseDown,children:$jsx("text",{fg:fg2,attributes:p.state==="ex"?TextAttributes.STRIKETHROUGH:TextAttributes.NONE,children:p.label})})});var WIDTH=48,PAD_L=12,INNER=WIDTH-4,trunc=(s,max)=>s.length<=max?s:s.slice(0,max-1)+"\u2026",Section=import_react33.memo((props)=>{let theme=useTheme().theme,[hover,setHover]=import_react33.useState(!1);return $jsxs("box",{flexDirection:"column",marginBottom:props.open?1:0,children:[$jsx("box",{height:1,onMouseDown:props.onToggle,onMouseOver:()=>setHover(!0),onMouseOut:()=>setHover(!1),children:$jsxs("text",{children:[$jsx("span",{fg:hover?theme.text:theme.textMuted,children:props.open?"\u25BE ":"\u25B8 "}),$jsx("span",{fg:theme.text,children:$jsx("strong",{children:props.title})}),props.hint?$jsx("span",{fg:theme.textMuted,children:` ${props.hint}`}):null]})}),props.open?$jsx("box",{flexDirection:"column",children:props.children}):null]})}),Avatar=(props)=>$jsx(AnimatedAvatar,{state:props.state,eikon:props.eikon,onHold:props.onHold},props.id),Row=(props)=>{let theme=useTheme().theme;if(props.block)return $jsxs("box",{flexDirection:"column",minHeight:2,marginBottom:1,children:[$jsx("text",{fg:theme.textMuted,children:` ${props.label}`}),$jsx("text",{fg:theme.text,wrapMode:"word",children:props.value})]});return $jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:` ${props.label.padEnd(PAD_L)}`}),props.strong?$jsx("span",{fg:theme.text,children:$jsx("strong",{children:trunc(props.value,INNER-PAD_L-2)})}):$jsx("span",{fg:theme.text,children:trunc(props.value,INNER-PAD_L-2)})]})})},Preview=(props)=>{let theme=useTheme().theme,meta=props.preview.eikon.meta,rows2=props.preview.rows??[{label:"Author",value:meta.author??"\u2014"},{label:"State",value:props.preview.state}],states=props.preview.states?.length?props.preview.states:void 0;return $jsxs("box",{flexDirection:"column",children:[$jsx(Row,{label:"Eikon",value:props.preview.title??meta.name,strong:!0}),props.preview.subtitle?$jsx(Row,{label:"Author",value:props.preview.subtitle}):null,props.preview.body?$jsx("box",{marginTop:1,marginBottom:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:props.preview.body})}):null,states?$jsx("box",{flexDirection:"row",flexWrap:"wrap",marginBottom:1,children:states.map((s,i)=>$jsx(FilterChip,{label:s,state:s===props.preview.state?"in":"off",gap:i===0?0:1,color:theme.primary,textColor:theme.textMuted,onMouseDown:()=>{if(props.preview.onState)props.preview.onState(s)}},s))}):null,rows2.map((r,i)=>$jsx(Row,{label:r.label,value:r.value,strong:r.strong,block:r.block},`${r.label}:${i}`))]})},Sidebar=import_react33.memo((props)=>{let theme=useTheme().theme,state=props.preview?.state??props.agentState??"idle",info=props.info,eikon=props.preview?.eikon??props.eikon,preview=!!props.preview,[mcpOpen,setMcpOpen]=import_react33.useState(!1),cwd=info?.cwd??process.cwd(),branch2=useGitBranch(cwd);return $jsxs("box",{width:WIDTH,flexDirection:"column",children:[$jsxs("box",{position:"relative",flexDirection:"column",height:24,overflow:"hidden",onMouseDown:preview?void 0:props.onAvatar,children:[$jsx(Avatar,{id:props.preview?.key,state,eikon,onHold:preview?void 0:props.onAvatarHold}),!preview&&props.cloud?$jsx("box",{position:"absolute",left:0,top:0,children:$jsx(Tail,{run:!!props.pulse})}):null]}),$jsxs("box",{padding:1,flexDirection:"column",flexGrow:1,overflow:"hidden",border:["top","left","right"],borderStyle:"double",borderColor:theme.hermAvatar,children:[props.preview?$jsx(Preview,{preview:props.preview}):$jsxs($Fragment,{children:[$jsx(Row,{label:"Title",value:props.title||"\u2014",strong:!!props.title}),$jsx(Row,{label:"Profile",value:props.profile??"default",strong:!!props.profile&&props.profile!=="default"}),$jsx(Row,{label:"Model",value:info?.model??"\u2014"}),info?.cwd?$jsx(Row,{label:"cwd",value:info.cwd}):null,branch2?$jsx(Row,{label:"Branch",value:rtrunc(branch2,INNER-PAD_L-2)}):null,(info?.mcp_servers?.length??0)>0?(()=>{let srv=info.mcp_servers,ok=srv.filter((s)=>s.connected).length;return $jsx(Section,{title:"MCP",hint:`${ok}/${srv.length} up`,open:mcpOpen,onToggle:()=>setMcpOpen((o)=>!o),children:srv.map((s)=>$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" "}),$jsx("span",{fg:s.connected?theme.text:theme.textMuted,children:(s.connected?"\u25CF ":"\u25CB ")+trunc(s.name,16).padEnd(16)}),$jsx("span",{fg:theme.textMuted,children:s.connected?` ${s.transport} \xB7 ${s.tools}t`:" failed"})]})},s.name))})})():null]}),$jsx("box",{flexGrow:1}),!props.preview?$jsx(ContextGauge,{info,usage:props.usage,width:INNER}):null]})]})});var import_react45=__toESM(require_react_production(),1);var import_react44=__toESM(require_react_production(),1);var import_react42=__toESM(require_react_production(),1);var import_react34=__toESM(require_react_production(),1);var LEFT_BAR={topLeft:"",bottomLeft:"",topRight:"",bottomRight:"",horizontal:"",vertical:"\u2503",topT:"",bottomT:"",leftT:"",rightT:"",cross:""},SIDE_PIPE={topLeft:"\u2502",bottomLeft:"\u2502",vertical:"\u2502",topRight:"\u2502",bottomRight:"\u2502",horizontal:"",topT:"",bottomT:"",leftT:"",rightT:"",cross:""},CORNERS={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:" ",vertical:" ",topT:" ",bottomT:" ",leftT:" ",rightT:" ",cross:" "};import{platform}from"os";var OSC52_CAPABLE=["ghostty","kitty","WezTerm","windows-terminal","vscode"];function detect(){let env2=process.env;if(env2.CURSOR_TRACE_ID)return"cursor";if(env2.TERM==="xterm-ghostty")return"ghostty";if(env2.TERM?.includes("kitty"))return"kitty";if(env2.TERM_PROGRAM)return env2.TERM_PROGRAM;if(env2.TMUX)return"tmux";if(env2.STY)return"screen";if(env2.KITTY_WINDOW_ID)return"kitty";if(env2.WT_SESSION)return"windows-terminal";return env2.TERM??null}var terminal=detect();function supportsOsc52Clipboard(t2=terminal){return OSC52_CAPABLE.includes(t2??"")}function shouldUseNativeClipboard(env2=process.env,t2=terminal){if(env2.SSH_CONNECTION)return!1;if(env2.TMUX||env2.STY)return!0;if(!process.stdout.isTTY)return!0;return!supportsOsc52Clipboard(t2)}function writeOsc52(text3){if(!process.stdout.isTTY)return;let osc52=`\x1B]52;c;${Buffer.from(text3).toString("base64")}\x07`,seq=process.env.TMUX||process.env.STY?`\x1BPtmux;\x1B${osc52}\x1B\\`:osc52;process.stdout.write(seq)}async function nativeCopy(text3){let os2=platform();if(os2==="darwin"){let proc=Bun.spawn(["pbcopy"],{stdin:"pipe"});proc.stdin.write(text3),proc.stdin.end(),await proc.exited;return}if(os2==="linux"){if(process.env.WAYLAND_DISPLAY)try{let proc=Bun.spawn(["wl-copy"],{stdin:"pipe",stdout:"ignore",stderr:"ignore"});proc.stdin.write(text3),proc.stdin.end(),await proc.exited;return}catch{}try{let proc=Bun.spawn(["xclip","-selection","clipboard"],{stdin:"pipe",stdout:"ignore",stderr:"ignore"});proc.stdin.write(text3),proc.stdin.end(),await proc.exited;return}catch{}try{let proc=Bun.spawn(["xsel","--clipboard","--input"],{stdin:"pipe",stdout:"ignore",stderr:"ignore"});proc.stdin.write(text3),proc.stdin.end(),await proc.exited;return}catch{}}}async function copy(text3){if(writeOsc52(text3),shouldUseNativeClipboard())await nativeCopy(text3).catch(()=>{})}function copySelection(renderer){let text3=renderer.getSelection()?.getSelectedText();if(!text3)return!1;return copy(text3).catch(()=>{}),renderer.clearSelection(),!0}var CAP2=6,ErrorBlock=import_react34.memo(({text:text3})=>{let theme=useTheme().theme,[open,setOpen]=import_react34.useState(!1),[copied,setCopied]=import_react34.useState(!1),lines3=text3.trimEnd().split(`
@@ -4125,16 +4125,17 @@ Current chat will be replaced.`,yes:"load"}).then((ok)=>{if(ok)l.onSwitch?.(sid2
4125
4125
 
4126
4126
  Its gateway is running and will be stopped first (may take up to ~10s).`:"";if(!await openConfirm(dialog,{title:"Delete Profile?",body:`'${p.name}' \u2014 config, env, memory, skills, and sessions will be removed. This cannot be undone.${warn}`,yes:"delete",danger:!0}))return;sh(`hermes profile delete ${p.name} -y`).then(()=>{toast.show({variant:"success",message:`Deleted '${p.name}'`}),loadProfiles()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[sh,dialog,toast,loadProfiles]),pSwitch=import_react74.useCallback(async(i)=>{let p=live.current.profiles[i];if(!p||p.is_active||!props.onSwitchProfile)return;if(await openConfirm(dialog,{title:`Switch to '${p.name}'?`,body:"The gateway restarts under this profile's HERMES_HOME. The current session ends (it stays in the outgoing profile's history).",yes:"switch"}))props.onSwitchProfile(p.path,p.name)},[dialog,props.onSwitchProfile]),pUpdate=import_react74.useCallback((p,force)=>{let cmd2=`hermes profile update ${p.name} -y${force?" --force-config":""}`;toast.show({variant:"info",message:`Updating '${p.name}'\u2026`}),sh(cmd2).then(()=>{if(toast.show({variant:"success",message:`Updated '${p.name}'`}),p.is_active&&props.onSwitchProfile){props.onSwitchProfile(p.path,p.name);return}loadProfiles()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[sh,toast,loadProfiles,props.onSwitchProfile]),pEnter=import_react74.useCallback((i)=>{setPSel(i);let p=live.current.profiles[i];if(!p)return;openProfileMenu(dialog,p,{switch:props.onSwitchProfile?()=>pSwitch(i):void 0,sticky:(pp)=>sh(`hermes profile use ${pp.name}`).then(()=>{toast.show({variant:"success",message:`Sticky default \u2192 '${pp.name}'`}),loadProfiles()}).catch((e)=>toast.show({variant:"error",message:e.message})),unsticky:()=>sh("hermes profile use --clear").then(()=>{toast.show({variant:"info",message:"Cleared sticky default"}),loadProfiles()}).catch((e)=>toast.show({variant:"error",message:e.message})),export:(pp)=>sh(`hermes profile export ${pp.name}`).then((out)=>toast.show({variant:"success",message:trunc5(out.trim()||`Exported '${pp.name}'`,80)})).catch((e)=>toast.show({variant:"error",message:e.message})),remove:()=>pDelete(i),update:(pp,force)=>pUpdate(pp,force)})},[sh,dialog,toast,loadProfiles,pDelete,pSwitch,pUpdate,props.onSwitchProfile]),dKill=import_react74.useCallback(async(i)=>{let r=live.current.active[i];if(!r)return;if(!await openConfirm(dialog,{title:"Interrupt subagent?",body:`${trunc5(r.goal,120)}
4127
4127
 
4128
- The child returns whatever partial result it has so far.`,yes:"interrupt",danger:!0}))return;gw.request("subagent.interrupt",{subagent_id:r.subagent_id}).then((res)=>{toast.show(res.found?{variant:"success",message:`Interrupted ${r.subagent_id}`}:{variant:"info",message:"Already finished"}),loadDeleg()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,loadDeleg]),create=import_react74.useCallback(()=>{openCreateProfile(dialog,{existing:live.current.profiles.map((p)=>p.name)}).then((r)=>{if(!r)return;let flags=[r.cloneFrom?`--clone --clone-from ${r.cloneFrom}`:"",r.alias?"":"--no-alias"].filter(Boolean).join(" ");return toast.show({variant:"info",message:`Creating '${r.name}'\u2026`}),sh(`hermes profile create ${r.name} ${flags}`.trim()).then(()=>{toast.show({variant:"success",message:`Created '${r.name}'`}),loadProfiles()})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[sh,dialog,toast,loadProfiles]),install2=import_react74.useCallback(()=>{openInstallDistribution(dialog,gw).then((r)=>{if(!r)return;let shq2=(s)=>`'${s.replace(/'/g,"'\\''")}'`,flags=[r.name?`--name ${shq2(r.name)}`:"",r.alias?"--alias":""].filter(Boolean).join(" ");return toast.show({variant:"info",message:`Installing '${r.manifest.name}'\u2026`}),sh(`hermes profile install ${shq2(r.source)} -y ${flags}`.trim()).then(()=>{let installed=r.name||r.manifest.name;toast.show({variant:"success",message:`Installed '${installed}'`}),loadProfiles();let reqs=r.manifest.env_requires.filter((e)=>e.required).map((e)=>e.name);if(reqs.length>0)toast.show({variant:"warning",title:"Env vars needed",message:`${reqs.join(", ")} \u2014 add to the profile's .env before using it`,duration:6000})})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,sh,dialog,toast,loadProfiles]),selected=profiles[pSel],statGen=import_react74.useRef(0);import_react74.useEffect(()=>{let path7=selected?.path;if(!path7||stats.has(path7))return;let g=++statGen.current;profileStats(path7).then((s)=>{if(statGen.current!==g)return;setStats((prev)=>new Map(prev).set(path7,s))})},[selected?.path,stats]);let dims=useTerminalDimensions(),wide=dims.width>=130,pWide=dims.width>=170||!wide&&dims.width>=90,pFollow=useFollow("prof"),dFollow=useFollow("deleg"),keys=useKeys();useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(key3.name==="tab")return setPane((p)=>p==="profiles"?"deleg":"profiles");if(keys.match("list.refresh",key3)){loadProfiles(),loadDeleg(),toast.show({variant:"info",message:"Reloaded",duration:1000});return}if(pane==="profiles"){if(key3.name==="escape"&&!pWide&&pView==="detail")return setPView("list");if(key3.name==="s")return void pSwitch(pSel);if(keys.match("agents.install",key3))return install2();handleListKey(keys,key3,{count:profiles.length,setSel:setPSel,...pFollow.opts,onNew:create,onDelete:()=>pDelete(pSel),onActivate:()=>{if(!pWide&&pView==="list")return setPView("detail");pEnter(pSel)}});return}if(handleListKey(keys,key3,{count:active.length,setSel:setDSel,...dFollow.opts,onDelete:()=>dKill(dSel)}))return;if(keys.match("agents.kill",key3))return dKill(dSel);if(keys.match("agents.history",key3))return openSpawnHistory(dialog,gw,props.sessionId)});let showProfiles=wide||pane==="profiles",showDeleg=wide||pane==="deleg",showList=pWide||pView==="list",showDetail=pWide||pView==="detail",limits=deleg?`depth\u2264${deleg.max_spawn_depth} \xB7 conc\u2264${deleg.max_concurrent_children}`:"",dHint=active.length>0?`${spark(nodes)} ${summary(all)}`:limits,togglePause=import_react74.useCallback(()=>{let next=!deleg?.paused;gw.request("delegation.pause",{paused:next}).then((r)=>{setDeleg((d2)=>d2?{...d2,paused:r.paused}:d2),toast.show({variant:"info",message:r.paused?"Delegation paused":"Delegation resumed"})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,deleg?.paused]);import_react74.useEffect(()=>cmd.register([{title:deleg?.paused?"Resume Delegation":"Pause Delegation",value:"deleg.pause",category:"Agents",onSelect:togglePause},{title:"Install Distribution\u2026",value:"profile.install",category:"Agents",description:"from git URL or local directory",onSelect:install2}]),[cmd,togglePause,deleg?.paused,install2]);let pair=(k2,v2)=>`[${k2}] ${v2}`,join13=(...parts2)=>parts2.filter(Boolean).join(" "),sw=props.onSwitchProfile?pair("s","switch"):"",profilesHint=`${pWide?join13("[\u2191\u2193] nav",pair(keys.print("list.activate"),"actions"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("agents.install"),"install"),pair(keys.print("list.delete"),"delete"),pair(keys.print("list.refresh"),"refresh")):pView==="list"?join13("[\u2191\u2193] nav",pair(keys.print("list.activate"),"detail"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("list.delete"),"delete")):join13(pair(keys.print("list.activate"),"actions"),sw,"[Esc] back",pair(keys.print("list.delete"),"delete"))} ${pair("Tab",wide?"\u2192 delegation":"\u2194 delegation")}`,delegKeys=join13("[\u2191\u2193] nav",pair(keys.print("agents.kill"),"interrupt"),pair(keys.print("agents.history"),"history"),pair(keys.print("list.refresh"),"refresh")),delegHint=dHint?`${delegKeys} \xB7 ${dHint}`:delegKeys,footerHint=wide?pane==="profiles"?`${profilesHint} \xB7 ${delegHint}`:`${delegHint} \xB7 ${profilesHint}`:pane==="profiles"?profilesHint:delegHint;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[showProfiles?$jsx(TabShell,{title:`Profiles (${profiles.length})${sticky?` \xB7 \u2605 ${sticky}`:""}`,error:err||null,focus:pane==="profiles",grow:3,children:$jsxs("box",{flexDirection:"row",flexGrow:1,minWidth:0,children:[showList?$jsx("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:14,children:$jsx("scrollbox",{ref:pFollow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:profiles.length===0?$jsx("box",{height:1,children:err?$jsx("text",{fg:theme.textMuted,children:"\u2014"}):$jsx(Spinner,{color:theme.textMuted,label:"scanning profiles\u2026"})}):profiles.map((p,i)=>$jsx(ProfileRow,{id:pFollow.id(i),p,idx:i,selected:i===pSel,onHover:pHover,onEnter:pEnter,onDelete:pDelete},p.name))})}):null,showList&&showDetail?$jsx("box",{width:2}):null,showDetail?$jsx("box",{flexDirection:"column",flexGrow:2,flexBasis:0,minWidth:0,children:selected?$jsx(ProfileDetail,{p:selected,stats:stats.get(selected.path)}):$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No profiles"})})}):null]})}):null,showDeleg?$jsxs(TabShell,{title:`Delegation (${active.length})`,focus:pane==="deleg",grow:2,children:[$jsxs("box",{height:1,flexDirection:"row",marginBottom:1,children:[$jsx("box",{flexShrink:0,paddingX:1,backgroundColor:deleg?.paused?theme.warning:theme.backgroundElement,onMouseDown:togglePause,children:$jsx("text",{fg:deleg?.paused?theme.background:theme.text,children:deleg?.paused?"\u23F8 paused":"\u25B6 active"})}),$jsx("box",{flexGrow:1}),$jsxs("text",{fg:theme.textMuted,children:["click to ",deleg?.paused?"resume":"pause"]})]}),active.length===0?$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.textMuted,children:deleg?.paused?"Paused \u2014 new subagents will queue":"No subagents running \xB7 h for history"})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:0,children:[$jsx("scrollbox",{ref:dFollow.ref,scrollY:!0,flexGrow:3,flexBasis:0,verticalScrollbarOptions:VBAR,children:active.map((r,i)=>{let lv=liveMap.get(r.subagent_id),row3=lv?{...r,tool_count:lv.tool_count}:r,h2=heat(aggOf.get(r.subagent_id)?.hot??0,hotPeak,HOT.length);return $jsx(DelegRow,{id:dFollow.id(i),r:row3,idx:i,selected:i===dSel,now,hot:h2,onHover:dHover,onKill:dKill},r.subagent_id)})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.border,children:"\u2500".repeat(4)})}),$jsx("box",{flexGrow:2,flexBasis:0,minHeight:0,children:active[dSel]?$jsx(DelegDetail,{r:active[dSel],live:liveMap.get(active[dSel].subagent_id),agg:aggOf.get(active[dSel].subagent_id),now}):null})]},"body")]}):null]}),$jsx(HintBar,{raw:footerHint})]})});var import_react76=__toESM(require_react_production(),1);var normalize=(j2)=>({id:j2.job_id??j2.id??"",name:j2.name??"",prompt:j2.prompt??j2.prompt_preview??"",schedule:j2.schedule??"",enabled:j2.enabled??!0,state:j2.state??"scheduled",deliver:j2.deliver??"local",repeat:j2.repeat,last_run:j2.last_run_at,next_run:j2.next_run_at,last_status:j2.last_status==="ok"||j2.last_status==="error"?j2.last_status:void 0,last_error:j2.last_delivery_error,paused_reason:j2.paused_reason,model:j2.model,skills:j2.skills,workdir:j2.workdir,script:j2.script}),sec2=(iso2)=>iso2?new Date(iso2).getTime()/1000:null,last2=(iso2)=>{let t2=sec2(iso2);return t2?ago(t2):"\u2014"},next=(iso2)=>{let t2=sec2(iso2);return t2?until(t2):"\u2014"},JobRow=import_react76.memo((props)=>{let theme=useTheme().theme,j2=props.job,bg2=props.selected?theme.backgroundElement:void 0,glyph=j2.enabled?"\u25CF":"\u25CB",glyphColor=!j2.enabled?theme.textMuted:j2.last_status==="error"?theme.error:j2.last_status==="ok"?theme.success:theme.textMuted;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:bg2,onMouseDown:props.onSelect,onMouseMove:props.onHover,children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "}),$jsx(Col,{w:2,fg:glyphColor,children:`${glyph} `}),$jsx(Col,{grow:!0,fg:props.selected?theme.accent:theme.text,children:j2.name||j2.id}),$jsx(Col,{w:18,fg:theme.textMuted,children:j2.schedule||"\u2014"}),$jsx(Col,{w:16,fg:theme.textMuted,children:`last: ${last2(j2.last_run)}`}),$jsx(Col,{w:16,fg:j2.enabled?theme.text:theme.textMuted,children:`next: ${j2.enabled?next(j2.next_run):"paused"}`})]})}),DetailPanel=import_react76.memo((props)=>{let theme=useTheme().theme,j2=props.job,[output,setOutput]=import_react76.useState(null);return import_react76.useEffect(()=>{let live=!0;return readCronOutput(j2.id,30).then((o)=>{if(live)setOutput(o)}),()=>{live=!1}},[j2.id,props.reloadKey]),$jsx(TabShell,{title:"Job Detail",grow:2,children:$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:j2.name||j2.id})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["ID",j2.id],["State",j2.enabled?"active":"paused",j2.enabled?theme.success:theme.warning],["Schedule",j2.schedule||"\u2014"],["Repeat",j2.repeat],["Deliver",j2.deliver??"local"],["Last Run",j2.last_run?`${last2(j2.last_run)} \xB7 ${j2.last_status??"?"}`:"never",j2.last_status==="error"?theme.error:void 0],["Next Run",j2.enabled?next(j2.next_run):"paused"],["Model",j2.model],["Skills",j2.skills?.length?j2.skills.join(", "):void 0],["Workdir",j2.workdir],["Script",j2.script],["Paused",j2.paused_reason],["Error",j2.last_error,theme.error]]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Prompt"})}),$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.text,children:j2.prompt})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["Last Output",output?` \xB7 ${ago(output.at.getTime()/1000)}`:""]})}),output?$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.text,children:output.text})}):$jsx("text",{fg:theme.textMuted,children:"(none yet)"})]})})})}),Cron=import_react76.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),[jobs,setJobs]=import_react76.useState([]),[sel,setSel]=import_react76.useState(0),[err,setErr]=import_react76.useState(null),[reloadKey,setReloadKey]=import_react76.useState(0),live=import_react76.useRef({jobs,sel});live.current={jobs,sel};let load4=import_react76.useCallback(()=>{gw.request("cron.manage",{action:"list"}).then((res)=>{setJobs((res.jobs??[]).map(normalize)),setErr(null),setReloadKey((k2)=>k2+1)}).catch((e)=>setErr(e instanceof Error?e.message:String(e)))},[gw]);import_react76.useEffect(()=>{load4()},[load4]);let create=import_react76.useCallback(async()=>{let schedule=await openTextPrompt(dialog,{title:"New Cron Job",label:"Schedule (cron expr or 'every 30m')"});if(schedule===null)return;let prompt=await openTextPrompt(dialog,{title:"New Cron Job",label:"Prompt"});if(prompt===null)return;gw.request("cron.manage",{action:"add",name:"",schedule,prompt}).then(()=>{toast.show({variant:"success",message:"Job created"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4]),toggle=import_react76.useCallback(()=>{let j2=live.current.jobs[live.current.sel];if(!j2)return;let action=j2.enabled?"pause":"resume";gw.request("cron.manage",{action,name:j2.id}).then(()=>{toast.show({variant:"success",message:j2.enabled?"Paused":"Resumed"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,load4]),remove2=import_react76.useCallback(async()=>{let j2=live.current.jobs[live.current.sel];if(!j2)return;if(!await openConfirm(dialog,{title:"Delete Job?",body:`Delete "${j2.name||j2.id}"? This cannot be undone.`,yes:"delete",danger:!0}))return;gw.request("cron.manage",{action:"remove",name:j2.id}).then(()=>{toast.show({variant:"success",message:"Deleted"}),setSel((s)=>Math.max(0,Math.min(s,live.current.jobs.length-2))),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4]),follow=useFollow("cron"),keys=useListKeys({active:()=>!!props.focused&&!dialog.open(),count:jobs.length,setSel,...follow.opts,onToggle:toggle,onDelete:remove2,onNew:create,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})}}),job=jobs[sel]??null,showDetail=dims.width>=120&&job!==null;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx(TabShell,{title:`Cron Jobs (${jobs.length})`,error:err,grow:3,children:jobs.length===0?$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.textMuted,children:"No cron jobs. Press n to create one."})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs(Hdr,{children:[$jsx(Col,{w:4,fg:theme.textMuted,children:""}),$jsx(Col,{grow:!0,fg:theme.textMuted,bold:!0,children:"Name"}),$jsx(Col,{w:18,fg:theme.textMuted,bold:!0,children:"Schedule"}),$jsx(Col,{w:16,fg:theme.textMuted,bold:!0,children:"Last"}),$jsx(Col,{w:16,fg:theme.textMuted,bold:!0,children:"Next"})]}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:jobs.map((j2,i)=>$jsx(JobRow,{id:follow.id(i),job:j2,selected:i===sel,onSelect:()=>setSel(i),onHover:()=>setSel(i)},j2.id))})]},"table")}),showDetail?$jsx(DetailPanel,{job,reloadKey}):null]}),$jsx(HintBar,{pairs:[["\u2191\u2193","nav"],[keys.print("list.new"),"new"],[keys.print("list.toggle"),"pause/resume"],[keys.print("list.delete"),"delete"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react80=__toESM(require_react_production(),1);import{Database as Database3}from"bun:sqlite";import{existsSync as existsSync15,readdirSync as readdirSync5,statSync as statSync4,openSync as openSync2,readSync as readSync2,closeSync as closeSync2,readFileSync as readFileSync8,fstatSync}from"fs";var STATUSES=["triage","todo","scheduled","ready","running","blocked","done"],SEV=new Set(["warning","error","critical"]);function parseDiagnostics(stdout){let trimmed=stdout.trim();if(!trimmed)return[];let raw;try{raw=JSON.parse(trimmed)}catch{return[]}if(!Array.isArray(raw))return[];return raw.flatMap((r)=>{if(!r||typeof r!=="object")return[];let rec=r,id=rec.task_id;if(typeof id!=="string"||!id)return[];let diags=Array.isArray(rec.diagnostics)?rec.diagnostics:[];return[{task_id:id,title:typeof rec.title==="string"?rec.title:void 0,status:typeof rec.status==="string"?rec.status:void 0,assignee:typeof rec.assignee==="string"?rec.assignee:null,diagnostics:diags.flatMap(toDiag)}]})}var toDiag=(raw)=>{if(!raw||typeof raw!=="object")return[];let r=raw,sev=r.severity;if(typeof sev!=="string"||!SEV.has(sev))return[];let actions=Array.isArray(r.actions)?r.actions.flatMap(toAction):[];return[{kind:String(r.kind??""),severity:sev,title:String(r.title??""),detail:String(r.detail??""),actions,first_seen_at:Number(r.first_seen_at)||0,last_seen_at:Number(r.last_seen_at)||0,count:Number(r.count)||1,run_id:typeof r.run_id==="number"?r.run_id:null,data:r.data&&typeof r.data==="object"?r.data:{}}]},toAction=(raw)=>{if(!raw||typeof raw!=="object")return[];let r=raw,kind2=r.kind,label2=r.label;if(typeof kind2!=="string"||typeof label2!=="string")return[];return[{kind:kind2,label:label2,payload:r.payload&&typeof r.payload==="object"?r.payload:{},suggested:r.suggested===!0}]},SEV_RANK={critical:3,error:2,warning:1},maxSeverity=(ds)=>{let best=null;for(let d2 of ds)if(!best||SEV_RANK[d2.severity]>SEV_RANK[best])best=d2.severity;return best},sortDiags=(ds)=>[...ds].sort((a,b2)=>SEV_RANK[b2.severity]-SEV_RANK[a.severity]||a.kind.localeCompare(b2.kind)),DEFAULT2="default",SLUG=/^[a-z0-9][a-z0-9_-]{0,63}$/,DEFAULT_BUSY_TIMEOUT_MS=120000,busyTimeoutMs=()=>{let raw=(process.env.HERMES_KANBAN_BUSY_TIMEOUT_MS??"").trim();if(!raw)return DEFAULT_BUSY_TIMEOUT_MS;let n=Number(raw);return Number.isFinite(n)&&n>0?Math.floor(n):DEFAULT_BUSY_TIMEOUT_MS},kanbanRoot=()=>{let pin=(process.env.HERMES_KANBAN_HOME??"").trim();if(pin)return pin.replace(/[\\/]+$/,"");return hermesPath("").replace(/[\\/]+$/,"").replace(/[\\/]profiles[\\/][^\\/]+$/,"")},kp=(rel2)=>`${kanbanRoot()}/${rel2}`,resolve9=()=>{let env2=(process.env.HERMES_KANBAN_BOARD??"").trim().toLowerCase();if(SLUG.test(env2))return env2;try{let txt=readFileSync8(kp("kanban/current"),"utf-8").trim().toLowerCase();if(SLUG.test(txt))return txt}catch{}return DEFAULT2},slug=resolve9(),handles=new Map,errors2=new Map,SQLITE_HEADER=Buffer.from("SQLite format 3\x00","binary"),CORRUPT_BACKUP=/^kanban\.db\.corrupt\..+\.bak$/,currentBoard=()=>slug,dbPath=(s)=>kp(s===DEFAULT2?"kanban.db":`kanban/boards/${s}/kanban.db`),dbDir=(s)=>kp(s===DEFAULT2?"":`kanban/boards/${s}`),logsDir=(s)=>kp(s===DEFAULT2?"kanban/logs":`kanban/boards/${s}/logs`),pair=(s)=>{let cached2=handles.get(s);if(cached2)return cached2;let next2={ro:null,rw:null};return handles.set(s,next2),next2},emptyBoard=()=>new Map(STATUSES.map((k2)=>[k2,[]])),boardErr=(kind2,path7,msg)=>({kind:kind2,path:path7,message:msg}),isCorrupt=(err)=>{let msg=String(err?.message??err).toLowerCase();return msg.includes("not a database")||msg.includes("malformed")||msg.includes("database disk image")||msg.includes("file is not a database")},headerError=(path7)=>{let st;try{st=statSync4(path7)}catch(e){return e.code==="ENOENT"?null:boardErr("unreadable",path7,String(e.message??e))}if(st.size===0)return null;let fd=-1;try{fd=openSync2(path7,"r");let head=Buffer.alloc(SQLITE_HEADER.length),n=readSync2(fd,head,0,head.length,0);if(n>=SQLITE_HEADER.length&&head.subarray(0,SQLITE_HEADER.length).equals(SQLITE_HEADER))return null;return boardErr("corrupt",path7,`invalid SQLite header; first_32=${head.subarray(0,Math.min(32,n)).toString("hex").match(/../g)?.join(" ")??""}`)}catch(e){return boardErr("unreadable",path7,String(e.message??e))}finally{if(fd>=0)try{closeSync2(fd)}catch{}}},dbOf=(s)=>{let h2=pair(s);if(h2.ro)return h2.ro;let path7=dbPath(s);if(!existsSync15(path7))return errors2.delete(s),null;let hdr=headerError(path7);if(hdr)return errors2.set(s,hdr),null;try{h2.ro=new Database3(path7,{readwrite:!0,create:!1}),errors2.delete(s)}catch(e){h2.ro=null,errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path7,String(e.message??e)))}return h2.ro},rwOf=(s)=>{let h2=pair(s);if(h2.rw)return h2.rw;let path7=dbPath(s);if(!existsSync15(path7))return null;let hdr=headerError(path7);if(hdr)return errors2.set(s,hdr),null;try{let db=new Database3(path7);db.exec(`PRAGMA busy_timeout=${busyTimeoutMs()}`);try{db.exec("PRAGMA journal_mode=WAL")}catch{}return db.exec(["PRAGMA synchronous=FULL","PRAGMA wal_autocheckpoint=100","PRAGMA secure_delete=ON","PRAGMA cell_size_check=ON","PRAGMA foreign_keys=ON"].join(";")),h2.rw=db,errors2.delete(s),db}catch(e){return errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path7,String(e.message??e))),null}},resetKanban=()=>{for(let h2 of handles.values())h2.ro?.close(),h2.rw?.close();handles.clear(),errors2.clear(),slug=resolve9()};function corruptBackupsOf(s){let dir=dbDir(s)||kanbanRoot();try{return readdirSync5(dir,{withFileTypes:!0}).filter((e)=>e.isFile()&&CORRUPT_BACKUP.test(e.name)).map((e)=>`${dir}/${e.name}`).sort()}catch{return[]}}function listBoards(){let out=new Map([[DEFAULT2,"Default"]]),dir=kp("kanban/boards");if(existsSync15(dir))for(let e of readdirSync5(dir,{withFileTypes:!0})){if(!e.isDirectory()||!SLUG.test(e.name))continue;let name=e.name;try{let meta=JSON.parse(readFileSync8(`${dir}/${e.name}/board.json`,"utf-8")),n=typeof meta?.name==="string"?meta.name:typeof meta?.display_name==="string"?meta.display_name:null;if(n)name=n}catch{}out.set(e.name,name)}return[...out].map(([s,n])=>({slug:s,name:n})).sort((a,b2)=>a.slug===DEFAULT2?-1:b2.slug===DEFAULT2?1:a.slug.localeCompare(b2.slug))}var AT="COALESCE(completed_at, started_at, created_at)",cols=new WeakMap,colsOf=(conn2)=>{let cached2=cols.get(conn2);if(cached2)return cached2;let set2=new Set;try{for(let r of conn2.query("PRAGMA table_info(tasks)").all())set2.add(r.name)}catch{}return cols.set(conn2,set2),set2},selectCol=(have,name,alias)=>{let a=alias??name;return have.has(name)?`${name} AS ${a}`:`NULL AS ${a}`},taskColumns=(have)=>["id","title",selectCol(have,"body"),selectCol(have,"assignee"),"status","priority",selectCol(have,"tenant"),selectCol(have,"created_at"),selectCol(have,"completed_at"),selectCol(have,"result"),selectCol(have,"last_spawn_error"),selectCol(have,"worker_pid"),selectCol(have,"workspace_kind"),selectCol(have,"workspace_path"),selectCol(have,"branch_name"),selectCol(have,"skills"),selectCol(have,"max_runtime_seconds"),selectCol(have,"max_retries"),selectCol(have,"model_override"),selectCol(have,"session_id"),selectCol(have,"last_heartbeat_at"),`${AT} AS updated_at`].join(", "),parseSkills=(raw)=>{if(typeof raw!=="string"||!raw)return[];try{let j2=JSON.parse(raw);return Array.isArray(j2)?j2.filter((v2)=>typeof v2==="string"&&!!v2):[]}catch{return[]}},toTask=(r)=>({id:String(r.id),title:String(r.title??""),body:r.body??null,assignee:r.assignee??null,status:r.status??"todo",priority:Number(r.priority)||0,created_at:Number(r.created_at)||0,updated_at:Number(r.updated_at)||0,completed_at:r.completed_at??null,result:r.result??null,error:r.last_spawn_error??null,tenant:r.tenant??null,pid:r.worker_pid??null,workspace_kind:r.workspace_kind??null,workspace_path:r.workspace_path??null,branch_name:r.branch_name??null,skills:parseSkills(r.skills),max_runtime_seconds:r.max_runtime_seconds??null,max_retries:r.max_retries??null,model_override:r.model_override??null,session_id:r.session_id??null,last_heartbeat_at:r.last_heartbeat_at??null}),toRun=(r)=>({id:Number(r.id),profile:r.profile??null,status:r.status??null,outcome:r.outcome??null,started_at:Number(r.started_at)||0,ended_at:r.ended_at??null,summary:r.summary??null,error:r.error??null,worker_pid:r.worker_pid??null}),toEvent=(r)=>{let raw=r.payload,payload=null;if(raw)try{payload=JSON.parse(raw)}catch{payload=raw}return{id:Number(r.id),kind:String(r.kind??""),payload,created_at:Number(r.created_at)||0,run_id:r.run_id??null}};function boardOf(s){let out=emptyBoard(),conn2=dbOf(s);if(!conn2)return out;try{let rows3=conn2.query(`SELECT ${taskColumns(colsOf(conn2))}
4128
+ The child returns whatever partial result it has so far.`,yes:"interrupt",danger:!0}))return;gw.request("subagent.interrupt",{subagent_id:r.subagent_id}).then((res)=>{toast.show(res.found?{variant:"success",message:`Interrupted ${r.subagent_id}`}:{variant:"info",message:"Already finished"}),loadDeleg()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,loadDeleg]),create=import_react74.useCallback(()=>{openCreateProfile(dialog,{existing:live.current.profiles.map((p)=>p.name)}).then((r)=>{if(!r)return;let flags=[r.cloneFrom?`--clone --clone-from ${r.cloneFrom}`:"",r.alias?"":"--no-alias"].filter(Boolean).join(" ");return toast.show({variant:"info",message:`Creating '${r.name}'\u2026`}),sh(`hermes profile create ${r.name} ${flags}`.trim()).then(()=>{toast.show({variant:"success",message:`Created '${r.name}'`}),loadProfiles()})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[sh,dialog,toast,loadProfiles]),install2=import_react74.useCallback(()=>{openInstallDistribution(dialog,gw).then((r)=>{if(!r)return;let shq2=(s)=>`'${s.replace(/'/g,"'\\''")}'`,flags=[r.name?`--name ${shq2(r.name)}`:"",r.alias?"--alias":""].filter(Boolean).join(" ");return toast.show({variant:"info",message:`Installing '${r.manifest.name}'\u2026`}),sh(`hermes profile install ${shq2(r.source)} -y ${flags}`.trim()).then(()=>{let installed=r.name||r.manifest.name;toast.show({variant:"success",message:`Installed '${installed}'`}),loadProfiles();let reqs=r.manifest.env_requires.filter((e)=>e.required).map((e)=>e.name);if(reqs.length>0)toast.show({variant:"warning",title:"Env vars needed",message:`${reqs.join(", ")} \u2014 add to the profile's .env before using it`,duration:6000})})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,sh,dialog,toast,loadProfiles]),selected=profiles[pSel],statGen=import_react74.useRef(0);import_react74.useEffect(()=>{let path7=selected?.path;if(!path7||stats.has(path7))return;let g=++statGen.current;profileStats(path7).then((s)=>{if(statGen.current!==g)return;setStats((prev)=>new Map(prev).set(path7,s))})},[selected?.path,stats]);let dims=useTerminalDimensions(),wide=dims.width>=130,pWide=dims.width>=170||!wide&&dims.width>=90,pFollow=useFollow("prof"),dFollow=useFollow("deleg"),keys=useKeys();useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(key3.name==="tab")return setPane((p)=>p==="profiles"?"deleg":"profiles");if(keys.match("list.refresh",key3)){loadProfiles(),loadDeleg(),toast.show({variant:"info",message:"Reloaded",duration:1000});return}if(pane==="profiles"){if(key3.name==="escape"&&!pWide&&pView==="detail")return setPView("list");if(key3.name==="s")return void pSwitch(pSel);if(keys.match("agents.install",key3))return install2();handleListKey(keys,key3,{count:profiles.length,setSel:setPSel,...pFollow.opts,onNew:create,onDelete:()=>pDelete(pSel),onActivate:()=>{if(!pWide&&pView==="list")return setPView("detail");pEnter(pSel)}});return}if(handleListKey(keys,key3,{count:active.length,setSel:setDSel,...dFollow.opts,onDelete:()=>dKill(dSel)}))return;if(keys.match("agents.kill",key3))return dKill(dSel);if(keys.match("agents.history",key3))return openSpawnHistory(dialog,gw,props.sessionId)});let showProfiles=wide||pane==="profiles",showDeleg=wide||pane==="deleg",showList=pWide||pView==="list",showDetail=pWide||pView==="detail",limits=deleg?`depth\u2264${deleg.max_spawn_depth} \xB7 conc\u2264${deleg.max_concurrent_children}`:"",dHint=active.length>0?`${spark(nodes)} ${summary(all)}`:limits,togglePause=import_react74.useCallback(()=>{let next=!deleg?.paused;gw.request("delegation.pause",{paused:next}).then((r)=>{setDeleg((d2)=>d2?{...d2,paused:r.paused}:d2),toast.show({variant:"info",message:r.paused?"Delegation paused":"Delegation resumed"})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,deleg?.paused]);import_react74.useEffect(()=>cmd.register([{title:deleg?.paused?"Resume Delegation":"Pause Delegation",value:"deleg.pause",category:"Agents",onSelect:togglePause},{title:"Install Distribution\u2026",value:"profile.install",category:"Agents",description:"from git URL or local directory",onSelect:install2}]),[cmd,togglePause,deleg?.paused,install2]);let pair=(k2,v2)=>`[${k2}] ${v2}`,join13=(...parts2)=>parts2.filter(Boolean).join(" "),sw=props.onSwitchProfile?pair("s","switch"):"",profilesHint=`${pWide?join13("[\u2191\u2193] nav",pair(keys.print("list.activate"),"actions"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("agents.install"),"install"),pair(keys.print("list.delete"),"delete"),pair(keys.print("list.refresh"),"refresh")):pView==="list"?join13("[\u2191\u2193] nav",pair(keys.print("list.activate"),"detail"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("list.delete"),"delete")):join13(pair(keys.print("list.activate"),"actions"),sw,"[Esc] back",pair(keys.print("list.delete"),"delete"))} ${pair("Tab",wide?"\u2192 delegation":"\u2194 delegation")}`,delegKeys=join13("[\u2191\u2193] nav",pair(keys.print("agents.kill"),"interrupt"),pair(keys.print("agents.history"),"history"),pair(keys.print("list.refresh"),"refresh")),delegHint=dHint?`${delegKeys} \xB7 ${dHint}`:delegKeys,footerHint=wide?pane==="profiles"?`${profilesHint} \xB7 ${delegHint}`:`${delegHint} \xB7 ${profilesHint}`:pane==="profiles"?profilesHint:delegHint;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[showProfiles?$jsx(TabShell,{title:`Profiles (${profiles.length})${sticky?` \xB7 \u2605 ${sticky}`:""}`,error:err||null,focus:pane==="profiles",grow:3,children:$jsxs("box",{flexDirection:"row",flexGrow:1,minWidth:0,children:[showList?$jsx("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:14,children:$jsx("scrollbox",{ref:pFollow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:profiles.length===0?$jsx("box",{height:1,children:err?$jsx("text",{fg:theme.textMuted,children:"\u2014"}):$jsx(Spinner,{color:theme.textMuted,label:"scanning profiles\u2026"})}):profiles.map((p,i)=>$jsx(ProfileRow,{id:pFollow.id(i),p,idx:i,selected:i===pSel,onHover:pHover,onEnter:pEnter,onDelete:pDelete},p.name))})}):null,showList&&showDetail?$jsx("box",{width:2}):null,showDetail?$jsx("box",{flexDirection:"column",flexGrow:2,flexBasis:0,minWidth:0,children:selected?$jsx(ProfileDetail,{p:selected,stats:stats.get(selected.path)}):$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No profiles"})})}):null]})}):null,showDeleg?$jsxs(TabShell,{title:`Delegation (${active.length})`,focus:pane==="deleg",grow:2,children:[$jsxs("box",{height:1,flexDirection:"row",marginBottom:1,children:[$jsx("box",{flexShrink:0,paddingX:1,backgroundColor:deleg?.paused?theme.warning:theme.backgroundElement,onMouseDown:togglePause,children:$jsx("text",{fg:deleg?.paused?theme.background:theme.text,children:deleg?.paused?"\u23F8 paused":"\u25B6 active"})}),$jsx("box",{flexGrow:1}),$jsxs("text",{fg:theme.textMuted,children:["click to ",deleg?.paused?"resume":"pause"]})]}),active.length===0?$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.textMuted,children:deleg?.paused?"Paused \u2014 new subagents will queue":"No subagents running \xB7 h for history"})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:0,children:[$jsx("scrollbox",{ref:dFollow.ref,scrollY:!0,flexGrow:3,flexBasis:0,verticalScrollbarOptions:VBAR,children:active.map((r,i)=>{let lv=liveMap.get(r.subagent_id),row3=lv?{...r,tool_count:lv.tool_count}:r,h2=heat(aggOf.get(r.subagent_id)?.hot??0,hotPeak,HOT.length);return $jsx(DelegRow,{id:dFollow.id(i),r:row3,idx:i,selected:i===dSel,now,hot:h2,onHover:dHover,onKill:dKill},r.subagent_id)})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.border,children:"\u2500".repeat(4)})}),$jsx("box",{flexGrow:2,flexBasis:0,minHeight:0,children:active[dSel]?$jsx(DelegDetail,{r:active[dSel],live:liveMap.get(active[dSel].subagent_id),agg:aggOf.get(active[dSel].subagent_id),now}):null})]},"body")]}):null]}),$jsx(HintBar,{raw:footerHint})]})});var import_react76=__toESM(require_react_production(),1);var normalize=(j2)=>({id:j2.job_id??j2.id??"",name:j2.name??"",prompt:j2.prompt??j2.prompt_preview??"",schedule:j2.schedule??"",enabled:j2.enabled??!0,state:j2.state??"scheduled",deliver:j2.deliver??"local",repeat:j2.repeat,last_run:j2.last_run_at,next_run:j2.next_run_at,last_status:j2.last_status==="ok"||j2.last_status==="error"?j2.last_status:void 0,last_error:j2.last_delivery_error,paused_reason:j2.paused_reason,model:j2.model,skills:j2.skills,workdir:j2.workdir,script:j2.script}),sec2=(iso2)=>iso2?new Date(iso2).getTime()/1000:null,last2=(iso2)=>{let t2=sec2(iso2);return t2?ago(t2):"\u2014"},next=(iso2)=>{let t2=sec2(iso2);return t2?until(t2):"\u2014"},JobRow=import_react76.memo((props)=>{let theme=useTheme().theme,j2=props.job,bg2=props.selected?theme.backgroundElement:void 0,glyph=j2.enabled?"\u25CF":"\u25CB",glyphColor=!j2.enabled?theme.textMuted:j2.last_status==="error"?theme.error:j2.last_status==="ok"?theme.success:theme.textMuted;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:bg2,onMouseDown:props.onSelect,onMouseMove:props.onHover,children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "}),$jsx(Col,{w:2,fg:glyphColor,children:`${glyph} `}),$jsx(Col,{grow:!0,fg:props.selected?theme.accent:theme.text,children:j2.name||j2.id}),$jsx(Col,{w:18,fg:theme.textMuted,children:j2.schedule||"\u2014"}),$jsx(Col,{w:16,fg:theme.textMuted,children:`last: ${last2(j2.last_run)}`}),$jsx(Col,{w:16,fg:j2.enabled?theme.text:theme.textMuted,children:`next: ${j2.enabled?next(j2.next_run):"paused"}`})]})}),DetailPanel=import_react76.memo((props)=>{let theme=useTheme().theme,j2=props.job,[output,setOutput]=import_react76.useState(null);return import_react76.useEffect(()=>{let live=!0;return readCronOutput(j2.id,30).then((o)=>{if(live)setOutput(o)}),()=>{live=!1}},[j2.id,props.reloadKey]),$jsx(TabShell,{title:"Job Detail",grow:2,children:$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:j2.name||j2.id})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["ID",j2.id],["State",j2.enabled?"active":"paused",j2.enabled?theme.success:theme.warning],["Schedule",j2.schedule||"\u2014"],["Repeat",j2.repeat],["Deliver",j2.deliver??"local"],["Last Run",j2.last_run?`${last2(j2.last_run)} \xB7 ${j2.last_status??"?"}`:"never",j2.last_status==="error"?theme.error:void 0],["Next Run",j2.enabled?next(j2.next_run):"paused"],["Model",j2.model],["Skills",j2.skills?.length?j2.skills.join(", "):void 0],["Workdir",j2.workdir],["Script",j2.script],["Paused",j2.paused_reason],["Error",j2.last_error,theme.error]]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Prompt"})}),$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.text,children:j2.prompt})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["Last Output",output?` \xB7 ${ago(output.at.getTime()/1000)}`:""]})}),output?$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.text,children:output.text})}):$jsx("text",{fg:theme.textMuted,children:"(none yet)"})]})})})}),Cron=import_react76.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),[jobs,setJobs]=import_react76.useState([]),[sel,setSel]=import_react76.useState(0),[err,setErr]=import_react76.useState(null),[reloadKey,setReloadKey]=import_react76.useState(0),live=import_react76.useRef({jobs,sel});live.current={jobs,sel};let load4=import_react76.useCallback(()=>{gw.request("cron.manage",{action:"list"}).then((res)=>{setJobs((res.jobs??[]).map(normalize)),setErr(null),setReloadKey((k2)=>k2+1)}).catch((e)=>setErr(e instanceof Error?e.message:String(e)))},[gw]);import_react76.useEffect(()=>{load4()},[load4]);let create=import_react76.useCallback(async()=>{let schedule=await openTextPrompt(dialog,{title:"New Cron Job",label:"Schedule (cron expr or 'every 30m')"});if(schedule===null)return;let prompt=await openTextPrompt(dialog,{title:"New Cron Job",label:"Prompt"});if(prompt===null)return;gw.request("cron.manage",{action:"add",name:"",schedule,prompt}).then(()=>{toast.show({variant:"success",message:"Job created"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4]),toggle=import_react76.useCallback(()=>{let j2=live.current.jobs[live.current.sel];if(!j2)return;let action=j2.enabled?"pause":"resume";gw.request("cron.manage",{action,name:j2.id}).then(()=>{toast.show({variant:"success",message:j2.enabled?"Paused":"Resumed"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,load4]),remove2=import_react76.useCallback(async()=>{let j2=live.current.jobs[live.current.sel];if(!j2)return;if(!await openConfirm(dialog,{title:"Delete Job?",body:`Delete "${j2.name||j2.id}"? This cannot be undone.`,yes:"delete",danger:!0}))return;gw.request("cron.manage",{action:"remove",name:j2.id}).then(()=>{toast.show({variant:"success",message:"Deleted"}),setSel((s)=>Math.max(0,Math.min(s,live.current.jobs.length-2))),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4]),follow=useFollow("cron"),keys=useListKeys({active:()=>!!props.focused&&!dialog.open(),count:jobs.length,setSel,...follow.opts,onToggle:toggle,onDelete:remove2,onNew:create,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})}}),job=jobs[sel]??null,showDetail=dims.width>=120&&job!==null;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx(TabShell,{title:`Cron Jobs (${jobs.length})`,error:err,grow:3,children:jobs.length===0?$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.textMuted,children:"No cron jobs. Press n to create one."})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs(Hdr,{children:[$jsx(Col,{w:4,fg:theme.textMuted,children:""}),$jsx(Col,{grow:!0,fg:theme.textMuted,bold:!0,children:"Name"}),$jsx(Col,{w:18,fg:theme.textMuted,bold:!0,children:"Schedule"}),$jsx(Col,{w:16,fg:theme.textMuted,bold:!0,children:"Last"}),$jsx(Col,{w:16,fg:theme.textMuted,bold:!0,children:"Next"})]}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:jobs.map((j2,i)=>$jsx(JobRow,{id:follow.id(i),job:j2,selected:i===sel,onSelect:()=>setSel(i),onHover:()=>setSel(i)},j2.id))})]},"table")}),showDetail?$jsx(DetailPanel,{job,reloadKey}):null]}),$jsx(HintBar,{pairs:[["\u2191\u2193","nav"],[keys.print("list.new"),"new"],[keys.print("list.toggle"),"pause/resume"],[keys.print("list.delete"),"delete"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react80=__toESM(require_react_production(),1);import{Database as Database3}from"bun:sqlite";import{existsSync as existsSync15,readdirSync as readdirSync5,statSync as statSync4,openSync as openSync2,readSync as readSync2,closeSync as closeSync2,readFileSync as readFileSync8,fstatSync}from"fs";import{relative as pathRelative,resolve as pathResolve}from"path";var STATUSES=["triage","todo","scheduled","ready","running","blocked","done"],SEV=new Set(["warning","error","critical"]);function parseDiagnostics(stdout){let trimmed=stdout.trim();if(!trimmed)return[];let raw;try{raw=JSON.parse(trimmed)}catch{return[]}if(!Array.isArray(raw))return[];return raw.flatMap((r)=>{if(!r||typeof r!=="object")return[];let rec=r,id=rec.task_id;if(typeof id!=="string"||!id)return[];let diags=Array.isArray(rec.diagnostics)?rec.diagnostics:[];return[{task_id:id,title:typeof rec.title==="string"?rec.title:void 0,status:typeof rec.status==="string"?rec.status:void 0,assignee:typeof rec.assignee==="string"?rec.assignee:null,diagnostics:diags.flatMap(toDiag)}]})}var toDiag=(raw)=>{if(!raw||typeof raw!=="object")return[];let r=raw,sev=r.severity;if(typeof sev!=="string"||!SEV.has(sev))return[];let actions=Array.isArray(r.actions)?r.actions.flatMap(toAction):[];return[{kind:String(r.kind??""),severity:sev,title:String(r.title??""),detail:String(r.detail??""),actions,first_seen_at:Number(r.first_seen_at)||0,last_seen_at:Number(r.last_seen_at)||0,count:Number(r.count)||1,run_id:typeof r.run_id==="number"?r.run_id:null,data:r.data&&typeof r.data==="object"?r.data:{}}]},toAction=(raw)=>{if(!raw||typeof raw!=="object")return[];let r=raw,kind2=r.kind,label2=r.label;if(typeof kind2!=="string"||typeof label2!=="string")return[];return[{kind:kind2,label:label2,payload:r.payload&&typeof r.payload==="object"?r.payload:{},suggested:r.suggested===!0}]},SEV_RANK={critical:3,error:2,warning:1},maxSeverity=(ds)=>{let best=null;for(let d2 of ds)if(!best||SEV_RANK[d2.severity]>SEV_RANK[best])best=d2.severity;return best},sortDiags=(ds)=>[...ds].sort((a,b2)=>SEV_RANK[b2.severity]-SEV_RANK[a.severity]||a.kind.localeCompare(b2.kind)),DEFAULT2="default",SLUG=/^[a-z0-9][a-z0-9_-]{0,63}$/,DEFAULT_BUSY_TIMEOUT_MS=120000,busyTimeoutMs=()=>{let raw=(process.env.HERMES_KANBAN_BUSY_TIMEOUT_MS??"").trim();if(!raw)return DEFAULT_BUSY_TIMEOUT_MS;let n=Number(raw);return Number.isFinite(n)&&n>0?Math.floor(n):DEFAULT_BUSY_TIMEOUT_MS},kanbanRoot=()=>{let pin=(process.env.HERMES_KANBAN_HOME??"").trim();if(pin)return pin.replace(/[\\/]+$/,"");return hermesPath("").replace(/[\\/]+$/,"").replace(/[\\/]profiles[\\/][^\\/]+$/,"")},kp=(rel2)=>`${kanbanRoot()}/${rel2}`,resolve9=()=>{let env2=(process.env.HERMES_KANBAN_BOARD??"").trim().toLowerCase();if(SLUG.test(env2))return env2;try{let txt=readFileSync8(kp("kanban/current"),"utf-8").trim().toLowerCase();if(SLUG.test(txt))return txt}catch{}return DEFAULT2},slug=resolve9(),handles=new Map,errors2=new Map,SQLITE_HEADER=Buffer.from("SQLite format 3\x00","binary"),CORRUPT_BACKUP=/^kanban\.db\.corrupt\..+\.bak$/,currentBoard=()=>slug,dbPath=(s)=>kp(s===DEFAULT2?"kanban.db":`kanban/boards/${s}/kanban.db`),dbDir=(s)=>kp(s===DEFAULT2?"":`kanban/boards/${s}`),logsDir=(s)=>kp(s===DEFAULT2?"kanban/logs":`kanban/boards/${s}/logs`),attachmentsRoot=(s)=>{let pin=(process.env.HERMES_KANBAN_ATTACHMENTS_ROOT??"").trim();if(pin)return pathResolve(pin);return pathResolve(kp(s===DEFAULT2?"kanban/attachments":`kanban/boards/${s}/attachments`))},safeAttachmentPath=(s,raw)=>{if(typeof raw!=="string"||!raw)return null;let root2=attachmentsRoot(s),path7=pathResolve(raw);return path7===root2||path7.startsWith(`${root2}/`)?path7:null},attachmentRelPath=(s,path7)=>path7?pathRelative(attachmentsRoot(s),path7):null,pair=(s)=>{let cached2=handles.get(s);if(cached2)return cached2;let next2={ro:null,rw:null};return handles.set(s,next2),next2},emptyBoard=()=>new Map(STATUSES.map((k2)=>[k2,[]])),boardErr=(kind2,path7,msg)=>({kind:kind2,path:path7,message:msg}),isCorrupt=(err)=>{let msg=String(err?.message??err).toLowerCase();return msg.includes("not a database")||msg.includes("malformed")||msg.includes("database disk image")||msg.includes("file is not a database")},headerError=(path7)=>{let st;try{st=statSync4(path7)}catch(e){return e.code==="ENOENT"?null:boardErr("unreadable",path7,String(e.message??e))}if(st.size===0)return null;let fd=-1;try{fd=openSync2(path7,"r");let head=Buffer.alloc(SQLITE_HEADER.length),n=readSync2(fd,head,0,head.length,0);if(n>=SQLITE_HEADER.length&&head.subarray(0,SQLITE_HEADER.length).equals(SQLITE_HEADER))return null;return boardErr("corrupt",path7,`invalid SQLite header; first_32=${head.subarray(0,Math.min(32,n)).toString("hex").match(/../g)?.join(" ")??""}`)}catch(e){return boardErr("unreadable",path7,String(e.message??e))}finally{if(fd>=0)try{closeSync2(fd)}catch{}}},dbOf=(s)=>{let h2=pair(s);if(h2.ro)return h2.ro;let path7=dbPath(s);if(!existsSync15(path7))return errors2.delete(s),null;let hdr=headerError(path7);if(hdr)return errors2.set(s,hdr),null;try{h2.ro=new Database3(path7,{readwrite:!0,create:!1}),errors2.delete(s)}catch(e){h2.ro=null,errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path7,String(e.message??e)))}return h2.ro},rwOf=(s)=>{let h2=pair(s);if(h2.rw)return h2.rw;let path7=dbPath(s);if(!existsSync15(path7))return null;let hdr=headerError(path7);if(hdr)return errors2.set(s,hdr),null;try{let db=new Database3(path7);db.exec(`PRAGMA busy_timeout=${busyTimeoutMs()}`);try{db.exec("PRAGMA journal_mode=WAL")}catch{}return db.exec(["PRAGMA synchronous=FULL","PRAGMA wal_autocheckpoint=100","PRAGMA secure_delete=ON","PRAGMA cell_size_check=ON","PRAGMA foreign_keys=ON"].join(";")),h2.rw=db,errors2.delete(s),db}catch(e){return errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path7,String(e.message??e))),null}},resetKanban=()=>{for(let h2 of handles.values())h2.ro?.close(),h2.rw?.close();handles.clear(),errors2.clear(),slug=resolve9()};function corruptBackupsOf(s){let dir=dbDir(s)||kanbanRoot();try{return readdirSync5(dir,{withFileTypes:!0}).filter((e)=>e.isFile()&&CORRUPT_BACKUP.test(e.name)).map((e)=>`${dir}/${e.name}`).sort()}catch{return[]}}function listBoards(){let out=new Map([[DEFAULT2,"Default"]]),dir=kp("kanban/boards");if(existsSync15(dir))for(let e of readdirSync5(dir,{withFileTypes:!0})){if(!e.isDirectory()||!SLUG.test(e.name))continue;let name=e.name;try{let meta=JSON.parse(readFileSync8(`${dir}/${e.name}/board.json`,"utf-8")),n=typeof meta?.name==="string"?meta.name:typeof meta?.display_name==="string"?meta.display_name:null;if(n)name=n}catch{}out.set(e.name,name)}return[...out].map(([s,n])=>({slug:s,name:n})).sort((a,b2)=>a.slug===DEFAULT2?-1:b2.slug===DEFAULT2?1:a.slug.localeCompare(b2.slug))}var AT="COALESCE(completed_at, started_at, created_at)",cols=new WeakMap,colsOf=(conn2)=>{let cached2=cols.get(conn2);if(cached2)return cached2;let set2=new Set;try{for(let r of conn2.query("PRAGMA table_info(tasks)").all())set2.add(r.name)}catch{}return cols.set(conn2,set2),set2},selectCol=(have,name,alias)=>{let a=alias??name;return have.has(name)?`${name} AS ${a}`:`NULL AS ${a}`},taskColumns=(have)=>["id","title",selectCol(have,"body"),selectCol(have,"assignee"),"status","priority",selectCol(have,"tenant"),selectCol(have,"created_at"),selectCol(have,"completed_at"),selectCol(have,"result"),selectCol(have,"last_spawn_error"),selectCol(have,"worker_pid"),selectCol(have,"workspace_kind"),selectCol(have,"workspace_path"),selectCol(have,"branch_name"),selectCol(have,"skills"),selectCol(have,"max_runtime_seconds"),selectCol(have,"max_retries"),selectCol(have,"model_override"),selectCol(have,"session_id"),selectCol(have,"last_heartbeat_at"),`${AT} AS updated_at`].join(", "),parseSkills=(raw)=>{if(typeof raw!=="string"||!raw)return[];try{let j2=JSON.parse(raw);return Array.isArray(j2)?j2.filter((v2)=>typeof v2==="string"&&!!v2):[]}catch{return[]}},toTask=(r)=>({id:String(r.id),title:String(r.title??""),body:r.body??null,assignee:r.assignee??null,status:r.status??"todo",priority:Number(r.priority)||0,created_at:Number(r.created_at)||0,updated_at:Number(r.updated_at)||0,completed_at:r.completed_at??null,result:r.result??null,error:r.last_spawn_error??null,tenant:r.tenant??null,pid:r.worker_pid??null,workspace_kind:r.workspace_kind??null,workspace_path:r.workspace_path??null,branch_name:r.branch_name??null,skills:parseSkills(r.skills),max_runtime_seconds:r.max_runtime_seconds??null,max_retries:r.max_retries??null,model_override:r.model_override??null,session_id:r.session_id??null,last_heartbeat_at:r.last_heartbeat_at??null}),toRun=(r)=>({id:Number(r.id),profile:r.profile??null,status:r.status??null,outcome:r.outcome??null,started_at:Number(r.started_at)||0,ended_at:r.ended_at??null,summary:r.summary??null,error:r.error??null,worker_pid:r.worker_pid??null}),toEvent=(r)=>{let raw=r.payload,payload=null;if(raw)try{payload=JSON.parse(raw)}catch{payload=raw}return{id:Number(r.id),kind:String(r.kind??""),payload,created_at:Number(r.created_at)||0,run_id:r.run_id??null}},toAttachment=(s,r)=>{let filename=String(r.filename??""),size=Number(r.size),path7=safeAttachmentPath(s,r.stored_path);return{id:Number(r.id),filename,name:filename,size:Number.isFinite(size)?size:null,created_at:Number(r.created_at)||0,stored_path:String(r.stored_path??""),relative_path:attachmentRelPath(s,path7),path:path7}};function boardOf(s){let out=emptyBoard(),conn2=dbOf(s);if(!conn2)return out;try{let rows3=conn2.query(`SELECT ${taskColumns(colsOf(conn2))}
4129
4129
  FROM tasks WHERE status != 'archived'
4130
- ORDER BY priority DESC, updated_at DESC`).all();for(let r of rows3){let t2=toTask(r);out.get(t2.status)?.push(t2)}errors2.delete(s)}catch(e){errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"query",dbPath(s),String(e.message??e)))}return out}function boardStateOf(s){return{columns:boardOf(s),error:errors2.get(s)??null,corruptBackups:corruptBackupsOf(s)}}var EVENT_TAIL=20;function detailOf(s,id){let conn2=dbOf(s);if(!conn2)return null;try{let row3=conn2.query(`SELECT ${taskColumns(colsOf(conn2))} FROM tasks WHERE id = ?`).get(id);if(!row3)return null;let parents=conn2.query("SELECT parent_id FROM task_links WHERE child_id = ?").all(id).map((r)=>r.parent_id),children2=conn2.query("SELECT child_id FROM task_links WHERE parent_id = ?").all(id).map((r)=>r.child_id),comments=conn2.query("SELECT author, body, created_at FROM task_comments WHERE task_id = ? ORDER BY created_at").all(id).map((c)=>({author:c.author,body:c.body,at:c.created_at})),runs=runsOf(conn2,id),events=eventsOf(conn2,id),latest2=latestSummary(conn2,id);return{...toTask(row3),parents,children:children2,comments,runs,events,latest_summary:latest2}}catch{return null}}var runsOf=(conn2,id)=>{try{return conn2.query(`SELECT id, profile, status, outcome, started_at, ended_at,
4130
+ ORDER BY priority DESC, updated_at DESC`).all();for(let r of rows3){let t2=toTask(r);out.get(t2.status)?.push(t2)}errors2.delete(s)}catch(e){errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"query",dbPath(s),String(e.message??e)))}return out}function boardStateOf(s){return{columns:boardOf(s),error:errors2.get(s)??null,corruptBackups:corruptBackupsOf(s)}}var EVENT_TAIL=20;function detailOf(s,id){let conn2=dbOf(s);if(!conn2)return null;try{let row3=conn2.query(`SELECT ${taskColumns(colsOf(conn2))} FROM tasks WHERE id = ?`).get(id);if(!row3)return null;let parents=conn2.query("SELECT parent_id FROM task_links WHERE child_id = ?").all(id).map((r)=>r.parent_id),children2=conn2.query("SELECT child_id FROM task_links WHERE parent_id = ?").all(id).map((r)=>r.child_id),comments=conn2.query("SELECT author, body, created_at FROM task_comments WHERE task_id = ? ORDER BY created_at").all(id).map((c)=>({author:c.author,body:c.body,at:c.created_at})),runs=runsOf(conn2,id),events=eventsOf(conn2,id),attachments=attachmentsOf(conn2,s,id),latest2=latestSummary(conn2,id);return{...toTask(row3),parents,children:children2,comments,runs,events,attachments,latest_summary:latest2}}catch{return null}}var runsOf=(conn2,id)=>{try{return conn2.query(`SELECT id, profile, status, outcome, started_at, ended_at,
4131
4131
  summary, error, worker_pid
4132
4132
  FROM task_runs WHERE task_id = ? ORDER BY id`).all(id).map(toRun)}catch{return[]}},eventsOf=(conn2,id)=>{try{return conn2.query(`SELECT id, kind, payload, created_at, run_id
4133
- FROM task_events WHERE task_id = ? ORDER BY id DESC LIMIT ?`).all(id,EVENT_TAIL).map(toEvent).reverse()}catch{return[]}},latestSummary=(conn2,id)=>{try{return conn2.query(`SELECT summary FROM task_runs
4133
+ FROM task_events WHERE task_id = ? ORDER BY id DESC LIMIT ?`).all(id,EVENT_TAIL).map(toEvent).reverse()}catch{return[]}},attachmentsOf=(conn2,s,id)=>{try{return conn2.query(`SELECT id, filename, stored_path, size, created_at
4134
+ FROM task_attachments WHERE task_id = ? ORDER BY created_at ASC, id ASC`).all(id).map((r)=>toAttachment(s,r))}catch{return[]}},latestSummary=(conn2,id)=>{try{return conn2.query(`SELECT summary FROM task_runs
4134
4135
  WHERE task_id = ? AND summary IS NOT NULL AND summary != ''
4135
4136
  ORDER BY id DESC LIMIT 1`).get(id)?.summary??null}catch{return null}};function tailLogOf(s,id,bytes=16384){let path7=`${logsDir(s)}/${id}.log`;if(!existsSync15(path7))return null;try{let size=statSync4(path7).size,want=Math.min(size,bytes),fd=openSync2(path7,"r"),buf=Buffer.alloc(want);readSync2(fd,buf,0,want,size-want),closeSync2(fd);let out=buf.toString("utf-8");if(size>bytes){let nl=out.indexOf(`
4136
4137
  `);if(nl>=0&&nl<out.length-1)out=out.slice(nl+1)}return out}catch{return null}}function assignees(s=slug){let seen=new Set,dir=kp("profiles");if(existsSync15(dir)){for(let e of readdirSync5(dir,{withFileTypes:!0}))if(e.isDirectory())seen.add(e.name)}let conn2=dbOf(s);if(conn2)try{for(let r of conn2.query("SELECT DISTINCT assignee FROM tasks WHERE assignee IS NOT NULL AND status != 'archived'").all())seen.add(r.assignee)}catch{}return[...seen].sort()}function checkFileLength(conn2){try{let row3=conn2.query("PRAGMA database_list").get(),path7=String(row3?.file??row3?.[2]??"");if(!path7)return;let pageRow=conn2.query("PRAGMA page_size").get(),pageSize=Number(Object.values(pageRow??{})[0]);if(!pageSize)return;let fd=openSync2(path7,"r");try{let buf=Buffer.alloc(4);if(readSync2(fd,buf,0,4,28)<4)return;let headerPages=buf.readUInt32BE(0);if(!headerPages)return;let actualPages=Math.floor(fstatSync(fd).size/pageSize);if(actualPages<headerPages)throw Error(`torn-extend detected: page count mismatch on ${path7}: header claims ${headerPages} pages, file has ${actualPages} pages`)}finally{closeSync2(fd)}}catch(err){if(err instanceof Error&&err.message.startsWith("torn-extend detected"))throw err}}function writeTxn(conn2,fn){conn2.exec("BEGIN IMMEDIATE");try{let out=fn();return conn2.exec("COMMIT"),checkFileLength(conn2),out}catch(err){try{conn2.exec("ROLLBACK")}catch{}throw err}}var now=()=>Math.floor(Date.now()/1000);function patchTask(s,id,patch){let conn2=rwOf(s);if(!conn2)return!1;if(!conn2.query("SELECT 1 FROM tasks WHERE id = ?").get(id))return!1;if(patch.priority!==void 0){let p=Math.max(0,Math.min(9,Math.floor(patch.priority)));writeTxn(conn2,()=>{conn2.query("UPDATE tasks SET priority = ? WHERE id = ?").run(p,id),conn2.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'reprioritized', ?, ?)").run(id,JSON.stringify({priority:p}),now())})}if(patch.title!==void 0||patch.body!==void 0){let sets=[],vals=[];if(patch.title!==void 0){let t2=patch.title.trim();if(!t2)throw Error("title cannot be empty");sets.push("title = ?"),vals.push(t2)}if(patch.body!==void 0)sets.push("body = ?"),vals.push(patch.body);vals.push(id),writeTxn(conn2,()=>{conn2.query(`UPDATE tasks SET ${sets.join(", ")} WHERE id = ?`).run(...vals),conn2.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'edited', NULL, ?)").run(id,now())})}return!0}var q3=(s)=>/^[A-Za-z0-9._\/:+=-]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`;var import_react78=__toESM(require_react_production(),1);function openCreateTask(dialog,opts){return new Promise((resolve4)=>{let done=(r)=>{dialog.clear(),resolve4(r)};dialog.replace($jsx(Form2,{pool:opts.assignees,parent:opts.parent,done}),void 0,{ownCancel:!0})})}var CORE=["title","body","assignee","priority","triage","more"],MORE=["tenant","workspace","maxRuntime","skills"],SELECTY=new Set(["assignee","priority","workspace"]),MAX_RUNTIME_RE=/^\d+[smhd]?$/,SKILL_MATCHES_MAX=6,wsLabel=(w2)=>w2.kind==="scratch"?"scratch":w2.kind==="worktree"?"worktree":`dir @ ${w2.path}`,Form2=(p)=>{let theme=useTheme().theme,gw=useGateway(),body=import_react78.useRef(null),[bodyText,setBodyText]=import_react78.useState(""),[field,setField]=import_react78.useState("title"),[more,setMore]=import_react78.useState(!1),[picker,setPicker]=import_react78.useState(null),[title,setTitle]=import_react78.useState(""),[assignee,setAssignee]=import_react78.useState(null),[priority,setPriority]=import_react78.useState(0),[triage,setTriage]=import_react78.useState(!1),[tenant,setTenant]=import_react78.useState(""),[workspace,setWorkspace]=import_react78.useState({kind:"scratch"}),[maxRuntime,setMaxRuntime]=import_react78.useState(""),[catalog2,setCatalog]=import_react78.useState([]),[skills,setSkills]=import_react78.useState([]),[filter,setFilter]=import_react78.useState(""),[matchIdx,setMatchIdx]=import_react78.useState(0);import_react78.useEffect(()=>{let live=!0;return gw.request("skills.manage",{action:"list"}).then((r)=>{if(!live)return;let raw=r.skills??{},out=[];for(let cat of Object.keys(raw))for(let name of raw[cat]??[])out.push({cat,name});out.sort((a,b2)=>a.name.localeCompare(b2.name)),setCatalog(out)}).catch(()=>{}),()=>{live=!1}},[gw]);let matches=import_react78.useMemo(()=>{if(!filter.trim())return[];let q4=filter.trim().toLowerCase(),picked=new Set(skills),hits=[];for(let s of catalog2){if(picked.has(s.name))continue;if(s.name.toLowerCase().includes(q4)||s.cat.toLowerCase().includes(q4))hits.push(s);if(hits.length>=SKILL_MATCHES_MAX)break}return hits},[catalog2,filter,skills]);import_react78.useEffect(()=>{if(matchIdx>0&&matchIdx>=matches.length)setMatchIdx(Math.max(0,matches.length-1))},[matches.length,matchIdx]);let order=()=>more?[...CORE,...MORE]:CORE,titleOk=title.trim().length>0,runtimeOk=maxRuntime.trim()===""||MAX_RUNTIME_RE.test(maxRuntime.trim()),valid=titleOk&&runtimeOk,submit2=()=>{if(!valid)return;p.done({title:title.trim(),body:(body.current?.plainText??bodyText).trim(),assignee,priority,parent:p.parent?.id??null,triage,tenant:tenant.trim()||null,workspace,maxRuntime:maxRuntime.trim()||null,skills})},moveField=(dir)=>{let o=order(),i=o.indexOf(field),next2=o[(i+dir+o.length)%o.length];setField(next2)},openPicker=()=>{if(field==="assignee")return setPicker({kind:"assignee"});if(field==="priority")return setPicker({kind:"priority"});if(field==="workspace")return setPicker({kind:"workspace"})},commitMatch=()=>{let hit=matches[matchIdx];if(!hit)return!1;return setSkills((s)=>s.includes(hit.name)?s:[...s,hit.name]),setFilter(""),setMatchIdx(0),!0},popSkill=()=>setSkills((s)=>s.slice(0,-1));if(useKeyboard((key3)=>{if(picker){if(key3.name==="escape")setPicker(picker.kind==="dirPath"?{kind:"workspace"}:null);return}if(key3.name==="escape")return p.done(null);if(key3.name==="return"){if(key3.ctrl)return submit2();if(field!=="body")return submit2();return}if(field==="skills"){if(key3.name==="tab"){if(!key3.shift&&commitMatch())return;return moveField(key3.shift?-1:1)}if(key3.name==="backspace"){if(filter.length>0)return setFilter((f)=>f.slice(0,-1));return popSkill()}if(key3.name==="up"){if(matches.length>0)return setMatchIdx((i)=>Math.max(0,i-1));return moveField(-1)}if(key3.name==="down"){if(matches.length>0)return setMatchIdx((i)=>Math.min(matches.length-1,i+1));return moveField(1)}if(key3.raw&&key3.raw.length===1&&/[A-Za-z0-9_\-/ ]/.test(key3.raw))setFilter((f)=>f+key3.raw),setMatchIdx(0);return}if(key3.name==="tab")return moveField(key3.shift?-1:1);if(key3.name==="up"){if(field==="body"){if((body.current?.logicalCursor.row??0)>0)return}return moveField(-1)}if(key3.name==="down"){if(field==="body"){let row3=body.current?.logicalCursor.row??0,last3=(body.current?.lineCount??1)-1;if(row3<last3)return}return moveField(1)}if(field==="more"){if(key3.name==="return"||key3.name==="space")return setMore((m2)=>!m2);return}if(field==="triage"&&key3.name==="space")return setTriage((t2)=>!t2);if(SELECTY.has(field)&&key3.name==="space")return openPicker()}),picker?.kind==="assignee"){let opts=[{title:"(unassigned)",value:""},...p.pool.map((n)=>({title:n,value:n}))];return $jsx(DialogSelect,{title:"Assignee",options:opts,placeholder:"Search profiles\u2026",current:assignee??"",onSelect:(o)=>{setAssignee(o.value||null),setPicker(null)}})}if(picker?.kind==="priority"){let opts=Array.from({length:10},(_2,n)=>({title:n===0?"P0 (none)":`P${n}`,value:String(n),description:n===0?"default":n<=2?"normal":n<=5?"elevated":"high"}));return $jsx(DialogSelect,{title:"Priority",options:opts,filterable:!1,current:String(priority),onSelect:(o)=>{setPriority(Number(o.value)),setPicker(null)}})}if(picker?.kind==="workspace")return $jsx(DialogSelect,{title:"Workspace",options:[{title:"scratch",value:"scratch",description:"isolated temp dir under the board root (default)"},{title:"worktree",value:"worktree",description:"git worktree at .worktrees/<task-id> \u2014 worker runs `git worktree add`"},{title:"dir:\u2026",value:"dir",description:"an exact absolute path (prompts next)"}],filterable:!1,current:workspace.kind,onSelect:(o)=>{if(o.value==="scratch")return setWorkspace({kind:"scratch"}),setPicker(null);if(o.value==="worktree")return setWorkspace({kind:"worktree"}),setPicker(null);return setPicker({kind:"dirPath",value:workspace.kind==="dir"?workspace.path:""})}});if(picker?.kind==="dirPath"){let val=picker.value,ok=val.trim().length>0&&val.trim().startsWith("/");return $jsxs("box",{flexDirection:"column",width:64,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Directory path"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"absolute path (required)"})}),$jsxs("box",{height:1,flexDirection:"row",overflow:"hidden",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.accent,children:"\u2503 "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value:val,onInput:(v2)=>setPicker({kind:"dirPath",value:v2}),onSubmit:()=>{if(!ok)return;setWorkspace({kind:"dir",path:val.trim()}),setPicker(null)},focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement},"dirpath")})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:ok?"Enter confirm \xB7 Esc back":"absolute path required \xB7 Esc back"})})]})}let lbl=(f,text3)=>$jsx("box",{width:13,flexShrink:0,children:$jsxs("text",{fg:field===f?theme.accent:theme.textMuted,children:[field===f?"\u25B8 ":" ",text3]})}),textRow=(f,label2,value,set2,placeholder)=>$jsxs("box",{height:1,flexDirection:"row",children:[lbl(f,label2),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value,onInput:set2,onSubmit:submit2,focused:field===f,placeholder,textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:field===f?theme.backgroundElement:void 0,focusedBackgroundColor:theme.backgroundElement},`field-${f}`)})]}),valRow=(f,label2,value,hint)=>$jsxs("box",{height:1,flexDirection:"row",children:[lbl(f,label2),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.text,children:value})}),field===f?$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]}),skillsRows=()=>{let focused=field==="skills",empty=skills.length===0&&!focused;return $jsxs($Fragment,{children:[$jsxs("box",{height:1,flexDirection:"row",children:[lbl("skills","Skills"),$jsxs("box",{flexGrow:1,minWidth:0,height:1,flexDirection:"row",overflow:"hidden",children:[skills.map((n)=>$jsx(FilterChip,{label:n,state:"in",gap:0},n)),empty?$jsx("text",{fg:theme.textMuted,children:"(none \u2014 focus field to pick)"}):$jsxs("box",{flexDirection:"row",marginLeft:skills.length>0?1:0,children:[$jsx("text",{fg:theme.text,children:filter}),focused?$jsx("text",{fg:theme.accent,children:"\u2588"}):null]})]})]}),focused&&matches.length>0?$jsx("box",{flexDirection:"column",children:matches.map((s,i)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsx("text",{fg:i===matchIdx?theme.accent:theme.textMuted,children:i===matchIdx?" \u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:i===matchIdx?theme.accent:theme.text,children:s.name}),$jsx("span",{fg:theme.textMuted,children:` ${s.cat}`})]})})]},`${s.cat}/${s.name}`))}):null]})},footer=!valid?!titleOk?"type a title":"fix runtime (e.g. 30m, 2h, 1800)":field==="body"?"Ctrl+Enter create \xB7 Tab leave \xB7 \u2191\u2193 cursor \xB7 Esc cancel":field==="more"?`Space ${more?"collapse":"expand"} \xB7 Ctrl+Enter create \xB7 \u2191\u2193/Tab \xB7 Esc`:field==="skills"?(()=>{if(matches.length>0)return"Tab add \xB7 \u2191\u2193 pick \xB7 Bksp remove \xB7 Enter create \xB7 Esc";if(skills.length>0)return"type to filter \xB7 Bksp remove last \xB7 Enter create \xB7 \u2191\u2193/Tab \xB7 Esc";return"type to filter \xB7 Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc cancel"})():SELECTY.has(field)?"Space pick \xB7 Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc cancel":field==="triage"?"Space toggle \xB7 Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc":"Enter create \xB7 \u2191\u2193/Tab field \xB7 Esc cancel";return $jsxs("box",{flexDirection:"column",width:66,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:p.parent?`New Task \xB7 child of ${p.parent.id}`:"New Task"})})}),p.parent?$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:[" ",p.parent.title]})}):null,$jsx("box",{height:1}),textRow("title","Title",title,setTitle,"one-line summary"),$jsxs("box",{flexDirection:"row",children:[lbl("body","Body"),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("textarea",{ref:body,initialValue:bodyText,onContentChange:()=>{if(body.current)setBodyText(body.current.plainText)},focused:field==="body",placeholder:"longer spec \u2014 markdown ok (Enter for newline)",textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:field==="body"?theme.backgroundElement:void 0,focusedBackgroundColor:theme.backgroundElement,minHeight:5,maxHeight:5},"field-body")})]}),valRow("assignee","Assignee",assignee??"(unassigned)","Space pick \u25BE"),valRow("priority","Priority",priority?`P${priority}`:"P0 (none)","Space pick \u25BE"),valRow("triage","Triage",triage?"yes \u2014 park for a specifier":"no","Space toggle"),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsxs("text",{fg:field==="more"?theme.accent:theme.textMuted,children:[field==="more"?"\u25B8 ":" ",more?"More \u25BE":"More \u25B8"]})}),!more?$jsx("box",{flexGrow:1,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:"tenant \xB7 workspace \xB7 runtime \xB7 skills"})}):null]}),more?textRow("tenant","Tenant",tenant,setTenant,"namespace (optional)"):null,more?valRow("workspace","Workspace",wsLabel(workspace),"Space pick \u25BE"):null,more?textRow("maxRuntime","Runtime",maxRuntime,setMaxRuntime,"e.g. 30m, 2h, 1800 (optional)"):null,more?skillsRows():null,$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:footer})})]})};var arr=(v2)=>Array.isArray(v2)?v2:[],str2=(v2)=>typeof v2==="string"?v2:"",num3=(v2)=>typeof v2==="number"&&Number.isFinite(v2)?v2:0,ids=(v2)=>arr(v2).map(str2).filter(Boolean),spawned=(v2)=>arr(v2).flatMap((x2)=>{if(!x2||typeof x2!=="object")return[];let r=x2,task_id=str2(r.task_id);if(!task_id)return[];return[{task_id,assignee:str2(r.assignee),workspace:str2(r.workspace)}]}),capped=(v2)=>arr(v2).flatMap((x2)=>{if(!x2||typeof x2!=="object")return[];let r=x2,task_id=str2(r.task_id);if(!task_id)return[];return[{task_id,assignee:str2(r.assignee),current:num3(r.current)}]}),guarded=(v2)=>arr(v2).flatMap((x2)=>{if(Array.isArray(x2)){let task_id2=str2(x2[0]);if(!task_id2)return[];return[{task_id:task_id2,reason:str2(x2[1])}]}if(!x2||typeof x2!=="object")return[];let r=x2,task_id=str2(r.task_id);if(!task_id)return[];return[{task_id,reason:str2(r.reason)}]}),parseDispatchResult=(out)=>{let raw=JSON.parse(out);return{reclaimed:num3(raw.reclaimed),promoted:num3(raw.promoted),spawned:spawned(raw.spawned),skipped_unassigned:ids(raw.skipped_unassigned),skipped_nonspawnable:ids(raw.skipped_nonspawnable),skipped_per_profile_capped:capped(raw.skipped_per_profile_capped),auto_assigned_default:ids(raw.auto_assigned_default),crashed:ids(raw.crashed),auto_blocked:ids(raw.auto_blocked),timed_out:ids(raw.timed_out),stale:ids(raw.stale),respawn_guarded:guarded(raw.respawn_guarded)}},dispatchFailures=(r)=>[...r.crashed,...r.auto_blocked,...r.timed_out,...r.stale],dispatchGuarded=(r)=>r.respawn_guarded.map((x2)=>x2.task_id),dispatchVariant=(r)=>{let failed=dispatchFailures(r).length,guarded2=dispatchGuarded(r).length,unassigned=r.skipped_unassigned.length,benign=r.skipped_per_profile_capped.length+r.skipped_nonspawnable.length;if(r.spawned.length===0&&(failed>0||unassigned>0))return"error";if(failed>0||guarded2>0||unassigned>0)return"warning";if(benign>0)return"info";return"success"},line2=(label2,xs)=>xs.length?[`${label2}: ${xs.join(", ")}`]:[],caps=(r)=>{let map=r.skipped_per_profile_capped.reduce((m2,x2)=>{let key3=x2.assignee||"unassigned";return m2.set(key3,[...m2.get(key3)??[],x2]),m2},new Map);if(map.size===0)return[];return["Deferred at per-profile cap:",...[...map.entries()].map(([k2,xs])=>` ${k2} (${Math.max(...xs.map((x2)=>x2.current))} running): ${xs.map((x2)=>x2.task_id).join(", ")}`)]},dispatchDetails=(r)=>[...line2("Defaulted to kanban.default_assignee",r.auto_assigned_default),...caps(r),...line2("Unassigned",r.skipped_unassigned),...line2("Non-spawnable lanes",r.skipped_nonspawnable),...line2("Failed/reclaimed \xB7 crashed",r.crashed),...line2("Failed/reclaimed \xB7 auto-blocked",r.auto_blocked),...line2("Failed/reclaimed \xB7 timed out",r.timed_out),...line2("Failed/reclaimed \xB7 stale",r.stale),...line2("Respawn guarded",r.respawn_guarded.map((x2)=>`${x2.task_id}${x2.reason?` (${x2.reason})`:""}`))].join(`
4137
- `);var NOBAR={visible:!1},RULE=["bottom"],HEAD={triage:"triage",todo:"todo",scheduled:"scheduled",ready:"ready",running:"running",blocked:"blocked",done:"done"},EMPTY2={who:new Map,pri:new Map,status:new Map},EMPTY_DIAG=new Map,EMPTY_DIAGS=[],chipId=(c)=>c.kind==="who"?`who:${c.v}`:c.kind==="pri"?`pri:${c.v}`:`st:${c.v}`,chipLabel=(c)=>c.kind==="who"?c.v:c.kind==="pri"?`P${c.v}`:HEAD[c.v],triOf=(c,m2)=>c.kind==="who"?m2.who.get(c.v)??"off":c.kind==="pri"?m2.pri.get(c.v)??"off":m2.status.get(c.v)??"off",recOf=(v2)=>v2&&typeof v2==="object"&&!Array.isArray(v2)?v2:null,assignedByDefault=(d2)=>d2.events.some((e)=>e.kind==="assigned"&&recOf(e.payload)?.source==="kanban.default_assignee");function admits(g,v2){let t2=g.get(v2);if(t2==="ex")return!1;if(t2==="in")return!0;for(let s of g.values())if(s==="in")return!1;return!0}var pass=(t2,m2)=>admits(m2.who,t2.assignee??null)&&admits(m2.pri,t2.priority),indexDiags=(rows3)=>{let out=new Map;for(let r of rows3)if(r.diagnostics.length>0)out.set(r.task_id,sortDiags(r.diagnostics));return out},maskFromPrefs=(raw)=>{let out=new Map;if(!raw)return out;for(let slug2 of Object.keys(raw)){let g=raw[slug2];out.set(slug2,{who:new Map(g.who??[]),pri:new Map(g.pri??[]),status:new Map(g.status??[])})}return out},maskToPrefs=(masks)=>{let out={};for(let[slug2,m2]of masks){let filt=(xs)=>xs.filter(([,t2])=>t2==="in"||t2==="ex"),who=filt([...m2.who]),pri=filt([...m2.pri]),status=filt([...m2.status]);if(who.length||pri.length||status.length)out[slug2]={who,pri,status}}return out},persist=(masks,open2)=>{let cur=load2().kanban??{};set("kanban",{...cur,open:[...open2],masks:maskToPrefs(masks)})},SEV_GLYPH={warning:"\u26A0",error:"!!",critical:"\u203C"},sevColor=(sev,theme)=>sev==="warning"?theme.warning:theme.error,Card=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsx("box",{id:p.id,height:2,flexDirection:"row",paddingLeft:1,border:RULE,borderStyle:"single",borderColor:theme.borderSubtle,backgroundColor:p.on?theme.backgroundElement:void 0,onMouseDown:p.onPick,onMouseMove:p.onHover,children:$jsxs(Ticker,{active:p.on||p.hov,fg:p.on?theme.accent:theme.text,children:[p.sev?$jsxs($Fragment,{children:[$jsx("span",{fg:sevColor(p.sev,theme),children:SEV_GLYPH[p.sev]})," "]}):null,p.t.title]})})}),Column=import_react80.memo((p)=>{let theme=useTheme().theme,box=import_react80.useRef(null),[hov,setHov]=import_react80.useState(-1),id=(i)=>`kb-${p.slug}-${p.status}-${i}`;import_react80.useEffect(()=>{if(p.on&&p.tasks.length>0)box.current?.scrollChildIntoView(id(p.sel))},[p.on,p.sel,p.tasks.length]);let tint=p.status==="blocked"?theme.warning:p.status==="running"?theme.success:p.status==="scheduled"?theme.textMuted:p.status==="done"?theme.textMuted:theme.primary;return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:18,border:!0,borderColor:p.on?theme.primary:theme.border,onMouseOut:()=>setHov(-1),children:[$jsx("box",{height:1,paddingLeft:1,children:$jsxs("text",{children:[$jsx("span",{fg:tint,children:$jsx("strong",{children:HEAD[p.status]})}),$jsx("span",{fg:theme.textMuted,children:` ${p.tasks.length}`})]})}),$jsx("scrollbox",{id:`kb-col-${p.slug}-${p.status}`,ref:box,scrollY:!0,flexGrow:1,verticalScrollbarOptions:NOBAR,onMouseScroll:(e)=>e.stopPropagation(),children:$jsx("box",{flexDirection:"column",width:"100%",children:p.tasks.map((t2,i)=>$jsx(Card,{id:id(i),t:t2,on:p.on&&i===p.sel,hov:i===hov,sev:maxSeverity(p.diags.get(t2.id)??[]),onHover:()=>{if(hov!==i)setHov(i)},onPick:()=>p.onPick(i)},t2.id))})})]})}),ErrorBanner=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsxs("box",{flexDirection:"column",marginLeft:2,marginBottom:1,paddingLeft:1,border:!0,borderColor:theme.error,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.error,children:$jsxs("strong",{children:["Kanban DB ",p.error.kind]})}),$jsx("span",{fg:theme.textMuted,children:` ${p.error.path}`})]})}),$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:p.error.message}),p.backups.length>0?$jsx("text",{wrapMode:"word",fg:theme.warning,children:`quarantine backup${p.backups.length===1?"":"s"}: ${p.backups.join(", ")}`}):null]})}),FilterBar=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsx("box",{height:1,flexDirection:"row",flexWrap:"no-wrap",overflow:"hidden",marginBottom:1,children:p.chips.flatMap((c,i)=>{let chip2=$jsx(FilterChip,{label:chipLabel(c),state:triOf(c,p.mask),selected:p.on&&i===p.sel,onMouseDown:()=>p.onPick(i)},chipId(c));if(i===0||p.chips[i-1].kind===c.kind)return[chip2];return[$jsx("box",{height:1,flexShrink:0,marginLeft:1,children:$jsx("text",{fg:theme.borderSubtle,children:"|"})},`sep:${chipId(c)}`),chip2]})})}),FIELDS=["title","body","assignee","priority","status","parents","result","comment"],fieldsFor=(t2)=>FIELDS.filter((f)=>{if(f==="result")return t2.status==="done";return!0}),SidePane=import_react80.memo((p)=>{let{theme,syntaxStyle}=useTheme();if(p.pane.kind==="log"||p.pane.kind==="dispatch")return $jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:theme.border,backgroundColor:theme.backgroundPanel,width:"50%",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:p.pane.kind==="log"?p.pane.id:"Dispatch"})}),$jsx("span",{fg:theme.textMuted,children:` \xB7 ${p.pane.slug} \xB7 ${p.pane.kind==="log"?"worker log (tail)":"details"}`})]})}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:p.pane.text||"(empty)"})})]});let d2=p.pane.d,fields=fieldsFor(d2),cur=p.on?fields[Math.min(p.sel,fields.length-1)]:null,srow=(f,label2,value,hint)=>{let active=cur===f;return $jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,backgroundColor:active?theme.backgroundElement:void 0,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:active?theme.accent:theme.textMuted,children:label2})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:active?theme.text:theme.textMuted,children:value})}),hint?$jsx("box",{flexShrink:0,paddingLeft:1,children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]},f)},mrow=(f,label2,content,hint)=>{let active=cur===f;return $jsxs("box",{flexDirection:"column",paddingLeft:1,backgroundColor:active?theme.backgroundElement:void 0,children:[$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:active?theme.accent:theme.textMuted,children:label2})}),hint?$jsx("box",{flexGrow:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]}),$jsx("box",{paddingLeft:10,flexShrink:0,children:content})]},f)},resultText=d2.result||d2.latest_summary||"";return $jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:theme.border,backgroundColor:theme.backgroundPanel,width:"50%",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:d2.id})}),$jsx("span",{fg:theme.textMuted,children:` \xB7 ${p.pane.slug} \xB7 ${d2.status} \xB7 ${ago(d2.updated_at)}`})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[srow("title","Title",d2.title,p.on&&cur==="title"?"Enter edit":void 0),mrow("body","Body",d2.body?cur==="body"?$jsx("text",{wrapMode:"word",fg:theme.text,children:d2.body}):$jsx("markdown",{content:d2.body,fg:theme.markdownText,syntaxStyle}):$jsx("text",{fg:theme.textMuted,children:"\u2014"}),p.on&&cur==="body"?"Enter edit (raw)":void 0),srow("assignee","Assignee",d2.assignee?assignedByDefault(d2)?`${d2.assignee} (default)`:d2.assignee:"\u2014",p.on&&cur==="assignee"?"Enter pick":void 0),srow("priority","Priority",d2.priority?`P${d2.priority}`:"\u2014",p.on&&cur==="priority"?"Enter select":void 0),srow("status","Status",d2.status,p.on&&cur==="status"?"Enter change":void 0),srow("parents","Parents",d2.parents.length?d2.parents.join(", "):"\u2014",p.on&&cur==="parents"?"Enter add/remove":void 0),d2.children.length?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Children"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.children.join(", ")})})]}):null,d2.workspace_kind?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Workspace"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsxs("text",{fg:theme.textMuted,children:[d2.workspace_kind,d2.workspace_path?` @ ${d2.workspace_path}`:""]})})]}):null,d2.branch_name?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Branch"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.branch_name})})]}):null,d2.skills.length?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Skills"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.skills.join(", ")})})]}):null,d2.model_override?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Model"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.model_override})})]}):null,d2.max_retries!==null?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Retries"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:String(d2.max_retries)})})]}):null,d2.pid?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"PID"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:String(d2.pid)})})]}):null,d2.last_heartbeat_at&&d2.status==="running"?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Heartbeat"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:ago(d2.last_heartbeat_at)})})]}):null,d2.session_id?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Session"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.session_id})})]}):null,d2.error?$jsxs("box",{flexDirection:"column",paddingLeft:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:"Error"})}),$jsx("box",{paddingLeft:2,children:$jsx("text",{fg:theme.error,wrapMode:"word",children:d2.error})})]}):null,d2.status==="done"?mrow("result","Result",resultText?cur==="result"?$jsx("text",{wrapMode:"word",fg:theme.text,children:resultText}):$jsx("markdown",{content:resultText,fg:theme.markdownText,syntaxStyle}):$jsx("text",{fg:theme.textMuted,children:"\u2014"}),p.on&&cur==="result"?"Enter edit":void 0):null,p.diags.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"Diagnostics "}),$jsx("span",{fg:sevColor(p.diags[0].severity,theme),children:`(${p.diags.length})`})]})}),p.diags.map((dx,i)=>$jsxs("box",{flexDirection:"column",marginTop:i===0?0:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:sevColor(dx.severity,theme),children:SEV_GLYPH[dx.severity]}),$jsx("span",{fg:theme.text,children:` [${dx.severity}] ${dx.kind}`}),dx.count>1?$jsx("span",{fg:theme.textMuted,children:` \xD7${dx.count}`}):null]})}),$jsxs("box",{paddingLeft:2,flexDirection:"column",children:[$jsx("text",{wrapMode:"word",fg:theme.text,children:dx.title}),dx.detail?$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:dx.detail}):null,dx.actions.map((a,j2)=>$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:a.suggested?theme.accent:theme.textMuted,children:a.suggested?"\u2192 ":"\xB7 "}),$jsx("span",{fg:a.suggested?theme.text:theme.textMuted,children:a.label})]})},j2))]})]},`${dx.kind}-${i}`))]}):null,d2.runs.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Runs (${d2.runs.length})`})}),d2.runs.map((r)=>{let outcome=r.outcome||r.status||(r.ended_at?"ended":"active"),elapsed=r.ended_at?`${Math.max(0,r.ended_at-r.started_at)}s`:"active";return $jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:`#${r.id} `}),$jsx("span",{fg:theme.text,children:outcome}),$jsx("span",{fg:theme.textMuted,children:` @${r.profile??"-"} ${elapsed} ${ago(r.started_at)}`})]})}),r.summary?$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:` \u2192 ${r.summary.split(`
4138
+ `);var NOBAR={visible:!1},RULE=["bottom"],HEAD={triage:"triage",todo:"todo",scheduled:"scheduled",ready:"ready",running:"running",blocked:"blocked",done:"done"},EMPTY2={who:new Map,pri:new Map,status:new Map},EMPTY_DIAG=new Map,EMPTY_DIAGS=[],chipId=(c)=>c.kind==="who"?`who:${c.v}`:c.kind==="pri"?`pri:${c.v}`:`st:${c.v}`,chipLabel=(c)=>c.kind==="who"?c.v:c.kind==="pri"?`P${c.v}`:HEAD[c.v],triOf=(c,m2)=>c.kind==="who"?m2.who.get(c.v)??"off":c.kind==="pri"?m2.pri.get(c.v)??"off":m2.status.get(c.v)??"off",recOf=(v2)=>v2&&typeof v2==="object"&&!Array.isArray(v2)?v2:null,assignedByDefault=(d2)=>d2.events.some((e)=>e.kind==="assigned"&&recOf(e.payload)?.source==="kanban.default_assignee");function admits(g,v2){let t2=g.get(v2);if(t2==="ex")return!1;if(t2==="in")return!0;for(let s of g.values())if(s==="in")return!1;return!0}var pass=(t2,m2)=>admits(m2.who,t2.assignee??null)&&admits(m2.pri,t2.priority),indexDiags=(rows3)=>{let out=new Map;for(let r of rows3)if(r.diagnostics.length>0)out.set(r.task_id,sortDiags(r.diagnostics));return out},maskFromPrefs=(raw)=>{let out=new Map;if(!raw)return out;for(let slug2 of Object.keys(raw)){let g=raw[slug2];out.set(slug2,{who:new Map(g.who??[]),pri:new Map(g.pri??[]),status:new Map(g.status??[])})}return out},maskToPrefs=(masks)=>{let out={};for(let[slug2,m2]of masks){let filt=(xs)=>xs.filter(([,t2])=>t2==="in"||t2==="ex"),who=filt([...m2.who]),pri=filt([...m2.pri]),status=filt([...m2.status]);if(who.length||pri.length||status.length)out[slug2]={who,pri,status}}return out},persist=(masks,open2)=>{let cur=load2().kanban??{};set("kanban",{...cur,open:[...open2],masks:maskToPrefs(masks)})},SEV_GLYPH={warning:"\u26A0",error:"!!",critical:"\u203C"},sevColor=(sev,theme)=>sev==="warning"?theme.warning:theme.error,Card=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsx("box",{id:p.id,height:2,flexDirection:"row",paddingLeft:1,border:RULE,borderStyle:"single",borderColor:theme.borderSubtle,backgroundColor:p.on?theme.backgroundElement:void 0,onMouseDown:p.onPick,onMouseMove:p.onHover,children:$jsxs(Ticker,{active:p.on||p.hov,fg:p.on?theme.accent:theme.text,children:[p.sev?$jsxs($Fragment,{children:[$jsx("span",{fg:sevColor(p.sev,theme),children:SEV_GLYPH[p.sev]})," "]}):null,p.t.title]})})}),Column=import_react80.memo((p)=>{let theme=useTheme().theme,box=import_react80.useRef(null),[hov,setHov]=import_react80.useState(-1),id=(i)=>`kb-${p.slug}-${p.status}-${i}`;import_react80.useEffect(()=>{if(p.on&&p.tasks.length>0)box.current?.scrollChildIntoView(id(p.sel))},[p.on,p.sel,p.tasks.length]);let tint=p.status==="blocked"?theme.warning:p.status==="running"?theme.success:p.status==="scheduled"?theme.textMuted:p.status==="done"?theme.textMuted:theme.primary;return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:18,border:!0,borderColor:p.on?theme.primary:theme.border,onMouseOut:()=>setHov(-1),children:[$jsx("box",{height:1,paddingLeft:1,children:$jsxs("text",{children:[$jsx("span",{fg:tint,children:$jsx("strong",{children:HEAD[p.status]})}),$jsx("span",{fg:theme.textMuted,children:` ${p.tasks.length}`})]})}),$jsx("scrollbox",{id:`kb-col-${p.slug}-${p.status}`,ref:box,scrollY:!0,flexGrow:1,verticalScrollbarOptions:NOBAR,onMouseScroll:(e)=>e.stopPropagation(),children:$jsx("box",{flexDirection:"column",width:"100%",children:p.tasks.map((t2,i)=>$jsx(Card,{id:id(i),t:t2,on:p.on&&i===p.sel,hov:i===hov,sev:maxSeverity(p.diags.get(t2.id)??[]),onHover:()=>{if(hov!==i)setHov(i)},onPick:()=>p.onPick(i)},t2.id))})})]})}),ErrorBanner=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsxs("box",{flexDirection:"column",marginLeft:2,marginBottom:1,paddingLeft:1,border:!0,borderColor:theme.error,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.error,children:$jsxs("strong",{children:["Kanban DB ",p.error.kind]})}),$jsx("span",{fg:theme.textMuted,children:` ${p.error.path}`})]})}),$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:p.error.message}),p.backups.length>0?$jsx("text",{wrapMode:"word",fg:theme.warning,children:`quarantine backup${p.backups.length===1?"":"s"}: ${p.backups.join(", ")}`}):null]})}),FilterBar=import_react80.memo((p)=>{let theme=useTheme().theme;return $jsx("box",{height:1,flexDirection:"row",flexWrap:"no-wrap",overflow:"hidden",marginBottom:1,children:p.chips.flatMap((c,i)=>{let chip2=$jsx(FilterChip,{label:chipLabel(c),state:triOf(c,p.mask),selected:p.on&&i===p.sel,onMouseDown:()=>p.onPick(i)},chipId(c));if(i===0||p.chips[i-1].kind===c.kind)return[chip2];return[$jsx("box",{height:1,flexShrink:0,marginLeft:1,children:$jsx("text",{fg:theme.borderSubtle,children:"|"})},`sep:${chipId(c)}`),chip2]})})}),FIELDS=["title","body","assignee","priority","status","parents","result","comment"],fieldsFor=(t2)=>FIELDS.filter((f)=>{if(f==="result")return t2.status==="done";return!0}),SidePane=import_react80.memo((p)=>{let{theme,syntaxStyle}=useTheme();if(p.pane.kind==="log"||p.pane.kind==="dispatch")return $jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:theme.border,backgroundColor:theme.backgroundPanel,width:"50%",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:p.pane.kind==="log"?p.pane.id:"Dispatch"})}),$jsx("span",{fg:theme.textMuted,children:` \xB7 ${p.pane.slug} \xB7 ${p.pane.kind==="log"?"worker log (tail)":"details"}`})]})}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:p.pane.text||"(empty)"})})]});let d2=p.pane.d,fields=fieldsFor(d2),cur=p.on?fields[Math.min(p.sel,fields.length-1)]:null,srow=(f,label2,value,hint)=>{let active=cur===f;return $jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,backgroundColor:active?theme.backgroundElement:void 0,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:active?theme.accent:theme.textMuted,children:label2})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:active?theme.text:theme.textMuted,children:value})}),hint?$jsx("box",{flexShrink:0,paddingLeft:1,children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]},f)},mrow=(f,label2,content,hint)=>{let active=cur===f;return $jsxs("box",{flexDirection:"column",paddingLeft:1,backgroundColor:active?theme.backgroundElement:void 0,children:[$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:active?theme.accent:theme.textMuted,children:label2})}),hint?$jsx("box",{flexGrow:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:hint})}):null]}),$jsx("box",{paddingLeft:10,flexShrink:0,children:content})]},f)},resultText=d2.result||d2.latest_summary||"",sizeText=(n)=>n===null?"size unknown":n<1024?`${n} B`:n<1048576?`${(n/1024).toFixed(0)} KB`:`${(n/1048576).toFixed(1)} MB`;return $jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:theme.border,backgroundColor:theme.backgroundPanel,width:"50%",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:d2.id})}),$jsx("span",{fg:theme.textMuted,children:` \xB7 ${p.pane.slug} \xB7 ${d2.status} \xB7 ${ago(d2.updated_at)}`})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[srow("title","Title",d2.title,p.on&&cur==="title"?"Enter edit":void 0),mrow("body","Body",d2.body?cur==="body"?$jsx("text",{wrapMode:"word",fg:theme.text,children:d2.body}):$jsx("markdown",{content:d2.body,fg:theme.markdownText,syntaxStyle}):$jsx("text",{fg:theme.textMuted,children:"\u2014"}),p.on&&cur==="body"?"Enter edit (raw)":void 0),srow("assignee","Assignee",d2.assignee?assignedByDefault(d2)?`${d2.assignee} (default)`:d2.assignee:"\u2014",p.on&&cur==="assignee"?"Enter pick":void 0),srow("priority","Priority",d2.priority?`P${d2.priority}`:"\u2014",p.on&&cur==="priority"?"Enter select":void 0),srow("status","Status",d2.status,p.on&&cur==="status"?"Enter change":void 0),srow("parents","Parents",d2.parents.length?d2.parents.join(", "):"\u2014",p.on&&cur==="parents"?"Enter add/remove":void 0),d2.children.length?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Children"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.children.join(", ")})})]}):null,d2.workspace_kind?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Workspace"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsxs("text",{fg:theme.textMuted,children:[d2.workspace_kind,d2.workspace_path?` @ ${d2.workspace_path}`:""]})})]}):null,d2.branch_name?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Branch"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.branch_name})})]}):null,d2.skills.length?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Skills"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.skills.join(", ")})})]}):null,d2.model_override?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Model"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.model_override})})]}):null,d2.max_retries!==null?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Retries"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:String(d2.max_retries)})})]}):null,d2.pid?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"PID"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:String(d2.pid)})})]}):null,d2.last_heartbeat_at&&d2.status==="running"?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Heartbeat"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:ago(d2.last_heartbeat_at)})})]}):null,d2.session_id?$jsxs("box",{height:1,flexDirection:"row",paddingLeft:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:"Session"})}),$jsx("box",{flexGrow:1,minWidth:0,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:d2.session_id})})]}):null,d2.attachments.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Attachments (${d2.attachments.length})`})}),d2.attachments.map((a)=>{let source=a.path?{file:a.path,relative:a.relative_path??a.path,label:a.name}:null;return $jsxs("box",{flexDirection:"column",paddingLeft:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:`#${a.id} `}),$jsx("span",{fg:theme.text,children:a.name}),$jsx("span",{fg:theme.textMuted,children:` ${sizeText(a.size)} ${ago(a.created_at)}`})]})}),source?$jsx("box",{height:1,overflow:"hidden",children:$jsx(FileLink,{source,children:source.relative})}):$jsx("text",{wrapMode:"word",fg:theme.error,children:`unsafe path omitted: ${a.stored_path}`})]},a.id)})]}):null,d2.error?$jsxs("box",{flexDirection:"column",paddingLeft:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:"Error"})}),$jsx("box",{paddingLeft:2,children:$jsx("text",{fg:theme.error,wrapMode:"word",children:d2.error})})]}):null,d2.status==="done"?mrow("result","Result",resultText?cur==="result"?$jsx("text",{wrapMode:"word",fg:theme.text,children:resultText}):$jsx("markdown",{content:resultText,fg:theme.markdownText,syntaxStyle}):$jsx("text",{fg:theme.textMuted,children:"\u2014"}),p.on&&cur==="result"?"Enter edit":void 0):null,p.diags.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"Diagnostics "}),$jsx("span",{fg:sevColor(p.diags[0].severity,theme),children:`(${p.diags.length})`})]})}),p.diags.map((dx,i)=>$jsxs("box",{flexDirection:"column",marginTop:i===0?0:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:sevColor(dx.severity,theme),children:SEV_GLYPH[dx.severity]}),$jsx("span",{fg:theme.text,children:` [${dx.severity}] ${dx.kind}`}),dx.count>1?$jsx("span",{fg:theme.textMuted,children:` \xD7${dx.count}`}):null]})}),$jsxs("box",{paddingLeft:2,flexDirection:"column",children:[$jsx("text",{wrapMode:"word",fg:theme.text,children:dx.title}),dx.detail?$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:dx.detail}):null,dx.actions.map((a,j2)=>$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:a.suggested?theme.accent:theme.textMuted,children:a.suggested?"\u2192 ":"\xB7 "}),$jsx("span",{fg:a.suggested?theme.text:theme.textMuted,children:a.label})]})},j2))]})]},`${dx.kind}-${i}`))]}):null,d2.runs.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Runs (${d2.runs.length})`})}),d2.runs.map((r)=>{let outcome=r.outcome||r.status||(r.ended_at?"ended":"active"),elapsed=r.ended_at?`${Math.max(0,r.ended_at-r.started_at)}s`:"active";return $jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:`#${r.id} `}),$jsx("span",{fg:theme.text,children:outcome}),$jsx("span",{fg:theme.textMuted,children:` @${r.profile??"-"} ${elapsed} ${ago(r.started_at)}`})]})}),r.summary?$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:` \u2192 ${r.summary.split(`
4138
4139
  `)[0].slice(0,200)}`}):null,r.error?$jsx("text",{wrapMode:"word",fg:theme.error,children:` \u2716 ${r.error.split(`
4139
4140
  `)[0].slice(0,200)}`}):null]},r.id)})]}):null,d2.events.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Events (${d2.events.length})`})}),d2.events.map((e)=>$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:`${ago(e.created_at).padEnd(10)} `}),$jsx("span",{fg:theme.text,children:e.kind}),e.payload?$jsx("span",{fg:theme.textMuted,children:` ${JSON.stringify(e.payload)}`}):null]})},e.id))]}):null,d2.comments.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Comments (${d2.comments.length})`})}),d2.comments.map((c,i)=>$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${c.author} \xB7 ${ago(c.at)}`})}),$jsx("text",{wrapMode:"word",children:c.body})]},i))]}):null,p.on&&cur==="comment"?$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.accent,children:"Enter add comment"})}):null]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.on?"Tab/\u2191\u2193 field Enter edit Esc grid a assign c comment l log":"Tab into pane a assign c comment u unblock d archive l log N child"})})]})}),Kanban=import_react80.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),keys=useKeys(),[boards,setBoards]=import_react80.useState(listBoards),[data2,setData]=import_react80.useState(()=>new Map(boards.map((b2)=>[b2.slug,boardStateOf(b2.slug)]))),[diags,setDiags]=import_react80.useState(()=>new Map),[masks,setMasks]=import_react80.useState(()=>maskFromPrefs(load2().kanban?.masks)),[open2,setOpen]=import_react80.useState(()=>{let saved=load2().kanban?.open;if(saved)return new Set(saved);let init=currentBoard();return new Set(listBoards().filter((b2)=>{let state2=boardStateOf(b2.slug);return b2.slug===init||[...state2.columns.values()].some((v2)=>v2.length>0)||!!state2.error}).map((b2)=>b2.slug))}),[at,setAt]=import_react80.useState(currentBoard),[tier,setTier]=import_react80.useState("grid"),[col,setCol]=import_react80.useState(0),[row3,setRow]=import_react80.useState(0),[chip2,setChip]=import_react80.useState(0),[paneSel,setPaneSel]=import_react80.useState(0),[pane,setPane]=import_react80.useState(null),outer=import_react80.useRef(null),load4=import_react80.useCallback(()=>{let bs=listBoards();setBoards(bs),setData(new Map(bs.map((b2)=>[b2.slug,boardStateOf(b2.slug)]))),setPane((p)=>p?.kind==="detail"?((d2)=>d2?{...p,d:d2}:null)(detailOf(p.slug,p.d.id)):p),Promise.all(bs.map((b2)=>gw.request("shell.exec",{command:`hermes kanban --board ${q3(b2.slug)} diagnostics --json`}).then((r)=>r.code===0?parseDiagnostics(r.stdout):[]).catch(()=>[]).then((rows3)=>[b2.slug,indexDiags(rows3)]))).then((pairs)=>setDiags(new Map(pairs)))},[gw]);import_react80.useEffect(load4,[load4]),import_react80.useEffect(()=>{persist(masks,open2)},[masks,open2]);let maskOf=(s)=>masks.get(s)??EMPTY2,wide=dims.width>=160,maxH=Math.max(8,dims.height-16),sections=import_react80.useMemo(()=>{let built=boards.map((b2)=>{let state2=data2.get(b2.slug)??boardStateOf(b2.slug),d2=state2.columns,flat=STATUSES.flatMap((s)=>d2.get(s)??[]),total=flat.length,who=[...new Set(flat.map((t2)=>t2.assignee).filter((v2)=>!!v2))].sort(),pri=[...new Set(flat.map((t2)=>t2.priority).filter((n)=>n>0))].sort((a,z2)=>z2-a),chips=[...who.map((v2)=>({kind:"who",v:v2})),...pri.map((v2)=>({kind:"pri",v:v2})),...STATUSES.map((v2)=>({kind:"status",v:v2}))],m2=maskOf(b2.slug),cols3=STATUSES.filter((s)=>admits(m2.status,s)).map((s)=>({status:s,tasks:(d2.get(s)??[]).filter((t2)=>pass(t2,m2))})).filter((c)=>wide||c.tasks.length>0),shown=cols3.reduce((a,c)=>a+c.tasks.length,0),tall=cols3.reduce((a,c)=>Math.max(a,c.tasks.length),0);return{board:b2,cols:cols3,chips,total,shown,running:d2.get("running")?.length??0,cap:Math.min(maxH,Math.max(5,3+2*tall)),error:state2.error,corruptBackups:state2.corruptBackups}});return[...built.filter((s)=>s.total>0),...built.filter((s)=>s.total===0)]},[boards,data2,masks,wide,maxH]),idx=sections.findIndex((s)=>s.board.slug===at),sec3=sections[idx]??sections[0],cols2=sec3?.cols??[],clampCol=Math.min(col,Math.max(0,cols2.length-1)),cur=cols2[clampCol],task=tier==="grid"||tier==="pane"?cur?.tasks[Math.min(row3,Math.max(0,(cur?.tasks.length??1)-1))]:void 0,grand=sections.reduce((a,s)=>a+s.total,0),running2=sections.reduce((a,s)=>a+s.running,0);import_react80.useEffect(()=>{if(pane?.kind!=="detail")return;if(tier!=="grid"&&tier!=="pane"){setPane(null);return}if(!task){setPane(null);return}if(pane.slug===at&&pane.d.id===task.id)return;let d2=detailOf(at,task.id);setPane(d2?{kind:"detail",slug:at,d:d2}:null),setPaneSel(0)},[task?.id,at,tier]),import_react80.useEffect(()=>{if(!props.focused||running2===0)return;let t2=setInterval(load4,3000);return()=>clearInterval(t2)},[props.focused,running2,load4]),import_react80.useEffect(()=>{outer.current?.scrollChildIntoView(`kb-sec-${at}`)},[at,open2]);let sh=import_react80.useCallback((argv,ok)=>gw.request("shell.exec",{command:`hermes kanban --board ${q3(at)} ${argv}`}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||`exit ${r.code}`).trim());if(ok)toast.show({variant:"success",message:ok});return resetKanban(),load4(),r.stdout}).catch((e)=>void toast.show({variant:"error",message:trunc5(e.message,120)})),[gw,toast,load4,at]),patchDirect=import_react80.useCallback((id,p,ok)=>{try{if(!patchTask(at,id,p))return void toast.show({variant:"error",message:`no such task: ${id}`});toast.show({variant:"success",message:ok}),load4()}catch(e){toast.show({variant:"error",message:trunc5(e.message,120)})}},[at,toast,load4]),enterTop=(s)=>{setAt(s.board.slug),setTier("head"),setChip(0),setRow(0)},enterBottom=(s)=>{if(setAt(s.board.slug),setChip(Math.max(0,s.chips.length-1)),open2.has(s.board.slug)&&s.shown>0){let nc=Math.min(col,Math.max(0,s.cols.length-1));setTier("grid"),setCol(nc),setRow(Math.max(0,(s.cols[nc]?.tasks.length??1)-1));return}if(open2.has(s.board.slug)){setTier("filter");return}setTier("head")},stepBoard=(d2)=>{let n=idx+d2;return n<0||n>=sections.length?null:sections[n]},goBoard=import_react80.useCallback((d2)=>{let n=(idx+d2+sections.length)%sections.length,s=sections[n];setAt(s.board.slug),setTier("head"),setCol(0),setRow(0),setChip(0),setOpen((o)=>o.has(s.board.slug)?o:new Set(o).add(s.board.slug))},[idx,sections]),flip=import_react80.useCallback((c)=>setMasks((m2)=>{let cur2=m2.get(at)??EMPTY2,who=new Map(cur2.who),pri=new Map(cur2.pri),status=new Map(cur2.status),g=c.kind==="who"?who:c.kind==="pri"?pri:status,next2=cycle(g.get(c.v)??"off");next2==="off"?g.delete(c.v):g.set(c.v,next2);let out=new Map(m2);return out.set(at,{who,pri,status}),setRow(0),out}),[at]),toggle=import_react80.useCallback((s)=>setOpen((o)=>{let n=new Set(o);return n.has(s)?n.delete(s):n.add(s),n}),[]),newBoard=import_react80.useCallback(()=>openTextPrompt(dialog,{title:"New board",label:"Slug (a-z, 0-9, -_)"}).then((v2)=>{if(!v2)return;return gw.request("shell.exec",{command:`hermes kanban boards create ${q3(v2)}`}).then((r)=>r.code===0?(toast.show({variant:"success",message:`Board '${v2}' created`}),resetKanban(),load4(),setAt(v2),setTier("head")):Promise.reject(Error((r.stderr||r.stdout).trim()))).catch((e)=>toast.show({variant:"error",message:trunc5(e.message,120)}))}),[dialog,gw,toast,load4]),live=import_react80.useRef({task,at,sec:sec3});live.current={task,at,sec:sec3};let create=import_react80.useCallback((parent2)=>openCreateTask(dialog,{assignees:assignees(live.current.at),parent:parent2?{id:parent2.id,title:parent2.title}:void 0}).then((d2)=>{if(!d2)return;let ws=d2.workspace.kind==="scratch"?"":d2.workspace.kind==="worktree"?"--workspace worktree":`--workspace ${q3(`dir:${d2.workspace.path}`)}`,flags=[d2.assignee?`--assignee ${q3(d2.assignee)}`:"",d2.body?`--body ${q3(d2.body)}`:"",d2.priority?`--priority ${d2.priority}`:"",d2.parent?`--parent ${q3(d2.parent)}`:"",d2.triage?"--triage":"",d2.tenant?`--tenant ${q3(d2.tenant)}`:"",ws,d2.maxRuntime?`--max-runtime ${q3(d2.maxRuntime)}`:"",...d2.skills.map((s)=>`--skill ${q3(s)}`)].filter(Boolean).join(" ");return sh(`create ${q3(d2.title)} ${flags}`.trim(),`Created${d2.triage?" (triage)":""}${d2.assignee?` \u2192 ${d2.assignee}`:""}`)}),[dialog,sh]),assign=import_react80.useCallback((t2)=>{let opts=[{title:"(unassigned)",value:"none"},...assignees(live.current.at).map((n)=>({title:n,value:n}))];dialog.replace($jsx(DialogSelect,{title:`Assign ${t2.id}`,options:opts,current:t2.assignee??"none",placeholder:"Search profiles\u2026",onSelect:(o)=>{dialog.clear(),sh(`assign ${q3(t2.id)} ${q3(o.value)}`,o.value==="none"?`Unassigned ${t2.id}`:`${t2.id} \u2192 ${o.value}`)}}))},[dialog,sh]),comment=import_react80.useCallback((t2)=>openTextPrompt(dialog,{title:`Comment on ${t2.id}`,label:t2.title}).then((v2)=>v2&&sh(`comment ${q3(t2.id)} ${q3(v2)} --author user`,"Comment added")),[dialog,sh]),unblock=import_react80.useCallback((t2)=>{if(t2.status!=="blocked"&&t2.status!=="scheduled")return void toast.show({variant:"info",message:`${t2.id} is ${t2.status}, not blocked/scheduled`});if(t2.status==="scheduled")return void sh(`unblock ${q3(t2.id)}`,`Released ${t2.id}`);return openTextPrompt(dialog,{title:`Unblock ${t2.id}`,label:"Answer (posted as comment, then task \u2192 ready)"}).then((v2)=>{if(v2)return sh(`comment ${q3(t2.id)} ${q3(v2)} --author user`)}).then(()=>sh(`unblock ${q3(t2.id)}`,`Unblocked ${t2.id}`))},[dialog,sh,toast]),archive=import_react80.useCallback((t2)=>openConfirm(dialog,{title:"Archive task?",danger:!0,yes:"archive",body:`${t2.id} \xB7 ${trunc5(t2.title,60)}
4140
4141
 
@@ -4157,7 +4158,7 @@ high contrast, light subject on dark, black background`,BINDS=[{name:"return",ac
4157
4158
  `).slice(-3).join(" ")||`python exited ${exit}`};let last3=out.trim().split(`
4158
4159
  `).pop();if(!last3)return{err:"no output"};let j2;try{j2=JSON.parse(last3)}catch{return{err:`unparseable: ${last3.slice(0,200)}`}}if(j2.success===!1||j2.error)return{err:String(j2.error??"provider error")};let ref=j2.image??j2.video;if(!ref)return{err:"provider returned no asset"};if(ref.startsWith("/")||ref.startsWith("file://"))return{path:ref.replace(/^file:\/\//,"")};if(/^https?:\/\//.test(ref))return fetchTo(ref,kind2==="image"?".png":".mp4").then((p)=>({path:p})).catch((e)=>({err:`download: ${e instanceof Error?e.message:e}`}));return{err:`unrecognized asset ref: ${ref.slice(0,80)}`}},impl=generate,probeImpl=probe2,current=()=>impl,setImpl=(fn)=>{impl=fn??generate},setProbe=(fn)=>{probeImpl=fn??probe2},probeCached=()=>probeImpl();var import_react102=__toESM(require_react_production(),1);var ORDER4=["name","from"],FROMS=[{id:"blank",label:"blank",hint:"author in Studio"},{id:"file",label:"local file",hint:"png / jpg / webp / gif / mp4"},{id:"install",label:"inspect/install",hint:"catalog name \xB7 github.com/u/r/name \xB7 local dir"}],INSTALL_HINT="catalog name \xB7 github.com/u/r/eikon-name \xB7 git URL \xB7 http://\u2026/ \xB7 local dir";function openNewEikon(dialog,opts={}){return new Promise((resolve4)=>{let chained=!1;dialog.replace($jsx(Form4,{initial:opts.initial,dialog,onChain:()=>{chained=!0},done:(r)=>{chained=!0,dialog.clear(),resolve4(r)}}),()=>{if(!chained)resolve4(null)})})}var Form4=(props)=>{let theme=useTheme().theme,[name,setName]=import_react102.useState(props.initial??""),[from2,setFrom]=import_react102.useState("blank"),[field,setField]=import_react102.useState("name"),slug3=name?exports_eikon_knobs.slug(name):"",ok=slug3.length>0,submit3=async()=>{if(!ok)return;if(from2==="blank")return props.done({name:slug3,from:"blank"});if(props.onChain(),from2==="file"){let file2=await openTextPrompt(props.dialog,{title:"Source file",label:"absolute or ~ path (png / jpg / webp / gif / mp4)"});return props.done(file2?{name:slug3,from:"file",file:file2}:null)}let src3=await openTextPrompt(props.dialog,{title:"Inspect eikon source",label:INSTALL_HINT});if(!src3)return props.done(null);try{let info2=await exports_eikon.inspectSource(src3),ok2=await openConfirm(props.dialog,{title:`Install '${info2.title??info2.name}'?`,body:[`Name: ${info2.name}`,`Author: ${info2.author??"unknown"}`,`Version: ${info2.version??"unknown"}`,`Source: ${info2.sourceLabel}`,`Trust: ${info2.trust}${info2.reason?` (${info2.reason})`:""}`,`Preview: ${info2.previewAvailable?"available":"none"}; poster: ${info2.posterAvailable?"available":"none"}`,"Install does not activate; use the Gallery after install to select it."].join(`
4159
4160
  `),yes:"install",no:"cancel"});return props.done(ok2?{name:slug3,from:"install",src:src3}:null)}catch(e){return await openConfirm(props.dialog,{title:"Inspect failed",danger:!0,body:e instanceof Error?e.message:String(e),yes:"ok",no:"cancel"}),props.done(null)}};useKeyboard((key3)=>{if(key3.name==="escape")return props.done(null);if(key3.name==="tab"){let i=ORDER4.indexOf(field);return setField(ORDER4[(i+(key3.shift?-1:1)+ORDER4.length)%ORDER4.length])}if(key3.name==="return")return void submit3();if(field==="name"){if(key3.name==="backspace")return setName((n)=>n.slice(0,-1));if(key3.raw&&key3.raw.length===1&&/[A-Za-z0-9 _-]/.test(key3.raw))return setName((n)=>n+key3.raw);return}if(key3.name==="up"){let i=FROMS.findIndex((f)=>f.id===from2);return setFrom(FROMS[Math.max(0,i-1)].id)}if(key3.name==="down"){let i=FROMS.findIndex((f)=>f.id===from2);return setFrom(FROMS[Math.min(FROMS.length-1,i+1)].id)}});let bg2=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"New eikon"})})}),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:bg2("name"),children:[$jsx("box",{width:9,children:$jsx("text",{fg:theme.textMuted,children:"Name"})}),$jsxs("text",{children:[$jsx("span",{fg:theme.text,children:name}),field==="name"?$jsx("span",{fg:theme.accent,children:"\u2588"}):null]})]}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:slug3?` \u2192 ${slug3}`:" type a name"})}),$jsx("box",{height:1}),$jsx("box",{height:1,backgroundColor:bg2("from"),children:$jsx("text",{fg:theme.textMuted,children:"From (\u2191\u2193)"})}),FROMS.map((f)=>{let on=f.id===from2,fg2=on?theme.accent:theme.text;return $jsxs("box",{height:1,flexDirection:"row",backgroundColor:bg2("from"),children:[$jsx("box",{width:2,children:$jsx("text",{fg:fg2,children:on?"\u25B8 ":" "})}),$jsx("box",{width:14,children:$jsx("text",{fg:fg2,children:f.label})}),$jsx("text",{fg:theme.textMuted,children:f.hint})]},f.id)}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:ok?"Enter create \xB7 Tab next field \xB7 Esc cancel":"type a name"})})]})};extend({slider:SliderRenderable});var PANES=["knobs","preview","strip"],HELP_H=4,COL={flexDirection:"column"},mb2=(n)=>n<1024?`${n} B`:n<1048576?`${(n/1024).toFixed(0)} KB`:`${(n/1048576).toFixed(1)} MB`,HEAD2=[{id:"open",kind:"select",label:"eikon"},{id:"rasterizer",kind:"select",label:"rasterizer"},{id:"source",kind:"prompt",label:"source"},{id:"-1",kind:"divider",label:""},{id:"fetch",kind:"action",label:"download source",show:(_s,status)=>status.downloadable},{id:"knobsfor",kind:"action",label:"tune",show:(_s,status)=>!!status.path},{id:"reset",kind:"action",label:"reset",show:(_s,status)=>!!status.path},{id:"revert",kind:"action",label:"revert",show:(s)=>s.dirty},{id:"-2",kind:"divider",label:"",show:(_s,status)=>!!status.path},{id:"h-input",kind:"header",label:"input",show:(_s,status)=>!!status.path},{id:"contrast",kind:"tone",label:"contrast",show:(_s,status)=>!!status.path,knob:{kind:"slider",min:0.25,max:4,step:0.05,default:1,hint:"Spread pixel values around their mean. \xD71 = source as-is; higher sharpens, lower flattens. Applied to the image before rasterizing."}},{id:"invert",kind:"tone",label:"invert",show:(_s,status)=>!!status.path,knob:{kind:"toggle",default:!0,hint:"Swap light\u2194dark in the source pixels. On for a light subject on a dark terminal background \u2014 turn off if the subject is darker than its surround."}},{id:"flip",kind:"tone",label:"flip",show:(_s,status)=>!!status.path,knob:{kind:"cycle",options:["none","h","v","hv"],default:"none",hint:"Mirror the source horizontally, vertically, or both before rasterizing."}},{id:"-3",kind:"divider",label:"",show:(_s,status)=>!!status.path}],HELP={open:"Which eikon you're editing. Enter to switch, create a new one, or install from elsewhere.",rasterizer:"The engine that turns your source image/video into text art. Each rasterizer exposes its own look-and-feel settings below the divider.",source:"Pick, generate, or clear source.",fetch:"Download published source for local editing.",knobsfor:"\u2190\u2192 toggles whether the settings below apply to every state or just the one selected in the strip.",reset:"Restore every setting below to this rasterizer's defaults and drop per-state overrides.",submit:"Submit this local eikon after backend preflight.",revert:"Throw away unsaved edits and reload this eikon from disk."},FLIPS=["none","h","v","hv"];function helpOf(row3){if(!row3)return"";if(row3.id==="source")return $jsx($Fragment,{children:$jsx("span",{children:HELP.source})});let head=HELP[row3.id];if(head)return head;if(!row3.knob)return"";if(row3.knob.hint)return row3.knob.hint;if(row3.knob.kind==="cycle")return`\u2190\u2192 or Enter cycles: ${row3.knob.options.join(" \xB7 ")}.`;if(row3.knob.kind==="toggle")return"Space or Enter toggles on/off.";return`\u2190\u2192 or drag adjusts (${row3.knob.min}\u2013${row3.knob.max}); scroll while selected also works.`}function buildRows(r,s,status){let dyn=status.path?Object.entries(r.knobs).map(([id,def2])=>({id,kind:"knob",label:def2.label??id,knob:def2})):[],head=HEAD2.filter((h2)=>h2.show?h2.show(s,status):!0);return dyn.length?[...head,{id:"h-r",kind:"header",label:r.name},...dyn]:head}var MINI_W=12;function Mini(props){let theme=useTheme().theme,d2=props.dims??{w:1,h:1},ar=d2.w/d2.h,bw=ar>=1?MINI_W:Math.max(4,Math.round(MINI_W*ar)),bh=ar>=1?Math.max(4,Math.round(MINI_W/ar)):MINI_W,short2=Math.min(bw,bh),cw=Math.max(1,short2*props.sp.zoom),cx=(bw-cw)*props.sp.ox,cy=(bh-cw)*props.sp.oy,on=(x2,y2)=>x2>=cx&&x2<cx+cw&&y2>=cy&&y2<cy+cw,cell=(x2,ty)=>{let up=on(x2,ty*2),dn=on(x2,ty*2+1);return up&&dn?"\u2588":up?"\u2580":dn?"\u2584":"\xB7"};return $jsx("box",{flexDirection:"column",flexShrink:0,backgroundColor:theme.backgroundElement,children:Array.from({length:Math.ceil(bh/2)},(_2,ty)=>$jsx("text",{fg:theme.textMuted,children:Array.from({length:bw},(_3,x2)=>cell(x2,ty)).join("")},ty))})}var SP_ROWS=["pan x","pan y","zoom","fps"];function PanBars(props){let theme=useTheme().theme,z2=props.sp.zoom,slack=1-z2,on=(i)=>props.focused&&props.sel===i,fg2=(i)=>on(i)?theme.accent:theme.textMuted,wheel=(k2)=>(e)=>{e.stopPropagation();let d2=e.scroll?.direction;if(d2==="up"||d2==="left")props.onWheel(k2,-1);if(d2==="down"||d2==="right")props.onWheel(k2,1)},drag=import_react104.useRef(null),grab=(k2,at)=>{drag.current={at,v:props.sp[k2],k:k2}},scrub=(at,L2)=>{let d2=drag.current;if(!d2||slack<=0)return;props.onSet(d2.k,Math.max(0,Math.min(1,+(d2.v+(at-d2.at)/(slack*L2)).toFixed(3))))},drop=()=>{drag.current=null},tw=Math.max(1,Math.round(z2*W2)),tl=Math.min(W2-tw,Math.round(props.sp.ox*slack*W2)),hbar=" ".repeat(tl)+"\u2588".repeat(tw)+" ".repeat(W2-tl-tw),vh=H*2,th=Math.max(1,z2*vh),ty=props.sp.oy*slack*vh,vbar=Array.from({length:H},(_2,y2)=>{let up=y2*2>=ty&&y2*2<ty+th,dn=y2*2+1>=ty&&y2*2+1<ty+th;return up&&dn?"\u2588\u2588":up?"\u2580\u2580":dn?"\u2584\u2584":" "});return $jsxs("box",{flexDirection:"row",flexShrink:0,children:[$jsxs("box",{flexDirection:"column",flexShrink:0,children:[props.children,$jsx("box",{width:W2,height:1,backgroundColor:theme.border,onMouseMove:()=>props.onHover(0),onMouseScroll:wheel("ox"),onMouseDown:(e)=>grab("ox",e.x),onMouseDrag:(e)=>scrub(e.x,W2),onMouseUp:drop,onMouseDragEnd:drop,children:$jsx("text",{fg:fg2(0),children:hbar})})]}),$jsx("box",{flexDirection:"column",width:2,height:H,backgroundColor:theme.border,onMouseMove:()=>props.onHover(1),onMouseScroll:wheel("oy"),onMouseDown:(e)=>grab("oy",e.y),onMouseDrag:(e)=>scrub(e.y,H),onMouseUp:drop,onMouseDragEnd:drop,children:vbar.map((g,y2)=>$jsx("text",{fg:fg2(1),children:g},y2))})]})}function SpatialBar(props){let theme=useTheme().theme,rows3=[{label:"zoom",k:"zoom",min:0.1,max:1,v:props.sp.zoom,i:2},{label:"fps",k:"fps",min:4,max:30,v:props.fps,i:3}],wheel=(k2)=>(e)=>{e.stopPropagation();let d2=e.scroll?.direction;if(d2==="up")props.onWheel(k2,-1);if(d2==="down")props.onWheel(k2,1)};return $jsxs("box",{flexDirection:"row",marginTop:1,flexShrink:0,children:[$jsx("box",{flexDirection:"column",gap:1,flexShrink:0,children:rows3.map((d2)=>{let on=props.focused&&d2.i===props.sel;return $jsxs("box",{height:1,flexDirection:"row",backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:()=>props.onHover(d2.i),onMouseScroll:wheel(d2.k),children:[$jsx("box",{width:2,children:$jsx("text",{fg:on?theme.primary:theme.textMuted,children:on?"\u25B8 ":" "})}),$jsx("box",{width:7,children:$jsx("text",{fg:on?theme.text:theme.textMuted,children:d2.label})}),$jsx("box",{width:20,height:1,children:$jsx("slider",{orientation:"horizontal",min:d2.min,max:d2.max,value:d2.v,foregroundColor:on?theme.accent:theme.textMuted,backgroundColor:theme.border,onChange:(v2)=>props.onSet(d2.k,d2.k==="fps"?Math.round(v2):+v2.toFixed(3))})}),$jsx("box",{width:7,children:$jsx("text",{fg:on?theme.text:theme.textMuted,children:` ${d2.k==="fps"?d2.v.toFixed(0):d2.v.toFixed(2)}`})})]},d2.label)})}),$jsx("box",{width:2}),$jsx(Mini,{sp:props.sp,dims:props.dims})]})}function valueOf(s,r,row3,theme,status,peek5,busy){if(row3.id==="open")return`${s.name} \u25B8`;if(row3.id==="rasterizer"){let a=r.available();if(a===!0)return`${r.name} \u25B8`;return $jsxs($Fragment,{children:[$jsx("span",{children:`${r.name} \u25B8`}),$jsx("span",{fg:theme.warning,children:` \u26A0 ${a}`})]})}if(row3.id==="source"){if(!status?.path){if(status?.kind==="downloadable")return"Download source";if(status?.kind==="baked")return"Baked only";return"Missing source"}let d2=s.dims,sz=status.size===void 0?"?":mb2(status.size);return d2?`${basename12(status.path)} \xB7 ${d2.w}\xD7${d2.h} \xB7 ${sz}`:`${basename12(status.path)} \xB7 ${sz}`}if(row3.id==="knobsfor")return`\u25C2 ${!!s.per[s.state]?`${s.state} only`:"all states"} \u25B8`;if(row3.id==="reset")return"\u25B8 defaults";if(row3.id==="revert")return"\u25B8 reload from disk";if(row3.kind==="tone"){if(row3.id==="contrast")return`\xD7${s.tone.contrast.toFixed(2)}`;if(row3.id==="invert")return s.tone.invert?"\u25CF on":"\u25CB off";if(row3.id==="flip")return`\u25C2 ${s.tone.flip} \u25B8`}if(row3.id==="fetch")return busy?"downloading\u2026":peek5?`\u25B8 ${peek5.n} files \xB7 ${mb2(peek5.bytes)}`:"\u25B8 local editable source";if(row3.kind==="knob"&&row3.knob){let k2=exports_eikon_knobs.eff(s,s.state)[row3.id]??row3.knob.default;if(row3.knob.kind==="cycle")return`\u25C2 ${String(k2)} \u25B8`;if(row3.knob.kind==="toggle")return k2?"\u25CF on":"\u25CB off";if(row3.knob.kind==="slider")return Number(k2).toFixed(2)}return""}function KnobRow(props){let theme=useTheme().theme,{row:row3,on,dim:dim2}=props,slider=row3.knob?.kind==="slider"?row3.knob:void 0,sval=!slider?0:row3.kind==="tone"?props.s.tone.contrast:Number(exports_eikon_knobs.eff(props.s,props.s.state)[row3.id]??slider.default),pushed=import_react104.useRef(sval);pushed.current=sval;let slide=(v2)=>{if(v2!==pushed.current)props.onSlide?.(v2)};if(row3.kind==="divider")return $jsx("box",{id:props.id,height:1,children:$jsx("text",{fg:theme.border,children:"\u2500".repeat(24)})});if(row3.kind==="header")return $jsx("box",{id:props.id,height:1,children:$jsx("text",{fg:theme.textMuted,children:$jsx("u",{children:row3.label})})});let scroll=(e)=>{if(!on||!slider||!props.onWheel)return;e.stopPropagation();let d2=e.scroll?.direction;if(d2==="up"||d2==="left")props.onWheel(-1);if(d2==="down"||d2==="right")props.onWheel(1)};return $jsxs("box",{id:props.id,height:1,flexDirection:"row",backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:props.onHover,onMouseDown:props.onClick,onMouseScroll:scroll,children:[$jsx("box",{width:2,children:$jsx("text",{fg:on?theme.primary:theme.textMuted,children:on?"\u25B8 ":" "})}),$jsx("box",{width:14,children:$jsx("text",{fg:dim2?theme.textMuted:on?theme.text:theme.textMuted,children:row3.label})}),slider?$jsxs($Fragment,{children:[$jsx("box",{width:20,height:1,children:$jsx("slider",{orientation:"horizontal",min:slider.min,max:slider.max,value:sval,foregroundColor:on?theme.accent:theme.textMuted,backgroundColor:theme.border,onChange:slide})}),$jsx("box",{width:1})]}):null,$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:props.busy&&row3.id==="fetch"?$jsx(Spinner,{color:theme.accent,label:"downloading\u2026"}):$jsx("text",{fg:dim2?theme.textMuted:theme.text,children:valueOf(props.s,props.r,row3,theme,props.status,props.peek,props.busy)})})]})}function Strip(props){let theme=useTheme().theme,glyph=useSpinnerGlyph(props.pending.size>0);return $jsx("box",{flexDirection:"row",gap:1,children:STATES2.map((st)=>{let on=props.s.state===st,own=!!props.s.per[st],status=props.stats.get(st),mark2=status.kind==="missing"?"missing":status.kind==="downloadable"?"download":status.role===st?"own src":own?"forked":"",f=props.frames.get(st),gen=props.pending.has(st),empty=!f&&!gen;return $jsxs("box",{flexDirection:"column",alignItems:"center",onMouseDown:()=>{if(props.onPick(st),empty)props.onEmpty?.(st)},children:[$jsx("box",{border:!0,borderStyle:"rounded",borderColor:on&&props.focused?theme.primary:on?theme.accent:theme.border,width:18,height:10,overflow:"hidden",alignItems:"center",justifyContent:"center",children:gen?$jsx("text",{fg:theme.accent,children:`${glyph} gen`}):f?f.map((ln,i)=>$jsx("text",{fg:on?theme.text:theme.textMuted,children:ln},i)):$jsx("text",{fg:theme.textMuted,children:"+"})}),$jsx("box",{height:1,children:$jsx("text",{fg:on?theme.accent:theme.textMuted,children:st})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:mark2})})]},st)})})}var BLANK3=Array.from({length:H},()=>" ".repeat(W2)),genCaps=null,probeGen=()=>{if(genCaps)return genCaps;let p=exports_eikon_gen.probeCached();return p.catch(()=>{genCaps=null}),genCaps=p};var EikonStudio=import_react104.memo((props)=>{let theme=useTheme().theme,keys=useKeys(),dialog=useDialog(),gw=useGateway(),toast=useToast(),wide=useTerminalDimensions().width>=120,ksb=import_react104.useRef(null),outer=import_react104.useRef(null);import_react104.useSyncExternalStore(exports_eikon.onRegistry,()=>exports_eikon.rasterizers().length);let[s,setS]=import_react104.useState(null),[pane,setPane]=import_react104.useState("knobs"),[sel,setSel]=import_react104.useState(0),[spSel,setSpSel]=import_react104.useState(0),selRef=import_react104.useRef(0);selRef.current=sel;let spRef=import_react104.useRef(0);spRef.current=spSel;let sRef=import_react104.useRef(null);sRef.current=s;let[frames,setFrames]=import_react104.useState([BLANK3]),[tick3,setTick]=import_react104.useState(0),[play,setPlay]=import_react104.useState(!0),[busy,setBusy]=import_react104.useState(!1),[fetching,setFetching]=import_react104.useState(!1),[peek5,setPeek]=import_react104.useState(void 0),[thumbs,setThumbs]=import_react104.useState(new Map),[err,setErr]=import_react104.useState(null),[saving,setSaving]=import_react104.useState(!1),[pending3,setPending]=import_react104.useState(new Set),[genOk,setGenOk]=import_react104.useState(null),frame=frames[tick3%frames.length]??BLANK3,stampRef=import_react104.useRef(""),rev2=import_react104.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision),r=import_react104.useMemo(()=>exports_eikon.pick(s?.rasterizer??get2("eikonRasterizer")),[s?.rasterizer]),spatialOk=caps2.ffmpeg,open2=import_react104.useCallback((name)=>{resetCache(),stampRef.current=exports_eikon.sourceStamp(name);let seed=exports_eikon.readStudio(name),ra=exports_eikon.pick(seed?.rasterizer??get2("eikonRasterizer")),next2=exports_eikon_knobs.fresh(name,ra,seed),src4=exports_eikon.findSource(name,"idle");next2.dims=src4?exports_eikon.probe(src4)??null:null;for(let st of STATES2){let p=exports_eikon.findSource(name,st);if(p)prewarm(p,next2.fps)}setS(next2),selRow.current=void 0,setSel(0),setPane("knobs"),setErr(null),setTick(0),setFrames([BLANK3])},[]),tried=import_react104.useRef(!1);import_react104.useEffect(()=>{if(tried.current)return;if(tried.current=!0,props.name)return open2(props.name||exports_eikon_knobs.slug("new"));let n2=get2("eikon");if(n2)open2(n2)},[open2,props.name]);let dialogRef=import_react104.useRef(dialog);dialogRef.current=dialog,import_react104.useEffect(()=>{if(props.name===void 0)return;let next2=props.name||exports_eikon_knobs.slug("new"),cur=sRef.current;if(cur?.name===next2)return;if(!cur?.dirty)return open2(next2);let dead=!1;return openConfirm(dialogRef.current,{title:"Discard unsaved edits?",danger:!0,body:`Switch to '${next2}' and drop in-memory changes to '${cur.name}'.`}).then((ok)=>{if(!dead&&ok)open2(next2)}),()=>{dead=!0}},[props.name,open2]),import_react104.useEffect(()=>{let dead=!1;return probeGen().then((c)=>{if(!dead)setGenOk(c)}).catch(()=>{}),()=>{dead=!0}},[]);let stats=import_react104.useMemo(()=>{if(!s)return new Map;return new Map(STATES2.map((st)=>[st,exports_eikon.sourceStatus(s.name,st,{sources:s.sources})]))},[s?.name,s?.sources,rev2]),status=s?stats.get(s.state):void 0,src3=status?.path,live=!!src3,baked2=import_react104.useMemo(()=>{if(live||!s)return;let p=exports_eikon.baked(s.name);if(!p)return;try{return exports_eikon.parseEikonFile(p)}catch{return}},[live,s?.name]),url2=status?.sourceUrl;import_react104.useEffect(()=>{if(setPeek(void 0),!url2||!status?.downloadable)return;let dead=!1;return exports_eikon.peekSource(url2).then((x2)=>{if(!dead)setPeek(x2)}),()=>{dead=!0}},[url2,status?.downloadable]),import_react104.useEffect(()=>{if(!s)return;let stamp2=exports_eikon.sourceStamp(s.name);if(!stampRef.current){stampRef.current=stamp2;return}if(stamp2===stampRef.current)return;if(stampRef.current=stamp2,s.dirty){toast.show({variant:"info",message:"Source changed on disk",duration:3000});return}open2(s.name)},[rev2,s?.name,s?.dirty,open2,toast]);let rows3=import_react104.useMemo(()=>s&&status?buildRows(r,s,status):[],[r,s,status]),navRows=import_react104.useMemo(()=>rows3.map((x2,i)=>({...x2,i})).filter((x2)=>x2.kind!=="divider"&&x2.kind!=="header"),[rows3]),selRow=import_react104.useRef(void 0),rid=(x2)=>`${x2.kind}:${x2.id}`,setSelBy=import_react104.useCallback((arg)=>{setSel((prev)=>{let next2=typeof arg==="function"?arg(prev):arg,row3=navRows[next2];return selRow.current=row3?rid(row3):void 0,next2})},[navRows]),prevRows=import_react104.useRef(navRows);import_react104.useEffect(()=>{if(prevRows.current===navRows)return;prevRows.current=navRows;let id=selRow.current;if(!id)return;let ni=navRows.findIndex((x2)=>rid(x2)===id);if(ni>=0&&ni!==selRef.current)setSel(ni)},[navRows]);let kScroll=(ni)=>{let row3=navRows[ni];if(row3)ksb.current?.scrollChildIntoView(`knob-${row3.kind}-${row3.id}`)};import_react104.useEffect(()=>{if(!s)return;if(!src3){let clip=baked2?.states.get(s.state);setFrames(clip?.frames.length?clip.frames:[BLANK3]),setErr(null),setBusy(!1),setTick(0);return}let ctrl=new AbortController;return setBusy(!0),cached2(r,src3,s.spatial,s.tone,s.fps,exports_eikon_knobs.eff(s,s.state),ctrl.signal).then((out)=>{if(ctrl.signal.aborted)return;if(setBusy(!1),"err"in out){setErr(out.err);return}setErr(null),setFrames(out.frames),setTick((t2)=>t2%out.frames.length)}),()=>ctrl.abort()},[s?.spatial,s?.tone,s?.base,s?.per,s?.state,s?.fps,s?.rasterizer,src3,r,baked2]),import_react104.useEffect(()=>{if(!play||!props.focused||frames.length<=1||busy)return;let fps=live?s?.fps??FPS0:baked2?.states.get(s?.state??"idle")?.fps??FPS0,id=setInterval(()=>setTick((t2)=>t2+1),1000/Math.max(1,fps));return()=>clearInterval(id)},[play,props.focused,frames.length,busy,live,s?.fps,s?.state,baked2]),import_react104.useEffect(()=>{if(!s)return;let dead=!1,t2=setTimeout(()=>{if(dead)return;let jobs=STATES2.map((st)=>{let sp=stats.get(st)?.path;if(!sp){let f=baked2?.states.get(st)?.frames[0];return Promise.resolve([st,f?thumb(f):void 0])}return cached2(r,sp,s.spatial,s.tone,s.fps,exports_eikon_knobs.eff(s,st)).then((res)=>[st,"err"in res?void 0:thumb(res.frames[0])])});Promise.all(jobs).then((done)=>{if(dead)return;setThumbs(new Map(done))})},400);return()=>{dead=!0,clearTimeout(t2)}},[frames,s?.per,s?.sources,s?.name,s?.fps,r,baked2,stats]);let mutate=(fn)=>setS((p)=>p?fn(p):p),setSpatial=(sp)=>mutate((p)=>({...p,spatial:{...p.spatial,...sp},dirty:!0})),setBar=(k2,v2)=>k2==="fps"?mutate((p)=>({...p,fps:Math.round(v2),dirty:!0})):setSpatial({[k2]:v2}),stepBar=(k2,d2)=>{let cur=sRef.current;if(!cur)return;if(k2==="fps")return setBar("fps",Math.max(4,Math.min(30,cur.fps+d2*2)));if(k2==="zoom")return setSpatial({zoom:Math.max(0.1,Math.min(1,+(cur.spatial.zoom+d2*0.03).toFixed(3)))});return setSpatial({[k2]:Math.max(0,Math.min(1,+(cur.spatial[k2]+d2*0.03).toFixed(3)))})},doSave=import_react104.useCallback(async()=>{if(!s)return!1;if(!s.dirty)return toast.show({variant:"info",message:"Nothing to save"}),!0;if(!live)return toast.show({variant:"warning",message:"No source \u2014 download or attach before saving"}),!1;setSaving(!0);try{let f=await exports_eikon.save({...s,dirty:!1});return mutate((p)=>({...p,dirty:!1})),toast.show({variant:"success",message:`Saved \u2192 ${basename12(f)}`}),!0}catch(e){return toast.error(e instanceof Error?e:Error(String(e))),!1}finally{setSaving(!1)}},[s,live,toast]),doSaveUse=import_react104.useCallback(async()=>{if(!s)return;if(!await doSave())return;exports_eikon.useInstalled(s.name),toast.show({variant:"success",message:`Avatar \u2192 ${s.name}`})},[doSave,s,toast]),doSelectRasterizer=()=>{let opts=exports_eikon.rasterizers().map((x2)=>{let a=x2.available();return{title:x2.name,value:x2.name,description:Object.keys(x2.knobs).join(" \xB7 "),hint:a===!0?void 0:a}});dialog.replace($jsx(DialogSelect,{title:"Rasterizer",filterable:!1,current:r.name,options:opts,onSelect:(o)=>{dialog.clear();let next2=exports_eikon.rasterizer(o.value);if(!next2)return;let a=next2.available();if(a!==!0)return toast.show({variant:"warning",message:`${o.value}: ${a}`});set("eikonRasterizer",o.value),mutate((p)=>exports_eikon_knobs.swap(p,next2))}}),()=>{})},runGenerate=async(st,kind2)=>{if(!s)return;let seed=stats.get("idle")?.path;setPending((prev)=>{let n2=new Set(prev);return n2.add(st),n2});let out=await openGenerate(dialog,exports_eikon_gen.current(),{state:st,kind:kind2,seed,lastPrompt:s.prompts?.[st]});if(!out){setPending((prev)=>{let n2=new Set(prev);return n2.delete(st),n2});return}let role=st==="idle"&&!s.sources.base?"base":st;try{let f=exports_eikon.adopt(s.name,out.path,role);mutate((p)=>({...p,sources:{...p.sources,[role]:f},prompts:{...p.prompts,[st]:out.prompt},dirty:!0}))}catch(e){toast.error(e instanceof Error?e:Error(String(e)))}finally{setPending((prev)=>{let n2=new Set(prev);return n2.delete(st),n2})}},download=async()=>{if(!s||fetching)return;setFetching(!0),await exports_eikon.downloadSource(s.name).then((out)=>{if(toast.show({variant:"success",message:`Downloaded ${out.n} file(s) \xB7 ${mb2(out.bytes)}`}),sRef.current?.dirty)mutate((prev)=>({...prev,sources:{...out.sources,...prev.sources}}));else open2(s.name)}).catch((e)=>toast.error(e instanceof Error?e:Error(String(e)))).finally(()=>setFetching(!1))},doSource=(forSt)=>{if(!s)return;let st=forSt??s.state,info2=stats.get(st)??exports_eikon.sourceStatus(s.name,st,{sources:s.sources}),own=info2.role===st||st==="idle"&&info2.role==="base"||s.sources[st]!==void 0,loc=exports_eikon.localSources(s.name),opts=[...info2.downloadable?[{title:"Download source",value:"download"}]:[],...loc.map((x2)=>({title:x2.file,value:`pick:${x2.file}`,hint:x2.role??"source"})),...genOk?.image?[{title:"Generate image\u2026",value:"gen-image"}]:[],...genOk?.video?[{title:"Generate video\u2026",value:"gen-video"}]:[],{title:"Local file\u2026",value:"local"},...st!=="idle"&&own?[{title:"Same as base",value:"same"}]:[],...own?[{title:"Remove",value:"remove"}]:[]];dialog.replace($jsx(DialogSelect,{title:`Source for '${st}'`,filterable:!1,options:opts,onSelect:async(o)=>{if(o.value==="download"){dialog.clear(),await download();return}if(o.value.startsWith("pick:")){dialog.clear();let file2=o.value.slice(5),role=st==="idle"&&loc.find((x2)=>x2.file===file2)?.role==="base"?"base":st;mutate((prev)=>({...prev,sources:{...prev.sources,[role]:file2},dirty:!0}));return}if(o.value==="local"){let p=await openPathPrompt(dialog,gw,{title:`Source for '${st}'`,label:"png/jpg/webp/gif/mp4/webm/mov \xB7 Tab completes",filter:/\.(png|jpe?g|webp|gif|mp4|webm|mov)$/i});if(!p)return;let role=st==="idle"&&!s.sources.base?"base":st;try{let f=exports_eikon.adopt(s.name,p,role);mutate((prev)=>({...prev,sources:{...prev.sources,[role]:f},dirty:!0}))}catch(e){toast.error(e instanceof Error?e:Error(String(e)))}return}if(o.value==="gen-image")return void runGenerate(st,"image");if(o.value==="gen-video")return void runGenerate(st,"video");dialog.clear(),mutate((prev)=>({...prev,sources:{...prev.sources,[st==="idle"?"base":st]:null},dirty:!0}))}}),()=>{})},doPrompt=async(id)=>{if(!s)return;if(id==="source")return doSource()},switchTo=import_react104.useCallback(async(name)=>{let cur=sRef.current;if(cur?.name===name)return;if(cur?.dirty){if(!await openConfirm(dialog,{title:"Discard unsaved edits?",danger:!0,body:`Open '${name}' and drop in-memory changes to '${cur.name}'.`}))return}open2(name)},[dialog,open2]),apply=import_react104.useCallback(async(res)=>{if(!res)return;if(res.from==="blank")return exports_eikon.ensure(res.name),switchTo(res.name);if(res.from==="file"){exports_eikon.ensure(res.name);try{exports_eikon.adopt(res.name,res.file,"base")}catch(e){return toast.error(e instanceof Error?e:Error(String(e)))}return switchTo(res.name)}toast.show({variant:"info",message:`Installing '${res.name}' from ${res.src}\u2026`}),await exports_eikon.installPackage(res.src,{name:res.name}).then((out)=>{toast.show({variant:"success",message:`Installed '${out.name}' (${out.n} files)`}),switchTo(out.name)}).catch((e)=>toast.error(e instanceof Error?e:Error(String(e))))},[switchTo,toast]),doNew=import_react104.useCallback(async()=>{let res=await openNewEikon(dialog,{});await apply(res)},[dialog,apply]),eikonOptions=import_react104.useCallback(()=>{let installed=exports_eikon.list().map((e)=>({title:e.name,value:e.name,category:"installed",hint:e.hasSource?"\u25CF source":e.sourceUrl?"\u25CB source available":"\u2014"})),seen=new Set(installed.map((o)=>o.value)),bundled=listEikons([BUNDLED_EIKON_DIR,hermesPath("eikons")]).filter((e)=>e.path.startsWith(BUNDLED_EIKON_DIR)).map((e)=>{let slug3=e.meta.name.toLowerCase();return{title:e.meta.name,value:slug3,category:"bundled",hint:`${e.meta.width}\xD7${e.meta.height}`}}).filter((o)=>!seen.has(o.value)),raw2=exports_eikon.raw().filter((n2)=>!seen.has(n2)).map((n2)=>({title:n2,value:n2,category:"installed",hint:"(unsaved)"}));return[...installed,...raw2,...bundled]},[]),doInstall=import_react104.useCallback(async()=>{let src4=await openTextPrompt(dialog,{title:"Inspect eikon source",label:"catalog name \xB7 github.com/u/r/eikon-name \xB7 git URL \xB7 http://\u2026/ \xB7 local dir"});if(!src4)return;let info2;try{info2=await exports_eikon.inspectSource(src4)}catch(e){return toast.error(e instanceof Error?e:Error(String(e)))}if(!await openConfirm(dialog,{title:`Install '${info2.title??info2.name}'?`,body:[`Name: ${info2.name}`,`Author: ${info2.author??"unknown"}`,`Version: ${info2.version??"unknown"}`,`Source: ${info2.sourceLabel}`,`Trust: ${info2.trust}${info2.reason?` (${info2.reason})`:""}`,`Preview: ${info2.previewAvailable?"available":"none"}; poster: ${info2.posterAvailable?"available":"none"}`,"Install does not activate; use Ctrl+U or Gallery after install to select it."].join(`
4160
- `),yes:"install",no:"cancel"}))return;toast.show({variant:"info",message:`Installing from ${src4}\u2026`}),await exports_eikon.installPackage(src4).then((out)=>{toast.show({variant:"success",message:`Installed '${out.name}' (${out.n} files)`}),switchTo(out.name)}).catch((e)=>toast.error(e instanceof Error?e:Error(String(e))))},[dialog,switchTo,toast]),doOpen=import_react104.useCallback(()=>{let cur=sRef.current,opts=[...eikonOptions(),{title:"+ New\u2026",value:"__new",category:""},{title:"+ Install\u2026",value:"__install",category:""}];dialog.replace($jsx(DialogSelect,{title:"Open eikon",current:cur?.name,options:opts,onSelect:(o)=>{if(dialog.clear(),o.value==="__new")return void doNew();if(o.value==="__install")return void doInstall();switchTo(o.value)}}),()=>{})},[dialog,eikonOptions,switchTo,doNew,doInstall]),doSubmit=import_react104.useCallback(async()=>{let cur=sRef.current;if(!cur)return;let path7=submitPath(cur.name);if(publishedInfo(path7)){toast.show({variant:"warning",title:"Published eikon",message:"Create a local draft before submitting",duration:6000});return}await openEikonSubmit(dialog,{name:cur.name,path:path7,submit:submit2})},[dialog,toast]),doAction=async(id)=>{if(!s)return;if(id==="knobsfor")return mutate((p)=>p.per[p.state]?exports_eikon_knobs.unfork(p):exports_eikon_knobs.fork(p));if(id==="submit"){doSubmit();return}if(id==="revert"){discard();return}if(id==="reset"){if(await openConfirm(dialog,{title:"Reset settings?",body:"Restore rasterizer defaults and drop all per-state overrides.",danger:!0}))mutate((p)=>exports_eikon_knobs.reset(p,r));return}if(id==="fetch"){if(!status?.downloadable||fetching)return;await download()}},doStripMenu=()=>{if(!s)return;dialog.replace($jsx(DialogSelect,{title:`State: ${s.state}`,filterable:!1,options:[{title:"Source\u2026",value:"source"},{title:s.per[s.state]?"Clear override (back to base)":"Tune this state only",value:"fork"}],onSelect:(o)=>{if(o.value==="source"){doSource();return}dialog.clear(),mutate(s.per[s.state]?exports_eikon_knobs.unfork:exports_eikon_knobs.fork)}}),()=>{})},setTone=(t2)=>mutate((p)=>({...p,tone:{...p.tone,...t2},dirty:!0})),stepRow=(row3,d2)=>{if(row3.kind==="tone"){if(row3.id==="contrast"){let def2=row3.knob,cur=sRef.current?.tone.contrast??1;return setTone({contrast:+Math.max(def2.min,Math.min(def2.max,cur+d2*def2.step)).toFixed(2)})}if(row3.id==="invert")return setTone({invert:!sRef.current?.tone.invert});if(row3.id==="flip"){let cur=sRef.current?.tone.flip??"none",i=FLIPS.indexOf(cur);return setTone({flip:FLIPS[(i+d2+FLIPS.length)%FLIPS.length]})}return}if(row3.kind!=="knob"||!row3.knob)return;mutate((p)=>exports_eikon_knobs.edit(p,(k2)=>exports_eikon_knobs.step(k2,row3.id,row3.knob,d2)))},act=(row3,via)=>{if(!row3||!sRef.current)return;if(row3.kind==="select"){if(row3.id==="open")return doOpen();return doSelectRasterizer()}if(row3.kind==="prompt")return void doPrompt(row3.id);if(row3.kind==="action"){if(via==="space"&&row3.id==="reset")return;return void doAction(row3.id)}if(row3.kind==="tone"||row3.kind==="knob"){if(row3.knob.kind==="slider")return;return stepRow(row3,1)}},activate=()=>act(navRows[selRef.current],"enter"),toggle=()=>act(navRows[selRef.current],"space"),adjust=(d2)=>{let row3=navRows[selRef.current];if(!row3)return;if(row3.id==="knobsfor")return void doAction("knobsfor");stepRow(row3,d2)},discard=async()=>{let cur=sRef.current;if(!cur?.dirty)return!1;let pick2=await openSaveDiscard(dialog,{title:"Unsaved edits",body:`'${cur.name}' has unsaved changes. Save them, discard them, or keep editing?`});if(pick2==="save"){if(await doSave())open2(cur.name);return!0}if(pick2==="discard")open2(cur.name);return!0},refresh=import_react104.useCallback(()=>{let cur=sRef.current;if(!cur)return;if(stampRef.current=exports_eikon.sourceStamp(cur.name),cur.dirty){toast.show({variant:"info",message:"Reload skipped: unsaved edits",duration:3000});return}open2(cur.name),toast.show({variant:"info",message:"Reloaded",duration:1000})},[open2,toast]);useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(key3.name==="u"&&key3.ctrl&&sRef.current)return void doSaveUse();if(key3.name==="u"&&sRef.current)return void doSubmit();if(key3.eventType==="release")return;if(keys.match("eikon.save",key3)){if(!saving)doSave();return}if(key3.name==="escape")return void discard();if(key3.name==="tab"){let i=PANES.indexOf(pane),next2=PANES[(i+(key3.shift?PANES.length-1:1))%PANES.length];setPane(next2),outer.current?.scrollChildIntoView(`studio-${next2}`);return}if(!s){if(key3.name==="return")return void doNew();return}if(pane==="knobs"){if(handleListKey(keys,key3,{count:navRows.length,setSel:setSelBy,scrollTo:kScroll,page:Math.max(1,(ksb.current?.viewport.height??10)-1),onActivate:activate,onToggle:toggle,onNew:()=>void doNew(),onRefresh:refresh}))return;if(key3.name==="left")return adjust(-1);if(key3.name==="right")return adjust(1);return}if(pane==="preview"){if(keys.match("list.toggle",key3))return setPlay((p)=>!p);if(!spatialOk||!live)return;if(handleListKey(keys,key3,{count:SP_ROWS.length,setSel:setSpSel}))return;let k2=["ox","oy","zoom","fps"][spRef.current],fine=key3.shift&&k2!=="fps",d2=(name)=>name==="left"?-1:1;if(key3.name==="left"||key3.name==="right"){if(fine&&(k2==="ox"||k2==="oy"||k2==="zoom")){let cur=sRef.current.spatial[k2];return setSpatial({[k2]:Math.max(k2==="zoom"?0.1:0,Math.min(1,+(cur+d2(key3.name)*0.01).toFixed(3)))})}return stepBar(k2,d2(key3.name))}return}if(key3.name==="left")return mutate((p)=>exports_eikon_knobs.cycle(p,-1));if(key3.name==="right")return mutate((p)=>exports_eikon_knobs.cycle(p,1));if(key3.name==="return")return doStripMenu()});let onScroll=(e)=>{if(e.stopPropagation(),!spatialOk||!live||!e.scroll)return;let d2=e.scroll.direction;if(d2!=="up"&&d2!=="down")return;let sign=d2==="up"?-1:1;if(e.modifiers.ctrl)return mutate((p)=>({...p,spatial:exports_eikon_knobs.zoom(p.spatial,sign),dirty:!0}));if(e.modifiers.shift)return mutate((p)=>({...p,spatial:exports_eikon_knobs.pan(p.spatial,sign,0),dirty:!0}));mutate((p)=>({...p,spatial:exports_eikon_knobs.pan(p.spatial,0,sign),dirty:!0}))},n=frames.length,title=s?`Preview \u2014 ${s.state}${s.per[s.state]?" (forked)":""}`+(n>1?` \xB7 ${play?"\u25B6":"\u23F8"} ${tick3%n+1}/${n}`:"")+(live?"":baked2?" \xB7 (baked)":""):"Preview",previewErr=err??(!s||src3||baked2?null:url2?"no source \u2014 Enter on 'download source'":"no source \u2014 Enter on 'source'"),hint=!s?[["Enter","new eikon"],["Shift+\u2192","gallery"]]:pane==="knobs"?[["\u2191\u2193","row"],["\u2190\u2192","adjust"],[keys.print("list.activate"),"edit"],[keys.print("list.refresh"),"reload"],[keys.print("list.new"),"new"],["u","submit"],[keys.print("eikon.save"),"save"],["Ctrl+U","save & use"],["Tab","pane"]]:pane==="preview"?[["\u2191\u2193","row"],["\u2190\u2192","adjust"],[keys.print("list.toggle"),"play/pause"],["wheel","pan"],["Ctrl+wheel","zoom"],[keys.print("eikon.save"),"save"],["Ctrl+U","save & use"],["Tab","pane"]]:[["\u2190\u2192","state"],[keys.print("list.activate"),"actions"],[keys.print("eikon.save"),"save"],["Ctrl+U","save & use"],["Tab","pane"]],BAR_H=spatialOk&&live?Math.max(Math.ceil(MINI_W/2),3)+1:0,PREVIEW_W=Math.max(W2+2,38+MINI_W)+6,PREVIEW_H=H+(spatialOk&&live?1:0)+BAR_H+6+(previewErr?1:0),body=$jsxs("box",{position:"relative",flexDirection:"column",width:W2,height:H,flexShrink:0,backgroundColor:theme.background,onMouseScroll:onScroll,onMouseDown:()=>setPlay((p)=>!p),children:[frame.map((ln,i)=>$jsx("text",{fg:err?theme.textMuted:theme.hermAvatar,children:ln},i)),busy&&frames[0]===BLANK3?$jsx("box",{position:"absolute",left:0,top:H>>1,width:W2,justifyContent:"center",children:$jsx(Spinner,{color:theme.textMuted,label:"decoding\u2026"})}):null]}),preview3=$jsxs(TabShell,{title:spatialOk?title:`${title} \xB7 (ffmpeg not installed)`,error:previewErr,focus:pane==="preview",children:[!live&&baked2?$jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:"Baked \u2014 download or attach source to edit."})}):null,spatialOk&&live&&s?$jsxs($Fragment,{children:[$jsx(PanBars,{sp:s.spatial,sel:spSel,focused:pane==="preview",onHover:(i)=>{setPane("preview"),setSpSel(i)},onSet:setBar,onWheel:stepBar,children:body}),$jsx(SpatialBar,{sp:s.spatial,fps:s.fps,dims:s.dims,sel:spSel,focused:pane==="preview",onHover:(i)=>{setPane("preview"),setSpSel(i)},onSet:setBar,onWheel:stepBar})]}):body]}),help=helpOf(navRows[sel]),panel=$jsx(TabShell,{title:s?`Settings \u2014 ${s.name}`:"Settings",focus:pane==="knobs",grow:1,children:!s?$jsx("box",{flexGrow:1,alignItems:"center",justifyContent:"center",children:$jsx("text",{fg:theme.textMuted,children:"No eikon open. Enter to create or pick one."})}):$jsxs($Fragment,{children:[$jsx("scrollbox",{id:"studio-knob-scroll",ref:ksb,scrollY:!0,flexGrow:1,contentOptions:COL,onMouseScroll:(e)=>e.stopPropagation(),children:rows3.map((row3,i)=>{let ni=navRows.findIndex((x2)=>x2.i===i),on=pane==="knobs"&&ni===sel,dim2=row3.kind==="knob"&&!src3;return $jsx(KnobRow,{id:`knob-${row3.kind}-${row3.id}`,row:row3,s,r,status,on,dim:dim2,peek:peek5,busy:row3.id==="fetch"&&fetching,onHover:()=>{if(ni>=0)setPane("knobs"),setSelBy(ni)},onClick:()=>{if(ni>=0)setSelBy(ni),setPane("knobs"),act(row3,"click")},onWheel:(d2)=>stepRow(row3,d2),onSlide:row3.knob?.kind!=="slider"?void 0:row3.kind==="tone"?(v2)=>setTone({contrast:+v2.toFixed(2)}):(v2)=>mutate((p)=>exports_eikon_knobs.edit(p,(k2)=>exports_eikon_knobs.setSlider(k2,row3.id,row3.knob,v2)))},`${row3.kind}:${r.name}:${row3.id}`)})}),$jsx("box",{flexShrink:0,height:HELP_H,marginTop:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:help})})]})}),strip=s?$jsx("box",{id:"studio-strip",flexShrink:0,height:18,children:$jsx(TabShell,{title:"States",focus:pane==="strip",children:$jsx(Strip,{s,frames:thumbs,stats,pending:pending3,focused:pane==="strip",onPick:(st)=>{setPane("strip"),mutate((p)=>exports_eikon_knobs.setState(p,st))},onEmpty:(st)=>doSource(st)})})}):null,top=wide?$jsxs("box",{flexDirection:"row",flexShrink:0,height:PREVIEW_H,children:[$jsx("box",{id:"studio-preview",flexShrink:0,width:PREVIEW_W,children:preview3}),$jsx("box",{id:"studio-knobs",flexGrow:1,flexBasis:0,minWidth:0,children:panel})]}):$jsxs($Fragment,{children:[$jsx("box",{id:"studio-preview",flexShrink:0,height:PREVIEW_H,children:preview3}),$jsx("box",{id:"studio-knobs",flexShrink:0,height:Math.max(rows3.length,1)+HELP_H+1+6,children:panel})]});return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,minHeight:0,children:[$jsxs("scrollbox",{ref:outer,scrollY:!0,flexGrow:1,contentOptions:COL,children:[top,strip]}),$jsx(HintBar,{pairs:hint,suffix:saving?"\u25CF saving\u2026":s?.dirty?"\u25CF unsaved":void 0})]})});var import_react106=__toESM(require_react_production(),1);import{existsSync as existsSync20,readFileSync as readFileSync13}from"fs";import{basename as basename13,dirname as dirname13,join as join17}from"path";var EikonGallery=import_react106.memo((props)=>{let theme=useTheme().theme,dialog=useDialog(),toast=useToast(),keys=useKeys(),rev2=import_react106.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision),rows3=import_react106.useMemo(()=>{let user=hermesPath("eikons"),own=exports_eikon.list(),map=new Map(own.map((x2)=>[x2.name.toLowerCase(),x2])),meta=own.map((x2)=>({inst:x2,ids:ids2(x2.manifest,x2.name,x2.sourceUrl)}));return listEikons([BUNDLED_EIKON_DIR,user]).map((e)=>{let slug3=e.path.startsWith(BUNDLED_EIKON_DIR)?e.meta.name.toLowerCase():basename13(dirname13(e.path)),man=manifest3(dirname13(e.path)),keys2=ids2(man,slug3),mine=meta.find((x2)=>x2.ids.some((k2)=>keys2.includes(k2)))?.inst??map.get(slug3);return{path:e.path,name:e.meta.name,slug:slug3,author:e.meta.author,bundled:e.path.startsWith(BUNDLED_EIKON_DIR),w:e.meta.width,h:e.meta.height,url:mine?.sourceUrl,hasSource:mine?.hasSource??!!exports_eikon.findSource(slug3),lifecycle:mine?.lifecycle,...man?{manifest:man}:{}}}).filter((r)=>!(r.bundled&&r.lifecycle))},[rev2]),active=usePref("eikon"),path7=import_react106.useMemo(()=>active?exports_eikon.baked(active):void 0,[active,rev2]),current2=(row3)=>path7===row3.path,[sel,setSel]=import_react106.useState(0),galleryFollow=useFollow("gal",(i)=>rows3[i]?.slug??i);import_react106.useEffect(()=>{if(sel>=rows3.length)setSel(Math.max(0,rows3.length-1))},[rows3.length,sel]);let cur=rows3[sel],parsed=import_react106.useMemo(()=>{if(!cur)return;try{return parseEikonFile(cur.path)}catch{return}},[cur]),activate=(row3=cur)=>{if(!row3)return;if(row3.bundled)set("eikon",row3.slug);else exports_eikon.useInstalled(row3.slug);toast.show({variant:"success",message:`Avatar \u2192 ${row3.name}`})},doNew=import_react106.useCallback(async()=>{let res=await openNewEikon(dialog,{});if(!res)return;if(res.from==="blank")return exports_eikon.ensure(res.name),props.onEdit?.(res.name);if(res.from==="file"){exports_eikon.ensure(res.name);try{exports_eikon.adopt(res.name,res.file,"base")}catch(e){return toast.error(e instanceof Error?e:Error(String(e)))}return props.onEdit?.(res.name)}toast.show({variant:"info",message:`Installing '${res.name}' from ${res.src}\u2026`}),await exports_eikon.installPackage(res.src,{name:res.name}).then((out)=>{toast.show({variant:"success",message:`Installed '${out.name}' (${out.n} files)`})}).catch((e)=>toast.error(e instanceof Error?e:Error(String(e))))},[dialog,toast,props]),updateLocal=import_react106.useCallback(async()=>{if(!cur||cur.bundled)return;try{let out=await exports_eikon.update(cur.slug);if("type"in out){if(!await openConfirm(dialog,{title:`Update active '${cur.name}'?`,danger:!0,body:`${out.message} The active avatar's backing package will change even though the selected name stays '${cur.slug}'.`,yes:"update active",no:"cancel"}))return;let done=await exports_eikon.update(cur.slug,{confirmActive:!0});if("type"in done)return toast.show({variant:"warning",message:done.message})}toast.show({variant:"success",message:`Updated ${cur.name}`})}catch(e){toast.error(e instanceof Error?e:Error(String(e)))}},[cur,dialog,toast]),submitLocal=import_react106.useCallback(async()=>{if(!cur||cur.bundled)return;let path8=submitPath(cur.slug);if(publishedInfo(path8)){toast.show({variant:"warning",title:"Published eikon",message:"Create a local draft before submitting",duration:6000});return}await openEikonSubmit(dialog,{name:cur.name,path:path8,submit:props.submit??submit2})},[cur,dialog,props.submit,toast]),del=async()=>{if(!cur||cur.bundled)return;let here=current2(cur),body=here?`Removes ${dirname13(cur.path)} and all its sources. This is the active avatar; deleting it will clear the active avatar selection.`:`Removes ${dirname13(cur.path)} and all its sources.`;if(!await openConfirm(dialog,{title:`Delete '${cur.name}'?`,danger:!0,body}))return;let removed=exports_eikon.remove(cur.slug,{confirmActive:here});if(removed)return toast.show({variant:"warning",message:removed.message});toast.show({variant:"info",message:`Deleted ${cur.name}`})};return useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(handleListKey(keys,key3,{count:rows3.length,setSel,page:galleryFollow.opts.page,scrollTo:(n)=>galleryFollow.ref.current?.scrollChildIntoView(galleryFollow.id(n)),onActivate:()=>activate(),onDelete:()=>void del(),onNew:doNew,onRefresh:()=>{exports_eikon.notifyRevision(),toast.show({variant:"info",message:"Reloaded",duration:1000})}}))return;if(key3.name==="u"&&cur&&!cur.bundled)return void updateLocal();if(key3.name==="s"&&cur&&!cur.bundled)return void submitLocal();if(key3.name==="e"&&cur&&props.onEdit)props.onEdit(cur.slug)}),$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx(TabShell,{title:`Gallery (${rows3.length})`,focus:props.focused,grow:3,children:$jsx("scrollbox",{ref:galleryFollow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:rows3.length===0?$jsx("text",{fg:theme.textMuted,children:"No eikons found."}):rows3.map((r,i)=>{let on=i===sel,here=current2(r);return $jsxs("box",{id:galleryFollow.id(i),flexDirection:"row",height:1,backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:()=>setSel(i),onMouseDown:()=>{setSel(i),activate(r)},children:[$jsx("box",{width:2,children:$jsx("text",{fg:on?theme.primary:theme.textMuted,children:on?"\u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsxs("text",{fg:here?theme.accent:theme.text,children:[here?"\u25CF ":" ",$jsx("strong",{children:r.name})]})})]},r.path)})})}),$jsx(TabShell,{title:cur?`Preview \u2014 ${cur.name}`:"Preview",grow:3,children:$jsxs("box",{flexDirection:"column",flexGrow:1,padding:1,children:[$jsx("box",{alignItems:"center",justifyContent:"center",flexGrow:1,children:parsed?$jsx(AnimatedAvatar,{state:"idle",eikon:parsed},cur.path):$jsx("text",{fg:theme.textMuted,children:"No preview."})}),cur?$jsxs("box",{flexDirection:"column",gap:1,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:cur.name})}),$jsxs("text",{fg:theme.textMuted,children:["Author: ",cur.author??"\u2014"]}),$jsxs("text",{fg:theme.textMuted,children:["Status: ",current2(cur)?"active":cur.bundled?"bundled/system":"installed"]}),$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["Source: ",gallerySource(cur)]}),$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["Trust: ",galleryTrust(cur)]}),$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["Package: ",packageId(cur)]}),$jsx("text",{fg:theme.textMuted,children:sourceBadge(cur)})]}):null]})})]}),$jsx(HintBar,{pairs:[[keys.print("list.activate"),"use"],["\u2191\u2193","select"],[keys.print("list.new"),"new / install"],[keys.print("list.refresh"),"reload"],...cur&&props.onEdit?[["e","edit"]]:[],...cur&&!cur.bundled?[["u/s/d","manage"]]:[]]})]})}),galleryTrust=(row3)=>{let t2=row3.lifecycle?.trust;if(t2==="verified")return"Verified";if(t2==="mismatch")return"Mismatch";if(t2==="unverified")return"Unverified";return row3.bundled?"Bundled":"Legacy local"},gallerySource=(row3)=>{let src3=row3.lifecycle?.source;if(src3)return src3.identity??src3.repo??src3.origin??src3.kind;if(row3.bundled)return"bundled/system";return"local"},packageId=(row3)=>typeof row3.manifest?.id==="string"?row3.manifest.id:row3.bundled?"bundled/system":"\u2014",manifest3=(dir2)=>{let file2=join17(dir2,"manifest.json");if(!existsSync20(file2))return;try{let raw2=JSON.parse(readFileSync13(file2,"utf8"));return raw2&&typeof raw2==="object"&&!Array.isArray(raw2)?raw2:void 0}catch{return}},sourceBadge=(row3)=>row3.hasSource?"\u25CF source":row3.url||row3.bundled?"\u25CB source available":"\u2014 no source",key3=(value)=>{try{let url2=new URL(value);if(url2.protocol==="http:"||url2.protocol==="https:"||url2.protocol==="file:")return url2.href.replace(/\/?$/,"/").toLowerCase()}catch{}return value.toLowerCase()},ids2=(man,name,url2)=>{let origin2=man?.origin&&typeof man.origin==="object"&&!Array.isArray(man.origin)?man.origin:void 0;return[...new Set([typeof man?.id==="string"?man.id:void 0,typeof origin2?.sourceKey==="string"?origin2.sourceKey:void 0,typeof origin2?.identityKey==="string"?origin2.identityKey:void 0,typeof origin2?.packageUrl==="string"?origin2.packageUrl:void 0,typeof origin2?.source==="string"?origin2.source:void 0,url2,name].filter((x2)=>!!x2).map(key3))]};var import_react109=__toESM(require_react_production(),1);var import_react108=__toESM(require_react_production(),1);var fmt3=(n)=>n==null?"size unknown":n<1024?`${n} B`:n<1048576?`${(n/1024).toFixed(1)} KiB`:`${(n/1024/1024).toFixed(1)} MiB`,choices=(row3,sizes)=>{if(row3.installState==="incompatible"||row3.installState==="mismatch")return[];if(!row3.installed)return[{label:"Eikon only",hint:fmt3(sizes?.eikon),value:"install"},{label:"Eikon + Source",hint:`${fmt3((sizes?.eikon??0)+(sizes?.source??0))} \xB7 Source files needed to edit Eikon in Studio`,value:"source"}];return[...!row3.active?[{label:"Use",hint:"set as active avatar",value:"use"}]:[],...row3.sourceDownloadable?[{label:"Download Source",hint:"needed to edit in Studio",value:"download"}]:[],...row3.removable?[{label:"Delete",value:"delete"}]:[]]},Action=(props)=>{let theme=useTheme().theme,opts=choices(props.row,props.sizes),[sel,setSel]=import_react108.useState(0),desc=opts.some((o)=>!!o.hint);return $jsxs("box",{flexDirection:"column",width:64,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.row.entry.name})}),$jsx("box",{height:1}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:props.row.entry.description??"No description."}),$jsx("box",{height:1}),opts.length>0?$jsx("select",{focused:!0,width:62,height:Math.min(12,Math.max(1,opts.length*(desc?2:1))),options:opts.map((o)=>({name:o.label,description:o.hint??"",value:o.value})),selectedIndex:Math.min(sel,opts.length-1),showDescription:desc,showScrollIndicator:opts.length>6,backgroundColor:theme.backgroundPanel,focusedBackgroundColor:theme.backgroundPanel,textColor:theme.textMuted,focusedTextColor:theme.text,selectedBackgroundColor:theme.backgroundElement,selectedTextColor:theme.text,descriptionColor:theme.textMuted,selectedDescriptionColor:theme.textMuted,keyBindings:[{name:"home",action:"move-up-fast"},{name:"end",action:"move-down-fast"},{name:"space",action:"select-current"},{name:" ",action:"select-current"},{name:"return",action:"select-current"}],onChange:(i)=>setSel(i),onSelect:(i)=>{let opt=opts[i];if(opt)props.onPick(opt.value)}}):$jsx("text",{fg:theme.textMuted,children:props.row.reason??"No available actions."}),$jsx("box",{height:1}),$jsx("text",{fg:theme.textMuted,children:"[\u2191\u2193] move [Space/Enter] confirm [Esc] cancel"})]})};function openEikonMarketplaceAction(dialog,opts){return new Promise((resolve4)=>{let done=(v2)=>{resolve4(v2),dialog.clear()};dialog.replace($jsx(Action,{...opts,onPick:done}),()=>resolve4(null))})}init_perf();import{existsSync as existsSync21,readFileSync as readFileSync14,readdirSync as readdirSync7,writeFileSync as writeFileSync6}from"fs";import{createHash as createHash4}from"crypto";import{basename as basename14,dirname as dirname14,extname as extname4,join as join18}from"path";var DEFAULT_TIMEOUT=5000,DEFAULT_CACHE_LIMIT=24,dec=new TextDecoder;function hash2(data2){return`sha256:${createHash4("sha256").update(data2).digest("hex")}`}function keyIdentity(s){try{let u3=new URL(s);if(u3.protocol==="http:"||u3.protocol==="https:"||u3.protocol==="file:")return u3.href.replace(/\/?$/,"/")}catch{}return s}function manifestBaseKey(s){try{let u3=new URL(s);if((u3.protocol==="http:"||u3.protocol==="https:"||u3.protocol==="file:")&&u3.pathname.endsWith("/manifest.json"))return new URL(".",u3).href}catch{}return}function registryKey(man,source){if(man?.kind!=="eikon.package"||typeof man.id!=="string")return;let sourceKey=man.origin?.sourceKey??man.origin?.identityKey;if(sourceKey)return keyIdentity(sourceKey);try{let host=source?new URL(source).host:void 0;if(!host)return;return`registry:${host}:${man.id}${typeof man.version==="string"&&man.version?`@${man.version}`:""}`}catch{return}}function entryKeys(entry2){return[...new Set([entry2.identityKey,entry2.sourceKey].filter(Boolean).map(keyIdentity))]}function keysFor(inst){let keys=new Set,man=inst.manifest,origin2=typeof man?.origin?.source==="string"?man.origin.source:void 0,head=exports_eikon.header(inst.file),src3=typeof head?.source_url==="string"?head.source_url:inst.sourceUrl,registry2=registryKey(man,origin2);if(registry2)keys.add(registry2);if(origin2){keys.add(keyIdentity(origin2));let base2=manifestBaseKey(origin2);if(base2)keys.add(keyIdentity(base2))}if(src3){keys.add(keyIdentity(src3));let base2=manifestBaseKey(src3);if(base2)keys.add(keyIdentity(base2))}return[...keys]}function read(path7){try{let man=JSON.parse(readFileSync14(path7,"utf8"));return obj(man)?man:void 0}catch{return}}function chosen(active,name){return active===name||active==="default"&&name==="nous"}function media(dir2){return existsSync21(dir2)&&readdirSync7(dir2).length>0}function text3(value){return typeof value==="string"&&value?value:void 0}function life(name,man){let origin2=obj(man.origin)?man.origin:{},display2=obj(man.display)?man.display:{},src3=text3(origin2.source),identity2=text3(origin2.identityKey)??text3(origin2.sourceKey)??text3(origin2.packageUrl)??text3(origin2.repo)??src3,title=text3(display2.title)??text3(man.title),author=text3(display2.author)??text3(man.author);return{name,...title?{title}:{},...author?{author}:{},...text3(man.version)?{version:text3(man.version)}:{},source:{kind:text3(origin2.kind)??"default-catalog",...identity2?{identity:identity2}:{},...src3?{origin:src3}:{},...text3(origin2.repo)?{repo:text3(origin2.repo)}:{},...text3(origin2.selector)?{selector:text3(origin2.selector)}:{},...text3(origin2.catalogRoot)?{catalogRoot:text3(origin2.catalogRoot)}:{},...text3(origin2.sha)?{sha:text3(origin2.sha)}:{},...text3(origin2.packageUrl)?{packageUrl:text3(origin2.packageUrl)}:{}},trust:text3(origin2.trust)??"verified",active:chosen(get2("eikon"),name),removable:!1,updateable:Boolean(src3??text3(origin2.packageUrl)),updateAvailable:!1,dirty:!1,...text3(man.poster)?{poster:text3(man.poster)}:{},...obj(man.compatibility)?{compatibility:man.compatibility}:{},...text3(origin2.at)?{installedAt:text3(origin2.at)}:{}}}function bundled(xs){let names=new Set(xs.map((x2)=>x2.name.toLowerCase()));return listEikons([BUNDLED_EIKON_DIR]).flatMap((e)=>{let man=read(join18(dirname14(e.path),"manifest.json"));if(man?.kind!=="eikon.package")return[];let name=text3(man.name)??e.meta.name.toLowerCase();if(names.has(name.toLowerCase()))return[];let inst={name,file:e.path,source:exports_eikon.sourceDir(name),hasSource:media(exports_eikon.sourceDir(name)),sourceUrl:text3(man.origin?.source)??text3(man.origin?.packageUrl),manifest:man,lifecycle:life(name,man)};return[{...inst,manifest:man,identityKeys:keysFor(inst)}]})}function cacheKey(entry2){return[entry2.identityKey||entry2.sourceKey||entry2.id,entry2.runtimeUrl,entry2.trust?.runtimeDigest,entry2.trust?.runtimeSize].filter(Boolean).join("|")}function blob(url2){return/\/blobs\/sha256\/[^/?#]+/.test(url2)}function artifact(entry2){return entry2}function obj(value){return!!value&&typeof value==="object"&&!Array.isArray(value)}function rawManifest(entry2){let raw2=entry2.raw;return obj(raw2.manifest)?raw2.manifest:void 0}function role(file2){if(file2.role==="source.base")return"base";if(file2.role?.startsWith("source."))return file2.role.slice(7);if(!file2.path)return;return basename14(file2.path,extname4(file2.path)).toLowerCase()||"base"}function sourceEntries2(man,strict=!1){if(!man)return[];try{let xs=entries(man).map(([r,rel2])=>[r,rel2]);if(xs.length)return xs;return(man.files??[]).flatMap((file2)=>{if(typeof file2.path!=="string"||!file2.role?.startsWith("source"))return[];let r=role(file2);return r?[[r,file2.path]]:[]})}catch(err){if(strict)throw err;return[]}}function sourceDescriptors2(man){return sourceEntries2(man).length>0}function sourceAvailable2(entry2,inst){return sourceDescriptors2(inst?.manifest)||sourceDescriptors2(rawManifest(entry2))}function trust(entry2){return entry2.trust}function boundTrust(entry2,raw2){let t2=trust(entry2),man=t2.manifestDigest,run=t2.runtimeDigest;if(!man&&!run)return"unverified";if(man&&hash2(raw2)!==man)throw Error(`catalog trust mismatch: manifest digest for ${entry2.name}`);let pkg=JSON.parse(dec.decode(raw2)),rel2=pkg.entrypoints?.default,got=rel2?pkg.files?.find((f)=>f.path===rel2)?.digest:void 0;if(run&&got!==run)throw Error(`catalog trust mismatch: runtime digest for ${entry2.name}`);return man&&run?"verified":"unverified"}function spec2(man,rel2){return man.files?.find((f)=>f.path===rel2)}async function sourceBytes(man,base2,rel2,opts){let file2=spec2(man,rel2);if(!file2?.digest||typeof file2.size!=="number")throw Error(`source descriptor missing digest or size: ${rel2}`);let raw2=await downloadBytes(new URL(rel2,base2).href,opts);if(raw2.length!==file2.size)throw Error(`source size mismatch: ${rel2}`);if(hash2(raw2)!==file2.digest)throw Error(`source digest mismatch: ${rel2}`);return raw2}function target(input){return typeof input==="string"?input:input instanceof URL?input.href:input.url}function verifiedCatalogTrust(entry2){let t2=trust(entry2);return typeof t2.manifestDigest==="string"&&t2.manifestDigest.length>0&&typeof t2.runtimeDigest==="string"&&t2.runtimeDigest.length>0}function installed(){let xs=exports_eikon.list().map((inst)=>({...inst,manifest:inst.manifest,identityKeys:keysFor(inst)}));return[...xs,...bundled(xs)]}function match2(entry2,xs){let keys=entryKeys(entry2),exact=xs.find((x2)=>x2.identityKeys.some((k2)=>keys.includes(k2)));if(exact)return{inst:exact,legacy:!1};let named=xs.find((x2)=>x2.name===entry2.name&&x2.identityKeys.length===0);if(named)return{inst:named,legacy:!0};return}function row3(entry2,xs){let usable=match2(entry2,xs),active=usable?chosen(get2("eikon"),usable.inst.name):!1,installed2=Boolean(usable),conflict=!usable&&chosen(get2("eikon"),entry2.name),blocked=entry2.compatibility?.available===!1,mismatch=usable?.inst.lifecycle.trust==="mismatch",installState=mismatch?"mismatch":blocked?"incompatible":active?"active":conflict?"active-name-conflict":!usable?"available":usable.legacy?"legacy-name-match":"installed",lifecycle2=usable?.inst.lifecycle??{name:entry2.name,title:entry2.title,author:entry2.author,version:entry2.version,source:{kind:"default-catalog",identity:entry2.sourceKey,packageUrl:entry2.packageUrl},trust:verifiedCatalogTrust(entry2)?"verified":"unverified",active:!1,removable:!1,updateable:!1,updateAvailable:!1,dirty:!1,...entry2.poster?{poster:entry2.poster}:{},compatibility:entry2.compatibility},available=sourceAvailable2(entry2,usable?.inst);return{entry:entry2,installed:installed2,active,installState,...usable?.inst.file?{installedPath:usable.inst.file,installedName:usable.inst.name}:{},...usable?.inst.manifest?{installedManifest:usable.inst.manifest}:{},lifecycle:lifecycle2,trust:lifecycle2.trust,updateable:lifecycle2.updateable,updateAvailable:lifecycle2.updateAvailable,removable:lifecycle2.removable,sourceIdentity:lifecycle2.source.identity,sourcePresent:usable?.inst.hasSource??!1,sourceAvailable:available,sourceDownloadable:Boolean(usable&&!usable.inst.hasSource&&available),reason:blocked?entry2.compatibility?.reason??"incompatible":mismatch?"trust mismatch":conflict?"install would replace the active avatar backing package":void 0,action:active?"active":installed2?"use":"install"}}function sizes(man){let files=Array.isArray(man.files)?man.files:[],eikon=files.filter((f)=>f.role==="runtime"||f.path===man.entrypoints?.default).map((f)=>f.size).filter((n)=>typeof n==="number").reduce((sum,n)=>sum+n,0),source=files.filter((f)=>typeof f.role==="string"&&f.role.startsWith("source")).map((f)=>f.size).filter((n)=>typeof n==="number").reduce((sum,n)=>sum+n,0);return{...eikon>0?{eikon}:{},...source>0?{source}:{}}}function abortErr(){return new DOMException("aborted","AbortError")}class MarketplaceService{catalog;fetcher;timeoutMs;previewCacheLimit;concurrency;allowPrivate;activeLoads=0;queue=[];cache=new Map;inFlight=new Map;constructor(catalog2,opts={}){this.catalog=catalog2,this.fetcher=opts.fetcher??fetch,this.timeoutMs=opts.timeoutMs??DEFAULT_TIMEOUT,this.previewCacheLimit=opts.previewCacheLimit??DEFAULT_CACHE_LIMIT,this.concurrency=Math.max(1,Math.floor(opts.concurrency??4)),this.allowPrivate=opts.allowPrivate===!0}rows(query=""){let entries2=searchCatalog(this.catalog.entries,query),xs=installed();return entries2.map((e)=>row3(e,xs))}entry(id){let key4=keyIdentity(id);return this.catalog.entries.find((e)=>keyIdentity(e.identityKey)===key4||keyIdentity(e.sourceKey)===key4||e.id===id||e.name===id)}dl(signal,fetcher=this.fetcher){return{allowPrivate:this.allowPrivate,fetcher:(input,init)=>fetcher(input,signal?{...init,signal}:init)}}runtime(entry2,signal){return async(input)=>{let url2=target(input),bound=keyIdentity(url2)===keyIdentity(entry2.runtimeUrl)&&(!!entry2.trust?.runtimeDigest||blob(url2)),raw2=await downloadBytes(url2,{...this.dl(signal),rejectContentEncoding:bound}),buf=raw2.buffer.slice(raw2.byteOffset,raw2.byteOffset+raw2.byteLength);return new Response(buf,{headers:{"content-length":String(raw2.length)}})}}cached(url2,raw2){let key4=keyIdentity(url2);return async(input,init)=>{if(keyIdentity(target(input))===key4)return new Response(raw2.slice(),{headers:{"content-length":String(raw2.length)}});return this.fetcher(input,init)}}async preview(id,opts={}){if(opts.signal?.aborted)throw abortErr();let entry2=this.entry(id);if(!entry2)throw Error(`marketplace: unknown eikon "${id}"`);let key4=cacheKey(entry2),hit2=this.cache.get(key4);if(hit2!==void 0)return hit2;let active=this.inFlight.get(key4);if(active)return active;let p=this.enqueue(()=>this.loadPreview(entry2,opts)).finally(()=>this.inFlight.delete(key4));return this.inFlight.set(key4,p),p}async packageSizes(id){let entry2=this.entry(id);if(!entry2)throw Error(`marketplace: unknown eikon "${id}"`);return sizes(JSON.parse(dec.decode(await downloadBytes(entry2.packageUrl,this.dl()))))}async install(id,opts={}){let entry2=this.entry(id);if(!entry2)throw Error(`marketplace: unknown eikon "${id}"`);if(entry2.compatibility?.available===!1)throw Error(entry2.compatibility.reason??"eikon is incompatible");if(!match2(entry2,installed())&&chosen(get2("eikon"),entry2.name)&&!opts.confirmActive)throw Error(`Installing '${entry2.name}' will replace the active avatar's backing package. Pass confirmActive to install it.`);let raw2=await downloadBytes(entry2.packageUrl,this.dl()),state2=boundTrust(entry2,raw2),out=await exports_eikon.fetchSource(entry2.packageUrl,{name:entry2.name,media:opts.media===!0,downloader:this.dl(void 0,this.cached(entry2.packageUrl,raw2))}),ef=exports_eikon.file(out.name);if(!existsSync21(ef)){let art=await loadRuntimeArtifact(entry2,this.runtime(entry2),{allowPrivate:this.allowPrivate});await Bun.write(ef,art.bytes),exports_eikon.notifyRevision()}let mf=join18(exports_eikon.dir(out.name),"manifest.json"),man=JSON.parse(readFileSync14(mf,"utf8")),origin2=man.origin&&typeof man.origin==="object"&&!Array.isArray(man.origin)?man.origin:{};return writeFileSync6(mf,JSON.stringify({...man,origin:{...origin2,sourceKey:entry2.sourceKey,identityKey:entry2.identityKey,packageUrl:entry2.packageUrl,trust:state2}},null,2)+`
4161
+ `),yes:"install",no:"cancel"}))return;toast.show({variant:"info",message:`Installing from ${src4}\u2026`}),await exports_eikon.installPackage(src4).then((out)=>{toast.show({variant:"success",message:`Installed '${out.name}' (${out.n} files)`}),switchTo(out.name)}).catch((e)=>toast.error(e instanceof Error?e:Error(String(e))))},[dialog,switchTo,toast]),doOpen=import_react104.useCallback(()=>{let cur=sRef.current,opts=[...eikonOptions(),{title:"+ New\u2026",value:"__new",category:""},{title:"+ Install\u2026",value:"__install",category:""}];dialog.replace($jsx(DialogSelect,{title:"Open eikon",current:cur?.name,options:opts,onSelect:(o)=>{if(dialog.clear(),o.value==="__new")return void doNew();if(o.value==="__install")return void doInstall();switchTo(o.value)}}),()=>{})},[dialog,eikonOptions,switchTo,doNew,doInstall]),doSubmit=import_react104.useCallback(async()=>{let cur=sRef.current;if(!cur)return;let path7=submitPath(cur.name);if(publishedInfo(path7)){toast.show({variant:"warning",title:"Published eikon",message:"Create a local draft before submitting",duration:6000});return}await openEikonSubmit(dialog,{name:cur.name,path:path7,submit:submit2})},[dialog,toast]),doAction=async(id)=>{if(!s)return;if(id==="knobsfor")return mutate((p)=>p.per[p.state]?exports_eikon_knobs.unfork(p):exports_eikon_knobs.fork(p));if(id==="submit"){doSubmit();return}if(id==="revert"){discard();return}if(id==="reset"){if(await openConfirm(dialog,{title:"Reset settings?",body:"Restore rasterizer defaults and drop all per-state overrides.",danger:!0}))mutate((p)=>exports_eikon_knobs.reset(p,r));return}if(id==="fetch"){if(!status?.downloadable||fetching)return;await download()}},doStripMenu=()=>{if(!s)return;dialog.replace($jsx(DialogSelect,{title:`State: ${s.state}`,filterable:!1,options:[{title:"Source\u2026",value:"source"},{title:s.per[s.state]?"Clear override (back to base)":"Tune this state only",value:"fork"}],onSelect:(o)=>{if(o.value==="source"){doSource();return}dialog.clear(),mutate(s.per[s.state]?exports_eikon_knobs.unfork:exports_eikon_knobs.fork)}}),()=>{})},setTone=(t2)=>mutate((p)=>({...p,tone:{...p.tone,...t2},dirty:!0})),stepRow=(row3,d2)=>{if(row3.kind==="tone"){if(row3.id==="contrast"){let def2=row3.knob,cur=sRef.current?.tone.contrast??1;return setTone({contrast:+Math.max(def2.min,Math.min(def2.max,cur+d2*def2.step)).toFixed(2)})}if(row3.id==="invert")return setTone({invert:!sRef.current?.tone.invert});if(row3.id==="flip"){let cur=sRef.current?.tone.flip??"none",i=FLIPS.indexOf(cur);return setTone({flip:FLIPS[(i+d2+FLIPS.length)%FLIPS.length]})}return}if(row3.kind!=="knob"||!row3.knob)return;mutate((p)=>exports_eikon_knobs.edit(p,(k2)=>exports_eikon_knobs.step(k2,row3.id,row3.knob,d2)))},act=(row3,via)=>{if(!row3||!sRef.current)return;if(row3.kind==="select"){if(row3.id==="open")return doOpen();return doSelectRasterizer()}if(row3.kind==="prompt")return void doPrompt(row3.id);if(row3.kind==="action"){if(via==="space"&&row3.id==="reset")return;return void doAction(row3.id)}if(row3.kind==="tone"||row3.kind==="knob"){if(row3.knob.kind==="slider")return;return stepRow(row3,1)}},activate=()=>act(navRows[selRef.current],"enter"),toggle=()=>act(navRows[selRef.current],"space"),adjust=(d2)=>{let row3=navRows[selRef.current];if(!row3)return;if(row3.id==="knobsfor")return void doAction("knobsfor");stepRow(row3,d2)},discard=async()=>{let cur=sRef.current;if(!cur?.dirty)return!1;let pick2=await openSaveDiscard(dialog,{title:"Unsaved edits",body:`'${cur.name}' has unsaved changes. Save them, discard them, or keep editing?`});if(pick2==="save"){if(await doSave())open2(cur.name);return!0}if(pick2==="discard")open2(cur.name);return!0},refresh=import_react104.useCallback(()=>{let cur=sRef.current;if(!cur)return;if(stampRef.current=exports_eikon.sourceStamp(cur.name),cur.dirty){toast.show({variant:"info",message:"Reload skipped: unsaved edits",duration:3000});return}open2(cur.name),toast.show({variant:"info",message:"Reloaded",duration:1000})},[open2,toast]);useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(key3.name==="u"&&key3.ctrl&&sRef.current)return void doSaveUse();if(key3.name==="u"&&sRef.current)return void doSubmit();if(key3.eventType==="release")return;if(keys.match("eikon.save",key3)){if(!saving)doSave();return}if(key3.name==="escape")return void discard();if(key3.name==="tab"){let i=PANES.indexOf(pane),next2=PANES[(i+(key3.shift?PANES.length-1:1))%PANES.length];setPane(next2),outer.current?.scrollChildIntoView(`studio-${next2}`);return}if(!s){if(key3.name==="return")return void doNew();return}if(pane==="knobs"){if(handleListKey(keys,key3,{count:navRows.length,setSel:setSelBy,scrollTo:kScroll,page:Math.max(1,(ksb.current?.viewport.height??10)-1),onActivate:activate,onToggle:toggle,onNew:()=>void doNew(),onRefresh:refresh}))return;if(key3.name==="left")return adjust(-1);if(key3.name==="right")return adjust(1);return}if(pane==="preview"){if(keys.match("list.toggle",key3))return setPlay((p)=>!p);if(!spatialOk||!live)return;if(handleListKey(keys,key3,{count:SP_ROWS.length,setSel:setSpSel}))return;let k2=["ox","oy","zoom","fps"][spRef.current],fine=key3.shift&&k2!=="fps",d2=(name)=>name==="left"?-1:1;if(key3.name==="left"||key3.name==="right"){if(fine&&(k2==="ox"||k2==="oy"||k2==="zoom")){let cur=sRef.current.spatial[k2];return setSpatial({[k2]:Math.max(k2==="zoom"?0.1:0,Math.min(1,+(cur+d2(key3.name)*0.01).toFixed(3)))})}return stepBar(k2,d2(key3.name))}return}if(key3.name==="left")return mutate((p)=>exports_eikon_knobs.cycle(p,-1));if(key3.name==="right")return mutate((p)=>exports_eikon_knobs.cycle(p,1));if(key3.name==="return")return doStripMenu()});let onScroll=(e)=>{if(e.stopPropagation(),!spatialOk||!live||!e.scroll)return;let d2=e.scroll.direction;if(d2!=="up"&&d2!=="down")return;let sign=d2==="up"?-1:1;if(e.modifiers.ctrl)return mutate((p)=>({...p,spatial:exports_eikon_knobs.zoom(p.spatial,sign),dirty:!0}));if(e.modifiers.shift)return mutate((p)=>({...p,spatial:exports_eikon_knobs.pan(p.spatial,sign,0),dirty:!0}));mutate((p)=>({...p,spatial:exports_eikon_knobs.pan(p.spatial,0,sign),dirty:!0}))},n=frames.length,title=s?`Preview \u2014 ${s.state}${s.per[s.state]?" (forked)":""}`+(n>1?` \xB7 ${play?"\u25B6":"\u23F8"} ${tick3%n+1}/${n}`:"")+(live?"":baked2?" \xB7 (baked)":""):"Preview",previewErr=err??(!s||src3||baked2?null:url2?"no source \u2014 Enter on 'download source'":"no source \u2014 Enter on 'source'"),hint=!s?[["Enter","new eikon"],["Shift+\u2192","gallery"]]:pane==="knobs"?[["\u2191\u2193","row"],["\u2190\u2192","adjust"],[keys.print("list.activate"),"edit"],[keys.print("list.refresh"),"reload"],[keys.print("list.new"),"new"],["u","submit"],[keys.print("eikon.save"),"save"],["Ctrl+U","save & use"],["Tab","pane"]]:pane==="preview"?[["\u2191\u2193","row"],["\u2190\u2192","adjust"],[keys.print("list.toggle"),"play/pause"],["wheel","pan"],["Ctrl+wheel","zoom"],[keys.print("eikon.save"),"save"],["Ctrl+U","save & use"],["Tab","pane"]]:[["\u2190\u2192","state"],[keys.print("list.activate"),"actions"],[keys.print("eikon.save"),"save"],["Ctrl+U","save & use"],["Tab","pane"]],BAR_H=spatialOk&&live?Math.max(Math.ceil(MINI_W/2),3)+1:0,PREVIEW_W=Math.max(W2+2,38+MINI_W)+6,PREVIEW_H=H+(spatialOk&&live?1:0)+BAR_H+6+(previewErr?1:0),body=$jsxs("box",{position:"relative",flexDirection:"column",width:W2,height:H,flexShrink:0,backgroundColor:theme.background,onMouseScroll:onScroll,onMouseDown:()=>setPlay((p)=>!p),children:[frame.map((ln,i)=>$jsx("text",{fg:err?theme.textMuted:theme.hermAvatar,children:ln},i)),busy&&frames[0]===BLANK3?$jsx("box",{position:"absolute",left:0,top:H>>1,width:W2,justifyContent:"center",children:$jsx(Spinner,{color:theme.textMuted,label:"decoding\u2026"})}):null]}),preview3=$jsxs(TabShell,{title:spatialOk?title:`${title} \xB7 (ffmpeg not installed)`,error:previewErr,focus:pane==="preview",children:[!live&&baked2?$jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:"Baked \u2014 download or attach source to edit."})}):null,spatialOk&&live&&s?$jsxs($Fragment,{children:[$jsx(PanBars,{sp:s.spatial,sel:spSel,focused:pane==="preview",onHover:(i)=>{setPane("preview"),setSpSel(i)},onSet:setBar,onWheel:stepBar,children:body}),$jsx(SpatialBar,{sp:s.spatial,fps:s.fps,dims:s.dims,sel:spSel,focused:pane==="preview",onHover:(i)=>{setPane("preview"),setSpSel(i)},onSet:setBar,onWheel:stepBar})]}):body]}),help=helpOf(navRows[sel]),panel=$jsx(TabShell,{title:s?`Settings \u2014 ${s.name}`:"Settings",focus:pane==="knobs",grow:1,children:!s?$jsx("box",{flexGrow:1,alignItems:"center",justifyContent:"center",children:$jsx("text",{fg:theme.textMuted,children:"No eikon open. Enter to create or pick one."})}):$jsxs($Fragment,{children:[$jsx("scrollbox",{id:"studio-knob-scroll",ref:ksb,scrollY:!0,flexGrow:1,contentOptions:COL,onMouseScroll:(e)=>e.stopPropagation(),children:rows3.map((row3,i)=>{let ni=navRows.findIndex((x2)=>x2.i===i),on=pane==="knobs"&&ni===sel,dim2=row3.kind==="knob"&&!src3;return $jsx(KnobRow,{id:`knob-${row3.kind}-${row3.id}`,row:row3,s,r,status,on,dim:dim2,peek:peek5,busy:row3.id==="fetch"&&fetching,onHover:()=>{if(ni>=0)setPane("knobs"),setSelBy(ni)},onClick:()=>{if(ni>=0)setSelBy(ni),setPane("knobs"),act(row3,"click")},onWheel:(d2)=>stepRow(row3,d2),onSlide:row3.knob?.kind!=="slider"?void 0:row3.kind==="tone"?(v2)=>setTone({contrast:+v2.toFixed(2)}):(v2)=>mutate((p)=>exports_eikon_knobs.edit(p,(k2)=>exports_eikon_knobs.setSlider(k2,row3.id,row3.knob,v2)))},`${row3.kind}:${r.name}:${row3.id}`)})}),$jsx("box",{flexShrink:0,height:HELP_H,marginTop:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:help})})]})}),strip=s?$jsx("box",{id:"studio-strip",flexShrink:0,height:18,children:$jsx(TabShell,{title:"States",focus:pane==="strip",children:$jsx(Strip,{s,frames:thumbs,stats,pending:pending3,focused:pane==="strip",onPick:(st)=>{setPane("strip"),mutate((p)=>exports_eikon_knobs.setState(p,st))},onEmpty:(st)=>doSource(st)})})}):null,top=wide?$jsxs("box",{flexDirection:"row",flexShrink:0,height:PREVIEW_H,children:[$jsx("box",{id:"studio-preview",flexShrink:0,width:PREVIEW_W,children:preview3}),$jsx("box",{id:"studio-knobs",flexGrow:1,flexBasis:0,minWidth:0,children:panel})]}):$jsxs($Fragment,{children:[$jsx("box",{id:"studio-preview",flexShrink:0,height:PREVIEW_H,children:preview3}),$jsx("box",{id:"studio-knobs",flexShrink:0,height:Math.max(rows3.length,1)+HELP_H+1+6,children:panel})]});return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,minHeight:0,children:[$jsxs("scrollbox",{ref:outer,scrollY:!0,flexGrow:1,contentOptions:COL,children:[top,strip]}),$jsx(HintBar,{pairs:hint,suffix:saving?"\u25CF saving\u2026":s?.dirty?"\u25CF unsaved":void 0})]})});var import_react106=__toESM(require_react_production(),1);import{existsSync as existsSync20,readFileSync as readFileSync13}from"fs";import{basename as basename13,dirname as dirname13,join as join17}from"path";var EikonGallery=import_react106.memo((props)=>{let theme=useTheme().theme,dialog=useDialog(),toast=useToast(),keys=useKeys(),rev2=import_react106.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision),rows3=import_react106.useMemo(()=>{let user=hermesPath("eikons"),own=exports_eikon.list(),map=new Map(own.map((x2)=>[x2.name.toLowerCase(),x2])),meta=own.map((x2)=>({inst:x2,ids:ids2(x2.manifest,x2.name,x2.sourceUrl)}));return listEikons([BUNDLED_EIKON_DIR,user]).map((e)=>{let slug3=e.path.startsWith(BUNDLED_EIKON_DIR)?e.meta.name.toLowerCase():basename13(dirname13(e.path)),man=manifest3(dirname13(e.path)),keys2=ids2(man,slug3),mine=meta.find((x2)=>x2.ids.some((k2)=>keys2.includes(k2)))?.inst??map.get(slug3);return{path:e.path,name:e.meta.name,slug:slug3,author:e.meta.author,bundled:e.path.startsWith(BUNDLED_EIKON_DIR),w:e.meta.width,h:e.meta.height,url:mine?.sourceUrl,hasSource:mine?.hasSource??!!exports_eikon.findSource(slug3),lifecycle:mine?.lifecycle,...man?{manifest:man}:{}}}).filter((r)=>!(r.bundled&&r.lifecycle))},[rev2]),active=usePref("eikon"),path7=import_react106.useMemo(()=>active?exports_eikon.baked(active):void 0,[active,rev2]),current2=(row3)=>path7===row3.path,[sel,setSel]=import_react106.useState(0),galleryFollow=useFollow("gal",(i)=>rows3[i]?.slug??i);import_react106.useEffect(()=>{if(sel>=rows3.length)setSel(Math.max(0,rows3.length-1))},[rows3.length,sel]);let cur=rows3[sel],parsed=import_react106.useMemo(()=>{if(!cur)return;try{return parseEikonFile(cur.path)}catch{return}},[cur]),activate=(row3=cur)=>{if(!row3)return;if(row3.bundled)set("eikon",row3.slug);else exports_eikon.useInstalled(row3.slug);toast.show({variant:"success",message:`Avatar \u2192 ${row3.name}`})},doNew=import_react106.useCallback(async()=>{let res=await openNewEikon(dialog,{});if(!res)return;if(res.from==="blank")return exports_eikon.ensure(res.name),props.onEdit?.(res.name);if(res.from==="file"){exports_eikon.ensure(res.name);try{exports_eikon.adopt(res.name,res.file,"base")}catch(e){return toast.error(e instanceof Error?e:Error(String(e)))}return props.onEdit?.(res.name)}toast.show({variant:"info",message:`Installing '${res.name}' from ${res.src}\u2026`}),await exports_eikon.installPackage(res.src,{name:res.name}).then((out)=>{toast.show({variant:"success",message:`Installed '${out.name}' (${out.n} files)`})}).catch((e)=>toast.error(e instanceof Error?e:Error(String(e))))},[dialog,toast,props]),updateLocal=import_react106.useCallback(async()=>{if(!cur||cur.bundled)return;try{let out=await exports_eikon.update(cur.slug);if("type"in out){if(!await openConfirm(dialog,{title:`Update active '${cur.name}'?`,danger:!0,body:`${out.message} The active avatar's backing package will change even though the selected name stays '${cur.slug}'.`,yes:"update active",no:"cancel"}))return;let done=await exports_eikon.update(cur.slug,{confirmActive:!0});if("type"in done)return toast.show({variant:"warning",message:done.message})}toast.show({variant:"success",message:`Updated ${cur.name}`})}catch(e){toast.error(e instanceof Error?e:Error(String(e)))}},[cur,dialog,toast]),submitLocal=import_react106.useCallback(async()=>{if(!cur||cur.bundled)return;let path8=submitPath(cur.slug);if(publishedInfo(path8)){toast.show({variant:"warning",title:"Published eikon",message:"Create a local draft before submitting",duration:6000});return}await openEikonSubmit(dialog,{name:cur.name,path:path8,submit:props.submit??submit2})},[cur,dialog,props.submit,toast]),del=async()=>{if(!cur||cur.bundled)return;let here=current2(cur),body=here?`Removes ${dirname13(cur.path)} and all its sources. This is the active avatar; deleting it will clear the active avatar selection.`:`Removes ${dirname13(cur.path)} and all its sources.`;if(!await openConfirm(dialog,{title:`Delete '${cur.name}'?`,danger:!0,body}))return;let removed=exports_eikon.remove(cur.slug,{confirmActive:here});if(removed)return toast.show({variant:"warning",message:removed.message});toast.show({variant:"info",message:`Deleted ${cur.name}`})};return useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(handleListKey(keys,key3,{count:rows3.length,setSel,page:galleryFollow.opts.page,scrollTo:(n)=>galleryFollow.ref.current?.scrollChildIntoView(galleryFollow.id(n)),onActivate:()=>activate(),onDelete:()=>void del(),onNew:doNew,onRefresh:()=>{exports_eikon.notifyRevision(),toast.show({variant:"info",message:"Reloaded",duration:1000})}}))return;if(key3.name==="u"&&cur&&!cur.bundled)return void updateLocal();if(key3.name==="s"&&cur&&!cur.bundled)return void submitLocal();if(key3.name==="e"&&cur&&props.onEdit)props.onEdit(cur.slug)}),$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx(TabShell,{title:`Gallery (${rows3.length})`,focus:props.focused,grow:3,children:$jsx("scrollbox",{ref:galleryFollow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:rows3.length===0?$jsx("text",{fg:theme.textMuted,children:"No eikons found."}):rows3.map((r,i)=>{let on=i===sel,here=current2(r);return $jsxs("box",{id:galleryFollow.id(i),flexDirection:"row",height:1,backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:()=>setSel(i),onMouseDown:()=>{setSel(i),activate(r)},children:[$jsx("box",{width:2,children:$jsx("text",{fg:on?theme.primary:theme.textMuted,children:on?"\u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsxs("text",{fg:here?theme.accent:theme.text,children:[here?"\u25CF ":" ",$jsx("strong",{children:r.name})]})})]},r.path)})})}),$jsx(TabShell,{title:cur?`Preview \u2014 ${cur.name}`:"Preview",grow:3,children:$jsxs("box",{flexDirection:"column",flexGrow:1,padding:1,children:[$jsx("box",{alignItems:"center",justifyContent:"center",flexGrow:1,children:parsed?$jsx(AnimatedAvatar,{state:"idle",eikon:parsed},cur.path):$jsx("text",{fg:theme.textMuted,children:"No preview."})}),cur?$jsxs("box",{flexDirection:"column",gap:1,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:cur.name})}),$jsxs("text",{fg:theme.textMuted,children:["Author: ",cur.author??"\u2014"]}),$jsxs("text",{fg:theme.textMuted,children:["Status: ",current2(cur)?"active":cur.bundled?"bundled/system":"installed"]}),$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["Source: ",gallerySource(cur)]}),$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["Trust: ",galleryTrust(cur)]}),$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["Package: ",packageId(cur)]}),$jsx("text",{fg:theme.textMuted,children:sourceBadge(cur)})]}):null]})})]}),$jsx(HintBar,{pairs:[[keys.print("list.activate"),"use"],["\u2191\u2193","select"],[keys.print("list.new"),"new / install"],[keys.print("list.refresh"),"reload"],...cur&&props.onEdit?[["e","edit"]]:[],...cur&&!cur.bundled?[["u/s/d","manage"]]:[]]})]})}),galleryTrust=(row3)=>{let t2=row3.lifecycle?.trust;if(t2==="verified")return"Verified";if(t2==="mismatch")return"Mismatch";if(t2==="unverified")return"Unverified";return row3.bundled?"Bundled":"Legacy local"},gallerySource=(row3)=>{let src3=row3.lifecycle?.source;if(src3)return src3.identity??src3.repo??src3.origin??src3.kind;if(row3.bundled)return"bundled/system";return"local"},packageId=(row3)=>typeof row3.manifest?.id==="string"?row3.manifest.id:row3.bundled?"bundled/system":"\u2014",manifest3=(dir2)=>{let file2=join17(dir2,"manifest.json");if(!existsSync20(file2))return;try{let raw2=JSON.parse(readFileSync13(file2,"utf8"));return raw2&&typeof raw2==="object"&&!Array.isArray(raw2)?raw2:void 0}catch{return}},sourceBadge=(row3)=>row3.hasSource?"\u25CF source":row3.url||row3.bundled?"\u25CB source available":"\u2014 no source",key3=(value)=>{try{let url2=new URL(value);if(url2.protocol==="http:"||url2.protocol==="https:"||url2.protocol==="file:")return url2.href.replace(/\/?$/,"/").toLowerCase()}catch{}return value.toLowerCase()},ids2=(man,name,url2)=>{let origin2=man?.origin&&typeof man.origin==="object"&&!Array.isArray(man.origin)?man.origin:void 0;return[...new Set([typeof man?.id==="string"?man.id:void 0,typeof origin2?.sourceKey==="string"?origin2.sourceKey:void 0,typeof origin2?.identityKey==="string"?origin2.identityKey:void 0,typeof origin2?.packageUrl==="string"?origin2.packageUrl:void 0,typeof origin2?.source==="string"?origin2.source:void 0,url2,name].filter((x2)=>!!x2).map(key3))]};var import_react109=__toESM(require_react_production(),1);var import_react108=__toESM(require_react_production(),1);var fmt3=(n)=>n==null?"size unknown":n<1024?`${n} B`:n<1048576?`${(n/1024).toFixed(1)} KiB`:`${(n/1024/1024).toFixed(1)} MiB`,choices=(row3,sizes)=>{if(row3.installState==="incompatible"||row3.installState==="mismatch")return[];if(!row3.installed)return[{label:"Eikon only",hint:fmt3(sizes?.eikon),value:"install"},{label:"Eikon + Source",hint:`${fmt3((sizes?.eikon??0)+(sizes?.source??0))} \xB7 Source files needed to edit Eikon in Studio`,value:"source"}];return[...!row3.active?[{label:"Use",hint:"set as active avatar",value:"use"}]:[],...row3.sourceDownloadable?[{label:"Download Source",hint:"needed to edit in Studio",value:"download"}]:[],...row3.removable?[{label:"Delete",value:"delete"}]:[]]},Action=(props)=>{let theme=useTheme().theme,opts=choices(props.row,props.sizes),[sel,setSel]=import_react108.useState(0),desc=opts.some((o)=>!!o.hint);return $jsxs("box",{flexDirection:"column",width:64,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.row.entry.name})}),$jsx("box",{height:1}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:props.row.entry.description??"No description."}),$jsx("box",{height:1}),opts.length>0?$jsx("select",{focused:!0,width:62,height:Math.min(12,Math.max(1,opts.length*(desc?2:1))),options:opts.map((o)=>({name:o.label,description:o.hint??"",value:o.value})),selectedIndex:Math.min(sel,opts.length-1),showDescription:desc,showScrollIndicator:opts.length>6,backgroundColor:theme.backgroundPanel,focusedBackgroundColor:theme.backgroundPanel,textColor:theme.textMuted,focusedTextColor:theme.text,selectedBackgroundColor:theme.backgroundElement,selectedTextColor:theme.text,descriptionColor:theme.textMuted,selectedDescriptionColor:theme.textMuted,keyBindings:[{name:"home",action:"move-up-fast"},{name:"end",action:"move-down-fast"},{name:"space",action:"select-current"},{name:" ",action:"select-current"},{name:"return",action:"select-current"}],onChange:(i)=>setSel(i),onSelect:(i)=>{let opt=opts[i];if(opt)props.onPick(opt.value)}}):$jsx("text",{fg:theme.textMuted,children:props.row.reason??"No available actions."}),$jsx("box",{height:1}),$jsx("text",{fg:theme.textMuted,children:"[\u2191\u2193] move [Space/Enter] confirm [Esc] cancel"})]})};function openEikonMarketplaceAction(dialog,opts){return new Promise((resolve4)=>{let done=(v2)=>{resolve4(v2),dialog.clear()};dialog.replace($jsx(Action,{...opts,onPick:done}),()=>resolve4(null))})}init_perf();import{existsSync as existsSync21,readFileSync as readFileSync14,readdirSync as readdirSync7,writeFileSync as writeFileSync6}from"fs";import{createHash as createHash4}from"crypto";import{basename as basename14,dirname as dirname14,extname as extname4,join as join18}from"path";var DEFAULT_TIMEOUT=5000,DEFAULT_CACHE_LIMIT=24,dec=new TextDecoder;function hash2(data2){return`sha256:${createHash4("sha256").update(data2).digest("hex")}`}function keyIdentity(s){try{let u3=new URL(s);if(u3.protocol==="http:"||u3.protocol==="https:"||u3.protocol==="file:")return u3.href.replace(/\/?$/,"/")}catch{}return s}function manifestBaseKey(s){try{let u3=new URL(s);if((u3.protocol==="http:"||u3.protocol==="https:"||u3.protocol==="file:")&&u3.pathname.endsWith("/manifest.json"))return new URL(".",u3).href}catch{}return}function registryKey(man,source){if(man?.kind!=="eikon.package"||typeof man.id!=="string")return;let sourceKey=man.origin?.sourceKey??man.origin?.identityKey;if(sourceKey)return keyIdentity(sourceKey);try{let host=source?new URL(source).host:void 0;if(!host)return;return`registry:${host}:${man.id}${typeof man.version==="string"&&man.version?`@${man.version}`:""}`}catch{return}}function entryKeys(entry2){return[...new Set([entry2.identityKey,entry2.sourceKey].filter(Boolean).map(keyIdentity))]}function keysFor(inst){let keys=new Set,man=inst.manifest,origin2=typeof man?.origin?.source==="string"?man.origin.source:void 0,head=exports_eikon.header(inst.file),src3=typeof head?.source_url==="string"?head.source_url:inst.sourceUrl,registry2=registryKey(man,origin2);if(registry2)keys.add(registry2);if(origin2){keys.add(keyIdentity(origin2));let base2=manifestBaseKey(origin2);if(base2)keys.add(keyIdentity(base2))}if(src3){keys.add(keyIdentity(src3));let base2=manifestBaseKey(src3);if(base2)keys.add(keyIdentity(base2))}return[...keys]}function read(path7){try{let man=JSON.parse(readFileSync14(path7,"utf8"));return obj(man)?man:void 0}catch{return}}function chosen(active,name){return active===name||active==="default"&&name==="nous"}function media(dir2){return existsSync21(dir2)&&readdirSync7(dir2).length>0}function text3(value){return typeof value==="string"&&value?value:void 0}function life(name,man){let origin2=obj(man.origin)?man.origin:{},display2=obj(man.display)?man.display:{},src3=text3(origin2.source),identity2=text3(origin2.identityKey)??text3(origin2.sourceKey)??text3(origin2.packageUrl)??text3(origin2.repo)??src3,title=text3(display2.title)??text3(man.title),author=text3(display2.author)??text3(man.author);return{name,...title?{title}:{},...author?{author}:{},...text3(man.version)?{version:text3(man.version)}:{},source:{kind:text3(origin2.kind)??"default-catalog",...identity2?{identity:identity2}:{},...src3?{origin:src3}:{},...text3(origin2.repo)?{repo:text3(origin2.repo)}:{},...text3(origin2.selector)?{selector:text3(origin2.selector)}:{},...text3(origin2.catalogRoot)?{catalogRoot:text3(origin2.catalogRoot)}:{},...text3(origin2.sha)?{sha:text3(origin2.sha)}:{},...text3(origin2.packageUrl)?{packageUrl:text3(origin2.packageUrl)}:{}},trust:text3(origin2.trust)??"verified",active:chosen(get2("eikon"),name),removable:!1,updateable:Boolean(src3??text3(origin2.packageUrl)),updateAvailable:!1,dirty:!1,...text3(man.poster)?{poster:text3(man.poster)}:{},...obj(man.compatibility)?{compatibility:man.compatibility}:{},...text3(origin2.at)?{installedAt:text3(origin2.at)}:{}}}function bundled(xs){let names=new Set(xs.map((x2)=>x2.name.toLowerCase()));return listEikons([BUNDLED_EIKON_DIR]).flatMap((e)=>{let man=read(join18(dirname14(e.path),"manifest.json"));if(man?.kind!=="eikon.package")return[];let name=text3(man.name)??e.meta.name.toLowerCase();if(names.has(name.toLowerCase()))return[];let inst={name,file:e.path,source:exports_eikon.sourceDir(name),hasSource:media(exports_eikon.sourceDir(name)),sourceUrl:text3(man.origin?.source)??text3(man.origin?.packageUrl),manifest:man,lifecycle:life(name,man)};return[{...inst,manifest:man,identityKeys:keysFor(inst)}]})}function cacheKey(entry2){return[entry2.identityKey||entry2.sourceKey||entry2.id,entry2.runtimeUrl,entry2.trust?.runtimeDigest,entry2.trust?.runtimeSize].filter(Boolean).join("|")}function blob(url2){return/\/blobs\/sha256\/[^/?#]+/.test(url2)}function artifact(entry2){return entry2}function obj(value){return!!value&&typeof value==="object"&&!Array.isArray(value)}function rawManifest(entry2){let raw2=entry2.raw;return obj(raw2.manifest)?raw2.manifest:void 0}function role(file2){if(file2.role==="source.base")return"base";if(file2.role?.startsWith("source."))return file2.role.slice(7);if(!file2.path)return;return basename14(file2.path,extname4(file2.path)).toLowerCase()||"base"}function sourceEntries2(man,strict=!1){if(!man)return[];try{let xs=entries(man).map(([r,rel2])=>[r,rel2]);if(xs.length)return xs;return(man.files??[]).flatMap((file2)=>{if(typeof file2.path!=="string"||!file2.role?.startsWith("source"))return[];let r=role(file2);return r?[[r,file2.path]]:[]})}catch(err){if(strict)throw err}return(man.files??[]).flatMap((file2)=>{if(typeof file2.path!=="string"||!file2.role?.startsWith("source"))return[];let r=role(file2);return r?[[r,file2.path]]:[]})}function sourceDescriptors2(man){return sourceEntries2(man).length>0}function sourceAvailable2(entry2,inst){return sourceDescriptors2(inst?.manifest)||sourceDescriptors2(rawManifest(entry2))}function trust(entry2){return entry2.trust}function boundTrust(entry2,raw2){let t2=trust(entry2),man=t2.manifestDigest,run=t2.runtimeDigest;if(!man&&!run)return"unverified";if(man&&hash2(raw2)!==man)throw Error(`catalog trust mismatch: manifest digest for ${entry2.name}`);let pkg=JSON.parse(dec.decode(raw2)),rel2=pkg.entrypoints?.default,got=rel2?pkg.files?.find((f)=>f.path===rel2)?.digest:void 0;if(run&&got!==run)throw Error(`catalog trust mismatch: runtime digest for ${entry2.name}`);return man&&run?"verified":"unverified"}function spec2(man,rel2){return man.files?.find((f)=>f.path===rel2)}async function sourceBytes(man,base2,rel2,opts){let file2=spec2(man,rel2);if(!file2?.digest||typeof file2.size!=="number")throw Error(`source descriptor missing digest or size: ${rel2}`);let raw2=await downloadBytes(new URL(rel2,base2).href,opts);if(raw2.length!==file2.size)throw Error(`source size mismatch: ${rel2}`);if(hash2(raw2)!==file2.digest)throw Error(`source digest mismatch: ${rel2}`);return raw2}function target(input){return typeof input==="string"?input:input instanceof URL?input.href:input.url}function verifiedCatalogTrust(entry2){let t2=trust(entry2);return typeof t2.manifestDigest==="string"&&t2.manifestDigest.length>0&&typeof t2.runtimeDigest==="string"&&t2.runtimeDigest.length>0}function installed(){let xs=exports_eikon.list().map((inst)=>({...inst,manifest:inst.manifest,identityKeys:keysFor(inst)}));return[...xs,...bundled(xs)]}function match2(entry2,xs){let keys=entryKeys(entry2),exact=xs.find((x2)=>x2.identityKeys.some((k2)=>keys.includes(k2)));if(exact)return{inst:exact,legacy:!1};let named=xs.find((x2)=>x2.name===entry2.name&&x2.identityKeys.length===0);if(named)return{inst:named,legacy:!0};return}function row3(entry2,xs){let usable=match2(entry2,xs),active=usable?chosen(get2("eikon"),usable.inst.name):!1,installed2=Boolean(usable),conflict=!usable&&chosen(get2("eikon"),entry2.name),blocked=entry2.compatibility?.available===!1,mismatch=usable?.inst.lifecycle.trust==="mismatch",installState=mismatch?"mismatch":blocked?"incompatible":active?"active":conflict?"active-name-conflict":!usable?"available":usable.legacy?"legacy-name-match":"installed",lifecycle2=usable?.inst.lifecycle??{name:entry2.name,title:entry2.title,author:entry2.author,version:entry2.version,source:{kind:"default-catalog",identity:entry2.sourceKey,packageUrl:entry2.packageUrl},trust:verifiedCatalogTrust(entry2)?"verified":"unverified",active:!1,removable:!1,updateable:!1,updateAvailable:!1,dirty:!1,...entry2.poster?{poster:entry2.poster}:{},compatibility:entry2.compatibility},available=sourceAvailable2(entry2,usable?.inst);return{entry:entry2,installed:installed2,active,installState,...usable?.inst.file?{installedPath:usable.inst.file,installedName:usable.inst.name}:{},...usable?.inst.manifest?{installedManifest:usable.inst.manifest}:{},lifecycle:lifecycle2,trust:lifecycle2.trust,updateable:lifecycle2.updateable,updateAvailable:lifecycle2.updateAvailable,removable:lifecycle2.removable,sourceIdentity:lifecycle2.source.identity,sourcePresent:usable?.inst.hasSource??!1,sourceAvailable:available,sourceDownloadable:Boolean(usable&&!usable.inst.hasSource&&available),reason:blocked?entry2.compatibility?.reason??"incompatible":mismatch?"trust mismatch":conflict?"install would replace the active avatar backing package":void 0,action:active?"active":installed2?"use":"install"}}function sizes(man){let files=Array.isArray(man.files)?man.files:[],eikon=files.filter((f)=>f.role==="runtime"||f.path===man.entrypoints?.default).map((f)=>f.size).filter((n)=>typeof n==="number").reduce((sum,n)=>sum+n,0),source=files.filter((f)=>typeof f.role==="string"&&f.role.startsWith("source")).map((f)=>f.size).filter((n)=>typeof n==="number").reduce((sum,n)=>sum+n,0);return{...eikon>0?{eikon}:{},...source>0?{source}:{}}}function abortErr(){return new DOMException("aborted","AbortError")}class MarketplaceService{catalog;fetcher;timeoutMs;previewCacheLimit;concurrency;allowPrivate;activeLoads=0;queue=[];cache=new Map;inFlight=new Map;constructor(catalog2,opts={}){this.catalog=catalog2,this.fetcher=opts.fetcher??fetch,this.timeoutMs=opts.timeoutMs??DEFAULT_TIMEOUT,this.previewCacheLimit=opts.previewCacheLimit??DEFAULT_CACHE_LIMIT,this.concurrency=Math.max(1,Math.floor(opts.concurrency??4)),this.allowPrivate=opts.allowPrivate===!0}rows(query=""){let entries2=searchCatalog(this.catalog.entries,query),xs=installed();return entries2.map((e)=>row3(e,xs))}entry(id){let key4=keyIdentity(id);return this.catalog.entries.find((e)=>keyIdentity(e.identityKey)===key4||keyIdentity(e.sourceKey)===key4||e.id===id||e.name===id)}dl(signal,fetcher=this.fetcher){return{allowPrivate:this.allowPrivate,fetcher:(input,init)=>fetcher(input,signal?{...init,signal}:init)}}runtime(entry2,signal){return async(input)=>{let url2=target(input),bound=keyIdentity(url2)===keyIdentity(entry2.runtimeUrl)&&(!!entry2.trust?.runtimeDigest||blob(url2)),raw2=await downloadBytes(url2,{...this.dl(signal),rejectContentEncoding:bound}),buf=raw2.buffer.slice(raw2.byteOffset,raw2.byteOffset+raw2.byteLength);return new Response(buf,{headers:{"content-length":String(raw2.length)}})}}cached(url2,raw2){let key4=keyIdentity(url2);return async(input,init)=>{if(keyIdentity(target(input))===key4)return new Response(raw2.slice(),{headers:{"content-length":String(raw2.length)}});return this.fetcher(input,init)}}async preview(id,opts={}){if(opts.signal?.aborted)throw abortErr();let entry2=this.entry(id);if(!entry2)throw Error(`marketplace: unknown eikon "${id}"`);let key4=cacheKey(entry2),hit2=this.cache.get(key4);if(hit2!==void 0)return hit2;let active=this.inFlight.get(key4);if(active)return active;let p=this.enqueue(()=>this.loadPreview(entry2,opts)).finally(()=>this.inFlight.delete(key4));return this.inFlight.set(key4,p),p}async packageSizes(id){let entry2=this.entry(id);if(!entry2)throw Error(`marketplace: unknown eikon "${id}"`);return sizes(JSON.parse(dec.decode(await downloadBytes(entry2.packageUrl,this.dl()))))}async install(id,opts={}){let entry2=this.entry(id);if(!entry2)throw Error(`marketplace: unknown eikon "${id}"`);if(entry2.compatibility?.available===!1)throw Error(entry2.compatibility.reason??"eikon is incompatible");if(!match2(entry2,installed())&&chosen(get2("eikon"),entry2.name)&&!opts.confirmActive)throw Error(`Installing '${entry2.name}' will replace the active avatar's backing package. Pass confirmActive to install it.`);let raw2=await downloadBytes(entry2.packageUrl,this.dl()),state2=boundTrust(entry2,raw2),out=await exports_eikon.fetchSource(entry2.packageUrl,{name:entry2.name,media:opts.media===!0,downloader:this.dl(void 0,this.cached(entry2.packageUrl,raw2))}),ef=exports_eikon.file(out.name);if(!existsSync21(ef)){let art=await loadRuntimeArtifact(entry2,this.runtime(entry2),{allowPrivate:this.allowPrivate});await Bun.write(ef,art.bytes),exports_eikon.notifyRevision()}let mf=join18(exports_eikon.dir(out.name),"manifest.json"),man=JSON.parse(readFileSync14(mf,"utf8")),origin2=man.origin&&typeof man.origin==="object"&&!Array.isArray(man.origin)?man.origin:{};return writeFileSync6(mf,JSON.stringify({...man,origin:{...origin2,sourceKey:entry2.sourceKey,identityKey:entry2.identityKey,packageUrl:entry2.packageUrl,trust:state2}},null,2)+`
4161
4162
  `),out}async downloadSource(id){let entry2=this.entry(id);if(!entry2)throw Error(`marketplace: unknown eikon "${id}"`);let usable=match2(entry2,installed());if(!usable)throw Error(`marketplace: "${entry2.name}" is not installed`);if(!sourceAvailable2(entry2,usable.inst))throw Error(`marketplace: no source media published for "${entry2.name}"`);let raw2=await downloadBytes(entry2.packageUrl,this.dl());boundTrust(entry2,raw2);let man=JSON.parse(dec.decode(raw2)),xs=sourceEntries2(man,!0);if(xs.length===0)throw Error(`marketplace: no source media published for "${entry2.name}"`);let base2=new URL(".",entry2.packageUrl).href,dir2=exports_eikon.ensure(usable.inst.name).source,pairs=await Promise.all(xs.map(async([r,rel2])=>{let data2=await sourceBytes(man,base2,rel2,this.dl());return[r,exports_eikon.sourceName(man,r,rel2),data2]})),sources={};return await Promise.all(pairs.map(async([r,fname,data2])=>{await Bun.write(join18(dir2,fname),data2),sources[r]=fname})),exports_eikon.attachSources(usable.inst.name,sources),{name:usable.inst.name,n:pairs.length,bytes:pairs.reduce((sum,[,,data2])=>sum+data2.length,0)}}enqueue(run){return new Promise((resolve4,reject)=>{this.queue.push({run,resolve:resolve4,reject}),this.pump()})}pump(){if(this.activeLoads>=this.concurrency)return;let job=this.queue.shift();if(!job)return;this.activeLoads+=1,job.run().then(job.resolve,job.reject).finally(()=>{this.activeLoads-=1,this.pump()})}async loadPreview(entry2,opts){let ctl=new AbortController,timeout=setTimeout(()=>ctl.abort(),opts.timeoutMs??this.timeoutMs),off=()=>ctl.abort();opts.signal?.addEventListener("abort",off,{once:!0});try{let item=artifact(entry2),text4=(await loadRuntimeArtifact(item,this.runtime(item,ctl.signal),{signal:ctl.signal,allowPrivate:this.allowPrivate})).text;this.cache.set(cacheKey(entry2),text4);while(this.cache.size>this.previewCacheLimit)this.cache.delete(this.cache.keys().next().value);return text4}finally{clearTimeout(timeout),opts.signal?.removeEventListener("abort",off)}}}async function load4(opts={}){let query=opts.query??"";try{if(opts.catalog)publicCatalogUrl(opts.catalog,void 0,opts);let cat=await loadCatalog(opts.catalog,opts.fetcher??fetch,opts),service=new MarketplaceService(cat,opts),rows3=service.rows(query);return{status:rows3.length>0?"ready":"empty",query,rows:rows3,selected:rows3[0],service}}catch(err){return{status:"error",query,rows:[],error:err instanceof Error?err.message:String(err)}}}var NO_MARKET={status:"empty",query:"",rows:[]};function localCatalog(raw2){if(!raw2)return!1;try{let url2=new URL(raw2),host=url2.hostname.toLowerCase().replace(/^\[|\]$/g,"");return url2.protocol==="file:"||host==="localhost"||host==="127.0.0.1"||host==="0.0.0.0"||host==="::1"||host.endsWith(".localhost")}catch{return!1}}var EikonMarketplace=import_react109.memo((props)=>{let toast=useToast(),dialog=useDialog(),keys=useKeys(),rev2=import_react109.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision),[sel,setSel]=import_react109.useState(0),[searching,setSearching]=import_react109.useState(!1),[query,setQuery]=import_react109.useState(""),[state2,setState2]=import_react109.useState(NO_MARKET),[loading,setLoading]=import_react109.useState(!1),[installing,setInstalling]=import_react109.useState(!1),[previewState,setPreviewState]=import_react109.useState("idle"),[detailPreview,setDetailPreview]=import_react109.useState(void 0),previewSeq=import_react109.useRef(0),follow=useFollow("market",(i)=>state2.rows[i]?.entry.identityKey??i);import_react109.useEffect(()=>{if(sel>=state2.rows.length)setSel(Math.max(0,state2.rows.length-1))},[state2.rows.length,sel]);let selected=state2.rows[sel];import_react109.useEffect(()=>{if(!selected||!state2.service){setDetailPreview(void 0),props.sidebarPreview?.(void 0);return}let id=++previewSeq.current,key4=selected.entry.identityKey;count("market:preview:load"),state2.service.preview(key4).then((text4)=>{if(previewSeq.current!==id)return;let e=parseEikon(text4),st=e.states.has(previewState)?previewState:"idle",preview3={key:`${key4}:${st}`,eikon:e,state:st,title:selected.entry.name,subtitle:selected.entry.author??"unknown",body:selected.entry.description??"No description.",rows:[{label:"Status",value:previewStatus(selected),block:!0},{label:"Source",value:sourceText(selected),block:!0},{label:"Compat",value:compatText(selected)},{label:"State",value:st},{label:"Digest",value:digest2(selected)??"unknown",block:!0}],states:[...e.states.keys()],onState:setPreviewState};if(props.sidebarPreview)props.sidebarPreview(preview3);setDetailPreview(preview3),count("market:preview:ready")}).catch(()=>{if(previewSeq.current!==id)return;setDetailPreview(void 0),props.sidebarPreview?.(void 0),count("market:preview:error")})},[selected,state2.service,previewState,props.sidebarPreview,props.sidebarHidden]),import_react109.useEffect(()=>()=>{previewSeq.current++,setDetailPreview(void 0),props.sidebarPreview?.(void 0)},[props.sidebarPreview]);let loadMarket=import_react109.useCallback((q5=query)=>{setLoading(!0);let end=mark("market:list:load"),catalog2=process.env.EIKON_URL;load4({catalog:catalog2,allowPrivate:localCatalog(catalog2),query:q5}).then((next2)=>{count("market:list:rows",next2.rows.length),setState2(next2),setSel((p)=>Math.max(0,Math.min(next2.rows.length-1,p)))}).finally(()=>{end(),setLoading(!1)})},[query]),refreshMarket=import_react109.useCallback((svc,q5=query)=>{let rows3=svc.rows(q5);setState2({status:rows3.length>0?"ready":"empty",query:q5,rows:rows3,selected:rows3[0],service:svc}),setSel((p)=>Math.max(0,Math.min(rows3.length-1,p)))},[query]);import_react109.useEffect(()=>{loadMarket(query)},[query,rev2,loadMarket]);let clearPreview=import_react109.useCallback(()=>{previewSeq.current++,props.sidebarPreview?.(void 0),setDetailPreview(void 0)},[props.sidebarPreview]),primary=import_react109.useCallback((idx)=>{let row4=state2.rows[idx??sel],svc=state2.service;if(!row4||!svc||installing)return;(async()=>{let sizes2=!row4.installed?await svc.packageSizes(row4.entry.identityKey).catch(()=>{return}):void 0,pick2=await openEikonMarketplaceAction(dialog,{row:row4,sizes:sizes2});if(!pick2)return;if(pick2==="use"){let name=row4.installedName??row4.entry.name;exports_eikon.useInstalled(name),toast.show({variant:"success",message:`Avatar \u2192 ${name}`}),refreshMarket(svc,query);return}if(pick2==="delete")return removeSelected(idx);setInstalling(!0);try{if(!(row4.installState==="active-name-conflict"?await openConfirm(dialog,{title:`Replace active '${row4.entry.name}'?`,danger:!0,body:`Installing this marketplace package will replace the active avatar's backing package for '${row4.entry.name}' because another package with the same installed name is active.`,yes:"replace active",no:"cancel"}):!0))return;let out=pick2==="download"?await svc.downloadSource(row4.entry.identityKey):await svc.install(row4.entry.identityKey,{media:pick2==="source",confirmActive:row4.installState==="active-name-conflict"});toast.show({variant:"success",message:pick2==="download"?`Downloaded source for '${out.name}'`:`Installed '${out.name}' (${out.n} files)`}),refreshMarket(svc,query)}catch(err){toast.show({variant:"error",title:pick2==="download"?"Source download failed":"Install failed",message:err instanceof Error?err.message:String(err),duration:6000}),refreshMarket(svc,query)}finally{setInstalling(!1)}})()},[dialog,state2.rows,state2.service,sel,installing,toast,refreshMarket,query]),removeSelected=import_react109.useCallback(async(idx)=>{let row4=state2.rows[idx??sel],svc=state2.service,name=row4?.installedName??row4?.entry.name;if(!row4||!svc||!name||!row4.removable)return toast.show({variant:"warning",message:"This eikon is not removable"});let active=row4.active;if(!await openConfirm(dialog,{title:`Remove '${name}'?`,danger:!0,body:active?`Remove the local package for '${name}'. This is the active avatar; removal will clear the active avatar selection.`:`Remove the local package for '${name}'. This does not change the active avatar.`,yes:"remove",no:"cancel"}))return;let out=exports_eikon.remove(name,{confirmActive:active});if(out)return toast.show({variant:"warning",message:out.message});toast.show({variant:"info",message:`Removed '${name}'`}),refreshMarket(svc,query)},[dialog,query,refreshMarket,sel,state2.rows,state2.service,toast]);useKeyboard((key4)=>{if(!props.focused||dialog.open())return;if(searching){if(key4.name==="escape"){setSearching(!1);return}if(key4.name==="backspace"){setQuery((q5)=>q5.slice(0,-1)),setSel(0);return}if(key4.raw&&key4.raw.length===1&&key4.raw>=" "){setQuery((q5)=>q5+key4.raw),setSel(0);return}return}if(key4.name==="escape")return clearPreview();let plain=!key4.shift&&!key4.ctrl&&!key4.meta,move=(by)=>setSel((p)=>{let n=Math.max(0,Math.min(state2.rows.length-1,p+by));return follow.opts.scrollTo?.(n),n});if(plain&&key4.name==="left"){move(-1);return}if(plain&&key4.name==="right"){move(1);return}if(plain&&key4.name==="up"){move(-2);return}if(plain&&key4.name==="down"){move(2);return}if(handleListKey(keys,key4,{count:state2.rows.length,setSel,...follow.opts,onActivate:primary,onToggle:()=>setPreviewState((s)=>s==="idle"?"thinking":"idle"),onSearch:()=>setSearching(!0),onRefresh:()=>loadMarket(query),onDelete:()=>void removeSelected()}))return}),count("market:render");let fallback=props.sidebarHidden||!props.sidebarPreview;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,minHeight:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,minWidth:0,minHeight:0,children:[$jsx(TabShell,{title:`Marketplace (${state2.rows.length})${searching?` Search: ${query}`:""}`,focus:props.focused,grow:fallback?3:1,children:$jsx(MarketplaceGrid,{rows:state2.rows,sel,follow,loading,error:state2.error,onSel:setSel,onUse:primary})}),fallback?$jsx(TabShell,{title:selected?`Details \u2014 ${selected.entry.name}`:"Details",grow:2,children:$jsx(MarketplaceDetail,{row:selected,loading,installing,onUse:()=>primary(),onState:setPreviewState,preview:detailPreview})}):null]}),$jsx(HintBar,{pairs:[[keys.print("list.activate"),"actions"],["\u2191\u2193\u2190\u2192/Pg","select"],[keys.print("list.search"),searching?"typing search":"search"],[keys.print("list.refresh"),"reload"],["d","delete in modal"],["Space","preview"]]})]})}),MarketplaceGrid=(props)=>{let theme=useTheme().theme;if(props.error)return $jsx("box",{padding:1,children:$jsxs("text",{fg:theme.error,wrapMode:"word",children:["Marketplace unavailable: ",props.error]})},"error");if(props.loading&&props.rows.length===0)return $jsx("box",{padding:1,children:$jsx("text",{fg:theme.textMuted,children:"Loading shared eikons\u2026"})},"loading");if(props.rows.length===0)return $jsx("box",{padding:1,children:$jsx("text",{fg:theme.textMuted,children:"No shared eikons match. Press / to change search."})},"empty");return $jsx("scrollbox",{ref:props.follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:chunk(props.rows,2).map((rows3,y2)=>{let h2=Math.max(...rows3.map(cardHeight));return $jsx("box",{flexDirection:"row",height:h2,flexShrink:0,width:"100%",children:rows3.map((r,x2)=>{let i=y2*2+x2,on=i===props.sel,lines3=posterLines(r.entry.poster);return $jsxs("box",{id:props.follow.id(i),flexDirection:"column",height:h2,width:"50%",paddingX:1,backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:()=>props.onSel(i),onMouseDown:()=>{props.onSel(i),props.onUse(i)},children:[$jsx("box",{height:lines3.length,overflow:"hidden",flexDirection:"column",children:lines3.map((line4,j2)=>$jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:line4||" "})},j2))}),$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{fg:r.active?theme.accent:theme.text,wrapMode:"none",children:[on?"\u25B8 ":" ",r.active?"\u25CF ":" ",$jsx("strong",{children:r.entry.name})]})}),$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{fg:theme.textMuted,wrapMode:"none",children:["by ",r.entry.author??"unknown"," \xB7 ",stateLabel(r,!0)]})})]},r.entry.identityKey)})},y2)})},"rows")},posterLines=(poster2)=>{let lines3=poster2?poster2.split(`
4162
4163
  `):[];return lines3.length?lines3:["(no poster)"]},cardHeight=(row4)=>posterLines(row4.entry.poster).length+2,chunk=(rows3,n)=>rows3.reduce((acc2,row4,i)=>{if(i%n===0)acc2.push([]);return acc2[acc2.length-1].push(row4),acc2},[]),MarketplaceDetail=(props)=>{let theme=useTheme().theme,r=props.row;if(!r)return $jsx("box",{padding:1,children:$jsx("text",{fg:theme.textMuted,children:props.loading?"Loading shared eikons\u2026":"No marketplace entry selected."})});let previewState=props.preview?.state??"idle",states=props.preview?[...props.preview.eikon.states.keys()]:[previewState];return $jsxs("box",{flexDirection:"column",padding:1,gap:1,children:[props.preview?$jsx("box",{alignItems:"center",justifyContent:"center",height:8,overflow:"hidden",children:$jsx("box",{flexDirection:"column",children:props.preview.eikon.states.get(props.preview.state)?.frames[0]?.map((line4,i)=>$jsx("text",{children:line4},i))})}):null,$jsx("text",{fg:r.active?theme.accent:theme.text,children:$jsxs("strong",{children:[r.active?"\u25CF ":"",r.entry.name]})}),$jsxs("text",{fg:theme.textMuted,children:["by ",r.entry.author??"unknown"]}),$jsx("text",{fg:theme.text,wrapMode:"word",children:r.entry.description??"No description."}),$jsx("box",{flexDirection:"row",height:1,children:states.map((s,i)=>$jsx(FilterChip,{label:s,state:s===previewState?"in":"off",gap:i===0?0:1,color:theme.primary,textColor:theme.textMuted,onMouseDown:()=>props.onState(s)},s))}),$jsx(DetailRow2,{label:"Status",value:stateLabel(r),block:!0}),$jsx(DetailRow2,{label:"Trust",value:trustLabel(r),block:!0}),$jsx(DetailRow2,{label:"Source",value:sourceText(r),block:!0}),$jsx(DetailRow2,{label:"Compat",value:compatText(r)}),$jsx(DetailRow2,{label:"Digest",value:digest2(r)??"unknown",block:!0}),$jsx("box",{height:1,onMouseDown:props.onUse,children:$jsx("text",{fg:r.action==="active"?theme.textMuted:theme.primary,children:props.installing?"Installing\u2026":"Open actions"})})]})},DetailRow2=(props)=>{let theme=useTheme().theme;if(props.block)return $jsxs("box",{flexDirection:"column",minHeight:2,children:[$jsx("text",{fg:theme.textMuted,children:props.label}),$jsx("text",{fg:theme.text,wrapMode:"word",children:props.value})]});return $jsxs("text",{fg:theme.textMuted,children:[props.label,": ",props.value]})},shortDigest=(value)=>{if(!value)return;let[algo,hash3]=value.includes(":")?value.split(":",2):[void 0,value];if(!hash3||hash3.length<=16)return value;return algo?`${algo}:${hash3.slice(0,12)}\u2026`:`${hash3.slice(0,12)}\u2026`},digest2=(row4)=>{let t2=row4.entry.trust;return shortDigest(t2.manifestDigest??t2.runtimeDigest??t2.digest)},trustLabel=(row4)=>{let t2=row4.trust==="mismatch"?"Mismatch":row4.trust==="verified"?"Verified":row4.trust==="unverified"?"Unverified":"Trust unknown";return row4.reason&&row4.trust==="mismatch"?`${t2}: ${row4.reason}`:t2},previewStatus=(row4)=>{let base2=row4.installState==="active-name-conflict"?"active name conflict":row4.active?"active":row4.installed?"installed":"not installed",src3=row4.sourcePresent?" \xB7 source present":row4.sourceAvailable?" \xB7 source available":"",rm=row4.removable?" \xB7 removable":row4.installed?" \xB7 not removable":"";return`${base2}${src3}${rm}`},sourceText=(row4)=>row4.sourceIdentity??row4.lifecycle.source.packageUrl??row4.entry.sourceKey??row4.entry.packageUrl,compatText=(row4)=>row4.installState==="incompatible"?`Blocked: ${row4.reason??"requires newer Herm/eikon"}`:row4.installState==="active-name-conflict"?`Requires confirmation: ${row4.reason}`:"Compatible",stateLabel=(row4,short2=!1)=>{let base2=row4.installState==="active-name-conflict"?"active name conflict":row4.active?"active":row4.installed?"installed":"not installed";if(short2)return base2;let src3=row4.sourcePresent?" \xB7 source present":row4.sourceDownloadable?" \xB7 source downloadable":row4.sourceAvailable?" \xB7 source available":"",rm=row4.removable?" \xB7 removable":row4.installed?" \xB7 not removable":"";return`${base2}${src3}${rm}`};var EikonGroup=import_react111.memo((props)=>{let labels=SUB_TABS[EIKON_TAB],[target2,setTarget]=import_react111.useState(void 0);import_react111.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]),import_react111.useEffect(()=>{if(props.sub!==2)props.sidebarPreview?.(void 0)},[props.sub,props.sidebarPreview]);let edit2=import_react111.useCallback((name)=>{setTarget(name),props.setSub(1)},[props]),hint="shift+\u2190/\u2192 sub";return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,minHeight:0,children:[$jsx(SubTabBar,{tabs:labels,active:props.sub,onChange:props.setSub,hint}),$jsxs("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:[$jsx(Pane4,{visible:props.sub===0,children:$jsx(EikonGallery,{focused:!!props.focused&&props.sub===0,onEdit:edit2})}),$jsx(Pane4,{visible:props.sub===1,children:$jsx(EikonStudio,{focused:!!props.focused&&props.sub===1,name:target2})}),$jsx(Pane4,{visible:props.sub===2,children:$jsx(EikonMarketplace,{focused:!!props.focused&&props.sub===2,sidebarPreview:props.sidebarPreview,sidebarHidden:props.sidebarHidden})})]})]})}),Pane4=({visible:visible2,children:children2})=>visible2?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react112=__toESM(require_react_production(),1);var FRAME={cw:16,ch:8,tw:20,tv:8},TL=["\u2800\u2880\u28E4\u2824\u2884\u28C0\u2804\u2880\u28E0\u28E4\u28C4\u2864\u2844\u2840\u2800\u2800","\u2800\u28DC\u2841\u28A9\u28C8\u2842\u2880\u28CB\u28ED\u2809\u2808\u2888\u28EE\u28FB\u2851\u28F6","\u2800\u28B8\u2856\u28BF\u280F\u28E4\u28F6\u28FD\u28EB\u28B6\u28E2\u284C\u2839\u28E7\u284F\u283B","\u2800\u2808\u2864\u2892\u28E6\u28BB\u28FF\u28FF\u28FF\u28BF\u28C5\u2847\u28C6\u2849\u2802\u2880","\u2801\u28B8\u284F\u2818\u280B\u289E\u28B3\u28FF\u28FF\u28DF\u284D\u284D\u28E4\u2805\u2800\u28A8","\u2800\u2824\u28AF\u28C6\u28C0\u2819\u28A6\u28FF\u284B\u2880\u28DC\u2807\u28C1\u28D2\u28CA\u28C9","\u2800\u2880\u28F7\u28DD\u28FB\u28F6\u28F6\u2884\u280D\u2818\u2841\u2847\u28E7\u28E0\u28E4\u2862","\u2800\u2800\u2818\u288E\u28BF\u28EF\u2803\u2801\u2864\u28DA\u287C\u2800\u284F\u28F9\u28FF\u2869"],TR=["\u2800\u2800\u2880\u28A0\u28A0\u28E0\u28E4\u28C0\u2840\u2820\u28C0\u2860\u2824\u28E4\u28C0\u2800","\u28F6\u288A\u28DF\u28F5\u2841\u2801\u2809\u28ED\u28D9\u2800\u2890\u28C2\u284D\u2888\u28E3\u2800","\u281F\u28B9\u28FC\u280F\u28A1\u28D4\u28B6\u28DD\u28EF\u28F6\u28E4\u2839\u287F\u28B2\u2847\u2800","\u2840\u2801\u2889\u28F0\u28B8\u28E8\u287F\u28FF\u28FF\u28FF\u285F\u28F4\u2852\u28A4\u2801\u2800","\u2845\u2804\u2828\u28E4\u28A9\u28A9\u28FB\u28FF\u28FF\u285E\u2873\u2819\u2803\u28B9\u2847\u2800","\u28C9\u28D1\u28D2\u28C8\u2838\u28E3\u2840\u2899\u28FF\u2874\u280B\u28C0\u28F0\u287D\u2824\u2880","\u2884\u28E4\u28C4\u28F8\u28B8\u2888\u2803\u2829\u2860\u28F6\u28F6\u28DF\u28EB\u28FE\u2802\u2800","\u288D\u28FF\u289F\u28B9\u2800\u28A7\u28D2\u28A4\u2801\u2808\u28FD\u287F\u2871\u2807\u2800\u2800"],BL=["\u2800\u2800\u28C0\u28FF\u28FF\u285F\u2801\u2800\u283B\u28AC\u28F3\u2800\u28C7\u28F2\u28DF\u28BF","\u2800\u2890\u287A\u28DB\u286F\u28ED\u2837\u280C\u2882\u2880\u2842\u2847\u284F\u2819\u281B\u2827","\u2800\u2816\u287C\u2809\u2809\u28A0\u28F0\u2825\u28AD\u2818\u28DB\u28C4\u288B\u28C9\u28C9\u2859","\u2800\u28B8\u284C\u2880\u28E0\u28F5\u28FF\u28FF\u28FF\u28FF\u28E8\u2803\u2837\u2802\u2810\u288D","\u2800\u2800\u283B\u281D\u283F\u28F4\u28FF\u28FF\u287F\u28FF\u28DF\u28CB\u284F\u2841\u2804\u2818","\u2800\u28B8\u28F0\u28F6\u28C4\u283B\u283F\u28FF\u28F9\u2830\u281F\u2882\u28A0\u285F\u28C6\u28F4","\u2800\u28AA\u2849\u2838\u28FB\u2807\u2800\u285D\u28DB\u2880\u2840\u28D8\u285F\u2877\u28EB\u286F","\u2800\u2819\u283B\u282A\u281C\u2813\u2802\u2808\u281B\u2813\u281B\u2819\u281A\u2808\u2801\u2800"],BR2=["\u287F\u28FB\u28D6\u28F8\u2800\u28DE\u2861\u281F\u2880\u2804\u28BB\u28FF\u28FF\u28C0\u2800\u2800","\u2836\u281B\u280B\u28B9\u28B8\u2890\u2840\u2850\u2821\u283E\u28ED\u28BD\u28DB\u2897\u2842\u2800","\u288B\u28C9\u28C9\u2859\u28E0\u28DB\u2803\u286D\u282C\u28C6\u2844\u2809\u2829\u28A7\u2832\u2800","\u2869\u2802\u2810\u283E\u2818\u28C5\u28FF\u28FF\u28FF\u28FF\u28EE\u28C4\u2840\u28B1\u2847\u2800","\u2803\u2880\u2888\u28B3\u28D9\u28FB\u28FF\u28DF\u28FF\u28FF\u28E6\u283F\u282B\u281F\u2800\u2800","\u28E6\u28F0\u28BB\u2844\u2850\u283B\u2803\u28CF\u28FF\u283F\u281F\u28E0\u28F6\u28C6\u2847\u2800","\u28BD\u28DD\u28AF\u28BB\u28C3\u2880\u2840\u28DB\u28E9\u2800\u2838\u28DF\u2807\u2889\u2855\u2800","\u2801\u2800\u2801\u2813\u280B\u281B\u281A\u281B\u2801\u2810\u281A\u2823\u2807\u281F\u280B\u2800"],T2=["\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800","\u2844\u28E2\u28F4\u28F6\u2836\u2816\u2832\u28CC\u2818\u2809\u2822\u285B\u28A1\u2834\u2832\u2836\u28F0\u2896\u28B4\u28E4","\u28FE\u28E5\u283F\u2800\u28E0\u28B0\u283F\u28BE\u2850\u283E\u283F\u2887\u2873\u28FF\u28D7\u2804\u2800\u2823\u28D1\u28F5","\u28BE\u285F\u2804\u2810\u28AD\u28CD\u2896\u2844\u2828\u28BB\u28EB\u283D\u287C\u287F\u28BD\u28A5\u2842\u2804\u283B\u287D","\u2813\u287B\u28B6\u28C4\u2848\u2818\u282D\u281A\u280D\u28BB\u2849\u280B\u280B\u282D\u2803\u2803\u2861\u28F6\u28DF\u28BE","\u2801\u2804\u2809\u2809\u281A\u2824\u2824\u282C\u281F\u2830\u2827\u280A\u282F\u2834\u2824\u2813\u281B\u2809\u2810\u2822","\u28DB\u28DB\u285F\u28DB\u285B\u28DB\u28DB\u289B\u28DB\u28DB\u285B\u28DB\u28DB\u289B\u28FB\u28FB\u28DF\u281B\u28FB\u28BB","\u28CA\u28C9\u28C9\u28DB\u28CB\u28D9\u28CB\u28FC\u28F7\u28E5\u28EF\u28FA\u28CB\u28F5\u28F7\u28ED\u28D9\u28D1\u28FB\u28FD"],B2=["\u28FF\u28BF\u28FF\u28FF\u28BF\u28FF\u287F\u287F\u28FF\u28FF\u283F\u28FF\u28BF\u287F\u28FF\u28FF\u287F\u28FF\u287F\u28BF","\u28C3\u28DB\u28C8\u28D3\u28DA\u28DA\u28C3\u28D9\u28DB\u28C9\u28DB\u28DB\u28C1\u28DB\u28D9\u28D9\u28CB\u28D8\u28C9\u28D9","\u2820\u2884\u2884\u28C0\u2864\u28E4\u2810\u28E0\u2884\u28A0\u2844\u2864\u28C4\u2800\u2864\u2884\u28C0\u2840\u2880\u2880","\u28F1\u282C\u282B\u2811\u2881\u28E0\u28A0\u286B\u28E1\u28E0\u28E4\u28C9\u2885\u2884\u28C4\u2809\u283B\u2850\u28A5\u28CC","\u2894\u28C8\u2800\u28B0\u2841\u28B6\u28FF\u28FF\u28DF\u28FF\u28C3\u285B\u2815\u280D\u28E6\u28C3\u2844\u2802\u28F9\u2862","\u287F\u288F\u2884\u2800\u2803\u28EB\u28FF\u289C\u28A9\u28F6\u28E6\u2809\u2876\u28FE\u2856\u281B\u2800\u28E0\u285B\u287F","\u283C\u28BE\u283F\u28F5\u28D6\u28D8\u2834\u2803\u2808\u2886\u2880\u2800\u2873\u2824\u28C2\u28F2\u28FE\u282F\u281A\u280F","\u2800\u2800\u2801\u2800\u2800\u2800\u2800\u2808\u2809\u2819\u280B\u2809\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800"],L2=["\u2800\u2800\u2890\u289F\u28FE\u283F\u282E\u2836\u2877\u28EA\u283E\u2802\u2857\u28AD\u28BF\u28B9","\u2800\u2800\u28E8\u2855\u2809\u2861\u2824\u28C1\u284C\u282A\u28A7\u2801\u2847\u28F0\u28FF\u28BC","\u2800\u2800\u2839\u2843\u28BE\u28D5\u28F7\u2866\u28D3\u2840\u2849\u2846\u284F\u28F6\u2863\u28FB","\u2800\u28B0\u2876\u28AC\u28ED\u285C\u28FF\u28FF\u28EF\u2888\u2893\u2801\u284F\u28DA\u287E\u28FF","\u2800\u2818\u285B\u288A\u28D9\u2823\u2887\u28AF\u28FF\u2828\u286D\u2841\u2867\u28BC\u28F2\u28FF","\u2800\u2800\u28B1\u2849\u28BF\u2847\u2824\u28DD\u2844\u2800\u2841\u2801\u284F\u28F6\u2896\u28BF","\u2800\u2800\u28B0\u28E7\u2840\u2813\u2813\u2809\u2881\u28F4\u284D\u2800\u2847\u283A\u283D\u28BA","\u2800\u2800\u2828\u283A\u28FD\u28F7\u28E6\u2874\u285A\u2803\u2880\u2800\u2847\u287E\u28FF\u28B9"],R=["\u284F\u287F\u286D\u28BA\u2880\u2837\u289D\u28BE\u2836\u2835\u283F\u28F7\u287B\u2842\u2800\u2800","\u2867\u28FF\u28C6\u28B8\u2800\u287C\u2815\u28A1\u28C0\u2824\u288C\u2809\u28AA\u28C5\u2801\u2800","\u28DF\u289C\u28F6\u28B9\u28B0\u2889\u2880\u28DA\u28B4\u28FE\u28EA\u2877\u2898\u280F\u2800\u2800","\u28FF\u28B7\u285B\u28B9\u2808\u285A\u2841\u28FD\u28FF\u28FF\u28A3\u28ED\u2865\u28B6\u2846\u2800","\u28FF\u28D6\u2867\u28BC\u2888\u28AD\u2805\u28FF\u287D\u2878\u2858\u28CB\u2851\u289B\u2803\u2800","\u287F\u2872\u28F6\u28B9\u2808\u2888\u2800\u28A0\u28EB\u2824\u28B8\u287F\u2889\u2846\u2800\u2800","\u2857\u282F\u2817\u28B8\u2800\u28A9\u28E6\u2848\u2809\u281A\u281A\u2880\u28FC\u2846\u2800\u2800","\u284F\u28FF\u28AF\u28B8\u2800\u2880\u2818\u2893\u28A6\u28B6\u28FE\u28EF\u2817\u2805\u2800\u2800"];function frame(w2,h2){let{cw,ch,tw,tv}=FRAME,mw=w2-2*cw,mh=h2-2*ch,inner={x:cw,y:ch,w:Math.max(0,mw),h:Math.max(0,mh)};if(mw<4||mh<2)return{lines:[],inner};let repH=(p,span2)=>p.map((l2)=>l2.repeat(Math.ceil(span2/tw)).slice(0,span2)),repV=(p,span2)=>Array.from({length:span2},(_2,i)=>p[i%tv]),t2=repH(T2,mw),b2=repH(B2,mw),l=repV(L2,mh),r=repV(R,mh),mid2=" ".repeat(mw),out=[];for(let i=0;i<ch;i++)out.push(TL[i]+t2[i]+TR[i]);for(let i=0;i<mh;i++)out.push(l[i]+mid2+r[i]);for(let i=0;i<ch;i++)out.push(BL[i]+b2[i]+BR2[i]);return{lines:out,inner}}import{readFileSync as readFileSync15}from"fs";import{join as join19}from"path";var FALLBACK=["`@file:path/to/file.py` injects file contents directly into your message.","`/title <name>` names the session \u2014 resume it later from the Sessions tab.","Ctrl+G opens $EDITOR seeded with the composer contents.","Ctrl+Z suspends to the shell; `fg` resumes.","Pasting 5+ lines collapses to a `[Pasted #N \u2026]` placeholder.","Click a user message in the transcript to rewind to that point."],HL=/(\/[a-z][\w-]*|@[\w:./-]+|(?:Ctrl|Alt|Shift)\+\S+|`[^`]+`|"[^"]+")/g;function splitTip(tip2){let out=[],i=0;for(let m2 of tip2.matchAll(HL)){let j2=m2.index;if(j2>i)out.push({t:tip2.slice(i,j2),hl:!1});out.push({t:m2[0].replace(/^`|`$/g,""),hl:!0}),i=j2+m2[0].length}if(i<tip2.length)out.push({t:tip2.slice(i),hl:!1});return out}var cache5=null;function loadTips(){if(cache5)return cache5;try{let body=readFileSync15(join19(hermesAgentRoot(),"hermes_cli","tips.py"),"utf8").split(/^TIPS\s*=\s*\[/m)[1]?.split(/^\]/m)[0]??"",tips=[];for(let line4 of body.split(`
4163
4164
  `)){let m2=line4.match(/^\s+"((?:[^"\\]|\\.)*)",?\s*$/);if(m2)tips.push(m2[1].replace(/\\"/g,'"').replace(/\\\\/g,"\\"))}cache5=tips.length>10?tips:FALLBACK}catch{cache5=FALLBACK}return cache5}function randomTip(prev){let t2=loadTips();if(t2.length<2)return t2[0]??"";let pick2=t2[Math.floor(Math.random()*t2.length)];while(pick2===prev)pick2=t2[Math.floor(Math.random()*t2.length)];return pick2}import{readFileSync as readFileSync16,existsSync as existsSync22}from"fs";import{dirname as dirname15,join as join20}from"path";var pkgVersion=(d2,up=4)=>{let p=join20(d2,"package.json");if(existsSync22(p))return JSON.parse(readFileSync16(p,"utf8")).version;return up>0?pkgVersion(dirname15(d2),up-1):"0.0.0"},VERSION=pkgVersion(import.meta.dirname);function parseLaunch(argv){let splash=!0;for(let i=0;i<argv.length;i++){let a=argv[i];if(a==="--no-splash"){splash=!1;continue}if(a==="-c"||a==="--continue")return{mode:"resume",splash};if(a==="--resume"){let next2=argv[i+1];return next2&&!next2.startsWith("-")?{mode:"resume",sid:next2,splash}:{mode:"resume",splash}}}return{mode:"new",splash}}var HELP2=`herm \u2014 OpenTUI client for hermes-agent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "herm-tui",
3
- "version": "1.9.0-dev.23",
3
+ "version": "1.9.0-dev.24",
4
4
  "description": "A modern TUI for Hermes Agent",
5
5
  "license": "MIT",
6
6
  "repository": {