sella-cli 0.9.0 → 0.9.1
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 +1 -0
- package/dist/chains.js +10 -1
- package/dist/clients.js +1 -1
- package/dist/credentials.js +2 -2
- package/dist/doctor.js +7 -7
- package/dist/index.js +55 -27
- package/dist/mcp-bridge.js +1 -1
- package/dist/publish.js +2 -2
- package/dist/ui.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -96,6 +96,7 @@ What's in there: a catalogue of 1,500+ machine-payable API providers with 8,000+
|
|
|
96
96
|
| `sella businesses` | Your agent's named runs, newest first: status, spend, tool calls, and the outcome it wrote. `--active` or `--closed` filters. |
|
|
97
97
|
| `sella fund` | Per-chain USDC deposit addresses, plus the funding page with QR codes and a fiat on-ramp. |
|
|
98
98
|
| `sella mcp` | Run a local stdio MCP server that proxies Sella with your stored key, for clients that cannot use a remote endpoint. |
|
|
99
|
+
| `sella skill` | Show the cached agent instruction bundle and its version. `sella skill update` refreshes it. A pinned local copy means two runs of the same prompt read the same instructions, instead of re-fetching 25 KB that can change mid-task. |
|
|
99
100
|
| `sella publish init <file.csv>` | Scaffold `sella-dataset.json` and pre-check the CSV structure. |
|
|
100
101
|
| `sella publish push` | Publish the dataset through the same route the web dashboard uses. |
|
|
101
102
|
|
package/dist/chains.js
CHANGED
|
@@ -47,8 +47,17 @@ export async function fetchChainRegistry(apiBase, fetchImpl = fetch) {
|
|
|
47
47
|
* What can the agent actually do with funds on this chain *today*?
|
|
48
48
|
* - `live` — Sella can settle an outbound provider payment from here → spendable now.
|
|
49
49
|
* - `deposit-only` — accepts deposits, but outbound settle isn't proven yet (fund it, can't spend).
|
|
50
|
-
* - `inbound-only` — settles inbound (agents paying Sella) with no agent-wallet spend
|
|
50
|
+
* - `inbound-only` — settles inbound (agents paying Sella) with no agent-wallet spend.
|
|
51
51
|
* - `unknown` — chain not in the registry (or registry unreachable).
|
|
52
|
+
*
|
|
53
|
+
* `inbound-only` used to name Stellar as its example. Stellar was removed from the registry on
|
|
54
|
+
* 2026-08-03 and there is no replacement to name: as of 2026-08-31 NO chain carries
|
|
55
|
+
* `settle.inbound: true`, so this branch is unreachable through the registry alone.
|
|
56
|
+
*
|
|
57
|
+
* That is not a bug in either place. Inbound is switched on per deployment by
|
|
58
|
+
* `X402_INBOUND_NETWORKS`, while the registry flag records only what has been PROVEN on-chain,
|
|
59
|
+
* which is deliberately slower-moving. The branch stays because a row can set the flag at any time,
|
|
60
|
+
* and reporting `unknown` for such a chain would be worse than reporting `inbound-only`.
|
|
52
61
|
*/
|
|
53
62
|
export function chainCapability(info) {
|
|
54
63
|
if (!info)
|
package/dist/clients.js
CHANGED
|
@@ -193,7 +193,7 @@ export function installSellaIntoClient(id, opts) {
|
|
|
193
193
|
doc = JSON.parse(raw);
|
|
194
194
|
}
|
|
195
195
|
catch {
|
|
196
|
-
throw new Error(`${spec.name} config at ${configPath} is not valid JSON
|
|
196
|
+
throw new Error(`${spec.name} config at ${configPath} is not valid JSON. Fix or remove it, then re-run.`);
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
}
|
package/dist/credentials.js
CHANGED
|
@@ -45,7 +45,7 @@ export function saveCredentials(payload, opts) {
|
|
|
45
45
|
files.push(p);
|
|
46
46
|
}
|
|
47
47
|
const custodyNote = keychainOk
|
|
48
|
-
? `API key stored in the macOS keychain (service "${KEYCHAIN_SERVICE}"). Wallet files are owner-read-only; client configs carry the key in plaintext
|
|
49
|
-
: `Secrets stored as owner-read-only files (0600)${env.platform === 'win32' ? '
|
|
48
|
+
? `API key stored in the macOS keychain (service "${KEYCHAIN_SERVICE}"). Wallet files are owner-read-only; client configs carry the key in plaintext, which is how MCP clients read headers today.`
|
|
49
|
+
: `Secrets stored as owner-read-only files (0600)${env.platform === 'win32' ? '. On Windows, protect your user profile' : ''}. Client configs carry the key in plaintext, which is how MCP clients read headers today. Never commit or share these files.`;
|
|
50
50
|
return { files, keyStorage: keychainOk ? 'keychain' : 'file', custodyNote };
|
|
51
51
|
}
|
package/dist/doctor.js
CHANGED
|
@@ -55,8 +55,8 @@ export async function runDoctor(opts) {
|
|
|
55
55
|
id: 'endpoint',
|
|
56
56
|
label: 'Sella MCP endpoint reachable',
|
|
57
57
|
ok: toolNames.length > 0,
|
|
58
|
-
detail: `${opts.mcpUrl}
|
|
59
|
-
...(toolNames.length === 0 ? { fix: 'The server answered but advertised no tools
|
|
58
|
+
detail: `${opts.mcpUrl}: ${toolNames.length} tools advertised`,
|
|
59
|
+
...(toolNames.length === 0 ? { fix: 'The server answered but advertised no tools. Check SELLA_MCP_URL points at /api/mcp.' } : {}),
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
catch (err) {
|
|
@@ -76,7 +76,7 @@ export async function runDoctor(opts) {
|
|
|
76
76
|
label: 'Onboarding tools advertised',
|
|
77
77
|
ok: hasBootstrap,
|
|
78
78
|
detail: hasBootstrap ? 'sella_setup_claim + sella_auth_* available' : `advertised: ${toolNames.slice(0, 6).join(', ')}…`,
|
|
79
|
-
...(hasBootstrap ? {} : { fix: 'The endpoint is not a Sella MCP server
|
|
79
|
+
...(hasBootstrap ? {} : { fix: 'The endpoint is not a Sella MCP server. Fix SELLA_MCP_URL.' }),
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
// 3. credentials — stored key present
|
|
@@ -122,7 +122,7 @@ export async function runDoctor(opts) {
|
|
|
122
122
|
try {
|
|
123
123
|
JSON.parse(fs.readFileSync(walletPath, 'utf8'));
|
|
124
124
|
walletOk = true;
|
|
125
|
-
walletDetail = `${walletPath} ok${fs.existsSync(agentWalletPath) ? ' · AgentWallet config ok' : ' · AgentWallet config absent (proxy payments off
|
|
125
|
+
walletDetail = `${walletPath} ok${fs.existsSync(agentWalletPath) ? ' · AgentWallet config ok' : ' · AgentWallet config absent (proxy payments off, re-run `sella pair` later)'}`;
|
|
126
126
|
}
|
|
127
127
|
catch {
|
|
128
128
|
/* stays missing/corrupt */
|
|
@@ -132,7 +132,7 @@ export async function runDoctor(opts) {
|
|
|
132
132
|
label: 'Wallet config files',
|
|
133
133
|
ok: walletOk,
|
|
134
134
|
detail: walletDetail,
|
|
135
|
-
...(walletOk ? {} : { fix: 'Run `sella pair
|
|
135
|
+
...(walletOk ? {} : { fix: 'Run `sella pair`. Wallet keys are delivered once at pairing.' }),
|
|
136
136
|
});
|
|
137
137
|
// 6. quote — paid-call economics computable (price + platform fee + settleable chains)
|
|
138
138
|
try {
|
|
@@ -147,7 +147,7 @@ export async function runDoctor(opts) {
|
|
|
147
147
|
detail: quote
|
|
148
148
|
? `${slug}: $${quote.totalUSD} total (${quote.feeBps} bps fee) on ${quote.payChains?.join('/') || 'no chains'}`
|
|
149
149
|
: 'catalog reachable but no quote returned',
|
|
150
|
-
...(quote ? {} : { fix: 'Catalog/quote API unavailable
|
|
150
|
+
...(quote ? {} : { fix: 'Catalog/quote API unavailable. Paid calls may still work; check the server logs.' }),
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
153
|
catch (err) {
|
|
@@ -156,7 +156,7 @@ export async function runDoctor(opts) {
|
|
|
156
156
|
label: 'x402 pay quote',
|
|
157
157
|
ok: false,
|
|
158
158
|
detail: err instanceof Error ? err.message : 'quote fetch failed',
|
|
159
|
-
fix: 'Could not fetch a pay quote from the catalog API
|
|
159
|
+
fix: 'Could not fetch a pay quote from the catalog API. Check the marketplace is up.',
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
162
|
return { ok: checks.every((c) => c.ok), checks };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as readline from 'node:readline/promises';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
+
import { readFileSync } from 'node:fs';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
4
6
|
import { detectClients, installSellaIntoClient, defaultEnv } from './clients.js';
|
|
5
7
|
import { pair } from './pairing.js';
|
|
6
8
|
import { runDoctor, runStatus, loadStoredKey } from './doctor.js';
|
|
@@ -14,7 +16,33 @@ import { defaultIo, Printer } from './output.js';
|
|
|
14
16
|
import { Ui } from './ui.js';
|
|
15
17
|
import { recordCliEvent, saveTelemetryDecision, shouldPromptTelemetry } from './telemetry.js';
|
|
16
18
|
const DEFAULT_MCP_URL = 'https://sellag.vercel.app/api/mcp';
|
|
17
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Read from package.json rather than hardcoded.
|
|
21
|
+
*
|
|
22
|
+
* It was hardcoded, and it drifted: this constant still said 0.8.0 while package.json and npm both
|
|
23
|
+
* served 0.9.0. `sella --version` therefore reported the wrong version on every install for weeks,
|
|
24
|
+
* the banner printed it, and `recordCliEvent` shipped it, so telemetry attributed 0.9.0 runs to
|
|
25
|
+
* 0.8.0. A version string that has to be bumped in two places is a version string that will be
|
|
26
|
+
* bumped in one.
|
|
27
|
+
*
|
|
28
|
+
* `../package.json` resolves correctly from both dist/index.js and src/index.ts, and npm always
|
|
29
|
+
* includes package.json in the tarball regardless of the `files` list, so it is there at runtime.
|
|
30
|
+
* Read with fs rather than a JSON import: import attributes are not available across the whole
|
|
31
|
+
* `engines: >=18` range this package claims to support.
|
|
32
|
+
*/
|
|
33
|
+
const VERSION = (() => {
|
|
34
|
+
try {
|
|
35
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
36
|
+
const raw = readFileSync(path.join(here, '..', 'package.json'), 'utf8');
|
|
37
|
+
const v = JSON.parse(raw)?.version;
|
|
38
|
+
return typeof v === 'string' && v ? v : 'unknown';
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Never let a missing or unreadable manifest take down the CLI: the version is informational
|
|
42
|
+
// everywhere it is used.
|
|
43
|
+
return 'unknown';
|
|
44
|
+
}
|
|
45
|
+
})();
|
|
18
46
|
function parseFlags(argv) {
|
|
19
47
|
const flags = {
|
|
20
48
|
json: false, yes: false, noColor: false, dryRun: false, noKeychain: false,
|
|
@@ -51,7 +79,7 @@ function parseFlags(argv) {
|
|
|
51
79
|
}
|
|
52
80
|
return flags;
|
|
53
81
|
}
|
|
54
|
-
const HELP = `sella
|
|
82
|
+
const HELP = `sella: the Sella onboarding CLI
|
|
55
83
|
|
|
56
84
|
Usage: sella <command> [options]
|
|
57
85
|
|
|
@@ -59,7 +87,7 @@ Commands:
|
|
|
59
87
|
init Guided onboarding: install the Sella MCP server, pair, verify
|
|
60
88
|
(also runs when you invoke \`sella\` with no command and no credentials yet)
|
|
61
89
|
pair Pair this machine only (setup code or email + OTP)
|
|
62
|
-
sandbox Try Sella with no signup
|
|
90
|
+
sandbox Try Sella with no signup. Search the live marketplace (rate-limited)
|
|
63
91
|
clients List detected agent clients (--install to write configs)
|
|
64
92
|
doctor Verify the install: endpoint, credentials, auth, wallets, pay-quote
|
|
65
93
|
status Show your key + AgentWallet balances
|
|
@@ -154,12 +182,12 @@ async function runPair(ctx, flags, emit, extra = {}) {
|
|
|
154
182
|
emit.error(outcome.error);
|
|
155
183
|
return { code: outcome.exitCode, summary: { paired: false, error: outcome.error } };
|
|
156
184
|
}
|
|
157
|
-
emit.ok(`Paired via ${outcome.method}
|
|
185
|
+
emit.ok(`Paired via ${outcome.method}. Status: ${outcome.payload.status || 'ok'}`);
|
|
158
186
|
for (const file of outcome.save.files)
|
|
159
187
|
emit.ok(`wrote ${file}`);
|
|
160
188
|
emit.info(outcome.save.custodyNote);
|
|
161
189
|
if (outcome.payload.agentWallet?.status === 'unavailable') {
|
|
162
|
-
emit.warn(`AgentWallet not provisioned (${outcome.payload.agentWallet.reason || 'backend unavailable'})
|
|
190
|
+
emit.warn(`AgentWallet not provisioned (${outcome.payload.agentWallet.reason || 'backend unavailable'}). MCP access still works; re-run \`sella pair\` later.`);
|
|
163
191
|
}
|
|
164
192
|
return {
|
|
165
193
|
code: 0,
|
|
@@ -193,7 +221,7 @@ async function collectPairChoice(ui, flags, ctx) {
|
|
|
193
221
|
if (method === 'setup-code') {
|
|
194
222
|
const code = await ui.text('Paste your setup code', {
|
|
195
223
|
placeholder: 'SELLA-XXXX-XXXX-XXXX-XXXX',
|
|
196
|
-
validate: (v) => (v ? undefined : 'A setup code is required
|
|
224
|
+
validate: (v) => (v ? undefined : 'A setup code is required. Mint one on the dashboard (Connect your agent).'),
|
|
197
225
|
});
|
|
198
226
|
return { setupCode: code };
|
|
199
227
|
}
|
|
@@ -282,14 +310,14 @@ async function cmdInit(ctx, flags, printer) {
|
|
|
282
310
|
(verify.ok ? sp.succeed : sp.succeed)(`${passed}/${verify.checks.length} checks passed`);
|
|
283
311
|
ui.checkStrip(verify.checks.map((c) => ({ id: c.id, ok: c.ok })));
|
|
284
312
|
for (const check of verify.checks.filter((c) => !c.ok)) {
|
|
285
|
-
ui.warn(`${check.label}
|
|
313
|
+
ui.warn(`${check.label}: ${check.detail}`);
|
|
286
314
|
if (check.fix)
|
|
287
315
|
ui.detail(`fix: ${check.fix}`);
|
|
288
316
|
}
|
|
289
317
|
verifySummary = { ok: verify.ok, passed, total: verify.checks.length };
|
|
290
318
|
}
|
|
291
319
|
catch (err) {
|
|
292
|
-
sp.fail('Verify could not run (network?)
|
|
320
|
+
sp.fail('Verify could not run (network?). Try `sella doctor` later.');
|
|
293
321
|
verifySummary = { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
294
322
|
}
|
|
295
323
|
// Cache the agent instruction bundle alongside the credentials, so the agent reads its
|
|
@@ -312,7 +340,7 @@ async function cmdInit(ctx, flags, printer) {
|
|
|
312
340
|
'Health check: sella doctor',
|
|
313
341
|
];
|
|
314
342
|
if (awStatus === 'unavailable') {
|
|
315
|
-
lines.push('AgentWallet pending (backend not configured)
|
|
343
|
+
lines.push('AgentWallet pending (backend not configured). Re-run `sella pair` later.');
|
|
316
344
|
}
|
|
317
345
|
ui.note('Sella is connected', lines, flags.dryRun ? 'plain' : awStatus === 'unavailable' ? 'warn' : 'ok');
|
|
318
346
|
// RFI: ready-to-send prompts for real agent tasks — the "now what?" answer.
|
|
@@ -320,9 +348,9 @@ async function cmdInit(ctx, flags, printer) {
|
|
|
320
348
|
ui.bar();
|
|
321
349
|
ui.step('Ideas to try with your agent (each is a ready-to-send prompt):');
|
|
322
350
|
ui.rows([
|
|
323
|
-
{ tag: 'invest', text: `Validate a startup idea for $25
|
|
324
|
-
{ tag: 'daily', text: `Get a daily morning brief
|
|
325
|
-
{ tag: 'free', text: `Test Sella without spending
|
|
351
|
+
{ tag: 'invest', text: `Validate a startup idea for $25: ${rfi}?uc=twenty-five-dollar-study`, tone: 'brand' },
|
|
352
|
+
{ tag: 'daily', text: `Get a daily morning brief: ${rfi}?uc=morning-brief`, tone: 'ok' },
|
|
353
|
+
{ tag: 'free', text: `Test Sella without spending: ${rfi}?uc=zero-dollar-demo`, tone: 'dim' },
|
|
326
354
|
]);
|
|
327
355
|
ui.detail(`Browse all ideas: ${rfi}`);
|
|
328
356
|
// One-time telemetry choice: only a human at a TTY is ever asked, and only once.
|
|
@@ -336,10 +364,10 @@ async function cmdInit(ctx, flags, printer) {
|
|
|
336
364
|
ui.detail(share === 'share' ? 'Thanks. Opt out anytime: SELLA_TELEMETRY=0' : 'Nothing will be sent. Opt in later: SELLA_TELEMETRY=1');
|
|
337
365
|
}
|
|
338
366
|
const took = Math.max(1, Math.round((Date.now() - startedAt) / 1000));
|
|
339
|
-
ui.outro(flags.dryRun ? 'Dry run complete
|
|
367
|
+
ui.outro(flags.dryRun ? 'Dry run complete. Nothing was written.' : `Done in ${took}s. Your agents can now buy on Sella.`);
|
|
340
368
|
}
|
|
341
369
|
else {
|
|
342
|
-
ui.outro('Pairing incomplete
|
|
370
|
+
ui.outro('Pairing incomplete. Fix the issue above, then re-run `sella init`.');
|
|
343
371
|
}
|
|
344
372
|
printer.jsonOut({ installed: install.results, pairing: paired.summary, reinstalled, verify: verifySummary });
|
|
345
373
|
return install.failed ? 1 : paired.code;
|
|
@@ -366,7 +394,7 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
|
|
|
366
394
|
// --json/--yes runs — automation must not fall into an interactive flow.
|
|
367
395
|
const interactive = io.isTTY && Boolean(process.stdin.isTTY) && !flags.json && !flags.yes;
|
|
368
396
|
if (interactive && !loadStoredKey(ctx.env)) {
|
|
369
|
-
printer.info('No Sella credentials on this machine yet
|
|
397
|
+
printer.info('No Sella credentials on this machine yet. Starting onboarding (Ctrl+C to abort, `sella --help` for commands).');
|
|
370
398
|
return await cmdInit(ctx, flags, printer);
|
|
371
399
|
}
|
|
372
400
|
io.stdout(HELP);
|
|
@@ -410,7 +438,7 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
|
|
|
410
438
|
if (choice.email)
|
|
411
439
|
ui.step(`Requesting a verification code for ${choice.email}…`);
|
|
412
440
|
const paired = await runPair(ctx, flags, emit, { ...choice, ask: wizardAsk(ui, ctx) });
|
|
413
|
-
ui.outro(paired.code === 0 ? 'Paired
|
|
441
|
+
ui.outro(paired.code === 0 ? 'Paired. Try `sella doctor` next.' : 'Pairing failed. See above.');
|
|
414
442
|
printer.jsonOut(paired.summary || {});
|
|
415
443
|
return paired.code;
|
|
416
444
|
}
|
|
@@ -428,12 +456,12 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
|
|
|
428
456
|
const total = result.datasets.length + result.apis.length;
|
|
429
457
|
printer.info(`Sandbox results for "${query}" (no account, rate-limited):`);
|
|
430
458
|
for (const d of result.datasets) {
|
|
431
|
-
printer.info(` dataset ${d.title || d.id}${d.priceUSDC ?
|
|
459
|
+
printer.info(` dataset ${d.title || d.id}${d.priceUSDC ? `, $${d.priceUSDC}/call` : ', free'}`);
|
|
432
460
|
}
|
|
433
461
|
for (const a of result.apis) {
|
|
434
462
|
printer.info(` api ${a.name || ''}${a.chains?.length ? ` [${a.chains.join('/')}]` : ''}`);
|
|
435
463
|
}
|
|
436
|
-
printer.info(total ? '\nPair to buy any of these: `sella init`.' : 'No matches
|
|
464
|
+
printer.info(total ? '\nPair to buy any of these: `sella init`.' : 'No matches. Try a broader query.');
|
|
437
465
|
}
|
|
438
466
|
return 0;
|
|
439
467
|
}
|
|
@@ -442,7 +470,7 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
|
|
|
442
470
|
printer.jsonOut(info);
|
|
443
471
|
if (!flags.json) {
|
|
444
472
|
if (!info.paired) {
|
|
445
|
-
printer.error('Not paired yet
|
|
473
|
+
printer.error('Not paired yet. Run `sella pair` first, then `sella fund`.');
|
|
446
474
|
return 2;
|
|
447
475
|
}
|
|
448
476
|
printer.info('Fund your Sella agent wallet with USDC:\n');
|
|
@@ -465,14 +493,14 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
|
|
|
465
493
|
printer.info('Sella doctor:');
|
|
466
494
|
for (const check of result.checks) {
|
|
467
495
|
if (check.ok)
|
|
468
|
-
printer.ok(`${check.label}
|
|
496
|
+
printer.ok(`${check.label}: ${check.detail}`);
|
|
469
497
|
else {
|
|
470
|
-
printer.error(`${check.label}
|
|
498
|
+
printer.error(`${check.label}: ${check.detail}`);
|
|
471
499
|
if (check.fix)
|
|
472
500
|
printer.info(` ↳ ${check.fix}`);
|
|
473
501
|
}
|
|
474
502
|
}
|
|
475
|
-
printer.info(result.ok ? '\nAll checks passed. Your agent is ready to buy.' : '\nSome checks failed
|
|
503
|
+
printer.info(result.ok ? '\nAll checks passed. Your agent is ready to buy.' : '\nSome checks failed. See the fixes above.');
|
|
476
504
|
}
|
|
477
505
|
return result.ok ? 0 : 1;
|
|
478
506
|
}
|
|
@@ -481,7 +509,7 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
|
|
|
481
509
|
printer.jsonOut(status);
|
|
482
510
|
if (!flags.json) {
|
|
483
511
|
const key = status.key;
|
|
484
|
-
printer.info(key.present ? `API key: ${key.prefix}… (${key.source})` : 'API key: not paired
|
|
512
|
+
printer.info(key.present ? `API key: ${key.prefix}… (${key.source})` : 'API key: not paired. Run `sella pair`');
|
|
485
513
|
const aw = status.agentWallet;
|
|
486
514
|
if (aw?.username) {
|
|
487
515
|
printer.info(`AgentWallet: ${aw.username}${aw.fundingStatus ? ` · ${aw.fundingStatus}` : ''}`);
|
|
@@ -605,7 +633,7 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
|
|
|
605
633
|
if (sub === 'push') {
|
|
606
634
|
const stored = loadStoredKey(ctx.env);
|
|
607
635
|
if (!stored) {
|
|
608
|
-
printer.error('Not paired
|
|
636
|
+
printer.error('Not paired. Run `sella pair` first, then `sella publish push`.');
|
|
609
637
|
printer.jsonOut({ ok: false, error: 'not_paired' });
|
|
610
638
|
return 2;
|
|
611
639
|
}
|
|
@@ -620,12 +648,12 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
|
|
|
620
648
|
printer.error(` ${k}: ${v}`);
|
|
621
649
|
}
|
|
622
650
|
else {
|
|
623
|
-
printer.ok(`Published
|
|
651
|
+
printer.ok(`Published. Status: ${result.status}`);
|
|
624
652
|
printer.info(` listing: ${result.listingUrl}`);
|
|
625
653
|
if (result.status === 'manual_review')
|
|
626
654
|
printer.info(' Sella is reviewing it; it goes live once approved.');
|
|
627
655
|
else if (result.status === 'processing')
|
|
628
|
-
printer.info(' Still scoring
|
|
656
|
+
printer.info(' Still scoring. Re-check later with `sella status` or the dashboard.');
|
|
629
657
|
}
|
|
630
658
|
}
|
|
631
659
|
return result.ok ? 0 : 1;
|
|
@@ -641,7 +669,7 @@ export async function runCli(argv, io = defaultIo(), env = defaultEnv()) {
|
|
|
641
669
|
ctx.io.stderr(`ok Sella MCP bridge → ${ctx.mcpUrl} (key from ${stored.source})`);
|
|
642
670
|
}
|
|
643
671
|
else {
|
|
644
|
-
ctx.io.stderr('warn No stored key
|
|
672
|
+
ctx.io.stderr('warn No stored key. Bridging free/sandbox tools only; run `sella pair` to enable paid tools.');
|
|
645
673
|
}
|
|
646
674
|
return await runMcpBridge({ mcpUrl: ctx.mcpUrl, apiKey: stored?.apiKey });
|
|
647
675
|
}
|
package/dist/mcp-bridge.js
CHANGED
|
@@ -40,7 +40,7 @@ export async function forwardMessage(msg, opts) {
|
|
|
40
40
|
});
|
|
41
41
|
const text = await res.text();
|
|
42
42
|
if (!res.ok) {
|
|
43
|
-
const hint = res.status === 401 ? '
|
|
43
|
+
const hint = res.status === 401 ? '. Run `sella pair` to (re)authenticate this machine' : '';
|
|
44
44
|
return { jsonrpc: '2.0', id, error: { code: -32000, message: `Sella endpoint responded ${res.status}${hint}` } };
|
|
45
45
|
}
|
|
46
46
|
if (!text)
|
package/dist/publish.js
CHANGED
|
@@ -33,7 +33,7 @@ export function precheckCsv(text) {
|
|
|
33
33
|
warnings.push(`Duplicate header(s): ${[...new Set(dupes)].join(', ')}.`);
|
|
34
34
|
const dataLines = lines.slice(1);
|
|
35
35
|
if (dataLines.length === 0)
|
|
36
|
-
warnings.push('No data rows
|
|
36
|
+
warnings.push('No data rows. Only a header was found.');
|
|
37
37
|
let emptyCells = 0;
|
|
38
38
|
let ragged = 0;
|
|
39
39
|
const nonEmptyPerColumn = new Array(columns.length).fill(0);
|
|
@@ -138,7 +138,7 @@ export async function pushDataset(opts) {
|
|
|
138
138
|
});
|
|
139
139
|
const json = await res.json().catch(() => ({}));
|
|
140
140
|
if (res.status === 401)
|
|
141
|
-
return { ok: false, error: 'Not authenticated
|
|
141
|
+
return { ok: false, error: 'Not authenticated. Run `sella pair` to (re)authenticate this machine.' };
|
|
142
142
|
if (res.status === 422)
|
|
143
143
|
return { ok: false, error: 'The listing was rejected by validation.', fieldErrors: json.fieldErrors };
|
|
144
144
|
if (!res.ok)
|
package/dist/ui.js
CHANGED
|
@@ -78,7 +78,7 @@ export class Ui {
|
|
|
78
78
|
if (this.quiet)
|
|
79
79
|
return;
|
|
80
80
|
if (!this.pretty) {
|
|
81
|
-
this.out(`SELLA
|
|
81
|
+
this.out(`SELLA · ${subtitle} (${meta})`);
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
84
|
this.out('');
|
|
@@ -277,7 +277,7 @@ export class Ui {
|
|
|
277
277
|
throw new Error(`Cannot prompt for "${label}" in a non-interactive run.`);
|
|
278
278
|
if (!this.pretty) {
|
|
279
279
|
this.out(label);
|
|
280
|
-
options.forEach((o, idx) => this.out(` ${idx + 1}) ${o.label}${o.hint ? `
|
|
280
|
+
options.forEach((o, idx) => this.out(` ${idx + 1}) ${o.label}${o.hint ? ` (${o.hint})` : ''}`));
|
|
281
281
|
for (;;) {
|
|
282
282
|
const answer = (await this.plainQuestion(`Choose 1-${options.length} (${initial + 1}): `)).trim();
|
|
283
283
|
if (!answer)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sella-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
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
5
|
"keywords": [
|
|
6
6
|
"cli",
|