@qodalis/cli-core 2.0.0-beta.12 → 2.0.0-beta.14
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/package.json +1 -1
- package/public-api.d.mts +2154 -1352
- package/public-api.d.ts +2154 -1352
- package/public-api.js +310 -18
- package/public-api.js.map +1 -1
- package/public-api.mjs +278 -19
- package/public-api.mjs.map +1 -1
package/public-api.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ITerminalOptions, ITerminalInitOnlyOptions, Terminal, ITheme } from '@xterm/xterm';
|
|
2
|
-
import {
|
|
2
|
+
import { Observable, Subscription, Subject } from 'rxjs';
|
|
3
3
|
|
|
4
4
|
type CliProcessCommand = {
|
|
5
5
|
/**
|
|
@@ -170,559 +170,428 @@ declare enum CliIcon {
|
|
|
170
170
|
Gift = "\uD83C\uDF81"
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
name: string;
|
|
179
|
-
/** Base URL of the server, e.g. "https://api.example.com" */
|
|
180
|
-
url: string;
|
|
181
|
-
/** Whether this server is enabled. @default true */
|
|
182
|
-
enabled?: boolean;
|
|
183
|
-
/** Custom headers sent with every request (e.g. auth tokens) */
|
|
184
|
-
headers?: Record<string, string>;
|
|
185
|
-
/** Request timeout in milliseconds. @default 30000 */
|
|
186
|
-
timeout?: number;
|
|
187
|
-
};
|
|
188
|
-
/**
|
|
189
|
-
* A single output item in a server response
|
|
190
|
-
*/
|
|
191
|
-
type CliServerOutput = {
|
|
192
|
-
type: 'text';
|
|
193
|
-
value: string;
|
|
194
|
-
style?: 'success' | 'error' | 'info' | 'warning';
|
|
195
|
-
} | {
|
|
196
|
-
type: 'table';
|
|
197
|
-
headers: string[];
|
|
198
|
-
rows: string[][];
|
|
199
|
-
} | {
|
|
200
|
-
type: 'list';
|
|
201
|
-
items: string[];
|
|
202
|
-
ordered?: boolean;
|
|
203
|
-
} | {
|
|
204
|
-
type: 'json';
|
|
205
|
-
value: any;
|
|
206
|
-
} | {
|
|
207
|
-
type: 'key-value';
|
|
208
|
-
entries: {
|
|
209
|
-
key: string;
|
|
210
|
-
value: string;
|
|
211
|
-
}[];
|
|
212
|
-
};
|
|
213
|
-
/**
|
|
214
|
-
* Structured response from a server command execution
|
|
215
|
-
*/
|
|
216
|
-
type CliServerResponse = {
|
|
217
|
-
exitCode: number;
|
|
218
|
-
outputs: CliServerOutput[];
|
|
219
|
-
};
|
|
220
|
-
/**
|
|
221
|
-
* Metadata about a remote command processor, returned by GET /api/qcli/commands
|
|
222
|
-
*/
|
|
223
|
-
type CliServerCommandDescriptor = {
|
|
224
|
-
command: string;
|
|
225
|
-
description?: string;
|
|
226
|
-
version?: string;
|
|
227
|
-
parameters?: {
|
|
228
|
-
name: string;
|
|
229
|
-
aliases?: string[];
|
|
230
|
-
description: string;
|
|
231
|
-
required: boolean;
|
|
232
|
-
type: string;
|
|
233
|
-
defaultValue?: any;
|
|
234
|
-
}[];
|
|
235
|
-
processors?: CliServerCommandDescriptor[];
|
|
236
|
-
};
|
|
237
|
-
/**
|
|
238
|
-
* Server capabilities returned by GET /api/qcli/capabilities
|
|
239
|
-
*/
|
|
240
|
-
type CliServerCapabilities = {
|
|
241
|
-
/** Whether this server supports remote shell access */
|
|
242
|
-
shell: boolean;
|
|
243
|
-
/** Server operating system (e.g. "linux", "win32", "darwin") */
|
|
244
|
-
os?: string;
|
|
245
|
-
/** Path to the shell binary on the server */
|
|
246
|
-
shellPath?: string;
|
|
247
|
-
/** Server version string */
|
|
248
|
-
version?: string;
|
|
249
|
-
/** Whether this server supports SSE streaming execution */
|
|
250
|
-
streaming?: boolean;
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Represents a package source for the CLI package manager
|
|
255
|
-
*/
|
|
256
|
-
interface CliPackageSource {
|
|
173
|
+
interface CliTableOptions {
|
|
174
|
+
/** Expand columns to fill the full terminal width. Default: false */
|
|
175
|
+
fullWidth?: boolean;
|
|
176
|
+
}
|
|
177
|
+
interface ICliTerminalWriter {
|
|
257
178
|
/**
|
|
258
|
-
*
|
|
179
|
+
* Write text to the terminal
|
|
180
|
+
* @param text The text to write
|
|
259
181
|
*/
|
|
260
|
-
|
|
182
|
+
write(text: string): void;
|
|
261
183
|
/**
|
|
262
|
-
*
|
|
184
|
+
* Write text to the terminal followed by a newline
|
|
185
|
+
* @param text The text to write
|
|
263
186
|
*/
|
|
264
|
-
|
|
187
|
+
writeln(text?: string): void;
|
|
265
188
|
/**
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
* - 'file': static file server, packages are discovered by probing known paths
|
|
269
|
-
* @default 'file'
|
|
189
|
+
* Write a success message to the terminal
|
|
190
|
+
* @param message The message to write
|
|
270
191
|
*/
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Represents a log level for the CLI
|
|
275
|
-
*/
|
|
276
|
-
declare enum CliLogLevel {
|
|
277
|
-
None = 0,
|
|
278
|
-
DEBUG = 1,
|
|
279
|
-
LOG = 2,
|
|
280
|
-
INFO = 3,
|
|
281
|
-
WARN = 4,
|
|
282
|
-
ERROR = 5
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Options for the CLI
|
|
286
|
-
*/
|
|
287
|
-
type CliOptions = Record<string, any> & {
|
|
192
|
+
writeSuccess(message: string): void;
|
|
288
193
|
/**
|
|
289
|
-
*
|
|
194
|
+
* Write an info message to the terminal
|
|
195
|
+
* @param message The message to write
|
|
290
196
|
*/
|
|
291
|
-
|
|
197
|
+
writeInfo(message: string): void;
|
|
292
198
|
/**
|
|
293
|
-
*
|
|
199
|
+
* Write an error message to the terminal
|
|
200
|
+
* @param message The message to write
|
|
294
201
|
*/
|
|
295
|
-
|
|
202
|
+
writeError(message: string): void;
|
|
296
203
|
/**
|
|
297
|
-
*
|
|
298
|
-
*
|
|
204
|
+
* Write a warning message to the terminal
|
|
205
|
+
* @param message The message to write
|
|
299
206
|
*/
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Name of the primary source. Defaults to 'unpkg'.
|
|
303
|
-
*/
|
|
304
|
-
primary?: string;
|
|
305
|
-
/**
|
|
306
|
-
* Additional custom sources
|
|
307
|
-
*/
|
|
308
|
-
sources?: CliPackageSource[];
|
|
309
|
-
};
|
|
207
|
+
writeWarning(message: string): void;
|
|
310
208
|
/**
|
|
311
|
-
*
|
|
312
|
-
*
|
|
209
|
+
* Wrap text in the specified foreground color.
|
|
210
|
+
* @param text The text to wrap
|
|
211
|
+
* @param color The foreground color to apply
|
|
212
|
+
* @returns The text wrapped in ANSI color codes
|
|
313
213
|
*/
|
|
314
|
-
|
|
214
|
+
wrapInColor(text: string, color: CliForegroundColor): string;
|
|
315
215
|
/**
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
* @default false
|
|
216
|
+
* Wrap text in the specified background color.
|
|
217
|
+
* @param text The text to wrap
|
|
218
|
+
* @param color The background color to apply
|
|
219
|
+
* @returns The text wrapped in ANSI background color codes
|
|
321
220
|
*/
|
|
322
|
-
|
|
323
|
-
};
|
|
324
|
-
/**
|
|
325
|
-
* Represents a package that can be installed
|
|
326
|
-
*/
|
|
327
|
-
interface Package {
|
|
221
|
+
wrapInBackgroundColor(text: string, color: CliBackgroundColor): string;
|
|
328
222
|
/**
|
|
329
|
-
*
|
|
223
|
+
* Write a JSON object to the terminal
|
|
224
|
+
* @param json The JSON object to write
|
|
330
225
|
*/
|
|
331
|
-
|
|
226
|
+
writeJson(json: any): void;
|
|
332
227
|
/**
|
|
333
|
-
*
|
|
228
|
+
* Write content to a file (triggers a browser download)
|
|
229
|
+
* @param fileName The name of the file to download
|
|
230
|
+
* @param content The content to write to the file
|
|
334
231
|
*/
|
|
335
|
-
|
|
232
|
+
writeToFile(fileName: string, content: string): void;
|
|
336
233
|
/**
|
|
337
|
-
*
|
|
234
|
+
* Write an object array as a table to the terminal
|
|
235
|
+
* @param objects The objects to write to the table
|
|
338
236
|
*/
|
|
339
|
-
|
|
237
|
+
writeObjectsAsTable(objects: any[]): void;
|
|
340
238
|
/**
|
|
341
|
-
*
|
|
239
|
+
* Write a table to the terminal
|
|
240
|
+
* @param headers The headers of the table
|
|
241
|
+
* @param rows The rows of the table
|
|
242
|
+
* @param options Optional table rendering options
|
|
342
243
|
*/
|
|
343
|
-
|
|
244
|
+
writeTable(headers: string[], rows: string[][], options?: CliTableOptions): void;
|
|
344
245
|
/**
|
|
345
|
-
*
|
|
246
|
+
* Write a divider to the terminal
|
|
247
|
+
* @param options Optional: color, length, character
|
|
346
248
|
*/
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
type CliProcessorMetadata = Record<string, any> & {
|
|
249
|
+
writeDivider(options?: {
|
|
250
|
+
color?: CliForegroundColor;
|
|
251
|
+
length?: number;
|
|
252
|
+
char?: string;
|
|
253
|
+
}): void;
|
|
353
254
|
/**
|
|
354
|
-
*
|
|
355
|
-
*
|
|
255
|
+
* Write a list of items to the terminal with bullet, numbered, or custom prefix.
|
|
256
|
+
* @param items The list items to display
|
|
257
|
+
* @param options Optional: ordered (numbered), prefix (custom marker), color
|
|
356
258
|
*/
|
|
357
|
-
|
|
259
|
+
writeList(items: string[], options?: {
|
|
260
|
+
ordered?: boolean;
|
|
261
|
+
prefix?: string;
|
|
262
|
+
color?: CliForegroundColor;
|
|
263
|
+
}): void;
|
|
358
264
|
/**
|
|
359
|
-
*
|
|
265
|
+
* Write aligned key-value pairs to the terminal.
|
|
266
|
+
* @param entries Key-value pairs as a Record or array of tuples
|
|
267
|
+
* @param options Optional: separator string, key color
|
|
360
268
|
*/
|
|
361
|
-
|
|
269
|
+
writeKeyValue(entries: Record<string, string> | [string, string][], options?: {
|
|
270
|
+
separator?: string;
|
|
271
|
+
keyColor?: CliForegroundColor;
|
|
272
|
+
}): void;
|
|
362
273
|
/**
|
|
363
|
-
*
|
|
274
|
+
* Write items in a multi-column layout.
|
|
275
|
+
* @param items The items to arrange in columns
|
|
276
|
+
* @param options Optional: number of columns, padding between columns
|
|
364
277
|
*/
|
|
365
|
-
|
|
278
|
+
writeColumns(items: string[], options?: {
|
|
279
|
+
columns?: number;
|
|
280
|
+
padding?: number;
|
|
281
|
+
}): void;
|
|
366
282
|
/**
|
|
367
|
-
*
|
|
283
|
+
* Write a clickable hyperlink using OSC 8 escape sequences.
|
|
284
|
+
* In terminals that support OSC 8, the text is clickable. In others,
|
|
285
|
+
* it falls back to displaying "text (url)".
|
|
286
|
+
* @param text The visible link text
|
|
287
|
+
* @param url The URL to link to
|
|
368
288
|
*/
|
|
369
|
-
|
|
289
|
+
writeLink(text: string, url: string): void;
|
|
370
290
|
/**
|
|
371
|
-
*
|
|
372
|
-
*
|
|
291
|
+
* Write text inside a bordered box.
|
|
292
|
+
* Useful for callouts, notices, and highlighted information.
|
|
293
|
+
* @param content The content lines to display inside the box
|
|
294
|
+
* @param options Optional: title, border color, padding
|
|
373
295
|
*/
|
|
374
|
-
|
|
296
|
+
writeBox(content: string | string[], options?: {
|
|
297
|
+
title?: string;
|
|
298
|
+
borderColor?: CliForegroundColor;
|
|
299
|
+
padding?: number;
|
|
300
|
+
}): void;
|
|
375
301
|
/**
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* If true, the processor is hidden from the help command listing.
|
|
382
|
-
* The command still works when typed directly and `help <command>` still shows its details.
|
|
302
|
+
* Write text with a specified indentation level.
|
|
303
|
+
* Each level adds 2 spaces of indentation.
|
|
304
|
+
* @param text The text to write
|
|
305
|
+
* @param level The indentation level (default: 1)
|
|
383
306
|
*/
|
|
384
|
-
|
|
385
|
-
}
|
|
307
|
+
writeIndented(text: string, level?: number): void;
|
|
308
|
+
}
|
|
309
|
+
|
|
386
310
|
/**
|
|
387
|
-
* Represents a
|
|
311
|
+
* Represents a clipboard for the CLI
|
|
388
312
|
*/
|
|
389
|
-
|
|
313
|
+
interface ICliClipboard {
|
|
390
314
|
/**
|
|
391
|
-
*
|
|
315
|
+
* Write text to the clipboard
|
|
316
|
+
* @param text The text to write to the clipboard
|
|
317
|
+
* @returns void
|
|
392
318
|
*/
|
|
393
|
-
|
|
319
|
+
write: (text: string) => Promise<void>;
|
|
394
320
|
/**
|
|
395
|
-
*
|
|
396
|
-
* @
|
|
321
|
+
* Read text from the clipboard
|
|
322
|
+
* @returns The text read from the clipboard
|
|
397
323
|
*/
|
|
398
|
-
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Position of the CLI panel relative to the viewport edge.
|
|
403
|
-
* - `'bottom'` — anchored to the bottom (default)
|
|
404
|
-
* - `'top'` — anchored to the top
|
|
405
|
-
* - `'left'` — anchored to the left (vertical layout)
|
|
406
|
-
* - `'right'` — anchored to the right (vertical layout)
|
|
407
|
-
*/
|
|
408
|
-
type CliPanelPosition = 'bottom' | 'top' | 'left' | 'right';
|
|
324
|
+
read: () => Promise<string>;
|
|
325
|
+
}
|
|
326
|
+
|
|
409
327
|
/**
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
328
|
+
* Describes a global parameter (e.g. --help, --version) together with
|
|
329
|
+
* the handler that executes when the parameter is present.
|
|
330
|
+
*
|
|
331
|
+
* Global parameters are checked for every command before the command
|
|
332
|
+
* processor's own `processCommand` runs. If the handler returns `true`,
|
|
333
|
+
* command execution is halted (the parameter "consumed" the invocation).
|
|
414
334
|
*/
|
|
415
|
-
|
|
335
|
+
interface ICliGlobalParameterHandler {
|
|
336
|
+
/**
|
|
337
|
+
* The parameter descriptor shown in help output and used for tab-completion.
|
|
338
|
+
*/
|
|
339
|
+
parameter: ICliCommandParameterDescriptor;
|
|
340
|
+
/**
|
|
341
|
+
* Execution priority — lower values run first.
|
|
342
|
+
* @default 0
|
|
343
|
+
*/
|
|
344
|
+
priority?: number;
|
|
345
|
+
/**
|
|
346
|
+
* Evaluate and optionally handle the parameter.
|
|
347
|
+
* @returns `true` to halt command execution, `false` to continue.
|
|
348
|
+
*/
|
|
349
|
+
handle(args: Record<string, any>, processor: ICliCommandProcessor, command: CliProcessCommand, context: ICliExecutionContext): boolean | Promise<boolean>;
|
|
350
|
+
}
|
|
351
|
+
|
|
416
352
|
/**
|
|
417
|
-
*
|
|
353
|
+
* Represents a service that executes commands
|
|
418
354
|
*/
|
|
419
|
-
interface
|
|
355
|
+
interface ICliCommandExecutorService {
|
|
420
356
|
/**
|
|
421
|
-
*
|
|
422
|
-
*
|
|
357
|
+
* Display the help output for a command, including its description,
|
|
358
|
+
* sub-commands, and parameters.
|
|
359
|
+
* @param command The parsed command to show help for
|
|
360
|
+
* @param context The execution context
|
|
423
361
|
*/
|
|
424
|
-
|
|
362
|
+
showHelp(command: CliProcessCommand, context: ICliExecutionContext): Promise<void>;
|
|
425
363
|
/**
|
|
426
|
-
*
|
|
427
|
-
* @
|
|
364
|
+
* Execute a command
|
|
365
|
+
* @param command The command to execute
|
|
366
|
+
* @param context The context in which the command is executed
|
|
428
367
|
*/
|
|
429
|
-
|
|
368
|
+
executeCommand(command: string, context: ICliExecutionContext): Promise<void>;
|
|
430
369
|
/**
|
|
431
|
-
*
|
|
432
|
-
*
|
|
370
|
+
* Register a global parameter handler.
|
|
371
|
+
* Global parameters (e.g. --help, --version) are evaluated for every
|
|
372
|
+
* command before the processor's own processCommand runs.
|
|
373
|
+
* @param handler The global parameter handler to register
|
|
433
374
|
*/
|
|
434
|
-
|
|
375
|
+
registerGlobalParameter(handler: ICliGlobalParameterHandler): void;
|
|
435
376
|
/**
|
|
436
|
-
*
|
|
437
|
-
*
|
|
377
|
+
* Returns the descriptors of all registered global parameters.
|
|
378
|
+
* Used by help output and tab-completion.
|
|
438
379
|
*/
|
|
439
|
-
|
|
380
|
+
getGlobalParameters(): ICliCommandParameterDescriptor[];
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Represents a registry for command processors
|
|
385
|
+
*/
|
|
386
|
+
interface ICliCommandProcessorRegistry {
|
|
440
387
|
/**
|
|
441
|
-
*
|
|
442
|
-
* @default true
|
|
388
|
+
* The processors registered with the registry
|
|
443
389
|
*/
|
|
444
|
-
|
|
390
|
+
readonly processors: ICliCommandProcessor[];
|
|
445
391
|
/**
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
* @
|
|
392
|
+
* Find a processor for a command
|
|
393
|
+
* @param mainCommand
|
|
394
|
+
* @param chainCommands
|
|
449
395
|
*/
|
|
450
|
-
|
|
396
|
+
findProcessor(mainCommand: string, chainCommands: string[]): ICliCommandProcessor | undefined;
|
|
451
397
|
/**
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
* @
|
|
398
|
+
* Recursively searches for a processor matching the given command.
|
|
399
|
+
* @param mainCommand The main command name.
|
|
400
|
+
* @param chainCommands The remaining chain commands (if any).
|
|
401
|
+
* @param processors The list of available processors.
|
|
402
|
+
* @returns The matching processor or undefined if not found.
|
|
456
403
|
*/
|
|
457
|
-
|
|
404
|
+
findProcessorInCollection(mainCommand: string, chainCommands: string[], processors: ICliCommandProcessor[]): ICliCommandProcessor | undefined;
|
|
458
405
|
/**
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
* are derived from the xterm theme and applied as inline styles.
|
|
462
|
-
* @default false
|
|
406
|
+
* Get the root processor for a child processor
|
|
407
|
+
* @param child The child processor
|
|
463
408
|
*/
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
type MultiServices = {
|
|
409
|
+
getRootProcessor(child: ICliCommandChildProcessor): ICliCommandProcessor;
|
|
468
410
|
/**
|
|
469
|
-
*
|
|
470
|
-
*
|
|
411
|
+
* Register a processor
|
|
412
|
+
* @param processor
|
|
471
413
|
*/
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
};
|
|
480
|
-
type CliFactoryProvider = MultiServices & {
|
|
481
|
-
useFactory: Function;
|
|
482
|
-
};
|
|
483
|
-
type CliProvider = {
|
|
484
|
-
provide: any;
|
|
485
|
-
} & (CliValueProvider | CliTypeProvider | CliFactoryProvider) & Record<string, any>;
|
|
486
|
-
|
|
414
|
+
registerProcessor(processor: ICliCommandProcessor): void;
|
|
415
|
+
/**
|
|
416
|
+
* Unregister a processor
|
|
417
|
+
* @param processor
|
|
418
|
+
*/
|
|
419
|
+
unregisterProcessor(processor: ICliCommandProcessor): void;
|
|
420
|
+
}
|
|
487
421
|
/**
|
|
488
|
-
* Represents a
|
|
422
|
+
* Represents a tracked CLI process entry
|
|
489
423
|
*/
|
|
490
|
-
interface
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
/** Login name (unique) */
|
|
424
|
+
interface ICliProcessEntry {
|
|
425
|
+
pid: number;
|
|
426
|
+
/** Display name (service name for bg services, command text for commands) */
|
|
494
427
|
name: string;
|
|
495
|
-
/**
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
/** Account creation timestamp */
|
|
502
|
-
createdAt: number;
|
|
503
|
-
/** Last modification timestamp */
|
|
504
|
-
updatedAt: number;
|
|
505
|
-
/** Whether the account is locked */
|
|
506
|
-
disabled?: boolean;
|
|
428
|
+
/** Process type */
|
|
429
|
+
type: 'command' | 'daemon' | 'job' | 'service';
|
|
430
|
+
command: string;
|
|
431
|
+
startTime: number;
|
|
432
|
+
status: 'running' | 'completed' | 'failed' | 'killed';
|
|
433
|
+
exitCode?: number;
|
|
507
434
|
}
|
|
508
|
-
/**
|
|
509
|
-
|
|
510
|
-
*/
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
|
|
516
|
-
/** Random salt for this user */
|
|
517
|
-
salt: string;
|
|
518
|
-
/** Timestamp of last password change */
|
|
519
|
-
lastChanged: number;
|
|
435
|
+
/** Options for registering a process */
|
|
436
|
+
interface ICliProcessRegisterOptions {
|
|
437
|
+
/** Display name (defaults to command) */
|
|
438
|
+
name?: string;
|
|
439
|
+
/** Process type (defaults to 'command') */
|
|
440
|
+
type?: 'command' | 'daemon' | 'job' | 'service';
|
|
441
|
+
/** Custom kill handler (e.g. for background services) */
|
|
442
|
+
onKill?: () => Promise<void> | void;
|
|
520
443
|
}
|
|
521
444
|
/**
|
|
522
|
-
*
|
|
445
|
+
* Registry for tracking CLI processes
|
|
523
446
|
*/
|
|
524
|
-
interface
|
|
525
|
-
/**
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
447
|
+
interface ICliProcessRegistry {
|
|
448
|
+
/** Register a new process, returns assigned PID */
|
|
449
|
+
register(command: string, options?: ICliProcessRegisterOptions): {
|
|
450
|
+
pid: number;
|
|
451
|
+
abortController: AbortController;
|
|
452
|
+
};
|
|
453
|
+
/** Mark process as completed */
|
|
454
|
+
complete(pid: number, exitCode: number): void;
|
|
455
|
+
/** Mark process as failed */
|
|
456
|
+
fail(pid: number): void;
|
|
457
|
+
/** Kill a process by PID */
|
|
458
|
+
kill(pid: number): boolean;
|
|
459
|
+
/** List all processes (running + recent completed) */
|
|
460
|
+
list(): ICliProcessEntry[];
|
|
461
|
+
/** Get the current foreground process PID */
|
|
462
|
+
readonly currentPid: number | undefined;
|
|
533
463
|
}
|
|
534
|
-
/**
|
|
535
|
-
* Represents an active user session
|
|
536
|
-
*/
|
|
537
|
-
interface ICliUserSession {
|
|
538
|
-
/** The user associated with this session */
|
|
539
|
-
user: ICliUser;
|
|
540
|
-
/** Pre-computed display name for the prompt (set by users module) */
|
|
541
|
-
displayName?: string;
|
|
542
|
-
/** Timestamp when the session started */
|
|
543
|
-
loginTime: number;
|
|
544
|
-
/** Timestamp of last activity */
|
|
545
|
-
lastActivity: number;
|
|
546
|
-
/** Extensible data (tokens, metadata, etc.) */
|
|
547
|
-
data?: Record<string, any>;
|
|
548
|
-
}
|
|
549
|
-
/** Fields required to create a new user */
|
|
550
|
-
type CliAddUser = Omit<ICliUser, 'id' | 'createdAt' | 'updatedAt'>;
|
|
551
|
-
/** Fields that can be updated on a user */
|
|
552
|
-
type CliUpdateUser = Partial<Omit<ICliUser, 'id' | 'createdAt'>>;
|
|
553
|
-
|
|
554
|
-
/** Ownership metadata attached to files, directories, or other resources */
|
|
555
|
-
interface ICliOwnership {
|
|
556
|
-
/** User ID of the owner */
|
|
557
|
-
uid: string;
|
|
558
|
-
/** Primary group name */
|
|
559
|
-
gid: string;
|
|
560
|
-
}
|
|
561
|
-
/** Default file permissions: rw-r--r-- (644) */
|
|
562
|
-
declare const DEFAULT_FILE_PERMISSIONS = "rw-r--r--";
|
|
563
|
-
/** Default directory permissions: rwxr-xr-x (755) */
|
|
564
|
-
declare const DEFAULT_DIR_PERMISSIONS = "rwxr-xr-x";
|
|
565
|
-
|
|
566
|
-
declare const enums: {
|
|
567
|
-
CliForegroundColor: typeof CliForegroundColor;
|
|
568
|
-
CliBackgroundColor: typeof CliBackgroundColor;
|
|
569
|
-
CliIcon: typeof CliIcon;
|
|
570
|
-
CliLogLevel: typeof CliLogLevel;
|
|
571
|
-
};
|
|
572
464
|
|
|
573
|
-
interface
|
|
574
|
-
/** Expand columns to fill the full terminal width. Default: false */
|
|
575
|
-
fullWidth?: boolean;
|
|
576
|
-
}
|
|
577
|
-
interface ICliTerminalWriter {
|
|
465
|
+
interface ICliExecutionProcess {
|
|
578
466
|
/**
|
|
579
|
-
*
|
|
580
|
-
* @param text The text to write
|
|
467
|
+
* Indicates if the process has exited
|
|
581
468
|
*/
|
|
582
|
-
|
|
469
|
+
exited?: boolean;
|
|
583
470
|
/**
|
|
584
|
-
*
|
|
585
|
-
* @param text The text to write
|
|
471
|
+
* The exit code of the process
|
|
586
472
|
*/
|
|
587
|
-
|
|
473
|
+
exitCode?: number;
|
|
588
474
|
/**
|
|
589
|
-
*
|
|
590
|
-
* @param message The message to write
|
|
475
|
+
* Indicates if the process is running
|
|
591
476
|
*/
|
|
592
|
-
|
|
477
|
+
running: boolean;
|
|
593
478
|
/**
|
|
594
|
-
*
|
|
595
|
-
* @param message The message to write
|
|
479
|
+
* The data of the process
|
|
596
480
|
*/
|
|
597
|
-
|
|
481
|
+
data: any | undefined;
|
|
598
482
|
/**
|
|
599
|
-
*
|
|
600
|
-
* @param
|
|
483
|
+
* Exit the process
|
|
484
|
+
* @param code The exit code
|
|
485
|
+
* @returns void
|
|
601
486
|
*/
|
|
602
|
-
|
|
487
|
+
exit: (
|
|
603
488
|
/**
|
|
604
|
-
*
|
|
605
|
-
* @param message The message to write
|
|
489
|
+
* The exit code
|
|
606
490
|
*/
|
|
607
|
-
|
|
491
|
+
code?: number,
|
|
608
492
|
/**
|
|
609
|
-
*
|
|
610
|
-
* @param text The text to wrap
|
|
611
|
-
* @param color The foreground color to apply
|
|
612
|
-
* @returns The text wrapped in ANSI color codes
|
|
493
|
+
* Options for exiting the process
|
|
613
494
|
*/
|
|
614
|
-
|
|
495
|
+
options?: {
|
|
496
|
+
/**
|
|
497
|
+
* Indicates if the exit should be silent, i.e. not throw an error
|
|
498
|
+
*/
|
|
499
|
+
silent?: boolean;
|
|
500
|
+
}) => void;
|
|
615
501
|
/**
|
|
616
|
-
*
|
|
617
|
-
* @param
|
|
618
|
-
* @param color The background color to apply
|
|
619
|
-
* @returns The text wrapped in ANSI background color codes
|
|
502
|
+
* Output data from the process
|
|
503
|
+
* @param data The data to output
|
|
620
504
|
*/
|
|
621
|
-
|
|
505
|
+
output(data: any): void;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Represents a key-value store for the CLI
|
|
510
|
+
*/
|
|
511
|
+
interface ICliKeyValueStore {
|
|
622
512
|
/**
|
|
623
|
-
*
|
|
624
|
-
* @param
|
|
513
|
+
* Retrieves a value by key.
|
|
514
|
+
* @param key - The key to retrieve the value for.
|
|
515
|
+
* @returns A promise resolving to the value or undefined if not found.
|
|
625
516
|
*/
|
|
626
|
-
|
|
517
|
+
get<T = any>(key: string): Promise<T | undefined>;
|
|
627
518
|
/**
|
|
628
|
-
*
|
|
629
|
-
* @param
|
|
630
|
-
* @param
|
|
519
|
+
* Sets a key-value pair in the store.
|
|
520
|
+
* @param key - The key to set.
|
|
521
|
+
* @param value - The value to store.
|
|
522
|
+
* @returns A promise resolving when the value is stored.
|
|
631
523
|
*/
|
|
632
|
-
|
|
524
|
+
set(key: string, value: any): Promise<void>;
|
|
633
525
|
/**
|
|
634
|
-
*
|
|
635
|
-
* @param
|
|
526
|
+
* Removes a key-value pair by key.
|
|
527
|
+
* @param key - The key to remove.
|
|
528
|
+
* @returns A promise resolving when the key is removed.
|
|
636
529
|
*/
|
|
637
|
-
|
|
530
|
+
remove(key: string): Promise<void>;
|
|
638
531
|
/**
|
|
639
|
-
*
|
|
640
|
-
* @
|
|
641
|
-
* @param rows The rows of the table
|
|
642
|
-
* @param options Optional table rendering options
|
|
532
|
+
* Clears all key-value pairs from the store.
|
|
533
|
+
* @returns A promise resolving when the store is cleared.
|
|
643
534
|
*/
|
|
644
|
-
|
|
535
|
+
clear(): Promise<void>;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Reactive state store scoped to a command processor or module.
|
|
539
|
+
*
|
|
540
|
+
* State is a plain object (`Record<string, any>`). Updates are shallow-merged
|
|
541
|
+
* (top-level keys are replaced, nested objects are not deep-merged).
|
|
542
|
+
* `getState()` returns a snapshot — mutating the returned object has no effect;
|
|
543
|
+
* always use `updateState()` to change state.
|
|
544
|
+
*/
|
|
545
|
+
interface ICliStateStore {
|
|
645
546
|
/**
|
|
646
|
-
*
|
|
647
|
-
* @
|
|
547
|
+
* Get a snapshot of the current state.
|
|
548
|
+
* @returns A shallow copy of the state object
|
|
648
549
|
*/
|
|
649
|
-
|
|
650
|
-
color?: CliForegroundColor;
|
|
651
|
-
length?: number;
|
|
652
|
-
char?: string;
|
|
653
|
-
}): void;
|
|
550
|
+
getState<T extends CliState = CliState>(): T;
|
|
654
551
|
/**
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
*
|
|
552
|
+
* Shallow-merge new values into the current state.
|
|
553
|
+
* Only the provided keys are updated; other keys are preserved.
|
|
554
|
+
* Triggers subscribers and persists if a storage backend is configured.
|
|
555
|
+
* @param newState Partial state to merge with the current state
|
|
658
556
|
*/
|
|
659
|
-
|
|
660
|
-
ordered?: boolean;
|
|
661
|
-
prefix?: string;
|
|
662
|
-
color?: CliForegroundColor;
|
|
663
|
-
}): void;
|
|
557
|
+
updateState(newState: Partial<CliState>): void;
|
|
664
558
|
/**
|
|
665
|
-
*
|
|
666
|
-
* @param
|
|
667
|
-
* @
|
|
559
|
+
* Select a specific property or computed value from the state.
|
|
560
|
+
* @param selector A function to project a slice of the state.
|
|
561
|
+
* @returns Observable of the selected value.
|
|
668
562
|
*/
|
|
669
|
-
|
|
670
|
-
separator?: string;
|
|
671
|
-
keyColor?: CliForegroundColor;
|
|
672
|
-
}): void;
|
|
563
|
+
select<K>(selector: (state: CliState) => K): Observable<K>;
|
|
673
564
|
/**
|
|
674
|
-
*
|
|
675
|
-
* @param
|
|
676
|
-
* @
|
|
565
|
+
* Subscribe to state changes.
|
|
566
|
+
* @param callback Callback function to handle state changes.
|
|
567
|
+
* @returns Subscription object to manage the subscription.
|
|
677
568
|
*/
|
|
678
|
-
|
|
679
|
-
columns?: number;
|
|
680
|
-
padding?: number;
|
|
681
|
-
}): void;
|
|
569
|
+
subscribe(callback: (state: CliState) => void): Subscription;
|
|
682
570
|
/**
|
|
683
|
-
*
|
|
684
|
-
* In terminals that support OSC 8, the text is clickable. In others,
|
|
685
|
-
* it falls back to displaying "text (url)".
|
|
686
|
-
* @param text The visible link text
|
|
687
|
-
* @param url The URL to link to
|
|
571
|
+
* Reset the state to its initial value.
|
|
688
572
|
*/
|
|
689
|
-
|
|
573
|
+
reset(): void;
|
|
690
574
|
/**
|
|
691
|
-
*
|
|
692
|
-
* Useful for callouts, notices, and highlighted information.
|
|
693
|
-
* @param content The content lines to display inside the box
|
|
694
|
-
* @param options Optional: title, border color, padding
|
|
575
|
+
* Persist the state to storage.
|
|
695
576
|
*/
|
|
696
|
-
|
|
697
|
-
title?: string;
|
|
698
|
-
borderColor?: CliForegroundColor;
|
|
699
|
-
padding?: number;
|
|
700
|
-
}): void;
|
|
577
|
+
persist(): Promise<void>;
|
|
701
578
|
/**
|
|
702
|
-
*
|
|
703
|
-
* Each level adds 2 spaces of indentation.
|
|
704
|
-
* @param text The text to write
|
|
705
|
-
* @param level The indentation level (default: 1)
|
|
579
|
+
* Initialize the state from storage.
|
|
706
580
|
*/
|
|
707
|
-
|
|
581
|
+
initialize(): Promise<void>;
|
|
708
582
|
}
|
|
709
583
|
|
|
710
|
-
/**
|
|
711
|
-
|
|
712
|
-
*/
|
|
713
|
-
|
|
714
|
-
/**
|
|
715
|
-
|
|
716
|
-
* @param text The text to write to the clipboard
|
|
717
|
-
* @returns void
|
|
718
|
-
*/
|
|
719
|
-
write: (text: string) => Promise<void>;
|
|
720
|
-
/**
|
|
721
|
-
* Read text from the clipboard
|
|
722
|
-
* @returns The text read from the clipboard
|
|
723
|
-
*/
|
|
724
|
-
read: () => Promise<string>;
|
|
584
|
+
/** Ownership metadata attached to files, directories, or other resources */
|
|
585
|
+
interface ICliOwnership {
|
|
586
|
+
/** User ID of the owner */
|
|
587
|
+
uid: string;
|
|
588
|
+
/** Primary group name */
|
|
589
|
+
gid: string;
|
|
725
590
|
}
|
|
591
|
+
/** Default file permissions: rw-r--r-- (644) */
|
|
592
|
+
declare const DEFAULT_FILE_PERMISSIONS = "rw-r--r--";
|
|
593
|
+
/** Default directory permissions: rwxr-xr-x (755) */
|
|
594
|
+
declare const DEFAULT_DIR_PERMISSIONS = "rwxr-xr-x";
|
|
726
595
|
|
|
727
596
|
/**
|
|
728
597
|
* Token for the CLI user session service.
|
|
@@ -764,37 +633,88 @@ declare const ICliPermissionService_TOKEN = "cli-permission-service";
|
|
|
764
633
|
* Token for the file picker provider.
|
|
765
634
|
*/
|
|
766
635
|
declare const ICliFilePickerProvider_TOKEN = "cli-file-picker-provider";
|
|
767
|
-
|
|
768
636
|
/**
|
|
769
|
-
*
|
|
637
|
+
* Token for the HTTP client service.
|
|
770
638
|
*/
|
|
771
|
-
|
|
772
|
-
/** Allow selecting multiple files. Default: false. */
|
|
773
|
-
multiple?: boolean;
|
|
774
|
-
/**
|
|
775
|
-
* File type filter. Accepts MIME types (e.g. 'image/*') or extensions
|
|
776
|
-
* (e.g. '.json,.txt'). Maps to the HTML accept attribute in browsers
|
|
777
|
-
* and file filter in Electron.
|
|
778
|
-
*/
|
|
779
|
-
accept?: string;
|
|
780
|
-
/**
|
|
781
|
-
* When true, pick a directory instead of files. Default: false.
|
|
782
|
-
* Cannot be combined with `multiple` — if both are set, `directory` takes precedence
|
|
783
|
-
* and a single directory is returned.
|
|
784
|
-
*/
|
|
785
|
-
directory?: boolean;
|
|
786
|
-
/**
|
|
787
|
-
* How to read file content. Default: 'text'.
|
|
788
|
-
* - 'text': Read as UTF-8 string (suitable for text files)
|
|
789
|
-
* - 'arraybuffer': Read as ArrayBuffer (suitable for binary files like images)
|
|
790
|
-
*/
|
|
791
|
-
readAs?: 'text' | 'arraybuffer';
|
|
792
|
-
}
|
|
639
|
+
declare const ICliHttpClient_TOKEN = "cli-http-client";
|
|
793
640
|
/**
|
|
794
|
-
*
|
|
641
|
+
* Token for the user event service (lifecycle events).
|
|
795
642
|
*/
|
|
796
|
-
|
|
797
|
-
|
|
643
|
+
declare const ICliUserEventService_TOKEN = "cli-user-event-service";
|
|
644
|
+
/**
|
|
645
|
+
* Token for the audit service (persistent event logging).
|
|
646
|
+
*/
|
|
647
|
+
declare const ICliAuditService_TOKEN = "cli-audit-service";
|
|
648
|
+
/**
|
|
649
|
+
* Token for the authorization service ({@link ICliAuthorizationService}).
|
|
650
|
+
* Provided by an auth module (e.g. `@qodalis/cli-users`); absent otherwise.
|
|
651
|
+
*/
|
|
652
|
+
declare const ICliAuthorizationService_TOKEN = "cli-authorization-service";
|
|
653
|
+
/**
|
|
654
|
+
* Token for the permission registry ({@link ICliPermissionRegistry}).
|
|
655
|
+
* Always provided by the CLI engine.
|
|
656
|
+
*/
|
|
657
|
+
declare const ICliPermissionRegistry_TOKEN = "cli-permission-registry";
|
|
658
|
+
/**
|
|
659
|
+
* Token for the sessions service ({@link ICliSessionsService}).
|
|
660
|
+
*/
|
|
661
|
+
declare const ICliSessionsService_TOKEN = "cli-sessions-service";
|
|
662
|
+
/**
|
|
663
|
+
* Token for the persistent key-value store used by modules (setup state, etc.).
|
|
664
|
+
*/
|
|
665
|
+
declare const ICliKeyValueStore_TOKEN = "cli-key-value-store";
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Abstract permission service for checking rwx permissions on resources.
|
|
669
|
+
* The default implementation lives in @qodalis/cli-users; consumers can
|
|
670
|
+
* replace it via the DI container.
|
|
671
|
+
*/
|
|
672
|
+
interface ICliPermissionService {
|
|
673
|
+
/**
|
|
674
|
+
* Check whether a user may perform an action on a resource.
|
|
675
|
+
* @param user The acting user.
|
|
676
|
+
* @param action The requested operation.
|
|
677
|
+
* @param ownership Owner/group of the resource.
|
|
678
|
+
* @param permissions Permission string (e.g. "rwxr-xr-x").
|
|
679
|
+
* @returns true if allowed.
|
|
680
|
+
*/
|
|
681
|
+
check(user: ICliUser, action: 'read' | 'write' | 'execute', ownership: ICliOwnership, permissions: string): boolean;
|
|
682
|
+
/** Parse octal (e.g. "755") to a permission string (e.g. "rwxr-xr-x"). */
|
|
683
|
+
parseOctal(octal: string): string;
|
|
684
|
+
/** Convert a permission string (e.g. "rwxr-xr-x") to octal (e.g. "755"). */
|
|
685
|
+
toOctal(permissions: string): string;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Options for readFile file picker.
|
|
690
|
+
*/
|
|
691
|
+
interface CliFilePickerOptions {
|
|
692
|
+
/** Allow selecting multiple files. Default: false. */
|
|
693
|
+
multiple?: boolean;
|
|
694
|
+
/**
|
|
695
|
+
* File type filter. Accepts MIME types (e.g. 'image/*') or extensions
|
|
696
|
+
* (e.g. '.json,.txt'). Maps to the HTML accept attribute in browsers
|
|
697
|
+
* and file filter in Electron.
|
|
698
|
+
*/
|
|
699
|
+
accept?: string;
|
|
700
|
+
/**
|
|
701
|
+
* When true, pick a directory instead of files. Default: false.
|
|
702
|
+
* Cannot be combined with `multiple` — if both are set, `directory` takes precedence
|
|
703
|
+
* and a single directory is returned.
|
|
704
|
+
*/
|
|
705
|
+
directory?: boolean;
|
|
706
|
+
/**
|
|
707
|
+
* How to read file content. Default: 'text'.
|
|
708
|
+
* - 'text': Read as UTF-8 string (suitable for text files)
|
|
709
|
+
* - 'arraybuffer': Read as ArrayBuffer (suitable for binary files like images)
|
|
710
|
+
*/
|
|
711
|
+
readAs?: 'text' | 'arraybuffer';
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Result returned by readFile for each selected file.
|
|
715
|
+
*/
|
|
716
|
+
interface CliFileResult {
|
|
717
|
+
/** File name without path (e.g. 'config.json') */
|
|
798
718
|
name: string;
|
|
799
719
|
/** Full file path. Available in Electron, undefined in browser. */
|
|
800
720
|
path?: string;
|
|
@@ -989,69 +909,523 @@ interface ICliInputReader {
|
|
|
989
909
|
}
|
|
990
910
|
|
|
991
911
|
/**
|
|
992
|
-
*
|
|
993
|
-
* - `'daemon'` — Long-running service whose `onStart` blocks until the abort signal
|
|
994
|
-
* fires. Suitable for event loops, polling, or WebSocket connections. Can be
|
|
995
|
-
* stopped and restarted.
|
|
996
|
-
* - `'job'` — Run-to-completion task whose `onStart` resolves when the work is done.
|
|
997
|
-
* Automatically transitions to `'done'` status on success. Cannot be restarted.
|
|
912
|
+
* Context passed to completion providers describing the current input state.
|
|
998
913
|
*/
|
|
999
|
-
|
|
914
|
+
interface ICliCompletionContext {
|
|
915
|
+
/** Full current line text */
|
|
916
|
+
input: string;
|
|
917
|
+
/** Cursor position in the line */
|
|
918
|
+
cursor: number;
|
|
919
|
+
/** The token (word) being completed at the cursor position */
|
|
920
|
+
token: string;
|
|
921
|
+
/** Start index of the token in the input string */
|
|
922
|
+
tokenStart: number;
|
|
923
|
+
/** Index of the token among all tokens (0 = command, 1+ = arguments) */
|
|
924
|
+
tokenIndex: number;
|
|
925
|
+
/** All tokens parsed from the input */
|
|
926
|
+
tokens: string[];
|
|
927
|
+
}
|
|
1000
928
|
/**
|
|
1001
|
-
*
|
|
929
|
+
* Provides tab-completion candidates for CLI input.
|
|
930
|
+
* Plugins can register providers to extend completion (e.g. file paths, custom values).
|
|
1002
931
|
*/
|
|
1003
|
-
|
|
932
|
+
interface ICliCompletionProvider {
|
|
933
|
+
/**
|
|
934
|
+
* Priority order. Lower values are checked first.
|
|
935
|
+
* Built-in defaults: 100 (commands), 200 (parameters).
|
|
936
|
+
* Plugins should use lower values (e.g. 50) to take precedence for specific commands.
|
|
937
|
+
*/
|
|
938
|
+
priority: number;
|
|
939
|
+
/**
|
|
940
|
+
* Return completion candidates for the current input context.
|
|
941
|
+
* Return an empty array if this provider does not apply.
|
|
942
|
+
*/
|
|
943
|
+
getCompletions(context: ICliCompletionContext): string[] | Promise<string[]>;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
interface ICliProgressBar {
|
|
947
|
+
/**
|
|
948
|
+
* Indicates if the progress bar is running
|
|
949
|
+
*/
|
|
950
|
+
isRunning: boolean;
|
|
951
|
+
/**
|
|
952
|
+
* Show the progress bar
|
|
953
|
+
*/
|
|
954
|
+
show: (text?: string) => void;
|
|
955
|
+
/**
|
|
956
|
+
* Hide the progress bar
|
|
957
|
+
*/
|
|
958
|
+
hide: () => void;
|
|
959
|
+
}
|
|
1004
960
|
/**
|
|
1005
|
-
*
|
|
961
|
+
* Represents a spinner for the CLI
|
|
1006
962
|
*/
|
|
1007
|
-
|
|
963
|
+
interface ICliSpinner extends ICliProgressBar {
|
|
964
|
+
/**
|
|
965
|
+
* Set the text of the spinner
|
|
966
|
+
* @param text The text to set
|
|
967
|
+
*/
|
|
968
|
+
setText: (text: string) => void;
|
|
969
|
+
}
|
|
970
|
+
type CliPercentageProgressBarUpdateValueOptions = {
|
|
971
|
+
/**
|
|
972
|
+
* The type of update to perform
|
|
973
|
+
* @default 'replace'
|
|
974
|
+
*/
|
|
975
|
+
type?: 'replace' | 'increment';
|
|
976
|
+
};
|
|
1008
977
|
/**
|
|
1009
|
-
*
|
|
1010
|
-
* Services control terminal notification visibility by setting `data.notify: true`.
|
|
978
|
+
* Represents a progress bar for the CLI
|
|
1011
979
|
*/
|
|
1012
|
-
interface
|
|
1013
|
-
/**
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
/**
|
|
1020
|
-
|
|
980
|
+
interface ICliPercentageProgressBar extends ICliProgressBar {
|
|
981
|
+
/**
|
|
982
|
+
* Update the progress of the progress bar.
|
|
983
|
+
* @param progress The progress value (0–100). Values outside this range are clamped.
|
|
984
|
+
* @param options Optional: update type ('replace' or 'increment')
|
|
985
|
+
*/
|
|
986
|
+
update: (progress: number, options?: CliPercentageProgressBarUpdateValueOptions) => void;
|
|
987
|
+
/**
|
|
988
|
+
* Complete the progress bar
|
|
989
|
+
* @returns void
|
|
990
|
+
*/
|
|
991
|
+
complete: () => void;
|
|
992
|
+
/**
|
|
993
|
+
* Set the text of the spinner
|
|
994
|
+
* @param text The text to set
|
|
995
|
+
*/
|
|
996
|
+
setText: (text: string) => void;
|
|
997
|
+
}
|
|
998
|
+
type CliTextAnimatorOptions = {
|
|
999
|
+
/**
|
|
1000
|
+
* The speed of the animation
|
|
1001
|
+
* @default 100
|
|
1002
|
+
*/
|
|
1003
|
+
speed?: number;
|
|
1004
|
+
/**
|
|
1005
|
+
* The text will be removed after typing
|
|
1006
|
+
*/
|
|
1007
|
+
removeAfterTyping?: boolean;
|
|
1008
|
+
};
|
|
1009
|
+
interface ICliTextAnimator extends ICliProgressBar {
|
|
1010
|
+
/**
|
|
1011
|
+
* Show animated text in a typing and erasing effect.
|
|
1012
|
+
* @param text The text to animate
|
|
1013
|
+
* @param options Optional: speed (ms per character), removeAfterTyping
|
|
1014
|
+
* @returns A promise that resolves when the animation completes
|
|
1015
|
+
*/
|
|
1016
|
+
showText: (text: string, options?: CliTextAnimatorOptions) => Promise<void>;
|
|
1021
1017
|
}
|
|
1018
|
+
|
|
1022
1019
|
/**
|
|
1023
|
-
*
|
|
1024
|
-
|
|
1025
|
-
|
|
1020
|
+
* Result of a guard check.
|
|
1021
|
+
*
|
|
1022
|
+
* - `true` or `undefined`: allow the command.
|
|
1023
|
+
* - `false`: block it with the generic message `<command>: permission denied`.
|
|
1024
|
+
* - a non-empty `string`: block it and print this message.
|
|
1025
|
+
* - `{ allowed, message }`: explicit form; `message` is used when `allowed` is false.
|
|
1026
|
+
*/
|
|
1027
|
+
type CliCommandGuardResult = boolean | string | void | {
|
|
1028
|
+
allowed: boolean;
|
|
1029
|
+
message?: string;
|
|
1030
|
+
};
|
|
1026
1031
|
/**
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1032
|
+
* A global command guard: a check that runs before **every** command, across
|
|
1033
|
+
* all processors and modules, and can block it.
|
|
1034
|
+
*
|
|
1035
|
+
* Use guards for cross-cutting policies such as authentication, permission
|
|
1036
|
+
* checks, feature flags, maintenance windows or rate limiting, instead of
|
|
1037
|
+
* repeating the check inside each processor.
|
|
1038
|
+
*
|
|
1039
|
+
* ## When guards run
|
|
1040
|
+
*
|
|
1041
|
+
* For each command the executor:
|
|
1042
|
+
* 1. parses the input and resolves the processor (and sub-processor);
|
|
1043
|
+
* 2. handles global parameters such as `--help` (help is never guarded);
|
|
1044
|
+
* 3. extracts the positional value into `command.value`;
|
|
1045
|
+
* 4. **runs the guards**;
|
|
1046
|
+
* 5. validates required values/parameters, runs processor hooks and finally
|
|
1047
|
+
* calls `processCommand`.
|
|
1048
|
+
*
|
|
1049
|
+
* Guards run in ascending `priority` (default `0`). For each guard the executor
|
|
1050
|
+
* calls `appliesTo` (if defined) and skips the guard when it returns `false`;
|
|
1051
|
+
* otherwise it awaits `canActivate`. The **first** guard that blocks stops the
|
|
1052
|
+
* chain: its message is written as an error and the command exits with code
|
|
1053
|
+
* `-1`. A guard that throws (in `appliesTo` or `canActivate`) also blocks the
|
|
1054
|
+
* command, so a broken guard fails closed.
|
|
1055
|
+
*
|
|
1056
|
+
* ## Access to the context
|
|
1057
|
+
*
|
|
1058
|
+
* Both `appliesTo` and `canActivate` receive the {@link ICliExecutionContext}
|
|
1059
|
+
* of the command about to run, so a guard can:
|
|
1060
|
+
* - resolve services with `context.services.get(...)` / `getRequired(...)`
|
|
1061
|
+
* (e.g. a policy, feature-flag or permission service registered by any
|
|
1062
|
+
* module) to decide **what** should be guarded and **whether** it may run;
|
|
1063
|
+
* - inspect `context.userSession` for the signed-in user and their groups;
|
|
1064
|
+
* - read the processor's `metadata` (for example `requireAuth` or
|
|
1065
|
+
* `requiredGroups`) and the parsed `command` (`command.value`, `command.args`);
|
|
1066
|
+
* - prompt the user via `context.reader` (e.g. a confirmation guard).
|
|
1067
|
+
*
|
|
1068
|
+
* Guards should not write to the terminal to report a denial; return a message
|
|
1069
|
+
* instead so the executor prints it consistently.
|
|
1070
|
+
*
|
|
1071
|
+
* ## Registering guards
|
|
1072
|
+
*
|
|
1073
|
+
* The preferred way is the module's `guards` array; the boot sequence
|
|
1074
|
+
* registers each entry as a multi-provider under {@link ICliCommandGuard_TOKEN}.
|
|
1075
|
+
* Several modules can contribute guards; all of them run.
|
|
1076
|
+
*
|
|
1077
|
+
* ```ts
|
|
1078
|
+
* const billingModule: ICliModule = {
|
|
1079
|
+
* apiVersion: 2,
|
|
1080
|
+
* name: 'billing',
|
|
1081
|
+
* processors: [new InvoiceProcessor()],
|
|
1082
|
+
* guards: [billingGuard],
|
|
1083
|
+
* };
|
|
1084
|
+
* ```
|
|
1085
|
+
*
|
|
1086
|
+
* Guards can also be added at runtime (e.g. from `onInit`):
|
|
1087
|
+
*
|
|
1088
|
+
* ```ts
|
|
1089
|
+
* context.services.set({ provide: ICliCommandGuard_TOKEN, useValue: myGuard, multi: true });
|
|
1090
|
+
* ```
|
|
1091
|
+
*
|
|
1092
|
+
* ## Example: policy resolved from a service
|
|
1093
|
+
*
|
|
1094
|
+
* ```ts
|
|
1095
|
+
* const featureFlagGuard: ICliCommandGuard = {
|
|
1096
|
+
* name: 'feature-flags',
|
|
1097
|
+
* // Only guard commands that are behind a flag; the flag list comes from a service
|
|
1098
|
+
* appliesTo: (processor, _command, context) =>
|
|
1099
|
+
* context.services.get<FeatureFlags>(FeatureFlags_TOKEN)?.isFlagged(processor.command) ?? false,
|
|
1100
|
+
* canActivate: async (_command, processor, context) => {
|
|
1101
|
+
* const flags = context.services.getRequired<FeatureFlags>(FeatureFlags_TOKEN);
|
|
1102
|
+
* return (await flags.isEnabled(processor.command, context.userSession?.user))
|
|
1103
|
+
* ? true
|
|
1104
|
+
* : `${processor.command}: not available for your account`;
|
|
1105
|
+
* },
|
|
1106
|
+
* };
|
|
1107
|
+
* ```
|
|
1108
|
+
*
|
|
1109
|
+
* ## Without a guard-providing module
|
|
1110
|
+
*
|
|
1111
|
+
* Guards are opt-in. When no guard is registered every command runs as before.
|
|
1112
|
+
* The engine registers three built-in guards that enforce the processor access
|
|
1113
|
+
* metadata (`requireAuth`, `requiredGroups`, `requiredPermissions`); they stay
|
|
1114
|
+
* inactive until an auth module (e.g. `@qodalis/cli-users`) registers an
|
|
1115
|
+
* `ICliAuthorizationService`, so without one that metadata is informational.
|
|
1116
|
+
*/
|
|
1117
|
+
interface ICliCommandGuard {
|
|
1118
|
+
/** Unique name, shown in diagnostics when the guard throws. */
|
|
1119
|
+
name: string;
|
|
1120
|
+
/** Execution order; lower runs first. Defaults to `0`. */
|
|
1121
|
+
priority?: number;
|
|
1122
|
+
/**
|
|
1123
|
+
* Optional filter deciding whether this guard is relevant for the command.
|
|
1124
|
+
* Return `false` to skip the guard. When omitted the guard applies to
|
|
1125
|
+
* every command. May be async, and may use `context` to resolve services.
|
|
1126
|
+
*/
|
|
1127
|
+
appliesTo?(processor: ICliCommandProcessor, command: CliProcessCommand, context: ICliExecutionContext): boolean | Promise<boolean>;
|
|
1128
|
+
/**
|
|
1129
|
+
* Decide whether the command may run. See {@link CliCommandGuardResult}
|
|
1130
|
+
* for the accepted return values.
|
|
1131
|
+
*/
|
|
1132
|
+
canActivate(command: CliProcessCommand, processor: ICliCommandProcessor, context: ICliExecutionContext): CliCommandGuardResult | Promise<CliCommandGuardResult>;
|
|
1133
|
+
}
|
|
1134
|
+
/** DI token for {@link ICliCommandGuard}; register guards as multi-providers. */
|
|
1135
|
+
declare const ICliCommandGuard_TOKEN = "cli-command-guard";
|
|
1136
|
+
|
|
1137
|
+
/**
|
|
1138
|
+
* A permission an extension uses, declared so tools (`perms --list`,
|
|
1139
|
+
* `groupmod --grant` completion, docs) can show it. Declaring is optional:
|
|
1140
|
+
* any `resource:action` string can be granted and checked.
|
|
1030
1141
|
*/
|
|
1031
|
-
|
|
1142
|
+
interface CliPermissionDefinition {
|
|
1143
|
+
/** Permission string, `resource:action` (e.g. `files:chown`). */
|
|
1144
|
+
name: string;
|
|
1145
|
+
/** Human readable description. */
|
|
1146
|
+
description?: string;
|
|
1147
|
+
/** Module that declared it (filled in at registration). */
|
|
1148
|
+
module?: string;
|
|
1149
|
+
}
|
|
1150
|
+
/** Registry of permissions declared by modules (`ICliModule.permissions`). */
|
|
1151
|
+
interface ICliPermissionRegistry {
|
|
1152
|
+
register(definitions: CliPermissionDefinition[], module?: string): void;
|
|
1153
|
+
list(): CliPermissionDefinition[];
|
|
1154
|
+
get(name: string): CliPermissionDefinition | undefined;
|
|
1155
|
+
}
|
|
1156
|
+
/** The identity checks are made against. */
|
|
1157
|
+
interface ICliPrincipal {
|
|
1158
|
+
/** User id */
|
|
1159
|
+
id: string;
|
|
1160
|
+
/** Login name (used as file owner) */
|
|
1161
|
+
name: string;
|
|
1162
|
+
/** Group (role) names */
|
|
1163
|
+
groups: string[];
|
|
1164
|
+
/** Effective permissions (union of the groups' permissions) */
|
|
1165
|
+
permissions: string[];
|
|
1166
|
+
}
|
|
1167
|
+
/** rwx-style protected resource (files, directories, or anything an extension owns). */
|
|
1168
|
+
interface ICliProtectedResource {
|
|
1169
|
+
ownership?: ICliOwnership;
|
|
1170
|
+
/** 9-char mode string, e.g. `rwxr-x---` */
|
|
1171
|
+
permissions?: string;
|
|
1172
|
+
}
|
|
1173
|
+
type CliAccessAction = 'read' | 'write' | 'execute';
|
|
1032
1174
|
/**
|
|
1033
|
-
*
|
|
1175
|
+
* Authorization service. Provided by an auth module (the users module provides
|
|
1176
|
+
* one in local and in server mode). Extensions should use the helpers
|
|
1177
|
+
* {@link cliAuthorize} / {@link cliCanAccess}, which allow everything when no
|
|
1178
|
+
* authorization service is registered.
|
|
1034
1179
|
*/
|
|
1035
|
-
interface
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1180
|
+
interface ICliAuthorizationService {
|
|
1181
|
+
/** The signed-in principal, or undefined when nobody is signed in. */
|
|
1182
|
+
getPrincipal(): ICliPrincipal | undefined;
|
|
1183
|
+
/** Does the current principal hold `permission` (wildcards honoured)? */
|
|
1184
|
+
can(permission: string): boolean;
|
|
1185
|
+
/**
|
|
1186
|
+
* rwx check on a resource for the current principal (owner / group / other).
|
|
1187
|
+
* Principals holding `*` or any of `bypassPermissions` are always allowed.
|
|
1188
|
+
* Resources without a mode or ownership are allowed.
|
|
1189
|
+
*/
|
|
1190
|
+
canAccess(resource: ICliProtectedResource, action: CliAccessAction, bypassPermissions?: string[]): boolean;
|
|
1039
1191
|
}
|
|
1192
|
+
/** Thrown when an operation is not permitted. The message is user facing. */
|
|
1193
|
+
declare class CliAccessDeniedError extends Error {
|
|
1194
|
+
readonly code = "EACCES";
|
|
1195
|
+
constructor(message?: string);
|
|
1196
|
+
}
|
|
1197
|
+
/** True for {@link CliAccessDeniedError} (also across bundle copies). */
|
|
1198
|
+
declare function isCliAccessDeniedError(error: unknown): error is CliAccessDeniedError;
|
|
1040
1199
|
/**
|
|
1041
|
-
*
|
|
1042
|
-
*
|
|
1043
|
-
* and scoped timers (not shared with the full-screen timer set).
|
|
1200
|
+
* Check a permission for the current principal. Returns `true` when no
|
|
1201
|
+
* authorization service is registered (no auth module loaded).
|
|
1044
1202
|
*/
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1203
|
+
declare function cliAuthorize(context: Pick<ICliExecutionContext, 'services'>, permission: string): boolean;
|
|
1204
|
+
/**
|
|
1205
|
+
* rwx check for the current principal. Returns `true` when no authorization
|
|
1206
|
+
* service is registered.
|
|
1207
|
+
*/
|
|
1208
|
+
declare function cliCanAccess(context: Pick<ICliExecutionContext, 'services'>, resource: ICliProtectedResource, action: CliAccessAction, bypassPermissions?: string[]): boolean;
|
|
1209
|
+
/**
|
|
1210
|
+
* Reference rwx evaluation shared by implementations of
|
|
1211
|
+
* {@link ICliAuthorizationService.canAccess}.
|
|
1212
|
+
*/
|
|
1213
|
+
declare function cliEvaluateAccess(principal: ICliPrincipal | undefined, resource: ICliProtectedResource, action: CliAccessAction, bypassPermissions?: string[]): boolean;
|
|
1214
|
+
|
|
1215
|
+
/** A sign-in session as listed by {@link ICliSessionsService}. Never carries a token. */
|
|
1216
|
+
interface ICliSessionInfo {
|
|
1217
|
+
id: string;
|
|
1218
|
+
userId: string;
|
|
1219
|
+
userName: string;
|
|
1220
|
+
createdAt: number;
|
|
1221
|
+
lastActivity: number;
|
|
1222
|
+
/** When the session expires if idle; undefined when there is no timeout */
|
|
1223
|
+
expiresAt?: number;
|
|
1224
|
+
/** True for the caller's own session */
|
|
1225
|
+
current?: boolean;
|
|
1226
|
+
metadata?: {
|
|
1227
|
+
userAgent?: string;
|
|
1228
|
+
remoteAddress?: string;
|
|
1229
|
+
[key: string]: unknown;
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Lists and revokes sign-in sessions. Implemented locally (sessions of this
|
|
1234
|
+
* browser) and by servers (all sessions). Used by `sessions` / `session-kick`.
|
|
1235
|
+
*/
|
|
1236
|
+
interface ICliSessionsService {
|
|
1237
|
+
/** All sessions visible to the caller */
|
|
1238
|
+
list(): Promise<ICliSessionInfo[]>;
|
|
1239
|
+
/** Revoke a session by id */
|
|
1240
|
+
revoke(sessionId: string, reason?: string): Promise<void>;
|
|
1241
|
+
/** Revoke every session of a user (optionally keeping one) */
|
|
1242
|
+
revokeUser(userId: string, options?: {
|
|
1243
|
+
exceptSessionId?: string;
|
|
1244
|
+
reason?: string;
|
|
1245
|
+
}): Promise<void>;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
/**
|
|
1249
|
+
* Represents a service that manages user sessions in the CLI
|
|
1250
|
+
*/
|
|
1251
|
+
interface ICliUserSessionService {
|
|
1252
|
+
/** Gets the current user session as a reactive stream */
|
|
1253
|
+
getUserSession(): Observable<ICliUserSession | undefined>;
|
|
1254
|
+
/** Sets the current user session */
|
|
1255
|
+
setUserSession(session: ICliUserSession): Promise<void>;
|
|
1256
|
+
/** Clears the current session (logout) */
|
|
1257
|
+
clearSession(): Promise<void>;
|
|
1258
|
+
/** Persists the current session to storage */
|
|
1259
|
+
persistSession(): Promise<void>;
|
|
1260
|
+
/** Restores a session from storage (called on boot) */
|
|
1261
|
+
restoreSession(): Promise<ICliUserSession | undefined>;
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Represents a service that manages users in the CLI
|
|
1265
|
+
*/
|
|
1266
|
+
interface ICliUsersStoreService {
|
|
1267
|
+
/** Gets users with optional filtering and pagination */
|
|
1268
|
+
getUsers(options?: {
|
|
1269
|
+
query?: string;
|
|
1270
|
+
skip?: number;
|
|
1271
|
+
take?: number;
|
|
1272
|
+
}): Observable<ICliUser[]>;
|
|
1273
|
+
/** Creates a new user */
|
|
1274
|
+
createUser(user: CliAddUser): Promise<ICliUser>;
|
|
1275
|
+
/** Gets a user by id, name, or email */
|
|
1276
|
+
getUser(id: string): Observable<ICliUser | undefined>;
|
|
1277
|
+
/** Updates an existing user */
|
|
1278
|
+
updateUser(id: string, updates: CliUpdateUser): Promise<ICliUser>;
|
|
1279
|
+
/** Deletes a user by id */
|
|
1280
|
+
deleteUser(id: string): Promise<void>;
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Represents a service that manages groups in the CLI
|
|
1284
|
+
*/
|
|
1285
|
+
interface ICliGroupsStoreService {
|
|
1286
|
+
/** Gets all groups */
|
|
1287
|
+
getGroups(): Observable<ICliGroup[]>;
|
|
1288
|
+
/** Gets a group by id or name */
|
|
1289
|
+
getGroup(id: string): Observable<ICliGroup | undefined>;
|
|
1290
|
+
/** Creates a new group (role), optionally with permissions */
|
|
1291
|
+
createGroup(name: string, description?: string, permissions?: string[]): Promise<ICliGroup>;
|
|
1292
|
+
/** Updates a group's description and/or permissions (by id or name) */
|
|
1293
|
+
updateGroup(id: string, updates: {
|
|
1294
|
+
description?: string;
|
|
1295
|
+
permissions?: string[];
|
|
1296
|
+
}): Promise<ICliGroup>;
|
|
1297
|
+
/** Adds a user (id or name) to a group (id or name) */
|
|
1298
|
+
addMember(groupId: string, userId: string): Promise<void>;
|
|
1299
|
+
/** Removes a user (id or name) from a group (id or name) */
|
|
1300
|
+
removeMember(groupId: string, userId: string): Promise<void>;
|
|
1301
|
+
/** Deletes a group by id */
|
|
1302
|
+
deleteGroup(id: string): Promise<void>;
|
|
1303
|
+
/** Gets all users that belong to a group */
|
|
1304
|
+
getGroupMembers(groupId: string): Observable<ICliUser[]>;
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Represents a service that handles authentication in the CLI
|
|
1308
|
+
*/
|
|
1309
|
+
interface ICliAuthService {
|
|
1310
|
+
/**
|
|
1311
|
+
* Authenticates a user and returns a session. `password` may be omitted
|
|
1312
|
+
* only when the implementation allows passwordless sign-in.
|
|
1313
|
+
*/
|
|
1314
|
+
login(username: string, password?: string): Promise<ICliUserSession>;
|
|
1315
|
+
/** Ends the current session (the CLI is left signed out) */
|
|
1316
|
+
logout(): Promise<void>;
|
|
1317
|
+
/**
|
|
1318
|
+
* Switch to another user (`su`). Requires the target's password unless
|
|
1319
|
+
* the caller may skip it (implementation-defined, e.g. `users:update`).
|
|
1320
|
+
* Goes through the same lockout, events and audit as `login`.
|
|
1321
|
+
*/
|
|
1322
|
+
switchUser?(username: string, password?: string): Promise<ICliUserSession>;
|
|
1323
|
+
/**
|
|
1324
|
+
* Sets or updates a user's password.
|
|
1325
|
+
* @param currentPassword The user's current password, when changing one's own
|
|
1326
|
+
* password. Server-backed implementations forward it so the server can
|
|
1327
|
+
* re-check it; local implementations may ignore it.
|
|
1328
|
+
*/
|
|
1329
|
+
setPassword(userId: string, password: string, currentPassword?: string): Promise<void>;
|
|
1330
|
+
/** Verifies a password against stored credentials */
|
|
1331
|
+
verifyPassword(userId: string, password: string): Promise<boolean>;
|
|
1332
|
+
/** Hashes a password with a salt using Web Crypto SHA-256 */
|
|
1333
|
+
hashPassword(password: string, salt: string): Promise<string>;
|
|
1334
|
+
/** Validate password against policy. Returns error message or null if valid. */
|
|
1335
|
+
validatePassword?(password: string): string | null;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
/**
|
|
1339
|
+
* Represents a serialized snapshot of a CLI engine's state.
|
|
1340
|
+
* Used to duplicate terminal tabs with full state preservation.
|
|
1341
|
+
*/
|
|
1342
|
+
interface CliEngineSnapshot {
|
|
1343
|
+
/** Schema version for forward compatibility */
|
|
1344
|
+
version: 1;
|
|
1345
|
+
/** Timestamp (ms since epoch) when the snapshot was taken */
|
|
1346
|
+
timestamp: number;
|
|
1347
|
+
/** Serialized terminal state */
|
|
1348
|
+
terminal: {
|
|
1349
|
+
/** Terminal buffer serialized via @xterm/addon-serialize */
|
|
1350
|
+
serializedBuffer: string;
|
|
1351
|
+
/** Terminal column count at time of snapshot */
|
|
1352
|
+
cols: number;
|
|
1353
|
+
/** Terminal row count at time of snapshot */
|
|
1354
|
+
rows: number;
|
|
1355
|
+
};
|
|
1356
|
+
/** Command history entries (most recent last) */
|
|
1357
|
+
commandHistory: string[];
|
|
1358
|
+
/** Named state store entries */
|
|
1359
|
+
stateStores: Array<{
|
|
1360
|
+
name: string;
|
|
1361
|
+
state: Record<string, any>;
|
|
1362
|
+
}>;
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
/**
|
|
1366
|
+
* Background service lifecycle type.
|
|
1367
|
+
* - `'daemon'` — Long-running service whose `onStart` blocks until the abort signal
|
|
1368
|
+
* fires. Suitable for event loops, polling, or WebSocket connections. Can be
|
|
1369
|
+
* stopped and restarted.
|
|
1370
|
+
* - `'job'` — Run-to-completion task whose `onStart` resolves when the work is done.
|
|
1371
|
+
* Automatically transitions to `'done'` status on success. Cannot be restarted.
|
|
1372
|
+
*/
|
|
1373
|
+
type CliBackgroundServiceType = 'daemon' | 'job';
|
|
1374
|
+
/**
|
|
1375
|
+
* Lifecycle status of a background service.
|
|
1376
|
+
*/
|
|
1377
|
+
type CliBackgroundServiceStatus = 'pending' | 'running' | 'stopped' | 'failed' | 'done';
|
|
1378
|
+
/**
|
|
1379
|
+
* Where the service code is executing.
|
|
1380
|
+
*/
|
|
1381
|
+
type CliServiceExecutionMode = 'main-thread' | 'worker';
|
|
1382
|
+
/**
|
|
1383
|
+
* An event emitted by a background service.
|
|
1384
|
+
* Services control terminal notification visibility by setting `data.notify: true`.
|
|
1385
|
+
*/
|
|
1386
|
+
interface ICliServiceEvent {
|
|
1387
|
+
/** Name of the service that emitted this event */
|
|
1388
|
+
source: string;
|
|
1389
|
+
/** Event type — services define their own, registry emits lifecycle events */
|
|
1390
|
+
type: string;
|
|
1391
|
+
/** Arbitrary payload */
|
|
1392
|
+
data?: unknown;
|
|
1393
|
+
/** Set automatically by the registry */
|
|
1394
|
+
timestamp?: Date;
|
|
1395
|
+
}
|
|
1396
|
+
/**
|
|
1397
|
+
* Handler function for service events.
|
|
1398
|
+
*/
|
|
1399
|
+
type CliServiceEventHandler = (event: ICliServiceEvent) => void;
|
|
1400
|
+
/**
|
|
1401
|
+
* Log severity level for background service messages.
|
|
1402
|
+
* Shared by `ICliServiceLogEntry`, `ICliServiceContext.log()`,
|
|
1403
|
+
* and `WorkerServiceContext.log()`.
|
|
1404
|
+
*/
|
|
1405
|
+
type CliServiceLogLevel = 'info' | 'warn' | 'error';
|
|
1406
|
+
/**
|
|
1407
|
+
* A single log entry from a background service.
|
|
1408
|
+
*/
|
|
1409
|
+
interface ICliServiceLogEntry {
|
|
1410
|
+
timestamp: Date;
|
|
1411
|
+
level: CliServiceLogLevel;
|
|
1412
|
+
message: string;
|
|
1413
|
+
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Per-service runtime context.
|
|
1416
|
+
* Each background service receives its own context with an independent abort signal
|
|
1417
|
+
* and scoped timers (not shared with the full-screen timer set).
|
|
1418
|
+
*/
|
|
1419
|
+
interface ICliServiceContext {
|
|
1420
|
+
/** AbortSignal scoped to this service — independent of Ctrl+C */
|
|
1421
|
+
signal: AbortSignal;
|
|
1422
|
+
/** Emit an event from this service */
|
|
1423
|
+
emit(event: ICliServiceEvent): void;
|
|
1424
|
+
/** Log a message to this service's private log buffer */
|
|
1425
|
+
log(message: string, level?: CliServiceLogLevel): void;
|
|
1426
|
+
/** Create an interval scoped to this service (auto-cleared on stop) */
|
|
1427
|
+
createInterval(callback: () => void, ms: number): ICliManagedInterval;
|
|
1428
|
+
/** Create a timeout scoped to this service (auto-cleared on stop) */
|
|
1055
1429
|
createTimeout(callback: () => void, ms: number): ICliManagedTimer;
|
|
1056
1430
|
/** Access the shared state store */
|
|
1057
1431
|
state: ICliStateStore;
|
|
@@ -1077,49 +1451,637 @@ interface ICliBackgroundService {
|
|
|
1077
1451
|
/** Called for graceful shutdown */
|
|
1078
1452
|
onStop?(context: ICliServiceContext): Promise<void>;
|
|
1079
1453
|
/**
|
|
1080
|
-
* Called when the service throws an unrecoverable error.
|
|
1081
|
-
* Use this hook for logging or cleanup; throwing from `onError` itself
|
|
1082
|
-
* is safe — the registry catches it and marks the service as failed.
|
|
1454
|
+
* Called when the service throws an unrecoverable error.
|
|
1455
|
+
* Use this hook for logging or cleanup; throwing from `onError` itself
|
|
1456
|
+
* is safe — the registry catches it and marks the service as failed.
|
|
1457
|
+
*/
|
|
1458
|
+
onError?(error: Error, context: ICliServiceContext): void;
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* Read-only snapshot of a background service's current state.
|
|
1462
|
+
*/
|
|
1463
|
+
interface ICliBackgroundServiceInfo {
|
|
1464
|
+
/** Process ID assigned by the process registry */
|
|
1465
|
+
pid?: number;
|
|
1466
|
+
name: string;
|
|
1467
|
+
description?: string;
|
|
1468
|
+
type: CliBackgroundServiceType;
|
|
1469
|
+
status: CliBackgroundServiceStatus;
|
|
1470
|
+
executionMode: CliServiceExecutionMode;
|
|
1471
|
+
startedAt?: Date;
|
|
1472
|
+
stoppedAt?: Date;
|
|
1473
|
+
error?: string;
|
|
1474
|
+
/** Uptime in milliseconds (only when running) */
|
|
1475
|
+
uptime?: number;
|
|
1476
|
+
}
|
|
1477
|
+
/**
|
|
1478
|
+
* Registry that manages background service lifecycle.
|
|
1479
|
+
* Exposed on `ICliExecutionContext.backgroundServices`.
|
|
1480
|
+
*/
|
|
1481
|
+
interface ICliBackgroundServiceRegistry {
|
|
1482
|
+
register(service: ICliBackgroundService): void;
|
|
1483
|
+
start(name: string): Promise<void>;
|
|
1484
|
+
stop(name: string): Promise<void>;
|
|
1485
|
+
restart(name: string): Promise<void>;
|
|
1486
|
+
startJob(name: string, task: (context: ICliServiceContext) => Promise<void>, options?: {
|
|
1487
|
+
workerCompatible?: boolean;
|
|
1488
|
+
}): Promise<void>;
|
|
1489
|
+
getStatus(name: string): ICliBackgroundServiceInfo | undefined;
|
|
1490
|
+
list(): ICliBackgroundServiceInfo[];
|
|
1491
|
+
getLogs(name: string, limit?: number): ICliServiceLogEntry[];
|
|
1492
|
+
on(handler: CliServiceEventHandler, filter?: {
|
|
1493
|
+
source?: string;
|
|
1494
|
+
type?: string;
|
|
1495
|
+
}): () => void;
|
|
1496
|
+
destroyAll(): Promise<void>;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
/**
|
|
1500
|
+
* Messages sent from the main thread to a background service Worker.
|
|
1501
|
+
*/
|
|
1502
|
+
type CliWorkerInboundMessage = {
|
|
1503
|
+
type: 'start';
|
|
1504
|
+
config?: Record<string, unknown>;
|
|
1505
|
+
} | {
|
|
1506
|
+
type: 'stop';
|
|
1507
|
+
} | {
|
|
1508
|
+
type: 'abort';
|
|
1509
|
+
};
|
|
1510
|
+
/**
|
|
1511
|
+
* Messages sent from a background service Worker to the main thread.
|
|
1512
|
+
*/
|
|
1513
|
+
type CliWorkerOutboundMessage = {
|
|
1514
|
+
type: 'log';
|
|
1515
|
+
level: 'info' | 'warn' | 'error';
|
|
1516
|
+
message: string;
|
|
1517
|
+
} | {
|
|
1518
|
+
type: 'event';
|
|
1519
|
+
event: Omit<ICliServiceEvent, 'timestamp'>;
|
|
1520
|
+
} | {
|
|
1521
|
+
type: 'state-update';
|
|
1522
|
+
patch: Record<string, unknown>;
|
|
1523
|
+
} | {
|
|
1524
|
+
type: 'status';
|
|
1525
|
+
status: CliBackgroundServiceStatus;
|
|
1526
|
+
} | {
|
|
1527
|
+
type: 'error';
|
|
1528
|
+
message: string;
|
|
1529
|
+
stack?: string;
|
|
1530
|
+
};
|
|
1531
|
+
|
|
1532
|
+
/**
|
|
1533
|
+
* Represents an entry in a file listing.
|
|
1534
|
+
*/
|
|
1535
|
+
interface ICliFileEntry {
|
|
1536
|
+
name: string;
|
|
1537
|
+
type: 'file' | 'directory';
|
|
1538
|
+
size: number;
|
|
1539
|
+
modified: string;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
/**
|
|
1543
|
+
* Abstraction for file transfer operations.
|
|
1544
|
+
* Default implementation uses browser-native APIs (file picker, download dialog).
|
|
1545
|
+
* @qodalis/cli-files overrides with virtual FS backed by IndexedDB.
|
|
1546
|
+
*/
|
|
1547
|
+
interface ICliFileTransferService {
|
|
1548
|
+
readFile(path: string): Promise<string | null>;
|
|
1549
|
+
writeFile(path: string, content: string): Promise<void>;
|
|
1550
|
+
listFiles(path: string): Promise<ICliFileEntry[]>;
|
|
1551
|
+
exists(path: string): Promise<boolean>;
|
|
1552
|
+
downloadToBrowser(filename: string, content: string | Blob): void;
|
|
1553
|
+
uploadFromBrowser(accept?: string): Promise<{
|
|
1554
|
+
name: string;
|
|
1555
|
+
content: string;
|
|
1556
|
+
} | null>;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
interface ICliDragDropService {
|
|
1560
|
+
/** Emits an array of dropped File objects each time files are dropped onto the terminal */
|
|
1561
|
+
readonly onFileDrop: Observable<File[]>;
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
/**
|
|
1565
|
+
* Opaque state value carried between lines during syntax highlighting.
|
|
1566
|
+
* Encodes context such as "inside a multi-line string" or "inside a block comment"
|
|
1567
|
+
* so the highlighter can resume correctly on the next line.
|
|
1568
|
+
* `0` typically represents the default/root state.
|
|
1569
|
+
*/
|
|
1570
|
+
type LineState = number;
|
|
1571
|
+
interface ISyntaxHighlightRule {
|
|
1572
|
+
pattern: RegExp;
|
|
1573
|
+
tokenType: string;
|
|
1574
|
+
captureGroup?: number;
|
|
1575
|
+
}
|
|
1576
|
+
interface ISyntaxHighlighter {
|
|
1577
|
+
id: string;
|
|
1578
|
+
/** Human-readable language name (e.g. 'TypeScript'). Falls back to `id` when absent. */
|
|
1579
|
+
name?: string;
|
|
1580
|
+
extensions: string[];
|
|
1581
|
+
initialState: LineState;
|
|
1582
|
+
getRules(state: LineState): ISyntaxHighlightRule[];
|
|
1583
|
+
getNextLineState(line: string, currentState: LineState): LineState;
|
|
1584
|
+
}
|
|
1585
|
+
interface ISyntaxTheme {
|
|
1586
|
+
name: string;
|
|
1587
|
+
colors: Record<string, string>;
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
/**
|
|
1591
|
+
* Represents a package source for the CLI package manager
|
|
1592
|
+
*/
|
|
1593
|
+
interface CliPackageSource {
|
|
1594
|
+
/**
|
|
1595
|
+
* The name of the source, e.g. 'local', 'unpkg', 'jsdelivr'
|
|
1596
|
+
*/
|
|
1597
|
+
name: string;
|
|
1598
|
+
/**
|
|
1599
|
+
* The base URL for fetching package files, e.g. 'http://localhost:3000/'
|
|
1600
|
+
*/
|
|
1601
|
+
url: string;
|
|
1602
|
+
/**
|
|
1603
|
+
* The kind of source.
|
|
1604
|
+
* - 'registry': npm-compatible registry with search API (e.g. npmjs.org, Verdaccio)
|
|
1605
|
+
* - 'file': static file server, packages are discovered by probing known paths
|
|
1606
|
+
* @default 'file'
|
|
1607
|
+
*/
|
|
1608
|
+
kind?: 'registry' | 'file';
|
|
1609
|
+
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Represents a log level for the CLI
|
|
1612
|
+
*/
|
|
1613
|
+
declare enum CliLogLevel {
|
|
1614
|
+
None = 0,
|
|
1615
|
+
DEBUG = 1,
|
|
1616
|
+
LOG = 2,
|
|
1617
|
+
INFO = 3,
|
|
1618
|
+
WARN = 4,
|
|
1619
|
+
ERROR = 5
|
|
1620
|
+
}
|
|
1621
|
+
/**
|
|
1622
|
+
* Options for the CLI
|
|
1623
|
+
*/
|
|
1624
|
+
type CliOptions = Record<string, any> & {
|
|
1625
|
+
/**
|
|
1626
|
+
* Custom terminal options
|
|
1627
|
+
*/
|
|
1628
|
+
terminalOptions?: ITerminalOptions & ITerminalInitOnlyOptions;
|
|
1629
|
+
/**
|
|
1630
|
+
* The minimum log level to display
|
|
1631
|
+
*/
|
|
1632
|
+
logLevel?: CliLogLevel;
|
|
1633
|
+
/**
|
|
1634
|
+
* Custom package sources for the package manager.
|
|
1635
|
+
* Built-in sources (unpkg, jsdelivr) are always available.
|
|
1636
|
+
*/
|
|
1637
|
+
packageSources?: {
|
|
1638
|
+
/**
|
|
1639
|
+
* Name of the primary source. Defaults to 'unpkg'.
|
|
1640
|
+
*/
|
|
1641
|
+
primary?: string;
|
|
1642
|
+
/**
|
|
1643
|
+
* Additional custom sources
|
|
1644
|
+
*/
|
|
1645
|
+
sources?: CliPackageSource[];
|
|
1646
|
+
};
|
|
1647
|
+
/**
|
|
1648
|
+
* Remote CLI servers to connect to.
|
|
1649
|
+
* Commands from each server are discovered and registered as proxy processors.
|
|
1650
|
+
*/
|
|
1651
|
+
servers?: CliServerConfig[];
|
|
1652
|
+
/**
|
|
1653
|
+
* Whether the `eval` / `js` / `calc` command is enabled.
|
|
1654
|
+
* Disabled by default because it runs arbitrary JavaScript via `eval()`
|
|
1655
|
+
* in the host page context — a security risk in multi-tenant or
|
|
1656
|
+
* user-facing deployments.
|
|
1657
|
+
* @default false
|
|
1658
|
+
*/
|
|
1659
|
+
allowEval?: boolean;
|
|
1660
|
+
};
|
|
1661
|
+
/**
|
|
1662
|
+
* Represents a package that can be installed
|
|
1663
|
+
*/
|
|
1664
|
+
interface Package {
|
|
1665
|
+
/**
|
|
1666
|
+
* The name of the package
|
|
1667
|
+
*/
|
|
1668
|
+
name: string;
|
|
1669
|
+
/**
|
|
1670
|
+
* The global name used to access the package
|
|
1671
|
+
*/
|
|
1672
|
+
globalName?: string;
|
|
1673
|
+
/**
|
|
1674
|
+
* The version of the package
|
|
1675
|
+
*/
|
|
1676
|
+
version: string;
|
|
1677
|
+
/**
|
|
1678
|
+
* The unpkg url to the package
|
|
1679
|
+
*/
|
|
1680
|
+
url: string;
|
|
1681
|
+
/**
|
|
1682
|
+
* The dependencies for the module
|
|
1683
|
+
*/
|
|
1684
|
+
dependencies?: Package[];
|
|
1685
|
+
}
|
|
1686
|
+
/**
|
|
1687
|
+
* Represents command processor metadata
|
|
1688
|
+
*/
|
|
1689
|
+
type CliProcessorMetadata = Record<string, any> & {
|
|
1690
|
+
/**
|
|
1691
|
+
* If true, the processor is sealed and cannot be replaced or removed.
|
|
1692
|
+
* Sealed processors can still be extended (wrapped) by processors with `extendsProcessor = true`.
|
|
1693
|
+
*/
|
|
1694
|
+
sealed?: boolean;
|
|
1695
|
+
/**
|
|
1696
|
+
* If true, the processor requires the server to be running
|
|
1697
|
+
*/
|
|
1698
|
+
requireServer?: boolean;
|
|
1699
|
+
/**
|
|
1700
|
+
* The module the processor belongs to
|
|
1701
|
+
*/
|
|
1702
|
+
module?: string;
|
|
1703
|
+
/**
|
|
1704
|
+
* An icon to display for the processor
|
|
1705
|
+
*/
|
|
1706
|
+
icon?: CliIcon | string;
|
|
1707
|
+
/**
|
|
1708
|
+
* The minimum required version of @qodalis/cli-core for this processor.
|
|
1709
|
+
* If the installed core version is lower, the processor will be skipped during boot.
|
|
1710
|
+
*/
|
|
1711
|
+
requiredCoreVersion?: string;
|
|
1712
|
+
/**
|
|
1713
|
+
* The minimum required version of @qodalis/cli for this processor.
|
|
1714
|
+
* If the installed CLI version is lower, the processor will be skipped during boot.
|
|
1715
|
+
*/
|
|
1716
|
+
requiredCliVersion?: string;
|
|
1717
|
+
/**
|
|
1718
|
+
* If true, the command requires a signed-in user. Enforced by a
|
|
1719
|
+
* core guard that activates when an auth module registers an
|
|
1720
|
+
* `ICliAuthorizationService` (e.g. `@qodalis/cli-users`); without one the
|
|
1721
|
+
* flag is informational.
|
|
1722
|
+
*/
|
|
1723
|
+
requireAuth?: boolean;
|
|
1724
|
+
/**
|
|
1725
|
+
* The signed-in user must belong to at least one of these groups
|
|
1726
|
+
* (e.g. `['admin']`). Implies `requireAuth`. Enforced like `requireAuth`.
|
|
1727
|
+
*/
|
|
1728
|
+
requiredGroups?: string[];
|
|
1729
|
+
/**
|
|
1730
|
+
* The signed-in user must hold **all** of these permissions
|
|
1731
|
+
* (e.g. `['users:create']`), granted through their groups (roles).
|
|
1732
|
+
* Implies `requireAuth`. Enforced like `requireAuth`.
|
|
1733
|
+
*/
|
|
1734
|
+
requiredPermissions?: string[];
|
|
1735
|
+
/**
|
|
1736
|
+
* If true, the processor is hidden from the help command listing.
|
|
1737
|
+
* The command still works when typed directly and `help <command>` still shows its details.
|
|
1738
|
+
*/
|
|
1739
|
+
hidden?: boolean;
|
|
1740
|
+
};
|
|
1741
|
+
/**
|
|
1742
|
+
* Represents a state configuration for the CLI processor
|
|
1743
|
+
*/
|
|
1744
|
+
type CliStateConfiguration = {
|
|
1745
|
+
/**
|
|
1746
|
+
* The initial state for the processor
|
|
1747
|
+
*/
|
|
1748
|
+
initialState: Record<string, any>;
|
|
1749
|
+
/**
|
|
1750
|
+
* The store identifier for the processor, if any
|
|
1751
|
+
* @remarks If the store identifier is not set, the processor command name is used
|
|
1752
|
+
*/
|
|
1753
|
+
storeName?: string;
|
|
1754
|
+
};
|
|
1755
|
+
type CliState = Record<string, any>;
|
|
1756
|
+
/**
|
|
1757
|
+
* Position of the CLI panel relative to the viewport edge.
|
|
1758
|
+
* - `'bottom'` — anchored to the bottom (default)
|
|
1759
|
+
* - `'top'` — anchored to the top
|
|
1760
|
+
* - `'left'` — anchored to the left (vertical layout)
|
|
1761
|
+
* - `'right'` — anchored to the right (vertical layout)
|
|
1762
|
+
*/
|
|
1763
|
+
type CliPanelPosition = 'bottom' | 'top' | 'left' | 'right';
|
|
1764
|
+
/**
|
|
1765
|
+
* Alignment of the hidden-mode tab along its viewport edge.
|
|
1766
|
+
* - `'start'` — left for horizontal panels, top for vertical panels
|
|
1767
|
+
* - `'center'` — centered along the edge (default)
|
|
1768
|
+
* - `'end'` — right for horizontal panels, bottom for vertical panels
|
|
1769
|
+
*/
|
|
1770
|
+
type CliPanelHideAlignment = 'start' | 'center' | 'end';
|
|
1771
|
+
/**
|
|
1772
|
+
* Configuration for the CLI panel component.
|
|
1773
|
+
*/
|
|
1774
|
+
interface CliPanelConfig {
|
|
1775
|
+
/**
|
|
1776
|
+
* Whether the CLI should be collapsed by default.
|
|
1777
|
+
* @default true
|
|
1778
|
+
*/
|
|
1779
|
+
isCollapsed?: boolean;
|
|
1780
|
+
/**
|
|
1781
|
+
* Whether the panel starts hidden (showing only the small tab/arrow).
|
|
1782
|
+
* @default false
|
|
1783
|
+
*/
|
|
1784
|
+
isHidden?: boolean;
|
|
1785
|
+
/**
|
|
1786
|
+
* Position of the panel relative to the viewport.
|
|
1787
|
+
* @default 'bottom'
|
|
1788
|
+
*/
|
|
1789
|
+
position?: CliPanelPosition;
|
|
1790
|
+
/**
|
|
1791
|
+
* Whether the close button is shown.
|
|
1792
|
+
* @default true
|
|
1793
|
+
*/
|
|
1794
|
+
closable?: boolean;
|
|
1795
|
+
/**
|
|
1796
|
+
* Whether the panel can be resized by dragging.
|
|
1797
|
+
* @default true
|
|
1798
|
+
*/
|
|
1799
|
+
resizable?: boolean;
|
|
1800
|
+
/**
|
|
1801
|
+
* Whether the hide button is shown. When hidden, the panel collapses
|
|
1802
|
+
* to a small tab at the viewport edge.
|
|
1803
|
+
* @default true
|
|
1804
|
+
*/
|
|
1805
|
+
hideable?: boolean;
|
|
1806
|
+
/**
|
|
1807
|
+
* Alignment of the hide tab along the panel's viewport edge.
|
|
1808
|
+
* For bottom/top: 'start' = left, 'center', 'end' = right.
|
|
1809
|
+
* For left/right: 'start' = top, 'center', 'end' = bottom.
|
|
1810
|
+
* @default 'center'
|
|
1811
|
+
*/
|
|
1812
|
+
hideAlignment?: CliPanelHideAlignment;
|
|
1813
|
+
/**
|
|
1814
|
+
* When true, the panel's chrome (header, border, background) automatically
|
|
1815
|
+
* syncs its colors with the active terminal theme. CSS custom properties
|
|
1816
|
+
* are derived from the xterm theme and applied as inline styles.
|
|
1817
|
+
* @default false
|
|
1818
|
+
*/
|
|
1819
|
+
syncTheme?: boolean;
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
/**
|
|
1823
|
+
* Framework-agnostic interface for programmatic control of the CLI panel.
|
|
1824
|
+
*
|
|
1825
|
+
* CliEngine is referenced as a generic to avoid a circular dependency
|
|
1826
|
+
* between @qodalis/cli-core and @qodalis/cli. Framework implementations
|
|
1827
|
+
* resolve this to the concrete CliEngine class.
|
|
1828
|
+
*/
|
|
1829
|
+
interface ICliPanelRef<TEngine = unknown> {
|
|
1830
|
+
/** Expand the panel (sets collapsed=false). Initializes the first tab on first call. */
|
|
1831
|
+
open(): void;
|
|
1832
|
+
/** Collapse the panel body (sets collapsed=true). */
|
|
1833
|
+
collapse(): void;
|
|
1834
|
+
toggleCollapse(): void;
|
|
1835
|
+
/** Hide the panel to a small viewport-edge tab (reversible via unhide). */
|
|
1836
|
+
hide(): void;
|
|
1837
|
+
unhide(): void;
|
|
1838
|
+
toggleHide(): void;
|
|
1839
|
+
/** Destroy the panel (removes from DOM). Irreversible. */
|
|
1840
|
+
close(): void;
|
|
1841
|
+
maximize(): void;
|
|
1842
|
+
restore(): void;
|
|
1843
|
+
toggleMaximize(): void;
|
|
1844
|
+
/**
|
|
1845
|
+
* Set panel dimensions. Only the dimension relevant to the current
|
|
1846
|
+
* position is applied immediately (height for top/bottom, width for
|
|
1847
|
+
* left/right). The other dimension is stored for when the position changes.
|
|
1848
|
+
*/
|
|
1849
|
+
resize(dimensions: {
|
|
1850
|
+
height?: number;
|
|
1851
|
+
width?: number;
|
|
1852
|
+
}): void;
|
|
1853
|
+
setPosition(position: CliPanelPosition): void;
|
|
1854
|
+
/** Create a new tab. Returns the new tab's ID. Title defaults to "Terminal {id}". */
|
|
1855
|
+
addTab(title?: string): number;
|
|
1856
|
+
/** Close a tab by ID. No-op if the ID does not exist. */
|
|
1857
|
+
closeTab(tabId: number): void;
|
|
1858
|
+
/** Activate a tab by ID. No-op if the ID does not exist. */
|
|
1859
|
+
selectTab(tabId: number): void;
|
|
1860
|
+
/** Programmatically rename a tab. No-op if the ID does not exist. */
|
|
1861
|
+
renameTab(tabId: number, title: string): void;
|
|
1862
|
+
/**
|
|
1863
|
+
* Split the active pane (or a pane within the specified tab) to create
|
|
1864
|
+
* a new pane to the right. Returns the new pane's ID.
|
|
1865
|
+
*/
|
|
1866
|
+
splitPane(tabId?: number): number;
|
|
1867
|
+
/**
|
|
1868
|
+
* Close a pane by ID. Searches all tabs for the pane.
|
|
1869
|
+
* No-op if the ID does not exist.
|
|
1870
|
+
*/
|
|
1871
|
+
closePane(paneId: number): void;
|
|
1872
|
+
/** Get the engine for a specific pane, or the active pane if omitted. */
|
|
1873
|
+
getEngine(paneId?: number): TEngine | undefined;
|
|
1874
|
+
getState(): CliPanelState;
|
|
1875
|
+
}
|
|
1876
|
+
interface CliPanelState {
|
|
1877
|
+
collapsed: boolean;
|
|
1878
|
+
hidden: boolean;
|
|
1879
|
+
maximized: boolean;
|
|
1880
|
+
position: CliPanelPosition;
|
|
1881
|
+
height: number;
|
|
1882
|
+
width: number;
|
|
1883
|
+
activeTabId: number;
|
|
1884
|
+
activePaneId: number;
|
|
1885
|
+
tabs: CliPanelTabState[];
|
|
1886
|
+
}
|
|
1887
|
+
interface CliPanelTabState {
|
|
1888
|
+
id: number;
|
|
1889
|
+
title: string;
|
|
1890
|
+
panes: CliPanelPaneState[];
|
|
1891
|
+
}
|
|
1892
|
+
interface CliPanelPaneState {
|
|
1893
|
+
id: number;
|
|
1894
|
+
widthPercent: number;
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
/**
|
|
1898
|
+
* Options for HTTP client requests.
|
|
1899
|
+
* Extends standard RequestInit with convenience fields.
|
|
1900
|
+
*/
|
|
1901
|
+
interface CliHttpRequestOptions extends Omit<RequestInit, 'method' | 'body'> {
|
|
1902
|
+
/**
|
|
1903
|
+
* Request timeout in milliseconds. When set, the request is automatically
|
|
1904
|
+
* aborted after this duration. Combines with any existing abort signal.
|
|
1083
1905
|
*/
|
|
1084
|
-
|
|
1906
|
+
timeout?: number;
|
|
1085
1907
|
}
|
|
1086
1908
|
/**
|
|
1087
|
-
*
|
|
1909
|
+
* HTTP client for making requests from command processors.
|
|
1910
|
+
*
|
|
1911
|
+
* Automatically merges the command's abort signal so that requests are
|
|
1912
|
+
* cancelled when the user presses Ctrl+C. Provides typed convenience
|
|
1913
|
+
* methods for common HTTP verbs as well as a raw `fetch()` for cases
|
|
1914
|
+
* that need full Response access (streaming, progress, etc.).
|
|
1915
|
+
*
|
|
1916
|
+
* Available on the execution context as `context.http`.
|
|
1917
|
+
*
|
|
1918
|
+
* @example
|
|
1919
|
+
* ```ts
|
|
1920
|
+
* // Typed JSON response
|
|
1921
|
+
* const users = await context.http.get<User[]>('https://api.example.com/users');
|
|
1922
|
+
*
|
|
1923
|
+
* // POST with body
|
|
1924
|
+
* await context.http.post('https://api.example.com/users', { name: 'John' });
|
|
1925
|
+
*
|
|
1926
|
+
* // Raw fetch for streaming
|
|
1927
|
+
* const response = await context.http.fetch('https://example.com/file.zip');
|
|
1928
|
+
* const reader = response.body?.getReader();
|
|
1929
|
+
* ```
|
|
1088
1930
|
*/
|
|
1089
|
-
interface
|
|
1090
|
-
/**
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
/**
|
|
1101
|
-
|
|
1931
|
+
interface ICliHttpClient {
|
|
1932
|
+
/**
|
|
1933
|
+
* Make a raw HTTP request. Returns the full Response object for cases
|
|
1934
|
+
* that need streaming, headers, or status inspection.
|
|
1935
|
+
* The command's abort signal is automatically merged.
|
|
1936
|
+
*/
|
|
1937
|
+
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
1938
|
+
/**
|
|
1939
|
+
* HTTP GET request. Returns the parsed JSON response body.
|
|
1940
|
+
*/
|
|
1941
|
+
get<T = any>(url: string, options?: CliHttpRequestOptions): Promise<T>;
|
|
1942
|
+
/**
|
|
1943
|
+
* HTTP POST request. Automatically serializes the body as JSON
|
|
1944
|
+
* (unless body is FormData, Blob, string, or ArrayBuffer).
|
|
1945
|
+
* Returns the parsed JSON response body.
|
|
1946
|
+
*/
|
|
1947
|
+
post<T = any>(url: string, body?: any, options?: CliHttpRequestOptions): Promise<T>;
|
|
1948
|
+
/**
|
|
1949
|
+
* HTTP PUT request. Automatically serializes the body as JSON.
|
|
1950
|
+
* Returns the parsed JSON response body.
|
|
1951
|
+
*/
|
|
1952
|
+
put<T = any>(url: string, body?: any, options?: CliHttpRequestOptions): Promise<T>;
|
|
1953
|
+
/**
|
|
1954
|
+
* HTTP PATCH request. Automatically serializes the body as JSON.
|
|
1955
|
+
* Returns the parsed JSON response body.
|
|
1956
|
+
*/
|
|
1957
|
+
patch<T = any>(url: string, body?: any, options?: CliHttpRequestOptions): Promise<T>;
|
|
1958
|
+
/**
|
|
1959
|
+
* HTTP DELETE request. Returns the parsed JSON response body (if any).
|
|
1960
|
+
*/
|
|
1961
|
+
delete<T = any>(url: string, options?: CliHttpRequestOptions): Promise<T>;
|
|
1962
|
+
/**
|
|
1963
|
+
* HTTP HEAD request. Returns the full Response (no body parsing).
|
|
1964
|
+
*/
|
|
1965
|
+
head(url: string, options?: CliHttpRequestOptions): Promise<Response>;
|
|
1966
|
+
/**
|
|
1967
|
+
* HTTP OPTIONS request. Returns the parsed JSON response body.
|
|
1968
|
+
*/
|
|
1969
|
+
options<T = any>(url: string, options?: CliHttpRequestOptions): Promise<T>;
|
|
1102
1970
|
}
|
|
1103
1971
|
/**
|
|
1104
|
-
*
|
|
1105
|
-
*
|
|
1972
|
+
* Error thrown by `ICliHttpClient` JSON helpers (`get`, `post`, `put`,
|
|
1973
|
+
* `patch`, `delete`, `options`) when the server responds with a non-2xx status.
|
|
1974
|
+
*
|
|
1975
|
+
* Exposes the HTTP status so callers can react to specific responses
|
|
1976
|
+
* (for example, clearing a stored session token on `401`).
|
|
1977
|
+
*
|
|
1978
|
+
* @example
|
|
1979
|
+
* ```ts
|
|
1980
|
+
* try {
|
|
1981
|
+
* await context.http.get(url);
|
|
1982
|
+
* } catch (e) {
|
|
1983
|
+
* if (e instanceof CliHttpError && e.status === 401) {
|
|
1984
|
+
* // token expired or revoked
|
|
1985
|
+
* }
|
|
1986
|
+
* }
|
|
1987
|
+
* ```
|
|
1106
1988
|
*/
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1989
|
+
declare class CliHttpError extends Error {
|
|
1990
|
+
/** HTTP status code of the failed response */
|
|
1991
|
+
readonly status: number;
|
|
1992
|
+
/** HTTP status text of the failed response */
|
|
1993
|
+
readonly statusText: string;
|
|
1994
|
+
/** Parsed JSON error body, when the server returned one */
|
|
1995
|
+
readonly body?: unknown | undefined;
|
|
1996
|
+
constructor(message: string,
|
|
1997
|
+
/** HTTP status code of the failed response */
|
|
1998
|
+
status: number,
|
|
1999
|
+
/** HTTP status text of the failed response */
|
|
2000
|
+
statusText?: string,
|
|
2001
|
+
/** Parsed JSON error body, when the server returned one */
|
|
2002
|
+
body?: unknown | undefined);
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
type CliNotificationLevel = 'info' | 'success' | 'warn' | 'error';
|
|
2006
|
+
interface CliNotification {
|
|
2007
|
+
level: CliNotificationLevel;
|
|
2008
|
+
message: string;
|
|
2009
|
+
timestamp: number;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
interface ICliNotifier {
|
|
2013
|
+
/** Set an info-level notification (progress, status updates). */
|
|
2014
|
+
info(message: string): void;
|
|
2015
|
+
/** Set a success-level notification. */
|
|
2016
|
+
success(message: string): void;
|
|
2017
|
+
/** Set a warn-level notification. */
|
|
2018
|
+
warn(message: string): void;
|
|
2019
|
+
/** Set an error-level notification. */
|
|
2020
|
+
error(message: string): void;
|
|
2021
|
+
/** Clear the current notification. */
|
|
2022
|
+
clear(): void;
|
|
2023
|
+
/** The current notification, or undefined if cleared. */
|
|
2024
|
+
readonly current: CliNotification | undefined;
|
|
2025
|
+
/** Observable that emits on every change (set or clear). */
|
|
2026
|
+
readonly change$: Observable<CliNotification | undefined>;
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
/** Represents a user lifecycle event */
|
|
2030
|
+
interface ICliUserEvent {
|
|
2031
|
+
/** The type of event that occurred */
|
|
2032
|
+
type: 'login' | 'logout' | 'login_failed' | 'user_created' | 'user_deleted' | 'user_updated' | 'password_changed' | 'user_switched' | 'user_disabled' | 'user_enabled' | 'group_created' | 'group_updated' | 'group_deleted' | 'group_member_added' | 'group_member_removed' | 'session_revoked' | 'audit_cleared';
|
|
2033
|
+
/** The user involved in the event (for group events: the acting user) */
|
|
2034
|
+
user: ICliUser;
|
|
2035
|
+
/** The acting user's name, when different from `user` (e.g. an admin) */
|
|
2036
|
+
actor?: string;
|
|
2037
|
+
/** When the event occurred */
|
|
2038
|
+
timestamp: number;
|
|
2039
|
+
/** Optional additional details */
|
|
2040
|
+
details?: string;
|
|
2041
|
+
/** `user_updated`: the user's name before a rename (set only when the name changed) */
|
|
2042
|
+
previousName?: string;
|
|
2043
|
+
}
|
|
2044
|
+
/** Service that emits user lifecycle events for plugins to subscribe to */
|
|
2045
|
+
interface ICliUserEventService {
|
|
2046
|
+
/** Observable stream of user events */
|
|
2047
|
+
readonly events$: Observable<ICliUserEvent>;
|
|
2048
|
+
/** Emit a user event */
|
|
2049
|
+
emit(event: ICliUserEvent): void;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
/** A single audit log entry */
|
|
2053
|
+
interface ICliAuditEntry {
|
|
2054
|
+
/** Entry id (server-assigned in server mode) */
|
|
2055
|
+
id?: string;
|
|
2056
|
+
/** When the event occurred */
|
|
2057
|
+
timestamp: number;
|
|
2058
|
+
/** Event type (e.g., 'login', 'logout', 'login_failed') */
|
|
2059
|
+
event: string;
|
|
2060
|
+
/** Username involved */
|
|
2061
|
+
username: string;
|
|
2062
|
+
/** Optional additional details */
|
|
2063
|
+
details?: string;
|
|
2064
|
+
/** Id of the user the entry is about, when known */
|
|
2065
|
+
userId?: string;
|
|
2066
|
+
/** The user who performed the action, when different from `username` */
|
|
2067
|
+
actor?: string;
|
|
2068
|
+
/** Id of the acting user, when different from the subject */
|
|
2069
|
+
actorId?: string;
|
|
2070
|
+
/** Extra data (e.g. remote address) */
|
|
2071
|
+
metadata?: Record<string, unknown>;
|
|
2072
|
+
}
|
|
2073
|
+
/** Service for persistent audit logging */
|
|
2074
|
+
interface ICliAuditService {
|
|
2075
|
+
/** Log an audit entry (timestamp is added automatically) */
|
|
2076
|
+
log(entry: Omit<ICliAuditEntry, 'timestamp'>): Promise<void>;
|
|
2077
|
+
/** Retrieve audit entries with optional filtering */
|
|
2078
|
+
getEntries(options?: {
|
|
2079
|
+
limit?: number;
|
|
2080
|
+
event?: string;
|
|
2081
|
+
username?: string;
|
|
2082
|
+
}): Promise<ICliAuditEntry[]>;
|
|
2083
|
+
/** Clear all audit entries */
|
|
2084
|
+
clear(): Promise<void>;
|
|
1123
2085
|
}
|
|
1124
2086
|
|
|
1125
2087
|
/**
|
|
@@ -1221,19 +2183,20 @@ interface ICliExecutionContext {
|
|
|
1221
2183
|
*/
|
|
1222
2184
|
submitCommand(command: string): Promise<void>;
|
|
1223
2185
|
/**
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
2186
|
+
* Notifier service for displaying status notifications in the panel header bar.
|
|
2187
|
+
* Supports severity levels: info, success, warn, error.
|
|
1226
2188
|
* Cleared automatically when the command finishes.
|
|
2189
|
+
*
|
|
2190
|
+
* @example
|
|
2191
|
+
* ```ts
|
|
2192
|
+
* context.notifier.info('Downloading 45%...');
|
|
2193
|
+
* context.notifier.success('Connected to server');
|
|
2194
|
+
* context.notifier.warn('Rate limited, retrying...');
|
|
2195
|
+
* context.notifier.error('Connection failed');
|
|
2196
|
+
* context.notifier.clear();
|
|
2197
|
+
* ```
|
|
1227
2198
|
*/
|
|
1228
|
-
|
|
1229
|
-
/**
|
|
1230
|
-
* Clear the custom status text from the panel header bar.
|
|
1231
|
-
*/
|
|
1232
|
-
clearStatusText(): void;
|
|
1233
|
-
/**
|
|
1234
|
-
* Get the current custom status text, if any.
|
|
1235
|
-
*/
|
|
1236
|
-
getStatusText(): string | undefined;
|
|
2199
|
+
notifier: ICliNotifier;
|
|
1237
2200
|
/**
|
|
1238
2201
|
* Set the current processor as the context processor, i.e. the processor that will handle the command
|
|
1239
2202
|
* @param processor The processor to set
|
|
@@ -1337,6 +2300,16 @@ interface ICliExecutionContext {
|
|
|
1337
2300
|
* are scoped to this session and destroyed when the engine shuts down.
|
|
1338
2301
|
*/
|
|
1339
2302
|
backgroundServices: ICliBackgroundServiceRegistry;
|
|
2303
|
+
/**
|
|
2304
|
+
* HTTP client for making requests. Automatically wires the command's
|
|
2305
|
+
* abort signal so requests are cancelled on Ctrl+C.
|
|
2306
|
+
*
|
|
2307
|
+
* @example
|
|
2308
|
+
* ```ts
|
|
2309
|
+
* const data = await context.http.get<MyData>('https://api.example.com/data');
|
|
2310
|
+
* ```
|
|
2311
|
+
*/
|
|
2312
|
+
http: ICliHttpClient;
|
|
1340
2313
|
}
|
|
1341
2314
|
|
|
1342
2315
|
interface ICliProcessorHook {
|
|
@@ -1344,512 +2317,255 @@ interface ICliProcessorHook {
|
|
|
1344
2317
|
execute: (context: ICliExecutionContext) => Promise<void>;
|
|
1345
2318
|
}
|
|
1346
2319
|
|
|
1347
|
-
interface ICliCommandAuthor {
|
|
1348
|
-
/**
|
|
1349
|
-
* The name of the author
|
|
1350
|
-
*/
|
|
1351
|
-
name: string;
|
|
1352
|
-
/**
|
|
1353
|
-
* The email of the author
|
|
1354
|
-
*/
|
|
1355
|
-
email: string;
|
|
1356
|
-
}
|
|
1357
|
-
/**
|
|
1358
|
-
* Represents a command parameter
|
|
1359
|
-
*/
|
|
1360
|
-
interface ICliCommandParameterDescriptor {
|
|
1361
|
-
/**
|
|
1362
|
-
* The name of the parameter
|
|
1363
|
-
*/
|
|
1364
|
-
name: string;
|
|
1365
|
-
/**
|
|
1366
|
-
* Aliases for the parameter
|
|
1367
|
-
*/
|
|
1368
|
-
aliases?: string[];
|
|
1369
|
-
/**
|
|
1370
|
-
* A description of the parameter
|
|
1371
|
-
*/
|
|
1372
|
-
description: string;
|
|
1373
|
-
/**
|
|
1374
|
-
* If true, the parameter is required
|
|
1375
|
-
*/
|
|
1376
|
-
required: boolean;
|
|
1377
|
-
/**
|
|
1378
|
-
* The type of the parameter
|
|
1379
|
-
*/
|
|
1380
|
-
type: 'string' | 'number' | 'boolean' | 'array' | 'object' | string;
|
|
1381
|
-
/**
|
|
1382
|
-
* The default value of the parameter
|
|
1383
|
-
*/
|
|
1384
|
-
defaultValue?: any;
|
|
1385
|
-
/**
|
|
1386
|
-
* A validator function that validates the value of the parameter
|
|
1387
|
-
* @param value The value to validate
|
|
1388
|
-
* @returns An object with a valid property that indicates if the value is valid and an optional message property that contains a message to display if the value is not valid
|
|
1389
|
-
*/
|
|
1390
|
-
validator?: (value: any) => {
|
|
1391
|
-
/**
|
|
1392
|
-
* Indicates if the value is valid
|
|
1393
|
-
*/
|
|
1394
|
-
valid: boolean;
|
|
1395
|
-
/**
|
|
1396
|
-
* An optional message to display if the value is not valid
|
|
1397
|
-
*/
|
|
1398
|
-
message?: string;
|
|
1399
|
-
};
|
|
1400
|
-
}
|
|
1401
|
-
/**
|
|
1402
|
-
* Represents a configuration option that a command processor exposes
|
|
1403
|
-
* for management via the `configure` command.
|
|
1404
|
-
*/
|
|
1405
|
-
interface ICliConfigurationOption {
|
|
1406
|
-
/**
|
|
1407
|
-
* The key used to store and retrieve this option, e.g. 'maxItems'
|
|
1408
|
-
*/
|
|
1409
|
-
key: string;
|
|
1410
|
-
/**
|
|
1411
|
-
* Human-readable label shown in the interactive menu
|
|
1412
|
-
*/
|
|
1413
|
-
label: string;
|
|
1414
|
-
/**
|
|
1415
|
-
* Description of what this option controls
|
|
1416
|
-
*/
|
|
1417
|
-
description: string;
|
|
1418
|
-
/**
|
|
1419
|
-
* The data type of the option
|
|
1420
|
-
*/
|
|
1421
|
-
type: 'string' | 'number' | 'boolean' | 'select';
|
|
1422
|
-
/**
|
|
1423
|
-
* The default value when no configuration has been set
|
|
1424
|
-
*/
|
|
1425
|
-
defaultValue: any;
|
|
1426
|
-
/**
|
|
1427
|
-
* Available choices for 'select' type options
|
|
1428
|
-
*/
|
|
1429
|
-
options?: {
|
|
1430
|
-
label: string;
|
|
1431
|
-
value: any;
|
|
1432
|
-
}[];
|
|
1433
|
-
/**
|
|
1434
|
-
* Optional validator function
|
|
1435
|
-
*/
|
|
1436
|
-
validator?: (value: any) => {
|
|
1437
|
-
valid: boolean;
|
|
1438
|
-
message?: string;
|
|
1439
|
-
};
|
|
1440
|
-
/**
|
|
1441
|
-
* Override the category grouping (defaults to the processor command name)
|
|
1442
|
-
*/
|
|
1443
|
-
category?: string;
|
|
1444
|
-
}
|
|
1445
|
-
/**
|
|
1446
|
-
* Represents a command processor
|
|
1447
|
-
*/
|
|
1448
|
-
interface ICliCommandProcessor {
|
|
1449
|
-
/**
|
|
1450
|
-
* The command that this processor handles
|
|
1451
|
-
*/
|
|
1452
|
-
command: string;
|
|
1453
|
-
/**
|
|
1454
|
-
* Alternative names for the command
|
|
1455
|
-
*/
|
|
1456
|
-
aliases?: string[];
|
|
1457
|
-
/**
|
|
1458
|
-
* A description of the command
|
|
1459
|
-
*/
|
|
1460
|
-
description?: string;
|
|
1461
|
-
/**
|
|
1462
|
-
* The author of the command
|
|
1463
|
-
*/
|
|
1464
|
-
author?: ICliCommandAuthor;
|
|
1465
|
-
/**
|
|
1466
|
-
* If true, the processor accepts raw text input after the command name as its value.
|
|
1467
|
-
* The captured text is available via `command.value` in `processCommand`.
|
|
1468
|
-
* @default false
|
|
1469
|
-
* @remarks When true, any text following the command name is extracted as the command value
|
|
1470
|
-
* rather than being interpreted as sub-commands. Use `valueRequired` instead if the value is mandatory.
|
|
1471
|
-
*/
|
|
1472
|
-
acceptsRawInput?: boolean;
|
|
1473
|
-
/**
|
|
1474
|
-
* If true, the command requires some form of input before it can execute.
|
|
1475
|
-
*
|
|
1476
|
-
* The requirement is satisfied by **any** of:
|
|
1477
|
-
* - A positional value (text after the command name, available via `command.value`)
|
|
1478
|
-
* - Piped data from a previous command (available via `command.data`)
|
|
1479
|
-
* - Named arguments (e.g. `--server=node --path=/app`)
|
|
1480
|
-
*
|
|
1481
|
-
* When set, `command.value` is automatically extracted from the raw input
|
|
1482
|
-
* (equivalent to setting `acceptsRawInput`).
|
|
1483
|
-
*
|
|
1484
|
-
* Additionally, when positional input is present the engine skips
|
|
1485
|
-
* required-parameter validation — the processor is responsible for
|
|
1486
|
-
* parsing positional text into individual values. Required-parameter
|
|
1487
|
-
* checks still apply when the user provides only named arguments.
|
|
1488
|
-
*
|
|
1489
|
-
* @default false
|
|
1490
|
-
*/
|
|
1491
|
-
valueRequired?: boolean;
|
|
1492
|
-
/**
|
|
1493
|
-
* The version of the command processor
|
|
1494
|
-
* @default '1.0.0'
|
|
1495
|
-
*/
|
|
1496
|
-
version?: string;
|
|
1497
|
-
/**
|
|
1498
|
-
* The metadata for the command processor
|
|
1499
|
-
*/
|
|
1500
|
-
metadata?: CliProcessorMetadata;
|
|
1501
|
-
/**
|
|
1502
|
-
* Processors that are nested under this processor
|
|
1503
|
-
*/
|
|
1504
|
-
processors?: ICliCommandChildProcessor[];
|
|
2320
|
+
interface ICliCommandAuthor {
|
|
1505
2321
|
/**
|
|
1506
|
-
*
|
|
2322
|
+
* The name of the author
|
|
1507
2323
|
*/
|
|
1508
|
-
|
|
2324
|
+
name: string;
|
|
1509
2325
|
/**
|
|
1510
|
-
*
|
|
2326
|
+
* The email of the author
|
|
1511
2327
|
*/
|
|
1512
|
-
|
|
2328
|
+
email: string;
|
|
2329
|
+
}
|
|
2330
|
+
/**
|
|
2331
|
+
* Represents a command parameter
|
|
2332
|
+
*/
|
|
2333
|
+
interface ICliCommandParameterDescriptor {
|
|
1513
2334
|
/**
|
|
1514
|
-
*
|
|
1515
|
-
* @remarks The state configuration is used to store and retrieve state information for the command processor
|
|
1516
|
-
* @remarks State configuration is optional and can be used to store and retrieve state information for the command processor
|
|
1517
|
-
* @remarks The state configuration is used only for root command processors and not for child command processors
|
|
2335
|
+
* The name of the parameter
|
|
1518
2336
|
*/
|
|
1519
|
-
|
|
2337
|
+
name: string;
|
|
1520
2338
|
/**
|
|
1521
|
-
*
|
|
1522
|
-
* When defined, these options appear in the interactive configuration menu
|
|
1523
|
-
* and can be managed via `configure get/set` subcommands.
|
|
2339
|
+
* Aliases for the parameter
|
|
1524
2340
|
*/
|
|
1525
|
-
|
|
2341
|
+
aliases?: string[];
|
|
1526
2342
|
/**
|
|
1527
|
-
*
|
|
1528
|
-
* command name instead of replacing it. The registry sets `originalProcessor`
|
|
1529
|
-
* to the previous processor so this one can delegate to it.
|
|
2343
|
+
* A description of the parameter
|
|
1530
2344
|
*/
|
|
1531
|
-
|
|
2345
|
+
description: string;
|
|
1532
2346
|
/**
|
|
1533
|
-
*
|
|
1534
|
-
* Set automatically by the registry — do not set manually.
|
|
1535
|
-
* Call `this.originalProcessor.processCommand(command, context)` to delegate.
|
|
2347
|
+
* If true, the parameter is required
|
|
1536
2348
|
*/
|
|
1537
|
-
|
|
2349
|
+
required: boolean;
|
|
1538
2350
|
/**
|
|
1539
|
-
*
|
|
1540
|
-
* @param command The command to process
|
|
1541
|
-
* @param context The context in which the command is executed
|
|
2351
|
+
* The type of the parameter
|
|
1542
2352
|
*/
|
|
1543
|
-
|
|
2353
|
+
type: 'string' | 'number' | 'boolean' | 'array' | 'object' | string;
|
|
1544
2354
|
/**
|
|
1545
|
-
*
|
|
1546
|
-
* @param context The context in which the command is executed
|
|
2355
|
+
* The default value of the parameter
|
|
1547
2356
|
*/
|
|
1548
|
-
|
|
2357
|
+
defaultValue?: any;
|
|
1549
2358
|
/**
|
|
1550
|
-
* A function that validates the
|
|
2359
|
+
* A validator function that validates the value of the parameter
|
|
1551
2360
|
* @param value The value to validate
|
|
1552
2361
|
* @returns An object with a valid property that indicates if the value is valid and an optional message property that contains a message to display if the value is not valid
|
|
1553
2362
|
*/
|
|
1554
|
-
|
|
2363
|
+
validator?: (value: any) => {
|
|
2364
|
+
/**
|
|
2365
|
+
* Indicates if the value is valid
|
|
2366
|
+
*/
|
|
1555
2367
|
valid: boolean;
|
|
2368
|
+
/**
|
|
2369
|
+
* An optional message to display if the value is not valid
|
|
2370
|
+
*/
|
|
1556
2371
|
message?: string;
|
|
1557
2372
|
};
|
|
1558
|
-
/**
|
|
1559
|
-
* Initialize the command processor
|
|
1560
|
-
* @param context The context in which the command is executed
|
|
1561
|
-
*/
|
|
1562
|
-
initialize?(context: ICliExecutionContext): Promise<void>;
|
|
1563
|
-
/**
|
|
1564
|
-
* Handle raw terminal data when this processor is the active context processor.
|
|
1565
|
-
* When implemented, ALL terminal input is routed here instead of normal CLI input handling.
|
|
1566
|
-
* Used for full-screen interactive modes (editors, pagers, etc.).
|
|
1567
|
-
* @param data The raw terminal data string (escape sequences, control chars, printable text)
|
|
1568
|
-
* @param context The execution context
|
|
1569
|
-
*/
|
|
1570
|
-
onData?(data: string, context: ICliExecutionContext): Promise<void>;
|
|
1571
|
-
/**
|
|
1572
|
-
* Called when the terminal is resized while this processor is the active
|
|
1573
|
-
* full-screen context processor. Allows processors to adapt their rendering
|
|
1574
|
-
* to the new terminal dimensions.
|
|
1575
|
-
* @param cols The new number of columns
|
|
1576
|
-
* @param rows The new number of rows
|
|
1577
|
-
* @param context The execution context
|
|
1578
|
-
*/
|
|
1579
|
-
onResize?(cols: number, rows: number, context: ICliExecutionContext): void;
|
|
1580
|
-
/**
|
|
1581
|
-
* Called when the processor is being disposed — either because full-screen
|
|
1582
|
-
* mode ended, the terminal disconnected, or the CLI component is being
|
|
1583
|
-
* destroyed. Use this to clean up resources (timers, subscriptions, etc.).
|
|
1584
|
-
* @param context The execution context
|
|
1585
|
-
*/
|
|
1586
|
-
onDispose?(context: ICliExecutionContext): void;
|
|
1587
2373
|
}
|
|
1588
2374
|
/**
|
|
1589
|
-
* Represents a
|
|
2375
|
+
* Represents a configuration option that a command processor exposes
|
|
2376
|
+
* for management via the `configure` command.
|
|
1590
2377
|
*/
|
|
1591
|
-
interface
|
|
2378
|
+
interface ICliConfigurationOption {
|
|
1592
2379
|
/**
|
|
1593
|
-
* The
|
|
2380
|
+
* The key used to store and retrieve this option, e.g. 'maxItems'
|
|
1594
2381
|
*/
|
|
1595
|
-
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
/**
|
|
1599
|
-
* Describes a global parameter (e.g. --help, --version) together with
|
|
1600
|
-
* the handler that executes when the parameter is present.
|
|
1601
|
-
*
|
|
1602
|
-
* Global parameters are checked for every command before the command
|
|
1603
|
-
* processor's own `processCommand` runs. If the handler returns `true`,
|
|
1604
|
-
* command execution is halted (the parameter "consumed" the invocation).
|
|
1605
|
-
*/
|
|
1606
|
-
interface ICliGlobalParameterHandler {
|
|
2382
|
+
key: string;
|
|
1607
2383
|
/**
|
|
1608
|
-
*
|
|
2384
|
+
* Human-readable label shown in the interactive menu
|
|
1609
2385
|
*/
|
|
1610
|
-
|
|
2386
|
+
label: string;
|
|
1611
2387
|
/**
|
|
1612
|
-
*
|
|
1613
|
-
* @default 0
|
|
2388
|
+
* Description of what this option controls
|
|
1614
2389
|
*/
|
|
1615
|
-
|
|
2390
|
+
description: string;
|
|
1616
2391
|
/**
|
|
1617
|
-
*
|
|
1618
|
-
* @returns `true` to halt command execution, `false` to continue.
|
|
2392
|
+
* The data type of the option
|
|
1619
2393
|
*/
|
|
1620
|
-
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
/**
|
|
1624
|
-
* Represents a service that executes commands
|
|
1625
|
-
*/
|
|
1626
|
-
interface ICliCommandExecutorService {
|
|
2394
|
+
type: 'string' | 'number' | 'boolean' | 'select';
|
|
1627
2395
|
/**
|
|
1628
|
-
*
|
|
1629
|
-
* sub-commands, and parameters.
|
|
1630
|
-
* @param command The parsed command to show help for
|
|
1631
|
-
* @param context The execution context
|
|
2396
|
+
* The default value when no configuration has been set
|
|
1632
2397
|
*/
|
|
1633
|
-
|
|
2398
|
+
defaultValue: any;
|
|
1634
2399
|
/**
|
|
1635
|
-
*
|
|
1636
|
-
* @param command The command to execute
|
|
1637
|
-
* @param context The context in which the command is executed
|
|
2400
|
+
* Available choices for 'select' type options
|
|
1638
2401
|
*/
|
|
1639
|
-
|
|
2402
|
+
options?: {
|
|
2403
|
+
label: string;
|
|
2404
|
+
value: any;
|
|
2405
|
+
}[];
|
|
1640
2406
|
/**
|
|
1641
|
-
*
|
|
1642
|
-
* Global parameters (e.g. --help, --version) are evaluated for every
|
|
1643
|
-
* command before the processor's own processCommand runs.
|
|
1644
|
-
* @param handler The global parameter handler to register
|
|
2407
|
+
* Optional validator function
|
|
1645
2408
|
*/
|
|
1646
|
-
|
|
2409
|
+
validator?: (value: any) => {
|
|
2410
|
+
valid: boolean;
|
|
2411
|
+
message?: string;
|
|
2412
|
+
};
|
|
1647
2413
|
/**
|
|
1648
|
-
*
|
|
1649
|
-
* Used by help output and tab-completion.
|
|
2414
|
+
* Override the category grouping (defaults to the processor command name)
|
|
1650
2415
|
*/
|
|
1651
|
-
|
|
2416
|
+
category?: string;
|
|
1652
2417
|
}
|
|
1653
|
-
|
|
1654
2418
|
/**
|
|
1655
|
-
* Represents a
|
|
2419
|
+
* Represents a command processor
|
|
1656
2420
|
*/
|
|
1657
|
-
interface
|
|
1658
|
-
/**
|
|
1659
|
-
* The processors registered with the registry
|
|
1660
|
-
*/
|
|
1661
|
-
readonly processors: ICliCommandProcessor[];
|
|
1662
|
-
/**
|
|
1663
|
-
* Find a processor for a command
|
|
1664
|
-
* @param mainCommand
|
|
1665
|
-
* @param chainCommands
|
|
1666
|
-
*/
|
|
1667
|
-
findProcessor(mainCommand: string, chainCommands: string[]): ICliCommandProcessor | undefined;
|
|
2421
|
+
interface ICliCommandProcessor {
|
|
1668
2422
|
/**
|
|
1669
|
-
*
|
|
1670
|
-
* @param mainCommand The main command name.
|
|
1671
|
-
* @param chainCommands The remaining chain commands (if any).
|
|
1672
|
-
* @param processors The list of available processors.
|
|
1673
|
-
* @returns The matching processor or undefined if not found.
|
|
2423
|
+
* The command that this processor handles
|
|
1674
2424
|
*/
|
|
1675
|
-
|
|
2425
|
+
command: string;
|
|
1676
2426
|
/**
|
|
1677
|
-
*
|
|
1678
|
-
* @param child The child processor
|
|
2427
|
+
* Alternative names for the command
|
|
1679
2428
|
*/
|
|
1680
|
-
|
|
2429
|
+
aliases?: string[];
|
|
1681
2430
|
/**
|
|
1682
|
-
*
|
|
1683
|
-
* @param processor
|
|
2431
|
+
* A description of the command
|
|
1684
2432
|
*/
|
|
1685
|
-
|
|
2433
|
+
description?: string;
|
|
1686
2434
|
/**
|
|
1687
|
-
*
|
|
1688
|
-
* @param processor
|
|
2435
|
+
* The author of the command
|
|
1689
2436
|
*/
|
|
1690
|
-
|
|
1691
|
-
}
|
|
1692
|
-
/**
|
|
1693
|
-
* Represents a tracked CLI process entry
|
|
1694
|
-
*/
|
|
1695
|
-
interface ICliProcessEntry {
|
|
1696
|
-
pid: number;
|
|
1697
|
-
/** Display name (service name for bg services, command text for commands) */
|
|
1698
|
-
name: string;
|
|
1699
|
-
/** Process type */
|
|
1700
|
-
type: 'command' | 'daemon' | 'job' | 'service';
|
|
1701
|
-
command: string;
|
|
1702
|
-
startTime: number;
|
|
1703
|
-
status: 'running' | 'completed' | 'failed' | 'killed';
|
|
1704
|
-
exitCode?: number;
|
|
1705
|
-
}
|
|
1706
|
-
/** Options for registering a process */
|
|
1707
|
-
interface ICliProcessRegisterOptions {
|
|
1708
|
-
/** Display name (defaults to command) */
|
|
1709
|
-
name?: string;
|
|
1710
|
-
/** Process type (defaults to 'command') */
|
|
1711
|
-
type?: 'command' | 'daemon' | 'job' | 'service';
|
|
1712
|
-
/** Custom kill handler (e.g. for background services) */
|
|
1713
|
-
onKill?: () => Promise<void> | void;
|
|
1714
|
-
}
|
|
1715
|
-
/**
|
|
1716
|
-
* Registry for tracking CLI processes
|
|
1717
|
-
*/
|
|
1718
|
-
interface ICliProcessRegistry {
|
|
1719
|
-
/** Register a new process, returns assigned PID */
|
|
1720
|
-
register(command: string, options?: ICliProcessRegisterOptions): {
|
|
1721
|
-
pid: number;
|
|
1722
|
-
abortController: AbortController;
|
|
1723
|
-
};
|
|
1724
|
-
/** Mark process as completed */
|
|
1725
|
-
complete(pid: number, exitCode: number): void;
|
|
1726
|
-
/** Mark process as failed */
|
|
1727
|
-
fail(pid: number): void;
|
|
1728
|
-
/** Kill a process by PID */
|
|
1729
|
-
kill(pid: number): boolean;
|
|
1730
|
-
/** List all processes (running + recent completed) */
|
|
1731
|
-
list(): ICliProcessEntry[];
|
|
1732
|
-
/** Get the current foreground process PID */
|
|
1733
|
-
readonly currentPid: number | undefined;
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
interface ICliExecutionProcess {
|
|
2437
|
+
author?: ICliCommandAuthor;
|
|
1737
2438
|
/**
|
|
1738
|
-
*
|
|
2439
|
+
* If true, the processor accepts raw text input after the command name as its value.
|
|
2440
|
+
* The captured text is available via `command.value` in `processCommand`.
|
|
2441
|
+
* @default false
|
|
2442
|
+
* @remarks When true, any text following the command name is extracted as the command value
|
|
2443
|
+
* rather than being interpreted as sub-commands. Use `valueRequired` instead if the value is mandatory.
|
|
1739
2444
|
*/
|
|
1740
|
-
|
|
2445
|
+
acceptsRawInput?: boolean;
|
|
1741
2446
|
/**
|
|
1742
|
-
*
|
|
2447
|
+
* If true, the command requires some form of input before it can execute.
|
|
2448
|
+
*
|
|
2449
|
+
* The requirement is satisfied by **any** of:
|
|
2450
|
+
* - A positional value (text after the command name, available via `command.value`)
|
|
2451
|
+
* - Piped data from a previous command (available via `command.data`)
|
|
2452
|
+
* - Named arguments (e.g. `--server=node --path=/app`)
|
|
2453
|
+
*
|
|
2454
|
+
* When set, `command.value` is automatically extracted from the raw input
|
|
2455
|
+
* (equivalent to setting `acceptsRawInput`).
|
|
2456
|
+
*
|
|
2457
|
+
* Additionally, when positional input is present the engine skips
|
|
2458
|
+
* required-parameter validation — the processor is responsible for
|
|
2459
|
+
* parsing positional text into individual values. Required-parameter
|
|
2460
|
+
* checks still apply when the user provides only named arguments.
|
|
2461
|
+
*
|
|
2462
|
+
* @default false
|
|
1743
2463
|
*/
|
|
1744
|
-
|
|
2464
|
+
valueRequired?: boolean;
|
|
1745
2465
|
/**
|
|
1746
|
-
*
|
|
2466
|
+
* The version of the command processor
|
|
2467
|
+
* @default '1.0.0'
|
|
1747
2468
|
*/
|
|
1748
|
-
|
|
2469
|
+
version?: string;
|
|
1749
2470
|
/**
|
|
1750
|
-
* The
|
|
2471
|
+
* The metadata for the command processor
|
|
1751
2472
|
*/
|
|
1752
|
-
|
|
2473
|
+
metadata?: CliProcessorMetadata;
|
|
1753
2474
|
/**
|
|
1754
|
-
*
|
|
1755
|
-
* @param code The exit code
|
|
1756
|
-
* @returns void
|
|
2475
|
+
* Processors that are nested under this processor
|
|
1757
2476
|
*/
|
|
1758
|
-
|
|
2477
|
+
processors?: ICliCommandChildProcessor[];
|
|
1759
2478
|
/**
|
|
1760
|
-
*
|
|
2479
|
+
* Parameters that the command accepts
|
|
1761
2480
|
*/
|
|
1762
|
-
|
|
2481
|
+
parameters?: ICliCommandParameterDescriptor[];
|
|
1763
2482
|
/**
|
|
1764
|
-
*
|
|
2483
|
+
* Hooks that are executed before and after the command is processed
|
|
1765
2484
|
*/
|
|
1766
|
-
|
|
1767
|
-
/**
|
|
1768
|
-
* Indicates if the exit should be silent, i.e. not throw an error
|
|
1769
|
-
*/
|
|
1770
|
-
silent?: boolean;
|
|
1771
|
-
}) => void;
|
|
2485
|
+
hooks?: ICliProcessorHook[];
|
|
1772
2486
|
/**
|
|
1773
|
-
*
|
|
1774
|
-
* @
|
|
2487
|
+
* Represents the state configuration for the command processor
|
|
2488
|
+
* @remarks The state configuration is used to store and retrieve state information for the command processor
|
|
2489
|
+
* @remarks State configuration is optional and can be used to store and retrieve state information for the command processor
|
|
2490
|
+
* @remarks The state configuration is used only for root command processors and not for child command processors
|
|
1775
2491
|
*/
|
|
1776
|
-
|
|
1777
|
-
}
|
|
1778
|
-
|
|
1779
|
-
/**
|
|
1780
|
-
* Represents a key-value store for the CLI
|
|
1781
|
-
*/
|
|
1782
|
-
interface ICliKeyValueStore {
|
|
2492
|
+
stateConfiguration?: CliStateConfiguration;
|
|
1783
2493
|
/**
|
|
1784
|
-
*
|
|
1785
|
-
*
|
|
1786
|
-
*
|
|
2494
|
+
* Configuration options exposed by this processor for the `configure` command.
|
|
2495
|
+
* When defined, these options appear in the interactive configuration menu
|
|
2496
|
+
* and can be managed via `configure get/set` subcommands.
|
|
1787
2497
|
*/
|
|
1788
|
-
|
|
2498
|
+
configurationOptions?: ICliConfigurationOption[];
|
|
1789
2499
|
/**
|
|
1790
|
-
*
|
|
1791
|
-
*
|
|
1792
|
-
*
|
|
1793
|
-
* @returns A promise resolving when the value is stored.
|
|
2500
|
+
* When true, this processor extends (wraps) an existing processor with the same
|
|
2501
|
+
* command name instead of replacing it. The registry sets `originalProcessor`
|
|
2502
|
+
* to the previous processor so this one can delegate to it.
|
|
1794
2503
|
*/
|
|
1795
|
-
|
|
2504
|
+
extendsProcessor?: boolean;
|
|
1796
2505
|
/**
|
|
1797
|
-
*
|
|
1798
|
-
*
|
|
1799
|
-
*
|
|
2506
|
+
* Reference to the original processor that this one extends.
|
|
2507
|
+
* Set automatically by the registry — do not set manually.
|
|
2508
|
+
* Call `this.originalProcessor.processCommand(command, context)` to delegate.
|
|
1800
2509
|
*/
|
|
1801
|
-
|
|
2510
|
+
originalProcessor?: ICliCommandProcessor;
|
|
1802
2511
|
/**
|
|
1803
|
-
*
|
|
1804
|
-
* @
|
|
2512
|
+
* Process the command
|
|
2513
|
+
* @param command The command to process
|
|
2514
|
+
* @param context The context in which the command is executed
|
|
1805
2515
|
*/
|
|
1806
|
-
|
|
1807
|
-
}
|
|
1808
|
-
/**
|
|
1809
|
-
* Reactive state store scoped to a command processor or module.
|
|
1810
|
-
*
|
|
1811
|
-
* State is a plain object (`Record<string, any>`). Updates are shallow-merged
|
|
1812
|
-
* (top-level keys are replaced, nested objects are not deep-merged).
|
|
1813
|
-
* `getState()` returns a snapshot — mutating the returned object has no effect;
|
|
1814
|
-
* always use `updateState()` to change state.
|
|
1815
|
-
*/
|
|
1816
|
-
interface ICliStateStore {
|
|
2516
|
+
processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void>;
|
|
1817
2517
|
/**
|
|
1818
|
-
*
|
|
1819
|
-
* @
|
|
2518
|
+
* Write the description of the command
|
|
2519
|
+
* @param context The context in which the command is executed
|
|
1820
2520
|
*/
|
|
1821
|
-
|
|
2521
|
+
writeDescription?(context: ICliExecutionContext): void;
|
|
1822
2522
|
/**
|
|
1823
|
-
*
|
|
1824
|
-
*
|
|
1825
|
-
*
|
|
1826
|
-
* @param newState Partial state to merge with the current state
|
|
2523
|
+
* A function that validates the command before execution
|
|
2524
|
+
* @param value The value to validate
|
|
2525
|
+
* @returns An object with a valid property that indicates if the value is valid and an optional message property that contains a message to display if the value is not valid
|
|
1827
2526
|
*/
|
|
1828
|
-
|
|
2527
|
+
validateBeforeExecution?: (command: CliProcessCommand, context: ICliExecutionContext) => {
|
|
2528
|
+
valid: boolean;
|
|
2529
|
+
message?: string;
|
|
2530
|
+
};
|
|
1829
2531
|
/**
|
|
1830
|
-
*
|
|
1831
|
-
* @param
|
|
1832
|
-
* @returns Observable of the selected value.
|
|
2532
|
+
* Initialize the command processor
|
|
2533
|
+
* @param context The context in which the command is executed
|
|
1833
2534
|
*/
|
|
1834
|
-
|
|
2535
|
+
initialize?(context: ICliExecutionContext): Promise<void>;
|
|
1835
2536
|
/**
|
|
1836
|
-
*
|
|
1837
|
-
*
|
|
1838
|
-
*
|
|
2537
|
+
* Handle raw terminal data when this processor is the active context processor.
|
|
2538
|
+
* When implemented, ALL terminal input is routed here instead of normal CLI input handling.
|
|
2539
|
+
* Used for full-screen interactive modes (editors, pagers, etc.).
|
|
2540
|
+
* @param data The raw terminal data string (escape sequences, control chars, printable text)
|
|
2541
|
+
* @param context The execution context
|
|
1839
2542
|
*/
|
|
1840
|
-
|
|
2543
|
+
onData?(data: string, context: ICliExecutionContext): Promise<void>;
|
|
1841
2544
|
/**
|
|
1842
|
-
*
|
|
2545
|
+
* Called when the terminal is resized while this processor is the active
|
|
2546
|
+
* full-screen context processor. Allows processors to adapt their rendering
|
|
2547
|
+
* to the new terminal dimensions.
|
|
2548
|
+
* @param cols The new number of columns
|
|
2549
|
+
* @param rows The new number of rows
|
|
2550
|
+
* @param context The execution context
|
|
1843
2551
|
*/
|
|
1844
|
-
|
|
2552
|
+
onResize?(cols: number, rows: number, context: ICliExecutionContext): void;
|
|
1845
2553
|
/**
|
|
1846
|
-
*
|
|
2554
|
+
* Called when the processor is being disposed — either because full-screen
|
|
2555
|
+
* mode ended, the terminal disconnected, or the CLI component is being
|
|
2556
|
+
* destroyed. Use this to clean up resources (timers, subscriptions, etc.).
|
|
2557
|
+
* @param context The execution context
|
|
1847
2558
|
*/
|
|
1848
|
-
|
|
2559
|
+
onDispose?(context: ICliExecutionContext): void;
|
|
2560
|
+
}
|
|
2561
|
+
/**
|
|
2562
|
+
* Represents a child command processor
|
|
2563
|
+
*/
|
|
2564
|
+
interface ICliCommandChildProcessor extends ICliCommandProcessor {
|
|
1849
2565
|
/**
|
|
1850
|
-
*
|
|
2566
|
+
* The parent processor, it is populated by the processor manager
|
|
1851
2567
|
*/
|
|
1852
|
-
|
|
2568
|
+
parent?: ICliCommandProcessor;
|
|
1853
2569
|
}
|
|
1854
2570
|
|
|
1855
2571
|
/**
|
|
@@ -1900,6 +2616,17 @@ interface ICliModule {
|
|
|
1900
2616
|
processors?: ICliCommandProcessor[];
|
|
1901
2617
|
/** Services registered into the shared service container */
|
|
1902
2618
|
services?: CliProvider[];
|
|
2619
|
+
/**
|
|
2620
|
+
* Global command guards contributed by this module. They are registered
|
|
2621
|
+
* when the module boots and run before every command (across all modules),
|
|
2622
|
+
* e.g. authentication or permission checks. See {@link ICliCommandGuard}.
|
|
2623
|
+
*/
|
|
2624
|
+
guards?: ICliCommandGuard[];
|
|
2625
|
+
/**
|
|
2626
|
+
* Permissions this module uses (`resource:action`), registered in the
|
|
2627
|
+
* {@link ICliPermissionRegistry} at boot so they can be listed and granted.
|
|
2628
|
+
*/
|
|
2629
|
+
permissions?: CliPermissionDefinition[];
|
|
1903
2630
|
/** Module configuration, set via configure() */
|
|
1904
2631
|
config?: Record<string, any>;
|
|
1905
2632
|
/**
|
|
@@ -1991,449 +2718,411 @@ interface ICliLogger {
|
|
|
1991
2718
|
*/
|
|
1992
2719
|
error(...args: any[]): void;
|
|
1993
2720
|
/**
|
|
1994
|
-
* Log a debug message (DEBUG level)
|
|
1995
|
-
* @param args The arguments to log
|
|
1996
|
-
*/
|
|
1997
|
-
debug(...args: any[]): void;
|
|
1998
|
-
}
|
|
1999
|
-
|
|
2000
|
-
/**
|
|
2001
|
-
* Provides internationalization (i18n) support for CLI strings.
|
|
2002
|
-
*/
|
|
2003
|
-
interface ICliTranslationService {
|
|
2004
|
-
/**
|
|
2005
|
-
* Translate a key to the current locale.
|
|
2006
|
-
* @param key The translation key (e.g. 'cli.echo.description')
|
|
2007
|
-
* @param defaultValue The English fallback string (returned if no translation found)
|
|
2008
|
-
* @param params Optional interpolation parameters for `{param}` placeholders
|
|
2009
|
-
*/
|
|
2010
|
-
t(key: string, defaultValue: string, params?: Record<string, string | number>): string;
|
|
2011
|
-
/**
|
|
2012
|
-
* Get the current locale code (e.g. 'en', 'es', 'fr').
|
|
2013
|
-
*/
|
|
2014
|
-
getLocale(): string;
|
|
2015
|
-
/**
|
|
2016
|
-
* Set the active locale.
|
|
2017
|
-
* @param locale The locale code to switch to
|
|
2018
|
-
*/
|
|
2019
|
-
setLocale(locale: string): void;
|
|
2020
|
-
/**
|
|
2021
|
-
* Register translations for a locale.
|
|
2022
|
-
* Can be called multiple times — translations are merged, with later calls overriding earlier ones.
|
|
2023
|
-
* @param locale The locale code
|
|
2024
|
-
* @param translations Flat key-value map of translation keys to translated strings
|
|
2025
|
-
*/
|
|
2026
|
-
addTranslations(locale: string, translations: Record<string, string>): void;
|
|
2027
|
-
/**
|
|
2028
|
-
* Get all locale codes that have at least one registered translation.
|
|
2029
|
-
*/
|
|
2030
|
-
getAvailableLocales(): string[];
|
|
2031
|
-
}
|
|
2032
|
-
/**
|
|
2033
|
-
* Dependency injection container for CLI services.
|
|
2034
|
-
* Services are registered with string tokens and retrieved by type.
|
|
2035
|
-
*/
|
|
2036
|
-
interface ICliServiceProvider {
|
|
2037
|
-
/**
|
|
2038
|
-
* Retrieve a service by its injection token.
|
|
2039
|
-
* @param service The token (typically a `*_TOKEN` constant) identifying the service
|
|
2040
|
-
* @returns The service instance, cast to `T`
|
|
2041
|
-
* @throws If no service is registered for the given token
|
|
2042
|
-
*/
|
|
2043
|
-
get<T = unknown>(service: any): T;
|
|
2044
|
-
/**
|
|
2045
|
-
* Register one or more service definitions.
|
|
2046
|
-
* @param definition A single provider or an array of providers to register
|
|
2047
|
-
*/
|
|
2048
|
-
set(definition: CliProvider | CliProvider[]): void;
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
|
-
/**
|
|
2052
|
-
* Abstract permission service for checking rwx permissions on resources.
|
|
2053
|
-
* The default implementation lives in @qodalis/cli-users; consumers can
|
|
2054
|
-
* replace it via the DI container.
|
|
2055
|
-
*/
|
|
2056
|
-
interface ICliPermissionService {
|
|
2057
|
-
/**
|
|
2058
|
-
* Check whether a user may perform an action on a resource.
|
|
2059
|
-
* @param user The acting user.
|
|
2060
|
-
* @param action The requested operation.
|
|
2061
|
-
* @param ownership Owner/group of the resource.
|
|
2062
|
-
* @param permissions Permission string (e.g. "rwxr-xr-x").
|
|
2063
|
-
* @returns true if allowed.
|
|
2064
|
-
*/
|
|
2065
|
-
check(user: ICliUser, action: 'read' | 'write' | 'execute', ownership: ICliOwnership, permissions: string): boolean;
|
|
2066
|
-
/** Parse octal (e.g. "755") to a permission string (e.g. "rwxr-xr-x"). */
|
|
2067
|
-
parseOctal(octal: string): string;
|
|
2068
|
-
/** Convert a permission string (e.g. "rwxr-xr-x") to octal (e.g. "755"). */
|
|
2069
|
-
toOctal(permissions: string): string;
|
|
2070
|
-
}
|
|
2071
|
-
|
|
2072
|
-
/**
|
|
2073
|
-
* Context passed to completion providers describing the current input state.
|
|
2074
|
-
*/
|
|
2075
|
-
interface ICliCompletionContext {
|
|
2076
|
-
/** Full current line text */
|
|
2077
|
-
input: string;
|
|
2078
|
-
/** Cursor position in the line */
|
|
2079
|
-
cursor: number;
|
|
2080
|
-
/** The token (word) being completed at the cursor position */
|
|
2081
|
-
token: string;
|
|
2082
|
-
/** Start index of the token in the input string */
|
|
2083
|
-
tokenStart: number;
|
|
2084
|
-
/** Index of the token among all tokens (0 = command, 1+ = arguments) */
|
|
2085
|
-
tokenIndex: number;
|
|
2086
|
-
/** All tokens parsed from the input */
|
|
2087
|
-
tokens: string[];
|
|
2721
|
+
* Log a debug message (DEBUG level)
|
|
2722
|
+
* @param args The arguments to log
|
|
2723
|
+
*/
|
|
2724
|
+
debug(...args: any[]): void;
|
|
2088
2725
|
}
|
|
2726
|
+
|
|
2089
2727
|
/**
|
|
2090
|
-
* Provides
|
|
2091
|
-
* Plugins can register providers to extend completion (e.g. file paths, custom values).
|
|
2728
|
+
* Provides internationalization (i18n) support for CLI strings.
|
|
2092
2729
|
*/
|
|
2093
|
-
interface
|
|
2730
|
+
interface ICliTranslationService {
|
|
2094
2731
|
/**
|
|
2095
|
-
*
|
|
2096
|
-
*
|
|
2097
|
-
*
|
|
2732
|
+
* Translate a key to the current locale.
|
|
2733
|
+
* @param key The translation key (e.g. 'cli.echo.description')
|
|
2734
|
+
* @param defaultValue The English fallback string (returned if no translation found)
|
|
2735
|
+
* @param params Optional interpolation parameters for `{param}` placeholders
|
|
2098
2736
|
*/
|
|
2099
|
-
|
|
2737
|
+
t(key: string, defaultValue: string, params?: Record<string, string | number>): string;
|
|
2100
2738
|
/**
|
|
2101
|
-
*
|
|
2102
|
-
* Return an empty array if this provider does not apply.
|
|
2739
|
+
* Get the current locale code (e.g. 'en', 'es', 'fr').
|
|
2103
2740
|
*/
|
|
2104
|
-
|
|
2105
|
-
}
|
|
2106
|
-
|
|
2107
|
-
interface ICliProgressBar {
|
|
2741
|
+
getLocale(): string;
|
|
2108
2742
|
/**
|
|
2109
|
-
*
|
|
2743
|
+
* Set the active locale.
|
|
2744
|
+
* @param locale The locale code to switch to
|
|
2110
2745
|
*/
|
|
2111
|
-
|
|
2746
|
+
setLocale(locale: string): void;
|
|
2112
2747
|
/**
|
|
2113
|
-
*
|
|
2748
|
+
* Register translations for a locale.
|
|
2749
|
+
* Can be called multiple times — translations are merged, with later calls overriding earlier ones.
|
|
2750
|
+
* @param locale The locale code
|
|
2751
|
+
* @param translations Flat key-value map of translation keys to translated strings
|
|
2114
2752
|
*/
|
|
2115
|
-
|
|
2753
|
+
addTranslations(locale: string, translations: Record<string, string>): void;
|
|
2116
2754
|
/**
|
|
2117
|
-
*
|
|
2755
|
+
* Get all locale codes that have at least one registered translation.
|
|
2118
2756
|
*/
|
|
2119
|
-
|
|
2757
|
+
getAvailableLocales(): string[];
|
|
2120
2758
|
}
|
|
2121
2759
|
/**
|
|
2122
|
-
*
|
|
2760
|
+
* Dependency injection container for CLI services.
|
|
2761
|
+
* Services are registered with string tokens and retrieved by type.
|
|
2123
2762
|
*/
|
|
2124
|
-
interface
|
|
2763
|
+
interface ICliServiceProvider {
|
|
2125
2764
|
/**
|
|
2126
|
-
*
|
|
2127
|
-
*
|
|
2765
|
+
* Retrieve a service by its injection token.
|
|
2766
|
+
* Returns `undefined` when no provider is registered for the token.
|
|
2767
|
+
* For multi-provider tokens, returns the last registered value (use `getAll` for the full array).
|
|
2768
|
+
* @param service The token (typically a `*_TOKEN` constant) identifying the service
|
|
2769
|
+
* @returns The service instance cast to `T`, or `undefined` if not registered
|
|
2128
2770
|
*/
|
|
2129
|
-
|
|
2130
|
-
}
|
|
2131
|
-
type CliPercentageProgressBarUpdateValueOptions = {
|
|
2771
|
+
get<T = unknown>(service: any): T | undefined;
|
|
2132
2772
|
/**
|
|
2133
|
-
*
|
|
2134
|
-
*
|
|
2773
|
+
* Retrieve all registered services for a multi-provider token.
|
|
2774
|
+
* Returns an empty array when no provider is registered for the token.
|
|
2775
|
+
* @param service The token (typically a `*_TOKEN` constant) identifying the service
|
|
2776
|
+
* @returns Array of all resolved service instances
|
|
2135
2777
|
*/
|
|
2136
|
-
|
|
2137
|
-
};
|
|
2138
|
-
/**
|
|
2139
|
-
* Represents a progress bar for the CLI
|
|
2140
|
-
*/
|
|
2141
|
-
interface ICliPercentageProgressBar extends ICliProgressBar {
|
|
2778
|
+
getAll<T = unknown>(service: any): T[];
|
|
2142
2779
|
/**
|
|
2143
|
-
*
|
|
2144
|
-
*
|
|
2145
|
-
*
|
|
2780
|
+
* Retrieve a service by its injection token, throwing if not registered.
|
|
2781
|
+
* Use this when the service is required and its absence is a programming error.
|
|
2782
|
+
* For multi-provider tokens, returns the last registered value (use `getAll` for the full array).
|
|
2783
|
+
* @param service The token (typically a `*_TOKEN` constant) identifying the service
|
|
2784
|
+
* @returns The service instance, cast to `T`
|
|
2785
|
+
* @throws If no service is registered for the given token
|
|
2146
2786
|
*/
|
|
2147
|
-
|
|
2787
|
+
getRequired<T = unknown>(service: any): T;
|
|
2148
2788
|
/**
|
|
2149
|
-
*
|
|
2150
|
-
* @
|
|
2789
|
+
* Check whether a service is registered for the given token.
|
|
2790
|
+
* @param service The token identifying the service
|
|
2791
|
+
* @returns `true` if a service is registered, `false` otherwise
|
|
2151
2792
|
*/
|
|
2152
|
-
|
|
2793
|
+
has(service: any): boolean;
|
|
2153
2794
|
/**
|
|
2154
|
-
*
|
|
2155
|
-
* @param
|
|
2795
|
+
* Register one or more service definitions.
|
|
2796
|
+
* @param definition A single provider or an array of providers to register
|
|
2156
2797
|
*/
|
|
2157
|
-
|
|
2798
|
+
set(definition: CliProvider | CliProvider[]): void;
|
|
2158
2799
|
}
|
|
2159
|
-
|
|
2800
|
+
/** DI token for `ICliServerAuthTokenProvider` (multi-provider) */
|
|
2801
|
+
declare const ICliServerAuthTokenProvider_TOKEN = "cli-server-auth-token-provider";
|
|
2802
|
+
/** DI token for `ICliServerAuthService` */
|
|
2803
|
+
declare const ICliServerAuthService_TOKEN = "cli-server-auth-service";
|
|
2804
|
+
/**
|
|
2805
|
+
* Integrators implement this interface to supply auth credentials
|
|
2806
|
+
* for server requests. Multiple providers can be registered — the
|
|
2807
|
+
* auth service merges headers from all of them (later providers
|
|
2808
|
+
* override earlier ones for the same header name).
|
|
2809
|
+
*
|
|
2810
|
+
* @example
|
|
2811
|
+
* ```ts
|
|
2812
|
+
* class MyAuthProvider implements ICliServerAuthTokenProvider {
|
|
2813
|
+
* getHeaders(serverName: string) {
|
|
2814
|
+
* return { Authorization: `Bearer ${this.oauthService.getAccessToken()}` };
|
|
2815
|
+
* }
|
|
2816
|
+
* }
|
|
2817
|
+
*
|
|
2818
|
+
* // Register in a module:
|
|
2819
|
+
* const myModule: ICliModule = {
|
|
2820
|
+
* name: 'my-auth',
|
|
2821
|
+
* services: [{
|
|
2822
|
+
* provide: ICliServerAuthTokenProvider_TOKEN,
|
|
2823
|
+
* useValue: new MyAuthProvider(),
|
|
2824
|
+
* multi: true,
|
|
2825
|
+
* }],
|
|
2826
|
+
* };
|
|
2827
|
+
* ```
|
|
2828
|
+
*/
|
|
2829
|
+
interface ICliServerAuthTokenProvider {
|
|
2160
2830
|
/**
|
|
2161
|
-
*
|
|
2162
|
-
*
|
|
2831
|
+
* Return headers for a given server. Called on every request,
|
|
2832
|
+
* so implementations can return fresh tokens.
|
|
2833
|
+
*
|
|
2834
|
+
* @param serverName The `name` field from `CliServerConfig`
|
|
2835
|
+
* @returns Headers to merge into the request, or an empty object
|
|
2163
2836
|
*/
|
|
2164
|
-
|
|
2837
|
+
getHeaders(serverName: string): Record<string, string>;
|
|
2165
2838
|
/**
|
|
2166
|
-
*
|
|
2839
|
+
* Optional: query parameters for WebSocket upgrades to this server (e.g. a
|
|
2840
|
+
* short-lived single-use ticket). Called right before each connection.
|
|
2841
|
+
* Return `undefined` when this provider does not handle the server.
|
|
2842
|
+
* When any provider returns params, headers are NOT copied into the URL
|
|
2843
|
+
* (so bearer tokens never appear in WebSocket URLs).
|
|
2167
2844
|
*/
|
|
2168
|
-
|
|
2169
|
-
}
|
|
2170
|
-
|
|
2845
|
+
getWebSocketParams?(serverName: string): Promise<Record<string, string> | undefined>;
|
|
2846
|
+
}
|
|
2847
|
+
/**
|
|
2848
|
+
* Minimal view of the CLI server manager (token `ICliServerManager_TOKEN`),
|
|
2849
|
+
* e.g. for auth modules that must refresh a server after sign-in.
|
|
2850
|
+
*/
|
|
2851
|
+
interface ICliServerManager {
|
|
2852
|
+
/** Reconnect a server: re-fetch its commands and reopen its event socket. */
|
|
2853
|
+
reconnect(name: string): Promise<{
|
|
2854
|
+
success: boolean;
|
|
2855
|
+
commandCount: number;
|
|
2856
|
+
}>;
|
|
2171
2857
|
/**
|
|
2172
|
-
*
|
|
2173
|
-
*
|
|
2174
|
-
*
|
|
2175
|
-
*
|
|
2858
|
+
* The server a command should target when the user names none: the
|
|
2859
|
+
* default server (`server default`) when connected, otherwise the first
|
|
2860
|
+
* connected server. `null` when no server is connected (for example every
|
|
2861
|
+
* server requires a login the user has not done yet).
|
|
2176
2862
|
*/
|
|
2177
|
-
|
|
2863
|
+
preferredServer?(): string | null;
|
|
2178
2864
|
}
|
|
2179
|
-
|
|
2865
|
+
/** Token for {@link ICliServerManager} */
|
|
2866
|
+
declare const ICliServerManager_TOKEN = "cli-server-manager";
|
|
2180
2867
|
/**
|
|
2181
|
-
*
|
|
2868
|
+
* Internal service that resolves auth headers for a server by merging:
|
|
2869
|
+
* 1. Static/dynamic headers from `CliServerConfig.headers`
|
|
2870
|
+
* 2. Headers from all registered `ICliServerAuthTokenProvider`s
|
|
2871
|
+
*
|
|
2872
|
+
* Consumers should use this service instead of reading `config.headers` directly.
|
|
2182
2873
|
*/
|
|
2183
|
-
interface
|
|
2184
|
-
/**
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2874
|
+
interface ICliServerAuthService {
|
|
2875
|
+
/**
|
|
2876
|
+
* Resolve the final set of headers for a server request.
|
|
2877
|
+
* Merges config headers with all registered token providers.
|
|
2878
|
+
*
|
|
2879
|
+
* @param serverName The server's `name` field
|
|
2880
|
+
* @param configHeaders The `headers` field from `CliServerConfig`
|
|
2881
|
+
* @returns Merged headers ready for use in fetch/WebSocket calls
|
|
2882
|
+
*/
|
|
2883
|
+
getHeaders(serverName: string, configHeaders?: CliHeadersProvider): Record<string, string>;
|
|
2884
|
+
/**
|
|
2885
|
+
* WebSocket upgrade query params from the registered token providers, or
|
|
2886
|
+
* `undefined` when no provider handles this server.
|
|
2887
|
+
*/
|
|
2888
|
+
getWebSocketParams?(serverName: string): Promise<Record<string, string> | undefined>;
|
|
2194
2889
|
}
|
|
2890
|
+
|
|
2195
2891
|
/**
|
|
2196
|
-
*
|
|
2892
|
+
* A static header map or a function that returns one.
|
|
2893
|
+
* Use a function when headers contain short-lived tokens (e.g. JWTs)
|
|
2894
|
+
* so that every request gets a fresh value.
|
|
2895
|
+
*
|
|
2896
|
+
* @example
|
|
2897
|
+
* // Static
|
|
2898
|
+
* headers: { 'X-Api-Key': 'abc123' }
|
|
2899
|
+
*
|
|
2900
|
+
* // Dynamic (token refresh)
|
|
2901
|
+
* headers: () => ({ Authorization: `Bearer ${auth.getToken()}` })
|
|
2197
2902
|
*/
|
|
2198
|
-
|
|
2199
|
-
/** Gets users with optional filtering and pagination */
|
|
2200
|
-
getUsers(options?: {
|
|
2201
|
-
query?: string;
|
|
2202
|
-
skip?: number;
|
|
2203
|
-
take?: number;
|
|
2204
|
-
}): Observable<ICliUser[]>;
|
|
2205
|
-
/** Creates a new user */
|
|
2206
|
-
createUser(user: CliAddUser): Promise<ICliUser>;
|
|
2207
|
-
/** Gets a user by id, name, or email */
|
|
2208
|
-
getUser(id: string): Observable<ICliUser | undefined>;
|
|
2209
|
-
/** Updates an existing user */
|
|
2210
|
-
updateUser(id: string, updates: CliUpdateUser): Promise<ICliUser>;
|
|
2211
|
-
/** Deletes a user by id */
|
|
2212
|
-
deleteUser(id: string): Promise<void>;
|
|
2213
|
-
}
|
|
2903
|
+
type CliHeadersProvider = Record<string, string> | (() => Record<string, string>);
|
|
2214
2904
|
/**
|
|
2215
|
-
*
|
|
2905
|
+
* Resolves a CliHeadersProvider to a plain header map.
|
|
2216
2906
|
*/
|
|
2217
|
-
|
|
2218
|
-
/** Gets all groups */
|
|
2219
|
-
getGroups(): Observable<ICliGroup[]>;
|
|
2220
|
-
/** Gets a group by id or name */
|
|
2221
|
-
getGroup(id: string): Observable<ICliGroup | undefined>;
|
|
2222
|
-
/** Creates a new group */
|
|
2223
|
-
createGroup(name: string, description?: string): Promise<ICliGroup>;
|
|
2224
|
-
/** Deletes a group by id */
|
|
2225
|
-
deleteGroup(id: string): Promise<void>;
|
|
2226
|
-
/** Gets all users that belong to a group */
|
|
2227
|
-
getGroupMembers(groupId: string): Observable<ICliUser[]>;
|
|
2228
|
-
}
|
|
2907
|
+
declare function resolveHeaders(provider?: CliHeadersProvider): Record<string, string>;
|
|
2229
2908
|
/**
|
|
2230
|
-
*
|
|
2909
|
+
* Resolves auth headers for a server request using the auth service if available,
|
|
2910
|
+
* otherwise falls back to resolving config headers directly.
|
|
2911
|
+
*
|
|
2912
|
+
* This is the single entry point plugins should use to get headers for server requests.
|
|
2913
|
+
*
|
|
2914
|
+
* @param services The service provider (from context.services)
|
|
2915
|
+
* @param serverName The server name
|
|
2916
|
+
* @param configHeaders The headers from CliServerConfig
|
|
2917
|
+
* @returns Resolved headers ready for use
|
|
2231
2918
|
*/
|
|
2232
|
-
|
|
2233
|
-
/** Authenticates a user and returns a session */
|
|
2234
|
-
login(username: string, password: string): Promise<ICliUserSession>;
|
|
2235
|
-
/** Ends the current session */
|
|
2236
|
-
logout(): Promise<void>;
|
|
2237
|
-
/** Sets or updates a user's password */
|
|
2238
|
-
setPassword(userId: string, password: string): Promise<void>;
|
|
2239
|
-
/** Verifies a password against stored credentials */
|
|
2240
|
-
verifyPassword(userId: string, password: string): Promise<boolean>;
|
|
2241
|
-
/** Hashes a password with a salt using Web Crypto SHA-256 */
|
|
2242
|
-
hashPassword(password: string, salt: string): Promise<string>;
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2919
|
+
declare function resolveServerHeaders(services: ICliServiceProvider | undefined, serverName: string, configHeaders?: CliHeadersProvider): Record<string, string>;
|
|
2245
2920
|
/**
|
|
2246
|
-
*
|
|
2247
|
-
* Used to duplicate terminal tabs with full state preservation.
|
|
2921
|
+
* Configuration for a remote CLI server
|
|
2248
2922
|
*/
|
|
2249
|
-
|
|
2250
|
-
/**
|
|
2251
|
-
|
|
2252
|
-
/**
|
|
2253
|
-
|
|
2254
|
-
/**
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
/** Named state store entries */
|
|
2266
|
-
stateStores: Array<{
|
|
2267
|
-
name: string;
|
|
2268
|
-
state: Record<string, any>;
|
|
2269
|
-
}>;
|
|
2270
|
-
}
|
|
2271
|
-
|
|
2923
|
+
type CliServerConfig = {
|
|
2924
|
+
/** Unique identifier, used for namespacing commands */
|
|
2925
|
+
name: string;
|
|
2926
|
+
/** Base URL of the server, e.g. "https://api.example.com" */
|
|
2927
|
+
url: string;
|
|
2928
|
+
/** Whether this server is enabled. @default true */
|
|
2929
|
+
enabled?: boolean;
|
|
2930
|
+
/**
|
|
2931
|
+
* Custom headers sent with every request (e.g. auth tokens).
|
|
2932
|
+
* Can be a static object or a function that returns fresh headers
|
|
2933
|
+
* on each call (useful for rotating tokens / JWTs).
|
|
2934
|
+
*/
|
|
2935
|
+
headers?: CliHeadersProvider;
|
|
2936
|
+
/** Request timeout in milliseconds. @default 30000 */
|
|
2937
|
+
timeout?: number;
|
|
2938
|
+
};
|
|
2272
2939
|
/**
|
|
2273
|
-
*
|
|
2940
|
+
* A single output item in a server response
|
|
2274
2941
|
*/
|
|
2275
|
-
type
|
|
2276
|
-
type: '
|
|
2277
|
-
|
|
2942
|
+
type CliServerOutput = {
|
|
2943
|
+
type: 'text';
|
|
2944
|
+
value: string;
|
|
2945
|
+
style?: 'success' | 'error' | 'info' | 'warning';
|
|
2278
2946
|
} | {
|
|
2279
|
-
type: '
|
|
2947
|
+
type: 'table';
|
|
2948
|
+
headers: string[];
|
|
2949
|
+
rows: string[][];
|
|
2280
2950
|
} | {
|
|
2281
|
-
type: '
|
|
2951
|
+
type: 'list';
|
|
2952
|
+
items: string[];
|
|
2953
|
+
ordered?: boolean;
|
|
2954
|
+
} | {
|
|
2955
|
+
type: 'json';
|
|
2956
|
+
value: any;
|
|
2957
|
+
} | {
|
|
2958
|
+
type: 'key-value';
|
|
2959
|
+
entries: {
|
|
2960
|
+
key: string;
|
|
2961
|
+
value: string;
|
|
2962
|
+
}[];
|
|
2963
|
+
};
|
|
2964
|
+
/**
|
|
2965
|
+
* Structured response from a server command execution
|
|
2966
|
+
*/
|
|
2967
|
+
type CliServerResponse = {
|
|
2968
|
+
exitCode: number;
|
|
2969
|
+
outputs: CliServerOutput[];
|
|
2970
|
+
};
|
|
2971
|
+
/**
|
|
2972
|
+
* Metadata about a remote command processor, returned by GET /api/qcli/commands
|
|
2973
|
+
*/
|
|
2974
|
+
type CliServerCommandDescriptor = {
|
|
2975
|
+
command: string;
|
|
2976
|
+
description?: string;
|
|
2977
|
+
version?: string;
|
|
2978
|
+
parameters?: {
|
|
2979
|
+
name: string;
|
|
2980
|
+
aliases?: string[];
|
|
2981
|
+
description: string;
|
|
2982
|
+
required: boolean;
|
|
2983
|
+
type: string;
|
|
2984
|
+
defaultValue?: any;
|
|
2985
|
+
}[];
|
|
2986
|
+
processors?: CliServerCommandDescriptor[];
|
|
2282
2987
|
};
|
|
2283
2988
|
/**
|
|
2284
|
-
*
|
|
2989
|
+
* Server capabilities returned by GET /api/qcli/capabilities
|
|
2285
2990
|
*/
|
|
2286
|
-
type
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2991
|
+
type CliServerCapabilities = {
|
|
2992
|
+
/** Whether this server supports remote shell access */
|
|
2993
|
+
shell: boolean;
|
|
2994
|
+
/** Server operating system (e.g. "linux", "win32", "darwin") */
|
|
2995
|
+
os?: string;
|
|
2996
|
+
/** Path to the shell binary on the server */
|
|
2997
|
+
shellPath?: string;
|
|
2998
|
+
/** Server version string */
|
|
2999
|
+
version?: string;
|
|
3000
|
+
/** Whether this server supports SSE streaming execution */
|
|
3001
|
+
streaming?: boolean;
|
|
3002
|
+
};
|
|
3003
|
+
|
|
3004
|
+
type MultiServices = {
|
|
3005
|
+
/**
|
|
3006
|
+
* When true, injector returns an array of instances. This is useful to allow multiple
|
|
3007
|
+
* providers spread across many files to provide configuration information to a common token.
|
|
3008
|
+
*/
|
|
3009
|
+
multi?: boolean;
|
|
3010
|
+
};
|
|
3011
|
+
type CliValueProvider = MultiServices & {
|
|
3012
|
+
useValue: any;
|
|
3013
|
+
};
|
|
3014
|
+
type CliTypeProvider = MultiServices & {
|
|
3015
|
+
useClass: any;
|
|
3016
|
+
/** DI tokens resolved from the container and passed as constructor arguments. */
|
|
3017
|
+
deps?: any[];
|
|
2303
3018
|
};
|
|
3019
|
+
type CliFactoryProvider = MultiServices & {
|
|
3020
|
+
useFactory: Function;
|
|
3021
|
+
/** DI tokens resolved from the container and passed as factory arguments. */
|
|
3022
|
+
deps?: any[];
|
|
3023
|
+
};
|
|
3024
|
+
type CliProvider = {
|
|
3025
|
+
provide: any;
|
|
3026
|
+
/** When true, this token is sealed after registration and cannot be overwritten. */
|
|
3027
|
+
sealed?: boolean;
|
|
3028
|
+
/** When true, a new instance is created on every `get()` call instead of returning a singleton. */
|
|
3029
|
+
transient?: boolean;
|
|
3030
|
+
} & (CliValueProvider | CliTypeProvider | CliFactoryProvider) & Record<string, any>;
|
|
2304
3031
|
|
|
2305
3032
|
/**
|
|
2306
|
-
* Represents
|
|
3033
|
+
* Represents a user in the CLI
|
|
2307
3034
|
*/
|
|
2308
|
-
interface
|
|
3035
|
+
interface ICliUser {
|
|
3036
|
+
/** Unique user identifier */
|
|
3037
|
+
id: string;
|
|
3038
|
+
/** Login name (unique) */
|
|
2309
3039
|
name: string;
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
3040
|
+
/** Email address (unique) */
|
|
3041
|
+
email: string;
|
|
3042
|
+
/** Group IDs this user belongs to */
|
|
3043
|
+
groups: string[];
|
|
3044
|
+
/** Virtual home directory path, e.g. /home/root */
|
|
3045
|
+
homeDir?: string;
|
|
3046
|
+
/** Account creation timestamp */
|
|
3047
|
+
createdAt: number;
|
|
3048
|
+
/** Last modification timestamp */
|
|
3049
|
+
updatedAt: number;
|
|
3050
|
+
/** Whether the account is locked */
|
|
3051
|
+
disabled?: boolean;
|
|
3052
|
+
/** The user must set a new password before doing anything else */
|
|
3053
|
+
mustChangePassword?: boolean;
|
|
3054
|
+
/** Extensible metadata (department, phone, preferences, etc.) */
|
|
3055
|
+
data?: Record<string, any>;
|
|
3056
|
+
/** Timestamp of last successful login */
|
|
3057
|
+
lastLoginAt?: number;
|
|
2313
3058
|
}
|
|
2314
|
-
|
|
2315
3059
|
/**
|
|
2316
|
-
*
|
|
2317
|
-
* Default implementation uses browser-native APIs (file picker, download dialog).
|
|
2318
|
-
* @qodalis/cli-files overrides with virtual FS backed by IndexedDB.
|
|
3060
|
+
* Represents user credentials (shadow pattern — stored separately from ICliUser)
|
|
2319
3061
|
*/
|
|
2320
|
-
interface
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
} | null>;
|
|
2330
|
-
}
|
|
2331
|
-
|
|
2332
|
-
interface ICliDragDropService {
|
|
2333
|
-
/** Emits an array of dropped File objects each time files are dropped onto the terminal */
|
|
2334
|
-
readonly onFileDrop: Observable<File[]>;
|
|
3062
|
+
interface ICliUserCredentials {
|
|
3063
|
+
/** The user ID this credential belongs to */
|
|
3064
|
+
userId: string;
|
|
3065
|
+
/** SHA-256 hash of salt + password */
|
|
3066
|
+
passwordHash: string;
|
|
3067
|
+
/** Random salt for this user */
|
|
3068
|
+
salt: string;
|
|
3069
|
+
/** Timestamp of last password change */
|
|
3070
|
+
lastChanged: number;
|
|
2335
3071
|
}
|
|
2336
|
-
|
|
2337
3072
|
/**
|
|
2338
|
-
*
|
|
2339
|
-
* Encodes context such as "inside a multi-line string" or "inside a block comment"
|
|
2340
|
-
* so the highlighter can resume correctly on the next line.
|
|
2341
|
-
* `0` typically represents the default/root state.
|
|
3073
|
+
* Represents a group in the CLI
|
|
2342
3074
|
*/
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
pattern: RegExp;
|
|
2346
|
-
tokenType: string;
|
|
2347
|
-
captureGroup?: number;
|
|
2348
|
-
}
|
|
2349
|
-
interface ISyntaxHighlighter {
|
|
3075
|
+
interface ICliGroup {
|
|
3076
|
+
/** Unique group identifier */
|
|
2350
3077
|
id: string;
|
|
2351
|
-
/**
|
|
2352
|
-
name?: string;
|
|
2353
|
-
extensions: string[];
|
|
2354
|
-
initialState: LineState;
|
|
2355
|
-
getRules(state: LineState): ISyntaxHighlightRule[];
|
|
2356
|
-
getNextLineState(line: string, currentState: LineState): LineState;
|
|
2357
|
-
}
|
|
2358
|
-
interface ISyntaxTheme {
|
|
3078
|
+
/** Group name (unique) */
|
|
2359
3079
|
name: string;
|
|
2360
|
-
|
|
3080
|
+
/** Optional group description */
|
|
3081
|
+
description?: string;
|
|
3082
|
+
/** Group creation timestamp */
|
|
3083
|
+
createdAt: number;
|
|
3084
|
+
/**
|
|
3085
|
+
* Permissions granted to every member of the group. Groups act as roles.
|
|
3086
|
+
* Permission strings are `resource:action` (e.g. `users:create`), with
|
|
3087
|
+
* `*` wildcards (`users:*`, `*`). See {@link cliPermissionMatches}.
|
|
3088
|
+
*/
|
|
3089
|
+
permissions?: string[];
|
|
3090
|
+
/** Built-in groups (`admin`, `users`) cannot be deleted */
|
|
3091
|
+
builtIn?: boolean;
|
|
3092
|
+
/** Last modification timestamp */
|
|
3093
|
+
updatedAt?: number;
|
|
2361
3094
|
}
|
|
2362
|
-
|
|
2363
3095
|
/**
|
|
2364
|
-
*
|
|
2365
|
-
*
|
|
2366
|
-
* CliEngine is referenced as a generic to avoid a circular dependency
|
|
2367
|
-
* between @qodalis/cli-core and @qodalis/cli. Framework implementations
|
|
2368
|
-
* resolve this to the concrete CliEngine class.
|
|
3096
|
+
* Represents an active user session
|
|
2369
3097
|
*/
|
|
2370
|
-
interface
|
|
2371
|
-
/**
|
|
2372
|
-
|
|
2373
|
-
/**
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
toggleHide(): void;
|
|
2380
|
-
/** Destroy the panel (removes from DOM). Irreversible. */
|
|
2381
|
-
close(): void;
|
|
2382
|
-
maximize(): void;
|
|
2383
|
-
restore(): void;
|
|
2384
|
-
toggleMaximize(): void;
|
|
2385
|
-
/**
|
|
2386
|
-
* Set panel dimensions. Only the dimension relevant to the current
|
|
2387
|
-
* position is applied immediately (height for top/bottom, width for
|
|
2388
|
-
* left/right). The other dimension is stored for when the position changes.
|
|
2389
|
-
*/
|
|
2390
|
-
resize(dimensions: {
|
|
2391
|
-
height?: number;
|
|
2392
|
-
width?: number;
|
|
2393
|
-
}): void;
|
|
2394
|
-
setPosition(position: CliPanelPosition): void;
|
|
2395
|
-
/** Create a new tab. Returns the new tab's ID. Title defaults to "Terminal {id}". */
|
|
2396
|
-
addTab(title?: string): number;
|
|
2397
|
-
/** Close a tab by ID. No-op if the ID does not exist. */
|
|
2398
|
-
closeTab(tabId: number): void;
|
|
2399
|
-
/** Activate a tab by ID. No-op if the ID does not exist. */
|
|
2400
|
-
selectTab(tabId: number): void;
|
|
2401
|
-
/** Programmatically rename a tab. No-op if the ID does not exist. */
|
|
2402
|
-
renameTab(tabId: number, title: string): void;
|
|
2403
|
-
/**
|
|
2404
|
-
* Split the active pane (or a pane within the specified tab) to create
|
|
2405
|
-
* a new pane to the right. Returns the new pane's ID.
|
|
2406
|
-
*/
|
|
2407
|
-
splitPane(tabId?: number): number;
|
|
3098
|
+
interface ICliUserSession {
|
|
3099
|
+
/** The user associated with this session */
|
|
3100
|
+
user: ICliUser;
|
|
3101
|
+
/** Pre-computed display name for the prompt (set by users module) */
|
|
3102
|
+
displayName?: string;
|
|
3103
|
+
/** Timestamp when the session started */
|
|
3104
|
+
loginTime: number;
|
|
3105
|
+
/** Timestamp of last activity */
|
|
3106
|
+
lastActivity: number;
|
|
2408
3107
|
/**
|
|
2409
|
-
*
|
|
2410
|
-
*
|
|
3108
|
+
* Effective permissions of the user (union of their groups' permissions),
|
|
3109
|
+
* resolved by the users module at login and refreshed when groups change.
|
|
2411
3110
|
*/
|
|
2412
|
-
|
|
2413
|
-
/**
|
|
2414
|
-
|
|
2415
|
-
getState(): CliPanelState;
|
|
2416
|
-
}
|
|
2417
|
-
interface CliPanelState {
|
|
2418
|
-
collapsed: boolean;
|
|
2419
|
-
hidden: boolean;
|
|
2420
|
-
maximized: boolean;
|
|
2421
|
-
position: CliPanelPosition;
|
|
2422
|
-
height: number;
|
|
2423
|
-
width: number;
|
|
2424
|
-
activeTabId: number;
|
|
2425
|
-
activePaneId: number;
|
|
2426
|
-
tabs: CliPanelTabState[];
|
|
2427
|
-
}
|
|
2428
|
-
interface CliPanelTabState {
|
|
2429
|
-
id: number;
|
|
2430
|
-
title: string;
|
|
2431
|
-
panes: CliPanelPaneState[];
|
|
2432
|
-
}
|
|
2433
|
-
interface CliPanelPaneState {
|
|
2434
|
-
id: number;
|
|
2435
|
-
widthPercent: number;
|
|
3111
|
+
permissions?: string[];
|
|
3112
|
+
/** Extensible data (tokens, metadata, etc.) */
|
|
3113
|
+
data?: Record<string, any>;
|
|
2436
3114
|
}
|
|
3115
|
+
/** Fields required to create a new user */
|
|
3116
|
+
type CliAddUser = Omit<ICliUser, 'id' | 'createdAt' | 'updatedAt'>;
|
|
3117
|
+
/** Fields that can be updated on a user */
|
|
3118
|
+
type CliUpdateUser = Partial<Omit<ICliUser, 'id' | 'createdAt'>>;
|
|
3119
|
+
|
|
3120
|
+
declare const enums: {
|
|
3121
|
+
CliForegroundColor: typeof CliForegroundColor;
|
|
3122
|
+
CliBackgroundColor: typeof CliBackgroundColor;
|
|
3123
|
+
CliIcon: typeof CliIcon;
|
|
3124
|
+
CliLogLevel: typeof CliLogLevel;
|
|
3125
|
+
};
|
|
2437
3126
|
|
|
2438
3127
|
/**
|
|
2439
3128
|
* Registry that tracks loaded web CLI modules (frontend plugins) and dispatches
|
|
@@ -2597,12 +3286,45 @@ declare class ServerVersionNegotiator {
|
|
|
2597
3286
|
* Returns the negotiated API version and the base path for all subsequent calls,
|
|
2598
3287
|
* or null if the server is unreachable or incompatible.
|
|
2599
3288
|
*/
|
|
2600
|
-
static discover(baseUrl: string): Promise<{
|
|
3289
|
+
static discover(baseUrl: string, headers?: CliHeadersProvider): Promise<{
|
|
2601
3290
|
apiVersion: number;
|
|
2602
3291
|
basePath: string;
|
|
2603
3292
|
} | null>;
|
|
2604
3293
|
}
|
|
2605
3294
|
|
|
3295
|
+
/**
|
|
3296
|
+
* Builds a WebSocket URL that includes authentication credentials from headers
|
|
3297
|
+
* as query parameters. Since the browser WebSocket API does not support custom
|
|
3298
|
+
* request headers, this allows the host server's auth middleware to validate
|
|
3299
|
+
* the connection during the HTTP upgrade handshake.
|
|
3300
|
+
*
|
|
3301
|
+
* All configured headers are forwarded as query parameters prefixed with
|
|
3302
|
+
* `_header_` to avoid collisions with application-level query params.
|
|
3303
|
+
*
|
|
3304
|
+
* Accepts both static header maps and dynamic provider functions.
|
|
3305
|
+
*
|
|
3306
|
+
* **Security note:** Query parameters are visible in browser history, server
|
|
3307
|
+
* access logs, proxy/CDN logs, and the `Referer` header. Tokens placed in the
|
|
3308
|
+
* URL are therefore more exposed than those sent via HTTP headers. This is an
|
|
3309
|
+
* inherent limitation of the browser WebSocket API (no custom headers).
|
|
3310
|
+
* Server-side middleware that reads `_header_*` params should strip them from
|
|
3311
|
+
* logs and avoid forwarding them in redirects.
|
|
3312
|
+
*
|
|
3313
|
+
* @param wsUrl The base WebSocket URL (may already contain query parameters)
|
|
3314
|
+
* @param headers The headers provider from CliServerConfig (may include Authorization, etc.)
|
|
3315
|
+
* @returns The WebSocket URL with auth credentials appended as query parameters
|
|
3316
|
+
*/
|
|
3317
|
+
declare function buildAuthenticatedWebSocketUrl(wsUrl: string, headers?: CliHeadersProvider): string;
|
|
3318
|
+
/**
|
|
3319
|
+
* Build the WebSocket URL for a configured server. Prefers upgrade params
|
|
3320
|
+
* from auth providers (e.g. a single-use ticket from the users module); only
|
|
3321
|
+
* when no provider handles the server are headers copied into the URL
|
|
3322
|
+
* (legacy behaviour, see {@link buildAuthenticatedWebSocketUrl}).
|
|
3323
|
+
*/
|
|
3324
|
+
declare function resolveServerWebSocketUrl(services: ICliServiceProvider | undefined, serverName: string, wsUrl: string, configHeaders?: CliHeadersProvider): Promise<string>;
|
|
3325
|
+
/** Append query params to a URL that may already have some. */
|
|
3326
|
+
declare function appendQueryParams(url: string, params: Record<string, string>): string;
|
|
3327
|
+
|
|
2606
3328
|
/**
|
|
2607
3329
|
* Derives CLI panel CSS custom property values from an xterm ITheme object.
|
|
2608
3330
|
* Used when `syncTheme` is enabled on the panel config.
|
|
@@ -2643,13 +3365,93 @@ declare function nextPanelPosition(current: CliPanelPosition): CliPanelPosition;
|
|
|
2643
3365
|
*/
|
|
2644
3366
|
declare function stripAnsi(text: string): string;
|
|
2645
3367
|
/**
|
|
2646
|
-
* Return the visible
|
|
2647
|
-
*
|
|
3368
|
+
* Return the visible (display) width of a string in terminal columns,
|
|
3369
|
+
* ignoring ANSI escape codes and accounting for wide characters (emoji,
|
|
3370
|
+
* East Asian fullwidth, etc.) that occupy two columns.
|
|
2648
3371
|
* @param text The text potentially containing ANSI codes
|
|
2649
|
-
* @returns The number of
|
|
3372
|
+
* @returns The number of terminal columns the text occupies
|
|
2650
3373
|
*/
|
|
2651
3374
|
declare function visibleLength(text: string): number;
|
|
2652
3375
|
|
|
3376
|
+
/**
|
|
3377
|
+
* Permission strings are `resource:action` (for example `users:create`).
|
|
3378
|
+
* A trailing `*` segment matches anything at that level and below; a `*`
|
|
3379
|
+
* in any other position matches exactly one segment:
|
|
3380
|
+
*
|
|
3381
|
+
* | granted | matches |
|
|
3382
|
+
* |---------------|---------------------------------------|
|
|
3383
|
+
* | `*` | every permission |
|
|
3384
|
+
* | `users:*` | `users:create`, `users:delete`, ... |
|
|
3385
|
+
* | `*:read` | `users:read`, `groups:read`, ... |
|
|
3386
|
+
* | `users:read` | only `users:read` |
|
|
3387
|
+
*
|
|
3388
|
+
* Matching is case-insensitive.
|
|
3389
|
+
*/
|
|
3390
|
+
declare function cliPermissionMatches(granted: string, required: string): boolean;
|
|
3391
|
+
/** True when any granted permission matches `required`. */
|
|
3392
|
+
declare function cliHasPermission(granted: readonly string[] | undefined, required: string): boolean;
|
|
3393
|
+
/** The subset of `required` permissions not covered by `granted`. */
|
|
3394
|
+
declare function cliMissingPermissions(granted: readonly string[] | undefined, required: readonly string[]): string[];
|
|
3395
|
+
/** Union of permissions, de-duplicated, preserving first-seen order. */
|
|
3396
|
+
declare function cliMergePermissions(...lists: (readonly string[] | undefined)[]): string[];
|
|
3397
|
+
/**
|
|
3398
|
+
* Built-in permissions used by the users module. Other modules define their
|
|
3399
|
+
* own (e.g. `deploy:run`); any string in `resource:action` form works.
|
|
3400
|
+
*/
|
|
3401
|
+
/** Permissions for remote CLI server features. */
|
|
3402
|
+
declare const CliServerPermissions: {
|
|
3403
|
+
/** Open a remote shell on a server (`ssh`) */
|
|
3404
|
+
readonly ShellExecute: "shell:execute";
|
|
3405
|
+
};
|
|
3406
|
+
declare const CliUsersPermissions: {
|
|
3407
|
+
readonly UsersRead: "users:read";
|
|
3408
|
+
readonly UsersCreate: "users:create";
|
|
3409
|
+
readonly UsersUpdate: "users:update";
|
|
3410
|
+
readonly UsersDelete: "users:delete";
|
|
3411
|
+
readonly GroupsRead: "groups:read";
|
|
3412
|
+
readonly GroupsCreate: "groups:create";
|
|
3413
|
+
readonly GroupsUpdate: "groups:update";
|
|
3414
|
+
readonly GroupsDelete: "groups:delete";
|
|
3415
|
+
readonly SessionsRead: "sessions:read";
|
|
3416
|
+
readonly SessionsRevoke: "sessions:revoke";
|
|
3417
|
+
readonly AuditRead: "audit:read";
|
|
3418
|
+
readonly AuditClear: "audit:clear";
|
|
3419
|
+
};
|
|
3420
|
+
|
|
3421
|
+
/**
|
|
3422
|
+
* `metadata.requireAuth` (also implied by `requiredGroups` /
|
|
3423
|
+
* `requiredPermissions`): the command needs a signed-in principal.
|
|
3424
|
+
* Active only when an {@link ICliAuthorizationService} is registered.
|
|
3425
|
+
*/
|
|
3426
|
+
declare const cliRequireAuthGuard: ICliCommandGuard;
|
|
3427
|
+
/**
|
|
3428
|
+
* `metadata.requiredGroups`: the principal must belong to at least one group.
|
|
3429
|
+
* Active only when an {@link ICliAuthorizationService} is registered.
|
|
3430
|
+
*/
|
|
3431
|
+
declare const cliRequiredGroupsGuard: ICliCommandGuard;
|
|
3432
|
+
/**
|
|
3433
|
+
* `metadata.requiredPermissions`: the principal must hold all permissions.
|
|
3434
|
+
* Active only when an {@link ICliAuthorizationService} is registered.
|
|
3435
|
+
*/
|
|
3436
|
+
declare const cliRequiredPermissionsGuard: ICliCommandGuard;
|
|
3437
|
+
/**
|
|
3438
|
+
* Guards enforcing access metadata on processors. Registered by the CLI
|
|
3439
|
+
* engine; they do nothing until an auth module registers an
|
|
3440
|
+
* {@link ICliAuthorizationService}.
|
|
3441
|
+
*/
|
|
3442
|
+
declare const cliAccessMetadataGuards: ICliCommandGuard[];
|
|
3443
|
+
|
|
3444
|
+
/**
|
|
3445
|
+
* The server a command should use when the user does not name one.
|
|
3446
|
+
*
|
|
3447
|
+
* Prefers the server manager's choice (the default server, else the first
|
|
3448
|
+
* connected one) so a command does not pick a server that is down or that
|
|
3449
|
+
* rejects the user (a protected server they have not signed in to). Falls
|
|
3450
|
+
* back to the first configured server when no manager is available or
|
|
3451
|
+
* nothing is connected, so callers still get a clear error from that server.
|
|
3452
|
+
*/
|
|
3453
|
+
declare function cliDefaultServer(context: Pick<ICliExecutionContext, 'services' | 'options'>): CliServerConfig | undefined;
|
|
3454
|
+
|
|
2653
3455
|
/**
|
|
2654
3456
|
* Retrieve a parameter's value from the parsed arguments, checking aliases.
|
|
2655
3457
|
* @param p The parameter descriptor
|
|
@@ -2802,7 +3604,7 @@ interface CliThemeInfo {
|
|
|
2802
3604
|
|
|
2803
3605
|
declare const DefaultThemeInfos: Record<string, CliThemeInfo>;
|
|
2804
3606
|
|
|
2805
|
-
declare const LIBRARY_VERSION = "2.0.0-beta.
|
|
3607
|
+
declare const LIBRARY_VERSION = "2.0.0-beta.14";
|
|
2806
3608
|
declare const API_VERSION = 2;
|
|
2807
3609
|
|
|
2808
3610
|
/**
|
|
@@ -2863,4 +3665,4 @@ declare class BrowserFileTransferService implements ICliFileTransferService {
|
|
|
2863
3665
|
private _pickFile;
|
|
2864
3666
|
}
|
|
2865
3667
|
|
|
2866
|
-
export { API_VERSION, BrowserFileTransferService, CANCELLATION_ERROR_MESSAGE, CLI_CONFIGURE_STORE_NAME, CancellablePromise, type CliAddUser, CliBackgroundColor, type CliBackgroundServiceStatus, type CliBackgroundServiceType, type CliDateOptions, type CliEngineSnapshot, type CliFactoryProvider, type CliFilePickerOptions, type CliFileResult, CliForegroundColor, type CliFullScreenOptions, CliIcon, type CliLineOptions, CliLogLevel, CliModuleRegistry, type CliMultiSelectOption, type CliMultiSelectOptions, type CliNumberOptions, type CliOptions, type CliPackageSource, type CliPanelConfig, type CliPanelHideAlignment, type CliPanelPaneState, type CliPanelPosition, type CliPanelState, type CliPanelTabState, type CliPercentageProgressBarUpdateValueOptions, type CliProcessCommand, type CliProcessorMetadata, type CliProvider, type CliSelectOption, type CliSelectOptions, type CliServerCapabilities, type CliServerCommandDescriptor, type CliServerConfig, type CliServerOutput, type CliServerResponse, type CliServiceEventHandler, type CliServiceExecutionMode, type CliServiceLogLevel, type CliState, type CliStateConfiguration, type CliTableOptions, type CliTextAnimatorOptions, type CliTheme, type CliThemeCategory, type CliThemeInfo, type CliTypeProvider, type CliUpdateUser, type CliValueProvider, type CliWorkerInboundMessage, type CliWorkerOutboundMessage, DEFAULT_DIR_PERMISSIONS, DEFAULT_FILE_PERMISSIONS, DefaultLibraryAuthor, DefaultThemeInfos, DefaultThemes, type DefaultThemesType, type ICliAuthService, ICliAuthService_TOKEN, type ICliBackgroundService, type ICliBackgroundServiceInfo, type ICliBackgroundServiceRegistry, type ICliClipboard, type ICliCommandAuthor, type ICliCommandChildProcessor, type ICliCommandExecutorService, type ICliCommandParameterDescriptor, type ICliCommandProcessor, type ICliCommandProcessorRegistry, type ICliCompletionContext, type ICliCompletionProvider, ICliCompletionProvider_TOKEN, type ICliConfigurableModule, type ICliConfigurationOption, type ICliDragDropService, ICliDragDropService_TOKEN, type ICliExecutionContext, type ICliExecutionProcess, type ICliFileEntry, type ICliFilePickerProvider, ICliFilePickerProvider_TOKEN, type ICliFileTransferService, ICliFileTransferService_TOKEN, type ICliGlobalParameterHandler, type ICliGroup, type ICliGroupsStoreService, ICliGroupsStoreService_TOKEN, type ICliInputReader, type ICliKeyValueStore, type ICliLogger, type ICliManagedInterval, type ICliManagedTimer, type ICliModule, type ICliOwnership, type ICliPanelRef, type ICliPercentageProgressBar, type ICliPermissionService, ICliPermissionService_TOKEN, type ICliPingServerService, type ICliProcessEntry, type ICliProcessRegisterOptions, type ICliProcessRegistry, type ICliProcessorHook, type ICliProgressBar, type ICliServiceContext, type ICliServiceEvent, type ICliServiceLogEntry, type ICliServiceProvider, type ICliSpinner, type ICliStateStore, type ICliTerminalWriter, type ICliTextAnimator, type ICliTranslationService, ICliTranslationService_TOKEN, type ICliUmdModule, type ICliUser, type ICliUserCredentials, type ICliUserSession, type ICliUserSessionService, ICliUserSessionService_TOKEN, type ICliUsersStoreService, ICliUsersStoreService_TOKEN, type ISyntaxHighlightRule, type ISyntaxHighlighter, type ISyntaxTheme, LIBRARY_VERSION, type LineState, ObjectDescriber, type Package, type ServerVersionInfo, ServerVersionNegotiator, type WorkerServiceContext, bootCliModule, bootUmdModule, clearTerminalLine, colorFirstWord, colorizeJson, compareVersions, constants, createWorkerService, delay, derivePanelThemeStyles, enums, formatJson, getConfigValue, getParameterValue, getPluginConfigValue, getRightOfWord, highlightTextWithBg, initializeBrowserEnvironment, loadPanelPosition, nextPanelPosition, resolveConfigurationCategories, satisfiesMinVersion, satisfiesVersionRange, savePanelPosition, stripAnsi, toQueryString, utils, visibleLength };
|
|
3668
|
+
export { API_VERSION, BrowserFileTransferService, CANCELLATION_ERROR_MESSAGE, CLI_CONFIGURE_STORE_NAME, CancellablePromise, type CliAccessAction, CliAccessDeniedError, type CliAddUser, CliBackgroundColor, type CliBackgroundServiceStatus, type CliBackgroundServiceType, type CliCommandGuardResult, type CliDateOptions, type CliEngineSnapshot, type CliFactoryProvider, type CliFilePickerOptions, type CliFileResult, CliForegroundColor, type CliFullScreenOptions, type CliHeadersProvider, CliHttpError, type CliHttpRequestOptions, CliIcon, type CliLineOptions, CliLogLevel, CliModuleRegistry, type CliMultiSelectOption, type CliMultiSelectOptions, type CliNotification, type CliNotificationLevel, type CliNumberOptions, type CliOptions, type CliPackageSource, type CliPanelConfig, type CliPanelHideAlignment, type CliPanelPaneState, type CliPanelPosition, type CliPanelState, type CliPanelTabState, type CliPercentageProgressBarUpdateValueOptions, type CliPermissionDefinition, type CliProcessCommand, type CliProcessorMetadata, type CliProvider, type CliSelectOption, type CliSelectOptions, type CliServerCapabilities, type CliServerCommandDescriptor, type CliServerConfig, type CliServerOutput, CliServerPermissions, type CliServerResponse, type CliServiceEventHandler, type CliServiceExecutionMode, type CliServiceLogLevel, type CliState, type CliStateConfiguration, type CliTableOptions, type CliTextAnimatorOptions, type CliTheme, type CliThemeCategory, type CliThemeInfo, type CliTypeProvider, type CliUpdateUser, CliUsersPermissions, type CliValueProvider, type CliWorkerInboundMessage, type CliWorkerOutboundMessage, DEFAULT_DIR_PERMISSIONS, DEFAULT_FILE_PERMISSIONS, DefaultLibraryAuthor, DefaultThemeInfos, DefaultThemes, type DefaultThemesType, type ICliAuditEntry, type ICliAuditService, ICliAuditService_TOKEN, type ICliAuthService, ICliAuthService_TOKEN, type ICliAuthorizationService, ICliAuthorizationService_TOKEN, type ICliBackgroundService, type ICliBackgroundServiceInfo, type ICliBackgroundServiceRegistry, type ICliClipboard, type ICliCommandAuthor, type ICliCommandChildProcessor, type ICliCommandExecutorService, type ICliCommandGuard, ICliCommandGuard_TOKEN, type ICliCommandParameterDescriptor, type ICliCommandProcessor, type ICliCommandProcessorRegistry, type ICliCompletionContext, type ICliCompletionProvider, ICliCompletionProvider_TOKEN, type ICliConfigurableModule, type ICliConfigurationOption, type ICliDragDropService, ICliDragDropService_TOKEN, type ICliExecutionContext, type ICliExecutionProcess, type ICliFileEntry, type ICliFilePickerProvider, ICliFilePickerProvider_TOKEN, type ICliFileTransferService, ICliFileTransferService_TOKEN, type ICliGlobalParameterHandler, type ICliGroup, type ICliGroupsStoreService, ICliGroupsStoreService_TOKEN, type ICliHttpClient, ICliHttpClient_TOKEN, type ICliInputReader, type ICliKeyValueStore, ICliKeyValueStore_TOKEN, type ICliLogger, type ICliManagedInterval, type ICliManagedTimer, type ICliModule, type ICliNotifier, type ICliOwnership, type ICliPanelRef, type ICliPercentageProgressBar, type ICliPermissionRegistry, ICliPermissionRegistry_TOKEN, type ICliPermissionService, ICliPermissionService_TOKEN, type ICliPingServerService, type ICliPrincipal, type ICliProcessEntry, type ICliProcessRegisterOptions, type ICliProcessRegistry, type ICliProcessorHook, type ICliProgressBar, type ICliProtectedResource, type ICliServerAuthService, ICliServerAuthService_TOKEN, type ICliServerAuthTokenProvider, ICliServerAuthTokenProvider_TOKEN, type ICliServerManager, ICliServerManager_TOKEN, type ICliServiceContext, type ICliServiceEvent, type ICliServiceLogEntry, type ICliServiceProvider, type ICliSessionInfo, type ICliSessionsService, ICliSessionsService_TOKEN, type ICliSpinner, type ICliStateStore, type ICliTerminalWriter, type ICliTextAnimator, type ICliTranslationService, ICliTranslationService_TOKEN, type ICliUmdModule, type ICliUser, type ICliUserCredentials, type ICliUserEvent, type ICliUserEventService, ICliUserEventService_TOKEN, type ICliUserSession, type ICliUserSessionService, ICliUserSessionService_TOKEN, type ICliUsersStoreService, ICliUsersStoreService_TOKEN, type ISyntaxHighlightRule, type ISyntaxHighlighter, type ISyntaxTheme, LIBRARY_VERSION, type LineState, ObjectDescriber, type Package, type ServerVersionInfo, ServerVersionNegotiator, type WorkerServiceContext, appendQueryParams, bootCliModule, bootUmdModule, buildAuthenticatedWebSocketUrl, clearTerminalLine, cliAccessMetadataGuards, cliAuthorize, cliCanAccess, cliDefaultServer, cliEvaluateAccess, cliHasPermission, cliMergePermissions, cliMissingPermissions, cliPermissionMatches, cliRequireAuthGuard, cliRequiredGroupsGuard, cliRequiredPermissionsGuard, colorFirstWord, colorizeJson, compareVersions, constants, createWorkerService, delay, derivePanelThemeStyles, enums, formatJson, getConfigValue, getParameterValue, getPluginConfigValue, getRightOfWord, highlightTextWithBg, initializeBrowserEnvironment, isCliAccessDeniedError, loadPanelPosition, nextPanelPosition, resolveConfigurationCategories, resolveHeaders, resolveServerHeaders, resolveServerWebSocketUrl, satisfiesMinVersion, satisfiesVersionRange, savePanelPosition, stripAnsi, toQueryString, utils, visibleLength };
|