@usenaive-sdk/cli 0.12.0 → 0.12.5

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 (87) hide show
  1. package/README.md +22 -0
  2. package/dist/client.d.ts +26 -1
  3. package/dist/client.js +167 -5
  4. package/dist/client.js.map +1 -1
  5. package/dist/commands/aeo.js +13 -6
  6. package/dist/commands/aeo.js.map +1 -1
  7. package/dist/commands/auth.d.ts +30 -0
  8. package/dist/commands/auth.js +400 -0
  9. package/dist/commands/auth.js.map +1 -0
  10. package/dist/commands/billing.js +9 -9
  11. package/dist/commands/billing.js.map +1 -1
  12. package/dist/commands/brain.d.ts +2 -0
  13. package/dist/commands/brain.js +509 -0
  14. package/dist/commands/brain.js.map +1 -0
  15. package/dist/commands/browser.js +28 -1
  16. package/dist/commands/browser.js.map +1 -1
  17. package/dist/commands/clone.d.ts +2 -0
  18. package/dist/commands/clone.js +199 -0
  19. package/dist/commands/clone.js.map +1 -0
  20. package/dist/commands/config.d.ts +2 -0
  21. package/dist/commands/config.js +36 -0
  22. package/dist/commands/config.js.map +1 -0
  23. package/dist/commands/env.d.ts +3 -3
  24. package/dist/commands/env.js +68 -4
  25. package/dist/commands/env.js.map +1 -1
  26. package/dist/commands/images.js +2 -2
  27. package/dist/commands/init.js +38 -23
  28. package/dist/commands/init.js.map +1 -1
  29. package/dist/commands/keys.js +26 -3
  30. package/dist/commands/keys.js.map +1 -1
  31. package/dist/commands/loops.d.ts +2 -0
  32. package/dist/commands/loops.js +260 -0
  33. package/dist/commands/loops.js.map +1 -0
  34. package/dist/commands/mobile.d.ts +2 -0
  35. package/dist/commands/mobile.js +341 -0
  36. package/dist/commands/mobile.js.map +1 -0
  37. package/dist/commands/payments.d.ts +2 -0
  38. package/dist/commands/payments.js +131 -0
  39. package/dist/commands/payments.js.map +1 -0
  40. package/dist/commands/phone.js +77 -2
  41. package/dist/commands/phone.js.map +1 -1
  42. package/dist/commands/register.js +4 -4
  43. package/dist/commands/register.js.map +1 -1
  44. package/dist/commands/up.js +14 -4
  45. package/dist/commands/up.js.map +1 -1
  46. package/dist/commands/usage.js +4 -4
  47. package/dist/commands/video.js +94 -273
  48. package/dist/commands/video.js.map +1 -1
  49. package/dist/commands/voice.d.ts +2 -0
  50. package/dist/commands/voice.js +516 -0
  51. package/dist/commands/voice.js.map +1 -0
  52. package/dist/commands/wallet.d.ts +2 -0
  53. package/dist/commands/wallet.js +244 -0
  54. package/dist/commands/wallet.js.map +1 -0
  55. package/dist/config.d.ts +15 -0
  56. package/dist/config.js +35 -6
  57. package/dist/config.js.map +1 -1
  58. package/dist/index.js +70 -4
  59. package/dist/index.js.map +1 -1
  60. package/dist/lib/unknown-command.d.ts +17 -0
  61. package/dist/lib/unknown-command.js +19 -0
  62. package/dist/lib/unknown-command.js.map +1 -0
  63. package/dist/lib/version-check.d.ts +26 -0
  64. package/dist/lib/version-check.js +21 -0
  65. package/dist/lib/version-check.js.map +1 -0
  66. package/dist/output.d.ts +20 -5
  67. package/dist/output.js +150 -5
  68. package/dist/output.js.map +1 -1
  69. package/dist/prompt.d.ts +17 -0
  70. package/dist/prompt.js +70 -0
  71. package/dist/prompt.js.map +1 -0
  72. package/package.json +10 -5
  73. package/dist/commands/billing-client.d.ts +0 -2
  74. package/dist/commands/billing-client.js +0 -271
  75. package/dist/commands/billing-client.js.map +0 -1
  76. package/dist/commands/crm-app.d.ts +0 -2
  77. package/dist/commands/crm-app.js +0 -306
  78. package/dist/commands/crm-app.js.map +0 -1
  79. package/dist/commands/crm.d.ts +0 -2
  80. package/dist/commands/crm.js +0 -319
  81. package/dist/commands/crm.js.map +0 -1
  82. package/dist/commands/integrations.d.ts +0 -2
  83. package/dist/commands/integrations.js +0 -199
  84. package/dist/commands/integrations.js.map +0 -1
  85. package/dist/commands/operators.d.ts +0 -11
  86. package/dist/commands/operators.js +0 -120
  87. package/dist/commands/operators.js.map +0 -1
