makeables 0.7.0 → 0.8.0

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.
Files changed (36) hide show
  1. package/README.md +28 -9
  2. package/dist/assets/stickers/moraleja/claude-01.webp +0 -0
  3. package/dist/assets/stickers/moraleja/claude-02.webp +0 -0
  4. package/dist/assets/stickers/moraleja/claude-03.webp +0 -0
  5. package/dist/assets/stickers/moraleja/code-brew-pereira.webp +0 -0
  6. package/dist/assets/stickers/moraleja/code-brew-san-01.webp +0 -0
  7. package/dist/assets/stickers/moraleja/code-brew-san-02.webp +0 -0
  8. package/dist/assets/stickers/moraleja/cooking.webp +0 -0
  9. package/dist/assets/stickers/moraleja/crafter-01.webp +0 -0
  10. package/dist/assets/stickers/moraleja/crafter-station.webp +0 -0
  11. package/dist/assets/stickers/moraleja/curious.webp +0 -0
  12. package/dist/assets/stickers/moraleja/jsi.webp +0 -0
  13. package/dist/assets/stickers/moraleja/kebo-01.webp +0 -0
  14. package/dist/assets/stickers/moraleja/kebo-02.webp +0 -0
  15. package/dist/assets/stickers/moraleja/kebo-03.webp +0 -0
  16. package/dist/assets/stickers/moraleja/kebo-04.webp +0 -0
  17. package/dist/assets/stickers/moraleja/kebo-brand.webp +0 -0
  18. package/dist/assets/stickers/moraleja/maca.webp +0 -0
  19. package/dist/assets/stickers/moraleja/moraleja-01.webp +0 -0
  20. package/dist/assets/stickers/moraleja/moraleja-lfg.webp +0 -0
  21. package/dist/assets/stickers/moraleja/pawboard.webp +0 -0
  22. package/dist/assets/stickers/moraleja/provenance.json +223 -0
  23. package/dist/assets/stickers/moraleja/qwstzw.webp +0 -0
  24. package/dist/assets/stickers/moraleja/repo-o-fake.webp +0 -0
  25. package/dist/assets/stickers/moraleja/she-ships.webp +0 -0
  26. package/dist/assets/stickers/moraleja/ship-or-sink.webp +0 -0
  27. package/dist/assets/stickers/moraleja/shippeando.webp +0 -0
  28. package/dist/assets/stickers/moraleja/shippervivbes.webp +0 -0
  29. package/dist/assets/stickers/moraleja/shipping.webp +0 -0
  30. package/dist/assets/stickers/moraleja/taste.webp +0 -0
  31. package/dist/assets/stickers/moraleja/tsb.webp +0 -0
  32. package/dist/assets/stickers/moraleja/vibing.webp +0 -0
  33. package/dist/{chunk-QJHEOZGN.js → chunk-NOES67KG.js} +252 -153
  34. package/dist/cli.js +260 -49
  35. package/dist/{mcp-AOJ6UJSC.js → mcp-54KV55QM.js} +1 -1
  36. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -52,7 +52,7 @@ import {
52
52
  svgNodeXml,
53
53
  version,
54
54
  writeAtomic
55
- } from "./chunk-QJHEOZGN.js";
55
+ } from "./chunk-NOES67KG.js";
56
56
 
57
57
  // src/cli.ts
58
58
  import { spawnSync as spawnSync2 } from "child_process";
@@ -1153,17 +1153,17 @@ import sharp7 from "sharp";
1153
1153
 
1154
1154
  // src/wallet-release.json
