xapi-to 0.1.18 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 xAPI Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -17,20 +17,38 @@ 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
23
36
  # 1. Register a new account (apiKey saved automatically)
24
37
  xapi-to register
38
+ # Open the returned private bindUrl to upgrade the virtual account through Twitter OAuth
25
39
 
26
40
  # 1b. Or register with an inviter's referral code (please replace xapito to your referral code)
27
41
  xapi-to register --referral-code xapito
28
42
 
29
- # 2. Or set an existing key
30
- xapi-to config set apiKey=sk-xxx
43
+ # 2. Or set an existing key without putting it in shell history
44
+ read -rsp 'xAPI key: ' XAPI_KEY_INPUT
45
+ printf '\n'
46
+ printf '%s\n' "$XAPI_KEY_INPUT" | xapi-to config set apiKey=-
47
+ unset XAPI_KEY_INPUT
31
48
 
32
49
  # 3. Or via env var
33
50
  export XAPI_KEY=sk-xxx
51
+ # XAPI_API_KEY is also accepted; XAPI_KEY has higher precedence
34
52
 
35
53
  # 4. Verify connectivity
36
54
  xapi-to config health
@@ -55,6 +73,9 @@ xapi-to list --service-id <id> # filter by service
55
73
 
56
74
  xapi-to search "twitter" # search by keyword
57
75
  xapi-to search "token price" --source api # search APIs only
76
+ xapi-to search "token price" --sort relevance # strongest text match
77
+ xapi-to search "token price" --sort price # lowest comparable price
78
+ xapi-to search "twitter" --include-all-versions # include active non-default majors
58
79
 
59
80
  xapi-to categories # list all categories
60
81
  xapi-to categories --source capability # categories for capabilities only
@@ -63,9 +84,33 @@ xapi-to services # list all services
63
84
  xapi-to services --category Social --page-size 10 # filter and paginate
64
85
 
65
86
  xapi-to get twitter.tweet_detail # get action schema
87
+ xapi-to get-batch twitter.tweet_detail crypto.token.price # get several schemas
66
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
90
+ xapi-to call ai.text.chat.fast --input '{"messages":[{"role":"user","content":"Hi"}]}' --stream
67
91
  ```
68
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
+
98
+ Search uses `--sort default|relevance|price`. `default` is the recommended
99
+ order: it considers keyword coverage and match quality first, then favors
100
+ stable built-in capabilities when matches are otherwise comparable.
101
+ `relevance` is source-neutral and selects the strongest text match. `price`
102
+ preserves keyword coverage and an exact action ID first, keeps endpoint-local
103
+ matches ahead of service-only matches, then orders comparable fixed per-call
104
+ USD list prices from low to high. Dynamic, per-token, per-resource, and unknown
105
+ prices appear after comparable prices in the same match bucket and are never
106
+ treated as free. All three modes rank the full matching result set before
107
+ applying `--page` and `--page-size`.
108
+
109
+ `--stream` forwards an HTTP Server-Sent Events (SSE) response; it is not a
110
+ WebSocket client. Active SSE and raw downloads may run longer than 60 seconds,
111
+ but abort after 60 seconds without data by default. Set
112
+ `XAPI_TRANSFER_IDLE_TIMEOUT_MS` to change that idle timeout.
113
+
69
114
  ### Async Task Commands
70
115
 
71
116
  Task helpers built on top of the `task.poll` capability.
@@ -76,12 +121,199 @@ xapi-to task wait 550e8400-e29b-41d4-a716-446655440000 # wait un
76
121
  xapi-to task wait 550e8400-e29b-41d4-a716-446655440000 --interval 1s --timeout 10m
77
122
  ```
78
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
+
79
309
  ### OAuth
80
310
 
81
311
  Bind third-party OAuth accounts (e.g. Twitter) to your API key.
82
312
 
83
313
  ```bash
84
314
  xapi-to oauth bind --provider twitter # bind Twitter account
315
+ xapi-to oauth providers # inspect current providers/default scopes
316
+ xapi-to oauth bind --provider twitter --scopes "<scope list>" # optional explicit override
85
317
  xapi-to oauth status # list current bindings
86
318
  xapi-to oauth unbind <binding-id> # remove a binding
87
319
  xapi-to oauth providers # list available providers
@@ -93,6 +325,7 @@ xapi-to oauth providers # list available provide
93
325
  xapi-to register # create account, saves apiKey automatically
94
326
  xapi-to register --referral-code xapito # register with an inviter's referral code (please replace xapito to your referral code)
95
327
  xapi-to register xapito # positional shorthand for --referral-code
328
+ xapi-to register --force # replace an existing file-based key
96
329
  xapi-to balance # show USD balance
97
330
  xapi-to topup # generate payment URL
98
331
  xapi-to topup --method stripe --amount 10 # stripe, $10
@@ -103,10 +336,14 @@ xapi-to topup --method x402 # x402 (USDC on Base)
103
336
 
104
337
  ```bash