@@ -0,0 +1,199 @@
1
+ import { Command, Option } from "commander";
2
+ import { readFileSync, existsSync } from "node:fs";
3
+ import { basename } from "node:path";
4
+ import { apiRequest, handleApiError } from "../client.js";
5
+ import { loadConfig, getApiKey } from "../config.js";
6
+ import { agentOutput, formatApiError } from "../output.js";
7
+ // naive clone generate — one-shot digital-twin video (reference image + a saved cloned
8
+ // voice + a script + an optional scene -> a lip-synced talking video). Mirrors
9
+ // `naive video generate`: submit (async, returns a job id), optional --wait poll.
10
+ // If --image is a LOCAL path, it is uploaded via `media upload` first to get a public URL.
11
+ export const cloneCmd = new Command("clone")
12
+ .description("Generate a lip-synced talking video of a real person from a reference image + a saved cloned voice + a script")
13
+ .addHelpText("after", `
14
+ Subcommands:
15
+ naive clone generate Generate a talking video (image + voice + script -> video)
16
+ naive clone status Check a clone generation job
17
+
18
+ Examples:
19
+ $ naive clone generate --voice <voice_id> --image ./frame.png --text "Hey, welcome." --i-affirm
20
+ $ naive clone generate --voice <voice_id> --image https://example.com/frame.jpg \\
21
+ --text "Walking the pool deck" --scene "cliffside mansion pool deck at golden hour" --i-affirm --wait
22
+
23
+ Cost:
24
+ - Image edit (only with --scene) + animate, billed on completion. The voice synth is
25
+ billed on its own meter. Credits deducted only on successful completion.
26
+ `);
27
+ cloneCmd
28
+ .command("generate")
29
+ .description("Generate a talking video (async — returns a job ID)")
30
+ .requiredOption("--voice <id>", "An existing cloned voice profile id (the subject's voice + consent)")
31
+ .requiredOption("--image <path|url>", "Reference image — a local file path or a public https URL")
32
+ .requiredOption("--text <script>", "The script the cloned voice should speak")
33
+ .option("--scene <description>", "Optional scene/relight, e.g. 'cliffside pool deck at golden hour'")
34
+ .addOption(new Option("--quality <tier>", "Animate model: 'max' (OmniHuman, best lip-sync, default) or 'fast' (Kling, ~27% cheaper, stabler background)").choices(["max", "fast"]))
35
+ .option("--i-affirm", "Affirm the depicted person consented to this likeness animation (required)")
36
+ .option("--wait", "Wait for the job to complete (polls until done)")
37
+ .addHelpText("after", `
38
+ What this does:
39
+ 1. (If --image is a local file) uploads it to get a public URL
40
+ 2. Submits a clone generation job (image + voice + script [+ scene])
41
+ 3. Returns a job ID (async, typically 1-3 minutes)
42
+ 4. Use --wait to block until done, or check with 'naive clone status'
43
+
44
+ Consent:
45
+ --i-affirm is required: you attest the depicted person consented to this likeness
46
+ animation. The voice must be a saved cloned-voice profile with self or verified
47
+ third-party consent (you are animating that subject's likeness), AND that consent
48
+ must authorize the clone_generate use. Clone the voice with that use enabled:
49
+ naive voice clone <file> --consent-type self --i-affirm \\
50
+ --authorized-uses voice_synthesis,clone_generate ...
51
+ A voice cloned without clone_generate in --authorized-uses will be rejected.
52
+ `)
53
+ .action(async (opts) => {
54
+ if (!opts.iAffirm) {
55
+ console.error(JSON.stringify({
56
+ success: false,
57
+ action: "clone.generate",
58
+ error: {
59
+ code: "missing_argument",
60
+ message: "--i-affirm is required: affirm the depicted person consented to this likeness animation",
61
+ },
62
+ recovery_steps: [
63
+ {
64
+ command: 'naive clone generate --voice <id> --image <path|url> --text "..." --i-affirm',
65
+ description: "Re-run with the consent affirmation",
66
+ },
67
+ ],
68
+ }, null, 2));
69
+ process.exit(1);
70
+ }
71
+ // Resolve --image to a public URL. A local path is uploaded first (the S3 bucket
72
+ // returns a presigned URL fal can GET); an http(s) URL is passed through unchanged.
73
+ let imageUrl = opts.image;
74
+ if (!/^https?:\/\//i.test(opts.image)) {
75
+ if (!existsSync(opts.image)) {
76
+ console.error(JSON.stringify({
77
+ success: false,
78
+ action: "clone.generate",
79
+ error: { code: "invalid_input", message: `Image file not found: ${opts.image}` },
80
+ }, null, 2));
81
+ process.exit(1);
82
+ }
83
+ imageUrl = await uploadLocalImage(opts.image);
84
+ }
85
+ const resp = await apiRequest("POST", "/v1/clone/generate", {
86
+ voice_id: opts.voice,
87
+ image_url: imageUrl,
88
+ text: opts.text,
89
+ ...(opts.scene ? { scene: opts.scene } : {}),
90
+ ...(opts.quality ? { quality: opts.quality } : {}),
91
+ i_affirm: true,
92
+ });
93
+ handleApiError("clone.generate", resp);
94
+ const data = resp.data;
95
+ if (opts.wait) {
96
+ agentOutput({
97
+ action: "clone.generate.submitted",
98
+ result: { job_id: data.job_id, status: "polling" },
99
+ next_steps: [],
100
+ hints: ["Waiting for clone generation to complete (typically 1-3 minutes)..."],
101
+ });
102
+ await pollJob(data.job_id);
103
+ }
104
+ else {
105
+ agentOutput({
106
+ action: "clone.generate.submitted",
107
+ result: { job_id: data.job_id, status: "queued" },
108
+ next_steps: [
109
+ { command: `naive clone status ${data.job_id}`, description: "Check clone generation progress" },
110
+ { command: `naive jobs get ${data.job_id}`, description: "Get full job details" },
111
+ ],
112
+ hints: [
113
+ "Clone generation submitted",
114
+ "Credits deducted only on successful completion",
115
+ "Typical time: 1-3 minutes",
116
+ ],
117
+ related_commands: ["naive clone status", "naive jobs"],
118
+ });
119
+ }
120
+ });
121
+ cloneCmd
122
+ .command("status <job_id>")
123
+ .description("Check the status of a clone generation job")
124
+ .addHelpText("after", `
125
+ Examples:
126
+ $ naive clone status 550e8400-e29b-41d4-a716-446655440000
127
+
128
+ When completed, the result includes the talking-video URL (result.url).
129
+ `)
130
+ .action(async (jobId) => {
131
+ const resp = await apiRequest("GET", `/v1/clone/${jobId}`);
132
+ handleApiError("clone.status", resp);
133
+ const data = resp.data;
134
+ agentOutput({
135
+ action: "clone.status",
136
+ result: resp.data,
137
+ next_steps: [
138
+ ...(data.status === "completed" && data.result?.url
139
+ ? [{ command: `# Download: curl -o clone.mp4 "${data.result.url}"`, description: "Download the talking video" }]
140
+ : []),
141
+ ...(data.status === "queued" || data.status === "processing"
142
+ ? [{ command: `naive clone status ${jobId}`, description: "Check again in 10-30 seconds" }]
143
+ : []),
144
+ ],
145
+ hints: [`Job status: ${data.status}`],
146
+ related_commands: ["naive clone generate", "naive jobs"],
147
+ });
148
+ });
149
+ // Upload a local image and return its presigned public URL (so fal can GET it). Mirrors
150
+ // the local-file branch of `media upload` (multipart to /v1/media/upload/file).
151
+ async function uploadLocalImage(filePath) {
152
+ const fileBuffer = readFileSync(filePath);
153
+ const filename = basename(filePath);
154
+ const config = loadConfig();
155
+ const url = `${config.base_url}/v1/media/upload/file`;
156
+ const formData = new FormData();
157
+ formData.append("file", new Blob([fileBuffer]), filename);
158
+ const resp = await fetch(url, {
159
+ method: "POST",
160
+ headers: { Authorization: `Bearer ${getApiKey()}` },
161
+ body: formData,
162
+ });
163
+ const data = (await resp.json());
164
+ if (resp.status >= 400 || !data.url) {
165
+ formatApiError("clone.generate", data);
166
+ process.exit(1);
167
+ }
168
+ return data.url;
169
+ }
170
+ // Polls a clone job to completion for `clone generate --wait`. Mirrors video.ts's pollJob.
171
+ async function pollJob(jobId) {
172
+ while (true) {
173
+ await new Promise((r) => setTimeout(r, 3000));
174
+ const resp = await apiRequest("GET", `/v1/jobs/${jobId}`);
175
+ const data = resp.data;
176
+ if (data.status === "completed" || data.status === "failed") {
177
+ const videoUrl = data.result?.url;
178
+ agentOutput({
179
+ action: "clone.generate.completed",
180
+ result: resp.data,
181
+ // On success surface a download command; on failure point at the full job details.
182
+ next_steps: data.status === "completed" && videoUrl
183
+ ? [{ command: `curl -L -o clone.mp4 "${videoUrl}"`, description: "Download the talking video" }]
184
+ : [{ command: `naive jobs get ${jobId}`, description: "Get full job details" }],
185
+ hints: [
186
+ data.status === "completed"
187
+ ? videoUrl
188
+ ? `Clone generation complete — video: ${videoUrl}`
189
+ : "Clone generation complete"
190
+ : `Generation failed: ${data.error ?? "see job details"} (no credits deducted)`,
191
+ ],
192
+ related_commands: ["naive clone generate", "naive clone status", "naive jobs"],
193
+ });
194
+ return;
195
+ }
196
+ process.stderr.write(` Progress: ${data.progress ?? 0}% (${data.status})\n`);
197
+ }
198
+ }
199
+ //# sourceMappingURL=clone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const configCmd: Command;
@@ -0,0 +1,36 @@
1
+ import { Command } from "commander";
2
+ import { loadConfig, saveConfig } from "../config.js";
3
+ import { agentOutput, agentError } from "../output.js";
4
+ export const configCmd = new Command("config").description("View or set CLI preferences (e.g. output format)");
5
+ configCmd
6
+ .command("output <mode>")
7
+ .description("Set output format: human (friendly, interactive) | json (machine, default)")
8
+ .action((mode) => {
9
+ if (mode !== "human" && mode !== "json") {
10
+ agentError({
11
+ action: "config.output",
12
+ error: { code: "invalid_input", message: "mode must be 'human' or 'json'" },
13
+ recovery_steps: [{ command: "naive config output human", description: "Enable friendly output" }],
14
+ });
15
+ return;
16
+ }
17
+ saveConfig({ output: mode, human_hint_shown: true });
18
+ agentOutput({
19
+ action: "config.output",
20
+ result: { output: mode },
21
+ next_steps: [{ command: "naive voice list", description: "Try it" }],
22
+ hints: [mode === "human" ? "Friendly output enabled. Agents/scripts can still force JSON with --json or NAIVE_JSON=1." : "Machine JSON output set."],
23
+ });
24
+ });
25
+ configCmd
26
+ .command("show")
27
+ .description("Show current CLI preferences")
28
+ .action(() => {
29
+ const c = loadConfig();
30
+ agentOutput({
31
+ action: "config.show",
32
+ result: { output: c.output ?? "json (default)", base_url: c.base_url },
33
+ next_steps: [{ command: "naive config output human", description: "Switch to friendly output" }],
34
+ });
35
+ });
36
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,kDAAkD,CAAC,CAAC;AAE/G,SAAS;KACN,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,4EAA4E,CAAC;KACzF,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;IACvB,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACxC,UAAU,CAAC;YACT,MAAM,EAAE,eAAe;YACvB,KAAK,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,gCAAgC,EAAE;YAC3E,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,2BAA2B,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;SAClG,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,UAAU,CAAC,EAAE,MAAM,EAAE,IAAwB,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;IACzE,WAAW,CAAC;QACV,MAAM,EAAE,eAAe;QACvB,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;QACxB,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;QACpE,KAAK,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,2FAA2F,CAAC,CAAC,CAAC,0BAA0B,CAAC;KACrJ,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,SAAS;KACN,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8BAA8B,CAAC;KAC3C,MAAM,CAAC,GAAG,EAAE;IACX,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IACvB,WAAW,CAAC;QACV,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,gBAAgB,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;QACtE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,2BAA2B,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC;KACjG,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  /**
3
- * Environments — switch the CLI between API environments (e.g. production vs a
4
- * staging/sandbox API), and create per-tenant preview sandboxes for testing
5
- * agent profiles without real sends/charges.
3
+ * Environments — the sandbox/production primitive (per-operator mode with
4
+ * stamped resources; see docs: getting-started/environments), plus the legacy
5
+ * base-URL switch and preview-sandbox helpers.
6
6
  */
