@spicyapi/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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SpicyAPI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # @spicyapi/cli
2
+
3
+ Official standalone command-line client for SpicyAPI. The package exposes the `spicyapi` binary and
4
+ depends on `@spicyapi/sdk`; it does not include the MCP server or Codex Skill.
5
+
6
+ ```bash
7
+ npx --yes @spicyapi/cli --help
8
+ npx --yes @spicyapi/cli status
9
+ npx --yes @spicyapi/cli --json models list --include-schema
10
+ ```
11
+
12
+ Set `SPICY_API_KEY` with your process secret manager. Billable commands require interactive
13
+ confirmation or an explicit `--yes`, and support stable idempotency keys.
14
+
15
+ Documentation: <https://spicyapi.ai/en/docs>
package/SECURITY.md ADDED
@@ -0,0 +1,4 @@
1
+ # Security
2
+
3
+ Report suspected vulnerabilities privately at <https://spicyapi.ai/security>. Never include API
4
+ keys, private media, signed URLs, recovery codes, or customer data in a public issue.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ export { createCli, runCli } from "./program.js";
3
+ export type { CliDependencies } from "./program.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import { isMainModule } from "../runtime/entrypoint.js";
3
+ import { runCli } from "./program.js";
4
+ export { createCli, runCli } from "./program.js";
5
+ if (isMainModule(import.meta.url)) {
6
+ process.exitCode = await runCli();
7
+ }
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGjD,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAClC,OAAO,CAAC,QAAQ,GAAG,MAAM,MAAM,EAAE,CAAC;AACpC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { UploadContentType } from "@spicyapi/sdk";
2
+ export declare const MAX_CLI_INPUT_BYTES = 1048576;
3
+ export interface CliIo {
4
+ stdout: (text: string) => void;
5
+ stderr: (text: string) => void;
6
+ stdinIsTTY: boolean;
7
+ readStdin: () => Promise<string>;
8
+ confirm: (message: string) => Promise<boolean>;
9
+ env: NodeJS.ProcessEnv;
10
+ }
11
+ export declare function defaultCliIo(): CliIo;
12
+ export declare function outputValue(value: unknown, json: boolean, io: CliIo): void;
13
+ export declare function readInputObject(inputJson: string | undefined, inputFile: string | undefined, io: CliIo): Promise<Record<string, unknown>>;
14
+ export declare function requireBillableConfirmation(message: string, yes: boolean, io: CliIo): Promise<void>;
15
+ export declare function parseUploadContentType(value: string): UploadContentType;
16
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../../src/cli/io.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAE7C,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB;AAED,wBAAgB,YAAY,IAAI,KAAK,CA0BpC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,GAAG,IAAI,CAc1E;AAkCD,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,EAAE,EAAE,KAAK,GACR,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQlC;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,OAAO,EACZ,EAAE,EAAE,KAAK,GACR,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAMvE"}
@@ -0,0 +1,109 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { createInterface } from "node:readline/promises";
3
+ export const MAX_CLI_INPUT_BYTES = 1_048_576;
4
+ export function defaultCliIo() {
5
+ return {
6
+ stdout: (text) => process.stdout.write(text),
7
+ stderr: (text) => process.stderr.write(text),
8
+ stdinIsTTY: Boolean(process.stdin.isTTY),
9
+ readStdin: async () => {
10
+ const chunks = [];
11
+ const stream = process.stdin;
12
+ for await (const chunk of stream) {
13
+ if (typeof chunk === "string")
14
+ chunks.push(chunk);
15
+ else if (chunk instanceof Uint8Array)
16
+ chunks.push(new TextDecoder().decode(chunk));
17
+ else
18
+ throw new TypeError("stdin yielded an unsupported value");
19
+ }
20
+ return chunks.join("");
21
+ },
22
+ confirm: async (message) => {
23
+ const prompt = createInterface({ input: process.stdin, output: process.stderr });
24
+ try {
25
+ const answer = await prompt.question(`${message} Continue? [y/N] `);
26
+ return /^(?:y|yes)$/i.test(answer.trim());
27
+ }
28
+ finally {
29
+ prompt.close();
30
+ }
31
+ },
32
+ env: process.env,
33
+ };
34
+ }
35
+ export function outputValue(value, json, io) {
36
+ if (json) {
37
+ io.stdout(`${JSON.stringify(value, null, 2)}\n`);
38
+ return;
39
+ }
40
+ if (typeof value === "string") {
41
+ io.stdout(`${value}\n`);
42
+ return;
43
+ }
44
+ if (Array.isArray(value)) {
45
+ for (const item of value)
46
+ io.stdout(`${formatRecord(item)}\n`);
47
+ return;
48
+ }
49
+ io.stdout(`${formatRecord(value)}\n`);
50
+ }
51
+ function formatRecord(value) {
52
+ if (value === null || typeof value !== "object")
53
+ return String(value);
54
+ const rows = Object.entries(value).map(([key, item]) => {
55
+ const formatted = item !== null && typeof item === "object"
56
+ ? JSON.stringify(item)
57
+ : item === undefined
58
+ ? ""
59
+ : String(item);
60
+ return `${key}: ${formatted}`;
61
+ });
62
+ return rows.join("\n");
63
+ }
64
+ function parseJsonObject(raw, label) {
65
+ if (Buffer.byteLength(raw, "utf8") > MAX_CLI_INPUT_BYTES) {
66
+ throw new TypeError(`${label} exceeds ${MAX_CLI_INPUT_BYTES} bytes`);
67
+ }
68
+ let parsed;
69
+ try {
70
+ parsed = JSON.parse(raw);
71
+ }
72
+ catch (error) {
73
+ throw new TypeError(`${label} is not valid JSON`, {
74
+ cause: error,
75
+ });
76
+ }
77
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
78
+ throw new TypeError(`${label} must contain a JSON object`);
79
+ }
80
+ return parsed;
81
+ }
82
+ export async function readInputObject(inputJson, inputFile, io) {
83
+ if (inputJson !== undefined && inputFile !== undefined) {
84
+ throw new TypeError("use either --input-json or --input-file, not both");
85
+ }
86
+ if (inputJson !== undefined)
87
+ return parseJsonObject(inputJson, "--input-json");
88
+ if (inputFile === undefined)
89
+ return {};
90
+ const raw = inputFile === "-" ? await io.readStdin() : await readFile(inputFile, "utf8");
91
+ return parseJsonObject(raw, inputFile === "-" ? "stdin" : "--input-file");
92
+ }
93
+ export async function requireBillableConfirmation(message, yes, io) {
94
+ if (yes)
95
+ return;
96
+ if (!io.stdinIsTTY) {
97
+ throw new Error("billable command requires an interactive confirmation or --yes");
98
+ }
99
+ if (!(await io.confirm(message)))
100
+ throw new Error("operation canceled");
101
+ }
102
+ export function parseUploadContentType(value) {
103
+ const supported = ["image/jpeg", "image/png", "image/webp", "image/gif"];
104
+ if (!supported.includes(value)) {
105
+ throw new TypeError(`content type must be one of: ${supported.join(", ")}`);
106
+ }
107
+ return value;
108
+ }
109
+ //# sourceMappingURL=io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.js","sourceRoot":"","sources":["../../../src/cli/io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAIzD,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAW7C,MAAM,UAAU,YAAY;IAC1B,OAAO;QACL,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5C,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5C,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;QACxC,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,MAAM,MAAM,GAA2B,OAAO,CAAC,KAAK,CAAC;YACrD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBACjC,IAAI,OAAO,KAAK,KAAK,QAAQ;oBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;qBAC7C,IAAI,KAAK,YAAY,UAAU;oBAAE,MAAM,CAAC,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;;oBAC9E,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACzB,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACjF,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,OAAO,mBAAmB,CAAC,CAAC;gBACpE,OAAO,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;oBAAS,CAAC;gBACT,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC;QACH,CAAC;QACD,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,IAAa,EAAE,EAAS;IAClE,IAAI,IAAI,EAAE,CAAC;QACT,EAAE,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,EAAE,CAAC,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,EAAE,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IACD,EAAE,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE;QACrD,MAAM,SAAS,GACb,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YACvC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YACtB,CAAC,CAAC,IAAI,KAAK,SAAS;gBAClB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrB,OAAO,GAAG,GAAG,KAAK,SAAS,EAAE,CAAC;IAChC,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,eAAe,CAAC,GAAW,EAAE,KAAa;IACjD,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,mBAAmB,EAAE,CAAC;QACzD,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,YAAY,mBAAmB,QAAQ,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,oBAAoB,EAAE;YAChD,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,6BAA6B,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,MAAiC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAA6B,EAC7B,SAA6B,EAC7B,EAAS;IAET,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QACvD,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAC/E,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACzF,OAAO,eAAe,CAAC,GAAG,EAAE,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAAe,EACf,GAAY,EACZ,EAAS;IAET,IAAI,GAAG;QAAE,OAAO;IAChB,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,MAAM,SAAS,GAAwB,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAC9F,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAA0B,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,SAAS,CAAC,gCAAgC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,KAA0B,CAAC;AACpC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Command } from "commander";
2
+ import { SpicyClient, type SpicyClientOptions } from "@spicyapi/sdk";
3
+ import { type CliIo } from "./io.js";
4
+ export interface CliDependencies {
5
+ io?: CliIo;
6
+ createClient?: (options: SpicyClientOptions) => SpicyClient;
7
+ }
8
+ export declare function createCli(dependencies?: CliDependencies): Command;
9
+ export declare function runCli(argv?: string[], dependencies?: CliDependencies): Promise<number>;
10
+ //# sourceMappingURL=program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../../src/cli/program.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAwC,MAAM,WAAW,CAAC;AAE1E,OAAO,EAGL,WAAW,EAEX,KAAK,kBAAkB,EAExB,MAAM,eAAe,CAAC;AACvB,OAAO,EAML,KAAK,KAAK,EACX,MAAM,SAAS,CAAC;AAgDjB,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,KAAK,CAAC;IACX,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,WAAW,CAAC;CAC7D;AAmDD,wBAAgB,SAAS,CAAC,YAAY,GAAE,eAAoB,GAAG,OAAO,CAyOrE;AAED,wBAAsB,MAAM,CAC1B,IAAI,WAAe,EACnB,YAAY,GAAE,eAAoB,GACjC,OAAO,CAAC,MAAM,CAAC,CAgBjB"}
@@ -0,0 +1,254 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ import { Command, CommanderError, InvalidArgumentError } from "commander";
4
+ import { searchDocumentation, SpicyApiError, SpicyClient, verifyWebhook, } from "@spicyapi/sdk";
5
+ import { defaultCliIo, outputValue, parseUploadContentType, readInputObject, requireBillableConfirmation, } from "./io.js";
6
+ function integer(value) {
7
+ const parsed = Number(value);
8
+ if (!Number.isSafeInteger(parsed) || parsed < 0) {
9
+ throw new InvalidArgumentError("must be a non-negative integer");
10
+ }
11
+ return parsed;
12
+ }
13
+ function clientOptions(program) {
14
+ const options = program.opts();
15
+ return {
16
+ ...(options.apiBaseUrl === undefined ? {} : { apiBaseUrl: options.apiBaseUrl }),
17
+ ...(options.serviceBaseUrl === undefined ? {} : { serviceBaseUrl: options.serviceBaseUrl }),
18
+ ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
19
+ ...(options.maxRetries === undefined ? {} : { maxRetries: options.maxRetries }),
20
+ };
21
+ }
22
+ function isJson(program) {
23
+ return Boolean(program.opts().json);
24
+ }
25
+ function taskWaitOptions(options) {
26
+ return {
27
+ ...(options.pollIntervalMs === undefined ? {} : { intervalMs: options.pollIntervalMs }),
28
+ ...(options.waitTimeoutMs === undefined ? {} : { timeoutMs: options.waitTimeoutMs }),
29
+ };
30
+ }
31
+ function describeError(error) {
32
+ if (error instanceof SpicyApiError) {
33
+ return {
34
+ error: error.message,
35
+ type: error.name,
36
+ status: error.status,
37
+ ...(error.code === undefined ? {} : { code: error.code }),
38
+ ...(error.requestId === undefined ? {} : { requestId: error.requestId }),
39
+ ...(error.retryAfterSeconds === undefined
40
+ ? {}
41
+ : { retryAfterSeconds: error.retryAfterSeconds }),
42
+ };
43
+ }
44
+ if (error instanceof Error)
45
+ return { error: error.message, type: error.name };
46
+ return { error: "unknown error", type: "Error" };
47
+ }
48
+ export function createCli(dependencies = {}) {
49
+ const io = dependencies.io ?? defaultCliIo();
50
+ const createClient = dependencies.createClient ?? ((options) => new SpicyClient(options));
51
+ const program = new Command();
52
+ program
53
+ .name("spicyapi")
54
+ .description("Official CLI for the SpicyAPI public API")
55
+ .version("0.1.0")
56
+ .option("--json", "emit machine-readable JSON")
57
+ .option("--api-base-url <url>", "override SPICY_API_BASE_URL")
58
+ .option("--service-base-url <url>", "override SPICY_SERVICE_BASE_URL")
59
+ .option("--timeout-ms <milliseconds>", "per-request timeout", integer)
60
+ .option("--max-retries <count>", "safe-request retry count (0-5)", integer)
61
+ .showSuggestionAfterError()
62
+ .configureOutput({
63
+ writeOut: (text) => io.stdout(text),
64
+ writeErr: (text) => io.stderr(text),
65
+ });
66
+ program
67
+ .command("status")
68
+ .description("check public health and readiness endpoints")
69
+ .action(async () => {
70
+ outputValue(await createClient(clientOptions(program)).getStatus(), isJson(program), io);
71
+ });
72
+ const docs = program.command("docs").description("discover first-party SpicyAPI documentation");
73
+ docs
74
+ .command("search")
75
+ .argument("[query]", "words to match", "")
76
+ .option("--limit <count>", "maximum results (1-25)", integer, 10)
77
+ .description("search the bundled first-party documentation index")
78
+ .action((query, options) => {
79
+ outputValue(searchDocumentation(query, options.limit), isJson(program), io);
80
+ });
81
+ const models = program
82
+ .command("models")
83
+ .description("inspect the live account-specific model catalog");
84
+ models
85
+ .command("list")
86
+ .option("--modality <type>", "image, video, audio, or text")
87
+ .option("--provider <name>")
88
+ .option("--task <task>")
89
+ .option("--search <text>")
90
+ .option("--include-schema", "include each model input schema")
91
+ .option("--include-examples", "include validated examples")
92
+ .description("list enabled models and account-specific prices")
93
+ .action(async (options) => {
94
+ const result = await createClient(clientOptions(program)).listModels(options);
95
+ outputValue(result, isJson(program), io);
96
+ });
97
+ models
98
+ .command("get")
99
+ .argument("<model>", "exact model ID; slashes are supported")
100
+ .description("get one model and its current input schema")
101
+ .action(async (model) => {
102
+ outputValue(await createClient(clientOptions(program)).getModel(model), isJson(program), io);
103
+ });
104
+ program
105
+ .command("balance")
106
+ .description("show available, held, and total USD credit")
107
+ .action(async () => {
108
+ outputValue(await createClient(clientOptions(program)).getBalance(), isJson(program), io);
109
+ });
110
+ const tasks = program.command("tasks").description("create, inspect, retry, and wait for tasks");
111
+ tasks
112
+ .command("get")
113
+ .argument("<task-id>")
114
+ .description("get a task visible to the current API key")
115
+ .action(async (taskId) => {
116
+ outputValue(await createClient(clientOptions(program)).getTask(taskId), isJson(program), io);
117
+ });
118
+ tasks
119
+ .command("wait")
120
+ .argument("<task-id>")
121
+ .option("--poll-interval-ms <milliseconds>", "poll interval", integer)
122
+ .option("--wait-timeout-ms <milliseconds>", "overall wait timeout", integer)
123
+ .description("poll until a task succeeds, fails, is canceled, or expires")
124
+ .action(async (taskId, options) => {
125
+ const task = await createClient(clientOptions(program)).waitForTask(taskId, taskWaitOptions(options));
126
+ outputValue(task, isJson(program), io);
127
+ });
128
+ tasks
129
+ .command("create")
130
+ .requiredOption("--model <model>", "exact live catalog model ID")
131
+ .option("--input-json <json>", "model input JSON object")
132
+ .option("--input-file <path>", "model input JSON file; use - for stdin")
133
+ .option("--callback-url <url>", "terminal webhook URL")
134
+ .option("--mature", "forward mature=true as caller-declared execution metadata")
135
+ .option("--idempotency-key <key>", "stable logical-operation key; generated when omitted")
136
+ .option("--yes", "confirm the billable action non-interactively")
137
+ .option("--wait", "wait for a terminal task after creation")
138
+ .option("--poll-interval-ms <milliseconds>", "poll interval used with --wait", integer)
139
+ .option("--wait-timeout-ms <milliseconds>", "overall timeout used with --wait", integer)
140
+ .description("create a billable asynchronous generation task")
141
+ .action(async (options) => {
142
+ const input = await readInputObject(options.inputJson, options.inputFile, io);
143
+ const idempotencyKey = options.idempotencyKey ?? randomUUID();
144
+ await requireBillableConfirmation(`Create a billable task with model ${options.model}. Idempotency-Key: ${idempotencyKey}.`, Boolean(options.yes), io);
145
+ io.stderr(`Idempotency-Key: ${idempotencyKey}\n`);
146
+ const client = createClient(clientOptions(program));
147
+ const created = await client.createTask({
148
+ model: options.model,
149
+ input,
150
+ ...(options.callbackUrl === undefined ? {} : { callBackUrl: options.callbackUrl }),
151
+ mature: Boolean(options.mature),
152
+ }, { idempotencyKey });
153
+ if (!options.wait) {
154
+ outputValue({ idempotencyKey, ...created }, isJson(program), io);
155
+ return;
156
+ }
157
+ const task = await client.waitForTask(created.taskId, taskWaitOptions(options));
158
+ outputValue({ idempotencyKey, accepted: created, task }, isJson(program), io);
159
+ });
160
+ tasks
161
+ .command("retry")
162
+ .argument("<task-id>", "failed or expired source task")
163
+ .option("--idempotency-key <key>", "stable logical-operation key; generated when omitted")
164
+ .option("--yes", "confirm the billable action non-interactively")
165
+ .option("--wait", "wait for the new retry task")
166
+ .option("--poll-interval-ms <milliseconds>", "poll interval used with --wait", integer)
167
+ .option("--wait-timeout-ms <milliseconds>", "overall timeout used with --wait", integer)
168
+ .description("create a new billable task from a failed or expired task")
169
+ .action(async (taskId, options) => {
170
+ const idempotencyKey = options.idempotencyKey ?? randomUUID();
171
+ await requireBillableConfirmation(`Retry source task ${taskId}. Current schema, price, balance, and policy will be evaluated again. Idempotency-Key: ${idempotencyKey}.`, Boolean(options.yes), io);
172
+ io.stderr(`Idempotency-Key: ${idempotencyKey}\n`);
173
+ const client = createClient(clientOptions(program));
174
+ const created = await client.retryTask(taskId, { idempotencyKey });
175
+ if (!options.wait) {
176
+ outputValue({ idempotencyKey, ...created }, isJson(program), io);
177
+ return;
178
+ }
179
+ const task = await client.waitForTask(created.taskId, taskWaitOptions(options));
180
+ outputValue({ idempotencyKey, accepted: created, task }, isJson(program), io);
181
+ });
182
+ const files = program
183
+ .command("files")
184
+ .description("upload inputs and create short-lived output links");
185
+ files
186
+ .command("upload")
187
+ .argument("<path>", "JPEG, PNG, WebP, or GIF file")
188
+ .option("--content-type <type>", "override MIME type", parseUploadContentType)
189
+ .description("prepare, PUT, and commit a private direct upload")
190
+ .action(async (filePath, options) => {
191
+ outputValue(await createClient(clientOptions(program)).uploadFile(filePath, options), isJson(program), io);
192
+ });
193
+ files
194
+ .command("download-url")
195
+ .argument("<task-id>")
196
+ .option("--key <key>", "specific task output key; first output when omitted")
197
+ .description("create a short-lived URL for a task output")
198
+ .action(async (taskId, options) => {
199
+ outputValue(await createClient(clientOptions(program)).createDownloadUrl(taskId, options.key), isJson(program), io);
200
+ });
201
+ const webhooks = program
202
+ .command("webhooks")
203
+ .description("verify current SpicyAPI callback signatures");
204
+ webhooks
205
+ .command("verify")
206
+ .requiredOption("--body-file <path>", "raw, unmodified request body")
207
+ .requiredOption("--timestamp <seconds>", "X-Webhook-Timestamp")
208
+ .requiredOption("--signature <base64>", "X-Webhook-Signature")
209
+ .requiredOption("--payload-version <version>", "X-Webhook-Payload-Version (1 or 2)", integer)
210
+ .option("--secret-env <name>", "environment variable containing the webhook secret", "SPICY_WEBHOOK_SECRET")
211
+ .option("--tolerance-seconds <seconds>", "accepted clock skew", integer, 300)
212
+ .description("verify exact raw bytes; the secret is never accepted as a command argument")
213
+ .action(async (options) => {
214
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(options.secretEnv)) {
215
+ throw new TypeError("--secret-env must be an environment variable name");
216
+ }
217
+ const secret = io.env[options.secretEnv];
218
+ if (!secret)
219
+ throw new Error(`${options.secretEnv} is required`);
220
+ if (options.payloadVersion !== 1 && options.payloadVersion !== 2) {
221
+ throw new TypeError("--payload-version must be 1 or 2");
222
+ }
223
+ const rawBody = await readFile(options.bodyFile);
224
+ outputValue(verifyWebhook({
225
+ rawBody,
226
+ timestamp: options.timestamp,
227
+ signature: options.signature,
228
+ payloadVersion: options.payloadVersion,
229
+ secret,
230
+ toleranceSeconds: options.toleranceSeconds,
231
+ }), isJson(program), io);
232
+ });
233
+ program.exitOverride();
234
+ return program;
235
+ }
236
+ export async function runCli(argv = process.argv, dependencies = {}) {
237
+ const io = dependencies.io ?? defaultCliIo();
238
+ const program = createCli({ ...dependencies, io });
239
+ try {
240
+ await program.parseAsync(argv);
241
+ return 0;
242
+ }
243
+ catch (error) {
244
+ if (error instanceof CommanderError && error.exitCode === 0)
245
+ return 0;
246
+ const details = describeError(error);
247
+ if (isJson(program))
248
+ io.stderr(`${JSON.stringify(details)}\n`);
249
+ else
250
+ io.stderr(`Error: ${details.error}${details.requestId ? ` (request ${details.requestId})` : ""}\n`);
251
+ return error instanceof CommanderError ? error.exitCode : 1;
252
+ }
253
+ }
254
+ //# sourceMappingURL=program.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.js","sourceRoot":"","sources":["../../../src/cli/program.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function isMainModule(moduleUrl: string, argv?: readonly string[]): boolean;
2
+ //# sourceMappingURL=entrypoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../../src/runtime/entrypoint.ts"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,SAAS,MAAM,EAAiB,GAAG,OAAO,CAS/F"}
@@ -0,0 +1,16 @@
1
+ import { realpathSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ export function isMainModule(moduleUrl, argv = process.argv) {
5
+ const entrypoint = argv[1];
6
+ if (!entrypoint)
7
+ return false;
8
+ const modulePath = fileURLToPath(moduleUrl);
9
+ try {
10
+ return realpathSync(modulePath) === realpathSync(entrypoint);
11
+ }
12
+ catch {
13
+ return path.resolve(modulePath) === path.resolve(entrypoint);
14
+ }
15
+ }
16
+ //# sourceMappingURL=entrypoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../../../src/runtime/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,YAAY,CAAC,SAAiB,EAAE,OAA0B,OAAO,CAAC,IAAI;IACpF,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,UAAU,CAAC,KAAK,YAAY,CAAC,UAAU,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@spicyapi/cli",
3
+ "version": "0.1.0",
4
+ "description": "Official command-line client for SpicyAPI",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/SpicyAPI/spicy-devkit.git",
10
+ "directory": "packages/cli"
11
+ },
12
+ "homepage": "https://spicyapi.ai",
13
+ "bugs": {
14
+ "url": "https://spicyapi.ai/contact"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "engines": {
20
+ "node": ">=22.13.0"
21
+ },
22
+ "main": "./dist/src/cli/index.js",
23
+ "types": "./dist/src/cli/index.d.ts",
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/src/cli/index.d.ts",
27
+ "import": "./dist/src/cli/index.js"
28
+ }
29
+ },
30
+ "bin": {
31
+ "spicyapi": "dist/src/cli/index.js"
32
+ },
33
+ "files": [
34
+ "dist/src",
35
+ "README.md",
36
+ "SECURITY.md",
37
+ "LICENSE"
38
+ ],
39
+ "scripts": {
40
+ "build": "tsc -p tsconfig.json",
41
+ "typecheck": "tsc -p tsconfig.json --noEmit"
42
+ },
43
+ "dependencies": {
44
+ "@spicyapi/sdk": "^0.1.0",
45
+ "commander": "15.0.0"
46
+ }
47
+ }