105
338
  xapi-to config show # show current config
106
- xapi-to config set apiKey=sk-xxx # save API key
339
+ xapi-to config set apiKey=- # paste key, then press Ctrl-D
107
340
  xapi-to config health # check backend connectivity
108
341
  ```
109
342
 
343
+ `XAPI_KEY` overrides `XAPI_API_KEY`, and both override the config file. The CLI
344
+ warns when a saved key is shadowed. Unset the environment variable before
345
+ `register`, including `register --force`, so the new account key becomes active.
346
+
110
347
  ## Workflow: Always GET before CALL
111
348
 
112
349
  Before calling any action, always read its schema first to understand required parameters:
@@ -133,7 +370,8 @@ xapi-to call openrouter.audio_speech \
133
370
 
134
371
  ## Output Formats
135
372
 
136
- All output is JSON by default designed for agent consumption.
373
+ Normal command output is JSON by default. `call --stream` writes raw HTTP SSE
374
+ frames, while `call --output` writes raw response bytes to the requested file.
137
375
 
138
376
  ```bash
139
377
  xapi-to list --format json # default, machine-readable
@@ -146,40 +384,50 @@ xapi-to list --format table # human-readable table
146
384
  | Variable | Description |
147
385
  |---|---|
148
386
  | `XAPI_KEY` | API key (overrides config file) |
387
+ | `XAPI_API_KEY` | Compatible API key alias (overrides config file; lower priority than `XAPI_KEY`) |
388
+ | `XAPI_SANDBOX_KEY` | Sandbox-only credential for OpenAI SandboxAgent examples/tests |
389
+ | `XAPI_AI_KEY` | AI Gateway credential for OpenAI-compatible model calls |
149
390
  | `XAPI_ACTION_HOST` | Action service host (default: `action.xapi.to`) |
391
+ | `XAPI_API_HOST` | Auth/account service host (default: `api.xapi.to`) |
392
+ | `XAPI_SANDBOX_HOST` | Sandbox gateway host (default: `sandbox.xapi.to`) |
150
393
  | `XAPI_OUTPUT` | Default output format (`json`\|`pretty`\|`table`) |
394
+ | `XAPI_TRANSFER_IDLE_TIMEOUT_MS` | SSE/download idle timeout in milliseconds (default: `60000`) |
151
395
 
152
396
  Config is stored at `~/.xapi/config.json`.
153
397
 
154
- ## Built-in Capabilities
398
+ ## Selected Built-in Capabilities
399
+
400
+ This is a small quick-reference subset, not the complete or permanently fixed
401
+ catalog. Use `xapi-to list --source capability`, `search`, and `get` for the
402
+ current IDs and schemas.
155
403
 
156
404
  | ID | Description |
157
405
  |---|---|
158
406
  | `twitter.tweet_detail` | Get tweet details and replies |
159
407
  | `twitter.user_by_screen_name` | Get user profile by username |
160
- | `twitter.user_by_screen_names` | Batch get user profiles by usernames |
161
408
  | `twitter.user_tweets` | Get tweets from a user |
162
409
  | `twitter.user_tweets_and_replies` | Get tweets and replies from a user |
163
410
  | `twitter.user_media` | Get media posts from a user |
164
411
  | `twitter.following` | Get user following list |
165
412
  | `twitter.followers` | Get user followers |
166
413
  | `twitter.retweeters` | Get tweet retweeters |
167
- | `twitter.search_timeline` | Search tweets, users, photos, videos |
414
+ | `twitter.search` | Search tweets |
168
415
  | `ai.text.chat.fast` | Fast AI chat completion |
169
416
  | `ai.text.chat.reasoning` | Advanced reasoning chat |
417
+ | `ai.text.chat.auto` | Model-selected chat with provider fallback |
170
418
  | `ai.text.summarize` | Summarize long text |
171
419
  | `ai.text.rewrite` | Rewrite text with different styles |
172
420
  | `ai.embedding.generate` | Generate vector embeddings |
173
421
  | `web.search` | Web search |
174
422
  | `web.search.realtime` | Realtime web search with time filters |
175
- | `news.search.latest` | Latest news search |
423
+ | `web.search.news` | News search |
176
424
  | `crypto.token.price` | Crypto token price and changes |
177
425
  | `crypto.token.metadata` | Crypto token metadata |
178
426
 
179
427
  ## Security
180
428
 
181
- - **NEVER send your API key to any domain other than `*.xapi.to`**
182
- - The key is stored at `~/.xapi/config.json` — do not expose this file
429
+ - 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.
430
+ - The key is stored at `~/.xapi/config.json`; the CLI enforces owner-only Unix permissions — do not expose this file
183
431
  - `topup` outputs a payment URL containing the API key — do not share publicly
184
432
 
185
433
  ## License