7
7
  export declare const envCmd: Command;
@@ -1,13 +1,77 @@
1
1
  import { Command } from "commander";
2
2
  import { saveConfig, loadConfig } from "../config.js";
3
3
  import { agentOutput } from "../output.js";
4
+ import { apiRequest } from "../client.js";
4
5
  /**
5
- * Environments — switch the CLI between API environments (e.g. production vs a
6
- * staging/sandbox API), and create per-tenant preview sandboxes for testing
7
- * agent profiles without real sends/charges.
6
+ * Environments — the sandbox/production primitive (per-operator mode with
7
+ * stamped resources; see docs: getting-started/environments), plus the legacy
8
+ * base-URL switch and preview-sandbox helpers.
8
9
  */
9
10
  export const envCmd = new Command("env")
10
- .description("Manage API environments and per-tenant preview sandboxes");
11
+ .description("Operator environments (sandbox/production): status, promote, reset");
12
+ /** Resolve the target user segment: explicit --user, else the active user. */
13
+ function userSegment(user) {
14
+ if (user)
15
+ return user;
16
+ const active = loadConfig().active_user_id;
17
+ if (active)
18
+ return active;
19
+ throw new Error("No target user: pass --user <id> or set one with `naive use <id>`.");
20
+ }
21
+ envCmd
22
+ .command("status")
23
+ .description("Show the operator's current environment (sandbox|production)")
24
+ .option("--user <id>", "Target a specific tenant user")
25
+ .action(async (opts) => {
26
+ const uid = userSegment(opts.user);
27
+ const { status, data } = await apiRequest("GET", `/v1/users/${uid}/environment`);
28
+ agentOutput({
29
+ action: "env.status",
30
+ result: status === 200 ? data : { error: data, status },
31
+ next_steps: [
32
+ { command: `naive env promote --user ${uid} --to production`, description: "Promote to production" },
33
+ { command: `naive env reset --user ${uid} --sandbox`, description: "Purge sandbox resources (keeps audit)" },
34
+ ],
35
+ });
36
+ });
37
+ envCmd
38
+ .command("promote")
39
+ .description("Promote (or demote) the operator's environment")
40
+ .option("--user <id>", "Target a specific tenant user")
41
+ .option("--to <environment>", "Target environment: production|sandbox", "production")
42
+ .action(async (opts) => {
43
+ const uid = userSegment(opts.user);
44
+ const { status, data } = await apiRequest("POST", `/v1/users/${uid}/environment`, {
45
+ environment: opts.to,
46
+ });
47
+ agentOutput({
48
+ action: "env.promote",
49
+ result: status === 200 ? data : { error: data, status },
50
+ next_steps: [
51
+ { command: "naive env status", description: "Confirm the operator's mode" },
52
+ ],
53
+ hints: [
54
+ "Promote flips only the mode. Sandbox residue keeps its stamp: excluded from default listings, never billed against production caps; frozen sandbox approvals must be re-requested.",
55
+ ],
56
+ });
57
+ });
58
+ envCmd
59
+ .command("reset")
60
+ .description("Purge the operator's sandbox resources (audit/trajectories are retained)")
61
+ .option("--user <id>", "Target a specific tenant user")
62
+ .option("--sandbox", "Confirm the sandbox purge (required)")
63
+ .action(async (opts) => {
64
+ if (!opts.sandbox) {
65
+ throw new Error("Pass --sandbox to confirm: this deletes sandbox-stamped resources (never audit).");
66
+ }
67
+ const uid = userSegment(opts.user);
68
+ const { status, data } = await apiRequest("POST", `/v1/users/${uid}/environment/reset`, {});
69
+ agentOutput({
70
+ action: "env.reset",
71
+ result: status === 200 ? data : { error: data, status },
72
+ next_steps: [{ command: "naive env status", description: "Confirm the operator's mode" }],
73
+ });
74
+ });
11
75
  envCmd
