@prospera/eprospera-cli 0.1.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +21 -0
  3. package/README.md +140 -0
  4. package/bin/eprospera.js +3 -0
  5. package/cli.ocs.yaml +406 -0
  6. package/dist/bundle/eprospera.mjs +28349 -0
  7. package/dist/completions/eprospera.bash +7 -0
  8. package/dist/completions/eprospera.fish +2 -0
  9. package/dist/completions/eprospera.ps1 +7 -0
  10. package/dist/completions/eprospera.zsh +4 -0
  11. package/dist/src/api/client.d.ts +29 -0
  12. package/dist/src/api/client.js +131 -0
  13. package/dist/src/api/errors.d.ts +11 -0
  14. package/dist/src/api/errors.js +125 -0
  15. package/dist/src/api/generated.d.ts +1159 -0
  16. package/dist/src/api/generated.js +6 -0
  17. package/dist/src/commands/application/create.d.ts +5 -0
  18. package/dist/src/commands/application/create.js +62 -0
  19. package/dist/src/commands/application/get.d.ts +2 -0
  20. package/dist/src/commands/application/get.js +11 -0
  21. package/dist/src/commands/application/list.d.ts +2 -0
  22. package/dist/src/commands/application/list.js +8 -0
  23. package/dist/src/commands/application/pay.d.ts +5 -0
  24. package/dist/src/commands/application/pay.js +27 -0
  25. package/dist/src/commands/application/watch.d.ts +7 -0
  26. package/dist/src/commands/application/watch.js +42 -0
  27. package/dist/src/commands/auth/login.d.ts +7 -0
  28. package/dist/src/commands/auth/login.js +60 -0
  29. package/dist/src/commands/auth/logout.d.ts +2 -0
  30. package/dist/src/commands/auth/logout.js +14 -0
  31. package/dist/src/commands/auth/whoami.d.ts +2 -0
  32. package/dist/src/commands/auth/whoami.js +19 -0
  33. package/dist/src/commands/completion.d.ts +3 -0
  34. package/dist/src/commands/completion.js +80 -0
  35. package/dist/src/commands/config/get.d.ts +2 -0
  36. package/dist/src/commands/config/get.js +9 -0
  37. package/dist/src/commands/config/list.d.ts +2 -0
  38. package/dist/src/commands/config/list.js +7 -0
  39. package/dist/src/commands/config/set.d.ts +2 -0
  40. package/dist/src/commands/config/set.js +9 -0
  41. package/dist/src/commands/config/unset.d.ts +2 -0
  42. package/dist/src/commands/config/unset.js +9 -0
  43. package/dist/src/commands/entity/documents.d.ts +2 -0
  44. package/dist/src/commands/entity/documents.js +11 -0
  45. package/dist/src/commands/entity/get.d.ts +2 -0
  46. package/dist/src/commands/entity/get.js +11 -0
  47. package/dist/src/commands/entity/search.d.ts +2 -0
  48. package/dist/src/commands/entity/search.js +17 -0
  49. package/dist/src/commands/entity/verify.d.ts +2 -0
  50. package/dist/src/commands/entity/verify.js +9 -0
  51. package/dist/src/commands/files.d.ts +2 -0
  52. package/dist/src/commands/files.js +24 -0
  53. package/dist/src/commands/me/id-verification.d.ts +2 -0
  54. package/dist/src/commands/me/id-verification.js +8 -0
  55. package/dist/src/commands/me/profile.d.ts +2 -0
  56. package/dist/src/commands/me/profile.js +8 -0
  57. package/dist/src/commands/me/residency.d.ts +2 -0
  58. package/dist/src/commands/me/residency.js +8 -0
  59. package/dist/src/commands/runtime.d.ts +56 -0
  60. package/dist/src/commands/runtime.js +101 -0
  61. package/dist/src/commands/schema.d.ts +2 -0
  62. package/dist/src/commands/schema.js +13 -0
  63. package/dist/src/config/store.d.ts +14 -0
  64. package/dist/src/config/store.js +99 -0
  65. package/dist/src/credentials/resolve.d.ts +15 -0
  66. package/dist/src/credentials/resolve.js +63 -0
  67. package/dist/src/credentials/store.d.ts +22 -0
  68. package/dist/src/credentials/store.js +184 -0
  69. package/dist/src/credentials/types.d.ts +15 -0
  70. package/dist/src/credentials/types.js +5 -0
  71. package/dist/src/errors.d.ts +39 -0
  72. package/dist/src/errors.js +38 -0
  73. package/dist/src/index.d.ts +4 -0
  74. package/dist/src/index.js +244 -0
  75. package/dist/src/output/format.d.ts +27 -0
  76. package/dist/src/output/format.js +126 -0
  77. package/dist/src/output/table.d.ts +5 -0
  78. package/dist/src/output/table.js +124 -0
  79. package/dist/src/output/tty.d.ts +26 -0
  80. package/dist/src/output/tty.js +41 -0
  81. package/dist/src/polling/watch.d.ts +19 -0
  82. package/dist/src/polling/watch.js +86 -0
  83. package/dist/src/prompts/confirm.d.ts +2 -0
  84. package/dist/src/prompts/confirm.js +19 -0
  85. package/dist/src/scopes/check.d.ts +17 -0
  86. package/dist/src/scopes/check.js +64 -0
  87. package/dist/src/scopes/map.d.ts +81 -0
  88. package/dist/src/scopes/map.js +76 -0
  89. package/dist/src/version.d.ts +1 -0
  90. package/dist/src/version.js +35 -0
  91. package/package.json +70 -0
