@happyvertical/smrt-app-cli 0.51.32 → 0.51.34

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/index.d.ts CHANGED
@@ -1,585 +1,98 @@
1
- import { Server } from '@modelcontextprotocol/server';
2
- import { Writable } from 'node:stream';
3
-
4
- declare type ApiHttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
5
-
6
- export declare interface AppCli {
7
- run(argv: string[]): Promise<void>;
8
- /**
9
- * Wire up the stdio MCP bridge and connect to stdin/stdout. The CLI
10
- * advertises itself to local MCP clients as `serverInfo.name` /
11
- * `.version`. Both fields default from `options.name` (so a brand-
12
- * new app gets `{ name: '<name>-mcp', version: '0.0.0' }`) — pass an
13
- * explicit object to override.
14
- */
15
- startMcpBridge(serverInfo?: {
16
- name?: string;
17
- version?: string;
18
- }): Promise<void>;
19
- }
20
-
21
- export declare interface AppCliCommand {
22
- name: string;
23
- description: string;
24
- /**
25
- * When true, the CLI ensures resources are fetched and available via
26
- * `ctx.getResources()` before `run()` is called. Default `false`.
27
- */
28
- needsResources?: boolean;
29
- run(args: string[], ctx: AppCliContext): Promise<void>;
30
- }
31
-
32
- export declare interface AppCliContext {
33
- config: CliConfig;
34
- serverUrl: string;
35
- token?: string;
36
- /** Lazy resource-list fetch. Cached for the duration of the CLI invocation. */
37
- getResources(): Promise<ResourceListResponse>;
38
- /** Issue a JSON request via the shared client. */
39
- requestJson<T = unknown>(path: string, init?: RequestInit, options?: RequestJsonOptions): Promise<T>;
40
- /** Issue a raw fetch (for streaming / content-type-aware responses). */
41
- request(path: string, init?: RequestInit): Promise<Response>;
42
- stdout: NodeJS.WriteStream;
43
- stderr: NodeJS.WriteStream;
44
- }
45
-
46
- export declare interface AppCliExecutableConfig {
47
- cliOptions: Pick<CreateAppCliOptions, 'name' | 'envPrefix' | 'configDir' | 'defaultServerUrl' | 'requireSecureServerUrl'>;
48
- argv: string[];
49
- mcp?: {
50
- name: string;
51
- version: string;
52
- };
53
- stdioMcp: boolean;
54
- }
55
-
56
- /** Error compatibility wrapper returned by the legacy throwing helper. */
57
- export declare class AppCliRequestError extends Error {
58
- readonly status: number;
59
- readonly metadata: AppCliResultMetadata;
60
- constructor(status: number, metadata: AppCliResultMetadata);
61
- }
62
-
63
- /** Structured metadata preserved for CLI JSON and MCP bridge consumers. */
64
- export declare type AppCliResultMetadata = AppResultMetadata;
65
-
66
- declare interface AppResultContract {
67
- schema: typeof SMRT_APP_RESULT_SCHEMA;
68
- version: typeof SMRT_APP_RESULT_VERSION;
69
- mcpMetadataKey: typeof SMRT_MCP_RESULT_METADATA_KEY;
70
- metadataFields: readonly [
71
- 'code',
72
- 'message',
73
- 'details',
74
- 'retryable',
75
- 'correlationId',
76
- 'idempotencyKey',
77
- 'expectedVersion'
78
- ];
79
- }
80
-
81
- /** Machine-readable metadata shared by HTTP CLI and MCP bridge results. */
82
- declare interface AppResultMetadata {
83
- code: string;
84
- message?: string;
85
- details?: JsonValue;
86
- retryable?: boolean;
87
- correlationId?: string;
88
- idempotencyKey?: DeclaredActionField;
89
- expectedVersion?: DeclaredActionField;
90
- }
91
-
92
- /** Enforce the executable-safe server URL policy without echoing URL values. */
93
- export declare function assertSecureServerUrl(value: string): void;
94
-
95
- export declare function buildFlagParser(schema: Record<string, unknown> | undefined, options?: ParserOptions): BuildParserResult;
96
-
97
- export declare interface BuildParserResult {
98
- /** Parses argv tail (everything after `<cli> <slug> <cmd> [id]`). */
99
- parse(argv: string[], httpMethod: string): ParsedArgs;
100
- /** Status of the underlying schema. */
101
- status: SchemaSupportStatus;
102
- }
103
-
104
- /**
105
- * Build only the URL — exposed for tests.
106
- */
107
- export declare function buildUrl(context: CliConfigContext, resource: CliResource, command: CommandDefinition, parsed: ParsedArgs, id?: string): Promise<string>;
108
-
109
- /**
110
- * Classify a JSONSchema. The CLI uses this to decide between rich flag
111
- * parsing and the positional JSON escape hatch.
112
- */
113
- export declare function classifySchema(schema: Record<string, unknown> | undefined): SchemaSupportStatus;
114
-
115
- /** Remove the token from the config file (e.g. on logout). */
116
- export declare function clearStoredToken(context: CliConfigContext): Promise<void>;
117
-
118
- /** Shape stored on disk in the app's CLI config file. */
119
- export declare interface CliConfig {
120
- /** Issuer selected for the currently configured server. */
121
- credentialIssuer?: string;
122
- serverUrl?: string;
123
- /** Legacy single-token field. Read only when its stored server still matches. */
124
- token?: string;
125
- /** Bearer credentials keyed by their exact issuer identifier. */
126
- tokensByIssuer?: Record<string, string>;
127
- }
128
-
129
- /**
130
- * Configuration for the env-var/config-file resolution chain.
131
- *
132
- * Env vars derived from `envPrefix`:
133
- *
134
- * - `${PREFIX}_SERVER_URL`
135
- * - `${PREFIX}_TOKEN`
136
- * - `${PREFIX}_CLI_CONFIG` (overrides config file path)
137
- */
138
- export declare interface CliConfigContext {
139
- /**
140
- * Uppercase prefix for env vars and the app's namespaced config dir.
141
- * Example: `WILLGRIFFIN` → reads `WILLGRIFFIN_SERVER_URL`, defaults the
142
- * config file to `~/.config/willgriffin/config.json` unless `appSlug`
143
- * overrides the directory name.
144
- */
145
- envPrefix: string;
146
- /** Directory name under `~/.config`. Defaults to lowercased `envPrefix`. */
147
- appSlug?: string;
148
- /** Fallback server URL if neither env nor config sets one. */
149
- defaultServerUrl?: string;
150
- /**
151
- * Require HTTPS for every resolved or request-level server URL, while still
152
- * permitting loopback HTTP for local development.
153
- */
154
- requireSecureServerUrl?: boolean;
155
- }
156
-
157
- export declare type CliResource = CliResource_2;
158
-
159
- declare interface CliResource_2 {
160
- /** Kebab-case identifier; the first positional argument after the CLI name. */
161
- slug: string;
162
- className: string;
163
- qualifiedName?: string;
164
- packageName?: string;
165
- label: string;
166
- /** Collection segment, no leading slash, no `/api` prefix. */
167
- apiPath: string;
168
- commands: CommandDefinition_2[];
169
- }
170
-
171
- export declare type CommandDefinition = CommandDefinition_2;
172
-
173
- declare interface CommandDefinition_2 {
174
- /** Method name in source casing — source of truth for HTTP routing. */
175
- methodName: string;
176
- /** Kebab-case identifier used by the CLI argv parser. */
177
- commandName: string;
178
- kind: CommandKind_2;
179
- scope: CommandScope_2;
180
- httpMethod: ApiHttpMethod;
181
- /** URL path segments after `/<apiPath>[/<id>]/`. May be empty. */
182
- pathSegments: string[];
183
- description?: string;
184
- /** JSONSchema describing the command's argv-flag surface. */
185
- parameters?: Record<string, unknown>;
186
- /** Retry and optimistic-concurrency fields declared by the action schema. */
187
- requirements?: CommandRequirements;
188
- }
189
-
190
- export declare type CommandKind = CommandKind_2;
191
-
192
- declare type CommandKind_2 = 'crud' | 'custom';
193
-
194
- /** Retry and concurrency declarations projected from a command schema. */
195
- declare interface CommandRequirements {
196
- idempotencyKey?: DeclaredActionField;
197
- expectedVersion?: DeclaredActionField;
198
- }
199
-
200
- export declare type CommandScope = CommandScope_2;
201
-
202
- declare type CommandScope_2 = 'item' | 'collection';
203
-
204
- export declare function createAppCli(options: CreateAppCliOptions): AppCli;
205
-
206
- export declare interface CreateAppCliOptions {
207
- /** Display + branding name, e.g. `willgriffin`. Also drives `envPrefix`. */
208
- name: string;
209
- /** Override the env-var prefix. Default: `name.toUpperCase()`. */
210
- envPrefix?: string;
211
- /** Override the config dir slug. Default: `name.toLowerCase()`. */
212
- configDir?: string;
213
- /** Baked-in default server URL when neither env nor config sets one. */
214
- defaultServerUrl?: string;
215
- /** Enforce HTTPS or loopback HTTP for every effective server URL. */
216
- requireSecureServerUrl?: boolean;
217
- /**
218
- * App-specific commands. Dispatched BEFORE built-ins (`auth`,
219
- * `resources`, `mcp`) and before the resource-slug dispatcher, so an
220
- * `extraCommands` entry takes precedence over anything with the same
221
- * top-level argv.
222
- *
223
- * - **Built-in shadowing** (`extraCommands: [{ name: 'mcp' }]`): the CLI
224
- * prints a one-line stderr warning on first invocation. The extra
225
- * command still wins, but the warning makes the override visible.
226
- *
227
- * - **Resource-slug shadowing** (`extraCommands: [{ name: 'praecos' }]`
228
- * when a server-side class also resolves to slug `praecos`): the
229
- * extra command silently wins. There's no warning because checking
230
- * would require a discovery round-trip on every invocation. Authors
231
- * are responsible for namespacing their extra commands (e.g. prefix
232
- * with the app name) to avoid accidental shadowing as the server's
233
- * class registry grows. (#1311 review C-2.)
234
- */
235
- extraCommands?: AppCliCommand[];
236
- }
237
-
238
- /** Build and validate the document hosted at an HTTPS URL used as client_id. */
239
- export declare function createMcpClientIdMetadataDocument(options: McpClientRegistrationOptions): McpClientIdMetadataDocument;
240
-
241
- /**
242
- * Wire up the stdio server. Use `runMcpStdioBridge` for a one-call entry
243
- * point in `bin/` scripts; this lower-level form is exposed for tests.
244
- */
245
- export declare function createMcpStdioBridge(options: McpStdioBridgeOptions): {
246
- server: Server;
247
- connect: () => Promise<void>;
248
- };
249
-
250
- /** A declared input field which controls retry or optimistic-concurrency use. */
251
- declare interface DeclaredActionField {
252
- /** JSON Schema property name supplied by the action. */
253
- field: string;
254
- /** Whether the action marks the field required. */
255
- required: boolean;
256
- }
257
-
258
- declare interface DiscoveryArtifactIntegrity {
259
- algorithm: 'sha256';
260
- /** `sha256:<lowercase-hex>` over canonical unsigned artifact JSON. */
261
- digest: string;
262
- }
263
-
264
- /** Versioned payload a consumer can validate and pin. */
265
- declare interface DiscoveryConformanceArtifact {
266
- schema: typeof SMRT_DISCOVERY_CONFORMANCE_SCHEMA;
267
- version: typeof SMRT_DISCOVERY_CONFORMANCE_VERSION;
268
- discovery: DiscoveryPayload;
269
- resultContract: AppResultContract;
270
- integrity: DiscoveryArtifactIntegrity;
271
- }
272
-
273
- /** The pre-artifact wire payload, kept for the existing `/_resources` fields. */
274
- declare type DiscoveryPayload = Omit<ResourceListResponseBody, 'artifact'>;
275
-
276
- /**
277
- * Fetch the discovery payload.
278
- *
279
- * Translates a 401 into a friendlier error so the CLI can prompt the
280
- * user to log in rather than dumping a raw HTTP error.
281
- */
282
- export declare function fetchResourceList(context: CliConfigContext, options?: FetchResourceListOptions): Promise<ResourceListResponse>;
283
-
284
- declare interface FetchResourceListOptions {
285
- /** Endpoint path on the server. Default `/api/_resources`. */
286
- path?: string;
287
- /** Custom fetch (tests). */
288
- fetch?: typeof fetch;
289
- /** When true, the request fails if no token is available. */
290
- requireAuth?: boolean;
291
- /**
292
- * Pre-loaded config to avoid re-reading from disk. Set by
293
- * `buildAppContext`, which has already loaded it. (#1311 review P2.)
294
- */
295
- loadedConfig?: CliConfig;
296
- }
297
-
298
- /**
299
- * Find a command on a resource by its CLI-facing name. Returns
300
- * `undefined` if not found.
301
- */
302
- export declare function findCommand(resource: CliResource, commandName: string): CommandDefinition | undefined;
303
-
304
- /**
305
- * Find a resource by slug in the discovery payload. Returns `undefined`
306
- * if the slug isn't present.
307
- */
308
- export declare function findResourceBySlug(response: ResourceListResponse, slug: string): CliResource | undefined;
309
-
310
- /** Resolve the server URL: env var → config file → `defaultServerUrl`. */
311
- export declare function getServerUrl(context: CliConfigContext, config?: CliConfig): Promise<string>;
312
-
313
- /** Resolve a bearer token only when it is bound to the exact target server. */
314
- export declare function getStoredToken(context: CliConfigContext, config?: CliConfig, serverUrl?: string): Promise<string | undefined>;
315
-
316
- /**
317
- * Build the URL the CLI should hit for this command, plus the fetch init
318
- * (headers, body) it should pass. Returns enough so callers can stream
319
- * the response — they decide how to render it (see `output.ts`).
320
- */
321
- export declare function invokeCommand(options: InvokeOptions): Promise<Response>;
322
-
323
- declare interface InvokeOptions {
324
- context: CliConfigContext;
325
- resource: CliResource;
326
- command: CommandDefinition;
327
- parsed: ParsedArgs;
328
- /** Positional `<id>` argument — only meaningful for item-scope commands. */
329
- id?: string;
330
- /** Custom fetch (tests). */
331
- fetch?: typeof fetch;
332
- }
333
-
334
- /** JSON-safe value used by structured details and parameter schemas. */
335
- declare type JsonValue = null | boolean | number | string | JsonValue[] | {
336
- [key: string]: JsonValue;
337
- };
338
-
339
- /** Read the CLI config file. Missing file → empty config. */
340
- export declare function loadCliConfig(context: CliConfigContext): Promise<CliConfig>;
341
-
342
- export declare interface McpClientIdMetadataDocument {
343
- application_type: OAuthApplicationType;
344
- client_id: string;
345
- client_name: string;
346
- grant_types: ['authorization_code'];
347
- redirect_uris: string[];
348
- response_types: ['code'];
349
- token_endpoint_auth_method: 'none';
350
- }
351
-
352
- export declare type McpClientRegistration = {
353
- clientId: string;
354
- kind: 'client_id_metadata_document';
355
- metadataDocument: McpClientIdMetadataDocument;
356
- } | {
357
- endpoint: string;
358
- kind: 'dynamic_client_registration';
359
- request: Omit<McpClientIdMetadataDocument, 'client_id'>;
360
- };
361
-
362
- export declare interface McpClientRegistrationOptions {
363
- applicationType: OAuthApplicationType;
364
- /** HTTPS metadata-document URL. Required only when CIMD is advertised. */
365
- clientId?: string;
366
- clientName: string;
367
- redirectUris: string[];
368
- }
369
-
370
- export declare interface McpRegisteredClient {
371
- clientId: string;
372
- kind: McpClientRegistration['kind'];
373
- metadataDocument?: McpClientIdMetadataDocument;
374
- registrationResponse?: Record<string, unknown>;
375
- }
376
-
377
- /**
378
- * Configuration for the bridge.
379
- *
380
- * Combines the {@link CliConfigContext} (env var + config file resolution)
381
- * with the local MCP server identity the bridge advertises to clients.
382
- */
383
- export declare interface McpStdioBridgeOptions extends CliConfigContext {
384
- /** MCP server identity advertised to local clients. */
385
- serverInfo: {
386
- name: string;
387
- version: string;
388
- };
389
- /** Override the tools endpoint path. Defaults to `/api/mcp/tools`. */
390
- toolsPath?: string;
391
- /** Override the call endpoint path. Defaults to `/api/mcp/call`. */
392
- callPath?: string;
393
- /**
394
- * Override fetch implementation (used by tests so we never hit the network).
395
- */
396
- fetch?: typeof fetch;
397
- }
398
-
399
- /** MCP OAuth client-registration helpers for remote HTTP deployments. */
400
- export declare type OAuthApplicationType = 'native' | 'web';
401
-
402
- export declare interface OAuthAuthorizationServerMetadata {
403
- client_id_metadata_document_supported?: boolean;
404
- registration_endpoint?: string;
405
- }
406
-
407
- declare interface OutputOptions {
408
- stdout?: NodeJS.WriteStream | Writable;
409
- stderr?: NodeJS.WriteStream | Writable;
410
- /**
411
- * Override the TTY detection (tests). Defaults to `stdout.isTTY`.
412
- */
413
- stdoutIsTty?: boolean;
414
- }
415
-
416
- /** Parse and validate the generic executable's non-secret configuration. */
417
- export declare function parseAppCliExecutableConfig(argv: string[], env?: NodeJS.ProcessEnv): AppCliExecutableConfig;
418
-
419
- export declare interface ParsedArgs {
420
- /** Body to send (JSON serialised, for POST/PUT/PATCH). May be empty. */
421
- body: Record<string, unknown>;
422
- /** Query string parameters (for GET). May be empty. */
423
- query: Record<string, string | string[]>;
424
- /** True when the user passed a positional `'<json>'` payload — body is that. */
425
- fromPositional: boolean;
426
- }
427
-
428
- declare interface ParserOptions {
429
- /** Force-treat schema as unsupported (caller already detected unsupportedness). */
430
- positionalOnly?: boolean;
431
- }
432
-
433
- /** Redact conventional credential fields before emitting transport metadata. */
434
- export declare function redactTransportValue(value: unknown): unknown;
435
-
436
- /**
437
- * Complete client registration against discovered authorization-server
438
- * metadata. A Client ID Metadata Document needs no registration request: the
439
- * authorization server retrieves it from the HTTPS client_id. The legacy DCR
440
- * fallback is executed as an RFC 7591 JSON POST.
441
- */
442
- export declare function registerMcpClient(authorizationServer: OAuthAuthorizationServerMetadata, options: McpClientRegistrationOptions, fetchImpl?: typeof fetch): Promise<McpRegisteredClient>;
443
-
444
- /**
445
- * Render the response. Returns the desired exit code.
446
- */
447
- export declare function renderResponse(response: Response, options?: OutputOptions): Promise<RenderResult>;
448
-
449
- export declare interface RenderResult {
450
- exitCode: number;
451
- }
452
-
453
- /**
454
- * JSON request helper that injects the stored bearer token. Returns the
455
- * parsed JSON body on success; throws an `Error` with the server's `error`
456
- * field (or `HTTP <status>`) on failure.
457
- */
458
- export declare function requestJson<T = unknown>(context: CliConfigContext, path: string, init?: RequestInit, options?: RequestJsonOptions): Promise<T>;
459
-
460
- declare interface RequestJsonFailure {
461
- ok: false;
462
- status: number;
463
- error: AppCliResultMetadata;
464
- }
465
-
466
- /** Options for `requestJson`. */
467
- export declare interface RequestJsonOptions {
468
- /**
469
- * When false, skip sending the Authorization header even if a token is
470
- * present. Defaults to true.
471
- */
472
- auth?: boolean;
473
- /**
474
- * When true, throw if no token is available and `auth` is not false.
475
- * Defaults to false.
476
- */
477
- requireAuth?: boolean;
478
- /** Override the server URL for this request. */
479
- serverUrl?: string;
480
- /** Override the fetch implementation (tests). */
481
- fetch?: typeof fetch;
482
- /**
483
- * Cap on response body size in bytes. The CLI buffers the full body
484
- * before JSON-parsing, so without this cap a misbehaving or malicious
485
- * server could OOM the CLI process with a multi-GB payload (auth and
486
- * discovery both use this code path). Defaults to 10MB — large enough
487
- * for any sensible discovery response, small enough that overflow is
488
- * a clear signal something's wrong. Pass `Infinity` to disable.
489
- * (#1311 review A4.)
490
- */
491
- maxResponseBytes?: number;
492
- /**
493
- * Pre-loaded config to avoid re-reading from disk. Set by callers that
494
- * already have it (e.g. `buildAppContext`); leave undefined for the
495
- * default behavior of loading per-call. (#1311 review P2.)
496
- */
497
- loadedConfig?: CliConfig;
498
- }
499
-
500
- /** Generic result/error envelope for a JSON request. */
501
- export declare type RequestJsonResult<T> = RequestJsonSuccess<T> | RequestJsonFailure;
502
-
503
- /**
504
- * Issue a JSON request without flattening a failure to an Error message.
505
- *
506
- * Metadata is deliberately copied only from conventional result/error fields
507
- * and response headers. Every value crossing this boundary is redacted before
508
- * a CLI or MCP client can observe it.
509
- */
510
- export declare function requestJsonResult<T = unknown>(context: CliConfigContext, path: string, init?: RequestInit, options?: RequestJsonOptions): Promise<RequestJsonResult<T>>;
511
-
512
- declare interface RequestJsonSuccess<T> {
513
- ok: true;
514
- result: T;
515
- metadata: AppCliResultMetadata;
516
- }
517
-
518
- /**
519
- * Select registration in MCP priority order: Client ID Metadata Documents
520
- * first, then RFC 7591 DCR as a compatibility fallback.
521
- */
522
- export declare function resolveMcpClientRegistration(authorizationServer: OAuthAuthorizationServerMetadata, options: McpClientRegistrationOptions): McpClientRegistration;
523
-
524
- export declare type ResourceListResponse = ResourceListResponseBody;
525
-
526
- declare interface ResourceListResponseBody {
527
- user: {
528
- authenticated: boolean;
529
- id?: string;
530
- };
531
- warnings: string[];
532
- resources: CliResource_2[];
533
- /** Versioned deterministic artifact for consumers that integrity-pin discovery. */
534
- artifact?: DiscoveryConformanceArtifact;
535
- }
536
-
537
- /** Create the canonical app CLI and execute its forwarded command or bridge. */
538
- export declare function runAppCliExecutable(options?: RunAppCliExecutableOptions): Promise<void>;
539
-
540
- export declare interface RunAppCliExecutableOptions {
541
- argv?: string[];
542
- env?: NodeJS.ProcessEnv;
543
- createCli?: (options: CreateAppCliOptions) => AppCli;
544
- }
545
-
546
- /**
547
- * One-call entry point — start the factory-owned stdio bridge. The returned
548
- * promise resolves once the stdio listener is installed.
549
- */
550
- export declare function runMcpStdioBridge(options: McpStdioBridgeOptions): Promise<void>;
551
-
552
- /** Persist a login with the bearer token keyed by its exact issuer. */
553
- export declare function saveAuth(context: CliConfigContext, serverUrl: string, token: string, issuer?: string): Promise<void>;
554
-
555
- /**
556
- * Write the CLI config to disk with 0600 permissions (the token is a bearer
557
- * credential — anyone who can read the file can impersonate the user).
558
- */
559
- export declare function saveCliConfig(context: CliConfigContext, config: CliConfig): Promise<void>;
560
-
561
- export declare type SchemaSupportStatus = {
562
- kind: 'ok';
563
- } | {
564
- kind: 'unsupported';
565
- reason: string;
566
- } | {
567
- kind: 'missing';
568
- };
569
-
570
- /** Versioned selector for structured application results and errors. */
571
- declare const SMRT_APP_RESULT_SCHEMA = "https://smrt.dev/schemas/app-result/v1";
572
-
573
- /** Version of the structured application result contract. */
574
- declare const SMRT_APP_RESULT_VERSION: 1;
575
-
576
- /** Immutable selector for this discovery artifact family. */
577
- declare const SMRT_DISCOVERY_CONFORMANCE_SCHEMA = "https://smrt.dev/schemas/discovery-conformance/v1";
578
-
579
- /** Version of the discovery artifact payload. */
580
- declare const SMRT_DISCOVERY_CONFORMANCE_VERSION: 1;
581
-
582
- /** MCP result `_meta` member carrying the app-result metadata. */
583
- export declare const SMRT_MCP_RESULT_METADATA_KEY = "io.happyvertical/smrt";
584
-
585
- export { }
1
+ /**
2
+ * `@happyvertical/smrt-app-cli` — reusable CLI factory for SMRT apps.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * #!/usr/bin/env node
7
+ * import { createAppCli } from '@happyvertical/smrt-app-cli';
8
+ *
9
+ * const cli = createAppCli({
10
+ * name: 'willgriffin',
11
+ * defaultServerUrl: 'https://willgriffin.dev',
12
+ * });
13
+ * await cli.run(process.argv.slice(2));
14
+ * ```
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ import { type CliConfig, type RequestJsonOptions } from './config.js';
19
+ export { AppCliRequestError, type AppCliResultMetadata, assertSecureServerUrl, type CliConfig, type CliConfigContext, clearStoredToken, getServerUrl, getStoredToken, loadCliConfig, type RequestJsonOptions, type RequestJsonResult, redactTransportValue, requestJson, requestJsonResult, saveAuth, saveCliConfig, } from './config.js';
20
+ import { type ResourceListResponse } from './discovery.js';
21
+ export { type CliResource, type CommandDefinition, type CommandKind, type CommandScope, fetchResourceList, findCommand, findResourceBySlug, type ResourceListResponse, } from './discovery.js';
22
+ export { buildUrl, invokeCommand } from './invoke.js';
23
+ export { createMcpClientIdMetadataDocument, type McpClientIdMetadataDocument, type McpClientRegistration, type McpClientRegistrationOptions, type McpRegisteredClient, type OAuthApplicationType, type OAuthAuthorizationServerMetadata, registerMcpClient, resolveMcpClientRegistration, } from './mcp-oauth.js';
24
+ export { type RenderResult, renderResponse } from './output.js';
25
+ export { type BuildParserResult, buildFlagParser, classifySchema, type ParsedArgs, type SchemaSupportStatus, } from './parser.js';
26
+ export { SMRT_MCP_RESULT_METADATA_KEY } from '@happyvertical/smrt-users/app-contract';
27
+ export { createMcpStdioBridge, type McpStdioBridgeOptions, runMcpStdioBridge, } from './bridge.js';
28
+ export { type AppCliExecutableConfig, parseAppCliExecutableConfig, type RunAppCliExecutableOptions, runAppCliExecutable, } from './executable.js';
29
+ export interface AppCliCommand {
30
+ name: string;
31
+ description: string;
32
+ /**
33
+ * When true, the CLI ensures resources are fetched and available via
34
+ * `ctx.getResources()` before `run()` is called. Default `false`.
35
+ */
36
+ needsResources?: boolean;
37
+ run(args: string[], ctx: AppCliContext): Promise<void>;
38
+ }
39
+ export interface AppCliContext {
40
+ config: CliConfig;
41
+ serverUrl: string;
42
+ token?: string;
43
+ /** Lazy resource-list fetch. Cached for the duration of the CLI invocation. */
44
+ getResources(): Promise<ResourceListResponse>;
45
+ /** Issue a JSON request via the shared client. */
46
+ requestJson<T = unknown>(path: string, init?: RequestInit, options?: RequestJsonOptions): Promise<T>;
47
+ /** Issue a raw fetch (for streaming / content-type-aware responses). */
48
+ request(path: string, init?: RequestInit): Promise<Response>;
49
+ stdout: NodeJS.WriteStream;
50
+ stderr: NodeJS.WriteStream;
51
+ }
52
+ export interface CreateAppCliOptions {
53
+ /** Display + branding name, e.g. `willgriffin`. Also drives `envPrefix`. */
54
+ name: string;
55
+ /** Override the env-var prefix. Default: `name.toUpperCase()`. */
56
+ envPrefix?: string;
57
+ /** Override the config dir slug. Default: `name.toLowerCase()`. */
58
+ configDir?: string;
59
+ /** Baked-in default server URL when neither env nor config sets one. */
60
+ defaultServerUrl?: string;
61
+ /** Enforce HTTPS or loopback HTTP for every effective server URL. */
62
+ requireSecureServerUrl?: boolean;
63
+ /**
64
+ * App-specific commands. Dispatched BEFORE built-ins (`auth`,
65
+ * `resources`, `mcp`) and before the resource-slug dispatcher, so an
66
+ * `extraCommands` entry takes precedence over anything with the same
67
+ * top-level argv.
68
+ *
69
+ * - **Built-in shadowing** (`extraCommands: [{ name: 'mcp' }]`): the CLI
70
+ * prints a one-line stderr warning on first invocation. The extra
71
+ * command still wins, but the warning makes the override visible.
72
+ *
73
+ * - **Resource-slug shadowing** (`extraCommands: [{ name: 'praecos' }]`
74
+ * when a server-side class also resolves to slug `praecos`): the
75
+ * extra command silently wins. There's no warning because checking
76
+ * would require a discovery round-trip on every invocation. Authors
77
+ * are responsible for namespacing their extra commands (e.g. prefix
78
+ * with the app name) to avoid accidental shadowing as the server's
79
+ * class registry grows. (#1311 review C-2.)
80
+ */
81
+ extraCommands?: AppCliCommand[];
82
+ }
83
+ export interface AppCli {
84
+ run(argv: string[]): Promise<void>;
85
+ /**
86
+ * Wire up the stdio MCP bridge and connect to stdin/stdout. The CLI
87
+ * advertises itself to local MCP clients as `serverInfo.name` /
88
+ * `.version`. Both fields default from `options.name` (so a brand-
89
+ * new app gets `{ name: '<name>-mcp', version: '0.0.0' }`) — pass an
90
+ * explicit object to override.
91
+ */
92
+ startMcpBridge(serverInfo?: {
93
+ name?: string;
94
+ version?: string;
95
+ }): Promise<void>;
96
+ }
97
+ export declare function createAppCli(options: CreateAppCliOptions): AppCli;
98
+ //# sourceMappingURL=index.d.ts.map