12
76
  .command("use")
13
77
  .description("Point the CLI at an API base URL (e.g. staging)")
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACrC,WAAW,CAAC,0DAA0D,CAAC,CAAC;AAE3E,MAAM;KACH,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,iDAAiD,CAAC;KAC9D,QAAQ,CAAC,YAAY,EAAE,oDAAoD,CAAC;KAC5E,MAAM,CAAC,CAAC,OAAe,EAAE,EAAE;IAC1B,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IACtD,WAAW,CAAC;QACV,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,QAAQ,EAAE;QAC3C,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;QACzG,KAAK,EAAE,CAAC,mBAAmB,OAAO,6CAA6C,CAAC;KACjF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,MAAM;KACH,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,+EAA+E,CAAC;KAC5F,MAAM,CAAC,eAAe,EAAE,mCAAmC,CAAC;KAC5D,MAAM,CAAC,cAAc,EAAE,sDAAsD,EAAE,YAAY,CAAC;KAC5F,MAAM,CAAC,CAAC,IAAwC,EAAE,EAAE;IACnD,+EAA+E;IAC/E,gFAAgF;IAChF,WAAW,CAAC;QACV,MAAM,EAAE,YAAY;QACpB,MAAM,EAAE;YACN,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;YAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,YAAY;YAC/B,MAAM,EAAE,WAAW;SACpB;QACD,UAAU,EAAE;YACV,EAAE,OAAO,EAAE,mDAAmD,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC,EAAE,WAAW,EAAE,+CAA+C,EAAE;SAC7J;QACD,KAAK,EAAE;YACL,6EAA6E;YAC7E,qGAAqG;SACtG;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,7 @@ Examples:
19
19
 
