@stackable-labs/cli-app-extension 1.37.0 → 1.39.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.
Files changed (2) hide show
  1. package/dist/index.js +606 -767
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -1,20 +1,27 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from 'module';
3
+ import { program } from 'commander';
4
+ import { render, useApp, Box, Text, useInput, useFocus, useFocusManager } from 'ink';
5
+ import { unlink, readFile, writeFile, mkdir, readdir, rm } from 'fs/promises';
6
+ import { join, dirname } from 'path';
7
+ import Spinner5 from 'ink-spinner';
8
+ import { useState, useCallback, useEffect, useRef, useMemo } from 'react';
9
+ import { delay } from '@stackable-labs/lib-utils-js';
10
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
11
+ import TextInput from 'ink-text-input';
12
+ import { execFile, spawn } from 'child_process';
13
+ import { promisify } from 'util';
14
+ import { installDependencies } from 'nypm';
15
+ import { downloadTemplate } from 'giget';
16
+ import { Tunnel } from 'cloudflared';
17
+ import clipboard from 'clipboardy';
18
+ import { existsSync, readFileSync } from 'fs';
19
+ import AdmZip from 'adm-zip';
20
+ import { createServer } from 'http';
21
+ import open from 'open';
22
+ import { homedir } from 'os';
23
+ import https from 'https';
2
24
 
3
- // src/index.tsx
4
- import { createRequire } from "module";
5
- import { program } from "commander";
6
- import { render } from "ink";
7
-
8
- // src/App.tsx
9
- import { readFile as readFile3 } from "fs/promises";
10
- import { join as join3 } from "path";
11
- import { Box as Box15, Text as Text15, useApp } from "ink";
12
- import Spinner4 from "ink-spinner";
13
- import { useCallback as useCallback2, useEffect as useEffect4, useState as useState11 } from "react";
14
-
15
- // src/components/Banner.tsx
16
- import { Box, Text } from "ink";
17
- import { jsx, jsxs } from "react/jsx-runtime";
18
25
  var WORDMARK = [
19
26
  " _ _ _ _ ",
20
27
  " ___| |_ __ _ ___| | ____ _| |__ | | ___",
@@ -68,11 +75,6 @@ var Banner = ({ userId, orgId } = {}) => {
68
75
  ] });
69
76
  };
70
77
 
71
- // src/components/Confirm.tsx
72
- import { Box as Box3, Text as Text3, useFocus, useFocusManager, useInput as useInput2 } from "ink";
73
- import TextInput from "ink-text-input";
74
- import { useEffect, useState } from "react";
75
-
76
78
  // src/constants.ts
77
79
  var TEMPLATE_SOURCES = {
78
80
  minimal: "github:stackable-labs/templates/app-extension-minimal",
@@ -106,10 +108,6 @@ var TARGET_PERMISSION_MAP = {
106
108
  "slot.footer": [],
107
109
  "slot.footer-links": []
108
110
  };
109
-
110
- // src/components/StepShell.tsx
111
- import { Box as Box2, Text as Text2, useInput } from "ink";
112
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
113
111
  var divider = (width) => "\u2500".repeat(width);
114
112
  var INNER_DIVIDER_WIDTH = 40;
115
113
  var StepShell = ({ title, hint, children, footer, onBack }) => {
@@ -119,29 +117,26 @@ var StepShell = ({ title, hint, children, footer, onBack }) => {
119
117
  onBack();
120
118
  }
121
119
  });
122
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", gap: 0, children: [
123
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: divider(termWidth) }),
124
- /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, paddingY: 1, gap: 1, children: [
125
- /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", gap: 0, children: [
126
- onBack && /* @__PURE__ */ jsxs2(Box2, { gap: 1, marginBottom: 1, children: [
127
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "\u2190 Back" }),
128
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "(Esc)" })
120
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
121
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: divider(termWidth) }),
122
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, gap: 1, children: [
123
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
124
+ onBack && /* @__PURE__ */ jsxs(Box, { gap: 1, marginBottom: 1, children: [
125
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2190 Back" }),
126
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "(Esc)" })
129
127
  ] }),
130
- /* @__PURE__ */ jsx2(Text2, { bold: true, color: "cyan", children: title }),
131
- hint && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: hint })
128
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: title }),
129
+ hint && /* @__PURE__ */ jsx(Text, { dimColor: true, children: hint })
132
130
  ] }),
133
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: divider(INNER_DIVIDER_WIDTH) }),
131
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: divider(INNER_DIVIDER_WIDTH) }),
134
132
  children
135
133
  ] }),
136
- footer && /* @__PURE__ */ jsxs2(Fragment, { children: [
137
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: divider(termWidth) }),
138
- /* @__PURE__ */ jsx2(Box2, { paddingX: 1, paddingTop: 1, children: footer })
134
+ footer && /* @__PURE__ */ jsxs(Fragment, { children: [
135
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: divider(termWidth) }),
136
+ /* @__PURE__ */ jsx(Box, { paddingX: 1, paddingTop: 1, children: footer })
139
137
  ] })
140
138
  ] });
141
139
  };
142
-
143
- // src/components/Confirm.tsx
144
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
145
140
  var compareSemver = (a, b) => {
146
141
  const pa = a.split(".").map(Number);
147
142
  const pb = b.split(".").map(Number);
@@ -154,7 +149,7 @@ var compareSemver = (a, b) => {
154
149
  var VersionRow = ({ currentVersion, value, onChange, onFocusChange, onConfirm, onCancel, selected }) => {
155
150
  const { isFocused } = useFocus();
156
151
  const { focusPrevious, focusNext } = useFocusManager();
157
- useInput2((_, key) => {
152
+ useInput((_, key) => {
158
153
  if (!isFocused) return;
159
154
  if (key.upArrow) {
160
155
  focusPrevious();
@@ -177,17 +172,17 @@ var VersionRow = ({ currentVersion, value, onChange, onFocusChange, onConfirm, o
177
172
  const isValid = /^\d+\.\d+\.\d+$/.test(value) && compareSemver(value, currentVersion) > 0;
178
173
  const showError = isFocused && value !== "" && !isValid;
179
174
  const hasChange = value !== currentVersion;
180
- return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
181
- /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
182
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Version " }),
183
- /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
175
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
176
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
177
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Version " }),
178
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
184
179
  currentVersion,
185
180
  hasChange ? " \u2192 " : ""
186
181
  ] }),
187
- isFocused ? /* @__PURE__ */ jsx3(TextInput, { value, onChange, placeholder: value }) : hasChange && /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: value }),
188
- isFocused && /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "(edit to override)" })
182
+ isFocused ? /* @__PURE__ */ jsx(TextInput, { value, onChange, placeholder: value }) : hasChange && /* @__PURE__ */ jsx(Text, { dimColor: true, children: value }),
183
+ isFocused && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "(edit to override)" })
189
184
  ] }),
190
- showError && /* @__PURE__ */ jsx3(Text3, { color: "red", children: " Version must be greater than " + currentVersion })
185
+ showError && /* @__PURE__ */ jsx(Text, { color: "red", children: " Version must be greater than " + currentVersion })
191
186
  ] });
192
187
  };
193
188
  var Confirm = ({
@@ -214,7 +209,7 @@ var Confirm = ({
214
209
  }) => {
215
210
  const [selected, setSelected] = useState("y");
216
211
  const [overrideFocused, setOverrideFocused] = useState(false);
217
- useInput2((input, key) => {
212
+ useInput((input, key) => {
218
213
  if (overrideFocused) return;
219
214
  if (key.leftArrow || key.rightArrow) {
220
215
  setSelected((s) => s === "y" ? "n" : "y");
@@ -238,29 +233,29 @@ var Confirm = ({
238
233
  }
239
234
  }
240
235
  });
241
- return /* @__PURE__ */ jsx3(
236
+ return /* @__PURE__ */ jsx(
242
237
  StepShell,
243
238
  {
244
239
  title: command === "update" /* UPDATE */ ? "Ready to update" : "Ready to scaffold",
245
240
  hint: "Review your settings before proceeding",
246
241
  onBack,
247
- footer: /* @__PURE__ */ jsxs3(Text3, { children: [
242
+ footer: /* @__PURE__ */ jsxs(Text, { children: [
248
243
  "Proceed?",
249
244
  " ",
250
- /* @__PURE__ */ jsx3(Text3, { bold: true, color: "green", inverse: selected === "y", children: "Y" }),
251
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "/" }),
252
- /* @__PURE__ */ jsx3(Text3, { bold: true, color: "red", inverse: selected === "n", children: "n" })
245
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "green", inverse: selected === "y", children: "Y" }),
246
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "/" }),
247
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "red", inverse: selected === "n", children: "n" })
253
248
  ] }),
254
- children: /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", gap: 1, children: [
255
- /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
256
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Name " }),
257
- /* @__PURE__ */ jsx3(Text3, { dimColor: !!extensionVersion, children: name })
249
+ children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
250
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
251
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Name " }),
252
+ /* @__PURE__ */ jsx(Text, { dimColor: !!extensionVersion, children: name })
258
253
  ] }),
259
- templateFlavor && /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
260
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Template " }),
261
- /* @__PURE__ */ jsx3(Text3, { children: TEMPLATE_FLAVOR_META[templateFlavor].label })
254
+ templateFlavor && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
255
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Template " }),
256
+ /* @__PURE__ */ jsx(Text, { children: TEMPLATE_FLAVOR_META[templateFlavor].label })
262
257
  ] }),
263
- extensionVersion && command === "update" /* UPDATE */ && newVersion && onVersionOverride && /* @__PURE__ */ jsx3(
258
+ extensionVersion && command === "update" /* UPDATE */ && newVersion && onVersionOverride && /* @__PURE__ */ jsx(
264
259
  VersionRow,
265
260
  {
266
261
  currentVersion: extensionVersion,
@@ -272,84 +267,84 @@ var Confirm = ({
272
267
  selected
273
268
  }
274
269
  ),
275
- extensionVersion && !(command === "update" /* UPDATE */ && newVersion && onVersionOverride) && /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
276
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Version " }),
277
- /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
270
+ extensionVersion && !(command === "update" /* UPDATE */ && newVersion && onVersionOverride) && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
271
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Version " }),
272
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
278
273
  extensionVersion,
279
274
  newVersion && newVersion !== extensionVersion ? ` \u2192 ${newVersion}` : ""
280
275
  ] })
281
276
  ] }),
282
- command !== "update" /* UPDATE */ && outputDir && /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
283
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Directory " }),
284
- /* @__PURE__ */ jsx3(Text3, { children: outputDir })
277
+ command !== "update" /* UPDATE */ && outputDir && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
278
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Directory " }),
279
+ /* @__PURE__ */ jsx(Text, { children: outputDir })
285
280
  ] }),
286
- command !== "update" /* UPDATE */ && extensionPort !== void 0 && /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
287
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Extension port" }),
288
- /* @__PURE__ */ jsx3(Text3, { children: extensionPort })
281
+ command !== "update" /* UPDATE */ && extensionPort !== void 0 && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
282
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Extension port" }),
283
+ /* @__PURE__ */ jsx(Text, { children: extensionPort })
289
284
  ] }),
290
- command !== "update" /* UPDATE */ && previewPort !== void 0 && /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
291
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Preview port " }),
292
- /* @__PURE__ */ jsx3(Text3, { children: previewPort })
285
+ command !== "update" /* UPDATE */ && previewPort !== void 0 && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
286
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Preview port " }),
287
+ /* @__PURE__ */ jsx(Text, { children: previewPort })
293
288
  ] }),
294
- command === "update" /* UPDATE */ && bundleUrl && /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
295
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Bundle URL " }),
296
- /* @__PURE__ */ jsx3(Text3, { children: bundleUrl })
289
+ command === "update" /* UPDATE */ && bundleUrl && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
290
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Bundle URL " }),
291
+ /* @__PURE__ */ jsx(Text, { children: bundleUrl })
297
292
  ] }),
298
- command === "update" /* UPDATE */ && enabled !== void 0 && /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
299
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Enabled " }),
300
- /* @__PURE__ */ jsx3(Text3, { color: enabled ? "green" : "red", children: enabled ? "Yes" : "No" })
293
+ command === "update" /* UPDATE */ && enabled !== void 0 && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
294
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Enabled " }),
295
+ /* @__PURE__ */ jsx(Text, { color: enabled ? "green" : "red", children: enabled ? "Yes" : "No" })
301
296
  ] }),
302
- /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
303
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Targets " }),
304
- /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
297
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
298
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Targets " }),
299
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
305
300
  targets.map((t) => {
306
301
  const isAdded = registryTargets && !registryTargets.includes(t);
307
- return /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
308
- /* @__PURE__ */ jsx3(Text3, { color: "green", children: "\u2022 " }),
309
- /* @__PURE__ */ jsx3(Text3, { children: t }),
310
- isAdded && /* @__PURE__ */ jsx3(Text3, { color: "green", dimColor: true, children: "(+ added)" })
302
+ return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
303
+ /* @__PURE__ */ jsx(Text, { color: "green", children: "\u2022 " }),
304
+ /* @__PURE__ */ jsx(Text, { children: t }),
305
+ isAdded && /* @__PURE__ */ jsx(Text, { color: "green", dimColor: true, children: "(+ added)" })
311
306
  ] }, t);
312
307
  }),
313
- registryTargets?.filter((t) => !targets.includes(t)).map((t) => /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
314
- /* @__PURE__ */ jsx3(Text3, { color: "red", children: "\u2022 " }),
315
- /* @__PURE__ */ jsx3(Text3, { color: "red", dimColor: true, strikethrough: true, children: t }),
316
- /* @__PURE__ */ jsx3(Text3, { color: "red", dimColor: true, children: "(- removed)" })
308
+ registryTargets?.filter((t) => !targets.includes(t)).map((t) => /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
309
+ /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2022 " }),
310
+ /* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, strikethrough: true, children: t }),
311
+ /* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, children: "(- removed)" })
317
312
  ] }, t))
318
313
  ] })
319
314
  ] }),
320
- permissions && (permissions.length > 0 || registryPermissions?.some((p) => !permissions.includes(p))) && /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
321
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Permissions " }),
322
- /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
315
+ permissions && (permissions.length > 0 || registryPermissions?.some((p) => !permissions.includes(p))) && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
316
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Permissions " }),
317
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
323
318
  permissions.map((p) => {
324
319
  const isAdded = registryPermissions && !registryPermissions.includes(p);
325
- return /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
326
- /* @__PURE__ */ jsx3(Text3, { color: "green", children: "\u2022 " }),
327
- /* @__PURE__ */ jsx3(Text3, { children: p }),
328
- isAdded && /* @__PURE__ */ jsx3(Text3, { color: "green", dimColor: true, children: "(+ added)" })
320
+ return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
321
+ /* @__PURE__ */ jsx(Text, { color: "green", children: "\u2022 " }),
322
+ /* @__PURE__ */ jsx(Text, { children: p }),
323
+ isAdded && /* @__PURE__ */ jsx(Text, { color: "green", dimColor: true, children: "(+ added)" })
329
324
  ] }, p);
330
325
  }),
