@gravity-rail/cli 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib.d.ts ADDED
@@ -0,0 +1,439 @@
1
+ import { GravityRailClient } from '@gravity-rail/sdk';
2
+ import { E as EnvironmentConfig, C as CredentialsManager } from './auth-DBspA1Dh.js';
3
+
4
+ /** Metadata extracted from a paginated API response */
5
+ interface PaginationMeta {
6
+ /** Total number of items across all pages (page-based only) */
7
+ total?: number;
8
+ /** Current page number (page-based only) */
9
+ page?: number;
10
+ /** Total pages (page-based only) */
11
+ totalPages?: number;
12
+ /** Whether more pages exist (cursor-based only) */
13
+ hasMore?: boolean;
14
+ /** Cursor for next page (cursor-based only) */
15
+ nextCursor?: string;
16
+ }
17
+ /** Explicit pagination contract passed from commands to outputData */
18
+ interface ListResult {
19
+ items: unknown[];
20
+ meta?: PaginationMeta;
21
+ supportsAll?: boolean;
22
+ }
23
+ /** Type guard: is the value a ListResult (explicit contract)? */
24
+ declare function isListResult(data: unknown): data is ListResult;
25
+ /** Check if a response looks like a page-based paginated envelope.
26
+ * Matches both `{ items, total, totalPages, page }` (standard) and
27
+ * `{ items, total, page, pageSize }` (legacy — e.g. InvitationListResponse,
28
+ * InquiryListResponse). This is a pure type guard with no side effects;
29
+ * totalPages computation for legacy shapes happens in extractPaginationMeta. */
30
+ declare function isPagePaginatedResponse(data: unknown): data is {
31
+ items: unknown[];
32
+ total: number;
33
+ page: number;
34
+ totalPages?: number;
35
+ pageSize?: number;
36
+ };
37
+ /** Check if a response looks like a cursor-based paginated envelope */
38
+ declare function isCursorPaginatedResponse(data: unknown): data is {
39
+ items: unknown[];
40
+ hasMore: boolean;
41
+ nextCursor?: string;
42
+ };
43
+ /** Check if a response is any paginated envelope ({ items: [...], ... }) */
44
+ declare function isPaginatedResponse(data: unknown): boolean;
45
+ /** Extract pagination metadata from a response, or return undefined for non-paginated responses.
46
+ * For legacy shapes without totalPages, computes it from total/pageSize. */
47
+ declare function extractPaginationMeta(data: unknown): PaginationMeta | undefined;
48
+ /** Format a pagination warning for stderr. Returns undefined if no warning needed.
49
+ * When `supportsAll` is false, the "Use --all" hint is omitted because the
50
+ * command does not actually expose the --all flag. */
51
+ declare function formatPaginationWarning(meta: PaginationMeta | undefined, supportsAll?: boolean): string | undefined;
52
+ /** Unwrap items from a paginated response or return the data as-is if it's an array */
53
+ declare function unwrapItems(data: unknown): unknown[];
54
+ /** Default pagination args for list commands (page, page-size, all). No search. */
55
+ declare const LIST_PAGINATION_ARGS: ArgDef[];
56
+ /** Convert parsed CLI args to API pagination options */
57
+ declare function parsePaginationArgs(args: ParsedArgs): {
58
+ page?: number;
59
+ pageSize?: number;
60
+ all?: boolean;
61
+ };
62
+ /**
63
+ * Fetch all pages from a page-based paginated endpoint.
64
+ * The fetcher receives { page, pageSize } and should return the raw API response.
65
+ * Throws CLIError if MAX_PAGES is reached without exhausting all pages.
66
+ */
67
+ declare function fetchAllPages(fetcher: (opts: {
68
+ page: number;
69
+ pageSize: number;
70
+ }) => Promise<unknown>): Promise<unknown[]>;
71
+ /**
72
+ * Fetch all pages from a cursor-based paginated endpoint.
73
+ * The fetcher receives { cursor? } and should return the raw API response.
74
+ * Throws CLIError if MAX_PAGES is reached without exhausting all pages.
75
+ */
76
+ declare function fetchAllCursorPages(fetcher: (opts: {
77
+ cursor?: string;
78
+ }) => Promise<unknown>): Promise<unknown[]>;
79
+ /**
80
+ * Wrap a raw API response into a ListResult with explicit pagination metadata.
81
+ * Works with both page-based and cursor-based responses, as well as plain arrays.
82
+ *
83
+ * @param data - Raw API response (paginated envelope or plain array)
84
+ * @param supportsAll - Whether the calling command exposes --all
85
+ */
86
+ declare function listResult(data: unknown, supportsAll?: boolean): ListResult;
87
+
88
+ type OutputFormat = 'json' | 'jsonl' | 'table';
89
+ interface OutputOptions {
90
+ outputFormat: OutputFormat;
91
+ }
92
+ interface TableColumn<T> {
93
+ header: string;
94
+ getValue: (item: T) => string;
95
+ maxWidth?: number;
96
+ }
97
+ /** Detect default output format based on whether stdout is a TTY */
98
+ declare function detectOutputFormat(explicit?: string): OutputFormat;
99
+ /**
100
+ * Write a list of items to stdout in the requested format.
101
+ *
102
+ * Accepts:
103
+ * - A `ListResult` (explicit contract with items, meta, supportsAll) — preferred.
104
+ * - Raw arrays, paginated responses ({ items: [...] }), or any object — legacy.
105
+ *
106
+ * When a `ListResult` is passed, its explicit `meta` and `supportsAll` are used.
107
+ * When raw data is passed, pagination metadata is auto-detected with
108
+ * `supportsAll: false` as the safe default.
109
+ *
110
+ * The optional `paginationMeta` and `supportsAll` parameters are kept for
111
+ * backward compatibility but are ignored when a `ListResult` is passed.
112
+ */
113
+ declare function outputData(data: unknown, opts: OutputOptions, columns?: TableColumn<any>[], paginationMeta?: PaginationMeta, supportsAll?: boolean): void;
114
+ /** Write a single object to stdout in the requested format */
115
+ declare function outputSingle<T>(data: T, opts: OutputOptions, columns?: TableColumn<T>[]): void;
116
+ /** Common column factory helpers for domain files */
117
+ declare const COL: {
118
+ id: () => TableColumn<any>;
119
+ uuid: () => TableColumn<any>;
120
+ name: () => TableColumn<any>;
121
+ status: () => TableColumn<any>;
122
+ created: () => TableColumn<any>;
123
+ updated: () => TableColumn<any>;
124
+ description: () => TableColumn<any>;
125
+ enabled: () => TableColumn<any>;
126
+ };
127
+ /** Write a status/progress message to stderr (never pollutes stdout) */
128
+ declare function stderr(msg: string): void;
129
+
130
+ interface GlobalOptions {
131
+ env: string;
132
+ realm?: string;
133
+ outputFormat?: string;
134
+ verbose?: boolean;
135
+ allowWrite?: boolean;
136
+ }
137
+ interface PublicGlobalOptions {
138
+ apiUrl?: string;
139
+ frontendUrl?: string;
140
+ outputFormat?: string;
141
+ verbose?: boolean;
142
+ allowWrite?: boolean;
143
+ }
144
+ interface CommandContext {
145
+ env: string;
146
+ envConfig: EnvironmentConfig;
147
+ outputFormat: OutputFormat;
148
+ verbose: boolean;
149
+ allowWrite: boolean;
150
+ credentialsManager: CredentialsManager;
151
+ }
152
+ interface AuthenticatedContext extends CommandContext {
153
+ accessToken: string;
154
+ apiClient: GravityRailClient;
155
+ realmWorkspace?: string;
156
+ }
157
+ /** Create a base command context (no auth required) */
158
+ declare function createContext(opts: GlobalOptions): CommandContext;
159
+ /** Create an authenticated command context. Tries realm, env var, then cached token. Never auto-triggers OAuth. */
160
+ declare function createAuthenticatedContext(opts: GlobalOptions): Promise<AuthenticatedContext>;
161
+ /**
162
+ * Narrow a handler context to `AuthenticatedContext`.
163
+ *
164
+ * Handler `ctx` is typed as `AuthenticatedContext | CommandContext` so that
165
+ * `requiresAuth: false` handlers can also share the type. At runtime, every
166
+ * handler that did not opt out of auth will receive an `AuthenticatedContext`,
167
+ * but TypeScript cannot verify this — call this helper before accessing
168
+ * `apiClient` / `accessToken`.
169
+ *
170
+ * Throws if called from a handler that did not declare `requiresAuth`.
171
+ */
172
+ declare function requireAuth(ctx: AuthenticatedContext | CommandContext): AuthenticatedContext;
173
+ /** Create a base command context for the public CLI (no --env flag, defaults to prod) */
174
+ declare function createPublicContext(opts: PublicGlobalOptions): CommandContext;
175
+ /** Create an authenticated context for the public CLI. Tries env var, then cached token. */
176
+ declare function createPublicAuthenticatedContext(opts: PublicGlobalOptions): Promise<AuthenticatedContext>;
177
+
178
+ interface ArgDef {
179
+ name: string;
180
+ alias?: string;
181
+ /** Additional long-form aliases (e.g. ['workspace-id', 'id'] for --wid) */
182
+ aliases?: string[];
183
+ description: string;
184
+ required?: boolean;
185
+ isFlag?: boolean;
186
+ default?: string | boolean;
187
+ }
188
+ type ParsedArgs = Record<string, string | boolean | undefined>;
189
+ /**
190
+ * Context passed to a command handler.
191
+ *
192
+ * `ctx` is a discriminated union of `AuthenticatedContext` and `CommandContext`.
193
+ * Handlers registered without `requiresAuth: false` always receive an
194
+ * `AuthenticatedContext` at runtime, but the type does not express this — call
195
+ * `requireAuth(hctx.ctx)` before accessing `apiClient` / `accessToken` so that
196
+ * a handler missing `requiresAuth: false` cannot silently access undefined
197
+ * fields if it is later miswired.
198
+ */
199
+ interface CommandHandlerContext {
200
+ ctx: AuthenticatedContext | CommandContext;
201
+ args: ParsedArgs;
202
+ workspace: string;
203
+ data?: unknown;
204
+ }
205
+ interface CommandDef<T = unknown> {
206
+ path: string[];
207
+ description: string;
208
+ args?: ArgDef[];
209
+ /** Example usage lines shown in command-level help */
210
+ examples?: string[];
211
+ requiresWorkspace?: boolean;
212
+ requiresAuth?: boolean;
213
+ /** Whether this command mutates data. Requires --allow-write to execute. */
214
+ mutates?: boolean;
215
+ columns?: TableColumn<T>[];
216
+ handler: (hctx: CommandHandlerContext) => Promise<void>;
217
+ }
218
+ interface DomainDef {
219
+ name: string;
220
+ description: string;
221
+ commands: CommandDef[];
222
+ }
223
+ /** Extract a required string arg, throwing if missing or not a string */
224
+ declare function requireString(args: ParsedArgs, key: string): string;
225
+ /** Extract a required numeric arg, throwing if missing */
226
+ declare function requireNumber(args: ParsedArgs, key: string): number;
227
+
228
+ /** Standard pagination args used by admin list commands (includes search).
229
+ * @deprecated Use LIST_PAGINATION_ARGS (page/page-size/all only) plus domain-specific filter args instead. */
230
+ declare const PAGINATION_ARGS: ArgDef[];
231
+ declare function parseArgs(defs: ArgDef[], argv: string[]): ParsedArgs;
232
+
233
+ declare class CLIError extends Error {
234
+ exitCode: number;
235
+ constructor(message: string, exitCode?: number);
236
+ }
237
+ declare class AuthRequiredError extends CLIError {
238
+ constructor(message?: string);
239
+ }
240
+ declare function handleError(err: unknown): never;
241
+
242
+ /** Read JSON input from --data string, --file path, or stdin (if piped) */
243
+ declare function readJsonInput(args: ParsedArgs): Promise<unknown | undefined>;
244
+
245
+ /**
246
+ * @deprecated Use `SimpleCrudConfig` with `simpleCrudCommands()` for new code.
247
+ *
248
+ * This interface uses string method names that are resolved at runtime via
249
+ * dynamic dispatch, which prevents TypeScript from validating call signatures.
250
+ * It is safe for simple top-level CRUD resources but must NOT be used for
251
+ * nested resources that require parent IDs.
252
+ */
253
+ interface CrudConfig<T = unknown> {
254
+ prefix: string[];
255
+ entityName: string;
256
+ listMethod?: string;
257
+ getMethod?: string;
258
+ createMethod?: string;
259
+ updateMethod?: string;
260
+ deleteMethod?: string;
261
+ archiveMethod?: string;
262
+ unarchiveMethod?: string;
263
+ /** When true, adds a --cascade flag to the delete command. Only enable for entities whose backend endpoint accepts a cascade parameter. */
264
+ supportsCascade?: boolean;
265
+ columns?: TableColumn<T>[];
266
+ requiresWorkspace?: boolean;
267
+ listArgs?: ArgDef[];
268
+ extra?: CommandDef[];
269
+ /** Example lines shown in help for the create command */
270
+ createExamples?: string[];
271
+ /**
272
+ * Controls how the CRUD list handler interacts with pagination.
273
+ *
274
+ * - `'full'` — The client method accepts an options object with page/pageSize.
275
+ * Pagination args (--page, --page-size, --all) are injected and
276
+ * forwarded to the API method via `callApiWithOptions`.
277
+ * - `'client-only'` — Pagination args are injected for --all support (client-side
278
+ * page-walking), but options are NOT forwarded to the API method.
279
+ * Use for raw-array endpoints that don't accept page/pageSize.
280
+ * - `false` — No pagination args are injected. The list method is called with
281
+ * `callApi` (workspace-only) or `callApiWithOptions` for domain
282
+ * listArgs only. Use for legacy/positional signatures where passing
283
+ * an options object would be misinterpreted.
284
+ *
285
+ * Default: `false` (safe — never forwards pagination options unless opted in).
286
+ */
287
+ paginationSupport?: 'full' | 'client-only' | false;
288
+ }
289
+ /**
290
+ * @deprecated Use `simpleCrudCommands()` for new code — it provides compile-time
291
+ * safety via typed callables instead of string method names.
292
+ *
293
+ * Existing usages are safe for simple top-level CRUD resources. Do NOT use this
294
+ * for nested resources that require parent IDs (workflowId, memberId, toolkitId, etc.).
295
+ */
296
+ declare function crudCommands<T>(config: CrudConfig<T>): CommandDef[];
297
+ /**
298
+ * Typed CRUD config for simple, top-level resources.
299
+ *
300
+ * Unlike the stringly-typed `CrudConfig`, operations are typed functions that
301
+ * receive the real `GravityRailClient`. TypeScript validates the call at the definition
302
+ * site, eliminating the string-dispatch + positional-argument blind spot.
303
+ *
304
+ * Use this for resources that fit the simple CRUD contract:
305
+ * - optional workspace scope
306
+ * - single resource ID (no parent IDs)
307
+ * - optional list-options object
308
+ *
309
+ * For nested resources that need parent IDs, use explicit handlers.
310
+ *
311
+ * @example
312
+ * ```ts
313
+ * simpleCrudCommands({
314
+ * prefix: ['tasks'],
315
+ * entityName: 'task',
316
+ * list: (client, wid) => client.getTasks(wid),
317
+ * get: (client, wid, id) => client.getTask(wid, id),
318
+ * create: (client, wid, data) => client.createTask(wid, data),
319
+ * update: (client, wid, id, data) => client.updateTask(wid, id, data),
320
+ * delete: (client, wid, id) => client.deleteTask(wid, id),
321
+ * })
322
+ * ```
323
+ */
324
+ interface SimpleCrudConfig<T = unknown> {
325
+ prefix: string[];
326
+ entityName: string;
327
+ columns?: TableColumn<T>[];
328
+ requiresWorkspace?: boolean;
329
+ listArgs?: ArgDef[];
330
+ extra?: CommandDef[];
331
+ createExamples?: string[];
332
+ paginationSupport?: 'full' | 'client-only' | false;
333
+ list?: (client: GravityRailClient, workspace: string, opts?: Record<string, unknown>) => Promise<unknown>;
334
+ get?: (client: GravityRailClient, workspace: string, id: string) => Promise<unknown>;
335
+ create?: (client: GravityRailClient, workspace: string, data: unknown) => Promise<unknown>;
336
+ update?: (client: GravityRailClient, workspace: string, id: string, data: unknown) => Promise<unknown>;
337
+ delete?: (client: GravityRailClient, workspace: string, id: string) => Promise<unknown>;
338
+ archive?: (client: GravityRailClient, workspace: string, id: string) => Promise<unknown>;
339
+ unarchive?: (client: GravityRailClient, workspace: string, id: string) => Promise<unknown>;
340
+ /** When true, adds a --cascade flag to the delete command. */
341
+ supportsCascade?: boolean;
342
+ deleteFn?: (client: GravityRailClient, workspace: string, id: string, cascade: boolean) => Promise<unknown>;
343
+ }
344
+ /**
345
+ * Generate CRUD commands from typed callable functions.
346
+ *
347
+ * This is the recommended path for new simple CRUD domains. It provides
348
+ * compile-time safety by accepting typed callables instead of string method names.
349
+ */
350
+ declare function simpleCrudCommands<T>(config: SimpleCrudConfig<T>): CommandDef[];
351
+
352
+ declare class CommandRegistry {
353
+ private commands;
354
+ private domains;
355
+ register(domain: DomainDef): void;
356
+ registerCommand(cmd: CommandDef): void;
357
+ /** Resolve command words to a CommandDef using longest-match.
358
+ * Supports {param} path segments that match any word and extract as pathParams. */
359
+ resolve(words: string[]): {
360
+ cmd: CommandDef;
361
+ rest: string[];
362
+ pathParams: Record<string, string>;
363
+ } | undefined;
364
+ /** Generate help text. If prefix given, show commands under that prefix. */
365
+ getHelp(prefix?: string[]): string;
366
+ private getCommandHelp;
367
+ private getTopLevelHelp;
368
+ }
369
+
370
+ /**
371
+ * Register the full set of public CLI domains on a registry.
372
+ *
373
+ * This file intentionally does NOT import any admin or infrastructure domains
374
+ * (deploy, rollback, railgun, admin/*). Those live in `@gravity-rail/gr-cli`
375
+ * and are layered on top via its own `registerAllDomains`.
376
+ */
377
+ declare function registerPublicDomains(registry: CommandRegistry): void;
378
+
379
+ /**
380
+ * Concierge API client — direct HTTP calls to the global concierge endpoints.
381
+ *
382
+ * The concierge is account-level (no workspace), so these bypass the ApiClient
383
+ * which is workspace-oriented.
384
+ */
385
+
386
+ interface ConciergeChat {
387
+ id: number;
388
+ uuid: string;
389
+ chatType: string;
390
+ title: string | null;
391
+ threadId: string;
392
+ createdAt: string;
393
+ updatedAt: string;
394
+ }
395
+ interface ConciergeMessage {
396
+ id: string;
397
+ role: string;
398
+ content: string;
399
+ createdAt: string | null;
400
+ toolCalls: any[] | null;
401
+ toolCallId: string | null;
402
+ }
403
+ declare function listConciergeChats(ctx: AuthenticatedContext): Promise<ConciergeChat[]>;
404
+ declare function createConciergeChat(ctx: AuthenticatedContext, title?: string): Promise<ConciergeChat>;
405
+ declare function getConciergeChat(ctx: AuthenticatedContext, chatId: number): Promise<ConciergeChat>;
406
+ declare function getConciergeChatMessages(ctx: AuthenticatedContext, chatId: number): Promise<ConciergeMessage[]>;
407
+
408
+ /**
409
+ * Open an authenticated browser session using the CLI's existing credentials.
410
+ *
411
+ * Flow:
412
+ * 1. Get the current account's email from the CLI session
413
+ * 2. Request a magic link via the API (token returned directly since caller is authenticated)
414
+ * 3. Open the magic link URL in the default browser (or print it with --no-open)
415
+ */
416
+ declare function authBrowserCommand(ctx: AuthenticatedContext, args: Record<string, unknown>): Promise<void>;
417
+
418
+ /**
419
+ * Concierge chat command — interactive chat with the global concierge agent.
420
+ *
421
+ * Supports the same modes as workspace manager chat (text, realtime, voice)
422
+ * but without requiring a workspace.
423
+ */
424
+
425
+ declare function conciergeCommand(hctx: CommandHandlerContext): Promise<void>;
426
+
427
+ declare function devImportLocalCommand(ctx: AuthenticatedContext, workspace: string): Promise<void>;
428
+
429
+ declare function loginCommand(ctx: CommandContext): Promise<void>;
430
+ declare function logoutCommand(ctx: CommandContext): Promise<void>;
431
+
432
+ declare function manageCommand(hctx: CommandHandlerContext): Promise<void>;
433
+ declare function chatCommand(hctx: CommandHandlerContext): Promise<void>;
434
+
435
+ declare function organizationsListCommand(ctx: AuthenticatedContext): Promise<void>;
436
+
437
+ declare function whoamiCommand(ctx: AuthenticatedContext): Promise<void>;
438
+
439
+ export { type ArgDef, AuthRequiredError, type AuthenticatedContext, CLIError, COL, type CommandContext, type CommandDef, type CommandHandlerContext, CommandRegistry, type ConciergeChat, type ConciergeMessage, type DomainDef, type GlobalOptions, LIST_PAGINATION_ARGS, type OutputFormat, type OutputOptions, PAGINATION_ARGS, type PaginationMeta, type ParsedArgs, type PublicGlobalOptions, type TableColumn, authBrowserCommand, chatCommand, conciergeCommand, createAuthenticatedContext, createConciergeChat, createContext, createPublicAuthenticatedContext, createPublicContext, crudCommands, detectOutputFormat, devImportLocalCommand, extractPaginationMeta, fetchAllCursorPages, fetchAllPages, formatPaginationWarning, getConciergeChat, getConciergeChatMessages, handleError, isCursorPaginatedResponse, isListResult, isPagePaginatedResponse, isPaginatedResponse, listConciergeChats, listResult, loginCommand, logoutCommand, manageCommand, organizationsListCommand, outputData, outputSingle, parseArgs, parsePaginationArgs, readJsonInput, registerPublicDomains, requireAuth, requireNumber, requireString, simpleCrudCommands, stderr, unwrapItems, whoamiCommand };