@lunora/cli 1.0.0-alpha.100 → 1.0.0-alpha.102

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 (83) hide show
  1. package/dist/bin.mjs +2 -10
  2. package/dist/index.mjs +1 -18
  3. package/dist/packem_chunks/handler.mjs +1 -160
  4. package/dist/packem_chunks/handler10.mjs +1 -16
  5. package/dist/packem_chunks/handler11.mjs +1 -23
  6. package/dist/packem_chunks/handler12.mjs +2 -192
  7. package/dist/packem_chunks/handler13.mjs +2 -131
  8. package/dist/packem_chunks/handler14.mjs +1 -65
  9. package/dist/packem_chunks/handler15.mjs +1 -100
  10. package/dist/packem_chunks/handler16.mjs +1 -44
  11. package/dist/packem_chunks/handler17.mjs +1 -105
  12. package/dist/packem_chunks/handler18.mjs +3 -170
  13. package/dist/packem_chunks/handler19.mjs +1 -128
  14. package/dist/packem_chunks/handler2.mjs +2 -116
  15. package/dist/packem_chunks/handler20.mjs +1 -94
  16. package/dist/packem_chunks/handler21.mjs +2 -202
  17. package/dist/packem_chunks/handler3.mjs +2 -208
  18. package/dist/packem_chunks/handler4.mjs +1 -33
  19. package/dist/packem_chunks/handler5.mjs +1 -52
  20. package/dist/packem_chunks/handler6.mjs +1 -94
  21. package/dist/packem_chunks/handler7.mjs +1 -42
  22. package/dist/packem_chunks/handler8.mjs +1 -174
  23. package/dist/packem_chunks/handler9.mjs +8 -334
  24. package/dist/packem_chunks/planDevCommand.mjs +7 -1181
  25. package/dist/packem_chunks/runCodegenCommand.mjs +4 -53
  26. package/dist/packem_chunks/runDeployCommand.mjs +1 -619
  27. package/dist/packem_chunks/runInitCommand.mjs +51 -1411
  28. package/dist/packem_chunks/runMigrateGenerateCommand.mjs +9 -442
  29. package/dist/packem_chunks/runResetCommand.mjs +1 -41
  30. package/dist/packem_chunks/runRpcCommand.mjs +1 -69
  31. package/dist/packem_shared/COMMANDS-DRqlsGT2.mjs +3 -0
  32. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-DL87PIEl.mjs +8 -0
  33. package/dist/packem_shared/admin-url-DfVehV3e.mjs +1 -0
  34. package/dist/packem_shared/api-spec-BENwiyUa.mjs +1 -0
  35. package/dist/packem_shared/buildRegistryIndex-DwySASBu.mjs +1 -0
  36. package/dist/packem_shared/codegen-error-DJN6pTH5.mjs +3 -0
  37. package/dist/packem_shared/command-Bjv4VmYA.mjs +1 -0
  38. package/dist/packem_shared/commands-BhX2Bo9B.mjs +19 -0
  39. package/dist/packem_shared/createLogger--C3x1FNE.mjs +2 -0
  40. package/dist/packem_shared/createRecordingSpawner-C8_7nffs.mjs +1 -0
  41. package/dist/packem_shared/detect-package-manager-B2eIuAiP.mjs +1 -0
  42. package/dist/packem_shared/diffSnapshots-9bDd9nOK.mjs +5 -0
  43. package/dist/packem_shared/docker-CKvYE9YF.mjs +1 -0
  44. package/dist/packem_shared/insertSchemaExtension-DZReBZ4_.mjs +8 -0
  45. package/dist/packem_shared/open-url-CTU_g9gr.mjs +1 -0
  46. package/dist/packem_shared/output-format-D7cKB-O5.mjs +2 -0
  47. package/dist/packem_shared/parseManifest-x3WsxKHz.mjs +1 -0
  48. package/dist/packem_shared/prompt-cancelled-C8Sj7OqI.mjs +1 -0
  49. package/dist/packem_shared/resolve-target-vxaXHmvg.mjs +1 -0
  50. package/dist/packem_shared/runAddCommand--TBYJQYi.mjs +1 -0
  51. package/dist/packem_shared/schema-drift-gate-CpqG-xP4.mjs +1 -0
  52. package/dist/packem_shared/schemaIrToSnapshot-Clwd2A8e.mjs +1 -0
  53. package/dist/packem_shared/storage-DOvAKGi4.mjs +1 -0
  54. package/dist/packem_shared/tui-prompts-CCt3jm1k.mjs +4 -0
  55. package/dist/packem_shared/wrangler-name-HIl0Z6yx.mjs +1 -0
  56. package/dist/packem_shared/wrangler-secrets-BMRJwKQU.mjs +1 -0
  57. package/package.json +6 -6
  58. package/dist/packem_shared/COMMANDS-BOJIDoVY.mjs +0 -1031
  59. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-D0VOTerB.mjs +0 -249
  60. package/dist/packem_shared/admin-url-4UzT-CI4.mjs +0 -19
  61. package/dist/packem_shared/api-spec-Bx0iKbxA.mjs +0 -15
  62. package/dist/packem_shared/buildRegistryIndex-BS5ig822.mjs +0 -38
  63. package/dist/packem_shared/codegen-error-DJG-ghs_.mjs +0 -31
  64. package/dist/packem_shared/command-lYnl4QyF.mjs +0 -19
  65. package/dist/packem_shared/commands-D5Yxt9VY.mjs +0 -991
  66. package/dist/packem_shared/createLogger-CIWSHrTL.mjs +0 -105
  67. package/dist/packem_shared/createRecordingSpawner-WuSn20kb.mjs +0 -64
  68. package/dist/packem_shared/detect-package-manager-v4hHpQd0.mjs +0 -62
  69. package/dist/packem_shared/diffSnapshots-BeDvvNiF.mjs +0 -161
  70. package/dist/packem_shared/docker-hMQ97KSQ.mjs +0 -21
  71. package/dist/packem_shared/insertSchemaExtension-DAqbfr9Z.mjs +0 -64
  72. package/dist/packem_shared/open-url-4PBLY9X0.mjs +0 -42
  73. package/dist/packem_shared/output-format-B4642rjE.mjs +0 -17
  74. package/dist/packem_shared/parseManifest-Dbp-Q2q3.mjs +0 -121
  75. package/dist/packem_shared/prompt-cancelled-APzX1Im-.mjs +0 -9
  76. package/dist/packem_shared/resolve-target-qbsJ_5sF.mjs +0 -16
  77. package/dist/packem_shared/runAddCommand-D1hgfqFQ.mjs +0 -4
  78. package/dist/packem_shared/schema-drift-gate-BtBt0as0.mjs +0 -79
  79. package/dist/packem_shared/schemaIrToSnapshot-DdsljJT-.mjs +0 -43
  80. package/dist/packem_shared/storage-BXU4ax4O.mjs +0 -84
  81. package/dist/packem_shared/tui-prompts-BjEN8XgP.mjs +0 -658
  82. package/dist/packem_shared/wrangler-name-cy4yhm9j.mjs +0 -12
  83. package/dist/packem_shared/wrangler-secrets-Coni-mER.mjs +0 -49
