herm-tui 1.11.0-dev.13 → 1.11.0-dev.14

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 +16 -16
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -18,7 +18,7 @@ No matching component was found for:
18
18
  `);var init_perf=__esm(()=>{level=process.env.PERF??"",enabled=level==="1"||level==="verbose",verbose=level==="verbose",timings=new Map,mark=enabled?(label)=>{let start=Bun.nanoseconds();return()=>{let ms=(Bun.nanoseconds()-start)/1e6,t2=timings.get(label);if(t2){if(t2.count++,t2.total+=ms,ms<t2.min)t2.min=ms;if(ms>t2.max)t2.max=ms;t2.last=ms}else timings.set(label,{count:1,total:ms,min:ms,max:ms,last:ms});if(verbose)log(`\u23F1 ${label}: ${ms.toFixed(2)}ms`);return ms}}:(_2)=>noop2,stages=[],counters=new Map,count=enabled?(label,n=1)=>{counters.set(label,(counters.get(label)??0)+n)}:(_label,_n)=>{},snapshots=[],mem=enabled?(label)=>{let m2=process.memoryUsage();snapshots.push({label,rss:m2.rss,heap:m2.heapUsed,external:m2.external,ts:Date.now()}),log(`\uD83D\uDCCA [${label}] RSS=${mb(m2.rss)}MB heap=${mb(m2.heapUsed)}MB ext=${mb(m2.external)}MB`)}:(_2)=>{},monitor=enabled?(ms=1e4)=>{let id=setInterval(()=>{let m2=process.memoryUsage(),gc=Bun.gc(!1);log(`\x1B[90m[mem] RSS=${mb(m2.rss)}MB heap=${mb(m2.heapUsed)}/${mb(m2.heapTotal)}MB ext=${mb(m2.external)}MB gcRuns=${gc?.eden_collections??"?"}/${gc?.full_collections??"?"}\x1B[0m`)},ms);return()=>clearInterval(id)}:(_ms)=>noop2,renders=new Map,onRender=enabled?(id,phase,actual)=>{let r=renders.get(id);if(r){if(r.count++,r.total+=actual,actual>r.max)r.max=actual;r.last=actual}else renders.set(id,{count:1,total:actual,max:actual,last:actual});if(verbose&&actual>1)log(`\uD83D\uDD04 [${id}] ${phase}: ${actual.toFixed(2)}ms`)}:(_id,_phase,_actual)=>{};if(enabled)process.on("exit",report),process.on("SIGINT",()=>{report(),process.exit(0)})});var EikonCompatibilityError,EikonValidationError;var init_errors=__esm(()=>{EikonCompatibilityError=class EikonCompatibilityError extends Error{problems;constructor(problems){super(problems.map((problem)=>problem.message).join(`
19
19
  `));this.name="EikonCompatibilityError",this.problems=problems}};EikonValidationError=class EikonValidationError extends Error{problems;constructor(problems){super(problems.map((problem)=>problem.message).join(`
20
20
  `));this.name="EikonValidationError",this.problems=problems}}});function canonicalSignal(state){return`state.${state}`}function defaultSignalMappings(){return Object.fromEntries(CANONICAL_STATES.map((state)=>[canonicalSignal(state),state==="idle"?{clip:state}:{clip:state,fallback:"state.idle"}]))}function majorOf(version){if(typeof version==="number")return version;return Number(version.split(".")[0])}function validateLaunchCompatibility(version,extensions={},support={}){let problems=[],major=majorOf(version);if(!Number.isFinite(major)||major!==LAUNCH_MAJOR_VERSION)problems.push({code:"unsupported-version",version:String(version),message:`unsupported Eikon stream version ${version}`});let known=new Set([...support.optional??[],...support.required??[]]);for(let ext of extensions.required??[]){if(known.has(ext))continue;problems.push({code:"unknown-required-extension",extension:ext,message:`unknown required Eikon extension ${ext}`})}return problems}function assertLaunchCompatibility(version,extensions,support){let problems=validateLaunchCompatibility(version,extensions,support);if(problems.length)throw new EikonCompatibilityError(problems)}var LAUNCH_MAJOR_VERSION=1,LAUNCH_MEDIA_TYPE="application/vnd.eikon.stream+jsonl",LAUNCH_STREAM_EXTENSION=".eikon",RUNTIME_ENCODINGS,PACKAGE_KIND="eikon.package",PACKAGE_SCHEMA_VERSION="1.0",CATALOG_KIND="eikon.catalog.entry",CATALOG_SCHEMA_VERSION="1.0",CANONICAL_STATES,CANONICAL_SIGNALS;var init_shape=__esm(()=>{init_errors();RUNTIME_ENCODINGS=["identity","gzip"],CANONICAL_STATES=["idle","listening","thinking","speaking","working","error"],CANONICAL_SIGNALS=CANONICAL_STATES.map((state)=>`state.${state}`)});var STATES,DEFAULT_CATALOG="https://eikon.liftaris.dev/eikons";var init_spec=__esm(()=>{init_shape();STATES=CANONICAL_STATES});function row(line,n){try{let value=JSON.parse(line);if(!value||typeof value!=="object"||Array.isArray(value))fail(n,"record must be an object");return value}catch(err){if(err instanceof EikonValidationError)throw err;let msg=err instanceof Error?err.message:String(err);throw new EikonValidationError([{code:"stream-json",path:`line ${n}`,message:`malformed JSON on line ${n}: ${msg}`}])}}function checkCompatibility(version,extensions,n){try{assertLaunchCompatibility(version,extensions)}catch(err){if(err instanceof EikonCompatibilityError)throw new EikonValidationError(err.problems.map((problem)=>({code:problem.code,path:`line ${n}`,message:`line ${n}: ${problem.message}`})));throw err}}function readHeader(record,n){if(record.type!=="header")fail(n,"first record must be header");for(let key2 of Object.keys(record))if(FORBIDDEN_HEADER_KEYS.has(key2))fail(n,`header field "${key2}" is not allowed in launch runtime streams`);if(record.eikon!==LAUNCH_MAJOR_VERSION)fail(n,`header.eikon must be ${LAUNCH_MAJOR_VERSION}`);let sizeRaw=record.size;if(!isObj(sizeRaw))fail(n,"header.size object required");let size=sizeRaw;if(!isInt(size.cols)||size.cols<=0)fail(n,"header.size.cols positive integer required");if(!isInt(size.rows)||size.rows<=0)fail(n,"header.size.rows positive integer required");if(!isStr(record.defaultSignal)||!isSignal(record.defaultSignal))fail(n,"header.defaultSignal namespaced string required");let{defaultSignal,signals:signalsRaw}=record;if(!isObj(signalsRaw))fail(n,"header.signals object required");let signals=signalsRaw;if(!signals[defaultSignal])fail(n,"header.defaultSignal must be declared in header.signals");for(let[signal,raw]of Object.entries(signals)){if(!isSignal(signal))fail(n,`header.signals key "${signal}" must be namespaced`);if(!isObj(raw))fail(n,`header.signals.${signal} object required`);let mapping=raw;if(!isStr(mapping.clip))fail(n,`header.signals.${signal}.clip string required`);if(mapping.fallback!=null&&(!isStr(mapping.fallback)||!isSignal(mapping.fallback)))fail(n,`header.signals.${signal}.fallback namespaced string required`)}return record}function readClip(record,n){if(!isStr(record.name))fail(n,"clip.name string required");if(!isNum(record.fps)||record.fps<=0)fail(n,"clip.fps positive number required");if(record.frameCount!=null&&(!isInt(record.frameCount)||record.frameCount<0))fail(n,"clip.frameCount non-negative integer required");if(record.loopFrom!=null&&(!isInt(record.loopFrom)||record.loopFrom<0))fail(n,"clip.loopFrom non-negative integer required");if("fallback"in record)fail(n,"clip.fallback is not part of the launch contract; use header.signals fallback");return record}function readFrame(record,n){if(!isStr(record.clip))fail(n,"frame.clip string required");if(!isInt(record.index)||record.index<0)fail(n,"frame.index non-negative integer required");if(!isRows(record.rows))fail(n,"frame.rows string array required");return record}function readExtension(record,n){if(!isStr(record.extension))fail(n,"extension.extension string required");if(!("payload"in record))fail(n,"extension.payload required");return record}function checkFrameSize(record,header,n){if(record.rows.length!==header.size.rows)fail(n,`frame height ${record.rows.length} does not match size.rows ${header.size.rows}`);for(let r of record.rows)if(Array.from(r).length!==header.size.cols)fail(n,`frame width ${Array.from(r).length} does not match size.cols ${header.size.cols}`)}function getState(states,clip,line){let state=states.get(clip);if(state===void 0)fail(line,`frame for clip "${clip}" before clip declaration`);return state}function validateFallbackGraph(header){for(let signal of Object.keys(header.signals)){let seen=new Set,current=signal;while(current){if(seen.has(current))failPath(`header.signals.${signal}.fallback`,`fallback cycle detected: ${[...seen,current].join(" -> ")}`);seen.add(current),current=header.signals[current]?.fallback}}}function resolveSignalInternal(header,clips,signal){let fallbackPath=[],seen=new Set,current=header.signals[signal]?signal:header.defaultSignal;if(!header.signals[signal])fallbackPath.push(signal);while(!0){if(seen.has(current))failPath(`header.signals.${signal}.fallback`,`fallback cycle detected: ${[...seen,current].join(" -> ")}`);seen.add(current),fallbackPath.push(current);let mapping=header.signals[current];if(!mapping)failPath(`header.signals.${current}`,"signal mapping missing");let resolvedMapping=mapping;if(clips.has(resolvedMapping.clip))return{signal:current,clip:resolvedMapping.clip,mapping:resolvedMapping,fallbackPath};let next=resolvedMapping.fallback??header.defaultSignal;if(next===current)failPath(`header.signals.${current}`,`signal maps to missing clip "${resolvedMapping.clip}" and fallback loops to itself`);current=next}}function validateSignalResolution(header,clips){validateFallbackGraph(header);for(let signal of Object.keys(header.signals))resolveSignalInternal(header,clips,signal);resolveSignalInternal(header,clips,header.defaultSignal)}function parseLaunchStream(text3){let lines3=text3.split(`
21
- `),records=[],head,building=new Map;for(let i=0;i<lines3.length;i++){let line=lines3[i];if(!line?.trim())continue;let n=i+1,rec=row(line,n);if(!head){head=readHeader(rec,n),checkCompatibility(head.eikon,head.extensions,n),records.push(head);continue}if(rec.type==="header")fail(n,"duplicate header record");if(rec.type==="clip"){let item=readClip(rec,n);if(checkCompatibility(head.eikon,item.extensions,n),building.has(item.name))fail(n,`duplicate clip "${item.name}"`);building.set(item.name,{record:item,frames:[],seen:new Set}),records.push(item);continue}if(rec.type==="frame"){let item=readFrame(rec,n);checkCompatibility(head.eikon,item.extensions,n),checkFrameSize(item,head,n);let state=getState(building,item.clip,n);if(state.seen.has(item.index))fail(n,`duplicate frame ${item.index} for clip "${item.clip}"`);if(item.index!==state.frames.length)fail(n,`frame index ${item.index} out of order for clip "${item.clip}"`);state.seen.add(item.index),state.frames.push(item.rows),records.push(item);continue}if(rec.type==="extension"){let item=readExtension(rec,n);records.push(item);continue}fail(n,"record.type must be header, clip, frame, or extension")}if(!head)fail(1,"empty stream");let header=head,clips=new Map,states=[];for(let[name,state]of building){let expected=state.record.frameCount;if(expected!=null&&expected!==state.frames.length)throw new EikonValidationError([{code:"stream-frame-count",path:`clip ${name}`,message:`clip "${name}": frameCount=${expected} but got ${state.frames.length}`}]);if(state.record.loopFrom!=null&&state.record.loopFrom>state.frames.length)failPath(`clip ${name}`,`loopFrom ${state.record.loopFrom} exceeds frame count ${state.frames.length}`);states.push(name),clips.set(name,{fps:state.record.fps,frames:state.frames,loopFrom:Math.max(0,Math.min(state.record.loopFrom??0,state.frames.length)),...state.record.color?{color:state.record.color}:{}})}validateSignalResolution(header,clips);let meta={version:header.eikon,name:header.title??header.id??"unnamed",title:header.title,author:header.author?.name,description:header.description,width:header.size.cols,height:header.size.rows,states};return{header,meta,clips,records}}function resolveSignal(stream,signal){let requested=isSignal(signal)?signal:stream.header.defaultSignal;return resolveSignalInternal(stream.header,stream.clips,requested)}function serializeLaunchStream(records){if(!records.length)throw new EikonValidationError([{code:"stream",path:"records",message:"stream requires records"}]);let text3=records.map((record)=>JSON.stringify(record)).join(`
21
+ `),records=[],head,building=new Map;for(let i=0;i<lines3.length;i++){let line=lines3[i];if(!line?.trim())continue;let n=i+1,rec2=row(line,n);if(!head){head=readHeader(rec2,n),checkCompatibility(head.eikon,head.extensions,n),records.push(head);continue}if(rec2.type==="header")fail(n,"duplicate header record");if(rec2.type==="clip"){let item=readClip(rec2,n);if(checkCompatibility(head.eikon,item.extensions,n),building.has(item.name))fail(n,`duplicate clip "${item.name}"`);building.set(item.name,{record:item,frames:[],seen:new Set}),records.push(item);continue}if(rec2.type==="frame"){let item=readFrame(rec2,n);checkCompatibility(head.eikon,item.extensions,n),checkFrameSize(item,head,n);let state=getState(building,item.clip,n);if(state.seen.has(item.index))fail(n,`duplicate frame ${item.index} for clip "${item.clip}"`);if(item.index!==state.frames.length)fail(n,`frame index ${item.index} out of order for clip "${item.clip}"`);state.seen.add(item.index),state.frames.push(item.rows),records.push(item);continue}if(rec2.type==="extension"){let item=readExtension(rec2,n);records.push(item);continue}fail(n,"record.type must be header, clip, frame, or extension")}if(!head)fail(1,"empty stream");let header=head,clips=new Map,states=[];for(let[name,state]of building){let expected=state.record.frameCount;if(expected!=null&&expected!==state.frames.length)throw new EikonValidationError([{code:"stream-frame-count",path:`clip ${name}`,message:`clip "${name}": frameCount=${expected} but got ${state.frames.length}`}]);if(state.record.loopFrom!=null&&state.record.loopFrom>state.frames.length)failPath(`clip ${name}`,`loopFrom ${state.record.loopFrom} exceeds frame count ${state.frames.length}`);states.push(name),clips.set(name,{fps:state.record.fps,frames:state.frames,loopFrom:Math.max(0,Math.min(state.record.loopFrom??0,state.frames.length)),...state.record.color?{color:state.record.color}:{}})}validateSignalResolution(header,clips);let meta={version:header.eikon,name:header.title??header.id??"unnamed",title:header.title,author:header.author?.name,description:header.description,width:header.size.cols,height:header.size.rows,states};return{header,meta,clips,records}}function resolveSignal(stream,signal){let requested=isSignal(signal)?signal:stream.header.defaultSignal;return resolveSignalInternal(stream.header,stream.clips,requested)}function serializeLaunchStream(records){if(!records.length)throw new EikonValidationError([{code:"stream",path:"records",message:"stream requires records"}]);let text3=records.map((record)=>JSON.stringify(record)).join(`
22
22
  `)+`
23
23
  `;return parseLaunchStream(text3),text3}var FORBIDDEN_HEADER_KEYS,fail=(line,message)=>{throw new EikonValidationError([{code:"stream",path:`line ${line}`,message:`line ${line}: ${message}`}])},failPath=(path4,message)=>{throw new EikonValidationError([{code:"stream",path:path4,message:`${path4}: ${message}`}])},isNum=(value)=>typeof value==="number"&&Number.isFinite(value),isInt=(value)=>isNum(value)&&Math.trunc(value)===value,isStr=(value)=>typeof value==="string"&&value.length>0,isObj=(value)=>!!value&&typeof value==="object"&&!Array.isArray(value),isRows=(value)=>Array.isArray(value)&&value.every((v2)=>typeof v2==="string"),isSignal=(value)=>value.includes(".")&&!value.startsWith(".")&&!value.endsWith(".");var init_parse=__esm(()=>{init_errors();init_shape();FORBIDDEN_HEADER_KEYS=new Set(["origin","originUrl","origin_url","source","sourceUrl","source_url","editPackageUrl","edit_package_url","generator","generatedBy","packageDigest","package_digest","poster","preview","license","provenance","platform","download","downloadUrl","download_url"])});function runtimeError(message){throw new EikonValidationError([{code:"runtime",path:"runtime",message}])}function isGzipBytes(bytes){return bytes.length>=2&&bytes[0]===31&&bytes[1]===139}function runtimeEncoding(bytes,desc){let packed=desc!==void 0,raw=desc?.encoding??(packed?"identity":isGzipBytes(bytes)?"gzip":"identity");if(raw!=="identity"&&raw!=="gzip")runtimeError(`unsupported runtime encoding: ${String(raw)}`);let gzip=isGzipBytes(bytes);if(packed&&raw==="gzip"&&!gzip)runtimeError("runtime encoding mismatch: descriptor says gzip but bytes are not gzip");if(packed&&raw==="identity"&&gzip)runtimeError("runtime encoding mismatch: descriptor says identity but bytes are gzip");return raw}function assertBytes(bytes,opts={}){let max=opts.maxBytes??DEFAULT_RUNTIME_MAX_BYTES;if(bytes.length>max)runtimeError(`runtime stored byte limit exceeded: ${bytes.length} > ${max}`);let size=opts.descriptor?.size;if(size!=null&&bytes.length!==size)runtimeError(`runtime stored size mismatch: ${bytes.length} !== ${size}`)}function assertDecoded(bytes,opts={}){let max=opts.maxDecodedBytes??DEFAULT_RUNTIME_MAX_DECODED_BYTES;if(bytes.length>max)runtimeError(`runtime decoded byte limit exceeded: ${bytes.length} > ${max}`);let size=opts.descriptor?.decodedSize;if(size!=null&&bytes.length!==size)runtimeError(`runtime decoded size mismatch: ${bytes.length} !== ${size}`)}function utf8(bytes){try{return new TextDecoder("utf-8",{fatal:!0}).decode(bytes)}catch(err){runtimeError(`runtime UTF-8 decode failed: ${err instanceof Error?err.message:String(err)}`)}}function textBytes(text3){return new TextEncoder().encode(text3)}var DEFAULT_RUNTIME_MAX_BYTES=33554432,DEFAULT_RUNTIME_MAX_DECODED_BYTES=33554432;var init_runtime=__esm(()=>{init_errors()});import{createHash}from"crypto";import{readFileSync as readFileSync3,writeFileSync as writeFileSync3}from"fs";import{gzipSync,gunzipSync}from"zlib";function sha256Bytes(bytes){return`sha256:${createHash("sha256").update(bytes).digest("hex")}`}function assertDigest(bytes,expected,label){if(expected&&sha256Bytes(bytes)!==expected)runtimeError(`runtime ${label} digest mismatch`)}function decodeRuntimeBytes(bytes,opts={}){assertBytes(bytes,opts),assertDigest(bytes,opts.descriptor?.digest,"stored");let decoded=runtimeEncoding(bytes,opts.descriptor)==="gzip"?gunzip(bytes,opts.maxDecodedBytes??DEFAULT_RUNTIME_MAX_DECODED_BYTES):bytes;return assertDecoded(decoded,opts),assertDigest(decoded,opts.descriptor?.decodedDigest,"decoded"),utf8(decoded)}function gunzip(bytes,max){try{return gunzipSync(bytes,{maxOutputLength:max})}catch(err){let msg=err instanceof Error?err.message:String(err);if(/larger than|maxOutputLength|unexpected end|incorrect header|invalid/.test(msg))runtimeError(`runtime gzip decode failed: ${msg}`);runtimeError(`runtime gzip decode failed: ${msg}`)}}function parseRuntimeBytes(bytes,opts={}){return parseLaunchStream(decodeRuntimeBytes(bytes,opts))}function decodeRuntimeFile(path4,opts={}){return decodeRuntimeBytes(readFileSync3(path4),opts)}function parseRuntimeFile(path4,opts={}){return parseRuntimeBytes(readFileSync3(path4),opts)}function encodeRuntimeText(text3,opts={}){let bytes=textBytes(text3);if((opts.encoding??"identity")==="identity")return bytes;if(opts.encoding==="gzip"){let cfg={level:opts.level??9,mtime:0};return gzipSync(bytes,cfg)}runtimeError(`unsupported runtime encoding: ${String(opts.encoding)}`)}function runtimeDescriptor(text3,opts={}){let decoded=textBytes(text3),encoding=opts.encoding??"identity",bytes=encodeRuntimeText(text3,opts);return{bytes,encoding,size:bytes.length,digest:sha256Bytes(bytes),decodedSize:decoded.length,decodedDigest:sha256Bytes(decoded)}}var init_runtime_host=__esm(()=>{init_parse();init_runtime()});function row2(line,n){try{return JSON.parse(line)}catch(e){let msg=e instanceof Error?e.message:String(e);throw Error(`eikon: malformed JSON on line ${n}: ${msg}`)}}function median(xs){let s=[...xs].sort((a,b2)=>a-b2),m2=s.length>>1;return s.length%2?s[m2]:(s[m2-1]+s[m2])/2}function parse3(text3){let lines3=text3.split(`
24
24
  `);if(!lines3[0]?.trim())throw Error("eikon: empty file (no header on line 1)");let head=row2(lines3[0],1);if(head.type==="header")return parseLaunchStream(text3);let meta={...head,version:num(head.eikon??head.version,1),name:str(head.name,"unnamed"),author:typeof head.author==="string"?head.author:void 0,glyph:typeof head.glyph==="string"?head.glyph:void 0,width:num(head.width,0),height:num(head.height,0),states:Array.isArray(head.states)?head.states:[]},clips=new Map,cur=null,seal=()=>{if(!cur)return;let fps=cur.fps??(cur.durs.length?Math.round(1000/median(cur.durs))||12:12),n=cur.frames.length,raw=cur.loop===!1?n:cur.loopFrom;clips.set(cur.name,{fps,frames:cur.frames,loopFrom:Math.max(0,Math.min(raw,n))}),cur=null};for(let i=1;i<lines3.length;i++){let line=lines3[i];if(!line||!line.trim())continue;let obj=row2(line,i+1);if(typeof obj.state==="string"){seal(),cur={name:obj.state,fps:typeof obj.fps==="number"?obj.fps:void 0,loopFrom:typeof obj.loop_from==="number"?Math.trunc(obj.loop_from):0,loop:typeof obj.loop==="boolean"?obj.loop:void 0,frames:[],durs:[]};continue}if(!cur)continue;let data2=typeof obj.data==="string"?obj.data.split(`
@@ -3466,7 +3466,7 @@ ${end.comment}`:end.comment}this.doc.range[2]=end.offset;break}default:this.erro
3466
3466
  JOIN messages m ON m.id = messages_fts.rowid
3467
3467
  JOIN sessions s ON s.id = m.session_id
3468
3468
  WHERE messages_fts MATCH ?
3469
- ORDER BY rank LIMIT ?`)?.all(m2,limit*4)??[],seen=new Set;return raw.filter((r)=>!seen.has(r.session_id)&&(seen.add(r.session_id),!0)).slice(0,limit)}finally{end()}}function rename(sid,title){let db=new Database(conn.path);try{return db.run("UPDATE sessions SET title = ? WHERE id = ?",[title,sid]),db.query("SELECT changes() AS c").get().c>0}finally{db.close()}}function remove(sid){let db=new Database(conn.path);try{return db.transaction((id)=>{if(!db.query("SELECT 1 FROM sessions WHERE id = ?").get(id))return!1;return db.run("UPDATE sessions SET parent_session_id = NULL WHERE parent_session_id = ?",[id]),db.run("DELETE FROM messages WHERE session_id = ?",[id]),db.run("DELETE FROM sessions WHERE id = ?",[id]),!0})(sid)}finally{db.close()}}var HERMES,SRC,conn,setHome=(h2)=>{let next=`${h2}/state.db`;if(conn.path===next)return;conn.path=SRC.file=next,resetDb()},stateDb=()=>{if(conn.ro)return conn.ro;try{return conn.ro=new Database(conn.path,{readwrite:!0,create:!1})}catch{return null}},resetDb=()=>{for(let s of stmts.values())s.finalize();stmts.clear(),msgCols.clear(),conn.ro?.close(),conn.ro=null},stmts,msgCols,q2=(sql)=>{let db=stateDb();if(!db)return null;let s=stmts.get(sql);if(!s)stmts.set(sql,s=db.query(sql));return s},hasMsgCol=(name)=>{let hit=msgCols.get(name);if(hit!==void 0)return hit;let db=stateDb(),ok=db?db.query("PRAGMA table_info(messages)").all().some((r)=>r.name===name):!1;return msgCols.set(name,ok),ok},cfg=(c,key3)=>`json_extract(COALESCE(${c}.model_config, '{}'), '$.${key3}')`,branched=(c)=>`${cfg(c,"_branched_from")} IS NOT NULL`,delegated=(c)=>`${cfg(c,"_delegate_from")} IS NOT NULL`,clean3=(c)=>`COALESCE(${c}.source, '') != 'tool' AND NOT (${branched(c)}) AND NOT (${delegated(c)})`,cont=(c,p)=>`(${p}.ended_at IS NOT NULL AND COALESCE(${p}.end_reason, '') = 'compression' AND ${clean3(c)})`,branch2=(c,p)=>`(NOT (${delegated(c)}) AND (${branched(c)} OR (${p}.ended_at IS NOT NULL AND COALESCE(${p}.end_reason, '') = 'branched' AND ${c}.started_at >= ${p}.ended_at)))`,sub2=(c,p)=>`(NOT (${branch2(c,p)}) AND NOT (${cont(c,p)}) AND (${p}.ended_at IS NULL OR ${c}.started_at < ${p}.ended_at OR COALESCE(${p}.end_reason, '') NOT IN ('compression', 'branched')))`,top=(s)=>`(${s}.parent_session_id IS NULL OR EXISTS (SELECT 1 FROM sessions p WHERE p.id = ${s}.parent_session_id AND ${branch2(s,"p")}))`,listable=(s)=>`(NOT (${delegated(s)}) AND ${top(s)})`,active=(s)=>`COALESCE((SELECT MAX(m.timestamp) FROM messages m WHERE m.session_id = ${s}.id), ${s}.started_at)`,order=(c)=>`CASE WHEN ${c}.end_reason = 'compression' THEN 0 WHEN ${c}.ended_at IS NULL THEN 1 ELSE 2 END ASC, ${active(c)} DESC, ${c}.started_at DESC, ${c}.id DESC`,next=(p,c="n")=>`(SELECT ${c}.id FROM sessions ${c} WHERE ${c}.parent_session_id = ${p}.id AND ${cont(c,p)} ORDER BY ${order(c)} LIMIT 1)`,marker=(raw,key3)=>{if(!raw)return!1;try{return Object.prototype.hasOwnProperty.call(JSON.parse(raw),key3)}catch{return!1}},kind=(parent2,child)=>{if(!parent2)return"root";if(marker(child.model_config,"_branched_from"))return"branch";if(parent2.end_reason==="compression"&&parent2.ended_at!=null&&child.source!=="tool"&&!marker(child.model_config,"_delegate_from"))return"continuation";if(parent2.ended_at==null||child.started_at<parent2.ended_at)return"subagent";if(parent2.end_reason==="branched")return"branch";return"subagent"},COLS,toRow=(r,lineage=null)=>({source:SRC,id:r.id,sessionSource:r.source,model:r.model,billing_provider:r.billing_provider,started_at:r.started_at,ended_at:r.ended_at,end_reason:r.end_reason,message_count:r.message_count,tool_call_count:r.tool_call_count,input_tokens:r.input_tokens,output_tokens:r.output_tokens,cache_read_tokens:r.cache_read_tokens,cache_write_tokens:r.cache_write_tokens,reasoning_tokens:r.reasoning_tokens,estimated_cost_usd:r.estimated_cost_usd,title:r.title,lastMessage:r.lastMessage,last_active:r.last_active,parent_session_id:r.parent_session_id,subagent_count:r.subagent_count,lineage_root_id:lineage}),one2=(id)=>q2(`SELECT ${COLS} FROM sessions s WHERE s.id = ?`)?.get(id)??null,byId=(id)=>{let r=one2(id);return r?toRow(r):null},lastReal=()=>{let hit=q2(`
3469
+ ORDER BY rank LIMIT ?`)?.all(m2,limit*4)??[],seen=new Set;return raw.filter((r)=>!seen.has(r.session_id)&&(seen.add(r.session_id),!0)).slice(0,limit)}finally{end()}}function rename(sid,title){let db=new Database(conn.path);try{return db.run("UPDATE sessions SET title = ? WHERE id = ?",[title,sid]),db.query("SELECT changes() AS c").get().c>0}finally{db.close()}}function remove(sid){let db=new Database(conn.path);try{return db.transaction((id)=>{if(!db.query("SELECT 1 FROM sessions WHERE id = ?").get(id))return!1;return db.run("UPDATE sessions SET parent_session_id = NULL WHERE parent_session_id = ?",[id]),db.run("DELETE FROM messages WHERE session_id = ?",[id]),db.run("DELETE FROM sessions WHERE id = ?",[id]),!0})(sid)}finally{db.close()}}var HERMES,SRC,conn,setHome=(h2)=>{let next=`${h2}/state.db`;if(conn.path===next)return;conn.path=SRC.file=next,resetDb()},stateDb=()=>{if(conn.ro)return conn.ro;try{return conn.ro=new Database(conn.path,{readwrite:!0,create:!1})}catch{return null}},resetDb=()=>{for(let s of stmts.values())s.finalize();stmts.clear(),msgCols.clear(),conn.ro?.close(),conn.ro=null},stmts,msgCols,q2=(sql)=>{let db=stateDb();if(!db)return null;let s=stmts.get(sql);if(!s)stmts.set(sql,s=db.query(sql));return s},hasMsgCol=(name)=>{let hit=msgCols.get(name);if(hit!==void 0)return hit;let db=stateDb(),ok=db?db.query("PRAGMA table_info(messages)").all().some((r)=>r.name===name):!1;return msgCols.set(name,ok),ok},cfg=(c,key3)=>`json_extract(COALESCE(${c}.model_config, '{}'), '$.${key3}')`,branched=(c)=>`${cfg(c,"_branched_from")} IS NOT NULL`,delegated=(c)=>`${cfg(c,"_delegate_from")} IS NOT NULL`,clean4=(c)=>`COALESCE(${c}.source, '') != 'tool' AND NOT (${branched(c)}) AND NOT (${delegated(c)})`,cont=(c,p)=>`(${p}.ended_at IS NOT NULL AND COALESCE(${p}.end_reason, '') = 'compression' AND ${clean4(c)})`,branch2=(c,p)=>`(NOT (${delegated(c)}) AND (${branched(c)} OR (${p}.ended_at IS NOT NULL AND COALESCE(${p}.end_reason, '') = 'branched' AND ${c}.started_at >= ${p}.ended_at)))`,sub2=(c,p)=>`(NOT (${branch2(c,p)}) AND NOT (${cont(c,p)}) AND (${p}.ended_at IS NULL OR ${c}.started_at < ${p}.ended_at OR COALESCE(${p}.end_reason, '') NOT IN ('compression', 'branched')))`,top=(s)=>`(${s}.parent_session_id IS NULL OR EXISTS (SELECT 1 FROM sessions p WHERE p.id = ${s}.parent_session_id AND ${branch2(s,"p")}))`,listable=(s)=>`(NOT (${delegated(s)}) AND ${top(s)})`,active=(s)=>`COALESCE((SELECT MAX(m.timestamp) FROM messages m WHERE m.session_id = ${s}.id), ${s}.started_at)`,order=(c)=>`CASE WHEN ${c}.end_reason = 'compression' THEN 0 WHEN ${c}.ended_at IS NULL THEN 1 ELSE 2 END ASC, ${active(c)} DESC, ${c}.started_at DESC, ${c}.id DESC`,next=(p,c="n")=>`(SELECT ${c}.id FROM sessions ${c} WHERE ${c}.parent_session_id = ${p}.id AND ${cont(c,p)} ORDER BY ${order(c)} LIMIT 1)`,marker=(raw,key3)=>{if(!raw)return!1;try{return Object.prototype.hasOwnProperty.call(JSON.parse(raw),key3)}catch{return!1}},kind=(parent2,child)=>{if(!parent2)return"root";if(marker(child.model_config,"_branched_from"))return"branch";if(parent2.end_reason==="compression"&&parent2.ended_at!=null&&child.source!=="tool"&&!marker(child.model_config,"_delegate_from"))return"continuation";if(parent2.ended_at==null||child.started_at<parent2.ended_at)return"subagent";if(parent2.end_reason==="branched")return"branch";return"subagent"},COLS,toRow=(r,lineage=null)=>({source:SRC,id:r.id,sessionSource:r.source,model:r.model,billing_provider:r.billing_provider,started_at:r.started_at,ended_at:r.ended_at,end_reason:r.end_reason,message_count:r.message_count,tool_call_count:r.tool_call_count,input_tokens:r.input_tokens,output_tokens:r.output_tokens,cache_read_tokens:r.cache_read_tokens,cache_write_tokens:r.cache_write_tokens,reasoning_tokens:r.reasoning_tokens,estimated_cost_usd:r.estimated_cost_usd,title:r.title,lastMessage:r.lastMessage,last_active:r.last_active,parent_session_id:r.parent_session_id,subagent_count:r.subagent_count,lineage_root_id:lineage}),one2=(id)=>q2(`SELECT ${COLS} FROM sessions s WHERE s.id = ?`)?.get(id)??null,byId=(id)=>{let r=one2(id);return r?toRow(r):null},lastReal=()=>{let hit=q2(`
3470
3470
  WITH RECURSIVE chain(root_id, cur_id) AS (
3471
3471
  SELECT s.id, s.id FROM sessions s
3472
3472
  WHERE s.source IN ('tui', 'cli') AND ${listable("s")}
@@ -3670,8 +3670,8 @@ Please report this to https://github.com/markedjs/marked.`,e){let r="<p>An error
3670
3670
  `));break;default:if("tokens"in token&&Array.isArray(token.tokens))this.renderInlineContent(token.tokens,chunks);else if("text"in token&&typeof token.text==="string")chunks.push(this.createDefaultChunk(token.text));break}}renderInlineTokenWithStyle(token,chunks,styleGroup,link2){switch(token.type){case"text":chunks.push(this.createChunk(token.text,styleGroup,link2));break;case"escape":chunks.push(this.createChunk(token.text,styleGroup,link2));break;case"codespan":if(this._conceal)chunks.push(this.createChunk(token.text,"markup.raw",link2));else chunks.push(this.createChunk("`","markup.raw",link2)),chunks.push(this.createChunk(token.text,"markup.raw",link2)),chunks.push(this.createChunk("`","markup.raw",link2));break;default:this.renderInlineToken(token,chunks);break}}applyMargins(renderable,marginTop,marginBottom){renderable.marginTop=marginTop,renderable.marginBottom=marginBottom}createMarkdownCodeRenderable(content,id,marginBottom=0,onChunks=this._linkifyMarkdownChunks,baseHighlight,initialStyledText){return new CodeRenderable(this.ctx,{id,content,filetype:"markdown",syntaxStyle:this._syntaxStyle,fg:this._fg,bg:this._bg,conceal:this._conceal,drawUnstyledText:initialStyledText!==void 0,streaming:!0,initialStyledText,baseHighlight,onChunks,treeSitterClient:this._treeSitterClient,width:"100%",marginBottom})}getBlockquoteContent(token){return"text"in token&&typeof token.text==="string"&&token.text?token.text:" "}getBlockquoteBorderColor(){return this.getStyle("conceal")?.fg??this.getStyle("default")?.fg??this._fg??"#FFFFFF"}createBlockquoteRenderable(token,id,marginBottom=0){let renderable=new BoxRenderable(this.ctx,{id,width:"100%",border:["left"],borderColor:this.getBlockquoteBorderColor(),paddingLeft:1,flexShrink:0,marginBottom});return renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token),`${id}-content`,0,this._linkifyMarkdownChunks,"markup.quote")),renderable}createListRenderable(token,id,marginBottom=0){let list=new BoxRenderable(this.ctx,{id,width:"100%",flexDirection:"column",flexShrink:0,marginBottom});for(let item of this.getListItemInputs(token,id))list.add(this.createListItemRenderable(item));return list}getListItemInputs(token,id){let items=token.items??[],start=token.start===""||token.start===void 0||token.start===null?1:Number(token.start),markerWidth=Math.max(1,...items.map((_2,index)=>(token.ordered?`${start+index}.`:"-").length));return items.map((item,index)=>({item,marker:token.ordered?`${start+index}.`:"-",markerWidth,id:`${id}-item-${index}`}))}applyListRenderable(renderable,token,previousToken,id,marginBottom=0){if(!(renderable instanceof BoxRenderable))return!1;renderable.marginBottom=marginBottom;let inputs=this.getListItemInputs(token,id),previousItems=previousToken?.items??[],rows=renderable.getChildren();for(let index=0;index<inputs.length;index+=1){let input=inputs[index],existing=rows[index];if(existing instanceof BoxRenderable&&this.applyListItemRenderable(existing,input,previousItems[index]))continue;existing?.destroyRecursively(),renderable.add(this.createListItemRenderable(input),index)}for(let index=rows.length-1;index>=inputs.length;index-=1)rows[index]?.destroyRecursively();return!0}createListItemRenderable(input){let row=new BoxRenderable(this.ctx,{id:input.id,width:"100%",flexDirection:"row",flexShrink:0,marginBottom:/\n[ \t]*\n$/.test(input.item.raw)?1:0});row.add(new TextRenderable(this.ctx,{id:`${input.id}-marker`,content:new StyledText([this.createChunk(input.marker.padStart(input.markerWidth)+" ","markup.list")]),width:input.markerWidth+1,flexShrink:0}));let content=new BoxRenderable(this.ctx,{id:`${input.id}-content`,flexDirection:"column",flexGrow:1,flexShrink:1});row.add(content);let pendingMarginTop=0;for(let index=0;index<input.item.tokens.length;index+=1){let child=input.item.tokens[index];if(!child)continue;if(child.type==="checkbox")continue;if(child.type==="space"){pendingMarginTop=Math.max(pendingMarginTop,1);continue}let renderable=this.createListChildRenderable(child,`${input.id}-child-${index}`);if(!renderable)continue;renderable.marginTop=child.type==="list"?0:pendingMarginTop,pendingMarginTop=0,content.add(renderable)}return row}applyListItemRenderable(row,input,previousItem){this.applyListItemMarker(row,input);let content=row.getChildren()[1];if(!(content instanceof BoxRenderable))return!1;if(previousItem&&previousItem.raw===input.item.raw)return!0;return this.applyListItemChildren(content,input.item,previousItem,input.id)}applyListItemChildren(content,item,previousItem,id){let previousTokens=previousItem?this.getRenderableListItemTokens(previousItem):[],children=content.getChildren(),childIndex=0,pendingMarginTop=0;for(let tokenIndex=0;tokenIndex<item.tokens.length;tokenIndex+=1){let token=item.tokens[tokenIndex];if(!token)continue;if(token.type==="checkbox")continue;if(token.type==="space"){pendingMarginTop=Math.max(pendingMarginTop,1);continue}let existing=children[childIndex],childId=`${id}-child-${tokenIndex}`,marginTop=token.type==="list"?0:pendingMarginTop;if(pendingMarginTop=0,!existing){let renderable=this.createListChildRenderable(token,childId);if(!renderable)return!1;renderable.marginTop=marginTop,content.add(renderable,childIndex),childIndex+=1;continue}if(!this.applyListChildRenderable(existing,token,previousTokens[childIndex],childId))return!1;existing.marginTop=marginTop,childIndex+=1}return this.destroyListItemChildrenAfter(content,childIndex),!0}getRenderableListItemTokens(item){let tokens=[];for(let token of item.tokens){if(token.type==="checkbox"||token.type==="space")continue;tokens.push(token)}return tokens}applyListChildRenderable(renderable,token,previousToken,id){if((token.type==="text"||token.type==="paragraph")&&renderable instanceof CodeRenderable)return this.applyMarkdownCodeRenderable(renderable,this.normalizeScrollbackMarkdownBlockRaw(token.raw),0),!0;if(token.type==="list"&&renderable instanceof BoxRenderable)return this.applyListRenderable(renderable,token,previousToken,id);if(token.type==="code"&&renderable instanceof CodeRenderable)return this.applyCodeBlockRenderable(renderable,token,0),!0;return previousToken?.raw===token.raw}destroyListItemChildrenAfter(content,index){let children=content.getChildren();for(let i=children.length-1;i>=index;i-=1)children[i]?.destroyRecursively()}applyListItemMarker(row,input){let marker=row.getChildren()[0];if(!(marker instanceof TextRenderable))return;let marginBottom=/\n[ \t]*\n$/.test(input.item.raw)?1:0,markerWidth=input.markerWidth+1,markerText=input.marker.padStart(input.markerWidth)+" ";if(row.marginBottom!==marginBottom)row.marginBottom=marginBottom;if(marker.width!==markerWidth)marker.width=markerWidth;if(marker.chunks[0]?.text!==markerText)marker.content=new StyledText([this.createChunk(markerText,"markup.list")])}createListChildRenderable(token,id){if(token.type==="text"||token.type==="paragraph")return this.createMarkdownCodeRenderable(this.normalizeScrollbackMarkdownBlockRaw(token.raw),id,0,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token));if(token.type==="list")return this.createListRenderable(token,id);if(token.type==="code")return this.createCodeRenderable(token,id);if(token.type==="blockquote")return this.createBlockquoteRenderable(token,id);if(token.type==="hr")return this.createHorizontalRuleRenderable(id);if(token.type==="table")return this.createTableBlock(token,id).renderable;return token.raw?this.createMarkdownCodeRenderable(token.raw,id,0,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token)):null}createHorizontalRuleRenderable(id,marginBottom=0){return new BoxRenderable(this.ctx,{id,width:"100%",height:1,border:["top"],borderColor:this.getStyle("conceal")?.fg??this._fg??"#888888",flexShrink:0,marginBottom})}createCodeRenderable(token,id,marginBottom=0){return new CodeRenderable(this.ctx,{id,content:token.text,filetype:infoStringToFiletype(token.lang??""),syntaxStyle:this._syntaxStyle,fg:this._fg,bg:this._bg,conceal:this._concealCode,drawUnstyledText:!this._streaming,streaming:this._streaming,treeSitterClient:this._treeSitterClient,width:"100%",marginBottom})}applyMarkdownCodeRenderable(renderable,content,marginBottom,baseHighlight,initialStyledText){renderable.initialStyledText=initialStyledText,renderable.filetype="markdown",renderable.syntaxStyle=this._syntaxStyle,renderable.fg=this._fg,renderable.bg=this._bg,renderable.conceal=this._conceal,renderable.drawUnstyledText=initialStyledText!==void 0,renderable.streaming=!0,renderable.baseHighlight=baseHighlight,renderable.content=content,renderable.marginBottom=marginBottom}applyBlockquoteRenderable(renderable,token,marginBottom){if(!(renderable instanceof BoxRenderable))return;renderable.borderColor=this.getBlockquoteBorderColor(),renderable.marginBottom=marginBottom;let child=renderable.getChildren()[0];if(child instanceof CodeRenderable){this.applyMarkdownCodeRenderable(child,this.getBlockquoteContent(token),0,"markup.quote");return}for(let existing of renderable.getChildren())existing.destroyRecursively();renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token),`${renderable.id}-content`,0,this._linkifyMarkdownChunks,"markup.quote"))}applyCodeBlockRenderable(renderable,token,marginBottom){if(!(renderable instanceof CodeRenderable))return;renderable.filetype=infoStringToFiletype(token.lang??""),renderable.syntaxStyle=this._syntaxStyle,renderable.fg=this._fg,renderable.bg=this._bg,renderable.conceal=this._concealCode,renderable.drawUnstyledText=!this._streaming,renderable.streaming=this._streaming,renderable.content=token.text,renderable.marginBottom=marginBottom}shouldRenderSeparately(token){return token.type==="code"||token.type==="table"||token.type==="blockquote"||token.type==="hr"}getInterBlockMargin(token,nextToken){if(!nextToken)return 0;if(this.shouldRenderSeparately(token))return 1;if(!this.shouldRenderSeparately(nextToken))return 0;return TRAILING_MARKDOWN_BLOCK_NEWLINES_RE.test(token.raw)?0:1}applyInterBlockMargin(state,token,nextToken){if(state.tracksInterBlockMargin===!1)return;state.renderable.marginBottom=this.getInterBlockMargin(token,nextToken)}createMarkdownBlockToken(raw){return{type:"paragraph",raw,text:raw,tokens:[]}}normalizeMarkdownBlockRaw(raw){return raw.replace(TRAILING_MARKDOWN_BLOCK_BREAKS_RE,`
3671
3671
  `)}normalizeScrollbackMarkdownBlockRaw(raw){return raw.replace(TRAILING_MARKDOWN_BLOCK_NEWLINES_RE,"")}isCodeBlockOnlyRenderer(){return this._renderNode?.codeBlockOnly===!0}buildRenderableTokens(tokens){if(this._renderNode&&!this.isCodeBlockOnlyRenderer())return tokens.filter((token)=>token.type!=="space");let renderTokens=[],markdownRaw="",flushMarkdownRaw=()=>{if(markdownRaw.length===0)return;let normalizedRaw=this.normalizeMarkdownBlockRaw(markdownRaw);if(normalizedRaw.length>0)renderTokens.push(this.createMarkdownBlockToken(normalizedRaw));markdownRaw=""};for(let i=0;i<tokens.length;i+=1){let token=tokens[i];if(token.type==="space"){if(markdownRaw.length===0)continue;let nextIndex=i+1;while(nextIndex<tokens.length&&tokens[nextIndex].type==="space")nextIndex+=1;let nextToken=tokens[nextIndex];if(nextToken&&!this.shouldRenderSeparately(nextToken))markdownRaw+=token.raw;continue}if(this.shouldRenderSeparately(token)){flushMarkdownRaw(),renderTokens.push(token);continue}markdownRaw+=token.raw}return flushMarkdownRaw(),renderTokens}buildTopLevelRenderBlocks(tokens){let blocks=[],gapBefore="";for(let i=0;i<tokens.length;i+=1){let token=tokens[i];if(token.type==="space"){gapBefore+=token.raw;continue}let prev=blocks[blocks.length-1],marginTop=prev&&this.shouldAddTopLevelMargin(prev.token,token,gapBefore)?1:0;blocks.push({token,sourceTokenEnd:i+1,marginTop}),gapBefore=""}return blocks}shouldAddTopLevelMargin(prev,current,gapBefore){if(this.isSeparatedTopLevelBlock(prev)||this.isSeparatedTopLevelBlock(current))return!0;if(prev.type!=="paragraph"||current.type!=="paragraph")return!1;return TRAILING_MARKDOWN_BLOCK_BREAKS_RE.test(prev.raw+gapBefore)}isSeparatedTopLevelBlock(token){return token.type==="heading"||token.type==="list"||this.shouldRenderSeparately(token)}getTableRowsToRender(table){return table.rows}hashString(value,seed){let hash=seed>>>0;for(let i=0;i<value.length;i+=1)hash^=value.charCodeAt(i),hash=Math.imul(hash,16777619);return hash>>>0}hashTableToken(token,seed,depth=0){let hash=this.hashString(token.type,seed);if("raw"in token&&typeof token.raw==="string")return this.hashString(token.raw,hash);if("text"in token&&typeof token.text==="string")hash=this.hashString(token.text,hash);if(depth<2&&"tokens"in token&&Array.isArray(token.tokens))for(let child of token.tokens)hash=this.hashTableToken(child,hash,depth+1);return hash>>>0}getTableCellKey(cell,isHeader){let seed=isHeader?2902232141:1371922141;if(!cell)return seed;if(typeof cell.text==="string")return this.hashString(cell.text,seed);if(Array.isArray(cell.tokens)&&cell.tokens.length>0){let hash=seed^cell.tokens.length;for(let token of cell.tokens)hash=this.hashTableToken(token,hash);return hash>>>0}return(seed^2654435769)>>>0}createTableDataCellChunks(cell){let chunks=[];if(cell)this.renderInlineContent(cell.tokens,chunks);return chunks.length>0?chunks:[this.createDefaultChunk(" ")]}createTableHeaderCellChunks(cell){let chunks=[];this.renderInlineContent(cell.tokens,chunks);let baseChunks=chunks.length>0?chunks:[this.createDefaultChunk(" ")],headingStyle=this.getStyle("markup.heading")||this.getStyle("default");if(!headingStyle)return baseChunks;let headingAttributes=createTextAttributes({bold:headingStyle.bold,italic:headingStyle.italic,underline:headingStyle.underline,dim:headingStyle.dim});return baseChunks.map((chunk)=>({...chunk,fg:headingStyle.fg??chunk.fg,bg:headingStyle.bg??chunk.bg,attributes:headingAttributes}))}buildTableContentCache(table,previous,forceRegenerate=!1){let colCount=table.header.length,rowsToRender=this.getTableRowsToRender(table);if(colCount===0||rowsToRender.length===0)return{cache:null,changed:previous!==void 0};let content=[],cellKeys=[],totalRows=rowsToRender.length+1,changed=forceRegenerate||!previous;for(let rowIndex=0;rowIndex<totalRows;rowIndex+=1){let rowContent=[],rowKeys=new Uint32Array(colCount);for(let colIndex=0;colIndex<colCount;colIndex+=1){let isHeader=rowIndex===0,cell=isHeader?table.header[colIndex]:rowsToRender[rowIndex-1]?.[colIndex],cellKey=this.getTableCellKey(cell,isHeader);rowKeys[colIndex]=cellKey;let previousCellKey=previous?.cellKeys[rowIndex]?.[colIndex],previousCellContent=previous?.content[rowIndex]?.[colIndex];if(!forceRegenerate&&previousCellKey===cellKey&&Array.isArray(previousCellContent)){rowContent.push(previousCellContent);continue}changed=!0,rowContent.push(isHeader?this.createTableHeaderCellChunks(table.header[colIndex]):this.createTableDataCellChunks(cell))}content.push(rowContent),cellKeys.push(rowKeys)}if(previous&&!changed){if(previous.content.length!==content.length)changed=!0;else for(let rowIndex=0;rowIndex<content.length;rowIndex+=1)if((previous.content[rowIndex]?.length??0)!==content[rowIndex].length){changed=!0;break}}return{cache:{content,cellKeys},changed}}resolveTableStyle(options=this._tableOptions){if(options?.style==="columns")return"columns";if(options?.style==="grid")return"grid";return this._internalBlockMode==="top-level"?"columns":"grid"}usesBorderlessColumnSpacing(options=this._tableOptions){let style=this.resolveTableStyle(options),borders=options?.borders??style==="grid";return style==="columns"&&!borders}resolveTableRenderableOptions(){let style=this.resolveTableStyle(),borders=this._tableOptions?.borders??style==="grid";return{columnWidthMode:this._tableOptions?.widthMode??(style==="columns"?"content":"full"),columnFitter:this._tableOptions?.columnFitter??"proportional",wrapMode:this._tableOptions?.wrapMode??"word",cellPadding:this._tableOptions?.cellPadding??0,cellPaddingX:this._tableOptions?.cellPaddingX??this._tableOptions?.cellPadding??0,cellPaddingY:this._tableOptions?.cellPaddingY??this._tableOptions?.cellPadding??0,columnGap:this.usesBorderlessColumnSpacing()?2:0,border:borders,outerBorder:this._tableOptions?.outerBorder??borders,showBorders:borders,borderStyle:this._tableOptions?.borderStyle??"single",borderColor:this._tableOptions?.borderColor??this.getStyle("conceal")?.fg??"#888888",selectable:this._tableOptions?.selectable??!0}}applyTableRenderableOptions(tableRenderable,options){tableRenderable.columnWidthMode=options.columnWidthMode,tableRenderable.columnFitter=options.columnFitter,tableRenderable.wrapMode=options.wrapMode,tableRenderable.cellPaddingX=options.cellPaddingX,tableRenderable.cellPaddingY=options.cellPaddingY,tableRenderable.columnGap=options.columnGap,tableRenderable.border=options.border,tableRenderable.outerBorder=options.outerBorder,tableRenderable.showBorders=options.showBorders,tableRenderable.borderStyle=options.borderStyle,tableRenderable.borderColor=options.borderColor,tableRenderable.selectable=options.selectable}applyTableOptionsToBlocks(){let options=this.resolveTableRenderableOptions(),updated=!1;for(let state of this._blockStates)if(state.renderable instanceof TextTableRenderable)this.applyTableRenderableOptions(state.renderable,options),updated=!0;if(updated)this.requestRender()}createTextTableRenderable(content,id,marginBottom=0){let options=this.resolveTableRenderableOptions();return new TextTableRenderable(this.ctx,{id,content,width:"100%",marginBottom,columnWidthMode:options.columnWidthMode,columnFitter:options.columnFitter,wrapMode:options.wrapMode,cellPadding:options.cellPadding,cellPaddingX:options.cellPaddingX,cellPaddingY:options.cellPaddingY,columnGap:options.columnGap,border:options.border,outerBorder:options.outerBorder,showBorders:options.showBorders,borderStyle:options.borderStyle,borderColor:options.borderColor,selectable:options.selectable})}createTableBlock(table,id,marginBottom=0,previousCache,forceRegenerate=!1){let{cache}=this.buildTableContentCache(table,previousCache,forceRegenerate);if(!cache)return{renderable:this.createMarkdownCodeRenderable(table.raw,id,marginBottom)};return{renderable:this.createTextTableRenderable(cache.content,id,marginBottom),tableContentCache:cache}}getStableBlockCount(blocks,stableTokenCount){if(this._internalBlockMode!=="top-level")return 0;let stableBlockCount=0;for(let block of blocks){if(block.sourceTokenEnd<=stableTokenCount){stableBlockCount+=1;continue}break}return stableBlockCount}syncTopLevelBlockState(state,block,tableContentCache=state.tableContentCache){state.token=block.token,state.tokenRaw=block.token.raw,state.marginTop=block.marginTop,state.tableContentCache=tableContentCache}getTopLevelBlockRaw(token){if(!token.raw)return;return this.shouldRenderSeparately(token)?token.raw:this.normalizeScrollbackMarkdownBlockRaw(token.raw)}createTopLevelDefaultRenderable(block,index){let{token,marginTop}=block,id=`${this.id}-block-${index}`;if(token.type==="code"){let renderable2=this.createCodeRenderable(token,id);return renderable2.marginTop=marginTop,{renderable:renderable2,canUpdateInPlace:!0}}if(token.type==="table"){let next=this.createTableBlock(token,id);return next.renderable.marginTop=marginTop,{...next,canUpdateInPlace:!0}}if(token.type==="blockquote"){let renderable2=this.createBlockquoteRenderable(token,id);return renderable2.marginTop=marginTop,{renderable:renderable2,canUpdateInPlace:!0}}if(token.type==="list"){let renderable2=this.createListRenderable(token,id);return renderable2.marginTop=marginTop,{renderable:renderable2,canUpdateInPlace:!0}}if(token.type==="hr"){let renderable2=this.createHorizontalRuleRenderable(id);return renderable2.marginTop=marginTop,{renderable:renderable2,canUpdateInPlace:!0}}let markdownRaw=this.getTopLevelBlockRaw(token);if(!markdownRaw)return{renderable:void 0,canUpdateInPlace:!0};let renderable=this.createMarkdownCodeRenderable(markdownRaw,id,0,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token));return renderable.marginTop=marginTop,{renderable,canUpdateInPlace:!0}}createTopLevelRenderable(block,index){if(!this._renderNode)return this.createTopLevelDefaultRenderable(block,index);let custom=this.createTopLevelCustomRenderable(block,index);if(!custom.renderable)return this.createTopLevelDefaultRenderable(block,index);let marginTop=typeof custom.renderable.marginTop==="number"?Math.max(custom.renderable.marginTop,block.marginTop):block.marginTop;return this.applyMargins(custom.renderable,marginTop,0),{renderable:custom.renderable,tableContentCache:custom.tableContentCache,canUpdateInPlace:custom.canUpdateInPlace}}createDefaultRenderable(token,index,nextToken){let id=`${this.id}-block-${index}`,marginBottom=this.getInterBlockMargin(token,nextToken);if(token.type==="code")return this.createCodeRenderable(token,id,marginBottom);if(token.type==="blockquote")return this.createBlockquoteRenderable(token,id,marginBottom);if(token.type==="list")return this.createListRenderable(token,id,marginBottom);if(token.type==="hr")return this.createHorizontalRuleRenderable(id,marginBottom);if(token.type==="table")return this.createTableBlock(token,id,marginBottom).renderable;if(token.type==="space")return null;if(!token.raw)return null;return this.createMarkdownCodeRenderable(token.raw,id,marginBottom,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token))}createCustomRenderable(token,index,nextToken){let custom=this.renderCustomNode(token,()=>{return{renderable:this.createDefaultRenderable(token,index,nextToken)}});if(!custom.renderable)return{tracksInterBlockMargin:!0,canUpdateInPlace:!0};let canUpdateInPlace=custom.renderable===custom.defaultResult?.renderable;return{renderable:custom.renderable,tracksInterBlockMargin:canUpdateInPlace,canUpdateInPlace}}createTopLevelCustomRenderable(block,index){let custom=this.renderCustomNode(block.token,()=>{return this.createTopLevelDefaultRenderable(block,index)});if(!custom.renderable)return{tracksInterBlockMargin:!0,canUpdateInPlace:!0};let canUpdateInPlace=custom.renderable===custom.defaultResult?.renderable;return{renderable:custom.renderable,tableContentCache:canUpdateInPlace?custom.defaultResult?.tableContentCache:void 0,tracksInterBlockMargin:canUpdateInPlace,canUpdateInPlace}}renderCustomNode(token,createDefault){if(!this._renderNode)return{};let defaultResult,custom=this._renderNode(token,{syntaxStyle:this._syntaxStyle,conceal:this._conceal,concealCode:this._concealCode,treeSitterClient:this._treeSitterClient,defaultRender:()=>{return defaultResult=createDefault(),defaultResult.renderable??null}});return this.destroyUnusedDefaultRenderable(defaultResult?.renderable,custom??void 0),custom?{renderable:custom,defaultResult}:{}}destroyUnusedDefaultRenderable(renderable,usedRenderable){if(!renderable||renderable===usedRenderable||renderable.parent)return;renderable.destroyRecursively()}updateBlockRenderable(state,token,index,nextToken,forceListRefresh=!1){let marginBottom=this.getInterBlockMargin(token,nextToken);if(token.type==="code"){this.applyCodeBlockRenderable(state.renderable,token,marginBottom);return}if(token.type==="blockquote"){this.applyBlockquoteRenderable(state.renderable,token,marginBottom);return}if(token.type==="list"){if(!this.applyListRenderable(state.renderable,token,forceListRefresh?void 0:state.token,`${this.id}-block-${index}`,marginBottom))state.renderable.destroyRecursively(),state.renderable=this.createListRenderable(token,`${this.id}-block-${index}`,marginBottom),this.add(state.renderable,index);return}if(token.type==="hr"){state.renderable.marginBottom=marginBottom;return}if(token.type==="table"){let tableToken=token,{cache,changed}=this.buildTableContentCache(tableToken,state.tableContentCache);if(!cache){if(state.renderable instanceof CodeRenderable){this.applyMarkdownCodeRenderable(state.renderable,tableToken.raw,marginBottom),state.tableContentCache=void 0;return}state.renderable.destroyRecursively();let fallbackRenderable=this.createMarkdownCodeRenderable(tableToken.raw,`${this.id}-block-${index}`,marginBottom);this.add(fallbackRenderable,index),state.renderable=fallbackRenderable,state.tableContentCache=void 0;return}if(state.renderable instanceof TextTableRenderable){if(changed)state.renderable.content=cache.content;this.applyTableRenderableOptions(state.renderable,this.resolveTableRenderableOptions()),state.renderable.marginBottom=marginBottom,state.tableContentCache=cache;return}state.renderable.destroyRecursively();let tableRenderable=this.createTextTableRenderable(cache.content,`${this.id}-block-${index}`,marginBottom);this.add(tableRenderable,index),state.renderable=tableRenderable,state.tableContentCache=cache;return}if(state.renderable instanceof CodeRenderable){this.applyMarkdownCodeRenderable(state.renderable,this.getTopLevelBlockRaw(token)??token.raw,marginBottom,void 0,this.createInitialStyledText(token));return}state.renderable.destroyRecursively();let markdownRenderable=this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(token)??token.raw,`${this.id}-block-${index}`,marginBottom,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token));this.add(markdownRenderable,index),state.renderable=markdownRenderable}updateTopLevelBlocks(tokens,forceTableRefresh){let blocks=this.buildTopLevelRenderBlocks(tokens);this._stableBlockCount=this.getStableBlockCount(blocks,this._parseState?.stableTokenCount??0);let blockIndex=0;for(let i=0;i<blocks.length;i+=1){let block=blocks[i],existing=this._blockStates[blockIndex];if(existing&&existing.token===block.token&&!forceTableRefresh){if(existing.marginTop!==block.marginTop)this.applyMargins(existing.renderable,block.marginTop,0);this.syncTopLevelBlockState(existing,block),blockIndex++;continue}if(existing&&existing.tokenRaw===block.token.raw&&existing.token.type===block.token.type&&!forceTableRefresh){if(existing.marginTop!==block.marginTop)this.applyMargins(existing.renderable,block.marginTop,0);this.syncTopLevelBlockState(existing,block),blockIndex++;continue}if(existing&&!forceTableRefresh&&existing.canUpdateInPlace&&existing.token.type===block.token.type&&this.canUpdateBlockRenderable(existing.renderable,block.token)){if(this._renderNode){let custom=this.createTopLevelCustomRenderable(block,blockIndex);if(custom.renderable&&!custom.canUpdateInPlace){let marginTop=typeof custom.renderable.marginTop==="number"?Math.max(custom.renderable.marginTop,block.marginTop):block.marginTop;if(this.applyMargins(custom.renderable,marginTop,0),custom.renderable!==existing.renderable)existing.renderable.destroyRecursively(),this.add(custom.renderable,blockIndex);this._blockStates[blockIndex]={token:block.token,tokenRaw:block.token.raw,marginTop:block.marginTop,renderable:custom.renderable,tableContentCache:custom.tableContentCache,canUpdateInPlace:custom.canUpdateInPlace},blockIndex++;continue}this.destroyUnusedDefaultRenderable(custom.renderable)}if(this.updateBlockRenderable(existing,block.token,blockIndex,blocks[i+1]?.token),existing.renderable.marginBottom=0,existing.marginTop!==block.marginTop)this.applyMargins(existing.renderable,block.marginTop,0);this.syncTopLevelBlockState(existing,block),blockIndex++;continue}if(existing)existing.renderable.destroyRecursively();let next=this.createTopLevelRenderable(block,blockIndex);if(next.renderable)this.add(next.renderable,blockIndex),this._blockStates[blockIndex]={token:block.token,tokenRaw:block.token.raw,marginTop:block.marginTop,renderable:next.renderable,tableContentCache:next.tableContentCache,canUpdateInPlace:next.canUpdateInPlace};blockIndex++}while(this._blockStates.length>blockIndex)this._blockStates.pop().renderable.destroyRecursively()}canUpdateBlockRenderable(renderable,token){if(token.type==="code")return renderable instanceof CodeRenderable;if(token.type==="table")return renderable instanceof TextTableRenderable;if(token.type==="blockquote")return renderable instanceof BoxRenderable;if(token.type==="list")return renderable instanceof BoxRenderable;if(token.type==="hr")return renderable instanceof BoxRenderable;return renderable instanceof CodeRenderable}updateBlocks(forceTableRefresh=!1){if(this.isDestroyed)return;if(!this._content){this.clearBlockStates(),this._parseState=null,this._stableBlockCount=0;return}let trailingUnstable=this._streaming?2:0;this._parseState=parseMarkdownIncremental(this._content,this._parseState,trailingUnstable);let tokens=this._parseState.tokens;if(tokens.length===0&&this._content.length>0){this.clearBlockStates(),this._stableBlockCount=0;let fallback=this.createMarkdownCodeRenderable(this._content,`${this.id}-fallback`);this.add(fallback),this._blockStates=[{token:{type:"text",raw:this._content,text:this._content},tokenRaw:this._content,marginTop:0,renderable:fallback,tracksInterBlockMargin:!0,canUpdateInPlace:!0}];return}if(this._internalBlockMode==="top-level"){this.updateTopLevelBlocks(tokens,forceTableRefresh);return}this._stableBlockCount=0;let blockTokens=this.buildRenderableTokens(tokens),blockIndex=0;for(let i=0;i<blockTokens.length;i++){let token=blockTokens[i],nextToken=blockTokens[i+1],existing=this._blockStates[blockIndex],shouldForceRefresh=forceTableRefresh;if(existing&&existing.token===token){if(shouldForceRefresh)this.updateBlockRenderable(existing,token,blockIndex,nextToken),existing.tokenRaw=token.raw;else this.applyInterBlockMargin(existing,token,nextToken);blockIndex++;continue}if(existing&&existing.tokenRaw===token.raw&&existing.token.type===token.type){if(existing.token=token,shouldForceRefresh)this.updateBlockRenderable(existing,token,blockIndex,nextToken),existing.tokenRaw=token.raw;else this.applyInterBlockMargin(existing,token,nextToken);blockIndex++;continue}if(existing&&existing.canUpdateInPlace&&existing.token.type===token.type){let custom2=this.createCustomRenderable(token,blockIndex,nextToken);if(custom2.renderable&&!custom2.canUpdateInPlace){if(custom2.renderable!==existing.renderable)existing.renderable.destroyRecursively(),this.add(custom2.renderable,blockIndex);this._blockStates[blockIndex]={token,tokenRaw:token.raw,renderable:custom2.renderable,tracksInterBlockMargin:custom2.tracksInterBlockMargin,canUpdateInPlace:custom2.canUpdateInPlace},blockIndex++;continue}this.destroyUnusedDefaultRenderable(custom2.renderable),this.updateBlockRenderable(existing,token,blockIndex,nextToken),existing.token=token,existing.tokenRaw=token.raw,existing.tracksInterBlockMargin=!0,blockIndex++;continue}if(existing)existing.renderable.destroyRecursively();let renderable,tableContentCache,tracksInterBlockMargin=!0,canUpdateInPlace=!0,custom=this.createCustomRenderable(token,blockIndex,nextToken);if(custom.renderable)renderable=custom.renderable,tracksInterBlockMargin=custom.tracksInterBlockMargin,canUpdateInPlace=custom.canUpdateInPlace;if(!renderable)if(token.type==="table"){let tableBlock=this.createTableBlock(token,`${this.id}-block-${blockIndex}`,this.getInterBlockMargin(token,nextToken));renderable=tableBlock.renderable,tableContentCache=tableBlock.tableContentCache}else renderable=this.createDefaultRenderable(token,blockIndex,nextToken)??void 0;if(token.type==="table"&&!tableContentCache&&renderable instanceof TextTableRenderable){let{cache}=this.buildTableContentCache(token);tableContentCache=cache??void 0}if(renderable)this.add(renderable,blockIndex),this._blockStates[blockIndex]={token,tokenRaw:token.raw,renderable,tableContentCache,tracksInterBlockMargin,canUpdateInPlace};blockIndex++}while(this._blockStates.length>blockIndex)this._blockStates.pop().renderable.destroyRecursively()}clearBlockStates(){for(let state of this._blockStates)state.renderable.destroyRecursively();this._blockStates=[],this._stableBlockCount=0}rerenderBlocks(){if(this._internalBlockMode==="top-level"){this.updateBlocks(!0);return}for(let i=0;i<this._blockStates.length;i++){let state=this._blockStates[i],marginBottom=this.getInterBlockMargin(state.token,this._blockStates[i+1]?.token);if(state.token.type==="code"){this.applyCodeBlockRenderable(state.renderable,state.token,marginBottom);continue}if(state.token.type==="blockquote"){this.applyBlockquoteRenderable(state.renderable,state.token,marginBottom);continue}if(state.token.type==="list"){this.updateBlockRenderable(state,state.token,i,this._blockStates[i+1]?.token,!0);continue}if(state.token.type==="hr"){state.renderable.marginBottom=marginBottom;continue}if(state.token.type==="table"){let tableToken=state.token,{cache}=this.buildTableContentCache(tableToken,state.tableContentCache,!0);if(!cache){if(state.renderable instanceof CodeRenderable)this.applyMarkdownCodeRenderable(state.renderable,tableToken.raw,marginBottom);else{state.renderable.destroyRecursively();let fallbackRenderable=this.createMarkdownCodeRenderable(tableToken.raw,`${this.id}-block-${i}`,marginBottom);this.add(fallbackRenderable,i),state.renderable=fallbackRenderable}state.tableContentCache=void 0;continue}if(state.renderable instanceof TextTableRenderable){state.renderable.content=cache.content,this.applyTableRenderableOptions(state.renderable,this.resolveTableRenderableOptions()),state.renderable.marginBottom=marginBottom,state.tableContentCache=cache;continue}state.renderable.destroyRecursively();let tableRenderable=this.createTextTableRenderable(cache.content,`${this.id}-block-${i}`,marginBottom);this.add(tableRenderable,i),state.renderable=tableRenderable,state.tableContentCache=cache;continue}if(state.renderable instanceof CodeRenderable){this.applyMarkdownCodeRenderable(state.renderable,this.getTopLevelBlockRaw(state.token)??state.token.raw,marginBottom,void 0,this.createInitialStyledText(state.token));continue}state.renderable.destroyRecursively();let markdownRenderable=this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(state.token)??state.token.raw,`${this.id}-block-${i}`,marginBottom,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(state.token));this.add(markdownRenderable,i),state.renderable=markdownRenderable}}clearCache(){this._parseState=null,this.clearBlockStates(),this.updateBlocks(),this.requestRender()}refreshStyles(){this._styleDirty=!1,this.rerenderBlocks(),this.requestRender()}renderSelf(buffer,deltaTime){if(this._styleDirty)this._styleDirty=!1,this.rerenderBlocks();super.renderSelf(buffer,deltaTime)}}var defaultThumbBackgroundColor=RGBA.fromHex("#9a9ea3"),defaultTrackBackgroundColor=RGBA.fromHex("#252527");class SliderRenderable extends Renderable{orientation;_value;_min;_max;_viewPortSize;_backgroundColor;_foregroundColor;_onChange;constructor(ctx,options){super(ctx,{flexShrink:0,...options});this.orientation=options.orientation,this._min=options.min??0,this._max=options.max??100,this._value=options.value??this._min,this._viewPortSize=options.viewPortSize??Math.max(1,(this._max-this._min)*0.1),this._onChange=options.onChange,this._backgroundColor=options.backgroundColor?parseColor(options.backgroundColor):defaultTrackBackgroundColor,this._foregroundColor=options.foregroundColor?parseColor(options.foregroundColor):defaultThumbBackgroundColor,this.setupMouseHandling()}get value(){return this._value}set value(newValue){let clamped=Math.max(this._min,Math.min(this._max,newValue));if(clamped!==this._value)this._value=clamped,this._onChange?.(clamped),this.emit("change",{value:clamped}),this.requestRender()}get min(){return this._min}set min(newMin){if(newMin!==this._min){if(this._min=newMin,this._value<newMin)this.value=newMin;this.requestRender()}}get max(){return this._max}set max(newMax){if(newMax!==this._max){if(this._max=newMax,this._value>newMax)this.value=newMax;this.requestRender()}}set viewPortSize(size){let clampedSize=Math.max(0.01,Math.min(size,this._max-this._min));if(clampedSize!==this._viewPortSize)this._viewPortSize=clampedSize,this.requestRender()}get viewPortSize(){return this._viewPortSize}get backgroundColor(){return this._backgroundColor}set backgroundColor(value){this._backgroundColor=parseColor(value),this.requestRender()}get foregroundColor(){return this._foregroundColor}set foregroundColor(value){this._foregroundColor=parseColor(value),this.requestRender()}calculateDragOffsetVirtual(event){let trackStart=this.orientation==="vertical"?this.y:this.x,mousePos=(this.orientation==="vertical"?event.y:event.x)-trackStart,virtualMousePos=Math.max(0,Math.min((this.orientation==="vertical"?this.height:this.width)*2,mousePos*2)),virtualThumbStart=this.getVirtualThumbStart(),virtualThumbSize=this.getVirtualThumbSize();return Math.max(0,Math.min(virtualThumbSize,virtualMousePos-virtualThumbStart))}setupMouseHandling(){let isDragging=!1,dragOffsetVirtual=0;this.onMouseDown=(event)=>{event.stopPropagation(),event.preventDefault();let thumb=this.getThumbRect();if(event.x>=thumb.x&&event.x<thumb.x+thumb.width&&event.y>=thumb.y&&event.y<thumb.y+thumb.height)isDragging=!0,dragOffsetVirtual=this.calculateDragOffsetVirtual(event);else this.updateValueFromMouseDirect(event),isDragging=!0,dragOffsetVirtual=this.calculateDragOffsetVirtual(event)},this.onMouseDrag=(event)=>{if(!isDragging)return;event.stopPropagation(),this.updateValueFromMouseWithOffset(event,dragOffsetVirtual)},this.onMouseUp=(event)=>{if(isDragging)this.updateValueFromMouseWithOffset(event,dragOffsetVirtual);isDragging=!1}}updateValueFromMouseDirect(event){let trackStart=this.orientation==="vertical"?this.y:this.x,trackSize=this.orientation==="vertical"?this.height:this.width,relativeMousePos=(this.orientation==="vertical"?event.y:event.x)-trackStart,clampedMousePos=Math.max(0,Math.min(trackSize,relativeMousePos)),ratio=trackSize===0?0:clampedMousePos/trackSize,range=this._max-this._min,newValue=this._min+ratio*range;this.value=newValue}updateValueFromMouseWithOffset(event,offsetVirtual){let trackStart=this.orientation==="vertical"?this.y:this.x,trackSize=this.orientation==="vertical"?this.height:this.width,mousePos=this.orientation==="vertical"?event.y:event.x,virtualTrackSize=trackSize*2,relativeMousePos=mousePos-trackStart,virtualMousePos=Math.max(0,Math.min(trackSize,relativeMousePos))*2,virtualThumbSize=this.getVirtualThumbSize(),maxThumbStart=Math.max(0,virtualTrackSize-virtualThumbSize),desiredThumbStart=virtualMousePos-offsetVirtual;desiredThumbStart=Math.max(0,Math.min(maxThumbStart,desiredThumbStart));let ratio=maxThumbStart===0?0:desiredThumbStart/maxThumbStart,range=this._max-this._min,newValue=this._min+ratio*range;this.value=newValue}getThumbRect(){let virtualThumbSize=this.getVirtualThumbSize(),virtualThumbStart=this.getVirtualThumbStart(),realThumbStart=Math.floor(virtualThumbStart/2),realThumbSize=Math.ceil((virtualThumbStart+virtualThumbSize)/2)-realThumbStart;if(this.orientation==="vertical")return{x:this.x,y:this.y+realThumbStart,width:this.width,height:Math.max(1,realThumbSize)};else return{x:this.x+realThumbStart,y:this.y,width:Math.max(1,realThumbSize),height:this.height}}renderSelf(buffer){if(this.orientation==="horizontal")this.renderHorizontal(buffer);else this.renderVertical(buffer)}renderHorizontal(buffer){let virtualThumbSize=this.getVirtualThumbSize(),virtualThumbStart=this.getVirtualThumbStart(),virtualThumbEnd=virtualThumbStart+virtualThumbSize;buffer.fillRect(this.x,this.y,this.width,this.height,this._backgroundColor);let realStartCell=Math.floor(virtualThumbStart/2),realEndCell=Math.ceil(virtualThumbEnd/2)-1,startX=Math.max(0,realStartCell),endX=Math.min(this.width-1,realEndCell);for(let realX=startX;realX<=endX;realX++){let virtualCellStart=realX*2,virtualCellEnd=virtualCellStart+2,thumbStartInCell=Math.max(virtualThumbStart,virtualCellStart),coverage=Math.min(virtualThumbEnd,virtualCellEnd)-thumbStartInCell,char=" ";if(coverage>=2)char="\u2588";else if(thumbStartInCell===virtualCellStart)char="\u258C";else char="\u2590";for(let y2=0;y2<this.height;y2++)buffer.setCellWithAlphaBlending(this.x+realX,this.y+y2,char,this._foregroundColor,this._backgroundColor)}}renderVertical(buffer){let virtualThumbSize=this.getVirtualThumbSize(),virtualThumbStart=this.getVirtualThumbStart(),virtualThumbEnd=virtualThumbStart+virtualThumbSize;buffer.fillRect(this.x,this.y,this.width,this.height,this._backgroundColor);let realStartCell=Math.floor(virtualThumbStart/2),realEndCell=Math.ceil(virtualThumbEnd/2)-1,startY=Math.max(0,realStartCell),endY=Math.min(this.height-1,realEndCell);for(let realY=startY;realY<=endY;realY++){let virtualCellStart=realY*2,virtualCellEnd=virtualCellStart+2,thumbStartInCell=Math.max(virtualThumbStart,virtualCellStart),coverage=Math.min(virtualThumbEnd,virtualCellEnd)-thumbStartInCell,char=" ";if(coverage>=2)char="\u2588";else if(coverage>0)if(thumbStartInCell-virtualCellStart===0)char="\u2580";else char="\u2584";for(let x2=0;x2<this.width;x2++)buffer.setCellWithAlphaBlending(this.x+x2,this.y+realY,char,this._foregroundColor,this._backgroundColor)}}getVirtualThumbSize(){let virtualTrackSize=this.orientation==="vertical"?this.height*2:this.width*2,range=this._max-this._min;if(range===0)return virtualTrackSize;let viewportSize=Math.max(1,this._viewPortSize),contentSize=range+viewportSize;if(contentSize<=viewportSize)return virtualTrackSize;let thumbRatio=viewportSize/contentSize,calculatedSize=Math.floor(virtualTrackSize*thumbRatio);return Math.max(1,Math.min(calculatedSize,virtualTrackSize))}getVirtualThumbStart(){let virtualTrackSize=this.orientation==="vertical"?this.height*2:this.width*2,range=this._max-this._min;if(range===0)return 0;let valueRatio=(this._value-this._min)/range,virtualThumbSize=this.getVirtualThumbSize();return Math.round(valueRatio*(virtualTrackSize-virtualThumbSize))}}class ScrollBarRenderable extends Renderable{slider;startArrow;endArrow;orientation;_focusable=!0;_scrollSize=0;_scrollPosition=0;_viewportSize=0;_showArrows=!1;_manualVisibility=!1;_onChange;scrollStep=null;get visible(){return super.visible}set visible(value){this._manualVisibility=!0,super.visible=value}resetVisibilityControl(){this._manualVisibility=!1,this.recalculateVisibility()}get scrollSize(){return this._scrollSize}get scrollPosition(){return this._scrollPosition}get viewportSize(){return this._viewportSize}set scrollSize(value){if(value===this.scrollSize)return;this._scrollSize=value,this.recalculateVisibility(),this.updateSliderFromScrollState(),this.scrollPosition=this.scrollPosition}set scrollPosition(value){let newPosition=Math.round(Math.min(Math.max(0,value),this.scrollSize-this.viewportSize));if(newPosition!==this._scrollPosition)this._scrollPosition=newPosition,this.updateSliderFromScrollState()}set viewportSize(value){if(value===this.viewportSize)return;this._viewportSize=value,this.slider.viewPortSize=Math.max(1,this._viewportSize),this.recalculateVisibility(),this.updateSliderFromScrollState(),this.scrollPosition=this.scrollPosition}get showArrows(){return this._showArrows}set showArrows(value){if(value===this._showArrows)return;this._showArrows=value,this.startArrow.visible=value,this.endArrow.visible=value}constructor(ctx,{trackOptions,arrowOptions,orientation,showArrows=!1,...options}){super(ctx,{flexDirection:orientation==="vertical"?"column":"row",alignSelf:"stretch",alignItems:"stretch",...options});this._onChange=options.onChange,this.orientation=orientation,this._showArrows=showArrows;let scrollRange=Math.max(0,this._scrollSize-this._viewportSize),defaultStepSize=Math.max(1,this._viewportSize),stepSize=trackOptions?.viewPortSize??defaultStepSize;this.slider=new SliderRenderable(ctx,{orientation,min:0,max:scrollRange,value:this._scrollPosition,viewPortSize:stepSize,onChange:(value)=>{this._scrollPosition=Math.round(value),this._onChange?.(this._scrollPosition),this.emit("change",{position:this._scrollPosition})},...orientation==="vertical"?{width:Math.max(1,Math.min(2,this.width)),height:"100%",marginLeft:"auto"}:{width:"100%",height:1,marginTop:"auto"},flexGrow:1,flexShrink:1,...trackOptions}),this.updateSliderFromScrollState();let arrowOpts=arrowOptions?{foregroundColor:arrowOptions.backgroundColor,backgroundColor:arrowOptions.backgroundColor,attributes:arrowOptions.attributes,...arrowOptions}:{};this.startArrow=new ArrowRenderable(ctx,{alignSelf:"center",visible:this.showArrows,direction:this.orientation==="vertical"?"up":"left",height:this.orientation==="vertical"?1:1,...arrowOpts}),this.endArrow=new ArrowRenderable(ctx,{alignSelf:"center",visible:this.showArrows,direction:this.orientation==="vertical"?"down":"right",height:this.orientation==="vertical"?1:1,...arrowOpts}),this.add(this.startArrow),this.add(this.slider),this.add(this.endArrow);let startArrowMouseTimeout=void 0,endArrowMouseTimeout=void 0;this.startArrow.onMouseDown=(event)=>{event.stopPropagation(),event.preventDefault(),this.scrollBy(-0.5,"viewport"),startArrowMouseTimeout=setTimeout(()=>{this.scrollBy(-0.5,"viewport"),startArrowMouseTimeout=setInterval(()=>{this.scrollBy(-0.2,"viewport")},200)},500)},this.startArrow.onMouseUp=(event)=>{event.stopPropagation(),clearInterval(startArrowMouseTimeout)},this.endArrow.onMouseDown=(event)=>{event.stopPropagation(),event.preventDefault(),this.scrollBy(0.5,"viewport"),endArrowMouseTimeout=setTimeout(()=>{this.scrollBy(0.5,"viewport"),endArrowMouseTimeout=setInterval(()=>{this.scrollBy(0.2,"viewport")},200)},500)},this.endArrow.onMouseUp=(event)=>{event.stopPropagation(),clearInterval(endArrowMouseTimeout)}}set arrowOptions(options){Object.assign(this.startArrow,options),Object.assign(this.endArrow,options),this.requestRender()}set trackOptions(options){Object.assign(this.slider,options),this.requestRender()}updateSliderFromScrollState(){let scrollRange=Math.max(0,this._scrollSize-this._viewportSize);this.slider.min=0,this.slider.max=scrollRange,this.slider.value=Math.min(this._scrollPosition,scrollRange)}scrollBy(delta,unit="absolute"){let resolvedDelta=(unit==="viewport"?this.viewportSize:unit==="content"?this.scrollSize:unit==="step"?this.scrollStep??1:1)*delta;this.scrollPosition+=resolvedDelta}recalculateVisibility(){if(!this._manualVisibility){let sizeRatio=this.scrollSize<=this.viewportSize?1:this.viewportSize/this.scrollSize;super.visible=sizeRatio<1}}handleKeyPress(key){switch(key.name){case"left":case"h":if(this.orientation!=="horizontal")return!1;return this.scrollBy(-0.2,"viewport"),!0;case"right":case"l":if(this.orientation!=="horizontal")return!1;return this.scrollBy(0.2,"viewport"),!0;case"up":case"k":if(this.orientation!=="vertical")return!1;return this.scrollBy(-0.2,"viewport"),!0;case"down":case"j":if(this.orientation!=="vertical")return!1;return this.scrollBy(0.2,"viewport"),!0;case"pageup":return this.scrollBy(-0.5,"viewport"),!0;case"pagedown":return this.scrollBy(0.5,"viewport"),!0;case"home":return this.scrollBy(-1,"content"),!0;case"end":return this.scrollBy(1,"content"),!0}return!1}}class ArrowRenderable extends Renderable{_direction;_foregroundColor;_backgroundColor;_attributes;_arrowChars;constructor(ctx,options){super(ctx,options);if(this._direction=options.direction,this._foregroundColor=options.foregroundColor?parseColor(options.foregroundColor):RGBA.fromValues(1,1,1,1),this._backgroundColor=options.backgroundColor?parseColor(options.backgroundColor):RGBA.fromValues(0,0,0,0),this._attributes=options.attributes??0,this._arrowChars={up:"\u25B2",down:"\u25BC",left:"\u25C0",right:"\u25B6",...options.arrowChars},!options.width)this.width=stringWidth2(this.getArrowChar())}get direction(){return this._direction}set direction(value){if(this._direction!==value)this._direction=value,this.requestRender()}get foregroundColor(){return this._foregroundColor}set foregroundColor(value){if(this._foregroundColor!==value)this._foregroundColor=parseColor(value),this.requestRender()}get backgroundColor(){return this._backgroundColor}set backgroundColor(value){if(this._backgroundColor!==value)this._backgroundColor=parseColor(value),this.requestRender()}get attributes(){return this._attributes}set attributes(value){if(this._attributes!==value)this._attributes=value,this.requestRender()}set arrowChars(value){this._arrowChars={...this._arrowChars,...value},this.requestRender()}renderSelf(buffer){let char=this.getArrowChar();buffer.drawText(char,this.x,this.y,this._foregroundColor,this._backgroundColor,this._attributes)}getArrowChar(){switch(this._direction){case"up":return this._arrowChars.up;case"down":return this._arrowChars.down;case"left":return this._arrowChars.left;case"right":return this._arrowChars.right;default:return"?"}}}class ContentRenderable extends BoxRenderable{viewport;_viewportCulling;constructor(ctx,viewport,viewportCulling,options){super(ctx,options);this.viewport=viewport,this._viewportCulling=viewportCulling}get viewportCulling(){return this._viewportCulling}set viewportCulling(value){this._viewportCulling=value}_hasVisibleChildFilter(){return this._viewportCulling}_getVisibleChildren(){if(this._viewportCulling)return getObjectsInViewport({x:this.viewport.screenX,y:this.viewport.screenY,width:this.viewport.width,height:this.viewport.height},this.getChildrenSortedByPrimaryAxis(),this.primaryAxis,0).map((child)=>child.num);return super._getVisibleChildren()}}var SCROLLBOX_PADDING_KEYS=["padding","paddingX","paddingY","paddingTop","paddingRight","paddingBottom","paddingLeft"];function pickScrollBoxPadding(options){if(!options)return{};let picked={};for(let key of SCROLLBOX_PADDING_KEYS){let value=options[key];if(value!==void 0)picked[key]=value}return picked}function stripScrollBoxPadding(options){let sanitized={...options};for(let key of SCROLLBOX_PADDING_KEYS)delete sanitized[key];return sanitized}class ScrollBoxRenderable extends BoxRenderable{static idCounter=0;internalId=0;wrapper;viewport;content;horizontalScrollBar;verticalScrollBar;_focusable=!0;selectionListener;autoScrollMouseX=0;autoScrollMouseY=0;autoScrollThresholdVertical=3;autoScrollThresholdHorizontal=3;autoScrollSpeedSlow=6;autoScrollSpeedMedium=36;autoScrollSpeedFast=72;isAutoScrolling=!1;cachedAutoScrollSpeed=3;autoScrollAccumulatorX=0;autoScrollAccumulatorY=0;scrollAccumulatorX=0;scrollAccumulatorY=0;_stickyScroll;_stickyScrollTop=!1;_stickyScrollBottom=!1;_stickyScrollLeft=!1;_stickyScrollRight=!1;_stickyStart;_hasManualScroll=!1;_isApplyingStickyScroll=!1;scrollAccel;get stickyScroll(){return this._stickyScroll}set stickyScroll(value){this._stickyScroll=value,this.updateStickyState()}get stickyStart(){return this._stickyStart}set stickyStart(value){this._stickyStart=value,this.updateStickyState()}get scrollTop(){return this.verticalScrollBar.scrollPosition}set scrollTop(value){this.verticalScrollBar.scrollPosition=value,this.updateStickyState()}get scrollLeft(){return this.horizontalScrollBar.scrollPosition}set scrollLeft(value){this.horizontalScrollBar.scrollPosition=value,this.updateStickyState()}get scrollWidth(){return this.horizontalScrollBar.scrollSize}get scrollHeight(){return this.verticalScrollBar.scrollSize}updateStickyState(){if(!this._stickyScroll){this.syncManualScrollState();return}let maxScrollTop=Math.max(0,this.scrollHeight-this.viewport.height),maxScrollLeft=Math.max(0,this.scrollWidth-this.viewport.width);if(this.scrollTop<=0)this._stickyScrollTop=!0,this._stickyScrollBottom=!1;else if(this.scrollTop>=maxScrollTop)this._stickyScrollTop=!1,this._stickyScrollBottom=!0;else this._stickyScrollTop=!1,this._stickyScrollBottom=!1;if(this.scrollLeft<=0)this._stickyScrollLeft=!0,this._stickyScrollRight=!1;else if(this.scrollLeft>=maxScrollLeft)this._stickyScrollLeft=!1,this._stickyScrollRight=!0;else this._stickyScrollLeft=!1,this._stickyScrollRight=!1;this.syncManualScrollState()}syncManualScrollState(){if(!this._stickyScroll){this._hasManualScroll=!1;return}let maxScrollTop=Math.max(0,this.scrollHeight-this.viewport.height),maxScrollLeft=Math.max(0,this.scrollWidth-this.viewport.width),hasScrollableContent=maxScrollTop>1||maxScrollLeft>1;if(this._isApplyingStickyScroll){if(this._hasManualScroll&&hasScrollableContent&&this.isAtStickyPosition())this._hasManualScroll=!1;return}this._hasManualScroll=hasScrollableContent&&!this.isAtStickyPosition()}applyStickyStart(stickyStart){let wasApplyingStickyScroll=this._isApplyingStickyScroll;this._isApplyingStickyScroll=!0;try{switch(stickyStart){case"top":this._stickyScrollTop=!0,this._stickyScrollBottom=!1,this.verticalScrollBar.scrollPosition=0;break;case"bottom":this._stickyScrollTop=!1,this._stickyScrollBottom=!0,this.verticalScrollBar.scrollPosition=Math.max(0,this.scrollHeight-this.viewport.height);break;case"left":this._stickyScrollLeft=!0,this._stickyScrollRight=!1,this.horizontalScrollBar.scrollPosition=0;break;case"right":this._stickyScrollLeft=!1,this._stickyScrollRight=!0,this.horizontalScrollBar.scrollPosition=Math.max(0,this.scrollWidth-this.viewport.width);break}}finally{this._isApplyingStickyScroll=wasApplyingStickyScroll}}constructor(ctx,options){let{wrapperOptions,viewportOptions,contentOptions,rootOptions,scrollbarOptions,verticalScrollbarOptions,horizontalScrollbarOptions,stickyScroll=!1,stickyStart,scrollX=!1,scrollY=!0,scrollAcceleration,viewportCulling=!0,...rootBoxOptions}=options,forwardedContentPadding={...pickScrollBoxPadding(rootBoxOptions),...pickScrollBoxPadding(rootOptions)},sanitizedRootBoxOptions=stripScrollBoxPadding(rootBoxOptions),sanitizedRootOptions=rootOptions?stripScrollBoxPadding(rootOptions):void 0,mergedContentOptions={...forwardedContentPadding,...contentOptions};super(ctx,{flexDirection:"row",alignItems:"stretch",...sanitizedRootBoxOptions,...sanitizedRootOptions});if(this.internalId=ScrollBoxRenderable.idCounter++,this._stickyScroll=stickyScroll,this._stickyStart=stickyStart,this.scrollAccel=scrollAcceleration??new LinearScrollAccel,this.wrapper=new BoxRenderable(ctx,{flexDirection:"column",flexGrow:1,...wrapperOptions,id:`scroll-box-wrapper-${this.internalId}`}),super.add(this.wrapper),this.viewport=new BoxRenderable(ctx,{flexDirection:"column",flexGrow:1,overflow:"hidden",onSizeChange:()=>{this.recalculateBarProps()},...viewportOptions,id:`scroll-box-viewport-${this.internalId}`}),this.wrapper.add(this.viewport),this.content=new ContentRenderable(ctx,this.viewport,viewportCulling,{alignSelf:"flex-start",flexShrink:0,...scrollX?{minWidth:"100%"}:{minWidth:"100%",maxWidth:"100%"},...scrollY?{minHeight:"100%"}:{minHeight:"100%",maxHeight:"100%"},onSizeChange:()=>{this.recalculateBarProps()},...mergedContentOptions,id:`scroll-box-content-${this.internalId}`}),this.viewport.add(this.content),this.verticalScrollBar=new ScrollBarRenderable(ctx,{...scrollbarOptions,...verticalScrollbarOptions,arrowOptions:{...scrollbarOptions?.arrowOptions,...verticalScrollbarOptions?.arrowOptions},id:`scroll-box-vertical-scrollbar-${this.internalId}`,orientation:"vertical",onChange:(position)=>{this.content.translateY=-position,this.updateStickyState()}}),super.add(this.verticalScrollBar),this.horizontalScrollBar=new ScrollBarRenderable(ctx,{...scrollbarOptions,...horizontalScrollbarOptions,arrowOptions:{...scrollbarOptions?.arrowOptions,...horizontalScrollbarOptions?.arrowOptions},id:`scroll-box-horizontal-scrollbar-${this.internalId}`,orientation:"horizontal",onChange:(position)=>{this.content.translateX=-position,this.updateStickyState()}}),this.wrapper.add(this.horizontalScrollBar),this.recalculateBarProps(),stickyStart&&stickyScroll)this.applyStickyStart(stickyStart);this.selectionListener=()=>{let selection=this._ctx.getSelection();if(!selection||!selection.isDragging)this.stopAutoScroll()},this._ctx.on("selection",this.selectionListener)}onUpdate(deltaTime){this.handleAutoScroll(deltaTime)}scrollBy(delta,unit="absolute"){if(typeof delta==="number")this.verticalScrollBar.scrollBy(delta,unit);else this.verticalScrollBar.scrollBy(delta.y,unit),this.horizontalScrollBar.scrollBy(delta.x,unit)}scrollChildIntoView(childId){let child=this.content.findDescendantById(childId);if(!child)return;let getNearestDelta=(elementStart,elementEnd,viewportStart,viewportEnd)=>{let elementSize=elementEnd-elementStart,viewportSize=viewportEnd-viewportStart,elementStartOutside=elementStart<viewportStart,elementEndOutside=elementEnd>viewportEnd;if(elementStartOutside&&elementEndOutside)return 0;if(elementStartOutside&&elementSize<viewportSize||elementEndOutside&&elementSize>viewportSize)return elementStart-viewportStart;if(elementStartOutside&&elementSize>viewportSize||elementEndOutside&&elementSize<viewportSize)return elementEnd-viewportEnd;return 0},childTop=child.y,childBottom=child.y+child.height,viewportTop=this.viewport.y,viewportBottom=this.viewport.y+this.viewport.height,dy=getNearestDelta(childTop,childBottom,viewportTop,viewportBottom),childLeft=child.x,childRight=child.x+child.width,viewportLeft=this.viewport.x,viewportRight=this.viewport.x+this.viewport.width,dx=getNearestDelta(childLeft,childRight,viewportLeft,viewportRight);if(dx!==0||dy!==0)this.scrollBy({x:dx,y:dy})}scrollTo(position){if(typeof position==="number")this.scrollTop=position;else this.scrollTop=position.y,this.scrollLeft=position.x}isAtStickyPosition(){if(!this._stickyScroll||!this._stickyStart)return!1;let maxScrollTop=Math.max(0,this.scrollHeight-this.viewport.height),maxScrollLeft=Math.max(0,this.scrollWidth-this.viewport.width);switch(this._stickyStart){case"top":return this.scrollTop===0;case"bottom":return this.scrollTop>=maxScrollTop;case"left":return this.scrollLeft===0;case"right":return this.scrollLeft>=maxScrollLeft;default:return!1}}isAtStickyReengagePoint(stickyStart,maxScrollTop,maxScrollLeft){switch(stickyStart){case"top":return maxScrollTop>0&&this.scrollTop<=0;case"bottom":return maxScrollTop>0&&this.scrollTop>=maxScrollTop-1;case"left":return maxScrollLeft>0&&this.scrollLeft<=0;case"right":return maxScrollLeft>0&&this.scrollLeft>=maxScrollLeft-1}}add(obj,index){return this.content.add(obj,index)}insertBefore(obj,anchor){return this.content.insertBefore(obj,anchor)}remove(child){if(child.parent===this){super.remove(child);return}this.content.remove(child)}getChildren(){return this.content.getChildren()}getRenderable(id){return this.content.getRenderable(id)}onMouseEvent(event){if(event.type==="scroll"){let dir=event.scroll?.direction;if(event.modifiers.shift)dir=dir==="up"?"left":dir==="down"?"right":dir==="right"?"down":"up";let baseDelta=event.scroll?.delta??0,now=Date.now(),multiplier=this.scrollAccel.tick(now),scrollAmount=baseDelta*multiplier;if(dir==="up"){this.scrollAccumulatorY-=scrollAmount;let integerScroll=Math.trunc(this.scrollAccumulatorY);if(integerScroll!==0)this.scrollTop+=integerScroll,this.scrollAccumulatorY-=integerScroll}else if(dir==="down"){this.scrollAccumulatorY+=scrollAmount;let integerScroll=Math.trunc(this.scrollAccumulatorY);if(integerScroll!==0)this.scrollTop+=integerScroll,this.scrollAccumulatorY-=integerScroll}else if(dir==="left"){this.scrollAccumulatorX-=scrollAmount;let integerScroll=Math.trunc(this.scrollAccumulatorX);if(integerScroll!==0)this.scrollLeft+=integerScroll,this.scrollAccumulatorX-=integerScroll}else if(dir==="right"){this.scrollAccumulatorX+=scrollAmount;let integerScroll=Math.trunc(this.scrollAccumulatorX);if(integerScroll!==0)this.scrollLeft+=integerScroll,this.scrollAccumulatorX-=integerScroll}this.syncManualScrollState()}if(event.type==="drag"&&event.isDragging)this.updateAutoScroll(event.x,event.y);else if(event.type==="up")this.stopAutoScroll()}handleKeyPress(key){if(this.verticalScrollBar.handleKeyPress(key))return this.scrollAccel.reset(),this.resetScrollAccumulators(),this.syncManualScrollState(),!0;if(this.horizontalScrollBar.handleKeyPress(key))return this.scrollAccel.reset(),this.resetScrollAccumulators(),this.syncManualScrollState(),!0;return!1}resetScrollAccumulators(){this.scrollAccumulatorX=0,this.scrollAccumulatorY=0}startAutoScroll(mouseX,mouseY){if(this.stopAutoScroll(),this.autoScrollMouseX=mouseX,this.autoScrollMouseY=mouseY,this.cachedAutoScrollSpeed=this.getAutoScrollSpeed(mouseX,mouseY),this.isAutoScrolling=!0,!this.live)this.live=!0}updateAutoScroll(mouseX,mouseY){this.autoScrollMouseX=mouseX,this.autoScrollMouseY=mouseY,this.cachedAutoScrollSpeed=this.getAutoScrollSpeed(mouseX,mouseY);let scrollX=this.getAutoScrollDirectionX(mouseX),scrollY=this.getAutoScrollDirectionY(mouseY);if(scrollX===0&&scrollY===0)this.stopAutoScroll();else if(!this.isAutoScrolling)this.startAutoScroll(mouseX,mouseY)}stopAutoScroll(){let wasAutoScrolling=this.isAutoScrolling;if(this.isAutoScrolling=!1,this.autoScrollAccumulatorX=0,this.autoScrollAccumulatorY=0,wasAutoScrolling&&!this.hasOtherLiveReasons())this.live=!1}hasOtherLiveReasons(){return!1}handleAutoScroll(deltaTime){if(!this.isAutoScrolling)return;let scrollX=this.getAutoScrollDirectionX(this.autoScrollMouseX),scrollY=this.getAutoScrollDirectionY(this.autoScrollMouseY),scrollAmount=this.cachedAutoScrollSpeed*(deltaTime/1000),scrolled=!1;if(scrollX!==0){this.autoScrollAccumulatorX+=scrollX*scrollAmount;let integerScrollX=Math.trunc(this.autoScrollAccumulatorX);if(integerScrollX!==0)this.scrollLeft+=integerScrollX,this.autoScrollAccumulatorX-=integerScrollX,scrolled=!0}if(scrollY!==0){this.autoScrollAccumulatorY+=scrollY*scrollAmount;let integerScrollY=Math.trunc(this.autoScrollAccumulatorY);if(integerScrollY!==0)this.scrollTop+=integerScrollY,this.autoScrollAccumulatorY-=integerScrollY,scrolled=!0}if(scrolled)this._ctx.requestSelectionUpdate();if(scrollX===0&&scrollY===0)this.stopAutoScroll()}getAutoScrollDirectionX(mouseX){let relativeX=mouseX-this.x,distToLeft=relativeX,distToRight=this.width-relativeX;if(distToLeft<=this.autoScrollThresholdHorizontal)return this.scrollLeft>0?-1:0;else if(distToRight<=this.autoScrollThresholdHorizontal){let maxScrollLeft=this.scrollWidth-this.viewport.width;return this.scrollLeft<maxScrollLeft?1:0}return 0}getAutoScrollDirectionY(mouseY){let relativeY=mouseY-this.y,distToTop=relativeY,distToBottom=this.height-relativeY;if(distToTop<=this.autoScrollThresholdVertical)return this.scrollTop>0?-1:0;else if(distToBottom<=this.autoScrollThresholdVertical){let maxScrollTop=this.scrollHeight-this.viewport.height;return this.scrollTop<maxScrollTop?1:0}return 0}getAutoScrollSpeed(mouseX,mouseY){let relativeX=mouseX-this.x,relativeY=mouseY-this.y,distToLeft=relativeX,distToRight=this.width-relativeX,distToTop=relativeY,distToBottom=this.height-relativeY,minDistance=Math.min(distToLeft,distToRight,distToTop,distToBottom);if(minDistance<=1)return this.autoScrollSpeedFast;else if(minDistance<=2)return this.autoScrollSpeedMedium;else return this.autoScrollSpeedSlow}recalculateBarProps(){let wasApplyingStickyScroll=this._isApplyingStickyScroll;this._isApplyingStickyScroll=!0;try{if(this.verticalScrollBar.scrollSize=this.content.height,this.verticalScrollBar.viewportSize=this.viewport.height,this.horizontalScrollBar.scrollSize=this.content.width,this.horizontalScrollBar.viewportSize=this.viewport.width,this._stickyScroll){let newMaxScrollTop=Math.max(0,this.scrollHeight-this.viewport.height),newMaxScrollLeft=Math.max(0,this.scrollWidth-this.viewport.width),stickyStart=this._stickyStart;if(stickyStart&&!this._hasManualScroll)this.applyStickyStart(stickyStart);else if(stickyStart&&this._hasManualScroll&&this.isAtStickyReengagePoint(stickyStart,newMaxScrollTop,newMaxScrollLeft))this._hasManualScroll=!1,this.applyStickyStart(stickyStart);else if(!this._hasManualScroll){if(this._stickyScrollTop)this.scrollTop=0;else if(this._stickyScrollBottom&&newMaxScrollTop>0)this.scrollTop=newMaxScrollTop;if(this._stickyScrollLeft)this.scrollLeft=0;else if(this._stickyScrollRight&&newMaxScrollLeft>0)this.scrollLeft=newMaxScrollLeft}}}finally{this._isApplyingStickyScroll=wasApplyingStickyScroll}process.nextTick(()=>{this.requestRender()})}set padding(value){this.content.padding=value,this.requestRender()}set paddingX(value){this.content.paddingX=value,this.requestRender()}set paddingY(value){this.content.paddingY=value,this.requestRender()}set paddingTop(value){this.content.paddingTop=value,this.requestRender()}set paddingRight(value){this.content.paddingRight=value,this.requestRender()}set paddingBottom(value){this.content.paddingBottom=value,this.requestRender()}set paddingLeft(value){this.content.paddingLeft=value,this.requestRender()}set rootOptions(options){Object.assign(this,options),this.requestRender()}set wrapperOptions(options){Object.assign(this.wrapper,options),this.requestRender()}set viewportOptions(options){Object.assign(this.viewport,options),this.requestRender()}set contentOptions(options){Object.assign(this.content,options),this.requestRender()}set scrollbarOptions(options){Object.assign(this.verticalScrollBar,options),Object.assign(this.horizontalScrollBar,options),this.requestRender()}set verticalScrollbarOptions(options){Object.assign(this.verticalScrollBar,options),this.requestRender()}set horizontalScrollbarOptions(options){Object.assign(this.horizontalScrollBar,options),this.requestRender()}get scrollAcceleration(){return this.scrollAccel}set scrollAcceleration(value){this.scrollAccel=value}get viewportCulling(){return this.content.viewportCulling}set viewportCulling(value){this.content.viewportCulling=value,this.requestRender()}destroySelf(){if(this.selectionListener)this._ctx.off("selection",this.selectionListener),this.selectionListener=void 0;super.destroySelf()}}var defaultSelectKeybindings=[{name:"up",action:"move-up"},{name:"k",action:"move-up"},{name:"down",action:"move-down"},{name:"j",action:"move-down"},{name:"up",shift:!0,action:"move-up-fast"},{name:"down",shift:!0,action:"move-down-fast"},{name:"return",action:"select-current"},{name:"linefeed",action:"select-current"}],SelectRenderableEvents;((SelectRenderableEvents2)=>{SelectRenderableEvents2.SELECTION_CHANGED="selectionChanged",SelectRenderableEvents2.ITEM_SELECTED="itemSelected"})(SelectRenderableEvents||={});class SelectRenderable extends Renderable{_focusable=!0;_options=[];_selectedIndex=0;scrollOffset=0;maxVisibleItems;_backgroundColor;_textColor;_focusedBackgroundColor;_focusedTextColor;_selectedBackgroundColor;_selectedTextColor;_descriptionColor;_selectedDescriptionColor;_showScrollIndicator;_wrapSelection;_showDescription;_showSelectionIndicator;_font;_itemSpacing;linesPerItem;fontHeight;_fastScrollStep;_keyBindingsMap;_keyAliasMap;_keyBindings;_defaultOptions={backgroundColor:"transparent",textColor:"#FFFFFF",focusedBackgroundColor:"#1a1a1a",focusedTextColor:"#FFFFFF",selectedBackgroundColor:"#334455",selectedTextColor:"#FFFF00",selectedIndex:0,descriptionColor:"#888888",selectedDescriptionColor:"#CCCCCC",showScrollIndicator:!1,wrapSelection:!1,showDescription:!0,showSelectionIndicator:!0,itemSpacing:0,fastScrollStep:5};constructor(ctx,options){super(ctx,{...options,buffered:!0});this._options=options.options||[];let requestedIndex=options.selectedIndex??this._defaultOptions.selectedIndex;this._selectedIndex=this._options.length>0?Math.min(requestedIndex,this._options.length-1):0,this._backgroundColor=parseColor(options.backgroundColor||this._defaultOptions.backgroundColor),this._textColor=parseColor(options.textColor||this._defaultOptions.textColor),this._focusedBackgroundColor=parseColor(options.focusedBackgroundColor||this._defaultOptions.focusedBackgroundColor),this._focusedTextColor=parseColor(options.focusedTextColor||this._defaultOptions.focusedTextColor),this._showScrollIndicator=options.showScrollIndicator??this._defaultOptions.showScrollIndicator,this._wrapSelection=options.wrapSelection??this._defaultOptions.wrapSelection,this._showDescription=options.showDescription??this._defaultOptions.showDescription,this._showSelectionIndicator=options.showSelectionIndicator??this._defaultOptions.showSelectionIndicator,this._font=options.font,this._itemSpacing=options.itemSpacing||this._defaultOptions.itemSpacing,this.fontHeight=this._font?measureText({text:"A",font:this._font}).height:1,this.linesPerItem=this._showDescription?this._font?this.fontHeight+1:2:this._font?this.fontHeight:1,this.linesPerItem+=this._itemSpacing,this.maxVisibleItems=Math.max(1,Math.floor(this.height/this.linesPerItem)),this._selectedBackgroundColor=parseColor(options.selectedBackgroundColor||this._defaultOptions.selectedBackgroundColor),this._selectedTextColor=parseColor(options.selectedTextColor||this._defaultOptions.selectedTextColor),this._descriptionColor=parseColor(options.descriptionColor||this._defaultOptions.descriptionColor),this._selectedDescriptionColor=parseColor(options.selectedDescriptionColor||this._defaultOptions.selectedDescriptionColor),this._fastScrollStep=options.fastScrollStep||this._defaultOptions.fastScrollStep,this._keyAliasMap=mergeKeyAliases(defaultKeyAliases,options.keyAliasMap||{}),this._keyBindings=options.keyBindings||[];let mergedBindings=mergeKeyBindings(defaultSelectKeybindings,this._keyBindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap),this.updateScrollOffset(),this.requestRender()}renderSelf(buffer,deltaTime){if(!this.visible||!this.frameBuffer)return;if(this.isDirty)this.refreshFrameBuffer()}refreshFrameBuffer(){if(!this.frameBuffer)return;let bgColor=this._focused?this._focusedBackgroundColor:this._backgroundColor;if(this.frameBuffer.clear(bgColor),this._options.length===0)return;let contentX=0,contentY=0,contentWidth=this.width,contentHeight=this.height,visibleOptions=this._options.slice(this.scrollOffset,this.scrollOffset+this.maxVisibleItems);for(let i=0;i<visibleOptions.length;i++){let actualIndex=this.scrollOffset+i,option=visibleOptions[i],isSelected=actualIndex===this._selectedIndex,itemY=contentY+i*this.linesPerItem;if(itemY+this.linesPerItem-1>=contentY+contentHeight)break;if(isSelected){let contentHeight2=this.linesPerItem-this._itemSpacing;this.frameBuffer.fillRect(contentX,itemY,contentWidth,contentHeight2,this._selectedBackgroundColor)}let indicator=this._showSelectionIndicator?isSelected?"\u25B6 ":" ":"",indicatorWidth=this._showSelectionIndicator?2:0,nameContent=`${indicator}${option.name}`,baseTextColor=this._focused?this._focusedTextColor:this._textColor,nameColor=isSelected?this._selectedTextColor:baseTextColor,textX=contentX+1+indicatorWidth;if(this._font){if(indicator)this.frameBuffer.drawText(indicator,contentX+1,itemY,nameColor);renderFontToFrameBuffer(this.frameBuffer,{text:option.name,x:textX,y:itemY,color:nameColor,backgroundColor:isSelected?this._selectedBackgroundColor:bgColor,font:this._font})}else this.frameBuffer.drawText(nameContent,contentX+1,itemY,nameColor);if(this._showDescription&&itemY+this.fontHeight<contentY+contentHeight){let descColor=isSelected?this._selectedDescriptionColor:this._descriptionColor;this.frameBuffer.drawText(option.description,textX,itemY+this.fontHeight,descColor)}}if(this._showScrollIndicator&&this._options.length>this.maxVisibleItems)this.renderScrollIndicatorToFrameBuffer(contentX,contentY,contentWidth,contentHeight)}renderScrollIndicatorToFrameBuffer(contentX,contentY,contentWidth,contentHeight){if(!this.frameBuffer)return;let maxScrollOffset=this._options.length-this.maxVisibleItems,scrollPercent=this.scrollOffset/maxScrollOffset,indicatorHeight=Math.max(1,contentHeight-2),indicatorY=contentY+1+Math.floor(scrollPercent*indicatorHeight),indicatorX=contentX+contentWidth-1;this.frameBuffer.drawText("\u2588",indicatorX,indicatorY,parseColor("#666666"))}get options(){return this._options}set options(options){this._options=options,this._selectedIndex=Math.min(this._selectedIndex,Math.max(0,options.length-1)),this.updateScrollOffset(),this.requestRender()}getSelectedOption(){return this._options[this._selectedIndex]||null}getSelectedIndex(){return this._selectedIndex}moveUp(steps=1){let newIndex=this._selectedIndex-steps;if(newIndex>=0)this._selectedIndex=newIndex;else if(this._wrapSelection&&this._options.length>0)this._selectedIndex=this._options.length-1;else this._selectedIndex=0;this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this._selectedIndex,this.getSelectedOption())}moveDown(steps=1){let newIndex=this._selectedIndex+steps;if(newIndex<this._options.length)this._selectedIndex=newIndex;else if(this._wrapSelection&&this._options.length>0)this._selectedIndex=0;else this._selectedIndex=this._options.length-1;this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this._selectedIndex,this.getSelectedOption())}selectCurrent(){let selected=this.getSelectedOption();if(selected)this.emit("itemSelected",this._selectedIndex,selected)}setSelectedIndex(index){if(index>=0&&index<this._options.length)this._selectedIndex=index,this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this._selectedIndex,this.getSelectedOption())}updateScrollOffset(){if(!this._options)return;let halfVisible=Math.floor(this.maxVisibleItems/2),newScrollOffset=Math.max(0,Math.min(this._selectedIndex-halfVisible,this._options.length-this.maxVisibleItems));if(newScrollOffset!==this.scrollOffset)this.scrollOffset=newScrollOffset,this.requestRender()}onResize(width,height){this.maxVisibleItems=Math.max(1,Math.floor(height/this.linesPerItem)),this.updateScrollOffset(),this.requestRender()}handleKeyPress(key){let action=getKeyBindingAction(this._keyBindingsMap,key);if(action)switch(action){case"move-up":return this.moveUp(1),!0;case"move-down":return this.moveDown(1),!0;case"move-up-fast":return this.moveUp(this._fastScrollStep),!0;case"move-down-fast":return this.moveDown(this._fastScrollStep),!0;case"select-current":return this.selectCurrent(),!0}return!1}get showScrollIndicator(){return this._showScrollIndicator}set showScrollIndicator(show){this._showScrollIndicator=show,this.requestRender()}get showDescription(){return this._showDescription}set showDescription(show){if(this._showDescription!==show)this._showDescription=show,this.linesPerItem=this._showDescription?this._font?this.fontHeight+1:2:this._font?this.fontHeight:1,this.linesPerItem+=this._itemSpacing,this.maxVisibleItems=Math.max(1,Math.floor(this.height/this.linesPerItem)),this.updateScrollOffset(),this.requestRender()}get showSelectionIndicator(){return this._showSelectionIndicator}set showSelectionIndicator(show){let next=show??this._defaultOptions.showSelectionIndicator;if(this._showSelectionIndicator!==next)this._showSelectionIndicator=next,this.requestRender()}get wrapSelection(){return this._wrapSelection}set wrapSelection(wrap){this._wrapSelection=wrap}set backgroundColor(value){let newColor=parseColor(value??this._defaultOptions.backgroundColor);if(this._backgroundColor!==newColor)this._backgroundColor=newColor,this.requestRender()}set textColor(value){let newColor=parseColor(value??this._defaultOptions.textColor);if(this._textColor!==newColor)this._textColor=newColor,this.requestRender()}set focusedBackgroundColor(value){let newColor=parseColor(value??this._defaultOptions.focusedBackgroundColor);if(this._focusedBackgroundColor!==newColor)this._focusedBackgroundColor=newColor,this.requestRender()}set focusedTextColor(value){let newColor=parseColor(value??this._defaultOptions.focusedTextColor);if(this._focusedTextColor!==newColor)this._focusedTextColor=newColor,this.requestRender()}set selectedBackgroundColor(value){let newColor=parseColor(value??this._defaultOptions.selectedBackgroundColor);if(this._selectedBackgroundColor!==newColor)this._selectedBackgroundColor=newColor,this.requestRender()}set selectedTextColor(value){let newColor=parseColor(value??this._defaultOptions.selectedTextColor);if(this._selectedTextColor!==newColor)this._selectedTextColor=newColor,this.requestRender()}set descriptionColor(value){let newColor=parseColor(value??this._defaultOptions.descriptionColor);if(this._descriptionColor!==newColor)this._descriptionColor=newColor,this.requestRender()}set selectedDescriptionColor(value){let newColor=parseColor(value??this._defaultOptions.selectedDescriptionColor);if(this._selectedDescriptionColor!==newColor)this._selectedDescriptionColor=newColor,this.requestRender()}set font(font){this._font=font,this.fontHeight=measureText({text:"A",font:this._font}).height,this.linesPerItem=this._showDescription?this._font?this.fontHeight+1:2:this._font?this.fontHeight:1,this.linesPerItem+=this._itemSpacing,this.maxVisibleItems=Math.max(1,Math.floor(this.height/this.linesPerItem)),this.updateScrollOffset(),this.requestRender()}set itemSpacing(spacing){this._itemSpacing=spacing,this.linesPerItem=this._showDescription?this._font?this.fontHeight+1:2:this._font?this.fontHeight:1,this.linesPerItem+=this._itemSpacing,this.maxVisibleItems=Math.max(1,Math.floor(this.height/this.linesPerItem)),this.updateScrollOffset(),this.requestRender()}set fastScrollStep(step){this._fastScrollStep=step}set keyBindings(bindings){this._keyBindings=bindings;let mergedBindings=mergeKeyBindings(defaultSelectKeybindings,bindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}set keyAliasMap(aliases){this._keyAliasMap=mergeKeyAliases(defaultKeyAliases,aliases);let mergedBindings=mergeKeyBindings(defaultSelectKeybindings,this._keyBindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}set selectedIndex(value){let newIndex=value??this._defaultOptions.selectedIndex,clampedIndex=this._options.length>0?Math.min(Math.max(0,newIndex),this._options.length-1):0;if(this._selectedIndex!==clampedIndex)this._selectedIndex=clampedIndex,this.updateScrollOffset(),this.requestRender()}}var defaultTabSelectKeybindings=[{name:"left",action:"move-left"},{name:"[",action:"move-left"},{name:"right",action:"move-right"},{name:"]",action:"move-right"},{name:"return",action:"select-current"},{name:"linefeed",action:"select-current"}],TabSelectRenderableEvents;((TabSelectRenderableEvents2)=>{TabSelectRenderableEvents2.SELECTION_CHANGED="selectionChanged",TabSelectRenderableEvents2.ITEM_SELECTED="itemSelected"})(TabSelectRenderableEvents||={});function calculateDynamicHeight(showUnderline,showDescription){let height=1;if(showUnderline)height+=1;if(showDescription)height+=1;return height}class TabSelectRenderable extends Renderable{_focusable=!0;_options=[];selectedIndex=0;scrollOffset=0;_tabWidth;maxVisibleTabs;_backgroundColor;_textColor;_focusedBackgroundColor;_focusedTextColor;_selectedBackgroundColor;_selectedTextColor;_selectedDescriptionColor;_showScrollArrows;_showDescription;_showUnderline;_wrapSelection;_keyBindingsMap;_keyAliasMap;_keyBindings;constructor(ctx,options){let calculatedHeight=calculateDynamicHeight(options.showUnderline??!0,options.showDescription??!0);super(ctx,{...options,height:calculatedHeight,buffered:!0});this._backgroundColor=parseColor(options.backgroundColor||"transparent"),this._textColor=parseColor(options.textColor||"#FFFFFF"),this._focusedBackgroundColor=parseColor(options.focusedBackgroundColor||options.backgroundColor||"#1a1a1a"),this._focusedTextColor=parseColor(options.focusedTextColor||options.textColor||"#FFFFFF"),this._options=options.options||[],this._tabWidth=options.tabWidth||20,this._showDescription=options.showDescription??!0,this._showUnderline=options.showUnderline??!0,this._showScrollArrows=options.showScrollArrows??!0,this._wrapSelection=options.wrapSelection??!1,this.maxVisibleTabs=Math.max(1,Math.floor(this.width/this._tabWidth)),this._selectedBackgroundColor=parseColor(options.selectedBackgroundColor||"#334455"),this._selectedTextColor=parseColor(options.selectedTextColor||"#FFFF00"),this._selectedDescriptionColor=parseColor(options.selectedDescriptionColor||"#CCCCCC"),this._keyAliasMap=mergeKeyAliases(defaultKeyAliases,options.keyAliasMap||{}),this._keyBindings=options.keyBindings||[];let mergedBindings=mergeKeyBindings(defaultTabSelectKeybindings,this._keyBindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}calculateDynamicHeight(){return calculateDynamicHeight(this._showUnderline,this._showDescription)}renderSelf(buffer,deltaTime){if(!this.visible||!this.frameBuffer)return;if(this.isDirty)this.refreshFrameBuffer()}refreshFrameBuffer(){if(!this.frameBuffer)return;let bgColor=this._focused?this._focusedBackgroundColor:this._backgroundColor;if(this.frameBuffer.clear(bgColor),this._options.length===0)return;let contentX=0,contentY=0,contentWidth=this.width,contentHeight=this.height,visibleOptions=this._options.slice(this.scrollOffset,this.scrollOffset+this.maxVisibleTabs);for(let i=0;i<visibleOptions.length;i++){let actualIndex=this.scrollOffset+i,option=visibleOptions[i],isSelected=actualIndex===this.selectedIndex,tabX=contentX+i*this._tabWidth;if(tabX>=contentX+contentWidth)break;let actualTabWidth=Math.min(this._tabWidth,contentWidth-i*this._tabWidth);if(isSelected)this.frameBuffer.fillRect(tabX,contentY,actualTabWidth,1,this._selectedBackgroundColor);let baseTextColor=this._focused?this._focusedTextColor:this._textColor,nameColor=isSelected?this._selectedTextColor:baseTextColor,nameContent=this.truncateText(option.name,actualTabWidth-2);if(this.frameBuffer.drawText(nameContent,tabX+1,contentY,nameColor),isSelected&&this._showUnderline&&contentHeight>=2){let underlineY=contentY+1,underlineBg=isSelected?this._selectedBackgroundColor:bgColor;this.frameBuffer.drawText("\u25AC".repeat(actualTabWidth),tabX,underlineY,nameColor,underlineBg)}}if(this._showDescription&&contentHeight>=(this._showUnderline?3:2)){let selectedOption=this.getSelectedOption();if(selectedOption){let descriptionY=contentY+(this._showUnderline?2:1),descColor=this._selectedDescriptionColor,descContent=this.truncateText(selectedOption.description,contentWidth-2);this.frameBuffer.drawText(descContent,contentX+1,descriptionY,descColor)}}if(this._showScrollArrows&&this._options.length>this.maxVisibleTabs)this.renderScrollArrowsToFrameBuffer(contentX,contentY,contentWidth,contentHeight)}truncateText(text,maxWidth){if(text.length<=maxWidth)return text;return text.substring(0,Math.max(0,maxWidth-1))+"\u2026"}renderScrollArrowsToFrameBuffer(contentX,contentY,contentWidth,contentHeight){if(!this.frameBuffer)return;let hasMoreLeft=this.scrollOffset>0,hasMoreRight=this.scrollOffset+this.maxVisibleTabs<this._options.length;if(hasMoreLeft)this.frameBuffer.drawText("\u2039",contentX,contentY,parseColor("#AAAAAA"));if(hasMoreRight)this.frameBuffer.drawText("\u203A",contentX+contentWidth-1,contentY,parseColor("#AAAAAA"))}setOptions(options){this._options=options,this.selectedIndex=Math.min(this.selectedIndex,Math.max(0,options.length-1)),this.updateScrollOffset(),this.requestRender()}getSelectedOption(){return this._options[this.selectedIndex]||null}getSelectedIndex(){return this.selectedIndex}moveLeft(){if(this.selectedIndex>0)this.selectedIndex--;else if(this._wrapSelection&&this._options.length>0)this.selectedIndex=this._options.length-1;else return;this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this.selectedIndex,this.getSelectedOption())}moveRight(){if(this.selectedIndex<this._options.length-1)this.selectedIndex++;else if(this._wrapSelection&&this._options.length>0)this.selectedIndex=0;else return;this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this.selectedIndex,this.getSelectedOption())}selectCurrent(){let selected=this.getSelectedOption();if(selected)this.emit("itemSelected",this.selectedIndex,selected)}setSelectedIndex(index){if(index>=0&&index<this._options.length)this.selectedIndex=index,this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this.selectedIndex,this.getSelectedOption())}updateScrollOffset(){let halfVisible=Math.floor(this.maxVisibleTabs/2),newScrollOffset=Math.max(0,Math.min(this.selectedIndex-halfVisible,this._options.length-this.maxVisibleTabs));if(newScrollOffset!==this.scrollOffset)this.scrollOffset=newScrollOffset,this.requestRender()}onResize(width,height){this.maxVisibleTabs=Math.max(1,Math.floor(width/this._tabWidth)),this.updateScrollOffset(),this.requestRender()}setTabWidth(tabWidth){if(this._tabWidth===tabWidth)return;this._tabWidth=tabWidth,this.maxVisibleTabs=Math.max(1,Math.floor(this.width/this._tabWidth)),this.updateScrollOffset(),this.requestRender()}getTabWidth(){return this._tabWidth}handleKeyPress(key){let action=getKeyBindingAction(this._keyBindingsMap,key);if(action)switch(action){case"move-left":return this.moveLeft(),!0;case"move-right":return this.moveRight(),!0;case"select-current":return this.selectCurrent(),!0}return!1}get options(){return this._options}set options(options){this._options=options,this.selectedIndex=Math.min(this.selectedIndex,Math.max(0,options.length-1)),this.updateScrollOffset(),this.requestRender()}set backgroundColor(color){this._backgroundColor=parseColor(color),this.requestRender()}set textColor(color){this._textColor=parseColor(color),this.requestRender()}set focusedBackgroundColor(color){this._focusedBackgroundColor=parseColor(color),this.requestRender()}set focusedTextColor(color){this._focusedTextColor=parseColor(color),this.requestRender()}set selectedBackgroundColor(color){this._selectedBackgroundColor=parseColor(color),this.requestRender()}set selectedTextColor(color){this._selectedTextColor=parseColor(color),this.requestRender()}set selectedDescriptionColor(color){this._selectedDescriptionColor=parseColor(color),this.requestRender()}get showDescription(){return this._showDescription}set showDescription(show){if(this._showDescription!==show){this._showDescription=show;let newHeight=this.calculateDynamicHeight();this.height=newHeight,this.requestRender()}}get showUnderline(){return this._showUnderline}set showUnderline(show){if(this._showUnderline!==show){this._showUnderline=show;let newHeight=this.calculateDynamicHeight();this.height=newHeight,this.requestRender()}}get showScrollArrows(){return this._showScrollArrows}set showScrollArrows(show){if(this._showScrollArrows!==show)this._showScrollArrows=show,this.requestRender()}get wrapSelection(){return this._wrapSelection}set wrapSelection(wrap){this._wrapSelection=wrap}get tabWidth(){return this._tabWidth}set tabWidth(tabWidth){if(this._tabWidth===tabWidth)return;this._tabWidth=tabWidth,this.maxVisibleTabs=Math.max(1,Math.floor(this.width/this._tabWidth)),this.updateScrollOffset(),this.requestRender()}set keyBindings(bindings){this._keyBindings=bindings;let mergedBindings=mergeKeyBindings(defaultTabSelectKeybindings,bindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}set keyAliasMap(aliases){this._keyAliasMap=mergeKeyAliases(defaultKeyAliases,aliases);let mergedBindings=mergeKeyBindings(defaultTabSelectKeybindings,this._keyBindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}}class TimeToFirstDrawRenderable extends Renderable{_runtimeMs=null;textColor;label;precision;constructor(ctx,options={}){super(ctx,{width:"100%",height:1,flexShrink:0,alignSelf:"center",...options});this.textColor=parseColor(options.fg??"#AAAAAA"),this.label=options.label??"Time to first draw",this.precision=this.normalizePrecision(options.precision??2)}get runtimeMs(){return this._runtimeMs}set fg(value){this.textColor=parseColor(value),this.requestRender()}set color(value){this.fg=value}set textLabel(value){if(value===this.label)return;this.label=value,this.requestRender()}set decimals(value){let nextPrecision=this.normalizePrecision(value);if(nextPrecision===this.precision)return;this.precision=nextPrecision,this.requestRender()}reset(){this._runtimeMs=null,this.requestRender()}renderSelf(buffer){if(this._runtimeMs===null)this._runtimeMs=performance.now();let content=`${this.label}: ${this._runtimeMs.toFixed(this.precision)}ms`,maxWidth=Math.max(this.width,1),visibleContent=content.length>maxWidth?content.slice(0,maxWidth):content,centeredX=this.x+Math.max(0,Math.floor((maxWidth-visibleContent.length)/2));buffer.drawText(visibleContent,centeredX,this.y,this.textColor)}normalizePrecision(value){if(!Number.isFinite(value))return 2;return Math.max(0,Math.floor(value))}}var import_react=__toESM(require_react_production(),1);var import_react2=__toESM(require_react_production(),1),import_react3=__toESM(require_react_production(),1);var REACT_ELEMENT_TYPE=Symbol.for("react.transitional.element"),REACT_FRAGMENT_TYPE=Symbol.for("react.fragment");function jsxProd(type,config,maybeKey){var key=null;if(maybeKey!==void 0&&(key=""+maybeKey),config.key!==void 0&&(key=""+config.key),"key"in config){maybeKey={};for(var propName in config)propName!=="key"&&(maybeKey[propName]=config[propName])}else maybeKey=config;return config=maybeKey.ref,{$$typeof:REACT_ELEMENT_TYPE,type,key,ref:config!==void 0?config:null,props:maybeKey}}var $Fragment=REACT_FRAGMENT_TYPE,$jsx=jsxProd,$jsxs=jsxProd;var jsxDEV=$jsx;var import_react_reconciler=__toESM(require_react_reconciler_production(),1);var $ConcurrentRoot=1;var $DefaultEventPriority=32;var $NoEventPriority=0;var import_react4=__toESM(require_react_production(),1);var textNodeKeys=["span","b","strong","i","em","u","br","a"];class SpanRenderable extends TextNodeRenderable{ctx;constructor(ctx,options){super(options);this.ctx=ctx}}class TextModifierRenderable extends SpanRenderable{constructor(options,modifier){super(null,options);if(modifier==="b"||modifier==="strong")this.attributes=(this.attributes||0)|TextAttributes.BOLD;else if(modifier==="i"||modifier==="em")this.attributes=(this.attributes||0)|TextAttributes.ITALIC;else if(modifier==="u")this.attributes=(this.attributes||0)|TextAttributes.UNDERLINE}}class BoldSpanRenderable extends TextModifierRenderable{constructor(_ctx,options){super(options,"b")}}class ItalicSpanRenderable extends TextModifierRenderable{constructor(_ctx,options){super(options,"i")}}class UnderlineSpanRenderable extends TextModifierRenderable{constructor(_ctx,options){super(options,"u")}}class LineBreakRenderable extends SpanRenderable{constructor(_ctx,options){super(null,options);this.add()}add(){return super.add(`
3672
3672
  `)}}class LinkRenderable extends SpanRenderable{constructor(_ctx,options){let linkOptions={...options,link:{url:options.href}};super(null,linkOptions)}}var baseComponents={box:BoxRenderable,text:TextRenderable,code:CodeRenderable,diff:DiffRenderable,markdown:MarkdownRenderable,input:InputRenderable,select:SelectRenderable,textarea:TextareaRenderable,scrollbox:ScrollBoxRenderable,"ascii-font":ASCIIFontRenderable,"tab-select":TabSelectRenderable,"line-number":LineNumberRenderable,span:SpanRenderable,br:LineBreakRenderable,b:BoldSpanRenderable,strong:BoldSpanRenderable,i:ItalicSpanRenderable,em:ItalicSpanRenderable,u:UnderlineSpanRenderable,a:LinkRenderable},componentCatalogue={...baseComponents};function extend(objects){Object.assign(componentCatalogue,objects)}function getComponentCatalogue(){return componentCatalogue}var AppContext=import_react.createContext({keyHandler:null,renderer:null}),useAppContext=()=>{return import_react.useContext(AppContext)};class ErrorBoundary extends import_react3.default.Component{constructor(props){super(props);this.state={hasError:!1,error:null}}static getDerivedStateFromError(error){return{hasError:!0,error}}render(){if(this.state.hasError&&this.state.error)return jsxDEV("box",{style:{flexDirection:"column",padding:2},children:jsxDEV("text",{fg:"red",children:this.state.error.stack||this.state.error.message},void 0,!1,void 0,this)},void 0,!1,void 0,this);return this.props.children}}var package_default={name:"@opentui/react",version:"0.4.3",description:"React renderer for building terminal user interfaces using OpenTUI core",license:"MIT",repository:{type:"git",url:"https://github.com/anomalyco/opentui",directory:"packages/react"},module:"src/index.ts",type:"module",private:!0,main:"src/index.ts",exports:{".":{import:"./src/index.ts",types:"./src/index.ts"},"./test-utils":{import:"./src/test-utils.ts",types:"./src/test-utils.d.ts"},"./runtime-plugin-support":{import:"./scripts/runtime-plugin-support.ts",types:"./scripts/runtime-plugin-support.ts"},"./runtime-plugin-support/configure":{import:"./scripts/runtime-plugin-support-configure.ts",types:"./scripts/runtime-plugin-support-configure.ts"},"./jsx-runtime":{import:"./jsx-runtime.js",types:"./jsx-runtime.d.ts"},"./jsx-dev-runtime":{import:"./jsx-dev-runtime.js",types:"./jsx-dev-runtime.d.ts"}},scripts:{build:"bun run scripts/build.ts","build:examples":"bun examples/build.ts","build:dev":"bun run scripts/build.ts --dev",publish:"bun run scripts/publish.ts",test:"bun test"},devDependencies:{"@opentui/keymap":"workspace:*","@types/bun":"latest","@types/node":"^24.0.0","@types/react":"^19.2.0","@types/react-reconciler":"^0.33.0","@types/ws":"^8.18.1",react:">=19.2.0","react-devtools-core":"^7.0.1",typescript:"^5",ws:"^8.18.0"},peerDependencies:{react:">=19.2.0","react-devtools-core":"^7.0.1",ws:"^8.18.0"},peerDependenciesMeta:{"react-devtools-core":{optional:!0},ws:{optional:!0}},dependencies:{"@opentui/core":"workspace:*","react-reconciler":"^0.33.0"}},idCounter=new Map;function getNextId(type){if(!idCounter.has(type))idCounter.set(type,0);let value=idCounter.get(type)+1;return idCounter.set(type,value),`${type}-${value}`}function initEventListeners(instance,eventName,listener,previousListener){if(previousListener)instance.off(eventName,previousListener);if(listener)instance.on(eventName,listener)}function setStyle(instance,styles,oldStyles){if(oldStyles!=null&&typeof oldStyles==="object"){for(let styleName in oldStyles)if(oldStyles.hasOwnProperty(styleName)){if(styles==null||!styles.hasOwnProperty(styleName))instance[styleName]=null}}if(styles!=null&&typeof styles==="object"){for(let styleName in styles)if(styles.hasOwnProperty(styleName)){let value=styles[styleName],oldValue=oldStyles?.[styleName];if(value!==oldValue)instance[styleName]=value}}}function setProperty(instance,type,propKey,propValue,oldPropValue){switch(propKey){case"onChange":if(instance instanceof InputRenderable)initEventListeners(instance,InputRenderableEvents.CHANGE,propValue,oldPropValue);else if(instance instanceof SelectRenderable)initEventListeners(instance,SelectRenderableEvents.SELECTION_CHANGED,propValue,oldPropValue);else if(instance instanceof TabSelectRenderable)initEventListeners(instance,TabSelectRenderableEvents.SELECTION_CHANGED,propValue,oldPropValue);break;case"onInput":if(instance instanceof InputRenderable)initEventListeners(instance,InputRenderableEvents.INPUT,propValue,oldPropValue);break;case"onSubmit":if(instance instanceof InputRenderable)initEventListeners(instance,InputRenderableEvents.ENTER,propValue,oldPropValue);else if(instance instanceof TextareaRenderable)instance.onSubmit=propValue;break;case"onSelect":if(instance instanceof SelectRenderable)initEventListeners(instance,SelectRenderableEvents.ITEM_SELECTED,propValue,oldPropValue);else if(instance instanceof TabSelectRenderable)initEventListeners(instance,TabSelectRenderableEvents.ITEM_SELECTED,propValue,oldPropValue);break;case"focused":if(isRenderable(instance))if(propValue)instance.focus();else instance.blur();break;case"style":setStyle(instance,propValue,oldPropValue);break;case"children":break;default:instance[propKey]=propValue}}function setInitialProperties(instance,type,props){for(let propKey in props){if(!props.hasOwnProperty(propKey))continue;let propValue=props[propKey];if(propValue==null)continue;setProperty(instance,type,propKey,propValue)}}function updateProperties(instance,type,oldProps,newProps){for(let propKey in oldProps){let oldProp=oldProps[propKey];if(oldProps.hasOwnProperty(propKey)&&oldProp!=null&&!newProps.hasOwnProperty(propKey))setProperty(instance,type,propKey,null,oldProp)}for(let propKey in newProps){let newProp=newProps[propKey],oldProp=oldProps[propKey];if(newProps.hasOwnProperty(propKey)&&newProp!==oldProp&&(newProp!=null||oldProp!=null))setProperty(instance,type,propKey,newProp,oldProp)}}var currentUpdatePriority=$NoEventPriority,hostConfig={supportsMutation:!0,supportsPersistence:!1,supportsHydration:!1,supportsMicrotasks:!0,scheduleMicrotask:queueMicrotask,createInstance(type,props,rootContainerInstance,hostContext){if(textNodeKeys.includes(type)&&!hostContext.isInsideText)throw Error(`Component of type "${type}" must be created inside of a text node`);let id=getNextId(type),components=getComponentCatalogue();if(!components[type])throw Error(`Unknown component type: ${type}`);return new components[type](rootContainerInstance.ctx,{id,...props})},appendChild(parent,child){parent.add(child)},removeChild(parent,child){if(!child.parent)return;parent.remove(child)},insertBefore(parent,child,beforeChild){parent.insertBefore(child,beforeChild)},insertInContainerBefore(parent,child,beforeChild){parent.insertBefore(child,beforeChild)},removeChildFromContainer(parent,child){if(!child.parent)return;parent.remove(child)},prepareForCommit(containerInfo){return null},resetAfterCommit(containerInfo){containerInfo.requestRender()},getRootHostContext(rootContainerInstance){return{isInsideText:!1}},getChildHostContext(parentHostContext,type,rootContainerInstance){let isInsideText=["text",...textNodeKeys].includes(type);return{...parentHostContext,isInsideText}},shouldSetTextContent(type,props){return!1},createTextInstance(text,rootContainerInstance,hostContext){if(!hostContext.isInsideText)throw Error("Text must be created inside of a text node");return TextNodeRenderable.fromString(text)},scheduleTimeout:setTimeout,cancelTimeout:clearTimeout,noTimeout:-1,shouldAttemptEagerTransition(){return!0},finalizeInitialChildren(instance,type,props,rootContainerInstance,hostContext){return setInitialProperties(instance,type,props),!1},commitMount(instance,type,props,internalInstanceHandle){},commitUpdate(instance,type,oldProps,newProps,internalInstanceHandle){updateProperties(instance,type,oldProps,newProps)},commitTextUpdate(textInstance,oldText,newText){textInstance.children=[newText]},appendChildToContainer(container,child){container.add(child)},appendInitialChild(parent,child){parent.add(child)},hideInstance(instance){instance.visible=!1},unhideInstance(instance,props){instance.visible=!0},hideTextInstance(textInstance){textInstance.visible=!1},unhideTextInstance(textInstance,text){textInstance.visible=!0},clearContainer(container){container.getChildren().forEach((child)=>container.remove(child))},setCurrentUpdatePriority(newPriority){currentUpdatePriority=newPriority},getCurrentUpdatePriority:()=>currentUpdatePriority,resolveUpdatePriority(){if(currentUpdatePriority!==$NoEventPriority)return currentUpdatePriority;return $DefaultEventPriority},maySuspendCommit(){return!1},maySuspendCommitOnUpdate(){return!1},maySuspendCommitInSyncRender(){return!1},NotPendingTransition:null,HostTransitionContext:import_react4.createContext(null),resetFormInstance(){},requestPostPaintCallback(){},trackSchedulerEvent(){},resolveEventType(){return null},resolveEventTimeStamp(){return-1.1},preloadInstance(){return!0},startSuspendingCommit(){},suspendInstance(){},waitForCommitToBeReady(){return null},detachDeletedInstance(instance){if(!instance.parent)instance.destroyRecursively()},getPublicInstance(instance){return instance},preparePortalMount(containerInfo){},isPrimaryRenderer:!0,getInstanceFromNode(){return null},beforeActiveInstanceBlur(){},afterActiveInstanceBlur(){},prepareScopeUpdate(){},getInstanceFromScope(){return null},rendererPackageName:"@opentui/react",rendererVersion:package_default.version},reconciler=import_react_reconciler.default(hostConfig);reconciler.injectIntoDevTools();function _render(element,root){let container=reconciler.createContainer(root,$ConcurrentRoot,null,!1,null,"",console.error,console.error,console.error,()=>{});return reconciler.updateContainer(element,container,null,()=>{}),container}var _r=reconciler,flushSync=_r.flushSyncFromReconciler??_r.flushSync;function createRoot(renderer){let container=null,cleanup=()=>{if(container)reconciler.updateContainer(null,container,null,()=>{}),reconciler.flushSyncWork(),container=null};return renderer.once(CliRenderEvents.DESTROY,cleanup),{render:(node)=>{engine.attach(renderer),container=_render(import_react2.default.createElement(AppContext.Provider,{value:{keyHandler:renderer.keyInput,renderer}},import_react2.default.createElement(ErrorBoundary,null,node)),renderer.root)},unmount:cleanup}}var import_react5=__toESM(require_react_production(),1),import_react6=__toESM(require_react_production(),1),import_react7=__toESM(require_react_production(),1),import_react8=__toESM(require_react_production(),1),import_react9=__toESM(require_react_production(),1),import_react10=__toESM(require_react_production(),1),import_react11=__toESM(require_react_production(),1),import_react12=__toESM(require_react_production(),1);var import_react13=__toESM(require_react_production(),1);var import_react14=__toESM(require_react_production(),1);var import_react15=__toESM(require_react_production(),1),import_react16=__toESM(require_react_production(),1);function useEffectEvent(handler){let handlerRef=import_react6.useRef(handler);return import_react6.useLayoutEffect(()=>{handlerRef.current=handler}),import_react6.useCallback((...args)=>{let fn=handlerRef.current;return fn(...args)},[])}var useRenderer=()=>{let{renderer}=useAppContext();if(!renderer)throw Error("Renderer not found.");return renderer};var useKeyboard=(handler,options={release:!1})=>{let{keyHandler}=useAppContext(),stableHandler=useEffectEvent(handler);import_react8.useEffect(()=>{if(keyHandler?.on("keypress",stableHandler),options?.release)keyHandler?.on("keyrelease",stableHandler);return()=>{if(keyHandler?.off("keypress",stableHandler),options?.release)keyHandler?.off("keyrelease",stableHandler)}},[keyHandler,options.release])};var useOnResize=(callback)=>{let renderer=useRenderer(),stableCallback=useEffectEvent(callback);return import_react10.useEffect(()=>{return renderer.on("resize",stableCallback),()=>{renderer.off("resize",stableCallback)}},[renderer]),renderer};var useTerminalDimensions=()=>{let renderer=useRenderer(),[dimensions,setDimensions]=import_react12.useState({width:renderer.width,height:renderer.height});return useOnResize((width,height)=>{setDimensions({width,height})}),dimensions};function createReactSlotRegistry(renderer,context,options={}){return createSlotRegistry(renderer,"react:slot-registry",context,options)}function renderPluginFailurePlaceholder(registry,pluginFailurePlaceholder,failure,pluginId,slot){if(!pluginFailurePlaceholder)return null;try{return pluginFailurePlaceholder(failure)}catch(error){return registry.reportPluginError({pluginId,slot,phase:"error_placeholder",source:"react",error}),null}}class PluginErrorBoundary extends import_react14.default.Component{constructor(props){super(props);this.state={failure:null}}componentDidCatch(error){let failure=this.props.registry.reportPluginError({pluginId:this.props.pluginId,slot:this.props.slotName,phase:"render",source:"react",error});this.setState({failure})}componentDidUpdate(previousProps){if(previousProps.resetToken!==this.props.resetToken&&this.state.failure)this.setState({failure:null})}render(){if(this.state.failure){let placeholder=renderPluginFailurePlaceholder(this.props.registry,this.props.pluginFailurePlaceholder,this.state.failure,this.props.pluginId,this.props.slotName);if(placeholder===null||placeholder===void 0||placeholder===!1)return this.props.fallbackOnFailure??null;return placeholder}return this.props.children}}function getSlotProps(props){let{children:_children,mode:_mode,name:_name,registry:_registry,pluginFailurePlaceholder:_pluginFailurePlaceholder,...slotProps}=props;return slotProps}function createSlot(registry,options={}){return function(props){return jsxDEV(Slot,{...props,registry,pluginFailurePlaceholder:options.pluginFailurePlaceholder},void 0,!1,void 0,this)}}function Slot(props){let[version,setVersion]=import_react14.useState(0),registry=props.registry,slotName=String(props.name),renderFailuresByPluginRef=import_react14.useRef(new Map),pendingRenderReportsRef=import_react14.useRef(new Map);import_react14.useEffect(()=>{return registry.subscribe(()=>{setVersion((current)=>current+1)})},[registry]),import_react14.useEffect(()=>{if(pendingRenderReportsRef.current.size===0)return;let pendingReports=[...pendingRenderReportsRef.current.values()];pendingRenderReportsRef.current.clear();for(let report of pendingReports){let failure=registry.reportPluginError({pluginId:report.pluginId,slot:report.slot,phase:"render",source:"react",error:report.error});renderFailuresByPluginRef.current.set(`${report.slot}:${report.pluginId}:render`,failure)}});let entries=import_react14.useMemo(()=>registry.resolveEntries(props.name),[registry,props.name,version]),slotProps=getSlotProps(props),renderEntry=(entry,fallbackOnFailure)=>{let key=`${slotName}:${entry.id}`,failureKey=`${slotName}:${entry.id}:render`;try{let rendered=entry.renderer(registry.context,slotProps);return renderFailuresByPluginRef.current.delete(failureKey),pendingRenderReportsRef.current.delete(failureKey),jsxDEV(PluginErrorBoundary,{registry,pluginFailurePlaceholder:props.pluginFailurePlaceholder,pluginId:entry.id,slotName,resetToken:version,fallbackOnFailure,children:rendered},key,!1,void 0,this)}catch(error){let normalizedError=error instanceof Error?error:typeof error==="string"?Error(error):Error(String(error)),lastFailure=renderFailuresByPluginRef.current.get(failureKey),isSameFailure=lastFailure&&lastFailure.error.message===normalizedError.message;if(!isSameFailure){let queued=pendingRenderReportsRef.current.get(failureKey);if(!queued||queued.error.message!==normalizedError.message)pendingRenderReportsRef.current.set(failureKey,{pluginId:entry.id,slot:slotName,error:normalizedError})}let failure=isSameFailure&&lastFailure?lastFailure:{pluginId:entry.id,slot:slotName,phase:"render",source:"react",error:normalizedError,timestamp:Date.now()};renderFailuresByPluginRef.current.set(failureKey,failure);let placeholder=renderPluginFailurePlaceholder(registry,props.pluginFailurePlaceholder,failure,entry.id,slotName);if(placeholder===null||placeholder===void 0||placeholder===!1)return fallbackOnFailure??null;return jsxDEV(import_react14.Fragment,{children:placeholder},key,!1,void 0,this)}};if(entries.length===0)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);if(props.mode==="single_winner"){let winner=entries[0];if(!winner)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);let rendered=renderEntry(winner,props.children);if(rendered===null||rendered===void 0||rendered===!1)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);return jsxDEV($Fragment,{children:rendered},void 0,!1,void 0,this)}if(props.mode==="replace"){if(entries.length===1){let rendered=renderEntry(entries[0],props.children);if(rendered===null||rendered===void 0||rendered===!1)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);return jsxDEV($Fragment,{children:rendered},void 0,!1,void 0,this)}let renderedEntries=entries.map((entry)=>renderEntry(entry));if(!renderedEntries.some((node)=>node!==null&&node!==void 0&&node!==!1))return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);return jsxDEV($Fragment,{children:renderedEntries},void 0,!1,void 0,this)}return jsxDEV($Fragment,{children:[props.children,entries.map((entry)=>renderEntry(entry))]},void 0,!0,void 0,this)}extend({"time-to-first-draw":TimeToFirstDrawRenderable});init_perf();var import_react165=__toESM(require_react_production(),1);var INTERP_RE=/\{!(.+?)\}/g,hasInterp=(s)=>/\{!.+?\}/.test(s);async function interpolate(gw,text){let hits=[...text.matchAll(INTERP_RE)];if(hits.length===0)return text;let outs=await Promise.all(hits.map((m2)=>gw.request("shell.exec",{command:m2[1]}).then((r)=>[r.stdout,r.stderr].filter(Boolean).join(`
3673
- `).trim()).catch(()=>"(error)"))),out=text;for(let i=hits.length-1;i>=0;i--){let m2=hits[i];out=out.slice(0,m2.index)+outs[i]+out.slice(m2.index+m2[0].length)}return out}var import_react17=__toESM(require_react_production(),1);import{EventEmitter as EventEmitter7}from"events";import{homedir}from"os";import{resolve as resolve3,delimiter}from"path";import{existsSync as existsSync4}from"fs";var BAD=/[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]/g;function scalar(s){let count2=0;return{text:s.replace(BAD,(m2)=>{if(m2.length===2)return m2;return count2+=1,"\uFFFD"}),count:count2}}function encode(v2){let paths=new WeakMap,issues=[];return{text:JSON.stringify(v2,function(key,value){let holder=this&&typeof this==="object"?paths.get(this):void 0,path4=key?`${holder??"$"}.${key}`:"$";if(value&&typeof value==="object")paths.set(value,path4);if(typeof value!=="string")return value;let next=scalar(value);if(next.count>0)issues.push({path:path4,count:next.count});return next.text})??"null",issues}}var LOG_MAX=200,LOG_PREVIEW=240,STARTUP_MS=15000,REQUEST_MS=120000,WS_CONNECTING=0,WS_OPEN=1,WS_CLOSING=2,WS_CLOSED=3,decoder2=new TextDecoder;function hermesAgentRoot(){if(process.env.HERMES_AGENT_ROOT)return process.env.HERMES_AGENT_ROOT;let homePath=`${process.env.HOME||homedir()}/.hermes/hermes-agent`;if(existsSync4(homePath))return homePath;let fhs="/usr/local/lib/hermes-agent";if(existsSync4(fhs))return fhs;return homePath}function gatewayUrl(){return process.env.HERM_GATEWAY_URL?.trim()||process.env.HERMES_TUI_GATEWAY_URL?.trim()||null}function websocketUrl(raw){let url=new URL(raw);if(url.protocol==="http:")url.protocol="ws:";else if(url.protocol==="https:")url.protocol="wss:";else if(url.protocol!=="ws:"&&url.protocol!=="wss:")throw Error(`unsupported gateway URL protocol: ${url.protocol}`);let prefix=url.pathname.replace(/\/+$/,"");if(!prefix.endsWith("/api/ws"))url.pathname=`${prefix}/api/ws`;return url.toString()}function redact(raw){try{let url=new URL(raw);if(url.username||url.password)url.username="***",url.password="";if(url.search)url.search="?***";return url.toString()}catch{return"invalid gateway URL"}}function python(root,platform=process.platform){let env2=process.env.HERMES_PYTHON?.trim();if(env2)return env2;let venv=process.env.VIRTUAL_ENV?.trim();return(platform==="win32"?[venv&&resolve3(venv,"Scripts","python.exe"),resolve3(root,"venv","Scripts","python.exe"),resolve3(root,".venv","Scripts","python.exe")]:[venv&&resolve3(venv,"bin","python"),venv&&resolve3(venv,"bin","python3"),resolve3(root,"venv","bin","python"),resolve3(root,"venv","bin","python3"),resolve3(root,".venv","bin","python"),resolve3(root,".venv","bin","python3")]).find((p)=>p&&existsSync4(p))||(platform==="win32"?"python":"python3")}function asEvent(v2){if(v2&&typeof v2==="object"&&!Array.isArray(v2)&&typeof v2.type==="string")return v2;return null}function text(raw){if(typeof raw==="string")return raw;if(raw instanceof ArrayBuffer)return decoder2.decode(raw);if(ArrayBuffer.isView(raw))return decoder2.decode(raw);return null}async function lines(stream,cb){let reader=stream.getReader(),decoder3=new TextDecoder,buf="";try{while(!0){let{done,value}=await reader.read();if(done)break;buf+=decoder3.decode(value,{stream:!0});let parts=buf.split(`
3674
- `);buf=parts.pop()||"";for(let line of parts)if(line)cb(line)}if(buf.trim())cb(buf)}catch{}}class GatewayClient extends EventEmitter7{proc=null;ws=null;link=null;target=null;id=0;logs=[];pending=new Map;buf=[];exit;ok=!1;timer=null;sub=!1;root(){return hermesAgentRoot()}push(ev){if(ev.type==="gateway.ready"){if(this.ok=!0,this.timer)clearTimeout(this.timer),this.timer=null}if(this.sub)return void this.emit("event",ev);this.buf.push(ev)}log(line){if(this.logs.push(line)>LOG_MAX)this.logs.splice(0,this.logs.length-LOG_MAX)}dispatch(msg){let id=msg.id,p=id?this.pending.get(id):void 0;if(p){if(this.pending.delete(id),msg.error){let err=msg.error;p.reject(Error(typeof err?.message==="string"?err.message:"request failed"))}else p.resolve(msg.result);return}if(msg.method==="event"){let ev=asEvent(msg.params);if(ev)this.push(ev)}}fail(err){for(let p of this.pending.values())p.reject(err);this.pending.clear()}connect(raw){let cwd=process.env.HERMES_CWD||process.cwd(),url;try{url=websocketUrl(raw)}catch(err){let message=err instanceof Error?err.message:String(err);if(this.log(`[startup] websocket failed: ${message}`),this.push({type:"gateway.stderr",payload:{line:message}}),this.sub)this.emit("exit",null);else this.exit=null;return}let safe=redact(url),ws;try{ws=new WebSocket(url)}catch(err){let message=err instanceof Error?err.message:String(err);if(this.log(`[startup] websocket failed (${safe}): ${message}`),this.push({type:"gateway.stderr",payload:{line:message}}),this.sub)this.emit("exit",null);else this.exit=null;return}this.target=raw,this.ws=ws;let settled=!1;this.link=new Promise((resolve4,reject)=>{ws.addEventListener("open",()=>{if(settled)return;settled=!0,resolve4()},{once:!0}),ws.addEventListener("error",()=>{if(settled)return;settled=!0,reject(Error("gateway websocket connection failed"));try{ws.close()}catch{}},{once:!0}),ws.addEventListener("close",(event)=>{if(settled)return;settled=!0,reject(Error(`gateway websocket closed (${event.code}) during connect`))},{once:!0})}),this.link.catch(()=>{}),this.timer=setTimeout(()=>{if(this.ok||this.ws!==ws)return;this.log(`[startup] timed out (websocket=${safe}, cwd=${cwd})`),this.push({type:"gateway.start_timeout",payload:{cwd,python:"websocket"}}),this.ws=null,this.link=null,this.fail(Error("gateway websocket startup timeout"));try{ws.close()}catch{}if(this.sub)this.emit("exit",null);else this.exit=null},STARTUP_MS),ws.addEventListener("message",(event)=>{if(this.ws!==ws)return;let raw2=text(event.data);if(!raw2)return;try{this.dispatch(JSON.parse(raw2))}catch{let preview=raw2.trim().slice(0,LOG_PREVIEW)||"(empty)";this.log(`[protocol] malformed websocket: ${preview}`),this.push({type:"gateway.protocol_error",payload:{preview}})}}),ws.addEventListener("error",()=>{if(this.ws!==ws)return;let line=`websocket transport error (${safe})`;this.log(`[gateway] ${line}`),this.push({type:"gateway.stderr",payload:{line}})}),ws.addEventListener("close",(event)=>{if(this.ws!==ws)return;if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.ws=null,this.link=null,this.fail(Error(`gateway websocket closed${event.code?` (${event.code})`:""}`)),this.sub)this.emit("exit",event.code);else this.exit=event.code})}start(){let raw=gatewayUrl(),root=this.root(),bin=python(root),cwd=process.env.HERMES_CWD||process.cwd(),env2={...process.env};if(!env2.TERMINAL_CWD)env2.TERMINAL_CWD=cwd;let pp=env2.PYTHONPATH?.trim();env2.PYTHONPATH=pp?`${root}${delimiter}${pp}`:root,env2.HERMES_PYTHON_SRC_ROOT=root,this.ok=!1,this.buf=[],this.exit=void 0;let restarted=!1,previous=this.proc;if(previous){this.proc=null,this.fail(Error("gateway restarted")),restarted=!0;try{previous.kill()}catch{}}let socket=this.ws;if(socket){if(this.ws=null,this.link=null,this.target=null,!restarted)this.fail(Error("gateway restarted"));try{socket.close()}catch{}}if(this.timer)clearTimeout(this.timer);if(raw){this.connect(raw);return}this.timer=setTimeout(()=>{if(this.ok)return;this.log(`[startup] timed out (python=${bin}, cwd=${cwd})`),this.push({type:"gateway.start_timeout",payload:{cwd,python:bin}});let proc2=this.proc;if(!proc2||proc2.exitCode!==null)return;try{proc2.kill()}catch(err){this.proc=null;let failure=Error(`gateway startup timeout: ${err instanceof Error?err.message:String(err)}`);if(this.fail(failure),this.sub)this.emit("exit",null);else this.exit=null}},STARTUP_MS);let proc=(()=>{try{return Bun.spawn([bin,"-u","-m","tui_gateway.entry"],{cwd,env:env2,stdin:"pipe",stdout:"pipe",stderr:"pipe"})}catch(err){if(this.timer)clearTimeout(this.timer),this.timer=null;this.proc=null;let message=err instanceof Error?err.message:String(err);if(this.log(`[startup] spawn failed: ${message}`),this.push({type:"gateway.stderr",payload:{line:message}}),this.sub)this.emit("exit",null);else this.exit=null;return null}})();if(!proc)return;if(this.proc=proc,proc.stdout)lines(proc.stdout,(raw2)=>{if(this.proc!==proc)return;try{this.dispatch(JSON.parse(raw2))}catch{let preview=raw2.trim().slice(0,LOG_PREVIEW)||"(empty)";this.log(`[protocol] malformed: ${preview}`),this.push({type:"gateway.protocol_error",payload:{preview}})}});if(proc.stderr)lines(proc.stderr,(raw2)=>{if(this.proc!==proc)return;let line=raw2.trim();if(!line)return;this.log(line),this.push({type:"gateway.stderr",payload:{line}})});proc.exited.then((code)=>{if(this.proc!==proc)return;if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.fail(Error(`gateway exited${code===null?"":` (${code})`}`)),this.sub)this.emit("exit",code);else this.exit=code})}drain(){if(this.sub)return;this.sub=!0;for(let ev of this.buf.splice(0))this.emit("event",ev);if(this.exit!==void 0){let code=this.exit;this.exit=void 0,this.emit("exit",code)}}tail(n=20){return this.logs.slice(-Math.max(1,n)).join(`
3673
+ `).trim()).catch(()=>"(error)"))),out=text;for(let i=hits.length-1;i>=0;i--){let m2=hits[i];out=out.slice(0,m2.index)+outs[i]+out.slice(m2.index+m2[0].length)}return out}var import_react17=__toESM(require_react_production(),1);import{EventEmitter as EventEmitter7}from"events";import{homedir}from"os";import{resolve as resolve3,delimiter}from"path";import{existsSync as existsSync4}from"fs";var GATEWAY_EVENT_TYPES=["gateway.ready","gateway.stderr","gateway.start_timeout","gateway.protocol_error","session.info","session.title","skin.changed","message.start","message.delta","message.complete","thinking.delta","reasoning.delta","reasoning.available","moa.reference","moa.aggregating","status.update","notification.show","notification.clear","tool.start","tool.progress","tool.generating","tool.complete","clarify.request","approval.request","sudo.request","secret.request","background.complete","review.summary","btw.complete","browser.progress","voice.status","voice.transcript","subagent.start","subagent.thinking","subagent.tool","subagent.progress","subagent.complete","error"],EVENT_TYPES=new Set(GATEWAY_EVENT_TYPES);function knownGatewayEvent(type){return EVENT_TYPES.has(type)}var BAD=/[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]/g;function scalar(s){let count2=0;return{text:s.replace(BAD,(m2)=>{if(m2.length===2)return m2;return count2+=1,"\uFFFD"}),count:count2}}function encode(v2){let paths=new WeakMap,issues=[];return{text:JSON.stringify(v2,function(key,value){let holder=this&&typeof this==="object"?paths.get(this):void 0,path4=key?`${holder??"$"}.${key}`:"$";if(value&&typeof value==="object")paths.set(value,path4);if(typeof value!=="string")return value;let next=scalar(value);if(next.count>0)issues.push({path:path4,count:next.count});return next.text})??"null",issues}}var LOG_MAX=200,LOG_PREVIEW=240,STARTUP_MS=15000,REQUEST_MS=120000,WS_CONNECTING=0,WS_OPEN=1,WS_CLOSING=2,WS_CLOSED=3,decoder2=new TextDecoder;function hermesAgentRoot(){if(process.env.HERMES_AGENT_ROOT)return process.env.HERMES_AGENT_ROOT;let homePath=`${process.env.HOME||homedir()}/.hermes/hermes-agent`;if(existsSync4(homePath))return homePath;let fhs="/usr/local/lib/hermes-agent";if(existsSync4(fhs))return fhs;return homePath}function gatewayUrl(){return process.env.HERM_GATEWAY_URL?.trim()||process.env.HERMES_TUI_GATEWAY_URL?.trim()||null}function websocketUrl(raw){let url=new URL(raw);if(url.protocol==="http:")url.protocol="ws:";else if(url.protocol==="https:")url.protocol="wss:";else if(url.protocol!=="ws:"&&url.protocol!=="wss:")throw Error(`unsupported gateway URL protocol: ${url.protocol}`);let prefix=url.pathname.replace(/\/+$/,"");if(!prefix.endsWith("/api/ws"))url.pathname=`${prefix}/api/ws`;return url.toString()}function redact(raw){try{let url=new URL(raw);if(url.username||url.password)url.username="***",url.password="";if(url.search)url.search="?***";return url.toString()}catch{return"invalid gateway URL"}}function python(root,platform=process.platform){let env2=process.env.HERMES_PYTHON?.trim();if(env2)return env2;let venv=process.env.VIRTUAL_ENV?.trim();return(platform==="win32"?[venv&&resolve3(venv,"Scripts","python.exe"),resolve3(root,"venv","Scripts","python.exe"),resolve3(root,".venv","Scripts","python.exe")]:[venv&&resolve3(venv,"bin","python"),venv&&resolve3(venv,"bin","python3"),resolve3(root,"venv","bin","python"),resolve3(root,"venv","bin","python3"),resolve3(root,".venv","bin","python"),resolve3(root,".venv","bin","python3")]).find((p)=>p&&existsSync4(p))||(platform==="win32"?"python":"python3")}function asEvent(v2){if(v2&&typeof v2==="object"&&!Array.isArray(v2)&&typeof v2.type==="string")return v2;return null}function text(raw){if(typeof raw==="string")return raw;if(raw instanceof ArrayBuffer)return decoder2.decode(raw);if(ArrayBuffer.isView(raw))return decoder2.decode(raw);return null}function rec(v2){if(v2&&typeof v2==="object"&&!Array.isArray(v2))return v2;return null}function crop(s){return s.length>LOG_PREVIEW?`${s.slice(0,LOG_PREVIEW)}\u2026`:s}function clean(v2,depth,seen){if(v2===null||typeof v2==="number"||typeof v2==="boolean")return v2;if(typeof v2==="string")return crop(v2);if(v2===void 0)return"[undefined]";if(typeof v2!=="object")return`[${typeof v2}]`;if(seen.has(v2))return"[circular]";if(depth>=3)return"[depth]";if(seen.add(v2),Array.isArray(v2)){let vals=v2.slice(0,6).map((x2)=>clean(x2,depth+1,seen));return v2.length>vals.length?[...vals,`\u2026+${v2.length-vals.length}`]:vals}let out={};for(let[key,val]of Object.entries(v2).slice(0,12))out[key]=/token|secret|password|credential|authorization|api[_-]?key|cookie|private[_-]?key/i.test(key)?"[redacted]":clean(val,depth+1,seen);let extra=Object.keys(v2).length-Object.keys(out).length;if(extra>0)out["\u2026"]=`+${extra}`;return out}function payload(ev){let obj=rec(ev);if(!obj||!("payload"in obj))return"(none)";try{return crop(JSON.stringify(clean(obj.payload,0,new WeakSet)))}catch{return"[unserializable]"}}function contract(ev){let obj=rec(ev),body=rec(obj?.payload),raw=obj?.contract_version??obj?.contractVersion??body?.contract_version??body?.contractVersion??rec(body?.contract)?.version;return raw===void 0||raw===null?"unknown":crop(String(raw))}async function lines(stream,cb){let reader=stream.getReader(),decoder3=new TextDecoder,buf="";try{while(!0){let{done,value}=await reader.read();if(done)break;buf+=decoder3.decode(value,{stream:!0});let parts=buf.split(`
3674
+ `);buf=parts.pop()||"";for(let line of parts)if(line)cb(line)}if(buf.trim())cb(buf)}catch{}}class GatewayClient extends EventEmitter7{proc=null;ws=null;link=null;target=null;id=0;logs=[];unknown=new Map;pending=new Map;buf=[];exit;ok=!1;timer=null;sub=!1;root(){return hermesAgentRoot()}push(ev,source="internal"){if(this.diagnose(ev,source),ev.type==="gateway.ready"){if(this.ok=!0,this.timer)clearTimeout(this.timer),this.timer=null}if(this.sub)return void this.emit("event",ev);this.buf.push(ev)}log(line){if(this.logs.push(line)>LOG_MAX){let cut=this.logs.length-LOG_MAX;this.logs.splice(0,cut);for(let d2 of this.unknown.values())d2.index-=cut}return this.logs.length-1}diagnose(ev,source="control"){try{if(knownGatewayEvent(ev.type))return;let version=contract(ev),key=`${source}\x00${version}\x00${ev.type}`,old=this.unknown.get(key);if(old&&old.index>=0&&old.index<this.logs.length){old.count++,this.logs[old.index]=old.line(old.count);return}let summary=payload(ev),line=(count2)=>`[event unknown] type=${ev.type} source=${source} contract=${version} count=${count2} payload=${summary}`;this.unknown.set(key,{count:1,index:this.log(line(1)),line})}catch(err){let text2=err instanceof Error?err.message:String(err);this.log(`[event diagnostic_failed] source=${source} error=${crop(text2)}`)}}dispatch(msg,source="stdio"){let id=msg.id,p=id?this.pending.get(id):void 0;if(p){if(this.pending.delete(id),msg.error){let err=msg.error;p.reject(Error(typeof err?.message==="string"?err.message:"request failed"))}else p.resolve(msg.result);return}if(msg.method==="event"){let ev=asEvent(msg.params);if(ev)this.push(ev,source)}}fail(err){for(let p of this.pending.values())p.reject(err);this.pending.clear()}connect(raw){let cwd=process.env.HERMES_CWD||process.cwd(),url;try{url=websocketUrl(raw)}catch(err){let message=err instanceof Error?err.message:String(err);if(this.log(`[startup] websocket failed: ${message}`),this.push({type:"gateway.stderr",payload:{line:message}}),this.sub)this.emit("exit",null);else this.exit=null;return}let safe=redact(url),ws;try{ws=new WebSocket(url)}catch(err){let message=err instanceof Error?err.message:String(err);if(this.log(`[startup] websocket failed (${safe}): ${message}`),this.push({type:"gateway.stderr",payload:{line:message}}),this.sub)this.emit("exit",null);else this.exit=null;return}this.target=raw,this.ws=ws;let settled=!1;this.link=new Promise((resolve4,reject)=>{ws.addEventListener("open",()=>{if(settled)return;settled=!0,resolve4()},{once:!0}),ws.addEventListener("error",()=>{if(settled)return;settled=!0,reject(Error("gateway websocket connection failed"));try{ws.close()}catch{}},{once:!0}),ws.addEventListener("close",(event)=>{if(settled)return;settled=!0,reject(Error(`gateway websocket closed (${event.code}) during connect`))},{once:!0})}),this.link.catch(()=>{}),this.timer=setTimeout(()=>{if(this.ok||this.ws!==ws)return;this.log(`[startup] timed out (websocket=${safe}, cwd=${cwd})`),this.push({type:"gateway.start_timeout",payload:{cwd,python:"websocket"}}),this.ws=null,this.link=null,this.fail(Error("gateway websocket startup timeout"));try{ws.close()}catch{}if(this.sub)this.emit("exit",null);else this.exit=null},STARTUP_MS),ws.addEventListener("message",(event)=>{if(this.ws!==ws)return;let raw2=text(event.data);if(!raw2)return;try{this.dispatch(JSON.parse(raw2),"websocket")}catch{let preview=raw2.trim().slice(0,LOG_PREVIEW)||"(empty)";this.log(`[protocol] malformed websocket: ${preview}`),this.push({type:"gateway.protocol_error",payload:{preview}})}}),ws.addEventListener("error",()=>{if(this.ws!==ws)return;let line=`websocket transport error (${safe})`;this.log(`[gateway] ${line}`),this.push({type:"gateway.stderr",payload:{line}})}),ws.addEventListener("close",(event)=>{if(this.ws!==ws)return;if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.ws=null,this.link=null,this.fail(Error(`gateway websocket closed${event.code?` (${event.code})`:""}`)),this.sub)this.emit("exit",event.code);else this.exit=event.code})}start(){let raw=gatewayUrl(),root=this.root(),bin=python(root),cwd=process.env.HERMES_CWD||process.cwd(),env2={...process.env};if(!env2.TERMINAL_CWD)env2.TERMINAL_CWD=cwd;let pp=env2.PYTHONPATH?.trim();env2.PYTHONPATH=pp?`${root}${delimiter}${pp}`:root,env2.HERMES_PYTHON_SRC_ROOT=root,this.ok=!1,this.buf=[],this.exit=void 0;let restarted=!1,previous=this.proc;if(previous){this.proc=null,this.fail(Error("gateway restarted")),restarted=!0;try{previous.kill()}catch{}}let socket=this.ws;if(socket){if(this.ws=null,this.link=null,this.target=null,!restarted)this.fail(Error("gateway restarted"));try{socket.close()}catch{}}if(this.timer)clearTimeout(this.timer);if(raw){this.connect(raw);return}this.timer=setTimeout(()=>{if(this.ok)return;this.log(`[startup] timed out (python=${bin}, cwd=${cwd})`),this.push({type:"gateway.start_timeout",payload:{cwd,python:bin}});let proc2=this.proc;if(!proc2||proc2.exitCode!==null)return;try{proc2.kill()}catch(err){this.proc=null;let failure=Error(`gateway startup timeout: ${err instanceof Error?err.message:String(err)}`);if(this.fail(failure),this.sub)this.emit("exit",null);else this.exit=null}},STARTUP_MS);let proc=(()=>{try{return Bun.spawn([bin,"-u","-m","tui_gateway.entry"],{cwd,env:env2,stdin:"pipe",stdout:"pipe",stderr:"pipe"})}catch(err){if(this.timer)clearTimeout(this.timer),this.timer=null;this.proc=null;let message=err instanceof Error?err.message:String(err);if(this.log(`[startup] spawn failed: ${message}`),this.push({type:"gateway.stderr",payload:{line:message}}),this.sub)this.emit("exit",null);else this.exit=null;return null}})();if(!proc)return;if(this.proc=proc,proc.stdout)lines(proc.stdout,(raw2)=>{if(this.proc!==proc)return;try{this.dispatch(JSON.parse(raw2),"stdio")}catch{let preview=raw2.trim().slice(0,LOG_PREVIEW)||"(empty)";this.log(`[protocol] malformed: ${preview}`),this.push({type:"gateway.protocol_error",payload:{preview}})}});if(proc.stderr)lines(proc.stderr,(raw2)=>{if(this.proc!==proc)return;let line=raw2.trim();if(!line)return;this.log(line),this.push({type:"gateway.stderr",payload:{line}})});proc.exited.then((code)=>{if(this.proc!==proc)return;if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.fail(Error(`gateway exited${code===null?"":` (${code})`}`)),this.sub)this.emit("exit",code);else this.exit=code})}drain(){if(this.sub)return;this.sub=!0;for(let ev of this.buf.splice(0))this.emit("event",ev);if(this.exit!==void 0){let code=this.exit;this.exit=void 0,this.emit("exit",code)}}tail(n=20){return this.logs.slice(-Math.max(1,n)).join(`
3675
3675
  `)}sid="";setSession(sid){this.sid=sid}request(method,params={}){let raw=gatewayUrl();if(raw)return this.remote(raw,method,params);if(!this.proc||this.proc.exitCode!==null)this.start();let stdin=this.proc?.stdin;if(!stdin||typeof stdin==="number")return Promise.reject(Error("gateway not running"));let rid=`r${++this.id}`,writer=stdin,merged=this.sid&&params.session_id===void 0?{session_id:this.sid,...params}:params;return new Promise((resolve4,reject)=>{let timeout=setTimeout(()=>{if(this.pending.delete(rid))reject(Error(`timeout: ${method}`))},REQUEST_MS);this.pending.set(rid,{reject:(e)=>{clearTimeout(timeout),reject(e)},resolve:(v2)=>{clearTimeout(timeout),resolve4(v2)}});try{let frame=encode({jsonrpc:"2.0",id:rid,method,params:merged});if(frame.issues.length){let detail=frame.issues.map((x2)=>`${x2.path}:${x2.count}`).join(", ");this.log(`[wire] sanitized invalid unicode for ${method}: ${detail}`)}writer.write(frame.text+`
3676
3676
  `)}catch(e){clearTimeout(timeout),this.pending.delete(rid),reject(e instanceof Error?e:Error(String(e)))}})}remote(raw,method,params){try{websocketUrl(raw)}catch(err){return Promise.reject(err instanceof Error?err:Error(String(err)))}if(this.target!==raw||!this.ws||this.ws.readyState===WS_CLOSING||this.ws.readyState===WS_CLOSED)this.start();let rid=`r${++this.id}`,merged=this.sid&&params.session_id===void 0?{session_id:this.sid,...params}:params;return new Promise((resolve4,reject)=>{let timeout=setTimeout(()=>{if(this.pending.delete(rid))reject(Error(`timeout: ${method}`))},REQUEST_MS);this.pending.set(rid,{reject:(e)=>{clearTimeout(timeout),reject(e)},resolve:(value)=>{clearTimeout(timeout),resolve4(value)}}),(async()=>{try{if(this.ws?.readyState===WS_CONNECTING)await this.link;if(!this.pending.has(rid))return;if(!this.ws||this.ws.readyState!==WS_OPEN)throw Error(`gateway not connected: ${method}`);let frame=encode({jsonrpc:"2.0",id:rid,method,params:merged});if(frame.issues.length){let detail=frame.issues.map((x2)=>`${x2.path}:${x2.count}`).join(", ");this.log(`[wire] sanitized invalid unicode for ${method}: ${detail}`)}this.ws.send(frame.text)}catch(err){if(clearTimeout(timeout),this.pending.delete(rid))reject(err instanceof Error?err:Error(String(err)))}})()})}kill(){this.proc?.kill();let ws=this.ws;if(!ws)return;if(this.ws=null,this.link=null,this.target=null,this.timer)clearTimeout(this.timer),this.timer=null;this.fail(Error("gateway websocket closed"));try{ws.close()}catch{}}get ready(){return this.ok}}var Gw=import_react17.createContext(null),GatewayProvider=({client,children})=>{let ref=import_react17.useRef(null);if(!ref.current)ref.current=client??new GatewayClient;let[ready,setReady]=import_react17.useState(ref.current.ready),retry=import_react17.useRef({attempts:0});import_react17.useEffect(()=>{let c=ref.current,onEvent=(ev)=>{if(ev.type==="gateway.ready"||ev.type==="session.info")setReady(!0);if(ev.type==="session.info"){if(retry.current.timer)clearTimeout(retry.current.timer);retry.current={attempts:0}}},onExit=()=>{if(setReady(!1),retry.current.timer)clearTimeout(retry.current.timer);if(retry.current.attempts>=3)return;let delay=250*2**retry.current.attempts++;retry.current.timer=setTimeout(()=>c.start(),delay)};return c.on("event",onEvent),c.on("exit",onExit),c.start(),c.drain(),()=>{if(c.off("event",onEvent),c.off("exit",onExit),retry.current.timer)clearTimeout(retry.current.timer);c.removeAllListeners(),c.kill()}},[]);let restart=import_react17.useCallback((mode="resume")=>{if(retry.current.timer)clearTimeout(retry.current.timer);retry.current={attempts:0},setReady(!1),ref.current.emit("restart",mode),ref.current.start()},[]),value=import_react17.useMemo(()=>({client:ref.current,ready,restart}),[ready,restart]);return $jsx(Gw.Provider,{value,children})};function useGateway(){let ctx=import_react17.useContext(Gw);if(!ctx)throw Error("useGateway() must be inside <GatewayProvider>");return ctx.client}function useGatewayEvent(handler){let ctx=import_react17.useContext(Gw);if(!ctx)throw Error("useGatewayEvent() must be inside <GatewayProvider>");let ref=import_react17.useRef(handler);ref.current=handler,import_react17.useEffect(()=>{let c=ctx.client,fn=(ev)=>ref.current(ev);return c.on("event",fn),c.drain(),()=>{c.off("event",fn)}},[ctx.client])}function useGatewayReady(){let ctx=import_react17.useContext(Gw);if(!ctx)throw Error("useGatewayReady() must be inside <GatewayProvider>");return ctx.ready}function useGatewayRestart(){let ctx=import_react17.useContext(Gw);if(!ctx)throw Error("useGatewayRestart() must be inside <GatewayProvider>");return ctx.restart}function text2(msg){return msg.parts.filter((p)=>p.type==="text").map((p)=>p.content).join("")}function mid(){return`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var pn=0;function pid(){return`p${++pn}`}var import_react26=__toESM(require_react_production(),1);var import_react25=__toESM(require_react_production(),1);var import_react21=__toESM(require_react_production(),1);var import_react20=__toESM(require_react_production(),1);var import_react18=__toESM(require_react_production(),1);function makeUse(ctx,name){return()=>{let v2=import_react18.useContext(ctx);if(v2===null)throw Error(`${name}() must be used inside its provider`);return v2}}function resolveTheme(theme,mode){let defs=theme.defs??{};function resolve4(c,chain=[]){if(c instanceof RGBA)return c;if(typeof c==="string"){if(c==="transparent"||c==="none")return RGBA.fromInts(0,0,0,0);if(c.startsWith("#"))return RGBA.fromHex(c);if(chain.includes(c))throw Error(`Circular color reference: ${[...chain,c].join(" -> ")}`);let next=defs[c]??theme.theme[c];if(next===void 0)throw Error(`Color reference "${c}" not found in defs or theme`);return resolve4(next,[...chain,c])}if(typeof c==="number")return ansiToRgba(c);return resolve4(c[mode],chain)}let resolved=Object.fromEntries(Object.entries(theme.theme).filter(([key])=>key!=="selectedListItemText"&&key!=="backgroundMenu"&&key!=="thinkingOpacity").map(([key,value])=>[key,resolve4(value)])),hasList=theme.theme.selectedListItemText!==void 0;resolved.selectedListItemText=hasList?resolve4(theme.theme.selectedListItemText):resolved.background,resolved.backgroundMenu=theme.theme.backgroundMenu!==void 0?resolve4(theme.theme.backgroundMenu):resolved.backgroundElement;let base={...resolved,_hasSelectedListItemText:hasList,thinkingOpacity:theme.theme.thinkingOpacity??0.6},herm=resolveHermTokens(resolved.accent);return{...base,...herm}}function resolveHermTokens(accent){return{hermAvatar:accent}}function ansiToRgba(code){if(code<16){let colors=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff"];return RGBA.fromHex(colors[code]??"#000000")}if(code<232){let idx=code-16,val=(x2)=>x2===0?0:x2*40+55;return RGBA.fromInts(val(Math.floor(idx/36)),val(Math.floor(idx/6)%6),val(idx%6))}if(code<256){let gray=(code-232)*10+8;return RGBA.fromInts(gray,gray,gray)}return RGBA.fromInts(0,0,0)}var PREVIEW={ares:{primary:"#C7A96B",accent:"#DD4A3A",background:"#2A1212"},aura:{primary:"#a277ff",accent:"#a277ff",background:"#0f0f0f"},ayu:{primary:"#59C2FF",accent:"#E6B450",background:"#0B0E14"},carbonfox:{primary:"#33b1ff",accent:"#ff7eb6",background:"#161616"},"catppuccin-frappe":{primary:"#8da4e2",accent:"#f4b8e4",background:"#303446"},"catppuccin-macchiato":{primary:"#8aadf4",accent:"#f5bde6",background:"#24273a"},catppuccin:{primary:"#89b4fa",accent:"#f5c2e7",background:"#1e1e2e"},charizard:{primary:"#FFD39A",accent:"#F29C38",background:"#2B160E"},cobalt2:{primary:"#0088ff",accent:"#2affdf",background:"#193549"},cursor:{primary:"#88c0d0",accent:"#88c0d0",background:"#181818"},daylight:{primary:"#233662",accent:"#597FE9",background:"#101014"},default:{primary:"#FFD700",accent:"#FFBF00",background:"#1a1a2e"},dracula:{primary:"#bd93f9",accent:"#8be9fd",background:"#282a36"},everforest:{primary:"#a7c080",accent:"#d699b6",background:"#2d353b"},flexoki:{primary:"#DA702C",accent:"#8B7EC8",background:"#100F0F"},github:{primary:"#58a6ff",accent:"#39c5cf",background:"#0d1117"},gruvbox:{primary:"#83a598",accent:"#8ec07c",background:"#282828"},kanagawa:{primary:"#7E9CD8",accent:"#D27E99",background:"#1F1F28"},"lucent-orng":{primary:"#EC5B2B",accent:"#FFF7F1",background:"transparent"},material:{primary:"#82aaff",accent:"#89ddff",background:"#263238"},matrix:{primary:"#2eff6a",accent:"#c770ff",background:"#0a0e0a"},mercury:{primary:"#8da4f5",accent:"#8da4f5",background:"#171721"},mono:{primary:"#e6edf3",accent:"#aaaaaa",background:"#1F1F1F"},monokai:{primary:"#66d9ef",accent:"#a6e22e",background:"#272822"},nightowl:{primary:"#82AAFF",accent:"#c792ea",background:"#011627"},nord:{primary:"#88C0D0",accent:"#8FBCBB",background:"#2E3440"},"one-dark":{primary:"#61afef",accent:"#56b6c2",background:"#282c34"},opencode:{primary:"#fab283",accent:"#9d7cd8",background:"#0a0a0a"},orng:{primary:"#EC5B2B",accent:"#FFF7F1",background:"#0a0a0a"},"osaka-jade":{primary:"#2DD5B7",accent:"#549e6a",background:"#111c18"},palenight:{primary:"#82aaff",accent:"#89ddff",background:"#292d3e"},poseidon:{primary:"#A9DFFF",accent:"#5DB8F5",background:"#0F2440"},rosepine:{primary:"#9ccfd8",accent:"#ebbcba",background:"#191724"},sisyphus:{primary:"#F5F5F5",accent:"#E7E7E7",background:"#202020"},slate:{primary:"#7eb8f6",accent:"#8EA8FF",background:"#151C2F"},solarized:{primary:"#268bd2",accent:"#2aa198",background:"#002b36"},synthwave84:{primary:"#36f9f6",accent:"#b084eb",background:"#262335"},tokyonight:{primary:"#82aaff",accent:"#ff966c",background:"#1a1b26"},vercel:{primary:"#0070F3",accent:"#8E4EC6",background:"#000000"},vesper:{primary:"#FFC799",accent:"#FFC799",background:"#101010"},"warm-lightmode":{primary:"#9D681D",accent:"#CE661C",background:"#101014"},zenburn:{primary:"#8cd0d3",accent:"#93e0e3",background:"#3f3f3f"}},NAMES=Object.keys(PREVIEW).sort();var DEFAULT_THEME="tokyonight",THEME_NAMES=NAMES;var cache=new Map,pending=new Map;async function load(name){let hit=cache.get(name);if(hit)return hit;let inflight=pending.get(name);if(inflight)return inflight;if(!PREVIEW[name])throw Error(`Unknown theme: ${name}`);let p=import(`./themes/${name}.json`).then((m2)=>{let json=m2.default??m2;return cache.set(name,json),pending.delete(name),json});return pending.set(name,p),p}function get(name){return cache.get(name)}async function prime(name){await load(name).catch(()=>{return})}function syntax(theme){return SyntaxStyle.fromTheme(rules(theme))}function rules(theme){return[{scope:["default"],style:{foreground:theme.text}},{scope:["comment","comment.documentation"],style:{foreground:theme.syntaxComment,italic:!0}},{scope:["string","symbol"],style:{foreground:theme.syntaxString}},{scope:["number","boolean"],style:{foreground:theme.syntaxNumber}},{scope:["keyword"],style:{foreground:theme.syntaxKeyword,italic:!0}},{scope:["keyword.return","keyword.conditional","keyword.repeat"],style:{foreground:theme.syntaxKeyword,italic:!0}},{scope:["keyword.type"],style:{foreground:theme.syntaxType,bold:!0}},{scope:["keyword.function","function.method"],style:{foreground:theme.syntaxFunction}},{scope:["function","function.call"],style:{foreground:theme.syntaxFunction}},{scope:["variable","variable.parameter"],style:{foreground:theme.syntaxVariable}},{scope:["type"],style:{foreground:theme.syntaxType}},{scope:["operator"],style:{foreground:theme.syntaxOperator}},{scope:["punctuation","punctuation.bracket","punctuation.delimiter"],style:{foreground:theme.syntaxPunctuation}},{scope:["markup.heading"],style:{foreground:theme.markdownHeading,bold:!0}},{scope:["markup.strong"],style:{foreground:theme.markdownStrong,bold:!0}},{scope:["markup.italic"],style:{foreground:theme.markdownEmph,italic:!0}},{scope:["markup.link"],style:{foreground:theme.markdownLink,underline:!0}},{scope:["markup.raw"],style:{foreground:theme.markdownCode}},{scope:["markup.list"],style:{foreground:theme.markdownListItem}}]}import{existsSync as existsSync7,readFileSync,readdirSync as readdirSync2}from"fs";import{basename as basename2,extname,join as join3}from"path";import{homedir as homedir2}from"os";import{join as join2}from"path";import{existsSync as existsSync6,mkdirSync,readdirSync,renameSync}from"fs";var HOME=()=>process.env.HOME||homedir2(),HERMES_HOME=()=>process.env.HERMES_HOME||join2(HOME(),".hermes"),migrated=!1;function configDir(){let dir=process.env.HERM_CONFIG_DIR||join2(HERMES_HOME(),"herm");if(!migrated)migrated=!0,maybeMigrateLegacy(dir);return dir}function maybeMigrateLegacy(target){if(process.env.HERM_CONFIG_DIR)return;let legacy=join2(HOME(),".config","herm");if(!existsSync6(legacy)||legacy===target)return;try{if(existsSync6(target)&&readdirSync(target).length>0)return;mkdirSync(target,{recursive:!0});for(let name of readdirSync(legacy)){let src=join2(legacy,name),dst=join2(target,name);if(existsSync6(dst))continue;try{renameSync(src,dst)}catch{}}}catch{}}var read=(path4)=>{try{let raw=JSON.parse(readFileSync(path4,"utf8"));if(!raw||typeof raw!=="object")return null;if(!raw.theme||typeof raw.theme!=="object")return null;return[basename2(path4,extname(path4)),raw]}catch{return null}};function userThemes(){let dir=join3(configDir(),"themes");if(!existsSync7(dir))return{};return Object.fromEntries(readdirSync2(dir,{withFileTypes:!0}).filter((e)=>e.isFile()&&e.name.endsWith(".json")).map((e)=>read(join3(dir,e.name))).filter((e)=>e!==null))}var exports_preferences={};__export(exports_preferences,{useRev:()=>useRev,usePref:()=>usePref,set:()=>set,reset:()=>reset,reload:()=>reload,prefs:()=>exports_preferences,load:()=>load2,get:()=>get2});var import_react19=__toESM(require_react_production(),1);import{join as join4}from"path";import{existsSync as existsSync8,mkdirSync as mkdirSync2,readFileSync as readFileSync2,writeFileSync as writeFileSync2}from"fs";var DEFAULTS={mouse:!0,targetFps:30};function configFile(){return join4(configDir(),"tui.json")}var cached=null,rev=0;function reset(){cached=null}function reload(){cached=null,rev++;for(let l of listeners)l()}function load2(){if(cached)return cached;let CONFIG_FILE=configFile();try{if(!existsSync8(CONFIG_FILE)){let prefs2={...DEFAULTS};return cached=prefs2,prefs2}let raw=JSON.parse(readFileSync2(CONFIG_FILE,"utf-8"));if(raw.eikonPath&&!raw.eikon)raw.eikon=raw.eikonPath.split("/").pop()?.replace(/\.eikon$/,""),delete raw.eikonPath;let prefs={...DEFAULTS,...raw};return cached=prefs,prefs}catch{let prefs={...DEFAULTS};return cached=prefs,prefs}}function save(partial){let current=load2();if(partial)Object.assign(current,partial);cached=current;try{let CONFIG_DIR=configDir();if(!existsSync8(CONFIG_DIR))mkdirSync2(CONFIG_DIR,{recursive:!0});let json=JSON.stringify(current,null,2)+`
3677
3677
  `;writeFileSync2(configFile(),json,"utf-8")}catch(err){if(process.env.PERF)console.error("[preferences] failed to save:",err)}}function get2(key){return load2()[key]}function set(key,value){if(load2()[key]===value)return;save({[key]:value}),rev++;for(let l of listeners)l()}var listeners=new Set;function subscribe(l){return listeners.add(l),()=>listeners.delete(l)}function usePref(key){return import_react19.useSyncExternalStore(subscribe,()=>load2()[key])}function useRev(){return import_react19.useSyncExternalStore(subscribe,()=>rev)}var Ctx=import_react20.createContext(null),THEMES_SET=new Set(THEME_NAMES),ThemeProvider=({children,initial,mode:initialMode="dark"})=>{let pref=usePref("theme"),modePref=usePref("themeMode"),rev2=useRev(),users=import_react20.useMemo(()=>userThemes(),[pref,rev2]),names=import_react20.useMemo(()=>[...new Set([...THEME_NAMES,...Object.keys(users)])].sort(),[users]),hasName=import_react20.useCallback((name)=>THEMES_SET.has(name)||users[name]!==void 0,[users]),active=pref&&hasName(pref)?pref:initial&&hasName(initial)?initial:DEFAULT_THEME,mode=modePref==="light"||modePref==="dark"?modePref:initialMode,[tick,force]=import_react20.useState(0);import_react20.useEffect(()=>{if((users[active]||get(active))&&get(DEFAULT_THEME))return;let cancelled=!1,need=[active,DEFAULT_THEME].filter((n)=>!users[n]&&!get(n)&&THEMES_SET.has(n));return Promise.all(need.map((n)=>load(n).catch(()=>{return}))).then(()=>{if(!cancelled)force((n)=>n+1)}),()=>{cancelled=!0}},[active,users]);let resolved=import_react20.useMemo(()=>{let json=users[active]??get(active)??get(DEFAULT_THEME);if(!json)return null;try{return resolveTheme(json,mode)}catch{let fallback=get(DEFAULT_THEME);return fallback?resolveTheme(fallback,mode):null}},[active,mode,tick,users]),set2=import_react20.useCallback((name)=>{if(!hasName(name))return!1;if(set("theme",name),THEMES_SET.has(name)&&!get(name))load(name).catch(()=>{});return!0},[hasName]),setMode=import_react20.useCallback((mode2)=>{set("themeMode",mode2)},[]),has=hasName,syntaxStyle=import_react20.useMemo(()=>resolved?syntax(resolved):null,[resolved]),value=import_react20.useMemo(()=>{if(!resolved||!syntaxStyle)return null;return{theme:resolved,syntaxStyle,name:active,mode,set:set2,setMode,names,has}},[resolved,syntaxStyle,active,mode,set2,setMode,names,has]);if(!value)return null;return $jsx(Ctx.Provider,{value,children})},useTheme=makeUse(Ctx,"useTheme");var ANSI2=new RegExp(["\\x1B\\[[\\x30-\\x3F]*[\\x20-\\x2F]*[\\x40-\\x7E]","\\x1B\\[[\\x30-\\x3F]*[\\x20-\\x2F]*","\\x1B\\][^\\x07\\x1B]*(?:\\x07|\\x1B\\\\)?","\\x1B[PX^_][^\\x1B]*(?:\\x1B\\\\)?","\\x1B[\\x20-\\x7E]","\\x1B"].join("|"),"g"),CTRL=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g;function sanitize(s){if(!s)return"";return s.replace(ANSI2,"").replace(CTRL,"")}function isDiff(s){if(!s)return!1;return/^--- a\//m.test(s)||/^@@ /m.test(s)||/^diff --git /m.test(s)}var CAP=80,WORD_CAP=40,tokens=(s)=>s.split(/(\s+)/).filter((t2)=>t2.length>0);function wordDiff(a,b2){let ta=tokens(a),tb=tokens(b2),p=0;while(p<ta.length&&p<tb.length&&ta[p]===tb[p])p++;let s=0;while(s<ta.length-p&&s<tb.length-p&&ta[ta.length-1-s]===tb[tb.length-1-s])s++;let seg=(t2)=>{let mid2=t2.slice(p,t2.length-s).join(""),out=[];if(p)out.push({text:t2.slice(0,p).join(""),hi:!1});if(mid2)out.push({text:mid2,hi:!0});if(s)out.push({text:t2.slice(t2.length-s).join(""),hi:!1});return out};return[seg(ta),seg(tb)]}function intraline(rows){let marks=rows.map(()=>null);if(rows.length>WORD_CAP)return marks;let del=(l)=>l.startsWith("-")&&!l.startsWith("---"),add=(l)=>l.startsWith("+")&&!l.startsWith("+++"),i=0;while(i<rows.length){if(!del(rows[i])){i++;continue}let j2=i;while(j2<rows.length&&del(rows[j2]))j2++;let k2=j2;while(k2<rows.length&&add(rows[k2]))k2++;let n=Math.min(j2-i,k2-j2);for(let d2=0;d2<n;d2++){let[rm,ad]=wordDiff(rows[i+d2].slice(1),rows[j2+d2].slice(1));marks[i+d2]=rm,marks[j2+d2]=ad}i=k2}return marks}var DiffBlock=import_react21.memo(({text:text3})=>{let theme=useTheme().theme,all=sanitize(text3).replace(/\n$/,"").split(`
@@ -4081,13 +4081,13 @@ Please report this to https://github.com/markedjs/marked.`,e){let r="<p>An error
4081
4081
  `;import{readdirSync as readdirSync6,readFileSync as readFileSync8}from"fs";import{dirname as dirname6,isAbsolute as isAbsolute3,join as join9,relative as relative3,resolve as resolve7}from"path";init_eikon();init_eikon();import{readFileSync as readFileSync4,statSync}from"fs";import{createHash as createHash2}from"crypto";import{join as join5,dirname as dirname2,basename as basename3}from"path";init_errors();init_shape();var NAME_RE=/^[a-z0-9][a-z0-9-]{1,63}$/,SAFE_PATH_RE=/^[a-zA-Z0-9._/-]+$/,problem=(path4,message)=>({code:"manifest",path:path4,message:`${path4}: ${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=(path4)=>path4.endsWith(LAUNCH_STREAM_EXTENSION)||/^blobs\/sha256\/[A-Fa-f0-9]{16,}(?:\.eikon)?$/.test(path4),STALE_DESCRIPTOR_ROLES=new Set(["stream","source"]);function isSafeRelativePath(path4){if(!path4||path4.startsWith("/")||path4.startsWith("./")||path4.includes("../")||path4==="..")return!1;if(/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(path4))return!1;if(!SAFE_PATH_RE.test(path4))return!1;return!path4.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_RE.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,path4]of Object.entries(man.entrypoints??{}))if(typeof path4!=="string"||!isSafeRelativePath(path4))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}var NAME_RE2=/^[a-z0-9-]{2,32}$/;function lint(raw){let e=parse3(raw),errs=[];if(!NAME_RE2.test(e.meta.name))errs.push(`name "${e.meta.name}" must match ${NAME_RE2}`);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(`
4082
4082
  `));return e}function sha(path4){return`sha256:${createHash2("sha256").update(readFileSync4(path4)).digest("hex")}`}function lintManifest(path4,raw){let man=validatePackageManifest(JSON.parse(raw),{registry:!0}),dir=dirname2(path4),errs=[];if(basename3(dir)!==man.name)errs.push(`name "${man.name}" \u2260 folder "${basename3(dir)}"`);for(let file of man.files??[]){let abs=join5(dir,file.path);try{let st=statSync(abs);if(typeof file.size==="number"&&st.size!==file.size)errs.push(`${file.path}: size mismatch`);if(file.digest&&sha(abs)!==file.digest)errs.push(`${file.path}: digest mismatch`)}catch{errs.push(`${file.path}: missing`)}}if(errs.length)throw Error(`${path4}:
4083
4083
  ${errs.join(`
4084
- `)}`);return man}init_spec();init_spec();import{existsSync as existsSync9,mkdirSync as mkdirSync3,readFileSync as readFileSync5,writeFileSync as writeFileSync4,copyFileSync,renameSync as renameSync2,rmSync,statSync as statSync2,readdirSync as readdirSync3,lstatSync}from"fs";import{join as join6,extname as extname2,basename as basename4,dirname as dirname3}from"path";import{mkdtempSync}from"fs";import{tmpdir}from"os";import{createHash as createHash3}from"crypto";init_errors();init_shape();init_spec();init_parse();init_runtime();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 path4=raw.split(/[?#]/,1)[0]??raw,decoded=(()=>{try{return decodeURIComponent(path4)}catch{return path4}})();return[path4,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}$/,text3=(value)=>typeof value==="string"&&!/[<>\u0000-\u001f]/.test(value),isObj3=(value)=>!!value&&typeof value==="object"&&!Array.isArray(value),problem2=(path4,message)=>({code:"catalog",path:path4,message:`${path4}: ${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,path4){return new URL(path4,base.endsWith("/")?base:`${base}/`).toString()}function relativeUrl(base,path4){if(!path4)return;if(/^https?:\/\//.test(path4))return url(path4);if(!isSafeRelativePath(path4))throw new EikonValidationError([problem2("path","safe relative path required")]);return joinUrl(base,path4)}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 runtimeDescriptor2(man){return man.files?.find((file)=>file.role==="runtime"&&file.path===runtimePath(man))}function digestFor(man,path4){return man.files?.find((file)=>file.path===path4)?.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=runtimeDescriptor2(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(text3):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&&!text3(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}}}init_parse();init_legacy();init_runtime();init_runtime_host();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[path4,query=""]=input.split("?"),[head,hash]=path4.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:${createHash3("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((path4)=>path4.split(/[\\/]/).some((part)=>part==="..")))throw Error(`download URL path escape: ${cleanUrl2(raw)}`);let url2=new URL(raw);if(pathParts(url2.pathname).some((path4)=>path4.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 sha2=await new Response(Bun.spawn(["git","-C",dst,"rev-parse","HEAD"],{stdout:"pipe"}).stdout).text();return rmSync(join6(dst,".git"),{recursive:!0,force:!0}),{dir:dst,sha:sha2.trim()||void 0,cleanup:!0}}function readJson(path4){return JSON.parse(readFileSync5(path4,"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(path4){let rel=asPackageIndex(readJson(path4))?.versions?.at(-1)?.manifest;if(!rel||!isSafeRelativePath(rel))throw Error(`${path4}: package index has no safe manifest path`);return join6(dirname3(path4),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=join6(repo,"packages",parts2[0],parts2[1],"index.json");if(!existsSync9(idx))return;let path5=latestPackageFromIndex(idx);return{manifest:manifest(readJson(path5)),staged:dirname3(path5),root:`packages/${parts2[0]}/${parts2[1]}/index.json`}}let matches=[],packages=join6(repo,"packages");if(existsSync9(packages))for(let ns2 of readdirSync3(packages,{withFileTypes:!0})){if(!ns2.isDirectory())continue;let idx=join6(packages,ns2.name,selector,"index.json");if(existsSync9(idx))matches.push(idx)}if(matches.length>1)throw Error(`ambiguous package selector "${selector}"; use namespace/name`);if(!matches.length)return;let path4=latestPackageFromIndex(matches[0]),ns=basename4(dirname3(dirname3(path4)));return{manifest:manifest(readJson(path4)),staged:dirname3(path4),root:`packages/${ns}/${selector}/index.json`}}function catalogResolution(repo,selector){for(let root of["eikons/index.json","registry.json","index.json"]){let path4=join6(repo,root);if(!existsSync9(path4))continue;let raw=readJson(path4);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=join6(repo,url2.pathname.replace(/^\//,"")),!existsSync9(pkgPath))pkgPath=join6(dirname3(path4),entry.packageUrl);return{entry,manifest:manifest(readJson(pkgPath)),staged:dirname3(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=join6(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 path4=assertSafePackageFile(staged,file.path),data2=readFileSync5(path4);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(existsSync9(join6(dir,"manifest.json")))return dir;for(let e of readdirSync3(dir,{withFileTypes:!0}))if(e.isDirectory()&&existsSync9(join6(dir,e.name,"manifest.json")))return join6(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 resolve5(src,opts={}){let at=new Date().toISOString(),local=src.replace(/^file:\/\//,"");if(!gitish(src)&&existsSync9(local)&&statSync2(local).isDirectory()){let staged=locate(local),man=manifest(JSON.parse(readFileSync5(join6(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(join6(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 sha2=await new Response(Bun.spawn(["git","-C",tmp,"rev-parse","HEAD"],{stdout:"pipe"}).stdout).text();rmSync(join6(tmp,".git"),{recursive:!0,force:!0});let staged2=locate(tmp),man2=manifest(JSON.parse(readFileSync5(join6(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:sha2.trim()||void 0,resolvedRef:sha2.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(readFileSync5(join6(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=resolve5(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=join6(r.staged,rel);return a+(existsSync9(p2)?statSync2(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 resolve5(src,opts);r.origin.scope=scope;let name=installName(opts.name??r.name);mkdirSync3(root,{recursive:!0});let dst=join6(root,name),tmp=mkdtempSync(join6(root,`.${name}-`)),srcd=join6(tmp,"source"),old=join6(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=readFileSync5(assertSafePackageFile(r.staged,rel));parseRuntimeBytes(launchBytes,{descriptor:desc}),mkdirSync3(srcd,{recursive:!0}),writeFileSync4(join6(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=join6(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(!existsSync9(from2))throw Error(`${rel2}: missing in ${r.staged}`);copyFileSync(from2,to),bytes+=statSync2(to).size}sources[role]=fname,tick2()}));let out=installManifest(r.manifest,{...r.origin,trust:r.trust.state});if(writeFileSync4(join6(tmp,"manifest.json"),JSON.stringify(out,null,2)+`
4084
+ `)}`);return man}init_spec();init_spec();import{existsSync as existsSync9,mkdirSync as mkdirSync3,readFileSync as readFileSync5,writeFileSync as writeFileSync4,copyFileSync,renameSync as renameSync2,rmSync,statSync as statSync2,readdirSync as readdirSync3,lstatSync}from"fs";import{join as join6,extname as extname2,basename as basename4,dirname as dirname3}from"path";import{mkdtempSync}from"fs";import{tmpdir}from"os";import{createHash as createHash3}from"crypto";init_errors();init_shape();init_spec();init_parse();init_runtime();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 path4=raw.split(/[?#]/,1)[0]??raw,decoded=(()=>{try{return decodeURIComponent(path4)}catch{return path4}})();return[path4,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}$/,text3=(value)=>typeof value==="string"&&!/[<>\u0000-\u001f]/.test(value),isObj3=(value)=>!!value&&typeof value==="object"&&!Array.isArray(value),problem2=(path4,message)=>({code:"catalog",path:path4,message:`${path4}: ${message}`}),digestRe=/^sha256:[A-Za-z0-9._~+/=-]+$/,encodings=new Set(["identity","gzip"]),trimSlash=(s)=>s.replace(/\/$/,""),slash=(s)=>s.replace(/\/?$/,"/"),clean2=(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,path4){return new URL(path4,base.endsWith("/")?base:`${base}/`).toString()}function relativeUrl(base,path4){if(!path4)return;if(/^https?:\/\//.test(path4))return url(path4);if(!isSafeRelativePath(path4))throw new EikonValidationError([problem2("path","safe relative path required")]);return joinUrl(base,path4)}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 runtimeDescriptor2(man){return man.files?.find((file)=>file.role==="runtime"&&file.path===runtimePath(man))}function digestFor(man,path4){return man.files?.find((file)=>file.path===path4)?.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=runtimeDescriptor2(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:clean2(input.name),author:clean2(input.author),glyph:clean2(input.glyph),tags:Array.isArray(input.tags)?input.tags.filter(text3):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:clean2(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&&!text3(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}}}init_parse();init_legacy();init_runtime();init_runtime_host();var clean3=(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[path4,query=""]=input.split("?"),[head,hash]=path4.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=clean3(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:${createHash3("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((path4)=>path4.split(/[\\/]/).some((part)=>part==="..")))throw Error(`download URL path escape: ${cleanUrl2(raw)}`);let url2=new URL(raw);if(pathParts(url2.pathname).some((path4)=>path4.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,...clean4}=man;return{...clean4,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 sha2=await new Response(Bun.spawn(["git","-C",dst,"rev-parse","HEAD"],{stdout:"pipe"}).stdout).text();return rmSync(join6(dst,".git"),{recursive:!0,force:!0}),{dir:dst,sha:sha2.trim()||void 0,cleanup:!0}}function readJson(path4){return JSON.parse(readFileSync5(path4,"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(path4){let rel=asPackageIndex(readJson(path4))?.versions?.at(-1)?.manifest;if(!rel||!isSafeRelativePath(rel))throw Error(`${path4}: package index has no safe manifest path`);return join6(dirname3(path4),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=join6(repo,"packages",parts2[0],parts2[1],"index.json");if(!existsSync9(idx))return;let path5=latestPackageFromIndex(idx);return{manifest:manifest(readJson(path5)),staged:dirname3(path5),root:`packages/${parts2[0]}/${parts2[1]}/index.json`}}let matches=[],packages=join6(repo,"packages");if(existsSync9(packages))for(let ns2 of readdirSync3(packages,{withFileTypes:!0})){if(!ns2.isDirectory())continue;let idx=join6(packages,ns2.name,selector,"index.json");if(existsSync9(idx))matches.push(idx)}if(matches.length>1)throw Error(`ambiguous package selector "${selector}"; use namespace/name`);if(!matches.length)return;let path4=latestPackageFromIndex(matches[0]),ns=basename4(dirname3(dirname3(path4)));return{manifest:manifest(readJson(path4)),staged:dirname3(path4),root:`packages/${ns}/${selector}/index.json`}}function catalogResolution(repo,selector){for(let root of["eikons/index.json","registry.json","index.json"]){let path4=join6(repo,root);if(!existsSync9(path4))continue;let raw=readJson(path4);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=join6(repo,url2.pathname.replace(/^\//,"")),!existsSync9(pkgPath))pkgPath=join6(dirname3(path4),entry.packageUrl);return{entry,manifest:manifest(readJson(pkgPath)),staged:dirname3(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=join6(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 path4=assertSafePackageFile(staged,file.path),data2=readFileSync5(path4);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(existsSync9(join6(dir,"manifest.json")))return dir;for(let e of readdirSync3(dir,{withFileTypes:!0}))if(e.isDirectory()&&existsSync9(join6(dir,e.name,"manifest.json")))return join6(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 resolve5(src,opts={}){let at=new Date().toISOString(),local=src.replace(/^file:\/\//,"");if(!gitish(src)&&existsSync9(local)&&statSync2(local).isDirectory()){let staged=locate(local),man=manifest(JSON.parse(readFileSync5(join6(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(join6(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 sha2=await new Response(Bun.spawn(["git","-C",tmp,"rev-parse","HEAD"],{stdout:"pipe"}).stdout).text();rmSync(join6(tmp,".git"),{recursive:!0,force:!0});let staged2=locate(tmp),man2=manifest(JSON.parse(readFileSync5(join6(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:sha2.trim()||void 0,resolvedRef:sha2.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(readFileSync5(join6(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=resolve5(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=join6(r.staged,rel);return a+(existsSync9(p2)?statSync2(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 resolve5(src,opts);r.origin.scope=scope;let name=installName(opts.name??r.name);mkdirSync3(root,{recursive:!0});let dst=join6(root,name),tmp=mkdtempSync(join6(root,`.${name}-`)),srcd=join6(tmp,"source"),old=join6(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=readFileSync5(assertSafePackageFile(r.staged,rel));parseRuntimeBytes(launchBytes,{descriptor:desc}),mkdirSync3(srcd,{recursive:!0}),writeFileSync4(join6(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=join6(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(!existsSync9(from2))throw Error(`${rel2}: missing in ${r.staged}`);copyFileSync(from2,to),bytes+=statSync2(to).size}sources[role]=fname,tick2()}));let out=installManifest(r.manifest,{...r.origin,trust:r.trust.state});if(writeFileSync4(join6(tmp,"manifest.json"),JSON.stringify(out,null,2)+`
4085
4085
  `),existsSync9(dst))renameSync2(dst,old);try{renameSync2(tmp,dst)}catch(err){if(existsSync9(old))renameSync2(old,dst);throw err}if(existsSync9(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=join6(dir,"manifest.json");if(!existsSync9(mf))return!1;let man=JSON.parse(readFileSync5(mf,"utf8"));if(!man.origin?.at)return!1;let since=Date.parse(man.origin.at);for(let e of readdirSync3(dir,{withFileTypes:!0,recursive:!0}))if(statSync2(join6(e.parentPath??dir,e.name)).mtimeMs>since+2000)return!0;return!1}init_errors();init_shape();init_errors();init_shape();init_shape();import{copyFileSync as copyFileSync3,existsSync as existsSync11,lstatSync as lstatSync2,mkdirSync as mkdirSync5,mkdtempSync as mkdtempSync3,readFileSync as readFileSync7,readdirSync as readdirSync5,statSync as statSync4,writeFileSync as writeFileSync6}from"fs";import{tmpdir as tmpdir2}from"os";import{dirname as dirname5,join as join8,relative as relative2,resolve as resolve6,sep}from"path";import{copyFileSync as copyFileSync2,cpSync,existsSync as existsSync10,mkdirSync as mkdirSync4,mkdtempSync as mkdtempSync2,readFileSync as readFileSync6,readdirSync as readdirSync4,rmSync as rmSync2,statSync as statSync3,writeFileSync as writeFileSync5}from"fs";import{dirname as dirname4,join as join7,relative}from"path";init_spec();init_eikon();init_legacy();import{createHash as createHash4}from"crypto";init_shape();var root=(opts={})=>{if(opts.root)return opts.root;let d2=import.meta.dir;while(!existsSync10(join7(d2,"eikons","index.json"))&&dirname4(d2)!==d2)d2=dirname4(d2);return join7(d2,"eikons")},siteRoot=(opts={})=>dirname4(root(opts)),slash2=(s)=>s.replace(/\/?$/,"/"),digestHex=(digest)=>digest.replace(/^sha256:/,""),blobRel=(digest)=>`blobs/sha256/${digestHex(digest)}`;function sha2563(path4){return`sha256:${createHash4("sha256").update(readFileSync6(path4)).digest("hex")}`}function sha256Bytes3(bytes){return`sha256:${createHash4("sha256").update(bytes).digest("hex")}`}function mediaType(path4){let lower=path4.toLowerCase();if(lower.endsWith(".eikon"))return LAUNCH_MEDIA_TYPE;if(lower.endsWith(".png"))return"image/png";if(lower.endsWith(".jpg")||lower.endsWith(".jpeg"))return"image/jpeg";if(lower.endsWith(".mp4"))return"video/mp4";if(lower.endsWith(".webm"))return"video/webm";if(lower.endsWith(".txt"))return"text/plain";if(lower.endsWith(".json"))return"application/json";return"application/octet-stream"}function fileInfo(dir,path4,role,signal){let full=join7(dir,path4);return{path:path4,role,mediaType:role==="runtime"?LAUNCH_MEDIA_TYPE:mediaType(path4),size:statSync3(full).size,digest:sha2563(full),...signal?{signal}:{}}}function localRuntimeInfo(dir,path4,text4){let info=fileInfo(dir,path4,"runtime"),bytes=readFileSync6(join7(dir,path4));if(bytes[0]!==31||bytes[1]!==139)return info;let decoded=new TextEncoder().encode(text4);return{...info,encoding:"gzip",decodedSize:decoded.length,decodedDigest:sha256Bytes3(decoded)}}function registryInfo(file){return{...file,path:blobRel(file.digest)}}function sourceMedia(man){let source={};if(man.kind===PACKAGE_KIND){let pkg=man;if(pkg.source?.base)source.base=pkg.source.base;if(pkg.source?.states)source.states=pkg.source.states}else{if(typeof man.source==="string")source.base=man.source;let states=man.states&&typeof man.states==="object"&&!Array.isArray(man.states)?man.states:{};for(let[key3,value]of Object.entries(states)){if(typeof value.file!=="string")continue;source.states??={},source.states[key3]={file:value.file}}}return source.base||source.states?source:void 0}function sourceDescriptors(dir,source){let out=[];if(source?.base&&existsSync10(join7(dir,source.base)))out.push(fileInfo(dir,source.base,"source.base"));for(let[signal,value]of Object.entries(source?.states??{})){if(!value?.file||!existsSync10(join7(dir,value.file)))continue;out.push(fileInfo(dir,value.file,"source.clip",signal.startsWith("state.")?signal:`state.${signal}`))}return out}function packageUrl(base,id,version){let[namespace="local",name=id]=id.split("/");return new URL(`/packages/${namespace}/${name}/${version}.json`,new URL(base)).toString()}function detailUrl(base,name){return new URL(name,slash2(base)).toString()}function packageBlobUrl(base,id,digest){let[namespace="local",name=id]=id.split("/");return new URL(`/packages/${namespace}/${name}/${blobRel(digest)}`,new URL(base)).toString()}function stageBlob(pkgDir,src,digest){let rel=blobRel(digest),local=join7(pkgDir,rel);mkdirSync4(dirname4(local),{recursive:!0}),copyFileSync2(src,local)}function stageBytes(pkgDir,bytes,digest){let rel=blobRel(digest),local=join7(pkgDir,rel);mkdirSync4(dirname4(local),{recursive:!0}),writeFileSync5(local,bytes)}function runtimeInfo(path4,text4,encoding){let info=runtimeDescriptor(text4,{encoding});return{path:path4,role:"runtime",mediaType:LAUNCH_MEDIA_TYPE,size:info.size,digest:info.digest,...encoding==="gzip"?{encoding:info.encoding,decodedSize:info.decodedSize,decodedDigest:info.decodedDigest}:{},bytes:info.bytes}}function registryRuntime(file){return{path:blobRel(file.digest),role:file.role,mediaType:file.mediaType,size:file.size,digest:file.digest,...file.encoding?{encoding:file.encoding}:{},...file.decodedSize!=null?{decodedSize:file.decodedSize}:{},...file.decodedDigest?{decodedDigest:file.decodedDigest}:{}}}function registrySource(source,localFiles){if(!source)return;let byPath=new Map(localFiles.map((file)=>[file.path,blobRel(file.digest)])),out={};if(source.base&&byPath.has(source.base))out.base=byPath.get(source.base);for(let[signal,value]of Object.entries(source.states??{})){if(!value?.file||!byPath.has(value.file))continue;out.states??={},out.states[signal]={...value,file:byPath.get(value.file)}}return out.base||out.states?out:void 0}function displayFrom(prior,launch,name){let displayPrior=prior.display&&typeof prior.display==="object"&&!Array.isArray(prior.display)?prior.display:{};return{title:typeof displayPrior.title==="string"?displayPrior.title:launch.header.title??name,author:typeof displayPrior.author==="string"?displayPrior.author:launch.header.author?.name,glyph:typeof displayPrior.glyph==="string"?displayPrior.glyph:void 0,description:typeof displayPrior.description==="string"?displayPrior.description:launch.header.description}}async function index(input=DEFAULT_CATALOG){let opts=typeof input==="string"?{base:input}:input,base=opts.base??DEFAULT_CATALOG,dir=root(opts),site=siteRoot(opts),out=[];for(let e of readdirSync4(dir,{withFileTypes:!0})){if(!e.isDirectory())continue;let d2=join7(dir,e.name),manifestPath=join7(d2,"manifest.json"),streamPath=join7(d2,`${e.name}.eikon`);if(!existsSync10(manifestPath)||!existsSync10(streamPath))continue;let local=validatePackageManifest(JSON.parse(readFileSync6(manifestPath,"utf8")),{registry:!0}),versionManifest=join7(site,"packages",...local.id.split("/"),`${local.version??"1.0.0"}.json`),man=existsSync10(versionManifest)?validatePackageManifest(JSON.parse(readFileSync6(versionManifest,"utf8")),{registry:!0}):local,stream=parseRuntimeFile(streamPath),runtime=man.files?.find((file)=>file.role==="runtime"&&file.path===man.entrypoints.default);if(!runtime?.digest)throw Error(`${e.name}: runtime descriptor missing digest`);let pkg=packageUrl(base,man.id,man.version??"1.0.0"),manifestDigest=existsSync10(versionManifest)?sha2563(versionManifest):void 0,normalized=normalizeCatalogEntry({manifest:man,packageUrl:pkg,sourceKey:`registry:${new URL(base).host}:${man.id}@${man.version??"1.0.0"}`,detailUrl:detailUrl(base,e.name)},base),entry=validateCatalogEntry({...normalized,poster:poster(stream),runtimeUrl:packageBlobUrl(base,man.id,runtime.digest),detailUrl:detailUrl(base,e.name),trust:{...normalized.trust,runtimeDigest:runtime.digest,...manifestDigest?{manifestDigest}:{}}});out.push(entry)}return out.sort((a,b2)=>a.name.localeCompare(b2.name)),await Bun.write(join7(dir,"index.json"),JSON.stringify(out,null,2)+`
4086
4086
  `),out.length}function manifest2(opts={}){let dir=root(opts),site=siteRoot(opts),encoding=opts.encoding??"identity";rmSync2(join7(site,"packages"),{recursive:!0,force:!0}),rmSync2(join7(site,"blobs"),{recursive:!0,force:!0});let n=0;for(let e of readdirSync4(dir,{withFileTypes:!0})){if(!e.isDirectory())continue;let d2=join7(dir,e.name),packed=join7(d2,`${e.name}.eikon`);if(!existsSync10(packed))continue;let oldManifest=join7(d2,"manifest.json"),prior=existsSync10(oldManifest)?JSON.parse(readFileSync6(oldManifest,"utf8")):{},text4=decodeRuntimeFile(packed),migrated2=text4.trimStart().startsWith('{"type":"header"')||text4.trimStart().startsWith('{"type":"header",')?void 0:migrateLegacyEikon(text4,{id:`liftaris/${e.name}`,entrypoint:`${e.name}.eikon`,version:"1.0.0"});if(migrated2)writeFileSync5(packed,migrated2.stream);let runtimeText=migrated2?.stream??text4,launch=parseRuntimeFile(packed),source=sourceMedia(prior),localRuntime=localRuntimeInfo(d2,`${e.name}.eikon`,runtimeText),runtime=runtimeInfo(`${e.name}.eikon`,runtimeText,encoding),localFiles=[localRuntime,...sourceDescriptors(d2,source)],registryFiles=[registryRuntime(runtime),...localFiles.slice(1).map(registryInfo)],registrySourceMedia=registrySource(source,localFiles),[namespace="local",packageName=e.name]=`liftaris/${e.name}`.split("/"),pkgDir=join7(site,"packages",namespace,packageName);mkdirSync4(pkgDir,{recursive:!0}),stageBytes(pkgDir,runtime.bytes,runtime.digest);for(let file of localFiles.slice(1))stageBlob(pkgDir,join7(d2,file.path),file.digest);let shared={kind:PACKAGE_KIND,schemaVersion:"1.0",id:`liftaris/${e.name}`,name:e.name,version:"1.0.0",display:displayFrom(prior,launch,e.name),compatibility:{eikon:">=1 <2"}},localManifest={...shared,...source?{source}:{},entrypoints:{default:`${e.name}.eikon`},files:localFiles},registryManifest={...shared,...registrySourceMedia?{source:registrySourceMedia}:{},entrypoints:{default:blobRel(runtime.digest)},files:registryFiles};validatePackageManifest(localManifest,{registry:!0}),validatePackageManifest(registryManifest,{registry:!0}),writeFileSync5(oldManifest,JSON.stringify(localManifest,null,2)+`
4087
4087
  `),writeFileSync5(join7(pkgDir,"1.0.0.json"),JSON.stringify(registryManifest,null,2)+`
4088
4088
  `),writeFileSync5(join7(pkgDir,"index.json"),JSON.stringify({kind:"eikon.package.index",id:shared.id,name:e.name,versions:[{version:"1.0.0",manifest:"1.0.0.json"}]},null,2)+`
4089
4089
  `),n++}return n}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;var hidden=(rel)=>rel.split(/[\\/]/).some((p)=>p.startsWith(".")),secret=(rel)=>SECRET.test(rel);var posix=(s)=>s.split(sep).join("/");function contain(root2,rel){if(rel.startsWith("/")||/^[A-Za-z]:[\\/]/.test(rel)||rel.split(/[\\/]/).some((p)=>p===".."))throw Error(`submission bundle path escape: ${rel}`);let abs=resolve6(root2,rel),back=relative2(root2,abs);if(back.startsWith("..")||back===""||resolve6(root2,back)!==abs)throw Error(`submission bundle path escape: ${rel}`);return{abs,rel:posix(back)}}function copy(root2,rel,out,opts){let path4=contain(root2,rel);if(!existsSync11(path4.abs))throw Error(`submission bundle missing source: ${path4.rel}`);if(!opts.allowHidden&&hidden(path4.rel))return;if(!opts.allowSecrets&&secret(path4.rel))return;let parts2=path4.rel.split("/"),cur=root2;for(let part of parts2){cur=join8(cur,part);let st=lstatSync2(cur);if(st.isSymbolicLink())throw Error(`submission bundle symlink unsupported: ${path4.rel}`);if(part!==parts2.at(-1)&&!st.isDirectory())return;if(part===parts2.at(-1)&&!st.isFile())return}mkdirSync5(dirname5(join8(out,path4.rel)),{recursive:!0}),copyFileSync3(path4.abs,join8(out,path4.rel))}function refs(raw){let man=JSON.parse(raw);if(man.kind==="eikon.package"){let source=man.source&&typeof man.source==="object"&&!Array.isArray(man.source)?man.source:{},states2=source.states&&typeof source.states==="object"&&!Array.isArray(source.states)?source.states:{};return[...typeof source.base==="string"?[source.base]:[],...Object.values(states2).flatMap((v2)=>typeof v2.file==="string"?[v2.file]:[])]}let states=man.states&&typeof man.states==="object"&&!Array.isArray(man.states)?man.states:{};return[...typeof man.source==="string"?[man.source]:[],...Object.values(states).flatMap((v2)=>typeof v2.file==="string"?[v2.file]:[])]}function walk(dir,base=dir){if(!existsSync11(dir))return[];return readdirSync5(dir,{withFileTypes:!0}).flatMap((item)=>{let abs=join8(dir,item.name);if(item.isDirectory())return walk(abs,base);if(!item.isFile())return[];return[posix(relative2(base,abs))]}).sort()}function artifactFiles(site,name){let keep=[`eikons/${name}/`,`packages/liftaris/${name}/`];return walk(site).filter((path4)=>path4==="eikons/index.json"||keep.some((prefix)=>path4.startsWith(prefix))).map((path4)=>({path:path4,dest:path4,abs:join8(site,path4),bytes:statSync4(join8(site,path4)).size}))}function bundleBytes(files,opts){let 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`)}function catalog2(site,name){let entry=JSON.parse(readFileSync7(join8(site,"eikons/index.json"),"utf8")).find((e)=>e.name===name);if(entry)return{...normalizeCatalogEntry(entry),w:0,h:0,width:0,height:0,identityKey:entry.sourceKey||entry.id,raw:entry,trust:entry.trust??{},poster:entry.poster??""};return catalogEntry({name},"https://eikon.liftaris.dev/eikons/",{allowPrivate:!0})}function mergeIndex(site,name){let file=join8(site,"eikons/index.json"),next=JSON.parse(readFileSync7(file,"utf8")),base=join8(import.meta.dir,"..","eikons","index.json"),merged=[...(existsSync11(base)?JSON.parse(readFileSync7(base,"utf8")):[]).filter((e)=>e.name!==name),...next].sort((a,b2)=>a.name.localeCompare(b2.name));writeFileSync6(file,JSON.stringify(merged,null,2)+`
4090
- `)}function display(value){let out=Object.fromEntries(Object.entries(value??{}).filter(([,v2])=>typeof v2==="string"&&v2.trim()).map(([k2,v2])=>[k2,v2.trim()]));return Object.keys(out).length?out:void 0}function applyDisplay(site,name,next){let clean3=display(next);if(!clean3)return;for(let path4 of[join8(site,"eikons",name,"manifest.json"),join8(site,"packages","liftaris",name,"1.0.0.json")]){let man=JSON.parse(readFileSync7(path4,"utf8"));writeFileSync6(path4,JSON.stringify({...man,display:{...man.display,...clean3}},null,2)+`
4090
+ `)}function display(value){let out=Object.fromEntries(Object.entries(value??{}).filter(([,v2])=>typeof v2==="string"&&v2.trim()).map(([k2,v2])=>[k2,v2.trim()]));return Object.keys(out).length?out:void 0}function applyDisplay(site,name,next){let clean4=display(next);if(!clean4)return;for(let path4 of[join8(site,"eikons",name,"manifest.json"),join8(site,"packages","liftaris",name,"1.0.0.json")]){let man=JSON.parse(readFileSync7(path4,"utf8"));writeFileSync6(path4,JSON.stringify({...man,display:{...man.display,...clean4}},null,2)+`
4091
4091
  `)}}async function previewSubmitBundle(opts){let input=resolve6(opts.path),source=dirname5(input),eikon,text4;try{text4=decodeRuntimeFile(input),eikon=lint(text4)}catch(err){throw Error(`invalid eikon: ${err instanceof Error?err.message:String(err)}`)}let name=eikon.meta.name,site=mkdtempSync3(join8(tmpdir2(),"eikon-submit-")),root2=join8(site,"eikons",name);mkdirSync5(root2,{recursive:!0});let runtime=text4.trimStart().startsWith('{"type":"header"')||text4.trimStart().startsWith('{"type":"header",')?text4:(await Promise.resolve().then(() => (init_legacy(),exports_legacy))).migrateLegacyEikon(text4,{id:`liftaris/${name}`,entrypoint:`${name}.eikon`,version:"1.0.0"}).stream;await Bun.write(join8(root2,`${name}.eikon`),encodeRuntimeText(runtime,{encoding:"gzip"}));let mf=join8(source,"manifest.json");if(existsSync11(mf)){copyFileSync3(mf,join8(root2,"manifest.json"));for(let rel of refs(readFileSync7(mf,"utf8")))copy(source,rel,root2,opts)}for(let rel of opts.extraFiles??[])copy(source,rel,root2,opts);manifest2({root:join8(site,"eikons"),encoding:"gzip"}),applyDisplay(site,name,opts.display),await index({root:join8(site,"eikons")}),mergeIndex(site,name);let manifest3=lintManifest(join8(root2,"manifest.json"),readFileSync7(join8(root2,"manifest.json"),"utf8")),files=artifactFiles(site,name);return bundleBytes(files,opts),{root:site,packed:join8(root2,`${name}.eikon`),files,meta:lint(decodeRuntimeFile(join8(root2,`${name}.eikon`))).meta,manifest:manifest3,catalog:catalog2(site,name),lint:[`\u2713 runtime ${name}.eikon`,`\u2713 package manifest ${manifest3.entrypoints.default}`,"\u2713 registry index eikons/index.json"]}}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,path4){try{let out=await run(["api","-X","GET",`repos/${fork}/contents/${path4}`,"-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(["api","user","-q",".login"]),{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]}`,main=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=${main}`]).catch(()=>"");for(let file of req.bundle.files){let content=Buffer.from(await Bun.file(file.abs).arrayBuffer()).toString("base64"),sha2=await existingSha(run,fork,branch,file.dest);await run(["api","-X","PUT",`repos/${fork}/contents/${file.dest}`,"--input","-"],JSON.stringify({message:`eikons: submit ${name}`,branch,content,...sha2?{sha:sha2}:{}}))}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(path4){try{let entrypoints=JSON.parse(readFileSync8(path4,"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(text4){let first=text4.split(`
4092
4092
  `,1)[0];if((first?JSON.parse(first):{}).type==="header"){let e2=parseLaunchStream(text4);return{meta:e2.meta,states:e2.clips,resolve:(signal)=>{try{return e2.clips.get(resolveSignal(e2,signal).clip)}catch{return}}}}let e=parse3(text4);return{meta:e.meta,states:e.clips,resolve:(signal)=>e.clips.get(signal.replace(/^state\./,""))}}function parseEikonFile(path4){return parseEikon(decodeRuntimeFile(path4))}function listEikons(dirs){return dirs.flatMap((dir)=>{let ents;try{ents=readdirSync6(dir,{recursive:!0})}catch{return[]}let paths=ents.map((e)=>join9(dir,e)),streamFiles=paths.filter((path4)=>STREAM_EXT.test(path4)),packageEntrypoints=new Map;for(let manifest3 of paths.filter((path4)=>path4.endsWith("manifest.json"))){let entrypoint=readManifestEntrypoint(manifest3);if(entrypoint){let root2=dirname6(manifest3);packageEntrypoints.set(root2,join9(root2,entrypoint))}}let packageRootFor=(path4)=>{for(let root2 of packageEntrypoints.keys()){let rel=relative3(root2,path4);if(rel&&!rel.startsWith("..")&&!isAbsolute3(rel))return root2}return};return streamFiles.sort((a,b2)=>a.localeCompare(b2)).filter((path4)=>{let packageRoot=packageRootFor(path4);return packageRoot?path4===packageEntrypoints.get(packageRoot):!0}).map((path4)=>({path:path4,meta:peek2(resolve7(path4))})).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 maxLines=(frames)=>frames.reduce((n,f)=>Math.max(n,f.length),0),AnimatedAvatar=import_react33.memo(({state="idle",eikon,onHold})=>{let g=globalThis;if(process.env.HERM_TEST_PERF==="1")g.__hermAvatarRenders=(g.__hermAvatarRenders??0)+1;let theme=useTheme().theme,refs2=import_react33.useRef([]),timer2=import_react33.useRef(null),holdRef=import_react33.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,lines3=maxLines(frames),first=frames[0]??[],animate=usePref("animations")!==!1,targetFps=usePref("targetFps")??30,dt=1000/Math.max(1,Math.min(fps,targetFps));import_react33.useEffect(()=>{let paint=(idx2)=>{let frame=frames[Math.min(idx2,count2-1)]??[];for(let i=0;i<lines3;i++){let node=refs2.current[i];if(node)node.children=[frame[i]??""]}};if(timer2.current)clearTimeout(timer2.current),timer2.current=null;if(paint(0),!animate||count2<2)return;if(count("avatar:timer:start"),process.env.HERM_TEST_PERF==="1")g.__hermAvatarTimerStarts=(g.__hermAvatarTimerStarts??0)+1;let idx=0,tick2=()=>{if(count("avatar:tick"),idx++,idx>=count2){if(loopFrom>=count2){timer2.current=null,paint(count2-1),holdRef.current?.(state);return}idx=loopFrom}paint(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,frames,count2,loopFrom,animate,dt,lines3,g]);let end=mark("avatar:render"),result=$jsx("box",{flexDirection:"column",children:Array.from({length:lines3},(_2,i)=>$jsx("text",{children:$jsx("span",{ref:(el)=>{refs2.current[i]=el},fg:theme.hermAvatar,children:first[i]??""})},i))});return end(),result});var exports_git={};__export(exports_git,{useGitStatus:()=>useGitStatus,useGitBranch:()=>useGitBranch,status:()=>status,rtrunc:()=>rtrunc,gitdir:()=>gitdir,git:()=>exports_git,branch:()=>branch});var import_react34=__toESM(require_react_production(),1);import{watch}from"fs";var TIMEOUT=500;async function git(cwd,...args){let p;try{p=Bun.spawn(["git","-C",cwd,...args],{stdout:"pipe",stderr:"ignore"})}catch{return null}let t2=setTimeout(()=>p.kill(),TIMEOUT),out=await new Response(p.stdout).text();return clearTimeout(t2),await p.exited===0?out.trimEnd():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_react34.useState(null);return import_react34.useEffect(()=>{if(!cwd){set2(null);return}let dead=!1,w2,read2=()=>branch(cwd).then((b2)=>{if(!dead)set2(b2)});return read2(),gitdir(cwd).then((dir)=>{if(dead||!dir)return;try{w2=watch(dir,{persistent:!1},(_ev,f)=>{if(f==="HEAD")read2()})}catch{}}),()=>{dead=!0,w2?.close()}},[cwd]),val}var rtrunc=(s,max)=>s.length<=max?s:"\u2026"+s.slice(-(max-1));async function status(cwd){let out=await git(cwd,"status","--porcelain");if(!out)return null;let files=out.split(`
4093
4093
  `).filter(Boolean).map((line)=>({code:line.slice(0,2),file:line.slice(3)})),added=0,modified=0,deleted=0;for(let f of files){let idx=f.code[0],wt=f.code[1];if(idx==="?"&&wt==="?"){added++;continue}if(idx==="A"){added++;continue}if(idx==="D"||wt==="D"){deleted++;continue}if(idx==="M"||wt==="M"||idx==="R")modified++}return{files,added,modified,deleted}}var same=(a,b2)=>a===b2||Boolean(a&&b2&&a.added===b2.added&&a.modified===b2.modified&&a.deleted===b2.deleted&&a.files.length===b2.files.length&&a.files.every((file,i)=>file.code===b2.files[i]?.code&&file.file===b2.files[i]?.file));function useGitStatus(cwd,delay=2000){let[val,set2]=import_react34.useState(null);return import_react34.useEffect(()=>{if(!cwd){set2(null);return}let dead=!1,seq=0,read2=()=>{let id=++seq;status(cwd).then((s)=>{if(!dead&&id===seq)set2((old)=>same(old,s)?old:s)})};read2();let timer2=setInterval(read2,Math.max(250,delay));return()=>{dead=!0,clearInterval(timer2)}},[cwd,delay]),val}var import_react35=__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_react35.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_react37=__toESM(require_react_production(),1);var import_react36=__toESM(require_react_production(),1);var Ctx3=import_react36.createContext(null),DEFAULT_DURATION=3000,ToastProvider=({children})=>{let[items,setItems]=import_react36.useState([]),counter=import_react36.useRef(0),timers=import_react36.useRef(new Map);import_react36.useEffect(()=>()=>{for(let t2 of timers.current.values())clearTimeout(t2)},[]);let show=import_react36.useCallback((opts)=>{let id=++counter.current;setItems((prev)=>{let drop=opts.key?prev.filter((t2)=>t2.key===opts.key):[];for(let item of drop){let t2=timers.current.get(item.id);if(t2)clearTimeout(t2);timers.current.delete(item.id)}return[...opts.key?prev.filter((t2)=>t2.key!==opts.key):prev,{...opts,id}]});let dur2=opts.duration??DEFAULT_DURATION;if(dur2===null)return;timers.current.set(id,setTimeout(()=>{timers.current.delete(id),setItems((prev)=>prev.filter((t2)=>t2.id!==id))},dur2))},[]),clear=import_react36.useCallback((key3)=>{setItems((prev)=>{for(let item of prev){if(item.key!==key3)continue;let t2=timers.current.get(item.id);if(t2)clearTimeout(t2);timers.current.delete(item.id)}return prev.filter((t2)=>t2.key!==key3)})},[]),error=import_react36.useCallback((err)=>{show({variant:"error",title:"Error",message:err.message})},[show]),value=import_react36.useMemo(()=>({show,clear,error}),[show,clear,error]);return $jsxs(Ctx3.Provider,{value,children:[children,items.length>0?$jsx(ToastOverlay,{items}):null]})},ToastOverlay=({items})=>{let theme=useTheme().theme,color=(variant)=>{switch(variant){case"error":return theme.error;case"warning":return theme.warning;case"success":return theme.success;default:return theme.info}};return $jsx("box",{position:"absolute",top:2,right:2,flexDirection:"column",gap:1,zIndex:200,maxWidth:60,children:items.map((item)=>$jsxs("box",{backgroundColor:theme.backgroundPanel,border:["left"],borderStyle:"single",borderColor:color(item.variant),paddingLeft:1,paddingRight:1,flexDirection:"column",children:[item.title?$jsx("text",{fg:theme.text,children:$jsx("strong",{children:item.title})}):null,$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:item.message}),item.action?$jsx("box",{height:1,marginTop:0,onMouseDown:item.action.run,children:$jsx("text",{fg:color(item.variant),children:$jsx("u",{children:item.action.label})})}):null]},item.id))})},useToast=makeUse(Ctx3,"useToast");var Ctx4=import_react37.createContext(null),BACKDROP=RGBA.fromInts(0,0,0,150),DialogProvider=({children})=>{let renderer=useRenderer(),toast=useToast(),[stack,setStack]=import_react37.useState([]),stackRef=import_react37.useRef(stack);stackRef.current=stack;let gate=import_react37.useRef(!1),listeners2=import_react37.useRef(new Set),gen=import_react37.useRef(0),prev=import_react37.useRef(null),refocus=import_react37.useCallback(()=>{setTimeout(()=>{if(gate.current)return;let target=prev.current;if(!target||target.isDestroyed){prev.current=null;return}let reachable=(node)=>{for(let c of node.getChildren())if(c===target||reachable(c))return!0;return!1};if(reachable(renderer.root))target.focus();prev.current=null},0)},[renderer]),replace=import_react37.useCallback((element,onClose,opts)=>{if(!gate.current&&!prev.current)prev.current=renderer.currentFocusedRenderable,prev.current?.blur();gate.current=!0,gen.current++;for(let listener of listeners2.current)listener();setStack((cur)=>{for(let e of cur)e.onClose?.();return[{element,onClose,ownCancel:opts?.ownCancel}]})},[renderer]),clear=import_react37.useCallback(()=>{let at=++gen.current;setStack((cur)=>{for(let e of cur)e.onClose?.();return[]}),queueMicrotask(()=>{if(gen.current!==at)return;gate.current=!1;for(let listener of listeners2.current)listener()}),refocus()},[refocus]),open=import_react37.useCallback(()=>gate.current,[]),version=import_react37.useCallback(()=>gen.current,[]),subscribe2=import_react37.useCallback((listener)=>{return listeners2.current.add(listener),()=>{listeners2.current.delete(listener)}},[]),onError=import_react37.useCallback((err)=>{clear(),toast.error(err)},[clear,toast]),keys=useKeys();useKeyboard((key3)=>{if(stack.length===0)return;if(renderer.getSelection()?.getSelectedText())return;if(stack[stack.length-1]?.ownCancel)return;if(keys.match("dialog.cancel",key3))clear()});let value=import_react37.useMemo(()=>({replace,clear,get stack(){return stackRef.current},open,version,subscribe:subscribe2}),[replace,clear,open,version,subscribe2]),top=stack[stack.length-1];return $jsxs(Ctx4.Provider,{value,children:[children,top?$jsx(Boundary,{onError,children:$jsx(Overlay,{entry:top,onClose:clear})}):null]})};class Boundary extends import_react37.Component{state={dead:!1};static getDerivedStateFromError(){return{dead:!0}}componentDidCatch(err,_info){this.props.onError(err)}render(){if(this.state.dead)return null;return this.props.children}}var Overlay=({entry,onClose})=>{let dims=useTerminalDimensions(),theme=useTheme().theme,renderer=useRenderer(),armed=import_react37.useRef(!1);return $jsx("box",{position:"absolute",left:0,top:0,width:dims.width,height:dims.height,zIndex:100,backgroundColor:BACKDROP,justifyContent:"center",alignItems:"center",onMouseDown:()=>{armed.current=!renderer.getSelection()},onMouseUp:()=>{if(!armed.current)return;armed.current=!1,onClose()},children:$jsx("box",{backgroundColor:theme.backgroundPanel,borderStyle:"single",border:!0,borderColor:theme.border,padding:1,flexDirection:"column",onMouseDown:(e)=>{e.stopPropagation()},onMouseUp:(e)=>{armed.current=!1,e.stopPropagation()},children:entry.element})})},useDialog=makeUse(Ctx4,"useDialog"),useDialogOpen=()=>{let dialog=useDialog();return import_react37.useSyncExternalStore(dialog.subscribe,dialog.open,dialog.open)};var WIDTH=48,PAD_L=12,INNER=WIDTH-4,trunc=(s,max)=>s.length<=max?s:s.slice(0,max-1)+"\u2026";function hidden2(props){let cwd=props.info?.cwd?.split(/[/\\]/).filter(Boolean).pop();return{profile:props.profile,model:props.info?.model,title:props.title,place:props.branch??cwd,context:typeof props.usage?.context_percent==="number"?`${props.usage.context_percent}%`:void 0}}var Section=import_react39.memo((props)=>{let theme=useTheme().theme,[hover,setHover]=import_react39.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)})]})})},ChangesDialog=import_react39.memo((props)=>{let theme=useTheme().theme;return $jsxs("box",{flexDirection:"column",width:70,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:`Changed Files (${props.files.length})`})}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,maxHeight:20,paddingRight:1,contentOptions:{flexDirection:"column"},children:props.files.map((f)=>$jsx("box",{height:1,paddingRight:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" "}),$jsx("span",{fg:f.code[0]==="?"?theme.diffAdded:f.code[0]==="A"||f.code[1]==="A"?theme.diffAdded:f.code[0]==="D"||f.code[1]==="D"?theme.diffRemoved:theme.warning,children:f.code}),$jsx("span",{fg:theme.textMuted,children:" "+f.file})]})},f.file))})]})}),Sidebar=import_react39.memo((props)=>{let theme=useTheme().theme,state=props.agentState??"idle",info=props.info,[mcpOpen,setMcpOpen]=import_react39.useState(!1),dialog=useDialog(),cwd=info?.cwd??process.cwd(),branch2=exports_git.useGitBranch(cwd),changes=exports_git.useGitStatus(cwd),keys=useKeys(),ref=import_react39.useRef(changes);ref.current=changes;let show=()=>{let cur=ref.current;if(!cur||cur.files.length===0||dialog.open())return;dialog.replace($jsx(ChangesDialog,{files:cur.files}))};return useKeyboard((key3)=>{if(dialog.open()||!keys.match("sidebar.changes",key3))return;key3.stopPropagation(),show()}),$jsxs("box",{width:WIDTH,flexDirection:"column",children:[$jsxs("box",{position:"relative",flexDirection:"column",height:24,overflow:"hidden",onMouseDown:props.onAvatar,children:[$jsx(Avatar,{state,eikon:props.eikon,onHold:props.onAvatarHold}),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:[$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:exports_git.rtrunc(branch2,INNER-PAD_L-2)}):null,changes&&changes.added+changes.modified+changes.deleted>0?$jsx("box",{height:1,onMouseDown:show,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u25B8 "}),$jsx("span",{fg:theme.text,children:$jsx("strong",{children:"Changes"})}),$jsx("span",{fg:theme.textMuted,children:` +${changes.added} ~${changes.modified} -${changes.deleted}`})]})}):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}),$jsx(ContextGauge,{info,usage:props.usage,width:INNER})]})]})});var import_react50=__toESM(require_react_production(),1);var import_react49=__toESM(require_react_production(),1);var import_react48=__toESM(require_react_production(),1);var import_react41=__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(text4){if(!process.stdout.isTTY)return;let osc52=`\x1B]52;c;${Buffer.from(text4).toString("base64")}\x07`,seq=process.env.TMUX||process.env.STY?`\x1BPtmux;\x1B${osc52}\x1B\\`:osc52;process.stdout.write(seq)}async function nativeCopy(text4){let os2=platform();if(os2==="darwin"){let proc=Bun.spawn(["pbcopy"],{stdin:"pipe"});proc.stdin.write(text4),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(text4),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(text4),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(text4),proc.stdin.end(),await proc.exited;return}catch{}}}async function copy2(text4){if(writeOsc52(text4),shouldUseNativeClipboard())await nativeCopy(text4).catch(()=>{})}function copied(toast,message="Copied to clipboard"){toast.show({key:"clipboard.copy",variant:"success",message})}function copyText(text4,toast,message="Copied to clipboard"){let p=copy2(text4);if(toast)copied(toast,message);return p}function copySelection(renderer,toast){let text4=renderer.getSelection()?.getSelectedText();if(!text4)return!1;return copyText(text4,toast).catch(()=>{}),renderer.clearSelection(),!0}var CAP2=6,ErrorBlock=import_react41.memo(({text:text4})=>{let theme=useTheme().theme,[open,setOpen]=import_react41.useState(!1),[copied2,setCopied]=import_react41.useState(!1),lines3=text4.trimEnd().split(`
@@ -4126,12 +4126,12 @@ Current chat will be replaced.`,yes:"load"}).then((ok)=>{if(ok)l.onSwitch?.(sid2
4126
4126
  `,nl+1)).trim().startsWith("#")){end=nl;break}}end=nl}mark2(skH,end+1,"skills","Skills Catalog",makeSource("skills","skills/"))}let proj=text4.indexOf("# Project Context");if(proj>=0){let conv2=text4.indexOf("Conversation started:");mark2(proj,conv2>proj?conv2:text4.length,"project","Project Context",makeSource("AGENTS.md"))}let conv=text4.indexOf("Conversation started:");if(conv>=0)mark2(conv,text4.length,"meta","Session Metadata");let start=-1;for(let i=0;i<=text4.length;i++)if(i<text4.length&&!used[i]){if(start<0)start=i}else if(start>=0){let slice=text4.slice(start,i);if(slice.trim().length>0)sections.push({id:"other",label:"Other",chars:slice.length,tokens:count2(slice),text:slice});start=-1}return sections.sort((a,b2)=>text4.indexOf(a.text)-text4.indexOf(b2.text))}function classifyTools(tools){let system=[],mcp=[];for(let t2 of tools)if(t2.name.startsWith("mcp_"))mcp.push(t2);else system.push(t2);return{system,mcp}}function toolTokens(tool){return Math.ceil((tool.descriptionLength+tool.paramsLength)/CPT)}function build(opts){let pct=(t2)=>opts.contextLength>0?t2/opts.contextLength*100:0,result=[],byId2=new Map;for(let s of opts.sections)byId2.set(s.id,s);let promptChildren=opts.sections.filter((sec)=>SYSTEM_PROMPT_IDS.has(sec.id)&&sec.tokens>0).map((sec)=>({id:sec.id,label:sec.label,tokens:sec.tokens,percent:pct(sec.tokens),section:sec})),promptTok=promptChildren.reduce((s,c)=>s+c.tokens,0);if(promptTok>0)result.push({id:"system_prompt",label:"System Prompt",tokens:promptTok,percent:pct(promptTok),children:promptChildren});let{system:sysTools,mcp:mcpTools}=classifyTools(opts.tools),sysToolsTok=sysTools.reduce((s,t2)=>s+toolTokens(t2),0);if(sysToolsTok>0)result.push({id:"system_tools",label:"System Tools",tokens:sysToolsTok,percent:pct(sysToolsTok)});let mcpToolsTok=mcpTools.reduce((s,t2)=>s+toolTokens(t2),0);if(mcpToolsTok>0)result.push({id:"mcp_tools",label:"MCP Tools",tokens:mcpToolsTok,percent:pct(mcpToolsTok)});let memChildren=opts.sections.filter((sec)=>MEMORY_IDS.has(sec.id)&&sec.tokens>0).map((sec)=>({id:sec.id,label:sec.label,tokens:sec.tokens,percent:pct(sec.tokens),section:sec})),memTok=memChildren.reduce((s,c)=>s+c.tokens,0);if(memTok>0)result.push({id:"memory",label:"Memory",tokens:memTok,percent:pct(memTok),children:memChildren});let skillsSec=byId2.get("skills"),skillsTok=skillsSec?.tokens??opts.skillsTokens??0;if(skillsTok>0)result.push({id:"skills",label:"Skills",tokens:skillsTok,percent:pct(skillsTok),section:skillsSec});if(opts.conversationTokens>0){let ct=opts.conversationTokens;result.push({id:"conversation",label:"~Conversation",tokens:ct,percent:pct(ct)})}let taken=result.reduce((s,g)=>s+g.tokens,0),used=opts.usedTokens;if(typeof used!=="number"){let unknown2=Math.max(0,opts.contextLength-taken);if(unknown2>0)result.push({id:"unknown",label:"Unknown (live unavailable)",tokens:unknown2,percent:pct(unknown2)});return result}let unknown=Math.max(0,used-taken);if(unknown>0)result.push({id:"unknown",label:"Unknown / Provider Overhead",tokens:unknown,percent:pct(unknown)});let overage=Math.max(0,taken-used);if(overage>0)result.push({id:"overage",label:"Estimate Overage",tokens:overage,percent:pct(overage)});let free=Math.max(0,opts.contextLength-used);return result.push({id:"free",label:"Free",tokens:free,percent:pct(free)}),result}function drill(group2){if(!group2.children||group2.children.length===0)return[];let total=group2.tokens;return group2.children.map((c)=>({...c,percent:total>0?c.tokens/total*100:0}))}function cells(segments,fallback2="free"){let filled=segments.flatMap((seg)=>Array.from({length:Math.round(seg.percent/100*GRID)},()=>({id:seg.id}))),pad=Array.from({length:Math.max(0,GRID-filled.length)},()=>({id:fallback2}));return[...filled,...pad].slice(0,GRID)}var import_react60=__toESM(require_react_production(),1);var FileLink=import_react60.memo(({source,children:children2})=>{let theme=useTheme().theme,[hovered,setHovered]=import_react60.useState(!1);return $jsx("box",{height:1,onMouseDown:()=>openFile(source.file),onMouseOver:()=>setHovered(!0),onMouseOut:()=>setHovered(!1),children:$jsx("text",{fg:theme.info,attributes:hovered?TextAttributes.UNDERLINE:TextAttributes.NONE,children:children2??source.label})})}),KVLink=(props)=>{let theme=useTheme().theme;return $jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:props.label})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx(FileLink,{source:props.source,children:props.text??props.source.label})})]})};var GOLDEN_ANGLE=137.50776405003785;function luminance(c){return 0.299*c.r+0.587*c.g+0.114*c.b}function rgbaToHsl(c){let{r,g,b:b2}=c,max=Math.max(r,g,b2),min=Math.min(r,g,b2),l=(max+min)/2,d2=max-min;if(d2===0)return[0,0,l];let s=l>0.5?d2/(2-max-min):d2/(max+min),h2;switch(max){case r:h2=(g-b2)/d2+(g<b2?6:0);break;case g:h2=(b2-r)/d2+2;break;default:h2=(r-g)/d2+4}return[h2*60,s,l]}function hslToRgba(h2,s,l){if(h2=(h2%360+360)%360/360,s===0)return RGBA.fromValues(l,l,l,1);let q3=l<0.5?l*(1+s):l+s-l*s,p=2*l-q3,ch=(t2)=>{if(t2<0)t2+=1;if(t2>1)t2-=1;if(t2<0.16666666666666666)return p+(q3-p)*6*t2;if(t2<0.5)return q3;if(t2<0.6666666666666666)return p+(q3-p)*(0.6666666666666666-t2)*6;return p};return RGBA.fromValues(ch(h2+0.3333333333333333),ch(h2),ch(h2-0.3333333333333333),1)}function categorical(seed,bg2,n){let[h0]=rgbaToHsl(seed),dark=luminance(bg2)<0.5,s=dark?0.6:0.7,l=dark?0.62:0.42,out=[];for(let i=0;i<n;i++)out.push(hslToRgba(h0+i*GOLDEN_ANGLE,s,l));return out}var DEFAULT_CTX=128000,COLS2=16,SLOTS2=["system_prompt","system_tools","mcp_tools","memory","skills","conversation","soul","mem0","user","project","meta","other","unknown","overage"],SLOT=Object.fromEntries(SLOTS2.map((id,i)=>[id,i])),REMOTE={tool_definitions:"system_tools",mcp:"mcp_tools",rules:"system_prompt",subagent_definitions:"system_tools"},ORDER2=["system_prompt","system_tools","mcp_tools","memory","skills","conversation"],LABEL2={system_prompt:"System Prompt",system_tools:"System Tools",mcp_tools:"MCP Tools",memory:"Memory",skills:"Skills",conversation:"Conversation"},rampCache=new WeakMap;function ramp2(theme){let r=rampCache.get(theme);if(!r)rampCache.set(theme,r=categorical(theme.primary,theme.background,SLOTS2.length));return r}function clr(id,theme){if(id==="free")return theme.borderSubtle;return ramp2(theme)[SLOT[id]??SLOT.other]}var fmt2=(n)=>{if(n>=1e6)return`${(n/1e6).toFixed(1)}M`;if(n>=1e4)return`${Math.round(n/1000)}k`;if(n>=1000)return`${(n/1000).toFixed(1)}k`;return String(n)},est=(s)=>s?count2(s):0,bar=(pct,w2=20)=>{let f=Math.round(Math.max(0,Math.min(100,pct))/100*w2);return`[${"\u2588".repeat(f)}${"\u2591".repeat(Math.max(0,w2-f))}]`},SectionPanel=import_react61.memo(({seg,theme})=>{let{syntaxStyle}=useTheme(),sec=seg.section;if(!sec)return null;return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(seg.id,theme),children:"\u25FC"})," ",seg.label," \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsxs("text",{children:[sec.chars.toLocaleString()," chars \xB7 ~",fmt2(sec.tokens)," tokens"]}),sec.source?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:"Source: "}),$jsx(FileLink,{source:sec.source})]}):null,$jsx("text",{children:" "}),$jsx("markdown",{content:sec.text,fg:theme.markdownText,syntaxStyle})]})}),MemoryPanel=import_react61.memo(({seg,theme,label:label2,chars,limit,pct,entries:entries2,source})=>$jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(seg.id,theme),children:"\u25FC"})," ",seg.label," \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:$jsx("strong",{children:label2})}),source?$jsxs($Fragment,{children:[$jsx("text",{children:" ("}),$jsx(FileLink,{source}),$jsx("text",{children:")"})]}):null]}),$jsxs("text",{children:[chars.toLocaleString()," / ",limit.toLocaleString()," chars (",pct,"%)"]}),$jsxs("text",{children:[bar(pct,25),pct>=95?" \u26A0 near limit":""]}),$jsx("text",{children:" "}),$jsxs("text",{children:[entries2.length," entries:"]}),entries2.map((e,i)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",e]},i))]})),SkillsPanel=import_react61.memo(({seg,theme})=>{let sec=seg.section;if(!sec)return null;let cats={};for(let line2 of sec.text.split(`
4127
4127
  `)){if(line2.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)){let cat=line2.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)[1];if(!cats[cat])cats[cat]=0}if(line2.match(/^\s{4}- \S+:/)){let last2=Object.keys(cats).pop();if(last2)cats[last2]++}}let sorted=Object.entries(cats).sort((a,b2)=>b2[1]-a[1]),total=sorted.reduce((s,[,n])=>s+n,0);return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("skills",theme),children:"\u25FC"})," Skills Catalog \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),sec.source?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:"Source: "}),$jsx(FileLink,{source:sec.source})]}):null,$jsx("text",{children:" "}),$jsxs("text",{children:[total," skills in ",sorted.length," categories \xB7 ",sec.chars.toLocaleString()," chars"]}),$jsx("text",{fg:theme.textMuted,children:"Largest context section \u2014 skill names + descriptions injected every turn."}),$jsx("text",{children:" "}),sorted.map(([cat,n])=>$jsxs("text",{fg:theme.text,children:["\xB7 ",cat," (",n,")"]},cat))]})}),ToolsPanel=import_react61.memo(({seg,theme,tools,kind:kind2})=>{let sorted=[...tools].sort((a,b2)=>b2.descriptionLength+b2.paramsLength-(a.descriptionLength+a.paramsLength)),label2=kind2==="mcp_tools"?"MCP Tools":"System Tools",blurb=kind2==="mcp_tools"?"MCP-loaded tools \u2014 schemas injected via mcp_ prefix.":"Built-in tool schemas sent with every API call.";return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(kind2,theme),children:"\u25FC"})," ",label2," \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:[tools.length," tools \u2014 ",blurb]}),$jsx("text",{children:" "}),sorted.map((t2)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",t2.name," (",fmt2(toolTokens(t2))," tok)"]},t2.name))]})}),ConvPanel=import_react61.memo(({seg,theme,messages,output})=>{let user=messages.filter((m2)=>m2.role==="user"),asst=messages.filter((m2)=>m2.role==="assistant"),non=messages.filter((m2)=>m2.role!=="system");return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("conversation",theme),children:"\u25FC"})," Conversation \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["User: ",user.length," msgs (~",fmt2(est(user.map((m2)=>text2(m2)).join("")))," tok)"]}),$jsxs("text",{children:["Agent: ",asst.length," msgs (~",fmt2(est(asst.map((m2)=>text2(m2)).join("")))," tok)"]}),output>0?$jsxs("text",{children:["Output generated: ",fmt2(output)," tokens"]}):null,$jsx("text",{children:" "}),non.length>0?$jsxs($Fragment,{children:[$jsx("text",{fg:theme.info,children:"Messages:"}),$jsx("text",{children:" "}),non.map((m2,i)=>$jsxs("text",{children:[$jsx("span",{fg:m2.role==="user"?theme.info:theme.success,children:m2.role==="user"?"\u25B8 You":"\u25C2 Agent"})," ","(",fmt2(est(text2(m2))),") ",text2(m2).replace(/\n/g," ")]},i))]}):$jsx("text",{fg:theme.warning,children:"No messages yet"})]})}),FreePanel=import_react61.memo(({seg,theme,ctxLen,comp,onEditThreshold})=>{let used=ctxLen-seg.tokens,threshold=Math.round(ctxLen*(comp?.threshold??0.5)),pct=threshold>0?Math.min(100,Math.round(used/threshold*100)):0;return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("free",theme),children:"\u25FB"})," Free Space \u2014 ",fmt2(seg.tokens)," tokens"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["Context window: ",fmt2(ctxLen)]}),$jsxs("text",{children:["Used: ",fmt2(used)," (",Math.round(used/ctxLen*100),"%)"]}),$jsxs("text",{children:["Available: ",fmt2(seg.tokens)," (",seg.percent.toFixed(1),"%)"]}),$jsx("text",{children:" "}),comp?$jsxs($Fragment,{children:[$jsx("text",{children:$jsx("strong",{children:"Compression"})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsxs("text",{children:[comp.enabled?"\u2713 Enabled":"\u2717 Disabled"," \xB7 threshold "]}),$jsx("box",{flexShrink:0,onMouseDown:onEditThreshold,children:$jsx("text",{fg:theme.info,children:$jsxs("u",{children:[Math.round(comp.threshold*100),"%"]})})}),$jsxs("text",{children:[" (",fmt2(threshold),")"]})]}),$jsxs("text",{children:[bar(pct)," ",pct,"%"]}),$jsxs("text",{children:["Protect last ",comp.protect_last_n," messages \xB7 target ratio ",Math.round(comp.target_ratio*100),"%"]}),comp.summary_model?$jsxs("text",{children:["Summary model: ",comp.summary_model]}):null]}):null]})}),NO_MESSAGES=Object.freeze([]),toolsFromInfo=(info)=>{if(!info||info.tools===void 0)return null;let tools=Object.entries(info.tools).flatMap(([group2,names])=>names.map((name)=>({name,descriptionLength:0,paramsLength:group2.length})));return{source:makeSource("state.db","session.info"),tools}},configuredContextLength=(config)=>{let n=config?.model?.context_length;return typeof n==="number"&&n>0?n:void 0},contextMeter=(usage,info,config)=>({max:usage?.context_max??info?.usage?.context_max??info?.context_max??configuredContextLength(config)??DEFAULT_CTX,used:usage?.context_used??info?.usage?.context_used??info?.context_used}),contextBreakdown=(data2)=>{if(!data2||typeof data2!=="object")return null;let raw=data2,max=Number(raw.context_max),used=Number(raw.context_used);if(!Number.isFinite(max)||max<=0||!Number.isFinite(used)||used<0)return null;if(!Array.isArray(raw.categories))return null;return{categories:raw.categories.flatMap((cat)=>{if(!cat||typeof cat!=="object")return[];let id=typeof cat.id==="string"?cat.id.trim():"",label2=typeof cat.label==="string"?cat.label.trim():"",tokens3=Number(cat.tokens);if(!id||!label2||!Number.isFinite(tokens3)||tokens3<0)return[];return[{id,label:label2,tokens:tokens3,color:typeof cat.color==="string"?cat.color:void 0}]}),context_max:max,context_used:Math.min(used,max),estimated_total:Number.isFinite(Number(raw.estimated_total))?Math.max(0,Number(raw.estimated_total)):0,model:typeof raw.model==="string"?raw.model:void 0}},remoteSegments=(data2,local)=>{let byId2=new Map(local.map((seg)=>[seg.id,seg])),bucket=new Map;for(let cat of data2.categories){let id=REMOTE[cat.id]??cat.id,prev=bucket.get(id);bucket.set(id,{label:byId2.get(id)?.label??prev?.label??cat.label,tokens:(prev?.tokens??0)+cat.tokens})}let pct=(n)=>data2.context_max>0?n/data2.context_max*100:0,segs=[...ORDER2,...bucket.keys().filter((id)=>!ORDER2.includes(id))].flatMap((id)=>{let cat=bucket.get(id);if(!cat||cat.tokens<=0)return[];let seg=byId2.get(id);return[{...seg??{},id,label:seg?.label??LABEL2[id]??cat.label,tokens:cat.tokens,percent:pct(cat.tokens)}]}),taken=segs.reduce((sum,seg)=>sum+seg.tokens,0),unknown=Math.max(0,data2.context_used-taken);if(unknown>0)segs.push({id:"unknown",label:"Unknown / Provider Overhead",tokens:unknown,percent:pct(unknown)});let free=Math.max(0,data2.context_max-data2.context_used);return segs.push({id:"free",label:"Free",tokens:free,percent:pct(free)}),segs},Context=import_react61.memo(({messages=NO_MESSAGES,info,usage,focused})=>{let config=useHome("config"),memory=useHome("memory"),userProfile=useHome("userProfile"),gw=useGateway(),dialog=useDialog(),toast=useToast(),systemPrompt2=useHome("systemPrompt"),toolsInfo=useHome("toolsInfo"),soul=useHome("soul"),[wire,setWire]=import_react61.useState({input:0,output:0,total:0,calls:0}),wireRef=import_react61.useRef(wire),theme=useTheme().theme,[hovered,setHovered]=import_react61.useState(null),[selected,setSelected]=import_react61.useState(null),[drilled,setDrilled]=import_react61.useState(null),[remote2,setRemote]=import_react61.useState(null);import_react61.useEffect(()=>{let input=0,output2=0,total=0,calls=0;for(let m2 of messages)if(m2.usage)input+=m2.usage.input,output2+=m2.usage.output,total+=m2.usage.total,calls++;let next2={input,output:output2,total,calls};wireRef.current=next2,setWire(next2)},[messages]);let rev2=usage?.context_used??info?.usage?.context_used??info?.context_used;import_react61.useEffect(()=>{let sid2=info?.session_id;if(!sid2){setRemote(null);return}let done=!1,timer2=setTimeout(()=>{gw.request("session.context_breakdown",{session_id:sid2}).then((data2)=>{if(!done)setRemote(contextBreakdown(data2))}).catch(()=>{if(!done)setRemote(null)})},300);return()=>{done=!0,clearTimeout(timer2)}},[gw,info?.session_id,info?.usage?.compressions,messages.length,rev2]);let localMeter=contextMeter(usage,info,config??null),meter=remote2?{max:remote2.context_max,used:remote2.context_used}:localMeter,ctxLen=meter.max,used=meter.used,reliable=typeof used==="number",output=wire.output,pct=reliable&&ctxLen>0?Math.round(used/ctxLen*100):0,thresholdPct=config?.compression?.threshold??0.5,thresholdIdx=Math.min(COLS2*COLS2,Math.max(0,Math.round(thresholdPct*COLS2*COLS2))),compressions=info?.usage?.compressions??0,promptText=info?.system_prompt??systemPrompt2?.text??"",sections=import_react61.useMemo(()=>parse4(promptText),[promptText]),convTok=import_react61.useMemo(()=>est(messages.filter((m2)=>m2.role!=="system").map((m2)=>text2(m2)).join("")),[messages]),currentTools=import_react61.useMemo(()=>{let liveTools=toolsFromInfo(info);if(liveTools)return liveTools;if(info?.tools!==void 0)return liveTools;return toolsInfo},[info,toolsInfo]),local=import_react61.useMemo(()=>build({contextLength:ctxLen,usedTokens:used,sections,conversationTokens:convTok,tools:currentTools?.tools??[]}),[ctxLen,used,sections,convTok,currentTools]),top2=import_react61.useMemo(()=>remote2?remoteSegments(remote2,local):local,[remote2,local]),drilledGroup=drilled?top2.find((s)=>s.id===drilled):null,view=drilledGroup?drill(drilledGroup):top2,grid=import_react61.useMemo(()=>cells(view,drilledGroup?drilledGroup.children?.[0]?.id??"other":reliable?"free":"unknown"),[view,drilledGroup,reliable]),findSeg=(id)=>{if(drilledGroup)return view.find((s)=>s.id===id);return top2.find((s)=>s.id===id)},memEntries=import_react61.useMemo(()=>(memory?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[memory?.content]),userEntries=import_react61.useMemo(()=>(userProfile?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[userProfile?.content]),click=(id)=>{if(drilled){setSelected(selected===id?null:id);return}let seg=top2.find((s)=>s.id===id);if(seg?.children&&seg.children.length>0){setDrilled(id),setSelected(null);return}setSelected(selected===id?null:id)},lastEsc=import_react61.useRef(0),segs=view.filter((s)=>s.tokens>0),idx=selected?segs.findIndex((s)=>s.id===selected):-1,setSel=(v2)=>{let n=Math.max(0,Math.min(segs.length-1,typeof v2==="function"?v2(idx):v2));setSelected(segs[n]?.id??null)},keys=useKeys();useKeyboard((key3)=>{if(!focused||dialog.open())return;if(handleListKey(keys,key3,{count:segs.length,setSel,onActivate:()=>{if(drilled||!selected)return;if(top2.find((s)=>s.id===selected)?.children?.length)setDrilled(selected),setSelected(null)}}))return;if(key3.name==="right")return setSel((p)=>p+1);if(key3.name==="left")return setSel((p)=>p-1);if(key3.name!=="escape")return;let now=Date.now();if(now-lastEsc.current<400){setSelected(null),setDrilled(null),lastEsc.current=0;return}if(lastEsc.current=now,selected)return setSelected(null);if(drilled)return setDrilled(null)});let editThreshold=async()=>{let cur=Math.round((config?.compression?.threshold??0.5)*100),v2=await openTextPrompt(dialog,{title:"Compression threshold",label:"Percent (10\u201395)",initial:String(cur)});if(v2===null)return;let n=Math.max(10,Math.min(95,Number(v2)||cur)),{writeConfig:writeConfig2}=await Promise.resolve().then(() => (init_lane(),exports_lane)),r=await writeConfig2(gw,[{key:"compression.threshold",to:n/100}]);if(r.failed.length)return toast.show({variant:"error",message:r.failed[0].err});home3.invalidate("config"),toast.show({variant:"success",message:`Threshold \u2192 ${n}%`})},detail=()=>{if(!selected)return null;let seg=findSeg(selected);if(!seg)return null;if(selected==="memory"&&drilled==="memory"&&memory)return $jsx(MemoryPanel,{seg,theme,label:"Agent Notes",chars:memory.charCount,limit:memory.charLimit,pct:memory.usagePercent,entries:memEntries,source:memory.source});if(selected==="user"&&userProfile)return $jsx(MemoryPanel,{seg,theme,label:"User Profile",chars:userProfile.charCount,limit:userProfile.charLimit,pct:userProfile.usagePercent,entries:userEntries,source:userProfile.source});if(selected==="skills")return $jsx(SkillsPanel,{seg,theme});if(selected==="system_tools"&&currentTools){let{system}=classifyTools(currentTools.tools);return $jsx(ToolsPanel,{seg,theme,tools:system,kind:"system_tools"})}if(selected==="mcp_tools"&&currentTools){let{mcp}=classifyTools(currentTools.tools);return $jsx(ToolsPanel,{seg,theme,tools:mcp,kind:"mcp_tools"})}if(selected==="soul"&&soul){let soulSeg={...seg,section:{id:"soul",label:"SOUL.md",chars:soul.charCount,tokens:soul.tokenEstimate,text:soul.content,source:soul.source}};return $jsx(SectionPanel,{seg:soulSeg,theme})}if(selected==="conversation")return $jsx(ConvPanel,{seg,theme,messages,output});if(selected==="free")return $jsx(FreePanel,{seg,theme,ctxLen,comp:config?.compression,onEditThreshold:editThreshold});return $jsx(SectionPanel,{seg,theme})},breakdown=()=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsxs("text",{children:[$jsx("strong",{children:"Breakdown"}),drilledGroup?$jsxs("span",{fg:theme.info,children:[" \xB7 ",drilledGroup.label," (",fmt2(drilledGroup.tokens)," tok)"]}):reliable?$jsx("span",{fg:theme.info,children:" (click group to expand)"}):$jsxs("span",{fg:theme.warning,children:[" \xB7 live usage unavailable \xB7 limit ",fmt2(ctxLen)]})]}),view.filter((s)=>s.tokens>0).map((s)=>$jsxs("text",{children:[$jsx("span",{fg:clr(s.id,theme),children:s.id==="free"?"\u25FB":"\u25FC"})," ",s.label," \u2014 ",fmt2(s.tokens)," (",s.percent.toFixed(1),"%)",s.children?$jsx("span",{fg:theme.textMuted,children:" \u25B8"}):null]},s.id)),output>0&&!drilled?$jsxs("text",{children:[$jsx("span",{fg:theme.success,children:"\u25FC"})," Output \u2014 ",fmt2(output)," tokens"]}):null,reliable&&!drilled?$jsx("text",{children:$jsxs("span",{fg:theme.textMuted,children:["\u25FC Beyond compression threshold (",Math.round(thresholdPct*100),"%)"]})}):null]}),crumb=drilled?`${drilledGroup?.label}${selected?` \xB7 ${findSeg(selected)?.label}`:""}`:reliable?"\u2191\u2193 nav \xB7 click a group to drill in":"live usage unavailable \xB7 estimates shown with ~",escHint=selected||drilled?" \xB7 Esc back":"",focus=selected||hovered,focusSeg=focus?findSeg(focus):null;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs(TabShell,{title:reliable?`Context \xB7 ${fmt2(used)} / ${fmt2(ctxLen)} (${pct}%)`:`Context \xB7 live usage unavailable \xB7 limit ${fmt2(ctxLen)}`,children:[$jsx("box",{height:1,children:focusSeg?$jsxs("text",{fg:clr(focusSeg.id,theme),children:["\u25FC ",focusSeg.label," \u2014 ",fmt2(focusSeg.tokens)," tok (",focusSeg.percent.toFixed(1),"%)"]}):$jsx("text",{children:" "})}),$jsx("box",{height:1}),$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsxs("box",{flexDirection:"column",marginRight:2,flexShrink:0,children:[!drilled&&compressions>0?$jsx("box",{height:1,marginBottom:1,children:$jsxs("text",{fg:theme.warning,children:["\xD7",compressions," compressed"]})}):null,$jsx("box",{border:!0,customBorderChars:CORNERS,borderColor:theme.border,children:[...Array(COLS2)].map((_2,row3)=>$jsx("box",{flexDirection:"row",height:1,children:[...Array(COLS2)].map((_3,col)=>{let cell=grid[row3*COLS2+col],hl=selected?selected===cell.id:hovered===cell.id,past=!drilled&&row3*COLS2+col>=thresholdIdx,glyph=!past&&cell.id==="free"?"\u25FB":"\u25FC";return $jsx("box",{height:1,width:2,backgroundColor:hl?clr(cell.id,theme):void 0,onMouseOver:()=>setHovered(cell.id),onMouseOut:()=>setHovered(null),onMouseDown:()=>click(cell.id),children:$jsx("text",{fg:past?theme.textMuted:clr(cell.id,theme),children:glyph})},col)})},row3))})]}),$jsx("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:selected?detail():breakdown()})]})]}),$jsx(HintBar,{raw:crumb+escHint})]})});var import_react64=__toESM(require_react_production(),1);init_hermes_analytics();var import_react63=__toESM(require_react_production(),1);init_hermes_analytics();var query=(days,opts)=>Promise.resolve(io.analytics(days,opts));function useAnalyticsData(days,tick3,load4=query){let[data2,setData]=import_react63.useState(()=>cache3.get(days)??null),[tools,setTools]=import_react63.useState(()=>cache3.get(days)?.byTool??null),[error,setError]=import_react63.useState(""),gen=import_react63.useRef(0);return import_react63.useEffect(()=>{let hit=cache3.get(days);setData(hit??null),setTools(hit?.byTool??null),setError("");let current=++gen.current;return load4(days,{tools:!1}).then((fast)=>{if(gen.current!==current)return;return setData(fast),load4(days).then((full)=>{if(gen.current!==current)return;cache3.set(days,full),setData(full),setTools(full.byTool)})}).catch((err)=>{if(gen.current===current)setError(err instanceof Error?err.message:String(err))}),()=>{gen.current++}},[days,tick3,load4]),{data:data2,tools,error}}var BLOCKS=" \u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588",rows2=(vals,h2)=>{let peak=Math.max(1,...vals),ticks=vals.map((v2)=>Math.round(h2*8*v2/peak));return Array.from({length:h2},(_2,r)=>{let floor=(h2-1-r)*8;return ticks.map((t2)=>BLOCKS[Math.max(0,Math.min(8,t2-floor))]).join("")})},Chart=import_react64.memo((p)=>{let theme=useTheme().theme,days=p.data.byDay,vals=days.map((d2)=>d2.cost),peak=Math.max(...vals,0.01),axis=(v2)=>cost2(v2).padStart(7),md=(s)=>s.slice(5);return $jsxs("box",{flexDirection:"column",children:[rows2(vals,p.h).map((line2,i)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:i===0?axis(peak):i===p.h-1?axis(0):""})}),$jsx("text",{fg:theme.primary,children:line2})]},i)),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,flexShrink:0}),$jsx("text",{fg:theme.textMuted,children:days.length>0?`${md(days[0].date)}${" ".repeat(Math.max(0,days.length-10))}${md(days[days.length-1].date)}`:""})]})]})}),Rank=import_react64.memo((p)=>{let theme=useTheme().theme;if(p.rows===null)return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.title})}),$jsx("box",{height:1,children:$jsx(Spinner,{label:"aggregating\u2026"})})]});let top2=p.rows.slice(0,p.n??10),peak=Math.max(1,...top2.map((r)=>r.n)),total=p.rows.reduce((a,r)=>a+r.n,0);return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.title})}),top2.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"\u2014"})}):top2.map((r)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx(Col,{w:18,children:trunc5(r.name,17)}),$jsx(Col,{w:12,fg:p.fg,children:"\u2587".repeat(Math.max(1,Math.round(10*r.n/peak)))}),$jsx(Col,{w:7,right:!0,children:fmt(r.n)}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:total?`${Math.round(100*r.n/total)}%`:""})]},r.name))]})}),Analytics=import_react64.memo((props)=>{let theme=useTheme().theme,dialog=useDialog(),dims=useTerminalDimensions(),[days,setDays]=import_react64.useState(7),[tick3,setTick]=import_react64.useState(0),{data:data2,tools,error}=useAnalyticsData(days,tick3,props.load),keys=useKeys();useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(keys.match("list.refresh",key3))return cache3.delete(days),setTick((n)=>n+1);if(key3.raw==="1")return setDays(1);if(key3.raw==="7")return setDays(7);if(key3.raw==="3")return setDays(30);if(key3.raw==="9")return setDays(90)});let t2=data2?.total,tok=(t2?.input??0)+(t2?.output??0),title=import_react64.useMemo(()=>!t2?`Analytics \xB7 ${days}d`:`Analytics \xB7 ${days}d \xB7 ${t2.sessions} sess \xB7 ${fmt(tok)} tok \xB7 ${cost2(t2.cost)}`,[days,t2,tok]),wide=dims.width>=110,chartH=dims.height>=40?8:6;if(!data2)return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(TabShell,{title,children:$jsx("box",{height:1,children:error?$jsx("text",{fg:theme.error,children:error}):$jsx(Spinner,{label:`aggregating ${days}d\u2026`})})}),$jsx(HintBar,{pairs:[["1/7/3/9","period"],[keys.print("list.refresh"),"reload"]]})]});let nTools=8,nSrc=6,ranksH=wide?Math.max(nTools,nSrc)+1:nTools+nSrc+3;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(TabShell,{title,children:$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,overflow:"hidden",children:[error?$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:error})}):null,$jsxs("box",{flexShrink:0,flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`Cost per day \xB7 ${fmt(t2.input)} in \xB7 ${fmt(t2.output)} out \xB7 ${fmt(t2.cache)} cache \xB7 ${fmt(t2.calls)} tool calls`})}),$jsx(Chart,{data:data2,h:chartH})]}),$jsx("box",{height:1,flexShrink:0}),$jsx("box",{flexShrink:0,children:$jsxs(Hdr,{children:[$jsx(Col,{grow:!0,min:18,fg:theme.textMuted,children:"Model"}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:"sess"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"in"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"out"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"cache"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"cost"})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,flexShrink:1,minHeight:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:data2.byModel.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"no sessions in range"})}):data2.byModel.map((m2)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx(Col,{grow:!0,min:18,children:trunc5(m2.model,40)}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:String(m2.sessions)}),$jsx(Col,{w:9,right:!0,children:fmt(m2.input)}),$jsx(Col,{w:9,right:!0,children:fmt(m2.output)}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:fmt(m2.cache)}),$jsx(Col,{w:9,right:!0,fg:theme.accent,children:cost2(m2.cost)})]},m2.model))})}),$jsx("box",{height:1,flexShrink:0}),$jsxs("box",{flexShrink:0,height:ranksH,flexDirection:wide?"row":"column",gap:wide?2:1,children:[$jsx(Rank,{title:"Tools",rows:tools,fg:theme.success,n:nTools}),$jsx(Rank,{title:"Sources",rows:data2.bySource,fg:theme.info,n:nSrc})]})]})}),$jsx(HintBar,{pairs:[["1/7/3/9","period"],[keys.print("list.refresh"),"reload"]]})]})});var import_react66=__toESM(require_react_production(),1);import{tmpdir as tmpdir3}from"os";import{join as join12}from"path";import{rm}from"fs/promises";async function editInEditor(renderer,seed,suffix2=".md"){let cmd=process.env.VISUAL||process.env.EDITOR;if(!cmd)return;let path4=join12(tmpdir3(),`herm-${Date.now()}${suffix2}`);await Bun.write(path4,seed);let suspended=!1;try{renderer.suspend(),suspended=!0,renderer.currentRenderBuffer.clear();let argv=process.platform==="win32"?["cmd.exe","/d","/s","/c",`${cmd} "${path4.replaceAll('"','""')}"`]:["/bin/sh","-c",`exec ${cmd} "$1"`,"herm-editor",path4],code=await Bun.spawn(argv,{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(code!==0)throw Error(`editor exited ${code}`);return(await Bun.file(path4).text().catch(()=>"")).trim()||void 0}finally{if(await rm(path4,{force:!0}).catch(()=>{}),suspended&&!renderer.isDestroyed)try{renderer.currentRenderBuffer.clear()}finally{renderer.resume(),renderer.requestRender()}}}function buildJourneyRows(buckets){return buckets.flatMap((bucket,b2)=>[...b2>0?[{kind:"gap"}]:[],{kind:"slice",bucket},...bucket.nodes.map((node,i)=>({kind:"node",bucket,node,last:i===bucket.nodes.length-1}))])}var style=(theme,key3,hex2)=>{if(hex2&&/^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$/.test(hex2))return RGBA.fromHex(hex2);if(key3==="skill")return theme.primary;if(key3==="memory")return theme.accent;if(key3==="label")return theme.text;if(key3==="dim")return theme.textMuted;if(key3==="bg")return theme.borderSubtle;return theme.textMuted},last2=(data2)=>data2?.frames.at(-1)?.grid??[],latest2=(rows3)=>{let i=[...rows3].reverse().findIndex((r)=>r.kind==="node");return i>=0?rows3.length-1-i:Math.max(0,rows3.length-1)},snap=(rows3,i,dir=1)=>{if(rows3.length===0)return 0;let at=Math.max(0,Math.min(rows3.length-1,i));if(rows3[at]?.kind!=="gap")return at;let rev2=[...rows3].reverse().findIndex((r,n)=>rows3.length-1-n<at&&r.kind!=="gap");if(dir<0&&rev2>=0)return rows3.length-1-rev2;let fwd=rows3.findIndex((r,n)=>n>at&&r.kind!=="gap");if(fwd>=0)return fwd;return rev2>=0?rows3.length-1-rev2:at},message=(err)=>err instanceof Error?err.message:String(err),rid=(r,i)=>{if(!r)return`empty-${i}`;if(r.kind==="slice")return`slice-${r.bucket.index}-${r.bucket.date??r.bucket.label}`;if(r.kind==="node")return`node-${r.bucket.index}-${r.node.id}`;return`gap-${i}`},Journey=import_react66.memo((props)=>{let gw=useGateway(),theme=useTheme().theme,dialog=useDialog(),toast=useToast(),renderer=useRenderer(),dims=useTerminalDimensions(),keys=useKeys(),[data2,setData]=import_react66.useState(null),[err,setErr]=import_react66.useState(null),[sel,setSel]=import_react66.useState(0),[detail,setDetail]=import_react66.useState(null),[pane,setPane]=import_react66.useState("list"),[busy,setBusy]=import_react66.useState(!1),[tick3,setTick]=import_react66.useState(0),rows3=import_react66.useMemo(()=>buildJourneyRows(data2?.buckets??[]),[data2]),row3=rows3[Math.min(sel,Math.max(0,rows3.length-1))],node=row3?.kind==="node"?row3.node:void 0,chart=last2(data2),h2=Math.max(5,Math.min(8,Math.floor(dims.height*0.2))),cols=Math.max(40,dims.width-8),follow=useFollow("journey",(i)=>rid(rows3[i],i)),scroll=import_react66.useRef(null),seq=import_react66.useRef(0),jump=import_react66.useCallback((i)=>{let n=snap(rows3,i);setSel(n),follow.opts.scrollTo(n)},[rows3]),setListSel=import_react66.useCallback((next2)=>{setSel((prev)=>{let target=typeof next2==="function"?next2(prev):next2,n=snap(rows3,target,target-prev);return follow.opts.scrollTo(n),n})},[rows3]);import_react66.useEffect(()=>{let n=0,cb=async()=>{if(n++,n<2)return;follow.opts.scrollTo(sel),renderer.removeFrameCallback(cb)};return renderer.setFrameCallback(cb),()=>renderer.removeFrameCallback(cb)},[renderer,rows3,sel]),import_react66.useEffect(()=>{let n=++seq.current;setErr(null),setBusy(!0);let timer2=setTimeout(()=>{gw.request("learning.frames",{cols,rows:h2,frames:2}).then((r)=>{if(n!==seq.current)return;setData(r);let tree=buildJourneyRows(r.buckets??[]);setSel(latest2(tree)),setDetail(null),setPane("list")}).catch((e)=>{if(n===seq.current)setErr(message(e))}).finally(()=>{if(n===seq.current)setBusy(!1)})},120);return()=>{clearTimeout(timer2),seq.current++}},[gw,cols,h2,tick3]);let open2=import_react66.useCallback(async(target)=>{setBusy(!0),setErr(null);try{let r=await gw.request("learning.detail",{id:target.id});if(setDetail(r),setPane("detail"),!r.ok)toast.show({variant:"warning",message:r.message})}catch(e){setErr(message(e))}finally{setBusy(!1)}},[gw,toast]),edit=import_react66.useCallback(async()=>{if(!node)return;setBusy(!0),setErr(null);try{let info=await gw.request("learning.detail",{id:node.id});if(!info.ok){toast.show({variant:"warning",message:info.message});return}let text4=await editInEditor(renderer,info.content,info.kind==="skill"?".md":".txt");if(text4===void 0||text4.trim()===info.content.trim()){toast.show({variant:"info",message:"no changes"});return}let req={id:node.id,content:text4},r=await gw.request("learning.edit",req);if(toast.show({variant:r.ok?"success":"warning",message:r.message}),r.ok||/stale|refresh/i.test(r.message))setTick((n)=>n+1)}catch(e){setErr(message(e))}finally{setBusy(!1)}},[gw,node,renderer,toast]),del=import_react66.useCallback(async()=>{if(!node)return;if(!await openConfirm(dialog,{title:`Delete ${node.label}?`,body:`${node.fullLabel||node.label}
4128
4128
 
4129
- This mutates the learning source through learning.delete.`,yes:"delete",danger:!0}))return;setBusy(!0),setErr(null);try{let req={id:node.id},r=await gw.request("learning.delete",req);if(toast.show({variant:r.ok?"success":"warning",message:r.message}),r.ok||/stale|refresh/i.test(r.message))setTick((n)=>n+1)}catch(e){setErr(message(e))}finally{setBusy(!1)}},[dialog,gw,node,toast]);useKeyboard((key3)=>{if(!props.focused||dialog.open()||busy)return;if(detail&&(key3.name==="tab"||keys.match("focus.cycle",key3))){setPane((p)=>p==="list"?"detail":"list");return}if(detail&&pane==="detail"){let page=Math.max(1,(scroll.current?.viewport.height??10)-1);if(key3.name==="escape"){setPane("list");return}if(key3.name==="up"||key3.name==="k"||key3.raw==="k"){scroll.current?.scrollBy(-1);return}if(key3.name==="down"||key3.name==="j"||key3.raw==="j"){scroll.current?.scrollBy(1);return}if(key3.name==="pageup"){scroll.current?.scrollBy(-page);return}if(key3.name==="pagedown"){scroll.current?.scrollBy(page);return}if(key3.name==="home"||key3.name==="g"){scroll.current?.scrollTo(0);return}if(key3.name==="end"||key3.raw==="G"||key3.name==="g"&&key3.shift){scroll.current?.scrollTo(scroll.current.scrollHeight);return}return}if(key3.name==="escape"&&detail){setDetail(null),setPane("list");return}if(handleListKey(keys,key3,{count:rows3.length,setSel:setListSel,...follow.opts,onActivate:()=>{if(node)open2(node)},onToggle:()=>{if(node)open2(node)},onRefresh:()=>setTick((n)=>n+1),onDelete:()=>void del()}))return;if(key3.name==="e"||key3.raw==="e"){edit();return}});let rowPick=import_react66.useCallback((i)=>jump(i),[jump]),rowOpen=import_react66.useCallback((i)=>{jump(i);let r=rows3[i];if(r?.kind==="node")open2(r.node)},[jump,open2,rows3]),hint=detail&&pane==="detail"?`\u2191\u2193/jk scroll ${keys.print("list.pageUp")}/${keys.print("list.pageDown")} page Tab list Esc list`:`${keys.print("list.activate")} detail ${keys.print("list.toggle")} detail e edit ${keys.print("list.delete")} delete ${keys.print("list.refresh")} reload${detail?" Tab detail Esc close":""}`;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,minWidth:0,children:[$jsxs(TabShell,{title:data2?`Journey \xB7 ${data2.count} learned item${data2.count===1?"":"s"}`:"Journey",error:err,focus:pane==="list",grow:detail?2:1,children:[!data2&&!err?$jsx(Loading,{}):null,!data2&&err?$jsx(ErrorState,{err}):null,data2&&data2.count===0?$jsx(Empty,{}):null,data2&&data2.count>0?$jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:0,children:[$jsx(Legend,{data:data2}),$jsx(Chart2,{rows:chart,theme}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",children:rows3.map((r,i)=>$jsx(Row2,{id:follow.id(i),row:r,index:i,active:i===sel,theme,pick:rowPick,open:rowOpen},rid(r,i)))})})]}):null]}),detail?$jsx(Detail2,{detail,box:scroll,focus:pane==="detail",theme}):null]}),$jsx(HintBar,{raw:busy?"loading\u2026":hint})]})}),Loading=()=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,justifyContent:"center",alignItems:"center",children:$jsx("text",{fg:theme.textMuted,children:"assembling learning map\u2026"})})},Empty=()=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,justifyContent:"center",alignItems:"center",children:$jsx("text",{fg:theme.textMuted,children:"No learning yet \u2014 skills and memories will appear here."})})},ErrorState=({err})=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,justifyContent:"center",alignItems:"center",children:$jsx("text",{fg:theme.error,wrapMode:"word",children:err})})},Legend=({data:data2})=>{let theme=useTheme().theme,text4=[...data2.legend??[],...data2.categories??[]].map((i)=>`${i.glyph} ${i.label}`).join(" ")||data2.summary.join(" ");return $jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:text4})})},Chart2=({rows:rows3,theme})=>$jsx("box",{flexDirection:"column",flexShrink:0,children:rows3.map((row3,i)=>$jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{wrapMode:"none",children:row3.map((run,n)=>$jsx("span",{fg:style(theme,run[1],run[3]),children:run[0]},n))})},i))}),Row2=import_react66.memo((props)=>{let bg2=props.active?props.theme.backgroundElement:void 0,caret=props.active?"\u25B8 ":" ";if(props.row.kind==="gap")return $jsx("box",{id:props.id,height:1});if(props.row.kind==="slice")return $jsx("box",{id:props.id,height:1,backgroundColor:bg2,onMouseMove:()=>props.pick(props.index),onMouseDown:()=>props.open(props.index),overflow:"hidden",children:$jsxs("text",{wrapMode:"none",children:[$jsx("span",{fg:props.theme.textMuted,children:caret}),$jsx("span",{fg:props.active?props.theme.accent:props.theme.primary,children:props.row.bucket.label}),$jsx("span",{fg:props.theme.textMuted,children:` ${props.row.bucket.total} total \xB7 ${props.row.bucket.memories} memories \xB7 ${props.row.bucket.skills} skills`})]})});return $jsx("box",{id:props.id,height:1,backgroundColor:bg2,onMouseMove:()=>props.pick(props.index),onMouseDown:()=>props.open(props.index),overflow:"hidden",children:$jsxs("text",{wrapMode:"none",children:[$jsx("span",{fg:props.theme.textMuted,children:caret}),$jsx("span",{fg:props.theme.textMuted,children:props.row.last?" \u2514\u2500 ":" \u251C\u2500 "}),$jsx("span",{fg:props.active?props.theme.accent:style(props.theme,props.row.node.style),children:`${props.row.node.glyph} ${trunc5(props.row.node.fullLabel||props.row.node.label,54)}`}),$jsx("span",{fg:props.theme.textMuted,children:props.row.node.meta?` ${props.row.node.meta}`:""})]})})}),Detail2=(props)=>$jsx(TabShell,{title:props.detail.ok?`${props.detail.kind} \xB7 ${props.detail.label}`:"Detail",focus:props.focus,grow:1,children:props.detail.ok?$jsx("scrollbox",{ref:props.box,scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:props.detail.content.split(/\r?\n/).map((line2,i)=>$jsx("box",{minHeight:1,children:$jsx("text",{fg:props.theme.text,wrapMode:"word",children:line2||" "})},i))})}):$jsx("text",{fg:props.theme.warning,wrapMode:"word",children:props.detail.message})});var import_react68=__toESM(require_react_production(),1);var SubTabBar=import_react68.memo((props)=>$jsx(TabStrip,{...props}));var TABS=[{name:"Chat",description:"Main chat interface"},{name:"Sessions",description:"Sessions, context, analytics"},{name:"Profiles & Automation",description:"Profiles, cron jobs, kanban boards"},{name:"Config",description:"Config, env, skills, toolsets, memory"},{name:"Eikon",description:"Avatar studio & library"}],TAB_MAX=TABS.length-1,CHAT_TAB=0,SESSIONS_TAB=1,AUTOMATION_TAB=2,CONFIG_TAB=3,EIKON_TAB=4,SUB_TABS={[1]:["List","Context","Analytics","Journey"],[2]:["Kanban","Profiles","Cron"],[3]:["Config","Skills","Toolsets","Env","Memory"],[4]:["Library","Catalog","Studio"]},TAB_SLASH={chat:{tab:0,sub:0},sessions:{tab:1,sub:0},context:{tab:1,sub:1},analytics:{tab:1,sub:2},insights:{tab:1,sub:2},journey:{tab:1,sub:3},learning:{tab:1,sub:3},"memory-graph":{tab:1,sub:3},kanban:{tab:2,sub:0},automation:{tab:2,sub:0},profiles:{tab:2,sub:1},agents:{tab:2,sub:1},cron:{tab:2,sub:2},config:{tab:3,sub:0},skills:{tab:3,sub:1},toolsets:{tab:3,sub:2},env:{tab:3,sub:3},memory:{tab:3,sub:4},library:{tab:4,sub:0},catalog:{tab:4,sub:1},studio:{tab:4,sub:2}};var SessionsGroup=import_react69.memo((props)=>{let labels=SUB_TABS[SESSIONS_TAB];import_react69.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]);let hint="shift+\u2190/\u2192 sub";return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(SubTabBar,{tabs:labels,active:props.sub,onChange:props.setSub,hint}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[$jsx(Pane,{visible:props.sub===0,children:$jsx(Sessions,{focused:!!props.focused&&props.sub===0,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId})}),$jsx(Pane,{visible:props.sub===1,children:$jsx(Context,{focused:!!props.focused&&props.sub===1,messages:props.messages,sessionStart:props.sessionStart,info:props.info,usage:props.usage})}),$jsx(Pane,{visible:props.sub===2,children:$jsx(Analytics,{focused:!!props.focused&&props.sub===2})}),$jsx(Pane,{visible:props.sub===3,children:$jsx(Journey,{focused:!!props.focused&&props.sub===3})})]})]})}),Pane=({visible:visible2,children:children2})=>visible2?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react94=__toESM(require_react_production(),1);var import_react83=__toESM(require_react_production(),1);var acc=new Map;function record(ev,p){let id=p.subagent_id;if(!id)return;let now=Date.now()/1000;if(ev==="start"){acc.set(id,{subagent_id:id,parent_id:p.parent_id??null,depth:p.depth??0,goal:p.goal,model:p.model,started_at:now,tool_count:0,status:"running",trail:[]});return}let r=acc.get(id);if(!r)return;if(ev==="tool"&&p.tool_name){r.tool_count++,r.trail=[...r.trail??[],{name:p.tool_name,preview:p.tool_preview}].slice(-20);return}if(ev==="complete")r.status=p.status??"completed",r.finished_at=now,r.input_tokens=p.input_tokens,r.output_tokens=p.output_tokens,r.cost_usd=p.cost_usd}function trail(id){return acc.get(id)?.trail??[]}function flush(gw,sessionId){if(acc.size===0)return;let subagents=[...acc.values()];acc.clear();let label2=(subagents.filter((s)=>s.parent_id==null).slice(0,2).map((s)=>s.goal).join(" \xB7 ")||`${subagents.length} subagents`).slice(0,120),started=Math.min(...subagents.map((s)=>s.started_at));gw.request("spawn_tree.save",{session_id:sessionId,label:label2,started_at:started,finished_at:Date.now()/1000,subagents}).catch(()=>{})}var import_react72=__toESM(require_react_production(),1);var import_react70=__toESM(require_react_production(),1);var DialogSelect=(props)=>{let filterable=props.filterable??!0,[filter,setFilter]=import_react70.useState(""),[cursor,setCursor]=import_react70.useState(0),mode2=import_react70.useRef("kb"),moved=import_react70.useRef(!1),sb=import_react70.useRef(null),theme=useTheme().theme,opts=import_react70.useMemo(()=>props.options.map((o)=>({name:`${props.current==null?"":o.value===props.current?"\u25CF ":" "}${o.title}`,description:o.hint?[o.description,o.hint].filter(Boolean).join(" \u2014 "):o.description??"",value:o.value})),[props.current,props.options]),sel=props.current==null?0:Math.max(0,props.options.findIndex((o)=>o.value===props.current)),desc=props.options.some((o)=>!!o.description||!!o.hint),filtered=import_react70.useMemo(()=>{let lower=filter.toLowerCase();return props.options.filter((o)=>o.title.toLowerCase().includes(lower)||(o.description??"").toLowerCase().includes(lower))},[filter,props.options]),groups=import_react70.useMemo(()=>{let map=new Map;return filtered.forEach((o)=>{let cat=o.category??"",arr=map.get(cat)??[];arr.push(o),map.set(cat,arr)}),map},[filtered]),rowId=(i)=>`ds-row-${i}`,scrollTo=(i)=>sb.current?.scrollChildIntoView(rowId(i));import_react70.useEffect(()=>{if(cursor>=filtered.length)setCursor(Math.max(0,filtered.length-1))},[filtered.length,cursor]),import_react70.useEffect(()=>{if(!props.current){setCursor(0);return}let i=filtered.findIndex((o)=>o.value===props.current),n=Math.max(0,i);setCursor(n),scrollTo(n)},[props.current,filtered]),import_react70.useEffect(()=>{if(!moved.current)return;moved.current=!1;let item=filtered[cursor];if(item&&props.onMove)props.onMove(item)},[cursor,filtered,props.onMove]);let keys=useKeys();useKeyboard((key3)=>{if(!filterable)return;if(handleListKey(keys,key3,{count:filtered.length,setSel:(fn)=>{mode2.current="kb",moved.current=!0,setCursor(fn)},scrollTo,page:Math.max(1,(sb.current?.viewport.height??10)-1),onActivate:()=>{let item=filtered[cursor];if(item)props.onSelect(item)}}))return;if(props.onKey?.(key3))return});let idx=0,entries2=Array.from(groups.entries());if(!filterable)return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.title})}),$jsx("box",{height:1}),$jsx("select",{focused:!0,width:58,height:Math.min(16,Math.max(1,props.options.length*(desc?2:1))),options:opts,selectedIndex:sel,showDescription:desc,showScrollIndicator:props.options.length>8,backgroundColor:theme.backgroundPanel,focusedBackgroundColor:theme.backgroundPanel,textColor:theme.textMuted,focusedTextColor:theme.text,selectedBackgroundColor:theme.backgroundElement,selectedTextColor:theme.text,descriptionColor:theme.textMuted,selectedDescriptionColor:theme.textMuted,fastScrollStep:Math.max(1,props.options.length),keyBindings:[{name:"home",action:"move-up-fast"},{name:"end",action:"move-down-fast"},{name:"pageup",action:"move-up-fast"},{name:"pagedown",action:"move-down-fast"},{name:"space",action:"select-current"},{name:" ",action:"select-current"}],onChange:(i)=>{let item=props.options[i];if(item&&props.onMove)props.onMove(item)},onSelect:(i)=>{let item=props.options[i];if(item)props.onSelect(item)}}),props.footer!=null?$jsx("box",{paddingTop:1,children:props.footer}):null]});return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.title})}),$jsx("box",{height:1}),filterable?$jsxs($Fragment,{children:[$jsx("input",{value:filter,onInput:(v2)=>{mode2.current="kb",setFilter(v2)},placeholder:props.placeholder??"Type to filter...",focused:!0,textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}),$jsx("box",{height:1})]}):null,$jsxs("scrollbox",{ref:sb,scrollY:!0,maxHeight:16,focused:!filterable,contentOptions:{flexDirection:"column"},paddingRight:1,children:[filtered.length===0?$jsx("text",{fg:theme.textMuted,children:"No results found"}):null,entries2.map(([cat,items])=>{let elements=[];if(cat)elements.push($jsx("text",{fg:theme.textMuted,children:$jsx("strong",{children:cat})},`cat-${cat}`));return items.forEach((item)=>{let i=idx++,active2=i===cursor,current=item.value===props.current;elements.push($jsxs("box",{id:rowId(i),flexDirection:"row",backgroundColor:active2?theme.backgroundElement:void 0,onMouseMove:()=>{mode2.current="mouse",moved.current=!0,setCursor((c)=>c===i?c:i)},onMouseOver:()=>{if(mode2.current==="mouse")moved.current=!0,setCursor(i)},onMouseDown:()=>props.onSelect(item),paddingLeft:1,paddingRight:1,children:[$jsx("box",{flexGrow:1,height:1,overflow:"hidden",children:$jsxs("text",{fg:active2?theme.text:theme.textMuted,children:[current?"\u25CF ":" ",item.title,item.description?` \u2014 ${item.description}`:""]})}),item.hint?$jsx("box",{flexShrink:0,height:1,children:$jsx("text",{fg:theme.textMuted,children:item.hint})}):null]},item.value))}),elements}).flat()]}),props.footer!=null?$jsx("box",{paddingTop:1,children:props.footer}):null]})};var Ctx6=import_react72.createContext(null),CommandProvider=({children:children2})=>{let registry=import_react72.useRef(new Map),enabled2=import_react72.useRef(!0),dialog=useDialog(),keys=useKeys(),all=import_react72.useCallback(()=>{let out=[];return registry.current.forEach((cmds)=>cmds.forEach((c)=>out.push(c))),out},[]),register=import_react72.useCallback((cmds)=>{let id=String(Date.now())+Math.random();return registry.current.set(id,cmds),()=>{registry.current.delete(id)}},[]),setEnabled=import_react72.useCallback((val)=>{enabled2.current=val},[]),open2=import_react72.useCallback(()=>{let cmds=all(),options=cmds.map((c)=>({title:c.title,value:c.value,description:c.description,hint:c.action?keys.print(c.action):void 0,category:c.category}));dialog.replace($jsx(DialogSelect,{title:"Command Palette",options,onSelect:(opt)=>{dialog.clear();let found=cmds.find((c)=>c.value===opt.value);if(found)found.onSelect()},placeholder:"Search commands..."}))},[all,dialog,keys]);useKeyboard((key3)=>{if(!enabled2.current||dialog.open())return;if(keys.match("palette.open",key3))return open2();for(let c of all())if(c.action&&keys.match(c.action,key3))return c.onSelect()});let value=import_react72.useMemo(()=>({register,setEnabled}),[register,setEnabled]);return $jsx(Ctx6.Provider,{value,children:children2})},useCommand=makeUse(Ctx6,"useCommand");var import_react74=__toESM(require_react_production(),1);function openAlert(dialog,title,body){dialog.replace($jsx(Alert,{title,body,onClose:()=>dialog.clear()}))}var Alert=(props)=>{let theme=useTheme().theme,keys=useKeys(),[copied2,setCopied]=import_react74.useState(!1),doCopy=()=>{copy2(props.body),setCopied(!0),setTimeout(()=>setCopied(!1),900)};return useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.accept",key3))props.onClose();if(keys.match("dialog.copy",key3))doCopy()}),$jsxs("box",{flexDirection:"column",width:84,maxHeight:28,border:["left"],borderColor:theme.info,customBorderChars:LEFT_BAR,backgroundColor:theme.backgroundPanel,paddingLeft:2,paddingRight:2,paddingY:1,gap:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.info,children:"\u25C8 "}),$jsx("span",{fg:theme.text,children:props.title})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:props.body})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:`${keys.print("dialog.cancel")} close \xB7 ${keys.print("dialog.copy")} `})}),$jsx("box",{flexShrink:0,onMouseDown:(e)=>{e.stopPropagation(),doCopy()},children:$jsx("text",{fg:copied2?theme.success:theme.textMuted,children:$jsx("u",{children:copied2?"copied":"copy"})})})]})]})};var Status=({s})=>{let theme=useTheme().theme,fg2=s==="completed"?theme.success:s==="failed"?theme.error:s==="error"?theme.error:s==="timeout"?theme.error:s==="interrupted"?theme.warning:theme.textMuted;return $jsx("span",{fg:fg2,children:s})},SnapshotView=(props)=>{let theme=useTheme().theme,subs2=props.snap.subagents??[],tok=subs2.reduce((n,s)=>n+(s.input_tokens??0)+(s.output_tokens??0),0),span2=props.snap.started_at&&props.snap.finished_at?dur2(props.snap.finished_at-props.snap.started_at):"\u2014";return $jsxs("box",{flexDirection:"column",width:80,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.entry.label||`${subs2.length} subagents`})}),$jsxs("text",{fg:theme.textMuted,children:[when(props.entry.finished_at)," \xB7 ",span2," \xB7 ",subs2.length," agents \xB7 ",fmt(tok)," tok"]}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,maxHeight:20,contentOptions:{flexDirection:"column"},children:subs2.map((s)=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "+"\xB7 ".repeat(s.depth)}),$jsx("span",{fg:theme.text,children:trunc5(s.goal.replace(/\s+/g," "),60)})]})}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["\u2503 "+" ".repeat(2*s.depth+2),$jsx(Status,{s:s.status}),` \xB7 ${s.tool_count}t`,s.finished_at?` \xB7 ${dur2(s.finished_at-s.started_at)}`:"",s.model?` \xB7 ${s.model}`:""]})})]},s.subagent_id))})]})};function openSpawnHistory(dialog,gw,sessionId){dialog.replace($jsx("box",{width:40,height:3,children:$jsx("text",{children:"Loading spawn history\u2026"})}));let listToken=dialog.version();gw.request("spawn_tree.list",{session_id:sessionId,limit:50}).then((r)=>{if(dialog.version()!==listToken)return;let entries2=r.entries??[];dialog.replace($jsx(DialogSelect,{title:"Spawn history",placeholder:entries2.length?"filter\u2026":"no saved spawn trees",options:entries2.map((e)=>({value:e.path,title:`${e.count.toString().padStart(2)}\xD7 ${trunc5(e.label||"(unlabeled)",40)}`,description:when(e.finished_at),category:e.session_id===sessionId?"This session":e.session_id})),onSelect:(opt)=>{let entry2=entries2.find((e)=>e.path===opt.value);dialog.replace($jsx("box",{width:40,height:3,children:$jsx("text",{children:"Loading spawn tree\u2026"})}));let token=dialog.version();gw.request("spawn_tree.load",{path:entry2.path}).then((snap2)=>{if(dialog.version()===token)dialog.replace($jsx(SnapshotView,{entry:entry2,snap:snap2}))}).catch((e)=>{if(dialog.version()===token)openAlert(dialog,"Spawn history",e instanceof Error?e.message:String(e))})}}))}).catch((e)=>{if(dialog.version()===listToken)openAlert(dialog,"Spawn history",e instanceof Error?e.message:String(e))})}var import_react77=__toESM(require_react_production(),1);var Dialog=(props)=>{let theme=useTheme().theme,keys=useKeys();useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.accept",key3))return props.onClose()});let d2=props.d,req=d2.env_requires.filter((e)=>e.required),opt=d2.env_requires.filter((e)=>!e.required),link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs("box",{flexDirection:"column",minWidth:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:`Distribution \xB7 ${props.profile}`})})}),$jsxs("box",{flexDirection:"column",children:[$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0],["Author",d2.author||void 0],["License",d2.license||void 0],["Description",d2.description||void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed",Number.isFinite(when2)?ago(when2/1000):void 0],["Owned",d2.distribution_owned.length?d2.distribution_owned.join(", "):void 0]]})]}),d2.env_requires.length?$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Environment variables"})})}),req.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Required"})}),req.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null,opt.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Optional"})}),opt.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null]}):null,$jsx("box",{height:1,children:$jsx("text",{fg:theme.borderSubtle,children:`[${keys.print("dialog.cancel")}] close`})})]})},EnvRow=(props)=>{let theme=useTheme().theme,tail=[props.desc,props.fallback?`default: ${props.fallback}`:""].filter(Boolean).join(" \xB7 ");return $jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:2,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:" "})}),$jsx("box",{width:22,flexShrink:0,children:$jsx("text",{fg:theme.accent,children:props.name})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:tail})})]})};function openDistributionInfo(dialog,opts){dialog.replace($jsx(Dialog,{profile:opts.profile,d:opts.d,yaml:opts.yaml,onClose:()=>dialog.clear()}))}function openProfileMenu(dialog,p,ops){let opts=[...ops.switch&&!p.is_active?[{category:"Switch",value:"switch",title:`Switch to '${p.name}'`,description:"restart gateway under this HERMES_HOME \u2014 ends current session"}]:[],{category:"Open",value:"soul",title:"SOUL.md",description:"edit persona/system prompt"},{category:"Open",value:"config",title:"config.yaml",description:"model, provider, toolsets"},...p.has_env?[{category:"Open",value:"env",title:".env",description:"API keys + secrets"}]:[],{category:"Open",value:"dir",title:"Directory",description:p.path},...p.distribution?[{category:"Distribution",value:"dist-info",title:"Info",description:`v${p.distribution.version}${p.distribution.source?` \xB7 ${p.distribution.source}`:""}`},{category:"Distribution",value:"dist-update",title:"Update",description:`hermes profile update ${p.name}${p.is_active?" \xB7 ends current session":""}`}]:[],...p.is_sticky?[{category:"Default",value:"unsticky",title:"Clear sticky default",description:"hermes profile use --clear"}]:[{category:"Default",value:"sticky",title:"Set as sticky default",description:`hermes profile use ${p.name}`}],{category:"Manage",value:"export",title:"Export",description:`hermes profile export ${p.name}`},...p.is_default||p.is_active?[]:[{category:"Manage",value:"delete",title:"Delete",description:"irreversible \u2014 removes config, env, memory, sessions"}]];dialog.replace($jsx(DialogSelect,{title:`Profile \xB7 ${p.name}${p.is_active?" (active)":""}`,options:opts,onSelect:(o)=>{if(o.value==="dist-info"){if(!p.distribution)return dialog.clear();return openDistributionInfo(dialog,{profile:p.name,d:p.distribution,yaml:p.sources.distribution})}if(o.value==="dist-update"){if(!p.distribution)return dialog.clear();return openUpdateDistribution(dialog,p,(force)=>ops.update(p,force))}if(dialog.clear(),o.value==="switch")return ops.switch?.();if(o.value==="soul")return openFile(p.sources.soul.file);if(o.value==="config")return openFile(p.sources.config.file);if(o.value==="env")return openFile(p.sources.env.file);if(o.value==="dir")return openFile(p.path);if(o.value==="sticky")return ops.sticky(p);if(o.value==="unsticky")return ops.unsticky();if(o.value==="export")return ops.export(p);if(o.value==="delete")return ops.remove(p)}}))}var UpdateForm=(props)=>{let theme=useTheme().theme,keys=useKeys(),[force,setForce]=import_react77.useState(!1);useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.deny",key3))return props.done(null);if(keys.match("dialog.confirm",key3)||keys.match("dialog.accept",key3))return props.done(force);if(key3.name==="space"||key3.name===" ")return setForce((f)=>!f)});let d2=props.p.distribution;return $jsxs("box",{flexDirection:"column",width:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:"Update distribution?"})})}),$jsxs("box",{flexDirection:"column",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:`'${props.p.name}' \xB7 v${d2.version}${d2.source?` \xB7 ${d2.source}`:""}`})}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:"Re-pulls from source; distribution-owned files are overwritten."})}),props.p.is_active?$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.warning,children:"\u26A0 This is the active profile. The gateway will re-spawn "+"and the current session will end."})}):null]}),$jsx("box",{height:1,children:$jsx("text",{fg:force?theme.warning:theme.textMuted,children:`${force?"[x]":"[ ]"} --force-config \xB7 also overwrite config.yaml`})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`[${keys.print("dialog.confirm")}] update [Space] toggle force [${keys.print("dialog.cancel")}] cancel`})})]})};function openUpdateDistribution(dialog,p,onConfirm){dialog.replace($jsx(UpdateForm,{p,done:(force)=>{if(dialog.clear(),force!==null)onConfirm(force)}}))}var import_react79=__toESM(require_react_production(),1);import{existsSync as existsSync18,readFileSync as readFileSync11}from"fs";import{readdir as readdir2}from"fs/promises";import{homedir as homedir7}from"os";import{join as join13,basename as basename9,dirname as dirname8}from"path";import{Database as Database2}from"bun:sqlite";var home4=()=>process.env.HOME||homedir7(),hermesHome=()=>process.env.HERMES_HOME||join13(home4(),".hermes");function root2(){let hh=hermesHome(),parent2=dirname8(hh);return basename9(parent2)==="profiles"?dirname8(parent2):hh}function profileNameFrom(hh){let parent2=dirname8(hh);return basename9(parent2)==="profiles"?basename9(hh):"default"}function activeProfileName(){return profileNameFrom(hermesHome())}function stickyDefault(){try{return readFileSync11(join13(root2(),"active_profile"),"utf-8").trim()||null}catch{return null}}var ID_RE=/^[a-z0-9][a-z0-9_-]{0,63}$/;function resolveProfileHome(name){if(name==="default")return root2();if(!ID_RE.test(name))return null;let dir=join13(root2(),"profiles",name);return existsSync18(dir)?dir:null}function readModel(dir){try{let raw=readFileSync11(join13(dir,"config.yaml"),"utf-8"),block=raw.split(/^model:\s*$/m)[1]?.split(/^\S/m)[0]??"",m2=block.match(/^\s+(?:default|model):\s*(.+)$/m)?.[1]?.trim()??raw.match(/^model:\s*(\S.+)$/m)?.[1]?.trim(),p=block.match(/^\s+provider:\s*(.+)$/m)?.[1]?.trim(),clean4=(s)=>s?.replace(/^["']|["']$/g,"")??null;return[clean4(m2),clean4(p)]}catch{return[null,null]}}async function countSkills(dir){let glob=new Bun.Glob("**/SKILL.md"),n=0;try{for await(let _2 of glob.scan({cwd:join13(dir,"skills"),onlyFiles:!0}))n++}catch{}return n}function gatewayRunning(dir){try{let raw=readFileSync11(join13(dir,"gateway.pid"),"utf-8").trim(),pid2=raw.startsWith("{")?Number(JSON.parse(raw).pid):Number(raw);if(!Number.isFinite(pid2)||pid2<=0)return!1;return process.kill(pid2,0),!0}catch{return!1}}function soul(dir){try{return readFileSync11(join13(dir,"SOUL.md"),"utf-8").replace(/^#[^\n]*\n+/,"").replace(/^\s+/,"").slice(0,400)}catch{return""}}function readDistributionManifest(dir){let path4=join13(dir,"distribution.yaml");if(!existsSync18(path4))return null;let data2=(()=>{try{return $parse(readFileSync11(path4,"utf-8"))}catch{return null}})();if(!data2||typeof data2!=="object"||Array.isArray(data2))return null;let d2=data2,name=typeof d2.name==="string"?d2.name.trim():"";if(!name)return null;let envs=(Array.isArray(d2.env_requires)?d2.env_requires:[]).flatMap((e)=>{if(!e||typeof e!=="object")return[];let r=e,n=typeof r.name==="string"?r.name.trim():"";if(!n)return[];return[{name:n,description:typeof r.description==="string"?r.description:"",required:r.required===void 0?!0:Boolean(r.required),default:typeof r.default==="string"?r.default:null}]}),owned=(Array.isArray(d2.distribution_owned)?d2.distribution_owned:[]).map((p)=>typeof p==="string"?p.trim().replace(/\/+$/,""):"").filter((p)=>p.length>0);return{name,version:typeof d2.version==="string"?d2.version:"0.1.0",description:typeof d2.description==="string"?d2.description:"",hermes_requires:typeof d2.hermes_requires==="string"?d2.hermes_requires:"",author:typeof d2.author==="string"?d2.author:"",license:typeof d2.license==="string"?d2.license:"",env_requires:envs,distribution_owned:owned,source:typeof d2.source==="string"?d2.source:"",installed_at:typeof d2.installed_at==="string"?d2.installed_at:""}}var src2=(file,label2)=>({file,relative:file.replace(home4()+"/","~/"),label:label2});async function info(name,dir,active2,sticky){let[model,provider]=readModel(dir),alias=join13(home4(),".local","bin",name);return{name,path:dir,is_default:name==="default",is_active:name===active2,is_sticky:name===sticky,gateway_running:gatewayRunning(dir),model,provider,has_env:existsSync18(join13(dir,".env")),skill_count:await countSkills(dir),has_alias:name!=="default"&&existsSync18(alias),soul_preview:soul(dir),distribution:readDistributionManifest(dir),sources:{dir:src2(dir,dir.replace(home4()+"/","~/")),config:src2(join13(dir,"config.yaml"),"config.yaml"),soul:src2(join13(dir,"SOUL.md"),"SOUL.md"),env:src2(join13(dir,".env"),".env"),distribution:src2(join13(dir,"distribution.yaml"),"distribution.yaml")}}}async function listProfiles(activeHome){let r=root2(),active2=profileNameFrom(activeHome??hermesHome()),sticky=stickyDefault(),jobs=[];if(existsSync18(r))jobs.push(info("default",r,active2,sticky));let pr=join13(r,"profiles");if(existsSync18(pr))for(let e of await readdir2(pr,{withFileTypes:!0})){if(!e.isDirectory()||!ID_RE.test(e.name))continue;jobs.push(info(e.name,join13(pr,e.name),active2,sticky))}return Promise.all(jobs)}function validateName(name,existing){if(!ID_RE.test(name))return"must match [a-z0-9][a-z0-9_-]{0,63}";if(existing.includes(name))return"already exists";if(["hermes","default","test","tmp","root","sudo"].includes(name))return"reserved name";return null}function readPrefs(dir){try{let raw=JSON.parse(readFileSync11(join13(dir,"herm","tui.json"),"utf-8"));return{theme:raw.theme,eikon:raw.eikon??(raw.eikonPath?basename9(raw.eikonPath,".eikon"):void 0),keys:raw.keys?Object.keys(raw.keys).length:0}}catch{return null}}async function profileStats(dir){let sessions=null,messages=null,dbPath=join13(dir,"state.db");if(existsSync18(dbPath))try{let db=new Database2(dbPath,{readwrite:!0,create:!1}),r=db.query("SELECT COUNT(*) AS s FROM sessions WHERE message_count > 0").get(),m2=db.query("SELECT COALESCE(SUM(message_count), 0) AS m FROM sessions").get();sessions=r.s,messages=m2.m,db.close()}catch{}let crons=null;try{let jobs=await Bun.file(join13(dir,"cron","jobs.json")).json();crons=Array.isArray(jobs)?jobs.length:jobs&&typeof jobs==="object"&&Array.isArray(jobs.jobs)?jobs.jobs.length:0}catch{crons=existsSync18(join13(dir,"cron"))?0:null}return{sessions,messages,crons,prefs:readPrefs(dir)}}var ORDER3=["name","clone","alias"];function openCreateProfile(dialog,opts){return new Promise((resolve4)=>{let done=(r)=>{dialog.clear(),resolve4(r)};dialog.replace($jsx(Form,{existing:opts.existing,done}))})}var Form=({existing,done})=>{let theme=useTheme().theme,[name,setName]=import_react79.useState(""),[cloneIdx,setCloneIdx]=import_react79.useState(0),[alias,setAlias]=import_react79.useState(!0),[field,setField]=import_react79.useState("name"),options=["(fresh)",...existing],err=name?validateName(name,existing):null,valid=!!name&&!err,submit2=()=>{if(!valid)return;done({name,cloneFrom:cloneIdx===0?null:options[cloneIdx],alias})},moveField=(dir)=>{let i=ORDER3.indexOf(field);setField(ORDER3[(i+dir+ORDER3.length)%ORDER3.length])};useKeyboard((key3)=>{if(key3.name==="escape")return done(null);if(key3.name==="tab")return moveField(key3.shift?-1:1);if(key3.name==="return")return submit2();if(field==="name"){if(key3.name==="backspace")return setName((n)=>n.slice(0,-1));if(key3.raw&&key3.raw.length===1&&/[a-z0-9_-]/.test(key3.raw))return setName((n)=>n+key3.raw);return}if(field==="clone"){if(key3.name==="up")return setCloneIdx((i)=>Math.max(0,i-1));if(key3.name==="down")return setCloneIdx((i)=>Math.min(options.length-1,i+1));return}if(field==="alias"){if(key3.name==="space"||key3.name===" ")return setAlias((a)=>!a)}});let focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"New Profile"})})}),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name"})}),$jsxs("text",{children:[$jsx("span",{fg:valid||!name?theme.text:theme.error,children:name}),field==="name"?$jsx("span",{fg:theme.accent,children:"\u2588"}):null]})]}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:" a-z 0-9 _ - \xB7 lowercase"})}),$jsx("box",{height:1}),$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsx("text",{fg:theme.textMuted,children:"Clone from (\u2191\u2193)"})}),options.map((o,i)=>$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsxs("text",{fg:i===cloneIdx?theme.accent:theme.text,children:[i===cloneIdx?"\u25B8 ":" ",o]})},o)),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] shell alias":"[ ] shell alias"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:valid?"Enter create \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel":err??"type a name"})})]})};var import_react81=__toESM(require_react_production(),1);import{rmSync as rmSync3,mkdtempSync as mkdtempSync4}from"fs";import{join as join14}from"path";import{tmpdir as tmpdir4}from"os";var shq=(s)=>`'${s.replace(/'/g,"'\\''")}'`;function openInstallDistribution(dialog,gw){return new Promise((resolve4)=>{askSource(dialog,gw,(r)=>{dialog.clear(),resolve4(r)})})}function askSource(dialog,gw,done){dialog.replace($jsx(Step1,{onSubmit:(source)=>preview(dialog,gw,source,done),onCancel:()=>done(null)}))}async function preview(dialog,gw,source,done){let tmp=mkdtempSync4(join14(tmpdir4(),"herm-dist-preview-")),cleanup=()=>{try{rmSync3(tmp,{recursive:!0,force:!0})}catch{}},state2={cancelled:!1},cancel=()=>{state2.cancelled=!0,cleanup(),done(null)};dialog.replace($jsx(Loading2,{label:`Cloning ${source}\u2026`,onCancel:cancel}),void 0,{ownCancel:!0});let cmd=`git clone --depth 1 --quiet ${shq(source)} ${shq(tmp)} 2>&1`,r=await gw.request("shell.exec",{command:cmd}).catch((e)=>({stdout:"",stderr:e.message,code:-1}));if(state2.cancelled)return;if(r.code!==0){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Clone failed",body:(r.stderr||r.stdout||`exit ${r.code}`).trim(),onClose:()=>done(null)}));return}let manifest3=readDistributionManifest(tmp);if(!manifest3){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Not a distribution",body:`No valid distribution.yaml at the root of ${source}. A manifest must declare at minimum a 'name:' key.`,onClose:()=>done(null)}));return}dialog.replace($jsx(ConfirmStep,{source,manifest:manifest3,onConfirm:(r2)=>{cleanup(),done(r2)},onCancel:()=>{cleanup(),done(null)}}),void 0,{ownCancel:!0})}var Step1=(p)=>{let theme=useTheme().theme,[value,setValue]=import_react81.useState("");return useKeyboard((key3)=>{if(key3.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:64,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Source \u2014 git URL, github.com/owner/repo, or local directory"})}),$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,onInput:setValue,onSubmit:()=>{let v2=value.trim();if(v2)p.onSubmit(v2)},focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement})})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:value.trim()?"Enter preview \xB7 Esc cancel":"Esc cancel"})})]})},Loading2=(p)=>{let theme=useTheme().theme;return useKeyboard((key3)=>{if(key3.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx(Spinner,{color:theme.accent,label:p.label})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Esc to cancel"})})]})},ErrorBox=(p)=>{let theme=useTheme().theme,keys=useKeys();return useKeyboard((key3)=>{if(keys.match("dialog.accept",key3)||keys.match("dialog.cancel",key3))return p.onClose()}),$jsxs("box",{flexDirection:"column",width:68,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:$jsx("strong",{children:p.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.text,children:p.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter / Esc to close"})})]})},ORDER4=["name","alias"],ConfirmStep=(p)=>{let theme=useTheme().theme,keys=useKeys(),[name,setName]=import_react81.useState(""),[alias,setAlias]=import_react81.useState(!1),[field,setField]=import_react81.useState("name"),fire=()=>p.onConfirm({source:p.source,manifest:p.manifest,name:name.trim()||null,alias}),move=(dir)=>{let i=ORDER4.indexOf(field);setField(ORDER4[(i+dir+ORDER4.length)%ORDER4.length])};useKeyboard((key3)=>{if(key3.name==="escape")return p.onCancel();if(key3.name==="tab")return move(key3.shift?-1:1);if(field!=="name"&&keys.match("dialog.accept",key3))return fire();if(field==="alias"&&(key3.name==="space"||key3.name===" "))return setAlias((a)=>!a)});let m2=p.manifest,reqEnv=m2.env_requires.filter((e)=>e.required),optEnv=m2.env_requires.filter((e)=>!e.required),focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:72,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx(KV2,{label:"Name",value:`${m2.name}${m2.version?` v${m2.version}`:""}`,theme}),m2.description?$jsx(KV2,{label:"About",value:m2.description,theme,wrap:!0}):null,m2.author?$jsx(KV2,{label:"Author",value:m2.author,theme}):null,m2.license?$jsx(KV2,{label:"License",value:m2.license,theme}):null,m2.hermes_requires?$jsx(KV2,{label:"Requires",value:`hermes ${m2.hermes_requires}`,theme}):null,$jsx(KV2,{label:"Source",value:p.source,theme}),m2.distribution_owned.length>0?$jsx(KV2,{label:"Owns",value:m2.distribution_owned.join(", "),theme,wrap:!0}):null,m2.env_requires.length>0?$jsx(KV2,{label:"Env",value:envSummary(reqEnv,optEnv),theme}):null,$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name as"})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:field==="name"?$jsx("input",{value:name,onInput:setName,onSubmit:fire,focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}):$jsx("text",{fg:name?theme.text:theme.textMuted,children:name||`(${m2.name})`})})]}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] create shell wrapper":"[ ] create shell wrapper"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter install \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel"})})]})},KV2=(p)=>$jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:11,flexShrink:0,children:$jsx("text",{fg:p.theme.textMuted,children:p.label})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:p.theme.text,wrapMode:p.wrap?"word":"none",children:p.value})})]});function envSummary(req,opt){return[req.length>0?`${req.length} required (${req.map((e)=>e.name).join(", ")})`:"",opt.length>0?`${opt.length} optional`:""].filter(Boolean).join(" \xB7 ")}var running=(s)=>!s||s==="running"||s==="queued";function tree(recs,live,now){let ids=new Set(recs.map((r)=>r.subagent_id)),by=new Map;for(let r of recs){let k2=r.parent_id&&ids.has(r.parent_id)?r.parent_id:"";(by.get(k2)??by.set(k2,[]).get(k2)).push(r)}let build2=(r)=>{let kids=(by.get(r.subagent_id)??[]).map(build2),lv=live.get(r.subagent_id)??{},dur3=r.started_at!=null?Math.max(0,now-r.started_at):0,a={agents:1,tools:lv.tool_count??r.tool_count??0,dur:dur3,tok:(lv.input_tokens??0)+(lv.output_tokens??0),cost:lv.cost_usd??0,active:running(lv.status??r.status)?1:0,depth:0,hot:0};for(let k2 of kids)a={agents:a.agents+k2.agg.agents,tools:a.tools+k2.agg.tools,dur:a.dur+k2.agg.dur,tok:a.tok+k2.agg.tok,cost:a.cost+k2.agg.cost,active:a.active+k2.agg.active,depth:Math.max(a.depth,k2.agg.depth+1),hot:0};return a.hot=a.dur>0?a.tools/a.dur:0,{rec:r,agg:a,kids}};return(by.get("")??[]).map(build2)}function totals(nodes){let z2={agents:0,tools:0,dur:0,tok:0,cost:0,active:0,depth:0,hot:0};for(let n of nodes)z2.agents+=n.agg.agents,z2.tools+=n.agg.tools,z2.dur+=n.agg.dur,z2.tok+=n.agg.tok,z2.cost+=n.agg.cost,z2.active+=n.agg.active,z2.depth=Math.max(z2.depth,n.agg.depth+1);return z2.hot=z2.dur>0?z2.tools/z2.dur:0,z2}var SPARK=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function spark(nodes){let w2=[],walk2=(ns,d2)=>{if(ns.length===0)return;w2[d2]=(w2[d2]??0)+ns.length;for(let n of ns)walk2(n.kids,d2+1)};if(walk2(nodes,0),w2.length===0)return"";let max=Math.max(...w2);return w2.map((v2)=>v2<=0?" ":SPARK[Math.min(7,Math.ceil(v2/max*7))]).join("")}var tk=(n)=>n<1000?String(Math.round(n)):n<1e4?`${(n/1000).toFixed(1)}k`:`${Math.round(n/1000)}k`,$$=(n)=>n<=0?"":n<0.01?"<$0.01":n<10?`$${n.toFixed(2)}`:`$${n.toFixed(1)}`,sec=(s)=>{if(s<60)return`${Math.round(s)}s`;let m2=Math.floor(s/60),r=Math.round(s-m2*60);return r===0?`${m2}m`:`${m2}m${r}s`};function summary(a){let p=[`d${a.depth}`,`${a.agents} agent${a.agents===1?"":"s"}`];if(a.tools>0)p.push(`${a.tools} tools`);if(a.dur>0)p.push(sec(a.dur));if(a.tok>0)p.push(`${tk(a.tok)} tok`);if(a.cost>0)p.push($$(a.cost));if(a.active>0)p.push(`\u26A1${a.active}`);return p.join(" \xB7 ")}function heat(hot,peak,buckets){if(hot<=0||peak<=0||buckets<=1)return 0;return Math.min(buckets-1,Math.round(Math.min(1,hot/peak)*(buckets-1)))}function peak(nodes){let p=0,walk2=(ns)=>{for(let n of ns)p=Math.max(p,n.agg.hot),walk2(n.kids)};return walk2(nodes),p}var ProfileRow=import_react83.memo((props)=>{let theme=useTheme().theme,{p,idx:i}=props,[x2,setX]=import_react83.useState(!1);return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),onMouseDown:()=>props.onEnter(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:p.is_active?theme.accent:theme.text,children:p.is_active?$jsx("strong",{children:p.name}):p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605"}):null,p.distribution?$jsx("span",{fg:theme.info,children:" \u2B22"}):null,p.gateway_running?$jsx("span",{fg:theme.success,children:" \u25CF"}):null]})}),$jsx("box",{width:4,height:1,children:$jsx("text",{fg:theme.textMuted,children:p.is_active?" you":""})}),p.is_default||p.is_active?$jsx("box",{width:3}):$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onDelete(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})}),DistBlock=import_react83.memo((props)=>{let theme=useTheme().theme,d2=props.d,req=d2.env_requires.filter((e)=>e.required).length,opt=d2.env_requires.length-req,link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Distribution"})})}),$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed at",Number.isFinite(when2)?ago(when2/1000):void 0],["Env vars",d2.env_requires.length?`${req} required, ${opt} optional`:void 0]]})]})}),ProfileDetail=import_react83.memo((props)=>{let{theme,syntaxStyle}=useTheme(),p=props.p,s=props.stats;return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{height:1,children:$jsxs("text",{fg:theme.accent,children:[$jsx("strong",{children:p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605 sticky default"}):null]})}),$jsx("box",{height:1}),$jsx(KVLink,{label:"Path",source:p.sources.dir,text:p.sources.dir.relative}),$jsx(KV,{label:"Active",value:p.is_active?"yes (this session)":"no",fg:p.is_active?theme.accent:theme.textMuted}),$jsx(KV,{label:"Model",value:p.model??"\u2014"}),$jsx(KV,{label:"Provider",value:p.provider??"\u2014"}),$jsx(KV,{label:"Skills",value:String(p.skill_count)}),$jsx(KV,{label:"Sessions",value:s?s.sessions==null?"\u2014":`${fmt(s.sessions)} (${fmt(s.messages??0)} msgs)`:"\u2026"}),$jsx(KV,{label:"Cron jobs",value:s?s.crons==null?"\u2014":String(s.crons):"\u2026"}),$jsx(KV,{label:"Theme",value:s?s.prefs?.theme??"\u2014":"\u2026"}),$jsx(KV,{label:"Avatar",value:s?s.prefs?.eikon??"\u2014":"\u2026"}),s?.prefs?.keys?$jsx(KV,{label:"Keybinds",value:`${s.prefs.keys} overrides`}):null,$jsx(KV,{label:"Gateway",value:p.gateway_running?"running":"stopped",fg:p.gateway_running?theme.success:theme.textMuted}),p.has_alias?$jsx(KV,{label:"Alias",value:`${p.name} (shell)`}):null,p.distribution?$jsx(DistBlock,{d:p.distribution,yaml:p.sources.distribution}):null,$jsx("box",{height:1}),$jsx(KVLink,{label:"Config",source:p.sources.config}),$jsx(KVLink,{label:"Soul",source:p.sources.soul}),p.has_env?$jsx(KVLink,{label:"Env",source:p.sources.env}):$jsx(KV,{label:"Env",value:"\u2014"}),p.soul_preview?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"SOUL.md"})}),$jsx("markdown",{content:p.soul_preview,fg:theme.markdownText,syntaxStyle})]}):null]})})}),HOT=["\u2800","\u2801","\u2803","\u2807","\u280F","\u281F","\u283F","\u287F","\u28FF"],DelegRow=import_react83.memo((props)=>{let theme=useTheme().theme,{r,idx:i,now}=props,[x2,setX]=import_react83.useState(!1),up=r.started_at?dur2(now-r.started_at):"\u2014",hotFg=[theme.textMuted,theme.textMuted,theme.text,theme.info,theme.info,theme.accent,theme.accent,theme.warning,theme.error][props.hot]??theme.textMuted;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{width:2,children:$jsxs("text",{fg:hotFg,children:[HOT[props.hot]," "]})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\xB7 ".repeat(r.depth)}),$jsx("span",{fg:theme.text,children:r.goal.replace(/\s+/g," ")})]})}),$jsx("box",{width:14,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:trunc5(r.model??"",13)})}),$jsx("box",{width:5,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:String(r.tool_count??0)})}),$jsx("box",{width:8,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:up})}),$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onKill(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})});function preorder(recs){let byParent=new Map;for(let r of recs){let k2=r.parent_id??null;(byParent.get(k2)??byParent.set(k2,[]).get(k2)).push(r)}let out=[],seen=new Set,walk2=(k2)=>{for(let r of byParent.get(k2)??[]){if(seen.has(r.subagent_id))continue;seen.add(r.subagent_id),out.push(r),walk2(r.subagent_id)}};walk2(null);for(let r of recs)if(!seen.has(r.subagent_id))out.push(r);return out}var DelegDetail=import_react83.memo((props)=>{let theme=useTheme().theme,{r,live,agg,now}=props,tc=live?.tool_count??r.tool_count??0,tr=trail(r.subagent_id);return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.accent,wrapMode:"word",children:$jsx("strong",{children:r.goal})})}),agg&&agg.agents>1?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:summary(agg)})}):null,$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Status",live?.status??r.status??"running"],["Model",r.model??"\u2014"],["Depth",String(r.depth)],["Parent",r.parent_id??"(root)"],["Uptime",r.started_at?dur2(now-r.started_at):"\u2014"],["Tools",String(tc)],["Tokens",live?`${fmt(live.input_tokens??0)} in / ${fmt(live.output_tokens??0)} out`:void 0],["Cost",live?.cost_usd!=null?`$${live.cost_usd.toFixed(4)}`:void 0]]}),live?.thinking?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"thinking"})}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:trunc5(live.thinking,200)})})]}):null,tr.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"recent tools"})}),tr.slice(-8).map((t2,i)=>$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "}),$jsx("span",{fg:theme.text,children:t2.name.padEnd(14)}),$jsx("span",{fg:theme.textMuted,children:t2.preview?trunc5(t2.preview.replace(/\s+/g," "),40):""})]})},i))]}):null]})})}),Agents=import_react83.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),cmd=useCommand(),[pane,setPane]=import_react83.useState("profiles"),[pView,setPView]=import_react83.useState("list"),[profiles,setProfiles]=import_react83.useState([]),[deleg,setDeleg]=import_react83.useState(null),[liveMap,setLiveMap]=import_react83.useState(()=>new Map),[now,setNow]=import_react83.useState(()=>Date.now()/1000),[pSel,setPSel]=import_react83.useState(0),[dSel,setDSel]=import_react83.useState(0),[err,setErr]=import_react83.useState(""),[delegErr,setDelegErr]=import_react83.useState(""),delegGen=import_react83.useRef(0),active2=preorder(deleg?.active??[]),nodes=tree(deleg?.active??[],liveMap,now),all=totals(nodes),hotPeak=peak(nodes),aggOf=new Map;{let walk2=(ns)=>{for(let n of ns)aggOf.set(n.rec.subagent_id,n.agg),walk2(n.kids)};walk2(nodes)}let live=import_react83.useRef({profiles,active:active2});live.current={profiles,active:active2};let gwHome=import_react83.useRef(void 0),[stats,setStats]=import_react83.useState(()=>new Map),[sticky,setSticky]=import_react83.useState(stickyDefault),loadProfiles=import_react83.useCallback(()=>{setStats(new Map),setSticky(stickyDefault()),listProfiles(gwHome.current).then((ps)=>{setProfiles(ps),setErr("")}).catch((e)=>setErr(`profiles: ${e.message}`))},[]);import_react83.useEffect(()=>{gw.request("config.get",{key:"profile"}).then((r)=>{gwHome.current=r.home}).catch(()=>{}).finally(loadProfiles)},[gw,loadProfiles]);let loadDeleg=import_react83.useCallback(()=>{let current=++delegGen.current;gw.request("delegation.status").then((r)=>{if(delegGen.current!==current)return;setDeleg(r),setNow(Date.now()/1000),setDelegErr("")}).catch((e)=>{if(delegGen.current===current)setDelegErr(e instanceof Error?e.message:String(e))})},[gw]);import_react83.useEffect(loadDeleg,[loadDeleg]),import_react83.useEffect(()=>()=>{delegGen.current++},[]),import_react83.useEffect(()=>{if(!props.focused)return;let ms2=(deleg?.active.length??0)>0?1500:5000,t2=setInterval(loadDeleg,ms2);return()=>clearInterval(t2)},[props.focused,deleg?.active.length,loadDeleg]),useGatewayEvent((ev)=>{if(!ev.type.startsWith("subagent."))return;let p=ev.payload,id=p.subagent_id;if(!id)return;if(setLiveMap((prev)=>{let next2=new Map(prev),cur=next2.get(id)??{tool_count:0};switch(ev.type){case"subagent.start":next2.set(id,{tool_count:0});break;case"subagent.tool":next2.set(id,{...cur,tool_count:cur.tool_count+1,last_tool:p.tool_name,last_preview:p.tool_preview});break;case"subagent.thinking":next2.set(id,{...cur,thinking:p.text});break;case"subagent.complete":next2.set(id,{...cur,status:p.status,input_tokens:p.input_tokens,output_tokens:p.output_tokens,cost_usd:p.cost_usd});break}return next2}),ev.type==="subagent.start"||ev.type==="subagent.complete")loadDeleg()});let sh=import_react83.useCallback((cmd2)=>gw.request("shell.exec",{command:cmd2}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||"exit "+r.code).trim());return r.stdout}),[gw]),pHover=import_react83.useCallback((i)=>setPSel(i),[]),dHover=import_react83.useCallback((i)=>setDSel(i),[]),pDelete=import_react83.useCallback(async(i)=>{let p=live.current.profiles[i];if(!p||p.is_default||p.is_active)return;let warn=p.gateway_running?`
4129
+ This mutates the learning source through learning.delete.`,yes:"delete",danger:!0}))return;setBusy(!0),setErr(null);try{let req={id:node.id},r=await gw.request("learning.delete",req);if(toast.show({variant:r.ok?"success":"warning",message:r.message}),r.ok||/stale|refresh/i.test(r.message))setTick((n)=>n+1)}catch(e){setErr(message(e))}finally{setBusy(!1)}},[dialog,gw,node,toast]);useKeyboard((key3)=>{if(!props.focused||dialog.open()||busy)return;if(detail&&(key3.name==="tab"||keys.match("focus.cycle",key3))){setPane((p)=>p==="list"?"detail":"list");return}if(detail&&pane==="detail"){let page=Math.max(1,(scroll.current?.viewport.height??10)-1);if(key3.name==="escape"){setPane("list");return}if(key3.name==="up"||key3.name==="k"||key3.raw==="k"){scroll.current?.scrollBy(-1);return}if(key3.name==="down"||key3.name==="j"||key3.raw==="j"){scroll.current?.scrollBy(1);return}if(key3.name==="pageup"){scroll.current?.scrollBy(-page);return}if(key3.name==="pagedown"){scroll.current?.scrollBy(page);return}if(key3.name==="home"||key3.name==="g"){scroll.current?.scrollTo(0);return}if(key3.name==="end"||key3.raw==="G"||key3.name==="g"&&key3.shift){scroll.current?.scrollTo(scroll.current.scrollHeight);return}return}if(key3.name==="escape"&&detail){setDetail(null),setPane("list");return}if(handleListKey(keys,key3,{count:rows3.length,setSel:setListSel,...follow.opts,onActivate:()=>{if(node)open2(node)},onToggle:()=>{if(node)open2(node)},onRefresh:()=>setTick((n)=>n+1),onDelete:()=>void del()}))return;if(key3.name==="e"||key3.raw==="e"){edit();return}});let rowPick=import_react66.useCallback((i)=>jump(i),[jump]),rowOpen=import_react66.useCallback((i)=>{jump(i);let r=rows3[i];if(r?.kind==="node")open2(r.node)},[jump,open2,rows3]),hint=detail&&pane==="detail"?`\u2191\u2193/jk scroll ${keys.print("list.pageUp")}/${keys.print("list.pageDown")} page Tab list Esc list`:`${keys.print("list.activate")} detail ${keys.print("list.toggle")} detail e edit ${keys.print("list.delete")} delete ${keys.print("list.refresh")} reload${detail?" Tab detail Esc close":""}`;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,minWidth:0,children:[$jsxs(TabShell,{title:data2?`Journey \xB7 ${data2.count} learned item${data2.count===1?"":"s"}`:"Journey",error:err,focus:pane==="list",grow:detail?2:1,children:[!data2&&!err?$jsx(Loading,{}):null,!data2&&err?$jsx(ErrorState,{err}):null,data2&&data2.count===0?$jsx(Empty,{}):null,data2&&data2.count>0?$jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:0,children:[$jsx(Legend,{data:data2}),$jsx(Chart2,{rows:chart,theme}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",children:rows3.map((r,i)=>$jsx(Row2,{id:follow.id(i),row:r,index:i,active:i===sel,theme,pick:rowPick,open:rowOpen},rid(r,i)))})})]}):null]}),detail?$jsx(Detail2,{detail,box:scroll,focus:pane==="detail",theme}):null]}),$jsx(HintBar,{raw:busy?"loading\u2026":hint})]})}),Loading=()=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,justifyContent:"center",alignItems:"center",children:$jsx("text",{fg:theme.textMuted,children:"assembling learning map\u2026"})})},Empty=()=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,justifyContent:"center",alignItems:"center",children:$jsx("text",{fg:theme.textMuted,children:"No learning yet \u2014 skills and memories will appear here."})})},ErrorState=({err})=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,justifyContent:"center",alignItems:"center",children:$jsx("text",{fg:theme.error,wrapMode:"word",children:err})})},Legend=({data:data2})=>{let theme=useTheme().theme,text4=[...data2.legend??[],...data2.categories??[]].map((i)=>`${i.glyph} ${i.label}`).join(" ")||data2.summary.join(" ");return $jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:text4})})},Chart2=({rows:rows3,theme})=>$jsx("box",{flexDirection:"column",flexShrink:0,children:rows3.map((row3,i)=>$jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{wrapMode:"none",children:row3.map((run,n)=>$jsx("span",{fg:style(theme,run[1],run[3]),children:run[0]},n))})},i))}),Row2=import_react66.memo((props)=>{let bg2=props.active?props.theme.backgroundElement:void 0,caret=props.active?"\u25B8 ":" ";if(props.row.kind==="gap")return $jsx("box",{id:props.id,height:1});if(props.row.kind==="slice")return $jsx("box",{id:props.id,height:1,backgroundColor:bg2,onMouseMove:()=>props.pick(props.index),onMouseDown:()=>props.open(props.index),overflow:"hidden",children:$jsxs("text",{wrapMode:"none",children:[$jsx("span",{fg:props.theme.textMuted,children:caret}),$jsx("span",{fg:props.active?props.theme.accent:props.theme.primary,children:props.row.bucket.label}),$jsx("span",{fg:props.theme.textMuted,children:` ${props.row.bucket.total} total \xB7 ${props.row.bucket.memories} memories \xB7 ${props.row.bucket.skills} skills`})]})});return $jsx("box",{id:props.id,height:1,backgroundColor:bg2,onMouseMove:()=>props.pick(props.index),onMouseDown:()=>props.open(props.index),overflow:"hidden",children:$jsxs("text",{wrapMode:"none",children:[$jsx("span",{fg:props.theme.textMuted,children:caret}),$jsx("span",{fg:props.theme.textMuted,children:props.row.last?" \u2514\u2500 ":" \u251C\u2500 "}),$jsx("span",{fg:props.active?props.theme.accent:style(props.theme,props.row.node.style),children:`${props.row.node.glyph} ${trunc5(props.row.node.fullLabel||props.row.node.label,54)}`}),$jsx("span",{fg:props.theme.textMuted,children:props.row.node.meta?` ${props.row.node.meta}`:""})]})})}),Detail2=(props)=>$jsx(TabShell,{title:props.detail.ok?`${props.detail.kind} \xB7 ${props.detail.label}`:"Detail",focus:props.focus,grow:1,children:props.detail.ok?$jsx("scrollbox",{ref:props.box,scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:props.detail.content.split(/\r?\n/).map((line2,i)=>$jsx("box",{minHeight:1,children:$jsx("text",{fg:props.theme.text,wrapMode:"word",children:line2||" "})},i))})}):$jsx("text",{fg:props.theme.warning,wrapMode:"word",children:props.detail.message})});var import_react68=__toESM(require_react_production(),1);var SubTabBar=import_react68.memo((props)=>$jsx(TabStrip,{...props}));var TABS=[{name:"Chat",description:"Main chat interface"},{name:"Sessions",description:"Sessions, context, analytics"},{name:"Profiles & Automation",description:"Profiles, cron jobs, kanban boards"},{name:"Config",description:"Config, env, skills, toolsets, memory"},{name:"Eikon",description:"Avatar studio & library"}],TAB_MAX=TABS.length-1,CHAT_TAB=0,SESSIONS_TAB=1,AUTOMATION_TAB=2,CONFIG_TAB=3,EIKON_TAB=4,SUB_TABS={[1]:["List","Context","Analytics","Journey"],[2]:["Kanban","Profiles","Cron"],[3]:["Config","Skills","Toolsets","Env","Memory"],[4]:["Library","Catalog","Studio"]},TAB_SLASH={chat:{tab:0,sub:0},sessions:{tab:1,sub:0},context:{tab:1,sub:1},analytics:{tab:1,sub:2},insights:{tab:1,sub:2},journey:{tab:1,sub:3},learning:{tab:1,sub:3},"memory-graph":{tab:1,sub:3},kanban:{tab:2,sub:0},automation:{tab:2,sub:0},profiles:{tab:2,sub:1},agents:{tab:2,sub:1},cron:{tab:2,sub:2},config:{tab:3,sub:0},skills:{tab:3,sub:1},toolsets:{tab:3,sub:2},env:{tab:3,sub:3},memory:{tab:3,sub:4},library:{tab:4,sub:0},catalog:{tab:4,sub:1},studio:{tab:4,sub:2}};var SessionsGroup=import_react69.memo((props)=>{let labels=SUB_TABS[SESSIONS_TAB];import_react69.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]);let hint="shift+\u2190/\u2192 sub";return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(SubTabBar,{tabs:labels,active:props.sub,onChange:props.setSub,hint}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[$jsx(Pane,{visible:props.sub===0,children:$jsx(Sessions,{focused:!!props.focused&&props.sub===0,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId})}),$jsx(Pane,{visible:props.sub===1,children:$jsx(Context,{focused:!!props.focused&&props.sub===1,messages:props.messages,sessionStart:props.sessionStart,info:props.info,usage:props.usage})}),$jsx(Pane,{visible:props.sub===2,children:$jsx(Analytics,{focused:!!props.focused&&props.sub===2})}),$jsx(Pane,{visible:props.sub===3,children:$jsx(Journey,{focused:!!props.focused&&props.sub===3})})]})]})}),Pane=({visible:visible2,children:children2})=>visible2?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react94=__toESM(require_react_production(),1);var import_react83=__toESM(require_react_production(),1);var acc=new Map;function record(ev,p){let id=p.subagent_id;if(!id)return;let now=Date.now()/1000;if(ev==="start"){acc.set(id,{subagent_id:id,parent_id:p.parent_id??null,depth:p.depth??0,goal:p.goal,model:p.model,started_at:now,tool_count:0,status:"running",trail:[]});return}let r=acc.get(id);if(!r)return;if(ev==="tool"&&p.tool_name){r.tool_count++,r.trail=[...r.trail??[],{name:p.tool_name,preview:p.tool_preview}].slice(-20);return}if(ev==="complete")r.status=p.status??"completed",r.finished_at=now,r.input_tokens=p.input_tokens,r.output_tokens=p.output_tokens,r.cost_usd=p.cost_usd}function trail(id){return acc.get(id)?.trail??[]}function flush(gw,sessionId){if(acc.size===0)return;let subagents=[...acc.values()];acc.clear();let label2=(subagents.filter((s)=>s.parent_id==null).slice(0,2).map((s)=>s.goal).join(" \xB7 ")||`${subagents.length} subagents`).slice(0,120),started=Math.min(...subagents.map((s)=>s.started_at));gw.request("spawn_tree.save",{session_id:sessionId,label:label2,started_at:started,finished_at:Date.now()/1000,subagents}).catch(()=>{})}var import_react72=__toESM(require_react_production(),1);var import_react70=__toESM(require_react_production(),1);var DialogSelect=(props)=>{let filterable=props.filterable??!0,[filter,setFilter]=import_react70.useState(""),[cursor,setCursor]=import_react70.useState(0),mode2=import_react70.useRef("kb"),moved=import_react70.useRef(!1),sb=import_react70.useRef(null),theme=useTheme().theme,opts=import_react70.useMemo(()=>props.options.map((o)=>({name:`${props.current==null?"":o.value===props.current?"\u25CF ":" "}${o.title}`,description:o.hint?[o.description,o.hint].filter(Boolean).join(" \u2014 "):o.description??"",value:o.value})),[props.current,props.options]),sel=props.current==null?0:Math.max(0,props.options.findIndex((o)=>o.value===props.current)),desc=props.options.some((o)=>!!o.description||!!o.hint),filtered=import_react70.useMemo(()=>{let lower=filter.toLowerCase();return props.options.filter((o)=>o.title.toLowerCase().includes(lower)||(o.description??"").toLowerCase().includes(lower))},[filter,props.options]),groups=import_react70.useMemo(()=>{let map=new Map;return filtered.forEach((o)=>{let cat=o.category??"",arr=map.get(cat)??[];arr.push(o),map.set(cat,arr)}),map},[filtered]),rowId=(i)=>`ds-row-${i}`,scrollTo=(i)=>sb.current?.scrollChildIntoView(rowId(i));import_react70.useEffect(()=>{if(cursor>=filtered.length)setCursor(Math.max(0,filtered.length-1))},[filtered.length,cursor]),import_react70.useEffect(()=>{if(!props.current){setCursor(0);return}let i=filtered.findIndex((o)=>o.value===props.current),n=Math.max(0,i);setCursor(n),scrollTo(n)},[props.current,filtered]),import_react70.useEffect(()=>{if(!moved.current)return;moved.current=!1;let item=filtered[cursor];if(item&&props.onMove)props.onMove(item)},[cursor,filtered,props.onMove]);let keys=useKeys();useKeyboard((key3)=>{if(!filterable)return;if(handleListKey(keys,key3,{count:filtered.length,setSel:(fn)=>{mode2.current="kb",moved.current=!0,setCursor(fn)},scrollTo,page:Math.max(1,(sb.current?.viewport.height??10)-1),onActivate:()=>{let item=filtered[cursor];if(item)props.onSelect(item)}}))return;if(props.onKey?.(key3))return});let idx=0,entries2=Array.from(groups.entries());if(!filterable)return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.title})}),$jsx("box",{height:1}),$jsx("select",{focused:!0,width:58,height:Math.min(16,Math.max(1,props.options.length*(desc?2:1))),options:opts,selectedIndex:sel,showDescription:desc,showScrollIndicator:props.options.length>8,backgroundColor:theme.backgroundPanel,focusedBackgroundColor:theme.backgroundPanel,textColor:theme.textMuted,focusedTextColor:theme.text,selectedBackgroundColor:theme.backgroundElement,selectedTextColor:theme.text,descriptionColor:theme.textMuted,selectedDescriptionColor:theme.textMuted,fastScrollStep:Math.max(1,props.options.length),keyBindings:[{name:"home",action:"move-up-fast"},{name:"end",action:"move-down-fast"},{name:"pageup",action:"move-up-fast"},{name:"pagedown",action:"move-down-fast"},{name:"space",action:"select-current"},{name:" ",action:"select-current"}],onChange:(i)=>{let item=props.options[i];if(item&&props.onMove)props.onMove(item)},onSelect:(i)=>{let item=props.options[i];if(item)props.onSelect(item)}}),props.footer!=null?$jsx("box",{paddingTop:1,children:props.footer}):null]});return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.title})}),$jsx("box",{height:1}),filterable?$jsxs($Fragment,{children:[$jsx("input",{value:filter,onInput:(v2)=>{mode2.current="kb",setFilter(v2)},placeholder:props.placeholder??"Type to filter...",focused:!0,textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}),$jsx("box",{height:1})]}):null,$jsxs("scrollbox",{ref:sb,scrollY:!0,maxHeight:16,focused:!filterable,contentOptions:{flexDirection:"column"},paddingRight:1,children:[filtered.length===0?$jsx("text",{fg:theme.textMuted,children:"No results found"}):null,entries2.map(([cat,items])=>{let elements=[];if(cat)elements.push($jsx("text",{fg:theme.textMuted,children:$jsx("strong",{children:cat})},`cat-${cat}`));return items.forEach((item)=>{let i=idx++,active2=i===cursor,current=item.value===props.current;elements.push($jsxs("box",{id:rowId(i),flexDirection:"row",backgroundColor:active2?theme.backgroundElement:void 0,onMouseMove:()=>{mode2.current="mouse",moved.current=!0,setCursor((c)=>c===i?c:i)},onMouseOver:()=>{if(mode2.current==="mouse")moved.current=!0,setCursor(i)},onMouseDown:()=>props.onSelect(item),paddingLeft:1,paddingRight:1,children:[$jsx("box",{flexGrow:1,height:1,overflow:"hidden",children:$jsxs("text",{fg:active2?theme.text:theme.textMuted,children:[current?"\u25CF ":" ",item.title,item.description?` \u2014 ${item.description}`:""]})}),item.hint?$jsx("box",{flexShrink:0,height:1,children:$jsx("text",{fg:theme.textMuted,children:item.hint})}):null]},item.value))}),elements}).flat()]}),props.footer!=null?$jsx("box",{paddingTop:1,children:props.footer}):null]})};var Ctx6=import_react72.createContext(null),CommandProvider=({children:children2})=>{let registry=import_react72.useRef(new Map),enabled2=import_react72.useRef(!0),dialog=useDialog(),keys=useKeys(),all=import_react72.useCallback(()=>{let out=[];return registry.current.forEach((cmds)=>cmds.forEach((c)=>out.push(c))),out},[]),register=import_react72.useCallback((cmds)=>{let id=String(Date.now())+Math.random();return registry.current.set(id,cmds),()=>{registry.current.delete(id)}},[]),setEnabled=import_react72.useCallback((val)=>{enabled2.current=val},[]),open2=import_react72.useCallback(()=>{let cmds=all(),options=cmds.map((c)=>({title:c.title,value:c.value,description:c.description,hint:c.action?keys.print(c.action):void 0,category:c.category}));dialog.replace($jsx(DialogSelect,{title:"Command Palette",options,onSelect:(opt)=>{dialog.clear();let found=cmds.find((c)=>c.value===opt.value);if(found)found.onSelect()},placeholder:"Search commands..."}))},[all,dialog,keys]);useKeyboard((key3)=>{if(!enabled2.current||dialog.open())return;if(keys.match("palette.open",key3))return open2();for(let c of all())if(c.action&&keys.match(c.action,key3))return c.onSelect()});let value=import_react72.useMemo(()=>({register,setEnabled}),[register,setEnabled]);return $jsx(Ctx6.Provider,{value,children:children2})},useCommand=makeUse(Ctx6,"useCommand");var import_react74=__toESM(require_react_production(),1);function openAlert(dialog,title,body){dialog.replace($jsx(Alert,{title,body,onClose:()=>dialog.clear()}))}var Alert=(props)=>{let theme=useTheme().theme,keys=useKeys(),[copied2,setCopied]=import_react74.useState(!1),doCopy=()=>{copy2(props.body),setCopied(!0),setTimeout(()=>setCopied(!1),900)};return useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.accept",key3))props.onClose();if(keys.match("dialog.copy",key3))doCopy()}),$jsxs("box",{flexDirection:"column",width:84,maxHeight:28,border:["left"],borderColor:theme.info,customBorderChars:LEFT_BAR,backgroundColor:theme.backgroundPanel,paddingLeft:2,paddingRight:2,paddingY:1,gap:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.info,children:"\u25C8 "}),$jsx("span",{fg:theme.text,children:props.title})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:props.body})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:`${keys.print("dialog.cancel")} close \xB7 ${keys.print("dialog.copy")} `})}),$jsx("box",{flexShrink:0,onMouseDown:(e)=>{e.stopPropagation(),doCopy()},children:$jsx("text",{fg:copied2?theme.success:theme.textMuted,children:$jsx("u",{children:copied2?"copied":"copy"})})})]})]})};var Status=({s})=>{let theme=useTheme().theme,fg2=s==="completed"?theme.success:s==="failed"?theme.error:s==="error"?theme.error:s==="timeout"?theme.error:s==="interrupted"?theme.warning:theme.textMuted;return $jsx("span",{fg:fg2,children:s})},SnapshotView=(props)=>{let theme=useTheme().theme,subs2=props.snap.subagents??[],tok=subs2.reduce((n,s)=>n+(s.input_tokens??0)+(s.output_tokens??0),0),span2=props.snap.started_at&&props.snap.finished_at?dur2(props.snap.finished_at-props.snap.started_at):"\u2014";return $jsxs("box",{flexDirection:"column",width:80,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.entry.label||`${subs2.length} subagents`})}),$jsxs("text",{fg:theme.textMuted,children:[when(props.entry.finished_at)," \xB7 ",span2," \xB7 ",subs2.length," agents \xB7 ",fmt(tok)," tok"]}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,maxHeight:20,contentOptions:{flexDirection:"column"},children:subs2.map((s)=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "+"\xB7 ".repeat(s.depth)}),$jsx("span",{fg:theme.text,children:trunc5(s.goal.replace(/\s+/g," "),60)})]})}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["\u2503 "+" ".repeat(2*s.depth+2),$jsx(Status,{s:s.status}),` \xB7 ${s.tool_count}t`,s.finished_at?` \xB7 ${dur2(s.finished_at-s.started_at)}`:"",s.model?` \xB7 ${s.model}`:""]})})]},s.subagent_id))})]})};function openSpawnHistory(dialog,gw,sessionId){dialog.replace($jsx("box",{width:40,height:3,children:$jsx("text",{children:"Loading spawn history\u2026"})}));let listToken=dialog.version();gw.request("spawn_tree.list",{session_id:sessionId,limit:50}).then((r)=>{if(dialog.version()!==listToken)return;let entries2=r.entries??[];dialog.replace($jsx(DialogSelect,{title:"Spawn history",placeholder:entries2.length?"filter\u2026":"no saved spawn trees",options:entries2.map((e)=>({value:e.path,title:`${e.count.toString().padStart(2)}\xD7 ${trunc5(e.label||"(unlabeled)",40)}`,description:when(e.finished_at),category:e.session_id===sessionId?"This session":e.session_id})),onSelect:(opt)=>{let entry2=entries2.find((e)=>e.path===opt.value);dialog.replace($jsx("box",{width:40,height:3,children:$jsx("text",{children:"Loading spawn tree\u2026"})}));let token=dialog.version();gw.request("spawn_tree.load",{path:entry2.path}).then((snap2)=>{if(dialog.version()===token)dialog.replace($jsx(SnapshotView,{entry:entry2,snap:snap2}))}).catch((e)=>{if(dialog.version()===token)openAlert(dialog,"Spawn history",e instanceof Error?e.message:String(e))})}}))}).catch((e)=>{if(dialog.version()===listToken)openAlert(dialog,"Spawn history",e instanceof Error?e.message:String(e))})}var import_react77=__toESM(require_react_production(),1);var Dialog=(props)=>{let theme=useTheme().theme,keys=useKeys();useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.accept",key3))return props.onClose()});let d2=props.d,req=d2.env_requires.filter((e)=>e.required),opt=d2.env_requires.filter((e)=>!e.required),link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs("box",{flexDirection:"column",minWidth:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:`Distribution \xB7 ${props.profile}`})})}),$jsxs("box",{flexDirection:"column",children:[$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0],["Author",d2.author||void 0],["License",d2.license||void 0],["Description",d2.description||void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed",Number.isFinite(when2)?ago(when2/1000):void 0],["Owned",d2.distribution_owned.length?d2.distribution_owned.join(", "):void 0]]})]}),d2.env_requires.length?$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Environment variables"})})}),req.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Required"})}),req.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null,opt.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Optional"})}),opt.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null]}):null,$jsx("box",{height:1,children:$jsx("text",{fg:theme.borderSubtle,children:`[${keys.print("dialog.cancel")}] close`})})]})},EnvRow=(props)=>{let theme=useTheme().theme,tail=[props.desc,props.fallback?`default: ${props.fallback}`:""].filter(Boolean).join(" \xB7 ");return $jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:2,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:" "})}),$jsx("box",{width:22,flexShrink:0,children:$jsx("text",{fg:theme.accent,children:props.name})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:tail})})]})};function openDistributionInfo(dialog,opts){dialog.replace($jsx(Dialog,{profile:opts.profile,d:opts.d,yaml:opts.yaml,onClose:()=>dialog.clear()}))}function openProfileMenu(dialog,p,ops){let opts=[...ops.switch&&!p.is_active?[{category:"Switch",value:"switch",title:`Switch to '${p.name}'`,description:"restart gateway under this HERMES_HOME \u2014 ends current session"}]:[],{category:"Open",value:"soul",title:"SOUL.md",description:"edit persona/system prompt"},{category:"Open",value:"config",title:"config.yaml",description:"model, provider, toolsets"},...p.has_env?[{category:"Open",value:"env",title:".env",description:"API keys + secrets"}]:[],{category:"Open",value:"dir",title:"Directory",description:p.path},...p.distribution?[{category:"Distribution",value:"dist-info",title:"Info",description:`v${p.distribution.version}${p.distribution.source?` \xB7 ${p.distribution.source}`:""}`},{category:"Distribution",value:"dist-update",title:"Update",description:`hermes profile update ${p.name}${p.is_active?" \xB7 ends current session":""}`}]:[],...p.is_sticky?[{category:"Default",value:"unsticky",title:"Clear sticky default",description:"hermes profile use --clear"}]:[{category:"Default",value:"sticky",title:"Set as sticky default",description:`hermes profile use ${p.name}`}],{category:"Manage",value:"export",title:"Export",description:`hermes profile export ${p.name}`},...p.is_default||p.is_active?[]:[{category:"Manage",value:"delete",title:"Delete",description:"irreversible \u2014 removes config, env, memory, sessions"}]];dialog.replace($jsx(DialogSelect,{title:`Profile \xB7 ${p.name}${p.is_active?" (active)":""}`,options:opts,onSelect:(o)=>{if(o.value==="dist-info"){if(!p.distribution)return dialog.clear();return openDistributionInfo(dialog,{profile:p.name,d:p.distribution,yaml:p.sources.distribution})}if(o.value==="dist-update"){if(!p.distribution)return dialog.clear();return openUpdateDistribution(dialog,p,(force)=>ops.update(p,force))}if(dialog.clear(),o.value==="switch")return ops.switch?.();if(o.value==="soul")return openFile(p.sources.soul.file);if(o.value==="config")return openFile(p.sources.config.file);if(o.value==="env")return openFile(p.sources.env.file);if(o.value==="dir")return openFile(p.path);if(o.value==="sticky")return ops.sticky(p);if(o.value==="unsticky")return ops.unsticky();if(o.value==="export")return ops.export(p);if(o.value==="delete")return ops.remove(p)}}))}var UpdateForm=(props)=>{let theme=useTheme().theme,keys=useKeys(),[force,setForce]=import_react77.useState(!1);useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.deny",key3))return props.done(null);if(keys.match("dialog.confirm",key3)||keys.match("dialog.accept",key3))return props.done(force);if(key3.name==="space"||key3.name===" ")return setForce((f)=>!f)});let d2=props.p.distribution;return $jsxs("box",{flexDirection:"column",width:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:"Update distribution?"})})}),$jsxs("box",{flexDirection:"column",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:`'${props.p.name}' \xB7 v${d2.version}${d2.source?` \xB7 ${d2.source}`:""}`})}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:"Re-pulls from source; distribution-owned files are overwritten."})}),props.p.is_active?$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.warning,children:"\u26A0 This is the active profile. The gateway will re-spawn "+"and the current session will end."})}):null]}),$jsx("box",{height:1,children:$jsx("text",{fg:force?theme.warning:theme.textMuted,children:`${force?"[x]":"[ ]"} --force-config \xB7 also overwrite config.yaml`})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`[${keys.print("dialog.confirm")}] update [Space] toggle force [${keys.print("dialog.cancel")}] cancel`})})]})};function openUpdateDistribution(dialog,p,onConfirm){dialog.replace($jsx(UpdateForm,{p,done:(force)=>{if(dialog.clear(),force!==null)onConfirm(force)}}))}var import_react79=__toESM(require_react_production(),1);import{existsSync as existsSync18,readFileSync as readFileSync11}from"fs";import{readdir as readdir2}from"fs/promises";import{homedir as homedir7}from"os";import{join as join13,basename as basename9,dirname as dirname8}from"path";import{Database as Database2}from"bun:sqlite";var home4=()=>process.env.HOME||homedir7(),hermesHome=()=>process.env.HERMES_HOME||join13(home4(),".hermes");function root2(){let hh=hermesHome(),parent2=dirname8(hh);return basename9(parent2)==="profiles"?dirname8(parent2):hh}function profileNameFrom(hh){let parent2=dirname8(hh);return basename9(parent2)==="profiles"?basename9(hh):"default"}function activeProfileName(){return profileNameFrom(hermesHome())}function stickyDefault(){try{return readFileSync11(join13(root2(),"active_profile"),"utf-8").trim()||null}catch{return null}}var ID_RE=/^[a-z0-9][a-z0-9_-]{0,63}$/;function resolveProfileHome(name){if(name==="default")return root2();if(!ID_RE.test(name))return null;let dir=join13(root2(),"profiles",name);return existsSync18(dir)?dir:null}function readModel(dir){try{let raw=readFileSync11(join13(dir,"config.yaml"),"utf-8"),block=raw.split(/^model:\s*$/m)[1]?.split(/^\S/m)[0]??"",m2=block.match(/^\s+(?:default|model):\s*(.+)$/m)?.[1]?.trim()??raw.match(/^model:\s*(\S.+)$/m)?.[1]?.trim(),p=block.match(/^\s+provider:\s*(.+)$/m)?.[1]?.trim(),clean5=(s)=>s?.replace(/^["']|["']$/g,"")??null;return[clean5(m2),clean5(p)]}catch{return[null,null]}}async function countSkills(dir){let glob=new Bun.Glob("**/SKILL.md"),n=0;try{for await(let _2 of glob.scan({cwd:join13(dir,"skills"),onlyFiles:!0}))n++}catch{}return n}function gatewayRunning(dir){try{let raw=readFileSync11(join13(dir,"gateway.pid"),"utf-8").trim(),pid2=raw.startsWith("{")?Number(JSON.parse(raw).pid):Number(raw);if(!Number.isFinite(pid2)||pid2<=0)return!1;return process.kill(pid2,0),!0}catch{return!1}}function soul(dir){try{return readFileSync11(join13(dir,"SOUL.md"),"utf-8").replace(/^#[^\n]*\n+/,"").replace(/^\s+/,"").slice(0,400)}catch{return""}}function readDistributionManifest(dir){let path4=join13(dir,"distribution.yaml");if(!existsSync18(path4))return null;let data2=(()=>{try{return $parse(readFileSync11(path4,"utf-8"))}catch{return null}})();if(!data2||typeof data2!=="object"||Array.isArray(data2))return null;let d2=data2,name=typeof d2.name==="string"?d2.name.trim():"";if(!name)return null;let envs=(Array.isArray(d2.env_requires)?d2.env_requires:[]).flatMap((e)=>{if(!e||typeof e!=="object")return[];let r=e,n=typeof r.name==="string"?r.name.trim():"";if(!n)return[];return[{name:n,description:typeof r.description==="string"?r.description:"",required:r.required===void 0?!0:Boolean(r.required),default:typeof r.default==="string"?r.default:null}]}),owned=(Array.isArray(d2.distribution_owned)?d2.distribution_owned:[]).map((p)=>typeof p==="string"?p.trim().replace(/\/+$/,""):"").filter((p)=>p.length>0);return{name,version:typeof d2.version==="string"?d2.version:"0.1.0",description:typeof d2.description==="string"?d2.description:"",hermes_requires:typeof d2.hermes_requires==="string"?d2.hermes_requires:"",author:typeof d2.author==="string"?d2.author:"",license:typeof d2.license==="string"?d2.license:"",env_requires:envs,distribution_owned:owned,source:typeof d2.source==="string"?d2.source:"",installed_at:typeof d2.installed_at==="string"?d2.installed_at:""}}var src2=(file,label2)=>({file,relative:file.replace(home4()+"/","~/"),label:label2});async function info(name,dir,active2,sticky){let[model,provider]=readModel(dir),alias=join13(home4(),".local","bin",name);return{name,path:dir,is_default:name==="default",is_active:name===active2,is_sticky:name===sticky,gateway_running:gatewayRunning(dir),model,provider,has_env:existsSync18(join13(dir,".env")),skill_count:await countSkills(dir),has_alias:name!=="default"&&existsSync18(alias),soul_preview:soul(dir),distribution:readDistributionManifest(dir),sources:{dir:src2(dir,dir.replace(home4()+"/","~/")),config:src2(join13(dir,"config.yaml"),"config.yaml"),soul:src2(join13(dir,"SOUL.md"),"SOUL.md"),env:src2(join13(dir,".env"),".env"),distribution:src2(join13(dir,"distribution.yaml"),"distribution.yaml")}}}async function listProfiles(activeHome){let r=root2(),active2=profileNameFrom(activeHome??hermesHome()),sticky=stickyDefault(),jobs=[];if(existsSync18(r))jobs.push(info("default",r,active2,sticky));let pr=join13(r,"profiles");if(existsSync18(pr))for(let e of await readdir2(pr,{withFileTypes:!0})){if(!e.isDirectory()||!ID_RE.test(e.name))continue;jobs.push(info(e.name,join13(pr,e.name),active2,sticky))}return Promise.all(jobs)}function validateName(name,existing){if(!ID_RE.test(name))return"must match [a-z0-9][a-z0-9_-]{0,63}";if(existing.includes(name))return"already exists";if(["hermes","default","test","tmp","root","sudo"].includes(name))return"reserved name";return null}function readPrefs(dir){try{let raw=JSON.parse(readFileSync11(join13(dir,"herm","tui.json"),"utf-8"));return{theme:raw.theme,eikon:raw.eikon??(raw.eikonPath?basename9(raw.eikonPath,".eikon"):void 0),keys:raw.keys?Object.keys(raw.keys).length:0}}catch{return null}}async function profileStats(dir){let sessions=null,messages=null,dbPath=join13(dir,"state.db");if(existsSync18(dbPath))try{let db=new Database2(dbPath,{readwrite:!0,create:!1}),r=db.query("SELECT COUNT(*) AS s FROM sessions WHERE message_count > 0").get(),m2=db.query("SELECT COALESCE(SUM(message_count), 0) AS m FROM sessions").get();sessions=r.s,messages=m2.m,db.close()}catch{}let crons=null;try{let jobs=await Bun.file(join13(dir,"cron","jobs.json")).json();crons=Array.isArray(jobs)?jobs.length:jobs&&typeof jobs==="object"&&Array.isArray(jobs.jobs)?jobs.jobs.length:0}catch{crons=existsSync18(join13(dir,"cron"))?0:null}return{sessions,messages,crons,prefs:readPrefs(dir)}}var ORDER3=["name","clone","alias"];function openCreateProfile(dialog,opts){return new Promise((resolve4)=>{let done=(r)=>{dialog.clear(),resolve4(r)};dialog.replace($jsx(Form,{existing:opts.existing,done}))})}var Form=({existing,done})=>{let theme=useTheme().theme,[name,setName]=import_react79.useState(""),[cloneIdx,setCloneIdx]=import_react79.useState(0),[alias,setAlias]=import_react79.useState(!0),[field,setField]=import_react79.useState("name"),options=["(fresh)",...existing],err=name?validateName(name,existing):null,valid=!!name&&!err,submit2=()=>{if(!valid)return;done({name,cloneFrom:cloneIdx===0?null:options[cloneIdx],alias})},moveField=(dir)=>{let i=ORDER3.indexOf(field);setField(ORDER3[(i+dir+ORDER3.length)%ORDER3.length])};useKeyboard((key3)=>{if(key3.name==="escape")return done(null);if(key3.name==="tab")return moveField(key3.shift?-1:1);if(key3.name==="return")return submit2();if(field==="name"){if(key3.name==="backspace")return setName((n)=>n.slice(0,-1));if(key3.raw&&key3.raw.length===1&&/[a-z0-9_-]/.test(key3.raw))return setName((n)=>n+key3.raw);return}if(field==="clone"){if(key3.name==="up")return setCloneIdx((i)=>Math.max(0,i-1));if(key3.name==="down")return setCloneIdx((i)=>Math.min(options.length-1,i+1));return}if(field==="alias"){if(key3.name==="space"||key3.name===" ")return setAlias((a)=>!a)}});let focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"New Profile"})})}),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name"})}),$jsxs("text",{children:[$jsx("span",{fg:valid||!name?theme.text:theme.error,children:name}),field==="name"?$jsx("span",{fg:theme.accent,children:"\u2588"}):null]})]}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:" a-z 0-9 _ - \xB7 lowercase"})}),$jsx("box",{height:1}),$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsx("text",{fg:theme.textMuted,children:"Clone from (\u2191\u2193)"})}),options.map((o,i)=>$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsxs("text",{fg:i===cloneIdx?theme.accent:theme.text,children:[i===cloneIdx?"\u25B8 ":" ",o]})},o)),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] shell alias":"[ ] shell alias"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:valid?"Enter create \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel":err??"type a name"})})]})};var import_react81=__toESM(require_react_production(),1);import{rmSync as rmSync3,mkdtempSync as mkdtempSync4}from"fs";import{join as join14}from"path";import{tmpdir as tmpdir4}from"os";var shq=(s)=>`'${s.replace(/'/g,"'\\''")}'`;function openInstallDistribution(dialog,gw){return new Promise((resolve4)=>{askSource(dialog,gw,(r)=>{dialog.clear(),resolve4(r)})})}function askSource(dialog,gw,done){dialog.replace($jsx(Step1,{onSubmit:(source)=>preview(dialog,gw,source,done),onCancel:()=>done(null)}))}async function preview(dialog,gw,source,done){let tmp=mkdtempSync4(join14(tmpdir4(),"herm-dist-preview-")),cleanup=()=>{try{rmSync3(tmp,{recursive:!0,force:!0})}catch{}},state2={cancelled:!1},cancel=()=>{state2.cancelled=!0,cleanup(),done(null)};dialog.replace($jsx(Loading2,{label:`Cloning ${source}\u2026`,onCancel:cancel}),void 0,{ownCancel:!0});let cmd=`git clone --depth 1 --quiet ${shq(source)} ${shq(tmp)} 2>&1`,r=await gw.request("shell.exec",{command:cmd}).catch((e)=>({stdout:"",stderr:e.message,code:-1}));if(state2.cancelled)return;if(r.code!==0){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Clone failed",body:(r.stderr||r.stdout||`exit ${r.code}`).trim(),onClose:()=>done(null)}));return}let manifest3=readDistributionManifest(tmp);if(!manifest3){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Not a distribution",body:`No valid distribution.yaml at the root of ${source}. A manifest must declare at minimum a 'name:' key.`,onClose:()=>done(null)}));return}dialog.replace($jsx(ConfirmStep,{source,manifest:manifest3,onConfirm:(r2)=>{cleanup(),done(r2)},onCancel:()=>{cleanup(),done(null)}}),void 0,{ownCancel:!0})}var Step1=(p)=>{let theme=useTheme().theme,[value,setValue]=import_react81.useState("");return useKeyboard((key3)=>{if(key3.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:64,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Source \u2014 git URL, github.com/owner/repo, or local directory"})}),$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,onInput:setValue,onSubmit:()=>{let v2=value.trim();if(v2)p.onSubmit(v2)},focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement})})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:value.trim()?"Enter preview \xB7 Esc cancel":"Esc cancel"})})]})},Loading2=(p)=>{let theme=useTheme().theme;return useKeyboard((key3)=>{if(key3.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx(Spinner,{color:theme.accent,label:p.label})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Esc to cancel"})})]})},ErrorBox=(p)=>{let theme=useTheme().theme,keys=useKeys();return useKeyboard((key3)=>{if(keys.match("dialog.accept",key3)||keys.match("dialog.cancel",key3))return p.onClose()}),$jsxs("box",{flexDirection:"column",width:68,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:$jsx("strong",{children:p.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.text,children:p.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter / Esc to close"})})]})},ORDER4=["name","alias"],ConfirmStep=(p)=>{let theme=useTheme().theme,keys=useKeys(),[name,setName]=import_react81.useState(""),[alias,setAlias]=import_react81.useState(!1),[field,setField]=import_react81.useState("name"),fire=()=>p.onConfirm({source:p.source,manifest:p.manifest,name:name.trim()||null,alias}),move=(dir)=>{let i=ORDER4.indexOf(field);setField(ORDER4[(i+dir+ORDER4.length)%ORDER4.length])};useKeyboard((key3)=>{if(key3.name==="escape")return p.onCancel();if(key3.name==="tab")return move(key3.shift?-1:1);if(field!=="name"&&keys.match("dialog.accept",key3))return fire();if(field==="alias"&&(key3.name==="space"||key3.name===" "))return setAlias((a)=>!a)});let m2=p.manifest,reqEnv=m2.env_requires.filter((e)=>e.required),optEnv=m2.env_requires.filter((e)=>!e.required),focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:72,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx(KV2,{label:"Name",value:`${m2.name}${m2.version?` v${m2.version}`:""}`,theme}),m2.description?$jsx(KV2,{label:"About",value:m2.description,theme,wrap:!0}):null,m2.author?$jsx(KV2,{label:"Author",value:m2.author,theme}):null,m2.license?$jsx(KV2,{label:"License",value:m2.license,theme}):null,m2.hermes_requires?$jsx(KV2,{label:"Requires",value:`hermes ${m2.hermes_requires}`,theme}):null,$jsx(KV2,{label:"Source",value:p.source,theme}),m2.distribution_owned.length>0?$jsx(KV2,{label:"Owns",value:m2.distribution_owned.join(", "),theme,wrap:!0}):null,m2.env_requires.length>0?$jsx(KV2,{label:"Env",value:envSummary(reqEnv,optEnv),theme}):null,$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name as"})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:field==="name"?$jsx("input",{value:name,onInput:setName,onSubmit:fire,focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}):$jsx("text",{fg:name?theme.text:theme.textMuted,children:name||`(${m2.name})`})})]}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] create shell wrapper":"[ ] create shell wrapper"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter install \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel"})})]})},KV2=(p)=>$jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:11,flexShrink:0,children:$jsx("text",{fg:p.theme.textMuted,children:p.label})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:p.theme.text,wrapMode:p.wrap?"word":"none",children:p.value})})]});function envSummary(req,opt){return[req.length>0?`${req.length} required (${req.map((e)=>e.name).join(", ")})`:"",opt.length>0?`${opt.length} optional`:""].filter(Boolean).join(" \xB7 ")}var running=(s)=>!s||s==="running"||s==="queued";function tree(recs,live,now){let ids=new Set(recs.map((r)=>r.subagent_id)),by=new Map;for(let r of recs){let k2=r.parent_id&&ids.has(r.parent_id)?r.parent_id:"";(by.get(k2)??by.set(k2,[]).get(k2)).push(r)}let build2=(r)=>{let kids=(by.get(r.subagent_id)??[]).map(build2),lv=live.get(r.subagent_id)??{},dur3=r.started_at!=null?Math.max(0,now-r.started_at):0,a={agents:1,tools:lv.tool_count??r.tool_count??0,dur:dur3,tok:(lv.input_tokens??0)+(lv.output_tokens??0),cost:lv.cost_usd??0,active:running(lv.status??r.status)?1:0,depth:0,hot:0};for(let k2 of kids)a={agents:a.agents+k2.agg.agents,tools:a.tools+k2.agg.tools,dur:a.dur+k2.agg.dur,tok:a.tok+k2.agg.tok,cost:a.cost+k2.agg.cost,active:a.active+k2.agg.active,depth:Math.max(a.depth,k2.agg.depth+1),hot:0};return a.hot=a.dur>0?a.tools/a.dur:0,{rec:r,agg:a,kids}};return(by.get("")??[]).map(build2)}function totals(nodes){let z2={agents:0,tools:0,dur:0,tok:0,cost:0,active:0,depth:0,hot:0};for(let n of nodes)z2.agents+=n.agg.agents,z2.tools+=n.agg.tools,z2.dur+=n.agg.dur,z2.tok+=n.agg.tok,z2.cost+=n.agg.cost,z2.active+=n.agg.active,z2.depth=Math.max(z2.depth,n.agg.depth+1);return z2.hot=z2.dur>0?z2.tools/z2.dur:0,z2}var SPARK=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function spark(nodes){let w2=[],walk2=(ns,d2)=>{if(ns.length===0)return;w2[d2]=(w2[d2]??0)+ns.length;for(let n of ns)walk2(n.kids,d2+1)};if(walk2(nodes,0),w2.length===0)return"";let max=Math.max(...w2);return w2.map((v2)=>v2<=0?" ":SPARK[Math.min(7,Math.ceil(v2/max*7))]).join("")}var tk=(n)=>n<1000?String(Math.round(n)):n<1e4?`${(n/1000).toFixed(1)}k`:`${Math.round(n/1000)}k`,$$=(n)=>n<=0?"":n<0.01?"<$0.01":n<10?`$${n.toFixed(2)}`:`$${n.toFixed(1)}`,sec=(s)=>{if(s<60)return`${Math.round(s)}s`;let m2=Math.floor(s/60),r=Math.round(s-m2*60);return r===0?`${m2}m`:`${m2}m${r}s`};function summary(a){let p=[`d${a.depth}`,`${a.agents} agent${a.agents===1?"":"s"}`];if(a.tools>0)p.push(`${a.tools} tools`);if(a.dur>0)p.push(sec(a.dur));if(a.tok>0)p.push(`${tk(a.tok)} tok`);if(a.cost>0)p.push($$(a.cost));if(a.active>0)p.push(`\u26A1${a.active}`);return p.join(" \xB7 ")}function heat(hot,peak,buckets){if(hot<=0||peak<=0||buckets<=1)return 0;return Math.min(buckets-1,Math.round(Math.min(1,hot/peak)*(buckets-1)))}function peak(nodes){let p=0,walk2=(ns)=>{for(let n of ns)p=Math.max(p,n.agg.hot),walk2(n.kids)};return walk2(nodes),p}var ProfileRow=import_react83.memo((props)=>{let theme=useTheme().theme,{p,idx:i}=props,[x2,setX]=import_react83.useState(!1);return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),onMouseDown:()=>props.onEnter(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:p.is_active?theme.accent:theme.text,children:p.is_active?$jsx("strong",{children:p.name}):p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605"}):null,p.distribution?$jsx("span",{fg:theme.info,children:" \u2B22"}):null,p.gateway_running?$jsx("span",{fg:theme.success,children:" \u25CF"}):null]})}),$jsx("box",{width:4,height:1,children:$jsx("text",{fg:theme.textMuted,children:p.is_active?" you":""})}),p.is_default||p.is_active?$jsx("box",{width:3}):$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onDelete(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})}),DistBlock=import_react83.memo((props)=>{let theme=useTheme().theme,d2=props.d,req=d2.env_requires.filter((e)=>e.required).length,opt=d2.env_requires.length-req,link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Distribution"})})}),$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed at",Number.isFinite(when2)?ago(when2/1000):void 0],["Env vars",d2.env_requires.length?`${req} required, ${opt} optional`:void 0]]})]})}),ProfileDetail=import_react83.memo((props)=>{let{theme,syntaxStyle}=useTheme(),p=props.p,s=props.stats;return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{height:1,children:$jsxs("text",{fg:theme.accent,children:[$jsx("strong",{children:p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605 sticky default"}):null]})}),$jsx("box",{height:1}),$jsx(KVLink,{label:"Path",source:p.sources.dir,text:p.sources.dir.relative}),$jsx(KV,{label:"Active",value:p.is_active?"yes (this session)":"no",fg:p.is_active?theme.accent:theme.textMuted}),$jsx(KV,{label:"Model",value:p.model??"\u2014"}),$jsx(KV,{label:"Provider",value:p.provider??"\u2014"}),$jsx(KV,{label:"Skills",value:String(p.skill_count)}),$jsx(KV,{label:"Sessions",value:s?s.sessions==null?"\u2014":`${fmt(s.sessions)} (${fmt(s.messages??0)} msgs)`:"\u2026"}),$jsx(KV,{label:"Cron jobs",value:s?s.crons==null?"\u2014":String(s.crons):"\u2026"}),$jsx(KV,{label:"Theme",value:s?s.prefs?.theme??"\u2014":"\u2026"}),$jsx(KV,{label:"Avatar",value:s?s.prefs?.eikon??"\u2014":"\u2026"}),s?.prefs?.keys?$jsx(KV,{label:"Keybinds",value:`${s.prefs.keys} overrides`}):null,$jsx(KV,{label:"Gateway",value:p.gateway_running?"running":"stopped",fg:p.gateway_running?theme.success:theme.textMuted}),p.has_alias?$jsx(KV,{label:"Alias",value:`${p.name} (shell)`}):null,p.distribution?$jsx(DistBlock,{d:p.distribution,yaml:p.sources.distribution}):null,$jsx("box",{height:1}),$jsx(KVLink,{label:"Config",source:p.sources.config}),$jsx(KVLink,{label:"Soul",source:p.sources.soul}),p.has_env?$jsx(KVLink,{label:"Env",source:p.sources.env}):$jsx(KV,{label:"Env",value:"\u2014"}),p.soul_preview?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"SOUL.md"})}),$jsx("markdown",{content:p.soul_preview,fg:theme.markdownText,syntaxStyle})]}):null]})})}),HOT=["\u2800","\u2801","\u2803","\u2807","\u280F","\u281F","\u283F","\u287F","\u28FF"],DelegRow=import_react83.memo((props)=>{let theme=useTheme().theme,{r,idx:i,now}=props,[x2,setX]=import_react83.useState(!1),up=r.started_at?dur2(now-r.started_at):"\u2014",hotFg=[theme.textMuted,theme.textMuted,theme.text,theme.info,theme.info,theme.accent,theme.accent,theme.warning,theme.error][props.hot]??theme.textMuted;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{width:2,children:$jsxs("text",{fg:hotFg,children:[HOT[props.hot]," "]})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\xB7 ".repeat(r.depth)}),$jsx("span",{fg:theme.text,children:r.goal.replace(/\s+/g," ")})]})}),$jsx("box",{width:14,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:trunc5(r.model??"",13)})}),$jsx("box",{width:5,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:String(r.tool_count??0)})}),$jsx("box",{width:8,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:up})}),$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onKill(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})});function preorder(recs){let byParent=new Map;for(let r of recs){let k2=r.parent_id??null;(byParent.get(k2)??byParent.set(k2,[]).get(k2)).push(r)}let out=[],seen=new Set,walk2=(k2)=>{for(let r of byParent.get(k2)??[]){if(seen.has(r.subagent_id))continue;seen.add(r.subagent_id),out.push(r),walk2(r.subagent_id)}};walk2(null);for(let r of recs)if(!seen.has(r.subagent_id))out.push(r);return out}var DelegDetail=import_react83.memo((props)=>{let theme=useTheme().theme,{r,live,agg,now}=props,tc=live?.tool_count??r.tool_count??0,tr=trail(r.subagent_id);return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.accent,wrapMode:"word",children:$jsx("strong",{children:r.goal})})}),agg&&agg.agents>1?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:summary(agg)})}):null,$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Status",live?.status??r.status??"running"],["Model",r.model??"\u2014"],["Depth",String(r.depth)],["Parent",r.parent_id??"(root)"],["Uptime",r.started_at?dur2(now-r.started_at):"\u2014"],["Tools",String(tc)],["Tokens",live?`${fmt(live.input_tokens??0)} in / ${fmt(live.output_tokens??0)} out`:void 0],["Cost",live?.cost_usd!=null?`$${live.cost_usd.toFixed(4)}`:void 0]]}),live?.thinking?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"thinking"})}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:trunc5(live.thinking,200)})})]}):null,tr.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"recent tools"})}),tr.slice(-8).map((t2,i)=>$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "}),$jsx("span",{fg:theme.text,children:t2.name.padEnd(14)}),$jsx("span",{fg:theme.textMuted,children:t2.preview?trunc5(t2.preview.replace(/\s+/g," "),40):""})]})},i))]}):null]})})}),Agents=import_react83.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),cmd=useCommand(),[pane,setPane]=import_react83.useState("profiles"),[pView,setPView]=import_react83.useState("list"),[profiles,setProfiles]=import_react83.useState([]),[deleg,setDeleg]=import_react83.useState(null),[liveMap,setLiveMap]=import_react83.useState(()=>new Map),[now,setNow]=import_react83.useState(()=>Date.now()/1000),[pSel,setPSel]=import_react83.useState(0),[dSel,setDSel]=import_react83.useState(0),[err,setErr]=import_react83.useState(""),[delegErr,setDelegErr]=import_react83.useState(""),delegGen=import_react83.useRef(0),active2=preorder(deleg?.active??[]),nodes=tree(deleg?.active??[],liveMap,now),all=totals(nodes),hotPeak=peak(nodes),aggOf=new Map;{let walk2=(ns)=>{for(let n of ns)aggOf.set(n.rec.subagent_id,n.agg),walk2(n.kids)};walk2(nodes)}let live=import_react83.useRef({profiles,active:active2});live.current={profiles,active:active2};let gwHome=import_react83.useRef(void 0),[stats,setStats]=import_react83.useState(()=>new Map),[sticky,setSticky]=import_react83.useState(stickyDefault),loadProfiles=import_react83.useCallback(()=>{setStats(new Map),setSticky(stickyDefault()),listProfiles(gwHome.current).then((ps)=>{setProfiles(ps),setErr("")}).catch((e)=>setErr(`profiles: ${e.message}`))},[]);import_react83.useEffect(()=>{gw.request("config.get",{key:"profile"}).then((r)=>{gwHome.current=r.home}).catch(()=>{}).finally(loadProfiles)},[gw,loadProfiles]);let loadDeleg=import_react83.useCallback(()=>{let current=++delegGen.current;gw.request("delegation.status").then((r)=>{if(delegGen.current!==current)return;setDeleg(r),setNow(Date.now()/1000),setDelegErr("")}).catch((e)=>{if(delegGen.current===current)setDelegErr(e instanceof Error?e.message:String(e))})},[gw]);import_react83.useEffect(loadDeleg,[loadDeleg]),import_react83.useEffect(()=>()=>{delegGen.current++},[]),import_react83.useEffect(()=>{if(!props.focused)return;let ms2=(deleg?.active.length??0)>0?1500:5000,t2=setInterval(loadDeleg,ms2);return()=>clearInterval(t2)},[props.focused,deleg?.active.length,loadDeleg]),useGatewayEvent((ev)=>{if(!ev.type.startsWith("subagent."))return;let p=ev.payload,id=p.subagent_id;if(!id)return;if(setLiveMap((prev)=>{let next2=new Map(prev),cur=next2.get(id)??{tool_count:0};switch(ev.type){case"subagent.start":next2.set(id,{tool_count:0});break;case"subagent.tool":next2.set(id,{...cur,tool_count:cur.tool_count+1,last_tool:p.tool_name,last_preview:p.tool_preview});break;case"subagent.thinking":next2.set(id,{...cur,thinking:p.text});break;case"subagent.complete":next2.set(id,{...cur,status:p.status,input_tokens:p.input_tokens,output_tokens:p.output_tokens,cost_usd:p.cost_usd});break}return next2}),ev.type==="subagent.start"||ev.type==="subagent.complete")loadDeleg()});let sh=import_react83.useCallback((cmd2)=>gw.request("shell.exec",{command:cmd2}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||"exit "+r.code).trim());return r.stdout}),[gw]),pHover=import_react83.useCallback((i)=>setPSel(i),[]),dHover=import_react83.useCallback((i)=>setDSel(i),[]),pDelete=import_react83.useCallback(async(i)=>{let p=live.current.profiles[i];if(!p||p.is_default||p.is_active)return;let warn=p.gateway_running?`
4130
4130
 
4131
4131
  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_react83.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_react83.useCallback(async(p,force)=>{let cmd2=`hermes profile update ${p.name} -y${force?" --force-config":""}`;toast.show({variant:"info",message:`Updating '${p.name}'\u2026`});try{await sh(cmd2),toast.show({variant:"success",message:`Updated '${p.name}'`})}catch(err2){let error=err2 instanceof Error?err2:Error(String(err2));if(!p.is_active||!props.onSwitchProfile||!/gateway (?:exited|restarted)/i.test(error.message)){toast.show({variant:"error",message:error.message});return}}if(p.is_active&&props.onSwitchProfile){props.onSwitchProfile(p.path,p.name);return}loadProfiles()},[sh,toast,loadProfiles,props.onSwitchProfile]),pEnter=import_react83.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_react83.useCallback(async(i)=>{let r=live.current.active[i];if(!r)return;if(!await openConfirm(dialog,{title:"Interrupt subagent?",body:`${trunc5(r.goal,120)}
4132
4132
 
4133
- 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_react83.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_react83.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_react83.useRef(0);import_react83.useEffect(()=>{let path4=selected?.path;if(!path4||stats.has(path4))return;let g=++statGen.current;profileStats(path4).then((s)=>{if(statGen.current!==g)return;setStats((prev)=>new Map(prev).set(path4,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:active2.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=active2.length>0?`${spark(nodes)} ${summary(all)}`:limits,togglePause=import_react83.useCallback(()=>{let next2=!deleg?.paused;gw.request("delegation.pause",{paused:next2}).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_react83.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}`,join15=(...parts2)=>parts2.filter(Boolean).join(" "),sw=props.onSwitchProfile?pair("s","switch"):"",profilesHint=`${pWide?join15("[\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"?join15("[\u2191\u2193] nav",pair(keys.print("list.activate"),"detail"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("list.delete"),"delete")):join15(pair(keys.print("list.activate"),"actions"),sw,"[Esc] back",pair(keys.print("list.delete"),"delete"))} ${pair("Tab",wide?"\u2192 delegation":"\u2194 delegation")}`,delegKeys=join15("[\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 (${active2.length})`,focus:pane==="deleg",grow:2,error:delegErr,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"]})]}),active2.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:active2.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:active2[dSel]?$jsx(DelegDetail,{r:active2[dSel],live:liveMap.get(active2[dSel].subagent_id),agg:aggOf.get(active2[dSel].subagent_id),now}):null})]},"body")]}):null]}),$jsx(HintBar,{raw:footerHint})]})});var import_react87=__toESM(require_react_production(),1);var import_react85=__toESM(require_react_production(),1);var exports_cron_model={};__export(exports_cron_model,{validate:()=>validate2,split:()=>split,payload:()=>payload,normalize:()=>normalize,has:()=>has,draft:()=>draft,cronModel:()=>exports_cron_model,base:()=>base2});var arr=(value)=>{if(Array.isArray(value))return value.filter(Boolean);if(typeof value==="string")return split(value);return},split=(value)=>value.split(/[\n,]/).map((s)=>s.trim()).filter(Boolean),base2=(value)=>value.trim().replace(/\/+$/,""),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,provider:j2.provider,model:j2.model,base_url:j2.base_url,no_agent:j2.no_agent,attach_to_session:j2.attach_to_session,skills:arr(j2.skills),context_from:arr(j2.context_from),enabled_toolsets:arr(j2.enabled_toolsets),workdir:j2.workdir,script:j2.script}),draft=(j2)=>({id:j2?.id??"",name:j2?.name??"",schedule:j2?.schedule??"",prompt:j2?.prompt??"",script:j2?.script??"",no_agent:!!j2?.no_agent,attach_to_session:!!j2?.attach_to_session,skills:j2?.skills?.join(", ")??"",provider:j2?.provider??"",model:j2?.model??"",base_url:j2?.base_url??"",context_from:j2?.context_from?.join(", ")??"",enabled_toolsets:j2?.enabled_toolsets?.join(", ")??"",workdir:j2?.workdir??"",deliver:j2?.deliver??"local",repeat:""}),has=(d2)=>{if(d2.no_agent)return d2.script.trim().length>0;return d2.prompt.trim().length>0||d2.script.trim().length>0||split(d2.skills).length>0},validate2=(d2)=>{if(!d2.schedule.trim())return"Schedule is required";if(!has(d2))return d2.no_agent?"No-agent jobs require a script":"Agent jobs require a prompt, skill, or script";if(d2.repeat.trim()&&(!Number.isInteger(Number(d2.repeat.trim()))||Number(d2.repeat.trim())<=0))return"Repeat must be a positive integer";if(base2(d2.base_url)){if(!URL.canParse(base2(d2.base_url)))return"Base URL must be a valid URL"}return null},payload=(action,d2,opts)=>{let out={action,name:action==="add"?d2.name.trim():d2.id,schedule:d2.schedule.trim(),prompt:d2.prompt.trim()},allowed=(key3)=>opts?.fields===void 0||opts.fields.has(key3);if(allowed("deliver"))out.deliver=d2.deliver.trim()||"local";if(allowed("no_agent"))out.no_agent=d2.no_agent;if(allowed("attach_to_session"))out.attach_to_session=d2.attach_to_session;let add=(key3,value)=>{if(value!==void 0)out[key3]=value},scalar2=(value)=>value.trim()||(action==="update"?"":void 0),skills=split(d2.skills),refs2=split(d2.context_from),tools=split(d2.enabled_toolsets);if(allowed("skills")&&(action==="update"||skills.length>0))add("skills",skills);if(allowed("context_from")&&(action==="update"||refs2.length>0))add("context_from",refs2);if(allowed("enabled_toolsets")&&(action==="update"||tools.length>0))add("enabled_toolsets",tools);if(allowed("provider"))add("provider",scalar2(d2.provider));if(allowed("model"))add("model",scalar2(d2.model));if(allowed("base_url"))add("base_url",base2(d2.base_url)||(action==="update"?"":void 0));if(allowed("script"))add("script",scalar2(d2.script));if(allowed("workdir"))add("workdir",scalar2(d2.workdir));if(allowed("repeat"))add("repeat",d2.repeat.trim()?Number(d2.repeat.trim()):action==="update"?0:void 0);return out};var FIELDS=["name","schedule","prompt","script","no_agent","attach_to_session","skills","provider","model","base_url","context_from","enabled_toolsets","workdir","deliver","repeat","submit"],LABELS2={id:"ID",name:"Name",schedule:"Schedule",prompt:"Prompt",script:"Script",no_agent:"No agent",attach_to_session:"Attach session",skills:"Skills",provider:"Provider",model:"Model",base_url:"Base URL",context_from:"Context from",enabled_toolsets:"Toolsets",workdir:"Workdir",deliver:"Deliver",repeat:"Repeat",submit:""},HELP={name:"blank lets the server derive one on create",schedule:"cron expr, ISO timestamp, or 'every 30m'",prompt:"required for agent jobs unless skills or script are set",script:"required when no_agent is on",attach_to_session:"continuable job deliveries; no effect with local delivery",skills:"comma or newline separated",context_from:"job ids; not returned by old gateways",enabled_toolsets:"comma or newline separated",deliver:"local, all, origin, or gateway target",repeat:"positive integer; blank uses gateway default"},multiline=new Set(["prompt","skills","context_from","enabled_toolsets"]),bools=new Set(["no_agent","attach_to_session"]),basic=new Set(["name","schedule","prompt","submit"]),editable=(f,p)=>f!=="submit"&&f!=="id"&&f!=="name"||p.mode==="create"&&f==="name",available=(f,p)=>basic.has(f)||p.fields===void 0||p.fields.has(f),value=(d2,f)=>f==="submit"?"":d2[f],height=(f)=>multiline.has(f)?3:1,set2=(d2,f,v2)=>{if(f==="submit")return d2;return{...d2,[f]:v2}},FieldRow=(p)=>{let f=p.field,val=value(p.draft,f),fg2=p.disabled?p.theme.textMuted:p.active?p.theme.accent:p.theme.text;if(f==="submit")return $jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:p.active?p.theme.accent:p.theme.textMuted,children:"[Ctrl+Enter] save"})});return $jsxs("box",{minHeight:height(f),flexDirection:"row",marginTop:f==="prompt"?1:0,children:[$jsx("box",{width:16,flexShrink:0,children:$jsxs("text",{fg:p.active?p.theme.accent:p.theme.textMuted,children:[p.active?"\u25B8 ":" ",LABELS2[f]]})}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[typeof val==="boolean"?$jsx("text",{fg:fg2,children:val?"\u25CF true":"\u25CB false"}):$jsx("box",{height:height(f),overflow:"hidden",backgroundColor:p.active&&!p.disabled?p.theme.backgroundElement:void 0,children:$jsx("text",{wrapMode:multiline.has(f)?"word":void 0,fg:fg2,children:val||(p.active?"\u2588":"\u2014")})}),p.active&&HELP[f]?$jsx("text",{fg:p.theme.textMuted,children:HELP[f]}):null]})]})},CronEditor=(props)=>{let theme=useTheme().theme,[draft2,setDraft]=import_react85.useState(props.initial),[field,setField]=import_react85.useState("schedule"),[err,setErr]=import_react85.useState(null),fields=FIELDS.filter((f)=>available(f,props)),move=(dir)=>{let i=fields.indexOf(field);setField(fields[(i+dir+fields.length)%fields.length]??"schedule")},submit2=()=>{let msg=exports_cron_model.validate(draft2);if(msg){setErr(msg);return}props.done({draft:draft2})},append=(raw)=>setDraft((d2)=>{let v2=value(d2,field);if(typeof v2!=="string")return d2;return set2(d2,field,v2+raw)}),back=()=>setDraft((d2)=>{let v2=value(d2,field);if(typeof v2!=="string")return d2;return set2(d2,field,v2.slice(0,-1))});return useKeyboard((key3)=>{if(key3.name==="escape")return props.done(null);if(key3.name==="tab")return move(key3.shift?-1:1);if(key3.ctrl&&key3.name==="return")return submit2();if(key3.name==="up")return move(-1);if(key3.name==="down")return move(1);if(field==="submit"&&key3.name==="return")return submit2();if(!editable(field,props))return;if(bools.has(field)&&(key3.name==="space"||key3.name==="return")){setDraft((d2)=>set2(d2,field,!value(d2,field)));return}if(bools.has(field))return;if(key3.name==="backspace")return back();if(key3.name==="return"){if(multiline.has(field))return append(`
4134
- `);return move(1)}if(key3.raw&&key3.raw.length===1&&key3.raw>=" ")return append(key3.raw)}),$jsxs("box",{flexDirection:"column",width:84,maxHeight:34,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:props.mode==="create"?"New Cron Job":"Edit Cron Job"})})}),props.fields?.size===0?$jsx("text",{fg:theme.warning,children:"Current gateway only accepts name, schedule, and prompt."}):null,$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",children:fields.map((f)=>$jsx(FieldRow,{field:f,draft:draft2,active:f===field,disabled:!1,theme},f))})}),err?$jsx("text",{fg:theme.error,children:err}):null,$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Tab field \xB7 \u2191\u2193 field \xB7 Ctrl+Enter save \xB7 Esc cancel"})})]})};function openCronEditor(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(CronEditor,{mode:opts.mode,initial:opts.initial,fields:opts.fields,done:(r)=>{resolve4(r),dialog.clear()}}),()=>resolve4(null),{ownCancel:!0})})}var FIELDS2=["script","no_agent","attach_to_session","skills","provider","model","base_url","context_from","enabled_toolsets","workdir","deliver","repeat"],caps=(r)=>{let actions=new Set(r.actions??[]),fields=new Set((r.fields??[]).filter((f)=>FIELDS2.includes(f))),broad=r.capabilities?.advanced===!0||r.capabilities?.advanced_create===!0;return{update:r.capabilities?.update===!0||actions.has("update"),fields:broad&&fields.size===0?void 0:fields}},sec2=(iso2)=>iso2?new Date(iso2).getTime()/1000:null,last3=(iso2)=>{let t2=sec2(iso2);return t2?ago(t2):"\u2014"},next2=(iso2)=>{let t2=sec2(iso2);return t2?until(t2):"\u2014"},JobRow=import_react87.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: ${last3(j2.last_run)}`}),$jsx(Col,{w:16,fg:j2.enabled?theme.text:theme.textMuted,children:`next: ${j2.enabled?next2(j2.next_run):"paused"}`})]})}),DetailPanel=import_react87.memo((props)=>{let theme=useTheme().theme,j2=props.job,[output,setOutput]=import_react87.useState(null);return import_react87.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?`${last3(j2.last_run)} \xB7 ${j2.last_status??"?"}`:"never",j2.last_status==="error"?theme.error:void 0],["Next Run",j2.enabled?next2(j2.next_run):"paused"],["Provider",j2.provider],["Model",j2.model],["Base URL",j2.base_url],["No Agent",j2.no_agent?"true":void 0],["Attach Session",j2.attach_to_session?"true":void 0],["Skills",j2.skills?.length?j2.skills.join(", "):void 0],["Context",j2.context_from?.length?j2.context_from.join(", "):void 0],["Toolsets",j2.enabled_toolsets?.length?j2.enabled_toolsets.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_react87.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),[jobs,setJobs]=import_react87.useState([]),[cap4,setCap]=import_react87.useState({update:!1,fields:new Set}),[sel,setSel]=import_react87.useState(0),[err,setErr]=import_react87.useState(null),[reloadKey,setReloadKey]=import_react87.useState(0),loadGen=import_react87.useRef(0),live=import_react87.useRef({jobs,sel});live.current={jobs,sel};let load4=import_react87.useCallback(()=>{let gen=++loadGen.current;gw.request("cron.manage",{action:"list"}).then((res)=>{if(loadGen.current!==gen)return;setJobs((res.jobs??[]).map(exports_cron_model.normalize)),setCap(caps(res)),setErr(null),setReloadKey((k2)=>k2+1)}).catch((e)=>{if(loadGen.current===gen)setErr(e instanceof Error?e.message:String(e))})},[gw]);import_react87.useEffect(()=>{return load4(),()=>{loadGen.current++}},[load4]);let create=import_react87.useCallback(async()=>{let r=await openCronEditor(dialog,{mode:"create",initial:exports_cron_model.draft(),fields:cap4.fields});if(!r)return;gw.request("cron.manage",exports_cron_model.payload("add",r.draft,{fields:cap4.fields})).then(()=>{toast.show({variant:"success",message:"Job created"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4,cap4.fields]),edit=import_react87.useCallback(async()=>{let j2=live.current.jobs[live.current.sel];if(j2&&!cap4.update){toast.show({variant:"warning",message:"Current gateway has no cron.manage update; this job is read-only here."});return}let r=await openCronEditor(dialog,{mode:j2?"edit":"create",initial:exports_cron_model.draft(j2??void 0),fields:cap4.fields});if(!r)return;let action=j2&&cap4.update?"update":"add";gw.request("cron.manage",exports_cron_model.payload(action,r.draft,{fields:cap4.fields})).then(()=>{toast.show({variant:"success",message:action==="add"?"Job created":"Job updated"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4,cap4]),toggle=import_react87.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_react87.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,onActivate:edit,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.activate"),"advanced"],[keys.print("list.toggle"),"pause/resume"],[keys.print("list.delete"),"delete"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react92=__toESM(require_react_production(),1);import{Database as Database4}from"bun:sqlite";import{existsSync as existsSync19,readdirSync as readdirSync9,statSync as statSync8,openSync as openSync3,readSync as readSync3,closeSync as closeSync3,readFileSync as readFileSync12}from"fs";import{relative as pathRelative,resolve as pathResolve}from"path";import{Database as Database3}from"bun:sqlite";import{closeSync as closeSync2,fstatSync,openSync as openSync2,readSync as readSync2,statSync as statSync7}from"fs";var DEFAULT_BUSY_TIMEOUT_MS=120000,BUSY_RETRIES=5,BUSY_BUDGET_MS=5000,BUSY_MIN_MS=20,BUSY_MAX_MS=150,handles=new Map,timeout=()=>{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},busy=(err)=>{let msg=String(err?.message??err).toLowerCase();return msg.includes("database is locked")||msg.includes("database is busy")},nap=()=>{let ms2=BUSY_MIN_MS+Math.random()*(BUSY_MAX_MS-BUSY_MIN_MS);Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,ms2)},boundary=(db,sql)=>{let attempts=Math.max(1,Math.min(BUSY_RETRIES+1,Math.ceil(BUSY_BUDGET_MS/timeout())));for(let i=0;i<attempts;i++)try{db.exec(sql);return}catch(err){if(!busy(err)||i===attempts-1)throw err;nap()}},pathOf=(root3,board)=>`${root3.replace(/[\\/]+$/,"")}/${board==="default"?"kanban.db":`kanban/boards/${board}/kanban.db`}`,open2=(root3,board)=>{let path4=pathOf(root3,board),cached2=handles.get(path4),ino=(()=>{try{return statSync7(path4).ino}catch{return null}})();if(cached2?.ino===ino)return cached2.db;if(cached2)cached2.db.close(),handles.delete(path4);if(ino===null)return null;try{let db=new Database3(path4);db.exec(`PRAGMA busy_timeout=${timeout()}`);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(";")),handles.set(path4,{db,ino}),db}catch{return null}},check=(db)=>{try{let row3=db.query("PRAGMA database_list").get(),path4=String(row3?.file??row3?.[2]??"");if(!path4)return;let page=db.query("PRAGMA page_size").get(),size=Number(Object.values(page??{})[0]);if(!size)return;let fd=openSync2(path4,"r");try{let buf=Buffer.alloc(4);if(readSync2(fd,buf,0,4,28)<4)return;let header=buf.readUInt32BE(0);if(!header)return;let actual=Math.floor(fstatSync(fd).size/size);if(actual<header)throw Error(`torn-extend detected: page count mismatch on ${path4}: header claims ${header} pages, file has ${actual} pages`)}finally{closeSync2(fd)}}catch(err){if(err instanceof Error&&err.message.startsWith("torn-extend detected"))throw err}};function writeTxn(db,fn){boundary(db,"BEGIN IMMEDIATE");let out=(()=>{try{return fn()}catch(err){try{db.exec("ROLLBACK")}catch{}throw err}})();try{boundary(db,"COMMIT")}catch(err){try{db.exec("ROLLBACK")}catch{}throw err}return check(db),out}function patchAt(root3,board,id,patch){let db=open2(root3,board);if(!db)return!1;if(!db.query("SELECT 1 FROM tasks WHERE id = ?").get(id))return!1;let priority=patch.priority===void 0?void 0:Math.max(0,Math.min(9,Math.floor(patch.priority))),sets=[],vals=[];if(patch.title!==void 0){let title=patch.title.trim();if(!title)throw Error("title cannot be empty");sets.push("title = ?"),vals.push(title)}if(patch.body!==void 0)sets.push("body = ?"),vals.push(patch.body);if(priority===void 0&&sets.length===0)return!0;return writeTxn(db,()=>{if(priority!==void 0)db.query("UPDATE tasks SET priority = ? WHERE id = ?").run(priority,id),db.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'reprioritized', ?, ?)").run(id,JSON.stringify({priority}),Math.floor(Date.now()/1000));if(sets.length>0)db.query(`UPDATE tasks SET ${sets.join(", ")} WHERE id = ?`).run(...vals,id),db.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'edited', NULL, ?)").run(id,Math.floor(Date.now()/1000))}),!0}function resetWrites(){for(let handle of handles.values())handle.db.close();handles.clear()}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}$/,kanbanRoot=()=>{let pin=(process.env.HERMES_KANBAN_HOME??"").trim();if(pin)return pin.replace(/[\\/]+$/,"");return hermesPath("").replace(/[\\/]+$/,"").replace(/[\\/]profiles[\\/][^\\/]+$/,"")},kp=(rel2)=>`${kanbanRoot()}/${rel2}`,resolve8=()=>{let env2=(process.env.HERMES_KANBAN_BOARD??"").trim().toLowerCase();if(SLUG.test(env2))return env2;try{let txt=readFileSync12(kp("kanban/current"),"utf-8").trim().toLowerCase();if(SLUG.test(txt))return txt}catch{}return DEFAULT2},slug=resolve8(),handles2=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 root3=attachmentsRoot(s),path4=pathResolve(raw);return path4===root3||path4.startsWith(`${root3}/`)?path4:null},attachmentRelPath=(s,path4)=>path4?pathRelative(attachmentsRoot(s),path4):null,pair=(s)=>{let cached2=handles2.get(s);if(cached2)return cached2;let next3={ro:null};return handles2.set(s,next3),next3},emptyBoard=()=>new Map(STATUSES.map((k2)=>[k2,[]])),boardErr=(kind2,path4,msg)=>({kind:kind2,path:path4,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=(path4)=>{let st;try{st=statSync8(path4)}catch(e){return e.code==="ENOENT"?null:boardErr("unreadable",path4,String(e.message??e))}if(st.size===0)return null;let fd=-1;try{fd=openSync3(path4,"r");let head=Buffer.alloc(SQLITE_HEADER.length),n=readSync3(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",path4,`invalid SQLite header; first_32=${head.subarray(0,Math.min(32,n)).toString("hex").match(/../g)?.join(" ")??""}`)}catch(e){return boardErr("unreadable",path4,String(e.message??e))}finally{if(fd>=0)try{closeSync3(fd)}catch{}}},dbOf=(s)=>{let h2=pair(s);if(h2.ro)return h2.ro;let path4=dbPath(s);if(!existsSync19(path4))return errors2.delete(s),null;let hdr=headerError(path4);if(hdr)return errors2.set(s,hdr),null;try{h2.ro=new Database4(path4,{readwrite:!0,create:!1}),errors2.delete(s)}catch(e){h2.ro=null,errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path4,String(e.message??e)))}return h2.ro},resetKanban=()=>{for(let h2 of handles2.values())h2.ro?.close();handles2.clear(),resetWrites(),errors2.clear(),slug=resolve8()};function corruptBackupsOf(s){let dir=dbDir(s)||kanbanRoot();try{return readdirSync9(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(existsSync19(dir))for(let e of readdirSync9(dir,{withFileTypes:!0})){if(!e.isDirectory()||!SLUG.test(e.name))continue;let name=e.name;try{let meta=JSON.parse(readFileSync12(`${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 set3=new Set;try{for(let r of conn2.query("PRAGMA table_info(tasks)").all())set3.add(r.name)}catch{}return cols.set(conn2,set3),set3},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,"project_id"),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"),selectCol(have,"block_kind"),selectCol(have,"block_recurrences"),`${AT} AS updated_at`].join(", "),BLOCK_KINDS=new Set(["dependency","needs_input","capability","transient"]),parseKind=(raw)=>typeof raw==="string"&&BLOCK_KINDS.has(raw)?raw:null,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,project_id:r.project_id??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,block_kind:parseKind(r.block_kind),block_recurrences:Math.max(0,Number(r.block_recurrences)||0)}),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,payload2=null;if(raw)try{payload2=JSON.parse(raw)}catch{payload2=raw}return{id:Number(r.id),kind:String(r.kind??""),payload:payload2,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),path4=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,path4),path:path4}};function boardOf(s){let out=emptyBoard(),conn2=dbOf(s);if(!conn2)return out;try{let rows3=conn2.query(`SELECT ${taskColumns(colsOf(conn2))}
4133
+ 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_react83.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_react83.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_react83.useRef(0);import_react83.useEffect(()=>{let path4=selected?.path;if(!path4||stats.has(path4))return;let g=++statGen.current;profileStats(path4).then((s)=>{if(statGen.current!==g)return;setStats((prev)=>new Map(prev).set(path4,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:active2.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=active2.length>0?`${spark(nodes)} ${summary(all)}`:limits,togglePause=import_react83.useCallback(()=>{let next2=!deleg?.paused;gw.request("delegation.pause",{paused:next2}).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_react83.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}`,join15=(...parts2)=>parts2.filter(Boolean).join(" "),sw=props.onSwitchProfile?pair("s","switch"):"",profilesHint=`${pWide?join15("[\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"?join15("[\u2191\u2193] nav",pair(keys.print("list.activate"),"detail"),sw,pair(keys.print("list.new"),"new"),pair(keys.print("list.delete"),"delete")):join15(pair(keys.print("list.activate"),"actions"),sw,"[Esc] back",pair(keys.print("list.delete"),"delete"))} ${pair("Tab",wide?"\u2192 delegation":"\u2194 delegation")}`,delegKeys=join15("[\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 (${active2.length})`,focus:pane==="deleg",grow:2,error:delegErr,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"]})]}),active2.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:active2.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:active2[dSel]?$jsx(DelegDetail,{r:active2[dSel],live:liveMap.get(active2[dSel].subagent_id),agg:aggOf.get(active2[dSel].subagent_id),now}):null})]},"body")]}):null]}),$jsx(HintBar,{raw:footerHint})]})});var import_react87=__toESM(require_react_production(),1);var import_react85=__toESM(require_react_production(),1);var exports_cron_model={};__export(exports_cron_model,{validate:()=>validate2,split:()=>split,payload:()=>payload2,normalize:()=>normalize,has:()=>has,draft:()=>draft,cronModel:()=>exports_cron_model,base:()=>base2});var arr=(value)=>{if(Array.isArray(value))return value.filter(Boolean);if(typeof value==="string")return split(value);return},split=(value)=>value.split(/[\n,]/).map((s)=>s.trim()).filter(Boolean),base2=(value)=>value.trim().replace(/\/+$/,""),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,provider:j2.provider,model:j2.model,base_url:j2.base_url,no_agent:j2.no_agent,attach_to_session:j2.attach_to_session,skills:arr(j2.skills),context_from:arr(j2.context_from),enabled_toolsets:arr(j2.enabled_toolsets),workdir:j2.workdir,script:j2.script}),draft=(j2)=>({id:j2?.id??"",name:j2?.name??"",schedule:j2?.schedule??"",prompt:j2?.prompt??"",script:j2?.script??"",no_agent:!!j2?.no_agent,attach_to_session:!!j2?.attach_to_session,skills:j2?.skills?.join(", ")??"",provider:j2?.provider??"",model:j2?.model??"",base_url:j2?.base_url??"",context_from:j2?.context_from?.join(", ")??"",enabled_toolsets:j2?.enabled_toolsets?.join(", ")??"",workdir:j2?.workdir??"",deliver:j2?.deliver??"local",repeat:""}),has=(d2)=>{if(d2.no_agent)return d2.script.trim().length>0;return d2.prompt.trim().length>0||d2.script.trim().length>0||split(d2.skills).length>0},validate2=(d2)=>{if(!d2.schedule.trim())return"Schedule is required";if(!has(d2))return d2.no_agent?"No-agent jobs require a script":"Agent jobs require a prompt, skill, or script";if(d2.repeat.trim()&&(!Number.isInteger(Number(d2.repeat.trim()))||Number(d2.repeat.trim())<=0))return"Repeat must be a positive integer";if(base2(d2.base_url)){if(!URL.canParse(base2(d2.base_url)))return"Base URL must be a valid URL"}return null},payload2=(action,d2,opts)=>{let out={action,name:action==="add"?d2.name.trim():d2.id,schedule:d2.schedule.trim(),prompt:d2.prompt.trim()},allowed=(key3)=>opts?.fields===void 0||opts.fields.has(key3);if(allowed("deliver"))out.deliver=d2.deliver.trim()||"local";if(allowed("no_agent"))out.no_agent=d2.no_agent;if(allowed("attach_to_session"))out.attach_to_session=d2.attach_to_session;let add=(key3,value)=>{if(value!==void 0)out[key3]=value},scalar2=(value)=>value.trim()||(action==="update"?"":void 0),skills=split(d2.skills),refs2=split(d2.context_from),tools=split(d2.enabled_toolsets);if(allowed("skills")&&(action==="update"||skills.length>0))add("skills",skills);if(allowed("context_from")&&(action==="update"||refs2.length>0))add("context_from",refs2);if(allowed("enabled_toolsets")&&(action==="update"||tools.length>0))add("enabled_toolsets",tools);if(allowed("provider"))add("provider",scalar2(d2.provider));if(allowed("model"))add("model",scalar2(d2.model));if(allowed("base_url"))add("base_url",base2(d2.base_url)||(action==="update"?"":void 0));if(allowed("script"))add("script",scalar2(d2.script));if(allowed("workdir"))add("workdir",scalar2(d2.workdir));if(allowed("repeat"))add("repeat",d2.repeat.trim()?Number(d2.repeat.trim()):action==="update"?0:void 0);return out};var FIELDS=["name","schedule","prompt","script","no_agent","attach_to_session","skills","provider","model","base_url","context_from","enabled_toolsets","workdir","deliver","repeat","submit"],LABELS2={id:"ID",name:"Name",schedule:"Schedule",prompt:"Prompt",script:"Script",no_agent:"No agent",attach_to_session:"Attach session",skills:"Skills",provider:"Provider",model:"Model",base_url:"Base URL",context_from:"Context from",enabled_toolsets:"Toolsets",workdir:"Workdir",deliver:"Deliver",repeat:"Repeat",submit:""},HELP={name:"blank lets the server derive one on create",schedule:"cron expr, ISO timestamp, or 'every 30m'",prompt:"required for agent jobs unless skills or script are set",script:"required when no_agent is on",attach_to_session:"continuable job deliveries; no effect with local delivery",skills:"comma or newline separated",context_from:"job ids; not returned by old gateways",enabled_toolsets:"comma or newline separated",deliver:"local, all, origin, or gateway target",repeat:"positive integer; blank uses gateway default"},multiline=new Set(["prompt","skills","context_from","enabled_toolsets"]),bools=new Set(["no_agent","attach_to_session"]),basic=new Set(["name","schedule","prompt","submit"]),editable=(f,p)=>f!=="submit"&&f!=="id"&&f!=="name"||p.mode==="create"&&f==="name",available=(f,p)=>basic.has(f)||p.fields===void 0||p.fields.has(f),value=(d2,f)=>f==="submit"?"":d2[f],height=(f)=>multiline.has(f)?3:1,set2=(d2,f,v2)=>{if(f==="submit")return d2;return{...d2,[f]:v2}},FieldRow=(p)=>{let f=p.field,val=value(p.draft,f),fg2=p.disabled?p.theme.textMuted:p.active?p.theme.accent:p.theme.text;if(f==="submit")return $jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:p.active?p.theme.accent:p.theme.textMuted,children:"[Ctrl+Enter] save"})});return $jsxs("box",{minHeight:height(f),flexDirection:"row",marginTop:f==="prompt"?1:0,children:[$jsx("box",{width:16,flexShrink:0,children:$jsxs("text",{fg:p.active?p.theme.accent:p.theme.textMuted,children:[p.active?"\u25B8 ":" ",LABELS2[f]]})}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[typeof val==="boolean"?$jsx("text",{fg:fg2,children:val?"\u25CF true":"\u25CB false"}):$jsx("box",{height:height(f),overflow:"hidden",backgroundColor:p.active&&!p.disabled?p.theme.backgroundElement:void 0,children:$jsx("text",{wrapMode:multiline.has(f)?"word":void 0,fg:fg2,children:val||(p.active?"\u2588":"\u2014")})}),p.active&&HELP[f]?$jsx("text",{fg:p.theme.textMuted,children:HELP[f]}):null]})]})},CronEditor=(props)=>{let theme=useTheme().theme,[draft2,setDraft]=import_react85.useState(props.initial),[field,setField]=import_react85.useState("schedule"),[err,setErr]=import_react85.useState(null),fields=FIELDS.filter((f)=>available(f,props)),move=(dir)=>{let i=fields.indexOf(field);setField(fields[(i+dir+fields.length)%fields.length]??"schedule")},submit2=()=>{let msg=exports_cron_model.validate(draft2);if(msg){setErr(msg);return}props.done({draft:draft2})},append=(raw)=>setDraft((d2)=>{let v2=value(d2,field);if(typeof v2!=="string")return d2;return set2(d2,field,v2+raw)}),back=()=>setDraft((d2)=>{let v2=value(d2,field);if(typeof v2!=="string")return d2;return set2(d2,field,v2.slice(0,-1))});return useKeyboard((key3)=>{if(key3.name==="escape")return props.done(null);if(key3.name==="tab")return move(key3.shift?-1:1);if(key3.ctrl&&key3.name==="return")return submit2();if(key3.name==="up")return move(-1);if(key3.name==="down")return move(1);if(field==="submit"&&key3.name==="return")return submit2();if(!editable(field,props))return;if(bools.has(field)&&(key3.name==="space"||key3.name==="return")){setDraft((d2)=>set2(d2,field,!value(d2,field)));return}if(bools.has(field))return;if(key3.name==="backspace")return back();if(key3.name==="return"){if(multiline.has(field))return append(`
4134
+ `);return move(1)}if(key3.raw&&key3.raw.length===1&&key3.raw>=" ")return append(key3.raw)}),$jsxs("box",{flexDirection:"column",width:84,maxHeight:34,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:props.mode==="create"?"New Cron Job":"Edit Cron Job"})})}),props.fields?.size===0?$jsx("text",{fg:theme.warning,children:"Current gateway only accepts name, schedule, and prompt."}):null,$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",children:fields.map((f)=>$jsx(FieldRow,{field:f,draft:draft2,active:f===field,disabled:!1,theme},f))})}),err?$jsx("text",{fg:theme.error,children:err}):null,$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Tab field \xB7 \u2191\u2193 field \xB7 Ctrl+Enter save \xB7 Esc cancel"})})]})};function openCronEditor(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(CronEditor,{mode:opts.mode,initial:opts.initial,fields:opts.fields,done:(r)=>{resolve4(r),dialog.clear()}}),()=>resolve4(null),{ownCancel:!0})})}var FIELDS2=["script","no_agent","attach_to_session","skills","provider","model","base_url","context_from","enabled_toolsets","workdir","deliver","repeat"],caps=(r)=>{let actions=new Set(r.actions??[]),fields=new Set((r.fields??[]).filter((f)=>FIELDS2.includes(f))),broad=r.capabilities?.advanced===!0||r.capabilities?.advanced_create===!0;return{update:r.capabilities?.update===!0||actions.has("update"),fields:broad&&fields.size===0?void 0:fields}},sec2=(iso2)=>iso2?new Date(iso2).getTime()/1000:null,last3=(iso2)=>{let t2=sec2(iso2);return t2?ago(t2):"\u2014"},next2=(iso2)=>{let t2=sec2(iso2);return t2?until(t2):"\u2014"},JobRow=import_react87.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: ${last3(j2.last_run)}`}),$jsx(Col,{w:16,fg:j2.enabled?theme.text:theme.textMuted,children:`next: ${j2.enabled?next2(j2.next_run):"paused"}`})]})}),DetailPanel=import_react87.memo((props)=>{let theme=useTheme().theme,j2=props.job,[output,setOutput]=import_react87.useState(null);return import_react87.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?`${last3(j2.last_run)} \xB7 ${j2.last_status??"?"}`:"never",j2.last_status==="error"?theme.error:void 0],["Next Run",j2.enabled?next2(j2.next_run):"paused"],["Provider",j2.provider],["Model",j2.model],["Base URL",j2.base_url],["No Agent",j2.no_agent?"true":void 0],["Attach Session",j2.attach_to_session?"true":void 0],["Skills",j2.skills?.length?j2.skills.join(", "):void 0],["Context",j2.context_from?.length?j2.context_from.join(", "):void 0],["Toolsets",j2.enabled_toolsets?.length?j2.enabled_toolsets.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_react87.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),[jobs,setJobs]=import_react87.useState([]),[cap4,setCap]=import_react87.useState({update:!1,fields:new Set}),[sel,setSel]=import_react87.useState(0),[err,setErr]=import_react87.useState(null),[reloadKey,setReloadKey]=import_react87.useState(0),loadGen=import_react87.useRef(0),live=import_react87.useRef({jobs,sel});live.current={jobs,sel};let load4=import_react87.useCallback(()=>{let gen=++loadGen.current;gw.request("cron.manage",{action:"list"}).then((res)=>{if(loadGen.current!==gen)return;setJobs((res.jobs??[]).map(exports_cron_model.normalize)),setCap(caps(res)),setErr(null),setReloadKey((k2)=>k2+1)}).catch((e)=>{if(loadGen.current===gen)setErr(e instanceof Error?e.message:String(e))})},[gw]);import_react87.useEffect(()=>{return load4(),()=>{loadGen.current++}},[load4]);let create=import_react87.useCallback(async()=>{let r=await openCronEditor(dialog,{mode:"create",initial:exports_cron_model.draft(),fields:cap4.fields});if(!r)return;gw.request("cron.manage",exports_cron_model.payload("add",r.draft,{fields:cap4.fields})).then(()=>{toast.show({variant:"success",message:"Job created"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4,cap4.fields]),edit=import_react87.useCallback(async()=>{let j2=live.current.jobs[live.current.sel];if(j2&&!cap4.update){toast.show({variant:"warning",message:"Current gateway has no cron.manage update; this job is read-only here."});return}let r=await openCronEditor(dialog,{mode:j2?"edit":"create",initial:exports_cron_model.draft(j2??void 0),fields:cap4.fields});if(!r)return;let action=j2&&cap4.update?"update":"add";gw.request("cron.manage",exports_cron_model.payload(action,r.draft,{fields:cap4.fields})).then(()=>{toast.show({variant:"success",message:action==="add"?"Job created":"Job updated"}),load4()}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,dialog,toast,load4,cap4]),toggle=import_react87.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_react87.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,onActivate:edit,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.activate"),"advanced"],[keys.print("list.toggle"),"pause/resume"],[keys.print("list.delete"),"delete"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react92=__toESM(require_react_production(),1);import{Database as Database4}from"bun:sqlite";import{existsSync as existsSync19,readdirSync as readdirSync9,statSync as statSync8,openSync as openSync3,readSync as readSync3,closeSync as closeSync3,readFileSync as readFileSync12}from"fs";import{relative as pathRelative,resolve as pathResolve}from"path";import{Database as Database3}from"bun:sqlite";import{closeSync as closeSync2,fstatSync,openSync as openSync2,readSync as readSync2,statSync as statSync7}from"fs";var DEFAULT_BUSY_TIMEOUT_MS=120000,BUSY_RETRIES=5,BUSY_BUDGET_MS=5000,BUSY_MIN_MS=20,BUSY_MAX_MS=150,handles=new Map,timeout=()=>{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},busy=(err)=>{let msg=String(err?.message??err).toLowerCase();return msg.includes("database is locked")||msg.includes("database is busy")},nap=()=>{let ms2=BUSY_MIN_MS+Math.random()*(BUSY_MAX_MS-BUSY_MIN_MS);Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,ms2)},boundary=(db,sql)=>{let attempts=Math.max(1,Math.min(BUSY_RETRIES+1,Math.ceil(BUSY_BUDGET_MS/timeout())));for(let i=0;i<attempts;i++)try{db.exec(sql);return}catch(err){if(!busy(err)||i===attempts-1)throw err;nap()}},pathOf=(root3,board)=>`${root3.replace(/[\\/]+$/,"")}/${board==="default"?"kanban.db":`kanban/boards/${board}/kanban.db`}`,open2=(root3,board)=>{let path4=pathOf(root3,board),cached2=handles.get(path4),ino=(()=>{try{return statSync7(path4).ino}catch{return null}})();if(cached2?.ino===ino)return cached2.db;if(cached2)cached2.db.close(),handles.delete(path4);if(ino===null)return null;try{let db=new Database3(path4);db.exec(`PRAGMA busy_timeout=${timeout()}`);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(";")),handles.set(path4,{db,ino}),db}catch{return null}},check=(db)=>{try{let row3=db.query("PRAGMA database_list").get(),path4=String(row3?.file??row3?.[2]??"");if(!path4)return;let page=db.query("PRAGMA page_size").get(),size=Number(Object.values(page??{})[0]);if(!size)return;let fd=openSync2(path4,"r");try{let buf=Buffer.alloc(4);if(readSync2(fd,buf,0,4,28)<4)return;let header=buf.readUInt32BE(0);if(!header)return;let actual=Math.floor(fstatSync(fd).size/size);if(actual<header)throw Error(`torn-extend detected: page count mismatch on ${path4}: header claims ${header} pages, file has ${actual} pages`)}finally{closeSync2(fd)}}catch(err){if(err instanceof Error&&err.message.startsWith("torn-extend detected"))throw err}};function writeTxn(db,fn){boundary(db,"BEGIN IMMEDIATE");let out=(()=>{try{return fn()}catch(err){try{db.exec("ROLLBACK")}catch{}throw err}})();try{boundary(db,"COMMIT")}catch(err){try{db.exec("ROLLBACK")}catch{}throw err}return check(db),out}function patchAt(root3,board,id,patch){let db=open2(root3,board);if(!db)return!1;if(!db.query("SELECT 1 FROM tasks WHERE id = ?").get(id))return!1;let priority=patch.priority===void 0?void 0:Math.max(0,Math.min(9,Math.floor(patch.priority))),sets=[],vals=[];if(patch.title!==void 0){let title=patch.title.trim();if(!title)throw Error("title cannot be empty");sets.push("title = ?"),vals.push(title)}if(patch.body!==void 0)sets.push("body = ?"),vals.push(patch.body);if(priority===void 0&&sets.length===0)return!0;return writeTxn(db,()=>{if(priority!==void 0)db.query("UPDATE tasks SET priority = ? WHERE id = ?").run(priority,id),db.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'reprioritized', ?, ?)").run(id,JSON.stringify({priority}),Math.floor(Date.now()/1000));if(sets.length>0)db.query(`UPDATE tasks SET ${sets.join(", ")} WHERE id = ?`).run(...vals,id),db.query("INSERT INTO task_events (task_id, run_id, kind, payload, created_at) VALUES (?, NULL, 'edited', NULL, ?)").run(id,Math.floor(Date.now()/1000))}),!0}function resetWrites(){for(let handle of handles.values())handle.db.close();handles.clear()}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 rec2=r,id=rec2.task_id;if(typeof id!=="string"||!id)return[];let diags=Array.isArray(rec2.diagnostics)?rec2.diagnostics:[];return[{task_id:id,title:typeof rec2.title==="string"?rec2.title:void 0,status:typeof rec2.status==="string"?rec2.status:void 0,assignee:typeof rec2.assignee==="string"?rec2.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}$/,kanbanRoot=()=>{let pin=(process.env.HERMES_KANBAN_HOME??"").trim();if(pin)return pin.replace(/[\\/]+$/,"");return hermesPath("").replace(/[\\/]+$/,"").replace(/[\\/]profiles[\\/][^\\/]+$/,"")},kp=(rel2)=>`${kanbanRoot()}/${rel2}`,resolve8=()=>{let env2=(process.env.HERMES_KANBAN_BOARD??"").trim().toLowerCase();if(SLUG.test(env2))return env2;try{let txt=readFileSync12(kp("kanban/current"),"utf-8").trim().toLowerCase();if(SLUG.test(txt))return txt}catch{}return DEFAULT2},slug=resolve8(),handles2=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 root3=attachmentsRoot(s),path4=pathResolve(raw);return path4===root3||path4.startsWith(`${root3}/`)?path4:null},attachmentRelPath=(s,path4)=>path4?pathRelative(attachmentsRoot(s),path4):null,pair=(s)=>{let cached2=handles2.get(s);if(cached2)return cached2;let next3={ro:null};return handles2.set(s,next3),next3},emptyBoard=()=>new Map(STATUSES.map((k2)=>[k2,[]])),boardErr=(kind2,path4,msg)=>({kind:kind2,path:path4,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=(path4)=>{let st;try{st=statSync8(path4)}catch(e){return e.code==="ENOENT"?null:boardErr("unreadable",path4,String(e.message??e))}if(st.size===0)return null;let fd=-1;try{fd=openSync3(path4,"r");let head=Buffer.alloc(SQLITE_HEADER.length),n=readSync3(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",path4,`invalid SQLite header; first_32=${head.subarray(0,Math.min(32,n)).toString("hex").match(/../g)?.join(" ")??""}`)}catch(e){return boardErr("unreadable",path4,String(e.message??e))}finally{if(fd>=0)try{closeSync3(fd)}catch{}}},dbOf=(s)=>{let h2=pair(s);if(h2.ro)return h2.ro;let path4=dbPath(s);if(!existsSync19(path4))return errors2.delete(s),null;let hdr=headerError(path4);if(hdr)return errors2.set(s,hdr),null;try{h2.ro=new Database4(path4,{readwrite:!0,create:!1}),errors2.delete(s)}catch(e){h2.ro=null,errors2.set(s,boardErr(isCorrupt(e)?"corrupt":"unreadable",path4,String(e.message??e)))}return h2.ro},resetKanban=()=>{for(let h2 of handles2.values())h2.ro?.close();handles2.clear(),resetWrites(),errors2.clear(),slug=resolve8()};function corruptBackupsOf(s){let dir=dbDir(s)||kanbanRoot();try{return readdirSync9(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(existsSync19(dir))for(let e of readdirSync9(dir,{withFileTypes:!0})){if(!e.isDirectory()||!SLUG.test(e.name))continue;let name=e.name;try{let meta=JSON.parse(readFileSync12(`${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 set3=new Set;try{for(let r of conn2.query("PRAGMA table_info(tasks)").all())set3.add(r.name)}catch{}return cols.set(conn2,set3),set3},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,"project_id"),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"),selectCol(have,"block_kind"),selectCol(have,"block_recurrences"),`${AT} AS updated_at`].join(", "),BLOCK_KINDS=new Set(["dependency","needs_input","capability","transient"]),parseKind=(raw)=>typeof raw==="string"&&BLOCK_KINDS.has(raw)?raw:null,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,project_id:r.project_id??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,block_kind:parseKind(r.block_kind),block_recurrences:Math.max(0,Number(r.block_recurrences)||0)}),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,payload3=null;if(raw)try{payload3=JSON.parse(raw)}catch{payload3=raw}return{id:Number(r.id),kind:String(r.kind??""),payload:payload3,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),path4=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,path4),path:path4}};function boardOf(s){let out=emptyBoard(),conn2=dbOf(s);if(!conn2)return out;try{let rows3=conn2.query(`SELECT ${taskColumns(colsOf(conn2))}
4135
4135
  FROM tasks WHERE status != 'archived'
4136
4136
  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),latest3=latestSummary(conn2,id);return{...toTask(row3),parents,children:children2,comments,runs,events,attachments,latest_summary:latest3}}catch{return null}}var runsOf=(conn2,id)=>{try{return conn2.query(`SELECT id, profile, status, outcome, started_at, ended_at,
4137
4137
  summary, error, worker_pid
@@ -4153,7 +4153,7 @@ Moves to 'archived' and ends any open run. Children stay; their dependency on th
4153
4153
  Reset these slots to auto so they follow the main model?`,yes:"reset stale",no:"keep"})){toast.show({variant:"warning",message:`Aux still pinned to another provider: ${names}. Press X to reset all to auto.`});return}for(let slot of stale){let r=await resetAux(gw,slot.key);if(r.failed.length){toast.show({variant:"error",message:`${slot.label}: ${r.failed.map((f)=>f.err).join("; ")}`});return}}toast.show({variant:"success",message:`Reset ${stale.length} aux slot${stale.length===1?"":"s"} \u2192 auto`}),load4()};openModelPicker(dialog,gw,{title:s.kind==="main"?"Set main model":`Set auxiliary \xB7 ${s.label}`,onApply:async(prov,model)=>{let token=dialog.version(),r=await assign(gw,s.key,prov,model);if(r.failed.length)return toast.show({variant:"error",message:r.failed.map((f)=>f.err).join("; ")});if(toast.show({variant:"success",message:s.kind==="main"?`main \u2192 ${prov} \xB7 ${model}`:`${s.key} \u2192 ${prov} \xB7 ${model}`}),r.warning)toast.show({variant:"warning",message:r.warning});if(load4(),s.kind==="main"&&dialog.version()===token)await warnStaleAux(prov)}})},[gw,dialog,toast,load4,managed,raw]),unset=import_react97.useCallback((s)=>{if(managed||s.kind!=="aux"||s.auto)return;resetAux(gw,s.key).then((r)=>{if(r.failed.length)return toast.show({variant:"error",message:r.failed.map((f)=>f.err).join("; ")});toast.show({variant:"success",message:`${s.key} \u2192 auto`}),load4()})},[gw,toast,load4,managed]),unsetAll=import_react97.useCallback(()=>openConfirm(dialog,{title:"Reset all auxiliary slots to auto?",body:`${AUX_TASKS.length} slots. Each falls back to the main model.`,yes:"reset",danger:!0}).then((ok)=>{if(!ok)return;resetAux(gw,"all").then((r)=>{if(r.failed.length)return toast.show({variant:"error",message:`${r.failed.length} failed`});toast.show({variant:"success",message:"All auxiliary slots \u2192 auto"}),load4()})}),[gw,dialog,toast,load4]),keys=useKeys();if(useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(keys.match("config.mode",key3)&&!editing&&!searching){setMode((m2)=>m2==="form"?"yaml":"form");return}if(keys.match("config.save",key3))return void save2();if(mode2==="yaml"){if(key3.name==="backspace"){loads.current++,setYaml((prev)=>prev.slice(0,-1));return}if(key3.name==="return"){loads.current++,setYaml((prev)=>prev+`
4154
4154
  `);return}if(key3.raw&&key3.raw.length===1&&key3.raw>=" "){loads.current++,setYaml((prev)=>prev+key3.raw);return}return}if(searching){if(key3.name==="escape"){setSearching(!1),setQuery(""),setCursor(0);return}if(key3.name==="backspace"){setQuery((prev)=>prev.slice(0,-1)),setCursor(0);return}if(key3.name==="up"){setCursor((c)=>Math.max(0,c-1));return}if(key3.name==="down"){setCursor((c)=>Math.min(count3-1,c+1));return}if(key3.raw&&key3.raw.length===1&&key3.raw>=" "){setQuery((prev)=>prev+key3.raw),setCursor(0);return}return}if(editing){let f2=fields[cursor];if(key3.name==="escape"){if(setEditing(!1),setBuf(""),f2)setErr((e)=>{let{[f2.key]:_2,...rest}=e;return rest});return}if(key3.name==="return"){if(f2){let msg=check2(f2.key,buf);if(msg){setErr((e)=>({...e,[f2.key]:msg}));return}setErr((e)=>{let{[f2.key]:_2,...rest}=e;return rest});let val=f2.type==="number"?Number(buf)||0:buf;update(f2.key,val)}setEditing(!1),setBuf("");return}if(key3.name==="backspace"){setBuf((prev)=>prev.slice(0,-1));return}if(key3.raw&&key3.raw.length===1){setBuf((prev)=>prev+key3.raw);return}return}if(key3.name==="tab"){setFocus((f2)=>f2==="categories"?"fields":"categories");return}if(keys.match("list.search",key3)){setSearching(!0),setQuery(""),setCursor(0);return}if(focus==="categories"){if(key3.name==="up"){setCat((c)=>{let n=Math.max(0,c-1);return catFollow.opts.scrollTo(n),n}),setCursor(0);return}if(key3.name==="down"){setCat((c)=>{let n=Math.min(groups.length-1,c+1);return catFollow.opts.scrollTo(n),n}),setCursor(0);return}if(key3.name==="return"){setFocus("fields");return}return}if(onSlots){let s=slots[cursor];if(handleListKey(keys,key3,{count:count3,setSel:setCursor,...follow.opts,onActivate:s?()=>pick(s):void 0,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})}})||!s)return;if(key3.raw==="x")return unset(s);if(key3.raw==="X")return void unsetAll();return}let f=fields[cursor],writable=!managed;if(handleListKey(keys,key3,{count:count3,setSel:setCursor,...follow.opts,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})},onToggle:writable&&f?.type==="boolean"?()=>{let value2=getNested(rawRef.current,f.key);update(f.key,!(value2===void 0?f.value:value2))}:void 0,onActivate:f&&writable&&(f.type==="string"||f.type==="number")?()=>{setEditing(!0),setBuf(String(f.value??""))}:void 0})||!f||!writable)return;if(f.type==="select"&&f.options){let value2=getNested(rawRef.current,f.key),idx=f.options.indexOf(String(value2===void 0?f.value:value2));if(key3.raw==="l"||key3.raw==="]"){update(f.key,f.options[(idx+1)%f.options.length]);return}if(key3.raw==="h"||key3.raw==="["){update(f.key,f.options[(idx-1+f.options.length)%f.options.length]);return}}}),mode2==="yaml")return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(TabShell,{title:"Config \xB7 YAML",error:loadErr,children:$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("text",{wrapMode:"word",children:[$jsx("span",{fg:theme.text,children:yaml}),$jsx("span",{fg:theme.accent,children:"\u2588"})]})})}),$jsx(HintBar,{pairs:[[keys.print("config.mode"),"form"],[keys.print("config.save"),"save"]]})]});return $jsxs("box",{flexDirection:"column",flexGrow:1,children:[searching?$jsx("box",{height:1,paddingLeft:1,paddingRight:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:"\u2503 "}),$jsx("span",{fg:theme.text,children:query2}),$jsx("span",{fg:theme.accent,children:"\u2588"}),$jsx("span",{fg:theme.textMuted,children:` ${count3} of ${all.length} \xB7 \u2191\u2193 nav \xB7 Esc close`})]})}):null,$jsxs("box",{flexDirection:"row",flexGrow:1,children:[searching?null:$jsx(TabShell,{title:"Config",grow:1,focus:focus==="categories",children:$jsx("scrollbox",{ref:catFollow.ref,scrollY:!0,flexGrow:1,children:groups.map((c,i)=>{let sel=i===cat,hot=sel&&focus==="categories",items=grouped.get(c)??[],n=c==="models"?slots.length:items.length,catDirty=items.some((f)=>changed(f.key));return $jsx("box",{id:catFollow.id(i),backgroundColor:hot?theme.backgroundElement:void 0,onMouseDown:()=>{setCat(i),setCursor(0),setFocus("categories")},children:$jsxs("text",{children:[$jsx("span",{fg:catDirty?theme.warning:theme.textMuted,children:catDirty?"\u25CF":" "}),$jsxs("span",{fg:hot?theme.accent:sel?theme.primary:theme.text,children:[sel?"\u25B8 ":" ",c]}),$jsx("span",{fg:theme.textMuted,children:` (${n})`})]})},c)})})}),$jsxs(TabShell,{title:onSlots?"models \xB7 applies immediately":searching?"Search":nChanged>0?`${active2} \xB7 ${nChanged} unsaved`:active2,grow:3,focus:focus==="fields"||searching,error:loadErr,children:[managed?$jsxs("box",{height:1,flexDirection:"row",gap:1,children:[$jsx("text",{fg:theme.warning,children:"\uD83D\uDD12 managed install \u2014 edit"}),$jsx(FileLink,{source:makeSource("config.yaml"),children:"config.yaml"}),$jsx("text",{fg:theme.warning,children:"via configuration.nix"})]}):null,onSlots?$jsxs("box",{flexDirection:"column",flexGrow:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Auxiliary tasks handle side-jobs. 'auto' = use main model. Per-task api_key/base_url/timeout live in the 'auxiliary' category."})}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:slots.map((s,i)=>$jsx(SlotRow,{id:follow.id(i),s,on:i===cursor&&focus==="fields"},s.key))})]},"slots"):$jsxs($Fragment,{children:[$jsxs(Hdr,{children:[$jsx(Col,{w:4,fg:theme.textMuted,children:""}),searching?$jsx(Col,{w:12,fg:theme.textMuted,bold:!0,children:"Category"}):null,$jsx(Col,{w:40,fg:theme.textMuted,bold:!0,children:"Field"}),$jsx(Col,{grow:!0,min:6,fg:theme.textMuted,bold:!0,children:"Value"}),$jsx(Col,{w:2,fg:theme.textMuted,children:""}),$jsx(Col,{w:9,fg:theme.textMuted,children:""})]}),$jsx("box",{height:1}),count3===0?$jsx("box",{flexGrow:1,padding:2,children:$jsx("text",{fg:theme.textMuted,children:searching?"No matching fields":"No fields in this category"})},"empty"):$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:secs.reduce((acc2,s)=>{if(s.head!==null)acc2.out.push($jsx("box",{height:1,marginTop:acc2.base>0?1:0,children:$jsxs("text",{fg:theme.textMuted,children:["\u2500 ",s.head," "]})},`\xA7${s.head}`));return s.items.forEach((f,j2)=>{let i=acc2.base+j2;acc2.out.push($jsx(FieldRow2,{id:follow.id(i),field:f,active:i===cursor&&(focus==="fields"||searching),changed:changed(f.key),editing:editing&&i===cursor,buf,readonly:!!managed,error:err[f.key],badge:searching?groupOf(f.key):void 0},f.key))}),acc2.base+=s.items.length,acc2},{base:0,out:[]}).out},"list")]})]})]}),managed?$jsx(HintBar,{raw:`read-only \xB7 managed by ${managed}`}):onSlots?$jsx(HintBar,{pairs:[["\u2191\u2193","nav"],["Enter","pick"],["x","reset"],["X","reset-all"],["Tab","categories"]]}):focus==="categories"&&!searching?$jsx(HintBar,{pairs:[["\u2191\u2193","select"],["Tab","fields"]]}):$jsx(HintBar,{pairs:[[keys.print("config.mode"),"yaml"],["Tab","categories"],["\u2191\u2193","nav"],[keys.print("list.search"),"search"],[keys.print("config.save"),"save"]],suffix:nChanged>0?`\u25CF ${nChanged} unsaved`:void 0})]})});var import_react101=__toESM(require_react_production(),1);var import_react99=__toESM(require_react_production(),1);var iso2=(s)=>{if(!s)return null;let t2=Date.parse(s);return Number.isFinite(t2)?Math.floor(t2/1000):null},parseList=(stdout)=>stdout.split(`
4155
4155
  `).map((s)=>s.trim()).filter((s)=>s.length>0&&!s.startsWith("(")),shq2=(s)=>/^[A-Za-z0-9._-]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`,CuratorDialog=()=>{let{theme,syntaxStyle}=useTheme(),gw=useGateway(),toast=useToast(),dialog=useDialog(),state3=useHome("curatorState"),cfg2=useHome("config")?.curator,[report2,setReport]=import_react99.useState(null),[loaded,setLoaded]=import_react99.useState(!1),[busy2,setBusy]=import_react99.useState(null),busyRef=import_react99.useRef(null),[archived,setArchived]=import_react99.useState([]),[mode2,setMode]=import_react99.useState("report"),[sel,setSel]=import_react99.useState(0),sb=import_react99.useRef(null);import_react99.useEffect(()=>{readLatestCuratorReport().then((r)=>{setReport(r),setLoaded(!0)}).catch(()=>setLoaded(!0))},[]);let refreshArchived=import_react99.useCallback(()=>{gw.request("shell.exec",{command:"hermes curator list-archived"}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||`exit ${r.code}`).trim());setArchived(parseList(r.stdout))}).catch((e)=>toast.show({variant:"error",message:trunc5(e instanceof Error?e.message:String(e),120)}))},[gw,toast]);import_react99.useEffect(()=>{refreshArchived()},[refreshArchived]);let sh=import_react99.useCallback((verb,ok)=>{if(busyRef.current)return;busyRef.current=verb,setBusy(verb),gw.request("shell.exec",{command:`hermes curator ${verb}`}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||`exit ${r.code}`).trim());toast.show({variant:"success",message:ok}),home3.invalidate("curatorState")}).catch((e)=>toast.show({variant:"error",message:trunc5(e.message,120)})).finally(()=>{busyRef.current=null,setBusy(null)})},[gw,toast]),restore=import_react99.useCallback((name)=>{if(busyRef.current)return;busyRef.current="restore",setBusy("restore"),gw.request("shell.exec",{command:`hermes curator restore ${shq2(name)}`}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||`exit ${r.code}`).trim());toast.show({variant:"success",message:`Restored ${name}`}),setArchived((prev)=>prev.filter((n)=>n!==name)),setSel((s)=>Math.max(0,s-1))}).catch((e)=>toast.show({variant:"error",message:trunc5(e.message,120)})).finally(()=>{busyRef.current=null,setBusy(null)})},[gw,toast]);useKeyboard((key3)=>{if(mode2==="archived"){if(key3.name==="escape"){setMode("report");return}if(key3.raw==="a"){setMode("report");return}if(key3.name==="up")return setSel((s)=>Math.max(0,s-1));if(key3.name==="down")return setSel((s)=>Math.min(archived.length-1,s+1));if(key3.name==="return"){let name=archived[sel];if(name)restore(name);return}return}if(key3.name==="escape")return dialog.clear();if(key3.raw==="r")return sh("run","Curator run started (background)");if(key3.raw==="p")return state3?.paused?sh("resume","Curator resumed"):sh("pause","Curator paused");if(key3.raw==="a"&&archived.length>0)setSel(0),setMode("archived")}),import_react99.useEffect(()=>{if(mode2==="archived")sb.current?.scrollChildIntoView(`arch-${sel}`)},[sel,mode2]);let last4=iso2(state3?.last_run_at??null),due=last4&&cfg2?last4+cfg2.interval_hours*3600:null,status2=cfg2?.enabled===!1?"disabled":state3?.paused?"paused":"enabled",tint=status2==="enabled"?theme.success:status2==="paused"?theme.warning:theme.textMuted;return $jsxs("box",{flexDirection:"column",width:120,height:34,children:[$jsxs("box",{height:1,flexDirection:"row",children:[$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:"Skill Curator"})}),$jsx("span",{fg:tint,children:` \xB7 ${status2}`})]}),busy2?$jsx("box",{marginLeft:2,children:$jsx(Spinner,{color:theme.textMuted,label:busy2})}):null]}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:state3?`${state3.run_count} run${state3.run_count===1?"":"s"}${last4?" \xB7 last "+ago(last4):" \xB7 never"} \xB7 Esc to close`:"No curator state yet \xB7 Esc to close"})}),$jsx("box",{height:1}),$jsxs("box",{flexDirection:"row",flexGrow:1,gap:2,children:[$jsxs("box",{flexDirection:"column",width:40,height:"100%",flexShrink:0,children:[$jsx(KVBlock,{rows:[["Next run",status2!=="enabled"?`\u2014 (${status2})`:due?until(due):"when idle"],["Last run",last4?ago(last4):"never"],["Duration",state3?.last_run_duration_seconds?dur2(state3.last_run_duration_seconds):void 0],["Archived",archived.length>0?String(archived.length):void 0]]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Config \xB7 edit in Config tab"})}),$jsx(KVBlock,{rows:[["Interval",cfg2?`${cfg2.interval_hours}h`:"\u2014"],["Stale after",cfg2?`${cfg2.stale_after_days}d`:"\u2014"],["Archive after",cfg2?`${cfg2.archive_after_days}d`:"\u2014"]]}),$jsx("box",{height:1}),$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:"r "}),$jsx("span",{fg:theme.text,children:"run now"}),$jsx("span",{fg:theme.textMuted,children:" (background)"})]})}),$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:"p "}),$jsx("span",{fg:theme.text,children:state3?.paused?"resume":"pause"})]})}),archived.length>0?$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:"a "}),$jsx("span",{fg:theme.text,children:"archived skills"}),$jsx("span",{fg:theme.textMuted,children:` (${archived.length})`})]})}):null]}),state3?.last_run_summary?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Last run"})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("markdown",{content:state3.last_run_summary,fg:theme.markdownText,syntaxStyle})})]}):null]}),mode2==="archived"?$jsxs("box",{flexDirection:"column",flexGrow:1,height:"100%",minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:`\u25BE Archived skills (${archived.length})`})})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"\u2191\u2193 select \xB7 Enter restore \xB7 a/Esc back to report"})}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:sb,scrollY:!0,flexGrow:1,border:!0,borderColor:theme.border,paddingLeft:1,paddingRight:1,contentOptions:{flexDirection:"column"},children:archived.length===0?$jsx("text",{fg:theme.textMuted,children:"No archived skills."}):archived.map((name,i)=>$jsx("box",{id:`arch-${i}`,height:1,backgroundColor:i===sel?theme.backgroundElement:void 0,onMouseMove:()=>setSel(i),onMouseDown:()=>restore(name),children:$jsxs("text",{fg:i===sel?theme.text:theme.textMuted,children:[i===sel?"\u25B8 ":" ",name]})},name))})]}):!loaded?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"loading report\u2026"})}):report2?$jsxs("box",{flexDirection:"column",flexGrow:1,height:"100%",minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:`\u25BE Report \xB7 ${report2.runId}`})})}),$jsx(KVLink,{label:"File",source:report2.source,text:report2.source.relative}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,border:!0,borderColor:theme.border,paddingLeft:1,paddingRight:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:$jsx("markdown",{content:report2.content||"(empty)",fg:theme.markdownText,syntaxStyle})})})]}):$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No runs yet \u2014 curator has not completed a cycle."})})]})]})},openCurator=(dialog)=>dialog.replace($jsx(CuratorDialog,{}),void 0,{ownCancel:!0});var NO_EVENTS=[],meta=(hit)=>{let parts2=[];if(hit.identifier)parts2.push(hit.identifier);if(hit.source)parts2.push(hit.source);if(hit.trust_level)parts2.push(hit.trust_level);return parts2.join(" \xB7 ")},iso3=(s)=>{if(!s)return null;let t2=Date.parse(s);return Number.isFinite(t2)?Math.floor(t2/1000):null},SkillRow=import_react101.memo((props)=>{let theme=useTheme().theme,s=props.skill,u3=props.usage,bg2=props.selected?theme.backgroundElement:void 0,used=iso3(u3?.last_used_at)??iso3(u3?.last_viewed_at),stale=u3?.state==="stale",archived=u3?.state==="archived";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:theme.warning,children:u3?.pinned?"\uD83D\uDCCC":" "}),$jsx(Marquee,{grow:!0,min:8,active:props.selected,fg:archived?theme.textMuted:props.selected?theme.accent:theme.text,children:s.name}),archived?$jsx(Col,{w:10,fg:theme.textMuted,children:"archived"}):stale?$jsx(Col,{w:10,fg:theme.warning,children:"stale"}):$jsx(Col,{w:10,fg:theme.textMuted,children:used?ago(used):""})]})}),HitRow=import_react101.memo((props)=>{let theme=useTheme().theme,on=props.selected,info2=meta(props.hit);return $jsxs("box",{flexDirection:"column",minHeight:info2?2:1,backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:props.onHover,onMouseDown:props.onSelect,children:[$jsxs("box",{flexDirection:"row",height:1,children:[$jsx(Col,{w:2,fg:on?theme.primary:theme.textMuted,children:on?"\u25B8 ":" "}),$jsx(Col,{w:28,fg:on?theme.accent:theme.text,children:props.hit.name}),$jsx(Col,{grow:!0,min:8,fg:theme.textMuted,children:props.hit.description||"\u2014"})]}),info2?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx(Col,{w:2,fg:theme.textMuted,children:""}),$jsx(Col,{grow:!0,min:8,fg:theme.info,children:info2})]}):null]})}),bycat=(skills)=>skills.reduce((map,s)=>{let cat=s.category||"uncategorized";return map.set(cat,[...map.get(cat)??[],s]),map},new Map),line3=(e)=>{switch(e.kind){case"absorbed":return`absorbed ${e.sources.map((s)=>`\`${s}\``).join(", ")}`;case"merged":return`merged into \`${e.into}\`${e.reason?` \u2014 ${e.reason}`:""}`;case"transition":return`${e.from} \u2192 ${e.to}`;case"pruned":return`pruned${e.reason?` \u2014 ${e.reason}`:""}`;case"added":return"created by curator"}},DetailPanel2=import_react101.memo((props)=>{let theme=useTheme().theme,s=props.skill,u3=props.usage,used=iso3(u3?.last_used_at),viewed=iso3(u3?.last_viewed_at),patched=iso3(u3?.last_patched_at);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:"Skill Detail"})}),u3?.pinned?$jsx("span",{fg:theme.warning,children:" \uD83D\uDCCC pinned"}):null,u3?.state==="stale"?$jsx("span",{fg:theme.warning,children:" \xB7 stale"}):null,u3?.state==="archived"?$jsx("span",{fg:theme.textMuted,children:" \xB7 archived"}):null]})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.accent,children:$jsx("strong",{children:s.name})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Category",s.category||"uncategorized",theme.info],["Tags",s.tags.length>0?s.tags.join(", "):void 0],u3?["Used",u3.use_count>0?`${u3.use_count}\xD7 \xB7 last ${used?ago(used):"never"}`:"never"]:null,u3&&viewed?["Viewed",`${u3.view_count}\xD7 \xB7 last ${ago(viewed)}`]:null,u3&&patched?["Patched",`${u3.patch_count}\xD7 \xB7 last ${ago(patched)}`]:null].filter(Boolean)}),$jsx(KVLink,{label:"File",source:s.source,text:s.source.relative}),$jsx("box",{height:1}),s.description?$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.text,children:s.description})}):$jsx("text",{fg:theme.textMuted,children:"No description"}),props.events.length>0?$jsxs("box",{flexDirection:"column",marginTop:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Curator lineage"})}),props.events.map((e,i)=>$jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:10,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:ago(e.at)})}),$jsx("box",{flexGrow:1,minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.text,children:line3(e)})})]},i))]}):u3?$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:"No curator events for this skill"})}):null]})}),EmptyState=import_react101.memo((props)=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,padding:2,children:$jsx("text",{children:$jsx("span",{fg:theme.textMuted,children:props.searching?"No matching skills on hub":"No skills found in ~/.hermes/skills/"})})})}),HistoryPanel=import_react101.memo((props)=>{let{theme,syntaxStyle}=useTheme(),dialog=useDialog(),keys=useKeys(),follow=useFollow("skills-history"),[runs,setRuns]=import_react101.useState(()=>listCuratorRuns()),[sel,setSel]=import_react101.useState(0),[open3,setOpen]=import_react101.useState(!1),[body,setBody]=import_react101.useState(""),run=runs[sel];import_react101.useEffect(()=>{if(!open3||!run)return;let live=!0;return readCuratorReport(run.id).then((t2)=>{if(live)setBody(t2)}),()=>{live=!1}},[open3,run?.id]);let moveSel=import_react101.useCallback((v2)=>{setOpen(!1),setSel(v2)},[]);return useKeyboard((key3)=>{if(!props.focused||dialog.open())return;handleListKey(keys,key3,{count:runs.length,setSel:moveSel,...follow.opts,onActivate:()=>setOpen((o)=>!o),onRefresh:()=>setRuns(listCuratorRuns())})}),$jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:props.focused?theme.primary: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:"Curator History"})}),$jsx("span",{fg:theme.textMuted,children:` ${runs.length} run${runs.length===1?"":"s"}${runs[0]?` \xB7 last ${ago(runs[0].at)}`:""}`})]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`\u2191\u2193 select \xB7 Enter expand \xB7 ${keys.print("list.refresh")} reload \xB7 h close`})}),$jsx("box",{height:1}),runs.length===0?$jsx("text",{fg:theme.textMuted,children:"no runs in ~/.hermes/logs/curator/"}):$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:runs.map((r,i)=>{let on=i===sel;return $jsxs("box",{id:follow.id(i),flexDirection:"column",children:[$jsxs("box",{height:1,flexDirection:"row",backgroundColor:on?theme.backgroundElement:void 0,onMouseDown:()=>{setSel(i),setOpen((o)=>i===sel?!o:!0)},children:[$jsx(Col,{w:2,fg:on?theme.primary:theme.textMuted,children:on?"\u25B8 ":" "}),$jsx(Col,{w:12,fg:on?theme.accent:theme.text,children:ago(r.at)}),$jsx(Col,{grow:!0,fg:theme.textMuted,children:`${r.before}\u2192${r.after} arch ${r.archived} cons ${r.consolidated}${r.added?` +${r.added}`:""}`})]}),on&&open3?$jsx("box",{marginLeft:2,marginTop:1,marginBottom:1,children:$jsx("markdown",{content:body||"\u2026",fg:theme.markdownText,syntaxStyle})}):null]},r.id)})})})]})}),Skills=import_react101.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),usage=useHome("skillUsage")??{},curator=useHome("curatorState"),lineage2=import_react101.useRef(indexCuratorLineage());import_react101.useEffect(()=>{lineage2.current=indexCuratorLineage()},[curator?.run_count]);let[skills,setSkills]=import_react101.useState([]),[selected,setSelected]=import_react101.useState(0),[searching,setSearching]=import_react101.useState(!1),[query2,setQuery]=import_react101.useState(""),[hits,setHits]=import_react101.useState([]),[sort,setSort]=import_react101.useState("name"),[history,setHistory]=import_react101.useState(!1),seq=import_react101.useRef(0),listSeq=import_react101.useRef(0),load4=import_react101.useCallback(()=>{let id=++listSeq.current;gw.request("skills.manage",{action:"list"}).then((res)=>{if(listSeq.current!==id)return;let raw=res.skills??{},rows3=Object.entries(raw).flatMap(([cat,names])=>names.map((n)=>{let source=makeSource(`skills/${cat}/${n}/SKILL.md`,`${n}/SKILL.md`),fm=readSkillFrontmatter(source);return{source,category:cat,name:n,description:fm.description,tags:fm.tags,tokenEstimate:count2(`${n} ${fm.description}`)}}));rows3.sort((a,b2)=>a.source.relative.localeCompare(b2.source.relative)),setSkills(rows3)}).catch((err)=>{if(listSeq.current===id)toast.show({variant:"error",message:err.message})})},[gw,toast]);import_react101.useEffect(()=>{return load4(),()=>{listSeq.current++}},[load4]),import_react101.useEffect(()=>{let id=++seq.current;if(!searching||!query2.trim()){setHits([]);return}let t2=setTimeout(()=>{gw.request("skills.manage",{action:"search",query:query2}).then((r)=>{if(seq.current!==id)return;setHits(r.results??[]),setSelected(0)}).catch((err)=>{if(seq.current!==id)return;setHits([]),toast.show({variant:"error",message:err.message})})},150);return()=>clearTimeout(t2)},[gw,toast,query2,searching]);let flat=[...sort==="used"?new Map([["by recency",[...skills].sort((a,b2)=>{let ta=iso3(usage[a.name]?.last_used_at)??iso3(usage[a.name]?.last_viewed_at)??0;return(iso3(usage[b2.name]?.last_used_at)??iso3(usage[b2.name]?.last_viewed_at)??0)-ta})]]):bycat(skills)].flatMap(([cat,items])=>[{type:"header",category:cat},...items.map((s)=>({type:"skill",skill:s}))]),skillRows=flat.filter((r)=>r.type==="skill"),count3=searching?hits.length:skillRows.length,current=!searching&&skillRows[selected]?.type==="skill"?skillRows[selected].skill:null,follow=useFollow("sk"),exit=import_react101.useCallback(()=>{setSearching(!1),setQuery(""),setHits([]),setSelected(0)},[]),install2=import_react101.useCallback(async(hit)=>{let query3=hit.identifier??hit.name;if(!await openConfirm(dialog,{title:"Install skill?",body:query3,yes:"install"}))return;gw.request("skills.manage",{action:"install",query:query3}).then(()=>{toast.show({variant:"success",message:`Installed ${query3}`}),exit(),load4()}).catch((e)=>toast.show({variant:"error",message:`Install failed: ${e.message}`}))},[dialog,gw,toast,exit,load4]),keys=useKeys();useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(searching){if(key3.name==="escape"){exit();return}if(key3.name==="backspace"){setQuery((p)=>p.slice(0,-1)),setSelected(0);return}if(key3.name==="up")return setSelected((p)=>Math.max(0,p-1));if(key3.name==="down")return setSelected((p)=>Math.min(count3-1,p+1));if(key3.name==="return"){let hit=hits[selected];if(hit)install2(hit);return}if(key3.raw&&key3.raw.length===1&&key3.raw>=" ")setQuery((p)=>p+key3.raw),setSelected(0);return}if(!key3.ctrl&&!key3.meta&&key3.raw==="s"){setSort((p)=>p==="name"?"used":"name"),setSelected(0);return}if(!key3.ctrl&&!key3.meta&&key3.raw==="c"){openCurator(dialog);return}if(!key3.ctrl&&!key3.meta&&key3.raw==="h"){setHistory((h2)=>!h2);return}if(history){if(key3.name==="escape")return setHistory(!1);return}handleListKey(keys,key3,{count:count3,setSel:setSelected,...follow.opts,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})},onSearch:()=>{setSearching(!0),setQuery(""),setHits([]),setSelected(0)}})});let skillIdx=-1;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsxs(TabShell,{title:searching?`Hub Search (${hits.length})`:`Skills (${skills.length}${sort==="used"?" \xB7 by use":""})`,children:[searching?$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:"/ "}),$jsx("span",{fg:theme.text,children:query2}),$jsx("span",{fg:theme.accent,children:"\u2588"})]})}):null,searching?null:$jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:theme.textMuted,children:""}),$jsx(Col,{grow:!0,min:8,fg:theme.textMuted,bold:!0,children:"Name"})]}),searching?null:$jsx("box",{height:1}),count3===0?$jsx(EmptyState,{searching}):searching?$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:hits.map((h2,i)=>$jsx(HitRow,{hit:h2,selected:i===selected,onHover:()=>setSelected(i),onSelect:()=>install2(h2)},h2.identifier??h2.name))})}):$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:flat.map((row3,i)=>{if(row3.type==="header")return $jsx("box",{marginTop:i>0?1:0,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:`\u25BE ${row3.category}`})})},`h-${row3.category}`);skillIdx++;let idx=skillIdx;return $jsx(SkillRow,{id:follow.id(idx),skill:row3.skill,usage:usage[row3.skill.name],selected:idx===selected,onSelect:()=>setSelected(idx),onHover:()=>setSelected(idx)},row3.skill.name)})}),!searching&&curator?$jsx("box",{height:1,flexShrink:0,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"curator \xB7 "}),curator.paused?$jsx("span",{fg:theme.warning,children:"paused"}):curator.last_run_at?$jsx("span",{fg:theme.textMuted,children:`${curator.run_count} run${curator.run_count===1?"":"s"} \xB7 last ${ago(iso3(curator.last_run_at)??0)}`}):$jsx("span",{fg:theme.textMuted,children:"never run"})]})}):null]}),history?$jsx(HistoryPanel,{focused:!!props.focused&&!searching}):current?$jsx(DetailPanel2,{skill:current,usage:usage[current.name],events:lineage2.current.get(current.name)??NO_EVENTS}):null]}),$jsx(HintBar,{pairs:searching?[["\u2191\u2193","navigate"],["Enter","install"],["Esc","cancel"]]:[["\u2191\u2193","navigate"],[keys.print("list.search"),"search hub"],["s","sort"],["c","curator"],["h","history"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react103=__toESM(require_react_production(),1);var kindOf=(ts)=>ts.name.includes(":")?"mcp":ts.name.startsWith("hermes-")?"platform":"core",KIND_LABEL={core:"core",platform:"platform bundles",mcp:"mcp"},group2=(list2)=>{let by={core:[],platform:[],mcp:[]};for(let ts of list2)by[kindOf(ts)].push(ts);return["core","platform","mcp"].filter((k2)=>by[k2].length>0).map((k2)=>({kind:k2,items:by[k2]}))},Row3=import_react103.memo((props)=>{let theme=useTheme().theme,ts=props.ts,bg2=props.selected?theme.backgroundElement:void 0,unavail=ts.available===!1,glyph=unavail?"\u25CC":ts.enabled?"\u25CF":"\u25CB",glyphFg=unavail?theme.warning:ts.enabled?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:glyphFg,children:`${glyph} `}),$jsx(Col,{grow:!0,fg:props.selected?theme.accent:theme.text,children:ts.name}),$jsx(Col,{w:9,fg:theme.info,right:!0,children:`${ts.tool_count} tools`})]})}),DetailPanel3=import_react103.memo((props)=>{let theme=useTheme().theme,ts=props.ts,unavail=ts.available===!1;return $jsxs("box",{flexDirection:"column",padding:1,border:!0,borderColor:theme.border,backgroundColor:theme.backgroundPanel,width:"40%",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.accent,children:$jsx("strong",{children:ts.name})})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:KIND_LABEL[kindOf(ts)]})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Status",unavail?"unavailable":ts.enabled?"enabled":"disabled",unavail?theme.warning:ts.enabled?theme.success:theme.textMuted],["Tools",String(ts.tool_count),theme.info],["Includes",ts.includes?.length?ts.includes.join(", "):void 0,theme.text],["Requires",ts.requirements?.length?ts.requirements.join(", "):void 0,unavail?theme.warning:theme.text]]}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.text,children:ts.description||"\u2014"})}),ts.tools?.length?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["Tools (",ts.tools.length,"):"]})}),$jsx("scrollbox",{flexGrow:1,scrollY:!0,children:ts.tools.map((n)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",n]},n))})]}):null]})}),Toolsets=import_react103.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),[list2,setList]=import_react103.useState([]),[sel,setSel]=import_react103.useState(0),[err,setErr]=import_react103.useState(null),rev2=import_react103.useRef(0),loads=import_react103.useRef(0),writes=import_react103.useRef(Promise.resolve()),known=import_react103.useRef(new Map),secs=group2(list2),flat=secs.flatMap((s)=>s.items),live=import_react103.useRef({flat,sel});live.current={flat,sel};let load4=import_react103.useCallback(()=>{let gen=++loads.current;gw.request("toolsets.list",{}).then((r)=>{if(loads.current!==gen)return;let next3=r.toolsets??[];known.current=new Map(next3.map((t2)=>[t2.name,t2.enabled])),setList(next3),setErr(null)}).catch((e)=>{if(loads.current===gen)setErr(e instanceof Error?e.message:String(e))})},[gw]);import_react103.useEffect(()=>{return load4(),()=>{rev2.current++,loads.current++}},[load4]);let toggle=import_react103.useCallback(()=>{let ts2=live.current.flat[live.current.sel];if(!ts2)return;if(ts2.available===!1){toast.show({variant:"warning",message:`${ts2.name} is unavailable`});return}let enabled2=!ts2.enabled,action=enabled2?"enable":"disable",gen=++rev2.current;loads.current++,live.current={...live.current,flat:live.current.flat.map((t2)=>t2.name===ts2.name?{...t2,enabled:enabled2}:t2)},setList((prev)=>prev.map((t2)=>t2.name===ts2.name?{...t2,enabled:enabled2}:t2)),writes.current=writes.current.then(async()=>{try{let r=await gw.request("tools.configure",{action,names:[ts2.name]}),authoritative=Array.isArray(r.enabled_toolsets)?new Set(r.enabled_toolsets):null;if(authoritative)known.current=new Map(live.current.flat.map((t2)=>[t2.name,authoritative.has(t2.name)]));if(rev2.current!==gen)return;if(r.unknown?.includes(ts2.name)){setList((prev)=>prev.map((t2)=>({...t2,enabled:known.current.get(t2.name)??t2.enabled}))),toast.show({variant:"warning",message:`${ts2.name} is not configurable`});return}if(r.missing_servers?.length&&ts2.name.includes(":")){let server=ts2.name.split(":",1)[0];if(r.missing_servers.includes(server)){setList((prev)=>prev.map((t2)=>({...t2,enabled:known.current.get(t2.name)??t2.enabled}))),toast.show({variant:"warning",message:`MCP server '${server}' not in config`});return}}if(authoritative)setList((prev)=>prev.map((t2)=>({...t2,enabled:authoritative.has(t2.name)})));else load4()}catch(e){if(rev2.current!==gen)return;setList((prev)=>prev.map((t2)=>({...t2,enabled:known.current.get(t2.name)??t2.enabled}))),toast.show({variant:"error",message:e instanceof Error?e.message:String(e)})}})},[gw,toast,load4]),count3=flat.length,ts=flat[sel]??null,follow=useFollow("ts"),keys=useListKeys({active:()=>!!props.focused&&!dialog.open(),count:count3,setSel,...follow.opts,onToggle:toggle,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})}});return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsxs(TabShell,{title:`Toolsets (${count3})`,error:err,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:9,fg:theme.textMuted,bold:!0,right:!0,children:"Tools"})]}),$jsx("box",{height:1}),count3===0?$jsx("box",{flexGrow:1,padding:2,children:$jsx("text",{fg:theme.textMuted,children:"No toolsets found"})},"empty"):$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:secs.reduce((acc2,s)=>{return acc2.out.push($jsx("box",{height:1,marginTop:acc2.base>0?1:0,children:$jsxs("text",{fg:theme.textMuted,children:["\u2500 ",KIND_LABEL[s.kind]," (",s.items.length,") "]})},`\xA7${s.kind}`)),s.items.forEach((t2,j2)=>{let i=acc2.base+j2;acc2.out.push($jsx(Row3,{id:follow.id(i),ts:t2,selected:i===sel,onSelect:()=>setSel(i),onHover:()=>setSel(i)},t2.name))}),acc2.base+=s.items.length,acc2},{base:0,out:[]}).out},"list")]}),ts?$jsx(DetailPanel3,{ts}):null]}),$jsx(HintBar,{pairs:[["\u2191\u2193","nav"],[keys.print("list.toggle"),"toggle"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react104=__toESM(require_react_production(),1);var mask=(val)=>"\u2022".repeat(Math.min(val.length,12)),VarRow=import_react104.memo((props)=>{let theme=useTheme().theme,set3=props.value!==void 0,bg2=props.selected?theme.backgroundElement:void 0;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:bg2,onMouseDown:props.onClick,onMouseMove:props.onHover,children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "}),$jsx(Col,{w:28,fg:props.selected?theme.accent:theme.text,children:props.name}),$jsx(Col,{w:8,fg:set3?theme.success:theme.textMuted,children:set3?" SET ":"UNSET"}),$jsx(Col,{grow:!0,min:4,fg:props.shown?theme.text:theme.textMuted,children:set3?props.shown?props.value:mask(props.value):"\u2014"})]})}),Env=import_react104.memo((props)=>{let theme=useTheme().theme,dialog=useDialog(),toast=useToast(),vars=useHome("env")??{},[sel,setSel]=import_react104.useState(0),[reveal,setReveal]=import_react104.useState(new Set),[collapsed,setCollapsed]=import_react104.useState({}),[searching,setSearching]=import_react104.useState(!1),[query2,setQuery]=import_react104.useState(""),known=new Set(ENV_CATALOG.flatMap((g)=>g.keys)),extra=Object.keys(vars).filter((k2)=>!known.has(k2)).sort(),rows3=(extra.length>0?[...ENV_CATALOG,{category:"Other",keys:extra}]:ENV_CATALOG).flatMap((g)=>{let keys2=searching&&query2.trim()?g.keys.filter((k2)=>k2.toLowerCase().includes(query2.toLowerCase())):g.keys;if(keys2.length===0)return[];let hide=collapsed[g.category]??!1,header={type:"header",category:g.category,collapsed:hide};if(hide)return[header];return[header,...keys2.map((key3)=>({type:"var",key:key3,value:vars[key3]}))]}),count3=rows3.length,cur=rows3[sel],setKeys=rows3.flatMap((r)=>r.type==="var"&&r.value!==void 0?[r.key]:[]),follow=useFollow("env"),edit=import_react104.useCallback(async(key3,initial)=>{let val=await openTextPrompt(dialog,{title:`Edit ${key3}`,label:"Value",initial});if(val==null)return;await writeEnvVar(key3,val),home3.invalidate("env"),toast.show({variant:"success",message:`${key3} saved`})},[dialog,toast]),add=import_react104.useCallback(async()=>{let key3=await openTextPrompt(dialog,{title:"New Variable",label:"Name (e.g. FOO_API_KEY)"});if(!key3)return;let val=await openTextPrompt(dialog,{title:`Set ${key3}`,label:"Value"});if(val==null)return;await writeEnvVar(key3,val),home3.invalidate("env"),toast.show({variant:"success",message:`${key3} added`})},[dialog,toast]),del=import_react104.useCallback(async(key3)=>{if(!await openConfirm(dialog,{title:"Delete Variable",body:`Remove ${key3} from .env?`,yes:"delete",danger:!0}))return;await removeEnvVar(key3),home3.invalidate("env"),toast.show({variant:"success",message:`${key3} removed`})},[dialog,toast]),revealAll=import_react104.useCallback(()=>setReveal((s)=>s.size===setKeys.length&&setKeys.length>0?new Set:new Set(setKeys)),[setKeys]),activateAt=import_react104.useCallback((i)=>{let r=rows3[i];if(r?.type==="header")return setCollapsed((p)=>({...p,[r.category]:!p[r.category]}));if(r?.type==="var"){if(r.value!==void 0&&!reveal.has(r.key))return setReveal((s)=>new Set(s).add(r.key));return void edit(r.key,r.value??"")}},[rows3,reveal,edit]),activate=import_react104.useCallback(()=>activateAt(sel),[activateAt,sel]),rowClick=import_react104.useCallback((i)=>{setSel(i),activateAt(i)},[activateAt]),keys=useKeys();return useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(searching){if(key3.name==="escape"){setSearching(!1),setQuery(""),setSel(0);return}if(key3.name==="backspace"){setQuery((q4)=>q4.slice(0,-1)),setSel(0);return}if(key3.name==="up")return setSel((p)=>Math.max(0,p-1));if(key3.name==="down")return setSel((p)=>Math.min(count3-1,p+1));if(key3.name==="return")return setSearching(!1),activate();if(key3.raw&&key3.raw.length===1&&key3.raw>=" "){setQuery((q4)=>q4+key3.raw),setSel(0);return}return}handleListKey(keys,key3,{count:count3,setSel,...follow.opts,onActivate:activate,onToggle:revealAll,onNew:add,onDelete:()=>{if(cur?.type==="var"&&cur.value!==void 0)del(cur.key)},onSearch:()=>{setSearching(!0),setQuery(""),setSel(0)},onRefresh:()=>{home3.invalidate("env"),toast.show({variant:"info",message:"Reloaded",duration:1000})}})}),$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs(TabShell,{title:searching?"Env (searching)":"Env / API Keys",children:[searching?$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:"/ "}),$jsx("span",{fg:theme.text,children:query2}),$jsx("span",{fg:theme.accent,children:"\u2588"})]})}):null,$jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:theme.textMuted,children:""}),$jsx(Col,{w:28,fg:theme.textMuted,bold:!0,children:"Name"}),$jsx(Col,{w:8,fg:theme.textMuted,bold:!0,children:"Status"}),$jsx(Col,{grow:!0,min:4,fg:theme.textMuted,bold:!0,children:"Value"})]}),$jsx("box",{height:1}),count3===0?$jsx("box",{flexGrow:1,padding:2,children:$jsx("text",{fg:theme.textMuted,children:searching?"No matching variables":"No variables configured"})},"empty"):$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:$jsx("box",{flexDirection:"column",width:"100%",children:rows3.map((row3,i)=>row3.type==="header"?$jsx("box",{id:follow.id(i),marginTop:i>0?1:0,backgroundColor:i===sel?theme.backgroundElement:void 0,onMouseMove:()=>setSel(i),onMouseDown:()=>rowClick(i),children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:`${row3.collapsed?"\u25B8":"\u25BE"} ${row3.category}`})})},`h-${row3.category}`):$jsx(VarRow,{id:follow.id(i),name:row3.key,value:row3.value,shown:reveal.has(row3.key),selected:i===sel,onHover:()=>setSel(i),onClick:()=>rowClick(i)},row3.key))})},"list")]}),$jsx(HintBar,{pairs:searching?[["\u2191\u2193","move"],["Enter","reveal/edit"],["Esc","cancel"]]:[["\u2191\u2193","move"],[keys.print("list.activate"),"reveal/edit"],[keys.print("list.toggle"),"show-all"],[keys.print("list.new"),"new"],[keys.print("list.delete"),"delete"],[keys.print("list.search"),"search"],[keys.print("list.refresh"),"reload"]]})]})});var import_react106=__toESM(require_react_production(),1);function usageColor(pct,theme){if(pct>=95)return theme.error;if(pct>=80)return theme.warning;return theme.success}function bar2(pct,w2){let filled=Math.round(pct/100*w2);return"\u2588".repeat(filled)+"\u2591".repeat(w2-filled)}var DESC={builtin:"File-based \xA7-delimited entries (MEMORY.md + USER.md). Always active.",mem0:"Server-side LLM fact extraction with semantic search and reranking.",honcho:"AI-native cross-session user modeling with dialectic Q&A.",hindsight:"Knowledge graph with entity resolution and multi-strategy retrieval.",holographic:"Local SQLite fact store with FTS5, trust scoring, HRR retrieval.",openviking:"Session-managed memory with tiered retrieval.",retaindb:"Cloud memory API with hybrid search and 7 memory types.",byterover:"Persistent knowledge tree via brv CLI.",supermemory:"Semantic long-term memory with profile recall and session ingest."},Memory=import_react106.memo((props)=>{let theme=useTheme().theme,dialog=useDialog(),toast=useToast(),gw=useGateway(),[sel,setSel]=import_react106.useState(0),config=useHome("config"),memory=useHome("memory"),userProfile=useHome("userProfile"),providers=useHome("memoryProviders")??[],activity=useHome("memoryActivity")??[],cfg2=config?.memory,active2=cfg2?.provider||"",cur=providers[sel],on=!!cur&&(cur.name==="builtin"||cur.name===active2),toggle=async()=>{if(!cur||cur.name==="builtin")return;let isOn=cur.name===active2;if(!await openConfirm(dialog,{title:isOn?"Deactivate memory provider?":"Activate memory provider?",body:isOn?`Clear '${cur.name}' as the active provider (revert to built-in only).`:`Set '${cur.name}' as the active provider. Ensure required env vars are set (Env tab).`,yes:isOn?"deactivate":"activate"}))return;let{writeConfig:writeConfig2}=await Promise.resolve().then(() => (init_lane(),exports_lane)),r=await writeConfig2(gw,[{key:"memory.provider",to:isOn?"":cur.name}]);if(r.failed.length)return toast.show({variant:"error",message:r.failed[0].err});home3.invalidate("config"),home3.invalidate("memoryProviders"),toast.show({variant:"success",message:isOn?"Deactivated":`Activated ${cur.name} \u2014 new sessions pick this up`})},keys=useListKeys({active:()=>!!props.focused&&!dialog.open(),count:providers.length,setSel,onToggle:toggle,onRefresh:()=>{home3.invalidate("memoryProviders"),home3.invalidate("memoryActivity"),toast.show({variant:"info",message:"Reloaded",duration:1000})}}),feed=!cur?[]:cur.name==="builtin"?activity:activity.filter((a)=>a.provider===cur.name);return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx(TabShell,{title:"Memory Providers",grow:1,children:$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:providers.map((p,i)=>{let pOn=p.name==="builtin"||p.name===active2,has2=Object.keys(p.config).length>0,dot=pOn?"\u25CF":has2?"\u25D0":"\u25CB",fg2=pOn?theme.success:has2?theme.warning:theme.textMuted,tag=pOn?"active":has2?"configured":"";return $jsxs("box",{flexDirection:"column",marginBottom:1,backgroundColor:i===sel?theme.backgroundElement:void 0,onMouseDown:()=>setSel(i),onMouseMove:()=>setSel(i),children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsxs("span",{fg:fg2,children:[dot," "]}),$jsx("span",{fg:i===sel?theme.accent:theme.text,children:p.name}),tag?$jsxs("span",{fg:fg2,children:[" (",tag,")"]}):null]})}),$jsx("box",{height:1,overflow:"hidden",paddingLeft:2,children:$jsx("text",{fg:theme.textMuted,children:DESC[p.name]||"\u2014"})})]},p.name)})})}),$jsx(TabShell,{title:cur?.name??"Provider",grow:2,children:cur?$jsx(ProviderDetail,{provider:cur,active:active2,cfg:cfg2,memory,userProfile,feed}):$jsx("text",{fg:theme.textMuted,children:"Select a provider"})})]}),$jsx(HintBar,{pairs:[["\u2191\u2193","select"],[keys.print("list.toggle"),"activate"]],suffix:on?"\u25CF active":"\u25CB inactive"})]})}),ProviderDetail=import_react106.memo((props)=>{let theme=useTheme().theme,p=props.provider,on=p.name==="builtin"||p.name===props.active;return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:DESC[p.name]||"Memory provider"})}),$jsx("box",{height:1}),p.name==="builtin"?$jsxs("box",{flexDirection:"column",children:[props.cfg?$jsxs($Fragment,{children:[$jsx(KVBlock,{rows:[["Notes",props.cfg.memory_enabled?"enabled":"disabled",props.cfg.memory_enabled?theme.success:theme.error],["Profile",props.cfg.user_profile_enabled?"enabled":"disabled",props.cfg.user_profile_enabled?theme.success:theme.error]]}),$jsx("box",{height:1})]}):null,$jsx(CapacityBar,{title:"Notes (MEMORY.md)",info:props.memory??null}),$jsx("box",{height:1}),$jsx(CapacityBar,{title:"Profile (USER.md)",info:props.userProfile??null})]}):null,p.name!=="builtin"&&on&&props.cfg?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.accent,children:$jsx("strong",{children:"Agent Settings"})})}),$jsx(KVBlock,{rows:[["Nudge",`every ${props.cfg.nudge_interval} turns`],["Flush",`after ${props.cfg.flush_min_turns} turns`]]}),$jsx("box",{height:1})]}):null,Object.keys(p.config).length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.accent,children:$jsx("strong",{children:"Local Configuration"})})}),$jsx(KVBlock,{rows:Object.entries(p.config).map(([k2,v2])=>[k2,String(v2)])})]}):p.name!=="builtin"?$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:"No local config found. Run `hermes memory setup` to configure."})}):null,$jsx(ActivityFeed,{items:props.feed,own:p.name})]})})}),OP_GLYPH={write:"+",read:"?"},ActivityFeed=import_react106.memo((props)=>{let theme=useTheme().theme,all=props.own==="builtin",nW=props.items.filter((a)=>a.op==="write").length;return $jsxs("box",{flexDirection:"column",marginTop:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:"Recent Activity"})}),props.items.length?$jsxs("span",{fg:theme.textMuted,children:[" \xB7 ",nW," writes, ",props.items.length-nW," reads"]}):null]})}),props.items.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No memory-tool calls in the last ~2000 messages"})}):null,props.items.map((a,i)=>$jsx("box",{height:1,flexDirection:"row",overflow:"hidden",children:$jsxs("text",{children:[$jsxs("span",{fg:a.op==="write"?theme.success:theme.textMuted,children:[OP_GLYPH[a.op]," "]}),$jsx("span",{fg:theme.textMuted,children:ago(a.ts).padEnd(8)}),all&&a.provider!=="builtin"?$jsxs("span",{fg:theme.primary,children:[a.provider,"\xB7"]}):null,$jsx("span",{fg:theme.text,children:a.verb}),$jsxs("span",{fg:theme.textMuted,children:[" ",a.summary]})]})},i))]})}),CapacityBar=import_react106.memo((props)=>{let theme=useTheme().theme;if(!props.info)return $jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:[props.title,": unavailable"]})});let color=usageColor(props.info.usagePercent,theme);return $jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.text,children:props.title}),$jsxs("span",{fg:theme.textMuted,children:[" \xB7 ",props.info.entryCount," entries"]})]})}),$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:color,children:bar2(props.info.usagePercent,20)}),$jsxs("span",{fg:theme.textMuted,children:[" ",props.info.charCount,"/",props.info.charLimit," (",props.info.usagePercent,"%)"]})]})})]})});var ConfigGroup=import_react107.memo((props)=>{let labels=SUB_TABS[CONFIG_TAB];import_react107.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]);let hint="shift+\u2190/\u2192 sub";return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(SubTabBar,{tabs:labels,active:props.sub,onChange:props.setSub,hint}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[$jsx(Pane3,{visible:props.sub===0,children:$jsx(Config2,{focused:!!props.focused&&props.sub===0})}),$jsx(Pane3,{visible:props.sub===1,children:$jsx(Skills,{focused:!!props.focused&&props.sub===1})}),$jsx(Pane3,{visible:props.sub===2,children:$jsx(Toolsets,{focused:!!props.focused&&props.sub===2})}),$jsx(Pane3,{visible:props.sub===3,children:$jsx(Env,{focused:!!props.focused&&props.sub===3})}),$jsx(Pane3,{visible:props.sub===4,children:$jsx(Memory,{focused:!!props.focused&&props.sub===4})})]})]})}),Pane3=({visible:visible2,children:children2})=>visible2?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react123=__toESM(require_react_production(),1);var import_react116=__toESM(require_react_production(),1);import{existsSync as existsSync25}from"fs";import{basename as basename12}from"path";var import_react108=__toESM(require_react_production(),1);var PathPrompt=(props)=>{let theme=useTheme().theme,[value2,setValue]=import_react108.useState(props.initial??""),[items,setItems]=import_react108.useState([]),seq=import_react108.useRef(0),ok=(it)=>it.meta==="dir"||!props.filter||props.filter.test(it.text);return import_react108.useEffect(()=>{if(!value2.trim()){setItems([]);return}let me2=++seq.current,t2=setTimeout(()=>{props.gw.request("complete.path",{word:value2}).then((r)=>{if(seq.current===me2)setItems((r.items??[]).filter(ok).slice(0,5))}).catch(()=>{if(seq.current===me2)setItems([])})},120);return()=>clearTimeout(t2)},[value2,props.gw]),useKeyboard((key3)=>{if(key3.name!=="tab")return;key3.preventDefault();let hit=items[0];if(hit)setValue(hit.text)}),$jsxs("box",{flexDirection:"column",width:72,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:props.title})})}),$jsx("box",{height:1}),props.label?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:props.label})}):null,$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:value2,onInput:setValue,onSubmit:()=>{let v2=value2.trim();if(v2)props.onSubmit(v2)},focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement})})]}),$jsx("box",{height:1}),items.length>0?items.map((it)=>$jsxs("box",{height:1,flexDirection:"row",overflow:"hidden",children:[$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:it.text})}),it.meta?$jsx("box",{flexShrink:0,height:1,children:$jsx("text",{fg:theme.textMuted,children:` ${it.meta}`})}):null]},it.text)):null,items.length>0?$jsx("box",{height:1}):null,$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:value2.trim()?`Tab complete \xB7 Enter confirm \xB7 Esc cancel${items.length>0?` \xB7 ${items.length} match${items.length===1?"":"es"}`:""}`:"Type a path \xB7 Esc cancel"})})]})};function openPathPrompt(dialog,gw,opts){return new Promise((resolve4)=>{dialog.replace($jsx(PathPrompt,{title:opts.title,label:opts.label,initial:opts.initial,filter:opts.filter,gw,onSubmit:(v2)=>{resolve4(v2),dialog.clear()}}),()=>resolve4(null))})}var import_react110=__toESM(require_react_production(),1);var BASE=`
4156
- high contrast, light subject on dark, black background`,BINDS=[{name:"return",action:"submit"},{name:"return",shift:!0,action:"newline"}],Generate=(props)=>{let theme=useTheme().theme,ta=import_react110.useRef(null),flight=import_react110.useRef(!1),[prompt,setPrompt]=import_react110.useState(props.lastPrompt??BASE),[useSeed,setUseSeed]=import_react110.useState(!!props.seed),[secs,setSecs]=import_react110.useState(2),[busy2,setBusy]=import_react110.useState(!1),[err,setErr]=import_react110.useState(null),[field,setField]=import_react110.useState("prompt");import_react110.useEffect(()=>{ta.current?.setCursor(0,0)},[]);let fields=props.kind==="video"?props.seed?["prompt","seed","seconds","submit"]:["prompt","seconds","submit"]:props.seed?["prompt","seed","submit"]:["prompt","submit"],advance=()=>setField((f)=>fields[(fields.indexOf(f)+1)%fields.length]),submit2=()=>{let p=prompt.trim(),bare=!props.lastPrompt&&p===BASE.trim();if(!p||bare||flight.current){if(bare)setErr("describe the subject on line 1");return}flight.current=!0,setBusy(!0),setErr(null),props.run(props.kind,p,{seed:props.seed&&useSeed?props.seed:void 0,seconds:props.kind==="video"?secs:void 0,aspect:props.kind==="video"?"1:1":"square"}).then((r)=>{if("err"in r){setErr(r.err),setBusy(!1);return}props.onDone(r.path,p)}).catch((e)=>{setErr(e instanceof Error?e.message:String(e)),setBusy(!1)}).finally(()=>{flight.current=!1})};useKeyboard((key3)=>{if(busy2)return;if(key3.name==="tab"){key3.preventDefault();let i=fields.indexOf(field),next3=fields[(i+(key3.shift?fields.length-1:1))%fields.length];setField(next3);return}if(field==="prompt")return;if(key3.name==="return")return field==="submit"?submit2():advance();if(field==="seed"&&(key3.name==="space"||key3.name==="left"||key3.name==="right")){setUseSeed((v2)=>!v2);return}if(field==="seconds"){if(key3.name==="left")return setSecs((v2)=>Math.max(1,v2-1));if(key3.name==="right")return setSecs((v2)=>Math.min(4,v2+1))}if(field==="submit"&&key3.name==="space")submit2()});let lbl=(id,text4)=>$jsx("box",{width:12,flexShrink:0,children:$jsxs("text",{fg:field===id?theme.accent:theme.textMuted,children:[field===id?"\u25B8 ":" ",text4]})});return $jsxs("box",{flexDirection:"column",width:72,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:`Generate ${props.kind} \u2014 ${props.state}`})})}),$jsx("box",{height:1}),$jsxs("box",{flexDirection:"row",children:[lbl("prompt","Prompt"),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("textarea",{ref:ta,initialValue:prompt,keyBindings:BINDS,onSubmit:advance,onContentChange:()=>{if(ta.current)setPrompt(ta.current.plainText)},focused:field==="prompt",placeholder:props.kind==="image"?"describe the image\u2026":"describe the motion\u2026",textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:field==="prompt"?theme.backgroundElement:void 0,focusedBackgroundColor:theme.backgroundElement,minHeight:4,maxHeight:6})})]}),props.seed?$jsxs("box",{height:1,flexDirection:"row",marginTop:1,children:[lbl("seed","Seed"),$jsx("box",{flexGrow:1,minWidth:0,height:1,children:$jsx("text",{fg:field==="seed"?theme.text:theme.textMuted,children:useSeed?"\u25CF base.png":"\u25CB none"})})]}):null,props.kind==="video"?$jsxs("box",{height:1,flexDirection:"row",marginTop:1,children:[lbl("seconds","Seconds"),$jsx("box",{width:20,height:1,children:$jsx("slider",{orientation:"horizontal",min:1,max:4,value:secs,foregroundColor:field==="seconds"?theme.accent:theme.textMuted,backgroundColor:theme.border,onChange:(v2)=>setSecs(Math.round(v2))})}),$jsx("box",{width:6,height:1,children:$jsx("text",{fg:field==="seconds"?theme.text:theme.textMuted,children:` ${secs}s`})})]}):null,$jsxs("box",{marginTop:1,flexDirection:"row",children:[lbl("submit",""),$jsx("box",{flexGrow:1,minWidth:0,children:busy2?$jsx("box",{height:1,children:$jsx(Spinner,{color:theme.accent,label:"generating\u2026"})}):err?$jsx("text",{fg:theme.warning,wrapMode:"word",children:err}):$jsx("box",{height:1,children:$jsx("text",{fg:field==="submit"?theme.accent:theme.textMuted,children:"[Enter] generate"})})})]}),$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter next \xB7 Shift+Enter newline \xB7 Tab field \xB7 Esc cancel"})})]})};function openGenerate(dialog,run,opts){return new Promise((resolve4)=>{let token=0;dialog.replace($jsx(Generate,{...opts,run,onDone:(p,txt)=>{if(resolve4(p?{path:p,prompt:txt}:null),dialog.version()===token)dialog.clear()}}),()=>resolve4(null)),token=dialog.version()})}var import_react112=__toESM(require_react_production(),1);import{existsSync as existsSync23,readFileSync as readFileSync15,rmSync as rmSync5}from"fs";import{createHash as createHash6}from"crypto";import{isIP}from"net";import{tmpdir as tmpdir5}from"os";import{basename as basename11,dirname as dirname11,join as join18}from"path";var exports_eikon={};__export(exports_eikon,{writeStudio:()=>writeStudio,useInstalled:()=>useInstalled,update:()=>update,studioFile:()=>studioFile,sourceStatus:()=>sourceStatus,sourceStamp:()=>sourceStamp,sourceName:()=>sourceName,sourceFetchUrl:()=>sourceFetchUrl,sourceExt:()=>sourceExt,sourceDir:()=>sourceDir,save:()=>save2,revision:()=>revision,remove:()=>remove2,register:()=>register,readStudio:()=>readStudio,raw:()=>raw,rasterizers:()=>rasterizers,rasterizer:()=>rasterizer,probe:()=>probe,previewPackage:()=>previewPackage,pick:()=>pick,peekSource:()=>peekSource,parseEikonFile:()=>parseEikonFile,parseEikon:()=>parseEikon,onRevision:()=>onRevision,onRegistry:()=>onRegistry,notifyRevision:()=>notifyRevision,localSources:()=>localSources,loadCatalog:()=>loadCatalog2,list:()=>list2,lifecycle:()=>lifecycle,installPackage:()=>installPackage,inspectSource:()=>inspectSource,header:()=>header,hasLocalSource:()=>hasLocalSource,findSource:()=>findSource,file:()=>file,fetchSource:()=>fetchSource,ensure:()=>ensure,eikon:()=>exports_eikon,downloadSource:()=>downloadSource,dir:()=>dir,baked:()=>baked,attachSources:()=>attachSources,adopt:()=>adopt,adaptPackage:()=>adaptPackage});import{existsSync as existsSync22,mkdirSync as mkdirSync6,readdirSync as readdirSync10,copyFileSync as copyFileSync4,readFileSync as readFileSync14,writeFileSync as writeFileSync7,rmSync as rmSync4,statSync as statSync10,renameSync as renameSync3}from"fs";import{createHash as createHash5}from"crypto";import{join as join17,extname as extname3,basename as basename10,dirname as dirname10}from"path";import{existsSync as existsSync21,readFileSync as readFileSync13}from"fs";import{join as join16,dirname as dirname9}from"path";var locate2=()=>{let d2=import.meta.dir;for(let i=0;i<5;i++){let p=join16(d2,"assets/eikons");if(existsSync21(p))return p;let up=dirname9(d2);if(up===d2)break;d2=up}return join16(import.meta.dir,"../../../assets/eikons")},BUNDLED_EIKON_DIR=locate2(),packageEntrypoint=(dir)=>{let manifest3=join16(dir,"manifest.json");if(!existsSync21(manifest3))return;try{let entrypoints=JSON.parse(readFileSync13(manifest3,"utf8")).entrypoints,value2=entrypoints&&typeof entrypoints==="object"&&!Array.isArray(entrypoints)?entrypoints.default:void 0,path4=typeof value2==="string"?join16(dir,value2):void 0;return path4&&existsSync21(path4)?path4:void 0}catch{return}};function bundledEikonPath(name){if(!name)return;let id=name==="default"?"nous":name,dir=join16(BUNDLED_EIKON_DIR,id),entry3=packageEntrypoint(dir);if(entry3)return entry3;for(let p of[join16(dir,`${id}.eikon`),join16(BUNDLED_EIKON_DIR,`${id}.eikon`)])if(existsSync21(p))return p;return}import{deflateSync}from"zlib";import{spawnSync}from"child_process";import{statSync as statSync9}from"fs";var W2=48,H=24,FPS0=16,MAXF=256,S0={zoom:1,ox:0.5,oy:0.5},T0={contrast:1,invert:!0,flip:"none"},defaults=(r)=>Object.fromEntries(Object.entries(r.knobs).map(([k2,d2])=>[k2,d2.default])),caps3={chafa:chafaBin(),ffmpeg:spawnSync("ffmpeg",["-version"],{stdio:"ignore"}).status===0,ffprobe:spawnSync("ffprobe",["-version"],{stdio:"ignore"}).status===0};function probe(path4){if(!caps3.ffprobe)return null;let r=spawnSync("ffprobe",["-v","error","-select_streams","v:0","-show_entries","stream=width,height","-of","csv=p=0",path4],{encoding:"utf8"});if(r.status!==0)return null;let m2=r.stdout.trim().match(/^(\d+),(\d+)/);return m2?{w:+m2[1],h:+m2[2]}:null}var clamp=(x2,lo,hi)=>Math.min(hi,Math.max(lo,x2)),SCALE=384,PLANE=SCALE*SCALE,VID=/\.(mp4|webm|mov|mkv|m4v|gif)$/i,clips=new Map,CLIP_CAP=8;function decode2(src3,fps=FPS0){let full=resolveImage(src3);if(!full)return Promise.resolve(`not found: ${src3}`);let mt=statSync9(full,{throwIfNoEntry:!1})?.mtimeMs??0,key3=`${full}:${mt}:${fps}`,got=clips.get(key3);if(got)return clips.delete(key3),clips.set(key3,got),got;if(!caps3.ffmpeg)return Promise.resolve("ffmpeg not installed");let video=VID.test(full),vf=[...video?[`fps=${fps}`]:[],`scale=${SCALE}:${SCALE}:force_original_aspect_ratio=increase`,`crop=${SCALE}:${SCALE}`].join(","),p=(async()=>{let ff=Bun.spawn(["ffmpeg","-hide_banner","-loglevel","error","-i",full,"-vf",vf,"-frames:v",video?String(MAXF):"1","-f","rawvideo","-pix_fmt","gray","-"],{stdout:"pipe",stderr:"pipe"}),[buf,err]=await Promise.all([new Response(ff.stdout).arrayBuffer().then((b2)=>new Uint8Array(b2)),new Response(ff.stderr).text()]);if(await ff.exited,ff.exitCode!==0)return`ffmpeg: ${err.trim()||"failed"}`;if(buf.length===0||buf.length%PLANE!==0)return`ffmpeg: bad read (${buf.length})`;let n=buf.length/PLANE;return{planes:Array.from({length:n},(_2,i)=>buf.subarray(i*PLANE,(i+1)*PLANE)),fps:video?fps:0,w:SCALE,h:SCALE}})();if(clips.size>=CLIP_CAP)clips.delete(clips.keys().next().value);return clips.set(key3,p),p}var prewarm=(src3,fps=FPS0)=>void decode2(src3,fps);function crop(clip,sp){let side=Math.max(1,Math.round(clip.w*clamp(sp.zoom,0.1,1))),x0=Math.round((clip.w-side)*clamp(sp.ox,0,1)),y0=Math.round((clip.h-side)*clamp(sp.oy,0,1)),n=clip.planes.length,gray=new Uint8Array(side*side*n);for(let f=0;f<n;f++){let pl=clip.planes[f],off=f*side*side;for(let y2=0;y2<side;y2++)gray.set(pl.subarray((y0+y2)*clip.w+x0,(y0+y2)*clip.w+x0+side),off+y2*side)}let enc2;return{gray,w:side,h:side,frames:n,png:()=>enc2??=png(gray,side,side*n)}}function png(gray,w2,h2){let be32=(n)=>new Uint8Array([n>>>24,n>>>16&255,n>>>8&255,n&255]),T2=png_crc,crc=(b2)=>{let c=4294967295;for(let i=0;i<b2.length;i++)c=T2[(c^b2[i])&255]^c>>>8;return~c>>>0},chunk=(tag,data2)=>{let t2=new TextEncoder().encode(tag),body=new Uint8Array(t2.length+data2.length);return body.set(t2),body.set(data2,4),[be32(data2.length),body,be32(crc(body))]},ihdr=new Uint8Array(13);ihdr.set(be32(w2),0),ihdr.set(be32(h2),4),ihdr[8]=8,ihdr[9]=0,ihdr[10]=0,ihdr[11]=0,ihdr[12]=0;let raw=new Uint8Array(h2*(w2+1));for(let y2=0;y2<h2;y2++)raw.set(gray.subarray(y2*w2,(y2+1)*w2),y2*(w2+1)+1);let idat=new Uint8Array(deflateSync(raw,{level:1})),parts2=[new Uint8Array([137,80,78,71,13,10,26,10]),...chunk("IHDR",ihdr),...chunk("IDAT",idat),...chunk("IEND",new Uint8Array(0))],out=new Uint8Array(parts2.reduce((n,p)=>n+p.length,0)),o=0;for(let p of parts2)out.set(p,o),o+=p.length;return out}var png_crc=(()=>{let t2=new Uint32Array(256);for(let n=0;n<256;n++){let c=n;for(let k2=0;k2<8;k2++)c=c&1?3988292384^c>>>1:c>>>1;t2[n]=c>>>0}return t2})(),cache4=new Map,CAP3=256;function put(key3,v2){if(cache4.size>=CAP3)cache4.delete(cache4.keys().next().value);return cache4.set(key3,v2),v2}function hit(key3){let v2=cache4.get(key3);if(!v2)return;return cache4.delete(key3),cache4.set(key3,v2),v2}function resetCache(){cache4.clear(),clips.clear()}var keyOf=(r,src3,sp,tn,fps,k2)=>`${r}|${src3}|${fps}|${sp.zoom.toFixed(3)}:${sp.ox.toFixed(3)}:${sp.oy.toFixed(3)}|${tn.contrast.toFixed(2)}:${+tn.invert}:${tn.flip}|${JSON.stringify(k2)}`;async function cached2(r,src3,sp,tn,fps,k2,signal){let key3=keyOf(r.name,src3,sp,tn,fps,k2),got=hit(key3);if(got)return{frames:got};let cl=await decode2(src3,fps);if(typeof cl==="string")return{err:cl};if(signal?.aborted)return{err:"aborted"};let out=await r.render(tone(crop(cl,sp),tn),k2,signal);if("err"in out)return out;if(signal?.aborted)return{err:"aborted"};return{frames:put(key3,out.frames)}}function pad(rows3){let out=rows3.slice(0,H);while(out.length<H)out.push("");return out.map((l)=>{if(l.includes("\x1B["))return l;let cp=Array.from(l);return cp.length>=W2?cp.slice(0,W2).join(""):l+" ".repeat(W2-cp.length)})}function box(out,n){let rows3=out.replace(/\n$/,"").split(`
4156
+ high contrast, light subject on dark, black background`,BINDS=[{name:"return",action:"submit"},{name:"return",shift:!0,action:"newline"}],Generate=(props)=>{let theme=useTheme().theme,ta=import_react110.useRef(null),flight=import_react110.useRef(!1),[prompt,setPrompt]=import_react110.useState(props.lastPrompt??BASE),[useSeed,setUseSeed]=import_react110.useState(!!props.seed),[secs,setSecs]=import_react110.useState(2),[busy2,setBusy]=import_react110.useState(!1),[err,setErr]=import_react110.useState(null),[field,setField]=import_react110.useState("prompt");import_react110.useEffect(()=>{ta.current?.setCursor(0,0)},[]);let fields=props.kind==="video"?props.seed?["prompt","seed","seconds","submit"]:["prompt","seconds","submit"]:props.seed?["prompt","seed","submit"]:["prompt","submit"],advance=()=>setField((f)=>fields[(fields.indexOf(f)+1)%fields.length]),submit2=()=>{let p=prompt.trim(),bare=!props.lastPrompt&&p===BASE.trim();if(!p||bare||flight.current){if(bare)setErr("describe the subject on line 1");return}flight.current=!0,setBusy(!0),setErr(null),props.run(props.kind,p,{seed:props.seed&&useSeed?props.seed:void 0,seconds:props.kind==="video"?secs:void 0,aspect:props.kind==="video"?"1:1":"square"}).then((r)=>{if("err"in r){setErr(r.err),setBusy(!1);return}props.onDone(r.path,p)}).catch((e)=>{setErr(e instanceof Error?e.message:String(e)),setBusy(!1)}).finally(()=>{flight.current=!1})};useKeyboard((key3)=>{if(busy2)return;if(key3.name==="tab"){key3.preventDefault();let i=fields.indexOf(field),next3=fields[(i+(key3.shift?fields.length-1:1))%fields.length];setField(next3);return}if(field==="prompt")return;if(key3.name==="return")return field==="submit"?submit2():advance();if(field==="seed"&&(key3.name==="space"||key3.name==="left"||key3.name==="right")){setUseSeed((v2)=>!v2);return}if(field==="seconds"){if(key3.name==="left")return setSecs((v2)=>Math.max(1,v2-1));if(key3.name==="right")return setSecs((v2)=>Math.min(4,v2+1))}if(field==="submit"&&key3.name==="space")submit2()});let lbl=(id,text4)=>$jsx("box",{width:12,flexShrink:0,children:$jsxs("text",{fg:field===id?theme.accent:theme.textMuted,children:[field===id?"\u25B8 ":" ",text4]})});return $jsxs("box",{flexDirection:"column",width:72,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:`Generate ${props.kind} \u2014 ${props.state}`})})}),$jsx("box",{height:1}),$jsxs("box",{flexDirection:"row",children:[lbl("prompt","Prompt"),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("textarea",{ref:ta,initialValue:prompt,keyBindings:BINDS,onSubmit:advance,onContentChange:()=>{if(ta.current)setPrompt(ta.current.plainText)},focused:field==="prompt",placeholder:props.kind==="image"?"describe the image\u2026":"describe the motion\u2026",textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:field==="prompt"?theme.backgroundElement:void 0,focusedBackgroundColor:theme.backgroundElement,minHeight:4,maxHeight:6})})]}),props.seed?$jsxs("box",{height:1,flexDirection:"row",marginTop:1,children:[lbl("seed","Seed"),$jsx("box",{flexGrow:1,minWidth:0,height:1,children:$jsx("text",{fg:field==="seed"?theme.text:theme.textMuted,children:useSeed?"\u25CF base.png":"\u25CB none"})})]}):null,props.kind==="video"?$jsxs("box",{height:1,flexDirection:"row",marginTop:1,children:[lbl("seconds","Seconds"),$jsx("box",{width:20,height:1,children:$jsx("slider",{orientation:"horizontal",min:1,max:4,value:secs,foregroundColor:field==="seconds"?theme.accent:theme.textMuted,backgroundColor:theme.border,onChange:(v2)=>setSecs(Math.round(v2))})}),$jsx("box",{width:6,height:1,children:$jsx("text",{fg:field==="seconds"?theme.text:theme.textMuted,children:` ${secs}s`})})]}):null,$jsxs("box",{marginTop:1,flexDirection:"row",children:[lbl("submit",""),$jsx("box",{flexGrow:1,minWidth:0,children:busy2?$jsx("box",{height:1,children:$jsx(Spinner,{color:theme.accent,label:"generating\u2026"})}):err?$jsx("text",{fg:theme.warning,wrapMode:"word",children:err}):$jsx("box",{height:1,children:$jsx("text",{fg:field==="submit"?theme.accent:theme.textMuted,children:"[Enter] generate"})})})]}),$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter next \xB7 Shift+Enter newline \xB7 Tab field \xB7 Esc cancel"})})]})};function openGenerate(dialog,run,opts){return new Promise((resolve4)=>{let token=0;dialog.replace($jsx(Generate,{...opts,run,onDone:(p,txt)=>{if(resolve4(p?{path:p,prompt:txt}:null),dialog.version()===token)dialog.clear()}}),()=>resolve4(null)),token=dialog.version()})}var import_react112=__toESM(require_react_production(),1);import{existsSync as existsSync23,readFileSync as readFileSync15,rmSync as rmSync5}from"fs";import{createHash as createHash6}from"crypto";import{isIP}from"net";import{tmpdir as tmpdir5}from"os";import{basename as basename11,dirname as dirname11,join as join18}from"path";var exports_eikon={};__export(exports_eikon,{writeStudio:()=>writeStudio,useInstalled:()=>useInstalled,update:()=>update,studioFile:()=>studioFile,sourceStatus:()=>sourceStatus,sourceStamp:()=>sourceStamp,sourceName:()=>sourceName,sourceFetchUrl:()=>sourceFetchUrl,sourceExt:()=>sourceExt,sourceDir:()=>sourceDir,save:()=>save2,revision:()=>revision,remove:()=>remove2,register:()=>register,readStudio:()=>readStudio,raw:()=>raw,rasterizers:()=>rasterizers,rasterizer:()=>rasterizer,probe:()=>probe,previewPackage:()=>previewPackage,pick:()=>pick,peekSource:()=>peekSource,parseEikonFile:()=>parseEikonFile,parseEikon:()=>parseEikon,onRevision:()=>onRevision,onRegistry:()=>onRegistry,notifyRevision:()=>notifyRevision,localSources:()=>localSources,loadCatalog:()=>loadCatalog2,list:()=>list2,lifecycle:()=>lifecycle,installPackage:()=>installPackage,inspectSource:()=>inspectSource,header:()=>header,hasLocalSource:()=>hasLocalSource,findSource:()=>findSource,file:()=>file,fetchSource:()=>fetchSource,ensure:()=>ensure,eikon:()=>exports_eikon,downloadSource:()=>downloadSource,dir:()=>dir,baked:()=>baked,attachSources:()=>attachSources,adopt:()=>adopt,adaptPackage:()=>adaptPackage});import{existsSync as existsSync22,mkdirSync as mkdirSync6,readdirSync as readdirSync10,copyFileSync as copyFileSync4,readFileSync as readFileSync14,writeFileSync as writeFileSync7,rmSync as rmSync4,statSync as statSync10,renameSync as renameSync3}from"fs";import{createHash as createHash5}from"crypto";import{join as join17,extname as extname3,basename as basename10,dirname as dirname10}from"path";import{existsSync as existsSync21,readFileSync as readFileSync13}from"fs";import{join as join16,dirname as dirname9}from"path";var locate2=()=>{let d2=import.meta.dir;for(let i=0;i<5;i++){let p=join16(d2,"assets/eikons");if(existsSync21(p))return p;let up=dirname9(d2);if(up===d2)break;d2=up}return join16(import.meta.dir,"../../../assets/eikons")},BUNDLED_EIKON_DIR=locate2(),packageEntrypoint=(dir)=>{let manifest3=join16(dir,"manifest.json");if(!existsSync21(manifest3))return;try{let entrypoints=JSON.parse(readFileSync13(manifest3,"utf8")).entrypoints,value2=entrypoints&&typeof entrypoints==="object"&&!Array.isArray(entrypoints)?entrypoints.default:void 0,path4=typeof value2==="string"?join16(dir,value2):void 0;return path4&&existsSync21(path4)?path4:void 0}catch{return}};function bundledEikonPath(name){if(!name)return;let id=name==="default"?"nous":name,dir=join16(BUNDLED_EIKON_DIR,id),entry3=packageEntrypoint(dir);if(entry3)return entry3;for(let p of[join16(dir,`${id}.eikon`),join16(BUNDLED_EIKON_DIR,`${id}.eikon`)])if(existsSync21(p))return p;return}import{deflateSync}from"zlib";import{spawnSync}from"child_process";import{statSync as statSync9}from"fs";var W2=48,H=24,FPS0=16,MAXF=256,S0={zoom:1,ox:0.5,oy:0.5},T0={contrast:1,invert:!0,flip:"none"},defaults=(r)=>Object.fromEntries(Object.entries(r.knobs).map(([k2,d2])=>[k2,d2.default])),caps3={chafa:chafaBin(),ffmpeg:spawnSync("ffmpeg",["-version"],{stdio:"ignore"}).status===0,ffprobe:spawnSync("ffprobe",["-version"],{stdio:"ignore"}).status===0};function probe(path4){if(!caps3.ffprobe)return null;let r=spawnSync("ffprobe",["-v","error","-select_streams","v:0","-show_entries","stream=width,height","-of","csv=p=0",path4],{encoding:"utf8"});if(r.status!==0)return null;let m2=r.stdout.trim().match(/^(\d+),(\d+)/);return m2?{w:+m2[1],h:+m2[2]}:null}var clamp=(x2,lo,hi)=>Math.min(hi,Math.max(lo,x2)),SCALE=384,PLANE=SCALE*SCALE,VID=/\.(mp4|webm|mov|mkv|m4v|gif)$/i,clips=new Map,CLIP_CAP=8;function decode2(src3,fps=FPS0){let full=resolveImage(src3);if(!full)return Promise.resolve(`not found: ${src3}`);let mt=statSync9(full,{throwIfNoEntry:!1})?.mtimeMs??0,key3=`${full}:${mt}:${fps}`,got=clips.get(key3);if(got)return clips.delete(key3),clips.set(key3,got),got;if(!caps3.ffmpeg)return Promise.resolve("ffmpeg not installed");let video=VID.test(full),vf=[...video?[`fps=${fps}`]:[],`scale=${SCALE}:${SCALE}:force_original_aspect_ratio=increase`,`crop=${SCALE}:${SCALE}`].join(","),p=(async()=>{let ff=Bun.spawn(["ffmpeg","-hide_banner","-loglevel","error","-i",full,"-vf",vf,"-frames:v",video?String(MAXF):"1","-f","rawvideo","-pix_fmt","gray","-"],{stdout:"pipe",stderr:"pipe"}),[buf,err]=await Promise.all([new Response(ff.stdout).arrayBuffer().then((b2)=>new Uint8Array(b2)),new Response(ff.stderr).text()]);if(await ff.exited,ff.exitCode!==0)return`ffmpeg: ${err.trim()||"failed"}`;if(buf.length===0||buf.length%PLANE!==0)return`ffmpeg: bad read (${buf.length})`;let n=buf.length/PLANE;return{planes:Array.from({length:n},(_2,i)=>buf.subarray(i*PLANE,(i+1)*PLANE)),fps:video?fps:0,w:SCALE,h:SCALE}})();if(clips.size>=CLIP_CAP)clips.delete(clips.keys().next().value);return clips.set(key3,p),p}var prewarm=(src3,fps=FPS0)=>void decode2(src3,fps);function crop2(clip,sp){let side=Math.max(1,Math.round(clip.w*clamp(sp.zoom,0.1,1))),x0=Math.round((clip.w-side)*clamp(sp.ox,0,1)),y0=Math.round((clip.h-side)*clamp(sp.oy,0,1)),n=clip.planes.length,gray=new Uint8Array(side*side*n);for(let f=0;f<n;f++){let pl=clip.planes[f],off=f*side*side;for(let y2=0;y2<side;y2++)gray.set(pl.subarray((y0+y2)*clip.w+x0,(y0+y2)*clip.w+x0+side),off+y2*side)}let enc2;return{gray,w:side,h:side,frames:n,png:()=>enc2??=png(gray,side,side*n)}}function png(gray,w2,h2){let be32=(n)=>new Uint8Array([n>>>24,n>>>16&255,n>>>8&255,n&255]),T2=png_crc,crc=(b2)=>{let c=4294967295;for(let i=0;i<b2.length;i++)c=T2[(c^b2[i])&255]^c>>>8;return~c>>>0},chunk=(tag,data2)=>{let t2=new TextEncoder().encode(tag),body=new Uint8Array(t2.length+data2.length);return body.set(t2),body.set(data2,4),[be32(data2.length),body,be32(crc(body))]},ihdr=new Uint8Array(13);ihdr.set(be32(w2),0),ihdr.set(be32(h2),4),ihdr[8]=8,ihdr[9]=0,ihdr[10]=0,ihdr[11]=0,ihdr[12]=0;let raw=new Uint8Array(h2*(w2+1));for(let y2=0;y2<h2;y2++)raw.set(gray.subarray(y2*w2,(y2+1)*w2),y2*(w2+1)+1);let idat=new Uint8Array(deflateSync(raw,{level:1})),parts2=[new Uint8Array([137,80,78,71,13,10,26,10]),...chunk("IHDR",ihdr),...chunk("IDAT",idat),...chunk("IEND",new Uint8Array(0))],out=new Uint8Array(parts2.reduce((n,p)=>n+p.length,0)),o=0;for(let p of parts2)out.set(p,o),o+=p.length;return out}var png_crc=(()=>{let t2=new Uint32Array(256);for(let n=0;n<256;n++){let c=n;for(let k2=0;k2<8;k2++)c=c&1?3988292384^c>>>1:c>>>1;t2[n]=c>>>0}return t2})(),cache4=new Map,CAP3=256;function put(key3,v2){if(cache4.size>=CAP3)cache4.delete(cache4.keys().next().value);return cache4.set(key3,v2),v2}function hit(key3){let v2=cache4.get(key3);if(!v2)return;return cache4.delete(key3),cache4.set(key3,v2),v2}function resetCache(){cache4.clear(),clips.clear()}var keyOf=(r,src3,sp,tn,fps,k2)=>`${r}|${src3}|${fps}|${sp.zoom.toFixed(3)}:${sp.ox.toFixed(3)}:${sp.oy.toFixed(3)}|${tn.contrast.toFixed(2)}:${+tn.invert}:${tn.flip}|${JSON.stringify(k2)}`;async function cached2(r,src3,sp,tn,fps,k2,signal){let key3=keyOf(r.name,src3,sp,tn,fps,k2),got=hit(key3);if(got)return{frames:got};let cl=await decode2(src3,fps);if(typeof cl==="string")return{err:cl};if(signal?.aborted)return{err:"aborted"};let out=await r.render(tone(crop2(cl,sp),tn),k2,signal);if("err"in out)return out;if(signal?.aborted)return{err:"aborted"};return{frames:put(key3,out.frames)}}function pad(rows3){let out=rows3.slice(0,H);while(out.length<H)out.push("");return out.map((l)=>{if(l.includes("\x1B["))return l;let cp=Array.from(l);return cp.length>=W2?cp.slice(0,W2).join(""):l+" ".repeat(W2-cp.length)})}function box(out,n){let rows3=out.replace(/\n$/,"").split(`
4157
4157
  `);return Array.from({length:n},(_2,i)=>pad(rows3.slice(i*H,(i+1)*H)))}function thumb(frame,w2=16,h2=8){let fx=W2/w2,fy=H/h2;return Array.from({length:h2},(_2,y2)=>{let row3=Array.from(frame[Math.min(H-1,Math.floor(y2*fy+fy/2))]??""),n=row3.length;return Array.from({length:w2},(_3,x2)=>row3[Math.min(n-1,Math.floor(x2*fx+fx/2))]??" ").join("")})}function tone(win,t2){let{gray:g,w:w2,h:h2,frames:n}=win,sz=w2*h2,flip=t2.flip,con=clamp(t2.contrast,0.25,4);for(let f=0;f<n;f++){let o=f*sz;if(flip==="h"||flip==="hv")for(let y2=0;y2<h2;y2++){let ro=o+y2*w2;for(let x2=0;x2<w2>>1;x2++){let t3=g[ro+x2];g[ro+x2]=g[ro+w2-1-x2],g[ro+w2-1-x2]=t3}}if(flip==="v"||flip==="hv")for(let y2=0;y2<h2>>1;y2++){let a=g.subarray(o+y2*w2,o+(y2+1)*w2),b2=g.subarray(o+(h2-1-y2)*w2,o+(h2-y2)*w2),t3=new Uint8Array(a);a.set(b2),b2.set(t3)}}if(Math.abs(con-1)>0.001)for(let f=0;f<n;f++){let o=f*sz,sum=0;for(let i=0;i<sz;i++)sum+=g[o+i];let m2=sum/sz;for(let i=0;i<sz;i++)g[o+i]=clamp(Math.round((g[o+i]-m2)*con+m2),0,255)}if(t2.invert)for(let i=0;i<g.length;i++)g[i]=255-g[i];return win}var chafa={name:"chafa",knobs:{symbols:{kind:"cycle",options:["braille","block","ascii","sextant","quad","half","wedge"],default:"braille",hint:"Glyph family used to draw pixels. Braille is densest; block is boldest; ascii is most compatible."},fill:{kind:"cycle",options:["none","stipple","ascii","braille"],default:"none",hint:"Secondary glyph set used where the primary leaves gaps."},dither:{kind:"cycle",options:["none","ordered","diffusion","noise"],default:"none",hint:"Adds texture to smooth gradients so mid-tones don't band."}},available:()=>caps3.chafa?!0:"chafa not installed",async render(win,k2,signal){let bin=caps3.chafa;if(!bin)return{err:"chafa not installed"};let fill=String(k2.fill??"none"),args=[`--size=${W2}x${H*win.frames}`,"--format=symbols","--stretch","--colors=none",`--symbols=${String(k2.symbols??"braille")}`,...fill==="none"?[]:[`--fill=${fill}`],`--dither=${String(k2.dither??"none")}`,"--preprocess","off","-"];if(signal?.aborted)return{err:"aborted"};let ch=Bun.spawn([bin,...args],{stdin:win.png(),stdout:"pipe",stderr:"pipe"}),kill=()=>ch.kill();signal?.addEventListener("abort",kill,{once:!0});let[out,cerr]=await Promise.all([new Response(ch.stdout).text(),new Response(ch.stderr).text()]);if(await ch.exited,signal?.removeEventListener("abort",kill),signal?.aborted)return{err:"aborted"};if(ch.exitCode!==0)return{err:`chafa: ${cerr.trim()||"failed"}`};return{frames:box(out,win.frames)}}},DOT=[[1,8],[2,16],[4,32],[64,128]],RAMP=" .:-=+*#%@";function sample(g,w2,h2,fw,fh){let sx=w2/fw,sy=h2/fh;return(gx,gy)=>g[Math.min(h2-1,Math.floor(gy*sy))*w2+Math.min(w2-1,Math.floor(gx*sx))]}function mean(g){let s=0;for(let i=0;i<g.length;i++)s+=g[i];return s/g.length}function braille(g,w2,h2){let at=sample(g,w2,h2,W2*2,H*4),thr=mean(g),rows3=[];for(let y2=0;y2<H;y2++){let row3="";for(let x2=0;x2<W2;x2++){let bits=0;for(let dy=0;dy<4;dy++)for(let dx=0;dx<2;dx++)if(at(x2*2+dx,y2*4+dy)>thr)bits|=DOT[dy][dx];row3+=String.fromCodePoint(10240+bits)}rows3.push(row3)}return rows3}function block(g,w2,h2){let at=sample(g,w2,h2,W2,H),n=RAMP.length-1,rows3=[];for(let y2=0;y2<H;y2++){let row3="";for(let x2=0;x2<W2;x2++)row3+=RAMP[Math.round(at(x2,y2)/255*n)];rows3.push(row3)}return rows3}var native={name:"native",knobs:{symbols:{kind:"cycle",options:["braille","block"],default:"braille",hint:"Glyph family used to draw pixels. Braille is denser; block is bolder."}},available:()=>caps3.ffmpeg?!0:"ffmpeg not installed",async render(win,k2){let fn=k2.symbols==="block"?block:braille,sz=win.w*win.h;return{frames:Array.from({length:win.frames},(_2,i)=>fn(win.gray.subarray(i*sz,(i+1)*sz),win.w,win.h))}}},BUILTIN=[chafa,native];var exports_eikon_knobs={};__export(exports_eikon_knobs,{zoom:()=>zoom,unfork:()=>unfork,toStudio:()=>toStudio,swap:()=>swap,step:()=>step,slug:()=>slug2,setState:()=>setState,setSlider:()=>setSlider,reset:()=>reset2,pan:()=>pan,knobs:()=>exports_eikon_knobs,fresh:()=>fresh,fork:()=>fork,eff:()=>eff,edit:()=>edit,cycle:()=>cycle2,STATES:()=>STATES2});var STATES2=["idle","listening","thinking","speaking","working","error"],clamp2=(x2,lo,hi)=>Math.min(hi,Math.max(lo,x2)),round=(x2,p=3)=>+x2.toFixed(p),wrap=(arr3,cur,d2)=>arr3[(Math.max(0,arr3.indexOf(cur))+d2+arr3.length)%arr3.length];function fresh(name,r,seed){return{name,state:"idle",dims:null,dirty:!1,rasterizer:seed?.rasterizer??r.name,spatial:seed?.spatial??{...S0},tone:{...T0,...seed?.tone},fps:seed?.fps??FPS0,base:seed?.base??defaults(r),per:seed?.per??{},glyph:seed?.glyph??"\u25C6",sources:seed?.sources??{},prompts:seed?.prompts??{}}}var eff=(s,state3)=>s.per[state3]??s.base;function edit(s,fn){let own=s.per[s.state];return own?{...s,per:{...s.per,[s.state]:fn(own)},dirty:!0}:{...s,base:fn(s.base),dirty:!0}}var fork=(s)=>s.per[s.state]?s:{...s,per:{...s.per,[s.state]:{...s.base}},dirty:!0},unfork=(s)=>{if(!s.per[s.state])return s;let{[s.state]:_2,...rest}=s.per;return{...s,per:rest,dirty:!0}},setState=(s,state3)=>({...s,state:state3}),cycle2=(s,d2)=>setState(s,wrap(STATES2,s.state,d2));function step(k2,id,def2,d2){if(def2.kind==="cycle")return{...k2,[id]:wrap(def2.options,String(k2[id]??def2.default),d2)};if(def2.kind==="toggle")return{...k2,[id]:!(k2[id]??def2.default)};let cur=Number(k2[id]??def2.default);return{...k2,[id]:round(clamp2(cur+d2*def2.step,def2.min,def2.max))}}function setSlider(k2,id,def2,v2){if(def2.kind!=="slider")return k2;return{...k2,[id]:round(clamp2(v2,def2.min,def2.max))}}function pan(sp,dx,dy,fine=!1){let s=fine?0.01:0.03;return{zoom:sp.zoom,ox:round(clamp2(sp.ox+dx*s,0,1)),oy:round(clamp2(sp.oy+dy*s,0,1))}}function zoom(sp,d2,fine=!1){let s=fine?0.02:0.05;return{...sp,zoom:round(clamp2(sp.zoom+d2*s,0.1,1))}}function swap(s,r){return{...s,rasterizer:r.name,base:defaults(r),per:{},dirty:!0}}var reset2=(s,r)=>({...s,spatial:{...S0},tone:{...T0},base:defaults(r),per:{},dirty:!0}),slug2=(v2)=>v2.toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/^-+|-+$/g,"")||"wip",toStudio=(s)=>({rasterizer:s.rasterizer,spatial:s.spatial,tone:s.tone,fps:s.fps,base:s.base,per:s.per,glyph:s.glyph,sources:s.sources,prompts:s.prompts});var ROOT=()=>hermesPath("eikons"),dir=(name)=>join17(ROOT(),name),file=(name)=>join17(dir(name),`${name}.eikon`),flat=(name)=>join17(ROOT(),`${name}.eikon`),sourceDir=(name)=>join17(dir(name),"source"),studioFile=(name)=>join17(dir(name),"studio.json");function ensure(name){return mkdirSync6(sourceDir(name),{recursive:!0}),{dir:dir(name),file:file(name),source:sourceDir(name)}}function manifest3(name){let p=join17(dir(name),"manifest.json");if(!existsSync22(p))return;try{let raw=JSON.parse(readFileSync14(p,"utf8"));if(raw&&typeof raw==="object")return raw}catch{}return}var LEGACY_SOURCE_URL="source_url",OBJ=(x2)=>!!x2&&typeof x2==="object"&&!Array.isArray(x2);function originObject(man){let o=man?.origin;return OBJ(o)?o:void 0}function origin(man){let src3=originObject(man)?.source;return typeof src3==="string"?src3:void 0}function legacySource(head){let src3=head?.[LEGACY_SOURCE_URL];return typeof src3==="string"?src3:void 0}function display2(man){return OBJ(man?.display)?man.display:void 0}function sourceInfo(man,head){let o=originObject(man),src3=typeof o?.source==="string"?o.source:legacySource(head),identity2=o?.identityKey??o?.sourceKey??o?.packageUrl??o?.repo??src3;return{kind:o?.kind??"unknown",...identity2?{identity:identity2}:{},...src3?{origin:src3}:{},...o?.repo?{repo:o.repo}:{},...o?.selector?{selector:o.selector}:{},...o?.catalogRoot?{catalogRoot:o.catalogRoot}:{},...o?.sha?{sha:o.sha}:{},...o?.packageUrl?{packageUrl:o.packageUrl}:{}}}function displayTitle(man){let disp=display2(man);return typeof disp?.title==="string"?disp.title:typeof man?.title==="string"?man.title:void 0}function displayAuthor(man){let disp=display2(man);return typeof disp?.author==="string"?disp.author:typeof man?.author==="string"?man.author:void 0}function sourceLabel(src3){let id=src3.repo??src3.identity??src3.origin??src3.packageUrl;if(!id)return src3.kind;if(src3.sha)return`${src3.kind} ${id}@${src3.sha.slice(0,12)}`;return`${src3.kind} ${id}`}function inspectResolved(src3,r,stat2){let{manifest:man,origin:o}=r,info2={kind:o.kind??"unknown",...o.identityKey||o.sourceKey||o.packageUrl||o.repo||o.source?{identity:o.identityKey??o.sourceKey??o.packageUrl??o.repo??o.source}:{},...o.source?{origin:o.source}:{},...o.repo?{repo:o.repo}:{},...o.selector?{selector:o.selector}:{},...o.catalogRoot?{catalogRoot:o.catalogRoot}:{},...o.sha?{sha:o.sha}:{},...o.packageUrl?{packageUrl:o.packageUrl}:{}},compatibility=OBJ(man.compatibility)?man.compatibility:void 0,poster2=typeof man.poster==="string"?man.poster:void 0,preview2=typeof man.preview==="string"?man.preview:void 0,out={name:r.name,...displayTitle(man)?{title:displayTitle(man)}:{},...displayAuthor(man)?{author:displayAuthor(man)}:{},...typeof man.version==="string"?{version:man.version}:{},source:info2,trust:r.trust.state,active:get2("eikon")===r.name,removable:!1,updateable:!0,updateAvailable:!1,dirty:!1,...poster2?{poster:poster2}:{},...preview2?{preview:preview2}:{},...compatibility?{compatibility}:{},installed:existsSync22(file(r.name)),sourceLabel:sourceLabel(info2),previewAvailable:Boolean(preview2||man.entrypoints?.default),posterAvailable:Boolean(poster2),...stat2?{n:stat2.n,bytes:stat2.bytes}:{},...r.trust.reason?{reason:r.trust.reason}:{}};if(!out.source.origin)out.source.origin=src3;return out}function changed(name){try{return dirty(dir(name))}catch{return!1}}function lifecycle(name,opts={}){let man=manifest3(name),head=header(file(name)),src3=sourceInfo(man,head),title=displayTitle(man),author=displayAuthor(man),version=typeof man?.version==="string"?man.version:void 0,compatibility=OBJ(man?.compatibility)?man.compatibility:void 0,installedAt=originObject(man)?.at,hasOrigin=Boolean(src3.origin??src3.packageUrl),isDirty=opts.dirty!==!1&&existsSync22(dir(name))?changed(name):!1;return{name,...title?{title}:{},...author?{author}:{},...version?{version}:{},source:src3,trust:originObject(man)?.trust??(src3.origin?"unverified":"unknown"),active:get2("eikon")===name,removable:existsSync22(file(name)),updateable:hasOrigin,updateAvailable:!1,dirty:isDirty,...typeof man?.poster==="string"?{poster:man.poster}:{},...typeof man?.preview==="string"?{preview:man.preview}:{},...compatibility?{compatibility}:{},...installedAt?{installedAt}:{}}}function list2(){let root3=ROOT();if(!existsSync22(root3))return[];return readdirSync10(root3,{withFileTypes:!0}).filter((e)=>e.isDirectory()&&existsSync22(join17(root3,e.name,`${e.name}.eikon`))).map((e)=>{let name=e.name;normalizeStoredSources(name);let man=manifest3(name),path4=join17(root3,name,`${name}.eikon`);return{name,file:path4,source:join17(root3,name,"source"),hasSource:hasLocalSource(name),sourceUrl:sourceUrl(man,header(path4)),manifest:man,lifecycle:lifecycle(name,{dirty:!1})}})}function raw(){let root3=ROOT();if(!existsSync22(root3))return[];return readdirSync10(root3,{withFileTypes:!0}).filter((e)=>e.isDirectory()).map((e)=>e.name)}var IMG=/\.(png|jpe?g|webp|gif|bmp)$/i,VID2=/\.(mp4|webm|mov|mkv)$/i,MEDIA_EXT={"image/png":".png","image/jpeg":".jpg","image/jpg":".jpg","image/webp":".webp","image/gif":".gif","image/bmp":".bmp","video/mp4":".mp4","video/webm":".webm","video/quicktime":".mov","video/x-matroska":".mkv"};function slot(role){return role==="base"||STATES2.includes(role)}function sourceExt(man,rel2){let ext=extname3(rel2).toLowerCase();if(ext)return ext;let type=man?.files?.find((f)=>f.path===rel2)?.mediaType?.split(";")[0]?.trim().toLowerCase();return type?MEDIA_EXT[type]??"":""}function sourceName(man,role,rel2){return`${role}${sourceExt(man,rel2)}`}function sourceRefs(man){if(!man)return new Map;try{return new Map(entries(man).filter(([role])=>slot(String(role))).map(([role,rel2])=>[String(role),rel2]))}catch{return new Map}}function normalizeSources(name,sources){let man=manifest3(name),refs2=sourceRefs(man),root3=sourceDir(name);return Object.fromEntries(Object.entries(sources).map(([role,fname])=>{if(!fname)return[role,fname];let rel2=refs2.get(role),next3=rel2?sourceName(man,role,rel2):fname;if(next3===fname)return[role,fname];let from2=join17(root3,fname),to=join17(root3,next3);if(existsSync22(from2)&&!existsSync22(to))renameSync3(from2,to);return[role,existsSync22(to)?next3:fname]}))}function sameSources(a,b2){return JSON.stringify(a)===JSON.stringify(b2)}function normalizeStudioSources(name,s){let prev=s.sources??{},sources=normalizeSources(name,prev);if(sameSources(prev,sources))return s;let next3={...s,sources};return writeFileSync7(studioFile(name),JSON.stringify(next3,null,2)+`
4158
4158
  `,"utf8"),next3}function normalizeStoredSources(name){try{readStudio(name)}catch{}}function fileOk(name){return IMG.test(name)||VID2.test(name)}function roleOf(name){let stem=basename10(name,extname3(name)).toLowerCase();if(stem==="base")return"base";return STATES2.includes(stem)?stem:void 0}function sourcePath(name,value2){return value2.includes("/")?value2:join17(sourceDir(name),value2)}function storedName(value2){return value2.includes("/")?basename10(value2):value2}function sourceFiles(name){let src3=sourceDir(name);if(!existsSync22(src3))return[];return readdirSync10(src3).filter(fileOk)}function byRole(files,role){return files.find((f)=>roleOf(f)===role)}function roles(state3){if(!state3)return["base","idle"];return state3==="idle"?["idle","base"]:[state3,"base","idle"]}function entryRole(value2,path4){if(value2==="source.base")return"base";if(value2?.startsWith("source.")){let role=value2.slice(7);if(role==="base")return"base";if(STATES2.includes(role))return role}return roleOf(path4)??"base"}function sourceEntries(man,strict=!1){if(!man)return[];try{let xs=entries(man).map(([role,path4])=>[role,path4]);if(xs.length)return xs}catch(err){if(strict)throw err}return(Array.isArray(man.files)?man.files:[]).flatMap((file2)=>{if(typeof file2==="string")return[[entryRole(void 0,file2)??"base",file2]];if(!OBJ(file2)||typeof file2.path!=="string"||!String(file2.role??"").startsWith("source"))return[];let role=entryRole(typeof file2.role==="string"?file2.role:void 0,file2.path);return role?[[role,file2.path]]:[]})}function sourceUrl(man,head){let src3=sourceInfo(man,head);return src3.packageUrl??src3.origin}function sourceFetchUrl(name){return sourceUrl(manifest3(name),header(file(name)))}function sourceStatus(name,state3,opts={}){let seed=opts.sources??readStudio(name)?.sources,files=sourceFiles(name),removed=new Set(Object.entries(seed??{}).flatMap(([role,value2])=>value2===null?[role]:[])),visible2=files.filter((f)=>{let role=roleOf(f);return!role||!removed.has(role)}),hit2=(role)=>{if(removed.has(role))return;let value2=seed?.[role];if(typeof value2==="string"&&value2){let path4=sourcePath(name,value2);if(existsSync22(path4)&&fileOk(path4))return{path:path4,file:storedName(value2),role,origin:opts.sources?"draft":"studio"}}let file2=byRole(visible2,role);return file2?{path:join17(sourceDir(name),file2),file:file2,role,origin:"discovered"}:void 0},found=roles(state3).map(hit2).find(Boolean),first=removed.size?void 0:visible2.find((f)=>IMG.test(f))??visible2.find((f)=>VID2.test(f)),src3=found??(first?{path:join17(sourceDir(name),first),file:first,role:roleOf(first),origin:"fallback"}:void 0),st=state3??"idle",own=Boolean(src3?.role&&(src3.role===st||st==="idle"&&src3.role==="base")),man=manifest3(name),pack=baked(name),head=header(file(name))??(pack?header(pack):void 0),url2=sourceUrl(man,head),downloadable=!src3&&Boolean(url2),size=src3?.path?(()=>{try{return statSync10(src3.path).size}catch{return}})():void 0;return{name,state:st,kind:src3?"local":downloadable?"downloadable":pack?"baked":"missing",...src3?.path?{path:src3.path}:{},...src3?.file?{file:src3.file}:{},...size!==void 0?{size}:{},...src3?.role?{role:src3.role}:{},...src3?.origin?{origin:src3.origin}:{},own,inherited:Boolean(src3&&!own),removed:roles(state3).some((role)=>removed.has(role)),downloadable,...url2?{sourceUrl:url2}:{}}}function localSources(name){return sourceFiles(name).map((file2)=>({file:file2,path:join17(sourceDir(name),file2),...roleOf(file2)?{role:roleOf(file2)}:{}}))}function hasLocalSource(name){if(sourceFiles(name).length>0)return!0;return Object.values(readStudio(name)?.sources??{}).some((value2)=>typeof value2==="string"&&fileOk(value2)&&existsSync22(sourcePath(name,value2)))}function sourceStamp(name){let src3=sourceDir(name),stats=[studioFile(name),existsSync22(file(name))?file(name):""].filter(Boolean).map((path4)=>{try{let st=statSync10(path4);return`${basename10(path4)}:${st.mtimeMs}:${st.size}`}catch{return`${basename10(path4)}:missing`}}),media=sourceFiles(name).sort().map((f)=>{try{let st=statSync10(join17(src3,f));return`${f}:${st.mtimeMs}:${st.size}`}catch{return`${f}:missing`}});return[...stats,...media].join("|")}function findSource(name,state3){return sourceStatus(name,state3).path}function adopt(name,from2,role="base"){let fname=`${role}${extname3(from2).toLowerCase()}`,dst=join17(ensure(name).source,fname);if(from2!==dst)copyFileSync4(from2,dst);return fname}function readStudio(name){let p=studioFile(name);if(!existsSync22(p))return;let raw2=JSON.parse(readFileSync14(p,"utf8"));if(!raw2||typeof raw2!=="object")return;return normalizeStudioSources(name,raw2)}function writeStudio(name,s){ensure(name),writeFileSync7(studioFile(name),JSON.stringify(s,null,2)+`
4159
4159
  `,"utf8")}function header(path4){if(!existsSync22(path4))return;return peek2(path4)??void 0}function baked(name){let local=file(name);if(existsSync22(local))return local;let old=flat(name);if(existsSync22(old))return old;let target=(name==="default"?"nous":name).toLowerCase();for(let e of listEikons([BUNDLED_EIKON_DIR]))if(basename10(dirname10(e.path)).toLowerCase()===target||e.meta.name.toLowerCase()===target)return e.path;return}var registry=new Map(BUILTIN.map((r)=>[r.name,r])),subs2=new Set;function register(r){registry.set(r.name,r);for(let f of subs2)f();return()=>{if(registry.get(r.name)===r)registry.delete(r.name);for(let f of subs2)f()}}var rasterizers=()=>[...registry.values()],rasterizer=(name)=>registry.get(name),onRegistry=(fn)=>{return subs2.add(fn),()=>subs2.delete(fn)};function pick(prefer){let want=prefer&&registry.get(prefer);if(want&&want.available()===!0)return want;for(let r of registry.values())if(r.available()===!0)return r;return registry.get("native")}var rev2=0,revSubs=new Set,revision=()=>rev2,onRevision=(fn)=>{return revSubs.add(fn),()=>revSubs.delete(fn)},bump=()=>{rev2++;for(let f of revSubs)f()},notifyRevision=bump;function serialize2(name,fps,clips2){let records=[{type:"header",eikon:1,id:name,title:name,author:{name:process.env.USER??"unknown"},size:{cols:W2,rows:H},defaultSignal:"state.idle",signals:defaultSignalMappings()}];for(let st of STATES2){let fs7=clips2.get(st);records.push({type:"clip",name:st,fps,frameCount:fs7.length,loopFrom:0}),fs7.forEach((f,i)=>records.push({type:"frame",clip:st,index:i,rows:f}))}return serializeLaunchStream(records)}function preserve(name,src3){if(!src3)return;let man=manifest3(name)??{name};if(origin(man))return;writeFileSync7(join17(dir(name),"manifest.json"),JSON.stringify({...man,origin:{source:src3,at:new Date().toISOString()}},null,2)+`
@@ -4161,14 +4161,14 @@ high contrast, light subject on dark, black background`,BINDS=[{name:"return",ac
4161
4161
  `,"utf8")}function statResolved(r){let xs=entries(r.manifest),files=Array.isArray(r.manifest.files)?r.manifest.files:[],sizes=xs.map(([,rel2])=>files.find((f)=>f.path===rel2)?.size);if(sizes.every((n)=>typeof n==="number"))return{n:xs.length,bytes:sizes.reduce((a,b2)=>a+b2,0)};if(r.staged)return{n:xs.length,bytes:xs.reduce((sum,[,rel2])=>{let p=join17(r.staged,rel2);return existsSync22(p)?sum+statSync10(p).size:sum},0)};return}async function inspectSource(src3){let dl=/^http:\/\/localhost[:/]/.test(src3)?{allowPrivate:!0}:void 0,r=await resolve5(src3,{downloader:dl});return inspectResolved(src3,r,statResolved(r))}function attachSources(name,sources){let prev=readStudio(name);writeStudio(name,{...prev??toStudio(fresh(name,pick())),sources:{...prev?.sources,...sources}}),bump()}function digest(data2){return`sha256:${createHash5("sha256").update(data2).digest("hex")}`}function dlOpts(url2,opts={}){return/^http:\/\/localhost[:/]/.test(url2)?{allowPrivate:!0,...opts}:opts}function manUrl(url2){if(url2.endsWith("manifest.json"))return url2;return new URL("manifest.json",url2.endsWith("/")?url2:`${url2}/`).toString()}function specOf(man,rel2){return(Array.isArray(man.files)?man.files:[]).find((f)=>OBJ(f)&&f.path===rel2)}async function readManifest(url2,opts){let raw2=await downloadBytes(url2,opts),man=JSON.parse(Buffer.from(raw2).toString("utf8"));if(!OBJ(man))throw Error("source manifest: object required");return man}async function readSource(file2,base3,rel2,opts){let raw2=await downloadBytes(new URL(rel2,base3).toString(),opts),size=file2?.size;if(typeof size==="number"&&raw2.length!==size)throw Error(`source size mismatch: ${rel2}`);if(typeof file2?.digest==="string"&&digest(raw2)!==file2.digest)throw Error(`source digest mismatch: ${rel2}`);return raw2}async function downloadSource(name,opts={}){let url2=sourceFetchUrl(name);if(!url2)throw Error(`eikon '${name}' has no published source`);let href=manUrl(url2),root3=href.slice(0,href.lastIndexOf("/")+1),dl=dlOpts(url2,opts.downloader),man=await readManifest(href,dl),xs=sourceEntries(man,!0);if(xs.length===0)throw Error(`eikon '${name}' has no published source media`);let dir2=ensure(name).source,pairs=await Promise.all(xs.map(async([role,rel2])=>{let file2=specOf(man,rel2),fname=sourceName(man,role,rel2);if(!fileOk(fname))throw Error(`source media type unsupported: ${rel2}`);return[role,fname,await readSource(file2,root3,rel2,dl)]})),sources={};return await Promise.all(pairs.map(async([role,fname,data2])=>{await Bun.write(join17(dir2,fname),data2),sources[role]=fname})),attachSources(name,sources),{name,sources,n:pairs.length,bytes:pairs.reduce((sum,[,,data2])=>sum+data2.length,0)}}async function fetchSource(src3,opts){let out=await install(src3,ROOT(),opts);stripManifestTrust(out.name);let sources=normalizeSources(out.name,out.sources);return attachSources(out.name,sources),{name:out.name,sources,n:out.n,bytes:out.bytes}}var SAFE=/^[a-zA-Z0-9._/-]+$/;function safePath(path4){if(!path4||path4.startsWith("/")||path4.startsWith("./")||path4.includes("../")||path4==="..")return!1;if(!SAFE.test(path4))return!1;return!path4.split("/").includes("..")}function pkgErr(path4,msg){return Error(`${path4}: ${msg}`)}function launchOk(range){let lower=range.match(/>=?\s*(\d+)/);if(lower&&Number(lower[1])>1)return!1;let exact=range.match(/^\s*(\d+)(?:\.\d+)?\s*$/);if(exact&&Number(exact[1])!==1)return!1;if(/>=?\s*2\b|\^\s*2\b/.test(range))return!1;return!/^\s*>=?\s*99/.test(range)}function validatePkg(value2){if(!OBJ(value2))throw pkgErr("manifest","object required");let man=value2;if(man.kind!=="eikon.package")throw pkgErr("kind","must be eikon.package");if(!/^[a-z0-9][a-z0-9-]{1,63}$/.test(String(man.name??"")))throw pkgErr("name","safe package name required");if(!man.id||typeof man.id!=="string")throw pkgErr("id","safe id required");if(!OBJ(man.compatibility)||typeof man.compatibility.eikon!=="string")throw pkgErr("compatibility.eikon","required");if(!launchOk(man.compatibility.eikon))throw pkgErr("compatibility.eikon","must support launch major version 1");if(!OBJ(man.entrypoints)||typeof man.entrypoints.default!=="string"||!safePath(man.entrypoints.default))throw pkgErr("entrypoints.default","safe relative path required");for(let[k2,p]of Object.entries(man.entrypoints))if(typeof p!=="string"||!safePath(p))throw pkgErr(`entrypoints.${k2}`,"safe relative path required");for(let f of man.files??[])if(!f||typeof f.path!=="string"||!safePath(f.path))throw pkgErr("files.path","safe relative path required");if(man.poster&&!safePath(man.poster))throw pkgErr("poster","safe relative path required");return man}function asUrl(value2,base3){if(/^file:\/\//.test(value2))return value2;let out=new URL(value2,base3);if(out.protocol!=="http:"&&out.protocol!=="https:")throw pkgErr("packageUrl","http(s) URL required");return out.toString()}function relUrl(base3,path4){if(!path4)return;if(/^(https?|file):\/\//.test(path4))return asUrl(path4);if(!safePath(path4))throw pkgErr("path","safe relative path required");return new URL(path4,base3).toString()}function entryState(name,available2=!0){if(!available2)return"incompatible";if(get2("eikon")===name)return"active";if(existsSync22(file(name)))return"installed";return"available"}function normalize2(input,base3){if(!OBJ(input))throw pkgErr("catalog","entry object required");if(input.kind==="eikon.catalog.entry"){let entry3=input;return{...entry3,state:entryState(entry3.name,entry3.compatibility?.available!==!1)}}if(OBJ(input.manifest)&&typeof input.packageUrl==="string"){let man=validatePkg(input.manifest),packageUrl3=asUrl(input.packageUrl,base3),root3=packageUrl3.slice(0,packageUrl3.lastIndexOf("/")+1);return{kind:"eikon.catalog.entry",schemaVersion:"1.0",id:man.id,sourceKey:typeof input.sourceKey==="string"?input.sourceKey:packageUrl3,name:man.name,title:man.display?.title,author:man.display?.author,description:man.display?.description,glyph:man.display?.glyph,tags:man.display?.tags,poster:relUrl(root3,man.poster),packageUrl:packageUrl3,detailUrl:typeof input.detailUrl==="string"?asUrl(input.detailUrl,root3):void 0,compatibility:{eikon:man.compatibility.eikon,hosts:man.compatibility.hosts,available:launchOk(man.compatibility.eikon)},state:entryState(man.name,launchOk(man.compatibility.eikon))}}let name=String(input.name??"");if(!/^[a-z0-9][a-z0-9-]{1,63}$/.test(name))throw pkgErr("name","safe catalog name required");let source=typeof input.source==="string"?input.source:`${name}/`,packageUrl2=/^(https?|file):\/\//.test(source)?asUrl(source):base3?new URL(source,base3).toString():source,manifest4=packageUrl2.endsWith("manifest.json")?packageUrl2:new URL("manifest.json",packageUrl2.endsWith("/")?packageUrl2:`${packageUrl2}/`).toString();return{kind:"eikon.catalog.entry",schemaVersion:"1.0",id:name,sourceKey:packageUrl2,name,author:typeof input.author==="string"?input.author:void 0,title:typeof input.title==="string"?input.title:void 0,description:typeof input.description==="string"?input.description:void 0,tags:Array.isArray(input.tags)?input.tags.filter((x2)=>typeof x2==="string"):void 0,glyph:typeof input.glyph==="string"?input.glyph:void 0,poster:typeof input.poster==="string"?input.poster:void 0,packageUrl:manifest4,compatibility:{eikon:">=1 <2",available:!0},state:entryState(name)}}async function loadText(url2,fetcher=fetch){if(url2.startsWith("file://"))return readFileSync14(new URL(url2),"utf8");let res=await fetcher(url2);if(!res.ok)throw Error(`fetch: ${res.status} ${url2}`);return await res.text()}async function loadBytes(url2,fetcher=fetch,desc){if(url2.startsWith("file://"))return new Uint8Array(readFileSync14(new URL(url2)));let res=await fetcher(url2);if(!res.ok)throw Error(`fetch: ${res.status} ${url2}`);let enc2=res.headers.get("content-encoding");if(enc2&&enc2.toLowerCase()!=="identity"&&desc?.digest)throw pkgErr("runtime",`artifact must be served without Content-Encoding: ${enc2}`);return new Uint8Array(await res.arrayBuffer())}async function loadJson(url2,fetcher=fetch){return JSON.parse(await loadText(url2,fetcher))}async function loadCatalog2(index3=process.env.HERM_EIKON_MARKETPLACE||DEFAULT_PUBLIC_CATALOG,fetcher=fetch){let url2=index3.endsWith("index.json")?index3:`${index3.replace(/\/$/,"")}/index.json`,raw2=await loadJson(url2,fetcher);if(!Array.isArray(raw2))throw pkgErr("catalog","index array required");let base3=url2.slice(0,url2.lastIndexOf("/")+1);return raw2.map((item)=>normalize2(item,base3))}async function adaptPackage(manifest4,streamText,legacyText){let man=validatePkg(manifest4),body=streamText??legacyText;if(!body)throw pkgErr("entrypoints.default","stream data required");let eik=parseEikon(body);for(let st of STATES2)if(!eik.states.has(st))throw pkgErr(`states.${st}`,"canonical lifecycle state required");return{manifest:man,eikon:eik,states:[...STATES2],triggers:man.triggers,extensions:man.extensions}}async function loadPackage(url2,fetcher=fetch){return{man:validatePkg(await loadJson(url2,fetcher)),base:url2.slice(0,url2.lastIndexOf("/")+1)}}function runtimeDesc2(man,path4=man.entrypoints.default){let file2=man.files?.find((f)=>f.path===path4)??man.files?.find((f)=>f.role==="runtime");if(!file2||!file2.digest&&file2.size==null&&!file2.encoding&&file2.decodedSize==null&&!file2.decodedDigest)return;return{digest:file2.digest,size:file2.size,encoding:file2.encoding,decodedSize:file2.decodedSize,decodedDigest:file2.decodedDigest}}async function loadRuntime(man,base3,fetcher=fetch,path4=man.entrypoints.default){let desc=runtimeDesc2(man,path4),bytes=await loadBytes(new URL(path4,base3).toString(),fetcher,desc);return{bytes,text:decodeRuntimeBytes(bytes,{descriptor:desc})}}async function previewPackage(entry3,fetcher=fetch){let{man,base:base3}=await loadPackage(entry3.packageUrl,fetcher);return adaptPackage(man,(await loadRuntime(man,base3,fetcher)).text)}async function installPackage(src3,opts={}){let url2=typeof src3==="string"?src3:src3.packageUrl;return fetchSource(url2,{name:opts.name,downloader:opts.fetcher?{fetcher:opts.fetcher}:void 0})}var 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._~+/=-]+|\*{3,})/gi,CTRL2=/[\u0000-\u001f\u007f-\u009f]/,SECRET2=/(\.env($|\.)|\.pem$|\.key$|\.p12$|\.pfx$|id_rsa$|id_ed25519$|token|secret|credential|password)/i,REPO=/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/,DEFAULT_REPO=process.env.EIKON_REPO??"liftaris/eikon";function submitPath(name){return file(name)}function targetRepo(){return DEFAULT_REPO}function publishedInfo(path4){let head=header(path4);if(typeof head?.source_url==="string"&&head.source_url.trim())return{source:head.source_url};let mf=join18(dirname11(path4),"manifest.json");if(!existsSync23(mf))return;try{let man=JSON.parse(readFileSync15(mf,"utf8")),src3=man.origin?.source??man.sourceUrl??man.source_url;if(typeof src3==="string"&&src3.trim())return{source:src3}}catch{}return}function redact2(message2){return message2.replace(TOKEN,"[redacted]")}function failureText(xs){return xs.map((x2)=>redact2(x2.message)).join(`
4162
4162
  `)}async function defaults2(input){let bundle;try{bundle=await previewSubmitBundle({path:input.path})}catch{}let meta2=bundle?.meta,name=typeof meta2?.name==="string"?meta2.name:basename11(input.path).replace(/\.eikon$/i,""),author=authorName(meta2?.author)??await ghUser()??process.env.USER??"unknown",glyph=typeof meta2?.glyph==="string"&&meta2.glyph.trim()?meta2.glyph.trim():"\u25C6";return{title:typeof meta2?.title==="string"&&meta2.title.trim()?meta2.title.trim():name,author,description:"Monochrome terminal avatar.",glyph}}async function prepare(input){let meta2=sanitize2(input.meta??await defaults2(input)),target=repo(input.target??DEFAULT_REPO),bundle=await previewSubmitBundle({path:input.path,display:meta2}),want=`${bundle.meta.name}.eikon`;if(basename11(input.path)!==want)throw Error(`runtime filename must match eikon name: expected ${want}`);scan(bundle);let req=request(bundle,meta2,target);return{path:input.path,name:bundle.meta.name,files:bundle.files.map((f)=>({path:f.path,bytes:f.bytes})),meta:meta2,target,source:bundle.files.some((f)=>/\/source\/|\/states\//.test(f.path)),bundleDir:bundle.root,bundleSource:source(bundle.root),title:req.title,body:req.body,url:fallbackUrl(target,bundle.meta.name),steps:steps(target,bundle.meta.name),lint:bundle.lint,bundle,request:req,snapshot:snap2(bundle)}}async function submit2(input,backend3){if(snap2(input.bundle)!==input.snapshot)return{kind:"validation-failed",failures:[{code:"invalid-eikon",message:"staged submission changed after preview; review the bundle again"}]};try{scan(input.bundle)}catch(err){return{kind:"validation-failed",failures:[{code:"invalid-eikon",message:err instanceof Error?err.message:String(err)}]}}let be2=backend3??githubSubmitBackend(input.target),setup=await be2.check();if(!setup.ok)return{kind:"setup-needed",failures:[{code:"missing-auth",message:redact2(setup.reason)}]};try{return await be2.create(request(input.bundle,input.meta,input.target))}catch(err){return{kind:"backend-failed",failures:[{code:"backend-failed",message:redact2(err instanceof Error?err.message:String(err))}]}}}function scan(bundle){let errs=bundle.files.flatMap((file2)=>{let text4=publicText(file2.abs,file2.path);if(text4===void 0)return[];if(secretLike(text4))return[`${file2.path} looks secret-like`];if(unsafeUrl(text4))return[`${file2.path} contains private or unsafe URL`];return[]});if(errs.length)throw Error(errs.join(`
4163
4163
  `))}function publicText(abs2,rel2){if(/\.eikon$/i.test(rel2))return decodeRuntimeFile(abs2);if(/\.(json|md|txt|ya?ml)$/i.test(rel2))return readFileSync15(abs2,"utf8");return}function request(bundle,meta2,target){let title=`eikons: submit ${bundle.meta.name}`,body=[`Submits \`${bundle.meta.name}\` for official registry review.`,"",`Title: ${meta2.title}`,`Author: ${meta2.author}`,`Description: ${meta2.description}`,`Glyph: ${meta2.glyph}`,`Target: ${target}`,"","Registry preflight:",...bundle.lint].join(`
4164
- `);return{bundle,title,body}}function sanitize2(meta2){let next3={title:clean4(meta2.title),author:clean4(meta2.author),description:clean4(meta2.description),glyph:clean4(meta2.glyph)},errs=Object.entries(next3).flatMap(([key3,value2])=>{if(!value2)return[`${key3} required`];if(CTRL2.test(value2))return[`${key3} contains control characters`];if(secretLike(value2))return[`${key3} looks secret-like`];if(unsafeUrl(value2))return[`${key3} contains private or unsafe URL`];return[]});if(Array.from(next3.glyph).length>2)errs.push("glyph must be one or two characters");if(errs.length)throw Error(errs.join(`
4165
- `));return next3}function secretLike(value2){return TOKEN.lastIndex=0,TOKEN.test(value2)||SECRET2.test(value2)}function clean4(value2){return value2.trim().replace(/\s+/g," ")}function authorName(value2){if(typeof value2==="string"&&value2.trim())return value2.trim();if(value2&&typeof value2==="object"&&!Array.isArray(value2)){let name=value2.name;if(typeof name==="string"&&name.trim())return name.trim()}return}function repo(value2){let clean5=value2.trim();if(!REPO.test(clean5))throw Error(`invalid submit repo: ${value2}`);return clean5}function unsafeUrl(value2){return(value2.match(/\b(?:https?|file|data|javascript):[^\s]+/gi)??[]).some((raw2)=>{let url2;try{url2=new URL(raw2)}catch{return!1}if(url2.protocol!=="http:"&&url2.protocol!=="https:")return!0;return privateHost2(url2.hostname)})}function privateHost2(host){let h2=host.toLowerCase().replace(/^\[|\]$/g,"");if(!h2||h2==="::"||h2==="localhost"||h2.endsWith(".localhost"))return!0;let ipv4=h2.match(/^(\d+)\.(\d+)\./);if(ipv4&&privateIpv42(Number(ipv4[1]),Number(ipv4[2])))return!0;if(h2.startsWith("fe80:")||/^f[cd][0-9a-f]{2}:/.test(h2))return!0;let mapped=h2.match(/^::ffff:(?:(\d+)\.(\d+)\.|([0-9a-f]{1,4}):([0-9a-f]{1,4}))/);if(mapped?.[1]&&privateIpv42(Number(mapped[1]),Number(mapped[2])))return!0;if(mapped?.[3]&&mapped?.[4]){let n=Number.parseInt(mapped[3],16)*65536+Number.parseInt(mapped[4],16);return privateIpv42(Math.floor(n/16777216),Math.floor(n/65536)&255)}return isIP(h2)!==0&&(h2==="0.0.0.0"||h2==="::1")}function privateIpv42(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 fallbackUrl(target,name){return`https://github.com/${target}/compare/main...submit%2F${encodeURIComponent(name)}`}function steps(target,name){return[`Open ${target} on GitHub.`,`Create a submit/${name} branch with the prepared files.`,"Open a pull request using the Eikon submission template."]}function snap2(bundle){let hash2=createHash6("sha256");for(let file2 of bundle.files)hash2.update(file2.path),hash2.update("\x00"),hash2.update(String(file2.bytes)),hash2.update("\x00"),hash2.update(readFileSync15(file2.abs)),hash2.update("\x00");return hash2.digest("hex")}function source(path4){return{file:path4,relative:path4,label:basename11(path4)}}async function ghUser(){try{let p=Bun.spawn(["gh","api","user","-q",".login"],{stdout:"pipe",stderr:"pipe"}),[out,code]=await Promise.all([new Response(p.stdout).text(),p.exited]);return code===0&&out.trim()?out.trim():void 0}catch{return}}function cleanup(input){if(dirname11(input.bundleDir)!==tmpdir5()||!basename11(input.bundleDir).startsWith("eikon-submit-"))return;rmSync5(input.bundleDir,{recursive:!0,force:!0})}var FIELDS4=["title","author","description","glyph"];function openEikonSubmit(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(Form3,{...opts,done:()=>{dialog.clear(),resolve4()}}),()=>resolve4())})}var Form3=(props)=>{let theme=useTheme().theme,touched=import_react112.useRef({}),flight=import_react112.useRef(!1),[busy2,setBusy]=import_react112.useState(!1),[status2,setStatus]=import_react112.useState(""),[result,setResult]=import_react112.useState(null),[prepared,setPrepared]=import_react112.useState(null),[field,setField]=import_react112.useState("title"),[meta2,setMeta]=import_react112.useState({title:props.name,author:"unknown",description:"Monochrome terminal avatar.",glyph:"\u25C6"});import_react112.useEffect(()=>{let dead=!1;return touched.current={},defaults2({path:props.path}).then((next3)=>{if(dead)return;setMeta((prev)=>({title:touched.current.title?prev.title:next3.title,author:touched.current.author?prev.author:next3.author,description:touched.current.description?prev.description:next3.description,glyph:touched.current.glyph?prev.glyph:next3.glyph}))}).catch((e)=>setStatus(`Defaults failed: ${redact2(e instanceof Error?e.message:String(e))}`)),()=>{dead=!0}},[props.path]);let close2=()=>{if(prepared&&!status2.includes("fallback"))cleanup(prepared);props.done()},edit2=(key3,value2)=>{if(touched.current[key3]=!0,setMeta((m2)=>({...m2,[key3]:value2})),prepared)cleanup(prepared);setPrepared(null),setResult(null)},prep=async()=>{if(flight.current)return;flight.current=!0,setBusy(!0),setResult(null);try{if(setStatus("Running registry preflight\u2026"),prepared)cleanup(prepared);let next3=await prepare({path:props.path,meta:meta2,includeSource:!1});setPrepared(next3),setStatus(`This will create a PR in ${next3.target} for review. Press Enter to submit.`)}catch(e){setStatus(`Submit failed: ${redact2(e instanceof Error?e.message:String(e))}`)}finally{flight.current=!1,setBusy(!1)}},send=async()=>{if(flight.current)return;if(!prepared)return prep();flight.current=!0,setBusy(!0),setResult(null);try{setStatus("Submitting\u2026");let next3=await props.submit(prepared);if(setResult(next3),next3.kind==="submitted")cleanup(prepared),setStatus("Your Eikon has been submitted and is being reviewed.");else if(next3.kind==="setup-needed")setStatus(`GitHub CLI unavailable. Follow the manual PR instructions below. ${failureText(next3.failures)}`);else setStatus(`Submit failed. Follow the manual PR instructions below. ${failureText(next3.failures)}`)}catch(e){setStatus(`Submit failed. Follow the manual PR instructions below. ${redact2(e instanceof Error?e.message:String(e))}`)}finally{flight.current=!1,setBusy(!1)}},open3=()=>{if(!prepared)return;let ok=openUrl(prepared.url);setStatus(ok?"Opened GitHub compare page":`Open failed; copy ${prepared.url}`)},move=(by)=>{let i=FIELDS4.indexOf(field);setField(FIELDS4[(i+by+FIELDS4.length)%FIELDS4.length])};useKeyboard((key3)=>{if(key3.name==="escape")return close2();if(busy2)return;if(!prepared&&key3.name==="up")return move(-1);if(!prepared&&key3.name==="down")return move(1);if(key3.name==="o"&&prepared)return open3();if(key3.name==="return")return void send()});let bad=status2.startsWith("Submit failed"),warn=status2.startsWith("GitHub")||status2.includes("fallback")||status2.includes("consent");return $jsxs("box",{flexDirection:"column",width:84,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Submit eikon"})})}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:[props.name," \xB7 official registry PR"]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:targetRepo()})}),$jsx("box",{height:1}),!prepared?$jsx(Meta,{meta:meta2,field,setField,setMeta:edit2}):$jsx(Preview,{prepared,result}),$jsx("box",{height:1}),$jsx("text",{fg:bad?theme.error:warn?theme.warning:theme.textMuted,wrapMode:"word",children:status2||(prepared?"Enter submit \xB7 o open GitHub compare \xB7 Esc cancel":"\u2191\u2193 field \xB7 Enter continue \xB7 Esc cancel")})]})};function Meta(props){return $jsxs("box",{flexDirection:"column",children:[$jsx("text",{fg:"gray",children:"Public metadata"}),$jsx(Input,{label:"title",value:props.meta.title,on:props.field==="title",setOn:()=>props.setField("title"),set:(v2)=>props.setMeta("title",v2)}),$jsx(Input,{label:"author",value:props.meta.author,on:props.field==="author",setOn:()=>props.setField("author"),set:(v2)=>props.setMeta("author",v2)}),$jsx(Input,{label:"description",value:props.meta.description,on:props.field==="description",setOn:()=>props.setField("description"),set:(v2)=>props.setMeta("description",v2)}),$jsx(Input,{label:"glyph",value:props.meta.glyph,on:props.field==="glyph",setOn:()=>props.setField("glyph"),set:(v2)=>props.setMeta("glyph",v2)})]})}function Input(props){let theme=useTheme().theme;return $jsxs("box",{height:1,flexDirection:"row",onMouseDown:props.setOn,children:[$jsx("box",{width:13,children:$jsxs("text",{fg:props.on?theme.primary:theme.textMuted,children:[props.on?"\u25B8 ":" ",props.label]})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value:props.value,onInput:props.set,focused:props.on,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement})})]})}function Preview(props){let theme=useTheme().theme,manual=props.result?.kind==="setup-needed"||props.result?.kind==="backend-failed";return $jsxs("box",{flexDirection:"column",children:[$jsx("text",{fg:theme.textMuted,children:"Registry preflight"}),props.prepared.lint.map((line4)=>$jsx("text",{fg:theme.accent,children:line4},line4)),$jsx("box",{height:1}),$jsx("text",{fg:theme.textMuted,children:"Package"}),$jsxs("text",{fg:theme.text,children:[props.prepared.files.length," files prepared for registry review"]}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,children:$jsx("text",{fg:theme.textMuted,children:"Bundle:"})}),$jsx(FileLink,{source:props.prepared.bundleSource,children:props.prepared.bundleDir})]}),$jsx("box",{height:1}),$jsx("text",{fg:theme.textMuted,children:"Metadata"}),$jsxs("text",{fg:theme.textMuted,children:["Title: ",props.prepared.meta.title]}),$jsxs("text",{fg:theme.textMuted,children:["Author: ",props.prepared.meta.author]}),$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["Description: ",props.prepared.meta.description]}),$jsxs("text",{fg:theme.textMuted,children:["Glyph: ",props.prepared.meta.glyph]}),manual?$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1}),$jsx("text",{fg:theme.warning,children:"Manual PR"}),props.prepared.steps.map((step2)=>$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["\u2022 ",step2]},step2)),$jsxs("text",{fg:theme.textMuted,children:["Compare: ",props.prepared.url]})]}):null]})}var exports_eikon_gen={};__export(exports_eikon_gen,{setProbe:()=>setProbe,setImpl:()=>setImpl,probeCached:()=>probeCached,probe:()=>probe2,generate:()=>generate,gen:()=>exports_eikon_gen,current:()=>current});import{existsSync as existsSync24,readFileSync as readFileSync16}from"fs";import{tmpdir as tmpdir6}from"os";import{join as join19}from"path";var ROOT2=()=>hermesPath("hermes-agent"),WIN=process.platform==="win32",PY=()=>{for(let v2 of["venv",".venv"]){let bin=WIN?`${ROOT2()}/${v2}/Scripts/python.exe`:`${ROOT2()}/${v2}/bin/python`;if(existsSync24(bin))return bin}return WIN?"python":"python3"},spawn4=(args)=>{try{return Bun.spawn([PY(),...args],{cwd:ROOT2(),env:env2(),stdout:"pipe",stderr:"pipe"})}catch(e){return e instanceof Error?e:Error(String(e))}};function dotenv(){let out={},path4=hermesPath(".env");if(!existsSync24(path4))return out;for(let raw2 of readFileSync16(path4,"utf8").split(`
4164
+ `);return{bundle,title,body}}function sanitize2(meta2){let next3={title:clean5(meta2.title),author:clean5(meta2.author),description:clean5(meta2.description),glyph:clean5(meta2.glyph)},errs=Object.entries(next3).flatMap(([key3,value2])=>{if(!value2)return[`${key3} required`];if(CTRL2.test(value2))return[`${key3} contains control characters`];if(secretLike(value2))return[`${key3} looks secret-like`];if(unsafeUrl(value2))return[`${key3} contains private or unsafe URL`];return[]});if(Array.from(next3.glyph).length>2)errs.push("glyph must be one or two characters");if(errs.length)throw Error(errs.join(`
4165
+ `));return next3}function secretLike(value2){return TOKEN.lastIndex=0,TOKEN.test(value2)||SECRET2.test(value2)}function clean5(value2){return value2.trim().replace(/\s+/g," ")}function authorName(value2){if(typeof value2==="string"&&value2.trim())return value2.trim();if(value2&&typeof value2==="object"&&!Array.isArray(value2)){let name=value2.name;if(typeof name==="string"&&name.trim())return name.trim()}return}function repo(value2){let clean6=value2.trim();if(!REPO.test(clean6))throw Error(`invalid submit repo: ${value2}`);return clean6}function unsafeUrl(value2){return(value2.match(/\b(?:https?|file|data|javascript):[^\s]+/gi)??[]).some((raw2)=>{let url2;try{url2=new URL(raw2)}catch{return!1}if(url2.protocol!=="http:"&&url2.protocol!=="https:")return!0;return privateHost2(url2.hostname)})}function privateHost2(host){let h2=host.toLowerCase().replace(/^\[|\]$/g,"");if(!h2||h2==="::"||h2==="localhost"||h2.endsWith(".localhost"))return!0;let ipv4=h2.match(/^(\d+)\.(\d+)\./);if(ipv4&&privateIpv42(Number(ipv4[1]),Number(ipv4[2])))return!0;if(h2.startsWith("fe80:")||/^f[cd][0-9a-f]{2}:/.test(h2))return!0;let mapped=h2.match(/^::ffff:(?:(\d+)\.(\d+)\.|([0-9a-f]{1,4}):([0-9a-f]{1,4}))/);if(mapped?.[1]&&privateIpv42(Number(mapped[1]),Number(mapped[2])))return!0;if(mapped?.[3]&&mapped?.[4]){let n=Number.parseInt(mapped[3],16)*65536+Number.parseInt(mapped[4],16);return privateIpv42(Math.floor(n/16777216),Math.floor(n/65536)&255)}return isIP(h2)!==0&&(h2==="0.0.0.0"||h2==="::1")}function privateIpv42(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 fallbackUrl(target,name){return`https://github.com/${target}/compare/main...submit%2F${encodeURIComponent(name)}`}function steps(target,name){return[`Open ${target} on GitHub.`,`Create a submit/${name} branch with the prepared files.`,"Open a pull request using the Eikon submission template."]}function snap2(bundle){let hash2=createHash6("sha256");for(let file2 of bundle.files)hash2.update(file2.path),hash2.update("\x00"),hash2.update(String(file2.bytes)),hash2.update("\x00"),hash2.update(readFileSync15(file2.abs)),hash2.update("\x00");return hash2.digest("hex")}function source(path4){return{file:path4,relative:path4,label:basename11(path4)}}async function ghUser(){try{let p=Bun.spawn(["gh","api","user","-q",".login"],{stdout:"pipe",stderr:"pipe"}),[out,code]=await Promise.all([new Response(p.stdout).text(),p.exited]);return code===0&&out.trim()?out.trim():void 0}catch{return}}function cleanup(input){if(dirname11(input.bundleDir)!==tmpdir5()||!basename11(input.bundleDir).startsWith("eikon-submit-"))return;rmSync5(input.bundleDir,{recursive:!0,force:!0})}var FIELDS4=["title","author","description","glyph"];function openEikonSubmit(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(Form3,{...opts,done:()=>{dialog.clear(),resolve4()}}),()=>resolve4())})}var Form3=(props)=>{let theme=useTheme().theme,touched=import_react112.useRef({}),flight=import_react112.useRef(!1),[busy2,setBusy]=import_react112.useState(!1),[status2,setStatus]=import_react112.useState(""),[result,setResult]=import_react112.useState(null),[prepared,setPrepared]=import_react112.useState(null),[field,setField]=import_react112.useState("title"),[meta2,setMeta]=import_react112.useState({title:props.name,author:"unknown",description:"Monochrome terminal avatar.",glyph:"\u25C6"});import_react112.useEffect(()=>{let dead=!1;return touched.current={},defaults2({path:props.path}).then((next3)=>{if(dead)return;setMeta((prev)=>({title:touched.current.title?prev.title:next3.title,author:touched.current.author?prev.author:next3.author,description:touched.current.description?prev.description:next3.description,glyph:touched.current.glyph?prev.glyph:next3.glyph}))}).catch((e)=>setStatus(`Defaults failed: ${redact2(e instanceof Error?e.message:String(e))}`)),()=>{dead=!0}},[props.path]);let close2=()=>{if(prepared&&!status2.includes("fallback"))cleanup(prepared);props.done()},edit2=(key3,value2)=>{if(touched.current[key3]=!0,setMeta((m2)=>({...m2,[key3]:value2})),prepared)cleanup(prepared);setPrepared(null),setResult(null)},prep=async()=>{if(flight.current)return;flight.current=!0,setBusy(!0),setResult(null);try{if(setStatus("Running registry preflight\u2026"),prepared)cleanup(prepared);let next3=await prepare({path:props.path,meta:meta2,includeSource:!1});setPrepared(next3),setStatus(`This will create a PR in ${next3.target} for review. Press Enter to submit.`)}catch(e){setStatus(`Submit failed: ${redact2(e instanceof Error?e.message:String(e))}`)}finally{flight.current=!1,setBusy(!1)}},send=async()=>{if(flight.current)return;if(!prepared)return prep();flight.current=!0,setBusy(!0),setResult(null);try{setStatus("Submitting\u2026");let next3=await props.submit(prepared);if(setResult(next3),next3.kind==="submitted")cleanup(prepared),setStatus("Your Eikon has been submitted and is being reviewed.");else if(next3.kind==="setup-needed")setStatus(`GitHub CLI unavailable. Follow the manual PR instructions below. ${failureText(next3.failures)}`);else setStatus(`Submit failed. Follow the manual PR instructions below. ${failureText(next3.failures)}`)}catch(e){setStatus(`Submit failed. Follow the manual PR instructions below. ${redact2(e instanceof Error?e.message:String(e))}`)}finally{flight.current=!1,setBusy(!1)}},open3=()=>{if(!prepared)return;let ok=openUrl(prepared.url);setStatus(ok?"Opened GitHub compare page":`Open failed; copy ${prepared.url}`)},move=(by)=>{let i=FIELDS4.indexOf(field);setField(FIELDS4[(i+by+FIELDS4.length)%FIELDS4.length])};useKeyboard((key3)=>{if(key3.name==="escape")return close2();if(busy2)return;if(!prepared&&key3.name==="up")return move(-1);if(!prepared&&key3.name==="down")return move(1);if(key3.name==="o"&&prepared)return open3();if(key3.name==="return")return void send()});let bad=status2.startsWith("Submit failed"),warn=status2.startsWith("GitHub")||status2.includes("fallback")||status2.includes("consent");return $jsxs("box",{flexDirection:"column",width:84,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Submit eikon"})})}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:[props.name," \xB7 official registry PR"]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:targetRepo()})}),$jsx("box",{height:1}),!prepared?$jsx(Meta,{meta:meta2,field,setField,setMeta:edit2}):$jsx(Preview,{prepared,result}),$jsx("box",{height:1}),$jsx("text",{fg:bad?theme.error:warn?theme.warning:theme.textMuted,wrapMode:"word",children:status2||(prepared?"Enter submit \xB7 o open GitHub compare \xB7 Esc cancel":"\u2191\u2193 field \xB7 Enter continue \xB7 Esc cancel")})]})};function Meta(props){return $jsxs("box",{flexDirection:"column",children:[$jsx("text",{fg:"gray",children:"Public metadata"}),$jsx(Input,{label:"title",value:props.meta.title,on:props.field==="title",setOn:()=>props.setField("title"),set:(v2)=>props.setMeta("title",v2)}),$jsx(Input,{label:"author",value:props.meta.author,on:props.field==="author",setOn:()=>props.setField("author"),set:(v2)=>props.setMeta("author",v2)}),$jsx(Input,{label:"description",value:props.meta.description,on:props.field==="description",setOn:()=>props.setField("description"),set:(v2)=>props.setMeta("description",v2)}),$jsx(Input,{label:"glyph",value:props.meta.glyph,on:props.field==="glyph",setOn:()=>props.setField("glyph"),set:(v2)=>props.setMeta("glyph",v2)})]})}function Input(props){let theme=useTheme().theme;return $jsxs("box",{height:1,flexDirection:"row",onMouseDown:props.setOn,children:[$jsx("box",{width:13,children:$jsxs("text",{fg:props.on?theme.primary:theme.textMuted,children:[props.on?"\u25B8 ":" ",props.label]})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value:props.value,onInput:props.set,focused:props.on,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement})})]})}function Preview(props){let theme=useTheme().theme,manual=props.result?.kind==="setup-needed"||props.result?.kind==="backend-failed";return $jsxs("box",{flexDirection:"column",children:[$jsx("text",{fg:theme.textMuted,children:"Registry preflight"}),props.prepared.lint.map((line4)=>$jsx("text",{fg:theme.accent,children:line4},line4)),$jsx("box",{height:1}),$jsx("text",{fg:theme.textMuted,children:"Package"}),$jsxs("text",{fg:theme.text,children:[props.prepared.files.length," files prepared for registry review"]}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,children:$jsx("text",{fg:theme.textMuted,children:"Bundle:"})}),$jsx(FileLink,{source:props.prepared.bundleSource,children:props.prepared.bundleDir})]}),$jsx("box",{height:1}),$jsx("text",{fg:theme.textMuted,children:"Metadata"}),$jsxs("text",{fg:theme.textMuted,children:["Title: ",props.prepared.meta.title]}),$jsxs("text",{fg:theme.textMuted,children:["Author: ",props.prepared.meta.author]}),$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["Description: ",props.prepared.meta.description]}),$jsxs("text",{fg:theme.textMuted,children:["Glyph: ",props.prepared.meta.glyph]}),manual?$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1}),$jsx("text",{fg:theme.warning,children:"Manual PR"}),props.prepared.steps.map((step2)=>$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:["\u2022 ",step2]},step2)),$jsxs("text",{fg:theme.textMuted,children:["Compare: ",props.prepared.url]})]}):null]})}var exports_eikon_gen={};__export(exports_eikon_gen,{setProbe:()=>setProbe,setImpl:()=>setImpl,probeCached:()=>probeCached,probe:()=>probe2,generate:()=>generate,gen:()=>exports_eikon_gen,current:()=>current});import{existsSync as existsSync24,readFileSync as readFileSync16}from"fs";import{tmpdir as tmpdir6}from"os";import{join as join19}from"path";var ROOT2=()=>hermesPath("hermes-agent"),WIN=process.platform==="win32",PY=()=>{for(let v2 of["venv",".venv"]){let bin=WIN?`${ROOT2()}/${v2}/Scripts/python.exe`:`${ROOT2()}/${v2}/bin/python`;if(existsSync24(bin))return bin}return WIN?"python":"python3"},spawn4=(args)=>{try{return Bun.spawn([PY(),...args],{cwd:ROOT2(),env:env2(),stdout:"pipe",stderr:"pipe"})}catch(e){return e instanceof Error?e:Error(String(e))}};function dotenv(){let out={},path4=hermesPath(".env");if(!existsSync24(path4))return out;for(let raw2 of readFileSync16(path4,"utf8").split(`
4166
4166
  `)){let ln=raw2.trim();if(!ln||ln.startsWith("#"))continue;let eq3=ln.indexOf("=");if(eq3<1)continue;let k2=ln.slice(0,eq3).replace(/^export\s+/,"").trim(),v2=ln.slice(eq3+1).trim();if(v2.startsWith('"')&&v2.endsWith('"')||v2.startsWith("'")&&v2.endsWith("'"))v2=v2.slice(1,-1);out[k2]=v2}return out}var env2=()=>{let base3=dotenv();for(let[k2,v2]of Object.entries(process.env))if(v2!==void 0)base3[k2]=v2;return base3},q4=(s)=>JSON.stringify(s);function code(kind2,prompt,o){if(kind2==="image")return["from tools.image_generation_tool import _handle_image_generate as g",`print(g({"prompt": ${q4(prompt)}, "aspect_ratio": ${q4(o.aspect??"square")}}))`].join("; ");let args=[`"prompt":${q4(prompt)}`,`"aspect_ratio":${q4(o.aspect??"1:1")}`];if(o.seconds)args.push(`"duration":${o.seconds}`);if(o.seed)args.push(`"image_url":${q4(o.seed)}`);return["from tools.video_generation_tool import _handle_video_generate as g",`print(g({${args.join(",")}}))`].join("; ")}async function probe2(){let root3=ROOT2();if(!existsSync24(root3))return{image:!1,video:!1};let src3=["import json","from tools.image_generation_tool import check_image_generation_requirements as ci","from tools.video_generation_tool import check_video_generation_requirements as cv","print(json.dumps({'image': bool(ci()), 'video': bool(cv())}))"].join("; "),r=spawn4(["-c",src3]);if(r instanceof Error)return{image:!1,video:!1};let out=await new Response(r.stdout).text();if(await r.exited!==0)return{image:!1,video:!1};let last4=out.trim().split(`
4167
4167
  `).pop();try{return JSON.parse(last4)}catch{return{image:!1,video:!1}}}async function fetchTo(url2,ext){let tmp=join19(tmpdir6(),`eikon-gen-${Date.now()}${ext}`),res=await fetch(url2);if(!res.ok)throw Error(`download ${res.status}`);return await Bun.write(tmp,await res.arrayBuffer()),tmp}var generate=async(kind2,prompt,opts)=>{let r=spawn4(["-c",code(kind2,prompt,opts)]);if(r instanceof Error)return{err:r.message};let[out,err,exit]=await Promise.all([new Response(r.stdout).text(),new Response(r.stderr).text(),r.exited]);if(exit!==0)return{err:(err||out).trim().split(`
4168
4168
  `).slice(-3).join(" ")||`python exited ${exit}`};let last4=out.trim().split(`
4169
4169
  `).pop();if(!last4)return{err:"no output"};let j2;try{j2=JSON.parse(last4)}catch{return{err:`unparseable: ${last4.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_react114=__toESM(require_react_production(),1);var ORDER5=["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_react114.useState(props.initial??""),[from2,setFrom]=import_react114.useState("blank"),[field,setField]=import_react114.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 Library after install to select it."].join(`
4170
4170
  `),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=ORDER5.indexOf(field);return setField(ORDER5[(i+(key3.shift?-1:1)+ORDER5.length)%ORDER5.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,status2)=>status2.downloadable},{id:"knobsfor",kind:"action",label:"tune",show:(_s,status2)=>!!status2.path},{id:"reset",kind:"action",label:"reset",show:(_s,status2)=>!!status2.path},{id:"revert",kind:"action",label:"revert",show:(s)=>s.dirty},{id:"-2",kind:"divider",label:"",show:(_s,status2)=>!!status2.path},{id:"h-input",kind:"header",label:"input",show:(_s,status2)=>!!status2.path},{id:"contrast",kind:"tone",label:"contrast",show:(_s,status2)=>!!status2.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,status2)=>!!status2.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,status2)=>!!status2.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,status2)=>!!status2.path}],HELP2={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:HELP2.source})});let head=HELP2[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,status2){let dyn=status2.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,status2):!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_react116.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})]})}var PreviewPane=import_react116.memo((props)=>{let theme=useTheme().theme,[tick3,setTick]=import_react116.useState(0),n=props.frames.length,fps=props.live?props.s?.fps??FPS0:props.baked?.states.get(props.s?.state??"idle")?.fps??FPS0;import_react116.useEffect(()=>setTick((value2)=>value2%n),[props.frames,n]),import_react116.useEffect(()=>{if(!props.play||!props.focused||n<=1||props.busy)return;let id=setInterval(()=>setTick((value2)=>value2+1),1000/Math.max(1,fps));return()=>clearInterval(id)},[props.play,props.focused,n,props.busy,fps]);let title=props.s?`Preview \u2014 ${props.s.state}${props.s.per[props.s.state]?" (forked)":""}`+(n>1?` \xB7 ${props.play?"\u25B6":"\u23F8"} ${tick3%n+1}/${n}`:"")+(props.live?"":props.baked?" \xB7 (baked)":""):"Preview",frame=props.frames[tick3%n]??BLANK3,body=$jsxs("box",{position:"relative",flexDirection:"column",width:W2,height:H,flexShrink:0,backgroundColor:theme.background,onMouseScroll:props.onScroll,onMouseDown:()=>props.setPlay((value2)=>!value2),children:[frame.map((line4,i)=>$jsx("text",{fg:props.error?theme.textMuted:theme.hermAvatar,children:line4},i)),props.busy&&props.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]});return $jsxs(TabShell,{title:props.spatialOk?title:`${title} \xB7 (ffmpeg not installed)`,error:props.error,focus:props.pane==="preview",children:[!props.live&&props.baked?$jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:"Baked \u2014 download or attach source to edit."})}):null,props.spatialOk&&props.live&&props.s?$jsxs($Fragment,{children:[$jsx(PanBars,{sp:props.s.spatial,sel:props.sel,focused:props.pane==="preview",onHover:(i)=>{props.onPane("preview"),props.onSel(i)},onSet:props.onSet,onWheel:props.onWheel,children:body}),$jsx(SpatialBar,{sp:props.s.spatial,fps:props.s.fps,dims:props.s.dims,sel:props.sel,focused:props.pane==="preview",onHover:(i)=>{props.onPane("preview"),props.onSel(i)},onSet:props.onSet,onWheel:props.onWheel})]}):body]})});function valueOf(s,r,row3,theme,status2,peek5,busy2){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(!status2?.path){if(status2?.kind==="downloadable")return"Download source";if(status2?.kind==="baked")return"Baked only";return"Missing source"}let d2=s.dims,sz=status2.size===void 0?"?":mb2(status2.size);return d2?`${basename12(status2.path)} \xB7 ${d2.w}\xD7${d2.h} \xB7 ${sz}`:`${basename12(status2.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 busy2?"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_react116.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],status2=props.stats.get(st),mark2=status2.kind==="missing"?"missing":status2.kind==="downloadable"?"download":status2.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_react116.memo((props)=>{let theme=useTheme().theme,keys=useKeys(),dialog=useDialog(),gw=useGateway(),toast=useToast(),wide=useTerminalDimensions().width>=120,ksb=import_react116.useRef(null),outer=import_react116.useRef(null);import_react116.useSyncExternalStore(exports_eikon.onRegistry,()=>exports_eikon.rasterizers().length);let[s,setS]=import_react116.useState(null),[pane,setPane]=import_react116.useState("knobs"),[sel,setSel]=import_react116.useState(0),[spSel,setSpSel]=import_react116.useState(0),selRef=import_react116.useRef(0);selRef.current=sel;let spRef=import_react116.useRef(0);spRef.current=spSel;let sRef=import_react116.useRef(null);sRef.current=s;let[frames,setFrames]=import_react116.useState([BLANK3]),[play,setPlay]=import_react116.useState(!0),[busy2,setBusy]=import_react116.useState(!1),[fetching,setFetching]=import_react116.useState(!1),[peek5,setPeek]=import_react116.useState(void 0),[thumbs,setThumbs]=import_react116.useState(new Map),[err,setErr]=import_react116.useState(null),[saving,setSaving]=import_react116.useState(!1),[pending3,setPending]=import_react116.useState(new Set),[genOk,setGenOk]=import_react116.useState(null),stampRef=import_react116.useRef(""),rev3=import_react116.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision),r=import_react116.useMemo(()=>exports_eikon.pick(s?.rasterizer??get2("eikonRasterizer")),[s?.rasterizer]),spatialOk=caps3.ffmpeg,open3=import_react116.useCallback((name)=>{resetCache(),stampRef.current=exports_eikon.sourceStamp(name);let seed=exports_eikon.readStudio(name),ra=exports_eikon.pick(seed?.rasterizer??get2("eikonRasterizer")),next3=exports_eikon_knobs.fresh(name,ra,seed),src4=exports_eikon.findSource(name,"idle");next3.dims=src4?exports_eikon.probe(src4)??null:null;for(let st of STATES2){let p=exports_eikon.findSource(name,st);if(p)prewarm(p,next3.fps)}setS(next3),selRow.current=void 0,setSel(0),setPane("knobs"),setErr(null),setFrames([BLANK3])},[]),tried=import_react116.useRef(!1);import_react116.useEffect(()=>{if(tried.current)return;if(tried.current=!0,props.name)return open3(props.name||exports_eikon_knobs.slug("new"));let n=get2("eikon");if(n)open3(n)},[open3,props.name]);let dialogRef=import_react116.useRef(dialog);dialogRef.current=dialog,import_react116.useEffect(()=>{if(props.name===void 0)return;let next3=props.name||exports_eikon_knobs.slug("new"),cur=sRef.current;if(cur?.name===next3)return;if(!cur?.dirty)return open3(next3);let dead=!1;return openConfirm(dialogRef.current,{title:"Discard unsaved edits?",danger:!0,body:`Switch to '${next3}' and drop in-memory changes to '${cur.name}'.`}).then((ok)=>{if(!dead&&ok)open3(next3)}),()=>{dead=!0}},[props.name,open3]),import_react116.useEffect(()=>{let dead=!1;return probeGen().then((c)=>{if(!dead)setGenOk(c)}).catch(()=>{}),()=>{dead=!0}},[]);let stats=import_react116.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,rev3]),status2=s?stats.get(s.state):void 0,src3=status2?.path,live=!!src3,baked2=import_react116.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=status2?.sourceUrl;import_react116.useEffect(()=>{if(setPeek(void 0),!url2||!status2?.downloadable)return;let dead=!1;return exports_eikon.peekSource(url2).then((x2)=>{if(!dead)setPeek(x2)}),()=>{dead=!0}},[url2,status2?.downloadable]),import_react116.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}open3(s.name)},[rev3,s?.name,s?.dirty,open3,toast]);let rows3=import_react116.useMemo(()=>s&&status2?buildRows(r,s,status2):[],[r,s,status2]),navRows=import_react116.useMemo(()=>rows3.map((x2,i)=>({...x2,i})).filter((x2)=>x2.kind!=="divider"&&x2.kind!=="header"),[rows3]),selRow=import_react116.useRef(void 0),rid2=(x2)=>`${x2.kind}:${x2.id}`,setSelBy=import_react116.useCallback((arg)=>{setSel((prev)=>{let next3=typeof arg==="function"?arg(prev):arg,row3=navRows[next3];return selRow.current=row3?rid2(row3):void 0,next3})},[navRows]),prevRows=import_react116.useRef(navRows);import_react116.useEffect(()=>{if(prevRows.current===navRows)return;prevRows.current=navRows;let id=selRow.current;if(!id)return;let ni=navRows.findIndex((x2)=>rid2(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_react116.useEffect(()=>{if(!s)return;if(!src3){let clip=baked2?.states.get(s.state);setFrames(clip?.frames.length?clip.frames:[BLANK3]),setErr(null),setBusy(!1);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)}),()=>ctrl.abort()},[s?.spatial,s?.tone,s?.base,s?.per,s?.state,s?.fps,s?.rasterizer,src3,r,baked2]),import_react116.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_react116.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_react116.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 next3=exports_eikon.rasterizer(o.value);if(!next3)return;let a=next3.available();if(a!==!0)return toast.show({variant:"warning",message:`${o.value}: ${a}`});set("eikonRasterizer",o.value),mutate((p)=>exports_eikon_knobs.swap(p,next3))}}),()=>{})},runGenerate=async(st,kind2)=>{if(!s)return;let seed=stats.get("idle")?.path;setPending((prev)=>{let n=new Set(prev);return n.add(st),n});let out=await openGenerate(dialog,exports_eikon_gen.current(),{state:st,kind:kind2,seed,lastPrompt:s.prompts?.[st]});if(!out){setPending((prev)=>{let n=new Set(prev);return n.delete(st),n});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 n=new Set(prev);return n.delete(st),n})}},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 open3(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_react116.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}open3(name)},[dialog,open3]),apply=import_react116.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_react116.useCallback(async()=>{let res=await openNewEikon(dialog,{});await apply(res)},[dialog,apply]),eikonOptions=import_react116.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((n)=>!seen.has(n)).map((n)=>({title:n,value:n,category:"installed",hint:"(unsaved)"}));return[...installed,...raw2,...bundled]},[]),doInstall=import_react116.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 Library after install to select it."].join(`
4171
- `),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_react116.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_react116.useCallback(async()=>{let cur=sRef.current;if(!cur)return;let path4=submitPath(cur.name);if(publishedInfo(path4)){toast.show({variant:"warning",title:"Published eikon",message:"Create a local draft before submitting",duration:6000});return}if(cur.dirty||!existsSync25(path4)){let pick2=await openSaveDiscard(dialog,{title:"Save before submit?",body:`'${cur.name}' has unsaved changes. Save to submit the current preview, discard to submit the last saved artifact, or keep editing.`});if(pick2==="save"){if(get2("eikon")===cur.name){if(!await openConfirm(dialog,{title:`Save active '${cur.name}' before submit?`,danger:!0,body:"Saving changes the active avatar's backing artifact. Submit itself will not change active selection.",yes:"save",no:"cancel"}))return}if(!await doSave())return}else if(pick2==="discard")open3(cur.name);else return}if(!existsSync25(path4)){toast.show({variant:"warning",message:"Save this eikon before submitting"});return}await openEikonSubmit(dialog,{name:cur.name,path:path4,submit:submit2})},[dialog,doSave,open3,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(!status2?.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())open3(cur.name);return!0}if(pick2==="discard")open3(cur.name);return!0},refresh=import_react116.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}open3(cur.name),toast.show({variant:"info",message:"Reloaded",duration:1000})},[open3,toast]);useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(key3.eventType==="release")return;if(key3.name==="u"&&key3.ctrl&&sRef.current)return void doSaveUse();if(key3.name==="u"&&sRef.current)return void doSubmit();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),next3=PANES[(i+(key3.shift?PANES.length-1:1))%PANES.length];setPane(next3),outer.current?.scrollChildIntoView(`studio-${next3}`);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}))},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","library"]]: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),preview2=$jsx(PreviewPane,{s,frames,play,setPlay,focused:Boolean(props.focused),busy:busy2,live,baked:baked2,spatialOk,error:previewErr,pane,sel:spSel,onPane:setPane,onSel:setSpSel,onSet:setBar,onWheel:stepBar,onScroll}),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:status2,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,top2=wide?$jsxs("box",{flexDirection:"row",flexShrink:0,height:PREVIEW_H,children:[$jsx("box",{id:"studio-preview",flexShrink:0,width:PREVIEW_W,children:preview2}),$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:preview2}),$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:[top2,strip]}),$jsx(HintBar,{pairs:hint,suffix:saving?"\u25CF saving\u2026":s?.dirty?"\u25CF unsaved":void 0})]})});var import_react118=__toESM(require_react_production(),1);import{existsSync as existsSync26,readFileSync as readFileSync17}from"fs";import{basename as basename13,dirname as dirname12,join as join20}from"path";var EIKON_CARD=50,titleWidth=(title,rows3)=>Math.max(title.length,...rows3.map((r)=>r.name.length+4))+7,cardWidth=(lines3)=>Math.max(EIKON_CARD,...lines3.map((line4)=>line4.length+2)),EikonTitleList=(props)=>{let theme=useTheme().theme;return $jsx("box",{width:props.width,flexShrink:0,minHeight:0,children:$jsx(TabShell,{title:props.title,focus:props.focus,grow:1,children:$jsx("box",{flexDirection:"column",flexGrow:1,minHeight:0,children:$jsx("scrollbox",{ref:props.follow.ref,scrollY:!0,flexGrow:1,children:props.rows.length===0?$jsx("text",{fg:theme.textMuted,children:"No eikons found."}):props.rows.map((r,i)=>{let on=i===props.sel;return $jsxs("box",{id:props.follow.id(i),flexDirection:"row",height:1,paddingRight:3,backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:()=>props.onSel(i),onMouseDown:()=>{props.onSel(i),props.onUse(i)},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:r.active?theme.accent:theme.text,children:[r.active?"\u25CF ":" ",$jsx("strong",{children:r.name})]})})]},r.key)})})})})})},EikonCardGrid=(props)=>{let theme=useTheme().theme;if(props.rows.length===0)return $jsx("box",{padding:1,children:props.empty??$jsx("text",{fg:theme.textMuted,children:"No eikons found."})});return $jsx("scrollbox",{ref:props.follow.ref,scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"row",flexWrap:"wrap",width:"100%",flexShrink:0,children:props.rows.map((r,i)=>{let on=i===props.sel;return $jsxs("box",{id:props.follow.id(i),flexDirection:"column",height:r.lines.length+2,width:cardWidth(r.lines),flexShrink:0,paddingX:1,backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:()=>props.onSel(i),onMouseDown:()=>{props.onSel(i),props.onUse(i)},children:[$jsx("box",{height:r.lines.length,overflow:"hidden",flexDirection:"column",children:r.lines.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.name})]})}),$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{fg:theme.textMuted,wrapMode:"none",children:["by ",r.author??"unknown"," \xB7 ",r.status]})})]},r.key)})})})};var PREVIEW2=54,EikonGallery=import_react118.memo((props)=>{let theme=useTheme().theme,dialog=useDialog(),toast=useToast(),keys=useKeys(),rev3=import_react118.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision),dims=useTerminalDimensions(),rows3=import_react118.useMemo(()=>{let user=hermesPath("eikons"),own=exports_eikon.list(),map=new Map(own.map((x2)=>[x2.name.toLowerCase(),x2])),meta2=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():dirname12(e.path)===user?basename13(e.path,".eikon"):basename13(dirname12(e.path)),man=manifest4(dirname12(e.path)),keys2=ids2(man,slug3),mine=meta2.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)).reduce((map2,row3)=>{let prev=map2.get(row3.slug);if(!prev||dirname12(prev.path)===user&&dirname12(row3.path)!==user)map2.set(row3.slug,row3);return map2},new Map).values()]},[rev3]),active2=usePref("eikon"),path4=import_react118.useMemo(()=>active2?exports_eikon.baked(active2):void 0,[active2,rev3]),current2=(row3)=>path4===row3.path,[sel,setSel]=import_react118.useState(0),[pane,setPane]=import_react118.useState("list"),[act,setAct]=import_react118.useState(0),galleryFollow=useFollow("gal",(i)=>rows3[i]?.slug??i),gridFollow=useFollow("lib-grid",(i)=>rows3[i]?.slug??i);import_react118.useEffect(()=>{if(sel>=rows3.length)setSel(Math.max(0,rows3.length-1))},[rows3.length,sel]);let cur=rows3[sel],parsed=import_react118.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_react118.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_react118.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_react118.useCallback(async()=>{if(!cur||cur.bundled)return;let path6=submitPath(cur.slug);if(publishedInfo(path6)){toast.show({variant:"warning",title:"Published eikon",message:"Create a local draft before submitting",duration:6000});return}await openEikonSubmit(dialog,{name:cur.name,path:path6,submit:props.submit??submit2})},[cur,dialog,props.submit,toast]),del=async()=>{if(!cur||cur.bundled)return;let here=current2(cur),base3=dirname12(cur.path)===hermesPath("eikons")?`Removes legacy flat file ${basename13(cur.path)}.`:`Removes ${dirname12(cur.path)} and all its sources.`,body=here?`${base3} This is the active avatar; deleting it will clear the active avatar selection.`:base3;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}`})},actions=import_react118.useMemo(()=>{if(!cur)return[];return[{key:"Enter",label:current2(cur)?"Use as active avatar (active)":"Use as active avatar",run:()=>activate()},...props.onEdit?[{key:"e",label:"Edit in Studio",run:()=>props.onEdit?.(cur.slug)}]:[],...!cur.bundled?[{key:"u",label:"Update local package",run:()=>void updateLocal()},{key:"s",label:"Share to catalog",run:()=>void submitLocal()},{key:"d",label:"Delete local eikon",run:()=>void del(),danger:!0}]:[]]},[cur,path4,props.onEdit,updateLocal,submitLocal]);import_react118.useEffect(()=>{if(act>=actions.length)setAct(Math.max(0,actions.length-1))},[act,actions.length]);let cards=import_react118.useMemo(()=>rows3.map((r)=>{let p=(()=>{try{return parseEikonFile(r.path)}catch{return}})(),lines3=p?.resolve("state.idle")?.frames[0]??p?.states.get("idle")?.frames[0]??["(no preview)"];return{key:r.path,name:r.name,active:current2(r),author:r.author,status:current2(r)?"active":r.bundled?"bundled/system":"installed",lines:lines3}}),[rows3,path4]);useKeyboard((key3)=>{if(!props.focused||dialog.open())return;let plain=!key3.shift&&!key3.ctrl&&!key3.meta;if(key3.name==="tab")return setPane((p)=>p==="list"?"actions":"list");if(pane==="actions"){if(key3.name==="escape"||plain&&key3.name==="left"){setPane("list");return}if(plain&&key3.name==="up"){setAct((i)=>Math.max(0,i-1));return}if(plain&&key3.name==="down"){setAct((i)=>Math.min(actions.length-1,i+1));return}if(keys.match("list.activate",key3)||keys.match("list.toggle",key3)){actions[act]?.run();return}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)});let listW=Math.max(13,...rows3.map((r)=>r.name.length+4))+7,showGrid=dims.width-listW-PREVIEW2>=EIKON_CARD;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,minHeight:0,children:[$jsx(EikonTitleList,{title:`Library (${rows3.length})`,rows:rows3.map((r)=>({key:r.path,name:r.name,active:current2(r)})),sel,focus:props.focused&&pane==="list",follow:galleryFollow,width:listW,onSel:setSel,onUse:(i)=>activate(rows3[i])}),showGrid?$jsx(TabShell,{title:"Grid",grow:1,children:$jsx(EikonCardGrid,{rows:cards,sel,follow:gridFollow,onSel:setSel,onUse:(i)=>activate(rows3[i])})}):null,$jsx("box",{width:PREVIEW2,flexShrink:0,minHeight:0,children:$jsx(TabShell,{title:cur?`Preview \u2014 ${cur.name}`:"Preview",grow:1,children:$jsxs("box",{flexDirection:"column",flexGrow:1,padding:1,alignItems:"center",children:[$jsx("box",{alignItems:"center",justifyContent:"center",width:48,height:24,flexShrink:0,overflow:"hidden",children:parsed?$jsx(AnimatedAvatar,{state:"idle",eikon:parsed},cur.path):$jsx("text",{fg:theme.textMuted,children:"No preview."})}),cur?$jsxs("box",{flexDirection:"column",width:48,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)}),$jsx("box",{height:1}),$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Actions"})}),actions.map((a,i)=>$jsx("box",{height:1,overflow:"hidden",paddingRight:1,backgroundColor:pane==="actions"&&i===act?theme.backgroundElement:void 0,onMouseDown:()=>{setPane("actions"),setAct(i),a.run()},children:$jsxs("text",{fg:a.danger?theme.error:theme.text,wrapMode:"none",children:[pane==="actions"&&i===act?"\u25B8 ":" ",a.label," [",a.key,"]"]})},a.label))]}):null]})})})]}),$jsx(HintBar,{pairs:[["Tab",pane==="list"?"actions":"library"],[keys.print("list.activate"),pane==="actions"?"run action":"use"],["\u2191\u2193",pane==="actions"?"action":"select"],[keys.print("list.new"),"new / install"],[keys.print("list.refresh"),"reload"],...cur&&props.onEdit?[["e","edit in Studio"]]:[]]})]})}),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",manifest4=(dir2)=>{let file2=join20(dir2,"manifest.json");if(!existsSync26(file2))return;try{let raw2=JSON.parse(readFileSync17(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=(value2)=>{try{let url2=new URL(value2);if(url2.protocol==="http:"||url2.protocol==="https:"||url2.protocol==="file:")return url2.href.replace(/\/?$/,"/").toLowerCase()}catch{}return value2.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_react121=__toESM(require_react_production(),1);var import_react120=__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[{label:"Delist from Registry",value:"delist"}];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"},{label:"Delist from Registry",value:"delist"}];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:"Uninstall",value:"delete"}]:[],{label:"Delist from Registry",value:"delist"}]},Action=(props)=>{let theme=useTheme().theme,opts=choices(props.row,props.sizes),[sel,setSel]=import_react120.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 existsSync27,readFileSync as readFileSync18,readdirSync as readdirSync11,writeFileSync as writeFileSync8}from"fs";import{createHash as createHash7}from"crypto";import{basename as basename14,dirname as dirname13,extname as extname4,join as join21}from"path";import{Buffer as Buffer6}from"buffer";var REPO2=process.env.EIKON_REPO??"liftaris/eikon",HOST="eikon.liftaris.dev",enc2=new TextEncoder;async function gh2(args,input){let p=Bun.spawn(["gh",...args],{stdin:input?enc2.encode(input):void 0,stdout:"pipe",stderr:"pipe"}),[out,err,code2]=await Promise.all([new Response(p.stdout).text(),new Response(p.stderr).text(),p.exited]);if(code2!==0)throw Error(err.trim()||out.trim()||`gh ${args[0]} failed`);return out.trim()}function json(text4){return JSON.parse(text4)}function clean5(value2){return value2.replace(/[^A-Za-z0-9_.-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function pkg(entry3){let parts2=entry3.id.includes("/")?entry3.id.split("/"):["liftaris",entry3.name];return{ns:parts2[0]||"liftaris",name:parts2[1]||entry3.name}}function dirs(entry3){let p=pkg(entry3);return[`eikons/${entry3.name}/`,`packages/${p.ns}/${p.name}/`]}function touches(entry3,path4){return dirs(entry3).some((dir2)=>path4.startsWith(dir2))}function official(entry3){try{return new URL(entry3.packageUrl).hostname===HOST&&[entry3.sourceKey,entry3.identityKey].some((key4)=>key4?.startsWith(`registry:${HOST}:`))}catch{return!1}}async function user(run){return run(["api","user","-q",".login"])}async function prs(entry3,repo2,run){let exact=(xs)=>xs.filter((pr)=>pr.title===`eikons: submit ${entry3.name}`&&pr.headRefName===`submit/${entry3.name}`),at=(pr)=>Number.isFinite(Date.parse(pr.mergedAt??""))?Date.parse(pr.mergedAt??""):0,sort=(xs)=>xs.toSorted((a,b2)=>at(a)-at(b2)||a.number-b2.number),first=exact(json(await run(["pr","list","-R",repo2,"--state","merged","--search",`"eikons: submit ${entry3.name}" in:title`,"--json","number,title,headRefName,url,mergedAt,author","--limit","100"])));if(first.length)return sort(first);return sort(exact(json(await run(["pr","list","-R",repo2,"--state","merged","--json","number,title,headRefName,url,mergedAt,author","--limit","100"]))))}async function files(repo2,pr,run){return(await run(["api","--paginate","-X","GET",`repos/${repo2}/pulls/${pr}/files`,"--jq",".[].filename"])).split(/\r?\n/).filter(Boolean).map((path4)=>({path:path4}))}async function found(entry3,repo2,run){for(let pr of await prs(entry3,repo2,run)){let title=pr.title===`eikons: submit ${entry3.name}`,head=pr.headRefName===`submit/${entry3.name}`;if(!title||!head)continue;if((await files(repo2,pr.number,run)).some((f)=>touches(entry3,f.path??f.filename??"")))return pr}return}async function info2(entry3,opts={}){let run=opts.run??gh2,repo2=opts.repo??REPO2;if(!official(entry3))return{eligible:!1,reason:"Registry delist is only available for official Eikon catalog entries"};let login;try{login=await user(run)}catch(err){return{eligible:!1,reason:err instanceof Error?err.message:String(err)}}let pr=await found(entry3,repo2,run),author=pr?.author?.login;if(!pr||!author)return{eligible:!1,user:login,reason:"No merged GitHub submission found"};if(author!==login)return{eligible:!1,user:login,author,pr:pr.number,url:pr.url,reason:`Submitted by @${author}`};return{eligible:!0,user:login,author,pr:pr.number,url:pr.url}}async function exists(run,repo2,branch3,path4){try{let raw2=await run(["api","-X","GET",`repos/${repo2}/contents/${path4}`,"-f",`ref=${branch3}`]);return json(raw2).sha}catch{return}}async function put2(run,repo2,branch3,path4,text4,msg){let sha2=await exists(run,repo2,branch3,path4);await run(["api","-X","PUT",`repos/${repo2}/contents/${path4}`,"--input","-"],JSON.stringify({message:msg,branch:branch3,content:Buffer6.from(text4).toString("base64"),...sha2?{sha:sha2}:{}}))}async function del(run,repo2,branch3,path4,sha2,msg){await run(["api","-X","DELETE",`repos/${repo2}/contents/${path4}`,"--input","-"],JSON.stringify({message:msg,branch:branch3,sha:sha2}))}async function main(run,repo2){let sha2=await run(["api",`repos/${repo2}/git/ref/heads/main`,"-q",".object.sha"]),tree2=await run(["api",`repos/${repo2}/git/commits/${sha2}`,"-q",".tree.sha"]);return{sha:sha2,tree:tree2}}async function tree2(run,repo2,sha2){return json(await run(["api","-X","GET",`repos/${repo2}/git/trees/${sha2}`,"-f","recursive=1"])).tree??[]}async function index3(run,repo2){let raw2=json(await run(["api","-X","GET",`repos/${repo2}/contents/eikons/index.json`,"-f","ref=main"]));return Buffer6.from((raw2.content??"").replace(/\s/g,""),"base64").toString("utf8")}async function reset3(run,repo2,name,sha2){try{await run(["api","-X","POST",`repos/${repo2}/git/refs`,"-f",`ref=refs/heads/${name}`,"-f",`sha=${sha2}`])}catch{await run(["api","-X","PATCH",`repos/${repo2}/git/refs/heads/${name}`,"--input","-"],JSON.stringify({sha:sha2,force:!0}))}}async function pr(run,repo2,user2,branch3,name,body){try{return await run(["pr","create","-R",repo2,"-H",`${user2}:${branch3}`,"-B","main","-t",`eikons: delist ${name}`,"-b",body])}catch{let raw2=await run(["api","-X","GET",`repos/${repo2}/pulls`,"-f","state=open","-f",`head=${user2}:${branch3}`]),hit2=json(raw2)[0]?.url;if(hit2)return hit2;throw Error("GitHub PR creation failed")}}async function submit3(entry3,opts={}){let run=opts.run??gh2,repo2=opts.repo??REPO2,own=await info2(entry3,{repo:repo2,run});if(!own.eligible||!own.user)throw Error(own.reason??"not authorized to delist this eikon");await run(["repo","fork",repo2,"--clone=false"]).catch(()=>"");let fork2=`${own.user}/${repo2.split("/")[1]}`,branch3=`delist/${clean5(entry3.name)}`,base3=await main(run,repo2);await reset3(run,fork2,branch3,base3.sha);let msg=`eikons: delist ${entry3.name}`,next3=json(await index3(run,repo2)).filter((e)=>e.name!==entry3.name&&e.id!==entry3.id);await put2(run,fork2,branch3,"eikons/index.json",`${JSON.stringify(next3,null,2)}
4171
+ `),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_react116.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_react116.useCallback(async()=>{let cur=sRef.current;if(!cur)return;let path4=submitPath(cur.name);if(publishedInfo(path4)){toast.show({variant:"warning",title:"Published eikon",message:"Create a local draft before submitting",duration:6000});return}if(cur.dirty||!existsSync25(path4)){let pick2=await openSaveDiscard(dialog,{title:"Save before submit?",body:`'${cur.name}' has unsaved changes. Save to submit the current preview, discard to submit the last saved artifact, or keep editing.`});if(pick2==="save"){if(get2("eikon")===cur.name){if(!await openConfirm(dialog,{title:`Save active '${cur.name}' before submit?`,danger:!0,body:"Saving changes the active avatar's backing artifact. Submit itself will not change active selection.",yes:"save",no:"cancel"}))return}if(!await doSave())return}else if(pick2==="discard")open3(cur.name);else return}if(!existsSync25(path4)){toast.show({variant:"warning",message:"Save this eikon before submitting"});return}await openEikonSubmit(dialog,{name:cur.name,path:path4,submit:submit2})},[dialog,doSave,open3,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(!status2?.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())open3(cur.name);return!0}if(pick2==="discard")open3(cur.name);return!0},refresh=import_react116.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}open3(cur.name),toast.show({variant:"info",message:"Reloaded",duration:1000})},[open3,toast]);useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(key3.eventType==="release")return;if(key3.name==="u"&&key3.ctrl&&sRef.current)return void doSaveUse();if(key3.name==="u"&&sRef.current)return void doSubmit();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),next3=PANES[(i+(key3.shift?PANES.length-1:1))%PANES.length];setPane(next3),outer.current?.scrollChildIntoView(`studio-${next3}`);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}))},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","library"]]: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),preview2=$jsx(PreviewPane,{s,frames,play,setPlay,focused:Boolean(props.focused),busy:busy2,live,baked:baked2,spatialOk,error:previewErr,pane,sel:spSel,onPane:setPane,onSel:setSpSel,onSet:setBar,onWheel:stepBar,onScroll}),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:status2,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,top2=wide?$jsxs("box",{flexDirection:"row",flexShrink:0,height:PREVIEW_H,children:[$jsx("box",{id:"studio-preview",flexShrink:0,width:PREVIEW_W,children:preview2}),$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:preview2}),$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:[top2,strip]}),$jsx(HintBar,{pairs:hint,suffix:saving?"\u25CF saving\u2026":s?.dirty?"\u25CF unsaved":void 0})]})});var import_react118=__toESM(require_react_production(),1);import{existsSync as existsSync26,readFileSync as readFileSync17}from"fs";import{basename as basename13,dirname as dirname12,join as join20}from"path";var EIKON_CARD=50,titleWidth=(title,rows3)=>Math.max(title.length,...rows3.map((r)=>r.name.length+4))+7,cardWidth=(lines3)=>Math.max(EIKON_CARD,...lines3.map((line4)=>line4.length+2)),EikonTitleList=(props)=>{let theme=useTheme().theme;return $jsx("box",{width:props.width,flexShrink:0,minHeight:0,children:$jsx(TabShell,{title:props.title,focus:props.focus,grow:1,children:$jsx("box",{flexDirection:"column",flexGrow:1,minHeight:0,children:$jsx("scrollbox",{ref:props.follow.ref,scrollY:!0,flexGrow:1,children:props.rows.length===0?$jsx("text",{fg:theme.textMuted,children:"No eikons found."}):props.rows.map((r,i)=>{let on=i===props.sel;return $jsxs("box",{id:props.follow.id(i),flexDirection:"row",height:1,paddingRight:3,backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:()=>props.onSel(i),onMouseDown:()=>{props.onSel(i),props.onUse(i)},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:r.active?theme.accent:theme.text,children:[r.active?"\u25CF ":" ",$jsx("strong",{children:r.name})]})})]},r.key)})})})})})},EikonCardGrid=(props)=>{let theme=useTheme().theme;if(props.rows.length===0)return $jsx("box",{padding:1,children:props.empty??$jsx("text",{fg:theme.textMuted,children:"No eikons found."})});return $jsx("scrollbox",{ref:props.follow.ref,scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"row",flexWrap:"wrap",width:"100%",flexShrink:0,children:props.rows.map((r,i)=>{let on=i===props.sel;return $jsxs("box",{id:props.follow.id(i),flexDirection:"column",height:r.lines.length+2,width:cardWidth(r.lines),flexShrink:0,paddingX:1,backgroundColor:on?theme.backgroundElement:void 0,onMouseMove:()=>props.onSel(i),onMouseDown:()=>{props.onSel(i),props.onUse(i)},children:[$jsx("box",{height:r.lines.length,overflow:"hidden",flexDirection:"column",children:r.lines.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.name})]})}),$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{fg:theme.textMuted,wrapMode:"none",children:["by ",r.author??"unknown"," \xB7 ",r.status]})})]},r.key)})})})};var PREVIEW2=54,EikonGallery=import_react118.memo((props)=>{let theme=useTheme().theme,dialog=useDialog(),toast=useToast(),keys=useKeys(),rev3=import_react118.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision),dims=useTerminalDimensions(),rows3=import_react118.useMemo(()=>{let user=hermesPath("eikons"),own=exports_eikon.list(),map=new Map(own.map((x2)=>[x2.name.toLowerCase(),x2])),meta2=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():dirname12(e.path)===user?basename13(e.path,".eikon"):basename13(dirname12(e.path)),man=manifest4(dirname12(e.path)),keys2=ids2(man,slug3),mine=meta2.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)).reduce((map2,row3)=>{let prev=map2.get(row3.slug);if(!prev||dirname12(prev.path)===user&&dirname12(row3.path)!==user)map2.set(row3.slug,row3);return map2},new Map).values()]},[rev3]),active2=usePref("eikon"),path4=import_react118.useMemo(()=>active2?exports_eikon.baked(active2):void 0,[active2,rev3]),current2=(row3)=>path4===row3.path,[sel,setSel]=import_react118.useState(0),[pane,setPane]=import_react118.useState("list"),[act,setAct]=import_react118.useState(0),galleryFollow=useFollow("gal",(i)=>rows3[i]?.slug??i),gridFollow=useFollow("lib-grid",(i)=>rows3[i]?.slug??i);import_react118.useEffect(()=>{if(sel>=rows3.length)setSel(Math.max(0,rows3.length-1))},[rows3.length,sel]);let cur=rows3[sel],parsed=import_react118.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_react118.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_react118.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_react118.useCallback(async()=>{if(!cur||cur.bundled)return;let path6=submitPath(cur.slug);if(publishedInfo(path6)){toast.show({variant:"warning",title:"Published eikon",message:"Create a local draft before submitting",duration:6000});return}await openEikonSubmit(dialog,{name:cur.name,path:path6,submit:props.submit??submit2})},[cur,dialog,props.submit,toast]),del=async()=>{if(!cur||cur.bundled)return;let here=current2(cur),base3=dirname12(cur.path)===hermesPath("eikons")?`Removes legacy flat file ${basename13(cur.path)}.`:`Removes ${dirname12(cur.path)} and all its sources.`,body=here?`${base3} This is the active avatar; deleting it will clear the active avatar selection.`:base3;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}`})},actions=import_react118.useMemo(()=>{if(!cur)return[];return[{key:"Enter",label:current2(cur)?"Use as active avatar (active)":"Use as active avatar",run:()=>activate()},...props.onEdit?[{key:"e",label:"Edit in Studio",run:()=>props.onEdit?.(cur.slug)}]:[],...!cur.bundled?[{key:"u",label:"Update local package",run:()=>void updateLocal()},{key:"s",label:"Share to catalog",run:()=>void submitLocal()},{key:"d",label:"Delete local eikon",run:()=>void del(),danger:!0}]:[]]},[cur,path4,props.onEdit,updateLocal,submitLocal]);import_react118.useEffect(()=>{if(act>=actions.length)setAct(Math.max(0,actions.length-1))},[act,actions.length]);let cards=import_react118.useMemo(()=>rows3.map((r)=>{let p=(()=>{try{return parseEikonFile(r.path)}catch{return}})(),lines3=p?.resolve("state.idle")?.frames[0]??p?.states.get("idle")?.frames[0]??["(no preview)"];return{key:r.path,name:r.name,active:current2(r),author:r.author,status:current2(r)?"active":r.bundled?"bundled/system":"installed",lines:lines3}}),[rows3,path4]);useKeyboard((key3)=>{if(!props.focused||dialog.open())return;let plain=!key3.shift&&!key3.ctrl&&!key3.meta;if(key3.name==="tab")return setPane((p)=>p==="list"?"actions":"list");if(pane==="actions"){if(key3.name==="escape"||plain&&key3.name==="left"){setPane("list");return}if(plain&&key3.name==="up"){setAct((i)=>Math.max(0,i-1));return}if(plain&&key3.name==="down"){setAct((i)=>Math.min(actions.length-1,i+1));return}if(keys.match("list.activate",key3)||keys.match("list.toggle",key3)){actions[act]?.run();return}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)});let listW=Math.max(13,...rows3.map((r)=>r.name.length+4))+7,showGrid=dims.width-listW-PREVIEW2>=EIKON_CARD;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,minHeight:0,children:[$jsx(EikonTitleList,{title:`Library (${rows3.length})`,rows:rows3.map((r)=>({key:r.path,name:r.name,active:current2(r)})),sel,focus:props.focused&&pane==="list",follow:galleryFollow,width:listW,onSel:setSel,onUse:(i)=>activate(rows3[i])}),showGrid?$jsx(TabShell,{title:"Grid",grow:1,children:$jsx(EikonCardGrid,{rows:cards,sel,follow:gridFollow,onSel:setSel,onUse:(i)=>activate(rows3[i])})}):null,$jsx("box",{width:PREVIEW2,flexShrink:0,minHeight:0,children:$jsx(TabShell,{title:cur?`Preview \u2014 ${cur.name}`:"Preview",grow:1,children:$jsxs("box",{flexDirection:"column",flexGrow:1,padding:1,alignItems:"center",children:[$jsx("box",{alignItems:"center",justifyContent:"center",width:48,height:24,flexShrink:0,overflow:"hidden",children:parsed?$jsx(AnimatedAvatar,{state:"idle",eikon:parsed},cur.path):$jsx("text",{fg:theme.textMuted,children:"No preview."})}),cur?$jsxs("box",{flexDirection:"column",width:48,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)}),$jsx("box",{height:1}),$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Actions"})}),actions.map((a,i)=>$jsx("box",{height:1,overflow:"hidden",paddingRight:1,backgroundColor:pane==="actions"&&i===act?theme.backgroundElement:void 0,onMouseDown:()=>{setPane("actions"),setAct(i),a.run()},children:$jsxs("text",{fg:a.danger?theme.error:theme.text,wrapMode:"none",children:[pane==="actions"&&i===act?"\u25B8 ":" ",a.label," [",a.key,"]"]})},a.label))]}):null]})})})]}),$jsx(HintBar,{pairs:[["Tab",pane==="list"?"actions":"library"],[keys.print("list.activate"),pane==="actions"?"run action":"use"],["\u2191\u2193",pane==="actions"?"action":"select"],[keys.print("list.new"),"new / install"],[keys.print("list.refresh"),"reload"],...cur&&props.onEdit?[["e","edit in Studio"]]:[]]})]})}),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",manifest4=(dir2)=>{let file2=join20(dir2,"manifest.json");if(!existsSync26(file2))return;try{let raw2=JSON.parse(readFileSync17(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=(value2)=>{try{let url2=new URL(value2);if(url2.protocol==="http:"||url2.protocol==="https:"||url2.protocol==="file:")return url2.href.replace(/\/?$/,"/").toLowerCase()}catch{}return value2.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_react121=__toESM(require_react_production(),1);var import_react120=__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[{label:"Delist from Registry",value:"delist"}];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"},{label:"Delist from Registry",value:"delist"}];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:"Uninstall",value:"delete"}]:[],{label:"Delist from Registry",value:"delist"}]},Action=(props)=>{let theme=useTheme().theme,opts=choices(props.row,props.sizes),[sel,setSel]=import_react120.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 existsSync27,readFileSync as readFileSync18,readdirSync as readdirSync11,writeFileSync as writeFileSync8}from"fs";import{createHash as createHash7}from"crypto";import{basename as basename14,dirname as dirname13,extname as extname4,join as join21}from"path";import{Buffer as Buffer6}from"buffer";var REPO2=process.env.EIKON_REPO??"liftaris/eikon",HOST="eikon.liftaris.dev",enc2=new TextEncoder;async function gh2(args,input){let p=Bun.spawn(["gh",...args],{stdin:input?enc2.encode(input):void 0,stdout:"pipe",stderr:"pipe"}),[out,err,code2]=await Promise.all([new Response(p.stdout).text(),new Response(p.stderr).text(),p.exited]);if(code2!==0)throw Error(err.trim()||out.trim()||`gh ${args[0]} failed`);return out.trim()}function json(text4){return JSON.parse(text4)}function clean6(value2){return value2.replace(/[^A-Za-z0-9_.-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function pkg(entry3){let parts2=entry3.id.includes("/")?entry3.id.split("/"):["liftaris",entry3.name];return{ns:parts2[0]||"liftaris",name:parts2[1]||entry3.name}}function dirs(entry3){let p=pkg(entry3);return[`eikons/${entry3.name}/`,`packages/${p.ns}/${p.name}/`]}function touches(entry3,path4){return dirs(entry3).some((dir2)=>path4.startsWith(dir2))}function official(entry3){try{return new URL(entry3.packageUrl).hostname===HOST&&[entry3.sourceKey,entry3.identityKey].some((key4)=>key4?.startsWith(`registry:${HOST}:`))}catch{return!1}}async function user(run){return run(["api","user","-q",".login"])}async function prs(entry3,repo2,run){let exact=(xs)=>xs.filter((pr)=>pr.title===`eikons: submit ${entry3.name}`&&pr.headRefName===`submit/${entry3.name}`),at=(pr)=>Number.isFinite(Date.parse(pr.mergedAt??""))?Date.parse(pr.mergedAt??""):0,sort=(xs)=>xs.toSorted((a,b2)=>at(a)-at(b2)||a.number-b2.number),first=exact(json(await run(["pr","list","-R",repo2,"--state","merged","--search",`"eikons: submit ${entry3.name}" in:title`,"--json","number,title,headRefName,url,mergedAt,author","--limit","100"])));if(first.length)return sort(first);return sort(exact(json(await run(["pr","list","-R",repo2,"--state","merged","--json","number,title,headRefName,url,mergedAt,author","--limit","100"]))))}async function files(repo2,pr,run){return(await run(["api","--paginate","-X","GET",`repos/${repo2}/pulls/${pr}/files`,"--jq",".[].filename"])).split(/\r?\n/).filter(Boolean).map((path4)=>({path:path4}))}async function found(entry3,repo2,run){for(let pr of await prs(entry3,repo2,run)){let title=pr.title===`eikons: submit ${entry3.name}`,head=pr.headRefName===`submit/${entry3.name}`;if(!title||!head)continue;if((await files(repo2,pr.number,run)).some((f)=>touches(entry3,f.path??f.filename??"")))return pr}return}async function info2(entry3,opts={}){let run=opts.run??gh2,repo2=opts.repo??REPO2;if(!official(entry3))return{eligible:!1,reason:"Registry delist is only available for official Eikon catalog entries"};let login;try{login=await user(run)}catch(err){return{eligible:!1,reason:err instanceof Error?err.message:String(err)}}let pr=await found(entry3,repo2,run),author=pr?.author?.login;if(!pr||!author)return{eligible:!1,user:login,reason:"No merged GitHub submission found"};if(author!==login)return{eligible:!1,user:login,author,pr:pr.number,url:pr.url,reason:`Submitted by @${author}`};return{eligible:!0,user:login,author,pr:pr.number,url:pr.url}}async function exists(run,repo2,branch3,path4){try{let raw2=await run(["api","-X","GET",`repos/${repo2}/contents/${path4}`,"-f",`ref=${branch3}`]);return json(raw2).sha}catch{return}}async function put2(run,repo2,branch3,path4,text4,msg){let sha2=await exists(run,repo2,branch3,path4);await run(["api","-X","PUT",`repos/${repo2}/contents/${path4}`,"--input","-"],JSON.stringify({message:msg,branch:branch3,content:Buffer6.from(text4).toString("base64"),...sha2?{sha:sha2}:{}}))}async function del(run,repo2,branch3,path4,sha2,msg){await run(["api","-X","DELETE",`repos/${repo2}/contents/${path4}`,"--input","-"],JSON.stringify({message:msg,branch:branch3,sha:sha2}))}async function main(run,repo2){let sha2=await run(["api",`repos/${repo2}/git/ref/heads/main`,"-q",".object.sha"]),tree2=await run(["api",`repos/${repo2}/git/commits/${sha2}`,"-q",".tree.sha"]);return{sha:sha2,tree:tree2}}async function tree2(run,repo2,sha2){return json(await run(["api","-X","GET",`repos/${repo2}/git/trees/${sha2}`,"-f","recursive=1"])).tree??[]}async function index3(run,repo2){let raw2=json(await run(["api","-X","GET",`repos/${repo2}/contents/eikons/index.json`,"-f","ref=main"]));return Buffer6.from((raw2.content??"").replace(/\s/g,""),"base64").toString("utf8")}async function reset3(run,repo2,name,sha2){try{await run(["api","-X","POST",`repos/${repo2}/git/refs`,"-f",`ref=refs/heads/${name}`,"-f",`sha=${sha2}`])}catch{await run(["api","-X","PATCH",`repos/${repo2}/git/refs/heads/${name}`,"--input","-"],JSON.stringify({sha:sha2,force:!0}))}}async function pr(run,repo2,user2,branch3,name,body){try{return await run(["pr","create","-R",repo2,"-H",`${user2}:${branch3}`,"-B","main","-t",`eikons: delist ${name}`,"-b",body])}catch{let raw2=await run(["api","-X","GET",`repos/${repo2}/pulls`,"-f","state=open","-f",`head=${user2}:${branch3}`]),hit2=json(raw2)[0]?.url;if(hit2)return hit2;throw Error("GitHub PR creation failed")}}async function submit3(entry3,opts={}){let run=opts.run??gh2,repo2=opts.repo??REPO2,own=await info2(entry3,{repo:repo2,run});if(!own.eligible||!own.user)throw Error(own.reason??"not authorized to delist this eikon");await run(["repo","fork",repo2,"--clone=false"]).catch(()=>"");let fork2=`${own.user}/${repo2.split("/")[1]}`,branch3=`delist/${clean6(entry3.name)}`,base3=await main(run,repo2);await reset3(run,fork2,branch3,base3.sha);let msg=`eikons: delist ${entry3.name}`,next3=json(await index3(run,repo2)).filter((e)=>e.name!==entry3.name&&e.id!==entry3.id);await put2(run,fork2,branch3,"eikons/index.json",`${JSON.stringify(next3,null,2)}
4172
4172
  `,msg);for(let item of await tree2(run,repo2,base3.tree)){if(!item.path||item.type!=="blob"||!item.sha||!touches(entry3,item.path))continue;let sha2=await exists(run,fork2,branch3,item.path)??item.sha;await del(run,fork2,branch3,item.path,sha2,msg)}return{url:await pr(run,repo2,own.user,branch3,entry3.name,`Requests delisting \`${entry3.name}\` from the Eikon registry.`),info:own}}var DEFAULT_TIMEOUT=5000,DEFAULT_CACHE_LIMIT=24,OFFICIAL_CATALOG="https://eikon.liftaris.dev/eikons",dec=new TextDecoder;function hash2(data2){return`sha256:${createHash7("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,source2){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=source2?new URL(source2).host:void 0;if(!host)return;return`registry:${host}:${man.id}${typeof man.version==="string"&&man.version?`@${man.version}`:""}`}catch{return}}function entryKeys(entry3){return[...new Set([entry3.identityKey,entry3.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 base3=manifestBaseKey(origin2);if(base3)keys.add(keyIdentity(base3))}if(src3){keys.add(keyIdentity(src3));let base3=manifestBaseKey(src3);if(base3)keys.add(keyIdentity(base3))}return[...keys]}function read2(path4){try{let man=JSON.parse(readFileSync18(path4,"utf8"));return obj(man)?man:void 0}catch{return}}function chosen(active2,name){return active2===name||active2==="default"&&name==="nous"}function media(dir2){return existsSync27(dir2)&&readdirSync11(dir2).length>0}function text4(value2){return typeof value2==="string"&&value2?value2:void 0}function life(name,man){let origin2=obj(man.origin)?man.origin:{},display3=obj(man.display)?man.display:{},src3=text4(origin2.source),identity2=text4(origin2.identityKey)??text4(origin2.sourceKey)??text4(origin2.packageUrl)??text4(origin2.repo)??src3,title=text4(display3.title)??text4(man.title),author=text4(display3.author)??text4(man.author);return{name,...title?{title}:{},...author?{author}:{},...text4(man.version)?{version:text4(man.version)}:{},source:{kind:text4(origin2.kind)??"default-catalog",...identity2?{identity:identity2}:{},...src3?{origin:src3}:{},...text4(origin2.repo)?{repo:text4(origin2.repo)}:{},...text4(origin2.selector)?{selector:text4(origin2.selector)}:{},...text4(origin2.catalogRoot)?{catalogRoot:text4(origin2.catalogRoot)}:{},...text4(origin2.sha)?{sha:text4(origin2.sha)}:{},...text4(origin2.packageUrl)?{packageUrl:text4(origin2.packageUrl)}:{}},trust:text4(origin2.trust)??"verified",active:chosen(get2("eikon"),name),removable:!1,updateable:Boolean(src3??text4(origin2.packageUrl)),updateAvailable:!1,dirty:!1,...text4(man.poster)?{poster:text4(man.poster)}:{},...obj(man.compatibility)?{compatibility:man.compatibility}:{},...text4(origin2.at)?{installedAt:text4(origin2.at)}:{}}}function bundled(xs){let names=new Set(xs.map((x2)=>x2.name.toLowerCase()));return listEikons([BUNDLED_EIKON_DIR]).flatMap((e)=>{let man=read2(join21(dirname13(e.path),"manifest.json"));if(man?.kind!=="eikon.package")return[];let name=text4(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:text4(man.origin?.source)??text4(man.origin?.packageUrl),manifest:man,lifecycle:life(name,man)};return[{...inst,manifest:man,identityKeys:keysFor(inst)}]})}function cacheKey(entry3){return[entry3.identityKey||entry3.sourceKey||entry3.id,entry3.runtimeUrl,entry3.trust?.runtimeDigest,entry3.trust?.runtimeSize].filter(Boolean).join("|")}function blob(url2){return/\/blobs\/sha256\/[^/?#]+/.test(url2)}function artifact(entry3){return entry3}function obj(value2){return!!value2&&typeof value2==="object"&&!Array.isArray(value2)}function rawManifest(entry3){let raw2=entry3.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 sourceDescriptors3(man){return sourceEntries2(man).length>0}function sourceAvailable2(entry3,inst){return sourceDescriptors3(inst?.manifest)||sourceDescriptors3(rawManifest(entry3))}function trust(entry3){return entry3.trust}function boundTrust(entry3,raw2){let t2=trust(entry3),man=t2.manifestDigest,run=t2.runtimeDigest;if(!man&&!run)return"unverified";if(man&&hash2(raw2)!==man)throw Error(`catalog trust mismatch: manifest digest for ${entry3.name}`);let pkg2=JSON.parse(dec.decode(raw2)),rel2=pkg2.entrypoints?.default,got=rel2?pkg2.files?.find((f)=>f.path===rel2)?.digest:void 0;if(run&&got!==run)throw Error(`catalog trust mismatch: runtime digest for ${entry3.name}`);return man&&run?"verified":"unverified"}function spec2(man,rel2){return man.files?.find((f)=>f.path===rel2)}async function sourceBytes(man,base3,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,base3).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(entry3){let t2=trust(entry3);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(entry3,xs){let keys=entryKeys(entry3),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===entry3.name&&x2.identityKeys.length===0);if(named)return{inst:named,legacy:!0};return}function row3(entry3,xs){let usable=match2(entry3,xs),active2=usable?chosen(get2("eikon"),usable.inst.name):!1,installed2=Boolean(usable),conflict=!usable&&chosen(get2("eikon"),entry3.name),blocked=entry3.compatibility?.available===!1,mismatch=usable?.inst.lifecycle.trust==="mismatch",installState=mismatch?"mismatch":blocked?"incompatible":active2?"active":conflict?"active-name-conflict":!usable?"available":usable.legacy?"legacy-name-match":"installed",lifecycle2=usable?.inst.lifecycle??{name:entry3.name,title:entry3.title,author:entry3.author,version:entry3.version,source:{kind:"default-catalog",identity:entry3.sourceKey,packageUrl:entry3.packageUrl},trust:verifiedCatalogTrust(entry3)?"verified":"unverified",active:!1,removable:!1,updateable:!1,updateAvailable:!1,dirty:!1,...entry3.poster?{poster:entry3.poster}:{},compatibility:entry3.compatibility},available2=sourceAvailable2(entry3,usable?.inst);return{entry:entry3,installed:installed2,active:active2,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:available2,sourceDownloadable:Boolean(usable&&!usable.inst.hasSource&&available2),reason:blocked?entry3.compatibility?.reason??"incompatible":mismatch?"trust mismatch":conflict?"install would replace the active avatar backing package":void 0,action:active2?"active":installed2?"use":"install"}}function sizes(man){let files2=Array.isArray(man.files)?man.files:[],eikon=files2.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),source2=files2.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}:{},...source2>0?{source:source2}:{}}}function abortErr(){return new DOMException("aborted","AbortError")}class MarketplaceService{catalog;fetcher;timeoutMs;previewCacheLimit;concurrency;allowPrivate;official;delistRepo;delistRun;activeLoads=0;queue=[];cache=new Map;inFlight=new Map;constructor(catalog3,opts={}){this.catalog=catalog3,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,this.official=keyIdentity(publicCatalogUrl(opts.catalog??OFFICIAL_CATALOG,void 0,opts))===keyIdentity(OFFICIAL_CATALOG),this.delistRepo=opts.delistRepo,this.delistRun=opts.delistRun}rows(query2=""){let entries2=searchCatalog(this.catalog.entries,query2),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(entry3,signal){return async(input)=>{let url2=target(input),bound=keyIdentity(url2)===keyIdentity(entry3.runtimeUrl)&&(!!entry3.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 entry3=this.entry(id);if(!entry3)throw Error(`marketplace: unknown eikon "${id}"`);let key4=cacheKey(entry3),hit2=this.cache.get(key4);if(hit2!==void 0)return hit2;let active2=this.inFlight.get(key4);if(active2)return active2;let p=this.enqueue(()=>this.loadPreview(entry3,opts)).finally(()=>this.inFlight.delete(key4));return this.inFlight.set(key4,p),p}async packageSizes(id){let entry3=this.entry(id);if(!entry3)throw Error(`marketplace: unknown eikon "${id}"`);return sizes(JSON.parse(dec.decode(await downloadBytes(entry3.packageUrl,this.dl()))))}async delistInfo(id){let entry3=this.entry(id);if(!entry3)throw Error(`marketplace: unknown eikon "${id}"`);if(!this.official)return{eligible:!1,reason:"Registry delist is only available from the official Eikon catalog"};return info2(entry3,{repo:this.delistRepo,run:this.delistRun})}async delist(id){let entry3=this.entry(id);if(!entry3)throw Error(`marketplace: unknown eikon "${id}"`);if(!this.official)throw Error("Registry delist is only available from the official Eikon catalog");return submit3(entry3,{repo:this.delistRepo,run:this.delistRun})}async install(id,opts={}){let entry3=this.entry(id);if(!entry3)throw Error(`marketplace: unknown eikon "${id}"`);if(entry3.compatibility?.available===!1)throw Error(entry3.compatibility.reason??"eikon is incompatible");if(!match2(entry3,installed())&&chosen(get2("eikon"),entry3.name)&&!opts.confirmActive)throw Error(`Installing '${entry3.name}' will replace the active avatar's backing package. Pass confirmActive to install it.`);let raw2=await downloadBytes(entry3.packageUrl,this.dl()),state3=boundTrust(entry3,raw2),out=await exports_eikon.fetchSource(entry3.packageUrl,{name:entry3.name,media:opts.media===!0,downloader:this.dl(void 0,this.cached(entry3.packageUrl,raw2))}),ef=exports_eikon.file(out.name);if(!existsSync27(ef)){let art=await loadRuntimeArtifact(entry3,this.runtime(entry3),{allowPrivate:this.allowPrivate});await Bun.write(ef,art.bytes),exports_eikon.notifyRevision()}let mf=join21(exports_eikon.dir(out.name),"manifest.json"),man=JSON.parse(readFileSync18(mf,"utf8")),origin2=man.origin&&typeof man.origin==="object"&&!Array.isArray(man.origin)?man.origin:{};return writeFileSync8(mf,JSON.stringify({...man,origin:{...origin2,sourceKey:entry3.sourceKey,identityKey:entry3.identityKey,packageUrl:entry3.packageUrl,trust:state3}},null,2)+`
4173
4173
  `),out}async downloadSource(id){let entry3=this.entry(id);if(!entry3)throw Error(`marketplace: unknown eikon "${id}"`);let usable=match2(entry3,installed());if(!usable)throw Error(`marketplace: "${entry3.name}" is not installed`);if(!sourceAvailable2(entry3,usable.inst))throw Error(`marketplace: no source media published for "${entry3.name}"`);let raw2=await downloadBytes(entry3.packageUrl,this.dl());boundTrust(entry3,raw2);let man=JSON.parse(dec.decode(raw2)),xs=sourceEntries2(man,!0);if(xs.length===0)throw Error(`marketplace: no source media published for "${entry3.name}"`);let base3=new URL(".",entry3.packageUrl).href,dir2=exports_eikon.ensure(usable.inst.name).source,pairs=await Promise.all(xs.map(async([r,rel2])=>{let data2=await sourceBytes(man,base3,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(join21(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(entry3,opts){let ctl=new AbortController,timeout2=setTimeout(()=>ctl.abort(),opts.timeoutMs??this.timeoutMs),off=()=>ctl.abort();opts.signal?.addEventListener("abort",off,{once:!0});try{let item=artifact(entry3),text5=(await loadRuntimeArtifact(item,this.runtime(item,ctl.signal),{signal:ctl.signal,allowPrivate:this.allowPrivate})).text;this.cache.set(cacheKey(entry3),text5);while(this.cache.size>this.previewCacheLimit)this.cache.delete(this.cache.keys().next().value);return text5}finally{clearTimeout(timeout2),opts.signal?.removeEventListener("abort",off)}}}async function load4(opts={}){let query2=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(query2);return{status:rows3.length>0?"ready":"empty",query:query2,rows:rows3,selected:rows3[0],service}}catch(err){return{status:"error",query:query2,rows:[],error:err instanceof Error?err.message:String(err)}}}var NO_MARKET={status:"empty",query:"",rows:[]},DETAIL=54;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 filterRows=(rows3,query2)=>{let q5=query2.trim().toLowerCase();if(!q5)return rows3;return rows3.filter((r)=>[r.entry.name,r.entry.author,r.entry.description,r.entry.id].some((x2)=>typeof x2==="string"&&x2.toLowerCase().includes(q5)))},EikonMarketplace=import_react121.memo((props)=>{let toast=useToast(),dialog=useDialog(),keys=useKeys(),theme=useTheme().theme,rev3=import_react121.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision),[sel,setSel]=import_react121.useState(0),[searching,setSearching]=import_react121.useState(!1),[query2,setQuery]=import_react121.useState(""),[state3,setState2]=import_react121.useState(NO_MARKET),[loading,setLoading]=import_react121.useState(!1),[installing,setInstalling]=import_react121.useState(!1),[acting,setActing]=import_react121.useState(!1),[previewState,setPreviewState]=import_react121.useState("idle"),[preview2,setPreview]=import_react121.useState(void 0),[pane,setPane]=import_react121.useState("grid"),previewSeq=import_react121.useRef(0),loadSeq=import_react121.useRef(0),actingRef=import_react121.useRef(!1),follow=useFollow("market",(i)=>state3.rows[i]?.entry.identityKey??i),listFollow=useFollow("market-list",(i)=>state3.rows[i]?.entry.identityKey??i),dims=useTerminalDimensions();import_react121.useEffect(()=>{if(sel>=state3.rows.length)setSel(Math.max(0,state3.rows.length-1))},[state3.rows.length,sel]);let selected=state3.rows[sel];import_react121.useEffect(()=>{if(!selected||!state3.service){setPreview(void 0);return}let id=++previewSeq.current,key4=selected.entry.identityKey;count("market:preview:load"),state3.service.preview(key4).then((text5)=>{if(previewSeq.current!==id)return;let e=parseEikon(text5),st=e.states.has(previewState)?previewState:"idle";setPreview({eikon:e,state:st,states:[...e.states.keys()]}),count("market:preview:ready")}).catch(()=>{if(previewSeq.current!==id)return;setPreview(void 0),count("market:preview:error")})},[selected,state3.service,previewState]),import_react121.useEffect(()=>()=>{previewSeq.current++,setPreview(void 0)},[]);let loadMarket=import_react121.useCallback((q5=query2)=>{let id=++loadSeq.current;setLoading(!0);let end=mark("market:list:load"),catalog3=process.env.EIKON_URL;load4({catalog:catalog3,allowPrivate:localCatalog(catalog3),query:q5}).then((next3)=>{if(loadSeq.current!==id)return;count("market:list:rows",next3.rows.length);let rows3=next3.service?filterRows(next3.service.rows(""),q5):filterRows(next3.rows,q5);setState2({...next3,status:rows3.length>0?"ready":"empty",rows:rows3,selected:rows3[0]}),setSel((p)=>Math.max(0,Math.min(rows3.length-1,p)))}).finally(()=>{if(end(),loadSeq.current===id)setLoading(!1)})},[query2]),refreshMarket=import_react121.useCallback((svc,q5=query2)=>{let rows3=filterRows(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)))},[query2]);import_react121.useEffect(()=>{loadMarket(query2)},[query2,rev3,loadMarket]);let cycle3=import_react121.useCallback((by)=>{let states=preview2?.states,cur=preview2?.state;if(!states?.length||!cur)return;let at=Math.max(0,states.indexOf(cur));setPreviewState(states[(at+by+states.length)%states.length])},[preview2]),removeSelected=import_react121.useCallback(async(idx)=>{let row4=state3.rows[idx??sel],svc=state3.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 active2=row4.active;if(!await openConfirm(dialog,{title:`Remove '${name}'?`,danger:!0,body:active2?`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:active2});if(out)return toast.show({variant:"warning",message:out.message});toast.show({variant:"info",message:`Removed '${name}'`}),refreshMarket(svc,query2)},[dialog,query2,refreshMarket,sel,state3.rows,state3.service,toast]),delistSelected=import_react121.useCallback(async(row4,svc)=>{let own;try{own=await svc.delistInfo(row4.entry.identityKey)}catch(err){toast.show({variant:"error",title:"Delist check failed",message:err instanceof Error?err.message:String(err),duration:6000});return}if(!own.eligible){toast.show({variant:"warning",title:"Delist unavailable",message:own.reason??"Only the original GitHub submitter can delist this eikon",duration:6000});return}if(!await openConfirm(dialog,{title:`Delist '${row4.entry.name}'?`,danger:!0,body:`This will open a GitHub delist request in liftaris/eikon for '${row4.entry.name}'. The registry will remove it automatically after authorship is verified.`,yes:"delist",no:"cancel"}))return;try{let out=await svc.delist(row4.entry.identityKey);toast.show({variant:"success",title:"Delist requested",message:`${row4.entry.name} will be removed automatically once GitHub verifies the request. ${out.url}`,duration:8000})}catch(err){toast.show({variant:"error",title:"Delist failed",message:err instanceof Error?err.message:String(err),duration:6000})}},[dialog,toast]),primary=import_react121.useCallback((idx)=>{let row4=state3.rows[idx??sel],svc=state3.service;if(!row4||!svc||actingRef.current||acting)return;(async()=>{actingRef.current=!0,setActing(!0);try{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,query2);return}if(pick2==="delete")return removeSelected(idx);if(pick2==="delist")return delistSelected(row4,svc);setInstalling(!0);try{if(!(row4.installState==="active-name-conflict"?await openConfirm(dialog,{title:`Replace active '${row4.entry.name}'?`,danger:!0,body:`Installing this catalog 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,query2)}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,query2)}finally{setInstalling(!1)}}finally{actingRef.current=!1,setActing(!1)}})()},[dialog,state3.rows,state3.service,sel,acting,toast,refreshMarket,query2,removeSelected,delistSelected]);useKeyboard((key4)=>{if(!props.focused||dialog.open())return;if(searching){if(key4.name==="escape"||key4.name==="esc"){setSearching(!1);return}if(key4.name==="backspace"){setQuery((q5)=>q5.slice(0,-1)),setSel(0);return}let seq=typeof key4.sequence==="string"?key4.sequence:"",ch=key4.raw&&key4.raw.length===1?key4.raw:seq.length===1?seq:key4.name.length===1&&!key4.ctrl&&!key4.meta?key4.name:"";if(ch>=" "){setQuery((q5)=>q5+ch),setSel(0);return}return}let plain=!key4.shift&&!key4.ctrl&&!key4.meta;if(key4.name==="tab")return setPane((p)=>p==="grid"?"detail":"grid");if(pane==="detail"){if(key4.name==="escape"||plain&&key4.name==="left"){setPane("grid");return}if(plain&&key4.name==="right"){cycle3(1);return}if(keys.match("list.activate",key4)){primary();return}if(keys.match("list.toggle",key4)){cycle3(1);return}if(keys.match("list.search",key4)){setPane("grid"),setSearching(!0);return}if(keys.match("list.refresh",key4)){loadMarket(query2);return}return}let move=(by)=>setSel((p)=>{let n=Math.max(0,Math.min(state3.rows.length-1,p+by));return follow.opts.scrollTo?.(n),listFollow.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(-1);return}if(plain&&key4.name==="down"){move(1);return}if(handleListKey(keys,key4,{count:state3.rows.length,setSel,page:listFollow.opts.page,scrollTo:(n)=>{follow.opts.scrollTo?.(n),listFollow.opts.scrollTo?.(n)},onActivate:primary,onToggle:()=>cycle3(1),onSearch:()=>setSearching(!0),onRefresh:()=>loadMarket(query2),onDelete:()=>void removeSelected()}))return}),count("market:render");let titles=state3.rows.map((r)=>({key:r.entry.identityKey,name:r.entry.name,active:r.active})),cards=state3.rows.map((r)=>({key:r.entry.identityKey,name:r.entry.name,active:r.active,author:r.entry.author,status:stateLabel(r,!0),lines:posterLines(r.entry.poster)})),listW=titleWidth(`Catalog (${state3.rows.length})`,titles),showGrid=dims.width-listW-DETAIL>=EIKON_CARD;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,minHeight:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,minWidth:0,minHeight:0,children:[$jsx(EikonTitleList,{title:`Catalog (${state3.rows.length})${searching?` Search: ${query2}`:""}`,rows:titles,sel,focus:props.focused&&pane==="grid",follow:listFollow,width:listW,onSel:setSel,onUse:primary}),showGrid?$jsx(TabShell,{title:"Posters",grow:1,children:state3.error?$jsx("box",{padding:1,children:$jsxs("text",{fg:theme.error,wrapMode:"word",children:["Catalog unavailable: ",state3.error]})}):loading&&state3.rows.length===0?$jsx("box",{padding:1,children:$jsx("text",{fg:theme.textMuted,children:"Loading shared eikons\u2026"})}):$jsx(EikonCardGrid,{rows:cards,sel,follow,empty:$jsx("text",{fg:theme.textMuted,children:"No catalog eikons match. Press / to change search."}),onSel:setSel,onUse:primary})}):null,$jsx("box",{width:DETAIL,flexShrink:0,minHeight:0,children:$jsx(TabShell,{title:selected?`Details \u2014 ${selected.entry.name}`:"Details",focus:props.focused&&pane==="detail",grow:1,children:$jsx(MarketplaceDetail,{row:selected,loading,installing,onUse:()=>primary(),onFocus:()=>setPane("detail"),onState:setPreviewState,preview:preview2})})})]}),$jsx(HintBar,{pairs:[["Tab",pane==="grid"?"details":"catalog"],[keys.print("list.activate"),"actions"],[pane==="detail"?"\u2192/Space":"\u2191\u2193\u2190\u2192/Pg",pane==="detail"?"state":"select"],[keys.print("list.search"),searching?"typing search":"search"],[keys.print("list.refresh"),"reload"],["d","delete in modal"],["Space","preview"]]})]})}),posterLines=(poster2)=>{let lines3=poster2?poster2.split(`
4174
4174
  `):[];return lines3.length?lines3:["(no poster)"]},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 catalog entry selected."})});let previewState=props.preview?.state??"idle",states=props.preview?.states??[previewState];return $jsxs("box",{flexDirection:"column",padding:1,onMouseDown:props.onFocus,children:[props.preview?$jsx("box",{alignItems:"center",justifyContent:"center",width:48,height:24,flexShrink:0,overflow:"hidden",children:$jsx(AnimatedAvatar,{state:props.preview.state,eikon:props.preview.eikon},`${r.entry.identityKey}:${props.preview.state}`)}):null,$jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{fg:r.active?theme.accent:theme.text,wrapMode:"none",children:$jsxs("strong",{children:[r.active?"\u25CF ":"",r.entry.name]})})}),$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{fg:theme.textMuted,wrapMode:"none",children:["by ",r.entry.author??"unknown"]})}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:r.entry.description??"No description."})}),$jsx("box",{flexDirection:"row",flexWrap:"wrap",flexShrink:0,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})]})},DetailRow2=(props)=>{let theme=useTheme().theme;if(props.block)return $jsx("box",{flexDirection:"column",minHeight:props.label==="Status"?2:1,children:$jsxs("text",{fg:theme.textMuted,wrapMode:"word",children:[props.label,": ",props.value]})});return $jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{fg:theme.textMuted,wrapMode:"none",children:[props.label,": ",props.value]})})},shortDigest=(value2)=>{if(!value2)return;let[algo,hash3]=value2.includes(":")?value2.split(":",2):[void 0,value2];if(!hash3||hash3.length<=16)return value2;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},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 base3=row4.installState==="active-name-conflict"?"active name conflict":row4.active?"active":row4.installed?"installed":"not installed";if(short2)return base3;let src3=row4.sourcePresent?" \xB7 source present":row4.sourceDownloadable?" \xB7 source downloadable":row4.sourceAvailable?" \xB7 source available":"",rm2=row4.removable?" \xB7 removable":row4.installed?" \xB7 not removable":"";return`${base3}${src3}${rm2}`};var EikonGroup=import_react123.memo((props)=>{let labels=SUB_TABS[EIKON_TAB],[target2,setTarget]=import_react123.useState(void 0);import_react123.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]);let edit2=import_react123.useCallback((name)=>{setTarget(name),props.setSub(2)},[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(EikonMarketplace,{focused:!!props.focused&&props.sub===1})}),$jsx(Pane4,{visible:props.sub===2,children:$jsx(EikonStudio,{focused:!!props.focused&&props.sub===2,name:target2})})]})]})}),Pane4=({visible:visible2,children:children2})=>visible2?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react124=__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"],BR=["\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]+BR[i]);return{lines:out,inner}}var exports_tips={};__export(exports_tips,{tips:()=>exports_tips,splitTip:()=>splitTip,resetTips:()=>resetTips,randomTip:()=>randomTip,parseTips:()=>parseTips,loadTips:()=>loadTips});import{readFileSync as readFileSync19}from"fs";import{join as join22}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 parseTips(src3){let body=src3.split(/^TIPS\s*=\s*\[/m)[1]?.split(/^\]/m)[0]??"",tips=[];for(let line4 of body.split(`
@@ -4198,14 +4198,14 @@ ${r.skipped.slice(0,8).join(", ")}${r.skipped.length>8?", \u2026":""}`:""}`,yes:
4198
4198
  `;writeSync(1,banner)}process.exit(0)}var exports_stash={};__export(exports_stash,{push:()=>push2,pop:()=>pop2,drop:()=>drop,all:()=>all,Stash:()=>exports_stash});import{join as join26}from"path";import{existsSync as existsSync31,readFileSync as readFileSync22,writeFileSync as writeFileSync9,mkdirSync as mkdirSync7}from"fs";var MAX=50,file2=()=>join26(configDir(),"stash.jsonl");function load5(){if(!existsSync31(file2()))return[];return readFileSync22(file2(),"utf-8").split(`
4199
4199
  `).filter(Boolean).map((l)=>JSON.parse(l)).slice(-MAX)}function save3(list3){mkdirSync7(configDir(),{recursive:!0}),writeFileSync9(file2(),list3.map((e)=>JSON.stringify(e)).join(`
4200
4200
  `)+`
4201
- `,"utf-8")}function push2(text5){let list3=load5(),at=Math.max(Date.now(),(list3[list3.length-1]?.at??0)+1);if(list3.push({text:text5,at}),list3.length>MAX)list3.shift();return save3(list3),list3.length}function pop2(){let list3=load5(),e=list3.pop();if(!e)return null;return save3(list3),e}function all(){return load5().reverse()}function drop(at){save3(load5().filter((e)=>e.at!==at))}var import_react139=__toESM(require_react_production(),1);var ctx=import_react139.createContext(null),BackgroundProvider=({children:children2})=>{let[jobs,setJobs]=import_react139.useState(()=>new Map),register2=import_react139.useCallback((id,title="")=>{if(!id)return;setJobs((prev)=>{if(prev.get(id)===title)return prev;let next3=new Map(prev);return next3.set(id,title),next3})},[]),unregister=import_react139.useCallback((id)=>{setJobs((prev)=>{if(!prev.has(id))return prev;let next3=new Map(prev);return next3.delete(id),next3})},[]),label2=import_react139.useCallback((id)=>jobs.get(id)?.trim()||void 0,[jobs]),ids3=import_react139.useMemo(()=>Array.from(jobs.keys()),[jobs]),value2=import_react139.useMemo(()=>({count:ids3.length,ids:ids3,register:register2,unregister,label:label2}),[ids3,register2,unregister,label2]);return $jsx(ctx.Provider,{value:value2,children:children2})},useBackground=makeUse(ctx,"useBackground");var initialTurn={messages:[],streaming:!1,hasContent:!1,toolActive:!1};function turnReducer(state3,a){switch(a.kind){case"reset":return initialTurn;case"load":return{...initialTurn,messages:a.messages};case"load.live":return{...initialTurn,messages:a.messages,streaming:a.streaming,hasContent:a.streaming&&Boolean(joinText(a.messages.at(-1)?.parts??[]))};case"push":return{...state3,messages:[...state3.messages,a.message]};case"user":return{...state3,messages:[...state3.messages,userMessage(a.text)]};case"system":return{...state3,messages:[...state3.messages,systemMessage(sanitize(a.text))]};case"background":return{...state3,messages:[...state3.messages,backgroundMessage(a.id,a.title,a.text)]};case"message.start":return{...state3,streaming:!0,hasContent:!1,toolActive:!1};case"message.delta":{let chunk=sanitize(a.chunk);if(!chunk)return state3;return{...state3,hasContent:!0,toolActive:!1,messages:appendText(state3.messages,chunk)}}case"message.complete":return{...state3,streaming:!1,hasContent:!1,toolActive:!1,messages:finalize(state3.messages,a.text!=null?sanitize(a.text):void 0,a.usage)};case"reference":{let text5=sanitize(a.text);if(!text5)return state3;return{...state3,hasContent:!0,toolActive:!1,messages:appendPart(state3.messages,{type:"text",key:pid(),content:text5,streaming:!1},!0)}}case"tool.start":{let preview2=sanitize(a.preview),args=sanitize(a.args),raw2=args||preview2,json2=raw2&&/^\s*\{/.test(raw2),part={type:"tool",id:a.id,name:a.name,args:json2?raw2:"",status:"running",startedAt:Date.now(),preview:preview2||void 0,verboseArgs:args||void 0};return{...state3,toolActive:!0,hasContent:!1,messages:appendPart(state3.messages,part,!0)}}case"tool.progress":return{...state3,messages:updateRunningTool(state3.messages,a.name,(p)=>({...p,preview:sanitize(a.preview)||p.preview}))};case"tool.generating":return{...state3,messages:updateRunningTool(state3.messages,a.name,(p)=>({...p,preview:p.preview??"generating\u2026"}))};case"tool.complete":{let summary2=sanitize(a.summary),error=sanitize(a.error),diff=sanitize(a.inline_diff),result=sanitize(a.result);return{...state3,toolActive:!1,messages:updateToolById(state3.messages,a.id,(p)=>({...p,status:a.error?"error":"done",duration:a.duration??(p.startedAt?Date.now()-p.startedAt:void 0),preview:summary2||diff||p.preview,result:error||summary2||void 0,verboseResult:result||void 0,diff:diff||void 0}))}}case"thinking":return{...state3,messages:upsertThinking(state3.messages,sanitize(a.text),a.final,a.verbose)};case"subagent":return{...state3,messages:renderSubagent(state3.messages,a.event,a.payload)};case"prompt":{let part={type:"prompt",id:a.id,variant:a.req.variant,req:a.req};return{...state3,messages:appendPart(state3.messages,part,!0)}}case"prompt.answered":return{...state3,messages:updatePrompt(state3.messages,a.id,(p)=>({...p,answered:{label:a.label,ok:a.ok,at:Date.now(),question:promptQuestion(p.req)}}))};case"error":{let msg=systemMessage(`Error: ${sanitize(a.text)}`);if(a.fatal===!1)return{...state3,messages:[...state3.messages,msg]};return{...state3,streaming:!1,hasContent:!1,toolActive:!1,messages:[...state3.messages,msg]}}case"interrupt.notice":{let clean6=sanitize(a.text),last4=state3.messages[state3.messages.length-1];if(last4?.role==="system"&&last4.parts[0]?.type==="text"&&last4.parts[0].content.includes(clean6))return state3;return{...state3,messages:[...state3.messages,systemMessage(clean6)]}}}}function userMessage(text5){return{id:mid(),role:"user",parts:[{type:"text",content:text5,streaming:!1}],timestamp:Date.now()/1000}}function systemMessage(text5){return{id:mid(),role:"system",parts:[{type:"text",content:text5,streaming:!1}],timestamp:Date.now()/1000}}function clip2(text5,max){return text5.length<=max?text5:text5.slice(0,max-1)+"\u2026"}function label2(text5,max){return clip2(sanitize(text5).replace(/\s+/g," ").trim(),max)}function backgroundMessage(id,title,text5){let tid=label2(id,32)||"?",name=label2(title,80);return{id:mid(),role:"assistant",speaker:`[bg ${tid}]${name?` ${name}`:""}`,parts:[{type:"text",content:sanitize(text5),streaming:!1}],timestamp:Date.now()/1000}}function flatten3(text5){if(typeof text5==="string")return text5;if(!Array.isArray(text5))return"";let out=[];for(let p of text5)if(p&&typeof p==="object"&&"type"in p&&p.type==="text"&&"text"in p&&typeof p.text==="string")out.push(p.text);return out.join(`
4201
+ `,"utf-8")}function push2(text5){let list3=load5(),at=Math.max(Date.now(),(list3[list3.length-1]?.at??0)+1);if(list3.push({text:text5,at}),list3.length>MAX)list3.shift();return save3(list3),list3.length}function pop2(){let list3=load5(),e=list3.pop();if(!e)return null;return save3(list3),e}function all(){return load5().reverse()}function drop(at){save3(load5().filter((e)=>e.at!==at))}var import_react139=__toESM(require_react_production(),1);var ctx=import_react139.createContext(null),BackgroundProvider=({children:children2})=>{let[jobs,setJobs]=import_react139.useState(()=>new Map),register2=import_react139.useCallback((id,title="")=>{if(!id)return;setJobs((prev)=>{if(prev.get(id)===title)return prev;let next3=new Map(prev);return next3.set(id,title),next3})},[]),unregister=import_react139.useCallback((id)=>{setJobs((prev)=>{if(!prev.has(id))return prev;let next3=new Map(prev);return next3.delete(id),next3})},[]),label2=import_react139.useCallback((id)=>jobs.get(id)?.trim()||void 0,[jobs]),ids3=import_react139.useMemo(()=>Array.from(jobs.keys()),[jobs]),value2=import_react139.useMemo(()=>({count:ids3.length,ids:ids3,register:register2,unregister,label:label2}),[ids3,register2,unregister,label2]);return $jsx(ctx.Provider,{value:value2,children:children2})},useBackground=makeUse(ctx,"useBackground");var initialTurn={messages:[],streaming:!1,hasContent:!1,toolActive:!1};function turnReducer(state3,a){switch(a.kind){case"reset":return initialTurn;case"load":return{...initialTurn,messages:a.messages};case"load.live":return{...initialTurn,messages:a.messages,streaming:a.streaming,hasContent:a.streaming&&Boolean(joinText(a.messages.at(-1)?.parts??[]))};case"push":return{...state3,messages:[...state3.messages,a.message]};case"user":return{...state3,messages:[...state3.messages,userMessage(a.text)]};case"system":return{...state3,messages:[...state3.messages,systemMessage(sanitize(a.text))]};case"background":return{...state3,messages:[...state3.messages,backgroundMessage(a.id,a.title,a.text)]};case"message.start":return{...state3,streaming:!0,hasContent:!1,toolActive:!1};case"message.delta":{let chunk=sanitize(a.chunk);if(!chunk)return state3;return{...state3,hasContent:!0,toolActive:!1,messages:appendText(state3.messages,chunk)}}case"message.complete":return{...state3,streaming:!1,hasContent:!1,toolActive:!1,messages:finalize(state3.messages,a.text!=null?sanitize(a.text):void 0,a.usage)};case"reference":{let text5=sanitize(a.text);if(!text5)return state3;return{...state3,hasContent:!0,toolActive:!1,messages:appendPart(state3.messages,{type:"text",key:pid(),content:text5,streaming:!1},!0)}}case"tool.start":{let preview2=sanitize(a.preview),args=sanitize(a.args),raw2=args||preview2,json2=raw2&&/^\s*\{/.test(raw2),part={type:"tool",id:a.id,name:a.name,args:json2?raw2:"",status:"running",startedAt:Date.now(),preview:preview2||void 0,verboseArgs:args||void 0};return{...state3,toolActive:!0,hasContent:!1,messages:appendPart(state3.messages,part,!0)}}case"tool.progress":return{...state3,messages:updateRunningTool(state3.messages,a.name,(p)=>({...p,preview:sanitize(a.preview)||p.preview}))};case"tool.generating":return{...state3,messages:updateRunningTool(state3.messages,a.name,(p)=>({...p,preview:p.preview??"generating\u2026"}))};case"tool.complete":{let summary2=sanitize(a.summary),error=sanitize(a.error),diff=sanitize(a.inline_diff),result=sanitize(a.result);return{...state3,toolActive:!1,messages:updateToolById(state3.messages,a.id,(p)=>({...p,status:a.error?"error":"done",duration:a.duration??(p.startedAt?Date.now()-p.startedAt:void 0),preview:summary2||diff||p.preview,result:error||summary2||void 0,verboseResult:result||void 0,diff:diff||void 0}))}}case"thinking":return{...state3,messages:upsertThinking(state3.messages,sanitize(a.text),a.final,a.verbose)};case"subagent":return{...state3,messages:renderSubagent(state3.messages,a.event,a.payload)};case"prompt":{let part={type:"prompt",id:a.id,variant:a.req.variant,req:a.req};return{...state3,messages:appendPart(state3.messages,part,!0)}}case"prompt.answered":return{...state3,messages:updatePrompt(state3.messages,a.id,(p)=>({...p,answered:{label:a.label,ok:a.ok,at:Date.now(),question:promptQuestion(p.req)}}))};case"error":{let msg=systemMessage(`Error: ${sanitize(a.text)}`);if(a.fatal===!1)return{...state3,messages:[...state3.messages,msg]};return{...state3,streaming:!1,hasContent:!1,toolActive:!1,messages:[...state3.messages,msg]}}case"interrupt.notice":{let clean7=sanitize(a.text),last4=state3.messages[state3.messages.length-1];if(last4?.role==="system"&&last4.parts[0]?.type==="text"&&last4.parts[0].content.includes(clean7))return state3;return{...state3,messages:[...state3.messages,systemMessage(clean7)]}}}}function userMessage(text5){return{id:mid(),role:"user",parts:[{type:"text",content:text5,streaming:!1}],timestamp:Date.now()/1000}}function systemMessage(text5){return{id:mid(),role:"system",parts:[{type:"text",content:text5,streaming:!1}],timestamp:Date.now()/1000}}function clip2(text5,max){return text5.length<=max?text5:text5.slice(0,max-1)+"\u2026"}function label2(text5,max){return clip2(sanitize(text5).replace(/\s+/g," ").trim(),max)}function backgroundMessage(id,title,text5){let tid=label2(id,32)||"?",name=label2(title,80);return{id:mid(),role:"assistant",speaker:`[bg ${tid}]${name?` ${name}`:""}`,parts:[{type:"text",content:sanitize(text5),streaming:!1}],timestamp:Date.now()/1000}}function flatten3(text5){if(typeof text5==="string")return text5;if(!Array.isArray(text5))return"";let out=[];for(let p of text5)if(p&&typeof p==="object"&&"type"in p&&p.type==="text"&&"text"in p&&typeof p.text==="string")out.push(p.text);return out.join(`
4202
4202
  `)}function transcriptToMessages(rows3){return rows3.filter((r)=>r.role==="user"||r.role==="assistant").map((r)=>({role:r.role,content:sanitize(flatten3(r.text))})).filter((r)=>r.content).map((r)=>({id:mid(),role:r.role,parts:[{type:"text",content:r.content,streaming:!1}],timestamp:Date.now()/1000}))}function assistant(parts2){return{id:mid(),role:"assistant",parts:parts2,timestamp:Date.now()/1000}}function withLastAssistant(messages,fn,otherwise){let last4=messages[messages.length-1];if(last4?.role==="assistant")return[...messages.slice(0,-1),fn(last4)];return[...messages,otherwise()]}function seal(parts2){let last4=parts2[parts2.length-1];if(last4?.type==="text"&&last4.streaming)return[...parts2.slice(0,-1),{...last4,streaming:!1}];return parts2}function appendText(messages,chunk){return withLastAssistant(messages,(m2)=>{let last4=m2.parts[m2.parts.length-1];if(last4?.type==="text"&&last4.streaming){let part={...last4,content:last4.content+chunk};return{...m2,parts:[...m2.parts.slice(0,-1),part]}}return{...m2,parts:[...m2.parts,{type:"text",key:pid(),content:chunk,streaming:!0}]}},()=>assistant([{type:"text",key:pid(),content:chunk,streaming:!0}]))}function appendPart(messages,part,close2){return withLastAssistant(messages,(m2)=>({...m2,parts:[...close2?seal(m2.parts):m2.parts,part]}),()=>assistant([part]))}function finalize(messages,final,usage){let last4=messages[messages.length-1];if(last4?.role==="assistant"){let tail=last4.parts[last4.parts.length-1],dup=final&&last4.parts.some((p)=>p.type==="text"&&sameText(p.content,final)),text5=tail?.type==="text"&&final&&sameText(tail.content,final)?tail.content:final,parts2=tail?.type==="text"&&tail.streaming?[...last4.parts.slice(0,-1),{...tail,content:text5||tail.content,streaming:!1}]:final&&!dup&&!sameText(joinText(last4.parts),final)?[...last4.parts,{type:"text",content:final,streaming:!1}]:seal(last4.parts);return expirePrompts([...messages.slice(0,-1),{...last4,parts:parts2,usage}])}let next3=final?[...messages,{...assistant([{type:"text",content:final,streaming:!1}]),usage}]:messages;return expirePrompts(next3)}function expirePrompts(messages){let at=Date.now();return messages.map((m2)=>m2.role==="assistant"?{...m2,parts:m2.parts.map((p)=>p.type==="prompt"&&!p.answered?{...p,answered:{label:"Timed out",ok:!1,at,question:promptQuestion(p.req)}}:p)}:m2)}function joinText(parts2){return parts2.filter((p)=>p.type==="text").map((p)=>p.content).join("")}function sameText(a,b2){return a.trim()===b2.trim()}function updateRunningTool(messages,name,fn){let last4=messages[messages.length-1];if(!last4||last4.role!=="assistant")return messages;for(let i=last4.parts.length-1;i>=0;i--){let p=last4.parts[i];if(p.type!=="tool"||p.status!=="running")continue;if(name&&p.name!==name)continue;let parts2=[...last4.parts];return parts2[i]=fn(p),[...messages.slice(0,-1),{...last4,parts:parts2}]}return messages}function updateToolById(messages,id,fn){let last4=messages[messages.length-1];if(!last4||last4.role!=="assistant")return messages;let parts2=last4.parts.map((p)=>p.type==="tool"&&p.id===id?fn(p):p);return[...messages.slice(0,-1),{...last4,parts:parts2}]}function updatePrompt(messages,id,fn){return messages.map((m2)=>{if(m2.role!=="assistant")return m2;if(!m2.parts.some((p)=>p.type==="prompt"&&p.id===id))return m2;return{...m2,parts:m2.parts.map((p)=>p.type==="prompt"&&p.id===id?fn(p):p)}})}function promptQuestion(req){if(req.variant==="clarify")return req.question;if(req.variant==="approval")return req.description||"Shell command";if(req.variant==="sudo")return"Sudo required";return req.env_var?`Secret: ${req.env_var}`:"Secret required"}function upsertThinking(messages,text5,final,verbose2){return withLastAssistant(messages,(m2)=>{let idx=m2.parts.findIndex((p)=>p.type==="thinking");if(idx>=0){let prev=m2.parts[idx],content=final?prev.content.trim()||text5:prev.content+text5,parts2=[...m2.parts];return parts2[idx]={...prev,content,streaming:!final,verbose:prev.verbose||verbose2||void 0},{...m2,parts:parts2}}return{...m2,parts:[{type:"thinking",key:pid(),content:text5,streaming:!final,verbose:verbose2},...m2.parts]}},()=>assistant([{type:"thinking",key:pid(),content:text5,streaming:!final,verbose:verbose2}]))}function renderSubagent(messages,event,p){let id=p.subagent_id?`sub-${p.subagent_id}`:`sub-${p.task_index}`;if(event==="start"){let goal=sanitize(p.goal),part={type:"tool",id,name:"delegate_task",args:"",status:"running",startedAt:Date.now(),preview:goal||void 0,goal:goal||void 0,depth:p.depth??0,trail:[]};return appendPart(messages,part,!0)}if(event==="tool"&&p.tool_name){let tname=sanitize(p.tool_name),tprev=sanitize(p.tool_preview);return updateToolById(messages,id,(t2)=>({...t2,trail:[...t2.trail??[],{name:tname,preview:tprev||void 0}],preview:tprev?`${tname}: ${tprev}`:tname}))}if(event==="complete"){let tokens3=(p.input_tokens??0)+(p.output_tokens??0),extra=tokens3?` \xB7 ${(tokens3/1000).toFixed(1)}k tok`:"",summary2=sanitize(p.summary);return updateToolById(messages,id,(t2)=>({...t2,status:p.status==="failed"||p.status==="error"||p.status==="timeout"||p.status==="interrupted"?"error":"done",duration:p.duration_seconds?p.duration_seconds*1000:t2.startedAt?Date.now()-t2.startedAt:void 0,result:summary2?summary2+extra:void 0,preview:t2.goal??t2.preview}))}return updateToolById(messages,id,(t2)=>({...t2,preview:sanitize(p.text)||t2.preview}))}var AGGRESSIVE="--aggressive is not supported; use '/compress here [N]' to keep only recent exchanges, or /undo to drop turns.";function flags(arg){let kept=[],preview2={on:!1,aggressive:!1};for(let tok of arg.split(/\s+/).filter(Boolean)){let low=tok.toLowerCase();if(low==="--preview"||low==="--dry-run"||low==="--dryrun")preview2.on=!0;else if(low==="--aggressive")preview2.aggressive=!0;else kept.push(tok)}return{arg:kept.join(" "),preview:preview2.on,aggressive:preview2.aggressive}}function partial(arg){let text5=arg.trim();if(!text5)return{on:!1,keep:2,focus:""};let bits=(text5.toLowerCase().startsWith("up to here")?text5.slice(6).trim():text5).toLowerCase().split(/\s+/),keep=(v2)=>Math.min(Math.max(parseInt(v2??"",10)||2,1),100);if(bits[0]==="here")return{on:!0,keep:keep(bits[1]),focus:""};if((bits[0]==="--keep"||bits[0]==="-k")&&bits[1])return{on:!0,keep:keep(bits[1]),focus:""};if(bits[0]?.startsWith("--keep="))return{on:!0,keep:keep(bits[0].split("=",2)[1]),focus:""};return{on:!1,keep:2,focus:text5}}function compressPreview(arg,msgs){let f=flags(arg);if(f.aggressive&&!f.preview)return[AGGRESSIVE];if(!f.preview)return null;let p=partial(f.arg),at=p.on?[...msgs].reverse().reduce((acc2,m2,i)=>{if(acc2.length<p.keep&&m2.role==="user")return[...acc2,msgs.length-1-i];return acc2},[]).at(-1):void 0,head=at===void 0||at===0?msgs:msgs.slice(0,at),tail=at===void 0||at===0?[]:msgs.slice(at),lines3=["Preview \u2014 no changes made.",`Would compress ${head.length} of ${msgs.length} message(s) (~${Math.ceil(msgs.map(text2).join(`
4203
4203
 
4204
4204
  `).length/4).toLocaleString()} tokens currently in context).`];if(p.on&&tail.length)lines3.push(`Boundary: keeping the last ${p.keep} exchange(s) (${tail.length} message(s)) verbatim.`);else if(p.on)lines3.push("Boundary: 'here' split would keep everything \u2014 falling back to full compression.");if(p.focus)lines3.push(`Focus topic: "${p.focus}"`);if(lines3.push("Run the command again without --preview to apply."),f.aggressive)lines3.push(AGGRESSIVE);return lines3}function useSlash(c){let gw=useGateway(),dialog=useDialog(),toast=useToast(),themeCtx=useTheme(),cmd=useCommand(),renderer=useRenderer(),cfg2=useHome("config"),bg2=useBackground(),ctx2=import_react140.useRef(c);ctx2.current=c;let gate=import_react140.useRef(cfg2);gate.current=cfg2;let destructive=import_react140.useCallback((arg,opts,action)=>{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",bypass=!(gate.current?.approvals?.destructive_slash_confirm??!0)||process.env.HERMES_TUI_NO_CONFIRM==="1",persist2=a==="always",fire=()=>{if(persist2)Promise.resolve().then(() => (init_lane(),exports_lane)).then(({writeConfig:writeConfig2})=>writeConfig2(gw,[{key:"approvals.destructive_slash_confirm",to:!1}]).then((r)=>{if(r.failed.length){toast.show({variant:"warning",message:`couldn't persist: ${r.failed[0].err}`});return}home3.invalidate("config"),toast.show({variant:"success",message:`${opts.yes} \xB7 future runs silent`})}).catch((e)=>toast.show({variant:"error",message:e.message})));action()};if(skip||bypass)return fire();openConfirm(dialog,{title:opts.title,body:opts.body,yes:opts.yes,danger:!0}).then((ok)=>{if(ok)fire()})},[gw,dialog,toast]),pickEikon=import_react140.useCallback(()=>openEikonPicker(dialog,(n)=>set("eikon",n)),[dialog]),applyTitle=import_react140.useCallback((t2)=>{gw.request("session.title",{title:t2}).then((r)=>{ctx2.current.setTitle(r.title),ctx2.current.dispatch({kind:"system",text:`Title: ${r.title}`})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),runCompress=import_react140.useCallback(async(arg="")=>{let raw2=arg.trim(),pv=compressPreview(raw2,ctx2.current.turnRef.current.messages);if(pv){ctx2.current.dispatch({kind:"system",text:pv.join(`
4205
4205
  `)}),toast.show({variant:pv.length===1?"warning":"info",message:pv.length===1?"compress unsupported":"Preview \u2014 no changes made"});return}toast.show({variant:"info",message:"Compressing session\u2026"});let r=await ctx2.current.session.compress(raw2).catch((err)=>{return toast.show({variant:"error",message:err.message}),null});if(!r)return;if(r.info)ctx2.current.setInfo(r.info);let out=r.lines?.length?r.lines:r.message?[r.message]:[];if(r.status==="preview"||r.status==="unsupported"||out.length){if(out.length)ctx2.current.dispatch({kind:"system",text:out.join(`
4206
4206
  `)});toast.show({variant:r.status==="unsupported"?"warning":"info",message:r.status==="unsupported"?"compress unsupported":"Preview \u2014 no changes made"});return}if(ctx2.current.setUsage((u3)=>{let base3=r.usage??u3,max=r.usage?.context_max??u3?.context_max;if(typeof r.after_tokens!=="number"||typeof max!=="number")return base3;return{...base3??{input:0,output:0,total:0},context_used:r.after_tokens,context_max:max}}),!r.summary)return;let s=r.summary;if(s.noop){toast.show({variant:"info",message:s.headline??`No changes \xB7 ~${r.before_tokens??0} tokens`});return}let lines3=[s.headline,s.token_line,s.note].filter(Boolean).join(`
4207
4207
  `);if(lines3)ctx2.current.dispatch({kind:"system",text:lines3});toast.show({variant:"success",message:s.headline??`Compressed ${r.before_messages??0}\u2192${r.after_messages??0} messages`})},[toast]),branch3=import_react140.useCallback((name)=>{let x2=ctx2.current;x2.session.branch(name?.trim()||void 0).then((id)=>id?void x2.activateSession(id):toast.show({variant:"error",message:"branch failed"})).catch((err)=>toast.show({variant:"error",message:err.message}))},[toast]),run=import_react140.useCallback((c2,arg="")=>{let x2=ctx2.current;if(c2.target==="local")switch(c2.name){case"clear":destructive(arg,{title:"Clear session?",body:"Discards the in-memory transcript. Your session on disk is unchanged; reload to restore.",yes:"clear"},()=>x2.dispatch({kind:"reset"}));return;case"new":destructive(arg,{title:"Start a new session?",body:"Ends the current session and starts a fresh one. The existing session remains saved and resumable.",yes:"new session"},()=>{x2.newSession()});return;case"theme":{let name=arg.trim();if(!name){openThemePicker(dialog,themeCtx);return}let mode2=name.toLowerCase();if(mode2==="dark"||mode2==="light"){themeCtx.setMode(mode2),x2.dispatch({kind:"system",text:`theme mode \u2192 ${mode2}`});return}if(!themeCtx.set(name)){toast.show({variant:"error",message:`unknown theme: ${name}`});return}x2.dispatch({kind:"system",text:`theme \u2192 ${name}`});return}case"help":dialog.replace($jsx(HelpDialog,{}));return;case"keys":openKeys(dialog);return;case"logs":openLogs(dialog);return;case"title":if(arg){applyTitle(arg);return}openTextPrompt(dialog,{title:"Session Title",initial:x2.title}).then((v2)=>{if(v2)applyTitle(v2)});return;case"rollback":openRollback(dialog,gw,toast);return;case"history":openHistory(dialog,gw);return;case"status":openStatus(dialog,x2.info,x2.sid);return;case"usage":openUsage(dialog,gw);return;case"profile":openProfile(dialog);return;case"journey":x2.goTo(TAB_SLASH.journey.tab,TAB_SLASH.journey.sub);return;case"chafa":if(!arg.trim()){toast.show({variant:"info",message:"usage: /chafa <path>"});return}openChafa(dialog,arg.trim());return;case"splash":x2.summoned.current=!0,x2.setSplash(!0);return;case"skin":{let name=arg.trim(),list3=skins();if(!name){x2.dispatch({kind:"system",text:`skin: ${x2.skin.skin?.name??"\u2014"}
4208
- ${list3.join(" ")}`});return}if(!list3.includes(name)){toast.show({variant:"error",message:`unknown skin: ${name}`});return}gw.request("config.set",{key:"skin",value:name}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});if(themeCtx.has(name)){themeCtx.set(name);let m2=mode(name);if(m2)themeCtx.setMode(m2)}set("eikon",void 0),set("eikonPath",void 0),x2.dispatch({kind:"system",text:`skin \u2192 ${name}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return}case"resume":if(arg){x2.switchSession(arg);return}x2.goTo(TAB_SLASH.sessions.tab,TAB_SLASH.sessions.sub);return;case"branch":branch3(arg);return;case"compress":runCompress(arg);return;case"undo":destructive(arg,{title:"Undo last turn?",body:"Pops the last user + assistant pair from the transcript. /redo in this session to restore.",yes:"undo"},()=>{let msgs=x2.turnRef.current.messages,at=msgs.map((m2)=>m2.role).lastIndexOf("user"),tail=at>=0?msgs.slice(at):[];x2.session.undo().then(()=>{if(tail.length)x2.undone.current.push(tail);return gw.request("session.history")}).then((r)=>x2.dispatch({kind:"load",messages:transcriptToMessages(r.messages??[])})).catch((err)=>toast.show({variant:"error",message:err.message}))});return;case"redo":{let head=x2.undone.current.pop()?.find((m2)=>m2.role==="user");if(!head){toast.show({variant:"info",message:"nothing to redo"});return}x2.sendRef.current(text2(head));return}case"retry":{let last4=[...x2.turnRef.current.messages].reverse().find((m2)=>m2.role==="user");if(!last4){toast.show({variant:"info",message:"nothing to retry"});return}x2.rewind(last4).then((ok)=>{if(ok)x2.sendRef.current(text2(last4))});return}case"model":if(!arg){openModelPicker(dialog,gw);return}if(arg.trim()==="--refresh"){openModelPicker(dialog,gw,{refresh:!0});return}gw.request("config.set",{key:"model",value:arg}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});x2.dispatch({kind:"system",text:`model \u2192 ${r.value??arg}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"yolo":gw.request("config.set",{key:"yolo"}).then((r)=>{if(r.info)x2.setInfo(r.info),x2.setUsage(r.info.usage);else x2.setInfo({...x2.info??{},yolo:!x2.info?.yolo});if(toast.show({variant:"success",message:`yolo ${r.value??"toggled"}`}),r.warning)toast.show({variant:"warning",message:r.warning})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"quit":quit(renderer,x2.resumeId||x2.sid,x2.title,gw);return;case"queue":if(!arg){x2.dispatch({kind:"system",text:`${x2.queueRef.current.length} queued`});return}x2.setQueue((q5)=>[...q5,arg]);return;case"stash":{let comp=x2.composer.current;if(arg==="pop"){let e=exports_stash.pop();if(!e)return toast.show({variant:"info",message:"stash empty"});comp?.set(e.text),x2.setFocusRegion("input");return}if(arg==="list"){let list3=exports_stash.all();if(list3.length===0)return toast.show({variant:"info",message:"stash empty"});dialog.replace($jsx(DialogSelect,{title:"Stashed prompts",filterable:list3.length>6,options:list3.map((e)=>({title:trunc5(e.text.replace(/\n/g," \u23CE "),50),value:String(e.at),hint:ago(e.at)})),onSelect:(o)=>{let e=list3.find((s)=>String(s.at)===o.value);if(e)exports_stash.drop(e.at),comp?.set(e.text),x2.setFocusRegion("input");dialog.clear()}}));return}let text5=arg||comp?.value().trim()||"";if(!text5)return toast.show({variant:"info",message:"nothing to stash \u2014 /stash list"});let n=exports_stash.push(text5);if(!arg)comp?.set("");toast.show({variant:"info",message:`stashed (${n}) \u2014 /stash pop to restore`});return}case"copy":{let all2=x2.turnRef.current.messages.filter((m3)=>m3.role==="assistant"),n=arg?Math.min(Math.max(1,parseInt(arg,10)||0),all2.length):all2.length,m2=all2[n-1];if(!m2){toast.show({variant:"info",message:"nothing to copy"});return}let body2=text2(m2);copyText(body2,toast,`copied ${body2.length} chars`);return}case"paste":x2.attachClipboard();return;case"image":if(!arg){toast.show({variant:"info",message:"usage: /image <path>"});return}gw.request("image.attach",{path:arg}).then((r)=>r.attached?x2.setAttachments((a)=>[...a,r]):toast.show({variant:"warning",message:r.message??"attach failed"})).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"background":if(!arg){x2.dispatch({kind:"system",text:"/background <prompt>"});return}gw.request("prompt.background",x2.sid?{session_id:x2.sid,text:arg}:{text:arg}).then((r)=>{if(!r.task_id){toast.show({variant:"error",message:"background start failed"});return}bg2.register(r.task_id,arg),x2.dispatch({kind:"system",text:`bg ${r.task_id} started`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"voice":x2.voiceToggle((arg||"status").toLowerCase(),x2.sid).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"mouse":{let want=arg==="on"?!0:arg==="off"?!1:!renderer.useMouse;renderer.useMouse=want,set("mouse",want),toast.show({variant:"info",message:`mouse ${want?"on":"off"}`});return}case"redraw":redraw(renderer);return;case"browser":{let parts2=arg.trim().split(/\s+/),sub3=parts2[0]?.toLowerCase()||"connect",url2=parts2[1];if(!["connect","disconnect","status"].includes(sub3)){toast.show({variant:"error",message:"usage: /browser [connect|disconnect|status] [url]"});return}let payload2={action:sub3};if(sub3==="connect"&&url2)payload2.url=url2;gw.request("browser.manage",payload2).then((r)=>{for(let m2 of r.messages??[])x2.dispatch({kind:"system",text:m2});if(r.connected)x2.dispatch({kind:"system",text:`Browser connected${r.url?` \u2192 ${r.url}`:""}`});else if(sub3==="disconnect")x2.dispatch({kind:"system",text:"Browser disconnected"});else if(sub3==="status")x2.dispatch({kind:"system",text:r.url??"No browser connected"})}).catch((e)=>toast.show({variant:"error",message:`browser: ${e.message}`}));return}case"setup":x2.dispatch({kind:"system",text:`/${c2.name} is an Ink-TUI command and has no effect in herm`});return;case"steer":{let fire=(text5)=>gw.request("session.steer",{text:text5}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(arg){fire(arg);return}openTextPrompt(dialog,{title:"Steer",label:"Note to inject on next tool result"}).then((text5)=>{if(text5)fire(text5)});return}case"reload-mcp":{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",fire=(always)=>gw.request("reload.mcp",{confirm:!0,always}).then((r)=>r.status==="confirm_required"?toast.show({variant:"warning",message:r.message??"reload requires confirmation"}):toast.show({variant:"success",message:always?"MCP servers reloaded \xB7 future /reload-mcp runs silently":"MCP servers reloaded"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(skip){fire(a==="always");return}openConfirm(dialog,{title:"Reload MCP servers?",body:"Rebuilds the MCP tool set. Invalidates the prompt cache, so the next message re-sends full input tokens.",yes:"reload",danger:!0}).then((ok)=>{if(ok)fire(!1)});return}case"reload":gw.request("reload.env",{}).then((r)=>{let n=Number(r.updated??0);toast.show({variant:"success",message:`Reloaded .env (${n} var${n===1?"":"s"} updated) \xB7 /new to apply`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"reload-skills":gw.request("skills.reload",{}).then((r)=>{x2.dispatch({kind:"system",text:r.output});let n=Number(r.result?.total??0);toast.show({variant:"success",message:`Skills reloaded (${n} available)`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"save":gw.request("session.save").then((r)=>toast.show({variant:"success",message:`Saved \u2192 ${r.file}`})).catch((e)=>toast.show({variant:"error",message:e.message}));return}if(c2.target!=="gateway"||!x2.capabilities.canDispatchGatewayCommand)return;let jump=TAB_SLASH[c2.name];if(jump!==void 0&&!arg){x2.goTo(jump.tab,jump.sub);return}let full=`/${c2.name}${arg?" "+arg:""}`;if(x2.turnRef.current.streaming){x2.setQueue((q5)=>[...q5,full]);return}x2.dispatch({kind:"user",text:full}),gw.request("slash.exec",{command:full}).then((res)=>{if(res?.warning)x2.dispatch({kind:"system",text:`\u26A0 ${res.warning}`});if(res?.output)x2.dispatch({kind:"system",text:res.output})}).catch(()=>{gw.request("command.dispatch",{name:c2.name,arg}).then((d2)=>{if(d2.notice)x2.dispatch({kind:"system",text:d2.notice});if(d2.type==="exec"||d2.type==="plugin")return x2.dispatch({kind:"system",text:d2.output||"(no output)"});if(d2.type==="alias"&&d2.target)return void x2.sendRef.current(`/${d2.target}${arg?" "+arg:""}`);if((d2.type==="skill"||d2.type==="send")&&d2.message){if(d2.type==="skill")x2.dispatch({kind:"system",text:`\u26A1 loading skill: ${d2.name??c2.name}`});return void x2.sendRef.current(d2.message)}x2.dispatch({kind:"system",text:`/${c2.name}: unknown`})}).catch((e)=>x2.dispatch({kind:"system",text:`error: ${e.message}`}))})},[gw,dialog,toast,themeCtx,renderer,destructive,applyTitle,runCompress,branch3]);return import_react140.useEffect(()=>cmd.register([{title:"Help",value:"help",action:"help.open",category:"General",onSelect:()=>dialog.replace($jsx(HelpDialog,{}))},{title:"Keybindings",value:"keys",description:"View & rebind shortcuts",category:"General",onSelect:()=>openKeys(dialog)},{title:"Gateway Logs",value:"logs",description:"Show gateway stderr",category:"General",onSelect:()=>openLogs(dialog)},{title:"Switch Theme",value:"theme",action:"theme.pick",category:"General",onSelect:()=>openThemePicker(dialog,themeCtx)},{title:"Switch Model",value:"model",action:"model.pick",category:"General",onSelect:()=>openModelPicker(dialog,gw)},{title:"Pick Avatar",value:"eikon",description:"Choose sidebar .eikon avatar",category:"General",onSelect:()=>pickEikon()},{title:"Rollback",value:"rollback",description:"Browse & restore checkpoints",category:"Session",onSelect:()=>openRollback(dialog,gw,toast)},{title:"History",value:"history",action:"session.timeline",category:"Session",onSelect:()=>openHistory(dialog,gw)},{title:"Status",value:"status",action:"status.open",category:"Info",onSelect:()=>openStatus(dialog,ctx2.current.info,ctx2.current.sid)},{title:"Usage",value:"usage",description:"Tokens \xB7 context \xB7 cost",category:"Info",onSelect:()=>openUsage(dialog,gw)},{title:"Profile",value:"profile",description:"Active profile details",category:"Info",onSelect:()=>openProfile(dialog)},{title:"New Session",value:"new-session",action:"session.new",category:"Session",onSelect:()=>destructive("",{title:"Start a new session?",body:"Ends the current session and starts a fresh one. The existing session remains saved and resumable.",yes:"new session"},()=>{ctx2.current.newSession()})},{title:"Compress Session",value:"compress",action:"session.compress",category:"Session",onSelect:()=>runCompress()},{title:"Undo Last Turn",value:"undo",description:"Pop last user+assistant pair",category:"Session",onSelect:()=>run({name:"undo",target:"local"})},{title:"Redo",value:"redo",action:"session.redo",category:"Session",onSelect:()=>run({name:"redo",target:"local"})},{title:"Branch Session",value:"branch",description:"Fork the current conversation",category:"Session",onSelect:()=>branch3()}]),[cmd,dialog,themeCtx,gw,toast,destructive,pickEikon,runCompress,branch3,run]),run}var import_react142=__toESM(require_react_production(),1);init_perf();function variant(level2){switch(level2){case"error":return"error";case"warning":case"warn":return"warning";case"success":return"success";default:return"info"}}function duration2(p){if(p.kind==="sticky")return null;if(typeof p.ttl_ms==="number")return p.ttl_ms;if(typeof p.duration_ms==="number")return p.duration_ms;return}function showNotification(toast,p){let text5=String(p?.text??"").trim();if(!text5)return;toast.show({key:p?.key,variant:variant(p?.level),message:text5,duration:duration2(p??{text:text5})})}function clearNotification(toast,p){let key5=String(p?.key??"").trim();if(!key5)return;toast.clear(key5)}function count3(o){return o?Object.values(o).reduce((n,v2)=>n+v2.length,0):0}function reference(label3,text5,index4,count4){let head=index4&&count4?`\u25C7 Reference ${index4}/${count4} \u2014 ${label3}`:`\u25C7 Reference \u2014 ${label3}`,body2=text5.trim();return body2?`${head}
4208
+ ${list3.join(" ")}`});return}if(!list3.includes(name)){toast.show({variant:"error",message:`unknown skin: ${name}`});return}gw.request("config.set",{key:"skin",value:name}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});if(themeCtx.has(name)){themeCtx.set(name);let m2=mode(name);if(m2)themeCtx.setMode(m2)}set("eikon",void 0),set("eikonPath",void 0),x2.dispatch({kind:"system",text:`skin \u2192 ${name}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return}case"resume":if(arg){x2.switchSession(arg);return}x2.goTo(TAB_SLASH.sessions.tab,TAB_SLASH.sessions.sub);return;case"branch":branch3(arg);return;case"compress":runCompress(arg);return;case"undo":destructive(arg,{title:"Undo last turn?",body:"Pops the last user + assistant pair from the transcript. /redo in this session to restore.",yes:"undo"},()=>{let msgs=x2.turnRef.current.messages,at=msgs.map((m2)=>m2.role).lastIndexOf("user"),tail=at>=0?msgs.slice(at):[];x2.session.undo().then(()=>{if(tail.length)x2.undone.current.push(tail);return gw.request("session.history")}).then((r)=>x2.dispatch({kind:"load",messages:transcriptToMessages(r.messages??[])})).catch((err)=>toast.show({variant:"error",message:err.message}))});return;case"redo":{let head=x2.undone.current.pop()?.find((m2)=>m2.role==="user");if(!head){toast.show({variant:"info",message:"nothing to redo"});return}x2.sendRef.current(text2(head));return}case"retry":{let last4=[...x2.turnRef.current.messages].reverse().find((m2)=>m2.role==="user");if(!last4){toast.show({variant:"info",message:"nothing to retry"});return}x2.rewind(last4).then((ok)=>{if(ok)x2.sendRef.current(text2(last4))});return}case"model":if(!arg){openModelPicker(dialog,gw);return}if(arg.trim()==="--refresh"){openModelPicker(dialog,gw,{refresh:!0});return}gw.request("config.set",{key:"model",value:arg}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});x2.dispatch({kind:"system",text:`model \u2192 ${r.value??arg}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"yolo":gw.request("config.set",{key:"yolo"}).then((r)=>{if(r.info)x2.setInfo(r.info),x2.setUsage(r.info.usage);else x2.setInfo({...x2.info??{},yolo:!x2.info?.yolo});if(toast.show({variant:"success",message:`yolo ${r.value??"toggled"}`}),r.warning)toast.show({variant:"warning",message:r.warning})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"quit":quit(renderer,x2.resumeId||x2.sid,x2.title,gw);return;case"queue":if(!arg){x2.dispatch({kind:"system",text:`${x2.queueRef.current.length} queued`});return}x2.setQueue((q5)=>[...q5,arg]);return;case"stash":{let comp=x2.composer.current;if(arg==="pop"){let e=exports_stash.pop();if(!e)return toast.show({variant:"info",message:"stash empty"});comp?.set(e.text),x2.setFocusRegion("input");return}if(arg==="list"){let list3=exports_stash.all();if(list3.length===0)return toast.show({variant:"info",message:"stash empty"});dialog.replace($jsx(DialogSelect,{title:"Stashed prompts",filterable:list3.length>6,options:list3.map((e)=>({title:trunc5(e.text.replace(/\n/g," \u23CE "),50),value:String(e.at),hint:ago(e.at)})),onSelect:(o)=>{let e=list3.find((s)=>String(s.at)===o.value);if(e)exports_stash.drop(e.at),comp?.set(e.text),x2.setFocusRegion("input");dialog.clear()}}));return}let text5=arg||comp?.value().trim()||"";if(!text5)return toast.show({variant:"info",message:"nothing to stash \u2014 /stash list"});let n=exports_stash.push(text5);if(!arg)comp?.set("");toast.show({variant:"info",message:`stashed (${n}) \u2014 /stash pop to restore`});return}case"copy":{let all2=x2.turnRef.current.messages.filter((m3)=>m3.role==="assistant"),n=arg?Math.min(Math.max(1,parseInt(arg,10)||0),all2.length):all2.length,m2=all2[n-1];if(!m2){toast.show({variant:"info",message:"nothing to copy"});return}let body2=text2(m2);copyText(body2,toast,`copied ${body2.length} chars`);return}case"paste":x2.attachClipboard();return;case"image":if(!arg){toast.show({variant:"info",message:"usage: /image <path>"});return}gw.request("image.attach",{path:arg}).then((r)=>r.attached?x2.setAttachments((a)=>[...a,r]):toast.show({variant:"warning",message:r.message??"attach failed"})).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"background":if(!arg){x2.dispatch({kind:"system",text:"/background <prompt>"});return}gw.request("prompt.background",x2.sid?{session_id:x2.sid,text:arg}:{text:arg}).then((r)=>{if(!r.task_id){toast.show({variant:"error",message:"background start failed"});return}bg2.register(r.task_id,arg),x2.dispatch({kind:"system",text:`bg ${r.task_id} started`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"voice":x2.voiceToggle((arg||"status").toLowerCase(),x2.sid).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"mouse":{let want=arg==="on"?!0:arg==="off"?!1:!renderer.useMouse;renderer.useMouse=want,set("mouse",want),toast.show({variant:"info",message:`mouse ${want?"on":"off"}`});return}case"redraw":redraw(renderer);return;case"browser":{let parts2=arg.trim().split(/\s+/),sub3=parts2[0]?.toLowerCase()||"connect",url2=parts2[1];if(!["connect","disconnect","status"].includes(sub3)){toast.show({variant:"error",message:"usage: /browser [connect|disconnect|status] [url]"});return}let payload3={action:sub3};if(sub3==="connect"&&url2)payload3.url=url2;gw.request("browser.manage",payload3).then((r)=>{for(let m2 of r.messages??[])x2.dispatch({kind:"system",text:m2});if(r.connected)x2.dispatch({kind:"system",text:`Browser connected${r.url?` \u2192 ${r.url}`:""}`});else if(sub3==="disconnect")x2.dispatch({kind:"system",text:"Browser disconnected"});else if(sub3==="status")x2.dispatch({kind:"system",text:r.url??"No browser connected"})}).catch((e)=>toast.show({variant:"error",message:`browser: ${e.message}`}));return}case"setup":x2.dispatch({kind:"system",text:`/${c2.name} is an Ink-TUI command and has no effect in herm`});return;case"steer":{let fire=(text5)=>gw.request("session.steer",{text:text5}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(arg){fire(arg);return}openTextPrompt(dialog,{title:"Steer",label:"Note to inject on next tool result"}).then((text5)=>{if(text5)fire(text5)});return}case"reload-mcp":{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",fire=(always)=>gw.request("reload.mcp",{confirm:!0,always}).then((r)=>r.status==="confirm_required"?toast.show({variant:"warning",message:r.message??"reload requires confirmation"}):toast.show({variant:"success",message:always?"MCP servers reloaded \xB7 future /reload-mcp runs silently":"MCP servers reloaded"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(skip){fire(a==="always");return}openConfirm(dialog,{title:"Reload MCP servers?",body:"Rebuilds the MCP tool set. Invalidates the prompt cache, so the next message re-sends full input tokens.",yes:"reload",danger:!0}).then((ok)=>{if(ok)fire(!1)});return}case"reload":gw.request("reload.env",{}).then((r)=>{let n=Number(r.updated??0);toast.show({variant:"success",message:`Reloaded .env (${n} var${n===1?"":"s"} updated) \xB7 /new to apply`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"reload-skills":gw.request("skills.reload",{}).then((r)=>{x2.dispatch({kind:"system",text:r.output});let n=Number(r.result?.total??0);toast.show({variant:"success",message:`Skills reloaded (${n} available)`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"save":gw.request("session.save").then((r)=>toast.show({variant:"success",message:`Saved \u2192 ${r.file}`})).catch((e)=>toast.show({variant:"error",message:e.message}));return}if(c2.target!=="gateway"||!x2.capabilities.canDispatchGatewayCommand)return;let jump=TAB_SLASH[c2.name];if(jump!==void 0&&!arg){x2.goTo(jump.tab,jump.sub);return}let full=`/${c2.name}${arg?" "+arg:""}`;if(x2.turnRef.current.streaming){x2.setQueue((q5)=>[...q5,full]);return}x2.dispatch({kind:"user",text:full}),gw.request("slash.exec",{command:full}).then((res)=>{if(res?.warning)x2.dispatch({kind:"system",text:`\u26A0 ${res.warning}`});if(res?.output)x2.dispatch({kind:"system",text:res.output})}).catch(()=>{gw.request("command.dispatch",{name:c2.name,arg}).then((d2)=>{if(d2.notice)x2.dispatch({kind:"system",text:d2.notice});if(d2.type==="exec"||d2.type==="plugin")return x2.dispatch({kind:"system",text:d2.output||"(no output)"});if(d2.type==="alias"&&d2.target)return void x2.sendRef.current(`/${d2.target}${arg?" "+arg:""}`);if((d2.type==="skill"||d2.type==="send")&&d2.message){if(d2.type==="skill")x2.dispatch({kind:"system",text:`\u26A1 loading skill: ${d2.name??c2.name}`});return void x2.sendRef.current(d2.message)}x2.dispatch({kind:"system",text:`/${c2.name}: unknown`})}).catch((e)=>x2.dispatch({kind:"system",text:`error: ${e.message}`}))})},[gw,dialog,toast,themeCtx,renderer,destructive,applyTitle,runCompress,branch3]);return import_react140.useEffect(()=>cmd.register([{title:"Help",value:"help",action:"help.open",category:"General",onSelect:()=>dialog.replace($jsx(HelpDialog,{}))},{title:"Keybindings",value:"keys",description:"View & rebind shortcuts",category:"General",onSelect:()=>openKeys(dialog)},{title:"Gateway Logs",value:"logs",description:"Show gateway stderr",category:"General",onSelect:()=>openLogs(dialog)},{title:"Switch Theme",value:"theme",action:"theme.pick",category:"General",onSelect:()=>openThemePicker(dialog,themeCtx)},{title:"Switch Model",value:"model",action:"model.pick",category:"General",onSelect:()=>openModelPicker(dialog,gw)},{title:"Pick Avatar",value:"eikon",description:"Choose sidebar .eikon avatar",category:"General",onSelect:()=>pickEikon()},{title:"Rollback",value:"rollback",description:"Browse & restore checkpoints",category:"Session",onSelect:()=>openRollback(dialog,gw,toast)},{title:"History",value:"history",action:"session.timeline",category:"Session",onSelect:()=>openHistory(dialog,gw)},{title:"Status",value:"status",action:"status.open",category:"Info",onSelect:()=>openStatus(dialog,ctx2.current.info,ctx2.current.sid)},{title:"Usage",value:"usage",description:"Tokens \xB7 context \xB7 cost",category:"Info",onSelect:()=>openUsage(dialog,gw)},{title:"Profile",value:"profile",description:"Active profile details",category:"Info",onSelect:()=>openProfile(dialog)},{title:"New Session",value:"new-session",action:"session.new",category:"Session",onSelect:()=>destructive("",{title:"Start a new session?",body:"Ends the current session and starts a fresh one. The existing session remains saved and resumable.",yes:"new session"},()=>{ctx2.current.newSession()})},{title:"Compress Session",value:"compress",action:"session.compress",category:"Session",onSelect:()=>runCompress()},{title:"Undo Last Turn",value:"undo",description:"Pop last user+assistant pair",category:"Session",onSelect:()=>run({name:"undo",target:"local"})},{title:"Redo",value:"redo",action:"session.redo",category:"Session",onSelect:()=>run({name:"redo",target:"local"})},{title:"Branch Session",value:"branch",description:"Fork the current conversation",category:"Session",onSelect:()=>branch3()}]),[cmd,dialog,themeCtx,gw,toast,destructive,pickEikon,runCompress,branch3,run]),run}var import_react142=__toESM(require_react_production(),1);init_perf();function variant(level2){switch(level2){case"error":return"error";case"warning":case"warn":return"warning";case"success":return"success";default:return"info"}}function duration2(p){if(p.kind==="sticky")return null;if(typeof p.ttl_ms==="number")return p.ttl_ms;if(typeof p.duration_ms==="number")return p.duration_ms;return}function showNotification(toast,p){let text5=String(p?.text??"").trim();if(!text5)return;toast.show({key:p?.key,variant:variant(p?.level),message:text5,duration:duration2(p??{text:text5})})}function clearNotification(toast,p){let key5=String(p?.key??"").trim();if(!key5)return;toast.clear(key5)}function count3(o){return o?Object.values(o).reduce((n,v2)=>n+v2.length,0):0}function reference(label3,text5,index4,count4){let head=index4&&count4?`\u25C7 Reference ${index4}/${count4} \u2014 ${label3}`:`\u25C7 Reference \u2014 ${label3}`,body2=text5.trim();return body2?`${head}
4209
4209
  ${body2}`:head}function formatProcessNotification(text5){let body2=text5.replace(/^\[IMPORTANT: /,"").replace(/\]$/,""),done2=body2.match(/^Background process (\S+) completed \(exit code (\S+)\)\.\nCommand: (.+?)(?:\n|$)/);if(done2)return`${done2[1]} exited ${done2[2]} \xB7 ${done2[3]}`;let hit2=body2.match(/^Background process (\S+) matched watch pattern "([^"]+)"\.\nCommand: (.+?)(?:\n|$)/);if(hit2)return`${hit2[1]} matched "${hit2[2]}" \xB7 ${hit2[3]}`;return body2.slice(0,100)}function mapEvent(ev,side){switch(ev.type){case"gateway.ready":if(side.onReady?.(),ev.payload?.skin)side.onSkin?.(ev.payload.skin);return null;case"session.info":{let si=ev.payload;side.onSessionInfo?.(si);let label3=si.model?`Connected \u2014 ${si.model} \xB7 ${count3(si.tools)} tools \xB7 ${count3(si.skills)} skills`:"Connected to Hermes";if(si.credential_warning)side.onStatus?.(si.credential_warning);return{kind:"system",text:label3}}case"session.title":return side.onSessionTitle?.(ev.payload.session_id,ev.payload.title),null;case"message.start":return count("stream:start"),mem("stream-start"),{kind:"message.start"};case"message.delta":{let chunk=ev.payload?.text??"";if(!chunk)return null;return count("stream:chunk"),{kind:"message.delta",chunk}}case"message.complete":{count("stream:done"),mem("stream-done");let p=ev.payload;if(p?.usage)side.onUsage?.(p.usage);if(side.onTurnComplete?.(),p?.status==="error")return{kind:"error",text:p.text||"request failed \u2014 see messages above"};if(p?.status==="interrupted")return{kind:"message.complete",text:(p.text||"")+`
4210
4210
 
4211
4211
  *[interrupted]*`,usage:p?.usage};return{kind:"message.complete",text:p?.text??void 0,usage:p?.usage}}case"tool.start":return{kind:"tool.start",id:ev.payload.tool_id,name:ev.payload.name??"unknown",preview:ev.payload.context,args:ev.payload.args_text};case"tool.progress":return{kind:"tool.progress",name:ev.payload.name,preview:ev.payload.preview};case"tool.generating":return{kind:"tool.generating",name:ev.payload.name};case"tool.complete":return{kind:"tool.complete",id:ev.payload.tool_id,summary:ev.payload.summary,error:ev.payload.error,inline_diff:ev.payload.inline_diff,duration:typeof ev.payload.duration_s==="number"?ev.payload.duration_s*1000:void 0,result:ev.payload.result_text};case"thinking.delta":return side.onStatus?.(ev.payload?.text??""),null;case"reasoning.delta":case"reasoning.available":{let text5=ev.payload?.text;if(!text5)return null;return{kind:"thinking",text:text5,final:ev.type==="reasoning.available",verbose:ev.payload?.verbose}}case"moa.reference":return{kind:"reference",text:reference(ev.payload?.label??"reference",ev.payload?.text??"",ev.payload?.index,ev.payload?.count)};case"moa.aggregating":{let agg=ev.payload?.aggregator;return side.onStatus?.(agg?`aggregating with ${agg}\u2026`:"aggregating\u2026"),null}case"subagent.start":case"subagent.thinking":case"subagent.tool":case"subagent.progress":case"subagent.complete":{let sub3=ev.type.slice(9);return record(sub3,ev.payload),{kind:"subagent",event:sub3,payload:ev.payload}}case"error":return{kind:"error",text:ev.payload?.message??"Unknown error"};case"clarify.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"clarify",...ev.payload}};case"approval.request":{let req={variant:"approval",...ev.payload},fallback2={kind:"prompt",id:`approval-${pid()}`,req};if(shouldRemember(req))return side.onApprovalRemembered?.(fallback2),null;return fallback2}case"sudo.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"sudo",...ev.payload}};case"secret.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"secret",...ev.payload}};case"background.complete":return side.onBackground?.(ev.payload.task_id,ev.payload.text),null;case"review.summary":{let text5=String(ev.payload?.text??"").trim();if(!text5)return null;return{kind:"system",text:text5}}case"btw.complete":return side.onBtw?.(ev.payload.text),null;case"gateway.stderr":{let line4=ev.payload.line;if(/error|fail|traceback|exception|\b[45]\d\d\b|refused|denied|unauthori/i.test(line4))return{kind:"error",text:line4,fatal:!1};return null}case"skin.changed":return side.onSkin?.(ev.payload),null;case"gateway.start_timeout":return{kind:"error",text:`gateway startup timed out (${ev.payload?.python??"python"} @ ${ev.payload?.cwd??"?"})`};case"gateway.protocol_error":return{kind:"system",text:`protocol error: ${ev.payload?.preview??"?"}`};case"browser.progress":{let text5=ev.payload?.message??"";if(!text5)return null;return ev.payload?.level==="error"?{kind:"error",text:text5}:{kind:"system",text:`\xB7 ${text5}`}}case"status.update":{let kind2=ev.payload?.kind,text5=ev.payload?.text??"";if(kind2==="process")return side.onStatus?.(formatProcessNotification(text5)),null;if(side.onStatus?.(text5),!kind2||kind2==="status")return null;return{kind:"system",text:text5}}case"notification.show":if(side.notices)showNotification(side.notices,ev.payload);return null;case"notification.clear":if(side.notices)clearNotification(side.notices,ev.payload);return null;case"voice.status":{let state3=String(ev.payload?.state??"");return side.onVoiceStatus?.(state3),null}case"voice.transcript":{if(ev.payload?.no_speech_limit===!0)return side.onVoiceTranscript?.("",!0),null;let text5=String(ev.payload?.text??"").trim();if(!text5)return null;return side.onVoiceTranscript?.(text5,!1),null}}return null}var STREAM_EVENTS=new Set(["message.start","message.delta","reasoning.delta","reasoning.available","thinking.delta","moa.reference","moa.aggregating","tool.start","tool.progress","tool.generating"]),TITLE_DELAYS=[1200,5000,15000,30000];function useStream(c){let gw=useGateway(),dialog=useDialog(),toast=useToast(),bg2=useBackground(),ctx2=import_react142.useRef(c);ctx2.current=c;let timers=import_react142.useRef([]);import_react142.useEffect(()=>()=>{timers.current.forEach(clearTimeout),timers.current=[]},[]);let interrupted=import_react142.useRef(!1),info3=import_react142.useRef(!1),deltas=import_react142.useRef({text:"",think:"",timer:null}),store=import_react142.useCallback((key5,id)=>{let sid2=key5??id;if(!sid2)return;ctx2.current.setDurable(sid2),ctx2.current.launchRef.current={mode:"resume",sid:sid2,splash:!1},set("lastSessionId",sid2)},[]),flush2=import_react142.useCallback(()=>{let d2=deltas.current;if(d2.timer)clearTimeout(d2.timer),d2.timer=null;if(d2.think)ctx2.current.dispatch({kind:"thinking",text:d2.think,final:!1}),d2.think="";if(d2.text)ctx2.current.dispatch({kind:"message.delta",chunk:d2.text}),d2.text=""},[]),sync=import_react142.useCallback((ms2=0)=>{let sid2=ctx2.current.sidRef.current;if(!sid2)return;let run=()=>gw.request("session.title",{session_id:sid2}).then((r)=>{if(ctx2.current.sidRef.current!==sid2)return;ctx2.current.setTitle(r.title??""),store(r.session_key)}).catch(()=>{});if(ms2<=0)return run();let id=setTimeout(()=>{timers.current=timers.current.filter((t2)=>t2!==id),run()},ms2);timers.current.push(id)},[gw]),retitle=import_react142.useCallback((sid2,title)=>{if(!sid2||title===void 0)return;if(sid2===ctx2.current.sidRef.current)ctx2.current.setTitle(title);home3.update("recentSessions",(rows3)=>rows3.map((r)=>r.id===sid2?{...r,title}:r))},[]),handle=import_react142.useCallback((ev)=>{let x2=ctx2.current;if(ev.type==="gateway.ready")info3.current=!1;if(ev.type==="message.start")x2.start();if(ev.type==="background.complete"&&ev.session_id&&x2.sidRef.current&&ev.session_id!==x2.sidRef.current){bg2.unregister(ev.payload.task_id);return}let shared=ev.type==="background.complete"&&!ev.session_id;if(ev.session_id&&x2.sidRef.current&&ev.session_id!==x2.sidRef.current&&!ev.type.startsWith("gateway.")&&!shared)return;if(interrupted.current){if(STREAM_EVENTS.has(ev.type))return;if(ev.type==="status.update"&&ev.payload?.kind==="lifecycle")return}let action=mapEvent(ev,{onReady:()=>{x2.session.boot(x2.launchRef.current).then((r)=>{if(x2.setSid(r.id),store(r.key,r.id),r.info)x2.setInfo(r.info),x2.setUsage(r.info.usage);if(x2.sessionStart.current=Date.now(),r.messages.length)x2.dispatch({kind:"load",messages:r.messages});if(r.note)toast.show({variant:"info",message:r.note})}).catch((err)=>{let msg=err instanceof Error?err.message:String(err);x2.setReady(!1),x2.setStarting(!1),x2.setStatus(`session boot failed: ${msg}`),x2.setErrorPulse(!0),x2.dispatch({kind:"system",text:`Failed to start session: ${msg}`})})},onSessionInfo:(si)=>{if(x2.setInfo(si),si.usage)x2.setUsage(si.usage);if(x2.setReady(!0),si.running===!1)x2.start(),x2.setStarting(!1),x2.setStatus("");if(si.session_id)x2.setSid(si.session_id);if(si.stored_session_id)store(si.stored_session_id,si.session_id??ev.session_id);if(x2.settle(),si.title!==void 0)x2.setTitle(si.title);let bad=(si.mcp_servers??[]).filter((s)=>!s.connected);if(bad.length)x2.dispatch({kind:"system",text:`MCP: ${bad.length} server(s) failed to connect \u2014 ${bad.map((s)=>s.name+(s.error?` (${s.error})`:"")).join(", ")}`});gw.request("config.get",{key:"busy"}).then((r)=>{let m2=r.value;if(m2==="queue"||m2==="steer"||m2==="interrupt")x2.setBusy(m2)}).catch(()=>{})},onUsage:(u3)=>x2.setUsage(u3),onTurnComplete:()=>{x2.setStarting(!1),x2.setStatus(""),flush(gw,x2.sidRef.current),x2.goalHook.check(x2.sidRef.current),TITLE_DELAYS.forEach(sync)},onBackground:(tid,text5)=>{let title=bg2.label(tid);bg2.unregister(tid),x2.dispatch({kind:"background",id:tid,title,text:text5})},onBtw:(text5)=>{let head=text5.split(`
@@ -4214,7 +4214,7 @@ ${body2}`:head}function formatProcessNotification(text5){let body2=text5.replace
4214
4214
  `):frame2;if(url2.searchParams.get("json")==="1")return json2({frame:body2,match:grep?frame2.includes(grep):void 0,lines:frame2.split(`
4215
4215
  `).length});return new Response(body2,{headers:{"Content-Type":"text/plain; charset=utf-8"}})}if(path4==="/logs"){let n=Number(url2.searchParams.get("n"))||200;return new Response(bridge.logs(n),{headers:{"Content-Type":"text/plain; charset=utf-8"}})}let pm=path4.match(/^\/plugin\/([^/]+)$/);if(pm&&req.method==="POST"){let body2=await req.json(),ok=await bridge.plugin(pm[1],body2.on!==!1);return json2({id:pm[1],on:body2.on!==!1,ok})}if(path4==="/push"&&req.method==="POST"){let body2=await req.json();if(!body2.type)return json2({error:"type required"},400);return bridge.push(body2),json2({pushed:body2.type})}if(path4==="/perf"){let d2=data();if(!d2)return json2({error:"PERF not enabled"},400);return json2(d2)}if(path4==="/tabs"){let ms2=Number(url2.searchParams.get("delay")||"500");for(let i=0;i<=TAB_MAX;i++)bridge.setTab(i),await new Promise((r)=>setTimeout(r,ms2));return bridge.setTab(CHAT_TAB),json2({cycled:TAB_MAX+1,delay:ms2})}if(path4==="/mem"){mem("control:snapshot");let m2=process.memoryUsage();return json2({rss:Math.round(m2.rss/1024/1024),heap:Math.round(m2.heapUsed/1024/1024),heapTotal:Math.round(m2.heapTotal/1024/1024),external:Math.round(m2.external/1024/1024)})}return json2({error:"not found",routes:["GET /status","GET /tab/:n","POST /send {message}","POST /key {name, ctrl?, shift?, meta?, raw?, safe?}","POST /keys {keys: [{name, ...}], delay?, safe?}","POST /type {text, delay?, safe?}","POST /input {text}","POST /plugin/:id {on}","POST /push {type, payload?}","GET /quit","GET /frame ?grep=pat&json=1","GET /logs ?n=200","GET /focus","GET /perf","GET /tabs","GET /mem"]},404)}function start(){if(!enabled2)return;Bun.serve({port:PORT,hostname:BIND,fetch:handle});let w2=warning();if(w2){process.stderr.write(`\x1B[33m[control] WARNING: ${w2.message}\x1B[0m
4216
4216
  `);return}process.stderr.write(`\x1B[90m[control] http://${BIND}:${PORT}\x1B[0m
4217
- `)}var import_react146=__toESM(require_react_production(),1);function select(dialog,opts){return new Promise((res)=>{let settled=!1,done2=(v2)=>{if(settled)return;settled=!0,res(v2),dialog.clear()};dialog.replace($jsx(DialogSelect,{title:opts.title,options:opts.options,placeholder:opts.placeholder,onSelect:(o)=>done2(o)}),()=>done2(null))})}function locate3(routes,name){let lower=name.toLowerCase(),hit2=TAB_SLASH[lower];if(hit2)return hit2;let i=[...routes.keys()].findIndex((n)=>n.toLowerCase()===lower);if(i<0)return;return{tab:TABS.length+i,sub:0}}function createApi(input){return{renderer:input.renderer,theme:{get current(){return input.theme.current.theme},get name(){return input.theme.current.name},get mode(){return input.theme.current.mode},set:(name)=>input.theme.current.set(name),setMode:(mode2)=>input.theme.current.setMode(mode2),has:(name)=>input.theme.current.has(name)},get keys(){return input.keys.current},ui:{dialog:input.dialog,toast:(o)=>input.toast.show({variant:o.variant??"info",title:o.title,message:o.message}),confirm:(o)=>openConfirm(input.dialog,o),prompt:(o)=>openTextPrompt(input.dialog,o),alert:(title,body2)=>openAlert(input.dialog,title,body2),select:(o)=>select(input.dialog,o)},kv:{get:(key5,fallback2)=>{return get2("plugin")?.[key5]??fallback2},set:(key5,value2)=>{let bag=get2("plugin")??{};set("plugin",{...bag,[key5]:value2})}},get client(){return input.gw.current},event:{on:(fn)=>{let c=input.gw.current,h2=(ev)=>fn(ev);return c.on("event",h2),()=>c.off("event",h2)}},route:{register:(defs)=>{for(let d2 of defs)input.routes.set(d2.name,d2);return input.bump(),()=>{for(let d2 of defs)input.routes.delete(d2.name);input.bump()}},navigate:(name,sub3)=>{let at=locate3(input.routes,name);if(!at)return;input.nav.current?.(at.tab,sub3??at.sub)},get current(){return input.cur.current?.()}},command:{register:(cmds)=>input.cmd.register(cmds)},slots:{register(){throw Error("slots.register is only available inside a plugin's tui() factory")}},eikon:{rasterizer:{register:(r)=>register(r)}},lifecycle:{signal:new AbortController().signal,onDispose:()=>()=>{}}}}function createScope(id,fail2){let ctrl=new AbortController,list3=[],done2=!1,onDispose=(fn)=>{if(done2)return()=>{};let key5=Symbol();return list3.push({key:key5,fn}),()=>{list3=list3.filter((x2)=>x2.key!==key5)}},track=(fn)=>{if(!fn)return()=>{};let ran=!1,drop2=()=>{},wrapped=()=>{if(ran)return;return ran=!0,drop2(),fn()};return drop2=onDispose(wrapped),wrapped},race=(fn,left)=>new Promise((res)=>{let t2=setTimeout(()=>res("timeout"),left);Promise.resolve().then(fn).then(()=>{clearTimeout(t2),res("ok")}).catch((e)=>{clearTimeout(t2),res(e instanceof Error?e:Error(String(e)))})}),dispose=async()=>{if(done2)return;done2=!0,ctrl.abort();let queue=[...list3].reverse();list3=[];let until2=Date.now()+5000;for(let item of queue){let left=until2-Date.now();if(left<=0){fail2(`[plugin:${id}] dispose budget exhausted`);return}let out=await race(item.fn,left);if(out==="ok")continue;if(out==="timeout"){fail2(`[plugin:${id}] dispose timed out`);return}fail2(`[plugin:${id}] dispose threw`,out)}};return{lifecycle:{signal:ctrl.signal,onDispose},track,dispose}}var import_react143=__toESM(require_react_production(),1);var fmt4=(d2)=>[d2.getHours(),d2.getMinutes(),d2.getSeconds()].map((n)=>String(n).padStart(2,"0")).join(":");function Clock(props){let[now,set3]=import_react143.useState(()=>new Date);return import_react143.useEffect(()=>{let t2=setInterval(()=>set3(new Date),1000);return()=>clearInterval(t2)},[]),$jsx("text",{fg:props.api.theme.current.textMuted,wrapMode:"none",children:fmt4(now)})}var plugin={id:"demo.clock",enabled:!1,tui(api){api.slots.register({order:100,slots:{app_bottom:()=>$jsx(Clock,{api})}})}},clock_default=plugin;var import_react144=__toESM(require_react_production(),1);import{readdirSync as readdirSync12,statSync as statSync11}from"fs";import{join as join27,basename as basename15}from"path";import{homedir as homedir10}from"os";var PREVIEW_MAX=200000,read4=(dir2)=>{return(dir2==="/"?[]:[{name:"..",dir:!0}]).concat(readdirSync12(dir2,{withFileTypes:!0}).filter((d2)=>!d2.name.startsWith(".")).sort((a,b2)=>a.isDirectory()===b2.isDirectory()?a.name.localeCompare(b2.name):a.isDirectory()?-1:1).map((d2)=>({name:d2.name,dir:d2.isDirectory()})))},isMd=(name)=>/\.(md|markdown|mdx)$/i.test(name);function Files(props){let api=props.api,theme=api.theme.current,[dir2,setDir]=import_react144.useState(()=>homedir10()),[sel,setSel]=import_react144.useState(0),[preview2,setPreview]=import_react144.useState(""),listing=import_react144.useMemo(()=>{try{return{rows:read4(dir2),error:""}}catch(e){return{rows:[],error:e instanceof Error?e.message:String(e)}}},[dir2]),rows3=listing.rows;import_react144.useEffect(()=>{setSel((s)=>Math.min(s,Math.max(0,rows3.length-1)))},[rows3.length]);let active2=rows3[sel];import_react144.useEffect(()=>{if(!active2||active2.dir){setPreview("");return}let path4=join27(dir2,active2.name),cancel=!1;return(async()=>{let st=statSync11(path4);if(st.size>PREVIEW_MAX){if(!cancel)setPreview(`(file too large \u2014 ${st.size} bytes)`);return}let text5=await Bun.file(path4).text();if(!cancel)setPreview(text5)})().catch((e)=>{if(!cancel)setPreview(`(read error: ${e})`)}),()=>{cancel=!0}},[dir2,active2?.name,active2?.dir]);let enter=()=>{if(!active2)return;if(active2.name===".."){setDir((d2)=>d2==="/"?"/":join27(d2,"..")),setSel(0);return}if(active2.dir)setDir((d2)=>join27(d2,active2.name)),setSel(0)};return useKeyboard((key5)=>{if(!props.focused||api.ui.dialog.open())return;if(key5.name==="left"){setDir((d2)=>d2==="/"?"/":join27(d2,"..")),setSel(0);return}handleListKey(api.keys,key5,{count:rows3.length,setSel,onActivate:enter})}),$jsxs("box",{flexGrow:1,flexDirection:"column",children:[$jsx("box",{height:1,flexShrink:0,paddingX:1,children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:dir2})}),$jsxs("box",{flexGrow:1,flexDirection:"row",children:[$jsxs("box",{width:32,flexShrink:0,flexDirection:"column",border:!0,borderColor:theme.border,children:[rows3.map((e,i)=>$jsx("box",{height:1,paddingX:1,backgroundColor:i===sel?theme.backgroundElement:void 0,children:$jsx("text",{fg:i===sel?theme.selectedListItemText:e.dir?theme.accent:theme.text,wrapMode:"none",children:(e.dir?"\u25B8 ":" ")+e.name})},e.name)),listing.error?$jsx("box",{height:1,paddingX:1,children:$jsx("text",{fg:theme.error,wrapMode:"none",children:listing.error})}):null]}),$jsx("box",{flexGrow:1,flexDirection:"column",border:!0,borderColor:theme.border,children:active2&&!active2.dir?$jsxs($Fragment,{children:[$jsx("box",{height:1,flexShrink:0,paddingX:1,children:$jsxs("text",{fg:theme.textMuted,wrapMode:"none",children:[basename15(active2.name),isMd(active2.name)?" \xB7 markdown":""]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:preview2})})]}):$jsx("box",{paddingX:1,children:$jsx("text",{fg:theme.textMuted,children:"Select a file to preview."})})})]})]})}var plugin2={id:"demo.files",enabled:!1,tui(api){api.route.register([{name:"Files",description:"File browser",render:({focused})=>$jsx(Files,{api,focused})}]),api.command.register([{title:"Files: open browser",value:"plugin.files.open",category:"Plugin",onSelect:()=>api.route.navigate("Files")}])}},files_default=plugin2;var INTERNAL=[clock_default,files_default];var KV_ENABLED="enabled",Ctx7=import_react146.createContext(null);function fail2(msg,err){let tail=err instanceof Error?`: ${err.message}`:err!==void 0?`: ${String(err)}`:"";console.error(msg+tail)}var RouteBody=(props)=>props.render(props.ctx);class RouteBoundary extends import_react146.Component{state={};static getDerivedStateFromError(error){return{error}}componentDidCatch(error,_info){fail2(`[plugin:${this.props.id}] render error in route "${this.props.name}"`,error)}render(){if(this.state.error)return $jsx("text",{children:`Plugin ${this.props.id} route ${this.props.name}: ${this.state.error.message}`});return this.props.children}}function enabledMap(){let v2=get2("plugin")?.[KV_ENABLED];return v2&&typeof v2==="object"?v2:{}}function persist2(id,on){let bag=get2("plugin")??{},map={...enabledMap(),[id]:on};set("plugin",{...bag,[KV_ENABLED]:map})}function scoped(base3,reg,id,scope){let n=0;return{...base3,slots:{register(p){let sid2=n++?`${id}:${n}`:id;return scope.track(reg.register({...p,id:sid2}))}},route:{register:(defs)=>scope.track(base3.route.register(defs.map((def2)=>({...def2,render:(ctx2)=>$jsx(RouteBoundary,{id,name:def2.name,children:$jsx(RouteBody,{render:def2.render,ctx:ctx2})})})))),navigate:base3.route.navigate,get current(){return base3.route.current}},event:{on:(fn)=>scope.track(base3.event.on(fn))},command:{register:(cmds)=>scope.track(base3.command.register(cmds))},eikon:{rasterizer:{register:(r)=>scope.track(base3.eikon.rasterizer.register(r))}},kv:{get:(key5,fb)=>base3.kv.get(`${id}.${key5}`,fb),set:(key5,v2)=>base3.kv.set(`${id}.${key5}`,v2)},lifecycle:scope.lifecycle}}var CELLS=new WeakMap;function ctxFor(renderer,themeRef){let hit2=CELLS.get(renderer);if(hit2)return hit2.themeRef=themeRef,hit2.ctx;let cell={themeRef,ctx:{}};return Object.defineProperty(cell.ctx,"theme",{get:()=>cell.themeRef.current.theme,enumerable:!0}),CELLS.set(renderer,cell),cell.ctx}function PluginProvider(props){let list3=props.plugins??INTERNAL,renderer=useRenderer(),themeCtx=useTheme(),keys=useKeys(),dialog=useDialog(),toast=useToast(),cmd=useCommand(),gw=useGateway(),themeRef=import_react146.useRef(themeCtx);themeRef.current=themeCtx;let keysRef=import_react146.useRef(keys);keysRef.current=keys;let gwRef=import_react146.useRef(gw);gwRef.current=gw;let navRef=import_react146.useRef(null),curRef=import_react146.useRef(null),routes=import_react146.useRef(new Map).current,[rev3,bump2]=import_react146.useReducer((x2)=>x2+1,0),reg=import_react146.useMemo(()=>createReactSlotRegistry(renderer,ctxFor(renderer,themeRef),{onPluginError:(e)=>fail2(`[plugin:${e.pluginId}] ${e.phase} error in slot "${e.slot}"`,e.error)}),[renderer]),Slot2=import_react146.useMemo(()=>createSlot(reg),[reg]),api=import_react146.useMemo(()=>createApi({renderer,theme:themeRef,keys:keysRef,dialog,toast,gw:gwRef,cmd,routes,bump:bump2,nav:navRef,cur:curRef}),[renderer,dialog,toast,cmd,routes]),entries2=import_react146.useRef(new Map),[gen,force]=import_react146.useReducer((x2)=>x2+1,0),activate=async(id,write=!0)=>{let e=entries2.current.get(id);if(!e)return!1;if(e.enabled=!0,write)persist2(id,!0);if(e.scope)return!0;let scope=createScope(id,fail2),ok=await Promise.resolve().then(()=>e.plugin.tui(scoped(api,reg,id,scope))).then(()=>!0).catch((err)=>{return fail2(`[plugin:${id}] activation failed`,err),e.error=String(err?.message??err),!1});if(!ok||!e.enabled)return await scope.dispose(),force(),ok&&!0;return e.scope=scope,e.error=void 0,force(),!0},deactivate=async(id,write=!0)=>{let e=entries2.current.get(id);if(!e)return!1;if(e.enabled=!1,write)persist2(id,!1);let scope=e.scope;if(e.scope=void 0,scope)await scope.dispose();return force(),!0},started=import_react146.useRef(!1);import_react146.useEffect(()=>{if(started.current)return;started.current=!0;let on=enabledMap();for(let p of list3)entries2.current.set(p.id,{plugin:p,enabled:on[p.id]??p.enabled??!0});return(async()=>{for(let[id,e]of entries2.current)if(e.enabled)await activate(id,!1)})(),()=>{for(let[,e]of entries2.current)e.scope?.dispose();entries2.current.clear(),routes.clear(),reg.clear()}},[]);let value2=import_react146.useMemo(()=>({Slot:Slot2,routes:[...routes.values()],bind:(nav,current2)=>{navRef.current=nav,curRef.current=current2},status:()=>[...entries2.current.values()].map((e)=>({id:e.plugin.id,enabled:e.enabled,active:!!e.scope,error:e.error})),has:(slot2)=>reg.resolveEntries(slot2).length>0,activate:(id)=>activate(id),deactivate:(id)=>deactivate(id)}),[Slot2,routes,rev3,gen]);return $jsx(Ctx7.Provider,{value:value2,children:props.children})}var usePlugins=makeUse(Ctx7,"usePlugins");function useBridge(o){let gw=useGateway(),renderer=useRenderer(),plugins=usePlugins(),state3=import_react148.useRef(o);state3.current=o,import_react148.useEffect(()=>{if(!enabled2)return;setBridge({tab:()=>state3.current.tab,setTab:o.setTab,send:async(msg)=>{let s=state3.current;if(!s.ready)throw Error("not connected");if(s.streaming)throw Error("already streaming");s.setTab(CHAT_TAB);try{await gw.request("prompt.submit",{text:msg}),s.dispatch({kind:"user",text:msg})}catch(err){let text5=err instanceof Error?err.message:String(err);throw s.dispatch({kind:"system",text:`Failed to send: ${text5}`}),err}},ready:()=>state3.current.ready,streaming:()=>state3.current.streaming,messages:()=>state3.current.messages.length,session:()=>state3.current.sid,input:()=>state3.current.composer.current?.value()??"",setInput:(v2)=>state3.current.composer.current?.set(v2),focusRegion:()=>state3.current.focusRegion,setFocusRegion:o.setFocusRegion,renderer:()=>renderer,logs:(n)=>gw.tail(n),plugin:(id,on)=>on?plugins.activate(id):plugins.deactivate(id),push:(ev)=>gw.emit("event",ev)})},[gw,renderer,plugins])}var import_react156=__toESM(require_react_production(),1);var winDrive=(s,off=0)=>s.length>=off+3&&/[A-Za-z]/.test(s[off])&&s[off+1]===":"&&(s[off+2]==="\\"||s[off+2]==="/");function looksLikePath(s){let t2=s.trim();if(!t2||t2.includes(`
4217
+ `)}var import_react146=__toESM(require_react_production(),1);function select(dialog,opts){return new Promise((res)=>{let settled=!1,done2=(v2)=>{if(settled)return;settled=!0,res(v2),dialog.clear()};dialog.replace($jsx(DialogSelect,{title:opts.title,options:opts.options,placeholder:opts.placeholder,onSelect:(o)=>done2(o)}),()=>done2(null))})}function locate3(routes,name){let lower=name.toLowerCase(),hit2=TAB_SLASH[lower];if(hit2)return hit2;let i=[...routes.keys()].findIndex((n)=>n.toLowerCase()===lower);if(i<0)return;return{tab:TABS.length+i,sub:0}}function createApi(input){return{renderer:input.renderer,theme:{get current(){return input.theme.current.theme},get name(){return input.theme.current.name},get mode(){return input.theme.current.mode},set:(name)=>input.theme.current.set(name),setMode:(mode2)=>input.theme.current.setMode(mode2),has:(name)=>input.theme.current.has(name)},get keys(){return input.keys.current},ui:{dialog:input.dialog,toast:(o)=>input.toast.show({variant:o.variant??"info",title:o.title,message:o.message}),confirm:(o)=>openConfirm(input.dialog,o),prompt:(o)=>openTextPrompt(input.dialog,o),alert:(title,body2)=>openAlert(input.dialog,title,body2),select:(o)=>select(input.dialog,o)},kv:{get:(key5,fallback2)=>{return get2("plugin")?.[key5]??fallback2},set:(key5,value2)=>{let bag=get2("plugin")??{};set("plugin",{...bag,[key5]:value2})}},get client(){return input.gw.current},event:{on:(fn)=>{let c=input.gw.current,h2=(ev)=>fn(ev);return c.on("event",h2),()=>c.off("event",h2)}},route:{register:(defs)=>{for(let d2 of defs)input.routes.set(d2.name,d2);return input.bump(),()=>{for(let d2 of defs)input.routes.delete(d2.name);input.bump()}},navigate:(name,sub3)=>{let at=locate3(input.routes,name);if(!at)return;input.nav.current?.(at.tab,sub3??at.sub)},get current(){return input.cur.current?.()}},command:{register:(cmds)=>input.cmd.register(cmds)},slots:{register(){throw Error("slots.register is only available inside a plugin's tui() factory")}},eikon:{rasterizer:{register:(r)=>register(r)}},lifecycle:{signal:new AbortController().signal,onDispose:()=>()=>{}}}}function createScope(id,fail2){let ctrl=new AbortController,list3=[],done2=!1,onDispose=(fn)=>{if(done2)return()=>{};let key5=Symbol();return list3.push({key:key5,fn}),()=>{list3=list3.filter((x2)=>x2.key!==key5)}},track=(fn)=>{if(!fn)return()=>{};let ran=!1,drop2=()=>{},wrapped=()=>{if(ran)return;return ran=!0,drop2(),fn()};return drop2=onDispose(wrapped),wrapped},race=(fn,left)=>new Promise((res)=>{let t2=setTimeout(()=>res("timeout"),left);Promise.resolve().then(fn).then(()=>{clearTimeout(t2),res("ok")}).catch((e)=>{clearTimeout(t2),res(e instanceof Error?e:Error(String(e)))})}),dispose=async()=>{if(done2)return;done2=!0,ctrl.abort();let queue=[...list3].reverse();list3=[];let until2=Date.now()+5000;for(let item of queue){let left=until2-Date.now();if(left<=0){fail2(`[plugin:${id}] dispose budget exhausted`);return}let out=await race(item.fn,left);if(out==="ok")continue;if(out==="timeout"){fail2(`[plugin:${id}] dispose timed out`);return}fail2(`[plugin:${id}] dispose threw`,out)}};return{lifecycle:{signal:ctrl.signal,onDispose},track,dispose}}var import_react143=__toESM(require_react_production(),1);var fmt4=(d2)=>[d2.getHours(),d2.getMinutes(),d2.getSeconds()].map((n)=>String(n).padStart(2,"0")).join(":");function Clock(props){let[now,set3]=import_react143.useState(()=>new Date);return import_react143.useEffect(()=>{let t2=setInterval(()=>set3(new Date),1000);return()=>clearInterval(t2)},[]),$jsx("text",{fg:props.api.theme.current.textMuted,wrapMode:"none",children:fmt4(now)})}var plugin={id:"demo.clock",enabled:!1,tui(api){api.slots.register({order:100,slots:{app_bottom:()=>$jsx(Clock,{api})}})}},clock_default=plugin;var import_react144=__toESM(require_react_production(),1);import{readdirSync as readdirSync12,statSync as statSync11}from"fs";import{join as join27,basename as basename15}from"path";import{homedir as homedir10}from"os";var PREVIEW_MAX=200000,read4=(dir2)=>{return(dir2==="/"?[]:[{name:"..",dir:!0}]).concat(readdirSync12(dir2,{withFileTypes:!0}).filter((d2)=>!d2.name.startsWith(".")).sort((a,b2)=>a.isDirectory()===b2.isDirectory()?a.name.localeCompare(b2.name):a.isDirectory()?-1:1).map((d2)=>({name:d2.name,dir:d2.isDirectory()})))},isMd=(name)=>/\.(md|markdown|mdx)$/i.test(name);function Files(props){let api=props.api,theme=api.theme.current,[dir2,setDir]=import_react144.useState(()=>homedir10()),[sel,setSel]=import_react144.useState(0),[preview2,setPreview]=import_react144.useState(""),listing=import_react144.useMemo(()=>{try{return{rows:read4(dir2),error:""}}catch(e){return{rows:[],error:e instanceof Error?e.message:String(e)}}},[dir2]),rows3=listing.rows;import_react144.useEffect(()=>{setSel((s)=>Math.min(s,Math.max(0,rows3.length-1)))},[rows3.length]);let active2=rows3[sel];import_react144.useEffect(()=>{if(!active2||active2.dir){setPreview("");return}let path4=join27(dir2,active2.name),cancel=!1;return(async()=>{let st=statSync11(path4);if(st.size>PREVIEW_MAX){if(!cancel)setPreview(`(file too large \u2014 ${st.size} bytes)`);return}let text5=await Bun.file(path4).text();if(!cancel)setPreview(text5)})().catch((e)=>{if(!cancel)setPreview(`(read error: ${e})`)}),()=>{cancel=!0}},[dir2,active2?.name,active2?.dir]);let enter=()=>{if(!active2)return;if(active2.name===".."){setDir((d2)=>d2==="/"?"/":join27(d2,"..")),setSel(0);return}if(active2.dir)setDir((d2)=>join27(d2,active2.name)),setSel(0)};return useKeyboard((key5)=>{if(!props.focused||api.ui.dialog.open())return;if(key5.name==="left"){setDir((d2)=>d2==="/"?"/":join27(d2,"..")),setSel(0);return}handleListKey(api.keys,key5,{count:rows3.length,setSel,onActivate:enter})}),$jsxs("box",{flexGrow:1,flexDirection:"column",children:[$jsx("box",{height:1,flexShrink:0,paddingX:1,children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:dir2})}),$jsxs("box",{flexGrow:1,flexDirection:"row",children:[$jsxs("box",{width:32,flexShrink:0,flexDirection:"column",border:!0,borderColor:theme.border,children:[rows3.map((e,i)=>$jsx("box",{height:1,paddingX:1,backgroundColor:i===sel?theme.backgroundElement:void 0,children:$jsx("text",{fg:i===sel?theme.selectedListItemText:e.dir?theme.accent:theme.text,wrapMode:"none",children:(e.dir?"\u25B8 ":" ")+e.name})},e.name)),listing.error?$jsx("box",{height:1,paddingX:1,children:$jsx("text",{fg:theme.error,wrapMode:"none",children:listing.error})}):null]}),$jsx("box",{flexGrow:1,flexDirection:"column",border:!0,borderColor:theme.border,children:active2&&!active2.dir?$jsxs($Fragment,{children:[$jsx("box",{height:1,flexShrink:0,paddingX:1,children:$jsxs("text",{fg:theme.textMuted,wrapMode:"none",children:[basename15(active2.name),isMd(active2.name)?" \xB7 markdown":""]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:preview2})})]}):$jsx("box",{paddingX:1,children:$jsx("text",{fg:theme.textMuted,children:"Select a file to preview."})})})]})]})}var plugin2={id:"demo.files",enabled:!1,tui(api){api.route.register([{name:"Files",description:"File browser",render:({focused})=>$jsx(Files,{api,focused})}]),api.command.register([{title:"Files: open browser",value:"plugin.files.open",category:"Plugin",onSelect:()=>api.route.navigate("Files")}])}},files_default=plugin2;var INTERNAL=[clock_default,files_default];var KV_ENABLED="enabled",Ctx7=import_react146.createContext(null);function fail2(msg,err){let tail=err instanceof Error?`: ${err.message}`:err!==void 0?`: ${String(err)}`:"";console.error(msg+tail)}var RouteBody=(props)=>props.render(props.ctx);class RouteBoundary extends import_react146.Component{state={};static getDerivedStateFromError(error){return{error}}componentDidCatch(error,_info){fail2(`[plugin:${this.props.id}] render error in route "${this.props.name}"`,error)}render(){if(this.state.error)return $jsx("text",{children:`Plugin ${this.props.id} route ${this.props.name}: ${this.state.error.message}`});return this.props.children}}function enabledMap(){let v2=get2("plugin")?.[KV_ENABLED];return v2&&typeof v2==="object"?v2:{}}function persist2(id,on){let bag=get2("plugin")??{},map={...enabledMap(),[id]:on};set("plugin",{...bag,[KV_ENABLED]:map})}function scoped(base3,reg,id,scope){let n=0;return{...base3,slots:{register(p){let sid2=n++?`${id}:${n}`:id;return scope.track(reg.register({...p,id:sid2}))}},route:{register:(defs)=>scope.track(base3.route.register(defs.map((def2)=>({...def2,render:(ctx2)=>$jsx(RouteBoundary,{id,name:def2.name,children:$jsx(RouteBody,{render:def2.render,ctx:ctx2})})})))),navigate:base3.route.navigate,get current(){return base3.route.current}},event:{on:(fn)=>scope.track(base3.event.on(fn))},command:{register:(cmds)=>scope.track(base3.command.register(cmds))},eikon:{rasterizer:{register:(r)=>scope.track(base3.eikon.rasterizer.register(r))}},kv:{get:(key5,fb)=>base3.kv.get(`${id}.${key5}`,fb),set:(key5,v2)=>base3.kv.set(`${id}.${key5}`,v2)},lifecycle:scope.lifecycle}}var CELLS=new WeakMap;function ctxFor(renderer,themeRef){let hit2=CELLS.get(renderer);if(hit2)return hit2.themeRef=themeRef,hit2.ctx;let cell={themeRef,ctx:{}};return Object.defineProperty(cell.ctx,"theme",{get:()=>cell.themeRef.current.theme,enumerable:!0}),CELLS.set(renderer,cell),cell.ctx}function PluginProvider(props){let list3=props.plugins??INTERNAL,renderer=useRenderer(),themeCtx=useTheme(),keys=useKeys(),dialog=useDialog(),toast=useToast(),cmd=useCommand(),gw=useGateway(),themeRef=import_react146.useRef(themeCtx);themeRef.current=themeCtx;let keysRef=import_react146.useRef(keys);keysRef.current=keys;let gwRef=import_react146.useRef(gw);gwRef.current=gw;let navRef=import_react146.useRef(null),curRef=import_react146.useRef(null),routes=import_react146.useRef(new Map).current,[rev3,bump2]=import_react146.useReducer((x2)=>x2+1,0),reg=import_react146.useMemo(()=>createReactSlotRegistry(renderer,ctxFor(renderer,themeRef),{onPluginError:(e)=>fail2(`[plugin:${e.pluginId}] ${e.phase} error in slot "${e.slot}"`,e.error)}),[renderer]),Slot2=import_react146.useMemo(()=>createSlot(reg),[reg]),api=import_react146.useMemo(()=>createApi({renderer,theme:themeRef,keys:keysRef,dialog,toast,gw:gwRef,cmd,routes,bump:bump2,nav:navRef,cur:curRef}),[renderer,dialog,toast,cmd,routes]),entries2=import_react146.useRef(new Map),[gen,force]=import_react146.useReducer((x2)=>x2+1,0),activate=async(id,write=!0)=>{let e=entries2.current.get(id);if(!e)return!1;if(e.enabled=!0,write)persist2(id,!0);if(e.scope)return!0;let scope=createScope(id,fail2),ok=await Promise.resolve().then(()=>e.plugin.tui(scoped(api,reg,id,scope))).then(()=>!0).catch((err)=>{return fail2(`[plugin:${id}] activation failed`,err),e.error=String(err?.message??err),!1});if(!ok||!e.enabled)return await scope.dispose(),force(),ok&&!0;return e.scope=scope,e.error=void 0,force(),!0},deactivate=async(id,write=!0)=>{let e=entries2.current.get(id);if(!e)return!1;if(e.enabled=!1,write)persist2(id,!1);let scope=e.scope;if(e.scope=void 0,scope)await scope.dispose();return force(),!0},started=import_react146.useRef(!1);import_react146.useEffect(()=>{if(started.current)return;started.current=!0;let on=enabledMap();for(let p of list3)entries2.current.set(p.id,{plugin:p,enabled:on[p.id]??p.enabled??!0});return(async()=>{for(let[id,e]of entries2.current)if(e.enabled)await activate(id,!1)})(),()=>{for(let[,e]of entries2.current)e.scope?.dispose();entries2.current.clear(),routes.clear(),reg.clear()}},[]);let value2=import_react146.useMemo(()=>({Slot:Slot2,routes:[...routes.values()],bind:(nav,current2)=>{navRef.current=nav,curRef.current=current2},status:()=>[...entries2.current.values()].map((e)=>({id:e.plugin.id,enabled:e.enabled,active:!!e.scope,error:e.error})),has:(slot2)=>reg.resolveEntries(slot2).length>0,activate:(id)=>activate(id),deactivate:(id)=>deactivate(id)}),[Slot2,routes,rev3,gen]);return $jsx(Ctx7.Provider,{value:value2,children:props.children})}var usePlugins=makeUse(Ctx7,"usePlugins");function useBridge(o){let gw=useGateway(),renderer=useRenderer(),plugins=usePlugins(),state3=import_react148.useRef(o);state3.current=o,import_react148.useEffect(()=>{if(!enabled2)return;setBridge({tab:()=>state3.current.tab,setTab:o.setTab,send:async(msg)=>{let s=state3.current;if(!s.ready)throw Error("not connected");if(s.streaming)throw Error("already streaming");s.setTab(CHAT_TAB);try{await gw.request("prompt.submit",{text:msg}),s.dispatch({kind:"user",text:msg})}catch(err){let text5=err instanceof Error?err.message:String(err);throw s.dispatch({kind:"system",text:`Failed to send: ${text5}`}),err}},ready:()=>state3.current.ready,streaming:()=>state3.current.streaming,messages:()=>state3.current.messages.length,session:()=>state3.current.sid,input:()=>state3.current.composer.current?.value()??"",setInput:(v2)=>state3.current.composer.current?.set(v2),focusRegion:()=>state3.current.focusRegion,setFocusRegion:o.setFocusRegion,renderer:()=>renderer,logs:(n)=>gw.tail(n),plugin:(id,on)=>on?plugins.activate(id):plugins.deactivate(id),push:(ev)=>{let e=ev;gw.diagnose?.(e,"control"),gw.emit("event",e)}})},[gw,renderer,plugins])}var import_react156=__toESM(require_react_production(),1);var winDrive=(s,off=0)=>s.length>=off+3&&/[A-Za-z]/.test(s[off])&&s[off+1]===":"&&(s[off+2]==="\\"||s[off+2]==="/");function looksLikePath(s){let t2=s.trim();if(!t2||t2.includes(`
4218
4218
  `))return!1;if(t2.startsWith("file://"))return!0;if(t2.startsWith("/")||t2.startsWith("~")||t2.startsWith("./")||t2.startsWith("../"))return!0;if(winDrive(t2))return!0;let q5=t2[0];if(q5==='"'||q5==="'"){let inner=t2[1];if(inner==="/"||inner==="~")return!0;if(winDrive(t2,1))return!0}return!1}var import_react150=__toESM(require_react_production(),1);var SEP=new Set(["-","_","/"," ","."]);function boundary2(hay,i){if(i===0)return!0;let prev=hay[i-1];if(SEP.has(prev))return!0;if(prev===prev.toLowerCase()&&hay[i]!==hay[i].toLowerCase())return!0;return!1}function score(needle,hay){if(!needle)return 0;let n=needle.toLowerCase(),h2=hay.toLowerCase(),pts=0,from2=0,prev=-2;for(let i=0;i<n.length;i++){let at=h2.indexOf(n[i],from2);if(at<0)return 0;if(pts+=1,at===0)pts+=8;if(at===prev+1)pts+=5;if(at!==prev+1&&boundary2(hay,at))pts+=4;pts-=(at-(prev<0?0:prev+1))*0.1,prev=at,from2=at+1}if(h2.startsWith(n))pts+=100;return pts-hay.length*0.01}function best(q5,cmd){return cmd.aliases.reduce((m2,a)=>Math.max(m2,score(q5,a)),score(q5,cmd.name))}function rank(list3,q5){if(!q5)return[...list3];return list3.map((cmd)=>({cmd,s:best(q5,cmd)})).filter((r)=>r.s>0).sort((a,b2)=>b2.s-a.s).map((r)=>r.cmd)}function boundary3(ch){return ch===void 0||/\s/.test(ch)||"({\"'`".includes(ch)}function tag2(s){return s?`${s.start}:${s.end}:${s.text}`:""}function exact(spot,cmds){let m2=spot.query.match(/^(\S+)(?:\s+(\S.*))?$/);if(!m2)return!1;return cmds.some((c)=>c.name===m2[1]||c.aliases.includes(m2[1]))&&(m2[2]!==void 0||spot.query===m2[1])}function slashTokenAt(input,caret=input.length){let off=Math.max(0,Math.min(caret,input.length));if(/^\/[A-Za-z0-9_-]*$/.test(input))return{text:input,query:input.slice(1),start:0,end:input.length,whole:!0};let line4=input.lastIndexOf(`
4219
4219
  `,Math.max(0,off-1))+1,slash3=input.lastIndexOf("/",off);if(slash3<line4)return null;if(!boundary3(input[slash3-1]))return null;if(input[slash3-1]==="("&&input[slash3-2]==="]")return null;if(input[slash3-1]==="[")return null;let query2=input.slice(slash3+1).match(/^[A-Za-z0-9_-]*/)?.[0]??"",end=slash3+1+query2.length;if(input[end]==="/")return null;if(slash3===line4&&off>end&&/^\s+[^\n]*$/.test(input.slice(end,off)))return{text:input.slice(slash3,off),query:input.slice(slash3+1,off),start:slash3,end:off,whole:!0};if(off>end||off<slash3)return null;if(!query2&&input[slash3+1]==="/")return null;return{text:input.slice(slash3,end),query:query2,start:slash3,end,whole:!1}}function replaceSlashToken(input,spot,cmd){let text5=`/${cmd.name}${cmd.name.includes(" ")?" ":""}`;return input.slice(0,spot.start)+text5+input.slice(spot.end)}function useSlashPopover(input,cmds,caret=input.length){let[cursor,setCursor]=import_react150.useState(0),[dismissed,setDismissed]=import_react150.useState(null),spot=import_react150.useMemo(()=>slashTokenAt(input,caret),[input,caret]),key5=tag2(spot),popover=import_react150.useMemo(()=>{if(!spot||dismissed===key5)return null;if(spot.whole&&exact(spot,cmds))return null;let subs3=matchSub(cmds,spot.text);if(subs3)return subs3;return rank(cmds,spot.query)},[spot,cmds,dismissed,key5]),active2=popover?Math.max(0,Math.min(cursor,popover.length-1)):0;import_react150.useEffect(()=>{setCursor((c)=>c===0?c:0),setDismissed((d2)=>d2&&d2!==key5?null:d2)},[key5]);let ghost=import_react150.useMemo(()=>{if(!popover||popover.length===0)return"";let hit2=popover[active2];if(!hit2||hit2.name.includes(" "))return"";if(!spot||!/^\/\S*$/.test(spot.text))return"";let typed=spot.query;if(typed.length<2)return"";if(!hit2.name.toLowerCase().startsWith(typed.toLowerCase()))return"";return hit2.name.slice(typed.length)},[spot,popover,active2]),open3=popover!==null&&popover.length>0;return{popover,cursor:active2,setCursor,ghost,open:open3,spot,dismiss:(next3,off=next3?.length??caret)=>setDismissed(tag2(next3===void 0?spot:slashTokenAt(next3,off)))}}var import_react151=__toESM(require_react_production(),1);var exports_frecency={};__export(exports_frecency,{score:()=>score2,frecency:()=>exports_frecency,bump:()=>bump2,_reset:()=>_reset});import{join as join28}from"path";import{existsSync as existsSync32,readFileSync as readFileSync23,writeFileSync as writeFileSync10,appendFileSync,mkdirSync as mkdirSync8}from"fs";var MAX2=1000,file3=()=>join28(configDir(),"frecency.jsonl"),data2=null;function load6(){if(!existsSync32(file3()))return{};let rows3=readFileSync23(file3(),"utf-8").split(`
4220
4220
  `).filter(Boolean).map((l)=>{try{return JSON.parse(l)}catch{return null}}).filter((e)=>e!==null),latest3={};for(let e of rows3)latest3[e.path]=e;let kept=Object.values(latest3).sort((a,b2)=>b2.at-a.at).slice(0,MAX2);if(kept.length<rows3.length)mkdirSync8(configDir(),{recursive:!0}),writeFileSync10(file3(),kept.map((e)=>JSON.stringify(e)).join(`