@stackable-labs/cli-app-extension 1.26.3 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +685 -410
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,9 +6,10 @@ import { program } from "commander";
|
|
|
6
6
|
import { render } from "ink";
|
|
7
7
|
|
|
8
8
|
// src/App.tsx
|
|
9
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
9
10
|
import { join as join3 } from "path";
|
|
10
|
-
import { Box as
|
|
11
|
-
import { useCallback, useState as
|
|
11
|
+
import { Box as Box15, Text as Text15, useApp } from "ink";
|
|
12
|
+
import { useCallback, useState as useState10 } from "react";
|
|
12
13
|
|
|
13
14
|
// src/components/Confirm.tsx
|
|
14
15
|
import { Box as Box2, Text as Text2, useFocus, useFocusManager, useInput as useInput2 } from "ink";
|
|
@@ -44,7 +45,7 @@ var TEMPLATE_FLAVOR_META = {
|
|
|
44
45
|
};
|
|
45
46
|
var TARGET_PERMISSION_MAP = {
|
|
46
47
|
"slot.header": ["context:read"],
|
|
47
|
-
"slot.content": ["context:read", "data:query", "actions:toast", "actions:invoke"],
|
|
48
|
+
"slot.content": ["context:read", "data:query", "data:fetch", "actions:toast", "actions:invoke"],
|
|
48
49
|
"slot.footer": [],
|
|
49
50
|
"slot.footer-links": []
|
|
50
51
|
};
|
|
@@ -98,11 +99,11 @@ var VersionRow = ({ currentVersion, value, onChange, onFocusChange, onConfirm, o
|
|
|
98
99
|
const { focusPrevious, focusNext } = useFocusManager();
|
|
99
100
|
useInput2((_, key) => {
|
|
100
101
|
if (!isFocused) return;
|
|
101
|
-
if (key.upArrow
|
|
102
|
+
if (key.upArrow) {
|
|
102
103
|
focusPrevious();
|
|
103
104
|
return;
|
|
104
105
|
}
|
|
105
|
-
if (key.
|
|
106
|
+
if (key.downArrow) {
|
|
106
107
|
focusNext();
|
|
107
108
|
return;
|
|
108
109
|
}
|
|
@@ -140,9 +141,14 @@ var Confirm = ({
|
|
|
140
141
|
extensionPort,
|
|
141
142
|
previewPort,
|
|
142
143
|
targets,
|
|
144
|
+
registryTargets,
|
|
143
145
|
outputDir,
|
|
144
146
|
bundleUrl,
|
|
145
147
|
enabled,
|
|
148
|
+
permissions,
|
|
149
|
+
allowedDomains,
|
|
150
|
+
registryPermissions,
|
|
151
|
+
registryAllowedDomains,
|
|
146
152
|
newVersion,
|
|
147
153
|
onVersionOverride,
|
|
148
154
|
onConfirm,
|
|
@@ -238,10 +244,57 @@ var Confirm = ({
|
|
|
238
244
|
] }),
|
|
239
245
|
/* @__PURE__ */ jsxs2(Box2, { gap: 2, children: [
|
|
240
246
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Targets " }),
|
|
241
|
-
/* @__PURE__ */
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
247
|
+
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
248
|
+
targets.map((t) => {
|
|
249
|
+
const isAdded = registryTargets && !registryTargets.includes(t);
|
|
250
|
+
return /* @__PURE__ */ jsxs2(Box2, { gap: 1, children: [
|
|
251
|
+
/* @__PURE__ */ jsx2(Text2, { color: "green", children: "\u2022 " }),
|
|
252
|
+
/* @__PURE__ */ jsx2(Text2, { children: t }),
|
|
253
|
+
isAdded && /* @__PURE__ */ jsx2(Text2, { color: "green", dimColor: true, children: "(+ added)" })
|
|
254
|
+
] }, t);
|
|
255
|
+
}),
|
|
256
|
+
registryTargets?.filter((t) => !targets.includes(t)).map((t) => /* @__PURE__ */ jsxs2(Box2, { gap: 1, children: [
|
|
257
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", children: "\u2022 " }),
|
|
258
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", dimColor: true, strikethrough: true, children: t }),
|
|
259
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", dimColor: true, children: "(- removed)" })
|
|
260
|
+
] }, t))
|
|
261
|
+
] })
|
|
262
|
+
] }),
|
|
263
|
+
permissions && (permissions.length > 0 || registryPermissions?.some((p) => !permissions.includes(p))) && /* @__PURE__ */ jsxs2(Box2, { gap: 2, children: [
|
|
264
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Permissions " }),
|
|
265
|
+
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
266
|
+
permissions.map((p) => {
|
|
267
|
+
const isAdded = registryPermissions && !registryPermissions.includes(p);
|
|
268
|
+
return /* @__PURE__ */ jsxs2(Box2, { gap: 1, children: [
|
|
269
|
+
/* @__PURE__ */ jsx2(Text2, { color: "green", children: "\u2022 " }),
|
|
270
|
+
/* @__PURE__ */ jsx2(Text2, { children: p }),
|
|
271
|
+
isAdded && /* @__PURE__ */ jsx2(Text2, { color: "green", dimColor: true, children: "(+ added)" })
|
|
272
|
+
] }, p);
|
|
273
|
+
}),
|
|
274
|
+
registryPermissions?.filter((p) => !permissions.includes(p)).map((p) => /* @__PURE__ */ jsxs2(Box2, { gap: 1, children: [
|
|
275
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", children: "\u2022 " }),
|
|
276
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", dimColor: true, strikethrough: true, children: p }),
|
|
277
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", dimColor: true, children: "(- removed)" })
|
|
278
|
+
] }, p))
|
|
279
|
+
] })
|
|
280
|
+
] }),
|
|
281
|
+
allowedDomains && (allowedDomains.length > 0 || registryAllowedDomains?.some((d) => !allowedDomains.includes(d))) && /* @__PURE__ */ jsxs2(Box2, { gap: 2, children: [
|
|
282
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Domains " }),
|
|
283
|
+
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
284
|
+
allowedDomains.map((d) => {
|
|
285
|
+
const isAdded = registryAllowedDomains && !registryAllowedDomains.includes(d);
|
|
286
|
+
return /* @__PURE__ */ jsxs2(Box2, { gap: 1, children: [
|
|
287
|
+
/* @__PURE__ */ jsx2(Text2, { color: "green", children: "\u2022 " }),
|
|
288
|
+
/* @__PURE__ */ jsx2(Text2, { children: d }),
|
|
289
|
+
isAdded && /* @__PURE__ */ jsx2(Text2, { color: "green", dimColor: true, children: "(+ added)" })
|
|
290
|
+
] }, d);
|
|
291
|
+
}),
|
|
292
|
+
registryAllowedDomains?.filter((d) => !allowedDomains.includes(d)).map((d) => /* @__PURE__ */ jsxs2(Box2, { gap: 1, children: [
|
|
293
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", children: "\u2022 " }),
|
|
294
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", dimColor: true, strikethrough: true, children: d }),
|
|
295
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", dimColor: true, children: "(- removed)" })
|
|
296
|
+
] }, d))
|
|
297
|
+
] })
|
|
245
298
|
] })
|
|
246
299
|
] })
|
|
247
300
|
}
|
|
@@ -447,24 +500,151 @@ var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
|
|
|
447
500
|
);
|
|
448
501
|
};
|
|
449
502
|
|
|
450
|
-
// src/components/
|
|
451
|
-
import { Box as Box7, Text as Text7,
|
|
452
|
-
import TextInput4 from "ink-text-input";
|
|
503
|
+
// src/components/ManifestReviewPrompt.tsx
|
|
504
|
+
import { Box as Box7, Text as Text7, useInput as useInput4 } from "ink";
|
|
453
505
|
import { useState as useState4 } from "react";
|
|
506
|
+
|
|
507
|
+
// src/lib/manifest-diff.ts
|
|
508
|
+
var diffManifestValues = (localValues, registryValues) => {
|
|
509
|
+
const localSet = new Set(localValues ?? []);
|
|
510
|
+
const registrySet = new Set(registryValues);
|
|
511
|
+
const all = /* @__PURE__ */ new Set([...localSet, ...registrySet]);
|
|
512
|
+
return [...all].map((value) => {
|
|
513
|
+
const inLocal = localSet.has(value);
|
|
514
|
+
const inRegistry = registrySet.has(value);
|
|
515
|
+
if (!inLocal) {
|
|
516
|
+
return { value, status: "removed", enabled: false };
|
|
517
|
+
}
|
|
518
|
+
return inRegistry ? { value, status: "unchanged", enabled: true } : { value, status: "new", enabled: false };
|
|
519
|
+
});
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
// src/components/ManifestReviewPrompt.tsx
|
|
454
523
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
455
|
-
var
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
524
|
+
var statusLabel = (status) => {
|
|
525
|
+
switch (status) {
|
|
526
|
+
case "new":
|
|
527
|
+
return "(+ added)";
|
|
528
|
+
case "removed":
|
|
529
|
+
return "(- removed)";
|
|
530
|
+
case "unchanged":
|
|
531
|
+
return void 0;
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
var statusColor = (status) => {
|
|
535
|
+
switch (status) {
|
|
536
|
+
case "new":
|
|
537
|
+
return "green";
|
|
538
|
+
case "removed":
|
|
539
|
+
return "red";
|
|
540
|
+
case "unchanged":
|
|
541
|
+
return void 0;
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
var ManifestReviewPrompt = ({
|
|
545
|
+
localManifest,
|
|
546
|
+
registryManifest,
|
|
547
|
+
onSubmit,
|
|
548
|
+
onBack
|
|
549
|
+
}) => {
|
|
550
|
+
const [permItems, setPermItems] = useState4(() => diffManifestValues(localManifest?.permissions, registryManifest.permissions));
|
|
551
|
+
const [domainItems, setDomainItems] = useState4(() => diffManifestValues(localManifest?.allowedDomains, registryManifest.allowedDomains));
|
|
552
|
+
const [cursor, setCursor] = useState4(0);
|
|
553
|
+
const totalItems = permItems.length + domainItems.length;
|
|
554
|
+
const cursorInPerms = cursor < permItems.length;
|
|
555
|
+
const cursorInDomains = cursor >= permItems.length;
|
|
556
|
+
const toggle = (index) => {
|
|
557
|
+
if (index < permItems.length) {
|
|
558
|
+
setPermItems((prev) => prev.map((item, i) => i === index ? { ...item, enabled: !item.enabled } : item));
|
|
559
|
+
} else {
|
|
560
|
+
const domainIndex = index - permItems.length;
|
|
561
|
+
setDomainItems((prev) => prev.map((item, i) => i === domainIndex ? { ...item, enabled: !item.enabled } : item));
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
const handleSubmit = () => {
|
|
565
|
+
onSubmit({
|
|
566
|
+
permissions: permItems.filter((i) => i.enabled).map((i) => i.value),
|
|
567
|
+
allowedDomains: domainItems.filter((i) => i.enabled).map((i) => i.value)
|
|
568
|
+
});
|
|
569
|
+
};
|
|
570
|
+
const domainSectionStart = permItems.length;
|
|
571
|
+
useInput4((input, key) => {
|
|
572
|
+
if (key.downArrow) {
|
|
573
|
+
setCursor((c) => Math.min(c + 1, totalItems - 1));
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
if (key.upArrow) {
|
|
577
|
+
setCursor((c) => Math.max(c - 1, 0));
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
460
580
|
if (key.tab && !key.shift) {
|
|
461
|
-
|
|
581
|
+
setCursor((c) => {
|
|
582
|
+
if (c < domainSectionStart && domainItems.length > 0) return domainSectionStart;
|
|
583
|
+
return c;
|
|
584
|
+
});
|
|
462
585
|
return;
|
|
463
586
|
}
|
|
464
587
|
if (key.tab && key.shift) {
|
|
465
|
-
|
|
588
|
+
setCursor((c) => {
|
|
589
|
+
if (c >= domainSectionStart) return 0;
|
|
590
|
+
return c;
|
|
591
|
+
});
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
if (input === " ") {
|
|
595
|
+
toggle(cursor);
|
|
466
596
|
return;
|
|
467
597
|
}
|
|
598
|
+
if (key.return) {
|
|
599
|
+
handleSubmit();
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
const renderItem = (item, index) => {
|
|
603
|
+
const isCursor = index === cursor;
|
|
604
|
+
return /* @__PURE__ */ jsxs7(Box7, { gap: 1, children: [
|
|
605
|
+
/* @__PURE__ */ jsx7(Text7, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
606
|
+
/* @__PURE__ */ jsx7(Text7, { color: item.enabled ? "green" : "gray", children: item.enabled ? "\u25C9" : "\u25CB" }),
|
|
607
|
+
/* @__PURE__ */ jsx7(Text7, { bold: isCursor, children: item.value }),
|
|
608
|
+
statusLabel(item.status) && /* @__PURE__ */ jsx7(Text7, { color: statusColor(item.status), dimColor: true, children: statusLabel(item.status) })
|
|
609
|
+
] }, item.value);
|
|
610
|
+
};
|
|
611
|
+
return /* @__PURE__ */ jsx7(
|
|
612
|
+
StepShell,
|
|
613
|
+
{
|
|
614
|
+
title: "Review Manifest changes",
|
|
615
|
+
hint: "Tab/shift-tab to jump section, \u2191/\u2193 navigate. Enter to submit",
|
|
616
|
+
onBack,
|
|
617
|
+
children: /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", gap: 1, children: [
|
|
618
|
+
!localManifest && /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "No local manifest.json found \u2014 showing registry values only" }),
|
|
619
|
+
/* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
620
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: !cursorInPerms, bold: cursorInPerms, children: "Permissions".padEnd(14) }),
|
|
621
|
+
/* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingLeft: 2, children: [
|
|
622
|
+
permItems.length > 0 ? permItems.map((item, i) => renderItem(item, i)) : /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " (none)" }),
|
|
623
|
+
cursorInPerms && /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " (space to toggle)" })
|
|
624
|
+
] })
|
|
625
|
+
] }),
|
|
626
|
+
/* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
627
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: !cursorInDomains, bold: cursorInDomains, children: "Allowed Domains".padEnd(14) }),
|
|
628
|
+
/* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingLeft: 2, children: [
|
|
629
|
+
domainItems.length > 0 ? domainItems.map((item, i) => renderItem(item, i + permItems.length)) : /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " (none)" }),
|
|
630
|
+
cursorInDomains && /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " (space to toggle)" })
|
|
631
|
+
] })
|
|
632
|
+
] })
|
|
633
|
+
] })
|
|
634
|
+
}
|
|
635
|
+
);
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
// src/components/UpdateSettingsPrompt.tsx
|
|
639
|
+
import { Box as Box8, Text as Text8, useFocus as useFocus3, useFocusManager as useFocusManager3, useInput as useInput5 } from "ink";
|
|
640
|
+
import TextInput4 from "ink-text-input";
|
|
641
|
+
import { useState as useState5 } from "react";
|
|
642
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
643
|
+
var FieldRow2 = ({ label, value, onChange, placeholder, autoFocus, isFirst, isLast, onSubmitAll }) => {
|
|
644
|
+
const { isFocused } = useFocus3({ autoFocus });
|
|
645
|
+
const { focusNext, focusPrevious } = useFocusManager3();
|
|
646
|
+
useInput5((_, key) => {
|
|
647
|
+
if (!isFocused) return;
|
|
468
648
|
if (key.downArrow) {
|
|
469
649
|
if (!isLast) focusNext();
|
|
470
650
|
return;
|
|
@@ -477,29 +657,17 @@ var FieldRow2 = ({ label, value, onChange, placeholder, autoFocus, isFirst, isLa
|
|
|
477
657
|
onSubmitAll();
|
|
478
658
|
}
|
|
479
659
|
});
|
|
480
|
-
return /* @__PURE__ */
|
|
481
|
-
/* @__PURE__ */
|
|
482
|
-
isFocused ? /* @__PURE__ */
|
|
660
|
+
return /* @__PURE__ */ jsxs8(Box8, { gap: 2, children: [
|
|
661
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: !isFocused, bold: isFocused, children: label.padEnd(14) }),
|
|
662
|
+
isFocused ? /* @__PURE__ */ jsx8(TextInput4, { value, onChange, placeholder }) : /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: value || placeholder || "" })
|
|
483
663
|
] });
|
|
484
664
|
};
|
|
485
665
|
var TargetToggleRow = ({ targets, availableTargets, onToggle, autoFocus, isLast, onSubmitAll }) => {
|
|
486
666
|
const { isFocused } = useFocus3({ autoFocus });
|
|
487
667
|
const { focusNext, focusPrevious } = useFocusManager3();
|
|
488
|
-
const [cursor, setCursor] =
|
|
489
|
-
|
|
668
|
+
const [cursor, setCursor] = useState5(0);
|
|
669
|
+
useInput5((input, key) => {
|
|
490
670
|
if (!isFocused) return;
|
|
491
|
-
if (key.tab && !key.shift) {
|
|
492
|
-
focusNext();
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
if (key.tab && key.shift) {
|
|
496
|
-
if (cursor > 0) {
|
|
497
|
-
setCursor((c) => c - 1);
|
|
498
|
-
} else {
|
|
499
|
-
focusPrevious();
|
|
500
|
-
}
|
|
501
|
-
return;
|
|
502
|
-
}
|
|
503
671
|
if (key.downArrow) {
|
|
504
672
|
if (cursor < availableTargets.length - 1) {
|
|
505
673
|
setCursor((c) => c + 1);
|
|
@@ -524,35 +692,27 @@ var TargetToggleRow = ({ targets, availableTargets, onToggle, autoFocus, isLast,
|
|
|
524
692
|
onSubmitAll();
|
|
525
693
|
}
|
|
526
694
|
});
|
|
527
|
-
return /* @__PURE__ */
|
|
528
|
-
/* @__PURE__ */
|
|
529
|
-
/* @__PURE__ */
|
|
695
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
696
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: !isFocused, bold: isFocused, children: "Targets".padEnd(14) }),
|
|
697
|
+
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingLeft: 2, children: [
|
|
530
698
|
availableTargets.map((t, i) => {
|
|
531
699
|
const selected = targets.includes(t);
|
|
532
700
|
const isCursor = isFocused && i === cursor;
|
|
533
|
-
return /* @__PURE__ */
|
|
534
|
-
/* @__PURE__ */
|
|
535
|
-
/* @__PURE__ */
|
|
536
|
-
/* @__PURE__ */
|
|
701
|
+
return /* @__PURE__ */ jsxs8(Box8, { gap: 1, children: [
|
|
702
|
+
/* @__PURE__ */ jsx8(Text8, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
703
|
+
/* @__PURE__ */ jsx8(Text8, { color: selected ? "green" : "gray", children: selected ? "\u25C9" : "\u25CB" }),
|
|
704
|
+
/* @__PURE__ */ jsx8(Text8, { bold: isCursor, children: t })
|
|
537
705
|
] }, t);
|
|
538
706
|
}),
|
|
539
|
-
isFocused && /* @__PURE__ */
|
|
707
|
+
isFocused && /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " (space to toggle)" })
|
|
540
708
|
] })
|
|
541
709
|
] });
|
|
542
710
|
};
|
|
543
711
|
var EnabledToggleRow = ({ enabled, onToggle, autoFocus, isLast, onSubmitAll }) => {
|
|
544
712
|
const { isFocused } = useFocus3({ autoFocus });
|
|
545
713
|
const { focusNext, focusPrevious } = useFocusManager3();
|
|
546
|
-
|
|
714
|
+
useInput5((input, key) => {
|
|
547
715
|
if (!isFocused) return;
|
|
548
|
-
if (key.tab && !key.shift) {
|
|
549
|
-
if (!isLast) focusNext();
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
if (key.tab && key.shift) {
|
|
553
|
-
focusPrevious();
|
|
554
|
-
return;
|
|
555
|
-
}
|
|
556
716
|
if (key.downArrow) {
|
|
557
717
|
if (!isLast) focusNext();
|
|
558
718
|
return;
|
|
@@ -569,25 +729,17 @@ var EnabledToggleRow = ({ enabled, onToggle, autoFocus, isLast, onSubmitAll }) =
|
|
|
569
729
|
onSubmitAll();
|
|
570
730
|
}
|
|
571
731
|
});
|
|
572
|
-
return /* @__PURE__ */
|
|
573
|
-
/* @__PURE__ */
|
|
574
|
-
/* @__PURE__ */
|
|
575
|
-
isFocused && /* @__PURE__ */
|
|
732
|
+
return /* @__PURE__ */ jsxs8(Box8, { gap: 2, children: [
|
|
733
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: !isFocused, bold: isFocused, children: "Enabled".padEnd(14) }),
|
|
734
|
+
/* @__PURE__ */ jsx8(Text8, { color: enabled ? "green" : "red", bold: isFocused, children: enabled ? "Yes" : "No" }),
|
|
735
|
+
isFocused && /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "(space/arrows to toggle)" })
|
|
576
736
|
] });
|
|
577
737
|
};
|
|
578
738
|
var ForceMajorToggleRow = ({ forceMajor, onToggle, autoFocus, isLast, onSubmitAll }) => {
|
|
579
739
|
const { isFocused } = useFocus3({ autoFocus });
|
|
580
740
|
const { focusPrevious, focusNext } = useFocusManager3();
|
|
581
|
-
|
|
741
|
+
useInput5((input, key) => {
|
|
582
742
|
if (!isFocused) return;
|
|
583
|
-
if (key.tab && !key.shift) {
|
|
584
|
-
if (!isLast) focusNext();
|
|
585
|
-
return;
|
|
586
|
-
}
|
|
587
|
-
if (key.tab && key.shift) {
|
|
588
|
-
focusPrevious();
|
|
589
|
-
return;
|
|
590
|
-
}
|
|
591
743
|
if (key.downArrow) {
|
|
592
744
|
if (!isLast) focusNext();
|
|
593
745
|
return;
|
|
@@ -604,10 +756,10 @@ var ForceMajorToggleRow = ({ forceMajor, onToggle, autoFocus, isLast, onSubmitAl
|
|
|
604
756
|
onSubmitAll();
|
|
605
757
|
}
|
|
606
758
|
});
|
|
607
|
-
return /* @__PURE__ */
|
|
608
|
-
/* @__PURE__ */
|
|
609
|
-
/* @__PURE__ */
|
|
610
|
-
isFocused && /* @__PURE__ */
|
|
759
|
+
return /* @__PURE__ */ jsxs8(Box8, { gap: 2, children: [
|
|
760
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: !isFocused, bold: isFocused, children: "Force major".padEnd(14) }),
|
|
761
|
+
/* @__PURE__ */ jsx8(Text8, { color: forceMajor ? "yellow" : "gray", bold: isFocused, children: forceMajor ? "Yes" : "No" }),
|
|
762
|
+
isFocused && /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "(space/arrows to toggle)" })
|
|
611
763
|
] });
|
|
612
764
|
};
|
|
613
765
|
var UpdateSettingsPrompt = ({
|
|
@@ -619,11 +771,11 @@ var UpdateSettingsPrompt = ({
|
|
|
619
771
|
onSubmit,
|
|
620
772
|
onBack
|
|
621
773
|
}) => {
|
|
622
|
-
const [nameValue, setNameValue] =
|
|
623
|
-
const [targetsValue, setTargetsValue] =
|
|
624
|
-
const [bundleUrlValue, setBundleUrlValue] =
|
|
625
|
-
const [enabledValue, setEnabledValue] =
|
|
626
|
-
const [forceMajorValue, setForceMajorValue] =
|
|
774
|
+
const [nameValue, setNameValue] = useState5(initialName);
|
|
775
|
+
const [targetsValue, setTargetsValue] = useState5(initialTargets);
|
|
776
|
+
const [bundleUrlValue, setBundleUrlValue] = useState5(initialBundleUrl);
|
|
777
|
+
const [enabledValue, setEnabledValue] = useState5(initialEnabled);
|
|
778
|
+
const [forceMajorValue, setForceMajorValue] = useState5(false);
|
|
627
779
|
const handleToggleTarget = (target) => {
|
|
628
780
|
setTargetsValue((prev) => prev.includes(target) ? prev.filter((t) => t !== target) : [...prev, target]);
|
|
629
781
|
};
|
|
@@ -637,14 +789,14 @@ var UpdateSettingsPrompt = ({
|
|
|
637
789
|
forceMajor: forceMajorValue
|
|
638
790
|
});
|
|
639
791
|
};
|
|
640
|
-
return /* @__PURE__ */
|
|
792
|
+
return /* @__PURE__ */ jsx8(
|
|
641
793
|
StepShell,
|
|
642
794
|
{
|
|
643
795
|
title: "Update Extension settings",
|
|
644
|
-
hint: "Tab/
|
|
796
|
+
hint: "Tab/shift-tab to jump section, \u2191/\u2193 navigate. Enter to submit",
|
|
645
797
|
onBack,
|
|
646
|
-
children: /* @__PURE__ */
|
|
647
|
-
/* @__PURE__ */
|
|
798
|
+
children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, children: [
|
|
799
|
+
/* @__PURE__ */ jsx8(
|
|
648
800
|
FieldRow2,
|
|
649
801
|
{
|
|
650
802
|
label: "Name",
|
|
@@ -656,7 +808,7 @@ var UpdateSettingsPrompt = ({
|
|
|
656
808
|
onSubmitAll: handleSubmitAll
|
|
657
809
|
}
|
|
658
810
|
),
|
|
659
|
-
/* @__PURE__ */
|
|
811
|
+
/* @__PURE__ */ jsx8(
|
|
660
812
|
TargetToggleRow,
|
|
661
813
|
{
|
|
662
814
|
targets: targetsValue,
|
|
@@ -665,7 +817,7 @@ var UpdateSettingsPrompt = ({
|
|
|
665
817
|
onSubmitAll: handleSubmitAll
|
|
666
818
|
}
|
|
667
819
|
),
|
|
668
|
-
/* @__PURE__ */
|
|
820
|
+
/* @__PURE__ */ jsx8(
|
|
669
821
|
FieldRow2,
|
|
670
822
|
{
|
|
671
823
|
label: "Bundle URL",
|
|
@@ -675,7 +827,7 @@ var UpdateSettingsPrompt = ({
|
|
|
675
827
|
onSubmitAll: handleSubmitAll
|
|
676
828
|
}
|
|
677
829
|
),
|
|
678
|
-
/* @__PURE__ */
|
|
830
|
+
/* @__PURE__ */ jsx8(
|
|
679
831
|
EnabledToggleRow,
|
|
680
832
|
{
|
|
681
833
|
enabled: enabledValue,
|
|
@@ -683,7 +835,7 @@ var UpdateSettingsPrompt = ({
|
|
|
683
835
|
onSubmitAll: handleSubmitAll
|
|
684
836
|
}
|
|
685
837
|
),
|
|
686
|
-
/* @__PURE__ */
|
|
838
|
+
/* @__PURE__ */ jsx8(
|
|
687
839
|
ForceMajorToggleRow,
|
|
688
840
|
{
|
|
689
841
|
forceMajor: forceMajorValue,
|
|
@@ -698,33 +850,33 @@ var UpdateSettingsPrompt = ({
|
|
|
698
850
|
};
|
|
699
851
|
|
|
700
852
|
// src/components/ScaffoldProgress.tsx
|
|
701
|
-
import { Box as
|
|
853
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
702
854
|
import Spinner from "ink-spinner";
|
|
703
|
-
import { jsx as
|
|
855
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
704
856
|
var stepIcon = (status) => {
|
|
705
857
|
switch (status) {
|
|
706
858
|
case "running":
|
|
707
|
-
return /* @__PURE__ */
|
|
859
|
+
return /* @__PURE__ */ jsx9(Spinner, { type: "dots" });
|
|
708
860
|
case "done":
|
|
709
|
-
return /* @__PURE__ */
|
|
861
|
+
return /* @__PURE__ */ jsx9(Text9, { color: "green", children: "\u2714" });
|
|
710
862
|
case "error":
|
|
711
|
-
return /* @__PURE__ */
|
|
863
|
+
return /* @__PURE__ */ jsx9(Text9, { color: "red", children: "\u2716" });
|
|
712
864
|
default:
|
|
713
|
-
return /* @__PURE__ */
|
|
865
|
+
return /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "\u25CB" });
|
|
714
866
|
}
|
|
715
867
|
};
|
|
716
|
-
var ScaffoldProgress = ({ steps }) => /* @__PURE__ */
|
|
717
|
-
/* @__PURE__ */
|
|
718
|
-
/* @__PURE__ */
|
|
868
|
+
var ScaffoldProgress = ({ steps }) => /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, children: [
|
|
869
|
+
/* @__PURE__ */ jsx9(Text9, { bold: true, children: "Scaffolding your Extension\u2026" }),
|
|
870
|
+
/* @__PURE__ */ jsx9(Box9, { flexDirection: "column", children: steps.map((step) => /* @__PURE__ */ jsxs9(Box9, { gap: 2, children: [
|
|
719
871
|
stepIcon(step.status),
|
|
720
|
-
/* @__PURE__ */
|
|
872
|
+
/* @__PURE__ */ jsx9(Text9, { dimColor: step.status === "pending", color: step.status === "running" ? "cyan" : void 0, children: step.label })
|
|
721
873
|
] }, step.label)) })
|
|
722
874
|
] });
|
|
723
875
|
|
|
724
876
|
// src/components/TargetSelect.tsx
|
|
725
|
-
import { Box as
|
|
726
|
-
import { useState as
|
|
727
|
-
import { jsx as
|
|
877
|
+
import { Box as Box10, Text as Text10, useInput as useInput6 } from "ink";
|
|
878
|
+
import { useState as useState6 } from "react";
|
|
879
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
728
880
|
var TARGET_DESCRIPTIONS = {
|
|
729
881
|
"slot.header": "Renders content in the panel header area",
|
|
730
882
|
"slot.content": "Renders the main panel body (includes store + navigation state)",
|
|
@@ -732,12 +884,12 @@ var TARGET_DESCRIPTIONS = {
|
|
|
732
884
|
"slot.footer-links": "Renders a link row in the global footer"
|
|
733
885
|
};
|
|
734
886
|
var TargetSelect = ({ availableTargets, preSelected, onSubmit, onBack }) => {
|
|
735
|
-
const [cursor, setCursor] =
|
|
736
|
-
const [selected, setSelected] =
|
|
887
|
+
const [cursor, setCursor] = useState6(0);
|
|
888
|
+
const [selected, setSelected] = useState6(
|
|
737
889
|
new Set(preSelected ?? (availableTargets.includes("slot.content") ? ["slot.content"] : []))
|
|
738
890
|
);
|
|
739
|
-
const [error, setError] =
|
|
740
|
-
|
|
891
|
+
const [error, setError] = useState6();
|
|
892
|
+
useInput6((input, key) => {
|
|
741
893
|
if (key.upArrow) {
|
|
742
894
|
setCursor((c) => Math.max(0, c - 1));
|
|
743
895
|
return;
|
|
@@ -768,39 +920,39 @@ var TargetSelect = ({ availableTargets, preSelected, onSubmit, onBack }) => {
|
|
|
768
920
|
onSubmit([...selected]);
|
|
769
921
|
}
|
|
770
922
|
});
|
|
771
|
-
return /* @__PURE__ */
|
|
923
|
+
return /* @__PURE__ */ jsxs10(
|
|
772
924
|
StepShell,
|
|
773
925
|
{
|
|
774
926
|
title: "Select Surface targets/slots",
|
|
775
927
|
hint: "Space to toggle, Enter to confirm",
|
|
776
928
|
onBack,
|
|
777
929
|
children: [
|
|
778
|
-
/* @__PURE__ */
|
|
930
|
+
/* @__PURE__ */ jsx10(Box10, { flexDirection: "column", gap: 1, children: availableTargets.map((target, i) => {
|
|
779
931
|
const isSelected = selected.has(target);
|
|
780
932
|
const isCursor = i === cursor;
|
|
781
|
-
return /* @__PURE__ */
|
|
782
|
-
/* @__PURE__ */
|
|
783
|
-
/* @__PURE__ */
|
|
784
|
-
/* @__PURE__ */
|
|
785
|
-
/* @__PURE__ */
|
|
786
|
-
/* @__PURE__ */
|
|
933
|
+
return /* @__PURE__ */ jsxs10(Box10, { gap: 1, children: [
|
|
934
|
+
/* @__PURE__ */ jsx10(Text10, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
935
|
+
/* @__PURE__ */ jsx10(Text10, { color: isSelected ? "green" : void 0, children: isSelected ? "\u25C9" : "\u25CB" }),
|
|
936
|
+
/* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
|
|
937
|
+
/* @__PURE__ */ jsx10(Text10, { bold: isSelected, children: target }),
|
|
938
|
+
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: TARGET_DESCRIPTIONS[target] ?? target })
|
|
787
939
|
] })
|
|
788
940
|
] }, target);
|
|
789
941
|
}) }),
|
|
790
|
-
error && /* @__PURE__ */
|
|
942
|
+
error && /* @__PURE__ */ jsx10(Text10, { color: "red", children: error })
|
|
791
943
|
]
|
|
792
944
|
}
|
|
793
945
|
);
|
|
794
946
|
};
|
|
795
947
|
|
|
796
948
|
// src/components/TemplateSelect.tsx
|
|
797
|
-
import { Box as
|
|
798
|
-
import { useState as
|
|
799
|
-
import { jsx as
|
|
949
|
+
import { Box as Box11, Text as Text11, useInput as useInput7 } from "ink";
|
|
950
|
+
import { useState as useState7 } from "react";
|
|
951
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
800
952
|
var FLAVORS = ["minimal", "starter", "kitchen-sink"];
|
|
801
953
|
var TemplateSelect = ({ onSubmit, onBack }) => {
|
|
802
|
-
const [cursor, setCursor] =
|
|
803
|
-
|
|
954
|
+
const [cursor, setCursor] = useState7(1);
|
|
955
|
+
useInput7((_input, key) => {
|
|
804
956
|
if (key.upArrow) {
|
|
805
957
|
setCursor((c) => Math.max(0, c - 1));
|
|
806
958
|
return;
|
|
@@ -813,21 +965,21 @@ var TemplateSelect = ({ onSubmit, onBack }) => {
|
|
|
813
965
|
onSubmit(FLAVORS[cursor]);
|
|
814
966
|
}
|
|
815
967
|
});
|
|
816
|
-
return /* @__PURE__ */
|
|
968
|
+
return /* @__PURE__ */ jsx11(
|
|
817
969
|
StepShell,
|
|
818
970
|
{
|
|
819
971
|
title: "Choose a template",
|
|
820
972
|
hint: "\u2191\u2193 to navigate, Enter to select",
|
|
821
973
|
onBack,
|
|
822
|
-
children: /* @__PURE__ */
|
|
974
|
+
children: /* @__PURE__ */ jsx11(Box11, { flexDirection: "column", gap: 1, children: FLAVORS.map((flavor, i) => {
|
|
823
975
|
const meta = TEMPLATE_FLAVOR_META[flavor];
|
|
824
976
|
const isCursor = i === cursor;
|
|
825
|
-
return /* @__PURE__ */
|
|
826
|
-
/* @__PURE__ */
|
|
827
|
-
/* @__PURE__ */
|
|
828
|
-
/* @__PURE__ */
|
|
829
|
-
/* @__PURE__ */
|
|
830
|
-
/* @__PURE__ */
|
|
977
|
+
return /* @__PURE__ */ jsxs11(Box11, { gap: 1, children: [
|
|
978
|
+
/* @__PURE__ */ jsx11(Text11, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
979
|
+
/* @__PURE__ */ jsx11(Text11, { color: isCursor ? "green" : void 0, children: isCursor ? "\u25C9" : "\u25CB" }),
|
|
980
|
+
/* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
981
|
+
/* @__PURE__ */ jsx11(Text11, { bold: isCursor, children: meta.label }),
|
|
982
|
+
/* @__PURE__ */ jsx11(Text11, { dimColor: true, children: meta.description })
|
|
831
983
|
] })
|
|
832
984
|
] }, flavor);
|
|
833
985
|
}) })
|
|
@@ -836,9 +988,9 @@ var TemplateSelect = ({ onSubmit, onBack }) => {
|
|
|
836
988
|
};
|
|
837
989
|
|
|
838
990
|
// src/components/AppSelect.tsx
|
|
839
|
-
import { Box as
|
|
991
|
+
import { Box as Box13, Text as Text13, useInput as useInput8 } from "ink";
|
|
840
992
|
import Spinner2 from "ink-spinner";
|
|
841
|
-
import { useEffect as useEffect2, useState as
|
|
993
|
+
import { useEffect as useEffect2, useState as useState8 } from "react";
|
|
842
994
|
|
|
843
995
|
// src/lib/api.ts
|
|
844
996
|
var DEFAULT_ADMIN_API_URL = "https://api-use1.stackablelabs.io/admin";
|
|
@@ -915,8 +1067,8 @@ var updateExtension = async (token, appId, extensionId, payload) => {
|
|
|
915
1067
|
};
|
|
916
1068
|
|
|
917
1069
|
// src/components/Banner.tsx
|
|
918
|
-
import { Box as
|
|
919
|
-
import { jsx as
|
|
1070
|
+
import { Box as Box12, Text as Text12 } from "ink";
|
|
1071
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
920
1072
|
var WORDMARK = [
|
|
921
1073
|
" _ _ _ _ ",
|
|
922
1074
|
" ___| |_ __ _ ___| | ____ _| |__ | | ___",
|
|
@@ -952,18 +1104,18 @@ var gradientColor = (row, col, rows, cols) => {
|
|
|
952
1104
|
var Banner = ({ userId, orgId } = {}) => {
|
|
953
1105
|
const termWidth = process.stdout.columns ?? 80;
|
|
954
1106
|
const maxLen = Math.max(...WORDMARK.map((l) => l.length));
|
|
955
|
-
return /* @__PURE__ */
|
|
956
|
-
/* @__PURE__ */
|
|
957
|
-
/* @__PURE__ */
|
|
958
|
-
WORDMARK.map((line, row) => /* @__PURE__ */
|
|
959
|
-
userId && orgId && /* @__PURE__ */
|
|
960
|
-
/* @__PURE__ */
|
|
961
|
-
/* @__PURE__ */
|
|
962
|
-
/* @__PURE__ */
|
|
1107
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
|
|
1108
|
+
/* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "\u2500".repeat(termWidth) }),
|
|
1109
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [
|
|
1110
|
+
WORDMARK.map((line, row) => /* @__PURE__ */ jsx12(Box12, { children: line.split("").map((ch, col) => /* @__PURE__ */ jsx12(Text12, { bold: true, color: ch === " " ? void 0 : gradientColor(row, col, WORDMARK.length, maxLen), children: ch }, col)) }, row)),
|
|
1111
|
+
userId && orgId && /* @__PURE__ */ jsxs12(Box12, { gap: 2, marginTop: 1, children: [
|
|
1112
|
+
/* @__PURE__ */ jsxs12(Box12, { gap: 1, children: [
|
|
1113
|
+
/* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "User:" }),
|
|
1114
|
+
/* @__PURE__ */ jsx12(Text12, { color: "cyan", children: userId })
|
|
963
1115
|
] }),
|
|
964
|
-
/* @__PURE__ */
|
|
965
|
-
/* @__PURE__ */
|
|
966
|
-
/* @__PURE__ */
|
|
1116
|
+
/* @__PURE__ */ jsxs12(Box12, { gap: 1, children: [
|
|
1117
|
+
/* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "Org:" }),
|
|
1118
|
+
/* @__PURE__ */ jsx12(Text12, { color: "cyan", children: orgId })
|
|
967
1119
|
] })
|
|
968
1120
|
] })
|
|
969
1121
|
] })
|
|
@@ -971,16 +1123,16 @@ var Banner = ({ userId, orgId } = {}) => {
|
|
|
971
1123
|
};
|
|
972
1124
|
|
|
973
1125
|
// src/components/AppSelect.tsx
|
|
974
|
-
import { jsx as
|
|
1126
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
975
1127
|
var AppSelect = ({ token, userId, orgId, onSubmit }) => {
|
|
976
|
-
const [apps, setApps] =
|
|
977
|
-
const [loading, setLoading] =
|
|
978
|
-
const [error, setError] =
|
|
979
|
-
const [cursor, setCursor] =
|
|
1128
|
+
const [apps, setApps] = useState8([]);
|
|
1129
|
+
const [loading, setLoading] = useState8(true);
|
|
1130
|
+
const [error, setError] = useState8();
|
|
1131
|
+
const [cursor, setCursor] = useState8(0);
|
|
980
1132
|
useEffect2(() => {
|
|
981
1133
|
fetchApps(token).then(setApps).catch((err) => setError(err instanceof Error ? err.message : String(err))).finally(() => setLoading(false));
|
|
982
1134
|
}, [token]);
|
|
983
|
-
|
|
1135
|
+
useInput8((_, key) => {
|
|
984
1136
|
if (loading || error || apps.length === 0) return;
|
|
985
1137
|
if (key.upArrow) {
|
|
986
1138
|
setCursor((c) => Math.max(0, c - 1));
|
|
@@ -992,26 +1144,26 @@ var AppSelect = ({ token, userId, orgId, onSubmit }) => {
|
|
|
992
1144
|
});
|
|
993
1145
|
const renderContent = () => {
|
|
994
1146
|
if (loading) {
|
|
995
|
-
return /* @__PURE__ */
|
|
996
|
-
/* @__PURE__ */
|
|
997
|
-
/* @__PURE__ */
|
|
1147
|
+
return /* @__PURE__ */ jsxs13(Box13, { gap: 2, children: [
|
|
1148
|
+
/* @__PURE__ */ jsx13(Spinner2, { type: "dots" }),
|
|
1149
|
+
/* @__PURE__ */ jsx13(Text13, { children: "Loading available Apps\u2026" })
|
|
998
1150
|
] });
|
|
999
1151
|
}
|
|
1000
1152
|
if (error) {
|
|
1001
|
-
return /* @__PURE__ */
|
|
1002
|
-
/* @__PURE__ */
|
|
1003
|
-
/* @__PURE__ */
|
|
1153
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", gap: 1, children: [
|
|
1154
|
+
/* @__PURE__ */ jsx13(Text13, { color: "red", bold: true, children: "Failed to load Apps" }),
|
|
1155
|
+
/* @__PURE__ */ jsx13(Text13, { color: "red", children: error })
|
|
1004
1156
|
] });
|
|
1005
1157
|
}
|
|
1006
1158
|
if (apps.length === 0) {
|
|
1007
|
-
return /* @__PURE__ */
|
|
1159
|
+
return /* @__PURE__ */ jsx13(Text13, { color: "yellow", children: "No Apps available. Contact your administrator." });
|
|
1008
1160
|
}
|
|
1009
|
-
return /* @__PURE__ */
|
|
1161
|
+
return /* @__PURE__ */ jsx13(Box13, { flexDirection: "column", children: apps.map((app, i) => {
|
|
1010
1162
|
const isCursor = i === cursor;
|
|
1011
|
-
return /* @__PURE__ */
|
|
1012
|
-
/* @__PURE__ */
|
|
1013
|
-
/* @__PURE__ */
|
|
1014
|
-
/* @__PURE__ */
|
|
1163
|
+
return /* @__PURE__ */ jsxs13(Box13, { gap: 1, children: [
|
|
1164
|
+
/* @__PURE__ */ jsx13(Text13, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
1165
|
+
/* @__PURE__ */ jsx13(Text13, { bold: isCursor, children: app.name }),
|
|
1166
|
+
/* @__PURE__ */ jsxs13(Text13, { dimColor: true, children: [
|
|
1015
1167
|
"(",
|
|
1016
1168
|
app.id,
|
|
1017
1169
|
")"
|
|
@@ -1019,26 +1171,26 @@ var AppSelect = ({ token, userId, orgId, onSubmit }) => {
|
|
|
1019
1171
|
] }, app.id);
|
|
1020
1172
|
}) });
|
|
1021
1173
|
};
|
|
1022
|
-
return /* @__PURE__ */
|
|
1023
|
-
/* @__PURE__ */
|
|
1024
|
-
/* @__PURE__ */
|
|
1174
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
|
|
1175
|
+
/* @__PURE__ */ jsx13(Banner, { userId, orgId }),
|
|
1176
|
+
/* @__PURE__ */ jsx13(StepShell, { title: "Select the App you are building an Extension for:", children: renderContent() })
|
|
1025
1177
|
] });
|
|
1026
1178
|
};
|
|
1027
1179
|
|
|
1028
1180
|
// src/components/ExtensionSelect.tsx
|
|
1029
|
-
import { Box as
|
|
1181
|
+
import { Box as Box14, Text as Text14, useInput as useInput9 } from "ink";
|
|
1030
1182
|
import Spinner3 from "ink-spinner";
|
|
1031
|
-
import { useEffect as useEffect3, useState as
|
|
1032
|
-
import { jsx as
|
|
1183
|
+
import { useEffect as useEffect3, useState as useState9 } from "react";
|
|
1184
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1033
1185
|
var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
1034
|
-
const [extensions, setExtensions] =
|
|
1035
|
-
const [loading, setLoading] =
|
|
1036
|
-
const [error, setError] =
|
|
1037
|
-
const [cursor, setCursor] =
|
|
1186
|
+
const [extensions, setExtensions] = useState9([]);
|
|
1187
|
+
const [loading, setLoading] = useState9(true);
|
|
1188
|
+
const [error, setError] = useState9();
|
|
1189
|
+
const [cursor, setCursor] = useState9(0);
|
|
1038
1190
|
useEffect3(() => {
|
|
1039
1191
|
fetchExtensions(token, appId).then((byId) => setExtensions(Object.values(byId))).catch((err) => setError(err instanceof Error ? err.message : String(err))).finally(() => setLoading(false));
|
|
1040
1192
|
}, [appId, token]);
|
|
1041
|
-
|
|
1193
|
+
useInput9((_, key) => {
|
|
1042
1194
|
if (key.upArrow) {
|
|
1043
1195
|
if (!loading && !error && extensions.length > 0) {
|
|
1044
1196
|
setCursor((c) => Math.max(0, c - 1));
|
|
@@ -1059,30 +1211,30 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
|
1059
1211
|
});
|
|
1060
1212
|
const renderContent = () => {
|
|
1061
1213
|
if (loading) {
|
|
1062
|
-
return /* @__PURE__ */
|
|
1063
|
-
/* @__PURE__ */
|
|
1064
|
-
/* @__PURE__ */
|
|
1214
|
+
return /* @__PURE__ */ jsxs14(Box14, { gap: 2, children: [
|
|
1215
|
+
/* @__PURE__ */ jsx14(Spinner3, { type: "dots" }),
|
|
1216
|
+
/* @__PURE__ */ jsx14(Text14, { children: "Loading Extensions\u2026" })
|
|
1065
1217
|
] });
|
|
1066
1218
|
}
|
|
1067
1219
|
if (error) {
|
|
1068
|
-
return /* @__PURE__ */
|
|
1069
|
-
/* @__PURE__ */
|
|
1070
|
-
/* @__PURE__ */
|
|
1220
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", gap: 1, children: [
|
|
1221
|
+
/* @__PURE__ */ jsx14(Text14, { color: "red", bold: true, children: "Failed to load Extensions" }),
|
|
1222
|
+
/* @__PURE__ */ jsx14(Text14, { color: "red", children: error })
|
|
1071
1223
|
] });
|
|
1072
1224
|
}
|
|
1073
1225
|
if (extensions.length === 0) {
|
|
1074
|
-
return /* @__PURE__ */
|
|
1226
|
+
return /* @__PURE__ */ jsx14(Text14, { color: "yellow", children: "No Extensions found for this App." });
|
|
1075
1227
|
}
|
|
1076
|
-
return /* @__PURE__ */
|
|
1228
|
+
return /* @__PURE__ */ jsx14(Box14, { flexDirection: "column", children: extensions.map((ext, i) => {
|
|
1077
1229
|
const isCursor = i === cursor;
|
|
1078
|
-
return /* @__PURE__ */
|
|
1079
|
-
/* @__PURE__ */
|
|
1080
|
-
/* @__PURE__ */
|
|
1081
|
-
/* @__PURE__ */
|
|
1230
|
+
return /* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
|
|
1231
|
+
/* @__PURE__ */ jsx14(Text14, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
1232
|
+
/* @__PURE__ */ jsx14(Text14, { bold: isCursor, children: ext.manifest.name }),
|
|
1233
|
+
/* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
|
|
1082
1234
|
"v",
|
|
1083
1235
|
ext.manifest.version
|
|
1084
1236
|
] }),
|
|
1085
|
-
/* @__PURE__ */
|
|
1237
|
+
/* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
|
|
1086
1238
|
"(",
|
|
1087
1239
|
ext.id,
|
|
1088
1240
|
")"
|
|
@@ -1090,7 +1242,7 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
|
1090
1242
|
] }, ext.id);
|
|
1091
1243
|
}) });
|
|
1092
1244
|
};
|
|
1093
|
-
return /* @__PURE__ */
|
|
1245
|
+
return /* @__PURE__ */ jsx14(
|
|
1094
1246
|
StepShell,
|
|
1095
1247
|
{
|
|
1096
1248
|
title: command === "update" /* UPDATE */ ? "Select an Extension to update:" : "Select an existing Extension to scaffold:",
|
|
@@ -1161,10 +1313,11 @@ var readDevContext = async (projectRoot) => {
|
|
|
1161
1313
|
const stackableEnv = await readEnvFile(join(projectRoot, ".env.stackable"));
|
|
1162
1314
|
const env = await readEnvFile(join(projectRoot, ".env"));
|
|
1163
1315
|
let extensionName = stackableEnv.EXTENSION_NAME || "Unknown Extension";
|
|
1316
|
+
let manifest = null;
|
|
1164
1317
|
try {
|
|
1165
1318
|
const manifestPath = join(projectRoot, "packages/extension/public/manifest.json");
|
|
1166
1319
|
const manifestContent = await readFile(manifestPath, "utf8");
|
|
1167
|
-
|
|
1320
|
+
manifest = JSON.parse(manifestContent);
|
|
1168
1321
|
extensionName = manifest.name;
|
|
1169
1322
|
} catch {
|
|
1170
1323
|
}
|
|
@@ -1179,7 +1332,8 @@ var readDevContext = async (projectRoot) => {
|
|
|
1179
1332
|
appName: stackableEnv.APP_NAME || null,
|
|
1180
1333
|
orgId: stackableEnv.ORG_ID || null,
|
|
1181
1334
|
extensionPort,
|
|
1182
|
-
previewPort
|
|
1335
|
+
previewPort,
|
|
1336
|
+
manifest
|
|
1183
1337
|
};
|
|
1184
1338
|
};
|
|
1185
1339
|
var DEV_LOCAL_ENV = ".env.development.local";
|
|
@@ -1209,11 +1363,13 @@ var writeDevContext = async (projectRoot, ctx) => {
|
|
|
1209
1363
|
await writeEnvFile(join(projectRoot, ".env.stackable"), env);
|
|
1210
1364
|
};
|
|
1211
1365
|
|
|
1212
|
-
// src/lib/
|
|
1366
|
+
// src/lib/utils.ts
|
|
1213
1367
|
var toKebabCase = (value) => value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1368
|
+
|
|
1369
|
+
// src/lib/scaffold.ts
|
|
1214
1370
|
var isTextFile = (filePath) => /\.(ts|tsx|js|jsx|json|md|html|yml|yaml|env|gitignore|nvmrc)$/i.test(filePath);
|
|
1215
1371
|
var normalizeTargets = (targets) => Array.from(new Set(targets));
|
|
1216
|
-
var
|
|
1372
|
+
var deriveScaffoldPermissions = (targets) => {
|
|
1217
1373
|
const permissions = /* @__PURE__ */ new Set();
|
|
1218
1374
|
for (const target of targets) {
|
|
1219
1375
|
for (const permission of TARGET_PERMISSION_MAP[target] ?? DEFAULT_PERMISSIONS) {
|
|
@@ -1539,7 +1695,7 @@ var scaffold = async (options) => {
|
|
|
1539
1695
|
});
|
|
1540
1696
|
if (flavor === "starter") {
|
|
1541
1697
|
const selectedTargets = normalizeTargets(options.targets);
|
|
1542
|
-
const derivedPermissions =
|
|
1698
|
+
const derivedPermissions = deriveScaffoldPermissions(selectedTargets);
|
|
1543
1699
|
await generateManifest(dir, options.name, selectedTargets, derivedPermissions);
|
|
1544
1700
|
await generateSurfaceFiles(dir, selectedTargets);
|
|
1545
1701
|
await rewriteExtensionIndex(dir, options.extensionId || options.name, selectedTargets);
|
|
@@ -1557,17 +1713,18 @@ var scaffold = async (options) => {
|
|
|
1557
1713
|
appName: options.appName || null,
|
|
1558
1714
|
extensionName: options.name,
|
|
1559
1715
|
extensionPort: options.extensionPort,
|
|
1560
|
-
previewPort: options.previewPort
|
|
1716
|
+
previewPort: options.previewPort,
|
|
1717
|
+
manifest: null
|
|
1561
1718
|
});
|
|
1562
1719
|
return options;
|
|
1563
1720
|
};
|
|
1564
1721
|
|
|
1565
1722
|
// src/App.tsx
|
|
1566
|
-
import { jsx as
|
|
1723
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1567
1724
|
var STEPS = {
|
|
1568
1725
|
["create" /* CREATE */]: ["app", "name", "template", "targets", "settings", "confirm"],
|
|
1569
1726
|
["scaffold" /* SCAFFOLD */]: ["app", "extensionSelect", "confirmTargets", "settings", "confirm"],
|
|
1570
|
-
["update" /* UPDATE */]: ["app", "extensionSelect", "updateSettings", "confirm"],
|
|
1727
|
+
["update" /* UPDATE */]: ["app", "extensionSelect", "updateSettings", "manifestReview", "confirm"],
|
|
1571
1728
|
["dev" /* DEV */]: []
|
|
1572
1729
|
// Dev command has no wizard steps
|
|
1573
1730
|
};
|
|
@@ -1589,8 +1746,7 @@ var PROGRESS_STEPS = {
|
|
|
1589
1746
|
["dev" /* DEV */]: []
|
|
1590
1747
|
// Dev command has no progress steps
|
|
1591
1748
|
};
|
|
1592
|
-
var
|
|
1593
|
-
var derivePermissions2 = (targets) => {
|
|
1749
|
+
var deriveRegistryPermissions = (targets) => {
|
|
1594
1750
|
const permissions = /* @__PURE__ */ new Set();
|
|
1595
1751
|
for (const target of targets) {
|
|
1596
1752
|
const mapped = TARGET_PERMISSION_MAP[target];
|
|
@@ -1609,33 +1765,37 @@ var derivePermissions2 = (targets) => {
|
|
|
1609
1765
|
};
|
|
1610
1766
|
var App = ({ command, token, userId, orgId, initialName, initialExtensionId, options }) => {
|
|
1611
1767
|
const { exit } = useApp();
|
|
1612
|
-
const [step, setStep] =
|
|
1613
|
-
const [name, setName] =
|
|
1614
|
-
const [extensionId, setExtensionId] =
|
|
1615
|
-
const [extensionVersion, setExtensionVersion] =
|
|
1616
|
-
const [bundleUrl, setBundleUrl] =
|
|
1617
|
-
const [enabled, setEnabled] =
|
|
1768
|
+
const [step, setStep] = useState10("app");
|
|
1769
|
+
const [name, setName] = useState10(initialName ?? options?.name ?? "");
|
|
1770
|
+
const [extensionId, setExtensionId] = useState10(initialExtensionId ?? "");
|
|
1771
|
+
const [extensionVersion, setExtensionVersion] = useState10("");
|
|
1772
|
+
const [bundleUrl, setBundleUrl] = useState10(options?.bundleUrl ?? "");
|
|
1773
|
+
const [enabled, setEnabled] = useState10(
|
|
1618
1774
|
options?.enabled !== void 0 ? options.enabled !== "false" : true
|
|
1619
1775
|
);
|
|
1620
|
-
const [versionOverride, setVersionOverride] =
|
|
1621
|
-
const [forceMajor, setForceMajor] =
|
|
1622
|
-
const [initialExtension, setInitialExtension] =
|
|
1623
|
-
const [templateFlavor, setTemplateFlavor] =
|
|
1776
|
+
const [versionOverride, setVersionOverride] = useState10(void 0);
|
|
1777
|
+
const [forceMajor, setForceMajor] = useState10(false);
|
|
1778
|
+
const [initialExtension, setInitialExtension] = useState10(null);
|
|
1779
|
+
const [templateFlavor, setTemplateFlavor] = useState10(
|
|
1624
1780
|
options?.template ?? "starter"
|
|
1625
1781
|
);
|
|
1626
|
-
const [targets, setTargets] =
|
|
1782
|
+
const [targets, setTargets] = useState10(
|
|
1627
1783
|
options?.targets ? options.targets.split(",").map((t) => t.trim()) : []
|
|
1628
1784
|
);
|
|
1629
|
-
const [selectedApp, setSelectedApp] =
|
|
1630
|
-
const [extensionPort, setExtensionPort] =
|
|
1785
|
+
const [selectedApp, setSelectedApp] = useState10(null);
|
|
1786
|
+
const [extensionPort, setExtensionPort] = useState10(
|
|
1631
1787
|
options?.extensionPort ? parseInt(options.extensionPort, 10) : 6543
|
|
1632
1788
|
);
|
|
1633
|
-
const [previewPort, setPreviewPort] =
|
|
1789
|
+
const [previewPort, setPreviewPort] = useState10(
|
|
1634
1790
|
options?.previewPort ? parseInt(options.previewPort, 10) : 6544
|
|
1635
1791
|
);
|
|
1636
|
-
const [
|
|
1637
|
-
const [
|
|
1638
|
-
const [
|
|
1792
|
+
const [registryManifest, setRegistryManifest] = useState10(null);
|
|
1793
|
+
const [localManifest, setLocalManifest] = useState10(null);
|
|
1794
|
+
const [confirmedPermissions, setConfirmedPermissions] = useState10([]);
|
|
1795
|
+
const [confirmedAllowedDomains, setConfirmedAllowedDomains] = useState10([]);
|
|
1796
|
+
const [outputDir, setOutputDir] = useState10("");
|
|
1797
|
+
const [progressSteps, setProgressSteps] = useState10(PROGRESS_STEPS[command]);
|
|
1798
|
+
const [errorMessage, setErrorMessage] = useState10();
|
|
1639
1799
|
const updateStep = useCallback((index, status) => {
|
|
1640
1800
|
setProgressSteps((prev) => prev.map((s, i) => i === index ? { ...s, status } : s));
|
|
1641
1801
|
}, []);
|
|
@@ -1670,8 +1830,47 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1670
1830
|
return idx > 0 ? steps[idx - 1] : prev;
|
|
1671
1831
|
});
|
|
1672
1832
|
}, [activeSteps]);
|
|
1673
|
-
const handleAppSelect = (app) => {
|
|
1833
|
+
const handleAppSelect = async (app) => {
|
|
1674
1834
|
setSelectedApp(app);
|
|
1835
|
+
if (command === "update" /* UPDATE */ && initialExtensionId) {
|
|
1836
|
+
try {
|
|
1837
|
+
const extensions = await fetchExtensions(token, app.id);
|
|
1838
|
+
const ext = extensions[initialExtensionId];
|
|
1839
|
+
if (!ext) {
|
|
1840
|
+
setErrorMessage(
|
|
1841
|
+
`Extension "${initialExtensionId}" not found or is disabled. If disabled, re-enable it in the admin dashboard before updating.`
|
|
1842
|
+
);
|
|
1843
|
+
setStep("error");
|
|
1844
|
+
return;
|
|
1845
|
+
}
|
|
1846
|
+
setName(ext.manifest.name);
|
|
1847
|
+
setExtensionId(ext.id);
|
|
1848
|
+
setExtensionVersion(ext.manifest.version);
|
|
1849
|
+
setTargets(ext.manifest.targets);
|
|
1850
|
+
setBundleUrl(ext.bundleUrl);
|
|
1851
|
+
setEnabled(ext.enabled ?? true);
|
|
1852
|
+
setInitialExtension({
|
|
1853
|
+
name: ext.manifest.name,
|
|
1854
|
+
targets: ext.manifest.targets,
|
|
1855
|
+
bundleUrl: ext.bundleUrl
|
|
1856
|
+
});
|
|
1857
|
+
setRegistryManifest(ext.manifest);
|
|
1858
|
+
const projectRoot = options?.dir || process.cwd();
|
|
1859
|
+
try {
|
|
1860
|
+
const manifestPath = join3(projectRoot, "packages/extension/public/manifest.json");
|
|
1861
|
+
const content = await readFile3(manifestPath, "utf8");
|
|
1862
|
+
setLocalManifest(JSON.parse(content));
|
|
1863
|
+
} catch {
|
|
1864
|
+
setLocalManifest(null);
|
|
1865
|
+
}
|
|
1866
|
+
setStep("updateSettings");
|
|
1867
|
+
} catch (err) {
|
|
1868
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1869
|
+
setErrorMessage(message);
|
|
1870
|
+
setStep("error");
|
|
1871
|
+
}
|
|
1872
|
+
return;
|
|
1873
|
+
}
|
|
1675
1874
|
if (command === "scaffold" /* SCAFFOLD */ || command === "update" /* UPDATE */) {
|
|
1676
1875
|
setStep("extensionSelect");
|
|
1677
1876
|
return;
|
|
@@ -1682,7 +1881,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1682
1881
|
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
1683
1882
|
setTargets(meta.defaultTargets);
|
|
1684
1883
|
if (options?.extensionPort || options?.previewPort) {
|
|
1685
|
-
setOutputDir(join3(process.cwd(),
|
|
1884
|
+
setOutputDir(join3(process.cwd(), toKebabCase(initialName)));
|
|
1686
1885
|
setStep("confirm");
|
|
1687
1886
|
} else {
|
|
1688
1887
|
setStep("settings");
|
|
@@ -1697,7 +1896,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1697
1896
|
setStep("name");
|
|
1698
1897
|
}
|
|
1699
1898
|
};
|
|
1700
|
-
const handleExtensionSelect = (ext) => {
|
|
1899
|
+
const handleExtensionSelect = async (ext) => {
|
|
1701
1900
|
setName(ext.manifest.name);
|
|
1702
1901
|
setExtensionId(ext.id);
|
|
1703
1902
|
setExtensionVersion(ext.manifest.version);
|
|
@@ -1709,6 +1908,15 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1709
1908
|
targets: ext.manifest.targets,
|
|
1710
1909
|
bundleUrl: ext.bundleUrl
|
|
1711
1910
|
});
|
|
1911
|
+
setRegistryManifest(ext.manifest);
|
|
1912
|
+
const projectRoot = options?.dir || process.cwd();
|
|
1913
|
+
try {
|
|
1914
|
+
const manifestPath = join3(projectRoot, "packages/extension/public/manifest.json");
|
|
1915
|
+
const content = await readFile3(manifestPath, "utf8");
|
|
1916
|
+
setLocalManifest(JSON.parse(content));
|
|
1917
|
+
} catch {
|
|
1918
|
+
setLocalManifest(null);
|
|
1919
|
+
}
|
|
1712
1920
|
if (command === "scaffold" /* SCAFFOLD */) {
|
|
1713
1921
|
setStep("confirmTargets");
|
|
1714
1922
|
} else if (command === "update" /* UPDATE */) {
|
|
@@ -1718,7 +1926,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1718
1926
|
const handleConfirmTargets = (value) => {
|
|
1719
1927
|
setTargets(value);
|
|
1720
1928
|
if (options?.extensionPort || options?.previewPort) {
|
|
1721
|
-
setOutputDir(join3(process.cwd(),
|
|
1929
|
+
setOutputDir(join3(process.cwd(), toKebabCase(extensionId || name)));
|
|
1722
1930
|
setStep("confirm");
|
|
1723
1931
|
} else {
|
|
1724
1932
|
setStep("settings");
|
|
@@ -1726,13 +1934,13 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1726
1934
|
};
|
|
1727
1935
|
const handleName = (value) => {
|
|
1728
1936
|
setName(value);
|
|
1729
|
-
setExtensionId(
|
|
1937
|
+
setExtensionId(toKebabCase(value));
|
|
1730
1938
|
if (options?.template) {
|
|
1731
1939
|
const meta = TEMPLATE_FLAVOR_META[templateFlavor];
|
|
1732
1940
|
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
1733
1941
|
setTargets(meta.defaultTargets);
|
|
1734
1942
|
if (options?.extensionPort || options?.previewPort) {
|
|
1735
|
-
setOutputDir(join3(process.cwd(),
|
|
1943
|
+
setOutputDir(join3(process.cwd(), toKebabCase(value)));
|
|
1736
1944
|
setStep("confirm");
|
|
1737
1945
|
} else {
|
|
1738
1946
|
setStep("settings");
|
|
@@ -1750,7 +1958,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1750
1958
|
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
1751
1959
|
setTargets(meta.defaultTargets);
|
|
1752
1960
|
if (options?.extensionPort || options?.previewPort) {
|
|
1753
|
-
setOutputDir(join3(process.cwd(),
|
|
1961
|
+
setOutputDir(join3(process.cwd(), toKebabCase(extensionId || name)));
|
|
1754
1962
|
setStep("confirm");
|
|
1755
1963
|
} else {
|
|
1756
1964
|
setStep("settings");
|
|
@@ -1762,7 +1970,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1762
1970
|
const handleTargets = (value) => {
|
|
1763
1971
|
setTargets(value);
|
|
1764
1972
|
if (options?.extensionPort || options?.previewPort) {
|
|
1765
|
-
setOutputDir(join3(process.cwd(),
|
|
1973
|
+
setOutputDir(join3(process.cwd(), toKebabCase(extensionId || name)));
|
|
1766
1974
|
setStep("confirm");
|
|
1767
1975
|
} else {
|
|
1768
1976
|
setStep("settings");
|
|
@@ -1784,7 +1992,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1784
1992
|
if (targetsChanged) return `${major}.${minor + 1}.0`;
|
|
1785
1993
|
const nameChanged = newName !== initialExtension.name;
|
|
1786
1994
|
if (nameChanged) return `${major}.${minor}.${patch + 1}`;
|
|
1787
|
-
return
|
|
1995
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
1788
1996
|
};
|
|
1789
1997
|
const handleConfirm = async () => {
|
|
1790
1998
|
if (command === "update" /* UPDATE */) {
|
|
@@ -1798,8 +2006,8 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1798
2006
|
name,
|
|
1799
2007
|
version: resolvedVersion,
|
|
1800
2008
|
targets,
|
|
1801
|
-
permissions:
|
|
1802
|
-
allowedDomains:
|
|
2009
|
+
permissions: confirmedPermissions,
|
|
2010
|
+
allowedDomains: confirmedAllowedDomains
|
|
1803
2011
|
},
|
|
1804
2012
|
bundleUrl: bundleUrl || void 0,
|
|
1805
2013
|
enabled
|
|
@@ -1817,7 +2025,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1817
2025
|
setStep("scaffolding");
|
|
1818
2026
|
setProgressSteps(PROGRESS_STEPS[command]);
|
|
1819
2027
|
try {
|
|
1820
|
-
let resolvedExtensionId = extensionId ||
|
|
2028
|
+
let resolvedExtensionId = extensionId || toKebabCase(name);
|
|
1821
2029
|
let scaffoldStepOffset = 0;
|
|
1822
2030
|
if (command === "create" /* CREATE */) {
|
|
1823
2031
|
scaffoldStepOffset = 1;
|
|
@@ -1827,7 +2035,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1827
2035
|
name,
|
|
1828
2036
|
version: "0.0.0",
|
|
1829
2037
|
targets,
|
|
1830
|
-
permissions:
|
|
2038
|
+
permissions: deriveRegistryPermissions(targets),
|
|
1831
2039
|
allowedDomains: []
|
|
1832
2040
|
},
|
|
1833
2041
|
bundleUrl: `http://localhost:${extensionPort}`
|
|
@@ -1849,6 +2057,17 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1849
2057
|
previewPort
|
|
1850
2058
|
});
|
|
1851
2059
|
updateStep(scaffoldStepOffset + 0, "done");
|
|
2060
|
+
if (command === "create" /* CREATE */) {
|
|
2061
|
+
const manifestPath = join3(outputDir, "packages/extension/public/manifest.json");
|
|
2062
|
+
try {
|
|
2063
|
+
const manifestContent = await readFile3(manifestPath, "utf8");
|
|
2064
|
+
const manifest = JSON.parse(manifestContent);
|
|
2065
|
+
await updateExtension(token, selectedApp.id, resolvedExtensionId, {
|
|
2066
|
+
manifest: { ...manifest, allowedDomains: [] }
|
|
2067
|
+
});
|
|
2068
|
+
} catch {
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
1852
2071
|
updateStep(scaffoldStepOffset + 1, "running");
|
|
1853
2072
|
await new Promise((r) => setTimeout(r, 200));
|
|
1854
2073
|
updateStep(scaffoldStepOffset + 1, "done");
|
|
@@ -1871,7 +2090,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1871
2090
|
};
|
|
1872
2091
|
switch (step) {
|
|
1873
2092
|
case "app": {
|
|
1874
|
-
return /* @__PURE__ */
|
|
2093
|
+
return /* @__PURE__ */ jsx15(
|
|
1875
2094
|
AppSelect,
|
|
1876
2095
|
{
|
|
1877
2096
|
token,
|
|
@@ -1882,7 +2101,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1882
2101
|
);
|
|
1883
2102
|
}
|
|
1884
2103
|
case "extensionSelect": {
|
|
1885
|
-
return /* @__PURE__ */
|
|
2104
|
+
return /* @__PURE__ */ jsx15(
|
|
1886
2105
|
ExtensionSelect,
|
|
1887
2106
|
{
|
|
1888
2107
|
appId: selectedApp.id,
|
|
@@ -1894,7 +2113,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1894
2113
|
);
|
|
1895
2114
|
}
|
|
1896
2115
|
case "confirmTargets": {
|
|
1897
|
-
return /* @__PURE__ */
|
|
2116
|
+
return /* @__PURE__ */ jsx15(
|
|
1898
2117
|
TargetSelect,
|
|
1899
2118
|
{
|
|
1900
2119
|
availableTargets: selectedApp?.targets ?? [],
|
|
@@ -1905,7 +2124,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1905
2124
|
);
|
|
1906
2125
|
}
|
|
1907
2126
|
case "name": {
|
|
1908
|
-
return /* @__PURE__ */
|
|
2127
|
+
return /* @__PURE__ */ jsx15(
|
|
1909
2128
|
NamePrompt,
|
|
1910
2129
|
{
|
|
1911
2130
|
initialValue: name,
|
|
@@ -1915,7 +2134,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1915
2134
|
);
|
|
1916
2135
|
}
|
|
1917
2136
|
case "template": {
|
|
1918
|
-
return /* @__PURE__ */
|
|
2137
|
+
return /* @__PURE__ */ jsx15(
|
|
1919
2138
|
TemplateSelect,
|
|
1920
2139
|
{
|
|
1921
2140
|
onSubmit: handleTemplateSelect,
|
|
@@ -1924,7 +2143,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1924
2143
|
);
|
|
1925
2144
|
}
|
|
1926
2145
|
case "targets": {
|
|
1927
|
-
return /* @__PURE__ */
|
|
2146
|
+
return /* @__PURE__ */ jsx15(
|
|
1928
2147
|
TargetSelect,
|
|
1929
2148
|
{
|
|
1930
2149
|
availableTargets: selectedApp?.targets ?? [],
|
|
@@ -1934,29 +2153,34 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1934
2153
|
);
|
|
1935
2154
|
}
|
|
1936
2155
|
case "settings": {
|
|
1937
|
-
return /* @__PURE__ */
|
|
2156
|
+
return /* @__PURE__ */ jsx15(
|
|
1938
2157
|
SettingsPrompt,
|
|
1939
2158
|
{
|
|
1940
|
-
defaultDir: join3(process.cwd(),
|
|
2159
|
+
defaultDir: join3(process.cwd(), toKebabCase(extensionId || name)),
|
|
1941
2160
|
onSubmit: handleSettings,
|
|
1942
2161
|
onBack: goBack
|
|
1943
2162
|
}
|
|
1944
2163
|
);
|
|
1945
2164
|
}
|
|
1946
2165
|
case "confirm": {
|
|
1947
|
-
return /* @__PURE__ */
|
|
2166
|
+
return /* @__PURE__ */ jsx15(
|
|
1948
2167
|
Confirm,
|
|
1949
2168
|
{
|
|
1950
2169
|
command,
|
|
1951
2170
|
name,
|
|
1952
2171
|
templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0,
|
|
1953
2172
|
targets,
|
|
2173
|
+
registryTargets: command === "update" /* UPDATE */ ? registryManifest?.targets : void 0,
|
|
1954
2174
|
outputDir,
|
|
1955
2175
|
previewPort,
|
|
1956
2176
|
extensionPort,
|
|
1957
2177
|
extensionVersion: command !== "create" /* CREATE */ ? extensionVersion : void 0,
|
|
1958
2178
|
bundleUrl: command === "update" /* UPDATE */ ? bundleUrl : void 0,
|
|
1959
2179
|
enabled: command === "update" /* UPDATE */ ? enabled : void 0,
|
|
2180
|
+
permissions: command === "update" /* UPDATE */ ? confirmedPermissions : void 0,
|
|
2181
|
+
allowedDomains: command === "update" /* UPDATE */ ? confirmedAllowedDomains : void 0,
|
|
2182
|
+
registryPermissions: command === "update" /* UPDATE */ ? registryManifest?.permissions : void 0,
|
|
2183
|
+
registryAllowedDomains: command === "update" /* UPDATE */ ? registryManifest?.allowedDomains : void 0,
|
|
1960
2184
|
newVersion: command === "update" /* UPDATE */ ? options?.setVersion ?? versionOverride ?? computeVersionBump(extensionVersion, name, targets, bundleUrl, forceMajor) : void 0,
|
|
1961
2185
|
onVersionOverride: command === "update" /* UPDATE */ ? setVersionOverride : void 0,
|
|
1962
2186
|
onConfirm: handleConfirm,
|
|
@@ -1966,10 +2190,10 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1966
2190
|
);
|
|
1967
2191
|
}
|
|
1968
2192
|
case "scaffolding": {
|
|
1969
|
-
return /* @__PURE__ */
|
|
2193
|
+
return /* @__PURE__ */ jsx15(ScaffoldProgress, { steps: progressSteps });
|
|
1970
2194
|
}
|
|
1971
2195
|
case "updateSettings": {
|
|
1972
|
-
return /* @__PURE__ */
|
|
2196
|
+
return /* @__PURE__ */ jsx15(
|
|
1973
2197
|
UpdateSettingsPrompt,
|
|
1974
2198
|
{
|
|
1975
2199
|
name,
|
|
@@ -1984,6 +2208,21 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1984
2208
|
setEnabled(updated.enabled);
|
|
1985
2209
|
setForceMajor(updated.forceMajor);
|
|
1986
2210
|
setVersionOverride(void 0);
|
|
2211
|
+
setStep("manifestReview");
|
|
2212
|
+
},
|
|
2213
|
+
onBack: goBack
|
|
2214
|
+
}
|
|
2215
|
+
);
|
|
2216
|
+
}
|
|
2217
|
+
case "manifestReview": {
|
|
2218
|
+
return /* @__PURE__ */ jsx15(
|
|
2219
|
+
ManifestReviewPrompt,
|
|
2220
|
+
{
|
|
2221
|
+
localManifest,
|
|
2222
|
+
registryManifest,
|
|
2223
|
+
onSubmit: (result) => {
|
|
2224
|
+
setConfirmedPermissions(result.permissions);
|
|
2225
|
+
setConfirmedAllowedDomains(result.allowedDomains);
|
|
1987
2226
|
setStep("confirm");
|
|
1988
2227
|
},
|
|
1989
2228
|
onBack: goBack
|
|
@@ -1991,46 +2230,46 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1991
2230
|
);
|
|
1992
2231
|
}
|
|
1993
2232
|
case "updating": {
|
|
1994
|
-
return /* @__PURE__ */
|
|
2233
|
+
return /* @__PURE__ */ jsx15(ScaffoldProgress, { steps: progressSteps });
|
|
1995
2234
|
}
|
|
1996
2235
|
case "updateDone": {
|
|
1997
|
-
return /* @__PURE__ */
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
/* @__PURE__ */
|
|
2236
|
+
return /* @__PURE__ */ jsx15(StepShell, { title: "Extension updated", onBack: goBack, children: /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
|
|
2237
|
+
/* @__PURE__ */ jsx15(Text15, { color: "green", bold: true, children: "Extension updated successfully!" }),
|
|
2238
|
+
/* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
2000
2239
|
"Name: ",
|
|
2001
2240
|
name
|
|
2002
2241
|
] }),
|
|
2003
|
-
/* @__PURE__ */
|
|
2242
|
+
/* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
2004
2243
|
"ID: ",
|
|
2005
2244
|
extensionId
|
|
2006
2245
|
] }),
|
|
2007
|
-
/* @__PURE__ */
|
|
2246
|
+
/* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
2008
2247
|
"Version: ",
|
|
2009
2248
|
extensionVersion
|
|
2010
2249
|
] })
|
|
2011
2250
|
] }) });
|
|
2012
2251
|
}
|
|
2013
2252
|
case "done": {
|
|
2014
|
-
return /* @__PURE__ */
|
|
2253
|
+
return /* @__PURE__ */ jsx15(Done, { name, outputDir, templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0 });
|
|
2015
2254
|
}
|
|
2016
2255
|
case "error": {
|
|
2017
|
-
return /* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
errorMessage && /* @__PURE__ */
|
|
2256
|
+
return /* @__PURE__ */ jsx15(StepShell, { title: "Operation failed", onBack: goBack, children: /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
|
|
2257
|
+
/* @__PURE__ */ jsx15(Text15, { color: "red", bold: true, children: "An error occurred" }),
|
|
2258
|
+
errorMessage && /* @__PURE__ */ jsx15(Text15, { color: "red", children: errorMessage })
|
|
2020
2259
|
] }) });
|
|
2021
2260
|
}
|
|
2022
2261
|
default: {
|
|
2023
|
-
return /* @__PURE__ */
|
|
2024
|
-
/* @__PURE__ */
|
|
2025
|
-
errorMessage && /* @__PURE__ */
|
|
2262
|
+
return /* @__PURE__ */ jsx15(StepShell, { title: "Scaffold failed", onBack: goBack, children: /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
|
|
2263
|
+
/* @__PURE__ */ jsx15(Text15, { color: "red", bold: true, children: "An error occurred" }),
|
|
2264
|
+
errorMessage && /* @__PURE__ */ jsx15(Text15, { color: "red", children: errorMessage })
|
|
2026
2265
|
] }) });
|
|
2027
2266
|
}
|
|
2028
2267
|
}
|
|
2029
2268
|
};
|
|
2030
2269
|
|
|
2031
2270
|
// src/components/DevApp.tsx
|
|
2032
|
-
import { useRef, useState as
|
|
2033
|
-
import { useInput as
|
|
2271
|
+
import { useRef, useState as useState12, useEffect as useEffect6, useCallback as useCallback2 } from "react";
|
|
2272
|
+
import { useInput as useInput11, Box as Box18, Text as Text18 } from "ink";
|
|
2034
2273
|
|
|
2035
2274
|
// src/lib/tunnel.ts
|
|
2036
2275
|
import { Tunnel } from "cloudflared";
|
|
@@ -2064,12 +2303,12 @@ var startDevServer = (projectRoot) => {
|
|
|
2064
2303
|
};
|
|
2065
2304
|
|
|
2066
2305
|
// src/components/DevSetup.tsx
|
|
2067
|
-
import { Box as
|
|
2068
|
-
import { useState as
|
|
2069
|
-
import { jsx as
|
|
2306
|
+
import { Box as Box16, Text as Text16 } from "ink";
|
|
2307
|
+
import { useState as useState11, useEffect as useEffect4 } from "react";
|
|
2308
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2070
2309
|
var DevSetup = ({ initialContext, token, onReady }) => {
|
|
2071
|
-
const [step, setStep] =
|
|
2072
|
-
const [selectedApp, setSelectedApp] =
|
|
2310
|
+
const [step, setStep] = useState11("app");
|
|
2311
|
+
const [selectedApp, setSelectedApp] = useState11(null);
|
|
2073
2312
|
useEffect4(() => {
|
|
2074
2313
|
if (initialContext.appId) {
|
|
2075
2314
|
setStep("extension");
|
|
@@ -2087,9 +2326,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2087
2326
|
});
|
|
2088
2327
|
};
|
|
2089
2328
|
if (step === "app") {
|
|
2090
|
-
return /* @__PURE__ */
|
|
2091
|
-
/* @__PURE__ */
|
|
2092
|
-
/* @__PURE__ */
|
|
2329
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
2330
|
+
/* @__PURE__ */ jsx16(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text16, { children: "Select the App for your extension:" }) }),
|
|
2331
|
+
/* @__PURE__ */ jsx16(
|
|
2093
2332
|
AppSelect,
|
|
2094
2333
|
{
|
|
2095
2334
|
token,
|
|
@@ -2098,9 +2337,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2098
2337
|
)
|
|
2099
2338
|
] });
|
|
2100
2339
|
}
|
|
2101
|
-
return /* @__PURE__ */
|
|
2102
|
-
/* @__PURE__ */
|
|
2103
|
-
/* @__PURE__ */
|
|
2340
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
2341
|
+
/* @__PURE__ */ jsx16(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text16, { children: "Select the Extension to develop:" }) }),
|
|
2342
|
+
/* @__PURE__ */ jsx16(
|
|
2104
2343
|
ExtensionSelect,
|
|
2105
2344
|
{
|
|
2106
2345
|
token,
|
|
@@ -2112,9 +2351,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2112
2351
|
};
|
|
2113
2352
|
|
|
2114
2353
|
// src/components/DevDashboard.tsx
|
|
2115
|
-
import { Box as
|
|
2354
|
+
import { Box as Box17, Text as Text17, useInput as useInput10 } from "ink";
|
|
2116
2355
|
import { useEffect as useEffect5 } from "react";
|
|
2117
|
-
import { jsx as
|
|
2356
|
+
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2118
2357
|
var DevDashboard = ({
|
|
2119
2358
|
previewTunnelUrl,
|
|
2120
2359
|
tunnelUrl,
|
|
@@ -2126,6 +2365,7 @@ var DevDashboard = ({
|
|
|
2126
2365
|
extensionName,
|
|
2127
2366
|
extensionPort,
|
|
2128
2367
|
previewPort,
|
|
2368
|
+
manifestWarnings = [],
|
|
2129
2369
|
onQuit
|
|
2130
2370
|
}) => {
|
|
2131
2371
|
useEffect5(() => {
|
|
@@ -2137,72 +2377,80 @@ var DevDashboard = ({
|
|
|
2137
2377
|
process.off("SIGINT", handler);
|
|
2138
2378
|
};
|
|
2139
2379
|
}, [onQuit]);
|
|
2140
|
-
|
|
2380
|
+
useInput10((input, key) => {
|
|
2141
2381
|
if (input === "q" || key.ctrl && input === "c") {
|
|
2142
2382
|
onQuit();
|
|
2143
2383
|
}
|
|
2144
2384
|
});
|
|
2145
|
-
return /* @__PURE__ */
|
|
2146
|
-
/* @__PURE__ */
|
|
2147
|
-
/* @__PURE__ */
|
|
2385
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
2386
|
+
/* @__PURE__ */ jsx17(Banner, { userId, orgId }),
|
|
2387
|
+
/* @__PURE__ */ jsxs17(
|
|
2148
2388
|
StepShell,
|
|
2149
2389
|
{
|
|
2150
2390
|
title: "dev",
|
|
2151
2391
|
hint: `Live development ${tunnelUrl ? "with" : "w/o"} Tunnel`,
|
|
2152
|
-
footer: /* @__PURE__ */
|
|
2392
|
+
footer: /* @__PURE__ */ jsx17(Box17, { flexDirection: "column", gap: 1, children: /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Press q or Ctrl-C to quit" }) }),
|
|
2153
2393
|
children: [
|
|
2154
|
-
/* @__PURE__ */
|
|
2155
|
-
/* @__PURE__ */
|
|
2156
|
-
/* @__PURE__ */
|
|
2157
|
-
/* @__PURE__ */
|
|
2394
|
+
/* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
2395
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2396
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Extension:" }),
|
|
2397
|
+
/* @__PURE__ */ jsxs17(Text17, { children: [
|
|
2158
2398
|
extensionName,
|
|
2159
2399
|
" (",
|
|
2160
2400
|
extensionId,
|
|
2161
2401
|
")"
|
|
2162
2402
|
] })
|
|
2163
2403
|
] }),
|
|
2164
|
-
/* @__PURE__ */
|
|
2165
|
-
/* @__PURE__ */
|
|
2166
|
-
/* @__PURE__ */
|
|
2404
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2405
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "App:" }),
|
|
2406
|
+
/* @__PURE__ */ jsx17(Text17, { children: `${appName ? `${appName} ` : ""}(${appId})` })
|
|
2167
2407
|
] }),
|
|
2168
|
-
/* @__PURE__ */
|
|
2169
|
-
/* @__PURE__ */
|
|
2170
|
-
/* @__PURE__ */
|
|
2408
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2409
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Bundle URL:" }),
|
|
2410
|
+
/* @__PURE__ */ jsx17(Text17, { children: tunnelUrl || `http://localhost:${extensionPort}` })
|
|
2171
2411
|
] })
|
|
2172
2412
|
] }),
|
|
2173
|
-
/* @__PURE__ */
|
|
2174
|
-
previewTunnelUrl && /* @__PURE__ */
|
|
2175
|
-
/* @__PURE__ */
|
|
2176
|
-
/* @__PURE__ */
|
|
2413
|
+
/* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
2414
|
+
previewTunnelUrl && /* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2415
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Tunnel Dev - Preview:" }),
|
|
2416
|
+
/* @__PURE__ */ jsx17(Text17, { children: previewTunnelUrl })
|
|
2177
2417
|
] }),
|
|
2178
|
-
/* @__PURE__ */
|
|
2179
|
-
/* @__PURE__ */
|
|
2180
|
-
/* @__PURE__ */
|
|
2418
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2419
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Local Dev - Preview:" }),
|
|
2420
|
+
/* @__PURE__ */ jsxs17(Text17, { children: [
|
|
2181
2421
|
"http://localhost:",
|
|
2182
2422
|
previewPort
|
|
2183
2423
|
] })
|
|
2184
2424
|
] })
|
|
2185
2425
|
] }),
|
|
2186
|
-
/* @__PURE__ */
|
|
2187
|
-
tunnelUrl && /* @__PURE__ */
|
|
2188
|
-
/* @__PURE__ */
|
|
2189
|
-
/* @__PURE__ */
|
|
2426
|
+
/* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
2427
|
+
tunnelUrl && /* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2428
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Tunnel Dev - Extension:" }),
|
|
2429
|
+
/* @__PURE__ */ jsx17(Text17, { children: tunnelUrl })
|
|
2190
2430
|
] }),
|
|
2191
|
-
/* @__PURE__ */
|
|
2192
|
-
/* @__PURE__ */
|
|
2193
|
-
/* @__PURE__ */
|
|
2431
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2432
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Local Dev - Extension:" }),
|
|
2433
|
+
/* @__PURE__ */ jsxs17(Text17, { children: [
|
|
2194
2434
|
"http://localhost:",
|
|
2195
2435
|
extensionPort
|
|
2196
2436
|
] })
|
|
2197
2437
|
] })
|
|
2198
2438
|
] }),
|
|
2199
|
-
/* @__PURE__ */
|
|
2200
|
-
/* @__PURE__ */
|
|
2201
|
-
/* @__PURE__ */
|
|
2439
|
+
/* @__PURE__ */ jsx17(Box17, { flexDirection: "column", children: tunnelUrl && /* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2440
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Host Dev - Query Param:" }),
|
|
2441
|
+
/* @__PURE__ */ jsxs17(Text17, { children: [
|
|
2202
2442
|
"?_stackable_dev=",
|
|
2203
2443
|
encodeURIComponent(`${extensionId}:${tunnelUrl}`)
|
|
2204
2444
|
] })
|
|
2205
|
-
] }) })
|
|
2445
|
+
] }) }),
|
|
2446
|
+
manifestWarnings.length > 0 && /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
2447
|
+
/* @__PURE__ */ jsx17(Text17, { color: "yellow", bold: true, children: "Local manifest differs from registry:" }),
|
|
2448
|
+
manifestWarnings.map((w, i) => /* @__PURE__ */ jsxs17(Text17, { color: "yellow", children: [
|
|
2449
|
+
" ",
|
|
2450
|
+
w
|
|
2451
|
+
] }, i)),
|
|
2452
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: " Run `stackable-app-extension update` to review and sync." })
|
|
2453
|
+
] })
|
|
2206
2454
|
]
|
|
2207
2455
|
}
|
|
2208
2456
|
)
|
|
@@ -2210,16 +2458,17 @@ var DevDashboard = ({
|
|
|
2210
2458
|
};
|
|
2211
2459
|
|
|
2212
2460
|
// src/components/DevApp.tsx
|
|
2213
|
-
import { jsx as
|
|
2461
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2214
2462
|
var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
2215
|
-
const [state, setState] =
|
|
2216
|
-
const [devContext, setDevContext] =
|
|
2217
|
-
const [resolvedContext, setResolvedContext] =
|
|
2218
|
-
const [tunnelUrl, setTunnelUrl] =
|
|
2219
|
-
const [previewTunnelUrl, setPreviewTunnelUrl] =
|
|
2220
|
-
const [tunnelHandle, setTunnelHandle] =
|
|
2221
|
-
const [previewTunnelHandle, setPreviewTunnelHandle] =
|
|
2222
|
-
const [devServerHandle, setDevServerHandle] =
|
|
2463
|
+
const [state, setState] = useState12("setup");
|
|
2464
|
+
const [devContext, setDevContext] = useState12(null);
|
|
2465
|
+
const [resolvedContext, setResolvedContext] = useState12(null);
|
|
2466
|
+
const [tunnelUrl, setTunnelUrl] = useState12(null);
|
|
2467
|
+
const [previewTunnelUrl, setPreviewTunnelUrl] = useState12(null);
|
|
2468
|
+
const [tunnelHandle, setTunnelHandle] = useState12(null);
|
|
2469
|
+
const [previewTunnelHandle, setPreviewTunnelHandle] = useState12(null);
|
|
2470
|
+
const [devServerHandle, setDevServerHandle] = useState12(null);
|
|
2471
|
+
const [manifestWarnings, setManifestWarnings] = useState12([]);
|
|
2223
2472
|
const shuttingDown = useRef(false);
|
|
2224
2473
|
const useTunnel = options.tunnel !== false;
|
|
2225
2474
|
useEffect6(() => {
|
|
@@ -2240,6 +2489,31 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2240
2489
|
extensionId: resolved.extensionId,
|
|
2241
2490
|
appName: resolved.appName || null
|
|
2242
2491
|
});
|
|
2492
|
+
if (devContext.manifest) {
|
|
2493
|
+
try {
|
|
2494
|
+
const extensions = await fetchExtensions(token, resolved.appId);
|
|
2495
|
+
const registryExt = extensions[resolved.extensionId];
|
|
2496
|
+
if (registryExt) {
|
|
2497
|
+
const localPerms = new Set(devContext.manifest.permissions);
|
|
2498
|
+
const registryPerms = new Set(registryExt.manifest.permissions);
|
|
2499
|
+
const missingPerms = [...localPerms].filter((p) => !registryPerms.has(p));
|
|
2500
|
+
const extraPerms = [...registryPerms].filter((p) => !localPerms.has(p));
|
|
2501
|
+
const localDomains = new Set(devContext.manifest.allowedDomains);
|
|
2502
|
+
const registryDomains = new Set(registryExt.manifest.allowedDomains);
|
|
2503
|
+
const missingDomains = [...localDomains].filter((d) => !registryDomains.has(d));
|
|
2504
|
+
const extraDomains = [...registryDomains].filter((d) => !localDomains.has(d));
|
|
2505
|
+
const warnings = [];
|
|
2506
|
+
if (missingPerms.length > 0) warnings.push(`Permissions in local but not registry: ${missingPerms.join(", ")}`);
|
|
2507
|
+
if (extraPerms.length > 0) warnings.push(`Permissions in registry but not local: ${extraPerms.join(", ")}`);
|
|
2508
|
+
if (missingDomains.length > 0) warnings.push(`Domains in local but not registry: ${missingDomains.join(", ")}`);
|
|
2509
|
+
if (extraDomains.length > 0) warnings.push(`Domains in registry but not local: ${extraDomains.join(", ")}`);
|
|
2510
|
+
if (warnings.length > 0) {
|
|
2511
|
+
setManifestWarnings(warnings);
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
} catch {
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2243
2517
|
const extensionPort = options.extensionPort ? parseInt(options.extensionPort, 10) : devContext.extensionPort;
|
|
2244
2518
|
const previewPort = options.previewPort ? parseInt(options.previewPort, 10) : devContext.previewPort;
|
|
2245
2519
|
await patchViteAllowedHosts(devContext.projectRoot);
|
|
@@ -2268,7 +2542,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2268
2542
|
setDevServerHandle(serverHandle);
|
|
2269
2543
|
console.log("[dev] Ready");
|
|
2270
2544
|
setState("running");
|
|
2271
|
-
}, [devContext, options.extensionPort, options.previewPort, useTunnel]);
|
|
2545
|
+
}, [devContext, token, options.extensionPort, options.previewPort, useTunnel]);
|
|
2272
2546
|
useEffect6(() => {
|
|
2273
2547
|
if (state === "setup" && devContext && devContext.appId && devContext.extensionId) {
|
|
2274
2548
|
handleSetupReady({
|
|
@@ -2304,7 +2578,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2304
2578
|
console.log("[dev] Done");
|
|
2305
2579
|
process.exit(0);
|
|
2306
2580
|
};
|
|
2307
|
-
|
|
2581
|
+
useInput11((input, key) => {
|
|
2308
2582
|
if (input === "c" && key.ctrl) {
|
|
2309
2583
|
if (state === "running") {
|
|
2310
2584
|
handleQuit();
|
|
@@ -2315,7 +2589,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2315
2589
|
});
|
|
2316
2590
|
if (state === "setup" && devContext) {
|
|
2317
2591
|
if (!devContext.appId || !devContext.extensionId) {
|
|
2318
|
-
return /* @__PURE__ */
|
|
2592
|
+
return /* @__PURE__ */ jsx18(
|
|
2319
2593
|
DevSetup,
|
|
2320
2594
|
{
|
|
2321
2595
|
token,
|
|
@@ -2327,7 +2601,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2327
2601
|
return null;
|
|
2328
2602
|
}
|
|
2329
2603
|
if (state === "running" && devContext && resolvedContext) {
|
|
2330
|
-
return /* @__PURE__ */
|
|
2604
|
+
return /* @__PURE__ */ jsx18(
|
|
2331
2605
|
DevDashboard,
|
|
2332
2606
|
{
|
|
2333
2607
|
previewTunnelUrl,
|
|
@@ -2340,6 +2614,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2340
2614
|
extensionId: resolvedContext.extensionId,
|
|
2341
2615
|
extensionPort: options.extensionPort ? parseInt(options.extensionPort, 10) : devContext.extensionPort,
|
|
2342
2616
|
previewPort: options.previewPort ? parseInt(options.previewPort, 10) : devContext.previewPort,
|
|
2617
|
+
manifestWarnings,
|
|
2343
2618
|
onQuit: handleQuit
|
|
2344
2619
|
}
|
|
2345
2620
|
);
|
|
@@ -2347,13 +2622,13 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2347
2622
|
if (state === "stopping") {
|
|
2348
2623
|
return null;
|
|
2349
2624
|
}
|
|
2350
|
-
return /* @__PURE__ */
|
|
2625
|
+
return /* @__PURE__ */ jsx18(Box18, { children: /* @__PURE__ */ jsx18(Text18, { children: "Loading..." }) });
|
|
2351
2626
|
};
|
|
2352
2627
|
|
|
2353
2628
|
// src/components/AIScaffold.tsx
|
|
2354
|
-
import { Box as
|
|
2629
|
+
import { Box as Box19, Text as Text19, useApp as useApp2 } from "ink";
|
|
2355
2630
|
import Spinner4 from "ink-spinner";
|
|
2356
|
-
import { useState as
|
|
2631
|
+
import { useState as useState13, useEffect as useEffect7 } from "react";
|
|
2357
2632
|
|
|
2358
2633
|
// src/lib/aiDocs.ts
|
|
2359
2634
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -2406,12 +2681,12 @@ var downloadAndExtractAiDocs = async (targetDir, version2) => {
|
|
|
2406
2681
|
};
|
|
2407
2682
|
|
|
2408
2683
|
// src/components/AIScaffold.tsx
|
|
2409
|
-
import { jsx as
|
|
2684
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2410
2685
|
var AIScaffold = ({ version: version2 }) => {
|
|
2411
2686
|
const { exit } = useApp2();
|
|
2412
|
-
const [state, setState] =
|
|
2413
|
-
const [files, setFiles] =
|
|
2414
|
-
const [errorMessage, setErrorMessage] =
|
|
2687
|
+
const [state, setState] = useState13("validating");
|
|
2688
|
+
const [files, setFiles] = useState13([]);
|
|
2689
|
+
const [errorMessage, setErrorMessage] = useState13("");
|
|
2415
2690
|
useEffect7(() => {
|
|
2416
2691
|
const run = async () => {
|
|
2417
2692
|
const projectDir = process.cwd();
|
|
@@ -2435,35 +2710,35 @@ var AIScaffold = ({ version: version2 }) => {
|
|
|
2435
2710
|
};
|
|
2436
2711
|
run();
|
|
2437
2712
|
}, []);
|
|
2438
|
-
return /* @__PURE__ */
|
|
2439
|
-
/* @__PURE__ */
|
|
2440
|
-
/* @__PURE__ */
|
|
2441
|
-
state === "validating" && /* @__PURE__ */
|
|
2442
|
-
/* @__PURE__ */
|
|
2443
|
-
/* @__PURE__ */
|
|
2713
|
+
return /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", children: [
|
|
2714
|
+
/* @__PURE__ */ jsx19(Banner, {}),
|
|
2715
|
+
/* @__PURE__ */ jsxs18(StepShell, { title: "AI Editor Config", children: [
|
|
2716
|
+
state === "validating" && /* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2717
|
+
/* @__PURE__ */ jsx19(Text19, { color: "cyan", children: /* @__PURE__ */ jsx19(Spinner4, { type: "dots" }) }),
|
|
2718
|
+
/* @__PURE__ */ jsx19(Text19, { children: "Checking project..." })
|
|
2444
2719
|
] }),
|
|
2445
|
-
state === "downloading" && /* @__PURE__ */
|
|
2446
|
-
/* @__PURE__ */
|
|
2447
|
-
/* @__PURE__ */
|
|
2720
|
+
state === "downloading" && /* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2721
|
+
/* @__PURE__ */ jsx19(Text19, { color: "cyan", children: /* @__PURE__ */ jsx19(Spinner4, { type: "dots" }) }),
|
|
2722
|
+
/* @__PURE__ */ jsxs18(Text19, { children: [
|
|
2448
2723
|
"Downloading AI editor configs (",
|
|
2449
2724
|
version2,
|
|
2450
2725
|
")..."
|
|
2451
2726
|
] })
|
|
2452
2727
|
] }),
|
|
2453
|
-
state === "done" && /* @__PURE__ */
|
|
2454
|
-
/* @__PURE__ */
|
|
2455
|
-
/* @__PURE__ */
|
|
2456
|
-
/* @__PURE__ */
|
|
2728
|
+
state === "done" && /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", gap: 1, children: [
|
|
2729
|
+
/* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2730
|
+
/* @__PURE__ */ jsx19(Text19, { color: "green", bold: true, children: "\u2714" }),
|
|
2731
|
+
/* @__PURE__ */ jsxs18(Text19, { bold: true, children: [
|
|
2457
2732
|
"AI editor configs installed (",
|
|
2458
2733
|
files.length,
|
|
2459
2734
|
" files)"
|
|
2460
2735
|
] })
|
|
2461
2736
|
] }),
|
|
2462
|
-
/* @__PURE__ */
|
|
2737
|
+
/* @__PURE__ */ jsx19(Box19, { flexDirection: "column", marginLeft: 2, children: files.map((f) => /* @__PURE__ */ jsx19(Text19, { dimColor: true, children: f }, f)) })
|
|
2463
2738
|
] }),
|
|
2464
|
-
state === "error" && /* @__PURE__ */
|
|
2465
|
-
/* @__PURE__ */
|
|
2466
|
-
/* @__PURE__ */
|
|
2739
|
+
state === "error" && /* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2740
|
+
/* @__PURE__ */ jsx19(Text19, { color: "red", children: "\u2716" }),
|
|
2741
|
+
/* @__PURE__ */ jsx19(Text19, { children: errorMessage })
|
|
2467
2742
|
] })
|
|
2468
2743
|
] })
|
|
2469
2744
|
] });
|
|
@@ -2471,20 +2746,20 @@ var AIScaffold = ({ version: version2 }) => {
|
|
|
2471
2746
|
|
|
2472
2747
|
// src/components/AuthLogin.tsx
|
|
2473
2748
|
import { createServer } from "http";
|
|
2474
|
-
import { Box as
|
|
2749
|
+
import { Box as Box20, Text as Text20, useApp as useApp3 } from "ink";
|
|
2475
2750
|
import Spinner5 from "ink-spinner";
|
|
2476
2751
|
import open from "open";
|
|
2477
|
-
import { useState as
|
|
2752
|
+
import { useState as useState14, useEffect as useEffect8 } from "react";
|
|
2478
2753
|
|
|
2479
2754
|
// src/lib/auth.ts
|
|
2480
|
-
import { readFile as
|
|
2755
|
+
import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir2, unlink } from "fs/promises";
|
|
2481
2756
|
import { join as join5 } from "path";
|
|
2482
2757
|
import { homedir } from "os";
|
|
2483
2758
|
var AUTH_DIR = join5(homedir(), ".stackable");
|
|
2484
2759
|
var AUTH_FILE = join5(AUTH_DIR, "auth.json");
|
|
2485
2760
|
var readAuthState = async () => {
|
|
2486
2761
|
try {
|
|
2487
|
-
const content = await
|
|
2762
|
+
const content = await readFile4(AUTH_FILE, "utf8");
|
|
2488
2763
|
return JSON.parse(content);
|
|
2489
2764
|
} catch {
|
|
2490
2765
|
return null;
|
|
@@ -2527,7 +2802,7 @@ var getToken = async () => {
|
|
|
2527
2802
|
};
|
|
2528
2803
|
|
|
2529
2804
|
// src/components/AuthLogin.tsx
|
|
2530
|
-
import { jsx as
|
|
2805
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2531
2806
|
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
2532
2807
|
var callbackPage = (heading, sub, redirectUrl) => `<!DOCTYPE html>
|
|
2533
2808
|
<html><head><meta charset="utf-8"><title>Stackable CLI</title>
|
|
@@ -2538,11 +2813,11 @@ ${redirectUrl ? `<script>(function(){var s=3,el=document.getElementById('h');fun
|
|
|
2538
2813
|
</body></html>`;
|
|
2539
2814
|
var AuthLogin = ({ dashboardUrl }) => {
|
|
2540
2815
|
const { exit } = useApp3();
|
|
2541
|
-
const [state, setState] =
|
|
2542
|
-
const [loginUrl, setLoginUrl] =
|
|
2543
|
-
const [userIdLabel, setUserIdLabel] =
|
|
2544
|
-
const [orgIdLabel, setOrgIdLabel] =
|
|
2545
|
-
const [errorMessage, setErrorMessage] =
|
|
2816
|
+
const [state, setState] = useState14("waiting");
|
|
2817
|
+
const [loginUrl, setLoginUrl] = useState14("");
|
|
2818
|
+
const [userIdLabel, setUserIdLabel] = useState14("");
|
|
2819
|
+
const [orgIdLabel, setOrgIdLabel] = useState14("");
|
|
2820
|
+
const [errorMessage, setErrorMessage] = useState14("");
|
|
2546
2821
|
useEffect8(() => {
|
|
2547
2822
|
let server;
|
|
2548
2823
|
let timeout;
|
|
@@ -2618,38 +2893,38 @@ var AuthLogin = ({ dashboardUrl }) => {
|
|
|
2618
2893
|
server?.close();
|
|
2619
2894
|
};
|
|
2620
2895
|
}, []);
|
|
2621
|
-
return /* @__PURE__ */
|
|
2622
|
-
/* @__PURE__ */
|
|
2623
|
-
/* @__PURE__ */
|
|
2624
|
-
state === "waiting" && /* @__PURE__ */
|
|
2625
|
-
/* @__PURE__ */
|
|
2626
|
-
/* @__PURE__ */
|
|
2627
|
-
/* @__PURE__ */
|
|
2896
|
+
return /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", children: [
|
|
2897
|
+
/* @__PURE__ */ jsx20(Banner, {}),
|
|
2898
|
+
/* @__PURE__ */ jsxs19(StepShell, { title: "Authenticate with Stackable", children: [
|
|
2899
|
+
state === "waiting" && /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", gap: 1, children: [
|
|
2900
|
+
/* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2901
|
+
/* @__PURE__ */ jsx20(Text20, { color: "cyan", children: /* @__PURE__ */ jsx20(Spinner5, { type: "dots" }) }),
|
|
2902
|
+
/* @__PURE__ */ jsx20(Text20, { children: "Waiting for browser authentication..." })
|
|
2628
2903
|
] }),
|
|
2629
|
-
loginUrl && /* @__PURE__ */
|
|
2904
|
+
loginUrl && /* @__PURE__ */ jsxs19(Text20, { dimColor: true, children: [
|
|
2630
2905
|
" ",
|
|
2631
2906
|
loginUrl
|
|
2632
2907
|
] })
|
|
2633
2908
|
] }),
|
|
2634
|
-
state === "success" && /* @__PURE__ */
|
|
2635
|
-
/* @__PURE__ */
|
|
2636
|
-
/* @__PURE__ */
|
|
2637
|
-
/* @__PURE__ */
|
|
2638
|
-
/* @__PURE__ */
|
|
2909
|
+
state === "success" && /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", gap: 1, children: [
|
|
2910
|
+
/* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", children: [
|
|
2911
|
+
/* @__PURE__ */ jsxs19(Box20, { gap: 2, children: [
|
|
2912
|
+
/* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "User:" }),
|
|
2913
|
+
/* @__PURE__ */ jsx20(Text20, { color: "cyan", children: userIdLabel })
|
|
2639
2914
|
] }),
|
|
2640
|
-
/* @__PURE__ */
|
|
2641
|
-
/* @__PURE__ */
|
|
2642
|
-
/* @__PURE__ */
|
|
2915
|
+
/* @__PURE__ */ jsxs19(Box20, { gap: 2, children: [
|
|
2916
|
+
/* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "Org: " }),
|
|
2917
|
+
/* @__PURE__ */ jsx20(Text20, { color: "cyan", children: orgIdLabel })
|
|
2643
2918
|
] })
|
|
2644
2919
|
] }),
|
|
2645
|
-
/* @__PURE__ */
|
|
2646
|
-
/* @__PURE__ */
|
|
2647
|
-
/* @__PURE__ */
|
|
2920
|
+
/* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2921
|
+
/* @__PURE__ */ jsx20(Text20, { color: "green", bold: true, children: "\u2714" }),
|
|
2922
|
+
/* @__PURE__ */ jsx20(Text20, { bold: true, children: "Authenticated" })
|
|
2648
2923
|
] })
|
|
2649
2924
|
] }),
|
|
2650
|
-
state === "error" && /* @__PURE__ */
|
|
2651
|
-
/* @__PURE__ */
|
|
2652
|
-
/* @__PURE__ */
|
|
2925
|
+
state === "error" && /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2926
|
+
/* @__PURE__ */ jsx20(Text20, { color: "red", children: "\u2716" }),
|
|
2927
|
+
/* @__PURE__ */ jsx20(Text20, { children: errorMessage })
|
|
2653
2928
|
] })
|
|
2654
2929
|
] })
|
|
2655
2930
|
] });
|
|
@@ -2657,70 +2932,70 @@ var AuthLogin = ({ dashboardUrl }) => {
|
|
|
2657
2932
|
|
|
2658
2933
|
// src/components/AuthLogout.tsx
|
|
2659
2934
|
import { useEffect as useEffect9 } from "react";
|
|
2660
|
-
import { Box as
|
|
2661
|
-
import { jsx as
|
|
2935
|
+
import { Box as Box21, Text as Text21, useApp as useApp4 } from "ink";
|
|
2936
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2662
2937
|
var AuthLogout = () => {
|
|
2663
2938
|
const { exit } = useApp4();
|
|
2664
2939
|
useEffect9(() => {
|
|
2665
2940
|
exit();
|
|
2666
2941
|
}, [exit]);
|
|
2667
|
-
return /* @__PURE__ */
|
|
2668
|
-
/* @__PURE__ */
|
|
2669
|
-
/* @__PURE__ */
|
|
2670
|
-
/* @__PURE__ */
|
|
2671
|
-
/* @__PURE__ */
|
|
2942
|
+
return /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", children: [
|
|
2943
|
+
/* @__PURE__ */ jsx21(Banner, {}),
|
|
2944
|
+
/* @__PURE__ */ jsx21(StepShell, { title: "Authenticate with Stackable", children: /* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
|
|
2945
|
+
/* @__PURE__ */ jsx21(Text21, { color: "green", bold: true, children: "\u2714" }),
|
|
2946
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: "Logged out" })
|
|
2672
2947
|
] }) })
|
|
2673
2948
|
] });
|
|
2674
2949
|
};
|
|
2675
2950
|
|
|
2676
2951
|
// src/components/AuthStatus.tsx
|
|
2677
2952
|
import { useEffect as useEffect10 } from "react";
|
|
2678
|
-
import { useApp as useApp5, Box as
|
|
2679
|
-
import { jsx as
|
|
2953
|
+
import { useApp as useApp5, Box as Box22, Text as Text22 } from "ink";
|
|
2954
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2680
2955
|
var AuthStatus = ({ state, userId, orgId, expiry }) => {
|
|
2681
2956
|
const { exit } = useApp5();
|
|
2682
2957
|
useEffect10(() => {
|
|
2683
2958
|
exit();
|
|
2684
2959
|
}, [exit]);
|
|
2685
|
-
return /* @__PURE__ */
|
|
2686
|
-
/* @__PURE__ */
|
|
2687
|
-
/* @__PURE__ */
|
|
2688
|
-
state === "authenticated" && /* @__PURE__ */
|
|
2689
|
-
/* @__PURE__ */
|
|
2690
|
-
/* @__PURE__ */
|
|
2691
|
-
/* @__PURE__ */
|
|
2692
|
-
/* @__PURE__ */
|
|
2960
|
+
return /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", children: [
|
|
2961
|
+
/* @__PURE__ */ jsx22(Banner, {}),
|
|
2962
|
+
/* @__PURE__ */ jsxs21(StepShell, { title: "Authenticate with Stackable", children: [
|
|
2963
|
+
state === "authenticated" && /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", gap: 1, children: [
|
|
2964
|
+
/* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", children: [
|
|
2965
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 2, children: [
|
|
2966
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "User:" }),
|
|
2967
|
+
/* @__PURE__ */ jsx22(Text22, { color: "cyan", children: userId })
|
|
2693
2968
|
] }),
|
|
2694
|
-
/* @__PURE__ */
|
|
2695
|
-
/* @__PURE__ */
|
|
2696
|
-
/* @__PURE__ */
|
|
2969
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 2, children: [
|
|
2970
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "Org: " }),
|
|
2971
|
+
/* @__PURE__ */ jsx22(Text22, { color: "cyan", children: orgId })
|
|
2697
2972
|
] }),
|
|
2698
|
-
expiry && /* @__PURE__ */
|
|
2699
|
-
/* @__PURE__ */
|
|
2700
|
-
/* @__PURE__ */
|
|
2973
|
+
expiry && /* @__PURE__ */ jsxs21(Box22, { gap: 2, children: [
|
|
2974
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "Exp: " }),
|
|
2975
|
+
/* @__PURE__ */ jsx22(Text22, { color: "cyan", children: expiry.toLocaleDateString() })
|
|
2701
2976
|
] })
|
|
2702
2977
|
] }),
|
|
2703
|
-
/* @__PURE__ */
|
|
2704
|
-
/* @__PURE__ */
|
|
2705
|
-
/* @__PURE__ */
|
|
2978
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 1, children: [
|
|
2979
|
+
/* @__PURE__ */ jsx22(Text22, { color: "green", bold: true, children: "\u2714" }),
|
|
2980
|
+
/* @__PURE__ */ jsx22(Text22, { bold: true, children: "Authenticated" })
|
|
2706
2981
|
] })
|
|
2707
2982
|
] }),
|
|
2708
|
-
state === "expired" && /* @__PURE__ */
|
|
2709
|
-
/* @__PURE__ */
|
|
2710
|
-
/* @__PURE__ */
|
|
2711
|
-
/* @__PURE__ */
|
|
2983
|
+
state === "expired" && /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", gap: 1, children: [
|
|
2984
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 1, children: [
|
|
2985
|
+
/* @__PURE__ */ jsx22(Text22, { color: "red", children: "\u2716" }),
|
|
2986
|
+
/* @__PURE__ */ jsxs21(Text22, { children: [
|
|
2712
2987
|
"Session expired",
|
|
2713
2988
|
expiry ? ` (${expiry.toLocaleDateString()})` : ""
|
|
2714
2989
|
] })
|
|
2715
2990
|
] }),
|
|
2716
|
-
/* @__PURE__ */
|
|
2991
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "Run `stackable-app-extension auth login` to re-authenticate." })
|
|
2717
2992
|
] }),
|
|
2718
|
-
state === "not-logged-in" && /* @__PURE__ */
|
|
2719
|
-
/* @__PURE__ */
|
|
2720
|
-
/* @__PURE__ */
|
|
2721
|
-
/* @__PURE__ */
|
|
2993
|
+
state === "not-logged-in" && /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", gap: 1, children: [
|
|
2994
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 1, children: [
|
|
2995
|
+
/* @__PURE__ */ jsx22(Text22, { color: "red", children: "\u2716" }),
|
|
2996
|
+
/* @__PURE__ */ jsx22(Text22, { children: "Not logged in" })
|
|
2722
2997
|
] }),
|
|
2723
|
-
/* @__PURE__ */
|
|
2998
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "Run `stackable-app-extension auth login`" })
|
|
2724
2999
|
] })
|
|
2725
3000
|
] })
|
|
2726
3001
|
] });
|
|
@@ -2774,7 +3049,7 @@ var checkForUpdate = (currentVersion) => {
|
|
|
2774
3049
|
};
|
|
2775
3050
|
|
|
2776
3051
|
// src/index.tsx
|
|
2777
|
-
import { jsx as
|
|
3052
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2778
3053
|
var require2 = createRequire(import.meta.url);
|
|
2779
3054
|
var { version } = require2("../package.json");
|
|
2780
3055
|
checkForUpdate(version);
|
|
@@ -2787,7 +3062,7 @@ var ensureToken = async () => {
|
|
|
2787
3062
|
const message = err instanceof Error ? err.message : String(err);
|
|
2788
3063
|
const isExpired = message.toLowerCase().includes("expired");
|
|
2789
3064
|
render(
|
|
2790
|
-
/* @__PURE__ */
|
|
3065
|
+
/* @__PURE__ */ jsx23(AuthStatus, { state: isExpired ? "expired" : "not-logged-in" })
|
|
2791
3066
|
);
|
|
2792
3067
|
return null;
|
|
2793
3068
|
}
|
|
@@ -2800,7 +3075,7 @@ program.command("create" /* CREATE */).description("Create a new Extension proje
|
|
|
2800
3075
|
}
|
|
2801
3076
|
const { token, userId, orgId } = auth2;
|
|
2802
3077
|
render(
|
|
2803
|
-
/* @__PURE__ */
|
|
3078
|
+
/* @__PURE__ */ jsx23(
|
|
2804
3079
|
App,
|
|
2805
3080
|
{
|
|
2806
3081
|
command: "create" /* CREATE */,
|
|
@@ -2820,7 +3095,7 @@ program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project
|
|
|
2820
3095
|
}
|
|
2821
3096
|
const { token, userId, orgId } = auth2;
|
|
2822
3097
|
render(
|
|
2823
|
-
/* @__PURE__ */
|
|
3098
|
+
/* @__PURE__ */ jsx23(
|
|
2824
3099
|
App,
|
|
2825
3100
|
{
|
|
2826
3101
|
command: "scaffold" /* SCAFFOLD */,
|
|
@@ -2832,14 +3107,14 @@ program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project
|
|
|
2832
3107
|
)
|
|
2833
3108
|
);
|
|
2834
3109
|
});
|
|
2835
|
-
program.command("update" /* UPDATE */).description("Update an existing Extension").argument("[extensionId]", "Extension ID to update").option("--app-id <id>", "Skip App selection").option("--name <name>", "New Extension name").option("--targets <targets>", "Comma-separated target slots (validated against app)").option("--bundle-url <url>", "New bundle URL").option("--enabled <bool>", "Enable/disable Extension").option("--set-version <version>", "Explicit version (skips auto-compute)").action(async (extensionId, options) => {
|
|
3110
|
+
program.command("update" /* UPDATE */).description("Update an existing Extension").argument("[extensionId]", "Extension ID to update").option("--app-id <id>", "Skip App selection").option("--name <name>", "New Extension name").option("--targets <targets>", "Comma-separated target slots (validated against app)").option("--bundle-url <url>", "New bundle URL").option("--enabled <bool>", "Enable/disable Extension").option("--set-version <version>", "Explicit version (skips auto-compute)").option("--dir <path>", "Project root (default: cwd)").action(async (extensionId, options) => {
|
|
2836
3111
|
const auth2 = await ensureToken();
|
|
2837
3112
|
if (!auth2) {
|
|
2838
3113
|
return;
|
|
2839
3114
|
}
|
|
2840
3115
|
const { token, userId, orgId } = auth2;
|
|
2841
3116
|
render(
|
|
2842
|
-
/* @__PURE__ */
|
|
3117
|
+
/* @__PURE__ */ jsx23(
|
|
2843
3118
|
App,
|
|
2844
3119
|
{
|
|
2845
3120
|
command: "update" /* UPDATE */,
|
|
@@ -2859,7 +3134,7 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
2859
3134
|
}
|
|
2860
3135
|
const { token, userId, orgId } = auth2;
|
|
2861
3136
|
render(
|
|
2862
|
-
/* @__PURE__ */
|
|
3137
|
+
/* @__PURE__ */ jsx23(
|
|
2863
3138
|
DevApp,
|
|
2864
3139
|
{
|
|
2865
3140
|
options,
|
|
@@ -2874,17 +3149,17 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
2874
3149
|
var DASHBOARD_URL = process.env.ADMIN_DASHBOARD_URL ?? "https://admin.stackablelabs.io";
|
|
2875
3150
|
var auth = program.command("auth").description("Manage CLI authentication");
|
|
2876
3151
|
auth.command("login").description("Authenticate with Stackable via browser").action(async () => {
|
|
2877
|
-
render(/* @__PURE__ */
|
|
3152
|
+
render(/* @__PURE__ */ jsx23(AuthLogin, { dashboardUrl: DASHBOARD_URL }));
|
|
2878
3153
|
});
|
|
2879
3154
|
auth.command("logout").description("Clear stored CLI credentials").action(async () => {
|
|
2880
3155
|
await clearAuthState();
|
|
2881
|
-
render(/* @__PURE__ */
|
|
3156
|
+
render(/* @__PURE__ */ jsx23(AuthLogout, {}));
|
|
2882
3157
|
});
|
|
2883
3158
|
auth.command("status").description("Show current authentication status").action(async () => {
|
|
2884
3159
|
const state = await readAuthState();
|
|
2885
3160
|
if (!state) {
|
|
2886
3161
|
render(
|
|
2887
|
-
/* @__PURE__ */
|
|
3162
|
+
/* @__PURE__ */ jsx23(AuthStatus, { state: "not-logged-in" })
|
|
2888
3163
|
);
|
|
2889
3164
|
return;
|
|
2890
3165
|
}
|
|
@@ -2892,11 +3167,11 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
2892
3167
|
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
2893
3168
|
const expiry = payload.exp ? new Date(payload.exp * 1e3) : null;
|
|
2894
3169
|
if (expiry && Date.now() >= expiry.getTime()) {
|
|
2895
|
-
render(/* @__PURE__ */
|
|
3170
|
+
render(/* @__PURE__ */ jsx23(AuthStatus, { state: "expired", expiry }));
|
|
2896
3171
|
return;
|
|
2897
3172
|
}
|
|
2898
3173
|
render(
|
|
2899
|
-
/* @__PURE__ */
|
|
3174
|
+
/* @__PURE__ */ jsx23(
|
|
2900
3175
|
AuthStatus,
|
|
2901
3176
|
{
|
|
2902
3177
|
state: "authenticated",
|
|
@@ -2909,6 +3184,6 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
2909
3184
|
});
|
|
2910
3185
|
var ai = program.command("ai").description("AI editor configuration tools");
|
|
2911
3186
|
ai.command("scaffold").description("Download AI editor config files into your Extension project").option("--version <version>", 'AI docs version (semver or "latest")', "latest").action(async (options) => {
|
|
2912
|
-
render(/* @__PURE__ */
|
|
3187
|
+
render(/* @__PURE__ */ jsx23(AIScaffold, { version: options.version }));
|
|
2913
3188
|
});
|
|
2914
3189
|
program.parse(process.argv.filter((arg) => arg !== "--"));
|