@clawcard/cli 1.1.1 → 1.1.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawcard/cli",
3
- "version": "1.1.1",
3
+ "version": "1.1.4",
4
4
  "description": "The ClawCard CLI — manage your agent keys, billing, and setup from the terminal",
5
5
  "bin": {
6
6
  "clawcard": "./bin/clawcard.mjs"
@@ -11,6 +11,9 @@ const COMMANDS = [
11
11
  [" logout", "Clear session"],
12
12
  [" whoami", "Show current account"],
13
13
  ["", ""],
14
+ [orange.bold("Agent"), ""],
15
+ [" agent", "Show your agent's identity"],
16
+ ["", ""],
14
17
  [orange.bold("Keys"), ""],
15
18
  [" keys", "Interactive key management"],
16
19
  [" keys create", "Create a new API key"],
@@ -102,16 +102,15 @@ export async function keysCreateCommand() {
102
102
  p.log.success("Copied to clipboard");
103
103
  }
104
104
 
105
- if (result.email || result.phone) {
106
- p.log.info(
107
- [
108
- result.email && `Email: ${result.email}`,
109
- result.phone && `Phone: ${result.phone}`,
110
- ]
111
- .filter(Boolean)
112
- .join("\n")
113
- );
114
- }
105
+ // Show provisioned resources
106
+ const details = [
107
+ `Name: ${orange.bold(result.name || "unnamed")}`,
108
+ result.email && `Email: ${result.email}`,
109
+ result.phone && `Phone: ${result.phone}`,
110
+ `Limit: $${(result.spendLimitCents / 100).toFixed(2)}`,
111
+ ].filter(Boolean).join("\n");
112
+
113
+ p.note(details, "Your Agent");
115
114
  } catch (err) {
116
115
  s.stop("Failed to create key");
117
116
  p.log.error(err.message);
@@ -209,6 +208,41 @@ export async function keysInfoCommand(keyIdOrPrefix) {
209
208
  }
210
209
  }
211
210
 
211
+ export async function agentStatusCommand() {
212
+ requireAuth();
213
+
214
+ const s = p.spinner();
215
+ s.start("Fetching agent...");
216
+
217
+ try {
218
+ const agents = await listAgents();
219
+ const active = agents.filter((a) => a.status === "active");
220
+
221
+ if (!active.length) {
222
+ s.stop("");
223
+ p.log.info("No active agent. Create one with: clawcard keys create");
224
+ return;
225
+ }
226
+
227
+ const agent = await getAgent(active[0].id);
228
+ s.stop("");
229
+
230
+ const info = [
231
+ `Name: ${orange.bold(agent.name || "unnamed")}`,
232
+ `Key: ${chalk.dim(agent.keyPrefix + "...")}`,
233
+ `Email: ${agent.email || "-"}`,
234
+ `Phone: ${agent.phone || "-"}`,
235
+ `Limit: $${(agent.spendLimitCents / 100).toFixed(2)}`,
236
+ `Status: ${chalk.green("active")}`,
237
+ ].join("\n");
238
+
239
+ p.note(info, "Your Agent");
240
+ } catch (err) {
241
+ s.stop("Failed");
242
+ p.log.error(err.message);
243
+ }
244
+ }
245
+
212
246
  export async function keysRevokeCommand() {
213
247
  requireAuth();
214
248
 
@@ -45,33 +45,53 @@ export async function signupCommand() {
45
45
 
46
46
  p.note(
47
47
  [
48
- `${orange.bold("Step 1:")} Create an API key`,
49
- ` ${chalk.dim("$ clawcard keys create")}`,
48
+ `${orange.bold("Step 1:")} Top up your balance`,
49
+ ` ${chalk.dim("Minimum $5 to get started")}`,
50
50
  "",
51
- `${orange.bold("Step 2:")} Set up your agent`,
52
- ` ${chalk.dim("$ clawcard setup")}`,
51
+ `${orange.bold("Step 2:")} Create your agent key`,
52
+ ` ${chalk.dim("Gets you an email, phone number, and virtual cards")}`,
53
53
  "",
54
- `${orange.bold("Step 3:")} Top up your balance`,
55
- ` ${chalk.dim("$ clawcard billing topup")}`,
54
+ `${orange.bold("Step 3:")} Set up your agent`,
55
+ ` ${chalk.dim("Installs the ClawCard skill for your agent")}`,
56
56
  ].join("\n"),
57
57
  "Getting Started"
58
58
  );
59
59
 
60
- const next = await p.confirm({
61
- message: "Create your first API key now?",
60
+ // Step 1: Top up
61
+ const topup = await p.confirm({
62
+ message: "Top up your balance now? (required to create an agent)",
62
63
  });
63
64
 
64
- if (!p.isCancel(next) && next) {
65
- const { keysCreateCommand } = await import("./keys.js");
66
- await keysCreateCommand();
65
+ if (!p.isCancel(topup) && topup) {
66
+ const { billingTopupCommand } = await import("./billing.js");
67
+ await billingTopupCommand();
67
68
 
68
- const runSetup = await p.confirm({
69
- message: "Set up your agent now?",
69
+ p.log.info(chalk.dim("Complete the payment in your browser, then come back here."));
70
+
71
+ const ready = await p.confirm({
72
+ message: "Payment complete?",
73
+ });
74
+
75
+ if (p.isCancel(ready) || !ready) return;
76
+
77
+ // Step 2: Create key
78
+ const createKey = await p.confirm({
79
+ message: "Create your agent key now?",
70
80
  });
71
81
 
72
- if (!p.isCancel(runSetup) && runSetup) {
73
- const { setupCommand } = await import("./setup.js");
74
- await setupCommand();
82
+ if (!p.isCancel(createKey) && createKey) {
83
+ const { keysCreateCommand } = await import("./keys.js");
84
+ await keysCreateCommand();
85
+
86
+ // Step 3: Setup
87
+ const runSetup = await p.confirm({
88
+ message: "Set up your agent now?",
89
+ });
90
+
91
+ if (!p.isCancel(runSetup) && runSetup) {
92
+ const { setupCommand } = await import("./setup.js");
93
+ await setupCommand();
94
+ }
75
95
  }
76
96
  }
77
97
  } catch (err) {
package/src/index.js CHANGED
@@ -88,6 +88,15 @@ keys
88
88
  await keysRevokeCommand();
89
89
  });
90
90
 
91
+ // Agent status
92
+ program
93
+ .command("agent")
94
+ .description("Show your agent's identity (email, phone, key)")
95
+ .action(async () => {
96
+ const { agentStatusCommand } = await import("./commands/keys.js");
97
+ await agentStatusCommand();
98
+ });
99
+
91
100
  // Setup
92
101
  program
93
102
  .command("setup")
@@ -177,28 +186,61 @@ if (process.argv.length <= 2) {
177
186
  );
178
187
  }
179
188
 
180
- const options = loggedIn
181
- ? [
182
- {
183
- value: "setup",
184
- label: "Setup",
185
- hint: "set up your agent",
186
- },
187
- { value: "billing", label: "Billing", hint: "check balance & top up" },
188
- { value: "referral", label: "Referral", hint: "share & earn $10" },
189
- { value: "whoami", label: "Who am I?", hint: "show current account" },
190
- { value: "logout", label: "Logout", hint: "clear session" },
191
- { value: "help", label: "Help", hint: "show all commands" },
192
- ]
193
- : [
194
- { value: "login", label: "Log in", hint: "authenticate via browser" },
195
- {
196
- value: "signup",
197
- label: "Sign up",
198
- hint: "create account with invite code",
199
- },
200
- { value: "help", label: "Help", hint: "show all commands" },
201
- ];
189
+ let options;
190
+
191
+ if (!loggedIn) {
192
+ options = [
193
+ { value: "login", label: "Log in", hint: "authenticate via browser" },
194
+ {
195
+ value: "signup",
196
+ label: "Sign up",
197
+ hint: "create account with invite code",
198
+ },
199
+ { value: "help", label: "Help", hint: "show all commands" },
200
+ ];
201
+ } else {
202
+ // Check user state to show contextual nudges
203
+ let hasBalance = true;
204
+ let hasAgent = true;
205
+
206
+ try {
207
+ const { getBalance, listAgents } = await import("./api.js");
208
+ const [balance, agents] = await Promise.all([
209
+ getBalance().catch(() => ({ amountCents: 0 })),
210
+ listAgents().catch(() => []),
211
+ ]);
212
+ hasBalance = balance.amountCents >= 500;
213
+ hasAgent = agents.some((a) => a.status === "active");
214
+ } catch {
215
+ // couldn't check — show full menu
216
+ }
217
+
218
+ if (!hasBalance) {
219
+ p.log.warn(
220
+ `You need at least $5 balance to create an agent. Run ${orange("clawcard billing topup")} to get started.`
221
+ );
222
+ } else if (!hasAgent) {
223
+ p.log.warn(
224
+ `You have balance but no agent yet. Run ${orange("clawcard keys create")} to create one.`
225
+ );
226
+ }
227
+
228
+ options = [
229
+ ...(!hasBalance
230
+ ? [{ value: "billing", label: "Top up balance", hint: "required — minimum $5 to get started" }]
231
+ : !hasAgent
232
+ ? [{ value: "keys-create", label: "Create agent", hint: "you have balance — create your agent now" }]
233
+ : [{ value: "agent", label: "My Agent", hint: "email, phone, key details" }]),
234
+ ...(hasAgent
235
+ ? [{ value: "setup", label: "Setup", hint: "set up your agent" }]
236
+ : []),
237
+ { value: "billing", label: "Billing", hint: "check balance & top up" },
238
+ { value: "referral", label: "Referral", hint: "share & earn $5" },
239
+ { value: "whoami", label: "Who am I?", hint: "show current account" },
240
+ { value: "logout", label: "Logout", hint: "clear session" },
241
+ { value: "help", label: "Help", hint: "show all commands" },
242
+ ];
243
+ }
202
244
 
203
245
  const action = await p.select({
204
246
  message: "What would you like to do?",
@@ -215,6 +257,8 @@ if (process.argv.length <= 2) {
215
257
  signup: () => import("./commands/signup.js").then((m) => m.signupCommand()),
216
258
  logout: () => import("./commands/logout.js").then((m) => m.logoutCommand()),
217
259
  whoami: () => import("./commands/whoami.js").then((m) => m.whoamiCommand()),
260
+ agent: () => import("./commands/keys.js").then((m) => m.agentStatusCommand()),
261
+ "keys-create": () => import("./commands/keys.js").then((m) => m.keysCreateCommand()),
218
262
  keys: () => import("./commands/keys.js").then((m) => m.keysCommand()),
219
263
  setup: () => import("./commands/setup.js").then((m) => m.setupCommand()),
220
264
  billing: () =>