@stackable-labs/cli-app-extension 1.25.3 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/index.js +444 -289
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,14 +7,48 @@ import { render } from "ink";
|
|
|
7
7
|
|
|
8
8
|
// src/App.tsx
|
|
9
9
|
import { join as join3 } from "path";
|
|
10
|
-
import { Box as
|
|
11
|
-
import { useCallback, useState as
|
|
10
|
+
import { Box as Box14, Text as Text14, useApp } from "ink";
|
|
11
|
+
import { useCallback, useState as useState9 } from "react";
|
|
12
12
|
|
|
13
13
|
// src/components/Confirm.tsx
|
|
14
14
|
import { Box as Box2, Text as Text2, useFocus, useFocusManager, useInput as useInput2 } from "ink";
|
|
15
15
|
import TextInput from "ink-text-input";
|
|
16
16
|
import { useEffect, useState } from "react";
|
|
17
17
|
|
|
18
|
+
// src/constants.ts
|
|
19
|
+
var TEMPLATE_SOURCES = {
|
|
20
|
+
minimal: "github:stackable-labs/templates/app-extension-minimal",
|
|
21
|
+
starter: "github:stackable-labs/templates/app-extension",
|
|
22
|
+
"kitchen-sink": "github:stackable-labs/templates/app-extension-kitchen-sink"
|
|
23
|
+
};
|
|
24
|
+
var DEFAULT_PERMISSIONS = ["context:read"];
|
|
25
|
+
var TEMPLATE_FLAVOR_META = {
|
|
26
|
+
minimal: {
|
|
27
|
+
label: "Minimal",
|
|
28
|
+
description: "Bare minimum \u2014 single surface, hello-world component",
|
|
29
|
+
defaultTargets: ["slot.content"],
|
|
30
|
+
skipTargetStep: true
|
|
31
|
+
},
|
|
32
|
+
starter: {
|
|
33
|
+
label: "Starter",
|
|
34
|
+
description: "Common patterns \u2014 store, api helpers, menu (current default)",
|
|
35
|
+
defaultTargets: null,
|
|
36
|
+
skipTargetStep: false
|
|
37
|
+
},
|
|
38
|
+
"kitchen-sink": {
|
|
39
|
+
label: "Kitchen Sink",
|
|
40
|
+
description: "Everything including the kitchen sink \u2014 every component, capability, surface, and hook we could fit",
|
|
41
|
+
defaultTargets: ["slot.header", "slot.content", "slot.footer", "slot.footer-links"],
|
|
42
|
+
skipTargetStep: true
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var TARGET_PERMISSION_MAP = {
|
|
46
|
+
"slot.header": ["context:read"],
|
|
47
|
+
"slot.content": ["context:read", "data:query", "actions:toast", "actions:invoke"],
|
|
48
|
+
"slot.footer": [],
|
|
49
|
+
"slot.footer-links": []
|
|
50
|
+
};
|
|
51
|
+
|
|
18
52
|
// src/components/StepShell.tsx
|
|
19
53
|
import { Box, Text, useInput } from "ink";
|
|
20
54
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -101,6 +135,7 @@ var VersionRow = ({ currentVersion, value, onChange, onFocusChange, onConfirm, o
|
|
|
101
135
|
var Confirm = ({
|
|
102
136
|
command,
|
|
103
137
|
name,
|
|
138
|
+
templateFlavor,
|
|
104
139
|
extensionVersion,
|
|
105
140
|
extensionPort,
|
|
106
141
|
previewPort,
|
|
@@ -158,6 +193,10 @@ var Confirm = ({
|
|
|
158
193
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Name " }),
|
|
159
194
|
/* @__PURE__ */ jsx2(Text2, { dimColor: !!extensionVersion, children: name })
|
|
160
195
|
] }),
|
|
196
|
+
templateFlavor && /* @__PURE__ */ jsxs2(Box2, { gap: 2, children: [
|
|
197
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Template " }),
|
|
198
|
+
/* @__PURE__ */ jsx2(Text2, { children: TEMPLATE_FLAVOR_META[templateFlavor].label })
|
|
199
|
+
] }),
|
|
161
200
|
extensionVersion && command === "update" /* UPDATE */ && newVersion && onVersionOverride && /* @__PURE__ */ jsx2(
|
|
162
201
|
VersionRow,
|
|
163
202
|
{
|
|
@@ -212,7 +251,12 @@ var Confirm = ({
|
|
|
212
251
|
// src/components/Done.tsx
|
|
213
252
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
214
253
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
215
|
-
var
|
|
254
|
+
var FLAVOR_HINTS = {
|
|
255
|
+
minimal: "A clean slate \u2014 add surfaces and capabilities as you need them.",
|
|
256
|
+
starter: "Common patterns included \u2014 customize and build from here.",
|
|
257
|
+
"kitchen-sink": "We threw in everything \u2014 including the kitchen sink. Poke around, steal patterns, then delete what you don't need."
|
|
258
|
+
};
|
|
259
|
+
var Done = ({ name, outputDir, templateFlavor }) => /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", gap: 1, children: [
|
|
216
260
|
/* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
|
|
217
261
|
/* @__PURE__ */ jsx3(Text3, { color: "green", bold: true, children: "\u2714" }),
|
|
218
262
|
/* @__PURE__ */ jsx3(Text3, { bold: true, children: "Extension scaffolded successfully!" })
|
|
@@ -222,11 +266,16 @@ var Done = ({ name, outputDir }) => /* @__PURE__ */ jsxs3(Box3, { flexDirection:
|
|
|
222
266
|
"Created: ",
|
|
223
267
|
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: name })
|
|
224
268
|
] }),
|
|
269
|
+
templateFlavor && /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
270
|
+
"Template: ",
|
|
271
|
+
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: TEMPLATE_FLAVOR_META[templateFlavor].label })
|
|
272
|
+
] }),
|
|
225
273
|
/* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
226
274
|
"Location: ",
|
|
227
275
|
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: outputDir })
|
|
228
276
|
] })
|
|
229
277
|
] }),
|
|
278
|
+
templateFlavor && /* @__PURE__ */ jsx3(Box3, { marginLeft: 2, children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: FLAVOR_HINTS[templateFlavor] }) }),
|
|
230
279
|
/* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "green", paddingX: 2, paddingY: 1, children: [
|
|
231
280
|
/* @__PURE__ */ jsx3(Text3, { bold: true, children: "Next steps:" }),
|
|
232
281
|
/* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, gap: 1, children: [
|
|
@@ -744,10 +793,52 @@ var TargetSelect = ({ availableTargets, preSelected, onSubmit, onBack }) => {
|
|
|
744
793
|
);
|
|
745
794
|
};
|
|
746
795
|
|
|
796
|
+
// src/components/TemplateSelect.tsx
|
|
797
|
+
import { Box as Box10, Text as Text10, useInput as useInput6 } from "ink";
|
|
798
|
+
import { useState as useState6 } from "react";
|
|
799
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
800
|
+
var FLAVORS = ["minimal", "starter", "kitchen-sink"];
|
|
801
|
+
var TemplateSelect = ({ onSubmit, onBack }) => {
|
|
802
|
+
const [cursor, setCursor] = useState6(1);
|
|
803
|
+
useInput6((_input, key) => {
|
|
804
|
+
if (key.upArrow) {
|
|
805
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
if (key.downArrow) {
|
|
809
|
+
setCursor((c) => Math.min(FLAVORS.length - 1, c + 1));
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
if (key.return) {
|
|
813
|
+
onSubmit(FLAVORS[cursor]);
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
return /* @__PURE__ */ jsx10(
|
|
817
|
+
StepShell,
|
|
818
|
+
{
|
|
819
|
+
title: "Choose a template",
|
|
820
|
+
hint: "\u2191\u2193 to navigate, Enter to select",
|
|
821
|
+
onBack,
|
|
822
|
+
children: /* @__PURE__ */ jsx10(Box10, { flexDirection: "column", gap: 1, children: FLAVORS.map((flavor, i) => {
|
|
823
|
+
const meta = TEMPLATE_FLAVOR_META[flavor];
|
|
824
|
+
const isCursor = i === cursor;
|
|
825
|
+
return /* @__PURE__ */ jsxs10(Box10, { gap: 1, children: [
|
|
826
|
+
/* @__PURE__ */ jsx10(Text10, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
827
|
+
/* @__PURE__ */ jsx10(Text10, { color: isCursor ? "green" : void 0, children: isCursor ? "\u25C9" : "\u25CB" }),
|
|
828
|
+
/* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
|
|
829
|
+
/* @__PURE__ */ jsx10(Text10, { bold: isCursor, children: meta.label }),
|
|
830
|
+
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: meta.description })
|
|
831
|
+
] })
|
|
832
|
+
] }, flavor);
|
|
833
|
+
}) })
|
|
834
|
+
}
|
|
835
|
+
);
|
|
836
|
+
};
|
|
837
|
+
|
|
747
838
|
// src/components/AppSelect.tsx
|
|
748
|
-
import { Box as
|
|
839
|
+
import { Box as Box12, Text as Text12, useInput as useInput7 } from "ink";
|
|
749
840
|
import Spinner2 from "ink-spinner";
|
|
750
|
-
import { useEffect as useEffect2, useState as
|
|
841
|
+
import { useEffect as useEffect2, useState as useState7 } from "react";
|
|
751
842
|
|
|
752
843
|
// src/lib/api.ts
|
|
753
844
|
var DEFAULT_ADMIN_API_URL = "https://api-use1.stackablelabs.io/admin";
|
|
@@ -775,7 +866,7 @@ var fetchApps = async (token) => {
|
|
|
775
866
|
iconUrl
|
|
776
867
|
}));
|
|
777
868
|
};
|
|
778
|
-
var createExtensionRemote = async (
|
|
869
|
+
var createExtensionRemote = async (token, appId, payload) => {
|
|
779
870
|
const baseUrl = getAdminApiBaseUrl();
|
|
780
871
|
const res = await fetch(`${baseUrl}/app-extension/${appId}/extensions`, {
|
|
781
872
|
method: "POST",
|
|
@@ -788,7 +879,7 @@ var createExtensionRemote = async (appId, token, payload) => {
|
|
|
788
879
|
}
|
|
789
880
|
return res.json();
|
|
790
881
|
};
|
|
791
|
-
var fetchExtensions = async (
|
|
882
|
+
var fetchExtensions = async (token, appId) => {
|
|
792
883
|
const baseUrl = getAdminApiBaseUrl();
|
|
793
884
|
const res = await fetch(`${baseUrl}/app-extension/${appId}/extensions`, {
|
|
794
885
|
headers: authHeaders(token)
|
|
@@ -810,7 +901,7 @@ var fetchExtensions = async (appId, token) => {
|
|
|
810
901
|
])
|
|
811
902
|
);
|
|
812
903
|
};
|
|
813
|
-
var updateExtension = async (appId, extensionId, payload
|
|
904
|
+
var updateExtension = async (token, appId, extensionId, payload) => {
|
|
814
905
|
const baseUrl = getAdminApiBaseUrl();
|
|
815
906
|
const res = await fetch(`${baseUrl}/app-extension/${appId}/extensions/${extensionId}`, {
|
|
816
907
|
method: "PUT",
|
|
@@ -824,8 +915,8 @@ var updateExtension = async (appId, extensionId, payload, token) => {
|
|
|
824
915
|
};
|
|
825
916
|
|
|
826
917
|
// src/components/Banner.tsx
|
|
827
|
-
import { Box as
|
|
828
|
-
import { jsx as
|
|
918
|
+
import { Box as Box11, Text as Text11 } from "ink";
|
|
919
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
829
920
|
var WORDMARK = [
|
|
830
921
|
" _ _ _ _ ",
|
|
831
922
|
" ___| |_ __ _ ___| | ____ _| |__ | | ___",
|
|
@@ -861,18 +952,18 @@ var gradientColor = (row, col, rows, cols) => {
|
|
|
861
952
|
var Banner = ({ userId, orgId } = {}) => {
|
|
862
953
|
const termWidth = process.stdout.columns ?? 80;
|
|
863
954
|
const maxLen = Math.max(...WORDMARK.map((l) => l.length));
|
|
864
|
-
return /* @__PURE__ */
|
|
865
|
-
/* @__PURE__ */
|
|
866
|
-
/* @__PURE__ */
|
|
867
|
-
WORDMARK.map((line, row) => /* @__PURE__ */
|
|
868
|
-
userId && orgId && /* @__PURE__ */
|
|
869
|
-
/* @__PURE__ */
|
|
870
|
-
/* @__PURE__ */
|
|
871
|
-
/* @__PURE__ */
|
|
955
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
956
|
+
/* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "\u2500".repeat(termWidth) }),
|
|
957
|
+
/* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [
|
|
958
|
+
WORDMARK.map((line, row) => /* @__PURE__ */ jsx11(Box11, { children: line.split("").map((ch, col) => /* @__PURE__ */ jsx11(Text11, { bold: true, color: ch === " " ? void 0 : gradientColor(row, col, WORDMARK.length, maxLen), children: ch }, col)) }, row)),
|
|
959
|
+
userId && orgId && /* @__PURE__ */ jsxs11(Box11, { gap: 2, marginTop: 1, children: [
|
|
960
|
+
/* @__PURE__ */ jsxs11(Box11, { gap: 1, children: [
|
|
961
|
+
/* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "User:" }),
|
|
962
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: userId })
|
|
872
963
|
] }),
|
|
873
|
-
/* @__PURE__ */
|
|
874
|
-
/* @__PURE__ */
|
|
875
|
-
/* @__PURE__ */
|
|
964
|
+
/* @__PURE__ */ jsxs11(Box11, { gap: 1, children: [
|
|
965
|
+
/* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "Org:" }),
|
|
966
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: orgId })
|
|
876
967
|
] })
|
|
877
968
|
] })
|
|
878
969
|
] })
|
|
@@ -880,16 +971,16 @@ var Banner = ({ userId, orgId } = {}) => {
|
|
|
880
971
|
};
|
|
881
972
|
|
|
882
973
|
// src/components/AppSelect.tsx
|
|
883
|
-
import { jsx as
|
|
974
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
884
975
|
var AppSelect = ({ token, userId, orgId, onSubmit }) => {
|
|
885
|
-
const [apps, setApps] =
|
|
886
|
-
const [loading, setLoading] =
|
|
887
|
-
const [error, setError] =
|
|
888
|
-
const [cursor, setCursor] =
|
|
976
|
+
const [apps, setApps] = useState7([]);
|
|
977
|
+
const [loading, setLoading] = useState7(true);
|
|
978
|
+
const [error, setError] = useState7();
|
|
979
|
+
const [cursor, setCursor] = useState7(0);
|
|
889
980
|
useEffect2(() => {
|
|
890
981
|
fetchApps(token).then(setApps).catch((err) => setError(err instanceof Error ? err.message : String(err))).finally(() => setLoading(false));
|
|
891
982
|
}, [token]);
|
|
892
|
-
|
|
983
|
+
useInput7((_, key) => {
|
|
893
984
|
if (loading || error || apps.length === 0) return;
|
|
894
985
|
if (key.upArrow) {
|
|
895
986
|
setCursor((c) => Math.max(0, c - 1));
|
|
@@ -901,26 +992,26 @@ var AppSelect = ({ token, userId, orgId, onSubmit }) => {
|
|
|
901
992
|
});
|
|
902
993
|
const renderContent = () => {
|
|
903
994
|
if (loading) {
|
|
904
|
-
return /* @__PURE__ */
|
|
905
|
-
/* @__PURE__ */
|
|
906
|
-
/* @__PURE__ */
|
|
995
|
+
return /* @__PURE__ */ jsxs12(Box12, { gap: 2, children: [
|
|
996
|
+
/* @__PURE__ */ jsx12(Spinner2, { type: "dots" }),
|
|
997
|
+
/* @__PURE__ */ jsx12(Text12, { children: "Loading available Apps\u2026" })
|
|
907
998
|
] });
|
|
908
999
|
}
|
|
909
1000
|
if (error) {
|
|
910
|
-
return /* @__PURE__ */
|
|
911
|
-
/* @__PURE__ */
|
|
912
|
-
/* @__PURE__ */
|
|
1001
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", gap: 1, children: [
|
|
1002
|
+
/* @__PURE__ */ jsx12(Text12, { color: "red", bold: true, children: "Failed to load Apps" }),
|
|
1003
|
+
/* @__PURE__ */ jsx12(Text12, { color: "red", children: error })
|
|
913
1004
|
] });
|
|
914
1005
|
}
|
|
915
1006
|
if (apps.length === 0) {
|
|
916
|
-
return /* @__PURE__ */
|
|
1007
|
+
return /* @__PURE__ */ jsx12(Text12, { color: "yellow", children: "No Apps available. Contact your administrator." });
|
|
917
1008
|
}
|
|
918
|
-
return /* @__PURE__ */
|
|
1009
|
+
return /* @__PURE__ */ jsx12(Box12, { flexDirection: "column", children: apps.map((app, i) => {
|
|
919
1010
|
const isCursor = i === cursor;
|
|
920
|
-
return /* @__PURE__ */
|
|
921
|
-
/* @__PURE__ */
|
|
922
|
-
/* @__PURE__ */
|
|
923
|
-
/* @__PURE__ */
|
|
1011
|
+
return /* @__PURE__ */ jsxs12(Box12, { gap: 1, children: [
|
|
1012
|
+
/* @__PURE__ */ jsx12(Text12, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
1013
|
+
/* @__PURE__ */ jsx12(Text12, { bold: isCursor, children: app.name }),
|
|
1014
|
+
/* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
924
1015
|
"(",
|
|
925
1016
|
app.id,
|
|
926
1017
|
")"
|
|
@@ -928,26 +1019,26 @@ var AppSelect = ({ token, userId, orgId, onSubmit }) => {
|
|
|
928
1019
|
] }, app.id);
|
|
929
1020
|
}) });
|
|
930
1021
|
};
|
|
931
|
-
return /* @__PURE__ */
|
|
932
|
-
/* @__PURE__ */
|
|
933
|
-
/* @__PURE__ */
|
|
1022
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
|
|
1023
|
+
/* @__PURE__ */ jsx12(Banner, { userId, orgId }),
|
|
1024
|
+
/* @__PURE__ */ jsx12(StepShell, { title: "Select the App you are building an Extension for:", children: renderContent() })
|
|
934
1025
|
] });
|
|
935
1026
|
};
|
|
936
1027
|
|
|
937
1028
|
// src/components/ExtensionSelect.tsx
|
|
938
|
-
import { Box as
|
|
1029
|
+
import { Box as Box13, Text as Text13, useInput as useInput8 } from "ink";
|
|
939
1030
|
import Spinner3 from "ink-spinner";
|
|
940
|
-
import { useEffect as useEffect3, useState as
|
|
941
|
-
import { jsx as
|
|
1031
|
+
import { useEffect as useEffect3, useState as useState8 } from "react";
|
|
1032
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
942
1033
|
var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
943
|
-
const [extensions, setExtensions] =
|
|
944
|
-
const [loading, setLoading] =
|
|
945
|
-
const [error, setError] =
|
|
946
|
-
const [cursor, setCursor] =
|
|
1034
|
+
const [extensions, setExtensions] = useState8([]);
|
|
1035
|
+
const [loading, setLoading] = useState8(true);
|
|
1036
|
+
const [error, setError] = useState8();
|
|
1037
|
+
const [cursor, setCursor] = useState8(0);
|
|
947
1038
|
useEffect3(() => {
|
|
948
|
-
fetchExtensions(
|
|
1039
|
+
fetchExtensions(token, appId).then((byId) => setExtensions(Object.values(byId))).catch((err) => setError(err instanceof Error ? err.message : String(err))).finally(() => setLoading(false));
|
|
949
1040
|
}, [appId, token]);
|
|
950
|
-
|
|
1041
|
+
useInput8((_, key) => {
|
|
951
1042
|
if (key.upArrow) {
|
|
952
1043
|
if (!loading && !error && extensions.length > 0) {
|
|
953
1044
|
setCursor((c) => Math.max(0, c - 1));
|
|
@@ -968,30 +1059,30 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
|
968
1059
|
});
|
|
969
1060
|
const renderContent = () => {
|
|
970
1061
|
if (loading) {
|
|
971
|
-
return /* @__PURE__ */
|
|
972
|
-
/* @__PURE__ */
|
|
973
|
-
/* @__PURE__ */
|
|
1062
|
+
return /* @__PURE__ */ jsxs13(Box13, { gap: 2, children: [
|
|
1063
|
+
/* @__PURE__ */ jsx13(Spinner3, { type: "dots" }),
|
|
1064
|
+
/* @__PURE__ */ jsx13(Text13, { children: "Loading Extensions\u2026" })
|
|
974
1065
|
] });
|
|
975
1066
|
}
|
|
976
1067
|
if (error) {
|
|
977
|
-
return /* @__PURE__ */
|
|
978
|
-
/* @__PURE__ */
|
|
979
|
-
/* @__PURE__ */
|
|
1068
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", gap: 1, children: [
|
|
1069
|
+
/* @__PURE__ */ jsx13(Text13, { color: "red", bold: true, children: "Failed to load Extensions" }),
|
|
1070
|
+
/* @__PURE__ */ jsx13(Text13, { color: "red", children: error })
|
|
980
1071
|
] });
|
|
981
1072
|
}
|
|
982
1073
|
if (extensions.length === 0) {
|
|
983
|
-
return /* @__PURE__ */
|
|
1074
|
+
return /* @__PURE__ */ jsx13(Text13, { color: "yellow", children: "No Extensions found for this App." });
|
|
984
1075
|
}
|
|
985
|
-
return /* @__PURE__ */
|
|
1076
|
+
return /* @__PURE__ */ jsx13(Box13, { flexDirection: "column", children: extensions.map((ext, i) => {
|
|
986
1077
|
const isCursor = i === cursor;
|
|
987
|
-
return /* @__PURE__ */
|
|
988
|
-
/* @__PURE__ */
|
|
989
|
-
/* @__PURE__ */
|
|
990
|
-
/* @__PURE__ */
|
|
1078
|
+
return /* @__PURE__ */ jsxs13(Box13, { gap: 1, children: [
|
|
1079
|
+
/* @__PURE__ */ jsx13(Text13, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
1080
|
+
/* @__PURE__ */ jsx13(Text13, { bold: isCursor, children: ext.manifest.name }),
|
|
1081
|
+
/* @__PURE__ */ jsxs13(Text13, { dimColor: true, children: [
|
|
991
1082
|
"v",
|
|
992
1083
|
ext.manifest.version
|
|
993
1084
|
] }),
|
|
994
|
-
/* @__PURE__ */
|
|
1085
|
+
/* @__PURE__ */ jsxs13(Text13, { dimColor: true, children: [
|
|
995
1086
|
"(",
|
|
996
1087
|
ext.id,
|
|
997
1088
|
")"
|
|
@@ -999,7 +1090,7 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
|
999
1090
|
] }, ext.id);
|
|
1000
1091
|
}) });
|
|
1001
1092
|
};
|
|
1002
|
-
return /* @__PURE__ */
|
|
1093
|
+
return /* @__PURE__ */ jsx13(
|
|
1003
1094
|
StepShell,
|
|
1004
1095
|
{
|
|
1005
1096
|
title: command === "update" /* UPDATE */ ? "Select an Extension to update:" : "Select an existing Extension to scaffold:",
|
|
@@ -1009,16 +1100,6 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
|
1009
1100
|
);
|
|
1010
1101
|
};
|
|
1011
1102
|
|
|
1012
|
-
// src/constants.ts
|
|
1013
|
-
var TEMPLATE_SOURCE = "github:stackable-labs/templates/app-extension";
|
|
1014
|
-
var DEFAULT_PERMISSIONS = ["context:read"];
|
|
1015
|
-
var TARGET_PERMISSION_MAP = {
|
|
1016
|
-
"slot.header": ["context:read"],
|
|
1017
|
-
"slot.content": ["context:read", "data:query", "actions:toast", "actions:invoke"],
|
|
1018
|
-
"slot.footer": [],
|
|
1019
|
-
"slot.footer-links": []
|
|
1020
|
-
};
|
|
1021
|
-
|
|
1022
1103
|
// src/lib/postScaffold.ts
|
|
1023
1104
|
import { execFile } from "child_process";
|
|
1024
1105
|
import { promisify } from "util";
|
|
@@ -1444,28 +1525,33 @@ var updateGitignore = async (dir) => {
|
|
|
1444
1525
|
}
|
|
1445
1526
|
};
|
|
1446
1527
|
var scaffold = async (options) => {
|
|
1447
|
-
const
|
|
1528
|
+
const flavor = options.templateFlavor ?? "starter";
|
|
1529
|
+
const templateSource = TEMPLATE_SOURCES[flavor];
|
|
1530
|
+
const { dir } = await downloadTemplate(templateSource, {
|
|
1448
1531
|
dir: options.outputDir,
|
|
1449
1532
|
force: true
|
|
1450
1533
|
});
|
|
1451
|
-
const selectedTargets = normalizeTargets(options.targets);
|
|
1452
|
-
const derivedPermissions = derivePermissions(selectedTargets);
|
|
1453
1534
|
await replacePlaceholders(dir, {
|
|
1454
1535
|
"__EXTENSION_ID__": toKebabCase(options.extensionId || options.name),
|
|
1455
1536
|
"__EXTENSION_DISPLAY_NAME__": options.name,
|
|
1456
1537
|
"replace-with-extension-name": toKebabCase(options.name),
|
|
1457
1538
|
"replace-with-extension-package-name": `@agnostack/extensions-${toKebabCase(options.extensionId || options.name)}`
|
|
1458
1539
|
});
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1540
|
+
if (flavor === "starter") {
|
|
1541
|
+
const selectedTargets = normalizeTargets(options.targets);
|
|
1542
|
+
const derivedPermissions = derivePermissions(selectedTargets);
|
|
1543
|
+
await generateManifest(dir, options.name, selectedTargets, derivedPermissions);
|
|
1544
|
+
await generateSurfaceFiles(dir, selectedTargets);
|
|
1545
|
+
await rewriteExtensionIndex(dir, options.extensionId || options.name, selectedTargets);
|
|
1546
|
+
await rewritePreviewApp(dir, selectedTargets, derivedPermissions);
|
|
1547
|
+
}
|
|
1463
1548
|
await rewriteTurboJson(dir);
|
|
1464
1549
|
await patchViteAllowedHosts(dir);
|
|
1465
1550
|
await writeEnvFile2(dir, options.extensionPort, options.previewPort);
|
|
1466
1551
|
await updateGitignore(dir);
|
|
1467
1552
|
await writeDevContext(dir, {
|
|
1468
1553
|
projectRoot: dir,
|
|
1554
|
+
orgId: null,
|
|
1469
1555
|
appId: options.appId,
|
|
1470
1556
|
extensionId: toKebabCase(options.extensionId || options.name),
|
|
1471
1557
|
appName: options.appName || null,
|
|
@@ -1477,9 +1563,9 @@ var scaffold = async (options) => {
|
|
|
1477
1563
|
};
|
|
1478
1564
|
|
|
1479
1565
|
// src/App.tsx
|
|
1480
|
-
import { jsx as
|
|
1566
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1481
1567
|
var STEPS = {
|
|
1482
|
-
["create" /* CREATE */]: ["app", "name", "targets", "settings", "confirm"],
|
|
1568
|
+
["create" /* CREATE */]: ["app", "name", "template", "targets", "settings", "confirm"],
|
|
1483
1569
|
["scaffold" /* SCAFFOLD */]: ["app", "extensionSelect", "confirmTargets", "settings", "confirm"],
|
|
1484
1570
|
["update" /* UPDATE */]: ["app", "extensionSelect", "updateSettings", "confirm"],
|
|
1485
1571
|
["dev" /* DEV */]: []
|
|
@@ -1523,30 +1609,33 @@ var derivePermissions2 = (targets) => {
|
|
|
1523
1609
|
};
|
|
1524
1610
|
var App = ({ command, token, userId, orgId, initialName, initialExtensionId, options }) => {
|
|
1525
1611
|
const { exit } = useApp();
|
|
1526
|
-
const [step, setStep] =
|
|
1527
|
-
const [name, setName] =
|
|
1528
|
-
const [extensionId, setExtensionId] =
|
|
1529
|
-
const [extensionVersion, setExtensionVersion] =
|
|
1530
|
-
const [bundleUrl, setBundleUrl] =
|
|
1531
|
-
const [enabled, setEnabled] =
|
|
1612
|
+
const [step, setStep] = useState9("app");
|
|
1613
|
+
const [name, setName] = useState9(initialName ?? options?.name ?? "");
|
|
1614
|
+
const [extensionId, setExtensionId] = useState9(initialExtensionId ?? "");
|
|
1615
|
+
const [extensionVersion, setExtensionVersion] = useState9("");
|
|
1616
|
+
const [bundleUrl, setBundleUrl] = useState9(options?.bundleUrl ?? "");
|
|
1617
|
+
const [enabled, setEnabled] = useState9(
|
|
1532
1618
|
options?.enabled !== void 0 ? options.enabled !== "false" : true
|
|
1533
1619
|
);
|
|
1534
|
-
const [versionOverride, setVersionOverride] =
|
|
1535
|
-
const [forceMajor, setForceMajor] =
|
|
1536
|
-
const [initialExtension, setInitialExtension] =
|
|
1537
|
-
const [
|
|
1620
|
+
const [versionOverride, setVersionOverride] = useState9(void 0);
|
|
1621
|
+
const [forceMajor, setForceMajor] = useState9(false);
|
|
1622
|
+
const [initialExtension, setInitialExtension] = useState9(null);
|
|
1623
|
+
const [templateFlavor, setTemplateFlavor] = useState9(
|
|
1624
|
+
options?.template ?? "starter"
|
|
1625
|
+
);
|
|
1626
|
+
const [targets, setTargets] = useState9(
|
|
1538
1627
|
options?.targets ? options.targets.split(",").map((t) => t.trim()) : []
|
|
1539
1628
|
);
|
|
1540
|
-
const [selectedApp, setSelectedApp] =
|
|
1541
|
-
const [extensionPort, setExtensionPort] =
|
|
1629
|
+
const [selectedApp, setSelectedApp] = useState9(null);
|
|
1630
|
+
const [extensionPort, setExtensionPort] = useState9(
|
|
1542
1631
|
options?.extensionPort ? parseInt(options.extensionPort, 10) : 6543
|
|
1543
1632
|
);
|
|
1544
|
-
const [previewPort, setPreviewPort] =
|
|
1633
|
+
const [previewPort, setPreviewPort] = useState9(
|
|
1545
1634
|
options?.previewPort ? parseInt(options.previewPort, 10) : 6544
|
|
1546
1635
|
);
|
|
1547
|
-
const [outputDir, setOutputDir] =
|
|
1548
|
-
const [progressSteps, setProgressSteps] =
|
|
1549
|
-
const [errorMessage, setErrorMessage] =
|
|
1636
|
+
const [outputDir, setOutputDir] = useState9("");
|
|
1637
|
+
const [progressSteps, setProgressSteps] = useState9(PROGRESS_STEPS[command]);
|
|
1638
|
+
const [errorMessage, setErrorMessage] = useState9();
|
|
1550
1639
|
const updateStep = useCallback((index, status) => {
|
|
1551
1640
|
setProgressSteps((prev) => prev.map((s, i) => i === index ? { ...s, status } : s));
|
|
1552
1641
|
}, []);
|
|
@@ -1554,6 +1643,10 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1554
1643
|
const base = STEPS[command];
|
|
1555
1644
|
const skipped = /* @__PURE__ */ new Set();
|
|
1556
1645
|
if (command === "create" /* CREATE */ && initialName) skipped.add("name");
|
|
1646
|
+
if (command === "create" /* CREATE */ && options?.template) skipped.add("template");
|
|
1647
|
+
if (command === "create" /* CREATE */ && TEMPLATE_FLAVOR_META[templateFlavor].skipTargetStep) {
|
|
1648
|
+
skipped.add("targets");
|
|
1649
|
+
}
|
|
1557
1650
|
if (options?.extensionPort || options?.previewPort) skipped.add("settings");
|
|
1558
1651
|
if (command === "update" /* UPDATE */) {
|
|
1559
1652
|
if (options?.appId) skipped.add("app");
|
|
@@ -1564,6 +1657,8 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1564
1657
|
command,
|
|
1565
1658
|
initialName,
|
|
1566
1659
|
initialExtensionId,
|
|
1660
|
+
templateFlavor,
|
|
1661
|
+
options?.template,
|
|
1567
1662
|
options?.extensionPort,
|
|
1568
1663
|
options?.previewPort,
|
|
1569
1664
|
options?.appId
|
|
@@ -1581,7 +1676,26 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1581
1676
|
setStep("extensionSelect");
|
|
1582
1677
|
return;
|
|
1583
1678
|
}
|
|
1584
|
-
|
|
1679
|
+
if (initialName) {
|
|
1680
|
+
if (options?.template) {
|
|
1681
|
+
const meta = TEMPLATE_FLAVOR_META[templateFlavor];
|
|
1682
|
+
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
1683
|
+
setTargets(meta.defaultTargets);
|
|
1684
|
+
if (options?.extensionPort || options?.previewPort) {
|
|
1685
|
+
setOutputDir(join3(process.cwd(), toKebabCase2(initialName)));
|
|
1686
|
+
setStep("confirm");
|
|
1687
|
+
} else {
|
|
1688
|
+
setStep("settings");
|
|
1689
|
+
}
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
setStep("targets");
|
|
1693
|
+
} else {
|
|
1694
|
+
setStep("template");
|
|
1695
|
+
}
|
|
1696
|
+
} else {
|
|
1697
|
+
setStep("name");
|
|
1698
|
+
}
|
|
1585
1699
|
};
|
|
1586
1700
|
const handleExtensionSelect = (ext) => {
|
|
1587
1701
|
setName(ext.manifest.name);
|
|
@@ -1613,6 +1727,36 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1613
1727
|
const handleName = (value) => {
|
|
1614
1728
|
setName(value);
|
|
1615
1729
|
setExtensionId(toKebabCase2(value));
|
|
1730
|
+
if (options?.template) {
|
|
1731
|
+
const meta = TEMPLATE_FLAVOR_META[templateFlavor];
|
|
1732
|
+
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
1733
|
+
setTargets(meta.defaultTargets);
|
|
1734
|
+
if (options?.extensionPort || options?.previewPort) {
|
|
1735
|
+
setOutputDir(join3(process.cwd(), toKebabCase2(value)));
|
|
1736
|
+
setStep("confirm");
|
|
1737
|
+
} else {
|
|
1738
|
+
setStep("settings");
|
|
1739
|
+
}
|
|
1740
|
+
return;
|
|
1741
|
+
}
|
|
1742
|
+
setStep("targets");
|
|
1743
|
+
} else {
|
|
1744
|
+
setStep("template");
|
|
1745
|
+
}
|
|
1746
|
+
};
|
|
1747
|
+
const handleTemplateSelect = (flavor) => {
|
|
1748
|
+
setTemplateFlavor(flavor);
|
|
1749
|
+
const meta = TEMPLATE_FLAVOR_META[flavor];
|
|
1750
|
+
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
1751
|
+
setTargets(meta.defaultTargets);
|
|
1752
|
+
if (options?.extensionPort || options?.previewPort) {
|
|
1753
|
+
setOutputDir(join3(process.cwd(), toKebabCase2(extensionId || name)));
|
|
1754
|
+
setStep("confirm");
|
|
1755
|
+
} else {
|
|
1756
|
+
setStep("settings");
|
|
1757
|
+
}
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1616
1760
|
setStep("targets");
|
|
1617
1761
|
};
|
|
1618
1762
|
const handleTargets = (value) => {
|
|
@@ -1649,7 +1793,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1649
1793
|
try {
|
|
1650
1794
|
updateStep(0, "running");
|
|
1651
1795
|
const resolvedVersion = options?.setVersion ?? versionOverride ?? computeVersionBump(extensionVersion, name, targets, bundleUrl, forceMajor);
|
|
1652
|
-
await updateExtension(selectedApp.id, extensionId, {
|
|
1796
|
+
await updateExtension(token, selectedApp.id, extensionId, {
|
|
1653
1797
|
manifest: {
|
|
1654
1798
|
name,
|
|
1655
1799
|
version: resolvedVersion,
|
|
@@ -1659,7 +1803,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1659
1803
|
},
|
|
1660
1804
|
bundleUrl: bundleUrl || void 0,
|
|
1661
1805
|
enabled
|
|
1662
|
-
}
|
|
1806
|
+
});
|
|
1663
1807
|
updateStep(0, "done");
|
|
1664
1808
|
setExtensionVersion(resolvedVersion);
|
|
1665
1809
|
setStep("updateDone");
|
|
@@ -1678,7 +1822,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1678
1822
|
if (command === "create" /* CREATE */) {
|
|
1679
1823
|
scaffoldStepOffset = 1;
|
|
1680
1824
|
updateStep(0, "running");
|
|
1681
|
-
const created = await createExtensionRemote(selectedApp.id, {
|
|
1825
|
+
const created = await createExtensionRemote(token, selectedApp.id, {
|
|
1682
1826
|
manifest: {
|
|
1683
1827
|
name,
|
|
1684
1828
|
version: "0.0.0",
|
|
@@ -1687,7 +1831,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1687
1831
|
allowedDomains: []
|
|
1688
1832
|
},
|
|
1689
1833
|
bundleUrl: `http://localhost:${extensionPort}`
|
|
1690
|
-
}
|
|
1834
|
+
});
|
|
1691
1835
|
resolvedExtensionId = created.id;
|
|
1692
1836
|
setExtensionId(created.id);
|
|
1693
1837
|
updateStep(0, "done");
|
|
@@ -1699,6 +1843,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1699
1843
|
name,
|
|
1700
1844
|
extensionId: resolvedExtensionId,
|
|
1701
1845
|
targets,
|
|
1846
|
+
templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0,
|
|
1702
1847
|
outputDir,
|
|
1703
1848
|
extensionPort,
|
|
1704
1849
|
previewPort
|
|
@@ -1726,7 +1871,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1726
1871
|
};
|
|
1727
1872
|
switch (step) {
|
|
1728
1873
|
case "app": {
|
|
1729
|
-
return /* @__PURE__ */
|
|
1874
|
+
return /* @__PURE__ */ jsx14(
|
|
1730
1875
|
AppSelect,
|
|
1731
1876
|
{
|
|
1732
1877
|
token,
|
|
@@ -1737,7 +1882,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1737
1882
|
);
|
|
1738
1883
|
}
|
|
1739
1884
|
case "extensionSelect": {
|
|
1740
|
-
return /* @__PURE__ */
|
|
1885
|
+
return /* @__PURE__ */ jsx14(
|
|
1741
1886
|
ExtensionSelect,
|
|
1742
1887
|
{
|
|
1743
1888
|
appId: selectedApp.id,
|
|
@@ -1749,7 +1894,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1749
1894
|
);
|
|
1750
1895
|
}
|
|
1751
1896
|
case "confirmTargets": {
|
|
1752
|
-
return /* @__PURE__ */
|
|
1897
|
+
return /* @__PURE__ */ jsx14(
|
|
1753
1898
|
TargetSelect,
|
|
1754
1899
|
{
|
|
1755
1900
|
availableTargets: selectedApp?.targets ?? [],
|
|
@@ -1760,7 +1905,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1760
1905
|
);
|
|
1761
1906
|
}
|
|
1762
1907
|
case "name": {
|
|
1763
|
-
return /* @__PURE__ */
|
|
1908
|
+
return /* @__PURE__ */ jsx14(
|
|
1764
1909
|
NamePrompt,
|
|
1765
1910
|
{
|
|
1766
1911
|
initialValue: name,
|
|
@@ -1769,8 +1914,17 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1769
1914
|
}
|
|
1770
1915
|
);
|
|
1771
1916
|
}
|
|
1917
|
+
case "template": {
|
|
1918
|
+
return /* @__PURE__ */ jsx14(
|
|
1919
|
+
TemplateSelect,
|
|
1920
|
+
{
|
|
1921
|
+
onSubmit: handleTemplateSelect,
|
|
1922
|
+
onBack: goBack
|
|
1923
|
+
}
|
|
1924
|
+
);
|
|
1925
|
+
}
|
|
1772
1926
|
case "targets": {
|
|
1773
|
-
return /* @__PURE__ */
|
|
1927
|
+
return /* @__PURE__ */ jsx14(
|
|
1774
1928
|
TargetSelect,
|
|
1775
1929
|
{
|
|
1776
1930
|
availableTargets: selectedApp?.targets ?? [],
|
|
@@ -1780,7 +1934,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1780
1934
|
);
|
|
1781
1935
|
}
|
|
1782
1936
|
case "settings": {
|
|
1783
|
-
return /* @__PURE__ */
|
|
1937
|
+
return /* @__PURE__ */ jsx14(
|
|
1784
1938
|
SettingsPrompt,
|
|
1785
1939
|
{
|
|
1786
1940
|
defaultDir: join3(process.cwd(), toKebabCase2(extensionId || name)),
|
|
@@ -1790,11 +1944,12 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1790
1944
|
);
|
|
1791
1945
|
}
|
|
1792
1946
|
case "confirm": {
|
|
1793
|
-
return /* @__PURE__ */
|
|
1947
|
+
return /* @__PURE__ */ jsx14(
|
|
1794
1948
|
Confirm,
|
|
1795
1949
|
{
|
|
1796
1950
|
command,
|
|
1797
1951
|
name,
|
|
1952
|
+
templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0,
|
|
1798
1953
|
targets,
|
|
1799
1954
|
outputDir,
|
|
1800
1955
|
previewPort,
|
|
@@ -1811,10 +1966,10 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1811
1966
|
);
|
|
1812
1967
|
}
|
|
1813
1968
|
case "scaffolding": {
|
|
1814
|
-
return /* @__PURE__ */
|
|
1969
|
+
return /* @__PURE__ */ jsx14(ScaffoldProgress, { steps: progressSteps });
|
|
1815
1970
|
}
|
|
1816
1971
|
case "updateSettings": {
|
|
1817
|
-
return /* @__PURE__ */
|
|
1972
|
+
return /* @__PURE__ */ jsx14(
|
|
1818
1973
|
UpdateSettingsPrompt,
|
|
1819
1974
|
{
|
|
1820
1975
|
name,
|
|
@@ -1836,46 +1991,46 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1836
1991
|
);
|
|
1837
1992
|
}
|
|
1838
1993
|
case "updating": {
|
|
1839
|
-
return /* @__PURE__ */
|
|
1994
|
+
return /* @__PURE__ */ jsx14(ScaffoldProgress, { steps: progressSteps });
|
|
1840
1995
|
}
|
|
1841
1996
|
case "updateDone": {
|
|
1842
|
-
return /* @__PURE__ */
|
|
1843
|
-
/* @__PURE__ */
|
|
1844
|
-
/* @__PURE__ */
|
|
1997
|
+
return /* @__PURE__ */ jsx14(StepShell, { title: "Extension updated", onBack: goBack, children: /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", gap: 1, children: [
|
|
1998
|
+
/* @__PURE__ */ jsx14(Text14, { color: "green", bold: true, children: "Extension updated successfully!" }),
|
|
1999
|
+
/* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
|
|
1845
2000
|
"Name: ",
|
|
1846
2001
|
name
|
|
1847
2002
|
] }),
|
|
1848
|
-
/* @__PURE__ */
|
|
2003
|
+
/* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
|
|
1849
2004
|
"ID: ",
|
|
1850
2005
|
extensionId
|
|
1851
2006
|
] }),
|
|
1852
|
-
/* @__PURE__ */
|
|
2007
|
+
/* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
|
|
1853
2008
|
"Version: ",
|
|
1854
2009
|
extensionVersion
|
|
1855
2010
|
] })
|
|
1856
2011
|
] }) });
|
|
1857
2012
|
}
|
|
1858
2013
|
case "done": {
|
|
1859
|
-
return /* @__PURE__ */
|
|
2014
|
+
return /* @__PURE__ */ jsx14(Done, { name, outputDir, templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0 });
|
|
1860
2015
|
}
|
|
1861
2016
|
case "error": {
|
|
1862
|
-
return /* @__PURE__ */
|
|
1863
|
-
/* @__PURE__ */
|
|
1864
|
-
errorMessage && /* @__PURE__ */
|
|
2017
|
+
return /* @__PURE__ */ jsx14(StepShell, { title: "Operation failed", onBack: goBack, children: /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", gap: 1, children: [
|
|
2018
|
+
/* @__PURE__ */ jsx14(Text14, { color: "red", bold: true, children: "An error occurred" }),
|
|
2019
|
+
errorMessage && /* @__PURE__ */ jsx14(Text14, { color: "red", children: errorMessage })
|
|
1865
2020
|
] }) });
|
|
1866
2021
|
}
|
|
1867
2022
|
default: {
|
|
1868
|
-
return /* @__PURE__ */
|
|
1869
|
-
/* @__PURE__ */
|
|
1870
|
-
errorMessage && /* @__PURE__ */
|
|
2023
|
+
return /* @__PURE__ */ jsx14(StepShell, { title: "Scaffold failed", onBack: goBack, children: /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", gap: 1, children: [
|
|
2024
|
+
/* @__PURE__ */ jsx14(Text14, { color: "red", bold: true, children: "An error occurred" }),
|
|
2025
|
+
errorMessage && /* @__PURE__ */ jsx14(Text14, { color: "red", children: errorMessage })
|
|
1871
2026
|
] }) });
|
|
1872
2027
|
}
|
|
1873
2028
|
}
|
|
1874
2029
|
};
|
|
1875
2030
|
|
|
1876
2031
|
// src/components/DevApp.tsx
|
|
1877
|
-
import { useRef, useState as
|
|
1878
|
-
import { useInput as
|
|
2032
|
+
import { useRef, useState as useState11, useEffect as useEffect6, useCallback as useCallback2 } from "react";
|
|
2033
|
+
import { useInput as useInput10, Box as Box17, Text as Text17 } from "ink";
|
|
1879
2034
|
|
|
1880
2035
|
// src/lib/tunnel.ts
|
|
1881
2036
|
import { Tunnel } from "cloudflared";
|
|
@@ -1909,12 +2064,12 @@ var startDevServer = (projectRoot) => {
|
|
|
1909
2064
|
};
|
|
1910
2065
|
|
|
1911
2066
|
// src/components/DevSetup.tsx
|
|
1912
|
-
import { Box as
|
|
1913
|
-
import { useState as
|
|
1914
|
-
import { jsx as
|
|
2067
|
+
import { Box as Box15, Text as Text15 } from "ink";
|
|
2068
|
+
import { useState as useState10, useEffect as useEffect4 } from "react";
|
|
2069
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1915
2070
|
var DevSetup = ({ initialContext, token, onReady }) => {
|
|
1916
|
-
const [step, setStep] =
|
|
1917
|
-
const [selectedApp, setSelectedApp] =
|
|
2071
|
+
const [step, setStep] = useState10("app");
|
|
2072
|
+
const [selectedApp, setSelectedApp] = useState10(null);
|
|
1918
2073
|
useEffect4(() => {
|
|
1919
2074
|
if (initialContext.appId) {
|
|
1920
2075
|
setStep("extension");
|
|
@@ -1932,9 +2087,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
1932
2087
|
});
|
|
1933
2088
|
};
|
|
1934
2089
|
if (step === "app") {
|
|
1935
|
-
return /* @__PURE__ */
|
|
1936
|
-
/* @__PURE__ */
|
|
1937
|
-
/* @__PURE__ */
|
|
2090
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
2091
|
+
/* @__PURE__ */ jsx15(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsx15(Text15, { children: "Select the App for your extension:" }) }),
|
|
2092
|
+
/* @__PURE__ */ jsx15(
|
|
1938
2093
|
AppSelect,
|
|
1939
2094
|
{
|
|
1940
2095
|
token,
|
|
@@ -1943,9 +2098,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
1943
2098
|
)
|
|
1944
2099
|
] });
|
|
1945
2100
|
}
|
|
1946
|
-
return /* @__PURE__ */
|
|
1947
|
-
/* @__PURE__ */
|
|
1948
|
-
/* @__PURE__ */
|
|
2101
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
2102
|
+
/* @__PURE__ */ jsx15(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsx15(Text15, { children: "Select the Extension to develop:" }) }),
|
|
2103
|
+
/* @__PURE__ */ jsx15(
|
|
1949
2104
|
ExtensionSelect,
|
|
1950
2105
|
{
|
|
1951
2106
|
token,
|
|
@@ -1957,9 +2112,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
1957
2112
|
};
|
|
1958
2113
|
|
|
1959
2114
|
// src/components/DevDashboard.tsx
|
|
1960
|
-
import { Box as
|
|
2115
|
+
import { Box as Box16, Text as Text16, useInput as useInput9 } from "ink";
|
|
1961
2116
|
import { useEffect as useEffect5 } from "react";
|
|
1962
|
-
import { jsx as
|
|
2117
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1963
2118
|
var DevDashboard = ({
|
|
1964
2119
|
previewTunnelUrl,
|
|
1965
2120
|
tunnelUrl,
|
|
@@ -1982,68 +2137,68 @@ var DevDashboard = ({
|
|
|
1982
2137
|
process.off("SIGINT", handler);
|
|
1983
2138
|
};
|
|
1984
2139
|
}, [onQuit]);
|
|
1985
|
-
|
|
2140
|
+
useInput9((input, key) => {
|
|
1986
2141
|
if (input === "q" || key.ctrl && input === "c") {
|
|
1987
2142
|
onQuit();
|
|
1988
2143
|
}
|
|
1989
2144
|
});
|
|
1990
|
-
return /* @__PURE__ */
|
|
1991
|
-
/* @__PURE__ */
|
|
1992
|
-
/* @__PURE__ */
|
|
2145
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
2146
|
+
/* @__PURE__ */ jsx16(Banner, { userId, orgId }),
|
|
2147
|
+
/* @__PURE__ */ jsxs16(
|
|
1993
2148
|
StepShell,
|
|
1994
2149
|
{
|
|
1995
2150
|
title: "dev",
|
|
1996
2151
|
hint: `Live development ${tunnelUrl ? "with" : "w/o"} Tunnel`,
|
|
1997
|
-
footer: /* @__PURE__ */
|
|
2152
|
+
footer: /* @__PURE__ */ jsx16(Box16, { flexDirection: "column", gap: 1, children: /* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "Press q or Ctrl-C to quit" }) }),
|
|
1998
2153
|
children: [
|
|
1999
|
-
/* @__PURE__ */
|
|
2000
|
-
/* @__PURE__ */
|
|
2001
|
-
/* @__PURE__ */
|
|
2002
|
-
/* @__PURE__ */
|
|
2154
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
2155
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 2, children: [
|
|
2156
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "Extension:" }),
|
|
2157
|
+
/* @__PURE__ */ jsxs16(Text16, { children: [
|
|
2003
2158
|
extensionName,
|
|
2004
2159
|
" (",
|
|
2005
2160
|
extensionId,
|
|
2006
2161
|
")"
|
|
2007
2162
|
] })
|
|
2008
2163
|
] }),
|
|
2009
|
-
/* @__PURE__ */
|
|
2010
|
-
/* @__PURE__ */
|
|
2011
|
-
/* @__PURE__ */
|
|
2164
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 2, children: [
|
|
2165
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "App:" }),
|
|
2166
|
+
/* @__PURE__ */ jsx16(Text16, { children: `${appName ? `${appName} ` : ""}(${appId})` })
|
|
2012
2167
|
] }),
|
|
2013
|
-
/* @__PURE__ */
|
|
2014
|
-
/* @__PURE__ */
|
|
2015
|
-
/* @__PURE__ */
|
|
2168
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 2, children: [
|
|
2169
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "Bundle URL:" }),
|
|
2170
|
+
/* @__PURE__ */ jsx16(Text16, { children: tunnelUrl || `http://localhost:${extensionPort}` })
|
|
2016
2171
|
] })
|
|
2017
2172
|
] }),
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
previewTunnelUrl && /* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2021
|
-
/* @__PURE__ */
|
|
2173
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
2174
|
+
previewTunnelUrl && /* @__PURE__ */ jsxs16(Box16, { gap: 2, children: [
|
|
2175
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "Tunnel Dev - Preview:" }),
|
|
2176
|
+
/* @__PURE__ */ jsx16(Text16, { children: previewTunnelUrl })
|
|
2022
2177
|
] }),
|
|
2023
|
-
/* @__PURE__ */
|
|
2024
|
-
/* @__PURE__ */
|
|
2025
|
-
/* @__PURE__ */
|
|
2178
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 2, children: [
|
|
2179
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "Local Dev - Preview:" }),
|
|
2180
|
+
/* @__PURE__ */ jsxs16(Text16, { children: [
|
|
2026
2181
|
"http://localhost:",
|
|
2027
2182
|
previewPort
|
|
2028
2183
|
] })
|
|
2029
2184
|
] })
|
|
2030
2185
|
] }),
|
|
2031
|
-
/* @__PURE__ */
|
|
2032
|
-
tunnelUrl && /* @__PURE__ */
|
|
2033
|
-
/* @__PURE__ */
|
|
2034
|
-
/* @__PURE__ */
|
|
2186
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
2187
|
+
tunnelUrl && /* @__PURE__ */ jsxs16(Box16, { gap: 2, children: [
|
|
2188
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "Tunnel Dev - Extension:" }),
|
|
2189
|
+
/* @__PURE__ */ jsx16(Text16, { children: tunnelUrl })
|
|
2035
2190
|
] }),
|
|
2036
|
-
/* @__PURE__ */
|
|
2037
|
-
/* @__PURE__ */
|
|
2038
|
-
/* @__PURE__ */
|
|
2191
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 2, children: [
|
|
2192
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "Local Dev - Extension:" }),
|
|
2193
|
+
/* @__PURE__ */ jsxs16(Text16, { children: [
|
|
2039
2194
|
"http://localhost:",
|
|
2040
2195
|
extensionPort
|
|
2041
2196
|
] })
|
|
2042
2197
|
] })
|
|
2043
2198
|
] }),
|
|
2044
|
-
/* @__PURE__ */
|
|
2045
|
-
/* @__PURE__ */
|
|
2046
|
-
/* @__PURE__ */
|
|
2199
|
+
/* @__PURE__ */ jsx16(Box16, { flexDirection: "column", children: tunnelUrl && /* @__PURE__ */ jsxs16(Box16, { gap: 2, children: [
|
|
2200
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "Host Dev - Query Param:" }),
|
|
2201
|
+
/* @__PURE__ */ jsxs16(Text16, { children: [
|
|
2047
2202
|
"?_stackable_dev=",
|
|
2048
2203
|
encodeURIComponent(`${extensionId}:${tunnelUrl}`)
|
|
2049
2204
|
] })
|
|
@@ -2055,16 +2210,16 @@ var DevDashboard = ({
|
|
|
2055
2210
|
};
|
|
2056
2211
|
|
|
2057
2212
|
// src/components/DevApp.tsx
|
|
2058
|
-
import { jsx as
|
|
2213
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
2059
2214
|
var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
2060
|
-
const [state, setState] =
|
|
2061
|
-
const [devContext, setDevContext] =
|
|
2062
|
-
const [resolvedContext, setResolvedContext] =
|
|
2063
|
-
const [tunnelUrl, setTunnelUrl] =
|
|
2064
|
-
const [previewTunnelUrl, setPreviewTunnelUrl] =
|
|
2065
|
-
const [tunnelHandle, setTunnelHandle] =
|
|
2066
|
-
const [previewTunnelHandle, setPreviewTunnelHandle] =
|
|
2067
|
-
const [devServerHandle, setDevServerHandle] =
|
|
2215
|
+
const [state, setState] = useState11("setup");
|
|
2216
|
+
const [devContext, setDevContext] = useState11(null);
|
|
2217
|
+
const [resolvedContext, setResolvedContext] = useState11(null);
|
|
2218
|
+
const [tunnelUrl, setTunnelUrl] = useState11(null);
|
|
2219
|
+
const [previewTunnelUrl, setPreviewTunnelUrl] = useState11(null);
|
|
2220
|
+
const [tunnelHandle, setTunnelHandle] = useState11(null);
|
|
2221
|
+
const [previewTunnelHandle, setPreviewTunnelHandle] = useState11(null);
|
|
2222
|
+
const [devServerHandle, setDevServerHandle] = useState11(null);
|
|
2068
2223
|
const shuttingDown = useRef(false);
|
|
2069
2224
|
const useTunnel = options.tunnel !== false;
|
|
2070
2225
|
useEffect6(() => {
|
|
@@ -2149,7 +2304,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2149
2304
|
console.log("[dev] Done");
|
|
2150
2305
|
process.exit(0);
|
|
2151
2306
|
};
|
|
2152
|
-
|
|
2307
|
+
useInput10((input, key) => {
|
|
2153
2308
|
if (input === "c" && key.ctrl) {
|
|
2154
2309
|
if (state === "running") {
|
|
2155
2310
|
handleQuit();
|
|
@@ -2160,7 +2315,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2160
2315
|
});
|
|
2161
2316
|
if (state === "setup" && devContext) {
|
|
2162
2317
|
if (!devContext.appId || !devContext.extensionId) {
|
|
2163
|
-
return /* @__PURE__ */
|
|
2318
|
+
return /* @__PURE__ */ jsx17(
|
|
2164
2319
|
DevSetup,
|
|
2165
2320
|
{
|
|
2166
2321
|
token,
|
|
@@ -2172,7 +2327,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2172
2327
|
return null;
|
|
2173
2328
|
}
|
|
2174
2329
|
if (state === "running" && devContext && resolvedContext) {
|
|
2175
|
-
return /* @__PURE__ */
|
|
2330
|
+
return /* @__PURE__ */ jsx17(
|
|
2176
2331
|
DevDashboard,
|
|
2177
2332
|
{
|
|
2178
2333
|
previewTunnelUrl,
|
|
@@ -2192,13 +2347,13 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2192
2347
|
if (state === "stopping") {
|
|
2193
2348
|
return null;
|
|
2194
2349
|
}
|
|
2195
|
-
return /* @__PURE__ */
|
|
2350
|
+
return /* @__PURE__ */ jsx17(Box17, { children: /* @__PURE__ */ jsx17(Text17, { children: "Loading..." }) });
|
|
2196
2351
|
};
|
|
2197
2352
|
|
|
2198
2353
|
// src/components/AIScaffold.tsx
|
|
2199
|
-
import { Box as
|
|
2354
|
+
import { Box as Box18, Text as Text18, useApp as useApp2 } from "ink";
|
|
2200
2355
|
import Spinner4 from "ink-spinner";
|
|
2201
|
-
import { useState as
|
|
2356
|
+
import { useState as useState12, useEffect as useEffect7 } from "react";
|
|
2202
2357
|
|
|
2203
2358
|
// src/lib/aiDocs.ts
|
|
2204
2359
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -2251,12 +2406,12 @@ var downloadAndExtractAiDocs = async (targetDir, version2) => {
|
|
|
2251
2406
|
};
|
|
2252
2407
|
|
|
2253
2408
|
// src/components/AIScaffold.tsx
|
|
2254
|
-
import { jsx as
|
|
2409
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2255
2410
|
var AIScaffold = ({ version: version2 }) => {
|
|
2256
2411
|
const { exit } = useApp2();
|
|
2257
|
-
const [state, setState] =
|
|
2258
|
-
const [files, setFiles] =
|
|
2259
|
-
const [errorMessage, setErrorMessage] =
|
|
2412
|
+
const [state, setState] = useState12("validating");
|
|
2413
|
+
const [files, setFiles] = useState12([]);
|
|
2414
|
+
const [errorMessage, setErrorMessage] = useState12("");
|
|
2260
2415
|
useEffect7(() => {
|
|
2261
2416
|
const run = async () => {
|
|
2262
2417
|
const projectDir = process.cwd();
|
|
@@ -2280,35 +2435,35 @@ var AIScaffold = ({ version: version2 }) => {
|
|
|
2280
2435
|
};
|
|
2281
2436
|
run();
|
|
2282
2437
|
}, []);
|
|
2283
|
-
return /* @__PURE__ */
|
|
2284
|
-
/* @__PURE__ */
|
|
2285
|
-
/* @__PURE__ */
|
|
2286
|
-
state === "validating" && /* @__PURE__ */
|
|
2287
|
-
/* @__PURE__ */
|
|
2288
|
-
/* @__PURE__ */
|
|
2438
|
+
return /* @__PURE__ */ jsxs17(Box18, { flexDirection: "column", children: [
|
|
2439
|
+
/* @__PURE__ */ jsx18(Banner, {}),
|
|
2440
|
+
/* @__PURE__ */ jsxs17(StepShell, { title: "AI Editor Config", children: [
|
|
2441
|
+
state === "validating" && /* @__PURE__ */ jsxs17(Box18, { gap: 1, children: [
|
|
2442
|
+
/* @__PURE__ */ jsx18(Text18, { color: "cyan", children: /* @__PURE__ */ jsx18(Spinner4, { type: "dots" }) }),
|
|
2443
|
+
/* @__PURE__ */ jsx18(Text18, { children: "Checking project..." })
|
|
2289
2444
|
] }),
|
|
2290
|
-
state === "downloading" && /* @__PURE__ */
|
|
2291
|
-
/* @__PURE__ */
|
|
2292
|
-
/* @__PURE__ */
|
|
2445
|
+
state === "downloading" && /* @__PURE__ */ jsxs17(Box18, { gap: 1, children: [
|
|
2446
|
+
/* @__PURE__ */ jsx18(Text18, { color: "cyan", children: /* @__PURE__ */ jsx18(Spinner4, { type: "dots" }) }),
|
|
2447
|
+
/* @__PURE__ */ jsxs17(Text18, { children: [
|
|
2293
2448
|
"Downloading AI editor configs (",
|
|
2294
2449
|
version2,
|
|
2295
2450
|
")..."
|
|
2296
2451
|
] })
|
|
2297
2452
|
] }),
|
|
2298
|
-
state === "done" && /* @__PURE__ */
|
|
2299
|
-
/* @__PURE__ */
|
|
2300
|
-
/* @__PURE__ */
|
|
2301
|
-
/* @__PURE__ */
|
|
2453
|
+
state === "done" && /* @__PURE__ */ jsxs17(Box18, { flexDirection: "column", gap: 1, children: [
|
|
2454
|
+
/* @__PURE__ */ jsxs17(Box18, { gap: 1, children: [
|
|
2455
|
+
/* @__PURE__ */ jsx18(Text18, { color: "green", bold: true, children: "\u2714" }),
|
|
2456
|
+
/* @__PURE__ */ jsxs17(Text18, { bold: true, children: [
|
|
2302
2457
|
"AI editor configs installed (",
|
|
2303
2458
|
files.length,
|
|
2304
2459
|
" files)"
|
|
2305
2460
|
] })
|
|
2306
2461
|
] }),
|
|
2307
|
-
/* @__PURE__ */
|
|
2462
|
+
/* @__PURE__ */ jsx18(Box18, { flexDirection: "column", marginLeft: 2, children: files.map((f) => /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: f }, f)) })
|
|
2308
2463
|
] }),
|
|
2309
|
-
state === "error" && /* @__PURE__ */
|
|
2310
|
-
/* @__PURE__ */
|
|
2311
|
-
/* @__PURE__ */
|
|
2464
|
+
state === "error" && /* @__PURE__ */ jsxs17(Box18, { gap: 1, children: [
|
|
2465
|
+
/* @__PURE__ */ jsx18(Text18, { color: "red", children: "\u2716" }),
|
|
2466
|
+
/* @__PURE__ */ jsx18(Text18, { children: errorMessage })
|
|
2312
2467
|
] })
|
|
2313
2468
|
] })
|
|
2314
2469
|
] });
|
|
@@ -2316,10 +2471,10 @@ var AIScaffold = ({ version: version2 }) => {
|
|
|
2316
2471
|
|
|
2317
2472
|
// src/components/AuthLogin.tsx
|
|
2318
2473
|
import { createServer } from "http";
|
|
2319
|
-
import { Box as
|
|
2474
|
+
import { Box as Box19, Text as Text19, useApp as useApp3 } from "ink";
|
|
2320
2475
|
import Spinner5 from "ink-spinner";
|
|
2321
2476
|
import open from "open";
|
|
2322
|
-
import { useState as
|
|
2477
|
+
import { useState as useState13, useEffect as useEffect8 } from "react";
|
|
2323
2478
|
|
|
2324
2479
|
// src/lib/auth.ts
|
|
2325
2480
|
import { readFile as readFile3, writeFile as writeFile4, mkdir as mkdir2, unlink } from "fs/promises";
|
|
@@ -2372,7 +2527,7 @@ var getToken = async () => {
|
|
|
2372
2527
|
};
|
|
2373
2528
|
|
|
2374
2529
|
// src/components/AuthLogin.tsx
|
|
2375
|
-
import { jsx as
|
|
2530
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2376
2531
|
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
2377
2532
|
var callbackPage = (heading, sub, redirectUrl) => `<!DOCTYPE html>
|
|
2378
2533
|
<html><head><meta charset="utf-8"><title>Stackable CLI</title>
|
|
@@ -2383,11 +2538,11 @@ ${redirectUrl ? `<script>(function(){var s=3,el=document.getElementById('h');fun
|
|
|
2383
2538
|
</body></html>`;
|
|
2384
2539
|
var AuthLogin = ({ dashboardUrl }) => {
|
|
2385
2540
|
const { exit } = useApp3();
|
|
2386
|
-
const [state, setState] =
|
|
2387
|
-
const [loginUrl, setLoginUrl] =
|
|
2388
|
-
const [userIdLabel, setUserIdLabel] =
|
|
2389
|
-
const [orgIdLabel, setOrgIdLabel] =
|
|
2390
|
-
const [errorMessage, setErrorMessage] =
|
|
2541
|
+
const [state, setState] = useState13("waiting");
|
|
2542
|
+
const [loginUrl, setLoginUrl] = useState13("");
|
|
2543
|
+
const [userIdLabel, setUserIdLabel] = useState13("");
|
|
2544
|
+
const [orgIdLabel, setOrgIdLabel] = useState13("");
|
|
2545
|
+
const [errorMessage, setErrorMessage] = useState13("");
|
|
2391
2546
|
useEffect8(() => {
|
|
2392
2547
|
let server;
|
|
2393
2548
|
let timeout;
|
|
@@ -2463,38 +2618,38 @@ var AuthLogin = ({ dashboardUrl }) => {
|
|
|
2463
2618
|
server?.close();
|
|
2464
2619
|
};
|
|
2465
2620
|
}, []);
|
|
2466
|
-
return /* @__PURE__ */
|
|
2467
|
-
/* @__PURE__ */
|
|
2468
|
-
/* @__PURE__ */
|
|
2469
|
-
state === "waiting" && /* @__PURE__ */
|
|
2470
|
-
/* @__PURE__ */
|
|
2471
|
-
/* @__PURE__ */
|
|
2472
|
-
/* @__PURE__ */
|
|
2621
|
+
return /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", children: [
|
|
2622
|
+
/* @__PURE__ */ jsx19(Banner, {}),
|
|
2623
|
+
/* @__PURE__ */ jsxs18(StepShell, { title: "Authenticate with Stackable", children: [
|
|
2624
|
+
state === "waiting" && /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", gap: 1, children: [
|
|
2625
|
+
/* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2626
|
+
/* @__PURE__ */ jsx19(Text19, { color: "cyan", children: /* @__PURE__ */ jsx19(Spinner5, { type: "dots" }) }),
|
|
2627
|
+
/* @__PURE__ */ jsx19(Text19, { children: "Waiting for browser authentication..." })
|
|
2473
2628
|
] }),
|
|
2474
|
-
loginUrl && /* @__PURE__ */
|
|
2629
|
+
loginUrl && /* @__PURE__ */ jsxs18(Text19, { dimColor: true, children: [
|
|
2475
2630
|
" ",
|
|
2476
2631
|
loginUrl
|
|
2477
2632
|
] })
|
|
2478
2633
|
] }),
|
|
2479
|
-
state === "success" && /* @__PURE__ */
|
|
2480
|
-
/* @__PURE__ */
|
|
2481
|
-
/* @__PURE__ */
|
|
2482
|
-
/* @__PURE__ */
|
|
2483
|
-
/* @__PURE__ */
|
|
2634
|
+
state === "success" && /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", gap: 1, children: [
|
|
2635
|
+
/* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", children: [
|
|
2636
|
+
/* @__PURE__ */ jsxs18(Box19, { gap: 2, children: [
|
|
2637
|
+
/* @__PURE__ */ jsx19(Text19, { dimColor: true, children: "User:" }),
|
|
2638
|
+
/* @__PURE__ */ jsx19(Text19, { color: "cyan", children: userIdLabel })
|
|
2484
2639
|
] }),
|
|
2485
|
-
/* @__PURE__ */
|
|
2486
|
-
/* @__PURE__ */
|
|
2487
|
-
/* @__PURE__ */
|
|
2640
|
+
/* @__PURE__ */ jsxs18(Box19, { gap: 2, children: [
|
|
2641
|
+
/* @__PURE__ */ jsx19(Text19, { dimColor: true, children: "Org: " }),
|
|
2642
|
+
/* @__PURE__ */ jsx19(Text19, { color: "cyan", children: orgIdLabel })
|
|
2488
2643
|
] })
|
|
2489
2644
|
] }),
|
|
2490
|
-
/* @__PURE__ */
|
|
2491
|
-
/* @__PURE__ */
|
|
2492
|
-
/* @__PURE__ */
|
|
2645
|
+
/* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2646
|
+
/* @__PURE__ */ jsx19(Text19, { color: "green", bold: true, children: "\u2714" }),
|
|
2647
|
+
/* @__PURE__ */ jsx19(Text19, { bold: true, children: "Authenticated" })
|
|
2493
2648
|
] })
|
|
2494
2649
|
] }),
|
|
2495
|
-
state === "error" && /* @__PURE__ */
|
|
2496
|
-
/* @__PURE__ */
|
|
2497
|
-
/* @__PURE__ */
|
|
2650
|
+
state === "error" && /* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
2651
|
+
/* @__PURE__ */ jsx19(Text19, { color: "red", children: "\u2716" }),
|
|
2652
|
+
/* @__PURE__ */ jsx19(Text19, { children: errorMessage })
|
|
2498
2653
|
] })
|
|
2499
2654
|
] })
|
|
2500
2655
|
] });
|
|
@@ -2502,70 +2657,70 @@ var AuthLogin = ({ dashboardUrl }) => {
|
|
|
2502
2657
|
|
|
2503
2658
|
// src/components/AuthLogout.tsx
|
|
2504
2659
|
import { useEffect as useEffect9 } from "react";
|
|
2505
|
-
import { Box as
|
|
2506
|
-
import { jsx as
|
|
2660
|
+
import { Box as Box20, Text as Text20, useApp as useApp4 } from "ink";
|
|
2661
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2507
2662
|
var AuthLogout = () => {
|
|
2508
2663
|
const { exit } = useApp4();
|
|
2509
2664
|
useEffect9(() => {
|
|
2510
2665
|
exit();
|
|
2511
2666
|
}, [exit]);
|
|
2512
|
-
return /* @__PURE__ */
|
|
2513
|
-
/* @__PURE__ */
|
|
2514
|
-
/* @__PURE__ */
|
|
2515
|
-
/* @__PURE__ */
|
|
2516
|
-
/* @__PURE__ */
|
|
2667
|
+
return /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", children: [
|
|
2668
|
+
/* @__PURE__ */ jsx20(Banner, {}),
|
|
2669
|
+
/* @__PURE__ */ jsx20(StepShell, { title: "Authenticate with Stackable", children: /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2670
|
+
/* @__PURE__ */ jsx20(Text20, { color: "green", bold: true, children: "\u2714" }),
|
|
2671
|
+
/* @__PURE__ */ jsx20(Text20, { bold: true, children: "Logged out" })
|
|
2517
2672
|
] }) })
|
|
2518
2673
|
] });
|
|
2519
2674
|
};
|
|
2520
2675
|
|
|
2521
2676
|
// src/components/AuthStatus.tsx
|
|
2522
2677
|
import { useEffect as useEffect10 } from "react";
|
|
2523
|
-
import { useApp as useApp5, Box as
|
|
2524
|
-
import { jsx as
|
|
2678
|
+
import { useApp as useApp5, Box as Box21, Text as Text21 } from "ink";
|
|
2679
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2525
2680
|
var AuthStatus = ({ state, userId, orgId, expiry }) => {
|
|
2526
2681
|
const { exit } = useApp5();
|
|
2527
2682
|
useEffect10(() => {
|
|
2528
2683
|
exit();
|
|
2529
2684
|
}, [exit]);
|
|
2530
|
-
return /* @__PURE__ */
|
|
2531
|
-
/* @__PURE__ */
|
|
2532
|
-
/* @__PURE__ */
|
|
2533
|
-
state === "authenticated" && /* @__PURE__ */
|
|
2534
|
-
/* @__PURE__ */
|
|
2535
|
-
/* @__PURE__ */
|
|
2536
|
-
/* @__PURE__ */
|
|
2537
|
-
/* @__PURE__ */
|
|
2685
|
+
return /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", children: [
|
|
2686
|
+
/* @__PURE__ */ jsx21(Banner, {}),
|
|
2687
|
+
/* @__PURE__ */ jsxs20(StepShell, { title: "Authenticate with Stackable", children: [
|
|
2688
|
+
state === "authenticated" && /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", gap: 1, children: [
|
|
2689
|
+
/* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", children: [
|
|
2690
|
+
/* @__PURE__ */ jsxs20(Box21, { gap: 2, children: [
|
|
2691
|
+
/* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "User:" }),
|
|
2692
|
+
/* @__PURE__ */ jsx21(Text21, { color: "cyan", children: userId })
|
|
2538
2693
|
] }),
|
|
2539
|
-
/* @__PURE__ */
|
|
2540
|
-
/* @__PURE__ */
|
|
2541
|
-
/* @__PURE__ */
|
|
2694
|
+
/* @__PURE__ */ jsxs20(Box21, { gap: 2, children: [
|
|
2695
|
+
/* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "Org: " }),
|
|
2696
|
+
/* @__PURE__ */ jsx21(Text21, { color: "cyan", children: orgId })
|
|
2542
2697
|
] }),
|
|
2543
|
-
expiry && /* @__PURE__ */
|
|
2544
|
-
/* @__PURE__ */
|
|
2545
|
-
/* @__PURE__ */
|
|
2698
|
+
expiry && /* @__PURE__ */ jsxs20(Box21, { gap: 2, children: [
|
|
2699
|
+
/* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "Exp: " }),
|
|
2700
|
+
/* @__PURE__ */ jsx21(Text21, { color: "cyan", children: expiry.toLocaleDateString() })
|
|
2546
2701
|
] })
|
|
2547
2702
|
] }),
|
|
2548
|
-
/* @__PURE__ */
|
|
2549
|
-
/* @__PURE__ */
|
|
2550
|
-
/* @__PURE__ */
|
|
2703
|
+
/* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
|
|
2704
|
+
/* @__PURE__ */ jsx21(Text21, { color: "green", bold: true, children: "\u2714" }),
|
|
2705
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: "Authenticated" })
|
|
2551
2706
|
] })
|
|
2552
2707
|
] }),
|
|
2553
|
-
state === "expired" && /* @__PURE__ */
|
|
2554
|
-
/* @__PURE__ */
|
|
2555
|
-
/* @__PURE__ */
|
|
2556
|
-
/* @__PURE__ */
|
|
2708
|
+
state === "expired" && /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", gap: 1, children: [
|
|
2709
|
+
/* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
|
|
2710
|
+
/* @__PURE__ */ jsx21(Text21, { color: "red", children: "\u2716" }),
|
|
2711
|
+
/* @__PURE__ */ jsxs20(Text21, { children: [
|
|
2557
2712
|
"Session expired",
|
|
2558
2713
|
expiry ? ` (${expiry.toLocaleDateString()})` : ""
|
|
2559
2714
|
] })
|
|
2560
2715
|
] }),
|
|
2561
|
-
/* @__PURE__ */
|
|
2716
|
+
/* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "Run `stackable-app-extension auth login` to re-authenticate." })
|
|
2562
2717
|
] }),
|
|
2563
|
-
state === "not-logged-in" && /* @__PURE__ */
|
|
2564
|
-
/* @__PURE__ */
|
|
2565
|
-
/* @__PURE__ */
|
|
2566
|
-
/* @__PURE__ */
|
|
2718
|
+
state === "not-logged-in" && /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", gap: 1, children: [
|
|
2719
|
+
/* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
|
|
2720
|
+
/* @__PURE__ */ jsx21(Text21, { color: "red", children: "\u2716" }),
|
|
2721
|
+
/* @__PURE__ */ jsx21(Text21, { children: "Not logged in" })
|
|
2567
2722
|
] }),
|
|
2568
|
-
/* @__PURE__ */
|
|
2723
|
+
/* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "Run `stackable-app-extension auth login`" })
|
|
2569
2724
|
] })
|
|
2570
2725
|
] })
|
|
2571
2726
|
] });
|
|
@@ -2619,7 +2774,7 @@ var checkForUpdate = (currentVersion) => {
|
|
|
2619
2774
|
};
|
|
2620
2775
|
|
|
2621
2776
|
// src/index.tsx
|
|
2622
|
-
import { jsx as
|
|
2777
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
2623
2778
|
var require2 = createRequire(import.meta.url);
|
|
2624
2779
|
var { version } = require2("../package.json");
|
|
2625
2780
|
checkForUpdate(version);
|
|
@@ -2632,20 +2787,20 @@ var ensureToken = async () => {
|
|
|
2632
2787
|
const message = err instanceof Error ? err.message : String(err);
|
|
2633
2788
|
const isExpired = message.toLowerCase().includes("expired");
|
|
2634
2789
|
render(
|
|
2635
|
-
/* @__PURE__ */
|
|
2790
|
+
/* @__PURE__ */ jsx22(AuthStatus, { state: isExpired ? "expired" : "not-logged-in" })
|
|
2636
2791
|
);
|
|
2637
2792
|
return null;
|
|
2638
2793
|
}
|
|
2639
2794
|
};
|
|
2640
2795
|
program.name("stackable-app-extension").description("Stackable Labs - App Extension developer CLI").version(version);
|
|
2641
|
-
program.command("create" /* CREATE */).description("Create a new Extension project").argument("[name]", "Extension project name").option("--extension-port <port>", "Extension dev server port (default: 6543)").option("--preview-port <port>", "Preview dev server port").option("--skip-install", "Skip package manager install").option("--skip-git", "Skip git initialization").action(async (name, options) => {
|
|
2796
|
+
program.command("create" /* CREATE */).description("Create a new Extension project").argument("[name]", "Extension project name").option("--template <flavor>", "Template flavor: minimal, starter, kitchen-sink").option("--extension-port <port>", "Extension dev server port (default: 6543)").option("--preview-port <port>", "Preview dev server port").option("--skip-install", "Skip package manager install").option("--skip-git", "Skip git initialization").action(async (name, options) => {
|
|
2642
2797
|
const auth2 = await ensureToken();
|
|
2643
2798
|
if (!auth2) {
|
|
2644
2799
|
return;
|
|
2645
2800
|
}
|
|
2646
2801
|
const { token, userId, orgId } = auth2;
|
|
2647
2802
|
render(
|
|
2648
|
-
/* @__PURE__ */
|
|
2803
|
+
/* @__PURE__ */ jsx22(
|
|
2649
2804
|
App,
|
|
2650
2805
|
{
|
|
2651
2806
|
command: "create" /* CREATE */,
|
|
@@ -2665,7 +2820,7 @@ program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project
|
|
|
2665
2820
|
}
|
|
2666
2821
|
const { token, userId, orgId } = auth2;
|
|
2667
2822
|
render(
|
|
2668
|
-
/* @__PURE__ */
|
|
2823
|
+
/* @__PURE__ */ jsx22(
|
|
2669
2824
|
App,
|
|
2670
2825
|
{
|
|
2671
2826
|
command: "scaffold" /* SCAFFOLD */,
|
|
@@ -2684,7 +2839,7 @@ program.command("update" /* UPDATE */).description("Update an existing Extension
|
|
|
2684
2839
|
}
|
|
2685
2840
|
const { token, userId, orgId } = auth2;
|
|
2686
2841
|
render(
|
|
2687
|
-
/* @__PURE__ */
|
|
2842
|
+
/* @__PURE__ */ jsx22(
|
|
2688
2843
|
App,
|
|
2689
2844
|
{
|
|
2690
2845
|
command: "update" /* UPDATE */,
|
|
@@ -2704,7 +2859,7 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
2704
2859
|
}
|
|
2705
2860
|
const { token, userId, orgId } = auth2;
|
|
2706
2861
|
render(
|
|
2707
|
-
/* @__PURE__ */
|
|
2862
|
+
/* @__PURE__ */ jsx22(
|
|
2708
2863
|
DevApp,
|
|
2709
2864
|
{
|
|
2710
2865
|
options,
|
|
@@ -2719,17 +2874,17 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
2719
2874
|
var DASHBOARD_URL = process.env.ADMIN_DASHBOARD_URL ?? "https://admin.stackablelabs.io";
|
|
2720
2875
|
var auth = program.command("auth").description("Manage CLI authentication");
|
|
2721
2876
|
auth.command("login").description("Authenticate with Stackable via browser").action(async () => {
|
|
2722
|
-
render(/* @__PURE__ */
|
|
2877
|
+
render(/* @__PURE__ */ jsx22(AuthLogin, { dashboardUrl: DASHBOARD_URL }));
|
|
2723
2878
|
});
|
|
2724
2879
|
auth.command("logout").description("Clear stored CLI credentials").action(async () => {
|
|
2725
2880
|
await clearAuthState();
|
|
2726
|
-
render(/* @__PURE__ */
|
|
2881
|
+
render(/* @__PURE__ */ jsx22(AuthLogout, {}));
|
|
2727
2882
|
});
|
|
2728
2883
|
auth.command("status").description("Show current authentication status").action(async () => {
|
|
2729
2884
|
const state = await readAuthState();
|
|
2730
2885
|
if (!state) {
|
|
2731
2886
|
render(
|
|
2732
|
-
/* @__PURE__ */
|
|
2887
|
+
/* @__PURE__ */ jsx22(AuthStatus, { state: "not-logged-in" })
|
|
2733
2888
|
);
|
|
2734
2889
|
return;
|
|
2735
2890
|
}
|
|
@@ -2737,11 +2892,11 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
2737
2892
|
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
2738
2893
|
const expiry = payload.exp ? new Date(payload.exp * 1e3) : null;
|
|
2739
2894
|
if (expiry && Date.now() >= expiry.getTime()) {
|
|
2740
|
-
render(/* @__PURE__ */
|
|
2895
|
+
render(/* @__PURE__ */ jsx22(AuthStatus, { state: "expired", expiry }));
|
|
2741
2896
|
return;
|
|
2742
2897
|
}
|
|
2743
2898
|
render(
|
|
2744
|
-
/* @__PURE__ */
|
|
2899
|
+
/* @__PURE__ */ jsx22(
|
|
2745
2900
|
AuthStatus,
|
|
2746
2901
|
{
|
|
2747
2902
|
state: "authenticated",
|
|
@@ -2754,6 +2909,6 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
2754
2909
|
});
|
|
2755
2910
|
var ai = program.command("ai").description("AI editor configuration tools");
|
|
2756
2911
|
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) => {
|
|
2757
|
-
render(/* @__PURE__ */
|
|
2912
|
+
render(/* @__PURE__ */ jsx22(AIScaffold, { version: options.version }));
|
|
2758
2913
|
});
|
|
2759
2914
|
program.parse(process.argv.filter((arg) => arg !== "--"));
|