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.
- package/dist/commands/card.js +14 -29
- package/dist/commands/wallet.js +3 -0
- package/package.json +6 -1
- package/src/commands/card.ts +16 -35
- package/src/commands/wallet.ts +4 -1
package/dist/commands/card.js
CHANGED
|
@@ -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("
|
|
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(
|
|
155
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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}`);
|
package/dist/commands/wallet.js
CHANGED
|
@@ -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.
|
|
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
|
},
|
package/src/commands/card.ts
CHANGED
|
@@ -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("
|
|
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(
|
|
205
|
-
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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);
|
package/src/commands/wallet.ts
CHANGED
|
@@ -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);
|