20
20
  Cost:
21
21
  - Image generation: dynamic, model-dependent (use GET /v1/images/pricing to preview)
22
- - Pricing based on model costs, converted to credits ($0.50/credit)
22
+ - Pricing based on model costs, converted to credits ($0.05/credit)
23
23
  - Stock photo search: 0 credits (free)
24
24
  - Credits deducted only on successful job completion
25
25
  `);
@@ -60,7 +60,7 @@ Parameters (via --input JSON):
60
60
  output_format "jpeg" or "png" (default: jpeg)
61
61
  enable_safety_checker Boolean (default: true)
62
62
 
63
- Cost: dynamic — based on model pricing ($0.50/credit)
63
+ Cost: dynamic — based on model pricing ($0.05/credit)
64
64
  Use 'GET /v1/images/pricing?model=<id>&num_images=<n>' to preview cost.
65
65
  Credits deducted only on successful completion. Failed jobs are free.
66
66
  `)
@@ -2,35 +2,50 @@ import { Command } from "commander";
2
2
  import { existsSync, writeFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { agentOutput } from "../output.js";
5
- const STARTER_CONFIG = `import { defineConfig, cloud, agentTemplate, policy } from "@usenaive-sdk/iac";
5
+ const STARTER_CONFIG = `import { defineConfig, cloud, business, agent, identity, skills } from "@usenaive-sdk/iac";
6
6
 
7
- // Naïve gives every agent its own governed real-world agent profile. This file
8
- // declares your project's own infrastructure (Path A) and the agent profile
9
- // template(s) each tenant gets. Run \`naive up\` to register it, then
10
- // \`naive agent-profiles provision <name>\` (or forUser(id).provision in the
11
- // server SDK) to instantiate one per tenant.
7
+ // Naïve gives every agent its own governed, real-world identity. Declare your
8
+ // project's shared infrastructure ONCE, then a blueprint per agent role. Run
9
+ // \`naive up\` to set it up, then \`naive.forUser(id).provision("support")\`
10
+ // (server SDK) or \`naive agent-profiles provision support --user <id>\` to
11
+ // stamp out a fresh, isolated, governed copy per user.
12
12
  export default defineConfig({
13
13
  project: "my-project",
14
14
 
15
- // Path A — your app's own shared infrastructure, as code. Omit this to bring
16
- // your own backend (Supabase, your VPC, etc.) and use Naïve only for the
17
- // regulated agent profile bundle.
15
+ // ── infrastructure: set up ONCE for the whole project ────────────────────
18
16
  infrastructure: {
19
- web: cloud.web({ framework: "nextjs", dir: "." }),
20
- database: cloud.postgres({ name: "app-db", size: "serverless" }),
21
- uploads: cloud.bucket({ name: "app-uploads" }),
17
+ // Cloud — one instance, shared by everyone. Naïve injects the secrets
18
+ // (database URL, storage credentials…) into your runtime automatically.
19
+ cloud: {
20
+ website: cloud.web({ framework: "nextjs", dir: "." }),
21
+ database: cloud.postgres({ size: "serverless" }),
22
+ storage: cloud.bucket(),
23
+ },
24
+
25
+ // Business — the real-world programs each agent draws from. Turning one ON
26
+ // registers the shared parent; each agent gets its OWN instance via \`has\`.
27
+ business: {
28
+ identity: business.entity({ form: "llc", verify: "kyb" }),
29
+ email: business.email({ domain: "mail.example.com" }),
30
+ cards: business.cards({ funding: "balance" }),
31
+ },
22
32
  },
23
33
 
24
- // The governed agent profile each tenant gets. Each entry is an agentTemplate.
25
- agentProfiles: {
26
- support: agentTemplate({
27
- identity: { kind: "business" },
28
- wallet: { card: "virtual", limit: "$50/day" },
29
- comms: { email: { domain: "per-tenant" } },
30
- policy: policy({
31
- allow: ["cards.refund", "email.send", "search"],
32
- approvals: [{ when: "cards.refund.amount > $50", via: "slack" }],
33
- }),
34
+ // ── agents: a blueprint per ROLE ─────────────────────────────────────────
35
+ // Naïve stamps out a fresh, isolated copy per user:
36
+ // naive.forUser(userId).provision("support")
37
+ agents: {
38
+ support: agent({
39
+ is: identity.business(), // a real, monetizable entity
40
+ has: {
41
+ email: true, // own address under the verified domain
42
+ cards: { limit: "$50/day" }, // own spend-capped card
43
+ },
44
+ can: [skills.email, skills.search, skills.llm],
45
+ limits: {
46
+ budget: "$200/mo", // alerts at 80%, hard-denies at cap
47
+ approve: [skills.cards.charge], // human OK before money moves
48
+ },
34
49
  }),
35
50
  },
36
51
  });
@@ -61,7 +76,7 @@ export const initCmd = new Command("init")
61
76
  { command: "naive up", description: "Register the templates declared in naive.config.ts" },
62
77
  { command: "naive agent-profiles provision support --user <tenant>", description: "Provision an agent profile from a template" },
63
78
  ],
64
- hints: ["Edit naive.config.ts to define your agent profile template(s): identity, wallet, comms, policy."],
79
+ hints: ["Edit naive.config.ts: declare shared infrastructure (cloud + business) once, then an agent blueprint per role (is / has / can / limits)."],
65
80
  });
66
81
  });
