agentmall 0.1.16 → 0.1.18

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/cli.js CHANGED
@@ -283,7 +283,7 @@ var RULE_WIDTH = 48;
283
283
  function banner() {
284
284
  console.log();
285
285
  console.log(
286
- ` ${c.bold}\u25CE agentmall${c.reset} ${c.dim}\u2014 buy anything with a URL${c.reset}`
286
+ ` ${c.bold}\u25CE AgentMall${c.reset} ${c.dim}\u2014 buy from the world's biggest retailers with a URL${c.reset}`
287
287
  );
288
288
  }
289
289
  function section(title) {
@@ -405,6 +405,71 @@ var FAILURE_MESSAGES = {
405
405
  function formatCents(cents) {
406
406
  return `$${(cents / 100).toFixed(2)}`;
407
407
  }
408
+ function compactTrackingValue(value) {
409
+ if (typeof value === "string") {
410
+ const trimmed = value.trim();
411
+ return trimmed || null;
412
+ }
413
+ if (typeof value === "number" || typeof value === "boolean") {
414
+ return String(value);
415
+ }
416
+ return null;
417
+ }
418
+ function normalizeTrackingCarrier(carrier, trackingNumber) {
419
+ const carrierValue = carrier?.trim().toLowerCase() ?? null;
420
+ const trackingValue = trackingNumber?.trim().toUpperCase() ?? null;
421
+ if ((carrierValue === "znlogic" || carrierValue === "amazon logistics") && trackingValue?.startsWith("TBA")) {
422
+ return "amazon";
423
+ }
424
+ return carrierValue;
425
+ }
426
+ function trackingUrlForCarrier(carrier, trackingNumber) {
427
+ if (!trackingNumber) return null;
428
+ switch (normalizeTrackingCarrier(carrier, trackingNumber)) {
429
+ case "ups":
430
+ return `https://www.ups.com/track?tracknum=${encodeURIComponent(trackingNumber)}`;
431
+ case "fedex":
432
+ return `https://www.fedex.com/fedextrack/?trknbr=${encodeURIComponent(trackingNumber)}`;
433
+ case "usps":
434
+ return `https://tools.usps.com/go/TrackConfirmAction?tLabels=${encodeURIComponent(trackingNumber)}`;
435
+ case "amazon":
436
+ return `https://www.amazon.com/progress-tracker/package/?trackingId=${encodeURIComponent(trackingNumber)}`;
437
+ case "dhl":
438
+ return `https://www.dhl.com/us-en/home/tracking.html?tracking-id=${encodeURIComponent(trackingNumber)}`;
439
+ default:
440
+ return null;
441
+ }
442
+ }
443
+ function trackingLines(tracking) {
444
+ const direct = compactTrackingValue(tracking);
445
+ if (direct) return [direct];
446
+ if (Array.isArray(tracking)) {
447
+ return tracking.flatMap((entry) => trackingLines(entry)).filter((line2, index, lines2) => line2 && lines2.indexOf(line2) === index);
448
+ }
449
+ if (!tracking || typeof tracking !== "object") {
450
+ return [];
451
+ }
452
+ const record = tracking;
453
+ const carrierRaw = compactTrackingValue(record.carrier) ?? compactTrackingValue(record.provider) ?? compactTrackingValue(record.shipper);
454
+ const number = compactTrackingValue(record.tracking_number) ?? compactTrackingValue(record.trackingNumber) ?? compactTrackingValue(record.number) ?? compactTrackingValue(record.code);
455
+ const carrier = normalizeTrackingCarrier(carrierRaw, number);
456
+ const url = compactTrackingValue(record.tracking_url) ?? compactTrackingValue(record.trackingUrl) ?? compactTrackingValue(record.url) ?? trackingUrlForCarrier(carrier, number);
457
+ const lines = [];
458
+ if (carrier && number) {
459
+ lines.push(`${carrier}: ${number}`);
460
+ } else if (number) {
461
+ lines.push(number);
462
+ } else if (carrier) {
463
+ lines.push(carrier);
464
+ }
465
+ if (url) lines.push(url);
466
+ for (const nestedKey of ["shipments", "tracking_numbers", "trackingNumbers", "numbers"]) {
467
+ if (nestedKey in record) {
468
+ lines.push(...trackingLines(record[nestedKey]));
469
+ }
470
+ }
471
+ return lines.filter((line2, index, all) => line2 && all.indexOf(line2) === index);
472
+ }
408
473
  function getBudgetBasePrice(product) {
409
474
  return product.price;
410
475
  }
@@ -568,6 +633,13 @@ function displayStatus(purchase) {
568
633
  if (purchase.deliveryMethod) {
569
634
  kv("Shipping", purchase.deliveryMethod);
570
635
  }
636
+ const tracking = trackingLines(purchase.tracking);
637
+ if (tracking.length) {
638
+ kv("Tracking", tracking[0]);
639
+ for (const extra of tracking.slice(1)) {
640
+ kv("", extra, { dim: true });
641
+ }
642
+ }
571
643
  kv("Created", new Date(purchase.createdAt).toLocaleString(), { dim: true });
572
644
  gap();
573
645
  }
@@ -592,7 +664,7 @@ function displayRefund(refund2) {
592
664
  import { input, confirm, select } from "@inquirer/prompts";
593
665
  async function promptProductUrl() {
594
666
  return input({
595
- message: "Product URL",
667
+ message: "Product URL or retailer link",
596
668
  validate: (value) => {
597
669
  try {
598
670
  const url = new URL(value);
@@ -758,6 +830,19 @@ async function getBuyerToken(purchaseId) {
758
830
 
759
831
  // src/cli/index.ts
760
832
  var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
833
+ var SUPPORTED_RETAILER_LABELS = [
834
+ "Amazon",
835
+ "Walmart",
836
+ "Target",
837
+ "Best Buy",
838
+ "Home Depot",
839
+ "eBay",
840
+ "Lowe's",
841
+ "Wayfair",
842
+ "Ace Hardware",
843
+ "1-800-Flowers",
844
+ "Pokemon Center"
845
+ ];
761
846
  function parseTempoBalance(balance) {
762
847
  const parsed = Number.parseFloat(balance ?? "0");
763
848
  return Number.isFinite(parsed) ? parsed : 0;
@@ -939,6 +1024,11 @@ async function buy(urlArg) {
939
1024
  try {
940
1025
  banner();
941
1026
  gap();
1027
+ if (!urlArg) {
1028
+ muted("Paste a product URL from a supported retailer.");
1029
+ muted(`Supported retailers: ${SUPPORTED_RETAILER_LABELS.join(", ")}.`);
1030
+ gap();
1031
+ }
942
1032
  const url = urlArg ?? await promptProductUrl();
943
1033
  const client = new AgentMall();
944
1034
  const product = await spin(
@@ -1059,32 +1149,38 @@ async function buy(urlArg) {
1059
1149
  throw error;
1060
1150
  }
1061
1151
  }
1062
- async function status(purchaseId) {
1152
+ async function status(purchaseId, options) {
1063
1153
  banner();
1064
1154
  const apiSecret = process.env.AGENTMALL_API_SECRET;
1065
- const buyerToken = apiSecret ? null : await getBuyerToken(purchaseId);
1155
+ const buyerToken = apiSecret ? null : options?.buyerToken?.trim() || await getBuyerToken(purchaseId);
1066
1156
  const client = apiSecret ? new AgentMall({ apiSecret }) : new AgentMall();
1067
1157
  if (!apiSecret && !buyerToken) {
1068
1158
  throw new Error(
1069
- "No saved buyer token found for this order on this machine."
1159
+ "No saved buyer token found for this order on this machine. Pass --buyer-token amtk_... to check it manually."
1070
1160
  );
1071
1161
  }
1162
+ if (!apiSecret && options?.buyerToken?.trim()) {
1163
+ await saveBuyerToken(purchaseId, options.buyerToken.trim());
1164
+ }
1072
1165
  const result = await spin(
1073
1166
  "Fetching order",
1074
1167
  () => client.purchases.get(purchaseId, buyerToken ? { buyerToken } : void 0)
1075
1168
  );
1076
1169
  displayStatus(result);
1077
1170
  }
1078
- async function refund(purchaseId) {
1171
+ async function refund(purchaseId, options) {
1079
1172
  banner();
1080
1173
  const apiSecret = process.env.AGENTMALL_API_SECRET;
1081
- const buyerToken = apiSecret ? null : await getBuyerToken(purchaseId);
1174
+ const buyerToken = apiSecret ? null : options?.buyerToken?.trim() || await getBuyerToken(purchaseId);
1082
1175
  const client = apiSecret ? new AgentMall({ apiSecret }) : new AgentMall();
1083
1176
  if (!apiSecret && !buyerToken) {
1084
1177
  throw new Error(
1085
- "No saved buyer token found for this order on this machine."
1178
+ "No saved buyer token found for this order on this machine. Pass --buyer-token amtk_... to check it manually."
1086
1179
  );
1087
1180
  }
1181
+ if (!apiSecret && options?.buyerToken?.trim()) {
1182
+ await saveBuyerToken(purchaseId, options.buyerToken.trim());
1183
+ }
1088
1184
  const result = await spin(
1089
1185
  "Fetching refund",
1090
1186
  () => client.refunds.getByPurchase(
@@ -1135,6 +1231,17 @@ var c2 = {
1135
1231
  };
1136
1232
  var args = process.argv.slice(2);
1137
1233
  var command = args[0];
1234
+ function readBuyerTokenFlag(values) {
1235
+ const inline = values.find((value) => value.startsWith("--buyer-token="));
1236
+ if (inline) {
1237
+ const token2 = inline.slice("--buyer-token=".length).trim();
1238
+ return token2 || void 0;
1239
+ }
1240
+ const index = values.indexOf("--buyer-token");
1241
+ if (index === -1) return void 0;
1242
+ const token = values[index + 1]?.trim();
1243
+ return token || void 0;
1244
+ }
1138
1245
  async function main() {
1139
1246
  try {
1140
1247
  switch (command) {
@@ -1143,17 +1250,17 @@ async function main() {
1143
1250
  break;
1144
1251
  case "status":
1145
1252
  if (!args[1]) {
1146
- console.error("Usage: agentmall status <purchase_id>");
1253
+ console.error("Usage: agentmall status <purchase_id> [--buyer-token <token>]");
1147
1254
  process.exit(1);
1148
1255
  }
1149
- await status(args[1]);
1256
+ await status(args[1], { buyerToken: readBuyerTokenFlag(args.slice(2)) });
1150
1257
  break;
1151
1258
  case "refund":
1152
1259
  if (!args[1]) {
1153
- console.error("Usage: agentmall refund <purchase_id>");
1260
+ console.error("Usage: agentmall refund <purchase_id> [--buyer-token <token>]");
1154
1261
  process.exit(1);
1155
1262
  }
1156
- await refund(args[1]);
1263
+ await refund(args[1], { buyerToken: readBuyerTokenFlag(args.slice(2)) });
1157
1264
  break;
1158
1265
  case "onboard":
1159
1266
  case "setup":
@@ -1187,7 +1294,7 @@ function printHelp() {
1187
1294
  };
1188
1295
  console.log();
1189
1296
  console.log(
1190
- ` ${c2.bold}\u25CE agentmall${c2.reset} ${c2.dim}\u2014 buy anything with a URL${c2.reset}`
1297
+ ` ${c2.bold}\u25CE AgentMall${c2.reset} ${c2.dim}\u2014 buy from the world's biggest retailers with a URL${c2.reset}`
1191
1298
  );
1192
1299
  console.log();
1193
1300
  console.log(` ${rule("Commands")}`);
@@ -1215,6 +1322,9 @@ function printHelp() {
1215
1322
  ` ${c2.dim}$${c2.reset} npx agentmall https://amazon.com/dp/B0DWTMJHCG`
1216
1323
  );
1217
1324
  console.log(` ${c2.dim}$${c2.reset} npx agentmall status pur_abc123`);
1325
+ console.log(
1326
+ ` ${c2.dim}$${c2.reset} npx agentmall status pur_abc123 --buyer-token amtk_...`
1327
+ );
1218
1328
  console.log(` ${c2.dim}$${c2.reset} npx agentmall refund pur_abc123`);
1219
1329
  console.log();
1220
1330
  }
package/dist/index.d.cts CHANGED
@@ -90,6 +90,7 @@ type Purchase = {
90
90
  status: PurchaseLifecycleStatus;
91
91
  items: PurchaseItem[];
92
92
  deliveryMethod?: string;
93
+ tracking?: unknown;
93
94
  maxBudget: number;
94
95
  finalTotal?: number;
95
96
  merchantReferences?: string[];
package/dist/index.d.ts CHANGED
@@ -90,6 +90,7 @@ type Purchase = {
90
90
  status: PurchaseLifecycleStatus;
91
91
  items: PurchaseItem[];
92
92
  deliveryMethod?: string;
93
+ tracking?: unknown;
93
94
  maxBudget: number;
94
95
  finalTotal?: number;
95
96
  merchantReferences?: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentmall",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "SDK and CLI for the AgentMall API — let AI agents buy physical products from US retailers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",