@@ -0,0 +1,86 @@
1
+ import { ExitCodes, ExitError } from "../errors.js";
2
+ const DEFAULT_TIMEOUT_MS = 30 * 60 * 1000;
3
+ const DEFAULT_INITIAL_INTERVAL_MS = 30 * 1000;
4
+ const DEFAULT_MAX_INTERVAL_MS = 5 * 60 * 1000;
5
+ const BACKOFF_AFTER_MS = 10 * 60 * 1000;
6
+ const SUCCESS_STATUSES = new Set(["Approved"]);
7
+ const FAILURE_STATUSES = new Set(["Rejected", "PaymentFailed", "Payment Failed"]);
8
+ export async function watchApplication(fetchApplication, options = {}) {
9
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
10
+ const initialIntervalMs = options.initialIntervalMs ?? DEFAULT_INITIAL_INTERVAL_MS;
11
+ const maxIntervalMs = options.maxIntervalMs ?? DEFAULT_MAX_INTERVAL_MS;
12
+ const now = options.now ?? Date.now;
13
+ const sleep = options.sleep ?? defaultSleep;
14
+ const startedAt = now();
15
+ let lastStatus;
16
+ let lastApplication;
17
+ for (;;) {
18
+ const application = await fetchApplication();
19
+ lastApplication = application;
20
+ const status = application.statusId;
21
+ if (status !== lastStatus) {
22
+ await options.onTransition?.(application);
23
+ lastStatus = status;
24
+ }
25
+ if (status && SUCCESS_STATUSES.has(status)) {
26
+ return { application, terminal: "approved" };
27
+ }
28
+ if (status && FAILURE_STATUSES.has(status)) {
29
+ throw new ExitError({
30
+ code: "TERMINAL_FAILURE_STATE",
31
+ message: `Application entered terminal failure state ${status}.`,
32
+ exitCode: ExitCodes.TerminalFailure,
33
+ details: application,
34
+ });
35
+ }
36
+ const elapsedMs = now() - startedAt;
37
+ if (elapsedMs >= timeoutMs) {
38
+ throw new ExitError({
39
+ code: "WATCH_TIMEOUT",
40
+ message: `Application did not reach a terminal success state within ${formatDuration(timeoutMs)}.`,
41
+ exitCode: ExitCodes.Timeout,
42
+ details: lastApplication ?? null,
43
+ });
44
+ }
45
+ const intervalMs = elapsedMs < BACKOFF_AFTER_MS ? initialIntervalMs : maxIntervalMs;
46
+ await sleep(Math.min(intervalMs, timeoutMs - elapsedMs));
47
+ }
48
+ }
49
+ export function parseDurationMs(value, fallbackMs) {
50
+ if (!value) {
51
+ return fallbackMs;
52
+ }
53
+ const match = /^(\d+)(ms|s|m|h)$/.exec(value.trim());
54
+ if (!match) {
55
+ throw new ExitError({
56
+ code: "INVALID_DURATION",
57
+ message: `Invalid duration ${value}. Use values such as 30s, 30m, or 1h.`,
58
+ exitCode: ExitCodes.Usage,
59
+ });
60
+ }
61
+ const amount = Number(match[1]);
62
+ const unit = match[2];
63
+ if (unit === "ms") {
64
+ return amount;
65
+ }
66
+ if (unit === "s") {
67
+ return amount * 1000;
68
+ }
69
+ if (unit === "m") {
70
+ return amount * 60 * 1000;
71
+ }
72
+ return amount * 60 * 60 * 1000;
73
+ }
74
+ function formatDuration(ms) {
75
+ if (ms % (60 * 1000) === 0) {
76
+ return `${ms / (60 * 1000)}m`;
77
+ }
78
+ if (ms % 1000 === 0) {
79
+ return `${ms / 1000}s`;
80
+ }
81
+ return `${ms}ms`;
82
+ }
83
+ function defaultSleep(ms) {
84
+ return new Promise((resolve) => setTimeout(resolve, ms));
85
+ }
86
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1,2 @@
1
+ import type { GlobalOptions, RuntimeDependencies } from "../commands/runtime.js";
2
+ export declare function confirmAction(message: string, globals: GlobalOptions, deps?: RuntimeDependencies): Promise<boolean>;
@@ -0,0 +1,19 @@
1
+ import { confirm } from "@inquirer/prompts";
2
+ import { terminalCapabilities } from "../output/tty.js";
3
+ export async function confirmAction(message, globals, deps = {}) {
4
+ if (globals.yes) {
5
+ return true;
6
+ }
7
+ const capabilities = terminalCapabilities({
8
+ json: globals.json,
9
+ raw: globals.raw,
10
+ noAutoJson: globals.autoJson === false,
11
+ quiet: globals.quiet,
12
+ env: deps.env,
13
+ }, deps.streams);
14
+ if (!capabilities.interactive) {
15
+ return true;
16
+ }
17
+ return deps.promptConfirm?.(message) ?? confirm({ message, default: false });
18
+ }
19
+ //# sourceMappingURL=confirm.js.map
@@ -0,0 +1,17 @@
1
+ import type { CredentialKind } from "../credentials/types.js";
2
+ export declare const SCOPE_REFERENCE_URL = "https://docs.eprospera.com/agent-keys.html#scope-reference";
3
+ export type ScopeCredential = {
4
+ kind: CredentialKind;
5
+ scopes: readonly string[];
6
+ };
7
+ export type ScopeCheckOptions = {
8
+ skipScopeCheck?: boolean;
9
+ };
10
+ export type ScopeCheckResult = {
11
+ ok: true;
12
+ } | {
13
+ ok: false;
14
+ missing: string;
15
+ };
16
+ export declare function checkCommandScope(commandId: string, credential: ScopeCredential | undefined, options?: ScopeCheckOptions): ScopeCheckResult;
17
+ export declare function assertCommandScope(commandId: string, credential: ScopeCredential | undefined, options?: ScopeCheckOptions): void;
@@ -0,0 +1,64 @@
1
+ import { ExitCodes, ExitError } from "../errors.js";
2
+ import { getCommandScope } from "./map.js";
3
+ export const SCOPE_REFERENCE_URL = "https://docs.eprospera.com/agent-keys.html#scope-reference";
4
+ export function checkCommandScope(commandId, credential, options = {}) {
5
+ const requirement = getCommandScope(commandId);
6
+ if (!requirement || !requiresCredential(requirement)) {
7
+ return { ok: true };
8
+ }
9
+ if (!credential) {
10
+ throw new ExitError({
11
+ code: "NO_CREDENTIAL",
12
+ message: "No API credential configured.",
13
+ exitCode: ExitCodes.Authentication,
14
+ });
15
+ }
16
+ if (requirement.credentialTypes && !requirement.credentialTypes.includes(credential.kind)) {
17
+ throw new ExitError({
18
+ code: "UNSUPPORTED_CREDENTIAL_TYPE",
19
+ message: `Command ${commandId} does not support ${credential.kind} credentials.`,
20
+ exitCode: ExitCodes.Authorization,
21
+ details: {
22
+ command: commandId,
23
+ credentialKind: credential.kind,
24
+ allowedCredentialTypes: requirement.credentialTypes,
25
+ },
26
+ });
27
+ }
28
+ if (options.skipScopeCheck) {
29
+ return { ok: true };
30
+ }
31
+ const requiredScope = requiredScopeForCredential(credential.kind, requirement);
32
+ if (requiredScope && !credential.scopes.includes(requiredScope)) {
33
+ return { ok: false, missing: requiredScope };
34
+ }
35
+ return { ok: true };
36
+ }
37
+ export function assertCommandScope(commandId, credential, options = {}) {
38
+ const result = checkCommandScope(commandId, credential, options);
39
+ if (!result.ok) {
40
+ throw new ExitError({
41
+ code: "MISSING_SCOPE",
42
+ message: `Credential is missing required scope ${result.missing}. See ${SCOPE_REFERENCE_URL}.`,
43
+ exitCode: ExitCodes.Authorization,
44
+ details: {
45
+ command: commandId,
46
+ missing: result.missing,
47
+ scopeReference: SCOPE_REFERENCE_URL,
48
+ },
49
+ });
50
+ }
51
+ }
52
+ function requiresCredential(requirement) {
53
+ return Boolean(requirement.requiredScope || requirement.oauthScope || requirement.credentialTypes?.length);
54
+ }
55
+ function requiredScopeForCredential(kind, requirement) {
56
+ if (kind === "ak") {
57
+ return requirement.requiredScope;
58
+ }
59
+ if (kind === "oauth") {
60
+ return requirement.oauthScope;
61
+ }
62
+ return undefined;
63
+ }
64
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1,81 @@
1
+ import type { CredentialKind } from "../credentials/types.js";
2
+ export type CommandScopeRequirement = {
3
+ requiredScope?: string;
4
+ oauthScope?: string;
5
+ credentialTypes?: readonly CredentialKind[];
6
+ };
7
+ declare const commandScopes: {
8
+ readonly "entity.verify": {
9
+ readonly requiredScope: "agent:verify_rpn";
10
+ readonly credentialTypes: readonly ["ak", "sk"];
11
+ };
12
+ readonly "entity.search": {
13
+ readonly requiredScope: "agent:registry.search";
14
+ readonly credentialTypes: readonly ["ak", "sk"];
15
+ };
16
+ readonly "entity.get": {
17
+ readonly requiredScope: "agent:entity.read";
18
+ readonly credentialTypes: readonly ["ak", "sk"];
19
+ };
20
+ readonly "entity.documents": {
21
+ readonly requiredScope: "agent:entity.documents.read";
22
+ readonly credentialTypes: readonly ["ak", "sk"];
23
+ };
24
+ readonly "application.list": {
25
+ readonly requiredScope: "agent:entity.application.read";
26
+ readonly credentialTypes: readonly ["ak", "sk"];
27
+ };
28
+ readonly "application.create": {
29
+ readonly requiredScope: "agent:entity.application.create";
30
+ readonly credentialTypes: readonly ["ak", "sk"];
31
+ };
32
+ readonly "application.get": {
33
+ readonly requiredScope: "agent:entity.application.read";
34
+ readonly credentialTypes: readonly ["ak", "sk"];
35
+ };
36
+ readonly "application.pay": {
37
+ readonly requiredScope: "agent:entity.application.pay";
38
+ readonly credentialTypes: readonly ["ak", "sk"];
39
+ };
40
+ readonly "application.watch": {
41
+ readonly requiredScope: "agent:entity.application.read";
42
+ readonly credentialTypes: readonly ["ak", "sk"];
43
+ };
44
+ readonly "me.profile": {
45
+ readonly requiredScope: "agent:person.details.read";
46
+ readonly oauthScope: "eprospera:person.details.read";
47
+ readonly credentialTypes: readonly ["ak", "oauth"];
48
+ };
49
+ readonly "me.residency": {
50
+ readonly requiredScope: "agent:person.residency.read";
51
+ readonly oauthScope: "eprospera:person.residency.read";
52
+ readonly credentialTypes: readonly ["ak", "oauth"];
53
+ };
54
+ readonly "me.id-verification": {
55
+ readonly requiredScope: "agent:person.id_verification.read";
56
+ readonly oauthScope: "eprospera:person.id_verification.read";
57
+ readonly credentialTypes: readonly ["ak", "oauth"];
58
+ };
59
+ readonly "auth.login": {
60
+ readonly credentialTypes: readonly ["ak", "sk"];
61
+ };
62
+ readonly "auth.whoami": {
63
+ readonly credentialTypes: readonly ["ak", "sk", "oauth"];
64
+ };
65
+ readonly "auth.logout": {
66
+ readonly credentialTypes: readonly ["ak", "sk", "oauth"];
67
+ };
68
+ readonly "config.get": {};
69
+ readonly "config.set": {};
70
+ readonly "config.list": {};
71
+ readonly "config.unset": {};
72
+ readonly "completion.bash": {};
73
+ readonly "completion.zsh": {};
74
+ readonly "completion.fish": {};
75
+ readonly "completion.powershell": {};
76
+ readonly schema: {};
77
+ };
78
+ export type CommandId = keyof typeof commandScopes;
79
+ export declare const COMMAND_SCOPES: Record<CommandId, CommandScopeRequirement>;
80
+ export declare function getCommandScope(commandId: string): CommandScopeRequirement | undefined;
81
+ export {};
@@ -0,0 +1,76 @@
1
+ const commandScopes = {
2
+ "entity.verify": {
3
+ requiredScope: "agent:verify_rpn",
4
+ credentialTypes: ["ak", "sk"],
5
+ },
6
+ "entity.search": {
7
+ requiredScope: "agent:registry.search",
8
+ credentialTypes: ["ak", "sk"],
9
+ },
10
+ "entity.get": {
11
+ requiredScope: "agent:entity.read",
12
+ credentialTypes: ["ak", "sk"],
13
+ },
14
+ "entity.documents": {
15
+ requiredScope: "agent:entity.documents.read",
16
+ credentialTypes: ["ak", "sk"],
17
+ },
18
+ "application.list": {
19
+ requiredScope: "agent:entity.application.read",
20
+ credentialTypes: ["ak", "sk"],
21
+ },
22
+ "application.create": {
23
+ requiredScope: "agent:entity.application.create",
24
+ credentialTypes: ["ak", "sk"],
25
+ },
26
+ "application.get": {
27
+ requiredScope: "agent:entity.application.read",
28
+ credentialTypes: ["ak", "sk"],
29
+ },
30
+ "application.pay": {
31
+ requiredScope: "agent:entity.application.pay",
32
+ credentialTypes: ["ak", "sk"],
33
+ },
34
+ "application.watch": {
35
+ requiredScope: "agent:entity.application.read",
36
+ credentialTypes: ["ak", "sk"],
37
+ },
38
+ "me.profile": {
39
+ requiredScope: "agent:person.details.read",
40
+ oauthScope: "eprospera:person.details.read",
41
+ credentialTypes: ["ak", "oauth"],
42
+ },
43
+ "me.residency": {
44
+ requiredScope: "agent:person.residency.read",
45
+ oauthScope: "eprospera:person.residency.read",
46
+ credentialTypes: ["ak", "oauth"],
47
+ },
48
+ "me.id-verification": {
49
+ requiredScope: "agent:person.id_verification.read",
50
+ oauthScope: "eprospera:person.id_verification.read",
51
+ credentialTypes: ["ak", "oauth"],
52
+ },
53
+ "auth.login": {
54
+ credentialTypes: ["ak", "sk"],
55
+ },
56
+ "auth.whoami": {
57
+ credentialTypes: ["ak", "sk", "oauth"],
58
+ },
59
+ "auth.logout": {
60
+ credentialTypes: ["ak", "sk", "oauth"],
61
+ },
62
+ "config.get": {},
63
+ "config.set": {},
64
+ "config.list": {},
65
+ "config.unset": {},
66
+ "completion.bash": {},
67
+ "completion.zsh": {},
68
+ "completion.fish": {},
69
+ "completion.powershell": {},
70
+ schema: {},
71
+ };
72
+ export const COMMAND_SCOPES = commandScopes;
73
+ export function getCommandScope(commandId) {
74
+ return COMMAND_SCOPES[commandId];
75
+ }
76
+ //# sourceMappingURL=map.js.map
@@ -0,0 +1 @@
1
+ export declare const VERSION: string;
@@ -0,0 +1,35 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const BUNDLED_VERSION = "__EPROSPERA_CLI_VERSION__";
5
+ export const VERSION = readPackageVersion() ?? BUNDLED_VERSION;
6
+ function readPackageVersion() {
7
+ let currentDir = dirname(fileURLToPath(import.meta.url));
8
+ for (;;) {
9
+ const packageJsonPath = join(currentDir, "package.json");
10
+ if (existsSync(packageJsonPath)) {
11
+ const version = parsePackageVersion(packageJsonPath);
12
+ if (version) {
13
+ return version;
14
+ }
15
+ }
16
+ const parentDir = dirname(currentDir);
17
+ if (parentDir === currentDir) {
18
+ return undefined;
19
+ }
20
+ currentDir = parentDir;
21
+ }
22
+ }
23
+ function parsePackageVersion(packageJsonPath) {
24
+ try {
25
+ const value = JSON.parse(readFileSync(packageJsonPath, "utf8"));
26
+ if (value.name === "@prospera/eprospera-cli" && typeof value.version === "string") {
27
+ return value.version;
28
+ }
29
+ }
30
+ catch {
31
+ return undefined;
32
+ }
33
+ return undefined;
34
+ }
35
+ //# sourceMappingURL=version.js.map
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@prospera/eprospera-cli",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript CLI for the e-Prospera public API.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/Honduras-Prospera-inc/eprospera-cli.git"
8
+ },
9
+ "bugs": {
10
+ "url": "https://github.com/Honduras-Prospera-inc/eprospera-cli/issues"
11
+ },
12
+ "homepage": "https://github.com/Honduras-Prospera-inc/eprospera-cli#readme",
13
+ "bin": {
14
+ "eprospera": "bin/eprospera.js"
15
+ },
16
+ "scripts": {
17
+ "build": "tsc -p tsconfig.json",
18
+ "bundle": "pnpm run build && tsx scripts/build-bundle.ts",
19
+ "check": "biome check . && tsc --noEmit",
20
+ "gen:all": "pnpm run gen:api && pnpm run gen:docs && pnpm run gen:completions",
21
+ "gen:api": "tsx scripts/gen-api-client.ts",
22
+ "gen:completions": "tsx scripts/gen-completions.ts",
23
+ "gen:docs": "tsx scripts/gen-docs.ts",
24
+ "pack:smoke": "tsx scripts/smoke-packed-install.ts",
25
+ "prepare": "simple-git-hooks",
26
+ "test": "vitest run",
27
+ "test:e2e": "vitest run test/e2e",
28
+ "typecheck": "tsc --noEmit",
29
+ "validate:ocs": "tsx scripts/validate-ocs.ts"
30
+ },
31
+ "keywords": [],
32
+ "author": "",
33
+ "license": "MIT",
34
+ "engines": {
35
+ "node": ">=20"
36
+ },
37
+ "packageManager": "pnpm@10.33.4",
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "type": "module",
42
+ "devDependencies": {
43
+ "@biomejs/biome": "^2.4.15",
44
+ "@changesets/cli": "^2.31.0",
45
+ "@types/node": "^25.9.1",
46
+ "@vercel/ncc": "^0.38.4",
47
+ "ajv": "^8.20.0",
48
+ "execa": "^9.6.1",
49
+ "msw": "^2.14.6",
50
+ "openapi-typescript": "^7.13.0",
51
+ "simple-git-hooks": "^2.13.1",
52
+ "tsx": "^4.22.3",
53
+ "typescript": "^6.0.3",
54
+ "vitest": "^4.1.7"
55
+ },
56
+ "dependencies": {
57
+ "@inquirer/prompts": "^8.4.3",
58
+ "cli-table3": "^0.6.5",
59
+ "commander": "^14.0.3",
60
+ "keytar": "^7.9.0",
61
+ "openapi-fetch": "^0.17.0",
62
+ "ora": "^9.4.0",
63
+ "picocolors": "^1.1.1",
64
+ "yaml": "^2.9.0",
65
+ "zod": "^4.4.3"
66
+ },
67
+ "simple-git-hooks": {
68
+ "pre-commit": "pnpm run gen:all"
69
+ }
70
+ }