makaron-cli 0.11.1 → 0.11.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makaron-cli",
3
- "version": "0.11.1",
3
+ "version": "0.11.2",
4
4
  "description": "AI image editing, video generation, music creation, and marketplace skill workflows via CLI. Agents can self-register, install skills, create projects, and produce creative media.",
5
5
  "author": {
6
6
  "name": "Makaron AI",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makaron-cli",
3
- "version": "0.11.1",
3
+ "version": "0.11.2",
4
4
  "description": "AI image editing, video generation, music creation, and marketplace skill workflows via CLI. Agents can self-register, install skills, create projects, and produce creative media.",
5
5
  "displayName": "Makaron",
6
6
  "shortDescription": "AI image/video/music creation from the terminal",
package/bin/makaron.mjs CHANGED
@@ -1031,6 +1031,25 @@ async function uploadFileViaSignedUrl(baseUrl, headers, projectId, filePath, con
1031
1031
  return publicUrl;
1032
1032
  }
1033
1033
 
1034
+ async function uploadImageFilesViaSignedUrl(baseUrl, headers, projectId, imagePaths) {
1035
+ const urls = [];
1036
+ for (const imagePath of imagePaths) {
1037
+ const valid = validateImage(imagePath);
1038
+ if (!valid.ok) {
1039
+ process.stderr.write(`❌ Cannot upload: ${path.basename(imagePath)}\n ${valid.error}\n`);
1040
+ process.exit(1);
1041
+ }
1042
+ process.stderr.write(`📤 Uploading ${path.basename(imagePath)}...\n`);
1043
+ const url = await uploadFileViaSignedUrl(baseUrl, headers, projectId, imagePath, valid.mime);
1044
+ if (!url) {
1045
+ process.stderr.write(`❌ Failed to upload image: ${imagePath}\n`);
1046
+ process.exit(1);
1047
+ }
1048
+ urls.push(url);
1049
+ }
1050
+ return urls;
1051
+ }
1052
+
1034
1053
  function imageToArg(imgPath) {
1035
1054
  if (imgPath.startsWith('http://') || imgPath.startsWith('https://')) return imgPath;
1036
1055
  return readImageAsDataUrl(imgPath);
@@ -1462,52 +1481,28 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
1462
1481
 
1463
1482
  // --project auto: create a new project (with images/videos if provided)
1464
1483
  if (!projectId || projectId === 'auto') {
1465
- if (chatImages.length === 0) {
1466
- // Create empty project (videos will be uploaded separately after)
1467
- process.stderr.write(`📦 Creating new project...\n`);
1468
- const res = await fetch(`${baseUrl}/api/projects/create`, {
1469
- method: 'POST',
1470
- headers: { 'Content-Type': 'application/json', ...headers },
1471
- body: JSON.stringify({ title: prompt.slice(0, 50) }),
1472
- });
1473
- if (!res.ok) { process.stderr.write(`❌ Failed to create project: ${await res.text()}\n`); process.exit(1); }
1474
- const data = await res.json();
1475
- projectId = data.projectId;
1476
- process.stderr.write(`📦 Project created: ${projectId}\n`);
1477
- } else {
1478
- // Create project with images (URLs and/or local files)
1479
- const base64s = imageFileList.map(imgPath => {
1480
- process.stderr.write(`📤 Uploading ${path.basename(imgPath)}...\n`);
1481
- return readImageAsDataUrl(imgPath);
1482
- });
1483
- if (imageUrlList.length) process.stderr.write(`📤 Attaching ${imageUrlList.length} URL image(s)...\n`);
1484
- const body = {};
1485
- if (base64s.length) body.imageBase64s = base64s;
1486
- if (imageUrlList.length) body.imageUrls = imageUrlList;
1487
- const res = await fetch(`${baseUrl}/api/projects/create`, {
1488
- method: 'POST',
1489
- headers: { 'Content-Type': 'application/json', ...headers },
1490
- body: JSON.stringify(body),
1491
- });
1492
- if (!res.ok) { process.stderr.write(`❌ Failed to create project: ${await res.text()}\n`); process.exit(1); }
1493
- const data = await res.json();
1494
- projectId = data.projectId;
1495
- process.stderr.write(`📦 Project created: ${projectId} (${data.snapshots?.length || 0} images)\n`);
1496
- }
1497
- chatImages.length = 0;
1498
- imageUrlList.length = 0;
1499
- imageFileList.length = 0;
1484
+ // Create an empty project first, then attach media by URL. Local images use
1485
+ // signed upload URLs so the agent never depends on the caller's filesystem.
1486
+ process.stderr.write(`📦 Creating new project...\n`);
1487
+ const res = await fetch(`${baseUrl}/api/projects/create`, {
1488
+ method: 'POST',
1489
+ headers: { 'Content-Type': 'application/json', ...headers },
1490
+ body: JSON.stringify({ title: prompt.slice(0, 50) }),
1491
+ });
1492
+ if (!res.ok) { process.stderr.write(`❌ Failed to create project: ${await res.text()}\n`); process.exit(1); }
1493
+ const data = await res.json();
1494
+ projectId = data.projectId;
1495
+ process.stderr.write(`📦 Project created: ${projectId}\n`);
1500
1496
  }
1501
1497
  // Upload additional images to existing project
1502
1498
  if (imageFileList.length > 0 || imageUrlList.length > 0) {
1503
- const base64s = imageFileList.map(imgPath => {
1504
- process.stderr.write(`📤 Uploading ${path.basename(imgPath)}...\n`);
1505
- return readImageAsDataUrl(imgPath);
1506
- });
1499
+ const uploadedImageUrls = imageFileList.length
1500
+ ? await uploadImageFilesViaSignedUrl(baseUrl, headers, projectId, imageFileList)
1501
+ : [];
1502
+ const allImageUrls = [...uploadedImageUrls, ...imageUrlList];
1507
1503
  if (imageUrlList.length) process.stderr.write(`📤 Attaching ${imageUrlList.length} URL image(s)...\n`);
1508
1504
  const body = { _addToProject: projectId };
1509
- if (base64s.length) body.imageBase64s = base64s;
1510
- if (imageUrlList.length) body.imageUrls = imageUrlList;
1505
+ if (allImageUrls.length) body.imageUrls = allImageUrls;
1511
1506
  const res = await fetch(`${baseUrl}/api/projects/create`, {
1512
1507
  method: 'POST',
1513
1508
  headers: { 'Content-Type': 'application/json', ...headers },
@@ -1515,10 +1510,19 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
1515
1510
  });
1516
1511
  if (res.ok) {
1517
1512
  const data = await res.json();
1518
- process.stderr.write(`📤 Added ${data.snapshots?.length || 0} image(s) to project\n`);
1513
+ const addedCount = data.snapshots?.length || 0;
1514
+ if (addedCount < allImageUrls.length) {
1515
+ process.stderr.write(`❌ Added only ${addedCount}/${allImageUrls.length} image(s) to project; aborting run.\n`);
1516
+ process.exit(1);
1517
+ }
1518
+ process.stderr.write(`📤 Added ${addedCount} image(s) to project\n`);
1519
1519
  } else {
1520
- process.stderr.write(`⚠️ Failed to upload images: ${await res.text()}\n`);
1520
+ process.stderr.write(`❌ Failed to add images: ${await res.text()}\n`);
1521
+ process.exit(1);
1521
1522
  }
1523
+ chatImages.length = 0;
1524
+ imageUrlList.length = 0;
1525
+ imageFileList.length = 0;
1522
1526
  }
1523
1527
 
1524
1528
  const resolvedSkill = await resolveChatSkill(baseUrl, headers, activeSkill);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makaron-cli",
3
- "version": "0.11.1",
3
+ "version": "0.11.2",
4
4
  "description": "Talk to Makaron Agent from the terminal — create projects, edit images, generate videos",
5
5
  "type": "module",
6
6
  "scripts": {