331
- registryPermissions?.filter((p) => !permissions.includes(p)).map((p) => /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
332
- /* @__PURE__ */ jsx3(Text3, { color: "red", children: "\u2022 " }),
333
- /* @__PURE__ */ jsx3(Text3, { color: "red", dimColor: true, strikethrough: true, children: p }),
334
- /* @__PURE__ */ jsx3(Text3, { color: "red", dimColor: true, children: "(- removed)" })
326
+ registryPermissions?.filter((p) => !permissions.includes(p)).map((p) => /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
327
+ /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2022 " }),
328
+ /* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, strikethrough: true, children: p }),
329
+ /* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, children: "(- removed)" })
335
330
  ] }, p))
336
331
  ] })
337
332
  ] }),
338
- allowedDomains && (allowedDomains.length > 0 || registryAllowedDomains?.some((d) => !allowedDomains.includes(d))) && /* @__PURE__ */ jsxs3(Box3, { gap: 2, children: [
339
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Domains " }),
340
- /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
333
+ allowedDomains && (allowedDomains.length > 0 || registryAllowedDomains?.some((d) => !allowedDomains.includes(d))) && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
334
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Domains " }),
335
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
341
336
  allowedDomains.map((d) => {
342
337
  const isAdded = registryAllowedDomains && !registryAllowedDomains.includes(d);
343
- return /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
344
- /* @__PURE__ */ jsx3(Text3, { color: "green", children: "\u2022 " }),
345
- /* @__PURE__ */ jsx3(Text3, { children: d }),
346
- isAdded && /* @__PURE__ */ jsx3(Text3, { color: "green", dimColor: true, children: "(+ added)" })
338
+ return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
339
+ /* @__PURE__ */ jsx(Text, { color: "green", children: "\u2022 " }),
340
+ /* @__PURE__ */ jsx(Text, { children: d }),
341
+ isAdded && /* @__PURE__ */ jsx(Text, { color: "green", dimColor: true, children: "(+ added)" })
347
342
  ] }, d);
348
343
  }),
349
- registryAllowedDomains?.filter((d) => !allowedDomains.includes(d)).map((d) => /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
350
- /* @__PURE__ */ jsx3(Text3, { color: "red", children: "\u2022 " }),
351
- /* @__PURE__ */ jsx3(Text3, { color: "red", dimColor: true, strikethrough: true, children: d }),
352
- /* @__PURE__ */ jsx3(Text3, { color: "red", dimColor: true, children: "(- removed)" })
344
+ registryAllowedDomains?.filter((d) => !allowedDomains.includes(d)).map((d) => /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
345
+ /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2022 " }),
346
+ /* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, strikethrough: true, children: d }),
347
+ /* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, children: "(- removed)" })
353
348
  ] }, d))
354
349
  ] })
355
350
  ] })
@@ -357,75 +352,59 @@ var Confirm = ({
357
352
  }
358
353
  );
359
354
  };
360
-
361
- // src/components/Done.tsx
362
- import { Box as Box4, Text as Text4 } from "ink";
363
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
364
355
  var FLAVOR_HINTS = {
365
356
  minimal: "A clean slate \u2014 add surfaces and capabilities as you need them.",
366
357
  starter: "Common patterns included \u2014 customize and build from here.",
367
358
  "kitchen-sink": "We threw in everything \u2014 including the kitchen sink. Poke around, steal patterns, then delete what you don't need."
368
359
  };
369
- var Done = ({ name, outputDir, templateFlavor }) => /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", gap: 1, children: [
370
- /* @__PURE__ */ jsxs4(Box4, { gap: 1, children: [
371
- /* @__PURE__ */ jsx4(Text4, { color: "green", bold: true, children: "\u2714" }),
372
- /* @__PURE__ */ jsx4(Text4, { bold: true, children: "Extension scaffolded successfully!" })
360
+ var Done = ({ name, outputDir, templateFlavor }) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
361
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
362
+ /* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
363
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Extension scaffolded successfully!" })
373
364
  ] }),
374
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginLeft: 2, children: [
375
- /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
365
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
366
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
376
367
  "Created: ",
377
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", children: name })
368
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: name })
378
369
  ] }),
379
- templateFlavor && /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
370
+ templateFlavor && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
380
371
  "Template: ",
381
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", children: TEMPLATE_FLAVOR_META[templateFlavor].label })
372
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: TEMPLATE_FLAVOR_META[templateFlavor].label })
382
373
  ] }),
383
- /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
374
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
384
375
  "Location: ",
385
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", children: outputDir })
376
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: outputDir })
386
377
  ] })
387
378
  ] }),
388
- templateFlavor && /* @__PURE__ */ jsx4(Box4, { marginLeft: 2, children: /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: FLAVOR_HINTS[templateFlavor] }) }),
389
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "green", paddingX: 2, paddingY: 1, children: [
390
- /* @__PURE__ */ jsx4(Text4, { bold: true, children: "Next steps:" }),
391
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, gap: 1, children: [
392
- /* @__PURE__ */ jsxs4(Box4, { gap: 1, children: [
393
- /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "1." }),
394
- /* @__PURE__ */ jsxs4(Text4, { children: [
395
- /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "cd " }),
396
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", children: outputDir })
379
+ templateFlavor && /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: FLAVOR_HINTS[templateFlavor] }) }),
380
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "green", paddingX: 2, paddingY: 1, children: [
381
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Next steps:" }),
382
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, gap: 1, children: [
383
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
384
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "1." }),
385
+ /* @__PURE__ */ jsxs(Text, { children: [
386
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "cd " }),
387
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: outputDir })
397
388
  ] })
398
389
  ] }),
399
- /* @__PURE__ */ jsxs4(Box4, { gap: 1, children: [
400
- /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "2." }),
401
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", children: "pnpm install" })
390
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
391
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "2." }),
392
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: "pnpm install" })
402
393
  ] }),
403
- /* @__PURE__ */ jsxs4(Box4, { gap: 1, children: [
404
- /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "3." }),
405
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", children: "pnpm dev" })
394
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
395
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "3." }),
396
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: "pnpm dev" })
406
397
  ] })
407
398
  ] })
408
399
  ] })
409
400
  ] });
410
-
411
- // src/components/NamePrompt.tsx
412
- import { Box as Box6, Text as Text6 } from "ink";
413
- import TextInput2 from "ink-text-input";
414
- import { useState as useState2 } from "react";
415
-
416
- // src/components/BackableInput.tsx
417
- import { Box as Box5, Text as Text5 } from "ink";
418
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
419
- var BackableInput = ({ label, hint, onBack, children, error }) => /* @__PURE__ */ jsx5(StepShell, { title: label, hint, onBack, children: /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", gap: 1, children: [
401
+ var BackableInput = ({ label, hint, onBack, children, error }) => /* @__PURE__ */ jsx(StepShell, { title: label, hint, onBack, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
420
402
  children(true),
421
- error && /* @__PURE__ */ jsx5(Text5, { color: "red", children: error })
403
+ error && /* @__PURE__ */ jsx(Text, { color: "red", children: error })
422
404
  ] }) });
423
-
424
- // src/components/NamePrompt.tsx
425
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
426
405
  var NamePrompt = ({ initialValue = "", onSubmit, onBack }) => {
427
- const [value, setValue] = useState2(initialValue);
428
- const [error, setError] = useState2();
406
+ const [value, setValue] = useState(initialValue);
407
+ const [error, setError] = useState();
429
408
  const handleSubmit = (val) => {
430
409
  const trimmed = val.trim();
431
410
  if (trimmed.length === 0) {
@@ -435,33 +414,27 @@ var NamePrompt = ({ initialValue = "", onSubmit, onBack }) => {
435
414
  setError(void 0);
436
415
  onSubmit(trimmed);
437
416
  };
438
- return /* @__PURE__ */ jsx6(BackableInput, { label: "What is your Extension name?", hint: "Press Enter to confirm", onBack, error, children: (isFocused) => /* @__PURE__ */ jsxs6(Box6, { children: [
439
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "> " }),
440
- /* @__PURE__ */ jsx6(TextInput2, { value, onChange: setValue, onSubmit: handleSubmit, focus: isFocused })
417
+ return /* @__PURE__ */ jsx(BackableInput, { label: "What is your Extension name?", hint: "Press Enter to confirm", onBack, error, children: (isFocused) => /* @__PURE__ */ jsxs(Box, { children: [
418
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "> " }),
419
+ /* @__PURE__ */ jsx(TextInput, { value, onChange: setValue, onSubmit: handleSubmit, focus: isFocused })
441
420
  ] }) });
442
421
  };
443
-
444
- // src/components/SettingsPrompt.tsx
445
- import { Box as Box7, Text as Text7, useFocus as useFocus2, useFocusManager as useFocusManager2, useInput as useInput3 } from "ink";
446
- import TextInput3 from "ink-text-input";
447
- import { useState as useState3 } from "react";
448
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
449
422
  var DEFAULT_EXTENSION_PORT = 6543;
450
423
  var DEFAULT_PREVIEW_PORT = DEFAULT_EXTENSION_PORT + 1;
451
424
  var FieldRow = ({ label, value, onChange, onSubmit, onConfirm, placeholder, autoFocus, isFirst, isLast }) => {
452
- const { isFocused } = useFocus2({ autoFocus });
453
- const { focusNext, focusPrevious } = useFocusManager2();
454
- useInput3((_input, key) => {
425
+ const { isFocused } = useFocus({ autoFocus });
426
+ const { focusNext, focusPrevious } = useFocusManager();
427
+ useInput((_input, key) => {
455
428
  if (!isFocused) return;
456
429
  if (key.downArrow && !isLast) focusNext();
457
430
  if (key.upArrow && !isFirst) focusPrevious();
458
431
  });
459
- return /* @__PURE__ */ jsxs7(Box7, { gap: 2, children: [
460
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: label }),
461
- isFocused ? /* @__PURE__ */ jsxs7(Box7, { children: [
462
- /* @__PURE__ */ jsx7(Text7, { color: "cyan", children: "\u2192 " }),
463
- /* @__PURE__ */ jsx7(
464
- TextInput3,
432
+ return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
433
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: label }),
434
+ isFocused ? /* @__PURE__ */ jsxs(Box, { children: [
435
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u2192 " }),
436
+ /* @__PURE__ */ jsx(
437
+ TextInput,
465
438
  {
466
439
  value,
467
440
  onChange,
@@ -473,13 +446,13 @@ var FieldRow = ({ label, value, onChange, onSubmit, onConfirm, placeholder, auto
473
446
  focus: isFocused
474
447
  }
475
448
  )
476
- ] }) : /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: value })
449
+ ] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: value })
477
450
  ] });
478
451
  };
479
452
  var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
480
- const [extensionPort, setExtensionPort] = useState3(String(DEFAULT_EXTENSION_PORT));
481
- const [previewPort, setPreviewPort] = useState3(String(DEFAULT_PREVIEW_PORT));
482
- const [outputDir, setOutputDir] = useState3(defaultDir);
453
+ const [extensionPort, setExtensionPort] = useState(String(DEFAULT_EXTENSION_PORT));
454
+ const [previewPort, setPreviewPort] = useState(String(DEFAULT_PREVIEW_PORT));
455
+ const [outputDir, setOutputDir] = useState(defaultDir);
483
456
  const handleConfirm = (resolvedExtPort, resolvedPrevPort, resolvedDir) => {
484
457
  const dir = resolvedDir.trim();
485
458
  if (!dir) return;
@@ -510,14 +483,14 @@ var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
510
483
  setOutputDir(trimmed);
511
484
  return [extensionPort, previewPort, trimmed];
512
485
  };
513
- return /* @__PURE__ */ jsx7(
486
+ return /* @__PURE__ */ jsx(
514
487
  StepShell,
515
488
  {
516
489
  title: "Project settings",
517
490
  hint: "\u2191\u2193 or Tab to move between fields, Enter to confirm",
518
491
  onBack,
519
- children: /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", gap: 1, children: [
520
- /* @__PURE__ */ jsx7(
492
+ children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
493
+ /* @__PURE__ */ jsx(
521
494
  FieldRow,
522
495
  {
523
496
  label: "Extension port ",
@@ -530,7 +503,7 @@ var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
530
503
  isFirst: true
531
504
  }
532
505
  ),
533
- /* @__PURE__ */ jsx7(
506
+ /* @__PURE__ */ jsx(
534
507
  FieldRow,
535
508
  {
536
509
  label: "Preview port ",
@@ -541,7 +514,7 @@ var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
541
514
  placeholder: String(DEFAULT_PREVIEW_PORT)
542
515
  }
543
516
  ),
544
- /* @__PURE__ */ jsx7(
517
+ /* @__PURE__ */ jsx(
545
518
  FieldRow,
546
519
  {
547
520
  label: "Output directory",
@@ -557,10 +530,6 @@ var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
557
530
  );
558
531
  };
559
532
 
560
- // src/components/ManifestReviewPrompt.tsx
561
- import { Box as Box8, Text as Text8, useInput as useInput4 } from "ink";
562
- import { useState as useState4 } from "react";
563
-
564
533
  // src/lib/manifest-diff.ts
565
534
  var diffManifestValues = (localValues, registryValues) => {
566
535
  const localSet = new Set(localValues ?? []);
@@ -575,9 +544,6 @@ var diffManifestValues = (localValues, registryValues) => {
575
544
  return inRegistry ? { value, status: "unchanged", enabled: true } : { value, status: "new", enabled: false };
576
545
  });
577
546
  };
578
-
579
- // src/components/ManifestReviewPrompt.tsx
580
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
581
547
  var statusLabel = (status) => {
582
548
  switch (status) {
583
549
  case "new":
@@ -604,9 +570,9 @@ var ManifestReviewPrompt = ({
604
570
  onSubmit,
605
571
  onBack
606
572
  }) => {
607
- const [permItems, setPermItems] = useState4(() => diffManifestValues(localManifest?.permissions, registryManifest.permissions));
608
- const [domainItems, setDomainItems] = useState4(() => diffManifestValues(localManifest?.allowedDomains, registryManifest.allowedDomains));
609
- const [cursor, setCursor] = useState4(0);
573
+ const [permItems, setPermItems] = useState(() => diffManifestValues(localManifest?.permissions, registryManifest.permissions));
574
+ const [domainItems, setDomainItems] = useState(() => diffManifestValues(localManifest?.allowedDomains, registryManifest.allowedDomains));
575
+ const [cursor, setCursor] = useState(0);
610
576
  const totalItems = permItems.length + domainItems.length;
611
577
  const cursorInPerms = cursor < permItems.length;
612
578
  const cursorInDomains = cursor >= permItems.length;
@@ -625,7 +591,7 @@ var ManifestReviewPrompt = ({
625
591
  });
626
592
  };
627
593
  const domainSectionStart = permItems.length;
628
- useInput4((input, key) => {
594
+ useInput((input, key) => {
629
595
  if (key.downArrow) {
630
596
  setCursor((c) => Math.min(c + 1, totalItems - 1));
631
597
  return;
@@ -658,49 +624,43 @@ var ManifestReviewPrompt = ({
658
624
  });
659
625
  const renderItem = (item, index) => {
660
626
  const isCursor = index === cursor;
661
- return /* @__PURE__ */ jsxs8(Box8, { gap: 1, children: [
662
- /* @__PURE__ */ jsx8(Text8, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
663
- /* @__PURE__ */ jsx8(Text8, { color: item.enabled ? "green" : "gray", children: item.enabled ? "\u25C9" : "\u25CB" }),
664
- /* @__PURE__ */ jsx8(Text8, { bold: isCursor, children: item.value }),
665
- statusLabel(item.status) && /* @__PURE__ */ jsx8(Text8, { color: statusColor(item.status), dimColor: true, children: statusLabel(item.status) })
627
+ return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
628
+ /* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
629
+ /* @__PURE__ */ jsx(Text, { color: item.enabled ? "green" : "gray", children: item.enabled ? "\u25C9" : "\u25CB" }),
630
+ /* @__PURE__ */ jsx(Text, { bold: isCursor, children: item.value }),
631
+ statusLabel(item.status) && /* @__PURE__ */ jsx(Text, { color: statusColor(item.status), dimColor: true, children: statusLabel(item.status) })
666
632
  ] }, item.value);
667
633
  };
668
- return /* @__PURE__ */ jsx8(
634
+ return /* @__PURE__ */ jsx(
669
635
  StepShell,
670
636
  {
671
637
  title: "Review Manifest changes",
672
638
  hint: "Tab/shift-tab to jump section, \u2191/\u2193 navigate. Enter to submit",
673
639
  onBack,
674
- children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, children: [
675
- !localManifest && /* @__PURE__ */ jsx8(Text8, { color: "yellow", children: "No local manifest.json found \u2014 showing registry values only" }),
676
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
677
- /* @__PURE__ */ jsx8(Text8, { dimColor: !cursorInPerms, bold: cursorInPerms, children: "Permissions".padEnd(14) }),
678
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingLeft: 2, children: [
679
- permItems.length > 0 ? permItems.map((item, i) => renderItem(item, i)) : /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " (none)" }),
680
- cursorInPerms && /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " (space to toggle)" })
640
+ children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
641
+ !localManifest && /* @__PURE__ */ jsx(Text, { color: "yellow", children: "No local manifest.json found \u2014 showing registry values only" }),
642
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
643
+ /* @__PURE__ */ jsx(Text, { dimColor: !cursorInPerms, bold: cursorInPerms, children: "Permissions".padEnd(14) }),
644
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [
645
+ permItems.length > 0 ? permItems.map((item, i) => renderItem(item, i)) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (none)" }),
646
+ cursorInPerms && /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (space to toggle)" })
681
647
  ] })
682
648
  ] }),
683
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
684
- /* @__PURE__ */ jsx8(Text8, { dimColor: !cursorInDomains, bold: cursorInDomains, children: "Allowed Domains".padEnd(14) }),
685
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingLeft: 2, children: [
686
- domainItems.length > 0 ? domainItems.map((item, i) => renderItem(item, i + permItems.length)) : /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " (none)" }),
687
- cursorInDomains && /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " (space to toggle)" })
649
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
650
+ /* @__PURE__ */ jsx(Text, { dimColor: !cursorInDomains, bold: cursorInDomains, children: "Allowed Domains".padEnd(14) }),
651
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [
652
+ domainItems.length > 0 ? domainItems.map((item, i) => renderItem(item, i + permItems.length)) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (none)" }),
653
+ cursorInDomains && /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (space to toggle)" })
688
654
  ] })
689
655
  ] })
690
656
  ] })
691
657
  }
692
658
  );
693
659
  };
