citadel_cli 1.1.5 → 1.1.6

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,13 +1,13 @@
1
1
  var ge = Object.defineProperty;
2
2
  var fe = (r, e, n) => e in r ? ge(r, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : r[e] = n;
3
- var b = (r, e, n) => fe(r, typeof e != "symbol" ? e + "" : e, n);
3
+ var y = (r, e, n) => fe(r, typeof e != "symbol" ? e + "" : e, n);
4
4
  import { jsx as m, jsxs as _, Fragment as we } from "react/jsx-runtime";
5
- import L, { createContext as be, useEffect as A, useContext as Y, useState as R, useCallback as w, useMemo as V, useReducer as ye, useRef as H } from "react";
5
+ import L, { createContext as be, useEffect as A, useContext as Y, useState as R, useCallback as b, useMemo as V, useReducer as ye, useRef as P } from "react";
6
6
  import { createRoot as xe } from "react-dom/client";
7
7
  var T = /* @__PURE__ */ ((r) => (r.Pending = "pending", r.Success = "success", r.Failure = "failure", r.Timeout = "timeout", r))(T || {});
8
8
  class U {
9
9
  constructor(e = Date.now()) {
10
- b(this, "_status", "pending");
10
+ y(this, "_status", "pending");
11
11
  this.timestamp = e;
12
12
  }
13
13
  get status() {
@@ -76,7 +76,7 @@ const Se = (r) => async function() {
76
76
  );
77
77
  };
78
78
  var W = /* @__PURE__ */ ((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))(W || {});
79
- class C {
79
+ class E {
80
80
  static configure(e) {
81
81
  this.level = e.level, this.prefix = e.prefix || "[Citadel]";
82
82
  }
@@ -96,7 +96,7 @@ class C {
96
96
  this.level >= 1 && console.error(this.prefix, ...e);
97
97
  }
98
98
  }
99
- b(C, "level", 0), b(C, "prefix", "");
99
+ y(E, "level", 0), y(E, "prefix", "");
100
100
  const z = {
101
101
  commandTimeoutMs: 1e4,
102
102
  cursorColor: "var(--cursor-color, #fff)",
@@ -118,7 +118,7 @@ const z = {
118
118
  };
119
119
  class ie {
120
120
  constructor(e) {
121
- b(this, "config");
121
+ y(this, "config");
122
122
  this.config = {
123
123
  type: "localStorage",
124
124
  maxCommands: 100,
@@ -138,7 +138,7 @@ class ie {
138
138
  class ke extends ie {
139
139
  constructor(n) {
140
140
  super(n);
141
- b(this, "storageKey", "citadel_command_history");
141
+ y(this, "storageKey", "citadel_command_history");
142
142
  }
143
143
  async getStoredCommands() {
144
144
  try {
@@ -173,7 +173,7 @@ class ke extends ie {
173
173
  class Ee extends ie {
174
174
  constructor(n) {
175
175
  super(n);
176
- b(this, "storedCommands", []);
176
+ y(this, "storedCommands", []);
177
177
  }
178
178
  async getStoredCommands() {
179
179
  return this.storedCommands.map((n) => ({
@@ -193,7 +193,7 @@ class Ee extends ie {
193
193
  }
194
194
  const D = class D {
195
195
  constructor() {
196
- b(this, "currentStorage");
196
+ y(this, "currentStorage");
197
197
  }
198
198
  static getInstance() {
199
199
  return D.instance || (D.instance = new D()), D.instance;
@@ -212,7 +212,7 @@ const D = class D {
212
212
  return this.currentStorage;
213
213
  }
214
214
  };
215
- b(D, "instance");
215
+ y(D, "instance");
216
216
  let q = D;
217
217
  const le = async () => new ae("");
218
218
  class J {
@@ -240,10 +240,10 @@ class _e extends J {
240
240
  }
241
241
  class Ae {
242
242
  constructor(e, n, t = le) {
243
- b(this, "_segments");
244
- b(this, "_description");
243
+ y(this, "_segments");
244
+ y(this, "_description");
245
245
  // Used by `Help` command, etc.
246
- b(this, "_handler");
246
+ y(this, "_handler");
247
247
  this._segments = e, this._description = n, this._handler = t;
248
248
  }
249
249
  get segments() {
@@ -270,7 +270,7 @@ class Ae {
270
270
  }
271
271
  class Q {
272
272
  constructor() {
273
- b(this, "_commands", []);
273
+ y(this, "_commands", []);
274
274
  }
275
275
  get commands() {
276
276
  return this._commands;
@@ -301,6 +301,16 @@ class Q {
301
301
  throw new Error(`Duplicate commands: '${s.fullPath_s}' and '${o.fullPath_s}'`);
302
302
  this._commands.push(o);
303
303
  }
304
+ /**
305
+ * Removes a command that exactly matches the provided path.
306
+ *
307
+ * @param path The command path to remove.
308
+ * @returns True if a command was removed; otherwise false.
309
+ */
310
+ removeCommand(e) {
311
+ const n = e.join(" "), t = this._commands.findIndex((o) => o.fullPath.join(" ") === n);
312
+ return t === -1 ? !1 : (this._commands.splice(t, 1), !0);
313
+ }
304
314
  /**
305
315
  * Retrieves a command from the registry for the given path.
306
316
  *
@@ -346,10 +356,10 @@ class Q {
346
356
  * @returns An array of completion strings.
347
357
  */
348
358
  getCompletions(e) {
349
- if (C.debug("[getCompletions] path: ", e), !e.length) {
359
+ if (E.debug("[getCompletions] path: ", e), !e.length) {
350
360
  const s = this._commands.map((d) => d.segments[0]), a = (d, c) => d.type === c.type && d.name === c.name;
351
361
  return s.filter(
352
- (d, c, u) => c === u.findIndex((p) => a(p, d))
362
+ (d, c, u) => c === u.findIndex((h) => a(h, d))
353
363
  );
354
364
  }
355
365
  const n = e.length;
@@ -378,9 +388,9 @@ class Q {
378
388
  }
379
389
  class de {
380
390
  constructor() {
381
- b(this, "segments", []);
382
- b(this, "nullSegment", new ce());
383
- b(this, "observers", []);
391
+ y(this, "segments", []);
392
+ y(this, "nullSegment", new ce());
393
+ y(this, "observers", []);
384
394
  }
385
395
  subscribe(e) {
386
396
  this.observers.push(e);
@@ -487,13 +497,19 @@ const ze = {
487
497
  s.storage ?? z.storage
488
498
  ), o(q.getInstance().getStorage());
489
499
  }, []), A(() => {
490
- if (e && s.includeHelpCommand && !e.commandExistsForPath(["help"])) {
491
- const l = Se(e);
492
- e.addCommand(
493
- [{ type: "word", name: "help" }],
494
- "Show available commands",
495
- l
496
- );
500
+ if (e) {
501
+ if (s.includeHelpCommand) {
502
+ if (!e.commandExistsForPath(["help"])) {
503
+ const l = Se(e);
504
+ e.addCommand(
505
+ [{ type: "word", name: "help" }],
506
+ "Show available commands",
507
+ l
508
+ );
509
+ }
510
+ return;
511
+ }
512
+ e.removeCommand(["help"]);
497
513
  }
498
514
  }, [e, s.includeHelpCommand]);
499
515
  const a = {
@@ -526,13 +542,13 @@ const ze = {
526
542
  };
527
543
  class Re {
528
544
  constructor(e, n) {
529
- b(this, "timestamp");
530
- b(this, "command");
531
- b(this, "result");
545
+ y(this, "timestamp");
546
+ y(this, "command");
547
+ y(this, "result");
532
548
  this.command = e.toArray().map((t) => t.type === "argument" ? t.value || "" : t.name), this.timestamp = Date.now(), this.result = n ?? new Ce();
533
549
  }
534
550
  }
535
- function Pe(r) {
551
+ function He(r) {
536
552
  return {
537
553
  commandSegments: r,
538
554
  timestamp: Date.now()
@@ -542,10 +558,10 @@ function ue() {
542
558
  const r = me(), [e, n] = R({
543
559
  storedCommands: [],
544
560
  position: null
545
- }), t = w(async (l) => {
561
+ }), t = b(async (l) => {
546
562
  if (r)
547
563
  try {
548
- const d = Pe(l);
564
+ const d = He(l);
549
565
  await r.addStoredCommand(d), n((c) => ({
550
566
  ...c,
551
567
  storedCommands: [...c.storedCommands, d],
@@ -554,7 +570,7 @@ function ue() {
554
570
  } catch (d) {
555
571
  console.warn("Failed to save command to history:", d);
556
572
  }
557
- }, [r]), o = w(async () => r ? await r.getStoredCommands() : [], [r]);
573
+ }, [r]), o = b(async () => r ? await r.getStoredCommands() : [], [r]);
558
574
  A(() => {
559
575
  if (!r) return;
560
576
  (async () => {
@@ -569,12 +585,12 @@ function ue() {
569
585
  }
570
586
  })();
571
587
  }, [r]);
572
- const s = w(async (l) => {
588
+ const s = b(async (l) => {
573
589
  if ((await o()).length === 0)
574
590
  return { segments: null, position: null };
575
591
  let c = null;
576
- return l === "up" ? e.position === null ? c = e.storedCommands.length - 1 : e.position > 0 ? c = e.position - 1 : c = 0 : e.position === null || e.position >= e.storedCommands.length - 1 ? c = null : c = e.position + 1, n((p) => ({
577
- ...p,
592
+ return l === "up" ? e.position === null ? c = e.storedCommands.length - 1 : e.position > 0 ? c = e.position - 1 : c = 0 : e.position === null || e.position >= e.storedCommands.length - 1 ? c = null : c = e.position + 1, n((h) => ({
593
+ ...h,
578
594
  position: c
579
595
  })), c === null ? {
580
596
  segments: [],
@@ -583,7 +599,7 @@ function ue() {
583
599
  segments: c !== null ? e.storedCommands[c].commandSegments : null,
584
600
  position: c
585
601
  };
586
- }, [e, o]), a = w(async () => {
602
+ }, [e, o]), a = b(async () => {
587
603
  try {
588
604
  if (!r) return;
589
605
  await r.clear(), n({
@@ -625,78 +641,78 @@ const X = () => {
625
641
  }));
626
642
  }, [n.history, o]);
627
643
  const l = {
628
- setCurrentInput: w((u) => {
629
- C.debug("[CitadelActions] setCurrentInput: ", u), a((p) => ({ ...p, currentInput: u }));
644
+ setCurrentInput: b((u) => {
645
+ E.debug("[CitadelActions] setCurrentInput: ", u), a((h) => ({ ...h, currentInput: u }));
630
646
  }, []),
631
- setIsEnteringArg: w((u) => {
632
- C.debug("[CitadelActions] setIsEnteringArg: ", u), a((p) => ({ ...p, isEnteringArg: u }));
647
+ setIsEnteringArg: b((u) => {
648
+ E.debug("[CitadelActions] setIsEnteringArg: ", u), a((h) => ({ ...h, isEnteringArg: u }));
633
649
  }, []),
634
- addOutput: w((u) => {
635
- C.debug("[CitadelActions]addOutput: ", u), a((p) => ({
636
- ...p,
637
- output: [...p.output, u]
650
+ addOutput: b((u) => {
651
+ E.debug("[CitadelActions]addOutput: ", u), a((h) => ({
652
+ ...h,
653
+ output: [...h.output, u]
638
654
  }));
639
655
  }, []),
640
- executeCommand: w(async () => {
641
- const u = t.path(), p = e.getCommand(u);
642
- if (!p) {
656
+ executeCommand: b(async () => {
657
+ const u = t.path(), h = e.getCommand(u);
658
+ if (!h) {
643
659
  console.error("[CitadelActions][executeCommand] Cannot execute command because no command was found for the given path: ", u);
644
660
  return;
645
661
  }
646
- const k = new Re(t);
647
- a((y) => ({
648
- ...y,
649
- output: [...y.output, k]
662
+ const C = new Re(t);
663
+ a((f) => ({
664
+ ...f,
665
+ output: [...f.output, C]
650
666
  }));
651
667
  try {
652
- const y = new Promise((i, h) => {
668
+ const f = new Promise((i, p) => {
653
669
  setTimeout(() => {
654
- h(new Error("Request timed out"));
670
+ p(new Error("Request timed out"));
655
671
  }, r.commandTimeoutMs);
656
- }), E = t.arguments.map((i) => i.value || ""), N = await Promise.race([
657
- p.handler(E),
658
- y
672
+ }), x = t.arguments.map((i) => i.value || ""), k = await Promise.race([
673
+ h.handler(x),
674
+ f
659
675
  ]);
660
- if (!(N instanceof U))
676
+ if (!(k instanceof U))
661
677
  throw new Error(
662
678
  `The ${u.join(".")} command returned an invalid result type. Commands must return an instance of a CommandResult.
663
679
  For example:
664
680
  return new JsonCommandResult({ text: "Hello World" });
665
681
  Check the definition of the ${u.join(".")} command and update the return type for its handler.`
666
682
  );
667
- N.markSuccess(), a((i) => ({
683
+ k.markSuccess(), a((i) => ({
668
684
  ...i,
669
685
  output: i.output.map(
670
- (h) => h.timestamp === k.timestamp ? { ...h, result: N } : h
686
+ (p) => p.timestamp === C.timestamp ? { ...p, result: k } : p
671
687
  )
672
688
  }));
673
- } catch (y) {
674
- const E = new ve(
675
- y instanceof Error ? y.message : "Unknown error"
689
+ } catch (f) {
690
+ const x = new ve(
691
+ f instanceof Error ? f.message : "Unknown error"
676
692
  );
677
- E.markFailure(), a((N) => ({
678
- ...N,
679
- output: N.output.map(
680
- (i) => i.timestamp === k.timestamp ? { ...i, result: E } : i
693
+ x.markFailure(), a((k) => ({
694
+ ...k,
695
+ output: k.output.map(
696
+ (i) => i.timestamp === C.timestamp ? { ...i, result: x } : i
681
697
  )
682
698
  }));
683
699
  }
684
700
  }, [e, r.commandTimeoutMs, t]),
685
- clearHistory: w(async () => {
701
+ clearHistory: b(async () => {
686
702
  try {
687
703
  await n.clear();
688
704
  } catch (u) {
689
705
  console.warn("Failed to clear history:", u);
690
706
  }
691
707
  }, [n])
692
- }, d = w(() => e.getCompletions_s(t.path()), [t, e]), c = w(() => e.getCompletions(t.path()), [t, e]);
708
+ }, d = b(() => e.getCompletions_s(t.path()), [t, e]), c = b(() => e.getCompletions(t.path()), [t, e]);
693
709
  return {
694
710
  state: s,
695
711
  actions: l,
696
712
  getAvailableCommands_s: d,
697
713
  getAvailableCommandSegments: c
698
714
  };
699
- }, He = ({ onOpen: r, onClose: e, isVisible: n, showCitadelKey: t }) => {
715
+ }, Pe = ({ onOpen: r, onClose: e, isVisible: n, showCitadelKey: t }) => {
700
716
  A(() => {
701
717
  const o = (s) => {
702
718
  var a, l;
@@ -775,7 +791,7 @@ Check the definition of the ${u.join(".")} command and update the return type fo
775
791
  }
776
792
  )
777
793
  ] }), Ve = ({ output: r, outputRef: e }) => {
778
- const n = F(), t = w(() => {
794
+ const n = F(), t = b(() => {
779
795
  if (e.current) {
780
796
  const o = e.current;
781
797
  requestAnimationFrame(() => {
@@ -841,7 +857,7 @@ Check the definition of the ${u.join(".")} command and update the return type fo
841
857
  A(() => {
842
858
  if (t.speed === 0) return;
843
859
  const u = setInterval(() => {
844
- t.type === "blink" ? s((p) => !p) : ["spin", "bbs"].includes(t.type) && l((p) => (p + 1) % (t.type === "bbs" ? ne.length : ee.length));
860
+ t.type === "blink" ? s((h) => !h) : ["spin", "bbs"].includes(t.type) && l((h) => (h + 1) % (t.type === "bbs" ? ne.length : ee.length));
845
861
  }, t.speed);
846
862
  return () => clearInterval(u);
847
863
  }, [t.type, t.speed]);
@@ -862,7 +878,7 @@ Check the definition of the ${u.join(".")} command and update the return type fo
862
878
  function Ye(r, e) {
863
879
  switch (e.type) {
864
880
  case "set":
865
- return C.debug(`[inputStateReducer] InputState changing from ${r} to ${e.state}`), e.state;
881
+ return E.debug(`[inputStateReducer] InputState changing from ${r} to ${e.state}`), e.state;
866
882
  default:
867
883
  return r;
868
884
  }
@@ -870,83 +886,83 @@ function Ye(r, e) {
870
886
  const Be = () => {
871
887
  const { state: r } = X(), e = B(), n = ue(), t = O(), [o, s] = ye(Ye, "idle"), a = (i) => {
872
888
  s({ type: "set", state: i });
873
- }, l = w(() => {
874
- const h = e.getCompletions(t.path())[0] || t.nullSegment;
875
- return C.debug("[getNextExpectedSegment] ", h), h;
876
- }, [e, t]), d = w(() => e.getCompletions_s(t.path()).map((h) => e.getCommand([...t.path(), h])).filter((h) => h !== void 0), [e, t]), c = w((i, h) => {
877
- if (!i) return h;
878
- const g = h.reduce((f, x) => {
879
- const v = l();
880
- return (v == null ? void 0 : v.type) === "word" && f.set(v.name, x), f;
889
+ }, l = b(() => {
890
+ const p = e.getCompletions(t.path())[0] || t.nullSegment;
891
+ return E.debug("[getNextExpectedSegment] ", p), p;
892
+ }, [e, t]), d = b(() => e.getCompletions_s(t.path()).map((p) => e.getCommand([...t.path(), p])).filter((p) => p !== void 0), [e, t]), c = b((i, p) => {
893
+ if (!i) return p;
894
+ const g = p.reduce((w, v) => {
895
+ const S = l();
896
+ return (S == null ? void 0 : S.type) === "word" && w.set(S.name, v), w;
881
897
  }, /* @__PURE__ */ new Map());
882
898
  return Array.from(g.values()).filter(() => {
883
- const f = l();
884
- return f.type !== "word" ? !1 : f.name.toLowerCase().startsWith(i.toLowerCase());
899
+ const w = l();
900
+ return w.type !== "word" ? !1 : w.name.toLowerCase().startsWith(i.toLowerCase());
885
901
  });
886
- }, [l]), u = w((i) => {
887
- const g = e.getCompletions(t.path()).filter((S) => S.type === "word").filter(
888
- (S) => S.name.toLowerCase().startsWith(i.toLowerCase())
902
+ }, [l]), u = b((i) => {
903
+ const g = e.getCompletions(t.path()).filter((N) => N.type === "word").filter(
904
+ (N) => N.name.toLowerCase().startsWith(i.toLowerCase())
889
905
  );
890
906
  return g.length === 1 ? g[0] : t.nullSegment;
891
- }, [e, t]), p = w((i) => {
892
- const h = t.path(), g = e.getCompletions(h);
893
- return g.length === 0 && i ? !1 : g.some((f) => f.type === "argument") ? !0 : g.some(
894
- (f) => f.type === "word" && f.name.toLowerCase().startsWith(i.toLowerCase())
907
+ }, [e, t]), h = b((i) => {
908
+ const p = t.path(), g = e.getCompletions(p);
909
+ return g.length === 0 && i ? !1 : g.some((w) => w.type === "argument") ? !0 : g.some(
910
+ (w) => w.type === "word" && w.name.toLowerCase().startsWith(i.toLowerCase())
895
911
  );
896
- }, [e, t]), k = w((i) => {
897
- C.debug("[tryAutoComplete] input: ", i);
898
- const h = u(i);
899
- return !h || h.name === i ? new ce() : (C.debug("[tryAutoComplete] result: ", h), h);
900
- }, [u]), y = w((i, h) => {
912
+ }, [e, t]), C = b((i) => {
913
+ E.debug("[tryAutoComplete] input: ", i);
914
+ const p = u(i);
915
+ return !p || p.name === i ? new ce() : (E.debug("[tryAutoComplete] result: ", p), p);
916
+ }, [u]), f = b((i, p) => {
901
917
  if (r.history.position === null) {
902
- if (h.setCurrentInput(i), C.debug("[useCommandParser][handleInputChange] newValue: ", i), o === "entering_argument") {
918
+ if (p.setCurrentInput(i), E.debug("[useCommandParser][handleInputChange] newValue: ", i), o === "entering_argument") {
903
919
  const g = te(i);
904
920
  if (g.isQuoted)
905
921
  if (g.isComplete) {
906
- const S = l();
907
- if (S.type === "argument") {
908
- const f = S;
909
- f.value = i.trim() || "", C.debug("[useCommandParser][handleInputChange][entering_command] pushing: ", f), t.push(f), h.setCurrentInput(""), a("idle");
922
+ const N = l();
923
+ if (N.type === "argument") {
924
+ const w = N;
925
+ w.value = i.trim() || "", E.debug("[useCommandParser][handleInputChange][entering_command] pushing: ", w), t.push(w), p.setCurrentInput(""), a("idle");
910
926
  return;
911
927
  }
912
928
  } else
913
929
  return;
914
930
  else if (g.isComplete) {
915
- const S = l();
916
- S.value = i.trim() || "", C.debug("[useCommandParser][handleInputChange][entering_command] pushing: ", S), t.push(S), h.setCurrentInput(""), a("idle");
931
+ const N = l();
932
+ N.value = i.trim() || "", E.debug("[useCommandParser][handleInputChange][entering_command] pushing: ", N), t.push(N), p.setCurrentInput(""), a("idle");
917
933
  return;
918
934
  } else
919
935
  return;
920
936
  }
921
937
  if (o == "entering_command") {
922
- const g = k(i);
938
+ const g = C(i);
923
939
  if (g.type === "word") {
924
- C.debug("[useCommandParser][handleInputChange][entering_command] pushing: ", g), t.push(g), h.setCurrentInput(""), a("idle");
940
+ E.debug("[useCommandParser][handleInputChange][entering_command] pushing: ", g), t.push(g), p.setCurrentInput(""), a("idle");
925
941
  return;
926
942
  }
927
943
  }
928
944
  }
929
- }, [k, r, l, o, t]), E = w((i) => {
945
+ }, [C, r, l, o, t]), x = b((i) => {
930
946
  i.setCurrentInput(""), i.setIsEnteringArg(!1), t.clear(), a("idle");
931
- }, [t]), N = w((i, h, g) => {
947
+ }, [t]), k = b((i, p, g) => {
932
948
  if (!(i.key === "Backspace" || i.key === "Enter" || i.key === "ArrowUp" || i.key === "ArrowDown" || i.key === "ArrowLeft" || i.key === "ArrowRight" || i.key === "Escape" || i.key === "Delete" || i.key === "Home" || i.key === "End" || i.key.length === 1))
933
949
  return !0;
934
- const { currentInput: f, isEnteringArg: x } = h, v = te(f);
950
+ const { currentInput: w, isEnteringArg: v } = p, S = te(w);
935
951
  switch (i.key) {
936
952
  case "Backspace":
937
- return f === "" && (i.preventDefault(), t.size() > 0 && t.pop(), a("idle")), !0;
953
+ return w === "" && (i.preventDefault(), t.size() > 0 && t.pop(), a("idle")), !0;
938
954
  case "Enter": {
939
- if (i.preventDefault(), v.isQuoted && !v.isComplete)
955
+ if (i.preventDefault(), S.isQuoted && !S.isComplete)
940
956
  return !0;
941
- if (o === "entering_argument" || x && f.trim()) {
957
+ if (o === "entering_argument" || v && w.trim()) {
942
958
  const G = l();
943
- G.value = f, C.debug("[handleKeyDown][Enter]['entering_argument'] pushing: ", G), t.push(G);
959
+ G.value = w, E.debug("[handleKeyDown][Enter]['entering_argument'] pushing: ", G), t.push(G);
944
960
  }
945
- const I = t.path(), P = e.getCommand(I);
946
- if (!P)
961
+ const I = t.path(), H = e.getCommand(I);
962
+ if (!H)
947
963
  return !1;
948
- const $ = P.segments.filter((M) => M.type === "argument"), K = t.arguments;
949
- return $.length > K.length ? !1 : (C.debug("[handleKeyDown][Enter] calling actions.executeCommand. segmentStack: ", t), g.executeCommand(), n.addStoredCommand(t.toArray()), E(g), !0);
964
+ const $ = H.segments.filter((M) => M.type === "argument"), K = t.arguments;
965
+ return $.length > K.length ? !1 : (E.debug("[handleKeyDown][Enter] calling actions.executeCommand. segmentStack: ", t), g.executeCommand(), n.addStoredCommand(t.toArray()), x(g), !0);
950
966
  }
951
967
  case "ArrowUp":
952
968
  return i.preventDefault(), (async () => {
@@ -959,9 +975,9 @@ const Be = () => {
959
975
  return I.segments && (t.clear(), t.pushAll(I.segments), g.setCurrentInput("")), !0;
960
976
  })();
961
977
  default: {
962
- if (!x && i.key.length === 1) {
963
- const I = f + i.key;
964
- if (!p(I))
978
+ if (!v && i.key.length === 1) {
979
+ const I = w + i.key;
980
+ if (!h(I))
965
981
  return i.preventDefault(), !1;
966
982
  }
967
983
  return !0;
@@ -969,16 +985,16 @@ const Be = () => {
969
985
  }
970
986
  }, [
971
987
  o,
972
- p,
988
+ h,
973
989
  l,
974
990
  n,
975
- E,
991
+ x,
976
992
  e,
977
993
  t
978
994
  ]);
979
995
  return {
980
- handleInputChange: y,
981
- handleKeyDown: N,
996
+ handleInputChange: f,
997
+ handleKeyDown: k,
982
998
  inputState: o,
983
999
  setInputStateWithLogging: a,
984
1000
  // Expose internal functions for testing
@@ -986,7 +1002,7 @@ const Be = () => {
986
1002
  getAutocompleteSuggestion: u,
987
1003
  getAvailableNodes: d,
988
1004
  getNextExpectedSegment: l,
989
- isValidCommandInput: p
1005
+ isValidCommandInput: h
990
1006
  };
991
1007
  };
992
1008
  function te(r) {
@@ -1020,62 +1036,62 @@ const Ge = () => {
1020
1036
  state: r,
1021
1037
  actions: e
1022
1038
  }) => {
1023
- const n = H(null), t = B(), o = O(), {
1039
+ const n = P(null), t = B(), o = O(), {
1024
1040
  handleKeyDown: s,
1025
1041
  handleInputChange: a,
1026
1042
  inputState: l,
1027
1043
  setInputStateWithLogging: d,
1028
1044
  getNextExpectedSegment: c
1029
- } = Be(), [u, p] = R(!1), k = F(), y = Ge(), E = async (x) => {
1030
- const v = s(x, r, e);
1031
- await Promise.resolve(v) === !1 && (p(!0), setTimeout(() => p(!1), 500));
1032
- }, N = (x) => {
1033
- a(x.target.value, e);
1034
- }, i = (x) => {
1035
- x.preventDefault();
1036
- const v = x.clipboardData.getData("text");
1037
- a(v, e);
1045
+ } = Be(), [u, h] = R(!1), C = F(), f = Ge(), x = async (v) => {
1046
+ const S = s(v, r, e);
1047
+ await Promise.resolve(S) === !1 && (h(!0), setTimeout(() => h(!1), 500));
1048
+ }, k = (v) => {
1049
+ a(v.target.value, e);
1050
+ }, i = (v) => {
1051
+ v.preventDefault();
1052
+ const S = v.clipboardData.getData("text");
1053
+ a(S, e);
1038
1054
  };
1039
1055
  A(() => {
1040
1056
  n.current && n.current.focus(), l !== "entering_command" && d("entering_command");
1041
1057
  }, [l, d]), A(() => {
1042
1058
  if (l !== "idle") return;
1043
- const x = c();
1044
- let v = "idle";
1045
- switch (x.type) {
1059
+ const v = c();
1060
+ let S = "idle";
1061
+ switch (v.type) {
1046
1062
  case "word":
1047
- v = "entering_command", e.setIsEnteringArg(!1);
1063
+ S = "entering_command", e.setIsEnteringArg(!1);
1048
1064
  break;
1049
1065
  case "argument":
1050
- v = "entering_argument", e.setIsEnteringArg(!0);
1066
+ S = "entering_argument", e.setIsEnteringArg(!0);
1051
1067
  break;
1052
1068
  }
1053
- d(v);
1054
- }, [y, l, c, d, e]);
1055
- const [h, g] = R([]);
1069
+ d(S);
1070
+ }, [f, l, c, d, e]);
1071
+ const [p, g] = R([]);
1056
1072
  A(() => {
1057
- const x = [], v = o.toArray().map((P, $) => {
1058
- x.push(P.name);
1059
- const K = t.hasNextSegment(x);
1060
- if (P.type === "argument") {
1061
- const M = P;
1073
+ const v = [], S = o.toArray().map((H, $) => {
1074
+ v.push(H.name);
1075
+ const K = t.hasNextSegment(v);
1076
+ if (H.type === "argument") {
1077
+ const M = H;
1062
1078
  return /* @__PURE__ */ _(L.Fragment, { children: [
1063
1079
  /* @__PURE__ */ m("span", { className: "text-gray-200 whitespace-pre", children: M.value }),
1064
1080
  $ < o.size() && K && /* @__PURE__ */ m("span", { className: "text-gray-200 whitespace-pre", children: " " })
1065
1081
  ] }, "arg-" + M.name + M.value);
1066
1082
  }
1067
1083
  return /* @__PURE__ */ _(L.Fragment, { children: [
1068
- /* @__PURE__ */ m("span", { className: "text-blue-400 whitespace-pre", children: P.name }),
1084
+ /* @__PURE__ */ m("span", { className: "text-blue-400 whitespace-pre", children: H.name }),
1069
1085
  $ < o.size() && K && /* @__PURE__ */ m("span", { className: "text-blue-400 whitespace-pre", children: " " })
1070
- ] }, "word-" + P.name);
1086
+ ] }, "word-" + H.name);
1071
1087
  });
1072
- g([/* @__PURE__ */ m("div", { className: "flex items-center gap-1", "data-testid": "user-input-area", children: v }, "{segmentStackVersion}")]);
1073
- }, [y, t, o]);
1074
- const [S, f] = R("");
1088
+ g([/* @__PURE__ */ m("div", { className: "flex items-center gap-1", "data-testid": "user-input-area", children: S }, "{segmentStackVersion}")]);
1089
+ }, [f, t, o]);
1090
+ const [N, w] = R("");
1075
1091
  return A(() => {
1076
- const x = c();
1077
- x.type === "argument" ? f(x.name) : f("");
1078
- }, [y, c]), /* @__PURE__ */ _("div", { className: "flex flex-col w-full bg-gray-900 rounded-lg p-4", children: [
1092
+ const v = c();
1093
+ v.type === "argument" ? w(v.name) : w("");
1094
+ }, [f, c]), /* @__PURE__ */ _("div", { className: "flex flex-col w-full bg-gray-900 rounded-lg p-4", children: [
1079
1095
  /* @__PURE__ */ m("style", { children: `
1080
1096
  @keyframes subtleGlow {
1081
1097
  0%, 100% { box-shadow: 0 0 0 rgba(239, 68, 68, 0); }
@@ -1088,7 +1104,7 @@ const Ge = () => {
1088
1104
  /* @__PURE__ */ _("div", { className: "flex items-center gap-2", children: [
1089
1105
  /* @__PURE__ */ m("div", { className: "text-gray-400 font-mono", children: ">" }),
1090
1106
  /* @__PURE__ */ _("div", { className: "flex-1 font-mono flex items-center", children: [
1091
- h,
1107
+ p,
1092
1108
  /* @__PURE__ */ _("div", { className: "relative flex-1", children: [
1093
1109
  /* @__PURE__ */ m(
1094
1110
  "input",
@@ -1097,14 +1113,14 @@ const Ge = () => {
1097
1113
  type: "text",
1098
1114
  role: "textbox",
1099
1115
  value: r.currentInput,
1100
- onChange: N,
1101
- onKeyDown: E,
1116
+ onChange: k,
1117
+ onKeyDown: x,
1102
1118
  onPaste: i,
1103
1119
  "data-testid": "citadel-command-input",
1104
1120
  className: `w-full bg-transparent outline-none text-gray-200 caret-transparent ${u ? "invalid-input-animation" : ""}`,
1105
1121
  spellCheck: !1,
1106
1122
  autoComplete: "off",
1107
- placeholder: S
1123
+ placeholder: N
1108
1124
  }
1109
1125
  ),
1110
1126
  /* @__PURE__ */ m(
@@ -1119,9 +1135,9 @@ const Ge = () => {
1119
1135
  qe,
1120
1136
  {
1121
1137
  style: {
1122
- type: k.cursorType ?? z.cursorType,
1123
- color: k.cursorColor || z.cursorColor,
1124
- speed: k.cursorSpeed || z.cursorSpeed
1138
+ type: C.cursorType ?? z.cursorType,
1139
+ color: C.cursorColor || z.cursorColor,
1140
+ speed: C.cursorSpeed || z.cursorSpeed
1125
1141
  }
1126
1142
  }
1127
1143
  )
@@ -1132,14 +1148,16 @@ const Ge = () => {
1132
1148
  ] })
1133
1149
  ] });
1134
1150
  }, Qe = () => {
1135
- const r = B(), e = F(), n = O(), t = "h-12 mt-2 border-t border-gray-700 px-4", o = "text-gray-300 pt-2", s = r.getCompletions(n.path());
1136
- C.debug("[AvailableCommands] nextCommandSegments: ", s);
1151
+ const r = B(), e = F(), n = O(), t = "mt-2 border-t border-gray-700 px-4 py-2", o = "text-gray-300", s = r.getCompletions(n.path());
1152
+ E.debug("[AvailableCommands] nextCommandSegments: ", s);
1137
1153
  const a = L.useMemo(() => {
1138
- if (e.includeHelpCommand) {
1139
- const c = s.filter((p) => p.name !== "help"), u = s.find((p) => p.name === "help");
1140
- return [...c, ...u ? [u] : []];
1141
- }
1142
- return s;
1154
+ const c = [...s], u = (x) => x.name.toLowerCase() === "help", C = c.filter((x) => !u(x)).sort(
1155
+ (x, k) => x.name.localeCompare(k.name, void 0, { sensitivity: "base" })
1156
+ );
1157
+ if (!e.includeHelpCommand)
1158
+ return C;
1159
+ const f = c.find(u);
1160
+ return f ? [...C, f] : C;
1143
1161
  }, [s, e.includeHelpCommand]), l = s.some((c) => c.type === "argument"), d = s[0];
1144
1162
  return /* @__PURE__ */ m("div", { className: t, "data-testid": "available-commands", children: /* @__PURE__ */ m("div", { className: o, children: l ? s.length > 0 ? /* @__PURE__ */ _(we, { children: [
1145
1163
  /* @__PURE__ */ m("span", { className: "text-blue-400", children: d.name }),
@@ -1148,12 +1166,12 @@ const Ge = () => {
1148
1166
  d.description
1149
1167
  ] })
1150
1168
  ] }) : null : /* @__PURE__ */ m("div", { className: "flex flex-wrap gap-2", children: a == null ? void 0 : a.map((c) => {
1151
- const u = a == null ? void 0 : a.reduce((p, k) => {
1152
- if (k === c) return p;
1153
- let y = 0;
1154
- for (; y < c.name.length && y < k.name.length && c.name[y].toLowerCase() === k.name[y].toLowerCase(); )
1155
- y++;
1156
- return Math.max(p, y + 1);
1169
+ const u = a == null ? void 0 : a.reduce((h, C) => {
1170
+ if (C === c) return h;
1171
+ let f = 0;
1172
+ for (; f < c.name.length && f < C.name.length && c.name[f].toLowerCase() === C.name[f].toLowerCase(); )
1173
+ f++;
1174
+ return Math.max(h, f + 1);
1157
1175
  }, 1);
1158
1176
  return /* @__PURE__ */ m(
1159
1177
  "div",
@@ -1178,36 +1196,36 @@ const Ge = () => {
1178
1196
  /* @__PURE__ */ m(Qe, {})
1179
1197
  ] })
1180
1198
  ] }), Xe = () => {
1181
- const [r, e] = R(!1), [n, t] = R(!1), o = F(), [s, a] = R(() => o.initialHeight || null), l = H(null), d = H(null), c = H(!1), u = H(0), p = H(0), { state: k, actions: y } = X();
1182
- He({
1199
+ const [r, e] = R(!1), [n, t] = R(!1), o = F(), [s, a] = R(() => o.initialHeight || null), l = P(null), d = P(null), c = P(!1), u = P(0), h = P(0), { state: C, actions: f } = X();
1200
+ Pe({
1183
1201
  onOpen: () => e(!0),
1184
1202
  onClose: () => t(!0),
1185
1203
  isVisible: r,
1186
1204
  showCitadelKey: o.showCitadelKey || "."
1187
1205
  });
1188
- const E = w((g) => {
1189
- var v;
1206
+ const x = b((g) => {
1207
+ var S;
1190
1208
  if (!c.current) return;
1191
- const S = g.clientY - u.current, f = (v = o.maxHeight) != null && v.endsWith("vh") ? window.innerHeight * parseInt(o.maxHeight, 10) / 100 : parseInt(o.maxHeight || "80vh", 10), x = Math.min(
1192
- Math.max(p.current - S, parseInt(o.minHeight || "200", 10)),
1193
- f
1209
+ const N = g.clientY - u.current, w = (S = o.maxHeight) != null && S.endsWith("vh") ? window.innerHeight * parseInt(o.maxHeight, 10) / 100 : parseInt(o.maxHeight || "80vh", 10), v = Math.min(
1210
+ Math.max(h.current - N, parseInt(o.minHeight || "200", 10)),
1211
+ w
1194
1212
  );
1195
- d.current && (d.current.style.height = `${x}px`, d.current.style.bottom = "0", a(`${x}px`));
1196
- }, [o.maxHeight, o.minHeight]), N = w(() => {
1197
- c.current = !1, document.documentElement.style.userSelect = "", document.documentElement.style.webkitUserSelect = "", document.documentElement.style.mozUserSelect = "", document.documentElement.style.msUserSelect = "", document.removeEventListener("mousemove", E), document.removeEventListener("mouseup", N);
1198
- }, [E]), i = w((g) => {
1199
- d.current && (c.current = !0, u.current = g.clientY, p.current = d.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", E), document.addEventListener("mouseup", N));
1200
- }, [E, N]);
1213
+ d.current && (d.current.style.height = `${v}px`, d.current.style.bottom = "0", a(`${v}px`));
1214
+ }, [o.maxHeight, o.minHeight]), k = b(() => {
1215
+ c.current = !1, document.documentElement.style.userSelect = "", document.documentElement.style.webkitUserSelect = "", document.documentElement.style.mozUserSelect = "", document.documentElement.style.msUserSelect = "", document.removeEventListener("mousemove", x), document.removeEventListener("mouseup", k);
1216
+ }, [x]), i = b((g) => {
1217
+ d.current && (c.current = !0, u.current = g.clientY, h.current = d.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", x), document.addEventListener("mouseup", k));
1218
+ }, [x, k]);
1201
1219
  A(() => () => {
1202
- document.removeEventListener("mousemove", E), document.removeEventListener("mouseup", N);
1203
- }, [E, N]);
1204
- const h = w(() => {
1220
+ document.removeEventListener("mousemove", x), document.removeEventListener("mouseup", k);
1221
+ }, [x, k]);
1222
+ const p = b(() => {
1205
1223
  n && (e(!1), t(!1));
1206
1224
  }, [n]);
1207
1225
  return $e({
1208
1226
  isVisible: r,
1209
1227
  isClosing: n,
1210
- onAnimationComplete: h
1228
+ onAnimationComplete: p
1211
1229
  }), r ? /* @__PURE__ */ _(
1212
1230
  "div",
1213
1231
  {
@@ -1222,8 +1240,8 @@ const Ge = () => {
1222
1240
  /* @__PURE__ */ m(
1223
1241
  pe,
1224
1242
  {
1225
- state: k,
1226
- actions: y,
1243
+ state: C,
1244
+ actions: f,
1227
1245
  outputRef: l
1228
1246
  }
1229
1247
  )
@@ -1231,7 +1249,7 @@ const Ge = () => {
1231
1249
  }
1232
1250
  ) : null;
1233
1251
  }, Ze = () => {
1234
- const { state: r, actions: e } = X(), n = H(null);
1252
+ const { state: r, actions: e } = X(), n = P(null);
1235
1253
  return /* @__PURE__ */ m(
1236
1254
  "div",
1237
1255
  {
@@ -2258,9 +2276,9 @@ video {
2258
2276
  commandRegistry: e = new Q(),
2259
2277
  containerId: n = null
2260
2278
  }) => {
2261
- const t = H(null), o = r.displayMode ?? z.displayMode ?? "panel";
2279
+ const t = P(null), o = r.displayMode ?? z.displayMode ?? "panel";
2262
2280
  return A(() => {
2263
- C.configure({
2281
+ E.configure({
2264
2282
  level: r.logLevel || z.logLevel || W.ERROR,
2265
2283
  prefix: "[Citadel]"
2266
2284
  });
@@ -2284,10 +2302,10 @@ class he extends HTMLElement {
2284
2302
  constructor(n, t) {
2285
2303
  var s;
2286
2304
  super();
2287
- b(this, "shadow");
2288
- b(this, "root", null);
2289
- b(this, "commandRegistry");
2290
- b(this, "config");
2305
+ y(this, "shadow");
2306
+ y(this, "root", null);
2307
+ y(this, "commandRegistry");
2308
+ y(this, "config");
2291
2309
  this.shadow = this.attachShadow({ mode: "open" }), this.commandRegistry = n, this.config = t;
2292
2310
  const o = ((s = this.config) == null ? void 0 : s.displayMode) ?? "panel";
2293
2311
  this.setAttribute("data-display-mode", o);
@@ -1,9 +1,9 @@
1
- (function(w,i){typeof exports=="object"&&typeof module<"u"?i(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"],i):(w=typeof globalThis<"u"?globalThis:w||self,i(w.Citadel={},w.jsxRuntime,w.React,w.client))})(this,function(w,i,s,pe){"use strict";var Ke=Object.defineProperty;var Le=(w,i,s)=>i in w?Ke(w,i,{enumerable:!0,configurable:!0,writable:!0,value:s}):w[i]=s;var y=(w,i,s)=>Le(w,typeof i!="symbol"?i+"":i,s);var D=(r=>(r.Pending="pending",r.Success="success",r.Failure="failure",r.Timeout="timeout",r))(D||{});class P{constructor(e=Date.now()){y(this,"_status","pending");this.timestamp=e}get status(){return this._status}markSuccess(){this._status="success"}markFailure(){this._status="failure"}markTimeout(){this._status="timeout"}}class he extends P{constructor(e,n){super(n),this.data=e}render(){return i.jsx("pre",{className:"text-gray-200",children:JSON.stringify(this.data,null,2)})}}class V extends P{constructor(e,n){super(n),this.text=e}render(){return i.jsx("div",{className:"text-gray-200 whitespace-pre font-mono",children:this.text})}}class G extends P{constructor(e,n){super(n),this.error=e,this.markFailure()}render(){return i.jsx("div",{className:"mt-1 text-red-400",children:this.error})}}class J extends P{render(){return i.jsx("div",{className:"text-gray-400",children:"..."})}}class ge extends P{constructor(e,n="",t){super(t),this.imageUrl=e,this.altText=n}render(){return i.jsx("div",{className:"my-2",children:i.jsx("img",{src:this.imageUrl,alt:this.altText,className:"max-w-[400px] max-h-[300px] h-auto rounded-lg object-contain"})})}}const fe=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.push("help - Show available commands"),new V(e.length>0?`Available Commands:
1
+ (function(w,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):(w=typeof globalThis<"u"?globalThis:w||self,a(w.Citadel={},w.jsxRuntime,w.React,w.client))})(this,function(w,a,s,pe){"use strict";var $e=Object.defineProperty;var Ke=(w,a,s)=>a in w?$e(w,a,{enumerable:!0,configurable:!0,writable:!0,value:s}):w[a]=s;var x=(w,a,s)=>Ke(w,typeof a!="symbol"?a+"":a,s);var D=(r=>(r.Pending="pending",r.Success="success",r.Failure="failure",r.Timeout="timeout",r))(D||{});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 he 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 V 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 G 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 J extends P{render(){return a.jsx("div",{className:"text-gray-400",children:"..."})}}class ge 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 fe=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.push("help - Show available commands"),new V(e.length>0?`Available Commands:
2
2
  `+e.join(`
3
- `):"No commands available yet. Add some commands to get started!")};var j=(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))(j||{});class S{static configure(e){this.level=e.level,this.prefix=e.prefix||"[Citadel]"}static trace(...e){this.level>=5&&process.env.NODE_ENV!=="production"&&console.trace(this.prefix,...e)}static debug(...e){this.level>=4&&process.env.NODE_ENV!=="production"&&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)}}y(S,"level",0),y(S,"prefix","");const A={commandTimeoutMs:1e4,cursorColor:"var(--cursor-color, #fff)",cursorSpeed:530,cursorType:"blink",includeHelpCommand:!0,initialHeight:"40vh",logLevel:process.env.NODE_ENV==="production"?j.ERROR:j.DEBUG,maxHeight:"80vh",minHeight:"200",outputFontSize:"0.875rem",resetStateOnHide:!1,showCitadelKey:".",displayMode:"panel",storage:{type:"localStorage",maxCommands:100}};class Q{constructor(e){y(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 we extends Q{constructor(n){super(n);y(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 be extends Q{constructor(n){super(n);y(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 H=class H{constructor(){y(this,"currentStorage")}static getInstance(){return H.instance||(H.instance=new H),H.instance}initializeStorage(e){if(!this.currentStorage)try{this.currentStorage=new we(e)}catch(n){console.warn("Failed to create storage, falling back to memory storage:",n),this.currentStorage=new be(e)}}getStorage(){if(!this.currentStorage)throw new Error("Storage not initialized. Call initializeStorage first.");return this.currentStorage}};y(H,"instance");let O=H;const X=async()=>new V("");class W{constructor(e,n,t){this.type=e,this.name=n,this.description=t}toString(){return this.name}}class Z extends W{constructor(){super("null",">null<","Empty segment")}}class ye extends W{constructor(e,n){super("word",e,n)}}class xe extends W{constructor(e,n,t,o){super("argument",e,n),this.value=t,this.valid=o}}class Ce{constructor(e,n,t=X){y(this,"_segments");y(this,"_description");y(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 ${constructor(){y(this,"_commands",[])}get commands(){return this._commands}addCommand(e,n,t=X){if(e===void 0||e.length===0)throw new Error("Command path cannot be empty");const o=new Ce(e,n,t),a=this._commands.find(l=>{const d=l.segments.map(m=>m.type==="argument"?"*":m.name).join(" "),u=e.map(m=>m.type==="argument"?"*":m.name).join(" ");return d===u});if(a)throw new Error(`Duplicate commands: '${a.fullPath_s}' and '${o.fullPath_s}'`);this._commands.push(o)}getCommand(e){return this._commands.find(n=>{const t=n.fullPath.join(" "),o=e.join(" ");if(t===o)return!0;const l=n.segments.filter(d=>d.type==="word").map(d=>d.name);return l.length===e.length&&l.join(" ")===o})}commandExistsForPath(e){const n=this._commands.map(o=>o.segments.map(a=>a.type==="argument"?"*":a.name).join(" ")),t=e.map((o,a)=>this._commands.some(d=>{var u;return((u=d.segments[a])==null?void 0:u.type)==="argument"})?"*":o).join(" ");return n.includes(t)}getCompletions_s(e){return this.getCompletions(e).map(n=>n.name)}getCompletions(e){if(S.debug("[getCompletions] path: ",e),!e.length){const a=this._commands.map(u=>u.segments[0]),l=(u,m)=>u.type===m.type&&u.name===m.name;return a.filter((u,m,p)=>m===p.findIndex(h=>l(h,u)))}const n=e.length;return this._commands.filter(a=>{const l=a.segments;if(l.length<=n-1)return!1;for(let d=0;d<n;d++){const u=e[d],m=l[d];if(!(u==="*"&&m.type==="argument")&&u!==m.name)return!1}return!0}).filter(a=>a.segments.length>n).map(a=>{const l=a.segments[n],d=l.type==="argument"?xe:ye;return new d(l.name,l.description)}).filter((a,l,d)=>l===d.findIndex(u=>u.type===a.type&&u.name===a.name))}hasNextSegment(e){return this.getCompletions(e).length>0}}class R{constructor(){y(this,"segments",[]);y(this,"nullSegment",new Z);y(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:A,commands:new $,segmentStack:new R},U=s.createContext(ve),Se=({config:r=A,commandRegistry:e,children:n})=>{const[t,o]=s.useState(),a={...A,...r,storage:{...A.storage,...r.storage},cursorType:r.cursorType??A.cursorType,cursorColor:r.cursorColor??A.cursorColor,cursorSpeed:r.cursorSpeed??A.cursorSpeed,showCitadelKey:r.showCitadelKey||"."};s.useEffect(()=>{O.getInstance().initializeStorage(a.storage??A.storage),o(O.getInstance().getStorage())},[]),s.useEffect(()=>{if(e&&a.includeHelpCommand&&!e.commandExistsForPath(["help"])){const d=fe(e);e.addCommand([{type:"word",name:"help"}],"Show available commands",d)}},[e,a.includeHelpCommand]);const l={config:a,commands:e||new $,storage:t,segmentStack:new R};return i.jsx(U.Provider,{value:l,children:n})},M=()=>{const r=s.useContext(U);if(r===void 0)throw new Error("useCitadelConfig must be used within a CitadelConfigProvider");return r.config},K=()=>{const r=s.useContext(U);if(r===void 0)throw new Error("useCitadelCommands must be used within a CitadelConfigProvider");return r.commands},ee=()=>{const r=s.useContext(U);if(r===void 0)throw new Error("useCitadelStorage must be used within a CitadelConfigProvider");return r.storage},F=()=>{const r=s.useContext(U);if(r===void 0)throw new Error("useSegmentStack must be used within a CitadelConfigProvider");return r.segmentStack};class ne{constructor(e,n){y(this,"timestamp");y(this,"command");y(this,"result");this.command=e.toArray().map(t=>t.type==="argument"?t.value||"":t.name),this.timestamp=Date.now(),this.result=n??new J}}function ke(r){return{commandSegments:r,timestamp:Date.now()}}function te(){const r=ee(),[e,n]=s.useState({storedCommands:[],position:null}),t=s.useCallback(async d=>{if(r)try{const u=ke(d);await r.addStoredCommand(u),n(m=>({...m,storedCommands:[...m.storedCommands,u],position:null}))}catch(u){console.warn("Failed to save command to history:",u)}},[r]),o=s.useCallback(async()=>r?await r.getStoredCommands():[],[r]);s.useEffect(()=>{if(!r)return;(async()=>{try{const u=await r.getStoredCommands();return n(m=>({...m,storedCommands:u})),u}catch(u){console.warn("Failed to load command history:",u)}})()},[r]);const a=s.useCallback(async d=>{if((await o()).length===0)return{segments:null,position:null};let m=null;return d==="up"?e.position===null?m=e.storedCommands.length-1:e.position>0?m=e.position-1:m=0:e.position===null||e.position>=e.storedCommands.length-1?m=null:m=e.position+1,n(h=>({...h,position:m})),m===null?{segments:[],position:null}:{segments:m!==null?e.storedCommands[m].commandSegments:null,position:m}},[e,o]),l=s.useCallback(async()=>{try{if(!r)return;await r.clear(),n({storedCommands:[],position:null})}catch(d){console.warn("Failed to clear command history:",d)}},[r]);return{history:e,addStoredCommand:t,getStoredCommands:o,navigateHistory:a,clear:l}}const Y=()=>{const r=M(),e=K(),n=te(),t=F(),o=ee(),[a,l]=s.useState({currentInput:"",isEnteringArg:!1,output:[],history:{commands:[],position:null,storage:o}});s.useEffect(()=>{},[o]),s.useEffect(()=>{l(p=>({...p,history:{commands:n.history.storedCommands,position:n.history.position,storage:o}}))},[n.history,o]);const d={setCurrentInput:s.useCallback(p=>{S.debug("[CitadelActions] setCurrentInput: ",p),l(h=>({...h,currentInput:p}))},[]),setIsEnteringArg:s.useCallback(p=>{S.debug("[CitadelActions] setIsEnteringArg: ",p),l(h=>({...h,isEnteringArg:p}))},[]),addOutput:s.useCallback(p=>{S.debug("[CitadelActions]addOutput: ",p),l(h=>({...h,output:[...h.output,p]}))},[]),executeCommand:s.useCallback(async()=>{const p=t.path(),h=e.getCommand(p);if(!h){console.error("[CitadelActions][executeCommand] Cannot execute command because no command was found for the given path: ",p);return}const E=new ne(t);l(x=>({...x,output:[...x.output,E]}));try{const x=new Promise((c,g)=>{setTimeout(()=>{g(new Error("Request timed out"))},r.commandTimeoutMs)}),_=t.arguments.map(c=>c.value||""),N=await Promise.race([h.handler(_),x]);if(!(N instanceof P))throw new Error(`The ${p.join(".")} command returned an invalid result type. Commands must return an instance of a CommandResult.
3
+ `):"No commands available yet. Add some commands to get started!")};var F=(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))(F||{});class E{static configure(e){this.level=e.level,this.prefix=e.prefix||"[Citadel]"}static trace(...e){this.level>=5&&process.env.NODE_ENV!=="production"&&console.trace(this.prefix,...e)}static debug(...e){this.level>=4&&process.env.NODE_ENV!=="production"&&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(E,"level",0),x(E,"prefix","");const A={commandTimeoutMs:1e4,cursorColor:"var(--cursor-color, #fff)",cursorSpeed:530,cursorType:"blink",includeHelpCommand:!0,initialHeight:"40vh",logLevel:process.env.NODE_ENV==="production"?F.ERROR:F.DEBUG,maxHeight:"80vh",minHeight:"200",outputFontSize:"0.875rem",resetStateOnHide:!1,showCitadelKey:".",displayMode:"panel",storage:{type:"localStorage",maxCommands:100}};class Q{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 we extends Q{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 be extends Q{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 H=class H{constructor(){x(this,"currentStorage")}static getInstance(){return H.instance||(H.instance=new H),H.instance}initializeStorage(e){if(!this.currentStorage)try{this.currentStorage=new we(e)}catch(n){console.warn("Failed to create storage, falling back to memory storage:",n),this.currentStorage=new be(e)}}getStorage(){if(!this.currentStorage)throw new Error("Storage not initialized. Call initializeStorage first.");return this.currentStorage}};x(H,"instance");let O=H;const X=async()=>new V("");class W{constructor(e,n,t){this.type=e,this.name=n,this.description=t}toString(){return this.name}}class Z extends W{constructor(){super("null",">null<","Empty segment")}}class ye extends W{constructor(e,n){super("word",e,n)}}class xe extends W{constructor(e,n,t,o){super("argument",e,n),this.value=t,this.valid=o}}class Ce{constructor(e,n,t=X){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 L{constructor(){x(this,"_commands",[])}get commands(){return this._commands}addCommand(e,n,t=X){if(e===void 0||e.length===0)throw new Error("Command path cannot be empty");const o=new Ce(e,n,t),i=this._commands.find(l=>{const m=l.segments.map(d=>d.type==="argument"?"*":d.name).join(" "),u=e.map(d=>d.type==="argument"?"*":d.name).join(" ");return m===u});if(i)throw new Error(`Duplicate commands: '${i.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 l=n.segments.filter(m=>m.type==="word").map(m=>m.name);return l.length===e.length&&l.join(" ")===o})}commandExistsForPath(e){const n=this._commands.map(o=>o.segments.map(i=>i.type==="argument"?"*":i.name).join(" ")),t=e.map((o,i)=>this._commands.some(m=>{var u;return((u=m.segments[i])==null?void 0:u.type)==="argument"})?"*":o).join(" ");return n.includes(t)}getCompletions_s(e){return this.getCompletions(e).map(n=>n.name)}getCompletions(e){if(E.debug("[getCompletions] path: ",e),!e.length){const i=this._commands.map(u=>u.segments[0]),l=(u,d)=>u.type===d.type&&u.name===d.name;return i.filter((u,d,p)=>d===p.findIndex(g=>l(g,u)))}const n=e.length;return this._commands.filter(i=>{const l=i.segments;if(l.length<=n-1)return!1;for(let m=0;m<n;m++){const u=e[m],d=l[m];if(!(u==="*"&&d.type==="argument")&&u!==d.name)return!1}return!0}).filter(i=>i.segments.length>n).map(i=>{const l=i.segments[n],m=l.type==="argument"?xe:ye;return new m(l.name,l.description)}).filter((i,l,m)=>l===m.findIndex(u=>u.type===i.type&&u.name===i.name))}hasNextSegment(e){return this.getCompletions(e).length>0}}class R{constructor(){x(this,"segments",[]);x(this,"nullSegment",new Z);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:A,commands:new L,segmentStack:new R},U=s.createContext(ve),Se=({config:r=A,commandRegistry:e,children:n})=>{const[t,o]=s.useState(),i={...A,...r,storage:{...A.storage,...r.storage},cursorType:r.cursorType??A.cursorType,cursorColor:r.cursorColor??A.cursorColor,cursorSpeed:r.cursorSpeed??A.cursorSpeed,showCitadelKey:r.showCitadelKey||"."};s.useEffect(()=>{O.getInstance().initializeStorage(i.storage??A.storage),o(O.getInstance().getStorage())},[]),s.useEffect(()=>{if(e){if(i.includeHelpCommand){if(!e.commandExistsForPath(["help"])){const m=fe(e);e.addCommand([{type:"word",name:"help"}],"Show available commands",m)}return}e.removeCommand(["help"])}},[e,i.includeHelpCommand]);const l={config:i,commands:e||new L,storage:t,segmentStack:new R};return a.jsx(U.Provider,{value:l,children:n})},M=()=>{const r=s.useContext(U);if(r===void 0)throw new Error("useCitadelConfig must be used within a CitadelConfigProvider");return r.config},$=()=>{const r=s.useContext(U);if(r===void 0)throw new Error("useCitadelCommands must be used within a CitadelConfigProvider");return r.commands},ee=()=>{const r=s.useContext(U);if(r===void 0)throw new Error("useCitadelStorage must be used within a CitadelConfigProvider");return r.storage},j=()=>{const r=s.useContext(U);if(r===void 0)throw new Error("useSegmentStack must be used within a CitadelConfigProvider");return r.segmentStack};class ne{constructor(e,n){x(this,"timestamp");x(this,"command");x(this,"result");this.command=e.toArray().map(t=>t.type==="argument"?t.value||"":t.name),this.timestamp=Date.now(),this.result=n??new J}}function ke(r){return{commandSegments:r,timestamp:Date.now()}}function te(){const r=ee(),[e,n]=s.useState({storedCommands:[],position:null}),t=s.useCallback(async m=>{if(r)try{const u=ke(m);await r.addStoredCommand(u),n(d=>({...d,storedCommands:[...d.storedCommands,u],position:null}))}catch(u){console.warn("Failed to save command to history:",u)}},[r]),o=s.useCallback(async()=>r?await r.getStoredCommands():[],[r]);s.useEffect(()=>{if(!r)return;(async()=>{try{const u=await r.getStoredCommands();return n(d=>({...d,storedCommands:u})),u}catch(u){console.warn("Failed to load command history:",u)}})()},[r]);const i=s.useCallback(async m=>{if((await o()).length===0)return{segments:null,position:null};let d=null;return m==="up"?e.position===null?d=e.storedCommands.length-1:e.position>0?d=e.position-1:d=0:e.position===null||e.position>=e.storedCommands.length-1?d=null:d=e.position+1,n(g=>({...g,position:d})),d===null?{segments:[],position:null}:{segments:d!==null?e.storedCommands[d].commandSegments:null,position:d}},[e,o]),l=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:i,clear:l}}const Y=()=>{const r=M(),e=$(),n=te(),t=j(),o=ee(),[i,l]=s.useState({currentInput:"",isEnteringArg:!1,output:[],history:{commands:[],position:null,storage:o}});s.useEffect(()=>{},[o]),s.useEffect(()=>{l(p=>({...p,history:{commands:n.history.storedCommands,position:n.history.position,storage:o}}))},[n.history,o]);const m={setCurrentInput:s.useCallback(p=>{E.debug("[CitadelActions] setCurrentInput: ",p),l(g=>({...g,currentInput:p}))},[]),setIsEnteringArg:s.useCallback(p=>{E.debug("[CitadelActions] setIsEnteringArg: ",p),l(g=>({...g,isEnteringArg:p}))},[]),addOutput:s.useCallback(p=>{E.debug("[CitadelActions]addOutput: ",p),l(g=>({...g,output:[...g.output,p]}))},[]),executeCommand:s.useCallback(async()=>{const p=t.path(),g=e.getCommand(p);if(!g){console.error("[CitadelActions][executeCommand] Cannot execute command because no command was found for the given path: ",p);return}const S=new ne(t);l(b=>({...b,output:[...b.output,S]}));try{const b=new Promise((c,h)=>{setTimeout(()=>{h(new Error("Request timed out"))},r.commandTimeoutMs)}),C=t.arguments.map(c=>c.value||""),_=await Promise.race([g.handler(C),b]);if(!(_ instanceof P))throw new Error(`The ${p.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 ${p.join(".")} command and update the return type for its handler.`);N.markSuccess(),l(c=>({...c,output:c.output.map(g=>g.timestamp===E.timestamp?{...g,result:N}:g)}))}catch(x){const _=new G(x instanceof Error?x.message:"Unknown error");_.markFailure(),l(N=>({...N,output:N.output.map(c=>c.timestamp===E.timestamp?{...c,result:_}:c)}))}},[e,r.commandTimeoutMs,t]),clearHistory:s.useCallback(async()=>{try{await n.clear()}catch(p){console.warn("Failed to clear history:",p)}},[n])},u=s.useCallback(()=>e.getCompletions_s(t.path()),[t,e]),m=s.useCallback(()=>e.getCompletions(t.path()),[t,e]);return{state:a,actions:d,getAvailableCommands_s:u,getAvailableCommandSegments:m}},Ee=({onOpen:r,onClose:e,isVisible:n,showCitadelKey:t})=>{s.useEffect(()=>{const o=a=>{var l,d;!n&&a.key===t&&!["input","textarea"].includes(((d=(l=a.target)==null?void 0:l.tagName)==null?void 0:d.toLowerCase())||"")&&(a.preventDefault(),r()),n&&a.key==="Escape"&&(a.preventDefault(),e())};return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[r,e,n,t])},re={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"},_e=r=>{const{isVisible:e,isClosing:n,onAnimationComplete:t}=r,o=s.useMemo(()=>e?n?re.slideDown:re.slideUp:"",[e,n]);return s.useEffect(()=>{if(t){const l=setTimeout(()=>{t()},200);return()=>clearTimeout(l)}},[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}},Ne=()=>i.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})=>i.jsxs("div",{className:"flex items-center gap-2 font-mono text-sm",children:[i.jsxs("span",{className:"text-gray-200",children:["> ",r.split(" ").map((t,o)=>{const a=t.startsWith("<")&&t.endsWith(">");return i.jsxs("span",{className:a?"text-green-400":"text-gray-200",children:[o>0?" ":"",t]},o)})]}),i.jsx("span",{className:"text-gray-400",children:"·"}),i.jsx("span",{className:"text-gray-500",children:e}),n===D.Pending&&i.jsx(Ne,{}),n===D.Success&&i.jsx("div",{"data-testid":"success-indicator",className:"w-4 h-4 rounded-full bg-green-500"}),(n===D.Timeout||n===D.Failure)&&i.jsx("div",{"data-testid":"success-indicator",className:"w-4 h-4 rounded-full bg-red-500"})]}),ze=({output:r,outputRef:e})=>{const n=M(),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"),a=o[o.length-1];if(a&&!a.complete)return a.addEventListener("load",t),()=>a.removeEventListener("load",t)}},[r,t,e]),i.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)=>i.jsxs("div",{className:"mb-4 last:mb-0",children:[i.jsx(Ae,{command:o.command.join(" "),timestamp:new Date(o.timestamp).toLocaleTimeString(),status:o.result.status}),i.jsx("pre",{className:`text-gray-200 whitespace-pre font-mono ${n.outputFontSize}`,children:o.result.render()})]},a))})},oe={blink:{character:"▋",speed:530,color:"#fff"},spin:{character:"⠋",speed:120,color:"#fff"},solid:{character:"▋",speed:0,color:"#fff"},bbs:{character:"|",speed:120,color:"#fff"}},se=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],ae=["|","/","-","\\"],Ie=({style:r={type:"blink"},isValid:e=!0,errorMessage:n})=>{const t=s.useMemo(()=>({...oe[r.type],...r}),[r]),[o,a]=s.useState(!0),[l,d]=s.useState(0);s.useEffect(()=>{if(t.speed===0)return;const p=setInterval(()=>{t.type==="blink"?a(h=>!h):["spin","bbs"].includes(t.type)&&d(h=>(h+1)%(t.type==="bbs"?ae.length:se.length))},t.speed);return()=>clearInterval(p)},[t.type,t.speed]);const u=s.useMemo(()=>({color:e?t.color:"#ff4444",transition:"color 0.15s ease-in-out"}),[e,t.color]),m=()=>!e&&n?"✗":["spin","bbs"].includes(t.type)?(t.type==="bbs"?ae:se)[l]:t.type==="solid"||o?t.character:" ";return i.jsx("div",{className:"relative inline-block",children:i.jsx("span",{className:`command-cursor ${e?"":"animate-shake"}`,style:u,title:n,children:m()})})};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}=Y(),e=K(),n=te(),t=F(),[o,a]=s.useReducer(Pe,"idle"),l=c=>{a({type:"set",state:c})},d=s.useCallback(()=>{const g=e.getCompletions(t.path())[0]||t.nullSegment;return S.debug("[getNextExpectedSegment] ",g),g},[e,t]),u=s.useCallback(()=>e.getCompletions_s(t.path()).map(g=>e.getCommand([...t.path(),g])).filter(g=>g!==void 0),[e,t]),m=s.useCallback((c,g)=>{if(!c)return g;const f=g.reduce((b,C)=>{const v=d();return(v==null?void 0:v.type)==="word"&&b.set(v.name,C),b},new Map);return Array.from(f.values()).filter(()=>{const b=d();return b.type!=="word"?!1:b.name.toLowerCase().startsWith(c.toLowerCase())})},[d]),p=s.useCallback(c=>{const f=e.getCompletions(t.path()).filter(k=>k.type==="word").filter(k=>k.name.toLowerCase().startsWith(c.toLowerCase()));return f.length===1?f[0]:t.nullSegment},[e,t]),h=s.useCallback(c=>{const g=t.path(),f=e.getCompletions(g);return f.length===0&&c?!1:f.some(b=>b.type==="argument")?!0:f.some(b=>b.type==="word"&&b.name.toLowerCase().startsWith(c.toLowerCase()))},[e,t]),E=s.useCallback(c=>{S.debug("[tryAutoComplete] input: ",c);const g=p(c);return!g||g.name===c?new Z:(S.debug("[tryAutoComplete] result: ",g),g)},[p]),x=s.useCallback((c,g)=>{if(r.history.position===null){if(g.setCurrentInput(c),S.debug("[useCommandParser][handleInputChange] newValue: ",c),o==="entering_argument"){const f=ie(c);if(f.isQuoted)if(f.isComplete){const k=d();if(k.type==="argument"){const b=k;b.value=c.trim()||"",S.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",b),t.push(b),g.setCurrentInput(""),l("idle");return}}else return;else if(f.isComplete){const k=d();k.value=c.trim()||"",S.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",k),t.push(k),g.setCurrentInput(""),l("idle");return}else return}if(o=="entering_command"){const f=E(c);if(f.type==="word"){S.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",f),t.push(f),g.setCurrentInput(""),l("idle");return}}}},[E,r,d,o,t]),_=s.useCallback(c=>{c.setCurrentInput(""),c.setIsEnteringArg(!1),t.clear(),l("idle")},[t]),N=s.useCallback((c,g,f)=>{if(!(c.key==="Backspace"||c.key==="Enter"||c.key==="ArrowUp"||c.key==="ArrowDown"||c.key==="ArrowLeft"||c.key==="ArrowRight"||c.key==="Escape"||c.key==="Delete"||c.key==="Home"||c.key==="End"||c.key.length===1))return!0;const{currentInput:b,isEnteringArg:C}=g,v=ie(b);switch(c.key){case"Backspace":return b===""&&(c.preventDefault(),t.size()>0&&t.pop(),l("idle")),!0;case"Enter":{if(c.preventDefault(),v.isQuoted&&!v.isComplete)return!0;if(o==="entering_argument"||C&&b.trim()){const B=d();B.value=b,S.debug("[handleKeyDown][Enter]['entering_argument'] pushing: ",B),t.push(B)}const z=t.path(),I=e.getCommand(z);if(!I)return!1;const L=I.segments.filter(T=>T.type==="argument"),q=t.arguments;return L.length>q.length?!1:(S.debug("[handleKeyDown][Enter] calling actions.executeCommand. segmentStack: ",t),f.executeCommand(),n.addStoredCommand(t.toArray()),_(f),!0)}case"ArrowUp":return c.preventDefault(),(async()=>{const z=await n.navigateHistory("up",t.toArray());return z.segments&&(t.clear(),t.pushAll(z.segments),f.setCurrentInput("")),!0})();case"ArrowDown":return c.preventDefault(),(async()=>{const z=await n.navigateHistory("down",t.toArray());return z.segments&&(t.clear(),t.pushAll(z.segments),f.setCurrentInput("")),!0})();default:{if(!C&&c.key.length===1){const z=b+c.key;if(!h(z))return c.preventDefault(),!1}return!0}}},[o,h,d,n,_,e,t]);return{handleInputChange:x,handleKeyDown:N,inputState:o,setInputStateWithLogging:l,findMatchingCommands:m,getAutocompleteSuggestion:p,getAvailableNodes:u,getNextExpectedSegment:d,isValidCommandInput:h}};function ie(r){const e=[];let n="",t=!1,o;for(let a=0;a<r.length;a++){const l=r[a];(l==='"'||l==="'")&&(!t||l===o)?t?(e.push(n),n="",t=!1,o=void 0):(n&&(e.push(n),n=""),t=!0,o=l):!t&&l===" "?n&&(e.push(n),n=""):n+=l}return{words:e,currentWord:n,isQuoted:t,quoteChar:o,isComplete:!t&&!n}}const De=()=>{const r=F(),[e,n]=s.useState(0);return s.useEffect(()=>{const t={update:()=>{n(o=>o+1)}};return r.subscribe(t),()=>{r.unsubscribe(t)}},[r]),e},Me=({state:r,actions:e})=>{const n=s.useRef(null),t=K(),o=F(),{handleKeyDown:a,handleInputChange:l,inputState:d,setInputStateWithLogging:u,getNextExpectedSegment:m}=He(),[p,h]=s.useState(!1),E=M(),x=De(),_=async C=>{const v=a(C,r,e);await Promise.resolve(v)===!1&&(h(!0),setTimeout(()=>h(!1),500))},N=C=>{l(C.target.value,e)},c=C=>{C.preventDefault();const v=C.clipboardData.getData("text");l(v,e)};s.useEffect(()=>{n.current&&n.current.focus(),d!=="entering_command"&&u("entering_command")},[d,u]),s.useEffect(()=>{if(d!=="idle")return;const C=m();let v="idle";switch(C.type){case"word":v="entering_command",e.setIsEnteringArg(!1);break;case"argument":v="entering_argument",e.setIsEnteringArg(!0);break}u(v)},[x,d,m,u,e]);const[g,f]=s.useState([]);s.useEffect(()=>{const C=[],v=o.toArray().map((I,L)=>{C.push(I.name);const q=t.hasNextSegment(C);if(I.type==="argument"){const T=I;return i.jsxs(s.Fragment,{children:[i.jsx("span",{className:"text-gray-200 whitespace-pre",children:T.value}),L<o.size()&&q&&i.jsx("span",{className:"text-gray-200 whitespace-pre",children:" "})]},"arg-"+T.name+T.value)}return i.jsxs(s.Fragment,{children:[i.jsx("span",{className:"text-blue-400 whitespace-pre",children:I.name}),L<o.size()&&q&&i.jsx("span",{className:"text-blue-400 whitespace-pre",children:" "})]},"word-"+I.name)});f([i.jsx("div",{className:"flex items-center gap-1","data-testid":"user-input-area",children:v},"{segmentStackVersion}")])},[x,t,o]);const[k,b]=s.useState("");return s.useEffect(()=>{const C=m();C.type==="argument"?b(C.name):b("")},[x,m]),i.jsxs("div",{className:"flex flex-col w-full bg-gray-900 rounded-lg p-4",children:[i.jsx("style",{children:`
6
+ Check the definition of the ${p.join(".")} command and update the return type for its handler.`);_.markSuccess(),l(c=>({...c,output:c.output.map(h=>h.timestamp===S.timestamp?{...h,result:_}:h)}))}catch(b){const C=new G(b instanceof Error?b.message:"Unknown error");C.markFailure(),l(_=>({..._,output:_.output.map(c=>c.timestamp===S.timestamp?{...c,result:C}:c)}))}},[e,r.commandTimeoutMs,t]),clearHistory:s.useCallback(async()=>{try{await n.clear()}catch(p){console.warn("Failed to clear history:",p)}},[n])},u=s.useCallback(()=>e.getCompletions_s(t.path()),[t,e]),d=s.useCallback(()=>e.getCompletions(t.path()),[t,e]);return{state:i,actions:m,getAvailableCommands_s:u,getAvailableCommandSegments:d}},Ee=({onOpen:r,onClose:e,isVisible:n,showCitadelKey:t})=>{s.useEffect(()=>{const o=i=>{var l,m;!n&&i.key===t&&!["input","textarea"].includes(((m=(l=i.target)==null?void 0:l.tagName)==null?void 0:m.toLowerCase())||"")&&(i.preventDefault(),r()),n&&i.key==="Escape"&&(i.preventDefault(),e())};return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[r,e,n,t])},re={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"},_e=r=>{const{isVisible:e,isClosing:n,onAnimationComplete:t}=r,o=s.useMemo(()=>e?n?re.slideDown:re.slideUp:"",[e,n]);return s.useEffect(()=>{if(t){const l=setTimeout(()=>{t()},200);return()=>clearTimeout(l)}},[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}},Ne=()=>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 i=t.startsWith("<")&&t.endsWith(">");return a.jsxs("span",{className:i?"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===D.Pending&&a.jsx(Ne,{}),n===D.Success&&a.jsx("div",{"data-testid":"success-indicator",className:"w-4 h-4 rounded-full bg-green-500"}),(n===D.Timeout||n===D.Failure)&&a.jsx("div",{"data-testid":"success-indicator",className:"w-4 h-4 rounded-full bg-red-500"})]}),ze=({output:r,outputRef:e})=>{const n=M(),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"),i=o[o.length-1];if(i&&!i.complete)return i.addEventListener("load",t),()=>i.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,i)=>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()})]},i))})},oe={blink:{character:"▋",speed:530,color:"#fff"},spin:{character:"⠋",speed:120,color:"#fff"},solid:{character:"▋",speed:0,color:"#fff"},bbs:{character:"|",speed:120,color:"#fff"}},se=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],ae=["|","/","-","\\"],Ie=({style:r={type:"blink"},isValid:e=!0,errorMessage:n})=>{const t=s.useMemo(()=>({...oe[r.type],...r}),[r]),[o,i]=s.useState(!0),[l,m]=s.useState(0);s.useEffect(()=>{if(t.speed===0)return;const p=setInterval(()=>{t.type==="blink"?i(g=>!g):["spin","bbs"].includes(t.type)&&m(g=>(g+1)%(t.type==="bbs"?ae.length:se.length))},t.speed);return()=>clearInterval(p)},[t.type,t.speed]);const u=s.useMemo(()=>({color:e?t.color:"#ff4444",transition:"color 0.15s ease-in-out"}),[e,t.color]),d=()=>!e&&n?"✗":["spin","bbs"].includes(t.type)?(t.type==="bbs"?ae:se)[l]: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:u,title:n,children:d()})})};function Pe(r,e){switch(e.type){case"set":return E.debug(`[inputStateReducer] InputState changing from ${r} to ${e.state}`),e.state;default:return r}}const He=()=>{const{state:r}=Y(),e=$(),n=te(),t=j(),[o,i]=s.useReducer(Pe,"idle"),l=c=>{i({type:"set",state:c})},m=s.useCallback(()=>{const h=e.getCompletions(t.path())[0]||t.nullSegment;return E.debug("[getNextExpectedSegment] ",h),h},[e,t]),u=s.useCallback(()=>e.getCompletions_s(t.path()).map(h=>e.getCommand([...t.path(),h])).filter(h=>h!==void 0),[e,t]),d=s.useCallback((c,h)=>{if(!c)return h;const f=h.reduce((y,v)=>{const k=m();return(k==null?void 0:k.type)==="word"&&y.set(k.name,v),y},new Map);return Array.from(f.values()).filter(()=>{const y=m();return y.type!=="word"?!1:y.name.toLowerCase().startsWith(c.toLowerCase())})},[m]),p=s.useCallback(c=>{const f=e.getCompletions(t.path()).filter(N=>N.type==="word").filter(N=>N.name.toLowerCase().startsWith(c.toLowerCase()));return f.length===1?f[0]:t.nullSegment},[e,t]),g=s.useCallback(c=>{const h=t.path(),f=e.getCompletions(h);return f.length===0&&c?!1:f.some(y=>y.type==="argument")?!0:f.some(y=>y.type==="word"&&y.name.toLowerCase().startsWith(c.toLowerCase()))},[e,t]),S=s.useCallback(c=>{E.debug("[tryAutoComplete] input: ",c);const h=p(c);return!h||h.name===c?new Z:(E.debug("[tryAutoComplete] result: ",h),h)},[p]),b=s.useCallback((c,h)=>{if(r.history.position===null){if(h.setCurrentInput(c),E.debug("[useCommandParser][handleInputChange] newValue: ",c),o==="entering_argument"){const f=ie(c);if(f.isQuoted)if(f.isComplete){const N=m();if(N.type==="argument"){const y=N;y.value=c.trim()||"",E.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",y),t.push(y),h.setCurrentInput(""),l("idle");return}}else return;else if(f.isComplete){const N=m();N.value=c.trim()||"",E.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",N),t.push(N),h.setCurrentInput(""),l("idle");return}else return}if(o=="entering_command"){const f=S(c);if(f.type==="word"){E.debug("[useCommandParser][handleInputChange][entering_command] pushing: ",f),t.push(f),h.setCurrentInput(""),l("idle");return}}}},[S,r,m,o,t]),C=s.useCallback(c=>{c.setCurrentInput(""),c.setIsEnteringArg(!1),t.clear(),l("idle")},[t]),_=s.useCallback((c,h,f)=>{if(!(c.key==="Backspace"||c.key==="Enter"||c.key==="ArrowUp"||c.key==="ArrowDown"||c.key==="ArrowLeft"||c.key==="ArrowRight"||c.key==="Escape"||c.key==="Delete"||c.key==="Home"||c.key==="End"||c.key.length===1))return!0;const{currentInput:y,isEnteringArg:v}=h,k=ie(y);switch(c.key){case"Backspace":return y===""&&(c.preventDefault(),t.size()>0&&t.pop(),l("idle")),!0;case"Enter":{if(c.preventDefault(),k.isQuoted&&!k.isComplete)return!0;if(o==="entering_argument"||v&&y.trim()){const B=m();B.value=y,E.debug("[handleKeyDown][Enter]['entering_argument'] pushing: ",B),t.push(B)}const z=t.path(),I=e.getCommand(z);if(!I)return!1;const K=I.segments.filter(T=>T.type==="argument"),q=t.arguments;return K.length>q.length?!1:(E.debug("[handleKeyDown][Enter] calling actions.executeCommand. segmentStack: ",t),f.executeCommand(),n.addStoredCommand(t.toArray()),C(f),!0)}case"ArrowUp":return c.preventDefault(),(async()=>{const z=await n.navigateHistory("up",t.toArray());return z.segments&&(t.clear(),t.pushAll(z.segments),f.setCurrentInput("")),!0})();case"ArrowDown":return c.preventDefault(),(async()=>{const z=await n.navigateHistory("down",t.toArray());return z.segments&&(t.clear(),t.pushAll(z.segments),f.setCurrentInput("")),!0})();default:{if(!v&&c.key.length===1){const z=y+c.key;if(!g(z))return c.preventDefault(),!1}return!0}}},[o,g,m,n,C,e,t]);return{handleInputChange:b,handleKeyDown:_,inputState:o,setInputStateWithLogging:l,findMatchingCommands:d,getAutocompleteSuggestion:p,getAvailableNodes:u,getNextExpectedSegment:m,isValidCommandInput:g}};function ie(r){const e=[];let n="",t=!1,o;for(let i=0;i<r.length;i++){const l=r[i];(l==='"'||l==="'")&&(!t||l===o)?t?(e.push(n),n="",t=!1,o=void 0):(n&&(e.push(n),n=""),t=!0,o=l):!t&&l===" "?n&&(e.push(n),n=""):n+=l}return{words:e,currentWord:n,isQuoted:t,quoteChar:o,isComplete:!t&&!n}}const De=()=>{const r=j(),[e,n]=s.useState(0);return s.useEffect(()=>{const t={update:()=>{n(o=>o+1)}};return r.subscribe(t),()=>{r.unsubscribe(t)}},[r]),e},Me=({state:r,actions:e})=>{const n=s.useRef(null),t=$(),o=j(),{handleKeyDown:i,handleInputChange:l,inputState:m,setInputStateWithLogging:u,getNextExpectedSegment:d}=He(),[p,g]=s.useState(!1),S=M(),b=De(),C=async v=>{const k=i(v,r,e);await Promise.resolve(k)===!1&&(g(!0),setTimeout(()=>g(!1),500))},_=v=>{l(v.target.value,e)},c=v=>{v.preventDefault();const k=v.clipboardData.getData("text");l(k,e)};s.useEffect(()=>{n.current&&n.current.focus(),m!=="entering_command"&&u("entering_command")},[m,u]),s.useEffect(()=>{if(m!=="idle")return;const v=d();let k="idle";switch(v.type){case"word":k="entering_command",e.setIsEnteringArg(!1);break;case"argument":k="entering_argument",e.setIsEnteringArg(!0);break}u(k)},[b,m,d,u,e]);const[h,f]=s.useState([]);s.useEffect(()=>{const v=[],k=o.toArray().map((I,K)=>{v.push(I.name);const q=t.hasNextSegment(v);if(I.type==="argument"){const T=I;return a.jsxs(s.Fragment,{children:[a.jsx("span",{className:"text-gray-200 whitespace-pre",children:T.value}),K<o.size()&&q&&a.jsx("span",{className:"text-gray-200 whitespace-pre",children:" "})]},"arg-"+T.name+T.value)}return a.jsxs(s.Fragment,{children:[a.jsx("span",{className:"text-blue-400 whitespace-pre",children:I.name}),K<o.size()&&q&&a.jsx("span",{className:"text-blue-400 whitespace-pre",children:" "})]},"word-"+I.name)});f([a.jsx("div",{className:"flex items-center gap-1","data-testid":"user-input-area",children:k},"{segmentStackVersion}")])},[b,t,o]);const[N,y]=s.useState("");return s.useEffect(()=>{const v=d();v.type==="argument"?y(v.name):y("")},[b,d]),a.jsxs("div",{className:"flex flex-col w-full bg-gray-900 rounded-lg p-4",children:[a.jsx("style",{children:`
7
7
  @keyframes subtleGlow {
8
8
  0%, 100% { box-shadow: 0 0 0 rgba(239, 68, 68, 0); }
9
9
  50% { box-shadow: 0 0 8px rgba(239, 68, 68, 0.6); }
@@ -11,7 +11,7 @@ Check the definition of the ${p.join(".")} command and update the return type fo
11
11
  .invalid-input-animation {
12
12
  animation: subtleGlow 0.4s ease-in-out;
13
13
  }
14
- `}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("div",{className:"text-gray-400 font-mono",children:">"}),i.jsxs("div",{className:"flex-1 font-mono flex items-center",children:[g,i.jsxs("div",{className:"relative flex-1",children:[i.jsx("input",{ref:n,type:"text",role:"textbox",value:r.currentInput,onChange:N,onKeyDown:_,onPaste:c,"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:k}),i.jsx("div",{className:"absolute top-0 pointer-events-none",style:{left:`${r.currentInput.length}ch`,transition:"left 0.05s ease-out"},children:i.jsx(Ie,{style:{type:E.cursorType??A.cursorType,color:E.cursorColor||A.cursorColor,speed:E.cursorSpeed||A.cursorSpeed}})})]})]})]})]})},Te=()=>{const r=K(),e=M(),n=F(),t="h-12 mt-2 border-t border-gray-700 px-4",o="text-gray-300 pt-2",a=r.getCompletions(n.path());S.debug("[AvailableCommands] nextCommandSegments: ",a);const l=s.useMemo(()=>{if(e.includeHelpCommand){const m=a.filter(h=>h.name!=="help"),p=a.find(h=>h.name==="help");return[...m,...p?[p]:[]]}return a},[a,e.includeHelpCommand]),d=a.some(m=>m.type==="argument"),u=a[0];return i.jsx("div",{className:t,"data-testid":"available-commands",children:i.jsx("div",{className:o,children:d?a.length>0?i.jsxs(i.Fragment,{children:[i.jsx("span",{className:"text-blue-400",children:u.name}),u.description&&i.jsxs("span",{className:"text-gray-400 ml-2",children:["- ",u.description]})]}):null:i.jsx("div",{className:"flex flex-wrap gap-2",children:l==null?void 0:l.map(m=>{const p=l==null?void 0:l.reduce((h,E)=>{if(E===m)return h;let x=0;for(;x<m.name.length&&x<E.name.length&&m.name[x].toLowerCase()===E.name[x].toLowerCase();)x++;return Math.max(h,x+1)},1);return i.jsx("div",{className:"px-2 py-1 rounded bg-gray-800 mr-2 last:mr-0",children:i.jsxs("span",{className:"font-mono text-white",children:[i.jsx("strong",{className:"underline",children:m.name.slice(0,p)}),m.name.slice(p)]})},m.name)})})})})},le=({state:r,actions:e,outputRef:n})=>i.jsxs("div",{className:"innerContainer",children:[i.jsx("div",{className:"flex-1 min-h-0 pt-3 px-4",children:i.jsx(ze,{output:r.output,outputRef:n})}),i.jsxs("div",{children:[i.jsx(Me,{state:r,actions:e}),i.jsx(Te,{})]})]}),Ue=()=>{const[r,e]=s.useState(!1),[n,t]=s.useState(!1),o=M(),[a,l]=s.useState(()=>o.initialHeight||null),d=s.useRef(null),u=s.useRef(null),m=s.useRef(!1),p=s.useRef(0),h=s.useRef(0),{state:E,actions:x}=Y();Ee({onOpen:()=>e(!0),onClose:()=>t(!0),isVisible:r,showCitadelKey:o.showCitadelKey||"."});const _=s.useCallback(f=>{var v;if(!m.current)return;const k=f.clientY-p.current,b=(v=o.maxHeight)!=null&&v.endsWith("vh")?window.innerHeight*parseInt(o.maxHeight,10)/100:parseInt(o.maxHeight||"80vh",10),C=Math.min(Math.max(h.current-k,parseInt(o.minHeight||"200",10)),b);u.current&&(u.current.style.height=`${C}px`,u.current.style.bottom="0",l(`${C}px`))},[o.maxHeight,o.minHeight]),N=s.useCallback(()=>{m.current=!1,document.documentElement.style.userSelect="",document.documentElement.style.webkitUserSelect="",document.documentElement.style.mozUserSelect="",document.documentElement.style.msUserSelect="",document.removeEventListener("mousemove",_),document.removeEventListener("mouseup",N)},[_]),c=s.useCallback(f=>{u.current&&(m.current=!0,p.current=f.clientY,h.current=u.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",_),document.addEventListener("mouseup",N))},[_,N]);s.useEffect(()=>()=>{document.removeEventListener("mousemove",_),document.removeEventListener("mouseup",N)},[_,N]);const g=s.useCallback(()=>{n&&(e(!1),t(!1))},[n]);return _e({isVisible:r,isClosing:n,onAnimationComplete:g}),r?i.jsxs("div",{ref:u,className:`panelContainer ${r?"citadel_slideUp":""} ${n?"citadel_slideDown":""}`,style:{...a?{height:a}:void 0,maxHeight:o.maxHeight},children:[i.jsx("div",{className:"resizeHandle",onMouseDown:c}),i.jsx(le,{state:E,actions:x,outputRef:d})]}):null},Fe=()=>{const{state:r,actions:e}=Y(),n=s.useRef(null);return i.jsx("div",{className:"inlineContainer","data-testid":"citadel-inline-container",children:i.jsx(le,{state:r,actions:e,outputRef:n})})},ce=`:host {
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:[h,a.jsxs("div",{className:"relative flex-1",children:[a.jsx("input",{ref:n,type:"text",role:"textbox",value:r.currentInput,onChange:_,onKeyDown:C,onPaste:c,"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:N}),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(Ie,{style:{type:S.cursorType??A.cursorType,color:S.cursorColor||A.cursorColor,speed:S.cursorSpeed||A.cursorSpeed}})})]})]})]})]})},Te=()=>{const r=$(),e=M(),n=j(),t="mt-2 border-t border-gray-700 px-4 py-2",o="text-gray-300",i=r.getCompletions(n.path());E.debug("[AvailableCommands] nextCommandSegments: ",i);const l=s.useMemo(()=>{const d=[...i],p=C=>C.name.toLowerCase()==="help",S=d.filter(C=>!p(C)).sort((C,_)=>C.name.localeCompare(_.name,void 0,{sensitivity:"base"}));if(!e.includeHelpCommand)return S;const b=d.find(p);return b?[...S,b]:S},[i,e.includeHelpCommand]),m=i.some(d=>d.type==="argument"),u=i[0];return a.jsx("div",{className:t,"data-testid":"available-commands",children:a.jsx("div",{className:o,children:m?i.length>0?a.jsxs(a.Fragment,{children:[a.jsx("span",{className:"text-blue-400",children:u.name}),u.description&&a.jsxs("span",{className:"text-gray-400 ml-2",children:["- ",u.description]})]}):null:a.jsx("div",{className:"flex flex-wrap gap-2",children:l==null?void 0:l.map(d=>{const p=l==null?void 0:l.reduce((g,S)=>{if(S===d)return g;let b=0;for(;b<d.name.length&&b<S.name.length&&d.name[b].toLowerCase()===S.name[b].toLowerCase();)b++;return Math.max(g,b+1)},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:d.name.slice(0,p)}),d.name.slice(p)]})},d.name)})})})})},le=({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(ze,{output:r.output,outputRef:n})}),a.jsxs("div",{children:[a.jsx(Me,{state:r,actions:e}),a.jsx(Te,{})]})]}),Ue=()=>{const[r,e]=s.useState(!1),[n,t]=s.useState(!1),o=M(),[i,l]=s.useState(()=>o.initialHeight||null),m=s.useRef(null),u=s.useRef(null),d=s.useRef(!1),p=s.useRef(0),g=s.useRef(0),{state:S,actions:b}=Y();Ee({onOpen:()=>e(!0),onClose:()=>t(!0),isVisible:r,showCitadelKey:o.showCitadelKey||"."});const C=s.useCallback(f=>{var k;if(!d.current)return;const N=f.clientY-p.current,y=(k=o.maxHeight)!=null&&k.endsWith("vh")?window.innerHeight*parseInt(o.maxHeight,10)/100:parseInt(o.maxHeight||"80vh",10),v=Math.min(Math.max(g.current-N,parseInt(o.minHeight||"200",10)),y);u.current&&(u.current.style.height=`${v}px`,u.current.style.bottom="0",l(`${v}px`))},[o.maxHeight,o.minHeight]),_=s.useCallback(()=>{d.current=!1,document.documentElement.style.userSelect="",document.documentElement.style.webkitUserSelect="",document.documentElement.style.mozUserSelect="",document.documentElement.style.msUserSelect="",document.removeEventListener("mousemove",C),document.removeEventListener("mouseup",_)},[C]),c=s.useCallback(f=>{u.current&&(d.current=!0,p.current=f.clientY,g.current=u.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",C),document.addEventListener("mouseup",_))},[C,_]);s.useEffect(()=>()=>{document.removeEventListener("mousemove",C),document.removeEventListener("mouseup",_)},[C,_]);const h=s.useCallback(()=>{n&&(e(!1),t(!1))},[n]);return _e({isVisible:r,isClosing:n,onAnimationComplete:h}),r?a.jsxs("div",{ref:u,className:`panelContainer ${r?"citadel_slideUp":""} ${n?"citadel_slideDown":""}`,style:{...i?{height:i}:void 0,maxHeight:o.maxHeight},children:[a.jsx("div",{className:"resizeHandle",onMouseDown:c}),a.jsx(le,{state:S,actions:b,outputRef:m})]}):null},je=()=>{const{state:r,actions:e}=Y(),n=s.useRef(null);return a.jsx("div",{className:"inlineContainer","data-testid":"citadel-inline-container",children:a.jsx(le,{state:r,actions:e,outputRef:n})})},ce=`:host {
15
15
  --citadel-bg: rgb(17, 24, 39);
16
16
  --citadel-text: rgba(255, 255, 255, 0.87);
17
17
  --citadel-border: rgb(55, 65, 81);
@@ -200,7 +200,7 @@ a:hover {
200
200
  `,me=`@tailwind base;
201
201
  @tailwind components;
202
202
  @tailwind utilities;
203
- `,je=`*, ::before, ::after {
203
+ `,Fe=`*, ::before, ::after {
204
204
  --tw-border-spacing-x: 0;
205
205
  --tw-border-spacing-y: 0;
206
206
  --tw-translate-x: 0;
@@ -1017,5 +1017,5 @@ video {
1017
1017
  .last\\:mr-0:last-child {
1018
1018
  margin-right: 0px;
1019
1019
  }
1020
- `,Oe=({config:r=A,commandRegistry:e=new $,containerId:n=null})=>{const t=s.useRef(null),o=r.displayMode??A.displayMode??"panel";return s.useEffect(()=>{S.configure({level:r.logLevel||A.logLevel||j.ERROR,prefix:"[Citadel]"});const a=new ue(e,r),l=o==="inline"&&!n,d=l?t.current:n?document.getElementById(n):document.body;if(d)d.appendChild(a);else{if(l){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(a)}return()=>{var u;(u=a.parentElement)==null||u.removeChild(a)}},[e,n,r,o]),o==="inline"&&!n?i.jsx("div",{ref:t,style:{width:"100%",height:"100%"}}):null};class ue extends HTMLElement{constructor(n,t){var a;super();y(this,"shadow");y(this,"root",null);y(this,"commandRegistry");y(this,"config");this.shadow=this.attachShadow({mode:"open"}),this.commandRegistry=n,this.config=t;const o=((a=this.config)==null?void 0:a.displayMode)??"panel";this.setAttribute("data-display-mode",o)}connectedCallback(){try{const t=[ce,de,me,je].map(o=>{const a=new CSSStyleSheet;return a.replaceSync(o),a});this.shadow.adoptedStyleSheets=[...t]}catch{const t=[ce,de,me].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=pe.createRoot(n),this.root.render(i.jsx(Se,{config:this.config||A,commandRegistry:this.commandRegistry,children:i.jsx($e,{})}))}}customElements.define("citadel-element",ue);const $e=()=>(M().displayMode??"panel")==="inline"?i.jsx(Fe,{}):i.jsx(Ue,{});w.Citadel=Oe,w.CommandRegistry=$,w.CommandResult=P,w.CommandStatus=D,w.DEFAULT_CURSOR_CONFIGS=oe,w.ErrorCommandResult=G,w.ImageCommandResult=ge,w.JsonCommandResult=he,w.OutputItem=ne,w.PendingCommandResult=J,w.TextCommandResult=V,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
1020
+ `,Oe=({config:r=A,commandRegistry:e=new L,containerId:n=null})=>{const t=s.useRef(null),o=r.displayMode??A.displayMode??"panel";return s.useEffect(()=>{E.configure({level:r.logLevel||A.logLevel||F.ERROR,prefix:"[Citadel]"});const i=new ue(e,r),l=o==="inline"&&!n,m=l?t.current:n?document.getElementById(n):document.body;if(m)m.appendChild(i);else{if(l){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(i)}return()=>{var u;(u=i.parentElement)==null||u.removeChild(i)}},[e,n,r,o]),o==="inline"&&!n?a.jsx("div",{ref:t,style:{width:"100%",height:"100%"}}):null};class ue extends HTMLElement{constructor(n,t){var i;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=((i=this.config)==null?void 0:i.displayMode)??"panel";this.setAttribute("data-display-mode",o)}connectedCallback(){try{const t=[ce,de,me,Fe].map(o=>{const i=new CSSStyleSheet;return i.replaceSync(o),i});this.shadow.adoptedStyleSheets=[...t]}catch{const t=[ce,de,me].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=pe.createRoot(n),this.root.render(a.jsx(Se,{config:this.config||A,commandRegistry:this.commandRegistry,children:a.jsx(Le,{})}))}}customElements.define("citadel-element",ue);const Le=()=>(M().displayMode??"panel")==="inline"?a.jsx(je,{}):a.jsx(Ue,{});w.Citadel=Oe,w.CommandRegistry=L,w.CommandResult=P,w.CommandStatus=D,w.DEFAULT_CURSOR_CONFIGS=oe,w.ErrorCommandResult=G,w.ImageCommandResult=ge,w.JsonCommandResult=he,w.OutputItem=ne,w.PendingCommandResult=J,w.TextCommandResult=V,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
@@ -66,6 +66,13 @@ export declare class CommandRegistry {
66
66
  * @throws {Error} If the segment list is empty or the path collides with an existing command.
67
67
  */
68
68
  addCommand(segments: CommandSegment[], description: string, handler?: CommandHandler): void;
69
+ /**
70
+ * Removes a command that exactly matches the provided path.
71
+ *
72
+ * @param path The command path to remove.
73
+ * @returns True if a command was removed; otherwise false.
74
+ */
75
+ removeCommand(path: string[]): boolean;
69
76
  /**
70
77
  * Retrieves a command from the registry for the given path.
71
78
  *
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "type": "git",
18
18
  "url": "git+https://github.com/jchilders/citadel_cli.git"
19
19
  },
20
- "version": "1.1.5",
20
+ "version": "1.1.6",
21
21
  "type": "module",
22
22
  "scripts": {
23
23
  "build": "tsc && vite build",