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 +249 -1
- package/dist/chunk-UEQCIJ7T.js +922 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1802 -726
- package/dist/openai-sandbox-client.d.ts +85 -0
- package/dist/openai-sandbox-client.js +285 -0
- package/examples/openai-agents-sandbox-local.ts +131 -0
- package/examples/sandbox-api-cli-openai.mjs +450 -0
- package/package.json +25 -3
- package/scripts/openai-sandbox-agent-e2e.ts +219 -0
- package/scripts/sandbox-playground-e2e.mjs +463 -0
- package/skills/xapi/SKILL.md +19 -7
- package/skills/xapi/guides/linkedin.md +55 -0
- package/skills/xapi/guides/provider.md +198 -0
- package/skills/xapi/guides/sandbox.md +520 -0
- package/skills/xapi/guides/serper.md +124 -0
- package/src/client.ts +715 -0
- package/src/config.ts +160 -0
- package/src/openai-sandbox-client.ts +349 -0
- package/src/sandbox-client.ts +309 -0
package/skills/xapi/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: xapi
|
|
3
|
-
description: Access real-time external data via the xapi CLI — Twitter/X
|
|
3
|
+
description: Access real-time external data and managed cloud sandboxes via the xapi CLI — Twitter/X, social platforms, crypto, web/news search, AI generation, SMS verification, and auditable ephemeral compute. Configure the xAPI AI or WebSocket Gateways, or use sandbox run for automatic quote/create/execute/cleanup. Use when the user mentions xapi, external services, or sandbox compute.
|
|
4
4
|
metadata: {"openclaw":{"emoji":"x","requires":{"anyBins":["npx"]},"primaryEnv":"XAPI_KEY"}}
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -62,6 +62,17 @@ xapi offers two types of APIs under a unified interface:
|
|
|
62
62
|
|
|
63
63
|
Both types use the same discovery and call workflow. Use `--source capability` or `--source api` on commands that expose source filtering.
|
|
64
64
|
|
|
65
|
+
## Managed Sandbox Compute
|
|
66
|
+
Read `guides/sandbox.md` before creating a billable instance. For a one-shot
|
|
67
|
+
command, prefer `sandbox run`; it quotes, applies a price ceiling, waits,
|
|
68
|
+
executes, and terminates in `finally`:
|
|
69
|
+
```bash
|
|
70
|
+
npx xapi-to sandbox run --command 'python3 -c "print(6 * 7)"'
|
|
71
|
+
```
|
|
72
|
+
Use granular commands only for multi-step work. Keep the instance ID, terminate
|
|
73
|
+
in cleanup, and verify terminal state/cost afterward. Do not use `--keep` unless
|
|
74
|
+
the user explicitly wants a reusable, continuing-to-bill instance.
|
|
75
|
+
|
|
65
76
|
## Usage Workflow
|
|
66
77
|
|
|
67
78
|
**Critical rule:** Before calling any API, always use `get` to understand the required parameters.
|
|
@@ -362,7 +373,7 @@ npx xapi-to call web.search --input '{"q":"hello world"}'
|
|
|
362
373
|
npx xapi-to call serper.search --input '{"body":{"q":"hello world"}}'
|
|
363
374
|
```
|
|
364
375
|
|
|
365
|
-
|
|
376
|
+
Read `guides/serper.md` before using direct `serper.*` actions; it covers all current v7 actions, mini-batches, Reviews, billing, and the `web.search.*` boundary.
|
|
366
377
|
|
|
367
378
|
## Code Generation (`--code`)
|
|
368
379
|
|
|
@@ -436,10 +447,10 @@ Beyond built-in capabilities, xapi proxies **dozens** of third-party API service
|
|
|
436
447
|
- **Douyin** (`douyin`) — Douyin/TikTok API (videos, users, trending, comments)
|
|
437
448
|
- **Twitter API** (`twitter`) — Alternative Twitter data API
|
|
438
449
|
- **Reddit** (`reddit`) — Reddit API (posts, comments, subreddits, search)
|
|
439
|
-
- **LinkedIn** (`linkedin`) — LinkedIn API (person profiles & career history, company pages, posts & comments, job search)
|
|
450
|
+
- **LinkedIn** (`linkedin`) — LinkedIn API (person profiles & career history, company pages, posts & comments, job search). For career history, see `guides/linkedin.md` first — the profile endpoint silently omits `experience`/`education` for ordinary profiles
|
|
440
451
|
- **Weibo** (`weibo-app`) — Weibo API (user profiles, feeds, search, trending)
|
|
441
452
|
- **5SIM SMS** (`5sim-sms`) — SMS verification (virtual numbers, activation codes)
|
|
442
|
-
- **Serper API** (`serper`) — Google Search
|
|
453
|
+
- **Serper API** (`serper`) — 12 provider-native Google Search actions including web, images, news, maps, places, video, shopping, scholar, patents, autocomplete, Lens, and reviews. Eleven support mini-batch; Reviews does not. Read `guides/serper.md` before calling them
|
|
443
454
|
- **OpenRouter API** (`openrouter`) — Multi-model AI gateway (chat, embeddings, audio transcription/speech, video)
|
|
444
455
|
|
|
445
456
|
The full catalog also spans many other categories — crypto/on-chain data, CEX market data, stocks & macro, social platforms, news, weather, and more. Discover them with `search` / `services`.
|
|
@@ -455,8 +466,6 @@ The full catalog also spans many other categories — crypto/on-chain data, CEX
|
|
|
455
466
|
|
|
456
467
|
The CLI retries idempotent metadata reads and `task poll` for transient timeouts, network failures, `408`, `429`, and `502`–`504`. It does not automatically retry arbitrary `call` actions because the upstream may already have completed a write; confirm the result before manually retrying posts, payments, or other mutations. Ordinary JSON execution has a 60-second request ceiling. HTTP SSE streams and raw downloads instead use a 60-second no-data timeout, reset whenever a chunk arrives; override it with `XAPI_TRANSFER_IDLE_TIMEOUT_MS` when an upstream legitimately pauses longer.
|
|
457
468
|
|
|
458
|
-
## Tips
|
|
459
|
-
|
|
460
469
|
- Use `--page` and `--page-size` for pagination on `list`, `search`, and `services`.
|
|
461
470
|
|
|
462
471
|
## Specialized Guides
|
|
@@ -465,17 +474,20 @@ When the user's task involves these workflows, read the corresponding guide file
|
|
|
465
474
|
|
|
466
475
|
- **`guides/twitter.md`** — Twitter/X (推特): read and paginate tweets/replies/media, download the highest-quality MP4 from a video tweet, advanced search, read long-form X Articles directly from `tweet_detail`, post tweets, reply, quote, like, retweet, OAuth binding
|
|
467
476
|
- **`guides/reddit.md`** — Reddit: user profiles, posts, comments, subreddit feeds, popular/news/games feeds, trending, search
|
|
468
|
-
- **`guides/linkedin.md`** — LinkedIn (领英): person profiles with career history, company pages, posts & comments, job search & job detail — every endpoint but job search is addressed by an ordinary LinkedIn page URL, and post comments need a numeric `urn` alongside `url`
|
|
477
|
+
- **`guides/linkedin.md`** — LinkedIn (领英): person profiles with career history, company pages, posts & comments, job search & job detail — every endpoint but job search is addressed by an ordinary LinkedIn page URL, and post comments need a numeric `urn` alongside `url`. **Read this guide before summarizing anyone's background:** `get__user__profile` returns `experience: null` / `education: null` for ordinary (non-creator) profiles because it reads the logged-out page, and the guide gives the fallback that recovers the real career history
|
|
469
478
|
- **`guides/tiktok.md`** — TikTok: user profiles, videos, comments, search, hashtags, music, live rooms, feed
|
|
470
479
|
- **`guides/douyin.md`** — Douyin (抖音): user profiles, videos, comments, hot search, hashtags, music, video mix/series
|
|
471
480
|
- **`guides/xiaohongshu.md`** — 小红书 (Xiaohongshu): user profiles, notes, comments, search, topics, products, creator inspiration
|
|
472
481
|
- **`guides/weibo.md`** — Weibo (微博): hot search, content search, user profiles, post details, comments, reposts, media
|
|
473
482
|
- **`guides/google_search.md`** — Google Search: web, realtime, news, image, video, scholar, maps, places, shopping
|
|
483
|
+
- **`guides/serper.md`** — direct Serper v7 API: 12 provider-native actions, object-or-array mini-batches, Reviews pagination and batch exception, Lens, dynamic per-credit billing, and the current Webpage service boundary
|
|
474
484
|
- **`guides/crypto.md`** — Crypto (加密货币): on-chain token price/overview/holders/security/OHLCV, wallet analytics, DEX pairs, CEX spot prices by symbol, news — covers contract-address vs symbol addressing and multi-chain
|
|
475
485
|
- **`guides/ai.md`** — AI (人工智能): synchronous or SSE-streamed text, embeddings, asynchronous image/video generation with `task wait`, text-to-speech, and speech-to-text
|
|
476
486
|
- **`guides/ai_gateway.md`** — xAPI AI Gateway: Claude Code and Anthropic/OpenAI SDK setup, model discovery, routing strategies, streaming, fallback, routing/billing headers, direct media endpoints, and known limitations
|
|
477
487
|
- **`guides/ws_gateway.md`** — xAPI WebSocket Gateway: OpenAI Realtime, streaming ASR/TTS, simultaneous interpretation, podcast generation, service/path routing, browser authentication, native binary protocols, limits, billing, close codes, and reconnects
|
|
488
|
+
- **`guides/sandbox.md`** — managed Sandbox compute: AI tool selection, one-shot and multi-step lifecycles, provider pinning, files, Cloudflare Web previews, suspension, GPU jobs, parallel agents, cleanup recovery, audit/history, and billing verification
|
|
478
489
|
- **`guides/sms.md`** — SMS verification: buy virtual phone numbers, receive verification codes, finish/cancel orders (5SIM)
|
|
490
|
+
- **`guides/provider.md`** — Provider management: create/update services, About/changelog, version lifecycle, metrics/events and request receipts, Skill upload/linking, rollback/delete, earnings transfer
|
|
479
491
|
|
|
480
492
|
## Security
|
|
481
493
|
|
|
@@ -8,6 +8,7 @@ Complete guide for LinkedIn operations via xAPI — person profiles with career
|
|
|
8
8
|
|
|
9
9
|
- [Key concept: everything is addressed by URL](#key-concept-everything-is-addressed-by-url)
|
|
10
10
|
- [Person data](#person-data)
|
|
11
|
+
- [When `experience` and `education` come back `null`](#when-experience-and-education-come-back-null)
|
|
11
12
|
- [Company data](#company-data)
|
|
12
13
|
- [Posts and comments](#posts-and-comments)
|
|
13
14
|
- [Jobs](#jobs)
|
|
@@ -56,6 +57,48 @@ One call returns the whole profile — no follow-up requests for individual sect
|
|
|
56
57
|
|
|
57
58
|
There are no separate `get__user__experience` / `educations` / `skills` / `honors` / `publications` endpoints in v2 — that was the older `username` → `urn` two-step API. If you were using those IDs, they now return `Action not found`.
|
|
58
59
|
|
|
60
|
+
### When `experience` and `education` come back `null`
|
|
61
|
+
|
|
62
|
+
`get__user__profile` reads the **logged-out** public page. LinkedIn renders the full career and school sections there only for creator/open profiles; on an ordinary member's page it serves a trimmed topcard. The call still succeeds with `code: 200`, so the failure is silent — you get identity, `current_company`, `educations_details`, `followers`, and `people_also_viewed`, but:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{ "position": null, "experience": null, "education": null, "about": "Don't use LinkedIn that much…" }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`null` here means **not rendered to logged-out visitors**, not "this person has no jobs listed". A truncated `about` ending in `…` is the same signal. Never summarize a person's background from a response in this state, and never report the profile as private or empty — fall back:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx xapi-to call icypeas-email.api_scrape_profile \
|
|
72
|
+
--input '{"method":"GET","params":{"url":"https://www.linkedin.com/in/ricky-wang-74b3a0194/"}}'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
This returns a differently-shaped payload under `data.result`:
|
|
76
|
+
|
|
77
|
+
| Field | Contents |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `worksFor[]` | Current positions — `jobTitle`, `startDate`, `description`, nested `company` (industry, size, website, HQ) |
|
|
80
|
+
| `alumniOf[]` | Past positions — same shape plus `endDate` |
|
|
81
|
+
| `educations[]` | `name`, `degree`, `fieldsOfStudy[]`, `description` |
|
|
82
|
+
| `headline`, `description` | Headline and the full untruncated About text |
|
|
83
|
+
| `firstname`, `lastname`, `address`, `numOfConnections`, `skills[]`, `languages[]` | Identity and profile detail |
|
|
84
|
+
|
|
85
|
+
Check `data.status` before reading `data.result`: `FOUND` means real data, `NOT_FOUND` means `result` is `null` and this source has nothing for that URL either. Two caveats worth carrying into any summary: the snapshot is cached, so `headline` can lag the person's current role, and `startDate`/`endDate` are year-granular (often stamped to January), so treat them as approximate. `jobTitle` also reflects whatever the member typed, which can disagree with a company's own announcement — prefer cross-checking a role against `web.search` before asserting a title.
|
|
86
|
+
|
|
87
|
+
Do not reach for `contactout-api.v1_linkedin_enrich` as a fallback. Without a separate ContactOut contract it returns a fully-populated **sample profile** (`"Example Person"` at `"Legros, Smitham and Kessler"`) with `status_code: 200`, which is easy to mistake for real data, and it is the most expensive LinkedIn-adjacent action in the catalog.
|
|
88
|
+
|
|
89
|
+
### Person profile decision path
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
get__user__profile
|
|
93
|
+
├─ experience[] present → done, use it
|
|
94
|
+
└─ experience/education == null → icypeas-email.api_scrape_profile
|
|
95
|
+
├─ status == FOUND → read worksFor / alumniOf / educations
|
|
96
|
+
└─ status == NOT_FOUND → say the career history is unavailable;
|
|
97
|
+
fall back to web.search for public
|
|
98
|
+
bios, or twitter.user_by_screen_name
|
|
99
|
+
when the person came from an X handle
|
|
100
|
+
```
|
|
101
|
+
|
|
59
102
|
### Get a person's posts
|
|
60
103
|
|
|
61
104
|
```bash
|
|
@@ -144,6 +187,10 @@ This is the most expensive LinkedIn endpoint — search first, then fetch detail
|
|
|
144
187
|
npx xapi-to call linkedin.api_v1_linkedin_web__v2_get__user__profile \
|
|
145
188
|
--input '{"method":"GET","params":{"url":"https://www.linkedin.com/in/williamhgates/"}}'
|
|
146
189
|
|
|
190
|
+
# 1b. Only if experience/education came back null — career history from the fallback
|
|
191
|
+
npx xapi-to call icypeas-email.api_scrape_profile \
|
|
192
|
+
--input '{"method":"GET","params":{"url":"https://www.linkedin.com/in/williamhgates/"}}'
|
|
193
|
+
|
|
147
194
|
# 2. Their posts (take `urn` from each item for step 3)
|
|
148
195
|
npx xapi-to call linkedin.api_v1_linkedin_web__v2_get__user__posts \
|
|
149
196
|
--input '{"method":"GET","params":{"url":"https://www.linkedin.com/in/williamhgates/","page":1}}'
|
|
@@ -186,6 +233,12 @@ npx xapi-to call linkedin.api_v1_linkedin_web__v2_get__company__profile \
|
|
|
186
233
|
| `search__jobs` | Job search | `keywords` | `location`, `page` |
|
|
187
234
|
| `get__job__detail` | Full job posting | `url` | — |
|
|
188
235
|
|
|
236
|
+
One non-`linkedin` action belongs in this workflow:
|
|
237
|
+
|
|
238
|
+
| Action ID | Purpose | Required params | Notes |
|
|
239
|
+
|---|---|---|---|
|
|
240
|
+
| `icypeas-email.api_scrape_profile` | Career history for profiles the logged-out page hides | `url` | Fallback when `get__user__profile` returns `experience: null`. Check `data.status == "FOUND"`. |
|
|
241
|
+
|
|
189
242
|
Detail-style endpoints (`get__*__profile`, `get__post__detail`) are the cheapest; list-style endpoints (posts, comments, job search) cost more per call, and `get__job__detail` is the most expensive. Run `npx xapi-to get <action-id>` for the current `meta.pricing` rather than assuming these ratios hold.
|
|
190
243
|
|
|
191
244
|
## Error Handling
|
|
@@ -195,4 +248,6 @@ Detail-style endpoints (`get__*__profile`, `get__post__detail`) are the cheapest
|
|
|
195
248
|
- **`must have required property 'urn'`** — `get__post__comments` needs the numeric `urn` alongside `url`. See [Get comments on a post](#get-comments-on-a-post).
|
|
196
249
|
- **`must match pattern "^[0-9]+$"` on `/params/urn`** — you passed the prefixed `urn:li:activity:<id>` form. Send the digits only.
|
|
197
250
|
- **`API Token lacks required permissions`** (upstream `403`) — the account's upstream provider token has no LinkedIn scope. This is an account entitlement, not a parameter problem; enable it in the provider dashboard.
|
|
251
|
+
- **`experience: null` / `education: null` / `about` ending in `…` on `get__user__profile`** — not an error and not a private profile: the logged-out page LinkedIn serves for ordinary members omits those sections. Fall back to `icypeas-email.api_scrape_profile`. See [When `experience` and `education` come back `null`](#when-experience-and-education-come-back-null).
|
|
252
|
+
- **A ContactOut response naming `Example Person` at `Legros, Smitham and Kessler`** — `contactout-api.*` returned its sample payload because the account has no ContactOut entitlement. It carries `status_code: 200` and a `message` pointing at a sales call. Discard it; never summarize from it.
|
|
198
253
|
- **Empty `data[]` on a valid URL** — either the page is private/deleted, or you paginated past the end. LinkedIn also rate-limits aggressively; retry with backoff rather than in a tight loop.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Provider service management
|
|
2
|
+
|
|
3
|
+
Read this guide for provider-side service authoring and operations. These
|
|
4
|
+
commands use `XAPI-KEY` directly and never exchange it for a broad JWT session.
|
|
5
|
+
The key must belong to the service owner and carry the scope named by the
|
|
6
|
+
operation.
|
|
7
|
+
|
|
8
|
+
## Inspect capabilities and scopes
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx xapi-to provider --help
|
|
12
|
+
npx xapi-to skill --help
|
|
13
|
+
npx xapi-to skill spec
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Use narrowly scoped keys. Common scopes are:
|
|
17
|
+
|
|
18
|
+
- `service:create`, `service:read`, `service:update`
|
|
19
|
+
- `version:create`, `service:publish`, `service:rollback`
|
|
20
|
+
- `observability:read`
|
|
21
|
+
- `skill:read`, `skill:submit`
|
|
22
|
+
- `earnings:read`; `earnings:transfer` only when reinvestment is intended
|
|
23
|
+
- `service:delete` only for deliberate removal workflows
|
|
24
|
+
|
|
25
|
+
Scope permission and ownership are independent. A key with a scope still cannot
|
|
26
|
+
manage another provider's service or Skill.
|
|
27
|
+
|
|
28
|
+
## Create and describe a service
|
|
29
|
+
|
|
30
|
+
Create uses the backend service DTO as JSON so credentials and endpoint
|
|
31
|
+
contracts do not have to appear in shell history:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx xapi-to provider create --file ./service.json
|
|
35
|
+
npx xapi-to provider list
|
|
36
|
+
npx xapi-to provider get <service-id>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Keep the three service content layers distinct:
|
|
40
|
+
|
|
41
|
+
- `description` is the short marketplace-card summary.
|
|
42
|
+
- `aboutMarkdown` is the long About tab.
|
|
43
|
+
- `website` is a public HTTP(S) link.
|
|
44
|
+
|
|
45
|
+
Prefer files for long text:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx xapi-to provider update <service-id> \
|
|
49
|
+
--description "Short marketplace summary" \
|
|
50
|
+
--about-file ./ABOUT.md \
|
|
51
|
+
--website https://example.com
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Use `--clear-about` or `--clear-website` to clear a value. Provider metadata
|
|
55
|
+
updates cannot modify the version contract or upstream credentials; use the
|
|
56
|
+
version command for those fields.
|
|
57
|
+
|
|
58
|
+
## Edit and publish a revision
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Inspect current majors and revisions
|
|
62
|
+
npx xapi-to provider versions <service-id>
|
|
63
|
+
|
|
64
|
+
# Either create a new major or pull a working revision from an existing major
|
|
65
|
+
npx xapi-to provider major create <service-id>
|
|
66
|
+
npx xapi-to provider revision start <service-id> <major>
|
|
67
|
+
|
|
68
|
+
# Merge a partial version-contract update; add --replace for full replacement
|
|
69
|
+
npx xapi-to provider version update \
|
|
70
|
+
<service-id> <version-id> --file ./contract.json
|
|
71
|
+
|
|
72
|
+
# Inspect before publishing
|
|
73
|
+
npx xapi-to provider diff <service-id> <major>
|
|
74
|
+
|
|
75
|
+
# Submit through the normal review gate with public release notes
|
|
76
|
+
npx xapi-to provider publish \
|
|
77
|
+
<service-id> <revision-id> --changelog-file ./CHANGELOG.md
|
|
78
|
+
|
|
79
|
+
# Inspect the review result
|
|
80
|
+
npx xapi-to provider review <service-id> <revision-id>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The changelog is provider-authored, public release information associated with
|
|
84
|
+
that revision. It is not a system deployment log. Build, review, and runtime
|
|
85
|
+
events are generated by the platform and should only be read, never uploaded as
|
|
86
|
+
if they were evidence.
|
|
87
|
+
|
|
88
|
+
`publish` can change live service behavior after review. The CLI does not
|
|
89
|
+
automatically retry this write after an ambiguous transport failure. Read the
|
|
90
|
+
version overview and review state before deciding whether to submit again.
|
|
91
|
+
|
|
92
|
+
## Create, upload, and link the usage Skill
|
|
93
|
+
|
|
94
|
+
Generate a service-specific starting point from the currently serving endpoints:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx xapi-to provider skill scaffold \
|
|
98
|
+
<service-id> --output ./my-service/SKILL.md
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The scaffold command refuses to overwrite an existing file unless `--force` is
|
|
102
|
+
explicitly supplied. Complete the instructions and metadata, then submit either
|
|
103
|
+
a local directory or a public GitHub tree:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npx xapi-to skill submit --dir ./my-service
|
|
107
|
+
|
|
108
|
+
npx xapi-to skill submit \
|
|
109
|
+
--github https://github.com/org/repo/tree/main/skills/my-service \
|
|
110
|
+
--version 1.0.0
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Local submission skips symlinks, `.git`, and `node_modules`; requires a root
|
|
114
|
+
`SKILL.md`; permits at most 100 files; limits each file to 512 KiB and the encoded
|
|
115
|
+
package to 2 MiB. The server still performs manifest validation and secret
|
|
116
|
+
scanning. A successful upload creates or updates the owned Skill version and
|
|
117
|
+
submits it for review; it is not immediately public.
|
|
118
|
+
|
|
119
|
+
Use the returned submission ID:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx xapi-to skill status <submission-id>
|
|
123
|
+
npx xapi-to skill wait <submission-id> --timeout 10m
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
After the Skill is published, bind it as the service's primary tutorial and
|
|
127
|
+
record the serving-contract fingerprint:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npx xapi-to provider skill link <service-id> <skill-id>
|
|
131
|
+
npx xapi-to provider skill fingerprint \
|
|
132
|
+
<service-id> --skill-version-id <skill-version-id>
|
|
133
|
+
npx xapi-to provider skill context <service-id>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Only a Skill owned by the same provider can be linked, and one Skill can be the
|
|
137
|
+
primary Skill of only one service. The backend permits linking a pending Skill,
|
|
138
|
+
but the public marketplace exposes only a published version; wait for publication
|
|
139
|
+
unless intentionally preparing the association early. Use `provider skill unlink`
|
|
140
|
+
to remove the primary association. The context response reports drift when host,
|
|
141
|
+
major version, or serving endpoints no longer match the stored fingerprint; update
|
|
142
|
+
and resubmit the Skill rather than merely overwriting the fingerprint.
|
|
143
|
+
|
|
144
|
+
## Observe and recover
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npx xapi-to provider metrics --days 30
|
|
148
|
+
npx xapi-to provider metrics <service-id> --days 7
|
|
149
|
+
npx xapi-to provider events --limit 50
|
|
150
|
+
npx xapi-to provider events --after '<opaque-next-cursor>' --limit 50
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Pass event cursors back unchanged. Metrics and events are owner-scoped; usage
|
|
154
|
+
events are also restricted to the current key where applicable.
|
|
155
|
+
|
|
156
|
+
Verify the finalized cost of a canary or provider call with its receipt ID. Use
|
|
157
|
+
the `X-XAPI-Request-Id` response header or the final `xapi.usage` SSE event, and
|
|
158
|
+
wait when asynchronous billing has not finalized yet:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npx xapi-to usage <request-id>
|
|
162
|
+
npx xapi-to usage wait <request-id> --timeout 1m
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Receipt reads are idempotent. The wait command applies one total deadline,
|
|
166
|
+
retries not-found and transient transport failures within that deadline, and
|
|
167
|
+
fails immediately for permanent authorization or validation errors.
|
|
168
|
+
|
|
169
|
+
Rollback and default-major changes affect live routing:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npx xapi-to provider rollback \
|
|
173
|
+
<service-id> <major> --revision <published-revision-id> \
|
|
174
|
+
--reason "Restore the last known-good contract"
|
|
175
|
+
npx xapi-to provider default-major <service-id> <major>
|
|
176
|
+
npx xapi-to provider deprecate <service-id> <major>
|
|
177
|
+
npx xapi-to provider restore <service-id> <major>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Inspect the target revision before rollback. Do not automatically retry an
|
|
181
|
+
ambiguous rollback response. Deletion requires both `service:delete` and an
|
|
182
|
+
explicit service name or ID confirmation:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
npx xapi-to provider delete <service-id> --confirm <service-name-or-id>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Earnings reinvestment
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
npx xapi-to earnings
|
|
192
|
+
npx xapi-to earnings list --status SETTLED
|
|
193
|
+
npx xapi-to earnings transfer 1 --idempotency-key <stable-operation-key>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Transfer is one-way: it converts settled provider earnings into spendable xAPI
|
|
197
|
+
balance. Confirm the amount and available settled balance first. A transfer may
|
|
198
|
+
be retried only with the same idempotency key and the same amount.
|