agentspend 0.1.8 → 0.1.10

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.
@@ -12,6 +12,7 @@ const CARD_FILE = (0, node_path_1.join)(CONFIG_DIR, "card.json");
12
12
  const API_BASE = process.env.AGENTSPEND_API_URL ?? "https://api.agentspend.co";
13
13
  async function ensureConfigDir() {
14
14
  await (0, promises_1.mkdir)(CONFIG_DIR, { recursive: true });
15
+ await (0, promises_1.chmod)(CONFIG_DIR, 0o700);
15
16
  }
16
17
  function openUrl(url) {
17
18
  const cmd = node_process_1.platform === "darwin" ? "open" : node_process_1.platform === "win32" ? "start" : "xdg-open";
@@ -144,47 +145,31 @@ function registerCardCommands(program) {
144
145
  });
145
146
  card
146
147
  .command("configure")
147
- .description("Set up or reconfigure your card — opens the configuration page in your browser")
148
+ .description("Get configuration URL to set up or reconfigure your card")
148
149
  .action(async () => {
149
150
  try {
150
151
  // Check if card.json exists — reconfigure flow
151
152
  const cardData = await readCardFile();
152
153
  if (cardData) {
153
154
  const result = await requestConfigure(cardData.card_id, cardData.card_secret);
154
- console.log("Opened configuration page in browser.");
155
- openUrl(result.configure_url);
155
+ console.log(`Configuration URL: ${result.configure_url}`);
156
+ console.log();
157
+ console.log("Open this URL in your browser to reconfigure (change weekly limit, swap card, or remove).");
156
158
  return;
157
159
  }
158
160
  // First-time setup flow
159
161
  const result = await createCard();
160
- console.log(`Setup ID: ${result.setup_id}`);
161
- console.log(`Opening configuration page in browser...`);
162
- openUrl(result.setup_url);
163
162
  await ensureConfigDir();
164
163
  await (0, promises_1.writeFile)(SETUP_FILE, JSON.stringify({ setup_id: result.setup_id }, null, 2));
165
- console.log("Waiting for setup to complete...");
166
- while (true) {
167
- await sleep(3000);
168
- const status = await getSetupStatus(result.setup_id);
169
- if (status.status === "ready") {
170
- console.log(`Card is ready!`);
171
- if (status.card_id) {
172
- await (0, promises_1.writeFile)(CARD_FILE, JSON.stringify({
173
- card_id: status.card_id,
174
- card_secret: status.card_secret,
175
- }, null, 2));
176
- console.log(`Card ID saved to ${CARD_FILE}`);
177
- }
178
- // Clean up setup file
179
- await (0, promises_1.unlink)(SETUP_FILE).catch(() => { });
180
- break;
181
- }
182
- if (status.status === "expired" || status.status === "failed") {
183
- await (0, promises_1.unlink)(SETUP_FILE).catch(() => { });
184
- throw new Error(`Setup ${status.status}. Please try again.`);
185
- }
186
- process.stdout.write(".");
187
- }
164
+ await (0, promises_1.chmod)(SETUP_FILE, 0o600);
165
+ console.log(`Configuration URL: ${result.setup_url}`);
166
+ console.log(`Expires: ${result.expires_at}`);
167
+ console.log();
168
+ console.log("Complete setup in your browser:");
169
+ console.log(" 1. Set your weekly spending limit");
170
+ console.log(" 2. Add your card via Stripe");
171
+ console.log();
172
+ console.log("Then run 'agentspend card status' to verify completion.");
188
173
  }
189
174
  catch (err) {
190
175
  console.error(`\nError: ${err instanceof Error ? err.message : err}`);
@@ -8,6 +8,7 @@ const CONFIG_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), ".agentspend"
8
8
  const WALLET_FILE = (0, node_path_1.join)(CONFIG_DIR, "wallet.json");
9
9
  async function ensureConfigDir() {
10
10
  await (0, promises_1.mkdir)(CONFIG_DIR, { recursive: true });
11
+ await (0, promises_1.chmod)(CONFIG_DIR, 0o700);
11
12
  }
12
13
  async function readWalletConfig() {
13
14
  try {
@@ -49,7 +50,9 @@ function registerWalletCommands(program) {
49
50
  private_key: privateKey,
50
51
  };
51
52
  await (0, promises_1.writeFile)(WALLET_FILE, JSON.stringify(config, null, 2));
53
+ await (0, promises_1.chmod)(WALLET_FILE, 0o600);
52
54
  console.log(`Wallet created. Address: ${account.address} — Fund it with USDC on Base.`);
55
+ console.log(`Private key saved to ${WALLET_FILE} (owner-only permissions). Keep this file secure.`);
53
56
  }
54
57
  catch (err) {
55
58
  console.error(`Error: ${err instanceof Error ? err.message : err}`);
package/package.json CHANGED
@@ -1,11 +1,16 @@
1
1
  {
2
2
  "name": "agentspend",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "CLI for AgentSpend — manage cards and crypto wallets for AI agent payments",
5
+ "homepage": "https://github.com/jpbonch/agentspend",
6
+ "license": "MIT",
5
7
  "repository": {
6
8
  "type": "git",
7
9
  "url": "git+https://github.com/jpbonch/agentspend.git"
8
10
  },
11
+ "engines": {
12
+ "node": ">=18"
13
+ },
9
14
  "bin": {
10
15
  "agentspend": "dist/index.js"
11
16
  },
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { readFile, writeFile, mkdir, unlink } from "node:fs/promises";
2
+ import { readFile, writeFile, mkdir, unlink, chmod } from "node:fs/promises";
3
3
  import { homedir } from "node:os";
4
4
  import { join } from "node:path";
5
5
  import { exec } from "node:child_process";
@@ -42,6 +42,7 @@ const API_BASE = process.env.AGENTSPEND_API_URL ?? "https://api.agentspend.co";
42
42
 
43
43
  async function ensureConfigDir(): Promise<void> {
44
44
  await mkdir(CONFIG_DIR, { recursive: true });
45
+ await chmod(CONFIG_DIR, 0o700);
45
46
  }
46
47
 
47
48
  function openUrl(url: string): void {
@@ -194,53 +195,33 @@ export function registerCardCommands(program: Command): void {
194
195
 
195
196
  card
196
197
  .command("configure")
197
- .description("Set up or reconfigure your card — opens the configuration page in your browser")
198
+ .description("Get configuration URL to set up or reconfigure your card")
198
199
  .action(async () => {
199
200
  try {
200
201
  // Check if card.json exists — reconfigure flow
201
202
  const cardData = await readCardFile();
202
203
  if (cardData) {
203
204
  const result = await requestConfigure(cardData.card_id, cardData.card_secret);
204
- console.log("Opened configuration page in browser.");
205
- openUrl(result.configure_url);
205
+ console.log(`Configuration URL: ${result.configure_url}`);
206
+ console.log();
207
+ console.log("Open this URL in your browser to reconfigure (change weekly limit, swap card, or remove).");
206
208
  return;
207
209
  }
208
210
 
209
211
  // First-time setup flow
210
212
  const result = await createCard();
211
- console.log(`Setup ID: ${result.setup_id}`);
212
- console.log(`Opening configuration page in browser...`);
213
- openUrl(result.setup_url);
214
-
215
213
  await ensureConfigDir();
216
214
  await writeFile(SETUP_FILE, JSON.stringify({ setup_id: result.setup_id }, null, 2));
217
-
218
- console.log("Waiting for setup to complete...");
219
- while (true) {
220
- await sleep(3000);
221
- const status = await getSetupStatus(result.setup_id);
222
-
223
- if (status.status === "ready") {
224
- console.log(`Card is ready!`);
225
- if (status.card_id) {
226
- await writeFile(CARD_FILE, JSON.stringify({
227
- card_id: status.card_id,
228
- card_secret: status.card_secret,
229
- }, null, 2));
230
- console.log(`Card ID saved to ${CARD_FILE}`);
231
- }
232
- // Clean up setup file
233
- await unlink(SETUP_FILE).catch(() => {});
234
- break;
235
- }
236
-
237
- if (status.status === "expired" || status.status === "failed") {
238
- await unlink(SETUP_FILE).catch(() => {});
239
- throw new Error(`Setup ${status.status}. Please try again.`);
240
- }
241
-
242
- process.stdout.write(".");
243
- }
215
+ await chmod(SETUP_FILE, 0o600);
216
+
217
+ console.log(`Configuration URL: ${result.setup_url}`);
218
+ console.log(`Expires: ${result.expires_at}`);
219
+ console.log();
220
+ console.log("Complete setup in your browser:");
221
+ console.log(" 1. Set your weekly spending limit");
222
+ console.log(" 2. Add your card via Stripe");
223
+ console.log();
224
+ console.log("Then run 'agentspend card status' to verify completion.");
244
225
  } catch (err: unknown) {
245
226
  console.error(`\nError: ${err instanceof Error ? err.message : err}`);
246
227
  process.exit(1);
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { readFile, writeFile, mkdir } from "node:fs/promises";
2
+ import { readFile, writeFile, mkdir, chmod } from "node:fs/promises";
3
3
  import { homedir } from "node:os";
4
4
  import { join } from "node:path";
5
5
 
@@ -8,6 +8,7 @@ const WALLET_FILE = join(CONFIG_DIR, "wallet.json");
8
8
 
9
9
  async function ensureConfigDir(): Promise<void> {
10
10
  await mkdir(CONFIG_DIR, { recursive: true });
11
+ await chmod(CONFIG_DIR, 0o700);
11
12
  }
12
13
 
13
14
  interface WalletConfig {
@@ -61,8 +62,10 @@ export function registerWalletCommands(program: Command): void {
61
62
  };
62
63
 
63
64
  await writeFile(WALLET_FILE, JSON.stringify(config, null, 2));
65
+ await chmod(WALLET_FILE, 0o600);
64
66
 
65
67
  console.log(`Wallet created. Address: ${account.address} — Fund it with USDC on Base.`);
68
+ console.log(`Private key saved to ${WALLET_FILE} (owner-only permissions). Keep this file secure.`);
66
69
  } catch (err: unknown) {
67
70
  console.error(`Error: ${err instanceof Error ? err.message : err}`);
68
71
  process.exit(1);