sella-cli 0.6.4 → 0.6.6

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
@@ -1,51 +1,219 @@
1
- # sella-cli
1
+ <p align="center">
2
+ <a href="https://sellag.vercel.app"><img src="https://sellag.vercel.app/sellalogo.png" alt="Sella" width="320" /></a>
3
+ </p>
2
4
 
3
- Terminal onboarding for [Sella](https://sellag.vercel.app) — the marketplace where agents buy datasets,
4
- models, and machine-payable APIs.
5
+ <h1 align="center">sella-cli</h1>
6
+
7
+ <p align="center">
8
+ <b>Your AI agent can buy the data and APIs it needs. On its own, paid per call, in USDC.<br/>
9
+ This CLI connects it in one command.</b>
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/sella-cli"><img src="https://img.shields.io/npm/v/sella-cli?color=E84B2A&label=npm" alt="npm version" /></a>
14
+ <a href="https://www.npmjs.com/package/sella-cli"><img src="https://img.shields.io/npm/dm/sella-cli?color=555" alt="npm downloads" /></a>
15
+ <a href="https://www.npmjs.com/package/sella-cli"><img src="https://img.shields.io/node/v/sella-cli?color=339933&label=node" alt="node version" /></a>
16
+ <a href="https://github.com/010100100100011101010100/ogsella/issues"><img src="https://img.shields.io/npm/l/sella-cli?color=blue" alt="license" /></a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="https://sellag.vercel.app">Website</a> ·
21
+ <a href="https://sella.mintlify.app">Docs</a> ·
22
+ <a href="https://sellag.vercel.app/marketplace">Marketplace</a> ·
23
+ <a href="https://github.com/010100100100011101010100/ogsella/issues">Report a bug</a>
24
+ </p>
25
+
26
+ ---
27
+
28
+ ## Connect your agent in about 30 seconds
5
29
 
6
30
  ```bash
7
31
  npx sella-cli
8
32
  ```
9
33
 
10
- That single command is the whole onboarding: with no stored credentials and a human at the
11
- terminal, the guided wizard starts by itself (`init` is the explicit spelling). It previews the
12
- marketplace, detects your agent clients (Claude Code, Claude Desktop, Cursor, Windsurf, VS Code,
13
- Cline), installs the Sella MCP server into each, pairs the machine (arrow-key choice of setup code
14
- or email + 6-digit code), wires your key into the client configs, and finishes with a live
15
- `doctor` verification. Installed users get the `sella` binary; `npm install` also prints a
16
- one-line pointer after install (silent in CI and non-TTY runs — installs are never interrupted).
34
+ That one command is the whole setup. The wizard:
35
+
36
+ 1. **Detects your agent clients**: Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, Cline.
37
+ 2. **Installs the Sella MCP server** into each one. Writes are idempotent and your other MCP servers are preserved.
38
+ 3. **Pairs the machine**: paste a setup code from the dashboard, or use your email and a 6-digit code.
39
+ 4. **Proves it works** with a live `sella doctor` run at the end.
40
+
41
+ <p align="center">
42
+ <img src="https://sellag.vercel.app/readme/cli-init.svg" alt="npx sella-cli: the wizard detects clients, installs the Sella MCP server, pairs the machine, and verifies with 6/6 checks" width="740" />
43
+ </p>
44
+
45
+ When it finishes, your agent can search a live marketplace and pay for what it finds, per call, in USDC. You set the budget. You can revoke the key anytime.
46
+
47
+ ## Why this exists
48
+
49
+ An agent can only use what a human wired up for it in advance. The moment it needs one more API mid-task, it stops and waits for you. Then you do this, again:
50
+
51
+ <p align="center">
52
+ <img src="https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif" alt="A cat typing frantically on a laptop" width="360" /><br/>
53
+ <sub><i>You, wiring up the seventh API key this month.</i></sub>
54
+ </p>
55
+
56
+ | The traditional way | With Sella |
57
+ |---|---|
58
+ | Find the API. Make an account. Add a card. Copy the key. Paste it into a config. Restart the client. Repeat for every provider. | Your agent searches the marketplace, pays per call in USDC, and keeps working. No account per provider, no key to paste. |
59
+ | Integration time: an evening, per API. | `npx sella-cli`, once. |
60
+ | The agent waits for you. | You set a budget and walk away. |
61
+
62
+ ## Try it free, right now (no account)
63
+
64
+ The sandbox searches the real marketplace. No signup, rate-limited:
65
+
66
+ ```bash
67
+ npx sella-cli sandbox "web search"
68
+ ```
69
+
70
+ <p align="center">
71
+ <img src="https://sellag.vercel.app/readme/cli-sandbox.svg" alt="sella sandbox returns live marketplace results: Exa, Tavily and more, with no account" width="740" />
72
+ </p>
73
+
74
+ What's in there: a catalogue of 1,100+ machine-payable API providers, plus first-party datasets, workflows, and Sella Native products such as Cradle. Free previews let your agent check quality before it pays.
75
+
76
+ ## What you get
77
+
78
+ - **One-command onboarding**, so you never hand-edit an MCP config again.
79
+ - **Pay-per-call in USDC**: fractions of a cent for most calls, multi-chain, with budgets you set and keys you can revoke.
80
+ - **A marketplace built for agents**: every listing is discoverable and payable over MCP + x402, so your agent buys mid-task instead of stalling.
81
+ - **Publishing from a CSV**, so you can sell your own data without opening a browser.
82
+ - **Agent-grade output**: every command supports `--json`, `--yes`, and env vars, with meaningful exit codes. Your CI can run it. Your agent can run it.
17
83
 
18
84
  ## Commands
19
85
 
20
86
  | Command | What it does |
21
87
  |---|---|
22
- | `sella init` | Guided wizard: detect clients install the Sella MCP server pair verify (auto-runs on bare `sella` when unpaired) |
23
- | `sella sandbox <query>` | Try Sella with **no signup** — search the live marketplace (rate-limited) |
24
- | `sella pair` | Pair this machine only (`--setup-code <code>` / `SELLA_SETUP_CODE`, or `--email` + OTP) |
25
- | `sella clients` | List detected clients (`--install` to write configs, `--client a,b` to filter, `--dry-run`) |
26
- | `sella doctor` | Verify the install: endpoint, credentials, auth, wallets, x402 pay-quote each failure names its fix |
27
- | `sella status` | Show your API key + AgentWallet funding/balances, with each chain marked **live** vs **deposit-only** |
28
- | `sella fund` | Per-chain USDC deposit addresses + funding page (QR + fiat on-ramp), labelled live vs deposit-only |
29
- | `sella mcp` | Run as a local **stdio MCP server** that proxies Sella with your stored key for clients that can't use a remote MCP endpoint |
30
- | `sella publish init <file.csv>` | Scaffold `sella-dataset.json` + a structural pre-check of the CSV |
31
- | `sella publish push` | Publish the dataset via the same route the web dashboard uses — a CSV → live listing without a browser |
32
-
33
- `status`/`fund` read the live chain registry (`GET {backend}/api/payments/chains`) to label each
34
- wallet **live · spendable** vs **deposit-only · settle pending**, so the CLI tracks the multi-chain
35
- rollout automatically — no per-chain update needed. If the backend is unreachable they still list
36
- your wallets, just without the label.
37
-
38
- ## Contract (every command)
39
-
40
- - `--json` exactly one JSON document on stdout; errors on stderr; meaningful exit codes.
41
- - `--yes` / env vars for every prompt — agents run this CLI too; nothing may hang on a TTY (the
42
- wizard renders as plain sequential lines off-TTY and never auto-starts in `--yes`/`--json` runs).
43
- - `NO_COLOR` / `--no-color` honored; no spinner-only feedback; color never carries meaning alone.
44
- - Config writes are idempotent, preserve other servers, and leave a one-time `.sella-backup`.
45
- - `SELLA_MCP_URL` overrides the endpoint (self-hosted / staging).
88
+ | `sella init` | The guided wizard: detect clients, install the Sella MCP server, pair, verify. Also runs on a bare `sella` when no credentials exist yet. |
89
+ | `sella sandbox <query>` | Search the live marketplace with no account. Rate-limited. |
90
+ | `sella pair` | Pair this machine only. Use `--setup-code <code>`, the `SELLA_SETUP_CODE` env var, or `--email` plus a 6-digit code. |
91
+ | `sella clients` | List detected agent clients. `--install` writes configs, `--client a,b` filters, `--dry-run` previews. |
92
+ | `sella doctor` | Six live checks, from endpoint reachability to a real x402 pay quote. Every failure names its fix. |
93
+ | `sella status` | Your API key and agent wallet balances, each chain labelled live or deposit-only. |
94
+ | `sella fund` | Per-chain USDC deposit addresses, plus the funding page with QR codes and a fiat on-ramp. |
95
+ | `sella mcp` | Run a local stdio MCP server that proxies Sella with your stored key, for clients that cannot use a remote endpoint. |
96
+ | `sella publish init <file.csv>` | Scaffold `sella-dataset.json` and pre-check the CSV structure. |
97
+ | `sella publish push` | Publish the dataset through the same route the web dashboard uses. |
98
+
99
+ Run `sella --help` for every flag.
100
+
101
+ ## Examples
102
+
103
+ ### Small: search the marketplace (10 seconds, free)
104
+
105
+ ```bash
106
+ npx sella-cli sandbox "flight prices"
107
+ ```
108
+
109
+ Real listings, real prices, no account.
110
+
111
+ ### Medium: connect Claude Code and let the agent do the buying
112
+
113
+ ```bash
114
+ npx sella-cli # detect, install, pair, verify
115
+ ```
116
+
117
+ Then ask your agent:
118
+
119
+ > Search Sella for a web search API and tell me what it costs per call.
120
+
121
+ The agent answers using the Sella MCP tools (`search_datasets`, `list_market_apis`, `try_dataset`, and friends) with the key this CLI stored for it. When you fund the agent wallet, it can buy what it found.
122
+
123
+ ### Real-world: publish a CSV and get paid in USDC
124
+
125
+ ```bash
126
+ sella publish init leads.csv # scaffolds sella-dataset.json + structural pre-check
127
+ # edit title, description, price in sella-dataset.json
128
+ sella publish push # same route the web dashboard uses
129
+ ```
130
+
131
+ Your CSV becomes a listing. Once it clears review it is live for every MCP agent to find, preview, and buy. You are paid per access.
132
+
133
+ ### Ready-made agent tasks
134
+
135
+ The [RFI gallery](https://sellag.vercel.app/rfi) is a list of ready-to-send prompts for your newly connected agent:
136
+
137
+ - [Validate a startup idea for $25](https://sellag.vercel.app/rfi?uc=twenty-five-dollar-study)
138
+ - [Get a daily morning brief](https://sellag.vercel.app/rfi?uc=morning-brief)
139
+ - [Test Sella without spending anything](https://sellag.vercel.app/rfi?uc=zero-dollar-demo)
140
+
141
+ ## Something broke?
142
+
143
+ <p align="center">
144
+ <img src="https://media.giphy.com/media/13HgwGsXF0aiGY/giphy.gif" alt="Moss from The IT Crowd typing calmly while a fire burns beside him" width="360" /><br/>
145
+ <sub><i>Debugging by vibes.</i></sub>
146
+ </p>
147
+
148
+ Don't. Run the doctor:
149
+
150
+ ```bash
151
+ sella doctor
152
+ ```
153
+
154
+ <p align="center">
155
+ <img src="https://sellag.vercel.app/readme/cli-doctor.svg" alt="sella doctor: six checks pass, from MCP endpoint reachability to a live x402 pay quote" width="740" />
156
+ </p>
157
+
158
+ Each failed check prints what happened and the exact fix, in plain language. If it still looks wrong after that, [open an issue](https://github.com/010100100100011101010100/ogsella/issues) and paste the `sella doctor --json` output.
159
+
160
+ ## Built for agents and CI, not just your terminal
161
+
162
+ - `--json` prints exactly one JSON document on stdout. Errors go to stderr. Exit codes mean something.
163
+ - `--yes` and env vars cover every prompt. Nothing hangs waiting for a TTY.
164
+ - `NO_COLOR` and `--no-color` are honored. Color never carries meaning alone.
165
+ - Config writes are idempotent, preserve your other MCP servers, and leave a one-time `.sella-backup`.
166
+ - `SELLA_MCP_URL` points the CLI at staging or a self-hosted Sella.
167
+
168
+ ```bash
169
+ # Headless pairing in CI
170
+ SELLA_SETUP_CODE=SELLA-XXXX-XXXX-XXXX-XXXX npx sella-cli init --yes --json
171
+ ```
46
172
 
47
173
  ## Security
48
174
 
49
- Install links and configs written before pairing carry **no secrets** Sella's bootstrap MCP tools
50
- (`sella_setup_claim`, `sella_auth_*`) are callable without a token, so the agent pairs itself and
51
- stores its own credentials. Never paste API keys into URLs or shell history.
175
+ - Configs written before pairing contain **no secrets**. Sella's bootstrap MCP tools are callable without a token, so the agent pairs itself and stores its own credentials.
176
+ - Your API key lands in the OS keychain, or in a `0600` file with `--no-keychain`.
177
+ - You set the budget. You can revoke a key from the dashboard at any time.
178
+ - Never paste API keys into URLs or shell history.
179
+
180
+ ## Telemetry (opt-in, off by default)
181
+
182
+ The CLI can count which commands run and whether they exit cleanly, so we know what to fix first. Nothing is sent unless you say yes to the one-time question at the end of `sella init`, or you set `SELLA_TELEMETRY=1`.
183
+
184
+ When enabled, each command sends one event: the command name (like `doctor`), the exit code, the CLI version, the OS name (like `darwin`), and a random install id. Never sent: search queries, emails, API keys, wallet addresses, file paths, or anything else you typed. Telemetry is always skipped in `--json`, `--yes`, and CI runs, and the send happens in a detached process, so it never delays a command.
185
+
186
+ Opt out anytime with `SELLA_TELEMETRY=0` or by deleting `~/.sella/telemetry.json`.
187
+
188
+ ## FAQ
189
+
190
+ **Is this crypto hype?**
191
+ No. Payments settle in USDC, a dollar-pegged stablecoin, and most calls cost fractions of a cent. It works with the agent clients you already use.
192
+
193
+ **Do I have to rebuild my stack?**
194
+ No. It is one MCP server entry in a config you already have, and this CLI writes it for you. Try the sandbox before you even sign up.
195
+
196
+ **Is my money safe?**
197
+ You fund a dedicated agent wallet, you set the budget, and you can revoke access anytime. Keys are stored encrypted.
198
+
199
+ **I don't like terminals.**
200
+ Sella has two other ways in: your agent can onboard itself over MCP with your email and a one-time code, or you sign up on the web and paste a setup code to your agent. This CLI is the third path, for people who live in a shell.
201
+
202
+ ## Links
203
+
204
+ | | |
205
+ |---|---|
206
+ | Website | https://sellag.vercel.app |
207
+ | Docs | https://sella.mintlify.app |
208
+ | Marketplace | https://sellag.vercel.app/marketplace |
209
+ | Agent task ideas | https://sellag.vercel.app/rfi |
210
+ | npm | https://www.npmjs.com/package/sella-cli |
211
+ | Issues | https://github.com/010100100100011101010100/ogsella/issues |
212
+
213
+ ## Found a bug?
214
+
215
+ Found a bug? Have an idea? [Mail us](rasesh@buildifi.ai). We read every one.
216
+
217
+ ## License
218
+
219
+ MIT
package/dist/index.js CHANGED
@@ -11,8 +11,9 @@ import { getFundingInfo, annotateFunding } from './fund.js';
11
11
  import { capabilityLabel } from './chains.js';
12
12
  import { defaultIo, Printer } from './output.js';
13
13
  import { Ui } from './ui.js';
14
+ import { recordCliEvent, saveTelemetryDecision, shouldPromptTelemetry } from './telemetry.js';
14
15
  const DEFAULT_MCP_URL = 'https://sellag.vercel.app/api/mcp';
15
- const VERSION = '0.6.4';
16
+ const VERSION = '0.6.6';
16
17
  function parseFlags(argv) {
17
18
  const flags = {
18
19
  json: false, yes: false, noColor: false, dryRun: false, noKeychain: false,
@@ -82,6 +83,11 @@ Environment:
82
83
  SELLA_MCP_URL Override the MCP endpoint (default ${DEFAULT_MCP_URL})
83
84
  SELLA_SETUP_CODE Setup code for headless/CI pairing
84
85
  SELLA_NO_KEYCHAIN Set to 1 to force file storage for the API key
86
+
87
+ Links:
88
+ Website https://sellag.vercel.app
89
+ Docs https://sella.mintlify.app
90
+ Issues https://github.com/010100100100011101010100/ogsella/issues
85
91
  `;
86
92
  function selectClientIds(flags, detected) {
87
93
  if (flags.clients) {
@@ -305,6 +311,16 @@ async function cmdInit(ctx, flags, printer) {
305
311
  { tag: 'free', text: `Test Sella without spending — ${rfi}?uc=zero-dollar-demo`, tone: 'dim' },
306
312
  ]);
307
313
  ui.detail(`Browse all ideas: ${rfi}`);
314
+ // One-time telemetry choice: only a human at a TTY is ever asked, and only once.
315
+ if (!flags.dryRun && shouldPromptTelemetry({ env: ctx.env, ioEnv: ctx.io.env, interactive: ui.interactive })) {
316
+ ui.bar();
317
+ const share = await ui.select('Help improve this CLI with anonymous usage stats?', [
318
+ { value: 'share', label: 'Share stats', hint: 'command name and pass or fail only, never your data or keys' },
319
+ { value: 'off', label: 'Keep it off', hint: 'nothing is sent' },
320
+ ]);
321
+ saveTelemetryDecision(ctx.env, share === 'share');
322
+ ui.detail(share === 'share' ? 'Thanks. Opt out anytime: SELLA_TELEMETRY=0' : 'Nothing will be sent. Opt in later: SELLA_TELEMETRY=1');
323
+ }
308
324
  const took = Math.max(1, Math.round((Date.now() - startedAt) / 1000));
309
325
  ui.outro(flags.dryRun ? 'Dry run complete — nothing was written.' : `Done in ${took}s — your agents can now buy on Sella.`);
310
326
  }
@@ -321,6 +337,9 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
321
337
  const command = flags.positional[0];
322
338
  if (flags.version) {
323
339
  io.stdout(VERSION);
340
+ // TTY-only: scripts capturing `sella --version` must still get a bare semver.
341
+ if (io.isTTY)
342
+ io.stdout('docs: https://sella.mintlify.app · issues: https://github.com/010100100100011101010100/ogsella/issues');
324
343
  return 0;
325
344
  }
326
345
  if (flags.help) {
@@ -548,8 +567,17 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
548
567
  // Bin entry (skipped when imported by tests).
549
568
  const isMain = process.argv[1]?.endsWith('index.js') || process.argv[1]?.endsWith('sella');
550
569
  if (isMain) {
551
- runCli(process.argv.slice(2))
552
- .then((code) => process.exit(code))
570
+ const argv = process.argv.slice(2);
571
+ runCli(argv)
572
+ .then((code) => {
573
+ try {
574
+ recordCliEvent({ argv, exitCode: code, version: VERSION, env: defaultEnv(), ioEnv: process.env });
575
+ }
576
+ catch {
577
+ // Telemetry must never affect the exit path.
578
+ }
579
+ process.exit(code);
580
+ })
553
581
  .catch((err) => {
554
582
  console.error(err instanceof Error ? err.message : String(err));
555
583
  process.exit(1);
@@ -0,0 +1,18 @@
1
+ // Detached one-shot telemetry sender: the CLI spawns this and exits immediately, so a slow or
2
+ // dead network can never delay a command. argv carries no secrets (see telemetry.ts payload).
3
+ const [, , url, body] = process.argv;
4
+ if (url && body) {
5
+ try {
6
+ await fetch(url, {
7
+ method: 'POST',
8
+ headers: { 'content-type': 'application/json' },
9
+ body,
10
+ signal: AbortSignal.timeout(4000),
11
+ });
12
+ }
13
+ catch {
14
+ // Best-effort by contract: there is nobody to report to.
15
+ }
16
+ }
17
+ process.exit(0);
18
+ export {};
@@ -0,0 +1,153 @@
1
+ import { spawn } from 'node:child_process';
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { randomUUID } from 'node:crypto';
6
+ /** Mirrored by CLI_TELEMETRY_COMMANDS in lib/telemetry/cli-event.ts (server side). */
7
+ export const TELEMETRY_COMMANDS = [
8
+ 'none',
9
+ 'init',
10
+ 'pair',
11
+ 'sandbox',
12
+ 'clients',
13
+ 'doctor',
14
+ 'status',
15
+ 'fund',
16
+ 'mcp',
17
+ 'publish',
18
+ 'publish:init',
19
+ 'publish:push',
20
+ 'version',
21
+ 'help',
22
+ 'unknown',
23
+ ];
24
+ const DEFAULT_ORIGIN = 'https://sellag.vercel.app';
25
+ /** Flags whose next token is a value, not a command (mirrors parseFlags in index.ts). */
26
+ const VALUE_FLAGS = new Set(['--client', '--clients', '--setup-code', '--email', '--card']);
27
+ export function telemetryPath(env) {
28
+ return path.join(env.home, '.sella', 'telemetry.json');
29
+ }
30
+ export function loadTelemetryDecision(env) {
31
+ try {
32
+ const raw = JSON.parse(fs.readFileSync(telemetryPath(env), 'utf8'));
33
+ if (typeof raw.enabled !== 'boolean')
34
+ return null;
35
+ return {
36
+ enabled: raw.enabled,
37
+ installId: typeof raw.installId === 'string' && raw.installId ? raw.installId : 'unset',
38
+ decidedAt: typeof raw.decidedAt === 'string' ? raw.decidedAt : '',
39
+ };
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ export function saveTelemetryDecision(env, enabled) {
46
+ const file = telemetryPath(env);
47
+ const existing = loadTelemetryDecision(env);
48
+ const decision = {
49
+ enabled,
50
+ installId: existing?.installId && existing.installId !== 'unset' ? existing.installId : randomUUID(),
51
+ decidedAt: new Date().toISOString(),
52
+ };
53
+ fs.mkdirSync(path.dirname(file), { recursive: true });
54
+ fs.writeFileSync(file, `${JSON.stringify(decision, null, 2)}\n`);
55
+ return { ...decision, path: file };
56
+ }
57
+ /** SELLA_TELEMETRY=1 forces on, =0 forces off, anything else defers to the stored decision. */
58
+ export function telemetryEnvOverride(ioEnv) {
59
+ const v = (ioEnv.SELLA_TELEMETRY || '').trim();
60
+ if (v === '1')
61
+ return true;
62
+ if (v === '0')
63
+ return false;
64
+ return null;
65
+ }
66
+ export function isCiRun(ioEnv) {
67
+ const v = (ioEnv.CI || '').trim().toLowerCase();
68
+ return v !== '' && v !== '0' && v !== 'false';
69
+ }
70
+ /** The single yes/no the sender consults. Defaults to off in every ambiguous case. */
71
+ export function telemetryEnabled(env, ioEnv) {
72
+ if (isCiRun(ioEnv))
73
+ return false;
74
+ const override = telemetryEnvOverride(ioEnv);
75
+ if (override !== null)
76
+ return override;
77
+ return loadTelemetryDecision(env)?.enabled === true;
78
+ }
79
+ /** Ask only when a human is present, nothing decided yet, and no env var already speaks. */
80
+ export function shouldPromptTelemetry(opts) {
81
+ if (!opts.interactive)
82
+ return false;
83
+ if (isCiRun(opts.ioEnv))
84
+ return false;
85
+ if (telemetryEnvOverride(opts.ioEnv) !== null)
86
+ return false;
87
+ return loadTelemetryDecision(opts.env) === null;
88
+ }
89
+ /** Collapse argv onto the fixed command vocabulary; free text can never pass through. */
90
+ export function commandFromArgv(argv) {
91
+ if (argv.includes('--version') || argv.includes('-v'))
92
+ return 'version';
93
+ if (argv.includes('--help') || argv.includes('-h'))
94
+ return 'help';
95
+ const positional = [];
96
+ for (let i = 0; i < argv.length; i += 1) {
97
+ const arg = argv[i];
98
+ if (VALUE_FLAGS.has(arg)) {
99
+ i += 1;
100
+ continue;
101
+ }
102
+ if (arg.startsWith('-'))
103
+ continue;
104
+ positional.push(arg);
105
+ }
106
+ const command = positional[0];
107
+ if (!command)
108
+ return 'none';
109
+ if (command === 'publish') {
110
+ const sub = positional[1];
111
+ if (sub === 'init')
112
+ return 'publish:init';
113
+ if (sub === 'push')
114
+ return 'publish:push';
115
+ return 'publish';
116
+ }
117
+ return TELEMETRY_COMMANDS.includes(command) && command !== 'unknown' && command !== 'none'
118
+ ? command
119
+ : 'unknown';
120
+ }
121
+ /**
122
+ * Fire one event for a finished command, if and only if the user opted in. Returns whether a
123
+ * send was attempted (for tests). Never throws; never delays the caller: the POST happens in a
124
+ * detached child that outlives this process.
125
+ */
126
+ export function recordCliEvent(opts) {
127
+ try {
128
+ // Agent/automation modes carry no telemetry at all, even for opted-in installs.
129
+ if (opts.argv.includes('--json') || opts.argv.includes('--yes') || opts.argv.includes('-y'))
130
+ return false;
131
+ if (!telemetryEnabled(opts.env, opts.ioEnv))
132
+ return false;
133
+ const payload = {
134
+ installId: loadTelemetryDecision(opts.env)?.installId || 'unset',
135
+ command: commandFromArgv(opts.argv),
136
+ exitCode: Number.isInteger(opts.exitCode) ? opts.exitCode : 1,
137
+ version: opts.version,
138
+ platform: process.platform,
139
+ };
140
+ const origin = (opts.ioEnv.SELLA_MCP_URL || `${DEFAULT_ORIGIN}/api/mcp`).replace(/\/api\/mcp\/?$/, '') || DEFAULT_ORIGIN;
141
+ const sender = opts.senderPath || fileURLToPath(new URL('./telemetry-send.js', import.meta.url));
142
+ const spawnFn = opts.spawnFn || spawn;
143
+ const child = spawnFn(process.execPath, [sender, `${origin}/api/telemetry/cli`, JSON.stringify(payload)], {
144
+ detached: true,
145
+ stdio: 'ignore',
146
+ });
147
+ child.unref();
148
+ return true;
149
+ }
150
+ catch {
151
+ return false;
152
+ }
153
+ }
package/package.json CHANGED
@@ -1,9 +1,28 @@
1
1
  {
2
2
  "name": "sella-cli",
3
- "version": "0.6.4",
4
- "description": "Sella onboarding CLI install Sella into your agent clients, pair, verify, fund, publish. (`npx sella-cli init`)",
3
+ "version": "0.6.6",
4
+ "description": "Connect your AI agent to Sella, the marketplace where agents buy data and APIs, in one command: npx sella-cli. Installs the Sella MCP server into Claude Code, Cursor and more, then pairs, verifies, funds, and publishes.",
5
+ "keywords": [
6
+ "cli",
7
+ "mcp",
8
+ "model-context-protocol",
9
+ "ai-agents",
10
+ "agentic-commerce",
11
+ "x402",
12
+ "usdc",
13
+ "micropayments",
14
+ "pay-per-call",
15
+ "data-marketplace",
16
+ "api-marketplace",
17
+ "datasets",
18
+ "claude",
19
+ "cursor",
20
+ "developer-tools",
21
+ "onboarding"
22
+ ],
5
23
  "license": "MIT",
6
24
  "homepage": "https://sellag.vercel.app",
25
+ "bugs": { "url": "https://github.com/010100100100011101010100/ogsella/issues" },
7
26
  "repository": { "type": "git", "url": "https://github.com/010100100100011101010100/ogsella", "directory": "cli" },
8
27
  "type": "module",
9
28
  "bin": { "sella": "./dist/index.js" },