1155
1155
  var wallet_release_default = {
1156
- version: "0.2.0",
1156
+ version: "0.3.0",
1157
1157
  protocol: 1,
1158
1158
  repository: "crafter-station/makeables-community",
1159
1159
  platforms: {
1160
1160
  "darwin-arm64": {
1161
- asset: "makeables-wallet-0.2.0-darwin-arm64.tar.gz",
1162
- sha256: "5c51f0bd17c80875c12d5913845f368d22501e0a37b03ce8cbcbdc17a0433c37"
1161
+ asset: "makeables-wallet-0.3.0-darwin-arm64.tar.gz",
1162
+ sha256: "ebd275228d84c75836820e12a999bcaa7e586dfbb215ba06882ae161a2e4a09f"
1163
1163
  },
1164
1164
  "darwin-x64": {
1165
- asset: "makeables-wallet-0.2.0-darwin-x64.tar.gz",
1166
- sha256: "39705b13b59034fa04872433ab4fa7cd04f6c5d1714df2a41698b316afcf95d8"
1165
+ asset: "makeables-wallet-0.3.0-darwin-x64.tar.gz",
1166
+ sha256: "c5bd51863895e6612be838b5023f7a1322424568ea4249651125930a66ff4ccb"
1167
1167
  }
1168
1168
  }
1169
1169
  };
@@ -1219,13 +1219,24 @@ async function execute(command, args, progress) {
1219
1219
  });
1220
1220
  }
1221
1221
  async function invoke(executable, args, progress) {
1222
- const result = JSON.parse(await execute(executable, args, progress));
1222
+ let result;
1223
+ try {
1224
+ result = JSON.parse(await execute(executable, args, progress));
1225
+ if (!result || typeof result.ok !== "boolean") throw new Error("Missing companion result.");
1226
+ } catch {
1227
+ throw new WalletError({
1228
+ code: "WALLET_COMPANION_FAILED",
1229
+ message: "The Wallet companion ended without a valid receipt. Inspect wallet backups and doctor before another device operation."
1230
+ });
1231
+ }
1223
1232
  if (!result.ok) {
1224
- if (result.error?.code === "INVALID_INPUT")
1225
- throw new InputError(result.error.message ?? "Invalid Wallet input.");
1226
1233
  throw new WalletError(result.error ?? {});
1227
1234
  }
1228
- if (!result.data) throw new Error("Wallet companion returned no receipt.");
1235
+ if (!result.data || typeof result.data !== "object" || Array.isArray(result.data))
1236
+ throw new WalletError({
1237
+ code: "WALLET_COMPANION_FAILED",
1238
+ message: "The Wallet companion returned no receipt. Inspect wallet backups before another device operation."
1239
+ });
1229
1240
  return result.data;
1230
1241
  }