67
82
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCtB,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KACvC,WAAW,CAAC,2DAA2D,CAAC;KACxE,MAAM,CAAC,SAAS,EAAE,uCAAuC,CAAC;KAC1D,MAAM,CAAC,CAAC,IAAyB,EAAE,EAAE;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAC;IACpD,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACpC,WAAW,CAAC;YACV,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE;YAChC,UAAU,EAAE;gBACV,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,wCAAwC,EAAE;gBACxF,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,oDAAoD,EAAE;aAC3F;YACD,KAAK,EAAE,CAAC,8EAA8E,CAAC;SACxF,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;IAC5C,WAAW,CAAC;QACV,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;QAC/B,UAAU,EAAE;YACV,EAAE,OAAO,EAAE,iDAAiD,EAAE,WAAW,EAAE,0BAA0B,EAAE;YACvG,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,oDAAoD,EAAE;YAC1F,EAAE,OAAO,EAAE,wDAAwD,EAAE,WAAW,EAAE,4CAA4C,EAAE;SACjI;QACD,KAAK,EAAE,CAAC,iGAAiG,CAAC;KAC3G,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CtB,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KACvC,WAAW,CAAC,2DAA2D,CAAC;KACxE,MAAM,CAAC,SAAS,EAAE,uCAAuC,CAAC;KAC1D,MAAM,CAAC,CAAC,IAAyB,EAAE,EAAE;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAC;IACpD,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACpC,WAAW,CAAC;YACV,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE;YAChC,UAAU,EAAE;gBACV,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,wCAAwC,EAAE;gBACxF,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,oDAAoD,EAAE;aAC3F;YACD,KAAK,EAAE,CAAC,8EAA8E,CAAC;SACxF,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;IAC5C,WAAW,CAAC;QACV,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;QAC/B,UAAU,EAAE;YACV,EAAE,OAAO,EAAE,iDAAiD,EAAE,WAAW,EAAE,0BAA0B,EAAE;YACvG,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,oDAAoD,EAAE;YAC1F,EAAE,OAAO,EAAE,wDAAwD,EAAE,WAAW,EAAE,4CAA4C,EAAE;SACjI;QACD,KAAK,EAAE,CAAC,0IAA0I,CAAC;KACpJ,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { apiRequest, handleApiError } from "../client.js";
2
+ import { apiRequest, sessionRequest, handleApiError } from "../client.js";
3
3
  import { agentOutput } from "../output.js";