694
-
695
- // src/components/UpdateSettingsPrompt.tsx
696
- import { Box as Box9, Text as Text9, useFocus as useFocus3, useFocusManager as useFocusManager3, useInput as useInput5 } from "ink";
697
- import TextInput4 from "ink-text-input";
698
- import { useState as useState5 } from "react";
699
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
700
660
  var FieldRow2 = ({ label, value, onChange, placeholder, autoFocus, isFirst, isLast, onSubmitAll }) => {
701
- const { isFocused } = useFocus3({ autoFocus });
702
- const { focusNext, focusPrevious } = useFocusManager3();
703
- useInput5((_, key) => {
661
+ const { isFocused } = useFocus({ autoFocus });
662
+ const { focusNext, focusPrevious } = useFocusManager();
663
+ useInput((_, key) => {
704
664
  if (!isFocused) return;
705
665
  if (key.downArrow) {
706
666
  if (!isLast) focusNext();
@@ -714,16 +674,16 @@ var FieldRow2 = ({ label, value, onChange, placeholder, autoFocus, isFirst, isLa
714
674
  onSubmitAll();
715
675
  }
716
676
  });
717
- return /* @__PURE__ */ jsxs9(Box9, { gap: 2, children: [
718
- /* @__PURE__ */ jsx9(Text9, { dimColor: !isFocused, bold: isFocused, children: label.padEnd(14) }),
719
- isFocused ? /* @__PURE__ */ jsx9(TextInput4, { value, onChange, placeholder }) : /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: value || placeholder || "" })
677
+ return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
678
+ /* @__PURE__ */ jsx(Text, { dimColor: !isFocused, bold: isFocused, children: label.padEnd(14) }),
679
+ isFocused ? /* @__PURE__ */ jsx(TextInput, { value, onChange, placeholder }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: value || placeholder || "" })
720
680
  ] });
721
681
  };
722
682
  var TargetToggleRow = ({ targets, availableTargets, onToggle, autoFocus, isLast, onSubmitAll }) => {
723
- const { isFocused } = useFocus3({ autoFocus });
724
- const { focusNext, focusPrevious } = useFocusManager3();
725
- const [cursor, setCursor] = useState5(0);
726
- useInput5((input, key) => {
683
+ const { isFocused } = useFocus({ autoFocus });
684
+ const { focusNext, focusPrevious } = useFocusManager();
685
+ const [cursor, setCursor] = useState(0);
686
+ useInput((input, key) => {
727
687
  if (!isFocused) return;
728
688
  if (key.downArrow) {
729
689
  if (cursor < availableTargets.length - 1) {
@@ -749,26 +709,26 @@ var TargetToggleRow = ({ targets, availableTargets, onToggle, autoFocus, isLast,
749
709
  onSubmitAll();
750
710
  }
751
711
  });
752
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
753
- /* @__PURE__ */ jsx9(Text9, { dimColor: !isFocused, bold: isFocused, children: "Targets".padEnd(14) }),
754
- /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingLeft: 2, children: [
712
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
713
+ /* @__PURE__ */ jsx(Text, { dimColor: !isFocused, bold: isFocused, children: "Targets".padEnd(14) }),
714
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [
755
715
  availableTargets.map((t, i) => {
756
716
  const selected = targets.includes(t);
757
717
  const isCursor = isFocused && i === cursor;
758
- return /* @__PURE__ */ jsxs9(Box9, { gap: 1, children: [
759
- /* @__PURE__ */ jsx9(Text9, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
760
- /* @__PURE__ */ jsx9(Text9, { color: selected ? "green" : "gray", children: selected ? "\u25C9" : "\u25CB" }),
761
- /* @__PURE__ */ jsx9(Text9, { bold: isCursor, children: t })
718
+ return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
719
+ /* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
720
+ /* @__PURE__ */ jsx(Text, { color: selected ? "green" : "gray", children: selected ? "\u25C9" : "\u25CB" }),
721
+ /* @__PURE__ */ jsx(Text, { bold: isCursor, children: t })
762
722
  ] }, t);
763
723
  }),
764
- isFocused && /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: " (space to toggle)" })
724
+ isFocused && /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (space to toggle)" })
765
725
  ] })
766
726
  ] });
767
727
  };
768
728
  var EnabledToggleRow = ({ enabled, onToggle, autoFocus, isLast, onSubmitAll }) => {
769
- const { isFocused } = useFocus3({ autoFocus });
770
- const { focusNext, focusPrevious } = useFocusManager3();
771
- useInput5((input, key) => {
729
+ const { isFocused } = useFocus({ autoFocus });
730
+ const { focusNext, focusPrevious } = useFocusManager();
731
+ useInput((input, key) => {
772
732
  if (!isFocused) return;
773
733
  if (key.downArrow) {
774
734
  if (!isLast) focusNext();
@@ -786,16 +746,16 @@ var EnabledToggleRow = ({ enabled, onToggle, autoFocus, isLast, onSubmitAll }) =
786
746
  onSubmitAll();
787
747
  }
788
748
  });
789
- return /* @__PURE__ */ jsxs9(Box9, { gap: 2, children: [
790
- /* @__PURE__ */ jsx9(Text9, { dimColor: !isFocused, bold: isFocused, children: "Enabled".padEnd(14) }),
791
- /* @__PURE__ */ jsx9(Text9, { color: enabled ? "green" : "red", bold: isFocused, children: enabled ? "Yes" : "No" }),
792
- isFocused && /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "(space/arrows to toggle)" })
749
+ return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
750
+ /* @__PURE__ */ jsx(Text, { dimColor: !isFocused, bold: isFocused, children: "Enabled".padEnd(14) }),
751
+ /* @__PURE__ */ jsx(Text, { color: enabled ? "green" : "red", bold: isFocused, children: enabled ? "Yes" : "No" }),
752
+ isFocused && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "(space/arrows to toggle)" })
793
753
  ] });
794
754
  };
795
755
  var ForceMajorToggleRow = ({ forceMajor, onToggle, autoFocus, isLast, onSubmitAll }) => {
796
- const { isFocused } = useFocus3({ autoFocus });
797
- const { focusPrevious, focusNext } = useFocusManager3();
798
- useInput5((input, key) => {
756
+ const { isFocused } = useFocus({ autoFocus });
757
+ const { focusPrevious, focusNext } = useFocusManager();
758
+ useInput((input, key) => {
799
759
  if (!isFocused) return;
800
760
  if (key.downArrow) {
801
761
  if (!isLast) focusNext();
@@ -813,10 +773,10 @@ var ForceMajorToggleRow = ({ forceMajor, onToggle, autoFocus, isLast, onSubmitAl
813
773
  onSubmitAll();
814
774
  }
815
775
  });
816
- return /* @__PURE__ */ jsxs9(Box9, { gap: 2, children: [
817
- /* @__PURE__ */ jsx9(Text9, { dimColor: !isFocused, bold: isFocused, children: "Force major".padEnd(14) }),
818
- /* @__PURE__ */ jsx9(Text9, { color: forceMajor ? "yellow" : "gray", bold: isFocused, children: forceMajor ? "Yes" : "No" }),
819
- isFocused && /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "(space/arrows to toggle)" })
776
+ return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
777
+ /* @__PURE__ */ jsx(Text, { dimColor: !isFocused, bold: isFocused, children: "Force major".padEnd(14) }),
778
+ /* @__PURE__ */ jsx(Text, { color: forceMajor ? "yellow" : "gray", bold: isFocused, children: forceMajor ? "Yes" : "No" }),
779
+ isFocused && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "(space/arrows to toggle)" })
820
780
  ] });
821
781
  };
