@clawcard/cli 1.0.5 → 1.0.9
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 +6 -4
- package/package.json +1 -1
- package/src/commands/billing.js +10 -50
- package/src/commands/help.js +0 -1
- package/src/commands/login.js +1 -13
- package/src/commands/setup.js +13 -169
- package/src/commands/signup.js +36 -12
- package/src/index.js +1 -10
package/README.md
CHANGED
|
@@ -79,11 +79,13 @@ Each API key comes with:
|
|
|
79
79
|
|
|
80
80
|
## Pricing
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
- **Starter** ($7/mo) — 2 keys, 5 cards/month
|
|
84
|
-
- **Pro** ($19/mo) — 5 keys, 25 cards/month
|
|
82
|
+
Pay as you go. No subscriptions, no monthly fees.
|
|
85
83
|
|
|
86
|
-
|
|
84
|
+
- **Minimum top-up** — $5
|
|
85
|
+
- **Processing fee** — 10%
|
|
86
|
+
- **Cards** — Unlimited
|
|
87
|
+
|
|
88
|
+
Top up your balance and your agent spends it on virtual cards.
|
|
87
89
|
|
|
88
90
|
## Links
|
|
89
91
|
|
package/package.json
CHANGED
package/src/commands/billing.js
CHANGED
|
@@ -2,13 +2,7 @@ import * as p from "@clack/prompts";
|
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import open from "open";
|
|
4
4
|
import { requireAuth } from "../auth-guard.js";
|
|
5
|
-
import {
|
|
6
|
-
getBalance,
|
|
7
|
-
getSubscription,
|
|
8
|
-
getTransactions,
|
|
9
|
-
createCheckout,
|
|
10
|
-
createPortal,
|
|
11
|
-
} from "../api.js";
|
|
5
|
+
import { getBalance, getTransactions, createCheckout } from "../api.js";
|
|
12
6
|
|
|
13
7
|
const orange = chalk.hex("#FF6B35");
|
|
14
8
|
|
|
@@ -19,26 +13,13 @@ export async function billingCommand() {
|
|
|
19
13
|
s.start("Loading billing info...");
|
|
20
14
|
|
|
21
15
|
try {
|
|
22
|
-
const
|
|
23
|
-
getBalance(),
|
|
24
|
-
getSubscription(),
|
|
25
|
-
]);
|
|
16
|
+
const balance = await getBalance();
|
|
26
17
|
s.stop("Billing loaded");
|
|
27
18
|
|
|
28
|
-
const planColors = {
|
|
29
|
-
free: chalk.gray,
|
|
30
|
-
starter: chalk.blue,
|
|
31
|
-
pro: orange,
|
|
32
|
-
};
|
|
33
|
-
const colorPlan = (planColors[sub.subscription?.plan] || chalk.white)(
|
|
34
|
-
sub.subscription?.planName || sub.subscription?.plan || "Free"
|
|
35
|
-
);
|
|
36
|
-
|
|
37
19
|
const info = [
|
|
38
|
-
`Plan: ${colorPlan}`,
|
|
39
20
|
`Balance: ${chalk.green("$" + (balance.amountCents / 100).toFixed(2))}`,
|
|
40
|
-
|
|
41
|
-
|
|
21
|
+
"",
|
|
22
|
+
chalk.dim("Pay as you go — 10% processing fee on top-ups"),
|
|
42
23
|
].join("\n");
|
|
43
24
|
|
|
44
25
|
p.note(info, "Billing");
|
|
@@ -47,7 +28,6 @@ export async function billingCommand() {
|
|
|
47
28
|
message: "What would you like to do?",
|
|
48
29
|
options: [
|
|
49
30
|
{ value: "topup", label: "Top up balance" },
|
|
50
|
-
{ value: "upgrade", label: "Upgrade plan" },
|
|
51
31
|
{ value: "transactions", label: "View transactions" },
|
|
52
32
|
{ value: "back", label: "Back" },
|
|
53
33
|
],
|
|
@@ -58,8 +38,6 @@ export async function billingCommand() {
|
|
|
58
38
|
switch (action) {
|
|
59
39
|
case "topup":
|
|
60
40
|
return billingTopupCommand();
|
|
61
|
-
case "upgrade":
|
|
62
|
-
return billingUpgradeCommand();
|
|
63
41
|
case "transactions":
|
|
64
42
|
return billingTransactionsCommand();
|
|
65
43
|
}
|
|
@@ -91,13 +69,13 @@ export async function billingTopupCommand() {
|
|
|
91
69
|
requireAuth();
|
|
92
70
|
|
|
93
71
|
const amount = await p.select({
|
|
94
|
-
message: "How much would you like to add?",
|
|
72
|
+
message: "How much would you like to add? (10% processing fee)",
|
|
95
73
|
options: [
|
|
96
|
-
{ value: 500, label: "$5.00" },
|
|
97
|
-
{ value: 1000, label: "$10.00" },
|
|
98
|
-
{ value: 2500, label: "$25.00" },
|
|
99
|
-
{ value: 5000, label: "$50.00" },
|
|
100
|
-
{ value: 10000, label: "$100.00" },
|
|
74
|
+
{ value: 500, label: "$5.00", hint: "you pay $5.50" },
|
|
75
|
+
{ value: 1000, label: "$10.00", hint: "you pay $11.00" },
|
|
76
|
+
{ value: 2500, label: "$25.00", hint: "you pay $27.50" },
|
|
77
|
+
{ value: 5000, label: "$50.00", hint: "you pay $55.00" },
|
|
78
|
+
{ value: 10000, label: "$100.00", hint: "you pay $110.00" },
|
|
101
79
|
],
|
|
102
80
|
});
|
|
103
81
|
|
|
@@ -119,24 +97,6 @@ export async function billingTopupCommand() {
|
|
|
119
97
|
}
|
|
120
98
|
}
|
|
121
99
|
|
|
122
|
-
export async function billingUpgradeCommand() {
|
|
123
|
-
requireAuth();
|
|
124
|
-
|
|
125
|
-
const s = p.spinner();
|
|
126
|
-
s.start("Opening billing portal...");
|
|
127
|
-
|
|
128
|
-
try {
|
|
129
|
-
const result = await createPortal();
|
|
130
|
-
s.stop("");
|
|
131
|
-
|
|
132
|
-
await open(result.url);
|
|
133
|
-
p.log.success("Manage your subscription in the browser");
|
|
134
|
-
} catch (err) {
|
|
135
|
-
s.stop("Failed");
|
|
136
|
-
p.log.error(err.message);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
100
|
export async function billingTransactionsCommand() {
|
|
141
101
|
requireAuth();
|
|
142
102
|
|
package/src/commands/help.js
CHANGED
|
@@ -25,7 +25,6 @@ const COMMANDS = [
|
|
|
25
25
|
[" billing", "Interactive billing dashboard"],
|
|
26
26
|
[" billing balance", "Quick balance check"],
|
|
27
27
|
[" billing topup", "Top up balance"],
|
|
28
|
-
[" billing upgrade", "Upgrade subscription"],
|
|
29
28
|
[" billing transactions", "View transaction history"],
|
|
30
29
|
["", ""],
|
|
31
30
|
[orange.bold("Other"), ""],
|
package/src/commands/login.js
CHANGED
|
@@ -49,19 +49,7 @@ async function pollForToken(code, timeout = 120_000) {
|
|
|
49
49
|
const data = await res.json();
|
|
50
50
|
|
|
51
51
|
if (data.status === "complete" && data.token) {
|
|
52
|
-
|
|
53
|
-
let email = "";
|
|
54
|
-
try {
|
|
55
|
-
const meRes = await fetch(`${BASE_URL}/api/me`, {
|
|
56
|
-
headers: { Authorization: `Bearer ${data.token}` },
|
|
57
|
-
});
|
|
58
|
-
const me = await meRes.json();
|
|
59
|
-
email = me.email || "";
|
|
60
|
-
} catch {
|
|
61
|
-
// non-critical
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return { token: data.token, email };
|
|
52
|
+
return { token: data.token, email: data.email || "" };
|
|
65
53
|
}
|
|
66
54
|
} catch {
|
|
67
55
|
// network error, keep polling
|
package/src/commands/setup.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
2
|
import { execSync } from "child_process";
|
|
3
|
-
import {
|
|
4
|
-
readFileSync,
|
|
5
|
-
writeFileSync,
|
|
6
|
-
mkdirSync,
|
|
7
|
-
existsSync,
|
|
8
|
-
} from "fs";
|
|
3
|
+
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
9
4
|
import { join } from "path";
|
|
10
5
|
import { homedir } from "os";
|
|
11
6
|
import { requireAuth } from "../auth-guard.js";
|
|
@@ -16,107 +11,13 @@ import chalk from "chalk";
|
|
|
16
11
|
const orange = chalk.hex("#FF6B35");
|
|
17
12
|
const home = homedir();
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const HARNESSES = [
|
|
22
|
-
{
|
|
23
|
-
value: "claude-code",
|
|
24
|
-
label: "Claude Code",
|
|
25
|
-
hint: "~/.claude/settings.json",
|
|
26
|
-
write(apiKey) {
|
|
27
|
-
const settingsPath = join(home, ".claude", "settings.json");
|
|
28
|
-
let settings = {};
|
|
29
|
-
try {
|
|
30
|
-
settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
31
|
-
} catch {
|
|
32
|
-
// doesn't exist yet
|
|
33
|
-
}
|
|
34
|
-
if (!settings.env) settings.env = {};
|
|
35
|
-
settings.env.CLAWCARD_API_KEY = apiKey;
|
|
36
|
-
mkdirSync(join(home, ".claude"), { recursive: true });
|
|
37
|
-
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
38
|
-
return settingsPath;
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
value: "cursor",
|
|
43
|
-
label: "Cursor",
|
|
44
|
-
hint: ".cursor/environment.json (project)",
|
|
45
|
-
write(apiKey) {
|
|
46
|
-
const envPath = join(process.cwd(), ".cursor", "environment.json");
|
|
47
|
-
let config = {};
|
|
48
|
-
try {
|
|
49
|
-
config = JSON.parse(readFileSync(envPath, "utf-8"));
|
|
50
|
-
} catch {
|
|
51
|
-
// doesn't exist yet
|
|
52
|
-
}
|
|
53
|
-
if (!config.env) config.env = {};
|
|
54
|
-
config.env.CLAWCARD_API_KEY = apiKey;
|
|
55
|
-
mkdirSync(join(process.cwd(), ".cursor"), { recursive: true });
|
|
56
|
-
writeFileSync(envPath, JSON.stringify(config, null, 2));
|
|
57
|
-
return envPath;
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
value: "openclaw",
|
|
62
|
-
label: "OpenClaw",
|
|
63
|
-
hint: "~/.openclaw/.env",
|
|
64
|
-
write(apiKey) {
|
|
65
|
-
const envPath = join(home, ".openclaw", ".env");
|
|
66
|
-
let content = "";
|
|
67
|
-
try {
|
|
68
|
-
content = readFileSync(envPath, "utf-8");
|
|
69
|
-
} catch {
|
|
70
|
-
// doesn't exist
|
|
71
|
-
}
|
|
72
|
-
const regex = /^CLAWCARD_API_KEY=.*$/m;
|
|
73
|
-
if (regex.test(content)) {
|
|
74
|
-
content = content.replace(regex, `CLAWCARD_API_KEY=${apiKey}`);
|
|
75
|
-
} else {
|
|
76
|
-
content = content.trimEnd() + `\nCLAWCARD_API_KEY=${apiKey}\n`;
|
|
77
|
-
}
|
|
78
|
-
mkdirSync(join(home, ".openclaw"), { recursive: true });
|
|
79
|
-
writeFileSync(envPath, content);
|
|
80
|
-
return envPath;
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
value: "codex",
|
|
85
|
-
label: "Codex (OpenAI)",
|
|
86
|
-
hint: "shell env",
|
|
87
|
-
write(apiKey) {
|
|
88
|
-
// Codex reads from shell env; write to ~/.clawcard/.env and instruct user
|
|
89
|
-
return writeToClawcardEnv(apiKey);
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
value: "cline",
|
|
94
|
-
label: "Cline",
|
|
95
|
-
hint: "shell env",
|
|
96
|
-
write(apiKey) {
|
|
97
|
-
// Cline reads from shell env; write to ~/.clawcard/.env and instruct user
|
|
98
|
-
return writeToClawcardEnv(apiKey);
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
value: "other",
|
|
103
|
-
label: "Other / manual",
|
|
104
|
-
hint: "~/.clawcard/.env",
|
|
105
|
-
write(apiKey) {
|
|
106
|
-
return writeToClawcardEnv(apiKey);
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
];
|
|
110
|
-
|
|
111
|
-
function writeToClawcardEnv(apiKey) {
|
|
14
|
+
function writeApiKey(apiKey) {
|
|
112
15
|
const envPath = join(home, ".clawcard", ".env");
|
|
113
16
|
mkdirSync(join(home, ".clawcard"), { recursive: true });
|
|
114
17
|
let content = "";
|
|
115
18
|
try {
|
|
116
19
|
content = readFileSync(envPath, "utf-8");
|
|
117
|
-
} catch {
|
|
118
|
-
// doesn't exist
|
|
119
|
-
}
|
|
20
|
+
} catch {}
|
|
120
21
|
const regex = /^CLAWCARD_API_KEY=.*$/m;
|
|
121
22
|
if (regex.test(content)) {
|
|
122
23
|
content = content.replace(regex, `CLAWCARD_API_KEY=${apiKey}`);
|
|
@@ -147,36 +48,17 @@ export async function setupCommand() {
|
|
|
147
48
|
}
|
|
148
49
|
|
|
149
50
|
if (agents.length === 0) {
|
|
150
|
-
p.log.info("You don't have
|
|
151
|
-
const { keysCreateCommand } = await import("./keys.js");
|
|
152
|
-
await keysCreateCommand();
|
|
153
|
-
return setupCommand();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const keyChoice = await p.select({
|
|
157
|
-
message: "Which API key should this agent use?",
|
|
158
|
-
options: [
|
|
159
|
-
...agents.map((a) => ({
|
|
160
|
-
value: a.id,
|
|
161
|
-
label: `${a.name || "unnamed"} (${a.keyPrefix}...)`,
|
|
162
|
-
hint: a.email,
|
|
163
|
-
})),
|
|
164
|
-
{ value: "create", label: "Create a new key" },
|
|
165
|
-
],
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
if (p.isCancel(keyChoice)) return;
|
|
169
|
-
|
|
170
|
-
if (keyChoice === "create") {
|
|
51
|
+
p.log.info("You don't have an agent key yet. Let's create one.");
|
|
171
52
|
const { keysCreateCommand } = await import("./keys.js");
|
|
172
53
|
await keysCreateCommand();
|
|
173
54
|
return setupCommand();
|
|
174
55
|
}
|
|
175
56
|
|
|
176
|
-
|
|
57
|
+
// Auto-select if there's only one key
|
|
58
|
+
const selectedKey = agents[0];
|
|
177
59
|
|
|
178
60
|
// Step 2: Get the raw API key
|
|
179
|
-
let apiKey = getSavedKey(
|
|
61
|
+
let apiKey = getSavedKey(selectedKey.id);
|
|
180
62
|
|
|
181
63
|
if (!apiKey) {
|
|
182
64
|
p.log.warn("Raw API key not found locally (it's only shown at creation).");
|
|
@@ -191,19 +73,7 @@ export async function setupCommand() {
|
|
|
191
73
|
apiKey = pastedKey;
|
|
192
74
|
}
|
|
193
75
|
|
|
194
|
-
// Step 3:
|
|
195
|
-
const harness = await p.select({
|
|
196
|
-
message: "Which agent harness are you using?",
|
|
197
|
-
options: HARNESSES.map((h) => ({
|
|
198
|
-
value: h.value,
|
|
199
|
-
label: h.label,
|
|
200
|
-
hint: h.hint,
|
|
201
|
-
})),
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
if (p.isCancel(harness)) return;
|
|
205
|
-
|
|
206
|
-
// Step 4: Global or project?
|
|
76
|
+
// Step 3: Global or project?
|
|
207
77
|
const scope = await p.select({
|
|
208
78
|
message: "Install skill globally or for this project?",
|
|
209
79
|
options: [
|
|
@@ -222,7 +92,7 @@ export async function setupCommand() {
|
|
|
222
92
|
|
|
223
93
|
if (p.isCancel(scope)) return;
|
|
224
94
|
|
|
225
|
-
// Step
|
|
95
|
+
// Step 4: Install skill via skills.sh (auto-detects all agents)
|
|
226
96
|
const s2 = p.spinner();
|
|
227
97
|
s2.start("Installing ClawCard skill...");
|
|
228
98
|
|
|
@@ -243,37 +113,11 @@ export async function setupCommand() {
|
|
|
243
113
|
);
|
|
244
114
|
}
|
|
245
115
|
|
|
246
|
-
// Step
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const harnessConfig = HARNESSES.find((h) => h.value === harness);
|
|
251
|
-
const writtenPath = harnessConfig.write(apiKey);
|
|
252
|
-
|
|
253
|
-
s3.stop("API key configured!");
|
|
254
|
-
|
|
255
|
-
// Step 7: Harness-specific follow-up instructions
|
|
256
|
-
const needsShellExport = ["codex", "cline", "other"].includes(harness);
|
|
257
|
-
|
|
258
|
-
if (needsShellExport) {
|
|
259
|
-
p.note(
|
|
260
|
-
[
|
|
261
|
-
`Key saved to: ${chalk.dim(writtenPath)}`,
|
|
262
|
-
"",
|
|
263
|
-
`Add this to your shell profile (.zshrc, .bashrc):`,
|
|
264
|
-
"",
|
|
265
|
-
orange(` export CLAWCARD_API_KEY="${apiKey}"`),
|
|
266
|
-
"",
|
|
267
|
-
chalk.dim("Or source the env file:"),
|
|
268
|
-
orange(` source ${writtenPath}`),
|
|
269
|
-
].join("\n"),
|
|
270
|
-
"Manual step required"
|
|
271
|
-
);
|
|
272
|
-
} else {
|
|
273
|
-
p.log.info(`Key written to ${chalk.dim(writtenPath)}`);
|
|
274
|
-
}
|
|
116
|
+
// Step 5: Write API key to ~/.clawcard/.env
|
|
117
|
+
const envPath = writeApiKey(apiKey);
|
|
118
|
+
p.log.info(`API key saved to ${chalk.dim(envPath)}`);
|
|
275
119
|
|
|
276
|
-
// Step
|
|
120
|
+
// Step 6: Summary
|
|
277
121
|
p.log.success("Your agent is ready to use ClawCard!");
|
|
278
122
|
p.log.info(
|
|
279
123
|
[
|
package/src/commands/signup.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
|
+
import chalk from "chalk";
|
|
2
3
|
import open from "open";
|
|
3
4
|
import crypto from "crypto";
|
|
4
5
|
import { saveConfig, BASE_URL } from "../config.js";
|
|
5
6
|
|
|
7
|
+
const orange = chalk.hex("#FF6B35");
|
|
8
|
+
|
|
6
9
|
export async function signupCommand() {
|
|
7
10
|
const inviteCode = await p.text({
|
|
8
11
|
message: "Enter your invite code",
|
|
@@ -39,6 +42,38 @@ export async function signupCommand() {
|
|
|
39
42
|
});
|
|
40
43
|
|
|
41
44
|
p.log.success(`Welcome to ClawCard, ${result.email}!`);
|
|
45
|
+
|
|
46
|
+
p.note(
|
|
47
|
+
[
|
|
48
|
+
`${orange.bold("Step 1:")} Create an API key`,
|
|
49
|
+
` ${chalk.dim("$ clawcard keys create")}`,
|
|
50
|
+
"",
|
|
51
|
+
`${orange.bold("Step 2:")} Set up your agent`,
|
|
52
|
+
` ${chalk.dim("$ clawcard setup")}`,
|
|
53
|
+
"",
|
|
54
|
+
`${orange.bold("Step 3:")} Top up your balance`,
|
|
55
|
+
` ${chalk.dim("$ clawcard billing topup")}`,
|
|
56
|
+
].join("\n"),
|
|
57
|
+
"Getting Started"
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const next = await p.confirm({
|
|
61
|
+
message: "Create your first API key now?",
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
if (!p.isCancel(next) && next) {
|
|
65
|
+
const { keysCreateCommand } = await import("./keys.js");
|
|
66
|
+
await keysCreateCommand();
|
|
67
|
+
|
|
68
|
+
const runSetup = await p.confirm({
|
|
69
|
+
message: "Set up your agent now?",
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (!p.isCancel(runSetup) && runSetup) {
|
|
73
|
+
const { setupCommand } = await import("./setup.js");
|
|
74
|
+
await setupCommand();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
42
77
|
} catch (err) {
|
|
43
78
|
s.stop("Signup failed");
|
|
44
79
|
p.log.error(err.message);
|
|
@@ -57,18 +92,7 @@ async function pollForToken(code, timeout = 120_000) {
|
|
|
57
92
|
const data = await res.json();
|
|
58
93
|
|
|
59
94
|
if (data.status === "complete" && data.token) {
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
const meRes = await fetch(`${BASE_URL}/api/me`, {
|
|
63
|
-
headers: { Authorization: `Bearer ${data.token}` },
|
|
64
|
-
});
|
|
65
|
-
const me = await meRes.json();
|
|
66
|
-
email = me.email || "";
|
|
67
|
-
} catch {
|
|
68
|
-
// non-critical
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return { token: data.token, email };
|
|
95
|
+
return { token: data.token, email: data.email || "" };
|
|
72
96
|
}
|
|
73
97
|
} catch {
|
|
74
98
|
// network error, keep polling
|
package/src/index.js
CHANGED
|
@@ -121,14 +121,6 @@ billing
|
|
|
121
121
|
await billingTopupCommand();
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
-
billing
|
|
125
|
-
.command("upgrade")
|
|
126
|
-
.description("Upgrade subscription")
|
|
127
|
-
.action(async () => {
|
|
128
|
-
const { billingUpgradeCommand } = await import("./commands/billing.js");
|
|
129
|
-
await billingUpgradeCommand();
|
|
130
|
-
});
|
|
131
|
-
|
|
132
124
|
billing
|
|
133
125
|
.command("transactions")
|
|
134
126
|
.description("View transaction history")
|
|
@@ -190,9 +182,8 @@ if (process.argv.length <= 2) {
|
|
|
190
182
|
{
|
|
191
183
|
value: "setup",
|
|
192
184
|
label: "Setup",
|
|
193
|
-
hint: "
|
|
185
|
+
hint: "set up your agent",
|
|
194
186
|
},
|
|
195
|
-
{ value: "keys", label: "Keys", hint: "create & manage API keys" },
|
|
196
187
|
{ value: "billing", label: "Billing", hint: "check balance & top up" },
|
|
197
188
|
{ value: "referral", label: "Referral", hint: "share & earn $10" },
|
|
198
189
|
{ value: "whoami", label: "Who am I?", hint: "show current account" },
|