4
4
  export const keysCmd = new Command("keys")
5
5
  .description("Manage API keys for the current agent and company")
@@ -60,22 +60,40 @@ keysCmd
60
60
  .command("create")
61
61
  .description("Create a new API key for the current agent/company")
62
62
  .option("--name <name>", "Human-readable label for the key (e.g. 'CI Key', 'Production')")
63
+ .option("--scope <scope...>", "Restrict the key to a scope. Repeatable. Requires a signed-in session ('naive auth login'). Available: wallet:admin")
63
64
  .addHelpText("after", `
64
65
  Examples:
65
66
  $ naive keys create --name "Production Server"
66
67
  $ naive keys create --name "GitHub Actions"
68
+ $ naive keys create --name "Wallet ops (CI)" --scope wallet:admin
67
69
 
68
70
  What this does:
69
71
  Issues a new API key (nv_sk_live_...) for the current agent and company.
70
72
  The key is shown ONCE — save it securely.
71
73
 
74
+ Scopes:
75
+ An unscoped key has full access. --scope narrows a key to one route family.
76
+ Minting a scoped key requires a signed-in SESSION, not an api key — because
77
+ "wallet:admin" GRANTS the wallet operator surface (fund/transfer/policy/sweep)
78
+ rather than restricting it, so a key that could mint it would be a way for an
79
+ agent to grant itself the float it is supposed to be denied.
80
+
81
+ wallet:admin Administer per-agent crypto wallets headlessly (CI). Reaches
82
+ /v1/users/*/wallet ONLY — deliberately NOT /payments, so the
83
+ key can move the float but cannot spend it.
84
+
72
85
  Use cases:
73
86
  - Provisioning keys for different environments
74
87
  - Giving a key to a specific service/integration
75
88
  - Rotating keys (create new, revoke old)
76
89
  `)
