citadel_cli 1.1.7 → 1.4.0

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.
@@ -1,36 +1,33 @@
1
- (function(y,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("react/jsx-runtime"),require("react"),require("react-dom/client")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","react-dom/client"],a):(y=typeof globalThis<"u"?globalThis:y||self,a(y.Citadel={},y.jsxRuntime,y.React,y.client))})(this,function(y,a,s,ge){"use strict";var Ke=Object.defineProperty;var qe=(y,a,s)=>a in y?Ke(y,a,{enumerable:!0,configurable:!0,writable:!0,value:s}):y[a]=s;var x=(y,a,s)=>qe(y,typeof a!="symbol"?a+"":a,s);var H=(r=>(r.Pending="pending",r.Success="success",r.Failure="failure",r.Timeout="timeout",r))(H||{});class P{constructor(e=Date.now()){x(this,"_status","pending");this.timestamp=e}get status(){return this._status}markSuccess(){this._status="success"}markFailure(){this._status="failure"}markTimeout(){this._status="timeout"}}class fe extends P{constructor(e,n){super(n),this.data=e}render(){return a.jsx("pre",{className:"text-gray-200",children:JSON.stringify(this.data,null,2)})}}class O extends P{constructor(e,n){super(n),this.text=e}render(){return a.jsx("div",{className:"text-gray-200 whitespace-pre font-mono",children:this.text})}}class J extends P{constructor(e,n){super(n),this.error=e,this.markFailure()}render(){return a.jsx("div",{className:"mt-1 text-red-400",children:this.error})}}class Q extends P{render(){return a.jsx("div",{className:"text-gray-400",children:"..."})}}class we extends P{constructor(e,n="",t){super(t),this.imageUrl=e,this.altText=n}render(){return a.jsx("div",{className:"my-2",children:a.jsx("img",{src:this.imageUrl,alt:this.altText,className:"max-w-[400px] max-h-[300px] h-auto rounded-lg object-contain"})})}}const be=r=>async function(){const e=r.commands.filter(n=>n.fullPath[0]!=="help").map(n=>`${n.segments.map(o=>o.type==="argument"?`<${o.name}>`:o.name).join(" ")} - ${n.description}`).sort();return e.length===0?new O("No commands available yet. Add some commands to get started!"):(e.push("help - Show available commands"),new O(`Available Commands:
2
- `+e.join(`
3
- `)))};var Y=(r=>(r[r.NONE=0]="NONE",r[r.ERROR=1]="ERROR",r[r.WARN=2]="WARN",r[r.INFO=3]="INFO",r[r.DEBUG=4]="DEBUG",r[r.TRACE=5]="TRACE",r))(Y||{});const X=!0;class S{static configure(e){this.level=e.level,this.prefix=e.prefix||"[Citadel]"}static trace(...e){this.level>=5&&!X&&console.trace(this.prefix,...e)}static debug(...e){this.level>=4&&!X&&console.debug(this.prefix,...e)}static info(...e){this.level>=3&&console.info(this.prefix,...e)}static warn(...e){this.level>=2&&console.warn(this.prefix,...e)}static error(...e){this.level>=1&&console.error(this.prefix,...e)}}x(S,"level",0),x(S,"prefix","");const N={commandTimeoutMs:1e4,cursorColor:"var(--cursor-color, #fff)",cursorSpeed:530,cursorType:"blink",includeHelpCommand:!0,initialHeight:"40vh",logLevel:Y.ERROR,maxHeight:"80vh",minHeight:"200",outputFontSize:"0.875rem",resetStateOnHide:!1,showCitadelKey:".",displayMode:"panel",storage:{type:"localStorage",maxCommands:100}};class Z{constructor(e){x(this,"config");this.config={type:"localStorage",maxCommands:100,...e}}async addStoredCommand(e){const n=await this.getStoredCommands();for(n.push(e);n.length>this.config.maxCommands;)n.shift();await this.saveCommands(n)}}class ye extends Z{constructor(n){super(n);x(this,"storageKey","citadel_command_history")}async getStoredCommands(){try{const n=window.localStorage.getItem(this.storageKey);return n?JSON.parse(n).map(o=>({commandSegments:o.commandSegments||[],timestamp:o.timestamp})):[]}catch(n){return console.warn("Failed to load commands from localStorage:",n),[]}}async clear(){try{window.localStorage.removeItem(this.storageKey)}catch(n){console.warn("Failed to clear localStorage:",n)}}async saveCommands(n){try{const t=n.map(o=>({commandSegments:Array.isArray(o.commandSegments)?[...o.commandSegments]:[],timestamp:o.timestamp}));window.localStorage.setItem(this.storageKey,JSON.stringify(t))}catch(t){throw console.warn("Failed to save commands to localStorage:",t),t}}}class R extends Z{constructor(n){super(n);x(this,"storedCommands",[])}async getStoredCommands(){return this.storedCommands.map(n=>({commandSegments:Array.isArray(n.commandSegments)?[...n.commandSegments]:[],timestamp:n.timestamp}))}async clear(){this.storedCommands=[]}async saveCommands(n){this.storedCommands=n.map(t=>({commandSegments:Array.isArray(t.commandSegments)?[...t.commandSegments]:[],timestamp:t.timestamp}))}}const z=class z{constructor(){x(this,"currentStorage")}static reset(){z.instance=void 0}static getInstance(){return z.instance||(z.instance=new z),z.instance}initializeStorage(e){try{e.type==="memory"?this.currentStorage=new R(e):this.currentStorage=new ye(e)}catch(n){console.warn("Failed to create storage, falling back to memory storage:",n),this.currentStorage=new R(e)}}getStorage(){if(!this.currentStorage)throw new Error("Storage not initialized. Call initializeStorage first.");return this.currentStorage}};x(z,"instance");let L=z;const ee=async()=>new O("");class B{constructor(e,n,t){this.type=e,this.name=n,this.description=t}toString(){return this.name}}class ne extends B{constructor(){super("null",">null<","Empty segment")}}class xe extends B{constructor(e,n){super("word",e,n)}}class $ extends B{constructor(e,n,t,o){super("argument",e,n),this.value=t,this.valid=o}}class Ce{constructor(e,n,t=ee){x(this,"_segments");x(this,"_description");x(this,"_handler");this._segments=e,this._description=n,this._handler=t}get segments(){return this._segments}get description(){return this._description}get handler(){return this._handler}get hasArguments(){return this.segments.some(e=>e.type==="argument")}get fullPath(){return this.segments.map(e=>e.name)}get fullPath_s(){return this.fullPath.join(" ")}equals(e){return this.fullPath.join(" ")===e.fullPath.join(" ")}}class K{constructor(){x(this,"_commands",[])}get commands(){return this._commands}addCommand(e,n,t=ee){if(e===void 0||e.length===0)throw new Error("Command path cannot be empty");const o=new Ce(e,n,t),l=this._commands.find(d=>{const m=d.segments.map(c=>c.type==="argument"?"*":c.name).join(" "),i=e.map(c=>c.type==="argument"?"*":c.name).join(" ");return m===i});if(l)throw new Error(`Duplicate commands: '${l.fullPath_s}' and '${o.fullPath_s}'`);this._commands.push(o)}removeCommand(e){const n=e.join(" "),t=this._commands.findIndex(o=>o.fullPath.join(" ")===n);return t===-1?!1:(this._commands.splice(t,1),!0)}getCommand(e){return this._commands.find(n=>{const t=n.fullPath.join(" "),o=e.join(" ");if(t===o)return!0;const d=n.segments.filter(m=>m.type==="word").map(m=>m.name);return d.length===e.length&&d.join(" ")===o})}commandExistsForPath(e){const n=this._commands.map(o=>o.segments.map(l=>l.type==="argument"?"*":l.name).join(" ")),t=e.map((o,l)=>this._commands.some(m=>{var i;return((i=m.segments[l])==null?void 0:i.type)==="argument"})?"*":o).join(" ");return n.includes(t)}getCompletionNames(e){return this.getCompletions(e).map(n=>n.name)}getCompletions(e){if(S.debug("[getCompletions] path: ",e),!e.length){const l=this._commands.map(i=>i.segments[0]),d=(i,c)=>i.type===c.type&&i.name===c.name;return l.filter((i,c,p)=>c===p.findIndex(g=>d(g,i)))}const n=e.length;return this._commands.filter(l=>{const d=l.segments;if(d.length<=n-1)return!1;for(let m=0;m<n;m++){const i=e[m],c=d[m];if(!(i==="*"&&c.type==="argument")&&i!==c.name)return!1}return!0}).filter(l=>l.segments.length>n).map(l=>{const d=l.segments[n],m=d.type==="argument"?$:xe;return new m(d.name,d.description)}).filter((l,d,m)=>d===m.findIndex(i=>i.type===l.type&&i.name===l.name))}hasNextSegment(e){return this.getCompletions(e).length>0}}class te{constructor(){x(this,"segments",[]);x(this,"nullSegment",new ne);x(this,"observers",[])}subscribe(e){this.observers.push(e)}unsubscribe(e){this.observers=this.observers.filter(n=>n!==e)}notifyObservers(){this.observers.forEach(e=>e.update())}clear(){this.segments=[],this.notifyObservers()}push(e){this.segments.push(e),this.notifyObservers()}pushAll(e){e.forEach(n=>this.push(n))}pop(){const e=this.segments.pop()||this.nullSegment;return this.notifyObservers(),e}peek(){return this.segments[this.segments.length-1]||this.nullSegment}size(){return this.segments.length}isEmpty(){return this.segments.length===0}get hasArguments(){return this.segments.some(e=>e.type==="argument")}get arguments(){return this.segments.filter(e=>e.type==="argument")}path(){return this.segments.map(e=>e.name)}toArray(){return[...this.segments]}}const ve={config:N,commands:new K,segmentStack:new te},D=s.createContext(ve),Se=({config:r=N,commandRegistry:e,children:n})=>{const[t,o]=s.useState(),[l]=s.useState(()=>new te),d={...N,...r,storage:{...N.storage,...r.storage},cursorType:r.cursorType??N.cursorType,cursorColor:r.cursorColor??N.cursorColor,cursorSpeed:r.cursorSpeed??N.cursorSpeed,showCitadelKey:r.showCitadelKey||"."};s.useEffect(()=>{L.getInstance().initializeStorage(d.storage??N.storage),o(L.getInstance().getStorage())},[]),s.useEffect(()=>{if(e){if(d.includeHelpCommand){if(!e.commandExistsForPath(["help"])){const i=be(e);e.addCommand([{type:"word",name:"help"}],"Show available commands",i)}return}e.removeCommand(["help"])}},[e,d.includeHelpCommand]);const m=s.useMemo(()=>({config:d,commands:e||new K,storage:t,segmentStack:l}),[d,e,t,l]);return a.jsx(D.Provider,{value:m,children:n})},T=()=>{const r=s.useContext(D);if(r===void 0)throw new Error("useCitadelConfig must be used within a CitadelConfigProvider");return r.config},q=()=>{const r=s.useContext(D);if(r===void 0)throw new Error("useCitadelCommands must be used within a CitadelConfigProvider");return r.commands},re=()=>{const r=s.useContext(D);if(r===void 0)throw new Error("useCitadelStorage must be used within a CitadelConfigProvider");return r.storage},U=()=>{const r=s.useContext(D);if(r===void 0)throw new Error("useSegmentStack must be used within a CitadelConfigProvider");return r.segmentStack},V=class V{constructor(e,n){x(this,"id");x(this,"timestamp");x(this,"command");x(this,"result");this.id=`output-${Date.now()}-${V.idCounter++}`,this.command=e.toArray().map(t=>t.type==="argument"?t.value||"":t.name),this.timestamp=Date.now(),this.result=n??new Q}};x(V,"idCounter",0);let W=V;function ke(r){return{commandSegments:r,timestamp:Date.now()}}function oe(){const r=re(),[e,n]=s.useState({storedCommands:[],position:null}),t=s.useCallback(async m=>{if(r)try{const i=ke(m);await r.addStoredCommand(i),n(c=>({...c,storedCommands:[...c.storedCommands,i],position:null}))}catch(i){console.warn("Failed to save command to history:",i)}},[r]),o=s.useCallback(async()=>r?await r.getStoredCommands():[],[r]);s.useEffect(()=>{if(!r)return;(async()=>{try{const i=await r.getStoredCommands();return n(c=>({...c,storedCommands:i})),i}catch(i){console.warn("Failed to load command history:",i)}})()},[r]);const l=s.useCallback(async m=>{const i=await o();if(i.length===0)return n(g=>({...g,storedCommands:[],position:null})),{segments:null,position:null};let c=null;if(m==="up"?e.position===null?c=i.length-1:e.position>0?c=e.position-1:c=0:e.position===null||e.position>=i.length-1?c=null:c=e.position+1,n(g=>({...g,storedCommands:i,position:c})),c===null)return{segments:[],position:null};const p=i[c];return p?{segments:p.commandSegments,position:c}:{segments:[],position:null}},[e.position,o]),d=s.useCallback(async()=>{try{if(!r)return;await r.clear(),n({storedCommands:[],position:null})}catch(m){console.warn("Failed to clear command history:",m)}},[r]);return{history:e,addStoredCommand:t,getStoredCommands:o,navigateHistory:l,clear:d}}const G=()=>{const r=T(),e=q(),n=oe(),t=U(),o=re(),[l,d]=s.useState({currentInput:"",isEnteringArg:!1,output:[],history:{commands:[],position:null,storage:o}});s.useEffect(()=>{},[o]),s.useEffect(()=>{d(i=>({...i,history:{commands:n.history.storedCommands,position:n.history.position,storage:o}}))},[n.history,o]);const m={setCurrentInput:s.useCallback(i=>{S.debug("[CitadelActions] setCurrentInput: ",i),d(c=>({...c,currentInput:i}))},[]),setIsEnteringArg:s.useCallback(i=>{S.debug("[CitadelActions] setIsEnteringArg: ",i),d(c=>({...c,isEnteringArg:i}))},[]),addOutput:s.useCallback(i=>{S.debug("[CitadelActions]addOutput: ",i),d(c=>({...c,output:[...c.output,i]}))},[]),executeCommand:s.useCallback(async()=>{const i=t.path(),c=e.getCommand(i);if(!c){console.error("[CitadelActions][executeCommand] Cannot execute command because no command was found for the given path: ",i);return}const p=new W(t);d(g=>({...g,output:[...g.output,p]}));try{const g=new Promise((h,E)=>{setTimeout(()=>{E(new Error("Request timed out"))},r.commandTimeoutMs)}),k=t.arguments.map(h=>h.value||""),v=await Promise.race([c.handler(k),g]);if(!(v instanceof P))throw new Error(`The ${i.join(".")} command returned an invalid result type. Commands must return an instance of a CommandResult.
1
+ (function(f,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("react/jsx-runtime"),require("react"),require("react-dom/client")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","react-dom/client"],c):(f=typeof globalThis<"u"?globalThis:f||self,c(f.Citadel={},f.jsxRuntime,f.React,f.client))})(this,function(f,c,o,Ae){"use strict";var ct=Object.defineProperty;var dt=(f,c,o)=>c in f?ct(f,c,{enumerable:!0,configurable:!0,writable:!0,value:o}):f[c]=o;var C=(f,c,o)=>dt(f,typeof c!="symbol"?c+"":c,o);var L=(n=>(n.Pending="pending",n.Success="success",n.Failure="failure",n.Timeout="timeout",n))(L||{});class j{constructor(e=Date.now()){C(this,"_status","pending");this.timestamp=e}get status(){return this._status}markSuccess(){this._status="success"}markFailure(){this._status="failure"}markTimeout(){this._status="timeout"}}class ae extends j{constructor(e,t){super(t),this.data=e}render(){return c.jsx("pre",{className:"citadel-result-json",children:JSON.stringify(this.data,null,2)})}}class O extends j{constructor(e,t){super(t),this.text=e}render(){return c.jsx("div",{className:"citadel-result-text",children:this.text})}}class Q extends j{constructor(e,t){super(t),this.error=e,this.markFailure()}render(){return c.jsx("div",{className:"citadel-result-error",children:this.error})}}class ie extends j{render(){return c.jsx("div",{className:"citadel-result-pending",children:"..."})}}class le extends j{constructor(e,t="",s){super(s),this.imageUrl=e,this.altText=t}render(){return c.jsx("div",{className:"citadel-result-image-wrap",children:c.jsx("img",{src:this.imageUrl,alt:this.altText,className:"citadel-result-image"})})}}const Pe=n=>async function(){const t=n.commands.filter(s=>s.fullPath[0]!=="help").map(s=>{const a=`${s.segments.map(d=>d.type==="argument"?`<${d.name}>`:d.name).join(" ")} - ${s.description}`,i=s.segments.filter(d=>d.type==="argument"&&d.description).map(d=>` <${d.name}>: ${d.description}`);return{commandLine:a,argumentLines:i}}).sort((s,r)=>s.commandLine.localeCompare(r.commandLine)).flatMap(s=>[s.commandLine,...s.argumentLines]);return t.length===0?new O("No commands available yet. Add some commands to get started!"):(t.push("help - Show available commands"),new O(`Available Commands:
2
+ `+t.join(`
3
+ `)))};var X=(n=>(n[n.NONE=0]="NONE",n[n.ERROR=1]="ERROR",n[n.WARN=2]="WARN",n[n.INFO=3]="INFO",n[n.DEBUG=4]="DEBUG",n[n.TRACE=5]="TRACE",n))(X||{});const ce=!0;class k{static configure(e){this.level=e.level,this.prefix=e.prefix||"[Citadel]"}static trace(...e){this.level>=5&&!ce&&console.trace(this.prefix,...e)}static debug(...e){this.level>=4&&!ce&&console.debug(this.prefix,...e)}static info(...e){this.level>=3&&console.info(this.prefix,...e)}static warn(...e){this.level>=2&&console.warn(this.prefix,...e)}static error(...e){this.level>=1&&console.error(this.prefix,...e)}}C(k,"level",0),C(k,"prefix","");const I={commandTimeoutMs:1e4,cursorColor:"var(--cursor-color, #fff)",cursorSpeed:530,cursorType:"blink",includeHelpCommand:!0,fontFamily:"monospace",fontSize:"0.875rem",initialHeight:"50vh",logLevel:X.ERROR,maxHeight:"80vh",minHeight:"200",outputFontSize:"0.875rem",resetStateOnHide:!1,showCitadelKey:".",displayMode:"panel",storage:{type:"localStorage",maxCommands:100}},de=async()=>new O("");class Z{constructor(e,t,s){this.type=e,this.name=t,this.description=s}toString(){return this.name}}class R extends Z{constructor(){super("null",">null<","Empty segment")}}class me extends Z{constructor(e,t){super("word",e,t)}}class U extends Z{constructor(e,t,s,r){super("argument",e,t),this.value=s,this.valid=r}}const Me=n=>{if(n.type==="word")return new me(n.name,n.description);if(n.type==="argument"){const e=n;return new U(e.name,e.description,e.value,e.valid)}return new R},M=n=>n.map(e=>Me(e));class He{constructor(e,t,s=de){C(this,"_segments");C(this,"_description");C(this,"_handler");this._segments=e,this._description=t,this._handler=s}get segments(){return this._segments}get description(){return this._description}get handler(){return this._handler}get hasArguments(){return this.segments.some(e=>e.type==="argument")}get fullPath(){return this.segments.map(e=>e.name)}get fullPath_s(){return this.fullPath.join(" ")}equals(e){return this.fullPath.join(" ")===e.fullPath.join(" ")}}class ${constructor(){C(this,"_commands",[])}get commands(){return this._commands}addCommand(e,t,s=de){if(e===void 0||e.length===0)throw new Error("Command path cannot be empty");const r=new He(e,t,s),a=this._commands.find(i=>{const d=i.segments.map(u=>u.type==="argument"?"*":u.name).join(" "),l=e.map(u=>u.type==="argument"?"*":u.name).join(" ");return d===l});if(a)throw new Error(`Duplicate commands: '${a.fullPath_s}' and '${r.fullPath_s}'`);this._commands.push(r)}removeCommand(e){const t=e.join(" "),s=this._commands.findIndex(r=>r.fullPath.join(" ")===t);return s===-1?!1:(this._commands.splice(s,1),!0)}getCommand(e){return this._commands.find(t=>{const s=t.fullPath.join(" "),r=e.join(" ");if(s===r)return!0;const i=t.segments.filter(d=>d.type==="word").map(d=>d.name);return i.length===e.length&&i.join(" ")===r})}commandExistsForPath(e){const t=this._commands.map(r=>r.segments.map(a=>a.type==="argument"?"*":a.name).join(" ")),s=e.map((r,a)=>this._commands.some(d=>{var l;return((l=d.segments[a])==null?void 0:l.type)==="argument"})?"*":r).join(" ");return t.includes(s)}getCompletionNames(e){return this.getCompletions(e).map(t=>t.name)}getMatchingCompletions(e,t){const s=t.trim().toLowerCase(),r=this.getCompletions(e);return s?r.filter(a=>a.name.toLowerCase().startsWith(s)):r}getUniqueCompletion(e,t){const s=this.getMatchingCompletions(e,t);if(s.length===1)return s[0]}getCompletions(e){if(k.debug("[getCompletions] path: ",e),!e.length){const a=this._commands.map(l=>l.segments[0]),i=(l,u)=>l.type===u.type&&l.name===u.name;return a.filter((l,u,y)=>u===y.findIndex(p=>i(p,l)))}const t=e.length;return this._commands.filter(a=>{const i=a.segments;if(i.length<=t-1)return!1;for(let d=0;d<t;d++){const l=e[d],u=i[d];if(!(l==="*"&&u.type==="argument")&&l!==u.name)return!1}return!0}).filter(a=>a.segments.length>t).map(a=>{const i=a.segments[t],d=i.type==="argument"?U:me;return new d(i.name,i.description)}).filter((a,i,d)=>i===d.findIndex(l=>l.type===a.type&&l.name===a.name))}hasNextSegment(e){return this.getCompletions(e).length>0}}class ue{constructor(e){C(this,"config");this.config={type:"localStorage",maxCommands:100,...e}}async addStoredCommand(e){const t=await this.getStoredCommands();for(t.push(e);t.length>this.config.maxCommands;)t.shift();await this.saveCommands(t)}}class _e extends ue{constructor(t){super(t);C(this,"storageKey","citadel_command_history")}async getStoredCommands(){try{const t=window.localStorage.getItem(this.storageKey);return t?JSON.parse(t).map(r=>({commandSegments:Array.isArray(r.commandSegments)?M(r.commandSegments):[],timestamp:r.timestamp})):[]}catch(t){return console.warn("Failed to load commands from localStorage:",t),[]}}async clear(){try{window.localStorage.removeItem(this.storageKey)}catch(t){console.warn("Failed to clear localStorage:",t)}}async saveCommands(t){try{const s=t.map(r=>({commandSegments:Array.isArray(r.commandSegments)?M(r.commandSegments).map(a=>({type:a.type,name:a.name,description:a.description,...a instanceof U?{value:a.value}:{}})):[],timestamp:r.timestamp}));window.localStorage.setItem(this.storageKey,JSON.stringify(s))}catch(s){throw console.warn("Failed to save commands to localStorage:",s),s}}}class pe extends ue{constructor(t){super(t);C(this,"storedCommands",[])}async getStoredCommands(){return this.storedCommands.map(t=>({commandSegments:Array.isArray(t.commandSegments)?M(t.commandSegments):[],timestamp:t.timestamp}))}async clear(){this.storedCommands=[]}async saveCommands(t){this.storedCommands=t.map(s=>({commandSegments:Array.isArray(s.commandSegments)?M(s.commandSegments):[],timestamp:s.timestamp}))}}const z=class z{constructor(){C(this,"currentStorage")}static reset(){z.instance=void 0}static getInstance(){return z.instance||(z.instance=new z),z.instance}initializeStorage(e){try{e.type==="memory"?this.currentStorage=new pe(e):this.currentStorage=new _e(e)}catch(t){console.warn("Failed to create storage, falling back to memory storage:",t),this.currentStorage=new pe(e)}}getStorage(){if(!this.currentStorage)throw new Error("Storage not initialized. Call initializeStorage first.");return this.currentStorage}};C(z,"instance");let B=z;class he{constructor(){C(this,"segments",[]);C(this,"nullSegment",new R);C(this,"observers",[])}subscribe(e){this.observers.push(e)}unsubscribe(e){this.observers=this.observers.filter(t=>t!==e)}notifyObservers(){this.observers.forEach(e=>e.update())}clear(){this.segments=[],this.notifyObservers()}push(e){this.segments.push(e),this.notifyObservers()}pushAll(e){e.forEach(t=>this.push(t))}pop(){const e=this.segments.pop()||this.nullSegment;return this.notifyObservers(),e}peek(){return this.segments[this.segments.length-1]||this.nullSegment}size(){return this.segments.length}isEmpty(){return this.segments.length===0}get hasArguments(){return this.segments.some(e=>e.type==="argument")}get arguments(){return this.segments.filter(e=>e.type==="argument")}path(){return this.segments.map(e=>e.name)}toArray(){return[...this.segments]}}const Te={config:I,commands:new $,segmentStack:new he},q=o.createContext(Te),ze=({config:n=I,commandRegistry:e,children:t})=>{const[s,r]=o.useState(),[a]=o.useState(()=>new he),i=o.useMemo(()=>({...I,...n,storage:{...I.storage,...n.storage},cursorType:n.cursorType??I.cursorType,cursorColor:n.cursorColor??I.cursorColor,cursorSpeed:n.cursorSpeed??I.cursorSpeed,showCitadelKey:n.showCitadelKey||"."}),[n]);o.useEffect(()=>{B.getInstance().initializeStorage(i.storage??I.storage),r(B.getInstance().getStorage())},[i.storage]),o.useEffect(()=>{if(e){if(i.includeHelpCommand){if(!e.commandExistsForPath(["help"])){const l=Pe(e);e.addCommand([{type:"word",name:"help"}],"Show available commands",l)}return}e.removeCommand(["help"])}},[e,i.includeHelpCommand]);const d=o.useMemo(()=>({config:i,commands:e||new $,storage:s,segmentStack:a}),[i,e,s,a]);return c.jsx(q.Provider,{value:d,children:t})},T=()=>{const n=o.useContext(q);if(n===void 0)throw new Error("useCitadelConfig must be used within a CitadelConfigProvider");return n.config},V=()=>{const n=o.useContext(q);if(n===void 0)throw new Error("useCitadelCommands must be used within a CitadelConfigProvider");return n.commands},ge=()=>{const n=o.useContext(q);if(n===void 0)throw new Error("useCitadelStorage must be used within a CitadelConfigProvider");return n.storage},W=()=>{const n=o.useContext(q);if(n===void 0)throw new Error("useSegmentStack must be used within a CitadelConfigProvider");return n.segmentStack},G=class G{constructor(e,t){C(this,"id");C(this,"timestamp");C(this,"command");C(this,"result");this.id=`output-${Date.now()}-${G.idCounter++}`,this.command=e.toArray().map(s=>s.type==="argument"?s.value||"":s.name),this.timestamp=Date.now(),this.result=t??new ie}};C(G,"idCounter",0);let Y=G;function De(n){return{commandSegments:M(n),timestamp:Date.now()}}function fe(){const n=ge(),[e,t]=o.useState({storedCommands:[],position:null}),s=o.useCallback(async d=>{if(n)try{const l=De(d);await n.addStoredCommand(l),t(u=>({...u,storedCommands:[...u.storedCommands,{...l,commandSegments:M(l.commandSegments)}],position:null}))}catch(l){console.warn("Failed to save command to history:",l)}},[n]),r=o.useCallback(async()=>n?(await n.getStoredCommands()).map(l=>({...l,commandSegments:M(l.commandSegments)})):[],[n]);o.useEffect(()=>{if(!n)return;(async()=>{try{const u=(await n.getStoredCommands()).map(y=>({...y,commandSegments:M(y.commandSegments)}));return t(y=>({...y,storedCommands:u})),u}catch(l){console.warn("Failed to load command history:",l)}})()},[n]);const a=o.useCallback(async d=>{const l=await r();if(l.length===0)return t(p=>({...p,storedCommands:[],position:null})),{segments:null,position:null};let u=null;if(d==="up"?e.position===null?u=l.length-1:e.position>0?u=e.position-1:u=0:e.position===null||e.position>=l.length-1?u=null:u=e.position+1,t(p=>({...p,storedCommands:l.map(g=>({...g,commandSegments:M(g.commandSegments)})),position:u})),u===null)return{segments:[],position:null};const y=l[u];return y?{segments:M(y.commandSegments),position:u}:{segments:[],position:null}},[e.position,r]),i=o.useCallback(async()=>{try{if(!n)return;await n.clear(),t({storedCommands:[],position:null})}catch(d){console.warn("Failed to clear command history:",d)}},[n]);return{history:e,addStoredCommand:s,getStoredCommands:r,navigateHistory:a,clear:i}}const ee=()=>{const n=T(),e=V(),t=fe(),s=W(),r=ge(),[a,i]=o.useState({currentInput:"",isEnteringArg:!1,output:[],history:{commands:[],position:null,storage:r}});o.useEffect(()=>{},[r]),o.useEffect(()=>{i(l=>({...l,history:{commands:t.history.storedCommands,position:t.history.position,storage:r}}))},[t.history,r]);const d={setCurrentInput:o.useCallback(l=>{k.debug("[CitadelActions] setCurrentInput: ",l),i(u=>({...u,currentInput:l}))},[]),setIsEnteringArg:o.useCallback(l=>{k.debug("[CitadelActions] setIsEnteringArg: ",l),i(u=>({...u,isEnteringArg:l}))},[]),addOutput:o.useCallback(l=>{k.debug("[CitadelActions]addOutput: ",l),i(u=>({...u,output:[...u.output,l]}))},[]),executeCommand:o.useCallback(async()=>{const l=s.path(),u=e.getCommand(l);if(!u){console.error("[CitadelActions][executeCommand] Cannot execute command because no command was found for the given path: ",l);return}const y=new Y(s);i(p=>({...p,output:[...p.output,y]}));try{const p=new Promise((w,S)=>{setTimeout(()=>{S(new Error("Request timed out"))},n.commandTimeoutMs)}),g=s.arguments.map(w=>w.value||""),x=await Promise.race([u.handler(g),p]);if(!(x instanceof j))throw new Error(`The ${l.join(".")} command returned an invalid result type. Commands must return an instance of a CommandResult.
4
4
  For example:
5
5
  return new JsonCommandResult({ text: "Hello World" });
6
- Check the definition of the ${i.join(".")} command and update the return type for its handler.`);v.markSuccess(),d(h=>({...h,output:h.output.map(E=>E.id===p.id?{...E,result:v}:E)}))}catch(g){const k=new J(g instanceof Error?g.message:"Unknown error");k.markFailure(),d(v=>({...v,output:v.output.map(h=>h.id===p.id?{...h,result:k}:h)}))}},[e,r.commandTimeoutMs,t]),clearHistory:s.useCallback(async()=>{try{await n.clear()}catch(i){console.warn("Failed to clear history:",i)}},[n])};return{state:l,actions:m}},Ee=({onOpen:r,onClose:e,isVisible:n,showCitadelKey:t})=>{s.useEffect(()=>{const o=l=>{var d,m;!n&&l.key===t&&!["input","textarea"].includes(((m=(d=l.target)==null?void 0:d.tagName)==null?void 0:m.toLowerCase())||"")&&(l.preventDefault(),r()),n&&l.key==="Escape"&&(l.preventDefault(),e())};return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[r,e,n,t])},se={panelContainer:"_panelContainer_1pav9_3",innerContainer:"_innerContainer_1pav9_19",inputSection:"_inputSection_1pav9_29",resizeHandle:"_resizeHandle_1pav9_36",citadel_slideUp:"_citadel_slideUp_1pav9_65",citadel_slideDown:"_citadel_slideDown_1pav9_69",inlineContainer:"_inlineContainer_1pav9_73"},Ne=r=>{const{isVisible:e,isClosing:n,onAnimationComplete:t}=r,o=s.useMemo(()=>e?n?se.slideDown:se.slideUp:"",[e,n]);return s.useEffect(()=>{if(t){const d=setTimeout(()=>{t()},200);return()=>clearTimeout(d)}},[n,t]),{style:s.useMemo(()=>({opacity:e?1:0,transform:e?"translateY(0)":n?"translateY(100%)":"translateY(-100%)",transition:"opacity 200ms ease-in-out, transform 200ms ease-in-out"}),[e,n]),animationClass:o}},_e=()=>a.jsx("div",{"data-testid":"spinner",className:"animate-spin rounded-full h-4 w-4 border-2 border-gray-300 border-t-gray-600"}),Ae=({command:r,timestamp:e,status:n})=>a.jsxs("div",{className:"flex items-center gap-2 font-mono text-sm",children:[a.jsxs("span",{className:"text-gray-200",children:["> ",r.split(" ").map((t,o)=>{const l=t.startsWith("<")&&t.endsWith(">");return a.jsxs("span",{className:l?"text-green-400":"text-gray-200",children:[o>0?" ":"",t]},o)})]}),a.jsx("span",{className:"text-gray-400",children:"·"}),a.jsx("span",{className:"text-gray-500",children:e}),n===H.Pending&&a.jsx(_e,{}),n===H.Success&&a.jsx("div",{"data-testid":"success-indicator",className:"w-4 h-4 rounded-full bg-green-500"}),(n===H.Timeout||n===H.Failure)&&a.jsx("div",{"data-testid":"success-indicator",className:"w-4 h-4 rounded-full bg-red-500"})]}),Ie=({output:r,outputRef:e})=>{const n=T(),t=s.useCallback(()=>{if(e.current){const o=e.current;requestAnimationFrame(()=>{o.scrollTop=o.scrollHeight})}},[e]);return s.useEffect(()=>{if(t(),e.current){const o=e.current.getElementsByTagName("img"),l=o[o.length-1];if(l&&!l.complete)return l.addEventListener("load",t),()=>l.removeEventListener("load",t)}},[r,t,e]),a.jsx("div",{ref:e,className:"h-full overflow-y-auto border border-gray-700 rounded-lg p-3 text-left","data-testid":"citadel-command-output",children:r.map(o=>a.jsxs("div",{className:"mb-4 last:mb-0",children:[a.jsx(Ae,{command:o.command.join(" "),timestamp:new Date(o.timestamp).toLocaleTimeString(),status:o.result.status}),a.jsx("pre",{className:`text-gray-200 whitespace-pre font-mono ${n.outputFontSize}`,children:o.result.render()})]},o.id))})},ae={blink:{character:"▋",speed:530,color:"#fff"},spin:{character:"⠋",speed:120,color:"#fff"},solid:{character:"▋",speed:0,color:"#fff"},bbs:{character:"|",speed:120,color:"#fff"}},ie=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],le=["|","/","-","\\"],ze=({style:r={type:"blink"},isValid:e=!0,errorMessage:n})=>{const t=s.useMemo(()=>({...ae[r.type],...r}),[r]),[o,l]=s.useState(!0),[d,m]=s.useState(0);s.useEffect(()=>{if(t.speed===0)return;const p=setInterval(()=>{t.type==="blink"?l(g=>!g):["spin","bbs"].includes(t.type)&&m(g=>(g+1)%(t.type==="bbs"?le.length:ie.length))},t.speed);return()=>clearInterval(p)},[t.type,t.speed]);const i=s.useMemo(()=>({color:e?t.color:"#ff4444",transition:"color 0.15s ease-in-out"}),[e,t.color]),c=()=>!e&&n?"✗":["spin","bbs"].includes(t.type)?(t.type==="bbs"?le:ie)[d]:t.type==="solid"||o?t.character:" ";return a.jsx("div",{className:"relative inline-block",children:a.jsx("span",{className:`command-cursor ${e?"":"animate-shake"}`,style:i,title:n,children:c()})})};function Pe(r,e){switch(e.type){case"set":return S.debug(`[inputStateReducer] InputState changing from ${r} to ${e.state}`),e.state;default:return r}}const He=()=>{const{state:r}=G(),e=q(),n=oe(),t=U(),[o,l]=s.useReducer(Pe,"idle"),d=u=>{l({type:"set",state:u})},m=s.useCallback(()=>{const w=e.getCompletions(t.path())[0]||t.nullSegment;return S.debug("[getNextExpectedSegment] ",w),w},[e,t]),i=s.useCallback(()=>e.getCompletionNames(t.path()).map(w=>e.getCommand([...t.path(),w])).filter(w=>w!==void 0),[e,t]),c=s.useCallback((u,w)=>{if(!u)return w;const b=t.path().length;return w.filter(C=>{const f=C.segments[b];return!f||f.type!=="word"?!1:f.name.toLowerCase().startsWith(u.toLowerCase())})},[t]),p=s.useCallback(u=>{const b=e.getCompletions(t.path()).filter(C=>C.type==="word").filter(C=>C.name.toLowerCase().startsWith(u.toLowerCase()));return b.length===1?b[0]:t.nullSegment},[e,t]),g=s.useCallback(u=>{const w=t.path(),b=e.getCompletions(w);return b.length===0&&u?!1:b.some(f=>f.type==="argument")?!0:b.some(f=>f.type==="word"&&f.name.toLowerCase().startsWith(u.toLowerCase()))},[e,t]),k=s.useCallback(u=>{S.debug("[tryAutoComplete] input: ",u);const w=p(u);return!w||w.name===u?new ne:(S.debug("[tryAutoComplete] result: ",w),w)},[p]),v=s.useCallback((u,w)=>{if(r.history.position===null){if(w.setCurrentInput(u),S.debug("[useCommandParser][handleInputChange] newValue: ",u),o==="entering_argument"){const b=ce(u);if(b.isQuoted)if(b.isComplete){const C=m();if(!(C instanceof $))return;C.value=u.trim()||"",S.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",C),t.push(C),w.setCurrentInput(""),d("idle");return}else return;else if(b.isComplete){const C=m();if(!(C instanceof $))return;C.value=u.trim()||"",S.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",C),t.push(C),w.setCurrentInput(""),d("idle");return}else return}if(o==="entering_command"){const b=k(u);if(b.type==="word"){S.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",b),t.push(b),w.setCurrentInput(""),d("idle");return}}}},[k,r,m,o,t]),h=s.useCallback(u=>{u.setCurrentInput(""),u.setIsEnteringArg(!1),t.clear(),d("idle")},[t]),E=s.useCallback((u,w,b)=>{if(!(u.key==="Backspace"||u.key==="Enter"||u.key==="ArrowUp"||u.key==="ArrowDown"||u.key==="ArrowLeft"||u.key==="ArrowRight"||u.key==="Escape"||u.key==="Delete"||u.key==="Home"||u.key==="End"||u.key.length===1))return!0;const{currentInput:f,isEnteringArg:_}=w,I=ce(f);switch(u.key){case"Backspace":return f===""&&(u.preventDefault(),t.size()>0&&t.pop(),d("idle")),!0;case"Enter":{if(u.preventDefault(),I.isQuoted&&!I.isComplete)return!0;if(o==="entering_argument"||_&&f.trim()){const M=m();M instanceof $&&(M.value=f,S.debug("[handleKeyDown][Enter]['entering_argument'] pushing: ",M),t.push(M))}const A=t.path(),j=e.getCommand(A);if(!j)return!1;const F=j.segments.filter(M=>M.type==="argument"),$e=t.arguments;return F.length>$e.length?!1:(S.debug("[handleKeyDown][Enter] calling actions.executeCommand. segmentStack: ",t),b.executeCommand(),n.addStoredCommand(t.toArray()),h(b),!0)}case"ArrowUp":return u.preventDefault(),(async()=>{const A=await n.navigateHistory("up");return A.segments&&(t.clear(),t.pushAll(A.segments),b.setCurrentInput("")),!0})();case"ArrowDown":return u.preventDefault(),(async()=>{const A=await n.navigateHistory("down");return A.segments&&(t.clear(),t.pushAll(A.segments),b.setCurrentInput("")),!0})();default:{if(!_&&u.key.length===1){const A=f+u.key;if(!g(A))return u.preventDefault(),!1}return!0}}},[o,g,m,n,h,e,t]);return{handleInputChange:v,handleKeyDown:E,inputState:o,setInputStateWithLogging:d,findMatchingCommands:c,getAutocompleteSuggestion:p,getAvailableNodes:i,getNextExpectedSegment:m,isValidCommandInput:g}};function ce(r){const e=[];let n="",t=!1,o;for(let l=0;l<r.length;l++){const d=r[l];(d==='"'||d==="'")&&(!t||d===o)?t?(e.push(n),n="",t=!1,o=void 0):(n&&(e.push(n),n=""),t=!0,o=d):!t&&d===" "?n&&(e.push(n),n=""):n+=d}return{words:e,currentWord:n,isQuoted:t,quoteChar:o,isComplete:!t&&!n}}const Me=()=>{const r=U(),[e,n]=s.useState(0);return s.useEffect(()=>{const t={update:()=>{n(o=>o+1)}};return r.subscribe(t),()=>{r.unsubscribe(t)}},[r]),e},De=({state:r,actions:e})=>{const n=s.useRef(null),t=q(),o=U(),{handleKeyDown:l,handleInputChange:d,inputState:m,setInputStateWithLogging:i,getNextExpectedSegment:c}=He(),[p,g]=s.useState(!1),k=T(),v=Me(),h=async f=>{const _=l(f,r,e);await Promise.resolve(_)===!1&&(g(!0),setTimeout(()=>g(!1),500))},E=f=>{d(f.target.value,e)},u=f=>{f.preventDefault();const _=f.clipboardData.getData("text");d(_,e)};s.useEffect(()=>{n.current&&n.current.focus(),m!=="entering_command"&&i("entering_command")},[m,i]),s.useEffect(()=>{if(m!=="idle")return;const f=c();let _="idle";switch(f.type){case"word":_="entering_command",e.setIsEnteringArg(!1);break;case"argument":_="entering_argument",e.setIsEnteringArg(!0);break}i(_)},[v,m,c,i,e]);const w=s.useMemo(()=>{const f=[],_=o.toArray().map((I,A)=>{f.push(I.name);const j=t.hasNextSegment(f);if(I.type==="argument"){const F=I;return a.jsxs(s.Fragment,{children:[a.jsx("span",{className:"text-gray-200 whitespace-pre",children:F.value}),A<o.size()&&j&&a.jsx("span",{className:"text-gray-200 whitespace-pre",children:" "})]},"arg-"+F.name+F.value)}return a.jsxs(s.Fragment,{children:[a.jsx("span",{className:"text-blue-400 whitespace-pre",children:I.name}),A<o.size()&&j&&a.jsx("span",{className:"text-blue-400 whitespace-pre",children:" "})]},"word-"+I.name)});return[a.jsx("div",{className:"flex items-center gap-1","data-testid":"user-input-area",children:_},"{segmentStackVersion}")]},[v,t,o]),[b,C]=s.useState("");return s.useEffect(()=>{const f=c();f.type==="argument"?C(f.name):C("")},[v,c]),a.jsxs("div",{className:"flex flex-col w-full bg-gray-900 rounded-lg p-4",children:[a.jsx("style",{children:`
7
- @keyframes subtleGlow {
8
- 0%, 100% { box-shadow: 0 0 0 rgba(239, 68, 68, 0); }
9
- 50% { box-shadow: 0 0 8px rgba(239, 68, 68, 0.6); }
10
- }
11
- .invalid-input-animation {
12
- animation: subtleGlow 0.4s ease-in-out;
13
- }
14
- `}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:"text-gray-400 font-mono",children:">"}),a.jsxs("div",{className:"flex-1 font-mono flex items-center",children:[w,a.jsxs("div",{className:"relative flex-1",children:[a.jsx("input",{ref:n,type:"text",role:"textbox",value:r.currentInput,onChange:E,onKeyDown:h,onPaste:u,"data-testid":"citadel-command-input",className:`w-full bg-transparent outline-none text-gray-200 caret-transparent ${p?"invalid-input-animation":""}`,spellCheck:!1,autoComplete:"off",placeholder:b}),a.jsx("div",{className:"absolute top-0 pointer-events-none",style:{left:`${r.currentInput.length}ch`,transition:"left 0.05s ease-out"},children:a.jsx(ze,{style:{type:k.cursorType??N.cursorType,color:k.cursorColor||N.cursorColor,speed:k.cursorSpeed||N.cursorSpeed}})})]})]})]})]})},Te=()=>{const r=q(),e=U(),n="mt-2 border-t border-gray-700 px-4 py-2",t="text-gray-300",o=r.getCompletions(e.path());S.debug("[AvailableCommands] nextCommandSegments: ",o);const l=s.useMemo(()=>{const c=[...o],p=h=>h.name.toLowerCase()==="help",g=c.filter(p);return[...c.filter(h=>!p(h)).sort((h,E)=>h.name.localeCompare(E.name,void 0,{sensitivity:"base"})),...g]},[o]),d=s.useMemo(()=>{const c=new Map;for(const p of l){const g=l.reduce((k,v)=>{if(v===p)return k;let h=0;for(;h<p.name.length&&h<v.name.length&&p.name[h].toLowerCase()===v.name[h].toLowerCase();)h++;return Math.max(k,h+1)},1);c.set(p.name,g)}return c},[l]),m=o.some(c=>c.type==="argument"),i=o[0];return a.jsx("div",{className:n,"data-testid":"available-commands",children:a.jsx("div",{className:t,children:m?o.length>0?a.jsxs(a.Fragment,{children:[a.jsx("span",{className:"text-blue-400",children:i.name}),i.description&&a.jsxs("span",{className:"text-gray-400 ml-2",children:["- ",i.description]})]}):null:a.jsx("div",{className:"flex flex-wrap gap-2",children:l==null?void 0:l.map(c=>{const p=d.get(c.name)??1;return a.jsx("div",{className:"px-2 py-1 rounded bg-gray-800 mr-2 last:mr-0",children:a.jsxs("span",{className:"font-mono text-white",children:[a.jsx("strong",{className:"underline",children:c.name.slice(0,p)}),c.name.slice(p)]})},c.name)})})})})},de=({state:r,actions:e,outputRef:n})=>a.jsxs("div",{className:"innerContainer",children:[a.jsx("div",{className:"flex-1 min-h-0 pt-3 px-4",children:a.jsx(Ie,{output:r.output,outputRef:n})}),a.jsxs("div",{children:[a.jsx(De,{state:r,actions:e}),a.jsx(Te,{})]})]}),Ue=()=>{const[r,e]=s.useState(!1),[n,t]=s.useState(!1),o=T(),[l,d]=s.useState(()=>o.initialHeight||null),m=s.useRef(null),i=s.useRef(null),c=s.useRef(!1),p=s.useRef(0),g=s.useRef(0),{state:k,actions:v}=G();Ee({onOpen:()=>e(!0),onClose:()=>t(!0),isVisible:r,showCitadelKey:o.showCitadelKey||"."});const h=s.useCallback(b=>{var I;if(!c.current)return;const C=b.clientY-p.current,f=(I=o.maxHeight)!=null&&I.endsWith("vh")?window.innerHeight*parseInt(o.maxHeight,10)/100:parseInt(o.maxHeight||"80vh",10),_=Math.min(Math.max(g.current-C,parseInt(o.minHeight||"200",10)),f);i.current&&(i.current.style.height=`${_}px`,i.current.style.bottom="0",d(`${_}px`))},[o.maxHeight,o.minHeight]),E=s.useCallback(()=>{c.current=!1,document.documentElement.style.userSelect="",document.documentElement.style.webkitUserSelect="",document.documentElement.style.mozUserSelect="",document.documentElement.style.msUserSelect="",document.removeEventListener("mousemove",h),document.removeEventListener("mouseup",E)},[h]),u=s.useCallback(b=>{i.current&&(c.current=!0,p.current=b.clientY,g.current=i.current.offsetHeight,document.documentElement.style.userSelect="none",document.documentElement.style.webkitUserSelect="none",document.documentElement.style.mozUserSelect="none",document.documentElement.style.msUserSelect="none",document.addEventListener("mousemove",h),document.addEventListener("mouseup",E))},[h,E]);s.useEffect(()=>()=>{document.removeEventListener("mousemove",h),document.removeEventListener("mouseup",E)},[h,E]);const w=s.useCallback(()=>{n&&(e(!1),t(!1))},[n]);return Ne({isVisible:r,isClosing:n,onAnimationComplete:w}),r?a.jsxs("div",{ref:i,className:`panelContainer ${r?"citadel_slideUp":""} ${n?"citadel_slideDown":""}`,style:{...l?{height:l}:void 0,maxHeight:o.maxHeight},children:[a.jsx("div",{className:"resizeHandle",onMouseDown:u}),a.jsx(de,{state:k,actions:v,outputRef:m})]}):null},je=()=>{const{state:r,actions:e}=G(),n=s.useRef(null);return a.jsx("div",{className:"inlineContainer","data-testid":"citadel-inline-container",children:a.jsx(de,{state:r,actions:e,outputRef:n})})},me=`:host {
15
- --citadel-bg: rgb(17, 24, 39);
16
- --citadel-text: rgba(255, 255, 255, 0.87);
17
- --citadel-border: rgb(55, 65, 81);
18
- --citadel-accent: #646cff;
19
- --citadel-accent-hover: #535bf2;
6
+ Check the definition of the ${l.join(".")} command and update the return type for its handler.`);x.markSuccess(),i(w=>({...w,output:w.output.map(S=>S.id===y.id?{...S,result:x}:S)}))}catch(p){const g=new Q(p instanceof Error?p.message:"Unknown error");g.markFailure(),i(x=>({...x,output:x.output.map(w=>w.id===y.id?{...w,result:g}:w)}))}},[e,n.commandTimeoutMs,s]),clearHistory:o.useCallback(async()=>{try{await t.clear()}catch(l){console.warn("Failed to clear history:",l)}},[t])};return{state:a,actions:d}},Fe=({onOpen:n,onClose:e,isVisible:t,showCitadelKey:s})=>{o.useEffect(()=>{const r=a=>{var i,d;!t&&a.key===s&&!["input","textarea"].includes(((d=(i=a.target)==null?void 0:i.tagName)==null?void 0:d.toLowerCase())||"")&&(a.preventDefault(),n()),t&&a.key==="Escape"&&(a.preventDefault(),e())};return document.addEventListener("keydown",r),()=>document.removeEventListener("keydown",r)},[n,e,t,s])},je=n=>{const{isVisible:e,isClosing:t,onAnimationComplete:s}=n,r=o.useMemo(()=>e?t?"citadel_slideDown":"citadel_slideUp":"",[e,t]);return o.useEffect(()=>{if(s){const i=setTimeout(()=>{s()},200);return()=>clearTimeout(i)}},[t,s]),{style:o.useMemo(()=>({opacity:e?1:0,transform:e?"translateY(0)":t?"translateY(100%)":"translateY(-100%)",transition:"opacity 200ms ease-in-out, transform 200ms ease-in-out"}),[e,t]),animationClass:r}},Le=()=>c.jsx("div",{"data-testid":"spinner",className:"citadel-spinner"}),ye=n=>{const e=n==null?void 0:n.trim();return e||void 0},Ue=n=>{const e=ye(n);return e?{style:{fontSize:e}}:{}},J=(n,e)=>{const t=ye(n),r={...Ue(e).style};return t&&(r.fontFamily=t),{style:Object.keys(r).length>0?r:void 0}},Oe=({command:n,timestamp:e,status:t,fontFamily:s,fontSize:r})=>{const a=o.useMemo(()=>J(s,r??"0.875rem"),[s,r]);return c.jsxs("div",{className:"citadel-output-line",style:a.style,children:[c.jsxs("span",{className:"citadel-output-command",children:["> ",n.split(" ").map((i,d)=>{const l=i.startsWith("<")&&i.endsWith(">");return c.jsxs("span",{className:l?"citadel-output-command-arg":"citadel-output-command-word",children:[d>0?" ":"",i]},d)})]}),c.jsx("span",{className:"citadel-output-separator",children:"·"}),c.jsx("span",{className:"citadel-output-timestamp",children:e}),t===L.Pending&&c.jsx(Le,{}),t===L.Success&&c.jsx("div",{"data-testid":"success-indicator",className:"citadel-status-dot citadel-status-dot-success"}),(t===L.Timeout||t===L.Failure)&&c.jsx("div",{"data-testid":"success-indicator",className:"citadel-status-dot citadel-status-dot-failure"})]})},$e=({output:n,outputRef:e})=>{const t=T(),s=o.useMemo(()=>J(t.fontFamily,t.outputFontSize??t.fontSize),[t.fontFamily,t.fontSize,t.outputFontSize]),r=o.useCallback(()=>{if(e.current){const a=e.current;requestAnimationFrame(()=>{a.scrollTop=a.scrollHeight})}},[e]);return o.useEffect(()=>{if(r(),e.current){const a=e.current.getElementsByTagName("img"),i=a[a.length-1];if(i&&!i.complete)return i.addEventListener("load",r),()=>i.removeEventListener("load",r)}},[n,r,e]),c.jsx("div",{ref:e,className:"citadel-output","data-testid":"citadel-command-output",children:n.map(a=>c.jsxs("div",{className:"citadel-output-item",children:[c.jsx(Oe,{command:a.command.join(" "),timestamp:new Date(a.timestamp).toLocaleTimeString(),status:a.result.status,fontFamily:t.fontFamily,fontSize:t.fontSize}),c.jsx("div",{className:"citadel-output-content",style:s.style,children:a.result.render()})]},a.id))})},Ce={blink:{character:"▋",speed:530,color:"#fff"},spin:{character:"⠋",speed:120,color:"#fff"},solid:{character:"▋",speed:0,color:"#fff"},bbs:{character:"|",speed:120,color:"#fff"}},we=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],ve=["|","/","-","\\"],qe=({style:n={type:"blink"},isValid:e=!0,errorMessage:t})=>{const s=o.useMemo(()=>({...Ce[n.type],...n}),[n]),[r,a]=o.useState(!0),[i,d]=o.useState(0);o.useEffect(()=>{if(s.speed===0)return;const y=setInterval(()=>{s.type==="blink"?a(p=>!p):["spin","bbs"].includes(s.type)&&d(p=>(p+1)%(s.type==="bbs"?ve.length:we.length))},s.speed);return()=>clearInterval(y)},[s.type,s.speed]);const l=o.useMemo(()=>({color:e?s.color:"#ff4444",transition:"color 0.15s ease-in-out"}),[e,s.color]),u=()=>!e&&t?"✗":["spin","bbs"].includes(s.type)?(s.type==="bbs"?ve:we)[i]:s.type==="solid"||r?s.character:" ";return c.jsx("div",{className:"citadel-cursor-wrapper",children:c.jsx("span",{className:`command-cursor ${e?"":"animate-shake"}`,style:l,title:t,children:u()})})};function We(n,e){switch(e.type){case"set":return k.debug(`[inputStateReducer] InputState changing from ${n} to ${e.state}`),e.state;default:return n}}const Ke=()=>{const{state:n}=ee(),e=V(),t=fe(),s=W(),[r,a]=o.useReducer(We,"idle"),i=m=>{a({type:"set",state:m})},d=o.useCallback(()=>{const h=e.getCompletions(s.path())[0]||s.nullSegment;return k.debug("[getNextExpectedSegment] ",h),h},[e,s]),l=o.useCallback(()=>e.getCompletionNames(s.path()).map(h=>e.getCommand([...s.path(),h])).filter(h=>h!==void 0),[e,s]),u=o.useCallback((m,h)=>{if(!m)return h;const v=s.path().length;return h.filter(H=>{const b=H.segments[v];return!b||b.type!=="word"?!1:b.name.toLowerCase().startsWith(m.toLowerCase())})},[s]),y=o.useCallback(m=>{const h=e.getUniqueCompletion(s.path(),m);return h&&h.type==="word"?h:s.nullSegment},[e,s]),p=o.useCallback(m=>{const h=s.path(),v=e.getCompletions(h);return v.length===0&&m?!1:v.some(b=>b.type==="argument")?!0:e.getMatchingCompletions(h,m).some(b=>b.type==="word")},[e,s]),g=o.useCallback(m=>{k.debug("[tryAutoComplete] input: ",m);const h=y(m);return!h||h.type==="null"?new R:(k.debug("[tryAutoComplete] result: ",h),h)},[y]),x=o.useCallback((m,h)=>{if(n.history.position!==null)return;h.setCurrentInput(m),k.debug("[useCommandParser][handleInputChange] newValue: ",m);const v=d();if(v.type==="argument"||r==="entering_argument"){const A=Se(m);if(A.isQuoted)if(A.isComplete){if(!(v instanceof U))return;v.value=m.trim()||"",k.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",v),s.push(v),h.setCurrentInput(""),i("idle");return}else return;else if(A.isComplete){if(!(v instanceof U))return;v.value=m.trim()||"",k.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",v),s.push(v),h.setCurrentInput(""),i("idle");return}else return}if(m.endsWith(" ")){const A=m.trim().toLowerCase(),_=e.getCompletions(s.path()).filter(E=>E.type==="word"&&E.name.toLowerCase()===A);if(_.length===1){s.push(_[0]),h.setCurrentInput(""),i("idle");return}}const b=g(m);if(b.type==="word"){k.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",b),s.push(b),h.setCurrentInput(""),i("idle");return}},[g,n,d,r,s,e]),w=o.useCallback(m=>{m.setCurrentInput(""),m.setIsEnteringArg(!1),s.clear(),i("idle")},[s]),S=o.useCallback((m,h,v)=>{if(!(m.key==="Backspace"||m.key==="Enter"||m.key==="ArrowUp"||m.key==="ArrowDown"||m.key==="ArrowLeft"||m.key==="ArrowRight"||m.key==="Escape"||m.key==="Delete"||m.key==="Home"||m.key==="End"||m.key.length===1))return!0;const{currentInput:b,isEnteringArg:A}=h,_=Se(b);switch(m.key){case"Backspace":return b===""&&(m.preventDefault(),s.size()>0&&s.pop(),i("idle")),!0;case"Enter":{if(m.preventDefault(),_.isQuoted&&!_.isComplete)return!0;if(r==="entering_argument"||A&&b.trim()){const D=d();D instanceof U&&(D.value=b,k.debug("[handleKeyDown][Enter]['entering_argument'] pushing: ",D),s.push(D))}const E=s.path(),ne=e.getCommand(E);if(!ne)return!1;const K=ne.segments.filter(D=>D.type==="argument"),se=s.arguments;return K.length>se.length?!1:(k.debug("[handleKeyDown][Enter] calling actions.executeCommand. segmentStack: ",s),v.executeCommand(),t.addStoredCommand(s.toArray()),w(v),!0)}case"ArrowUp":return m.preventDefault(),(async()=>{const E=await t.navigateHistory("up");return E.segments&&(s.clear(),s.pushAll(E.segments),v.setCurrentInput("")),!0})();case"ArrowDown":return m.preventDefault(),(async()=>{const E=await t.navigateHistory("down");return E.segments&&(s.clear(),s.pushAll(E.segments),v.setCurrentInput("")),!0})();default:{if(!A&&m.key.length===1){const E=b+m.key;if(!p(E))return m.preventDefault(),!1}return!0}}},[r,p,d,t,w,e,s]);return{handleInputChange:x,handleKeyDown:S,inputState:r,setInputStateWithLogging:i,findMatchingCommands:u,getAutocompleteSuggestion:y,getAvailableNodes:l,getNextExpectedSegment:d,isValidCommandInput:p}};function Se(n){const e=[];let t="",s=!1,r;for(let a=0;a<n.length;a++){const i=n[a];(i==='"'||i==="'")&&(!s||i===r)?s?(e.push(t),t="",s=!1,r=void 0):(t&&(e.push(t),t=""),s=!0,r=i):!s&&i===" "?t&&(e.push(t),t=""):t+=i}return{words:e,currentWord:t,isQuoted:s,quoteChar:r,isComplete:!s&&!t}}const Be=()=>{const n=W(),[e,t]=o.useState(0);return o.useEffect(()=>{const s={update:()=>{t(r=>r+1)}};return n.subscribe(s),()=>{n.unsubscribe(s)}},[n]),e},Ve=({state:n,actions:e})=>{const t=o.useRef(null),s=V(),r=W(),{handleKeyDown:a,handleInputChange:i,inputState:d,setInputStateWithLogging:l,getNextExpectedSegment:u}=Ke(),[y,p]=o.useState(!1),g=T(),x=Be(),w=o.useRef(null),[S,m]=o.useState(0),h=o.useMemo(()=>J(g.fontFamily,g.fontSize),[g.fontFamily,g.fontSize]),v=o.useCallback(async N=>{const P=a(N,n,e);await Promise.resolve(P)===!1&&(p(!0),setTimeout(()=>p(!1),500))},[e,a,n]),H=o.useCallback(N=>{i(N.target.value,e)},[e,i]),b=o.useCallback(N=>{N.preventDefault();const P=N.clipboardData.getData("text");i(P,e)},[e,i]);o.useEffect(()=>{t.current&&t.current.focus(),d!=="entering_command"&&l("entering_command")},[d,l]),o.useEffect(()=>{if(d!=="idle")return;const N=u();let P="idle";switch(N.type){case"word":P="entering_command",e.setIsEnteringArg(!1);break;case"argument":P="entering_argument",e.setIsEnteringArg(!0);break}l(P)},[x,d,u,l,e]);const A=o.useMemo(()=>{const N=[],P=r.toArray().map((F,re)=>{N.push(F.name);const Ie=s.hasNextSegment(N);if(F.type==="argument"){const oe=F;return c.jsxs(o.Fragment,{children:[c.jsx("span",{className:"citadel-input-segment-arg",children:oe.value}),re<r.size()&&Ie&&c.jsx("span",{className:"citadel-input-segment-space",children:" "})]},"arg-"+oe.name+oe.value)}return c.jsxs(o.Fragment,{children:[c.jsx("span",{className:"citadel-input-segment-word",children:F.name}),re<r.size()&&Ie&&c.jsx("span",{className:"citadel-input-segment-space citadel-input-segment-space-command",children:" "})]},"word-"+F.name)});return[c.jsx("div",{className:"citadel-input-segments","data-testid":"user-input-area",children:P},x)]},[x,s,r]),[_,E]=o.useState("");o.useEffect(()=>{const N=u();N.type==="argument"?E(N.name):E("")},[x,u]);const K=!n.isEnteringArg?"is-command-mode":"is-argument-mode",se=o.useMemo(()=>({left:`${S}px`,transition:"left 0.05s ease-out"}),[S]),D=o.useMemo(()=>({type:g.cursorType??I.cursorType,color:g.cursorColor||I.cursorColor,speed:g.cursorSpeed||I.cursorSpeed}),[g.cursorColor,g.cursorSpeed,g.cursorType]);return o.useLayoutEffect(()=>{const N=w.current,P=t.current;if(!N||!P){m(0);return}const F=N.getBoundingClientRect().width;m(Math.max(0,F-P.scrollLeft))},[n.currentInput,K,h.style]),c.jsx("div",{className:"citadel-input-shell",children:c.jsxs("div",{className:"citadel-input-line",style:h.style,children:[c.jsx("div",{className:"citadel-input-prompt",children:">"}),c.jsxs("div",{className:"citadel-input-row",children:[A,c.jsxs("div",{className:"citadel-input-control",children:[c.jsx("span",{ref:w,className:`citadel-input-measure ${K}`.trim(),"aria-hidden":"true",children:n.currentInput}),c.jsx("input",{ref:t,type:"text",role:"textbox",value:n.currentInput,onChange:H,onKeyDown:v,onPaste:b,"data-testid":"citadel-command-input",className:`citadel-input-field ${K} ${y?"invalid-input-animation":""}`.trim(),spellCheck:!1,autoComplete:"off",placeholder:_}),c.jsx("div",{className:"citadel-input-cursor",style:se,children:c.jsx(qe,{style:D})})]})]})]})})},Ye=({currentInput:n=""})=>{const e=V(),t=T(),s=W(),r=o.useMemo(()=>J(t.fontFamily,t.fontSize),[t.fontFamily,t.fontSize]),a=n.trim().toLowerCase(),i=e.getMatchingCompletions(s.path(),a);k.debug("[AvailableCommands] nextCommandSegments: ",i);const d=o.useMemo(()=>{const p=[...i],g=m=>m.name.toLowerCase()==="help",x=p.filter(g);return[...p.filter(m=>!g(m)).sort((m,h)=>m.name.localeCompare(h.name,void 0,{sensitivity:"base"})),...x]},[i]),l=o.useMemo(()=>{const p=new Map;for(const g of d){const x=d.reduce((w,S)=>{if(S===g)return w;let m=0;for(;m<g.name.length&&m<S.name.length&&g.name[m].toLowerCase()===S.name[m].toLowerCase();)m++;return Math.max(w,m+1)},1);p.set(g.name,x)}return p},[d]),u=i.some(p=>p.type==="argument"),y=i[0];return c.jsx("div",{className:"citadel-available-commands","data-testid":"available-commands",children:c.jsx("div",{className:"citadel-available-commands-content",style:r.style,children:u?i.length>0?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"citadel-available-next-arg",children:y.name}),y.description&&c.jsxs("span",{className:"citadel-available-next-desc",children:["- ",y.description]})]}):null:c.jsx("div",{className:"citadel-available-chip-list",children:d==null?void 0:d.map(p=>{const g=l.get(p.name)??1;return c.jsx("div",{"data-testid":"available-command-chip",className:"citadel-available-chip",children:c.jsxs("span",{className:"citadel-available-chip-text",children:[c.jsx("strong",{className:"citadel-available-chip-prefix",children:p.name.slice(0,g)}),p.name.slice(g)]})},p.name)})})})})},be=({state:n,actions:e,outputRef:t})=>{const r=T().displayMode==="inline",a=o.useMemo(()=>r?{overflow:"hidden"}:void 0,[r]);return c.jsxs("div",{className:"innerContainer citadel-tty",children:[c.jsx("div",{className:"citadel-tty-output-pane","data-testid":"citadel-output-pane",style:a,children:c.jsx($e,{output:n.output,outputRef:t})}),c.jsxs("div",{className:"citadel-tty-input-region",children:[c.jsx(Ve,{state:n,actions:e}),c.jsx(Ye,{currentInput:n.isEnteringArg?"":n.currentInput})]})]})},Je=()=>{const[n,e]=o.useState(!1),[t,s]=o.useState(!1),r=T(),[a,i]=o.useState(()=>r.initialHeight||null),d=o.useRef(null),l=o.useRef(null),u=o.useRef(!1),y=o.useRef(0),p=o.useRef(0),{state:g,actions:x}=ee();Fe({onOpen:()=>e(!0),onClose:()=>s(!0),isVisible:n,showCitadelKey:r.showCitadelKey||"."});const w=o.useCallback(H=>{var E;if(!u.current)return;const b=H.clientY-y.current,A=(E=r.maxHeight)!=null&&E.endsWith("vh")?window.innerHeight*parseInt(r.maxHeight,10)/100:parseInt(r.maxHeight||"80vh",10),_=Math.min(Math.max(p.current-b,parseInt(r.minHeight||"200",10)),A);l.current&&(l.current.style.height=`${_}px`,l.current.style.bottom="0",i(`${_}px`))},[r.maxHeight,r.minHeight]),S=o.useCallback(()=>{u.current=!1,document.documentElement.style.userSelect="",document.documentElement.style.webkitUserSelect="",document.documentElement.style.mozUserSelect="",document.documentElement.style.msUserSelect="",document.removeEventListener("mousemove",w),document.removeEventListener("mouseup",S)},[w]),m=o.useCallback(H=>{l.current&&(u.current=!0,y.current=H.clientY,p.current=l.current.offsetHeight,document.documentElement.style.userSelect="none",document.documentElement.style.webkitUserSelect="none",document.documentElement.style.mozUserSelect="none",document.documentElement.style.msUserSelect="none",document.addEventListener("mousemove",w),document.addEventListener("mouseup",S))},[w,S]);o.useEffect(()=>()=>{document.removeEventListener("mousemove",w),document.removeEventListener("mouseup",S)},[w,S]);const h=o.useCallback(()=>{t&&(e(!1),s(!1))},[t]);je({isVisible:n,isClosing:t,onAnimationComplete:h});const v=o.useMemo(()=>({...a?{height:a}:{},maxHeight:r.maxHeight}),[r.maxHeight,a]);return n?c.jsxs("div",{ref:l,className:`panelContainer ${n?"citadel_slideUp":""} ${t?"citadel_slideDown":""}`,style:v,children:[c.jsx("div",{className:"resizeHandle",onMouseDown:m}),c.jsx(be,{state:g,actions:x,outputRef:d})]}):null},te=n=>{if(!n)return;const e=n.trim();if(e)return/^\d+(\.\d+)?$/.test(e)?`${e}px`:e},Ge=()=>{const{state:n,actions:e}=ee(),t=T(),s=o.useRef(null),r=o.useMemo(()=>({height:te(t.initialHeight),maxHeight:te(t.maxHeight),minHeight:te(t.minHeight)}),[t.initialHeight,t.maxHeight,t.minHeight]);return c.jsx("div",{className:"inlineContainer","data-testid":"citadel-inline-container",style:r,children:c.jsx(be,{state:n,actions:e,outputRef:s})})},xe=`:host {
7
+ --citadel-bg: oklch(20.8% 0.042 265.8);
8
+ --citadel-surface: oklch(27.9% 0.041 260);
9
+ --citadel-border: oklch(37.2% 0.044 257.3);
10
+ --citadel-text: oklch(92.8% 0.006 264.5);
11
+ --citadel-muted: oklch(70.7% 0.022 261.3);
12
+ --citadel-subtle: oklch(55.1% 0.023 264.4);
13
+ --citadel-word: oklch(70.7% 0.165 254.6);
14
+ --citadel-arg: oklch(72.3% 0.219 149.6);
15
+ --citadel-error: oklch(70.4% 0.191 22.2);
16
+ --citadel-success: oklch(72.3% 0.219 149.6);
20
17
  --citadel-min-height: 200px;
21
18
  --citadel-max-height: 80vh;
22
19
  --citadel-default-height: 35vh;
23
- --citadel-error: rgb(239, 68, 68);
24
20
 
25
21
  display: block;
26
22
  pointer-events: auto;
23
+ color: var(--citadel-text);
27
24
  font-synthesis: none;
28
25
  text-rendering: optimizeLegibility;
29
26
  -webkit-font-smoothing: antialiased;
30
27
  -moz-osx-font-smoothing: grayscale;
31
28
  }
32
29
 
33
- :host([data-display-mode="panel"]) {
30
+ :host([data-display-mode='panel']) {
34
31
  position: fixed;
35
32
  bottom: 0;
36
33
  left: 0;
@@ -39,11 +36,11 @@ Check the definition of the ${i.join(".")} command and update the return type fo
39
36
  height: var(--citadel-default-height);
40
37
  max-height: var(--citadel-max-height);
41
38
  min-height: var(--citadel-min-height);
42
- z-index: 2147483647; /* Maximum z-index value */
39
+ z-index: 2147483647;
43
40
  overflow: hidden;
44
41
  }
45
42
 
46
- :host([data-display-mode="inline"]) {
43
+ :host([data-display-mode='inline']) {
47
44
  position: relative;
48
45
  bottom: auto;
49
46
  left: auto;
@@ -56,127 +53,93 @@ Check the definition of the ${i.join(".")} command and update the return type fo
56
53
  overflow: hidden;
57
54
  }
58
55
 
59
- button {
60
- border-radius: 8px;
61
- border: 1px solid transparent;
62
- padding: 0.6em 1.2em;
63
- font-size: 1em;
64
- font-weight: 500;
65
- font-family: inherit;
66
- background-color: #1a1a1a;
67
- cursor: pointer;
68
- transition: border-color 0.25s;
69
- }
70
-
71
- button:hover {
72
- border-color: var(--citadel-accent);
73
- }
74
-
75
- button:focus,
76
- button:focus-visible {
77
- outline: 4px auto -webkit-focus-ring-color;
78
- }
79
-
80
- a {
81
- font-weight: 500;
82
- color: var(--citadel-accent);
83
- text-decoration: inherit;
84
- }
85
-
86
- a:hover {
87
- color: var(--citadel-accent-hover);
88
- }
89
-
90
- .flex-1 { flex: 1 1 0%; }
91
- .flex-shrink-0 { flex-shrink: 0; }
92
- .min-h-0 { min-height: 0px; }
93
- .pt-3 { padding-top: 0.75rem; }
94
- .px-4 { padding-left: 1rem; padding-right: 1rem; }
95
-
96
- .h-full {
56
+ #citadel-root {
57
+ width: 100%;
97
58
  height: 100%;
98
59
  }
99
- .overflow-y-auto {
100
- overflow-y: auto;
101
- }
102
- .border {
103
- border-width: 1px;
104
- }
105
- .border-gray-700 {
106
- --tw-border-opacity: 1;
107
- border-color: rgb(55 65 81 / var(--tw-border-opacity, 1));
108
- }
109
- .rounded-lg {
110
- border-radius: 0.5rem;
111
- }
112
- .p-3 {
113
- padding: 0.75rem;
114
- }
115
- .text-left {
116
- text-align: left;
60
+
61
+ #citadel-root,
62
+ #citadel-root * {
63
+ box-sizing: border-box;
117
64
  }
118
- `,ue=`/* Keep only component-specific styles here */
119
65
 
120
66
  .panelContainer {
121
67
  position: fixed;
68
+ bottom: 0;
69
+ left: 0;
70
+ right: 0;
71
+ width: 100%;
122
72
  height: var(--citadel-default-height);
123
73
  min-height: var(--citadel-min-height);
124
74
  max-height: var(--citadel-max-height);
125
- background-color: var(--citadel-bg);
126
- overflow: hidden;
127
- width: 100%;
128
- box-sizing: border-box;
129
75
  margin: 0;
130
76
  padding: 0;
131
- bottom: 0;
132
- left: 0;
133
- right: 0;
77
+ background-color: var(--citadel-bg);
78
+ overflow: hidden;
134
79
  }
135
80
 
136
81
  .innerContainer {
137
- height: 100%;
138
- flex: 1;
139
82
  width: 100%;
140
- display: flex;
141
- flex-direction: column;
83
+ height: 100%;
142
84
  margin: 0;
143
85
  padding: 0;
86
+ display: flex;
87
+ flex: 1;
88
+ flex-direction: column;
144
89
  }
145
90
 
146
- .inputSection {
147
- border-top: 1px solid var(--citadel-border);
148
- padding: 1rem;
149
- margin: 0;
150
- box-sizing: border-box;
91
+ .citadel-tty {
92
+ background: var(--citadel-bg);
93
+ }
94
+
95
+ .citadel-tty-output-pane {
96
+ display: flex;
97
+ flex: 1 1 auto;
98
+ min-height: 0;
99
+ padding: 0.75rem 1rem 0;
100
+ }
101
+
102
+ .citadel-tty-input-region {
103
+ flex-shrink: 0;
151
104
  }
152
105
 
153
106
  .resizeHandle {
154
- width: 100%;
155
- height: 6px;
156
- background: transparent;
157
- cursor: ns-resize;
158
107
  position: absolute;
159
108
  top: -3px;
160
109
  left: 0;
161
110
  right: 0;
162
111
  z-index: 10;
112
+ width: 100%;
113
+ height: 6px;
114
+ background: transparent;
115
+ cursor: ns-resize;
163
116
  user-select: none;
164
117
  -webkit-user-select: none;
165
118
  pointer-events: all;
166
119
  }
167
120
 
168
121
  .resizeHandle:hover {
169
- background: rgba(255, 255, 255, 0.1);
122
+ background: color-mix(in oklch, var(--citadel-text) 10%, transparent);
170
123
  }
171
124
 
172
125
  @keyframes citadel_slideUp {
173
- from { transform: translateY(100%); }
174
- to { transform: translateY(0); }
126
+ from {
127
+ transform: translateY(100%);
128
+ }
129
+
130
+ to {
131
+ transform: translateY(0);
132
+ }
175
133
  }
176
134
 
177
135
  @keyframes citadel_slideDown {
178
- from { transform: translateY(0); }
179
- to { transform: translateY(100%); }
136
+ from {
137
+ transform: translateY(0);
138
+ }
139
+
140
+ to {
141
+ transform: translateY(100%);
142
+ }
180
143
  }
181
144
 
182
145
  .citadel_slideUp {
@@ -195,827 +158,309 @@ a:hover {
195
158
  flex-direction: column;
196
159
  background-color: var(--citadel-bg);
197
160
  overflow: hidden;
198
- box-sizing: border-box;
199
161
  }
200
- `,he=`@tailwind base;
201
- @tailwind components;
202
- @tailwind utilities;
203
- `,Fe=`*, ::before, ::after {
204
- --tw-border-spacing-x: 0;
205
- --tw-border-spacing-y: 0;
206
- --tw-translate-x: 0;
207
- --tw-translate-y: 0;
208
- --tw-rotate: 0;
209
- --tw-skew-x: 0;
210
- --tw-skew-y: 0;
211
- --tw-scale-x: 1;
212
- --tw-scale-y: 1;
213
- --tw-pan-x: ;
214
- --tw-pan-y: ;
215
- --tw-pinch-zoom: ;
216
- --tw-scroll-snap-strictness: proximity;
217
- --tw-gradient-from-position: ;
218
- --tw-gradient-via-position: ;
219
- --tw-gradient-to-position: ;
220
- --tw-ordinal: ;
221
- --tw-slashed-zero: ;
222
- --tw-numeric-figure: ;
223
- --tw-numeric-spacing: ;
224
- --tw-numeric-fraction: ;
225
- --tw-ring-inset: ;
226
- --tw-ring-offset-width: 0px;
227
- --tw-ring-offset-color: #fff;
228
- --tw-ring-color: rgb(59 130 246 / 0.5);
229
- --tw-ring-offset-shadow: 0 0 #0000;
230
- --tw-ring-shadow: 0 0 #0000;
231
- --tw-shadow: 0 0 #0000;
232
- --tw-shadow-colored: 0 0 #0000;
233
- --tw-blur: ;
234
- --tw-brightness: ;
235
- --tw-contrast: ;
236
- --tw-grayscale: ;
237
- --tw-hue-rotate: ;
238
- --tw-invert: ;
239
- --tw-saturate: ;
240
- --tw-sepia: ;
241
- --tw-drop-shadow: ;
242
- --tw-backdrop-blur: ;
243
- --tw-backdrop-brightness: ;
244
- --tw-backdrop-contrast: ;
245
- --tw-backdrop-grayscale: ;
246
- --tw-backdrop-hue-rotate: ;
247
- --tw-backdrop-invert: ;
248
- --tw-backdrop-opacity: ;
249
- --tw-backdrop-saturate: ;
250
- --tw-backdrop-sepia: ;
251
- --tw-contain-size: ;
252
- --tw-contain-layout: ;
253
- --tw-contain-paint: ;
254
- --tw-contain-style: ;
255
- }
256
-
257
- ::backdrop {
258
- --tw-border-spacing-x: 0;
259
- --tw-border-spacing-y: 0;
260
- --tw-translate-x: 0;
261
- --tw-translate-y: 0;
262
- --tw-rotate: 0;
263
- --tw-skew-x: 0;
264
- --tw-skew-y: 0;
265
- --tw-scale-x: 1;
266
- --tw-scale-y: 1;
267
- --tw-pan-x: ;
268
- --tw-pan-y: ;
269
- --tw-pinch-zoom: ;
270
- --tw-scroll-snap-strictness: proximity;
271
- --tw-gradient-from-position: ;
272
- --tw-gradient-via-position: ;
273
- --tw-gradient-to-position: ;
274
- --tw-ordinal: ;
275
- --tw-slashed-zero: ;
276
- --tw-numeric-figure: ;
277
- --tw-numeric-spacing: ;
278
- --tw-numeric-fraction: ;
279
- --tw-ring-inset: ;
280
- --tw-ring-offset-width: 0px;
281
- --tw-ring-offset-color: #fff;
282
- --tw-ring-color: rgb(59 130 246 / 0.5);
283
- --tw-ring-offset-shadow: 0 0 #0000;
284
- --tw-ring-shadow: 0 0 #0000;
285
- --tw-shadow: 0 0 #0000;
286
- --tw-shadow-colored: 0 0 #0000;
287
- --tw-blur: ;
288
- --tw-brightness: ;
289
- --tw-contrast: ;
290
- --tw-grayscale: ;
291
- --tw-hue-rotate: ;
292
- --tw-invert: ;
293
- --tw-saturate: ;
294
- --tw-sepia: ;
295
- --tw-drop-shadow: ;
296
- --tw-backdrop-blur: ;
297
- --tw-backdrop-brightness: ;
298
- --tw-backdrop-contrast: ;
299
- --tw-backdrop-grayscale: ;
300
- --tw-backdrop-hue-rotate: ;
301
- --tw-backdrop-invert: ;
302
- --tw-backdrop-opacity: ;
303
- --tw-backdrop-saturate: ;
304
- --tw-backdrop-sepia: ;
305
- --tw-contain-size: ;
306
- --tw-contain-layout: ;
307
- --tw-contain-paint: ;
308
- --tw-contain-style: ;
309
- }/*
310
- ! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com
311
- *//*
312
- 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
313
- 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
314
- */
315
-
316
- *,
317
- ::before,
318
- ::after {
319
- box-sizing: border-box; /* 1 */
320
- border-width: 0; /* 2 */
321
- border-style: solid; /* 2 */
322
- border-color: #e5e7eb; /* 2 */
323
- }
324
-
325
- ::before,
326
- ::after {
327
- --tw-content: '';
328
- }
329
-
330
- /*
331
- 1. Use a consistent sensible line-height in all browsers.
332
- 2. Prevent adjustments of font size after orientation changes in iOS.
333
- 3. Use a more readable tab size.
334
- 4. Use the user's configured \`sans\` font-family by default.
335
- 5. Use the user's configured \`sans\` font-feature-settings by default.
336
- 6. Use the user's configured \`sans\` font-variation-settings by default.
337
- 7. Disable tap highlights on iOS
338
- */
339
-
340
- html,
341
- :host {
342
- line-height: 1.5; /* 1 */
343
- -webkit-text-size-adjust: 100%; /* 2 */
344
- -moz-tab-size: 4; /* 3 */
345
- -o-tab-size: 4;
346
- tab-size: 4; /* 3 */
347
- font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
348
- font-feature-settings: normal; /* 5 */
349
- font-variation-settings: normal; /* 6 */
350
- -webkit-tap-highlight-color: transparent; /* 7 */
351
- }
352
-
353
- /*
354
- 1. Remove the margin in all browsers.
355
- 2. Inherit line-height from \`html\` so users can set them as a class directly on the \`html\` element.
356
- */
357
-
358
- body {
359
- margin: 0; /* 1 */
360
- line-height: inherit; /* 2 */
361
- }
362
-
363
- /*
364
- 1. Add the correct height in Firefox.
365
- 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
366
- 3. Ensure horizontal rules are visible by default.
367
- */
368
-
369
- hr {
370
- height: 0; /* 1 */
371
- color: inherit; /* 2 */
372
- border-top-width: 1px; /* 3 */
373
- }
374
-
375
- /*
376
- Add the correct text decoration in Chrome, Edge, and Safari.
377
- */
378
-
379
- abbr:where([title]) {
380
- -webkit-text-decoration: underline dotted;
381
- text-decoration: underline dotted;
382
- }
383
-
384
- /*
385
- Remove the default font size and weight for headings.
386
- */
387
-
388
- h1,
389
- h2,
390
- h3,
391
- h4,
392
- h5,
393
- h6 {
394
- font-size: inherit;
395
- font-weight: inherit;
396
- }
397
-
398
- /*
399
- Reset links to optimize for opt-in styling instead of opt-out.
400
- */
401
-
402
- a {
403
- color: inherit;
404
- text-decoration: inherit;
405
- }
406
-
407
- /*
408
- Add the correct font weight in Edge and Safari.
409
- */
410
-
411
- b,
412
- strong {
413
- font-weight: bolder;
414
- }
415
-
416
- /*
417
- 1. Use the user's configured \`mono\` font-family by default.
418
- 2. Use the user's configured \`mono\` font-feature-settings by default.
419
- 3. Use the user's configured \`mono\` font-variation-settings by default.
420
- 4. Correct the odd \`em\` font sizing in all browsers.
421
- */
422
-
423
- code,
424
- kbd,
425
- samp,
426
- pre {
427
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */
428
- font-feature-settings: normal; /* 2 */
429
- font-variation-settings: normal; /* 3 */
430
- font-size: 1em; /* 4 */
431
- }
432
-
433
- /*
434
- Add the correct font size in all browsers.
435
- */
436
162
 
437
- small {
438
- font-size: 80%;
163
+ .citadel-output {
164
+ width: 100%;
165
+ height: 100%;
166
+ overflow-y: auto;
167
+ padding: 0.75rem;
168
+ border: 1px solid var(--citadel-border);
169
+ border-radius: 0.5rem;
170
+ background: color-mix(in oklch, var(--citadel-bg) 75%, black);
171
+ text-align: left;
439
172
  }
440
173
 
441
- /*
442
- Prevent \`sub\` and \`sup\` elements from affecting the line height in all browsers.
443
- */
444
-
445
- sub,
446
- sup {
447
- font-size: 75%;
448
- line-height: 0;
449
- position: relative;
450
- vertical-align: baseline;
174
+ .citadel-output-item {
175
+ margin-bottom: 1rem;
451
176
  }
452
177
 
453
- sub {
454
- bottom: -0.25em;
178
+ .citadel-output-item:last-child {
179
+ margin-bottom: 0;
455
180
  }
456
181
 
457
- sup {
458
- top: -0.5em;
182
+ .citadel-output-content {
183
+ margin-top: 0.35rem;
184
+ color: var(--citadel-text);
459
185
  }
460
186
 
461
- /*
462
- 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
463
- 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
464
- 3. Remove gaps between table borders by default.
465
- */
466
-
467
- table {
468
- text-indent: 0; /* 1 */
469
- border-color: inherit; /* 2 */
470
- border-collapse: collapse; /* 3 */
187
+ .citadel-output-content > :first-child {
188
+ margin-top: 0;
471
189
  }
472
190
 
473
- /*
474
- 1. Change the font styles in all browsers.
475
- 2. Remove the margin in Firefox and Safari.
476
- 3. Remove default padding in all browsers.
477
- */
478
-
479
- button,
480
- input,
481
- optgroup,
482
- select,
483
- textarea {
484
- font-family: inherit; /* 1 */
485
- font-feature-settings: inherit; /* 1 */
486
- font-variation-settings: inherit; /* 1 */
487
- font-size: 100%; /* 1 */
488
- font-weight: inherit; /* 1 */
489
- line-height: inherit; /* 1 */
490
- letter-spacing: inherit; /* 1 */
491
- color: inherit; /* 1 */
492
- margin: 0; /* 2 */
493
- padding: 0; /* 3 */
191
+ .citadel-output-content > :last-child {
192
+ margin-bottom: 0;
494
193
  }
495
194
 
496
- /*
497
- Remove the inheritance of text transform in Edge and Firefox.
498
- */
499
-
500
- button,
501
- select {
502
- text-transform: none;
195
+ .citadel-output-line {
196
+ display: flex;
197
+ flex-wrap: wrap;
198
+ align-items: center;
199
+ gap: 0.5rem;
503
200
  }
504
201
 
505
- /*
506
- 1. Correct the inability to style clickable types in iOS and Safari.
507
- 2. Remove default button styles.
508
- */
509
-
510
- button,
511
- input:where([type='button']),
512
- input:where([type='reset']),
513
- input:where([type='submit']) {
514
- -webkit-appearance: button; /* 1 */
515
- background-color: transparent; /* 2 */
516
- background-image: none; /* 2 */
202
+ .citadel-output-command,
203
+ .citadel-output-command-word {
204
+ color: var(--citadel-text);
517
205
  }
518
206
 
519
- /*
520
- Use the modern Firefox focus style for all focusable elements.
521
- */
522
-
523
- :-moz-focusring {
524
- outline: auto;
207
+ .citadel-output-command-arg {
208
+ color: var(--citadel-arg);
525
209
  }
526
210
 
527
- /*
528
- Remove the additional \`:invalid\` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
529
- */
211
+ .citadel-output-separator {
212
+ color: var(--citadel-muted);
213
+ }
530
214
 
531
- :-moz-ui-invalid {
532
- box-shadow: none;
215
+ .citadel-output-timestamp {
216
+ color: var(--citadel-subtle);
533
217
  }
534
218
 
535
- /*
536
- Add the correct vertical alignment in Chrome and Firefox.
537
- */
219
+ .citadel-status-dot {
220
+ width: 1rem;
221
+ height: 1rem;
222
+ border-radius: 999px;
223
+ }
538
224
 
539
- progress {
540
- vertical-align: baseline;
225
+ .citadel-status-dot-success {
226
+ background: var(--citadel-success);
541
227
  }
542
228
 
543
- /*
544
- Correct the cursor style of increment and decrement buttons in Safari.
545
- */
229
+ .citadel-status-dot-failure {
230
+ background: var(--citadel-error);
231
+ }
546
232
 
547
- ::-webkit-inner-spin-button,
548
- ::-webkit-outer-spin-button {
549
- height: auto;
233
+ .citadel-spinner {
234
+ width: 1rem;
235
+ height: 1rem;
236
+ border: 2px solid color-mix(in oklch, var(--citadel-text) 60%, transparent);
237
+ border-top-color: color-mix(in oklch, var(--citadel-muted) 80%, black);
238
+ border-radius: 999px;
239
+ animation: citadel-spin 0.9s linear infinite;
550
240
  }
551
241
 
552
- /*
553
- 1. Correct the odd appearance in Chrome and Safari.
554
- 2. Correct the outline style in Safari.
555
- */
242
+ @keyframes citadel-spin {
243
+ to {
244
+ transform: rotate(360deg);
245
+ }
246
+ }
556
247
 
557
- [type='search'] {
558
- -webkit-appearance: textfield; /* 1 */
559
- outline-offset: -2px; /* 2 */
248
+ .citadel-input-shell {
249
+ width: 100%;
250
+ padding: 1rem;
251
+ border-radius: 0.5rem;
252
+ background-color: var(--citadel-bg);
560
253
  }
561
254
 
562
- /*
563
- Remove the inner padding in Chrome and Safari on macOS.
564
- */
255
+ .citadel-input-line {
256
+ display: flex;
257
+ align-items: center;
258
+ gap: 0.5rem;
259
+ }
565
260
 
566
- ::-webkit-search-decoration {
567
- -webkit-appearance: none;
261
+ .citadel-input-prompt {
262
+ color: var(--citadel-muted);
568
263
  }
569
264
 
570
- /*
571
- 1. Correct the inability to style clickable types in iOS and Safari.
572
- 2. Change font properties to \`inherit\` in Safari.
573
- */
265
+ .citadel-input-row {
266
+ display: flex;
267
+ align-items: center;
268
+ flex: 1 1 auto;
269
+ min-width: 0;
270
+ }
574
271
 
575
- ::-webkit-file-upload-button {
576
- -webkit-appearance: button; /* 1 */
577
- font: inherit; /* 2 */
272
+ .citadel-input-segments {
273
+ display: flex;
274
+ align-items: center;
275
+ gap: 0.25rem;
578
276
  }
579
277
 
580
- /*
581
- Add the correct display in Chrome and Safari.
582
- */
278
+ .citadel-input-segment-arg {
279
+ color: var(--citadel-text);
280
+ white-space: pre;
281
+ }
583
282
 
584
- summary {
585
- display: list-item;
283
+ .citadel-input-segment-word {
284
+ color: var(--citadel-word);
285
+ white-space: pre;
586
286
  }
587
287
 
588
- /*
589
- Removes the default spacing and border for appropriate elements.
590
- */
288
+ .citadel-input-segment-space {
289
+ color: var(--citadel-text);
290
+ white-space: pre;
291
+ }
591
292
 
592
- blockquote,
593
- dl,
594
- dd,
595
- h1,
596
- h2,
597
- h3,
598
- h4,
599
- h5,
600
- h6,
601
- hr,
602
- figure,
603
- p,
604
- pre {
605
- margin: 0;
293
+ .citadel-input-segment-space-command {
294
+ color: var(--citadel-word);
606
295
  }
607
296
 
608
- fieldset {
609
- margin: 0;
610
- padding: 0;
297
+ .citadel-input-control {
298
+ position: relative;
299
+ flex: 1 1 auto;
300
+ min-width: 0;
611
301
  }
612
302
 
613
- legend {
614
- padding: 0;
303
+ .citadel-input-measure {
304
+ position: absolute;
305
+ top: 0;
306
+ left: 0;
307
+ visibility: hidden;
308
+ pointer-events: none;
309
+ white-space: pre;
310
+ font: inherit;
311
+ letter-spacing: inherit;
615
312
  }
616
313
 
617
- ol,
618
- ul,
619
- menu {
620
- list-style: none;
314
+ .citadel-input-field {
315
+ width: 100%;
621
316
  margin: 0;
622
317
  padding: 0;
318
+ border: 0;
319
+ border-radius: 0;
320
+ outline: none;
321
+ background: transparent;
322
+ font: inherit;
323
+ line-height: inherit;
324
+ letter-spacing: inherit;
325
+ appearance: none;
326
+ -webkit-appearance: none;
327
+ caret-color: transparent;
623
328
  }
624
329
 
625
- /*
626
- Reset default styling for dialogs.
627
- */
628
- dialog {
629
- padding: 0;
330
+ .citadel-input-field::placeholder {
331
+ color: var(--citadel-subtle);
332
+ opacity: 1;
630
333
  }
631
334
 
632
- /*
633
- Prevent resizing textareas horizontally by default.
634
- */
635
-
636
- textarea {
637
- resize: vertical;
335
+ .citadel-input-field.is-command-mode {
336
+ color: var(--citadel-word);
638
337
  }
639
338
 
640
- /*
641
- 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
642
- 2. Set the default placeholder color to the user's configured gray 400 color.
643
- */
644
-
645
- input::-moz-placeholder, textarea::-moz-placeholder {
646
- opacity: 1; /* 1 */
647
- color: #9ca3af; /* 2 */
339
+ .citadel-input-field.is-argument-mode {
340
+ color: var(--citadel-text);
648
341
  }
649
342
 
650
- input::placeholder,
651
- textarea::placeholder {
652
- opacity: 1; /* 1 */
653
- color: #9ca3af; /* 2 */
343
+ .citadel-input-cursor {
344
+ position: absolute;
345
+ top: 0;
346
+ pointer-events: none;
654
347
  }
655
348
 
656
- /*
657
- Set the default cursor for buttons.
658
- */
349
+ @keyframes citadel-invalid-glow {
350
+ 0%,
351
+ 100% {
352
+ box-shadow: 0 0 0 color-mix(in oklch, var(--citadel-error) 0%, transparent);
353
+ }
659
354
 
660
- button,
661
- [role="button"] {
662
- cursor: pointer;
355
+ 50% {
356
+ box-shadow: 0 0 8px color-mix(in oklch, var(--citadel-error) 70%, transparent);
357
+ }
663
358
  }
664
359
 
665
- /*
666
- Make sure disabled buttons don't get the pointer cursor.
667
- */
668
- :disabled {
669
- cursor: default;
360
+ .invalid-input-animation {
361
+ animation: citadel-invalid-glow 0.4s ease-in-out;
670
362
  }
671
363
 
672
- /*
673
- 1. Make replaced elements \`display: block\` by default. (https://github.com/mozdevs/cssremedy/issues/14)
674
- 2. Add \`vertical-align: middle\` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
675
- This can trigger a poorly considered lint error in some tools but is included by design.
676
- */
364
+ .citadel-cursor-wrapper {
365
+ position: relative;
366
+ display: inline-block;
367
+ }
677
368
 
678
- img,
679
- svg,
680
- video,
681
- canvas,
682
- audio,
683
- iframe,
684
- embed,
685
- object {
686
- display: block; /* 1 */
687
- vertical-align: middle; /* 2 */
369
+ .command-cursor {
370
+ display: inline-block;
371
+ white-space: pre;
688
372
  }
689
373
 
690
- /*
691
- Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
692
- */
374
+ @keyframes citadel-shake {
375
+ 0%,
376
+ 100% {
377
+ transform: translateX(0);
378
+ }
693
379
 
694
- img,
695
- video {
696
- max-width: 100%;
697
- height: auto;
698
- }
380
+ 25% {
381
+ transform: translateX(-4px);
382
+ }
699
383
 
700
- /* Make elements with the HTML hidden attribute stay hidden by default */
701
- [hidden]:where(:not([hidden="until-found"])) {
702
- display: none;
703
- }
704
- .container {
705
- width: 100%;
706
- }
707
- .pointer-events-none {
708
- pointer-events: none;
709
- }
710
- .visible {
711
- visibility: visible;
712
- }
713
- .static {
714
- position: static;
715
- }
716
- .fixed {
717
- position: fixed;
718
- }
719
- .absolute {
720
- position: absolute;
721
- }
722
- .relative {
723
- position: relative;
724
- }
725
- .top-0 {
726
- top: 0px;
727
- }
728
- .my-2 {
729
- margin-top: 0.5rem;
730
- margin-bottom: 0.5rem;
731
- }
732
- .mb-4 {
733
- margin-bottom: 1rem;
734
- }
735
- .ml-2 {
736
- margin-left: 0.5rem;
737
- }
738
- .mr-2 {
739
- margin-right: 0.5rem;
384
+ 75% {
385
+ transform: translateX(4px);
386
+ }
740
387
  }
741
- .mt-1 {
742
- margin-top: 0.25rem;
388
+
389
+ .animate-shake {
390
+ animation: citadel-shake 0.2s ease-in-out;
743
391
  }
744
- .mt-2 {
392
+
393
+ .citadel-available-commands {
745
394
  margin-top: 0.5rem;
395
+ padding: 0.5rem 1rem;
396
+ border-top: 1px solid var(--citadel-border);
746
397
  }
747
- .block {
748
- display: block;
749
- }
750
- .inline-block {
751
- display: inline-block;
752
- }
753
- .flex {
754
- display: flex;
755
- }
756
- .hidden {
757
- display: none;
758
- }
759
- .h-12 {
760
- height: 3rem;
761
- }
762
- .h-4 {
763
- height: 1rem;
764
- }
765
- .h-auto {
766
- height: auto;
767
- }
768
- .h-full {
769
- height: 100%;
770
- }
771
- .max-h-\\[300px\\] {
772
- max-height: 300px;
773
- }
774
- .min-h-0 {
775
- min-height: 0px;
776
- }
777
- .min-h-screen {
778
- min-height: 100vh;
779
- }
780
- .w-4 {
781
- width: 1rem;
782
- }
783
- .w-full {
784
- width: 100%;
785
- }
786
- .max-w-\\[400px\\] {
787
- max-width: 400px;
788
- }
789
- .flex-1 {
790
- flex: 1 1 0%;
791
- }
792
- .flex-shrink-0 {
793
- flex-shrink: 0;
794
- }
795
- .transform {
796
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
797
- }
798
- @keyframes spin {
799
398
 
800
- to {
801
- transform: rotate(360deg);
802
- }
803
- }
804
- .animate-spin {
805
- animation: spin 1s linear infinite;
806
- }
807
- .flex-col {
808
- flex-direction: column;
399
+ .citadel-available-commands-content {
400
+ color: var(--citadel-muted);
809
401
  }
810
- .flex-wrap {
402
+
403
+ .citadel-available-chip-list {
404
+ display: flex;
811
405
  flex-wrap: wrap;
812
- }
813
- .items-center {
814
- align-items: center;
815
- }
816
- .justify-center {
817
- justify-content: center;
818
- }
819
- .gap-2 {
820
406
  gap: 0.5rem;
821
407
  }
822
- .overflow-y-auto {
823
- overflow-y: auto;
824
- }
825
- .whitespace-pre {
826
- white-space: pre;
827
- }
828
- .rounded {
829
- border-radius: 0.25rem;
830
- }
831
- .rounded-full {
832
- border-radius: 9999px;
833
- }
834
- .rounded-lg {
835
- border-radius: 0.5rem;
836
- }
837
- .border {
838
- border-width: 1px;
839
- }
840
- .border-2 {
841
- border-width: 2px;
842
- }
843
- .border-t {
844
- border-top-width: 1px;
845
- }
846
- .border-gray-300 {
847
- --tw-border-opacity: 1;
848
- border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
849
- }
850
- .border-gray-700 {
851
- --tw-border-opacity: 1;
852
- border-color: rgb(55 65 81 / var(--tw-border-opacity, 1));
853
- }
854
- .border-t-gray-600 {
855
- --tw-border-opacity: 1;
856
- border-top-color: rgb(75 85 99 / var(--tw-border-opacity, 1));
857
- }
858
- .bg-gray-100 {
859
- --tw-bg-opacity: 1;
860
- background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
861
- }
862
- .bg-gray-800 {
863
- --tw-bg-opacity: 1;
864
- background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
865
- }
866
- .bg-gray-900 {
867
- --tw-bg-opacity: 1;
868
- background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1));
869
- }
870
- .bg-green-500 {
871
- --tw-bg-opacity: 1;
872
- background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
873
- }
874
- .bg-red-500 {
875
- --tw-bg-opacity: 1;
876
- background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
877
- }
878
- .bg-transparent {
879
- background-color: transparent;
880
- }
881
- .bg-white {
882
- --tw-bg-opacity: 1;
883
- background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
884
- }
885
- .object-contain {
886
- -o-object-fit: contain;
887
- object-fit: contain;
888
- }
889
- .p-3 {
890
- padding: 0.75rem;
891
- }
892
- .p-4 {
893
- padding: 1rem;
894
- }
895
- .p-6 {
896
- padding: 1.5rem;
897
- }
898
- .px-2 {
899
- padding-left: 0.5rem;
900
- padding-right: 0.5rem;
901
- }
902
- .px-4 {
903
- padding-left: 1rem;
904
- padding-right: 1rem;
905
- }
906
- .py-1 {
907
- padding-top: 0.25rem;
908
- padding-bottom: 0.25rem;
909
- }
910
- .pt-2 {
911
- padding-top: 0.5rem;
912
- }
913
- .pt-3 {
914
- padding-top: 0.75rem;
915
- }
916
- .text-left {
917
- text-align: left;
918
- }
919
- .font-mono {
920
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
921
- }
922
- .text-base {
923
- font-size: 1rem;
924
- line-height: 1.5rem;
925
- }
926
- .text-lg {
927
- font-size: 1.125rem;
928
- line-height: 1.75rem;
929
- }
930
- .text-sm {
931
- font-size: 0.875rem;
932
- line-height: 1.25rem;
933
- }
934
- .text-xs {
935
- font-size: 0.75rem;
936
- line-height: 1rem;
937
- }
938
- .text-blue-400 {
939
- --tw-text-opacity: 1;
940
- color: rgb(96 165 250 / var(--tw-text-opacity, 1));
941
- }
942
- .text-gray-200 {
943
- --tw-text-opacity: 1;
944
- color: rgb(229 231 235 / var(--tw-text-opacity, 1));
945
- }
946
- .text-gray-300 {
947
- --tw-text-opacity: 1;
948
- color: rgb(209 213 219 / var(--tw-text-opacity, 1));
949
- }
950
- .text-gray-400 {
951
- --tw-text-opacity: 1;
952
- color: rgb(156 163 175 / var(--tw-text-opacity, 1));
953
- }
954
- .text-gray-500 {
955
- --tw-text-opacity: 1;
956
- color: rgb(107 114 128 / var(--tw-text-opacity, 1));
957
- }
958
- .text-gray-700 {
959
- --tw-text-opacity: 1;
960
- color: rgb(55 65 81 / var(--tw-text-opacity, 1));
961
- }
962
- .text-green-500 {
963
- --tw-text-opacity: 1;
964
- color: rgb(34 197 94 / var(--tw-text-opacity, 1));
965
- }
966
- .text-red-400 {
967
- --tw-text-opacity: 1;
968
- color: rgb(248 113 113 / var(--tw-text-opacity, 1));
969
- }
970
- .text-red-500 {
971
- --tw-text-opacity: 1;
972
- color: rgb(239 68 68 / var(--tw-text-opacity, 1));
973
- }
974
- .text-white {
975
- --tw-text-opacity: 1;
976
- color: rgb(255 255 255 / var(--tw-text-opacity, 1));
408
+
409
+ .citadel-available-chip {
410
+ padding: 0.25rem 0.5rem;
411
+ border-radius: 0.375rem;
412
+ background: var(--citadel-surface);
977
413
  }
978
- .underline {
979
- text-decoration-line: underline;
414
+
415
+ .citadel-available-chip-text {
416
+ color: white;
980
417
  }
981
- .caret-transparent {
982
- caret-color: transparent;
418
+
419
+ .citadel-available-chip-prefix {
420
+ text-decoration: underline;
983
421
  }
984
- .shadow {
985
- --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
986
- --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
987
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
422
+
423
+ .citadel-available-next-arg {
424
+ color: var(--citadel-word);
988
425
  }
989
- .shadow-lg {
990
- --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
991
- --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
992
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
426
+
427
+ .citadel-available-next-desc {
428
+ margin-left: 0.5rem;
429
+ color: var(--citadel-muted);
993
430
  }
994
- .outline-none {
995
- outline: 2px solid transparent;
996
- outline-offset: 2px;
431
+
432
+ .citadel-result-json,
433
+ .citadel-result-text {
434
+ color: var(--citadel-text);
997
435
  }
998
- .filter {
999
- filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
436
+
437
+ .citadel-result-json {
438
+ margin: 0;
1000
439
  }
1001
- .transition {
1002
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
1003
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
1004
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
1005
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1006
- transition-duration: 150ms;
440
+
441
+ .citadel-result-text {
442
+ white-space: pre;
1007
443
  }
1008
- .ease-in-out {
1009
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
444
+
445
+ .citadel-result-error {
446
+ margin-top: 0.25rem;
447
+ color: var(--citadel-error);
1010
448
  }
1011
- .ease-out {
1012
- transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
449
+
450
+ .citadel-result-pending {
451
+ color: var(--citadel-muted);
1013
452
  }
1014
- .last\\:mb-0:last-child {
1015
- margin-bottom: 0px;
453
+
454
+ .citadel-result-image-wrap {
455
+ margin-block: 0.5rem;
1016
456
  }
1017
- .last\\:mr-0:last-child {
1018
- margin-right: 0px;
457
+
458
+ .citadel-result-image {
459
+ max-width: 400px;
460
+ max-height: 300px;
461
+ height: auto;
462
+ object-fit: contain;
463
+ border-radius: 0.5rem;
1019
464
  }
1020
- `,Oe=({config:r=N,commandRegistry:e=new K,containerId:n=null})=>{const t=s.useRef(null),o=r.displayMode??N.displayMode??"panel";return s.useEffect(()=>{S.configure({level:r.logLevel||N.logLevel||Y.ERROR,prefix:"[Citadel]"});const l=new pe(e,r),d=o==="inline"&&!n,m=d?t.current:n?document.getElementById(n):document.body;if(m)m.appendChild(l);else{if(d){console.warn("[Citadel] No host available for inline mode; skipping mount.");return}console.warn(`Container with id "${n}" not found, falling back to body`),document.body.appendChild(l)}return()=>{var i;(i=l.parentElement)==null||i.removeChild(l)}},[e,n,r,o]),o==="inline"&&!n?a.jsx("div",{ref:t,style:{width:"100%",height:"100%"}}):null};class pe extends HTMLElement{constructor(n,t){var l;super();x(this,"shadow");x(this,"root",null);x(this,"commandRegistry");x(this,"config");this.shadow=this.attachShadow({mode:"open"}),this.commandRegistry=n,this.config=t;const o=((l=this.config)==null?void 0:l.displayMode)??"panel";this.setAttribute("data-display-mode",o)}connectedCallback(){try{const t=[me,ue,he,Fe].map(o=>{const l=new CSSStyleSheet;return l.replaceSync(o),l});this.shadow.adoptedStyleSheets=[...t]}catch{const t=[me,ue,he].join(`
1021
- `),o=document.createElement("style");o.textContent=t,this.shadow.appendChild(o)}const n=document.createElement("div");n.id="citadel-root",n.style.width="100%",n.style.height="100%",this.shadow.appendChild(n),this.root=ge.createRoot(n),this.root.render(a.jsx(Se,{config:this.config||N,commandRegistry:this.commandRegistry,children:a.jsx(Le,{})}))}disconnectedCallback(){const n=this.root;if(this.root=null,!n){this.shadow.replaceChildren();return}queueMicrotask(()=>{n.unmount(),this.shadow.replaceChildren()})}}typeof window<"u"&&window.customElements&&!window.customElements.get("citadel-element")&&window.customElements.define("citadel-element",pe);const Le=()=>(T().displayMode??"panel")==="inline"?a.jsx(je,{}):a.jsx(Ue,{});y.Citadel=Oe,y.CommandRegistry=K,y.CommandResult=P,y.CommandStatus=H,y.DEFAULT_CURSOR_CONFIGS=ae,y.ErrorCommandResult=J,y.ImageCommandResult=we,y.JsonCommandResult=fe,y.OutputItem=W,y.PendingCommandResult=Q,y.TextCommandResult=O,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
465
+ `,Qe=({config:n=I,commandRegistry:e,containerId:t=null})=>{const s=o.useRef(new $),r=e??s.current,a=o.useRef(null),i=o.useMemo(()=>({width:"100%",height:"100%"}),[]),d=n.displayMode??I.displayMode??"panel";return o.useEffect(()=>{k.configure({level:n.logLevel||I.logLevel||X.ERROR,prefix:"[Citadel]"});const l=new ke(r,n),u=d==="inline"&&!t,y=u?a.current:t?document.getElementById(t):document.body;if(y)y.appendChild(l);else{if(u){console.warn("[Citadel] No host available for inline mode; skipping mount.");return}console.warn(`Container with id "${t}" not found, falling back to body`),document.body.appendChild(l)}return()=>{var p;(p=l.parentElement)==null||p.removeChild(l)}},[r,t,n,d]),d==="inline"&&!t?c.jsx("div",{ref:a,style:i}):null};class ke extends HTMLElement{constructor(t,s){var a;super();C(this,"shadow");C(this,"root",null);C(this,"commandRegistry");C(this,"config");this.shadow=this.attachShadow({mode:"open"}),this.commandRegistry=t,this.config=s;const r=((a=this.config)==null?void 0:a.displayMode)??"panel";this.setAttribute("data-display-mode",r)}connectedCallback(){try{const s=[xe].map(r=>{const a=new CSSStyleSheet;return a.replaceSync(r),a});this.shadow.adoptedStyleSheets=[...s]}catch{const s=[xe].join(`
466
+ `),r=document.createElement("style");r.textContent=s,this.shadow.appendChild(r)}const t=document.createElement("div");t.id="citadel-root",t.style.width="100%",t.style.height="100%",this.shadow.appendChild(t),this.root=Ae.createRoot(t),this.root.render(c.jsx(ze,{config:this.config||I,commandRegistry:this.commandRegistry,children:c.jsx(Xe,{})}))}disconnectedCallback(){const t=this.root;if(this.root=null,!t){this.shadow.replaceChildren();return}queueMicrotask(()=>{t.unmount(),this.shadow.replaceChildren()})}}typeof window<"u"&&window.customElements&&!window.customElements.get("citadel-element")&&window.customElements.define("citadel-element",ke);const Xe=()=>(T().displayMode??"panel")==="inline"?c.jsx(Ge,{}):c.jsx(Je,{});class Ze{constructor(){C(this,"_description")}describe(e){return this._description=e,this}get description(){return this._description}}class Re{constructor(e){C(this,"state");this.state={path:e,description:"",segments:et(e)}}describe(e){return this.state.description=e,this}details(e){return this.state.details=e,this}arg(e,t){const s=new Ze;return t==null||t(s),this.state.segments.push({type:"argument",name:e,description:s.description}),this}handle(e){return{path:this.state.path,description:this.state.description,details:this.state.details,segments:[...this.state.segments],handler:e}}}function et(n){const e=n.trim();if(!e)throw new Error("Command path cannot be empty");const t=e.split(".");if(t.some(s=>s.trim()===""))throw new Error(`Invalid command path "${n}". Empty segments are not allowed.`);if(t.some(s=>s.includes(" ")))throw new Error(`Invalid command path "${n}". Use dot-delimited words (e.g. "user.show").`);return t.map(s=>({type:"word",name:s}))}function tt(n){return n.flatMap(e=>e.type==="argument"?[e.name]:[])}function nt(n){const e=tt(n.segments);return async t=>{const s=e.reduce((r,a,i)=>(r[a]=t[i],r),{});return Promise.resolve(n.handler({rawArgs:t,namedArgs:s,commandPath:n.path}))}}function st(n){return new Re(n)}function Ee(n,e){n.addCommand(e.segments,e.description,nt(e))}function Ne(n,e){return e.forEach(t=>Ee(n,t)),n}function rt(n){const e=new $;return Ne(e,n)}function ot(n){return new O(n)}function at(n){return new ae(n)}function it(n,e=""){return new le(n,e)}function lt(n){return new Q(n)}f.Citadel=Qe,f.CommandRegistry=$,f.CommandResult=j,f.CommandStatus=L,f.DEFAULT_CURSOR_CONFIGS=Ce,f.ErrorCommandResult=Q,f.ImageCommandResult=le,f.JsonCommandResult=ae,f.OutputItem=Y,f.PendingCommandResult=ie,f.TextCommandResult=O,f.command=st,f.createCommandRegistry=rt,f.error=lt,f.image=it,f.json=at,f.registerCommand=Ee,f.registerCommands=Ne,f.text=ot,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});