@@ -1,658 +0,0 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { isInteractive, ACCENT, LUNA_ART, LUNA_NAME, LUNA_SIGNOFF, BADGE_COLUMN_WIDTH, badgeLead, padBadge, badgeWidth } from '@lunora/config';
3
- import { render } from '@visulima/tui';
4
- import '@visulima/tui/components/big-text';
5
- import { Box } from '@visulima/tui/components/box';
6
- import { CommandPalette } from '@visulima/tui/components/command-palette';
7
- import { ConfirmInput } from '@visulima/tui/components/confirm-input';
8
- import { SelectInput } from '@visulima/tui/components/select-input';
9
- import { Spinner } from '@visulima/tui/components/spinner';
10
- import { Text } from '@visulima/tui/components/text';
11
- import { TextInput } from '@visulima/tui/components/text-input';
12
- import { useApp } from '@visulima/tui/hooks/use-app';
13
- import { useInput } from '@visulima/tui/hooks/use-input';
14
- import { useInterval } from '@visulima/tui/hooks/use-interval';
15
- import { useEffect, useState } from 'react';
16
- import { P as PromptCancelledError } from './prompt-cancelled-APzX1Im-.mjs';
17
-
18
- let listenerCapRaised = false;
19
- const raiseListenerCap = () => {
20
- if (listenerCapRaised) {
21
- return;
22
- }
23
- listenerCapRaised = true;
24
- if (process.getMaxListeners() < 64) {
25
- process.setMaxListeners(64);
26
- }
27
- };
28
- const CtrlCGuard = ({ children, onCancel }) => {
29
- const { exit } = useApp();
30
- useInput((input, key) => {
31
- if (key.ctrl && input === "c") {
32
- onCancel();
33
- exit();
34
- }
35
- });
36
- return children;
37
- };
38
- const toError = (failure) => {
39
- if (failure instanceof Error) {
40
- return failure;
41
- }
42
- return new Error(typeof failure === "string" ? failure : "task failed");
43
- };
44
- const SCROLL_LIMIT = 10;
45
- const FILTER_THRESHOLD = 8;
46
- const Badge = ({ spec }) => jsxs(Text, { children: [
47
- jsx(Text, { children: badgeLead(spec.text) }),
48
- jsx(Text, { backgroundColor: spec.bg, bold: true, color: spec.fg, children: padBadge(spec.text) })
49
- ] });
50
- const PromptHeader = ({ badge, message }) => badge === void 0 ? jsx(Text, { bold: true, children: message }) : jsxs(Box, { children: [
51
- jsx(Badge, { spec: badge }),
52
- jsx(Text, { bold: true, children: ` ${message}` })
53
- ] });
54
- const BODY_INDENT = 2;
55
- const HEADER_INDENT = " ".repeat(BADGE_COLUMN_WIDTH - 1);
56
- const badgeIndent = (badge) => " ".repeat(badgeWidth(badge) + 1);
57
- const bodyIndent = (badge) => badge === void 0 ? BODY_INDENT : badgeWidth(badge) + 1;
58
- const PromptShell = ({
59
- badge,
60
- children,
61
- message
62
- }) => jsxs(Box, { flexDirection: "column", children: [
63
- jsx(PromptHeader, { badge, message }),
64
- jsx(Box, { flexDirection: "column", marginLeft: bodyIndent(badge), children })
65
- ] });
66
- const AnsweredLine = ({ answer, badge, message }) => jsxs(Box, { flexDirection: "column", children: [
67
- jsx(PromptHeader, { badge, message }),
68
- answer === "" ? null : jsx(Text, { dimColor: true, children: `${badge === void 0 ? " ".repeat(BODY_INDENT) : badgeIndent(badge)}${answer}` })
69
- ] });
70
- const useAnswer = (finish) => {
71
- const { exit } = useApp();
72
- const [answer, setAnswer] = useState(void 0);
73
- useEffect(() => {
74
- if (answer !== void 0) {
75
- exit();
76
- }
77
- }, [answer, exit]);
78
- return {
79
- answer,
80
- submit: (result, display) => {
81
- finish(result);
82
- setAnswer(display);
83
- }
84
- };
85
- };
86
- const SelfExit = ({ children }) => {
87
- const { exit } = useApp();
88
- useEffect(() => {
89
- exit();
90
- }, [exit]);
91
- return children;
92
- };
93
- const printFrame = async (element) => {
94
- raiseListenerCap();
95
- process.stdout.write("\n");
96
- const instance = render(jsx(SelfExit, { children: element }));
97
- try {
98
- await instance.waitUntilExit();
99
- } catch {
100
- } finally {
101
- instance.unmount();
102
- }
103
- };
104
- const tuiStep = async (badge, message, answer) => {
105
- if (!isInteractive()) {
106
- return;
107
- }
108
- const answerLines = answer === void 0 || answer === "" ? [] : answer.split("\n");
109
- await printFrame(
110
- jsxs(Box, { flexDirection: "column", children: [
111
- jsxs(Box, { children: [
112
- jsx(Badge, { spec: badge }),
113
- jsx(Text, { bold: true, children: ` ${message}` })
114
- ] }),
115
- answerLines.map((line) => jsx(Text, { dimColor: true, children: `${badgeIndent(badge)}${line}` }, line))
116
- ] })
117
- );
118
- };
119
- const runInkApp = async (element) => {
120
- raiseListenerCap();
121
- process.stdout.write("\n");
122
- const cancel = { value: false };
123
- const instance = render(
124
- jsx(
125
- CtrlCGuard,
126
- {
127
- onCancel: () => {
128
- cancel.value = true;
129
- },
130
- children: element
131
- }
132
- ),
133
- { exitOnCtrlC: false }
134
- );
135
- try {
136
- await instance.waitUntilExit();
137
- } finally {
138
- instance.unmount();
139
- }
140
- if (cancel.value) {
141
- throw new PromptCancelledError();
142
- }
143
- };
144
- const runInkPrompt = async (build, fallback) => {
145
- let result = fallback;
146
- await runInkApp(
147
- build((value) => {
148
- result = value;
149
- })
150
- );
151
- return result;
152
- };
153
- const itemLabel = (option) => option.description === void 0 ? option.label : `${option.label} — ${option.description}`;
154
- const useEscapeToExit = () => {
155
- const { exit } = useApp();
156
- useInput((_input, key) => {
157
- if (key.escape) {
158
- exit();
159
- }
160
- });
161
- };
162
- const SelectView = ({ badge, finish, initialIndex, message, options }) => {
163
- const { answer, submit } = useAnswer(finish);
164
- useEscapeToExit();
165
- if (answer !== void 0) {
166
- return jsx(AnsweredLine, { answer, badge, message });
167
- }
168
- return jsx(PromptShell, { badge, message, children: jsx(
169
- SelectInput,
170
- {
171
- accentColor: ACCENT,
172
- initialIndex,
173
- items: options.map((option) => {
174
- return { key: option.value, label: itemLabel(option), value: option.value };
175
- }),
176
- limit: SCROLL_LIMIT,
177
- onSelect: (item) => {
178
- submit(item.value, options.find((option) => option.value === item.value)?.label ?? item.value);
179
- }
180
- }
181
- ) });
182
- };
183
- const PaletteView = ({ badge, finish, message, options }) => {
184
- const { exit } = useApp();
185
- const { answer, submit } = useAnswer(finish);
186
- if (answer !== void 0) {
187
- return jsx(AnsweredLine, { answer, badge, message });
188
- }
189
- return jsx(PromptShell, { badge, message, children: jsx(
190
- CommandPalette,
191
- {
192
- accentColor: ACCENT,
193
- autoFocus: true,
194
- commands: options.map((option) => {
195
- return { description: option.description, id: option.value, label: option.label };
196
- }),
197
- limit: SCROLL_LIMIT,
198
- onCancel: () => {
199
- exit();
200
- },
201
- onSelect: (id) => {
202
- submit(id, options.find((option) => option.value === id)?.label ?? id);
203
- },
204
- placeholder: "Type to filter…"
205
- }
206
- ) });
207
- };
208
- const tuiSelect = async (message, options, settings) => {
209
- if (!isInteractive() || options.length === 0) {
210
- return settings?.default;
211
- }
212
- const { badge } = settings ?? {};
213
- if (options.length > FILTER_THRESHOLD) {
214
- return runInkPrompt((finish) => jsx(PaletteView, { badge, finish, message, options }), settings?.default);
215
- }
216
- const defaultIndex = settings?.default === void 0 ? -1 : options.findIndex((option) => option.value === settings.default);
217
- return runInkPrompt(
218
- (finish) => jsx(SelectView, { badge, finish, initialIndex: defaultIndex >= 0 ? defaultIndex : void 0, message, options }),
219
- settings?.default
220
- );
221
- };
222
- const TextView = ({ badge, defaultValue, finish, message, placeholder }) => {
223
- const { answer, submit } = useAnswer(finish);
224
- useEscapeToExit();
225
- if (answer !== void 0) {
226
- return jsx(AnsweredLine, { answer, badge, message });
227
- }
228
- return jsx(PromptShell, { badge, message, children: jsx(
229
- TextInput,
230
- {
231
- defaultValue,
232
- onSubmit: (value) => {
233
- const chosen = value.trim() === "" ? defaultValue : value.trim();
234
- submit(chosen, chosen);
235
- },
236
- placeholder
237
- }
238
- ) });
239
- };
240
- const tuiText = async (message, settings) => {
241
- const fallback = settings?.default ?? "";
242
- if (!isInteractive()) {
243
- return fallback;
244
- }
245
- const { badge } = settings ?? {};
246
- return runInkPrompt(
247
- (finish) => jsx(TextView, { badge, defaultValue: fallback, finish, message, placeholder: settings?.placeholder }),
248
- fallback
249
- );
250
- };
251
- const MultiSelectView = ({ badge, defaults, finish, message, options }) => {
252
- const { answer, submit } = useAnswer(finish);
253
- const [cursor, setCursor] = useState(0);
254
- const [selected, setSelected] = useState(() => new Set(defaults));
255
- useEscapeToExit();
256
- useInput((input, key) => {
257
- if (answer !== void 0 || options.length === 0) {
258
- return;
259
- }
260
- if (key.upArrow) {
261
- setCursor((current) => (current - 1 + options.length) % options.length);
262
- } else if (key.downArrow) {
263
- setCursor((current) => (current + 1) % options.length);
264
- } else if (input === " ") {
265
- const option = options[cursor];
266
- if (option !== void 0) {
267
- setSelected((previous) => {
268
- const next = new Set(previous);
269
- if (next.has(option.value)) {
270
- next.delete(option.value);
271
- } else {
272
- next.add(option.value);
273
- }
274
- return next;
275
- });
276
- }
277
- } else if (key.return) {
278
- const picked = options.filter((option) => selected.has(option.value));
279
- submit(
280
- picked.map((option) => option.value),
281
- picked.length > 0 ? picked.map((option) => option.label).join(", ") : "none"
282
- );
283
- }
284
- });
285
- if (answer !== void 0) {
286
- return jsx(AnsweredLine, { answer, badge, message });
287
- }
288
- return jsx(PromptShell, { badge, message, children: jsxs(Box, { flexDirection: "column", children: [
289
- jsx(Text, { dimColor: true, children: "space toggles · enter confirms · esc cancels" }),
290
- options.map((option, index) => {
291
- const onCursor = index === cursor;
292
- return jsx(Text, { color: onCursor ? ACCENT : void 0, children: `${onCursor ? "▸ " : " "}${selected.has(option.value) ? "◼" : "◻"} ${itemLabel(option)}` }, option.value);
293
- })
294
- ] }) });
295
- };
296
- const tuiMultiSelect = async (message, options, settings) => {
297
- const defaults = settings?.defaults ?? [];
298
- if (!isInteractive() || options.length === 0) {
299
- return [...defaults];
300
- }
301
- const { badge } = settings ?? {};
302
- return runInkPrompt(
303
- (finish) => jsx(MultiSelectView, { badge, defaults, finish, message, options }),
304
- [...defaults]
305
- );
306
- };
307
- const ConfirmView = ({ badge, defaultYes, finish, message }) => {
308
- const { answer, submit } = useAnswer(finish);
309
- if (answer !== void 0) {
310
- return jsx(AnsweredLine, { answer, badge, message });
311
- }
312
- return jsxs(Box, { children: [
313
- badge === void 0 ? null : jsx(Badge, { spec: badge }),
314
- jsx(Text, { bold: true, children: badge === void 0 ? `${message} ` : ` ${message} ` }),
315
- jsx(
316
- ConfirmInput,
317
- {
318
- defaultChoice: defaultYes ? "confirm" : "cancel",
319
- onCancel: () => {
320
- submit(false, "No");
321
- },
322
- onConfirm: () => {
323
- submit(true, "Yes");
324
- }
325
- }
326
- )
327
- ] });
328
- };
329
- const tuiConfirm = async (message, options) => {
330
- const defaultYes = options?.defaultYes === true;
331
- if (!isInteractive()) {
332
- return defaultYes;
333
- }
334
- const { badge } = options ?? {};
335
- return runInkPrompt((finish) => jsx(ConfirmView, { badge, defaultYes, finish, message }), false);
336
- };
337
- const createTuiConfirm = () => isInteractive() ? (message) => tuiConfirm(message, { defaultYes: true }) : () => Promise.resolve(false);
338
- const STAR_BRIGHT = "#c8a8ff";
339
- const MOON_LIGHT = "#d9c8ff";
340
- const MOON_FACE = "#6b5b9a";
341
- const MoonRow = ({ moon, prefix, suffix }) => jsxs(Box, { children: [
342
- jsx(Text, { color: STAR_BRIGHT, dimColor: true, children: prefix }),
343
- typeof moon === "string" ? jsx(Text, { color: MOON_LIGHT, children: moon }) : moon,
344
- suffix === void 0 ? null : jsx(Text, { color: STAR_BRIGHT, children: suffix })
345
- ] });
346
- const MoonFace = ({ left, right }) => jsxs(Text, { color: MOON_LIGHT, children: [
347
- left,
348
- jsx(Text, { color: MOON_FACE, children: "●●" }),
349
- right
350
- ] });
351
- const MoonriseHeader = () => jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
352
- jsx(MoonRow, { moon: ".-‐-.", prefix: "· ✦ · ", suffix: " ✦" }),
353
- jsx(MoonRow, { moon: jsx(MoonFace, { left: "/", right: "\\" }), prefix: " ✦ · ", suffix: " ·" }),
354
- jsx(MoonRow, { moon: jsx(MoonFace, { left: "\\", right: "/" }), prefix: " . ✦ · " }),
355
- jsxs(Box, { children: [
356
- jsx(Text, { bold: true, color: ACCENT, children: " lunora init " }),
357
- jsx(Text, { dimColor: true, children: "· moonrise sequence" }),
358
- jsx(Text, { color: MOON_LIGHT })
359
- ] })
360
- ] });
361
- const tuiMoonrise = async (subtitle) => {
362
- if (!isInteractive()) {
363
- return;
364
- }
365
- await printFrame(
366
- jsxs(Box, { flexDirection: "column", children: [
367
- jsx(MoonriseHeader, {}),
368
- jsx(Box, { paddingX: 1, children: jsx(Text, { dimColor: true, children: subtitle }) })
369
- ] })
370
- );
371
- };
372
- const SpinnerView = ({ label }) => jsxs(Box, { children: [
373
- jsx(Text, { color: ACCENT, children: jsx(Spinner, { type: "dots" }) }),
374
- jsxs(Text, { children: [
375
- " ",
376
- label
377
- ] })
378
- ] });
379
- const withTuiSpinner = async (label, task) => {
380
- if (!isInteractive()) {
381
- return task();
382
- }
383
- raiseListenerCap();
384
- const instance = render(jsx(SpinnerView, { label }));
385
- try {
386
- return await task();
387
- } finally {
388
- instance.unmount();
389
- }
390
- };
391
- const tuiMascot = async () => {
392
- if (!isInteractive()) {
393
- return;
394
- }
395
- await printFrame(
396
- jsxs(Box, { paddingX: 1, children: [
397
- jsx(Text, { color: MOON_LIGHT, children: LUNA_ART }),
398
- jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
399
- jsx(Text, { bold: true, color: ACCENT, children: LUNA_NAME }),
400
- jsx(Text, { children: LUNA_SIGNOFF })
401
- ] })
402
- ] })
403
- );
404
- };
405
- const INFO_CYAN = "#06b6d4";
406
- const PROSE_INDENT = " ".repeat(9);
407
- const tuiHeadline = async (message) => {
408
- if (!isInteractive()) {
409
- return;
410
- }
411
- await printFrame(jsx(Text, { bold: true, children: `${PROSE_INDENT}${message}` }));
412
- };
413
- const tuiInfo = async (message) => {
414
- if (!isInteractive()) {
415
- return;
416
- }
417
- await printFrame(
418
- jsxs(Box, { children: [
419
- jsx(Text, { color: INFO_CYAN, children: `${HEADER_INDENT}◼` }),
420
- jsx(Text, { children: ` ${message}` })
421
- ] })
422
- );
423
- };
424
- const tuiNextSteps = async (badge, header, steps, help) => {
425
- if (!isInteractive()) {
426
- return;
427
- }
428
- await printFrame(
429
- jsxs(Box, { flexDirection: "column", children: [
430
- jsxs(Box, { children: [
431
- jsx(Badge, { spec: badge }),
432
- jsx(Text, { bold: true, children: ` ${header}` })
433
- ] }),
434
- jsx(Box, { flexDirection: "column", marginTop: 1, children: steps.map((step) => jsxs(Text, { children: [
435
- `${PROSE_INDENT}${step.lead} `,
436
- jsx(Text, { color: ACCENT, children: step.code }),
437
- step.tail ?? ""
438
- ] }, step.lead)) }),
439
- jsx(Box, { flexDirection: "column", marginTop: 1, children: help.map((line) => jsxs(Text, { children: [
440
- `${PROSE_INDENT}${line.lead} `,
441
- jsx(Text, { color: ACCENT, children: line.code }),
442
- line.tail ?? ""
443
- ] }, line.lead)) })
444
- ] })
445
- );
446
- };
447
- const TASK_INDENT = " ".repeat(BADGE_COLUMN_WIDTH - 1);
448
- const SPINNER_FIRST = "#a855f7";
449
- const SPINNER_LAST = "#06b6d4";
450
- const SPINNER_COLORS = [SPINNER_FIRST, "#9b51f6", "#8a5cf6", "#6f86f6", "#4aa6ef", "#2bb6dd", "#12bcd0", SPINNER_LAST];
451
- const SPINNER_BAR_WIDTH = SPINNER_COLORS.length - 2;
452
- const repeatColor = (count, value) => Array.from({ length: Math.max(0, count) }, () => value);
453
- const SPINNER_STRIP = [
454
- ...repeatColor(SPINNER_COLORS.length - 1, SPINNER_FIRST),
455
- ...SPINNER_COLORS,
456
- ...repeatColor(SPINNER_COLORS.length - 1, SPINNER_LAST),
457
- ...SPINNER_COLORS.toReversed()
458
- ];
459
- const SPINNER_FRAMES = SPINNER_STRIP.map((_, offset) => {
460
- const window = SPINNER_STRIP.slice(offset, offset + SPINNER_BAR_WIDTH);
461
- return [...window, ...repeatColor(SPINNER_BAR_WIDTH - window.length, SPINNER_FIRST)];
462
- });
463
- const SPINNER_LEAD = " ".repeat(Math.max(0, BADGE_COLUMN_WIDTH - SPINNER_BAR_WIDTH));
464
- const GradientSpinner = ({ label }) => {
465
- const [index, setIndex] = useState(0);
466
- useInterval(() => {
467
- setIndex((previous) => (previous + 1) % SPINNER_FRAMES.length);
468
- }, 90);
469
- const colors = SPINNER_FRAMES[index % SPINNER_FRAMES.length] ?? [];
470
- return jsxs(Text, { children: [
471
- SPINNER_LEAD,
472
- colors.map((color, blockIndex) => (
473
- // eslint-disable-next-line react-x/no-array-index-key -- fixed-length gradient bar that never reorders.
474
- jsx(Text, { color, children: "█" }, blockIndex)
475
- )),
476
- ` ${label}`
477
- ] });
478
- };
479
- const TaskRow = ({ label, status }) => {
480
- if (status === "running") {
481
- return jsx(Text, { color: ACCENT, children: `${TASK_INDENT}▶ ${label}` });
482
- }
483
- if (status === "failed") {
484
- return jsx(Text, { color: "red", children: `${TASK_INDENT}✖ ${label}` });
485
- }
486
- if (status === "done") {
487
- return jsx(Text, { dimColor: true, children: `${TASK_INDENT}■ ${label}` });
488
- }
489
- return jsx(Text, { dimColor: true, children: `${TASK_INDENT}□ ${label}` });
490
- };
491
- const runTaskList = async (tasks, mark) => {
492
- const results = [];
493
- let failure;
494
- for (const [index, task] of tasks.entries()) {
495
- mark(index, "running");
496
- try {
497
- results.push(await task.run());
498
- mark(index, "done");
499
- } catch (error) {
500
- mark(index, "failed");
501
- failure = error;
502
- break;
503
- }
504
- }
505
- return { failure, results };
506
- };
507
- const startTasks = (tasks, setStatuses, onSettle, exit) => {
508
- let active = true;
509
- const mark = (index, status) => {
510
- if (active) {
511
- setStatuses((previous) => previous.map((value, position) => position === index ? status : value));
512
- }
513
- };
514
- runTaskList(tasks, mark).then(({ failure, results }) => {
515
- setTimeout(() => {
516
- if (active) {
517
- onSettle(results, failure);
518
- exit();
519
- }
520
- }, 400);
521
- return void 0;
522
- }).catch(() => {
523
- });
524
- return () => {
525
- active = false;
526
- };
527
- };
528
- const TasksView = ({ end, onSettle, start, tasks }) => {
529
- const { exit } = useApp();
530
- const [statuses, setStatuses] = useState(() => tasks.map(() => "pending"));
531
- useEffect(() => startTasks(tasks, setStatuses, onSettle, exit), [exit, onSettle, tasks]);
532
- const allDone = statuses.length > 0 && statuses.every((status) => status === "done");
533
- return jsxs(Box, { flexDirection: "column", children: [
534
- allDone ? jsxs(Box, { children: [
535
- jsx(Text, { bold: true, color: "green", children: `${HEADER_INDENT}✔` }),
536
- jsx(Text, { bold: true, color: "green", children: ` ${end}` })
537
- ] }) : jsx(GradientSpinner, { label: start }),
538
- tasks.map((task, index) => jsx(TaskRow, { label: task.label, status: statuses[index] ?? "pending" }, task.label))
539
- ] });
540
- };
541
- const tuiTasks = async (tasks, labels) => {
542
- if (!isInteractive()) {
543
- const results2 = [];
544
- for (const task of tasks) {
545
- results2.push(await task.run());
546
- }
547
- return results2;
548
- }
549
- let results = [];
550
- let failure;
551
- await runInkApp(
552
- jsx(
553
- TasksView,
554
- {
555
- end: labels.end,
556
- onSettle: (settledResults, settledFailure) => {
557
- results = settledResults;
558
- failure = settledFailure;
559
- },
560
- start: labels.start,
561
- tasks
562
- }
563
- )
564
- );
565
- if (failure !== void 0) {
566
- throw toError(failure);
567
- }
568
- return results;
569
- };
570
- const runProgressSteps = async (steps, mark) => {
571
- const values = [];
572
- let failure;
573
- for (const [index, step] of steps.entries()) {
574
- mark(index);
575
- try {
576
- values.push(await step.task());
577
- } catch (error) {
578
- failure = error;
579
- break;
580
- }
581
- }
582
- return { failure, values };
583
- };
584
- const BadgeProgressView = ({ badge, done, onSettle, steps }) => {
585
- const { exit } = useApp();
586
- const [index, setIndex] = useState(0);
587
- const [finished, setFinished] = useState(false);
588
- useEffect(() => {
589
- let active = true;
590
- let timer;
591
- const mark = (next) => {
592
- if (active) {
593
- setIndex(next);
594
- }
595
- };
596
- runProgressSteps(steps, mark).then(({ failure, values }) => {
597
- if (!active) {
598
- return void 0;
599
- }
600
- if (failure !== void 0) {
601
- onSettle({ error: failure, ok: false });
602
- exit();
603
- return void 0;
604
- }
605
- setFinished(true);
606
- timer = setTimeout(() => {
607
- if (active) {
608
- onSettle({ ok: true, values });
609
- exit();
610
- }
611
- }, 400);
612
- return void 0;
613
- }).catch(() => {
614
- });
615
- return () => {
616
- active = false;
617
- if (timer !== void 0) {
618
- clearTimeout(timer);
619
- }
620
- };
621
- }, [exit, onSettle, steps]);
622
- return finished ? jsxs(Box, { children: [
623
- jsx(Badge, { spec: badge }),
624
- jsx(Text, { bold: true, children: ` ${done}` })
625
- ] }) : jsx(GradientSpinner, { label: steps[index]?.running ?? "" });
626
- };
627
- const withTuiBadgeProgress = async (badge, steps, done) => {
628
- if (!isInteractive()) {
629
- const values = [];
630
- for (const step of steps) {
631
- values.push(await step.task());
632
- }
633
- return values;
634
- }
635
- let outcome;
636
- await runInkApp(
637
- jsx(
638
- BadgeProgressView,
639
- {
640
- badge,
641
- done,
642
- onSettle: (settled) => {
643
- outcome = settled;
644
- },
645
- steps
646
- }
647
- )
648
- );
649
- if (outcome === void 0) {
650
- throw new PromptCancelledError();
651
- }
652
- if (!outcome.ok) {
653
- throw toError(outcome.error);
654
- }
655
- return outcome.values;
656
- };
657
-
658
- export { tuiSelect as a, tuiConfirm as b, createTuiConfirm as c, tuiMascot as d, tuiStep as e, tuiMoonrise as f, tuiHeadline as g, tuiInfo as h, tuiNextSteps as i, tuiTasks as j, tuiMultiSelect as k, withTuiBadgeProgress as l, tuiText as t, withTuiSpinner as w };
@@ -1,12 +0,0 @@
1
- import { findWranglerFile, readWranglerJsonc } from '@lunora/config';
2
-
3
- const readWranglerName = (cwd) => {
4
- const wranglerPath = findWranglerFile(cwd);
5
- if (!wranglerPath) {
6
- return void 0;
7
- }
8
- const { parsed } = readWranglerJsonc(wranglerPath);
9
- return typeof parsed?.name === "string" && parsed.name.length > 0 ? parsed.name : void 0;
10
- };
11
-
12
- export { readWranglerName as r };