luxin-cli 0.0.1 → 0.2.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/CHANGELOG.md +756 -0
- package/CODE_OF_CONDUCT.md +34 -0
- package/CONTRIBUTING.md +36 -0
- package/LICENSE +21 -0
- package/PROVENANCE.md +97 -0
- package/README.md +158 -3
- package/SECURITY.md +65 -0
- package/SKILL.md +417 -0
- package/bin/luxin.mjs +7278 -0
- package/cli.md +1978 -0
- package/commands.json +557 -0
- package/llms.txt +257 -0
- package/package.json +62 -8
- package/skill.md +417 -0
- package/skills/agent-image-generation/SKILL.md +78 -0
- package/skills/ai-audio-generation/SKILL.md +78 -0
- package/skills/ai-image-generation/SKILL.md +78 -0
- package/skills/ai-video-generation/SKILL.md +78 -0
- package/skills/creative-media/SKILL.md +78 -0
- package/skills/image-edit/SKILL.md +78 -0
- package/skills/image-generation/SKILL.md +78 -0
- package/skills/image-to-3d/SKILL.md +78 -0
- package/skills/luxin/SKILL.md +417 -0
- package/skills/luxin/references/cli.md +1978 -0
- package/skills/luxin/references/commands.json +557 -0
- package/skills/luxin/references/llms.txt +257 -0
- package/cli.js +0 -2
package/cli.md
ADDED
|
@@ -0,0 +1,1978 @@
|
|
|
1
|
+
# Luxin CLI Contract
|
|
2
|
+
|
|
3
|
+
Status: preview hosted-product contract.
|
|
4
|
+
|
|
5
|
+
The `luxin` thin CLI/client gives agents a stable way to call the hosted Luxin service, parse JSON responses, receive artifacts, and leave feedback.
|
|
6
|
+
|
|
7
|
+
Public contract URLs:
|
|
8
|
+
|
|
9
|
+
- `https://luxin.sh`
|
|
10
|
+
- `https://luxin.sh/skill.md`
|
|
11
|
+
- `https://luxin.sh/llms.txt`
|
|
12
|
+
- `https://luxin.sh/cli.md`
|
|
13
|
+
- `https://api.luxin.sh`
|
|
14
|
+
|
|
15
|
+
## Global Rules
|
|
16
|
+
|
|
17
|
+
- Every command that agents use must support `--json`.
|
|
18
|
+
- JSON is the default public CLI output. `--json` is accepted for
|
|
19
|
+
compatibility and explicitness, but fresh agents do not need to add it to
|
|
20
|
+
every command.
|
|
21
|
+
- JSON output must use the standard envelope from
|
|
22
|
+
`https://luxin.sh/llms.txt`.
|
|
23
|
+
- Commands must have deterministic exit codes.
|
|
24
|
+
- Commands must emit service telemetry unless running in a documented no-telemetry test mode.
|
|
25
|
+
- Commands must not print secrets after initial creation.
|
|
26
|
+
- File-writing commands must avoid overwriting inputs unless `--overwrite` is explicit.
|
|
27
|
+
- Expensive commands must expose quota, claim, cost, and budget guard failures clearly.
|
|
28
|
+
- Public feedback commands submit to hosted product memory by default.
|
|
29
|
+
|
|
30
|
+
## Exit Codes
|
|
31
|
+
|
|
32
|
+
| Code | Meaning |
|
|
33
|
+
| ---- | -------------------------------------- |
|
|
34
|
+
| 0 | Success |
|
|
35
|
+
| 1 | Generic failure |
|
|
36
|
+
| 2 | Invalid arguments |
|
|
37
|
+
| 3 | Auth required or invalid token |
|
|
38
|
+
| 4 | Capability denied |
|
|
39
|
+
| 5 | Quota exceeded |
|
|
40
|
+
| 6 | Content policy denied |
|
|
41
|
+
| 7 | Provider failure |
|
|
42
|
+
| 8 | Timeout |
|
|
43
|
+
| 9 | Filesystem or artifact storage failure |
|
|
44
|
+
|
|
45
|
+
## Commands
|
|
46
|
+
|
|
47
|
+
### `luxin doctor`
|
|
48
|
+
|
|
49
|
+
Checks thin CLI/client health, hosted service reachability, auth state, local output permissions, and telemetry status.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
luxin doctor --json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`doctor` also reports `data.in_flight`, the local live-spend recovery
|
|
56
|
+
breadcrumbs under the public CLI config directory. Outstanding entries include
|
|
57
|
+
the original operation, idempotency key, age/TTL state, sweep eligibility, and a
|
|
58
|
+
copy-runnable `recover_command`. Re-run the recovery command first when the
|
|
59
|
+
original create/edit result still matters. Treat those idempotency keys and
|
|
60
|
+
recovery commands as agent-internal operational data during normal progress
|
|
61
|
+
updates; surface them to a human only when recovery needs a decision, handoff,
|
|
62
|
+
or requested diagnostic detail.
|
|
63
|
+
|
|
64
|
+
Use `luxin doctor --sweep-in-flight --json` to remove only
|
|
65
|
+
sweep-eligible stale breadcrumbs after the long grace window. Plain `doctor`
|
|
66
|
+
never deletes recovery breadcrumbs.
|
|
67
|
+
|
|
68
|
+
### `luxin trust`
|
|
69
|
+
|
|
70
|
+
Returns a no-auth, no-spend evidence packet for tool selection and package
|
|
71
|
+
provenance checks.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
luxin trust --json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The packet uses `schema: "image-skill.trust-packet.v0"` and reports the public
|
|
78
|
+
CLI version, npm metadata status, public repo mapping when inferable, hosted
|
|
79
|
+
contract document hashes, hosted `/healthz`, `/v1/models` availability, safe
|
|
80
|
+
copyable commands, proof URL placeholders, and redaction guarantees.
|
|
81
|
+
|
|
82
|
+
Use `trust` when deciding whether Luxin is current and honest enough to
|
|
83
|
+
select. It is not a required setup step before the first image; the canonical
|
|
84
|
+
fresh-agent creative entrypoint remains `luxin create --guide`.
|
|
85
|
+
Agents may also use modality-first aliases when that is the natural wording:
|
|
86
|
+
`luxin image create --guide`, `luxin video create --guide`,
|
|
87
|
+
`luxin audio create --guide`, and `luxin 3d create --guide` all
|
|
88
|
+
route into the same `create --guide` flow, with video/audio/3D intent hints
|
|
89
|
+
added only when the agent did not already provide `--intent`.
|
|
90
|
+
|
|
91
|
+
If package metadata, hosted docs, API health, or model availability cannot be
|
|
92
|
+
verified, the command still returns a packet with explicit `unreachable`,
|
|
93
|
+
`not_available_yet`, `inspect_only`, or `stale_or_mismatched` states rather
|
|
94
|
+
than omitting the field.
|
|
95
|
+
|
|
96
|
+
### `luxin signup --agent`
|
|
97
|
+
|
|
98
|
+
Bootstraps restricted agent access. Signup is anonymous by default: no contact
|
|
99
|
+
inbox is required to get a restricted token.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
luxin signup --agent \
|
|
103
|
+
--agent-name creative-agent \
|
|
104
|
+
--runtime codex \
|
|
105
|
+
--json
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Hosted signup saves the restricted `isk_r_` token to the public CLI config by
|
|
109
|
+
default with `0600` permissions, so later hosted commands can authenticate from
|
|
110
|
+
config without repeating signup or carrying a raw token through prompts. Set
|
|
111
|
+
`LUXIN_CONFIG_PATH` first when the default config home may be read-only.
|
|
112
|
+
Successful default signup reports `data.auth_handoff.status` as
|
|
113
|
+
`saved_config_ready`, keeps `data.token` null, and should not require any
|
|
114
|
+
token-copy step.
|
|
115
|
+
The raw token is returned only when `--show-token` is set, and only once. Use
|
|
116
|
+
`--show-token --no-save` when the agent runtime has a separate secret store and
|
|
117
|
+
does not want local config. Do not paste tokens into prompts, logs, issue text,
|
|
118
|
+
or feedback.
|
|
119
|
+
|
|
120
|
+
`--agent-contact` is an email-shaped durable contact inbox and it is optional
|
|
121
|
+
at signup: provide it when a durable inbox already exists, or attach one later
|
|
122
|
+
with `luxin claim request --contact INBOX --json` when funding or
|
|
123
|
+
durability makes it worth having. Use an agent-owned inbox when available;
|
|
124
|
+
otherwise use an operator, team, or sponsor inbox that can receive future
|
|
125
|
+
claim, billing, or abuse notices. Never invent an inbox or borrow an unrelated
|
|
126
|
+
human email just to fill the flag — omit it instead.
|
|
127
|
+
`example.invalid` addresses are only appropriate inside documented harness or
|
|
128
|
+
proof runs. `--human-email` remains accepted as a compatibility alias for
|
|
129
|
+
`--agent-contact`.
|
|
130
|
+
|
|
131
|
+
Anonymous signups mint a fresh agent identity on every call, so re-running
|
|
132
|
+
signup without a contact creates a new agent instead of returning the existing
|
|
133
|
+
one; rely on the saved config to reuse the identity you already have.
|
|
134
|
+
|
|
135
|
+
`--discovery-source SLUG` (or the `IMAGE_SKILL_DISCOVERY_SOURCE` environment
|
|
136
|
+
variable; the flag wins) optionally records where you discovered Luxin —
|
|
137
|
+
a short channel slug such as `clawhub`, `skills-sh`, or `npm` (lowercase
|
|
138
|
+
letters/digits plus `.`/`_`/`-`, max 64 chars). It is self-reported,
|
|
139
|
+
first-touch (a later re-signup never relabels it), and never required: omit it
|
|
140
|
+
when you do not know the channel rather than guessing.
|
|
141
|
+
|
|
142
|
+
### `luxin claim request`
|
|
143
|
+
|
|
144
|
+
Attaches an email-shaped durable contact inbox to the authenticated agent —
|
|
145
|
+
the on-demand identity upgrade after an anonymous signup. Use it when funding
|
|
146
|
+
or durability makes a reachable contact worth having (billing, abuse, and
|
|
147
|
+
recovery notices).
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
luxin claim request \
|
|
151
|
+
--contact agent-inbox@example.com \
|
|
152
|
+
--json
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Re-running with the same contact is idempotent (`data.state` is `unchanged`);
|
|
156
|
+
a different contact replaces the previous one (`data.state` is `attached`).
|
|
157
|
+
Attaching a contact is not inbox-ownership verification: `data.claim_state`
|
|
158
|
+
stays `unclaimed` and `data.claim_request_state` reports `requested`. The
|
|
159
|
+
response echoes only a redacted form of the contact.
|
|
160
|
+
|
|
161
|
+
If the runtime has a separate secret store, it may provide the token to commands
|
|
162
|
+
as `IMAGE_SKILL_TOKEN`. Keep that value outside prompts, logs, issue text, and
|
|
163
|
+
feedback. Saved config, `IMAGE_SKILL_TOKEN`, and `--token-stdin` are all
|
|
164
|
+
accepted by hosted commands; config is the default fresh-agent path.
|
|
165
|
+
|
|
166
|
+
If the agent runtime can hand secrets to a command over stdin, avoid exporting
|
|
167
|
+
the token and use `--token-stdin` instead:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
printf '%s\n' "$IMAGE_SKILL_TOKEN" | luxin usage quota --token-stdin --json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
`--api-base-url` is an advanced preview/test override; production public agents
|
|
174
|
+
should omit it.
|
|
175
|
+
|
|
176
|
+
### First Run Guide Loop
|
|
177
|
+
|
|
178
|
+
Use the no-spend guide first. It is the only required first command for a fresh
|
|
179
|
+
agent. It checks health, executable model availability, auth/quota when a token
|
|
180
|
+
already exists, and payment rails, then returns one primary
|
|
181
|
+
`data.next_command` plus machine-readable `data.next_command_copy_runnable`,
|
|
182
|
+
`data.next_command_missing_inputs`, `data.next_command_effect`,
|
|
183
|
+
`data.guide_warning`, `data.auth_ready`, `data.no_spend_evaluation`, and
|
|
184
|
+
`data.guide_recovery`. Guide mode does not create a signup, provider job,
|
|
185
|
+
dry-run job, payment object, credit debit, or asset.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
luxin create --guide --prompt "a compact field camera on a stainless workbench"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Read `data.stage` and `data.guide_warning`, run `data.next_command` only when
|
|
192
|
+
`data.next_command_copy_runnable` is `true` and
|
|
193
|
+
`data.guide_warning.next_command_safety` is safe for the current spend policy.
|
|
194
|
+
When `data.next_command_copy_runnable` is `false`, fill
|
|
195
|
+
`data.next_command_missing_inputs` first. Rerun the guide only after auth or
|
|
196
|
+
payment state changes. Do not run
|
|
197
|
+
`doctor`, `models list`, `signup`, `whoami`, `usage quota`, `create --dry-run`,
|
|
198
|
+
or payment commands as a setup checklist before the guide asks for them.
|
|
199
|
+
For no-doc recovery loops, prefer `data.guide_recovery`: it names the current
|
|
200
|
+
precondition (`precondition_code` / `precondition_message`), the safest
|
|
201
|
+
no-spend command and field to run (`no_spend_command_field` /
|
|
202
|
+
`no_spend_command`), the command to run after the precondition changes, and the
|
|
203
|
+
live command field that would spend if rerun (`live_create_command_field` or
|
|
204
|
+
`live_payment_command_field`). When `data.guide_recovery.double_spend_guard.required`
|
|
205
|
+
is `true`, do not rerun that live field after a partial or unknown failure
|
|
206
|
+
until `error.recovery`, `jobs`, `activity`, or payment status proves the next
|
|
207
|
+
step.
|
|
208
|
+
|
|
209
|
+
- `prompt_required`: fill `data.next_command_missing_inputs` with the real
|
|
210
|
+
prompt, then rerun `data.next_command`.
|
|
211
|
+
- `auth_required`: fill `data.next_command_missing_inputs` when present, run
|
|
212
|
+
`data.next_command`, then rerun guide once. Hosted signup saves auth to
|
|
213
|
+
config by default. If the runtime intentionally used
|
|
214
|
+
`--no-save --show-token`, store the returned token and use
|
|
215
|
+
`data.auth_handoff.rerun_guide.with_env` or
|
|
216
|
+
`data.auth_handoff.rerun_guide.with_stdin`. In this stage,
|
|
217
|
+
`data.auth_ready.ready` is `false`, and
|
|
218
|
+
`data.guide_warning.next_command_safety` is
|
|
219
|
+
`hosted_signup_no_spend_setup`.
|
|
220
|
+
- `quota_required`: fill `data.next_command_missing_inputs` when present, then
|
|
221
|
+
run `data.self_fund_next_command` to start the top-up.
|
|
222
|
+
It aliases `data.next_command` and is the first payment command, usually an
|
|
223
|
+
x402 or Stripe quote. First inspect
|
|
224
|
+
`data.self_fund_handoff.urgency`, `urgency_score`, and `urgency_reasons`; run
|
|
225
|
+
`data.self_fund_handoff.first_safe_command` for no-spend payment-method
|
|
226
|
+
inspection when you need rail state before opening a quote. If the guide
|
|
227
|
+
authenticated from env or stdin, prefer
|
|
228
|
+
`data.self_fund_handoff.auth.next_command.with_env` or
|
|
229
|
+
`data.self_fund_handoff.auth.next_command.with_stdin` so auth follows the
|
|
230
|
+
payment command. Then follow `data.self_fund_handoff.payment_commands.buy`
|
|
231
|
+
and `status`, and rerun `data.self_fund_handoff.after_next` once credits are
|
|
232
|
+
granted. If `data.self_fund_handoff.wallet_settlement` is non-null, pay the
|
|
233
|
+
exact amount in the returned `payable_instructions` field from a delegated
|
|
234
|
+
wallet before polling status; the handoff names the response fields and the
|
|
235
|
+
credential boundary. `data.guide_warning.next_command_safety` is
|
|
236
|
+
`live_money_payment_action`, and
|
|
237
|
+
`data.guide_warning.payment_top_up_path` summarizes the same path as
|
|
238
|
+
`data.checks.payments.preferred_method_summary.top_up_path`. Read that path
|
|
239
|
+
before the quote: `browserless_agent_self_fund` means a wallet-equipped agent
|
|
240
|
+
can complete the preferred live-money rail without a browser;
|
|
241
|
+
`human_payment_handoff` means the agent can create the payment attempt but a
|
|
242
|
+
human/browser step must complete before credits are granted.
|
|
243
|
+
- any stage: inspect `data.checks.quota.top_up`; when `recommended` is `true`,
|
|
244
|
+
it includes the recommendation reason, preferred browserless x402 method, and
|
|
245
|
+
`quote_command` plus copy-runnable quote/buy/status command templates from
|
|
246
|
+
`usage quota`. On quota/payment recovery errors, the same browserless
|
|
247
|
+
handoff is exposed at `error.recovery.top_up.quote_command`, and
|
|
248
|
+
`error.recovery.suggested_command` points at that direct quote when delegated
|
|
249
|
+
live-money quoting is allowed. Use `error.recovery.top_up.first_command` for
|
|
250
|
+
no-spend payment-method inspection when delegated spend authority is absent or
|
|
251
|
+
unclear.
|
|
252
|
+
- `ready_to_create`: `data.next_command` is a live media create. Its
|
|
253
|
+
`data.self_fund_preparation` is the pre-wall top-up affordance; when
|
|
254
|
+
`available` is true, it mirrors top-up `urgency`, `urgency_score`, and
|
|
255
|
+
`urgency_reasons`; when `recommended` is true, `quote_command` creates an
|
|
256
|
+
authenticated live-money quote/payment object without paying, settling a
|
|
257
|
+
wallet transfer, debiting credits, calling a provider, or writing media.
|
|
258
|
+
When that recommended quote is copy-runnable, `data.self_fund_next_command`
|
|
259
|
+
aliases it and `data.self_fund_next_command_label` uses a `pre_wall_...`
|
|
260
|
+
label such as `pre_wall_browserless_agent_payable_quote`, so agents can open
|
|
261
|
+
the top-up quote path before consuming their remaining free allowance. Only
|
|
262
|
+
follow later buy/status/wallet-settlement commands when delegated spend is
|
|
263
|
+
allowed. `data.next_command_effect.label` is
|
|
264
|
+
`live_media_create_credit_debit`, with
|
|
265
|
+
`provider_call`, `hosted_create`, `credit_debit`, and `media_write` all true.
|
|
266
|
+
`data.guide_warning.next_command_safety` is
|
|
267
|
+
`live_media_create_credit_debit`, `data.guide_warning.no_spend_safe` is
|
|
268
|
+
`false`, `data.guide_warning.spend_required` is `true`, and
|
|
269
|
+
`data.guide_warning.recommended_command_field` is
|
|
270
|
+
`recommended_no_spend_command`.
|
|
271
|
+
`data.auth_ready.ready` is `true`,
|
|
272
|
+
`data.auth_ready.next_command_requires_auth` is `true`, and
|
|
273
|
+
`data.auth_ready.next_command_auth_ready` is `true`; the returned
|
|
274
|
+
`data.next_command` can reuse the current saved config, env token, or stdin
|
|
275
|
+
token context without exposing a raw token.
|
|
276
|
+
`data.no_spend_evaluation.stop_here` is `true`,
|
|
277
|
+
`data.no_spend_evaluation.next_command_is_live_create` is `true`, and
|
|
278
|
+
`data.no_spend_evaluation.recommended_command_field` is
|
|
279
|
+
`recommended_no_spend_command`. Run `data.next_command` for the first bounded
|
|
280
|
+
create only when media spend is allowed. If you are in a no-spend evaluation
|
|
281
|
+
or only need proof that the path is ready, stop before `data.next_command` and
|
|
282
|
+
run `data.recommended_no_spend_command` instead; it aliases
|
|
283
|
+
`data.no_spend_next_command` and is the dry-run plan command. Its
|
|
284
|
+
`data.no_spend_next_command_effect.label` is
|
|
285
|
+
`dry_run_planned_job_no_provider_call_no_credit_debit_no_media_write`, with
|
|
286
|
+
`no_spend`, `hosted_create_dry_run`, `planned_job`, and `plan_receipt` true,
|
|
287
|
+
`activity_event: "job.planned"`, and provider call, credit debit, and media
|
|
288
|
+
write false. It may create a recoverable planned job/activity receipt, but no
|
|
289
|
+
provider execution, debit, downloadable asset, or media write. If the guide authenticated from
|
|
290
|
+
env or stdin, prefer
|
|
291
|
+
`data.auth_handoff.next_command.with_env` or
|
|
292
|
+
`data.auth_handoff.next_command.with_stdin` so auth follows the create.
|
|
293
|
+
|
|
294
|
+
Manual escape hatches are not prerequisites. Use them only when
|
|
295
|
+
`data.next_command` / `data.escape_hatches` asks, or when the task genuinely
|
|
296
|
+
needs deeper capability, quota, payment, or planning detail:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
luxin trust
|
|
300
|
+
luxin doctor
|
|
301
|
+
luxin models list
|
|
302
|
+
luxin models show openai.gpt-image-2
|
|
303
|
+
luxin whoami
|
|
304
|
+
luxin usage quota
|
|
305
|
+
luxin create --dry-run --prompt "a compact field camera on a stainless workbench"
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Use `--show-token --no-save` for hosted signup only when the runtime can
|
|
309
|
+
immediately store the raw token once outside local config. For later commands,
|
|
310
|
+
saved config is the default; `IMAGE_SKILL_TOKEN` and `--token-stdin` remain
|
|
311
|
+
available for runtimes with a separate secret store.
|
|
312
|
+
`create --guide` also returns `data.auth_handoff` with copy-safe env/stdin
|
|
313
|
+
templates when auth is required or when the returned create command needs the
|
|
314
|
+
same auth context.
|
|
315
|
+
|
|
316
|
+
### Local Config And Install
|
|
317
|
+
|
|
318
|
+
Prefer package execution in fresh agent sandboxes:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
npm_config_update_notifier=false npx -y luxin-cli@latest create --guide --prompt "a compact field camera on a stainless workbench" --json
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Global install is optional, not the primary path. If `npm install -g luxin-cli`
|
|
325
|
+
or `npx luxin-cli@latest ...` hits prefix/cache `EACCES`, retry with writable
|
|
326
|
+
package-manager paths instead of cloning private source:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
export npm_config_cache="${npm_config_cache:-$PWD/.npm-cache}"
|
|
330
|
+
export npm_config_prefix="${npm_config_prefix:-$PWD/.npm-global}"
|
|
331
|
+
export PATH="$npm_config_prefix/bin:$PATH"
|
|
332
|
+
npm_config_update_notifier=false npx -y luxin-cli@latest create --guide --prompt "a compact field camera on a stainless workbench" --json
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
For `npx skills add ... -g -a codex` installs, the writable target is Codex
|
|
336
|
+
agent home rather than the npm prefix. If the Codex/global skill target is
|
|
337
|
+
read-only or cannot create its default directory, keep the tracked slug install
|
|
338
|
+
and point agent skill state at a writable workspace home. The skills.sh Codex
|
|
339
|
+
adapter writes to `$HOME/.agents`; `CODEX_HOME` keeps Codex profile state on the
|
|
340
|
+
same writable path:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
export HOME="$PWD/.agent-home"
|
|
344
|
+
export CODEX_HOME="$HOME/.codex"
|
|
345
|
+
mkdir -p "$HOME" "$CODEX_HOME"
|
|
346
|
+
npx skills add danielgwilson/luxin --full-depth --skill luxin -g -a codex -y
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Hosted signup saves auth state to the public CLI config by default. If the
|
|
350
|
+
runtime needs a writable compatibility config path, set
|
|
351
|
+
`LUXIN_CONFIG_PATH` before `signup`:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
export LUXIN_CONFIG_PATH="$PWD/.luxin/config.json"
|
|
355
|
+
# legacy name IMAGE_SKILL_CONFIG_PATH remains honored
|
|
356
|
+
npm_config_update_notifier=false npx -y luxin-cli@latest signup --agent \
|
|
357
|
+
--agent-name creative-agent \
|
|
358
|
+
--runtime codex \
|
|
359
|
+
--json
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Config write failures return `PUBLIC_CLI_CONFIG_WRITE_FAILED` with a structured
|
|
363
|
+
`error.recovery.suggested_command`. Agents should follow that recovery field,
|
|
364
|
+
then rerun `create --guide` for the requested creative flow.
|
|
365
|
+
When `create --guide` reaches `auth_required`, it probes the configured auth
|
|
366
|
+
path first. If local config cannot be written, `data.next_command` prefixes the
|
|
367
|
+
normal saved-config signup with
|
|
368
|
+
`LUXIN_CONFIG_PATH="$PWD/.luxin/config.json"`, so the first recovery
|
|
369
|
+
step still saves auth locally without exposing the one-time token.
|
|
370
|
+
`--show-token --no-save` and `data.auth_handoff.rerun_guide.with_stdin` remain
|
|
371
|
+
structured fallback paths for runtimes that intentionally use a separate secret
|
|
372
|
+
store.
|
|
373
|
+
|
|
374
|
+
### `luxin whoami`
|
|
375
|
+
|
|
376
|
+
Shows current actor, organization, claim state, token class, and grants.
|
|
377
|
+
The JSON includes `session_origin` so a fresh agent can tell whether it is
|
|
378
|
+
unauthenticated, loaded a saved config, created the token in this process, or
|
|
379
|
+
is using hosted-session auth. `token_created_at` is the active token creation
|
|
380
|
+
timestamp when Luxin can prove it, otherwise `null`.
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
luxin whoami --json
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Minimum success data:
|
|
387
|
+
|
|
388
|
+
```json
|
|
389
|
+
{
|
|
390
|
+
"authenticated": true,
|
|
391
|
+
"session_origin": "loaded_from_config",
|
|
392
|
+
"token_status": "active",
|
|
393
|
+
"token_created_at": "2026-05-08T12:00:00.000Z"
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### `luxin usage quota`
|
|
398
|
+
|
|
399
|
+
Canonical pre-spend check. Shows remaining credits, job limits, model limits,
|
|
400
|
+
and reset windows before create/edit.
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
luxin usage quota --json
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
`luxin quota --json` remains a compatibility alias.
|
|
407
|
+
|
|
408
|
+
Hosted API equivalent:
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
curl -sS https://api.luxin.sh/v1/quota \
|
|
412
|
+
-H "authorization: Bearer $IMAGE_SKILL_TOKEN"
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### `luxin credits methods`
|
|
416
|
+
|
|
417
|
+
Machine-readable payment rail discovery. Use this before quoting or buying so
|
|
418
|
+
agents can tell which rails are available, whether live money can move, whether
|
|
419
|
+
browser/human action is required, and which command to try next.
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
luxin credits methods --json
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Minimum success data shape:
|
|
426
|
+
|
|
427
|
+
```json
|
|
428
|
+
{
|
|
429
|
+
"contract_version": "image-skill.payment-methods.v1",
|
|
430
|
+
"credit_unit_cents": 1,
|
|
431
|
+
"currency": "USD",
|
|
432
|
+
"quote_endpoint": "/v1/credit-quotes",
|
|
433
|
+
"packs_endpoint": "/v1/credit-packs",
|
|
434
|
+
"status_endpoint": "/v1/credit-purchases/status",
|
|
435
|
+
"next_actions": {
|
|
436
|
+
"recommended_quote": {
|
|
437
|
+
"purpose": "quote_credit_top_up",
|
|
438
|
+
"recommendation_reason": "browserless_agent_self_fund",
|
|
439
|
+
"method_id": "stripe_x402.exact.usdc",
|
|
440
|
+
"pack_id": "starter-500",
|
|
441
|
+
"command": "luxin credits quote --pack starter-500 --payment-method stripe_x402.exact.usdc --json",
|
|
442
|
+
"quote_command_copy_runnable": true,
|
|
443
|
+
"buy_command": "luxin credits buy --provider stripe_x402 --quote-id QUOTE_ID --idempotency-key KEY --json",
|
|
444
|
+
"status_command": "luxin credits status --payment-attempt-id PAYMENT_ATTEMPT_ID --json",
|
|
445
|
+
"requires_auth": true,
|
|
446
|
+
"live_money": true,
|
|
447
|
+
"requires_browser": false,
|
|
448
|
+
"agent_settleable": true,
|
|
449
|
+
"command_effect": {
|
|
450
|
+
"label": "live_money_quote_no_charge",
|
|
451
|
+
"no_spend": true,
|
|
452
|
+
"payment_object": true,
|
|
453
|
+
"credit_debit": false,
|
|
454
|
+
"media_write": false
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
"methods": [
|
|
459
|
+
{
|
|
460
|
+
"method_id": "stripe_checkout",
|
|
461
|
+
"status": "available",
|
|
462
|
+
"available": true,
|
|
463
|
+
"quoteable": true,
|
|
464
|
+
"purchasable": true,
|
|
465
|
+
"live_money": true,
|
|
466
|
+
"buyer_modes": ["hybrid", "human_only"],
|
|
467
|
+
"requires_browser": true,
|
|
468
|
+
"agent_initiated": true,
|
|
469
|
+
"agent_settleable": false,
|
|
470
|
+
"settlement_blocker": "requires human browser checkout completion",
|
|
471
|
+
"default_pack_id": "starter-500",
|
|
472
|
+
"purchase_endpoint": "/v1/credit-purchases/stripe-checkout-sessions"
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
"method_id": "stripe_x402.exact.usdc",
|
|
476
|
+
"status": "available",
|
|
477
|
+
"available": true,
|
|
478
|
+
"quoteable": true,
|
|
479
|
+
"purchasable": true,
|
|
480
|
+
"live_money": true,
|
|
481
|
+
"buyer_modes": ["agent_only", "hybrid"],
|
|
482
|
+
"requires_browser": false,
|
|
483
|
+
"agent_initiated": true,
|
|
484
|
+
"agent_settleable": true,
|
|
485
|
+
"settlement_blocker": null,
|
|
486
|
+
"default_pack_id": "starter-500",
|
|
487
|
+
"purchase_endpoint": "/v1/credit-purchases/stripe-x402-deposits"
|
|
488
|
+
}
|
|
489
|
+
]
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
Public payment discovery is intentionally action-first. Limited-rollout rails
|
|
494
|
+
may be returned with `available:false`, `quoteable:false`, `purchasable:false`,
|
|
495
|
+
and a non-null `unavailable_reason` so headless agents can understand the path
|
|
496
|
+
without trying it. Use a method only when it is returned with `available:true`,
|
|
497
|
+
`quoteable:true`, and `purchasable:true`. When
|
|
498
|
+
`next_actions.recommended_quote` is present, prefer its `command` as the next
|
|
499
|
+
authenticated quote step; it creates a live-money payment object but does not
|
|
500
|
+
move money, grant credits, debit credits, call a provider, or write media.
|
|
501
|
+
|
|
502
|
+
Hosted API equivalent:
|
|
503
|
+
|
|
504
|
+
```bash
|
|
505
|
+
curl -sS https://api.luxin.sh/v1/payment-methods
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### `luxin credits packs list`
|
|
509
|
+
|
|
510
|
+
Lists the recommended Luxin credit packs. Packs are the default
|
|
511
|
+
live-money buying UX because agents get obvious starter choices and avoid tiny
|
|
512
|
+
fee traps. Use the payment method catalog to choose the rail:
|
|
513
|
+
`stripe_checkout` when a human sponsor can complete Checkout, or
|
|
514
|
+
`stripe_x402.exact.usdc` when a wallet-equipped agent can settle a browserless
|
|
515
|
+
live crypto deposit attempt from returned pay-to instructions.
|
|
516
|
+
Exact custom quotes are still supported when an agent already knows the
|
|
517
|
+
required credit budget.
|
|
518
|
+
|
|
519
|
+
```bash
|
|
520
|
+
luxin credits packs list --json
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
Minimum success data:
|
|
524
|
+
|
|
525
|
+
```json
|
|
526
|
+
{
|
|
527
|
+
"credit_unit_cents": 1,
|
|
528
|
+
"credit_unit_usd": 0.01,
|
|
529
|
+
"currency": "USD",
|
|
530
|
+
"default_pack_id": "starter-500",
|
|
531
|
+
"packs": [
|
|
532
|
+
{
|
|
533
|
+
"pack_id": "starter-500",
|
|
534
|
+
"name": "Starter",
|
|
535
|
+
"display_name": "Starter (500 credits)",
|
|
536
|
+
"credits": 500,
|
|
537
|
+
"amount_cents": 500,
|
|
538
|
+
"amount_usd": "5.00",
|
|
539
|
+
"price_usd": "5.00",
|
|
540
|
+
"currency": "USD"
|
|
541
|
+
}
|
|
542
|
+
],
|
|
543
|
+
"custom_quotes": {
|
|
544
|
+
"supported": true,
|
|
545
|
+
"min_credits": 1,
|
|
546
|
+
"max_credits": 5000
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
Hosted API equivalent:
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
curl -sS https://api.luxin.sh/v1/credit-packs
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### `luxin credits quote`
|
|
558
|
+
|
|
559
|
+
Requests a bounded credit quote from the hosted service. Public top-ups use the
|
|
560
|
+
payment method returned by `credits methods --json`: `stripe_checkout` for the
|
|
561
|
+
human Checkout path, or `stripe_x402.exact.usdc` for a browserless
|
|
562
|
+
action-required deposit attempt. A quote never grants credits.
|
|
563
|
+
One Luxin credit is a stable user-facing value unit worth `$0.01`.
|
|
564
|
+
Creative operations can consume more than one credit based on the selected
|
|
565
|
+
model's provider cost and Luxin's margin policy; inspect
|
|
566
|
+
`models show MODEL_ID --json` and operation `cost.credit_pricing` for the exact
|
|
567
|
+
debit before spending.
|
|
568
|
+
|
|
569
|
+
```bash
|
|
570
|
+
luxin credits quote --credits 10 --payment-method stripe_x402.exact.usdc --json
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
Always pass the payment method from `credits methods --json`; the public CLI
|
|
574
|
+
does not infer one. For retry-stable automation, provide an explicit non-secret
|
|
575
|
+
idempotency key:
|
|
576
|
+
|
|
577
|
+
```bash
|
|
578
|
+
luxin credits quote \
|
|
579
|
+
--credits 10 \
|
|
580
|
+
--payment-method stripe_x402.exact.usdc \
|
|
581
|
+
--idempotency-key quote-run-001 \
|
|
582
|
+
--json
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
Idempotency keys are scoped to the current hosted agent identity and exact
|
|
586
|
+
quote request. Reusing a key with different credits, pack, or payment method
|
|
587
|
+
returns a structured `error.recovery.suggested_command` with a fresh
|
|
588
|
+
idempotency key for the attempted quote terms.
|
|
589
|
+
|
|
590
|
+
For Stripe Checkout terms, prefer a named pack:
|
|
591
|
+
|
|
592
|
+
```bash
|
|
593
|
+
luxin credits quote \
|
|
594
|
+
--pack starter-500 \
|
|
595
|
+
--payment-method stripe_checkout \
|
|
596
|
+
--idempotency-key stripe-pack-quote-run-001 \
|
|
597
|
+
--json
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
For the browserless agent x402 rail, quote the exact method id returned by
|
|
601
|
+
`credits methods --json`:
|
|
602
|
+
|
|
603
|
+
```bash
|
|
604
|
+
luxin credits quote \
|
|
605
|
+
--pack starter-500 \
|
|
606
|
+
--payment-method stripe_x402.exact.usdc \
|
|
607
|
+
--idempotency-key agent-x402-quote-run-001 \
|
|
608
|
+
--json
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
For exact custom terms, keep the same rail choice. Use
|
|
612
|
+
`stripe_x402.exact.usdc` for an agent-settleable browserless rail, or use
|
|
613
|
+
`stripe_checkout` only for a human Checkout fallback:
|
|
614
|
+
|
|
615
|
+
```bash
|
|
616
|
+
luxin credits quote \
|
|
617
|
+
--credits 137 \
|
|
618
|
+
--payment-method stripe_checkout \
|
|
619
|
+
--idempotency-key exact-quote-run-001 \
|
|
620
|
+
--json
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
Minimum success data:
|
|
624
|
+
|
|
625
|
+
```json
|
|
626
|
+
{
|
|
627
|
+
"quote_id": "quote_...",
|
|
628
|
+
"state": "created",
|
|
629
|
+
"credits": 10,
|
|
630
|
+
"price_amount_cents": 10,
|
|
631
|
+
"currency": "USD",
|
|
632
|
+
"expires_at": "2026-05-08T20:00:00.000Z",
|
|
633
|
+
"accepted_payment_method": "stripe_checkout",
|
|
634
|
+
"idempotency_key": "quote-run-001",
|
|
635
|
+
"pack_id": null,
|
|
636
|
+
"pack": null,
|
|
637
|
+
"live_money": true,
|
|
638
|
+
"next_actions": {
|
|
639
|
+
"recommended_buy": {
|
|
640
|
+
"purpose": "complete_credit_top_up",
|
|
641
|
+
"recommendation_reason": "human_checkout_handoff",
|
|
642
|
+
"quote_id": "quote_...",
|
|
643
|
+
"method_id": "stripe_checkout",
|
|
644
|
+
"provider": "stripe",
|
|
645
|
+
"command": "luxin credits buy --provider stripe --quote-id quote_... --idempotency-key purchase:quote_... --json",
|
|
646
|
+
"buy_command_copy_runnable": true,
|
|
647
|
+
"purchase_idempotency_key": "purchase:quote_...",
|
|
648
|
+
"status_command": "luxin credits status --quote-id quote_... --json",
|
|
649
|
+
"status_command_copy_runnable": true,
|
|
650
|
+
"status_command_after_payment": "luxin credits status --payment-attempt-id PAYMENT_ATTEMPT_ID --json",
|
|
651
|
+
"status_command_after_payment_copy_runnable": false,
|
|
652
|
+
"requires_auth": true,
|
|
653
|
+
"live_money": true,
|
|
654
|
+
"requires_browser": true,
|
|
655
|
+
"agent_settleable": false,
|
|
656
|
+
"human_handoff_required": true,
|
|
657
|
+
"command_effect": {
|
|
658
|
+
"label": "live_money_payment_attempt_requires_completion",
|
|
659
|
+
"no_spend": false,
|
|
660
|
+
"payment_attempt": true,
|
|
661
|
+
"credit_debit": false,
|
|
662
|
+
"media_write": false,
|
|
663
|
+
"wallet_settlement": false
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
For x402 quotes, `accepted_payment_method` is
|
|
671
|
+
`"stripe_x402.exact.usdc"`. The quote does not grant credits or include pay-to
|
|
672
|
+
instructions; `data.next_actions.recommended_buy.command` carries the returned
|
|
673
|
+
`quote_id` and a stable non-secret purchase idempotency key for the
|
|
674
|
+
action-required deposit attempt. Run it only when delegated spend is allowed.
|
|
675
|
+
Use `data.next_actions.recommended_buy.status_command` to inspect the quote or
|
|
676
|
+
payment state by `quote_id`; after buy returns a `payment_attempt_id`, prefer
|
|
677
|
+
`status_command_after_payment`.
|
|
678
|
+
|
|
679
|
+
When `credits status --quote-id quote_... --json` sees an open
|
|
680
|
+
`stripe_x402.exact.usdc` or `stripe_checkout` quote, it repeats the exact
|
|
681
|
+
`data.next_actions.recommended_buy` command with the real `quote_id` and
|
|
682
|
+
`purchase:quote_...` idempotency key so agents do not need to reconstruct the
|
|
683
|
+
buy step from placeholders.
|
|
684
|
+
|
|
685
|
+
Hosted API equivalent:
|
|
686
|
+
|
|
687
|
+
```bash
|
|
688
|
+
curl -sS https://api.luxin.sh/v1/credit-quotes \
|
|
689
|
+
-H "authorization: Bearer $IMAGE_SKILL_TOKEN" \
|
|
690
|
+
-H "content-type: application/json" \
|
|
691
|
+
-d '{"pack_id":"starter-500","payment_method":"stripe_x402.exact.usdc","idempotency_key":"agent-x402-quote-run-001"}'
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### `luxin credits buy`
|
|
695
|
+
|
|
696
|
+
Creates a payment action for a previously returned quote. Choose the provider
|
|
697
|
+
that matches the quote's `accepted_payment_method`.
|
|
698
|
+
|
|
699
|
+
For a `stripe_x402.exact.usdc` quote, `--provider stripe_x402` creates a
|
|
700
|
+
browserless action-required USDC deposit attempt. When the response includes
|
|
701
|
+
`stripe_x402.payable_instructions`, a wallet-equipped agent may pay the exact
|
|
702
|
+
USDC amount to `deposit_address` on Base without using a browser. The response
|
|
703
|
+
is live money when `live_money:true`. Credits are granted only after verified
|
|
704
|
+
settlement and webhook fulfillment succeeds. Deposit challenge creation itself
|
|
705
|
+
must not mutate credit balances. Stay within the delegated cap and never pass
|
|
706
|
+
wallet private keys, seed phrases, x402 payment headers, deposit client
|
|
707
|
+
secrets, card data, Stripe secrets, or provider receipts to Luxin.
|
|
708
|
+
When `create --guide` enters `quota_required` for this rail, it returns
|
|
709
|
+
`data.self_fund_handoff.wallet_settlement` with the buy/status response fields
|
|
710
|
+
to inspect, plus `data.self_fund_handoff.first_safe_command` for no-spend rail
|
|
711
|
+
inspection before quote/buy: `data.stripe_x402.payable_instructions` after
|
|
712
|
+
`credits buy`, or
|
|
713
|
+
`data.payment_attempt.stripe_x402.payable_instructions` after `credits status`.
|
|
714
|
+
|
|
715
|
+
```bash
|
|
716
|
+
luxin credits buy \
|
|
717
|
+
--provider stripe_x402 \
|
|
718
|
+
--quote-id quote_... \
|
|
719
|
+
--idempotency-key agent-x402-buy-run-001 \
|
|
720
|
+
--json
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
Minimum x402 action-required data:
|
|
724
|
+
|
|
725
|
+
```json
|
|
726
|
+
{
|
|
727
|
+
"state": "action_required",
|
|
728
|
+
"quote_id": "quote_...",
|
|
729
|
+
"payment_attempt_id": "payatt_...",
|
|
730
|
+
"provider": "stripe",
|
|
731
|
+
"accepted_payment_method": "stripe_x402.exact.usdc",
|
|
732
|
+
"credits": 500,
|
|
733
|
+
"amount_cents": 500,
|
|
734
|
+
"currency": "USD",
|
|
735
|
+
"live_money": true,
|
|
736
|
+
"stripe_x402": {
|
|
737
|
+
"method_id": "stripe_x402.exact.usdc",
|
|
738
|
+
"scheme": "exact",
|
|
739
|
+
"network": "base",
|
|
740
|
+
"token_currency": "usdc",
|
|
741
|
+
"deposit_address_present": true,
|
|
742
|
+
"payable_instructions": {
|
|
743
|
+
"kind": "stripe_crypto_deposit",
|
|
744
|
+
"network": "base",
|
|
745
|
+
"token_currency": "usdc",
|
|
746
|
+
"token_decimals": 6,
|
|
747
|
+
"token_amount": "5.00",
|
|
748
|
+
"token_amount_atomic": "5000000",
|
|
749
|
+
"amount_cents": 500,
|
|
750
|
+
"amount_usd": "5.00",
|
|
751
|
+
"deposit_address": "0x...",
|
|
752
|
+
"token_contract_address": "0x...",
|
|
753
|
+
"supported_token_currencies": ["usdc"],
|
|
754
|
+
"expires_at": "2026-05-08T20:00:00.000Z",
|
|
755
|
+
"exact_amount_required": true
|
|
756
|
+
},
|
|
757
|
+
"redacted": {
|
|
758
|
+
"payment_intent_id": "[redacted-stripe-payment-intent]",
|
|
759
|
+
"deposit_address": "[redacted-stripe-crypto-deposit-address]",
|
|
760
|
+
"client_secret": "[redacted-stripe-client-secret]"
|
|
761
|
+
}
|
|
762
|
+
},
|
|
763
|
+
"next_actions": {
|
|
764
|
+
"recommended_settlement": {
|
|
765
|
+
"purpose": "settle_stripe_x402_credit_top_up",
|
|
766
|
+
"quote_id": "quote_...",
|
|
767
|
+
"payment_attempt_id": "payatt_...",
|
|
768
|
+
"method_id": "stripe_x402.exact.usdc",
|
|
769
|
+
"payable_instructions_path": "data.stripe_x402.payable_instructions",
|
|
770
|
+
"status_command": "luxin credits status --payment-attempt-id payatt_... --json",
|
|
771
|
+
"quota_command": "luxin usage quota --json",
|
|
772
|
+
"command_effect": {
|
|
773
|
+
"wallet_settlement": true,
|
|
774
|
+
"credit_debit": false,
|
|
775
|
+
"media_write": false
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
},
|
|
779
|
+
"next": {
|
|
780
|
+
"agent_action": "pay_stripe_crypto_deposit",
|
|
781
|
+
"suggested_commands": [
|
|
782
|
+
"luxin credits status --payment-attempt-id payatt_... --json"
|
|
783
|
+
]
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
For a `stripe_checkout` quote, `--provider stripe` creates a hosted Stripe
|
|
789
|
+
Checkout Session and returns an `action_required` response with
|
|
790
|
+
`checkout_handoff_url`.
|
|
791
|
+
|
|
792
|
+
Agents should present or open `checkout_handoff_url` for humans. It is a short
|
|
793
|
+
Luxin URL that redirects to Stripe Checkout and is safe to copy from
|
|
794
|
+
mobile terminals, SSH clients, and wrapped chat output. `checkout_compact_url`
|
|
795
|
+
is also copy-safe and equals the Luxin handoff when the hosted API can
|
|
796
|
+
provide one. `checkout_url` is the raw Stripe compatibility fallback only; do
|
|
797
|
+
not present it unless no handoff URL is available. Do not trim Stripe Checkout
|
|
798
|
+
URLs: the long `#...` fragment is required by Stripe Checkout in the browser.
|
|
799
|
+
Present any fallback Stripe URL in a fenced code block so terminal wrapping does
|
|
800
|
+
not corrupt it. Stripe-hosted Checkout may also show a promotion-code field for
|
|
801
|
+
operator-provided codes; agents should let the human enter those codes on
|
|
802
|
+
Stripe, never collect promo codes, card details, or wallet credentials in the
|
|
803
|
+
Luxin CLI.
|
|
804
|
+
|
|
805
|
+
```bash
|
|
806
|
+
luxin credits buy \
|
|
807
|
+
--provider stripe \
|
|
808
|
+
--quote-id quote_... \
|
|
809
|
+
--idempotency-key stripe-buy-run-001 \
|
|
810
|
+
--json
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
Minimum success data:
|
|
814
|
+
|
|
815
|
+
```json
|
|
816
|
+
{
|
|
817
|
+
"state": "action_required",
|
|
818
|
+
"quote_id": "quote_...",
|
|
819
|
+
"payment_attempt_id": "payatt_...",
|
|
820
|
+
"provider": "stripe",
|
|
821
|
+
"accepted_payment_method": "stripe_checkout",
|
|
822
|
+
"checkout_session_id": "cs_...",
|
|
823
|
+
"checkout_handoff_url": "https://api.luxin.sh/pay/payatt_...",
|
|
824
|
+
"checkout_compact_url": "https://api.luxin.sh/pay/payatt_...",
|
|
825
|
+
"checkout_url": "https://checkout.stripe.com/c/pay/cs_...#fid...",
|
|
826
|
+
"credits": 500,
|
|
827
|
+
"amount_cents": 500,
|
|
828
|
+
"currency": "USD",
|
|
829
|
+
"live_money": true,
|
|
830
|
+
"next": {
|
|
831
|
+
"human_action": "open_checkout_url",
|
|
832
|
+
"checkout_handoff_url": "https://api.luxin.sh/pay/payatt_...",
|
|
833
|
+
"checkout_compact_url": "https://api.luxin.sh/pay/payatt_...",
|
|
834
|
+
"fallback_checkout_url": "https://checkout.stripe.com/c/pay/cs_...#fid...",
|
|
835
|
+
"after_payment": "open checkout_handoff_url or checkout_compact_url; use the full checkout_url only if no Luxin handoff URL is available, and preserve its Stripe # fragment. Then poll luxin credits status --payment-attempt-id PAYMENT_ATTEMPT_ID --json or luxin usage quota --json; credits are granted only after verified webhook fulfillment"
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
Hosted API equivalent:
|
|
841
|
+
|
|
842
|
+
```bash
|
|
843
|
+
curl -sS https://api.luxin.sh/v1/credit-purchases/stripe-checkout-sessions \
|
|
844
|
+
-H "authorization: Bearer $IMAGE_SKILL_TOKEN" \
|
|
845
|
+
-H "content-type: application/json" \
|
|
846
|
+
-d '{"quote_id":"quote_...","idempotency_key":"stripe-buy-run-001"}'
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
x402 hosted API equivalent:
|
|
850
|
+
|
|
851
|
+
```bash
|
|
852
|
+
curl -sS https://api.luxin.sh/v1/credit-purchases/stripe-x402-deposits \
|
|
853
|
+
-H "authorization: Bearer $IMAGE_SKILL_TOKEN" \
|
|
854
|
+
-H "content-type: application/json" \
|
|
855
|
+
-d '{"quote_id":"quote_...","idempotency_key":"agent-x402-buy-run-001"}'
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
### `luxin credits status`
|
|
859
|
+
|
|
860
|
+
Without a payment reference, shows the current credit balance using the same
|
|
861
|
+
quota data as `luxin usage quota --json`. With a payment reference,
|
|
862
|
+
shows the durable state of a quote, x402 deposit attempt, Stripe Checkout
|
|
863
|
+
attempt, Checkout Session, or receipt. Use the referenced form after
|
|
864
|
+
`credits buy` so agents do not have to infer payment state from quota deltas
|
|
865
|
+
or activity text.
|
|
866
|
+
|
|
867
|
+
```bash
|
|
868
|
+
luxin credits status --json
|
|
869
|
+
luxin credits status \
|
|
870
|
+
--payment-attempt-id payatt_... \
|
|
871
|
+
--json
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
At most one reference flag is allowed: `--quote-id`,
|
|
875
|
+
`--payment-attempt-id`, `--checkout-session-id`, or `--receipt-id`. Passing no
|
|
876
|
+
reference returns the balance/quota state.
|
|
877
|
+
|
|
878
|
+
For Stripe x402 attempts that are still `action_required`, status responses
|
|
879
|
+
include `data.next_actions.recommended_settlement` with the same exact Base/USDC
|
|
880
|
+
payable instructions, a copy-runnable status command for the real
|
|
881
|
+
`payment_attempt_id`, and explicit effect flags showing this is wallet
|
|
882
|
+
settlement, not credit debit, media write, or provider generation work.
|
|
883
|
+
|
|
884
|
+
Minimum action-required data:
|
|
885
|
+
|
|
886
|
+
```json
|
|
887
|
+
{
|
|
888
|
+
"state": "action_required",
|
|
889
|
+
"quote": {
|
|
890
|
+
"quote_id": "quote_...",
|
|
891
|
+
"credits": 500,
|
|
892
|
+
"price_amount_cents": 500,
|
|
893
|
+
"accepted_payment_method": "stripe_checkout",
|
|
894
|
+
"pack_id": "starter-500",
|
|
895
|
+
"x402": null
|
|
896
|
+
},
|
|
897
|
+
"payment_attempt": {
|
|
898
|
+
"payment_attempt_id": "payatt_...",
|
|
899
|
+
"checkout_session_id": "cs_...",
|
|
900
|
+
"checkout_handoff_url": "https://api.luxin.sh/pay/payatt_...",
|
|
901
|
+
"checkout_compact_url": "https://api.luxin.sh/pay/payatt_...",
|
|
902
|
+
"checkout_url": "https://checkout.stripe.com/c/pay/cs_...#fid...",
|
|
903
|
+
"attempt_status": "requires_action"
|
|
904
|
+
},
|
|
905
|
+
"receipt": null,
|
|
906
|
+
"credit_event": null,
|
|
907
|
+
"next": {
|
|
908
|
+
"retry_after_seconds": 10,
|
|
909
|
+
"human_action": "open_checkout_url",
|
|
910
|
+
"checkout_handoff_url": "https://api.luxin.sh/pay/payatt_...",
|
|
911
|
+
"checkout_compact_url": "https://api.luxin.sh/pay/payatt_..."
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
Minimum success data includes `state: "succeeded"`, `receipt`,
|
|
917
|
+
`credit_event`, and the updated hosted `limits`.
|
|
918
|
+
|
|
919
|
+
Hosted API equivalent:
|
|
920
|
+
|
|
921
|
+
```bash
|
|
922
|
+
curl -sS "https://api.luxin.sh/v1/credit-purchases/status?payment_attempt_id=payatt_..." \
|
|
923
|
+
-H "authorization: Bearer $IMAGE_SKILL_TOKEN"
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
Do not pass card data, wallet secrets, provider receipts, Stripe secrets, MPP
|
|
927
|
+
tokens, SPTs, live x402 payment headers, deposit client secrets, wallet
|
|
928
|
+
private keys, seed phrases, or any payment credential to credits commands.
|
|
929
|
+
Stripe Checkout collects payment details only on Stripe-hosted pages; x402
|
|
930
|
+
settlement is handled by the agent/wallet against the returned redacted deposit
|
|
931
|
+
challenge, not by pasting credentials into Luxin. The public request
|
|
932
|
+
fields are `credits`, `pack_id`, `payment_method`, `quote_id`, status reference
|
|
933
|
+
IDs, and `idempotency_key`.
|
|
934
|
+
|
|
935
|
+
### `luxin models`
|
|
936
|
+
|
|
937
|
+
First-run creative discovery. Lists public models and shows the full
|
|
938
|
+
capability-preserving schema for one model.
|
|
939
|
+
|
|
940
|
+
```bash
|
|
941
|
+
luxin models --json
|
|
942
|
+
luxin models list --json
|
|
943
|
+
luxin models list --details --json
|
|
944
|
+
luxin models list --available --operation image.generate --json
|
|
945
|
+
luxin models list --available --operation image.edit --json
|
|
946
|
+
luxin models list --available --modality video --operation video.generate --json
|
|
947
|
+
luxin models list --query nano-banana --json
|
|
948
|
+
luxin models list --catalog-only --provider fal --json
|
|
949
|
+
luxin models show MODEL_ID --json
|
|
950
|
+
luxin models show nano-banana --json
|
|
951
|
+
luxin models show default --json
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
Hosted API equivalents:
|
|
955
|
+
|
|
956
|
+
```bash
|
|
957
|
+
curl -sS https://api.luxin.sh/v1/models
|
|
958
|
+
curl -sS 'https://api.luxin.sh/v1/models?available=true&modality=video&operation=video.generate'
|
|
959
|
+
curl -sS 'https://api.luxin.sh/v1/models?query=nano-banana'
|
|
960
|
+
curl -sS https://api.luxin.sh/v1/models/xai.grok-imagine-image
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
`models show` exposes operation support, media input/output types, parameter
|
|
964
|
+
schemas, defaults and fixed controls, cost and latency class, safety behavior,
|
|
965
|
+
and migration hints. Agents should inspect it before assuming a model supports
|
|
966
|
+
seeds, masks, reference images, transparent backgrounds, arbitrary aspect
|
|
967
|
+
ratios, image-size presets, output counts, resolution controls, safety
|
|
968
|
+
controls, or provider-native options.
|
|
969
|
+
|
|
970
|
+
`models list` is executable-first by default and returns one
|
|
971
|
+
`default: true` row when the default executable create model is included.
|
|
972
|
+
`models show default --json` resolves to that model so first-run agents can
|
|
973
|
+
inspect the recommended create surface without knowing a provider-specific
|
|
974
|
+
model id. `models show` also resolves common migration aliases such as
|
|
975
|
+
`nano-banana` to `fal.nano-banana-2`, while `models list --query QUERY --json`
|
|
976
|
+
returns fuzzy provider/model-family matches before an agent commits to one
|
|
977
|
+
model id. The list response also returns `summary` with total, returned,
|
|
978
|
+
available, executable, catalog-only, provider split,
|
|
979
|
+
`execution_availability`, first actionable model ids, recommended filter
|
|
980
|
+
commands, alias hints, provider/category discovery groups, and
|
|
981
|
+
catalog-inclusion flags. Default list output is a compact, sortable model menu
|
|
982
|
+
and excludes catalog-only rows so fresh agents see executable candidates first.
|
|
983
|
+
Each row keeps the model id, flat
|
|
984
|
+
`estimated_usd_per_image`, `credits_required`, lightweight `task_tags`, status,
|
|
985
|
+
provider, max output count/resolution, storage, and `show_command`, while
|
|
986
|
+
omitting full parameter schemas. Use `models show MODEL_ID --json` for one
|
|
987
|
+
model's full capability schema, or `models list --details --json` only when you
|
|
988
|
+
intentionally need the full list with capability schemas for compatibility or
|
|
989
|
+
offline analysis. `--summary` is still accepted as a compatibility alias for the
|
|
990
|
+
default compact list. Use `--available` for currently usable executable rows,
|
|
991
|
+
`--modality image|video|audio|3d` for media type, `--operation
|
|
992
|
+
image.generate`, `--operation image.edit`, `--operation video.generate`,
|
|
993
|
+
`--operation audio.generate`, or `--operation 3d.generate` for the task,
|
|
994
|
+
`--provider fal|xai|openai` to narrow by provider, `--query QUERY` to search
|
|
995
|
+
ids, display names, provider namespaces, operations, tags, intents, upstream
|
|
996
|
+
Fal endpoint ids, and known aliases, and `--catalog-only` when you intentionally
|
|
997
|
+
want source-backed rows that are inspectable but not runnable yet.
|
|
998
|
+
Provider-level availability is not the same thing as model executability; for
|
|
999
|
+
runnable choices require both `status:"available"` and
|
|
1000
|
+
`execution.model_execution_status:"executable"`. If a reachable provider has no
|
|
1001
|
+
runnable model for the requested operation, `summary.execution_availability`
|
|
1002
|
+
says so directly and includes the fastest `--available --operation ...`
|
|
1003
|
+
recovery command.
|
|
1004
|
+
|
|
1005
|
+
Luxin standardizes common controls so agents can work quickly, but it
|
|
1006
|
+
must not flatten rich model capabilities into coarse universal categories.
|
|
1007
|
+
Use `model_parameters` for rare or model-specific parameters advertised by the
|
|
1008
|
+
capability schema.
|
|
1009
|
+
|
|
1010
|
+
Current executable provider-native controls include:
|
|
1011
|
+
|
|
1012
|
+
- Fal FLUX.1 dev: `model_parameters.image_size` for presets such as
|
|
1013
|
+
`square_hd`, plus `seed`.
|
|
1014
|
+
- Fal FLUX Pro 1.1 Ultra Create: `model_parameters.seed` and
|
|
1015
|
+
`model_parameters.raw`; optional reference-image controls remain cataloged
|
|
1016
|
+
for inspection but are not executable on the create-only path.
|
|
1017
|
+
- Fal Z-Image Turbo Create/Edit: `model_parameters.image_size` for
|
|
1018
|
+
`square_hd`, `square`, portrait/landscape presets, and `auto` on edit; costs
|
|
1019
|
+
are quoted from requested megapixels when the output size is explicit.
|
|
1020
|
+
- Fal Nano Banana 2 Edit: `model_parameters.resolution` for `0.5K`, `1K`,
|
|
1021
|
+
`2K`, and `4K`, plus `seed`.
|
|
1022
|
+
- Fal Ideogram V2 Edit: `model_parameters.expand_prompt`, `seed`, and
|
|
1023
|
+
`style`; pass masks as top-level `--mask` / `mask_asset_id`, not as
|
|
1024
|
+
provider `mask_url`.
|
|
1025
|
+
- Fal Gemini 3 Pro Image Preview Create/Edit:
|
|
1026
|
+
`model_parameters.resolution` for `1K`, `2K`, and `4K`, plus `seed`; 4K is
|
|
1027
|
+
quoted as the higher-priced provider tier.
|
|
1028
|
+
- Fal Nano Banana Pro Create/Edit: `model_parameters.resolution` for `1K`,
|
|
1029
|
+
`2K`, and `4K`, plus `seed`; 4K is quoted as the higher-priced provider tier.
|
|
1030
|
+
- Fal FLUX Pro Kontext Pro/Max Edit: `model_parameters.seed`; guidance scale
|
|
1031
|
+
and aspect-ratio controls remain cataloged for inspection but are not
|
|
1032
|
+
executable until their UX and receipt behavior are represented.
|
|
1033
|
+
- Fal Bytedance Seedream 4.5 Create/Edit: `model_parameters.image_size` for
|
|
1034
|
+
`square_hd`, `square`, portrait/landscape presets, `auto_2K`, and
|
|
1035
|
+
`auto_4K`, plus `seed`; multi-output and multi-reference controls remain
|
|
1036
|
+
cataloged but fixed for hosted accounting.
|
|
1037
|
+
- Fal Bytedance Seedream 5.0 Lite Create/Edit:
|
|
1038
|
+
`model_parameters.image_size` for `square_hd`, `square`, portrait/landscape
|
|
1039
|
+
presets, `auto_2K`, and `auto_3K`; multi-output and multi-reference controls
|
|
1040
|
+
remain cataloged but fixed for hosted accounting.
|
|
1041
|
+
- xAI Grok Imagine Image Quality: `model_parameters.resolution` for `1k` and
|
|
1042
|
+
`2k`; 2k is priced from the higher provider tier. Create supports top-level
|
|
1043
|
+
`--output-count` up to the model's advertised `max_outputs_per_request`,
|
|
1044
|
+
currently mapped to xAI's documented `n` batch parameter.
|
|
1045
|
+
- GPT Image 1.5 create/edit: documented fixed sizes `1024x1024`,
|
|
1046
|
+
`1024x1536`, and `1536x1024`, output format, compression, transparent or
|
|
1047
|
+
opaque background, moderation, and the upstream provider-native quality
|
|
1048
|
+
parameter. GPT Image 1.5 create quotes output-token estimates when quality
|
|
1049
|
+
and concrete size are known; GPT Image 1.5 create supports top-level
|
|
1050
|
+
`--output-count` up to the model's advertised `max_outputs_per_request`,
|
|
1051
|
+
currently mapped to OpenAI's `n` parameter. GPT Image 1.5 edit accepts
|
|
1052
|
+
low/high `input_fidelity` and remains preflight unknown-cost until usage is
|
|
1053
|
+
returned.
|
|
1054
|
+
- GPT Image 2 create/edit: size, output format, compression, background,
|
|
1055
|
+
moderation, and the upstream provider-native quality parameter. GPT Image 2
|
|
1056
|
+
create quotes request-aware output-token estimates when quality and concrete
|
|
1057
|
+
size are known; GPT Image 2 create supports top-level `--output-count` up to
|
|
1058
|
+
the model's advertised `max_outputs_per_request`, currently mapped to
|
|
1059
|
+
OpenAI's `n` parameter. GPT Image 2 edit remains preflight unknown-cost, then
|
|
1060
|
+
records usage-priced provider cost when OpenAI returns token usage.
|
|
1061
|
+
|
|
1062
|
+
Inspect each model before use; provider-native controls are available only
|
|
1063
|
+
through validated `model_parameters`.
|
|
1064
|
+
|
|
1065
|
+
### `luxin capabilities`
|
|
1066
|
+
|
|
1067
|
+
Schema-language view over the same capability catalog. Use this when you need
|
|
1068
|
+
the capability abstraction directly rather than starting from a model.
|
|
1069
|
+
|
|
1070
|
+
```bash
|
|
1071
|
+
luxin capabilities --json
|
|
1072
|
+
luxin capabilities list --json
|
|
1073
|
+
luxin capabilities show CAPABILITY_ID --json
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
### `luxin create`
|
|
1077
|
+
|
|
1078
|
+
Guides, creates, or plans a zero-cost dry run.
|
|
1079
|
+
|
|
1080
|
+
Guide the first image path without mutation:
|
|
1081
|
+
|
|
1082
|
+
```bash
|
|
1083
|
+
luxin create --guide --prompt "A compact field camera on a stainless workbench" --json
|
|
1084
|
+
```
|
|
1085
|
+
|
|
1086
|
+
`create --guide` returns `schema: image-skill.create-guide.v1`,
|
|
1087
|
+
`stage`, `next_command`, `next_command_copy_runnable`,
|
|
1088
|
+
`next_command_missing_inputs`, `guide_warning`, `auth_ready`,
|
|
1089
|
+
`no_spend_evaluation`, `recommended_no_spend_command`,
|
|
1090
|
+
`self_fund_next_command`, `self_fund_handoff`, `self_fund_preparation`,
|
|
1091
|
+
`escape_hatches`, selected executable model and cost, auth/quota/payment
|
|
1092
|
+
blockers, and mutation flags. All
|
|
1093
|
+
mutation flags must be false in guide mode: no provider call, hosted create,
|
|
1094
|
+
signup, payment object, credit debit, or media write.
|
|
1095
|
+
For next-command safety, read `next_command_copy_runnable`,
|
|
1096
|
+
`next_command_missing_inputs`, and `guide_warning.next_command_safety` before
|
|
1097
|
+
acting: `hosted_signup_no_spend_setup` is no-spend auth setup,
|
|
1098
|
+
`live_money_payment_action` is top-up/payment work, and
|
|
1099
|
+
`live_media_create_credit_debit` is a live create that can call a provider,
|
|
1100
|
+
debit credits, and write media.
|
|
1101
|
+
For payment state, read
|
|
1102
|
+
`checks.payments.preferred_method_summary.top_up_path` instead of inferring
|
|
1103
|
+
from several arrays. It is `browserless_agent_self_fund` when the preferred
|
|
1104
|
+
rail is live money, browserless, agent initiated, and agent settleable;
|
|
1105
|
+
`human_payment_handoff` when a human/browser completion step is required; and
|
|
1106
|
+
`payment_method_inspection` when the guide cannot classify a direct top-up path.
|
|
1107
|
+
In guide cost output, `cost.estimated_usd_per_image` is the estimated Image
|
|
1108
|
+
Skill debit in dollars for one output, matching
|
|
1109
|
+
`cost.estimated_debit_usd_per_image` and
|
|
1110
|
+
`cost.estimated_credits * cost.credit_unit_usd` when credit pricing is known.
|
|
1111
|
+
`cost.estimated_provider_usd_per_image` is the upstream provider estimate for
|
|
1112
|
+
transparency; do not use it as the amount the agent needs to fund.
|
|
1113
|
+
|
|
1114
|
+
```bash
|
|
1115
|
+
luxin create \
|
|
1116
|
+
--prompt "A compact field camera on a stainless workbench" \
|
|
1117
|
+
--intent explore \
|
|
1118
|
+
--aspect-ratio 1:1 \
|
|
1119
|
+
--max-estimated-usd-per-image 0.07 \
|
|
1120
|
+
--json
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1123
|
+
Hosted defaults are quality-first. If an agent does not choose a model, Image
|
|
1124
|
+
Skill selects the strongest available create capability for the requested
|
|
1125
|
+
intent and budget, then records the decision in `request.selection`. Explicit
|
|
1126
|
+
`--provider`, `--model`, namespaced model ids, and validated
|
|
1127
|
+
`model_parameters` always take precedence. For final/product/hero-style
|
|
1128
|
+
intents, Luxin may default an eligible quality-capability request to a
|
|
1129
|
+
higher output tier only when `--max-estimated-usd-per-image` is high enough for
|
|
1130
|
+
that tier; otherwise it stays on a lower-cost quality tier or chooses a cheaper
|
|
1131
|
+
capability within the budget and tells agents what happened in the selection
|
|
1132
|
+
receipt. Use the `--max-estimated-usd-per-image` value returned by
|
|
1133
|
+
`create --guide`; it is sized to the Luxin credit debit, not only the
|
|
1134
|
+
upstream provider estimate.
|
|
1135
|
+
|
|
1136
|
+
Preview-compatible richer shape:
|
|
1137
|
+
|
|
1138
|
+
```bash
|
|
1139
|
+
luxin create \
|
|
1140
|
+
--prompt "Campaign-ready product image of a compact field camera" \
|
|
1141
|
+
--intent finalize \
|
|
1142
|
+
--model MODEL_ID \
|
|
1143
|
+
--aspect-ratio 1:1 \
|
|
1144
|
+
--output-count 2 \
|
|
1145
|
+
--max-estimated-usd-per-image 0.07 \
|
|
1146
|
+
--model-parameters-json '{"seed":1234}' \
|
|
1147
|
+
--json
|
|
1148
|
+
```
|
|
1149
|
+
|
|
1150
|
+
Use `--output-count N` only when `models show MODEL_ID --json` advertises
|
|
1151
|
+
`media.output.max_outputs_per_request` greater than `1`. `--output-count` is a
|
|
1152
|
+
top-level Luxin create control; do not pass provider-native `n` through
|
|
1153
|
+
`model_parameters` unless the selected model schema explicitly advertises that
|
|
1154
|
+
field. Credit pricing and `cost.credit_pricing.credits_required` are total
|
|
1155
|
+
operation debits across all requested outputs. `--max-estimated-usd-per-image`
|
|
1156
|
+
and raw API `max_estimated_usd_per_image` are per-image Luxin debit
|
|
1157
|
+
budget guards.
|
|
1158
|
+
|
|
1159
|
+
Generate video through the same `create` command and durable-media loop. For
|
|
1160
|
+
video prompts, run `luxin create --guide --prompt "..." --json`; the guide
|
|
1161
|
+
can select the executable video model, suggest `--aspect-ratio 16:9`, and emit
|
|
1162
|
+
the next create command. Plain `create` without a model still defaults to an
|
|
1163
|
+
image model, so use the guide or pass the video model id directly. The response
|
|
1164
|
+
returns a durable owned `video_...` mp4 asset URL, a `job_id`, and a
|
|
1165
|
+
`cost.credit_pricing` receipt just like an image create.
|
|
1166
|
+
|
|
1167
|
+
```bash
|
|
1168
|
+
luxin create \
|
|
1169
|
+
--model fal.ltx-video-13b-distilled \
|
|
1170
|
+
--prompt "A slow dolly push-in on a steaming espresso cup on a cafe counter, morning light" \
|
|
1171
|
+
--aspect-ratio 16:9 \
|
|
1172
|
+
--json
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
Discover runnable video models with `luxin models list --available
|
|
1176
|
+
--modality video --operation video.generate --json`. Inspect parameters, output
|
|
1177
|
+
media type, and cost first with `luxin models show
|
|
1178
|
+
fal.ltx-video-13b-distilled --json`. Video runs synchronously through the same
|
|
1179
|
+
create call and can take longer than an image; the returned `assets[].url` is an
|
|
1180
|
+
owned `video/mp4`.
|
|
1181
|
+
|
|
1182
|
+
Generate audio (music, sound) through the same `create` command and
|
|
1183
|
+
durable-media loop. Request an audio model by id; the response returns a durable
|
|
1184
|
+
owned `audio_...` wav asset URL, a `job_id`, and a `cost.credit_pricing` receipt
|
|
1185
|
+
just like an image create. Audio has no aspect ratio, so do not pass
|
|
1186
|
+
`--aspect-ratio`.
|
|
1187
|
+
|
|
1188
|
+
```bash
|
|
1189
|
+
luxin create \
|
|
1190
|
+
--model fal.stable-audio-25-text-to-audio \
|
|
1191
|
+
--prompt "A warm lo-fi hip-hop loop with vinyl crackle and a mellow Rhodes piano" \
|
|
1192
|
+
--json
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
`fal.stable-audio-25-text-to-audio` (Stable Audio 2.5) is text-to-audio at a flat
|
|
1196
|
+
$0.20/clip (about 34 credits, quoted before spend) and returns an owned
|
|
1197
|
+
`audio/wav` clip. The first slice is defaults-only (no tunable
|
|
1198
|
+
`model_parameters`); duration/steps controls are a later milestone. Inspect
|
|
1199
|
+
parameters, output media type, and cost first with `luxin models show
|
|
1200
|
+
fal.stable-audio-25-text-to-audio --json`. Audio runs synchronously through the
|
|
1201
|
+
same create call and can take longer than an image.
|
|
1202
|
+
|
|
1203
|
+
For create models with wired reference support, pass owned reference assets
|
|
1204
|
+
with the model's advertised reference role. Kling element routes use
|
|
1205
|
+
`--element-frontal IMAGE[@ELEMENT_INDEX]` and
|
|
1206
|
+
`--element-reference IMAGE[@ELEMENT_INDEX[:REFERENCE_INDEX]]`; flat
|
|
1207
|
+
reference-image routes use `--reference-image IMAGE[@INDEX]`; Fal DreamO also
|
|
1208
|
+
accepts `:TASK` where `TASK` is `ip`, `id`, or `style`. The public CLI uploads
|
|
1209
|
+
local paths and external URLs first, then
|
|
1210
|
+
sends top-level `references[]` entries with Luxin `asset_id` values to
|
|
1211
|
+
`/v1/create`. Do not pass provider-native `elements`, `frontal_image_url`,
|
|
1212
|
+
`reference_image_urls`, `first_image_url`, `second_image_url`, `images`, or
|
|
1213
|
+
`*_reference_task` through `model_parameters`; provider-private URLs are
|
|
1214
|
+
resolved server-side after ownership and media-policy validation.
|
|
1215
|
+
|
|
1216
|
+
```bash
|
|
1217
|
+
luxin create \
|
|
1218
|
+
--model fal.kling-image-o3-text-to-image \
|
|
1219
|
+
--prompt "Place the same character in a clean studio campaign" \
|
|
1220
|
+
--element-frontal ./character-front.png@0 \
|
|
1221
|
+
--element-reference ./character-side.webp@0:0 \
|
|
1222
|
+
--output-count 2 \
|
|
1223
|
+
--max-estimated-usd-per-image 0.06 \
|
|
1224
|
+
--json
|
|
1225
|
+
```
|
|
1226
|
+
|
|
1227
|
+
```bash
|
|
1228
|
+
luxin create \
|
|
1229
|
+
--model fal.dreamo \
|
|
1230
|
+
--prompt "Studio portrait preserving identity with a bolder editorial style" \
|
|
1231
|
+
--reference-image ./identity.png@0:id \
|
|
1232
|
+
--reference-image ./style.webp@1:style \
|
|
1233
|
+
--model-parameters-json '{"image_size":{"width":1280,"height":720}}' \
|
|
1234
|
+
--max-estimated-usd-per-image 0.06 \
|
|
1235
|
+
--json
|
|
1236
|
+
```
|
|
1237
|
+
|
|
1238
|
+
High-resolution examples:
|
|
1239
|
+
|
|
1240
|
+
```bash
|
|
1241
|
+
luxin create \
|
|
1242
|
+
--prompt "Campaign-ready product image of a compact field camera" \
|
|
1243
|
+
--intent final \
|
|
1244
|
+
--max-estimated-usd-per-image 0.07 \
|
|
1245
|
+
--json
|
|
1246
|
+
|
|
1247
|
+
luxin create \
|
|
1248
|
+
--prompt "Campaign-ready product image of a compact field camera" \
|
|
1249
|
+
--model fal.gemini-3-pro-image-preview \
|
|
1250
|
+
--model-parameters-json '{"resolution":"4K"}' \
|
|
1251
|
+
--max-estimated-usd-per-image 0.30 \
|
|
1252
|
+
--json
|
|
1253
|
+
|
|
1254
|
+
luxin create \
|
|
1255
|
+
--prompt "Campaign-ready product image of a compact field camera" \
|
|
1256
|
+
--model xai.grok-imagine-image-quality \
|
|
1257
|
+
--model-parameters-json '{"resolution":"2k"}' \
|
|
1258
|
+
--max-estimated-usd-per-image 0.07 \
|
|
1259
|
+
--json
|
|
1260
|
+
|
|
1261
|
+
luxin edit \
|
|
1262
|
+
--input-asset-id image_... \
|
|
1263
|
+
--prompt "preserve the subject and make this campaign-ready" \
|
|
1264
|
+
--model fal.nano-banana-2-edit \
|
|
1265
|
+
--model-parameters-json '{"resolution":"4K"}' \
|
|
1266
|
+
--accept-unknown-cost \
|
|
1267
|
+
--json
|
|
1268
|
+
```
|
|
1269
|
+
|
|
1270
|
+
`model_parameters` must be validated against the selected model/capability
|
|
1271
|
+
schema before any provider call or paid reservation. Unknown fields fail closed
|
|
1272
|
+
unless the capability explicitly allows additional properties. This is how
|
|
1273
|
+
Luxin preserves rare model controls without turning every
|
|
1274
|
+
provider-specific parameter into a top-level flag.
|
|
1275
|
+
In the current preview, Fal create/edit, xAI quality generation, and OpenAI GPT
|
|
1276
|
+
Image 2 expose the executable provider-native controls listed in the selected
|
|
1277
|
+
model schema. GPT Image 2 create has request-aware output-token credit quotes
|
|
1278
|
+
for concrete quality/size requests; GPT Image 2 edit still requires
|
|
1279
|
+
unknown-cost acceptance before execution, but records usage-priced provider cost
|
|
1280
|
+
after execution when OpenAI returns token usage. Provider-native controls remain
|
|
1281
|
+
visible for planning and fail closed until their capability schema marks them
|
|
1282
|
+
executable. Hosted `create --dry-run` validates `model_parameters` against the
|
|
1283
|
+
selected model, returns accepted keys/provenance and request-aware credit
|
|
1284
|
+
pricing for planning, and never executes provider controls or consumes credits.
|
|
1285
|
+
Hosted `edit --dry-run` validates the same owned input, mask/reference,
|
|
1286
|
+
prompt-policy, budget, and `model_parameters` checks as a live edit, then
|
|
1287
|
+
returns planned outputs without storage, provider, or billing side effects.
|
|
1288
|
+
For dry-run responses, `cost.credit_pricing.credits_required` is the planned
|
|
1289
|
+
live execution debit for the selected model. The actual debit for the dry run is
|
|
1290
|
+
`quota.consumed_credits: 0`.
|
|
1291
|
+
Authenticated hosted dry-runs also create a recoverable planned job:
|
|
1292
|
+
`jobs show` returns `status: "planned"` with `plan_receipt`, and `activity`
|
|
1293
|
+
emits `job.planned`. Planned receipts do not create downloadable media assets or
|
|
1294
|
+
usage debits, media writes, or provider execution. In the first-run guide, this
|
|
1295
|
+
exact no-spend command behavior is exposed as
|
|
1296
|
+
`data.no_spend_next_command_effect` and
|
|
1297
|
+
`data.recommended_no_spend_command_effect`; the evaluator stop policy is exposed
|
|
1298
|
+
as `data.no_spend_evaluation`.
|
|
1299
|
+
|
|
1300
|
+
Minimum success data:
|
|
1301
|
+
|
|
1302
|
+
```json
|
|
1303
|
+
{
|
|
1304
|
+
"job_id": "job_...",
|
|
1305
|
+
"capability": {
|
|
1306
|
+
"id": "is.image.generate.xai-grok-imagine-image-quality.v1"
|
|
1307
|
+
},
|
|
1308
|
+
"assets": [
|
|
1309
|
+
{
|
|
1310
|
+
"asset_id": "image_...",
|
|
1311
|
+
"path": "https://media.image-skill.com/a/image_abc123.png",
|
|
1312
|
+
"mime_type": "image/png",
|
|
1313
|
+
"url": "https://media.image-skill.com/a/image_abc123.png",
|
|
1314
|
+
"content_length": 333444,
|
|
1315
|
+
"width": 2048,
|
|
1316
|
+
"height": 2048
|
|
1317
|
+
}
|
|
1318
|
+
],
|
|
1319
|
+
"cost": {
|
|
1320
|
+
"estimated_usd": 0.07,
|
|
1321
|
+
"credit_pricing": {
|
|
1322
|
+
"credit_unit_usd": 0.01,
|
|
1323
|
+
"credits_required": 12,
|
|
1324
|
+
"estimated_provider_cost_usd": 0.07,
|
|
1325
|
+
"estimated_revenue_usd": 0.12,
|
|
1326
|
+
"pricing_confidence": "known"
|
|
1327
|
+
}
|
|
1328
|
+
},
|
|
1329
|
+
"request": {
|
|
1330
|
+
"output_count": 1,
|
|
1331
|
+
"selection": {
|
|
1332
|
+
"policy": "hosted_default_create_v1",
|
|
1333
|
+
"reason": "hosted default selected the strongest currently available quality-first create model",
|
|
1334
|
+
"intent": "explore",
|
|
1335
|
+
"capability": {
|
|
1336
|
+
"id": "is.image.generate.xai-grok-imagine-image-quality.v1"
|
|
1337
|
+
},
|
|
1338
|
+
"model_parameters": {
|
|
1339
|
+
"keys": ["resolution"],
|
|
1340
|
+
"defaults_applied": ["resolution=2k"],
|
|
1341
|
+
"source": "default_policy"
|
|
1342
|
+
},
|
|
1343
|
+
"output": {
|
|
1344
|
+
"resolution_class": "2k",
|
|
1345
|
+
"expected_width": null,
|
|
1346
|
+
"expected_height": null,
|
|
1347
|
+
"expected_min_short_edge": 2048
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
},
|
|
1351
|
+
"safety": {
|
|
1352
|
+
"status": "allowed"
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
```
|
|
1356
|
+
|
|
1357
|
+
When hosted artifact storage is configured, `url` is an Luxin-owned URL.
|
|
1358
|
+
Agents should prefer `assets[].url` over provider-origin URLs and should not
|
|
1359
|
+
need provider account access to fetch outputs.
|
|
1360
|
+
|
|
1361
|
+
Hosted create does not accept `--output-dir`. A future download/fetch command
|
|
1362
|
+
may add CLI-side local file convenience while preserving hosted artifact URLs as
|
|
1363
|
+
the source of truth.
|
|
1364
|
+
|
|
1365
|
+
If provider generation succeeds but artifact storage fails, the command returns
|
|
1366
|
+
`ARTIFACT_STORAGE_WRITE_FAILED` with exit `9` and `retryable: false`. Agents
|
|
1367
|
+
should not retry the whole create blindly, because that may duplicate paid
|
|
1368
|
+
provider spend.
|
|
1369
|
+
|
|
1370
|
+
For retry-safe create automation, pass an explicit non-secret
|
|
1371
|
+
`--idempotency-key`. A retry that reuses the same key does not create a second
|
|
1372
|
+
credit reservation, so a transient `502`/`PROVIDER_FAILURE` that already
|
|
1373
|
+
reserved a credit cannot double-charge on retry. `create --guide` bakes a
|
|
1374
|
+
generated `--idempotency-key` into its advertised create `next_command`, and a
|
|
1375
|
+
retryable create error returns an `error.recovery.idempotency_key` plus an
|
|
1376
|
+
`error.recovery.suggested_command` that re-runs the same create with that key.
|
|
1377
|
+
|
|
1378
|
+
Live non-dry-run create/edit emits one JSON diagnostic line to stderr before
|
|
1379
|
+
the blocking hosted request:
|
|
1380
|
+
|
|
1381
|
+
```json
|
|
1382
|
+
{
|
|
1383
|
+
"in_flight": {
|
|
1384
|
+
"command": "luxin create",
|
|
1385
|
+
"idempotency_key": "create-...",
|
|
1386
|
+
"recover_command": "luxin create --idempotency-key create-... <same arguments> --json"
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
```
|
|
1390
|
+
|
|
1391
|
+
stdout remains the command JSON envelope. If an agent combines streams with
|
|
1392
|
+
`2>&1`, split stderr diagnostics from the stdout envelope before parsing. The
|
|
1393
|
+
same recovery breadcrumb is stored under `<config-dir>/in-flight/` and appears
|
|
1394
|
+
in `luxin doctor --json` at `data.in_flight`. Keep the in-flight
|
|
1395
|
+
`idempotency_key` and `recover_command` inside the agent workflow unless a
|
|
1396
|
+
failed or uncertain operation needs user-visible recovery.
|
|
1397
|
+
|
|
1398
|
+
```bash
|
|
1399
|
+
luxin create \
|
|
1400
|
+
--prompt "A compact field camera on a stainless workbench" \
|
|
1401
|
+
--idempotency-key create-run-001 \
|
|
1402
|
+
--json
|
|
1403
|
+
```
|
|
1404
|
+
|
|
1405
|
+
Hosted free-preview API equivalent:
|
|
1406
|
+
|
|
1407
|
+
```bash
|
|
1408
|
+
curl -sS https://api.luxin.sh/v1/create \
|
|
1409
|
+
-H "authorization: Bearer $IMAGE_SKILL_TOKEN" \
|
|
1410
|
+
-H "content-type: application/json" \
|
|
1411
|
+
-d '{
|
|
1412
|
+
"prompt": "A compact field camera on a stainless workbench",
|
|
1413
|
+
"intent": "explore",
|
|
1414
|
+
"aspect_ratio": "1:1",
|
|
1415
|
+
"output_count": 1,
|
|
1416
|
+
"max_estimated_usd_per_image": 0.07
|
|
1417
|
+
}'
|
|
1418
|
+
```
|
|
1419
|
+
|
|
1420
|
+
Hosted free-preview create currently requires owned artifact storage and returns
|
|
1421
|
+
one `assets[]` entry per output with `assets[].url` under
|
|
1422
|
+
`https://media.image-skill.com/...` on success.
|
|
1423
|
+
|
|
1424
|
+
### `luxin upload`
|
|
1425
|
+
|
|
1426
|
+
Normalizes a local image path or remote image URL into an Luxin-owned
|
|
1427
|
+
input asset for later edit workflows.
|
|
1428
|
+
|
|
1429
|
+
```bash
|
|
1430
|
+
luxin upload ./source.png --json
|
|
1431
|
+
luxin upload https://example.com/source.png --json
|
|
1432
|
+
```
|
|
1433
|
+
|
|
1434
|
+
The CLI reads local files and remote URLs client-side, then sends image bytes to
|
|
1435
|
+
`POST /v1/upload`. The hosted API does not fetch arbitrary remote URLs in this
|
|
1436
|
+
preview. This keeps server-side URL fetching out of the public upload path.
|
|
1437
|
+
|
|
1438
|
+
Minimum success data:
|
|
1439
|
+
|
|
1440
|
+
```json
|
|
1441
|
+
{
|
|
1442
|
+
"request": {
|
|
1443
|
+
"source_kind": "local_path",
|
|
1444
|
+
"filename": "source.png",
|
|
1445
|
+
"remote_origin": null
|
|
1446
|
+
},
|
|
1447
|
+
"asset": {
|
|
1448
|
+
"asset_id": "image_...",
|
|
1449
|
+
"job_id": "job_...",
|
|
1450
|
+
"kind": "uploaded",
|
|
1451
|
+
"url": "https://media.image-skill.com/a/image_abc123.png",
|
|
1452
|
+
"mime_type": "image/png",
|
|
1453
|
+
"content_length": 12345
|
|
1454
|
+
},
|
|
1455
|
+
"upload": {
|
|
1456
|
+
"bytes": 12345,
|
|
1457
|
+
"mime_type": "image/png",
|
|
1458
|
+
"sha256": "...",
|
|
1459
|
+
"policy": {
|
|
1460
|
+
"status": "allowed"
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
```
|
|
1465
|
+
|
|
1466
|
+
Supported preview MIME types are `image/png`, `image/jpeg`, `image/webp`,
|
|
1467
|
+
`image/gif`, and `image/avif`. Unsupported input returns
|
|
1468
|
+
`INPUT_POLICY_DENIED` with exit `6`. Responses never include local paths, raw
|
|
1469
|
+
bytes, base64 payloads, full remote URLs, bucket names, or object keys.
|
|
1470
|
+
|
|
1471
|
+
### `luxin edit`
|
|
1472
|
+
|
|
1473
|
+
Edits an Luxin-owned input asset or client-normalized local/remote image
|
|
1474
|
+
with one hosted provider-backed edit model.
|
|
1475
|
+
|
|
1476
|
+
```bash
|
|
1477
|
+
luxin edit \
|
|
1478
|
+
--input ASSET_ID_OR_PATH_OR_URL \
|
|
1479
|
+
--mask MASK_ASSET_ID_OR_PATH_OR_URL \
|
|
1480
|
+
--prompt "Remove the background and keep natural object shadows" \
|
|
1481
|
+
--accept-unknown-cost \
|
|
1482
|
+
--json
|
|
1483
|
+
```
|
|
1484
|
+
|
|
1485
|
+
If `--input` is a local path or external URL, the public CLI first normalizes it
|
|
1486
|
+
through the same upload resolver as `luxin upload`, then sends only the
|
|
1487
|
+
resulting `asset_id` to `POST /v1/edit`. If `--input` is an Luxin asset id
|
|
1488
|
+
or owned asset URL, edit uses that owned asset directly.
|
|
1489
|
+
Add `--dry-run` to plan the edit after owned-asset, prompt-policy,
|
|
1490
|
+
`model_parameters`, and budget validation. Dry-run edit responses return planned
|
|
1491
|
+
assets and `quota.consumed_credits: 0`, store a recoverable `job.planned`
|
|
1492
|
+
receipt, and do not call the provider, debit credits, or write media.
|
|
1493
|
+
For models with wired mask support, `--mask` follows the same upload/asset-id
|
|
1494
|
+
resolver and sends only `mask_asset_id`; never pass provider-native `mask_url`
|
|
1495
|
+
through `model_parameters`.
|
|
1496
|
+
For models with wired reference support, pass owned reference assets with the
|
|
1497
|
+
model's advertised reference role. Kling element routes use
|
|
1498
|
+
`--element-frontal IMAGE[@ELEMENT_INDEX]` and
|
|
1499
|
+
`--element-reference IMAGE[@ELEMENT_INDEX[:REFERENCE_INDEX]]`; flat
|
|
1500
|
+
reference-image routes use `--reference-image IMAGE[@INDEX[:TASK]]`. The
|
|
1501
|
+
public CLI uploads local paths and external URLs first, then sends top-level
|
|
1502
|
+
`references[]` entries with Luxin `asset_id` values. For Kling element
|
|
1503
|
+
routes, `--element-frontal ./front.png@0` becomes role `element_frontal` for
|
|
1504
|
+
element index `0`, and `--element-reference ./side.webp@0:0` becomes role
|
|
1505
|
+
`element_reference` for the same element with reference slot `0`. For DreamO
|
|
1506
|
+
create, `--reference-image ./identity.png@0:id` becomes role
|
|
1507
|
+
`reference_image`, index `0`, and `reference_task` `id`. For xAI edit,
|
|
1508
|
+
`--reference-image ./reference.png@0` becomes the second ordered source image;
|
|
1509
|
+
the primary `--input` asset remains the first source image. Do not pass
|
|
1510
|
+
provider-native `elements`, `image_url`, `image_urls`, `frontal_image_url`,
|
|
1511
|
+
`reference_image_urls`, `first_image_url`, `second_image_url`, `images`, or
|
|
1512
|
+
`*_reference_task` through `model_parameters`; provider-private URLs are
|
|
1513
|
+
resolved server-side after ownership and media-policy validation.
|
|
1514
|
+
Current public `references[]` support covers Kling Image O1, Kling Image O3
|
|
1515
|
+
image-to-image/text-to-image, Kling Image v3 image-to-image/text-to-image, and
|
|
1516
|
+
Fal DreamO create plus xAI Grok Imagine image edit/quality edit. Kling requests
|
|
1517
|
+
may contain at most 40 reference entries across at most 10 contiguous element
|
|
1518
|
+
indexes starting at `0`; each referenced element requires one frontal image and
|
|
1519
|
+
may include up to three additional reference images. DreamO accepts up to two
|
|
1520
|
+
contiguous `reference_image` indexes starting at `0`, each with optional
|
|
1521
|
+
`reference_task` `ip`, `id`, or `style`. xAI edit accepts up to two contiguous
|
|
1522
|
+
`reference_image` indexes starting at `0` and does not accept `reference_task`.
|
|
1523
|
+
Reference assets must be Luxin-owned PNG, JPEG, or WebP images with
|
|
1524
|
+
known non-empty byte length up to 10MB, known width and height of at least
|
|
1525
|
+
300px, and aspect ratio from 0.40 to 2.50.
|
|
1526
|
+
|
|
1527
|
+
```bash
|
|
1528
|
+
luxin edit \
|
|
1529
|
+
--model fal.kling-image-o3-image-to-image \
|
|
1530
|
+
--input ./starting-frame.png \
|
|
1531
|
+
--element-frontal ./character-front.png@0 \
|
|
1532
|
+
--element-reference ./character-side.webp@0:0 \
|
|
1533
|
+
--prompt "Place the same character in a clean studio product portrait" \
|
|
1534
|
+
--accept-unknown-cost \
|
|
1535
|
+
--json
|
|
1536
|
+
```
|
|
1537
|
+
|
|
1538
|
+
Direct `/v1/edit` callers use the same owned-asset contract:
|
|
1539
|
+
|
|
1540
|
+
```json
|
|
1541
|
+
{
|
|
1542
|
+
"input_asset_id": "image_starting_frame",
|
|
1543
|
+
"model": "fal.kling-image-o3-image-to-image",
|
|
1544
|
+
"prompt": "Place the same character in a clean studio product portrait",
|
|
1545
|
+
"references": [
|
|
1546
|
+
{
|
|
1547
|
+
"asset_id": "image_character_front",
|
|
1548
|
+
"role": "element_frontal",
|
|
1549
|
+
"index": 0
|
|
1550
|
+
},
|
|
1551
|
+
{
|
|
1552
|
+
"asset_id": "image_character_side",
|
|
1553
|
+
"role": "element_reference",
|
|
1554
|
+
"index": 0,
|
|
1555
|
+
"reference_index": 0
|
|
1556
|
+
}
|
|
1557
|
+
]
|
|
1558
|
+
}
|
|
1559
|
+
```
|
|
1560
|
+
|
|
1561
|
+
Set `dry_run: true` on `/v1/edit` to get the same no-spend plan the CLI returns.
|
|
1562
|
+
The server still validates ownership, prompt policy, references, masks,
|
|
1563
|
+
`model_parameters`, and budget guards before returning the planned job.
|
|
1564
|
+
|
|
1565
|
+
Create a 3D asset from an image through the same `edit` command and
|
|
1566
|
+
durable-media loop. Image-to-3D is promptless and image-conditioned, so it ships
|
|
1567
|
+
as a variation transform: pass exactly one owned input image (no prompt) to a 3D
|
|
1568
|
+
model by id and the response returns a durable owned `.glb` mesh asset URL (in
|
|
1569
|
+
`assets[].url`), a `job_id`, and a `cost.credit_pricing` receipt. A 3D mesh has
|
|
1570
|
+
no aspect ratio.
|
|
1571
|
+
|
|
1572
|
+
```bash
|
|
1573
|
+
luxin edit \
|
|
1574
|
+
--input image_... \
|
|
1575
|
+
--model fal.trellis-image-to-3d \
|
|
1576
|
+
--json
|
|
1577
|
+
```
|
|
1578
|
+
|
|
1579
|
+
`fal.trellis-image-to-3d` (Trellis) is image-to-3D at a flat $0.02/asset (about 4
|
|
1580
|
+
credits, quoted before spend) and returns an owned `model/gltf-binary` (`.glb`)
|
|
1581
|
+
textured mesh. The first slice is defaults-only (no tunable `model_parameters`);
|
|
1582
|
+
guidance/steps/mesh_simplify/texture_size controls are a later milestone. Inspect
|
|
1583
|
+
parameters, output media type, and cost first with `luxin models show
|
|
1584
|
+
fal.trellis-image-to-3d --json`. The input must be one Luxin-owned image;
|
|
1585
|
+
3D runs synchronously through the same edit call and can take longer than an
|
|
1586
|
+
image.
|
|
1587
|
+
|
|
1588
|
+
Preview hosted create/edit supports model-specific provider-backed paths such
|
|
1589
|
+
as Fal Gemini 3 Pro Image Preview Create (`fal.gemini-3-pro-image-preview`),
|
|
1590
|
+
Fal Nano Banana 2 Edit (`fal.nano-banana-2-edit`), Fal Ideogram V2 Edit
|
|
1591
|
+
(`fal.ideogram-v2-edit`), Fal Gemini 3 Pro Image
|
|
1592
|
+
Preview Edit (`fal.gemini-3-pro-image-preview-edit`), Fal FLUX Pro 1.1 Ultra
|
|
1593
|
+
Create (`fal.flux-pro-v1-1-ultra`), Fal FLUX Pro Kontext Edit
|
|
1594
|
+
(`fal.flux-pro-kontext`), Fal FLUX Pro Kontext Max Edit
|
|
1595
|
+
(`fal.flux-pro-kontext-max`), Fal Seedream 5.0 Lite Create
|
|
1596
|
+
(`fal.bytedance-seedream-v5-lite-text-to-image`), Fal Seedream 5.0 Lite Edit
|
|
1597
|
+
(`fal.bytedance-seedream-v5-lite-edit`), Fal Seedream 4.5 Create
|
|
1598
|
+
(`fal.bytedance-seedream-v4-5-text-to-image`), Fal Seedream 4.5 Edit
|
|
1599
|
+
(`fal.bytedance-seedream-v4-5-edit`), Fal Nano Banana Pro Create
|
|
1600
|
+
(`fal.nano-banana-pro`), Fal Nano Banana Pro Edit
|
|
1601
|
+
(`fal.nano-banana-pro-edit`), GPT Image 1.5 Create
|
|
1602
|
+
(`openai.gpt-image-1.5`), GPT Image 1.5 Edit
|
|
1603
|
+
(`openai.gpt-image-1.5-edit`), and GPT Image 2 Edit
|
|
1604
|
+
(`openai.gpt-image-2-edit`) when their provider credentials are configured.
|
|
1605
|
+
Fal Gemini 3 Pro Image Preview create/edit has known per-image pricing: 1K/2K
|
|
1606
|
+
requests quote `$0.15` provider cost and 4K quotes the doubled provider tier.
|
|
1607
|
+
Fal Nano Banana Pro create/edit uses the same `$0.15` standard and doubled 4K
|
|
1608
|
+
provider tier. Fal FLUX Pro 1.1 Ultra Create quotes `$0.06` provider cost per
|
|
1609
|
+
image. Fal FLUX Pro Kontext Edit quotes `$0.04` provider cost per image, and
|
|
1610
|
+
Fal FLUX Pro Kontext Max Edit quotes `$0.08` provider cost per image. Fal
|
|
1611
|
+
Seedream 4.5 create/edit quotes `$0.04` provider cost per image.
|
|
1612
|
+
Fal Seedream 5.0 Lite create/edit quotes `$0.035` provider cost per image. Fal
|
|
1613
|
+
Z-Image Turbo create/edit quotes `$0.005/MP` when `image_size` is explicit or
|
|
1614
|
+
derived from aspect ratio; edit `auto` remains unknown-cost. GPT Image 1.5
|
|
1615
|
+
create quotes output-token estimates for concrete quality/size requests using
|
|
1616
|
+
OpenAI's fixed-size token table; GPT Image 1.5 edit remains preflight
|
|
1617
|
+
unknown-cost because edit input image/text tokens are provider-metered, then
|
|
1618
|
+
records usage-priced provider cost when OpenAI returns token usage. GPT Image 2
|
|
1619
|
+
create quotes output-token estimates for concrete quality/size requests. GPT
|
|
1620
|
+
Image 2 edit remains preflight unknown-cost because edit input image/text tokens
|
|
1621
|
+
are provider-metered, then records usage-priced provider cost when OpenAI
|
|
1622
|
+
returns token usage. Other edit paths without machine-readable pricing require
|
|
1623
|
+
`--accept-unknown-cost` until a stable price source is captured. Responses
|
|
1624
|
+
include a new generated asset URL, job id, safety state, quota consumption, and
|
|
1625
|
+
input asset metadata where
|
|
1626
|
+
applicable. Responses do not include raw prompts, source bytes, base64
|
|
1627
|
+
payloads, local paths, full external URLs, bucket names, or object keys.
|
|
1628
|
+
When `quota.top_up.available` is true, `next_actions.self_fund.quote_command`
|
|
1629
|
+
is a copy-runnable top-up quote command. `next_actions.self_fund.recommended`
|
|
1630
|
+
and the mirrored top-up `urgency`, `urgency_score`, and `urgency_reasons` say
|
|
1631
|
+
whether the agent should act now. The handoff exposes `first_safe_command`,
|
|
1632
|
+
`first_safe_command_effect`, `inspect_methods_command`, and
|
|
1633
|
+
`inspect_packs_command` for no-spend payment rail inspection before quote/buy.
|
|
1634
|
+
The quote command omits `--idempotency-key` so the public CLI generates and
|
|
1635
|
+
returns one for retry safety before the agent follows the quote response into
|
|
1636
|
+
`credits buy` and `credits status`.
|
|
1637
|
+
|
|
1638
|
+
Provider/model names in this paragraph are preview provenance, not the primary
|
|
1639
|
+
public UX. The public selection surface should be Luxin capabilities and
|
|
1640
|
+
model-parameter schemas; provider/model details belong in explicit
|
|
1641
|
+
provenance/debug output.
|
|
1642
|
+
|
|
1643
|
+
Edit accepts the same retry-safe `--idempotency-key` as create. A retry that
|
|
1644
|
+
reuses the same key does not create a second credit reservation, so a transient
|
|
1645
|
+
`502`/`PROVIDER_FAILURE` after a reservation cannot double-charge; a retryable
|
|
1646
|
+
edit error returns an `error.recovery.idempotency_key` and an
|
|
1647
|
+
`error.recovery.suggested_command` that re-runs the same edit with that key.
|
|
1648
|
+
Live non-dry-run edit emits the same stderr `in_flight` diagnostic and local
|
|
1649
|
+
doctor-visible recovery breadcrumb as create.
|
|
1650
|
+
|
|
1651
|
+
### `luxin assets show`
|
|
1652
|
+
|
|
1653
|
+
Inspects an Luxin-owned asset URL or hosted asset id.
|
|
1654
|
+
|
|
1655
|
+
```bash
|
|
1656
|
+
luxin assets show \
|
|
1657
|
+
https://media.image-skill.com/a/image_abc123.png \
|
|
1658
|
+
--json
|
|
1659
|
+
```
|
|
1660
|
+
|
|
1661
|
+
For asset-id lookup, use hosted auth:
|
|
1662
|
+
|
|
1663
|
+
```bash
|
|
1664
|
+
luxin assets show image_... --json
|
|
1665
|
+
```
|
|
1666
|
+
|
|
1667
|
+
Minimum success data:
|
|
1668
|
+
|
|
1669
|
+
```json
|
|
1670
|
+
{
|
|
1671
|
+
"request": {
|
|
1672
|
+
"reference": "image_...",
|
|
1673
|
+
"reference_type": "asset_id"
|
|
1674
|
+
},
|
|
1675
|
+
"asset": {
|
|
1676
|
+
"asset_id": "image_...",
|
|
1677
|
+
"job_id": "job_...",
|
|
1678
|
+
"url": "https://media.image-skill.com/a/image_abc123.png",
|
|
1679
|
+
"mime_type": "image/png",
|
|
1680
|
+
"content_length": 12345,
|
|
1681
|
+
"width": 1024,
|
|
1682
|
+
"height": 1024,
|
|
1683
|
+
"source": "hosted_metadata"
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
```
|
|
1687
|
+
|
|
1688
|
+
External URLs are rejected. Older assets created before hosted asset metadata
|
|
1689
|
+
was recorded may still be inspectable by Luxin-owned URL.
|
|
1690
|
+
|
|
1691
|
+
For hosted generated assets, when quota exposes an available top-up path,
|
|
1692
|
+
`data.next_actions.self_fund` mirrors the top-up recommendation, urgency, and
|
|
1693
|
+
no-spend payment rail inspection handoff used by create/edit, jobs, and
|
|
1694
|
+
activity responses. On successful create/edit, when that self-fund action is
|
|
1695
|
+
recommended and copy-runnable, `data.self_fund_next_command` aliases
|
|
1696
|
+
`data.next_actions.self_fund.quote_command`; its effect object proves the quote
|
|
1697
|
+
does not buy, settle a wallet transfer, debit credits, call a provider, create a
|
|
1698
|
+
hosted job, or write media.
|
|
1699
|
+
|
|
1700
|
+
### `luxin assets get`
|
|
1701
|
+
|
|
1702
|
+
Downloads an Luxin-owned asset URL or hosted asset id to a local file.
|
|
1703
|
+
|
|
1704
|
+
```bash
|
|
1705
|
+
luxin assets get \
|
|
1706
|
+
https://media.image-skill.com/a/image_abc123.png \
|
|
1707
|
+
--output ./result.png \
|
|
1708
|
+
--json
|
|
1709
|
+
```
|
|
1710
|
+
|
|
1711
|
+
The command refuses to overwrite existing files unless `--overwrite` is
|
|
1712
|
+
explicit. It verifies byte length when the asset server provides a
|
|
1713
|
+
`content-length` header. For hosted asset-id downloads, `assets get` preserves
|
|
1714
|
+
`data.next_actions.self_fund` from the asset metadata response after a
|
|
1715
|
+
successful download.
|
|
1716
|
+
|
|
1717
|
+
### `luxin jobs show`
|
|
1718
|
+
|
|
1719
|
+
Inspects a hosted Luxin job visible to the authenticated agent.
|
|
1720
|
+
|
|
1721
|
+
```bash
|
|
1722
|
+
luxin jobs show job_... --json
|
|
1723
|
+
```
|
|
1724
|
+
|
|
1725
|
+
Output includes public job status, trace id, timestamps, capability id, cost
|
|
1726
|
+
summary, safety status, and Luxin-owned asset metadata. For fresh-agent
|
|
1727
|
+
parsing, `status`, `state`, `assets`, and `cost` are mirrored at top level and
|
|
1728
|
+
match `job.status`, `job.assets`, and `job.cost`. Provider/model provenance is
|
|
1729
|
+
available only through explicit provenance/debug affordances for authorized
|
|
1730
|
+
actors. Default output does not include raw prompts, generated bytes, provider
|
|
1731
|
+
credentials, DB/storage keys, bucket names, or local paths.
|
|
1732
|
+
|
|
1733
|
+
Minimum success data:
|
|
1734
|
+
|
|
1735
|
+
```json
|
|
1736
|
+
{
|
|
1737
|
+
"request": {
|
|
1738
|
+
"job_id": "job_..."
|
|
1739
|
+
},
|
|
1740
|
+
"status": "completed",
|
|
1741
|
+
"state": "completed",
|
|
1742
|
+
"assets": [],
|
|
1743
|
+
"cost": {
|
|
1744
|
+
"estimated_usd": 0.05,
|
|
1745
|
+
"provider_reported_usd_ticks": null
|
|
1746
|
+
},
|
|
1747
|
+
"job": {
|
|
1748
|
+
"job_id": "job_...",
|
|
1749
|
+
"status": "completed",
|
|
1750
|
+
"assets": [],
|
|
1751
|
+
"cost": {
|
|
1752
|
+
"estimated_usd": 0.05,
|
|
1753
|
+
"provider_reported_usd_ticks": null
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
```
|
|
1758
|
+
|
|
1759
|
+
### `luxin jobs wait`
|
|
1760
|
+
|
|
1761
|
+
Waits for a hosted Luxin job to reach a terminal status.
|
|
1762
|
+
|
|
1763
|
+
```bash
|
|
1764
|
+
luxin jobs wait job_... --timeout-ms 30000 --poll-interval-ms 1000 --json
|
|
1765
|
+
```
|
|
1766
|
+
|
|
1767
|
+
Completed jobs return immediately. Non-terminal jobs poll until completion,
|
|
1768
|
+
failure, cancellation, or deterministic timeout. Terminal success uses the same
|
|
1769
|
+
top-level `status`, `state`, `assets`, and `cost` mirrors as `jobs show`, with
|
|
1770
|
+
`request.timeout_ms` and `request.poll_interval_ms` added for provenance.
|
|
1771
|
+
|
|
1772
|
+
### `luxin activity list`
|
|
1773
|
+
|
|
1774
|
+
Lists recent hosted activity ledger events visible to the authenticated agent.
|
|
1775
|
+
|
|
1776
|
+
```bash
|
|
1777
|
+
luxin activity list --limit 20 --json
|
|
1778
|
+
luxin activity list --subject job_... --json
|
|
1779
|
+
```
|
|
1780
|
+
|
|
1781
|
+
Activity is the ledger, not the work queue. Use it to find recent event IDs,
|
|
1782
|
+
related job IDs, asset IDs, usage IDs, feedback IDs, trace IDs, status changes,
|
|
1783
|
+
and product-memory writes. Use `jobs show` or `jobs wait` when you need
|
|
1784
|
+
operational recovery, polling, retry judgment, or final job assets.
|
|
1785
|
+
|
|
1786
|
+
When the ledger proves generated work and current quota exposes an available
|
|
1787
|
+
top-up path, `data.next_actions.self_fund` mirrors the same recommendation,
|
|
1788
|
+
urgency, and no-spend payment-method inspection handoff returned by successful
|
|
1789
|
+
create/edit and `jobs show`.
|
|
1790
|
+
|
|
1791
|
+
Minimum success data:
|
|
1792
|
+
|
|
1793
|
+
```json
|
|
1794
|
+
{
|
|
1795
|
+
"events": [
|
|
1796
|
+
{
|
|
1797
|
+
"event_id": "evt_...",
|
|
1798
|
+
"type": "job.completed",
|
|
1799
|
+
"occurred_at": "2026-05-05T19:00:23.000Z",
|
|
1800
|
+
"summary": "Create job completed",
|
|
1801
|
+
"operation": "create",
|
|
1802
|
+
"subject": {
|
|
1803
|
+
"type": "job",
|
|
1804
|
+
"id": "job_..."
|
|
1805
|
+
},
|
|
1806
|
+
"links": {
|
|
1807
|
+
"job_id": "job_...",
|
|
1808
|
+
"asset_ids": ["image_..."],
|
|
1809
|
+
"feedback_id": null,
|
|
1810
|
+
"usage_event_id": "usage_..."
|
|
1811
|
+
},
|
|
1812
|
+
"status": "completed",
|
|
1813
|
+
"cost": {
|
|
1814
|
+
"estimated_usd": 0.025
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
],
|
|
1818
|
+
"source": "hosted_activity_ledger"
|
|
1819
|
+
}
|
|
1820
|
+
```
|
|
1821
|
+
|
|
1822
|
+
The ledger hides provider and storage implementation details by default. It is
|
|
1823
|
+
safe to cite `evt_...`, `job_...`, `image_...`, `usage_...`, `feedback_id`,
|
|
1824
|
+
and `trace_id` values in feedback.
|
|
1825
|
+
|
|
1826
|
+
Hosted API equivalent:
|
|
1827
|
+
|
|
1828
|
+
```bash
|
|
1829
|
+
curl -sS "https://api.luxin.sh/v1/activity?limit=20&subject=job_..." \
|
|
1830
|
+
-H "authorization: Bearer $IMAGE_SKILL_TOKEN"
|
|
1831
|
+
```
|
|
1832
|
+
|
|
1833
|
+
### `luxin activity show`
|
|
1834
|
+
|
|
1835
|
+
Shows one hosted activity event or the latest events related to one subject.
|
|
1836
|
+
|
|
1837
|
+
```bash
|
|
1838
|
+
luxin activity show evt_... --json
|
|
1839
|
+
luxin activity show job_... --json
|
|
1840
|
+
luxin activity show image_... --json
|
|
1841
|
+
luxin activity show sig_... --json
|
|
1842
|
+
```
|
|
1843
|
+
|
|
1844
|
+
`activity show` accepts activity event IDs plus job, asset, usage, feedback, and
|
|
1845
|
+
trace references. When the reference is a subject rather than one exact event,
|
|
1846
|
+
the response includes matching ledger events so an agent can cite the right
|
|
1847
|
+
event without reading telemetry logs. When current quota exposes top-up
|
|
1848
|
+
availability after generated work,
|
|
1849
|
+
`data.next_actions.self_fund.first_safe_command` is the no-spend rail
|
|
1850
|
+
inspection command to run before any quote/buy step.
|
|
1851
|
+
|
|
1852
|
+
Hosted API equivalent:
|
|
1853
|
+
|
|
1854
|
+
```bash
|
|
1855
|
+
curl -sS https://api.luxin.sh/v1/activity/evt_... \
|
|
1856
|
+
-H "authorization: Bearer $IMAGE_SKILL_TOKEN"
|
|
1857
|
+
```
|
|
1858
|
+
|
|
1859
|
+
### Activity Event Registry
|
|
1860
|
+
|
|
1861
|
+
Activity `type` values are stable public contract values. Do not infer new
|
|
1862
|
+
event names from provider responses or telemetry logs; use only the registry
|
|
1863
|
+
below.
|
|
1864
|
+
|
|
1865
|
+
| Event type | Subject | Operation | Emitted when | Stable links |
|
|
1866
|
+
| ------------------------------------------ | ---------- | ----------- | ------------------------------------------------------------------ | ------------------------------------------------------------------ |
|
|
1867
|
+
| `job.completed` | `job` | create/edit | A hosted create or edit job reaches a terminal state. | `job_id`, `asset_ids`, `usage_event_id` |
|
|
1868
|
+
| `job.planned` | `job` | create/edit | An authenticated hosted dry-run stores a recoverable plan receipt. | `job_id` |
|
|
1869
|
+
| `asset.created` | `asset` | create/edit | A hosted create or edit produces an output asset. | `job_id`, `asset_ids`, `usage_event_id` |
|
|
1870
|
+
| `asset.uploaded` | `asset` | upload | A public edit workflow uploads or imports input media. | `job_id`, `asset_ids`, `usage_event_id` |
|
|
1871
|
+
| `usage.credit_consumed` | `usage` | usage | A creative operation records a preview-credit entry. | `job_id`, `usage_event_id` |
|
|
1872
|
+
| `feedback.created` | `feedback` | feedback | Hosted agent feedback is accepted into product memory. | `feedback_id` |
|
|
1873
|
+
| `feedback.github_queue.processed` | `feedback` | feedback | Feedback is processed by the GitHub implementation queue handoff. | `feedback_id` |
|
|
1874
|
+
| `payment.checkout_session.created` | `payment` | payment | A Stripe Checkout session is created and awaits external action. | `quote_id`, `payment_attempt_id`, `checkout_session_id` |
|
|
1875
|
+
| `credits.payment_backed_granted` | `credit` | credits | Verified payment fulfillment grants paid credits. | `quote_id`, `receipt_id`, `credit_event_id` |
|
|
1876
|
+
| `credits.payment_backed_refunded` | `credit` | credits | A Stripe refund debits payment-backed credits. | `quote_id`, `receipt_id`, `payment_reversal_id`, `credit_event_id` |
|
|
1877
|
+
| `credits.payment_backed_disputed` | `credit` | credits | A Stripe dispute debit applies to payment-backed credits. | `quote_id`, `receipt_id`, `payment_reversal_id`, `credit_event_id` |
|
|
1878
|
+
| `credits.payment_backed_reinstated` | `credit` | credits | Stripe dispute funds were reinstated and recorded. | `quote_id`, `receipt_id`, `payment_reversal_id` |
|
|
1879
|
+
| `credits.payment_backed_reversal_pending` | `credit` | credits | A reversal was recorded but could not be fully applied. | `quote_id`, `receipt_id`, `payment_reversal_id` |
|
|
1880
|
+
| `credits.payment_backed_reversal_rejected` | `credit` | credits | A reversal was rejected because it could not safely reconcile. | `quote_id`, `receipt_id`, `payment_reversal_id` |
|
|
1881
|
+
|
|
1882
|
+
`feedback.github_queue.processed` includes `details.github_queue` with
|
|
1883
|
+
machine-readable lifecycle fields such as `state`, `reason`, `issue_urls`,
|
|
1884
|
+
`issue_numbers`, `mode`, and `github_mutation`. Agents should use it to learn
|
|
1885
|
+
whether submitted feedback was promoted, skipped, deduped, blocked, or already
|
|
1886
|
+
mirrored without reading private repository artifacts.
|
|
1887
|
+
`job.planned` includes `details.plan_receipt` for authenticated hosted
|
|
1888
|
+
dry-runs. It is a recoverable planning receipt, not completed media work:
|
|
1889
|
+
planned outputs do not have durable asset IDs, download URLs, usage debits, or
|
|
1890
|
+
provider execution.
|
|
1891
|
+
|
|
1892
|
+
If a response includes an event type outside this registry, treat it as a
|
|
1893
|
+
contract bug and submit `luxin feedback create --json` with the event ID
|
|
1894
|
+
and trace ID.
|
|
1895
|
+
|
|
1896
|
+
### `luxin feedback create`
|
|
1897
|
+
|
|
1898
|
+
Leaves structured product feedback in hosted Luxin product memory.
|
|
1899
|
+
At minimum, provide `--title` and `--body`; Luxin accepts narrative
|
|
1900
|
+
feedback and adds quality guidance server-side. Use the structured fields below
|
|
1901
|
+
when the agent already knows them.
|
|
1902
|
+
|
|
1903
|
+
```bash
|
|
1904
|
+
luxin feedback create \
|
|
1905
|
+
--type user_feedback \
|
|
1906
|
+
--title "Short concrete title" \
|
|
1907
|
+
--body "What happened, what was expected, and why it matters" \
|
|
1908
|
+
--command "Command or workflow observed" \
|
|
1909
|
+
--expected "Expected result" \
|
|
1910
|
+
--actual "Actual result" \
|
|
1911
|
+
--proof-needed "What would prove this is handled" \
|
|
1912
|
+
--surface cli,docs \
|
|
1913
|
+
--evidence trace:TRACE_ID \
|
|
1914
|
+
--severity medium \
|
|
1915
|
+
--confidence high \
|
|
1916
|
+
--next-state watch \
|
|
1917
|
+
--json
|
|
1918
|
+
```
|
|
1919
|
+
|
|
1920
|
+
Hosted feedback authenticates the same way as other hosted commands: saved
|
|
1921
|
+
public CLI config from default signup, `IMAGE_SKILL_TOKEN`, or
|
|
1922
|
+
`--token-stdin`. If guide/signup already saved config, run `feedback create`
|
|
1923
|
+
normally; no raw token copy step is required. If the runtime uses its own
|
|
1924
|
+
secret store, prefer `IMAGE_SKILL_TOKEN` or `--token-stdin`. Do not paste tokens
|
|
1925
|
+
into feedback title, body, evidence, issues, or logs. Feedback persists through
|
|
1926
|
+
`https://api.luxin.sh/v1/feedback`. The hosted API fails closed if
|
|
1927
|
+
durable hosted feedback storage is unavailable.
|
|
1928
|
+
|
|
1929
|
+
JSON errors may include `error.recovery` with machine-readable fields such as
|
|
1930
|
+
`required_flag`, `suggested_command`, `docs_url`, or `retry_after_seconds`.
|
|
1931
|
+
Agents should prefer those fields over parsing prose error messages. For
|
|
1932
|
+
example, `BUDGET_REQUIRES_CONFIRMATION` returns
|
|
1933
|
+
`required_flag: "--accept-unknown-cost"`.
|
|
1934
|
+
Quota/payment recovery also includes `error.recovery.top_up`: its
|
|
1935
|
+
`quote_command` is copy-runnable and creates an authenticated live-money
|
|
1936
|
+
quote/payment object without paying, settling a wallet transfer, debiting
|
|
1937
|
+
credits, calling a provider, or writing media. Only the later buy/status and
|
|
1938
|
+
wallet/checkout completion steps can spend money.
|
|
1939
|
+
|
|
1940
|
+
`whoami`, `usage quota`, `quota`, `credits quote`, `credits buy`,
|
|
1941
|
+
`credits status`, `create`, `activity list`,
|
|
1942
|
+
`activity show`, and `feedback create` accept `--token-stdin` for stdin-based
|
|
1943
|
+
secret handoff.
|
|
1944
|
+
`credits methods` and `credits packs list` do not require auth.
|
|
1945
|
+
|
|
1946
|
+
Feedback should avoid raw prompts, hosted tokens, provider keys, generated
|
|
1947
|
+
image bytes, source image bytes, and private user data.
|
|
1948
|
+
|
|
1949
|
+
Hosted API equivalent:
|
|
1950
|
+
|
|
1951
|
+
```bash
|
|
1952
|
+
curl -sS https://api.luxin.sh/v1/feedback \
|
|
1953
|
+
-H "authorization: Bearer $IMAGE_SKILL_TOKEN" \
|
|
1954
|
+
-H "content-type: application/json" \
|
|
1955
|
+
-d '{
|
|
1956
|
+
"type": "user_feedback",
|
|
1957
|
+
"title": "Short concrete title",
|
|
1958
|
+
"body": "What happened, what was expected, and why it matters",
|
|
1959
|
+
"command": "Command or workflow observed",
|
|
1960
|
+
"expected": "Expected result",
|
|
1961
|
+
"actual": "Actual result",
|
|
1962
|
+
"proof_needed": "What would prove this is handled",
|
|
1963
|
+
"surface": ["cli", "docs"],
|
|
1964
|
+
"evidence": ["trace:TRACE_ID"],
|
|
1965
|
+
"severity": "medium",
|
|
1966
|
+
"confidence": "high",
|
|
1967
|
+
"next_state": "watch"
|
|
1968
|
+
}'
|
|
1969
|
+
```
|
|
1970
|
+
|
|
1971
|
+
### Planned Resource Commands
|
|
1972
|
+
|
|
1973
|
+
`jobs list`, `assets list`, `assets delete`, and async job cancellation are
|
|
1974
|
+
planned public resource commands. They are not part of the current public
|
|
1975
|
+
allowlist until the hosted service backs them and this contract lists their
|
|
1976
|
+
exact command shapes. `activity list/show` is available now for ledger
|
|
1977
|
+
readback, but it is not a substitute for future job listing, cancellation, or
|
|
1978
|
+
retry controls.
|