@outfitter/cli 0.1.0-rc.1
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 +436 -0
- package/dist/actions.d.ts +13 -0
- package/dist/actions.js +175 -0
- package/dist/cli.d.ts +104 -0
- package/dist/cli.js +55 -0
- package/dist/command.d.ts +74 -0
- package/dist/command.js +46 -0
- package/dist/index.d.ts +607 -0
- package/dist/index.js +50 -0
- package/dist/input.d.ts +278 -0
- package/dist/input.js +439 -0
- package/dist/output.d.ts +69 -0
- package/dist/output.js +156 -0
- package/dist/pagination.d.ts +96 -0
- package/dist/pagination.js +90 -0
- package/dist/shared/@outfitter/cli-4yy82cmp.js +20 -0
- package/dist/types.d.ts +253 -0
- package/dist/types.js +12 -0
- package/package.json +100 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { CancelledError, ValidationError } from "@outfitter/contracts";
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for creating a CLI instance.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const config: CLIConfig = {
|
|
9
|
+
* name: "waymark",
|
|
10
|
+
* version: "1.0.0",
|
|
11
|
+
* description: "A note management CLI",
|
|
12
|
+
* };
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
interface CLIConfig {
|
|
16
|
+
/** CLI name (used in help output and error messages) */
|
|
17
|
+
readonly name: string;
|
|
18
|
+
/** CLI version (displayed with --version) */
|
|
19
|
+
readonly version: string;
|
|
20
|
+
/** CLI description (displayed in help output) */
|
|
21
|
+
readonly description?: string;
|
|
22
|
+
/** Custom error handler */
|
|
23
|
+
readonly onError?: (error: Error) => void;
|
|
24
|
+
/** Custom exit handler (defaults to process.exit) */
|
|
25
|
+
readonly onExit?: (code: number) => never;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* CLI instance returned by createCLI.
|
|
29
|
+
*/
|
|
30
|
+
interface CLI {
|
|
31
|
+
/** Register a command with the CLI */
|
|
32
|
+
register(command: CommandBuilder | Command): this;
|
|
33
|
+
/** Parse arguments and execute the matched command */
|
|
34
|
+
parse(argv?: readonly string[]): Promise<void>;
|
|
35
|
+
/** Get the underlying Commander program */
|
|
36
|
+
readonly program: Command;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Configuration for a single command.
|
|
40
|
+
*/
|
|
41
|
+
interface CommandConfig {
|
|
42
|
+
/** Command name and argument syntax (e.g., "list" or "get <id>") */
|
|
43
|
+
readonly name: string;
|
|
44
|
+
/** Command description */
|
|
45
|
+
readonly description?: string;
|
|
46
|
+
/** Command aliases */
|
|
47
|
+
readonly aliases?: readonly string[];
|
|
48
|
+
/** Whether to hide from help output */
|
|
49
|
+
readonly hidden?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Action function executed when a command is invoked.
|
|
53
|
+
*
|
|
54
|
+
* @typeParam TFlags - Type of parsed command flags
|
|
55
|
+
*/
|
|
56
|
+
type CommandAction<TFlags extends CommandFlags = CommandFlags> = (context: {
|
|
57
|
+
/** Parsed command-line arguments */
|
|
58
|
+
readonly args: readonly string[];
|
|
59
|
+
/** Parsed command flags */
|
|
60
|
+
readonly flags: TFlags;
|
|
61
|
+
/** Raw Commander command instance */
|
|
62
|
+
readonly command: Command;
|
|
63
|
+
}) => Promise<void> | void;
|
|
64
|
+
/**
|
|
65
|
+
* Base type for command flags.
|
|
66
|
+
* All flag types must extend this.
|
|
67
|
+
*/
|
|
68
|
+
type CommandFlags = Record<string, unknown>;
|
|
69
|
+
/**
|
|
70
|
+
* Builder interface for constructing commands fluently.
|
|
71
|
+
*/
|
|
72
|
+
interface CommandBuilder {
|
|
73
|
+
/** Set command description */
|
|
74
|
+
description(text: string): this;
|
|
75
|
+
/** Add a command option/flag */
|
|
76
|
+
option(flags: string, description: string, defaultValue?: unknown): this;
|
|
77
|
+
/** Add a required option */
|
|
78
|
+
requiredOption(flags: string, description: string, defaultValue?: unknown): this;
|
|
79
|
+
/** Add command aliases */
|
|
80
|
+
alias(alias: string): this;
|
|
81
|
+
/** Set the action handler */
|
|
82
|
+
action<TFlags extends CommandFlags = CommandFlags>(handler: CommandAction<TFlags>): this;
|
|
83
|
+
/** Build the underlying Commander command */
|
|
84
|
+
build(): Command;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Available output modes for CLI commands.
|
|
88
|
+
*/
|
|
89
|
+
type OutputMode = "human" | "json" | "jsonl" | "tree" | "table";
|
|
90
|
+
/**
|
|
91
|
+
* Options for the output() function.
|
|
92
|
+
*/
|
|
93
|
+
interface OutputOptions {
|
|
94
|
+
/** Force a specific output mode (overrides flag detection) */
|
|
95
|
+
readonly mode?: OutputMode;
|
|
96
|
+
/** Stream to write to (defaults to stdout) */
|
|
97
|
+
readonly stream?: NodeJS.WritableStream;
|
|
98
|
+
/** Whether to pretty-print JSON output */
|
|
99
|
+
readonly pretty?: boolean;
|
|
100
|
+
/** Exit code to use after output (undefined = don't exit) */
|
|
101
|
+
readonly exitCode?: number;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Options for collectIds() input utility.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const ids = await collectIds(args, {
|
|
109
|
+
* allowFile: true, // @file expansion
|
|
110
|
+
* allowStdin: true, // - reads from stdin
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
interface CollectIdsOptions {
|
|
115
|
+
/** Allow @file expansion (reads IDs from file) */
|
|
116
|
+
readonly allowFile?: boolean;
|
|
117
|
+
/** Allow glob patterns */
|
|
118
|
+
readonly allowGlob?: boolean;
|
|
119
|
+
/** Allow reading from stdin with "-" */
|
|
120
|
+
readonly allowStdin?: boolean;
|
|
121
|
+
/** Separator for comma-separated values */
|
|
122
|
+
readonly separator?: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Options for expandFileArg() input utility.
|
|
126
|
+
*/
|
|
127
|
+
interface ExpandFileOptions {
|
|
128
|
+
/** Encoding for file reads (defaults to utf-8) */
|
|
129
|
+
readonly encoding?: BufferEncoding;
|
|
130
|
+
/** Maximum file size to read (in bytes) */
|
|
131
|
+
readonly maxSize?: number;
|
|
132
|
+
/** Whether to trim the file content */
|
|
133
|
+
readonly trim?: boolean;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Options for parseGlob() input utility.
|
|
137
|
+
*/
|
|
138
|
+
interface ParseGlobOptions {
|
|
139
|
+
/** Current working directory for glob resolution */
|
|
140
|
+
readonly cwd?: string;
|
|
141
|
+
/** Whether to follow symlinks */
|
|
142
|
+
readonly followSymlinks?: boolean;
|
|
143
|
+
/** Patterns to exclude */
|
|
144
|
+
readonly ignore?: readonly string[];
|
|
145
|
+
/** Only match files (not directories) */
|
|
146
|
+
readonly onlyFiles?: boolean;
|
|
147
|
+
/** Only match directories (not files) */
|
|
148
|
+
readonly onlyDirectories?: boolean;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Options for normalizeId().
|
|
152
|
+
*/
|
|
153
|
+
interface NormalizeIdOptions {
|
|
154
|
+
/** Whether to lowercase the ID */
|
|
155
|
+
readonly lowercase?: boolean;
|
|
156
|
+
/** Whether to trim whitespace */
|
|
157
|
+
readonly trim?: boolean;
|
|
158
|
+
/** Minimum length requirement */
|
|
159
|
+
readonly minLength?: number;
|
|
160
|
+
/** Maximum length requirement */
|
|
161
|
+
readonly maxLength?: number;
|
|
162
|
+
/** Pattern the ID must match */
|
|
163
|
+
readonly pattern?: RegExp;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Options for confirmDestructive().
|
|
167
|
+
*/
|
|
168
|
+
interface ConfirmDestructiveOptions {
|
|
169
|
+
/** Message to display to the user */
|
|
170
|
+
readonly message: string;
|
|
171
|
+
/** Whether to bypass confirmation (e.g., --yes flag) */
|
|
172
|
+
readonly bypassFlag?: boolean;
|
|
173
|
+
/** Number of items affected (shown in confirmation) */
|
|
174
|
+
readonly itemCount?: number;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Numeric or date range parsed from CLI input.
|
|
178
|
+
*/
|
|
179
|
+
type Range = NumericRange | DateRange;
|
|
180
|
+
/**
|
|
181
|
+
* Numeric range (e.g., "1-10").
|
|
182
|
+
*/
|
|
183
|
+
interface NumericRange {
|
|
184
|
+
readonly type: "number";
|
|
185
|
+
readonly min: number;
|
|
186
|
+
readonly max: number;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Date range (e.g., "2024-01-01..2024-12-31").
|
|
190
|
+
*/
|
|
191
|
+
interface DateRange {
|
|
192
|
+
readonly type: "date";
|
|
193
|
+
readonly start: Date;
|
|
194
|
+
readonly end: Date;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Filter expression parsed from CLI input.
|
|
198
|
+
*/
|
|
199
|
+
interface FilterExpression {
|
|
200
|
+
readonly field: string;
|
|
201
|
+
readonly value: string;
|
|
202
|
+
readonly operator?: "eq" | "ne" | "gt" | "lt" | "gte" | "lte" | "contains";
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Sort criteria parsed from CLI input.
|
|
206
|
+
*/
|
|
207
|
+
interface SortCriteria {
|
|
208
|
+
readonly field: string;
|
|
209
|
+
readonly direction: "asc" | "desc";
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Key-value pair parsed from CLI input.
|
|
213
|
+
*/
|
|
214
|
+
interface KeyValuePair {
|
|
215
|
+
readonly key: string;
|
|
216
|
+
readonly value: string;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* State for paginated command results.
|
|
220
|
+
*/
|
|
221
|
+
interface PaginationState {
|
|
222
|
+
/** Cursor for the next page */
|
|
223
|
+
readonly cursor: string;
|
|
224
|
+
/** Command that generated this state */
|
|
225
|
+
readonly command: string;
|
|
226
|
+
/** Context key for scoping pagination */
|
|
227
|
+
readonly context?: string;
|
|
228
|
+
/** Timestamp when state was created */
|
|
229
|
+
readonly timestamp: number;
|
|
230
|
+
/** Whether there are more results */
|
|
231
|
+
readonly hasMore: boolean;
|
|
232
|
+
/** Total count (if known) */
|
|
233
|
+
readonly total?: number;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Options for cursor persistence operations.
|
|
237
|
+
*/
|
|
238
|
+
interface CursorOptions {
|
|
239
|
+
/** Command name for cursor scoping */
|
|
240
|
+
readonly command: string;
|
|
241
|
+
/** Context key for additional scoping */
|
|
242
|
+
readonly context?: string;
|
|
243
|
+
/** Tool name for XDG path resolution */
|
|
244
|
+
readonly toolName: string;
|
|
245
|
+
/** Maximum age in milliseconds before a cursor is treated as expired */
|
|
246
|
+
readonly maxAgeMs?: number;
|
|
247
|
+
/** Whether there are more results (defaults to true) */
|
|
248
|
+
readonly hasMore?: boolean;
|
|
249
|
+
/** Total count of results (if known) */
|
|
250
|
+
readonly total?: number;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Output data to the console with automatic mode selection.
|
|
254
|
+
*
|
|
255
|
+
* Respects --json, --jsonl, --tree, --table flags automatically.
|
|
256
|
+
* Defaults to human-friendly output when no flags are present.
|
|
257
|
+
*
|
|
258
|
+
* @param data - The data to output
|
|
259
|
+
* @param options - Output configuration options
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* ```typescript
|
|
263
|
+
* import { output } from "@outfitter/cli";
|
|
264
|
+
*
|
|
265
|
+
* // Basic usage - mode auto-detected from flags
|
|
266
|
+
* output(results);
|
|
267
|
+
*
|
|
268
|
+
* // Force JSON mode
|
|
269
|
+
* output(results, { mode: "json" });
|
|
270
|
+
*
|
|
271
|
+
* // Pretty-print JSON
|
|
272
|
+
* output(results, { mode: "json", pretty: true });
|
|
273
|
+
*
|
|
274
|
+
* // Output to stderr
|
|
275
|
+
* output(errors, { stream: process.stderr });
|
|
276
|
+
*
|
|
277
|
+
* // Await for large outputs (recommended)
|
|
278
|
+
* await output(largeDataset, { mode: "jsonl" });
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
declare function output(data: unknown, options?: OutputOptions): Promise<void>;
|
|
282
|
+
/**
|
|
283
|
+
* Exit the process with an error message.
|
|
284
|
+
*
|
|
285
|
+
* Formats the error according to the current output mode (human or JSON)
|
|
286
|
+
* and exits with an appropriate exit code.
|
|
287
|
+
*
|
|
288
|
+
* @param error - The error to display
|
|
289
|
+
* @returns Never returns (exits the process)
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```typescript
|
|
293
|
+
* import { exitWithError } from "@outfitter/cli";
|
|
294
|
+
*
|
|
295
|
+
* try {
|
|
296
|
+
* await riskyOperation();
|
|
297
|
+
* } catch (error) {
|
|
298
|
+
* exitWithError(error instanceof Error ? error : new Error(String(error)));
|
|
299
|
+
* }
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
declare function exitWithError(error: Error, options?: OutputOptions): never;
|
|
303
|
+
/**
|
|
304
|
+
* Load persisted pagination state for a command.
|
|
305
|
+
*
|
|
306
|
+
* @param options - Cursor options specifying command and context
|
|
307
|
+
* @returns The pagination state if it exists, undefined otherwise
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* ```typescript
|
|
311
|
+
* const state = loadCursor({
|
|
312
|
+
* command: "list",
|
|
313
|
+
* toolName: "waymark",
|
|
314
|
+
* });
|
|
315
|
+
*
|
|
316
|
+
* if (state) {
|
|
317
|
+
* // Continue from last position
|
|
318
|
+
* const results = await listNotes({ cursor: state.cursor });
|
|
319
|
+
* }
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
declare function loadCursor(options: CursorOptions): PaginationState | undefined;
|
|
323
|
+
/**
|
|
324
|
+
* Save pagination state for a command.
|
|
325
|
+
*
|
|
326
|
+
* The cursor is persisted to XDG state directory, scoped by
|
|
327
|
+
* tool name, command, and optional context.
|
|
328
|
+
*
|
|
329
|
+
* @param cursor - The cursor string to persist
|
|
330
|
+
* @param options - Cursor options specifying command and context
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```typescript
|
|
334
|
+
* const results = await listNotes({ limit: 20 });
|
|
335
|
+
*
|
|
336
|
+
* if (results.hasMore) {
|
|
337
|
+
* saveCursor(results.cursor, {
|
|
338
|
+
* command: "list",
|
|
339
|
+
* toolName: "waymark",
|
|
340
|
+
* });
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
declare function saveCursor(cursor: string, options: CursorOptions): void;
|
|
345
|
+
/**
|
|
346
|
+
* Clear persisted pagination state for a command.
|
|
347
|
+
*
|
|
348
|
+
* Called when --reset flag is passed or when pagination completes.
|
|
349
|
+
*
|
|
350
|
+
* @param options - Cursor options specifying command and context
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```typescript
|
|
354
|
+
* // User passed --reset flag
|
|
355
|
+
* if (flags.reset) {
|
|
356
|
+
* clearCursor({
|
|
357
|
+
* command: "list",
|
|
358
|
+
* toolName: "waymark",
|
|
359
|
+
* });
|
|
360
|
+
* }
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
declare function clearCursor(options: CursorOptions): void;
|
|
364
|
+
import { CancelledError as CancelledError2, ValidationError as ValidationError2 } from "@outfitter/contracts";
|
|
365
|
+
import { Result as Result2 } from "better-result";
|
|
366
|
+
/**
|
|
367
|
+
* Collect IDs from various input formats.
|
|
368
|
+
*
|
|
369
|
+
* Handles space-separated, comma-separated, repeated flags, @file, and stdin.
|
|
370
|
+
*
|
|
371
|
+
* @param input - Raw input from CLI arguments
|
|
372
|
+
* @param options - Collection options
|
|
373
|
+
* @returns Array of collected IDs
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```typescript
|
|
377
|
+
* // All these produce the same result:
|
|
378
|
+
* // wm show id1 id2 id3
|
|
379
|
+
* // wm show id1,id2,id3
|
|
380
|
+
* // wm show --ids id1 --ids id2
|
|
381
|
+
* // wm show @ids.txt
|
|
382
|
+
* const ids = await collectIds(args.ids, {
|
|
383
|
+
* allowFile: true,
|
|
384
|
+
* allowStdin: true,
|
|
385
|
+
* });
|
|
386
|
+
* ```
|
|
387
|
+
*/
|
|
388
|
+
declare function collectIds(input: string | readonly string[], options?: CollectIdsOptions): Promise<string[]>;
|
|
389
|
+
/**
|
|
390
|
+
* Expand @file references to file contents.
|
|
391
|
+
*
|
|
392
|
+
* If the input starts with @, reads the file and returns its contents.
|
|
393
|
+
* Otherwise, returns the input unchanged.
|
|
394
|
+
*
|
|
395
|
+
* @param input - Raw input that may be a @file reference
|
|
396
|
+
* @param options - Expansion options
|
|
397
|
+
* @returns File contents or original input
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* ```typescript
|
|
401
|
+
* // wm create @template.md
|
|
402
|
+
* const content = await expandFileArg(args.content);
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
declare function expandFileArg(input: string, options?: ExpandFileOptions): Promise<string>;
|
|
406
|
+
/**
|
|
407
|
+
* Parse and expand glob patterns.
|
|
408
|
+
*
|
|
409
|
+
* Uses Bun.Glob with workspace constraints.
|
|
410
|
+
*
|
|
411
|
+
* @param pattern - Glob pattern to expand
|
|
412
|
+
* @param options - Glob options
|
|
413
|
+
* @returns Array of matched file paths
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```typescript
|
|
417
|
+
* // wm index "src/**\/*.ts"
|
|
418
|
+
* const files = await parseGlob(args.pattern, {
|
|
419
|
+
* cwd: workspaceRoot,
|
|
420
|
+
* ignore: ["node_modules/**"],
|
|
421
|
+
* });
|
|
422
|
+
* ```
|
|
423
|
+
*/
|
|
424
|
+
declare function parseGlob(pattern: string, options?: ParseGlobOptions): Promise<string[]>;
|
|
425
|
+
/**
|
|
426
|
+
* Parse key=value pairs from CLI input.
|
|
427
|
+
*
|
|
428
|
+
* @param input - Raw input containing key=value pairs
|
|
429
|
+
* @returns Array of parsed key-value pairs
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* ```typescript
|
|
433
|
+
* // --set key=value --set key2=value2
|
|
434
|
+
* // --set key=value,key2=value2
|
|
435
|
+
* const pairs = parseKeyValue(args.set);
|
|
436
|
+
* // => [{ key: "key", value: "value" }, { key: "key2", value: "value2" }]
|
|
437
|
+
* ```
|
|
438
|
+
*/
|
|
439
|
+
declare function parseKeyValue(input: string | readonly string[]): Result2<KeyValuePair[], InstanceType<typeof ValidationError2>>;
|
|
440
|
+
/**
|
|
441
|
+
* Parse range inputs (numeric or date).
|
|
442
|
+
*
|
|
443
|
+
* @param input - Range string (e.g., "1-10" or "2024-01-01..2024-12-31")
|
|
444
|
+
* @param type - Type of range to parse
|
|
445
|
+
* @returns Parsed range
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
* ```typescript
|
|
449
|
+
* parseRange("1-10", "number");
|
|
450
|
+
* // => Result<{ type: "number", min: 1, max: 10 }, ValidationError>
|
|
451
|
+
*
|
|
452
|
+
* parseRange("2024-01-01..2024-12-31", "date");
|
|
453
|
+
* // => Result<{ type: "date", start: Date, end: Date }, ValidationError>
|
|
454
|
+
* ```
|
|
455
|
+
*/
|
|
456
|
+
declare function parseRange(input: string, type: "number" | "date"): Result2<Range, InstanceType<typeof ValidationError2>>;
|
|
457
|
+
/**
|
|
458
|
+
* Parse filter expressions from CLI input.
|
|
459
|
+
*
|
|
460
|
+
* @param input - Filter string (e.g., "status:active,priority:high")
|
|
461
|
+
* @returns Array of parsed filter expressions
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* ```typescript
|
|
465
|
+
* parseFilter("status:active,priority:high");
|
|
466
|
+
* // => Result<[
|
|
467
|
+
* // { field: "status", value: "active" },
|
|
468
|
+
* // { field: "priority", value: "high" }
|
|
469
|
+
* // ], ValidationError>
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
472
|
+
declare function parseFilter(input: string): Result2<FilterExpression[], InstanceType<typeof ValidationError2>>;
|
|
473
|
+
/**
|
|
474
|
+
* Parse sort specification from CLI input.
|
|
475
|
+
*
|
|
476
|
+
* @param input - Sort string (e.g., "modified:desc,title:asc")
|
|
477
|
+
* @returns Array of parsed sort criteria
|
|
478
|
+
*
|
|
479
|
+
* @example
|
|
480
|
+
* ```typescript
|
|
481
|
+
* parseSortSpec("modified:desc,title:asc");
|
|
482
|
+
* // => Result<[
|
|
483
|
+
* // { field: "modified", direction: "desc" },
|
|
484
|
+
* // { field: "title", direction: "asc" }
|
|
485
|
+
* // ], ValidationError>
|
|
486
|
+
* ```
|
|
487
|
+
*/
|
|
488
|
+
declare function parseSortSpec(input: string): Result2<SortCriteria[], InstanceType<typeof ValidationError2>>;
|
|
489
|
+
/**
|
|
490
|
+
* Normalize an identifier (trim, lowercase where appropriate).
|
|
491
|
+
*
|
|
492
|
+
* @param input - Raw identifier input
|
|
493
|
+
* @param options - Normalization options
|
|
494
|
+
* @returns Normalized identifier
|
|
495
|
+
*
|
|
496
|
+
* @example
|
|
497
|
+
* ```typescript
|
|
498
|
+
* normalizeId(" MY-ID ", { lowercase: true, trim: true });
|
|
499
|
+
* // => Result<"my-id", ValidationError>
|
|
500
|
+
* ```
|
|
501
|
+
*/
|
|
502
|
+
declare function normalizeId(input: string, options?: NormalizeIdOptions): Result2<string, InstanceType<typeof ValidationError2>>;
|
|
503
|
+
/**
|
|
504
|
+
* Prompt for confirmation before destructive operations.
|
|
505
|
+
*
|
|
506
|
+
* Respects --yes flag for non-interactive mode.
|
|
507
|
+
*
|
|
508
|
+
* @param options - Confirmation options
|
|
509
|
+
* @returns Whether the user confirmed
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```typescript
|
|
513
|
+
* const confirmed = await confirmDestructive({
|
|
514
|
+
* message: "Delete 5 notes?",
|
|
515
|
+
* bypassFlag: flags.yes,
|
|
516
|
+
* itemCount: 5,
|
|
517
|
+
* });
|
|
518
|
+
*
|
|
519
|
+
* if (confirmed.isErr()) {
|
|
520
|
+
* // User cancelled
|
|
521
|
+
* process.exit(0);
|
|
522
|
+
* }
|
|
523
|
+
* ```
|
|
524
|
+
*/
|
|
525
|
+
declare function confirmDestructive(options: ConfirmDestructiveOptions): Promise<Result2<boolean, InstanceType<typeof CancelledError2>>>;
|
|
526
|
+
/**
|
|
527
|
+
* Create a new CLI instance with the given configuration.
|
|
528
|
+
*
|
|
529
|
+
* The CLI wraps Commander.js with typed helpers, output contract enforcement,
|
|
530
|
+
* and pagination state management.
|
|
531
|
+
*
|
|
532
|
+
* @param config - CLI configuration options
|
|
533
|
+
* @returns A CLI instance ready for command registration
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```typescript
|
|
537
|
+
* import { createCLI, command, output } from "@outfitter/cli";
|
|
538
|
+
*
|
|
539
|
+
* const cli = createCLI({
|
|
540
|
+
* name: "waymark",
|
|
541
|
+
* version: "1.0.0",
|
|
542
|
+
* description: "A note management CLI",
|
|
543
|
+
* });
|
|
544
|
+
*
|
|
545
|
+
* cli.register(
|
|
546
|
+
* command("list")
|
|
547
|
+
* .description("List all notes")
|
|
548
|
+
* .action(async () => {
|
|
549
|
+
* const notes = await getNotes();
|
|
550
|
+
* output(notes);
|
|
551
|
+
* })
|
|
552
|
+
* );
|
|
553
|
+
*
|
|
554
|
+
* await cli.parse();
|
|
555
|
+
* ```
|
|
556
|
+
*/
|
|
557
|
+
declare function createCLI(config: CLIConfig): CLI;
|
|
558
|
+
import { ActionRegistry, ActionSurface, AnyActionSpec, HandlerContext } from "@outfitter/contracts";
|
|
559
|
+
import { Command as Command2 } from "commander";
|
|
560
|
+
interface BuildCliCommandsOptions {
|
|
561
|
+
readonly createContext?: (input: {
|
|
562
|
+
action: AnyActionSpec;
|
|
563
|
+
args: readonly string[];
|
|
564
|
+
flags: Record<string, unknown>;
|
|
565
|
+
}) => HandlerContext;
|
|
566
|
+
readonly includeSurfaces?: readonly ActionSurface[];
|
|
567
|
+
}
|
|
568
|
+
type ActionSource = ActionRegistry | readonly AnyActionSpec[];
|
|
569
|
+
declare function buildCliCommands(source: ActionSource, options?: BuildCliCommandsOptions): Command2[];
|
|
570
|
+
/**
|
|
571
|
+
* Create a new command builder with the given name.
|
|
572
|
+
*
|
|
573
|
+
* The command builder provides a fluent API for defining CLI commands
|
|
574
|
+
* with typed flags, arguments, and actions.
|
|
575
|
+
*
|
|
576
|
+
* @param name - Command name and optional argument syntax (e.g., "list" or "get <id>")
|
|
577
|
+
* @returns A CommandBuilder instance for fluent configuration
|
|
578
|
+
*
|
|
579
|
+
* @example
|
|
580
|
+
* ```typescript
|
|
581
|
+
* import { command, output } from "@outfitter/cli";
|
|
582
|
+
*
|
|
583
|
+
* const list = command("list")
|
|
584
|
+
* .description("List all notes")
|
|
585
|
+
* .option("--limit <n>", "Max results", "20")
|
|
586
|
+
* .option("--json", "Output as JSON")
|
|
587
|
+
* .option("--next", "Continue from last position")
|
|
588
|
+
* .action(async ({ flags }) => {
|
|
589
|
+
* const results = await listNotes(flags);
|
|
590
|
+
* output(results);
|
|
591
|
+
* });
|
|
592
|
+
* ```
|
|
593
|
+
*
|
|
594
|
+
* @example
|
|
595
|
+
* ```typescript
|
|
596
|
+
* // Command with required argument
|
|
597
|
+
* const get = command("get <id>")
|
|
598
|
+
* .description("Get a note by ID")
|
|
599
|
+
* .action(async ({ args }) => {
|
|
600
|
+
* const [id] = args;
|
|
601
|
+
* const note = await getNote(id);
|
|
602
|
+
* output(note);
|
|
603
|
+
* });
|
|
604
|
+
* ```
|
|
605
|
+
*/
|
|
606
|
+
declare function command(name: string): CommandBuilder;
|
|
607
|
+
export { saveCursor, parseSortSpec, parseRange, parseKeyValue, parseGlob, parseFilter, output, normalizeId, loadCursor, expandFileArg, exitWithError, createCLI, confirmDestructive, command, collectIds, clearCursor, buildCliCommands, ValidationError, SortCriteria, Range, ParseGlobOptions, PaginationState, OutputOptions, OutputMode, NumericRange, NormalizeIdOptions, KeyValuePair, FilterExpression, ExpandFileOptions, DateRange, CursorOptions, ConfirmDestructiveOptions, CommandFlags, CommandConfig, CommandBuilder, CommandAction, CollectIdsOptions, CancelledError, CLIConfig, CLI, BuildCliCommandsOptions };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
exitWithError,
|
|
4
|
+
output
|
|
5
|
+
} from "./output.js";
|
|
6
|
+
import"./shared/@outfitter/cli-4yy82cmp.js";
|
|
7
|
+
import {
|
|
8
|
+
clearCursor,
|
|
9
|
+
loadCursor,
|
|
10
|
+
saveCursor
|
|
11
|
+
} from "./pagination.js";
|
|
12
|
+
import {
|
|
13
|
+
collectIds,
|
|
14
|
+
confirmDestructive,
|
|
15
|
+
expandFileArg,
|
|
16
|
+
normalizeId,
|
|
17
|
+
parseFilter,
|
|
18
|
+
parseGlob,
|
|
19
|
+
parseKeyValue,
|
|
20
|
+
parseRange,
|
|
21
|
+
parseSortSpec
|
|
22
|
+
} from "./input.js";
|
|
23
|
+
import {
|
|
24
|
+
createCLI
|
|
25
|
+
} from "./cli.js";
|
|
26
|
+
import {
|
|
27
|
+
buildCliCommands
|
|
28
|
+
} from "./actions.js";
|
|
29
|
+
import {
|
|
30
|
+
command
|
|
31
|
+
} from "./command.js";
|
|
32
|
+
export {
|
|
33
|
+
saveCursor,
|
|
34
|
+
parseSortSpec,
|
|
35
|
+
parseRange,
|
|
36
|
+
parseKeyValue,
|
|
37
|
+
parseGlob,
|
|
38
|
+
parseFilter,
|
|
39
|
+
output,
|
|
40
|
+
normalizeId,
|
|
41
|
+
loadCursor,
|
|
42
|
+
expandFileArg,
|
|
43
|
+
exitWithError,
|
|
44
|
+
createCLI,
|
|
45
|
+
confirmDestructive,
|
|
46
|
+
command,
|
|
47
|
+
collectIds,
|
|
48
|
+
clearCursor,
|
|
49
|
+
buildCliCommands
|
|
50
|
+
};
|