77
90
  .action(async (opts) => {
78
- const resp = await apiRequest("POST", "/v1/auth/keys", { name: opts.name });
91
+ const scopes = opts.scope?.length ? opts.scope : undefined;
92
+ // Scoped keys are session-only (see above), so they go over sessionRequest —
93
+ // apiRequest would send the agent bearer and be refused by the server.
94
+ const resp = scopes
95
+ ? await sessionRequest("POST", "/v1/auth/keys", { body: { name: opts.name, scopes } })
96
+ : await apiRequest("POST", "/v1/auth/keys", { name: opts.name });
79
97
  handleApiError("keys.create", resp);
80
98
  const data = resp.data;
81
99
  agentOutput({
@@ -92,9 +110,14 @@ Use cases:
92
110
  "IMPORTANT: Save this key now. It will not be shown again.",
93
111
  "Use this key as a Bearer token: Authorization: Bearer <key>",
94
112
  "Set as NAIVE_API_KEY environment variable for headless use",
113
+ ...(scopes?.length
114
+ ? [`This key is restricted to: ${scopes.join(", ")}. It cannot reach any other route family.`]
115
+ : []),
95
116
  ],
96
117
  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```",
118
+ // Security: the raw key is echoed ONCE in result.api_key above. Do NOT interpolate it into
119
+ // these example commands — that multiplied it 3× and made it a copy-into-shell-history footgun.
120
+ help_markdown: "### Key Created\n\n**Save the `api_key` above immediately** — it cannot be retrieved later.\n\nTo use:\n```bash\nexport NAIVE_API_KEY=\"<your-key>\"\n# or in requests:\ncurl -H \"Authorization: Bearer <your-key>\" ...\n```",
98
121
  });
99
122
  });
100
123
  keysCmd
@@ -1 +1 @@
1
- {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const loopsCmd: Command;