@stackable-labs/cli-app-extension 1.26.4 → 1.27.1
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 +686 -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) {
|
|
@@ -1529,6 +1685,7 @@ var scaffold = async (options) => {
|
|
|
1529
1685
|
const templateSource = TEMPLATE_SOURCES[flavor];
|
|
1530
1686
|
const { dir } = await downloadTemplate(templateSource, {
|
|
1531
1687
|
dir: options.outputDir,
|
|
1688
|
+
forceClean: true,
|
|
1532
1689
|
force: true
|
|
1533
1690
|
});
|
|
1534
1691
|
await replacePlaceholders(dir, {
|
|
@@ -1539,7 +1696,7 @@ var scaffold = async (options) => {
|
|
|
1539
1696
|
});
|
|
1540
1697
|
if (flavor === "starter") {
|
|
1541
1698
|
const selectedTargets = normalizeTargets(options.targets);
|
|
1542
|
-
const derivedPermissions =
|
|
1699
|
+
const derivedPermissions = deriveScaffoldPermissions(selectedTargets);
|
|
1543
1700
|
await generateManifest(dir, options.name, selectedTargets, derivedPermissions);
|
|
1544
1701
|
await generateSurfaceFiles(dir, selectedTargets);
|
|
1545
1702
|
await rewriteExtensionIndex(dir, options.extensionId || options.name, selectedTargets);
|
|
@@ -1557,17 +1714,18 @@ var scaffold = async (options) => {
|
|
|
1557
1714
|
appName: options.appName || null,
|
|
1558
1715
|
extensionName: options.name,
|
|
1559
1716
|
extensionPort: options.extensionPort,
|
|
1560
|
-
previewPort: options.previewPort
|
|
1717
|
+
previewPort: options.previewPort,
|
|
1718
|
+
manifest: null
|
|
1561
1719
|
});
|
|
1562
1720
|
return options;
|
|
1563
1721
|
};
|
|
1564
1722
|
|
|
1565
1723
|
// src/App.tsx
|
|
1566
|
-
import { jsx as
|
|
1724
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1567
1725
|
var STEPS = {
|
|
1568
1726
|
["create" /* CREATE */]: ["app", "name", "template", "targets", "settings", "confirm"],
|
|
1569
1727
|
["scaffold" /* SCAFFOLD */]: ["app", "extensionSelect", "confirmTargets", "settings", "confirm"],
|
|
1570
|
-
["update" /* UPDATE */]: ["app", "extensionSelect", "updateSettings", "confirm"],
|
|
1728
|
+
["update" /* UPDATE */]: ["app", "extensionSelect", "updateSettings", "manifestReview", "confirm"],
|
|
1571
1729
|
["dev" /* DEV */]: []
|
|
1572
1730
|
// Dev command has no wizard steps
|
|
1573
1731
|
};
|
|
@@ -1589,8 +1747,7 @@ var PROGRESS_STEPS = {
|
|
|
1589
1747
|
["dev" /* DEV */]: []
|
|
1590
1748
|
// Dev command has no progress steps
|
|
1591
1749
|
};
|
|
1592
|
-
var
|
|
1593
|
-
var derivePermissions2 = (targets) => {
|
|
1750
|
+
var deriveRegistryPermissions = (targets) => {
|
|
1594
1751
|
const permissions = /* @__PURE__ */ new Set();
|
|
1595
1752
|
for (const target of targets) {
|
|
1596
1753
|
const mapped = TARGET_PERMISSION_MAP[target];
|
|
@@ -1609,33 +1766,37 @@ var derivePermissions2 = (targets) => {
|
|
|
1609
1766
|
};
|
|
1610
1767
|
var App = ({ command, token, userId, orgId, initialName, initialExtensionId, options }) => {
|
|
1611
1768
|
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] =
|
|
1769
|
+
const [step, setStep] = useState10("app");
|
|
1770
|
+
const [name, setName] = useState10(initialName ?? options?.name ?? "");
|
|
1771
|
+
const [extensionId, setExtensionId] = useState10(initialExtensionId ?? "");
|
|
1772
|
+
const [extensionVersion, setExtensionVersion] = useState10("");
|
|
1773
|
+
const [bundleUrl, setBundleUrl] = useState10(options?.bundleUrl ?? "");
|
|
1774
|
+
const [enabled, setEnabled] = useState10(
|
|
1618
1775
|
options?.enabled !== void 0 ? options.enabled !== "false" : true
|
|
1619
1776
|
);
|
|
1620
|
-
const [versionOverride, setVersionOverride] =
|
|
1621
|
-
const [forceMajor, setForceMajor] =
|
|
1622
|
-
const [initialExtension, setInitialExtension] =
|
|
1623
|
-
const [templateFlavor, setTemplateFlavor] =
|
|
1777
|
+
const [versionOverride, setVersionOverride] = useState10(void 0);
|
|
1778
|
+
const [forceMajor, setForceMajor] = useState10(false);
|
|
1779
|
+
const [initialExtension, setInitialExtension] = useState10(null);
|
|
1780
|
+
const [templateFlavor, setTemplateFlavor] = useState10(
|
|
1624
1781
|
options?.template ?? "starter"
|
|
1625
1782
|
);
|
|
1626
|
-
const [targets, setTargets] =
|
|
1783
|
+
const [targets, setTargets] = useState10(
|
|
1627
1784
|
options?.targets ? options.targets.split(",").map((t) => t.trim()) : []
|
|
1628
1785
|
);
|
|
1629
|
-
const [selectedApp, setSelectedApp] =
|
|
1630
|
-
const [extensionPort, setExtensionPort] =
|
|
1786
|
+
const [selectedApp, setSelectedApp] = useState10(null);
|
|
1787
|
+
const [extensionPort, setExtensionPort] = useState10(
|
|
1631
1788
|
options?.extensionPort ? parseInt(options.extensionPort, 10) : 6543
|
|
1632
1789
|
);
|
|
1633
|
-
const [previewPort, setPreviewPort] =
|
|
1790
|
+
const [previewPort, setPreviewPort] = useState10(
|
|
1634
1791
|
options?.previewPort ? parseInt(options.previewPort, 10) : 6544
|
|
1635
1792
|
);
|
|
1636
|
-
const [
|
|
1637
|
-
const [
|
|
1638
|
-
const [
|
|
1793
|
+
const [registryManifest, setRegistryManifest] = useState10(null);
|
|
1794
|
+
const [localManifest, setLocalManifest] = useState10(null);
|
|
1795
|
+
const [confirmedPermissions, setConfirmedPermissions] = useState10([]);
|
|
1796
|
+
const [confirmedAllowedDomains, setConfirmedAllowedDomains] = useState10([]);
|
|
1797
|
+
const [outputDir, setOutputDir] = useState10("");
|
|
1798
|
+
const [progressSteps, setProgressSteps] = useState10(PROGRESS_STEPS[command]);
|
|
1799
|
+
const [errorMessage, setErrorMessage] = useState10();
|
|
1639
1800
|
const updateStep = useCallback((index, status) => {
|
|
1640
1801
|
setProgressSteps((prev) => prev.map((s, i) => i === index ? { ...s, status } : s));
|
|
1641
1802
|
}, []);
|
|
@@ -1670,8 +1831,47 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1670
1831
|
return idx > 0 ? steps[idx - 1] : prev;
|
|
1671
1832
|
});
|
|
1672
1833
|
}, [activeSteps]);
|
|
1673
|
-
const handleAppSelect = (app) => {
|
|
1834
|
+
const handleAppSelect = async (app) => {
|
|
1674
1835
|
setSelectedApp(app);
|
|
1836
|
+
if (command === "update" /* UPDATE */ && initialExtensionId) {
|
|
1837
|
+
try {
|
|
1838
|
+
const extensions = await fetchExtensions(token, app.id);
|
|
1839
|
+
const ext = extensions[initialExtensionId];
|
|
1840
|
+
if (!ext) {
|
|
1841
|
+
setErrorMessage(
|
|
1842
|
+
`Extension "${initialExtensionId}" not found or is disabled. If disabled, re-enable it in the admin dashboard before updating.`
|
|
1843
|
+
);
|
|
1844
|
+
setStep("error");
|
|
1845
|
+
return;
|
|
1846
|
+
}
|
|
1847
|
+
setName(ext.manifest.name);
|
|
1848
|
+
setExtensionId(ext.id);
|
|
1849
|
+
setExtensionVersion(ext.manifest.version);
|
|
1850
|
+
setTargets(ext.manifest.targets);
|
|
1851
|
+
setBundleUrl(ext.bundleUrl);
|
|
1852
|
+
setEnabled(ext.enabled ?? true);
|
|
1853
|
+
setInitialExtension({
|
|
1854
|
+
name: ext.manifest.name,
|
|
1855
|
+
targets: ext.manifest.targets,
|
|
1856
|
+
bundleUrl: ext.bundleUrl
|
|
1857
|
+
});
|
|
1858
|
+
setRegistryManifest(ext.manifest);
|
|
1859
|
+
const projectRoot = options?.dir || process.cwd();
|
|
1860
|
+
try {
|
|
1861
|
+
const manifestPath = join3(projectRoot, "packages/extension/public/manifest.json");
|
|
1862
|
+
const content = await readFile3(manifestPath, "utf8");
|
|
1863
|
+
setLocalManifest(JSON.parse(content));
|
|
1864
|
+
} catch {
|
|
1865
|
+
setLocalManifest(null);
|
|
1866
|
+
}
|
|
1867
|
+
setStep("updateSettings");
|
|
1868
|
+
} catch (err) {
|
|
1869
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1870
|
+
setErrorMessage(message);
|
|
1871
|
+
setStep("error");
|
|
1872
|
+
}
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1675
1875
|
if (command === "scaffold" /* SCAFFOLD */ || command === "update" /* UPDATE */) {
|
|
1676
1876
|
setStep("extensionSelect");
|
|
1677
1877
|
return;
|
|
@@ -1682,7 +1882,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1682
1882
|
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
1683
1883
|
setTargets(meta.defaultTargets);
|
|
1684
1884
|
if (options?.extensionPort || options?.previewPort) {
|
|
1685
|
-
setOutputDir(join3(process.cwd(),
|
|
1885
|
+
setOutputDir(join3(process.cwd(), toKebabCase(initialName)));
|
|
1686
1886
|
setStep("confirm");
|
|
1687
1887
|
} else {
|
|
1688
1888
|
setStep("settings");
|
|
@@ -1697,7 +1897,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1697
1897
|
setStep("name");
|
|
1698
1898
|
}
|
|
1699
1899
|
};
|
|
1700
|
-
const handleExtensionSelect = (ext) => {
|
|
1900
|
+
const handleExtensionSelect = async (ext) => {
|
|
1701
1901
|
setName(ext.manifest.name);
|
|
1702
1902
|
setExtensionId(ext.id);
|
|
1703
1903
|
setExtensionVersion(ext.manifest.version);
|
|
@@ -1709,6 +1909,15 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1709
1909
|
targets: ext.manifest.targets,
|
|
1710
1910
|
bundleUrl: ext.bundleUrl
|
|
1711
1911
|
});
|
|
1912
|
+
setRegistryManifest(ext.manifest);
|
|
1913
|
+
const projectRoot = options?.dir || process.cwd();
|
|
1914
|
+
try {
|
|
1915
|
+
const manifestPath = join3(projectRoot, "packages/extension/public/manifest.json");
|
|
1916
|
+
const content = await readFile3(manifestPath, "utf8");
|
|
1917
|
+
setLocalManifest(JSON.parse(content));
|
|
1918
|
+
} catch {
|
|
1919
|
+
setLocalManifest(null);
|
|
1920
|
+
}
|
|
1712
1921
|
if (command === "scaffold" /* SCAFFOLD */) {
|
|
1713
1922
|
setStep("confirmTargets");
|
|
1714
1923
|
} else if (command === "update" /* UPDATE */) {
|
|
@@ -1718,7 +1927,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1718
1927
|
const handleConfirmTargets = (value) => {
|
|
1719
1928
|
setTargets(value);
|
|
1720
1929
|
if (options?.extensionPort || options?.previewPort) {
|
|
1721
|
-
setOutputDir(join3(process.cwd(),
|
|
1930
|
+
setOutputDir(join3(process.cwd(), toKebabCase(extensionId || name)));
|
|
1722
1931
|
setStep("confirm");
|
|
1723
1932
|
} else {
|
|
1724
1933
|
setStep("settings");
|
|
@@ -1726,13 +1935,13 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1726
1935
|
};
|
|
1727
1936
|
const handleName = (value) => {
|
|
1728
1937
|
setName(value);
|
|
1729
|
-
setExtensionId(
|
|
1938
|
+
setExtensionId(toKebabCase(value));
|
|
1730
1939
|
if (options?.template) {
|
|
1731
1940
|
const meta = TEMPLATE_FLAVOR_META[templateFlavor];
|
|
1732
1941
|
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
1733
1942
|
setTargets(meta.defaultTargets);
|
|
1734
1943
|
if (options?.extensionPort || options?.previewPort) {
|
|
1735
|
-
setOutputDir(join3(process.cwd(),
|
|
1944
|
+
setOutputDir(join3(process.cwd(), toKebabCase(value)));
|
|
1736
1945
|
setStep("confirm");
|
|
1737
1946
|
} else {
|
|
1738
1947
|
setStep("settings");
|
|
@@ -1750,7 +1959,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1750
1959
|
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
1751
1960
|
setTargets(meta.defaultTargets);
|
|
1752
1961
|
if (options?.extensionPort || options?.previewPort) {
|
|
1753
|
-
setOutputDir(join3(process.cwd(),
|
|
1962
|
+
setOutputDir(join3(process.cwd(), toKebabCase(extensionId || name)));
|
|
1754
1963
|
setStep("confirm");
|
|
1755
1964
|
} else {
|
|
1756
1965
|
setStep("settings");
|
|
@@ -1762,7 +1971,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1762
1971
|
const handleTargets = (value) => {
|
|
1763
1972
|
setTargets(value);
|
|
1764
1973
|
if (options?.extensionPort || options?.previewPort) {
|
|
1765
|
-
setOutputDir(join3(process.cwd(),
|
|
1974
|
+
setOutputDir(join3(process.cwd(), toKebabCase(extensionId || name)));
|
|
1766
1975
|
setStep("confirm");
|
|
1767
1976
|
} else {
|
|
1768
1977
|
setStep("settings");
|
|
@@ -1784,7 +1993,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1784
1993
|
if (targetsChanged) return `${major}.${minor + 1}.0`;
|
|
1785
1994
|
const nameChanged = newName !== initialExtension.name;
|
|
1786
1995
|
if (nameChanged) return `${major}.${minor}.${patch + 1}`;
|
|
1787
|
-
return
|
|
1996
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
1788
1997
|
};
|
|
1789
1998
|
const handleConfirm = async () => {
|
|
1790
1999
|
if (command === "update" /* UPDATE */) {
|
|
@@ -1798,8 +2007,8 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1798
2007
|
name,
|
|
1799
2008
|
version: resolvedVersion,
|
|
1800
2009
|
targets,
|
|
1801
|
-
permissions:
|
|
1802
|
-
allowedDomains:
|
|
2010
|
+
permissions: confirmedPermissions,
|
|
2011
|
+
allowedDomains: confirmedAllowedDomains
|
|
1803
2012
|
},
|
|
1804
2013
|
bundleUrl: bundleUrl || void 0,
|
|
1805
2014
|
enabled
|
|
@@ -1817,7 +2026,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1817
2026
|
setStep("scaffolding");
|
|
1818
2027
|
setProgressSteps(PROGRESS_STEPS[command]);
|
|
1819
2028
|
try {
|
|
1820
|
-
let resolvedExtensionId = extensionId ||
|
|
2029
|
+
let resolvedExtensionId = extensionId || toKebabCase(name);
|
|
1821
2030
|
let scaffoldStepOffset = 0;
|
|
1822
2031
|
if (command === "create" /* CREATE */) {
|
|
1823
2032
|
scaffoldStepOffset = 1;
|
|
@@ -1827,7 +2036,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1827
2036
|
name,
|
|
1828
2037
|
version: "0.0.0",
|
|
1829
2038
|
targets,
|
|
1830
|
-
permissions:
|
|
2039
|
+
permissions: deriveRegistryPermissions(targets),
|
|
1831
2040
|
allowedDomains: []
|
|
1832
2041
|
},
|
|
1833
2042
|
bundleUrl: `http://localhost:${extensionPort}`
|
|
@@ -1849,6 +2058,17 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1849
2058
|
previewPort
|
|
1850
2059
|
});
|
|
1851
2060
|
updateStep(scaffoldStepOffset + 0, "done");
|
|
2061
|
+
if (command === "create" /* CREATE */) {
|
|
2062
|
+
const manifestPath = join3(outputDir, "packages/extension/public/manifest.json");
|
|
2063
|
+
try {
|
|
2064
|
+
const manifestContent = await readFile3(manifestPath, "utf8");
|
|
2065
|
+
const manifest = JSON.parse(manifestContent);
|
|
2066
|
+
await updateExtension(token, selectedApp.id, resolvedExtensionId, {
|
|
2067
|
+
manifest: { ...manifest, allowedDomains: [] }
|
|
2068
|
+
});
|
|
2069
|
+
} catch {
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
1852
2072
|
updateStep(scaffoldStepOffset + 1, "running");
|
|
1853
2073
|
await new Promise((r) => setTimeout(r, 200));
|
|
1854
2074
|
updateStep(scaffoldStepOffset + 1, "done");
|
|
@@ -1871,7 +2091,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1871
2091
|
};
|
|
1872
2092
|
switch (step) {
|
|
1873
2093
|
case "app": {
|
|
1874
|
-
return /* @__PURE__ */
|
|
2094
|
+
return /* @__PURE__ */ jsx15(
|
|
1875
2095
|
AppSelect,
|
|
1876
2096
|
{
|
|
1877
2097
|
token,
|
|
@@ -1882,7 +2102,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1882
2102
|
);
|
|
1883
2103
|
}
|
|
1884
2104
|
case "extensionSelect": {
|
|
1885
|
-
return /* @__PURE__ */
|
|
2105
|
+
return /* @__PURE__ */ jsx15(
|
|
1886
2106
|
ExtensionSelect,
|
|
1887
2107
|
{
|
|
1888
2108
|
appId: selectedApp.id,
|
|
@@ -1894,7 +2114,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1894
2114
|
);
|
|
1895
2115
|
}
|
|
1896
2116
|
case "confirmTargets": {
|
|
1897
|
-
return /* @__PURE__ */
|
|
2117
|
+
return /* @__PURE__ */ jsx15(
|
|
1898
2118
|
TargetSelect,
|
|
1899
2119
|
{
|
|
1900
2120
|
availableTargets: selectedApp?.targets ?? [],
|
|
@@ -1905,7 +2125,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1905
2125
|
);
|
|
1906
2126
|
}
|
|
1907
2127
|
case "name": {
|
|
1908
|
-
return /* @__PURE__ */
|
|
2128
|
+
return /* @__PURE__ */ jsx15(
|
|
1909
2129
|
NamePrompt,
|
|
1910
2130
|
{
|
|
1911
2131
|
initialValue: name,
|
|
@@ -1915,7 +2135,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1915
2135
|
);
|
|
1916
2136
|
}
|
|
1917
2137
|
case "template": {
|
|
1918
|
-
return /* @__PURE__ */
|
|
2138
|
+
return /* @__PURE__ */ jsx15(
|
|
1919
2139
|
TemplateSelect,
|
|
1920
2140
|
{
|
|
1921
2141
|
onSubmit: handleTemplateSelect,
|
|
@@ -1924,7 +2144,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1924
2144
|
);
|
|
1925
2145
|
}
|
|
1926
2146
|
case "targets": {
|
|
1927
|
-
return /* @__PURE__ */
|
|
2147
|
+
return /* @__PURE__ */ jsx15(
|
|
1928
2148
|
TargetSelect,
|
|
1929
2149
|
{
|
|
1930
2150
|
availableTargets: selectedApp?.targets ?? [],
|
|
@@ -1934,29 +2154,34 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1934
2154
|
);
|
|
1935
2155
|
}
|
|
1936
2156
|
case "settings": {
|
|
1937
|
-
return /* @__PURE__ */
|
|
2157
|
+
return /* @__PURE__ */ jsx15(
|
|
1938
2158
|
SettingsPrompt,
|
|
1939
2159
|
{
|
|
1940
|
-
defaultDir: join3(process.cwd(),
|
|
2160
|
+
defaultDir: join3(process.cwd(), toKebabCase(extensionId || name)),
|
|
1941
2161
|
onSubmit: handleSettings,
|
|
1942
2162
|
onBack: goBack
|
|
1943
2163
|
}
|
|
1944
2164
|
);
|
|
1945
2165
|
}
|
|
1946
2166
|
case "confirm": {
|
|
1947
|
-
return /* @__PURE__ */
|
|
2167
|
+
return /* @__PURE__ */ jsx15(
|
|
1948
2168
|
Confirm,
|
|
1949
2169
|
{
|
|
1950
2170
|
command,
|
|
1951
2171
|
name,
|
|
1952
2172
|
templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0,
|
|
1953
2173
|
targets,
|
|
2174
|
+
registryTargets: command === "update" /* UPDATE */ ? registryManifest?.targets : void 0,
|
|
1954
2175
|
outputDir,
|
|
1955
2176
|
previewPort,
|
|
1956
2177
|
extensionPort,
|
|
1957
2178
|
extensionVersion: command !== "create" /* CREATE */ ? extensionVersion : void 0,
|
|
1958
2179
|
bundleUrl: command === "update" /* UPDATE */ ? bundleUrl : void 0,
|
|
1959
2180
|
enabled: command === "update" /* UPDATE */ ? enabled : void 0,
|
|
2181
|
+
permissions: command === "update" /* UPDATE */ ? confirmedPermissions : void 0,
|
|
2182
|
+
allowedDomains: command === "update" /* UPDATE */ ? confirmedAllowedDomains : void 0,
|
|
2183
|
+
registryPermissions: command === "update" /* UPDATE */ ? registryManifest?.permissions : void 0,
|
|
2184
|
+
registryAllowedDomains: command === "update" /* UPDATE */ ? registryManifest?.allowedDomains : void 0,
|
|
1960
2185
|
newVersion: command === "update" /* UPDATE */ ? options?.setVersion ?? versionOverride ?? computeVersionBump(extensionVersion, name, targets, bundleUrl, forceMajor) : void 0,
|
|
1961
2186
|
onVersionOverride: command === "update" /* UPDATE */ ? setVersionOverride : void 0,
|
|
1962
2187
|
onConfirm: handleConfirm,
|
|
@@ -1966,10 +2191,10 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1966
2191
|
);
|
|
1967
2192
|
}
|
|
1968
2193
|
case "scaffolding": {
|
|
1969
|
-
return /* @__PURE__ */
|
|
2194
|
+
return /* @__PURE__ */ jsx15(ScaffoldProgress, { steps: progressSteps });
|
|
1970
2195
|
}
|
|
1971
2196
|
case "updateSettings": {
|
|
1972
|
-
return /* @__PURE__ */
|
|
2197
|
+
return /* @__PURE__ */ jsx15(
|
|
1973
2198
|
UpdateSettingsPrompt,
|
|
1974
2199
|
{
|
|
1975
2200
|
name,
|
|
@@ -1984,6 +2209,21 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1984
2209
|
setEnabled(updated.enabled);
|
|
1985
2210
|
setForceMajor(updated.forceMajor);
|
|
1986
2211
|
setVersionOverride(void 0);
|
|
2212
|
+
setStep("manifestReview");
|
|
2213
|
+
},
|
|
2214
|
+
onBack: goBack
|
|
2215
|
+
}
|
|
2216
|
+
);
|
|
2217
|
+
}
|
|
2218
|
+
case "manifestReview": {
|
|
2219
|
+
return /* @__PURE__ */ jsx15(
|
|
2220
|
+
ManifestReviewPrompt,
|
|
2221
|
+
{
|
|
2222
|
+
localManifest,
|
|
2223
|
+
registryManifest,
|
|
2224
|
+
onSubmit: (result) => {
|
|
2225
|
+
setConfirmedPermissions(result.permissions);
|
|
2226
|
+
setConfirmedAllowedDomains(result.allowedDomains);
|
|
1987
2227
|
setStep("confirm");
|
|
1988
2228
|
},
|
|
1989
2229
|
onBack: goBack
|
|
@@ -1991,46 +2231,46 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1991
2231
|
);
|
|
1992
2232
|
}
|
|
1993
2233
|
case "updating": {
|
|
1994
|
-
return /* @__PURE__ */
|
|
2234
|
+
return /* @__PURE__ */ jsx15(ScaffoldProgress, { steps: progressSteps });
|
|
1995
2235
|
}
|
|
1996
2236
|
case "updateDone": {
|
|
1997
|
-
return /* @__PURE__ */
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
/* @__PURE__ */
|
|
2237
|
+
return /* @__PURE__ */ jsx15(StepShell, { title: "Extension updated", onBack: goBack, children: /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
|
|
2238
|
+
/* @__PURE__ */ jsx15(Text15, { color: "green", bold: true, children: "Extension updated successfully!" }),
|
|
2239
|
+
/* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
2000
2240
|
"Name: ",
|
|
2001
2241
|
name
|
|
2002
2242
|
] }),
|
|
2003
|
-
/* @__PURE__ */
|
|
2243
|
+
/* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
2004
2244
|
"ID: ",
|
|
2005
2245
|
extensionId
|
|
2006
2246
|
] }),
|
|
2007
|
-
/* @__PURE__ */
|
|
2247
|
+
/* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
2008
2248
|
"Version: ",
|
|
2009
2249
|
extensionVersion
|
|
2010
2250
|
] })
|
|
2011
2251
|
] }) });
|
|
2012
2252
|
}
|
|
2013
2253
|
case "done": {
|
|
2014
|
-
return /* @__PURE__ */
|
|
2254
|
+
return /* @__PURE__ */ jsx15(Done, { name, outputDir, templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0 });
|
|
2015
2255
|
}
|
|
2016
2256
|
case "error": {
|
|
2017
|
-
return /* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
errorMessage && /* @__PURE__ */
|
|
2257
|
+
return /* @__PURE__ */ jsx15(StepShell, { title: "Operation failed", onBack: goBack, children: /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
|
|
2258
|
+
/* @__PURE__ */ jsx15(Text15, { color: "red", bold: true, children: "An error occurred" }),
|
|
2259
|
+
errorMessage && /* @__PURE__ */ jsx15(Text15, { color: "red", children: errorMessage })
|
|
2020
2260
|
] }) });
|
|
2021
2261
|
}
|
|
2022
2262
|
default: {
|
|
2023
|
-
return /* @__PURE__ */
|
|
2024
|
-
/* @__PURE__ */
|
|
2025
|
-
errorMessage && /* @__PURE__ */
|
|
2263
|
+
return /* @__PURE__ */ jsx15(StepShell, { title: "Scaffold failed", onBack: goBack, children: /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
|
|
2264
|
+
/* @__PURE__ */ jsx15(Text15, { color: "red", bold: true, children: "An error occurred" }),
|
|
2265
|
+
errorMessage && /* @__PURE__ */ jsx15(Text15, { color: "red", children: errorMessage })
|
|
2026
2266
|
] }) });
|
|
2027
2267
|
}
|
|
2028
2268
|
}
|
|
2029
2269
|
};
|
|
2030
2270
|
|
|
2031
2271
|
// src/components/DevApp.tsx
|
|
2032
|
-
import { useRef, useState as
|
|
2033
|
-
import { useInput as
|
|
2272
|
+
import { useRef, useState as useState12, useEffect as useEffect6, useCallback as useCallback2 } from "react";
|
|
2273
|
+
import { useInput as useInput11, Box as Box18, Text as Text18 } from "ink";
|
|
2034
2274
|
|
|
2035
2275
|
// src/lib/tunnel.ts
|
|
2036
2276
|
import { Tunnel } from "cloudflared";
|
|
@@ -2064,12 +2304,12 @@ var startDevServer = (projectRoot) => {
|
|
|
2064
2304
|
};
|
|
2065
2305
|
|
|
2066
2306
|
// src/components/DevSetup.tsx
|
|
2067
|
-
import { Box as
|
|
2068
|
-
import { useState as
|
|
2069
|
-
import { jsx as
|
|
2307
|
+
import { Box as Box16, Text as Text16 } from "ink";
|
|
2308
|
+
import { useState as useState11, useEffect as useEffect4 } from "react";
|
|
2309
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2070
2310
|
var DevSetup = ({ initialContext, token, onReady }) => {
|
|
2071
|
-
const [step, setStep] =
|
|
2072
|
-
const [selectedApp, setSelectedApp] =
|
|
2311
|
+
const [step, setStep] = useState11("app");
|
|
2312
|
+
const [selectedApp, setSelectedApp] = useState11(null);
|
|
2073
2313
|
useEffect4(() => {
|
|
2074
2314
|
if (initialContext.appId) {
|
|
2075
2315
|
setStep("extension");
|
|
@@ -2087,9 +2327,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2087
2327
|
});
|
|
2088
2328
|
};
|
|
2089
2329
|
if (step === "app") {
|
|
2090
|
-
return /* @__PURE__ */
|
|
2091
|
-
/* @__PURE__ */
|
|
2092
|
-
/* @__PURE__ */
|
|
2330
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
2331
|
+
/* @__PURE__ */ jsx16(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text16, { children: "Select the App for your extension:" }) }),
|
|
2332
|
+
/* @__PURE__ */ jsx16(
|
|
2093
2333
|
AppSelect,
|
|
2094
2334
|
{
|
|
2095
2335
|
token,
|
|
@@ -2098,9 +2338,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2098
2338
|
)
|
|
2099
2339
|
] });
|
|
2100
2340
|
}
|
|
2101
|
-
return /* @__PURE__ */
|
|
2102
|
-
/* @__PURE__ */
|
|
2103
|
-
/* @__PURE__ */
|
|
2341
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
2342
|
+
/* @__PURE__ */ jsx16(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text16, { children: "Select the Extension to develop:" }) }),
|
|
2343
|
+
/* @__PURE__ */ jsx16(
|
|
2104
2344
|
ExtensionSelect,
|
|
2105
2345
|
{
|
|
2106
2346
|
token,
|
|
@@ -2112,9 +2352,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2112
2352
|
};
|
|
2113
2353
|
|
|
2114
2354
|
// src/components/DevDashboard.tsx
|
|
2115
|
-
import { Box as
|
|
2355
|
+
import { Box as Box17, Text as Text17, useInput as useInput10 } from "ink";
|
|
2116
2356
|
import { useEffect as useEffect5 } from "react";
|
|
2117
|
-
import { jsx as
|
|
2357
|
+
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2118
2358
|
var DevDashboard = ({
|
|
2119
2359
|
previewTunnelUrl,
|
|
2120
2360
|
tunnelUrl,
|
|
@@ -2126,6 +2366,7 @@ var DevDashboard = ({
|
|
|
2126
2366
|
extensionName,
|
|
2127
2367
|
extensionPort,
|
|
2128
2368
|
previewPort,
|
|
2369
|
+
manifestWarnings = [],
|
|
2129
2370
|
onQuit
|
|
2130
2371
|
}) => {
|
|
2131
2372
|
useEffect5(() => {
|
|
@@ -2137,72 +2378,80 @@ var DevDashboard = ({
|
|
|
2137
2378
|
process.off("SIGINT", handler);
|
|
2138
2379
|
};
|
|
2139
2380
|
}, [onQuit]);
|
|
2140
|
-
|
|
2381
|
+
useInput10((input, key) => {
|
|
2141
2382
|
if (input === "q" || key.ctrl && input === "c") {
|
|
2142
2383
|
onQuit();
|
|
2143
2384
|
}
|
|
2144
2385
|
});
|
|
2145
|
-
return /* @__PURE__ */
|
|
2146
|
-
/* @__PURE__ */
|
|
2147
|
-
/* @__PURE__ */
|
|
2386
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
2387
|
+
/* @__PURE__ */ jsx17(Banner, { userId, orgId }),
|
|
2388
|
+
/* @__PURE__ */ jsxs17(
|
|
2148
2389
|
StepShell,
|
|
2149
2390
|
{
|
|
2150
2391
|
title: "dev",
|
|
2151
2392
|
hint: `Live development ${tunnelUrl ? "with" : "w/o"} Tunnel`,
|
|
2152
|
-
footer: /* @__PURE__ */
|
|
2393
|
+
footer: /* @__PURE__ */ jsx17(Box17, { flexDirection: "column", gap: 1, children: /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Press q or Ctrl-C to quit" }) }),
|
|
2153
2394
|
children: [
|
|
2154
|
-
/* @__PURE__ */
|
|
2155
|
-
/* @__PURE__ */
|
|
2156
|
-
/* @__PURE__ */
|
|
2157
|
-
/* @__PURE__ */
|
|
2395
|
+
/* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
2396
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2397
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Extension:" }),
|
|
2398
|
+
/* @__PURE__ */ jsxs17(Text17, { children: [
|
|
2158
2399
|
extensionName,
|
|
2159
2400
|
" (",
|
|
2160
2401
|
extensionId,
|
|
2161
2402
|
")"
|
|
2162
2403
|
] })
|
|
2163
2404
|
] }),
|
|
2164
|
-
/* @__PURE__ */
|
|
2165
|
-
/* @__PURE__ */
|
|
2166
|
-
/* @__PURE__ */
|
|
2405
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2406
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "App:" }),
|
|
2407
|
+
/* @__PURE__ */ jsx17(Text17, { children: `${appName ? `${appName} ` : ""}(${appId})` })
|
|
2167
2408
|
] }),
|
|
2168
|
-
/* @__PURE__ */
|
|
2169
|
-
/* @__PURE__ */
|
|
2170
|
-
/* @__PURE__ */
|
|
2409
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2410
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Bundle URL:" }),
|
|
2411
|
+
/* @__PURE__ */ jsx17(Text17, { children: tunnelUrl || `http://localhost:${extensionPort}` })
|
|
2171
2412
|
] })
|
|
2172
2413
|
] }),
|
|
2173
|
-
/* @__PURE__ */
|
|
2174
|
-
previewTunnelUrl && /* @__PURE__ */
|
|
2175
|
-
/* @__PURE__ */
|
|
2176
|
-
/* @__PURE__ */
|
|
2414
|
+
/* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
2415
|
+
previewTunnelUrl && /* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2416
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Tunnel Dev - Preview:" }),
|
|
2417
|
+
/* @__PURE__ */ jsx17(Text17, { children: previewTunnelUrl })
|
|
2177
2418
|
] }),
|
|
2178
|
-
/* @__PURE__ */
|
|
2179
|
-
/* @__PURE__ */
|
|
2180
|
-
/* @__PURE__ */
|
|
2419
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2420
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Local Dev - Preview:" }),
|
|
2421
|
+
/* @__PURE__ */ jsxs17(Text17, { children: [
|
|
2181
2422
|
"http://localhost:",
|
|
2182
2423
|
previewPort
|
|
2183
2424
|
] })
|
|
2184
2425
|
] })
|
|
2185
2426
|
] }),
|
|
2186
|
-
/* @__PURE__ */
|
|
2187
|
-
tunnelUrl && /* @__PURE__ */
|
|
2188
|
-
/* @__PURE__ */
|
|
2189
|
-
/* @__PURE__ */
|
|
2427
|
+
/* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
2428
|
+
tunnelUrl && /* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2429
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Tunnel Dev - Extension:" }),
|
|
2430
|
+
/* @__PURE__ */ jsx17(Text17, { children: tunnelUrl })
|
|
2190
2431
|
] }),
|
|
2191
|
-
/* @__PURE__ */
|
|
2192
|
-
/* @__PURE__ */
|
|
2193
|
-
/* @__PURE__ */
|
|
2432
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2433
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Local Dev - Extension:" }),
|
|
2434
|
+
/* @__PURE__ */ jsxs17(Text17, { children: [
|
|
2194
2435
|
"http://localhost:",
|
|
2195
2436
|
extensionPort
|
|
2196
2437
|
] })
|
|
2197
2438
|
] })
|
|
2198
2439
|
] }),
|
|
2199
|
-
/* @__PURE__ */
|
|
2200
|
-
/* @__PURE__ */
|
|
2201
|
-
/* @__PURE__ */
|
|
2440
|
+
/* @__PURE__ */ jsx17(Box17, { flexDirection: "column", children: tunnelUrl && /* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2441
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Host Dev - Query Param:" }),
|
|
2442
|
+
/* @__PURE__ */ jsxs17(Text17, { children: [
|
|
2202
2443
|
"?_stackable_dev=",
|
|
2203
2444
|
encodeURIComponent(`${extensionId}:${tunnelUrl}`)
|
|
2204
2445
|
] })
|
|
2205
|
-
] }) })
|
|
2446
|
+
] }) }),
|
|
2447
|
+
manifestWarnings.length > 0 && /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
2448
|
+
/* @__PURE__ */ jsx17(Text17, { color: "yellow", bold: true, children: "Local manifest differs from registry:" }),
|
|
2449
|
+
manifestWarnings.map((w, i) => /* @__PURE__ */ jsxs17(Text17, { color: "yellow", children: [
|
|
2450
|
+
" ",
|
|
2451
|
+
w
|
|
2452
|
+
] }, i)),
|
|
2453
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: " Run `pnpm dlx @stackable-labs/cli-app-extension@latest update` to review and sync." })
|
|
2454
|
+
] })
|
|
2206
2455
|
]
|
|
2207
2456
|
}
|
|
2208
2457
|
)
|
|
@@ -2210,16 +2459,17 @@ var DevDashboard = ({
|
|
|
2210
2459
|
};
|
|
2211
2460
|
|
|
2212
2461
|
// src/components/DevApp.tsx
|
|
2213
|
-
import { jsx as
|
|
2462
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2214
2463
|
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] =
|
|
2464
|
+
const [state, setState] = useState12("setup");
|
|
2465
|
+
const [devContext, setDevContext] = useState12(null);
|
|
2466
|
+
const [resolvedContext, setResolvedContext] = useState12(null);
|
|
2467
|
+
const [tunnelUrl, setTunnelUrl] = useState12(null);
|
|
2468
|
+
const [previewTunnelUrl, setPreviewTunnelUrl] = useState12(null);
|
|
2469
|
+
const [tunnelHandle, setTunnelHandle] = useState12(null);
|
|
2470
|
+
const [previewTunnelHandle, setPreviewTunnelHandle] = useState12(null);
|
|
2471
|
+
const [devServerHandle, setDevServerHandle] = useState12(null);
|
|
2472
|
+
const [manifestWarnings, setManifestWarnings] = useState12([]);
|
|
2223
2473
|
const shuttingDown = useRef(false);
|
|
2224
2474
|
const useTunnel = options.tunnel !== false;
|
|
2225
2475
|
useEffect6(() => {
|
|
@@ -2240,6 +2490,31 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2240
2490
|
extensionId: resolved.extensionId,
|
|
2241
2491
|
appName: resolved.appName || null
|
|
2242
2492
|
});
|
|
2493
|
+
if (devContext.manifest) {
|
|
2494
|
+
try {
|
|
2495
|
+
const extensions = await fetchExtensions(token, resolved.appId);
|
|
2496
|
+
const registryExt = extensions[resolved.extensionId];
|
|
2497
|
+
if (registryExt) {
|
|
2498
|
+
const localPerms = new Set(devContext.manifest.permissions);
|
|
2499
|
+
const registryPerms = new Set(registryExt.manifest.permissions);
|
|
2500
|
+
const missingPerms = [...localPerms].filter((p) => !registryPerms.has(p));
|
|
2501
|
+
const extraPerms = [...registryPerms].filter((p) => !localPerms.has(p));
|
|
2502
|
+
const localDomains = new Set(devContext.manifest.allowedDomains);
|
|
2503
|
+
const registryDomains = new Set(registryExt.manifest.allowedDomains);
|
|
2504
|
+
const missingDomains = [...localDomains].filter((d) => !registryDomains.has(d));
|
|
2505
|
+
const extraDomains = [...registryDomains].filter((d) => !localDomains.has(d));
|
|
2506
|
+
const warnings = [];
|
|
2507
|
+
if (missingPerms.length > 0) warnings.push(`Permissions in local but not registry: ${missingPerms.join(", ")}`);
|
|
2508
|
+
if (extraPerms.length > 0) warnings.push(`Permissions in registry but not local: ${extraPerms.join(", ")}`);
|
|
2509
|
+
if (missingDomains.length > 0) warnings.push(`Domains in local but not registry: ${missingDomains.join(", ")}`);
|
|
2510
|
+
if (extraDomains.length > 0) warnings.push(`Domains in registry but not local: ${extraDomains.join(", ")}`);
|
|
2511
|
+
if (warnings.length > 0) {
|
|
2512
|
+
setManifestWarnings(warnings);
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
} catch {
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2243
2518
|
const extensionPort = options.extensionPort ? parseInt(options.extensionPort, 10) : devContext.extensionPort;
|
|
2244
2519
|
const previewPort = options.previewPort ? parseInt(options.previewPort, 10) : devContext.previewPort;
|
|
2245
2520
|
await patchViteAllowedHosts(devContext.projectRoot);
|
|
@@ -2268,7 +2543,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2268
2543
|
setDevServerHandle(serverHandle);
|
|
2269
2544
|
console.log("[dev] Ready");
|
|
2270
2545
|
setState("running");
|
|
2271
|
-
}, [devContext, options.extensionPort, options.previewPort, useTunnel]);
|
|
2546
|
+
}, [devContext, token, options.extensionPort, options.previewPort, useTunnel]);
|
|
2272
2547
|
useEffect6(() => {
|
|
2273
2548
|
if (state === "setup" && devContext && devContext.appId && devContext.extensionId) {
|
|
2274
2549
|
handleSetupReady({
|
|
@@ -2304,7 +2579,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2304
2579
|
console.log("[dev] Done");
|
|
2305
2580
|
process.exit(0);
|
|
2306
2581
|
};
|
|
2307
|
-
|
|
2582
|
+
useInput11((input, key) => {
|
|
2308
2583
|
if (input === "c" && key.ctrl) {
|
|
2309
2584
|
if (state === "running") {
|
|
2310
2585
|
handleQuit();
|
|
@@ -2315,7 +2590,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2315
2590
|
});
|
|
2316
2591
|
if (state === "setup" && devContext) {
|
|
2317
2592
|
if (!devContext.appId || !devContext.extensionId) {
|
|
2318
|
-
return /* @__PURE__ */
|
|
2593
|
+
return /* @__PURE__ */ jsx18(
|
|
2319
2594
|
DevSetup,
|
|
2320
2595
|
{
|
|
2321
2596
|
token,
|
|
@@ -2327,7 +2602,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2327
2602
|
return null;
|
|
2328
2603
|
}
|
|
2329
2604
|
if (state === "running" && devContext && resolvedContext) {
|
|
2330
|
-
return /* @__PURE__ */
|
|
2605
|
+
return /* @__PURE__ */ jsx18(
|
|
2331
2606
|
DevDashboard,
|
|
2332
2607
|
{
|
|
2333
2608
|
previewTunnelUrl,
|
|
@@ -2340,6 +2615,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2340
2615
|
extensionId: resolvedContext.extensionId,
|
|
2341
2616
|
extensionPort: options.extensionPort ? parseInt(options.extensionPort, 10) : devContext.extensionPort,
|
|
2342
2617
|
previewPort: options.previewPort ? parseInt(options.previewPort, 10) : devContext.previewPort,
|
|
2618
|
+
manifestWarnings,
|
|
2343
2619
|
onQuit: handleQuit
|
|
2344
2620
|
}
|
|
2345
2621
|
);
|
|
@@ -2347,13 +2623,13 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2347
2623
|
if (state === "stopping") {
|
|
2348
2624
|
return null;
|
|
2349
2625
|
}
|
|
2350
|
-
return /* @__PURE__ */
|
|
2626
|
+
return /* @__PURE__ */ jsx18(Box18, { children: /* @__PURE__ */ jsx18(Text18, { children: "Loading..." }) });
|
|
2351
2627
|
};
|
|
2352
2628
|
|
|
2353
2629
|
// src/components/AIScaffold.tsx
|
|
2354
|
-
import { Box as
|
|
2630
|
+
import { Box as Box19, Text as Text19, useApp as useApp2 } from "ink";
|
|
2355
2631
|
import Spinner4 from "ink-spinner";
|
|
2356
|
-
import { useState as
|
|
2632
|
+
import { useState as useState13, useEffect as useEffect7 } from "react";
|
|
2357
2633
|
|
|
2358
2634
|
// src/lib/aiDocs.ts
|
|
2359
2635
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -2406,12 +2682,12 @@ var downloadAndExtractAiDocs = async (targetDir, version2) => {
|
|
|
2406
2682
|
};
|
|
2407
2683
|
|
|
2408
2684
|
// src/components/AIScaffold.tsx
|
|
2409
|
-
import { jsx as
|
|
2685
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2410
2686
|
var AIScaffold = ({ version: version2 }) => {
|
|
2411
2687
|
const { exit } = useApp2();
|
|
2412
|
-
const [state, setState] =
|
|
2413
|
-
const [files, setFiles] =
|
|
2414
|
-
const [errorMessage, setErrorMessage] =
|
|
2688
|
+
const [state, setState] = useState13("validating");
|
|
2689
|
+
const [files, setFiles] = useState13([]);
|
|
2690
|
+
const [errorMessage, setErrorMessage] = useState13("");
|
|
2415
2691
|
useEffect7(() => {
|
|
2416
2692
|
const run = async () => {
|
|
2417
2693
|
const projectDir = process.cwd();
|
|
@@ -2435,35 +2711,35 @@ var AIScaffold = ({ version: version2 }) => {
|
|
|
2435
2711
|
};
|
|
2436
2712
|
run();
|
|
2437
2713
|
}, []);
|
|
2438
|
-
return /* @__PURE__ */
|
|
2439
|
-
/* @__PURE__ */
|
|
2440
|
-
/* @__PURE__ */
|
|
2441
|
-
state === "validating" && /* @__PURE__ */
|
|
2442
|
-
/* @__PURE__ */
|
|
2443
|
-
/* @__PURE__ */
|
|
2714
|
+
return /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", children: [
|
|
2715
|
+
/* @__PURE__ */ jsx19(Banner, {}),
|
|
2716
|
+
/* @__PURE__ */ jsxs18(StepShell, { title: "AI Editor Config", children: [
|
|
2717
|
+
state === "validating" && /* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2718
|
+
/* @__PURE__ */ jsx19(Text19, { color: "cyan", children: /* @__PURE__ */ jsx19(Spinner4, { type: "dots" }) }),
|
|
2719
|
+
/* @__PURE__ */ jsx19(Text19, { children: "Checking project..." })
|
|
2444
2720
|
] }),
|
|
2445
|
-
state === "downloading" && /* @__PURE__ */
|
|
2446
|
-
/* @__PURE__ */
|
|
2447
|
-
/* @__PURE__ */
|
|
2721
|
+
state === "downloading" && /* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2722
|
+
/* @__PURE__ */ jsx19(Text19, { color: "cyan", children: /* @__PURE__ */ jsx19(Spinner4, { type: "dots" }) }),
|
|
2723
|
+
/* @__PURE__ */ jsxs18(Text19, { children: [
|
|
2448
2724
|
"Downloading AI editor configs (",
|
|
2449
2725
|
version2,
|
|
2450
2726
|
")..."
|
|
2451
2727
|
] })
|
|
2452
2728
|
] }),
|
|
2453
|
-
state === "done" && /* @__PURE__ */
|
|
2454
|
-
/* @__PURE__ */
|
|
2455
|
-
/* @__PURE__ */
|
|
2456
|
-
/* @__PURE__ */
|
|
2729
|
+
state === "done" && /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", gap: 1, children: [
|
|
2730
|
+
/* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2731
|
+
/* @__PURE__ */ jsx19(Text19, { color: "green", bold: true, children: "\u2714" }),
|
|
2732
|
+
/* @__PURE__ */ jsxs18(Text19, { bold: true, children: [
|
|
2457
2733
|
"AI editor configs installed (",
|
|
2458
2734
|
files.length,
|
|
2459
2735
|
" files)"
|
|
2460
2736
|
] })
|
|
2461
2737
|
] }),
|
|
2462
|
-
/* @__PURE__ */
|
|
2738
|
+
/* @__PURE__ */ jsx19(Box19, { flexDirection: "column", marginLeft: 2, children: files.map((f) => /* @__PURE__ */ jsx19(Text19, { dimColor: true, children: f }, f)) })
|
|
2463
2739
|
] }),
|
|
2464
|
-
state === "error" && /* @__PURE__ */
|
|
2465
|
-
/* @__PURE__ */
|
|
2466
|
-
/* @__PURE__ */
|
|
2740
|
+
state === "error" && /* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2741
|
+
/* @__PURE__ */ jsx19(Text19, { color: "red", children: "\u2716" }),
|
|
2742
|
+
/* @__PURE__ */ jsx19(Text19, { children: errorMessage })
|
|
2467
2743
|
] })
|
|
2468
2744
|
] })
|
|
2469
2745
|
] });
|
|
@@ -2471,20 +2747,20 @@ var AIScaffold = ({ version: version2 }) => {
|
|
|
2471
2747
|
|
|
2472
2748
|
// src/components/AuthLogin.tsx
|
|
2473
2749
|
import { createServer } from "http";
|
|
2474
|
-
import { Box as
|
|
2750
|
+
import { Box as Box20, Text as Text20, useApp as useApp3 } from "ink";
|
|
2475
2751
|
import Spinner5 from "ink-spinner";
|
|
2476
2752
|
import open from "open";
|
|
2477
|
-
import { useState as
|
|
2753
|
+
import { useState as useState14, useEffect as useEffect8 } from "react";
|
|
2478
2754
|
|
|
2479
2755
|
// src/lib/auth.ts
|
|
2480
|
-
import { readFile as
|
|
2756
|
+
import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir2, unlink } from "fs/promises";
|
|
2481
2757
|
import { join as join5 } from "path";
|
|
2482
2758
|
import { homedir } from "os";
|
|
2483
2759
|
var AUTH_DIR = join5(homedir(), ".stackable");
|
|
2484
2760
|
var AUTH_FILE = join5(AUTH_DIR, "auth.json");
|
|
2485
2761
|
var readAuthState = async () => {
|
|
2486
2762
|
try {
|
|
2487
|
-
const content = await
|
|
2763
|
+
const content = await readFile4(AUTH_FILE, "utf8");
|
|
2488
2764
|
return JSON.parse(content);
|
|
2489
2765
|
} catch {
|
|
2490
2766
|
return null;
|
|
@@ -2527,7 +2803,7 @@ var getToken = async () => {
|
|
|
2527
2803
|
};
|
|
2528
2804
|
|
|
2529
2805
|
// src/components/AuthLogin.tsx
|
|
2530
|
-
import { jsx as
|
|
2806
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2531
2807
|
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
2532
2808
|
var callbackPage = (heading, sub, redirectUrl) => `<!DOCTYPE html>
|
|
2533
2809
|
<html><head><meta charset="utf-8"><title>Stackable CLI</title>
|
|
@@ -2538,11 +2814,11 @@ ${redirectUrl ? `<script>(function(){var s=3,el=document.getElementById('h');fun
|
|
|
2538
2814
|
</body></html>`;
|
|
2539
2815
|
var AuthLogin = ({ dashboardUrl }) => {
|
|
2540
2816
|
const { exit } = useApp3();
|
|
2541
|
-
const [state, setState] =
|
|
2542
|
-
const [loginUrl, setLoginUrl] =
|
|
2543
|
-
const [userIdLabel, setUserIdLabel] =
|
|
2544
|
-
const [orgIdLabel, setOrgIdLabel] =
|
|
2545
|
-
const [errorMessage, setErrorMessage] =
|
|
2817
|
+
const [state, setState] = useState14("waiting");
|
|
2818
|
+
const [loginUrl, setLoginUrl] = useState14("");
|
|
2819
|
+
const [userIdLabel, setUserIdLabel] = useState14("");
|
|
2820
|
+
const [orgIdLabel, setOrgIdLabel] = useState14("");
|
|
2821
|
+
const [errorMessage, setErrorMessage] = useState14("");
|
|
2546
2822
|
useEffect8(() => {
|
|
2547
2823
|
let server;
|
|
2548
2824
|
let timeout;
|
|
@@ -2618,38 +2894,38 @@ var AuthLogin = ({ dashboardUrl }) => {
|
|
|
2618
2894
|
server?.close();
|
|
2619
2895
|
};
|
|
2620
2896
|
}, []);
|
|
2621
|
-
return /* @__PURE__ */
|
|
2622
|
-
/* @__PURE__ */
|
|
2623
|
-
/* @__PURE__ */
|
|
2624
|
-
state === "waiting" && /* @__PURE__ */
|
|
2625
|
-
/* @__PURE__ */
|
|
2626
|
-
/* @__PURE__ */
|
|
2627
|
-
/* @__PURE__ */
|
|
2897
|
+
return /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", children: [
|
|
2898
|
+
/* @__PURE__ */ jsx20(Banner, {}),
|
|
2899
|
+
/* @__PURE__ */ jsxs19(StepShell, { title: "Authenticate with Stackable", children: [
|
|
2900
|
+
state === "waiting" && /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", gap: 1, children: [
|
|
2901
|
+
/* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2902
|
+
/* @__PURE__ */ jsx20(Text20, { color: "cyan", children: /* @__PURE__ */ jsx20(Spinner5, { type: "dots" }) }),
|
|
2903
|
+
/* @__PURE__ */ jsx20(Text20, { children: "Waiting for browser authentication..." })
|
|
2628
2904
|
] }),
|
|
2629
|
-
loginUrl && /* @__PURE__ */
|
|
2905
|
+
loginUrl && /* @__PURE__ */ jsxs19(Text20, { dimColor: true, children: [
|
|
2630
2906
|
" ",
|
|
2631
2907
|
loginUrl
|
|
2632
2908
|
] })
|
|
2633
2909
|
] }),
|
|
2634
|
-
state === "success" && /* @__PURE__ */
|
|
2635
|
-
/* @__PURE__ */
|
|
2636
|
-
/* @__PURE__ */
|
|
2637
|
-
/* @__PURE__ */
|
|
2638
|
-
/* @__PURE__ */
|
|
2910
|
+
state === "success" && /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", gap: 1, children: [
|
|
2911
|
+
/* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", children: [
|
|
2912
|
+
/* @__PURE__ */ jsxs19(Box20, { gap: 2, children: [
|
|
2913
|
+
/* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "User:" }),
|
|
2914
|
+
/* @__PURE__ */ jsx20(Text20, { color: "cyan", children: userIdLabel })
|
|
2639
2915
|
] }),
|
|
2640
|
-
/* @__PURE__ */
|
|
2641
|
-
/* @__PURE__ */
|
|
2642
|
-
/* @__PURE__ */
|
|
2916
|
+
/* @__PURE__ */ jsxs19(Box20, { gap: 2, children: [
|
|
2917
|
+
/* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "Org: " }),
|
|
2918
|
+
/* @__PURE__ */ jsx20(Text20, { color: "cyan", children: orgIdLabel })
|
|
2643
2919
|
] })
|
|
2644
2920
|
] }),
|
|
2645
|
-
/* @__PURE__ */
|
|
2646
|
-
/* @__PURE__ */
|
|
2647
|
-
/* @__PURE__ */
|
|
2921
|
+
/* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2922
|
+
/* @__PURE__ */ jsx20(Text20, { color: "green", bold: true, children: "\u2714" }),
|
|
2923
|
+
/* @__PURE__ */ jsx20(Text20, { bold: true, children: "Authenticated" })
|
|
2648
2924
|
] })
|
|
2649
2925
|
] }),
|
|
2650
|
-
state === "error" && /* @__PURE__ */
|
|
2651
|
-
/* @__PURE__ */
|
|
2652
|
-
/* @__PURE__ */
|
|
2926
|
+
state === "error" && /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2927
|
+
/* @__PURE__ */ jsx20(Text20, { color: "red", children: "\u2716" }),
|
|
2928
|
+
/* @__PURE__ */ jsx20(Text20, { children: errorMessage })
|
|
2653
2929
|
] })
|
|
2654
2930
|
] })
|
|
2655
2931
|
] });
|
|
@@ -2657,70 +2933,70 @@ var AuthLogin = ({ dashboardUrl }) => {
|
|
|
2657
2933
|
|
|
2658
2934
|
// src/components/AuthLogout.tsx
|
|
2659
2935
|
import { useEffect as useEffect9 } from "react";
|
|
2660
|
-
import { Box as
|
|
2661
|
-
import { jsx as
|
|
2936
|
+
import { Box as Box21, Text as Text21, useApp as useApp4 } from "ink";
|
|
2937
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2662
2938
|
var AuthLogout = () => {
|
|
2663
2939
|
const { exit } = useApp4();
|
|
2664
2940
|
useEffect9(() => {
|
|
2665
2941
|
exit();
|
|
2666
2942
|
}, [exit]);
|
|
2667
|
-
return /* @__PURE__ */
|
|
2668
|
-
/* @__PURE__ */
|
|
2669
|
-
/* @__PURE__ */
|
|
2670
|
-
/* @__PURE__ */
|
|
2671
|
-
/* @__PURE__ */
|
|
2943
|
+
return /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", children: [
|
|
2944
|
+
/* @__PURE__ */ jsx21(Banner, {}),
|
|
2945
|
+
/* @__PURE__ */ jsx21(StepShell, { title: "Authenticate with Stackable", children: /* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
|
|
2946
|
+
/* @__PURE__ */ jsx21(Text21, { color: "green", bold: true, children: "\u2714" }),
|
|
2947
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: "Logged out" })
|
|
2672
2948
|
] }) })
|
|
2673
2949
|
] });
|
|
2674
2950
|
};
|
|
2675
2951
|
|
|
2676
2952
|
// src/components/AuthStatus.tsx
|
|
2677
2953
|
import { useEffect as useEffect10 } from "react";
|
|
2678
|
-
import { useApp as useApp5, Box as
|
|
2679
|
-
import { jsx as
|
|
2954
|
+
import { useApp as useApp5, Box as Box22, Text as Text22 } from "ink";
|
|
2955
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2680
2956
|
var AuthStatus = ({ state, userId, orgId, expiry }) => {
|
|
2681
2957
|
const { exit } = useApp5();
|
|
2682
2958
|
useEffect10(() => {
|
|
2683
2959
|
exit();
|
|
2684
2960
|
}, [exit]);
|
|
2685
|
-
return /* @__PURE__ */
|
|
2686
|
-
/* @__PURE__ */
|
|
2687
|
-
/* @__PURE__ */
|
|
2688
|
-
state === "authenticated" && /* @__PURE__ */
|
|
2689
|
-
/* @__PURE__ */
|
|
2690
|
-
/* @__PURE__ */
|
|
2691
|
-
/* @__PURE__ */
|
|
2692
|
-
/* @__PURE__ */
|
|
2961
|
+
return /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", children: [
|
|
2962
|
+
/* @__PURE__ */ jsx22(Banner, {}),
|
|
2963
|
+
/* @__PURE__ */ jsxs21(StepShell, { title: "Authenticate with Stackable", children: [
|
|
2964
|
+
state === "authenticated" && /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", gap: 1, children: [
|
|
2965
|
+
/* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", children: [
|
|
2966
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 2, children: [
|
|
2967
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "User:" }),
|
|
2968
|
+
/* @__PURE__ */ jsx22(Text22, { color: "cyan", children: userId })
|
|
2693
2969
|
] }),
|
|
2694
|
-
/* @__PURE__ */
|
|
2695
|
-
/* @__PURE__ */
|
|
2696
|
-
/* @__PURE__ */
|
|
2970
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 2, children: [
|
|
2971
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "Org: " }),
|
|
2972
|
+
/* @__PURE__ */ jsx22(Text22, { color: "cyan", children: orgId })
|
|
2697
2973
|
] }),
|
|
2698
|
-
expiry && /* @__PURE__ */
|
|
2699
|
-
/* @__PURE__ */
|
|
2700
|
-
/* @__PURE__ */
|
|
2974
|
+
expiry && /* @__PURE__ */ jsxs21(Box22, { gap: 2, children: [
|
|
2975
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "Exp: " }),
|
|
2976
|
+
/* @__PURE__ */ jsx22(Text22, { color: "cyan", children: expiry.toLocaleDateString() })
|
|
2701
2977
|
] })
|
|
2702
2978
|
] }),
|
|
2703
|
-
/* @__PURE__ */
|
|
2704
|
-
/* @__PURE__ */
|
|
2705
|
-
/* @__PURE__ */
|
|
2979
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 1, children: [
|
|
2980
|
+
/* @__PURE__ */ jsx22(Text22, { color: "green", bold: true, children: "\u2714" }),
|
|
2981
|
+
/* @__PURE__ */ jsx22(Text22, { bold: true, children: "Authenticated" })
|
|
2706
2982
|
] })
|
|
2707
2983
|
] }),
|
|
2708
|
-
state === "expired" && /* @__PURE__ */
|
|
2709
|
-
/* @__PURE__ */
|
|
2710
|
-
/* @__PURE__ */
|
|
2711
|
-
/* @__PURE__ */
|
|
2984
|
+
state === "expired" && /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", gap: 1, children: [
|
|
2985
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 1, children: [
|
|
2986
|
+
/* @__PURE__ */ jsx22(Text22, { color: "red", children: "\u2716" }),
|
|
2987
|
+
/* @__PURE__ */ jsxs21(Text22, { children: [
|
|
2712
2988
|
"Session expired",
|
|
2713
2989
|
expiry ? ` (${expiry.toLocaleDateString()})` : ""
|
|
2714
2990
|
] })
|
|
2715
2991
|
] }),
|
|
2716
|
-
/* @__PURE__ */
|
|
2992
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "Run `stackable-app-extension auth login` to re-authenticate." })
|
|
2717
2993
|
] }),
|
|
2718
|
-
state === "not-logged-in" && /* @__PURE__ */
|
|
2719
|
-
/* @__PURE__ */
|
|
2720
|
-
/* @__PURE__ */
|
|
2721
|
-
/* @__PURE__ */
|
|
2994
|
+
state === "not-logged-in" && /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", gap: 1, children: [
|
|
2995
|
+
/* @__PURE__ */ jsxs21(Box22, { gap: 1, children: [
|
|
2996
|
+
/* @__PURE__ */ jsx22(Text22, { color: "red", children: "\u2716" }),
|
|
2997
|
+
/* @__PURE__ */ jsx22(Text22, { children: "Not logged in" })
|
|
2722
2998
|
] }),
|
|
2723
|
-
/* @__PURE__ */
|
|
2999
|
+
/* @__PURE__ */ jsx22(Text22, { dimColor: true, children: "Run `stackable-app-extension auth login`" })
|
|
2724
3000
|
] })
|
|
2725
3001
|
] })
|
|
2726
3002
|
] });
|
|
@@ -2774,7 +3050,7 @@ var checkForUpdate = (currentVersion) => {
|
|
|
2774
3050
|
};
|
|
2775
3051
|
|
|
2776
3052
|
// src/index.tsx
|
|
2777
|
-
import { jsx as
|
|
3053
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2778
3054
|
var require2 = createRequire(import.meta.url);
|
|
2779
3055
|
var { version } = require2("../package.json");
|
|
2780
3056
|
checkForUpdate(version);
|
|
@@ -2787,7 +3063,7 @@ var ensureToken = async () => {
|
|
|
2787
3063
|
const message = err instanceof Error ? err.message : String(err);
|
|
2788
3064
|
const isExpired = message.toLowerCase().includes("expired");
|
|
2789
3065
|
render(
|
|
2790
|
-
/* @__PURE__ */
|
|
3066
|
+
/* @__PURE__ */ jsx23(AuthStatus, { state: isExpired ? "expired" : "not-logged-in" })
|
|
2791
3067
|
);
|
|
2792
3068
|
return null;
|
|
2793
3069
|
}
|
|
@@ -2800,7 +3076,7 @@ program.command("create" /* CREATE */).description("Create a new Extension proje
|
|
|
2800
3076
|
}
|
|
2801
3077
|
const { token, userId, orgId } = auth2;
|
|
2802
3078
|
render(
|
|
2803
|
-
/* @__PURE__ */
|
|
3079
|
+
/* @__PURE__ */ jsx23(
|
|
2804
3080
|
App,
|
|
2805
3081
|
{
|
|
2806
3082
|
command: "create" /* CREATE */,
|
|
@@ -2820,7 +3096,7 @@ program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project
|
|
|
2820
3096
|
}
|
|
2821
3097
|
const { token, userId, orgId } = auth2;
|
|
2822
3098
|
render(
|
|
2823
|
-
/* @__PURE__ */
|
|
3099
|
+
/* @__PURE__ */ jsx23(
|
|
2824
3100
|
App,
|
|
2825
3101
|
{
|
|
2826
3102
|
command: "scaffold" /* SCAFFOLD */,
|
|
@@ -2832,14 +3108,14 @@ program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project
|
|
|
2832
3108
|
)
|
|
2833
3109
|
);
|
|
2834
3110
|
});
|
|
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) => {
|
|
3111
|
+
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
3112
|
const auth2 = await ensureToken();
|
|
2837
3113
|
if (!auth2) {
|
|
2838
3114
|
return;
|
|
2839
3115
|
}
|
|
2840
3116
|
const { token, userId, orgId } = auth2;
|
|
2841
3117
|
render(
|
|
2842
|
-
/* @__PURE__ */
|
|
3118
|
+
/* @__PURE__ */ jsx23(
|
|
2843
3119
|
App,
|
|
2844
3120
|
{
|
|
2845
3121
|
command: "update" /* UPDATE */,
|
|
@@ -2859,7 +3135,7 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
2859
3135
|
}
|
|
2860
3136
|
const { token, userId, orgId } = auth2;
|
|
2861
3137
|
render(
|
|
2862
|
-
/* @__PURE__ */
|
|
3138
|
+
/* @__PURE__ */ jsx23(
|
|
2863
3139
|
DevApp,
|
|
2864
3140
|
{
|
|
2865
3141
|
options,
|
|
@@ -2874,17 +3150,17 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
2874
3150
|
var DASHBOARD_URL = process.env.ADMIN_DASHBOARD_URL ?? "https://admin.stackablelabs.io";
|
|
2875
3151
|
var auth = program.command("auth").description("Manage CLI authentication");
|
|
2876
3152
|
auth.command("login").description("Authenticate with Stackable via browser").action(async () => {
|
|
2877
|
-
render(/* @__PURE__ */
|
|
3153
|
+
render(/* @__PURE__ */ jsx23(AuthLogin, { dashboardUrl: DASHBOARD_URL }));
|
|
2878
3154
|
});
|
|
2879
3155
|
auth.command("logout").description("Clear stored CLI credentials").action(async () => {
|
|
2880
3156
|
await clearAuthState();
|
|
2881
|
-
render(/* @__PURE__ */
|
|
3157
|
+
render(/* @__PURE__ */ jsx23(AuthLogout, {}));
|
|
2882
3158
|
});
|
|
2883
3159
|
auth.command("status").description("Show current authentication status").action(async () => {
|
|
2884
3160
|
const state = await readAuthState();
|
|
2885
3161
|
if (!state) {
|
|
2886
3162
|
render(
|
|
2887
|
-
/* @__PURE__ */
|
|
3163
|
+
/* @__PURE__ */ jsx23(AuthStatus, { state: "not-logged-in" })
|
|
2888
3164
|
);
|
|
2889
3165
|
return;
|
|
2890
3166
|
}
|
|
@@ -2892,11 +3168,11 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
2892
3168
|
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
2893
3169
|
const expiry = payload.exp ? new Date(payload.exp * 1e3) : null;
|
|
2894
3170
|
if (expiry && Date.now() >= expiry.getTime()) {
|
|
2895
|
-
render(/* @__PURE__ */
|
|
3171
|
+
render(/* @__PURE__ */ jsx23(AuthStatus, { state: "expired", expiry }));
|
|
2896
3172
|
return;
|
|
2897
3173
|
}
|
|
2898
3174
|
render(
|
|
2899
|
-
/* @__PURE__ */
|
|
3175
|
+
/* @__PURE__ */ jsx23(
|
|
2900
3176
|
AuthStatus,
|
|
2901
3177
|
{
|
|
2902
3178
|
state: "authenticated",
|
|
@@ -2909,6 +3185,6 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
2909
3185
|
});
|
|
2910
3186
|
var ai = program.command("ai").description("AI editor configuration tools");
|
|
2911
3187
|
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__ */
|
|
3188
|
+
render(/* @__PURE__ */ jsx23(AIScaffold, { version: options.version }));
|
|
2913
3189
|
});
|
|
2914
3190
|
program.parse(process.argv.filter((arg) => arg !== "--"));
|