@enactprotocol/cli 1.2.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/package.json +34 -38
- package/src/commands/auth/index.ts +940 -0
- package/src/commands/cache/index.ts +361 -0
- package/src/commands/config/README.md +239 -0
- package/src/commands/config/index.ts +164 -0
- package/src/commands/env/README.md +197 -0
- package/src/commands/env/index.ts +392 -0
- package/src/commands/exec/README.md +110 -0
- package/src/commands/exec/index.ts +195 -0
- package/src/commands/get/index.ts +198 -0
- package/src/commands/index.ts +30 -0
- package/src/commands/inspect/index.ts +264 -0
- package/src/commands/install/README.md +146 -0
- package/src/commands/install/index.ts +682 -0
- package/src/commands/list/README.md +115 -0
- package/src/commands/list/index.ts +138 -0
- package/src/commands/publish/index.ts +350 -0
- package/src/commands/report/index.ts +366 -0
- package/src/commands/run/README.md +124 -0
- package/src/commands/run/index.ts +686 -0
- package/src/commands/search/index.ts +368 -0
- package/src/commands/setup/index.ts +274 -0
- package/src/commands/sign/index.ts +652 -0
- package/src/commands/trust/README.md +214 -0
- package/src/commands/trust/index.ts +453 -0
- package/src/commands/unyank/index.ts +107 -0
- package/src/commands/yank/index.ts +143 -0
- package/src/index.ts +96 -0
- package/src/types.ts +81 -0
- package/src/utils/errors.ts +409 -0
- package/src/utils/exit-codes.ts +159 -0
- package/src/utils/ignore.ts +147 -0
- package/src/utils/index.ts +107 -0
- package/src/utils/output.ts +242 -0
- package/src/utils/spinner.ts +214 -0
- package/tests/commands/auth.test.ts +217 -0
- package/tests/commands/cache.test.ts +286 -0
- package/tests/commands/config.test.ts +277 -0
- package/tests/commands/env.test.ts +293 -0
- package/tests/commands/exec.test.ts +112 -0
- package/tests/commands/get.test.ts +179 -0
- package/tests/commands/inspect.test.ts +201 -0
- package/tests/commands/install-integration.test.ts +343 -0
- package/tests/commands/install.test.ts +288 -0
- package/tests/commands/list.test.ts +160 -0
- package/tests/commands/publish.test.ts +186 -0
- package/tests/commands/report.test.ts +194 -0
- package/tests/commands/run.test.ts +231 -0
- package/tests/commands/search.test.ts +131 -0
- package/tests/commands/sign.test.ts +164 -0
- package/tests/commands/trust.test.ts +236 -0
- package/tests/commands/unyank.test.ts +114 -0
- package/tests/commands/yank.test.ts +154 -0
- package/tests/e2e.test.ts +554 -0
- package/tests/fixtures/calculator/enact.yaml +34 -0
- package/tests/fixtures/echo-tool/enact.md +31 -0
- package/tests/fixtures/env-tool/enact.yaml +19 -0
- package/tests/fixtures/greeter/enact.yaml +18 -0
- package/tests/fixtures/invalid-tool/enact.yaml +4 -0
- package/tests/index.test.ts +8 -0
- package/tests/types.test.ts +84 -0
- package/tests/utils/errors.test.ts +303 -0
- package/tests/utils/exit-codes.test.ts +189 -0
- package/tests/utils/ignore.test.ts +461 -0
- package/tests/utils/output.test.ts +126 -0
- package/tsconfig.json +17 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/dist/index.js +0 -231410
- package/dist/index.js.bak +0 -231409
- package/dist/web/static/app.js +0 -663
- package/dist/web/static/index.html +0 -117
- package/dist/web/static/style.css +0 -291
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Output formatting
|
|
6
|
+
export {
|
|
7
|
+
colors,
|
|
8
|
+
symbols,
|
|
9
|
+
success,
|
|
10
|
+
error,
|
|
11
|
+
warning,
|
|
12
|
+
info,
|
|
13
|
+
dim,
|
|
14
|
+
newline,
|
|
15
|
+
header,
|
|
16
|
+
keyValue,
|
|
17
|
+
listItem,
|
|
18
|
+
table,
|
|
19
|
+
json,
|
|
20
|
+
jsonCompact,
|
|
21
|
+
formatError,
|
|
22
|
+
errorWithDetails,
|
|
23
|
+
suggest,
|
|
24
|
+
status,
|
|
25
|
+
clearLine,
|
|
26
|
+
type TableColumn,
|
|
27
|
+
} from "./output";
|
|
28
|
+
|
|
29
|
+
// Spinner and prompts
|
|
30
|
+
export {
|
|
31
|
+
createSpinner,
|
|
32
|
+
withSpinner,
|
|
33
|
+
intro,
|
|
34
|
+
outro,
|
|
35
|
+
confirm,
|
|
36
|
+
text,
|
|
37
|
+
password,
|
|
38
|
+
select,
|
|
39
|
+
isCancel,
|
|
40
|
+
cancel,
|
|
41
|
+
log,
|
|
42
|
+
logInfo,
|
|
43
|
+
logSuccess,
|
|
44
|
+
logWarning,
|
|
45
|
+
logError,
|
|
46
|
+
logStep,
|
|
47
|
+
type SpinnerInstance,
|
|
48
|
+
} from "./spinner";
|
|
49
|
+
|
|
50
|
+
// Exit codes
|
|
51
|
+
export {
|
|
52
|
+
EXIT_SUCCESS,
|
|
53
|
+
EXIT_FAILURE,
|
|
54
|
+
EXIT_USAGE,
|
|
55
|
+
EXIT_DATAERR,
|
|
56
|
+
EXIT_NOINPUT,
|
|
57
|
+
EXIT_NOUSER,
|
|
58
|
+
EXIT_NOHOST,
|
|
59
|
+
EXIT_UNAVAILABLE,
|
|
60
|
+
EXIT_SOFTWARE,
|
|
61
|
+
EXIT_OSERR,
|
|
62
|
+
EXIT_OSFILE,
|
|
63
|
+
EXIT_CANTCREAT,
|
|
64
|
+
EXIT_IOERR,
|
|
65
|
+
EXIT_TEMPFAIL,
|
|
66
|
+
EXIT_PROTOCOL,
|
|
67
|
+
EXIT_NOPERM,
|
|
68
|
+
EXIT_CONFIG,
|
|
69
|
+
EXIT_TOOL_NOT_FOUND,
|
|
70
|
+
EXIT_MANIFEST_ERROR,
|
|
71
|
+
EXIT_EXECUTION_ERROR,
|
|
72
|
+
EXIT_TIMEOUT,
|
|
73
|
+
EXIT_TRUST_ERROR,
|
|
74
|
+
EXIT_REGISTRY_ERROR,
|
|
75
|
+
EXIT_AUTH_ERROR,
|
|
76
|
+
EXIT_VALIDATION_ERROR,
|
|
77
|
+
EXIT_NETWORK_ERROR,
|
|
78
|
+
EXIT_CONTAINER_ERROR,
|
|
79
|
+
getExitCodeDescription,
|
|
80
|
+
exit,
|
|
81
|
+
exitSuccess,
|
|
82
|
+
exitFailure,
|
|
83
|
+
} from "./exit-codes";
|
|
84
|
+
|
|
85
|
+
// Error handling
|
|
86
|
+
export {
|
|
87
|
+
CliError,
|
|
88
|
+
ToolNotFoundError,
|
|
89
|
+
ManifestError,
|
|
90
|
+
ValidationError,
|
|
91
|
+
AuthError,
|
|
92
|
+
NetworkError,
|
|
93
|
+
RegistryError,
|
|
94
|
+
TrustError,
|
|
95
|
+
TimeoutError,
|
|
96
|
+
ExecutionError,
|
|
97
|
+
ContainerError,
|
|
98
|
+
FileNotFoundError,
|
|
99
|
+
PermissionError,
|
|
100
|
+
ConfigError,
|
|
101
|
+
UsageError,
|
|
102
|
+
handleError,
|
|
103
|
+
withErrorHandling,
|
|
104
|
+
categorizeError,
|
|
105
|
+
ErrorMessages,
|
|
106
|
+
printErrorWithSuggestions,
|
|
107
|
+
} from "./errors";
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output utilities for CLI
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent formatting, colors, and output helpers
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import pc from "picocolors";
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Colors and Formatting
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
export const colors = {
|
|
14
|
+
// Status colors
|
|
15
|
+
success: pc.green,
|
|
16
|
+
error: pc.red,
|
|
17
|
+
warning: pc.yellow,
|
|
18
|
+
info: pc.blue,
|
|
19
|
+
dim: pc.dim,
|
|
20
|
+
bold: pc.bold,
|
|
21
|
+
|
|
22
|
+
// Semantic colors
|
|
23
|
+
command: pc.cyan,
|
|
24
|
+
path: pc.underline,
|
|
25
|
+
value: pc.yellow,
|
|
26
|
+
key: pc.bold,
|
|
27
|
+
version: pc.magenta,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Symbols
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
export const symbols = {
|
|
35
|
+
success: pc.green("✓"),
|
|
36
|
+
error: pc.red("✗"),
|
|
37
|
+
warning: pc.yellow("⚠"),
|
|
38
|
+
info: pc.blue("ℹ"),
|
|
39
|
+
arrow: pc.dim("→"),
|
|
40
|
+
bullet: pc.dim("•"),
|
|
41
|
+
check: pc.green("✔"),
|
|
42
|
+
cross: pc.red("✘"),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Output Functions
|
|
47
|
+
// ============================================================================
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Print a success message
|
|
51
|
+
*/
|
|
52
|
+
export function success(message: string): void {
|
|
53
|
+
console.log(`${symbols.success} ${message}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Print an error message
|
|
58
|
+
*/
|
|
59
|
+
export function error(message: string): void {
|
|
60
|
+
console.error(`${symbols.error} ${colors.error(message)}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Print a warning message
|
|
65
|
+
*/
|
|
66
|
+
export function warning(message: string): void {
|
|
67
|
+
console.warn(`${symbols.warning} ${colors.warning(message)}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Print an info message
|
|
72
|
+
*/
|
|
73
|
+
export function info(message: string): void {
|
|
74
|
+
console.log(`${symbols.info} ${message}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Print a dim/subtle message
|
|
79
|
+
*/
|
|
80
|
+
export function dim(message: string): void {
|
|
81
|
+
console.log(colors.dim(message));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Print a newline
|
|
86
|
+
*/
|
|
87
|
+
export function newline(): void {
|
|
88
|
+
console.log();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Print a header
|
|
93
|
+
*/
|
|
94
|
+
export function header(text: string): void {
|
|
95
|
+
console.log();
|
|
96
|
+
console.log(colors.bold(text));
|
|
97
|
+
console.log(colors.dim("─".repeat(text.length)));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Print a key-value pair
|
|
102
|
+
*/
|
|
103
|
+
export function keyValue(key: string, value: string, indent = 0): void {
|
|
104
|
+
const padding = " ".repeat(indent);
|
|
105
|
+
console.log(`${padding}${colors.key(key)}: ${value}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Print a list item
|
|
110
|
+
*/
|
|
111
|
+
export function listItem(text: string, indent = 0): void {
|
|
112
|
+
const padding = " ".repeat(indent);
|
|
113
|
+
console.log(`${padding}${symbols.bullet} ${text}`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// Tables
|
|
118
|
+
// ============================================================================
|
|
119
|
+
|
|
120
|
+
export interface TableColumn {
|
|
121
|
+
key: string;
|
|
122
|
+
header: string;
|
|
123
|
+
width?: number;
|
|
124
|
+
align?: "left" | "right" | "center";
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Print a simple table
|
|
129
|
+
*/
|
|
130
|
+
export function table<T extends Record<string, unknown>>(data: T[], columns: TableColumn[]): void {
|
|
131
|
+
if (data.length === 0) {
|
|
132
|
+
dim(" No items to display");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Calculate column widths
|
|
137
|
+
const widths = columns.map((col) => {
|
|
138
|
+
const headerWidth = col.header.length;
|
|
139
|
+
const maxDataWidth = Math.max(...data.map((row) => String(row[col.key] ?? "").length));
|
|
140
|
+
return col.width ?? Math.max(headerWidth, maxDataWidth);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Print header
|
|
144
|
+
const headerLine = columns
|
|
145
|
+
.map((col, i) => pad(col.header, widths[i] ?? col.header.length, col.align))
|
|
146
|
+
.join(" ");
|
|
147
|
+
console.log(colors.bold(headerLine));
|
|
148
|
+
console.log(colors.dim("─".repeat(headerLine.length)));
|
|
149
|
+
|
|
150
|
+
// Print rows
|
|
151
|
+
for (const row of data) {
|
|
152
|
+
const line = columns
|
|
153
|
+
.map((col, i) => pad(String(row[col.key] ?? ""), widths[i] ?? 10, col.align))
|
|
154
|
+
.join(" ");
|
|
155
|
+
console.log(line);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function pad(text: string, width: number, align: "left" | "right" | "center" = "left"): string {
|
|
160
|
+
const padding = width - text.length;
|
|
161
|
+
if (padding <= 0) return text.slice(0, width);
|
|
162
|
+
|
|
163
|
+
switch (align) {
|
|
164
|
+
case "right":
|
|
165
|
+
return " ".repeat(padding) + text;
|
|
166
|
+
case "center": {
|
|
167
|
+
const left = Math.floor(padding / 2);
|
|
168
|
+
const right = padding - left;
|
|
169
|
+
return " ".repeat(left) + text + " ".repeat(right);
|
|
170
|
+
}
|
|
171
|
+
default:
|
|
172
|
+
return text + " ".repeat(padding);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ============================================================================
|
|
177
|
+
// JSON Output
|
|
178
|
+
// ============================================================================
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Print data as JSON (for --json flag)
|
|
182
|
+
*/
|
|
183
|
+
export function json(data: unknown): void {
|
|
184
|
+
console.log(JSON.stringify(data, null, 2));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Print data as compact JSON
|
|
189
|
+
*/
|
|
190
|
+
export function jsonCompact(data: unknown): void {
|
|
191
|
+
console.log(JSON.stringify(data));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ============================================================================
|
|
195
|
+
// Error Formatting
|
|
196
|
+
// ============================================================================
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Format an error for display
|
|
200
|
+
*/
|
|
201
|
+
export function formatError(err: unknown): string {
|
|
202
|
+
if (err instanceof Error) {
|
|
203
|
+
return err.message;
|
|
204
|
+
}
|
|
205
|
+
return String(err);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Print an error with details
|
|
210
|
+
*/
|
|
211
|
+
export function errorWithDetails(message: string, details?: string): void {
|
|
212
|
+
error(message);
|
|
213
|
+
if (details) {
|
|
214
|
+
console.error(colors.dim(` ${details}`));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Print a suggestion after an error
|
|
220
|
+
*/
|
|
221
|
+
export function suggest(message: string): void {
|
|
222
|
+
console.log();
|
|
223
|
+
console.log(`${colors.info("Suggestion:")} ${message}`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ============================================================================
|
|
227
|
+
// Progress / Status
|
|
228
|
+
// ============================================================================
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Print a status line that can be updated
|
|
232
|
+
*/
|
|
233
|
+
export function status(message: string): void {
|
|
234
|
+
process.stdout.write(`\r${symbols.info} ${message}`);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Clear the current line
|
|
239
|
+
*/
|
|
240
|
+
export function clearLine(): void {
|
|
241
|
+
process.stdout.write("\r\x1b[K");
|
|
242
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spinner utility using @clack/prompts
|
|
3
|
+
*
|
|
4
|
+
* Provides loading spinners for long-running operations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as p from "@clack/prompts";
|
|
8
|
+
|
|
9
|
+
export interface SpinnerInstance {
|
|
10
|
+
start: (message?: string) => void;
|
|
11
|
+
stop: (message?: string, code?: number) => void;
|
|
12
|
+
message: (message: string) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create a spinner for long-running operations
|
|
17
|
+
*/
|
|
18
|
+
export function createSpinner(): SpinnerInstance {
|
|
19
|
+
const spinner = p.spinner();
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
start(message = "Loading...") {
|
|
23
|
+
spinner.start(message);
|
|
24
|
+
},
|
|
25
|
+
stop(message?: string, code = 0) {
|
|
26
|
+
spinner.stop(message, code);
|
|
27
|
+
},
|
|
28
|
+
message(message: string) {
|
|
29
|
+
spinner.message(message);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Run an async operation with a spinner
|
|
36
|
+
*/
|
|
37
|
+
export async function withSpinner<T>(
|
|
38
|
+
message: string,
|
|
39
|
+
fn: () => Promise<T>,
|
|
40
|
+
successMessage?: string
|
|
41
|
+
): Promise<T> {
|
|
42
|
+
const spinner = createSpinner();
|
|
43
|
+
spinner.start(message);
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const result = await fn();
|
|
47
|
+
spinner.stop(successMessage ?? message);
|
|
48
|
+
return result;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
spinner.stop(`Failed: ${message}`, 1);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Show a simple intro banner
|
|
57
|
+
*/
|
|
58
|
+
export function intro(message: string): void {
|
|
59
|
+
p.intro(message);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Show an outro message
|
|
64
|
+
*/
|
|
65
|
+
export function outro(message: string): void {
|
|
66
|
+
p.outro(message);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Prompt for confirmation
|
|
71
|
+
*/
|
|
72
|
+
export async function confirm(message: string, initialValue = false): Promise<boolean> {
|
|
73
|
+
const result = await p.confirm({
|
|
74
|
+
message,
|
|
75
|
+
initialValue,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (p.isCancel(result)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Prompt for text input
|
|
87
|
+
*/
|
|
88
|
+
export async function text(
|
|
89
|
+
message: string,
|
|
90
|
+
options?: {
|
|
91
|
+
placeholder?: string;
|
|
92
|
+
defaultValue?: string;
|
|
93
|
+
validate?: (value: string) => string | undefined;
|
|
94
|
+
}
|
|
95
|
+
): Promise<string | null> {
|
|
96
|
+
const textOptions: {
|
|
97
|
+
message: string;
|
|
98
|
+
placeholder?: string;
|
|
99
|
+
defaultValue?: string;
|
|
100
|
+
validate?: (value: string) => string | undefined;
|
|
101
|
+
} = {
|
|
102
|
+
message,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
if (options?.placeholder) {
|
|
106
|
+
textOptions.placeholder = options.placeholder;
|
|
107
|
+
}
|
|
108
|
+
if (options?.defaultValue) {
|
|
109
|
+
textOptions.defaultValue = options.defaultValue;
|
|
110
|
+
}
|
|
111
|
+
if (options?.validate) {
|
|
112
|
+
textOptions.validate = options.validate;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const result = await p.text(textOptions);
|
|
116
|
+
|
|
117
|
+
if (p.isCancel(result)) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Prompt for password input (masked)
|
|
126
|
+
*/
|
|
127
|
+
export async function password(message: string): Promise<string | null> {
|
|
128
|
+
const result = await p.password({
|
|
129
|
+
message,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if (p.isCancel(result)) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Prompt for selection from options
|
|
141
|
+
*/
|
|
142
|
+
export async function select<T extends string>(
|
|
143
|
+
message: string,
|
|
144
|
+
options: Array<{ value: T; label: string; hint?: string }>
|
|
145
|
+
): Promise<T | null> {
|
|
146
|
+
const result = await p.select({
|
|
147
|
+
message,
|
|
148
|
+
// biome-ignore lint/suspicious/noExplicitAny: clack types are strict about optional props
|
|
149
|
+
options: options as any,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
if (p.isCancel(result)) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return result as T;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Check if user cancelled
|
|
161
|
+
*/
|
|
162
|
+
export function isCancel(value: unknown): boolean {
|
|
163
|
+
return p.isCancel(value);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Cancel and exit
|
|
168
|
+
*/
|
|
169
|
+
export function cancel(message = "Operation cancelled"): never {
|
|
170
|
+
p.cancel(message);
|
|
171
|
+
process.exit(0);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Log a message (respects CI mode)
|
|
176
|
+
*/
|
|
177
|
+
export function log(message: string): void {
|
|
178
|
+
p.log.message(message);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Log an info message
|
|
183
|
+
*/
|
|
184
|
+
export function logInfo(message: string): void {
|
|
185
|
+
p.log.info(message);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Log a success message
|
|
190
|
+
*/
|
|
191
|
+
export function logSuccess(message: string): void {
|
|
192
|
+
p.log.success(message);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Log a warning
|
|
197
|
+
*/
|
|
198
|
+
export function logWarning(message: string): void {
|
|
199
|
+
p.log.warn(message);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Log an error
|
|
204
|
+
*/
|
|
205
|
+
export function logError(message: string): void {
|
|
206
|
+
p.log.error(message);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Log a step
|
|
211
|
+
*/
|
|
212
|
+
export function logStep(message: string): void {
|
|
213
|
+
p.log.step(message);
|
|
214
|
+
}
|