xapi-to 0.1.19 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,6 +17,19 @@ cd xapi-cli && bun install
17
17
 
18
18
  The published CLI runs on Node.js 18+. Bun is only required for local source development and tests.
19
19
 
20
+ ## Teach Your Agent the xAPI Skill
21
+
22
+ Paste into Cursor, Claude Code, or any agent that supports skills:
23
+
24
+ ```bash
25
+ npx skills add xapi-labs/xapi-cli
26
+ ```
27
+
28
+ This installs the bundled [`xapi` skill](skills/xapi), which teaches the agent
29
+ how to call social, search, crypto, and AI data through this CLI. Then just ask
30
+ — "what's the price of BTC" — and it takes it from there. Set up a key first;
31
+ see [Quick Start](#quick-start).
32
+
20
33
  ## Quick Start
21
34
 
22
35
  ```bash
@@ -73,9 +86,15 @@ xapi-to services --category Social --page-size 10 # filter and paginate
73
86
  xapi-to get twitter.tweet_detail # get action schema
74
87
  xapi-to get-batch twitter.tweet_detail crypto.token.price # get several schemas
75
88
  xapi-to call twitter.tweet_detail --input '{"tweet_id":"1234567890"}' # execute
89
+ xapi-to call serper.search --input '{"body":[{"q":"OpenAI"},{"q":"Cloudflare"}]}' # Serper mini-batch
76
90
  xapi-to call ai.text.chat.fast --input '{"messages":[{"role":"user","content":"Hi"}]}' --stream
77
91
  ```
78
92
 
93
+ Direct `serper.*` actions use a nested `body`. Eleven current v7 actions accept
94
+ one request object or a mini-batch array; `serper.reviews` accepts only one
95
+ object. See the bundled [Serper guide](skills/xapi/guides/serper.md) for the
96
+ Action list, examples, and dynamic per-credit billing.
97
+
79
98
  Search uses `--sort default|relevance|price`. `default` is the recommended
80
99
  order: it considers keyword coverage and match quality first, then favors
81
100
  stable built-in capabilities when matches are otherwise comparable.
@@ -102,6 +121,191 @@ xapi-to task wait 550e8400-e29b-41d4-a716-446655440000 # wait un
102
121
  xapi-to task wait 550e8400-e29b-41d4-a716-446655440000 --interval 1s --timeout 10m
103
122
  ```
104
123
 
124
+ ### Sandbox Commands
125
+
126
+ Sandbox commands provide an AI-friendly cloud computer lifecycle. The fastest
127
+ safe path is `sandbox run`: it quotes by capabilities, applies a default
128
+ `$0.20/hour` ceiling, creates an instance, waits for `RUNNING`, executes the
129
+ command, and terminates in `finally` even when execution fails.
130
+
131
+ ```bash
132
+ # One-shot execution with automatic cleanup
133
+ xapi-to sandbox run --command 'python3 -c "print(6 * 7)"'
134
+
135
+ # Arguments after a bare -- are joined as the remote command
136
+ xapi-to sandbox run -- node --version
137
+
138
+ # Pin a provider and request specific capabilities/resources
139
+ xapi-to sandbox run \
140
+ --provider cf-edge \
141
+ --capabilities exec,files,ports \
142
+ --cpu 1 --memory 1 \
143
+ --command 'pwd'
144
+
145
+ # Inspect selection before spending anything
146
+ xapi-to sandbox offerings --format table
147
+ xapi-to sandbox quote --capabilities exec,files --max-hourly-usd 0.10
148
+
149
+ # Every command has focused help
150
+ xapi-to sandbox create --help
151
+ xapi-to sandbox run --help
152
+
153
+ # Fine-grained lifecycle for agents that need several tool calls
154
+ xapi-to sandbox create --capabilities exec,files --wait
155
+ xapi-to sandbox exec <id> --command 'npm test' --timeout 120
156
+ xapi-to sandbox file write <id> task.md --file ./task.md
157
+ xapi-to sandbox file read <id> result.json --output ./result.json
158
+ xapi-to sandbox file list <id> --path . --depth 3
159
+ xapi-to sandbox port <id> 8080
160
+ xapi-to sandbox extension <id> runpod.connection_info --input '{}'
161
+ xapi-to sandbox audit <id> --kind operations
162
+ xapi-to sandbox history --state HISTORY --page-size 20
163
+ xapi-to sandbox suspend <id>
164
+ xapi-to sandbox resume <id>
165
+ xapi-to sandbox terminate <id>
166
+ ```
167
+
168
+ For a long-running Web server, select an Offering that explicitly declares
169
+ `backgroundExec` and `ports`, then use the provider-managed background mode:
170
+
171
+ ```bash
172
+ # Confirm the selected row reports background=yes and ports=yes before creating.
173
+ xapi-to sandbox offerings --provider daytona --format table
174
+
175
+ xapi-to sandbox create \
176
+ --provider daytona \
177
+ --capabilities exec,backgroundExec,ports \
178
+ --wait
179
+
180
+ xapi-to sandbox exec <id> --provider daytona --background --command \
181
+ 'python3 -m http.server 25319 --bind 0.0.0.0'
182
+ xapi-to sandbox port <id> 25319 --provider daytona
183
+ ```
184
+
185
+ Do not substitute `nohup ... &` on providers that do not declare
186
+ `backgroundExec`: some providers reclaim the command session and its child
187
+ processes as soon as the foreground exec response completes. A successful
188
+ background response means the session was accepted; verify the public URL and
189
+ expected marker before reporting success.
190
+
191
+ `--format table` is a compact comparison view; truncated cells end with `…`.
192
+ Use the default JSON output when copying a complete quote ID, instance ID, or
193
+ audit payload. Sandbox subcommands reject unknown flags before making a request.
194
+
195
+ An exact `--offering-id` cannot be combined with `--max-hourly-usd`, because an
196
+ Offering bypasses requirements-based quote selection. Use requirements plus the
197
+ ceiling, or create from a quote whose price was already checked. Successful
198
+ `create` output includes `clientIdempotencyKey`. If `create --wait` fails after
199
+ the instance was accepted, its structured error includes the instance ID,
200
+ observed state, idempotency key, and inspect/terminate recovery commands.
201
+
202
+ Provider pinning uses a provider-specific gateway such as
203
+ `cf-edge.sandbox.xapi.to`; the CLI also resolves the deployed production aliases
204
+ `daytona-sandbox.sandbox.xapi.to` and `e2b-sandbox.sandbox.xapi.to`, while the
205
+ test gateways remain `daytona.sandbox.test.xapi.to` and
206
+ `e2b.sandbox.test.xapi.to`. Omit `--provider` or use `auto` for cross-provider
207
+ selection. `sandbox run --keep` is deliberately explicit because the instance
208
+ continues billing until later termination. Remote non-zero command exit codes
209
+ are returned as the CLI process exit code after cleanup.
210
+
211
+ For the test service, override only the Sandbox host; the CLI still refuses to
212
+ send the key outside `*.xapi.to` or localhost:
213
+
214
+ ```bash
215
+ XAPI_SANDBOX_HOST=sandbox.test.xapi.to \
216
+ xapi-to sandbox run --provider cf-edge --command 'echo test-ok'
217
+ ```
218
+
219
+ The repository includes a real acceptance suite for the original nine Sandbox
220
+ Playground workflows. It exercises catalog/quote, AI coding, CI repair, data analysis,
221
+ parallel agents, GPU connection data, one-shot execution, Cloudflare web
222
+ preview, suspend/resume, audits, billing, history, and a final zero-active-
223
+ instance cleanup gate:
224
+
225
+ ```bash
226
+ # Uses the API key already stored by `xapi-to config set apiKey=-`
227
+ npm run test:sandbox:playground -- --host sandbox.test.xapi.to
228
+
229
+ # Focused retry or lower-cost run
230
+ npm run test:sandbox:playground -- --host sandbox.test.xapi.to --only 8,9
231
+ npm run test:sandbox:playground -- --host sandbox.test.xapi.to --skip-gpu
232
+ ```
233
+
234
+ Each run writes a redacted JSON report under the operating system temporary
235
+ directory. The key is read from normal CLI configuration or environment and is
236
+ never accepted on the command line or written to the report.
237
+
238
+ The tenth Playground scenario uses the official OpenAI Agents SDK
239
+ `SandboxAgent` with DeepSeek through the OpenAI Chat Completions-compatible
240
+ `https://ai.xapi.to/v1` gateway and xAPI Sandbox compute. The reusable adapter
241
+ is exported as `xapi-to/openai-sandbox`; its current verified scope is an empty
242
+ Manifest plus the SDK Shell capability. Run the real SDK agent loop against the
243
+ test service with:
244
+
245
+ ```bash
246
+ XAPI_SANDBOX_KEY='sk-sandbox-test-...' \
247
+ XAPI_AI_KEY='sk-ai-production-...' \
248
+ npm run test:sandbox:openai -- \
249
+ --host sandbox.test.xapi.to \
250
+ --provider daytona \
251
+ --model deepseek-v4-pro
252
+ ```
253
+
254
+ The test keeps credentials separate: `XAPI_AI_KEY` is sent only to
255
+ `ai.xapi.to`, while `XAPI_SANDBOX_KEY` is sent only to the selected Sandbox
256
+ Gateway. A production key with both permissions may be supplied to both
257
+ variables. The test disables OpenAI tracing because an xAPI credential is not
258
+ an OpenAI telemetry credential, and configures `useResponses: false` because
259
+ `ai.xapi.to` currently exposes the Chat Completions protocol.
260
+
261
+ For a shorter, zero-context walkthrough of all three public entry points, run
262
+ the standalone JavaScript demo. It creates its own instances and cleans each
263
+ one up; no quote ID or instance ID needs to be prepared:
264
+
265
+ ```bash
266
+ # Required for the default test host; paste without putting the key on argv.
267
+ read -s XAPI_SANDBOX_KEY && export XAPI_SANDBOX_KEY
268
+
269
+ # Required by the OpenAI/DeepSeek section; this targets production ai.xapi.to.
270
+ read -s XAPI_AI_KEY && export XAPI_AI_KEY
271
+
272
+ # Direct HTTP API + local CLI + OpenAI Agents SDK/DeepSeek
273
+ npm run demo:sandbox
274
+
275
+ # Run only one section
276
+ npm run demo:sandbox -- api
277
+ npm run demo:sandbox -- cli
278
+ npm run demo:sandbox -- openai
279
+
280
+ unset XAPI_SANDBOX_KEY XAPI_AI_KEY
281
+ ```
282
+
283
+ The default test host uses a dedicated Sandbox credential. The OpenAI section
284
+ uses a separate production AI Gateway credential because there is currently no
285
+ test AI Gateway. The report includes credential source names but no credential
286
+ fragments; the CLI child receives only the Sandbox credential. The demo defaults
287
+ to Daytona and `deepseek-v4-pro`. Its final JSON verifies markers,
288
+ `TERMINATED`, successful operations, settled usage and billing,
289
+ service-calculated costs, and a zero-residual gate scoped to instances created
290
+ by that demo (unrelated account instances do not fail it).
291
+
292
+ Before the package version containing `xapi-to/openai-sandbox` is published,
293
+ run the same flow directly from this checkout. The example imports the adapter
294
+ from `src/`, defaults to `sandbox.test.xapi.to`, supports separate Sandbox and
295
+ AI Gateway credentials, and always closes the created session:
296
+
297
+ ```bash
298
+ npm run example:sandbox:openai
299
+
300
+ # Mixed-environment credentials and optional overrides
301
+ XAPI_SANDBOX_KEY='sk-sandbox-test-...' \
302
+ XAPI_AI_KEY='sk-ai-production-...' \
303
+ XAPI_SANDBOX_HOST=sandbox.test.xapi.to \
304
+ XAPI_SANDBOX_PROVIDER=daytona \
305
+ XAPI_MODEL=deepseek-v4-pro \
306
+ npm run example:sandbox:openai
307
+ ```
308
+
105
309
  ### OAuth
106
310
 
107
311
  Bind third-party OAuth accounts (e.g. Twitter) to your API key.
@@ -123,11 +327,52 @@ xapi-to register --referral-code xapito # register with an invit
123
327
  xapi-to register xapito # positional shorthand for --referral-code
124
328
  xapi-to register --force # replace an existing file-based key
125
329
  xapi-to balance # show USD balance
330
+ xapi-to usage <request-id> # finalized cost + balance-after receipt
331
+ xapi-to usage wait <request-id> --timeout 1m # poll until a streaming receipt is finalized
332
+ xapi-to earnings # spendable balance + provider earnings
333
+ xapi-to earnings list --status SETTLED --limit 20 # provider earning records
334
+ xapi-to earnings transfer 1 --idempotency-key reinvest-001 # reinvest settled earnings
126
335
  xapi-to topup # generate payment URL
127
336
  xapi-to topup --method stripe --amount 10 # stripe, $10
128
337
  xapi-to topup --method x402 # x402 (USDC on Base)
129
338
  ```
130
339
 
340
+ `earnings` summary/list require the `earnings:read` scope on the current key;
341
+ `earnings transfer` requires `earnings:transfer`. Transfers are one-way and
342
+ idempotent: reuse a key only when retrying the same amount.
343
+
344
+ ### Provider Management
345
+
346
+ Provider commands use scoped `XAPI-KEY` routes for service and release
347
+ management without a JWT exchange:
348
+
349
+ ```bash
350
+ xapi-to provider list
351
+ xapi-to provider create --file ./service.json
352
+ xapi-to provider update <service-id> --about-file ./ABOUT.md --website https://example.com
353
+ xapi-to provider versions <service-id>
354
+ xapi-to provider revision start <service-id> 1
355
+ xapi-to provider version update <service-id> <version-id> --file ./contract.json
356
+ xapi-to provider diff <service-id> 1
357
+ xapi-to provider publish <service-id> <revision-id> --changelog-file ./CHANGELOG.md
358
+ xapi-to provider metrics <service-id> --days 7
359
+ xapi-to provider events --after '<opaque-next-cursor>'
360
+ ```
361
+
362
+ Service usage tutorials are Skill packages. Scaffold one from the serving
363
+ contract, submit it for review, wait for publication, then link it:
364
+
365
+ ```bash
366
+ xapi-to provider skill scaffold <service-id> --output ./my-skill/SKILL.md
367
+ xapi-to skill submit --dir ./my-skill
368
+ xapi-to skill wait <submission-id> --timeout 10m
369
+ xapi-to provider skill link <service-id> <skill-id>
370
+ xapi-to provider skill fingerprint <service-id> --skill-version-id <version-id>
371
+ ```
372
+
373
+ Run `xapi-to provider --help` and `xapi-to skill --help` for the complete
374
+ lifecycle, rollback, deletion, GitHub import, scope, and safety options.
375
+
131
376
  ### Config
132
377
 
133
378
  ```bash
@@ -181,8 +426,11 @@ xapi-to list --format table # human-readable table
181
426
  |---|---|
182
427
  | `XAPI_KEY` | API key (overrides config file) |
183
428
  | `XAPI_API_KEY` | Compatible API key alias (overrides config file; lower priority than `XAPI_KEY`) |
429
+ | `XAPI_SANDBOX_KEY` | Sandbox-only credential for OpenAI SandboxAgent examples/tests |
430
+ | `XAPI_AI_KEY` | AI Gateway credential for OpenAI-compatible model calls |
184
431
  | `XAPI_ACTION_HOST` | Action service host (default: `action.xapi.to`) |
185
432
  | `XAPI_API_HOST` | Auth/account service host (default: `api.xapi.to`) |
433
+ | `XAPI_SANDBOX_HOST` | Sandbox gateway host (default: `sandbox.xapi.to`) |
186
434
  | `XAPI_OUTPUT` | Default output format (`json`\|`pretty`\|`table`) |
187
435
  | `XAPI_TRANSFER_IDLE_TIMEOUT_MS` | SSE/download idle timeout in milliseconds (default: `60000`) |
188
436
 
@@ -219,7 +467,7 @@ current IDs and schemas.
219
467
 
220
468
  ## Security
221
469
 
222
- - **NEVER send your API key to any domain other than `xapi.to`, `*.xapi.to`, `xapi.xyz`, `*.xapi.xyz`, or explicitly configured localhost/loopback development hosts**
470
+ - General action commands retain compatibility with `xapi.to`, `*.xapi.to`, `xapi.xyz`, `*.xapi.xyz`, and localhost/loopback development hosts. Sandbox commands deliberately apply the stricter `*.xapi.to`/localhost-only policy.
223
471
  - The key is stored at `~/.xapi/config.json`; the CLI enforces owner-only Unix permissions — do not expose this file
224
472
  - `topup` outputs a payment URL containing the API key — do not share publicly
225
473