1231
1242
  async function walletDoctor() {
@@ -1278,6 +1289,7 @@ async function setupWallet(progress) {
1278
1289
  const url = `https://github.com/${wallet_release_default.repository}/releases/download/wallet-v${wallet_release_default.version}/${artifact.asset}`;
1279
1290
  progress?.({
1280
1291
  event: "wallet_progress",
1292
+ phase: "setup",
1281
1293
  message: `Downloading the Wallet companion ${wallet_release_default.version} for ${platform}.`
1282
1294
  });
1283
1295
  const response = await fetch(url, { signal: AbortSignal.timeout(18e4) });
@@ -1321,14 +1333,6 @@ async function setupWallet(progress) {
1321
1333
  }
1322
1334
  return walletDoctor();
1323
1335
  }
1324
- async function companion() {
1325
- const info = await walletDoctor();
1326
- if (!info.ready || !("installed" in info) || typeof info.installed !== "string")
1327
- throw new InputError(
1328
- "Run makeables wallet setup first. It installs the macOS companion without a source checkout."
1329
- );
1330
- return info.installed;
1331
- }
1332
1336
  async function walletArtwork(file, side2 = "front") {
1333
1337
  const input = resolve5(file);
1334
1338
  const info = await lstat(input);
@@ -1348,73 +1352,268 @@ async function walletArtwork(file, side2 = "front") {
1348
1352
  }
1349
1353
  return sharp7(source, { limitInputPixels: 24e6, density: 144 }).rotate().resize(1536, 969, { fit: "contain", background: "#000000" }).flatten({ background: "#000000" }).toColourspace("srgb").png().toBuffer();
1350
1354
  }
1355
+ async function preparedArtwork(directory) {
1356
+ const path = resolve5(directory);
1357
+ if (!(await lstat(path)).isDirectory())
1358
+ throw new InputError("--assets must be a prepared artwork directory.");
1359
+ for (const name of [
1360
+ "cardBackgroundCombined@3x.png",
1361
+ "cardBackgroundCombined@2x.png",
1362
+ "cardBackgroundCombined.pdf"
1363
+ ]) {
1364
+ const file = join3(path, name);
1365
+ const info = await lstat(file);
1366
+ if (!info.isFile() || info.size === 0 || info.size > 16 * 1024 * 1024)
1367
+ throw new InputError(`Invalid prepared asset: ${name}. Run wallet prep again.`);
1368
+ const signature = Buffer.from(name.endsWith(".pdf") ? "%PDF-" : "\x89PNG\r\n\n", "latin1");
1369
+ if (!(await readFile6(file)).subarray(0, signature.length).equals(signature))
1370
+ throw new InputError(`Invalid prepared asset: ${name}. Run wallet prep again.`);
1371
+ }
1372
+ return { path, preview: join3(path, "cardBackgroundCombined@3x.png") };
1373
+ }
1351
1374
  async function walletCommand(command, values, progress) {
1375
+ const started = performance.now();
1376
+ const elapsed = () => Math.round(performance.now() - started);
1377
+ let latestPhase;
1378
+ const report = (phase, message) => {
1379
+ latestPhase = phase;
1380
+ progress({
1381
+ event: "wallet_progress",
1382
+ phase,
1383
+ message,
1384
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1385
+ elapsedMs: elapsed()
1386
+ });
1387
+ };
1388
+ const forward = (data) => {
1389
+ if (data && typeof data === "object") {
1390
+ if ("phase" in data && typeof data.phase === "string") latestPhase = data.phase;
1391
+ progress({
1392
+ ...data,
1393
+ phase: latestPhase,
1394
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1395
+ elapsedMs: elapsed()
1396
+ });
1397
+ }
1398
+ };
1352
1399
  const need = (flag) => {
1353
1400
  const value = values[flag];
1354
1401
  if (typeof value !== "string" || !value) throw new InputError(`Supply --${flag}.`);
1355
1402
  return value;
1356
1403
  };
1357
1404
  if (command === "wallet doctor") return walletDoctor();
1358
- if (command === "wallet setup") return setupWallet(progress);
1359
- if (command === "wallet apply" || command === "wallet restore" || command === "wallet recover") {
1405
+ if (command === "wallet setup") return setupWallet(forward);
1406
+ const installing = command === "wallet install";
1407
+ const applying = command === "wallet apply" || installing && Boolean(values.card || values.backup);
1408
+ if (applying || command === "wallet restore" || command === "wallet recover") {
1360
1409
  if (!values.yes)
1361
1410
  throw new InputError(
1362
1411
  "Use --yes only after the user requests this operation on the selected card."
1363
1412
  );
1364
1413
  }
1365
- if (command === "wallet apply" && Boolean(values.card) === Boolean(values.backup))
1414
+ if (applying && Boolean(values.card) === Boolean(values.backup))
1366
1415
  throw new InputError("Choose exactly one --card selection or --backup original.");
1367
- const executable = await companion();
1416
+ if (installing && values.yes && !applying)
1417
+ throw new InputError("Select an explicit --card or --backup before using --yes.");
1418
+ if (installing && applying && (values.device || values.seconds))
1419
+ throw new InputError(
1420
+ "--device and --seconds are for selection; --card or --backup already binds the target."
1421
+ );
1422
+ if (values.seconds && (!/^\d+$/.test(String(values.seconds)) || Number(values.seconds) < 1 || Number(values.seconds) > 300))
1423
+ throw new InputError("--seconds must be between 1 and 300.");
1424
+ if (installing || applying) {
1425
+ if (Boolean(values.file) === Boolean(values.assets))
1426
+ throw new InputError("Supply exactly one --file artwork or --assets prepared directory.");
1427
+ if (values.assets && values.side)
1428
+ throw new InputError("--side applies to --file, not already prepared --assets.");
1429
+ }
1430
+ if (values.side && !["front", "back"].includes(String(values.side)))
1431
+ throw new InputError("--side must be front or back.");
1432
+ if (command === "wallet prep") {
1433
+ need("file");
1434
+ need("out");
1435
+ }
1436
+ if (command === "wallet restore") need("backup");
1437
+ const existing = values.assets ? await preparedArtwork(need("assets")) : void 0;
1438
+ if (installing) report("setup", "Checking the Wallet companion.");
1439
+ const info = installing ? await setupWallet(forward) : await walletDoctor();
1440
+ if (!info.ready || !("installed" in info) || typeof info.installed !== "string")
1441
+ throw new InputError("Run makeables wallet setup first.");
1442
+ const executable = info.installed;
1443
+ const capabilities = "capabilities" in info && Array.isArray(info.capabilities) ? info.capabilities : [];
1368
1444
  if (command === "wallet list") {
1369
1445
  const args = ["list"];
1370
1446
  for (const flag of ["device", "seconds"])
1371
1447
  if (typeof values[flag] === "string") args.push(`--${flag}`, String(values[flag]));
1372
- return invoke(executable, args, progress);
1448
+ if (values.first) {
1449
+ if (!capabilities.includes("first-selection"))
1450
+ throw new InputError(
1451
+ "This companion needs an update for --first. Omit --first for a full scan."
1452
+ );
1453
+ args.push("--first");
1454
+ }
1455
+ return invoke(executable, args, forward);
1373
1456
  }
1374
1457
  if (command === "wallet backups") {
1375
1458
  return invoke(
1376
1459
  executable,
1377
1460
  ["backups", ...values.backup ? ["--backup", need("backup")] : []],
1378
- progress
1461
+ forward
1379
1462
  );
1380
1463
  }
1381
1464
  if (command === "wallet recover") {
1382
1465
  return invoke(
1383
1466
  executable,
1384
1467
  ["recover", "--backup", need("backup"), "--device", need("device"), "--yes"],
1385
- progress
1468
+ forward
1386
1469
  );
1387
1470
  }
1388
1471
  if (command === "wallet restore") {
1389
- return invoke(executable, ["restore", "--backup", need("backup"), "--yes"], progress);
1390
- }
1391
- if (command === "wallet prep" || command === "wallet apply") {
1392
- const file = need("file");
1393
- if (values.side && !["front", "back"].includes(String(values.side)))
1394
- throw new InputError("--side must be front or back.");
1395
- const png = await walletArtwork(file, values.side === "back" ? "back" : "front");
1396
- const work = await mkdtemp(join3(tmpdir2(), "makeables-wallet-"));
1472
+ report("preflight", "Checking the original artwork backup and connected iPhone.");
1397
1473
  try {
1398
- const raster = join3(work, "artwork.png");
1399
- await writeFile2(raster, png, { mode: 384 });
1400
- const target = command === "wallet prep" ? resolve5(need("out")) : join3(work, "assets");
1401
- const prepared = await invoke(
1474
+ const result = await invoke(
1402
1475
  executable,
1403
- ["prepare", "--file", raster, "--out", target],
1404
- progress
1476
+ ["restore", "--backup", need("backup"), "--yes"],
1477
+ forward
1405
1478
  );
1479
+ return { ...result, elapsedMs: elapsed() };
1480
+ } catch (error) {
1481
+ if (error instanceof WalletError)
1482
+ throw new WalletError({
1483
+ ...error.details,
1484
+ phase: error.details.phase ?? latestPhase ?? "preflight",
1485
+ deviceWriteAttempted: error.details.deviceWriteAttempted ?? true,
1486
+ nextAction: error.details.nextAction ?? "inspect-backups"
1487
+ });
1488
+ throw error;
1489
+ }
1490
+ }
1491
+ if (command === "wallet prep" || applying || installing) {
1492
+ const work = await mkdtemp(join3(tmpdir2(), "makeables-wallet-"));
1493
+ let phase = "prepare";
1494
+ let deviceWriteAttempted = false;
1495
+ let persistent;
1496
+ let prepared;
1497
+ try {
1498
+ let target;
1499
+ if (existing) {
1500
+ target = resolve5(need("assets"));
1501
+ prepared = existing;
1502
+ } else {
1503
+ report("prepare", "Preparing the complete card artwork.");
1504
+ const png = await walletArtwork(need("file"), values.side === "back" ? "back" : "front");
1505
+ const raster = join3(work, "artwork.png");
1506
+ await writeFile2(raster, png, { mode: 384 });
1507
+ if (command === "wallet prep") {
1508
+ target = resolve5(need("out"));
1509
+ } else if (installing && !applying) {
1510
+ const root = join3(
1511
+ process.env.MAKEABLES_WALLET_HOME ?? join3(homedir2(), "Library", "Application Support", "Makeables", "Wallet"),
1512
+ "prepared"
1513
+ );
1514
+ await mkdir2(root, { recursive: true, mode: 448 });
1515
+ if ((await lstat(root)).isSymbolicLink())
1516
+ throw new InputError("Prepared artwork storage cannot be a symbolic link.");
1517
+ persistent = await mkdtemp(join3(root, "install-"));
1518
+ target = join3(persistent, "assets");
1519
+ } else {
1520
+ target = join3(work, "assets");
1521
+ }
1522
+ prepared = await invoke(
1523
+ executable,
1524
+ ["prepare", "--file", raster, "--out", target],
1525
+ forward
1526
+ );
1527
+ await preparedArtwork(target);
1528
+ }
1406
1529
  if (command === "wallet prep") return prepared;
1407
- progress({ event: "wallet_progress", message: "Full artwork rendered and prepared." });
1530
+ if (installing && !applying) {
1531
+ phase = "selection";
1532
+ report("selection", "Artwork is ready. Open Wallet and tap the card to customize.");
1533
+ const args2 = ["list"];
1534
+ for (const flag of ["device", "seconds"])
1535
+ if (typeof values[flag] === "string") args2.push(`--${flag}`, String(values[flag]));
1536
+ if (capabilities.includes("first-selection")) args2.push("--first");
1537
+ const selection = await invoke(executable, args2, forward);
1538
+ const hasCards = Array.isArray(selection.cards) && selection.cards.length > 0;
1539
+ const status = selection.needsDevice ? "needs-device" : hasCards ? "needs-selection" : "needs-card";
1540
+ return {
1541
+ ...selection,
1542
+ status,
1543
+ assets: target,
1544
+ preview: prepared.preview,
1545
+ deviceWriteAttempted: false,
1546
+ nextAction: selection.needsDevice ? "select-device" : hasCards ? "confirm-card" : "tap-card",
1547
+ next: {
1548
+ command: "wallet install",
1549
+ args: ["--assets", target],
1550
+ required: selection.needsDevice ? ["device"] : hasCards ? ["card", "yes"] : []
1551
+ },
1552
+ elapsedMs: elapsed()
1553
+ };
1554
+ }
1555
+ report("preflight", "Artwork is ready. Keep the selected iPhone connected.");
1408
1556
  const args = ["apply", "--assets", target, "--yes"];
1409
1557
  if (values.card) args.push("--card", need("card"));
1410
1558
  if (values.backup) args.push("--backup", need("backup"));
1411
- return invoke(executable, args, progress);
1559
+ phase = "apply";
1560
+ deviceWriteAttempted = true;
1561
+ const result = await invoke(executable, args, forward);
1562
+ return { ...result, elapsedMs: elapsed() };
1563
+ } catch (error) {
1564
+ if (error instanceof WalletError) {
1565
+ throw new WalletError({
1566
+ ...error.details,
1567
+ phase: error.details.phase ?? latestPhase ?? phase,
1568
+ deviceWriteAttempted: error.details.deviceWriteAttempted ?? deviceWriteAttempted,
1569
+ ...phase === "selection" && prepared ? {
1570
+ assets: String(prepared.path),
1571
+ preview: String(prepared.preview),
1572
+ nextAction: "retry-selection"
1573
+ } : {}
1574
+ });
1575
+ }
1576
+ throw error;
1412
1577
  } finally {
1413
1578
  await rm2(work, { recursive: true, force: true });
1579
+ if (persistent && phase === "prepare") await rm2(persistent, { recursive: true, force: true });
1414
1580
  }
1415
1581
  }
1416
1582
  throw new InputError("Unknown Wallet command.");
1417
1583
  }
1584
+ function walletSummary(result) {
1585
+ if (result.status === "restored") {
1586
+ const seconds = typeof result.elapsedMs === "number" ? ` in ${(result.elapsedMs / 1e3).toFixed(1)}s` : "";
1587
+ return [
1588
+ `Original Wallet artwork restored${seconds}.`,
1589
+ ...result.backupVerified ? ["Original backup preserved and verified."] : [],
1590
+ ...typeof result.backup === "string" ? [`Backup: ${result.backup}`] : [],
1591
+ "Force-close Wallet, reopen it and check the original design."
1592
+ ].join("\n");
1593
+ }
1594
+ if (result.status === "complete") {
1595
+ const seconds = typeof result.elapsedMs === "number" ? ` in ${(result.elapsedMs / 1e3).toFixed(1)}s` : "";
1596
+ return [
1597
+ `Wallet artwork installed${seconds}.`,
1598
+ result.backupVerified ? "Original artwork backup saved and verified." : "Original artwork backup saved.",
1599
+ ...typeof result.backup === "string" ? [`Backup: ${result.backup}`] : [],
1600
+ typeof result.refresh === "string" ? result.refresh : "Close and reopen Wallet to see the design."
1601
+ ].join("\n");
1602
+ }
1603
+ if (["needs-device", "needs-selection", "needs-card"].includes(String(result.status)))
1604
+ return [
1605
+ "Artwork prepared. No card has been changed.",
1606
+ `Preview: ${String(result.preview)}`,
1607
+ result.status === "needs-device" ? "Connect an unlocked iPhone or choose a listed device." : result.status === "needs-card" ? "No card was detected. Open Wallet, tap the card, and repeat using the prepared assets." : "Confirm which observed card you want to customize, then use its selection handle with --yes.",
1608
+ JSON.stringify(
1609
+ { assets: result.assets, devices: result.devices, cards: result.cards },
1610
+ null,
1611
+ 2
1612
+ ),
1613
+ `Continue: makeables wallet install --assets '${String(result.assets).replaceAll("'", "'\\''")}'${result.status === "needs-selection" ? " --card <selection> --yes" : result.status === "needs-device" ? " --device <selection>" : ""}`
1614
+ ].join("\n");
1615
+ return JSON.stringify(result, null, 2);
1616
+ }
1418
1617
 
1419
1618
  // src/cli.ts
1420
1619
  var commands = [
@@ -1442,9 +1641,10 @@ var commands = [
1442
1641
  ),
1443
1642
  "wallet setup",
1444
1643
  "wallet doctor",
1445
- "wallet list [--device <selection>] [--seconds 45]",
1644
+ "wallet install (--file <artwork> | --assets <directory>) [(--card <selection> | --backup <id|path>) --yes]",
1645
+ "wallet list [--device <selection>] [--seconds 45] [--first]",
1446
1646
  "wallet prep --file <card.json|artwork.svg|image.png> --out <new-directory> [--side front|back]",
1447
- "wallet apply --file <artwork> --card <selection> | --backup <id|path> --yes",
1647
+ "wallet apply (--file <artwork> | --assets <directory>) (--card <selection> | --backup <id|path>) --yes",
1448
1648
  "wallet restore --backup <id|path> --yes",
1449
1649
  "wallet backups [--backup <id|path>]",
1450
1650
  "wallet recover --backup <transaction-path> --device <selection> --yes",
@@ -1536,6 +1736,8 @@ async function run() {
1536
1736
  backup: { type: "string" },
1537
1737
  device: { type: "string" },
1538
1738
  seconds: { type: "string" },
1739
+ assets: { type: "string" },
1740
+ first: { type: "boolean" },
1539
1741
  type: { type: "string" },
1540
1742
  size: { type: "string" },
1541
1743
  "width-mm": { type: "string" },
@@ -1573,9 +1775,10 @@ From a built checkout: npm run studio -- <command>`,
1573
1775
  ),
1574
1776
  "wallet setup": [],
1575
1777
  "wallet doctor": [],
1576
- "wallet list": ["device", "seconds"],
1778
+ "wallet install": ["file", "assets", "card", "backup", "side", "device", "seconds", "yes"],
1779
+ "wallet list": ["device", "seconds", "first"],
1577
1780
  "wallet prep": ["file", "out", "side"],
1578
- "wallet apply": ["file", "card", "backup", "side", "yes"],
1781
+ "wallet apply": ["file", "assets", "card", "backup", "side", "yes"],
1579
1782
  "wallet restore": ["backup", "yes"],
1580
1783
  "wallet backups": ["backup"],
1581
1784
  "wallet recover": ["backup", "device", "yes"],
@@ -1648,8 +1851,16 @@ From a built checkout: npm run studio -- <command>`,
1648
1851
  if (values.product && !["card", "badge", "sticker"].includes(values.product))
1649
1852
  throw new InputError("--product must be card, badge or sticker.");
1650
1853
  if (command.startsWith("wallet ")) {
1651
- const result2 = await walletCommand(command, values, progress);
1652
- emit(result2, ["makeables skills get wallet"], JSON.stringify(result2, null, 2), json);
1854
+ const walletProgress = (data) => {
1855
+ if (json) return progress(data);
1856
+ if (data && typeof data === "object" && "message" in data) {
1857
+ const phase = "phase" in data ? `[${String(data.phase)}] ` : "";
1858
+ process.stderr.write(`${phase}${String(data.message)}
1859
+ `);
1860
+ }
1861
+ };
1862
+ const result2 = await walletCommand(command, values, walletProgress);
1863
+ emit(result2, ["makeables skills get wallet"], walletSummary(result2), json);
1653
1864
  return;
1654
1865
  }
1655
1866
  if (command.startsWith("image ") && imageTools.some((tool) => command === `image ${tool}`)) {
@@ -1804,7 +2015,7 @@ Run makeables skills get core for setup.`,
1804
2015
  }
1805
2016
  if (command === "mcp") {
1806
2017
  try {
1807
- const { runMcp } = await import("./mcp-AOJ6UJSC.js");
2018
+ const { runMcp } = await import("./mcp-54KV55QM.js");
1808
2019
  await runMcp(values.root ?? process.cwd());
1809
2020
  } catch (error) {
1810
2021
  process.stderr.write(
@@ -2422,7 +2633,7 @@ ${path ?? `No file written. Add --out ${kind}.json.`}`,
2422
2633
  return false;
2423
2634
  }
2424
2635
  run().catch((error) => {
2425
- const userError = error instanceof InputError || error instanceof SyntaxError || [
2636
+ const userError = error instanceof InputError || error instanceof WalletError && error.details.code === "INVALID_INPUT" || error instanceof SyntaxError || [
2426
2637
  "ERR_PARSE_ARGS_UNKNOWN_OPTION",
2427
2638
  "ERR_PARSE_ARGS_INVALID_OPTION_VALUE",
2428
2639
  "ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL",
@@ -15,7 +15,7 @@ import {
15
15
  stickerStyles,
16
16
  version,
17
17
  writeAtomic
18
- } from "./chunk-QJHEOZGN.js";
18
+ } from "./chunk-NOES67KG.js";
19
19
 
20
20
  // src/mcp.ts
21
21
  import { readFile as readFile2 } from "fs/promises";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makeables",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Create editable cards, badges and stickers with layered designs, live materials and your coding agent.",
5
5
  "homepage": "https://makeables.dev",
6
6
  "repository": {
@@ -51,9 +51,9 @@
51
51
  "@types/proper-lockfile": "4.1.4",
52
52
  "tsup": "^8.4.0",
53
53
  "typescript": "^5.8.3",
54
- "@makeables/design": "0.0.1",
55
54
  "@makeables/renderer": "0.0.1",
56
- "@makeables/testing": "0.0.0"
55
+ "@makeables/testing": "0.0.0",
56
+ "@makeables/design": "0.0.1"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">=22"