822
782
  var UpdateSettingsPrompt = ({
@@ -829,12 +789,12 @@ var UpdateSettingsPrompt = ({
829
789
  onSubmit,
830
790
  onBack
831
791
  }) => {
832
- const [nameValue, setNameValue] = useState5(initialName);
833
- const [targetsValue, setTargetsValue] = useState5(initialTargets);
834
- const [bundleUrlValue, setBundleUrlValue] = useState5(initialBundleUrl);
835
- const [allowedDomainsValue, setAllowedDomainsValue] = useState5(initialAllowedDomains.join(", "));
836
- const [enabledValue, setEnabledValue] = useState5(initialEnabled);
837
- const [forceMajorValue, setForceMajorValue] = useState5(false);
792
+ const [nameValue, setNameValue] = useState(initialName);
793
+ const [targetsValue, setTargetsValue] = useState(initialTargets);
794
+ const [bundleUrlValue, setBundleUrlValue] = useState(initialBundleUrl);
795
+ const [allowedDomainsValue, setAllowedDomainsValue] = useState(initialAllowedDomains.join(", "));
796
+ const [enabledValue, setEnabledValue] = useState(initialEnabled);
797
+ const [forceMajorValue, setForceMajorValue] = useState(false);
838
798
  const handleToggleTarget = (target) => {
839
799
  setTargetsValue((prev) => prev.includes(target) ? prev.filter((t) => t !== target) : [...prev, target]);
840
800
  };
@@ -849,14 +809,14 @@ var UpdateSettingsPrompt = ({
849
809
  forceMajor: forceMajorValue
850
810
  });
851
811
  };
852
- return /* @__PURE__ */ jsx9(
812
+ return /* @__PURE__ */ jsx(
853
813
  StepShell,
854
814
  {
855
815
  title: "Update Extension settings",
856
816
  hint: "Tab/shift-tab to jump section, \u2191/\u2193 navigate. Enter to submit",
857
817
  onBack,
858
- children: /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, children: [
859
- /* @__PURE__ */ jsx9(
818
+ children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
819
+ /* @__PURE__ */ jsx(
860
820
  FieldRow2,
861
821
  {
862
822
  label: "Name",
@@ -868,7 +828,7 @@ var UpdateSettingsPrompt = ({
868
828
  onSubmitAll: handleSubmitAll
869
829
  }
870
830
  ),
871
- /* @__PURE__ */ jsx9(
831
+ /* @__PURE__ */ jsx(
872
832
  TargetToggleRow,
873
833
  {
874
834
  targets: targetsValue,
@@ -877,7 +837,7 @@ var UpdateSettingsPrompt = ({
877
837
  onSubmitAll: handleSubmitAll
878
838
  }
879
839
  ),
880
- /* @__PURE__ */ jsx9(
840
+ /* @__PURE__ */ jsx(
881
841
  FieldRow2,
882
842
  {
883
843
  label: "Bundle URL",
@@ -887,7 +847,7 @@ var UpdateSettingsPrompt = ({
887
847
  onSubmitAll: handleSubmitAll
888
848
  }
889
849
  ),
890
- /* @__PURE__ */ jsx9(
850
+ /* @__PURE__ */ jsx(
891
851
  FieldRow2,
892
852
  {
893
853
  label: "Allowed Domains",
@@ -897,7 +857,7 @@ var UpdateSettingsPrompt = ({
897
857
  onSubmitAll: handleSubmitAll
898
858
  }
899
859
  ),
900
- /* @__PURE__ */ jsx9(
860
+ /* @__PURE__ */ jsx(
901
861
  EnabledToggleRow,
902
862
  {
903
863
  enabled: enabledValue,
@@ -905,7 +865,7 @@ var UpdateSettingsPrompt = ({
905
865
  onSubmitAll: handleSubmitAll
906
866
  }
907
867
  ),
908
- /* @__PURE__ */ jsx9(
868
+ /* @__PURE__ */ jsx(
909
869
  ForceMajorToggleRow,
910
870
  {
911
871
  forceMajor: forceMajorValue,
@@ -918,35 +878,25 @@ var UpdateSettingsPrompt = ({
918
878
  }
919
879
  );
920
880
  };
921
-
922
- // src/components/ScaffoldProgress.tsx
923
- import { Box as Box10, Text as Text10 } from "ink";
924
- import Spinner from "ink-spinner";
925
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
926
881
  var stepIcon = (status) => {
927
882
  switch (status) {
928
883
  case "running":
929
- return /* @__PURE__ */ jsx10(Spinner, { type: "dots" });
884
+ return /* @__PURE__ */ jsx(Spinner5, { type: "dots" });
930
885
  case "done":
931
- return /* @__PURE__ */ jsx10(Text10, { color: "green", children: "\u2714" });
886
+ return /* @__PURE__ */ jsx(Text, { color: "green", children: "\u2714" });
932
887
  case "error":
933
- return /* @__PURE__ */ jsx10(Text10, { color: "red", children: "\u2716" });
888
+ return /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" });
934
889
  default:
935
- return /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "\u25CB" });
890
+ return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u25CB" });
936
891
  }
937
892
  };
938
- var ScaffoldProgress = ({ steps }) => /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", gap: 1, children: [
939
- /* @__PURE__ */ jsx10(Text10, { bold: true, children: "Scaffolding your Extension\u2026" }),
940
- /* @__PURE__ */ jsx10(Box10, { flexDirection: "column", children: steps.map((step) => /* @__PURE__ */ jsxs10(Box10, { gap: 2, children: [
893
+ var ScaffoldProgress = ({ steps }) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
894
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Scaffolding your Extension\u2026" }),
895
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: steps.map((step) => /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
941
896
  stepIcon(step.status),
942
- /* @__PURE__ */ jsx10(Text10, { dimColor: step.status === "pending", color: step.status === "running" ? "cyan" : void 0, children: step.label })
897
+ /* @__PURE__ */ jsx(Text, { dimColor: step.status === "pending", color: step.status === "running" ? "cyan" : void 0, children: step.label })
943
898
  ] }, step.label)) })
944
899
  ] });
945
-
946
- // src/components/TargetSelect.tsx
947
- import { Box as Box11, Text as Text11, useInput as useInput6 } from "ink";
948
- import { useState as useState6 } from "react";
949
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
950
900
  var TARGET_DESCRIPTIONS = {
951
901
  "slot.header": "Renders content in the panel header area",
952
902
  "slot.content": "Renders the main panel body (includes store + navigation state)",
@@ -954,12 +904,12 @@ var TARGET_DESCRIPTIONS = {
954
904
  "slot.footer-links": "Renders a link row in the global footer"
955
905
  };
956
906
  var TargetSelect = ({ availableTargets, preSelected, onSubmit, onBack }) => {
957
- const [cursor, setCursor] = useState6(0);
958
- const [selected, setSelected] = useState6(
907
+ const [cursor, setCursor] = useState(0);
908
+ const [selected, setSelected] = useState(
959
909
  new Set(preSelected ?? (availableTargets.includes("slot.content") ? ["slot.content"] : []))
960
910
  );
961
- const [error, setError] = useState6();
962
- useInput6((input, key) => {
911
+ const [error, setError] = useState();
912
+ useInput((input, key) => {
963
913
  if (key.upArrow) {
964
914
  setCursor((c) => Math.max(0, c - 1));
965
915
  return;
@@ -990,39 +940,34 @@ var TargetSelect = ({ availableTargets, preSelected, onSubmit, onBack }) => {
990
940
  onSubmit([...selected]);
991
941
  }
992
942
  });
993
- return /* @__PURE__ */ jsxs11(
943
+ return /* @__PURE__ */ jsxs(
994
944
  StepShell,
995
945
  {
996
946
  title: "Select Surface targets/slots",
997
947
  hint: "Space to toggle, Enter to confirm",
998
948
  onBack,
999
949
  children: [
1000
- /* @__PURE__ */ jsx11(Box11, { flexDirection: "column", gap: 1, children: availableTargets.map((target, i) => {
950
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", gap: 1, children: availableTargets.map((target, i) => {
1001
951
  const isSelected = selected.has(target);
1002
952
  const isCursor = i === cursor;
1003
- return /* @__PURE__ */ jsxs11(Box11, { gap: 1, children: [
1004
- /* @__PURE__ */ jsx11(Text11, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
1005
- /* @__PURE__ */ jsx11(Text11, { color: isSelected ? "green" : void 0, children: isSelected ? "\u25C9" : "\u25CB" }),
1006
- /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
1007
- /* @__PURE__ */ jsx11(Text11, { bold: isSelected, children: target }),
1008
- /* @__PURE__ */ jsx11(Text11, { dimColor: true, children: TARGET_DESCRIPTIONS[target] ?? target })
953
+ return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
954
+ /* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
955
+ /* @__PURE__ */ jsx(Text, { color: isSelected ? "green" : void 0, children: isSelected ? "\u25C9" : "\u25CB" }),
956
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
957
+ /* @__PURE__ */ jsx(Text, { bold: isSelected, children: target }),
958
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: TARGET_DESCRIPTIONS[target] ?? target })
1009
959
  ] })
1010
960
  ] }, target);
1011
961
  }) }),
1012
- error && /* @__PURE__ */ jsx11(Text11, { color: "red", children: error })
962
+ error && /* @__PURE__ */ jsx(Text, { color: "red", children: error })
1013
963
  ]
1014
964
  }
1015
965
  );
1016
966
  };
1017
-
1018
- // src/components/TemplateSelect.tsx
1019
- import { Box as Box12, Text as Text12, useInput as useInput7 } from "ink";
1020
- import { useState as useState7 } from "react";
1021
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1022
967
  var FLAVORS = ["minimal", "starter", "kitchen-sink"];
1023
968
  var TemplateSelect = ({ onSubmit, onBack }) => {
1024
- const [cursor, setCursor] = useState7(1);
1025
- useInput7((_input, key) => {
969
+ const [cursor, setCursor] = useState(1);
970
+ useInput((_input, key) => {
1026
971
  if (key.upArrow) {
1027
972
  setCursor((c) => Math.max(0, c - 1));
1028
973
  return;
@@ -1035,21 +980,21 @@ var TemplateSelect = ({ onSubmit, onBack }) => {
1035
980
  onSubmit(FLAVORS[cursor]);
1036
981
  }
1037
982
  });
1038
- return /* @__PURE__ */ jsx12(
983
+ return /* @__PURE__ */ jsx(
1039
984
  StepShell,
1040
985
  {
1041
986
  title: "Choose a template",
1042
987
  hint: "\u2191\u2193 to navigate, Enter to select",
1043
988
  onBack,
1044
- children: /* @__PURE__ */ jsx12(Box12, { flexDirection: "column", gap: 1, children: FLAVORS.map((flavor, i) => {
989
+ children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", gap: 1, children: FLAVORS.map((flavor, i) => {
1045
990
  const meta = TEMPLATE_FLAVOR_META[flavor];
1046
991
  const isCursor = i === cursor;
1047
- return /* @__PURE__ */ jsxs12(Box12, { gap: 1, children: [
1048
- /* @__PURE__ */ jsx12(Text12, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
1049
- /* @__PURE__ */ jsx12(Text12, { color: isCursor ? "green" : void 0, children: isCursor ? "\u25C9" : "\u25CB" }),
1050
- /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
1051
- /* @__PURE__ */ jsx12(Text12, { bold: isCursor, children: meta.label }),
1052
- /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: meta.description })
992
+ return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
993
+ /* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
994
+ /* @__PURE__ */ jsx(Text, { color: isCursor ? "green" : void 0, children: isCursor ? "\u25C9" : "\u25CB" }),
995
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
996
+ /* @__PURE__ */ jsx(Text, { bold: isCursor, children: meta.label }),
997
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: meta.description })
1053
998
  ] })
1054
999
  ] }, flavor);
1055
1000
  }) })
@@ -1057,11 +1002,6 @@ var TemplateSelect = ({ onSubmit, onBack }) => {
1057
1002
  );
1058
1003
  };
1059
1004
 
1060
- // src/components/AppSelect.tsx
1061
- import { Box as Box13, Text as Text13, useInput as useInput8 } from "ink";
1062
- import Spinner2 from "ink-spinner";
1063
- import { useEffect as useEffect2, useState as useState8 } from "react";
1064
-
1065
1005
  // src/lib/api.ts
1066
1006
  var DEFAULT_ADMIN_API_URL = "https://api-use1.stackablelabs.io/admin";
1067
1007
  var DEFAULT_PUBLIC_API_URL = "https://api.stackablelabs.io/app-extension/v1";
@@ -1193,18 +1133,15 @@ var updateExtension = async (token, appId, extensionId, payload) => {
1193
1133
  throw new Error(`Failed to update extension: ${res.status} ${body}`);
1194
1134
  }
1195
1135
  };
1196
-
1197
- // src/components/AppSelect.tsx
1198
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1199
1136
  var AppSelect = ({ token, userId, orgId, onSubmit }) => {
1200
- const [apps, setApps] = useState8([]);
1201
- const [loading, setLoading] = useState8(true);
1202
- const [error, setError] = useState8();
1203
- const [cursor, setCursor] = useState8(0);
1204
- useEffect2(() => {
1137
+ const [apps, setApps] = useState([]);
1138
+ const [loading, setLoading] = useState(true);
1139
+ const [error, setError] = useState();
1140
+ const [cursor, setCursor] = useState(0);
1141
+ useEffect(() => {
1205
1142
  fetchApps(token).then(setApps).catch((err) => setError(err instanceof Error ? err.message : String(err))).finally(() => setLoading(false));
1206
1143
  }, [token]);
1207
- useInput8((_, key) => {
1144
+ useInput((_, key) => {
1208
1145
  if (loading || error || apps.length === 0) return;
1209
1146
  if (key.upArrow) {
1210
1147
  setCursor((c) => Math.max(0, c - 1));
@@ -1216,26 +1153,26 @@ var AppSelect = ({ token, userId, orgId, onSubmit }) => {
1216
1153
  });
1217
1154
  const renderContent = () => {
1218
1155
  if (loading) {
1219
- return /* @__PURE__ */ jsxs13(Box13, { gap: 2, children: [
1220
- /* @__PURE__ */ jsx13(Spinner2, { type: "dots" }),
1221
- /* @__PURE__ */ jsx13(Text13, { children: "Loading available Apps\u2026" })
1156
+ return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
1157
+ /* @__PURE__ */ jsx(Spinner5, { type: "dots" }),
1158
+ /* @__PURE__ */ jsx(Text, { children: "Loading available Apps\u2026" })
1222
1159
  ] });
1223
1160
  }
1224
1161
  if (error) {
1225
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", gap: 1, children: [
1226
- /* @__PURE__ */ jsx13(Text13, { color: "red", bold: true, children: "Failed to load Apps" }),
1227
- /* @__PURE__ */ jsx13(Text13, { color: "red", children: error })
1162
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
1163
+ /* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "Failed to load Apps" }),
1164
+ /* @__PURE__ */ jsx(Text, { color: "red", children: error })
1228
1165
  ] });
1229
1166
  }
1230
1167
  if (apps.length === 0) {
1231
- return /* @__PURE__ */ jsx13(Text13, { color: "yellow", children: "No Apps available. Contact your administrator." });
1168
+ return /* @__PURE__ */ jsx(Text, { color: "yellow", children: "No Apps available. Contact your administrator." });
1232
1169
  }
1233
- return /* @__PURE__ */ jsx13(Box13, { flexDirection: "column", children: apps.map((app, i) => {
1170
+ return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: apps.map((app, i) => {
1234
1171
  const isCursor = i === cursor;
1235
- return /* @__PURE__ */ jsxs13(Box13, { gap: 1, children: [
1236
- /* @__PURE__ */ jsx13(Text13, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
1237
- /* @__PURE__ */ jsx13(Text13, { bold: isCursor, children: app.name }),
1238
- /* @__PURE__ */ jsxs13(Text13, { dimColor: true, children: [
1172
+ return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
1173
+ /* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
1174
+ /* @__PURE__ */ jsx(Text, { bold: isCursor, children: app.name }),
1175
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
1239
1176
  "(",
1240
1177
  app.id,
1241
1178
  ")"
@@ -1243,26 +1180,20 @@ var AppSelect = ({ token, userId, orgId, onSubmit }) => {
1243
1180
  ] }, app.id);
1244
1181
  }) });
1245
1182
  };
1246
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
1247
- /* @__PURE__ */ jsx13(Banner, { userId, orgId }),
1248
- /* @__PURE__ */ jsx13(StepShell, { title: "Select the App you are building an Extension for:", children: renderContent() })
1183
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
1184
+ /* @__PURE__ */ jsx(Banner, { userId, orgId }),
1185
+ /* @__PURE__ */ jsx(StepShell, { title: "Select the App you are building an Extension for:", children: renderContent() })
1249
1186
  ] });
1250
1187
  };
1251
-
1252
- // src/components/ExtensionSelect.tsx
1253
- import { Box as Box14, Text as Text14, useInput as useInput9 } from "ink";
1254
- import Spinner3 from "ink-spinner";
1255
- import { useEffect as useEffect3, useState as useState9 } from "react";
1256
- import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
1257
1188
  var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
1258
- const [extensions, setExtensions] = useState9([]);
1259
- const [loading, setLoading] = useState9(true);
1260
- const [error, setError] = useState9();
1261
- const [cursor, setCursor] = useState9(0);
1262
- useEffect3(() => {
1189
+ const [extensions, setExtensions] = useState([]);
1190
+ const [loading, setLoading] = useState(true);
1191
+ const [error, setError] = useState();
1192
+ const [cursor, setCursor] = useState(0);
1193
+ useEffect(() => {
1263
1194
  fetchExtensions(token, appId).then((byId) => setExtensions(Object.values(byId))).catch((err) => setError(err instanceof Error ? err.message : String(err))).finally(() => setLoading(false));
1264
1195
  }, [appId, token]);
1265
- useInput9((_, key) => {
1196
+ useInput((_, key) => {
1266
1197
  if (key.upArrow) {
1267
1198
  if (!loading && !error && extensions.length > 0) {
1268
1199
  setCursor((c) => Math.max(0, c - 1));
@@ -1283,30 +1214,30 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
1283
1214
  });
1284
1215
  const renderContent = () => {
1285
1216
  if (loading) {
1286
- return /* @__PURE__ */ jsxs14(Box14, { gap: 2, children: [
1287
- /* @__PURE__ */ jsx14(Spinner3, { type: "dots" }),
1288
- /* @__PURE__ */ jsx14(Text14, { children: "Loading Extensions\u2026" })
1217
+ return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
1218
+ /* @__PURE__ */ jsx(Spinner5, { type: "dots" }),
1219
+ /* @__PURE__ */ jsx(Text, { children: "Loading Extensions\u2026" })
1289
1220
  ] });
1290
1221
  }
1291
1222
  if (error) {
1292
- return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", gap: 1, children: [
1293
- /* @__PURE__ */ jsx14(Text14, { color: "red", bold: true, children: "Failed to load Extensions" }),
1294
- /* @__PURE__ */ jsx14(Text14, { color: "red", children: error })
1223
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
1224
+ /* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "Failed to load Extensions" }),
1225
+ /* @__PURE__ */ jsx(Text, { color: "red", children: error })
1295
1226
  ] });
1296
1227
  }
1297
1228
  if (extensions.length === 0) {
1298
- return /* @__PURE__ */ jsx14(Text14, { color: "yellow", children: "No Extensions found for this App." });
1229
+ return /* @__PURE__ */ jsx(Text, { color: "yellow", children: "No Extensions found for this App." });
1299
1230
  }
1300
- return /* @__PURE__ */ jsx14(Box14, { flexDirection: "column", children: extensions.map((ext, i) => {
1231
+ return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: extensions.map((ext, i) => {
1301
1232
  const isCursor = i === cursor;
1302
- return /* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
1303
- /* @__PURE__ */ jsx14(Text14, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
1304
- /* @__PURE__ */ jsx14(Text14, { bold: isCursor, children: ext.manifest.name }),
1305
- /* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
1233
+ return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
1234
+ /* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
1235
+ /* @__PURE__ */ jsx(Text, { bold: isCursor, children: ext.manifest.name }),
1236
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
1306
1237
  "v",
1307
1238
  ext.manifest.version
1308
1239
  ] }),
1309
- /* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
1240
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
1310
1241
  "(",
1311
1242
  ext.id,
1312
1243
  ")"
@@ -1314,7 +1245,7 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
1314
1245
  ] }, ext.id);
1315
1246
  }) });
1316
1247
  };
1317
- return /* @__PURE__ */ jsx14(
1248
+ return /* @__PURE__ */ jsx(
1318
1249
  StepShell,
1319
1250
  {
1320
1251
  title: command === "update" /* UPDATE */ ? "Select an Extension to update:" : "Select an existing Extension to scaffold:",
@@ -1323,9 +1254,6 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
1323
1254
  }
1324
1255
  );
1325
1256
  };
1326
-
1327
- // src/hooks/useWizardSteps.ts
1328
- import { useCallback, useMemo, useState as useState10 } from "react";
1329
1257
  var STEPS = {
1330
1258
  ["create" /* CREATE */]: ["app", "name", "template", "targets", "settings", "confirm"],
1331
1259
  ["scaffold" /* SCAFFOLD */]: ["app", "extensionSelect", "template", "confirmTargets", "settings", "confirm"],
@@ -1364,7 +1292,7 @@ var computeActiveSteps = (conditions) => {
1364
1292
  return base.filter((s) => !skipped.has(s));
1365
1293
  };
1366
1294
  var useWizardSteps = (opts) => {
1367
- const [step, setStep] = useState10("app");
1295
+ const [step, setStep] = useState("app");
1368
1296
  const activeSteps = useMemo(
1369
1297
  () => computeActiveSteps(opts),
1370
1298
  [
@@ -1407,11 +1335,6 @@ var useWizardSteps = (opts) => {
1407
1335
  }, []);
1408
1336
  return { step, activeSteps, goForward, goBack, goTo };
1409
1337
  };
1410
-
1411
- // src/lib/postScaffold.ts
1412
- import { execFile } from "child_process";
1413
- import { promisify } from "util";
1414
- import { installDependencies } from "nypm";
1415
1338
  var execFileAsync = promisify(execFile);
1416
1339
  var gitInit = async (dir) => {
1417
1340
  try {
@@ -1425,19 +1348,10 @@ var postScaffold = async (options) => {
1425
1348
  if (!options.skipGit) {
1426
1349
  await gitInit(options.outputDir);
1427
1350
  }
1428
- if (!options.skipInstall) {
1351
+ {
1429
1352
  await installDependencies({ cwd: options.outputDir, silent: true });
1430
1353
  }
1431
1354
  };
1432
-
1433
- // src/lib/scaffold.ts
1434
- import { readFile as readFile2, readdir, rm, writeFile as writeFile2 } from "fs/promises";
1435
- import { join as join2 } from "path";
1436
- import { downloadTemplate } from "giget";
1437
-
1438
- // src/lib/devContext.ts
1439
- import { readFile, writeFile } from "fs/promises";
1440
- import { join } from "path";
1441
1355
  var parseEnvFile = (content) => {
1442
1356
  const lines = content.split("\n");
1443
1357
  const env = {};
@@ -1541,7 +1455,7 @@ var deriveScaffoldPermissions = (targets) => {
1541
1455
  };
1542
1456
  var upsertOrRemove = async (filePath, shouldExist, content) => {
1543
1457
  if (shouldExist) {
1544
- await writeFile2(filePath, content);
1458
+ await writeFile(filePath, content);
1545
1459
  return;
1546
1460
  }
1547
1461
  await rm(filePath, { force: true });
@@ -1553,7 +1467,7 @@ var walkFiles = async (rootDir) => {
1553
1467
  if (entry.name === ".git" || entry.name === "node_modules" || entry.name === "dist") {
1554
1468
  continue;
1555
1469
  }
1556
- const fullPath = join2(rootDir, entry.name);
1470
+ const fullPath = join(rootDir, entry.name);
1557
1471
  if (entry.isDirectory()) {
1558
1472
  files.push(...await walkFiles(fullPath));
1559
1473
  continue;
@@ -1568,7 +1482,7 @@ var replacePlaceholders = async (rootDir, replacements) => {
1568
1482
  if (!isTextFile(filePath)) {
1569
1483
  continue;
1570
1484
  }
1571
- let content = await readFile2(filePath, "utf8");
1485
+ let content = await readFile(filePath, "utf8");
1572
1486
  let changed = false;
1573
1487
  for (const [needle, value] of Object.entries(replacements)) {
1574
1488
  if (content.includes(needle)) {
@@ -1577,18 +1491,18 @@ var replacePlaceholders = async (rootDir, replacements) => {
1577
1491
  }
1578
1492
  }
1579
1493
  if (changed) {
1580
- await writeFile2(filePath, content);
1494
+ await writeFile(filePath, content);
1581
1495
  }
1582
1496
  }
1583
1497
  };
1584
1498
  var generateManifest = async (rootDir, extensionName, targets, permissions) => {
1585
- const manifestPath = join2(rootDir, "packages/extension/public/manifest.json");
1586
- const raw = await readFile2(manifestPath, "utf8");
1499
+ const manifestPath = join(rootDir, "packages/extension/public/manifest.json");
1500
+ const raw = await readFile(manifestPath, "utf8");
1587
1501
  const manifest = JSON.parse(raw);
1588
1502
  manifest.name = extensionName;
1589
1503
  manifest.targets = targets;
1590
1504
  manifest.permissions = permissions;
1591
- await writeFile2(manifestPath, `${JSON.stringify(manifest, null, 2)}
1505
+ await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
1592
1506
  `);
1593
1507
  };
1594
1508
  var buildFooterSurface = (targets) => {
@@ -1615,12 +1529,12 @@ ${blocks.join("\n")}
1615
1529
  `;
1616
1530
  };
1617
1531
  var generateSurfaceFiles = async (rootDir, targets) => {
1618
- const surfaceDir = join2(rootDir, "packages/extension/src/surfaces");
1532
+ const surfaceDir = join(rootDir, "packages/extension/src/surfaces");
1619
1533
  const wantsHeader = targets.includes("slot.header");
1620
1534
  const wantsContent = targets.includes("slot.content");
1621
1535
  const wantsFooter = targets.includes("slot.footer") || targets.includes("slot.footer-links");
1622
1536
  await upsertOrRemove(
1623
- join2(surfaceDir, "Header.tsx"),
1537
+ join(surfaceDir, "Header.tsx"),
1624
1538
  wantsHeader,
1625
1539
  `import { ui, Surface } from '@stackable-labs/sdk-extension-react'
1626
1540
 
@@ -1634,7 +1548,7 @@ export function Header() {
1634
1548
  `
1635
1549
  );
1636
1550
  await upsertOrRemove(
1637
- join2(surfaceDir, "Content.tsx"),
1551
+ join(surfaceDir, "Content.tsx"),
1638
1552
  wantsContent,
1639
1553
  `import { ui, useStore, useContextData, Surface } from '@stackable-labs/sdk-extension-react'
1640
1554
  import { appStore } from '../store'
@@ -1667,14 +1581,14 @@ export function Content() {
1667
1581
  `
1668
1582
  );
1669
1583
  await upsertOrRemove(
1670
- join2(rootDir, "packages/extension/src/store.ts"),
1584
+ join(rootDir, "packages/extension/src/store.ts"),
1671
1585
  wantsContent,
1672
1586
  "import { createStore } from '@stackable-labs/sdk-extension-react'\n\nexport type ViewState = { type: 'menu' }\n\nexport interface AppState {\n viewState: ViewState\n}\n\nexport const appStore = createStore<AppState>({\n viewState: { type: 'menu' },\n})\n"
1673
1587
  );
1674
- await upsertOrRemove(join2(surfaceDir, "Footer.tsx"), wantsFooter, buildFooterSurface(targets));
1588
+ await upsertOrRemove(join(surfaceDir, "Footer.tsx"), wantsFooter, buildFooterSurface(targets));
1675
1589
  };
1676
1590
  var rewriteExtensionIndex = async (rootDir, extensionId, targets) => {
1677
- const indexPath = join2(rootDir, "packages/extension/src/index.tsx");
1591
+ const indexPath = join(rootDir, "packages/extension/src/index.tsx");
1678
1592
  const imports = ["import { createExtension } from '@stackable-labs/sdk-extension-react'"];
1679
1593
  const components = [];
1680
1594
  if (targets.includes("slot.header")) {
@@ -1700,10 +1614,10 @@ ${components.join("\n")}
1700
1614
  { extensionId: '${toKebabCase(extensionId)}' },
1701
1615
  )
1702
1616
  `;
1703
- await writeFile2(indexPath, content);
1617
+ await writeFile(indexPath, content);
1704
1618
  };
1705
1619
  var rewritePreviewApp = async (rootDir, targets, permissions) => {
1706
- const appPath = join2(rootDir, "packages/preview/src/App.tsx");
1620
+ const appPath = join(rootDir, "packages/preview/src/App.tsx");
1707
1621
  const includeDataQuery = permissions.includes("data:query");
1708
1622
  const includeToast = permissions.includes("actions:toast");
1709
1623
  const includeInvoke = permissions.includes("actions:invoke");
@@ -1782,17 +1696,17 @@ export default function App() {
1782
1696
  )
1783
1697
  }
1784
1698
  `;
1785
- await writeFile2(appPath, appContent);
1699
+ await writeFile(appPath, appContent);
1786
1700
  };
1787
1701
  var patchViteAllowedHosts = async (rootDir) => {
1788
1702
  const configs = [
1789
- join2(rootDir, "packages/extension/vite.config.ts"),
1790
- join2(rootDir, "packages/preview/vite.config.ts")
1703
+ join(rootDir, "packages/extension/vite.config.ts"),
1704
+ join(rootDir, "packages/preview/vite.config.ts")
1791
1705
  ];
1792
1706
  for (const configPath of configs) {
1793
1707
  let content;
1794
1708
  try {
1795
- content = await readFile2(configPath, "utf8");
1709
+ content = await readFile(configPath, "utf8");
1796
1710
  } catch {
1797
1711
  continue;
1798
1712
  }
@@ -1802,38 +1716,38 @@ var patchViteAllowedHosts = async (rootDir) => {
1802
1716
  "server: {\n allowedHosts: true,"
1803
1717
  );
1804
1718
  if (patched !== content) {
1805
- await writeFile2(configPath, patched);
1719
+ await writeFile(configPath, patched);
1806
1720
  }
1807
1721
  }
1808
1722
  };
1809
1723
  var rewriteTurboJson = async (rootDir) => {
1810
- const turboPath = join2(rootDir, "turbo.json");
1811
- const raw = await readFile2(turboPath, "utf8");
1724
+ const turboPath = join(rootDir, "turbo.json");
1725
+ const raw = await readFile(turboPath, "utf8");
1812
1726
  const turbo = JSON.parse(raw);
1813
1727
  delete turbo["extends"];
1814
1728
  turbo["globalEnv"] = ["VITE_EXTENSION_PORT", "VITE_PREVIEW_PORT", "VITE_EXTENSION_BUNDLE_URL"];
1815
- await writeFile2(turboPath, `${JSON.stringify(turbo, null, 2)}
1729
+ await writeFile(turboPath, `${JSON.stringify(turbo, null, 2)}
1816
1730
  `);
1817
1731
  };
1818
1732
  var writeEnvFile2 = async (dir, extensionPort, previewPort) => {
1819
- const envPath = join2(dir, ".env");
1733
+ const envPath = join(dir, ".env");
1820
1734
  const content = `VITE_EXTENSION_PORT=${extensionPort}
1821
1735
  VITE_PREVIEW_PORT=${previewPort}
1822
1736
  `;
1823
- await writeFile2(envPath, content);
1737
+ await writeFile(envPath, content);
1824
1738
  };
1825
1739
  var updateGitignore = async (dir) => {
1826
- const gitignorePath = join2(dir, ".gitignore");
1740
+ const gitignorePath = join(dir, ".gitignore");
1827
1741
  let gitignore = "";
1828
1742
  try {
1829
- gitignore = await readFile2(gitignorePath, "utf8");
1743
+ gitignore = await readFile(gitignorePath, "utf8");
1830
1744
  } catch {
1831
1745
  }
1832
1746
  if (!gitignore.includes(".env.stackable")) {
1833
1747
  const newGitignore = gitignore ? `${gitignore}
1834
1748
  .env.stackable
1835
1749
  ` : ".env.stackable\n";
1836
- await writeFile2(gitignorePath, newGitignore);
1750
+ await writeFile(gitignorePath, newGitignore);
1837
1751
  }
1838
1752
  };
1839
1753
  var scaffold = async (options) => {
@@ -1863,32 +1777,25 @@ var scaffold = async (options) => {
1863
1777
  await writeEnvFile2(dir, options.extensionPort, options.previewPort);
1864
1778
  await updateGitignore(dir);
1865
1779
  await writeDevContext(dir, {
1866
- projectRoot: dir,
1867
- orgId: null,
1868
1780
  appId: options.appId,
1869
1781
  extensionId: toKebabCase(options.extensionId || options.name),
1870
1782
  appName: options.appName || null,
1871
1783
  extensionName: options.name,
1872
1784
  extensionPort: options.extensionPort,
1873
- previewPort: options.previewPort,
1874
- manifest: null
1875
- });
1785
+ previewPort: options.previewPort});
1876
1786
  if (options.projectFiles) {
1877
- const extensionSrcDir = join2(dir, "packages/extension/src");
1787
+ const extensionSrcDir = join(dir, "packages/extension/src");
1878
1788
  for (const [filename, content] of Object.entries(options.projectFiles)) {
1879
- await writeFile2(join2(extensionSrcDir, filename), content);
1789
+ await writeFile(join(extensionSrcDir, filename), content);
1880
1790
  }
1881
1791
  }
1882
1792
  if (options.projectManifest) {
1883
- const manifestPath = join2(dir, "packages/extension/public/manifest.json");
1884
- await writeFile2(manifestPath, `${JSON.stringify(options.projectManifest, null, 2)}
1793
+ const manifestPath = join(dir, "packages/extension/public/manifest.json");
1794
+ await writeFile(manifestPath, `${JSON.stringify(options.projectManifest, null, 2)}
1885
1795
  `);
1886
1796
  }
1887
1797
  return options;
1888
1798
  };
1889
-
1890
- // src/App.tsx
1891
- import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
1892
1799
  var PROGRESS_STEPS = {
1893
1800
  ["create" /* CREATE */]: [
1894
1801
  { label: "Registering Extension", status: "pending" },
@@ -1926,39 +1833,39 @@ var deriveRegistryPermissions = (targets) => {
1926
1833
  };
1927
1834
  var App = ({ command, token, userId, orgId, initialName, initialExtensionId, options }) => {
1928
1835
  const { exit } = useApp();
1929
- const [name, setName] = useState11(initialName ?? options?.name ?? "");
1930
- const [extensionId, setExtensionId] = useState11(initialExtensionId ?? "");
1931
- const [extensionVersion, setExtensionVersion] = useState11("");
1932
- const [bundleUrl, setBundleUrl] = useState11(options?.bundleUrl ?? "");
1933
- const [enabled, setEnabled] = useState11(
1836
+ const [name, setName] = useState(initialName ?? options?.name ?? "");
1837
+ const [extensionId, setExtensionId] = useState(initialExtensionId ?? "");
1838
+ const [extensionVersion, setExtensionVersion] = useState("");
1839
+ const [bundleUrl, setBundleUrl] = useState(options?.bundleUrl ?? "");
1840
+ const [enabled, setEnabled] = useState(
1934
1841
  options?.enabled !== void 0 ? options.enabled !== "false" : true
1935
1842
  );
1936
- const [versionOverride, setVersionOverride] = useState11(void 0);
1937
- const [forceMajor, setForceMajor] = useState11(false);
1938
- const [initialExtension, setInitialExtension] = useState11(null);
1939
- const [templateFlavor, setTemplateFlavor] = useState11(
1843
+ const [versionOverride, setVersionOverride] = useState(void 0);
1844
+ const [forceMajor, setForceMajor] = useState(false);
1845
+ const [initialExtension, setInitialExtension] = useState(null);
1846
+ const [templateFlavor, setTemplateFlavor] = useState(
1940
1847
  options?.template ?? "starter"
1941
1848
  );
1942
- const [targets, setTargets] = useState11(
1849
+ const [targets, setTargets] = useState(
1943
1850
  options?.targets ? options.targets.split(",").map((t) => t.trim()) : []
1944
1851
  );
1945
- const [selectedApp, setSelectedApp] = useState11(null);
1946
- const [extensionPort, setExtensionPort] = useState11(
1852
+ const [selectedApp, setSelectedApp] = useState(null);
1853
+ const [extensionPort, setExtensionPort] = useState(
1947
1854
  options?.extensionPort ? parseInt(options.extensionPort, 10) : 6543
1948
1855
  );
1949
- const [previewPort, setPreviewPort] = useState11(
1856
+ const [previewPort, setPreviewPort] = useState(
1950
1857
  options?.previewPort ? parseInt(options.previewPort, 10) : 6544
1951
1858
  );
1952
- const [registryManifest, setRegistryManifest] = useState11(null);
1953
- const [localManifest, setLocalManifest] = useState11(null);
1954
- const [confirmedPermissions, setConfirmedPermissions] = useState11([]);
1955
- const [confirmedAllowedDomains, setConfirmedAllowedDomains] = useState11([]);
1956
- const [userEditedAllowedDomains, setUserEditedAllowedDomains] = useState11([]);
1957
- const [outputDir, setOutputDir] = useState11("");
1958
- const [studioProject, setStudioProject] = useState11(null);
1959
- const [hasLocalProject, setHasLocalProject] = useState11(false);
1960
- const [progressSteps, setProgressSteps] = useState11(PROGRESS_STEPS[command]);
1961
- const [errorMessage, setErrorMessage] = useState11();
1859
+ const [registryManifest, setRegistryManifest] = useState(null);
1860
+ const [localManifest, setLocalManifest] = useState(null);
1861
+ const [confirmedPermissions, setConfirmedPermissions] = useState([]);
1862
+ const [confirmedAllowedDomains, setConfirmedAllowedDomains] = useState([]);
1863
+ const [userEditedAllowedDomains, setUserEditedAllowedDomains] = useState([]);
1864
+ const [outputDir, setOutputDir] = useState("");
1865
+ const [studioProject, setStudioProject] = useState(null);
1866
+ const [hasLocalProject, setHasLocalProject] = useState(false);
1867
+ const [progressSteps, setProgressSteps] = useState(PROGRESS_STEPS[command]);
1868
+ const [errorMessage, setErrorMessage] = useState();
1962
1869
  const { step, goForward, goBack, goTo } = useWizardSteps({
1963
1870
  command,
1964
1871
  initialName,
@@ -1968,7 +1875,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
1968
1875
  hasLocalProject,
1969
1876
  options
1970
1877
  });
1971
- const updateStep = useCallback2((index, status) => {
1878
+ const updateStep = useCallback((index, status) => {
1972
1879
  setProgressSteps((prev) => prev.map((s, i) => i === index ? { ...s, status } : s));
1973
1880
  }, []);
1974
1881
  const handleAppSelect = async (app) => {
@@ -2018,8 +1925,8 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2018
1925
  if (command === "update" /* UPDATE */ || command === "scaffold" /* SCAFFOLD */) {
2019
1926
  const projectRoot = options?.dir || process.cwd();
2020
1927
  try {
2021
- const manifestPath = join3(projectRoot, "packages/extension/public/manifest.json");
2022
- const content = await readFile3(manifestPath, "utf8");
1928
+ const manifestPath = join(projectRoot, "packages/extension/public/manifest.json");
1929
+ const content = await readFile(manifestPath, "utf8");
2023
1930
  setLocalManifest(JSON.parse(content));
2024
1931
  setHasLocalProject(true);
2025
1932
  localProjectFound = true;
@@ -2040,13 +1947,13 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2040
1947
  if (meta.skipTargetStep && meta.defaultTargets) {
2041
1948
  setTargets(meta.defaultTargets);
2042
1949
  if (options?.extensionPort || options?.previewPort) {
2043
- setOutputDir(join3(process.cwd(), toKebabCase(initialName)));
1950
+ setOutputDir(join(process.cwd(), toKebabCase(initialName)));
2044
1951
  }
2045
1952
  }
2046
1953
  }
2047
1954
  goForward();
2048
1955
  };
2049
- useEffect4(() => {
1956
+ useEffect(() => {
2050
1957
  if (!options?.appId) return;
2051
1958
  fetchApps(token).then((apps) => {
2052
1959
  const app = apps.find((a) => a.id === options.appId);
@@ -2061,7 +1968,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2061
1968
  goTo("error");
2062
1969
  });
2063
1970
  }, []);
2064
- useEffect4(() => {
1971
+ useEffect(() => {
2065
1972
  if (options?.appId || !initialExtensionId) return;
2066
1973
  if (command !== "update" /* UPDATE */ && command !== "scaffold" /* SCAFFOLD */) return;
2067
1974
  resolveAppForExtension(token, initialExtensionId).then((result) => {
@@ -2094,8 +2001,8 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2094
2001
  let localProjectFound = false;
2095
2002
  const projectRoot = options?.dir || process.cwd();
2096
2003
  try {
2097
- const manifestPath = join3(projectRoot, "packages/extension/public/manifest.json");
2098
- const content = await readFile3(manifestPath, "utf8");
2004
+ const manifestPath = join(projectRoot, "packages/extension/public/manifest.json");
2005
+ const content = await readFile(manifestPath, "utf8");
2099
2006
  setLocalManifest(JSON.parse(content));
2100
2007
  setHasLocalProject(true);
2101
2008
  localProjectFound = true;
@@ -2107,7 +2014,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2107
2014
  const handleConfirmTargets = (value) => {
2108
2015
  setTargets(value);
2109
2016
  if (options?.extensionPort || options?.previewPort) {
2110
- setOutputDir(join3(process.cwd(), toKebabCase(name || extensionId)));
2017
+ setOutputDir(join(process.cwd(), toKebabCase(name || extensionId)));
2111
2018
  }
2112
2019
  goForward();
2113
2020
  };
@@ -2121,7 +2028,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2121
2028
  }
2122
2029
  }
2123
2030
  if (options?.extensionPort || options?.previewPort) {
2124
- setOutputDir(join3(process.cwd(), toKebabCase(value)));
2031
+ setOutputDir(join(process.cwd(), toKebabCase(value)));
2125
2032
  }
2126
2033
  goForward();
2127
2034
  };
@@ -2132,14 +2039,14 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2132
2039
  setTargets(meta.defaultTargets);
2133
2040
  }
2134
2041
  if (options?.extensionPort || options?.previewPort) {
2135
- setOutputDir(join3(process.cwd(), toKebabCase(name || extensionId)));
2042
+ setOutputDir(join(process.cwd(), toKebabCase(name || extensionId)));
2136
2043
  }
2137
2044
  goForward({ templateFlavor: flavor });
2138
2045
  };
2139
2046
  const handleTargets = (value) => {
2140
2047
  setTargets(value);
2141
2048
  if (options?.extensionPort || options?.previewPort) {
2142
- setOutputDir(join3(process.cwd(), toKebabCase(name || extensionId)));
2049
+ setOutputDir(join(process.cwd(), toKebabCase(name || extensionId)));
2143
2050
  }
2144
2051
  goForward();
2145
2052
  };
@@ -2237,9 +2144,9 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2237
2144
  }
2238
2145
  }
2239
2146
  if (command === "create" /* CREATE */) {
2240
- const manifestPath = join3(outputDir, "packages/extension/public/manifest.json");
2147
+ const manifestPath = join(outputDir, "packages/extension/public/manifest.json");
2241
2148
  try {
2242
- const manifestContent = await readFile3(manifestPath, "utf8");
2149
+ const manifestContent = await readFile(manifestPath, "utf8");
2243
2150
  const manifest = JSON.parse(manifestContent);
2244
2151
  await updateExtension(token, selectedApp.id, resolvedExtensionId, {
2245
2152
  manifest: { ...manifest, allowedDomains: [] }
@@ -2248,7 +2155,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2248
2155
  }
2249
2156
  }
2250
2157
  updateStep(scaffoldStepOffset + 1, "running");
2251
- await new Promise((r) => setTimeout(r, 200));
2158
+ await delay(200);
2252
2159
  updateStep(scaffoldStepOffset + 1, "done");
2253
2160
  if (!options?.skipInstall) {
2254
2161
  updateStep(scaffoldStepOffset + 2, "running");
@@ -2270,15 +2177,15 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2270
2177
  switch (step) {
2271
2178
  case "app": {
2272
2179
  if (options?.appId || initialExtensionId && (command === "update" /* UPDATE */ || command === "scaffold" /* SCAFFOLD */)) {
2273
- return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
2274
- /* @__PURE__ */ jsx15(Banner, { userId, orgId }),
2275
- /* @__PURE__ */ jsx15(StepShell, { title: "Loading App\u2026", children: /* @__PURE__ */ jsxs15(Box15, { gap: 2, children: [
2276
- /* @__PURE__ */ jsx15(Spinner4, { type: "dots" }),
2277
- /* @__PURE__ */ jsx15(Text15, { children: options?.appId ? "Fetching app details\u2026" : "Resolving app from extension\u2026" })
2180
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2181
+ /* @__PURE__ */ jsx(Banner, { userId, orgId }),
2182
+ /* @__PURE__ */ jsx(StepShell, { title: "Loading App\u2026", children: /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
2183
+ /* @__PURE__ */ jsx(Spinner5, { type: "dots" }),
2184
+ /* @__PURE__ */ jsx(Text, { children: options?.appId ? "Fetching app details\u2026" : "Resolving app from extension\u2026" })
2278
2185
  ] }) })
2279
2186
  ] });
2280
2187
  }
2281
- return /* @__PURE__ */ jsx15(
2188
+ return /* @__PURE__ */ jsx(
2282
2189
  AppSelect,
2283
2190
  {
2284
2191
  token,
@@ -2289,7 +2196,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2289
2196
  );
2290
2197
  }
2291
2198
  case "extensionSelect": {
2292
- return /* @__PURE__ */ jsx15(
2199
+ return /* @__PURE__ */ jsx(
2293
2200
  ExtensionSelect,
2294
2201
  {
2295
2202
  appId: selectedApp.id,
@@ -2301,7 +2208,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2301
2208
  );
2302
2209
  }
2303
2210
  case "confirmTargets": {
2304
- return /* @__PURE__ */ jsx15(
2211
+ return /* @__PURE__ */ jsx(
2305
2212
  TargetSelect,
2306
2213
  {
2307
2214
  availableTargets: selectedApp?.targets ?? [],
@@ -2312,7 +2219,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2312
2219
  );
2313
2220
  }
2314
2221
  case "name": {
2315
- return /* @__PURE__ */ jsx15(
2222
+ return /* @__PURE__ */ jsx(
2316
2223
  NamePrompt,
2317
2224
  {
2318
2225
  initialValue: name,
@@ -2322,7 +2229,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2322
2229
  );
2323
2230
  }
2324
2231
  case "template": {
2325
- return /* @__PURE__ */ jsx15(
2232
+ return /* @__PURE__ */ jsx(
2326
2233
  TemplateSelect,
2327
2234
  {
2328
2235
  onSubmit: handleTemplateSelect,
@@ -2331,7 +2238,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2331
2238
  );
2332
2239
  }
2333
2240
  case "targets": {
2334
- return /* @__PURE__ */ jsx15(
2241
+ return /* @__PURE__ */ jsx(
2335
2242
  TargetSelect,
2336
2243
  {
2337
2244
  availableTargets: selectedApp?.targets ?? [],
@@ -2342,17 +2249,17 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2342
2249
  );
2343
2250
  }
2344
2251
  case "settings": {
2345
- return /* @__PURE__ */ jsx15(
2252
+ return /* @__PURE__ */ jsx(
2346
2253
  SettingsPrompt,
2347
2254
  {
2348
- defaultDir: join3(process.cwd(), toKebabCase(name || extensionId)),
2255
+ defaultDir: join(process.cwd(), toKebabCase(name || extensionId)),
2349
2256
  onSubmit: handleSettings,
2350
2257
  onBack: goBack
2351
2258
  }
2352
2259
  );
2353
2260
  }
2354
2261
  case "confirm": {
2355
- return /* @__PURE__ */ jsx15(
2262
+ return /* @__PURE__ */ jsx(
2356
2263
  Confirm,
2357
2264
  {
2358
2265
  command,
@@ -2379,10 +2286,10 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2379
2286
  );
2380
2287
  }
2381
2288
  case "scaffolding": {
2382
- return /* @__PURE__ */ jsx15(ScaffoldProgress, { steps: progressSteps });
2289
+ return /* @__PURE__ */ jsx(ScaffoldProgress, { steps: progressSteps });
2383
2290
  }
2384
2291
  case "updateSettings": {
2385
- return /* @__PURE__ */ jsx15(
2292
+ return /* @__PURE__ */ jsx(
2386
2293
  UpdateSettingsPrompt,
2387
2294
  {
2388
2295
  name,
@@ -2406,8 +2313,17 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2406
2313
  );
2407
2314
  }
2408
2315
  case "manifestReview": {
2409
- const effectiveLocalManifest = localManifest ? { ...localManifest, allowedDomains: userEditedAllowedDomains } : userEditedAllowedDomains.length > 0 ? { name, version: "0.0.0", targets, permissions: [], allowedDomains: userEditedAllowedDomains } : localManifest;
2410
- return /* @__PURE__ */ jsx15(
2316
+ const buildEffectiveManifest = () => {
2317
+ if (localManifest) {
2318
+ return { ...localManifest, allowedDomains: userEditedAllowedDomains };
2319
+ }
2320
+ if (userEditedAllowedDomains.length > 0) {
2321
+ return { name, version: "0.0.0", targets, permissions: [], allowedDomains: userEditedAllowedDomains };
2322
+ }
2323
+ return localManifest;
2324
+ };
2325
+ const effectiveLocalManifest = buildEffectiveManifest();
2326
+ return /* @__PURE__ */ jsx(
2411
2327
  ManifestReviewPrompt,
2412
2328
  {
2413
2329
  localManifest: effectiveLocalManifest,
@@ -2422,49 +2338,42 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2422
2338
  );
2423
2339
  }
2424
2340
  case "updating": {
2425
- return /* @__PURE__ */ jsx15(ScaffoldProgress, { steps: progressSteps });
2341
+ return /* @__PURE__ */ jsx(ScaffoldProgress, { steps: progressSteps });
2426
2342
  }
2427
2343
  case "updateDone": {
2428
- return /* @__PURE__ */ jsx15(StepShell, { title: "Extension updated", onBack: goBack, children: /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
2429
- /* @__PURE__ */ jsx15(Text15, { color: "green", bold: true, children: "Extension updated successfully!" }),
2430
- /* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
2344
+ return /* @__PURE__ */ jsx(StepShell, { title: "Extension updated", onBack: goBack, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
2345
+ /* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "Extension updated successfully!" }),
2346
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2431
2347
  "Name: ",
2432
2348
  name
2433
2349
  ] }),
2434
- /* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
2350
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2435
2351
  "ID: ",
2436
2352
  extensionId
2437
2353
  ] }),
2438
- /* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
2354
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2439
2355
  "Version: ",
2440
2356
  extensionVersion
2441
2357
  ] })
2442
2358
  ] }) });
2443
2359
  }
2444
2360
  case "done": {
2445
- return /* @__PURE__ */ jsx15(Done, { name, outputDir, templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0 });
2361
+ return /* @__PURE__ */ jsx(Done, { name, outputDir, templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0 });
2446
2362
  }
2447
2363
  case "error": {
2448
- return /* @__PURE__ */ jsx15(StepShell, { title: "Operation failed", onBack: goBack, children: /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
2449
- /* @__PURE__ */ jsx15(Text15, { color: "red", bold: true, children: "An error occurred" }),
2450
- errorMessage && /* @__PURE__ */ jsx15(Text15, { color: "red", children: errorMessage })
2364
+ return /* @__PURE__ */ jsx(StepShell, { title: "Operation failed", onBack: goBack, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
2365
+ /* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "An error occurred" }),
2366
+ errorMessage && /* @__PURE__ */ jsx(Text, { color: "red", children: errorMessage })
2451
2367
  ] }) });
2452
2368
  }
2453
2369
  default: {
2454
- return /* @__PURE__ */ jsx15(StepShell, { title: "Scaffold failed", onBack: goBack, children: /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
2455
- /* @__PURE__ */ jsx15(Text15, { color: "red", bold: true, children: "An error occurred" }),
2456
- errorMessage && /* @__PURE__ */ jsx15(Text15, { color: "red", children: errorMessage })
2370
+ return /* @__PURE__ */ jsx(StepShell, { title: "Scaffold failed", onBack: goBack, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
2371
+ /* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "An error occurred" }),
2372
+ errorMessage && /* @__PURE__ */ jsx(Text, { color: "red", children: errorMessage })
2457
2373
  ] }) });
2458
2374
  }
2459
2375
  }
2460
2376
  };
2461
-
2462
- // src/components/DevApp.tsx
2463
- import { useRef, useState as useState14, useEffect as useEffect7, useCallback as useCallback4 } from "react";
2464
- import { useInput as useInput12, Box as Box19, Text as Text19 } from "ink";
2465
-
2466
- // src/lib/devServer.ts
2467
- import { spawn } from "child_process";
2468
2377
  var startDevServer = (projectRoot) => {
2469
2378
  const child = spawn("pnpm", ["dev"], {
2470
2379
  cwd: projectRoot,
@@ -2475,9 +2384,6 @@ var startDevServer = (projectRoot) => {
2475
2384
  };
2476
2385
  return { process: child, stop };
2477
2386
  };
2478
-
2479
- // src/lib/tunnel.ts
2480
- import { Tunnel } from "cloudflared";
2481
2387
  var MAX_RETRIES = 3;
2482
2388
  var RETRY_DELAY_MS = 2e3;
2483
2389
  var isValidTunnelUrl = (url) => {
@@ -2514,7 +2420,6 @@ var startTunnelOnce = (port) => new Promise((resolve, reject) => {
2514
2420
  reject(err);
2515
2421
  });
2516
2422
  });
2517
- var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2518
2423
  var startTunnel = async (port) => {
2519
2424
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
2520
2425
  try {
@@ -2531,15 +2436,10 @@ var startTunnel = async (port) => {
2531
2436
  }
2532
2437
  throw new Error(`Tunnel failed to return a valid URL after ${MAX_RETRIES} attempts`);
2533
2438
  };
2534
-
2535
- // src/components/DevSetup.tsx
2536
- import { Box as Box16, Text as Text16 } from "ink";
2537
- import { useState as useState12, useEffect as useEffect5 } from "react";
2538
- import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
2539
2439
  var DevSetup = ({ initialContext, token, onReady }) => {
2540
- const [step, setStep] = useState12("app");
2541
- const [selectedApp, setSelectedApp] = useState12(null);
2542
- useEffect5(() => {
2440
+ const [step, setStep] = useState("app");
2441
+ const [selectedApp, setSelectedApp] = useState(null);
2442
+ useEffect(() => {
2543
2443
  if (initialContext.appId) {
2544
2444
  setStep("extension");
2545
2445
  }
@@ -2556,9 +2456,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
2556
2456
  });
2557
2457
  };
2558
2458
  if (step === "app") {
2559
- return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
2560
- /* @__PURE__ */ jsx16(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text16, { children: "Select the App for your extension:" }) }),
2561
- /* @__PURE__ */ jsx16(
2459
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2460
+ /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { children: "Select the App for your extension:" }) }),
2461
+ /* @__PURE__ */ jsx(
2562
2462
  AppSelect,
2563
2463
  {
2564
2464
  token,
@@ -2567,9 +2467,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
2567
2467
  )
2568
2468
  ] });
2569
2469
  }
2570
- return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
2571
- /* @__PURE__ */ jsx16(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text16, { children: "Select the Extension to develop:" }) }),
2572
- /* @__PURE__ */ jsx16(
2470
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2471
+ /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { children: "Select the Extension to develop:" }) }),
2472
+ /* @__PURE__ */ jsx(
2573
2473
  ExtensionSelect,
2574
2474
  {
2575
2475
  token,
@@ -2579,16 +2479,6 @@ var DevSetup = ({ initialContext, token, onReady }) => {
2579
2479
  )
2580
2480
  ] });
2581
2481
  };
2582
-
2583
- // src/components/DevDashboard.tsx
2584
- import { Box as Box18, Text as Text18, useInput as useInput11 } from "ink";
2585
- import { useEffect as useEffect6, useMemo as useMemo2 } from "react";
2586
-
2587
- // src/components/CopyableField.tsx
2588
- import { useState as useState13, useCallback as useCallback3 } from "react";
2589
- import { useInput as useInput10, Box as Box17, Text as Text17 } from "ink";
2590
- import clipboard from "clipboardy";
2591
- import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
2592
2482
  var CopyableField = ({
2593
2483
  label,
2594
2484
  value,
@@ -2598,9 +2488,9 @@ var CopyableField = ({
2598
2488
  labelColor,
2599
2489
  children
2600
2490
  }) => {
2601
- const [expanded, setExpanded] = useState13(false);
2602
- const [copied, setCopied] = useState13(false);
2603
- const handleCopy = useCallback3(async () => {
2491
+ const [expanded, setExpanded] = useState(false);
2492
+ const [copied, setCopied] = useState(false);
2493
+ const handleCopy = useCallback(async () => {
2604
2494
  if (expanded) {
2605
2495
  setExpanded(false);
2606
2496
  setCopied(false);
@@ -2618,20 +2508,20 @@ var CopyableField = ({
2618
2508
  setExpanded(true);
2619
2509
  }
2620
2510
  }, [expanded, value]);
2621
- useInput10((input) => {
2511
+ useInput((input) => {
2622
2512
  if (input === shortcutKey) {
2623
2513
  handleCopy();
2624
2514
  }
2625
2515
  });
2626
2516
  const truncated = value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;
2627
2517
  const keyHint = shortcutLabel || shortcutKey;
2628
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
2629
- /* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
2630
- /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: label }),
2631
- copied && /* @__PURE__ */ jsx17(Text17, { color: "green", bold: true, children: "Copied!" }),
2632
- !copied && /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
2518
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2519
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
2520
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: label }),
2521
+ copied && /* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "Copied!" }),
2522
+ !copied && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2633
2523
  "press ",
2634
- /* @__PURE__ */ jsxs17(Text17, { bold: true, color: "yellow", children: [
2524
+ /* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", children: [
2635
2525
  "[",
2636
2526
  keyHint,
2637
2527
  "]"
@@ -2639,12 +2529,9 @@ var CopyableField = ({
2639
2529
  " to copy (and see full value)"
2640
2530
  ] })
2641
2531
  ] }),
2642
- /* @__PURE__ */ jsx17(Box17, { paddingLeft: 2, children: expanded ? /* @__PURE__ */ jsx17(Text17, { wrap: "wrap", children: value }) : children || /* @__PURE__ */ jsx17(Text17, { children: labelColor ? /* @__PURE__ */ jsx17(Text17, { color: labelColor, children: truncated }) : truncated }) })
2532
+ /* @__PURE__ */ jsx(Box, { paddingLeft: 2, children: expanded ? /* @__PURE__ */ jsx(Text, { wrap: "wrap", children: value }) : children || /* @__PURE__ */ jsx(Text, { children: labelColor ? /* @__PURE__ */ jsx(Text, { color: labelColor, children: truncated }) : truncated }) })
2643
2533
  ] });
2644
2534
  };
2645
-
2646
- // src/components/DevDashboard.tsx
2647
- import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
2648
2535
  var toBase64Url = (input) => btoa(input).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
2649
2536
  var DevDashboard = ({
2650
2537
  previewTunnelUrl,
@@ -2661,7 +2548,7 @@ var DevDashboard = ({
2661
2548
  devSessionToken,
2662
2549
  onQuit
2663
2550
  }) => {
2664
- useEffect6(() => {
2551
+ useEffect(() => {
2665
2552
  const handler = () => {
2666
2553
  onQuit();
2667
2554
  };
@@ -2670,107 +2557,107 @@ var DevDashboard = ({
2670
2557
  process.off("SIGINT", handler);
2671
2558
  };
2672
2559
  }, [onQuit]);
2673
- const devParamBlob = useMemo2(() => {
2560
+ const devParamBlob = useMemo(() => {
2674
2561
  if (!tunnelUrl || !devSessionToken) return "";
2675
2562
  return toBase64Url(JSON.stringify({ url: tunnelUrl, token: devSessionToken }));
2676
2563
  }, [tunnelUrl, devSessionToken]);
2677
- useInput11((input, key) => {
2564
+ useInput((input, key) => {
2678
2565
  if (input === "q" || key.ctrl && input === "c") {
2679
2566
  onQuit();
2680
2567
  }
2681
2568
  });
2682
- return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
2683
- /* @__PURE__ */ jsx18(Banner, { userId, orgId }),
2684
- /* @__PURE__ */ jsxs18(
2569
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2570
+ /* @__PURE__ */ jsx(Banner, { userId, orgId }),
2571
+ /* @__PURE__ */ jsxs(
2685
2572
  StepShell,
2686
2573
  {
2687
2574
  title: "dev",
2688
2575
  hint: `Live development ${tunnelUrl ? "with" : "w/o"} Tunnel \u2014 ${appName ? `${appName} ` : ""}(${appId})`,
2689
- footer: /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", gap: 1, children: [
2690
- devParamBlob && /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
2576
+ footer: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
2577
+ devParamBlob && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2691
2578
  "Press ",
2692
- /* @__PURE__ */ jsx18(Text18, { bold: true, color: "yellow", children: "[d]" }),
2579
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "[d]" }),
2693
2580
  " to copy Dev Param, ",
2694
- /* @__PURE__ */ jsx18(Text18, { bold: true, color: "yellow", children: "[s]" }),
2581
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "[s]" }),
2695
2582
  " to copy Staging Param"
2696
2583
  ] }),
2697
- /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
2584
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2698
2585
  "Press ",
2699
- /* @__PURE__ */ jsx18(Text18, { bold: true, color: "yellow", children: "[q]" }),
2586
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "[q]" }),
2700
2587
  " or Ctrl-C to quit"
2701
2588
  ] })
2702
2589
  ] }),
2703
2590
  children: [
2704
- /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
2705
- /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
2706
- /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Extension:" }),
2707
- /* @__PURE__ */ jsxs18(Text18, { children: [
2591
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2592
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
2593
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Extension:" }),
2594
+ /* @__PURE__ */ jsxs(Text, { children: [
2708
2595
  extensionName,
2709
2596
  " (",
2710
2597
  extensionId,
2711
2598
  ")"
2712
2599
  ] })
2713
2600
  ] }),
2714
- /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
2715
- /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Bundle URL:" }),
2716
- /* @__PURE__ */ jsx18(Text18, { children: tunnelUrl || `http://localhost:${extensionPort}` })
2601
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
2602
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Bundle URL:" }),
2603
+ /* @__PURE__ */ jsx(Text, { children: tunnelUrl || `http://localhost:${extensionPort}` })
2717
2604
  ] })
2718
2605
  ] }),
2719
- /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
2720
- previewTunnelUrl && /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
2721
- /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Tunnel Dev - Preview:" }),
2722
- /* @__PURE__ */ jsx18(Text18, { children: previewTunnelUrl })
2606
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2607
+ previewTunnelUrl && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
2608
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Tunnel Dev - Preview:" }),
2609
+ /* @__PURE__ */ jsx(Text, { children: previewTunnelUrl })
2723
2610
  ] }),
2724
- /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
2725
- /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Local Dev - Preview:" }),
2726
- /* @__PURE__ */ jsxs18(Text18, { children: [
2611
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
2612
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Local Dev - Preview:" }),
2613
+ /* @__PURE__ */ jsxs(Text, { children: [
2727
2614
  "http://localhost:",
2728
2615
  previewPort
2729
2616
  ] })
2730
2617
  ] })
2731
2618
  ] }),
2732
- /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
2733
- tunnelUrl && /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
2734
- /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Tunnel Dev - Extension:" }),
2735
- /* @__PURE__ */ jsx18(Text18, { children: tunnelUrl })
2619
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2620
+ tunnelUrl && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
2621
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Tunnel Dev - Extension:" }),
2622
+ /* @__PURE__ */ jsx(Text, { children: tunnelUrl })
2736
2623
  ] }),
2737
- /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
2738
- /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Local Dev - Extension:" }),
2739
- /* @__PURE__ */ jsxs18(Text18, { children: [
2624
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
2625
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Local Dev - Extension:" }),
2626
+ /* @__PURE__ */ jsxs(Text, { children: [
2740
2627
  "http://localhost:",
2741
2628
  extensionPort
2742
2629
  ] })
2743
2630
  ] })
2744
2631
  ] }),
2745
- tunnelUrl && devSessionToken && /* @__PURE__ */ jsxs18(Fragment2, { children: [
2746
- /* @__PURE__ */ jsx18(
2632
+ tunnelUrl && devSessionToken && /* @__PURE__ */ jsxs(Fragment, { children: [
2633
+ /* @__PURE__ */ jsx(
2747
2634
  CopyableField,
2748
2635
  {
2749
2636
  label: "Dev Param (no encryption):",
2750
2637
  value: `?_stackable_dev=${extensionId}:${devParamBlob}`,
2751
2638
  shortcutKey: "d",
2752
- children: /* @__PURE__ */ jsxs18(Text18, { children: [
2639
+ children: /* @__PURE__ */ jsxs(Text, { children: [
2753
2640
  "?",
2754
- /* @__PURE__ */ jsx18(Text18, { color: "yellow", children: "_stackable_dev" }),
2641
+ /* @__PURE__ */ jsx(Text, { color: "yellow", children: "_stackable_dev" }),
2755
2642
  "=",
2756
- /* @__PURE__ */ jsx18(Text18, { color: "cyan", children: extensionId }),
2643
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: extensionId }),
2757
2644
  ":",
2758
2645
  devParamBlob.slice(0, 20),
2759
2646
  "..."
2760
2647
  ] })
2761
2648
  }
2762
2649
  ),
2763
- /* @__PURE__ */ jsx18(
2650
+ /* @__PURE__ */ jsx(
2764
2651
  CopyableField,
2765
2652
  {
2766
2653
  label: "Staging Param (with encryption):",
2767
2654
  value: `?_stackable_staging=${extensionId}:${devParamBlob}`,
2768
2655
  shortcutKey: "s",
2769
- children: /* @__PURE__ */ jsxs18(Text18, { children: [
2656
+ children: /* @__PURE__ */ jsxs(Text, { children: [
2770
2657
  "?",
2771
- /* @__PURE__ */ jsx18(Text18, { color: "yellow", children: "_stackable_staging" }),
2658
+ /* @__PURE__ */ jsx(Text, { color: "yellow", children: "_stackable_staging" }),
2772
2659
  "=",
2773
- /* @__PURE__ */ jsx18(Text18, { color: "cyan", children: extensionId }),
2660
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: extensionId }),
2774
2661
  ":",
2775
2662
  devParamBlob.slice(0, 20),
2776
2663
  "..."
@@ -2778,47 +2665,44 @@ var DevDashboard = ({
2778
2665
  }
2779
2666
  )
2780
2667
  ] }),
2781
- tunnelUrl && !devSessionToken && /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
2782
- /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Host Dev - Query Param:" }),
2783
- /* @__PURE__ */ jsxs18(Text18, { children: [
2668
+ tunnelUrl && !devSessionToken && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
2669
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Host Dev - Query Param:" }),
2670
+ /* @__PURE__ */ jsxs(Text, { children: [
2784
2671
  "?",
2785
- /* @__PURE__ */ jsx18(Text18, { color: "yellow", children: "_stackable_dev" }),
2672
+ /* @__PURE__ */ jsx(Text, { color: "yellow", children: "_stackable_dev" }),
2786
2673
  "=",
2787
- /* @__PURE__ */ jsx18(Text18, { color: "cyan", children: extensionId }),
2674
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: extensionId }),
2788
2675
  ":",
2789
2676
  tunnelUrl
2790
2677
  ] })
2791
2678
  ] }),
2792
- manifestWarnings.length > 0 && /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
2793
- /* @__PURE__ */ jsx18(Text18, { color: "yellow", bold: true, children: "Local manifest differs from registry:" }),
2794
- manifestWarnings.map((w, i) => /* @__PURE__ */ jsxs18(Text18, { color: "yellow", children: [
2679
+ manifestWarnings.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
2680
+ /* @__PURE__ */ jsx(Text, { color: "yellow", bold: true, children: "Local manifest differs from registry:" }),
2681
+ manifestWarnings.map((w, i) => /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
2795
2682
  " ",
2796
2683
  w
2797
2684
  ] }, i)),
2798
- /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: " Run `pnpm --config.dlx-cache-max-age=0 dlx @stackable-labs/cli-app-extension@latest update` to review and sync." })
2685
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: " Run `pnpm --config.dlx-cache-max-age=0 dlx @stackable-labs/cli-app-extension@latest update` to review and sync." })
2799
2686
  ] })
2800
2687
  ]
2801
2688
  }
2802
2689
  )
2803
2690
  ] });
2804
2691
  };
2805
-
2806
- // src/components/DevApp.tsx
2807
- import { jsx as jsx19 } from "react/jsx-runtime";
2808
2692
  var DevApp = ({ token, userId, orgId, options = {} }) => {
2809
- const [state, setState] = useState14("setup");
2810
- const [devContext, setDevContext] = useState14(null);
2811
- const [resolvedContext, setResolvedContext] = useState14(null);
2812
- const [tunnelUrl, setTunnelUrl] = useState14(null);
2813
- const [previewTunnelUrl, setPreviewTunnelUrl] = useState14(null);
2814
- const [tunnelHandle, setTunnelHandle] = useState14(null);
2815
- const [previewTunnelHandle, setPreviewTunnelHandle] = useState14(null);
2816
- const [devServerHandle, setDevServerHandle] = useState14(null);
2817
- const [manifestWarnings, setManifestWarnings] = useState14([]);
2818
- const [devSessionToken, setDevSessionToken] = useState14(null);
2693
+ const [state, setState] = useState("setup");
2694
+ const [devContext, setDevContext] = useState(null);
2695
+ const [resolvedContext, setResolvedContext] = useState(null);
2696
+ const [tunnelUrl, setTunnelUrl] = useState(null);
2697
+ const [previewTunnelUrl, setPreviewTunnelUrl] = useState(null);
2698
+ const [tunnelHandle, setTunnelHandle] = useState(null);
2699
+ const [previewTunnelHandle, setPreviewTunnelHandle] = useState(null);
2700
+ const [devServerHandle, setDevServerHandle] = useState(null);
2701
+ const [manifestWarnings, setManifestWarnings] = useState([]);
2702
+ const [devSessionToken, setDevSessionToken] = useState(null);
2819
2703
  const shuttingDown = useRef(false);
2820
2704
  const useTunnel = options.tunnel !== false;
2821
- useEffect7(() => {
2705
+ useEffect(() => {
2822
2706
  const projectRoot = options.dir || process.cwd();
2823
2707
  console.log(`[dev] Reading context from ${projectRoot}`);
2824
2708
  readDevContext(projectRoot).then((ctx) => {
@@ -2826,7 +2710,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
2826
2710
  setDevContext(ctx);
2827
2711
  });
2828
2712
  }, [options.dir]);
2829
- const handleSetupReady = useCallback4(async (resolved) => {
2713
+ const handleSetupReady = useCallback(async (resolved) => {
2830
2714
  if (!devContext) return;
2831
2715
  setResolvedContext(resolved);
2832
2716
  console.log(`[dev] Saving context: appId=${resolved.appId} extensionId=${resolved.extensionId}`);
@@ -2898,7 +2782,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
2898
2782
  console.log("[dev] Ready");
2899
2783
  setState("running");
2900
2784
  }, [devContext, token, options.extensionPort, options.previewPort, useTunnel]);
2901
- useEffect7(() => {
2785
+ useEffect(() => {
2902
2786
  if (state === "setup" && devContext && devContext.appId && devContext.extensionId) {
2903
2787
  handleSetupReady({
2904
2788
  appId: devContext.appId,
@@ -2933,7 +2817,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
2933
2817
  console.log("[dev] Done");
2934
2818
  process.exit(0);
2935
2819
  };
2936
- useInput12((input, key) => {
2820
+ useInput((input, key) => {
2937
2821
  if (input === "c" && key.ctrl) {
2938
2822
  if (state === "running") {
2939
2823
  handleQuit();
@@ -2944,7 +2828,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
2944
2828
  });
2945
2829
  if (state === "setup" && devContext) {
2946
2830
  if (!devContext.appId || !devContext.extensionId) {
2947
- return /* @__PURE__ */ jsx19(
2831
+ return /* @__PURE__ */ jsx(
2948
2832
  DevSetup,
2949
2833
  {
2950
2834
  token,
@@ -2956,7 +2840,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
2956
2840
  return null;
2957
2841
  }
2958
2842
  if (state === "running" && devContext && resolvedContext) {
2959
- return /* @__PURE__ */ jsx19(
2843
+ return /* @__PURE__ */ jsx(
2960
2844
  DevDashboard,
2961
2845
  {
2962
2846
  previewTunnelUrl,
@@ -2978,19 +2862,8 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
2978
2862
  if (state === "stopping") {
2979
2863
  return null;
2980
2864
  }
2981
- return /* @__PURE__ */ jsx19(Box19, { children: /* @__PURE__ */ jsx19(Text19, { children: "Loading..." }) });
2865
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: "Loading..." }) });
2982
2866
  };
2983
-
2984
- // src/components/AIScaffold.tsx
2985
- import { Box as Box20, Text as Text20, useApp as useApp2 } from "ink";
2986
- import Spinner5 from "ink-spinner";
2987
- import { useState as useState15, useEffect as useEffect8 } from "react";
2988
-
2989
- // src/lib/aiDocs.ts
2990
- import { existsSync, readFileSync } from "fs";
2991
- import { join as join4, dirname } from "path";
2992
- import { mkdir, writeFile as writeFile3 } from "fs/promises";
2993
- import AdmZip from "adm-zip";
2994
2867
  var DEFAULT_STATIC_CDN_URL = "https://static.stackablelabs.io";
2995
2868
  var AI_DOCS_FILENAME = "extension-ai-docs.zip";
2996
2869
  var getStaticCdnBaseUrl = () => process.env.STATIC_CDN_BASE_URL ?? DEFAULT_STATIC_CDN_URL;
@@ -3000,7 +2873,7 @@ var isValidManifest = (data) => {
3000
2873
  return typeof m.name === "string" && m.name.length > 0 && typeof m.version === "string" && Array.isArray(m.targets) && Array.isArray(m.permissions) && Array.isArray(m.allowedDomains);
3001
2874
  };
3002
2875
  var isExtensionProject = (dir) => {
3003
- const manifestPath = join4(dir, "packages/extension/public/manifest.json");
2876
+ const manifestPath = join(dir, "packages/extension/public/manifest.json");
3004
2877
  if (!existsSync(manifestPath)) {
3005
2878
  return { valid: false, reason: "No manifest.json found at packages/extension/public/manifest.json \u2014 is this an Extension project?" };
3006
2879
  }
@@ -3028,22 +2901,19 @@ var downloadAndExtractAiDocs = async (targetDir, version2) => {
3028
2901
  const extractedFiles = [];
3029
2902
  for (const entry of entries) {
3030
2903
  if (entry.isDirectory) continue;
3031
- const targetPath = join4(targetDir, entry.entryName);
2904
+ const targetPath = join(targetDir, entry.entryName);
3032
2905
  await mkdir(dirname(targetPath), { recursive: true });
3033
- await writeFile3(targetPath, entry.getData());
2906
+ await writeFile(targetPath, entry.getData());
3034
2907
  extractedFiles.push(entry.entryName);
3035
2908
  }
3036
2909
  return { files: extractedFiles.sort() };
3037
2910
  };
3038
-
3039
- // src/components/AIScaffold.tsx
3040
- import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
3041
2911
  var AIScaffold = ({ version: version2 }) => {
3042
- const { exit } = useApp2();
3043
- const [state, setState] = useState15("validating");
3044
- const [files, setFiles] = useState15([]);
3045
- const [errorMessage, setErrorMessage] = useState15("");
3046
- useEffect8(() => {
2912
+ const { exit } = useApp();
2913
+ const [state, setState] = useState("validating");
2914
+ const [files, setFiles] = useState([]);
2915
+ const [errorMessage, setErrorMessage] = useState("");
2916
+ useEffect(() => {
3047
2917
  const run = async () => {
3048
2918
  const projectDir = process.cwd();
3049
2919
  const check = isExtensionProject(projectDir);
@@ -3066,64 +2936,52 @@ var AIScaffold = ({ version: version2 }) => {
3066
2936
  };
3067
2937
  run();
3068
2938
  }, []);
3069
- return /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", children: [
3070
- /* @__PURE__ */ jsx20(Banner, {}),
3071
- /* @__PURE__ */ jsxs19(StepShell, { title: "AI Editor Config", children: [
3072
- state === "validating" && /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
3073
- /* @__PURE__ */ jsx20(Text20, { color: "cyan", children: /* @__PURE__ */ jsx20(Spinner5, { type: "dots" }) }),
3074
- /* @__PURE__ */ jsx20(Text20, { children: "Checking project..." })
2939
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
2940
+ /* @__PURE__ */ jsx(Banner, {}),
2941
+ /* @__PURE__ */ jsxs(StepShell, { title: "AI Editor Config", children: [
2942
+ state === "validating" && /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
2943
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: /* @__PURE__ */ jsx(Spinner5, { type: "dots" }) }),
2944
+ /* @__PURE__ */ jsx(Text, { children: "Checking project..." })
3075
2945
  ] }),
3076
- state === "downloading" && /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
3077
- /* @__PURE__ */ jsx20(Text20, { color: "cyan", children: /* @__PURE__ */ jsx20(Spinner5, { type: "dots" }) }),
3078
- /* @__PURE__ */ jsxs19(Text20, { children: [
2946
+ state === "downloading" && /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
2947
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: /* @__PURE__ */ jsx(Spinner5, { type: "dots" }) }),
2948
+ /* @__PURE__ */ jsxs(Text, { children: [
3079
2949
  "Downloading AI editor configs (",
3080
2950
  version2,
3081
2951
  ")..."
3082
2952
  ] })
3083
2953
  ] }),
3084
- state === "done" && /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", gap: 1, children: [
3085
- /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
3086
- /* @__PURE__ */ jsx20(Text20, { color: "green", bold: true, children: "\u2714" }),
3087
- /* @__PURE__ */ jsxs19(Text20, { bold: true, children: [
2954
+ state === "done" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
2955
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
2956
+ /* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
2957
+ /* @__PURE__ */ jsxs(Text, { bold: true, children: [
3088
2958
  "AI editor configs installed (",
3089
2959
  files.length,
3090
2960
  " files)"
3091
2961
  ] })
3092
2962
  ] }),
3093
- /* @__PURE__ */ jsx20(Box20, { flexDirection: "column", marginLeft: 2, children: files.map((f) => /* @__PURE__ */ jsx20(Text20, { dimColor: true, children: f }, f)) })
2963
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 2, children: files.map((f) => /* @__PURE__ */ jsx(Text, { dimColor: true, children: f }, f)) })
3094
2964
  ] }),
3095
- state === "error" && /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
3096
- /* @__PURE__ */ jsx20(Text20, { color: "red", children: "\u2716" }),
3097
- /* @__PURE__ */ jsx20(Text20, { children: errorMessage })
2965
+ state === "error" && /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
2966
+ /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" }),
2967
+ /* @__PURE__ */ jsx(Text, { children: errorMessage })
3098
2968
  ] })
3099
2969
  ] })
3100
2970
  ] });
3101
2971
  };
3102
-
3103
- // src/components/AuthLogin.tsx
3104
- import { createServer } from "http";
3105
- import { Box as Box21, Text as Text21, useApp as useApp3 } from "ink";
3106
- import Spinner6 from "ink-spinner";
3107
- import open from "open";
3108
- import { useState as useState16, useEffect as useEffect9 } from "react";
3109
-
3110
- // src/lib/auth.ts
3111
- import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir2, unlink } from "fs/promises";
3112
- import { join as join5 } from "path";
3113
- import { homedir } from "os";
3114
- var AUTH_DIR = join5(homedir(), ".stackable");
3115
- var AUTH_FILE = join5(AUTH_DIR, "auth.json");
2972
+ var AUTH_DIR = join(homedir(), ".stackable");
2973
+ var AUTH_FILE = join(AUTH_DIR, "auth.json");
3116
2974
  var readAuthState = async () => {
3117
2975
  try {
3118
- const content = await readFile4(AUTH_FILE, "utf8");
2976
+ const content = await readFile(AUTH_FILE, "utf8");
3119
2977
  return JSON.parse(content);
3120
2978
  } catch {
3121
2979
  return null;
3122
2980
  }
3123
2981
  };
3124
2982
  var writeAuthState = async (state) => {
3125
- await mkdir2(AUTH_DIR, { recursive: true, mode: 448 });
3126
- await writeFile4(AUTH_FILE, JSON.stringify(state, null, 2), { mode: 384 });
2983
+ await mkdir(AUTH_DIR, { recursive: true, mode: 448 });
2984
+ await writeFile(AUTH_FILE, JSON.stringify(state, null, 2), { mode: 384 });
3127
2985
  };
3128
2986
  var clearAuthState = async () => {
3129
2987
  try {
@@ -3156,9 +3014,6 @@ var getToken = async () => {
3156
3014
  }
3157
3015
  return state.token;
3158
3016
  };
3159
-
3160
- // src/components/AuthLogin.tsx
3161
- import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
3162
3017
  var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
3163
3018
  var callbackPage = (heading, sub, redirectUrl) => `<!DOCTYPE html>
3164
3019
  <html><head><meta charset="utf-8"><title>Stackable CLI</title>
@@ -3168,13 +3023,13 @@ var callbackPage = (heading, sub, redirectUrl) => `<!DOCTYPE html>
3168
3023
  ${redirectUrl ? `<script>(function(){var s=3,el=document.getElementById('h');function t(){if(s<=0){location.href='${redirectUrl}';return}el.textContent='Redirecting in '+s+'s\u2026';s--;setTimeout(t,1000)}t()})()</script>` : ""}
3169
3024
  </body></html>`;
3170
3025
  var AuthLogin = ({ dashboardUrl }) => {
3171
- const { exit } = useApp3();
3172
- const [state, setState] = useState16("waiting");
3173
- const [loginUrl, setLoginUrl] = useState16("");
3174
- const [userIdLabel, setUserIdLabel] = useState16("");
3175
- const [orgIdLabel, setOrgIdLabel] = useState16("");
3176
- const [errorMessage, setErrorMessage] = useState16("");
3177
- useEffect9(() => {
3026
+ const { exit } = useApp();
3027
+ const [state, setState] = useState("waiting");
3028
+ const [loginUrl, setLoginUrl] = useState("");
3029
+ const [userIdLabel, setUserIdLabel] = useState("");
3030
+ const [orgIdLabel, setOrgIdLabel] = useState("");
3031
+ const [errorMessage, setErrorMessage] = useState("");
3032
+ useEffect(() => {
3178
3033
  let server;
3179
3034
  let timeout;
3180
3035
  const run = async () => {
@@ -3249,116 +3104,103 @@ var AuthLogin = ({ dashboardUrl }) => {
3249
3104
  server?.close();
3250
3105
  };
3251
3106
  }, []);
3252
- return /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", children: [
3253
- /* @__PURE__ */ jsx21(Banner, {}),
3254
- /* @__PURE__ */ jsxs20(StepShell, { title: "Authenticate with Stackable", children: [
3255
- state === "waiting" && /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", gap: 1, children: [
3256
- /* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
3257
- /* @__PURE__ */ jsx21(Text21, { color: "cyan", children: /* @__PURE__ */ jsx21(Spinner6, { type: "dots" }) }),
3258
- /* @__PURE__ */ jsx21(Text21, { children: "Waiting for browser authentication..." })
3107
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3108
+ /* @__PURE__ */ jsx(Banner, {}),
3109
+ /* @__PURE__ */ jsxs(StepShell, { title: "Authenticate with Stackable", children: [
3110
+ state === "waiting" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
3111
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
3112
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: /* @__PURE__ */ jsx(Spinner5, { type: "dots" }) }),
3113
+ /* @__PURE__ */ jsx(Text, { children: "Waiting for browser authentication..." })
3259
3114
  ] }),
3260
- loginUrl && /* @__PURE__ */ jsxs20(Text21, { dimColor: true, children: [
3115
+ loginUrl && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
3261
3116
  " ",
3262
3117
  loginUrl
3263
3118
  ] })
3264
3119
  ] }),
3265
- state === "success" && /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", gap: 1, children: [
3266
- /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", children: [
3267
- /* @__PURE__ */ jsxs20(Box21, { gap: 2, children: [
3268
- /* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "User:" }),
3269
- /* @__PURE__ */ jsx21(Text21, { color: "cyan", children: userIdLabel })
3120
+ state === "success" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
3121
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3122
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
3123
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "User:" }),
3124
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: userIdLabel })
3270
3125
  ] }),
3271
- /* @__PURE__ */ jsxs20(Box21, { gap: 2, children: [
3272
- /* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "Org: " }),
3273
- /* @__PURE__ */ jsx21(Text21, { color: "cyan", children: orgIdLabel })
3126
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
3127
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Org: " }),
3128
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: orgIdLabel })
3274
3129
  ] })
3275
3130
  ] }),
3276
- /* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
3277
- /* @__PURE__ */ jsx21(Text21, { color: "green", bold: true, children: "\u2714" }),
3278
- /* @__PURE__ */ jsx21(Text21, { bold: true, children: "Authenticated" })
3131
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
3132
+ /* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
3133
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Authenticated" })
3279
3134
  ] })
3280
3135
  ] }),
3281
- state === "error" && /* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
3282
- /* @__PURE__ */ jsx21(Text21, { color: "red", children: "\u2716" }),
3283
- /* @__PURE__ */ jsx21(Text21, { children: errorMessage })
3136
+ state === "error" && /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
3137
+ /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" }),
3138
+ /* @__PURE__ */ jsx(Text, { children: errorMessage })
3284
3139
  ] })
3285
3140
  ] })
3286
3141
  ] });
3287
3142
  };
3288
-
3289
- // src/components/AuthLogout.tsx
3290
- import { useEffect as useEffect10 } from "react";
3291
- import { Box as Box22, Text as Text22, useApp as useApp4 } from "ink";
3292
- import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
3293
3143
  var AuthLogout = () => {
3294
- const { exit } = useApp4();
3295
- useEffect10(() => {
3144
+ const { exit } = useApp();
3145
+ useEffect(() => {
3296
3146
  exit();
3297
3147
  }, [exit]);
3298
- return /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", children: [
3299
- /* @__PURE__ */ jsx22(Banner, {}),
3300
- /* @__PURE__ */ jsx22(StepShell, { title: "Authenticate with Stackable", children: /* @__PURE__ */ jsxs21(Box22, { gap: 1, children: [
3301
- /* @__PURE__ */ jsx22(Text22, { color: "green", bold: true, children: "\u2714" }),
3302
- /* @__PURE__ */ jsx22(Text22, { bold: true, children: "Logged out" })
3148
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3149
+ /* @__PURE__ */ jsx(Banner, {}),
3150
+ /* @__PURE__ */ jsx(StepShell, { title: "Authenticate with Stackable", children: /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
3151
+ /* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
3152
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Logged out" })
3303
3153
  ] }) })
3304
3154
  ] });
3305
3155
  };
3306
-
3307
- // src/components/AuthStatus.tsx
3308
- import { useEffect as useEffect11 } from "react";
3309
- import { useApp as useApp5, Box as Box23, Text as Text23 } from "ink";
3310
- import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
3311
3156
  var AuthStatus = ({ state, userId, orgId, expiry }) => {
3312
- const { exit } = useApp5();
3313
- useEffect11(() => {
3157
+ const { exit } = useApp();
3158
+ useEffect(() => {
3314
3159
  exit();
3315
3160
  }, [exit]);
3316
- return /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", children: [
3317
- /* @__PURE__ */ jsx23(Banner, {}),
3318
- /* @__PURE__ */ jsxs22(StepShell, { title: "Authenticate with Stackable", children: [
3319
- state === "authenticated" && /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", gap: 1, children: [
3320
- /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", children: [
3321
- /* @__PURE__ */ jsxs22(Box23, { gap: 2, children: [
3322
- /* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "User:" }),
3323
- /* @__PURE__ */ jsx23(Text23, { color: "cyan", children: userId })
3161
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3162
+ /* @__PURE__ */ jsx(Banner, {}),
3163
+ /* @__PURE__ */ jsxs(StepShell, { title: "Authenticate with Stackable", children: [
3164
+ state === "authenticated" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
3165
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3166
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
3167
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "User:" }),
3168
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: userId })
3324
3169
  ] }),
3325
- /* @__PURE__ */ jsxs22(Box23, { gap: 2, children: [
3326
- /* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "Org: " }),
3327
- /* @__PURE__ */ jsx23(Text23, { color: "cyan", children: orgId })
3170
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
3171
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Org: " }),
3172
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: orgId })
3328
3173
  ] }),
3329
- expiry && /* @__PURE__ */ jsxs22(Box23, { gap: 2, children: [
3330
- /* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "Exp: " }),
3331
- /* @__PURE__ */ jsx23(Text23, { color: "cyan", children: expiry.toLocaleDateString() })
3174
+ expiry && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
3175
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Exp: " }),
3176
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: expiry.toLocaleDateString() })
3332
3177
  ] })
3333
3178
  ] }),
3334
- /* @__PURE__ */ jsxs22(Box23, { gap: 1, children: [
3335
- /* @__PURE__ */ jsx23(Text23, { color: "green", bold: true, children: "\u2714" }),
3336
- /* @__PURE__ */ jsx23(Text23, { bold: true, children: "Authenticated" })
3179
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
3180
+ /* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
3181
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Authenticated" })
3337
3182
  ] })
3338
3183
  ] }),
3339
- state === "expired" && /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", gap: 1, children: [
3340
- /* @__PURE__ */ jsxs22(Box23, { gap: 1, children: [
3341
- /* @__PURE__ */ jsx23(Text23, { color: "red", children: "\u2716" }),
3342
- /* @__PURE__ */ jsxs22(Text23, { children: [
3184
+ state === "expired" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
3185
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
3186
+ /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" }),
3187
+ /* @__PURE__ */ jsxs(Text, { children: [
3343
3188
  "Session expired",
3344
3189
  expiry ? ` (${expiry.toLocaleDateString()})` : ""
3345
3190
  ] })
3346
3191
  ] }),
3347
- /* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "Run `stackable-app-extension auth login` to re-authenticate." })
3192
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Run `stackable-app-extension auth login` to re-authenticate." })
3348
3193
  ] }),
3349
- state === "not-logged-in" && /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", gap: 1, children: [
3350
- /* @__PURE__ */ jsxs22(Box23, { gap: 1, children: [
3351
- /* @__PURE__ */ jsx23(Text23, { color: "red", children: "\u2716" }),
3352
- /* @__PURE__ */ jsx23(Text23, { children: "Not logged in" })
3194
+ state === "not-logged-in" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
3195
+ /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
3196
+ /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" }),
3197
+ /* @__PURE__ */ jsx(Text, { children: "Not logged in" })
3353
3198
  ] }),
3354
- /* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "Run `stackable-app-extension auth login`" })
3199
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Run `stackable-app-extension auth login`" })
3355
3200
  ] })
3356
3201
  ] })
3357
3202
  ] });
3358
3203
  };
3359
-
3360
- // src/lib/versionCheck.ts
3361
- import https from "https";
3362
3204
  var PACKAGE_NAME = "@stackable-labs/cli-app-extension";
3363
3205
  var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
3364
3206
  var TIMEOUT_MS = 3e3;
@@ -3403,9 +3245,6 @@ var checkForUpdate = (currentVersion) => {
3403
3245
  } catch {
3404
3246
  }
3405
3247
  };
3406
-
3407
- // src/index.tsx
3408
- import { jsx as jsx24 } from "react/jsx-runtime";
3409
3248
  var require2 = createRequire(import.meta.url);
3410
3249
  var { version } = require2("../package.json");
3411
3250
  checkForUpdate(version);
@@ -3418,7 +3257,7 @@ var ensureToken = async () => {
3418
3257
  const message = err instanceof Error ? err.message : String(err);
3419
3258
  const isExpired = message.toLowerCase().includes("expired");
3420
3259
  render(
3421
- /* @__PURE__ */ jsx24(AuthStatus, { state: isExpired ? "expired" : "not-logged-in" })
3260
+ /* @__PURE__ */ jsx(AuthStatus, { state: isExpired ? "expired" : "not-logged-in" })
3422
3261
  );
3423
3262
  return null;
3424
3263
  }
@@ -3431,7 +3270,7 @@ program.command("create" /* CREATE */).description("Create a new Extension proje
3431
3270
  }
3432
3271
  const { token, userId, orgId } = auth2;
3433
3272
  render(
3434
- /* @__PURE__ */ jsx24(
3273
+ /* @__PURE__ */ jsx(
3435
3274
  App,
3436
3275
  {
3437
3276
  command: "create" /* CREATE */,
@@ -3451,7 +3290,7 @@ program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project
3451
3290
  }
3452
3291
  const { token, userId, orgId } = auth2;
3453
3292
  render(
3454
- /* @__PURE__ */ jsx24(
3293
+ /* @__PURE__ */ jsx(
3455
3294
  App,
3456
3295
  {
3457
3296
  command: "scaffold" /* SCAFFOLD */,
@@ -3471,7 +3310,7 @@ program.command("update" /* UPDATE */).description("Update an existing Extension
3471
3310
  }
3472
3311
  const { token, userId, orgId } = auth2;
3473
3312
  render(
3474
- /* @__PURE__ */ jsx24(
3313
+ /* @__PURE__ */ jsx(
3475
3314
  App,
3476
3315
  {
3477
3316
  command: "update" /* UPDATE */,
@@ -3491,7 +3330,7 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
3491
3330
  }
3492
3331
  const { token, userId, orgId } = auth2;
3493
3332
  render(
3494
- /* @__PURE__ */ jsx24(
3333
+ /* @__PURE__ */ jsx(
3495
3334
  DevApp,
3496
3335
  {
3497
3336
  options,
@@ -3506,17 +3345,17 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
3506
3345
  var DASHBOARD_URL = process.env.ADMIN_DASHBOARD_URL ?? "https://admin.stackablelabs.io";
3507
3346
  var auth = program.command("auth").description("Manage CLI authentication");
3508
3347
  auth.command("login").description("Authenticate with Stackable via browser").action(async () => {
3509
- render(/* @__PURE__ */ jsx24(AuthLogin, { dashboardUrl: DASHBOARD_URL }));
3348
+ render(/* @__PURE__ */ jsx(AuthLogin, { dashboardUrl: DASHBOARD_URL }));
3510
3349
  });
3511
3350
  auth.command("logout").description("Clear stored CLI credentials").action(async () => {
3512
3351
  await clearAuthState();
3513
- render(/* @__PURE__ */ jsx24(AuthLogout, {}));
3352
+ render(/* @__PURE__ */ jsx(AuthLogout, {}));
3514
3353
  });
3515
3354
  auth.command("status").description("Show current authentication status").action(async () => {
3516
3355
  const state = await readAuthState();
3517
3356
  if (!state) {
3518
3357
  render(
3519
- /* @__PURE__ */ jsx24(AuthStatus, { state: "not-logged-in" })
3358
+ /* @__PURE__ */ jsx(AuthStatus, { state: "not-logged-in" })
3520
3359
  );
3521
3360
  return;
3522
3361
  }
@@ -3524,11 +3363,11 @@ auth.command("status").description("Show current authentication status").action(
3524
3363
  const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
3525
3364
  const expiry = payload.exp ? new Date(payload.exp * 1e3) : null;
3526
3365
  if (expiry && Date.now() >= expiry.getTime()) {
3527
- render(/* @__PURE__ */ jsx24(AuthStatus, { state: "expired", expiry }));
3366
+ render(/* @__PURE__ */ jsx(AuthStatus, { state: "expired", expiry }));
3528
3367
  return;
3529
3368
  }
3530
3369
  render(
3531
- /* @__PURE__ */ jsx24(
3370
+ /* @__PURE__ */ jsx(
3532
3371
  AuthStatus,
3533
3372
  {
3534
3373
  state: "authenticated",
@@ -3541,6 +3380,6 @@ auth.command("status").description("Show current authentication status").action(
3541
3380
  });
3542
3381
  var ai = program.command("ai").description("AI editor configuration tools");
3543
3382
  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) => {
3544
- render(/* @__PURE__ */ jsx24(AIScaffold, { version: options.version }));
3383
+ render(/* @__PURE__ */ jsx(AIScaffold, { version: options.version }));
3545
3384
  });
3546
3385
  program.parse(process.argv.filter((arg) => arg !== "--"));