@usenaive-sdk/cli 0.2.0 → 0.2.2
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/README.md +25 -0
- package/dist/client.d.ts +10 -0
- package/dist/client.js +25 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/billing.d.ts +2 -0
- package/dist/commands/billing.js +204 -0
- package/dist/commands/billing.js.map +1 -0
- package/dist/commands/companies.d.ts +2 -0
- package/dist/commands/companies.js +88 -0
- package/dist/commands/companies.js.map +1 -0
- package/dist/commands/domains.d.ts +2 -0
- package/dist/commands/domains.js +252 -0
- package/dist/commands/domains.js.map +1 -0
- package/dist/commands/email.d.ts +2 -0
- package/dist/commands/email.js +289 -0
- package/dist/commands/email.js.map +1 -0
- package/dist/commands/identity.d.ts +2 -0
- package/dist/commands/identity.js +109 -0
- package/dist/commands/identity.js.map +1 -0
- package/dist/commands/images.d.ts +2 -0
- package/dist/commands/images.js +291 -0
- package/dist/commands/images.js.map +1 -0
- package/dist/commands/jobs.d.ts +2 -0
- package/dist/commands/jobs.js +143 -0
- package/dist/commands/jobs.js.map +1 -0
- package/dist/commands/keys.d.ts +2 -0
- package/dist/commands/keys.js +133 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/link.d.ts +3 -0
- package/dist/commands/link.js +91 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +63 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/register.d.ts +2 -0
- package/dist/commands/register.js +68 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/search.d.ts +2 -0
- package/dist/commands/search.js +209 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/social.d.ts +2 -0
- package/dist/commands/social.js +402 -0
- package/dist/commands/social.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +47 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/usage.d.ts +2 -0
- package/dist/commands/usage.js +62 -0
- package/dist/commands/usage.js.map +1 -0
- package/dist/commands/video.d.ts +2 -0
- package/dist/commands/video.js +243 -0
- package/dist/commands/video.js.map +1 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +37 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +40 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/output.d.ts +37 -0
- package/dist/output.js +84 -0
- package/dist/output.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { apiRequest, handleApiError } from "../client.js";
|
|
3
|
+
import { agentOutput } from "../output.js";
|
|
4
|
+
export const imagesCmd = new Command("images")
|
|
5
|
+
.description("Generate AI images (fal.ai) or search stock photos (Pexels)")
|
|
6
|
+
.addHelpText("after", `
|
|
7
|
+
Subcommands:
|
|
8
|
+
naive images generate <prompt> Generate images using fal.ai models
|
|
9
|
+
naive images stock <query> Search stock photos from Pexels
|
|
10
|
+
naive images status <job_id> Check generation job status
|
|
11
|
+
naive images models List available fal.ai models
|
|
12
|
+
|
|
13
|
+
Examples:
|
|
14
|
+
$ naive images generate "a futuristic city at sunset" --model fal-ai/flux/schnell
|
|
15
|
+
$ naive images generate --input '{"prompt":"cat","image_size":"landscape_16_9"}' --model fal-ai/flux-pro/v1.1
|
|
16
|
+
$ naive images stock "team collaboration" --count 5 --orientation landscape
|
|
17
|
+
$ naive images models
|
|
18
|
+
$ naive images status job-uuid-123
|
|
19
|
+
|
|
20
|
+
Cost:
|
|
21
|
+
- Image generation: dynamic, model-dependent (use GET /v1/images/pricing to preview)
|
|
22
|
+
- Pricing based on fal.ai model costs, converted to credits ($0.50/credit)
|
|
23
|
+
- Stock photo search: 0 credits (free)
|
|
24
|
+
- Credits deducted only on successful job completion
|
|
25
|
+
`);
|
|
26
|
+
imagesCmd
|
|
27
|
+
.command("generate [prompt]")
|
|
28
|
+
.description("Generate images using fal.ai (async — returns job ID)")
|
|
29
|
+
.option("--model <model>", "fal.ai model ID (default: fal-ai/flux/schnell)")
|
|
30
|
+
.option("--input <json>", "Full fal.ai input parameters as JSON (overrides prompt)")
|
|
31
|
+
.option("--size <size>", "Image size: square_hd, landscape_4_3, landscape_16_9, portrait_4_3, portrait_16_9")
|
|
32
|
+
.option("--num <n>", "Number of images to generate (default: 1)", "1")
|
|
33
|
+
.option("--wait", "Wait for job to complete (polls until done)")
|
|
34
|
+
.addHelpText("after", `
|
|
35
|
+
Examples:
|
|
36
|
+
$ naive images generate "a cat in a space suit" --model fal-ai/flux/schnell
|
|
37
|
+
$ naive images generate "minimalist logo" --model fal-ai/flux-pro/v1.1 --size square_hd --num 4
|
|
38
|
+
$ naive images generate --model fal-ai/flux/schnell --input '{"prompt":"sunset","image_size":"landscape_16_9","num_images":2}'
|
|
39
|
+
$ naive images generate "product photo" --model fal-ai/flux/schnell --wait
|
|
40
|
+
|
|
41
|
+
What this does:
|
|
42
|
+
1. Submits an image generation request to fal.ai
|
|
43
|
+
2. Returns a job ID (async processing)
|
|
44
|
+
3. Use --wait to block until images are ready, or check with 'naive images status'
|
|
45
|
+
|
|
46
|
+
Available models (use 'naive images models' for full list):
|
|
47
|
+
fal-ai/flux/schnell Fast generation (~5s), good quality (default)
|
|
48
|
+
fal-ai/flux-pro/v1.1 High quality (~15s)
|
|
49
|
+
fal-ai/flux/dev Development model (~10s)
|
|
50
|
+
fal-ai/flux-realism Photorealistic results
|
|
51
|
+
fal-ai/recraft-v3 Design-focused (logos, illustrations)
|
|
52
|
+
|
|
53
|
+
Parameters (via --input JSON — passed directly to fal.ai):
|
|
54
|
+
prompt Text description of the image (required)
|
|
55
|
+
image_size square_hd | square | landscape_4_3 | landscape_16_9 | portrait_4_3 | portrait_16_9
|
|
56
|
+
num_images Number of images (1-4)
|
|
57
|
+
seed Reproducibility seed (same seed + prompt = same result)
|
|
58
|
+
guidance_scale CFG guidance scale (FLUX Schnell/Dev only, default 3.5)
|
|
59
|
+
num_inference_steps Quality steps (FLUX Schnell: 1-12, default 4)
|
|
60
|
+
output_format "jpeg" or "png" (default: jpeg)
|
|
61
|
+
enable_safety_checker Boolean (default: true)
|
|
62
|
+
|
|
63
|
+
Cost: dynamic — based on fal.ai model pricing ($0.50/credit)
|
|
64
|
+
Use 'GET /v1/images/pricing?model=<id>&num_images=<n>' to preview cost.
|
|
65
|
+
Credits deducted only on successful completion. Failed jobs are free.
|
|
66
|
+
`)
|
|
67
|
+
.action(async (prompt, opts) => {
|
|
68
|
+
let input;
|
|
69
|
+
if (opts.input) {
|
|
70
|
+
input = JSON.parse(opts.input);
|
|
71
|
+
}
|
|
72
|
+
else if (prompt) {
|
|
73
|
+
input = {
|
|
74
|
+
prompt,
|
|
75
|
+
image_size: opts.size ?? "square_hd",
|
|
76
|
+
num_images: parseInt(opts.num),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
console.error(JSON.stringify({
|
|
81
|
+
success: false,
|
|
82
|
+
action: "images.generate",
|
|
83
|
+
error: { code: "missing_argument", message: "Provide a prompt or --input JSON" },
|
|
84
|
+
recovery_steps: [
|
|
85
|
+
{ command: 'naive images generate "your prompt" --model fal-ai/flux/schnell', description: "Generate with a text prompt" },
|
|
86
|
+
{ command: "naive images generate --model <model> --input '{...}'", description: "Generate with full fal.ai parameters" },
|
|
87
|
+
{ command: "naive images models", description: "List available models" },
|
|
88
|
+
],
|
|
89
|
+
}, null, 2));
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const resp = await apiRequest("POST", "/v1/images/generate", {
|
|
93
|
+
model: opts.model,
|
|
94
|
+
input,
|
|
95
|
+
});
|
|
96
|
+
handleApiError("images.generate", resp);
|
|
97
|
+
if (resp.status === 202) {
|
|
98
|
+
const data = resp.data;
|
|
99
|
+
const modelUsed = opts.model ?? "fal-ai/flux/schnell";
|
|
100
|
+
if (opts.wait) {
|
|
101
|
+
agentOutput({
|
|
102
|
+
action: "images.generate.submitted",
|
|
103
|
+
result: { job_id: data.job_id, status: "polling", model: modelUsed },
|
|
104
|
+
next_steps: [],
|
|
105
|
+
hints: ["Waiting for image generation to complete..."],
|
|
106
|
+
});
|
|
107
|
+
await pollJob(data.job_id);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
agentOutput({
|
|
111
|
+
action: "images.generate.submitted",
|
|
112
|
+
result: { job_id: data.job_id, status: "queued", model: modelUsed },
|
|
113
|
+
next_steps: [
|
|
114
|
+
{ command: `naive images status ${data.job_id}`, description: "Check generation progress" },
|
|
115
|
+
{ command: `naive jobs get ${data.job_id}`, description: "Get full job details" },
|
|
116
|
+
],
|
|
117
|
+
hints: [
|
|
118
|
+
`Image generation submitted (model: ${modelUsed})`,
|
|
119
|
+
"Credits deducted only on successful completion",
|
|
120
|
+
"Typical time: 5-15 seconds depending on model",
|
|
121
|
+
],
|
|
122
|
+
related_commands: ["naive images status", "naive jobs get", "naive jobs"],
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
agentOutput({
|
|
128
|
+
action: "images.generate",
|
|
129
|
+
result: resp.data,
|
|
130
|
+
next_steps: [
|
|
131
|
+
{ command: 'naive images generate "another prompt" --model <model>', description: "Generate another image" },
|
|
132
|
+
{ command: "naive images stock <query>", description: "Search stock photos instead" },
|
|
133
|
+
],
|
|
134
|
+
hints: ["Image generated synchronously"],
|
|
135
|
+
related_commands: ["naive images stock", "naive images models"],
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
imagesCmd
|
|
140
|
+
.command("status <job_id>")
|
|
141
|
+
.description("Check the status of an image generation job")
|
|
142
|
+
.addHelpText("after", `
|
|
143
|
+
Examples:
|
|
144
|
+
$ naive images status 550e8400-e29b-41d4-a716-446655440000
|
|
145
|
+
|
|
146
|
+
What this does:
|
|
147
|
+
Returns the current status of an image generation job:
|
|
148
|
+
- queued: waiting to be processed
|
|
149
|
+
- processing: actively generating
|
|
150
|
+
- completed: images ready (includes URLs)
|
|
151
|
+
- failed: generation failed (includes error message)
|
|
152
|
+
|
|
153
|
+
When completed, the result includes image URLs that you can download or use.
|
|
154
|
+
`)
|
|
155
|
+
.action(async (jobId) => {
|
|
156
|
+
const resp = await apiRequest("GET", `/v1/images/${jobId}`);
|
|
157
|
+
handleApiError("images.status", resp);
|
|
158
|
+
const data = resp.data;
|
|
159
|
+
agentOutput({
|
|
160
|
+
action: "images.status",
|
|
161
|
+
result: resp.data,
|
|
162
|
+
next_steps: [
|
|
163
|
+
...(data.status === "completed" && data.result?.images
|
|
164
|
+
? [{ command: `# Download: curl -o image.png "${data.result.images[0]?.url}"`, description: "Download the generated image" }]
|
|
165
|
+
: []),
|
|
166
|
+
...(data.status === "queued" || data.status === "processing"
|
|
167
|
+
? [{ command: `naive images status ${jobId}`, description: "Check again in a few seconds" }]
|
|
168
|
+
: []),
|
|
169
|
+
{ command: 'naive images generate "new prompt" --model <model>', description: "Generate another image" },
|
|
170
|
+
],
|
|
171
|
+
hints: [
|
|
172
|
+
`Job status: ${data.status}`,
|
|
173
|
+
...(data.status === "completed" ? [`${data.result?.images?.length ?? 0} image(s) generated`] : []),
|
|
174
|
+
],
|
|
175
|
+
related_commands: ["naive images generate", "naive jobs"],
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
imagesCmd
|
|
179
|
+
.command("stock <query>")
|
|
180
|
+
.description("Search stock photos from Pexels")
|
|
181
|
+
.option("--count <n>", "Number of results (default: 10, max: 80)", "10")
|
|
182
|
+
.option("--orientation <type>", "Filter: landscape | portrait | square")
|
|
183
|
+
.option("--color <color>", "Filter by color (red, orange, yellow, green, turquoise, blue, violet, pink, brown, black, gray, white, or hex like #ffffff)")
|
|
184
|
+
.option("--size <size>", "Minimum photo size: large | medium | small")
|
|
185
|
+
.addHelpText("after", `
|
|
186
|
+
Examples:
|
|
187
|
+
$ naive images stock "team collaboration"
|
|
188
|
+
$ naive images stock "nature mountain" --count 5 --orientation landscape
|
|
189
|
+
$ naive images stock "office workspace" --orientation square
|
|
190
|
+
$ naive images stock "abstract background" --color blue --size large
|
|
191
|
+
|
|
192
|
+
What this does:
|
|
193
|
+
Searches Pexels for stock photos matching the query.
|
|
194
|
+
Returns photo URLs in multiple sizes (original, large, medium, small).
|
|
195
|
+
|
|
196
|
+
Parameters:
|
|
197
|
+
query Search terms (natural language)
|
|
198
|
+
--count Number of results (1-80, default 10)
|
|
199
|
+
--orientation Filter by aspect ratio: landscape, portrait, or square
|
|
200
|
+
--color Filter by dominant color
|
|
201
|
+
--size Minimum photo size: large (24MP+), medium (12MP+), small
|
|
202
|
+
|
|
203
|
+
Cost: 0 credits (free)
|
|
204
|
+
`)
|
|
205
|
+
.action(async (query, opts) => {
|
|
206
|
+
const params = new URLSearchParams({ query, count: opts.count });
|
|
207
|
+
if (opts.orientation)
|
|
208
|
+
params.set("orientation", opts.orientation);
|
|
209
|
+
if (opts.color)
|
|
210
|
+
params.set("color", opts.color);
|
|
211
|
+
if (opts.size)
|
|
212
|
+
params.set("size", opts.size);
|
|
213
|
+
const resp = await apiRequest("GET", `/v1/images/stock?${params}`);
|
|
214
|
+
handleApiError("images.stock", resp);
|
|
215
|
+
const data = resp.data;
|
|
216
|
+
const count = data.photos?.length ?? 0;
|
|
217
|
+
agentOutput({
|
|
218
|
+
action: "images.stock",
|
|
219
|
+
result: resp.data,
|
|
220
|
+
next_steps: [
|
|
221
|
+
{ command: `naive images stock "${query}" --count 20`, description: "Get more results" },
|
|
222
|
+
{ command: `naive images stock "${query}" --orientation landscape`, description: "Filter by orientation" },
|
|
223
|
+
{ command: 'naive images generate "custom version of this concept"', description: "Generate a custom AI image instead", when: "Stock photos don't match your needs" },
|
|
224
|
+
],
|
|
225
|
+
hints: [
|
|
226
|
+
`Found ${count} stock photos for "${query}"`,
|
|
227
|
+
"Photos include URLs in multiple sizes (original, large, medium, small)",
|
|
228
|
+
"Cost: 0 credits (free)",
|
|
229
|
+
],
|
|
230
|
+
related_commands: ["naive images generate", "naive images models"],
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
imagesCmd
|
|
234
|
+
.command("models")
|
|
235
|
+
.description("List available fal.ai image generation models with pricing")
|
|
236
|
+
.addHelpText("after", `
|
|
237
|
+
Examples:
|
|
238
|
+
$ naive images models
|
|
239
|
+
|
|
240
|
+
What this does:
|
|
241
|
+
Returns all supported fal.ai models with:
|
|
242
|
+
- Model ID (use as --model parameter)
|
|
243
|
+
- Name and description
|
|
244
|
+
- Approximate generation time
|
|
245
|
+
- Credit cost per generation
|
|
246
|
+
`)
|
|
247
|
+
.action(async () => {
|
|
248
|
+
const resp = await apiRequest("GET", "/v1/images/models");
|
|
249
|
+
handleApiError("images.models", resp);
|
|
250
|
+
agentOutput({
|
|
251
|
+
action: "images.models",
|
|
252
|
+
result: resp.data,
|
|
253
|
+
next_steps: [
|
|
254
|
+
{ command: 'naive images generate "your prompt" --model <model_id>', description: "Generate an image with one of these models" },
|
|
255
|
+
],
|
|
256
|
+
hints: [
|
|
257
|
+
"Use the model 'id' field as the --model parameter in 'naive images generate'",
|
|
258
|
+
"Faster models cost fewer credits; higher-quality models cost more",
|
|
259
|
+
],
|
|
260
|
+
related_commands: ["naive images generate", "naive images stock"],
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
async function pollJob(jobId) {
|
|
264
|
+
while (true) {
|
|
265
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
266
|
+
const resp = await apiRequest("GET", `/v1/jobs/${jobId}`);
|
|
267
|
+
const data = resp.data;
|
|
268
|
+
if (data.status === "completed" || data.status === "failed") {
|
|
269
|
+
agentOutput({
|
|
270
|
+
action: "images.generate.completed",
|
|
271
|
+
result: resp.data,
|
|
272
|
+
next_steps: [
|
|
273
|
+
...(data.status === "completed" && data.result?.images
|
|
274
|
+
? [{ command: `# Download: curl -o image.png "${data.result.images[0]?.url}"`, description: "Download the generated image" }]
|
|
275
|
+
: []),
|
|
276
|
+
{ command: 'naive images generate "another prompt" --model <model>', description: "Generate another image" },
|
|
277
|
+
{ command: "naive images stock <query>", description: "Search stock photos instead" },
|
|
278
|
+
],
|
|
279
|
+
hints: [
|
|
280
|
+
data.status === "completed"
|
|
281
|
+
? `Generation complete — ${data.result?.images?.length ?? 0} image(s) ready`
|
|
282
|
+
: "Generation failed — no credits deducted",
|
|
283
|
+
],
|
|
284
|
+
related_commands: ["naive images generate", "naive images stock", "naive jobs"],
|
|
285
|
+
});
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
process.stderr.write(` Progress: ${data.progress ?? 0}% (${data.status})\n`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=images.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.js","sourceRoot":"","sources":["../../src/commands/images.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { apiRequest, handleApiError } from "../client.js";
|
|
3
|
+
import { agentOutput } from "../output.js";
|
|
4
|
+
export const jobsCmd = new Command("jobs")
|
|
5
|
+
.description("List and manage async jobs (image generation, video generation, deep research)")
|
|
6
|
+
.option("--status <status>", "Filter by status: queued | processing | completed | failed")
|
|
7
|
+
.option("--limit <n>", "Maximum number of jobs to return (default: 20)", "20")
|
|
8
|
+
.addHelpText("after", `
|
|
9
|
+
Subcommands:
|
|
10
|
+
naive jobs List all jobs (with optional filters)
|
|
11
|
+
naive jobs get <job_id> Get detailed status for a specific job
|
|
12
|
+
naive jobs cancel <job_id> Cancel a queued or running job
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
$ naive jobs
|
|
16
|
+
$ naive jobs --status processing
|
|
17
|
+
$ naive jobs --status completed --limit 5
|
|
18
|
+
$ naive jobs get 550e8400-e29b-41d4-a716-446655440000
|
|
19
|
+
$ naive jobs cancel 550e8400-e29b-41d4-a716-446655440000
|
|
20
|
+
|
|
21
|
+
What are jobs?
|
|
22
|
+
Long-running operations (image generation, video generation, deep research)
|
|
23
|
+
are processed asynchronously. When you submit one, you get a job_id.
|
|
24
|
+
Use this command to monitor progress and retrieve results.
|
|
25
|
+
|
|
26
|
+
Job lifecycle:
|
|
27
|
+
queued → processing → completed (success) or failed (error)
|
|
28
|
+
|
|
29
|
+
Credit behavior:
|
|
30
|
+
- Credits are NOT reserved at submission time
|
|
31
|
+
- Credits are deducted ONLY when a job completes successfully
|
|
32
|
+
- Failed or cancelled jobs do not cost any credits
|
|
33
|
+
`)
|
|
34
|
+
.action(async (opts) => {
|
|
35
|
+
const params = new URLSearchParams({ limit: opts.limit });
|
|
36
|
+
if (opts.status)
|
|
37
|
+
params.set("status", opts.status);
|
|
38
|
+
const resp = await apiRequest("GET", `/v1/jobs?${params}`);
|
|
39
|
+
handleApiError("jobs.list", resp);
|
|
40
|
+
const data = resp.data;
|
|
41
|
+
const count = data.jobs?.length ?? 0;
|
|
42
|
+
const running = data.jobs?.filter((j) => j.status === "processing" || j.status === "queued") ?? [];
|
|
43
|
+
agentOutput({
|
|
44
|
+
action: "jobs.list",
|
|
45
|
+
result: resp.data,
|
|
46
|
+
next_steps: [
|
|
47
|
+
...(running.length > 0
|
|
48
|
+
? [{ command: `naive jobs get ${running[0].id}`, description: `Check progress of ${running[0].type} job` }]
|
|
49
|
+
: []),
|
|
50
|
+
{ command: "naive jobs --status completed --limit 5", description: "See recently completed jobs with results" },
|
|
51
|
+
...(running.length > 0
|
|
52
|
+
? [{ command: `naive jobs cancel ${running[0].id}`, description: "Cancel a running job (no credits charged)" }]
|
|
53
|
+
: []),
|
|
54
|
+
],
|
|
55
|
+
hints: [
|
|
56
|
+
`${count} jobs found${opts.status ? ` (filtered: ${opts.status})` : ""}`,
|
|
57
|
+
`${running.length} active (queued/processing)`,
|
|
58
|
+
"Credits are deducted only when jobs complete successfully",
|
|
59
|
+
],
|
|
60
|
+
related_commands: ["naive jobs get", "naive jobs cancel", "naive images generate", "naive video generate", "naive search research"],
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
jobsCmd
|
|
64
|
+
.command("get <job_id>")
|
|
65
|
+
.description("Get full details and result for a specific job")
|
|
66
|
+
.addHelpText("after", `
|
|
67
|
+
Examples:
|
|
68
|
+
$ naive jobs get 550e8400-e29b-41d4-a716-446655440000
|
|
69
|
+
|
|
70
|
+
What this does:
|
|
71
|
+
Returns comprehensive details for a job:
|
|
72
|
+
- Status (queued, processing, completed, failed)
|
|
73
|
+
- Type (image_generation, video_generation, deep_research)
|
|
74
|
+
- Progress percentage
|
|
75
|
+
- Model used
|
|
76
|
+
- Input parameters
|
|
77
|
+
- Result (when completed — includes URLs for generated media)
|
|
78
|
+
- Error message (when failed)
|
|
79
|
+
- Credits used
|
|
80
|
+
- Timestamps (created, started, completed)
|
|
81
|
+
`)
|
|
82
|
+
.action(async (id) => {
|
|
83
|
+
const resp = await apiRequest("GET", `/v1/jobs/${id}`);
|
|
84
|
+
handleApiError("jobs.get", resp);
|
|
85
|
+
const data = resp.data;
|
|
86
|
+
agentOutput({
|
|
87
|
+
action: "jobs.get",
|
|
88
|
+
result: resp.data,
|
|
89
|
+
next_steps: [
|
|
90
|
+
...(data.status === "queued" || data.status === "processing"
|
|
91
|
+
? [
|
|
92
|
+
{ command: `naive jobs get ${id}`, description: "Check again in a few seconds" },
|
|
93
|
+
{ command: `naive jobs cancel ${id}`, description: "Cancel this job" },
|
|
94
|
+
]
|
|
95
|
+
: []),
|
|
96
|
+
...(data.status === "completed"
|
|
97
|
+
? [{ command: `naive ${data.type === "video_generation" ? "video" : data.type === "image_generation" ? "images" : "search"} generate "new prompt"`, description: `Generate another ${data.type?.replace("_generation", "") ?? "item"}` }]
|
|
98
|
+
: []),
|
|
99
|
+
{ command: "naive jobs", description: "View all jobs" },
|
|
100
|
+
],
|
|
101
|
+
hints: [
|
|
102
|
+
`Job ${id}: ${data.status}`,
|
|
103
|
+
...(data.status === "completed" ? ["Result is included in the output above"] : []),
|
|
104
|
+
...(data.status === "processing" ? ["Job is actively processing — check back soon"] : []),
|
|
105
|
+
],
|
|
106
|
+
related_commands: ["naive jobs", "naive jobs cancel"],
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
jobsCmd
|
|
110
|
+
.command("cancel <job_id>")
|
|
111
|
+
.description("Cancel a queued or processing job (no credits charged for cancelled jobs)")
|
|
112
|
+
.addHelpText("after", `
|
|
113
|
+
Examples:
|
|
114
|
+
$ naive jobs cancel 550e8400-e29b-41d4-a716-446655440000
|
|
115
|
+
|
|
116
|
+
What this does:
|
|
117
|
+
Attempts to cancel the specified job. Cancellation is best-effort:
|
|
118
|
+
- Queued jobs: cancelled immediately
|
|
119
|
+
- Processing jobs: cancellation requested (may still complete)
|
|
120
|
+
- Completed/failed jobs: cannot be cancelled
|
|
121
|
+
|
|
122
|
+
Notes:
|
|
123
|
+
- Cancelled jobs never deduct credits
|
|
124
|
+
- If the job already completed, you'll get an error
|
|
125
|
+
`)
|
|
126
|
+
.action(async (id) => {
|
|
127
|
+
const resp = await apiRequest("DELETE", `/v1/jobs/${id}`);
|
|
128
|
+
handleApiError("jobs.cancel", resp);
|
|
129
|
+
agentOutput({
|
|
130
|
+
action: "jobs.cancel",
|
|
131
|
+
result: { job_id: id, cancelled: true },
|
|
132
|
+
next_steps: [
|
|
133
|
+
{ command: "naive jobs --status processing", description: "Check remaining active jobs" },
|
|
134
|
+
{ command: `naive jobs get ${id}`, description: "Verify cancellation status" },
|
|
135
|
+
],
|
|
136
|
+
hints: [
|
|
137
|
+
"Job cancellation requested — no credits will be charged",
|
|
138
|
+
"Running jobs may still complete if processing already started",
|
|
139
|
+
],
|
|
140
|
+
related_commands: ["naive jobs", "naive jobs get"],
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
//# sourceMappingURL=jobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/commands/jobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { apiRequest, handleApiError } from "../client.js";
|
|
3
|
+
import { agentOutput } from "../output.js";
|
|
4
|
+
export const keysCmd = new Command("keys")
|
|
5
|
+
.description("Manage API keys for the current agent and company")
|
|
6
|
+
.addHelpText("after", `
|
|
7
|
+
Subcommands:
|
|
8
|
+
naive keys list List all API keys
|
|
9
|
+
naive keys create Create a new API key
|
|
10
|
+
naive keys revoke Revoke (deactivate) an API key
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
$ naive keys list
|
|
14
|
+
$ naive keys create --name "CI Pipeline Key"
|
|
15
|
+
$ naive keys revoke abc123-def456
|
|
16
|
+
|
|
17
|
+
Notes:
|
|
18
|
+
- API keys are scoped to a specific agent + company pair
|
|
19
|
+
- Revoking a key is permanent — it cannot be un-revoked
|
|
20
|
+
- Each login/register creates a key; use 'keys list' to audit them
|
|
21
|
+
`);
|
|
22
|
+
keysCmd
|
|
23
|
+
.command("list")
|
|
24
|
+
.description("List all API keys for the current agent/company")
|
|
25
|
+
.addHelpText("after", `
|
|
26
|
+
Examples:
|
|
27
|
+
$ naive keys list
|
|
28
|
+
|
|
29
|
+
Output includes:
|
|
30
|
+
- Key ID (for revocation)
|
|
31
|
+
- Key name/label
|
|
32
|
+
- Last 4 characters (masked)
|
|
33
|
+
- Creation date
|
|
34
|
+
- Last used date
|
|
35
|
+
- Revoked status
|
|
36
|
+
`)
|
|
37
|
+
.action(async () => {
|
|
38
|
+
const resp = await apiRequest("GET", "/v1/auth/keys");
|
|
39
|
+
handleApiError("keys.list", resp);
|
|
40
|
+
const data = resp.data;
|
|
41
|
+
const activeKeys = data.keys?.filter((k) => !k.revoked) ?? [];
|
|
42
|
+
const revokedKeys = data.keys?.filter((k) => k.revoked) ?? [];
|
|
43
|
+
agentOutput({
|
|
44
|
+
action: "keys.list",
|
|
45
|
+
result: resp.data,
|
|
46
|
+
next_steps: [
|
|
47
|
+
{ command: "naive keys create --name <label>", description: "Create a new API key", when: "You need a key for another service or environment" },
|
|
48
|
+
...(activeKeys.length > 1
|
|
49
|
+
? [{ command: `naive keys revoke <key_id>`, description: "Revoke an unused key", when: "You want to deactivate a key you no longer need" }]
|
|
50
|
+
: []),
|
|
51
|
+
],
|
|
52
|
+
hints: [
|
|
53
|
+
`${activeKeys.length} active keys, ${revokedKeys.length} revoked`,
|
|
54
|
+
"Revoked keys are shown for audit purposes but cannot authenticate",
|
|
55
|
+
],
|
|
56
|
+
related_commands: ["naive keys create", "naive keys revoke", "naive whoami"],
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
keysCmd
|
|
60
|
+
.command("create")
|
|
61
|
+
.description("Create a new API key for the current agent/company")
|
|
62
|
+
.option("--name <name>", "Human-readable label for the key (e.g. 'CI Key', 'Production')")
|
|
63
|
+
.addHelpText("after", `
|
|
64
|
+
Examples:
|
|
65
|
+
$ naive keys create --name "Production Server"
|
|
66
|
+
$ naive keys create --name "GitHub Actions"
|
|
67
|
+
|
|
68
|
+
What this does:
|
|
69
|
+
Issues a new API key (nv_sk_live_...) for the current agent and company.
|
|
70
|
+
The key is shown ONCE — save it securely.
|
|
71
|
+
|
|
72
|
+
Use cases:
|
|
73
|
+
- Provisioning keys for different environments
|
|
74
|
+
- Giving a key to a specific service/integration
|
|
75
|
+
- Rotating keys (create new, revoke old)
|
|
76
|
+
`)
|
|
77
|
+
.action(async (opts) => {
|
|
78
|
+
const resp = await apiRequest("POST", "/v1/auth/keys", { name: opts.name });
|
|
79
|
+
handleApiError("keys.create", resp);
|
|
80
|
+
const data = resp.data;
|
|
81
|
+
agentOutput({
|
|
82
|
+
action: "keys.create",
|
|
83
|
+
result: {
|
|
84
|
+
key_id: data.key_id,
|
|
85
|
+
name: data.name,
|
|
86
|
+
api_key: data.api_key,
|
|
87
|
+
},
|
|
88
|
+
next_steps: [
|
|
89
|
+
{ command: "naive keys list", description: "Verify the new key appears in your key list" },
|
|
90
|
+
],
|
|
91
|
+
hints: [
|
|
92
|
+
"IMPORTANT: Save this key now. It will not be shown again.",
|
|
93
|
+
"Use this key as a Bearer token: Authorization: Bearer <key>",
|
|
94
|
+
"Set as NAIVE_API_KEY environment variable for headless use",
|
|
95
|
+
],
|
|
96
|
+
related_commands: ["naive keys list", "naive keys revoke"],
|
|
97
|
+
help_markdown: "### Key Created\n\n**Save this key immediately** — it cannot be retrieved later.\n\nTo use:\n```bash\nexport NAIVE_API_KEY=\"" + data.api_key + "\"\n# or in requests:\ncurl -H \"Authorization: Bearer " + data.api_key + "\" ...\n```",
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
keysCmd
|
|
101
|
+
.command("revoke <key_id>")
|
|
102
|
+
.description("Permanently revoke an API key (cannot be undone)")
|
|
103
|
+
.addHelpText("after", `
|
|
104
|
+
Examples:
|
|
105
|
+
$ naive keys revoke 550e8400-e29b-41d4-a716-446655440000
|
|
106
|
+
|
|
107
|
+
What this does:
|
|
108
|
+
Permanently deactivates the specified key. Any requests using
|
|
109
|
+
this key will receive 401 Unauthorized.
|
|
110
|
+
|
|
111
|
+
WARNING:
|
|
112
|
+
- This action cannot be undone
|
|
113
|
+
- Ensure no active services depend on this key before revoking
|
|
114
|
+
- Use 'naive keys list' to find the key ID
|
|
115
|
+
`)
|
|
116
|
+
.action(async (id) => {
|
|
117
|
+
const resp = await apiRequest("DELETE", `/v1/auth/keys/${id}`);
|
|
118
|
+
handleApiError("keys.revoke", resp);
|
|
119
|
+
agentOutput({
|
|
120
|
+
action: "keys.revoke",
|
|
121
|
+
result: { key_id: id, revoked: true },
|
|
122
|
+
next_steps: [
|
|
123
|
+
{ command: "naive keys list", description: "Verify the key shows as revoked" },
|
|
124
|
+
{ command: "naive keys create --name <label>", description: "Create a replacement key if needed" },
|
|
125
|
+
],
|
|
126
|
+
hints: [
|
|
127
|
+
"This key is now permanently deactivated",
|
|
128
|
+
"Any service using this key will receive 401 errors",
|
|
129
|
+
],
|
|
130
|
+
related_commands: ["naive keys list", "naive keys create"],
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
|