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.
package/dist/citadel.es.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
244
|
-
|
|
243
|
+
y(this, "_segments");
|
|
244
|
+
y(this, "_description");
|
|
245
245
|
// Used by `Help` command, etc.
|
|
246
|
-
|
|
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
|
-
|
|
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 (
|
|
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((
|
|
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
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
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
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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
|
|
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 =
|
|
561
|
+
}), t = b(async (l) => {
|
|
546
562
|
if (r)
|
|
547
563
|
try {
|
|
548
|
-
const d =
|
|
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 =
|
|
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 =
|
|
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((
|
|
577
|
-
...
|
|
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 =
|
|
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:
|
|
629
|
-
|
|
644
|
+
setCurrentInput: b((u) => {
|
|
645
|
+
E.debug("[CitadelActions] setCurrentInput: ", u), a((h) => ({ ...h, currentInput: u }));
|
|
630
646
|
}, []),
|
|
631
|
-
setIsEnteringArg:
|
|
632
|
-
|
|
647
|
+
setIsEnteringArg: b((u) => {
|
|
648
|
+
E.debug("[CitadelActions] setIsEnteringArg: ", u), a((h) => ({ ...h, isEnteringArg: u }));
|
|
633
649
|
}, []),
|
|
634
|
-
addOutput:
|
|
635
|
-
|
|
636
|
-
...
|
|
637
|
-
output: [...
|
|
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:
|
|
641
|
-
const u = t.path(),
|
|
642
|
-
if (!
|
|
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
|
|
647
|
-
a((
|
|
648
|
-
...
|
|
649
|
-
output: [...
|
|
662
|
+
const C = new Re(t);
|
|
663
|
+
a((f) => ({
|
|
664
|
+
...f,
|
|
665
|
+
output: [...f.output, C]
|
|
650
666
|
}));
|
|
651
667
|
try {
|
|
652
|
-
const
|
|
668
|
+
const f = new Promise((i, p) => {
|
|
653
669
|
setTimeout(() => {
|
|
654
|
-
|
|
670
|
+
p(new Error("Request timed out"));
|
|
655
671
|
}, r.commandTimeoutMs);
|
|
656
|
-
}),
|
|
657
|
-
|
|
658
|
-
|
|
672
|
+
}), x = t.arguments.map((i) => i.value || ""), k = await Promise.race([
|
|
673
|
+
h.handler(x),
|
|
674
|
+
f
|
|
659
675
|
]);
|
|
660
|
-
if (!(
|
|
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
|
-
|
|
683
|
+
k.markSuccess(), a((i) => ({
|
|
668
684
|
...i,
|
|
669
685
|
output: i.output.map(
|
|
670
|
-
(
|
|
686
|
+
(p) => p.timestamp === C.timestamp ? { ...p, result: k } : p
|
|
671
687
|
)
|
|
672
688
|
}));
|
|
673
|
-
} catch (
|
|
674
|
-
const
|
|
675
|
-
|
|
689
|
+
} catch (f) {
|
|
690
|
+
const x = new ve(
|
|
691
|
+
f instanceof Error ? f.message : "Unknown error"
|
|
676
692
|
);
|
|
677
|
-
|
|
678
|
-
...
|
|
679
|
-
output:
|
|
680
|
-
(i) => i.timestamp ===
|
|
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:
|
|
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 =
|
|
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
|
-
},
|
|
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 =
|
|
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((
|
|
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
|
|
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 =
|
|
874
|
-
const
|
|
875
|
-
return
|
|
876
|
-
}, [e, t]), d =
|
|
877
|
-
if (!i) return
|
|
878
|
-
const g =
|
|
879
|
-
const
|
|
880
|
-
return (
|
|
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
|
|
884
|
-
return
|
|
899
|
+
const w = l();
|
|
900
|
+
return w.type !== "word" ? !1 : w.name.toLowerCase().startsWith(i.toLowerCase());
|
|
885
901
|
});
|
|
886
|
-
}, [l]), u =
|
|
887
|
-
const g = e.getCompletions(t.path()).filter((
|
|
888
|
-
(
|
|
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]),
|
|
892
|
-
const
|
|
893
|
-
return g.length === 0 && i ? !1 : g.some((
|
|
894
|
-
(
|
|
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]),
|
|
897
|
-
|
|
898
|
-
const
|
|
899
|
-
return !
|
|
900
|
-
}, [u]),
|
|
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 (
|
|
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
|
|
907
|
-
if (
|
|
908
|
-
const
|
|
909
|
-
|
|
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
|
|
916
|
-
|
|
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 =
|
|
938
|
+
const g = C(i);
|
|
923
939
|
if (g.type === "word") {
|
|
924
|
-
|
|
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
|
-
}, [
|
|
945
|
+
}, [C, r, l, o, t]), x = b((i) => {
|
|
930
946
|
i.setCurrentInput(""), i.setIsEnteringArg(!1), t.clear(), a("idle");
|
|
931
|
-
}, [t]),
|
|
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:
|
|
950
|
+
const { currentInput: w, isEnteringArg: v } = p, S = te(w);
|
|
935
951
|
switch (i.key) {
|
|
936
952
|
case "Backspace":
|
|
937
|
-
return
|
|
953
|
+
return w === "" && (i.preventDefault(), t.size() > 0 && t.pop(), a("idle")), !0;
|
|
938
954
|
case "Enter": {
|
|
939
|
-
if (i.preventDefault(),
|
|
955
|
+
if (i.preventDefault(), S.isQuoted && !S.isComplete)
|
|
940
956
|
return !0;
|
|
941
|
-
if (o === "entering_argument" ||
|
|
957
|
+
if (o === "entering_argument" || v && w.trim()) {
|
|
942
958
|
const G = l();
|
|
943
|
-
G.value =
|
|
959
|
+
G.value = w, E.debug("[handleKeyDown][Enter]['entering_argument'] pushing: ", G), t.push(G);
|
|
944
960
|
}
|
|
945
|
-
const I = t.path(),
|
|
946
|
-
if (!
|
|
961
|
+
const I = t.path(), H = e.getCommand(I);
|
|
962
|
+
if (!H)
|
|
947
963
|
return !1;
|
|
948
|
-
const $ =
|
|
949
|
-
return $.length > K.length ? !1 : (
|
|
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 (!
|
|
963
|
-
const I =
|
|
964
|
-
if (!
|
|
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
|
-
|
|
988
|
+
h,
|
|
973
989
|
l,
|
|
974
990
|
n,
|
|
975
|
-
|
|
991
|
+
x,
|
|
976
992
|
e,
|
|
977
993
|
t
|
|
978
994
|
]);
|
|
979
995
|
return {
|
|
980
|
-
handleInputChange:
|
|
981
|
-
handleKeyDown:
|
|
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:
|
|
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 =
|
|
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,
|
|
1030
|
-
const
|
|
1031
|
-
await Promise.resolve(
|
|
1032
|
-
},
|
|
1033
|
-
a(
|
|
1034
|
-
}, i = (
|
|
1035
|
-
|
|
1036
|
-
const
|
|
1037
|
-
a(
|
|
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
|
|
1044
|
-
let
|
|
1045
|
-
switch (
|
|
1059
|
+
const v = c();
|
|
1060
|
+
let S = "idle";
|
|
1061
|
+
switch (v.type) {
|
|
1046
1062
|
case "word":
|
|
1047
|
-
|
|
1063
|
+
S = "entering_command", e.setIsEnteringArg(!1);
|
|
1048
1064
|
break;
|
|
1049
1065
|
case "argument":
|
|
1050
|
-
|
|
1066
|
+
S = "entering_argument", e.setIsEnteringArg(!0);
|
|
1051
1067
|
break;
|
|
1052
1068
|
}
|
|
1053
|
-
d(
|
|
1054
|
-
}, [
|
|
1055
|
-
const [
|
|
1069
|
+
d(S);
|
|
1070
|
+
}, [f, l, c, d, e]);
|
|
1071
|
+
const [p, g] = R([]);
|
|
1056
1072
|
A(() => {
|
|
1057
|
-
const
|
|
1058
|
-
|
|
1059
|
-
const K = t.hasNextSegment(
|
|
1060
|
-
if (
|
|
1061
|
-
const M =
|
|
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:
|
|
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-" +
|
|
1086
|
+
] }, "word-" + H.name);
|
|
1071
1087
|
});
|
|
1072
|
-
g([/* @__PURE__ */ m("div", { className: "flex items-center gap-1", "data-testid": "user-input-area", children:
|
|
1073
|
-
}, [
|
|
1074
|
-
const [
|
|
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
|
|
1077
|
-
|
|
1078
|
-
}, [
|
|
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
|
-
|
|
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:
|
|
1101
|
-
onKeyDown:
|
|
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:
|
|
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:
|
|
1123
|
-
color:
|
|
1124
|
-
speed:
|
|
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 = "
|
|
1136
|
-
|
|
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
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
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((
|
|
1152
|
-
if (
|
|
1153
|
-
let
|
|
1154
|
-
for (;
|
|
1155
|
-
|
|
1156
|
-
return Math.max(
|
|
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 =
|
|
1182
|
-
|
|
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
|
|
1189
|
-
var
|
|
1206
|
+
const x = b((g) => {
|
|
1207
|
+
var S;
|
|
1190
1208
|
if (!c.current) return;
|
|
1191
|
-
const
|
|
1192
|
-
Math.max(
|
|
1193
|
-
|
|
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 = `${
|
|
1196
|
-
}, [o.maxHeight, o.minHeight]),
|
|
1197
|
-
c.current = !1, document.documentElement.style.userSelect = "", document.documentElement.style.webkitUserSelect = "", document.documentElement.style.mozUserSelect = "", document.documentElement.style.msUserSelect = "", document.removeEventListener("mousemove",
|
|
1198
|
-
}, [
|
|
1199
|
-
d.current && (c.current = !0, u.current = g.clientY,
|
|
1200
|
-
}, [
|
|
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",
|
|
1203
|
-
}, [
|
|
1204
|
-
const
|
|
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:
|
|
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:
|
|
1226
|
-
actions:
|
|
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 =
|
|
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 =
|
|
2279
|
+
const t = P(null), o = r.displayMode ?? z.displayMode ?? "panel";
|
|
2262
2280
|
return A(() => {
|
|
2263
|
-
|
|
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
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
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);
|
package/dist/citadel.umd.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
(function(w,
|
|
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
|
-
`}),
|
|
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
|
-
`,
|
|
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
|
|
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(
|
|
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
|
*
|