@lunora/cli 1.0.0-alpha.32 → 1.0.0-alpha.321
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +33 -0
- package/README.md +1 -1
- package/dist/bin.mjs +2 -10
- package/dist/index.d.mts +960 -370
- package/dist/index.d.ts +960 -370
- package/dist/index.mjs +1 -19
- package/dist/packem_chunks/dispatch.mjs +1 -0
- package/dist/packem_chunks/handler.mjs +1 -160
- package/dist/packem_chunks/handler10.mjs +1 -16
- package/dist/packem_chunks/handler11.mjs +2 -22
- package/dist/packem_chunks/handler12.mjs +1 -192
- package/dist/packem_chunks/handler13.mjs +1 -131
- package/dist/packem_chunks/handler14.mjs +1 -65
- package/dist/packem_chunks/handler15.mjs +1 -58
- package/dist/packem_chunks/handler16.mjs +3 -80
- package/dist/packem_chunks/handler17.mjs +1 -43
- package/dist/packem_chunks/handler18.mjs +1 -105
- package/dist/packem_chunks/handler19.mjs +7 -170
- package/dist/packem_chunks/handler2.mjs +1 -114
- package/dist/packem_chunks/handler20.mjs +1 -94
- package/dist/packem_chunks/handler21.mjs +3 -94
- package/dist/packem_chunks/handler22.mjs +3 -0
- package/dist/packem_chunks/handler23.mjs +1 -0
- package/dist/packem_chunks/handler24.mjs +2 -0
- package/dist/packem_chunks/handler25.mjs +99 -0
- package/dist/packem_chunks/handler26.mjs +10 -0
- package/dist/packem_chunks/handler3.mjs +1 -204
- package/dist/packem_chunks/handler4.mjs +1 -33
- package/dist/packem_chunks/handler5.mjs +1 -49
- package/dist/packem_chunks/handler6.mjs +1 -91
- package/dist/packem_chunks/handler7.mjs +3 -42
- package/dist/packem_chunks/handler8.mjs +1 -174
- package/dist/packem_chunks/handler9.mjs +1 -315
- package/dist/packem_chunks/planDevCommand.mjs +7 -541
- package/dist/packem_chunks/runCodegenCommand.mjs +4 -52
- package/dist/packem_chunks/runDeployCommand.mjs +7 -594
- package/dist/packem_chunks/runInitCommand.mjs +162 -1430
- package/dist/packem_chunks/runResetCommand.mjs +1 -41
- package/dist/packem_chunks/runRpcCommand.mjs +1 -68
- package/dist/packem_shared/COMMANDS-DdaAWPtr.mjs +1 -0
- package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-BgMPHEoe.mjs +1 -0
- package/dist/packem_shared/EXIT_CODE-08cwt3MK.mjs +1 -0
- package/dist/packem_shared/admin-token-VdUnvnKW.mjs +1 -0
- package/dist/packem_shared/admin-url-BhF5ufg1.mjs +1 -0
- package/dist/packem_shared/binding-manifest-file-CQ1eQYy1.mjs +2 -0
- package/dist/packem_shared/buildRegistryIndex-Dc8D8AR6.mjs +1 -0
- package/dist/packem_shared/catalog-CahzmDLV.mjs +1 -0
- package/dist/packem_shared/cli-DOpChqUe.mjs +2 -0
- package/dist/packem_shared/codegen-error-AmH54ofi.mjs +3 -0
- package/dist/packem_shared/command-Mmxzxyr5.mjs +1 -0
- package/dist/packem_shared/commands-CNqednoX.mjs +13 -0
- package/dist/packem_shared/createLogger-Cl18I8AX.mjs +2 -0
- package/dist/packem_shared/createRecordingSpawner-sS7LEN7x.mjs +1 -0
- package/dist/packem_shared/deploy-target-DCWwiuAe.mjs +1 -0
- package/dist/packem_shared/diffSnapshots-WWwx-KvZ.mjs +5 -0
- package/dist/packem_shared/docker-DpVxvYpL.mjs +1 -0
- package/dist/packem_shared/import-D7qdpSmJ.mjs +12 -0
- package/dist/packem_shared/insertSchemaExtension-DuiV6cba.mjs +8 -0
- package/dist/packem_shared/lint-ignore-report-DKZagpqk.mjs +2 -0
- package/dist/packem_shared/open-url-EnKy--w-.mjs +1 -0
- package/dist/packem_shared/parseManifest-CwPTKdtS.mjs +1 -0
- package/dist/packem_shared/path-containment-CgxYZggb.mjs +1 -0
- package/dist/packem_shared/platform-diagnostics-Cn2g6Jh-.mjs +4 -0
- package/dist/packem_shared/prompt-cancelled-BvsNxg_Q.mjs +1 -0
- package/dist/packem_shared/render-lunora-error--4tmM6mt.mjs +3 -0
- package/dist/packem_shared/resolve-DUCSc7jQ.mjs +5 -0
- package/dist/packem_shared/resolve-target-C_ZloTvd.mjs +1 -0
- package/dist/packem_shared/runAddCommand-Cf2q2y27.mjs +1 -0
- package/dist/packem_shared/runExportCommand-DxsJHYZt.mjs +5 -0
- package/dist/packem_shared/runMigrateGenerateCommand-CDHswpMU.mjs +11 -0
- package/dist/packem_shared/schema-drift-gate-BDCkQ1S6.mjs +1 -0
- package/dist/packem_shared/schemaIrToSnapshot-BjK-0IRo.mjs +1 -0
- package/dist/packem_shared/shared-D-zCOmgY.mjs +1 -0
- package/dist/packem_shared/storage-J4xhM4FU.mjs +1 -0
- package/dist/packem_shared/tui-prompts-B3YwUhGw.mjs +4 -0
- package/dist/packem_shared/vectorize-metadata-dXpl2_Ar.mjs +1 -0
- package/dist/packem_shared/wrangler-name-Dsk5K1f-.mjs +1 -0
- package/dist/packem_shared/wrangler-secrets-C9lJnd5N.mjs +1 -0
- package/package.json +39 -19
- package/skills/README.md +35 -17
- package/skills/lunora/SKILL.md +123 -9
- package/skills/lunora-create-package/SKILL.md +4 -3
- package/skills/lunora-deploy/SKILL.md +42 -11
- package/skills/lunora-functions/SKILL.md +120 -15
- package/skills/lunora-migration-helper/SKILL.md +74 -21
- package/skills/lunora-performance-audit/SKILL.md +78 -9
- package/skills/lunora-quickstart/SKILL.md +93 -27
- package/skills/lunora-realtime/SKILL.md +73 -39
- package/skills/lunora-setup-auth/SKILL.md +33 -6
- package/skills/lunora-setup-hyperdrive/SKILL.md +33 -13
- package/skills/lunora-setup-hyperdrive-global/SKILL.md +5 -0
- package/skills/lunora-setup-mail/SKILL.md +34 -28
- package/skills/lunora-setup-scheduler/SKILL.md +18 -14
- package/skills/lunora-setup-storage/SKILL.md +187 -27
- package/dist/packem_chunks/runMigrateGenerateCommand.mjs +0 -397
- package/dist/packem_shared/COMMANDS-B0ftFD_3.mjs +0 -948
- package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-Ck-2bU08.mjs +0 -244
- package/dist/packem_shared/admin-url-4UzT-CI4.mjs +0 -19
- package/dist/packem_shared/api-spec-CtA6ilu4.mjs +0 -13
- package/dist/packem_shared/buildRegistryIndex-BcYe607_.mjs +0 -38
- package/dist/packem_shared/codegen-error-DJG-ghs_.mjs +0 -31
- package/dist/packem_shared/command-D3lB_4Az.mjs +0 -19
- package/dist/packem_shared/commands-B-gR09Z_.mjs +0 -845
- package/dist/packem_shared/createLogger-B40gPzQo.mjs +0 -78
- package/dist/packem_shared/createRecordingSpawner-DxI3mebw.mjs +0 -43
- package/dist/packem_shared/detect-package-manager-DYp7n3mJ.mjs +0 -61
- package/dist/packem_shared/diffSnapshots-BeDvvNiF.mjs +0 -161
- package/dist/packem_shared/docker-hMQ97KSQ.mjs +0 -21
- package/dist/packem_shared/insertSchemaExtension-DAqbfr9Z.mjs +0 -64
- package/dist/packem_shared/open-url-Dfq6fAyT.mjs +0 -41
- package/dist/packem_shared/output-format-wUvAN6AL.mjs +0 -17
- package/dist/packem_shared/parseArgs-YXFuKdEk.mjs +0 -56
- package/dist/packem_shared/parseManifest--vZf2FY1.mjs +0 -94
- package/dist/packem_shared/prompt-cancelled-APzX1Im-.mjs +0 -9
- package/dist/packem_shared/resolve-target-qbsJ_5sF.mjs +0 -16
- package/dist/packem_shared/runAddCommand-bnY6-HKb.mjs +0 -4
- package/dist/packem_shared/schema-drift-gate-BtBt0as0.mjs +0 -79
- package/dist/packem_shared/schemaIrToSnapshot-DdsljJT-.mjs +0 -43
- package/dist/packem_shared/storage-BIsph-Vk.mjs +0 -84
- package/dist/packem_shared/tui-prompts-BjEN8XgP.mjs +0 -658
- package/dist/packem_shared/wrangler-name-cy4yhm9j.mjs +0 -12
- package/dist/packem_shared/wrangler-secrets-P2_ZUR-k.mjs +0 -47
|
@@ -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 };
|